Feature/0723/zr #8
+17
-4
@@ -8,7 +8,7 @@ export interface TournamentAdminOrderPageVO {
|
||||
/** 订单编号 */
|
||||
orderNo: string;
|
||||
/** 选手ID */
|
||||
uniqueId: number;
|
||||
uniqueId: string;
|
||||
/** 赛事名称 */
|
||||
name: string;
|
||||
/** 选手名称 */
|
||||
@@ -36,9 +36,9 @@ export interface TournamentAdminOrderPageVO {
|
||||
/** 支付时间;yyyy.MM.dd HH:mm:ss */
|
||||
payTime: string;
|
||||
/** 订单状态;1=已支付,2=部分退款,3=全部退款,4=已关闭,-1=其他 */
|
||||
orderStatus: number;
|
||||
orderStatus: string;
|
||||
/** 退款状态;1=无退款,2=退款成功,3=退款失败,-1=其他 */
|
||||
refundStatus: number;
|
||||
refundStatus: string;
|
||||
}
|
||||
|
||||
/** 订单列表查询参数 */
|
||||
@@ -62,11 +62,24 @@ export interface OrderListQueryParams {
|
||||
status?: string;
|
||||
/**
|
||||
* 退款状态
|
||||
* 不传=全部、0=退款失败,1=退款成功
|
||||
* 不传=全部、2=退款成功,3=退款失败
|
||||
*/
|
||||
refundStatus?: string;
|
||||
}
|
||||
|
||||
/** 订单分页数据(含列表统计字段) */
|
||||
export interface OrderPageData extends PageData<TournamentAdminOrderPageVO> {
|
||||
/** 扩展数据 */
|
||||
exData: {
|
||||
/** 总订单金额(已支付) */
|
||||
totalOrderAmount: string;
|
||||
/** 总实付金额 */
|
||||
totalActualAmount: string;
|
||||
/** 总退款金额 */
|
||||
totalRefundAmount: string;
|
||||
};
|
||||
}
|
||||
|
||||
/** 分页数据 */
|
||||
export interface PageData<T> {
|
||||
total: number;
|
||||
|
||||
@@ -180,3 +180,13 @@ export function usePagination(options: UsePaginationOptions = {}): UsePagination
|
||||
refresh,
|
||||
};
|
||||
}
|
||||
|
||||
/** 将接口返回的分页 total 同步到 pagination(支持 number / 数字字符串,含 0) */
|
||||
export function syncPaginationTotal(
|
||||
pagination: Pick<UsePaginationReturn, 'setTotal'>,
|
||||
total: unknown,
|
||||
): void {
|
||||
if (total == null || total === '') return;
|
||||
const n = Number(total);
|
||||
if (Number.isFinite(n)) pagination.setTotal(n);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ function renderBodyCell({
|
||||
|
||||
// 跳转地址列
|
||||
if (column.dataIndex === 'linkUrl') {
|
||||
return <span>{text || '-'}</span>;
|
||||
return <span>{text || '--'}</span>;
|
||||
}
|
||||
|
||||
// 展示时间列
|
||||
@@ -100,7 +100,7 @@ function renderBodyCell({
|
||||
if (column.key === 'action') {
|
||||
const isEnabled = record.status === '1';
|
||||
const { canEdit, canToggleStatus, canDelete } = permissions;
|
||||
if (!canEdit && !canToggleStatus && !canDelete) return <span>-</span>;
|
||||
if (!canEdit && !canToggleStatus && !canDelete) return <span>--</span>;
|
||||
|
||||
return (
|
||||
<Space>
|
||||
|
||||
@@ -243,12 +243,12 @@ export function useBannerModel() {
|
||||
|
||||
// ===== 渲染工具 =====
|
||||
const renderJumpType = (type: string) => {
|
||||
const info = JUMP_TYPE_MAP[type] || { label: type || '-', tone: 'default' as const };
|
||||
const info = JUMP_TYPE_MAP[type] || { label: type || '--', tone: 'default' as const };
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
};
|
||||
|
||||
const renderStatus = (status: string) => {
|
||||
const info = STATUS_MAP[status] || { label: status || '-', tone: 'default' as const };
|
||||
const info = STATUS_MAP[status] || { label: status || '--', tone: 'default' as const };
|
||||
return h(StatusTag, { label: info.label, tone: info.tone, dimmed: info.dimmed });
|
||||
};
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ export default defineComponent({
|
||||
|
||||
/** 格式化时间范围 */
|
||||
const formatRange = (start: string, end: string) => {
|
||||
if (!start && !end) return '-';
|
||||
if (!start && !end) return '--';
|
||||
return `${start || '?'} ~ ${end || '?'}`;
|
||||
};
|
||||
|
||||
@@ -98,25 +98,25 @@ export default defineComponent({
|
||||
<div class={styles.section}>
|
||||
<div class={styles.sectionTitle}>基础信息</div>
|
||||
<Descriptions size="small" bordered column={3} class={styles.desc}>
|
||||
<Descriptions.Item label="赛事名称">{d.name || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="赛事名称">{d.name || '--'}</Descriptions.Item>
|
||||
<Descriptions.Item label="赛事时间" span={2}>
|
||||
{formatRange(d.startTimeBegin, d.startTimeEnd)}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="赛事说明" span={3}>
|
||||
{d.descr || '-'}
|
||||
{d.descr || '--'}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="报名起止时间">
|
||||
{formatRange(d.signupTimeBegin, d.signupTimeEnd)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="取消报名截止时间" span={2}>
|
||||
{d.signupTimeEnd || '-'}
|
||||
{d.signupTimeEnd || '--'}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="省市区">{d.venueArea || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="地点">{d.venue || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="场地编号">{d.venueNo || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="省市区">{d.venueArea || '--'}</Descriptions.Item>
|
||||
<Descriptions.Item label="地点">{d.venue || '--'}</Descriptions.Item>
|
||||
<Descriptions.Item label="场地编号">{d.venueNo || '--'}</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="公开活动">
|
||||
{boolText(d.isPublic, '在首页展示赛事', '非公开')}
|
||||
@@ -128,15 +128,15 @@ export default defineComponent({
|
||||
{boolText(d.isRequireIdCardImg, '需要提供', '无需提供')}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="创建时间">{d.createTime || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="创建人">{d.createNickname || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="创建时间">{d.createTime || '--'}</Descriptions.Item>
|
||||
<Descriptions.Item label="创建人">{d.createNickname || '--'}</Descriptions.Item>
|
||||
<Descriptions.Item label="状态">待审核</Descriptions.Item>
|
||||
<Descriptions.Item label="报名人数">{d.signupCount || '0'}</Descriptions.Item>
|
||||
<Descriptions.Item label="取消报名人数" span={1}>
|
||||
{d.dropoutCount || '0'}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="最大人数">{d.totalLimit || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="最大人数">{d.totalLimit || '--'}</Descriptions.Item>
|
||||
<Descriptions.Item label="对岸数量">{d.matchTotalCount || '0'}</Descriptions.Item>
|
||||
<Descriptions.Item label="已完成对岸数量">{d.matchCount || '0'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
|
||||
@@ -32,7 +32,7 @@ const PAGE_SIZE = 10;
|
||||
/** 渲染身份证图片(cover 填充,与封面显示方式一致) */
|
||||
const renderIdImages = (imgList: string[], singleImg: string) => {
|
||||
const urls = imgList.length > 0 ? imgList : singleImg ? [singleImg] : [];
|
||||
if (urls.length === 0) return <span>-</span>;
|
||||
if (urls.length === 0) return <span>--</span>;
|
||||
return (
|
||||
<Image.PreviewGroup>
|
||||
<div class={styles.idImageGrid}>
|
||||
@@ -63,14 +63,14 @@ const PLAYER_COLUMNS = [
|
||||
key: 'idCard',
|
||||
width: 180,
|
||||
customRender: ({ record }: { record?: TournamentAdminInfoSignupVO }) =>
|
||||
record?.idCard ? record.idCard : <span>-</span>,
|
||||
record?.idCard ? record.idCard : <span>--</span>,
|
||||
|
|
||||
},
|
||||
{
|
||||
title: '证件图片',
|
||||
key: 'idCardImgs',
|
||||
width: 280,
|
||||
customRender: ({ record }: { record?: TournamentAdminInfoSignupVO }) =>
|
||||
record ? renderIdImages(record.idCardImgList || [], record.idCardImg || '') : <span>-</span>,
|
||||
record ? renderIdImages(record.idCardImgList || [], record.idCardImg || '') : <span>--</span>,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -193,7 +193,7 @@ export default defineComponent({
|
||||
<Descriptions.Item label="省市区">{detail.value.venueArea}</Descriptions.Item>
|
||||
<Descriptions.Item label="地点">{detail.value.venue}</Descriptions.Item>
|
||||
<Descriptions.Item label="场地编号" class={styles.statCell}>
|
||||
{detail.value.venueNo || '-'}
|
||||
{detail.value.venueNo || '--'}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="公开活动">
|
||||
@@ -217,7 +217,7 @@ export default defineComponent({
|
||||
label="最大人数"
|
||||
class={[styles.statCell, styles.statCellNoWrap]}
|
||||
>
|
||||
{detail.value.totalLimit || '-'}
|
||||
{detail.value.totalLimit || '--'}
|
||||
</Descriptions.Item>
|
||||
|
||||
<Descriptions.Item label="总对阵数">
|
||||
|
||||
@@ -159,7 +159,7 @@ export default defineComponent({
|
||||
查看
|
||||
</a>
|
||||
) : (
|
||||
<span>-</span>
|
||||
<span>--</span>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Modal, message } from 'ant-design-vue';
|
||||
import { useState, useDebounce } from '@/hooks';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { useEffect } from '@/hooks/useEffect';
|
||||
import { usePagination } from '@/hooks/usePagination';
|
||||
import { usePagination, syncPaginationTotal } from '@/hooks/usePagination';
|
||||
import { hasValue, isEmptyValue, safeTransform } from '@/utils';
|
||||
import type { TournamentAdminVO, EventListQueryParams, PageData, ApiResult } from './services';
|
||||
import { getEventList, toggleEventOnline } from './services';
|
||||
@@ -78,9 +78,8 @@ export function useEventListModel() {
|
||||
|
||||
// 同步分页总条数
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
}, [data]);
|
||||
syncPaginationTotal(pagination, listData.value?.total);
|
||||
}, [listData]);
|
||||
|
||||
const hasFilter = computed(() => {
|
||||
const f = filterForm;
|
||||
|
||||
@@ -30,11 +30,10 @@ const LogContentCell = defineComponent({
|
||||
};
|
||||
let observer: ResizeObserver | null = null;
|
||||
useEffect(() => {
|
||||
const el = textRef.value;
|
||||
if (!el) return;
|
||||
if (!textRef.value) return;
|
||||
nextTick(checkOverflow);
|
||||
|
chenzhen
commented
何必呢 const el = textRef.value; 何必呢 const el = textRef.value;
|
||||
observer = new ResizeObserver(checkOverflow);
|
||||
observer.observe(el);
|
||||
observer.observe(textRef.value);
|
||||
return () => {
|
||||
observer?.disconnect();
|
||||
observer = null;
|
||||
@@ -96,13 +95,13 @@ export default defineComponent({
|
||||
}) => {
|
||||
if (column.key === 'content') {
|
||||
const raw = text || '';
|
||||
return raw ? <LogContentCell text={raw} /> : <span>-</span>;
|
||||
return raw ? <LogContentCell text={raw} /> : <span>--</span>;
|
||||
}
|
||||
// 有 customRender 的列使用其渲染函数(如操作类型/操作来源的代码→中文映射)
|
||||
if (column.customRender) {
|
||||
return column.customRender({ text, record, index, column });
|
||||
}
|
||||
return <span>{text || '-'}</span>;
|
||||
return <span>{text || '--'}</span>;
|
||||
};
|
||||
|
||||
return () => (
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { type VNodeChild } from 'vue';
|
||||
import { ACTION_TYPE_MAP, ACTION_SOURCE_MAP } from './config';
|
||||
|
||||
const renderType = (text: string): string => ACTION_TYPE_MAP[text] || text || '-';
|
||||
const renderType = (text: string): string => ACTION_TYPE_MAP[text] || text || '--';
|
||||
|
||||
const renderSource = (text: string): string => ACTION_SOURCE_MAP[text] || text || '-';
|
||||
const renderSource = (text: string): string => ACTION_SOURCE_MAP[text] || text || '--';
|
||||
|
||||
/**
|
||||
* 操作日志页 - 表格列配置(视图层)
|
||||
|
||||
@@ -2,7 +2,11 @@ import { computed, reactive, toRef, Ref, type UnwrapRef } from 'vue';
|
||||
import { useDebounce } from '@/hooks';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { useEffect } from '@/hooks/useEffect';
|
||||
import { usePagination, type UsePaginationReturn } from '@/hooks/usePagination';
|
||||
import {
|
||||
usePagination,
|
||||
syncPaginationTotal,
|
||||
type UsePaginationReturn,
|
||||
} from '@/hooks/usePagination';
|
||||
import { hasValue, isEmptyValue, safeTransform } from '@/utils';
|
||||
import {
|
||||
getOperationLogs,
|
||||
@@ -102,9 +106,8 @@ export function useLogModel() {
|
||||
|
||||
// 同步分页总条数
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
}, [data]);
|
||||
syncPaginationTotal(pagination, listData.value?.total);
|
||||
}, [listData]);
|
||||
|
||||
const hasFilter = computed(() => {
|
||||
return (
|
||||
|
||||
@@ -24,7 +24,7 @@ const GENDER_MAP: Record<string, string> = { '1': '男', '2': '女' };
|
||||
const formatGender = (v: string) => GENDER_MAP[v] ?? v;
|
||||
const formatMoney = (v: string) => {
|
||||
const n = parseFloat(v);
|
||||
return isNaN(n) ? '-' : `${n.toFixed(2)}`;
|
||||
return isNaN(n) ? '--' : `${n.toFixed(2)}`;
|
||||
};
|
||||
|
||||
const PLAYER_COLUMNS = [
|
||||
@@ -55,7 +55,7 @@ const PLAYER_COLUMNS = [
|
||||
: record.idCardImg
|
||||
? [record.idCardImg]
|
||||
: [];
|
||||
if (!urls.length) return <span>-</span>;
|
||||
if (!urls.length) return <span>--</span>;
|
||||
return (
|
||||
<Space>
|
||||
{urls.map((src) => (
|
||||
@@ -102,7 +102,8 @@ const PLAYER_COLUMNS = [
|
||||
key: 'refundAmount',
|
||||
width: 100,
|
||||
align: 'right' as const,
|
||||
customRender: ({ text }: { text: string }) => (text === '-' || !text ? '-' : formatMoney(text)),
|
||||
customRender: ({ text }: { text: string }) =>
|
||||
text === '--' || !text ? '--' : formatMoney(text),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -160,7 +161,7 @@ export default defineComponent({
|
||||
return records.some((r) => {
|
||||
if (!r) return false;
|
||||
const hasRefundAmount = parseFloat(r.refundAmount || '0') > 0;
|
||||
const hasRefundTime = r.refundTime && r.refundTime !== '-';
|
||||
const hasRefundTime = r.refundTime && r.refundTime !== '--';
|
||||
return hasRefundAmount && !hasRefundTime;
|
||||
});
|
||||
});
|
||||
@@ -329,11 +330,11 @@ export default defineComponent({
|
||||
</span>
|
||||
</div>
|
||||
<div>申请时间:{r.refundApplyTime}</div>
|
||||
<div>完款时间:{r.refundTime || '-'}</div>
|
||||
<div>完款时间:{r.refundTime || '--'}</div>
|
||||
</div>
|
||||
<div class={styles.refundCol}>
|
||||
<div>退款方式:{r.refundMethod}</div>
|
||||
<div>第三方退款单号:{r.refundOutTradeNo || '-'}</div>
|
||||
<div>第三方退款单号:{r.refundOutTradeNo || '--'}</div>
|
||||
<div>已退金额:¥{formatMoney(r.refundedAmount)}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -230,21 +230,15 @@ export default defineComponent({
|
||||
<div class={pageStyles.summary}>
|
||||
<span class={pageStyles.summaryItem}>
|
||||
<span class={pageStyles.summaryLabel}>总订单金额(已支付):</span>
|
||||
<span class={pageStyles.summaryValue}>
|
||||
{summary.value.totalOrderAmount.toFixed(2)}元
|
||||
</span>
|
||||
<span class={pageStyles.summaryValue}>{summary.value.totalOrderAmount}元</span>
|
||||
</span>
|
||||
<span class={pageStyles.summaryItem}>
|
||||
<span class={pageStyles.summaryLabel}>总实付金额:</span>
|
||||
<span class={pageStyles.summaryValue}>
|
||||
{summary.value.totalPaidAmount.toFixed(2)}元
|
||||
</span>
|
||||
<span class={pageStyles.summaryValue}>{summary.value.totalActualAmount}元</span>
|
||||
</span>
|
||||
<span class={pageStyles.summaryItem}>
|
||||
<span class={pageStyles.summaryLabel}>总退款金额:</span>
|
||||
<span class={pageStyles.summaryValue}>
|
||||
{summary.value.totalRefundAmount.toFixed(2)}元
|
||||
</span>
|
||||
<span class={pageStyles.summaryValue}>{summary.value.totalRefundAmount}元</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -49,9 +49,9 @@ export const ORDER_STATUS_OPTIONS = [
|
||||
{ value: '4', label: '超时关闭' },
|
||||
] as const;
|
||||
|
||||
/** 退款状态选项(value 对应 API refundStatus: 不传=全部、0=退款失败,1=退款成功) */
|
||||
/** 退款状态选项(value 对应 API refundStatus: 不传=全部、2=退款成功,3=退款失败) */
|
||||
export const REFUND_STATUS_OPTIONS = [
|
||||
{ value: '', label: '全部' },
|
||||
{ value: '1', label: '退款成功' },
|
||||
{ value: '0', label: '退款失败' },
|
||||
{ value: '2', label: '退款成功' },
|
||||
{ value: '3', label: '退款失败' },
|
||||
] as const;
|
||||
|
||||
@@ -11,6 +11,7 @@ import type {
|
||||
TournamentAdminOrderPageVO,
|
||||
TournamentAdminOrderInfoVO,
|
||||
TournamentAdminOrderInfoPageVO,
|
||||
OrderPageData,
|
||||
PageData,
|
||||
ApiResult,
|
||||
} from '@/api/orders/types';
|
||||
@@ -24,6 +25,7 @@ export type {
|
||||
OrderDetailQueryParams,
|
||||
OrderPlayerListQueryParams,
|
||||
RetryRefundParams,
|
||||
OrderPageData,
|
||||
PageData,
|
||||
ApiResult,
|
||||
} from '@/api/orders/types';
|
||||
@@ -43,7 +45,7 @@ const retryRefund = '/admin/manager/order/retryRefund';
|
||||
/** 订单管理 - 订单分页 */
|
||||
export async function getOrderList(
|
||||
params: OrderListQueryParams,
|
||||
): Promise<ApiResult<PageData<TournamentAdminOrderPageVO>>> {
|
||||
): Promise<ApiResult<OrderPageData>> {
|
||||
return get(orderList, params as Record<string, any>);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { computed, reactive, toRef, Ref, h } from 'vue';
|
||||
import Big from 'big.js';
|
||||
import { StatusTag, type StatusTagTone } from '@/components';
|
||||
import { useDebounce } from '@/hooks';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { useEffect } from '@/hooks/useEffect';
|
||||
import { usePagination } from '@/hooks/usePagination';
|
||||
import { usePagination, syncPaginationTotal } from '@/hooks/usePagination';
|
||||
import { hasValue, isEmptyValue, safeTransform } from '@/utils';
|
||||
import type {
|
||||
TournamentAdminOrderPageVO,
|
||||
OrderListQueryParams,
|
||||
PageData,
|
||||
OrderPageData,
|
||||
ApiResult,
|
||||
} from './services';
|
||||
import { getOrderList } from './services';
|
||||
@@ -23,18 +22,18 @@ import {
|
||||
export { ORDER_STATUS_OPTIONS, REFUND_STATUS_OPTIONS };
|
||||
|
||||
/** 订单状态 StatusTag 映射 */
|
||||
const ORDER_STATUS_MAP: Record<number, { label: string; tone: StatusTagTone }> = {
|
||||
1: { label: '支付成功', tone: 'success' },
|
||||
2: { label: '部分退款', tone: 'orange' },
|
||||
3: { label: '全部退款', tone: 'primary' },
|
||||
4: { label: '已关闭', tone: 'default' },
|
||||
const ORDER_STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||
'1': { label: '支付成功', tone: 'success' },
|
||||
'2': { label: '部分退款', tone: 'orange' },
|
||||
'3': { label: '全部退款', tone: 'primary' },
|
||||
'4': { label: '已关闭', tone: 'default' },
|
||||
};
|
||||
|
||||
/** 退款状态 StatusTag 映射 */
|
||||
const REFUND_STATUS_MAP: Record<number, { label: string; tone: StatusTagTone }> = {
|
||||
1: { label: '无退款', tone: 'default' },
|
||||
2: { label: '退款成功', tone: 'success' },
|
||||
3: { label: '退款失败', tone: 'danger' },
|
||||
const REFUND_STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
|
||||
'1': { label: '无退款', tone: 'default' },
|
||||
'2': { label: '退款成功', tone: 'success' },
|
||||
'3': { label: '退款失败', tone: 'danger' },
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -82,12 +81,12 @@ export function useOrderModel() {
|
||||
data,
|
||||
loading,
|
||||
run: fetchList,
|
||||
} = useRequest<ApiResult<PageData<TournamentAdminOrderPageVO>>>(
|
||||
() => getOrderList(buildQueryParams()),
|
||||
{ refreshDeps: [], formatResult: (res) => res },
|
||||
);
|
||||
} = useRequest<ApiResult<OrderPageData>>(() => getOrderList(buildQueryParams()), {
|
||||
refreshDeps: [],
|
||||
formatResult: (res) => res,
|
||||
});
|
||||
|
||||
const listData = computed<PageData<TournamentAdminOrderPageVO> | undefined>(() => {
|
||||
const listData = computed<OrderPageData | undefined>(() => {
|
||||
const res = data.value;
|
||||
return res ? (res as any).data : undefined;
|
||||
});
|
||||
@@ -95,26 +94,16 @@ export function useOrderModel() {
|
||||
const dataSource = computed(() => listData.value?.list || []);
|
||||
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
}, [data]);
|
||||
syncPaginationTotal(pagination, listData.value?.total);
|
||||
}, [listData]);
|
||||
|
||||
/** 金额汇总(API 直接返回,无需前端累加) */
|
||||
const summary = computed(() => {
|
||||
const list = listData.value?.list || [];
|
||||
let totalOrder = new Big(0);
|
||||
let totalPaid = new Big(0);
|
||||
let totalRefund = new Big(0);
|
||||
|
||||
for (const item of list) {
|
||||
totalOrder = totalOrder.plus(new Big(item.creatorSignupFee || 0));
|
||||
totalPaid = totalPaid.plus(new Big(item.creatorSignupFeeActual || 0));
|
||||
totalRefund = totalRefund.plus(new Big(item.creatorSignupFeeRefund || 0));
|
||||
}
|
||||
|
||||
const d = listData.value;
|
||||
return {
|
||||
totalOrderAmount: totalOrder.toNumber(),
|
||||
totalPaidAmount: totalPaid.toNumber(),
|
||||
totalRefundAmount: totalRefund.toNumber(),
|
||||
totalOrderAmount: d?.exData?.totalOrderAmount || '0',
|
||||
totalActualAmount: d?.exData?.totalActualAmount || '0',
|
||||
totalRefundAmount: d?.exData?.totalRefundAmount || '0',
|
||||
};
|
||||
});
|
||||
|
||||
@@ -189,9 +178,9 @@ export function useOrderModel() {
|
||||
dataIndex: 'orderStatus',
|
||||
key: 'orderStatus',
|
||||
width: 100,
|
||||
customRender: ({ text }: { text: number }) => {
|
||||
customRender: ({ text }: { text: string }) => {
|
||||
const info = ORDER_STATUS_MAP[text] || {
|
||||
label: String(text ?? '-'),
|
||||
label: String(text ?? '--'),
|
||||
tone: 'default' as const,
|
||||
};
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
@@ -203,9 +192,8 @@ export function useOrderModel() {
|
||||
key: 'refundStatus',
|
||||
width: 100,
|
||||
align: 'center' as const,
|
||||
customRender: ({ text }: { text: number }) => {
|
||||
if (text === 1) return h('span', '-');
|
||||
const info = REFUND_STATUS_MAP[text] || { label: String(text), tone: 'default' as const };
|
||||
customRender: ({ text }: { text: string }) => {
|
||||
const info = REFUND_STATUS_MAP[text] || { label: '--', tone: 'default' as const };
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
},
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@ export default defineComponent({
|
||||
|
||||
/** 渲染操作列 */
|
||||
const renderAction = (record: any) => {
|
||||
if (!canToggleStatus) return <span>-</span>;
|
||||
if (!canToggleStatus) return <span>--</span>;
|
||||
|
||||
const isActive = record.status === '1';
|
||||
return (
|
||||
|
||||
@@ -62,7 +62,7 @@ export function useUserColumns() {
|
||||
align: 'center' as const,
|
||||
customRender: ({ text }: { text: string[] }): VNodeChild => {
|
||||
const imgList = Array.isArray(text) ? text : [];
|
||||
if (imgList.length === 0) return '-';
|
||||
if (imgList.length === 0) return '--';
|
||||
return h(
|
||||
Space,
|
||||
{ size: 4 },
|
||||
|
||||
@@ -3,7 +3,11 @@ import { Modal, message } from 'ant-design-vue';
|
||||
import { useState, useDebounce } from '@/hooks';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { useEffect } from '@/hooks/useEffect';
|
||||
import { usePagination, type UsePaginationReturn } from '@/hooks/usePagination';
|
||||
import {
|
||||
usePagination,
|
||||
syncPaginationTotal,
|
||||
type UsePaginationReturn,
|
||||
} from '@/hooks/usePagination';
|
||||
import { hasValue, isEmptyValue, safeTransform } from '@/utils';
|
||||
import {
|
||||
getUserList,
|
||||
@@ -94,9 +98,8 @@ export function useUserModel() {
|
||||
|
||||
// 同步分页总条数
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
}, [data]);
|
||||
syncPaginationTotal(pagination, listData.value?.total);
|
||||
}, [listData]);
|
||||
|
||||
// ===== 计算属性 =====
|
||||
const hasFilter = computed(() => {
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { computed, reactive, toRef, Ref } from 'vue';
|
||||
import { useDebounce, useThrottleFn, useRequest, usePagination, useEffect } from '@/hooks';
|
||||
import {
|
||||
useDebounce,
|
||||
useThrottleFn,
|
||||
useRequest,
|
||||
usePagination,
|
||||
useEffect,
|
||||
syncPaginationTotal,
|
||||
} from '@/hooks';
|
||||
import { getPaymentFlowList, type PaymentFlowVO, type PaymentFlowQueryParams } from './services';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@@ -81,9 +88,8 @@ export function usePaymentsModel() {
|
||||
|
||||
// 同步 total 到 pagination
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
}, [data]);
|
||||
syncPaginationTotal(pagination, listData.value?.total);
|
||||
}, [listData]);
|
||||
|
||||
// ===== 表格列(dataIndex 对齐 API) =====
|
||||
const columns = [
|
||||
@@ -94,7 +100,7 @@ export function usePaymentsModel() {
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: 110,
|
||||
customRender: ({ text }: { text: number }) => PAYMENT_TYPE_MAP[text] || text || '-',
|
||||
customRender: ({ text }: { text: number }) => PAYMENT_TYPE_MAP[text] || text || '--',
|
||||
},
|
||||
{ title: '用户昵称', dataIndex: 'nickname', key: 'nickname', width: 120 },
|
||||
{ title: '手机号', dataIndex: 'phone', key: 'phone', width: 140 },
|
||||
|
||||
@@ -113,7 +113,7 @@ export default defineComponent({
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: 120,
|
||||
customRender: ({ text }: { text: number }) => TRANSACTION_TYPE_MAP[text] || text || '-',
|
||||
customRender: ({ text }: { text: number }) => TRANSACTION_TYPE_MAP[text] || text || '--',
|
||||
},
|
||||
{
|
||||
title: '金额',
|
||||
@@ -162,14 +162,14 @@ export default defineComponent({
|
||||
dataIndex: 'freezeTime',
|
||||
key: 'freezeTime',
|
||||
width: 140,
|
||||
customRender: ({ text }: { text: string }) => text || '-',
|
||||
customRender: ({ text }: { text: string }) => text || '--',
|
||||
},
|
||||
{
|
||||
title: '解冻时间',
|
||||
dataIndex: 'unfreezeTime',
|
||||
key: 'unfreezeTime',
|
||||
width: 140,
|
||||
customRender: ({ text }: { text: string }) => text || '-',
|
||||
customRender: ({ text }: { text: string }) => text || '--',
|
||||
},
|
||||
{
|
||||
title: '关联单号',
|
||||
|
||||
@@ -30,7 +30,7 @@ function renderBodyCell({
|
||||
canViewDetail: boolean;
|
||||
}) {
|
||||
if (column.key === 'action') {
|
||||
if (!canViewDetail) return <span>-</span>;
|
||||
if (!canViewDetail) return <span>--</span>;
|
||||
|
||||
return (
|
||||
<Button type="link" size="small" onClick={() => onViewDetail(record)}>
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
useRequest,
|
||||
usePagination,
|
||||
useEffect,
|
||||
syncPaginationTotal,
|
||||
} from '@/hooks';
|
||||
import { getWalletList, type WalletSummaryVO, type WalletQueryParams } from './services';
|
||||
|
||||
@@ -111,9 +112,8 @@ export function useWalletModel() {
|
||||
|
||||
// 同步 total 到 pagination
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
}, [data]);
|
||||
syncPaginationTotal(pagination, listData.value?.total);
|
||||
}, [listData]);
|
||||
|
||||
// ===== 详情弹窗状态 =====
|
||||
const [detailVisible, setDetailVisible] = useState<boolean>(false);
|
||||
|
||||
@@ -153,14 +153,14 @@ export default defineComponent({
|
||||
const renderItem = (label: string, value: any, isBold = false) => (
|
||||
<div class={styles.descItem}>
|
||||
<span class={styles.descLabel}>{label}</span>
|
||||
<span class={[styles.descValue, isBold ? styles.descValueBold : '']}>{value || '-'}</span>
|
||||
<span class={[styles.descValue, isBold ? styles.descValueBold : '']}>{value || '--'}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
/** 渲染内容区(加载完成后) */
|
||||
const renderContent = () => {
|
||||
const d = detail.value!;
|
||||
const bankCardTypeLabel = d.bankCardType === 1 ? '个人' : d.bankCardType || '-';
|
||||
const bankCardTypeLabel = d.bankCardType === 1 ? '个人' : d.bankCardType || '--';
|
||||
const isPending = d.auditStatus == 0;
|
||||
|
||||
return (
|
||||
@@ -200,7 +200,7 @@ export default defineComponent({
|
||||
<div class={styles.section}>
|
||||
<div class={styles.sectionTitle}>支付信息</div>
|
||||
<div class={styles.descGrid}>
|
||||
{renderItem('到账支付时间:', d.payTime || '-')}
|
||||
{renderItem('到账支付时间:', d.payTime || '--')}
|
||||
{renderItem('订单号:', d.orderNo)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
useRequest,
|
||||
usePagination,
|
||||
useEffect,
|
||||
syncPaginationTotal,
|
||||
} from '@/hooks';
|
||||
import { getWithdrawList, type WithdrawVO, type WithdrawQueryParams } from './services';
|
||||
|
||||
@@ -47,7 +48,7 @@ const PAY_STATUS_MAP: Record<number, { label: string; tone: StatusTagTone }> = {
|
||||
/** 渲染审核状态 StatusTag */
|
||||
export function renderAuditStatus(status: number) {
|
||||
const info = AUDIT_STATUS_MAP[status] || {
|
||||
label: String(status ?? '-'),
|
||||
label: String(status ?? '--'),
|
||||
tone: 'default' as const,
|
||||
};
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
@@ -61,12 +62,12 @@ export function renderPayStatus(status: number) {
|
||||
|
||||
/** 获取审核状态纯文本(详情弹窗用) */
|
||||
export function getAuditStatusText(status: number): string {
|
||||
return AUDIT_STATUS_MAP[status]?.label ?? String(status ?? '-');
|
||||
return AUDIT_STATUS_MAP[status]?.label ?? String(status ?? '--');
|
||||
}
|
||||
|
||||
/** 获取到账状态纯文本(详情弹窗用) */
|
||||
export function getPayStatusText(status: number): string {
|
||||
return PAY_STATUS_MAP[status]?.label ?? String(status ?? '-');
|
||||
return PAY_STATUS_MAP[status]?.label ?? String(status ?? '--');
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
@@ -132,9 +133,8 @@ export function useWithdrawModel() {
|
||||
|
||||
// 同步 total 到 pagination
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
}, [data]);
|
||||
syncPaginationTotal(pagination, listData.value?.total);
|
||||
}, [listData]);
|
||||
|
||||
// ===== 审核弹窗状态 =====
|
||||
const [auditVisible, setAuditVisible] = useState<boolean>(false);
|
||||
|
||||
@@ -11,9 +11,9 @@ const { RangePicker } = DatePicker;
|
||||
*/
|
||||
function renderBodyCell({ column, text }: { column: any; text: any }) {
|
||||
if (column.key === 'type') {
|
||||
return <span>{ACTION_TYPE_MAP[text as number] || text || '-'}</span>;
|
||||
return <span>{ACTION_TYPE_MAP[text as number] || text || '--'}</span>;
|
||||
}
|
||||
return <span>{text || '-'}</span>;
|
||||
return <span>{text || '--'}</span>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@ import dayjs from 'dayjs';
|
||||
import { useDebounce, useThrottleFn } from '@/hooks';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { useEffect } from '@/hooks/useEffect';
|
||||
import { usePagination } from '@/hooks/usePagination';
|
||||
import { usePagination, syncPaginationTotal } from '@/hooks/usePagination';
|
||||
import {
|
||||
getOperationLogList,
|
||||
type SysOperationLogVO,
|
||||
@@ -100,8 +100,7 @@ export function useLogModel() {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
syncPaginationTotal(pagination, (data.value as any)?.data?.total);
|
||||
}, [data]);
|
||||
|
||||
// ===== 表格列配置(字段名对齐 API) =====
|
||||
|
||||
@@ -44,7 +44,10 @@ export default defineComponent({
|
||||
width: 90,
|
||||
align: 'center' as const,
|
||||
customRender: ({ text }: { text: number }) => {
|
||||
const info = STATUS_MAP[text] || { label: String(text ?? '-'), tone: 'default' as const };
|
||||
const info = STATUS_MAP[text] || {
|
||||
label: String(text ?? '--'),
|
||||
tone: 'default' as const,
|
||||
};
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
},
|
||||
},
|
||||
|
||||
@@ -40,7 +40,7 @@ function renderBodyCell({
|
||||
|
||||
if (column.key === 'action') {
|
||||
const { canEdit, canDelete } = permissions;
|
||||
if (!canEdit && !canDelete) return <span>-</span>;
|
||||
if (!canEdit && !canDelete) return <span>--</span>;
|
||||
|
||||
return (
|
||||
<Space>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { message } from 'ant-design-vue';
|
||||
import { useState, useDebounce, useThrottleFn } from '@/hooks';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { useEffect } from '@/hooks/useEffect';
|
||||
import { usePagination } from '@/hooks/usePagination';
|
||||
import { usePagination, syncPaginationTotal } from '@/hooks/usePagination';
|
||||
import {
|
||||
getRoleList,
|
||||
saveRole,
|
||||
@@ -61,8 +61,7 @@ export function useRoleModel() {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
syncPaginationTotal(pagination, (data.value as any)?.data?.total);
|
||||
}, [data]);
|
||||
|
||||
// ===== 弹窗状态 =====
|
||||
|
||||
@@ -41,7 +41,7 @@ function renderBodyCell({
|
||||
if (column.key === 'action') {
|
||||
const isActive = record.status === '1';
|
||||
const { canEdit, canToggleStatus } = permissions;
|
||||
if (!canEdit && !canToggleStatus) return <span>-</span>;
|
||||
if (!canEdit && !canToggleStatus) return <span>--</span>;
|
||||
|
||||
return (
|
||||
<Space>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { StatusTag, type StatusTagTone } from '@/components';
|
||||
import { useDebounce, useThrottleFn } from '@/hooks';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { useEffect } from '@/hooks/useEffect';
|
||||
import { usePagination } from '@/hooks/usePagination';
|
||||
import { usePagination, syncPaginationTotal } from '@/hooks/usePagination';
|
||||
import {
|
||||
getUserList,
|
||||
type TournamentAdminUserVO,
|
||||
@@ -102,8 +102,7 @@ export function useUserModel() {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const total = (data.value as any)?.data?.total;
|
||||
if (total !== undefined) pagination.setTotal(total);
|
||||
syncPaginationTotal(pagination, (data.value as any)?.data?.total);
|
||||
}, [data]);
|
||||
|
||||
// ===== 表格列配置 =====
|
||||
@@ -118,7 +117,7 @@ export function useUserModel() {
|
||||
width: 100,
|
||||
align: 'center' as const,
|
||||
customRender: ({ text }: { text: string }) => {
|
||||
const info = STATUS_MAP[text] || { label: text || '-', tone: 'default' as const };
|
||||
const info = STATUS_MAP[text] || { label: text || '--', tone: 'default' as const };
|
||||
return h(StatusTag, { label: info.label, tone: info.tone });
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user
--