feat: support WPS report material workbooks
This commit is contained in:
@@ -1,45 +1,12 @@
|
||||
import { BadRequestException, ConflictException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { BadRequestException, NotFoundException } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import ExcelJS from 'exceljs';
|
||||
import { createHash, randomUUID } from 'node:crypto';
|
||||
import { extname } from 'node:path';
|
||||
import { FilesService } from '../files/files.service';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { SmsConfigService } from '../sms-config/sms-config.service';
|
||||
import type {
|
||||
AnalyzeImportOptions,
|
||||
CreateImportProfileDto,
|
||||
CreateReportBatchDto,
|
||||
EmbeddedImage,
|
||||
ImportCommitDto,
|
||||
ImportMapping,
|
||||
PagedQuery,
|
||||
ReportBatchInspection,
|
||||
ReportBatchTarget,
|
||||
ReviewImportItemsDto,
|
||||
SingleReportMaterialDto,
|
||||
} from './report-materials.contracts';
|
||||
import type { SingleReportMaterialDto } from './report-materials.contracts';
|
||||
import {
|
||||
profileData,
|
||||
validateProfile,
|
||||
loadWorkbook,
|
||||
assertSafeWorkbook,
|
||||
safeSpreadsheetText,
|
||||
readEmbeddedImages,
|
||||
suggestMappings,
|
||||
remapProfileColumns,
|
||||
signatureCoreMapping,
|
||||
drainageCoreMapping,
|
||||
normalizeHeader,
|
||||
normalizeFieldCode,
|
||||
clamp,
|
||||
normalizePage,
|
||||
normalizePageSize,
|
||||
dateRange,
|
||||
cellText,
|
||||
transformValue,
|
||||
mappedCoreValue,
|
||||
dynamicValues,
|
||||
jsonRecord,
|
||||
hasValue,
|
||||
isFileRef,
|
||||
@@ -47,12 +14,9 @@ import {
|
||||
applyExportTransform,
|
||||
styleHeader,
|
||||
normalizeImageExtension,
|
||||
imageContentType,
|
||||
safeFileName,
|
||||
normalizeBatchIdempotencyKey,
|
||||
jsonStringArray,
|
||||
jsonSafe,
|
||||
} from './report-materials.helpers';
|
||||
import { convertWorkbookOutput } from './workbook-compatibility';
|
||||
import type { ReportBatchGenerationService } from './batch-generation.service';
|
||||
|
||||
/** R4 report-materials domain service composed behind ReportMaterialsService. */
|
||||
@@ -97,7 +61,7 @@ export class ReportChannelExportService {
|
||||
);
|
||||
const smsContentField = fields.find((field) => field.name.trim() === '短信内容');
|
||||
const smsContentValue = smsContentField
|
||||
? resolveExportValue(item.snapshot, smsContentField.code, smsContentField.name) ?? ''
|
||||
? (resolveExportValue(item.snapshot, smsContentField.code, smsContentField.name) ?? '')
|
||||
: '';
|
||||
const smsContent = isFileRef(smsContentValue) ? '' : String(smsContentValue ?? '');
|
||||
const missing = fields.filter((field, index) => field.required && !hasValue(values[index]));
|
||||
@@ -292,6 +256,11 @@ export class ReportChannelExportService {
|
||||
});
|
||||
const configuredCodes = new Set(fields.map((field) => field.code));
|
||||
const values = jsonRecord(snapshot.values);
|
||||
const historicalCodes = Object.keys(values).filter((code) => !configuredCodes.has(code));
|
||||
const historicalDefinitions = historicalCodes.length
|
||||
? await this.prisma.drainageField.findMany({ where: { code: { in: historicalCodes } } })
|
||||
: [];
|
||||
const historicalDefinitionByCode = new Map(historicalDefinitions.map((field) => [field.code, field]));
|
||||
const materialFields = fields.map((field) => {
|
||||
const submittedValue = resolveExportValue(snapshot, field.code, field.name);
|
||||
const value = hasValue(submittedValue) ? submittedValue : field.defaultValue;
|
||||
@@ -312,9 +281,9 @@ export class ReportChannelExportService {
|
||||
};
|
||||
});
|
||||
const historicalFields = Object.entries(values)
|
||||
.filter(([code, value]) => !configuredCodes.has(code) && hasValue(value))
|
||||
.filter(([code]) => !configuredCodes.has(code) && historicalDefinitionByCode.get(code)?.status !== 'deleted')
|
||||
.sort(([left], [right]) => left.localeCompare(right, 'zh-CN'))
|
||||
.map(([code, value]) => ({ code, name: code, value }));
|
||||
.map(([code, value]) => ({ code, name: historicalDefinitionByCode.get(code)?.name ?? code, value }));
|
||||
return {
|
||||
reportType,
|
||||
signatureId: signature.id,
|
||||
@@ -380,7 +349,7 @@ export class ReportChannelExportService {
|
||||
}
|
||||
row.height = targetHeight;
|
||||
const fileName = `${safeFileName(detail.channel.name)}-${safeFileName(detail.signatureName)}-V${detail.materialVersion}.xlsx`;
|
||||
const content = Buffer.from(await workbook.xlsx.writeBuffer());
|
||||
const content = await convertWorkbookOutput(Buffer.from(await workbook.xlsx.writeBuffer()), data.outputFormat);
|
||||
await this.prisma.operationLog.create({
|
||||
data: {
|
||||
tenantId: detail.tenant.id,
|
||||
|
||||
Reference in New Issue
Block a user