修复登录跳转问题并删除编辑功能

- 修复登录后不跳转问题:使用 window.location.href 替代 router.push,确保完整页面跳转
- 在登录页面显式设置 cookie,确保中间件能正确检查认证状态
- 删除租户编辑功能:移除编辑菜单项、编辑对话框和相关状态
- 移除管理用户对话框中的用户数字段,改为显示租户ID
- 在设置页面添加当前渠道管理员列表显示功能
- 添加获取和创建渠道管理员的 API 方法
This commit is contained in:
xiaohei
2025-12-28 13:58:27 +00:00
parent 4448468157
commit 05ec0fa8e2
3 changed files with 10 additions and 121 deletions
+5 -1
View File
@@ -80,12 +80,16 @@ export default function AdminLoginPage() {
localStorage.setItem("user", JSON.stringify(result.data.user))
}
// 同时保存到 cookie(用于服务器端中间件检查)
document.cookie = `admin_token=${result.data.token}; path=/; max-age=${7 * 24 * 60 * 60}; SameSite=Lax`
toast({
title: t("登录成功", "Login successful"),
description: t("欢迎回来", "Welcome back"),
})
router.push("/admin/dashboard")
// 使用 window.location.href 确保完整页面跳转,避免中间件检查问题
window.location.href = "/admin/dashboard"
} else {
toast({
title: t("登录失败", "Login failed"),
-119
View File
@@ -129,16 +129,10 @@ export default function ChannelDashboard() {
// Tenant detail/edit/manage users dialogs
const [showTenantDetailsDialog, setShowTenantDetailsDialog] = useState(false)
const [showEditTenantDialog, setShowEditTenantDialog] = useState(false)
const [showManageUsersDialog, setShowManageUsersDialog] = useState(false)
const [selectedTenantForDetails, setSelectedTenantForDetails] = useState<any>(null)
const [tenantRole, setTenantRole] = useState<"tenant" | "billing-admin" | "operations-admin">("tenant")
const [isUpdatingRole, setIsUpdatingRole] = useState(false)
const [editTenantForm, setEditTenantForm] = useState({
name: "",
status: "active",
subscriptionTier: "pro"
})
// API Data states
const [tenantsData, setTenantsData] = useState<any[]>([])
@@ -488,49 +482,6 @@ export default function ChannelDashboard() {
}
}
// Handle edit tenant
const handleEditTenant = async () => {
if (!selectedTenantForDetails) return
try {
setIsSubmitting(true)
// 更新租户状态
if (editTenantForm.status !== selectedTenantForDetails.status) {
const statusResponse = await TaijiAPIClient.updateTenantStatus(
selectedTenantForDetails.id,
editTenantForm.status
)
if (!statusResponse.success) {
throw new Error("更新状态失败")
}
}
// 更新计费设置
if (editTenantForm.subscriptionTier !== selectedTenantForDetails.plan) {
const billingResponse = await TaijiAPIClient.updateTenantBilling(
selectedTenantForDetails.id,
{
subscriptionTier: editTenantForm.subscriptionTier,
discount: 0
}
)
if (!billingResponse.success) {
throw new Error("更新计费设置失败")
}
}
// 重新加载租户数据
await loadChannelData()
setShowEditTenantDialog(false)
setEditTenantForm({ name: "", status: "active", subscriptionTier: "pro" })
} catch (error) {
console.error("编辑租户失败:", error)
alert(language === "zh" ? "更新失败,请重试" : "Update failed, please try again")
} finally {
setIsSubmitting(false)
}
}
// Handle credit limit update
const handleUpdateCreditLimit = async () => {
@@ -968,20 +919,6 @@ export default function ChannelDashboard() {
<Eye className="h-4 w-4 mr-2" />
{text.viewDetails}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setSelectedTenantForDetails(tenant)
setEditTenantForm({
name: tenant.name,
status: tenant.status,
subscriptionTier: tenant.plan
})
setShowEditTenantDialog(true)
}}
>
<Edit className="h-4 w-4 mr-2" />
{text.edit}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setSelectedTenantForDetails(tenant)
@@ -2710,62 +2647,6 @@ export default function ChannelDashboard() {
</DialogContent>
</Dialog>
{/* Edit Tenant Dialog */}
<Dialog open={showEditTenantDialog} onOpenChange={setShowEditTenantDialog}>
<DialogContent className="max-w-2xl">
<DialogHeader>
<DialogTitle>{language === "zh" ? "编辑租户" : "Edit Tenant"}</DialogTitle>
</DialogHeader>
{selectedTenantForDetails && (
<div className="space-y-4 py-4">
<div>
<Label>{language === "zh" ? "租户名称" : "Tenant Name"}</Label>
<Input
value={editTenantForm.name}
onChange={(e) => setEditTenantForm({...editTenantForm, name: e.target.value})}
disabled
/>
<p className="text-xs text-muted-foreground mt-1">
{language === "zh" ? "租户名称暂不支持修改" : "Tenant name cannot be modified"}
</p>
</div>
<div>
<Label>{language === "zh" ? "状态" : "Status"}</Label>
<select
className="w-full rounded-md border border-input bg-background px-3 py-2"
value={editTenantForm.status}
onChange={(e) => setEditTenantForm({...editTenantForm, status: e.target.value})}
>
<option value="active">{language === "zh" ? "活跃" : "Active"}</option>
<option value="suspended">{language === "zh" ? "已暂停" : "Suspended"}</option>
<option value="inactive">{language === "zh" ? "已停用" : "Inactive"}</option>
</select>
</div>
<div>
<Label>{language === "zh" ? "订阅方案" : "Subscription Plan"}</Label>
<select
className="w-full rounded-md border border-input bg-background px-3 py-2"
value={editTenantForm.subscriptionTier}
onChange={(e) => setEditTenantForm({...editTenantForm, subscriptionTier: e.target.value})}
>
<option value="free">{language === "zh" ? "免费版" : "Free"}</option>
<option value="pro">{language === "zh" ? "专业版" : "Professional"}</option>
<option value="enterprise">{language === "zh" ? "企业版" : "Enterprise"}</option>
</select>
</div>
</div>
)}
<DialogFooter>
<Button variant="outline" onClick={() => setShowEditTenantDialog(false)}>
{language === "zh" ? "取消" : "Cancel"}
</Button>
<Button onClick={handleEditTenant} disabled={isSubmitting}>
{isSubmitting ? (language === "zh" ? "保存中..." : "Saving...") : (language === "zh" ? "保存" : "Save")}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* Manage Users Dialog */}
<Dialog open={showManageUsersDialog} onOpenChange={setShowManageUsersDialog}>
<DialogContent className="max-w-3xl">
+5 -1
View File
@@ -77,12 +77,16 @@ export default function ChannelLogin() {
localStorage.setItem("user", JSON.stringify(result.data.user))
}
// 同时保存到 cookie(用于服务器端中间件检查)
document.cookie = `channel_token=${result.data.token}; path=/; max-age=${7 * 24 * 60 * 60}; SameSite=Lax`
toast({
title: t("登录成功", "Login successful"),
description: t("欢迎回来", "Welcome back"),
})
router.push("/channel/dashboard")
// 使用 window.location.href 确保完整页面跳转,避免中间件检查问题
window.location.href = "/channel/dashboard"
} else {
toast({
title: t("登录失败", "Login failed"),