@chenchaolong/plugin-trade-compliance-workbench 1.0.84 → 1.0.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/entities/catalog.entity.d.ts +3 -1
- package/dist/lib/entities/catalog.entity.d.ts.map +1 -1
- package/dist/lib/entities/catalog.entity.js +8 -0
- package/dist/lib/entities/catalog.entity.js.map +1 -1
- package/dist/lib/remote-components/trade-compliance-workbench/app.css +1 -1
- package/dist/lib/remote-components/trade-compliance-workbench/app.js +5 -5
- package/dist/lib/remote-ui/action-execution.d.ts.map +1 -1
- package/dist/lib/remote-ui/action-execution.js +1 -0
- package/dist/lib/remote-ui/action-execution.js.map +1 -1
- package/dist/lib/remote-ui/app-source.js +38 -6
- package/dist/lib/remote-ui/app-source.js.map +1 -1
- package/dist/lib/remote-ui/components/bulk-delete.js +1 -1
- package/dist/lib/remote-ui/components/bulk-delete.js.map +1 -1
- package/dist/lib/remote-ui/components/data-grid.js +2 -2
- package/dist/lib/remote-ui/components/data-grid.js.map +1 -1
- package/dist/lib/remote-ui/components/task-status.js +1 -1
- package/dist/lib/remote-ui/components/task-status.js.map +1 -1
- package/dist/lib/remote-ui/contracts.d.ts +3 -0
- package/dist/lib/remote-ui/contracts.d.ts.map +1 -1
- package/dist/lib/remote-ui/pages/analytics.js +1 -1
- package/dist/lib/remote-ui/pages/analytics.js.map +1 -1
- package/dist/lib/remote-ui/pages/catalogs.css +36 -0
- package/dist/lib/remote-ui/pages/catalogs.d.ts +2 -1
- package/dist/lib/remote-ui/pages/catalogs.d.ts.map +1 -1
- package/dist/lib/remote-ui/pages/catalogs.js +31 -11
- package/dist/lib/remote-ui/pages/catalogs.js.map +1 -1
- package/dist/lib/remote-ui/pages/contracts.css +3 -3
- package/dist/lib/remote-ui/pages/files-prototype.css +1 -1
- package/dist/lib/remote-ui/pages/sales-files.css +2 -2
- package/dist/lib/remote-ui/pages/settings.css +10 -9
- package/dist/lib/remote-ui/styles.css +15 -11
- package/dist/lib/schema-maintenance.d.ts.map +1 -1
- package/dist/lib/schema-maintenance.js +4 -2
- package/dist/lib/schema-maintenance.js.map +1 -1
- package/dist/lib/types.d.ts +2 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +1 -0
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/workbench-action-contract.d.ts +1 -1
- package/dist/lib/workbench-action-contract.d.ts.map +1 -1
- package/dist/lib/workbench-action-contract.js +1 -0
- package/dist/lib/workbench-action-contract.js.map +1 -1
- package/dist/lib/workbench-view.provider.d.ts.map +1 -1
- package/dist/lib/workbench-view.provider.js +4 -1
- package/dist/lib/workbench-view.provider.js.map +1 -1
- package/dist/lib/workbench.service.d.ts +7 -0
- package/dist/lib/workbench.service.d.ts.map +1 -1
- package/dist/lib/workbench.service.js +28 -5
- package/dist/lib/workbench.service.js.map +1 -1
- package/package.json +23 -24
|
@@ -144,7 +144,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
144
144
|
}
|
|
145
145
|
async listControlledGoods(scope, query = {}) {
|
|
146
146
|
const page = await this.pagedCatalogQuery(ControlledGoodsRecord, ControlledCatalogBatch, scope, query, {
|
|
147
|
-
exact: { catalogType: query.parameters?.catalogType },
|
|
147
|
+
exact: { catalogType: query.parameters?.catalogType, reviewStatus: query.parameters?.reviewStatus },
|
|
148
148
|
fuzzy: { productName: query.parameters?.productName, hsCode: query.parameters?.hsCode },
|
|
149
149
|
batchSourceFileName: query.parameters?.sourceFileName
|
|
150
150
|
});
|
|
@@ -306,7 +306,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
306
306
|
const duplicate = await repo.findOne({ where: { ...activeScope(scope), lifecycleStatus: 'ACTIVE', catalogType: input.catalogType, normalizedProductName, normalizedHsCode, deletedAt: IsNull() } });
|
|
307
307
|
if (duplicate)
|
|
308
308
|
throw new DomainError(DomainErrorCodes.DUPLICATE_CATALOG_RECORD, '相同目录类型、商品名称和海关编码的记录已存在', { id: duplicate.id });
|
|
309
|
-
return controlledGoodsDto(await repo.save(repo.create({ ...auditScope(scope), lifecycleStatus: 'ACTIVE', sourceType: input.sourceType ?? 'MANUAL_ENTRY', catalogType: input.catalogType, productName, normalizedProductName, hsCode: input.hsCode ?? null, normalizedHsCode, controlDescription: input.controlDescription ?? null, sourceLocation: input.sourceLocation ?? null, sourceContent: input.sourceContent ?? null })));
|
|
309
|
+
return controlledGoodsDto(await repo.save(repo.create({ ...auditScope(scope), lifecycleStatus: 'ACTIVE', reviewStatus: 'PENDING', sourceType: input.sourceType ?? 'MANUAL_ENTRY', catalogType: input.catalogType, productName, normalizedProductName, hsCode: input.hsCode ?? null, normalizedHsCode, controlDescription: input.controlDescription ?? null, sourceLocation: input.sourceLocation ?? null, sourceContent: input.sourceContent ?? null })));
|
|
310
310
|
};
|
|
311
311
|
return this.dataSource.options?.type === 'postgres' ? this.dataSource.transaction(persist) : persist(this.dataSource);
|
|
312
312
|
}
|
|
@@ -316,6 +316,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
316
316
|
Object.assign(item, pick(input, ['catalogType', 'productName', 'hsCode', 'controlDescription']));
|
|
317
317
|
item.normalizedProductName = item.productName.trim();
|
|
318
318
|
item.normalizedHsCode = String(item.hsCode ?? '').replace(/\s/g, '');
|
|
319
|
+
item.reviewStatus = 'REVIEWED';
|
|
319
320
|
item.updatedById = scope.userId ?? null;
|
|
320
321
|
const saved = await repo.save(item);
|
|
321
322
|
await this.recalculateProductRisks(scope, 'CATALOG_CHANGED');
|
|
@@ -558,7 +559,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
558
559
|
await issueRepo.save(issueRepo.create({ ...createdScope(scope), batchId: batch.id, issueType: 'DUPLICATE', sourceSequence: batch.totalCount, sourceLocation: row.sourceLocation ?? null, sourceContent: row.sourceContent ?? null, parsedPayload: row, message: '目录中已存在相同商品名称和海关编码' }));
|
|
559
560
|
continue;
|
|
560
561
|
}
|
|
561
|
-
await recordRepo.save(recordRepo.create({ ...auditScope(scope), batchId: batch.id, lifecycleStatus: batch.lifecycleStatus, sourceType: 'FILE_IMPORT', catalogType: batch.catalogType, productName, normalizedProductName: productName, hsCode: row.hsCode ?? null, normalizedHsCode, controlDescription: localized.controlDescription, originalProductName: localized.originalProductName, originalControlDescription: localized.originalControlDescription, translationSource: localized.translationSource, controlCode: row.controlCode ?? null, sourceSection: row.sourceSection ?? null, sourceOrdinal: row.sourceOrdinal ?? null, sourceLocation: row.sourceLocation ?? null, sourceContent: row.sourceContent ?? null }));
|
|
562
|
+
await recordRepo.save(recordRepo.create({ ...auditScope(scope), batchId: batch.id, lifecycleStatus: batch.lifecycleStatus, reviewStatus: 'PENDING', sourceType: 'FILE_IMPORT', catalogType: batch.catalogType, productName, normalizedProductName: productName, hsCode: row.hsCode ?? null, normalizedHsCode, controlDescription: localized.controlDescription, originalProductName: localized.originalProductName, originalControlDescription: localized.originalControlDescription, translationSource: localized.translationSource, controlCode: row.controlCode ?? null, sourceSection: row.sourceSection ?? null, sourceOrdinal: row.sourceOrdinal ?? null, sourceLocation: row.sourceLocation ?? null, sourceContent: row.sourceContent ?? null }));
|
|
562
563
|
batch.successCount += 1;
|
|
563
564
|
batch.riskRecalculatedAt = null;
|
|
564
565
|
}
|
|
@@ -656,6 +657,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
656
657
|
}
|
|
657
658
|
async listSanctionedCompanies(scope, query = {}) {
|
|
658
659
|
const page = await this.pagedCatalogQuery(SanctionedCompanyRecord, SanctionCatalogBatch, scope, query, {
|
|
660
|
+
exact: { reviewStatus: query.parameters?.reviewStatus },
|
|
659
661
|
fuzzy: {
|
|
660
662
|
companyName: query.parameters?.companyName,
|
|
661
663
|
countryOrRegion: query.parameters?.countryOrRegion,
|
|
@@ -714,7 +716,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
714
716
|
const duplicate = await repo.findOne({ where: { ...activeScope(scope), lifecycleStatus: 'ACTIVE', normalizedCompanyName, normalizedSanctionListSource, deletedAt: IsNull() } });
|
|
715
717
|
if (duplicate)
|
|
716
718
|
throw new DomainError(DomainErrorCodes.DUPLICATE_CATALOG_RECORD, '相同公司名称和制裁名单来源的记录已存在', { id: duplicate.id });
|
|
717
|
-
return repo.save(repo.create({ ...auditScope(scope), lifecycleStatus: 'ACTIVE', sourceType: input.sourceType ?? 'MANUAL_ENTRY', companyName, normalizedCompanyName, countryOrRegion: input.countryOrRegion ?? null, sanctionListSource: input.sanctionListSource ?? null, normalizedSanctionListSource, sanctionReason: input.sanctionReason ?? null, effectiveDate: input.effectiveDate ?? null, remarks: input.remarks ?? null, sourceLocation: input.sourceLocation ?? null, sourceContent: input.sourceContent ?? null }));
|
|
719
|
+
return repo.save(repo.create({ ...auditScope(scope), lifecycleStatus: 'ACTIVE', reviewStatus: 'PENDING', sourceType: input.sourceType ?? 'MANUAL_ENTRY', companyName, normalizedCompanyName, countryOrRegion: input.countryOrRegion ?? null, sanctionListSource: input.sanctionListSource ?? null, normalizedSanctionListSource, sanctionReason: input.sanctionReason ?? null, effectiveDate: input.effectiveDate ?? null, remarks: input.remarks ?? null, sourceLocation: input.sourceLocation ?? null, sourceContent: input.sourceContent ?? null }));
|
|
718
720
|
};
|
|
719
721
|
const saved = await (this.dataSource.options?.type === 'postgres' ? this.dataSource.transaction(persist) : persist(this.dataSource));
|
|
720
722
|
await this.recalculateCompanyRisks(scope, 'CATALOG_CHANGED');
|
|
@@ -724,6 +726,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
724
726
|
const repo = this.dataSource.getRepository(SanctionedCompanyRecord);
|
|
725
727
|
const item = await required(repo.findOne({ where: { ...activeScope(scope), id, lifecycleStatus: 'ACTIVE', deletedAt: IsNull() } }), '制裁公司不存在');
|
|
726
728
|
Object.assign(item, pick(input, ['companyName', 'countryOrRegion', 'sanctionListSource', 'sanctionReason', 'effectiveDate', 'remarks']));
|
|
729
|
+
item.reviewStatus = 'REVIEWED';
|
|
727
730
|
item.normalizedCompanyName = normalizeExactName(item.companyName);
|
|
728
731
|
item.normalizedSanctionListSource = normalizeSanctionSource(item.sanctionListSource);
|
|
729
732
|
item.updatedById = scope.userId ?? null;
|
|
@@ -789,7 +792,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
789
792
|
await issueRepo.save(issueRepo.create({ ...createdScope(scope), batchId: result.id, issueType: 'DUPLICATE', sourceSequence: result.totalCount, sourceLocation: row.sourceLocation ?? null, sourceContent: row.sourceContent ?? null, parsedPayload: row, message: '制裁目录中已存在相同公司和名单来源' }));
|
|
790
793
|
continue;
|
|
791
794
|
}
|
|
792
|
-
await recordRepo.save(recordRepo.create({ ...auditScope(scope), batchId: result.id, lifecycleStatus: result.lifecycleStatus, sourceType: 'FILE_IMPORT', companyName, normalizedCompanyName, countryOrRegion: row.countryOrRegion ?? null, sanctionListSource: row.sanctionListSource ?? null, normalizedSanctionListSource, sanctionReason: row.sanctionReason ?? null, effectiveDate: row.effectiveDate ?? null, remarks: row.remarks ?? null, sourceLocation: row.sourceLocation ?? null, sourceContent: row.sourceContent ?? null }));
|
|
795
|
+
await recordRepo.save(recordRepo.create({ ...auditScope(scope), batchId: result.id, lifecycleStatus: result.lifecycleStatus, reviewStatus: 'PENDING', sourceType: 'FILE_IMPORT', companyName, normalizedCompanyName, countryOrRegion: row.countryOrRegion ?? null, sanctionListSource: row.sanctionListSource ?? null, normalizedSanctionListSource, sanctionReason: row.sanctionReason ?? null, effectiveDate: row.effectiveDate ?? null, remarks: row.remarks ?? null, sourceLocation: row.sourceLocation ?? null, sourceContent: row.sourceContent ?? null }));
|
|
793
796
|
result.successCount += 1;
|
|
794
797
|
}
|
|
795
798
|
if (changed)
|
|
@@ -3317,6 +3320,26 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
|
|
|
3317
3320
|
await this.recalculateProductRisks(scope, 'CATALOG_CHANGED');
|
|
3318
3321
|
return result;
|
|
3319
3322
|
}
|
|
3323
|
+
async clearSanctionCatalog(scope) {
|
|
3324
|
+
const result = await this.dataSource.transaction(async (manager) => {
|
|
3325
|
+
const scoped = activeScope(scope);
|
|
3326
|
+
const now = new Date();
|
|
3327
|
+
const matches = await manager.getRepository(CompanySanctionMatch).update({ ...scoped, deletedAt: IsNull() }, { deletedAt: now, invalidationReason: 'CATALOG_CHANGED' });
|
|
3328
|
+
const issues = await manager.getRepository(SanctionCatalogImportIssue).delete(scoped);
|
|
3329
|
+
const aliases = await manager.getRepository(SanctionedCompanyAlias).delete(scoped);
|
|
3330
|
+
const records = await manager.getRepository(SanctionedCompanyRecord).delete(scoped);
|
|
3331
|
+
const batches = await manager.getRepository(SanctionCatalogBatch).delete(scoped);
|
|
3332
|
+
return {
|
|
3333
|
+
deletedRecords: records.affected ?? 0,
|
|
3334
|
+
deletedAliases: aliases.affected ?? 0,
|
|
3335
|
+
deletedBatches: batches.affected ?? 0,
|
|
3336
|
+
deletedIssues: issues.affected ?? 0,
|
|
3337
|
+
invalidatedMatches: matches.affected ?? 0
|
|
3338
|
+
};
|
|
3339
|
+
});
|
|
3340
|
+
await this.recalculateCompanyRisks(scope, 'CATALOG_CHANGED');
|
|
3341
|
+
return result;
|
|
3342
|
+
}
|
|
3320
3343
|
async listGeneratedFiles(scope, query = {}) {
|
|
3321
3344
|
const parameters = query.parameters ?? {};
|
|
3322
3345
|
const fileName = parameters.fileName;
|