From e64327bf093721e2691351de21da748a1b3cef88 Mon Sep 17 00:00:00 2001 From: chen wei bo <1025839511@qq.com> Date: Fri, 15 Aug 2025 14:29:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=8E=AF=E5=A2=83=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/Scripts/chat18x/config.meta | 9 ++ assets/Scripts/chat18x/config/env.meta | 9 ++ .../Scripts/chat18x/config/env/appConfig.ts | 126 ++++++++++++++++++ .../chat18x/config/env/appConfig.ts.meta | 9 ++ assets/Scripts/chat18x/config/env/dev.ts | 14 ++ assets/Scripts/chat18x/config/env/dev.ts.meta | 9 ++ assets/Scripts/chat18x/config/env/env.ts | 25 ++++ assets/Scripts/chat18x/config/env/env.ts.meta | 9 ++ assets/Scripts/chat18x/config/env/prod.ts | 14 ++ .../Scripts/chat18x/config/env/prod.ts.meta | 9 ++ assets/Scripts/chat18x/config/env/test.ts | 14 ++ .../Scripts/chat18x/config/env/test.ts.meta | 9 ++ .../chat18x/network/client/ApiClient.ts | 5 +- .../chat18x/network/client/endpoints.ts | 9 +- .../chat18x/network/services/AuthService.ts | 15 +-- 15 files changed, 269 insertions(+), 16 deletions(-) create mode 100644 assets/Scripts/chat18x/config.meta create mode 100644 assets/Scripts/chat18x/config/env.meta create mode 100644 assets/Scripts/chat18x/config/env/appConfig.ts create mode 100644 assets/Scripts/chat18x/config/env/appConfig.ts.meta create mode 100644 assets/Scripts/chat18x/config/env/dev.ts create mode 100644 assets/Scripts/chat18x/config/env/dev.ts.meta create mode 100644 assets/Scripts/chat18x/config/env/env.ts create mode 100644 assets/Scripts/chat18x/config/env/env.ts.meta create mode 100644 assets/Scripts/chat18x/config/env/prod.ts create mode 100644 assets/Scripts/chat18x/config/env/prod.ts.meta create mode 100644 assets/Scripts/chat18x/config/env/test.ts create mode 100644 assets/Scripts/chat18x/config/env/test.ts.meta diff --git a/assets/Scripts/chat18x/config.meta b/assets/Scripts/chat18x/config.meta new file mode 100644 index 00000000..ddeb38e5 --- /dev/null +++ b/assets/Scripts/chat18x/config.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "78089db8-0ee4-4f29-9a3b-8ee927360d57", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/config/env.meta b/assets/Scripts/chat18x/config/env.meta new file mode 100644 index 00000000..a13297ee --- /dev/null +++ b/assets/Scripts/chat18x/config/env.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "d82373f7-a30d-43a3-84b1-e4d7e37c8e09", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/config/env/appConfig.ts b/assets/Scripts/chat18x/config/env/appConfig.ts new file mode 100644 index 00000000..11a99095 --- /dev/null +++ b/assets/Scripts/chat18x/config/env/appConfig.ts @@ -0,0 +1,126 @@ +/** + * 整个APP的环境配置逻辑 + */ +import { sys } from "cc"; +import { DEBUG, EDITOR, PREVIEW } from "cc/env"; +import { Env, AppConfigShape } from "./env"; +import { devConfig } from "./dev"; +import { testConfig } from "./test"; +import { prodConfig } from "./prod"; + +type PartialEndpoints = Partial; + +const LS_ENV_KEY = "app_env"; +const LS_OVERRIDE_KEY = "app_endpoints_override"; // 存JSON字符串 + +export class AppConfig { + private static _I: AppConfig | null = null; + static get I(): AppConfig { + if (!AppConfig._I) AppConfig._I = new AppConfig(); + return AppConfig._I; + } + + private _cfg!: AppConfigShape; + + private constructor() { + const env = this.detectEnv(); + this._cfg = this.byEnv(env); + + // 运行时覆盖:query > localStorage + // this.applyQueryOverride(); + // this.applyLocalOverride(); + } + + /** 外部读取用 */ + get env() { return this._cfg.env; } + get endpoints() { return this._cfg.endpoints; } + + /** 切换环境(开发工具用) */ + public switchEnv(env: Env) { + this._cfg = this.byEnv(env); + sys.localStorage.setItem(LS_ENV_KEY, env); + } + + /** 运行时局部覆盖 endpoints(紧急切换) */ + public overrideEndpoints(patch: PartialEndpoints) { + this._cfg = { + ...this._cfg, + endpoints: { ...this._cfg.endpoints, ...patch, cdn: { ...this._cfg.endpoints.cdn, ...(patch.cdn || {}) } } + }; + sys.localStorage.setItem(LS_OVERRIDE_KEY, JSON.stringify(patch)); + } + + /** 清除覆盖,回到纯环境配置 */ + public clearOverrides() { + sys.localStorage.removeItem(LS_OVERRIDE_KEY); + this._cfg = this.byEnv(this._cfg.env); + } + + /** 获取 HTTP 基础地址 + * @param stripTrailingSlash 是否去掉末尾斜杠,默认 true + */ + public getHttpBase(stripTrailingSlash: boolean = true): string { + const raw = this._cfg.endpoints.httpBase || ""; + if (stripTrailingSlash) { + return raw.replace(/\/+$/, ""); + } + // 保证有一个结尾斜杠 + return raw.endsWith("/") ? raw : raw + "/"; + } + + // ------------ 内部 ------------ + private byEnv(env: Env): AppConfigShape { + switch (env) { + case Env.Dev: return devConfig; + case Env.Test: return testConfig; + default: return prodConfig; + } + } + + private isEnv(x: any): x is Env { + return x === Env.Dev || x === Env.Test || x === Env.Prod; + } + + /** 默认环境:优先 localStorage,再看 EDITOR/DEBUG,最后 prod */ + private detectEnv(): Env { + const saved = sys.localStorage.getItem(LS_ENV_KEY) as Env | null; + if (saved && this.isEnv(saved)) { + return saved; + } + // 编辑器/预览时默认 dev + if (EDITOR || (PREVIEW && DEBUG)) return Env.Dev; + // 调试构建默认 test + if (DEBUG) return Env.Test; + // 发行构建默认 prod + return Env.Prod; + } + + private applyLocalOverride() { + const raw = sys.localStorage.getItem(LS_OVERRIDE_KEY); + if (raw) { + try { + this.overrideEndpoints(JSON.parse(raw)); + } catch { /* ignore */ } + } + } + + /** 支持浏览器 query 覆盖:?env=test&http=...&socket=...&cdn_bgm=... */ + private applyQueryOverride() { + if (!sys.isBrowser) return; + const qs = new URLSearchParams(window.location.search); + const qEnv = qs.get("env") as Env | null; + if (qEnv && this.isEnv(qEnv)) { + this._cfg = this.byEnv(qEnv); + sys.localStorage.setItem(LS_ENV_KEY, qEnv); + } + const patch: PartialEndpoints = {}; + if (qs.get("http")) (patch.httpBase = qs.get("http")!); + if (qs.get("socket")) (patch.socketBase = qs.get("socket")!); + const cdnPatch: any = {}; + if (qs.get("cdn_bgm")) cdnPatch.bgm = qs.get("cdn_bgm"); + if (qs.get("cdn_zhen")) cdnPatch.zhenCang = qs.get("cdn_zhen"); + if (qs.get("cdn_bgvideo")) cdnPatch.bgVideo = qs.get("cdn_bgvideo"); + if (Object.keys(cdnPatch).length) (patch.cdn = cdnPatch); + if (Object.keys(patch).length) this.overrideEndpoints(patch); + } +} diff --git a/assets/Scripts/chat18x/config/env/appConfig.ts.meta b/assets/Scripts/chat18x/config/env/appConfig.ts.meta new file mode 100644 index 00000000..e81e812c --- /dev/null +++ b/assets/Scripts/chat18x/config/env/appConfig.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "56e9ec0c-c2ef-4ace-89f7-73829135c361", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/config/env/dev.ts b/assets/Scripts/chat18x/config/env/dev.ts new file mode 100644 index 00000000..7b568a4b --- /dev/null +++ b/assets/Scripts/chat18x/config/env/dev.ts @@ -0,0 +1,14 @@ +/** + * 开发环境配置 + */ +import { AppConfigShape, Env } from "./env"; +export const devConfig: AppConfigShape = { + env: Env.Dev, + endpoints: { + httpBase: "http://43.139.27.67:8081/", + socketBase: "ws://127.0.0.1:9001/ws/", + cdn: { + bgm: "http://127.0.0.1:8081/BGM/", + }, + }, +}; \ No newline at end of file diff --git a/assets/Scripts/chat18x/config/env/dev.ts.meta b/assets/Scripts/chat18x/config/env/dev.ts.meta new file mode 100644 index 00000000..88f4fc48 --- /dev/null +++ b/assets/Scripts/chat18x/config/env/dev.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "c1151830-fdb3-40f2-a317-9a5f37aed7d8", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/config/env/env.ts b/assets/Scripts/chat18x/config/env/env.ts new file mode 100644 index 00000000..373acd0f --- /dev/null +++ b/assets/Scripts/chat18x/config/env/env.ts @@ -0,0 +1,25 @@ +/** + * 环境的类型,接口定义 + */ +export enum Env { + Dev = "dev", + Test = "test", + Prod = "prod", +} + +export interface CDNConfig { + bgm: string; +} + +export interface Endpoints { + httpBase: string; // 业务 HTTP + socketBase: string; // WebSocket + cdn: CDNConfig; // 各类静态资源 +} + +export interface AppConfigShape { + env: Env; + endpoints: Endpoints; + // 其他:开关、埋点、灰度、版本号…… +} + \ No newline at end of file diff --git a/assets/Scripts/chat18x/config/env/env.ts.meta b/assets/Scripts/chat18x/config/env/env.ts.meta new file mode 100644 index 00000000..f5f15c96 --- /dev/null +++ b/assets/Scripts/chat18x/config/env/env.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "4d45e3c5-2567-4426-a736-0329df3f0549", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/config/env/prod.ts b/assets/Scripts/chat18x/config/env/prod.ts new file mode 100644 index 00000000..159a2190 --- /dev/null +++ b/assets/Scripts/chat18x/config/env/prod.ts @@ -0,0 +1,14 @@ +/** + * 生产环境配置 + */ +import { AppConfigShape, Env } from "./env"; +export const prodConfig: AppConfigShape = { + env: Env.Prod, + endpoints: { + httpBase: "https://xqmnyx.vip.hnhxzkj.com/api/", + socketBase: "wss://www.confessioncontract.com/game/ai/response/", + cdn: { + bgm: "https://hxzgame.vip.hnhxzkj.com/lzx/XiangQin/BGM/", + }, + }, +}; \ No newline at end of file diff --git a/assets/Scripts/chat18x/config/env/prod.ts.meta b/assets/Scripts/chat18x/config/env/prod.ts.meta new file mode 100644 index 00000000..e5943286 --- /dev/null +++ b/assets/Scripts/chat18x/config/env/prod.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "80fc473d-912a-4b60-824f-f6de8db5e4c3", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/config/env/test.ts b/assets/Scripts/chat18x/config/env/test.ts new file mode 100644 index 00000000..65ca48af --- /dev/null +++ b/assets/Scripts/chat18x/config/env/test.ts @@ -0,0 +1,14 @@ +/** + * 测试环境配置 + */ +import { AppConfigShape, Env } from "./env"; +export const testConfig: AppConfigShape = { + env: Env.Test, + endpoints: { + httpBase: "http://43.139.27.67:8081/", + socketBase: "wss://www.confessioncontract.com/test/game/ai/response/", + cdn: { + bgm: "https://test-cdn.example.com/BGM/", + }, + }, +}; \ No newline at end of file diff --git a/assets/Scripts/chat18x/config/env/test.ts.meta b/assets/Scripts/chat18x/config/env/test.ts.meta new file mode 100644 index 00000000..d9dd4cc3 --- /dev/null +++ b/assets/Scripts/chat18x/config/env/test.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "9cbbaeca-8a67-49c7-8c2c-75afedc8d8c0", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/chat18x/network/client/ApiClient.ts b/assets/Scripts/chat18x/network/client/ApiClient.ts index 77909997..ef7fab38 100644 --- a/assets/Scripts/chat18x/network/client/ApiClient.ts +++ b/assets/Scripts/chat18x/network/client/ApiClient.ts @@ -1,4 +1,3 @@ - import { HttpManager, HttpMethod } from "../transport/HttpManager"; import { JsonCodec } from "../codec/JsonCodec"; import { ProtoCodec } from "../codec/ProtoCodec"; @@ -6,6 +5,7 @@ import type { Endpoint } from "./endpoints"; import { ApiCode, type ApiResponse } from "./types"; import { DataManager, DataId } from "db://assets/Scripts/chat18x/data/DataManager"; import { LoginData } from "db://assets/Scripts/chat18x/data/LoginData"; +import { AppConfig } from "db://assets/Scripts/chat18x/config/env/appConfig"; export class ApiClient { private static _I: ApiClient | null = null; @@ -14,8 +14,7 @@ export class ApiClient { return ApiClient._I; } private constructor(private http = HttpManager.I) {} - // TODO - private get baseUrl() { return "http://43.139.27.67:8081" } + private get baseUrl() { return AppConfig.I.getHttpBase() } private get token() { return DataManager.I.getDataById(DataId.Login).getToken();} public async call(ep: Endpoint, req: Req): Promise> { diff --git a/assets/Scripts/chat18x/network/client/endpoints.ts b/assets/Scripts/chat18x/network/client/endpoints.ts index 091c0ac0..1820a91d 100644 --- a/assets/Scripts/chat18x/network/client/endpoints.ts +++ b/assets/Scripts/chat18x/network/client/endpoints.ts @@ -6,9 +6,8 @@ export type CodecKind = "json" | "proto"; export interface Endpoint { path: string; method: HttpMethod; - codec: CodecKind; - reqType?: Type; // codec=proto 时必填 - resType?: Type; // codec=proto 时必填 - needsAuth?: boolean; - lock?: boolean; + codec: CodecKind; // 编解码类型,"json", "proto" + reqType?: Type; // codec=proto 时必填 + resType?: Type; // codec=proto 时必填 + needsAuth?: boolean; // 是否需要token } \ No newline at end of file diff --git a/assets/Scripts/chat18x/network/services/AuthService.ts b/assets/Scripts/chat18x/network/services/AuthService.ts index 03fc8f9b..1dd53c02 100644 --- a/assets/Scripts/chat18x/network/services/AuthService.ts +++ b/assets/Scripts/chat18x/network/services/AuthService.ts @@ -11,15 +11,14 @@ export class AuthService { } private constructor(private api = ApiClient.I) {} - private EP_LOGIN: Endpoint = { - path: "login", - method: "POST", - codec: "json", - needsAuth: false - }; - // 登录 public async login(req: proto.ProtoMsg.ILoginReq): Promise> { - return this.api.call(this.EP_LOGIN, req); + let EP_LOGIN: Endpoint = { + path: "login", + method: "POST", + codec: "json", + needsAuth: false + }; + return this.api.call(EP_LOGIN, req); } }