diff --git a/assets/Scripts/chat18x/data/GirlData.ts b/assets/Scripts/chat18x/data/GirlData.ts index 93a070a5..7026b511 100644 --- a/assets/Scripts/chat18x/data/GirlData.ts +++ b/assets/Scripts/chat18x/data/GirlData.ts @@ -4,84 +4,301 @@ 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[]; +// 分类的数据结构 +interface CategoryBucket { + // 技师的简要数据 + briefs: Map; + // 技师的详细数据 + details: Map; + // 技师的id + girlIds: number[]; } export class GirlData extends BaseData { - // 实体归一化 - private _briefs = new Map(); - private _details = new Map(); - + // 大分类 + private _categories = 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(); + this._categories.clear(); } public clear(): void { - this._briefs.clear(); - this._details.clear(); - this._dailyRecommend = []; - this._categoryPages.clear(); + this._categories.clear(); } public destroy(): void { super.destroy(); - this._briefs = null; - this._details = null; - this._dailyRecommend = null; - this._categoryPages = null; + 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; } - /** 合并 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, - }); + /** 获取付费类型 */ + 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 ?? [];