refactor(apple-card-info): 重构充值记录页面

- 新增 AccountInfo 组件,将原有逻辑和模板移至新组件中
- 在路由组件中引入并使用 AccountInfo 组件
- 优化代码结构,提高可维护性和可读性
This commit is contained in:
danial
2025-02-09 17:31:27 +08:00
parent 1d9b3e253a
commit 35993bb2af
3 changed files with 460 additions and 456 deletions

View File

@@ -276,7 +276,6 @@ func main() {
| 参数名称 | 类型 | 是否必须 | 描述 | 示例 |
| ----------- | ------ | -------- | ------------------ | --------------------------------------------------- |
| exValue | string | 是 | 扩展参数 | 卡密数据(具体格式如下) |
| orderNo | string | 是 | 订单号 | 20190520123456789 |
| orderPeriod | int | 否 | 订单有效期(小时) | 24 |
| orderPrice | float | 是 | 订单价格 | 100.12 |
@@ -285,7 +284,6 @@ func main() {
| timestamp | int | 是 | 时间戳 | Unix 时间戳,时区为 GMT+8 允许与服务器最大误差 30 秒 |
| sign | string | 是 | 签名 | 签名算法如下 |
| productCode | string | 卡片编码 | 是 | 8456 |
| timestamp | int | 是 | 时间戳 | Unix 时间戳,时区为 GMT+8 允许与服务器最大误差 30 秒 |
### 返回参数

View File

@@ -0,0 +1,457 @@
<template>
<div class="container">
<Breadcrumb :items="['充值账户管理', '充值记录']" />
<a-card class="general-card" title="充值记录">
<a-row>
<a-col :flex="1">
<a-form
:model="formModel"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }"
label-align="left"
>
<a-row :gutter="16">
<a-col :span="8">
<a-form-item field="account" label="账户">
<a-input
v-model="formModel.account"
placeholder="请输入账户名称"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="attach" label="系统订单">
<a-input
v-model="formModel.attach"
placeholder="请输入系统订单号"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="merchantId" label="商户订单号">
<a-input
v-model="formModel.merchantId"
placeholder="请输入商户订单号"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="dateRange" label="创建时间">
<a-range-picker v-model="formModel.dateRange" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="cardPass" label="卡密">
<a-input
v-model="formModel.cardPass"
placeholder="请输入卡密"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-col>
<a-divider style="height: 42px" direction="vertical" />
<a-col flex="172px" style="text-align: right">
<a-space direction="vertical" :size="18">
<a-space direction="horizontal" :size="18">
<a-button type="primary" @click="search">
<template #icon>
<icon-search />
</template>
搜索
</a-button>
<a-button @click="reset">
<template #icon>
<icon-refresh />
</template>
重置
</a-button>
</a-space>
<a-space direction="horizontal" :size="18">
<a-button
type="secondary"
status="warning"
@click="downloadDataList"
>
<template #icon>
<icon-download />
</template>
下载
</a-button>
</a-space>
</a-space>
</a-col>
</a-row>
<a-divider style="margin-top: 0" />
<a-table
:loading="loading"
:pagination="{
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
pageSizeOptions: [10, 20, 50, 100],
showPageSize: true,
showTotal: true
}"
:columns="columns"
:data="renderData"
:bordered="false"
column-resizable:bordered="{cell:true}"
@page-change="onPageChange"
@page-size-change="onPageSizeChange"
>
<template #index="{ rowIndex }">
{{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
</template>
<template #status="{ record }">
<a-space>
<a-tag
:key="record.status"
:color="getStatusColorMap(record.status).color"
size="small"
>
{{ getStatusColorMap(record.status).text }}
</a-tag>
<a-tag
v-if="record.status === 0 || record.status === 16"
color="gray"
size="small"
>
{{ record.remark }}
</a-tag>
<a-tag
v-if="[1, 2].includes(record.notifyStatus)"
size="small"
:color="record.notifyStatus === 1 ? 'green' : 'red'"
>
回调{{ record.notifyStatus === 1 ? '成功' : '失败' }}
</a-tag>
</a-space>
</template>
<template #operations="{ record }">
<a-space size="small">
<a-tooltip content="详情">
<a-button
size="small"
@click="showRechargeHistory(record.orderNo)"
>
<template #icon>
<icon-list />
</template>
</a-button>
</a-tooltip>
<a-popconfirm
v-if="checkTokenFromIframe() && record.status === 16"
content="确认重置?"
@ok="() => resetStatus(record.orderNo)"
>
<a-button size="small" status="warning">重置</a-button>
</a-popconfirm>
<a-tooltip content="修正">
<a-button
v-if="checkTokenFromIframe() && record.status === 0"
size="small"
status="success"
@click="showActualAmountModal(record.orderNo, record)"
>
<template #icon>
<icon-refresh />
</template>
</a-button>
</a-tooltip>
<a-tooltip content="回调">
<a-button
v-if="
(checkTokenFromIframe() && record.status === 0) ||
record.status === 1
"
size="small"
status="warning"
@click="callBackOrderManual(record.orderNo)"
>
<template #icon>
<icon-send />
</template>
</a-button>
</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>
</template>
</a-table>
</a-card>
<recharge-history
v-model:visible="state.rechargeHistoryModalVisible"
:order-no="state.selectedOrderNo"
/>
<change-amount
v-model:visible="state.changeAmountModalVisible"
:record="state.currentRecord"
:order-no="state.selectedOrderNo"
/>
</div>
</template>
<script lang="ts" setup>
import { Message, TableColumnData } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import { Pagination } from '@/types/global';
import { onMounted, reactive, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import {
AppleCardRechargeOrderParams,
AppleCardRechargeOrderRecord,
callBackOrderManualAPI,
downloadDataListApi,
modifyStatusToSucceedAPI,
queryAppleCardRechargeOrderList,
resetOrderStatusAPI
} from '@/api/apple-card-recharge-history';
import RechargeHistory from './components/recharge-history.vue';
import ChangeAmount from './components/change-amount.vue';
import { checkTokenFromIframe } from '@/utils/auth';
const route = useRoute();
const { accountID } = route.params;
const basePagination: Pagination = {
current: 1,
pageSize: 20
};
const pagination = reactive({
accountID: accountID as string,
...basePagination
});
const columns: TableColumnData[] = [
{
title: '序号',
dataIndex: 'index',
slotName: 'index'
},
{
title: '订单号',
dataIndex: 'orderNo'
},
{
title: '系统订单号',
dataIndex: 'attach'
},
{
title: '商户订单号',
dataIndex: 'merchantId'
},
{
title: '分配账号',
dataIndex: 'accountName',
slotName: 'account'
},
{
title: '卡密',
dataIndex: 'cardPass',
slotName: 'cardPass'
},
{
title: '卡面金额',
dataIndex: 'cardAmount',
slotName: 'cardAmount'
},
{
title: '支付金额',
dataIndex: 'actualAmount',
slotName: 'actualAmount'
},
{
title: '创建时间',
dataIndex: 'createdAt',
slotName: 'createdAt'
},
{
title: '状态',
dataIndex: 'status',
slotName: 'status'
},
{
title: '操作',
dataIndex: 'operations',
slotName: 'operations'
}
];
const generateFormModel = () => {
return {
account: '',
orderNo: '',
attach: '',
cardNo: '',
cardPass: '',
merchantId: '',
dateRange: []
};
};
const { loading, setLoading } = useLoading(true);
const renderData = ref<AppleCardRechargeOrderRecord[]>([]);
const formModel = ref<{
account: string;
orderNo: string;
attach: string;
cardNo: string;
cardPass: string;
merchantId: string;
dateRange: Date[];
}>(generateFormModel());
const state = reactive({
rechargeHistoryModalVisible: false,
selectedOrderNo: '',
changeAmountModalVisible: false,
currentRecord: {} as AppleCardRechargeOrderRecord
});
const fetchData = async (
params: AppleCardRechargeOrderParams = {
current: 1,
pageSize: 20
}
) => {
setLoading(true);
try {
const {
data: { list, total }
} = await queryAppleCardRechargeOrderList(params);
renderData.value = list;
pagination.current = params.current;
pagination.pageSize = params.pageSize;
pagination.total = total;
} catch (err) {
console.error(err);
} finally {
setLoading(false);
}
};
const onPageChange = (current: number) => {
fetchData({ ...pagination, current });
};
const onPageSizeChange = (pageSize: number) => {
fetchData({ ...pagination, pageSize });
};
const search = () => {
fetchData({
...basePagination,
...formModel.value
});
};
const reset = () => {
formModel.value = generateFormModel();
};
const showRechargeHistory = (orderNo: string) => {
state.rechargeHistoryModalVisible = true;
state.selectedOrderNo = orderNo;
};
const getStatusColorMap = (status: number) => {
type colorMap = {
color: string;
text: string;
};
let c: colorMap = {
color: '',
text: ''
};
switch (status) {
case 0:
c = {
color: 'red',
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) => {
await callBackOrderManualAPI({ orderNo });
fetchData({ ...pagination, ...formModel.value });
Message.success('回调成功');
};
const showActualAmountModal = (
orderNo: string,
record: AppleCardRechargeOrderRecord
) => {
state.changeAmountModalVisible = true;
state.selectedOrderNo = orderNo;
state.currentRecord = record;
};
const modifyStatusToSucceed = async (orderNo: string) => {
await modifyStatusToSucceedAPI({ orderNo });
fetchData({ ...pagination, ...formModel.value });
Message.success('处理成功');
};
watch(
() => state.changeAmountModalVisible,
newValue => {
if (newValue === false) {
search();
}
}
);
const resetStatus = (orderNo: string) => {
resetOrderStatusAPI({ orderNo }).then(() => {
Message.success('重置成功');
search();
});
};
onMounted(() => fetchData({ ...pagination }));
const downloadDataList = async () => {
await downloadDataListApi({
...basePagination,
...formModel.value
});
};
</script>

View File

@@ -1,458 +1,7 @@
<template>
<div class="container">
<Breadcrumb :items="['充值账户管理', '充值记录']" />
<a-card class="general-card" title="充值记录">
<a-row>
<a-col :flex="1">
<a-form
:model="formModel"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }"
label-align="left"
>
<a-row :gutter="16">
<a-col :span="8">
<a-form-item field="account" label="账户">
<a-input
v-model="formModel.account"
placeholder="请输入账户名称"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="attach" label="系统订单">
<a-input
v-model="formModel.attach"
placeholder="请输入系统订单号"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="merchantId" label="商户订单号">
<a-input
v-model="formModel.merchantId"
placeholder="请输入商户订单号"
/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="dateRange" label="创建时间">
<a-range-picker v-model="formModel.dateRange" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item field="cardPass" label="卡密">
<a-input
v-model="formModel.cardPass"
placeholder="请输入卡密"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-col>
<a-divider style="height: 42px" direction="vertical" />
<a-col flex="172px" style="text-align: right">
<a-space direction="vertical" :size="18">
<a-space direction="horizontal" :size="18">
<a-button type="primary" @click="search">
<template #icon>
<icon-search />
</template>
搜索
</a-button>
<a-button @click="reset">
<template #icon>
<icon-refresh />
</template>
重置
</a-button>
</a-space>
<a-space direction="horizontal" :size="18">
<a-button
type="secondary"
status="warning"
@click="downloadDataList"
>
<template #icon>
<icon-download />
</template>
下载
</a-button>
</a-space>
</a-space>
</a-col>
</a-row>
<a-divider style="margin-top: 0" />
<a-table
:loading="loading"
:pagination="{
current: pagination.current,
pageSize: pagination.pageSize,
total: pagination.total,
pageSizeOptions: [10, 20, 50, 100],
showPageSize: true,
showTotal: true
}"
:columns="columns"
:data="renderData"
:bordered="false"
column-resizable:bordered="{cell:true}"
@page-change="onPageChange"
@page-size-change="onPageSizeChange"
>
<template #index="{ rowIndex }">
{{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
</template>
<template #status="{ record }">
<a-space>
<a-tag
:key="record.status"
:color="getStatusColorMap(record.status).color"
size="small"
>
{{ getStatusColorMap(record.status).text }}
</a-tag>
<a-tag
v-if="record.status === 0 || record.status === 16"
color="gray"
size="small"
>
{{ record.remark }}
</a-tag>
<a-tag
v-if="[1, 2].includes(record.notifyStatus)"
size="small"
:color="record.notifyStatus === 1 ? 'green' : 'red'"
>
回调{{ record.notifyStatus === 1 ? '成功' : '失败' }}
</a-tag>
</a-space>
</template>
<template #operations="{ record }">
<a-space size="small">
<a-tooltip content="详情">
<a-button
size="small"
@click="showRechargeHistory(record.orderNo)"
>
<template #icon>
<icon-list />
</template>
</a-button>
</a-tooltip>
<a-popconfirm
v-if="checkTokenFromIframe() && record.status === 16"
content="确认重置?"
@ok="() => resetStatus(record.orderNo)"
>
<a-button size="small" status="warning">重置</a-button>
</a-popconfirm>
<a-tooltip content="修正">
<a-button
v-if="checkTokenFromIframe() && record.status === 0"
size="small"
status="success"
@click="showActualAmountModal(record.orderNo, record)"
>
<template #icon>
<icon-refresh />
</template>
</a-button>
</a-tooltip>
<a-tooltip content="回调">
<a-button
v-if="
(checkTokenFromIframe() && record.status === 0) ||
record.status === 1
"
size="small"
status="warning"
@click="callBackOrderManual(record.orderNo)"
>
<template #icon>
<icon-send />
</template>
</a-button>
</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>
</template>
</a-table>
</a-card>
<recharge-history
v-model:visible="state.rechargeHistoryModalVisible"
:order-no="state.selectedOrderNo"
/>
<change-amount
v-model:visible="state.changeAmountModalVisible"
:record="state.currentRecord"
:order-no="state.selectedOrderNo"
/>
</div>
<account-info />
</template>
<script lang="ts" setup>
import { Message, TableColumnData } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import { Pagination } from '@/types/global';
import { onMounted, reactive, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import {
AppleCardRechargeOrderParams,
AppleCardRechargeOrderRecord,
callBackOrderManualAPI,
downloadDataListApi,
modifyStatusToSucceedAPI,
queryAppleCardRechargeOrderList,
resetOrderStatusAPI
} from '@/api/apple-card-recharge-history';
import RechargeHistory from './components/recharge-history.vue';
import ChangeAmount from './components/change-amount.vue';
import { checkTokenFromIframe } from '@/utils/auth';
const route = useRoute();
const { accountID } = route.params;
const basePagination: Pagination = {
current: 1,
pageSize: 20
};
const pagination = reactive({
accountID: accountID as string,
...basePagination
});
const columns: TableColumnData[] = [
{
title: '序号',
dataIndex: 'index',
slotName: 'index'
},
// {
// title: '订单号',
// dataIndex: 'orderNo',
// slotName: 'orderNo'
// },
{
title: '系统订单号',
dataIndex: 'attach'
},
{
title: '商户订单号',
dataIndex: 'merchantId'
},
{
title: '分配账号',
dataIndex: 'accountName',
slotName: 'account'
},
{
title: '卡密',
dataIndex: 'cardPass',
slotName: 'cardPass'
},
{
title: '卡面金额',
dataIndex: 'cardAmount',
slotName: 'cardAmount'
},
{
title: '支付金额',
dataIndex: 'actualAmount',
slotName: 'actualAmount'
},
{
title: '创建时间',
dataIndex: 'createdAt',
slotName: 'createdAt'
},
{
title: '状态',
dataIndex: 'status',
slotName: 'status'
},
{
title: '操作',
dataIndex: 'operations',
slotName: 'operations'
}
];
const generateFormModel = () => {
return {
account: '',
orderNo: '',
attach: '',
cardNo: '',
cardPass: '',
merchantId: '',
dateRange: []
};
};
const { loading, setLoading } = useLoading(true);
const renderData = ref<AppleCardRechargeOrderRecord[]>([]);
const formModel = ref<{
account: string;
orderNo: string;
attach: string;
cardNo: string;
cardPass: string;
merchantId: string;
dateRange: Date[];
}>(generateFormModel());
const state = reactive({
rechargeHistoryModalVisible: false,
selectedOrderNo: '',
changeAmountModalVisible: false,
currentRecord: {} as AppleCardRechargeOrderRecord
});
const fetchData = async (
params: AppleCardRechargeOrderParams = {
current: 1,
pageSize: 20
}
) => {
setLoading(true);
try {
const {
data: { list, total }
} = await queryAppleCardRechargeOrderList(params);
renderData.value = list;
pagination.current = params.current;
pagination.pageSize = params.pageSize;
pagination.total = total;
} catch (err) {
console.error(err);
} finally {
setLoading(false);
}
};
const onPageChange = (current: number) => {
fetchData({ ...pagination, current });
};
const onPageSizeChange = (pageSize: number) => {
fetchData({ ...pagination, pageSize });
};
const search = () => {
fetchData({
...basePagination,
...formModel.value
});
};
const reset = () => {
formModel.value = generateFormModel();
};
const showRechargeHistory = (orderNo: string) => {
state.rechargeHistoryModalVisible = true;
state.selectedOrderNo = orderNo;
};
const getStatusColorMap = (status: number) => {
type colorMap = {
color: string;
text: string;
};
let c: colorMap = {
color: '',
text: ''
};
switch (status) {
case 0:
c = {
color: 'red',
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) => {
await callBackOrderManualAPI({ orderNo });
fetchData({ ...pagination, ...formModel.value });
Message.success('回调成功');
};
const showActualAmountModal = (
orderNo: string,
record: AppleCardRechargeOrderRecord
) => {
state.changeAmountModalVisible = true;
state.selectedOrderNo = orderNo;
state.currentRecord = record;
};
const modifyStatusToSucceed = async (orderNo: string) => {
await modifyStatusToSucceedAPI({ orderNo });
fetchData({ ...pagination, ...formModel.value });
Message.success('处理成功');
};
watch(
() => state.changeAmountModalVisible,
newValue => {
if (newValue === false) {
search();
}
}
);
const resetStatus = (orderNo: string) => {
resetOrderStatusAPI({ orderNo }).then(() => {
Message.success('重置成功');
search();
});
};
onMounted(() => fetchData({ ...pagination }));
const downloadDataList = async () => {
await downloadDataListApi({
...basePagination,
...formModel.value
});
};
<script lang="ts">
import AccountInfo from './account-info.vue';
</script>