fix: improve return receipt client display
This commit is contained in:
@@ -21,3 +21,24 @@ test('新建退货预报使用加宽的双列表单弹窗', () => {
|
||||
assert.match(view, /title="新建退货预报" width="1120px"/)
|
||||
assert.match(view, /return-create-form \{ display:grid; grid-template-columns:repeat\(2,minmax\(0,1fr\)\)/)
|
||||
})
|
||||
|
||||
test('退货列表和详情使用客户可读仓库、状态与时间', () => {
|
||||
assert.match(view, /function operationWarehouseLabel\(warehouseId: string\)/)
|
||||
assert.match(view, /return warehouse \? warehouseLabel\(warehouse\) : '未关联'/)
|
||||
assert.match(view, /PENDING_RECEIPT: '待签收'/)
|
||||
assert.match(view, /PARTIALLY_RECEIVED: '部分签收'/)
|
||||
assert.match(view, /COMPLETED: '已完成'/)
|
||||
assert.match(view, /function formatDateTime\(value\?: string \| null\)/)
|
||||
assert.match(view, /\{\{ operationWarehouseLabel\(row\.overseasWarehouseId\) \}\}/)
|
||||
assert.match(view, /\{\{ statusLabel\(row\.status\) \}\}/)
|
||||
assert.match(view, /\{\{ formatDateTime\(row\.createdAt\) \}\}/)
|
||||
assert.doesNotMatch(view, /<el-table-column prop="overseasWarehouseId"/)
|
||||
assert.doesNotMatch(view, /\{\{ selected\.order\.overseasWarehouseId \}\}/)
|
||||
})
|
||||
|
||||
test('可操作退货表格把操作列固定在最左侧', () => {
|
||||
const mainTable = view.slice(view.indexOf('<el-table v-loading="loading"'), view.indexOf('<el-pagination'))
|
||||
const createTable = view.slice(view.indexOf('<el-table :data="form.items"'), view.indexOf('</el-table>', view.indexOf('<el-table :data="form.items"')))
|
||||
assert.match(mainTable, /^<el-table[\s\S]*?<el-table-column label="操作" width="90" fixed="left">/)
|
||||
assert.match(createTable, /^<el-table[\s\S]*?<el-table-column label="操作" width="80" fixed="left">/)
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Plus, Search } from '@lucide/vue'
|
||||
import { getMerchantWarehouses, type MerchantWarehouse } from '@/modules/first-leg/api/firstLeg'
|
||||
import { createReturnOrder, getReturnOrder, listReturnOrders, type ReturnOrderDetail, type ReturnOrderSummary } from '../api/returnOrders'
|
||||
import { createReturnOrder, getReturnOrder, listReturnOrders, type ReturnOrderDetail, type ReturnOrderSummary, type ReturnReceipt } from '../api/returnOrders'
|
||||
|
||||
const loading = ref(false)
|
||||
const creating = ref(false)
|
||||
@@ -32,6 +32,10 @@ const duplicateSkuIds = computed(() => {
|
||||
})
|
||||
function resetForm() { Object.assign(form, { overseasWarehouseId: '', warehouseContactName: '', warehouseContactPhone: '', customerReferenceNo: '', remark: '', needRelabel: false, items: [emptySku()] }) }
|
||||
function warehouseLabel(warehouse: MerchantWarehouse) { return `${warehouse.warehouseName} · ${warehouse.warehouseCode}` }
|
||||
function operationWarehouseLabel(warehouseId: string) {
|
||||
const warehouse = operationWarehouses.value.find(item => String(item.id) === String(warehouseId))
|
||||
return warehouse ? warehouseLabel(warehouse) : '未关联'
|
||||
}
|
||||
function selectOperationWarehouse() {
|
||||
const warehouse = operationWarehouses.value.find(item => String(item.id) === form.overseasWarehouseId)
|
||||
form.warehouseContactName = warehouse?.contactName || ''
|
||||
@@ -53,7 +57,7 @@ async function loadOperationWarehouses() {
|
||||
function openCreate() {
|
||||
resetForm()
|
||||
showCreate.value = true
|
||||
void loadOperationWarehouses()
|
||||
if (!operationWarehouses.value.length && !operationWarehousesLoading.value) void loadOperationWarehouses()
|
||||
}
|
||||
function addItem() { form.items.push(emptySku()) }
|
||||
function removeItem(index: number) { if (form.items.length > 1) form.items.splice(index, 1) }
|
||||
@@ -75,7 +79,17 @@ async function submit() {
|
||||
} finally { creating.value = false }
|
||||
}
|
||||
function statusType(status: string) { return status === 'COMPLETED' ? 'success' : status === 'PARTIALLY_RECEIVED' ? 'warning' : 'info' }
|
||||
onMounted(load)
|
||||
function statusLabel(status: string) {
|
||||
return ({ PENDING_RECEIPT: '待签收', PARTIALLY_RECEIVED: '部分签收', COMPLETED: '已完成' } as Record<string, string>)[status] ?? '未知状态'
|
||||
}
|
||||
function startedByLabel(startedBy: ReturnReceipt['startedBy']) { return startedBy === 'SKU' ? 'SKU 查询' : '退货单号' }
|
||||
function formatDateTime(value?: string | null) {
|
||||
if (!value) return '—'
|
||||
const date = new Date(value)
|
||||
if (Number.isNaN(date.getTime())) return '—'
|
||||
return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).format(date)
|
||||
}
|
||||
onMounted(() => { void Promise.all([load(), loadOperationWarehouses()]) })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -89,16 +103,16 @@ onMounted(load)
|
||||
<el-button @click="query.page=1; load()"><Search :size="16" />查询</el-button>
|
||||
</div>
|
||||
<el-table v-loading="loading" :data="rows" @row-click="row => openDetail(row.returnNo)">
|
||||
<el-table-column label="操作" width="90" fixed="left"><template #default="{ row }"><el-button link type="primary" @click.stop="openDetail(row.returnNo)">详情</el-button></template></el-table-column>
|
||||
<el-table-column prop="returnNo" label="退货单号" min-width="190" />
|
||||
<el-table-column prop="customerReferenceNo" label="客户参考号" min-width="150" />
|
||||
<el-table-column prop="overseasWarehouseId" label="操作仓" min-width="120" />
|
||||
<el-table-column label="操作仓" min-width="190"><template #default="{ row }">{{ operationWarehouseLabel(row.overseasWarehouseId) }}</template></el-table-column>
|
||||
<el-table-column label="换标" width="100"><template #default="{ row }"><el-tag v-if="row.needRelabel" type="warning">需要换标</el-tag><span v-else>否</span></template></el-table-column>
|
||||
<el-table-column prop="skuTypes" label="SKU种类" width="100" />
|
||||
<el-table-column prop="expectedQuantity" label="预报数量" width="110" />
|
||||
<el-table-column prop="receivedQuantity" label="实收数量" width="110" />
|
||||
<el-table-column label="状态" width="130"><template #default="{ row }"><el-tag :type="statusType(row.status)">{{ row.status }}</el-tag></template></el-table-column>
|
||||
<el-table-column prop="createdAt" label="创建时间" min-width="170" />
|
||||
<el-table-column label="操作" width="90" fixed="right"><template #default="{ row }"><el-button link type="primary" @click.stop="openDetail(row.returnNo)">详情</el-button></template></el-table-column>
|
||||
<el-table-column label="状态" width="130"><template #default="{ row }"><el-tag :type="statusType(row.status)">{{ statusLabel(row.status) }}</el-tag></template></el-table-column>
|
||||
<el-table-column label="创建时间" min-width="180"><template #default="{ row }">{{ formatDateTime(row.createdAt) }}</template></el-table-column>
|
||||
</el-table>
|
||||
<el-pagination v-model:current-page="query.page" v-model:page-size="query.size" :total="total" layout="total, prev, pager, next" @current-change="load" />
|
||||
|
||||
@@ -114,14 +128,14 @@ onMounted(load)
|
||||
<div class="return-relabel-option"><span>换标</span><el-checkbox v-model="form.needRelabel">需要换标</el-checkbox></div>
|
||||
<div class="items-hint">客户只需填写预计退回的 SKU 和数量;快递单号由仓库签收时按实际包裹扫描绑定。</div>
|
||||
<el-table :data="form.items" row-key="id" size="small">
|
||||
<el-table-column label="操作" width="80" fixed="left"><template #default="{ $index }"><el-button link type="danger" :disabled="form.items.length === 1" @click="removeItem($index)">删除</el-button></template></el-table-column>
|
||||
<el-table-column label="SKU" min-width="200"><template #default="{ row }"><div><el-input v-model="row.skuCode" :class="{ 'duplicate-sku-input': duplicateSkuIds.has(row.id) }" placeholder="填写 SKU" @blur="row.skuCode = row.skuCode.trim()" /><div v-if="duplicateSkuIds.has(row.id)" class="duplicate-sku-error">该 SKU 已在明细中填写</div></div></template></el-table-column>
|
||||
<el-table-column label="中文品名" min-width="260"><template #default="{ row }"><el-input v-model="row.productNameZh" placeholder="填写中文品名(选填)" /></template></el-table-column>
|
||||
<el-table-column label="预报数量" width="160"><template #default="{ row }"><el-input-number v-model="row.expectedQuantity" :min="1" controls-position="right" placeholder="数量" /></template></el-table-column>
|
||||
<el-table-column label="操作" width="80"><template #default="{ $index }"><el-button link type="danger" :disabled="form.items.length === 1" @click="removeItem($index)">删除</el-button></template></el-table-column>
|
||||
</el-table>
|
||||
<template #footer><el-button @click="showCreate=false">取消</el-button><el-button type="primary" :loading="creating" @click="submit">提交预报</el-button></template>
|
||||
</el-dialog>
|
||||
<el-drawer v-model="showDetail" title="退货签收详情" size="760px"><template v-if="selected"><el-descriptions :column="2" border><el-descriptions-item label="退货单号">{{ selected.order.returnNo }}</el-descriptions-item><el-descriptions-item label="状态"><el-tag :type="statusType(selected.order.status)">{{ selected.order.status }}</el-tag></el-descriptions-item><el-descriptions-item label="操作仓">{{ selected.order.overseasWarehouseId }}</el-descriptions-item><el-descriptions-item label="实收 / 预报">{{ selected.order.receivedQuantity }} / {{ selected.order.expectedQuantity }}</el-descriptions-item><el-descriptions-item label="中转仓联系人">{{ selected.order.warehouseContactName || '—' }}</el-descriptions-item><el-descriptions-item label="中转仓联系电话">{{ selected.order.warehouseContactPhone || '—' }}</el-descriptions-item></el-descriptions><p v-if="selected.remark" class="remark">备注:{{ selected.remark }}</p><h3>预报与实收</h3><el-table :data="selected.items" size="small"><el-table-column prop="skuCode" label="SKU" /><el-table-column prop="productNameZh" label="中文品名" /><el-table-column prop="expectedQuantity" label="预报" /><el-table-column prop="receivedQuantity" label="实收" /></el-table><h3>签收批次</h3><el-table :data="selected.receipts" size="small"><el-table-column prop="receiptBatchNo" label="批次号" min-width="170" /><el-table-column prop="receiptNo" label="签收单号" min-width="170" /><el-table-column prop="cartonMark" label="箱号" min-width="190" /><el-table-column prop="trackingNo" label="快递单号"><template #default="{ row }">{{ row.trackingNo || '无快递单号' }}</template></el-table-column><el-table-column prop="startedBy" label="开始方式" /><el-table-column prop="receivedQuantity" label="实收" /><el-table-column prop="signedAt" label="签收时间" min-width="170" /></el-table></template></el-drawer>
|
||||
<el-drawer v-model="showDetail" title="退货签收详情" size="760px"><template v-if="selected"><el-descriptions :column="2" border><el-descriptions-item label="退货单号">{{ selected.order.returnNo }}</el-descriptions-item><el-descriptions-item label="状态"><el-tag :type="statusType(selected.order.status)">{{ statusLabel(selected.order.status) }}</el-tag></el-descriptions-item><el-descriptions-item label="操作仓">{{ operationWarehouseLabel(selected.order.overseasWarehouseId) }}</el-descriptions-item><el-descriptions-item label="实收 / 预报">{{ selected.order.receivedQuantity }} / {{ selected.order.expectedQuantity }}</el-descriptions-item><el-descriptions-item label="中转仓联系人">{{ selected.order.warehouseContactName || '—' }}</el-descriptions-item><el-descriptions-item label="中转仓联系电话">{{ selected.order.warehouseContactPhone || '—' }}</el-descriptions-item></el-descriptions><p v-if="selected.remark" class="remark">备注:{{ selected.remark }}</p><h3>预报与实收</h3><el-table :data="selected.items" size="small"><el-table-column prop="skuCode" label="SKU" /><el-table-column prop="productNameZh" label="中文品名" /><el-table-column prop="expectedQuantity" label="预报" /><el-table-column prop="receivedQuantity" label="实收" /></el-table><h3>签收批次</h3><el-table :data="selected.receipts" size="small"><el-table-column prop="receiptBatchNo" label="批次号" min-width="170" /><el-table-column prop="receiptNo" label="签收单号" min-width="170" /><el-table-column prop="cartonMark" label="箱号" min-width="190" /><el-table-column prop="trackingNo" label="快递单号"><template #default="{ row }">{{ row.trackingNo || '无快递单号' }}</template></el-table-column><el-table-column label="开始方式"><template #default="{ row }">{{ startedByLabel(row.startedBy) }}</template></el-table-column><el-table-column prop="receivedQuantity" label="实收" /><el-table-column label="签收时间" min-width="180"><template #default="{ row }">{{ formatDateTime(row.signedAt) }}</template></el-table-column></el-table></template></el-drawer>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user