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'; @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, select } = args; const { fieldValues, ...staffData } = data as any; // 创建员工基本信息 const staff = await super.create({ ...args, data: { ...staffData, password: await argon2.hash((staffData.password || '123456') as string), }, }); // 如果有自定义字段值,创建它们 if (fieldValues) { await db.staffFieldValue.createMany({ data: Object.entries(fieldValues).map(([fieldId, value]) => ({ staffId: staff.id, fieldId, value: String(value), })), }); } this.emitDataChangedEvent(staff, CrudOperation.CREATED); return staff; } async update(args: Prisma.StaffUpdateArgs) { const { data, where } = args; const { fieldValues, ...staffData } = data as any; // 更新员工基本信息 const staff = await super.update({ ...args, data: { ...staffData, ...(staffData.password && { password: await argon2.hash(staffData.password as string), }), }, }); // 如果有自定义字段值,更新它们 if (fieldValues) { await Promise.all( Object.entries(fieldValues).map(([fieldId, value]) => db.staffFieldValue.upsert({ where: { staffId_fieldId: { staffId: staff.id, fieldId, }, }, create: { staffId: staff.id, fieldId, value: String(value), }, update: { value: String(value), }, }), ), ); } this.emitDataChangedEvent(staff, CrudOperation.UPDATED); return staff; } 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 findUnique(args: Prisma.StaffFindUniqueArgs) { const staff = await super.findUnique(args); if (!staff) return null; // 获取自定义字段值 const fieldValues = await db.staffFieldValue.findMany({ where: { staffId: staff.id }, include: { field: true }, }); return { ...staff, fieldValues: fieldValues.reduce((acc, { field, value }) => ({ ...acc, [field.name]: value, }), {}), }; } async addCustomField(data: { name: string; label?: string; type: string; required?: boolean; order?: number; options?: any; group?: string; }) { return this.prisma.staffField.create({ data: { ...data, }, }); } async updateCustomField(data: { id: string; name?: string; label?: string; type?: string; required?: boolean; order?: number; options?: any; group?: string; }) { const { id, ...updateData } = data; return this.prisma.staffField.update({ where: { id }, data: updateData, }); } async deleteCustomField(id: string) { return this.prisma.staffField.delete({ where: { id }, }); } async getCustomFields() { return this.prisma.staffField.findMany({ orderBy: { order: 'asc' }, }); } async setCustomFieldValue(data: { staffId: string; fieldId: string; value?: string; }) { const { staffId, fieldId, value } = data; return this.prisma.staffFieldValue.upsert({ where: { staffId_fieldId: { staffId, fieldId, } }, create: { staffId, fieldId, value, }, update: { value, }, }); } }