This commit is contained in:
2026-08-26 15:59:08 +08:00
parent ee83d87a85
commit 3c283ada46
19 changed files with 196 additions and 46 deletions
@@ -0,0 +1,73 @@
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
const read = (relative) => readFileSync(new URL(relative, import.meta.url), 'utf8')
const page = read('../src/pages/operation/operation.vue')
const adapter = read('../src/api/receiving-adapter.js')
const inbound = read('../src/api/inbound.js')
const controller = read('../../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/controller/ReceivingContainerController.java')
const openapi = read('../../../baiyue-firstleg/lastleg-service/src/main/resources/openapi/overseas-business-v1.yaml')
function photoUiBlockers() {
const values = []
const hasThumbnail = /<image[\s\S]*photoSlots\[index\]/.test(page)
const hasPreview = /uni\.previewImage\(/.test(page)
const hasRestoreDownload = /@GetMapping\([^\n]*unload-photos/.test(controller)
|| /receiving-containers\/current\/unload-photos\/files\/\{fileId\}/.test(openapi)
const hasRestoreClient = /downloadCurrentUnloadPhoto/.test(inbound) && /downloadPath/.test(page)
const developmentLabels = ['真实接口', '待 PDA 接口', 'Mock']
.filter((label) => page.toLowerCase().includes(label.toLowerCase()))
if (!hasThumbnail || !hasPreview) values.push({
code: 'PHOTO_THUMBNAIL_PREVIEW_MISSING', deploymentBlocker: true,
reason: '上传成功后只显示完成图标,尚未渲染缩略图或调用uni.previewImage',
})
if (!hasRestoreDownload) values.push({
code: 'PHOTO_RESTORE_DOWNLOAD_ENDPOINT_MISSING', deploymentBlocker: true,
reason: 'current恢复只返回fileId/role,后端没有签收照片鉴权下载端点,无法恢复后回显',
})
else if (!hasRestoreClient) values.push({
code: 'PHOTO_RESTORE_CLIENT_PENDING', deploymentBlocker: true,
reason: '后端下载契约仍在冻结中,前端尚未接入重载后的鉴权照片回显',
})
if (developmentLabels.length) values.push({
code: 'DEVELOPMENT_LABELS_VISIBLE', deploymentBlocker: true,
reason: `页面仍含开发标识:${developmentLabels.join(',')}`,
})
return values
}
test('three fixed receiving photo roles and string file IDs are frozen', () => {
assert.match(adapter, /RECEIVING_PHOTO_ROLES = \['LICENSE_PLATE', 'CONTAINER_SEAL', 'DOOR_OPEN'\]/)
assert.match(adapter, /fileId: String\(photo\.fileId\)/)
assert.match(page, /fileId: String\(file\.fileId\)/)
assert.match(page, /fileId: String\(item\.fileId\)/)
assert.doesNotMatch(inbound, /customerId|planNo|allocationId|warehouseId|locationId/)
})
test('camera or album replaces only one fixed slot and failed replacement preserves its previous success', () => {
assert.match(page, /choosePhotos\(index, sourceType\)[\s\S]*uni\.chooseImage\(\{ count: 1, sourceType: \[sourceType\]/)
assert.match(page, /choosePhotos\(index, 'camera'\)/)
assert.match(page, /choosePhotos\(index, 'album'\)/)
assert.match(page, /async replacePhoto\(index, path\)[\s\S]*const previous = receiving\.photoSlots\[index\]/)
assert.match(page, /await uploadCurrentUnloadPhoto\(path\)[\s\S]*fileId: String\(file\.fileId\)[\s\S]*localPath: path/)
assert.match(page, /previous\?\.fileId \? \{ \.\.\.previous, status: 'error'/)
assert.match(page, /status: 'uploading'/)
assert.match(page, /status: 'error'/)
assert.match(page, /已保留原图/)
assert.match(page, /photoSlots\[index\]\?\.fileId \? '重拍' : '拍照'/)
assert.match(page, /photoSlots\[index\]\?\.fileId \? '重新选择' : '从相册选择'/)
assert.match(page, /previewPhoto\(index\)/)
assert.match(page, /uploadedPhotoCount\(\) \{ return this\.photoSlots\.filter\(\(item\) => item\?\.fileId\)\.length \}/)
assert.match(page, /photosReady\(\) \{ return this\.uploadedPhotoCount === 3 && !this\.photoSlots\.some/)
assert.match(page, /:disabled="busy \|\| !photosReady" @tap="signContainer"/)
assert.match(page, /async signContainer\(\) \{ if \(!this\.photosReady\) return;/)
assert.match(page, /const photos = this\.photoSlots\.map\(/)
assert.doesNotMatch(page, /count:\s*9|flatMap\(|photoSlots\[index\]\.push/)
})
test('local thumbnail, preview, and authenticated session restore are wired to the frozen contract', () => {
assert.match(page, /restorePhotoPreviews\(\)[\s\S]*photo\?\.downloadPath[\s\S]*downloadCurrentUnloadPhoto\(photo\.downloadPath\)/)
assert.deepEqual(photoUiBlockers().map((item) => item.code), [])
assert.ok(photoUiBlockers().every((item) => item.deploymentBlocker === true && item.reason))
})