feat(camel-oil): 更新账号相关API模型和界面组件
- 从账号历史记录模型中移除historyUuid字段 - 在创建令牌请求模型中新增phone字段用于绑定手机号 - 在令牌信息模型中新增phone字段 - 移除账号详情页面中的账号ID显示和统计信息卡片 - 更新账号历史记录组件的筛选条件和展示字段 - 修改账号列表中的状态选项和显示逻辑 - 移除账号关联订单统计弹窗及相关功能 - 更新订单历史记录模型枚举值,新增FillCard类型 - 调整.clau ```
This commit is contained in:
@@ -9,7 +9,9 @@
|
|||||||
"Bash(pnpm lint:*)",
|
"Bash(pnpm lint:*)",
|
||||||
"Bash(pnpm prettier:fix)",
|
"Bash(pnpm prettier:fix)",
|
||||||
"Bash(pnpm eslint:*)",
|
"Bash(pnpm eslint:*)",
|
||||||
"Bash(mkdir:*)"
|
"Bash(mkdir:*)",
|
||||||
|
"Bash(pnpm build)",
|
||||||
|
"Bash(pnpm eslint:fix)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
| Name | Type | Description | Notes |
|
| Name | Type | Description | Notes |
|
||||||
| ---------------- | ---------- | ------------ | --------------------------------- |
|
| ---------------- | ---------- | ------------ | --------------------------------- |
|
||||||
| **historyUuid** | **string** | 历史记录UUID | [optional] [default to undefined] |
|
|
||||||
| **accountId** | **number** | 账号ID | [optional] [default to undefined] |
|
| **accountId** | **number** | 账号ID | [optional] [default to undefined] |
|
||||||
| **changeType** | **string** | 变更类型 | [optional] [default to undefined] |
|
| **changeType** | **string** | 变更类型 | [optional] [default to undefined] |
|
||||||
| **changeText** | **string** | 变更类型文本 | [optional] [default to undefined] |
|
| **changeText** | **string** | 变更类型文本 | [optional] [default to undefined] |
|
||||||
@@ -20,7 +19,6 @@
|
|||||||
import { KamiApiCamelOilV1AccountHistoryItem } from './api';
|
import { KamiApiCamelOilV1AccountHistoryItem } from './api';
|
||||||
|
|
||||||
const instance: KamiApiCamelOilV1AccountHistoryItem = {
|
const instance: KamiApiCamelOilV1AccountHistoryItem = {
|
||||||
historyUuid,
|
|
||||||
accountId,
|
accountId,
|
||||||
changeType,
|
changeType,
|
||||||
changeText,
|
changeText,
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
| Name | Type | Description | Notes |
|
| Name | Type | Description | Notes |
|
||||||
| -------------- | ---------- | ----------- | --------------------------------- |
|
| -------------- | ---------- | ------------ | --------------------------------- |
|
||||||
| **tokenName** | **string** | Token名称 | [default to undefined] |
|
| **tokenName** | **string** | Token名称 | [default to undefined] |
|
||||||
| **tokenValue** | **string** | Token值 | [default to undefined] |
|
| **tokenValue** | **string** | Token值 | [default to undefined] |
|
||||||
| **remark** | **string** | 备注 | [optional] [default to undefined] |
|
| **phone** | **string** | 绑定的手机号 | [optional] [default to undefined] |
|
||||||
|
| **remark** | **string** | 备注 | [optional] [default to undefined] |
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ import { KamiApiCamelOilV1CreateTokenReq } from './api';
|
|||||||
const instance: KamiApiCamelOilV1CreateTokenReq = {
|
const instance: KamiApiCamelOilV1CreateTokenReq = {
|
||||||
tokenName,
|
tokenName,
|
||||||
tokenValue,
|
tokenValue,
|
||||||
|
phone,
|
||||||
remark
|
remark
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
| Name | Type | Description | Notes |
|
| Name | Type | Description | Notes |
|
||||||
| --------------- | ---------- | ------------ | --------------------------------- |
|
| --------------- | ---------- | ------------ | --------------------------------- |
|
||||||
| **historyUuid** | **string** | 历史记录UUID | [optional] [default to undefined] |
|
|
||||||
| **orderNo** | **string** | 订单号 | [optional] [default to undefined] |
|
| **orderNo** | **string** | 订单号 | [optional] [default to undefined] |
|
||||||
| **changeType** | **string** | 变更类型 | [optional] [default to undefined] |
|
| **changeType** | **string** | 变更类型 | [optional] [default to undefined] |
|
||||||
| **changeText** | **string** | 变更类型文本 | [optional] [default to undefined] |
|
| **changeText** | **string** | 变更类型文本 | [optional] [default to undefined] |
|
||||||
@@ -20,7 +19,6 @@
|
|||||||
import { KamiApiCamelOilV1OrderHistoryItem } from './api';
|
import { KamiApiCamelOilV1OrderHistoryItem } from './api';
|
||||||
|
|
||||||
const instance: KamiApiCamelOilV1OrderHistoryItem = {
|
const instance: KamiApiCamelOilV1OrderHistoryItem = {
|
||||||
historyUuid,
|
|
||||||
orderNo,
|
orderNo,
|
||||||
changeType,
|
changeType,
|
||||||
changeText,
|
changeText,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
| **id** | **number** | Token ID | [optional] [default to undefined] |
|
| **id** | **number** | Token ID | [optional] [default to undefined] |
|
||||||
| **tokenName** | **string** | Token名称 | [optional] [default to undefined] |
|
| **tokenName** | **string** | Token名称 | [optional] [default to undefined] |
|
||||||
| **tokenValue** | **string** | Token值 | [optional] [default to undefined] |
|
| **tokenValue** | **string** | Token值 | [optional] [default to undefined] |
|
||||||
|
| **phone** | **string** | 绑定的手机号 | [optional] [default to undefined] |
|
||||||
| **status** | **number** | 状态 | [optional] [default to undefined] |
|
| **status** | **number** | 状态 | [optional] [default to undefined] |
|
||||||
| **bindCount** | **number** | 已绑定卡密数量 | [optional] [default to undefined] |
|
| **bindCount** | **number** | 已绑定卡密数量 | [optional] [default to undefined] |
|
||||||
| **totalBindAmount** | **object** | | [optional] [default to undefined] |
|
| **totalBindAmount** | **object** | | [optional] [default to undefined] |
|
||||||
@@ -25,6 +26,7 @@ const instance: KamiApiCamelOilV1TokenInfo = {
|
|||||||
id,
|
id,
|
||||||
tokenName,
|
tokenName,
|
||||||
tokenValue,
|
tokenValue,
|
||||||
|
phone,
|
||||||
status,
|
status,
|
||||||
bindCount,
|
bindCount,
|
||||||
totalBindAmount,
|
totalBindAmount,
|
||||||
|
|||||||
@@ -13,10 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface KamiApiCamelOilV1AccountHistoryItem {
|
export interface KamiApiCamelOilV1AccountHistoryItem {
|
||||||
/**
|
|
||||||
* 历史记录UUID
|
|
||||||
*/
|
|
||||||
historyUuid?: string;
|
|
||||||
/**
|
/**
|
||||||
* 账号ID
|
* 账号ID
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ export interface KamiApiCamelOilV1CreateTokenReq {
|
|||||||
* Token值
|
* Token值
|
||||||
*/
|
*/
|
||||||
tokenValue: string;
|
tokenValue: string;
|
||||||
|
/**
|
||||||
|
* 绑定的手机号
|
||||||
|
*/
|
||||||
|
phone?: string;
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -13,10 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export interface KamiApiCamelOilV1OrderHistoryItem {
|
export interface KamiApiCamelOilV1OrderHistoryItem {
|
||||||
/**
|
|
||||||
* 历史记录UUID
|
|
||||||
*/
|
|
||||||
historyUuid?: string;
|
|
||||||
/**
|
/**
|
||||||
* 订单号
|
* 订单号
|
||||||
*/
|
*/
|
||||||
@@ -57,6 +53,7 @@ export enum KamiApiCamelOilV1OrderHistoryItemChangeTypeEnum {
|
|||||||
CheckPay = 'check_pay',
|
CheckPay = 'check_pay',
|
||||||
Create = 'create',
|
Create = 'create',
|
||||||
Fail = 'fail',
|
Fail = 'fail',
|
||||||
|
FillCard = 'fill_card',
|
||||||
GetPayUrl = 'get_pay_url',
|
GetPayUrl = 'get_pay_url',
|
||||||
Paid = 'paid',
|
Paid = 'paid',
|
||||||
Submit = 'submit',
|
Submit = 'submit',
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ export interface KamiApiCamelOilV1TokenInfo {
|
|||||||
* Token值
|
* Token值
|
||||||
*/
|
*/
|
||||||
tokenValue?: string;
|
tokenValue?: string;
|
||||||
|
/**
|
||||||
|
* 绑定的手机号
|
||||||
|
*/
|
||||||
|
phone?: string;
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,257 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-modal
|
|
||||||
v-model:visible="modalVisible"
|
|
||||||
title="账号关联订单统计"
|
|
||||||
width="600px"
|
|
||||||
:footer="false"
|
|
||||||
>
|
|
||||||
<a-spin :loading="loading" style="width: 100%">
|
|
||||||
<div v-if="accountOrderStats" class="orders-stats">
|
|
||||||
<!-- 订单统计卡片 -->
|
|
||||||
<a-row :gutter="16" style="margin-bottom: 24px">
|
|
||||||
<a-col :span="6">
|
|
||||||
<a-statistic
|
|
||||||
title="总订单数"
|
|
||||||
:value="statistics.totalOrders"
|
|
||||||
suffix="单"
|
|
||||||
:value-style="{ color: '#165dff', fontSize: '24px' }"
|
|
||||||
/>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="6">
|
|
||||||
<a-statistic
|
|
||||||
title="已支付订单"
|
|
||||||
:value="statistics.paidOrders"
|
|
||||||
suffix="单"
|
|
||||||
:value-style="{ color: '#00b42a', fontSize: '24px' }"
|
|
||||||
/>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="6">
|
|
||||||
<a-statistic
|
|
||||||
title="待支付订单"
|
|
||||||
:value="statistics.pendingOrders"
|
|
||||||
suffix="单"
|
|
||||||
:value-style="{ color: '#ff7d00', fontSize: '24px' }"
|
|
||||||
/>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="6">
|
|
||||||
<a-statistic
|
|
||||||
title="超时订单"
|
|
||||||
:value="statistics.timeoutOrders"
|
|
||||||
suffix="单"
|
|
||||||
:value-style="{ color: '#f53f3f', fontSize: '24px' }"
|
|
||||||
/>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
|
|
||||||
<!-- 详细统计信息 -->
|
|
||||||
<a-card title="详细统计" class="detail-stats-card">
|
|
||||||
<a-descriptions :column="2" bordered>
|
|
||||||
<a-descriptions-item label="总订单数">
|
|
||||||
<a-tag color="blue">{{ statistics.totalOrders }} 单</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="已支付订单">
|
|
||||||
<a-tag color="green">{{ statistics.paidOrders }} 单</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="待支付订单">
|
|
||||||
<a-tag color="orange">{{ statistics.pendingOrders }} 单</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="超时订单">
|
|
||||||
<a-tag color="red">{{ statistics.timeoutOrders }} 单</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="支付成功率">
|
|
||||||
<span :class="paymentRateClass">{{ paymentRate }}%</span>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="待支付率">
|
|
||||||
<span :class="pendingRateClass">{{ pendingRate }}%</span>
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 空状态 -->
|
|
||||||
<a-empty v-else description="暂无订单统计数据" />
|
|
||||||
</a-spin>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
|
||||||
import { jdV2OrderClient } from '@/api/index.ts';
|
|
||||||
import type { KamiApiCamelOilV1AccountOrderListResOrderStats } from '@/api/generated/models/index.ts';
|
|
||||||
|
|
||||||
// Props 定义
|
|
||||||
interface Props {
|
|
||||||
visible: boolean;
|
|
||||||
accountId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
visible: false,
|
|
||||||
accountId: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
// Emits 定义
|
|
||||||
interface Emits {
|
|
||||||
(e: 'update:visible', value: boolean): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
|
||||||
|
|
||||||
// 响应式数据
|
|
||||||
const loading = ref(false);
|
|
||||||
const accountOrderStats =
|
|
||||||
ref<KamiApiCamelOilV1AccountOrderListResOrderStats | null>(null);
|
|
||||||
|
|
||||||
// 统计数据
|
|
||||||
const statistics = reactive({
|
|
||||||
totalOrders: 0,
|
|
||||||
paidOrders: 0,
|
|
||||||
pendingOrders: 0,
|
|
||||||
timeoutOrders: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算属性
|
|
||||||
const modalVisible = computed({
|
|
||||||
get: () => props.visible,
|
|
||||||
set: value => emit('update:visible', value)
|
|
||||||
});
|
|
||||||
|
|
||||||
const paymentRate = computed(() => {
|
|
||||||
if (statistics.totalOrders === 0) return 0;
|
|
||||||
return ((statistics.paidOrders / statistics.totalOrders) * 100).toFixed(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
const pendingRate = computed(() => {
|
|
||||||
if (statistics.totalOrders === 0) return 0;
|
|
||||||
return ((statistics.pendingOrders / statistics.totalOrders) * 100).toFixed(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
const paymentRateClass = computed(() => {
|
|
||||||
const rate = parseFloat(paymentRate.value.toString());
|
|
||||||
if (rate >= 90) return 'rate-excellent';
|
|
||||||
if (rate >= 70) return 'rate-good';
|
|
||||||
return 'rate-poor';
|
|
||||||
});
|
|
||||||
|
|
||||||
const pendingRateClass = computed(() => {
|
|
||||||
const rate = parseFloat(pendingRate.value.toString());
|
|
||||||
if (rate <= 10) return 'rate-excellent';
|
|
||||||
if (rate <= 30) return 'rate-good';
|
|
||||||
return 'rate-poor';
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取账号订单统计数据
|
|
||||||
*/
|
|
||||||
const fetchAccountOrderStats = async () => {
|
|
||||||
if (!props.accountId) return;
|
|
||||||
|
|
||||||
loading.value = true;
|
|
||||||
try {
|
|
||||||
// 由于API结构问题,这里暂时使用模拟数据
|
|
||||||
// 实际应该调用: camelOilOrderClient.apiCamelOilOrderAccountOrdersGet()
|
|
||||||
// 但是这个API返回的是单个账号的订单统计,不是列表
|
|
||||||
|
|
||||||
// 模拟数据,等待API完善
|
|
||||||
accountOrderStats.value = {
|
|
||||||
totalOrders: 150,
|
|
||||||
paidOrders: 120,
|
|
||||||
pendingOrders: 25,
|
|
||||||
timeoutOrders: 5
|
|
||||||
};
|
|
||||||
|
|
||||||
// 更新统计数据
|
|
||||||
if (accountOrderStats.value) {
|
|
||||||
Object.assign(statistics, {
|
|
||||||
totalOrders: accountOrderStats.value.totalOrders || 0,
|
|
||||||
paidOrders: accountOrderStats.value.paidOrders || 0,
|
|
||||||
pendingOrders: accountOrderStats.value.pendingOrders || 0,
|
|
||||||
timeoutOrders: accountOrderStats.value.timeoutOrders || 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取账号订单统计失败:', error);
|
|
||||||
accountOrderStats.value = null;
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 监听弹窗显示状态
|
|
||||||
watch(
|
|
||||||
() => props.visible,
|
|
||||||
visible => {
|
|
||||||
if (visible && props.accountId) {
|
|
||||||
fetchAccountOrderStats();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
// 监听账号ID变化
|
|
||||||
watch(
|
|
||||||
() => props.accountId,
|
|
||||||
accountId => {
|
|
||||||
if (accountId && props.visible) {
|
|
||||||
fetchAccountOrderStats();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.orders-stats {
|
|
||||||
padding: 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-stats-card {
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rate-excellent {
|
|
||||||
color: #00b42a;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rate-good {
|
|
||||||
color: #ff7d00;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rate-poor {
|
|
||||||
color: #f53f3f;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-statistic) {
|
|
||||||
text-align: center;
|
|
||||||
padding: 16px;
|
|
||||||
border-radius: 6px;
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-statistic-title) {
|
|
||||||
color: #86909c;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-statistic-value) {
|
|
||||||
color: #1d2129;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-descriptions-item-label) {
|
|
||||||
font-weight: 600;
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-modal-body) {
|
|
||||||
max-height: 70vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -10,9 +10,6 @@
|
|||||||
<!-- 基本信息 -->
|
<!-- 基本信息 -->
|
||||||
<a-card title="基本信息" class="detail-card">
|
<a-card title="基本信息" class="detail-card">
|
||||||
<a-descriptions :column="2" bordered>
|
<a-descriptions :column="2" bordered>
|
||||||
<a-descriptions-item label="账号ID">
|
|
||||||
{{ accountDetail.accountId }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="账号名称">
|
<a-descriptions-item label="账号名称">
|
||||||
{{ accountDetail.accountName }}
|
{{ accountDetail.accountName }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
@@ -35,33 +32,6 @@
|
|||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<!-- 统计信息 -->
|
|
||||||
<a-card title="统计信息" class="detail-card">
|
|
||||||
<a-row :gutter="16">
|
|
||||||
<a-col :span="8">
|
|
||||||
<a-statistic
|
|
||||||
title="今日充值金额"
|
|
||||||
:value="parseFloat(statistics.todayAmount)"
|
|
||||||
prefix="¥"
|
|
||||||
/>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="8">
|
|
||||||
<a-statistic
|
|
||||||
title="今日充值次数"
|
|
||||||
:value="parseFloat(statistics.todayCount)"
|
|
||||||
suffix="次"
|
|
||||||
/>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="8">
|
|
||||||
<a-statistic
|
|
||||||
title="本月充值金额"
|
|
||||||
:value="parseFloat(statistics.monthAmount)"
|
|
||||||
prefix="¥"
|
|
||||||
/>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
@@ -98,13 +68,6 @@ const loading = ref(false);
|
|||||||
const accountDetail =
|
const accountDetail =
|
||||||
ref<KamiApiCamelOilV1AccountStatisticsResAccountInfo | null>(null);
|
ref<KamiApiCamelOilV1AccountStatisticsResAccountInfo | null>(null);
|
||||||
|
|
||||||
// 统计数据
|
|
||||||
const statistics = ref({
|
|
||||||
todayAmount: '0',
|
|
||||||
todayCount: '0',
|
|
||||||
monthAmount: '0'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const modalVisible = computed({
|
const modalVisible = computed({
|
||||||
get: () => props.visible,
|
get: () => props.visible,
|
||||||
@@ -112,26 +75,19 @@ const modalVisible = computed({
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取账号详情和统计信息
|
* 获取账号详情
|
||||||
*/
|
*/
|
||||||
const fetchAccountDetail = async () => {
|
const fetchAccountDetail = async () => {
|
||||||
if (!props.accountId) return;
|
if (!props.accountId) return;
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
// 获取账号统计信息
|
// 获取账号详情信息
|
||||||
const { data } = await jdV2AccountClient.apiJdV2AccountStatisticsGet({
|
const { data } = await jdV2AccountClient.apiJdV2AccountStatisticsGet({
|
||||||
accountId: parseInt(props.accountId)
|
accountId: parseInt(props.accountId)
|
||||||
});
|
});
|
||||||
|
|
||||||
accountDetail.value = data.accountInfo;
|
accountDetail.value = data.accountInfo;
|
||||||
|
|
||||||
// 暂时使用默认统计信息,等待API完善
|
|
||||||
statistics.value = {
|
|
||||||
todayAmount: '0',
|
|
||||||
todayCount: '0',
|
|
||||||
monthAmount: '0'
|
|
||||||
};
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取账号详情失败:', error);
|
console.error('获取账号详情失败:', error);
|
||||||
accountDetail.value = null;
|
accountDetail.value = null;
|
||||||
@@ -148,20 +104,20 @@ const fetchAccountDetail = async () => {
|
|||||||
const statusMapper = (
|
const statusMapper = (
|
||||||
status: number | undefined
|
status: number | undefined
|
||||||
): { text: string; color: string } => {
|
): { text: string; color: string } => {
|
||||||
if (!status) return { text: '未知', color: 'gray' };
|
if (!status) return { text: '未知状态', color: 'gray' };
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
return { text: '失效', color: 'red' };
|
return { text: '待登录', color: 'orange' }; // 需要登录验证
|
||||||
case 1:
|
case 1:
|
||||||
return { text: '正常', color: 'green' };
|
return { text: '发送验证码', color: 'blue' }; // 正在发送验证码
|
||||||
case 2:
|
case 2:
|
||||||
return { text: '充值过快', color: 'orange' };
|
return { text: '在线', color: 'green' }; // 账户在线,可用
|
||||||
case 3:
|
case 3:
|
||||||
return { text: '账号受限', color: 'red' };
|
return { text: '已暂停', color: 'orange' }; // 账户被暂停使用
|
||||||
case 4:
|
case 4:
|
||||||
return { text: '异常', color: 'gray' };
|
return { text: '已失效', color: 'red' }; // 账户已失效
|
||||||
default:
|
default:
|
||||||
return { text: '未知', color: 'gray' };
|
return { text: '未知状态', color: 'gray' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -200,39 +156,8 @@ watch(
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-text {
|
|
||||||
color: #00b42a;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.recharge-text {
|
|
||||||
color: #165dff;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-descriptions-item-label) {
|
:deep(.arco-descriptions-item-label) {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
background-color: #f7f8fa;
|
background-color: var(--color-fill-2);
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-statistic) {
|
|
||||||
text-align: center;
|
|
||||||
padding: 16px;
|
|
||||||
border-radius: 6px;
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-statistic-title) {
|
|
||||||
color: #86909c;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-statistic-value) {
|
|
||||||
color: #1d2129;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -27,18 +27,26 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item field="action" label="操作类型">
|
<a-form-item field="changeType" label="变更类型">
|
||||||
<a-select
|
<a-select
|
||||||
v-model="filterForm.action"
|
v-model="filterForm.changeType"
|
||||||
placeholder="请选择操作类型"
|
placeholder="请选择变更类型"
|
||||||
allow-clear
|
allow-clear
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<a-option value="create">创建</a-option>
|
<a-option value="create">创建账号</a-option>
|
||||||
<a-option value="update">更新</a-option>
|
<a-option value="login">登录成功</a-option>
|
||||||
<a-option value="delete">删除</a-option>
|
<a-option value="offline">检测到掉线</a-option>
|
||||||
<a-option value="recharge">充值</a-option>
|
<a-option value="login_fail">登录失败</a-option>
|
||||||
<a-option value="consume">消费</a-option>
|
<a-option value="pause">订单数达到10,暂停使用</a-option>
|
||||||
|
<a-option value="resume">次日重置,恢复使用</a-option>
|
||||||
|
<a-option value="invalidate">
|
||||||
|
单日下单不足10个,账号失效
|
||||||
|
</a-option>
|
||||||
|
<a-option value="order_bind">绑定订单</a-option>
|
||||||
|
<a-option value="order_complete">订单完成</a-option>
|
||||||
|
<a-option value="update">更新账号信息</a-option>
|
||||||
|
<a-option value="delete">删除账号</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -79,31 +87,39 @@
|
|||||||
@page-change="onPageChange"
|
@page-change="onPageChange"
|
||||||
@page-size-change="onPageSizeChange"
|
@page-size-change="onPageSizeChange"
|
||||||
>
|
>
|
||||||
<template #action="{ record }">
|
<template #changeType="{ record }">
|
||||||
<a-tag :color="actionMapper(record.action).color">
|
<a-tag :color="changeTypeMapper(record.changeType).color">
|
||||||
{{ actionMapper(record.action).text }}
|
{{ changeTypeMapper(record.changeType).text }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #amount="{ record }">
|
<template #beforeStatus="{ record }">
|
||||||
<span
|
<a-tag
|
||||||
v-if="record.amount"
|
v-if="
|
||||||
:class="{
|
record.statusBefore !== undefined &&
|
||||||
'amount-positive': record.amount > 0,
|
record.statusBefore !== null
|
||||||
'amount-negative': record.amount < 0
|
"
|
||||||
}"
|
:color="statusColorMapper(record.statusBefore)"
|
||||||
>
|
>
|
||||||
{{ record.amount > 0 ? '+' : '' }}¥{{ record.amount }}
|
{{ statusMapper(record.statusBefore).text }}
|
||||||
</span>
|
</a-tag>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #balance="{ record }">
|
<template #afterStatus="{ record }">
|
||||||
<span class="balance-text">¥{{ record.balance || 0 }}</span>
|
<a-tag
|
||||||
|
v-if="
|
||||||
|
record.statusAfter !== undefined && record.statusAfter !== null
|
||||||
|
"
|
||||||
|
:color="statusColorMapper(record.statusAfter)"
|
||||||
|
>
|
||||||
|
{{ statusMapper(record.statusAfter).text }}
|
||||||
|
</a-tag>
|
||||||
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #details="{ record }">
|
<template #remark="{ record }">
|
||||||
<a-tooltip v-if="record.details" :content="record.details">
|
<a-tooltip v-if="record.remark" :content="record.remark">
|
||||||
<a-button size="small" type="text">
|
<a-button size="small" type="text">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-eye />
|
<icon-eye />
|
||||||
@@ -120,10 +136,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
import { computed, reactive, ref, watch } from 'vue';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import { TableColumnData } from '@arco-design/web-vue';
|
import { TableColumnData } from '@arco-design/web-vue';
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import { Pagination } from '@/types/global';
|
import { Pagination } from '@/types/global';
|
||||||
import { jdV2AccountClient } from '@/api/index.ts';
|
import { jdV2AccountClient } from '@/api/index.ts';
|
||||||
import type { KamiApiCamelOilV1AccountHistoryItem } from '@/api/generated/models/index.ts';
|
import type { KamiApiCamelOilV1AccountHistoryItem } from '@/api/generated/models/index.ts';
|
||||||
@@ -148,7 +163,7 @@ interface Emits {
|
|||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const { loading, setLoading } = useLoading(false);
|
const loading = ref(false);
|
||||||
const tableLoading = ref(false);
|
const tableLoading = ref(false);
|
||||||
const historyData = ref<KamiApiCamelOilV1AccountHistoryItem[]>([]);
|
const historyData = ref<KamiApiCamelOilV1AccountHistoryItem[]>([]);
|
||||||
|
|
||||||
@@ -163,7 +178,7 @@ const pagination = reactive({ ...basePagination });
|
|||||||
// 筛选表单
|
// 筛选表单
|
||||||
const filterForm = reactive({
|
const filterForm = reactive({
|
||||||
dateRange: [] as Date[],
|
dateRange: [] as Date[],
|
||||||
action: undefined as string | undefined
|
changeType: undefined as string | undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
// 时间快捷选项
|
// 时间快捷选项
|
||||||
@@ -220,43 +235,37 @@ const columns: TableColumnData[] = [
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作类型',
|
title: '变更类型',
|
||||||
dataIndex: 'action',
|
dataIndex: 'changeType',
|
||||||
slotName: 'action',
|
slotName: 'changeType',
|
||||||
|
width: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '变更前状态',
|
||||||
|
dataIndex: 'statusBefore',
|
||||||
|
slotName: 'beforeStatus',
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作人',
|
title: '变更后状态',
|
||||||
dataIndex: 'operator',
|
dataIndex: 'statusAfter',
|
||||||
width: 120
|
slotName: 'afterStatus',
|
||||||
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '金额变化',
|
title: '备注说明',
|
||||||
dataIndex: 'amount',
|
dataIndex: 'remark',
|
||||||
slotName: 'amount',
|
|
||||||
width: 120
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作后余额',
|
|
||||||
dataIndex: 'balance',
|
|
||||||
slotName: 'balance',
|
|
||||||
width: 120
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作说明',
|
|
||||||
dataIndex: 'description',
|
|
||||||
width: 200,
|
width: 200,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: true
|
tooltip: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '详细信息',
|
title: '失败次数',
|
||||||
dataIndex: 'details',
|
dataIndex: 'failureCount',
|
||||||
slotName: 'details',
|
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作时间',
|
title: '创建时间',
|
||||||
dataIndex: 'createdAt',
|
dataIndex: 'createdAt',
|
||||||
width: 180
|
width: 180
|
||||||
}
|
}
|
||||||
@@ -338,31 +347,90 @@ const searchHistory = () => {
|
|||||||
*/
|
*/
|
||||||
const resetFilter = () => {
|
const resetFilter = () => {
|
||||||
filterForm.dateRange = [];
|
filterForm.dateRange = [];
|
||||||
filterForm.action = undefined;
|
filterForm.changeType = undefined;
|
||||||
searchHistory();
|
searchHistory();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作类型映射器
|
* 变更类型映射器
|
||||||
* @param action 操作类型
|
* 基于后端Go定义的CamelOilAccountChangeType
|
||||||
* @returns 操作类型文本和颜色
|
* @param changeType 变更类型
|
||||||
|
* @returns 变更类型文本和颜色
|
||||||
*/
|
*/
|
||||||
const actionMapper = (action: string): { text: string; color: string } => {
|
const changeTypeMapper = (
|
||||||
switch (action) {
|
changeType: string
|
||||||
|
): { text: string; color: string } => {
|
||||||
|
switch (changeType) {
|
||||||
case 'create':
|
case 'create':
|
||||||
return { text: '创建', color: 'green' };
|
return { text: '创建账号', color: 'green' };
|
||||||
|
case 'login':
|
||||||
|
return { text: '登录成功', color: 'blue' };
|
||||||
|
case 'offline':
|
||||||
|
return { text: '检测到掉线', color: 'orange' };
|
||||||
|
case 'login_fail':
|
||||||
|
return { text: '登录失败', color: 'red' };
|
||||||
|
case 'pause':
|
||||||
|
return { text: '订单数达到10,暂停使用', color: 'orange' };
|
||||||
|
case 'resume':
|
||||||
|
return { text: '次日重置,恢复使用', color: 'green' };
|
||||||
|
case 'invalidate':
|
||||||
|
return { text: '单日下单不足10个,账号失效', color: 'red' };
|
||||||
|
case 'order_bind':
|
||||||
|
return { text: '绑定订单', color: 'blue' };
|
||||||
|
case 'order_complete':
|
||||||
|
return { text: '订单完成', color: 'green' };
|
||||||
case 'update':
|
case 'update':
|
||||||
return { text: '更新', color: 'blue' };
|
return { text: '更新账号信息', color: 'blue' };
|
||||||
case 'delete':
|
case 'delete':
|
||||||
return { text: '删除', color: 'red' };
|
return { text: '删除账号', color: 'red' };
|
||||||
case 'recharge':
|
|
||||||
return { text: '充值', color: 'green' };
|
|
||||||
case 'consume':
|
|
||||||
return { text: '消费', color: 'orange' };
|
|
||||||
case 'status_change':
|
|
||||||
return { text: '状态变更', color: 'purple' };
|
|
||||||
default:
|
default:
|
||||||
return { text: '未知', color: 'gray' };
|
return { text: '未知变更', color: 'gray' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态颜色映射器
|
||||||
|
* 基于后端Go定义的CamelOilAccountStatus
|
||||||
|
* @param status 状态值
|
||||||
|
* @returns 状态颜色
|
||||||
|
*/
|
||||||
|
const statusColorMapper = (status: number): string => {
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
return 'orange'; // 待登录
|
||||||
|
case 1:
|
||||||
|
return 'blue'; // 发送验证码
|
||||||
|
case 2:
|
||||||
|
return 'green'; // 在线
|
||||||
|
case 3:
|
||||||
|
return 'orange'; // 已暂停
|
||||||
|
case 4:
|
||||||
|
return 'red'; // 已失效
|
||||||
|
default:
|
||||||
|
return 'gray'; // 未知状态
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态文本映射器
|
||||||
|
* 基于后端Go定义的CamelOilAccountStatus
|
||||||
|
* @param status 状态值
|
||||||
|
* @returns 状态文本
|
||||||
|
*/
|
||||||
|
const statusMapper = (status: number): { text: string } => {
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
return { text: '待登录' };
|
||||||
|
case 1:
|
||||||
|
return { text: '发送验证码' };
|
||||||
|
case 2:
|
||||||
|
return { text: '在线' };
|
||||||
|
case 3:
|
||||||
|
return { text: '已暂停' };
|
||||||
|
case 4:
|
||||||
|
return { text: '已失效' };
|
||||||
|
default:
|
||||||
|
return { text: '未知状态' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -393,23 +461,25 @@ watch(
|
|||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.amount-positive {
|
|
||||||
color: #00b42a;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.amount-negative {
|
|
||||||
color: #f53f3f;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance-text {
|
|
||||||
color: #165dff;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-modal-body) {
|
:deep(.arco-modal-body) {
|
||||||
max-height: 70vh;
|
max-height: 70vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
/* 确保滚动条样式跟随主题 */
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--color-border-3) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar) {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-thumb) {
|
||||||
|
background-color: var(--color-border-3);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-track) {
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,135 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-modal
|
|
||||||
v-model:visible="modalVisible"
|
|
||||||
title="订单详情"
|
|
||||||
width="700px"
|
|
||||||
:footer="false"
|
|
||||||
>
|
|
||||||
<div v-if="order" class="order-detail">
|
|
||||||
<a-descriptions :column="2" bordered>
|
|
||||||
<a-descriptions-item label="订单号">
|
|
||||||
{{ order.orderNo }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="商户订单号">
|
|
||||||
{{ order.merchantOrderNo || '-' }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="订单金额">
|
|
||||||
<span class="amount-text">¥{{ order.amount }}</span>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="订单状态">
|
|
||||||
<a-tag :color="statusMapper(order.status).color">
|
|
||||||
{{ statusMapper(order.status).text }}
|
|
||||||
</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="支付状态">
|
|
||||||
<a-tag :color="payStatusMapper(order.payStatus).color">
|
|
||||||
{{ payStatusMapper(order.payStatus).text }}
|
|
||||||
</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="充值账号">
|
|
||||||
{{ order.accountName }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="充值手机">
|
|
||||||
{{ order.accountPhone }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="回调状态">
|
|
||||||
<a-tag :color="order.callbackStatus === 1 ? 'green' : 'red'">
|
|
||||||
{{ order.callbackStatus === 1 ? '成功' : '失败' }}
|
|
||||||
</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="创建时间" :span="2">
|
|
||||||
{{ order.createdAt }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="更新时间" :span="2">
|
|
||||||
{{ order.updatedAt }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="备注" :span="2">
|
|
||||||
{{ order.remark || '-' }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
</div>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
|
|
||||||
// Props 定义
|
|
||||||
interface Props {
|
|
||||||
visible: boolean;
|
|
||||||
order: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
visible: false,
|
|
||||||
order: null
|
|
||||||
});
|
|
||||||
|
|
||||||
// Emits 定义
|
|
||||||
interface Emits {
|
|
||||||
(e: 'update:visible', value: boolean): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
|
||||||
|
|
||||||
// 计算属性
|
|
||||||
const modalVisible = computed({
|
|
||||||
get: () => props.visible,
|
|
||||||
set: value => emit('update:visible', value)
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订单状态映射器
|
|
||||||
* @param status 状态值
|
|
||||||
* @returns 状态文本和颜色
|
|
||||||
*/
|
|
||||||
const statusMapper = (status: number): { text: string; color: string } => {
|
|
||||||
switch (status) {
|
|
||||||
case 0:
|
|
||||||
return { text: '待处理', color: 'orange' };
|
|
||||||
case 1:
|
|
||||||
return { text: '成功', color: 'green' };
|
|
||||||
case 2:
|
|
||||||
return { text: '失败', color: 'red' };
|
|
||||||
case 3:
|
|
||||||
return { text: '已取消', color: 'gray' };
|
|
||||||
default:
|
|
||||||
return { text: '未知', color: 'gray' };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付状态映射器
|
|
||||||
* @param status 支付状态
|
|
||||||
* @returns 支付状态文本和颜色
|
|
||||||
*/
|
|
||||||
const payStatusMapper = (status: number): { text: string; color: string } => {
|
|
||||||
switch (status) {
|
|
||||||
case 0:
|
|
||||||
return { text: '未支付', color: 'orange' };
|
|
||||||
case 1:
|
|
||||||
return { text: '已支付', color: 'green' };
|
|
||||||
case 2:
|
|
||||||
return { text: '支付失败', color: 'red' };
|
|
||||||
default:
|
|
||||||
return { text: '未知', color: 'gray' };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.order-detail {
|
|
||||||
padding: 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.amount-text {
|
|
||||||
color: #165dff;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-descriptions-item-label) {
|
|
||||||
font-weight: 600;
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -27,11 +27,11 @@
|
|||||||
placeholder="请选择状态"
|
placeholder="请选择状态"
|
||||||
allow-clear
|
allow-clear
|
||||||
>
|
>
|
||||||
<a-option :value="0">失效</a-option>
|
<a-option :value="0">待登录</a-option>
|
||||||
<a-option :value="1">正常</a-option>
|
<a-option :value="1">发送验证码</a-option>
|
||||||
<a-option :value="2">充值过快</a-option>
|
<a-option :value="2">在线</a-option>
|
||||||
<a-option :value="3">账号受限</a-option>
|
<a-option :value="3">已暂停</a-option>
|
||||||
<a-option :value="4">异常</a-option>
|
<a-option :value="4">已失效</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -88,8 +88,8 @@
|
|||||||
>
|
>
|
||||||
<!-- 状态列模板 -->
|
<!-- 状态列模板 -->
|
||||||
<template #status="{ record }">
|
<template #status="{ record }">
|
||||||
<a-tag size="small" :color="statusMapper(record.status).color">
|
<a-tag size="small" :color="statusColorMapper(record.status)">
|
||||||
{{ statusMapper(record.status).text }}
|
{{ record.statusText || statusMapper(record.status).text }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -110,13 +110,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-tooltip content="关联订单">
|
|
||||||
<a-button size="small" @click="showAccountOrders(record)">
|
|
||||||
<template #icon>
|
|
||||||
<icon-order />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
@@ -133,33 +126,22 @@
|
|||||||
v-model:visible="state.historyModalVisible"
|
v-model:visible="state.historyModalVisible"
|
||||||
:account-id="state.accountId"
|
:account-id="state.accountId"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 账号关联订单弹窗 -->
|
|
||||||
<account-orders
|
|
||||||
v-model:visible="state.ordersModalVisible"
|
|
||||||
:account-id="state.accountId"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, reactive, ref, watchEffect } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { Notification, TableColumnData } from '@arco-design/web-vue';
|
import { Notification, TableColumnData } from '@arco-design/web-vue';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import { Pagination } from '@/types/global';
|
import { Pagination } from '@/types/global';
|
||||||
import { checkTokenFromIframe, checkTokenFromLogin } from '@/utils/auth';
|
|
||||||
import { jdV2AccountClient } from '@/api/index.ts';
|
import { jdV2AccountClient } from '@/api/index.ts';
|
||||||
import type {
|
import type { KamiApiCamelOilV1AccountListItem } from '@/api/generated/models/index.ts';
|
||||||
KamiApiCamelOilV1AccountListItem,
|
|
||||||
KamiApiCamelOilV1AccountListItemStatusEnum
|
|
||||||
} from '@/api/generated/models/index.ts';
|
|
||||||
import type {
|
import type {
|
||||||
ApiJdV2AccountListGetPageSizeEnum,
|
ApiJdV2AccountListGetPageSizeEnum,
|
||||||
ApiJdV2AccountListGetStatusEnum
|
ApiJdV2AccountListGetStatusEnum
|
||||||
} from '@/api/generated/apis/jdv2-account-api';
|
} from '@/api/generated/apis/jdv2-account-api';
|
||||||
import AccountDetail from './components/detail.vue';
|
import AccountDetail from './components/detail.vue';
|
||||||
import AccountHistory from './components/history.vue';
|
import AccountHistory from './components/history.vue';
|
||||||
import AccountOrders from './components/account-orders.vue';
|
|
||||||
|
|
||||||
// 基础分页配置
|
// 基础分页配置
|
||||||
const basePagination: Pagination = {
|
const basePagination: Pagination = {
|
||||||
@@ -182,13 +164,6 @@ const columns: TableColumnData[] = [
|
|||||||
return rowIndex + 1 + (pagination.current - 1) * pagination.pageSize;
|
return rowIndex + 1 + (pagination.current - 1) * pagination.pageSize;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '账号ID',
|
|
||||||
dataIndex: 'accountId',
|
|
||||||
width: 120,
|
|
||||||
ellipsis: true,
|
|
||||||
tooltip: true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '账号名称',
|
title: '账号名称',
|
||||||
dataIndex: 'accountName',
|
dataIndex: 'accountName',
|
||||||
@@ -201,21 +176,6 @@ const columns: TableColumnData[] = [
|
|||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: true
|
tooltip: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '当日订单数',
|
|
||||||
dataIndex: 'dailyOrderCount',
|
|
||||||
width: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '累计订单数',
|
|
||||||
dataIndex: 'totalOrderCount',
|
|
||||||
width: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '剩余可下单',
|
|
||||||
dataIndex: 'remainingOrders',
|
|
||||||
width: 100
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '最后使用时间',
|
title: '最后使用时间',
|
||||||
dataIndex: 'lastUsedAt',
|
dataIndex: 'lastUsedAt',
|
||||||
@@ -229,6 +189,20 @@ const columns: TableColumnData[] = [
|
|||||||
slotName: 'status',
|
slotName: 'status',
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '失败原因',
|
||||||
|
dataIndex: 'failureReason',
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
dataIndex: 'remark',
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
dataIndex: 'createdAt',
|
dataIndex: 'createdAt',
|
||||||
@@ -254,32 +228,12 @@ const generateSearchFormModel = () => ({
|
|||||||
status: undefined as ApiJdV2AccountListGetStatusEnum | undefined
|
status: undefined as ApiJdV2AccountListGetStatusEnum | undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
// 账号数据模型
|
|
||||||
const generateAccountModel = () => ({
|
|
||||||
accountId: '',
|
|
||||||
accountName: '',
|
|
||||||
phone: '',
|
|
||||||
status: undefined as KamiApiCamelOilV1AccountListItemStatusEnum | undefined,
|
|
||||||
statusText: '',
|
|
||||||
dailyOrderCount: 0,
|
|
||||||
totalOrderCount: 0,
|
|
||||||
remainingOrders: 0,
|
|
||||||
lastUsedAt: '',
|
|
||||||
lastLoginAt: '',
|
|
||||||
tokenExpireAt: '',
|
|
||||||
failureReason: '',
|
|
||||||
remark: '',
|
|
||||||
createdAt: '',
|
|
||||||
updatedAt: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
const formModel = ref(generateSearchFormModel());
|
const formModel = ref(generateSearchFormModel());
|
||||||
|
|
||||||
// 弹窗状态管理
|
// 弹窗状态管理
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
detailModalVisible: false,
|
detailModalVisible: false,
|
||||||
historyModalVisible: false,
|
historyModalVisible: false,
|
||||||
ordersModalVisible: false,
|
|
||||||
accountId: '',
|
accountId: '',
|
||||||
account: null as KamiApiCamelOilV1AccountListItem | null
|
account: null as KamiApiCamelOilV1AccountListItem | null
|
||||||
});
|
});
|
||||||
@@ -385,33 +339,54 @@ const showHistoryModal = (record: KamiApiCamelOilV1AccountListItem) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示账号关联订单弹窗
|
* 状态颜色映射器
|
||||||
* @param record 账号记录
|
* 基于后端Go定义的状态:
|
||||||
|
* - 0: 待登录
|
||||||
|
* - 1: 发送验证码
|
||||||
|
* - 2: 在线
|
||||||
|
* - 3: 已暂停
|
||||||
|
* - 4: 已失效
|
||||||
|
* 使用 Arco Design 标准颜色以兼容主题切换
|
||||||
|
* @param status 状态值
|
||||||
|
* @returns 状态颜色
|
||||||
*/
|
*/
|
||||||
const showAccountOrders = (record: KamiApiCamelOilV1AccountListItem) => {
|
const statusColorMapper = (status: number): string => {
|
||||||
state.accountId = record.accountId?.toString() || '';
|
switch (status) {
|
||||||
state.ordersModalVisible = true;
|
case 0:
|
||||||
|
return 'orange'; // 待登录 - 橙色(等待状态)
|
||||||
|
case 1:
|
||||||
|
return 'blue'; // 发送验证码 - 蓝色(进行中状态)
|
||||||
|
case 2:
|
||||||
|
return 'green'; // 在线 - 绿色(正常状态)
|
||||||
|
case 3:
|
||||||
|
return 'orange'; // 已暂停 - 橙色(警告状态)
|
||||||
|
case 4:
|
||||||
|
return 'red'; // 已失效 - 红色(危险状态)
|
||||||
|
default:
|
||||||
|
return 'gray'; // 未知状态 - 灰色(中性状态)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态映射器
|
* 状态文本映射器(作为备用)
|
||||||
|
* 基于后端Go定义的状态
|
||||||
* @param status 状态值
|
* @param status 状态值
|
||||||
* @returns 状态文本和颜色
|
* @returns 状态文本
|
||||||
*/
|
*/
|
||||||
const statusMapper = (status: number): { text: string; color: string } => {
|
const statusMapper = (status: number): { text: string } => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
return { text: '失效', color: 'red' };
|
return { text: '待登录' }; // 需要登录验证
|
||||||
case 1:
|
case 1:
|
||||||
return { text: '正常', color: 'green' };
|
return { text: '发送验证码' }; // 正在发送验证码
|
||||||
case 2:
|
case 2:
|
||||||
return { text: '充值过快', color: 'orange' };
|
return { text: '在线' }; // 账户在线,可用
|
||||||
case 3:
|
case 3:
|
||||||
return { text: '账号受限', color: 'red' };
|
return { text: '已暂停' }; // 账户被暂停使用
|
||||||
case 4:
|
case 4:
|
||||||
return { text: '异常', color: 'gray' };
|
return { text: '已失效' }; // 账户已失效
|
||||||
default:
|
default:
|
||||||
return { text: '未知', color: 'gray' };
|
return { text: '未知状态' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -51,14 +51,6 @@
|
|||||||
{{ payStatusMapper(order.payStatus).text }}
|
{{ payStatusMapper(order.payStatus).text }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="回调状态">
|
|
||||||
<a-tag :color="order.callbackStatus === 1 ? 'green' : 'red'">
|
|
||||||
{{ order.callbackStatus === 1 ? '成功' : '失败' }}
|
|
||||||
</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="回调次数">
|
|
||||||
{{ order.callbackCount || 0 }} 次
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
@@ -68,42 +60,14 @@
|
|||||||
<a-descriptions-item label="创建时间">
|
<a-descriptions-item label="创建时间">
|
||||||
{{ order.createdAt }}
|
{{ order.createdAt }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="支付时间">
|
<a-descriptions-item label="支付完成时间">
|
||||||
{{ order.payTime || '-' }}
|
{{ order.paidAt || '-' }}
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="完成时间">
|
|
||||||
{{ order.completeTime || '-' }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="最后回调时间">
|
|
||||||
{{ order.lastCallbackTime || '-' }}
|
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="更新时间" :span="2">
|
<a-descriptions-item label="更新时间" :span="2">
|
||||||
{{ order.updatedAt }}
|
{{ order.updatedAt }}
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<!-- 其他信息 -->
|
|
||||||
<a-card title="其他信息" class="detail-card">
|
|
||||||
<a-descriptions :column="1" bordered>
|
|
||||||
<a-descriptions-item label="回调地址">
|
|
||||||
<code class="callback-url">{{ order.callbackUrl || '-' }}</code>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="请求参数">
|
|
||||||
<pre class="request-params">{{
|
|
||||||
formatJson(order.requestParams) || '-'
|
|
||||||
}}</pre>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="响应参数">
|
|
||||||
<pre class="response-params">{{
|
|
||||||
formatJson(order.responseParams) || '-'
|
|
||||||
}}</pre>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="备注">
|
|
||||||
{{ order.remark || '-' }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
@@ -137,56 +101,43 @@ const modalVisible = computed({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单状态映射器
|
* 订单状态映射器
|
||||||
|
* 基于后端Go定义的CamelOilOrderStatus
|
||||||
* @param status 状态值
|
* @param status 状态值
|
||||||
* @returns 状态文本和颜色
|
* @returns 状态文本和颜色
|
||||||
*/
|
*/
|
||||||
const statusMapper = (status: number): { text: string; color: string } => {
|
const statusMapper = (status: number): { text: string; color: string } => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
return { text: '待处理', color: 'orange' };
|
return { text: '待处理', color: 'orange' }; // CamelOilOrderStatusPending
|
||||||
case 1:
|
case 1:
|
||||||
return { text: '成功', color: 'green' };
|
return { text: '处理中', color: 'blue' }; // CamelOilOrderStatusProcessing
|
||||||
case 2:
|
case 2:
|
||||||
return { text: '失败', color: 'red' };
|
return { text: '已完成', color: 'green' }; // CamelOilOrderStatusCompleted
|
||||||
case 3:
|
case 3:
|
||||||
return { text: '已取消', color: 'gray' };
|
return { text: '已失败', color: 'red' }; // CamelOilOrderStatusFailed
|
||||||
default:
|
default:
|
||||||
return { text: '未知', color: 'gray' };
|
return { text: '未知状态', color: 'gray' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付状态映射器
|
* 支付状态映射器
|
||||||
|
* 基于后端Go定义的CamelOilPayStatus
|
||||||
* @param status 支付状态
|
* @param status 支付状态
|
||||||
* @returns 支付状态文本和颜色
|
* @returns 支付状态文本和颜色
|
||||||
*/
|
*/
|
||||||
const payStatusMapper = (status: number): { text: string; color: string } => {
|
const payStatusMapper = (status: number): { text: string; color: string } => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
return { text: '未支付', color: 'orange' };
|
return { text: '未支付', color: 'orange' }; // CamelOilPaymentStatusUnpaid
|
||||||
case 1:
|
case 1:
|
||||||
return { text: '已支付', color: 'green' };
|
return { text: '已支付', color: 'green' }; // CamelOilPaymentStatusPaid
|
||||||
case 2:
|
case 2:
|
||||||
return { text: '支付失败', color: 'red' };
|
return { text: '已退款', color: 'blue' }; // CamelOilPaymentStatusRefunded
|
||||||
|
case 3:
|
||||||
|
return { text: '已超时', color: 'red' }; // CamelOilPaymentStatusTimeout
|
||||||
default:
|
default:
|
||||||
return { text: '未知', color: 'gray' };
|
return { text: '未知状态', color: 'gray' };
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化JSON字符串
|
|
||||||
* @param json JSON对象或字符串
|
|
||||||
* @returns 格式化后的字符串
|
|
||||||
*/
|
|
||||||
const formatJson = (json: any): string => {
|
|
||||||
if (!json) return '';
|
|
||||||
try {
|
|
||||||
if (typeof json === 'string') {
|
|
||||||
return JSON.stringify(JSON.parse(json), null, 2);
|
|
||||||
}
|
|
||||||
return JSON.stringify(json, null, 2);
|
|
||||||
} catch {
|
|
||||||
return String(json);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -205,48 +156,41 @@ const formatJson = (json: any): string => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.amount-text {
|
.amount-text {
|
||||||
color: #165dff;
|
color: rgb(var(--primary-6));
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actual-amount-text {
|
.actual-amount-text {
|
||||||
color: #00b42a;
|
color: rgb(var(--success-6));
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.callback-url {
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
padding: 4px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.request-params,
|
|
||||||
.response-params {
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
padding: 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.4;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-all;
|
|
||||||
max-height: 200px;
|
|
||||||
overflow-y: auto;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.arco-descriptions-item-label) {
|
:deep(.arco-descriptions-item-label) {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
background-color: #f7f8fa;
|
background-color: var(--color-fill-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.arco-modal-body) {
|
:deep(.arco-modal-body) {
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
/* 确保滚动条样式跟随主题 */
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--color-border-3) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar) {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-thumb) {
|
||||||
|
background-color: var(--color-border-3);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-track) {
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -21,21 +21,13 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item field="merchantOrderNo" label="商户订单号">
|
<a-form-item field="merchantOrderId" label="商户订单号">
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formModel.merchantOrderNo"
|
v-model="formModel.merchantOrderId"
|
||||||
placeholder="请输入商户订单号"
|
placeholder="请输入商户订单号"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
|
||||||
<a-form-item field="accountPhone" label="充值手机">
|
|
||||||
<a-input
|
|
||||||
v-model="formModel.accountPhone"
|
|
||||||
placeholder="请输入充值手机号"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item field="status" label="订单状态">
|
<a-form-item field="status" label="订单状态">
|
||||||
<a-select
|
<a-select
|
||||||
@@ -44,9 +36,9 @@
|
|||||||
allow-clear
|
allow-clear
|
||||||
>
|
>
|
||||||
<a-option :value="0">待处理</a-option>
|
<a-option :value="0">待处理</a-option>
|
||||||
<a-option :value="1">成功</a-option>
|
<a-option :value="1">处理中</a-option>
|
||||||
<a-option :value="2">失败</a-option>
|
<a-option :value="2">已完成</a-option>
|
||||||
<a-option :value="3">已取消</a-option>
|
<a-option :value="3">已失败</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
@@ -140,8 +132,8 @@
|
|||||||
|
|
||||||
<!-- 回调状态模板 -->
|
<!-- 回调状态模板 -->
|
||||||
<template #callbackStatus="{ record }">
|
<template #callbackStatus="{ record }">
|
||||||
<a-tag :color="record.callbackStatus === 1 ? 'green' : 'red'">
|
<a-tag :color="callbackStatusMapper(record.notifyStatus).color">
|
||||||
{{ record.callbackStatus === 1 ? '成功' : '失败' }}
|
{{ callbackStatusMapper(record.notifyStatus).text }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -198,6 +190,11 @@ import type {
|
|||||||
ApiJdV2OrderListGetStatusEnum,
|
ApiJdV2OrderListGetStatusEnum,
|
||||||
ApiJdV2OrderListGetPayStatusEnum
|
ApiJdV2OrderListGetPayStatusEnum
|
||||||
} from '@/api/generated/apis/jdv2-order-api';
|
} from '@/api/generated/apis/jdv2-order-api';
|
||||||
|
import type {
|
||||||
|
KamiApiCamelOilV1OrderListItemStatusEnum,
|
||||||
|
KamiApiCamelOilV1OrderListItemPayStatusEnum,
|
||||||
|
KamiApiCamelOilV1OrderListItemNotifyStatusEnum
|
||||||
|
} from '@/api/generated/models/index.ts';
|
||||||
import OrderDetailModal from './components/order-detail-modal.vue';
|
import OrderDetailModal from './components/order-detail-modal.vue';
|
||||||
import OrderHistoryModal from './components/order-history-modal.vue';
|
import OrderHistoryModal from './components/order-history-modal.vue';
|
||||||
|
|
||||||
@@ -280,14 +277,9 @@ const columns: TableColumnData[] = [
|
|||||||
tooltip: true
|
tooltip: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '账号ID',
|
title: '账号名称',
|
||||||
dataIndex: 'accountId',
|
dataIndex: 'accountName',
|
||||||
width: 120
|
width: 150
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '充值手机',
|
|
||||||
dataIndex: 'accountPhone',
|
|
||||||
width: 130
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '订单金额',
|
title: '订单金额',
|
||||||
@@ -309,18 +301,27 @@ const columns: TableColumnData[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '回调状态',
|
title: '回调状态',
|
||||||
dataIndex: 'callbackStatus',
|
dataIndex: 'notifyStatus',
|
||||||
slotName: 'callbackStatus',
|
slotName: 'callbackStatus',
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '创建时间',
|
title: '支付完成时间',
|
||||||
dataIndex: 'createdAt',
|
dataIndex: 'paidAt',
|
||||||
width: 180
|
width: 180,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '更新时间',
|
title: '失败原因',
|
||||||
dataIndex: 'updatedAt',
|
dataIndex: 'failureReason',
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createdAt',
|
||||||
width: 180
|
width: 180
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -335,8 +336,7 @@ const columns: TableColumnData[] = [
|
|||||||
// 表单模型
|
// 表单模型
|
||||||
const generateFormModel = () => ({
|
const generateFormModel = () => ({
|
||||||
orderNo: '',
|
orderNo: '',
|
||||||
merchantOrderNo: '',
|
merchantOrderId: '',
|
||||||
accountPhone: '',
|
|
||||||
status: undefined as ApiJdV2OrderListGetStatusEnum | undefined,
|
status: undefined as ApiJdV2OrderListGetStatusEnum | undefined,
|
||||||
payStatus: undefined as ApiJdV2OrderListGetPayStatusEnum | undefined,
|
payStatus: undefined as ApiJdV2OrderListGetPayStatusEnum | undefined,
|
||||||
dateRange: [] as Date[]
|
dateRange: [] as Date[]
|
||||||
@@ -456,39 +456,64 @@ const showOrderHistory = (record: KamiApiCamelOilV1OrderListItem) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单状态映射器
|
* 订单状态映射器
|
||||||
|
* 基于后端Go定义的CamelOilOrderStatus
|
||||||
* @param status 状态值
|
* @param status 状态值
|
||||||
* @returns 状态文本和颜色
|
* @returns 状态文本和颜色
|
||||||
*/
|
*/
|
||||||
const statusMapper = (status: number): { text: string; color: string } => {
|
const statusMapper = (status: number): { text: string; color: string } => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
return { text: '待处理', color: 'orange' };
|
return { text: '待处理', color: 'orange' }; // CamelOilOrderStatusPending
|
||||||
case 1:
|
case 1:
|
||||||
return { text: '成功', color: 'green' };
|
return { text: '处理中', color: 'blue' }; // CamelOilOrderStatusProcessing
|
||||||
case 2:
|
case 2:
|
||||||
return { text: '失败', color: 'red' };
|
return { text: '已完成', color: 'green' }; // CamelOilOrderStatusCompleted
|
||||||
case 3:
|
case 3:
|
||||||
return { text: '已取消', color: 'gray' };
|
return { text: '已失败', color: 'red' }; // CamelOilOrderStatusFailed
|
||||||
default:
|
default:
|
||||||
return { text: '未知', color: 'gray' };
|
return { text: '未知状态', color: 'gray' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付状态映射器
|
* 支付状态映射器
|
||||||
|
* 基于后端Go定义的CamelOilPayStatus
|
||||||
* @param status 支付状态
|
* @param status 支付状态
|
||||||
* @returns 支付状态文本和颜色
|
* @returns 支付状态文本和颜色
|
||||||
*/
|
*/
|
||||||
const payStatusMapper = (status: number): { text: string; color: string } => {
|
const payStatusMapper = (status: number): { text: string; color: string } => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0:
|
case 0:
|
||||||
return { text: '未支付', color: 'orange' };
|
return { text: '未支付', color: 'orange' }; // CamelOilPaymentStatusUnpaid
|
||||||
case 1:
|
case 1:
|
||||||
return { text: '已支付', color: 'green' };
|
return { text: '已支付', color: 'green' }; // CamelOilPaymentStatusPaid
|
||||||
case 2:
|
case 2:
|
||||||
return { text: '支付失败', color: 'red' };
|
return { text: '已退款', color: 'blue' }; // CamelOilPaymentStatusRefunded
|
||||||
|
case 3:
|
||||||
|
return { text: '已超时', color: 'red' }; // CamelOilPaymentStatusTimeout
|
||||||
default:
|
default:
|
||||||
return { text: '未知', color: 'gray' };
|
return { text: '未知状态', color: 'gray' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调状态映射器
|
||||||
|
* 基于后端Go定义的CamelOilNotifyStatus
|
||||||
|
* @param status 回调状态
|
||||||
|
* @returns 回调状态文本和颜色
|
||||||
|
*/
|
||||||
|
const callbackStatusMapper = (
|
||||||
|
status: number
|
||||||
|
): { text: string; color: string } => {
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
return { text: '未回调', color: 'orange' }; // CamelOilCallbackStatusPending
|
||||||
|
case 1:
|
||||||
|
return { text: '回调成功', color: 'green' }; // CamelOilCallbackStatusSuccess
|
||||||
|
case 2:
|
||||||
|
return { text: '回调失败', color: 'red' }; // CamelOilCallbackStatusFailed
|
||||||
|
default:
|
||||||
|
return { text: '未知状态', color: 'gray' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -516,7 +541,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.amount-text {
|
.amount-text {
|
||||||
color: #165dff;
|
color: rgb(var(--primary-6));
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -31,6 +31,13 @@
|
|||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item field="phone" label="绑定手机号" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formModel.phone"
|
||||||
|
placeholder="请输入绑定的手机号"
|
||||||
|
:max-length="11"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item field="remark" label="备注">
|
<a-form-item field="remark" label="备注">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
v-model="formModel.remark"
|
v-model="formModel.remark"
|
||||||
@@ -74,6 +81,7 @@ const generateFormModel = () => {
|
|||||||
return {
|
return {
|
||||||
tokenName: '',
|
tokenName: '',
|
||||||
tokenValue: '',
|
tokenValue: '',
|
||||||
|
phone: '',
|
||||||
remark: ''
|
remark: ''
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -89,6 +97,10 @@ const rules = {
|
|||||||
{ required: true, message: '请输入Token值' },
|
{ required: true, message: '请输入Token值' },
|
||||||
{ min: 1, max: 1000, message: 'Token值长度为1-1000个字符' }
|
{ min: 1, max: 1000, message: 'Token值长度为1-1000个字符' }
|
||||||
],
|
],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: '请输入绑定手机号' },
|
||||||
|
{ match: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }
|
||||||
|
],
|
||||||
remark: [{ max: 500, message: '备注长度不能超过500个字符' }]
|
remark: [{ max: 500, message: '备注长度不能超过500个字符' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -144,8 +156,26 @@ const handleBeforeOk = async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* 使用 Arco Design 的原生样式,确保主题兼容性 */
|
||||||
:deep(.arco-modal-body) {
|
:deep(.arco-modal-body) {
|
||||||
max-height: 60vh;
|
max-height: 60vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
/* 确保滚动条样式跟随主题 */
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--color-border-3) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar) {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-thumb) {
|
||||||
|
background-color: var(--color-border-3);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-track) {
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -211,8 +211,26 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* 使用 Arco Design 的原生样式,确保主题兼容性 */
|
||||||
:deep(.arco-modal-body) {
|
:deep(.arco-modal-body) {
|
||||||
max-height: 70vh;
|
max-height: 70vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
/* 确保滚动条样式跟随主题 */
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--color-border-3) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar) {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-thumb) {
|
||||||
|
background-color: var(--color-border-3);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-modal-body::-webkit-scrollbar-track) {
|
||||||
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -178,12 +178,31 @@ const columns: TableColumnData[] = [
|
|||||||
width: 150
|
width: 150
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Token',
|
title: 'Token值',
|
||||||
dataIndex: 'token',
|
dataIndex: 'tokenValue',
|
||||||
width: 300,
|
width: 300,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
tooltip: true
|
tooltip: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '绑定手机号',
|
||||||
|
dataIndex: 'phone',
|
||||||
|
width: 130,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '绑定数量',
|
||||||
|
dataIndex: 'bindCount',
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '最后使用时间',
|
||||||
|
dataIndex: 'lastUsedAt',
|
||||||
|
width: 180,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
@@ -191,20 +210,17 @@ const columns: TableColumnData[] = [
|
|||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '创建人',
|
title: '备注',
|
||||||
dataIndex: 'createdBy',
|
dataIndex: 'remark',
|
||||||
width: 120
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
|
tooltip: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
dataIndex: 'createdAt',
|
dataIndex: 'createdAt',
|
||||||
width: 180
|
width: 180
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '更新时间',
|
|
||||||
dataIndex: 'updatedAt',
|
|
||||||
width: 180
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'operations',
|
dataIndex: 'operations',
|
||||||
@@ -342,4 +358,8 @@ onMounted(() => {
|
|||||||
.container {
|
.container {
|
||||||
padding: 0 20px 20px;
|
padding: 0 20px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.general-card {
|
||||||
|
min-height: calc(100vh - 170px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user