支持普通链接二维码进入绑定页
This commit is contained in:
@@ -26,6 +26,50 @@ const SESSION_STATUS_COMPLETED = 2
|
||||
const SESSION_STATUS_EXPIRED = 3
|
||||
const SESSION_STATUS_FAILED = 4
|
||||
const SESSION_STATUS_CANCELLED = 5
|
||||
const BIND_PAGE_URL = '/pages/bind/index'
|
||||
|
||||
function safeDecodeURIComponent(value: string): string {
|
||||
try {
|
||||
return decodeURIComponent(value)
|
||||
} catch (error) {
|
||||
console.log('[bind] decode uri component failed:', error)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
function decodeQueryComponent(value: string): string {
|
||||
return safeDecodeURIComponent(value.replace(/\+/g, ' '))
|
||||
}
|
||||
|
||||
function decodeLaunchQrValue(value: string): string {
|
||||
let decoded = String(value || '').trim()
|
||||
for (let index = 0; index < 2; index += 1) {
|
||||
const nextDecoded = safeDecodeURIComponent(decoded).trim()
|
||||
if (nextDecoded === decoded) break
|
||||
decoded = nextDecoded
|
||||
}
|
||||
return decoded
|
||||
}
|
||||
|
||||
function getRouteParam(params: Record<string, unknown> | undefined, key: string): string {
|
||||
const value = params?.[key]
|
||||
if (Array.isArray(value)) return String(value[0] || '').trim()
|
||||
return String(value || '').trim()
|
||||
}
|
||||
|
||||
function buildPageUrl(pagePath: string, params: Record<string, unknown> | undefined): string {
|
||||
const query = Object.entries(params || {})
|
||||
.filter(([key, value]) => key && value !== undefined && value !== null && value !== '')
|
||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
||||
.join('&')
|
||||
|
||||
return query ? `${pagePath}?${query}` : pagePath
|
||||
}
|
||||
|
||||
function getLaunchQrPayload(params: Record<string, unknown> | undefined): string {
|
||||
const qParam = getRouteParam(params, 'q')
|
||||
return qParam ? decodeLaunchQrValue(qParam) : ''
|
||||
}
|
||||
|
||||
function normalizeExpiresAt(expiresAt: string): string {
|
||||
let normalized = String(expiresAt || '').trim()
|
||||
@@ -71,7 +115,7 @@ function parseBindingPayload(rawValue: string): { deviceId: string; serialNumber
|
||||
const pairMap = queryPart.split('&').reduce<Record<string, string>>((result, item) => {
|
||||
const [key, ...restValue] = item.split('=')
|
||||
if (!key) return result
|
||||
result[decodeURIComponent(key)] = decodeURIComponent(restValue.join('=') || '')
|
||||
result[decodeQueryComponent(key)] = decodeQueryComponent(restValue.join('=') || '')
|
||||
return result
|
||||
}, {})
|
||||
const deviceId = pairMap.device_id || pairMap.deviceId || ''
|
||||
@@ -128,6 +172,7 @@ export default function Bind() {
|
||||
const [remainingBindSeconds, setRemainingBindSeconds] = useState(0)
|
||||
const pollingRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null)
|
||||
const appliedLaunchQrRef = useRef('')
|
||||
|
||||
useDidShow(() => {
|
||||
void loadPageData()
|
||||
@@ -200,6 +245,27 @@ export default function Bind() {
|
||||
setRemainingBindSeconds(0)
|
||||
}
|
||||
|
||||
const applyLaunchQrPayload = () => {
|
||||
if (isAssignMode) return false
|
||||
|
||||
const launchPayload = getLaunchQrPayload(router.params)
|
||||
if (!launchPayload || appliedLaunchQrRef.current === launchPayload) return false
|
||||
|
||||
appliedLaunchQrRef.current = launchPayload
|
||||
const parsed = parseBindingPayload(launchPayload)
|
||||
if (!parsed.deviceId && !parsed.serialNumber) return false
|
||||
|
||||
resetBindSessionState()
|
||||
if (parsed.deviceId) setDeviceId(parsed.deviceId)
|
||||
if (parsed.serialNumber) setSerialNumber(parsed.serialNumber)
|
||||
setBindHint(
|
||||
parsed.serialNumber
|
||||
? '已读取设备二维码信息,请选择儿童后发送绑卡指令'
|
||||
: '已读取设备号,请补充设备序列号'
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
const resetExpiredBindSession = (showToast = true) => {
|
||||
stopPolling()
|
||||
stopCountdown()
|
||||
@@ -300,6 +366,7 @@ export default function Bind() {
|
||||
|
||||
const loadPageData = async () => {
|
||||
if (!getToken()) {
|
||||
Taro.setStorageSync('postLoginRedirect', buildPageUrl(BIND_PAGE_URL, router.params))
|
||||
Taro.reLaunch({ url: '/pages/login/index' })
|
||||
return
|
||||
}
|
||||
@@ -317,6 +384,7 @@ export default function Bind() {
|
||||
setDeviceId(activeBinding.device_id)
|
||||
} else {
|
||||
setPendingDeviceId(null)
|
||||
applyLaunchQrPayload()
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('[bind] load failed:', error)
|
||||
|
||||
Reference in New Issue
Block a user