优化
This commit is contained in:
@@ -170,7 +170,7 @@
|
|||||||
<text class="remote-error" role="alert">{{ remoteError }}</text>
|
<text class="remote-error" role="alert">{{ remoteError }}</text>
|
||||||
<button class="evidence-retry-btn" :disabled="remoteLoading" @tap="refreshTask">刷新任务</button>
|
<button class="evidence-retry-btn" :disabled="remoteLoading" @tap="refreshTask">刷新任务</button>
|
||||||
</view>
|
</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 }}
|
{{ submitting ? '正在提交…' : submitButtonText }}
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@@ -421,7 +421,8 @@
|
|||||||
return this.boxes.length - this.completedCount
|
return this.boxes.length - this.completedCount
|
||||||
},
|
},
|
||||||
pickingCompleted() {
|
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))
|
const hasServerPending = this.currentBox.items.some((item) => ['PENDING', 'PICKING'].includes(item.itemStatus))
|
||||||
return isPickingCompleteTask(this.remotePick) && !hasServerPending
|
return isPickingCompleteTask(this.remotePick) && !hasServerPending
|
||||||
}
|
}
|
||||||
@@ -469,10 +470,10 @@
|
|||||||
return ''
|
return ''
|
||||||
},
|
},
|
||||||
submitButtonText() {
|
submitButtonText() {
|
||||||
return this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted ? '该柜次已完成' : this.summary.buttonText
|
return this.pickingCompleted ? '该柜次已完成' : this.summary.buttonText
|
||||||
},
|
},
|
||||||
submitStatusHint() {
|
submitStatusHint() {
|
||||||
if (this.completedBoxes[this.currentBoxIndex] || this.pickingCompleted) return '本柜次任务已完成'
|
if (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}`
|
||||||
@@ -503,6 +504,9 @@
|
|||||||
onLoad(options = {}) {
|
onLoad(options = {}) {
|
||||||
if (!requireSession()) return
|
if (!requireSession()) return
|
||||||
if (options.taskId) {
|
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 = [{
|
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 || ''),
|
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,
|
taskId: String(options.taskId), loadingPlanId: null, containerBookingId: null,
|
||||||
@@ -1305,7 +1309,7 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!this.isEvidenceContextActive(contextId, identity)) return
|
if (!this.isEvidenceContextActive(contextId, identity)) return
|
||||||
if (this.isTaskConflict(error)) {
|
if (this.isTaskConflict(error)) {
|
||||||
await this.refreshAfterTaskConflict(error.message || '装柜前置条件已变化,请刷新后重试')
|
await this.refreshAfterTaskConflict(error.message || '订舱、装柜关联或证据状态已变化,请刷新后重试')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.remoteError = error.network ? '网络失败,装柜完成未提交' : (error.message || '装柜完成失败')
|
this.remoteError = error.network ? '网络失败,装柜完成未提交' : (error.message || '装柜完成失败')
|
||||||
@@ -1434,7 +1438,7 @@
|
|||||||
},
|
},
|
||||||
submitPicking() {
|
submitPicking() {
|
||||||
if (!this.requirePickingOperation()) return
|
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) {
|
if (this.summary.pending > 0) {
|
||||||
this.selectedIncompleteReason = ''
|
this.selectedIncompleteReason = ''
|
||||||
this.openOverlay('submitConfirm')
|
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, /createEvidenceUploadQueue/)
|
||||||
assert.match(page, /retryEvidence/)
|
assert.match(page, /retryEvidence/)
|
||||||
assert.match(page, /uploadEvidenceFile/)
|
assert.match(page, /uploadEvidenceFile/)
|
||||||
assert.match(page, /submitting \|\| completedBoxes\[currentBoxIndex\]/)
|
assert.match(page, /submitting \|\| pickingCompleted \|\| !summary\.canSubmit/)
|
||||||
assert.match(page, /completePicking\(/)
|
assert.match(page, /completePicking\(/)
|
||||||
assert.match(page, /sourceType: \['camera'\]/)
|
assert.match(page, /sourceType: \['camera'\]/)
|
||||||
assert.doesNotMatch(page, /sourceType: \['camera', 'album'\]/)
|
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, /availablePickQuantity/)
|
||||||
assert.match(page, /库存\/库位可用量不足/)
|
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', () => {
|
test('picking and photo workspaces are independently selectable', () => {
|
||||||
assert.match(page, /v-if="activeStage === 'evidence' && loadingStageReady" class="loading-evidence-section"/)
|
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, /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, /请先处理并提交全部待拣明细/)
|
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', () => {
|
test('loading evidence is not requested before picking completion', () => {
|
||||||
assert.match(page, /if \(this\.loadingStageReady\) await this\.loadLoadingEvidence\(\)/)
|
assert.match(page, /if \(this\.loadingStageReady\) await this\.loadLoadingEvidence\(\)/)
|
||||||
const loader = page.match(/async loadLoadingEvidence\(\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
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', () => {
|
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] || ''
|
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] || ''
|
const save = page.match(/async saveEvidence\([^)]*\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
||||||
assert.match(save, /this\.isTaskConflict\(error\)[\s\S]*?refreshAfterTaskConflict/)
|
assert.match(save, /this\.isTaskConflict\(error\)[\s\S]*?refreshAfterTaskConflict/)
|
||||||
const flush = page.match(/async flushPendingEvidence\(\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
const flush = page.match(/async flushPendingEvidence\(\) \{[\s\S]*?\n\t\t\t\},/)?.[0] || ''
|
||||||
|
|||||||
Reference in New Issue
Block a user