Ver código fonte

完成依赖解耦

yuanmingze 8 meses atrás
pai
commit
22bf1a10f4

+ 11 - 1
src/App.vue

@@ -1,5 +1,15 @@
 <script setup lang="ts">
-import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
+import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
+
+import { setTokenProvider } from '@/services/request/tokenProvider'
+
+import { useUserStore } from '@/stores/modules/user'
+
+setTokenProvider(() => {
+  const userStore = useUserStore()
+  return userStore.access_token
+})
+
 onLaunch(() => {
   console.log('App Launch')
 })

+ 22 - 85
src/services/request/index.ts

@@ -1,18 +1,17 @@
 import {
   BASE_API,
   MODE,
-  TIMEOUT,
-  SUCCESS_CODE_LIST,
   NOT_OAUTH_BASIC_TOKEN,
   OAUTH_BASIC_TOKEN,
+  SUCCESS_CODE_LIST,
+  TIMEOUT,
 } from './config'
-import { useUserStore } from '@/stores/modules/user'
+import { getToken } from './tokenProvider'
 
 /* -------------------------------------------------------------------------- */
-/*                                类型定义                                    */
+/*                                   类型                                     */
 /* -------------------------------------------------------------------------- */
 
-/** 后端统一返回结构 */
 export interface ApiResponse<T = any> {
   code: number
   msg: string
@@ -35,38 +34,25 @@ export interface RequestConfig extends BaseOptions {
 /*                               核心 request                                  */
 /* -------------------------------------------------------------------------- */
 
-/**
- * 默认请求:永远返回 ApiResponse<T>
- * - 白名单:不校验 code,但仍返回 ApiResponse<T>
- * - 非白名单:校验 code,不通过 reject(ApiResponse<T>)
- */
 export function request<T = any>(config: RequestConfig): Promise<ApiResponse<T>> {
-  const userStore = useUserStore()
-
   return new Promise((resolve, reject) => {
     uni.request({
       url: resolveUrl(config.url),
-      method: config.method || 'GET',
+      method: config.method ?? 'GET',
       data: config.data,
       timeout: config.timeout ?? TIMEOUT,
-      header: buildHeaders(config.url, userStore, config.header),
+      header: buildHeaders(config.url, config.header),
 
       success(res) {
         const result = res.data as ApiResponse<T>
 
-        // 白名单接口:不校验 code,直接放行(仍返回 ApiResponse<T>)
+        // 白名单接口:不校验 code
         if (isWhiteList(config.url)) {
           return resolve(result)
         }
 
         // 业务失败
         if (!SUCCESS_CODE_LIST.includes(result.code)) {
-          if (!config.silent) {
-            uni.showToast({
-              title: result.msg || '业务错误',
-              icon: 'none',
-            })
-          }
           return reject(result)
         }
 
@@ -74,10 +60,6 @@ export function request<T = any>(config: RequestConfig): Promise<ApiResponse<T>>
       },
 
       fail(err) {
-        uni.showToast({
-          title: '网络异常',
-          icon: 'none',
-        })
         reject(err)
       },
     })
@@ -85,27 +67,22 @@ export function request<T = any>(config: RequestConfig): Promise<ApiResponse<T>>
 }
 
 /**
- * 特殊接口:后端不包 ApiResponse,直接返回 T
- * - 不做 code 校验
- * - 适用于少量 legacy 接口
+ * 后端不包 ApiResponse 的接口
  */
 export function requestRaw<T = any>(config: RequestConfig): Promise<T> {
-  const userStore = useUserStore()
   return new Promise((resolve, reject) => {
     uni.request({
       url: resolveUrl(config.url),
-      method: config.method || 'GET',
+      method: config.method ?? 'GET',
       data: config.data,
       timeout: config.timeout ?? TIMEOUT,
-      header: buildHeaders(config.url, userStore, config.header),
+      header: buildHeaders(config.url, config.header),
+
       success(res) {
         resolve(res.data as T)
       },
+
       fail(err) {
-        uni.showToast({
-          title: '网络异常',
-          icon: 'none',
-        })
         reject(err)
       },
     })
@@ -113,78 +90,43 @@ export function requestRaw<T = any>(config: RequestConfig): Promise<T> {
 }
 
 /* -------------------------------------------------------------------------- */
-/*                       默认 http(get / post 语法糖)                         */
+/*                               http 语法糖                                  */
 /* -------------------------------------------------------------------------- */
 
 const http = {
-  /**
-   * 默认 get:返回 ApiResponse<T>
-   */
   get<T = any>(url: string, params?: any, options?: BaseOptions) {
-    return request<T>({
-      url,
-      method: 'GET',
-      data: params,
-      ...options,
-    })
+    return request<T>({ url, method: 'GET', data: params, ...options })
   },
 
-  /**
-   * 默认 post:返回 ApiResponse<T>
-   */
   post<T = any>(url: string, data?: any, options?: BaseOptions) {
-    return request<T>({
-      url,
-      method: 'POST',
-      data,
-      ...options,
-    })
+    return request<T>({ url, method: 'POST', data, ...options })
   },
 
-  /**
-   * 特殊接口 get:返回 T
-   */
   getRaw<T = any>(url: string, params?: any, options?: BaseOptions) {
-    return requestRaw<T>({
-      url,
-      method: 'GET',
-      data: params,
-      ...options,
-    })
+    return requestRaw<T>({ url, method: 'GET', data: params, ...options })
   },
 
-  /**
-   * 特殊接口 post:返回 T
-   */
   postRaw<T = any>(url: string, data?: any, options?: BaseOptions) {
-    return requestRaw<T>({
-      url,
-      method: 'POST',
-      data,
-      ...options,
-    })
+    return requestRaw<T>({ url, method: 'POST', data, ...options })
   },
 }
 
 export default http
 
 /* -------------------------------------------------------------------------- */
-/*                               工具函数                                     */
+/*                                 工具函数                                   */
 /* -------------------------------------------------------------------------- */
 
 function resolveUrl(url: string) {
-  // 小程序环境:必须使用绝对路径
   // #ifdef MP
   return BASE_API + url
   // #endif
 
-  // H5 环境:开发时允许走代理(相对路径)
   // #ifdef H5
   if (MODE === 'development') return url
   return BASE_API + url
   // #endif
 
-  // 其他平台兜底
   return BASE_API + url
 }
 
@@ -192,25 +134,20 @@ function isWhiteList(url: string) {
   return ['/auth/oauth/token'].some((item) => url.includes(item))
 }
 
-function buildHeaders(
-  url: string,
-  userStore: ReturnType<typeof useUserStore>,
-  extraHeader?: UniApp.RequestOptions['header']
-) {
+function buildHeaders(url: string, extraHeader?: UniApp.RequestOptions['header']) {
   const headers: Record<string, any> = {
     ...(extraHeader || {}),
   }
 
-  const access_token = userStore.access_token
+  const accessToken = getToken()
 
   if (url.includes('auth/mobile/token/sms')) {
     headers.Authorization = NOT_OAUTH_BASIC_TOKEN
-    // headers['TENANT-ID'] = '1'
   } else if (url.includes('auth/oauth/token')) {
     headers.Authorization = OAUTH_BASIC_TOKEN
     headers['TENANT-ID'] = '1'
-  } else if (access_token) {
-    headers.Authorization = `Bearer ${access_token}`
+  } else if (accessToken) {
+    headers.Authorization = `Bearer ${accessToken}`
   }
 
   return headers

+ 9 - 0
src/services/request/tokenProvider.ts

@@ -0,0 +1,9 @@
+let tokenProvider: (() => string | undefined) | null = null
+
+export function setTokenProvider(fn: () => string | undefined) {
+  tokenProvider = fn
+}
+
+export function getToken() {
+  return tokenProvider?.()
+}

+ 2 - 1
src/stores/modules/user.ts

@@ -45,7 +45,7 @@ export const useUserStore = defineStore('user', {
       }
       // 登录成功
       this.access_token = res.access_token
-      // 拉取用户信息(这里可以继续 try/catch)
+      // 拉取用户信息
       await this.getUserInfoByCode()
       return {
         success: true,
@@ -57,6 +57,7 @@ export const useUserStore = defineStore('user', {
         const userInfoResult = await getUserInfoByCodeApi(res.code)
         if (userInfoResult.code === 0 && userInfoResult.data) {
           this.userInfoList = userInfoResult.data.userInfo
+          // 检查黑名单状态
           if (this.userInfoList[0]) {
             const { phone, idCardNumber } = this.userInfoList[0]
             this.fetchUserBlacklistStatus({