Release/test 合并上生产 #2
@@ -699,6 +699,26 @@ describe('ContainersView', () => {
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it.each([undefined, null, '', '客户一'])('renders optional booking customer %s without leaking a missing value', async (customerName) => {
|
||||
vi.mocked(listOceanBookingLinkCandidates).mockResolvedValueOnce({ records: [{
|
||||
oceanBookingId: '315', bookingNo: 'OB-OPTIONAL-CUSTOMER', requirementId: '45315',
|
||||
containerType: '40HC', remainingQuantity: 1, customerName, warehouseName: '义乌仓', channelName: 'EXX海卡',
|
||||
}], page: 1, size: 200, total: 1, pages: 1 } as never)
|
||||
const router = createTestRouter()
|
||||
await router.push('/'); await router.isReady()
|
||||
const wrapper = mount(ContainersView, { attachTo: document.body, global: { plugins: [ElementPlus, router] } })
|
||||
await flushPromises()
|
||||
await wrapper.find('button[aria-label="更多货柜操作"]').trigger('click')
|
||||
await flushPromises()
|
||||
Array.from(document.body.querySelectorAll<HTMLElement>('.el-dropdown-menu__item'))
|
||||
.filter((item) => item.textContent?.includes('关联已放舱订舱')).at(-1)!.click()
|
||||
await flushPromises()
|
||||
const label = `OB-OPTIONAL-CUSTOMER · 40HC × 1 · ${customerName || '未关联客户'} · 义乌仓 · EXX海卡`
|
||||
expect(document.body.textContent).toContain(label)
|
||||
expect((wrapper.vm as unknown as { linkCandidates: Array<{ label: string }> }).linkCandidates[0]?.label).toBe(label)
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('keeps a three-field match selectable when only capacity snapshots differ and blocks duplicate waves', async () => {
|
||||
let resolveCandidates!: (value: Awaited<ReturnType<typeof listOceanBookingLinkCandidates>>) => void
|
||||
vi.mocked(listContainers).mockResolvedValue({ records: [{
|
||||
|
||||
@@ -526,7 +526,7 @@ async function openLink(source: object) {
|
||||
oceanBookingId: candidate.oceanBookingId,
|
||||
requirementId: candidate.requirementId,
|
||||
disabled: false,
|
||||
label: `${candidate.bookingNo} · ${candidate.containerType} × ${candidate.remainingQuantity} · ${candidate.customerName} · ${candidate.warehouseName} · ${candidate.channelName}`,
|
||||
label: `${candidate.bookingNo} · ${candidate.containerType} × ${candidate.remainingQuantity} · ${candidate.customerName || '未关联客户'} · ${candidate.warehouseName} · ${candidate.channelName}`,
|
||||
}))
|
||||
} catch (error) {
|
||||
if (sequence === linkSequence) linkError.value = getApiErrorDetails(error, '已放舱订舱候选加载失败')
|
||||
|
||||
@@ -183,13 +183,13 @@ onMounted(load)
|
||||
</section>
|
||||
<AppDialog v-model="feeDialogOpen" title="新增费用" width="min(720px, calc(100vw - 28px))" confirm-text="保存费用" :confirm-loading="saving" @confirm="saveFee">
|
||||
<el-form class="fee-form" label-position="top"><div class="fee-form-grid">
|
||||
<el-form-item label="费用项目" required><el-select v-model="feeForm.itemCode" filterable placeholder="请选择费用项目" @change="feeForm.itemName = feeItemOptions.find(item => item.code === feeForm.itemCode)?.name || ''"><el-option v-for="item in feeItemOptions" :key="item.code" :label="item.name" :value="item.code" /></el-select></el-form-item>
|
||||
<el-form-item label="费用项目" required><el-select v-model="feeForm.itemCode" filterable allow-create clearable default-first-option placeholder="请选择或输入费用项目" @change="feeForm.itemName = feeItemOptions.find(item => item.code === feeForm.itemCode)?.name || String(feeForm.itemCode).trim()"><el-option v-for="item in feeItemOptions" :key="item.code" :label="item.name" :value="item.code" /></el-select></el-form-item>
|
||||
<el-form-item label="收付方向" required><el-select v-model="feeForm.direction"><el-option label="应收客户" value="RECEIVABLE" /><el-option label="应付供应商" value="PAYABLE" /></el-select></el-form-item>
|
||||
<el-form-item v-if="feeForm.direction === 'PAYABLE'" label="供应商" required><el-select v-model="feeForm.supplierId" filterable placeholder="请选择供应商"><el-option v-for="item in supplierOptions" :key="String(item.id)" :label="item.name" :value="String(item.id)" /></el-select></el-form-item>
|
||||
<el-form-item label="业务日期" required><el-date-picker v-model="feeForm.businessDate" type="date" value-format="YYYY-MM-DD" /></el-form-item>
|
||||
<el-form-item label="币种" required><el-select v-model="feeForm.currency" placeholder="请选择币种"><el-option label="USD" value="USD" /><el-option label="CNY" value="CNY" /></el-select></el-form-item>
|
||||
<el-form-item label="金额" required><el-input-number v-model="feeForm.amount" :min="0" :precision="2" :step="10" controls-position="right" placeholder="请输入费用金额" /></el-form-item>
|
||||
<el-form-item label="计费数量"><el-input-number v-model="feeForm.quantity" :min="0.0001" :precision="4" controls-position="right" /></el-form-item><el-form-item label="计费单位"><el-input v-model="feeForm.quantityUnit" :disabled="feeForm.quantity == null" placeholder="如 箱、托、天、m³" /></el-form-item>
|
||||
<el-form-item label="计费数量"><el-input-number v-model="feeForm.quantity" :min="0.0001" :precision="4" controls-position="right" placeholder="请输入计费数量" /></el-form-item><el-form-item label="计费单位"><el-input v-model="feeForm.quantityUnit" :disabled="feeForm.quantity == null" placeholder="如 箱、托、天、m³" /></el-form-item>
|
||||
<el-form-item label="计费开始日期"><el-date-picker v-model="feeForm.periodStart" type="date" value-format="YYYY-MM-DD" placeholder="仓租等周期费用填写" /></el-form-item><el-form-item label="计费结束日期"><el-date-picker v-model="feeForm.periodEnd" type="date" value-format="YYYY-MM-DD" placeholder="仓租等周期费用填写" /></el-form-item>
|
||||
</div></el-form>
|
||||
</AppDialog>
|
||||
|
||||
@@ -29,17 +29,17 @@ describe('OutboundsView permissions and navigation', () => {
|
||||
const wrapper = mount(OutboundsView, { global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('详情')
|
||||
expect(wrapper.text()).not.toContain('一件代发出库')
|
||||
expect(wrapper.text()).not.toContain('新建出库单')
|
||||
expect(wrapper.text()).not.toContain('取消')
|
||||
expect(OutboundsView.__file).toContain('OutboundsView.vue')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('shows one-click creation and cancellation only with their exact permissions', async () => {
|
||||
it('shows outbound creation and cancellation only with their exact permissions', async () => {
|
||||
canPermission.mockImplementation((code: string) => ['platform:overseas-warehouse:outbound:create', 'platform:overseas-warehouse:outbound:cancel'].includes(code))
|
||||
const wrapper = mount(OutboundsView, { global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('一件代发出库')
|
||||
expect(wrapper.text()).toContain('新建出库单')
|
||||
expect(wrapper.text()).toContain('取消')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
@@ -84,9 +84,12 @@ describe('overseas warehouse first-batch prototype contract', () => {
|
||||
const value = source(fileName)
|
||||
expect(value).toContain('<OverseasReadOnlyDetail')
|
||||
expect(value).toContain('@back="back"')
|
||||
expect(value).not.toContain('AppDialog')
|
||||
expect(value).not.toContain('AppDrawer')
|
||||
if (fileName !== 'RelabelOrderDetailView.vue') expect(value).not.toContain('AppDialog')
|
||||
}
|
||||
const relabel = source('RelabelOrderDetailView.vue')
|
||||
expect(relabel).toContain('<AppDialog v-if="previewUrl"')
|
||||
expect(relabel).toContain('<iframe :src="previewUrl"')
|
||||
})
|
||||
|
||||
it('keeps second-batch forms non-submitting until overseas write contracts exist', () => {
|
||||
|
||||
Reference in New Issue
Block a user