From 3cd7a044cab5e37775aa25dabbcb54d3e517d249 Mon Sep 17 00:00:00 2001 From: EL <1175065040@qq.com> Date: Thu, 12 Mar 2026 17:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=98=E6=9B=B4=E7=BB=9F=E8=AE=A1=E6=98=AF?= =?UTF-8?q?=204=20=E4=B8=AA=E5=B7=B2=E7=BA=B3=E5=85=A5=20diff=20=E7=9A=84?= =?UTF-8?q?=E6=96=87=E4=BB=B6=EF=BC=8C=E5=85=B1=20137=20=E8=A1=8C=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=8140=20=E8=A1=8C=E5=88=A0=E9=99=A4=E3=80=82?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E5=86=85=E5=AE=B9=E6=98=AF=E6=8A=8A=20Prisma?= =?UTF-8?q?=20schema=20=E4=BB=8E=E5=8E=9F=E6=9C=AC=E7=9A=84=20User/Post=20?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E4=B8=BA=E5=8C=BB=E9=99=A2=E3=80=81=E7=A7=91?= =?UTF-8?q?=E5=AE=A4=E3=80=81=E5=8C=BB=E7=96=97=E7=BB=84=E3=80=81=E6=82=A3?= =?UTF-8?q?=E8=80=85=E3=80=81=E5=B7=A5=E7=A8=8B=E5=B8=88=E5=88=86=E9=85=8D?= =?UTF-8?q?=E7=AD=89=E6=A8=A1=E5=9E=8B=EF=BC=8C=E5=90=8C=E6=97=B6=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E8=B0=83=E6=95=B4=E4=BA=86=E7=94=A8=E6=88=B7=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=20DTO=20=E5=92=8C=20service=20=E7=9A=84=E5=85=A5?= =?UTF-8?q?=E5=8F=82=E6=98=A0=E5=B0=84=EF=BC=8C=E5=B9=B6=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BA=86=E4=B8=80=E4=BB=BD=E5=AF=B9=E5=BA=94=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E3=80=81=E5=88=A0=E9=99=A4=E4=BA=86=E4=B8=80=E4=BB=BD=E6=97=A7?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20260312073029_init/migration.sql | 25 --- .../migrations/20260312092840/migration.sql | 151 ++++++++++++++++++ prisma/schema.prisma | 114 +++++++++++-- src/users/dto/create-user.dto.ts | 26 ++- src/users/users.service.ts | 10 +- 5 files changed, 287 insertions(+), 39 deletions(-) delete mode 100644 prisma/migrations/20260312073029_init/migration.sql create mode 100644 prisma/migrations/20260312092840/migration.sql diff --git a/prisma/migrations/20260312073029_init/migration.sql b/prisma/migrations/20260312073029_init/migration.sql deleted file mode 100644 index 72c87ae..0000000 --- a/prisma/migrations/20260312073029_init/migration.sql +++ /dev/null @@ -1,25 +0,0 @@ --- CreateTable -CREATE TABLE "User" ( - "id" SERIAL NOT NULL, - "email" TEXT NOT NULL, - "name" TEXT, - - CONSTRAINT "User_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "Post" ( - "id" SERIAL NOT NULL, - "title" TEXT NOT NULL, - "content" TEXT, - "published" BOOLEAN DEFAULT false, - "authorId" INTEGER, - - CONSTRAINT "Post_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); - --- AddForeignKey -ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20260312092840/migration.sql b/prisma/migrations/20260312092840/migration.sql new file mode 100644 index 0000000..e6846bd --- /dev/null +++ b/prisma/migrations/20260312092840/migration.sql @@ -0,0 +1,151 @@ +-- CreateEnum +CREATE TYPE "UserRole" AS ENUM ('SYSTEM_ADMIN', 'HOSPITAL_ADMIN', 'DIRECTOR', 'TEAM_LEAD', 'DOCTOR', 'ENGINEER'); + +-- CreateTable +CREATE TABLE "Hospital" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "code" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Hospital_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Department" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "hospitalId" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Department_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "MedicalGroup" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "departmentId" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "MedicalGroup_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "role" "UserRole" NOT NULL DEFAULT 'DOCTOR', + "hospitalId" INTEGER, + "departmentId" INTEGER, + "medicalGroupId" INTEGER, + "managerId" INTEGER, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Patient" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "hospitalId" INTEGER NOT NULL, + "departmentId" INTEGER, + "medicalGroupId" INTEGER, + "doctorId" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Patient_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "EngineerHospitalAssignment" ( + "id" SERIAL NOT NULL, + "hospitalId" INTEGER NOT NULL, + "engineerId" INTEGER NOT NULL, + "assignedById" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "EngineerHospitalAssignment_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Hospital_code_key" ON "Hospital"("code"); + +-- CreateIndex +CREATE UNIQUE INDEX "Department_hospitalId_name_key" ON "Department"("hospitalId", "name"); + +-- CreateIndex +CREATE UNIQUE INDEX "MedicalGroup_departmentId_name_key" ON "MedicalGroup"("departmentId", "name"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); + +-- CreateIndex +CREATE INDEX "User_role_idx" ON "User"("role"); + +-- CreateIndex +CREATE INDEX "User_hospitalId_idx" ON "User"("hospitalId"); + +-- CreateIndex +CREATE INDEX "User_managerId_idx" ON "User"("managerId"); + +-- CreateIndex +CREATE INDEX "Patient_doctorId_idx" ON "Patient"("doctorId"); + +-- CreateIndex +CREATE INDEX "Patient_hospitalId_idx" ON "Patient"("hospitalId"); + +-- CreateIndex +CREATE INDEX "EngineerHospitalAssignment_engineerId_idx" ON "EngineerHospitalAssignment"("engineerId"); + +-- CreateIndex +CREATE INDEX "EngineerHospitalAssignment_assignedById_idx" ON "EngineerHospitalAssignment"("assignedById"); + +-- CreateIndex +CREATE UNIQUE INDEX "EngineerHospitalAssignment_hospitalId_engineerId_key" ON "EngineerHospitalAssignment"("hospitalId", "engineerId"); + +-- AddForeignKey +ALTER TABLE "Department" ADD CONSTRAINT "Department_hospitalId_fkey" FOREIGN KEY ("hospitalId") REFERENCES "Hospital"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "MedicalGroup" ADD CONSTRAINT "MedicalGroup_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "User" ADD CONSTRAINT "User_hospitalId_fkey" FOREIGN KEY ("hospitalId") REFERENCES "Hospital"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "User" ADD CONSTRAINT "User_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "User" ADD CONSTRAINT "User_medicalGroupId_fkey" FOREIGN KEY ("medicalGroupId") REFERENCES "MedicalGroup"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "User" ADD CONSTRAINT "User_managerId_fkey" FOREIGN KEY ("managerId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Patient" ADD CONSTRAINT "Patient_hospitalId_fkey" FOREIGN KEY ("hospitalId") REFERENCES "Hospital"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Patient" ADD CONSTRAINT "Patient_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Patient" ADD CONSTRAINT "Patient_medicalGroupId_fkey" FOREIGN KEY ("medicalGroupId") REFERENCES "MedicalGroup"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Patient" ADD CONSTRAINT "Patient_doctorId_fkey" FOREIGN KEY ("doctorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EngineerHospitalAssignment" ADD CONSTRAINT "EngineerHospitalAssignment_hospitalId_fkey" FOREIGN KEY ("hospitalId") REFERENCES "Hospital"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EngineerHospitalAssignment" ADD CONSTRAINT "EngineerHospitalAssignment_engineerId_fkey" FOREIGN KEY ("engineerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EngineerHospitalAssignment" ADD CONSTRAINT "EngineerHospitalAssignment_assignedById_fkey" FOREIGN KEY ("assignedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 178b772..a16dada 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -13,18 +13,108 @@ datasource db { provider = "postgresql" } -model User { - id Int @id @default(autoincrement()) - email String @unique - name String? - posts Post[] +enum UserRole { + SYSTEM_ADMIN + HOSPITAL_ADMIN + DIRECTOR + TEAM_LEAD + DOCTOR + ENGINEER } -model Post { - id Int @id @default(autoincrement()) - title String - content String? - published Boolean? @default(false) - author User? @relation(fields: [authorId], references: [id]) - authorId Int? +model Hospital { + id Int @id @default(autoincrement()) + name String + code String @unique + departments Department[] + users User[] + patients Patient[] + engineerAssignments EngineerHospitalAssignment[] + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt +} + +model Department { + id Int @id @default(autoincrement()) + name String + hospitalId Int + hospital Hospital @relation(fields: [hospitalId], references: [id], onDelete: Cascade) + medicalGroups MedicalGroup[] + users User[] + patients Patient[] + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + @@unique([hospitalId, name]) +} + +model MedicalGroup { + id Int @id @default(autoincrement()) + name String + departmentId Int + department Department @relation(fields: [departmentId], references: [id], onDelete: Cascade) + users User[] + patients Patient[] + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + @@unique([departmentId, name]) +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + role UserRole @default(DOCTOR) + hospitalId Int? + departmentId Int? + medicalGroupId Int? + managerId Int? + hospital Hospital? @relation(fields: [hospitalId], references: [id], onDelete: SetNull) + department Department? @relation(fields: [departmentId], references: [id], onDelete: SetNull) + medicalGroup MedicalGroup? @relation(fields: [medicalGroupId], references: [id], onDelete: SetNull) + manager User? @relation("UserHierarchy", fields: [managerId], references: [id], onDelete: SetNull) + subordinates User[] @relation("UserHierarchy") + patients Patient[] @relation("DoctorPatients") + engineerAssignments EngineerHospitalAssignment[] @relation("EngineerAssignments") + assignedEngineerHospitals EngineerHospitalAssignment[] @relation("SystemAdminAssignments") + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + @@index([role]) + @@index([hospitalId]) + @@index([managerId]) +} + +model Patient { + id Int @id @default(autoincrement()) + name String + hospitalId Int + departmentId Int? + medicalGroupId Int? + doctorId Int + hospital Hospital @relation(fields: [hospitalId], references: [id], onDelete: Restrict) + department Department? @relation(fields: [departmentId], references: [id], onDelete: SetNull) + medicalGroup MedicalGroup? @relation(fields: [medicalGroupId], references: [id], onDelete: SetNull) + doctor User @relation("DoctorPatients", fields: [doctorId], references: [id], onDelete: Restrict) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + @@index([doctorId]) + @@index([hospitalId]) +} + +model EngineerHospitalAssignment { + id Int @id @default(autoincrement()) + hospitalId Int + engineerId Int + assignedById Int + hospital Hospital @relation(fields: [hospitalId], references: [id], onDelete: Cascade) + engineer User @relation("EngineerAssignments", fields: [engineerId], references: [id], onDelete: Restrict) + assignedBy User @relation("SystemAdminAssignments", fields: [assignedById], references: [id], onDelete: Restrict) + createdAt DateTime @default(now()) + + @@unique([hospitalId, engineerId]) + @@index([engineerId]) + @@index([assignedById]) } diff --git a/src/users/dto/create-user.dto.ts b/src/users/dto/create-user.dto.ts index 0e19f8e..6ae1277 100644 --- a/src/users/dto/create-user.dto.ts +++ b/src/users/dto/create-user.dto.ts @@ -1,4 +1,5 @@ -import { IsEmail, IsOptional, IsString } from 'class-validator'; +import { UserRole } from '../../generated/prisma/enums.js'; +import { IsEmail, IsEnum, IsInt, IsOptional, IsString, Min } from 'class-validator'; export class CreateUserDto { @IsEmail() @@ -7,4 +8,27 @@ export class CreateUserDto { @IsString() @IsOptional() name?: string; + + @IsEnum(UserRole) + role: UserRole; + + @IsInt() + @Min(1) + @IsOptional() + hospitalId?: number; + + @IsInt() + @Min(1) + @IsOptional() + departmentId?: number; + + @IsInt() + @Min(1) + @IsOptional() + medicalGroupId?: number; + + @IsInt() + @Min(1) + @IsOptional() + managerId?: number; } diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 4425c04..8b0e751 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -20,7 +20,15 @@ export class UsersService { } return this.prisma.user.create({ - data: createUserDto, + data: { + email: createUserDto.email, + name: createUserDto.name, + role: createUserDto.role, + hospitalId: createUserDto.hospitalId, + departmentId: createUserDto.departmentId, + medicalGroupId: createUserDto.medicalGroupId, + managerId: createUserDto.managerId, + }, }); }