增加订单推送日志、分账日志
Some checks failed
Some checks failed
This commit is contained in:
parent
fac91a81e2
commit
02373f243e
22
src/api/orderQueue.js
Normal file
22
src/api/orderQueue.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单队列 API 基础地址
|
||||||
|
* 开发环境使用内网地址,生产环境可切换为 https://print.buzhiyushu.cn
|
||||||
|
*/
|
||||||
|
//const ORDER_QUEUE_API_BASE = 'http://192.168.101.127:8075'
|
||||||
|
const ORDER_QUEUE_API_BASE = 'https://print.buzhiyushu.cn'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取订单推送列表
|
||||||
|
* @param {Object} params - 查询参数
|
||||||
|
* @param {number} params.pageNum - 页码
|
||||||
|
* @param {number} params.pageSize - 每页条数
|
||||||
|
* @param {string|number} params.createdBy - 创建人ID (about_id)
|
||||||
|
* @param {string} [params.orderSn] - 订单编号(可选搜索条件)
|
||||||
|
* @returns {Promise<Object>}
|
||||||
|
*/
|
||||||
|
export const fetchOrderQueueList = async (params) => {
|
||||||
|
const res = await axios.get(`${ORDER_QUEUE_API_BASE}/api/erpGoodsOrderQueue/getList`, { params })
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
36
src/api/splitAccountLog.js
Normal file
36
src/api/splitAccountLog.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分账日志汇总列表
|
||||||
|
* @param {Object} params - { page, page_size, about_id }
|
||||||
|
* @returns {Promise<Object>}
|
||||||
|
*/
|
||||||
|
export const fetchSplitAccountLogSummary = (params) => {
|
||||||
|
return request.get('/split-account-deduction-log/summary', { params })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分账日志明细列表(不同服务器,传递完整URL使request忽略baseURL)
|
||||||
|
* @param {string} businessNo - 业务单号
|
||||||
|
* @param {string|number} aboutId - 登录用户 about_id
|
||||||
|
* @returns {Promise<Object>}
|
||||||
|
*/
|
||||||
|
export const fetchSplitAccountLogDetail = (businessNo, aboutId) => {
|
||||||
|
return request.get('https://psi.api.buzhiyushu.cn/api/split-account-deduction-log/detail-list', {
|
||||||
|
params: { business_no: businessNo, about_id: aboutId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询订单详情(印刷系统,独立 axios 实例,不走拦截器)
|
||||||
|
* @param {string} ids - 逗号分隔的 erpOrderId 列表
|
||||||
|
* @returns {Promise<Array>}
|
||||||
|
*/
|
||||||
|
export const fetchOrdersByIds = async (ids) => {
|
||||||
|
const instance = axios.create({ timeout: 15000 })
|
||||||
|
const res = await instance.get('https://print.buzhiyushu.cn/api/erpGoodsOrder/getListByIds', {
|
||||||
|
params: { ids }
|
||||||
|
})
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
@ -48,6 +48,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-menu-item index="/split-account-config" @click="goTo('/split-account-config')">分账配置</el-menu-item>
|
<el-menu-item index="/split-account-config" @click="goTo('/split-account-config')">分账配置</el-menu-item>
|
||||||
<el-menu-item index="/split-account-employee" @click="goTo('/split-account-employee')">分账设置</el-menu-item>
|
<el-menu-item index="/split-account-employee" @click="goTo('/split-account-employee')">分账设置</el-menu-item>
|
||||||
|
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
|
|
||||||
<!-- 以下菜单 - 所有登录用户可见 -->
|
<!-- 以下菜单 - 所有登录用户可见 -->
|
||||||
@ -173,6 +174,16 @@
|
|||||||
<span>销毁记录</span>
|
<span>销毁记录</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
|
<el-sub-menu index="order-log">
|
||||||
|
<template #title>
|
||||||
|
<el-icon>
|
||||||
|
<List />
|
||||||
|
</el-icon>
|
||||||
|
<span>订单日志</span>
|
||||||
|
</template>
|
||||||
|
<el-menu-item index="/order-push" @click="goTo('/order-push')">订单推送</el-menu-item>
|
||||||
|
<el-menu-item index="/split-account-log" @click="goTo('/split-account-log')">分账日志</el-menu-item>
|
||||||
|
</el-sub-menu>
|
||||||
<el-sub-menu index="sales-order">
|
<el-sub-menu index="sales-order">
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
|
|||||||
@ -196,6 +196,15 @@ const routes = [
|
|||||||
// 普通用户也可访问
|
// 普通用户也可访问
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'order-push',
|
||||||
|
name: 'OrderPush',
|
||||||
|
component: () => import('@/views/orderLog/orderPush.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '订单推送',
|
||||||
|
requiresAuth: true
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'sales-order',
|
path: 'sales-order',
|
||||||
name: 'sales-order',
|
name: 'sales-order',
|
||||||
@ -369,6 +378,16 @@ const routes = [
|
|||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
requiresAdmin: true
|
requiresAdmin: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'split-account-log',
|
||||||
|
name: 'SplitAccountLog',
|
||||||
|
component: () => import('@/views/splitAccount/SplitAccountLog.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '分账日志',
|
||||||
|
requiresAuth: true,
|
||||||
|
requiresAdmin: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
320
src/views/orderLog/orderPush.vue
Normal file
320
src/views/orderLog/orderPush.vue
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
<template>
|
||||||
|
<el-card class="order-push-manager">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">订单推送</div>
|
||||||
|
</template>
|
||||||
|
<div class="filter-bar">
|
||||||
|
<el-input v-model="searchForm.orderSn" placeholder="订单编号" clearable style="width: 220px"
|
||||||
|
@keyup.enter="handleSearch">
|
||||||
|
<template #prefix>
|
||||||
|
<el-icon><Search /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<el-select v-model="searchForm.shopType" placeholder="店铺类型" clearable style="width: 130px" @change="handleSearch">
|
||||||
|
<el-option label="拼多多" value="1" />
|
||||||
|
<el-option label="孔夫子" value="2" />
|
||||||
|
<el-option label="闲鱼" value="5" />
|
||||||
|
</el-select>
|
||||||
|
<el-input v-model="searchForm.shopErpName" placeholder="店铺名称" clearable style="width: 180px"
|
||||||
|
@keyup.enter="handleSearch" />
|
||||||
|
|
||||||
|
<el-select v-model="searchForm.orderType" placeholder="订单类型" clearable style="width: 140px" @change="handleSearch">
|
||||||
|
<el-option label="订单创建" value="0" />
|
||||||
|
<el-option label="订单完成" value="1" />
|
||||||
|
<el-option label="订单退款" value="2" />
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<el-select v-model="searchForm.status" placeholder="推送状态" clearable style="width: 140px" @change="handleSearch">
|
||||||
|
<el-option label="未推送" value="0" />
|
||||||
|
<el-option label="成功" value="1" />
|
||||||
|
<el-option label="失败" value="2" />
|
||||||
|
<el-option label="异常" value="3" />
|
||||||
|
</el-select>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="searchForm.createTimeRange"
|
||||||
|
type="datetimerange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="创建开始"
|
||||||
|
end-placeholder="创建结束"
|
||||||
|
value-format="x"
|
||||||
|
style="width: 340px"
|
||||||
|
@change="handleSearch"
|
||||||
|
/>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="searchForm.useTimeRange"
|
||||||
|
type="datetimerange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="修改开始"
|
||||||
|
end-placeholder="修改结束"
|
||||||
|
value-format="x"
|
||||||
|
style="width: 340px"
|
||||||
|
@change="handleSearch"
|
||||||
|
/>
|
||||||
|
<el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
|
||||||
|
<el-button :icon="Refresh" @click="resetSearch">重置</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="tableData" v-loading="loading" border stripe style="width: 100%">
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" v-if="false"/>
|
||||||
|
|
||||||
|
<el-table-column label="商品图片" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-image
|
||||||
|
v-if="parseItemList(row.itemList)?.goodsImgs?.[0]"
|
||||||
|
:src="parseItemList(row.itemList).goodsImgs[0]"
|
||||||
|
style="width: 50px; height: 50px"
|
||||||
|
fit="cover"
|
||||||
|
:preview-src-list="[parseItemList(row.itemList).goodsImgs[0]]"
|
||||||
|
preview-teleported
|
||||||
|
>
|
||||||
|
<template #error>
|
||||||
|
<div class="image-placeholder">📖</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
<span v-else class="image-placeholder">-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="订单类型" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ orderTypeLabel(row.orderType) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="orderSn" label="订单编号" min-width="120" show-overflow-tooltip align="center" />
|
||||||
|
<el-table-column prop="shopErpName" label="店铺名称" width="140" show-overflow-tooltip align="center" />
|
||||||
|
<el-table-column label="店铺类型" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ shopTypeLabel(row.shopType) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="商品名称" min-width="160" show-overflow-tooltip align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ parseItemList(row.itemList)?.goodsName || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="收货地址" min-width="200" show-overflow-tooltip align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatAddress(row) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="receiverName" label="联系人" width="100" show-overflow-tooltip align="center" />
|
||||||
|
<el-table-column prop="mobile" label="联系电话" width="130" align="center" />
|
||||||
|
<el-table-column label="创建时间" width="160" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatTime(row.queueCreateTime) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" width="90" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="statusType(row.status)" size="small">
|
||||||
|
{{ statusLabel(row.status) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="修改时间" width="160" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatTime(row.useTime) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="日志" min-width="180" show-overflow-tooltip align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span style="font-size: 12px; color: #909399">{{ row.msg || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="pagination.pageNum"
|
||||||
|
v-model:page-size="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@current-change="fetchData"
|
||||||
|
@size-change="fetchData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { Search, Refresh } from '@element-plus/icons-vue'
|
||||||
|
import { useUserStore } from '@/store/user'
|
||||||
|
import { fetchOrderQueueList } from '@/api/orderQueue'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const tableData = ref([])
|
||||||
|
|
||||||
|
const searchForm = reactive({
|
||||||
|
orderSn: '',
|
||||||
|
status: '',
|
||||||
|
orderType: '',
|
||||||
|
shopErpName: '',
|
||||||
|
shopType: '',
|
||||||
|
createTimeRange: null,
|
||||||
|
useTimeRange: null
|
||||||
|
})
|
||||||
|
|
||||||
|
const pagination = reactive({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 状态映射
|
||||||
|
const STATUS_MAP = {
|
||||||
|
'0': { label: '未推送', type: 'info' },
|
||||||
|
'1': { label: '成功', type: 'success' },
|
||||||
|
'2': { label: '失败', type: 'danger' },
|
||||||
|
'3': { label: '异常', type: 'warning' }
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusLabel = (status) => STATUS_MAP[status]?.label || status
|
||||||
|
const statusType = (status) => STATUS_MAP[status]?.type || ''
|
||||||
|
|
||||||
|
// 订单类型映射
|
||||||
|
const ORDER_TYPE_MAP = {
|
||||||
|
'0': '订单创建',
|
||||||
|
'1': '订单完成',
|
||||||
|
'2': '订单退款'
|
||||||
|
}
|
||||||
|
const orderTypeLabel = (type) => ORDER_TYPE_MAP[type] || type
|
||||||
|
|
||||||
|
// 店铺类型映射
|
||||||
|
const SHOP_TYPE_MAP = {
|
||||||
|
'1': '拼多多',
|
||||||
|
'2': '孔夫子',
|
||||||
|
'5': '闲鱼'
|
||||||
|
}
|
||||||
|
const shopTypeLabel = (type) => SHOP_TYPE_MAP[type] || type
|
||||||
|
|
||||||
|
// 解析 itemList JSON 字符串
|
||||||
|
const parseItemList = (itemListStr) => {
|
||||||
|
if (!itemListStr) return null
|
||||||
|
try {
|
||||||
|
return typeof itemListStr === 'string' ? JSON.parse(itemListStr) : itemListStr
|
||||||
|
} catch {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unix 时间戳转 年-月-日 时:分:秒
|
||||||
|
const formatTime = (timestamp) => {
|
||||||
|
if (!timestamp) return '-'
|
||||||
|
const numTs = Number(timestamp)
|
||||||
|
if (isNaN(numTs)) return '-'
|
||||||
|
// 秒级时间戳转毫秒
|
||||||
|
const d = new Date(numTs > 1e12 ? numTs : numTs * 1000)
|
||||||
|
const pad = (n) => String(n).padStart(2, '0')
|
||||||
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化省市区详细地址
|
||||||
|
const formatAddress = (row) => {
|
||||||
|
const parts = [row.province, row.city, row.country, row.town].filter(Boolean)
|
||||||
|
return parts.join(' ') || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
pageNum: pagination.pageNum,
|
||||||
|
pageSize: pagination.pageSize,
|
||||||
|
createdBy: userStore.adminUserInfo?.about_id
|
||||||
|
}
|
||||||
|
if (searchForm.orderSn) {
|
||||||
|
params.orderSn = searchForm.orderSn
|
||||||
|
}
|
||||||
|
if (searchForm.status !== '') {
|
||||||
|
params.status = searchForm.status
|
||||||
|
}
|
||||||
|
if (searchForm.orderType !== '') {
|
||||||
|
params.orderType = searchForm.orderType
|
||||||
|
}
|
||||||
|
if (searchForm.shopErpName) {
|
||||||
|
params.shopErpName = searchForm.shopErpName
|
||||||
|
}
|
||||||
|
if (searchForm.shopType !== '') {
|
||||||
|
params.shopType = searchForm.shopType
|
||||||
|
}
|
||||||
|
if (searchForm.createTimeRange) {
|
||||||
|
params.startCreateTime = Math.floor(searchForm.createTimeRange[0] / 1000)
|
||||||
|
params.endCreateTime = Math.floor(searchForm.createTimeRange[1] / 1000)
|
||||||
|
}
|
||||||
|
if (searchForm.useTimeRange) {
|
||||||
|
params.startUseTime = Math.floor(searchForm.useTimeRange[0] / 1000)
|
||||||
|
params.endUseTime = Math.floor(searchForm.useTimeRange[1] / 1000)
|
||||||
|
}
|
||||||
|
const res = await fetchOrderQueueList(params)
|
||||||
|
if (res.code === '200') {
|
||||||
|
tableData.value = res.list || []
|
||||||
|
pagination.total = res.total || 0
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 错误已在拦截器中处理
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
pagination.pageNum = 1
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetSearch = () => {
|
||||||
|
searchForm.orderSn = ''
|
||||||
|
searchForm.status = ''
|
||||||
|
searchForm.orderType = ''
|
||||||
|
searchForm.shopErpName = ''
|
||||||
|
searchForm.shopType = ''
|
||||||
|
searchForm.createTimeRange = null
|
||||||
|
searchForm.useTimeRange = null
|
||||||
|
pagination.pageNum = 1
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.filter-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-placeholder {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 20px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
514
src/views/splitAccount/SplitAccountLog.vue
Normal file
514
src/views/splitAccount/SplitAccountLog.vue
Normal file
@ -0,0 +1,514 @@
|
|||||||
|
<template>
|
||||||
|
<el-card class="split-account-log-manager">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">分账日志</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
:data="tableData"
|
||||||
|
v-loading="loading"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
style="width: 100%"
|
||||||
|
row-key="business_no"
|
||||||
|
@expand-change="onExpandChange"
|
||||||
|
>
|
||||||
|
<el-table-column type="expand" width="50">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div
|
||||||
|
v-if="expandedMap[row.business_no]?.loading"
|
||||||
|
style="text-align: center; padding: 20px"
|
||||||
|
>
|
||||||
|
<el-icon class="is-loading"><Loading /></el-icon> 加载中...
|
||||||
|
</div>
|
||||||
|
<el-table
|
||||||
|
v-else-if="expandedMap[row.business_no]?.detailList"
|
||||||
|
:data="expandedMap[row.business_no].detailList"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
size="small"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column label="消息" width="300">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
{{ d.deduction_details?.msg || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="金额来自" width="150" align="center">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
{{ d.deduction_details?.fromUser || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="手续费" width="100" align="right">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
{{ fmtYuan(d.deduction_details?.handlingFee) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="扣款前余额" width="140" align="right">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
{{ d.total_amount }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="扣款金额" width="120" align="right">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
<span
|
||||||
|
:style="{
|
||||||
|
color: d.deduction_amount < 0 ? '#67c23a' : '#f56c6c',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ d.deduction_amount >= 0 ? "+" : ""
|
||||||
|
}}{{ d.deduction_amount }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="扣款后余额" width="140" align="right">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
{{ d.remaining_amount }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="用户" width="120" align="center">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
{{
|
||||||
|
d.deduction_details?.usePhone === "18904056805"
|
||||||
|
? "0"
|
||||||
|
: d.deduction_details?.usePhone || "-"
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="时间" width="160" align="center">
|
||||||
|
<template #default="{ row: d }">
|
||||||
|
{{ formatTime(d.created_at) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div v-else style="text-align: center; padding: 20px; color: #999">
|
||||||
|
暂无明细数据
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 订单号 -->
|
||||||
|
<el-table-column
|
||||||
|
label="平台订单号"
|
||||||
|
min-width="180"
|
||||||
|
show-overflow-tooltip
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row._order?.orderSn || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
label="商品ID"
|
||||||
|
width="120"
|
||||||
|
show-overflow-tooltip
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getItemList(row._order)?.goodsId || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 商品信息 -->
|
||||||
|
<el-table-column label="商品图片" width="80" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-image
|
||||||
|
v-if="getItemList(row._order)?.goodsImgs?.[0]"
|
||||||
|
:src="getItemList(row._order)?.goodsImgs[0]"
|
||||||
|
style="width: 50px; height: 50px"
|
||||||
|
fit="cover"
|
||||||
|
:preview-src-list="[getItemList(row._order)?.goodsImgs[0]]"
|
||||||
|
preview-teleported
|
||||||
|
>
|
||||||
|
<template #error><span style="font-size: 18px">📖</span></template>
|
||||||
|
</el-image>
|
||||||
|
<span v-else style="font-size: 18px">📖</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 物流 -->
|
||||||
|
<el-table-column
|
||||||
|
label="快递单号"
|
||||||
|
width="150"
|
||||||
|
show-overflow-tooltip
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row._order?.trackingNumber || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 状态 -->
|
||||||
|
<el-table-column label="订单状态" width="105" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="orderStatusTag(row._order?.orderStatus)" size="small">
|
||||||
|
{{
|
||||||
|
orderStatusMap[row._order?.orderStatus] ||
|
||||||
|
row._order?.orderStatus ||
|
||||||
|
"-"
|
||||||
|
}}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="售后状态" width="110" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag
|
||||||
|
:type="afterSalesTag(row._order?.afterSalesStatus)"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
afterSalesMap[row._order?.afterSalesStatus] ||
|
||||||
|
row._order?.afterSalesStatus ||
|
||||||
|
"-"
|
||||||
|
}}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="店铺类型" width="90" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="shopTypeTag(row._order?.shopType)" size="small">
|
||||||
|
{{
|
||||||
|
shopTypeMap[row._order?.shopType] || row._order?.shopType || "-"
|
||||||
|
}}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 店铺信息 -->
|
||||||
|
<el-table-column
|
||||||
|
label="店铺名称"
|
||||||
|
min-width="150"
|
||||||
|
show-overflow-tooltip
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row._order?.shopErpName || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="商品名称" min-width="200" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getItemList(row._order)?.goodsName || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="数量" width="60" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getItemList(row._order)?.goodsCount || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 金额 -->
|
||||||
|
<el-table-column label="订单金额" width="100" align="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{
|
||||||
|
row._order?.orderTotal
|
||||||
|
? (row._order.orderTotal / 100).toFixed(2)
|
||||||
|
: "-"
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 仓库价格(summary 返回) -->
|
||||||
|
<el-table-column label="仓库价格" width="100" align="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ fmtYuan(row.deduction_details?.product?.sale_price) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 运费(summary 返回) -->
|
||||||
|
<el-table-column label="运费" width="90" align="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ fmtYuan(row.deduction_details?.product?.cost) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 支付时间 -->
|
||||||
|
<el-table-column label="支付时间" width="150" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatTime(row._order?.payAt) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 收货信息 -->
|
||||||
|
<el-table-column label="收货地址" min-width="200" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatAddress(row._order) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="联系人" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row._order?.receiverName || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="联系电话" width="120" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row._order?.mobile || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 仓库信息(summary 返回) -->
|
||||||
|
<el-table-column label="仓库编码" width="90" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getWh(row)?.warehouse_code || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="仓库名称" width="120" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getWh(row)?.warehouse_name || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="库位名称" width="120" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ getWh(row)?.location_name || "-" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="pagination.page"
|
||||||
|
v-model:page-size="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@current-change="fetchData"
|
||||||
|
@size-change="fetchData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from "vue";
|
||||||
|
import { Loading } from "@element-plus/icons-vue";
|
||||||
|
import { useUserStore } from "@/store/user";
|
||||||
|
import {
|
||||||
|
fetchSplitAccountLogSummary,
|
||||||
|
fetchSplitAccountLogDetail,
|
||||||
|
fetchOrdersByIds,
|
||||||
|
} from "@/api/splitAccountLog";
|
||||||
|
|
||||||
|
console.log("[分账日志] 组件加载");
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const tableData = ref([]);
|
||||||
|
const expandedMap = reactive({});
|
||||||
|
|
||||||
|
const pagination = reactive({
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const shopTypeMap = { 1: "拼多多", 2: "孔夫子", 5: "闲鱼" };
|
||||||
|
|
||||||
|
const orderStatusMap = {
|
||||||
|
1: "待付款",
|
||||||
|
2: "待发货",
|
||||||
|
3: "已发货待签收",
|
||||||
|
4: "交易成功",
|
||||||
|
5: "已退款",
|
||||||
|
6: "交易关闭",
|
||||||
|
7: "售后处理中",
|
||||||
|
};
|
||||||
|
|
||||||
|
const afterSalesMap = {
|
||||||
|
0: "无售后",
|
||||||
|
2: "买家申请退款,待商家处理",
|
||||||
|
3: "退货退款,待商家处理",
|
||||||
|
4: "商家同意退款,退款中",
|
||||||
|
5: "平台同意退款,退款中",
|
||||||
|
6: "驳回退款,待买家处理",
|
||||||
|
7: "已同意退货退款,待用户发货",
|
||||||
|
8: "平台处理中",
|
||||||
|
9: "平台拒绝退款,退款关闭",
|
||||||
|
10: "退款成功",
|
||||||
|
11: "买家撤销",
|
||||||
|
12: "买家逾期未处理,退款失败",
|
||||||
|
13: "买家逾期,超过有效期",
|
||||||
|
14: "换货补寄待商家处理",
|
||||||
|
15: "换货补寄待用户处理",
|
||||||
|
16: "换货补寄成功",
|
||||||
|
17: "换货补寄失败",
|
||||||
|
18: "换货补寄待用户确认完成",
|
||||||
|
21: "待商家同意维修",
|
||||||
|
22: "待用户确认发货",
|
||||||
|
24: "维修关闭",
|
||||||
|
25: "维修成功",
|
||||||
|
27: "待用户确认收货",
|
||||||
|
31: "已同意拒收退款,待用户拒收",
|
||||||
|
32: "补寄待商家发货",
|
||||||
|
33: "同意召回后退款,待商家召回",
|
||||||
|
600: "申请退货中",
|
||||||
|
601: "拒绝退货中",
|
||||||
|
602: "待买家退货",
|
||||||
|
603: "待卖家确认收货并退款",
|
||||||
|
604: "等待卖家确认退货地址",
|
||||||
|
605: "拒绝退款中",
|
||||||
|
606: "卖家已取消",
|
||||||
|
};
|
||||||
|
|
||||||
|
const shopTypeTag = (type) => {
|
||||||
|
const m = { 1: "danger", 2: "warning", 5: "info" };
|
||||||
|
return m[type] || "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const orderStatusTag = (status) => {
|
||||||
|
const m = {
|
||||||
|
1: "info",
|
||||||
|
2: "warning",
|
||||||
|
3: "primary",
|
||||||
|
4: "success",
|
||||||
|
5: "danger",
|
||||||
|
6: "info",
|
||||||
|
7: "danger",
|
||||||
|
};
|
||||||
|
return m[status] || "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const afterSalesTag = (status) => {
|
||||||
|
if (status === 0 || status === undefined || status === null) return "success";
|
||||||
|
if ([9, 10, 11, 12, 13, 16, 17, 24, 25, 606].includes(status)) return "info";
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
2, 3, 4, 5, 6, 7, 8, 14, 15, 18, 21, 22, 27, 31, 32, 33, 600, 601, 602,
|
||||||
|
603, 604, 605,
|
||||||
|
].includes(status)
|
||||||
|
)
|
||||||
|
return "warning";
|
||||||
|
return "danger";
|
||||||
|
};
|
||||||
|
|
||||||
|
const getItemList = (order) => {
|
||||||
|
if (!order?.itemList) return null;
|
||||||
|
if (typeof order.itemList === "string") {
|
||||||
|
try {
|
||||||
|
return JSON.parse(order.itemList);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return order.itemList;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getWh = (row) => row.deduction_details?.warehouses?.[0] || null
|
||||||
|
|
||||||
|
const formatAddress = (order) => {
|
||||||
|
if (!order) return "-";
|
||||||
|
const parts = [order.province, order.city, order.country, order.town].filter(
|
||||||
|
Boolean
|
||||||
|
);
|
||||||
|
return parts.length ? parts.join(" ") : "-";
|
||||||
|
};
|
||||||
|
|
||||||
|
const fmtYuan = (fen) => {
|
||||||
|
if (fen === null || fen === undefined) return "-";
|
||||||
|
const n = Number(fen);
|
||||||
|
if (isNaN(n)) return "-";
|
||||||
|
return (n / 100).toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getQueryAboutId = () => {
|
||||||
|
const rawId = userStore.adminUserInfo?.about_id;
|
||||||
|
return String(rawId) === "1965254774327533570" ? 0 : rawId;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatTime = (timestamp) => {
|
||||||
|
if (!timestamp) return "-";
|
||||||
|
const numTs = Number(timestamp);
|
||||||
|
if (isNaN(numTs)) return "-";
|
||||||
|
const d = new Date(numTs > 1e12 ? numTs : numTs * 1000);
|
||||||
|
const pad = (n) => String(n).padStart(2, "0");
|
||||||
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(
|
||||||
|
d.getHours()
|
||||||
|
)}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onExpandChange = async (row, expandedRows) => {
|
||||||
|
const isExpanded = expandedRows.some(
|
||||||
|
(r) => r.business_no === row.business_no
|
||||||
|
);
|
||||||
|
if (!isExpanded) return;
|
||||||
|
if (expandedMap[row.business_no]?.detailList) return;
|
||||||
|
|
||||||
|
expandedMap[row.business_no] = { loading: true, detailList: null };
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetchSplitAccountLogDetail(
|
||||||
|
row.business_no,
|
||||||
|
'0' // 默认先查看全部
|
||||||
|
);
|
||||||
|
if (res.code === 200) {
|
||||||
|
expandedMap[row.business_no].detailList = res.data || [];
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 拦截器已处理
|
||||||
|
} finally {
|
||||||
|
expandedMap[row.business_no].loading = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
page: pagination.page,
|
||||||
|
page_size: pagination.pageSize,
|
||||||
|
about_id: getQueryAboutId(),
|
||||||
|
};
|
||||||
|
const res = await fetchSplitAccountLogSummary(params);
|
||||||
|
if (res.code === 200) {
|
||||||
|
const list = res.data?.list || [];
|
||||||
|
tableData.value = list;
|
||||||
|
pagination.total = res.data?.total || 0;
|
||||||
|
|
||||||
|
// ⭐ 从 deduction_details 取 erpOrderId
|
||||||
|
const ids = list
|
||||||
|
.map((r) => r.deduction_details?.erpOrderId)
|
||||||
|
.filter(Boolean);
|
||||||
|
if (ids.length > 0) {
|
||||||
|
try {
|
||||||
|
const orderRes = await fetchOrdersByIds(ids.join(","));
|
||||||
|
const orderArr = Array.isArray(orderRes)
|
||||||
|
? orderRes
|
||||||
|
: orderRes?.data || [];
|
||||||
|
const orderMap = {};
|
||||||
|
orderArr.forEach((o) => {
|
||||||
|
orderMap[o.id] = o;
|
||||||
|
});
|
||||||
|
tableData.value = list.map((r) => {
|
||||||
|
const eid = r.deduction_details?.erpOrderId;
|
||||||
|
return { ...r, _order: orderMap[eid] || null };
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// 订单查询失败不影响主列表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 拦截器已处理
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.card-header {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user