优化
This commit is contained in:
@@ -111,7 +111,7 @@ async function save() {
|
||||
<LoadErrorState v-if="error" compact title="派送资料操作失败" :message="error.message" :loading="busy || loading" :show-retry="!snapshot || conflict" @retry="reload"><template #details><ApiErrorMeta :details="error" /></template></LoadErrorState>
|
||||
<section class="density-dialog-section" data-tone="summary" aria-label="派送资料摘要"><h3 class="density-dialog-section__title">资料核对</h3><table class="density-table"><tbody><tr><th scope="row">派送单号</th><td>{{ deliveryNo || '—' }}</td><th scope="row">资料类别</th><td>{{ snapshot ? uploadedCount + '/3 已上传' : loading ? '正在读取…' : '资料未返回' }}</td></tr></tbody></table><p v-if="snapshot" class="density-dialog-note">{{ canEdit ? '上传、替换和删除将在保存资料后生效;关闭将放弃未保存修改。' : '当前账号仅可查看已保存资料。' }}</p></section>
|
||||
<template v-if="snapshot">
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="BOL资料登记"><h3 class="density-dialog-section__title">BOL资料</h3><el-form class="density-form" label-position="left" label-width="80px" :disabled="busy || conflict || loading"><table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="BOL号"><el-input v-if="canEdit" v-model="bolNo" :disabled="busy || conflict || loading" placeholder="未填写" /><span v-else>{{ bolNo || '—' }}</span></el-form-item></td></tr></tbody></table></el-form></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="BOL资料登记"><h3 class="density-dialog-section__title">BOL资料</h3><el-form class="density-form" label-position="left" label-width="80px" :disabled="busy || conflict || loading"><table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="BOL号"><el-input v-if="canEdit" v-model="bolNo" :disabled="busy || conflict || loading" /><span v-else>{{ bolNo || '—' }}</span></el-form-item></td></tr></tbody></table></el-form></section>
|
||||
<section v-for="group in draft" :key="group.category" class="document-group density-dialog-section" data-tone="source" :data-category="group.category">
|
||||
<header><h3 class="density-dialog-section__title">{{ group.label }}</h3><el-tag :type="group.files.length ? 'success' : 'info'">{{ group.files.length ? '已上传' : '待上传' }}</el-tag><span>{{ group.files.length }}/20</span><el-upload v-if="canEdit" :key="uploadKey" :auto-upload="false" :show-file-list="false" :disabled="busy || conflict || group.files.length >= 20" :on-change="(file: UploadFile) => upload(group.category, file)"><el-button class="density-action" data-tone="primary" :disabled="busy || conflict || group.files.length >= 20">上传</el-button></el-upload></header>
|
||||
<p v-if="!group.files.length" class="density-dialog-note">尚未上传文件</p>
|
||||
|
||||
@@ -39,12 +39,12 @@ defineExpose({ covered })
|
||||
<table class="density-table density-table--editable arrange-editor-table"><tbody>
|
||||
<tr><td><el-form-item label="预计派送时间" required><el-date-picker v-model="groups[index]!.plannedDeliveryAt" :disabled="disabled" type="datetime" value-format="YYYY-MM-DDTHH:mm:ssZ" placeholder="请选择派送时间" /></el-form-item></td><td><el-form-item label="派送方式" required><el-select v-model="groups[index]!.deliveryMethod" :disabled="disabled" placeholder="请选择"><el-option label="卡派打托" value="TRUCK_PALLET" /><el-option label="卡派地板" value="TRUCK_FLOOR" /><el-option label="FBA自提" value="FBA_PICKUP" /><el-option label="客户自提" value="CUSTOMER_PICKUP" /><el-option label="快递" value="EXPRESS" /><el-option label="外配" value="OUTSOURCED" /><el-option label="专车直送" value="DEDICATED_TRUCK" /><el-option label="零担派送" value="LTL" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="提货方式" required><el-select v-model="groups[index]!.pickupMethod" :disabled="disabled" placeholder="请选择"><el-option label="一提一卸" value="ONE_PICKUP_ONE_DROP" /><el-option label="一提多卸" value="ONE_PICKUP_MULTI_DROP" /><el-option label="多提一卸" value="MULTI_PICKUP_ONE_DROP" /><el-option label="多提多卸" value="MULTI_PICKUP_MULTI_DROP" /><el-option label="仓库自提" value="WAREHOUSE_PICKUP" /></el-select></el-form-item></td><td><el-form-item label="装车类型" required><el-select v-model="groups[index]!.loadingType" :disabled="disabled" placeholder="请选择"><el-option label="托盘" value="PALLET" /><el-option label="地板" value="FLOOR" /><el-option label="混装" value="MIXED" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="承运商"><el-input v-model="groups[index]!.carrierName" :disabled="disabled" placeholder="请输入承运商(选填)" /></el-form-item></td><td><el-form-item label="运单号"><el-input v-model="groups[index]!.waybillNo" :disabled="disabled" placeholder="请输入运单号(选填)" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="车型"><el-input v-model="groups[index]!.vehicleType" :disabled="disabled" placeholder="请输入本组派送车型(选填)" /></el-form-item></td><td><el-form-item label="车辆尺寸"><el-input v-model="groups[index]!.vehicleSize" :disabled="disabled" placeholder="请输入车辆尺寸(选填)" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="预约账号"><el-select v-model="groups[index]!.appointmentAccount" :disabled="disabled" clearable placeholder="请选择"><el-option label="自有账号" value="SELF" /><el-option label="买约" value="BUY_APPOINTMENT" /></el-select></el-form-item></td><td><el-form-item v-if="groups[index]!.appointmentAccount === 'BUY_APPOINTMENT'" label="卖家姓名" required><el-input v-model="groups[index]!.sellerName" :disabled="disabled" placeholder="请输入卖家姓名" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="groups[index]!.remark" :disabled="disabled" placeholder="请输入本组派送备注(选填)" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="承运商"><el-input v-model="groups[index]!.carrierName" :disabled="disabled" /></el-form-item></td><td><el-form-item label="运单号"><el-input v-model="groups[index]!.waybillNo" :disabled="disabled" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="车型"><el-input v-model="groups[index]!.vehicleType" :disabled="disabled" /></el-form-item></td><td><el-form-item label="车辆尺寸"><el-input v-model="groups[index]!.vehicleSize" :disabled="disabled" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="预约账号"><el-select v-model="groups[index]!.appointmentAccount" :disabled="disabled" clearable placeholder="请选择"><el-option label="自有账号" value="SELF" /><el-option label="买约" value="BUY_APPOINTMENT" /></el-select></el-form-item></td><td><el-form-item v-if="groups[index]!.appointmentAccount === 'BUY_APPOINTMENT'" label="卖家姓名" required><el-input v-model="groups[index]!.sellerName" :disabled="disabled" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="groups[index]!.remark" :disabled="disabled" /></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
<h4 class="density-dialog-section__title">本组新增费用</h4><table class="density-table density-table--editable"><tbody><tr v-for="fee in groups[index]!.fees.filter(item => required(index, previewGroup, item.feeType))" :key="fee.feeType"><td><el-form-item v-if="!covered(index, previewGroup, fee.feeType)" :label="(serviceLabels[fee.feeType] || fee.feeName) + '(未覆盖部分)'" required><div class="arrange-fee-controls"><el-input-number v-model="fee.amount" :disabled="disabled" :min="0.01" :precision="2" placeholder="请输入实际新增应收" controls-position="right" /><el-select v-model="fee.currency" :disabled="disabled" placeholder="币种"><el-option label="USD" value="USD" /><el-option label="CNY" value="CNY" /></el-select></div></el-form-item><p v-else class="density-dialog-note">本组{{ serviceLabels[fee.feeType] || fee.feeName }}已全部覆盖,不重复登记。</p></td></tr></tbody></table>
|
||||
<h4 class="density-dialog-section__title">本组新增费用</h4><table class="density-table density-table--editable"><tbody><tr v-for="fee in groups[index]!.fees.filter(item => required(index, previewGroup, item.feeType))" :key="fee.feeType"><td><el-form-item v-if="!covered(index, previewGroup, fee.feeType)" :label="(serviceLabels[fee.feeType] || fee.feeName) + '(未覆盖部分)'" required><div class="arrange-fee-controls"><el-input-number v-model="fee.amount" :disabled="disabled" :min="0.01" :precision="2" controls-position="right" /><el-select v-model="fee.currency" :disabled="disabled" placeholder="币种"><el-option label="USD" value="USD" /><el-option label="CNY" value="CNY" /></el-select></div></el-form-item><p v-else class="density-dialog-note">本组{{ serviceLabels[fee.feeType] || fee.feeName }}已全部覆盖,不重复登记。</p></td></tr></tbody></table>
|
||||
</section>
|
||||
</template>
|
||||
</section>
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('dispatch workflow native layout', () => {
|
||||
field(dialog, '实际托位容量').getComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 22)
|
||||
await field(dialog, '司机姓名').get('input').setValue('新司机')
|
||||
field(dialog, '计划发车时间').getComponent({ name: 'ElDatePicker' }).vm.$emit('update:modelValue', '2026-11-01T10:00:00Z')
|
||||
await dialog.get('textarea[placeholder="请输入本次备注(选填)"]').setValue('维护备注')
|
||||
await dialog.get('textarea[aria-label="本次操作备注"]').setValue('维护备注')
|
||||
await dialog.get('button[aria-label="展开全屏"]').trigger('click'); await flushPromises()
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
const { vehicleStatus: _status, ...vehicle } = resources().vehicle
|
||||
@@ -87,7 +87,7 @@ describe('dispatch workflow native layout', () => {
|
||||
vi.mocked(api.updateDispatch).mockRejectedValueOnce(new ApiResponseError('结果未确认', 'A0503', 503, null, 'workflow-request')).mockImplementationOnce(async (_, body) => command('EDIT', body.idempotencyKey))
|
||||
const { wrapper, dialog } = await render('EDIT')
|
||||
await field(dialog, '车牌号').get('input').setValue('CA-PRESERVED')
|
||||
await dialog.get('textarea[placeholder="请输入本次备注(选填)"]').setValue('保留本次输入')
|
||||
await dialog.get('textarea[aria-label="本次操作备注"]').setValue('保留本次输入')
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
const original = JSON.parse(JSON.stringify(vi.mocked(api.updateDispatch).mock.calls[0]![1])) as UpdateDispatch
|
||||
expect(dialog.text()).toContain('workflow-request')
|
||||
@@ -96,7 +96,7 @@ describe('dispatch workflow native layout', () => {
|
||||
expect(dialog.props('title')).toBe('维护车辆信息 · PC/1')
|
||||
await wrapper.setProps({ modelValue: false }); await wrapper.setProps({ modelValue: true }); await flushPromises()
|
||||
expect((field(dialog, '车牌号').get('input').element as HTMLInputElement).value).toBe('CA-PRESERVED')
|
||||
expect((dialog.get('textarea[placeholder="请输入本次备注(选填)"]').element as HTMLTextAreaElement).value).toBe('保留本次输入')
|
||||
expect((dialog.get('textarea[aria-label="本次操作备注"]').element as HTMLTextAreaElement).value).toBe('保留本次输入')
|
||||
dialog.findComponent(LoadErrorState).vm.$emit('retry'); await flushPromises()
|
||||
expect(vi.mocked(api.updateDispatch).mock.calls[1]![1]).toEqual(original)
|
||||
})
|
||||
|
||||
@@ -256,8 +256,8 @@ watch([open, () => props.dispatchNo, () => props.action, () => props.operation],
|
||||
<DispatchEvidenceFiles v-model="vehicle.evidenceFileIds" :dispatch-no="currentNo" kind="VEHICLE" :readonly="currentAction !== 'EDIT'" :disabled="frozen || loading || uploadingEvidence || !allowed" @busy="evidenceBusy.VEHICLE = $event" />
|
||||
<DispatchEvidenceFiles v-if="driver.evidence" v-model="driver.evidence.fileIds" :dispatch-no="currentNo" kind="DRIVER" :readonly="currentAction !== 'EDIT'" :disabled="frozen || loading || uploadingEvidence || !allowed" @busy="evidenceBusy.DRIVER = $event" />
|
||||
</template>
|
||||
<section v-if="currentOperation === 'ROUTE' || ['REMOVE_CARGO', 'CANCEL', 'RETURN_TO_REVIEW', 'DISPATCH_REVIEW', 'LOADING_REVIEW'].includes(currentAction)" class="density-dialog-section" data-tone="work" aria-label="操作原因与意见"><h3 class="density-dialog-section__title">操作说明</h3><table class="density-table density-table--editable"><tbody><tr><td><el-form-item :label="currentOperation === 'ROUTE' || form.decision === 'REJECTED' || ['REMOVE_CARGO', 'CANCEL', 'RETURN_TO_REVIEW'].includes(currentAction) ? '原因(必填)' : '审核意见(选填)'"><el-input v-model="form.reason" :disabled="frozen || loading || uploadingEvidence || !allowed" type="textarea" :rows="3" placeholder="请输入操作原因或审核意见" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section v-else-if="currentAction !== 'ARRANGE_DELIVERY' && currentAction !== 'ADD_CARGO'" class="density-dialog-section" data-tone="work" aria-label="本次操作备注"><h3 class="density-dialog-section__title">本次备注</h3><table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="备注"><el-input v-model="form.remark" :disabled="frozen || loading || uploadingEvidence || !allowed" type="textarea" :rows="3" placeholder="请输入本次备注(选填)" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section v-if="currentOperation === 'ROUTE' || ['REMOVE_CARGO', 'CANCEL', 'RETURN_TO_REVIEW', 'DISPATCH_REVIEW', 'LOADING_REVIEW'].includes(currentAction)" class="density-dialog-section" data-tone="work" aria-label="操作原因与意见"><h3 class="density-dialog-section__title">操作说明</h3><table class="density-table density-table--editable"><tbody><tr><td><el-form-item :label="currentOperation === 'ROUTE' || form.decision === 'REJECTED' || ['REMOVE_CARGO', 'CANCEL', 'RETURN_TO_REVIEW'].includes(currentAction) ? '原因(必填)' : '审核意见(选填)'"><el-input v-model="form.reason" :disabled="frozen || loading || uploadingEvidence || !allowed" type="textarea" :rows="3" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section v-else-if="currentAction !== 'ARRANGE_DELIVERY' && currentAction !== 'ADD_CARGO'" class="density-dialog-section" data-tone="work" aria-label="本次操作备注"><h3 class="density-dialog-section__title">本次备注</h3><table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="备注"><el-input v-model="form.remark" aria-label="本次操作备注" :disabled="frozen || loading || uploadingEvidence || !allowed" type="textarea" :rows="3" /></el-form-item></td></tr></tbody></table></section>
|
||||
</el-form>
|
||||
</div>
|
||||
</AppDialog>
|
||||
|
||||
@@ -203,7 +203,7 @@ watch(() => [props.customerId, props.exceptionNo, props.active], () => { ++seque
|
||||
<p v-if="detail.order.evidenceFileIds?.length">已保存 {{ detail.order.evidenceFileIds.length }} 份历史证据;本次可按需选用,不自动全部提交。</p>
|
||||
<template v-if="canProcess">
|
||||
<el-form label-position="top" :disabled="locked">
|
||||
<el-form-item label="处理说明 / 取消原因(选填)"><el-input v-model="notes" data-test="notes" type="textarea" :rows="2" maxlength="1000" placeholder="可补充实际情况;留空按本次操作记录标准说明" /></el-form-item>
|
||||
<el-form-item label="处理说明 / 取消原因(选填)"><el-input v-model="notes" data-test="notes" type="textarea" :rows="2" maxlength="1000" /></el-form-item>
|
||||
<template v-if="allowed('COMPLETE_EXCEPTION')">
|
||||
<label>处理证据 <input data-test="evidence" type="file" :disabled="locked" @change="upload" /></label>
|
||||
<div v-for="(fileId, index) in detail.order.evidenceFileIds || []" :key="fileId"><label><input :data-test="`history-${index}`" type="checkbox" :checked="selectedHistory.includes(fileId)" :disabled="locked" @change="selectHistory(fileId, $event)" />选用历史证据 {{ index + 1 }}</label></div>
|
||||
|
||||
@@ -13,7 +13,7 @@ defineProps<{ model: AppointmentForm; appointmentNo?: string; timezone?: string
|
||||
<tr><td colspan="2"><el-form-item label="外部约号" required><el-input v-model="model.confirmationNo" maxlength="128" placeholder="填写收货方提供的确认号" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="对方确认开始时间" required><el-date-picker v-model="model.appointmentAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="目的仓当地时间" @change="model.startOffset = ''" /></el-form-item></td><td><el-form-item label="对方确认结束时间"><el-date-picker v-model="model.appointmentEndAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="未明确可留空" @change="model.endOffset = ''" /></el-form-item></td></tr>
|
||||
</template>
|
||||
<tr><td colspan="2"><el-form-item :label="model.appointmentStatus === 'FAILED' ? '原因' : '备注'" :required="model.appointmentStatus === 'FAILED'"><el-input v-model="model.appointmentRemark" maxlength="1000" placeholder="有需交接的事项时填写" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item :label="model.appointmentStatus === 'FAILED' ? '原因' : '备注'" :required="model.appointmentStatus === 'FAILED'"><el-input v-model="model.appointmentRemark" aria-label="预约备注" maxlength="1000" /></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
<details><summary>补充计划时段与夏令时信息</summary><table class="density-table density-table--editable appointment-editor-table"><tbody>
|
||||
<tr><td><el-form-item label="计划开始时段"><el-date-picker v-model="model.plannedAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="只知道日期时不必填写" /></el-form-item></td><td><el-form-item label="计划结束时段"><el-date-picker v-model="model.plannedEndAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" /></el-form-item></td></tr>
|
||||
@@ -31,7 +31,7 @@ defineProps<{ model: AppointmentForm; appointmentNo?: string; timezone?: string
|
||||
<el-form-item label="对方确认开始时间" required><el-date-picker v-model="model.appointmentAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="目的仓当地时间" @change="model.startOffset = ''" /></el-form-item>
|
||||
<el-form-item label="对方确认结束时间"><el-date-picker v-model="model.appointmentEndAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="未明确可留空" @change="model.endOffset = ''" /></el-form-item>
|
||||
</template>
|
||||
<el-form-item :label="model.appointmentStatus === 'FAILED' ? '原因' : '备注'" :required="model.appointmentStatus === 'FAILED'"><el-input v-model="model.appointmentRemark" maxlength="1000" placeholder="有需交接的事项时填写" /></el-form-item>
|
||||
<el-form-item :label="model.appointmentStatus === 'FAILED' ? '原因' : '备注'" :required="model.appointmentStatus === 'FAILED'"><el-input v-model="model.appointmentRemark" aria-label="预约备注" maxlength="1000" /></el-form-item>
|
||||
<details class="appointment-fields__extra"><summary>补充计划时段与夏令时信息</summary>
|
||||
<div class="appointment-fields__extra-grid">
|
||||
<el-form-item label="计划开始时段"><el-date-picker v-model="model.plannedAt" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="只知道日期时不必填写" /></el-form-item>
|
||||
|
||||
@@ -176,7 +176,7 @@ watch(() => props.modelValue, value => { if (value) void init(); else generation
|
||||
<table class="density-table density-table--editable dispatch-create-table"><tbody>
|
||||
<tr><td><el-form-item label="建单方式"><el-radio-group v-model="mode" :disabled="frozen || loading"><el-radio value="cargo">先选货建单</el-radio><el-radio value="empty">先建空单后加货</el-radio></el-radio-group></el-form-item></td><td><el-form-item label="起运仓" required><el-select v-model="warehouseId" :disabled="frozen || loading || Boolean(draft)" placeholder="请选择起运仓" @change="search"><el-option v-for="warehouse in warehouses" :key="String(warehouse.id)" :value="String(warehouse.id)" :label="warehouse.warehouseName" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="计划发车时间"><el-date-picker v-model="form.plannedDepartureAt" :disabled="frozen || loading || (mode === 'cargo' && !activeContainerId)" type="datetime" value-format="YYYY-MM-DDTHH:mm:ssZ" placeholder="可先保存,审核前补齐" /></el-form-item></td><td><el-form-item label="预计到达时间"><el-date-picker v-model="form.estimatedArrivalAt" :disabled="frozen || loading || (mode === 'cargo' && !activeContainerId)" type="datetime" value-format="YYYY-MM-DDTHH:mm:ssZ" placeholder="请选择预计到达时间(选填)" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="form.remark" :disabled="frozen || loading || (mode === 'cargo' && !activeContainerId)" placeholder="请输入本趟备注(选填)" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="form.remark" :disabled="frozen || loading || (mode === 'cargo' && !activeContainerId)" /></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
</section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="排车车辆与司机"><h3 class="density-dialog-section__title">车辆与司机</h3><DispatchResourceFields continuous v-model:vehicle="vehicle" v-model:driver="driver" :disabled="frozen || loading || (mode === 'cargo' && !activeContainerId)" /></section>
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('WarehouseTransferReviewDialog', () => {
|
||||
const wrapper = mountDialog()
|
||||
expect(wrapper.text()).toContain('仓储转运单审核 · WT-1')
|
||||
expect(wrapper.text()).toContain('测试客户')
|
||||
expect(wrapper.text()).toContain('审核通过后,转运单将进入海外仓收货打托作业。')
|
||||
expect(wrapper.text()).not.toContain('审核通过后,转运单将进入海外仓收货打托作业。')
|
||||
expect(wrapper.find('.back').text()).toBe('返回')
|
||||
expect(wrapper.find('.approve').text()).toBe('审核通过')
|
||||
expect(wrapper.find('textarea, input, table').exists()).toBe(false)
|
||||
|
||||
@@ -39,6 +39,6 @@ async function submit() {
|
||||
:confirm-loading="saving"
|
||||
@confirm="submit"
|
||||
>
|
||||
<section class="density-dialog-section" data-tone="source" aria-label="转运审核对象"><p class="density-dialog-note">客户:{{ customerName || '—' }}</p><div>审核通过后,转运单将进入海外仓收货打托作业。</div></section>
|
||||
<section class="density-dialog-section" data-tone="source" aria-label="转运审核对象"><p class="density-dialog-note">客户:{{ customerName || '—' }}</p></section>
|
||||
</AppDialog>
|
||||
</template>
|
||||
|
||||
@@ -43,13 +43,12 @@ describe('overseas warehouse 1920px layout acceptance', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('provides semantic placeholders for editable form controls', () => {
|
||||
it('preserves semantic placeholders for query fields while forms use their labels', () => {
|
||||
for (const name of ['LastMileOrdersView.vue', 'InboundOrdersView.vue', 'OutboundsView.vue', 'DeliveryOrdersView.vue', 'RelabelOrdersView.vue', 'PalletsView.vue', 'InventoryView.vue']) {
|
||||
const editableControls = [...page(name).matchAll(/<el-(?:input-number|date-picker|input|select)[ >][^>]*>/g)]
|
||||
.map(([tag]) => tag)
|
||||
.filter((tag) => !/\s(?:readonly|disabled)(?:\s|\/?>)/.test(tag))
|
||||
.filter((tag) => !tag.includes('v-model="planEditForm.warehouseId"'))
|
||||
expect(editableControls.every((tag) => tag.includes('placeholder=')), `${name} has an editable control without placeholder`).toBe(true)
|
||||
const source = page(name)
|
||||
const queryFields = [...source.matchAll(/\{ key: '[^']+', type: '(?:input|select)'[^\r\n]*/g)].map(([field]) => field)
|
||||
expect(queryFields.length, name).toBeGreaterThan(0)
|
||||
expect(queryFields.every((field) => field.includes('placeholder:')), `${name} has a query field without placeholder`).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -52,17 +52,17 @@ function openDetail(source: object) { const row = source as CartonListItem; void
|
||||
</ListPageLayout>
|
||||
<ContractPendingFormDialog v-model="dialogOpen" :title="dialogMode === 'create' ? '新增箱号' : '编辑箱号'" width="min(860px, calc(100vw - 28px))" domain="箱号">
|
||||
<el-form label-position="top"><el-row :gutter="16">
|
||||
<el-col :span="12"><el-form-item label="箱号" required><el-input v-model="form.cartonNo" :readonly="dialogMode === 'edit'" placeholder="请输入箱号" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="箱号" required><el-input v-model="form.cartonNo" :readonly="dialogMode === 'edit'" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="所属 FBA 仓" required><el-select v-model="form.fbaWarehouse" placeholder="FBA仓候选接口待接入" disabled /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="商品 SKU" required><el-input v-model="form.sku" placeholder="请输入商品 SKU" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="中文品名" required><el-input v-model="form.productName" placeholder="请输入中文品名" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="数量" required><el-input-number v-model="form.quantity" :min="1" :precision="0" controls-position="right" placeholder="请输入数量" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="重量(kg)" required><el-input-number v-model="form.weight" :min="0.01" :precision="2" controls-position="right" placeholder="请输入重量" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联托盘"><el-input v-model="form.palletNo" placeholder="请输入关联托盘号" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联入库单"><el-input v-model="form.inboundOrderNo" placeholder="请输入关联入库单号" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="商品 SKU" required><el-input v-model="form.sku" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="中文品名" required><el-input v-model="form.productName" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="数量" required><el-input-number v-model="form.quantity" :min="1" :precision="0" controls-position="right" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="重量(kg)" required><el-input-number v-model="form.weight" :min="0.01" :precision="2" controls-position="right" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联托盘"><el-input v-model="form.palletNo" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联入库单"><el-input v-model="form.inboundOrderNo" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="关联出库单"><el-input v-model="form.outboundOrderNo" readonly /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="状态"><el-input v-model="form.status" readonly /></el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注(选填)" /></el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item></el-col>
|
||||
</el-row></el-form>
|
||||
</ContractPendingFormDialog>
|
||||
</AdminPage>
|
||||
|
||||
@@ -196,7 +196,7 @@ onMounted(load)
|
||||
</el-form-item>
|
||||
<el-form-item label="回访结果" required><el-select v-model="form.visitResult" placeholder="请选择回访结果"><el-option v-for="(label, value) in resultLabels" :key="value" :label="label" :value="value" /></el-select></el-form-item>
|
||||
<el-form-item label="客户反馈"><el-input v-model="form.customerFeedback" type="textarea" :rows="4" maxlength="2000" show-word-limit placeholder="记录客户对派送服务的反馈" /></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="补充后续跟进事项" /></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit /></el-form-item>
|
||||
<el-form-item label="回访资料">
|
||||
<el-button :disabled="uploading" :loading="uploading" @click="fileInput?.click()"><FileUp :size="16" />{{ uploading ? '上传中...' : '选择文件' }}</el-button><input ref="fileInput" hidden type="file" multiple :disabled="uploading" accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png,.webp" @change="selectFiles" />
|
||||
<span class="file-tip">支持 PDF、Office、JPG、PNG、WEBP,单个不超过20MB</span>
|
||||
|
||||
@@ -197,7 +197,7 @@ onMounted(() => { void load(); void loadWarehouses() })
|
||||
<el-alert title="取消派送请先解除未执行车次关联,再前往关联出库单取消出库;已出库或已发车不能直接取消。" type="warning" :closable="false" show-icon />
|
||||
<section class="density-dialog-section" data-tone="source" aria-label="派送状态依据"><h3 class="density-dialog-section__title">当前资料</h3><table class="density-table"><tbody><tr><th scope="row">当前状态</th><td>{{ statusLabels[String(statusRow?.status)] || '—' }}</td></tr><tr><th scope="row">关联出库</th><td>{{ statusRow?.outboundNo || '—' }}</td></tr></tbody></table></section>
|
||||
<el-alert v-if="statusRow && !statusLoading && !statusError && !statusOptions.length" title="当前状态已无可操作的派送状态,请核对最新资料。" type="info" :closable="false" show-icon />
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="派送状态登记"><h3 class="density-dialog-section__title">状态登记</h3><el-form class="density-form" label-position="left" label-width="100px" :disabled="statusLoading || statusSaving || statusConflict || !statusOptions.length || !access.can(permission.deliveryStatus)"><table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="派送状态" required><el-select v-model="statusForm.status" placeholder="请选择派送状态"><el-option v-for="option in statusOptions" :key="option.value" :label="option.label" :value="option.value" /></el-select></el-form-item></td></tr><tr><td><el-form-item label="备注"><el-input v-model="statusForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入状态备注(选填)" /></el-form-item></td></tr></tbody></table></el-form></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="派送状态登记"><h3 class="density-dialog-section__title">状态登记</h3><el-form class="density-form" label-position="left" label-width="100px" :disabled="statusLoading || statusSaving || statusConflict || !statusOptions.length || !access.can(permission.deliveryStatus)"><table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="派送状态" required><el-select v-model="statusForm.status" placeholder="请选择派送状态"><el-option v-for="option in statusOptions" :key="option.value" :label="option.label" :value="option.value" /></el-select></el-form-item></td></tr><tr><td><el-form-item label="备注"><el-input v-model="statusForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item></td></tr></tbody></table></el-form></section>
|
||||
<LoadErrorState v-if="statusError" compact title="派送状态操作失败" :message="statusError.message" :loading="statusLoading || statusSaving" :show-retry="statusConflict" @retry="refreshStatus"><template #details><ApiErrorMeta :details="statusError" /></template></LoadErrorState>
|
||||
</div>
|
||||
</AppDialog>
|
||||
@@ -206,7 +206,7 @@ onMounted(() => { void load(); void loadWarehouses() })
|
||||
<el-form class="density-form density-dialog-sections" label-position="left" label-width="110px" :disabled="returnLoading || returnSaving || !returnRow || !canReturn(returnRow)">
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="退货登记"><h3 class="density-dialog-section__title">退货资料</h3><table class="density-table density-table--editable delivery-return-editor"><tbody>
|
||||
<tr><td colspan="2"><el-form-item label="对应尾程主单" required><el-select v-model="returnForm.lastMileOrderId" placeholder="请选择该派送单对应的尾程主单"><el-option v-for="option in returnOptions" :key="option.lastMileOrderId" :value="option.lastMileOrderId" :label="returnRelationLabel(option)" /></el-select></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="退货原因" required><el-input v-model="returnForm.reason" type="textarea" :rows="4" maxlength="1000" show-word-limit placeholder="请输入退货原因" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="退货原因" required><el-input v-model="returnForm.reason" type="textarea" :rows="4" maxlength="1000" show-word-limit /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="退货去向" required><el-select v-model="returnForm.returnDirection" placeholder="请选择退货去向"><el-option label="退回海外仓" value="OVERSEAS_WAREHOUSE" /><el-option label="退回客户" value="CUSTOMER" /><el-option label="其他" value="OTHER" /></el-select></el-form-item></td><td><el-form-item label="退回物流单号"><el-input v-model="returnForm.returnLogisticsNo" placeholder="可安排物流后补充" /></el-form-item></td></tr>
|
||||
</tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="source" aria-label="原出库可退明细"><h3 class="density-dialog-section__title">原出库明细</h3><p v-if="!returnItems.length" class="density-dialog-note">暂无可退原出库明细</p>
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('ExceptionOrdersView permissions and creation', () => {
|
||||
await flushPromises()
|
||||
await wrapper.findAll('button').find(button => button.text().includes('新增异常订单'))!.trigger('click')
|
||||
const dialog = wrapper.find('[data-dialog="新增异常订单"]')
|
||||
await dialog.find('input[placeholder="请输入入仓码"]').setValue(' IN-1 ')
|
||||
await dialog.find('input[aria-label="异常入仓码"]').setValue(' IN-1 ')
|
||||
await dialog.find('select').setValue('RETURN')
|
||||
await dialog.find('textarea').setValue(' 包裹破损 ')
|
||||
await dialog.find('.dialog-confirm').trigger('click')
|
||||
|
||||
@@ -97,13 +97,13 @@ onMounted(load)
|
||||
<AppDialog class="admin-density-dialog" v-model="createOpen" title="新增异常订单" width="min(760px, calc(100vw - 28px))" confirm-text="保存" :confirm-loading="saving" :loading="resolving" @confirm="submit">
|
||||
<el-alert title="入仓码和尾程订单号至少填写一个;两项都填写时必须属于同一订单。" type="warning" :closable="false" />
|
||||
<el-form label-position="top" class="create-form density-form"><div class="form-grid">
|
||||
<el-form-item label="入仓码"><el-input v-model="form.inboundCode" placeholder="请输入入仓码" @blur="resolveRelation" /></el-form-item>
|
||||
<el-form-item label="尾程订单号"><el-input v-model="form.lastMileOrderNo" placeholder="请输入尾程订单号" @blur="resolveRelation" /></el-form-item>
|
||||
<el-form-item label="入仓码"><el-input v-model="form.inboundCode" aria-label="异常入仓码" @blur="resolveRelation" /></el-form-item>
|
||||
<el-form-item label="尾程订单号"><el-input v-model="form.lastMileOrderNo" @blur="resolveRelation" /></el-form-item>
|
||||
<el-form-item label="异常类型" required><el-select v-model="form.exceptionType" placeholder="请选择异常类型"><el-option v-for="(label, value) in typeLabels" :key="value" :label="label" :value="value" /></el-select></el-form-item>
|
||||
<el-form-item label="处理状态"><el-input model-value="待处理" readonly /></el-form-item>
|
||||
<el-form-item label="箱数"><el-input-number v-model="form.packageCount" :min="1" :max="relation?.availablePackages || 999999" placeholder="请输入箱数" /></el-form-item>
|
||||
<el-form-item label="SKU(可自由填写)"><el-input v-model="form.skuCode" maxlength="128" placeholder="请输入 SKU(选填)" /></el-form-item>
|
||||
</div><el-form-item label="异常原因" required><el-input v-model="form.reason" type="textarea" :rows="4" maxlength="1000" show-word-limit placeholder="请输入异常原因" /></el-form-item>
|
||||
<el-form-item label="箱数"><el-input-number v-model="form.packageCount" :min="1" :max="relation?.availablePackages || 999999" /></el-form-item>
|
||||
<el-form-item label="SKU(可自由填写)"><el-input v-model="form.skuCode" maxlength="128" /></el-form-item>
|
||||
</div><el-form-item label="异常原因" required><el-input v-model="form.reason" type="textarea" :rows="4" maxlength="1000" show-word-limit /></el-form-item>
|
||||
<el-alert v-if="relation" type="success" :closable="false"><template #title><span class="relation-alert-title">已关联:<OrderReferenceText :value="relation.lastMileOrderNo || '无尾程单'" /> / {{ relation.inboundCode || '无入仓单' }},客户 {{ relation.customerName || '客户信息待补充' }}</span></template></el-alert>
|
||||
<el-alert v-else-if="relationError" :title="relationError" type="error" :closable="false" />
|
||||
</el-form>
|
||||
|
||||
@@ -111,7 +111,7 @@ describe('inbound appointment native dialogs', () => {
|
||||
await wrapper.findAll('.el-table__body-wrapper button').find(button => button.text() === (mode === 'permission' ? '查看预约' : '预约'))!.trigger('click'); await flushPromises()
|
||||
const dialog = popup(wrapper, '查看预约')
|
||||
expect(dialog.getComponent(FbaAppointmentFields).props('disabled')).toBe(true)
|
||||
expect(dialog.get('input[placeholder="有需交接的事项时填写"]').attributes('disabled')).toBeDefined()
|
||||
expect(dialog.get('input[aria-label="预约备注"]').attributes('disabled')).toBeDefined()
|
||||
expect(dialog.props('showConfirm')).toBe(false)
|
||||
if (mode === 'replacement') expect(dialog.text()).toContain('替代预约:AP-NEW')
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
@@ -179,7 +179,7 @@ describe('inbound plan and pallet move native dialogs', () => {
|
||||
expect(listOverseasLocations).toHaveBeenCalledExactlyOnceWith('WH-1', { page: 1, size: 200 })
|
||||
expect(dialog.get('[aria-label="移库来源"]').findAll('input')).toHaveLength(0)
|
||||
expect(dialog.findAllComponents({ name: 'ElOption' }).map(option => option.props('value'))).toEqual(['N01', 'A0'])
|
||||
dialog.findComponent({ name: 'ElSelect' }).vm.$emit('update:modelValue', 'A0'); await dialog.get('input[placeholder="请输入移库原因"]').setValue(' 上架到溢出位 ')
|
||||
dialog.findComponent({ name: 'ElSelect' }).vm.$emit('update:modelValue', 'A0'); await dialog.get('input[aria-label="移库原因"]').setValue(' 上架到溢出位 ')
|
||||
await dialog.get('button[aria-label="展开全屏"]').trigger('click'); await flushPromises()
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(moveInboundPallet).toHaveBeenCalledExactlyOnceWith({ overseasWarehouseId: 'WH-1', sourcePalletCode: 'PALLET-1', targetLocationCode: 'A0', expectedPalletVersion: 0, reason: '上架到溢出位', idempotencyKey: expect.stringMatching(/^admin-inbound-move-PALLET-1-\d+$/) })
|
||||
@@ -189,15 +189,15 @@ describe('inbound plan and pallet move native dialogs', () => {
|
||||
let reject!: (reason: unknown) => void
|
||||
vi.mocked(moveInboundPallet).mockReturnValue(new Promise((_, no) => { reject = no }))
|
||||
const { dialog } = await openMove()
|
||||
dialog.findComponent({ name: 'ElSelect' }).vm.$emit('update:modelValue', 'N01'); await dialog.get('input[placeholder="请输入移库原因"]').setValue('现场上架')
|
||||
dialog.findComponent({ name: 'ElSelect' }).vm.$emit('update:modelValue', 'N01'); await dialog.get('input[aria-label="移库原因"]').setValue('现场上架')
|
||||
dialog.vm.$emit('confirm'); dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(moveInboundPallet).toHaveBeenCalledTimes(1)
|
||||
expect(dialog.findComponent({ name: 'ElDialog' }).props()).toMatchObject({ showClose: false, closeOnPressEscape: false })
|
||||
expect(dialog.get('input[placeholder="请输入移库原因"]').attributes('disabled')).toBeDefined()
|
||||
expect(dialog.get('input[aria-label="移库原因"]').attributes('disabled')).toBeDefined()
|
||||
reject(new ApiResponseError('移库未完成', 'A0409', 409, null, 'move-popup-request')); await flushPromises()
|
||||
expect(dialog.props('modelValue')).toBe(true)
|
||||
expect(dialog.findComponent({ name: 'ElSelect' }).props('modelValue')).toBe('N01')
|
||||
expect((dialog.get('input[placeholder="请输入移库原因"]').element as HTMLInputElement).value).toBe('现场上架')
|
||||
expect((dialog.get('input[aria-label="移库原因"]').element as HTMLInputElement).value).toBe('现场上架')
|
||||
expect(dialog.text()).toContain('move-popup-request')
|
||||
})
|
||||
it('keeps failed location queries explicit and retries without losing the move reason', async () => {
|
||||
@@ -205,11 +205,11 @@ describe('inbound plan and pallet move native dialogs', () => {
|
||||
const { dialog } = await openMove()
|
||||
expect(dialog.props('confirmDisabled')).toBe(true)
|
||||
expect(dialog.text()).toContain('location-popup-request')
|
||||
await dialog.get('input[placeholder="请输入移库原因"]').setValue('保留原因')
|
||||
await dialog.get('input[aria-label="移库原因"]').setValue('保留原因')
|
||||
dialog.vm.$emit('confirm'); await flushPromises(); expect(moveInboundPallet).not.toHaveBeenCalled()
|
||||
dialog.findComponent(LoadErrorState).vm.$emit('retry'); await flushPromises()
|
||||
expect(listOverseasLocations).toHaveBeenCalledTimes(2)
|
||||
expect((dialog.get('input[placeholder="请输入移库原因"]').element as HTMLInputElement).value).toBe('保留原因')
|
||||
expect((dialog.get('input[aria-label="移库原因"]').element as HTMLInputElement).value).toBe('保留原因')
|
||||
expect(dialog.findAllComponents({ name: 'ElOption' })).toHaveLength(2)
|
||||
})
|
||||
it('keeps server move blockers visible and does not close the form or refresh as success', async () => {
|
||||
|
||||
@@ -105,7 +105,7 @@ onMounted(load)
|
||||
<LoadErrorState v-if="moveError" compact title="移库未完成" :message="moveError.message" :show-retry="false"><template #details><ApiErrorMeta :details="moveError" /></template></LoadErrorState>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="移库登记"><h3 class="density-dialog-section__title">移库登记</h3><el-form class="density-form" label-position="left" label-width="100px" :disabled="moveSaving || moveLocationsLoading"><table class="density-table density-table--editable"><tbody>
|
||||
<tr><td><el-form-item label="目标库位" required><el-select v-model="targetLocationCode" filterable :loading="moveLocationsLoading" placeholder="请选择普通库位或 A0"><el-option v-for="item in availableLocations" :key="item.id" :value="item.locationCode" :label="`${item.locationCode}${item.sharedOverflow || item.locationType === 'SHARED_OVERFLOW' ? ' · A0共享溢出位' : ''}`" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="操作原因" required><el-input v-model="moveReason" maxlength="200" placeholder="请输入移库原因" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="操作原因" required><el-input v-model="moveReason" aria-label="移库原因" maxlength="200" /></el-form-item></td></tr>
|
||||
</tbody></table></el-form><el-alert v-if="!moveLocationsLoading && !moveLocationError && !availableLocations.length" title="暂无可用普通库位或 A0" type="info" :closable="false" show-icon /></section>
|
||||
</div></AppDialog></template>
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ function back() { void router.push({ name: 'overseas-inventory' }) }; onMounted(
|
||||
|
||||
<template><OverseasDetailShell class="admin-density" dense title="库存详情" :reference-label="referenceLabel" :reference-value="referenceValue" back-label="返回库存管理" domain="库存详情" :pending="false" :status-text="balance ? '库存事实' : '加载中'" @back="back"><LoadErrorState v-if="loadError" title="库存详情加载失败" :message="loadError.message" :loading="loading" @retry="load"><template #details><ApiErrorMeta :details="loadError" /></template></LoadErrorState>
|
||||
<template v-else><section v-loading="loading" class="overview-panel" aria-label="库存概览"><section aria-labelledby="inventory-product-heading"><h2 id="inventory-product-heading">商品信息</h2><dl class="detail-fields density-fields"><div v-for="label in productFields" :key="label"><dt>{{ label }}</dt><dd>{{ productValues[label as keyof typeof productValues] }}</dd></div></dl></section><section aria-labelledby="inventory-summary-heading"><h2 id="inventory-summary-heading">库存状态汇总</h2><dl class="detail-fields density-fields"><div v-for="label in stockFields" :key="label"><dt>{{ label }}</dt><dd>{{ stockValues[label as keyof typeof stockValues] }}</dd></div></dl></section></section>
|
||||
<section class="ledger-section" aria-labelledby="inventory-location-heading"><h2 id="inventory-location-heading">库位库存</h2><div class="inventory-table-wrap"><DataTable :data="locationRows" :columns="locationColumns" column-settings-mode="hide" row-key="id" empty-text="暂无库位库存" /></div></section><section class="ledger-section" aria-labelledby="inventory-pallet-heading"><h2 id="inventory-pallet-heading">托盘箱号信息</h2><div class="inventory-table-wrap"><DataTable :data="palletRows" :columns="palletColumns" column-settings-mode="hide" row-key="id" empty-text="暂无托盘库存" /></div></section><section class="ledger-section" aria-labelledby="inventory-ledger-heading"><h2 id="inventory-ledger-heading">进销存单据明细</h2><p class="ledger-note">按该库存记录的入库单范围展示,出库字段仅为只读事实。</p><div class="inventory-table-wrap"><DataTable :data="ledgerRows" :columns="ledgerColumns" column-settings-mode="hide" row-key="id" empty-text="暂无进销存明细" /></div></section></template>
|
||||
<section class="ledger-section" aria-labelledby="inventory-location-heading"><h2 id="inventory-location-heading">库位库存</h2><div class="inventory-table-wrap"><DataTable :data="locationRows" :columns="locationColumns" column-settings-mode="hide" row-key="id" empty-text="暂无库位库存" /></div></section><section class="ledger-section" aria-labelledby="inventory-pallet-heading"><h2 id="inventory-pallet-heading">托盘箱号信息</h2><div class="inventory-table-wrap"><DataTable :data="palletRows" :columns="palletColumns" column-settings-mode="hide" row-key="id" empty-text="暂无托盘库存" /></div></section><section class="ledger-section" aria-labelledby="inventory-ledger-heading"><h2 id="inventory-ledger-heading">进销存单据明细</h2><div class="inventory-table-wrap"><DataTable :data="ledgerRows" :columns="ledgerColumns" column-settings-mode="hide" row-key="id" empty-text="暂无进销存明细" /></div></section></template>
|
||||
</OverseasDetailShell></template>
|
||||
<style scoped>.overview-panel>section{min-width:0;padding:var(--admin-space-5) var(--admin-space-5) var(--admin-space-5);border-right:1px solid var(--cc-border)}.overview-panel>section:last-child{border-right:0}.overview-panel h2,.ledger-section h2{margin:0 0 var(--admin-space-5);color:var(--cc-text);font-size:var(--admin-font-section)}.ledger-section h2,.ledger-note{margin-right:var(--admin-space-5);margin-left:var(--admin-space-5)}.ledger-note{color:var(--cc-muted);font-size:var(--admin-font-caption)}@media(max-width:1100px){.overview-panel,.detail-fields{grid-template-columns:1fr}.overview-panel>section{border-right:0;border-bottom:1px solid var(--cc-border)}}
|
||||
.overview-panel {display:grid;min-width:0; grid-template-columns: minmax(0, 1fr); border: 0;background:#fff; }
|
||||
|
||||
@@ -375,7 +375,7 @@ onMounted(load)
|
||||
<tr><td><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></td><td><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></td></tr>
|
||||
<tr v-if="feeForm.direction === 'PAYABLE'"><td colspan="2"><el-form-item 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></td></tr>
|
||||
<tr><td><el-form-item label="业务日期" required><el-date-picker v-model="feeForm.businessDate" type="date" value-format="YYYY-MM-DD" /></el-form-item></td><td><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></td></tr>
|
||||
<tr><td><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></td><td><el-form-item label="计费数量"><el-input-number v-model="feeForm.quantity" :min="0.0001" :precision="4" controls-position="right" placeholder="请输入计费数量" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="金额" required><el-input-number v-model="feeForm.amount" :min="0" :precision="2" :step="10" controls-position="right" /></el-form-item></td><td><el-form-item label="计费数量"><el-input-number v-model="feeForm.quantity" :min="0.0001" :precision="4" controls-position="right" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="计费单位"><el-input v-model="feeForm.quantityUnit" :disabled="saving || feeForm.quantity == null" placeholder="如 箱、托、天、m³" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="计费开始日期"><el-date-picker v-model="feeForm.periodStart" type="date" value-format="YYYY-MM-DD" placeholder="仓租等周期费用填写" /></el-form-item></td><td><el-form-item label="计费结束日期"><el-date-picker v-model="feeForm.periodEnd" type="date" value-format="YYYY-MM-DD" placeholder="仓租等周期费用填写" /></el-form-item></td></tr>
|
||||
</tbody></table></el-form>
|
||||
|
||||
@@ -1182,7 +1182,7 @@ onMounted(() => { void load() })
|
||||
<section v-else class="density-dialog-section" data-tone="work" aria-label="转仓登记"><h3 class="density-dialog-section__title">转仓登记</h3>
|
||||
<el-form class="density-form" label-position="left" label-width="110px" :disabled="actionLoading"><table class="density-table density-table--editable"><tbody>
|
||||
<tr><td><el-form-item label="目的 FBA 仓" required><el-select v-model="transferForm.warehouseId" filterable clearable placeholder="请选择目的 FBA 仓" @update:model-value="selectTransferWarehouse"><el-option v-for="warehouse in transferWarehouseOptions" :key="warehouse.warehouseId" :label="warehouse.label" :value="warehouse.warehouseId" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="备注"><el-input v-model="transferForm.remark" type="textarea" maxlength="500" placeholder="请输入转仓备注(选填)" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="备注"><el-input v-model="transferForm.remark" type="textarea" maxlength="500" /></el-form-item></td></tr>
|
||||
</tbody></table></el-form>
|
||||
<el-alert v-if="!transferWarehouseLoading && !transferWarehouseOptions.length" title="暂无可用 FBA 仓候选" type="info" :closable="false" show-icon />
|
||||
</section>
|
||||
@@ -1264,7 +1264,7 @@ onMounted(() => { void load() })
|
||||
</el-form-item>
|
||||
<el-alert v-if="receivingWarehouseForm.warehouseId === receivingWarehouseTarget?.overseasWarehouseId" title="新的海外接柜仓必须与当前仓不同" type="warning" :closable="false" show-icon />
|
||||
<el-alert v-if="!receivingWarehouseLoading && !receivingWarehouseOptions.length" title="暂无可用的 ACTIVE 海外接柜仓" type="info" :closable="false" show-icon />
|
||||
<el-form-item label="备注"><el-input v-model="receivingWarehouseForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入修改备注(选填)" /></el-form-item>
|
||||
<el-form-item label="备注"><el-input v-model="receivingWarehouseForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item>
|
||||
<LoadErrorState v-if="receivingWarehouseActionError" title="海外接柜仓修改失败" :message="receivingWarehouseActionError.message" compact>
|
||||
<template #details><ApiErrorMeta :details="receivingWarehouseActionError" /></template>
|
||||
</LoadErrorState>
|
||||
@@ -1282,10 +1282,10 @@ onMounted(() => { void load() })
|
||||
</section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="入库计划登记"><h3 class="density-dialog-section__title">计划登记</h3>
|
||||
<table class="density-table density-table--editable last-mile-command-table"><tbody>
|
||||
<tr><td><el-form-item label="托数" required><span v-if="inboundPlanIsDropship" class="frozen-pallet-count">{{ inboundPlanForm.palletCount }}</span><el-input-number v-else v-model="inboundPlanForm.palletCount" :min="inboundPlanMinimumPalletCount" :max="999" controls-position="right" placeholder="请输入托数" /><span class="density-dialog-note" v-if="inboundPlanIsDropship">一件代发固定按头程已封托托盘数整体入库,不可增减。</span><span class="density-dialog-note" v-else>按柜级预览至少 {{ inboundPlanMinimumPalletCount }} 托,可增加,不能减少。</span></el-form-item></td><td><el-form-item label="托盘类型"><el-select v-model="inboundPlanForm.palletType" placeholder="请选择托盘类型"><el-option label="标准托盘" value="STANDARD" /><el-option label="木托盘" value="WOOD" /><el-option label="纸托盘" value="PAPER" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="托数" required><span v-if="inboundPlanIsDropship" class="frozen-pallet-count">{{ inboundPlanForm.palletCount }}</span><el-input-number v-else v-model="inboundPlanForm.palletCount" :min="inboundPlanMinimumPalletCount" :max="999" controls-position="right" /><span class="density-dialog-note" v-if="inboundPlanIsDropship">一件代发固定按头程已封托托盘数整体入库,不可增减。</span><span class="density-dialog-note" v-else>按柜级预览至少 {{ inboundPlanMinimumPalletCount }} 托,可增加,不能减少。</span></el-form-item></td><td><el-form-item label="托盘类型"><el-select v-model="inboundPlanForm.palletType" placeholder="请选择托盘类型"><el-option label="标准托盘" value="STANDARD" /><el-option label="木托盘" value="WOOD" /><el-option label="纸托盘" value="PAPER" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="是否分配"><el-switch v-model="inboundPlanForm.assigned" inline-prompt active-text="是" inactive-text="否" /></el-form-item></td><td><el-form-item label="允许合托"><el-switch v-model="inboundPlanForm.mergeRequired" inline-prompt active-text="是" inactive-text="否" /><InlineHelp title="合托提示说明">仅作为现场可选提示,不强制工人合托。</InlineHelp></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="是否加急"><el-switch v-model="inboundPlanForm.urgent" inline-prompt active-text="是" inactive-text="否" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="inboundPlanForm.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit placeholder="请输入备注(选填)" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="inboundPlanForm.remark" type="textarea" :rows="3" maxlength="1000" show-word-limit /></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
</section>
|
||||
</el-form>
|
||||
@@ -1295,7 +1295,7 @@ onMounted(() => { void load() })
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="暂扣变更登记"><h3 class="density-dialog-section__title">变更登记</h3><el-form class="density-form" label-position="left" label-width="100px" :disabled="actionLoading"><table class="density-table density-table--editable"><tbody>
|
||||
<tr><td><el-form-item label="暂扣状态" required><el-radio-group v-model="holdForm.held"><el-radio :value="true">暂扣</el-radio><el-radio :value="false">解除暂扣</el-radio></el-radio-group></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="是否计费" required><el-radio-group v-model="holdForm.chargeable"><el-radio :value="true">是</el-radio><el-radio :value="false">否</el-radio></el-radio-group></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="变更原因" required><el-input v-model="holdForm.reason" type="textarea" :rows="4" maxlength="500" show-word-limit placeholder="请输入暂扣或解除暂扣原因" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="变更原因" required><el-input v-model="holdForm.reason" type="textarea" :rows="4" maxlength="500" show-word-limit /></el-form-item></td></tr>
|
||||
</tbody></table></el-form></section>
|
||||
</AppDialog>
|
||||
<AppDialog class="admin-density-dialog" v-model="manualNodesOpen" :title="`修改节点 · ${actionTarget?.orderNo || '—'}`" width="min(700px, calc(100vw - 28px))" fullscreenable confirm-text="保存" :loading="manualNodesLoading" :confirm-loading="actionLoading" @confirm="submitManualNodes">
|
||||
|
||||
@@ -130,9 +130,9 @@ onMounted(() => { void loadWarehouses() })
|
||||
<section class="density-dialog-section" data-tone="work">
|
||||
<table class="density-table density-table--editable"><tbody>
|
||||
<tr><td><el-form-item label="海外仓" required><span v-if="editing">{{ selectedWarehouse ? `${selectedWarehouse.warehouseName}(${selectedWarehouse.warehouseCode})` : '—' }}</span><el-select v-else v-model="form.warehouseId" placeholder="请选择海外仓"><el-option v-for="item in warehouses" :key="item.id" :value="item.id" :label="`${item.warehouseName}(${item.warehouseCode})`" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="库位编码" required><el-input v-model="form.locationCode" maxlength="50" placeholder="请输入库位编码" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="最大承重(kg)" required><el-input-number v-model="form.maxWeightKg" :min="0.001" :precision="3" controls-position="right" placeholder="请输入最大承重" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="备注"><el-input v-model="form.remark" maxlength="500" placeholder="请输入备注(选填)" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="库位编码" required><el-input v-model="form.locationCode" maxlength="50" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="最大承重(kg)" required><el-input-number v-model="form.maxWeightKg" :min="0.001" :precision="3" controls-position="right" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="备注"><el-input v-model="form.remark" maxlength="500" /></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
</section>
|
||||
</el-form>
|
||||
|
||||
@@ -230,12 +230,12 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
|
||||
</ListPageLayout>
|
||||
<AppDialog v-model="editOpen" class="admin-density-dialog" title="编辑 SKU 测量修正版" width="min(620px, calc(100vw - 28px))" confirm-text="保存并重新同步" :confirm-loading="Boolean(actionId)" @confirm="saveEdit">
|
||||
<el-form label-position="top" class="sync-edit-form">
|
||||
<el-form-item label="SKU"><el-input v-model.trim="editForm.skuCode" placeholder="请输入 SKU" /></el-form-item>
|
||||
<el-form-item label="SKU"><el-input v-model.trim="editForm.skuCode" /></el-form-item>
|
||||
<div class="sync-edit-grid">
|
||||
<el-form-item label="长(cm)"><el-input-number v-model="editForm.lengthCm" :min="0.001" :controls="false" placeholder="请输入长度" /></el-form-item>
|
||||
<el-form-item label="宽(cm)"><el-input-number v-model="editForm.widthCm" :min="0.001" :controls="false" placeholder="请输入宽度" /></el-form-item>
|
||||
<el-form-item label="高(cm)"><el-input-number v-model="editForm.heightCm" :min="0.001" :controls="false" placeholder="请输入高度" /></el-form-item>
|
||||
<el-form-item label="重量(kg)"><el-input-number v-model="editForm.weightKg" :min="0.001" :controls="false" placeholder="请输入重量" /></el-form-item>
|
||||
<el-form-item label="长(cm)"><el-input-number v-model="editForm.lengthCm" :min="0.001" :controls="false" /></el-form-item>
|
||||
<el-form-item label="宽(cm)"><el-input-number v-model="editForm.widthCm" :min="0.001" :controls="false" /></el-form-item>
|
||||
<el-form-item label="高(cm)"><el-input-number v-model="editForm.heightCm" :min="0.001" :controls="false" /></el-form-item>
|
||||
<el-form-item label="重量(kg)"><el-input-number v-model="editForm.weightKg" :min="0.001" :controls="false" /></el-form-item>
|
||||
</div>
|
||||
<el-alert type="info" :closable="false" title="原始墨家测量记录不可变,本次保存会生成新的人工修正版并进入同步队列。" />
|
||||
</el-form>
|
||||
|
||||
@@ -385,7 +385,7 @@ onMounted(load)
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="本次出库备注"><h3 class="density-dialog-section__title">备注</h3><table class="density-table density-table--editable outbound-editor-table "><tbody><tr><td colspan="2"><el-form-item label="备注"><el-input v-model="remark" type="textarea" :autosize="{ minRows: 1, maxRows: 3 }" placeholder="请输入备注(选填)" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="本次出库备注"><h3 class="density-dialog-section__title">备注</h3><table class="density-table density-table--editable outbound-editor-table "><tbody><tr><td colspan="2"><el-form-item label="备注"><el-input v-model="remark" type="textarea" :autosize="{ minRows: 1, maxRows: 3 }" /></el-form-item></td></tr></tbody></table></section>
|
||||
</el-form>
|
||||
</div>
|
||||
</AppDialog>
|
||||
|
||||
@@ -189,11 +189,11 @@ onMounted(initialize)
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="托盘基础资料">
|
||||
<h3 class="density-dialog-section__title">托盘资料</h3>
|
||||
<table class="density-table density-table--editable pallet-editor-table"><tbody>
|
||||
<tr><td><el-form-item label="托盘编码" required><el-input v-model="form.code" maxlength="128" placeholder="请输入托盘编码" /></el-form-item></td><td><el-form-item label="托盘类型" required><el-select v-model="form.type" placeholder="请选择托盘类型"><el-option v-for="value in ['WOOD', 'PLASTIC', 'METAL', 'PAPER', 'FUMIGATION_FREE']" :key="value" :label="palletTypeLabel(value)" :value="value" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="容积(m³)" required><el-input-number v-model="form.volume" :min="0.0001" :precision="4" controls-position="right" placeholder="请输入容积" /></el-form-item></td><td><el-form-item label="采购价格(USD)" required><el-input-number v-model="form.purchasePrice" :min="0" :precision="2" controls-position="right" placeholder="请输入采购价格" /></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="托盘编码" required><el-input v-model="form.code" maxlength="128" /></el-form-item></td><td><el-form-item label="托盘类型" required><el-select v-model="form.type" placeholder="请选择托盘类型"><el-option v-for="value in ['WOOD', 'PLASTIC', 'METAL', 'PAPER', 'FUMIGATION_FREE']" :key="value" :label="palletTypeLabel(value)" :value="value" /></el-select></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="容积(m³)" required><el-input-number v-model="form.volume" :min="0.0001" :precision="4" controls-position="right" /></el-form-item></td><td><el-form-item label="采购价格(USD)" required><el-input-number v-model="form.purchasePrice" :min="0" :precision="2" controls-position="right" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item v-if="dialogMode === 'create'" label="仓库" required><el-select v-model="form.warehouseId" filterable placeholder="请选择海外仓"><el-option v-for="item in warehouses" :key="item.id" :label="`${item.warehouseName}(${item.warehouseCode})`" :value="String(item.id)" /></el-select></el-form-item><el-form-item v-else label="仓库"><span>{{ warehouseName(form.warehouseId) }}</span></el-form-item></td></tr>
|
||||
<tr><td><el-form-item label="所属 FBA 仓" required><el-select v-model="form.fbaWarehouseCode" filterable placeholder="请选择所属 FBA 仓"><el-option v-for="item in fbaWarehouses" :key="String(item.id)" :label="`${item.warehouseName}(${item.warehouseCode})`" :value="item.warehouseCode" /></el-select></el-form-item></td><td><el-form-item label="状态" required><el-select v-model="form.status" placeholder="请选择托盘状态"><el-option label="闲置" value="IDLE" /><el-option label="占用" value="OCCUPIED" /><el-option label="已报废" value="SCRAPPED" /></el-select></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="2" maxlength="500" show-word-limit placeholder="请输入备注(选填)" /></el-form-item></td></tr>
|
||||
<tr><td colspan="2"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="2" maxlength="500" show-word-limit /></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
</section>
|
||||
</el-form>
|
||||
|
||||
@@ -52,13 +52,13 @@ function openDetail(source: object) { const row = source as ProductListItem; voi
|
||||
<ContractPendingFormDialog v-model="dialogOpen" :title="dialogMode === 'create' ? '新增产品' : '编辑产品'" width="min(560px, calc(100vw - 28px))" domain="产品" confirm-text="确定">
|
||||
<el-form label-width="110px" label-position="right">
|
||||
<el-form-item label="商品SKU" required><el-input v-model="form.sku" placeholder="如 SKU-A1001" /></el-form-item>
|
||||
<el-form-item label="中文品名" required><el-input v-model="form.productName" placeholder="请输入中文品名" /></el-form-item>
|
||||
<el-form-item label="英文品名"><el-input v-model="form.englishName" placeholder="请输入英文品名" /></el-form-item>
|
||||
<el-form-item label="中文品名" required><el-input v-model="form.productName" /></el-form-item>
|
||||
<el-form-item label="英文品名"><el-input v-model="form.englishName" /></el-form-item>
|
||||
<el-form-item label="品类" required><el-select v-model="form.category" placeholder="请选择品类"><el-option v-for="value in ['电子', '家居', '服饰', '户外']" :key="value" :label="value" :value="value" /></el-select></el-form-item>
|
||||
<el-form-item label="长(cm)"><el-input-number v-model="form.length" :min="0" :precision="2" controls-position="right" placeholder="请输入长度" /></el-form-item>
|
||||
<el-form-item label="宽(cm)"><el-input-number v-model="form.width" :min="0" :precision="2" controls-position="right" placeholder="请输入宽度" /></el-form-item>
|
||||
<el-form-item label="高(cm)"><el-input-number v-model="form.height" :min="0" :precision="2" controls-position="right" placeholder="请输入高度" /></el-form-item>
|
||||
<el-form-item label="重量(kg)"><el-input-number v-model="form.weight" :min="0" :precision="3" controls-position="right" placeholder="请输入重量" /></el-form-item>
|
||||
<el-form-item label="长(cm)"><el-input-number v-model="form.length" :min="0" :precision="2" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="宽(cm)"><el-input-number v-model="form.width" :min="0" :precision="2" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="高(cm)"><el-input-number v-model="form.height" :min="0" :precision="2" controls-position="right" /></el-form-item>
|
||||
<el-form-item label="重量(kg)"><el-input-number v-model="form.weight" :min="0" :precision="3" controls-position="right" /></el-form-item>
|
||||
</el-form>
|
||||
</ContractPendingFormDialog>
|
||||
</AdminPage>
|
||||
|
||||
@@ -301,8 +301,8 @@ watch(dialogOpen, (open) => { if (!open) createIdempotencyKey.value = '' })
|
||||
<el-form class="density-form density-dialog-sections" label-position="left" label-width="120px" :disabled="formLocked">
|
||||
<template v-if="dialogMode === 'create'">
|
||||
<section class="density-dialog-section" data-tone="summary" aria-label="换标单生成方式"><table class="density-table"><tbody><tr><th scope="row">换标单号</th><td>系统自动生成</td></tr></tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标基础资料"><h3 class="density-dialog-section__title">订单信息</h3><table class="density-table density-table--editable relabel-editor-table"><tbody><tr><td><el-form-item label="关联订单" required><el-input v-model="form.relatedOrderNo" placeholder="请输入关联订单号" /></el-form-item></td><td><el-form-item label="客户" required><el-select v-model="form.customerId" filterable :loading="customersLoading" placeholder="请选择客户"><el-option v-for="item in customers" :key="String(item.id)" :label="item.tenantName" :value="String(item.id)" /></el-select></el-form-item></td></tr><tr><td><el-form-item label="公共海外收货仓" required><el-select v-model="form.warehouseId" filterable :loading="warehousesLoading" placeholder="请选择公共海外收货仓"><el-option v-for="item in warehouses" :key="item.id" :label="`${item.warehouseName} · ${item.warehouseCode}`" :value="String(item.id)" /></el-select></el-form-item></td><td><el-form-item label="截止时间" required><el-date-picker v-model="form.labelDeadline" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择截止时间" /></el-form-item></td></tr><tr><td colspan="2"><el-form-item label="换标费用(CNY)" required><el-input-number v-model="form.relabelCost" :min="0.01" :precision="2" controls-position="right" placeholder="请输入换标费用" /></el-form-item></td></tr><tr><td><el-form-item label="联系人" required><el-input v-model="form.contactName" placeholder="请输入联系人" /></el-form-item></td><td><el-form-item label="联系电话" required><el-input v-model="form.contactPhone" placeholder="请输入联系电话" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标作业要求"><h3 class="density-dialog-section__title">作业要求</h3><table class="density-table density-table--editable relabel-editor-table"><tbody><tr><td><el-form-item label="贴标要求" required><el-input v-model="form.labelRequirement" placeholder="请输入贴标要求" /></el-form-item></td><td><el-form-item label="货件号" required><el-input v-model="form.shipmentNo" placeholder="请输入货件号" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标基础资料"><h3 class="density-dialog-section__title">订单信息</h3><table class="density-table density-table--editable relabel-editor-table"><tbody><tr><td><el-form-item label="关联订单" required><el-input v-model="form.relatedOrderNo" /></el-form-item></td><td><el-form-item label="客户" required><el-select v-model="form.customerId" filterable :loading="customersLoading" placeholder="请选择客户"><el-option v-for="item in customers" :key="String(item.id)" :label="item.tenantName" :value="String(item.id)" /></el-select></el-form-item></td></tr><tr><td><el-form-item label="公共海外收货仓" required><el-select v-model="form.warehouseId" filterable :loading="warehousesLoading" placeholder="请选择公共海外收货仓"><el-option v-for="item in warehouses" :key="item.id" :label="`${item.warehouseName} · ${item.warehouseCode}`" :value="String(item.id)" /></el-select></el-form-item></td><td><el-form-item label="截止时间" required><el-date-picker v-model="form.labelDeadline" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" placeholder="请选择截止时间" /></el-form-item></td></tr><tr><td colspan="2"><el-form-item label="换标费用(CNY)" required><el-input-number v-model="form.relabelCost" :min="0.01" :precision="2" controls-position="right" /></el-form-item></td></tr><tr><td><el-form-item label="联系人" required><el-input v-model="form.contactName" /></el-form-item></td><td><el-form-item label="联系电话" required><el-input v-model="form.contactPhone" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标作业要求"><h3 class="density-dialog-section__title">作业要求</h3><table class="density-table density-table--editable relabel-editor-table"><tbody><tr><td><el-form-item label="贴标要求" required><el-input v-model="form.labelRequirement" /></el-form-item></td><td><el-form-item label="货件号" required><el-input v-model="form.shipmentNo" /></el-form-item></td></tr></tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标类型与去向">
|
||||
<el-form-item label="换标类型" required><el-select v-model="createOperation" placeholder="请选择换标类型"><el-option label="只换箱唛" value="CARTON_LABEL" /><el-option label="只换 SKU" value="SKU_LABEL" /><el-option label="箱唛和 SKU 都换" value="CARTON_AND_SKU" /></el-select></el-form-item>
|
||||
<template v-if="createOperation !== 'SKU_LABEL'"><el-form-item label="FBA 目的仓" required><el-input v-model="createDestination" placeholder="填写正式 FBA 仓码" /></el-form-item><el-form-item label="配送方式" required><el-select v-model="createDelivery" placeholder="请选择配送方式"><el-option label="普通自提" value="PICKUP" /><el-option label="平台卡车" value="TRUCK" /><el-option label="快递" value="EXPRESS" /><el-option label="亚马逊自提" value="AMAZON_PICKUP" /><el-option label="客户自提" value="CUSTOMER_PICKUP" /></el-select></el-form-item></template>
|
||||
@@ -318,7 +318,7 @@ watch(dialogOpen, (open) => { if (!open) createIdempotencyKey.value = '' })
|
||||
</tbody></table></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标审核结论"><h3 class="density-dialog-section__title">审核结论</h3><table class="density-table density-table--editable relabel-editor-table"><tbody><tr><td colspan="2"><el-form-item label="审核动作"><el-select v-model="form.status" placeholder="请选择审核动作"><el-option v-for="value in allowedStatusOptions" :key="value" :label="relabelAuditStatusLabel(value)" :value="value" /></el-select></el-form-item></td></tr></tbody></table></section>
|
||||
</template>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标备注与原因"><h3 class="density-dialog-section__title">{{ dialogMode === 'edit' ? '审核备注' : '备注' }}</h3><table class="density-table density-table--editable relabel-editor-table"><tbody><tr><td colspan="2"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请输入备注(选填)" /></el-form-item></td></tr></tbody></table><p v-if="dialogMode === 'edit'" class="density-dialog-note">审核驳回时必须填写原因。</p></section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="换标备注与原因"><h3 class="density-dialog-section__title">{{ dialogMode === 'edit' ? '审核备注' : '备注' }}</h3><table class="density-table density-table--editable relabel-editor-table"><tbody><tr><td colspan="2"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" :rows="3" maxlength="500" show-word-limit /></el-form-item></td></tr></tbody></table><p v-if="dialogMode === 'edit'" class="density-dialog-note">审核驳回时必须填写原因。</p></section>
|
||||
</el-form>
|
||||
</div>
|
||||
</AppDialog>
|
||||
|
||||
@@ -848,7 +848,7 @@ const tableColumns = computed(() =>
|
||||
</section>
|
||||
<section class="density-dialog-section" data-tone="work" aria-label="合箱备注">
|
||||
<el-alert type="info" :closable="false" title="部分包裹/箱必须生成独立新箱并贴标签;整包裹/箱合并可使用已有目标箱。箱规由 PDA 填写。提交即锁定来源库存,取消计划可释放。" />
|
||||
<table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="合箱备注(可选)"><el-input v-model="packingForm.remark" type="textarea" :rows="2" maxlength="1000" show-word-limit resize="vertical" placeholder="请输入合箱说明,最多 1000 字" /></el-form-item></td></tr></tbody></table>
|
||||
<table class="density-table density-table--editable"><tbody><tr><td><el-form-item label="合箱备注(可选)"><el-input v-model="packingForm.remark" type="textarea" :rows="2" maxlength="1000" show-word-limit resize="vertical" /></el-form-item></td></tr></tbody></table>
|
||||
</section>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
|
||||
Reference in New Issue
Block a user