@chenchaolong/plugin-trade-compliance-workbench 1.0.24 → 1.0.26

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 (76) hide show
  1. package/dist/lib/import-jobs/import-job-callback.processor.d.ts.map +1 -1
  2. package/dist/lib/import-jobs/import-job-callback.processor.js +5 -4
  3. package/dist/lib/import-jobs/import-job-callback.processor.js.map +1 -1
  4. package/dist/lib/remote-components/trade-compliance-workbench/app.css +1 -1
  5. package/dist/lib/remote-components/trade-compliance-workbench/app.js +5 -5
  6. package/dist/lib/remote-ui/action-execution.d.ts +5 -2
  7. package/dist/lib/remote-ui/action-execution.d.ts.map +1 -1
  8. package/dist/lib/remote-ui/action-execution.js +2 -2
  9. package/dist/lib/remote-ui/action-execution.js.map +1 -1
  10. package/dist/lib/remote-ui/app-source.d.ts.map +1 -1
  11. package/dist/lib/remote-ui/app-source.js +134 -35
  12. package/dist/lib/remote-ui/app-source.js.map +1 -1
  13. package/dist/lib/remote-ui/bulk-delete.d.ts +56 -0
  14. package/dist/lib/remote-ui/bulk-delete.d.ts.map +1 -0
  15. package/dist/lib/remote-ui/bulk-delete.js +138 -0
  16. package/dist/lib/remote-ui/bulk-delete.js.map +1 -0
  17. package/dist/lib/remote-ui/components/bulk-delete.d.ts +21 -0
  18. package/dist/lib/remote-ui/components/bulk-delete.d.ts.map +1 -0
  19. package/dist/lib/remote-ui/components/bulk-delete.js +9 -0
  20. package/dist/lib/remote-ui/components/bulk-delete.js.map +1 -0
  21. package/dist/lib/remote-ui/components/data-grid.d.ts +12 -1
  22. package/dist/lib/remote-ui/components/data-grid.d.ts.map +1 -1
  23. package/dist/lib/remote-ui/components/data-grid.js +24 -5
  24. package/dist/lib/remote-ui/components/data-grid.js.map +1 -1
  25. package/dist/lib/remote-ui/components/task-status.d.ts +10 -1
  26. package/dist/lib/remote-ui/components/task-status.d.ts.map +1 -1
  27. package/dist/lib/remote-ui/components/task-status.js +79 -10
  28. package/dist/lib/remote-ui/components/task-status.js.map +1 -1
  29. package/dist/lib/remote-ui/customer-contract-contracts.d.ts +7 -2
  30. package/dist/lib/remote-ui/customer-contract-contracts.d.ts.map +1 -1
  31. package/dist/lib/remote-ui/customer-contract-contracts.js.map +1 -1
  32. package/dist/lib/remote-ui/import-task-status.d.ts +1 -1
  33. package/dist/lib/remote-ui/import-task-status.d.ts.map +1 -1
  34. package/dist/lib/remote-ui/import-task-status.js +2 -2
  35. package/dist/lib/remote-ui/import-task-status.js.map +1 -1
  36. package/dist/lib/remote-ui/model.d.ts +1 -0
  37. package/dist/lib/remote-ui/model.d.ts.map +1 -1
  38. package/dist/lib/remote-ui/model.js +3 -0
  39. package/dist/lib/remote-ui/model.js.map +1 -1
  40. package/dist/lib/remote-ui/pages/catalogs.css +91 -0
  41. package/dist/lib/remote-ui/pages/catalogs.d.ts +49 -3
  42. package/dist/lib/remote-ui/pages/catalogs.d.ts.map +1 -1
  43. package/dist/lib/remote-ui/pages/catalogs.js +123 -12
  44. package/dist/lib/remote-ui/pages/catalogs.js.map +1 -1
  45. package/dist/lib/remote-ui/pages/contracts.css +42 -6
  46. package/dist/lib/remote-ui/pages/contracts.d.ts +61 -3
  47. package/dist/lib/remote-ui/pages/contracts.d.ts.map +1 -1
  48. package/dist/lib/remote-ui/pages/contracts.js +213 -11
  49. package/dist/lib/remote-ui/pages/contracts.js.map +1 -1
  50. package/dist/lib/remote-ui/pages/files.d.ts +52 -10
  51. package/dist/lib/remote-ui/pages/files.d.ts.map +1 -1
  52. package/dist/lib/remote-ui/pages/files.js +122 -12
  53. package/dist/lib/remote-ui/pages/files.js.map +1 -1
  54. package/dist/lib/remote-ui/pages/home.js +4 -4
  55. package/dist/lib/remote-ui/pages/home.js.map +1 -1
  56. package/dist/lib/remote-ui/pages/procurement.d.ts +87 -2
  57. package/dist/lib/remote-ui/pages/procurement.d.ts.map +1 -1
  58. package/dist/lib/remote-ui/pages/procurement.js +225 -21
  59. package/dist/lib/remote-ui/pages/procurement.js.map +1 -1
  60. package/dist/lib/remote-ui/pages/settings.d.ts +39 -6
  61. package/dist/lib/remote-ui/pages/settings.d.ts.map +1 -1
  62. package/dist/lib/remote-ui/pages/settings.js +94 -5
  63. package/dist/lib/remote-ui/pages/settings.js.map +1 -1
  64. package/dist/lib/remote-ui/polling.d.ts +1 -0
  65. package/dist/lib/remote-ui/polling.d.ts.map +1 -1
  66. package/dist/lib/remote-ui/polling.js +6 -1
  67. package/dist/lib/remote-ui/polling.js.map +1 -1
  68. package/dist/lib/remote-ui/procurement-contracts.d.ts +6 -2
  69. package/dist/lib/remote-ui/procurement-contracts.d.ts.map +1 -1
  70. package/dist/lib/remote-ui/procurement-contracts.js +11 -1
  71. package/dist/lib/remote-ui/procurement-contracts.js.map +1 -1
  72. package/dist/lib/remote-ui/styles.css +55 -19
  73. package/dist/lib/workbench.service.d.ts.map +1 -1
  74. package/dist/lib/workbench.service.js +20 -23
  75. package/dist/lib/workbench.service.js.map +1 -1
  76. package/package.json +2 -1
@@ -43,12 +43,9 @@ const SKIPPED_REASON_MESSAGES = {
43
43
  };
44
44
  const RUNNING_IMPORT_TASK_STATUSES = ['EXTRACTING', 'AI_PARSING', 'VALIDATING', 'PERSISTING'];
45
45
  const RECOVERABLE_IMPORT_TASK_STATUSES = ['QUEUED', 'EXTRACTING', 'AI_PARSING', 'VALIDATING', 'PERSISTING'];
46
+ const DELETABLE_IMPORT_TASK_STATUSES = [...RECOVERABLE_IMPORT_TASK_STATUSES, 'AWAITING_REVIEW', 'FAILED', 'TIMED_OUT'];
46
47
  const RECOVERABLE_REANALYSIS_STATUSES = ['PENDING', 'RUNNING'];
47
48
  const TERMINAL_IMPORT_TASK_STATUSES = ['AWAITING_REVIEW', 'SUCCEEDED', 'FAILED', 'TIMED_OUT', 'CANCELED'];
48
- const DELETABLE_IMPORT_TASK_STATUSES = [
49
- 'QUEUED', 'EXTRACTING', 'AI_PARSING', 'VALIDATING',
50
- 'AWAITING_REVIEW', 'PERSISTING', 'FAILED', 'TIMED_OUT'
51
- ];
52
49
  const CATALOG_RISK_RECOMMENDATIONS = {
53
50
  DUAL_USE: '建议核验军民两用物项许可要求,并在出口前完成合规审批',
54
51
  OVERSEAS_SANCTION: '建议核验海外制裁限制及交易对手风险,并在交易前完成合规审批'
@@ -231,7 +228,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
231
228
  async listActiveCustomerContractReanalyses(scope) {
232
229
  const [contracts, tasks] = await Promise.all([
233
230
  this.dataSource.getRepository(CustomerContract).find({ where: { ...activeScope(scope), currentReanalysisRunId: Not(IsNull()), deletedAt: IsNull() } }),
234
- this.dataSource.getRepository(ImportTask).find({ where: { ...activeScope(scope), currentReanalysisRunId: Not(IsNull()) } })
231
+ this.dataSource.getRepository(ImportTask).find({ where: { ...activeScope(scope), currentReanalysisRunId: Not(IsNull()), deletedAt: IsNull() } })
235
232
  ]);
236
233
  const unconsumedIds = new Set([...contracts, ...tasks].map(item => item.currentReanalysisRunId).filter((id) => Boolean(id)));
237
234
  const where = [
@@ -647,7 +644,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
647
644
  }
648
645
  async getImportTaskResult(scope, taskId) {
649
646
  await this.expireStaleImportTasks(scope);
650
- const task = await required(this.dataSource.getRepository(ImportTask).findOne({ where: { ...activeScope(scope), id: taskId } }), '解析任务不存在');
647
+ const task = await required(this.dataSource.getRepository(ImportTask).findOne({ where: { ...activeScope(scope), id: taskId, deletedAt: IsNull() } }), '解析任务不存在');
651
648
  const publicTask = publicImportTaskDto(task);
652
649
  if (!task.resultEntityId)
653
650
  return { task: publicTask };
@@ -1132,8 +1129,9 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1132
1129
  const task = await required(repo.findOne({
1133
1130
  where: { ...activeScope(scope), id: taskId }, lock: { mode: 'pessimistic_write' }
1134
1131
  }), '解析任务不存在');
1135
- if (isCanceledImportTask(task))
1132
+ if (task.deletedAt || TERMINAL_IMPORT_TASK_STATUSES.includes(task.status)) {
1136
1133
  return task;
1134
+ }
1137
1135
  if (task.observerConversationId && task.observerConversationId !== normalizedConversationId) {
1138
1136
  throw new DomainError(DomainErrorCodes.INVALID_INPUT, '观察会话标识不一致');
1139
1137
  }
@@ -1335,7 +1333,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1335
1333
  }
1336
1334
  async findNextQueuedImportTaskCandidate(scope) {
1337
1335
  return this.dataSource.getRepository(ImportTask).findOne({
1338
- where: { ...activeScope(scope), status: 'QUEUED' },
1336
+ where: { ...activeScope(scope), status: 'QUEUED', deletedAt: IsNull() },
1339
1337
  order: { queuedAt: 'ASC', id: 'ASC' }
1340
1338
  });
1341
1339
  }
@@ -1344,7 +1342,8 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1344
1342
  where: {
1345
1343
  ...activeScope(scope),
1346
1344
  documentType: In(['CONTROLLED_CATALOG', 'SANCTION_CATALOG']),
1347
- status: In(['EXTRACTING', 'VALIDATING', 'PERSISTING'])
1345
+ status: In(['EXTRACTING', 'VALIDATING', 'PERSISTING']),
1346
+ deletedAt: IsNull()
1348
1347
  },
1349
1348
  order: { startedAt: 'ASC', id: 'ASC' }
1350
1349
  });
@@ -1358,7 +1357,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1358
1357
  return null;
1359
1358
  const repo = manager.getRepository(ImportTask);
1360
1359
  const task = await repo.findOne({
1361
- where: { ...activeScope(scope), id, status: 'QUEUED' },
1360
+ where: { ...activeScope(scope), id, status: 'QUEUED', deletedAt: IsNull() },
1362
1361
  lock: { mode: 'pessimistic_write', onLocked: 'skip_locked' }
1363
1362
  });
1364
1363
  if (!task)
@@ -1381,7 +1380,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1381
1380
  if (await organizationHasActiveParsing(manager, scope))
1382
1381
  return null;
1383
1382
  const task = await repo.findOne({
1384
- where: { ...activeScope(scope), status: 'QUEUED' },
1383
+ where: { ...activeScope(scope), status: 'QUEUED', deletedAt: IsNull() },
1385
1384
  order: { queuedAt: 'ASC', id: 'ASC' },
1386
1385
  lock: { mode: 'pessimistic_write', onLocked: 'skip_locked' }
1387
1386
  });
@@ -1410,7 +1409,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1410
1409
  const recoveryScope = scope ? activeScope(scope) : {};
1411
1410
  const [tasks, runs] = await Promise.all([
1412
1411
  this.dataSource.getRepository(ImportTask).find({
1413
- where: { ...recoveryScope, status: In([...RECOVERABLE_IMPORT_TASK_STATUSES]) },
1412
+ where: { ...recoveryScope, status: In([...RECOVERABLE_IMPORT_TASK_STATUSES]), deletedAt: IsNull() },
1414
1413
  select: {
1415
1414
  id: true, tenantId: true, organizationId: true, targetAssistantId: true,
1416
1415
  status: true, claimAttemptToken: true, commandDispatchedAt: true, startedAt: true
@@ -1461,7 +1460,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1461
1460
  async failRecoverableImportWithoutTarget(snapshot) {
1462
1461
  await this.dataSource.transaction(async (manager) => {
1463
1462
  const repo = manager.getRepository(ImportTask);
1464
- const task = await repo.findOne({ where: { ...activeScope(snapshot), id: snapshot.id }, lock: { mode: 'pessimistic_write' } });
1463
+ const task = await repo.findOne({ where: { ...activeScope(snapshot), id: snapshot.id, deletedAt: IsNull() }, lock: { mode: 'pessimistic_write' } });
1465
1464
  if (!task || task.targetAssistantId || !RECOVERABLE_IMPORT_TASK_STATUSES.includes(task.status))
1466
1465
  return;
1467
1466
  await this.applyImportTaskFailure(manager, snapshot, task, 'FAILED', 'TARGET_ASSISTANT_MISSING', '历史解析任务缺少目标智能体,无法自动恢复');
@@ -1607,9 +1606,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1607
1606
  where: { ...activeScope(scope), id },
1608
1607
  lock: { mode: 'pessimistic_write' }
1609
1608
  }), '解析任务不存在');
1610
- if (task.status === 'AWAITING_REVIEW' || task.status === 'SUCCEEDED')
1611
- return task;
1612
- if (task.status === 'FAILED' || task.status === 'TIMED_OUT')
1609
+ if (TERMINAL_IMPORT_TASK_STATUSES.includes(task.status))
1613
1610
  return task;
1614
1611
  await this.applyImportTaskFailure(manager, scope, task, 'FAILED', 'AGENT_HANDOFF_RESULT_MISSING', '智能体已结束,但解析工具未保存业务结果');
1615
1612
  return repo.save(task);
@@ -1682,14 +1679,14 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
1682
1679
  const targetAssistantId = requiredId(requestedTargetAssistantId, '目标智能体标识');
1683
1680
  return this.dataSource.transaction(async (manager) => {
1684
1681
  const repo = manager.getRepository(ImportTask);
1685
- const source = await required(repo.findOne({ where: { ...activeScope(scope), id: sourceTaskId }, lock: { mode: 'pessimistic_write' } }), '解析任务不存在');
1682
+ const source = await required(repo.findOne({ where: { ...activeScope(scope), id: sourceTaskId, deletedAt: IsNull() }, lock: { mode: 'pessimistic_write' } }), '解析任务不存在');
1686
1683
  if (source.status !== 'FAILED' && source.status !== 'TIMED_OUT')
1687
1684
  throw new DomainError(DomainErrorCodes.INVALID_INPUT, '仅失败或超时任务可以重新解析');
1688
1685
  if (!['CONTROLLED_CATALOG', 'SANCTION_CATALOG', 'PURCHASE_CONTRACT', 'CUSTOMER_CONTRACT'].includes(source.documentType))
1689
1686
  throw new DomainError(DomainErrorCodes.INVALID_INPUT, '仅目录和合同任务支持重新解析');
1690
1687
  if (!source.executionInput)
1691
1688
  throw new DomainError(DomainErrorCodes.INVALID_INPUT, '原任务缺少可恢复执行参数');
1692
- const existing = await repo.findOne({ where: { ...activeScope(scope), retryOfTaskId: source.id } });
1689
+ const existing = await repo.findOne({ where: { ...activeScope(scope), retryOfTaskId: source.id, deletedAt: IsNull() } });
1693
1690
  if (existing) {
1694
1691
  return TERMINAL_IMPORT_TASK_STATUSES.includes(existing.status)
1695
1692
  ? { kind: 'EXISTING_TERMINAL', task: existing }
@@ -2396,7 +2393,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
2396
2393
  return outcome.run;
2397
2394
  }
2398
2395
  async getSourceFileDescriptor(scope, sourceFileId) {
2399
- const task = await required(this.dataSource.getRepository(ImportTask).findOne({ where: { ...activeScope(scope), sourceFileId } }), '源文件不存在');
2396
+ const task = await required(this.dataSource.getRepository(ImportTask).findOne({ where: { ...activeScope(scope), sourceFileId, deletedAt: IsNull() } }), '源文件不存在');
2400
2397
  return { sourceFileId: task.sourceFileId, sourceFileName: task.sourceFileName };
2401
2398
  }
2402
2399
  async updateCustomerContractReview(scope, id, input) {
@@ -3368,7 +3365,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
3368
3365
  }
3369
3366
  async expireStaleImportTasks(scope) {
3370
3367
  const repo = this.dataSource.getRepository(ImportTask);
3371
- const tasks = await repo.find({ where: { ...activeScope(scope), status: In(['QUEUED', 'EXTRACTING', 'AI_PARSING', 'VALIDATING', 'PERSISTING']) } });
3368
+ const tasks = await repo.find({ where: { ...activeScope(scope), status: In(['QUEUED', 'EXTRACTING', 'AI_PARSING', 'VALIDATING', 'PERSISTING']), deletedAt: IsNull() } });
3372
3369
  const now = new Date();
3373
3370
  for (const task of tasks) {
3374
3371
  const startedAt = task.startedAt ?? task.queuedAt ?? task.createdAt;
@@ -3376,7 +3373,7 @@ let TradeComplianceWorkbenchService = class TradeComplianceWorkbenchService {
3376
3373
  continue;
3377
3374
  await this.dataSource.transaction(async (manager) => {
3378
3375
  const lockedRepo = manager.getRepository(ImportTask);
3379
- const locked = await lockedRepo.findOne({ where: { ...activeScope(scope), id: task.id }, lock: { mode: 'pessimistic_write' } });
3376
+ const locked = await lockedRepo.findOne({ where: { ...activeScope(scope), id: task.id, deletedAt: IsNull() }, lock: { mode: 'pessimistic_write' } });
3380
3377
  if (!locked || !RECOVERABLE_IMPORT_TASK_STATUSES.includes(locked.status))
3381
3378
  return;
3382
3379
  const lockedStartedAt = locked.startedAt ?? locked.queuedAt ?? locked.createdAt;
@@ -3434,7 +3431,7 @@ async function lockOrganizationTaskClaim(manager, scope) {
3434
3431
  }
3435
3432
  async function organizationHasActiveParsing(manager, scope) {
3436
3433
  const activeImport = await manager.getRepository(ImportTask).findOne({
3437
- where: { ...activeScope(scope), status: In([...RUNNING_IMPORT_TASK_STATUSES]) },
3434
+ where: { ...activeScope(scope), status: In([...RUNNING_IMPORT_TASK_STATUSES]), deletedAt: IsNull() },
3438
3435
  order: { startedAt: 'ASC', id: 'ASC' },
3439
3436
  lock: { mode: 'pessimistic_write' }
3440
3437
  });
@@ -3448,7 +3445,7 @@ async function organizationHasActiveParsing(manager, scope) {
3448
3445
  return Boolean(activeRun);
3449
3446
  }
3450
3447
  function assertImportTaskResultWritable(task) {
3451
- if (TERMINAL_IMPORT_TASK_STATUSES.includes(task.status)) {
3448
+ if (task.deletedAt || TERMINAL_IMPORT_TASK_STATUSES.includes(task.status)) {
3452
3449
  throw new DomainError(DomainErrorCodes.INVALID_INPUT, '解析任务状态不允许保存结果');
3453
3450
  }
3454
3451
  }