diff --git a/prisma/migrations/20261014043411_c0_base/migration.sql b/prisma/migrations/20261014043411_c0_base/migration.sql new file mode 100644 index 0000000..a3ab138 --- /dev/null +++ b/prisma/migrations/20261014043411_c0_base/migration.sql @@ -0,0 +1,150 @@ +-- CreateTable +CREATE TABLE `sys_agency` ( + `code` VARCHAR(64) NOT NULL, + `org_name` VARCHAR(100) NOT NULL, + `org_type` VARCHAR(20) NOT NULL, + `credit_code` VARCHAR(18) NOT NULL, + `loc_code` VARCHAR(12) NOT NULL, + `loc_name` VARCHAR(50) NOT NULL, + `svc_source` VARCHAR(10) NOT NULL, + `license_no` VARCHAR(50) NULL, + `address` VARCHAR(200) NOT NULL, + `contact_name` VARCHAR(30) NOT NULL, + `contact_phone` VARCHAR(15) NOT NULL, + `bed_count` INTEGER NULL, + `sign_date` DATE NULL, + `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `created_by` VARCHAR(36) NULL, + `updated_at` DATETIME(3) NOT NULL, + `deleted_at` DATETIME(3) NULL, + + PRIMARY KEY (`code`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_staff` ( + `id` VARCHAR(36) NOT NULL, + `tenant_code` VARCHAR(64) NOT NULL, + `user_id` VARCHAR(36) NULL, + `name` VARCHAR(30) NOT NULL, + `id_card_no` VARCHAR(255) NOT NULL, + `person_code` VARCHAR(20) NULL, + `phone` VARCHAR(15) NOT NULL, + `job_type` VARCHAR(20) NOT NULL, + `work_type` VARCHAR(10) NOT NULL, + `entry_date` DATE NULL, + `leave_date` DATE NULL, + `employ_status` VARCHAR(10) NOT NULL, + `cert_type` VARCHAR(20) NULL, + `cert_no` VARCHAR(50) NULL, + `cert_level` VARCHAR(20) NULL, + `cert_expire` DATE NULL, + `cert_status` VARCHAR(20) NULL, + `cert_verify_url` VARCHAR(200) NULL, + `group_leader_id` VARCHAR(36) NULL, + `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `created_by` VARCHAR(36) NULL, + `updated_at` DATETIME(3) NOT NULL, + `deleted_at` DATETIME(3) NULL, + + UNIQUE INDEX `sys_staff_user_id_key`(`user_id`), + INDEX `sys_staff_tenant_code_name_idx`(`tenant_code`, `name`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_svc_national` ( + `id` VARCHAR(36) NOT NULL, + `nat_code` VARCHAR(20) NOT NULL, + `nat_name` VARCHAR(100) NOT NULL, + `nat_category` VARCHAR(20) NOT NULL, + `nat_sub_category` VARCHAR(50) NULL, + `recommend_staff` VARCHAR(50) NULL, + `recommend_duration` VARCHAR(50) NULL, + `is_medical` BOOLEAN NOT NULL DEFAULT false, + `version` INTEGER NOT NULL DEFAULT 1, + + UNIQUE INDEX `sys_svc_national_nat_code_key`(`nat_code`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_svc_local` ( + `id` VARCHAR(36) NOT NULL, + `loc_code` VARCHAR(12) NOT NULL, + `local_item_name` VARCHAR(100) NOT NULL, + `local_category` VARCHAR(20) NULL, + `svc_time` VARCHAR(50) NULL, + `min_freq` VARCHAR(50) NULL, + `staff_qual` VARCHAR(50) NULL, + `is_medical` BOOLEAN NOT NULL DEFAULT false, + `source_doc` VARCHAR(200) NULL, + `map_status` VARCHAR(20) NOT NULL DEFAULT 'mapped', + + INDEX `sys_svc_local_loc_code_idx`(`loc_code`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_svc_mapping` ( + `id` VARCHAR(36) NOT NULL, + `loc_id` VARCHAR(36) NOT NULL, + `nat_id` VARCHAR(36) NULL, + `map_type` VARCHAR(20) NOT NULL, + `map_note` VARCHAR(200) NULL, + `status` VARCHAR(20) NOT NULL DEFAULT 'confirmed', + + INDEX `sys_svc_mapping_loc_id_idx`(`loc_id`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_svc_org` ( + `id` VARCHAR(36) NOT NULL, + `tenant_code` VARCHAR(64) NOT NULL, + `src_type` VARCHAR(10) NOT NULL, + `src_id` VARCHAR(36) NOT NULL, + `is_enabled` BOOLEAN NOT NULL DEFAULT true, + `price` VARCHAR(50) NULL, + `price_effective` DATETIME(3) NULL, + `is_new_national` BOOLEAN NOT NULL DEFAULT false, + `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `created_by` VARCHAR(36) NULL, + `updated_at` DATETIME(3) NOT NULL, + `deleted_at` DATETIME(3) NULL, + + INDEX `sys_svc_org_tenant_code_src_type_idx`(`tenant_code`, `src_type`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_dict_abnormal_type` ( + `id` VARCHAR(36) NOT NULL, + `code` VARCHAR(50) NOT NULL, + `name` VARCHAR(50) NOT NULL, + `sort` INTEGER NOT NULL DEFAULT 0, + + UNIQUE INDEX `sys_dict_abnormal_type_code_key`(`code`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_dict_photo_tier` ( + `id` VARCHAR(36) NOT NULL, + `code` VARCHAR(20) NOT NULL, + `name` VARCHAR(50) NOT NULL, + `tier` VARCHAR(10) NOT NULL, + + UNIQUE INDEX `sys_dict_photo_tier_code_key`(`code`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +-- CreateTable +CREATE TABLE `sys_loc_config` ( + `loc_code` VARCHAR(12) NOT NULL, + `loc_name` VARCHAR(50) NOT NULL, + `svc_source` VARCHAR(10) NOT NULL, + `item_count_rule` VARCHAR(100) NULL, + + PRIMARY KEY (`loc_code`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ee5c4bb..55d2719 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -298,3 +298,150 @@ model RoleOrg { @@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") +} diff --git a/src/prisma/prisma.service.ts b/src/prisma/prisma.service.ts index 3d4a765..bed4316 100644 --- a/src/prisma/prisma.service.ts +++ b/src/prisma/prisma.service.ts @@ -3,9 +3,9 @@ import { PrismaClient } from '@prisma/client'; import { getRequestContext } from '../common/context/request-context.js'; /** 不带 tenantCode 的模型(租户表自身)。 */ -const TENANT_FREE = new Set(['Tenant']); +const TENANT_FREE = new Set(['Tenant', 'Agency', 'SvcNational', 'SvcLocal', 'SvcMapping', 'DictAbnormalType', 'DictPhotoTier', 'LocConfig']); /** 软删模型:读操作统一注入 deletedAt IS NULL。 */ -const SOFT_DELETE = new Set(['User', 'Role', 'Resource', 'Org', 'DictType', 'DictItem', 'Config', 'Notice']); +const SOFT_DELETE = new Set(['User', 'Role', 'Resource', 'Org', 'DictType', 'DictItem', 'Config', 'Notice', 'Staff', 'SvcOrg']); const READ_OPS = new Set(['findMany', 'findFirst', 'findUnique', 'count', 'aggregate', 'groupBy']); /** 没有 where 子句的操作(create 的租户由 service 在 data 里显式写入)。 */ const NO_WHERE_OPS = new Set(['create', 'createMany']);