feat(08-05-contract-detail-workspace): 完成合同详情与终止状态治理

这个提交包含在:
2026-08-08 02:02:52 +08:00
父节点 7546d372d6
当前提交 21851774dd
共修改 25 个文件,包含 2516 行新增和 1021 行删除
+35 -7
查看文件
@@ -7,6 +7,23 @@ const ExcelJS = require('exceljs');
const { createPrismaClient } = require('../prismaClient');
const SUPPORTED_TYPES = ['projects', 'members', 'milestones', 'risks', 'contracts'];
const CONTRACT_IMPORT_STATUS_VALUES = new Set(['draft', 'active', 'archived']);
function validateContractImportStatus(importedStatus, currentStatus = null) {
if (!CONTRACT_IMPORT_STATUS_VALUES.has(importedStatus)) {
return `status_not_importable:${importedStatus}`;
}
if (currentStatus === 'terminated') {
return 'terminated_contract_is_final';
}
if (currentStatus === 'archived') {
return 'archived_contract_requires_correction_api';
}
if (currentStatus && currentStatus !== importedStatus) {
return 'status_change_requires_contract_api';
}
return null;
}
function printHelp() {
console.log(`用法:
@@ -310,7 +327,7 @@ async function handleRisks({ prisma, rows, apply, summary }) {
async function handleContracts({ prisma, rows, apply, summary }) {
assertRequiredHeaders(rows, ['contract_no', 'counterparty_name', 'summary', 'archive_location', 'owner_employee_no']);
const refs = await buildReferenceMaps(prisma);
const existing = new Map((await prisma.contractRegistry.findMany({ select: { id: true, contract_no: true } })).map((item) => [item.contract_no, item]));
const existing = new Map((await prisma.contractRegistry.findMany({ select: { id: true, contract_no: true, status: true } })).map((item) => [item.contract_no, item]));
for (const row of rows) {
const data = row.data;
@@ -325,6 +342,14 @@ async function handleContracts({ prisma, rows, apply, summary }) {
continue;
}
const importedStatus = data.status || 'active';
const current = existing.get(data.contract_no);
const statusError = validateContractImportStatus(importedStatus, current?.status ?? null);
if (statusError) {
pushError(summary, row.rowNumber, statusError);
continue;
}
const payload = {
contract_no: data.contract_no,
project_id: project?.id ?? null,
@@ -334,10 +359,9 @@ async function handleContracts({ prisma, rows, apply, summary }) {
archive_location: data.archive_location,
offline_archive_no: data.offline_archive_no || null,
owner_employee_id: owner.id,
status: data.status || 'active',
status: importedStatus,
};
const current = existing.get(data.contract_no);
if (!current) summary.createCount += 1;
else summary.updateCount += 1;
@@ -400,7 +424,11 @@ async function main() {
}
}
main().catch((error) => {
console.error(error?.message ?? error);
process.exit(1);
});
if (require.main === module) {
main().catch((error) => {
console.error(error?.message ?? error);
process.exit(1);
});
}
module.exports = { validateContractImportStatus };