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

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,7 @@
74
74
  const [query, setQuery] = React.useState('')
75
75
  const [showManualForm, setShowManualForm] = React.useState(false)
76
76
  const [form, setForm] = React.useState({ productName: '', hsCode: '', keywords: '', controlNote: '', enabled: true })
77
+ const pollingRef = React.useRef(null)
77
78
 
78
79
  React.useEffect(() => {
79
80
  window.__tradeComplianceSetContext = (nextContext) => {
@@ -86,6 +87,7 @@
86
87
  return () => {
87
88
  window.__tradeComplianceSetContext = null
88
89
  window.__tradeComplianceHostEvent = null
90
+ stopRecognitionPolling()
89
91
  }
90
92
  }, [])
91
93
 
@@ -123,6 +125,8 @@
123
125
 
124
126
  async function handleFile(actionKey, file) {
125
127
  if (!file || busy) return
128
+ const expectedType = reviewTypeForUploadAction(actionKey)
129
+ const previousCount = countReviewItemsByType(data.reviewItems, expectedType)
126
130
  setBusy(true)
127
131
  try {
128
132
  const response = await executeFileAction(actionKey, file, { name: file.name, fileName: file.name }, {})
@@ -130,6 +134,7 @@
130
134
  const dispatched = await dispatchAssistantCommands(getActionDataPayload(response))
131
135
  showNotice(dispatched ? '文件已发送给智能体解析,识别结果会进入待审核列表。' : '文件已登记,等待识别结果。', 'success')
132
136
  await reload()
137
+ if (dispatched && expectedType) startRecognitionPolling(expectedType, previousCount)
133
138
  } catch (error) {
134
139
  showNotice(getErrorMessage(error), 'error')
135
140
  } finally {
@@ -239,6 +244,30 @@
239
244
  setTimeout(() => setNotice(''), 4500)
240
245
  }
241
246
 
247
+ function startRecognitionPolling(expectedType, previousCount) {
248
+ stopRecognitionPolling()
249
+ let attempts = 0
250
+ pollingRef.current = setInterval(async () => {
251
+ attempts += 1
252
+ try {
253
+ const response = await request('requestData', { query: { page: 1, pageSize: 200, search: query, parameters: {} } })
254
+ const nextData = normalizeData(getResponsePayload(response))
255
+ setData(nextData)
256
+ if (countReviewItemsByType(nextData.reviewItems, expectedType) > previousCount || attempts >= 36) {
257
+ stopRecognitionPolling()
258
+ }
259
+ } catch (_error) {
260
+ if (attempts >= 36) stopRecognitionPolling()
261
+ }
262
+ }, 2500)
263
+ }
264
+
265
+ function stopRecognitionPolling() {
266
+ if (!pollingRef.current) return
267
+ clearInterval(pollingRef.current)
268
+ pollingRef.current = null
269
+ }
270
+
242
271
  return h('div', { className: 'tcw-shell' },
243
272
  h('header', { className: 'tcw-header' },
244
273
  h('div', { className: 'tcw-title-block' },
@@ -626,6 +655,18 @@
626
655
  return items.filter((item) => (item.reviewStatus || 'pending') === statusFilter)
627
656
  }
628
657
 
658
+ function reviewTypeForUploadAction(actionKey) {
659
+ if (actionKey === 'upload_controlled_goods_file') return 'controlled_goods'
660
+ if (actionKey === 'upload_supplier_contract') return 'supplier_product'
661
+ if (actionKey === 'upload_sales_contract') return 'customs_workbook'
662
+ return null
663
+ }
664
+
665
+ function countReviewItemsByType(items, type) {
666
+ if (!type || !Array.isArray(items)) return 0
667
+ return items.filter((item) => item.type === type && !isPlaceholderReviewItem(item)).length
668
+ }
669
+
629
670
  function isPlaceholderReviewItem(item) {
630
671
  const merged = readMerged(item || {})
631
672
  if (!item || !item.type) return true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chenchaolong/plugin-trade-compliance-workbench",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
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",