/** * 技师数据 */ import { BaseData } from "./BaseData"; import proto from 'db://assets/Scripts/proto/proto.pb.js'; export interface GirlBriefVO { id: number; name: string; age: number; tagKey: string; priceType: number; price: number; // 用 number 存(i64 转) avatar: string; star: number; } export interface GirlPhotoVO { pic: string; isRelease: boolean; price: number; } export interface GirlDetailVO { id: number; // = brief.id desc: string; isRelease: boolean; chatCount: number; photos: GirlPhotoVO[]; } export class GirlData extends BaseData { // 实体归一化 private _briefs = new Map(); private _details = new Map(); // 列表索引 private _dailyRecommend: number[] = []; private _categoryPages = new Map>(); // category -> (page -> [girlId]) get briefById() { return this._briefs; } get detailById() { return this._details; } get dailyRecommendIds() { return this._dailyRecommend; } public reset(): void { this._briefs.clear(); this._details.clear(); this._dailyRecommend = []; this._categoryPages.clear(); } public clear(): void { this._briefs.clear(); this._details.clear(); this._dailyRecommend = []; this._categoryPages.clear(); } public destroy(): void { super.destroy(); this._briefs = null; this._details = null; this._dailyRecommend = null; this._categoryPages = null; } /** 合并 Brief 列表到缓存(去重+覆盖最新字段) */ mergeBriefs(list: pb.cs.IGirlBrief[] | pb.cs.GirlBrief[]): void { for (const g of list) { const id = g.id!; this._briefs.set(id, { id, name: g.name || "", age: g.age || 0, tagKey: g.tagKey || "", priceType: g.priceType || 0, price: i64(g.price), avatar: g.avatar || "", star: g.star || 0, }); } } /** 每日推荐:只维护 id 索引,实体来自 _briefs */ applyDailyRecommend(res: pb.cs.ICSDailyRecommendRes): void { const girls = res.girls ?? []; this.mergeBriefs(girls); this._dailyRecommend = girls.map(g => g.id!); } /** 分类分页列表:category + page -> id[] */ applyGirlList(category: number, page: number, res: pb.cs.ICSGetGirlListRes): void { const girls = res.girls ?? []; this.mergeBriefs(girls); if (!this._categoryPages.has(category)) { this._categoryPages.set(category, new Map()); } const pages = this._categoryPages.get(category)!; pages.set(page, girls.map(g => g.id!)); } /** 详情:合并 brief + detail */ applyGirlDetail(res: pb.cs.ICSGetGirlDetailRes): void { const d = res.detail!; const b = d.brief!; this.mergeBriefs([b]); const vo: GirlDetailVO = { id: b.id!, desc: d.desc || "", isRelease: !!d.isRelease, chatCount: d.chatCount || 0, photos: (d.photos ?? []).map(p => ({ pic: p.pic || "", isRelease: !!p.isRelease, price: p.price || 0, })), }; this._details.set(vo.id, vo); } /** 页面读取:根据分类+页获取 id 列表 */ getPageIds(category: number, page: number): number[] { const pages = this._categoryPages.get(category); return pages?.get(page) ?? []; } /** 本地变更:聊天次数变更(成功买次数后) */ incChatCount(girlId: number, delta: number) { const d = this._details.get(girlId); if (d) d.chatCount = Math.max(0, d.chatCount + delta); } /** 本地变更:解锁技师/照片(例如购买后或服务器回调) */ setGirlReleased(girlId: number, v: boolean) { const d = this._details.get(girlId); if (d) d.isRelease = v; } setPhotoReleased(girlId: number, pic: string, v: boolean) { const d = this._details.get(girlId); if (!d) return; const p = d.photos.find(x => x.pic === pic); if (p) p.isRelease = v; } }