优化
This commit is contained in:
@@ -100,6 +100,7 @@ function measurement(overrides: Partial<InboundMeasurementDetail> = {}): Inbound
|
||||
async function mountPanel(permissions = [
|
||||
'platform:firstleg:inbound:measure:view',
|
||||
'platform:firstleg:inbound:measure:edit',
|
||||
'platform:firstleg:inbound:measure:manual-entry',
|
||||
'platform:firstleg:inbound:measure:submit',
|
||||
]) {
|
||||
const pinia = createPinia()
|
||||
@@ -170,6 +171,16 @@ describe('InboundMeasurementPanel', () => {
|
||||
expect(document.body.textContent).toContain('保存箱规')
|
||||
})
|
||||
|
||||
it('does not expose manual carton entry without its dedicated permission', async () => {
|
||||
const wrapper = await mountPanel([
|
||||
'platform:firstleg:inbound:measure:view',
|
||||
'platform:firstleg:inbound:measure:edit',
|
||||
'platform:firstleg:inbound:measure:submit',
|
||||
])
|
||||
|
||||
expect(wrapper.text()).not.toContain('手动录入箱规')
|
||||
})
|
||||
|
||||
it('does not expose unknown measurement source codes', async () => {
|
||||
vi.mocked(getInboundMeasurement).mockResolvedValueOnce(measurement({ sourceType: 'LEGACY_DEVICE' }))
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ const manualForm = reactive<ManualCartonFormModel>({
|
||||
|
||||
const canView = computed(() => access.can('platform:firstleg:inbound:measure:view'))
|
||||
const canEdit = computed(() => access.can('platform:firstleg:inbound:measure:edit'))
|
||||
const canManualEntry = computed(() => access.can('platform:firstleg:inbound:measure:manual-entry'))
|
||||
const canSubmit = computed(() => access.can('platform:firstleg:inbound:measure:submit'))
|
||||
const customerId = computed(() => props.customerId || props.tenantId || '')
|
||||
const hasContext = computed(() => Boolean(customerId.value && props.inboundId))
|
||||
@@ -104,7 +105,7 @@ const countEditableProcess = computed(() => ['WAIT_MEASURE', 'MEASURING', 'MEASU
|
||||
const submitEditableProcess = computed(() => ['WAIT_MEASURE', 'MEASURING', 'MEASURE_REJECTED'].includes(detail.value?.processStatus || ''))
|
||||
const mayMaintain = computed(() => canEdit.value && countEditableProcess.value && !loading.value && !submitting.value)
|
||||
const manualEntryEditableProcess = computed(() => ['WAIT_MEASURE', 'MEASURING', 'MEASURE_REJECTED'].includes(detail.value?.processStatus || ''))
|
||||
const mayCreateManualEntry = computed(() => canEdit.value && manualEntryEditableProcess.value && !loading.value && !saving.value && !submitting.value && !isDirty.value)
|
||||
const mayCreateManualEntry = computed(() => canManualEntry.value && manualEntryEditableProcess.value && !loading.value && !saving.value && !submitting.value && !isDirty.value)
|
||||
const confirmedPackageCount = computed(() => form.items.reduce((sum, item) => sum + (Number.isFinite(item.packageCount) ? item.packageCount : 0), 0))
|
||||
const expectedPackageCount = computed(() => detail.value?.originalPackageCount ?? null)
|
||||
const packageCountDifference = computed(() => expectedPackageCount.value == null ? null : confirmedPackageCount.value - expectedPackageCount.value)
|
||||
@@ -556,7 +557,7 @@ onBeforeUnmount(releaseImagePreview)
|
||||
<section class="measurement-section measurement-items-section">
|
||||
<div class="measurement-section__heading">
|
||||
<div><h3>扫描箱测量数据明细</h3><p>每条记录对应一个实际扫描箱;人工只确认该条记录代表的箱数,设备实测值不可在此修改。</p></div>
|
||||
<el-button v-if="canEdit" type="primary" plain :disabled="!mayCreateManualEntry" @click="openManualEntry"><Plus :size="15" />手动录入箱规</el-button>
|
||||
<el-button v-if="canManualEntry" type="primary" plain :disabled="!mayCreateManualEntry" @click="openManualEntry"><Plus :size="15" />手动录入箱规</el-button>
|
||||
</div>
|
||||
|
||||
<el-empty v-if="!form.items.length" description="暂无扫描箱测量数据" />
|
||||
|
||||
@@ -112,7 +112,7 @@ describe('inbound measurement API', () => {
|
||||
machineNo: 'MANUAL-ADMIN', measuredAt: '2026-08-12T14:00:00', scannedShipmentId: null,
|
||||
}, image)).resolves.toEqual(result)
|
||||
const [path, body, config] = vi.mocked(http.post).mock.calls[0]!
|
||||
expect(path).toBe('/platform/v1/first-leg/inbounds/7001/measurement/carton-scans')
|
||||
expect(path).toBe('/platform/v1/first-leg/inbounds/7001/measurement/manual-cartons')
|
||||
expect(body).toBeInstanceOf(FormData)
|
||||
expect((body as FormData).get('image')).toBe(image)
|
||||
expect(config).toEqual({ params: { tenantId: '10001' }, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
|
||||
@@ -78,7 +78,7 @@ export async function createManualCartonScan(
|
||||
data.append('data', new Blob([JSON.stringify(payload)], { type: 'application/json' }))
|
||||
data.append('image', image)
|
||||
const response = await http.post<ApiEnvelope<CartonMeasurementResult>, ApiEnvelope<CartonMeasurementResult>>(
|
||||
`${measurementPath(inboundId)}/carton-scans`,
|
||||
`${measurementPath(inboundId)}/manual-cartons`,
|
||||
data,
|
||||
{ params: { tenantId: customerId }, headers: { 'Content-Type': 'multipart/form-data' } },
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user