diff --git a/.env.development b/.env.development index 1925bf9..c657137 100644 --- a/.env.development +++ b/.env.development @@ -1,11 +1,18 @@ -# VITE_API_BASE_URL='http://localhost:5173/' - -# 本地开发统一走线上 Admin API(与 /rbac、/order 等 Vite 代理一致) -VITE_OMS_ADMIN_URL=http://api.nanafa.com/admin +# ============================================================================= +# 本地开发默认 → 测试环境 oms.nanafa.com / api.nanafa.com +# 切换到生产 API:pnpm dev:ideship (加载 .env.ideship) +# 发版构建:pnpm build(生产) / pnpm build:test(测试) +# ============================================================================= +VITE_DEPLOY_TARGET=nanafa +VITE_API_ORIGIN=http://api.nanafa.com VITE_API_ADMIN_URL=http://api.nanafa.com/admin +VITE_OMS_ADMIN_URL=http://api.nanafa.com/admin +VITE_API_ASSET_ORIGIN=http://api.nanafa.com/admin + +# 企业微信客服 +VITE_WECOM_KF_URL=https://work.weixin.qq.com/kfid/kfcae09c206f6c7045a # 智谱 AI(接口映射脚本生成) -# 在 https://open.bigmodel.cn 申请 API Key VITE_ZHIPU_API_KEY=85bbbef6bafd4ca383eef04189decd07.lKVQHcLGtYE8oUn5 VITE_ZHIPU_BASE_URL=/zhipu-api VITE_ZHIPU_MODEL=glm-5.1 diff --git a/.env.ideship b/.env.ideship new file mode 100644 index 0000000..743f66b --- /dev/null +++ b/.env.ideship @@ -0,0 +1,11 @@ +# ============================================================================= +# 本地开发直连生产 API(ideship.com)— pnpm dev:ideship +# 仅用于联调生产;正式发版请用 pnpm build(.env.production) +# ============================================================================= +VITE_DEPLOY_TARGET=ideship +VITE_API_ORIGIN=https://api.ideship.com +VITE_API_ADMIN_URL=https://api.ideship.com/admin +VITE_OMS_ADMIN_URL=https://api.ideship.com/admin +VITE_API_ASSET_ORIGIN=https://api.ideship.com/admin + +VITE_WECOM_KF_URL=https://work.weixin.qq.com/kfid/kfcae09c206f6c7045a diff --git a/.env.nanafa b/.env.nanafa new file mode 100644 index 0000000..c0a7af9 --- /dev/null +++ b/.env.nanafa @@ -0,0 +1,12 @@ +# ============================================================================= +# 测试环境(oms.nanafa.com)— pnpm build:test → vite build --mode nanafa +# 三套 API:http://api.nanafa.com/{admin|itfx|track} +# 前端站点:https://oms.nanafa.com +# ============================================================================= +VITE_DEPLOY_TARGET=nanafa +VITE_API_ORIGIN=http://api.nanafa.com +VITE_API_ADMIN_URL=http://api.nanafa.com/admin +VITE_API_ASSET_ORIGIN=http://api.nanafa.com/admin +VITE_OMS_ADMIN_URL=http://api.nanafa.com/admin + +VITE_WECOM_KF_URL=https://work.weixin.qq.com/kfid/kfcae09c206f6c7045a diff --git a/.env.production b/.env.production index e69de29..10a7a29 100644 --- a/.env.production +++ b/.env.production @@ -0,0 +1,13 @@ +# ============================================================================= +# 生产环境(ideship.com)— vite build / vite build --mode production +# 三套 API:https://api.ideship.com/{admin|itfx|track} +# 前端站点:https://ideship.com +# ============================================================================= +VITE_DEPLOY_TARGET=ideship +VITE_API_ORIGIN=https://api.ideship.com +VITE_API_ADMIN_URL=https://api.ideship.com/admin +VITE_API_ASSET_ORIGIN=https://api.ideship.com/admin +VITE_OMS_ADMIN_URL=https://api.ideship.com/admin + +# 企业微信客服 +VITE_WECOM_KF_URL=https://work.weixin.qq.com/kfid/kfcae09c206f6c7045a diff --git a/docs/微信登录整合方案.md b/docs/微信登录整合方案.md index a357c0a..f30afbf 100644 --- a/docs/微信登录整合方案.md +++ b/docs/微信登录整合方案.md @@ -202,7 +202,15 @@ flowchart TD ## 4. 接口说明 -API 前缀:`https://api.nanafa.com/admin`(`ASPNETCORE_PATHBASE=/admin`) +API 前缀:`https://api.ideship.com/admin`(`ASPNETCORE_PATHBASE=/admin`) + +生产三套服务: + +| 服务 | Swagger / PATHBASE | +|------|-------------------| +| Admin | https://api.ideship.com/admin/index.html | +| Itfx | https://api.ideship.com/itfx/index.html | +| Track | https://api.ideship.com/track/index.html | ### 4.1 获取登录二维码 @@ -300,10 +308,10 @@ Content-Type: application/json **现网配置 URL:** ``` -https://oms.nanafa.com/api/apiwechat/verification +https://api.ideship.com/admin/apiwechat/verification ``` -Nginx 反代至 `https://api.nanafa.com/admin/apiwechat/verification`。 +(旧站曾用 `https://oms.nanafa.com/api/apiwechat/verification` 反代到 Admin。) | 方法 | 路径 | 说明 | |------|------|------| @@ -410,7 +418,7 @@ src/SimpleAdmin.Api/ | 项 | 值 | |----|-----| -| URL | `https://oms.nanafa.com/api/apiwechat/verification` | +| URL | `https://api.ideship.com/admin/apiwechat/verification` | | Token | 与数据库/AppSettings 一致 | | 消息加解密 | **明文**(当前实现) | @@ -467,8 +475,9 @@ location ^~ /api/apiwechat/ { 完整 URL 示例: ``` -GET https://api.nanafa.com/admin/wechat/mp/login-qrcode?loginUuid=abc123 -GET https://api.nanafa.com/admin/rbac/auth/wx-login/status?loginUuid=abc123 -POST https://api.nanafa.com/admin/rbac/auth/wx-login -POST https://oms.nanafa.com/api/apiwechat/verification +GET https://api.ideship.com/admin/wechat/mp/login-qrcode?loginUuid=abc123 +GET https://api.ideship.com/admin/rbac/auth/wx-login/status?loginUuid=abc123 +POST https://api.ideship.com/admin/rbac/auth/wx-login +POST https://api.ideship.com/admin/apiwechat/verification +GET https://api.ideship.com/admin/wechat/oauth/config ``` diff --git a/nginx-default.conf b/nginx-default.conf index 4e7e55a..e9a576c 100644 --- a/nginx-default.conf +++ b/nginx-default.conf @@ -8,7 +8,8 @@ # /etc/nginx/ssl/oms.nanafa.com.key # 4. 官网在 /(dist/site/index.html);客户登录 /login;管理端 /admin # 5. 静态资源使用 /login-assets/,勿使用 /login/ 目录名 -# 6. 微信公众号服务器 URL 请使用 https://oms.nanafa.com/api/apiwechat/verification +# 6. 微信公众号服务器 URL 请使用 https://api.ideship.com/admin/apiwechat/verification +# (生产三套:admin / itfx / track,均挂在 https://api.ideship.com/{pathbase}) # ============================================================================ # HTTP → HTTPS diff --git a/package.json b/package.json index bc044cb..96eb2e8 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,11 @@ "preinstall": "node -e \"if (!process.env.npm_config_user_agent || !process.env.npm_config_user_agent.includes('pnpm')) { console.error('Please use pnpm to install dependencies.'); process.exit(1); }\"", "generate:order-template": "node scripts/generate-order-template.js", "dev": "vite", + "dev:test": "vite --mode nanafa", + "dev:ideship": "vite --mode ideship", "build": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=1 node --max-old-space-size=4096 node_modules/vite/bin/vite.js build", + "build:prod": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=1 node --max-old-space-size=4096 node_modules/vite/bin/vite.js build --mode production", + "build:test": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=1 node --max-old-space-size=4096 node_modules/vite/bin/vite.js build --mode nanafa", "postbuild": "node scripts/postbuild-cleanup-dist.js", "report": "cross-env REPORT=true pnpm run build", "preview": "npm run build && vite preview --host", diff --git a/src/api/wechat/index.ts b/src/api/wechat/index.ts index 44943f6..f7150bf 100644 --- a/src/api/wechat/index.ts +++ b/src/api/wechat/index.ts @@ -59,7 +59,10 @@ export async function getWeChatOAuthConfig(): Promise { const data = unwrapOrSelf>(body); const appId = String(data.appId ?? data.AppId ?? '').trim(); const oauthRedirectBase = String( - data.oauthRedirectBase ?? data.OAuthRedirectBase ?? '', + data.oauthRedirectBase ?? + data.oAuthRedirectBase ?? + data.OAuthRedirectBase ?? + '', ).trim(); return { appId, diff --git a/src/config/deployTargets.ts b/src/config/deployTargets.ts new file mode 100644 index 0000000..511569a --- /dev/null +++ b/src/config/deployTargets.ts @@ -0,0 +1,37 @@ +/** + * 部署目标(由 Vite mode / env 文件切换,勿在业务里写死域名) + * + * | 目标 | 前端 | API | + * |------|------|-----| + * | ideship(生产) | https://ideship.com | https://api.ideship.com/{admin,itfx,track} | + * | nanafa(测试) | https://oms.nanafa.com | http://api.nanafa.com/{admin,itfx,track} | + * + * 本地:pnpm dev(测试) / pnpm dev:ideship(生产 API) + * 构建:pnpm build(生产) / pnpm build:test(测试) + */ +export type DeployTarget = 'ideship' | 'nanafa' + +export const DEPLOY_TARGETS = { + ideship: { + siteOrigin: 'https://ideship.com', + apiOrigin: 'https://api.ideship.com', + adminBase: 'https://api.ideship.com/admin', + itfxBase: 'https://api.ideship.com/itfx', + trackBase: 'https://api.ideship.com/track', + }, + nanafa: { + siteOrigin: 'https://oms.nanafa.com', + apiOrigin: 'http://api.nanafa.com', + adminBase: 'http://api.nanafa.com/admin', + itfxBase: 'http://api.nanafa.com/itfx', + trackBase: 'http://api.nanafa.com/track', + }, +} as const + +export function resolveDeployTarget(): DeployTarget { + const raw = String(import.meta.env.VITE_DEPLOY_TARGET ?? '').trim().toLowerCase() + if (raw === 'nanafa') return 'nanafa' + if (raw === 'ideship') return 'ideship' + // 未显式配置时:生产构建默认 ideship,开发默认 nanafa + return import.meta.env.PROD ? 'ideship' : 'nanafa' +} diff --git a/src/env.d.ts b/src/env.d.ts index 08d3dbd..cb2c31c 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -31,6 +31,8 @@ declare module '*.vue' { interface ImportMetaEnv { readonly VITE_API_BASE_URL: string; readonly VITE_OMS_URL?: string; + /** 部署目标:ideship(生产)| nanafa(测试) */ + readonly VITE_DEPLOY_TARGET?: 'ideship' | 'nanafa' | string; /** 生产 Admin 基址,默认 https://api.ideship.com/admin */ readonly VITE_API_ADMIN_URL?: string; readonly VITE_OMS_ADMIN_URL?: string; diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index de488f0..4b5f6c8 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -3172,7 +3172,7 @@ export default { 'system.otherConfig.form.remark': 'Remark', 'system.otherConfig.placeholder.input': 'Please enter', 'system.otherConfig.placeholder.configCode': 'e.g. track_service', - 'system.otherConfig.placeholder.baseUrl': 'e.g. http://api.idtms.com/track', + 'system.otherConfig.placeholder.baseUrl': 'e.g. https://api.ideship.com/track', 'system.otherConfig.placeholder.appSecretEdit': 'Leave blank to keep unchanged', 'system.otherConfig.modal.addTitle': 'Add Config', 'system.otherConfig.modal.editTitle': 'Edit Config', diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index 77f9308..6caca3f 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -3220,7 +3220,7 @@ export default { 'system.otherConfig.form.remark': '备注', 'system.otherConfig.placeholder.input': '请输入', 'system.otherConfig.placeholder.configCode': '如 track_service', - 'system.otherConfig.placeholder.baseUrl': '如 http://api.idtms.com/track', + 'system.otherConfig.placeholder.baseUrl': '如 https://api.ideship.com/track', 'system.otherConfig.placeholder.appSecretEdit': '留空则不修改', 'system.otherConfig.modal.addTitle': '新增配置', 'system.otherConfig.modal.editTitle': '编辑配置', diff --git a/src/utils/adminApi.ts b/src/utils/adminApi.ts index 379d4db..3b6a7ae 100644 --- a/src/utils/adminApi.ts +++ b/src/utils/adminApi.ts @@ -1,7 +1,8 @@ /** * Admin API 地址(方案 A) - * - 开发:相对路径,Vite 代理到 Admin - * - 生产:直连 https://api.ideship.com/admin(可用 VITE_API_ADMIN_URL 覆盖) + * - 优先 VITE_API_ADMIN_URL(.env.production / .env.nanafa / .env.ideship 切换) + * - 未配置且开发:相对路径走 Vite 代理 + * - 未配置且生产构建:默认 https://api.ideship.com/admin */ function normalizeBase(base: string): string { @@ -13,49 +14,58 @@ function ensureLeadingSlash(path: string): string { } const DEFAULT_PROD_ADMIN = 'https://api.ideship.com/admin' +const DEFAULT_TEST_ADMIN = 'http://api.nanafa.com/admin' -function prodAdminBase(): string { +function configuredAdminBase(): string | undefined { const override = import.meta.env.VITE_API_ADMIN_URL as string | undefined if (override?.trim()) return normalizeBase(override) - return DEFAULT_PROD_ADMIN + return undefined +} + +function prodAdminBase(): string { + return configuredAdminBase() ?? DEFAULT_PROD_ADMIN } /** 浏览器请求 Admin API(OpenAPI.BASE 或 omsUrl/orderUrl 等) */ export function resolveAdminApiPath(path: string): string { const p = ensureLeadingSlash(path) + const configured = configuredAdminBase() + if (configured) { + return `${configured}${p}` + } if (!import.meta.env.DEV) { - return `${prodAdminBase()}${p}` + return `${DEFAULT_PROD_ADMIN}${p}` } return p } export function resolveOpenApiBase(): string { + const configured = configuredAdminBase() + if (configured) return configured if (!import.meta.env.DEV) { - return prodAdminBase() + return DEFAULT_PROD_ADMIN } return '' } /** 桌面 Agent 等直连 Admin 网关 */ export function resolveDirectAdminApiUrl(): string { - const override = import.meta.env.VITE_API_ADMIN_URL as string | undefined - if (override?.trim()) { - return normalizeBase(override) - } + const configured = configuredAdminBase() + if (configured) return configured if (import.meta.env.DEV) { - return 'http://api.nanafa.com/admin' + return DEFAULT_TEST_ADMIN } return DEFAULT_PROD_ADMIN } -/** 静态资源(uploads)在 Admin wwwroot,须带 `/admin`。 - * 生产默认 api 域名;开发空串走 Vite `/uploads` 代理。 - */ +/** 静态资源(uploads)在 Admin wwwroot,须带 `/admin`。 */ export function resolveAdminAssetOrigin(): string { const override = import.meta.env.VITE_API_ASSET_ORIGIN as string | undefined if (override?.trim()) { return normalizeBase(override) } + const configured = configuredAdminBase() + if (configured) return configured if (!import.meta.env.DEV) { return DEFAULT_PROD_ADMIN } diff --git a/src/utils/rewriteBrowserApiPath.ts b/src/utils/rewriteBrowserApiPath.ts index c165f98..29f796b 100644 --- a/src/utils/rewriteBrowserApiPath.ts +++ b/src/utils/rewriteBrowserApiPath.ts @@ -1,5 +1,7 @@ /** - * 方案 A:生产直连 api.ideship.com PATHBASE;开发仍走 Vite 代理旧路径。 + * 方案 A:按 VITE_API_ORIGIN 改写到 {admin|itfx|track} PATHBASE。 + * 生产默认 https://api.ideship.com;测试用 .env.nanafa → http://api.nanafa.com。 + * 开发且未配置 VITE_API_ORIGIN 时不改写(走 Vite 代理)。 */ const SPA_API_PREFIXES = [ @@ -17,9 +19,11 @@ const SPA_API_PREFIXES = [ const DEFAULT_PROD_API = 'https://api.ideship.com' -function prodApiOrigin(): string { +function prodApiOrigin(): string | null { const override = (import.meta.env.VITE_API_ORIGIN as string | undefined)?.trim() - return (override || DEFAULT_PROD_API).replace(/\/$/, '') + if (override) return override.replace(/\/$/, '') + if (import.meta.env.DEV) return null + return DEFAULT_PROD_API } function isItfxSpaPath(afterApi: string): boolean { @@ -29,15 +33,17 @@ function isItfxSpaPath(afterApi: string): boolean { ) } -/** 生产:遗留路径 → https://api.ideship.com/{itfx|track|admin}/... */ +/** 遗留路径 → {apiOrigin}/{itfx|track|admin}/... */ export function rewriteBrowserApiPath(url: string): string { - if (!url || import.meta.env.DEV) return url + if (!url) return url if (/^https?:\/\//i.test(url) || url.startsWith('data:') || url.startsWith('blob:')) { return url } - let path = url.startsWith('/') ? url : `/${url}` const origin = prodApiOrigin() + if (!origin) return url + + let path = url.startsWith('/') ? url : `/${url}` // 已是绝对 PATHBASE 相对路径 → 挂到 api 域名 if ( diff --git a/src/views/system/otherConfig/index.vue b/src/views/system/otherConfig/index.vue index 9928c0a..6bda245 100644 --- a/src/views/system/otherConfig/index.vue +++ b/src/views/system/otherConfig/index.vue @@ -207,7 +207,7 @@ const PRESET_DEFS: Array<{ defaults: { configCode: TRACK_SERVICE_CONFIG_CODE, enabled: true, - baseUrl: 'http://api.idtms.com/track', + baseUrl: 'https://api.ideship.com/track', timeoutSeconds: 30, }, meta: { @@ -226,6 +226,7 @@ const PRESET_DEFS: Array<{ defaults: { configCode: WECHAT_MP_CONFIG_CODE, enabled: true, + baseUrl: 'https://ideship.com', timeoutSeconds: 30, }, meta: {