chore: sync marketing pages, CMS extensions, tests and project docs
同步工作区剩余变更,主要包括: - 营销页面组件与布局持续优化(about/news/services/solutions/team 等) - 详情页四层叙事组件、布局组件、UI 组件调整 - CMS 数据模型、API 路由、权限、工作流、站内通知、媒体管理扩展 - 新增/补充单元测试与 E2E 测试(cms-workflow.spec.ts 等) - ESLint 9 迁移、jest/tsconfig 配置更新、依赖调整 - 新增 ADR、CMS 评估文档、Release Review / Acceptance 报告 - 移除水墨装饰组件与大体积未使用字体文件
This commit is contained in:
+99
-54
@@ -8,69 +8,100 @@ datasource db {
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ============ 用户与认证 ============
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
username String @unique
|
||||
id String @id @default(cuid())
|
||||
username String @unique
|
||||
password String
|
||||
nickname String @default("")
|
||||
avatar String @default("")
|
||||
email String @default("")
|
||||
phone String @default("")
|
||||
status Int @default(1) // 1=正常, 0=禁用
|
||||
role String @default("admin") // admin | editor
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
nickname String @default("")
|
||||
avatar String @default("")
|
||||
email String @default("")
|
||||
phone String @default("")
|
||||
status Int @default(1)
|
||||
role String @default("admin")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
roles UserRole[]
|
||||
}
|
||||
|
||||
// ============ 内容模型定义 ============
|
||||
model Role {
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
name String
|
||||
description String @default("")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
permissions Permission[]
|
||||
users UserRole[]
|
||||
}
|
||||
|
||||
model Permission {
|
||||
id String @id @default(cuid())
|
||||
roleCode String
|
||||
modelCode String
|
||||
action String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
role Role @relation(fields: [roleCode], references: [code], onDelete: Cascade)
|
||||
|
||||
@@unique([roleCode, modelCode, action])
|
||||
@@index([modelCode])
|
||||
@@index([action])
|
||||
}
|
||||
|
||||
model UserRole {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
roleCode String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
role Role @relation(fields: [roleCode], references: [code], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, roleCode])
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
model ContentModel {
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
name String
|
||||
description String @default("")
|
||||
fields String // JSON: FieldDefinition[]
|
||||
isPageType Boolean @default(false)
|
||||
urlPattern String @default("")
|
||||
hasVersions Boolean @default(false)
|
||||
hasDraft Boolean @default(false)
|
||||
icon String @default("")
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
description String @default("")
|
||||
fields String
|
||||
isPageType Boolean @default(false)
|
||||
urlPattern String @default("")
|
||||
hasVersions Boolean @default(false)
|
||||
hasDraft Boolean @default(false)
|
||||
icon String @default("")
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
items ContentItem[]
|
||||
}
|
||||
|
||||
// ============ 内容条目 ============
|
||||
|
||||
model ContentItem {
|
||||
id String @id @default(cuid())
|
||||
id String @id @default(cuid())
|
||||
modelId String
|
||||
modelCode String
|
||||
title String
|
||||
slug String @default("")
|
||||
status String @default("draft") // draft | published | archived
|
||||
data String // JSON: Record<string, unknown>
|
||||
version Int @default(1)
|
||||
sortOrder Int @default(0)
|
||||
slug String @default("")
|
||||
locale String @default("zh-CN")
|
||||
status String @default("draft")
|
||||
data String
|
||||
version Int @default(1)
|
||||
sortOrder Int @default(0)
|
||||
publishedAt DateTime?
|
||||
createdBy String @default("system")
|
||||
updatedBy String @default("system")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
createdBy String @default("system")
|
||||
updatedBy String @default("system")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
model ContentModel @relation(fields: [modelId], references: [id])
|
||||
|
||||
@@unique([modelCode, slug])
|
||||
@@unique([modelCode, slug, locale])
|
||||
@@index([modelCode])
|
||||
@@index([status])
|
||||
@@index([locale])
|
||||
}
|
||||
|
||||
// ============ 内容区域 ============
|
||||
|
||||
model ContentZone {
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
@@ -78,17 +109,15 @@ model ContentZone {
|
||||
description String @default("")
|
||||
pageCode String @default("")
|
||||
zoneKey String @default("")
|
||||
allowedModels String @default("[]") // JSON: string[]
|
||||
items String @default("[]") // JSON: ContentZoneItem[]
|
||||
settings String @default("{}") // JSON: ContentZoneSettings
|
||||
allowedModels String @default("[]")
|
||||
items String @default("[]")
|
||||
settings String @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([pageCode])
|
||||
}
|
||||
|
||||
// ============ 媒体资源 ============
|
||||
|
||||
model MediaAsset {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
@@ -99,22 +128,38 @@ model MediaAsset {
|
||||
width Int @default(0)
|
||||
height Int @default(0)
|
||||
alt String @default("")
|
||||
storageType String @default("local") // local | oss | s3
|
||||
storageType String @default("local")
|
||||
derivatives String @default("{}")
|
||||
createdBy String @default("system")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ============ 操作日志 ============
|
||||
model Notification {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
type String
|
||||
title String
|
||||
message String
|
||||
relatedItemId String @default("")
|
||||
relatedModelCode String @default("")
|
||||
read Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
@@index([read])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
model AuditLog {
|
||||
id String @id @default(cuid())
|
||||
module String // model | item | zone | theme | media
|
||||
module String
|
||||
targetId String
|
||||
action String // create | update | delete | publish | unpublish
|
||||
action String
|
||||
operator String
|
||||
beforeData String @default("{}") // JSON
|
||||
afterData String @default("{}") // JSON
|
||||
beforeData String @default("{}")
|
||||
afterData String @default("{}")
|
||||
ip String @default("")
|
||||
userAgent String @default("")
|
||||
createdAt DateTime @default(now())
|
||||
@@ -122,4 +167,4 @@ model AuditLog {
|
||||
@@index([module])
|
||||
@@index([targetId])
|
||||
@@index([createdAt])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user