fix: 处理赛事订单管理详情弹窗样式问题

This commit is contained in:
ZhuRui
2026-08-06 17:05:13 +08:00
parent 98b073e8f5
commit a7e31613c5
5 changed files with 72 additions and 86 deletions
+4 -4
View File
@@ -140,9 +140,9 @@ export interface TournamentAdminOrderInfoVO {
/** 订单详情查询参数 */ /** 订单详情查询参数 */
export interface OrderDetailQueryParams { export interface OrderDetailQueryParams {
/** 订单编号 */ /** 订单编号 */
orderNo: string; orderNo?: string;
/** 选手ID */ /** 选手ID */
uniqueId: string; uniqueId?: string;
} }
// ============================================================ // ============================================================
@@ -178,9 +178,9 @@ export interface TournamentAdminOrderInfoPageVO {
/** 选手列表查询参数 */ /** 选手列表查询参数 */
export interface OrderPlayerListQueryParams { export interface OrderPlayerListQueryParams {
/** 订单编号 */ /** 订单编号 */
orderNo: string; orderNo?: string;
/** 选手ID */ /** 选手ID */
uniqueId: string; uniqueId?: string;
page: string; page: string;
limit: string; limit: string;
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

@@ -59,11 +59,6 @@
font-weight: 500; font-weight: 500;
} }
.tableWrap {
max-height: 200px;
overflow-y: auto;
}
.paginationRow { .paginationRow {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
@@ -80,30 +75,4 @@
font-size: 13px; font-size: 13px;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
} }
.idImageGrid {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.idImageCell {
width: 128px;
height: 82px;
border-radius: 4px;
overflow: hidden;
border: 1px solid #f0f0f0;
flex-shrink: 0;
:global(.ant-image) {
width: 100%;
height: 100%;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
} }
@@ -1,5 +1,5 @@
import { defineComponent, reactive, ref } from 'vue'; import { defineComponent, computed, reactive, ref } from 'vue';
import { Modal, Descriptions, Image, Table, Pagination, Spin } from 'ant-design-vue'; import { Modal, Descriptions, Image, Table, Pagination, Spin, Space } from 'ant-design-vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { import {
getEventDetail, getEventDetail,
@@ -9,6 +9,7 @@ import {
type TournamentAdminInfoSignupVO, type TournamentAdminInfoSignupVO,
} from '../model/services'; } from '../model/services';
import { useState, useEffect } from '@/hooks'; import { useState, useEffect } from '@/hooks';
import defaultCover from '@/assets/img/default.png';
import styles from './EventDetailModal.module.less'; import styles from './EventDetailModal.module.less';
interface EventDetailModalProps { interface EventDetailModalProps {
@@ -27,27 +28,29 @@ const formatYN = (v: string) => YES_NO_MAP[v] ?? v;
const formatPublic = (v: string) => PUBLIC_MAP[v] ?? v; const formatPublic = (v: string) => PUBLIC_MAP[v] ?? v;
const formatGender = (v: string) => GENDER_MAP[v] ?? v; const formatGender = (v: string) => GENDER_MAP[v] ?? v;
const PAGE_SIZE = 10; const PAGE_SIZE = 5;
/** 渲染身份证图片(cover 填充,与封面显示方式一致 */ /** 渲染身份证图片(缩略图,点击可预览 */
const renderIdImages = (imgList: string[], singleImg: string) => { const renderIdImages = (imgList: string[], singleImg: string) => {
const urls = imgList.length > 0 ? imgList : singleImg ? [singleImg] : []; const urls = imgList.length > 0 ? imgList : singleImg ? [singleImg] : [];
if (urls.length === 0) return <span>--</span>; if (urls.length === 0) return <span>--</span>;
return ( return (
<Image.PreviewGroup> <Space size={4}>
<div class={styles.idImageGrid}>
{urls.map((url) => ( {urls.map((url) => (
<div class={styles.idImageCell}> <Image
<Image src={url} /> key={url}
</div> src={url}
width={40}
height={40}
style={{ objectFit: 'cover', borderRadius: '4px', cursor: 'pointer' }}
/>
))} ))}
</div> </Space>
</Image.PreviewGroup>
); );
}; };
/** 选手表格 */ /** 选手表格基础列(不含证件号/证件图片,由 setup 内 computed 按需拼接) */
const PLAYER_COLUMNS = [ const BASE_PLAYER_COLUMNS: any[] = [
{ title: '选手', dataIndex: 'realName', key: 'realName', width: 100 }, { title: '选手', dataIndex: 'realName', key: 'realName', width: 100 },
{ {
title: '性别', title: '性别',
@@ -57,22 +60,24 @@ const PLAYER_COLUMNS = [
customRender: ({ text }: { text: string }) => formatGender(text), customRender: ({ text }: { text: string }) => formatGender(text),
}, },
{ title: '手机号', dataIndex: 'phone', key: 'phone', width: 130 }, { title: '手机号', dataIndex: 'phone', key: 'phone', width: 130 },
{ ];
const ID_CARD_COLUMN: any = {
title: '证件号', title: '证件号',
dataIndex: 'idCard', dataIndex: 'idCard',
key: 'idCard', key: 'idCard',
width: 180, width: 180,
customRender: ({ record }: { record?: TournamentAdminInfoSignupVO }) => customRender: ({ record }: { record?: TournamentAdminInfoSignupVO }) =>
record?.idCard ? record.idCard : <span>--</span>, record?.idCard ? record.idCard : <span>--</span>,
}, };
{
const ID_CARD_IMG_COLUMN: any = {
title: '证件图片', title: '证件图片',
key: 'idCardImgs', key: 'idCardImgs',
width: 280, width: 120,
customRender: ({ record }: { record?: TournamentAdminInfoSignupVO }) => customRender: ({ record }: { record?: TournamentAdminInfoSignupVO }) =>
record ? renderIdImages(record.idCardImgList || [], record.idCardImg || '') : <span>--</span>, record ? renderIdImages(record.idCardImgList || [], record.idCardImg || '') : <span>--</span>,
}, };
];
export default defineComponent({ export default defineComponent({
name: 'EventDetailModal', name: 'EventDetailModal',
@@ -86,6 +91,14 @@ export default defineComponent({
const [detail, setDetail] = useState<TournamentAdminInfoVO | null>(null); const [detail, setDetail] = useState<TournamentAdminInfoVO | null>(null);
const [detailLoading, setDetailLoading] = useState(false); const [detailLoading, setDetailLoading] = useState(false);
/** 动态列:根据赛事是否要求证件号/证件图片决定显示 */
const playerColumns = computed(() => {
const cols = [...BASE_PLAYER_COLUMNS];
if (detail.value?.isRequireIdCardNo === '1') cols.push(ID_CARD_COLUMN);
if (detail.value?.isRequireIdCardImg === '1') cols.push(ID_CARD_IMG_COLUMN);
return cols;
});
// ===== 每个组别的选手数据(key = categoryId ===== // ===== 每个组别的选手数据(key = categoryId =====
const categoryPlayers = ref<Record<string, TournamentAdminInfoSignupVO[]>>({}); const categoryPlayers = ref<Record<string, TournamentAdminInfoSignupVO[]>>({});
const categoryPlayerTotal = ref<Record<string, number>>({}); const categoryPlayerTotal = ref<Record<string, number>>({});
@@ -230,12 +243,14 @@ export default defineComponent({
</div> </div>
{/* ===== 封面 ===== */} {/* ===== 封面 ===== */}
{detail.value.img && (
<div class={styles.section}> <div class={styles.section}>
<div class={styles.sectionTitle}></div> <div class={styles.sectionTitle}></div>
<Image style={{ maxHeight: '380px' }} src={detail.value.img} /> <Image
style={{ maxHeight: '380px' }}
src={detail.value.img || defaultCover}
fallback={defaultCover}
/>
</div> </div>
)}
{/* ===== 赛事公告 ===== */} {/* ===== 赛事公告 ===== */}
{detail.value.notice && ( {detail.value.notice && (
@@ -249,21 +264,20 @@ export default defineComponent({
{detail.value.categoryList && detail.value.categoryList.length > 0 && ( {detail.value.categoryList && detail.value.categoryList.length > 0 && (
<div class={styles.section}> <div class={styles.section}>
<div class={styles.sectionTitle}></div> <div class={styles.sectionTitle}></div>
{detail.value.categoryList.map((cat: InnerCategoryVO) => ( {detail.value.categoryList.map((cat: InnerCategoryVO, idx: number) => (
<div key={cat.id} class={styles.group}> <div key={cat.id} class={styles.group}>
<div class={styles.groupTitle}> <div class={styles.groupTitle}>
{cat.name}{CATEGORY_TYPE_MAP[cat.type] ?? cat.type} {idx + 1}{cat.name}{CATEGORY_TYPE_MAP[cat.type] ?? cat.type}
</div> </div>
<div class={styles.tableWrap}>
<Table <Table
columns={PLAYER_COLUMNS} columns={playerColumns.value}
dataSource={categoryPlayers.value[cat.id] || []} dataSource={categoryPlayers.value[cat.id] || []}
loading={categoryPlayerLoading.value[cat.id]} loading={categoryPlayerLoading.value[cat.id]}
size="small" size="small"
pagination={false} pagination={false}
bordered bordered
scroll={{ x: 'max-content', y: 200 }}
/> />
</div>
{categoryPlayerTotal.value[cat.id] > 0 && ( {categoryPlayerTotal.value[cat.id] > 0 && (
<div class={styles.paginationRow}> <div class={styles.paginationRow}>
<Pagination <Pagination
@@ -8,6 +8,7 @@ import {
type TournamentAdminOrderInfoVO, type TournamentAdminOrderInfoVO,
type InnerRefundInfo, type InnerRefundInfo,
type TournamentAdminOrderInfoPageVO, type TournamentAdminOrderInfoPageVO,
OrderDetailQueryParams,
} from '../model/services'; } from '../model/services';
import styles from './OrderDetailModal.module.less'; import styles from './OrderDetailModal.module.less';
@@ -143,8 +144,7 @@ export default defineComponent({
setPlayersLoading(true); setPlayersLoading(true);
try { try {
const res = await getOrderPlayerList({ const res = await getOrderPlayerList({
orderNo: props.orderNo, ...(props.orderNo ? { orderNo: props.orderNo } : { uniqueId: props.uniqueId }),
uniqueId: props.uniqueId,
page: String(page), page: String(page),
limit: String(playerPageSize), limit: String(playerPageSize),
}); });
@@ -179,7 +179,10 @@ export default defineComponent({
const refundSuccessCount = computed(() => refundSuccessList.value.length); const refundSuccessCount = computed(() => refundSuccessList.value.length);
const fetchData = async () => { const fetchData = async () => {
const params = { orderNo: props.orderNo, uniqueId: props.uniqueId }; const params: OrderDetailQueryParams = {};
if (props.orderNo) params['orderNo'] = props.orderNo;
else params['uniqueId'] = props.uniqueId;
const [detailRes] = await Promise.all([getOrderDetail(params), fetchPlayers(1)]); const [detailRes] = await Promise.all([getOrderDetail(params), fetchPlayers(1)]);
if (detailRes.code == 200) { if (detailRes.code == 200) {
setDetail(detailRes.data); setDetail(detailRes.data);