@chenchaolong/plugin-trade-compliance-workbench 0.1.48 → 0.1.50
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.
|
@@ -74,6 +74,8 @@
|
|
|
74
74
|
const [busy, setBusy] = React.useState(false)
|
|
75
75
|
const [query, setQuery] = React.useState('')
|
|
76
76
|
const [pageByList, setPageByList] = React.useState({})
|
|
77
|
+
const [pageSizeByList, setPageSizeByList] = React.useState({})
|
|
78
|
+
const [pageJumpByList, setPageJumpByList] = React.useState({})
|
|
77
79
|
const [detailItem, setDetailItem] = React.useState(null)
|
|
78
80
|
const [formDialog, setFormDialog] = React.useState(null)
|
|
79
81
|
const [deleteDialog, setDeleteDialog] = React.useState(null)
|
|
@@ -84,6 +86,7 @@
|
|
|
84
86
|
loading: false,
|
|
85
87
|
searched: false,
|
|
86
88
|
error: '',
|
|
89
|
+
jumpPage: '',
|
|
87
90
|
result: null
|
|
88
91
|
})
|
|
89
92
|
const pollingRef = React.useRef(null)
|
|
@@ -104,10 +107,11 @@
|
|
|
104
107
|
}
|
|
105
108
|
}, [])
|
|
106
109
|
|
|
107
|
-
React.useEffect(reportResize, [data, activePage, selectedIds, statusFilter, overviewTab, busy, formDialog, deleteDialog, hsCodeSearch, hsCodeDetailDialog])
|
|
110
|
+
React.useEffect(reportResize, [data, activePage, selectedIds, statusFilter, overviewTab, pageByList, pageSizeByList, busy, formDialog, deleteDialog, hsCodeSearch, hsCodeDetailDialog])
|
|
108
111
|
|
|
109
112
|
const reviewItems = data.reviewItems.filter((item) => !isPlaceholderReviewItem(item))
|
|
110
113
|
const pendingItems = reviewItems.filter((item) => (item.reviewStatus || 'pending') === 'pending')
|
|
114
|
+
const filteredPendingItems = filterItems(pendingItems, query, overviewSearchKeys)
|
|
111
115
|
const controlledReviewRows = reviewItems.filter((item) => item.type === 'controlled_goods' && item.reviewStatus !== 'confirmed')
|
|
112
116
|
const controlledRows = controlledReviewRows.concat(data.controlledGoods.map(toControlledGoodsReviewRow))
|
|
113
117
|
const controlledReviews = applyStatusFilter(filterItems(controlledRows, query, reviewSearchKeys), statusFilter)
|
|
@@ -223,6 +227,7 @@
|
|
|
223
227
|
setFormDialog((current) => current ? Object.assign({}, current, {
|
|
224
228
|
hsCandidateKeyword: keyword,
|
|
225
229
|
hsCandidatePage: nextPage,
|
|
230
|
+
hsCandidateLocalPage: 1,
|
|
226
231
|
hsCandidateLoading: false,
|
|
227
232
|
hsCandidateError: '',
|
|
228
233
|
hsCandidateStatus: candidates.length ? 'pending_confirmation' : 'not_found',
|
|
@@ -471,6 +476,10 @@
|
|
|
471
476
|
hsCandidates: Array.isArray(merged.hsCodeCandidates) ? merged.hsCodeCandidates : [],
|
|
472
477
|
hsCandidateKeyword: merged.hsCodeLookupKeyword || buildSupplierHsCandidateKeyword(merged),
|
|
473
478
|
hsCandidatePage: 1,
|
|
479
|
+
hsCandidateJumpPage: '',
|
|
480
|
+
hsCandidateLocalPage: 1,
|
|
481
|
+
hsCandidateLocalPageSize: 5,
|
|
482
|
+
hsCandidateLocalJumpPage: '',
|
|
474
483
|
hsCandidatePagination: null,
|
|
475
484
|
hsCandidateStatus: merged.hsCodeLookupStatus || '',
|
|
476
485
|
hsCandidateError: merged.hsCodeLookupError || '',
|
|
@@ -487,6 +496,10 @@
|
|
|
487
496
|
hsCandidates: [],
|
|
488
497
|
hsCandidateKeyword: '',
|
|
489
498
|
hsCandidatePage: 1,
|
|
499
|
+
hsCandidateJumpPage: '',
|
|
500
|
+
hsCandidateLocalPage: 1,
|
|
501
|
+
hsCandidateLocalPageSize: 5,
|
|
502
|
+
hsCandidateLocalJumpPage: '',
|
|
490
503
|
hsCandidatePagination: null,
|
|
491
504
|
hsCandidateStatus: '',
|
|
492
505
|
hsCandidateError: '',
|
|
@@ -672,15 +685,20 @@
|
|
|
672
685
|
}
|
|
673
686
|
|
|
674
687
|
function renderOverviewPage() {
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
688
|
+
const filteredPendingControlledItems = filteredPendingItems.filter((item) => item.type === 'controlled_goods')
|
|
689
|
+
const filteredPendingSupplierItems = filteredPendingItems.filter((item) => item.type === 'supplier_product')
|
|
690
|
+
const filteredPendingSalesItems = filteredPendingItems.filter((item) => item.type === 'customs_workbook')
|
|
691
|
+
const overviewRows = overviewTab === 'all'
|
|
692
|
+
? filteredPendingItems
|
|
693
|
+
: filteredPendingItems.filter((item) => item.type === overviewTab)
|
|
694
|
+
const overviewListKey = `overview-${overviewTab}`
|
|
695
|
+
const overviewPage = paginateRows(overviewListKey, overviewRows)
|
|
678
696
|
return h('div', { className: 'tcw-page overview-page' },
|
|
679
697
|
h('section', { className: 'tcw-metrics' },
|
|
680
|
-
metric('待审核',
|
|
681
|
-
metric('管控识别待审',
|
|
682
|
-
metric('供应商商品待审',
|
|
683
|
-
metric('销售合同待审',
|
|
698
|
+
metric('待审核', filteredPendingItems.length, 'dashboard', 'blue'),
|
|
699
|
+
metric('管控识别待审', filteredPendingControlledItems.length, 'shield', 'green'),
|
|
700
|
+
metric('供应商商品待审', filteredPendingSupplierItems.length, 'box', 'orange'),
|
|
701
|
+
metric('销售合同待审', filteredPendingSalesItems.length, 'invoice', 'violet'),
|
|
684
702
|
metric('已入库管控商品', data.controlledGoods.length, 'archive', 'slate'),
|
|
685
703
|
metric('已入库供应商商品', data.products.length, 'supplier', 'green'),
|
|
686
704
|
metric('销售发票历史', data.workbookGenerations.length, 'document', 'violet'),
|
|
@@ -689,14 +707,15 @@
|
|
|
689
707
|
panel('待办事项明细',
|
|
690
708
|
h('div', { className: 'tcw-overview-panel' },
|
|
691
709
|
h('div', { className: 'tcw-overview-tabs' }, [
|
|
692
|
-
overviewTabButton('all', '全部',
|
|
693
|
-
overviewTabButton('controlled_goods', '管控商品',
|
|
694
|
-
overviewTabButton('supplier_product', '供应商商品',
|
|
695
|
-
overviewTabButton('customs_workbook', '销售发票',
|
|
710
|
+
overviewTabButton('all', '全部', filteredPendingItems.length),
|
|
711
|
+
overviewTabButton('controlled_goods', '管控商品', filteredPendingControlledItems.length),
|
|
712
|
+
overviewTabButton('supplier_product', '供应商商品', filteredPendingSupplierItems.length),
|
|
713
|
+
overviewTabButton('customs_workbook', '销售发票', filteredPendingSalesItems.length)
|
|
696
714
|
]),
|
|
697
|
-
|
|
698
|
-
? compactReviewList(
|
|
699
|
-
: empty('暂无待审核记录。智能体识别结果会先出现在这里。')
|
|
715
|
+
overviewPage.rows.length
|
|
716
|
+
? compactReviewList(overviewPage.rows)
|
|
717
|
+
: empty('暂无待审核记录。智能体识别结果会先出现在这里。'),
|
|
718
|
+
pagination(overviewListKey, overviewRows.length)
|
|
700
719
|
)
|
|
701
720
|
)
|
|
702
721
|
)
|
|
@@ -892,20 +911,26 @@
|
|
|
892
911
|
function renderHsCodePagination(pagination) {
|
|
893
912
|
if (!pagination || (!pagination.hasPrevious && !pagination.hasNext && (!pagination.pages || pagination.pages.length <= 1))) return null
|
|
894
913
|
const pages = Array.isArray(pagination.pages) ? pagination.pages.filter((item) => item.page) : []
|
|
895
|
-
const
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
)
|
|
908
|
-
|
|
914
|
+
const maxPage = Number(pagination.maxVisiblePage) || Math.max(...pages.map((item) => Number(item.page) || 0), pagination.currentPage || hsCodeSearch.page || 1)
|
|
915
|
+
const currentPage = pagination.currentPage || hsCodeSearch.page || 1
|
|
916
|
+
return renderUnifiedPagination({
|
|
917
|
+
page: currentPage,
|
|
918
|
+
totalPages: Math.max(1, maxPage),
|
|
919
|
+
pageSize: 10,
|
|
920
|
+
fixedPageSize: true,
|
|
921
|
+
loading: hsCodeSearch.loading,
|
|
922
|
+
hasPrevious: pagination.hasPrevious,
|
|
923
|
+
hasNext: pagination.hasNext,
|
|
924
|
+
jumpValue: hsCodeSearch.jumpPage || '',
|
|
925
|
+
onPageChange: searchHsCodePage,
|
|
926
|
+
onJumpInput: (nextValue) => setHsCodeSearch(Object.assign({}, hsCodeSearch, { jumpPage: nextValue })),
|
|
927
|
+
onJump: () => {
|
|
928
|
+
const nextPage = Number(hsCodeSearch.jumpPage)
|
|
929
|
+
if (!Number.isFinite(nextPage) || nextPage <= 0) return
|
|
930
|
+
searchHsCodePage(nextPage)
|
|
931
|
+
setHsCodeSearch((current) => Object.assign({}, current, { jumpPage: '' }))
|
|
932
|
+
}
|
|
933
|
+
})
|
|
909
934
|
}
|
|
910
935
|
|
|
911
936
|
function compactReviewList(items) {
|
|
@@ -1050,7 +1075,7 @@
|
|
|
1050
1075
|
}
|
|
1051
1076
|
|
|
1052
1077
|
function paginateRows(listKey, rows) {
|
|
1053
|
-
const pageSize =
|
|
1078
|
+
const pageSize = getPageSize(listKey)
|
|
1054
1079
|
const total = rows.length
|
|
1055
1080
|
const totalPages = Math.max(1, Math.ceil(total / pageSize))
|
|
1056
1081
|
const current = Math.min(Math.max(pageByList[listKey] || 1, 1), totalPages)
|
|
@@ -1058,15 +1083,44 @@
|
|
|
1058
1083
|
}
|
|
1059
1084
|
|
|
1060
1085
|
function pagination(listKey, total) {
|
|
1061
|
-
if (total <=
|
|
1086
|
+
if (total <= 0) return null
|
|
1062
1087
|
const page = paginateRows(listKey, Array.from({ length: total }))
|
|
1063
|
-
return
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1088
|
+
return renderUnifiedPagination({
|
|
1089
|
+
total,
|
|
1090
|
+
page: page.page,
|
|
1091
|
+
totalPages: page.totalPages,
|
|
1092
|
+
pageSize: page.pageSize,
|
|
1093
|
+
pageSizeOptions: [10, 20, 50],
|
|
1094
|
+
jumpValue: pageJumpByList[listKey] || '',
|
|
1095
|
+
onPageChange: (nextPage) => setLocalPage(listKey, nextPage, page.totalPages),
|
|
1096
|
+
onPageSizeChange: (nextSize) => setLocalPageSize(listKey, nextSize),
|
|
1097
|
+
onJumpInput: (nextValue) => setPageJumpByList(Object.assign({}, pageJumpByList, { [listKey]: nextValue })),
|
|
1098
|
+
onJump: () => jumpLocalPage(listKey, page.totalPages)
|
|
1099
|
+
})
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
function getPageSize(listKey) {
|
|
1103
|
+
const value = Number(pageSizeByList[listKey])
|
|
1104
|
+
return Number.isFinite(value) && value > 0 ? value : 10
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
function setLocalPage(listKey, nextPage, totalPages) {
|
|
1108
|
+
const page = Math.min(Math.max(Number(nextPage) || 1, 1), totalPages || 1)
|
|
1109
|
+
setPageByList(Object.assign({}, pageByList, { [listKey]: page }))
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
function setLocalPageSize(listKey, nextSize) {
|
|
1113
|
+
const pageSize = Number(nextSize) || 10
|
|
1114
|
+
setPageSizeByList(Object.assign({}, pageSizeByList, { [listKey]: pageSize }))
|
|
1115
|
+
setPageByList(Object.assign({}, pageByList, { [listKey]: 1 }))
|
|
1116
|
+
setPageJumpByList(Object.assign({}, pageJumpByList, { [listKey]: '' }))
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
function jumpLocalPage(listKey, totalPages) {
|
|
1120
|
+
const value = Number(pageJumpByList[listKey])
|
|
1121
|
+
if (!Number.isFinite(value) || value <= 0) return
|
|
1122
|
+
setLocalPage(listKey, value, totalPages)
|
|
1123
|
+
setPageJumpByList(Object.assign({}, pageJumpByList, { [listKey]: '' }))
|
|
1070
1124
|
}
|
|
1071
1125
|
|
|
1072
1126
|
function renderDetailModal() {
|
|
@@ -1128,6 +1182,13 @@
|
|
|
1128
1182
|
function renderSupplierHsCandidatePanel() {
|
|
1129
1183
|
const candidates = Array.isArray(formDialog.hsCandidates) ? formDialog.hsCandidates : []
|
|
1130
1184
|
const pagination = formDialog.hsCandidatePagination || null
|
|
1185
|
+
const hasSourcePagination = pagination && (pagination.hasPrevious || pagination.hasNext || (pagination.pages && pagination.pages.length > 1))
|
|
1186
|
+
const localPageSize = Math.max(1, Number(formDialog.hsCandidateLocalPageSize) || 5)
|
|
1187
|
+
const localTotalPages = Math.max(1, Math.ceil(candidates.length / localPageSize))
|
|
1188
|
+
const localPage = Math.min(Math.max(Number(formDialog.hsCandidateLocalPage) || 1, 1), localTotalPages)
|
|
1189
|
+
const visibleCandidates = hasSourcePagination
|
|
1190
|
+
? candidates
|
|
1191
|
+
: candidates.slice((localPage - 1) * localPageSize, localPage * localPageSize)
|
|
1131
1192
|
return h('section', { className: 'tcw-hs-candidate-panel' },
|
|
1132
1193
|
h('div', { className: 'tcw-subsection-head' },
|
|
1133
1194
|
h('div', null,
|
|
@@ -1146,7 +1207,7 @@
|
|
|
1146
1207
|
),
|
|
1147
1208
|
formDialog.hsCandidateError ? h('div', { className: 'tcw-error' }, formDialog.hsCandidateError) : null,
|
|
1148
1209
|
candidates.length ? h('div', { className: 'tcw-hs-candidate-result' },
|
|
1149
|
-
table(['编码', '商品名称', '英文名称', '单位', '退税率', '监管', '检验检疫', '操作'],
|
|
1210
|
+
table(['编码', '商品名称', '英文名称', '单位', '退税率', '监管', '检验检疫', '操作'], visibleCandidates, (candidate) => [
|
|
1150
1211
|
h('strong', { className: 'tcw-hs-code-text' }, value(candidate.code)),
|
|
1151
1212
|
value(candidate.name),
|
|
1152
1213
|
value(candidate.englishName),
|
|
@@ -1159,28 +1220,100 @@
|
|
|
1159
1220
|
h('button', { type: 'button', className: 'tcw-mini-btn', disabled: !candidate.code && !candidate.detailUrl, onClick: () => loadHsCodeDetail(candidate) }, '详情')
|
|
1160
1221
|
)
|
|
1161
1222
|
], '暂无候选编码。'),
|
|
1162
|
-
|
|
1223
|
+
hasSourcePagination
|
|
1224
|
+
? renderSupplierHsCandidatePagination(pagination)
|
|
1225
|
+
: renderSupplierHsCandidateLocalPagination(candidates.length, localPage, localTotalPages, localPageSize)
|
|
1163
1226
|
) : empty('暂无候选编码,可调整关键词后查询。')
|
|
1164
1227
|
)
|
|
1165
1228
|
}
|
|
1166
1229
|
|
|
1230
|
+
function renderSupplierHsCandidateLocalPagination(total, page, totalPages, pageSize) {
|
|
1231
|
+
if (total <= pageSize) return null
|
|
1232
|
+
return renderUnifiedPagination({
|
|
1233
|
+
total,
|
|
1234
|
+
page,
|
|
1235
|
+
totalPages,
|
|
1236
|
+
pageSize,
|
|
1237
|
+
pageSizeOptions: [5, 10, 20],
|
|
1238
|
+
jumpValue: formDialog.hsCandidateLocalJumpPage || '',
|
|
1239
|
+
onPageChange: (nextPage) => setFormDialog(Object.assign({}, formDialog, { hsCandidateLocalPage: Math.min(Math.max(Number(nextPage) || 1, 1), totalPages) })),
|
|
1240
|
+
onPageSizeChange: (nextSize) => setFormDialog(Object.assign({}, formDialog, { hsCandidateLocalPageSize: Number(nextSize) || 5, hsCandidateLocalPage: 1, hsCandidateLocalJumpPage: '' })),
|
|
1241
|
+
onJumpInput: (nextValue) => setFormDialog(Object.assign({}, formDialog, { hsCandidateLocalJumpPage: nextValue })),
|
|
1242
|
+
onJump: () => {
|
|
1243
|
+
const nextPage = Number(formDialog.hsCandidateLocalJumpPage)
|
|
1244
|
+
if (!Number.isFinite(nextPage) || nextPage <= 0) return
|
|
1245
|
+
setFormDialog(Object.assign({}, formDialog, {
|
|
1246
|
+
hsCandidateLocalPage: Math.min(Math.max(nextPage, 1), totalPages),
|
|
1247
|
+
hsCandidateLocalJumpPage: ''
|
|
1248
|
+
}))
|
|
1249
|
+
}
|
|
1250
|
+
})
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1167
1253
|
function renderSupplierHsCandidatePagination(pagination) {
|
|
1168
1254
|
if (!pagination || (!pagination.hasPrevious && !pagination.hasNext && (!pagination.pages || pagination.pages.length <= 1))) return null
|
|
1169
1255
|
const pages = Array.isArray(pagination.pages) ? pagination.pages.filter((item) => item.page) : []
|
|
1170
|
-
const visiblePages = pages.filter((item, index, arr) => arr.findIndex((candidate) => candidate.page === item.page) === index).slice(0, 10)
|
|
1171
1256
|
const currentPage = pagination.currentPage || formDialog.hsCandidatePage || 1
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
)
|
|
1257
|
+
const maxPage = Number(pagination.maxVisiblePage) || Math.max(...pages.map((item) => Number(item.page) || 0), currentPage)
|
|
1258
|
+
return renderUnifiedPagination({
|
|
1259
|
+
page: currentPage,
|
|
1260
|
+
totalPages: Math.max(1, maxPage),
|
|
1261
|
+
pageSize: 10,
|
|
1262
|
+
fixedPageSize: true,
|
|
1263
|
+
loading: formDialog.hsCandidateLoading,
|
|
1264
|
+
hasPrevious: pagination.hasPrevious,
|
|
1265
|
+
hasNext: pagination.hasNext,
|
|
1266
|
+
jumpValue: formDialog.hsCandidateJumpPage || '',
|
|
1267
|
+
onPageChange: searchSupplierHsCandidatesForForm,
|
|
1268
|
+
onJumpInput: (nextValue) => setFormDialog(Object.assign({}, formDialog, { hsCandidateJumpPage: nextValue })),
|
|
1269
|
+
onJump: () => {
|
|
1270
|
+
const nextPage = Number(formDialog.hsCandidateJumpPage)
|
|
1271
|
+
if (!Number.isFinite(nextPage) || nextPage <= 0) return
|
|
1272
|
+
searchSupplierHsCandidatesForForm(nextPage)
|
|
1273
|
+
setFormDialog((current) => current ? Object.assign({}, current, { hsCandidateJumpPage: '' }) : current)
|
|
1274
|
+
}
|
|
1275
|
+
})
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
function renderUnifiedPagination(config) {
|
|
1279
|
+
const totalPages = Math.max(1, Number(config.totalPages) || 1)
|
|
1280
|
+
const page = Math.min(Math.max(Number(config.page) || 1, 1), totalPages)
|
|
1281
|
+
const canPrevious = config.hasPrevious === undefined ? page > 1 : Boolean(config.hasPrevious)
|
|
1282
|
+
const canNext = config.hasNext === undefined ? page < totalPages : Boolean(config.hasNext)
|
|
1283
|
+
const loading = Boolean(config.loading)
|
|
1284
|
+
const jumpValue = config.jumpValue || ''
|
|
1285
|
+
const pageSize = Number(config.pageSize) || 10
|
|
1286
|
+
return h('div', { className: 'tcw-pagination tcw-pagination-unified' },
|
|
1287
|
+
config.total == null ? null : h('span', { className: 'tcw-pagination-total' }, `共 ${config.total} 条`),
|
|
1288
|
+
h('button', { className: 'tcw-page-btn', disabled: loading || !canPrevious, onClick: () => config.onPageChange(1) }, '首页'),
|
|
1289
|
+
h('button', { className: 'tcw-page-btn', disabled: loading || !canPrevious, onClick: () => config.onPageChange(page - 1) }, '上一页'),
|
|
1290
|
+
h('span', { className: 'tcw-page-current' }, `第 ${page} / ${totalPages} 页`),
|
|
1291
|
+
h('button', { className: 'tcw-page-btn', disabled: loading || !canNext, onClick: () => config.onPageChange(page + 1) }, '下一页'),
|
|
1292
|
+
h('button', { className: 'tcw-page-btn', disabled: loading || !canNext, onClick: () => config.onPageChange(totalPages) }, '末页'),
|
|
1293
|
+
h('span', { className: 'tcw-page-size-label' }, '每页'),
|
|
1294
|
+
config.fixedPageSize
|
|
1295
|
+
? h('span', { className: 'tcw-page-size-fixed' }, `${pageSize} 条/页`)
|
|
1296
|
+
: h('select', {
|
|
1297
|
+
className: 'tcw-page-size-select',
|
|
1298
|
+
value: pageSize,
|
|
1299
|
+
onChange: (event) => config.onPageSizeChange(Number(event.target.value))
|
|
1300
|
+
}, (config.pageSizeOptions || [10, 20, 50]).map((size) => h('option', { key: size, value: size }, `${size} 条/页`))),
|
|
1301
|
+
h('input', {
|
|
1302
|
+
className: 'tcw-page-jump-input',
|
|
1303
|
+
type: 'number',
|
|
1304
|
+
min: 1,
|
|
1305
|
+
max: totalPages,
|
|
1306
|
+
value: jumpValue,
|
|
1307
|
+
placeholder: String(page),
|
|
1308
|
+
onChange: (event) => config.onJumpInput(event.target.value),
|
|
1309
|
+
onKeyDown: (event) => {
|
|
1310
|
+
if (event.key === 'Enter') {
|
|
1311
|
+
event.preventDefault()
|
|
1312
|
+
config.onJump()
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
}),
|
|
1316
|
+
h('button', { className: 'tcw-page-btn', disabled: loading, onClick: config.onJump }, '跳转')
|
|
1184
1317
|
)
|
|
1185
1318
|
}
|
|
1186
1319
|
|
|
@@ -1372,6 +1505,27 @@
|
|
|
1372
1505
|
}
|
|
1373
1506
|
|
|
1374
1507
|
const reviewSearchKeys = ['title', 'sourceLocation']
|
|
1508
|
+
const overviewSearchKeys = [
|
|
1509
|
+
'title',
|
|
1510
|
+
'sourceLocation',
|
|
1511
|
+
'sourceFileName',
|
|
1512
|
+
'fileName',
|
|
1513
|
+
'supplierName',
|
|
1514
|
+
'supplierCreditCode',
|
|
1515
|
+
'productName',
|
|
1516
|
+
'model',
|
|
1517
|
+
'description',
|
|
1518
|
+
'hsCode',
|
|
1519
|
+
'contractHsCode',
|
|
1520
|
+
'enrichedHsCode',
|
|
1521
|
+
'englishName',
|
|
1522
|
+
'invoiceNo',
|
|
1523
|
+
'contractNo',
|
|
1524
|
+
'buyerName',
|
|
1525
|
+
'sellerName',
|
|
1526
|
+
'controlNote',
|
|
1527
|
+
'keywords'
|
|
1528
|
+
]
|
|
1375
1529
|
const controlledGoodsFormFields = [
|
|
1376
1530
|
{ key: 'productName', label: '商品名称', placeholder: '例如:高性能服务器' },
|
|
1377
1531
|
{ key: 'hsCode', label: '海关编码', placeholder: '例如:8471501010' },
|
|
@@ -1977,8 +2131,74 @@ button, input, textarea, select { font: inherit; letter-spacing: 0; }
|
|
|
1977
2131
|
.tcw-error { border: 1px solid color-mix(in srgb, var(--tcw-danger) 35%, var(--tcw-border)); border-radius: 8px; background: color-mix(in srgb, var(--tcw-danger) 6%, var(--tcw-card)); color: var(--tcw-danger); padding: 10px 12px; font-size: 13px; font-weight: 800; }
|
|
1978
2132
|
.row-selection-checkbox { width: 16px; height: 16px; }
|
|
1979
2133
|
.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; }
|
|
1980
|
-
.tcw-pagination {
|
|
2134
|
+
.tcw-pagination {
|
|
2135
|
+
display: flex;
|
|
2136
|
+
flex-wrap: wrap;
|
|
2137
|
+
align-items: center;
|
|
2138
|
+
gap: 6px;
|
|
2139
|
+
border: 1px solid var(--tcw-border);
|
|
2140
|
+
border-radius: 8px;
|
|
2141
|
+
background: var(--tcw-card);
|
|
2142
|
+
padding: 8px 10px;
|
|
2143
|
+
color: var(--tcw-muted);
|
|
2144
|
+
font-size: 12px;
|
|
2145
|
+
}
|
|
2146
|
+
.tcw-pagination-unified { justify-content: flex-start; }
|
|
1981
2147
|
.tcw-page-buttons { display: flex; gap: 8px; }
|
|
2148
|
+
.tcw-pagination-total {
|
|
2149
|
+
display: inline-flex;
|
|
2150
|
+
align-items: center;
|
|
2151
|
+
min-height: 28px;
|
|
2152
|
+
color: var(--tcw-primary);
|
|
2153
|
+
}
|
|
2154
|
+
.tcw-page-btn {
|
|
2155
|
+
display: inline-flex;
|
|
2156
|
+
align-items: center;
|
|
2157
|
+
justify-content: center;
|
|
2158
|
+
min-width: 48px;
|
|
2159
|
+
min-height: 28px;
|
|
2160
|
+
border: 1px solid var(--tcw-border);
|
|
2161
|
+
border-radius: 6px;
|
|
2162
|
+
background: #fff;
|
|
2163
|
+
color: var(--tcw-primary);
|
|
2164
|
+
padding: 4px 9px;
|
|
2165
|
+
cursor: pointer;
|
|
2166
|
+
font-size: 12px;
|
|
2167
|
+
font-weight: 700;
|
|
2168
|
+
}
|
|
2169
|
+
.tcw-page-btn:disabled {
|
|
2170
|
+
cursor: not-allowed;
|
|
2171
|
+
background: var(--tcw-soft);
|
|
2172
|
+
color: #9aa7b8;
|
|
2173
|
+
}
|
|
2174
|
+
.tcw-page-current {
|
|
2175
|
+
display: inline-flex;
|
|
2176
|
+
align-items: center;
|
|
2177
|
+
min-height: 28px;
|
|
2178
|
+
border-radius: 6px;
|
|
2179
|
+
background: var(--tcw-primary);
|
|
2180
|
+
color: #fff;
|
|
2181
|
+
padding: 4px 12px;
|
|
2182
|
+
font-weight: 800;
|
|
2183
|
+
}
|
|
2184
|
+
.tcw-page-size-label {
|
|
2185
|
+
color: var(--tcw-primary);
|
|
2186
|
+
font-weight: 800;
|
|
2187
|
+
}
|
|
2188
|
+
.tcw-page-size-select,
|
|
2189
|
+
.tcw-page-jump-input,
|
|
2190
|
+
.tcw-page-size-fixed {
|
|
2191
|
+
min-height: 28px;
|
|
2192
|
+
border: 1px solid var(--tcw-border);
|
|
2193
|
+
border-radius: 6px;
|
|
2194
|
+
background: #fff;
|
|
2195
|
+
color: var(--tcw-text);
|
|
2196
|
+
padding: 4px 8px;
|
|
2197
|
+
font-size: 12px;
|
|
2198
|
+
}
|
|
2199
|
+
.tcw-page-size-select { min-width: 92px; }
|
|
2200
|
+
.tcw-page-size-fixed { display: inline-flex; align-items: center; }
|
|
2201
|
+
.tcw-page-jump-input { width: 56px; }
|
|
1982
2202
|
.tcw-modal-backdrop { position: fixed; inset: 0; z-index: 10; display: grid; place-items: center; background: rgba(15, 23, 42, .32); padding: 20px; }
|
|
1983
2203
|
.tcw-modal { display: grid; gap: 12px; width: min(900px, 100%); max-height: calc(100vh - 48px); overflow: auto; border: 1px solid var(--tcw-border); border-radius: 8px; background: var(--tcw-card); padding: 16px; box-shadow: 0 18px 48px rgba(15, 23, 42, .18); }
|
|
1984
2204
|
.tcw-form-modal { width: min(960px, 100%); }
|
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.50",
|
|
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",
|