优化
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
||||
|
||||
export type MojiaSkuSyncStatus = 'PENDING' | 'SUCCESS' | 'FAILED'
|
||||
export type MojiaMeasurementKind = 'BOX_LABEL' | 'SKU'
|
||||
|
||||
export interface MojiaSkuSyncRecord {
|
||||
id: string
|
||||
skuCode: string
|
||||
measurementKind: MojiaMeasurementKind
|
||||
boxCode: string
|
||||
inboundCode?: string | null
|
||||
skuCode?: string | null
|
||||
lengthCm: number
|
||||
widthCm: number
|
||||
heightCm: number
|
||||
@@ -13,7 +17,7 @@ export interface MojiaSkuSyncRecord {
|
||||
imageUrl?: string | null
|
||||
measuredAt?: string | null
|
||||
receivedAt?: string | null
|
||||
syncStatus: MojiaSkuSyncStatus
|
||||
syncStatus?: MojiaSkuSyncStatus | null
|
||||
syncFailureCode?: string | null
|
||||
syncFailureReason?: string | null
|
||||
lingxingSkuId?: string | null
|
||||
@@ -32,7 +36,8 @@ export interface MojiaSkuSyncPage {
|
||||
export interface MojiaSkuSyncQuery {
|
||||
page: number
|
||||
size: number
|
||||
skuCode?: string
|
||||
code?: string
|
||||
measurementKind?: MojiaMeasurementKind
|
||||
syncStatus?: MojiaSkuSyncStatus
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { getApiErrorMessage } from '@/shared/api/http'
|
||||
import {
|
||||
getMojiaSkuSyncConfig, listMojiaSkuSync, retryMojiaSkuSync, submitLingxingVerificationCode, testLingxingConnection, updateMojiaSkuSync,
|
||||
type LingxingConnectionTestResult, type MojiaSkuSyncRecord, type MojiaSkuSyncStatus,
|
||||
type LingxingConnectionTestResult, type MojiaSkuSyncRecord, type MojiaSkuSyncStatus, type MojiaMeasurementKind,
|
||||
} from '../api/mojiaSkuSync'
|
||||
|
||||
const permission = {
|
||||
@@ -37,14 +37,16 @@ const submittingVerification = ref(false)
|
||||
const pendingVerificationAction = ref<{ type: 'test' } | { type: 'retry', id: string, revision: number } | null>(null)
|
||||
const page = ref(1)
|
||||
const size = ref(20)
|
||||
const form = reactive({ skuCode: '', syncStatus: '' as '' | MojiaSkuSyncStatus })
|
||||
const form = reactive({ code: '', measurementKind: '' as '' | MojiaMeasurementKind, syncStatus: '' as '' | MojiaSkuSyncStatus })
|
||||
const editOpen = ref(false)
|
||||
const editing = ref<MojiaSkuSyncRecord | null>(null)
|
||||
const editForm = reactive({ skuCode: '', lengthCm: 0, widthCm: 0, heightCm: 0, weightKg: 0, revision: 0 })
|
||||
|
||||
const columns: DataTableColumn[] = [
|
||||
{ key: 'actions', label: '操作', width: 190, fixed: 'left', slotName: 'actions' },
|
||||
{ key: 'skuCode', prop: 'skuCode', label: 'SKU', minWidth: 180, showOverflowTooltip: true },
|
||||
{ key: 'sourceCode', label: '上传标识', minWidth: 180, showOverflowTooltip: true, slotName: 'sourceCode' },
|
||||
{ key: 'kind', label: '类型', width: 110, slotName: 'kind' },
|
||||
{ key: 'inboundCode', prop: 'inboundCode', label: '命中入仓码', minWidth: 150, showOverflowTooltip: true },
|
||||
{ key: 'image', label: '测量图片', width: 110, slotName: 'image' },
|
||||
{ key: 'dimensions', label: '长 × 宽 × 高(cm)', width: 170, slotName: 'dimensions' },
|
||||
{ key: 'weightKg', prop: 'weightKg', label: '重量(kg)', width: 110 },
|
||||
@@ -65,11 +67,11 @@ async function load() {
|
||||
loading.value = true
|
||||
error.value = ''
|
||||
try {
|
||||
const result = await listMojiaSkuSync({ page: page.value, size: size.value, skuCode: form.skuCode || undefined, syncStatus: form.syncStatus || undefined })
|
||||
const result = await listMojiaSkuSync({ page: page.value, size: size.value, code: form.code || undefined, measurementKind: form.measurementKind || undefined, syncStatus: form.syncStatus || undefined })
|
||||
rows.value = result.records
|
||||
total.value = result.total
|
||||
} catch (cause) {
|
||||
error.value = getApiErrorMessage(cause, 'SKU同步记录加载失败')
|
||||
error.value = getApiErrorMessage(cause, '称重机器上传记录加载失败')
|
||||
} finally { loading.value = false }
|
||||
}
|
||||
|
||||
@@ -82,14 +84,22 @@ async function loadConfig() {
|
||||
}
|
||||
|
||||
function search() { page.value = 1; void load() }
|
||||
function reset() { form.skuCode = ''; form.syncStatus = ''; search() }
|
||||
function reset() { form.code = ''; form.measurementKind = ''; form.syncStatus = ''; search() }
|
||||
function formatTime(value?: string | null) { return value ? value.replace('T', ' ').slice(0, 19) : '—' }
|
||||
function asRecord(row: unknown) { return row as MojiaSkuSyncRecord }
|
||||
function syncLabel(row: unknown) { return statusLabel[asRecord(row).syncStatus] }
|
||||
function syncTagType(row: unknown) { return statusType[asRecord(row).syncStatus] }
|
||||
function syncLabel(row: unknown) {
|
||||
const value = asRecord(row)
|
||||
if (value.measurementKind === 'BOX_LABEL') return value.inboundCode ? '已命中入仓码' : '未命中'
|
||||
return value.syncStatus ? statusLabel[value.syncStatus] : '—'
|
||||
}
|
||||
function syncTagType(row: unknown) {
|
||||
const value = asRecord(row)
|
||||
if (value.measurementKind === 'BOX_LABEL') return value.inboundCode ? 'success' : 'warning'
|
||||
return value.syncStatus ? statusType[value.syncStatus] : 'info'
|
||||
}
|
||||
|
||||
async function testConnection() {
|
||||
const skuCode = form.skuCode.trim()
|
||||
const skuCode = form.code.trim()
|
||||
if (!skuCode) { ElMessage.warning('请先输入要查询的 SKU'); return }
|
||||
testingConnection.value = true
|
||||
try {
|
||||
@@ -129,7 +139,7 @@ async function submitVerification() {
|
||||
|
||||
function openEdit(row: MojiaSkuSyncRecord) {
|
||||
editing.value = row
|
||||
Object.assign(editForm, { skuCode: row.skuCode, lengthCm: row.lengthCm, widthCm: row.widthCm, heightCm: row.heightCm, weightKg: row.weightKg, revision: row.revision })
|
||||
Object.assign(editForm, { skuCode: row.skuCode || '', lengthCm: row.lengthCm, widthCm: row.widthCm, heightCm: row.heightCm, weightKg: row.weightKg, revision: row.revision })
|
||||
editOpen.value = true
|
||||
}
|
||||
|
||||
@@ -177,7 +187,7 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
|
||||
|
||||
<template>
|
||||
<AdminPage class="admin-density mojia-sku-sync-page">
|
||||
<ListPageLayout aria-label="SKU同步">
|
||||
<ListPageLayout aria-label="称重机器">
|
||||
<section class="surface-panel table-panel" :aria-busy="loading">
|
||||
<el-alert v-if="error" type="error" :title="error" show-icon :closable="false" />
|
||||
<el-alert
|
||||
@@ -187,10 +197,11 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
<DataTable :data="rows" :columns="columns" :loading="loading" row-key="id" border stripe empty-text="暂无墨家 SKU 测量记录">
|
||||
<DataTable :data="rows" :columns="columns" :loading="loading" row-key="id" border stripe empty-text="暂无墨家机器上传记录">
|
||||
<template #toolbar-start>
|
||||
<div class="sync-filters">
|
||||
<el-input v-model.trim="form.skuCode" clearable placeholder="搜索 SKU" @keyup.enter="search" />
|
||||
<el-input v-model.trim="form.code" clearable placeholder="搜索箱码或 SKU" @keyup.enter="search" />
|
||||
<el-select v-model="form.measurementKind" clearable placeholder="上传类型" style="width: 130px"><el-option label="箱码" value="BOX_LABEL" /><el-option label="SKU" value="SKU" /></el-select>
|
||||
<el-select v-model="form.syncStatus" clearable placeholder="同步状态" style="width: 140px">
|
||||
<el-option v-for="(label, value) in statusLabel" :key="value" :label="label" :value="value" />
|
||||
</el-select>
|
||||
@@ -203,9 +214,11 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
|
||||
<template #actions="{ row }">
|
||||
<div class="density-actions">
|
||||
<el-button v-if="canEdit" class="density-action" @click="openEdit(asRecord(row))"><Edit3 :size="15" />编辑</el-button>
|
||||
<el-button v-if="canRetry && row.syncStatus !== 'SUCCESS'" class="density-action" data-tone="primary" :loading="actionId === row.id" @click="retry(asRecord(row))"><RotateCw :size="15" />人工推送</el-button>
|
||||
<el-button v-if="canRetry && row.measurementKind === 'SKU' && row.syncStatus !== 'SUCCESS'" class="density-action" data-tone="primary" :loading="actionId === row.id" @click="retry(asRecord(row))"><RotateCw :size="15" />人工推送</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #sourceCode="{ row }">{{ row.measurementKind === 'SKU' ? row.skuCode : row.boxCode }}</template>
|
||||
<template #kind="{ row }">{{ row.measurementKind === 'SKU' ? 'SKU测量' : '箱码测量' }}</template>
|
||||
<template #image="{ row }"><el-image v-if="row.imageUrl" :src="row.imageUrl" fit="cover" class="sync-image" preview-teleported /><span v-else>—</span></template>
|
||||
<template #dimensions="{ row }">{{ row.lengthCm }} × {{ row.widthCm }} × {{ row.heightCm }}</template>
|
||||
<template #syncStatus="{ row }"><el-tag size="small" :type="syncTagType(row)">{{ syncLabel(row) }}</el-tag></template>
|
||||
|
||||
@@ -140,6 +140,6 @@ export const overseasWarehouseRoutes = [
|
||||
path: 'general/mojia-sku-sync',
|
||||
name: 'mojia-sku-sync',
|
||||
component: () => import('./pages/MojiaSkuSyncView.vue'),
|
||||
meta: { title: 'SKU同步', description: '查看墨家测量数据并同步领星 SKU 尺寸重量', permission: permission.mojiaSkuSyncList },
|
||||
meta: { title: '称重机器', description: '查看墨家机器上传的箱码和 SKU 测量记录', permission: permission.mojiaSkuSyncList },
|
||||
},
|
||||
] satisfies RouteRecordRaw[]
|
||||
|
||||
Reference in New Issue
Block a user