增加订单推送日志、分账日志
Some checks failed
CI / build (18.x) (push) Failing after 13m28s
CI / build (20.x) (push) Failing after 16m46s
CI / deploy-preview (push) Has been skipped
CI / lint (push) Failing after 14m54s
CI / test (push) Successful in 21m3s
CI / security (push) Failing after 1m34s

This commit is contained in:
凌尛 2026-06-30 10:01:56 +08:00
parent fac91a81e2
commit 02373f243e
6 changed files with 922 additions and 0 deletions

22
src/api/orderQueue.js Normal file
View 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
}

View 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
}

View File

@ -48,6 +48,7 @@
</template>
<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-sub-menu>
<!-- 以下菜单 - 所有登录用户可见 -->
@ -173,6 +174,16 @@
<span>销毁记录</span>
</el-menu-item>
</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">
<template #title>
<el-icon>

View File

@ -196,6 +196,15 @@ const routes = [
// 普通用户也可访问
}
},
{
path: 'order-push',
name: 'OrderPush',
component: () => import('@/views/orderLog/orderPush.vue'),
meta: {
title: '订单推送',
requiresAuth: true
}
},
{
path: 'sales-order',
name: 'sales-order',
@ -369,6 +378,16 @@ const routes = [
requiresAuth: true,
requiresAdmin: true
}
},
{
path: 'split-account-log',
name: 'SplitAccountLog',
component: () => import('@/views/splitAccount/SplitAccountLog.vue'),
meta: {
title: '分账日志',
requiresAuth: true,
requiresAdmin: true
}
}
]
},

View 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>

View 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>