import { Injectable } from '@nestjs/common'; import { db, StaffMethodSchema, ObjectType, UserProfile, Prisma, } from '@nice/common'; import { DepartmentService } from '../department/department.service'; import { z } from 'zod'; import { BaseService } from '../base/base.service'; import * as argon2 from 'argon2'; import EventBus, { CrudOperation } from '@server/utils/event-bus'; import { DefaultArgs } from '@prisma/client/runtime/library'; @Injectable() export class StaffService extends BaseService { constructor(private readonly departmentService: DepartmentService) { super(db, ObjectType.STAFF, true); } /** * 获取某一单位下所有staff的记录 * @param deptId 单位的id * @returns 查到的staff记录 */ async findByDept(data: z.infer) { const { deptId, domainId } = data; const childDepts = await this.departmentService.getDescendantIds( deptId, true, ); const result = await db.staff.findMany({ where: { deptId: { in: childDepts }, domainId, }, }); return result; } async create(args: Prisma.StaffCreateArgs) { const { data } = args; await this.validateUniqueFields(data); const createData = { ...data, password: await argon2.hash((data.password || '123456') as string), }; const result = await super.create({ ...args, data: createData }); this.emitDataChangedEvent(result, CrudOperation.CREATED); return result; } async update(args: Prisma.StaffUpdateArgs) { const { data, where } = args; await this.validateUniqueFields(data, where.id); const updateData = { ...data, ...(data.password && { password: await argon2.hash(data.password as string), }), }; const result = await super.update({ ...args, data: updateData }); this.emitDataChangedEvent(result, CrudOperation.UPDATED); return result; } private async validateUniqueFields(data: any, excludeId?: string) { const uniqueFields = [ { field: 'officerId', errorMsg: (val: string) => `证件号为${val}的用户已存在`, }, { field: 'phoneNumber', errorMsg: (val: string) => `手机号为${val}的用户已存在`, }, { field: 'username', errorMsg: (val: string) => `帐号为${val}的用户已存在`, }, ]; for (const { field, errorMsg } of uniqueFields) { if (data[field]) { const count = await db.staff.count({ where: { [field]: data[field], ...(excludeId && { id: { not: excludeId } }), }, }); if (count > 0) { throw new Error(errorMsg(data[field])); } } } } private emitDataChangedEvent(data: any, operation: CrudOperation) { EventBus.emit('dataChanged', { type: this.objectType, operation, data, }); } /** * 更新员工DomainId * @param data 包含domainId对象 * @returns 更新后的员工记录 */ async updateUserDomain(data: { domainId?: string }, staff?: UserProfile) { const { domainId } = data; if (staff.domainId !== domainId) { const result = await this.update({ where: { id: staff.id }, data: { domainId, deptId: null, }, }); return result; } else { return staff; } } async findManyWithPagination(args: { page?: number; pageSize?: number; where?: Prisma.StaffWhereInput; select?: Prisma.StaffSelect; orderBy?: Prisma.StaffOrderByWithRelationInput; }) { if (args.where.deptId && typeof args.where.deptId === 'string') { const childDepts = await this.departmentService.getDescendantIds( args.where.deptId, true, ); args.where.deptId = { in: childDepts, }; } return super.findManyWithPagination(args as any); } }