refactor(prefetch): 拆分预拉取订单日志和列表为独立组件

- 将预拉取订单日志相关代码拆分到 prefetch-logs 组件中
- 将预拉取订单列表相关代码拆分到 prefetch-orders 组件中
- 在主页面使用 prefetch-logs 和 prefetch-orders 组件替代原内嵌实现
- 优化主页面代码结构,移除重复和冗余的代码
- 保持功能与交互不变,方便后续维护与扩展
This commit is contained in:
danial
2025-12-06 00:33:29 +08:00
parent 00c06d461d
commit 98777f50d8
3 changed files with 650 additions and 654 deletions

View File

@@ -0,0 +1,284 @@
<template>
<div class="prefetch-logs">
<!-- 搜索表单区域 -->
<a-row>
<a-col :flex="1">
<a-form
:model="formModel"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }"
label-align="left"
>
<a-row :gutter="16">
<a-col :span="8">
<a-form-item field="startTime" label="开始时间">
<a-date-picker
v-model="formModel.startTime"
style="width: 100%"
format="YYYY-MM-DD HH:mm:ss"
show-time
placeholder="请选择开始时间"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="endTime" label="结束时间">
<a-date-picker
v-model="formModel.endTime"
style="width: 100%"
format="YYYY-MM-DD HH:mm:ss"
show-time
placeholder="请选择结束时间"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-col>
<a-divider style="height: 42px" direction="vertical" />
<a-col flex="180px" style="text-align: right">
<a-space direction="horizontal" :size="18">
<a-button type="primary" @click="searchLogs">
<template #icon>
<icon-search />
</template>
搜索
</a-button>
<a-button @click="resetLogs">
<template #icon>
<icon-refresh />
</template>
重置
</a-button>
</a-space>
</a-col>
</a-row>
<a-divider style="margin-top: 0" />
<!-- 表格操作按钮 -->
<div class="table-actions">
<a-button @click="$emit('showSettings')">
<template #icon>
<icon-settings />
</template>
设置
</a-button>
</div>
<!-- 日志数据文本区域 -->
<div class="log-container">
<div class="log-header">
<span class="log-title">预拉取订单日志</span>
</div>
<div ref="logContentRef" class="log-content">
<div v-if="loading" class="log-loading">
<a-spin />
<span>加载日志中...</span>
</div>
<div v-else-if="logsRenderData.length === 0" class="log-empty">
暂无日志数据
</div>
<div v-else class="log-entries">
<div
v-for="(log, index) in logsRenderData"
:key="log.timestamp || index"
class="log-entry"
>
<div class="log-time">
{{ formatDateTime(log.timestamp) }}
</div>
<div class="log-response">
<div class="log-response-header">
<span>响应数据:</span>
</div>
<div class="log-response-content">
{{ log.responseData || '无响应数据' }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import type { KamiApiCamelOilV1PrefetchOrderLogItem } from '@/api/generated/index.ts';
import { jdV2PrefetchClient } from '@/api/index.ts';
import dayjs from 'dayjs';
interface Emits {
(e: 'showSettings'): void;
}
const emit = defineEmits<Emits>();
const { loading, setLoading } = useLoading(false);
const formModel = reactive({
startTime: null,
endTime: null
});
const logsRenderData = ref<KamiApiCamelOilV1PrefetchOrderLogItem[]>([]);
const generateFormModel = () => {
const now = dayjs();
return {
startTime: now.subtract(1, 'day').toDate(),
endTime: now.toDate()
};
};
// 初始化表单数据
formModel.startTime = generateFormModel().startTime;
formModel.endTime = generateFormModel().endTime;
const formatDateTime = (dateTime: string | undefined): string => {
if (!dateTime) return '-';
return dayjs(dateTime).format('YYYY-MM-DD HH:mm:ss');
};
const fetchLogs = async () => {
if (!formModel.startTime || !formModel.endTime) {
Message.warning({
content: '请选择开始时间和结束时间',
closable: true
});
setLoading(false);
return;
}
setLoading(true);
try {
const { data } = await jdV2PrefetchClient.apiJdV2PrefetchLogsGet({
startTime: dayjs(formModel.startTime).format('YYYY-MM-DD HH:mm:ss'),
endTime: dayjs(formModel.endTime).format('YYYY-MM-DD HH:mm:ss')
});
// 直接使用API返回的全部日志数据
logsRenderData.value = data.logs || [];
} catch (err) {
console.error('获取预拉取订单日志失败:', err);
Message.error({
content: '获取预拉取订单日志失败',
closable: true
});
} finally {
setLoading(false);
}
};
const searchLogs = () => {
fetchLogs();
};
const resetLogs = () => {
const defaultData = generateFormModel();
formModel.startTime = defaultData.startTime;
formModel.endTime = defaultData.endTime;
searchLogs();
};
// 组件挂载时加载数据
fetchLogs();
</script>
<style scoped>
.prefetch-logs {
width: 100%;
}
.table-actions {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
/* 日志容器样式 */
.log-container {
border: 1px solid var(--color-border-2);
border-radius: var(--border-radius-medium);
overflow: hidden;
}
.log-header {
padding: 12px 16px;
background-color: var(--color-fill-1);
border-bottom: 1px solid var(--color-border-2);
}
.log-title {
font-size: 14px;
font-weight: 500;
color: var(--color-text-1);
}
.log-content {
max-height: 600px;
overflow-y: auto;
background-color: var(--color-bg-2);
}
.log-loading,
.log-empty {
padding: 40px;
text-align: center;
color: var(--color-text-3);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.log-entries {
padding: 16px;
}
.log-entry {
margin-bottom: 16px;
padding: 12px;
background-color: var(--color-bg-1);
border: 1px solid var(--color-border-2);
border-radius: var(--border-radius-small);
}
.log-entry:last-child {
margin-bottom: 0;
}
.log-time {
font-size: 12px;
color: var(--color-text-3);
margin-bottom: 8px;
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
}
.log-response-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.log-response-header span {
font-size: 13px;
font-weight: 500;
color: var(--color-text-1);
}
.log-response-content {
font-size: 12px;
color: var(--color-text-2);
line-height: 1.5;
word-break: break-all;
background-color: var(--color-fill-1);
padding: 8px;
border-radius: var(--border-radius-small);
max-height: 200px;
overflow-y: auto;
}
</style>

View File

@@ -0,0 +1,356 @@
<template>
<div class="prefetch-orders">
<!-- 搜索表单区域 -->
<a-row>
<a-col :flex="1">
<a-form
:model="formModel"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }"
label-align="left"
>
<a-row :gutter="16">
<a-col :span="6">
<a-form-item field="accountName" label="账号名称">
<a-input
v-model="formModel.accountName"
placeholder="请输入账号名称"
allow-clear
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item field="platformOrderNo" label="平台订单号">
<a-input
v-model="formModel.platformOrderNo"
placeholder="请输入平台订单号"
allow-clear
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item field="amount" label="订单金额">
<a-input-number
v-model="formModel.amount"
placeholder="请输入订单金额"
style="width: 100%"
:min="0"
:precision="2"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item field="status" label="状态">
<a-select
v-model="formModel.status"
placeholder="请选择状态"
allow-clear
>
<a-option :value="1">待匹配</a-option>
<a-option :value="2">已匹配</a-option>
<a-option :value="3">已过期</a-option>
<a-option :value="4">已失效</a-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="8">
<a-form-item field="dateRange" label="创建时间">
<a-range-picker
v-model="formModel.dateRange"
style="width: 100%"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
:placeholder="['开始日期', '结束日期']"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-col>
<a-divider style="height: 42px" direction="vertical" />
<a-col flex="180px" style="text-align: right">
<a-space direction="horizontal" :size="18">
<a-button type="primary" @click="searchOrders">
<template #icon>
<icon-search />
</template>
搜索
</a-button>
<a-button @click="resetOrders">
<template #icon>
<icon-refresh />
</template>
重置
</a-button>
</a-space>
</a-col>
</a-row>
<a-divider style="margin-top: 0" />
<!-- 订单数据表格区域 -->
<a-table
:loading="loading"
:data="ordersRenderData"
:columns="orderColumns"
:scroll="{ x: 1600 }"
:pagination="{
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
pageSizeOptions: [10, 20, 50, 100],
showPageSize: true
}"
row-key="id"
@page-change="onPageChange"
@page-size-change="onPageSizeChange"
>
<!-- 订单金额列模板 -->
<template #orderAmount="{ record }">
<span v-if="record.amount">¥{{ record.amount.toFixed(2) }}</span>
<span v-else>-</span>
</template>
<!-- 状态列模板 -->
<template #orderStatus="{ record }">
<a-tag v-if="record.status" :color="getStatusColor(record.status)">
{{ record.statusText || getStatusText(record.status) }}
</a-tag>
<span v-else>-</span>
</template>
<!-- 创建时间列模板 -->
<template #createdAt="{ record }">
<span v-if="record.createdAt">
{{ formatDateTime(record.createdAt) }}
</span>
<span v-else>-</span>
</template>
<!-- 匹配时间列模板 -->
<template #matchedAt="{ record }">
<span v-if="record.matchedAt">
{{ formatDateTime(record.matchedAt) }}
</span>
<span v-else>-</span>
</template>
<!-- 过期时间列模板 -->
<template #expireAt="{ record }">
<span v-if="record.expireAt">
{{ formatDateTime(record.expireAt) }}
</span>
<span v-else>-</span>
</template>
</a-table>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import type { Pagination } from '@/types/global';
import type { KamiApiCamelOilV1PrefetchOrderListItem } from '@/api/generated/index.ts';
import { jdV2PrefetchClient } from '@/api/index.ts';
import dayjs from 'dayjs';
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
const { loading, setLoading } = useLoading(false);
// 订单列表相关状态
const basePagination: Pagination = {
current: 1,
pageSize: 20
};
const pagination = reactive({
...basePagination
});
const ordersRenderData = ref<KamiApiCamelOilV1PrefetchOrderListItem[]>([]);
const generateOrderFormModel = () => {
return {
accountName: '',
platformOrderNo: '',
amount: undefined,
status: undefined,
dateRange: undefined as Array<string> | undefined
};
};
const formModel = ref(generateOrderFormModel());
const orderColumns: TableColumnData[] = [
{
title: '序号',
dataIndex: 'index',
width: 80,
render: ({ rowIndex }) => {
return rowIndex + 1 + (pagination.current - 1) * pagination.pageSize;
}
},
{
title: '账号名称',
dataIndex: 'accountName',
width: 120,
ellipsis: true,
tooltip: true
},
{
title: '平台订单号',
dataIndex: 'platformOrderNo',
width: 180,
ellipsis: true,
tooltip: true
},
{
title: '订单金额',
dataIndex: 'amount',
slotName: 'orderAmount',
width: 100
},
{
title: '状态',
dataIndex: 'status',
slotName: 'orderStatus',
width: 100
},
{
title: '匹配订单号',
dataIndex: 'orderNo',
width: 150,
ellipsis: true,
tooltip: true
},
{
title: '创建时间',
dataIndex: 'createdAt',
slotName: 'createdAt',
width: 160
},
{
title: '匹配时间',
dataIndex: 'matchedAt',
slotName: 'matchedAt',
width: 160
},
{
title: '过期时间',
dataIndex: 'expireAt',
slotName: 'expireAt',
width: 160
},
{
title: '失败原因',
dataIndex: 'failureReason',
width: 120,
ellipsis: true,
tooltip: true
},
{
title: '备注',
dataIndex: 'remark',
width: 120,
ellipsis: true,
tooltip: true
}
];
const formatDateTime = (dateTime: string | undefined): string => {
if (!dateTime) return '-';
return dayjs(dateTime).format('YYYY-MM-DD HH:mm:ss');
};
const getStatusText = (status: number): string => {
const statusMap: Record<number, string> = {
1: '待匹配',
2: '已匹配',
3: '已过期',
4: '已失效'
};
return statusMap[status] || '未知';
};
const getStatusColor = (status: number): string => {
const colorMap: Record<number, string> = {
1: 'blue', // 待匹配
2: 'green', // 已匹配
3: 'orange', // 已过期
4: 'red' // 已失效
};
return colorMap[status] || 'gray';
};
const fetchOrders = async (params: any = { current: 1, pageSize: 20 }) => {
setLoading(true);
try {
const requestParams: any = {
current: params.current,
pageSize: params.pageSize
};
// 添加搜索条件
if (formModel.value.accountName) {
requestParams.accountName = formModel.value.accountName;
}
if (formModel.value.platformOrderNo) {
requestParams.platformOrderNo = formModel.value.platformOrderNo;
}
if (formModel.value.amount) {
requestParams.amount = formModel.value.amount;
}
if (formModel.value.status) {
requestParams.status = formModel.value.status;
}
if (formModel.value.dateRange && formModel.value.dateRange.length === 2) {
requestParams.dateRange = formModel.value.dateRange;
}
const { data } =
await jdV2PrefetchClient.apiJdV2PrefetchOrdersGet(requestParams);
ordersRenderData.value = data.list || [];
pagination.current = params.current;
pagination.pageSize = params.pageSize;
pagination.total = data.total || 0;
} catch (err) {
console.error('获取预拉取订单列表失败:', err);
Message.error({
content: '获取预拉取订单列表失败',
closable: true
});
} finally {
setLoading(false);
}
};
const onPageChange = (current: number) => {
fetchOrders({ ...pagination, current });
};
const onPageSizeChange = (pageSize: number) => {
fetchOrders({ ...pagination, pageSize, current: 1 });
};
const searchOrders = () => {
fetchOrders({
...basePagination
});
};
const resetOrders = () => {
formModel.value = generateOrderFormModel();
searchOrders();
};
// 组件挂载时加载数据
fetchOrders();
</script>
<style scoped>
.prefetch-orders {
width: 100%;
}
</style>

View File

@@ -10,269 +10,14 @@
</a-radio-group>
</template>
<!-- 预拉取订单日志内容 -->
<div v-show="activeView === 'logs'">
<!-- 搜索表单区域 -->
<a-row>
<a-col :flex="1">
<a-form
:model="logFormModel"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }"
label-align="left"
>
<a-row :gutter="16">
<a-col :span="8">
<a-form-item field="startTime" label="开始时间">
<a-date-picker
v-model="logFormModel.startTime"
style="width: 100%"
format="YYYY-MM-DD HH:mm:ss"
show-time
placeholder="请选择开始时间"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="endTime" label="结束时间">
<a-date-picker
v-model="logFormModel.endTime"
style="width: 100%"
format="YYYY-MM-DD HH:mm:ss"
show-time
placeholder="请选择结束时间"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-col>
<a-divider style="height: 42px" direction="vertical" />
<a-col flex="180px" style="text-align: right">
<a-space direction="horizontal" :size="18">
<a-button type="primary" @click="searchLogs">
<template #icon>
<icon-search />
</template>
搜索
</a-button>
<a-button @click="resetLogs">
<template #icon>
<icon-refresh />
</template>
重置
</a-button>
</a-space>
</a-col>
</a-row>
<a-divider style="margin-top: 0" />
<!-- 预拉取订单日志组件 -->
<prefetch-logs
v-if="activeView === 'logs'"
@showSettings="showSettingsModal"
/>
<!-- 表格操作按钮 -->
<div class="table-actions">
<a-button @click="showSettingsModal">
<template #icon>
<icon-settings />
</template>
设置
</a-button>
</div>
<!-- 日志数据文本区域 -->
<div class="log-container">
<div class="log-header">
<a-space>
<a-button size="small" @click="copyLogs">
<template #icon>
<icon-copy />
</template>
复制日志
</a-button>
<a-button size="small" @click="clearLogs">
<template #icon>
<icon-delete />
</template>
清空日志
</a-button>
</a-space>
</div>
<div ref="logContentRef" class="log-content">
<div v-if="logsLoading" class="log-loading">
<a-spin />
<span>加载日志中...</span>
</div>
<div v-else-if="logsRenderData.length === 0" class="log-empty">
暂无日志数据
</div>
<div v-else class="log-entries">
<div
v-for="(log, index) in logsRenderData"
:key="log.timestamp || index"
class="log-entry"
>
<div class="log-time">
{{ formatDateTime(log.timestamp) }}
</div>
<div class="log-response">
<div class="log-response-header">
<span>响应数据:</span>
</div>
<div class="log-response-content">
{{ log.responseData || '无响应数据' }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 预拉取订单列表内容 -->
<div v-show="activeView === 'orders'">
<!-- 搜索表单区域 -->
<a-row>
<a-col :flex="1">
<a-form
:model="orderFormModel"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }"
label-align="left"
>
<a-row :gutter="16">
<a-col :span="6">
<a-form-item field="accountName" label="账号名称">
<a-input
v-model="orderFormModel.accountName"
placeholder="请输入账号名称"
allow-clear
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item field="platformOrderNo" label="平台订单号">
<a-input
v-model="orderFormModel.platformOrderNo"
placeholder="请输入平台订单号"
allow-clear
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item field="amount" label="订单金额">
<a-input-number
v-model="orderFormModel.amount"
placeholder="请输入订单金额"
style="width: 100%"
:min="0"
:precision="2"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item field="status" label="状态">
<a-select
v-model="orderFormModel.status"
placeholder="请选择状态"
allow-clear
>
<a-option :value="1">待匹配</a-option>
<a-option :value="2">已匹配</a-option>
<a-option :value="3">已过期</a-option>
<a-option :value="4">已失效</a-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="8">
<a-form-item field="dateRange" label="创建时间">
<a-range-picker
v-model="orderFormModel.dateRange"
style="width: 100%"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
:placeholder="['开始日期', '结束日期']"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-col>
<a-divider style="height: 42px" direction="vertical" />
<a-col flex="180px" style="text-align: right">
<a-space direction="horizontal" :size="18">
<a-button type="primary" @click="searchOrders">
<template #icon>
<icon-search />
</template>
搜索
</a-button>
<a-button @click="resetOrders">
<template #icon>
<icon-refresh />
</template>
重置
</a-button>
</a-space>
</a-col>
</a-row>
<a-divider style="margin-top: 0" />
<!-- 订单数据表格区域 -->
<a-table
:loading="ordersLoading"
:data="ordersRenderData"
:columns="orderColumns"
:scroll="{ x: 1600 }"
:pagination="{
current: ordersPagination.current,
pageSize: ordersPagination.pageSize,
total: ordersPagination.total,
pageSizeOptions: [10, 20, 50, 100],
showPageSize: true
}"
row-key="id"
@page-change="onOrdersPageChange"
@page-size-change="onOrdersPageSizeChange"
>
<!-- 订单金额列模板 -->
<template #orderAmount="{ record }">
<span v-if="record.amount">¥{{ record.amount.toFixed(2) }}</span>
<span v-else>-</span>
</template>
<!-- 状态列模板 -->
<template #orderStatus="{ record }">
<a-tag v-if="record.status" :color="getStatusColor(record.status)">
{{ record.statusText || getStatusText(record.status) }}
</a-tag>
<span v-else>-</span>
</template>
<!-- 创建时间列模板 -->
<template #createdAt="{ record }">
<span v-if="record.createdAt">
{{ formatDateTime(record.createdAt) }}
</span>
<span v-else>-</span>
</template>
<!-- 匹配时间列模板 -->
<template #matchedAt="{ record }">
<span v-if="record.matchedAt">
{{ formatDateTime(record.matchedAt) }}
</span>
<span v-else>-</span>
</template>
<!-- 过期时间列模板 -->
<template #expireAt="{ record }">
<span v-if="record.expireAt">
{{ formatDateTime(record.expireAt) }}
</span>
<span v-else>-</span>
</template>
</a-table>
</div>
<!-- 预拉取订单列表组件 -->
<prefetch-orders v-else />
</a-card>
<!-- 设置配置弹窗 -->
@@ -289,17 +34,10 @@
</template>
<script lang="ts" setup>
import useLoading from '@/hooks/loading';
import { Pagination } from '@/types/global';
import { onMounted, reactive, ref, computed, watch } from 'vue';
import { Notification, Message } from '@arco-design/web-vue';
import { ref, reactive, computed } from 'vue';
import SettingsForm from './components/settings-form.vue';
import type {
KamiApiCamelOilV1PrefetchOrderLogItem,
KamiApiCamelOilV1PrefetchOrderListItem
} from '@/api/generated/index.ts';
import { jdV2PrefetchClient } from '@/api/index.ts';
import dayjs from 'dayjs';
import PrefetchLogs from './components/prefetch-logs.vue';
import PrefetchOrders from './components/prefetch-orders.vue';
// 当前活跃视图
const activeView = ref('logs');
@@ -309,309 +47,13 @@ const cardTitle = computed(() => {
return activeView.value === 'logs' ? '预拉取订单日志' : '预拉取订单列表';
});
// 订单列表相关状态
const baseOrdersPagination: Pagination = {
current: 1,
pageSize: 20
};
const ordersPagination = reactive({
...baseOrdersPagination
});
const generateLogFormModel = () => {
const now = dayjs();
return {
startTime: now.subtract(1, 'day').toDate(),
endTime: now.toDate()
};
};
const { loading: logsLoading, setLoading: setLogsLoading } = useLoading(false);
const logsRenderData = ref<KamiApiCamelOilV1PrefetchOrderLogItem[]>([]);
const logFormModel = ref(generateLogFormModel());
const { loading: ordersLoading, setLoading: setOrdersLoading } =
useLoading(false);
const ordersRenderData = ref<KamiApiCamelOilV1PrefetchOrderListItem[]>([]);
const generateOrderFormModel = () => {
return {
accountName: '',
platformOrderNo: '',
amount: undefined,
status: undefined,
dateRange: undefined as Array<string> | undefined
};
};
const orderFormModel = ref(generateOrderFormModel());
const orderColumns = [
{
title: '序号',
dataIndex: 'index',
width: 80,
render: ({ rowIndex }) => {
return (
rowIndex +
1 +
(ordersPagination.current - 1) * ordersPagination.pageSize
);
}
},
{
title: '账号名称',
dataIndex: 'accountName',
width: 120,
ellipsis: true,
tooltip: true
},
{
title: '平台订单号',
dataIndex: 'platformOrderNo',
width: 180,
ellipsis: true,
tooltip: true
},
{
title: '订单金额',
dataIndex: 'amount',
slotName: 'orderAmount',
width: 100
},
{
title: '状态',
dataIndex: 'status',
slotName: 'orderStatus',
width: 100
},
{
title: '匹配订单号',
dataIndex: 'orderNo',
width: 150,
ellipsis: true,
tooltip: true
},
{
title: '创建时间',
dataIndex: 'createdAt',
slotName: 'createdAt',
width: 160
},
{
title: '匹配时间',
dataIndex: 'matchedAt',
slotName: 'matchedAt',
width: 160
},
{
title: '过期时间',
dataIndex: 'expireAt',
slotName: 'expireAt',
width: 160
},
{
title: '失败原因',
dataIndex: 'failureReason',
width: 120,
ellipsis: true,
tooltip: true
},
{
title: '备注',
dataIndex: 'remark',
width: 120,
ellipsis: true,
tooltip: true
}
];
const state = reactive({
settingsModalVisible: false
});
// 日志相关方法
const fetchLogs = async () => {
if (!logFormModel.value.startTime || !logFormModel.value.endTime) {
Notification.warning({
content: '请选择开始时间和结束时间',
closable: true
});
setLogsLoading(false);
return;
}
setLogsLoading(true);
try {
const { data } = await jdV2PrefetchClient.apiJdV2PrefetchLogsGet({
startTime: dayjs(logFormModel.value.startTime).format(
'YYYY-MM-DD HH:mm:ss'
),
endTime: dayjs(logFormModel.value.endTime).format('YYYY-MM-DD HH:mm:ss')
});
// 直接使用API返回的全部日志数据
logsRenderData.value = data.logs || [];
} catch (err) {
console.error('获取预拉取订单日志失败:', err);
Notification.error({
content: '获取预拉取订单日志失败',
closable: true
});
} finally {
setLogsLoading(false);
}
};
const searchLogs = () => {
fetchLogs();
};
const resetLogs = () => {
logFormModel.value = generateLogFormModel();
searchLogs();
};
const copyLogs = async () => {
try {
const logText = logsRenderData.value
.map(log => {
const time = formatDateTime(log.timestamp);
const data = log.responseData || '无响应数据';
return `[${time}] ${data}`;
})
.join('\n\n');
await navigator.clipboard.writeText(logText);
Message.success({
content: '日志复制成功',
duration: 2000
});
} catch (err) {
console.error('复制日志失败:', err);
Message.error({
content: '复制日志失败',
duration: 2000
});
}
};
const clearLogs = () => {
logsRenderData.value = [];
Message.info({
content: '日志已清空',
duration: 2000
});
};
const showSettingsModal = () => {
state.settingsModalVisible = true;
};
const formatDateTime = (dateTime: string | undefined): string => {
if (!dateTime) return '-';
return dayjs(dateTime).format('YYYY-MM-DD HH:mm:ss');
};
// 订单列表相关方法
const fetchOrders = async (params: any = { current: 1, pageSize: 20 }) => {
setOrdersLoading(true);
try {
const requestParams: any = {
current: params.current,
pageSize: params.pageSize
};
// 添加搜索条件
if (orderFormModel.value.accountName) {
requestParams.accountName = orderFormModel.value.accountName;
}
if (orderFormModel.value.platformOrderNo) {
requestParams.platformOrderNo = orderFormModel.value.platformOrderNo;
}
if (orderFormModel.value.amount) {
requestParams.amount = orderFormModel.value.amount;
}
if (orderFormModel.value.status) {
requestParams.status = orderFormModel.value.status;
}
if (
orderFormModel.value.dateRange &&
orderFormModel.value.dateRange.length === 2
) {
requestParams.dateRange = orderFormModel.value.dateRange;
}
const { data } =
await jdV2PrefetchClient.apiJdV2PrefetchOrdersGet(requestParams);
ordersRenderData.value = data.list || [];
ordersPagination.current = params.current;
ordersPagination.pageSize = params.pageSize;
ordersPagination.total = data.total || 0;
} catch (err) {
console.error('获取预拉取订单列表失败:', err);
Notification.error({
content: '获取预拉取订单列表失败',
closable: true
});
} finally {
setOrdersLoading(false);
}
};
const onOrdersPageChange = (current: number) => {
fetchOrders({ ...ordersPagination, current });
};
const onOrdersPageSizeChange = (pageSize: number) => {
fetchOrders({ ...ordersPagination, pageSize, current: 1 });
};
const searchOrders = () => {
fetchOrders({
...baseOrdersPagination
});
};
const resetOrders = () => {
orderFormModel.value = generateOrderFormModel();
searchOrders();
};
// 状态相关方法
const getStatusText = (status: number): string => {
const statusMap: Record<number, string> = {
1: '待匹配',
2: '已匹配',
3: '已过期',
4: '已失效'
};
return statusMap[status] || '未知';
};
const getStatusColor = (status: number): string => {
const colorMap: Record<number, string> = {
1: 'blue', // 待匹配
2: 'green', // 已匹配
3: 'orange', // 已过期
4: 'red' // 已失效
};
return colorMap[status] || 'gray';
};
// 视图切换处理
watch(activeView, newValue => {
if (newValue === 'orders' && ordersRenderData.value.length === 0) {
// 首次切换到订单列表视图时加载数据
fetchOrders();
}
});
onMounted(() => {
// 页面加载时默认加载日志数据
fetchLogs();
});
</script>
<style scoped>
@@ -622,90 +64,4 @@ onMounted(() => {
.general-card {
min-height: calc(100vh - 200px);
}
.table-actions {
display: flex;
justify-content: flex-end;
margin-bottom: 16px;
}
/* 日志容器样式 */
.log-container {
border: 1px solid var(--color-border-2);
border-radius: var(--border-radius-medium);
overflow: hidden;
}
.log-header {
padding: 12px 16px;
background-color: var(--color-fill-1);
border-bottom: 1px solid var(--color-border-2);
display: flex;
justify-content: flex-end;
}
.log-content {
max-height: 600px;
overflow-y: auto;
background-color: var(--color-bg-2);
}
.log-loading,
.log-empty {
padding: 40px;
text-align: center;
color: var(--color-text-3);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.log-entries {
padding: 16px;
}
.log-entry {
margin-bottom: 16px;
padding: 12px;
background-color: var(--color-bg-1);
border: 1px solid var(--color-border-2);
border-radius: var(--border-radius-small);
}
.log-entry:last-child {
margin-bottom: 0;
}
.log-time {
font-size: 12px;
color: var(--color-text-3);
margin-bottom: 8px;
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
}
.log-response-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.log-response-header span {
font-size: 13px;
font-weight: 500;
color: var(--color-text-1);
}
.log-response-content {
font-size: 12px;
color: var(--color-text-2);
line-height: 1.5;
word-break: break-all;
background-color: var(--color-fill-1);
padding: 8px;
border-radius: var(--border-radius-small);
max-height: 200px;
overflow-y: auto;
}
</style>