feat: 实现需求管理、加班记录、成员/角色管理模块

- 需求模块:完整 CRUD、状态流转(采纳/拒绝/关闭)、详情抽屉、产品→项目级联选择
- 加班记录:产品→项目→版本三级联动、月份筛选(MonthPicker)、CSV 导出
- 成员管理:左右布局(部门树+成员列表)、手机号脱敏、初始密码自动生成及规则设置
- 角色管理:卡片列表、系统角色保护、CRUD
- 通用组件:FilterSelect 下拉、MonthPicker 月份选择器、Pagination 分页
- 样式统一:状态标签加 border、日期输入现代化、筛选组件风格一致

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Script Generator
2026-06-09 18:16:18 +08:00
parent 24ba61f929
commit 9a0b16a8f1
36 changed files with 4355 additions and 272 deletions

View File

@@ -1,7 +1,7 @@
'use client';
import { usePathname, useRouter } from 'next/navigation';
import { Inbox, Package, FolderKanban, Tag, Users, LayoutGrid, Search } from 'lucide-react';
import { Inbox, Package, FolderKanban, Tag, Users, LayoutGrid, Search, Lightbulb, Clock, Shield } from 'lucide-react';
const NAV_GROUPS = [
{
@@ -11,12 +11,15 @@ const NAV_GROUPS = [
{ label: '产品', path: '/products', icon: Package },
{ label: '项目', path: '/projects', icon: FolderKanban },
{ label: '版本', path: '/versions', icon: Tag },
{ label: '需求', path: '/requirements', icon: Lightbulb },
{ label: '加班记录', path: '/overtime', icon: Clock },
],
},
{
label: '管理',
items: [
{ label: '成员', path: '/admin/members', icon: Users },
{ label: '角色', path: '/admin/roles', icon: Shield },
],
},
];
@@ -34,7 +37,7 @@ export function Sidebar() {
<div className="flex h-7 w-7 items-center justify-center rounded-lg bg-[var(--accent)]">
<LayoutGrid className="h-4 w-4 text-white" strokeWidth={2.25} />
</div>
<span className="text-[14px] font-semibold tracking-tight text-[var(--ink)]">FTB</span>
<span className="text-[13px] font-semibold tracking-tight text-[var(--ink)]">FTB</span>
</div>
<div className="px-3 pb-2">
@@ -42,7 +45,7 @@ export function Sidebar() {
<Search className="pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-[var(--ink-muted)]" strokeWidth={2} />
<input
placeholder="搜索"
className="h-8 w-full rounded-lg border border-[var(--line)] bg-[var(--bg-subtle)] pl-8 pr-2 text-[12.5px] text-[var(--ink)] placeholder:text-[var(--ink-muted)] focus:border-[var(--accent)] focus:bg-[var(--bg-card)] focus:outline-none focus:ring-2 focus:ring-[var(--accent-ring)]"
className="h-8 w-full rounded-lg border border-[var(--line)] bg-[var(--bg-subtle)] pl-8 pr-2 text-[13px] text-[var(--ink)] placeholder:text-[var(--ink-muted)] focus:border-[var(--accent)] focus:bg-[var(--bg-card)] focus:outline-none focus:ring-2 focus:ring-[var(--accent-ring)]"
/>
</div>
</div>