2026-04-15 17:08:17 +08:00
|
|
|
|
import * as React from "react"
|
2026-04-13 20:28:09 +08:00
|
|
|
|
import { Settings2 } from "lucide-react"
|
|
|
|
|
|
|
|
|
|
|
|
import type { RoleView, WorkflowConfig } from "@/App"
|
|
|
|
|
|
import { Badge } from "@/components/ui/badge"
|
|
|
|
|
|
import { Button } from "@/components/ui/button"
|
|
|
|
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
|
|
|
|
import { Input } from "@/components/ui/input"
|
|
|
|
|
|
|
|
|
|
|
|
type SystemSettingsProps = {
|
|
|
|
|
|
roleView: RoleView
|
|
|
|
|
|
onRoleViewChange: (role: RoleView) => void
|
|
|
|
|
|
workflowConfig: WorkflowConfig
|
|
|
|
|
|
onWorkflowConfigChange: (next: WorkflowConfig) => void
|
|
|
|
|
|
auditLogs: string[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function SystemSettings({
|
|
|
|
|
|
roleView,
|
|
|
|
|
|
onRoleViewChange,
|
|
|
|
|
|
workflowConfig,
|
|
|
|
|
|
onWorkflowConfigChange,
|
|
|
|
|
|
auditLogs,
|
|
|
|
|
|
}: SystemSettingsProps) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="flex flex-col gap-6 p-8">
|
|
|
|
|
|
<div className="flex flex-col gap-1">
|
|
|
|
|
|
<h1 className="text-3xl font-bold tracking-tight">系统设置</h1>
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<p className="text-muted-foreground">管理角色视角、可选发布能力、私有云账号与导出迁移准备。</p>
|
2026-04-13 20:28:09 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="grid gap-6 lg:grid-cols-2">
|
|
|
|
|
|
<Card className="border-none shadow-sm bg-white">
|
|
|
|
|
|
<CardHeader>
|
|
|
|
|
|
<CardTitle className="text-lg font-bold">角色视角切换</CardTitle>
|
|
|
|
|
|
<CardDescription>切换后将影响车型库中的可见操作与可执行动作。</CardDescription>
|
|
|
|
|
|
</CardHeader>
|
|
|
|
|
|
<CardContent className="flex flex-wrap gap-2">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant={roleView === "content-ops" ? "default" : "outline"}
|
|
|
|
|
|
onClick={() => onRoleViewChange("content-ops")}
|
|
|
|
|
|
>
|
|
|
|
|
|
内容运营专员
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant={roleView === "biz-market" ? "default" : "outline"}
|
|
|
|
|
|
onClick={() => onRoleViewChange("biz-market")}
|
|
|
|
|
|
>
|
|
|
|
|
|
业务/市场负责人
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant={roleView === "pm-ops" ? "default" : "outline"}
|
|
|
|
|
|
onClick={() => onRoleViewChange("pm-ops")}
|
|
|
|
|
|
>
|
|
|
|
|
|
项目与运维负责人
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
|
|
<Card className="border-none shadow-sm bg-white">
|
|
|
|
|
|
<CardHeader>
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<CardTitle className="text-lg font-bold">可选发布能力</CardTitle>
|
|
|
|
|
|
<CardDescription>以下能力用于展示成熟平台的扩展性,均不作为本期上线阻断项。</CardDescription>
|
2026-04-13 20:28:09 +08:00
|
|
|
|
</CardHeader>
|
|
|
|
|
|
<CardContent className="space-y-3 text-sm">
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
|
|
|
|
|
<span>启用预发布</span>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
size="sm"
|
|
|
|
|
|
variant={workflowConfig.enablePrePublish ? "default" : "outline"}
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
onWorkflowConfigChange({
|
|
|
|
|
|
...workflowConfig,
|
|
|
|
|
|
enablePrePublish: !workflowConfig.enablePrePublish,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
|
|
|
|
|
{workflowConfig.enablePrePublish ? "已开启" : "已关闭"}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
|
|
|
|
|
<span>允许发布后撤回</span>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
size="sm"
|
|
|
|
|
|
variant={workflowConfig.allowRecall ? "default" : "outline"}
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
onWorkflowConfigChange({
|
|
|
|
|
|
...workflowConfig,
|
|
|
|
|
|
allowRecall: !workflowConfig.allowRecall,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
|
|
|
|
|
{workflowConfig.allowRecall ? "已开启" : "已关闭"}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
|
|
|
|
|
<span>发布方式</span>
|
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
size="sm"
|
|
|
|
|
|
variant={workflowConfig.publishStrategy === "manual" ? "default" : "outline"}
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
onWorkflowConfigChange({ ...workflowConfig, publishStrategy: "manual" })
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
|
|
|
|
|
手动发布
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
size="sm"
|
|
|
|
|
|
variant={workflowConfig.publishStrategy === "scheduled" ? "default" : "outline"}
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
onWorkflowConfigChange({ ...workflowConfig, publishStrategy: "scheduled" })
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
|
|
|
|
|
定时发布
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{workflowConfig.publishStrategy === "scheduled" && (
|
|
|
|
|
|
<div className="grid gap-2 rounded-lg border p-3">
|
|
|
|
|
|
<span className="text-muted-foreground">默认发布时间(用于新建内容)</span>
|
|
|
|
|
|
<Input
|
|
|
|
|
|
type="time"
|
|
|
|
|
|
value={workflowConfig.defaultPublishTime}
|
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
|
onWorkflowConfigChange({
|
|
|
|
|
|
...workflowConfig,
|
|
|
|
|
|
defaultPublishTime: e.target.value,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
|
|
<Card className="border-none shadow-sm bg-white">
|
|
|
|
|
|
<CardHeader>
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<CardTitle className="text-lg font-bold">官网周更规则</CardTitle>
|
|
|
|
|
|
<CardDescription>当前口径为每周人工巡检和人工更新,不展示自动日更能力。</CardDescription>
|
2026-04-13 20:28:09 +08:00
|
|
|
|
</CardHeader>
|
|
|
|
|
|
<CardContent className="space-y-3 text-sm">
|
|
|
|
|
|
<div className="grid gap-2">
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<span className="text-muted-foreground">执行频率</span>
|
|
|
|
|
|
<Badge variant="outline" className="w-fit">固定为每周人工巡检</Badge>
|
2026-04-13 20:28:09 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div className="grid gap-2">
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<span className="text-muted-foreground">建议执行时间</span>
|
2026-04-13 20:28:09 +08:00
|
|
|
|
<Input
|
|
|
|
|
|
type="time"
|
|
|
|
|
|
value={workflowConfig.syncExecutionTime}
|
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
|
onWorkflowConfigChange({
|
|
|
|
|
|
...workflowConfig,
|
|
|
|
|
|
syncExecutionTime: e.target.value,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="grid gap-2">
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<span className="text-muted-foreground">异常重试次数</span>
|
2026-04-13 20:28:09 +08:00
|
|
|
|
<Input
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
min={0}
|
|
|
|
|
|
max={5}
|
|
|
|
|
|
value={workflowConfig.retryCount}
|
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
|
onWorkflowConfigChange({
|
|
|
|
|
|
...workflowConfig,
|
|
|
|
|
|
retryCount: Number(e.target.value || 0),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<span>更新后人工确认</span>
|
2026-04-13 20:28:09 +08:00
|
|
|
|
<Button
|
|
|
|
|
|
size="sm"
|
|
|
|
|
|
variant={workflowConfig.manualConfirmSync ? "default" : "outline"}
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
onWorkflowConfigChange({
|
|
|
|
|
|
...workflowConfig,
|
|
|
|
|
|
manualConfirmSync: !workflowConfig.manualConfirmSync,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
|
|
|
|
|
{workflowConfig.manualConfirmSync ? "需要确认" : "自动通过"}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p className="text-xs text-muted-foreground">
|
2026-04-15 17:08:17 +08:00
|
|
|
|
需要确认:周更完成后进入待确认队列,由项目与运维负责人核查差异摘要并手动放行。
|
2026-04-13 20:28:09 +08:00
|
|
|
|
</p>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
|
|
<Card className="border-none shadow-sm bg-white">
|
2026-04-15 17:08:17 +08:00
|
|
|
|
<CardHeader>
|
|
|
|
|
|
<CardTitle className="text-lg font-bold">私有云账号与访问</CardTitle>
|
|
|
|
|
|
<CardDescription>展示平台部署和后台登录的基础准备项。</CardDescription>
|
|
|
|
|
|
</CardHeader>
|
|
|
|
|
|
<CardContent className="space-y-3 text-sm">
|
|
|
|
|
|
<div className="grid gap-2">
|
|
|
|
|
|
<span className="text-muted-foreground">后台访问地址</span>
|
|
|
|
|
|
<Input defaultValue="https://portal.audi-private-cloud.example" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="grid gap-2">
|
|
|
|
|
|
<span className="text-muted-foreground">账号开通原则</span>
|
|
|
|
|
|
<Input defaultValue="按角色开通账号,最小权限访问" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
|
|
|
|
|
<span>专有云环境状态</span>
|
|
|
|
|
|
<Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-200">已纳入部署方案</Badge>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
|
|
<Card className="border-none shadow-sm bg-white">
|
|
|
|
|
|
<CardHeader>
|
|
|
|
|
|
<CardTitle className="text-lg font-bold">导出与迁移准备</CardTitle>
|
|
|
|
|
|
<CardDescription>用于说明内容平台后续迁移到 Audi 其他平台时的交接能力。</CardDescription>
|
|
|
|
|
|
</CardHeader>
|
|
|
|
|
|
<CardContent className="space-y-3 text-sm">
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
|
|
|
|
|
<span>内容全量导出</span>
|
|
|
|
|
|
<Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-200">支持</Badge>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
|
|
|
|
|
<span>素材打包导出</span>
|
|
|
|
|
|
<Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-200">支持</Badge>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3">
|
|
|
|
|
|
<span>配置与日志交接</span>
|
|
|
|
|
|
<Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-200">支持</Badge>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
|
|
<Card className="border-none shadow-sm bg-white">
|
2026-04-13 20:28:09 +08:00
|
|
|
|
<CardHeader>
|
|
|
|
|
|
<CardTitle className="text-lg font-bold">变更与审计</CardTitle>
|
|
|
|
|
|
<CardDescription>展示最近关键操作,用于审核与回溯演示。</CardDescription>
|
|
|
|
|
|
</CardHeader>
|
|
|
|
|
|
<CardContent className="space-y-3">
|
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
|
<Settings2 className="h-4 w-4 text-audi-red" />
|
|
|
|
|
|
<span className="text-sm font-medium">最近 12 条关键变更</span>
|
|
|
|
|
|
<Badge variant="outline" className="ml-auto">
|
|
|
|
|
|
{auditLogs.length} 条
|
|
|
|
|
|
</Badge>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
|
{auditLogs.map((item, idx) => (
|
|
|
|
|
|
<div key={`${item}-${idx}`} className="rounded-lg border px-3 py-2 text-sm text-muted-foreground">
|
|
|
|
|
|
{item}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|