/** * 技师数据 */ import { BaseData } from "./BaseData"; import proto from 'db://assets/Scripts/proto/proto.pb.js'; // 分类的数据结构 interface CategoryBucket { // 技师的简要数据 briefs: Map; // 技师的详细数据 details: Map; // 技师的id girlIds: number[]; } export class GirlData extends BaseData { // 大分类 private _categories = new Map(); // 列表索引 private _dailyRecommend: number[] = []; public reset(): void { this._categories.clear(); } public clear(): void { this._categories.clear(); } public destroy(): void { super.destroy(); this._categories = null; } /** 保障 _categories 存在 */ private ensureCategories(): Map { if (!this._categories) { this._categories = new Map(); } return this._categories; } /** 获取或创建分类桶 */ private ensureBucket(categoryId: string): CategoryBucket { const cats = this.ensureCategories(); let bucket = cats.get(categoryId); if (!bucket) { bucket = { briefs: new Map(), details: new Map(), girlIds: [], }; cats.set(categoryId, bucket); } return bucket; } /** 取分类下的全部 girlIds(若分类不存在返回空数组) */ public getGirlIds(categoryId: string): number[] { const b = this.ensureCategories().get(categoryId); return b ? b.girlIds : []; } /** --------------------------------------------------------- 技师的简要数据 --------------------------------------------------------- */ // 解析技师简要数据,一个 private parseOneGirlBrief(data: proto.cs.IGirlBrief): proto.cs.IGirlBrief | null { if (!data) return null; const oneData: proto.cs.IGirlBrief = { id: data.id, // id name: data.name, // 名字 age: data.age, // 年龄 tagKey: data.tagKey, // 标签 priceType: data.priceType, // 付费类型 price: data.price, // 价格 avatar: data.avatar, // 头像 star: data.star, // 星级 }; return oneData; } // 解析技师简要数据,多个 private parseAllGirlBrief(data: proto.cs.IGirlBrief[]): proto.cs.IGirlBrief[] | null { if (!data) return null; let allData = []; for (const value of data) { const oneData: proto.cs.IGirlBrief = this.parseOneGirlBrief(value); if (oneData) { allData.push(oneData); } } return allData; } /** 保存技师的简要数据 */ public setGirlBriefs(categoryId: string, data: proto.cs.ICSGetGirlListRes): void { let allData = this.parseAllGirlBrief(data.girls); if (!allData) return; const bucket = this.ensureBucket(categoryId); if (allData) { for (const g of allData) { const id = g.id; bucket.briefs.set(id, g); // TODO,去重 bucket.girlIds.push(id); } } console.log("保存技师的简要数据: ", bucket); } /** 取某分类 + girlId 的简要信息 */ private getGrilBrief(categoryId: string, girlId: number): proto.cs.IGirlBrief | null { const b = this.ensureCategories().get(categoryId); if (!b) return null; return b.briefs.get(girlId) ?? null; } /** 获取名字 */ public getGrilName(categoryId: string, girlId: number): string { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return ""; return oneData.name; } /** 获取年龄 */ public getGrilAge(categoryId: string, girlId: number): number { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return 0; return oneData.age; } /** 获取标签 */ public getGrilTagKey(categoryId: string, girlId: number): string { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return ""; return oneData.tagKey; } /** 获取付费类型 */ public getGrilPriceType(categoryId: string, girlId: number): number { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return 0; return oneData.priceType; } /** 获取价格 */ public getGrilPrice(categoryId: string, girlId: number): number { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return 0; return oneData.price; } /** 获取头像 */ public getGrilAvatar(categoryId: string, girlId: number): string { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return ""; return oneData.avatar; } /** 获取星级 */ public getGrilStar(categoryId: string, girlId: number): number { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return 0; return oneData.star; } /** --------------------------------------------------------- 技师的详细数据 --------------------------------------------------------- */ // 解析技师图片数据,一个 private parseOneGirlPhoto(data: proto.cs.IGirlPhoto): proto.cs.IGirlPhoto | null { if (!data) return null; const oneData: proto.cs.IGirlPhoto = { pic: data.pic, // 图片路径 isRelease: data.isRelease, // 是否解锁 price: data.price, // 价格 }; return oneData; } // 解析技师图片数据,多个 private parseAllGirlPhoto(data: proto.cs.IGirlPhoto[]): proto.cs.IGirlPhoto[] | null { if (!data) return null; let allData = []; for (const value of data) { const oneData: proto.cs.IGirlPhoto = this.parseOneGirlPhoto(value); if (oneData) { allData.push(oneData); } } return allData; } // 解析技师详细数据,一个 private parseOneGirlDetail(data: proto.cs.IGirlDetail): proto.cs.IGirlDetail | null { if (!data) return null; const photoData = this.parseAllGirlPhoto(data.photos); const briefData = this.parseOneGirlBrief(data.brief); const oneData: proto.cs.IGirlDetail = { brief: briefData, // 技师简要数据 desc: data.desc, // 技师描述 photos: photoData, // 技师图片列表 isRelease: data.isRelease, // 技师是否解锁 chatCount: data.chatCount, // 剩余聊天次数 }; return oneData; } // 解析技师详细数据,多个 private parseAllGirlDetail(data: proto.cs.IGirlDetail[]): proto.cs.IGirlDetail[] | null { if (!data) return null; let allData = []; for (const value of data) { const oneData: proto.cs.IGirlDetail = this.parseOneGirlDetail(value); if (oneData) { allData.push(oneData); } } return allData; } /** 保存技师的详细数据 */ public setGirlDetails(categoryId: string, data: proto.cs.ICSGetGirlDetailRes): void { const d = this.parseOneGirlDetail(data.detail); if (!d) return; const bucket = this.ensureBucket(categoryId); // id const id = d.brief?.id ?? 0; // 合并简要 if (d.brief) { bucket.briefs.set(id, d.brief); // TODO,去重 bucket.girlIds.push(id); } // 写入详情 bucket.details.set(id, d); console.log("保存技师的详细数据: ", bucket); } /** 取某分类 + girlId 的详细信息 */ public getGrilDetail(categoryId: string, girlId: number): proto.cs.IGirlDetail | null { const b = this.ensureCategories().get(categoryId); if (!b) return null; return b.details.get(girlId) ?? null; } /** 获取技师描述 */ public getGrilDesc(categoryId: string, girlId: number): string { let oneData = this.getGrilDetail(categoryId, girlId); if (!oneData) return ""; return oneData.desc; } /** 获取技师是否解锁 */ public getGrilIsRelease(categoryId: string, girlId: number): boolean { let oneData = this.getGrilDetail(categoryId, girlId); if (!oneData) return false; return oneData.isRelease; } /** 获取技师剩余聊天次数 */ public getGrilChatCount(categoryId: string, girlId: number): number { let oneData = this.getGrilDetail(categoryId, girlId); if (!oneData) return 0; return oneData.chatCount; } /** 获取技师图片数据,通过 index */ public getGrilPhotoData(categoryId: string, girlId: number, index: number): proto.cs.IGirlPhoto | null { let oneData = this.getGrilDetail(categoryId, girlId); if (!oneData || !oneData.photos) return null; // 下标越界保护 if (index < 0 || index >= oneData.photos.length) return null; return oneData.photos[index] ?? null; } /** 获取技师图片的路径 */ public getGrilPhotoPic(categoryId: string, girlId: number, index: number): string { let oneData = this.getGrilPhotoData(categoryId, girlId, index); if (!oneData) return ""; return oneData.pic; } /** 获取技师图片是否解锁 */ public getGrilPhotoIsRelease(categoryId: string, girlId: number, index: number): boolean { let oneData = this.getGrilPhotoData(categoryId, girlId, index); if (!oneData) return false; return oneData.isRelease; } /** 获取技师图片的价格 */ public getGrilPhotoPrice(categoryId: string, girlId: number, index: number): number { let oneData = this.getGrilPhotoData(categoryId, girlId, index); if (!oneData) return 0; return oneData.price; } /** --------------------------------------------------------- 每日推荐 --------------------------------------------------------- */ /** 每日推荐:只维护 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; } }