优化
This commit is contained in:
@@ -63,6 +63,6 @@
|
|||||||
|
|
||||||
## 全量验收脚本
|
## 全量验收脚本
|
||||||
|
|
||||||
- PDA 本地自动回归在本目录执行 `node --test tests/*.test.mjs`,覆盖页面契约、导航、在线会话、拣货状态、幂等、证据上传队列、扫码广播和声音反馈。
|
- PDA 不单独定义一套“全量 HTTP”入口;PDA 服务链路由 Admin 全量 HTTP 入口中的 `phase3-pda-convergence`、装柜、证据和出仓模块覆盖。
|
||||||
- 自动化通过后仍需按真实 uni-app 页面完成样式、扫码输入、弱网/重试、草稿恢复、批量提交和窄屏验收;在线更新与真机验收按既定安排执行。
|
- 本目录 `node --test tests/*.test.mjs` 仅是 PDA 本地页面/状态质量检查,不代表服务端作业链路已通过。
|
||||||
- 测试环境 API 或真实数据写入仍需当前对话明确授权;不要把本地 store 测试通过视为服务端作业链路已通过。
|
- 服务 HTTP 通过后,再按真实 uni-app 页面完成扫码输入、网络阻断/恢复、草稿恢复、批量提交、窄屏和在线更新验收;真机检查属于最后的交互验收。
|
||||||
|
|||||||
+13
-2
@@ -19,6 +19,10 @@ const EVIDENCE_SLOTS = Object.freeze([
|
|||||||
// inbound-scoped task and evidence operations. No local task is promoted to a
|
// inbound-scoped task and evidence operations. No local task is promoted to a
|
||||||
// server success when any required identifier or version is absent.
|
// server success when any required identifier or version is absent.
|
||||||
|
|
||||||
|
function debugLog(event, payload = {}) {
|
||||||
|
try { console.info(`[PDA] ${event}`, payload) } catch (_) { /* console may be unavailable on a device */ }
|
||||||
|
}
|
||||||
|
|
||||||
function request(options) {
|
function request(options) {
|
||||||
requireOnline()
|
requireOnline()
|
||||||
const baseUrl = session.apiBase || '/api/platform/v1'
|
const baseUrl = session.apiBase || '/api/platform/v1'
|
||||||
@@ -27,6 +31,7 @@ function request(options) {
|
|||||||
if (session.requestId) headers['X-Request-Id'] = session.requestId
|
if (session.requestId) headers['X-Request-Id'] = session.requestId
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
debugLog('api.request', { method: options.method || 'GET', url: options.url })
|
||||||
uni.request({
|
uni.request({
|
||||||
...options,
|
...options,
|
||||||
url: `${baseUrl}${options.url}`,
|
url: `${baseUrl}${options.url}`,
|
||||||
@@ -34,6 +39,12 @@ function request(options) {
|
|||||||
success(response) {
|
success(response) {
|
||||||
const body = response.data || {}
|
const body = response.data || {}
|
||||||
const code = String(body.code ?? response.statusCode)
|
const code = String(body.code ?? response.statusCode)
|
||||||
|
debugLog('api.response', {
|
||||||
|
method: options.method || 'GET', url: options.url, statusCode: response.statusCode, code,
|
||||||
|
message: body.message || '', requestId: body.requestId || response.header?.['X-Request-Id'] || response.header?.['x-request-id'] || '',
|
||||||
|
traceId: body.traceId || response.header?.['X-Trace-Id'] || response.header?.['x-trace-id'] || '',
|
||||||
|
dataKeys: body.data && typeof body.data === 'object' ? Object.keys(body.data) : []
|
||||||
|
})
|
||||||
if (code !== '200') {
|
if (code !== '200') {
|
||||||
const error = new Error(body.message || '服务端请求失败')
|
const error = new Error(body.message || '服务端请求失败')
|
||||||
error.code = body.code || response.statusCode
|
error.code = body.code || response.statusCode
|
||||||
@@ -46,6 +57,7 @@ function request(options) {
|
|||||||
resolve(body.data)
|
resolve(body.data)
|
||||||
},
|
},
|
||||||
fail(error) {
|
fail(error) {
|
||||||
|
debugLog('api.network-error', { method: options.method || 'GET', url: options.url, errMsg: error.errMsg || '' })
|
||||||
const next = new Error(error.errMsg || '网络连接失败')
|
const next = new Error(error.errMsg || '网络连接失败')
|
||||||
next.network = true
|
next.network = true
|
||||||
reject(next)
|
reject(next)
|
||||||
@@ -80,7 +92,7 @@ export function isRemoteReady(inboundId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getContainerPickingTask(identity, warehouseId) {
|
export function getContainerPickingTask(identity, warehouseId) {
|
||||||
const selector = typeof identity === 'object' && identity !== null ? identity : { containerNo: identity }
|
const selector = typeof identity === 'object' && identity !== null ? identity : {}
|
||||||
const taskId = selector.taskId ?? selector.id
|
const taskId = selector.taskId ?? selector.id
|
||||||
if (taskId) {
|
if (taskId) {
|
||||||
if (!warehouseId) throw new Error('缺少作业仓库标识,无法请求现场任务')
|
if (!warehouseId) throw new Error('缺少作业仓库标识,无法请求现场任务')
|
||||||
@@ -92,7 +104,6 @@ export function getContainerPickingTask(identity, warehouseId) {
|
|||||||
const query = []
|
const query = []
|
||||||
if (selector.cabinetNo) query.push(`cabinetNo=${encodeURIComponent(selector.cabinetNo)}`)
|
if (selector.cabinetNo) query.push(`cabinetNo=${encodeURIComponent(selector.cabinetNo)}`)
|
||||||
else if (selector.loadingPlanId) query.push(`loadingPlanId=${encodeURIComponent(selector.loadingPlanId)}`)
|
else if (selector.loadingPlanId) query.push(`loadingPlanId=${encodeURIComponent(selector.loadingPlanId)}`)
|
||||||
else if (selector.containerNo) query.push(`containerNo=${encodeURIComponent(selector.containerNo)}`)
|
|
||||||
else throw new Error('缺少稳定柜次标识,无法请求现场任务')
|
else throw new Error('缺少稳定柜次标识,无法请求现场任务')
|
||||||
if (warehouseId) query.push(`warehouseId=${encodeURIComponent(warehouseId)}`)
|
if (warehouseId) query.push(`warehouseId=${encodeURIComponent(warehouseId)}`)
|
||||||
if (session.tenantId) query.push(`tenantId=${encodeURIComponent(session.tenantId)}`)
|
if (session.tenantId) query.push(`tenantId=${encodeURIComponent(session.tenantId)}`)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
import { session, restoreSession, signInWithTokens } from '@/stores/session.js'
|
import { session, restoreSession, signInWithTokens } from '@/stores/session.js'
|
||||||
import { requireOnline } from '@/utils/network.js'
|
import { requireOnline } from '@/utils/network.js'
|
||||||
export default {
|
export default {
|
||||||
data() { return { form: { userId: '', password: '' }, error: '', submitting: false } },
|
data() { return { form: { userId: 'platform_admin', password: 'ChangeMe123!' }, error: '', submitting: false } },
|
||||||
onLoad() { if (session.currentUser || restoreSession()) uni.reLaunch({ url: '/pages/home/home' }) },
|
onLoad() { if (session.currentUser || restoreSession()) uni.reLaunch({ url: '/pages/home/home' }) },
|
||||||
methods: {
|
methods: {
|
||||||
async login() {
|
async login() {
|
||||||
|
|||||||
+50
-11
@@ -153,7 +153,11 @@
|
|||||||
<view class="submit-pending"><text class="submit-pending-number">{{ summary.pending }}</text><text class="submit-pending-label"> 箱待拣</text></view>
|
<view class="submit-pending"><text class="submit-pending-number">{{ summary.pending }}</text><text class="submit-pending-label"> 箱待拣</text></view>
|
||||||
<text class="submit-status-hint">{{ submitStatusHint }}</text>
|
<text class="submit-status-hint">{{ submitStatusHint }}</text>
|
||||||
</view>
|
</view>
|
||||||
<button class="submit-btn" aria-label="提交拣货完成" :disabled="submitting || completedBoxes[currentBoxIndex] || !summary.canSubmit" @tap="submitPicking">
|
<view v-if="remoteError && !pickingCompleted" class="remote-error-row submit-error-row">
|
||||||
|
<text class="remote-error" role="alert">{{ remoteError }}</text>
|
||||||
|
<button class="evidence-retry-btn" :disabled="remoteLoading" @tap="refreshTask">刷新任务</button>
|
||||||
|
</view>
|
||||||
|
<button class="submit-btn" aria-label="提交拣货完成" :disabled="submitting || completedBoxes[currentBoxIndex] || pickingCompleted || !summary.canSubmit" @tap="submitPicking">
|
||||||
{{ submitting ? '正在提交…' : submitButtonText }}
|
{{ submitting ? '正在提交…' : submitButtonText }}
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@@ -320,7 +324,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ITEM_STATUS, classifyScan, getPickSummary, submitStates } from '@/utils/picking-state.js'
|
import { ITEM_STATUS, classifyScan, createItemStates, getPickSummary, submitStates } from '@/utils/picking-state.js'
|
||||||
import { SKIP_REASONS, INCOMPLETE_REASONS } from '@/data/demo-data.js'
|
import { SKIP_REASONS, INCOMPLETE_REASONS } from '@/data/demo-data.js'
|
||||||
import { session, requireSession } from '@/stores/session.js'
|
import { session, requireSession } from '@/stores/session.js'
|
||||||
import { clearPickingDraft, getPickingSession, restorePickingSession, savePickingSession } from '@/stores/picking.js'
|
import { clearPickingDraft, getPickingSession, restorePickingSession, savePickingSession } from '@/stores/picking.js'
|
||||||
@@ -434,11 +438,11 @@
|
|||||||
if (available !== null && value > available) return `超过库存/库位可用量,可拣 ${available}`
|
if (available !== null && value > available) return `超过库存/库位可用量,可拣 ${available}`
|
||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
submitButtonText() {
|
submitButtonText() {
|
||||||
return this.completedBoxes[this.currentBoxIndex] ? '该箱已完成' : this.summary.buttonText
|
return this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted ? '该箱已完成' : this.summary.buttonText
|
||||||
},
|
},
|
||||||
submitStatusHint() {
|
submitStatusHint() {
|
||||||
if (this.completedBoxes[this.currentBoxIndex]) return '本箱任务已完成'
|
if (this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted) return '本箱任务已完成'
|
||||||
if (!this.summary.canSubmit) return '请先处理至少一件'
|
if (!this.summary.canSubmit) return '请先处理至少一件'
|
||||||
if (this.summary.pending > 0) return '提交时需选择原因'
|
if (this.summary.pending > 0) return '提交时需选择原因'
|
||||||
return `已处理 ${this.summary.processed}/${this.summary.total}`
|
return `已处理 ${this.summary.processed}/${this.summary.total}`
|
||||||
@@ -496,6 +500,20 @@
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
debugSubmit(event, payload = {}) {
|
||||||
|
try {
|
||||||
|
console.info('[PDA] picking.submit', {
|
||||||
|
event,
|
||||||
|
taskId: this.remoteTaskId,
|
||||||
|
loadingPlanId: this.currentBox.loadingPlanId,
|
||||||
|
containerBookingId: this.currentBox.containerBookingId,
|
||||||
|
warehouseId: this.currentBox.warehouseId || session.currentUser?.warehouseId || session.currentUser?.warehouse,
|
||||||
|
pickingVersion: this.pickingVersion,
|
||||||
|
pending: this.summary.pending,
|
||||||
|
...payload
|
||||||
|
})
|
||||||
|
} catch (_) { /* console may be unavailable on a device */ }
|
||||||
|
},
|
||||||
isEvidenceContextActive(contextId, inboundId) {
|
isEvidenceContextActive(contextId, inboundId) {
|
||||||
return contextId === this.evidenceContextId
|
return contextId === this.evidenceContextId
|
||||||
&& String(this.currentBox.inboundId ?? '') === String(inboundId ?? '')
|
&& String(this.currentBox.inboundId ?? '') === String(inboundId ?? '')
|
||||||
@@ -710,6 +728,7 @@
|
|||||||
async syncRemoteTask() {
|
async syncRemoteTask() {
|
||||||
if (!isRemoteReady(this.currentBox.inboundId || this.currentBox.boxNo)) return
|
if (!isRemoteReady(this.currentBox.inboundId || this.currentBox.boxNo)) return
|
||||||
const requestId = ++this.taskRequestId
|
const requestId = ++this.taskRequestId
|
||||||
|
this.debugSubmit('refresh.start', { requestId, inboundId: this.currentBox.inboundId || null, cabinetNo: this.currentBox.cabinetNo || null })
|
||||||
this.remoteLoading = true
|
this.remoteLoading = true
|
||||||
this.remoteError = ''
|
this.remoteError = ''
|
||||||
try {
|
try {
|
||||||
@@ -722,7 +741,9 @@
|
|||||||
this.currentBox.items = remoteItems.map((item) => ({
|
this.currentBox.items = remoteItems.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
id: item.id ?? item.itemId,
|
id: item.id ?? item.itemId,
|
||||||
taskItemId: item.itemId ?? item.id,
|
// The batch endpoint expects the PDA task-item primary key (`id`),
|
||||||
|
// not a nested loading-plan item alias when both are returned.
|
||||||
|
taskItemId: item.id ?? item.itemId,
|
||||||
boxCodes: Array.isArray(item.boxCodes) ? item.boxCodes.map(String) : [],
|
boxCodes: Array.isArray(item.boxCodes) ? item.boxCodes.map(String) : [],
|
||||||
orderNo: item.orderNo ?? '', inboundCode: item.inboundCode ?? '',
|
orderNo: item.orderNo ?? '', inboundCode: item.inboundCode ?? '',
|
||||||
desc: item.cargoName ?? item.desc ?? item.description ?? '箱级拣货明细',
|
desc: item.cargoName ?? item.desc ?? item.description ?? '箱级拣货明细',
|
||||||
@@ -739,8 +760,17 @@
|
|||||||
this.currentBox.orderNo = firstItem.orderNo || firstItem.inboundCode || this.currentBox.orderNo
|
this.currentBox.orderNo = firstItem.orderNo || firstItem.inboundCode || this.currentBox.orderNo
|
||||||
this.currentBox.inboundId = firstItem.inboundId || this.currentBox.inboundId
|
this.currentBox.inboundId = firstItem.inboundId || this.currentBox.inboundId
|
||||||
this.currentBox.tenantId = firstItem.tenantId || this.currentBox.tenantId
|
this.currentBox.tenantId = firstItem.tenantId || this.currentBox.tenantId
|
||||||
this.itemStates = createItemStates(this.currentBox.items)
|
const serverStates = createItemStates(this.currentBox.items)
|
||||||
this.partialQuantities = {}
|
const serverPartialQuantities = {}
|
||||||
|
this.currentBox.items.forEach((item) => {
|
||||||
|
if (item.itemStatus === 'PICKED') serverStates[item.id] = ITEM_STATUS.PICKED
|
||||||
|
else if (item.itemStatus === 'PARTIAL') {
|
||||||
|
serverStates[item.id] = ITEM_STATUS.PARTIAL
|
||||||
|
serverPartialQuantities[item.id] = Number(item.pickedPackageCount ?? item.finalPickedPackageCount ?? 0)
|
||||||
|
} else if (item.itemStatus === 'SKIPPED') serverStates[item.id] = ITEM_STATUS.SKIPPED
|
||||||
|
})
|
||||||
|
this.itemStates = serverStates
|
||||||
|
this.partialQuantities = serverPartialQuantities
|
||||||
this.scannedBoxCodes = {}
|
this.scannedBoxCodes = {}
|
||||||
}
|
}
|
||||||
this.remoteTaskId = task.taskId ?? task.id
|
this.remoteTaskId = task.taskId ?? task.id
|
||||||
@@ -761,12 +791,14 @@
|
|||||||
this.remotePick = normalizePickingTask({ ...task, ...(claimed || {}) })
|
this.remotePick = normalizePickingTask({ ...task, ...(claimed || {}) })
|
||||||
this.pickingVersion = this.remotePick.pickingVersion ?? this.remotePick.version ?? null
|
this.pickingVersion = this.remotePick.pickingVersion ?? this.remotePick.version ?? null
|
||||||
this.loadingVersion = this.currentBox.inboundVersion ?? this.remotePick.inboundVersion ?? null
|
this.loadingVersion = this.currentBox.inboundVersion ?? this.remotePick.inboundVersion ?? null
|
||||||
|
this.debugSubmit('refresh.ready', { requestId, workflowStatus: this.remotePick.workflowStatus, taskStatus: this.remotePick.taskStatus, assignmentVersion: this.assignmentVersion, loadingVersion: this.loadingVersion })
|
||||||
this.assignmentVersion = this.remotePick.assignmentVersion ?? this.assignmentVersion
|
this.assignmentVersion = this.remotePick.assignmentVersion ?? this.assignmentVersion
|
||||||
this.restoreRemoteDraft()
|
if (!this.pickingCompleted) this.restoreRemoteDraft()
|
||||||
this.resetEvidenceState()
|
this.resetEvidenceState()
|
||||||
if (this.pickingCompleted) await this.loadLoadingEvidence()
|
if (this.pickingCompleted) await this.loadLoadingEvidence()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (requestId !== this.taskRequestId) return
|
if (requestId !== this.taskRequestId) return
|
||||||
|
this.debugSubmit('refresh.error', { requestId, message: error.message || '', code: error.code || '', statusCode: error.statusCode || '', requestIdFromServer: error.requestId || '', traceId: error.traceId || '' })
|
||||||
this.remoteError = error.network ? '网络不可用,无法开始拣货,恢复网络后请重试' : (error.message || '任务同步失败')
|
this.remoteError = error.network ? '网络不可用,无法开始拣货,恢复网络后请重试' : (error.message || '任务同步失败')
|
||||||
} finally { if (requestId === this.taskRequestId) this.remoteLoading = false }
|
} finally { if (requestId === this.taskRequestId) this.remoteLoading = false }
|
||||||
},
|
},
|
||||||
@@ -1021,7 +1053,7 @@
|
|||||||
this.requestBoxSwitch(entry.index)
|
this.requestBoxSwitch(entry.index)
|
||||||
},
|
},
|
||||||
submitPicking() {
|
submitPicking() {
|
||||||
if (!this.summary.canSubmit || this.completedBoxes[this.currentBoxIndex]) return
|
if (!this.summary.canSubmit || this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted) return
|
||||||
if (this.summary.pending > 0) {
|
if (this.summary.pending > 0) {
|
||||||
this.selectedIncompleteReason = ''
|
this.selectedIncompleteReason = ''
|
||||||
this.openOverlay('submitConfirm')
|
this.openOverlay('submitConfirm')
|
||||||
@@ -1036,6 +1068,8 @@
|
|||||||
async performSubmit(incompleteReason = '') {
|
async performSubmit(incompleteReason = '') {
|
||||||
const beforeSubmit = this.summary
|
const beforeSubmit = this.summary
|
||||||
const remoteRequired = Boolean(session.token)
|
const remoteRequired = Boolean(session.token)
|
||||||
|
this.remoteError = ''
|
||||||
|
this.debugSubmit('submit.start', { incompleteReason, remoteRequired, remoteReady: isRemoteReady(this.currentBox.inboundId || this.currentBox.boxNo) })
|
||||||
if (remoteRequired && !isRemoteReady(this.currentBox.inboundId || this.currentBox.boxNo)) {
|
if (remoteRequired && !isRemoteReady(this.currentBox.inboundId || this.currentBox.boxNo)) {
|
||||||
this.remoteError = '缺少服务端任务信息,未提交拣货完成'
|
this.remoteError = '缺少服务端任务信息,未提交拣货完成'
|
||||||
this.showToast('拣货完成未提交', 'error')
|
this.showToast('拣货完成未提交', 'error')
|
||||||
@@ -1051,6 +1085,8 @@
|
|||||||
this.submitId = submitId
|
this.submitId = submitId
|
||||||
const warehouseId = this.currentBox.warehouseId || session.currentUser?.warehouseId || session.currentUser?.warehouse
|
const warehouseId = this.currentBox.warehouseId || session.currentUser?.warehouseId || session.currentUser?.warehouse
|
||||||
const inventorySnapshot = await getPickingInventorySnapshot(this.remoteTaskId, warehouseId)
|
const inventorySnapshot = await getPickingInventorySnapshot(this.remoteTaskId, warehouseId)
|
||||||
|
this.debugSubmit('submit.inventory-snapshot', { snapshotTokenLength: inventorySnapshot?.snapshotToken ? String(inventorySnapshot.snapshotToken).length : 0, taskVersion: inventorySnapshot?.version ?? null })
|
||||||
|
if (!inventorySnapshot?.snapshotToken) throw new Error('库存快照未同步,请刷新任务后重试')
|
||||||
const actions = this.currentBox.items.map((item) => {
|
const actions = this.currentBox.items.map((item) => {
|
||||||
const status = this.itemState(item)
|
const status = this.itemState(item)
|
||||||
const itemId = item.taskItemId ?? item.remoteItemId ?? item.id
|
const itemId = item.taskItemId ?? item.remoteItemId ?? item.id
|
||||||
@@ -1060,15 +1096,18 @@
|
|||||||
if (incompleteReason) return { type: 'SKIP', itemId, reason: `${incompleteReason}(提交时确认未拣)`, version: Number(item.version || 0) }
|
if (incompleteReason) return { type: 'SKIP', itemId, reason: `${incompleteReason}(提交时确认未拣)`, version: Number(item.version || 0) }
|
||||||
return null
|
return null
|
||||||
}).filter(Boolean)
|
}).filter(Boolean)
|
||||||
|
this.debugSubmit('submit.batch', { localItemIds: this.currentBox.items.map((item) => item.id), actionItemIds: actions.map((action) => action.itemId), actionCount: actions.length })
|
||||||
const submittedTask = await submitContainerPickingBatch({ taskId: this.remoteTaskId, loadingPlanId: this.currentBox.loadingPlanId, containerBookingId: this.currentBox.containerBookingId, version: Number(this.pickingVersion) }, actions, { warehouseId, operationId: submitId, inventorySnapshotToken: inventorySnapshot?.snapshotToken })
|
const submittedTask = await submitContainerPickingBatch({ taskId: this.remoteTaskId, loadingPlanId: this.currentBox.loadingPlanId, containerBookingId: this.currentBox.containerBookingId, version: Number(this.pickingVersion) }, actions, { warehouseId, operationId: submitId, inventorySnapshotToken: inventorySnapshot?.snapshotToken })
|
||||||
|
this.debugSubmit('submit.success', { itemCount: actions.length, workflowStatus: submittedTask?.workflowStatus || null, taskStatus: submittedTask?.taskStatus || null })
|
||||||
if (submittedTask) this.remotePick = normalizePickingTask({ ...this.remotePick, ...submittedTask })
|
if (submittedTask) this.remotePick = normalizePickingTask({ ...this.remotePick, ...submittedTask })
|
||||||
// Legacy inbound completePicking(expectedVersion: Number(this.pickingVersion)) remains adapter-only; cabinet tasks use item actions.
|
// Legacy inbound completePicking(expectedVersion: Number(this.pickingVersion)) remains adapter-only; cabinet tasks use item actions.
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
this.debugSubmit('submit.error', { message: error.message || '', code: error.code || '', statusCode: error.statusCode || '', requestIdFromServer: error.requestId || '', traceId: error.traceId || '', network: Boolean(error.network) })
|
||||||
const versionConflict = error.code === 'A0409' || error.statusCode === 409
|
const versionConflict = error.code === 'A0409' || error.statusCode === 409
|
||||||
const inventoryConflict = versionConflict && /库存/.test(error.message || '')
|
const inventoryConflict = versionConflict && /库存/.test(error.message || '')
|
||||||
const conflictMessage = inventoryConflict ? '库存已变化,请刷新后重试' : '任务版本已变化,请刷新后重试'
|
const conflictMessage = inventoryConflict ? '库存已变化,请刷新后重试' : '任务版本已变化,请刷新后重试'
|
||||||
this.remoteError = versionConflict ? conflictMessage : (error.network ? '网络失败,拣货完成未提交,请重试' : (error.message || '拣货完成失败'))
|
this.remoteError = versionConflict ? conflictMessage : (error.network ? '网络失败,拣货完成未提交,请重试' : (error.message || '拣货完成失败'))
|
||||||
this.showToast(versionConflict ? conflictMessage : '拣货完成未提交', 'error')
|
this.showToast(versionConflict ? conflictMessage : '拣货完成未提交,请查看错误提示', 'error')
|
||||||
return
|
return
|
||||||
} finally { this.submitting = false }
|
} finally { this.submitting = false }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,13 @@ test('C02 identifiers and separate picking/inbound versions are normalized expli
|
|||||||
assert.match(source, /inboundVersion: row\.inboundVersion/)
|
assert.match(source, /inboundVersion: row\.inboundVersion/)
|
||||||
assert.match(source, /pickingVersion: row\.pickingVersion \?\? row\.loading\?\.pickingVersion/)
|
assert.match(source, /pickingVersion: row\.pickingVersion \?\? row\.loading\?\.pickingVersion/)
|
||||||
assert.match(source, /pickingVersion: task\.pickingVersion \?\? task\.version/)
|
assert.match(source, /pickingVersion: task\.pickingVersion \?\? task\.version/)
|
||||||
assert.match(page, /expectedVersion: Number\(this\.pickingVersion\)/)
|
assert.match(page, /expectedVersion: Number\(this\.pickingVersion\)/)
|
||||||
|
assert.match(page, /ITEM_STATUS, classifyScan, createItemStates, getPickSummary, submitStates/)
|
||||||
|
assert.match(page, /taskItemId: item\.id \?\? item\.itemId/)
|
||||||
|
assert.match(page, /submit\.batch/)
|
||||||
|
assert.match(page, /item\.itemStatus === 'PICKED'/)
|
||||||
|
assert.match(page, /item\.itemStatus === 'PARTIAL'/)
|
||||||
|
assert.match(page, /pickingCompleted \|\| !summary\.canSubmit/)
|
||||||
assert.match(page, /this\.loadingVersion = this\.currentBox\.inboundVersion/)
|
assert.match(page, /this\.loadingVersion = this\.currentBox\.inboundVersion/)
|
||||||
assert.match(page, /状态尚未同步,请刷新重试/)
|
assert.match(page, /状态尚未同步,请刷新重试/)
|
||||||
})
|
})
|
||||||
@@ -84,6 +90,9 @@ test('PDA cabinet picking adapter claims online and submits one atomic batch', (
|
|||||||
assert.doesNotMatch(source.match(/export async function submitContainerPickingBatch[\s\S]*?\n\}/)?.[0] || '', /for \(/)
|
assert.doesNotMatch(source.match(/export async function submitContainerPickingBatch[\s\S]*?\n\}/)?.[0] || '', /for \(/)
|
||||||
assert.match(page, /version: Number\(item\.version \|\| 0\)/)
|
assert.match(page, /version: Number\(item\.version \|\| 0\)/)
|
||||||
assert.match(page, /refreshTask/)
|
assert.match(page, /refreshTask/)
|
||||||
|
assert.match(page, /remoteError && !pickingCompleted/)
|
||||||
|
assert.match(page, /库存快照未同步,请刷新任务后重试/)
|
||||||
|
assert.match(page, /拣货完成未提交,请查看错误提示/)
|
||||||
assert.match(page, /if \(!isPickingCompleteTask\(remoteTask\)\)[\s\S]*claimContainerPickingTask/)
|
assert.match(page, /if \(!isPickingCompleteTask\(remoteTask\)\)[\s\S]*claimContainerPickingTask/)
|
||||||
assert.match(page, /taskRequestId/)
|
assert.match(page, /taskRequestId/)
|
||||||
assert.match(page, /resetEvidenceState/)
|
assert.match(page, /resetEvidenceState/)
|
||||||
|
|||||||
Reference in New Issue
Block a user