refactor(prefetch): 优化预拉取订单日志展示和设置逻辑

- 移除响应数据详情弹窗,改为日志文本方式展示全部响应数据
- 新增复制日志和清空日志功能及按钮
- 移除日志分页,直接显示全部日志数据
- 设置界面新增豪猪平台用户名和密码字段,支持条件校验
- 优化设置表单逻辑,加载、提交和重置均由组件内部管理
- 删除多余API响应字段如statusText等,简化数据结构
- 统一预拉取订单列表和日志的代码风格及样式调整
- 增加日志复制和操作的用户提示信息
This commit is contained in:
danial
2025-12-06 00:13:40 +08:00
parent 6d25b11074
commit 00c06d461d
21 changed files with 313 additions and 460 deletions

View File

@@ -8,7 +8,6 @@
| **accountName** | **string** | 账号名称 | [optional] [default to undefined] | | **accountName** | **string** | 账号名称 | [optional] [default to undefined] |
| **phone** | **string** | 手机号(脱敏) | [optional] [default to undefined] | | **phone** | **string** | 手机号(脱敏) | [optional] [default to undefined] |
| **status** | **number** | 状态 | [optional] [default to undefined] | | **status** | **number** | 状态 | [optional] [default to undefined] |
| **statusText** | **string** | 状态文本 | [optional] [default to undefined] |
| **dailyOrderCount** | **number** | 当日下单数 | [optional] [default to undefined] | | **dailyOrderCount** | **number** | 当日下单数 | [optional] [default to undefined] |
| **dailyOrderDate** | **string** | 当日日期 | [optional] [default to undefined] | | **dailyOrderDate** | **string** | 当日日期 | [optional] [default to undefined] |
| **totalOrderCount** | **number** | 累计下单数 | [optional] [default to undefined] | | **totalOrderCount** | **number** | 累计下单数 | [optional] [default to undefined] |
@@ -31,7 +30,6 @@ const instance: KamiApiCamelOilV1AccountListItem = {
accountName, accountName,
phone, phone,
status, status,
statusText,
dailyOrderCount, dailyOrderCount,
dailyOrderDate, dailyOrderDate,
totalOrderCount, totalOrderCount,

View File

@@ -8,7 +8,6 @@
| **accountName** | **string** | 账号名称 | [optional] [default to undefined] | | **accountName** | **string** | 账号名称 | [optional] [default to undefined] |
| **phone** | **string** | 手机号(脱敦) | [optional] [default to undefined] | | **phone** | **string** | 手机号(脱敦) | [optional] [default to undefined] |
| **status** | **number** | 状态 | [optional] [default to undefined] | | **status** | **number** | 状态 | [optional] [default to undefined] |
| **statusText** | **string** | 状态文本 | [optional] [default to undefined] |
## Example ## Example
@@ -19,8 +18,7 @@ const instance: KamiApiCamelOilV1AccountOrderListResAccountInfo = {
accountId, accountId,
accountName, accountName,
phone, phone,
status, status
statusText
}; };
``` ```

View File

@@ -8,7 +8,6 @@
| **accountName** | **string** | 账号名称 | [optional] [default to undefined] | | **accountName** | **string** | 账号名称 | [optional] [default to undefined] |
| **phone** | **string** | 手机号(脱敏) | [optional] [default to undefined] | | **phone** | **string** | 手机号(脱敏) | [optional] [default to undefined] |
| **status** | **number** | 状态 | [optional] [default to undefined] | | **status** | **number** | 状态 | [optional] [default to undefined] |
| **statusText** | **string** | 状态文本 | [optional] [default to undefined] |
| **lastUsedAt** | **string** | 最后使用时间 | [optional] [default to undefined] | | **lastUsedAt** | **string** | 最后使用时间 | [optional] [default to undefined] |
| **lastLoginAt** | **string** | 最后登录时间 | [optional] [default to undefined] | | **lastLoginAt** | **string** | 最后登录时间 | [optional] [default to undefined] |
| **tokenExpireAt** | **string** | Token过期时间 | [optional] [default to undefined] | | **tokenExpireAt** | **string** | Token过期时间 | [optional] [default to undefined] |
@@ -23,7 +22,6 @@ const instance: KamiApiCamelOilV1AccountStatisticsResAccountInfo = {
accountName, accountName,
phone, phone,
status, status,
statusText,
lastUsedAt, lastUsedAt,
lastLoginAt, lastLoginAt,
tokenExpireAt tokenExpireAt

View File

@@ -5,6 +5,8 @@
| Name | Type | Description | Notes | | Name | Type | Description | Notes |
| ------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------ | --------------------------------- | | ------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------ | --------------------------------- |
| **useHaozhuPlatform** | **boolean** | 是否从豪猪平台获取手机号登录 | [optional] [default to undefined] | | **useHaozhuPlatform** | **boolean** | 是否从豪猪平台获取手机号登录 | [optional] [default to undefined] |
| **haozhuUsername** | **string** | 豪猪平台用户名 | [optional] [default to undefined] |
| **haozhuPassword** | **string** | 豪猪平台密码 | [optional] [default to undefined] |
| **loginAccountCount** | **number** | 要登录的手机号数量 | [optional] [default to undefined] | | **loginAccountCount** | **number** | 要登录的手机号数量 | [optional] [default to undefined] |
| **prefetchConcurrencyAccounts** | **number** | 提前拉单并发的账号数量 | [optional] [default to undefined] | | **prefetchConcurrencyAccounts** | **number** | 提前拉单并发的账号数量 | [optional] [default to undefined] |
| **singleAccountConcurrency** | **number** | 单个账号的并发数量 | [optional] [default to undefined] | | **singleAccountConcurrency** | **number** | 单个账号的并发数量 | [optional] [default to undefined] |
@@ -17,6 +19,8 @@ import { KamiApiCamelOilV1GetSettingsRes } from './api';
const instance: KamiApiCamelOilV1GetSettingsRes = { const instance: KamiApiCamelOilV1GetSettingsRes = {
useHaozhuPlatform, useHaozhuPlatform,
haozhuUsername,
haozhuPassword,
loginAccountCount, loginAccountCount,
prefetchConcurrencyAccounts, prefetchConcurrencyAccounts,
singleAccountConcurrency, singleAccountConcurrency,

View File

@@ -8,7 +8,6 @@
| **accountName** | **string** | 账号名称 | [optional] [default to undefined] | | **accountName** | **string** | 账号名称 | [optional] [default to undefined] |
| **phone** | **string** | 手机号(脱敦) | [optional] [default to undefined] | | **phone** | **string** | 手机号(脱敦) | [optional] [default to undefined] |
| **status** | **number** | 状态 | [optional] [default to undefined] | | **status** | **number** | 状态 | [optional] [default to undefined] |
| **statusText** | **string** | 状态文本 | [optional] [default to undefined] |
| **lastUsedAt** | **string** | 最后使用时间 | [optional] [default to undefined] | | **lastUsedAt** | **string** | 最后使用时间 | [optional] [default to undefined] |
## Example ## Example
@@ -21,7 +20,6 @@ const instance: KamiApiCamelOilV1OrderDetailResAccountInfo = {
accountName, accountName,
phone, phone,
status, status,
statusText,
lastUsedAt lastUsedAt
}; };
``` ```

View File

@@ -2,27 +2,24 @@
## Properties ## Properties
| Name | Type | Description | Notes | | Name | Type | Description | Notes |
| -------------------- | ---------- | ---------------- | --------------------------------- | | ------------------- | ---------- | ---------------- | --------------------------------- |
| **orderNo** | **string** | 系统订单号 | [optional] [default to undefined] | | **orderNo** | **string** | 系统订单号 | [optional] [default to undefined] |
| **merchantOrderId** | **string** | 商户订单号 | [optional] [default to undefined] | | **merchantOrderId** | **string** | 商户订单号 | [optional] [default to undefined] |
| **accountId** | **number** | 账号ID | [optional] [default to undefined] | | **accountId** | **number** | 账号ID | [optional] [default to undefined] |
| **accountName** | **string** | 账号名称 | [optional] [default to undefined] | | **accountName** | **string** | 账号名称 | [optional] [default to undefined] |
| **amount** | **number** | 订单金额 | [optional] [default to undefined] | | **amount** | **number** | 订单金额 | [optional] [default to undefined] |
| **alipayUrl** | **string** | 支付宝支付链接 | [optional] [default to undefined] | | **alipayUrl** | **string** | 支付宝支付链接 | [optional] [default to undefined] |
| **status** | **number** | 订单状态 | [optional] [default to undefined] | | **status** | **number** | 订单状态 | [optional] [default to undefined] |
| **statusText** | **string** | 订单状态文本 | [optional] [default to undefined] | | **payStatus** | **number** | 支付状态 | [optional] [default to undefined] |
| **payStatus** | **number** | 支付状态 | [optional] [default to undefined] | | **notifyStatus** | **number** | 回调状态 | [optional] [default to undefined] |
| **payStatusText** | **string** | 支付状态文本 | [optional] [default to undefined] | | **notifyCount** | **number** | 回调次数 | [optional] [default to undefined] |
| **notifyStatus** | **number** | 回调状态 | [optional] [default to undefined] | | **paidAt** | **string** | 支付完成时间 | [optional] [default to undefined] |
| **notifyStatusText** | **string** | 回调状态文本 | [optional] [default to undefined] | | **lastCheckAt** | **string** | 最后检测支付时间 | [optional] [default to undefined] |
| **notifyCount** | **number** | 回调次数 | [optional] [default to undefined] | | **attach** | **string** | 附加信息 | [optional] [default to undefined] |
| **paidAt** | **string** | 支付完成时间 | [optional] [default to undefined] | | **failureReason** | **string** | 失败原因 | [optional] [default to undefined] |
| **lastCheckAt** | **string** | 最后检测支付时间 | [optional] [default to undefined] | | **createdAt** | **string** | 创建时间 | [optional] [default to undefined] |
| **attach** | **string** | 附加信息 | [optional] [default to undefined] | | **updatedAt** | **string** | 更新时间 | [optional] [default to undefined] |
| **failureReason** | **string** | 失败原因 | [optional] [default to undefined] |
| **createdAt** | **string** | 创建时间 | [optional] [default to undefined] |
| **updatedAt** | **string** | 更新时间 | [optional] [default to undefined] |
## Example ## Example
@@ -37,11 +34,8 @@ const instance: KamiApiCamelOilV1OrderDetailResOrderInfo = {
amount, amount,
alipayUrl, alipayUrl,
status, status,
statusText,
payStatus, payStatus,
payStatusText,
notifyStatus, notifyStatus,
notifyStatusText,
notifyCount, notifyCount,
paidAt, paidAt,
lastCheckAt, lastCheckAt,

View File

@@ -2,26 +2,23 @@
## Properties ## Properties
| Name | Type | Description | Notes | | Name | Type | Description | Notes |
| -------------------- | ---------- | ---------------- | --------------------------------- | | ------------------- | ---------- | ---------------- | --------------------------------- |
| **orderNo** | **string** | 系统订单号 | [optional] [default to undefined] | | **orderNo** | **string** | 系统订单号 | [optional] [default to undefined] |
| **merchantOrderId** | **string** | 商户订单号 | [optional] [default to undefined] | | **merchantOrderId** | **string** | 商户订单号 | [optional] [default to undefined] |
| **accountId** | **number** | 账号ID | [optional] [default to undefined] | | **accountId** | **number** | 账号ID | [optional] [default to undefined] |
| **accountName** | **string** | 账号名称 | [optional] [default to undefined] | | **accountName** | **string** | 账号名称 | [optional] [default to undefined] |
| **amount** | **number** | 订单金额 | [optional] [default to undefined] | | **amount** | **number** | 订单金额 | [optional] [default to undefined] |
| **alipayUrl** | **string** | 支付宝支付链接 | [optional] [default to undefined] | | **alipayUrl** | **string** | 支付宝支付链接 | [optional] [default to undefined] |
| **status** | **number** | 订单状态 | [optional] [default to undefined] | | **status** | **number** | 订单状态 | [optional] [default to undefined] |
| **statusText** | **string** | 订单状态文本 | [optional] [default to undefined] | | **payStatus** | **number** | 支付状态 | [optional] [default to undefined] |
| **payStatus** | **number** | 支付状态 | [optional] [default to undefined] | | **notifyStatus** | **number** | 回调状态 | [optional] [default to undefined] |
| **payStatusText** | **string** | 支付状态文本 | [optional] [default to undefined] | | **notifyCount** | **number** | 回调次数 | [optional] [default to undefined] |
| **notifyStatus** | **number** | 回调状态 | [optional] [default to undefined] | | **paidAt** | **string** | 支付完成时间 | [optional] [default to undefined] |
| **notifyStatusText** | **string** | 回调状态文本 | [optional] [default to undefined] | | **lastCheckAt** | **string** | 最后检测支付时间 | [optional] [default to undefined] |
| **notifyCount** | **number** | 回调次数 | [optional] [default to undefined] | | **failureReason** | **string** | 失败原因 | [optional] [default to undefined] |
| **paidAt** | **string** | 支付完成时间 | [optional] [default to undefined] | | **createdAt** | **string** | 创建时间 | [optional] [default to undefined] |
| **lastCheckAt** | **string** | 最后检测支付时间 | [optional] [default to undefined] | | **updatedAt** | **string** | 更新时间 | [optional] [default to undefined] |
| **failureReason** | **string** | 失败原因 | [optional] [default to undefined] |
| **createdAt** | **string** | 创建时间 | [optional] [default to undefined] |
| **updatedAt** | **string** | 更新时间 | [optional] [default to undefined] |
## Example ## Example
@@ -36,11 +33,8 @@ const instance: KamiApiCamelOilV1OrderListItem = {
amount, amount,
alipayUrl, alipayUrl,
status, status,
statusText,
payStatus, payStatus,
payStatusText,
notifyStatus, notifyStatus,
notifyStatusText,
notifyCount, notifyCount,
paidAt, paidAt,
lastCheckAt, lastCheckAt,

View File

@@ -5,8 +5,6 @@
| Name | Type | Description | Notes | | Name | Type | Description | Notes |
| ---------------- | ---------- | --------------- | --------------------------------- | | ---------------- | ---------- | --------------- | --------------------------------- |
| **timestamp** | **string** | 请求时间戳 | [optional] [default to undefined] | | **timestamp** | **string** | 请求时间戳 | [optional] [default to undefined] |
| **phone** | **string** | 手机号(脱敏) | [optional] [default to undefined] |
| **amount** | **number** | 订单面额 | [optional] [default to undefined] |
| **responseData** | **string** | API响应原始数据 | [optional] [default to undefined] | | **responseData** | **string** | API响应原始数据 | [optional] [default to undefined] |
## Example ## Example
@@ -16,8 +14,6 @@ import { KamiApiCamelOilV1PrefetchOrderLogItem } from './api';
const instance: KamiApiCamelOilV1PrefetchOrderLogItem = { const instance: KamiApiCamelOilV1PrefetchOrderLogItem = {
timestamp, timestamp,
phone,
amount,
responseData responseData
}; };
``` ```

View File

@@ -5,6 +5,8 @@
| Name | Type | Description | Notes | | Name | Type | Description | Notes |
| ------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------ | --------------------------------- | | ------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------ | --------------------------------- |
| **useHaozhuPlatform** | **boolean** | 是否从豪猪平台获取手机号登录 | [optional] [default to undefined] | | **useHaozhuPlatform** | **boolean** | 是否从豪猪平台获取手机号登录 | [optional] [default to undefined] |
| **haozhuUsername** | **string** | 豪猪平台用户名 | [optional] [default to undefined] |
| **haozhuPassword** | **string** | 豪猪平台密码 | [optional] [default to undefined] |
| **loginAccountCount** | **number** | 要登录的手机号数量 | [optional] [default to undefined] | | **loginAccountCount** | **number** | 要登录的手机号数量 | [optional] [default to undefined] |
| **prefetchConcurrencyAccounts** | **number** | 提前拉单并发的账号数量 | [optional] [default to undefined] | | **prefetchConcurrencyAccounts** | **number** | 提前拉单并发的账号数量 | [optional] [default to undefined] |
| **singleAccountConcurrency** | **number** | 单个账号的并发数量 | [optional] [default to undefined] | | **singleAccountConcurrency** | **number** | 单个账号的并发数量 | [optional] [default to undefined] |
@@ -17,6 +19,8 @@ import { KamiApiCamelOilV1UpdateSettingsReq } from './api';
const instance: KamiApiCamelOilV1UpdateSettingsReq = { const instance: KamiApiCamelOilV1UpdateSettingsReq = {
useHaozhuPlatform, useHaozhuPlatform,
haozhuUsername,
haozhuPassword,
loginAccountCount, loginAccountCount,
prefetchConcurrencyAccounts, prefetchConcurrencyAccounts,
singleAccountConcurrency, singleAccountConcurrency,

View File

@@ -29,10 +29,6 @@ export interface KamiApiCamelOilV1AccountListItem {
* 状态 * 状态
*/ */
status?: KamiApiCamelOilV1AccountListItemStatusEnum; status?: KamiApiCamelOilV1AccountListItemStatusEnum;
/**
* 状态文本
*/
statusText?: string;
/** /**
* 当日下单数 * 当日下单数
*/ */

View File

@@ -29,10 +29,6 @@ export interface KamiApiCamelOilV1AccountOrderListResAccountInfo {
* 状态 * 状态
*/ */
status?: KamiApiCamelOilV1AccountOrderListResAccountInfoStatusEnum; status?: KamiApiCamelOilV1AccountOrderListResAccountInfoStatusEnum;
/**
* 状态文本
*/
statusText?: string;
} }
export enum KamiApiCamelOilV1AccountOrderListResAccountInfoStatusEnum { export enum KamiApiCamelOilV1AccountOrderListResAccountInfoStatusEnum {

View File

@@ -29,10 +29,6 @@ export interface KamiApiCamelOilV1AccountStatisticsResAccountInfo {
* 状态 * 状态
*/ */
status?: KamiApiCamelOilV1AccountStatisticsResAccountInfoStatusEnum; status?: KamiApiCamelOilV1AccountStatisticsResAccountInfoStatusEnum;
/**
* 状态文本
*/
statusText?: string;
/** /**
* 最后使用时间 * 最后使用时间
*/ */

View File

@@ -21,6 +21,14 @@ export interface KamiApiCamelOilV1GetSettingsRes {
* 是否从豪猪平台获取手机号登录 * 是否从豪猪平台获取手机号登录
*/ */
useHaozhuPlatform?: boolean; useHaozhuPlatform?: boolean;
/**
* 豪猪平台用户名
*/
haozhuUsername?: string;
/**
* 豪猪平台密码
*/
haozhuPassword?: string;
/** /**
* 要登录的手机号数量 * 要登录的手机号数量
*/ */

View File

@@ -29,10 +29,6 @@ export interface KamiApiCamelOilV1OrderDetailResAccountInfo {
* 状态 * 状态
*/ */
status?: KamiApiCamelOilV1OrderDetailResAccountInfoStatusEnum; status?: KamiApiCamelOilV1OrderDetailResAccountInfoStatusEnum;
/**
* 状态文本
*/
statusText?: string;
/** /**
* 最后使用时间 * 最后使用时间
*/ */

View File

@@ -41,26 +41,14 @@ export interface KamiApiCamelOilV1OrderDetailResOrderInfo {
* 订单状态 * 订单状态
*/ */
status?: KamiApiCamelOilV1OrderDetailResOrderInfoStatusEnum; status?: KamiApiCamelOilV1OrderDetailResOrderInfoStatusEnum;
/**
* 订单状态文本
*/
statusText?: string;
/** /**
* 支付状态 * 支付状态
*/ */
payStatus?: KamiApiCamelOilV1OrderDetailResOrderInfoPayStatusEnum; payStatus?: KamiApiCamelOilV1OrderDetailResOrderInfoPayStatusEnum;
/**
* 支付状态文本
*/
payStatusText?: string;
/** /**
* 回调状态 * 回调状态
*/ */
notifyStatus?: KamiApiCamelOilV1OrderDetailResOrderInfoNotifyStatusEnum; notifyStatus?: KamiApiCamelOilV1OrderDetailResOrderInfoNotifyStatusEnum;
/**
* 回调状态文本
*/
notifyStatusText?: string;
/** /**
* 回调次数 * 回调次数
*/ */

View File

@@ -41,26 +41,14 @@ export interface KamiApiCamelOilV1OrderListItem {
* 订单状态 * 订单状态
*/ */
status?: KamiApiCamelOilV1OrderListItemStatusEnum; status?: KamiApiCamelOilV1OrderListItemStatusEnum;
/**
* 订单状态文本
*/
statusText?: string;
/** /**
* 支付状态 * 支付状态
*/ */
payStatus?: KamiApiCamelOilV1OrderListItemPayStatusEnum; payStatus?: KamiApiCamelOilV1OrderListItemPayStatusEnum;
/**
* 支付状态文本
*/
payStatusText?: string;
/** /**
* 回调状态 * 回调状态
*/ */
notifyStatus?: KamiApiCamelOilV1OrderListItemNotifyStatusEnum; notifyStatus?: KamiApiCamelOilV1OrderListItemNotifyStatusEnum;
/**
* 回调状态文本
*/
notifyStatusText?: string;
/** /**
* 回调次数 * 回调次数
*/ */

View File

@@ -17,14 +17,6 @@ export interface KamiApiCamelOilV1PrefetchOrderLogItem {
* 请求时间戳 * 请求时间戳
*/ */
timestamp?: string; timestamp?: string;
/**
* 手机号(脱敏)
*/
phone?: string;
/**
* 订单面额
*/
amount?: number;
/** /**
* API响应原始数据 * API响应原始数据
*/ */

View File

@@ -21,6 +21,14 @@ export interface KamiApiCamelOilV1UpdateSettingsReq {
* 是否从豪猪平台获取手机号登录 * 是否从豪猪平台获取手机号登录
*/ */
useHaozhuPlatform?: boolean; useHaozhuPlatform?: boolean;
/**
* 豪猪平台用户名
*/
haozhuUsername?: string;
/**
* 豪猪平台密码
*/
haozhuPassword?: string;
/** /**
* 要登录的手机号数量 * 要登录的手机号数量
*/ */

View File

@@ -1,133 +0,0 @@
<template>
<a-modal
v-model:visible="visible"
title="API响应数据"
width="800px"
:footer="false"
@cancel="handleCancel"
>
<div class="response-container">
<div class="response-header">
<a-space>
<a-button size="small" @click="formatJson">
<template #icon>
<icon-code />
</template>
格式化
</a-button>
<a-button size="small" @click="copyToClipboard">
<template #icon>
<icon-copy />
</template>
复制
</a-button>
</a-space>
</div>
<pre class="response-content" :class="{ formatted: isFormatted }">{{
displayData
}}</pre>
</div>
</a-modal>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { Message } from '@arco-design/web-vue';
interface Props {
visible: boolean;
responseData: string;
}
interface Emits {
(e: 'update:visible', value: boolean): void;
}
const props = defineProps<Props>();
const emit = defineEmits<Emits>();
const visible = computed({
get: () => props.visible,
set: value => emit('update:visible', value)
});
const isFormatted = ref(false);
const displayData = computed(() => {
if (!props.responseData) return '';
if (isFormatted.value) {
try {
// 尝试解析为JSON并格式化
const parsed = JSON.parse(props.responseData);
return JSON.stringify(parsed, null, 2);
} catch {
// 如果不是有效的JSON直接返回原始数据
return props.responseData;
}
}
return props.responseData;
});
const formatJson = () => {
isFormatted.value = !isFormatted.value;
};
const copyToClipboard = async () => {
try {
await navigator.clipboard.writeText(displayData.value);
Message.success({
content: '复制成功',
duration: 2000
});
} catch (err) {
console.error('复制失败:', err);
Message.error({
content: '复制失败',
duration: 2000
});
}
};
const handleCancel = () => {
isFormatted.value = false; // 重置格式化状态
visible.value = false;
};
</script>
<style scoped>
.response-container {
position: relative;
}
.response-header {
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 1px solid var(--color-border-2);
}
.response-content {
max-height: 500px;
overflow-y: auto;
background-color: var(--color-fill-2);
padding: 16px;
border-radius: var(--border-radius-medium);
font-size: 12px;
line-height: 1.4;
white-space: pre-wrap;
word-break: break-all;
margin: 0;
color: var(--color-text-1);
}
.response-content.formatted {
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
white-space: pre;
word-break: normal;
}
:deep(.arco-modal-body) {
max-height: 70vh;
overflow-y: auto;
}
</style>

View File

@@ -22,6 +22,45 @@
<template #help>是否从豪猪平台获取手机号登录</template> <template #help>是否从豪猪平台获取手机号登录</template>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12">
<a-form-item
field="haozhuUsername"
label="豪猪用户名"
:rules="[
{
required: formModel.useHaozhuPlatform,
message: '启用豪猪平台时请输入用户名'
}
]"
>
<a-input
v-model="formModel.haozhuUsername"
placeholder="请输入豪猪平台用户名"
:disabled="!formModel.useHaozhuPlatform"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item
field="haozhuPassword"
label="豪猪密码"
:rules="[
{
required: formModel.useHaozhuPlatform,
message: '启用豪猪平台时请输入密码'
}
]"
>
<a-input-password
v-model="formModel.haozhuPassword"
placeholder="请输入豪猪平台密码"
:disabled="!formModel.useHaozhuPlatform"
/>
</a-form-item>
</a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item <a-form-item
field="loginAccountCount" field="loginAccountCount"
@@ -185,28 +224,19 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref } from 'vue'; import { reactive, onMounted } from 'vue';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import type { KamiApiCamelOilV1DenominationSetting } from '@/api/generated/index.ts'; import type { KamiApiCamelOilV1DenominationSetting } from '@/api/generated/index.ts';
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'; import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
import { jdV2SettingsClient } from '@/api/index.ts'; import { jdV2SettingsClient } from '@/api/index.ts';
interface Props { const { loading, setLoading } = useLoading(false);
loading?: boolean;
}
interface Emits {
(e: 'submit', data: any): void;
(e: 'reset'): void;
}
const props = withDefaults(defineProps<Props>(), {
loading: false
});
const emit = defineEmits<Emits>();
const formModel = reactive({ const formModel = reactive({
useHaozhuPlatform: false, useHaozhuPlatform: false,
haozhuUsername: '',
haozhuPassword: '',
loginAccountCount: 5, loginAccountCount: 5,
prefetchConcurrencyAccounts: 2, prefetchConcurrencyAccounts: 2,
singleAccountConcurrency: 3, singleAccountConcurrency: 3,
@@ -264,6 +294,17 @@ const removeDenomination = (index: number) => {
const handleSubmit = async () => { const handleSubmit = async () => {
try { try {
// 验证豪猪平台设置
if (formModel.useHaozhuPlatform) {
if (!formModel.haozhuUsername || !formModel.haozhuPassword) {
Message.warning({
content: '启用豪猪平台时请填写用户名和密码',
duration: 3000
});
return;
}
}
// 验证面额设置 // 验证面额设置
if ( if (
formModel.targetDenominations && formModel.targetDenominations &&
@@ -288,36 +329,53 @@ const handleSubmit = async () => {
} }
} }
emit('submit', { ...formModel }); setLoading(true);
await jdV2SettingsClient.apiJdV2SettingsUpdatePost({
kamiApiCamelOilV1UpdateSettingsReq: { ...formModel }
});
Message.success({
content: '设置保存成功',
duration: 2000
});
} catch (error) { } catch (error) {
console.error('表单验证失败:', error); console.error('保存设置失败:', error);
Message.error({
content: '保存设置失败',
duration: 2000
});
} finally {
setLoading(false);
} }
}; };
const resetForm = () => { const resetForm = () => {
formModel.useHaozhuPlatform = false; loadSettings();
formModel.loginAccountCount = 5;
formModel.prefetchConcurrencyAccounts = 2;
formModel.singleAccountConcurrency = 3;
formModel.targetDenominations = [];
emit('reset');
}; };
// 暴露方法供父组件调用 // 加载设置数据
const setFormData = (data: any) => { const loadSettings = async () => {
Object.assign(formModel, data); setLoading(true);
if (!formModel.targetDenominations) { try {
formModel.targetDenominations = []; const { data } = await jdV2SettingsClient.apiJdV2SettingsGetGet();
Object.assign(formModel, data);
if (!formModel.targetDenominations) {
formModel.targetDenominations = [];
}
} catch (error) {
console.error('获取设置失败:', error);
Message.error({
content: '获取设置失败',
duration: 2000
});
} finally {
setLoading(false);
} }
}; };
const getFormData = () => { // 组件挂载时加载设置
return { ...formModel }; onMounted(() => {
}; loadSettings();
defineExpose({
setFormData,
getFormData
}); });
</script> </script>

View File

@@ -77,49 +77,53 @@
</a-button> </a-button>
</div> </div>
<!-- 日志数据表格区域 --> <!-- 日志数据文本区域 -->
<a-table <div class="log-container">
:loading="logsLoading" <div class="log-header">
:data="logsRenderData" <a-space>
:columns="logColumns" <a-button size="small" @click="copyLogs">
:scroll="{ x: 1200 }"
:pagination="{
current: logsPagination.current,
pageSize: logsPagination.pageSize,
total: logsPagination.total,
pageSizeOptions: [10, 20, 50, 100],
showPageSize: true
}"
row-key="timestamp"
@page-change="onLogsPageChange"
@page-size-change="onLogsPageSizeChange"
>
<!-- 订单面额列模板 -->
<template #amount="{ record }">
<span v-if="record.amount">¥{{ record.amount.toFixed(2) }}</span>
<span v-else>-</span>
</template>
<!-- 响应数据列模板 -->
<template #responseData="{ record }">
<a-tooltip
v-if="record.responseData"
content="点击查看完整响应数据"
>
<a-button
size="small"
type="text"
@click="showResponseData(record.responseData)"
>
<template #icon> <template #icon>
<icon-eye /> <icon-copy />
</template> </template>
查看响应 复制日志
</a-button> </a-button>
</a-tooltip> <a-button size="small" @click="clearLogs">
<span v-else>-</span> <template #icon>
</template> <icon-delete />
</a-table> </template>
清空日志
</a-button>
</a-space>
</div>
<div ref="logContentRef" class="log-content">
<div v-if="logsLoading" class="log-loading">
<a-spin />
<span>加载日志中...</span>
</div>
<div v-else-if="logsRenderData.length === 0" class="log-empty">
暂无日志数据
</div>
<div v-else class="log-entries">
<div
v-for="(log, index) in logsRenderData"
:key="log.timestamp || index"
class="log-entry"
>
<div class="log-time">
{{ formatDateTime(log.timestamp) }}
</div>
<div class="log-response">
<div class="log-response-header">
<span>响应数据:</span>
</div>
<div class="log-response-content">
{{ log.responseData || '无响应数据' }}
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<!-- 预拉取订单列表内容 --> <!-- 预拉取订单列表内容 -->
@@ -271,12 +275,6 @@
</div> </div>
</a-card> </a-card>
<!-- 响应数据详情弹窗 -->
<response-data-modal
v-model:visible="state.responseModalVisible"
:response-data="state.selectedResponseData"
/>
<!-- 设置配置弹窗 --> <!-- 设置配置弹窗 -->
<a-modal <a-modal
v-model:visible="state.settingsModalVisible" v-model:visible="state.settingsModalVisible"
@@ -285,12 +283,7 @@
:footer="false" :footer="false"
@cancel="state.settingsModalVisible = false" @cancel="state.settingsModalVisible = false"
> >
<settings-form <settings-form />
ref="settingsFormRef"
:loading="settingsLoading"
@submit="handleSettingsSubmit"
@reset="handleSettingsReset"
/>
</a-modal> </a-modal>
</div> </div>
</template> </template>
@@ -299,18 +292,15 @@
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
import { Pagination } from '@/types/global'; import { Pagination } from '@/types/global';
import { onMounted, reactive, ref, computed, watch } from 'vue'; import { onMounted, reactive, ref, computed, watch } from 'vue';
import { Notification } from '@arco-design/web-vue'; import { Notification, Message } from '@arco-design/web-vue';
import SettingsForm from './components/settings-form.vue'; import SettingsForm from './components/settings-form.vue';
import ResponseDataModal from './components/response-data-modal.vue';
import type { import type {
KamiApiCamelOilV1PrefetchOrderLogItem, KamiApiCamelOilV1PrefetchOrderLogItem,
KamiApiCamelOilV1PrefetchOrderListItem KamiApiCamelOilV1PrefetchOrderListItem
} from '@/api/generated/index.ts'; } from '@/api/generated/index.ts';
import { jdV2PrefetchClient, jdV2SettingsClient } from '@/api/index.ts'; import { jdV2PrefetchClient } from '@/api/index.ts';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
const settingsFormRef = ref();
// 当前活跃视图 // 当前活跃视图
const activeView = ref('logs'); const activeView = ref('logs');
@@ -319,19 +309,6 @@ const cardTitle = computed(() => {
return activeView.value === 'logs' ? '预拉取订单日志' : '预拉取订单列表'; return activeView.value === 'logs' ? '预拉取订单日志' : '预拉取订单列表';
}); });
// 设置相关状态
const { loading: settingsLoading, setLoading: setSettingsLoading } =
useLoading(false);
// 日志相关状态
const baseLogsPagination: Pagination = {
current: 1,
pageSize: 50
};
const logsPagination = reactive({
...baseLogsPagination
});
// 订单列表相关状态 // 订单列表相关状态
const baseOrdersPagination: Pagination = { const baseOrdersPagination: Pagination = {
current: 1, current: 1,
@@ -341,46 +318,6 @@ const ordersPagination = reactive({
...baseOrdersPagination ...baseOrdersPagination
}); });
const logColumns = [
{
title: '序号',
dataIndex: 'index',
width: 80,
render: ({ rowIndex }) => {
return (
rowIndex + 1 + (logsPagination.current - 1) * logsPagination.pageSize
);
}
},
{
title: '请求时间',
dataIndex: 'timestamp',
width: 180,
render: ({ record }) => {
return formatDateTime(record.timestamp);
}
},
{
title: '手机号',
dataIndex: 'phone',
width: 130,
ellipsis: true,
tooltip: true
},
{
title: '订单面额',
dataIndex: 'amount',
slotName: 'amount',
width: 100
},
{
title: '响应数据',
dataIndex: 'responseData',
slotName: 'responseData',
width: 120
}
];
const generateLogFormModel = () => { const generateLogFormModel = () => {
const now = dayjs(); const now = dayjs();
return { return {
@@ -490,58 +427,11 @@ const orderColumns = [
]; ];
const state = reactive({ const state = reactive({
responseModalVisible: false,
selectedResponseData: '',
settingsModalVisible: false settingsModalVisible: false
}); });
// 设置相关方法
const loadSettings = async () => {
setSettingsLoading(true);
try {
const { data } = await jdV2SettingsClient.apiJdV2SettingsGetGet();
if (settingsFormRef.value) {
settingsFormRef.value.setFormData(data);
}
} catch (err) {
console.error('获取设置失败:', err);
Notification.error({
content: '获取设置失败',
closable: true
});
} finally {
setSettingsLoading(false);
}
};
const handleSettingsSubmit = async (formData: any) => {
setSettingsLoading(true);
try {
await jdV2SettingsClient.apiJdV2SettingsUpdatePost({
kamiApiCamelOilV1UpdateSettingsReq: formData
});
Notification.success({
content: '设置保存成功',
closable: true
});
} catch (err) {
console.error('保存设置失败:', err);
Notification.error({
content: '保存设置失败',
closable: true
});
} finally {
setSettingsLoading(false);
}
};
const handleSettingsReset = () => {
loadSettings();
};
// 日志相关方法 // 日志相关方法
const fetchLogs = async (params: any = { current: 1, pageSize: 50 }) => { const fetchLogs = async () => {
if (!logFormModel.value.startTime || !logFormModel.value.endTime) { if (!logFormModel.value.startTime || !logFormModel.value.endTime) {
Notification.warning({ Notification.warning({
content: '请选择开始时间和结束时间', content: '请选择开始时间和结束时间',
@@ -560,17 +450,8 @@ const fetchLogs = async (params: any = { current: 1, pageSize: 50 }) => {
endTime: dayjs(logFormModel.value.endTime).format('YYYY-MM-DD HH:mm:ss') endTime: dayjs(logFormModel.value.endTime).format('YYYY-MM-DD HH:mm:ss')
}); });
// 模拟分页,因为API返回的全部数据 // 直接使用API返回的全部日志数据
const allData = data.logs || []; logsRenderData.value = data.logs || [];
const total = allData.length;
const start = (params.current - 1) * params.pageSize;
const end = start + params.pageSize;
const pageData = allData.slice(start, end);
logsRenderData.value = pageData;
logsPagination.current = params.current;
logsPagination.pageSize = params.pageSize;
logsPagination.total = total;
} catch (err) { } catch (err) {
console.error('获取预拉取订单日志失败:', err); console.error('获取预拉取订单日志失败:', err);
Notification.error({ Notification.error({
@@ -582,18 +463,8 @@ const fetchLogs = async (params: any = { current: 1, pageSize: 50 }) => {
} }
}; };
const onLogsPageChange = (current: number) => {
fetchLogs({ ...logsPagination, current });
};
const onLogsPageSizeChange = (pageSize: number) => {
fetchLogs({ ...logsPagination, pageSize, current: 1 });
};
const searchLogs = () => { const searchLogs = () => {
fetchLogs({ fetchLogs();
...baseLogsPagination
});
}; };
const resetLogs = () => { const resetLogs = () => {
@@ -601,15 +472,40 @@ const resetLogs = () => {
searchLogs(); searchLogs();
}; };
const showResponseData = (responseData: string) => { const copyLogs = async () => {
state.selectedResponseData = responseData; try {
state.responseModalVisible = true; const logText = logsRenderData.value
.map(log => {
const time = formatDateTime(log.timestamp);
const data = log.responseData || '无响应数据';
return `[${time}] ${data}`;
})
.join('\n\n');
await navigator.clipboard.writeText(logText);
Message.success({
content: '日志复制成功',
duration: 2000
});
} catch (err) {
console.error('复制日志失败:', err);
Message.error({
content: '复制日志失败',
duration: 2000
});
}
};
const clearLogs = () => {
logsRenderData.value = [];
Message.info({
content: '日志已清空',
duration: 2000
});
}; };
const showSettingsModal = () => { const showSettingsModal = () => {
state.settingsModalVisible = true; state.settingsModalVisible = true;
// 打开弹窗时加载设置
loadSettings();
}; };
const formatDateTime = (dateTime: string | undefined): string => { const formatDateTime = (dateTime: string | undefined): string => {
@@ -732,4 +628,84 @@ onMounted(() => {
justify-content: flex-end; justify-content: flex-end;
margin-bottom: 16px; margin-bottom: 16px;
} }
/* 日志容器样式 */
.log-container {
border: 1px solid var(--color-border-2);
border-radius: var(--border-radius-medium);
overflow: hidden;
}
.log-header {
padding: 12px 16px;
background-color: var(--color-fill-1);
border-bottom: 1px solid var(--color-border-2);
display: flex;
justify-content: flex-end;
}
.log-content {
max-height: 600px;
overflow-y: auto;
background-color: var(--color-bg-2);
}
.log-loading,
.log-empty {
padding: 40px;
text-align: center;
color: var(--color-text-3);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.log-entries {
padding: 16px;
}
.log-entry {
margin-bottom: 16px;
padding: 12px;
background-color: var(--color-bg-1);
border: 1px solid var(--color-border-2);
border-radius: var(--border-radius-small);
}
.log-entry:last-child {
margin-bottom: 0;
}
.log-time {
font-size: 12px;
color: var(--color-text-3);
margin-bottom: 8px;
font-family: Monaco, Menlo, 'Ubuntu Mono', monospace;
}
.log-response-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.log-response-header span {
font-size: 13px;
font-weight: 500;
color: var(--color-text-1);
}
.log-response-content {
font-size: 12px;
color: var(--color-text-2);
line-height: 1.5;
word-break: break-all;
background-color: var(--color-fill-1);
padding: 8px;
border-radius: var(--border-radius-small);
max-height: 200px;
overflow-y: auto;
}
</style> </style>