chore(api): 修复cookie列表错误
修复cookie列表错误
This commit is contained in:
@@ -22,16 +22,6 @@ const JDOrder: AppRouteRecordRaw = {
|
||||
roles: ['*']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'cookie-history',
|
||||
name: 'jdOrderCookieHistory',
|
||||
component: () => import('@/views/jd-order/cookie/history.vue'),
|
||||
meta: {
|
||||
locale: 'Cookie变更历史',
|
||||
requiresAuth: true,
|
||||
roles: ['*']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'order',
|
||||
name: 'jdOrderManagement',
|
||||
@@ -43,11 +33,11 @@ const JDOrder: AppRouteRecordRaw = {
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'order-history',
|
||||
name: 'jdOrderHistory',
|
||||
component: () => import('@/views/jd-order/order/history.vue'),
|
||||
path: 'jd-orders',
|
||||
name: 'jdOrders',
|
||||
component: () => import('@/views/jd-order/jd-orders/index.vue'),
|
||||
meta: {
|
||||
locale: '订单变更历史',
|
||||
locale: '京东订单',
|
||||
requiresAuth: true,
|
||||
roles: ['*']
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ const { loading, setLoading } = useLoading(false);
|
||||
|
||||
const emit = defineEmits(['update:visible']);
|
||||
const handleOk = (done: (closed: boolean) => void) => {
|
||||
formDataRef.value.validate().then(async res => {
|
||||
formDataRef.value.validate().then(async (res: any) => {
|
||||
if (res) return done(false);
|
||||
try {
|
||||
setLoading(true);
|
||||
@@ -101,6 +101,7 @@ const handleOk = (done: (closed: boolean) => void) => {
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log('success');
|
||||
done(true);
|
||||
emit('update:visible', false);
|
||||
formData.value = generateFormData();
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
<template>
|
||||
<a-button @click="handleClick">
|
||||
<template #icon>
|
||||
<icon-upload />
|
||||
</template>
|
||||
批量导入
|
||||
</a-button>
|
||||
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="批量导入Cookie"
|
||||
:visible="visible"
|
||||
title="批量添加Cookie"
|
||||
width="600px"
|
||||
@cancel="handleCancel"
|
||||
@before-ok="handleSubmit"
|
||||
@@ -17,15 +10,13 @@
|
||||
<a-form-item label="Cookie数据">
|
||||
<a-textarea
|
||||
v-model="formModel.cookieData"
|
||||
placeholder="每行一个Cookie,格式:cookie值 昵称 邮箱 余额"
|
||||
placeholder="每行一个Cookie,格式:Cookie值,昵称,备注"
|
||||
:auto-size="{ minRows: 6, maxRows: 12 }"
|
||||
placeholder-class="batch-textarea"
|
||||
/>
|
||||
<div class="tip-text">
|
||||
<icon-info-circle />
|
||||
<span>
|
||||
支持批量粘贴,每行一个Cookie,格式:Cookie值,昵称,邮箱,余额
|
||||
</span>
|
||||
<span>支持批量粘贴,每行一个Cookie,格式:Cookie值,昵称,备注</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -37,13 +28,18 @@ import { ref, reactive } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { jdCookieClient } from '@/api';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
(e: 'success'): void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
@@ -51,12 +47,8 @@ const formModel = reactive({
|
||||
cookieData: ''
|
||||
});
|
||||
|
||||
const handleClick = (): void => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const handleCancel = (): void => {
|
||||
visible.value = false;
|
||||
emit('update:visible', false);
|
||||
formModel.cookieData = '';
|
||||
};
|
||||
|
||||
@@ -79,7 +71,7 @@ const handleSubmit = async (): Promise<boolean> => {
|
||||
return {
|
||||
cookieValue: parts[0] || '',
|
||||
accountName: parts[1] || '',
|
||||
remark: `批量导入于 ${new Date().toLocaleString()}`
|
||||
remark: `批量添加于 ${new Date().toLocaleString()}`
|
||||
};
|
||||
})
|
||||
.filter(account => account.cookieValue);
|
||||
@@ -96,11 +88,11 @@ const handleSubmit = async (): Promise<boolean> => {
|
||||
}
|
||||
});
|
||||
|
||||
Message.success(`成功导入 ${cookieAccounts.length} 个Cookie`);
|
||||
Message.success(`成功添加 ${cookieAccounts.length} 个Cookie`);
|
||||
emit('success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
Message.error('批量导入失败');
|
||||
Message.error('批量添加失败');
|
||||
return false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
||||
417
src/views/jd-order/cookie/components/cookie-history-drawer.vue
Normal file
417
src/views/jd-order/cookie/components/cookie-history-drawer.vue
Normal file
@@ -0,0 +1,417 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:visible="visible"
|
||||
:width="800"
|
||||
:title="`Cookie变更记录 - ${cookieId}`"
|
||||
:footer="false"
|
||||
unmount-on-close
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-spin :loading="loading" style="width: 100%">
|
||||
<div v-if="historyData.length > 0" class="history-container">
|
||||
<a-timeline>
|
||||
<a-timeline-item
|
||||
v-for="(item, index) in historyData"
|
||||
:key="item.historyUuid || index"
|
||||
:dot-color="getTimelineDotColor(item.changeType)"
|
||||
:dot-type="index === 0 ? 'filled' : 'hollow'"
|
||||
>
|
||||
<div class="timeline-content">
|
||||
<!-- 变更时间和类型 -->
|
||||
<div class="timeline-header">
|
||||
<div class="time-info">
|
||||
<span class="change-time">
|
||||
{{ formatTime(item.createdAt) }}
|
||||
</span>
|
||||
<a-tag
|
||||
:color="getChangeTypeColor(item.changeType)"
|
||||
size="small"
|
||||
>
|
||||
{{ getChangeTypeText(item.changeType) }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 状态变更信息 -->
|
||||
<div
|
||||
v-if="
|
||||
item.statusBefore !== undefined &&
|
||||
item.statusAfter !== undefined
|
||||
"
|
||||
class="status-change"
|
||||
>
|
||||
<div class="status-info">
|
||||
<span class="label">状态变更:</span>
|
||||
<a-tag
|
||||
:color="getStatusColor(item.statusBefore)"
|
||||
size="small"
|
||||
class="status-before"
|
||||
>
|
||||
{{ getStatusText(item.statusBefore) }}
|
||||
</a-tag>
|
||||
<icon-right class="arrow-icon" />
|
||||
<a-tag
|
||||
:color="getStatusColor(item.statusAfter)"
|
||||
size="small"
|
||||
class="status-after"
|
||||
>
|
||||
{{ getStatusText(item.statusAfter) }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 失败次数 -->
|
||||
<div
|
||||
v-if="item.failureCount && item.failureCount > 0"
|
||||
class="failure-info"
|
||||
>
|
||||
<span class="label">失败次数:</span>
|
||||
<a-tag color="red" size="small">
|
||||
{{ item.failureCount }} 次
|
||||
</a-tag>
|
||||
</div>
|
||||
|
||||
<!-- 关联订单 -->
|
||||
<div v-if="item.userOrderId" class="order-info">
|
||||
<span class="label">关联订单:</span>
|
||||
<a-typography-text
|
||||
copyable
|
||||
:content="item.userOrderId"
|
||||
class="order-id"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 历史记录ID -->
|
||||
<div class="history-id">
|
||||
<span class="label">记录ID:</span>
|
||||
<a-typography-text
|
||||
copyable
|
||||
:content="item.historyUuid || ''"
|
||||
class="uuid-text"
|
||||
type="secondary"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<div v-if="hasMore" class="load-more">
|
||||
<a-button :loading="loadingMore" type="outline" @click="loadMore">
|
||||
加载更多
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-empty v-else description="暂无变更记录" />
|
||||
</a-spin>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { IconRight } from '@arco-design/web-vue/es/icon';
|
||||
import { JDHistoryApi } from '@/api/generated';
|
||||
import type { KamiApiJdCookieV1CookieHistoryInfo } from '@/api/generated';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
cookieId: string;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const historyApi = new JDHistoryApi();
|
||||
|
||||
// 状态管理
|
||||
const loading = ref(false);
|
||||
const loadingMore = ref(false);
|
||||
const historyData = ref<KamiApiJdCookieV1CookieHistoryInfo[]>([]);
|
||||
const hasMore = ref(false);
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0
|
||||
});
|
||||
|
||||
// 处理取消
|
||||
const handleCancel = (): void => {
|
||||
emit('update:visible', false);
|
||||
};
|
||||
|
||||
// 格式化时间
|
||||
const formatTime = (timeStr?: string): string => {
|
||||
if (!timeStr) return '-';
|
||||
try {
|
||||
const date = new Date(timeStr);
|
||||
return date.toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
});
|
||||
} catch {
|
||||
return timeStr;
|
||||
}
|
||||
};
|
||||
|
||||
// 获取时间线节点颜色
|
||||
const getTimelineDotColor = (changeType?: string): string => {
|
||||
switch (changeType) {
|
||||
case 'status_change':
|
||||
return '#165DFF';
|
||||
case 'failure_reset':
|
||||
return '#FF7D00';
|
||||
case 'auto_suspend':
|
||||
return '#F53F3F';
|
||||
case 'manual_resume':
|
||||
return '#00B42A';
|
||||
case 'order_check':
|
||||
return '#722ED1';
|
||||
default:
|
||||
return '#86909C';
|
||||
}
|
||||
};
|
||||
|
||||
// 获取变更类型颜色
|
||||
const getChangeTypeColor = (changeType?: string): string => {
|
||||
switch (changeType) {
|
||||
case 'status_change':
|
||||
return 'blue';
|
||||
case 'failure_reset':
|
||||
return 'orange';
|
||||
case 'auto_suspend':
|
||||
return 'red';
|
||||
case 'manual_resume':
|
||||
return 'green';
|
||||
case 'order_check':
|
||||
return 'purple';
|
||||
default:
|
||||
return 'gray';
|
||||
}
|
||||
};
|
||||
|
||||
// 获取变更类型文本
|
||||
const getChangeTypeText = (changeType?: string): string => {
|
||||
switch (changeType) {
|
||||
case 'status_change':
|
||||
return '状态变更';
|
||||
case 'failure_reset':
|
||||
return '失败次数重置';
|
||||
case 'auto_suspend':
|
||||
return '自动暂停';
|
||||
case 'manual_resume':
|
||||
return '手动恢复';
|
||||
case 'order_check':
|
||||
return '订单检查';
|
||||
default:
|
||||
return changeType || '未知';
|
||||
}
|
||||
};
|
||||
|
||||
// 获取状态颜色
|
||||
const getStatusColor = (status?: number): string => {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return 'green';
|
||||
case 2:
|
||||
return 'orange';
|
||||
case 3:
|
||||
return 'red';
|
||||
default:
|
||||
return 'gray';
|
||||
}
|
||||
};
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status?: number): string => {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return '正常';
|
||||
case 2:
|
||||
return '暂停';
|
||||
case 3:
|
||||
return '失效';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
};
|
||||
|
||||
// 获取变更记录数据
|
||||
const fetchHistoryData = async (isLoadMore = false): Promise<void> => {
|
||||
if (!props.cookieId) return;
|
||||
|
||||
if (isLoadMore) {
|
||||
loadingMore.value = true;
|
||||
} else {
|
||||
loading.value = true;
|
||||
pagination.current = 1;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await historyApi.apiJdCookieHistoryCookieGet({
|
||||
cookieId: props.cookieId,
|
||||
page: pagination.current,
|
||||
size: pagination.pageSize
|
||||
});
|
||||
|
||||
const newData = response.data.list || [];
|
||||
|
||||
if (isLoadMore) {
|
||||
historyData.value = [...historyData.value, ...newData];
|
||||
} else {
|
||||
historyData.value = newData;
|
||||
}
|
||||
|
||||
pagination.total = response.data.total || 0;
|
||||
hasMore.value = historyData.value.length < pagination.total;
|
||||
} catch (error) {
|
||||
Message.error('获取变更记录失败');
|
||||
if (!isLoadMore) {
|
||||
historyData.value = [];
|
||||
pagination.total = 0;
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
loadingMore.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 加载更多
|
||||
const loadMore = (): void => {
|
||||
pagination.current += 1;
|
||||
fetchHistoryData(true);
|
||||
};
|
||||
|
||||
// 监听弹窗显示状态
|
||||
watch(
|
||||
() => props.visible,
|
||||
newVal => {
|
||||
if (newVal && props.cookieId) {
|
||||
pagination.current = 1;
|
||||
historyData.value = [];
|
||||
fetchHistoryData();
|
||||
} else {
|
||||
historyData.value = [];
|
||||
pagination.total = 0;
|
||||
hasMore.value = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.history-container {
|
||||
max-height: calc(100vh - 120px);
|
||||
overflow-y: auto;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.time-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.change-time {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
|
||||
.status-change {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
color: var(--color-text-3);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.failure-info,
|
||||
.order-info,
|
||||
.history-id {
|
||||
margin: 4px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 13px;
|
||||
color: var(--color-text-3);
|
||||
min-width: 70px;
|
||||
}
|
||||
|
||||
.order-id {
|
||||
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.uuid-text {
|
||||
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.load-more {
|
||||
text-align: center;
|
||||
margin-top: 24px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--color-border-2);
|
||||
}
|
||||
|
||||
:deep(.arco-timeline-item-content) {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
:deep(.arco-timeline-item:last-child .arco-timeline-item-content) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.history-container::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.history-container::-webkit-scrollbar-track {
|
||||
background: var(--color-fill-1);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.history-container::-webkit-scrollbar-thumb {
|
||||
background: var(--color-border-3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.history-container::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--color-border-4);
|
||||
}
|
||||
</style>
|
||||
@@ -1,319 +0,0 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:visible="visible"
|
||||
title="Cookie变更历史"
|
||||
width="900px"
|
||||
footer
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<template v-if="cookieId">
|
||||
<!-- 筛选条件 -->
|
||||
<a-row style="margin-bottom: 16px">
|
||||
<a-col :flex="1">
|
||||
<a-form :model="filterModel" layout="inline">
|
||||
<a-form-item field="changeType" label="变更类型">
|
||||
<a-select
|
||||
v-model="filterModel.changeType"
|
||||
placeholder="请选择变更类型"
|
||||
allow-clear
|
||||
style="width: 200px"
|
||||
@change="fetchHistory"
|
||||
>
|
||||
<a-option value="create">创建</a-option>
|
||||
<a-option value="update">更新</a-option>
|
||||
<a-option value="status_change">状态变更</a-option>
|
||||
<a-option value="balance_change">余额变更</a-option>
|
||||
<a-option value="delete">删除</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-col>
|
||||
<a-col flex="100px">
|
||||
<a-button @click="fetchHistory">
|
||||
<template #icon>
|
||||
<icon-refresh />
|
||||
</template>
|
||||
刷新
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 时间线 -->
|
||||
<a-timeline v-if="historyData.length > 0" class="history-timeline">
|
||||
<a-timeline-item
|
||||
v-for="(item, index) in historyData"
|
||||
:key="index"
|
||||
:dot-color="getTimelineColor(item.changeType)"
|
||||
>
|
||||
<template #dot>
|
||||
<icon-check-circle-fill v-if="item.changeType === 'create'" />
|
||||
<icon-edit-fill v-else-if="item.changeType === 'update'" />
|
||||
<icon-exclamation-circle-fill
|
||||
v-else-if="item.changeType === 'status_change'"
|
||||
/>
|
||||
<icon-dollar-circle-fill
|
||||
v-else-if="item.changeType === 'balance_change'"
|
||||
/>
|
||||
<icon-close-circle-fill v-else-if="item.changeType === 'delete'" />
|
||||
<icon-info-circle-fill v-else />
|
||||
</template>
|
||||
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-title">
|
||||
{{ getChangeTypeText(item.changeType) }}
|
||||
</span>
|
||||
<a-tag :color="getChangeTypeColor(item.changeType)" size="small">
|
||||
{{ item.changeType }}
|
||||
</a-tag>
|
||||
</div>
|
||||
|
||||
<div class="timeline-time">
|
||||
<icon-clock-circle />
|
||||
{{ item.createdAt }}
|
||||
</div>
|
||||
|
||||
<div class="timeline-description">
|
||||
<a-descriptions :column="1" size="small" bordered>
|
||||
<a-descriptions-item label="变更类型">
|
||||
{{ item.changeType }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
v-if="item.statusBefore"
|
||||
label="变更前状态"
|
||||
>
|
||||
<a-tag :color="item.statusBefore === 1 ? 'green' : 'red'">
|
||||
{{ item.statusBefore === 1 ? '正常' : '失效' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="item.statusAfter" label="变更后状态">
|
||||
<a-tag :color="item.statusAfter === 1 ? 'green' : 'red'">
|
||||
{{ item.statusAfter === 1 ? '正常' : '失效' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="item.userOrderId" label="关联订单">
|
||||
{{ item.userOrderId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<a-empty v-else description="暂无变更历史" />
|
||||
|
||||
<!-- 分页 -->
|
||||
<div v-if="historyData.length > 0" class="pagination-wrapper">
|
||||
<a-pagination
|
||||
:current="pagination.current"
|
||||
:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:show-total="true"
|
||||
:show-page-size="true"
|
||||
:page-size-options="[10, 20, 50, 100]"
|
||||
@change="onPageChange"
|
||||
@page-size-change="onPageSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<a-empty v-else description="请选择Cookie查看历史记录" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { jdHistoryClient } from '@/api';
|
||||
import type { KamiApiJdCookieV1CookieHistoryInfo } from '@/api/generated';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
cookieId: string;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
}
|
||||
|
||||
interface FilterModel {
|
||||
changeType: string | undefined;
|
||||
}
|
||||
|
||||
interface Pagination {
|
||||
current: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const historyData = ref<KamiApiJdCookieV1CookieHistoryInfo[]>([]);
|
||||
const loading = ref(false);
|
||||
|
||||
// 处理取消
|
||||
const handleCancel = (): void => {
|
||||
emit('update:visible', false);
|
||||
};
|
||||
const filterModel = reactive<FilterModel>({
|
||||
changeType: undefined
|
||||
});
|
||||
const pagination = reactive<Pagination>({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0
|
||||
});
|
||||
|
||||
// 监听弹窗显示状态
|
||||
watch(
|
||||
() => props.visible,
|
||||
newVal => {
|
||||
if (newVal && props.cookieId) {
|
||||
fetchHistory();
|
||||
} else {
|
||||
historyData.value = [];
|
||||
pagination.current = 1;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 获取历史记录
|
||||
const fetchHistory = async (): Promise<void> => {
|
||||
if (!props.cookieId) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await jdHistoryClient.apiJdCookieHistoryCookieGet({
|
||||
cookieId: props.cookieId,
|
||||
page: pagination.current,
|
||||
size: pagination.pageSize,
|
||||
changeType: filterModel.changeType
|
||||
});
|
||||
|
||||
historyData.value = response.data.list || [];
|
||||
pagination.total = response.data.total || 0;
|
||||
} catch (error) {
|
||||
Message.error('获取变更历史失败');
|
||||
historyData.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const onPageChange = (current: number): void => {
|
||||
pagination.current = current;
|
||||
fetchHistory();
|
||||
};
|
||||
|
||||
const onPageSizeChange = (pageSize: number): void => {
|
||||
pagination.pageSize = pageSize;
|
||||
pagination.current = 1;
|
||||
fetchHistory();
|
||||
};
|
||||
|
||||
// 获取时间线颜色
|
||||
const getTimelineColor = (changeType: string): string => {
|
||||
const colors: Record<string, string> = {
|
||||
create: '#00b42a',
|
||||
update: '#165dff',
|
||||
status_change: '#ff7d00',
|
||||
balance_change: '#722ed1',
|
||||
delete: '#f53f3f'
|
||||
};
|
||||
return colors[changeType] || '#86909c';
|
||||
};
|
||||
|
||||
// 获取变更类型文本
|
||||
const getChangeTypeText = (changeType: string): string => {
|
||||
const texts: Record<string, string> = {
|
||||
create: '创建Cookie',
|
||||
update: '更新信息',
|
||||
status_change: '状态变更',
|
||||
balance_change: '余额变更',
|
||||
delete: '删除Cookie'
|
||||
};
|
||||
return texts[changeType] || '未知变更';
|
||||
};
|
||||
|
||||
// 获取变更类型颜色
|
||||
const getChangeTypeColor = (changeType: string): string => {
|
||||
const colors: Record<string, string> = {
|
||||
create: 'green',
|
||||
update: 'blue',
|
||||
status_change: 'orange',
|
||||
balance_change: 'purple',
|
||||
delete: 'red'
|
||||
};
|
||||
return colors[changeType] || 'gray';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.history-timeline {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-title {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--color-text-3);
|
||||
font-size: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.timeline-description {
|
||||
background: var(--color-fill-1);
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
border-left: 3px solid var(--color-primary-light-4);
|
||||
}
|
||||
|
||||
.old-value {
|
||||
color: #f53f3f;
|
||||
background: var(--color-danger-light-1);
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.new-value {
|
||||
color: #00b42a;
|
||||
background: var(--color-success-light-1);
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 24px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--color-border-2);
|
||||
}
|
||||
</style>
|
||||
@@ -3,6 +3,7 @@
|
||||
:visible="visible"
|
||||
:title="cookieId ? '编辑Cookie' : '添加Cookie'"
|
||||
width="600px"
|
||||
:loading="loading"
|
||||
@before-ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
@@ -14,16 +15,9 @@
|
||||
:auto-size="{ minRows: 3, maxRows: 6 }"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item field="accountName" label="账户昵称">
|
||||
<a-form-item field="accountName" label="账户昵称" required>
|
||||
<a-input v-model="formModel.accountName" placeholder="请输入账户昵称" />
|
||||
</a-form-item>
|
||||
<a-form-item field="status" label="状态">
|
||||
<a-select v-model="formModel.status" placeholder="请选择状态">
|
||||
<a-option :value="1">正常</a-option>
|
||||
<a-option :value="0">失效</a-option>
|
||||
<a-option :value="2">异常</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="remark" label="备注">
|
||||
<a-textarea
|
||||
v-model="formModel.remark"
|
||||
@@ -73,23 +67,41 @@ const formModel = reactive({
|
||||
// 表单验证规则
|
||||
const rules: Record<string, any[]> = {
|
||||
cookieValue: [
|
||||
{ required: true, message: '请输入Cookie内容' },
|
||||
{ minLength: 10, message: 'Cookie内容不能少于10个字符' }
|
||||
]
|
||||
{ required: true, message: '请输入Cookie内容', trigger: 'blur' }
|
||||
],
|
||||
accountName: [{ required: true, message: '请输入账户昵称', trigger: 'blur' }]
|
||||
};
|
||||
|
||||
// 监听props变化,更新表单数据
|
||||
watch(
|
||||
() => props.visible,
|
||||
newVal => {
|
||||
if (newVal && props.cookieData) {
|
||||
// 编辑模式
|
||||
Object.assign(formModel, {
|
||||
cookieValue: props.cookieData.cookieId || '',
|
||||
accountName: props.cookieData.accountName || '',
|
||||
status: props.cookieData.status || 1,
|
||||
remark: props.cookieData.remark || ''
|
||||
});
|
||||
async newVal => {
|
||||
if (newVal && props.cookieId) {
|
||||
// 编辑模式 - 需要获取完整的 cookie 数据
|
||||
try {
|
||||
const response = await jdCookieClient.apiJdCookieAccountGetGet({
|
||||
cookieId: props.cookieId
|
||||
});
|
||||
const account = response.data.account;
|
||||
if (account) {
|
||||
Object.assign(formModel, {
|
||||
cookieValue: account.cookieId || '', // 这里的 cookieId 实际存储的是完整的 cookie 值
|
||||
accountName: account.accountName || '',
|
||||
status: account.status || 1,
|
||||
remark: account.remark || ''
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// 如果获取失败,使用传入的数据作为后备
|
||||
if (props.cookieData) {
|
||||
Object.assign(formModel, {
|
||||
cookieValue: props.cookieData.cookieId || '',
|
||||
accountName: props.cookieData.accountName || '',
|
||||
status: props.cookieData.status || 1,
|
||||
remark: props.cookieData.remark || ''
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (newVal) {
|
||||
// 添加模式
|
||||
Object.assign(formModel, {
|
||||
@@ -103,45 +115,48 @@ watch(
|
||||
);
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async (): Promise<boolean> => {
|
||||
const valid = await formRef.value?.validate();
|
||||
if (!valid) return false;
|
||||
const handleSubmit = (done: (closed: boolean) => void) => {
|
||||
formRef.value?.validate().then(async (res: any) => {
|
||||
if (res) return done(false);
|
||||
try {
|
||||
loading.value = true;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
if (props.cookieId) {
|
||||
// 编辑模式
|
||||
const updateData: KamiApiJdCookieV1UpdateAccountReq = {
|
||||
cookieId: props.cookieId,
|
||||
cookieValue: formModel.cookieValue,
|
||||
accountName: formModel.accountName,
|
||||
status: formModel.status,
|
||||
remark: formModel.remark
|
||||
};
|
||||
await jdCookieClient.apiJdCookieAccountUpdatePut({
|
||||
kamiApiJdCookieV1UpdateAccountReq: updateData
|
||||
});
|
||||
} else {
|
||||
// 添加模式
|
||||
const createData: KamiApiJdCookieV1CreateAccountReq = {
|
||||
cookieValue: formModel.cookieValue,
|
||||
accountName: formModel.accountName,
|
||||
remark: formModel.remark
|
||||
};
|
||||
await jdCookieClient.apiJdCookieAccountCreatePost({
|
||||
kamiApiJdCookieV1CreateAccountReq: createData
|
||||
});
|
||||
if (props.cookieId) {
|
||||
// 编辑模式
|
||||
const updateData: KamiApiJdCookieV1UpdateAccountReq = {
|
||||
cookieId: props.cookieId,
|
||||
cookieValue: formModel.cookieValue,
|
||||
accountName: formModel.accountName,
|
||||
status: formModel.status,
|
||||
remark: formModel.remark
|
||||
};
|
||||
await jdCookieClient.apiJdCookieAccountUpdatePut({
|
||||
kamiApiJdCookieV1UpdateAccountReq: updateData
|
||||
});
|
||||
} else {
|
||||
// 添加模式
|
||||
const createData: KamiApiJdCookieV1CreateAccountReq = {
|
||||
cookieValue: formModel.cookieValue,
|
||||
accountName: formModel.accountName,
|
||||
remark: formModel.remark
|
||||
};
|
||||
await jdCookieClient.apiJdCookieAccountCreatePost({
|
||||
kamiApiJdCookieV1CreateAccountReq: createData
|
||||
});
|
||||
}
|
||||
|
||||
Message.success(props.cookieId ? '修改成功' : '添加成功');
|
||||
emit('success');
|
||||
done(true);
|
||||
emit('update:visible', false);
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error);
|
||||
Message.error(props.cookieId ? '修改失败' : '添加失败');
|
||||
done(false);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
Message.success(props.cookieId ? '修改成功' : '添加成功');
|
||||
emit('success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
Message.error(props.cookieId ? '修改失败' : '添加失败');
|
||||
return false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 取消
|
||||
|
||||
@@ -1,285 +0,0 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['京东订单管理', 'Cookie变更历史']" />
|
||||
<a-card class="general-card" title="Cookie变更历史">
|
||||
<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="cookieId" label="Cookie ID">
|
||||
<a-input
|
||||
v-model="formModel.cookieId"
|
||||
placeholder="请输入Cookie ID"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item field="changeType" label="变更类型">
|
||||
<a-select
|
||||
v-model="formModel.changeType"
|
||||
placeholder="请选择变更类型"
|
||||
allow-clear
|
||||
>
|
||||
<a-option value="create">创建</a-option>
|
||||
<a-option value="update">更新</a-option>
|
||||
<a-option value="status_change">状态变更</a-option>
|
||||
<a-option value="balance_change">余额变更</a-option>
|
||||
<a-option value="delete">删除</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-col>
|
||||
<a-divider style="height: 42px" direction="vertical" />
|
||||
<a-col flex="172px" style="text-align: right">
|
||||
<a-space direction="horizontal" :size="18">
|
||||
<a-button type="primary" @click="search">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
</template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button @click="reset">
|
||||
<template #icon>
|
||||
<icon-refresh />
|
||||
</template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider style="margin-top: 0" />
|
||||
|
||||
<a-timeline>
|
||||
<a-timeline-item
|
||||
v-for="record in renderData"
|
||||
:key="record.historyUuid"
|
||||
:dot-color="getTimelineColor(record.changeType)"
|
||||
>
|
||||
<template #dot>
|
||||
<icon-clock-circle v-if="record.changeType === 'create'" />
|
||||
<icon-edit v-else-if="record.changeType === 'update'" />
|
||||
<icon-exclamation-circle
|
||||
v-else-if="record.changeType === 'status_change'"
|
||||
/>
|
||||
<icon-transaction
|
||||
v-else-if="record.changeType === 'balance_change'"
|
||||
/>
|
||||
<icon-delete v-else-if="record.changeType === 'delete'" />
|
||||
<icon-info-circle v-else />
|
||||
</template>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-title">
|
||||
{{ getChangeTypeText(record.changeType) }}
|
||||
</span>
|
||||
<span class="timeline-time">{{ record.createdAt }}</span>
|
||||
</div>
|
||||
<div class="timeline-body">
|
||||
<a-descriptions :column="1" size="small">
|
||||
<a-descriptions-item label="Cookie ID">
|
||||
<a-typography-text copyable>
|
||||
{{ record.cookieId }}
|
||||
</a-typography-text>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="变更类型">
|
||||
{{ record.changeType }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
v-if="record.statusBefore"
|
||||
label="变更前状态"
|
||||
>
|
||||
<a-tag :color="record.statusBefore === 1 ? 'green' : 'red'">
|
||||
{{ record.statusBefore === 1 ? '正常' : '失效' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
v-if="record.statusAfter"
|
||||
label="变更后状态"
|
||||
>
|
||||
<a-tag :color="record.statusAfter === 1 ? 'green' : 'red'">
|
||||
{{ record.statusAfter === 1 ? '正常' : '失效' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.userOrderId" label="关联订单">
|
||||
{{ record.userOrderId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
|
||||
<div class="pagination-wrapper">
|
||||
<a-pagination
|
||||
:total="pagination.total"
|
||||
:current="pagination.current"
|
||||
:page-size="pagination.pageSize"
|
||||
:page-size-options="[10, 20, 50, 100]"
|
||||
show-page-size
|
||||
@change="onPageChange"
|
||||
@page-size-change="onPageSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { Pagination } from '@/types/global';
|
||||
import { jdHistoryClient } from '@/api';
|
||||
import type {
|
||||
KamiApiJdCookieV1CookieHistoryRes,
|
||||
KamiApiJdCookieV1CookieHistoryInfo
|
||||
} from '@/api/generated';
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
|
||||
// 分页配置
|
||||
const basePagination: Pagination = {
|
||||
current: 1,
|
||||
pageSize: 20
|
||||
};
|
||||
const pagination = reactive({ ...basePagination });
|
||||
|
||||
// 类型定义
|
||||
interface FormModel {
|
||||
cookieId: string;
|
||||
changeType: string;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
current?: number;
|
||||
pageSize?: number;
|
||||
cookieId?: string;
|
||||
changeType?: string;
|
||||
}
|
||||
|
||||
// 数据状态
|
||||
const renderData = ref<KamiApiJdCookieV1CookieHistoryInfo[]>([]);
|
||||
const formModel = reactive<FormModel>({
|
||||
cookieId: '',
|
||||
changeType: ''
|
||||
});
|
||||
|
||||
// 获取变更记录列表
|
||||
const fetchData = async (params: QueryParams = {}) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await jdHistoryClient.apiJdCookieHistoryCookieGet({
|
||||
cookieId: params.cookieId || undefined,
|
||||
page: params.current || pagination.current,
|
||||
size: params.pageSize || pagination.pageSize,
|
||||
changeType: params.changeType || undefined
|
||||
});
|
||||
|
||||
renderData.value = response.data.list || [];
|
||||
pagination.total = response.data.total || 0;
|
||||
} catch (error) {
|
||||
Message.error('获取变更历史失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const search = (): void => {
|
||||
fetchData({
|
||||
current: 1,
|
||||
...formModel
|
||||
});
|
||||
};
|
||||
|
||||
// 重置
|
||||
const reset = (): void => {
|
||||
formModel.cookieId = '';
|
||||
formModel.changeType = '';
|
||||
search();
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const onPageChange = (current: number): void => {
|
||||
pagination.current = current;
|
||||
fetchData(formModel);
|
||||
};
|
||||
|
||||
const onPageSizeChange = (pageSize: number): void => {
|
||||
pagination.pageSize = pageSize;
|
||||
pagination.current = 1;
|
||||
fetchData(formModel);
|
||||
};
|
||||
|
||||
// 获取时间线颜色
|
||||
const getTimelineColor = (changeType: string): string => {
|
||||
const colors: Record<string, string> = {
|
||||
create: '#00b42a',
|
||||
update: '#165dff',
|
||||
status_change: '#ff7d00',
|
||||
balance_change: '#722ed1',
|
||||
delete: '#f53f3f'
|
||||
};
|
||||
return colors[changeType] || '#86909c';
|
||||
};
|
||||
|
||||
// 获取变更类型文本
|
||||
const getChangeTypeText = (changeType: string): string => {
|
||||
const texts: Record<string, string> = {
|
||||
create: '创建Cookie',
|
||||
update: '更新Cookie',
|
||||
status_change: '状态变更',
|
||||
balance_change: '余额变更',
|
||||
delete: '删除Cookie'
|
||||
};
|
||||
return texts[changeType] || '未知操作';
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.timeline-content {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-title {
|
||||
font-weight: 500;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
color: var(--color-text-3);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.timeline-body {
|
||||
background-color: var(--color-fill-1);
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid var(--color-primary-light-3);
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -15,7 +15,7 @@
|
||||
<a-form-item field="keyword" label="关键字">
|
||||
<a-input
|
||||
v-model="formModel.keyword"
|
||||
placeholder="Cookie/昵称/邮箱"
|
||||
placeholder="Cookie ID/账户名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
@@ -27,8 +27,8 @@
|
||||
allow-clear
|
||||
>
|
||||
<a-option :value="1">正常</a-option>
|
||||
<a-option :value="0">失效</a-option>
|
||||
<a-option :value="2">异常</a-option>
|
||||
<a-option :value="2">暂停</a-option>
|
||||
<a-option :value="3">失效</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
@@ -67,16 +67,11 @@
|
||||
</template>
|
||||
添加Cookie
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:loading="batchChecking"
|
||||
@click="batchCheckStatus"
|
||||
>
|
||||
<a-button type="secondary" size="small" @click="showBatchAddModal">
|
||||
<template #icon>
|
||||
<icon-check-circle />
|
||||
<icon-plus-circle />
|
||||
</template>
|
||||
批量检查
|
||||
批量添加Cookie
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
@@ -97,18 +92,10 @@
|
||||
>
|
||||
<template #status="{ record }">
|
||||
<a-tag v-if="record.status === 1" color="green">正常</a-tag>
|
||||
<a-tag v-else-if="record.status === 0" color="red">失效</a-tag>
|
||||
<a-tag v-else-if="record.status === 2" color="orange">异常</a-tag>
|
||||
<a-tag v-else-if="record.status === 2" color="orange">暂停</a-tag>
|
||||
<a-tag v-else-if="record.status === 3" color="red">失效</a-tag>
|
||||
<a-tag v-else color="gray">未知</a-tag>
|
||||
</template>
|
||||
<template #cookie="{ record }">
|
||||
<a-tooltip :content="record.cookie">
|
||||
<span>{{ record.cookie?.slice(0, 20) + '...' }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #balance="{ record }">
|
||||
<span class="arco-text-primary">¥{{ record.balance || '0.00' }}</span>
|
||||
</template>
|
||||
<template #operations="{ record }">
|
||||
<a-space size="small">
|
||||
<a-tooltip content="查看详情">
|
||||
@@ -118,6 +105,13 @@
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip content="变更记录">
|
||||
<a-button size="small" @click="showHistory(record)">
|
||||
<template #icon>
|
||||
<icon-history />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip content="编辑">
|
||||
<a-button
|
||||
size="small"
|
||||
@@ -129,17 +123,6 @@
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip content="查看历史">
|
||||
<a-button
|
||||
size="small"
|
||||
status="success"
|
||||
@click="showHistory(record)"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-history />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-popconfirm
|
||||
content="确认删除此Cookie吗?"
|
||||
@ok="deleteCookie(record.cookieId)"
|
||||
@@ -171,11 +154,17 @@
|
||||
:cookie-id="currentCookieId"
|
||||
/>
|
||||
|
||||
<!-- 变更历史弹窗 -->
|
||||
<cookie-history
|
||||
<!-- Cookie变更记录侧边栏 -->
|
||||
<cookie-history-drawer
|
||||
v-model:visible="historyVisible"
|
||||
:cookie-id="currentCookieId"
|
||||
/>
|
||||
|
||||
<!-- 批量添加Cookie弹窗 -->
|
||||
<batch-import-modal
|
||||
v-model:visible="batchAddVisible"
|
||||
@success="handleBatchAddSuccess"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -193,7 +182,8 @@ import type {
|
||||
} from '@/api/generated';
|
||||
import CookieModal from './components/cookie-modal.vue';
|
||||
import CookieDetail from './components/cookie-detail.vue';
|
||||
import CookieHistory from './components/cookie-history.vue';
|
||||
import CookieHistoryDrawer from './components/cookie-history-drawer.vue';
|
||||
import BatchImportModal from './components/batch-import-modal.vue';
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
|
||||
@@ -214,36 +204,34 @@ const columns: TableColumnData[] = [
|
||||
return rowIndex + 1 + (pagination.current - 1) * pagination.pageSize;
|
||||
}
|
||||
},
|
||||
// {
|
||||
// title: 'Cookie ID',
|
||||
// dataIndex: 'cookieId',
|
||||
// width: 200,
|
||||
// ellipsis: true,
|
||||
// tooltip: true
|
||||
// },
|
||||
{
|
||||
title: 'Cookie ID',
|
||||
dataIndex: 'cookieId',
|
||||
width: 200,
|
||||
title: '账户名称',
|
||||
dataIndex: 'accountName',
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: 'Cookie内容',
|
||||
dataIndex: 'cookie',
|
||||
slotName: 'cookie',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: '账户昵称',
|
||||
dataIndex: 'nickname',
|
||||
title: '连续失败次数',
|
||||
dataIndex: 'failureCount',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '邮箱',
|
||||
dataIndex: 'email',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
title: '最后使用时间',
|
||||
dataIndex: 'lastUsedAt',
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: '余额',
|
||||
dataIndex: 'balance',
|
||||
slotName: 'balance',
|
||||
width: 100
|
||||
title: '暂停解除时间',
|
||||
dataIndex: 'suspendUntil',
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
@@ -256,6 +244,13 @@ const columns: TableColumnData[] = [
|
||||
dataIndex: 'createdAt',
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
dataIndex: 'remark',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operations',
|
||||
@@ -289,9 +284,9 @@ const formModel = reactive<FormModel>({
|
||||
const modalVisible = ref(false);
|
||||
const detailVisible = ref(false);
|
||||
const historyVisible = ref(false);
|
||||
const batchAddVisible = ref(false);
|
||||
const currentCookieId = ref('');
|
||||
const currentCookie = ref<KamiApiJdCookieV1CookieAccountInfo | null>(null);
|
||||
const batchChecking = ref(false);
|
||||
|
||||
// 获取Cookie列表
|
||||
const fetchData = async (params: QueryParams = {}) => {
|
||||
@@ -340,24 +335,6 @@ const onPageSizeChange = (pageSize: number): void => {
|
||||
fetchData(formModel);
|
||||
};
|
||||
|
||||
// 批量检查状态
|
||||
const batchCheckStatus = async (): Promise<void> => {
|
||||
batchChecking.value = true;
|
||||
try {
|
||||
await jdCookieClient.apiJdCookieAccountBatchCheckPost({
|
||||
kamiApiJdCookieV1BatchCheckReq: {
|
||||
cookieIds: renderData.value.map(item => item.cookieId)
|
||||
}
|
||||
});
|
||||
Message.success('批量检查完成');
|
||||
search();
|
||||
} catch (error) {
|
||||
Message.error('批量检查失败');
|
||||
} finally {
|
||||
batchChecking.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 显示添加弹窗
|
||||
const showAddModal = (): void => {
|
||||
currentCookieId.value = '';
|
||||
@@ -378,7 +355,7 @@ const showDetail = (record: KamiApiJdCookieV1CookieAccountInfo): void => {
|
||||
detailVisible.value = true;
|
||||
};
|
||||
|
||||
// 显示历史
|
||||
// 显示变更记录
|
||||
const showHistory = (record: KamiApiJdCookieV1CookieAccountInfo): void => {
|
||||
currentCookieId.value = record.cookieId;
|
||||
historyVisible.value = true;
|
||||
@@ -395,11 +372,21 @@ const deleteCookie = async (cookieId: string): Promise<void> => {
|
||||
}
|
||||
};
|
||||
|
||||
// 显示批量添加弹窗
|
||||
const showBatchAddModal = (): void => {
|
||||
batchAddVisible.value = true;
|
||||
};
|
||||
|
||||
// 弹窗成功回调
|
||||
const handleModalSuccess = (): void => {
|
||||
search();
|
||||
};
|
||||
|
||||
// 批量添加成功回调
|
||||
const handleBatchAddSuccess = (): void => {
|
||||
search();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
|
||||
399
src/views/jd-order/jd-orders/index.vue
Normal file
399
src/views/jd-order/jd-orders/index.vue
Normal file
@@ -0,0 +1,399 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['京东订单管理', '京东订单']" />
|
||||
<a-card class="general-card" title="京东订单查询">
|
||||
<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="keyword" label="订单号">
|
||||
<a-input
|
||||
v-model="formModel.keyword"
|
||||
placeholder="请输入订单号"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<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-col :span="8">
|
||||
<a-form-item field="dateRange" label="时间范围">
|
||||
<a-range-picker
|
||||
v-model="formModel.dateRange"
|
||||
:shortcuts="dateRangeShortcuts"
|
||||
format="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-col>
|
||||
<a-divider style="height: 42px" direction="vertical" />
|
||||
<a-col flex="172px" style="text-align: right">
|
||||
<a-space direction="horizontal" :size="18">
|
||||
<a-button type="primary" @click="search">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
</template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button @click="reset">
|
||||
<template #icon>
|
||||
<icon-refresh />
|
||||
</template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider style="margin-top: 0" />
|
||||
|
||||
<a-table
|
||||
:loading="loading"
|
||||
:pagination="{
|
||||
current: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
total: pagination.total,
|
||||
pageSizeOptions: [10, 20, 50, 100],
|
||||
showPageSize: true
|
||||
}"
|
||||
:columns="columns"
|
||||
:data="renderData"
|
||||
:scroll="{ x: 1200 }"
|
||||
@page-change="onPageChange"
|
||||
@page-size-change="onPageSizeChange"
|
||||
>
|
||||
<template #status="{ record }">
|
||||
<a-tag v-if="record.status === 1" color="orange">待支付</a-tag>
|
||||
<a-tag v-else-if="record.status === 2" color="green">已支付</a-tag>
|
||||
<a-tag v-else-if="record.status === 3" color="red">已过期</a-tag>
|
||||
<a-tag v-else-if="record.status === 4" color="gray">已取消</a-tag>
|
||||
<a-tag v-else color="gray">未知</a-tag>
|
||||
</template>
|
||||
<template #amount="{ record }">
|
||||
<span class="arco-text-primary">
|
||||
¥{{ record.amount?.toFixed(2) || '0.00' }}
|
||||
</span>
|
||||
</template>
|
||||
<template #operations="{ record }">
|
||||
<a-space size="small">
|
||||
<a-tooltip content="查看详情">
|
||||
<a-button size="small" @click="showDetail(record)">
|
||||
<template #icon>
|
||||
<icon-eye />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 订单详情弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="detailVisible"
|
||||
title="京东订单详情"
|
||||
width="800px"
|
||||
:footer="false"
|
||||
>
|
||||
<div v-if="currentOrder" class="order-detail">
|
||||
<a-descriptions :column="2" bordered>
|
||||
<a-descriptions-item label="京东订单号">
|
||||
{{ currentOrder.jdOrderId }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="内部订单号">
|
||||
{{ currentOrder.orderId }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="商品品类">
|
||||
{{ currentOrder.category }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="订单金额">
|
||||
<span class="arco-text-primary">
|
||||
¥{{ currentOrder.amount?.toFixed(2) || '0.00' }}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="getStatusColor(currentOrder.status)">
|
||||
{{ getStatusText(currentOrder.status) }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="支付时间">
|
||||
{{ currentOrder.paidAt || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">
|
||||
{{ currentOrder.createdAt }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="更新时间">
|
||||
{{ currentOrder.updatedAt }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import type { TableColumnData } from '@arco-design/web-vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { Pagination } from '@/types/global';
|
||||
import { jdOrderClient } from '@/api';
|
||||
import type { KamiApiJdCookieV1JdOrderInfo } from '@/api/generated';
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
|
||||
// 分页配置
|
||||
const basePagination: Pagination = {
|
||||
current: 1,
|
||||
pageSize: 20
|
||||
};
|
||||
const pagination = reactive({ ...basePagination });
|
||||
|
||||
// 日期范围快捷选项
|
||||
const dateRangeShortcuts = [
|
||||
{
|
||||
label: '今天',
|
||||
value: () => {
|
||||
const today = new Date();
|
||||
return [today, today];
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '最近7天',
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setDate(start.getDate() - 6);
|
||||
return [start, end];
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '最近30天',
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setDate(start.getDate() - 29);
|
||||
return [start, end];
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// 表格列配置
|
||||
const columns: TableColumnData[] = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
width: 80,
|
||||
render: ({ rowIndex }) => {
|
||||
return rowIndex + 1 + (pagination.current - 1) * pagination.pageSize;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '京东订单号',
|
||||
dataIndex: 'jdOrderId',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: '内部订单号',
|
||||
dataIndex: 'orderId',
|
||||
width: 180,
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: '商品品类',
|
||||
dataIndex: 'category',
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
tooltip: true
|
||||
},
|
||||
{
|
||||
title: '订单金额',
|
||||
dataIndex: 'amount',
|
||||
slotName: 'amount',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '订单状态',
|
||||
dataIndex: 'status',
|
||||
slotName: 'status',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdAt',
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operations',
|
||||
slotName: 'operations',
|
||||
width: 120,
|
||||
fixed: 'right'
|
||||
}
|
||||
];
|
||||
|
||||
// 类型定义
|
||||
interface FormModel {
|
||||
keyword: string;
|
||||
status: number | undefined;
|
||||
dateRange: (Date | undefined)[] | undefined;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
current?: number;
|
||||
pageSize?: number;
|
||||
keyword?: string;
|
||||
status?: number;
|
||||
startTime?: string;
|
||||
endTime?: string;
|
||||
}
|
||||
|
||||
// 数据状态
|
||||
const renderData = ref<KamiApiJdCookieV1JdOrderInfo[]>([]);
|
||||
const formModel = reactive<FormModel>({
|
||||
keyword: '',
|
||||
status: undefined,
|
||||
dateRange: undefined
|
||||
});
|
||||
|
||||
// 弹窗状态
|
||||
const detailVisible = ref(false);
|
||||
const currentOrder = ref<KamiApiJdCookieV1JdOrderInfo | null>(null);
|
||||
|
||||
// 获取订单列表
|
||||
const fetchData = async (params: QueryParams = {}) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await jdOrderClient.apiJdCookieOrderJdListGet({
|
||||
page: params.current || pagination.current,
|
||||
size: params.pageSize || pagination.pageSize,
|
||||
orderId: params.keyword,
|
||||
status: params.status,
|
||||
startTime: params.startTime,
|
||||
endTime: params.endTime
|
||||
});
|
||||
|
||||
renderData.value = response.data.list || [];
|
||||
pagination.total = response.data.total || 0;
|
||||
} catch (error) {
|
||||
Message.error('获取订单列表失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const search = (): void => {
|
||||
const params: QueryParams = {
|
||||
current: 1,
|
||||
keyword: formModel.keyword,
|
||||
status: formModel.status
|
||||
};
|
||||
|
||||
if (formModel.dateRange && formModel.dateRange.length === 2) {
|
||||
params.startTime = formModel.dateRange[0]?.toISOString().split('T')[0];
|
||||
params.endTime = formModel.dateRange[1]?.toISOString().split('T')[0];
|
||||
}
|
||||
|
||||
fetchData(params);
|
||||
};
|
||||
|
||||
// 重置
|
||||
const reset = (): void => {
|
||||
formModel.keyword = '';
|
||||
formModel.status = undefined;
|
||||
formModel.dateRange = undefined;
|
||||
search();
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const onPageChange = (current: number): void => {
|
||||
pagination.current = current;
|
||||
const params: QueryParams = {
|
||||
keyword: formModel.keyword,
|
||||
status: formModel.status
|
||||
};
|
||||
|
||||
if (formModel.dateRange && formModel.dateRange.length === 2) {
|
||||
params.startTime = formModel.dateRange[0]?.toISOString().split('T')[0];
|
||||
params.endTime = formModel.dateRange[1]?.toISOString().split('T')[0];
|
||||
}
|
||||
|
||||
fetchData(params);
|
||||
};
|
||||
|
||||
const onPageSizeChange = (pageSize: number): void => {
|
||||
pagination.pageSize = pageSize;
|
||||
pagination.current = 1;
|
||||
const params: QueryParams = {
|
||||
keyword: formModel.keyword,
|
||||
status: formModel.status
|
||||
};
|
||||
|
||||
if (formModel.dateRange && formModel.dateRange.length === 2) {
|
||||
params.startTime = formModel.dateRange[0]?.toISOString().split('T')[0];
|
||||
params.endTime = formModel.dateRange[1]?.toISOString().split('T')[0];
|
||||
}
|
||||
|
||||
fetchData(params);
|
||||
};
|
||||
|
||||
// 获取状态颜色
|
||||
const getStatusColor = (status: number): string => {
|
||||
const colors: Record<number, string> = {
|
||||
1: 'orange', // 待支付
|
||||
2: 'green', // 已支付
|
||||
3: 'red', // 已过期
|
||||
4: 'gray' // 已取消
|
||||
};
|
||||
return colors[status] || 'gray';
|
||||
};
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status: number): string => {
|
||||
const statusMap: Record<number, string> = {
|
||||
1: '待支付',
|
||||
2: '已支付',
|
||||
3: '已过期',
|
||||
4: '已取消'
|
||||
};
|
||||
return statusMap[status] || '未知';
|
||||
};
|
||||
|
||||
// 显示详情
|
||||
const showDetail = (record: KamiApiJdCookieV1JdOrderInfo): void => {
|
||||
currentOrder.value = record;
|
||||
detailVisible.value = true;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.order-detail {
|
||||
padding: 16px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,148 +0,0 @@
|
||||
<template>
|
||||
<a-button @click="handleClick">
|
||||
<template #icon>
|
||||
<icon-upload />
|
||||
</template>
|
||||
批量导入订单
|
||||
</a-button>
|
||||
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="批量导入订单"
|
||||
width="600px"
|
||||
@cancel="handleCancel"
|
||||
@before-ok="handleSubmit"
|
||||
>
|
||||
<a-form :model="formModel" layout="vertical">
|
||||
<a-form-item label="订单数据">
|
||||
<a-textarea
|
||||
v-model="formModel.orderData"
|
||||
placeholder="每行一个订单,格式:订单号,商品品类,金额,京东订单号 例如:ORDER001,数码产品,299.99,JD123456789"
|
||||
:auto-size="{ minRows: 6, maxRows: 12 }"
|
||||
placeholder-class="batch-textarea"
|
||||
/>
|
||||
<div class="tip-text">
|
||||
<icon-info-circle />
|
||||
<span>
|
||||
支持批量粘贴,每行一个订单,格式:订单号,商品品类,金额,京东订单号(可选)
|
||||
</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { jdOrderClient } from '@/api';
|
||||
import type { KamiApiJdCookieV1CreateOrderReq } from '@/api/generated';
|
||||
|
||||
interface Emits {
|
||||
(e: 'success'): void;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const formModel = reactive({
|
||||
orderData: ''
|
||||
});
|
||||
|
||||
const handleClick = (): void => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const handleCancel = (): void => {
|
||||
visible.value = false;
|
||||
formModel.orderData = '';
|
||||
};
|
||||
|
||||
const handleSubmit = async (): Promise<boolean> => {
|
||||
if (!formModel.orderData.trim()) {
|
||||
Message.warning('请输入订单数据');
|
||||
return false;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
// 解析批量数据
|
||||
const lines = formModel.orderData
|
||||
.trim()
|
||||
.split('\n')
|
||||
.filter(line => line.trim());
|
||||
const orders = lines
|
||||
.map(line => {
|
||||
const parts = line.split(',').map(part => part.trim());
|
||||
return {
|
||||
orderId: parts[0] || '',
|
||||
category: parts[1] || '',
|
||||
amount: parts[2] ? parseFloat(parts[2]) : 0,
|
||||
jdOrderId: parts[3] || '',
|
||||
remark: `批量导入于 ${new Date().toLocaleString()}`
|
||||
};
|
||||
})
|
||||
.filter(order => order.orderId && order.category && order.amount > 0);
|
||||
|
||||
if (orders.length === 0) {
|
||||
Message.warning('没有有效的订单数据');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 逐个创建订单
|
||||
let successCount = 0;
|
||||
for (const order of orders) {
|
||||
try {
|
||||
const createData: KamiApiJdCookieV1CreateOrderReq = {
|
||||
orderId: order.orderId,
|
||||
category: order.category,
|
||||
amount: order.amount
|
||||
};
|
||||
|
||||
await jdOrderClient.apiJdCookieOrderCreatePost({
|
||||
kamiApiJdCookieV1CreateOrderReq: createData
|
||||
});
|
||||
|
||||
successCount++;
|
||||
} catch (error) {
|
||||
console.error(`创建订单失败: ${order.orderId}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
if (successCount > 0) {
|
||||
Message.success(
|
||||
`成功导入 ${successCount} 个订单${successCount < orders.length ? `,失败 ${orders.length - successCount} 个` : ''}`
|
||||
);
|
||||
emit('success');
|
||||
return true;
|
||||
} else {
|
||||
Message.error('批量导入失败,所有订单都创建失败');
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
Message.error('批量导入失败');
|
||||
return false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tip-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--color-text-3);
|
||||
font-size: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.batch-textarea {
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,257 +0,0 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:visible="visible"
|
||||
title="订单变更历史"
|
||||
width="800px"
|
||||
:footer="false"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<div v-if="orderId" class="order-history">
|
||||
<a-timeline :loading="loading">
|
||||
<a-timeline-item
|
||||
v-for="record in renderData"
|
||||
:key="record.historyUuid"
|
||||
:dot-color="getTimelineColor(record.changeType)"
|
||||
>
|
||||
<template #dot>
|
||||
<icon-clock-circle v-if="record.changeType === 'create'" />
|
||||
<icon-edit v-else-if="record.changeType === 'update'" />
|
||||
<icon-exclamation-circle
|
||||
v-else-if="record.changeType === 'status_change'"
|
||||
/>
|
||||
<icon-transaction
|
||||
v-else-if="record.changeType === 'payment_check'"
|
||||
/>
|
||||
<icon-link
|
||||
v-else-if="record.changeType === 'payment_url_generated'"
|
||||
/>
|
||||
<icon-delete v-else-if="record.changeType === 'cancel'" />
|
||||
<icon-info-circle v-else />
|
||||
</template>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-title">
|
||||
{{ getChangeTypeText(record.changeType) }}
|
||||
</span>
|
||||
<span class="timeline-time">{{ record.createdAt }}</span>
|
||||
</div>
|
||||
<div class="timeline-body">
|
||||
<a-descriptions :column="1" size="small">
|
||||
<a-descriptions-item label="订单号">
|
||||
<a-typography-text copyable>
|
||||
{{ record.orderId }}
|
||||
</a-typography-text>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.jdOrderId" label="京东订单号">
|
||||
<a-typography-text copyable>
|
||||
{{ record.jdOrderId }}
|
||||
</a-typography-text>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.wxPayUrl" label="支付链接">
|
||||
<a-link
|
||||
:href="record.wxPayUrl"
|
||||
target="_blank"
|
||||
type="primary"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-link />
|
||||
</template>
|
||||
打开链接
|
||||
</a-link>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
|
||||
<div v-if="renderData.length === 0 && !loading" class="empty-wrapper">
|
||||
<a-empty description="暂无变更历史" />
|
||||
</div>
|
||||
|
||||
<div v-if="renderData.length > 0" class="pagination-wrapper">
|
||||
<a-pagination
|
||||
:total="pagination.total"
|
||||
:current="pagination.current"
|
||||
:page-size="pagination.pageSize"
|
||||
:page-size-options="[10, 20, 50]"
|
||||
show-page-size
|
||||
size="small"
|
||||
@change="onPageChange"
|
||||
@page-size-change="onPageSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<a-empty v-else description="暂无订单数据" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { jdHistoryClient } from '@/api';
|
||||
import { ApiJdCookieHistoryOrderGetOrderTypeEnum } from '@/api/generated';
|
||||
import type {
|
||||
KamiApiJdCookieV1OrderHistoryRes,
|
||||
KamiApiJdCookieV1OrderHistoryInfo
|
||||
} from '@/api/generated';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
orderId: string;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
// 处理取消
|
||||
const handleCancel = (): void => {
|
||||
emit('update:visible', false);
|
||||
};
|
||||
const renderData = ref<KamiApiJdCookieV1OrderHistoryInfo[]>([]);
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0
|
||||
});
|
||||
|
||||
// 获取订单变更历史
|
||||
const fetchData = async () => {
|
||||
if (!props.orderId) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await jdHistoryClient.apiJdCookieHistoryOrderGet({
|
||||
orderId: props.orderId,
|
||||
orderType: ApiJdCookieHistoryOrderGetOrderTypeEnum.User,
|
||||
page: pagination.current,
|
||||
size: pagination.pageSize
|
||||
});
|
||||
|
||||
renderData.value = response.data.list || [];
|
||||
pagination.total = response.data.total || 0;
|
||||
} catch (error) {
|
||||
Message.error('获取订单变更历史失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const onPageChange = (current: number): void => {
|
||||
pagination.current = current;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
const onPageSizeChange = (pageSize: number): void => {
|
||||
pagination.pageSize = pageSize;
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取时间线颜色
|
||||
const getTimelineColor = (changeType: string): string => {
|
||||
const colors: Record<string, string> = {
|
||||
create: '#00b42a',
|
||||
update: '#165dff',
|
||||
status_change: '#ff7d00',
|
||||
payment_check: '#722ed1',
|
||||
payment_url_generated: '#14c9c9',
|
||||
cancel: '#f53f3f'
|
||||
};
|
||||
return colors[changeType] || '#86909c';
|
||||
};
|
||||
|
||||
// 获取变更类型文本
|
||||
const getChangeTypeText = (changeType: string): string => {
|
||||
const texts: Record<string, string> = {
|
||||
create: '创建订单',
|
||||
update: '更新订单',
|
||||
status_change: '状态变更',
|
||||
payment_check: '检查支付',
|
||||
payment_url_generated: '生成支付链接',
|
||||
cancel: '取消订单'
|
||||
};
|
||||
return texts[changeType] || '未知操作';
|
||||
};
|
||||
|
||||
// 监听orderId变化
|
||||
watch(
|
||||
() => props.orderId,
|
||||
newOrderId => {
|
||||
if (newOrderId && props.visible) {
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 监听弹窗显示状态
|
||||
watch(
|
||||
() => props.visible,
|
||||
visible => {
|
||||
if (visible && props.orderId) {
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.order-history {
|
||||
padding: 16px 0;
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-title {
|
||||
font-weight: 500;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
color: var(--color-text-3);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.timeline-body {
|
||||
background-color: var(--color-fill-1);
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid var(--color-primary-light-3);
|
||||
}
|
||||
|
||||
.empty-wrapper {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--color-border-2);
|
||||
}
|
||||
</style>
|
||||
@@ -1,104 +0,0 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:visible="visible"
|
||||
title="创建订单"
|
||||
width="600px"
|
||||
@before-ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="formModel" :rules="rules" layout="vertical">
|
||||
<a-form-item field="category" label="商品品类" required>
|
||||
<a-input v-model="formModel.category" placeholder="请输入商品品类" />
|
||||
</a-form-item>
|
||||
<a-form-item field="amount" label="订单金额" required>
|
||||
<a-input-number
|
||||
v-model="formModel.amount"
|
||||
placeholder="请输入订单金额"
|
||||
:precision="2"
|
||||
:min="0.01"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template #prefix>¥</template>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { Message, type FormInstance } from '@arco-design/web-vue';
|
||||
import { jdOrderClient } from '@/api';
|
||||
import type { KamiApiJdCookieV1CreateOrderReq } from '@/api/generated';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:visible', value: boolean): void;
|
||||
(e: 'success'): void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const loading = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const formModel = reactive({
|
||||
category: '',
|
||||
amount: 0
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const rules: Record<string, any[]> = {
|
||||
category: [
|
||||
{ required: true, message: '请输入商品品类' },
|
||||
{ minLength: 1, message: '商品品类不能为空' }
|
||||
],
|
||||
amount: [
|
||||
{ required: true, message: '请输入订单金额' },
|
||||
{ type: 'number', min: 0.01, message: '订单金额必须大于0' }
|
||||
]
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async (): Promise<boolean> => {
|
||||
const valid = await formRef.value?.validate();
|
||||
if (!valid) return false;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const createData: KamiApiJdCookieV1CreateOrderReq = {
|
||||
orderId: `ORDER_${Date.now()}`,
|
||||
category: formModel.category,
|
||||
amount: formModel.amount
|
||||
};
|
||||
|
||||
await jdOrderClient.apiJdCookieOrderCreatePost({
|
||||
kamiApiJdCookieV1CreateOrderReq: createData
|
||||
});
|
||||
|
||||
Message.success('创建订单成功');
|
||||
emit('success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
Message.error('创建订单失败');
|
||||
return false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 取消
|
||||
const handleCancel = (): void => {
|
||||
emit('update:visible', false);
|
||||
// 重置表单
|
||||
Object.assign(formModel, {
|
||||
category: '',
|
||||
amount: 0
|
||||
});
|
||||
};
|
||||
</script>
|
||||
@@ -1,378 +0,0 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['京东订单管理', '订单变更历史']" />
|
||||
<a-card class="general-card" title="订单变更历史">
|
||||
<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="orderId" label="订单号">
|
||||
<a-input
|
||||
v-model="formModel.orderId"
|
||||
placeholder="请输入订单号"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item field="orderType" label="订单类型">
|
||||
<a-select
|
||||
v-model="formModel.orderType"
|
||||
placeholder="请选择订单类型"
|
||||
allow-clear
|
||||
>
|
||||
<a-option value="user">用户订单</a-option>
|
||||
<a-option value="jd">京东订单</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item field="dateRange" label="时间范围">
|
||||
<a-range-picker
|
||||
v-model="formModel.dateRange"
|
||||
:shortcuts="dateRangeShortcuts"
|
||||
format="YYYY-MM-DD"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-col>
|
||||
<a-divider style="height: 42px" direction="vertical" />
|
||||
<a-col flex="172px" style="text-align: right">
|
||||
<a-space direction="horizontal" :size="18">
|
||||
<a-button type="primary" @click="search">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
</template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button @click="reset">
|
||||
<template #icon>
|
||||
<icon-refresh />
|
||||
</template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider style="margin-top: 0" />
|
||||
|
||||
<div class="timeline-wrapper">
|
||||
<a-timeline :loading="loading">
|
||||
<a-timeline-item
|
||||
v-for="record in renderData"
|
||||
:key="record.historyUuid"
|
||||
:dot-color="getTimelineColor(record.changeType)"
|
||||
>
|
||||
<template #dot>
|
||||
<icon-clock-circle v-if="record.changeType === 'create'" />
|
||||
<icon-edit v-else-if="record.changeType === 'update'" />
|
||||
<icon-exclamation-circle
|
||||
v-else-if="record.changeType === 'status_change'"
|
||||
/>
|
||||
<icon-transaction
|
||||
v-else-if="record.changeType === 'payment_check'"
|
||||
/>
|
||||
<icon-link
|
||||
v-else-if="record.changeType === 'payment_url_generated'"
|
||||
/>
|
||||
<icon-delete v-else-if="record.changeType === 'cancel'" />
|
||||
<icon-info-circle v-else />
|
||||
</template>
|
||||
<div class="timeline-content">
|
||||
<div class="timeline-header">
|
||||
<span class="timeline-title">
|
||||
{{ getChangeTypeText(record.changeType) }}
|
||||
</span>
|
||||
<span class="timeline-time">{{ record.createdAt }}</span>
|
||||
</div>
|
||||
<div class="timeline-body">
|
||||
<a-descriptions :column="1" size="small">
|
||||
<a-descriptions-item label="订单号">
|
||||
<a-typography-text copyable>
|
||||
{{ record.orderId }}
|
||||
</a-typography-text>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
v-if="record.jdOrderId"
|
||||
label="京东订单号"
|
||||
>
|
||||
<a-typography-text copyable>
|
||||
{{ record.jdOrderId }}
|
||||
</a-typography-text>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.wxPayUrl" label="支付链接">
|
||||
<a-link
|
||||
:href="record.wxPayUrl"
|
||||
target="_blank"
|
||||
type="primary"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-link />
|
||||
</template>
|
||||
打开链接
|
||||
</a-link>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
|
||||
<div v-if="renderData.length === 0 && !loading" class="empty-wrapper">
|
||||
<a-empty description="暂无变更历史" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pagination-wrapper">
|
||||
<a-pagination
|
||||
:total="pagination.total"
|
||||
:current="pagination.current"
|
||||
:page-size="pagination.pageSize"
|
||||
:page-size-options="[10, 20, 50, 100]"
|
||||
show-page-size
|
||||
@change="onPageChange"
|
||||
@page-size-change="onPageSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { Pagination } from '@/types/global';
|
||||
import { jdHistoryClient } from '@/api';
|
||||
import { ApiJdCookieHistoryOrderGetOrderTypeEnum } from '@/api/generated';
|
||||
import type {
|
||||
KamiApiJdCookieV1OrderHistoryRes,
|
||||
KamiApiJdCookieV1OrderHistoryInfo
|
||||
} from '@/api/generated';
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
|
||||
// 分页配置
|
||||
const basePagination: Pagination = {
|
||||
current: 1,
|
||||
pageSize: 20
|
||||
};
|
||||
const pagination = reactive({ ...basePagination });
|
||||
|
||||
// 日期范围快捷选项
|
||||
const dateRangeShortcuts = [
|
||||
{
|
||||
label: '今天',
|
||||
value: () => {
|
||||
const today = new Date();
|
||||
return [today, today];
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '最近7天',
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setDate(start.getDate() - 6);
|
||||
return [start, end];
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '最近30天',
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setDate(start.getDate() - 29);
|
||||
return [start, end];
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// 类型定义
|
||||
interface FormModel {
|
||||
orderId: string;
|
||||
orderType: string;
|
||||
dateRange: (Date | undefined)[] | undefined;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
current?: number;
|
||||
pageSize?: number;
|
||||
orderId?: string;
|
||||
orderType?: string;
|
||||
startTime?: string;
|
||||
endTime?: string;
|
||||
}
|
||||
|
||||
// 数据状态
|
||||
const renderData = ref<KamiApiJdCookieV1OrderHistoryInfo[]>([]);
|
||||
const formModel = reactive<FormModel>({
|
||||
orderId: '',
|
||||
orderType: '',
|
||||
dateRange: undefined
|
||||
});
|
||||
|
||||
// 获取变更记录列表
|
||||
const fetchData = async (params: QueryParams = {}) => {
|
||||
if (!params.orderId) {
|
||||
renderData.value = [];
|
||||
pagination.total = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const orderType =
|
||||
params.orderType === 'jd'
|
||||
? ApiJdCookieHistoryOrderGetOrderTypeEnum.Jd
|
||||
: ApiJdCookieHistoryOrderGetOrderTypeEnum.User;
|
||||
|
||||
const response = await jdHistoryClient.apiJdCookieHistoryOrderGet({
|
||||
orderId: params.orderId,
|
||||
orderType,
|
||||
page: params.current || pagination.current,
|
||||
size: params.pageSize || pagination.pageSize
|
||||
});
|
||||
|
||||
renderData.value = response.data.list || [];
|
||||
pagination.total = response.data.total || 0;
|
||||
} catch (error) {
|
||||
Message.error('获取变更历史失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const search = (): void => {
|
||||
if (!formModel.orderId) {
|
||||
Message.warning('请输入订单号');
|
||||
return;
|
||||
}
|
||||
|
||||
const params: QueryParams = {
|
||||
current: 1,
|
||||
orderId: formModel.orderId,
|
||||
orderType: formModel.orderType
|
||||
};
|
||||
|
||||
fetchData(params);
|
||||
};
|
||||
|
||||
// 重置
|
||||
const reset = (): void => {
|
||||
formModel.orderId = '';
|
||||
formModel.orderType = '';
|
||||
formModel.dateRange = undefined;
|
||||
renderData.value = [];
|
||||
pagination.total = 0;
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const onPageChange = (current: number): void => {
|
||||
pagination.current = current;
|
||||
const params: QueryParams = {
|
||||
orderId: formModel.orderId,
|
||||
orderType: formModel.orderType
|
||||
};
|
||||
|
||||
fetchData(params);
|
||||
};
|
||||
|
||||
const onPageSizeChange = (pageSize: number): void => {
|
||||
pagination.pageSize = pageSize;
|
||||
pagination.current = 1;
|
||||
const params: QueryParams = {
|
||||
orderId: formModel.orderId,
|
||||
orderType: formModel.orderType
|
||||
};
|
||||
|
||||
fetchData(params);
|
||||
};
|
||||
|
||||
// 获取时间线颜色
|
||||
const getTimelineColor = (changeType: string): string => {
|
||||
const colors: Record<string, string> = {
|
||||
create: '#00b42a',
|
||||
update: '#165dff',
|
||||
status_change: '#ff7d00',
|
||||
payment_check: '#722ed1',
|
||||
payment_url_generated: '#14c9c9',
|
||||
cancel: '#f53f3f'
|
||||
};
|
||||
return colors[changeType] || '#86909c';
|
||||
};
|
||||
|
||||
// 获取变更类型文本
|
||||
const getChangeTypeText = (changeType: string): string => {
|
||||
const texts: Record<string, string> = {
|
||||
create: '创建订单',
|
||||
update: '更新订单',
|
||||
status_change: '状态变更',
|
||||
payment_check: '检查支付',
|
||||
payment_url_generated: '生成支付链接',
|
||||
cancel: '取消订单'
|
||||
};
|
||||
return texts[changeType] || '未知操作';
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 初始时不需要加载数据,需要用户输入订单号
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.timeline-wrapper {
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.timeline-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.timeline-title {
|
||||
font-weight: 500;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
color: var(--color-text-3);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.timeline-body {
|
||||
background-color: var(--color-fill-1);
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid var(--color-primary-light-3);
|
||||
}
|
||||
|
||||
.empty-wrapper {
|
||||
text-align: center;
|
||||
padding: 80px 0;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--color-border-2);
|
||||
}
|
||||
</style>
|
||||
@@ -64,33 +64,6 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider style="margin-top: 0" />
|
||||
<a-row style="margin-bottom: 16px">
|
||||
<a-space>
|
||||
<a-button
|
||||
v-if="checkTokenFromLogin()"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="showCreateModal()"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
创建订单
|
||||
</a-button>
|
||||
<batch-import-modal />
|
||||
<a-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:loading="batchChecking"
|
||||
@click="batchCheckPayment"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-check-circle />
|
||||
</template>
|
||||
批量检查支付
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-table
|
||||
:loading="loading"
|
||||
:pagination="{
|
||||
@@ -143,29 +116,6 @@
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip content="查看历史">
|
||||
<a-button
|
||||
size="small"
|
||||
status="success"
|
||||
@click="showHistory(record)"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-history />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip content="检查支付">
|
||||
<a-button
|
||||
size="small"
|
||||
status="warning"
|
||||
:loading="checkingOrders.includes(record.orderId)"
|
||||
@click="checkPayment(record)"
|
||||
>
|
||||
<template #icon>
|
||||
<icon-check-circle />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip content="获取支付链接">
|
||||
<a-button
|
||||
size="small"
|
||||
@@ -183,17 +133,8 @@
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 创建订单弹窗 -->
|
||||
<order-modal v-model:visible="modalVisible" @success="handleModalSuccess" />
|
||||
|
||||
<!-- 订单详情弹窗 -->
|
||||
<order-detail v-model:visible="detailVisible" :order-data="currentOrder" />
|
||||
|
||||
<!-- 订单历史弹窗 -->
|
||||
<order-history
|
||||
v-model:visible="historyVisible"
|
||||
:order-id="currentOrderId"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -203,16 +144,12 @@ import { Message } from '@arco-design/web-vue';
|
||||
import type { TableColumnData } from '@arco-design/web-vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { Pagination } from '@/types/global';
|
||||
import { checkTokenFromLogin } from '@/utils/auth';
|
||||
import { jdOrderClient, jdHistoryClient } from '@/api';
|
||||
import type {
|
||||
KamiApiJdCookieV1ListOrderRes,
|
||||
KamiApiJdCookieV1OrderInfo
|
||||
} from '@/api/generated';
|
||||
import OrderModal from './components/order-modal.vue';
|
||||
import OrderDetail from './components/order-detail.vue';
|
||||
import OrderHistory from './components/order-history.vue';
|
||||
import BatchImportModal from './components/batch-import-modal.vue';
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
|
||||
@@ -343,13 +280,8 @@ const formModel = reactive<FormModel>({
|
||||
});
|
||||
|
||||
// 弹窗状态
|
||||
const modalVisible = ref(false);
|
||||
const detailVisible = ref(false);
|
||||
const historyVisible = ref(false);
|
||||
const currentOrder = ref<KamiApiJdCookieV1OrderInfo | null>(null);
|
||||
const currentOrderId = ref('');
|
||||
const batchChecking = ref(false);
|
||||
const checkingOrders = ref<string[]>([]);
|
||||
const paymentUrlLoading = ref<string[]>([]);
|
||||
|
||||
// 获取订单列表
|
||||
@@ -429,60 +361,6 @@ const onPageSizeChange = (pageSize: number): void => {
|
||||
fetchData(params);
|
||||
};
|
||||
|
||||
// 批量检查支付
|
||||
const batchCheckPayment = async (): Promise<void> => {
|
||||
batchChecking.value = true;
|
||||
try {
|
||||
const orderIds = renderData.value
|
||||
.filter(order => order.status === 1)
|
||||
.map(order => order.orderId);
|
||||
|
||||
if (orderIds.length === 0) {
|
||||
Message.warning('没有待支付的订单');
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
orderIds.map(orderId =>
|
||||
jdOrderClient.apiJdCookieOrderJdPaymentStatusPost({
|
||||
kamiApiJdCookieV1CheckJdOrderPaymentReq: {
|
||||
jd_order_id: orderId
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
Message.success('批量检查支付完成');
|
||||
search();
|
||||
} catch (error) {
|
||||
Message.error('批量检查支付失败');
|
||||
} finally {
|
||||
batchChecking.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 检查支付
|
||||
const checkPayment = async (
|
||||
record: KamiApiJdCookieV1OrderInfo
|
||||
): Promise<void> => {
|
||||
checkingOrders.value.push(record.orderId);
|
||||
try {
|
||||
await jdOrderClient.apiJdCookieOrderJdPaymentStatusPost({
|
||||
kamiApiJdCookieV1CheckJdOrderPaymentReq: {
|
||||
jd_order_id: record.orderId
|
||||
}
|
||||
});
|
||||
Message.success('检查支付完成');
|
||||
search();
|
||||
} catch (error) {
|
||||
Message.error('检查支付失败');
|
||||
} finally {
|
||||
checkingOrders.value = checkingOrders.value.filter(
|
||||
id => id !== record.orderId
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取支付链接
|
||||
const getPaymentUrl = async (
|
||||
record: KamiApiJdCookieV1OrderInfo
|
||||
@@ -509,28 +387,12 @@ const getPaymentUrl = async (
|
||||
}
|
||||
};
|
||||
|
||||
// 显示创建弹窗
|
||||
const showCreateModal = (): void => {
|
||||
modalVisible.value = true;
|
||||
};
|
||||
|
||||
// 显示详情
|
||||
const showDetail = (record: KamiApiJdCookieV1OrderInfo): void => {
|
||||
currentOrder.value = record;
|
||||
detailVisible.value = true;
|
||||
};
|
||||
|
||||
// 显示历史
|
||||
const showHistory = (record: KamiApiJdCookieV1OrderInfo): void => {
|
||||
currentOrderId.value = record.orderId;
|
||||
historyVisible.value = true;
|
||||
};
|
||||
|
||||
// 弹窗成功回调
|
||||
const handleModalSuccess = (): void => {
|
||||
search();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user