@chenchaolong/plugin-trade-compliance-workbench 0.1.8 → 0.1.9

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.
@@ -321,12 +321,14 @@
321
321
 
322
322
  function renderControlledGoodsPage() {
323
323
  return h('div', { className: 'tcw-page controlled-goods-page' },
324
- pageToolbar('管控商品', '智能体识别结果先进入待审核,确认后写入正式管控商品库。', [
324
+ businessPanel('管控商品', '上传管控目录后,识别结果在列表内完成审核、驳回和入库。', [
325
325
  uploadButton('upload_controlled_goods_file', '上传管控商品文件'),
326
326
  h('button', { className: 'tcw-btn tcw-btn-soft', onClick: () => setShowManualForm(!showManualForm) }, showManualForm ? '收起新增' : '手动新增')
327
- ]),
328
- showManualForm ? renderControlledGoodsForm() : null,
329
- renderListPanel('管控商品列表', 'pending-controlled-goods confirmed-controlled-goods', controlledReviews, ['商品名称', '海关编码', '关键词', '管控说明', '来源'], (item) => {
327
+ ], [
328
+ showManualForm ? renderControlledGoodsForm() : null,
329
+ renderListToolbar('管控商品列表', controlledReviews.length),
330
+ h('div', { className: 'pending-controlled-goods confirmed-controlled-goods tcw-table-section' },
331
+ reviewTable(['商品名称', '海关编码', '关键词', '管控说明', '来源'], controlledReviews, (item) => {
330
332
  const row = readMerged(item)
331
333
  return [
332
334
  value(row.productName || item.title),
@@ -335,7 +337,9 @@
335
337
  value(row.controlNote),
336
338
  value(item.sourceLocation || row.sourceFileName)
337
339
  ]
338
- }, '暂无管控商品识别结果。上传目录并等待智能体调用工具后会显示在这里。')
340
+ }, '暂无管控商品识别结果。上传目录并等待智能体调用工具后会显示在这里。')
341
+ )
342
+ ])
339
343
  )
340
344
  }
341
345
 
@@ -458,7 +462,26 @@
458
462
  }
459
463
 
460
464
  function reviewTable(headers, rows, mapRow, emptyText) {
461
- return table(['', ...headers, '状态', '操作'], rows, (row) => [
465
+ const selectableIds = getSelectableRowIds(rows)
466
+ const selectedVisibleIds = selectableIds.filter((id) => selectedIds.includes(id))
467
+ const allVisibleSelected = selectableIds.length > 0 && selectedVisibleIds.length === selectableIds.length
468
+ const partiallySelected = selectedVisibleIds.length > 0 && selectedVisibleIds.length < selectableIds.length
469
+ return table([
470
+ h('input', {
471
+ className: 'row-selection-checkbox',
472
+ type: 'checkbox',
473
+ 'aria-label': '全选当前列表',
474
+ checked: allVisibleSelected,
475
+ disabled: selectableIds.length === 0,
476
+ ref: (node) => {
477
+ if (node) node.indeterminate = partiallySelected
478
+ },
479
+ onChange: (event) => toggleAllVisibleRows(rows, event.target.checked)
480
+ }),
481
+ ...headers,
482
+ '状态',
483
+ '操作'
484
+ ], rows, (row) => [
462
485
  h('input', {
463
486
  className: 'row-selection-checkbox',
464
487
  type: 'checkbox',
@@ -480,6 +503,21 @@
480
503
  setSelectedIds(checked ? Array.from(new Set([...selectedIds, id])) : selectedIds.filter((item) => item !== id))
481
504
  }
482
505
 
506
+ function toggleAllVisibleRows(rows, checked) {
507
+ const visibleIds = getSelectableRowIds(rows)
508
+ if (checked) {
509
+ setSelectedIds(Array.from(new Set([...selectedIds, ...visibleIds])))
510
+ return
511
+ }
512
+ setSelectedIds(selectedIds.filter((id) => !visibleIds.includes(id)))
513
+ }
514
+
515
+ function getSelectableRowIds(rows) {
516
+ return (rows || [])
517
+ .filter((row) => row.id && !row.materializedOnly && row.reviewStatus !== 'confirmed')
518
+ .map((row) => row.id)
519
+ }
520
+
483
521
  function pageToolbar(title, subtitle, actions) {
484
522
  return h('div', { className: 'tcw-page-head' },
485
523
  h('div', null, h('h2', null, title), h('p', null, subtitle)),
@@ -523,7 +561,7 @@
523
561
  if (!rows || rows.length === 0) return empty(emptyText || '暂无数据。')
524
562
  return h('div', { className: 'tcw-table-wrap' },
525
563
  h('table', { className: 'tcw-table' },
526
- h('thead', null, h('tr', null, headers.map((item) => h('th', { key: item }, item)))),
564
+ h('thead', null, h('tr', null, headers.map((item, index) => h('th', { key: index }, item)))),
527
565
  h('tbody', null, rows.map((row, index) =>
528
566
  h('tr', { key: row.id || index, className: onRowClick ? 'clickable' : '', onClick: onRowClick ? () => onRowClick(row) : undefined },
529
567
  mapRow(row).map((cell, cellIndex) => h('td', { key: cellIndex }, cell))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chenchaolong/plugin-trade-compliance-workbench",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
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",