2
0

fix:充值记录界面

This commit is contained in:
zhongzm
2025-01-10 14:48:46 +08:00
parent 10153e2c6b
commit 9390aace95
6 changed files with 261 additions and 106 deletions

View File

@@ -10,6 +10,7 @@ const viewEn: any = {
"view.billing": "Billing", "view.billing": "Billing",
"view.billing_histories": "Historical", "view.billing_histories": "Historical",
"view.billing_Rechargehistory":"Recharge history", "view.billing_Rechargehistory":"Recharge history",
"view.billing_packagehistories":"Package history",
"view.billing_Internetdetails":"Internet details", "view.billing_Internetdetails":"Internet details",
"view.billing_billservice":"Bill service", "view.billing_billservice":"Bill service",
"view.set-meal": "Package", "view.set-meal": "Package",
@@ -564,6 +565,22 @@ const local: any = {
amount:"Amount", amount:"Amount",
Payment:"Payment Method", Payment:"Payment Method",
recharge:"Recharge History", recharge:"Recharge History",
type:"Type",
status:"Status",
rechargeType:"Recharge",
packageType:"Package",
paid:"Paid",
unpaid:"Unpaid",
},
packagehistories: {
title: 'Package History',
orderdate: 'Order Date',
amount: 'Amount',
type: 'Type',
status: 'Status',
packageType: 'Package',
paid: 'Paid',
unpaid: 'Unpaid'
}, },
cdrlrecords:{ cdrlrecords:{
devicename:"Device name", devicename:"Device name",

View File

@@ -11,6 +11,7 @@ const viewZh: any = {
"view.billing_billservice":"账单服务", "view.billing_billservice":"账单服务",
"view.billing_histories": "历史查询", "view.billing_histories": "历史查询",
"view.billing_Rechargehistory":"充值记录", "view.billing_Rechargehistory":"充值记录",
"view.billing_packagehistories":"套餐记录",
"view.billing_Internetdetails":"上网详单", "view.billing_Internetdetails":"上网详单",
"view.set-meal": "套餐", "view.set-meal": "套餐",
"view.userInfo":"个人信息", "view.userInfo":"个人信息",
@@ -564,6 +565,22 @@ const local:any = {
amount:"充值金额", amount:"充值金额",
Payment:"充值方式", Payment:"充值方式",
recharge:"充值记录", recharge:"充值记录",
type:"类型",
status:"状态",
rechargeType:"充值",
packageType:"套餐",
paid:"已支付",
unpaid:"未支付",
},
packagehistories: {
title: '套餐历史',
orderdate: '订单时间',
amount: '金额',
type: '类型',
status: '状态',
packageType: '套餐',
paid: '已支付',
unpaid: '未支付'
}, },
cdrlrecords:{ cdrlrecords:{
devicename:"设备名称", devicename:"设备名称",

View File

@@ -144,5 +144,20 @@ export function fetchBillHistory(params: Api.Bill.BillQueryParams) {
params params
}); });
} }
/** Get recharge history records */
export function fetchRechargeHistory(params: Api.Recharge.RechargeQueryParams) {
return request<Api.Recharge.RechargeListResponse>({
url: '/u/order/rechargePage',
method: 'get',
params
});
}
/** Get package history records */
export function fetchPackageHistory(params: Api.Package.PackageHistoryQueryParams) {
return request<Api.Package.PackageHistoryListResponse>({
url: '/u/order/packagePage',
method: 'get',
params
});
}

138
src/typings/api.d.ts vendored
View File

@@ -77,6 +77,7 @@ declare namespace Api {
access_token: string; access_token: string;
refreshToken: string; refreshToken: string;
} }
/** User info */ /** User info */
interface UserInfo { interface UserInfo {
user: User | null; user: User | null;
@@ -104,7 +105,7 @@ declare namespace Api {
delFlag: string; delFlag: string;
loginIp: string; loginIp: string;
loginDate: string; loginDate: string;
birthDate:string; birthDate: string;
dept: Department.Dept; dept: Department.Dept;
roles: Role[]; roles: Role[];
roleId: string; roleId: string;
@@ -139,10 +140,11 @@ declare namespace Api {
authType: string; authType: string;
wanfiRedirectParams: any; wanfiRedirectParams: any;
} }
interface RegisterBody{
interface RegisterBody {
username: string; username: string;
password: string; password: string;
authType:string; authType: string;
email: string; email: string;
fullName?: string; fullName?: string;
age: number; age: number;
@@ -150,24 +152,27 @@ declare namespace Api {
sex?: string; sex?: string;
phonenumber?: string; phonenumber?: string;
} }
interface EmailCaptcha{
email:string; interface EmailCaptcha {
email: string;
} }
interface CheckBody{
interface CheckBody {
username?: string; username?: string;
email?: string; email?: string;
phonenumber?:string; phonenumber?: string;
authType: string; authType: string;
} }
interface ChangeInfoBody{
userId:number; interface ChangeInfoBody {
userId: number;
userName: string; userName: string;
nickName?: string|undefined; nickName?: string | undefined;
email: string; email: string;
phonenumber?: string|undefined; phonenumber?: string | undefined;
sex?: string|undefined; sex?: string | undefined;
birthDate?:string|undefined; birthDate?: string | undefined;
age?:number; age?: number;
} }
} }
@@ -259,7 +264,7 @@ declare namespace Api {
/** user search params */ /** user search params */
type UserSearchParams = Partial< type UserSearchParams = Partial<
Pick<Auth.User, 'userName' | 'nickName' | 'phonenumber' | 'status' | 'sex' | 'email' | 'deptId'> & Pick<Auth.User, 'userName' | 'nickName' | 'phonenumber' | 'status' | 'sex' | 'email' | 'deptId'> &
CommonSearchParams CommonSearchParams
>; >;
/** user list */ /** user list */
@@ -520,6 +525,7 @@ declare namespace Api {
total: number; total: number;
rows: DeviceInfo[]; rows: DeviceInfo[];
} }
interface HistoricalDeviceInfo { interface HistoricalDeviceInfo {
id: number; id: number;
clientName: string; clientName: string;
@@ -552,6 +558,7 @@ declare namespace Api {
/** Last seen time */ /** Last seen time */
last_seen_time: string; last_seen_time: string;
} }
interface CDRRecord { interface CDRRecord {
/** Record ID */ /** Record ID */
id: number; id: number;
@@ -599,40 +606,42 @@ declare namespace Api {
data: PackageItem[]; data: PackageItem[];
total?: number; total?: number;
} }
interface OrderSubmitParams { interface OrderSubmitParams {
packageId: string; packageId: string;
type: 0; // 限定为字面量类型 0 type: 0; // 限定为字面量类型 0
} }
}
namespace Order { /** Package history record information */
/** Order type enum */ interface PackageHistoryRecord {
type OrderType = 0 | 1 | 2; // 根据实际需要添加其他类型 id: string;
delFlag: boolean;
/** Base order params */ createBy: number;
interface BaseOrderParams { createTime: string;
type: OrderType; updateBy: number;
} updateTime: string;
userId: number;
/** Package order params */
interface PackageOrderParams extends BaseOrderParams {
type: 0;
packageId: string; packageId: string;
paymentId: string | null;
orderNo: string | null;
type: number; // 0 表示套餐
orderAmount: string;
status: number; // 0未支付1已支付
} }
/** Recharge order params */ /** Package history list response */
interface RechargeOrderParams extends BaseOrderParams { interface PackageHistoryListResponse {
type: 1; rows: PackageHistoryRecord[];
orderAmount: number; total: number;
} }
/** Combined order params type */ /** Package history query parameters */
type SubmitOrderParams = PackageOrderParams | RechargeOrderParams; interface PackageHistoryQueryParams {
pageNum: number;
pageSize: number;
}
} }
/** /**
* Namespace Bill * Namespace Bill
* *
@@ -662,4 +671,59 @@ declare namespace Api {
pageSize: number; pageSize: number;
} }
} }
namespace Recharge {
/** Recharge record information */
interface RechargeRecord {
id: string;
delFlag: boolean;
createBy: number;
createTime: string;
updateBy: number;
updateTime: string;
userId: number;
packageId: string | null;
paymentId: string | null;
orderNo: string | null;
type: number;
orderAmount: string;
status: number;
}
/** Recharge list response */
interface RechargeListResponse {
rows: RechargeRecord[];
total: number;
}
/** Recharge query parameters */
interface RechargeQueryParams {
pageNum: number;
pageSize: number;
}
}
namespace Order {
/** Order type enum */
type OrderType = 0 | 1 | 2; // 根据实际需要添加其他类型
/** Base order params */
interface BaseOrderParams {
type: OrderType;
}
/** Package order params */
interface PackageOrderParams extends BaseOrderParams {
type: 0;
packageId: string;
}
/** Recharge order params */
interface RechargeOrderParams extends BaseOrderParams {
type: 1;
orderAmount: number;
}
/** Combined order params type */
type SubmitOrderParams = PackageOrderParams | RechargeOrderParams;
}
} }

View File

@@ -92,6 +92,7 @@ declare global {
const expect: typeof import('vitest')['expect'] const expect: typeof import('vitest')['expect']
const extendRef: typeof import('@vueuse/core')['extendRef'] const extendRef: typeof import('@vueuse/core')['extendRef']
const extractTabsByAllRoutes: typeof import('../store/modules/tab/shared')['extractTabsByAllRoutes'] const extractTabsByAllRoutes: typeof import('../store/modules/tab/shared')['extractTabsByAllRoutes']
const fetchBillHistory: typeof import('../service/api/auth')['fetchBillHistory']
const fetchCDRHistory: typeof import('../service/api/auth')['fetchCDRHistory'] const fetchCDRHistory: typeof import('../service/api/auth')['fetchCDRHistory']
const fetchCurrentDevices: typeof import('../service/api/auth')['fetchCurrentDevices'] const fetchCurrentDevices: typeof import('../service/api/auth')['fetchCurrentDevices']
const fetchCustomBackendError: typeof import('../service/api/auth')['fetchCustomBackendError'] const fetchCustomBackendError: typeof import('../service/api/auth')['fetchCustomBackendError']
@@ -102,7 +103,9 @@ declare global {
const fetchHistoricalDevices: typeof import('../service/api/auth')['fetchHistoricalDevices'] const fetchHistoricalDevices: typeof import('../service/api/auth')['fetchHistoricalDevices']
const fetchIsRouteExist: typeof import('../service/api/route')['fetchIsRouteExist'] const fetchIsRouteExist: typeof import('../service/api/route')['fetchIsRouteExist']
const fetchLogin: typeof import('../service/api/auth')['fetchLogin'] const fetchLogin: typeof import('../service/api/auth')['fetchLogin']
const fetchPackageHistory: typeof import('../service/api/auth')['fetchPackageHistory']
const fetchPackageList: typeof import('../service/api/auth')['fetchPackageList'] const fetchPackageList: typeof import('../service/api/auth')['fetchPackageList']
const fetchRechargeHistory: typeof import('../service/api/auth')['fetchRechargeHistory']
const fetchRefreshToken: typeof import('../service/api/auth')['fetchRefreshToken'] const fetchRefreshToken: typeof import('../service/api/auth')['fetchRefreshToken']
const fetchRegister: typeof import('../service/api/auth')['fetchRegister'] const fetchRegister: typeof import('../service/api/auth')['fetchRegister']
const filterAuthRoutesByRoles: typeof import('../store/modules/route/shared')['filterAuthRoutesByRoles'] const filterAuthRoutesByRoles: typeof import('../store/modules/route/shared')['filterAuthRoutesByRoles']

View File

@@ -1,100 +1,136 @@
<script setup lang="ts" xmlns="http://www.w3.org/1999/html"> <script setup lang="ts">
import { ref, h } from 'vue' import { ref, computed, onMounted } from 'vue'
import type { TableColumnsType } from 'ant-design-vue' import type { TableColumnsType } from 'ant-design-vue'
import { Tag as ATag, Table as ATable } from 'ant-design-vue' import { Tag as ATag, Table as ATable } from 'ant-design-vue'
import {useI18n} from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { fetchRechargeHistory } from '@/service/api/auth';
import { useWindowSize } from '@vueuse/core';
const router = useRouter(); const router = useRouter();
const handleBack = () => { const handleBack = () => {
router.push('/billing/billservice'); router.push('/billing/billservice');
}; };
const {t} = useI18n(); const { t } = useI18n();
interface RechargeRecord { const rechargeData = ref<Api.Recharge.RechargeRecord[]>([]);
id: number const total = ref(0);
date: string
amount: number
paymentMethod: string
}
// 模拟充值记录数据 const { width } = useWindowSize();
const rechargeData = ref<RechargeRecord[]>([ const isMobile = computed(() => width.value < 768);
{
id: 1, const formatDateTime = (dateTimeString: string) => {
date: '2024-03-15', if (!dateTimeString) return '';
amount: 500, const date = new Date(dateTimeString);
paymentMethod: '支付宝' return date.toLocaleString('zh-CN', {
}, year: 'numeric',
{ month: '2-digit',
id: 2, day: '2-digit',
date: '2024-03-10', hour: '2-digit',
amount: 200, minute: '2-digit',
paymentMethod: '微信支付' second: '2-digit',
}, hour12: false
{ });
id: 3, };
date: '2024-03-05',
amount: 1000, const getRechargeData = async () => {
paymentMethod: '银行卡' try {
}, const response = await fetchRechargeHistory({
{ pageNum: 1,
id: 4, pageSize: 10
date: '2024-02-28', });
amount: 300, console.log('API Response:', response);
paymentMethod: '支付宝' if (response?.data?.rows) {
}, console.log('Setting data:', response.data.rows);
{ rechargeData.value = response.data.rows;
id: 5, total.value = response.data.total;
date: '2024-02-20', }
amount: 600, } catch (error) {
paymentMethod: '微信支付' console.error('Failed to fetch recharge history:', error);
} }
]) };
const columns: TableColumnsType = [ onMounted(() => {
getRechargeData();
});
const columns = computed<TableColumnsType>(() => [
{ {
title: t('page.Rechargehistory.topupdate'), title: t('page.Rechargehistory.topupdate'),
dataIndex: 'date', dataIndex: 'createTime',
key: 'date' key: 'createTime',
responsive: ['md'],
customRender: ({ text }) => text ? formatDateTime(text) : ''
}, },
{ {
title: t('page.Rechargehistory.amount'), title: t('page.Rechargehistory.amount'),
dataIndex: 'amount', dataIndex: 'orderAmount',
key: 'amount', key: 'orderAmount',
customRender: ({ text }: { text: number }) => `¥${text}` customRender: ({ text }: { text: string }) => {
const formattedAmount = Number(text).toFixed(2);
return `¥${formattedAmount}`;
}
}, },
{ {
title: t('page.Rechargehistory.Payment'), title: t('page.Rechargehistory.type'),
dataIndex: 'paymentMethod', dataIndex: 'type',
key: 'paymentMethod' key: 'type',
customRender: ({ text }: { text: number }) => {
return h(ATag, {
color: text === 1 ? 'blue' : 'green'
}, {
default: () => text === 1 ? t('page.Rechargehistory.rechargeType') : t('page.Rechargehistory.packageType')
})
}
},
{
title: t('page.Rechargehistory.status'),
dataIndex: 'status',
key: 'status',
customRender: ({ text }: { text: number }) => {
return h(ATag, {
color: text === 1 ? 'success' : 'warning'
}, {
default: () => text === 1 ? t('page.Rechargehistory.paid') : t('page.Rechargehistory.unpaid')
})
}
} }
] ]);
</script> </script>
<template> <template>
<div class="p-4"> <div class="p-4">
<div class="text-lg font-bold mb-4 flex justify-between items-center"> <div class="text-lg font-bold mb-4 flex justify-between items-center">
<span>{{t('page.Rechargehistory.recharge')}}</span> <span>{{ t('page.Rechargehistory.recharge') }}</span>
<a-button @click="handleBack"> <a-button @click="handleBack">
{{ t('page.login.common.back') }} {{ t('page.login.common.back') }}
</a-button> </a-button>
</div> </div>
<div> <div>
<ATable <ATable
:columns="columns" :columns="columns"
:data-source="rechargeData" :data-source="rechargeData"
:row-key="(record: RechargeRecord) => record.id" :row-key="(record: Api.Recharge.RechargeRecord) => record.id"
:pagination="{ :pagination="{
pageSize: 5, pageSize: 5,
total: rechargeData.length, total: total,
showTotal: (total: number) => `${total}`, showTotal: (total: number) => `${total}`,
showSizeChanger: true, showSizeChanger: true,
showQuickJumper: true, showQuickJumper: true,
pageSizeOptions: ['5', '10', '20', '50'] pageSizeOptions: ['5', '10', '20', '50']
}" }"
/> >
</div> <template #expandedRowRender="{ record }">
<div class="pl-4">
<div v-if="isMobile" class="mb-2">
<strong>{{ t('page.Rechargehistory.topupdate') }}:</strong>
{{ formatDateTime(record.createTime) }}
</div>
</div>
</template>
</ATable>
</div>
</div> </div>
</template> </template>
@@ -111,4 +147,7 @@ const columns: TableColumnsType = [
.font-bold { .font-bold {
font-weight: bold; font-weight: bold;
} }
.pl-4 {
padding-left: 1rem;
}
</style> </style>