协议数据模拟测试
This commit is contained in:
@@ -1,24 +1,32 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IAuthService } from "./IAuthService";
|
||||
import { HttpAuthService } from "./HttpAuthService";
|
||||
import { MockAuthService } from "./MockAuthService";
|
||||
|
||||
export class AuthService {
|
||||
// 模拟开关
|
||||
const USE_MOCK = false;
|
||||
|
||||
export class AuthService implements IAuthService {
|
||||
private static _I: AuthService | null = null;
|
||||
public static get I(): AuthService {
|
||||
if (!AuthService._I) AuthService._I = new AuthService();
|
||||
return AuthService._I;
|
||||
}
|
||||
private constructor(private api = ApiClient.I) {}
|
||||
|
||||
private impl: IAuthService;
|
||||
|
||||
private constructor() {
|
||||
this.impl = USE_MOCK ? new MockAuthService() : new HttpAuthService();
|
||||
}
|
||||
|
||||
/** 运行期动态切换 */
|
||||
public switch(useMock: boolean) {
|
||||
this.impl = useMock ? new MockAuthService() : new HttpAuthService();
|
||||
}
|
||||
|
||||
// 登录
|
||||
public async login(req: proto.cs.ICSLoginReq): Promise<ApiResponse<proto.cs.ICSLoginRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSLoginReq, proto.cs.ICSLoginRes> = {
|
||||
path: "api/acc/login",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: false
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
return this.impl.login(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
// assets/Scripts/services/logic/ChatService.ts
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IChatService } from "./IChatService";
|
||||
import { HttpChatService } from "./HttpChatService";
|
||||
import { MockChatService } from "./MockChatService";
|
||||
|
||||
export class ChatService {
|
||||
// 模拟开关
|
||||
const USE_MOCK = true;
|
||||
|
||||
export class ChatService implements IChatService {
|
||||
private static _I: ChatService | null = null;
|
||||
public static get I(): ChatService {
|
||||
if (!ChatService._I) ChatService._I = new ChatService();
|
||||
return ChatService._I;
|
||||
}
|
||||
private constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 购买聊天次数
|
||||
private impl: IChatService;
|
||||
|
||||
private constructor() {
|
||||
this.impl = USE_MOCK ? new MockChatService() : new HttpChatService();
|
||||
}
|
||||
|
||||
/** 运行期动态切换 */
|
||||
public switch(useMock: boolean) {
|
||||
this.impl = useMock ? new MockChatService() : new HttpChatService();
|
||||
}
|
||||
|
||||
// 对外 API 保持不变
|
||||
public async reqBuyChat(req: proto.cs.ICSBuyChatReq): Promise<ApiResponse<proto.cs.ICSBuyChatRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSBuyChatReq, proto.cs.ICSBuyChatRes> = {
|
||||
path: "api/logic/buyChat",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
return this.impl.reqBuyChat(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +1,41 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { IGirlService } from "./IGirlService";
|
||||
import { HttpGirlService } from "./HttpGirlService";
|
||||
import { MockGirlService } from "./MockGirlService";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
|
||||
export class GirlService {
|
||||
// 模拟开关
|
||||
const USE_MOCK = false;
|
||||
|
||||
export class GirlService implements IGirlService {
|
||||
private static _I: GirlService | null = null;
|
||||
public static get I(): GirlService {
|
||||
if (!GirlService._I) GirlService._I = new GirlService();
|
||||
return GirlService._I;
|
||||
}
|
||||
private constructor(private api = ApiClient.I) {}
|
||||
|
||||
private impl: IGirlService;
|
||||
private constructor() {
|
||||
this.impl = USE_MOCK ? new MockGirlService() : new HttpGirlService();
|
||||
}
|
||||
|
||||
/** 可运行期切换 */
|
||||
public switch(useMock: boolean) {
|
||||
this.impl = useMock ? new MockGirlService() : new HttpGirlService();
|
||||
}
|
||||
|
||||
// 每日推荐
|
||||
public async reqDailyRecommend(req: proto.cs.ICSDailyRecommendReq): Promise<ApiResponse<proto.cs.ICSDailyRecommendRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSDailyRecommendReq, proto.cs.ICSDailyRecommendRes> = {
|
||||
path: "api/logic/dailyRecommend",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
return this.impl.reqDailyRecommend(req);
|
||||
}
|
||||
|
||||
// 获取技师列表
|
||||
public async reqGetGirlList(req: proto.cs.ICSGetGirlListReq): Promise<ApiResponse<proto.cs.ICSGetGirlListRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSGetGirlListReq, proto.cs.ICSGetGirlListRes> = {
|
||||
path: "api/logic/getGirls",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
}
|
||||
return this.impl.reqGetGirlList(req);
|
||||
}
|
||||
|
||||
// 获取技师详细信息
|
||||
public async reqGetGirlDetail(req: proto.cs.ICSGetGirlDetailReq): Promise<ApiResponse<proto.cs.ICSGetGirlDetailRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSGetGirlDetailReq, proto.cs.ICSGetGirlDetailRes> = {
|
||||
path: "api/logic/girlDetail",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
}
|
||||
return this.impl.reqGetGirlDetail(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IAuthService } from "./IAuthService";
|
||||
|
||||
export class HttpAuthService implements IAuthService {
|
||||
constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 登录
|
||||
async login(req: proto.cs.ICSLoginReq): Promise<ApiResponse<proto.cs.ICSLoginRes>> {
|
||||
const ep: Endpoint<proto.cs.ICSLoginReq, proto.cs.ICSLoginRes> = {
|
||||
path: "api/acc/login",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: false,
|
||||
};
|
||||
return this.api.call(ep, req);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "24bc5b19-b50b-417b-a289-6daaf1631e5e",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IChatService } from "./IChatService";
|
||||
|
||||
export class HttpChatService implements IChatService {
|
||||
constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 购买聊天次数
|
||||
async reqBuyChat(req: proto.cs.ICSBuyChatReq): Promise<ApiResponse<proto.cs.ICSBuyChatRes>> {
|
||||
const ep: Endpoint<proto.cs.ICSBuyChatReq, proto.cs.ICSBuyChatRes> = {
|
||||
path: "api/logic/buyChat",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true,
|
||||
};
|
||||
return this.api.call(ep, req);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "eeceea12-9271-4d6e-accb-6fa845679bae",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IGirlService } from "./IGirlService";
|
||||
|
||||
export class HttpGirlService implements IGirlService {
|
||||
constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 每日推荐
|
||||
async reqDailyRecommend(req: proto.cs.ICSDailyRecommendReq): Promise<ApiResponse<proto.cs.ICSDailyRecommendRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSDailyRecommendReq, proto.cs.ICSDailyRecommendRes> = {
|
||||
path: "api/logic/dailyRecommend",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
}
|
||||
|
||||
// 获取技师列表
|
||||
async reqGetGirlList(req: proto.cs.ICSGetGirlListReq): Promise<ApiResponse<proto.cs.ICSGetGirlListRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSGetGirlListReq, proto.cs.ICSGetGirlListRes> = {
|
||||
path: "api/logic/getGirls",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
}
|
||||
|
||||
// 获取技师详细信息
|
||||
async reqGetGirlDetail(req: proto.cs.ICSGetGirlDetailReq): Promise<ApiResponse<proto.cs.ICSGetGirlDetailRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSGetGirlDetailReq, proto.cs.ICSGetGirlDetailRes> = {
|
||||
path: "api/logic/girlDetail",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "44a2654f-adcb-429c-9263-1c3af2fe892a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IPlayerDataService } from "./IPlayerDataService";
|
||||
|
||||
export class HttpPlayerDataService implements IPlayerDataService {
|
||||
constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 获取个人信息
|
||||
async reqMyInfo(req: proto.cs.ICSMyInfoReq): Promise<ApiResponse<proto.cs.ICSMyInfoRes>> {
|
||||
const ep: Endpoint<proto.cs.ICSMyInfoReq, proto.cs.ICSMyInfoRes> = {
|
||||
path: "api/acc/info",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true,
|
||||
};
|
||||
return this.api.call(ep, req);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ab96e711-2298-4537-940e-76456dbc0bae",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IShopService } from "./IShopService";
|
||||
|
||||
export class HttpShopService implements IShopService {
|
||||
constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 获取商品列表
|
||||
async reqShopList(req: proto.cs.ICSGetShopReq): Promise<ApiResponse<proto.cs.ICSGetShopRes>> {
|
||||
const ep: Endpoint<proto.cs.ICSGetShopReq, proto.cs.ICSGetShopRes> = {
|
||||
path: "api/logic/shop",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true,
|
||||
};
|
||||
return this.api.call(ep, req);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e3cabad6-a951-4c68-9a25-ead65e5e2df1",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IThemeService } from "./IThemeService";
|
||||
|
||||
export class HttpThemeService implements IThemeService {
|
||||
constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 获取大厅分类列表
|
||||
async reqHallTheme(req: proto.cs.ICSHallThemeReq): Promise<ApiResponse<proto.cs.ICSHallThemeRes>> {
|
||||
const ep: Endpoint<proto.cs.ICSHallThemeReq, proto.cs.ICSHallThemeRes> = {
|
||||
path: "api/logic/hallTheme",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true,
|
||||
};
|
||||
return this.api.call(ep, req);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "6f1c9a8b-d57c-42ba-973c-f766e240c6d9",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
|
||||
export interface IAuthService {
|
||||
// 登录
|
||||
login(req: proto.cs.ICSLoginReq): Promise<ApiResponse<proto.cs.ICSLoginRes>>;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f6cd1a0f-bbf1-4c31-97d3-a38cb289a43b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// assets/Scripts/services/logic/IChatService.ts
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
|
||||
export interface IChatService {
|
||||
// 购买聊天次数
|
||||
reqBuyChat(req: proto.cs.ICSBuyChatReq): Promise<ApiResponse<proto.cs.ICSBuyChatRes>>;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "eb6b8f79-cd6e-469f-b0f3-4f7e228f28c2",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
|
||||
export interface IGirlService {
|
||||
// 每日推荐
|
||||
reqDailyRecommend(req: proto.cs.ICSDailyRecommendReq): Promise<ApiResponse<proto.cs.ICSDailyRecommendRes>>;
|
||||
// 获取技师列表
|
||||
reqGetGirlList(req: proto.cs.ICSGetGirlListReq): Promise<ApiResponse<proto.cs.ICSGetGirlListRes>>;
|
||||
// 获取技师详细信息
|
||||
reqGetGirlDetail(req: proto.cs.ICSGetGirlDetailReq): Promise<ApiResponse<proto.cs.ICSGetGirlDetailRes>>;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "7a3984ae-374c-4a29-9829-cc34bf786bd3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
|
||||
export interface IPlayerDataService {
|
||||
// 获取个人信息
|
||||
reqMyInfo(req: proto.cs.ICSMyInfoReq): Promise<ApiResponse<proto.cs.ICSMyInfoRes>>;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "b430ee20-dcca-4283-8c12-05fbaf0ef9cd",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
|
||||
export interface IShopService {
|
||||
// 获取商品列表
|
||||
reqShopList(req: proto.cs.ICSGetShopReq): Promise<ApiResponse<proto.cs.ICSGetShopRes>>;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "02999aec-9975-46ba-a11f-af36e470a92f",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
|
||||
export interface IThemeService {
|
||||
// 获取大厅分类列表
|
||||
reqHallTheme(req: proto.cs.ICSHallThemeReq): Promise<ApiResponse<proto.cs.ICSHallThemeRes>>;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "2bdda7f1-a550-4f93-8ae7-d21b58e75bf0",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IAuthService } from "./IAuthService";
|
||||
|
||||
export class MockAuthService implements IAuthService {
|
||||
private delay(ms = 180) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
|
||||
// 项目里 ApiResponse 结构若固定(code/message 等),把 ok()/err() 调整为你的真实结构即可
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
// private err<T = unknown>(message = "mock login error"): ApiResponse<T> {
|
||||
// return ({ ok: false, error: { message } } as unknown) as ApiResponse<T>;
|
||||
// }
|
||||
|
||||
// 登录
|
||||
async login(req: proto.cs.ICSLoginReq): Promise<ApiResponse<proto.cs.ICSLoginRes>> {
|
||||
await this.delay(150);
|
||||
|
||||
const name = req?.platType === "guest" ? `guest_${(req?.userId ?? "uid").toString().slice(-6)}` : "tester";
|
||||
// 注意:protobufjs 会把 int64 表达为 number/Long。这里用「秒」级时间戳更常见
|
||||
const expireSeconds = Math.floor(Date.now() / 1000) + 7 * 24 * 3600;
|
||||
|
||||
// 你的生成器通常会把 refresh_token 转成 refreshToken(camelCase)
|
||||
const res: proto.cs.ICSLoginRes = {
|
||||
name,
|
||||
token: `mock_token_${Date.now()}`,
|
||||
refreshToken: `mock_refresh_${Date.now()}`,
|
||||
expire: expireSeconds,
|
||||
};
|
||||
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "2604979a-f511-42c6-acec-8df2728a036b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IChatService } from "./IChatService";
|
||||
|
||||
export class MockChatService implements IChatService {
|
||||
private delay(ms = 160) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
|
||||
// 按你们项目的 ApiResponse 结构调整这里即可
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
// private err<T = unknown>(message = "mock buyChat error"): ApiResponse<T> {
|
||||
// return ({ ok: false, error: { message } } as unknown) as ApiResponse<T>;
|
||||
// }
|
||||
|
||||
async reqBuyChat(_req: proto.cs.ICSBuyChatReq): Promise<ApiResponse<proto.cs.ICSBuyChatRes>> {
|
||||
await this.delay();
|
||||
// CSBuyChatRes 在 proto 中为空消息,这里返回 {}
|
||||
const res: proto.cs.ICSBuyChatRes = {};
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "3b9927c4-335d-4593-a646-0136b2f82025",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IGirlService } from "./IGirlService";
|
||||
|
||||
export class MockGirlService implements IGirlService {
|
||||
private delay(ms = 180) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
private randInt(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1)) + min; }
|
||||
private pick<T>(arr: T[]) { return arr[this.randInt(0, arr.length - 1)]; }
|
||||
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
private err<T = unknown>(message = "mock error"): ApiResponse<T> {
|
||||
return ({ ok: false, error: { message } } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
|
||||
private genBrief(id: number): proto.cs.IGirlBrief {
|
||||
const tags = ["cute", "cool", "elegant", "sporty", "sweet"];
|
||||
return {
|
||||
id,
|
||||
name: `Girl-${id}`,
|
||||
age: this.randInt(18, 28),
|
||||
tagKey: this.pick(tags),
|
||||
priceType: (id % 2) + 1,
|
||||
price: 50 + (id % 6) * 10,
|
||||
avatar: `https://dummy.local/avatar/${id}.png`,
|
||||
star: (id % 5) + 1,
|
||||
};
|
||||
}
|
||||
|
||||
private genPhoto(idx: number): proto.cs.IGirlPhoto {
|
||||
return { pic: `https://dummy.local/photo/${idx}.jpg`, isRelease: Math.random() < 0.5, price: 20 + (idx % 5) * 5 };
|
||||
}
|
||||
|
||||
private genDetail(id: number): proto.cs.IGirlDetail {
|
||||
const photos = Array.from({ length: 4 }, (_, i) => this.genPhoto(id * 10 + i));
|
||||
return { brief: this.genBrief(id), desc: `Mock detail for ${id}`, photos, isRelease: Math.random() < 0.4, chatCount: this.randInt(0, 5) };
|
||||
}
|
||||
|
||||
// 每日推荐
|
||||
async reqDailyRecommend(_req: proto.cs.ICSDailyRecommendReq): Promise<ApiResponse<proto.cs.ICSDailyRecommendRes>> {
|
||||
await this.delay(180);
|
||||
const count = this.randInt(4, 8);
|
||||
const girls = Array.from({ length: count }, (_, i) => this.genBrief(100 + i));
|
||||
return this.ok({ girls });
|
||||
}
|
||||
|
||||
// 获取技师列表
|
||||
async reqGetGirlList(req: proto.cs.ICSGetGirlListReq): Promise<ApiResponse<proto.cs.ICSGetGirlListRes>> {
|
||||
await this.delay(200);
|
||||
const base = (req?.category ?? 0) * 1000 + (req?.page ?? 1) * 100;
|
||||
const limit = Math.max(1, Math.min(req?.limit ?? 10, 50));
|
||||
const girls = Array.from({ length: limit }, (_, i) => this.genBrief(base + i));
|
||||
return this.ok({ girls });
|
||||
}
|
||||
|
||||
// 获取技师详细信息
|
||||
async reqGetGirlDetail(req: proto.cs.ICSGetGirlDetailReq): Promise<ApiResponse<proto.cs.ICSGetGirlDetailRes>> {
|
||||
await this.delay(160);
|
||||
const id = req?.id ?? this.randInt(1, 9999);
|
||||
return this.ok({ detail: this.genDetail(id) });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "842792c0-92ee-47f7-adbf-9abe668dd089",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IPlayerDataService } from "./IPlayerDataService";
|
||||
|
||||
export class MockPlayerDataService implements IPlayerDataService {
|
||||
private delay(ms = 160) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
|
||||
// 按你项目的 ApiResponse 真实结构调整这里
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
// 如需模拟失败
|
||||
// private err<T = unknown>(message = "mock myInfo error"): ApiResponse<T> {
|
||||
// return ({ ok: false, error: { message } } as unknown) as ApiResponse<T>;
|
||||
// }
|
||||
|
||||
// 获取个人信息
|
||||
async reqMyInfo(_req: proto.cs.ICSMyInfoReq): Promise<ApiResponse<proto.cs.ICSMyInfoRes>> {
|
||||
await this.delay();
|
||||
|
||||
// 由于我们并不知道 ICSMyInfoRes 的具体字段,这里提供一个“最安全”的空对象返回;
|
||||
// 如果你有明确字段(例如 name/diamond/vipExpire 等),可在此构造并 as-cast:
|
||||
// const res = { name: "Player-001", diamond: 123, vipExpire: Math.floor(Date.now()/1000) } as unknown as proto.cs.ICSMyInfoRes;
|
||||
|
||||
const res = ({} as unknown) as proto.cs.ICSMyInfoRes;
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "827b309b-4711-4458-8914-edc1d9d9c7c3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IShopService } from "./IShopService";
|
||||
|
||||
export class MockShopService implements IShopService {
|
||||
private delay(ms = 180) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
private randInt(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1)) + min; }
|
||||
private priceUSD(min = 0.99, max = 49.99) {
|
||||
const v = Math.random() * (max - min) + min;
|
||||
return v.toFixed(2); // 字符串,保留两位小数
|
||||
}
|
||||
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
|
||||
private genGood(id: number, vip = false): proto.cs.IGood {
|
||||
return {
|
||||
id,
|
||||
name: vip ? `VIP-${id}` : `Diamond Pack ${id}`,
|
||||
desc: vip ? `VIP access for ${this.randInt(24, 168)} hours` : `Diamonds x${this.randInt(60, 2000)}`,
|
||||
price: this.priceUSD(vip ? 4.99 : 0.99, vip ? 49.99 : 29.99),
|
||||
count: vip ? this.randInt(24, 168) : this.randInt(60, 2000), // VIP=小时,普通=数量
|
||||
};
|
||||
}
|
||||
|
||||
// 获取商品列表
|
||||
async reqShopList(_req: proto.cs.ICSGetShopReq): Promise<ApiResponse<proto.cs.ICSGetShopRes>> {
|
||||
await this.delay();
|
||||
|
||||
// 普通商品(<=2000)+ VIP 商品(>2000)
|
||||
const normals: proto.cs.IGood[] = Array.from({ length: 5 }, (_, i) => this.genGood(1000 + i, false));
|
||||
const vips: proto.cs.IGood[] = Array.from({ length: 3 }, (_, i) => this.genGood(2001 + i, true));
|
||||
|
||||
// 注意:你的 proto 定义中字段名为 "Goods"(大写 G)
|
||||
const res: proto.cs.ICSGetShopRes = { Goods: [...normals, ...vips] };
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "23c641b5-906c-4623-a581-2152bb42dab3",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IThemeService } from "./IThemeService";
|
||||
|
||||
export class MockThemeService implements IThemeService {
|
||||
private delay(ms = 160) { return new Promise<void>(r => setTimeout(r, ms)); }
|
||||
private ok<T>(data: T): ApiResponse<T> {
|
||||
return ({ ok: true, data } as unknown) as ApiResponse<T>;
|
||||
}
|
||||
|
||||
private makeTheme(id: number, name: string, category: number, isRelease = true): proto.cs.IHallTheme {
|
||||
return {
|
||||
id,
|
||||
key: `theme_${id}`,
|
||||
name,
|
||||
category,
|
||||
isRelease,
|
||||
path: `https://dummy.local/theme/${id}.png`,
|
||||
};
|
||||
// 若你使用资源服路径,可替换 path 为实际地址或 db:// 本地资源
|
||||
}
|
||||
|
||||
// 获取大厅分类列表
|
||||
async reqHallTheme(_req: proto.cs.ICSHallThemeReq): Promise<ApiResponse<proto.cs.ICSHallThemeRes>> {
|
||||
await this.delay();
|
||||
|
||||
const themes: proto.cs.IHallTheme[] = [
|
||||
this.makeTheme(1, "Hot", 1, true),
|
||||
this.makeTheme(2, "New", 2, true),
|
||||
this.makeTheme(3, "Popular", 3, true),
|
||||
this.makeTheme(4, "VIP Only", 4, false),
|
||||
this.makeTheme(5, "Classic", 5, true),
|
||||
this.makeTheme(6, "Editor Pick",6, true),
|
||||
];
|
||||
|
||||
const res: proto.cs.ICSHallThemeRes = { themes };
|
||||
return this.ok(res);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "b8fc6f81-7ccf-448d-9591-a1ebccf60bda",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -1,24 +1,32 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IPlayerDataService } from "./IPlayerDataService";
|
||||
import { HttpPlayerDataService } from "./HttpPlayerDataService";
|
||||
import { MockPlayerDataService } from "./MockPlayerDataService";
|
||||
|
||||
export class PlayerDataService {
|
||||
// 模拟开关
|
||||
const USE_MOCK = true;
|
||||
|
||||
export class PlayerDataService implements IPlayerDataService {
|
||||
private static _I: PlayerDataService | null = null;
|
||||
public static get I(): PlayerDataService {
|
||||
if (!PlayerDataService._I) PlayerDataService._I = new PlayerDataService();
|
||||
return PlayerDataService._I;
|
||||
}
|
||||
private constructor(private api = ApiClient.I) {}
|
||||
|
||||
// 获取个人信息
|
||||
private impl: IPlayerDataService;
|
||||
|
||||
private constructor() {
|
||||
this.impl = USE_MOCK ? new MockPlayerDataService() : new HttpPlayerDataService();
|
||||
}
|
||||
|
||||
/** 运行期切换 */
|
||||
public switch(useMock: boolean) {
|
||||
this.impl = useMock ? new MockPlayerDataService() : new HttpPlayerDataService();
|
||||
}
|
||||
|
||||
// 获取个人信息
|
||||
public async reqMyInfo(req: proto.cs.ICSMyInfoReq): Promise<ApiResponse<proto.cs.ICSMyInfoRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSMyInfoReq, proto.cs.ICSMyInfoRes> = {
|
||||
path: "api/acc/info",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
return this.impl.reqMyInfo(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IShopService } from "./IShopService";
|
||||
import { HttpShopService } from "./HttpShopService";
|
||||
import { MockShopService } from "./MockShopService";
|
||||
|
||||
export class ShopService {
|
||||
// 模拟开关
|
||||
const USE_MOCK = true;
|
||||
|
||||
export class ShopService implements IShopService {
|
||||
private static _I: ShopService | null = null;
|
||||
public static get I(): ShopService {
|
||||
if (!ShopService._I) ShopService._I = new ShopService();
|
||||
return ShopService._I;
|
||||
}
|
||||
private constructor(private api = ApiClient.I) {}
|
||||
|
||||
private impl: IShopService;
|
||||
|
||||
private constructor() {
|
||||
this.impl = USE_MOCK ? new MockShopService() : new HttpShopService();
|
||||
}
|
||||
|
||||
/** 运行期切换 */
|
||||
public switch(useMock: boolean) {
|
||||
this.impl = useMock ? new MockShopService() : new HttpShopService();
|
||||
}
|
||||
|
||||
// 获取商品列表
|
||||
public async reqShopList(req: proto.cs.ICSGetShopReq): Promise<ApiResponse<proto.cs.ICSGetShopRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSGetShopReq, proto.cs.ICSGetShopRes> = {
|
||||
path: "api/logic/shop",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
return this.impl.reqShopList(req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
import { ApiClient } from "../client/ApiClient";
|
||||
import type { Endpoint } from "../client/endpoints";
|
||||
import type { ApiResponse } from "../client/types";
|
||||
import proto from 'db://assets/Scripts/proto/proto.pb.js';
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import type { IThemeService } from "./IThemeService";
|
||||
import { HttpThemeService } from "./HttpThemeService";
|
||||
import { MockThemeService } from "./MockThemeService";
|
||||
|
||||
export class ThemeService {
|
||||
// 模拟开关
|
||||
const USE_MOCK = true;
|
||||
|
||||
export class ThemeService implements IThemeService {
|
||||
private static _I: ThemeService | null = null;
|
||||
public static get I(): ThemeService {
|
||||
if (!ThemeService._I) ThemeService._I = new ThemeService();
|
||||
return ThemeService._I;
|
||||
}
|
||||
private constructor(private api = ApiClient.I) {}
|
||||
|
||||
private impl: IThemeService;
|
||||
|
||||
private constructor() {
|
||||
this.impl = USE_MOCK ? new MockThemeService() : new HttpThemeService();
|
||||
}
|
||||
|
||||
/** 运行期切换 */
|
||||
public switch(useMock: boolean) {
|
||||
this.impl = useMock ? new MockThemeService() : new HttpThemeService();
|
||||
}
|
||||
|
||||
// 获取大厅分类列表
|
||||
public async reqHallTheme(req: proto.cs.ICSHallThemeReq): Promise<ApiResponse<proto.cs.ICSHallThemeRes>> {
|
||||
let epData: Endpoint<proto.cs.ICSHallThemeReq, proto.cs.ICSHallThemeRes> = {
|
||||
path: "api/logic/hallTheme",
|
||||
method: "POST",
|
||||
codec: "json",
|
||||
needsAuth: true
|
||||
};
|
||||
return this.api.call(epData, req);
|
||||
return this.impl.reqHallTheme(req);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user