@@ -11,7 +11,7 @@ import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { getApiErrorMessage } from '@/shared/api/http'
import { getApiErrorMessage } from '@/shared/api/http'
import {
import {
getMojiaSkuSyncConfig , listMojiaSkuSync , retryMojiaSkuSync , submitLingxingVerificationCode , testLingxingConnection , updateMojiaSkuSync ,
getMojiaSkuSyncConfig , listMojiaSkuSync , retryMojiaSkuSync , submitLingxingVerificationCode , testLingxingConnection , updateMojiaSkuSync ,
type LingxingConnectionTestResult , type MojiaSkuSyncRecord , type MojiaSkuSyncStatus ,
type LingxingConnectionTestResult , type MojiaSkuSyncRecord , type MojiaSkuSyncStatus , type MojiaMeasurementKind ,
} from '../api/mojiaSkuSync'
} from '../api/mojiaSkuSync'
const permission = {
const permission = {
@@ -37,14 +37,16 @@ const submittingVerification = ref(false)
const pendingVerificationAction = ref < { type : 'test' } | { type : 'retry' , id : string , revision : number } | null > ( null )
const pendingVerificationAction = ref < { type : 'test' } | { type : 'retry' , id : string , revision : number } | null > ( null )
const page = ref ( 1 )
const page = ref ( 1 )
const size = ref ( 20 )
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 editOpen = ref ( false )
const editing = ref < MojiaSkuSyncRecord | null > ( null )
const editing = ref < MojiaSkuSyncRecord | null > ( null )
const editForm = reactive ( { skuCode : '' , lengthCm : 0 , widthCm : 0 , heightCm : 0 , weightKg : 0 , revision : 0 } )
const editForm = reactive ( { skuCode : '' , lengthCm : 0 , widthCm : 0 , heightCm : 0 , weightKg : 0 , revision : 0 } )
const columns : DataTableColumn [ ] = [
const columns : DataTableColumn [ ] = [
{ key : 'actions' , label : '操作' , width : 190 , fixed : 'left' , slotName : 'actions' } ,
{ key : 'actions' , label : '操作' , width : 190 , fixed : 'left' , slotName : 'actions' } ,
{ key : 'sku Code' , prop : 'skuCode ' , label : 'SKU' , minWidth : 180 , showOverflowTooltip : true } ,
{ key : 'source Code' , 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 : 'image' , label : '测量图片' , width : 110 , slotName : 'image' } ,
{ key : 'dimensions' , label : '长 × 宽 × 高(cm) ' , width : 170 , slotName : 'dimensions' } ,
{ key : 'dimensions' , label : '长 × 宽 × 高(cm) ' , width : 170 , slotName : 'dimensions' } ,
{ key : 'weightKg' , prop : 'weightKg' , label : '重量(kg) ' , width : 110 } ,
{ key : 'weightKg' , prop : 'weightKg' , label : '重量(kg) ' , width : 110 } ,
@@ -65,11 +67,11 @@ async function load() {
loading . value = true
loading . value = true
error . value = ''
error . value = ''
try {
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
rows . value = result . records
total . value = result . total
total . value = result . total
} catch ( cause ) {
} catch ( cause ) {
error . value = getApiErrorMessage ( cause , 'SKU同步 记录加载失败' )
error . value = getApiErrorMessage ( cause , '称重机器上传 记录加载失败' )
} finally { loading . value = false }
} finally { loading . value = false }
}
}
@@ -82,14 +84,22 @@ async function loadConfig() {
}
}
function search ( ) { page . value = 1 ; void load ( ) }
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 formatTime ( value ? : string | null ) { return value ? value . replace ( 'T' , ' ' ) . slice ( 0 , 19 ) : '—' }
function asRecord ( row : unknown ) { return row as MojiaSkuSyncRecord }
function asRecord ( row : unknown ) { return row as MojiaSkuSyncRecord }
function syncLabel ( row : unknown ) { return statusLabel [ asRecord ( row ) . syncStatus ] }
function syncLabel ( row : unknown ) {
function syncTagType ( row : unknown ) { return statusType [ asRecord ( row ) . syncStatus ] }
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 ( ) {
async function testConnection ( ) {
const skuCode = form . skuCode . trim ( )
const skuCode = form . code . trim ( )
if ( ! skuCode ) { ElMessage . warning ( '请先输入要查询的 SKU' ) ; return }
if ( ! skuCode ) { ElMessage . warning ( '请先输入要查询的 SKU' ) ; return }
testingConnection . value = true
testingConnection . value = true
try {
try {
@@ -129,7 +139,7 @@ async function submitVerification() {
function openEdit ( row : MojiaSkuSyncRecord ) {
function openEdit ( row : MojiaSkuSyncRecord ) {
editing . value = row
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
editOpen . value = true
}
}
@@ -177,7 +187,7 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
< template >
< template >
< AdminPage class = "admin-density mojia-sku-sync-page" >
< AdminPage class = "admin-density mojia-sku-sync-page" >
< ListPageLayout aria -label = " SKU同步 " >
< ListPageLayout aria -label = " 称重机器 " >
< section class = "surface-panel table-panel" :aria-busy = "loading" >
< section class = "surface-panel table-panel" :aria-busy = "loading" >
< el-alert v-if = "error" type="error" :title="error" show-icon :closable="false" / >
< el-alert v-if = "error" type="error" :title="error" show-icon :closable="false" / >
< el-alert
< el-alert
@@ -187,10 +197,11 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
show -icon
show -icon
:closable = "false"
: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 >
< template # toolbar -start >
< div class = "sync-filters" >
< 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-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 -option v-for = "(label, value) in statusLabel" :key="value" :label="label" :value="value" / >
< / el-select >
< / el-select >
@@ -203,9 +214,11 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
< template # actions = "{ row }" >
< template # actions = "{ row }" >
< div class = "density-actions" >
< 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 = "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 >
< / div >
< / template >
< / 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 # 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 # dimensions = "{ row }" > { { row . lengthCm } } × { { row . widthCm } } × { { row . heightCm } } < / template >
< template # syncStatus = "{ row }" > < el-tag size = "small" :type = "syncTagType(row)" > { { syncLabel ( row ) } } < / el-tag > < / template >
< template # syncStatus = "{ row }" > < el-tag size = "small" :type = "syncTagType(row)" > { { syncLabel ( row ) } } < / el-tag > < / template >