diff --git a/docs/Precision-Atelier设计系统改造记录.md b/docs/Precision-Atelier设计系统改造记录.md index 2dae1627..0abbf8e0 100644 --- a/docs/Precision-Atelier设计系统改造记录.md +++ b/docs/Precision-Atelier设计系统改造记录.md @@ -241,14 +241,40 @@ - **背景文字装饰**:绝对定位的 `text-[80px]` 背景大字(如模块 path),设置 `opacity-[0.03]` 极低透明度,增加“空间感”。 **4. 状态指标看板 (System Health Dashboard)** -- **应用场景**:`/admin` 首页。 -- **组成**:Icon 容器 + 上下两行文本(上行为微缩标签,下行为状态值)。 -- **配色**:动态使用 `emerald-500` (正常), `blue-500` (活动), `amber-500` (注意)。 +- 应用场景:`/admin` 首页。 +- 组成:Icon 容器 + 上下两行文本(上行为微缩标签,下行为状态值)。 +- 配色:动态使用 `emerald-500` (正常), `blue-500` (活动), `amber-500` (注意)。 + +**5. 三栏工作区 (Three-Column Workspace)** +- 应用场景:`/asset-center/material-library`。 +- 定义:左侧极简分类 (Navigation) + 中间响应式网格 (Grid) + 右侧实时定义面板 (Inspector)。 +- 优势:极大降低页面跳转成本,实现“即时反馈”。 + +**6. 精密滑块交互 (Precision Sliders)** +- 视觉表现:细条轨道 + 圆形 Thumb + 右侧数值百分比徽章。 +- 应用场景:物理参数调节 (Metallic/Roughness/Opacity)。 +- 规范:取代原有的输入框,滑动步长固定为 0.01 (1%)。 + +**7. 悬浮坞系统 (Floating Dock System)** +- 应用场景:`/assisted-assembly`。 +- 定义:左侧布局的交互式入口,采用 `bg-black/60` + `backdrop-blur-3xl`。 +- 动效:点击后向右水平展开列表。 +- 逻辑:通过视觉发光 (Glow) 和计数徽标反馈当前分类的选择状态。 + +**8. 环境 HUD (Ambient HUD)** +- 定义:底部的非侵入式信息条。 +- 样式:极圆胶囊型,`backdrop-blur-xl`。 +- 作用:提供当前操作环境的实时状态(如“捕捉已就绪”)。 ### 11. 改动文件清单 | 文件 | 改动类型 | 备注 | |------|----------|------| -| `src/app/admin/page.tsx` | 重构 | 系统总控制台首页视觉重写 | -| `src/app/users/page.tsx` | 重构 | 身份控制中心 (用户管理) 视觉重写 | +| `src/app/admin/page.tsx` | 重构 | 系统总控制台首页视觉重载 | +| `src/app/users/page.tsx` | 重构 | 身份控制中心 (用户管理) 三栏重写 | +| `src/app/asset-center/material-library/MaterialLibraryClient.tsx` | 重构 | 材质库首页视觉重写 (草稿图 12.png) | +| `src/app/assisted-assembly/AssistedAssemblyClient.tsx` | 重构 | 拼装工作台沉浸式重写 & 引入 Floating Dock | +| `src/components/platform/PlatformSplitLayout.tsx` | 基础重构 | 统一加装 backHref 导航标准 | + + diff --git a/docs/前端UI改动清单.md b/docs/前端UI改动清单.md index 3263b66a..c7075dc2 100644 --- a/docs/前端UI改动清单.md +++ b/docs/前端UI改动清单.md @@ -6,16 +6,42 @@ - **重构页面**: - `系统总控制台 (/admin)`:引入“中枢枢纽”布局,增加系统状态看板 (Mock),优化卡片视觉张力。 - `身份控制中心 (/users)`:引入“沉浸式页头”与“精密控制条”,整合搜索与筛选器。 - - **核心特性**: - - **Frosted Glass (磨砂玻璃)**:全局背景与卡片采用 70% 透明度 + 30px 模糊。 - - **Visual Hierarchy (视觉层级)**:通过大面积阴影与精致边框区分功能模块。 - - **Typography (排版)**:强化了 Manrope 标题与 Inter 技术标签的对比。 - **负责人**:Gemini UI Engineer - **完成日期**:2026-04-16 +- **基础资料库重构 (Material Library Pro Refactor)** + - **参考稿**:基于用户草稿 (12.png) 与 Precision Atelier 规范。 + - **核心改动**: + - **三栏架构**:左侧分类 - 中间网格 - 右侧实时工作区。 + - **实时预览 (Real-time Preview)**:面板顶部集成大面积材质物理表现预览。 + - **精密滑块 (Precision Sliders)**:金属度、粗糙度、透明度全部由 Input 切换为 Slider 交互。 + - **网格升级**:优化了花色卡片的视觉尺寸与 Metadata(元数据)展示。 + - **负责人**:Gemini UI Engineer + - **完成日期**:2026-04-16 + +- **辅助装配工作台沉浸式重构 (Assisted Assembly Workbench Immersive Refactor)** + - **重构页面**:`辅助装配工作台 (/assisted-assembly)`。 + - **核心改动**: + - **沉浸式 3D 画布**:移除所有边框,采用 `#0c0e10` 深邃背景,占据 100% 中心区域。 + - **悬浮 Dock 系统 (Floating Dock)**:左侧零件选择改为三个磨砂玻璃质感的悬浮坞(板件/支撑/连接件),支持平滑展开与计数反馈。 + - **实时装配报告 (Inspector)**:右侧面板重塑为技术报告风格,展示拓扑节点、已连接对数及结构稳固性指标。 + - **环境提示条 (Ambient HUD)**:底部增加半透明环境信息条,提示“孔位捕捉已就绪”。 + - **导航标准化**:加装“资产中心 / 拼装”精密返回按钮。 + - **负责人**:Gemini UI Engineer + - **完成日期**:2026-04-17 + + + --- ## 进行中任务 (In Progress) - assisted-assembly(辅助装配):真实样本联调与验收 - 负责人:Codex + - 当前进展: + - 已补回孔位吸附的真实距离闸门,避免组件离目标过远时仍被误判为可吸附。 + - 已移除缺少孔位 / 安装图样语义时回退到旧中心点假吸附的旧逻辑。 + - 已将右侧提示收口为状态反馈卡,可区分“已进入吸附范围 / 缺少安装图样语义 / 缺少孔位语义”等状态。 + - 已补齐辅助装配工作台与装配规则层回归测试,并通过 `jest(测试)` 与 `type-check(类型检查)`。 + - 待完成: + - 用真实样本在浏览器里完成最终点验,确认拖拽、预吸附、松手吸附与右侧提示在真实模型下都一致。 diff --git a/furniture-3d-system/prisma/migrations/20260417113000_simplify_user_roles_and_pending_activation/migration.sql b/furniture-3d-system/prisma/migrations/20260417113000_simplify_user_roles_and_pending_activation/migration.sql new file mode 100644 index 00000000..cadda9f7 --- /dev/null +++ b/furniture-3d-system/prisma/migrations/20260417113000_simplify_user_roles_and_pending_activation/migration.sql @@ -0,0 +1,19 @@ +CREATE TYPE "Role_new" AS ENUM ('SUPER_ADMIN', 'ADMIN', 'SUPERVISOR', 'DESIGNER', 'USER'); + +ALTER TABLE "User" ALTER COLUMN "role" DROP DEFAULT; + +ALTER TABLE "User" +ALTER COLUMN "role" TYPE "Role_new" +USING ( + CASE + WHEN "role"::text = 'VIEWER' THEN 'USER' + WHEN "role"::text IN ('DEPARTMENT_MANAGER', 'TEAM_LEADER') THEN 'SUPERVISOR' + ELSE "role"::text + END +)::"Role_new"; + +DROP TYPE "Role"; +ALTER TYPE "Role_new" RENAME TO "Role"; + +ALTER TABLE "User" ALTER COLUMN "role" SET DEFAULT 'USER'; +ALTER TABLE "User" ALTER COLUMN "status" SET DEFAULT 'PENDING'; diff --git a/furniture-3d-system/prisma/schema.prisma b/furniture-3d-system/prisma/schema.prisma index 7f044e56..8049df33 100644 --- a/furniture-3d-system/prisma/schema.prisma +++ b/furniture-3d-system/prisma/schema.prisma @@ -920,10 +920,9 @@ model PackagedItem { enum Role { SUPER_ADMIN // 超级管理员 ADMIN // 管理员 - DEPARTMENT_MANAGER // 部门管理员 - TEAM_LEADER // 组长 + SUPERVISOR // 主管(按部门/小组管理锚点区分范围) DESIGNER // 设计师 - VIEWER // 查看者 + USER // 普通用户 } // 用户状态枚举 @@ -998,7 +997,7 @@ model User { phone String? // 角色与权限 - role Role @default(DESIGNER) + role Role @default(USER) // 组织架构 departmentId String? @@ -1012,7 +1011,7 @@ model User { managedTeam Team? @relation("TeamLeader") // 状态 - status UserStatus @default(ACTIVE) + status UserStatus @default(PENDING) // 关联 createdProducts Product[] @relation("ProductCreator") diff --git a/furniture-3d-system/prisma/seed.ts b/furniture-3d-system/prisma/seed.ts index 050514be..6c0797a2 100644 --- a/furniture-3d-system/prisma/seed.ts +++ b/furniture-3d-system/prisma/seed.ts @@ -365,7 +365,7 @@ async function main() { email: 'design.manager@furniture3d.com', name: '张设计', password: hashedPassword, - role: 'DEPARTMENT_MANAGER', + role: 'SUPERVISOR', departmentId: designDept.id, isFirstLogin: false, status: 'ACTIVE', @@ -383,7 +383,7 @@ async function main() { email: 'modeling.leader@furniture3d.com', name: '李组长', password: hashedPassword, - role: 'TEAM_LEADER', + role: 'SUPERVISOR', departmentId: design3DDept.id, teamId: modelingTeam.id, isFirstLogin: false, diff --git a/furniture-3d-system/scripts/run-type-check.js b/furniture-3d-system/scripts/run-type-check.js index 39f034d5..986a71bc 100644 --- a/furniture-3d-system/scripts/run-type-check.js +++ b/furniture-3d-system/scripts/run-type-check.js @@ -5,6 +5,7 @@ const { spawn } = require('child_process') const repoRoot = process.cwd() const nextBin = path.join(repoRoot, 'node_modules', 'next', 'dist', 'bin', 'next') const tscBin = path.join(repoRoot, 'node_modules', 'typescript', 'bin', 'tsc') +const tsconfigPath = path.join(repoRoot, 'tsconfig.json') function run(command, args) { return new Promise((resolve, reject) => { @@ -25,30 +26,6 @@ function run(command, args) { }) } -async function collectTypeFiles(dirPath) { - try { - const entries = await fs.readdir(dirPath, { withFileTypes: true }) - const files = await Promise.all( - entries.map(async (entry) => { - const fullPath = path.join(dirPath, entry.name) - if (entry.isDirectory()) { - return collectTypeFiles(fullPath) - } - - if (entry.name.endsWith('.ts') || entry.name.endsWith('.d.ts')) { - return [fullPath] - } - - return [] - }), - ) - - return files.flat() - } catch { - return [] - } -} - async function ensureNextCacheLifeStub() { const candidatePaths = [ path.join(repoRoot, '.next', 'types', 'cache-life.d.ts'), @@ -66,36 +43,10 @@ async function ensureNextCacheLifeStub() { } } -async function createTypeCheckTsconfig() { - const tsconfigPath = path.join(repoRoot, 'tsconfig.json') - const rawConfig = await fs.readFile(tsconfigPath, 'utf8') - const baseConfig = JSON.parse(rawConfig) - const generatedTypeFiles = [ - ...(await collectTypeFiles(path.join(repoRoot, '.next', 'types'))), - ...(await collectTypeFiles(path.join(repoRoot, '.next', 'dev', 'types'))), - ] - .map((filePath) => path.relative(repoRoot, filePath).replace(/\\/g, '/')) - .sort() - - const tempConfigPath = path.join(repoRoot, 'tsconfig.typecheck.generated.json') - const tempConfig = { - ...baseConfig, - include: (baseConfig.include || []).filter( - (entry) => typeof entry === 'string' && !entry.startsWith('.next/'), - ), - exclude: Array.from(new Set([...(baseConfig.exclude || []), '.next'])), - files: generatedTypeFiles.length > 0 ? generatedTypeFiles : undefined, - } - - await fs.writeFile(tempConfigPath, JSON.stringify(tempConfig, null, 2), 'utf8') - return tempConfigPath -} - async function main() { await run(process.execPath, [nextBin, 'typegen']) await ensureNextCacheLifeStub() - const tempConfigPath = await createTypeCheckTsconfig() - await run(process.execPath, [tscBin, '-p', tempConfigPath, '--noEmit', '--incremental', 'false']) + await run(process.execPath, [tscBin, '-p', tsconfigPath, '--noEmit', '--incremental', 'false']) } main().catch((error) => { diff --git a/furniture-3d-system/src/app/admin/page.tsx b/furniture-3d-system/src/app/admin/page.tsx index 5a0f537d..1e7a1eba 100644 --- a/furniture-3d-system/src/app/admin/page.tsx +++ b/furniture-3d-system/src/app/admin/page.tsx @@ -2,11 +2,13 @@ import Link from 'next/link' import { cookies } from 'next/headers' import { redirect } from 'next/navigation' import { - Users, Palette, SwatchBook, Grid, ArrowRight, - ShieldCheck, Activity, Database, Zap, type LucideIcon + Users, Palette, SwatchBook, Grid, ArrowLeft, ArrowRight, + ShieldCheck, Activity, Database, Zap, Clock, + Cpu, Terminal, ShieldAlert, BarChart3 } from 'lucide-react' import { cn } from '@/lib/utils' import { verifyToken } from '@/lib/jwt' +import Button from '@/components/ui/Button' const adminModules = [ { @@ -17,7 +19,7 @@ const adminModules = [ icon: Users, color: 'text-blue-600', bgColor: 'bg-blue-50', - accentColor: 'group-hover:bg-blue-600', + stats: '1,248 Users Active', }, { title: '主题视觉管理', @@ -27,7 +29,7 @@ const adminModules = [ icon: Palette, color: 'text-indigo-600', bgColor: 'bg-indigo-50', - accentColor: 'group-hover:bg-indigo-600', + stats: '12 Active Themes', }, { title: '材质物理库', @@ -37,7 +39,7 @@ const adminModules = [ icon: SwatchBook, color: 'text-emerald-600', bgColor: 'bg-emerald-50', - accentColor: 'group-hover:bg-emerald-600', + stats: '450+ Materials', }, { title: '分类体系定义', @@ -47,130 +49,167 @@ const adminModules = [ icon: Grid, color: 'text-amber-600', bgColor: 'bg-amber-50', - accentColor: 'group-hover:bg-amber-600', + stats: '32 Categories', }, ] export const metadata = { - title: '管理总控制台 | Precision Atelier', - description: '后台管理总入口', + title: '系统总控制台 | Precision Atelier', } export default async function AdminPortalPage() { const cookieStore = await cookies() const token = cookieStore.get('auth-token')?.value - if (!token) { - redirect('/login?redirect=/admin') - } - + if (!token) redirect('/login?redirect=/admin') const payload = verifyToken(token) - if (!payload) { - redirect('/login?redirect=/admin') - } + if (!payload) redirect('/login?redirect=/admin') const allowedRoles = ['SUPER_ADMIN', 'ADMIN'] - if (!allowedRoles.includes(payload.role)) { - redirect('/?error=unauthorized') - } + if (!allowedRoles.includes(payload.role)) redirect('/?error=unauthorized') return ( -
- {/* 增强型背景装饰 */} +
+ {/* 沉浸式背景背景 */}
-
-
-
+
+
+
-
- {/* 顶部状态栏 Concept */} -
-
-
- -
-
- - System Infrastructure - -

- 管理控制中心 -

-
-
- -
- - - -
-
- - {/* 核心功能网格 */} -
- {adminModules.map((module) => ( - -
-
- -
-
- +
+ {/* Header Section */} +
+
+
+ + + +
+ +
+
- -
- - {module.subtitle} +
+
+
+ + Precision Master Console -

- {module.title} -

-

- {module.description} -

+
+
+

+ 系统总控制台 +

+

+ 集成式基础设施管理中心 · 实时监控系统运行状态与核心资产分发 +

+
+
+ + +
+ + + +
+
+ +
+ {/* Left: Core Modules (8 Columns) */} +
+
+ {adminModules.map((module, idx) => ( + +
+
+ +
+
+ +
+
+ +
+ + {module.subtitle} + +

+ {module.title} +

+

+ {module.description} +

+
+ + {/* Footer Stats inside card */} +
+ {module.stats} + ENTER CENTER +
+ + + {module.href.split('/').pop()} + + + ))} +
+
+ + {/* Right: System Health & Logs (4 Columns) */} +
+
+
+

System Health

+ +
+ +
+ + + + +
+ +
+
+ +
+ 安全提示 + 发现 2 个未挂载的材质分区 +
+
+
- {/* 背景装饰性文字 */} - - {module.href.split('/').pop()} - - - {/* 装饰线 */} -
- - ))} +
+
+

Live Logs

+ +
+
+ + + + +
+
+
- {/* 底部脚注 */} -