/** * 技师数据 */ import { BaseData } from "./BaseData"; import proto from 'db://assets/Scripts/proto/proto.pb.js'; // 分类的数据结构 interface CategoryBucket { // 技师的简要数据 briefs: Map; // 技师的详细数据 details: Map; // 技师的id girlIds: number[]; } // 每日推荐专用分类 const DAILY_BUCKET = "__daily__"; export class GirlData extends BaseData { // 大分类 private _categories = new Map(); // 每日推荐(存放在 DAILY_BUCKET 中,同时保留 id 索引便于 UI 使用) private _dailyRecommendIds: 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 mergeBriefs(categoryId: string, respOrList: proto.cs.IGirlBrief[]): void { if (!respOrList) return; let allData = this.parseAllGirlBrief(respOrList); if (!allData) return; const bucket = this.ensureBucket(categoryId); for (const g of allData) { const id = g.id; bucket.briefs.set(id, g); // TODO,去重 bucket.girlIds.push(id); } console.log("保存技师的简要数据: ", 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, // 星级 category: data.category, // 主题枚举 listAvatarPath: data.listAvatarPath, // list头像路径 }; 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 { this.mergeBriefs(categoryId, data.girls); } /** 取某分类 + 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; } /** 获取主题枚举 */ public getGrilCategory(categoryId: string, girlId: number): number { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return 0; return oneData.category; } /** 获取主题枚举,根据 id */ public getGrilCategoryById(girlId: number): number { const cats = this.ensureCategories(); for (const bucket of cats.values()) { // 先查简要信息 const brief = bucket.briefs.get(girlId); if (brief && brief.category) { return brief.category; } // 兜底:若只缓存了详情,也从详情里的 brief 取 const detail = bucket.details.get(girlId); if (detail?.brief && typeof detail.brief.category) { return detail.brief.category; } } // 未找到 return 0; } /** 获取list头像路径 */ public getGrilListAvatar(categoryId: string, girlId: number): string { let oneData = this.getGrilBrief(categoryId, girlId); if (!oneData) return ""; return oneData.listAvatarPath; } /** --------------------------------------------------------- 技师的详细数据 --------------------------------------------------------- */ // 解析技师图片数据,一个 private parseOneGirlPhoto(data: proto.cs.IPurchaseCommercialImage): proto.cs.IPurchaseCommercialImage | null { if (!data) return null; const oneData: proto.cs.IPurchaseCommercialImage = { imageType: data.imageType, // 图片类型 imagePrice: data.imagePrice, // 图片价格 path: data.path, // 图片资源路径 isRelease: data.isRelease, // 是否解锁 }; return oneData; } // 解析技师图片数据,多个 private parseAllGirlPhoto(data: proto.cs.IPurchaseCommercialImage[]): proto.cs.IPurchaseCommercialImage[] | null { if (!data) return null; let allData = []; for (const value of data) { const oneData: proto.cs.IPurchaseCommercialImage = this.parseOneGirlPhoto(value); if (oneData) { allData.push(oneData); } } return allData; } // 解析技师视频数据,一个 private parseOneGirlVideo(data: proto.cs.IPurchaseCommercialVideo): proto.cs.IPurchaseCommercialVideo | null { if (!data) return null; const oneData: proto.cs.IPurchaseCommercialVideo = { path: data.path, // 视频资源路径 emotion: data.emotion, // 关联情绪 videoPrice: data.videoPrice, // 价格 isRelease: data.isRelease, // 是否解锁 }; return oneData; } // 解析技师视频数据,多个 private parseAllGirlVideo(data: proto.cs.IPurchaseCommercialVideo[]): proto.cs.IPurchaseCommercialVideo[] | null { if (!data) return null; let allData = []; for (const value of data) { const oneData: proto.cs.IPurchaseCommercialVideo = this.parseOneGirlVideo(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.images); const videoData = this.parseAllGirlVideo(data.videos); const briefData = this.parseOneGirlBrief(data.brief); const oneData: proto.cs.IGirlDetail = { brief: briefData, // 技师简要数据 desc: data.desc, // 技师描述 isRelease: data.isRelease, // 技师是否解锁 chatCount: data.chatCount, // 剩余聊天次数 images: photoData, // 技师图片列表 videos: videoData, // 技师视频列表 }; 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 = data?.detail; if (!d) return; // 合并简要信息 if (d.brief) this.mergeBriefs(categoryId, [d.brief]); const oneDetail = this.parseOneGirlDetail(d); const bucket = this.ensureBucket(categoryId); // id const id = d.brief?.id ?? 0; // 写入详情 bucket.details.set(id, oneDetail); 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; } /** 获取所有技师图片数据 */ private getAllGrilPhotoData(categoryId: string, girlId: number): proto.cs.IPurchaseCommercialImage[] | null { let oneData = this.getGrilDetail(categoryId, girlId); if (!oneData || !oneData.images) return null; return oneData.images; } /** 获取所有技师图片数据的数量 */ public getAllGrilPhotoDataCount(categoryId: string, girlId: number): number { let allData = this.getAllGrilPhotoData(categoryId, girlId); if (!allData) return 0; return allData.length; } /** 获取技师图片数据,通过 index */ private getGrilPhotoData(categoryId: string, girlId: number, index: number): proto.cs.IPurchaseCommercialImage | null { let allData = this.getAllGrilPhotoData(categoryId, girlId); if (!allData) return null; // 下标越界保护 if (index < 0 || index >= allData.length) return null; return allData[index] ?? null; } /** 获取技师图片的类型 */ public getGrilPhotoType(categoryId: string, girlId: number, index: number): number { let oneData = this.getGrilPhotoData(categoryId, girlId, index); if (!oneData) return 0; return oneData.imageType; } /** 获取技师图片的价格 */ public getGrilPhotoPrice(categoryId: string, girlId: number, index: number): number { let oneData = this.getGrilPhotoData(categoryId, girlId, index); if (!oneData) return 0; return oneData.imagePrice; } /** 获取技师图片的路径 */ public getGrilPhotoPic(categoryId: string, girlId: number, index: number): string { let oneData = this.getGrilPhotoData(categoryId, girlId, index); if (!oneData) return ""; return oneData.path; } /** 获取技师图片是否解锁 */ public getGrilPhotoIsRelease(categoryId: string, girlId: number, index: number): boolean { let oneData = this.getGrilPhotoData(categoryId, girlId, index); if (!oneData) return false; return oneData.isRelease; } /** 获取所有技师视频数据 */ private getAllGrilVideoData(categoryId: string, girlId: number): proto.cs.IPurchaseCommercialVideo[] | null { let oneData = this.getGrilDetail(categoryId, girlId); if (!oneData || !oneData.videos) return null; return oneData.videos ?? null; } /** 获取所有技师视频数据的数量 */ public getAllGrilVideoDataCount(categoryId: string, girlId: number): number { let allData = this.getAllGrilVideoData(categoryId, girlId); if (!allData) return 0; return allData.length; } /** 获取技师视频数据,通过 index */ private getGrilVideoData(categoryId: string, girlId: number, index: number): proto.cs.IPurchaseCommercialVideo | null { let allData = this.getAllGrilVideoData(categoryId, girlId); if (!allData) return null; // 下标越界保护 if (index < 0 || index >= allData.length) return null; return allData[index] ?? null; } /** 获取技师视频的路径 */ public getGrilVideoPath(categoryId: string, girlId: number, index: number): string { let oneData = this.getGrilVideoData(categoryId, girlId, index); if (!oneData) return ""; return oneData.path; } /** 获取技师视频的关联情绪 */ public getGrilVideoEmotion(categoryId: string, girlId: number, index: number): number { let oneData = this.getGrilVideoData(categoryId, girlId, index); if (!oneData) return 0; return oneData.emotion; } /** 获取技师视频的价格 */ public getGrilVideoPrice(categoryId: string, girlId: number, index: number): number { let oneData = this.getGrilVideoData(categoryId, girlId, index); if (!oneData) return 0; return oneData.videoPrice; } /** 获取技师视频是否解锁 */ public getGrilVideoIsRelease(categoryId: string, girlId: number, index: number): boolean { let oneData = this.getGrilVideoData(categoryId, girlId, index); if (!oneData) return false; return oneData.isRelease; } /** --------------------------------------------------------- 每日推荐 --------------------------------------------------------- */ /** 保存每日推荐:放入特殊分类 DAILY_BUCKET,并维护 id 索引 */ public setDailyRecommend(res: proto.cs.ICSDailyRecommendRes): void { this.mergeBriefs(DAILY_BUCKET, res.girls); this._dailyRecommendIds = res.girls.map(g => g.id ?? 0); console.log("保存每日推荐: ", this._dailyRecommendIds); } /** 获取每日推荐的简要信息 */ private getRecommendGrilBrief(categoryId: string, index: number): proto.cs.IGirlBrief | null { const b = this.ensureCategories().get(categoryId); if (!b) return null; if (index < 0 || index >= b.girlIds.length) return null; return b.briefs.get(b.girlIds[index]) ?? null; } /** 获取 id */ public getRecommendGrilId(index: number): number { let oneData = this.getRecommendGrilBrief(DAILY_BUCKET, index); if (!oneData) return 0; return oneData.id; } /** 获取名字 */ public getRecommendGrilName(index: number): string { let oneData = this.getRecommendGrilBrief(DAILY_BUCKET, index); if (!oneData) return ""; return oneData.name; } /** 获取头像 */ public getRecommendGrilAvatar(index: number): string { let oneData = this.getRecommendGrilBrief(DAILY_BUCKET, index); if (!oneData) return ""; return oneData.avatar; } }