优化
This commit is contained in:
@@ -170,7 +170,7 @@
|
||||
<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">
|
||||
<button class="submit-btn" aria-label="提交拣货完成" :disabled="submitting || pickingCompleted || !summary.canSubmit" @tap="submitPicking">
|
||||
{{ submitting ? '正在提交…' : submitButtonText }}
|
||||
</button>
|
||||
</view>
|
||||
@@ -421,7 +421,8 @@
|
||||
return this.boxes.length - this.completedCount
|
||||
},
|
||||
pickingCompleted() {
|
||||
if (this.remotePick) {
|
||||
if (this.remoteTaskId || this.currentBox.taskId) {
|
||||
if (!this.remotePick) return false
|
||||
const hasServerPending = this.currentBox.items.some((item) => ['PENDING', 'PICKING'].includes(item.itemStatus))
|
||||
return isPickingCompleteTask(this.remotePick) && !hasServerPending
|
||||
}
|
||||
@@ -469,10 +470,10 @@
|
||||
return ''
|
||||
},
|
||||
submitButtonText() {
|
||||
return this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted ? '该柜次已完成' : this.summary.buttonText
|
||||
return this.pickingCompleted ? '该柜次已完成' : this.summary.buttonText
|
||||
},
|
||||
submitStatusHint() {
|
||||
if (this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted) return '本柜次任务已完成'
|
||||
if (this.pickingCompleted) return '本柜次任务已完成'
|
||||
if (!this.summary.canSubmit) return '请先处理至少一件'
|
||||
if (this.summary.pending > 0) return '提交时需选择原因'
|
||||
return `已处理 ${this.summary.processed}/${this.summary.total}`
|
||||
@@ -503,6 +504,9 @@
|
||||
onLoad(options = {}) {
|
||||
if (!requireSession()) return
|
||||
if (options.taskId) {
|
||||
// A local completion marker belongs to the previously opened task. The
|
||||
// canonical server detail decides whether this task is complete.
|
||||
this.completedBoxes = {}
|
||||
this.boxes = [{
|
||||
boxNo: String(options.currentContainerNo || options.cabinetNo || '同步中'), cabinetNo: options.cabinetNo ? String(options.cabinetNo) : null, currentContainerNo: options.currentContainerNo ? String(options.currentContainerNo) : null, orderNo: String(options.orderNo || options.inboundCode || ''),
|
||||
taskId: String(options.taskId), loadingPlanId: null, containerBookingId: null,
|
||||
@@ -1305,7 +1309,7 @@
|
||||
} catch (error) {
|
||||
if (!this.isEvidenceContextActive(contextId, identity)) return
|
||||
if (this.isTaskConflict(error)) {
|
||||
await this.refreshAfterTaskConflict(error.message || '装柜前置条件已变化,请刷新后重试')
|
||||
await this.refreshAfterTaskConflict(error.message || '订舱、装柜关联或证据状态已变化,请刷新后重试')
|
||||
return
|
||||
}
|
||||
this.remoteError = error.network ? '网络失败,装柜完成未提交' : (error.message || '装柜完成失败')
|
||||
@@ -1434,7 +1438,7 @@
|
||||
},
|
||||
submitPicking() {
|
||||
if (!this.requirePickingOperation()) return
|
||||
if (!this.summary.canSubmit || this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted) return
|
||||
if (!this.summary.canSubmit || this.pickingCompleted) return
|
||||
if (this.summary.pending > 0) {
|
||||
this.selectedIncompleteReason = ''
|
||||
this.openOverlay('submitConfirm')
|
||||
|
||||
@@ -62,7 +62,7 @@ test('picking page exposes five evidence slots, retry and remote completion stat
|
||||
assert.match(page, /createEvidenceUploadQueue/)
|
||||
assert.match(page, /retryEvidence/)
|
||||
assert.match(page, /uploadEvidenceFile/)
|
||||
assert.match(page, /submitting \|\| completedBoxes\[currentBoxIndex\]/)
|
||||
assert.match(page, /submitting \|\| pickingCompleted \|\| !summary\.canSubmit/)
|
||||
assert.match(page, /completePicking\(/)
|
||||
assert.match(page, /sourceType: \['camera'\]/)
|
||||
assert.doesNotMatch(page, /sourceType: \['camera', 'album'\]/)
|
||||
@@ -126,3 +126,9 @@ test('PDA cabinet picking adapter claims online and submits one atomic batch', (
|
||||
assert.match(page, /availablePickQuantity/)
|
||||
assert.match(page, /库存\/库位可用量不足/)
|
||||
})
|
||||
|
||||
test('PDA final completion delegates automatic cabinet side effects to the task complete endpoint', () => {
|
||||
const complete = source.match(/export function completeContainerPickingTask\(taskId, payload = \{\}\) \{[\s\S]*?\n\}/)?.[0] || ''
|
||||
assert.match(complete, /\/first-leg\/pda-loading\/tasks\/\$\{encodeURIComponent\(taskId\)\}\/complete/)
|
||||
assert.doesNotMatch(complete, /拖车|trucking/i)
|
||||
})
|
||||
|
||||
@@ -7,10 +7,20 @@ const page = await readFile(new URL('../pages/picking/picking.vue', import.meta.
|
||||
test('picking and photo workspaces are independently selectable', () => {
|
||||
assert.match(page, /v-if="activeStage === 'evidence' && loadingStageReady" class="loading-evidence-section"/)
|
||||
assert.match(page, /isPickingCompleteTask\(task\)[\s\S]*?AWAITING_REVIEW[\s\S]*?COMPLETED/)
|
||||
assert.match(page, /pickingCompleted\(\)[\s\S]*?if \(this\.remotePick\)[\s\S]*?hasServerPending[\s\S]*?isPickingCompleteTask\(this\.remotePick\) && !hasServerPending/)
|
||||
assert.match(page, /pickingCompleted\(\)[\s\S]*?this\.remoteTaskId \|\| this\.currentBox\.taskId[\s\S]*?if \(!this\.remotePick\) return false[\s\S]*?hasServerPending[\s\S]*?isPickingCompleteTask\(this\.remotePick\) && !hasServerPending/)
|
||||
assert.match(page, /请先处理并提交全部待拣明细/)
|
||||
})
|
||||
|
||||
test('a server task never inherits a completed marker from the previously opened local cabinet', () => {
|
||||
assert.match(page, /pickingCompleted\(\) \{[\s\S]*?this\.remoteTaskId \|\| this\.currentBox\.taskId[\s\S]*?if \(!this\.remotePick\) return false[\s\S]*?hasServerPending/)
|
||||
assert.match(page, /if \(options\.taskId\) \{[\s\S]*?this\.completedBoxes = \{\}[\s\S]*?this\.boxes = \[/)
|
||||
assert.match(page, /:disabled="submitting \|\| pickingCompleted \|\| !summary\.canSubmit"/)
|
||||
assert.match(page, /submitButtonText\(\)[\s\S]*?return this\.pickingCompleted \? '该柜次已完成'/)
|
||||
assert.match(page, /submitStatusHint\(\)[\s\S]*?if \(this\.pickingCompleted\) return '本柜次任务已完成'/)
|
||||
const submit = page.match(/submitPicking\(\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
||||
assert.doesNotMatch(submit, /completedBoxes/)
|
||||
})
|
||||
|
||||
test('loading evidence is not requested before picking completion', () => {
|
||||
assert.match(page, /if \(this\.loadingStageReady\) await this\.loadLoadingEvidence\(\)/)
|
||||
const loader = page.match(/async loadLoadingEvidence\(\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
||||
@@ -72,7 +82,8 @@ test('incremental batch submits only current server-pending items and refreshes
|
||||
|
||||
test('final completion preserves backend gate errors and refreshes after an atomic A0409', () => {
|
||||
const complete = page.match(/async completeLoadingTask\(\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
||||
assert.match(complete, /this\.isTaskConflict\(error\)[\s\S]*?await this\.refreshAfterTaskConflict\(error\.message \|\| '装柜前置条件已变化,请刷新后重试'\)/)
|
||||
assert.match(complete, /this\.isTaskConflict\(error\)[\s\S]*?await this\.refreshAfterTaskConflict\(error\.message \|\| '订舱、装柜关联或证据状态已变化,请刷新后重试'\)/)
|
||||
assert.doesNotMatch(complete, /拖车|trucking/i)
|
||||
const save = page.match(/async saveEvidence\([^)]*\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
||||
assert.match(save, /this\.isTaskConflict\(error\)[\s\S]*?refreshAfterTaskConflict/)
|
||||
const flush = page.match(/async flushPendingEvidence\(\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
||||
|
||||
Reference in New Issue
Block a user