@chenchaolong/plugin-trade-compliance-workbench 0.1.6 → 0.1.7
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.
|
@@ -311,12 +311,13 @@
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
function renderProductsPage() {
|
|
314
|
-
const groups = groupBy(filteredProducts, (item) => value(item.supplierName, '未识别供应商'))
|
|
315
314
|
return h('div', { className: 'tcw-page products-page' },
|
|
316
|
-
|
|
315
|
+
businessPanel('供应商商品', '上传供应商合同后,识别结果在列表内完成审核、驳回和入库。', [
|
|
317
316
|
uploadButton('upload_supplier_contract', '上传供应商合同')
|
|
318
|
-
]
|
|
319
|
-
|
|
317
|
+
], [
|
|
318
|
+
renderListToolbar('供应商商品列表', supplierReviews.length),
|
|
319
|
+
h('div', { className: 'pending-supplier-products tcw-table-section' },
|
|
320
|
+
reviewTable(['供应商', '商品', '型号', '海关编码', '退税率', '英文品名', '管控状态'], supplierReviews, (item) => {
|
|
320
321
|
const row = readMerged(item)
|
|
321
322
|
return [
|
|
322
323
|
value(row.supplierName),
|
|
@@ -327,17 +328,21 @@
|
|
|
327
328
|
value(row.englishName),
|
|
328
329
|
status(controlStatusText(row.controlledStatus), controlStatusLevel(row.controlledStatus))
|
|
329
330
|
]
|
|
330
|
-
|
|
331
|
+
}, '暂无供应商商品识别结果。上传供应商合同并等待智能体识别后会显示在这里。')
|
|
332
|
+
)
|
|
333
|
+
])
|
|
331
334
|
)
|
|
332
335
|
}
|
|
333
336
|
|
|
334
337
|
function renderWorkbooksPage() {
|
|
335
338
|
return h('div', { className: 'tcw-page workbooks-page' },
|
|
336
|
-
|
|
339
|
+
businessPanel('销售发票', '上传购销合同后,先审核发票字段,再生成固定模板 Excel。', [
|
|
337
340
|
uploadButton('upload_sales_contract', '上传购销合同'),
|
|
338
341
|
h('button', { className: 'tcw-btn tcw-btn-primary', disabled: busy, onClick: generateWorkbook }, '生成销售发票')
|
|
339
|
-
]
|
|
340
|
-
|
|
342
|
+
], [
|
|
343
|
+
renderListToolbar('购销合同识别列表', salesReviews.length),
|
|
344
|
+
h('div', { className: 'pending-sales-contracts tcw-table-section' },
|
|
345
|
+
reviewTable(['文件/标题', '发票号', '合同号', '买方', '卖方'], salesReviews, (item) => {
|
|
341
346
|
const row = readMerged(item)
|
|
342
347
|
return [
|
|
343
348
|
value(item.title),
|
|
@@ -346,14 +351,21 @@
|
|
|
346
351
|
value(row.buyerName),
|
|
347
352
|
value(row.sellerName)
|
|
348
353
|
]
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
354
|
+
}, '暂无购销合同识别结果。')
|
|
355
|
+
),
|
|
356
|
+
h('section', { className: 'tcw-history-section' },
|
|
357
|
+
h('div', { className: 'tcw-subsection-head' },
|
|
358
|
+
h('div', null, h('h3', null, '已生成销售发票'), h('p', null, `${filteredWorkbooks.length} 条生成历史`))
|
|
359
|
+
),
|
|
360
|
+
table(['文件名', '发票号', '合同号', '模板工作表', '状态'], filteredWorkbooks, (item) => [
|
|
361
|
+
value(item.fileName),
|
|
362
|
+
value(item.invoiceNo),
|
|
363
|
+
value(item.contractNo),
|
|
364
|
+
Array.isArray(item.sheetNames) ? item.sheetNames.join('、') : '-',
|
|
365
|
+
status(value(item.status, 'generated'), 'ok')
|
|
366
|
+
], '暂无销售发票生成历史。')
|
|
367
|
+
)
|
|
368
|
+
])
|
|
357
369
|
)
|
|
358
370
|
}
|
|
359
371
|
|
|
@@ -380,7 +392,28 @@
|
|
|
380
392
|
|
|
381
393
|
function renderListPanel(title, className, rows, headers, mapRow, emptyText) {
|
|
382
394
|
return panel(title, h('div', { className },
|
|
383
|
-
|
|
395
|
+
renderListToolbar(null, rows.length),
|
|
396
|
+
reviewTable(headers, rows, mapRow, emptyText)
|
|
397
|
+
))
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function businessPanel(title, subtitle, actions, content) {
|
|
401
|
+
return h('section', { className: 'tcw-business-panel' },
|
|
402
|
+
h('div', { className: 'tcw-business-head' },
|
|
403
|
+
h('div', null, h('h2', null, title), h('p', null, subtitle)),
|
|
404
|
+
h('div', { className: 'tcw-button-row' }, actions)
|
|
405
|
+
),
|
|
406
|
+
h('div', { className: 'tcw-business-body' }, content)
|
|
407
|
+
)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function renderListToolbar(title, total) {
|
|
411
|
+
return h('div', { className: 'tcw-list-toolbar' },
|
|
412
|
+
h('div', { className: 'tcw-list-title' },
|
|
413
|
+
title ? h('h3', null, title) : null,
|
|
414
|
+
h('span', null, `${total || 0} 条记录`)
|
|
415
|
+
),
|
|
416
|
+
h('div', { className: 'tcw-list-actions' },
|
|
384
417
|
h('label', { className: 'tcw-filter' },
|
|
385
418
|
h('span', null, '状态'),
|
|
386
419
|
h('select', { className: 'status-filter', value: statusFilter, onChange: (event) => { setStatusFilter(event.target.value); setSelectedIds([]) } },
|
|
@@ -391,9 +424,8 @@
|
|
|
391
424
|
)
|
|
392
425
|
),
|
|
393
426
|
h('button', { className: 'tcw-btn tcw-btn-primary', disabled: busy || selectedIds.length === 0, onClick: batchApproveSelected }, `批量审核${selectedIds.length ? ` (${selectedIds.length})` : ''}`)
|
|
394
|
-
)
|
|
395
|
-
|
|
396
|
-
))
|
|
427
|
+
)
|
|
428
|
+
)
|
|
397
429
|
}
|
|
398
430
|
|
|
399
431
|
function reviewTable(headers, rows, mapRow, emptyText) {
|
|
@@ -680,11 +712,11 @@
|
|
|
680
712
|
* { box-sizing: border-box; }
|
|
681
713
|
body { margin: 0; background: var(--tcw-bg); color: var(--tcw-text); font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
|
|
682
714
|
button, input { font: inherit; letter-spacing: 0; }
|
|
683
|
-
.tcw-shell { display: grid; gap:
|
|
684
|
-
.tcw-header { display: grid; grid-template-columns: minmax(
|
|
715
|
+
.tcw-shell { display: grid; gap: 10px; min-height: 100vh; padding: 12px 14px 18px; }
|
|
716
|
+
.tcw-header { display: grid; grid-template-columns: minmax(260px, .72fr) minmax(340px, 520px); gap: 12px; align-items: center; border: 1px solid var(--tcw-border); border-radius: 8px; background: var(--tcw-card); padding: 12px 14px; }
|
|
685
717
|
.tcw-title-block { display: grid; gap: 3px; }
|
|
686
718
|
.tcw-kicker { color: var(--tcw-primary); font-size: 12px; font-weight: 900; }
|
|
687
|
-
.tcw-title-block h1 { margin: 0; font-size:
|
|
719
|
+
.tcw-title-block h1 { margin: 0; font-size: 20px; line-height: 1.22; }
|
|
688
720
|
.tcw-title-block p, .tcw-page-head p, .tcw-drawer-head p { margin: 0; color: var(--tcw-muted); font-size: 13px; }
|
|
689
721
|
.tcw-header-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
|
|
690
722
|
.tcw-search, .tcw-field input { width: 100%; min-height: 36px; border: 1px solid var(--tcw-border); border-radius: 6px; background: var(--tcw-card); color: var(--tcw-text); padding: 8px 10px; }
|
|
@@ -697,18 +729,28 @@ button, input { font: inherit; letter-spacing: 0; }
|
|
|
697
729
|
.tcw-upload { border-style: dashed; border-color: color-mix(in srgb, var(--tcw-primary) 42%, var(--tcw-border)); color: var(--tcw-primary); font-weight: 800; }
|
|
698
730
|
.tcw-upload input { display: none; }
|
|
699
731
|
.tcw-notice { border: 1px solid color-mix(in srgb, var(--tcw-primary) 24%, var(--tcw-border)); border-radius: 6px; background: color-mix(in srgb, var(--tcw-primary) 7%, var(--tcw-card)); padding: 10px 12px; color: var(--tcw-primary-dark); font-size: 13px; }
|
|
700
|
-
.tcw-tabs { display: flex; gap: 6px; overflow-x: auto; border-bottom: 1px solid var(--tcw-border); }
|
|
701
|
-
.tcw-tab { min-height:
|
|
732
|
+
.tcw-tabs { display: flex; gap: 6px; overflow-x: auto; border-bottom: 1px solid var(--tcw-border); padding: 0 2px; }
|
|
733
|
+
.tcw-tab { min-height: 34px; border: 0; border-bottom: 3px solid transparent; background: transparent; color: var(--tcw-muted); padding: 7px 12px; cursor: pointer; font-weight: 900; }
|
|
702
734
|
.tcw-tab.active { border-color: var(--tcw-primary); color: var(--tcw-primary); }
|
|
703
735
|
.tcw-main { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; align-items: start; }
|
|
704
736
|
.tcw-main.with-drawer { grid-template-columns: minmax(0, 1fr) minmax(340px, 410px); }
|
|
705
737
|
.tcw-content, .tcw-drawer, .tcw-panel, .tcw-supplier-block { border: 1px solid var(--tcw-border); border-radius: 8px; background: var(--tcw-card); }
|
|
706
|
-
.tcw-content { min-width: 0; padding:
|
|
738
|
+
.tcw-content { min-width: 0; border: 0; background: transparent; padding: 0; }
|
|
707
739
|
.tcw-page { display: grid; gap: 12px; }
|
|
708
740
|
.tcw-page-head, .tcw-drawer-head, .tcw-supplier-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
|
|
709
741
|
.tcw-page-head h2, .tcw-drawer-head h2, .tcw-panel h3 { margin: 0 0 4px; font-size: 16px; line-height: 1.35; }
|
|
710
742
|
.tcw-button-row { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
|
|
711
743
|
.tcw-panel { display: grid; gap: 10px; padding: 12px; }
|
|
744
|
+
.tcw-business-panel { display: grid; gap: 0; border: 1px solid var(--tcw-border); border-radius: 8px; background: var(--tcw-card); overflow: hidden; }
|
|
745
|
+
.tcw-business-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; border-bottom: 1px solid var(--tcw-border); background: var(--tcw-card); padding: 14px 16px; }
|
|
746
|
+
.tcw-business-head h2 { margin: 0 0 4px; font-size: 18px; line-height: 1.25; }
|
|
747
|
+
.tcw-business-head p { margin: 0; color: var(--tcw-muted); font-size: 13px; }
|
|
748
|
+
.tcw-business-body { display: grid; gap: 12px; padding: 14px 16px 16px; }
|
|
749
|
+
.tcw-table-section { display: grid; gap: 0; }
|
|
750
|
+
.tcw-history-section { display: grid; gap: 10px; border-top: 1px solid var(--tcw-border); padding-top: 14px; }
|
|
751
|
+
.tcw-subsection-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
752
|
+
.tcw-subsection-head h3, .tcw-list-title h3 { margin: 0; font-size: 15px; line-height: 1.3; }
|
|
753
|
+
.tcw-subsection-head p, .tcw-list-title span { margin: 0; color: var(--tcw-muted); font-size: 12px; }
|
|
712
754
|
.tcw-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
|
|
713
755
|
.tcw-metric { display: grid; gap: 4px; border: 1px solid var(--tcw-border); border-radius: 8px; background: var(--tcw-card); padding: 12px; }
|
|
714
756
|
.tcw-metric span { color: var(--tcw-muted); font-size: 12px; }
|
|
@@ -724,7 +766,9 @@ button, input { font: inherit; letter-spacing: 0; }
|
|
|
724
766
|
.tcw-table tr:last-child td { border-bottom: 0; }
|
|
725
767
|
.tcw-table tr.clickable { cursor: pointer; }
|
|
726
768
|
.tcw-table tr.clickable:hover td { background: color-mix(in srgb, var(--tcw-primary) 5%, transparent); }
|
|
727
|
-
.tcw-list-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
|
|
769
|
+
.tcw-list-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
|
|
770
|
+
.tcw-list-title { display: grid; gap: 2px; min-width: 160px; }
|
|
771
|
+
.tcw-list-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
|
|
728
772
|
.tcw-filter { display: inline-flex; align-items: center; gap: 8px; color: var(--tcw-muted); font-size: 13px; font-weight: 800; }
|
|
729
773
|
.tcw-filter select { min-height: 34px; border: 1px solid var(--tcw-border); border-radius: 6px; background: var(--tcw-card); color: var(--tcw-text); padding: 6px 28px 6px 9px; }
|
|
730
774
|
.tcw-row-actions { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
@@ -732,7 +776,7 @@ button, input { font: inherit; letter-spacing: 0; }
|
|
|
732
776
|
.tcw-mini-btn.danger { border-color: color-mix(in srgb, var(--tcw-danger) 35%, var(--tcw-border)); background: color-mix(in srgb, var(--tcw-danger) 6%, var(--tcw-card)); color: var(--tcw-danger); }
|
|
733
777
|
.tcw-mini-btn:disabled { cursor: not-allowed; opacity: .5; }
|
|
734
778
|
.row-selection-checkbox { width: 16px; height: 16px; }
|
|
735
|
-
.tcw-empty { display: grid; place-items: center; min-height:
|
|
779
|
+
.tcw-empty { display: grid; place-items: center; min-height: 86px; border: 1px dashed var(--tcw-border); border-radius: 8px; background: var(--tcw-soft); color: var(--tcw-muted); padding: 16px; text-align: center; }
|
|
736
780
|
.tcw-supplier-block { display: grid; gap: 10px; padding: 12px; }
|
|
737
781
|
.tcw-supplier-head strong { font-size: 15px; }
|
|
738
782
|
.tcw-supplier-head span { color: var(--tcw-muted); font-size: 12px; }
|
|
@@ -758,6 +802,8 @@ button, input { font: inherit; letter-spacing: 0; }
|
|
|
758
802
|
.tcw-status.muted { background: #eef2f6; color: var(--tcw-muted); }
|
|
759
803
|
@media (max-width: 1040px) {
|
|
760
804
|
.tcw-header, .tcw-main.with-drawer, .tcw-form { grid-template-columns: 1fr; }
|
|
805
|
+
.tcw-business-head { align-items: stretch; flex-direction: column; }
|
|
806
|
+
.tcw-button-row, .tcw-list-actions { justify-content: flex-start; }
|
|
761
807
|
.tcw-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
762
808
|
.tcw-drawer { position: static; max-height: none; }
|
|
763
809
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chenchaolong/plugin-trade-compliance-workbench",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Trade Compliance Workbench app plugin for controlled goods review, supplier product management, and customs workbook generation.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "XpertAI",
|