fix: align reporting fields queries and disk monitoring
This commit is contained in:
@@ -172,4 +172,9 @@ export class DictionariesController {
|
||||
deleteCommonReportField(@Param('id') id: string) {
|
||||
return this.dictionaries.deleteCommonReportField(id);
|
||||
}
|
||||
|
||||
@Put('common-report-fields/:id')
|
||||
updateCommonReportField(@Param('id') id: string, @Body() body: CreateCommonReportFieldDto, @CurrentSessionUserId() operatorId?: string) {
|
||||
return this.dictionaries.updateCommonReportField(id, body, operatorId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,24 @@ function createPrismaMock() {
|
||||
}
|
||||
|
||||
describe('DictionariesService', () => {
|
||||
it('edits common configuration in place with an audit trail and rejects duplicate or inactive fields', async () => {
|
||||
const prisma = createPrismaMock();
|
||||
const existing = { id: 'common-1', drainageFieldId: 'field-1', reportType: 'signature', required: false };
|
||||
prisma.commonReportField.findUnique.mockImplementation(({ where }: { where: { id?: string } }) => Promise.resolve(where.id ? existing : null) as never);
|
||||
prisma.drainageField.findUnique.mockResolvedValue({ id: 'field-2', status: 'active' } as never);
|
||||
const tx = { commonReportField: { update: jest.fn().mockResolvedValue({ ...existing, required: true }) }, operationLog: { create: jest.fn() } };
|
||||
prisma.$transaction.mockImplementation((callback) => callback(tx));
|
||||
const service = new DictionariesService(prisma as never);
|
||||
const body = { drainageFieldId: 'field-2', reportType: 'drainage' as const, required: true };
|
||||
await service.updateCommonReportField('common-1', body, 'admin-1');
|
||||
expect(tx.commonReportField.update).toHaveBeenCalledWith(expect.objectContaining({ where: { id: 'common-1' }, data: { ...body, sortOrder: undefined } }));
|
||||
expect(tx.operationLog.create).toHaveBeenCalledWith(expect.objectContaining({ data: expect.objectContaining({ action: 'common_report_field.update', userId: 'admin-1' }) }));
|
||||
prisma.commonReportField.findUnique.mockResolvedValue({ id: 'other' } as never);
|
||||
await expect(service.updateCommonReportField('common-1', body)).rejects.toThrow('已配置');
|
||||
prisma.drainageField.findUnique.mockResolvedValue({ id: 'field-2', status: 'inactive' } as never);
|
||||
await expect(service.updateCommonReportField('common-1', body)).rejects.toThrow('已停用');
|
||||
await expect(service.updateCommonReportField('common-1', { ...body, required: 'false' as never })).rejects.toThrow('无效');
|
||||
});
|
||||
it('builds the enterprise province and city library from distinct real phone segment regions', async () => {
|
||||
const prisma = createPrismaMock();
|
||||
prisma.phoneSegment.findMany.mockResolvedValue([
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BadRequestException, ConflictException, Injectable, Optional } from '@nestjs/common';
|
||||
import { BadRequestException, ConflictException, Injectable, NotFoundException, Optional } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { PhoneRoutingLookupService } from './phone-routing-lookup.service';
|
||||
@@ -545,6 +545,42 @@ export class DictionariesService {
|
||||
return this.prisma.commonReportField.delete({ where: { id } });
|
||||
}
|
||||
|
||||
async updateCommonReportField(id: string, data: CreateCommonReportFieldDto, operatorId?: string) {
|
||||
if (!['signature', 'drainage'].includes(data.reportType) || typeof data.required !== 'boolean') {
|
||||
throw new BadRequestException('资料用途或是否必填无效');
|
||||
}
|
||||
if (data.sortOrder !== undefined && !Number.isInteger(data.sortOrder)) {
|
||||
throw new BadRequestException('排序值必须为整数');
|
||||
}
|
||||
const existing = await this.prisma.commonReportField.findUnique({ where: { id } });
|
||||
if (!existing) throw new NotFoundException('通用字段配置不存在');
|
||||
const field = await this.prisma.drainageField.findUnique({ where: { id: data.drainageFieldId } });
|
||||
if (!field || field.status !== 'active') throw new BadRequestException('报备字段库字段不存在或已停用');
|
||||
const duplicate = await this.prisma.commonReportField.findUnique({
|
||||
where: { drainageFieldId_reportType: { drainageFieldId: field.id, reportType: data.reportType } },
|
||||
});
|
||||
if (duplicate && duplicate.id !== id) throw new ConflictException('该字段已配置为对应类型的通用字段');
|
||||
try {
|
||||
return await this.prisma.$transaction(async (tx) => {
|
||||
const updated = await tx.commonReportField.update({
|
||||
where: { id },
|
||||
data: { drainageFieldId: field.id, reportType: data.reportType, required: data.required, sortOrder: data.sortOrder },
|
||||
include: { drainageField: true },
|
||||
});
|
||||
await tx.operationLog.create({ data: {
|
||||
userId: operatorId, action: 'common_report_field.update', resource: 'common_report_field', resourceId: id,
|
||||
detail: { before: { drainageFieldId: existing.drainageFieldId, reportType: existing.reportType, required: existing.required }, after: { drainageFieldId: field.id, reportType: data.reportType, required: data.required } },
|
||||
} });
|
||||
return updated;
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2002') {
|
||||
throw new ConflictException('该字段已配置为对应类型的通用字段');
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private writeOperationLog(userId: string | undefined, action: string, resource: string, resourceId: string, detail: Record<string, unknown>) {
|
||||
return this.prisma.operationLog.create({
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user