优化
This commit is contained in:
@@ -6,6 +6,7 @@ import { firstLegBusinessTypeLabel, firstLegTaxModeLabel } from '@/shared/utils/
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import OperationErrorToast from '@/shared/components/OperationErrorToast.vue'
|
||||
import {
|
||||
ApiResponseError,
|
||||
getApiErrorDetails,
|
||||
@@ -365,6 +366,8 @@ defineExpose({ reload: loadFee })
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<OperationErrorToast :details="adjustmentError" />
|
||||
|
||||
<AppDialog
|
||||
v-model="adjustOpen"
|
||||
title="调整入库费用"
|
||||
@@ -379,11 +382,6 @@ defineExpose({ reload: loadFee })
|
||||
<template #title>费用已被其他操作员更新,系统已刷新最新快照</template>
|
||||
<p>当前输入仍保留,请先核对最新版本后再提交。</p>
|
||||
</el-alert>
|
||||
<el-alert v-if="adjustmentError" class="adjustment-alert" type="error" :closable="false" show-icon role="alert">
|
||||
<template #title>费用调整失败</template>
|
||||
<p>{{ adjustmentError.message }}</p>
|
||||
<ApiErrorMeta :details="adjustmentError" />
|
||||
</el-alert>
|
||||
<el-form ref="adjustFormRef" :model="adjustmentForm" :rules="adjustmentRules" label-position="top" class="adjustment-form" :disabled="adjusting">
|
||||
<div class="adjustment-amounts">
|
||||
<el-form-item label="调整后计费量" prop="chargeableQuantity" required>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import ElementPlus, { ElMessageBox } from 'element-plus'
|
||||
import ElementPlus, { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
||||
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
@@ -275,6 +275,7 @@ describe('InboundMeasurementPanel', () => {
|
||||
})
|
||||
|
||||
it('shows a normal A0409 business reason instead of relabeling it as a version conflict', async () => {
|
||||
const messageSpy = vi.spyOn(ElMessage, 'error')
|
||||
vi.mocked(updateConfirmedPackageCount).mockRejectedValueOnce(
|
||||
new ApiResponseError('该托盘已被占用,请重新选择', 'A0409', 409),
|
||||
)
|
||||
@@ -285,11 +286,31 @@ describe('InboundMeasurementPanel', () => {
|
||||
await save?.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.text()).toContain('该托盘已被占用,请重新选择')
|
||||
expect(wrapper.text()).toContain('操作未完成')
|
||||
expect(messageSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||
message: '该托盘已被占用,请重新选择',
|
||||
showClose: true,
|
||||
duration: 4500,
|
||||
}))
|
||||
expect(wrapper.text()).not.toContain('操作未完成')
|
||||
expect(wrapper.text()).not.toContain('数据版本已变化,当前修改尚未丢失')
|
||||
})
|
||||
|
||||
it('reports draft validation as a dismissible light message without a fixed page alert', async () => {
|
||||
const messageSpy = vi.spyOn(ElMessage, 'warning')
|
||||
vi.mocked(getInboundMeasurement).mockResolvedValueOnce(measurement({ items: [] }))
|
||||
const wrapper = await mountPanel()
|
||||
const save = wrapper.findAll('button').find((button) => button.text().includes('保存测量数据'))
|
||||
await save?.trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
expect(messageSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||
message: '请至少保留一条实际扫描箱测量记录',
|
||||
showClose: true,
|
||||
duration: 4500,
|
||||
}))
|
||||
expect(wrapper.text()).not.toContain('请修正测量草稿中的问题')
|
||||
})
|
||||
|
||||
it('requires the dirty draft to be saved before submitting for review', async () => {
|
||||
const wrapper = await mountPanel()
|
||||
const countInput = wrapper.find('.measurement-count-editor input')
|
||||
|
||||
@@ -200,8 +200,7 @@ async function submitManualEntry() {
|
||||
await loadMeasurement()
|
||||
emit('updated')
|
||||
} catch (error) {
|
||||
const details = setOperationError(error, '手动箱规录入失败,请检查后重试')
|
||||
ElMessage.error(details.message)
|
||||
setOperationError(error, '手动箱规录入失败,请检查后重试')
|
||||
} finally {
|
||||
manualEntrySubmitting.value = false
|
||||
}
|
||||
@@ -311,14 +310,26 @@ function validateDraft() {
|
||||
})
|
||||
if (general.length) errors.general = general
|
||||
validationErrors.value = errors
|
||||
const messages = Object.values(errors).flat()
|
||||
if (messages.length) {
|
||||
ElMessage.warning({
|
||||
message: messages.length === 1 ? messages[0] : `${messages[0]}(另有 ${messages.length - 1} 项)`,
|
||||
showClose: true,
|
||||
duration: 4500,
|
||||
})
|
||||
}
|
||||
return Object.keys(errors).length === 0
|
||||
}
|
||||
|
||||
function setOperationError(error: unknown, fallback: string) {
|
||||
const details = getApiErrorDetails(error, fallback)
|
||||
operationError.value = details
|
||||
conflictDetected.value = details.message.includes('版本已变化')
|
||||
const conflict = details.message.includes('版本已变化')
|
||||
|| details.message.includes('并发修改')
|
||||
conflictDetected.value = conflict
|
||||
operationError.value = conflict ? details : null
|
||||
if (!conflict) {
|
||||
ElMessage.error({ message: details.message, showClose: true, duration: 4500 })
|
||||
}
|
||||
return details
|
||||
}
|
||||
|
||||
@@ -365,8 +376,7 @@ async function saveDraft() {
|
||||
emit('saved')
|
||||
emit('changed')
|
||||
} catch (error) {
|
||||
const details = setOperationError(error, '测量草稿保存失败,请检查后重试')
|
||||
if (!conflictDetected.value) ElMessage.error(details.message)
|
||||
setOperationError(error, '测量草稿保存失败,请检查后重试')
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
@@ -400,8 +410,7 @@ async function submitForReview() {
|
||||
emit('submitted')
|
||||
emit('changed')
|
||||
} catch (error) {
|
||||
const details = setOperationError(error, '测量数据提交失败,请检查图片和称重结果后重试')
|
||||
if (!conflictDetected.value) ElMessage.error(details.message)
|
||||
setOperationError(error, '测量数据提交失败,请检查图片和称重结果后重试')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
@@ -505,18 +514,9 @@ defineExpose({ saveDraft, submitForReview, updateActualGrossWeight, mayMaintain,
|
||||
<ApiErrorMeta v-if="operationError" :details="operationError" />
|
||||
<el-button size="small" @click="reloadLatest">加载最新版本</el-button>
|
||||
</el-alert>
|
||||
<el-alert v-else-if="operationError" type="error" :closable="false" show-icon class="measurement-alert">
|
||||
<template #title>操作未完成</template>
|
||||
<p>{{ operationError.message }}</p>
|
||||
<ApiErrorMeta :details="operationError" />
|
||||
</el-alert>
|
||||
|
||||
<el-alert v-if="Object.keys(validationErrors).length" type="error" :closable="false" show-icon class="measurement-alert">
|
||||
<template #title>请修正测量草稿中的问题</template>
|
||||
<ul>
|
||||
<li v-for="message in Object.values(validationErrors).flat()" :key="message">{{ message }}</li>
|
||||
</ul>
|
||||
</el-alert>
|
||||
<p v-if="Object.keys(validationErrors).length" class="sr-only" role="alert">
|
||||
{{ Object.values(validationErrors).flat().join(';') }}
|
||||
</p>
|
||||
|
||||
<form class="measurement-form" @submit.prevent="saveDraft">
|
||||
<fieldset :disabled="!mayMaintain || saving">
|
||||
|
||||
Reference in New Issue
Block a user