fix: 体验优化

This commit is contained in:
ZhuRui
2026-07-29 10:39:46 +08:00
parent 594324c459
commit 04ff2fb4df
6 changed files with 100 additions and 40 deletions
@@ -1,5 +1,6 @@
import { computed, reactive, toRef, Ref, h } from 'vue'; import { computed, reactive, toRef, Ref, h } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { StatusTag, type StatusTagTone } from '@/components'; import { StatusTag, type StatusTagTone } from '@/components';
import { useState, useDebounce, useThrottleFn } from '@/hooks'; import { useState, useDebounce, useThrottleFn } from '@/hooks';
@@ -108,6 +109,15 @@ const MOCK_DATA = Array.from({ length: 12 }, (_, i) => {
}; };
}); });
/**
* 临时排序:对假数据按创建时间倒序排列。
* 【注意】实际项目中排序由后端接口负责,对接后端后请删除此函数及相关调用。
*/
const sortByTimeDesc = (list: any[], field: string) =>
[...list].sort((a, b) => dayjs(b[field]).valueOf() - dayjs(a[field]).valueOf());
const SORTED_MOCK_DATA = sortByTimeDesc(MOCK_DATA, 'createTime');
// ============================================================ // ============================================================
// Model // Model
// ============================================================ // ============================================================
@@ -130,11 +140,11 @@ export function useBannerModel() {
// ===== 表格状态 ===== // ===== 表格状态 =====
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>(MOCK_DATA); const [dataSource, setDataSource] = useState<any[]>(SORTED_MOCK_DATA);
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
total: MOCK_DATA.length, total: SORTED_MOCK_DATA.length,
}); });
// ===== 弹窗状态 ===== // ===== 弹窗状态 =====
@@ -180,8 +190,8 @@ export function useBannerModel() {
status: filterForm.status, status: filterForm.status,
}); });
// TODO: 替换为真实 API 调用 // TODO: 替换为真实 API 调用
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
setPagination({ ...pagination.value, total: MOCK_DATA.length }); setPagination({ ...pagination.value, total: SORTED_MOCK_DATA.length });
message.success('查询成功'); message.success('查询成功');
} catch (error: any) { } catch (error: any) {
message.error(error.msg || '查询失败'); message.error(error.msg || '查询失败');
@@ -194,8 +204,8 @@ export function useBannerModel() {
const handleReset = useThrottleFn(() => { const handleReset = useThrottleFn(() => {
filterForm.searchTitle = ''; filterForm.searchTitle = '';
filterForm.status = ''; filterForm.status = '';
setPagination({ current: 1, pageSize: 10, total: MOCK_DATA.length }); setPagination({ current: 1, pageSize: 10, total: SORTED_MOCK_DATA.length });
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
}, 500); }, 500);
const handlePageChange = (page: number, pageSize: number) => { const handlePageChange = (page: number, pageSize: number) => {
@@ -1,5 +1,6 @@
import { computed, reactive, toRef, Ref, h } from 'vue'; import { computed, reactive, toRef, Ref, h } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { StatusTag, type StatusTagTone } from '@/components'; import { StatusTag, type StatusTagTone } from '@/components';
import { useState, useDebounce, useThrottleFn } from '@/hooks'; import { useState, useDebounce, useThrottleFn } from '@/hooks';
@@ -61,12 +62,21 @@ const MOCK_DATA = Array.from({ length: 12 }, (_, i) => ({
needIdCardImage: i % 2 === 0 ? '是' : '否', needIdCardImage: i % 2 === 0 ? '是' : '否',
creatorNickname: ['张运营', '李管理', '王策划', '赵赛事'][i % 4], creatorNickname: ['张运营', '李管理', '王策划', '赵赛事'][i % 4],
creatorPhone: ['13800138001', '13900139002', '13700137003', '13600136004'][i % 4], creatorPhone: ['13800138001', '13900139002', '13700137003', '13600136004'][i % 4],
createTime: '2026-07-01 14:30:00', createTime: `2026-07-${String((i % 10) + 1).padStart(2, '0')} ${String((i * 3 + 8) % 24).padStart(2, '0')}:${String((i * 17 + 11) % 60).padStart(2, '0')}:${String((i * 13 + 7) % 60).padStart(2, '0')}`,
status: (['pending', 'enrolling', 'deleted', 'removed', 'rejected'] as const)[i % 5], status: (['pending', 'enrolling', 'deleted', 'removed', 'rejected'] as const)[i % 5],
enrolledCount: [128, 256, 512, 64, 0][i % 5], enrolledCount: [128, 256, 512, 64, 0][i % 5],
cancelledCount: [5, 12, 8, 3, 0][i % 5], cancelledCount: [5, 12, 8, 3, 0][i % 5],
})); }));
/**
* 临时排序:对假数据按创建时间倒序排列。
* 【注意】实际项目中排序由后端接口负责,对接后端后请删除此函数及相关调用。
*/
const sortByTimeDesc = (list: any[], field: string) =>
[...list].sort((a, b) => dayjs(b[field]).valueOf() - dayjs(a[field]).valueOf());
const SORTED_MOCK_DATA = sortByTimeDesc(MOCK_DATA, 'createTime');
/** 状态标签映射 */ /** 状态标签映射 */
const STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = { const STATUS_MAP: Record<string, { label: string; tone: StatusTagTone }> = {
pending: { label: '待审核', tone: 'warning' }, pending: { label: '待审核', tone: 'warning' },
@@ -109,11 +119,11 @@ export function useEventListModel() {
// ===== 表格状态 ===== // ===== 表格状态 =====
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>(MOCK_DATA); const [dataSource, setDataSource] = useState<any[]>(SORTED_MOCK_DATA);
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
total: MOCK_DATA.length, total: SORTED_MOCK_DATA.length,
}); });
// ===== 表格列配置 ===== // ===== 表格列配置 =====
@@ -213,8 +223,8 @@ export function useEventListModel() {
needIdCardImage: filterForm.needIdCardImage, needIdCardImage: filterForm.needIdCardImage,
}); });
// TODO: 替换为真实 API 调用 // TODO: 替换为真实 API 调用
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
setPagination({ ...pagination.value, total: MOCK_DATA.length }); setPagination({ ...pagination.value, total: SORTED_MOCK_DATA.length });
message.success('查询成功'); message.success('查询成功');
} catch (error: any) { } catch (error: any) {
message.error(error.msg || '查询失败'); message.error(error.msg || '查询失败');
@@ -234,8 +244,8 @@ export function useEventListModel() {
filterForm.publicEvent = ''; filterForm.publicEvent = '';
filterForm.needIdCard = ''; filterForm.needIdCard = '';
filterForm.needIdCardImage = ''; filterForm.needIdCardImage = '';
setPagination({ current: 1, pageSize: 10, total: MOCK_DATA.length }); setPagination({ current: 1, pageSize: 10, total: SORTED_MOCK_DATA.length });
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
}, 500); }, 500);
const handlePageChange = (page: number, pageSize: number) => { const handlePageChange = (page: number, pageSize: number) => {
+18 -8
View File
@@ -1,5 +1,6 @@
import { computed, reactive, toRef, Ref, h } from 'vue'; import { computed, reactive, toRef, Ref, h } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { StatusTag, type StatusTagTone } from '@/components'; import { StatusTag, type StatusTagTone } from '@/components';
import { useState, useDebounce, useThrottleFn } from '@/hooks'; import { useState, useDebounce, useThrottleFn } from '@/hooks';
@@ -131,8 +132,8 @@ const MOCK_DATA = Array.from({ length: 12 }, (_, i) => {
registrant: ['张报名', '李报名', '王报名', '赵报名'][i % 4], registrant: ['张报名', '李报名', '王报名', '赵报名'][i % 4],
registrantPhone: ['13800138001', '13900139002', '13700137003', '13600136004'][i % 4], registrantPhone: ['13800138001', '13900139002', '13700137003', '13600136004'][i % 4],
registrantCount: [1, 2, 1, 3][i % 4], registrantCount: [1, 2, 1, 3][i % 4],
orderTime: '2026-07-15 10:30:00', orderTime: `2026-07-${String((i % 12) + 1).padStart(2, '0')} ${String((i * 2 + 8) % 24).padStart(2, '0')}:${String((i * 13 + 7) % 60).padStart(2, '0')}:${String((i * 11 + 3) % 60).padStart(2, '0')}`,
payTime: '2026-07-15 10:32:15', payTime: `2026-07-${String((i % 12) + 1).padStart(2, '0')} ${String((i * 2 + 8) % 24).padStart(2, '0')}:${String((i * 13 + 9) % 60).padStart(2, '0')}:${String((i * 11 + 5) % 60).padStart(2, '0')}`,
totalAmount, totalAmount,
discountAmount, discountAmount,
paidAmount: totalAmount - discountAmount, paidAmount: totalAmount - discountAmount,
@@ -144,6 +145,15 @@ const MOCK_DATA = Array.from({ length: 12 }, (_, i) => {
}; };
}); });
/**
* 临时排序:对假数据按订单时间倒序排列。
* 【注意】实际项目中排序由后端接口负责,对接后端后请删除此函数及相关调用。
*/
const sortByTimeDesc = (list: any[], field: string) =>
[...list].sort((a, b) => dayjs(b[field]).valueOf() - dayjs(a[field]).valueOf());
const SORTED_MOCK_DATA = sortByTimeDesc(MOCK_DATA, 'orderTime');
// ============================================================ // ============================================================
// 金额汇总假数据 // 金额汇总假数据
// ============================================================ // ============================================================
@@ -188,11 +198,11 @@ export function useOrderModel() {
// ===== 表格状态 ===== // ===== 表格状态 =====
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>(MOCK_DATA); const [dataSource, setDataSource] = useState<any[]>(SORTED_MOCK_DATA);
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
total: MOCK_DATA.length, total: SORTED_MOCK_DATA.length,
}); });
// ===== 金额汇总 ===== // ===== 金额汇总 =====
@@ -300,8 +310,8 @@ export function useOrderModel() {
refundStatus: filterForm.refundStatus, refundStatus: filterForm.refundStatus,
}); });
// TODO: 替换为真实 API 调用 // TODO: 替换为真实 API 调用
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
setPagination({ ...pagination.value, total: MOCK_DATA.length }); setPagination({ ...pagination.value, total: SORTED_MOCK_DATA.length });
setSummary(MOCK_SUMMARY); setSummary(MOCK_SUMMARY);
message.success('查询成功'); message.success('查询成功');
} catch (error: any) { } catch (error: any) {
@@ -319,8 +329,8 @@ export function useOrderModel() {
filterForm.searchPlayerName = ''; filterForm.searchPlayerName = '';
filterForm.orderStatus = ''; filterForm.orderStatus = '';
filterForm.refundStatus = ''; filterForm.refundStatus = '';
setPagination({ current: 1, pageSize: 10, total: MOCK_DATA.length }); setPagination({ current: 1, pageSize: 10, total: SORTED_MOCK_DATA.length });
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
setSummary(MOCK_SUMMARY); setSummary(MOCK_SUMMARY);
}, 500); }, 500);
+17 -7
View File
@@ -1,5 +1,6 @@
import { computed, reactive, toRef, Ref, h } from 'vue'; import { computed, reactive, toRef, Ref, h } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { StatusTag, type StatusTagTone } from '@/components'; import { StatusTag, type StatusTagTone } from '@/components';
import { useState, useDebounce, useThrottleFn } from '@/hooks'; import { useState, useDebounce, useThrottleFn } from '@/hooks';
@@ -38,9 +39,18 @@ const MOCK_DATA = Array.from({ length: 12 }, (_, i) => ({
? ['https://picsum.photos/seed/idcard-a/120/80', 'https://picsum.photos/seed/idcard-b/120/80'] ? ['https://picsum.photos/seed/idcard-a/120/80', 'https://picsum.photos/seed/idcard-b/120/80']
: [], : [],
status: (i % 4 === 3 ? 'disabled' : 'active') as string, status: (i % 4 === 3 ? 'disabled' : 'active') as string,
loginTime: '2026-07-20 14:30:00', loginTime: `2026-07-${String((i % 20) + 1).padStart(2, '0')} ${String((i * 3 + 6) % 24).padStart(2, '0')}:${String((i * 17 + 11) % 60).padStart(2, '0')}:${String((i * 13 + 7) % 60).padStart(2, '0')}`,
})); }));
/**
* 临时排序:对假数据按登录时间倒序排列。
* 【注意】实际项目中排序由后端接口负责,对接后端后请删除此函数及相关调用。
*/
const sortByTimeDesc = (list: any[], field: string) =>
[...list].sort((a, b) => dayjs(b[field]).valueOf() - dayjs(a[field]).valueOf());
const SORTED_MOCK_DATA = sortByTimeDesc(MOCK_DATA, 'loginTime');
// ============================================================ // ============================================================
// Model // Model
// ============================================================ // ============================================================
@@ -68,11 +78,11 @@ export function useUserModel() {
// ===== 表格状态 ===== // ===== 表格状态 =====
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>(MOCK_DATA); const [dataSource, setDataSource] = useState<any[]>(SORTED_MOCK_DATA);
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
total: MOCK_DATA.length, total: SORTED_MOCK_DATA.length,
}); });
// ===== 表格列配置 ===== // ===== 表格列配置 =====
@@ -123,8 +133,8 @@ export function useUserModel() {
status: filterForm.status, status: filterForm.status,
}); });
// TODO: 替换为真实 API 调用 // TODO: 替换为真实 API 调用
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
setPagination({ ...pagination.value, total: MOCK_DATA.length }); setPagination({ ...pagination.value, total: SORTED_MOCK_DATA.length });
message.success('查询成功'); message.success('查询成功');
} catch (error: any) { } catch (error: any) {
message.error(error.msg || '查询失败'); message.error(error.msg || '查询失败');
@@ -138,8 +148,8 @@ export function useUserModel() {
filterForm.searchUserName = ''; filterForm.searchUserName = '';
filterForm.searchPhone = ''; filterForm.searchPhone = '';
filterForm.status = ''; filterForm.status = '';
setPagination({ current: 1, pageSize: 10, total: MOCK_DATA.length }); setPagination({ current: 1, pageSize: 10, total: SORTED_MOCK_DATA.length });
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
}, 500); }, 500);
const handlePageChange = (page: number, pageSize: number) => { const handlePageChange = (page: number, pageSize: number) => {
+16 -6
View File
@@ -1,5 +1,6 @@
import { computed, reactive, toRef, Ref, h } from 'vue'; import { computed, reactive, toRef, Ref, h } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { StatusTag, type StatusTagTone } from '@/components'; import { StatusTag, type StatusTagTone } from '@/components';
import { useState, useDebounce, useThrottleFn } from '@/hooks'; import { useState, useDebounce, useThrottleFn } from '@/hooks';
@@ -38,6 +39,15 @@ const MOCK_DATA = [
}, },
]; ];
/**
* 临时排序:对假数据按创建时间倒序排列。
* 【注意】实际项目中排序由后端接口负责,对接后端后请删除此函数及相关调用。
*/
const sortByTimeDesc = (list: any[], field: string) =>
[...list].sort((a, b) => dayjs(b[field]).valueOf() - dayjs(a[field]).valueOf());
const SORTED_MOCK_DATA = sortByTimeDesc(MOCK_DATA, 'createTime');
/** 角色下用户列表 mock */ /** 角色下用户列表 mock */
const MOCK_USERS: Record<string, any[]> = { const MOCK_USERS: Record<string, any[]> = {
R20250601001: [ R20250601001: [
@@ -159,11 +169,11 @@ export function useRoleModel() {
// ===== 表格状态 ===== // ===== 表格状态 =====
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>(MOCK_DATA); const [dataSource, setDataSource] = useState<any[]>(SORTED_MOCK_DATA);
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
total: MOCK_DATA.length, total: SORTED_MOCK_DATA.length,
}); });
// ===== 弹窗状态 ===== // ===== 弹窗状态 =====
@@ -202,8 +212,8 @@ export function useRoleModel() {
try { try {
console.log('搜索条件:', { keyword: debouncedKeyword.value }); console.log('搜索条件:', { keyword: debouncedKeyword.value });
// TODO: 替换为真实 API 调用 // TODO: 替换为真实 API 调用
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
setPagination({ ...pagination.value, total: MOCK_DATA.length }); setPagination({ ...pagination.value, total: SORTED_MOCK_DATA.length });
message.success('查询成功'); message.success('查询成功');
} catch (error: any) { } catch (error: any) {
message.error(error.msg || '查询失败'); message.error(error.msg || '查询失败');
@@ -215,8 +225,8 @@ export function useRoleModel() {
/** 重置 */ /** 重置 */
const handleReset = useThrottleFn(() => { const handleReset = useThrottleFn(() => {
filterForm.searchKeyword = ''; filterForm.searchKeyword = '';
setPagination({ current: 1, pageSize: 10, total: MOCK_DATA.length }); setPagination({ current: 1, pageSize: 10, total: SORTED_MOCK_DATA.length });
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
}, 500); }, 500);
const handlePageChange = (page: number, pageSize: number) => { const handlePageChange = (page: number, pageSize: number) => {
+16 -6
View File
@@ -1,5 +1,6 @@
import { computed, reactive, toRef, Ref, h } from 'vue'; import { computed, reactive, toRef, Ref, h } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { StatusTag, type StatusTagTone } from '@/components'; import { StatusTag, type StatusTagTone } from '@/components';
import { useState, useDebounce, useThrottleFn } from '@/hooks'; import { useState, useDebounce, useThrottleFn } from '@/hooks';
@@ -58,6 +59,15 @@ const MOCK_DATA = [
}, },
]; ];
/**
* 临时排序:对假数据按创建时间倒序排列。
* 【注意】实际项目中排序由后端接口负责,对接后端后请删除此函数及相关调用。
*/
const sortByTimeDesc = (list: any[], field: string) =>
[...list].sort((a, b) => dayjs(b[field]).valueOf() - dayjs(a[field]).valueOf());
const SORTED_MOCK_DATA = sortByTimeDesc(MOCK_DATA, 'createTime');
// ============================================================ // ============================================================
// Model // Model
// ============================================================ // ============================================================
@@ -81,11 +91,11 @@ export function useUserModel() {
// ===== 表格状态 ===== // ===== 表格状态 =====
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>(MOCK_DATA); const [dataSource, setDataSource] = useState<any[]>(SORTED_MOCK_DATA);
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
total: MOCK_DATA.length, total: SORTED_MOCK_DATA.length,
}); });
// ===== 弹窗状态 ===== // ===== 弹窗状态 =====
@@ -144,8 +154,8 @@ export function useUserModel() {
status: filterForm.status, status: filterForm.status,
}); });
// TODO: 替换为真实 API 调用 // TODO: 替换为真实 API 调用
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
setPagination({ ...pagination.value, total: MOCK_DATA.length }); setPagination({ ...pagination.value, total: SORTED_MOCK_DATA.length });
message.success('查询成功'); message.success('查询成功');
} catch (error: any) { } catch (error: any) {
message.error(error.msg || '查询失败'); message.error(error.msg || '查询失败');
@@ -159,8 +169,8 @@ export function useUserModel() {
filterForm.searchKeyword = ''; filterForm.searchKeyword = '';
filterForm.role = ''; filterForm.role = '';
filterForm.status = ''; filterForm.status = '';
setPagination({ current: 1, pageSize: 10, total: MOCK_DATA.length }); setPagination({ current: 1, pageSize: 10, total: SORTED_MOCK_DATA.length });
setDataSource(MOCK_DATA); setDataSource(SORTED_MOCK_DATA);
}, 500); }, 500);
const handlePageChange = (page: number, pageSize: number) => { const handlePageChange = (page: number, pageSize: number) => {