@chenchaolong/plugin-trade-compliance-workbench 1.0.85 → 1.0.87

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.
Files changed (50) hide show
  1. package/dist/lib/entities/catalog.entity.d.ts +3 -1
  2. package/dist/lib/entities/catalog.entity.d.ts.map +1 -1
  3. package/dist/lib/entities/catalog.entity.js +8 -0
  4. package/dist/lib/entities/catalog.entity.js.map +1 -1
  5. package/dist/lib/remote-components/trade-compliance-workbench/app.css +1 -1
  6. package/dist/lib/remote-components/trade-compliance-workbench/app.js +5 -5
  7. package/dist/lib/remote-ui/action-execution.d.ts.map +1 -1
  8. package/dist/lib/remote-ui/action-execution.js +1 -0
  9. package/dist/lib/remote-ui/action-execution.js.map +1 -1
  10. package/dist/lib/remote-ui/app-source.js +33 -6
  11. package/dist/lib/remote-ui/app-source.js.map +1 -1
  12. package/dist/lib/remote-ui/components/bulk-delete.js +1 -1
  13. package/dist/lib/remote-ui/components/bulk-delete.js.map +1 -1
  14. package/dist/lib/remote-ui/components/data-grid.js +2 -2
  15. package/dist/lib/remote-ui/components/data-grid.js.map +1 -1
  16. package/dist/lib/remote-ui/components/task-status.js +1 -1
  17. package/dist/lib/remote-ui/components/task-status.js.map +1 -1
  18. package/dist/lib/remote-ui/contracts.d.ts +3 -0
  19. package/dist/lib/remote-ui/contracts.d.ts.map +1 -1
  20. package/dist/lib/remote-ui/pages/analytics.js +1 -1
  21. package/dist/lib/remote-ui/pages/analytics.js.map +1 -1
  22. package/dist/lib/remote-ui/pages/catalogs.css +36 -0
  23. package/dist/lib/remote-ui/pages/catalogs.d.ts +2 -1
  24. package/dist/lib/remote-ui/pages/catalogs.d.ts.map +1 -1
  25. package/dist/lib/remote-ui/pages/catalogs.js +45 -13
  26. package/dist/lib/remote-ui/pages/catalogs.js.map +1 -1
  27. package/dist/lib/remote-ui/pages/contracts.css +3 -3
  28. package/dist/lib/remote-ui/pages/files-prototype.css +1 -1
  29. package/dist/lib/remote-ui/pages/sales-files.css +2 -2
  30. package/dist/lib/remote-ui/pages/settings.css +10 -9
  31. package/dist/lib/remote-ui/styles.css +15 -11
  32. package/dist/lib/schema-maintenance.d.ts.map +1 -1
  33. package/dist/lib/schema-maintenance.js +4 -2
  34. package/dist/lib/schema-maintenance.js.map +1 -1
  35. package/dist/lib/types.d.ts +2 -0
  36. package/dist/lib/types.d.ts.map +1 -1
  37. package/dist/lib/types.js +1 -0
  38. package/dist/lib/types.js.map +1 -1
  39. package/dist/lib/workbench-action-contract.d.ts +1 -1
  40. package/dist/lib/workbench-action-contract.d.ts.map +1 -1
  41. package/dist/lib/workbench-action-contract.js +1 -0
  42. package/dist/lib/workbench-action-contract.js.map +1 -1
  43. package/dist/lib/workbench-view.provider.d.ts.map +1 -1
  44. package/dist/lib/workbench-view.provider.js +4 -1
  45. package/dist/lib/workbench-view.provider.js.map +1 -1
  46. package/dist/lib/workbench.service.d.ts +7 -0
  47. package/dist/lib/workbench.service.d.ts.map +1 -1
  48. package/dist/lib/workbench.service.js +28 -5
  49. package/dist/lib/workbench.service.js.map +1 -1
  50. 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;