同步列表
Some checks failed
Some checks failed
This commit is contained in:
parent
62e3781ecf
commit
fac91a81e2
26
node_modules/.vite/deps/_metadata.json
generated
vendored
26
node_modules/.vite/deps/_metadata.json
generated
vendored
@ -1,71 +1,71 @@
|
||||
{
|
||||
"hash": "780fd6b7",
|
||||
"browserHash": "11a50aed",
|
||||
"hash": "7466b81f",
|
||||
"browserHash": "72dd502f",
|
||||
"optimized": {
|
||||
"@element-plus/icons-vue": {
|
||||
"src": "../../@element-plus/icons-vue/dist/index.js",
|
||||
"file": "@element-plus_icons-vue.js",
|
||||
"fileHash": "e73a6617",
|
||||
"fileHash": "a827a77d",
|
||||
"needsInterop": false
|
||||
},
|
||||
"axios": {
|
||||
"src": "../../axios/index.js",
|
||||
"file": "axios.js",
|
||||
"fileHash": "9ada0434",
|
||||
"fileHash": "563efb6a",
|
||||
"needsInterop": false
|
||||
},
|
||||
"crypto-js": {
|
||||
"src": "../../crypto-js/index.js",
|
||||
"file": "crypto-js.js",
|
||||
"fileHash": "35b4399e",
|
||||
"fileHash": "70871dfd",
|
||||
"needsInterop": true
|
||||
},
|
||||
"dayjs": {
|
||||
"src": "../../dayjs/dayjs.min.js",
|
||||
"file": "dayjs.js",
|
||||
"fileHash": "3c458ca9",
|
||||
"fileHash": "330e0aa9",
|
||||
"needsInterop": true
|
||||
},
|
||||
"element-plus": {
|
||||
"src": "../../element-plus/es/index.mjs",
|
||||
"file": "element-plus.js",
|
||||
"fileHash": "65c76065",
|
||||
"fileHash": "c8723d93",
|
||||
"needsInterop": false
|
||||
},
|
||||
"element-plus/es/locale/lang/zh-cn": {
|
||||
"src": "../../element-plus/es/locale/lang/zh-cn.mjs",
|
||||
"file": "element-plus_es_locale_lang_zh-cn.js",
|
||||
"fileHash": "05b5b909",
|
||||
"fileHash": "5d10d7a9",
|
||||
"needsInterop": false
|
||||
},
|
||||
"jsbarcode": {
|
||||
"src": "../../jsbarcode/bin/JsBarcode.js",
|
||||
"file": "jsbarcode.js",
|
||||
"fileHash": "d60441c9",
|
||||
"fileHash": "5b45d96a",
|
||||
"needsInterop": true
|
||||
},
|
||||
"json-bigint": {
|
||||
"src": "../../json-bigint/index.js",
|
||||
"file": "json-bigint.js",
|
||||
"fileHash": "4eb91e5f",
|
||||
"fileHash": "43b512d4",
|
||||
"needsInterop": true
|
||||
},
|
||||
"pinia": {
|
||||
"src": "../../pinia/dist/pinia.mjs",
|
||||
"file": "pinia.js",
|
||||
"fileHash": "461b0d9b",
|
||||
"fileHash": "9078f52d",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vue": {
|
||||
"src": "../../vue/dist/vue.runtime.esm-bundler.js",
|
||||
"file": "vue.js",
|
||||
"fileHash": "aa9868f1",
|
||||
"fileHash": "bd6fb29e",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vue-router": {
|
||||
"src": "../../vue-router/dist/vue-router.mjs",
|
||||
"file": "vue-router.js",
|
||||
"fileHash": "010be937",
|
||||
"fileHash": "d015433f",
|
||||
"needsInterop": false
|
||||
}
|
||||
},
|
||||
|
||||
@ -15,10 +15,12 @@ export const fetchTodayStats = async () => {
|
||||
total_receiving_count: data?.total_receiving_count ?? 0,
|
||||
total_outbound_count: data?.total_outbound_count ?? 0,
|
||||
total_sale_count: data?.total_sale_count ?? 0,
|
||||
today_sale_amount: data?.today_sale_amount ?? 0,
|
||||
yesterday_order_count: data?.yesterday_order_count ?? 0,
|
||||
yesterday_receiving_count: data?.yesterday_receiving_count ?? 0,
|
||||
yesterday_outbound_count: data?.yesterday_outbound_count ?? 0,
|
||||
yesterday_sale_count: data?.yesterday_sale_count ?? 0
|
||||
yesterday_sale_count: data?.yesterday_sale_count ?? 0,
|
||||
yesterday_sale_amount: data?.yesterday_sale_amount ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +43,7 @@ export const fetchEmployeeStats = async () => {
|
||||
/**
|
||||
* 获取店铺信息列表
|
||||
* @param {Object} params - { time_range?: string, store_name?: string }
|
||||
* @returns {Promise<Array<{store_name: string, store_type: string, sale_count: number, outbound_count: number, receiving_count: number, order_count: number}>>}
|
||||
* @returns {Promise<Array<{store_name: string, store_type: string, sale_amount: number, outbound_count: number, receiving_count: number, order_count: number}>>}
|
||||
*/
|
||||
export const fetchStoreInfo = async (params = {}) => {
|
||||
const response = await request.get(`${ADMIN_BASE}/store-info`, { params })
|
||||
@ -51,7 +53,7 @@ export const fetchStoreInfo = async (params = {}) => {
|
||||
return (data?.data ?? []).map(item => ({
|
||||
store_name: item.store_name ?? '-',
|
||||
store_type: item.store_type ?? '-',
|
||||
sale_count: item.sale_count ?? 0,
|
||||
sale_amount: item.sale_amount ?? 0,
|
||||
outbound_count: item.outbound_count ?? 0,
|
||||
receiving_count: item.receiving_count ?? 0,
|
||||
order_count: item.order_count ?? 0,
|
||||
|
||||
@ -386,4 +386,15 @@ export const fetchDestroyLog = async ({ keyword, page, pageSize }) => {
|
||||
export const restoreProduct = async ({ destroy_log_id }) => {
|
||||
const response = await request.post(`${API_BASE}/restore`, { destroy_log_id })
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 从旺店通同步商品
|
||||
* @param {Object} params
|
||||
* @param {string} params.start_time - 开始时间 yyyy-MM-dd HH:mm:ss
|
||||
* @param {string} params.end_time - 结束时间 yyyy-MM-dd HH:mm:ss
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export const syncGoodsFromWdt = async ({ start_time, end_time }) => {
|
||||
return request.get('/wangdian/query-goods', { params: { start_time, end_time } })
|
||||
}
|
||||
@ -122,3 +122,12 @@ export const releaseWave = async (data) => {
|
||||
export const exportPurchaseOrderToWdt = async (params) => {
|
||||
return request.get('/purchase-order/export-to-wdt', { params, responseType: 'blob' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建采购单(推送到旺店通)
|
||||
* @param {number} purchase_order_id - 采购单ID
|
||||
* @returns {Promise} 接口返回的 Promise 对象
|
||||
*/
|
||||
export const pushPurchaseOrderToWdt = async (purchase_order_id) => {
|
||||
return request.post('/wangdian/purchase-order-push', { purchase_order_id })
|
||||
}
|
||||
|
||||
@ -224,16 +224,27 @@ export const fetchExpressInfo = async (waybillNo) => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收快递单号
|
||||
* 回收快递单号(旧接口 /logistics/cancel)
|
||||
* @param {Object} params
|
||||
* @param {string|number} params.user_id - 用户ID
|
||||
* @param {string} params.logistics_no - 物流单号
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export const recycleWaybillNo = async ({ user_id, logistics_no }) => {
|
||||
const formData = new FormData()
|
||||
formData.append('user_id', String(user_id))
|
||||
formData.append('logistics_no', logistics_no)
|
||||
const res = await request.post(`/logistics/cancel`, formData)
|
||||
// export const recycleWaybillNo = async ({ user_id, logistics_no }) => {
|
||||
// const formData = new FormData()
|
||||
// formData.append('user_id', String(user_id))
|
||||
// formData.append('logistics_no', logistics_no)
|
||||
// const res = await request.post(`/logistics/cancel`, formData)
|
||||
// return res.data
|
||||
// }
|
||||
|
||||
/**
|
||||
* 回收快递单号(新接口 /print/cancelBmOrderApi)
|
||||
* @param {Object} params
|
||||
* @param {string} params.mailNo - 快递单号
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export const recycleWaybillNo = async ({ mailNo }) => {
|
||||
const res = await axios.post(`${PRINT_API_BASE}/api/print/cancelBmOrderApi`, { mailNo })
|
||||
return res.data
|
||||
}
|
||||
@ -83,4 +83,12 @@ export const updateSupplier = async (supplier) => {
|
||||
*/
|
||||
export const deleteSupplier = async (supplier) => {
|
||||
return request.post(`${API_BASE}/delete`, supplier)
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步供应商(从旺店通拉取)
|
||||
* @returns {Promise} 接口返回的 Promise 对象
|
||||
*/
|
||||
export const syncSupplierFromWdt = async () => {
|
||||
return request.get('/wangdian/query-provider')
|
||||
}
|
||||
28
src/api/wangdian.js
Normal file
28
src/api/wangdian.js
Normal file
@ -0,0 +1,28 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 标准化列表接口返回的数据格式
|
||||
*/
|
||||
const normalizeListResponse = (payload) => {
|
||||
const data = payload?.data
|
||||
if (!data) return { list: [], total: 0 }
|
||||
if (Array.isArray(data)) return { list: data, total: data.length }
|
||||
return {
|
||||
list: Array.isArray(data.list) ? data.list : [],
|
||||
total: typeof data.total === 'number' ? data.total : 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取旺店通同步任务列表
|
||||
* @param {Object} params
|
||||
* @param {number} params.page - 当前页码
|
||||
* @param {number} params.pageSize - 每页条数
|
||||
* @returns {Promise<{list: Array, total: number}>}
|
||||
*/
|
||||
export const fetchSyncTaskList = async ({ page, pageSize }) => {
|
||||
const response = await request.get('/wangdian/sync-task-list', {
|
||||
params: { page, page_size: pageSize }
|
||||
})
|
||||
return normalizeListResponse(response)
|
||||
}
|
||||
@ -107,4 +107,12 @@ export const updateWarehouse = async (warehouse) => {
|
||||
*/
|
||||
export const deleteWarehouse = async (warehouse) => {
|
||||
return request.post(`${API_BASE}/delete`, warehouse)
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步仓库(从旺店通拉取)
|
||||
* @returns {Promise} 接口返回的 Promise 对象
|
||||
*/
|
||||
export const syncWarehouseFromWdt = async () => {
|
||||
return request.get('/wangdian/query-warehouse')
|
||||
}
|
||||
@ -29,6 +29,15 @@
|
||||
<el-menu-item index="/admin/employee-type" @click="goTo('/admin/employee-type')">账户类型</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<!-- 旺店通 -->
|
||||
<el-sub-menu index="wangdian" v-if="userStore.adminUserInfo">
|
||||
<template #title>
|
||||
<el-icon><Connection /></el-icon>
|
||||
<span>旺店通</span>
|
||||
</template>
|
||||
<el-menu-item index="/wangdian/sync-task" @click="goTo('/wangdian/sync-task')">同步列表</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<!-- 分账管理 - 仅管理员可见 -->
|
||||
<el-sub-menu index="splitAccount" v-if="userStore.userInfo.username == '18904056800'">
|
||||
<template #title>
|
||||
@ -297,7 +306,7 @@
|
||||
<script setup>import { ref, computed } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Monitor, Tickets, User, DataLine, List, Fold, Expand, ArrowDown, SwitchButton, Wallet, Money, Avatar, Tools, Upload, Box, Document, Setting, Van, Finished, Shop, Printer, Edit } from '@element-plus/icons-vue'
|
||||
import { Monitor, Tickets, User, DataLine, List, Fold, Expand, ArrowDown, SwitchButton, Wallet, Money, Avatar, Tools, Upload, Box, Document, Setting, Van, Finished, Shop, Printer, Edit, Connection } from '@element-plus/icons-vue'
|
||||
import { removeAdminToken, removeAdminUserInfo } from '@/utils/auth'
|
||||
import { useUserStore } from '@/store/user'
|
||||
|
||||
|
||||
@ -197,7 +197,7 @@
|
||||
<el-table-column prop="updated_at" label="更新时间" width="170" align="center">
|
||||
<template #default="{ row }">{{ formatTimestamp(row.updated_at) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" align="center" fixed="right">
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link :icon="Edit" size="small" @click="handleEdit(row)">修改</el-button>
|
||||
<el-tooltip v-if="row.warehouse_name" content="已落位商品不可删除" placement="top" :disabled="false">
|
||||
@ -205,6 +205,7 @@
|
||||
</el-tooltip>
|
||||
<el-button v-else type="danger" link :icon="Delete" size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button type="danger" link :icon="Delete" size="small" @click="handleDestroy(row)">销毁</el-button>
|
||||
<el-button type="primary" link size="small" @click="handleSyncGoods(row)">同步商品</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -252,7 +253,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Search, Refresh, MoreFilled, Upload, Edit, Delete } from '@element-plus/icons-vue'
|
||||
import GoodsPop from '@/components/goodsPop/index.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { fetchProductList, retryProductPublish, importProductsByExcel, deleteProduct, destroyProduct } from '@/api/product'
|
||||
import { fetchProductList, retryProductPublish, importProductsByExcel, deleteProduct, destroyProduct, syncGoodsFromWdt } from '@/api/product'
|
||||
import { fetchWarehouseList } from '@/api/warehouse'
|
||||
|
||||
interface ShopListItem {
|
||||
@ -481,6 +482,17 @@ export default defineComponent({
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
const handleSyncGoods = async (row: ProductItem): Promise<void> => {
|
||||
const start_time = formatTimestamp(row.created_at)
|
||||
const end_time = formatTimestamp(row.updated_at)
|
||||
try {
|
||||
await syncGoodsFromWdt({ start_time, end_time })
|
||||
ElMessage.success({ message: '已同步,在任务管理里查看进度', customClass: 'scan-success-message' })
|
||||
} catch {
|
||||
ElMessage.error({ message: '同步失败', customClass: 'scan-error-message' })
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectionChange = (rows: ProductItem[]): void => {
|
||||
selectedRows.value = rows
|
||||
}
|
||||
@ -567,7 +579,7 @@ export default defineComponent({
|
||||
stats,
|
||||
formatTimestamp, formatAppearance, getFirstImage, getImageList, showAllShopMsg,
|
||||
handleSearch, resetSearch, handleCurrentChange, handleSizeChange,
|
||||
handleEdit, handleDelete, reTryGoosTask, handleDestroy,
|
||||
handleEdit, handleDelete, reTryGoosTask, handleDestroy, handleSyncGoods,
|
||||
refreshList, selectedRows, handleSelectionChange,
|
||||
// 导入
|
||||
importDialogVisible, importWarehouseId, importFile, importLoading, uploadRef, warehouseOptions,
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
<el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
|
||||
<el-button :icon="Refresh" @click="resetSearch">重置</el-button>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增仓库</el-button>
|
||||
<el-button type="warning" @click="handleSyncFromWdt">同步仓库</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 仓库列表表格:支持单选、行高亮、占位行(保持表格高度一致) -->
|
||||
@ -316,7 +317,8 @@ import {
|
||||
fetchWarehouseDetail,
|
||||
createWarehouse,
|
||||
updateWarehouse,
|
||||
deleteWarehouse
|
||||
deleteWarehouse,
|
||||
syncWarehouseFromWdt
|
||||
} from '@/api/warehouse'
|
||||
import { fetchLogisticsList } from '@/api/logistics'
|
||||
import { regionData } from './regionData'
|
||||
@ -855,6 +857,17 @@ export default defineComponent({
|
||||
Object.assign(formData, createDefaultFormData())
|
||||
}
|
||||
|
||||
// 同步仓库(从旺店通拉取)
|
||||
const handleSyncFromWdt = async (): Promise<void> => {
|
||||
try {
|
||||
await syncWarehouseFromWdt()
|
||||
ElMessage.success({ message: '已同步,在任务管理里查看进度' })
|
||||
refreshList()
|
||||
} catch (error) {
|
||||
ElMessage.error({ message: '同步失败', customClass: 'scan-error-message' })
|
||||
}
|
||||
}
|
||||
|
||||
// 加载物流模板列表
|
||||
const fetchLogisticsTemplates = async (): Promise<void> => {
|
||||
logisticsLoading.value = true
|
||||
@ -918,6 +931,7 @@ export default defineComponent({
|
||||
handleDelete,
|
||||
submitForm,
|
||||
resetForm,
|
||||
handleSyncFromWdt,
|
||||
// 详情弹窗相关
|
||||
detailDialogVisible,
|
||||
detailLoading,
|
||||
|
||||
@ -109,6 +109,15 @@ const routes = [
|
||||
// 普通用户也可访问
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'wangdian/sync-task',
|
||||
name: 'wangdian-sync-task',
|
||||
component: () => import('@/views/wangdian/syncTaskList.vue'),
|
||||
meta: {
|
||||
title: '同步列表',
|
||||
requiresAuth: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'location',
|
||||
name: 'location',
|
||||
|
||||
@ -14,8 +14,8 @@ const USE_MOCK = false // 设置为true使用模拟数据
|
||||
// 创建axios实例
|
||||
const request = axios.create({
|
||||
// baseURL: import.meta.env.DEV ? '/api' : (import.meta.env.VITE_API_BASE || 'http://127.0.0.1:9090/api'),
|
||||
baseURL: import.meta.env.DEV ? '/api' : (import.meta.env.VITE_API_BASE || 'http://192.168.101.213:9090/api'),
|
||||
// baseURL: import.meta.env.DEV ? '/api' : (import.meta.env.VITE_API_BASE || 'https://psi.api.buzhiyushu.cn/api'),
|
||||
// baseURL: import.meta.env.DEV ? '/api' : (import.meta.env.VITE_API_BASE || 'http://192.168.101.213:9090/api'),
|
||||
baseURL: import.meta.env.DEV ? '/api' : (import.meta.env.VITE_API_BASE || 'https://psi.api.buzhiyushu.cn/api'),
|
||||
timeout: 10000,
|
||||
// 用 JSONbig 替代默认 JSON.parse,保留大整数精度
|
||||
transformResponse: [
|
||||
|
||||
@ -91,16 +91,16 @@
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-title">今日销售</div>
|
||||
<div class="stat-value">{{ todayStats.total_sale_count }}</div>
|
||||
<div class="stat-desc">销售数量</div>
|
||||
<div class="stat-value">{{ (todayStats.today_sale_amount / 100).toFixed(2) }}</div>
|
||||
<div class="stat-desc">销售金额</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-divider"></div>
|
||||
<div class="stat-sub">
|
||||
<div class="stat-info">
|
||||
<div class="stat-title">昨日销售</div>
|
||||
<div class="stat-value">{{ yesterdayStats.yesterday_sale_count }}</div>
|
||||
<div class="stat-desc">销售数量</div>
|
||||
<div class="stat-value">{{ (yesterdayStats.yesterday_sale_amount / 100).toFixed(2) }}</div>
|
||||
<div class="stat-desc">销售金额</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -209,9 +209,9 @@
|
||||
<el-table-column prop="store_type" label="店铺类型" min-width="120" align="center">
|
||||
<template #default="{ row }">{{ row.store_type || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sale_count" label="销售数量" min-width="100" align="center">
|
||||
<el-table-column prop="sale_amount" label="销售金额" min-width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag type="warning" size="small">{{ row.sale_count ?? 0 }}</el-tag>
|
||||
<el-tag type="warning" size="small">¥{{ ((row.sale_amount ?? 0) / 100).toFixed(2) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="outbound_count" label="出库数量" min-width="100" align="center">
|
||||
@ -255,7 +255,8 @@ const todayStats = ref({
|
||||
total_order_count: 0,
|
||||
total_receiving_count: 0,
|
||||
total_outbound_count: 0,
|
||||
total_sale_count: 0
|
||||
total_sale_count: 0,
|
||||
today_sale_amount: 0
|
||||
})
|
||||
|
||||
// 昨日统计数据
|
||||
@ -263,7 +264,8 @@ const yesterdayStats = ref({
|
||||
yesterday_order_count: 0,
|
||||
yesterday_receiving_count: 0,
|
||||
yesterday_outbound_count: 0,
|
||||
yesterday_sale_count: 0
|
||||
yesterday_sale_count: 0,
|
||||
yesterday_sale_amount: 0
|
||||
})
|
||||
|
||||
// 最新商品列表
|
||||
@ -295,13 +297,15 @@ const loadTodayStats = async () => {
|
||||
total_order_count: data.total_order_count,
|
||||
total_receiving_count: data.total_receiving_count,
|
||||
total_outbound_count: data.total_outbound_count,
|
||||
total_sale_count: data.total_sale_count
|
||||
total_sale_count: data.total_sale_count,
|
||||
today_sale_amount: data.today_sale_amount
|
||||
}
|
||||
yesterdayStats.value = {
|
||||
yesterday_order_count: data.yesterday_order_count,
|
||||
yesterday_receiving_count: data.yesterday_receiving_count,
|
||||
yesterday_outbound_count: data.yesterday_outbound_count,
|
||||
yesterday_sale_count: data.yesterday_sale_count
|
||||
yesterday_sale_count: data.yesterday_sale_count,
|
||||
yesterday_sale_amount: data.yesterday_sale_amount
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载今日统计失败:', error)
|
||||
@ -309,13 +313,15 @@ const loadTodayStats = async () => {
|
||||
total_order_count: 0,
|
||||
total_receiving_count: 0,
|
||||
total_outbound_count: 0,
|
||||
total_sale_count: 0
|
||||
total_sale_count: 0,
|
||||
today_sale_amount: 0
|
||||
}
|
||||
yesterdayStats.value = {
|
||||
yesterday_order_count: 0,
|
||||
yesterday_receiving_count: 0,
|
||||
yesterday_outbound_count: 0,
|
||||
yesterday_sale_count: 0
|
||||
yesterday_sale_count: 0,
|
||||
yesterday_sale_amount: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,8 +104,9 @@
|
||||
<el-table-column prop="remark" label="备注" min-width="150" show-overflow-tooltip align="center">
|
||||
<template #default="{ row }" >{{ row.remark || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" fixed="right" align="center">
|
||||
<el-table-column label="操作" width="200" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handlePushToWdt(row)">创建采购单</el-button>
|
||||
<!-- <el-button type="primary" link :icon="Edit" @click="handleEdit(row)" :disabled="Number(row.status) >= 3">编辑</el-button> -->
|
||||
<el-button type="danger" link :icon="Delete" @click="handleDelete(row)" :disabled="Number(row.status) >= 2">删除</el-button>
|
||||
</template>
|
||||
@ -131,7 +132,7 @@ import { defineComponent, ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Search, Refresh, Plus, Edit, Delete, View, Loading } from '@element-plus/icons-vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { fetchPurchaseOrderList, fetchPurchaseOrderDetail, createPurchaseOrder, updatePurchaseOrder, deletePurchaseOrder, exportPurchaseOrderToWdt } from '@/api/purchaseOrder'
|
||||
import { fetchPurchaseOrderList, fetchPurchaseOrderDetail, createPurchaseOrder, updatePurchaseOrder, deletePurchaseOrder, exportPurchaseOrderToWdt, pushPurchaseOrderToWdt } from '@/api/purchaseOrder'
|
||||
import { fetchSupplierList } from '@/api/supplier'
|
||||
import { fetchWarehouseList } from '@/api/warehouse'
|
||||
|
||||
@ -335,6 +336,15 @@ export default defineComponent({
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
const handlePushToWdt = async (row: any): Promise<void> => {
|
||||
try {
|
||||
await pushPurchaseOrderToWdt(row.id)
|
||||
ElMessage.success({ message: '已创建,在任务管理里查看进度', customClass: 'scan-success-message' })
|
||||
} catch (error) {
|
||||
ElMessage.error({ message: '创建采购单失败', customClass: 'scan-error-message' })
|
||||
}
|
||||
}
|
||||
|
||||
const handleExport = async (): Promise<void> => {
|
||||
try {
|
||||
const res = await exportPurchaseOrderToWdt({
|
||||
@ -394,7 +404,7 @@ export default defineComponent({
|
||||
statusLabel, statusTagType,
|
||||
formatTimestamp, formatAmount,
|
||||
handleSearch, resetSearch, handleCurrentChange, handleSizeChange,
|
||||
handleExpandChange, handleView, handleDelete, handleExport, resetForm
|
||||
handleExpandChange, handleView, handleDelete, handlePushToWdt, handleExport, resetForm
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -1031,14 +1031,8 @@ export default defineComponent({
|
||||
/** 回收快递单号 */
|
||||
const handleRecycleWaybill = async (item: any) => {
|
||||
if (!item?.logistics_no) return
|
||||
const userInfo = JSON.parse(localStorage.getItem('admin_userInfo') || '{}')
|
||||
const userId = userInfo?.about_id
|
||||
if (!userId) {
|
||||
ElMessage.error({ message: '未获取到用户信息', customClass: 'scan-error-message' })
|
||||
return
|
||||
}
|
||||
try {
|
||||
await recycleWaybillNo({ user_id: userId, logistics_no: item.logistics_no })
|
||||
await recycleWaybillNo({ mailNo: item.logistics_no })
|
||||
ElMessage.success({ message: `快递单 ${item.logistics_no} 已回收`, customClass: 'scan-success-message' })
|
||||
// 清空详情缓存并刷新列表
|
||||
detailCache.value = {}
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
<el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
|
||||
<el-button :icon="Refresh" @click="resetSearch">重置</el-button>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增供应商</el-button>
|
||||
<el-button type="warning" @click="handleSyncFromWdt">同步供应商</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="tableData" v-loading="loading" border stripe style="width: 100%">
|
||||
@ -129,7 +130,8 @@ import {
|
||||
fetchSupplierDetail,
|
||||
createSupplier,
|
||||
updateSupplier,
|
||||
deleteSupplier
|
||||
deleteSupplier,
|
||||
syncSupplierFromWdt
|
||||
} from '@/api/supplier'
|
||||
|
||||
interface SupplierItem {
|
||||
@ -380,6 +382,15 @@ export default defineComponent({
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
const handleSyncFromWdt = async (): Promise<void> => {
|
||||
try {
|
||||
await syncSupplierFromWdt()
|
||||
ElMessage.success({ message: '已同步,在任务管理里查看进度', customClass: 'scan-success-message' })
|
||||
} catch (error) {
|
||||
ElMessage.error({ message: '同步供应商失败', customClass: 'scan-error-message' })
|
||||
}
|
||||
}
|
||||
|
||||
const submitForm = async (): Promise<void> => {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
@ -453,6 +464,7 @@ export default defineComponent({
|
||||
handleDetail,
|
||||
handleEdit,
|
||||
handleDelete,
|
||||
handleSyncFromWdt,
|
||||
submitForm,
|
||||
resetForm
|
||||
}
|
||||
|
||||
162
src/views/wangdian/syncTaskList.vue
Normal file
162
src/views/wangdian/syncTaskList.vue
Normal file
@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<el-card class="sync-task-manager">
|
||||
<template #header>
|
||||
<div class="card-header">旺店通同步列表</div>
|
||||
</template>
|
||||
|
||||
<el-table :data="tableData" v-loading="loading" border stripe style="width: 100%">
|
||||
<el-table-column prop="task_type" label="任务类型" width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small">{{ taskTypeLabel(row.task_type) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="statusTagType(row.status)" size="small">
|
||||
{{ statusLabel(row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="progress" label="已处理" width="100" align="center" />
|
||||
<el-table-column prop="total" label="总数" width="100" align="center" />
|
||||
<el-table-column prop="error_msg" label="错误信息" min-width="200" show-overflow-tooltip align="center">
|
||||
<template #default="{ row }">{{ row.error_msg || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始时间" width="170" align="center">
|
||||
<template #default="{ row }">{{ formatTimestamp(row.started_at) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="完成时间" width="170" align="center">
|
||||
<template #default="{ row }">{{ formatTimestamp(row.finished_at) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" width="170" align="center">
|
||||
<template #default="{ row }">{{ formatTimestamp(row.created_at) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新时间" width="170" align="center">
|
||||
<template #default="{ row }">{{ formatTimestamp(row.updated_at) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-wrapper">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pagination.total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, onMounted } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { fetchSyncTaskList } from '@/api/wangdian'
|
||||
|
||||
const TASK_TYPE_MAP: Record<string, string> = {
|
||||
purchase_push: '采购单推送',
|
||||
sync_provider: '同步供应商',
|
||||
sync_warehouse: '同步仓库',
|
||||
sync_goods: '同步商品'
|
||||
}
|
||||
|
||||
const STATUS_MAP: Record<string, { label: string; type: string }> = {
|
||||
running: { label: '运行中', type: 'warning' },
|
||||
completed: { label: '已完成', type: 'success' },
|
||||
cancelled: { label: '已取消', type: 'info' },
|
||||
failed: { label: '失败', type: 'danger' }
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SyncTaskList',
|
||||
setup() {
|
||||
const loading = ref<boolean>(false)
|
||||
const tableData = ref<any[]>([])
|
||||
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
const taskTypeLabel = (type: string): string => TASK_TYPE_MAP[type] || type
|
||||
const statusLabel = (status: string): string => STATUS_MAP[status]?.label || status
|
||||
const statusTagType = (status: string): string => STATUS_MAP[status]?.type || 'info'
|
||||
|
||||
const formatTimestamp = (timestamp?: number | string | null): string => {
|
||||
if (!timestamp && timestamp !== 0) return '-'
|
||||
const num = Number(timestamp)
|
||||
if (num === 0) return '-'
|
||||
return dayjs.unix(num).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
const loadList = async (): Promise<void> => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await fetchSyncTaskList({
|
||||
page: pagination.current,
|
||||
pageSize: pagination.pageSize
|
||||
})
|
||||
tableData.value = res.list || []
|
||||
pagination.total = res.total || 0
|
||||
} catch {
|
||||
tableData.value = []
|
||||
pagination.total = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleCurrentChange = (page: number): void => {
|
||||
pagination.current = page
|
||||
void loadList()
|
||||
}
|
||||
|
||||
const handleSizeChange = (size: number): void => {
|
||||
pagination.pageSize = size
|
||||
pagination.current = 1
|
||||
void loadList()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void loadList()
|
||||
})
|
||||
|
||||
return {
|
||||
loading, tableData, pagination,
|
||||
taskTypeLabel, statusLabel, statusTagType,
|
||||
formatTimestamp,
|
||||
handleCurrentChange, handleSizeChange
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sync-task-manager {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
background: white;
|
||||
padding: 14px 20px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-table) {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
</style>
|
||||
@ -246,9 +246,9 @@ module.exports = defineConfig({
|
||||
proxy: {
|
||||
'/api': {
|
||||
// target: 'http://127.0.0.1:9090',
|
||||
target: 'http://192.168.101.213:9090',
|
||||
// target: 'https://psi.api.buzhiyushu.cn',
|
||||
// target: 'http://192.168.101.213:9090',
|
||||
// target: 'https://psi.api.buzhiyushu.cn',
|
||||
target: 'http://127.0.0.1:9090',
|
||||
changeOrigin: true
|
||||
},
|
||||
'/api/print': {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user