feat:请求封装的接入

This commit is contained in:
YunaiV
2025-12-12 19:14:26 +08:00
parent 7f9eaf82a2
commit 6a4c78f0a9
5 changed files with 74 additions and 34 deletions

21
env/.env vendored
View File

@@ -1,4 +1,4 @@
VITE_APP_TITLE = 'unibest'
VITE_APP_TITLE = '芋道管理系统'
VITE_APP_PORT = 9000
VITE_UNI_APPID = '__UNI__D1E5001'
@@ -10,7 +10,8 @@ VITE_WX_APPID = 'wxa2abb91f64032a2b'
VITE_APP_PUBLIC_BASE=/
# 后台请求地址
VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
VITE_SERVER_BASEURL = 'http://localhost:48080/admin-api'
VITE_UPLOAD_BASEURL = 'http://localhost:48080/upload'
# 备注如果后台带统一前缀则也要加到后面eg: https://ukw0y1.laf.run/api
# 注意,如果是微信小程序,还有一套请求地址的配置,根据 develop、trial、release 分别设置上传地址,见 `src/utils/index.ts`。
@@ -18,13 +19,25 @@ VITE_SERVER_BASEURL = 'https://ukw0y1.laf.run'
# h5是否需要配置代理
VITE_APP_PROXY_ENABLE = false
# 下面的不用修改,只要不跟你后台的统一前缀冲突就行。如果修改了,记得修改 `nginx` 里面的配置
VITE_APP_PROXY_PREFIX = '/fg-api'
VITE_APP_PROXY_PREFIX = '/admin-api'
# 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务
VITE_UPLOAD_TYPE=server
# 第二个请求地址 (目前alova中可以使用)
VITE_SERVER_BASEURL_SECONDARY = 'https://ukw0y1.laf.run'
# 认证模式,'single' | 'double' ==> 单token | 双token
VITE_AUTH_MODE = 'single'
VITE_AUTH_MODE = 'double'
# 原生插件资源复制开关,控制是否启用 copy-native-resources 插件
VITE_COPY_NATIVE_RES_ENABLE = false
# 租户开关
VITE_APP_TENANT_ENABLE=true
# 验证码的开关
VITE_APP_CAPTCHA_ENABLE=true
# 默认账户密码
VITE_APP_DEFAULT_LOGIN_TENANT_ID = 1
VITE_APP_DEFAULT_LOGIN_USERNAME = admin
VITE_APP_DEFAULT_LOGIN_PASSWORD = admin123

View File

@@ -2,7 +2,7 @@ import type { IDoubleTokenRes } from '@/api/types/login'
import type { CustomRequestOptions, IResponse } from '@/http/types'
import { nextTick } from 'vue'
import { useTokenStore } from '@/store/token'
import { isDoubleTokenMode } from '@/utils'
import { getLastPage, isDoubleTokenMode } from '@/utils'
import { toLoginPage } from '@/utils/toLoginPage'
import { ResultEnum } from './tools/enum'
@@ -55,11 +55,12 @@ export function http<T>(options: CustomRequestOptions) {
refreshing = false
nextTick(() => {
// 关闭其他弹窗
uni.hideToast()
uni.showToast({
title: 'token 刷新成功',
icon: 'none',
})
// 注释 by 芋艿:刷新 token 成功,是后台静默操作,没必要提示用户
// uni.hideToast()
// uni.showToast({
// title: 'token 刷新成功',
// icon: 'none',
// })
})
// 将任务队列的所有任务重新请求
taskQueue.forEach(task => task())
@@ -80,7 +81,14 @@ export function http<T>(options: CustomRequestOptions) {
await tokenStore.logout()
// 跳转到登录页
setTimeout(() => {
toLoginPage()
// 优化 by 芋艿:跳转登录页时,携带上次浏览的页面地址,登录成功后可以跳回去
const lastPage = getLastPage()
let queryString = ''
if (lastPage) {
const fullPath = lastPage.$page?.fullPath || `/${lastPage.route}`
queryString = `?redirect=${encodeURIComponent(fullPath)}`
}
toLoginPage({ queryString })
}, 2000)
}
finally {
@@ -96,10 +104,14 @@ export function http<T>(options: CustomRequestOptions) {
if (res.statusCode >= 200 && res.statusCode < 300) {
// 处理业务逻辑错误
if (code !== ResultEnum.Success0 && code !== ResultEnum.Success200) {
uni.showToast({
// add by 芋艿:后端返回的 msg 提示
!options.hideErrorToast
&& uni.showToast({
icon: 'none',
title: responseData.msg || responseData.message || '请求错误',
})
// add by 芋艿reject 替代原本的 resolve避免调用的地方以为请求成功
return reject(responseData)
}
return resolve(responseData.data)
}
@@ -191,9 +203,3 @@ http.get = httpGet
http.post = httpPost
http.put = httpPut
http.delete = httpDelete
// 支持与 alovaJS 类似的API调用
http.Get = httpGet
http.Post = httpPost
http.Put = httpPut
http.Delete = httpDelete

View File

@@ -1,20 +1,22 @@
import type { CustomRequestOptions } from '@/http/types'
import { useTokenStore } from '@/store'
import { useTokenStore, useUserStore } from '@/store'
import { getEnvBaseUrl } from '@/utils'
import { stringifyQuery } from './tools/queryString'
// 请求基准地址
const baseUrl = getEnvBaseUrl()
const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
const whiteList: string[] = [
'/login',
'/refresh-token',
'/system/tenant/get-id-by-name',
] // 白名单列表,不需要传递 token 字段
// 拦截器配置
const httpInterceptor = {
// 拦截前触发
invoke(options: CustomRequestOptions) {
// 如果您使用了alova则请把下面的代码放开注释
// alova 执行流程alova beforeRequest --> 本拦截器 --> alova responded
// return options
// 非 alova 请求,正常执行
// 接口请求支持通过 query 参数配置 queryString
if (options.query) {
const queryStr = stringifyQuery(options.query)
@@ -51,10 +53,23 @@ const httpInterceptor = {
// 3. 添加 token 请求头标识
const tokenStore = useTokenStore()
const token = tokenStore.validToken
if (token) {
let isToken = (options!.header || {}).isToken === false
whiteList.some((v) => {
if (options.url && options.url.indexOf(v) > -1) {
return (isToken = false)
}
})
if (!isToken && token) {
options.header.Authorization = `Bearer ${token}`
}
// 4. 添加租户标识
if (tenantEnable && tenantEnable === 'true') {
const tenantId = useUserStore().tenantId
if (tenantId) {
options.header['tenant-id'] = tenantId
}
}
return options
},
}

View File

@@ -20,17 +20,18 @@ export type IResponse<T = any> = {
[key: string]: any // 允许额外属性
}
// 分页请求参数
export interface PageParams {
page: number
/** 分页参数 */
export interface PageParam {
pageNo: number
pageSize: number
[key: string]: any
[key: string]: any // 允许额外属性
}
// 分页响应数据
/** 分页结果 */
export interface PageResult<T> {
list: T[]
total: number
page: number
pageSize: number
}
/** 加载状态枚举 - 从 wot-design-uni 重新导出 */
export type { LoadMoreState } from 'wot-design-uni/components/wd-loadmore/types'

View File

@@ -23,7 +23,12 @@ const LOGIN_PAGE = '/pages/login/index'
* 如果要立即跳转,不做延时,可以使用 `toLoginPage.flush()` 方法
*/
export const toLoginPage = debounce((options: ToLoginPageOptions = {}) => {
const { mode = 'navigateTo', queryString = '' } = options
let { mode = 'navigateTo', queryString = '' } = options
// add by 芋艿:如果有查询参数,强制使用 reLaunch 模式。
// 原因:携带 redirect 参数,登录成功后可以跳回去。避免使用 navigateTo 导致页面数据不会刷新
if (queryString) {
mode = 'reLaunch'
}
const url = `${LOGIN_PAGE}${queryString}`