fix(api): 替换所有接口请求的域名为 guilixu-api.websoft.top

- 将获取 STS Token 的接口地址由 paopao-api 改为 guilixu-api
- 更新图片上传接口地址为新的 guilixu-api 域名
- 修改用户推广页面中邀请码链接和二维码接口的域名
- 更改注册页微信登录接口请求的域名为 guilixu-api
This commit is contained in:
2026-06-16 17:15:59 +08:00
commit f3886664f7
617 changed files with 77059 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
import React, { useState } from 'react'
import { View, Text } from '@tarojs/components'
import { Button, Loading } from '@nutui/nutui-react-taro'
import { Failure, Scan, Success } from '@nutui/icons-react-taro'
import Taro from '@tarojs/taro'
import { confirmWechatQRLogin, parseQRContent } from '@/api/passport/qr-login'
export interface QRLoginScannerProps {
onSuccess?: (result: any) => void
onError?: (error: string) => void
className?: string
buttonText?: string
showStatus?: boolean
}
type ScanState = 'idle' | 'scanning' | 'confirming' | 'success' | 'error'
const QRLoginScanner: React.FC<QRLoginScannerProps> = ({
onSuccess,
onError,
className = '',
buttonText = '开始扫码登录',
showStatus = true,
}) => {
const [state, setState] = useState<ScanState>('idle')
const [error, setError] = useState('')
const [result, setResult] = useState<any>(null)
const reset = () => {
setState('idle')
setError('')
setResult(null)
}
const startScan = async () => {
try {
setState('scanning')
setError('')
const scanRes = await Taro.scanCode({ onlyFromCamera: false, scanType: ['qrCode'] })
const rawContent = scanRes.result || ''
const token = parseQRContent(rawContent)
const userId = Number(Taro.getStorageSync('UserId'))
if (!token) {
throw new Error('未识别到有效的登录二维码')
}
if (!userId) {
throw new Error('当前用户未登录')
}
setState('confirming')
const confirmRes = await confirmWechatQRLogin(token, userId)
setResult(confirmRes)
setState('success')
onSuccess?.(confirmRes)
} catch (err: any) {
const message = err?.errMsg?.includes('cancel')
? '已取消扫码'
: err?.message || '扫码登录失败'
setError(message)
setState('error')
onError?.(message)
}
}
const renderStatus = () => {
switch (state) {
case 'scanning':
return (
<View className="flex items-center justify-center text-blue-500">
<Loading className="mr-2" />
<Text>...</Text>
</View>
)
case 'confirming':
return (
<View className="flex items-center justify-center text-orange-500">
<Loading className="mr-2" />
<Text>...</Text>
</View>
)
case 'success':
return (
<View className="flex items-center justify-center text-green-500">
<Success className="mr-2" />
<Text></Text>
</View>
)
case 'error':
return (
<View className="flex items-center justify-center text-red-500">
<Failure className="mr-2" />
<Text>{error || '扫码登录失败'}</Text>
</View>
)
default:
return null
}
}
const loading = state === 'scanning' || state === 'confirming'
return (
<View className={`qr-login-scanner ${className}`}>
<Button
type="primary"
size="large"
loading={loading}
onClick={state === 'success' ? reset : startScan}
className="w-full"
>
{!loading && <Scan className="mr-2" />}
{state === 'success' ? '重新扫码' : state === 'error' ? '重试' : buttonText}
</Button>
{showStatus && <View className="mt-4 text-center">{renderStatus()}</View>}
{state === 'success' && result && (
<View className="mt-4 rounded-lg bg-green-50 p-4">
<Text className="text-sm text-green-700"></Text>
</View>
)}
{state === 'idle' && (
<View className="mt-4 text-center">
<Text className="text-xs text-gray-500"></Text>
</View>
)}
</View>
)
}
export default QRLoginScanner