feat(pda): connect online picking workflow
This commit is contained in:
+76
-5
@@ -1,26 +1,97 @@
|
||||
import { reactive } from 'vue'
|
||||
import { resetPickingSession } from '@/stores/picking.js'
|
||||
import { PLATFORM_API_ROOT } from '@/config/runtime.js'
|
||||
|
||||
export const session = reactive({ currentUser: null, token: '', tenantId: '', apiBase: '' })
|
||||
const SESSION_KEY = 'pda-auth-session'
|
||||
|
||||
export const session = reactive({ currentUser: null, token: '', refreshToken: '', tenantId: '', apiBase: PLATFORM_API_ROOT })
|
||||
|
||||
function decodeBase64Url(value) {
|
||||
const normalized = value.replace(/-/g, '+').replace(/_/g, '/')
|
||||
const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=')
|
||||
if (typeof atob === 'function') return decodeURIComponent(Array.from(atob(padded), (char) => `%${char.charCodeAt(0).toString(16).padStart(2, '0')}`).join(''))
|
||||
throw new Error('当前运行环境无法解析登录令牌')
|
||||
}
|
||||
|
||||
export function decodeAccessToken(token) {
|
||||
const payload = String(token || '').split('.')[1]
|
||||
if (!payload) throw new Error('登录响应中的 accessToken 格式无效')
|
||||
try {
|
||||
return JSON.parse(decodeBase64Url(payload))
|
||||
} catch (error) {
|
||||
if (error.message === '当前运行环境无法解析登录令牌') throw error
|
||||
throw new Error('登录响应中的 accessToken 无法解析')
|
||||
}
|
||||
}
|
||||
|
||||
function storageAvailable() {
|
||||
return typeof uni !== 'undefined' && typeof uni.setStorageSync === 'function' && typeof uni.getStorageSync === 'function'
|
||||
}
|
||||
|
||||
function persistSession() {
|
||||
if (!storageAvailable()) return
|
||||
uni.setStorageSync(SESSION_KEY, {
|
||||
currentUser: session.currentUser,
|
||||
token: session.token,
|
||||
refreshToken: session.refreshToken,
|
||||
tenantId: session.tenantId,
|
||||
apiBase: session.apiBase
|
||||
})
|
||||
}
|
||||
|
||||
export function signIn(account, warehouse, options = {}) {
|
||||
session.currentUser = { id: account.id, name: account.name, role: account.role, warehouse }
|
||||
session.currentUser = { id: String(account.id), name: account.name, role: account.role, roles: account.roles || [], warehouse, warehouseId: account.warehouseId || null }
|
||||
session.token = options.token || account.token || ''
|
||||
session.refreshToken = options.refreshToken || account.refreshToken || ''
|
||||
session.tenantId = options.tenantId || account.tenantId || ''
|
||||
session.apiBase = options.apiBase || account.apiBase || ''
|
||||
session.apiBase = options.apiBase || account.apiBase || PLATFORM_API_ROOT
|
||||
persistSession()
|
||||
return session.currentUser
|
||||
}
|
||||
|
||||
export function signInWithTokens(tokens) {
|
||||
if (!tokens?.accessToken) throw new Error('登录响应缺少 accessToken')
|
||||
const claims = decodeAccessToken(tokens.accessToken)
|
||||
if (claims.app_code !== 'PLATFORM') throw new Error('当前账号不属于平台作业端')
|
||||
if (claims.exp && claims.exp * 1000 <= Date.now()) throw new Error('登录状态已过期')
|
||||
return signIn({
|
||||
id: claims.user_id ?? '',
|
||||
name: claims.username || '仓库作业员',
|
||||
role: Array.isArray(claims.roles) ? claims.roles.join('、') : '',
|
||||
roles: claims.roles || []
|
||||
}, '', {
|
||||
token: tokens.accessToken,
|
||||
refreshToken: tokens.refreshToken || '',
|
||||
tenantId: claims.tenant_id == null ? '' : String(claims.tenant_id)
|
||||
})
|
||||
}
|
||||
|
||||
export function restoreSession() {
|
||||
if (!storageAvailable()) return false
|
||||
const saved = uni.getStorageSync(SESSION_KEY)
|
||||
if (!saved?.token || !saved?.currentUser) return false
|
||||
try {
|
||||
const claims = decodeAccessToken(saved.token)
|
||||
if (claims.exp && claims.exp * 1000 <= Date.now()) return false
|
||||
Object.assign(session, saved, { apiBase: saved.apiBase || PLATFORM_API_ROOT })
|
||||
return true
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function signOut() {
|
||||
session.currentUser = null
|
||||
session.token = ''
|
||||
session.refreshToken = ''
|
||||
session.tenantId = ''
|
||||
session.apiBase = ''
|
||||
session.apiBase = PLATFORM_API_ROOT
|
||||
if (typeof uni !== 'undefined' && typeof uni.removeStorageSync === 'function') uni.removeStorageSync(SESSION_KEY)
|
||||
resetPickingSession()
|
||||
}
|
||||
|
||||
export function requireSession() {
|
||||
if (session.currentUser) return true
|
||||
if (session.currentUser || restoreSession()) return true
|
||||
uni.reLaunch({ url: '/pages/login/login' })
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user