第三次版本迭代更新
This commit is contained in:
@@ -186,6 +186,8 @@ export const mockApi = {
|
||||
async orderDetail(orderId: string): Promise<UserOrderDetail> {
|
||||
await wait()
|
||||
const order = orders.find((item) => item.id === orderId) || orders[0]
|
||||
const totalCount = Number(order.commodityAmount) || 1
|
||||
const writeOffCount = order.writeOffTime ? totalCount : 0
|
||||
return {
|
||||
orderId: order.id,
|
||||
orderAmt: order.orderAmt,
|
||||
@@ -228,7 +230,12 @@ export const mockApi = {
|
||||
commodityPackageConfig: [
|
||||
{
|
||||
packageName: order.commodityName,
|
||||
packageContent: `${order.commodityName} x ${order.commodityAmount}`
|
||||
packageContent: `${order.commodityName} x ${order.commodityAmount}`,
|
||||
name: order.commodityName,
|
||||
count: totalCount,
|
||||
unit: '份',
|
||||
packageStatus: writeOffCount >= totalCount ? 1 : 0,
|
||||
writeOffCount
|
||||
}
|
||||
],
|
||||
reservationEnabled: order.reservationDate ? 1 : 0,
|
||||
|
||||
@@ -29,7 +29,10 @@ export const fetchOrderDetail = async (orderId: string): Promise<UserOrderDetail
|
||||
|
||||
export const writeOffOrder = async (payload: WriteOffPayload): Promise<WriteOffResult> => {
|
||||
if (env.useMock) return mockApi.writeOff(payload)
|
||||
await http.post<boolean>(joinUrl(env.staffBase, 'order/writeOff'), payload)
|
||||
const success = await http.post<boolean>(joinUrl(env.staffBase, 'order/writeOff'), payload)
|
||||
if (!success) {
|
||||
throw new Error('商品核销失败')
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
orderId: payload.orderId,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import axios, { AxiosError } from 'axios'
|
||||
import { showToast } from 'vant'
|
||||
import { AUTH_EXPIRED_EVENT, AUTH_STORAGE_KEYS, clearAuthStorage } from '@/utils/authStorage'
|
||||
import { env } from '@/utils/env'
|
||||
|
||||
const http = axios.create({
|
||||
@@ -7,9 +8,49 @@ const http = axios.create({
|
||||
timeout: 15000
|
||||
})
|
||||
|
||||
let isRedirectingToLogin = false
|
||||
|
||||
const authExpiredTexts = ['请求令牌已过期', '令牌已过期', 'token已过期', 'Token已过期', 'invalid_token']
|
||||
|
||||
const getHeader = (headers: unknown, key: string) => {
|
||||
if (!headers || typeof headers !== 'object') return ''
|
||||
const maybeHeaders = headers as Record<string, unknown> & { get?: (name: string) => unknown }
|
||||
return String(maybeHeaders[key] || maybeHeaders[key.toLowerCase()] || maybeHeaders.get?.(key) || '')
|
||||
}
|
||||
|
||||
const hasBearerAuthorization = (headers: unknown) => getHeader(headers, 'Authorization').startsWith('Bearer ')
|
||||
|
||||
const isAuthExpired = (status?: number, code?: unknown, message = '', hasBearerToken = false) => {
|
||||
const normalizedCode = String(code || '')
|
||||
return (
|
||||
authExpiredTexts.some((text) => message.includes(text)) ||
|
||||
((status === 401 || normalizedCode === '401') && hasBearerToken)
|
||||
)
|
||||
}
|
||||
|
||||
const redirectToLogin = (message: string) => {
|
||||
clearAuthStorage()
|
||||
window.dispatchEvent(new Event(AUTH_EXPIRED_EVENT))
|
||||
|
||||
if (isRedirectingToLogin || window.location.pathname.endsWith('/login')) return
|
||||
isRedirectingToLogin = true
|
||||
showToast(message || '登录已失效,请重新登录')
|
||||
|
||||
const fallbackRedirect = `${window.location.pathname}${window.location.search}${window.location.hash}`
|
||||
import('@/router').then(({ default: router }) => {
|
||||
const currentPath = router.currentRoute.value.fullPath
|
||||
router.replace({
|
||||
name: 'login',
|
||||
query: {
|
||||
redirect: currentPath && currentPath !== '/login' ? currentPath : fallbackRedirect
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
http.interceptors.request.use((config) => {
|
||||
const token = localStorage.getItem('hotel_h5_access_token')
|
||||
if (token) {
|
||||
const token = localStorage.getItem(AUTH_STORAGE_KEYS.token)
|
||||
if (token && !getHeader(config.headers, 'Authorization')) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
@@ -22,12 +63,27 @@ http.interceptors.response.use(
|
||||
if (payload.code === 0 || payload.code === 200) {
|
||||
return payload.data === undefined ? payload : payload.data
|
||||
}
|
||||
return Promise.reject(new Error(payload.msg || '请求失败'))
|
||||
const message = payload.msg || payload.message || '请求失败'
|
||||
if (isAuthExpired(response.status, payload.code, message, hasBearerAuthorization(response.config.headers))) {
|
||||
redirectToLogin(message)
|
||||
}
|
||||
return Promise.reject(new Error(message))
|
||||
}
|
||||
return payload
|
||||
},
|
||||
(error: AxiosError<{ msg?: string }>) => {
|
||||
const message = error.response?.data?.msg || error.message || '网络异常'
|
||||
(error: AxiosError<{ code?: number | string; msg?: string; message?: string }>) => {
|
||||
const message = error.response?.data?.msg || error.response?.data?.message || error.message || '网络异常'
|
||||
if (
|
||||
isAuthExpired(
|
||||
error.response?.status,
|
||||
error.response?.data?.code,
|
||||
message,
|
||||
hasBearerAuthorization(error.config?.headers)
|
||||
)
|
||||
) {
|
||||
redirectToLogin(message)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
showToast(message)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user