feat: 精简玩家端页面结构并支持局域网开发热更新
Some checks failed
lotteryfront CI / build (push) Has been cancelled

- 合并钱包、订单、开奖、通知等独立 screen 到页面层,减少重复壳组件
- 优化订单列表/详情、钱包划转与待对账展示、开奖核对与结果详情交互
- 改进入口 gate、移动端视口与下拉刷新在窄屏下的表现
- dev 绑定 0.0.0.0 并默认放行 192.168/10 网段,修复局域网 HMR WebSocket
This commit is contained in:
2026-06-26 14:10:47 +08:00
parent dd1155978a
commit e5622c58cb
51 changed files with 1184 additions and 1335 deletions

View File

@@ -15,8 +15,6 @@ export type TicketItemGroup = {
jackpot_win_amount: number;
};
export const ORDER_GROUP_STORAGE_PREFIX = "lottery:order-group:v1:";
/** 分组键:有 order_no 则按订单;否则 draw_no + placed_at + currency + status 兜底 */
export function getTicketItemGroupKey(row: TicketItemListRow): string {
const orderNo = (row.order_no ?? "").trim();
@@ -135,56 +133,6 @@ export function groupTicketItems(items: TicketItemListRow[]): TicketItemGroup[]
});
}
export function persistOrderGroup(group: TicketItemGroup): void {
try {
sessionStorage.setItem(
ORDER_GROUP_STORAGE_PREFIX + group.key,
JSON.stringify(group),
);
} catch {
/* quota / private mode */
}
}
export function loadPersistedOrderGroup(groupKey: string): TicketItemGroup | null {
try {
const raw = sessionStorage.getItem(ORDER_GROUP_STORAGE_PREFIX + groupKey);
if (!raw) return null;
const parsed = JSON.parse(raw) as TicketItemGroup;
if (!parsed?.key || !Array.isArray(parsed.items)) return null;
return { ...parsed, items: sortTicketGroupItems(parsed.items) };
} catch {
return null;
}
}
export function orderGroupPath(groupKey: string, ticketNos?: string[]): string {
const base = `/orders/group/${encodeURIComponent(groupKey)}`;
if (!ticketNos?.length) return base;
return `${base}?tickets=${encodeURIComponent(ticketNos.join(","))}`;
}
export function orderGroupHref(group: TicketItemGroup): string {
if (group.items.length === 1) {
return `/orders/${encodeURIComponent(group.items[0].ticket_no)}`;
}
return orderGroupPath(
group.key,
group.items.map((i) => i.ticket_no),
);
}
/** 注项详情;来自订单组时带上 fromGroup便于返回订单详情 */
export function ticketDetailHref(
ticketNo: string,
fromGroup?: TicketItemGroup | null,
): string {
const base = `/orders/${encodeURIComponent(ticketNo)}`;
const key = (fromGroup?.key ?? "").trim();
if (!key) return base;
const params = new URLSearchParams({ fromGroup: key });
if (fromGroup && fromGroup.items.length > 1) {
params.set("tickets", fromGroup.items.map((i) => i.ticket_no).join(","));
}
return `${base}?${params.toString()}`;
}
export function ticketDetailHref(ticketNo: string): string {
return `/orders/${encodeURIComponent(ticketNo)}`;
}