ec-nest/prisma/schema.prisma
liuyun 6f32875295 feat(c0): 服务机构端基础数据模型(9 表 + 多租户/软删清单)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 12:36:43 +08:00

448 lines
17 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 通用系统管理脚手架 (sysmgr) 数据模型
// 约定:表名 sys_ 前缀;列 snake_case(模型 camelCase + @map);业务键关联(角色/资源/组织/字典/租户用 code,用户用 id)。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
/// 租户
model Tenant {
id String @id @default(uuid(7)) @db.VarChar(36)
code String @unique @db.VarChar(64)
name String @db.VarChar(128)
status String @default("enabled") @db.VarChar(16)
remark String? @db.VarChar(255)
brandName String? @map("brand_name") @db.VarChar(64)
logoUrl String? @map("logo_url") @db.VarChar(255)
themeColor String? @map("theme_color") @db.VarChar(16)
copyright String? @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
@@map("sys_tenant")
}
/// 用户
model User {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
username String @db.VarChar(64)
passwordHash String @map("password_hash") @db.VarChar(255)
nickname String? @db.VarChar(64)
email String? @db.VarChar(128)
phone String? @db.VarChar(32)
avatar String? @db.VarChar(255)
status String @default("enabled") @db.VarChar(16)
tokenVersion Int @default(0) @map("token_version")
lockedAt DateTime? @map("locked_at")
lockReason String? @map("lock_reason") @db.VarChar(255)
mustChangePassword Boolean @default(false) @map("must_change_password")
orgCode String? @map("org_code") @db.VarChar(64)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@unique([tenantCode, username])
@@index([tenantCode])
@@index([orgCode])
@@map("sys_user")
}
/// 角色
model Role {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
code String @db.VarChar(64)
name String @db.VarChar(64)
dataScope String @default("all") @map("data_scope") @db.VarChar(16)
status String @default("enabled") @db.VarChar(16)
remark String? @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@unique([tenantCode, code])
@@index([tenantCode])
@@map("sys_role")
}
/// 资源(菜单/按钮/接口)
model Resource {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
parentCode String? @map("parent_code") @db.VarChar(64)
type String @db.VarChar(16)
code String @db.VarChar(128)
name String @db.VarChar(64)
path String? @db.VarChar(255)
component String? @db.VarChar(255)
method String? @db.VarChar(8)
apiPath String? @map("api_path") @db.VarChar(255)
icon String? @db.VarChar(64)
sort Int @default(0)
status String @default("enabled") @db.VarChar(16)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@unique([tenantCode, code])
@@index([tenantCode])
@@index([parentCode])
@@map("sys_resource")
}
/// 组织
model Org {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
parentCode String? @map("parent_code") @db.VarChar(64)
code String @db.VarChar(64)
name String @db.VarChar(64)
leader String? @db.VarChar(64)
sort Int @default(0)
status String @default("enabled") @db.VarChar(16)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@unique([tenantCode, code])
@@index([tenantCode])
@@index([parentCode])
@@map("sys_org")
}
/// 字典类型
model DictType {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
code String @db.VarChar(64)
name String @db.VarChar(64)
status String @default("enabled") @db.VarChar(16)
builtIn Boolean @default(false) @map("built_in")
remark String? @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@unique([tenantCode, code])
@@index([tenantCode])
@@map("sys_dict_type")
}
/// 字典项
model DictItem {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
dictTypeCode String @map("dict_type_code") @db.VarChar(64)
label String @db.VarChar(64)
value String @db.VarChar(64)
sort Int @default(0)
status String @default("enabled") @db.VarChar(16)
builtIn Boolean @default(false) @map("built_in")
colorType String? @map("color_type") @db.VarChar(16)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@unique([tenantCode, dictTypeCode, value])
@@index([tenantCode, dictTypeCode])
@@map("sys_dict_item")
}
/// 参数配置
model Config {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
key String @db.VarChar(128)
value String? @db.Text
remark String? @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@unique([tenantCode, key])
@@map("sys_config")
}
/// 操作日志(只增,硬删)
model AuditLog {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
userId String? @map("user_id") @db.VarChar(36)
username String? @db.VarChar(64)
module String? @db.VarChar(64)
action String? @db.VarChar(64)
method String? @db.VarChar(8)
path String? @db.VarChar(255)
params String? @db.Text
result String? @db.Text
status String? @db.VarChar(16)
errorMessage String? @map("error_message") @db.Text
ip String? @db.VarChar(64)
userAgent String? @map("user_agent") @db.VarChar(255)
durationMs Int? @map("duration_ms")
createdAt DateTime @default(now()) @map("created_at")
@@index([tenantCode, createdAt])
@@map("sys_audit_log")
}
/// 登录日志(只增,硬删)
model LoginLog {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
username String? @db.VarChar(64)
ip String? @db.VarChar(64)
userAgent String? @map("user_agent") @db.VarChar(255)
status String @default("success") @db.VarChar(16)
message String? @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at")
@@index([tenantCode, createdAt])
@@map("sys_login_log")
}
/// 刷新令牌(会话载体,硬删)
model RefreshToken {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
userId String @map("user_id") @db.VarChar(36)
sid String? @db.VarChar(36)
jti String @unique @db.VarChar(64)
tokenHash String @map("token_hash") @db.VarChar(255)
ip String? @db.VarChar(64)
userAgent String? @map("user_agent") @db.VarChar(255)
loginAt DateTime @default(now()) @map("login_at")
expireAt DateTime @map("expire_at")
revokedAt DateTime? @map("revoked_at")
createdAt DateTime @default(now()) @map("created_at")
@@index([tenantCode, userId])
@@index([sid])
@@map("sys_refresh_token")
}
/// 通知/公告
model Notice {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
title String @db.VarChar(128)
content String @db.Text
status String @default("enabled") @db.VarChar(16)
createdBy String? @map("created_by") @db.VarChar(36)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@index([tenantCode])
@@map("sys_notice")
}
/// 通知已读追踪
model NoticeRead {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
noticeId String @map("notice_id") @db.VarChar(36)
userId String @map("user_id") @db.VarChar(36)
readAt DateTime @default(now()) @map("read_at")
@@unique([tenantCode, noticeId, userId])
@@index([tenantCode, userId])
@@map("sys_notice_read")
}
/// 用户-角色关联
model UserRole {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
userId String @map("user_id") @db.VarChar(36)
roleCode String @map("role_code") @db.VarChar(64)
@@unique([tenantCode, userId, roleCode])
@@index([tenantCode, userId])
@@map("sys_user_role")
}
/// 角色-资源关联
model RoleResource {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
roleCode String @map("role_code") @db.VarChar(64)
resourceCode String @map("resource_code") @db.VarChar(128)
@@unique([tenantCode, roleCode, resourceCode])
@@index([tenantCode, roleCode])
@@map("sys_role_resource")
}
/// 角色-组织关联(数据权限「自定义」)
model RoleOrg {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
roleCode String @map("role_code") @db.VarChar(64)
orgCode String @map("org_code") @db.VarChar(64)
@@unique([tenantCode, roleCode, orgCode])
@@map("sys_role_org")
}
/// 机构(=租户的业务信息,1:1 于 Tenant,code 与 tenant.code 同值)
model Agency {
code String @id @db.VarChar(64)
orgName String @map("org_name") @db.VarChar(100)
orgType String @map("org_type") @db.VarChar(20)
creditCode String @map("credit_code") @db.VarChar(18)
locCode String @map("loc_code") @db.VarChar(12)
locName String @map("loc_name") @db.VarChar(50)
svcSource String @map("svc_source") @db.VarChar(10)
licenseNo String? @map("license_no") @db.VarChar(50)
address String @map("address") @db.VarChar(200)
contactName String @map("contact_name") @db.VarChar(30)
contactPhone String @map("contact_phone") @db.VarChar(15)
bedCount Int? @map("bed_count")
signDate DateTime? @map("sign_date") @db.Date
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@map("sys_agency")
}
/// 人员(护理员/医护/组长,账号在 User,staff.user_id 关联 user.id)
model Staff {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
userId String? @unique @map("user_id") @db.VarChar(36)
name String @db.VarChar(30)
idCardNo String @map("id_card_no") @db.VarChar(255)
personCode String? @map("person_code") @db.VarChar(20)
phone String @db.VarChar(15)
jobType String @map("job_type") @db.VarChar(20)
workType String @map("work_type") @db.VarChar(10)
entryDate DateTime? @map("entry_date") @db.Date
leaveDate DateTime? @map("leave_date") @db.Date
employStatus String @map("employ_status") @db.VarChar(10)
certType String? @map("cert_type") @db.VarChar(20)
certNo String? @map("cert_no") @db.VarChar(50)
certLevel String? @map("cert_level") @db.VarChar(20)
certExpire DateTime? @map("cert_expire") @db.Date
certStatus String? @map("cert_status") @db.VarChar(20)
certVerifyUrl String? @map("cert_verify_url") @db.VarChar(200)
groupLeaderId String? @map("group_leader_id") @db.VarChar(36)
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@index([tenantCode, name])
@@map("sys_staff")
}
/// 国家基准库 L1(全局,36 项)
model SvcNational {
id String @id @default(uuid(7)) @db.VarChar(36)
natCode String @unique @map("nat_code") @db.VarChar(20)
natName String @map("nat_name") @db.VarChar(100)
natCategory String @map("nat_category") @db.VarChar(20)
natSubCategory String? @map("nat_sub_category") @db.VarChar(50)
recommendStaff String? @map("recommend_staff") @db.VarChar(50)
recommendDuration String? @map("recommend_duration") @db.VarChar(50)
isMedical Boolean @default(false) @map("is_medical")
version Int @default(1)
@@map("sys_svc_national")
}
/// 属地目录 L2(全局,昆明 45 项 / 州市引用 L1)
model SvcLocal {
id String @id @default(uuid(7)) @db.VarChar(36)
locCode String @map("loc_code") @db.VarChar(12)
localItemName String @map("local_item_name") @db.VarChar(100)
localCategory String? @map("local_category") @db.VarChar(20)
svcTime String? @map("svc_time") @db.VarChar(50)
minFreq String? @map("min_freq") @db.VarChar(50)
staffQual String? @map("staff_qual") @db.VarChar(50)
isMedical Boolean @default(false) @map("is_medical")
sourceDoc String? @map("source_doc") @db.VarChar(200)
mapStatus String @default("mapped") @map("map_status") @db.VarChar(20)
@@index([locCode])
@@map("sys_svc_local")
}
/// 属地↔国家映射 L3(全局,机构不可见)
model SvcMapping {
id String @id @default(uuid(7)) @db.VarChar(36)
locId String @map("loc_id") @db.VarChar(36)
natId String? @map("nat_id") @db.VarChar(36)
mapType String @map("map_type") @db.VarChar(20)
mapNote String? @map("map_note") @db.VarChar(200)
status String @default("confirmed") @db.VarChar(20)
@@index([locId])
@@map("sys_svc_mapping")
}
/// 机构项目库 L4(租户级:机构勾选+配价)
model SvcOrg {
id String @id @default(uuid(7)) @db.VarChar(36)
tenantCode String @map("tenant_code") @db.VarChar(64)
srcType String @map("src_type") @db.VarChar(10)
srcId String @map("src_id") @db.VarChar(36)
isEnabled Boolean @default(true) @map("is_enabled")
price String? @map("price") @db.VarChar(50)
priceEffective DateTime? @map("price_effective")
isNewNational Boolean @default(false) @map("is_new_national")
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by") @db.VarChar(36)
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@index([tenantCode, srcType])
@@map("sys_svc_org")
}
/// 异常分类字典(全局)
model DictAbnormalType {
id String @id @default(uuid(7)) @db.VarChar(36)
code String @unique @db.VarChar(50)
name String @db.VarChar(50)
sort Int @default(0)
@@map("sys_dict_abnormal_type")
}
/// 拍照分档字典(全局)
model DictPhotoTier {
id String @id @default(uuid(7)) @db.VarChar(36)
code String @unique @db.VarChar(20)
name String @db.VarChar(50)
tier String @db.VarChar(10)
@@map("sys_dict_photo_tier")
}
/// 统筹区配置(全局)
model LocConfig {
locCode String @id @map("loc_code") @db.VarChar(12)
locName String @map("loc_name") @db.VarChar(50)
svcSource String @map("svc_source") @db.VarChar(10)
itemCountRule String? @map("item_count_rule") @db.VarChar(100)
@@map("sys_loc_config")
}