feat(pay): 新增小程序支付页面及相关隐私协议处理

- 新增支付页面组件,实现JSAPI支付流程和多状态页面展示
- 配置支付页面导航条样式和标题
- app.config.ts中添加支付页面路径
- app.tsx中新增微信隐私协议授权弹窗,拦截敏感API授权流程
- api/system/file中导出ensurePrivacyAuthorized用于隐私授权预检
- 登录页和注册页新增useDidShow钩子调用ensurePrivacyAuthorized预检隐私协议
- 登录和注册接口请求迁移至统一request封装,修正响应解构
- 支付流程中新增获取openid和自动登录逻辑,支持未注册用户跳转登录
- 支付成功后通知后端确认并自动跳转到已购产品页面
- 优化支付状态判断逻辑,正确识别支付和订单状态
- 添加错误处理和用户提示,提升支付体验安全性与稳定性
This commit is contained in:
2026-07-16 00:26:42 +08:00
parent 549e8258b6
commit ca78e73f51
7 changed files with 492 additions and 61 deletions

View File

@@ -1,11 +1,13 @@
import { useEffect, useMemo, useState } from 'react'
import Taro from '@tarojs/taro'
import Taro, { useDidShow } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import { Button, Checkbox } from '@nutui/nutui-react-taro'
import { TenantId } from '@/config/app'
import { getUserInfo, getWxOpenId } from '@/api/layout'
import { saveStorageByLoginUser } from '@/utils/server'
import { saveStorageByLoginUser, SERVER_API_URL } from '@/utils/server'
import { isUserDisabled } from '@/utils/auth'
import request from '@/utils/request'
import { ensurePrivacyAuthorized } from '@/api/system/file'
import {
getStoredInviteParams,
parseInviteParams,
@@ -25,17 +27,6 @@ interface GetPhoneNumberEvent {
detail: GetPhoneNumberDetail
}
interface LoginResponse {
data: {
code?: number
message?: string
data?: {
access_token: string
user: any
}
}
}
async function getWeappLoginCode(): Promise<string | undefined> {
try {
const res = await new Promise<{ code?: string }>((resolve, reject) => {
@@ -110,9 +101,13 @@ const Register = () => {
const router = Taro.getCurrentInstance().router
useEffect(() => {
// register 页面不是 tabBar 页面,无需调用 hideTabBar
}, [])
/** 页面显示时预检隐私协议,避免 getPhoneNumber 因未授权隐私协议而失败 */
useDidShow(() => {
if (!isWeapp) return
ensurePrivacyAuthorized().catch((e) => {
console.warn('注册页隐私协议预检失败:', e)
})
})
const redirectUrl = useMemo(() => {
const raw = (router?.params as any)?.redirect as string | undefined
@@ -195,10 +190,9 @@ const Register = () => {
// 获取小程序登录 code用于后续绑定 openid
const wxLoginCode = await getWeappLoginCode()
const res = (await Taro.request({
url: 'https://shop-api.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
const res: any = await request.post(
`${SERVER_API_URL}/wx-login/loginByMpWxPhone`,
{
code: phoneCode,
encryptedData,
iv,
@@ -207,19 +201,16 @@ const Register = () => {
sceneType: 'save_referee',
tenantId: TenantId,
},
header: {
'content-type': 'application/json',
TenantId,
},
})) as unknown as LoginResponse
{ showError: false }
)
if ((res as any)?.data?.code === 1) {
Taro.showToast({ title: res.data.message || '登录失败', icon: 'none' })
if (res?.code === 1) {
Taro.showToast({ title: res.message || '登录失败', icon: 'none' })
return
}
const token = res?.data?.data?.access_token
const user = res?.data?.data?.user
const token = res?.data?.access_token
const user = res?.data?.user
if (!token || !user?.userId) {
Taro.showToast({ title: '登录失败,请重试', icon: 'none' })
return