feat: add lingxing connection test action
This commit is contained in:
@@ -40,6 +40,25 @@ export interface MojiaSkuSyncConfig {
|
|||||||
autoSyncEnabled: boolean
|
autoSyncEnabled: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LingxingWarehouseTestResult {
|
||||||
|
whCode: string
|
||||||
|
reachable: boolean
|
||||||
|
matched: boolean
|
||||||
|
maintained: boolean
|
||||||
|
productSku?: string | null
|
||||||
|
barcode?: string | null
|
||||||
|
length?: number | null
|
||||||
|
width?: number | null
|
||||||
|
height?: number | null
|
||||||
|
weight?: number | null
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LingxingConnectionTestResult {
|
||||||
|
skuCode: string
|
||||||
|
warehouses: LingxingWarehouseTestResult[]
|
||||||
|
}
|
||||||
|
|
||||||
const basePath = '/platform/v1/firstleg/mojia-sku-sync'
|
const basePath = '/platform/v1/firstleg/mojia-sku-sync'
|
||||||
|
|
||||||
export async function listMojiaSkuSync(query: MojiaSkuSyncQuery) {
|
export async function listMojiaSkuSync(query: MojiaSkuSyncQuery) {
|
||||||
@@ -56,6 +75,13 @@ export async function getMojiaSkuSyncConfig() {
|
|||||||
return unwrapApiResponse(response)
|
return unwrapApiResponse(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function testLingxingConnection(skuCode: string) {
|
||||||
|
const response = await http.post<ApiEnvelope<LingxingConnectionTestResult>, ApiEnvelope<LingxingConnectionTestResult>>(
|
||||||
|
`${basePath}/test-connection`, { skuCode },
|
||||||
|
)
|
||||||
|
return unwrapApiResponse(response)
|
||||||
|
}
|
||||||
|
|
||||||
export async function updateMojiaSkuSync(id: string, data: {
|
export async function updateMojiaSkuSync(id: string, data: {
|
||||||
skuCode: string
|
skuCode: string
|
||||||
lengthCm: number
|
lengthCm: number
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import '@/styles/adminDensity.css'
|
import '@/styles/adminDensity.css'
|
||||||
import { computed, onMounted, reactive, ref } from 'vue'
|
import { computed, onMounted, reactive, ref } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { Edit3, RefreshCw, RotateCw } from '@lucide/vue'
|
import { Cable, Edit3, RefreshCw, RotateCw } from '@lucide/vue'
|
||||||
import AdminPage from '@/shared/components/AdminPage.vue'
|
import AdminPage from '@/shared/components/AdminPage.vue'
|
||||||
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
|
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
|
||||||
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
||||||
@@ -10,8 +10,8 @@ import AppDialog from '@/shared/components/AppDialog.vue'
|
|||||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||||
import { getApiErrorMessage } from '@/shared/api/http'
|
import { getApiErrorMessage } from '@/shared/api/http'
|
||||||
import {
|
import {
|
||||||
getMojiaSkuSyncConfig, listMojiaSkuSync, retryMojiaSkuSync, updateMojiaSkuSync,
|
getMojiaSkuSyncConfig, listMojiaSkuSync, retryMojiaSkuSync, testLingxingConnection, updateMojiaSkuSync,
|
||||||
type MojiaSkuSyncRecord, type MojiaSkuSyncStatus,
|
type LingxingConnectionTestResult, type MojiaSkuSyncRecord, type MojiaSkuSyncStatus,
|
||||||
} from '../api/mojiaSkuSync'
|
} from '../api/mojiaSkuSync'
|
||||||
|
|
||||||
const permission = {
|
const permission = {
|
||||||
@@ -28,6 +28,9 @@ const loading = ref(false)
|
|||||||
const autoSyncEnabled = ref(false)
|
const autoSyncEnabled = ref(false)
|
||||||
const error = ref('')
|
const error = ref('')
|
||||||
const actionId = ref('')
|
const actionId = ref('')
|
||||||
|
const testingConnection = ref(false)
|
||||||
|
const testOpen = ref(false)
|
||||||
|
const testResult = ref<LingxingConnectionTestResult | 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({ skuCode: '', syncStatus: '' as '' | MojiaSkuSyncStatus })
|
||||||
@@ -81,6 +84,17 @@ function asRecord(row: unknown) { return row as MojiaSkuSyncRecord }
|
|||||||
function syncLabel(row: unknown) { return statusLabel[asRecord(row).syncStatus] }
|
function syncLabel(row: unknown) { return statusLabel[asRecord(row).syncStatus] }
|
||||||
function syncTagType(row: unknown) { return statusType[asRecord(row).syncStatus] }
|
function syncTagType(row: unknown) { return statusType[asRecord(row).syncStatus] }
|
||||||
|
|
||||||
|
async function testConnection() {
|
||||||
|
const skuCode = form.skuCode.trim()
|
||||||
|
if (!skuCode) { ElMessage.warning('请先输入要查询的 SKU'); return }
|
||||||
|
testingConnection.value = true
|
||||||
|
try {
|
||||||
|
testResult.value = await testLingxingConnection(skuCode)
|
||||||
|
testOpen.value = true
|
||||||
|
} catch (cause) { ElMessage.error(getApiErrorMessage(cause, '领星连接测试失败')) }
|
||||||
|
finally { testingConnection.value = false }
|
||||||
|
}
|
||||||
|
|
||||||
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 })
|
||||||
@@ -137,6 +151,7 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
|
|||||||
</el-select>
|
</el-select>
|
||||||
<el-button type="primary" @click="search">查询</el-button>
|
<el-button type="primary" @click="search">查询</el-button>
|
||||||
<el-button @click="reset">重置</el-button>
|
<el-button @click="reset">重置</el-button>
|
||||||
|
<el-button :loading="testingConnection" @click="testConnection"><Cable :size="16" />测试连接</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #toolbar-actions><el-button :loading="loading" @click="load"><RefreshCw :size="16" />刷新</el-button></template>
|
<template #toolbar-actions><el-button :loading="loading" @click="load"><RefreshCw :size="16" />刷新</el-button></template>
|
||||||
@@ -168,6 +183,17 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
|
|||||||
<el-alert type="info" :closable="false" title="原始墨家测量记录不可变,本次保存会生成新的人工修正版并进入同步队列。" />
|
<el-alert type="info" :closable="false" title="原始墨家测量记录不可变,本次保存会生成新的人工修正版并进入同步队列。" />
|
||||||
</el-form>
|
</el-form>
|
||||||
</AppDialog>
|
</AppDialog>
|
||||||
|
<AppDialog v-model="testOpen" class="admin-density-dialog" title="领星连接测试" width="min(720px, calc(100vw - 28px))" :show-cancel="false" confirm-text="关闭" @confirm="testOpen = false">
|
||||||
|
<div v-if="testResult" class="connection-result">
|
||||||
|
<div class="connection-result__sku">查询 SKU:<strong>{{ testResult.skuCode }}</strong></div>
|
||||||
|
<el-table :data="testResult.warehouses" border>
|
||||||
|
<el-table-column prop="whCode" label="仓库" width="90" />
|
||||||
|
<el-table-column label="结果" width="110"><template #default="{ row }"><el-tag :type="row.matched ? 'success' : 'danger'">{{ row.matched ? '已命中' : '未命中' }}</el-tag></template></el-table-column>
|
||||||
|
<el-table-column label="维护状态" width="110"><template #default="{ row }">{{ row.matched ? (row.maintained ? '已维护' : '待维护') : '—' }}</template></el-table-column>
|
||||||
|
<el-table-column label="领星数据" min-width="220"><template #default="{ row }">{{ row.matched ? `${row.length ?? 0} × ${row.width ?? 0} × ${row.height ?? 0} cm / ${row.weight ?? 0} kg` : row.message }}</template></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</AppDialog>
|
||||||
</AdminPage>
|
</AdminPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -179,5 +205,8 @@ onMounted(() => { void Promise.all([loadConfig(), load()]) })
|
|||||||
.sync-pagination { display: flex; justify-content: flex-end; padding: var(--admin-space-4); }
|
.sync-pagination { display: flex; justify-content: flex-end; padding: var(--admin-space-4); }
|
||||||
.sync-edit-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
|
.sync-edit-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
|
||||||
.sync-edit-grid :deep(.el-input-number) { width: 100%; }
|
.sync-edit-grid :deep(.el-input-number) { width: 100%; }
|
||||||
|
.connection-result { display: grid; gap: var(--admin-space-4); }
|
||||||
|
.connection-result__sku { color: var(--cc-muted); }
|
||||||
|
.connection-result__sku strong { color: var(--cc-text); }
|
||||||
@media (max-width: 900px) { .sync-filters .el-input { width: 180px; } }
|
@media (max-width: 900px) { .sync-filters .el-input { width: 180px; } }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user