@chenchaolong/plugin-trade-compliance-workbench 0.1.43 → 0.1.45
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.
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
const [activePage, setActivePage] = React.useState('overview-page')
|
|
71
71
|
const [selectedIds, setSelectedIds] = React.useState([])
|
|
72
72
|
const [statusFilter, setStatusFilter] = React.useState('all')
|
|
73
|
+
const [overviewTab, setOverviewTab] = React.useState('all')
|
|
73
74
|
const [busy, setBusy] = React.useState(false)
|
|
74
75
|
const [query, setQuery] = React.useState('')
|
|
75
76
|
const [pageByList, setPageByList] = React.useState({})
|
|
@@ -103,7 +104,7 @@
|
|
|
103
104
|
}
|
|
104
105
|
}, [])
|
|
105
106
|
|
|
106
|
-
React.useEffect(reportResize, [data, activePage, selectedIds, statusFilter, busy, formDialog, deleteDialog, hsCodeSearch, hsCodeDetailDialog])
|
|
107
|
+
React.useEffect(reportResize, [data, activePage, selectedIds, statusFilter, overviewTab, busy, formDialog, deleteDialog, hsCodeSearch, hsCodeDetailDialog])
|
|
107
108
|
|
|
108
109
|
const reviewItems = data.reviewItems.filter((item) => !isPlaceholderReviewItem(item))
|
|
109
110
|
const pendingItems = reviewItems.filter((item) => (item.reviewStatus || 'pending') === 'pending')
|
|
@@ -606,59 +607,144 @@
|
|
|
606
607
|
}
|
|
607
608
|
|
|
608
609
|
return h('div', { className: 'tcw-shell' },
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
h('
|
|
613
|
-
|
|
610
|
+
renderSidebar(),
|
|
611
|
+
h('section', { className: 'tcw-workspace' },
|
|
612
|
+
h('header', { className: 'tcw-header' },
|
|
613
|
+
h('div', { className: 'tcw-title-block' },
|
|
614
|
+
h('span', { className: 'tcw-kicker' }, pageBreadcrumb(activePage)),
|
|
615
|
+
h('h1', null, pageTitle(activePage)),
|
|
616
|
+
h('p', null, pageSubtitle(activePage))
|
|
617
|
+
),
|
|
618
|
+
h('div', { className: 'tcw-header-actions' },
|
|
619
|
+
h('input', { className: 'tcw-search', value: query, placeholder: '搜索商品、供应商、海关编码、文件名', onChange: (event) => setQuery(event.target.value) }),
|
|
620
|
+
h('button', { className: 'tcw-btn tcw-btn-soft', disabled: busy, onClick: () => reload() }, busy ? '处理中' : '刷新')
|
|
621
|
+
)
|
|
614
622
|
),
|
|
615
|
-
h('
|
|
616
|
-
h('
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
tab('products-page', '供应商商品'),
|
|
624
|
-
tab('workbooks-page', '销售发票'),
|
|
625
|
-
tab('hs-code-search-page', '海关编码查询')
|
|
626
|
-
]),
|
|
627
|
-
h('main', { className: 'tcw-main tcw-frame' },
|
|
628
|
-
h('section', { className: 'tcw-content' },
|
|
629
|
-
activePage === 'overview-page' ? renderOverviewPage() : null,
|
|
630
|
-
activePage === 'controlled-goods-page' ? renderControlledGoodsPage() : null,
|
|
631
|
-
activePage === 'products-page' ? renderProductsPage() : null,
|
|
632
|
-
activePage === 'workbooks-page' ? renderWorkbooksPage() : null,
|
|
633
|
-
activePage === 'hs-code-search-page' ? renderHsCodeSearchPage() : null
|
|
623
|
+
h('main', { className: 'tcw-main' },
|
|
624
|
+
h('section', { className: 'tcw-content' },
|
|
625
|
+
activePage === 'overview-page' ? renderOverviewPage() : null,
|
|
626
|
+
activePage === 'controlled-goods-page' ? renderControlledGoodsPage() : null,
|
|
627
|
+
activePage === 'products-page' ? renderProductsPage() : null,
|
|
628
|
+
activePage === 'workbooks-page' ? renderWorkbooksPage() : null,
|
|
629
|
+
activePage === 'hs-code-search-page' ? renderHsCodeSearchPage() : null
|
|
630
|
+
)
|
|
634
631
|
)
|
|
635
632
|
),
|
|
633
|
+
renderAssistantPanel(),
|
|
636
634
|
detailItem ? renderDetailModal() : null,
|
|
637
635
|
formDialog ? renderFormModal() : null,
|
|
638
636
|
deleteDialog ? renderDeleteConfirmModal() : null,
|
|
639
637
|
hsCodeDetailDialog ? renderHsCodeDetailModal() : null
|
|
640
638
|
)
|
|
641
639
|
|
|
642
|
-
function
|
|
643
|
-
return h('
|
|
640
|
+
function renderSidebar() {
|
|
641
|
+
return h('aside', { className: 'tcw-sidebar' },
|
|
642
|
+
h('div', { className: 'tcw-brand' },
|
|
643
|
+
h('div', { className: 'tcw-brand-mark' }, 'TC'),
|
|
644
|
+
h('div', null,
|
|
645
|
+
h('strong', null, '外贸合规工作台'),
|
|
646
|
+
h('span', null, 'Trade Compliance')
|
|
647
|
+
)
|
|
648
|
+
),
|
|
649
|
+
h('nav', { className: 'tcw-nav', 'aria-label': '主导航' }, [
|
|
650
|
+
tab('overview-page', '总览', '1', pendingItems.length, 'blue'),
|
|
651
|
+
tab('controlled-goods-page', '管控规则库', '2', controlledReviews.length, 'green'),
|
|
652
|
+
tab('products-page', '供应商商品', '3', supplierReviews.length, 'orange'),
|
|
653
|
+
tab('workbooks-page', '销售发票', '4', salesReviews.length + filteredWorkbooks.length, 'violet'),
|
|
654
|
+
tab('hs-code-search-page', '工具', '5', null, 'slate')
|
|
655
|
+
]),
|
|
656
|
+
h('section', { className: 'tcw-sidebar-section' },
|
|
657
|
+
h('h2', null, '主流程'),
|
|
658
|
+
h('ol', { className: 'tcw-flow-list' }, [
|
|
659
|
+
'维护管控规则',
|
|
660
|
+
'上传供应商合同',
|
|
661
|
+
'确认 HS 编码候选',
|
|
662
|
+
'审核供应商商品',
|
|
663
|
+
'上传购销合同',
|
|
664
|
+
'生成销售发票'
|
|
665
|
+
].map((item) => h('li', { key: item }, h('span', null), item)))
|
|
666
|
+
),
|
|
667
|
+
h('section', { className: 'tcw-sidebar-section compact' },
|
|
668
|
+
h('h2', null, '数据关系'),
|
|
669
|
+
h('p', null, '管控规则用于匹配供应商商品,已确认商品进入销售发票生成流程。')
|
|
670
|
+
)
|
|
671
|
+
)
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function renderAssistantPanel() {
|
|
675
|
+
return h('aside', { className: 'tcw-assistant' },
|
|
676
|
+
h('div', { className: 'tcw-assistant-head' },
|
|
677
|
+
h('span', { className: 'tcw-assistant-mark' }, 'AI'),
|
|
678
|
+
h('div', null,
|
|
679
|
+
h('strong', null, '外贸合规助手'),
|
|
680
|
+
h('p', null, '按流程处理识别结果,减少来回切换。')
|
|
681
|
+
)
|
|
682
|
+
),
|
|
683
|
+
h('section', { className: 'tcw-assistant-card' },
|
|
684
|
+
h('h3', null, '当前建议'),
|
|
685
|
+
h('p', null, assistantTip(activePage))
|
|
686
|
+
),
|
|
687
|
+
h('section', { className: 'tcw-assistant-card' },
|
|
688
|
+
h('h3', null, '快捷入口'),
|
|
689
|
+
h('div', { className: 'tcw-assistant-actions' }, [
|
|
690
|
+
h('button', { className: 'tcw-mini-btn', onClick: () => setActivePage('controlled-goods-page') }, '管控规则'),
|
|
691
|
+
h('button', { className: 'tcw-mini-btn', onClick: () => setActivePage('products-page') }, '商品审核'),
|
|
692
|
+
h('button', { className: 'tcw-mini-btn', onClick: () => setActivePage('hs-code-search-page') }, '查 HS 编码')
|
|
693
|
+
])
|
|
694
|
+
),
|
|
695
|
+
h('section', { className: 'tcw-assistant-card' },
|
|
696
|
+
h('h3', null, '处理顺序'),
|
|
697
|
+
h('p', null, '先把管控规则和供应商商品确认入库,再审核购销合同并生成销售发票。')
|
|
698
|
+
)
|
|
699
|
+
)
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function tab(key, label, icon, count, tone) {
|
|
703
|
+
return h('button', { key, className: key === activePage ? 'tcw-tab active' : 'tcw-tab', onClick: () => setActivePage(key) },
|
|
704
|
+
h('span', { className: 'tcw-nav-icon ' + (tone || 'blue') }, icon),
|
|
705
|
+
h('span', null, label),
|
|
706
|
+
count == null ? null : h('em', null, count)
|
|
707
|
+
)
|
|
644
708
|
}
|
|
645
709
|
|
|
646
710
|
function renderOverviewPage() {
|
|
711
|
+
const pendingOverviewItems = overviewTab === 'all'
|
|
712
|
+
? pendingItems.slice(0, 12)
|
|
713
|
+
: pendingItems.filter((item) => item.type === overviewTab).slice(0, 12)
|
|
647
714
|
return h('div', { className: 'tcw-page overview-page' },
|
|
648
715
|
h('section', { className: 'tcw-metrics' },
|
|
649
|
-
metric('待审核', pendingItems.length),
|
|
650
|
-
metric('管控识别待审', pendingControlledReviews.length),
|
|
651
|
-
metric('供应商商品待审', pendingSupplierReviews.length),
|
|
652
|
-
metric('销售合同待审', pendingSalesReviews.length),
|
|
653
|
-
metric('已入库管控商品', data.controlledGoods.length),
|
|
654
|
-
metric('已入库供应商商品', data.products.length),
|
|
655
|
-
metric('销售发票历史', data.workbookGenerations.length),
|
|
656
|
-
metric('全部审核记录', reviewItems.length)
|
|
716
|
+
metric('待审核', pendingItems.length, '总', 'blue'),
|
|
717
|
+
metric('管控识别待审', pendingControlledReviews.length, '盾', 'green'),
|
|
718
|
+
metric('供应商商品待审', pendingSupplierReviews.length, '品', 'orange'),
|
|
719
|
+
metric('销售合同待审', pendingSalesReviews.length, '票', 'violet'),
|
|
720
|
+
metric('已入库管控商品', data.controlledGoods.length, '仓', 'slate'),
|
|
721
|
+
metric('已入库供应商商品', data.products.length, '商', 'green'),
|
|
722
|
+
metric('销售发票历史', data.workbookGenerations.length, '文', 'violet'),
|
|
723
|
+
metric('全部审核记录', reviewItems.length, '记', 'blue')
|
|
657
724
|
),
|
|
658
|
-
panel('
|
|
659
|
-
|
|
660
|
-
|
|
725
|
+
panel('待办事项明细',
|
|
726
|
+
h('div', { className: 'tcw-overview-panel' },
|
|
727
|
+
h('div', { className: 'tcw-overview-tabs' }, [
|
|
728
|
+
overviewTabButton('all', '全部', pendingItems.length),
|
|
729
|
+
overviewTabButton('controlled_goods', '规则', pendingItems.filter((item) => item.type === 'controlled_goods').length),
|
|
730
|
+
overviewTabButton('supplier_product', '商品', pendingItems.filter((item) => item.type === 'supplier_product').length),
|
|
731
|
+
overviewTabButton('customs_workbook', '发票', pendingItems.filter((item) => item.type === 'customs_workbook').length)
|
|
732
|
+
]),
|
|
733
|
+
pendingOverviewItems.length
|
|
734
|
+
? compactReviewList(pendingOverviewItems)
|
|
735
|
+
: empty('暂无待审核记录。智能体识别结果会先出现在这里。')
|
|
736
|
+
)
|
|
737
|
+
)
|
|
661
738
|
)
|
|
739
|
+
|
|
740
|
+
function overviewTabButton(key, label, count) {
|
|
741
|
+
return h('button', {
|
|
742
|
+
key,
|
|
743
|
+
type: 'button',
|
|
744
|
+
className: overviewTab === key ? 'tcw-overview-tab active' : 'tcw-overview-tab',
|
|
745
|
+
onClick: () => setOverviewTab(key)
|
|
746
|
+
}, `${label}${typeof count === 'number' ? ` ${count}` : ''}`)
|
|
747
|
+
}
|
|
662
748
|
}
|
|
663
749
|
|
|
664
750
|
function renderControlledGoodsPage() {
|
|
@@ -671,7 +757,7 @@
|
|
|
671
757
|
renderListToolbar('管控商品列表', controlledReviews.length),
|
|
672
758
|
h('div', { className: 'pending-controlled-goods confirmed-controlled-goods tcw-table-section' },
|
|
673
759
|
reviewTable(['商品名称', '海关编码', '关键词', '管控说明', '来源'], page.rows, (item) => {
|
|
674
|
-
const row =
|
|
760
|
+
const row = readMerged(item)
|
|
675
761
|
return [
|
|
676
762
|
value(row.productName || item.title),
|
|
677
763
|
value(row.hsCode),
|
|
@@ -1219,8 +1305,14 @@
|
|
|
1219
1305
|
|
|
1220
1306
|
}
|
|
1221
1307
|
|
|
1222
|
-
function metric(label, valueText) {
|
|
1223
|
-
return h('div', { className: 'tcw-metric' },
|
|
1308
|
+
function metric(label, valueText, icon, tone) {
|
|
1309
|
+
return h('div', { className: 'tcw-metric' },
|
|
1310
|
+
h('span', { className: 'tcw-metric-icon ' + (tone || 'blue') }, icon || '·'),
|
|
1311
|
+
h('div', { className: 'tcw-metric-body' },
|
|
1312
|
+
h('span', null, label),
|
|
1313
|
+
h('strong', null, valueText)
|
|
1314
|
+
)
|
|
1315
|
+
)
|
|
1224
1316
|
}
|
|
1225
1317
|
|
|
1226
1318
|
function panel(title, content) {
|
|
@@ -1731,21 +1823,37 @@
|
|
|
1731
1823
|
}
|
|
1732
1824
|
|
|
1733
1825
|
function pageTitle(key) {
|
|
1734
|
-
if (key === 'overview-page') return '
|
|
1735
|
-
if (key === 'controlled-goods-page') return '
|
|
1826
|
+
if (key === 'overview-page') return '总览'
|
|
1827
|
+
if (key === 'controlled-goods-page') return '管控规则库'
|
|
1736
1828
|
if (key === 'products-page') return '供应商商品'
|
|
1737
|
-
if (key === 'hs-code-search-page') return '
|
|
1829
|
+
if (key === 'hs-code-search-page') return '工具'
|
|
1738
1830
|
return '销售发票'
|
|
1739
1831
|
}
|
|
1740
1832
|
|
|
1741
1833
|
function pageSubtitle(key) {
|
|
1742
|
-
if (key === 'overview-page') return '
|
|
1834
|
+
if (key === 'overview-page') return '按业务顺序聚合待审核事项,先确认基础资料,再生成销售发票。'
|
|
1743
1835
|
if (key === 'controlled-goods-page') return '上传管控目录、审核识别结果、维护正式管控商品库。'
|
|
1744
1836
|
if (key === 'products-page') return '上传供应商合同,审核商品、HS Code、退税率和管控状态。'
|
|
1745
1837
|
if (key === 'hs-code-search-page') return '输入商品名称或海关编码,查询 HS 编码网结果。'
|
|
1746
1838
|
return '上传购销合同,审核发票字段并生成固定模板 Excel。'
|
|
1747
1839
|
}
|
|
1748
1840
|
|
|
1841
|
+
function pageBreadcrumb(key) {
|
|
1842
|
+
if (key === 'overview-page') return 'Workspace / 总览'
|
|
1843
|
+
if (key === 'controlled-goods-page') return 'Workspace / 管控规则库'
|
|
1844
|
+
if (key === 'products-page') return 'Workspace / 供应商商品'
|
|
1845
|
+
if (key === 'workbooks-page') return 'Workspace / 销售发票'
|
|
1846
|
+
return 'Workspace / 工具'
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
function assistantTip(key) {
|
|
1850
|
+
if (key === 'overview-page') return '从总览开始,优先确认管控规则和供应商商品,再推进发票生成。'
|
|
1851
|
+
if (key === 'controlled-goods-page') return '维护管控商品时,建议先核对 HS 编码和关键词,再保存入库。'
|
|
1852
|
+
if (key === 'products-page') return '供应商商品可先选用候选 HS 编码,再检查英文品名和管控状态。'
|
|
1853
|
+
if (key === 'workbooks-page') return '购销合同审核完毕后,再生成销售发票,避免后面重改。'
|
|
1854
|
+
return '海关编码查询页用于人工确认候选结果,必要时可回到商品页继续处理。'
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1749
1857
|
function isObject(value) {
|
|
1750
1858
|
return value && typeof value === 'object' && !Array.isArray(value)
|
|
1751
1859
|
}
|
|
@@ -1799,9 +1907,33 @@ button, input, textarea, select { font: inherit; letter-spacing: 0; }
|
|
|
1799
1907
|
.tcw-subsection-head h3, .tcw-list-title h3 { margin: 0; font-size: 15px; line-height: 1.3; }
|
|
1800
1908
|
.tcw-subsection-head p, .tcw-list-title span { margin: 0; color: var(--tcw-muted); font-size: 12px; }
|
|
1801
1909
|
.tcw-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
|
|
1802
|
-
.tcw-metric {
|
|
1803
|
-
|
|
1804
|
-
|
|
1910
|
+
.tcw-metric {
|
|
1911
|
+
display: grid;
|
|
1912
|
+
grid-template-columns: 44px minmax(0, 1fr);
|
|
1913
|
+
gap: 10px;
|
|
1914
|
+
align-items: center;
|
|
1915
|
+
border: 1px solid var(--tcw-border);
|
|
1916
|
+
border-radius: 8px;
|
|
1917
|
+
background: var(--tcw-card);
|
|
1918
|
+
padding: 12px;
|
|
1919
|
+
}
|
|
1920
|
+
.tcw-metric-icon {
|
|
1921
|
+
display: grid;
|
|
1922
|
+
place-items: center;
|
|
1923
|
+
width: 44px;
|
|
1924
|
+
height: 44px;
|
|
1925
|
+
border-radius: 10px;
|
|
1926
|
+
font-size: 18px;
|
|
1927
|
+
font-weight: 900;
|
|
1928
|
+
}
|
|
1929
|
+
.tcw-metric-icon.blue { background: #e8f0ff; color: var(--tcw-primary); }
|
|
1930
|
+
.tcw-metric-icon.green { background: #e7f8ef; color: var(--tcw-success); }
|
|
1931
|
+
.tcw-metric-icon.orange { background: #fff2df; color: var(--tcw-warning); }
|
|
1932
|
+
.tcw-metric-icon.violet { background: #f1eaff; color: var(--tcw-violet); }
|
|
1933
|
+
.tcw-metric-icon.slate { background: #eef2f6; color: var(--tcw-slate); }
|
|
1934
|
+
.tcw-metric-body { display: grid; gap: 2px; }
|
|
1935
|
+
.tcw-metric-body span { color: var(--tcw-muted); font-size: 12px; }
|
|
1936
|
+
.tcw-metric-body strong { font-size: 22px; line-height: 1; }
|
|
1805
1937
|
.tcw-field { display: grid; gap: 5px; min-width: 0; }
|
|
1806
1938
|
.tcw-field span { color: var(--tcw-muted); font-size: 12px; font-weight: 800; }
|
|
1807
1939
|
.tcw-field-check { align-content: end; }
|
|
@@ -1888,6 +2020,345 @@ button, input, textarea, select { font: inherit; letter-spacing: 0; }
|
|
|
1888
2020
|
.tcw-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
1889
2021
|
.tcw-drawer { position: static; max-height: none; }
|
|
1890
2022
|
}
|
|
2023
|
+
|
|
2024
|
+
/* V2 process-oriented shell */
|
|
2025
|
+
:root {
|
|
2026
|
+
--tcw-bg:#f4f7fb;
|
|
2027
|
+
--tcw-card:#ffffff;
|
|
2028
|
+
--tcw-soft:#f8fafc;
|
|
2029
|
+
--tcw-text:#172033;
|
|
2030
|
+
--tcw-muted:#65758c;
|
|
2031
|
+
--tcw-border:#dbe5f0;
|
|
2032
|
+
--tcw-primary:#2563eb;
|
|
2033
|
+
--tcw-primary-dark:#1d4ed8;
|
|
2034
|
+
--tcw-success:#139160;
|
|
2035
|
+
--tcw-warning:#e07818;
|
|
2036
|
+
--tcw-danger:#bd2f2f;
|
|
2037
|
+
--tcw-violet:#7c3aed;
|
|
2038
|
+
--tcw-slate:#526174;
|
|
2039
|
+
--tcw-shadow:0 14px 42px rgba(20, 35, 55, .08);
|
|
2040
|
+
}
|
|
2041
|
+
body { background: var(--tcw-bg); letter-spacing: 0; }
|
|
2042
|
+
.tcw-shell {
|
|
2043
|
+
display: grid;
|
|
2044
|
+
grid-template-columns: 248px minmax(0, 1fr) 300px;
|
|
2045
|
+
grid-template-rows: 1fr;
|
|
2046
|
+
gap: 0;
|
|
2047
|
+
min-height: 100vh;
|
|
2048
|
+
padding: 0;
|
|
2049
|
+
background: var(--tcw-bg);
|
|
2050
|
+
}
|
|
2051
|
+
.tcw-sidebar {
|
|
2052
|
+
display: grid;
|
|
2053
|
+
grid-template-rows: auto auto auto 1fr;
|
|
2054
|
+
align-content: start;
|
|
2055
|
+
gap: 18px;
|
|
2056
|
+
min-width: 0;
|
|
2057
|
+
border-right: 1px solid var(--tcw-border);
|
|
2058
|
+
background: var(--tcw-card);
|
|
2059
|
+
padding: 20px 14px;
|
|
2060
|
+
}
|
|
2061
|
+
.tcw-brand {
|
|
2062
|
+
display: flex;
|
|
2063
|
+
align-items: center;
|
|
2064
|
+
gap: 10px;
|
|
2065
|
+
padding: 0 6px 6px;
|
|
2066
|
+
}
|
|
2067
|
+
.tcw-brand-mark {
|
|
2068
|
+
display: grid;
|
|
2069
|
+
place-items: center;
|
|
2070
|
+
width: 34px;
|
|
2071
|
+
height: 34px;
|
|
2072
|
+
border-radius: 8px;
|
|
2073
|
+
background: #e8f0ff;
|
|
2074
|
+
color: var(--tcw-primary);
|
|
2075
|
+
font-size: 12px;
|
|
2076
|
+
font-weight: 900;
|
|
2077
|
+
}
|
|
2078
|
+
.tcw-brand strong { display: block; font-size: 16px; line-height: 1.2; }
|
|
2079
|
+
.tcw-brand span { display: block; color: var(--tcw-muted); font-size: 12px; }
|
|
2080
|
+
.tcw-nav { display: grid; gap: 6px; }
|
|
2081
|
+
.tcw-tab {
|
|
2082
|
+
display: grid;
|
|
2083
|
+
grid-template-columns: 26px minmax(0, 1fr) auto;
|
|
2084
|
+
align-items: center;
|
|
2085
|
+
gap: 8px;
|
|
2086
|
+
min-height: 38px;
|
|
2087
|
+
border: 1px solid transparent;
|
|
2088
|
+
border-radius: 8px;
|
|
2089
|
+
background: transparent;
|
|
2090
|
+
color: var(--tcw-text);
|
|
2091
|
+
padding: 7px 8px;
|
|
2092
|
+
text-align: left;
|
|
2093
|
+
font-weight: 800;
|
|
2094
|
+
}
|
|
2095
|
+
.tcw-tab.active {
|
|
2096
|
+
border-color: #d8e7ff;
|
|
2097
|
+
background: #eff6ff;
|
|
2098
|
+
color: #174ea6;
|
|
2099
|
+
}
|
|
2100
|
+
.tcw-overview-panel {
|
|
2101
|
+
display: grid;
|
|
2102
|
+
gap: 12px;
|
|
2103
|
+
}
|
|
2104
|
+
.tcw-overview-tabs {
|
|
2105
|
+
display: inline-flex;
|
|
2106
|
+
align-items: center;
|
|
2107
|
+
gap: 0;
|
|
2108
|
+
width: fit-content;
|
|
2109
|
+
border: 1px solid var(--tcw-border);
|
|
2110
|
+
border-radius: 12px;
|
|
2111
|
+
overflow: hidden;
|
|
2112
|
+
background: #fff;
|
|
2113
|
+
}
|
|
2114
|
+
.tcw-overview-tab {
|
|
2115
|
+
min-height: 38px;
|
|
2116
|
+
border: 0;
|
|
2117
|
+
border-right: 1px solid var(--tcw-border);
|
|
2118
|
+
background: #fff;
|
|
2119
|
+
color: var(--tcw-muted);
|
|
2120
|
+
padding: 8px 16px;
|
|
2121
|
+
font-weight: 800;
|
|
2122
|
+
}
|
|
2123
|
+
.tcw-overview-tab:last-child { border-right: 0; }
|
|
2124
|
+
.tcw-overview-tab.active {
|
|
2125
|
+
background: #eff6ff;
|
|
2126
|
+
color: var(--tcw-primary);
|
|
2127
|
+
}
|
|
2128
|
+
.tcw-tab em {
|
|
2129
|
+
min-width: 22px;
|
|
2130
|
+
border-radius: 999px;
|
|
2131
|
+
background: #edf2f7;
|
|
2132
|
+
color: var(--tcw-muted);
|
|
2133
|
+
padding: 2px 6px;
|
|
2134
|
+
font-size: 11px;
|
|
2135
|
+
font-style: normal;
|
|
2136
|
+
text-align: center;
|
|
2137
|
+
}
|
|
2138
|
+
.tcw-nav-icon {
|
|
2139
|
+
display: grid;
|
|
2140
|
+
place-items: center;
|
|
2141
|
+
width: 24px;
|
|
2142
|
+
height: 24px;
|
|
2143
|
+
border-radius: 7px;
|
|
2144
|
+
font-size: 11px;
|
|
2145
|
+
font-weight: 900;
|
|
2146
|
+
}
|
|
2147
|
+
.tcw-nav-icon.blue { background: #e8f0ff; color: var(--tcw-primary); }
|
|
2148
|
+
.tcw-nav-icon.green { background: #e7f8ef; color: var(--tcw-success); }
|
|
2149
|
+
.tcw-nav-icon.orange { background: #fff2df; color: var(--tcw-warning); }
|
|
2150
|
+
.tcw-nav-icon.violet { background: #f1eaff; color: var(--tcw-violet); }
|
|
2151
|
+
.tcw-nav-icon.slate { background: #eef2f6; color: var(--tcw-slate); }
|
|
2152
|
+
.tcw-sidebar-section {
|
|
2153
|
+
display: grid;
|
|
2154
|
+
gap: 8px;
|
|
2155
|
+
border-top: 1px solid var(--tcw-border);
|
|
2156
|
+
padding: 14px 6px 0;
|
|
2157
|
+
}
|
|
2158
|
+
.tcw-sidebar-section h2 {
|
|
2159
|
+
margin: 0;
|
|
2160
|
+
color: var(--tcw-muted);
|
|
2161
|
+
font-size: 12px;
|
|
2162
|
+
}
|
|
2163
|
+
.tcw-sidebar-section.compact p {
|
|
2164
|
+
margin: 0;
|
|
2165
|
+
color: var(--tcw-muted);
|
|
2166
|
+
font-size: 12px;
|
|
2167
|
+
line-height: 1.6;
|
|
2168
|
+
}
|
|
2169
|
+
.tcw-flow-list {
|
|
2170
|
+
display: grid;
|
|
2171
|
+
gap: 8px;
|
|
2172
|
+
margin: 0;
|
|
2173
|
+
padding: 0;
|
|
2174
|
+
list-style: none;
|
|
2175
|
+
color: var(--tcw-text);
|
|
2176
|
+
font-size: 12px;
|
|
2177
|
+
}
|
|
2178
|
+
.tcw-flow-list li {
|
|
2179
|
+
display: flex;
|
|
2180
|
+
gap: 8px;
|
|
2181
|
+
align-items: center;
|
|
2182
|
+
}
|
|
2183
|
+
.tcw-flow-list span {
|
|
2184
|
+
width: 7px;
|
|
2185
|
+
height: 7px;
|
|
2186
|
+
border-radius: 999px;
|
|
2187
|
+
background: var(--tcw-primary);
|
|
2188
|
+
}
|
|
2189
|
+
.tcw-workspace {
|
|
2190
|
+
display: grid;
|
|
2191
|
+
grid-template-rows: auto 1fr;
|
|
2192
|
+
min-width: 0;
|
|
2193
|
+
padding: 18px;
|
|
2194
|
+
}
|
|
2195
|
+
.tcw-header {
|
|
2196
|
+
display: flex;
|
|
2197
|
+
align-items: center;
|
|
2198
|
+
justify-content: space-between;
|
|
2199
|
+
gap: 14px;
|
|
2200
|
+
min-height: 64px;
|
|
2201
|
+
border: 0;
|
|
2202
|
+
border-radius: 0;
|
|
2203
|
+
background: transparent;
|
|
2204
|
+
padding: 0 0 14px;
|
|
2205
|
+
}
|
|
2206
|
+
.tcw-kicker {
|
|
2207
|
+
margin: 0 0 3px;
|
|
2208
|
+
color: var(--tcw-muted);
|
|
2209
|
+
font-size: 12px;
|
|
2210
|
+
font-weight: 700;
|
|
2211
|
+
}
|
|
2212
|
+
.tcw-title-block h1 {
|
|
2213
|
+
margin: 0;
|
|
2214
|
+
font-size: 24px;
|
|
2215
|
+
line-height: 1.2;
|
|
2216
|
+
}
|
|
2217
|
+
.tcw-title-block p {
|
|
2218
|
+
margin: 4px 0 0;
|
|
2219
|
+
color: var(--tcw-muted);
|
|
2220
|
+
font-size: 13px;
|
|
2221
|
+
}
|
|
2222
|
+
.tcw-header-actions {
|
|
2223
|
+
display: grid;
|
|
2224
|
+
grid-template-columns: minmax(260px, 380px) auto;
|
|
2225
|
+
gap: 8px;
|
|
2226
|
+
align-items: center;
|
|
2227
|
+
}
|
|
2228
|
+
.tcw-main { display: grid; min-width: 0; }
|
|
2229
|
+
.tcw-content { min-width: 0; border: 0; background: transparent; padding: 0; }
|
|
2230
|
+
.tcw-business-panel, .tcw-panel {
|
|
2231
|
+
border: 1px solid var(--tcw-border);
|
|
2232
|
+
border-radius: 8px;
|
|
2233
|
+
background: var(--tcw-card);
|
|
2234
|
+
box-shadow: var(--tcw-shadow);
|
|
2235
|
+
}
|
|
2236
|
+
.tcw-business-head {
|
|
2237
|
+
min-height: auto;
|
|
2238
|
+
align-items: center;
|
|
2239
|
+
border-bottom: 1px solid var(--tcw-border);
|
|
2240
|
+
background: linear-gradient(90deg, #ffffff, #f7fbff);
|
|
2241
|
+
padding: 20px 22px;
|
|
2242
|
+
}
|
|
2243
|
+
.tcw-business-head h2 { font-size: 18px; }
|
|
2244
|
+
.tcw-business-body { padding: 18px 22px 22px; }
|
|
2245
|
+
.tcw-metrics {
|
|
2246
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
2247
|
+
gap: 10px;
|
|
2248
|
+
}
|
|
2249
|
+
.tcw-metric {
|
|
2250
|
+
border-color: var(--tcw-border);
|
|
2251
|
+
background: var(--tcw-card);
|
|
2252
|
+
box-shadow: var(--tcw-shadow);
|
|
2253
|
+
}
|
|
2254
|
+
.tcw-metric strong { color: var(--tcw-text); font-size: 24px; }
|
|
2255
|
+
.tcw-btn, .tcw-upload, .tcw-mini-btn, .tcw-icon-btn {
|
|
2256
|
+
border-radius: 7px;
|
|
2257
|
+
}
|
|
2258
|
+
.tcw-btn-primary {
|
|
2259
|
+
border-color: var(--tcw-primary);
|
|
2260
|
+
background: var(--tcw-primary);
|
|
2261
|
+
}
|
|
2262
|
+
.tcw-btn-primary:hover:not(:disabled) { background: var(--tcw-primary-dark); }
|
|
2263
|
+
.tcw-upload {
|
|
2264
|
+
border-color: #bcd3ff;
|
|
2265
|
+
background: #eff6ff;
|
|
2266
|
+
color: var(--tcw-primary);
|
|
2267
|
+
}
|
|
2268
|
+
.tcw-table-wrap {
|
|
2269
|
+
border-color: var(--tcw-border);
|
|
2270
|
+
border-radius: 8px;
|
|
2271
|
+
}
|
|
2272
|
+
.tcw-table th {
|
|
2273
|
+
background: var(--tcw-soft);
|
|
2274
|
+
color: var(--tcw-muted);
|
|
2275
|
+
font-size: 11px;
|
|
2276
|
+
}
|
|
2277
|
+
.tcw-table td { background: var(--tcw-card); }
|
|
2278
|
+
.tcw-table tr:hover td { background: #fbfdff; }
|
|
2279
|
+
.tcw-assistant {
|
|
2280
|
+
display: grid;
|
|
2281
|
+
align-content: start;
|
|
2282
|
+
gap: 12px;
|
|
2283
|
+
border-left: 1px solid var(--tcw-border);
|
|
2284
|
+
background: var(--tcw-card);
|
|
2285
|
+
padding: 18px 14px;
|
|
2286
|
+
}
|
|
2287
|
+
.tcw-assistant-head {
|
|
2288
|
+
display: flex;
|
|
2289
|
+
align-items: flex-start;
|
|
2290
|
+
gap: 10px;
|
|
2291
|
+
padding: 2px 4px 8px;
|
|
2292
|
+
}
|
|
2293
|
+
.tcw-assistant-mark {
|
|
2294
|
+
display: grid;
|
|
2295
|
+
place-items: center;
|
|
2296
|
+
width: 32px;
|
|
2297
|
+
height: 32px;
|
|
2298
|
+
border-radius: 8px;
|
|
2299
|
+
background: #e7f8ef;
|
|
2300
|
+
color: var(--tcw-success);
|
|
2301
|
+
font-size: 12px;
|
|
2302
|
+
font-weight: 900;
|
|
2303
|
+
}
|
|
2304
|
+
.tcw-assistant-head strong { display: block; font-size: 15px; }
|
|
2305
|
+
.tcw-assistant-head p {
|
|
2306
|
+
margin: 3px 0 0;
|
|
2307
|
+
color: var(--tcw-muted);
|
|
2308
|
+
font-size: 12px;
|
|
2309
|
+
line-height: 1.5;
|
|
2310
|
+
}
|
|
2311
|
+
.tcw-assistant-card {
|
|
2312
|
+
display: grid;
|
|
2313
|
+
gap: 8px;
|
|
2314
|
+
border: 1px solid var(--tcw-border);
|
|
2315
|
+
border-radius: 8px;
|
|
2316
|
+
background: var(--tcw-soft);
|
|
2317
|
+
padding: 12px;
|
|
2318
|
+
}
|
|
2319
|
+
.tcw-assistant-card h3 {
|
|
2320
|
+
margin: 0;
|
|
2321
|
+
font-size: 13px;
|
|
2322
|
+
}
|
|
2323
|
+
.tcw-assistant-card p {
|
|
2324
|
+
margin: 0;
|
|
2325
|
+
color: var(--tcw-muted);
|
|
2326
|
+
font-size: 12px;
|
|
2327
|
+
line-height: 1.6;
|
|
2328
|
+
}
|
|
2329
|
+
.tcw-assistant-actions {
|
|
2330
|
+
display: flex;
|
|
2331
|
+
flex-wrap: wrap;
|
|
2332
|
+
gap: 8px;
|
|
2333
|
+
}
|
|
2334
|
+
.tcw-status.ok { background: #e7f8ef; color: var(--tcw-success); }
|
|
2335
|
+
.tcw-status.warn { background: #fff2df; color: #b35b00; }
|
|
2336
|
+
.tcw-status.danger { background: #fde8e6; color: var(--tcw-danger); }
|
|
2337
|
+
.tcw-status.muted { background: #eef2f6; color: var(--tcw-muted); }
|
|
2338
|
+
@media (max-width: 1280px) {
|
|
2339
|
+
.tcw-shell { grid-template-columns: 230px minmax(0, 1fr); }
|
|
2340
|
+
.tcw-assistant { display: none; }
|
|
2341
|
+
}
|
|
2342
|
+
@media (max-width: 900px) {
|
|
2343
|
+
.tcw-shell { grid-template-columns: 1fr; }
|
|
2344
|
+
.tcw-sidebar {
|
|
2345
|
+
position: static;
|
|
2346
|
+
border-right: 0;
|
|
2347
|
+
border-bottom: 1px solid var(--tcw-border);
|
|
2348
|
+
}
|
|
2349
|
+
.tcw-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
2350
|
+
.tcw-workspace { padding: 14px; }
|
|
2351
|
+
.tcw-header, .tcw-business-head, .tcw-list-toolbar {
|
|
2352
|
+
align-items: stretch;
|
|
2353
|
+
flex-direction: column;
|
|
2354
|
+
}
|
|
2355
|
+
.tcw-header-actions { grid-template-columns: 1fr; }
|
|
2356
|
+
.tcw-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
2357
|
+
}
|
|
2358
|
+
@media (max-width: 560px) {
|
|
2359
|
+
.tcw-nav { grid-template-columns: 1fr; }
|
|
2360
|
+
.tcw-metrics, .tcw-edit-grid, .tcw-edit-grid-two { grid-template-columns: 1fr; }
|
|
2361
|
+
}
|
|
1891
2362
|
`
|
|
1892
2363
|
document.head.appendChild(style)
|
|
1893
2364
|
}
|
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.45",
|
|
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",
|