@chenchaolong/plugin-trade-compliance-workbench 1.0.3 → 1.0.5

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 (97) hide show
  1. package/README.md +5 -3
  2. package/dist/lib/demo-data.definitions.js +1 -1
  3. package/dist/lib/demo-data.definitions.js.map +1 -1
  4. package/dist/lib/demo-data.service.d.ts.map +1 -1
  5. package/dist/lib/demo-data.service.js +1 -3
  6. package/dist/lib/demo-data.service.js.map +1 -1
  7. package/dist/lib/entities/index.d.ts +2 -2
  8. package/dist/lib/entities/index.d.ts.map +1 -1
  9. package/dist/lib/entities/index.js +2 -2
  10. package/dist/lib/entities/index.js.map +1 -1
  11. package/dist/lib/entities/shared.entity.d.ts +2 -5
  12. package/dist/lib/entities/shared.entity.d.ts.map +1 -1
  13. package/dist/lib/entities/shared.entity.js +5 -16
  14. package/dist/lib/entities/shared.entity.js.map +1 -1
  15. package/dist/lib/legacy-schema-cleanup.d.ts +9 -0
  16. package/dist/lib/legacy-schema-cleanup.d.ts.map +1 -0
  17. package/dist/lib/legacy-schema-cleanup.js +28 -0
  18. package/dist/lib/legacy-schema-cleanup.js.map +1 -0
  19. package/dist/lib/remote-components/trade-compliance-workbench/app.css +3268 -1
  20. package/dist/lib/remote-components/trade-compliance-workbench/app.js +5 -5
  21. package/dist/lib/remote-ui/app-source.d.ts.map +1 -1
  22. package/dist/lib/remote-ui/app-source.js +7 -6
  23. package/dist/lib/remote-ui/app-source.js.map +1 -1
  24. package/dist/lib/remote-ui/bridge.d.ts +0 -4
  25. package/dist/lib/remote-ui/bridge.d.ts.map +1 -1
  26. package/dist/lib/remote-ui/bridge.js +23 -20
  27. package/dist/lib/remote-ui/bridge.js.map +1 -1
  28. package/dist/lib/remote-ui/components/data-grid.js +1 -1
  29. package/dist/lib/remote-ui/components/data-grid.js.map +1 -1
  30. package/dist/lib/remote-ui/components/forms.js +2 -2
  31. package/dist/lib/remote-ui/components/forms.js.map +1 -1
  32. package/dist/lib/remote-ui/components/layout.d.ts +5 -1
  33. package/dist/lib/remote-ui/components/layout.d.ts.map +1 -1
  34. package/dist/lib/remote-ui/components/layout.js +23 -3
  35. package/dist/lib/remote-ui/components/layout.js.map +1 -1
  36. package/dist/lib/remote-ui/contracts.d.ts +1 -0
  37. package/dist/lib/remote-ui/contracts.d.ts.map +1 -1
  38. package/dist/lib/remote-ui/model.d.ts.map +1 -1
  39. package/dist/lib/remote-ui/model.js +11 -11
  40. package/dist/lib/remote-ui/model.js.map +1 -1
  41. package/dist/lib/remote-ui/pages/analytics.js +1 -1
  42. package/dist/lib/remote-ui/pages/analytics.js.map +1 -1
  43. package/dist/lib/remote-ui/pages/catalogs.js +14 -14
  44. package/dist/lib/remote-ui/pages/catalogs.js.map +1 -1
  45. package/dist/lib/remote-ui/pages/contracts.js +3 -3
  46. package/dist/lib/remote-ui/pages/contracts.js.map +1 -1
  47. package/dist/lib/remote-ui/pages/files.js +5 -5
  48. package/dist/lib/remote-ui/pages/files.js.map +1 -1
  49. package/dist/lib/remote-ui/pages/home.d.ts +18 -62
  50. package/dist/lib/remote-ui/pages/home.d.ts.map +1 -1
  51. package/dist/lib/remote-ui/pages/home.js +25 -131
  52. package/dist/lib/remote-ui/pages/home.js.map +1 -1
  53. package/dist/lib/remote-ui/pages/procurement.js +11 -11
  54. package/dist/lib/remote-ui/pages/procurement.js.map +1 -1
  55. package/dist/lib/remote-ui/pages/sales.js +8 -8
  56. package/dist/lib/remote-ui/pages/sales.js.map +1 -1
  57. package/dist/lib/remote-ui/pages/settings.d.ts +0 -3
  58. package/dist/lib/remote-ui/pages/settings.d.ts.map +1 -1
  59. package/dist/lib/remote-ui/pages/settings.js +7 -56
  60. package/dist/lib/remote-ui/pages/settings.js.map +1 -1
  61. package/dist/lib/remote-ui/settings-contracts.d.ts +2 -16
  62. package/dist/lib/remote-ui/settings-contracts.d.ts.map +1 -1
  63. package/dist/lib/remote-ui/settings-contracts.js +2 -2
  64. package/dist/lib/remote-ui/settings-contracts.js.map +1 -1
  65. package/dist/lib/remote-ui/sidebar-state.d.ts +5 -0
  66. package/dist/lib/remote-ui/sidebar-state.d.ts.map +1 -0
  67. package/dist/lib/remote-ui/sidebar-state.js +18 -0
  68. package/dist/lib/remote-ui/sidebar-state.js.map +1 -0
  69. package/dist/lib/runtime-validation.d.ts +0 -1
  70. package/dist/lib/runtime-validation.d.ts.map +1 -1
  71. package/dist/lib/runtime-validation.js +0 -17
  72. package/dist/lib/runtime-validation.js.map +1 -1
  73. package/dist/lib/types.d.ts +11 -10
  74. package/dist/lib/types.d.ts.map +1 -1
  75. package/dist/lib/types.js +8 -2
  76. package/dist/lib/types.js.map +1 -1
  77. package/dist/lib/view-parameters.d.ts +3 -0
  78. package/dist/lib/view-parameters.d.ts.map +1 -0
  79. package/dist/lib/view-parameters.js +23 -0
  80. package/dist/lib/view-parameters.js.map +1 -0
  81. package/dist/lib/workbench-view.provider.d.ts +14 -9
  82. package/dist/lib/workbench-view.provider.d.ts.map +1 -1
  83. package/dist/lib/workbench-view.provider.js +55 -20
  84. package/dist/lib/workbench-view.provider.js.map +1 -1
  85. package/dist/lib/workbench.plugin.d.ts +4 -1
  86. package/dist/lib/workbench.plugin.d.ts.map +1 -1
  87. package/dist/lib/workbench.plugin.js +12 -4
  88. package/dist/lib/workbench.plugin.js.map +1 -1
  89. package/dist/lib/workbench.service.d.ts +4 -8
  90. package/dist/lib/workbench.service.d.ts.map +1 -1
  91. package/dist/lib/workbench.service.js +10 -25
  92. package/dist/lib/workbench.service.js.map +1 -1
  93. package/package.json +3 -1
  94. package/dist/lib/domain/risk-notice.d.ts +0 -59
  95. package/dist/lib/domain/risk-notice.d.ts.map +0 -1
  96. package/dist/lib/domain/risk-notice.js +0 -30
  97. package/dist/lib/domain/risk-notice.js.map +0 -1
@@ -1,5 +1,17 @@
1
- import { type DefaultRiskOperationItem } from '../../domain/risk-notice.js';
2
- export type RiskOperationItem = DefaultRiskOperationItem;
1
+ export type RiskOperationItem = {
2
+ key: string;
3
+ title: string;
4
+ description: string;
5
+ icon: string;
6
+ };
7
+ export type WorkflowDirection = 'right' | 'down' | 'left' | null;
8
+ export type WorkflowArea = `step-${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8}`;
9
+ export type WorkflowLayout = {
10
+ area: WorkflowArea;
11
+ desktop: WorkflowDirection;
12
+ tablet: WorkflowDirection;
13
+ mobile: WorkflowDirection;
14
+ };
3
15
  export type WorkflowStep = {
4
16
  key: string;
5
17
  title: string;
@@ -7,65 +19,9 @@ export type WorkflowStep = {
7
19
  description: string;
8
20
  icon: string;
9
21
  tone: 'blue' | 'green' | 'violet' | 'orange';
22
+ layout: WorkflowLayout;
10
23
  };
11
- export type RiskNoticePayload = {
12
- content?: unknown;
13
- };
14
- export type HomePageProps = {
15
- dashboard?: Record<string, unknown> | null;
16
- riskNotice?: RiskNoticePayload | string | null;
17
- };
18
- export declare const RISK_OPERATION_ITEMS: readonly [{
19
- readonly key: "replace-controlled";
20
- readonly title: "覆盖管控目录";
21
- readonly description: "确认目录类型和被覆盖的历史文件。覆盖后新目录立即生效,原目录数据只在后台留痕,前端暂不支持恢复。";
22
- readonly icon: "ri-folder-warning-line";
23
- }, {
24
- readonly key: "duplicate-contract";
25
- readonly title: "重复上传合同";
26
- readonly description: "采购合同和客户合同均不允许覆盖;发现相同合同编码时系统会阻止上传。确需重传时必须先逻辑删除旧合同,旧合同人工金额不迁移到新记录。";
27
- readonly icon: "ri-upload-cloud-2-line";
28
- }, {
29
- readonly key: "replace-catalog";
30
- readonly title: "覆盖目录";
31
- readonly description: "管控商品目录和公司制裁目录覆盖都会立即影响风险结果,请确认被覆盖文件和记录数量。";
32
- readonly icon: "ri-book-open-line";
33
- }, {
34
- readonly key: "delete-business";
35
- readonly title: "删除业务数据";
36
- readonly description: "删除供应商、客户、订单、商品、目录记录或历史文件前,请确认其下游影响。业务删除和目录覆盖均为逻辑删除。";
37
- readonly icon: "ri-delete-bin-line";
38
- }, {
39
- readonly key: "payments";
40
- readonly title: "维护付款、收款和退税";
41
- readonly description: "采购和销售金额统一使用人民币;金额超过订单总额或预计退税额时系统将禁止保存。";
42
- readonly icon: "ri-money-cny-circle-line";
43
- }, {
44
- readonly key: "profit-rate";
45
- readonly title: "维护利润率";
46
- readonly description: "客户默认利润率会实时影响其全部未单独设置利润率的派生销售订单,历史生成文件不会自动更新。";
47
- readonly icon: "ri-line-chart-line";
48
- }, {
49
- readonly key: "risk-review";
50
- readonly title: "核对风险";
51
- readonly description: "系统会匹配管控商品目录和公司制裁目录;命中制裁公司只提示、不阻止保存,但必须人工核对风险明细。";
52
- readonly icon: "ri-shield-check-line";
53
- }, {
54
- readonly key: "sales-file";
55
- readonly title: "生成销售文件";
56
- readonly description: "生成前请确认公司信息、银行信息和利润率规则。模板辅助字段由用户在生成后的 Excel 中审核修改。";
57
- readonly icon: "ri-file-excel-2-line";
58
- }, {
59
- readonly key: "edit-excel";
60
- readonly title: "在线编辑 Excel";
61
- readonly description: "历史文件在线保存会直接覆盖当前文件,不保留旧版本,也不会反向更新采购合同、客户合同或数据分析数据。";
62
- readonly icon: "ri-edit-box-line";
63
- }, {
64
- readonly key: "confirm-operation";
65
- readonly title: "操作前请确认";
66
- readonly description: "外贸合规数据会直接影响合同关联、利润校验、销售文件和经营报表。执行目录覆盖、合同删除、金额修改或文件生成前,请核对业务对象和数据内容。";
67
- readonly icon: "ri-error-warning-line";
68
- }];
69
- export declare const WORKFLOW_STEPS: WorkflowStep[];
70
- export declare function HomePage({ dashboard, riskNotice }?: HomePageProps): import("react/jsx-runtime").JSX.Element;
24
+ export declare const RISK_OPERATION_ITEMS: readonly RiskOperationItem[];
25
+ export declare const WORKFLOW_STEPS: readonly WorkflowStep[];
26
+ export declare function HomePage(): import("react/jsx-runtime").JSX.Element;
71
27
  //# sourceMappingURL=home.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"home.d.ts","sourceRoot":"","sources":["../../../../src/lib/remote-ui/pages/home.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgC,KAAK,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AAEzG,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CAAA;AAExD,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC1C,UAAU,CAAC,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAA;CAC/C,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA+B,CAAA;AAEhE,eAAO,MAAM,cAAc,EAAE,YAAY,EASxC,CAAA;AAUD,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,GAAE,aAAkB,2CAkDrE"}
1
+ {"version":3,"file":"home.d.ts","sourceRoot":"","sources":["../../../../src/lib/remote-ui/pages/home.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AACjG,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAChE,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAA;AAClE,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAA;AACrI,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAA;AAEjM,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAWnD,CAAA;AAEV,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EASxC,CAAA;AAEV,wBAAgB,QAAQ,4CAcvB"}
@@ -1,136 +1,30 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React from 'react';
3
- import { DEFAULT_RISK_OPERATION_ITEMS } from '../../domain/risk-notice.js';
4
- export const RISK_OPERATION_ITEMS = DEFAULT_RISK_OPERATION_ITEMS;
2
+ export const RISK_OPERATION_ITEMS = [
3
+ { key: 'catalog-replace', title: '覆盖管控目录', description: '确认目录类型和被覆盖的历史文件。', icon: 'ri-file-warning-line' },
4
+ { key: 'duplicate-contract', title: '重复上传合同', description: '采购合同和客户合同不允许覆盖已有记录。', icon: 'ri-file-copy-2-line' },
5
+ { key: 'catalog-impact', title: '覆盖目录', description: '目录覆盖会立即影响商品和公司风险结果。', icon: 'ri-refresh-line' },
6
+ { key: 'delete-data', title: '删除业务数据', description: '删除前请核对其下游影响,前端不提供恢复。', icon: 'ri-delete-bin-line' },
7
+ { key: 'payments', title: '维护付款、收款和退税', description: '金额使用人民币,超过订单总额时禁止保存。', icon: 'ri-money-cny-circle-line' },
8
+ { key: 'profit', title: '维护利润率', description: '客户默认利润率会影响派生销售订单。', icon: 'ri-percent-line' },
9
+ { key: 'risk-review', title: '核对风险', description: '命中管控或制裁目录时必须人工复核。', icon: 'ri-shield-check-line' },
10
+ { key: 'generate-file', title: '生成销售文件', description: '生成前确认公司、银行和利润率规则。', icon: 'ri-file-excel-2-line' },
11
+ { key: 'edit-excel', title: '在线编辑 Excel', description: '保存会直接覆盖当前历史文件。', icon: 'ri-edit-box-line' },
12
+ { key: 'confirm', title: '操作前请确认', description: '目录、合同、金额和文件操作会影响下游业务。', icon: 'ri-error-warning-line' }
13
+ ];
5
14
  export const WORKFLOW_STEPS = [
6
- { key: 'catalogs', title: '维护管控商品与公司制裁目录', titleLines: ['维护管控商品与', '公司制裁目录'], description: '上传并维护管控商品目录和公司制裁目录', icon: 'ri-book-open-line', tone: 'blue' },
7
- { key: 'contracts', title: '上传并审核采购合同和客户合同', titleLines: ['上传并审核采购', '合同和客户合同'], description: '上传采购合同和客户合同并进行审核入库', icon: 'ri-file-upload-line', tone: 'green' },
8
- { key: 'risk-match', title: '商品及公司风险匹配', titleLines: ['商品及公司', '风险匹配'], description: '系统匹配目录进行商品和公司风险识别', icon: 'ri-shield-check-line', tone: 'violet' },
9
- { key: 'derive-sales', title: '自动派生销售订单', titleLines: ['自动派生', '销售订单'], description: '根据客户合同自动关联采购合同并派生订单', icon: 'ri-shopping-cart-line', tone: 'orange' },
10
- { key: 'profit-check', title: '利润率校验', titleLines: ['利润率校验'], description: '校验利润率是否符合企业规则和要求', icon: 'ri-percent-line', tone: 'blue' },
11
- { key: 'bank', title: '选择银行信息(报关单跳过)', titleLines: ['选择银行信息', '(报关单跳过)'], description: '选择或确认银行信息用于相关单据', icon: 'ri-bank-line', tone: 'green' },
12
- { key: 'review-files', title: '生成并在线审核销售文件', titleLines: ['生成并在线审核', '销售文件'], description: '生成销售文件并在 Excel 中审核修改', icon: 'ri-file-check-line', tone: 'violet' },
13
- { key: 'analytics', title: '数据分析', titleLines: ['数据分析'], description: '查看业务数据和经营分析报表', icon: 'ri-bar-chart-line', tone: 'blue' }
15
+ { key: 'catalogs', title: '维护管控商品与公司制裁目录', titleLines: ['维护管控商品与', '公司制裁目录'], description: '上传并维护管控商品目录和公司制裁目录', icon: 'ri-book-open-line', tone: 'blue', layout: { area: 'step-1', desktop: 'right', tablet: 'right', mobile: 'down' } },
16
+ { key: 'contracts', title: '上传并审核采购合同和客户合同', titleLines: ['上传并审核采购', '合同和客户合同'], description: '上传采购合同和客户合同并进行审核入库', icon: 'ri-file-upload-line', tone: 'green', layout: { area: 'step-2', desktop: 'right', tablet: 'down', mobile: 'down' } },
17
+ { key: 'risk-match', title: '商品及公司风险匹配', titleLines: ['商品及公司', '风险匹配'], description: '系统匹配目录进行商品和公司风险识别', icon: 'ri-shield-check-line', tone: 'violet', layout: { area: 'step-3', desktop: 'right', tablet: 'left', mobile: 'down' } },
18
+ { key: 'derive-sales', title: '自动派生销售订单', titleLines: ['自动派生', '销售订单'], description: '根据客户合同自动关联采购合同并派生订单', icon: 'ri-shopping-cart-line', tone: 'orange', layout: { area: 'step-4', desktop: 'down', tablet: 'down', mobile: 'down' } },
19
+ { key: 'profit-check', title: '利润率校验', titleLines: ['利润率校验'], description: '校验利润率是否符合企业规则和要求', icon: 'ri-percent-line', tone: 'blue', layout: { area: 'step-5', desktop: 'left', tablet: 'right', mobile: 'down' } },
20
+ { key: 'bank', title: '选择银行信息(报关单跳过)', titleLines: ['选择银行信息', '(报关单跳过)'], description: '选择或确认银行信息用于相关单据', icon: 'ri-bank-line', tone: 'green', layout: { area: 'step-6', desktop: 'left', tablet: 'down', mobile: 'down' } },
21
+ { key: 'review-files', title: '生成并在线审核销售文件', titleLines: ['生成并在线审核', '销售文件'], description: '生成销售文件并在 Excel 中审核修改', icon: 'ri-file-check-line', tone: 'violet', layout: { area: 'step-7', desktop: 'left', tablet: 'left', mobile: 'down' } },
22
+ { key: 'analytics', title: '数据分析', titleLines: ['数据分析'], description: '查看业务数据和经营分析报表', icon: 'ri-bar-chart-line', tone: 'blue', layout: { area: 'step-8', desktop: null, tablet: null, mobile: null } }
14
23
  ];
15
- const SAFE_RICH_TEXT_TAGS = new Set(['h2', 'h3', 'h4', 'p', 'strong', 'b', 'ul', 'ol', 'li', 'br']);
16
- const BLOCKED_RICH_TEXT_TAGS = new Set(['script', 'style', 'iframe', 'object', 'template', 'svg', 'math']);
17
- export function HomePage({ dashboard, riskNotice } = {}) {
18
- const configuredContent = resolveRiskNoticeContent(dashboard, riskNotice);
19
- const configuredNodes = configuredContent ? parseSafeRichText(configuredContent) : [];
20
- const configuredItems = extractRiskItems(configuredNodes);
21
- const riskItems = configuredContent ? configuredItems : RISK_OPERATION_ITEMS;
22
- return (_jsxs("div", { className: "tcw-home-page", children: [_jsxs("section", { className: "tcw-home-section", "aria-labelledby": "risk-operation-title", children: [_jsxs("h2", { id: "risk-operation-title", className: "tcw-home-section-title", children: [_jsx("i", { className: "ri-shield-flash-line", "aria-hidden": "true" }), "\u98CE\u9669\u64CD\u4F5C\u63D0\u793A"] }), riskItems.length > 0 ? (_jsx("div", { className: "tcw-home-risk-matrix", children: riskItems.map((item) => (_jsxs("article", { className: "tcw-home-risk-item", "data-risk-operation": item.key, children: [_jsxs("div", { className: "tcw-home-risk-heading", children: [_jsx("i", { className: item.icon, "aria-hidden": "true" }), _jsx("h3", { children: item.title })] }), _jsx("p", { children: item.description })] }, item.key))) })) : (_jsx("div", { className: "tcw-home-maintained-notice", "data-maintained-risk-notice": true, children: renderSafeRichTextNodes(configuredNodes, 'risk') }))] }), _jsxs("section", { className: "tcw-home-section", "aria-labelledby": "workflow-title", children: [_jsxs("div", { className: "tcw-home-workflow-heading", children: [_jsx("h2", { id: "workflow-title", className: "tcw-home-section-title", children: "\u4E1A\u52A1\u6D41\u7A0B\u56FE" }), _jsx("p", { children: "\u8BF7\u6309\u7167\u4EE5\u4E0B\u4E1A\u52A1\u6D41\u7A0B\u8FDB\u884C\u64CD\u4F5C" })] }), _jsx("div", { className: "tcw-home-workflow-scroll", children: _jsx("div", { className: "tcw-home-workflow", children: WORKFLOW_STEPS.map((step, index) => (_jsxs(React.Fragment, { children: [_jsxs("article", { className: `tcw-home-workflow-step tcw-home-workflow-step--${step.tone}`, "data-workflow-step": step.key, children: [_jsx("span", { className: "tcw-home-step-number", children: index + 1 }), _jsx("i", { className: step.icon, "aria-hidden": "true" }), _jsx("h3", { "aria-label": step.title, children: step.titleLines.map((line) => _jsx("span", { className: "tcw-home-step-title-line", children: line }, line)) }), _jsx("p", { children: step.description })] }), index < WORKFLOW_STEPS.length - 1 && (_jsx("i", { className: "ri-arrow-right-line tcw-home-workflow-connector", "data-workflow-connector": true, "aria-hidden": "true" }))] }, step.key))) }) })] })] }));
23
- }
24
- function resolveRiskNoticeContent(dashboard, riskNotice) {
25
- const source = riskNotice === undefined ? dashboard?.riskNotice : riskNotice;
26
- if (typeof source === 'string')
27
- return source.trim();
28
- if (!source || typeof source !== 'object')
29
- return '';
30
- const content = source.content;
31
- return typeof content === 'string' ? content.trim() : '';
32
- }
33
- function parseSafeRichText(content) {
34
- const root = { tag: 'root', children: [] };
35
- const stack = [root];
36
- const blockedTags = [];
37
- for (const token of content.match(/<[^>]*>|[^<]+|</g) ?? []) {
38
- if (!token.startsWith('<')) {
39
- if (blockedTags.length === 0)
40
- stack.at(-1)?.children.push(decodeHtmlEntities(token));
41
- continue;
42
- }
43
- const match = token.match(/^<\s*(\/?)\s*([a-z][a-z0-9]*)[^>]*>$/i);
44
- if (!match)
45
- continue;
46
- const closing = match[1] === '/';
47
- const rawTag = match[2].toLowerCase();
48
- const selfClosing = token.endsWith('/>');
49
- if (blockedTags.length > 0) {
50
- if (closing && rawTag === blockedTags.at(-1))
51
- blockedTags.pop();
52
- else if (!closing && !selfClosing && BLOCKED_RICH_TEXT_TAGS.has(rawTag))
53
- blockedTags.push(rawTag);
54
- continue;
55
- }
56
- if (BLOCKED_RICH_TEXT_TAGS.has(rawTag)) {
57
- if (!closing && !selfClosing)
58
- blockedTags.push(rawTag);
59
- continue;
60
- }
61
- if (!SAFE_RICH_TEXT_TAGS.has(rawTag))
62
- continue;
63
- const tag = rawTag === 'b' ? 'strong' : rawTag;
64
- if (closing) {
65
- let openIndex = -1;
66
- for (let index = stack.length - 1; index > 0; index -= 1) {
67
- if (stack[index].tag === tag) {
68
- openIndex = index;
69
- break;
70
- }
71
- }
72
- if (openIndex > 0)
73
- stack.splice(openIndex);
74
- continue;
75
- }
76
- const node = { tag, children: [] };
77
- stack.at(-1)?.children.push(node);
78
- if (tag !== 'br' && !selfClosing)
79
- stack.push(node);
80
- }
81
- return root.children;
82
- }
83
- function extractRiskItems(nodes) {
84
- const listItems = nodes.flatMap((node) => {
85
- if (typeof node === 'string' || (node.tag !== 'ul' && node.tag !== 'ol'))
86
- return [];
87
- return node.children.filter((child) => typeof child !== 'string' && child.tag === 'li');
88
- });
89
- return listItems.map((item, index) => {
90
- const titleNode = findFirstNode(item, 'strong');
91
- const title = titleNode ? nodeText(titleNode).trim() : `风险提示 ${index + 1}`;
92
- const description = nodeText(item, titleNode).replace(/^[\s::,,。-]+/, '').trim();
93
- return {
94
- key: `configured-${index + 1}`,
95
- title,
96
- description,
97
- icon: 'ri-error-warning-line'
98
- };
99
- });
100
- }
101
- function findFirstNode(node, tag) {
102
- for (const child of node.children) {
103
- if (typeof child === 'string')
104
- continue;
105
- if (child.tag === tag)
106
- return child;
107
- const nested = findFirstNode(child, tag);
108
- if (nested)
109
- return nested;
110
- }
111
- return null;
112
- }
113
- function nodeText(node, excluded = null) {
114
- return node.children.map((child) => {
115
- if (typeof child === 'string')
116
- return child;
117
- return child === excluded ? '' : nodeText(child, excluded);
118
- }).join('');
119
- }
120
- function renderSafeRichTextNodes(nodes, keyPrefix) {
121
- return nodes.map((node, index) => {
122
- if (typeof node === 'string')
123
- return node;
124
- return React.createElement(node.tag, { key: `${keyPrefix}-${index}` }, ...renderSafeRichTextNodes(node.children, `${keyPrefix}-${index}`));
125
- });
126
- }
127
- function decodeHtmlEntities(value) {
128
- const entities = { amp: '&', apos: "'", gt: '>', lt: '<', nbsp: '\u00a0', quot: '"' };
129
- return value.replace(/&(#x[\da-f]+|#\d+|[a-z]+);/gi, (entity, code) => {
130
- if (code[0] !== '#')
131
- return entities[code.toLowerCase()] ?? entity;
132
- const point = code[1].toLowerCase() === 'x' ? Number.parseInt(code.slice(2), 16) : Number.parseInt(code.slice(1), 10);
133
- return Number.isSafeInteger(point) && point >= 0 && point <= 0x10ffff ? String.fromCodePoint(point) : entity;
134
- });
24
+ export function HomePage() {
25
+ return _jsxs("div", { className: "tcw-home-page", children: [_jsxs("section", { className: "tcw-home-section", "aria-labelledby": "risk-operation-title", children: [_jsxs("h2", { id: "risk-operation-title", className: "tcw-home-section-title", children: [_jsx("i", { className: "ri-shield-flash-line", "aria-hidden": "true" }), "\u98CE\u9669\u64CD\u4F5C\u63D0\u793A"] }), _jsx("div", { className: "tcw-home-risk-matrix", children: RISK_OPERATION_ITEMS.map(item => _jsxs("article", { className: "tcw-home-risk-item", "data-risk-operation": item.key, children: [_jsxs("div", { className: "tcw-home-risk-heading", children: [_jsx("i", { className: item.icon, "aria-hidden": "true" }), _jsx("h3", { children: item.title })] }), _jsx("p", { children: item.description })] }, item.key)) })] }), _jsxs("section", { className: "tcw-home-section", "aria-labelledby": "workflow-title", children: [_jsxs("div", { className: "tcw-home-workflow-heading", children: [_jsx("h2", { id: "workflow-title", className: "tcw-home-section-title", children: "\u4E1A\u52A1\u6D41\u7A0B\u56FE" }), _jsx("p", { children: "\u8BF7\u6309\u7167\u4EE5\u4E0B\u4E1A\u52A1\u6D41\u7A0B\u8FDB\u884C\u64CD\u4F5C" })] }), _jsx("div", { className: "tcw-home-workflow", children: WORKFLOW_STEPS.map((step, index) => {
26
+ const { layout } = step;
27
+ return _jsxs("article", { className: `tcw-home-workflow-step tcw-home-workflow-step--${step.tone}`, style: { gridArea: layout.area }, "data-workflow-step": step.key, children: [_jsx("span", { className: "tcw-home-step-number", children: index + 1 }), _jsx("i", { className: step.icon, "aria-hidden": "true" }), _jsx("h3", { "aria-label": step.title, children: step.titleLines.map(line => _jsx("span", { className: "tcw-home-step-title-line", children: line }, line)) }), _jsx("p", { children: step.description }), layout.desktop && _jsx("i", { className: "ri-arrow-right-line tcw-home-workflow-connector", "data-workflow-connector": true, "data-desktop-direction": layout.desktop, "data-tablet-direction": layout.tablet ?? undefined, "data-mobile-direction": layout.mobile ?? undefined, "aria-hidden": "true" })] }, step.key);
28
+ }) })] })] });
135
29
  }
136
30
  //# sourceMappingURL=home.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"home.js","sourceRoot":"","sources":["../../../../src/lib/remote-ui/pages/home.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"home.js","sourceRoot":"","sources":["../../../../src/lib/remote-ui/pages/home.tsx"],"names":[],"mappings":"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"}
@@ -210,7 +210,7 @@ export function ProcurementPage(props) {
210
210
  return api.updatePurchaseLine({ ...item, id: item.id });
211
211
  };
212
212
  const reviewVisible = Boolean(props.importTask && (draft || props.importTask.duplicateContractError));
213
- return (_jsxs("section", { className: "tcw-procurement-page", "data-procurement-level": props.route.level, children: [message && _jsx("div", { className: "tcw-procurement-feedback", role: "status", children: message }), props.importTask && (props.importTask.status === 'FAILED' || props.importTask.status === 'TIMED_OUT') && _jsxs("div", { className: "tcw-procurement-feedback", role: "alert", children: [props.importTask.errorMessage || '采购合同解析失败', props.onRetryImport && _jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: () => void props.onRetryImport?.(props.importTask.id), children: "\u91CD\u65B0\u89E3\u6790" })] }), props.route.level === 'suppliers' && _jsx(SupplierLevel, { props: props, filters: filters, definitions: definitions, onFilter: changeFilter, onSubmit: () => scheduler.flush(filters), onReset: reset, onPage: (page) => void query(page, filters), onSupplierDialog: setSupplierDialog, onDelete: (item) => setDeleteTarget({ entityType: 'supplier', item }) }), props.route.level === 'orders' && _jsx(OrderLevel, { props: props, filters: filters, definitions: definitions, onFilter: changeFilter, onSubmit: () => scheduler.flush(filters), onReset: reset, onPage: (page) => void query(page, filters), onOrderDialog: setOrderDialog, onDelete: (item) => setDeleteTarget({ entityType: 'purchaseOrder', item }) }), props.route.level === 'lines' && _jsx(LineLevel, { props: props, filters: filters, definitions: definitions, onFilter: changeFilter, onSubmit: () => scheduler.flush(filters), onReset: reset, onPage: (page) => void query(page, filters), onLineDialog: setLineDialog, onDelete: (item) => setDeleteTarget({ entityType: 'purchaseLine', item }) }), _jsx(SupplierDialog, { state: supplierDialog, busy: props.busy, onClose: () => setSupplierDialog(null), onSave: (item) => execute(() => api.updateSupplier(item), '供应商主档已保存').then((saved) => { if (saved)
213
+ return (_jsxs("section", { className: "tcw-procurement-page", "data-procurement-level": props.route.level, children: [message && _jsx("div", { className: "tcw-procurement-feedback", role: "status", children: message }), props.importTask && (props.importTask.status === 'FAILED' || props.importTask.status === 'TIMED_OUT') && _jsxs("div", { className: "tcw-procurement-feedback", role: "alert", children: [props.importTask.errorMessage || '采购合同解析失败', props.onRetryImport && _jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: () => void props.onRetryImport?.(props.importTask.id), children: [_jsx("i", { className: "ri-restart-line", "aria-hidden": "true" }), "\u91CD\u65B0\u89E3\u6790"] })] }), props.route.level === 'suppliers' && _jsx(SupplierLevel, { props: props, filters: filters, definitions: definitions, onFilter: changeFilter, onSubmit: () => scheduler.flush(filters), onReset: reset, onPage: (page) => void query(page, filters), onSupplierDialog: setSupplierDialog, onDelete: (item) => setDeleteTarget({ entityType: 'supplier', item }) }), props.route.level === 'orders' && _jsx(OrderLevel, { props: props, filters: filters, definitions: definitions, onFilter: changeFilter, onSubmit: () => scheduler.flush(filters), onReset: reset, onPage: (page) => void query(page, filters), onOrderDialog: setOrderDialog, onDelete: (item) => setDeleteTarget({ entityType: 'purchaseOrder', item }) }), props.route.level === 'lines' && _jsx(LineLevel, { props: props, filters: filters, definitions: definitions, onFilter: changeFilter, onSubmit: () => scheduler.flush(filters), onReset: reset, onPage: (page) => void query(page, filters), onLineDialog: setLineDialog, onDelete: (item) => setDeleteTarget({ entityType: 'purchaseLine', item }) }), _jsx(SupplierDialog, { state: supplierDialog, busy: props.busy, onClose: () => setSupplierDialog(null), onSave: (item) => execute(() => api.updateSupplier(item), '供应商主档已保存').then((saved) => { if (saved)
214
214
  setSupplierDialog(null); }) }), _jsx(OrderDialog, { state: orderDialog, lines: props.purchaseLines.items, busy: props.busy, onClose: () => setOrderDialog(null), onSave: (item) => execute(() => api.updatePurchaseOrder(item), '采购订单已保存').then((saved) => { if (saved)
215
215
  setOrderDialog(null); }) }), _jsx(LineDialog, { state: lineDialog, order: props.order ?? null, busy: props.busy, onAction: props.onAction, onClose: () => setLineDialog(null), onSave: (item) => execute(() => saveLine(item), '采购商品已保存').then((saved) => { if (saved)
216
216
  setLineDialog(null); }) }), _jsx(PurchaseContractReviewDialog, { open: reviewVisible, task: props.importTask, draft: draft, busy: props.busy, onChange: setDraft, onClose: closeDraft, onSave: (nextDraft) => execute(() => api.savePurchaseReview(props.importTask.id, nextDraft), '采购合同审核已保存').then((saved) => { if (saved)
@@ -223,7 +223,7 @@ export function ProcurementPage(props) {
223
223
  }
224
224
  function SupplierLevel({ props, filters, definitions, onFilter, onSubmit, onReset, onPage, onSupplierDialog, onDelete }) {
225
225
  const columns = [
226
- { type: 'custom', key: 'code', header: '供应商代码', width: 130, render: (_, row) => _jsx(LinkButton, { onClick: () => row.id && props.onRouteChange({ type: 'procurement', level: 'orders', supplierId: row.id }), children: row.code || '—' }) },
226
+ { type: 'custom', key: 'code', header: '供应商代码', width: 130, render: (_, row) => _jsx(LinkButton, { icon: "ri-file-list-3-line", onClick: () => row.id && props.onRouteChange({ type: 'procurement', level: 'orders', supplierId: row.id }), children: row.code || '—' }) },
227
227
  { type: 'ellipsis', key: 'name', header: '供应商名称', width: 240, maxWidth: 240 },
228
228
  { type: 'text', key: 'shortName', header: '简称', width: 140 },
229
229
  { type: 'text', key: 'contactName', header: '联系人', width: 130 },
@@ -231,12 +231,12 @@ function SupplierLevel({ props, filters, definitions, onFilter, onSubmit, onRese
231
231
  { type: 'custom', key: 'sanctionStatus', header: '制裁风险', width: 110, render: (_, row) => _jsx(StatusTag, { tone: row.sanctionStatus === 'HIT' ? 'danger' : row.sanctionStatus === 'CLEAR' ? 'success' : 'muted', children: sanctionLabels[row.sanctionStatus ?? 'UNCHECKED'] }) },
232
232
  { type: 'text', key: 'createdAt', header: '创建时间', width: 170 }
233
233
  ];
234
- return _jsxs(_Fragment, { children: [_jsx(ProcurementLevelHeading, { title: "\u4F9B\u5E94\u5546\u5217\u8868", description: "\u4E00\u7EA7\u9875\u9762\uFF1A\u7BA1\u7406\u4F9B\u5E94\u5546\u4E3B\u6863\uFF0C\u5E76\u901A\u8FC7\u4F9B\u5E94\u5546\u4EE3\u7801\u8FDB\u5165\u8BE5\u4F9B\u5E94\u5546\u7684\u91C7\u8D2D\u8BA2\u5355\u5217\u8868\u3002" }), _jsx(FilterPanel, { definitions: definitions, values: filters, onChange: onFilter, onQuery: onSubmit, onReset: onReset }), _jsx(InfoNotice, { children: "\u91C7\u8D2D\u5408\u540C\u4E0A\u4F20\u540E\u81EA\u52A8\u5F52\u5165\u4F9B\u5E94\u5546\uFF1B\u540C\u540D\u4F9B\u5E94\u5546\u5F52\u5E76\u5230\u540C\u4E00\u4E3B\u6863\u3002\u70B9\u51FB\u4F9B\u5E94\u5546\u4EE3\u7801\u8FDB\u5165\u91C7\u8D2D\u8BA2\u5355\u5217\u8868\u3002" }), _jsx(DataGrid, { columns: columns, rows: props.suppliers.items, rowKey: (row, index) => row.id ?? index, pagination: pagination(props.suppliers), onPageChange: onPage, emptyText: "\u6682\u65E0\u4F9B\u5E94\u5546\u6570\u636E", actionWidth: 160, actions: (row) => _jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => onSupplierDialog({ mode: 'detail', item: row }), children: "\u8BE6\u60C5" }), _jsx("button", { type: "button", onClick: () => onSupplierDialog({ mode: 'review', item: row }), children: "\u5BA1\u6838" }), _jsx("button", { type: "button", className: "is-danger", onClick: () => onDelete(row), children: "\u5220\u9664" })] }) })] });
234
+ return _jsxs(_Fragment, { children: [_jsx(ProcurementLevelHeading, { title: "\u4F9B\u5E94\u5546\u5217\u8868", description: "\u4E00\u7EA7\u9875\u9762\uFF1A\u7BA1\u7406\u4F9B\u5E94\u5546\u4E3B\u6863\uFF0C\u5E76\u901A\u8FC7\u4F9B\u5E94\u5546\u4EE3\u7801\u8FDB\u5165\u8BE5\u4F9B\u5E94\u5546\u7684\u91C7\u8D2D\u8BA2\u5355\u5217\u8868\u3002" }), _jsx(FilterPanel, { definitions: definitions, values: filters, onChange: onFilter, onQuery: onSubmit, onReset: onReset }), _jsx(InfoNotice, { children: "\u91C7\u8D2D\u5408\u540C\u4E0A\u4F20\u540E\u81EA\u52A8\u5F52\u5165\u4F9B\u5E94\u5546\uFF1B\u540C\u540D\u4F9B\u5E94\u5546\u5F52\u5E76\u5230\u540C\u4E00\u4E3B\u6863\u3002\u70B9\u51FB\u4F9B\u5E94\u5546\u4EE3\u7801\u8FDB\u5165\u91C7\u8D2D\u8BA2\u5355\u5217\u8868\u3002" }), _jsx(DataGrid, { columns: columns, rows: props.suppliers.items, rowKey: (row, index) => row.id ?? index, pagination: pagination(props.suppliers), onPageChange: onPage, emptyText: "\u6682\u65E0\u4F9B\u5E94\u5546\u6570\u636E", actionWidth: 160, actions: (row) => _jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => onSupplierDialog({ mode: 'detail', item: row }), children: [_jsx("i", { className: "ri-eye-line", "aria-hidden": "true" }), "\u8BE6\u60C5"] }), _jsxs("button", { type: "button", onClick: () => onSupplierDialog({ mode: 'review', item: row }), children: [_jsx("i", { className: "ri-edit-line", "aria-hidden": "true" }), "\u5BA1\u6838"] }), _jsxs("button", { type: "button", className: "is-danger", onClick: () => onDelete(row), children: [_jsx("i", { className: "ri-delete-bin-line", "aria-hidden": "true" }), "\u5220\u9664"] })] }) })] });
235
235
  }
236
236
  function OrderLevel({ props, filters, definitions, onFilter, onSubmit, onReset, onPage, onOrderDialog, onDelete }) {
237
237
  const metrics = props.metrics ?? buildProcurementMetrics(props.purchaseOrders.items, props.purchaseLines.items);
238
238
  const columns = [
239
- { type: 'custom', key: 'contractNo', header: '采购合同编号', width: 160, render: (_, row) => _jsx(LinkButton, { onClick: () => row.id && props.onRouteChange({ type: 'procurement', level: 'lines', supplierId: props.route.level === 'orders' ? props.route.supplierId : row.supplierId, orderId: row.id }), children: row.contractNo }) },
239
+ { type: 'custom', key: 'contractNo', header: '采购合同编号', width: 160, render: (_, row) => _jsx(LinkButton, { icon: "ri-file-list-2-line", onClick: () => row.id && props.onRouteChange({ type: 'procurement', level: 'lines', supplierId: props.route.level === 'orders' ? props.route.supplierId : row.supplierId, orderId: row.id }), children: row.contractNo }) },
240
240
  { type: 'text', key: 'orderDate', header: '下单日期', width: 120 },
241
241
  { type: 'text', key: 'contractAmountCny', header: '采购金额(人民币)', width: 160, align: 'right', format: currency },
242
242
  { type: 'text', key: 'paidAmountCny', header: '已付款', width: 130, align: 'right', format: currency },
@@ -246,7 +246,7 @@ function OrderLevel({ props, filters, definitions, onFilter, onSubmit, onReset,
246
246
  { type: 'text', key: 'unrefundedAmount', header: '未退税', width: 130, align: 'right', accessor: (row) => balance(metrics, row).unrefundedAmountCny, format: currency },
247
247
  { type: 'text', key: 'customerContractNo', header: '匹配客户合同', width: 150, format: (value) => String(value || '未关联') }
248
248
  ];
249
- return _jsxs(_Fragment, { children: [props.supplier && _jsx(ProcurementContextBar, { level: "supplier", supplier: props.supplier, onRouteChange: props.onRouteChange }), _jsx(ProcurementLevelHeading, { title: "\u91C7\u8D2D\u8BA2\u5355\u5217\u8868", description: "\u4E8C\u7EA7\u9875\u9762\uFF1A\u67E5\u770B\u5F53\u524D\u4F9B\u5E94\u5546\u7684\u91C7\u8D2D\u8BA2\u5355\uFF0C\u5E76\u901A\u8FC7\u91C7\u8D2D\u5408\u540C\u7F16\u53F7\u8FDB\u5165\u8BA2\u5355\u5546\u54C1\u5217\u8868\u3002" }), _jsx(MetricStrip, { metrics: metrics }), _jsx(FilterPanel, { definitions: definitions, values: filters, onChange: onFilter, onQuery: onSubmit, onReset: onReset }), _jsx(DataGrid, { columns: columns, rows: props.purchaseOrders.items, rowKey: (row, index) => row.id ?? index, pagination: pagination(props.purchaseOrders), onPageChange: onPage, emptyText: "\u6682\u65E0\u91C7\u8D2D\u8BA2\u5355\u6570\u636E", actionWidth: 160, actions: (row) => _jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => onOrderDialog({ mode: 'detail', item: row }), children: "\u8BE6\u60C5" }), _jsx("button", { type: "button", onClick: () => onOrderDialog({ mode: 'review', item: row }), children: "\u5BA1\u6838" }), _jsx("button", { type: "button", className: "is-danger", onClick: () => onDelete(row), children: "\u5220\u9664" })] }) })] });
249
+ return _jsxs(_Fragment, { children: [props.supplier && _jsx(ProcurementContextBar, { level: "supplier", supplier: props.supplier, onRouteChange: props.onRouteChange }), _jsx(ProcurementLevelHeading, { title: "\u91C7\u8D2D\u8BA2\u5355\u5217\u8868", description: "\u4E8C\u7EA7\u9875\u9762\uFF1A\u67E5\u770B\u5F53\u524D\u4F9B\u5E94\u5546\u7684\u91C7\u8D2D\u8BA2\u5355\uFF0C\u5E76\u901A\u8FC7\u91C7\u8D2D\u5408\u540C\u7F16\u53F7\u8FDB\u5165\u8BA2\u5355\u5546\u54C1\u5217\u8868\u3002" }), _jsx(MetricStrip, { metrics: metrics }), _jsx(FilterPanel, { definitions: definitions, values: filters, onChange: onFilter, onQuery: onSubmit, onReset: onReset }), _jsx(DataGrid, { columns: columns, rows: props.purchaseOrders.items, rowKey: (row, index) => row.id ?? index, pagination: pagination(props.purchaseOrders), onPageChange: onPage, emptyText: "\u6682\u65E0\u91C7\u8D2D\u8BA2\u5355\u6570\u636E", actionWidth: 160, actions: (row) => _jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => onOrderDialog({ mode: 'detail', item: row }), children: [_jsx("i", { className: "ri-eye-line", "aria-hidden": "true" }), "\u8BE6\u60C5"] }), _jsxs("button", { type: "button", onClick: () => onOrderDialog({ mode: 'review', item: row }), children: [_jsx("i", { className: "ri-edit-line", "aria-hidden": "true" }), "\u5BA1\u6838"] }), _jsxs("button", { type: "button", className: "is-danger", onClick: () => onDelete(row), children: [_jsx("i", { className: "ri-delete-bin-line", "aria-hidden": "true" }), "\u5220\u9664"] })] }) })] });
250
250
  }
251
251
  function LineLevel({ props, filters, definitions, onFilter, onSubmit, onReset, onPage, onLineDialog, onDelete }) {
252
252
  const columns = [
@@ -265,7 +265,7 @@ function LineLevel({ props, filters, definitions, onFilter, onSubmit, onReset, o
265
265
  { type: 'text', key: 'sourceType', header: '来源类型', width: 110, format: (value) => sourceTypeLabels[value] }
266
266
  ];
267
267
  const newLine = { purchaseOrderId: props.order?.id ?? '', sourceType: 'MANUAL_ENTRY', productName: '', quantity: '', unitPriceTaxIncluded: '', lineAmountTaxIncluded: '', hsCodeStatus: 'UNCONFIRMED' };
268
- return _jsxs(_Fragment, { children: [_jsx(ProcurementLevelHeading, { title: "\u91C7\u8D2D\u5546\u54C1\u5217\u8868", description: "\u4E09\u7EA7\u9875\u9762\uFF1A\u67E5\u770B\u5F53\u524D\u91C7\u8D2D\u8BA2\u5355\u7684\u5546\u54C1\u660E\u7EC6\uFF0C\u53EF\u65B0\u589E\u3001\u5BA1\u6838\u548C\u903B\u8F91\u5220\u9664\u5546\u54C1\u3002", commands: _jsxs("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: props.busy || !props.order?.id, onClick: () => onLineDialog({ mode: 'create', item: newLine }), children: [_jsx("i", { className: "ri-add-line", "aria-hidden": "true" }), "\u65B0\u589E\u5546\u54C1"] }) }), props.supplier && props.order && _jsx(ProcurementContextBar, { level: "order", supplier: props.supplier, order: props.order, onRouteChange: props.onRouteChange }), _jsx(FilterPanel, { definitions: definitions, values: filters, onChange: onFilter, onQuery: onSubmit, onReset: onReset }), _jsx(InfoNotice, { children: "\u53EF\u901A\u8FC7\u5BA1\u6838\u5B8C\u5584\u82F1\u6587\u540D\u79F0\u3001\u6D77\u5173\u7F16\u7801\u3001\u9000\u7A0E\u7387\u548C\u98CE\u9669\u5339\u914D\u4FE1\u606F\u3002" }), _jsx(DataGrid, { columns: columns, rows: props.purchaseLines.items, rowKey: (row, index) => row.id ?? index, pagination: pagination(props.purchaseLines), onPageChange: onPage, emptyText: "\u6682\u65E0\u91C7\u8D2D\u5546\u54C1\u6570\u636E", actionWidth: 120, actions: (row) => _jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => onLineDialog({ mode: 'review', item: row }), children: "\u5BA1\u6838" }), _jsx("button", { type: "button", className: "is-danger", onClick: () => onDelete(row), children: "\u5220\u9664" })] }) })] });
268
+ return _jsxs(_Fragment, { children: [_jsx(ProcurementLevelHeading, { title: "\u91C7\u8D2D\u5546\u54C1\u5217\u8868", description: "\u4E09\u7EA7\u9875\u9762\uFF1A\u67E5\u770B\u5F53\u524D\u91C7\u8D2D\u8BA2\u5355\u7684\u5546\u54C1\u660E\u7EC6\uFF0C\u53EF\u65B0\u589E\u3001\u5BA1\u6838\u548C\u903B\u8F91\u5220\u9664\u5546\u54C1\u3002", commands: _jsxs("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: props.busy || !props.order?.id, onClick: () => onLineDialog({ mode: 'create', item: newLine }), children: [_jsx("i", { className: "ri-add-line", "aria-hidden": "true" }), "\u65B0\u589E\u5546\u54C1"] }) }), props.supplier && props.order && _jsx(ProcurementContextBar, { level: "order", supplier: props.supplier, order: props.order, onRouteChange: props.onRouteChange }), _jsx(FilterPanel, { definitions: definitions, values: filters, onChange: onFilter, onQuery: onSubmit, onReset: onReset }), _jsx(InfoNotice, { children: "\u53EF\u901A\u8FC7\u5BA1\u6838\u5B8C\u5584\u82F1\u6587\u540D\u79F0\u3001\u6D77\u5173\u7F16\u7801\u3001\u9000\u7A0E\u7387\u548C\u98CE\u9669\u5339\u914D\u4FE1\u606F\u3002" }), _jsx(DataGrid, { columns: columns, rows: props.purchaseLines.items, rowKey: (row, index) => row.id ?? index, pagination: pagination(props.purchaseLines), onPageChange: onPage, emptyText: "\u6682\u65E0\u91C7\u8D2D\u5546\u54C1\u6570\u636E", actionWidth: 120, actions: (row) => _jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => onLineDialog({ mode: 'review', item: row }), children: [_jsx("i", { className: "ri-edit-line", "aria-hidden": "true" }), "\u5BA1\u6838"] }), _jsxs("button", { type: "button", className: "is-danger", onClick: () => onDelete(row), children: [_jsx("i", { className: "ri-delete-bin-line", "aria-hidden": "true" }), "\u5220\u9664"] })] }) })] });
269
269
  }
270
270
  function ProcurementLevelHeading({ title, description, commands }) {
271
271
  return _jsxs("header", { className: "tcw-procurement-level-heading", children: [_jsxs("div", { children: [_jsx("h2", { children: title }), _jsx("p", { children: description })] }), commands && _jsx("div", { className: "tcw-procurement-toolbar", children: commands })] });
@@ -291,7 +291,7 @@ function SupplierDialog({ state, busy, onClose, onSave }) {
291
291
  const fields = [
292
292
  ['code', '供应商代码'], ['name', '供应商名称', true], ['shortName', '简称'], ['countryOrRegion', '国别/地区'], ['contactName', '联系人'], ['phone', '联系电话'], ['wechat', '微信'], ['email', '邮箱'], ['address', '地址'], ['taxNumber', '税号'], ['paymentAccount', '收款账号'], ['bankName', '开户行'], ['taxpayerRating', '纳税等级'], ['website', '公司网站'], ['businessProducts', '经营产品']
293
293
  ];
294
- return _jsxs(Modal, { open: true, title: state.mode === 'detail' ? '供应商详情' : '供应商详情审核', size: "wide", onClose: onClose, footer: disabled ? _jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: "\u5173\u95ED" }) : _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: "\u53D6\u6D88" }), _jsx("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || !value.name.trim(), onClick: () => void onSave(value), children: "\u4FDD\u5B58" })] }), children: [_jsx(FieldGrid, { columns: 2, children: fields.map(([key, label, required]) => _jsx(FormField, { label: label, required: required, full: key === 'address' || key === 'businessProducts', children: _jsx("input", { disabled: disabled, value: String(value[key] ?? ''), onChange: (event) => setValue({ ...value, [key]: event.target.value }) }) }, key)) }), _jsxs("div", { className: "tcw-procurement-audit-meta", children: [_jsx(StatusTag, { tone: value.sanctionStatus === 'HIT' ? 'danger' : 'success', children: sanctionLabels[value.sanctionStatus ?? 'UNCHECKED'] }), _jsxs("span", { children: ["\u6700\u8FD1\u5236\u88C1\u68C0\u67E5\uFF1A", value.complianceCheckedAt || '尚未检查'] }), _jsxs("span", { children: ["\u6700\u540E\u7F16\u8F91\uFF1A", value.updatedByName || '—', " ", value.updatedAt || ''] })] })] });
294
+ return _jsxs(Modal, { open: true, title: state.mode === 'detail' ? '供应商详情' : '供应商详情审核', size: "wide", onClose: onClose, footer: disabled ? _jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: [_jsx("i", { className: "ri-close-line", "aria-hidden": "true" }), "\u5173\u95ED"] }) : _jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: [_jsx("i", { className: "ri-close-line", "aria-hidden": "true" }), "\u53D6\u6D88"] }), _jsxs("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || !value.name.trim(), onClick: () => void onSave(value), children: [_jsx("i", { className: "ri-save-line", "aria-hidden": "true" }), "\u4FDD\u5B58"] })] }), children: [_jsx(FieldGrid, { columns: 2, children: fields.map(([key, label, required]) => _jsx(FormField, { label: label, required: required, full: key === 'address' || key === 'businessProducts', children: _jsx("input", { disabled: disabled, value: String(value[key] ?? ''), onChange: (event) => setValue({ ...value, [key]: event.target.value }) }) }, key)) }), _jsxs("div", { className: "tcw-procurement-audit-meta", children: [_jsx(StatusTag, { tone: value.sanctionStatus === 'HIT' ? 'danger' : 'success', children: sanctionLabels[value.sanctionStatus ?? 'UNCHECKED'] }), _jsxs("span", { children: ["\u6700\u8FD1\u5236\u88C1\u68C0\u67E5\uFF1A", value.complianceCheckedAt || '尚未检查'] }), _jsxs("span", { children: ["\u6700\u540E\u7F16\u8F91\uFF1A", value.updatedByName || '—', " ", value.updatedAt || ''] })] })] });
295
295
  }
296
296
  function OrderDialog({ state, lines, busy, onClose, onSave }) {
297
297
  const [value, setValue] = React.useState(state?.item ?? null);
@@ -301,7 +301,7 @@ function OrderDialog({ state, lines, busy, onClose, onSave }) {
301
301
  const disabled = state.mode === 'detail';
302
302
  const estimated = value.estimatedRefundAmountCny ?? lines.filter((item) => item.purchaseOrderId === value.id).reduce((total, item) => total + estimatedLineRefund(item), 0).toFixed(2);
303
303
  const error = amount(value.paidAmountCny) > amount(value.contractAmountCny) ? '已付款不能超过采购订单总额' : amount(value.refundedAmountCny) > amount(estimated) ? '已退税不能超过预计退税总额' : '';
304
- return _jsxs(Modal, { open: true, title: disabled ? '采购订单详情' : '采购订单审核', size: "wide", onClose: onClose, footer: disabled ? _jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: "\u5173\u95ED" }) : _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: "\u53D6\u6D88" }), _jsx("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || Boolean(error) || !value.orderDate, onClick: () => void onSave(value), children: "\u4FDD\u5B58" })] }), children: [error && _jsx(RiskNotice, { children: error }), _jsxs(FieldGrid, { columns: 2, children: [_jsx(FormField, { label: "\u91C7\u8D2D\u5408\u540C\u7F16\u53F7", required: true, children: _jsx("input", { disabled: true, value: value.contractNo }) }), _jsx(FormField, { label: "\u4E0B\u5355\u65E5\u671F", required: true, children: _jsx("input", { type: "date", disabled: disabled, value: value.orderDate, onChange: (event) => setValue({ ...value, orderDate: event.target.value }) }) }), _jsx(MoneyField, { label: "\u91C7\u8D2D\u8BA2\u5355\u603B\u989D", disabled: disabled, value: value.contractAmountCny, onChange: (next) => setValue({ ...value, contractAmountCny: next }) }), _jsx(MoneyField, { label: "\u5DF2\u4ED8\u6B3E", disabled: disabled, value: value.paidAmountCny, onChange: (next) => setValue({ ...value, paidAmountCny: next }) }), _jsx(MoneyField, { label: "\u672A\u4ED8\u6B3E", disabled: true, value: String(Math.max(amount(value.contractAmountCny) - amount(value.paidAmountCny), 0)) }), _jsx(MoneyField, { label: "\u5DF2\u9000\u7A0E", disabled: disabled, value: value.refundedAmountCny, onChange: (next) => setValue({ ...value, refundedAmountCny: next }) }), _jsx(MoneyField, { label: "\u9884\u8BA1\u9000\u7A0E\u603B\u989D", disabled: true, value: estimated }), _jsx(MoneyField, { label: "\u672A\u9000\u7A0E", disabled: true, value: String(Math.max(amount(estimated) - amount(value.refundedAmountCny), 0)) }), _jsx(FormField, { label: "\u5339\u914D\u5BA2\u6237\u5408\u540C", children: _jsx("input", { disabled: true, value: value.customerContractNo || '未关联' }) }), _jsx(FormField, { label: "\u6765\u6E90\u6587\u4EF6", children: _jsx("input", { disabled: true, value: value.sourceFileName || '—' }) })] })] });
304
+ return _jsxs(Modal, { open: true, title: disabled ? '采购订单详情' : '采购订单审核', size: "wide", onClose: onClose, footer: disabled ? _jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: [_jsx("i", { className: "ri-close-line", "aria-hidden": "true" }), "\u5173\u95ED"] }) : _jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: [_jsx("i", { className: "ri-close-line", "aria-hidden": "true" }), "\u53D6\u6D88"] }), _jsxs("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || Boolean(error) || !value.orderDate, onClick: () => void onSave(value), children: [_jsx("i", { className: "ri-save-line", "aria-hidden": "true" }), "\u4FDD\u5B58"] })] }), children: [error && _jsx(RiskNotice, { children: error }), _jsxs(FieldGrid, { columns: 2, children: [_jsx(FormField, { label: "\u91C7\u8D2D\u5408\u540C\u7F16\u53F7", required: true, children: _jsx("input", { disabled: true, value: value.contractNo }) }), _jsx(FormField, { label: "\u4E0B\u5355\u65E5\u671F", required: true, children: _jsx("input", { type: "date", disabled: disabled, value: value.orderDate, onChange: (event) => setValue({ ...value, orderDate: event.target.value }) }) }), _jsx(MoneyField, { label: "\u91C7\u8D2D\u8BA2\u5355\u603B\u989D", disabled: disabled, value: value.contractAmountCny, onChange: (next) => setValue({ ...value, contractAmountCny: next }) }), _jsx(MoneyField, { label: "\u5DF2\u4ED8\u6B3E", disabled: disabled, value: value.paidAmountCny, onChange: (next) => setValue({ ...value, paidAmountCny: next }) }), _jsx(MoneyField, { label: "\u672A\u4ED8\u6B3E", disabled: true, value: String(Math.max(amount(value.contractAmountCny) - amount(value.paidAmountCny), 0)) }), _jsx(MoneyField, { label: "\u5DF2\u9000\u7A0E", disabled: disabled, value: value.refundedAmountCny, onChange: (next) => setValue({ ...value, refundedAmountCny: next }) }), _jsx(MoneyField, { label: "\u9884\u8BA1\u9000\u7A0E\u603B\u989D", disabled: true, value: estimated }), _jsx(MoneyField, { label: "\u672A\u9000\u7A0E", disabled: true, value: String(Math.max(amount(estimated) - amount(value.refundedAmountCny), 0)) }), _jsx(FormField, { label: "\u5339\u914D\u5BA2\u6237\u5408\u540C", children: _jsx("input", { disabled: true, value: value.customerContractNo || '未关联' }) }), _jsx(FormField, { label: "\u6765\u6E90\u6587\u4EF6", children: _jsx("input", { disabled: true, value: value.sourceFileName || '—' }) })] })] });
305
305
  }
306
306
  function LineDialog({ state, order, busy, onAction, onClose, onSave }) {
307
307
  const [value, setValue] = React.useState(state?.item ?? null);
@@ -317,12 +317,12 @@ function LineDialog({ state, order, busy, onAction, onClose, onSave }) {
317
317
  return Promise.resolve({ success: false, message: '采购商品仅支持海关编码查询' });
318
318
  return onAction(actionKey, input);
319
319
  };
320
- return _jsxs(_Fragment, { children: [_jsxs(Modal, { open: true, title: state.mode === 'create' ? '新增商品' : '采购商品审核', size: "wide", onClose: onClose, footer: _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: "\u53D6\u6D88" }), _jsx("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || errors.length > 0, onClick: () => void onSave(value), children: "\u4FDD\u5B58" })] }), children: [_jsxs("div", { className: "tcw-procurement-source-label", children: ["\u6765\u6E90\u7C7B\u578B\uFF1A", sourceTypeLabels[value.sourceType]] }), errors.length > 0 && _jsx(RiskNotice, { children: errors.join(';') }), _jsxs(FieldGrid, { columns: 2, children: [_jsx(TextField, { label: "\u5546\u54C1\u540D\u79F0", required: true, value: value.productName, onChange: (next) => setValue({ ...value, productName: next }) }), _jsx(TextField, { label: "\u5546\u54C1\u63CF\u8FF0", value: value.productDescription, onChange: (next) => setValue({ ...value, productDescription: next }) }), _jsx(TextField, { label: "\u89C4\u683C\u578B\u53F7", value: value.modelSpecification, onChange: (next) => setValue({ ...value, modelSpecification: next }) }), _jsx(TextField, { label: "\u5355\u4F4D", required: true, value: value.unit, onChange: (next) => setValue({ ...value, unit: next }) }), _jsx(TextField, { label: "\u6570\u91CF", required: true, type: "number", value: value.quantity, onChange: (next) => setValue({ ...value, quantity: next, lineAmountTaxIncluded: String(amount(next) * amount(value.unitPriceTaxIncluded)) }) }), _jsx(TextField, { label: "\u542B\u7A0E\u5355\u4EF7\uFF08\u4EBA\u6C11\u5E01\uFF09", required: true, type: "number", value: value.unitPriceTaxIncluded, onChange: (next) => setValue({ ...value, unitPriceTaxIncluded: next, lineAmountTaxIncluded: String(amount(value.quantity) * amount(next)) }) }), _jsx(TextField, { label: "\u542B\u7A0E\u91D1\u989D\uFF08\u4EBA\u6C11\u5E01\uFF09", required: true, type: "number", value: value.lineAmountTaxIncluded || String(computedAmount), onChange: (next) => setValue({ ...value, lineAmountTaxIncluded: next }) }), _jsx(TextField, { label: "\u589E\u503C\u7A0E\u7387", required: true, type: "number", value: value.vatRate, onChange: (next) => setValue({ ...value, vatRate: next }) }), _jsx(FormField, { label: "\u6D77\u5173\u7F16\u7801", children: _jsxs("div", { className: "tcw-procurement-inline-field", children: [_jsx("input", { value: value.hsCode ?? '', onChange: (event) => setValue({ ...value, hsCode: event.target.value }) }), _jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: () => setHsOpen(true), children: "HS\u7F16\u7801\u67E5\u8BE2" })] }) }), _jsx(FormField, { label: "\u7F16\u7801\u786E\u8BA4\u72B6\u6001", children: _jsx("select", { value: value.hsCodeStatus ?? 'UNCONFIRMED', onChange: (event) => setValue({ ...value, hsCodeStatus: event.target.value }), children: enumOptions(hsStatusLabels).map((item) => _jsx("option", { value: item.value, children: item.label }, item.value)) }) }), _jsx(TextField, { label: "\u9000\u7A0E\u7387", required: true, type: "number", value: value.refundRate, onChange: (next) => setValue({ ...value, refundRate: next }) }), _jsx(TextField, { label: "\u9000\u7A0E\u653F\u7B56\u4F9D\u636E", required: true, value: value.refundPolicyReference, onChange: (next) => setValue({ ...value, refundPolicyReference: next }) }), _jsx(TextField, { label: "\u653F\u7B56\u65E5\u671F", required: true, type: "date", value: value.refundPolicyDate, onChange: (next) => setValue({ ...value, refundPolicyDate: next, refundValidationMethod: 'REVIEW_CONFIRMED' }) }), _jsx(TextField, { label: "\u82F1\u6587\u540D\u79F0", value: value.englishName, onChange: (next) => setValue({ ...value, englishName: next }) })] })] }), _jsx(HsCodeLookupDialog, { open: hsOpen, initialQuery: value.hsCode || value.englishName || value.productName, onAction: hsAction, onClose: () => setHsOpen(false) })] });
320
+ return _jsxs(_Fragment, { children: [_jsxs(Modal, { open: true, title: state.mode === 'create' ? '新增商品' : '采购商品审核', size: "wide", onClose: onClose, footer: _jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: [_jsx("i", { className: "ri-close-line", "aria-hidden": "true" }), "\u53D6\u6D88"] }), _jsxs("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || errors.length > 0, onClick: () => void onSave(value), children: [_jsx("i", { className: "ri-save-line", "aria-hidden": "true" }), "\u4FDD\u5B58"] })] }), children: [_jsxs("div", { className: "tcw-procurement-source-label", children: ["\u6765\u6E90\u7C7B\u578B\uFF1A", sourceTypeLabels[value.sourceType]] }), errors.length > 0 && _jsx(RiskNotice, { children: errors.join(';') }), _jsxs(FieldGrid, { columns: 2, children: [_jsx(TextField, { label: "\u5546\u54C1\u540D\u79F0", required: true, value: value.productName, onChange: (next) => setValue({ ...value, productName: next }) }), _jsx(TextField, { label: "\u5546\u54C1\u63CF\u8FF0", value: value.productDescription, onChange: (next) => setValue({ ...value, productDescription: next }) }), _jsx(TextField, { label: "\u89C4\u683C\u578B\u53F7", value: value.modelSpecification, onChange: (next) => setValue({ ...value, modelSpecification: next }) }), _jsx(TextField, { label: "\u5355\u4F4D", required: true, value: value.unit, onChange: (next) => setValue({ ...value, unit: next }) }), _jsx(TextField, { label: "\u6570\u91CF", required: true, type: "number", value: value.quantity, onChange: (next) => setValue({ ...value, quantity: next, lineAmountTaxIncluded: String(amount(next) * amount(value.unitPriceTaxIncluded)) }) }), _jsx(TextField, { label: "\u542B\u7A0E\u5355\u4EF7\uFF08\u4EBA\u6C11\u5E01\uFF09", required: true, type: "number", value: value.unitPriceTaxIncluded, onChange: (next) => setValue({ ...value, unitPriceTaxIncluded: next, lineAmountTaxIncluded: String(amount(value.quantity) * amount(next)) }) }), _jsx(TextField, { label: "\u542B\u7A0E\u91D1\u989D\uFF08\u4EBA\u6C11\u5E01\uFF09", required: true, type: "number", value: value.lineAmountTaxIncluded || String(computedAmount), onChange: (next) => setValue({ ...value, lineAmountTaxIncluded: next }) }), _jsx(TextField, { label: "\u589E\u503C\u7A0E\u7387", required: true, type: "number", value: value.vatRate, onChange: (next) => setValue({ ...value, vatRate: next }) }), _jsx(FormField, { label: "\u6D77\u5173\u7F16\u7801", children: _jsxs("div", { className: "tcw-procurement-inline-field", children: [_jsx("input", { value: value.hsCode ?? '', onChange: (event) => setValue({ ...value, hsCode: event.target.value }) }), _jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: () => setHsOpen(true), children: [_jsx("i", { className: "ri-search-line", "aria-hidden": "true" }), "HS\u7F16\u7801\u67E5\u8BE2"] })] }) }), _jsx(FormField, { label: "\u7F16\u7801\u786E\u8BA4\u72B6\u6001", children: _jsx("select", { value: value.hsCodeStatus ?? 'UNCONFIRMED', onChange: (event) => setValue({ ...value, hsCodeStatus: event.target.value }), children: enumOptions(hsStatusLabels).map((item) => _jsx("option", { value: item.value, children: item.label }, item.value)) }) }), _jsx(TextField, { label: "\u9000\u7A0E\u7387", required: true, type: "number", value: value.refundRate, onChange: (next) => setValue({ ...value, refundRate: next }) }), _jsx(TextField, { label: "\u9000\u7A0E\u653F\u7B56\u4F9D\u636E", required: true, value: value.refundPolicyReference, onChange: (next) => setValue({ ...value, refundPolicyReference: next }) }), _jsx(TextField, { label: "\u653F\u7B56\u65E5\u671F", required: true, type: "date", value: value.refundPolicyDate, onChange: (next) => setValue({ ...value, refundPolicyDate: next, refundValidationMethod: 'REVIEW_CONFIRMED' }) }), _jsx(TextField, { label: "\u82F1\u6587\u540D\u79F0", value: value.englishName, onChange: (next) => setValue({ ...value, englishName: next }) })] })] }), _jsx(HsCodeLookupDialog, { open: hsOpen, initialQuery: value.hsCode || value.englishName || value.productName, onAction: hsAction, onClose: () => setHsOpen(false) })] });
321
321
  }
322
322
  function PurchaseContractReviewDialog({ open, task, draft, busy, onChange, onClose, onSave }) {
323
323
  const errors = draft ? validatePurchaseContractReview(draft) : [];
324
324
  const duplicate = task?.duplicateContractError;
325
- return _jsxs(Modal, { open: open, title: "\u91C7\u8D2D\u5408\u540C\u5BA1\u6838", size: "full", onClose: onClose, footer: _jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: "\u53D6\u6D88" }), _jsx("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || !draft || Boolean(duplicate) || errors.length > 0, onClick: () => draft && void onSave(draft), children: "\u5BA1\u6838\u5E76\u5165\u5E93" })] }), children: [duplicate && _jsx(RiskNotice, { children: duplicate }), !draft ? _jsx(RiskNotice, { children: task?.errorMessage || '采购合同解析结果不可用' }) : _jsx(ReviewSplit, { editor: _jsxs("div", { className: "tcw-procurement-review-editor", children: [errors.length > 0 && _jsx(RiskNotice, { children: errors.join(';') }), _jsx(ReviewSection, { title: "\u4F9B\u5E94\u5546\u4FE1\u606F", children: _jsx(SupplierDraftEditor, { supplier: draft.supplier, onChange: (supplier) => onChange({ ...draft, supplier }) }) }), _jsx(ReviewSection, { title: "\u8BA2\u5355\u4FE1\u606F", children: _jsxs(FieldGrid, { columns: 2, children: [_jsx(TextField, { label: "\u91C7\u8D2D\u5408\u540C\u7F16\u53F7", required: true, value: draft.order.contractNo, onChange: (value) => onChange({ ...draft, order: { ...draft.order, contractNo: value } }) }), _jsx(TextField, { label: "\u4E0B\u5355\u65E5\u671F", required: true, type: "date", value: draft.order.orderDate, onChange: (value) => onChange({ ...draft, order: { ...draft.order, orderDate: value } }) }), _jsx(TextField, { label: "\u91C7\u8D2D\u603B\u989D\uFF08\u4EBA\u6C11\u5E01\uFF09", required: true, type: "number", value: draft.order.contractAmountCny, onChange: (value) => onChange({ ...draft, order: { ...draft.order, contractAmountCny: value } }) }), _jsx(TextField, { label: "\u5DF2\u4ED8\u6B3E", type: "number", value: draft.order.paidAmountCny, onChange: (value) => onChange({ ...draft, order: { ...draft.order, paidAmountCny: value } }) }), _jsx(TextField, { label: "\u5DF2\u9000\u7A0E", type: "number", value: draft.order.refundedAmountCny, onChange: (value) => onChange({ ...draft, order: { ...draft.order, refundedAmountCny: value } }) })] }) }), _jsx(ReviewSection, { title: `全部商品(${draft.lines.length})`, children: _jsx("div", { className: "tcw-procurement-review-lines", children: draft.lines.map((line, index) => _jsx(ContractLineEditor, { index: index, line: line, onChange: (next) => onChange({ ...draft, lines: draft.lines.map((item, lineIndex) => lineIndex === index ? next : item) }) }, line.id ?? index)) }) })] }), source: _jsx(SourcePreview, { draft: draft, task: task }) })] });
325
+ return _jsxs(Modal, { open: open, title: "\u91C7\u8D2D\u5408\u540C\u5BA1\u6838", size: "full", onClose: onClose, footer: _jsxs(_Fragment, { children: [_jsxs("button", { type: "button", className: "tcw-button tcw-button--secondary", onClick: onClose, children: [_jsx("i", { className: "ri-close-line", "aria-hidden": "true" }), "\u53D6\u6D88"] }), _jsxs("button", { type: "button", className: "tcw-button tcw-button--primary", disabled: busy || !draft || Boolean(duplicate) || errors.length > 0, onClick: () => draft && void onSave(draft), children: [_jsx("i", { className: "ri-check-double-line", "aria-hidden": "true" }), "\u5BA1\u6838\u5E76\u5165\u5E93"] })] }), children: [duplicate && _jsx(RiskNotice, { children: duplicate }), !draft ? _jsx(RiskNotice, { children: task?.errorMessage || '采购合同解析结果不可用' }) : _jsx(ReviewSplit, { editor: _jsxs("div", { className: "tcw-procurement-review-editor", children: [errors.length > 0 && _jsx(RiskNotice, { children: errors.join(';') }), _jsx(ReviewSection, { title: "\u4F9B\u5E94\u5546\u4FE1\u606F", children: _jsx(SupplierDraftEditor, { supplier: draft.supplier, onChange: (supplier) => onChange({ ...draft, supplier }) }) }), _jsx(ReviewSection, { title: "\u8BA2\u5355\u4FE1\u606F", children: _jsxs(FieldGrid, { columns: 2, children: [_jsx(TextField, { label: "\u91C7\u8D2D\u5408\u540C\u7F16\u53F7", required: true, value: draft.order.contractNo, onChange: (value) => onChange({ ...draft, order: { ...draft.order, contractNo: value } }) }), _jsx(TextField, { label: "\u4E0B\u5355\u65E5\u671F", required: true, type: "date", value: draft.order.orderDate, onChange: (value) => onChange({ ...draft, order: { ...draft.order, orderDate: value } }) }), _jsx(TextField, { label: "\u91C7\u8D2D\u603B\u989D\uFF08\u4EBA\u6C11\u5E01\uFF09", required: true, type: "number", value: draft.order.contractAmountCny, onChange: (value) => onChange({ ...draft, order: { ...draft.order, contractAmountCny: value } }) }), _jsx(TextField, { label: "\u5DF2\u4ED8\u6B3E", type: "number", value: draft.order.paidAmountCny, onChange: (value) => onChange({ ...draft, order: { ...draft.order, paidAmountCny: value } }) }), _jsx(TextField, { label: "\u5DF2\u9000\u7A0E", type: "number", value: draft.order.refundedAmountCny, onChange: (value) => onChange({ ...draft, order: { ...draft.order, refundedAmountCny: value } }) })] }) }), _jsx(ReviewSection, { title: `全部商品(${draft.lines.length})`, children: _jsx("div", { className: "tcw-procurement-review-lines", children: draft.lines.map((line, index) => _jsx(ContractLineEditor, { index: index, line: line, onChange: (next) => onChange({ ...draft, lines: draft.lines.map((item, lineIndex) => lineIndex === index ? next : item) }) }, line.id ?? index)) }) })] }), source: _jsx(SourcePreview, { draft: draft, task: task }) })] });
326
326
  }
327
327
  function ContractLineEditor({ line, index, onChange }) {
328
328
  return _jsxs("section", { className: "tcw-procurement-review-line", children: [_jsxs("h4", { children: ["\u5546\u54C1 ", index + 1, " ", _jsx(StatusTag, { tone: "muted", children: sourceTypeLabels[line.sourceType] })] }), _jsxs(FieldGrid, { columns: 2, children: [_jsx(TextField, { label: "\u5546\u54C1\u540D\u79F0", required: true, value: line.productName, onChange: (value) => onChange({ ...line, productName: value }) }), _jsx(TextField, { label: "\u5546\u54C1\u63CF\u8FF0", value: line.productDescription, onChange: (value) => onChange({ ...line, productDescription: value }) }), _jsx(TextField, { label: "\u82F1\u6587\u540D\u79F0", value: line.englishName, onChange: (value) => onChange({ ...line, englishName: value }) }), _jsx(TextField, { label: "\u89C4\u683C\u578B\u53F7", value: line.modelSpecification, onChange: (value) => onChange({ ...line, modelSpecification: value }) }), _jsx(TextField, { label: "\u5355\u4F4D", required: true, value: line.unit, onChange: (value) => onChange({ ...line, unit: value }) }), _jsx(TextField, { label: "\u6570\u91CF", required: true, type: "number", value: line.quantity, onChange: (value) => onChange({ ...line, quantity: value }) }), _jsx(TextField, { label: "\u542B\u7A0E\u5355\u4EF7", required: true, type: "number", value: line.unitPriceTaxIncluded, onChange: (value) => onChange({ ...line, unitPriceTaxIncluded: value }) }), _jsx(TextField, { label: "\u542B\u7A0E\u91D1\u989D", required: true, type: "number", value: line.lineAmountTaxIncluded, onChange: (value) => onChange({ ...line, lineAmountTaxIncluded: value }) }), _jsx(TextField, { label: "\u589E\u503C\u7A0E\u7387", required: true, type: "number", value: line.vatRate, onChange: (value) => onChange({ ...line, vatRate: value }) }), _jsx(TextField, { label: "\u6D77\u5173\u7F16\u7801", value: line.hsCode, onChange: (value) => onChange({ ...line, hsCode: value }) }), _jsx(FormField, { label: "\u7F16\u7801\u786E\u8BA4\u72B6\u6001", children: _jsx("select", { value: line.hsCodeStatus ?? 'UNCONFIRMED', onChange: (event) => onChange({ ...line, hsCodeStatus: event.target.value }), children: enumOptions(hsStatusLabels).map((item) => _jsx("option", { value: item.value, children: item.label }, item.value)) }) }), _jsx(TextField, { label: "\u9000\u7A0E\u7387", required: true, type: "number", value: line.refundRate, onChange: (value) => onChange({ ...line, refundRate: value }) }), _jsx(TextField, { label: "\u9000\u7A0E\u653F\u7B56\u4F9D\u636E", required: true, value: line.refundPolicyReference, onChange: (value) => onChange({ ...line, refundPolicyReference: value }) }), _jsx(TextField, { label: "\u9000\u7A0E\u653F\u7B56\u65E5\u671F", required: true, type: "date", value: line.refundPolicyDate, onChange: (value) => onChange({ ...line, refundPolicyDate: value, refundValidationMethod: 'REVIEW_CONFIRMED' }) }), line.amountMismatch && _jsx(FormField, { label: "\u91D1\u989D\u5DEE\u5F02\u786E\u8BA4", required: true, children: _jsxs("label", { className: "tcw-procurement-checkbox", children: [_jsx("input", { type: "checkbox", checked: Boolean(line.amountMismatchConfirmed), onChange: (event) => onChange({ ...line, amountMismatchConfirmed: event.target.checked }) }), "\u786E\u8BA4\u4FDD\u7559\u5408\u540C\u539F\u59CB\u91D1\u989D"] }) })] })] });
@@ -346,7 +346,7 @@ function DeleteDialog({ target, supplier, busy, onCancel, onConfirm }) {
346
346
  }
347
347
  function ReviewSection({ title, children }) { return _jsxs("section", { className: "tcw-procurement-review-section", children: [_jsx("h3", { children: title }), children] }); }
348
348
  function ContextValue({ label, value }) { return _jsxs("div", { children: [_jsx("span", { children: label }), _jsx("strong", { children: String(value || '—') })] }); }
349
- function LinkButton({ children, onClick }) { return _jsx("button", { type: "button", className: "tcw-procurement-link", onClick: onClick, children: children }); }
349
+ function LinkButton({ children, icon, onClick }) { return _jsxs("button", { type: "button", className: "tcw-procurement-link", onClick: onClick, children: [_jsx("i", { className: icon, "aria-hidden": "true" }), children] }); }
350
350
  function StatusTag({ children, tone }) { return _jsx("span", { className: `tcw-procurement-status tcw-procurement-status--${tone}`, children: children }); }
351
351
  function TextField({ label, value, required, type = 'text', onChange }) { return _jsx(FormField, { label: label, required: required, children: _jsx("input", { type: type, value: String(value ?? ''), onChange: (event) => onChange(event.target.value) }) }); }
352
352
  function MoneyField({ label, value, disabled, onChange }) { return _jsx(FormField, { label: label, children: _jsx("input", { type: "number", disabled: disabled, value: String(value ?? ''), onChange: (event) => onChange?.(event.target.value) }) }); }