From 85a1558e845ab20bde7a6eedf7b2bae93ed3c581 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com>
Date: Thu, 16 Jul 2026 01:34:27 +0800
Subject: [PATCH] =?UTF-8?q?feat(passport):=20=E8=BF=81=E7=A7=BB=E5=B9=B6?=
=?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=94=AF=E4=BB=98?=
=?UTF-8?q?=E9=A1=B5=E9=9D=A2=E8=AE=BF=E9=97=AE=20websopy=20API=20?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 迁移 src/passport/pay 相关代码至当前项目,无需替换文件
- 新增环境变量 WEBSOPY_API_BASE_URL,提供 websopy API 基础地址
- 在 config/app.ts 导出 WebsopyBaseUrl,供代码引用
- 配置 env.d.ts 类型定义,消除 TypeScript 隐式 any 错误
- request 请求方法支持自定义 baseUrl 以调用不同接口地址
- passport/pay 页面调用订阅接口统一传入 WebsopyBaseUrl
- 修正 tenantId 类型为 number,调整登录用户类型断言
- 确认编译成功,dist 目录生成对应文件及正确请求地址
- 说明 type-check 依赖库问题不影响正常构建和运行
---
.idea/workspace.xml | 32 +++++++++++++++++++-------------
.workbuddy/memory/2026-07-16.md | 15 ++++++++++++++-
config/app.ts | 3 ++-
config/env.d.ts | 30 ++++++++++++++++++++++++++++++
config/env.js | 5 ++++-
src/passport/pay/index.tsx | 16 ++++++++++------
src/utils/request.ts | 25 +++++++++++++------------
taro-feature-migration.zip | Bin 0 -> 1590 bytes
8 files changed, 92 insertions(+), 34 deletions(-)
create mode 100644 config/env.d.ts
create mode 100644 taro-feature-migration.zip
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index b56158b..cbdef5b 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,7 +4,13 @@
-
+
+
+
+
+
+
+
@@ -111,15 +117,7 @@
-
-
-
-
- 1775896148590
-
-
-
- 1775896148590
+
@@ -505,7 +503,15 @@
1784131564427
-
+
+
+ 1784135922873
+
+
+
+ 1784135922873
+
+
@@ -525,7 +531,6 @@
-
@@ -550,7 +555,8 @@
-
+
+
\ No newline at end of file
diff --git a/.workbuddy/memory/2026-07-16.md b/.workbuddy/memory/2026-07-16.md
index 919d357..f5799b5 100644
--- a/.workbuddy/memory/2026-07-16.md
+++ b/.workbuddy/memory/2026-07-16.md
@@ -13,4 +13,17 @@
- 补充 `register`(`src/passport/register.tsx` 存在但未声明)
- 统一引号风格、清理尾随逗号
-待确认:phone-auth / invite / webview 三个页面是否需要新建(目前无文件、无引用)。
+## passport/pay 功能从 websopy-taro-bak 迁移
+
+问题:`src/passport/pay/index.tsx` 失效,原因是当前项目基于 xinlong-shop 框架,`API_BASE_URL` 指向商城接口 `https://shop-api.websoft.top/api`,而 pay 页面需要访问 websopy 业务接口 `https://websopy-api.websoft.top/api` 的 `/app/subscription/*`。
+
+迁移与修复:
+- 确认 `src/passport/pay/` 与 `src/api/passport/wx-login/` 文件和备份项目一致,无需替换。
+- 在 `config/env.js` 新增 `WEBSOPY_API_BASE_URL`。
+- 在 `config/app.ts` 导出 `WebsopyBaseUrl`。
+- 创建 `config/env.d.ts` 消除 `config/app.ts` 导入 `.js` 的隐式 any 类型错误。
+- 增强 `src/utils/request.ts`:在 `RequestConfig` 增加 `baseUrl?: string`,`request`/`get`/`post` 等函数支持自定义 baseUrl,相对路径会自动拼接;完整 URL 保持不变。
+- 修改 `src/passport/pay/index.tsx`:三个订阅接口请求均传入 `baseUrl: WebsopyBaseUrl`;修复 `tenantId` 类型(string -> number)和 `saveStorageByLoginUser` 的 user 类型断言。
+- 运行 `npx taro build --type weapp` 构建成功;dist 中 `passport/pay` 文件生成,确认请求使用 websopy API。
+- 说明:`npm run type-check` 仍因 `@tarojs/taro` 类型包解析问题失败,这是项目既有环境问题,不影响构建。
+
diff --git a/config/app.ts b/config/app.ts
index 822a56d..48a03ae 100644
--- a/config/app.ts
+++ b/config/app.ts
@@ -1,7 +1,8 @@
-import { API_BASE_URL, SERVER_API_URL } from './env'
+import { API_BASE_URL, SERVER_API_URL, WEBSOPY_API_BASE_URL } from './env'
export const TenantId = '5'
export const TenantName = '威硕开发助手'
export const BaseUrl = API_BASE_URL
export const ServerBaseUrl = SERVER_API_URL
+export const WebsopyBaseUrl = WEBSOPY_API_BASE_URL
export const Version = 'v3.0.0'
diff --git a/config/env.d.ts b/config/env.d.ts
new file mode 100644
index 0000000..4c1ef61
--- /dev/null
+++ b/config/env.d.ts
@@ -0,0 +1,30 @@
+export const CURRENT_ENV: string
+export const ENV_CONFIG: {
+ development: {
+ API_BASE_URL: string
+ SERVER_API_URL: string
+ WEBSOPY_API_BASE_URL: string
+ APP_NAME: string
+ DEBUG: string
+ }
+ test: {
+ API_BASE_URL: string
+ SERVER_API_URL: string
+ WEBSOPY_API_BASE_URL: string
+ APP_NAME: string
+ DEBUG: string
+ }
+ production: {
+ API_BASE_URL: string
+ SERVER_API_URL: string
+ WEBSOPY_API_BASE_URL: string
+ APP_NAME: string
+ DEBUG: string
+ }
+}
+export function getEnvConfig(): (typeof ENV_CONFIG)[keyof typeof ENV_CONFIG]
+export const API_BASE_URL: string
+export const SERVER_API_URL: string
+export const WEBSOPY_API_BASE_URL: string
+export const APP_NAME: string
+export const DEBUG: string
diff --git a/config/env.js b/config/env.js
index b233b5a..808fe7e 100644
--- a/config/env.js
+++ b/config/env.js
@@ -4,18 +4,21 @@ export const ENV_CONFIG = {
development: {
API_BASE_URL: 'https://shop-api.websoft.top/api',
SERVER_API_URL: 'https://server.websoft.top/api',
+ WEBSOPY_API_BASE_URL: 'https://websopy-api.websoft.top/api',
APP_NAME: '威硕谱软件',
DEBUG: 'true',
},
test: {
API_BASE_URL: 'https://shop-api.websoft.top/api',
SERVER_API_URL: 'https://server.websoft.top/api',
+ WEBSOPY_API_BASE_URL: 'https://websopy-api.websoft.top/api',
APP_NAME: '威硕谱软件',
DEBUG: 'true',
},
production: {
API_BASE_URL: 'https://shop-api.websoft.top/api',
SERVER_API_URL: 'https://server.websoft.top/api',
+ WEBSOPY_API_BASE_URL: 'https://websopy-api.websoft.top/api',
APP_NAME: '威硕谱软件',
DEBUG: 'false',
},
@@ -25,4 +28,4 @@ export function getEnvConfig() {
return ENV_CONFIG[CURRENT_ENV] || ENV_CONFIG.development
}
-export const { API_BASE_URL, SERVER_API_URL, APP_NAME, DEBUG } = getEnvConfig()
+export const { API_BASE_URL, SERVER_API_URL, WEBSOPY_API_BASE_URL, APP_NAME, DEBUG } = getEnvConfig()
diff --git a/src/passport/pay/index.tsx b/src/passport/pay/index.tsx
index 4aff7f2..dfc0324 100644
--- a/src/passport/pay/index.tsx
+++ b/src/passport/pay/index.tsx
@@ -5,8 +5,9 @@ import { Check, Close, Tips, Clock } from '@nutui/icons-react-taro'
import Taro from '@tarojs/taro'
import { request } from '@/utils/request'
import { getOpenId, loginByOpenId } from '@/api/passport/wx-login'
+import type { User } from '@/api/system/user/model'
import { saveStorageByLoginUser } from '@/utils/server'
-import { TenantId } from '@/config/app'
+import { TenantId, WebsopyBaseUrl } from '@/config/app'
/**
* 小程序支付页面
@@ -87,7 +88,8 @@ const PayPage: React.FC = () => {
const data: any = await request({
url: `/app/subscription/detail-by-no/${subscriptionNo}`,
method: 'GET',
- returnRaw: true // 先用 returnRaw=true 拿到完整响应,方便调试
+ returnRaw: true,
+ baseUrl: WebsopyBaseUrl
})
console.log('[PayPage] 接口完整返回(returnRaw=true):', JSON.stringify(data))
@@ -175,13 +177,13 @@ const PayPage: React.FC = () => {
try {
const loginResult = await loginByOpenId({
code: loginRes.code,
- tenantId: TenantId
+ tenantId: Number(TenantId)
})
console.log('[PayPage] loginByOpenId 结果:', loginResult)
if (loginResult.success && loginResult.data) {
// 登录成功,保存 token
- saveStorageByLoginUser(loginResult.data.access_token || '', loginResult.data.user)
+ saveStorageByLoginUser(loginResult.data.access_token || '', loginResult.data.user as unknown as User)
console.log('[PayPage] 自动登录成功,已保存 token')
} else {
console.warn('[PayPage] 自动登录失败:', loginResult.message)
@@ -211,7 +213,8 @@ const PayPage: React.FC = () => {
url: `/app/subscription/mp-prepay/${detail.id}`,
method: 'POST',
data: { openid },
- returnRaw: true
+ returnRaw: true,
+ baseUrl: WebsopyBaseUrl
})
console.log('[PayPage] mp-prepay 完整返回:', JSON.stringify(prepayRes))
@@ -240,7 +243,8 @@ const PayPage: React.FC = () => {
await request({
url: `/app/subscription/mp-confirm/${detail.subscriptionNo}`,
method: 'POST',
- data: {}
+ data: {},
+ baseUrl: WebsopyBaseUrl
})
} catch (confirmErr) {
console.warn('支付确认通知失败,等待轮询:', confirmErr)
diff --git a/src/utils/request.ts b/src/utils/request.ts
index b0b865e..8655ca7 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -12,6 +12,7 @@ export interface RequestConfig {
showLoading?: boolean
showError?: boolean
returnRaw?: boolean
+ baseUrl?: string
}
interface ApiResponse {
@@ -206,7 +207,7 @@ const retryRequest = async (config: RequestConfig, retryCount = 0): Promise(options: RequestConfig): Promise {
try {
- const config = requestInterceptor({ ...DEFAULT_CONFIG, ...options })
+ const config = requestInterceptor({ ...DEFAULT_CONFIG, ...options, url: buildUrl(options.url, options.baseUrl) })
return await retryRequest(config)
} catch (error) {
const requestError = error as RequestError
@@ -215,11 +216,11 @@ export async function request(options: RequestConfig): Promise {
}
}
-const buildUrl = (url: string): string => {
+const buildUrl = (url: string, customBaseUrl?: string): string => {
if (url.startsWith('http://') || url.startsWith('https://')) {
return url
}
- return `${baseUrl}${url}`
+ return `${customBaseUrl || baseUrl}${url}`
}
const buildQueryString = (params: Record): string => {
@@ -231,41 +232,41 @@ const buildQueryString = (params: Record): string => {
}
export function get(url: string, params?: any, config?: Partial): Promise {
- const fullUrl = buildUrl(url) + (params ? buildQueryString(params) : '')
+ const fullUrl = buildUrl(url, config?.baseUrl) + (params ? buildQueryString(params) : '')
return request({ url: fullUrl, method: 'GET', returnRaw: true, ...config })
}
export function post(url: string, data?: any, config?: Partial): Promise {
- return request({ url: buildUrl(url), method: 'POST', data, returnRaw: true, ...config })
+ return request({ url: buildUrl(url, config?.baseUrl), method: 'POST', data, returnRaw: true, ...config })
}
export function put(url: string, data?: any, config?: Partial): Promise {
- return request({ url: buildUrl(url), method: 'PUT', data, returnRaw: true, ...config })
+ return request({ url: buildUrl(url, config?.baseUrl), method: 'PUT', data, returnRaw: true, ...config })
}
export function patch(url: string, data?: any, config?: Partial): Promise {
- return request({ url: buildUrl(url), method: 'PATCH', data, returnRaw: true, ...config })
+ return request({ url: buildUrl(url, config?.baseUrl), method: 'PATCH', data, returnRaw: true, ...config })
}
export function del(url: string, data?: any, config?: Partial): Promise {
- return request({ url: buildUrl(url), method: 'DELETE', data, returnRaw: true, ...config })
+ return request({ url: buildUrl(url, config?.baseUrl), method: 'DELETE', data, returnRaw: true, ...config })
}
export function getData(url: string, params?: any, config?: Partial): Promise {
- const fullUrl = buildUrl(url) + (params ? buildQueryString(params) : '')
+ const fullUrl = buildUrl(url, config?.baseUrl) + (params ? buildQueryString(params) : '')
return request({ url: fullUrl, method: 'GET', returnRaw: false, ...config })
}
export function postData(url: string, data?: any, config?: Partial): Promise {
- return request({ url: buildUrl(url), method: 'POST', data, returnRaw: false, ...config })
+ return request({ url: buildUrl(url, config?.baseUrl), method: 'POST', data, returnRaw: false, ...config })
}
export function putData(url: string, data?: any, config?: Partial): Promise {
- return request({ url: buildUrl(url), method: 'PUT', data, returnRaw: false, ...config })
+ return request({ url: buildUrl(url, config?.baseUrl), method: 'PUT', data, returnRaw: false, ...config })
}
export function delData(url: string, data?: any, config?: Partial): Promise {
- return request({ url: buildUrl(url), method: 'DELETE', data, returnRaw: false, ...config })
+ return request({ url: buildUrl(url, config?.baseUrl), method: 'DELETE', data, returnRaw: false, ...config })
}
export default {
diff --git a/taro-feature-migration.zip b/taro-feature-migration.zip
new file mode 100644
index 0000000000000000000000000000000000000000..59e4d05f6efc73a7c465957532b23c8621a68a79
GIT binary patch
literal 1590
zcmai#dpHvc0L3Q_5yFhhqV5*M=20}2N?5av)->~2vRK7JW|&ekk36E#+@h?;5T>C*
z9_ew5WPBcDMkSG`l|0%tbanr~-#zD#^L^(#fBy~vr@R&f007hg(DmObS>0iW@_+z9
ziUt5+yxKCUjBvzB8kHHvpdmtoPcf*>;P5ajPn;Vbj|>gU^ujTu=nW%dpkp-^81uD+
zzmeY6dhI0?tRxT1Ul+Wo;G&{qb2OK=dEL~GDLF{cGkFA}Vm=c60x+>ZB$&hv!;z>Yo$i}2rqrG&K
zTMs2qq-(Sa9g8yfJ8>|wll4st+=9P8urmZ`TgFFsE%@B&>E5b?P_~(rTY-luDBpF8
zUz4emqz3N*H$Fv64yN|T%e&(fPo!7xYkr0cc$ExUKfls=Ysv!<)1sbGlB;Ye}
zLEG$w4&aNvOpenfZV8Vaq5=1*u4aY(@dD9`ZU1s@3c)?(0~g2=JiDV@Y#__?uekBQ
zR-`&XsMFjv&Fa<+u#7h?@QiJJyGf6ID1&bl1Ns3dBjO)
z-+R>E3VggZ1DbkOf4bAez9%W#iLaT`bdfRaik|G?rUyg$J~nEOmxPz98rH|
z7$vE8(QSt=uK7xqUNq)}`=+`gUb*$|RCYLOVLIpSalF}W4M%!Uq5e21XE(^yxy>zt
zMwf@E`@K{2tI`yd=XZc+-ydI@r1+V-+N-CU73W&gr?Xr*@OkzqBKgP(U(E67eN@vQ
z&Zf}1vEJ#7j^i>dT_DmpuBi$;h6=PIg&(-eRj(dh>8tE%9m$)%mo<1f*nF#{<2)7twt!!#1$owy{p6@0}P;n2G97BOoB|qvbM97@4V-S
zO?Q9`EW11ARySPQZ`}1KDE24OaIxNE9So+Na=E0_*Mo{Au{P#VcvlbDrq#luCmBry
zVfG`ZF~7G
zOLSks9~T8$+1I=!^QKp%7iN=Rk7=~J+x|{y_{I&fL6%mOG-Fn
zJy8qHc`(xhem`o;;%&|R@<-Z}hztm%CTYoP)RhJkvjCc!0;}Up9nsAod;j3Yrt}*F
z17o$h1$DWNWP@*AqIc^XM;D4GMj{8ZhhREXCT0ZZcST9OUn{zG=9E2o55OI(tRgjM
zL*A6l2-EbxG^ALHoyG{~?nu#Ikcg}9($CBF15sP8s&!vSp&U`%$Y;IPf>Nnf3o2L3
zYhCGPZ_|q_!u>y6;_!yn`CUyfN=e^3Sv{M>o>J0Cvki8`Y2kCwCxG`<<8K14q)C1>
zxaDcR>Cm}fDMy!LcP5rcbkO3mVR4B&g{@8pFF?t6cLi3DccjGl%#B{F3aMPF6OA@r
z*A4`$mbx+32exoVhf$;6^?T%b!=e>tCn6|5Ug0QgHqd!p*C^X2i5_o$q|hedl-7Wh
i{~PM7T>n?a3BTii5Kq7XResNuR_(r;y{qp40Q>_g^X4c3
literal 0
HcmV?d00001