Initial commit
This commit is contained in:
@@ -0,0 +1,288 @@
|
||||
import * as React from "react"
|
||||
import { ShieldCheck, UserCog, Users } from "lucide-react"
|
||||
|
||||
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"
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table"
|
||||
|
||||
type UserStatus = "enabled" | "disabled"
|
||||
|
||||
type UserRecord = {
|
||||
id: string
|
||||
name: string
|
||||
account: string
|
||||
role: "业务/市场负责人" | "内容运营专员" | "项目与运维负责人"
|
||||
status: UserStatus
|
||||
lastLogin: string
|
||||
}
|
||||
|
||||
type PermissionKey =
|
||||
| "dashboard.view"
|
||||
| "source.sync"
|
||||
| "content.edit"
|
||||
| "content.approve"
|
||||
| "content.publish"
|
||||
| "leads.manage"
|
||||
| "settings.manage"
|
||||
| "users.manage"
|
||||
|
||||
type RolePermission = {
|
||||
roleName: "业务/市场负责人" | "内容运营专员" | "项目与运维负责人"
|
||||
permissions: PermissionKey[]
|
||||
}
|
||||
|
||||
const INITIAL_USERS: UserRecord[] = [
|
||||
{
|
||||
id: "u1",
|
||||
name: "陈经理",
|
||||
account: "market.chen",
|
||||
role: "业务/市场负责人",
|
||||
status: "enabled",
|
||||
lastLogin: "2026-04-12 09:18",
|
||||
},
|
||||
{
|
||||
id: "u2",
|
||||
name: "刘运营",
|
||||
account: "content.liu",
|
||||
role: "内容运营专员",
|
||||
status: "enabled",
|
||||
lastLogin: "2026-04-12 08:42",
|
||||
},
|
||||
{
|
||||
id: "u3",
|
||||
name: "王运维",
|
||||
account: "ops.wang",
|
||||
role: "项目与运维负责人",
|
||||
status: "enabled",
|
||||
lastLogin: "2026-04-11 20:05",
|
||||
},
|
||||
{
|
||||
id: "u4",
|
||||
name: "赵测试",
|
||||
account: "qa.zhao",
|
||||
role: "内容运营专员",
|
||||
status: "disabled",
|
||||
lastLogin: "2026-04-01 11:20",
|
||||
},
|
||||
]
|
||||
|
||||
const PERMISSION_LABEL: Record<PermissionKey, string> = {
|
||||
"dashboard.view": "查看仪表盘",
|
||||
"source.sync": "车型同步",
|
||||
"content.edit": "内容编辑",
|
||||
"content.approve": "内容审核",
|
||||
"content.publish": "内容发布",
|
||||
"leads.manage": "潜客管理",
|
||||
"settings.manage": "系统设置",
|
||||
"users.manage": "用户与权限管理",
|
||||
}
|
||||
|
||||
const INITIAL_ROLE_PERMISSIONS: RolePermission[] = [
|
||||
{
|
||||
roleName: "业务/市场负责人",
|
||||
permissions: [
|
||||
"dashboard.view",
|
||||
"content.approve",
|
||||
"content.publish",
|
||||
"leads.manage",
|
||||
],
|
||||
},
|
||||
{
|
||||
roleName: "内容运营专员",
|
||||
permissions: [
|
||||
"dashboard.view",
|
||||
"source.sync",
|
||||
"content.edit",
|
||||
"content.publish",
|
||||
"leads.manage",
|
||||
],
|
||||
},
|
||||
{
|
||||
roleName: "项目与运维负责人",
|
||||
permissions: [
|
||||
"dashboard.view",
|
||||
"source.sync",
|
||||
"settings.manage",
|
||||
"users.manage",
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const PERMISSION_COLUMNS: PermissionKey[] = [
|
||||
"dashboard.view",
|
||||
"source.sync",
|
||||
"content.edit",
|
||||
"content.approve",
|
||||
"content.publish",
|
||||
"leads.manage",
|
||||
"settings.manage",
|
||||
"users.manage",
|
||||
]
|
||||
|
||||
export function UserAccessManagement() {
|
||||
const [query, setQuery] = React.useState("")
|
||||
const [users, setUsers] = React.useState<UserRecord[]>(INITIAL_USERS)
|
||||
const [rolePermissions, setRolePermissions] = React.useState<RolePermission[]>(INITIAL_ROLE_PERMISSIONS)
|
||||
|
||||
const filteredUsers = users.filter((user) => {
|
||||
const key = `${user.name} ${user.account} ${user.role}`.toLowerCase()
|
||||
return key.includes(query.toLowerCase())
|
||||
})
|
||||
|
||||
const toggleUserStatus = (id: string) => {
|
||||
setUsers((prev) =>
|
||||
prev.map((user) =>
|
||||
user.id === id
|
||||
? { ...user, status: user.status === "enabled" ? "disabled" : "enabled" }
|
||||
: user
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const togglePermission = (roleName: RolePermission["roleName"], permission: PermissionKey) => {
|
||||
setRolePermissions((prev) =>
|
||||
prev.map((role) => {
|
||||
if (role.roleName !== roleName) return role
|
||||
const has = role.permissions.includes(permission)
|
||||
return {
|
||||
...role,
|
||||
permissions: has
|
||||
? role.permissions.filter((item) => item !== permission)
|
||||
: [...role.permissions, permission],
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 p-8">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<h1 className="text-3xl font-bold tracking-tight">用户与权限管理</h1>
|
||||
<p className="text-muted-foreground">集中维护账号状态、角色定义与权限边界。</p>
|
||||
</div>
|
||||
<Button className="bg-audi-black hover:bg-audi-dark-gray text-white px-6">新增用户</Button>
|
||||
</div>
|
||||
|
||||
<Card className="border-none shadow-sm bg-white">
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<CardTitle className="text-lg font-bold">用户管理</CardTitle>
|
||||
<CardDescription>管理账号启用状态与角色归属。</CardDescription>
|
||||
</div>
|
||||
<div className="w-full max-w-xs">
|
||||
<Input
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="搜索姓名、账号或角色..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="hover:bg-transparent border-b border-gray-100">
|
||||
<TableHead className="font-bold text-audi-black">姓名</TableHead>
|
||||
<TableHead className="font-bold text-audi-black">账号</TableHead>
|
||||
<TableHead className="font-bold text-audi-black">角色</TableHead>
|
||||
<TableHead className="font-bold text-audi-black">状态</TableHead>
|
||||
<TableHead className="font-bold text-audi-black">最近登录</TableHead>
|
||||
<TableHead className="text-right font-bold text-audi-black">操作</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{filteredUsers.map((user) => (
|
||||
<TableRow key={user.id} className="hover:bg-gray-50/50 border-b border-gray-50 transition-colors">
|
||||
<TableCell className="font-medium">{user.name}</TableCell>
|
||||
<TableCell className="text-muted-foreground">{user.account}</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant="outline">{user.role}</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={
|
||||
user.status === "enabled"
|
||||
? "bg-emerald-50 text-emerald-700 border-emerald-200"
|
||||
: "bg-zinc-100 text-zinc-700 border-zinc-200"
|
||||
}
|
||||
>
|
||||
{user.status === "enabled" ? "启用" : "停用"}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="text-xs text-muted-foreground">{user.lastLogin}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<div className="inline-flex gap-2">
|
||||
<Button size="sm" variant="outline">
|
||||
编辑角色
|
||||
</Button>
|
||||
<Button size="sm" variant="outline" onClick={() => toggleUserStatus(user.id)}>
|
||||
{user.status === "enabled" ? "停用" : "启用"}
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="border-none shadow-sm bg-white">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg font-bold">角色与权限管理</CardTitle>
|
||||
<CardDescription>按角色授予菜单、操作与审批权限(原型可直接勾选)。</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="mb-3 flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<Users className="h-4 w-4" />角色
|
||||
<UserCog className="h-4 w-4 ml-4" />权限
|
||||
<ShieldCheck className="h-4 w-4 ml-4 text-audi-red" />权限边界
|
||||
</div>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="hover:bg-transparent border-b border-gray-100">
|
||||
<TableHead className="font-bold text-audi-black">角色</TableHead>
|
||||
{PERMISSION_COLUMNS.map((permission) => (
|
||||
<TableHead key={permission} className="font-bold text-audi-black text-xs">
|
||||
{PERMISSION_LABEL[permission]}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{rolePermissions.map((role) => (
|
||||
<TableRow key={role.roleName} className="hover:bg-gray-50/50 border-b border-gray-50 transition-colors">
|
||||
<TableCell className="font-medium">{role.roleName}</TableCell>
|
||||
{PERMISSION_COLUMNS.map((permission) => {
|
||||
const checked = role.permissions.includes(permission)
|
||||
return (
|
||||
<TableCell key={`${role.roleName}-${permission}`}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onChange={() => togglePermission(role.roleName, permission)}
|
||||
/>
|
||||
</TableCell>
|
||||
)
|
||||
})}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user