refactor(recharge-history): 优化苹果卡充值历史页面代码结构和逻辑

- 统一icon模板写法,提升代码简洁性
- 表格分页配置改为计算属性,改善代码组织
- 显示状态标签新增文字长度判断和悬浮提示优化
- 增加类型兼容适配函数,支持新旧数据结构转换
- 重构fetchData函数,调用新版API并简化参数处理
- 优化分页、查询、重置相关函数逻辑,避免重复传参
- 使用常量对象维护状态映射,减少冗余代码
- 异步调用改用apiClient封装,提升接口调用一致性
- 优化文件下载逻辑,支持xlsx格式并自动触发保存
- 删除已注释和废弃代码,提升代码可维护性
This commit is contained in:
danial
2025-12-06 15:10:05 +08:00
parent 98777f50d8
commit 7af3c2759e

View File

@@ -56,44 +56,29 @@
<a-space direction="vertical" :size="18"> <a-space direction="vertical" :size="18">
<a-space direction="horizontal" :size="18"> <a-space direction="horizontal" :size="18">
<a-button type="primary" @click="search"> <a-button type="primary" @click="search">
<template #icon> <template #icon><icon-search /></template>
<icon-search />
</template>
搜索 搜索
</a-button> </a-button>
<a-button @click="reset"> <a-button @click="reset">
<template #icon> <template #icon><icon-refresh /></template>
<icon-refresh />
</template>
重置 重置
</a-button> </a-button>
</a-space> </a-space>
<a-space direction="horizontal" :size="18"> <a-button
<a-button type="secondary"
type="secondary" status="warning"
status="warning" @click="downloadDataList"
@click="downloadDataList" >
> <template #icon><icon-download /></template>
<template #icon> 下载
<icon-download /> </a-button>
</template>
下载
</a-button>
</a-space>
</a-space> </a-space>
</a-col> </a-col>
</a-row> </a-row>
<a-divider style="margin-top: 0" /> <a-divider style="margin-top: 0" />
<a-table <a-table
:loading="loading" :loading="loading"
:pagination="{ :pagination="paginationConfig"
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
pageSizeOptions: [10, 20, 50, 100],
showPageSize: true,
showTotal: true
}"
:columns="columns" :columns="columns"
:data="renderData" :data="renderData"
:bordered="false" :bordered="false"
@@ -113,13 +98,20 @@
> >
{{ getStatusColorMap(record.status).text }} {{ getStatusColorMap(record.status).text }}
</a-tag> </a-tag>
<a-tag <template v-if="record.status === 0 || record.status === 16">
v-if="record.status === 0 || record.status === 16" <a-tag
color="gray" v-if="record.remark.length <= 10"
size="small" color="gray"
> size="small"
{{ record.remark }} >
</a-tag> {{ record.remark }}
</a-tag>
<a-tooltip v-else :content="record.remark" position="top">
<a-tag color="gray" size="small">
{{ truncateText(record.remark, 10) }}
</a-tag>
</a-tooltip>
</template>
<a-tag <a-tag
v-if="[1, 2].includes(record.notifyStatus)" v-if="[1, 2].includes(record.notifyStatus)"
size="small" size="small"
@@ -136,9 +128,7 @@
size="small" size="small"
@click="showRechargeHistory(record.orderNo)" @click="showRechargeHistory(record.orderNo)"
> >
<template #icon> <template #icon><icon-list /></template>
<icon-list />
</template>
</a-button> </a-button>
</a-tooltip> </a-tooltip>
<a-popconfirm <a-popconfirm
@@ -155,9 +145,7 @@
status="success" status="success"
@click="showActualAmountModal(record.orderNo, record)" @click="showActualAmountModal(record.orderNo, record)"
> >
<template #icon> <template #icon><icon-refresh /></template>
<icon-refresh />
</template>
</a-button> </a-button>
</a-tooltip> </a-tooltip>
<a-tooltip content="回调"> <a-tooltip content="回调">
@@ -170,19 +158,9 @@
status="warning" status="warning"
@click="callBackOrderManual(record.orderNo)" @click="callBackOrderManual(record.orderNo)"
> >
<template #icon> <template #icon><icon-send /></template>
<icon-send />
</template>
</a-button> </a-button>
</a-tooltip> </a-tooltip>
<!-- <a-popconfirm
v-if="record.status === 14"
content="确认修改状态到成功状态?"
type="warning"
@ok="modifyStatusToSucceed(record.orderNo)"
>
<a-button size="small" status="danger">修正状态</a-button>
</a-popconfirm> -->
</a-space> </a-space>
</template> </template>
</a-table> </a-table>
@@ -193,7 +171,7 @@
/> />
<change-amount <change-amount
v-model:visible="state.changeAmountModalVisible" v-model:visible="state.changeAmountModalVisible"
:record="state.currentRecord" :record="createCompatibleRecord(state.currentRecord)"
:order-no="state.selectedOrderNo" :order-no="state.selectedOrderNo"
/> />
</div> </div>
@@ -202,18 +180,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import { Message, TableColumnData } from '@arco-design/web-vue'; import { Message, TableColumnData } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
import { Pagination } from '@/types/global'; import type { Pagination } from '@/types/global';
import { onMounted, reactive, ref, watch } from 'vue'; import { onMounted, reactive, ref, computed, watch } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { import type { KamiInternalModelEntityV1CardAppleRechargeInfo } from '@/api/generated/models';
AppleCardRechargeOrderParams, import type { AppleCardRechargeOrderRecord } from '@/api/apple-card-recharge-history';
AppleCardRechargeOrderRecord, import { apiClient } from '@/api';
callBackOrderManualAPI,
downloadDataListApi,
modifyStatusToSucceedAPI,
queryAppleCardRechargeOrderList,
resetOrderStatusAPI
} from '@/api/apple-card-recharge-history';
import RechargeHistory from './components/recharge-history.vue'; import RechargeHistory from './components/recharge-history.vue';
import ChangeAmount from './components/change-amount.vue'; import ChangeAmount from './components/change-amount.vue';
import { checkTokenFromIframe } from '@/utils/auth'; import { checkTokenFromIframe } from '@/utils/auth';
@@ -221,14 +193,22 @@ import { checkTokenFromIframe } from '@/utils/auth';
const route = useRoute(); const route = useRoute();
const { accountID } = route.params; const { accountID } = route.params;
const basePagination: Pagination = { const basePagination: Pagination = { current: 1, pageSize: 50 };
current: 1,
pageSize: 50
};
const pagination = reactive({ const pagination = reactive({
accountID: accountID as string, accountID: accountID as string,
...basePagination ...basePagination
}); });
// Status mapping constants
const STATUS_MAP = Object.freeze({
0: { color: 'red', text: '失败' },
1: { color: 'green', text: '成功' },
2: { color: 'orange', text: '调度中' },
3: { color: 'blue', text: '等待' },
14: { color: 'blue', text: '卡密重复(需人工介入)' },
15: { color: 'red', text: '失败(金额异议)' },
16: { color: 'red', text: '冻结' }
} as const);
const columns: TableColumnData[] = [ const columns: TableColumnData[] = [
{ {
title: '序号', title: '序号',
@@ -283,20 +263,8 @@ const columns: TableColumnData[] = [
slotName: 'operations' slotName: 'operations'
} }
]; ];
const generateFormModel = () => { // Form model type definition
return { interface FormModel {
account: '',
orderNo: '',
attach: '',
cardNo: '',
cardPass: '',
merchantId: '',
dateRange: []
};
};
const { loading, setLoading } = useLoading(true);
const renderData = ref<AppleCardRechargeOrderRecord[]>([]);
const formModel = ref<{
account: string; account: string;
orderNo: string; orderNo: string;
attach: string; attach: string;
@@ -304,29 +272,72 @@ const formModel = ref<{
cardPass: string; cardPass: string;
merchantId: string; merchantId: string;
dateRange: Date[]; dateRange: Date[];
}>(generateFormModel()); }
const generateFormModel = (): FormModel => ({
account: '',
orderNo: '',
attach: '',
cardNo: '',
cardPass: '',
merchantId: '',
dateRange: []
});
const { loading, setLoading } = useLoading(true);
const renderData = ref<KamiInternalModelEntityV1CardAppleRechargeInfo[]>([]);
const formModel = ref<FormModel>(generateFormModel());
const state = reactive({ const state = reactive({
rechargeHistoryModalVisible: false, rechargeHistoryModalVisible: false,
selectedOrderNo: '', selectedOrderNo: '',
changeAmountModalVisible: false, changeAmountModalVisible: false,
currentRecord: {} as AppleCardRechargeOrderRecord currentRecord: {} as KamiInternalModelEntityV1CardAppleRechargeInfo
}); });
const fetchData = async ( // 创建类型适配器,确保向后兼容
params: AppleCardRechargeOrderParams = { const createCompatibleRecord = (
current: 1, record: KamiInternalModelEntityV1CardAppleRechargeInfo
pageSize: 50 ): AppleCardRechargeOrderRecord => ({
} id: record.id || 0,
) => { orderNo: record.orderNo || '',
actualAmount: record.actualAmount || 0,
cardAmount: record.cardAmount || 0,
balance: record.balance || 0,
accountName: record.accountName || '',
attach: record.attach || '',
notifyStatus: record.notifyStatus || 0,
merchantId: record.merchantId || '',
createdAt: record.createdAt || ''
});
const paginationConfig = computed(() => ({
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
pageSizeOptions: [10, 20, 50, 100],
showPageSize: true,
showTotal: true
}));
const fetchData = async () => {
setLoading(true); setLoading(true);
try { try {
const { const { data } = await apiClient.apiCardInfoAppleCardRechargeOrderListGet({
data: { list, total } current: pagination.current,
} = await queryAppleCardRechargeOrderList(params); pageSize: pagination.pageSize,
renderData.value = list; account: formModel.value.account,
pagination.current = params.current; accountId: accountID as string,
pagination.pageSize = params.pageSize; attach: formModel.value.attach,
pagination.total = total; orderNo: formModel.value.orderNo,
cardNo: formModel.value.cardNo,
cardPass: formModel.value.cardPass,
merchantId: formModel.value.merchantId,
startDate: formModel.value.dateRange?.[0]?.toISOString(),
endDate: formModel.value.dateRange?.[1]?.toISOString()
});
renderData.value = data.list || [];
pagination.total = data.total || 0;
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} finally { } finally {
@@ -335,123 +346,95 @@ const fetchData = async (
}; };
const onPageChange = (current: number) => { const onPageChange = (current: number) => {
fetchData({ ...pagination, current }); pagination.current = current;
fetchData();
}; };
const onPageSizeChange = (pageSize: number) => { const onPageSizeChange = (pageSize: number) => {
fetchData({ ...pagination, pageSize }); pagination.pageSize = pageSize;
fetchData();
}; };
const search = () => { const search = () => {
fetchData({ Object.assign(pagination, basePagination);
...basePagination, fetchData();
...formModel.value
});
}; };
const reset = () => { const reset = () => {
formModel.value = generateFormModel(); formModel.value = generateFormModel();
search();
}; };
const showRechargeHistory = (orderNo: string) => { const showRechargeHistory = (orderNo: string) => {
state.rechargeHistoryModalVisible = true; Object.assign(state, {
state.selectedOrderNo = orderNo; rechargeHistoryModalVisible: true,
selectedOrderNo: orderNo
});
}; };
const getStatusColorMap = (status: number) => { const truncateText = (text: string, maxLength: number) =>
type colorMap = { text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
color: string;
text: string;
};
let c: colorMap = {
color: '',
text: ''
};
switch (status) { const getStatusColorMap = (status: number) =>
case 0: STATUS_MAP[status as keyof typeof STATUS_MAP] || {
c = { color: 'grey',
color: 'red', text: '其他状态,待更新'
text: '失败' };
};
break;
case 1:
c = {
color: 'green',
text: '成功'
};
break;
case 15:
c = {
color: 'red',
text: '失败(金额异议)'
};
break;
case 14:
c = {
color: 'blue',
text: '卡密重复(需人工介入)'
};
break;
case 2:
c = {
color: 'orange',
text: '调度中'
};
break;
case 3:
c = {
color: 'blue',
text: '等待'
};
break;
case 16:
c = {
color: 'red',
text: '冻结'
};
break;
default:
c = {
color: 'grey',
text: '其他状态,待更新'
};
break;
}
return c;
};
const callBackOrderManual = async (orderNo: string) => { const callBackOrderManual = async (orderNo: string) => {
await callBackOrderManualAPI({ orderNo }); await apiClient.apiCardInfoAppleCardRechargeOrderCallbackByManualPost({
fetchData({ ...pagination, ...formModel.value }); kamiApiCardInfoAppleV1CallBackOrderManualReq: { orderNo }
});
fetchData();
Message.success('回调成功'); Message.success('回调成功');
}; };
const showActualAmountModal = ( const showActualAmountModal = (
orderNo: string, orderNo: string,
record: AppleCardRechargeOrderRecord record: KamiInternalModelEntityV1CardAppleRechargeInfo
) => { ) => {
state.changeAmountModalVisible = true; Object.assign(state, {
state.selectedOrderNo = orderNo; changeAmountModalVisible: true,
state.currentRecord = record; selectedOrderNo: orderNo,
}; currentRecord: record
const modifyStatusToSucceed = async (orderNo: string) => { });
await modifyStatusToSucceedAPI({ orderNo });
fetchData({ ...pagination, ...formModel.value });
Message.success('处理成功');
}; };
watch( watch(
() => state.changeAmountModalVisible, () => state.changeAmountModalVisible,
newValue => { newValue => {
if (newValue === false) { if (!newValue) search();
search();
}
} }
); );
const resetStatus = (orderNo: string) => {
resetOrderStatusAPI({ orderNo }).then(() => { const resetStatus = async (orderNo: string) => {
Message.success('重置成功'); await apiClient.apiCardInfoAppleCardRechargeOrderResetStatusPost({
search(); kamiApiCardInfoAppleV1RechargeOrderResetStatusReq: { orderNo }
}); });
Message.success('重置成功');
search();
}; };
onMounted(() => fetchData({ ...pagination }));
onMounted(() => fetchData());
const downloadDataList = async () => { const downloadDataList = async () => {
await downloadDataListApi({ const response = await apiClient.apiCardInfoAppleCardRechargeOrderDownloadGet(
...basePagination, {
...formModel.value accountId: accountID as string,
account: formModel.value.account,
attach: formModel.value.attach,
orderNo: formModel.value.orderNo,
cardNo: formModel.value.cardNo,
merchantId: formModel.value.merchantId,
cardPass: formModel.value.cardPass,
startDate: formModel.value.dateRange?.[0]?.toISOString(),
endDate: formModel.value.dateRange?.[1]?.toISOString()
}
);
// 处理文件下载
const blob = new Blob([response.data as unknown as ArrayBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}); });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'apple_recharge_history.xlsx';
link.click();
window.URL.revokeObjectURL(url);
}; };
</script> </script>