@fairys/taro-tools-react 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1,10 @@
1
1
  # 框架 ui 组件库
2
+
3
+ - [X] 全局弹框
4
+ - [X] 页面布局
5
+ - [X] 请求封装
6
+ - [X] 路由封装
7
+ - [X] 权限管理
8
+ - [X] 用户信息
9
+
10
+ 文档地址:[fairys-taro-react](https://autumn-fairy-tales.github.io/fairys-taro-react/)
@@ -6,6 +6,8 @@ export interface AuthDataInstanceState<T = any> {
6
6
  token?: string;
7
7
  /**权限列表*/
8
8
  permissions?: string[];
9
+ /**菜单权限列表*/
10
+ menusPermissions?: string[];
9
11
  /**数据默认值不使用*/
10
12
  __defaultValue?: string;
11
13
  }
@@ -41,6 +43,22 @@ export declare class AuthDataInstance<T = any> {
41
43
  * @returns 权限列表
42
44
  */
43
45
  get permissions(): string[];
46
+ /**
47
+ * 设置菜单权限列表
48
+ * @param menusPermissions 菜单权限列表
49
+ */
50
+ set menusPermissions(menusPermissions: string[]);
51
+ /**
52
+ * 获取菜单权限列表
53
+ * @returns 菜单权限列表
54
+ */
55
+ get menusPermissions(): string[];
56
+ /**
57
+ * 判断是否有指定菜单权限
58
+ * @param menuPermission 菜单权限
59
+ * @returns 是否有指定菜单权限
60
+ */
61
+ hasMenuPermission(menuPermission: string): boolean;
44
62
  /**
45
63
  * 判断是否有指定权限
46
64
  * @param permission 权限
@@ -5,7 +5,8 @@ class AuthDataInstance {
5
5
  store = proxy({
6
6
  userInfo: void 0,
7
7
  token: void 0,
8
- permissions: void 0
8
+ permissions: void 0,
9
+ menusPermissions: void 0
9
10
  });
10
11
  set userInfo(userInfo) {
11
12
  this.store.userInfo = userInfo;
@@ -51,7 +52,28 @@ class AuthDataInstance {
51
52
  }
52
53
  return this.store.permissions || [];
53
54
  }
55
+ set menusPermissions(menusPermissions) {
56
+ this.store.menusPermissions = menusPermissions;
57
+ if (menusPermissions) taro.setStorageSync('menusPermissions', JSON.stringify(menusPermissions));
58
+ else taro.removeStorageSync('menusPermissions');
59
+ }
60
+ get menusPermissions() {
61
+ if (!this.store.menusPermissions) {
62
+ const menusPermissions = taro.getStorageSync('menusPermissions');
63
+ if (menusPermissions) try {
64
+ this.store.menusPermissions = JSON.parse(menusPermissions);
65
+ } catch (error) {
66
+ console.error("\u89E3\u6790\u83DC\u5355\u6743\u9650\u5217\u8868\u5931\u8D25", error);
67
+ }
68
+ }
69
+ return this.store.menusPermissions || [];
70
+ }
71
+ hasMenuPermission(menuPermission) {
72
+ if (!globalSettingDataInstance.store.isEnableAuth) return true;
73
+ return this.menusPermissions.includes(menuPermission);
74
+ }
54
75
  hasPermission(permission) {
76
+ if (!globalSettingDataInstance.store.isEnableAuth) return true;
55
77
  return this.permissions.includes(permission);
56
78
  }
57
79
  }
@@ -25,15 +25,26 @@ export interface GlobalSettingDataInstanceState {
25
25
  * @default pages/login/index
26
26
  */
27
27
  loginPageRoute?: string;
28
+ /**跳转忽略权限校验的路由*/
29
+ ignoreAuthRoutes?: string[];
30
+ /**路由跳转默认使用authDataInstance中的hasMenuPermission 判断是否有菜单权限*/
31
+ useAuthHasMenuPermission?: boolean;
32
+ /**是否开启权限校验*/
33
+ isEnableAuth?: boolean;
28
34
  /**数据默认值不使用*/
29
35
  __defaultValue?: string;
30
36
  }
31
37
  export declare class GlobalSettingDataInstance extends ProxyInstanceObjectBase<GlobalSettingDataInstanceState> {
38
+ defaultStore: GlobalSettingDataInstanceState;
32
39
  store: GlobalSettingDataInstanceState;
33
40
  /**
34
41
  * 扩展全局设置数据状态
35
42
  */
36
43
  extendStore: (state: Partial<GlobalSettingDataInstanceState>) => void;
44
+ /**
45
+ * 判断是否跳转忽略权限校验的路由
46
+ */
47
+ isIgnoreAuthRoutes: (route: string) => boolean;
37
48
  }
38
49
  /**
39
50
  * 全局设置数据实例
@@ -1,15 +1,30 @@
1
1
  import { proxy, useSnapshot } from "valtio";
2
2
  import { ProxyInstanceObjectBase } from "../utils/valtio/instance.js";
3
3
  class GlobalSettingDataInstance extends ProxyInstanceObjectBase {
4
- store = proxy({
4
+ defaultStore = {
5
5
  requestSuccessCode: 200,
6
6
  tokenFieldName: 'token',
7
7
  headerTokenName: 'token',
8
8
  tokenExpiredCode: 401,
9
- loginPageRoute: 'pages/login/index'
9
+ loginPageRoute: 'pages/login/index',
10
+ ignoreAuthRoutes: [],
11
+ useAuthHasMenuPermission: true,
12
+ isEnableAuth: true
13
+ };
14
+ store = proxy({
15
+ ...this.defaultStore
10
16
  });
11
17
  extendStore = (state)=>{
12
- this._setValues(state);
18
+ this._setValues({
19
+ ...this.defaultStore,
20
+ ...state
21
+ });
22
+ };
23
+ isIgnoreAuthRoutes = (route)=>{
24
+ const _route = route.replace(/^\//, '');
25
+ const _loginPageRoute = this.store.loginPageRoute.replace(/^\//, '');
26
+ if (_route === _loginPageRoute) return true;
27
+ return (this.store.ignoreAuthRoutes || []).includes(_route) || (this.store.ignoreAuthRoutes || []).includes(route);
13
28
  };
14
29
  }
15
30
  const globalSettingDataInstance = new GlobalSettingDataInstance();
@@ -1,6 +1,6 @@
1
1
  import Taro from '@tarojs/taro';
2
2
  declare class NavigateInstance {
3
- /**判断是否已登录(方法需要在项目入口文件中进行挂载)*/
3
+ /**判断是否已登录(方法需要在项目入口文件中进行挂载,如果不挂载,默认使用 authDataInstance.hasMenuPermission 判断是否有菜单权限)*/
4
4
  isAuth: (url: string) => Promise<boolean> | boolean;
5
5
  private _isAuth;
6
6
  /**
@@ -1,12 +1,19 @@
1
1
  import taro from "@tarojs/taro";
2
+ import { globalSettingDataInstance } from "../context/global.setting.data.instance.js";
3
+ import { authDataInstance } from "../context/auth.data.instance.js";
2
4
  class NavigateInstance {
3
5
  isAuth;
4
6
  _isAuth = async (url)=>{
5
7
  let isAuthTo = true;
6
- if (url && 'function' == typeof this.isAuth) isAuthTo = await this.isAuth(url);
8
+ const isIgnoreAuthRoutes = globalSettingDataInstance.isIgnoreAuthRoutes(url);
9
+ const useAuthHasMenuPermission = globalSettingDataInstance.store.useAuthHasMenuPermission;
10
+ const isEnableAuth = globalSettingDataInstance.store.isEnableAuth;
11
+ let isAuthFunction = this.isAuth;
12
+ if (useAuthHasMenuPermission && 'function' != typeof isAuthFunction && isEnableAuth) isAuthFunction = authDataInstance.hasMenuPermission;
13
+ if (url && 'function' == typeof isAuthFunction && !isIgnoreAuthRoutes && isEnableAuth) isAuthTo = await isAuthFunction(url);
7
14
  if (false === isAuthTo) {
8
15
  taro.showToast({
9
- title: "\u65E0\u6743\u8BBF\u95EE",
16
+ title: `${url} \u{65E0}\u{6743}\u{8BBF}\u{95EE}`,
10
17
  icon: 'none'
11
18
  });
12
19
  return false;
@@ -1,5 +1,5 @@
1
1
  import Taro from '@tarojs/taro';
2
- export interface RequestInstanceOptions extends Taro.request.Option<any, any> {
2
+ export interface TaroRequestOption {
3
3
  /**模块名称*/
4
4
  module?: string;
5
5
  /**是否忽略token*/
@@ -7,6 +7,16 @@ export interface RequestInstanceOptions extends Taro.request.Option<any, any> {
7
7
  /**是否提示错误信息*/
8
8
  isShowErrorMessage?: boolean;
9
9
  }
10
+ export interface RequestInstanceOptions extends Taro.request.Option<any, any>, TaroRequestOption {
11
+ }
12
+ export interface DownloadFileOptions extends Taro.downloadFile.Option, TaroRequestOption {
13
+ /**下载进度回调*/
14
+ onProgress?: Taro.DownloadTask.OnProgressUpdateCallback;
15
+ }
16
+ export interface UploadFileOptions extends Taro.uploadFile.Option, TaroRequestOption {
17
+ /**上传进度回调*/
18
+ onProgress?: Taro.UploadTask.OnProgressUpdateCallback;
19
+ }
10
20
  export interface RequestInstanceCreateOptions {
11
21
  /**
12
22
  * 公共请求配置
@@ -58,6 +68,71 @@ export declare class RequestInstance {
58
68
  };
59
69
  /**格式化地址*/
60
70
  formatUrl: (url: string, module?: string) => string;
71
+ formatRequestOptions: (options: RequestInstanceOptions | DownloadFileOptions | UploadFileOptions) => {
72
+ url: string;
73
+ data?: any;
74
+ timeout?: number;
75
+ method?: keyof Taro.request.Method;
76
+ dataType?: keyof Taro.request.DataType | string;
77
+ responseType?: keyof Taro.request.ResponseType;
78
+ enableHttp2?: boolean;
79
+ enableQuic?: boolean;
80
+ enableCache?: boolean;
81
+ enableHttpDNS?: boolean;
82
+ httpDNSServiceId?: string;
83
+ enableChunked?: boolean;
84
+ forceCellularNetwork?: boolean;
85
+ enableCookie?: boolean;
86
+ referrerStrategy?: keyof Taro.request.ReferrerStrategy;
87
+ success?: (result: Taro.request.SuccessCallbackResult<any>) => void;
88
+ fail?: (res: TaroGeneral.CallbackResult) => void;
89
+ complete?: (res: Partial<Taro.request.SuccessCallbackResult> & TaroGeneral.CallbackResult) => void;
90
+ jsonp?: boolean | string;
91
+ jsonpCache?: RequestCache;
92
+ mode?: keyof Taro.request.CorsMode;
93
+ credentials?: keyof Taro.request.Credentials;
94
+ cache?: keyof Taro.request.Cache;
95
+ retryTimes?: number;
96
+ backup?: string | string[];
97
+ signal?: AbortSignal;
98
+ dataCheck?(): boolean;
99
+ useStore?: boolean;
100
+ storeCheckKey?: string;
101
+ storeSign?: string;
102
+ storeCheck?(): boolean;
103
+ header: {
104
+ [x: string]: any;
105
+ };
106
+ } | {
107
+ url: string;
108
+ /**下载进度回调*/
109
+ onProgress?: Taro.DownloadTask.OnProgressUpdateCallback;
110
+ filePath?: string;
111
+ timeout?: number;
112
+ withCredentials?: boolean;
113
+ complete?: (res: TaroGeneral.CallbackResult) => void;
114
+ fail?: (res: TaroGeneral.CallbackResult) => void;
115
+ success?: (result: Taro.downloadFile.FileSuccessCallbackResult) => void;
116
+ header: {
117
+ [x: string]: any;
118
+ };
119
+ } | {
120
+ url: string;
121
+ /**上传进度回调*/
122
+ onProgress?: Taro.UploadTask.OnProgressUpdateCallback;
123
+ filePath: string;
124
+ name: string;
125
+ formData?: TaroGeneral.IAnyObject;
126
+ timeout?: number;
127
+ fileName?: string;
128
+ withCredentials?: boolean;
129
+ complete?: (res: TaroGeneral.CallbackResult) => void;
130
+ fail?: (res: TaroGeneral.CallbackResult) => void;
131
+ success?: (result: Taro.uploadFile.SuccessCallbackResult) => void;
132
+ header: {
133
+ [x: string]: any;
134
+ };
135
+ };
61
136
  /**发送请求,返回 Taro.RequestTask */
62
137
  requestBase: (options: RequestInstanceOptions) => Taro.RequestTask<any>;
63
138
  /**发送请求,返回 Promise */
@@ -90,6 +165,14 @@ export declare class RequestInstance {
90
165
  data?: any;
91
166
  message?: string;
92
167
  }>;
168
+ /**下载文件(返回 Taro.DownloadTask.DownloadTaskPromise ,可显示下载进度)*/
169
+ downloadFileTask: (options: DownloadFileOptions) => Taro.DownloadTask.DownloadTaskPromise | undefined;
170
+ /**下载文件*/
171
+ downloadFile: (options: DownloadFileOptions) => Promise<Taro.downloadFile.FileSuccessCallbackResult>;
172
+ /**上传文件(返回 Taro.UploadTask.UploadTaskPromise ,可显示上传进度)*/
173
+ uploadFileTask: (options: UploadFileOptions) => Taro.UploadTask.UploadTaskPromise;
174
+ /**上传文件*/
175
+ uploadFile: (options: UploadFileOptions) => Promise<Taro.uploadFile.SuccessCallbackResult>;
93
176
  }
94
177
  /** 请求*/
95
178
  export declare const request: RequestInstance;
@@ -19,15 +19,13 @@ const requestResponseHandle = (result, options)=>{
19
19
  try {
20
20
  const statusCode = result.statusCode;
21
21
  const code = result?.data?.code;
22
- if (result?.data) {
23
- if (401 === statusCode || 401 === code || code === globalSettingDataInstance.store.tokenExpiredCode) {
24
- msg = "\u8BF7\u91CD\u65B0\u767B\u5F55";
25
- globalDataInstance.toLoginPage();
26
- } else if (![
27
- globalSettingDataInstance.store.requestSuccessCode,
28
- 200
29
- ].includes(code)) msg = result?.data?.message || "\u63A5\u53E3\u5F02\u5E38";
30
- } else msg = codeMessage[result?.statusCode];
22
+ if (401 === statusCode || 401 === code || code === globalSettingDataInstance.store.tokenExpiredCode) {
23
+ msg = "\u8BF7\u91CD\u65B0\u767B\u5F55";
24
+ globalDataInstance.toLoginPage();
25
+ } else msg = [
26
+ globalSettingDataInstance.store.requestSuccessCode,
27
+ 200
28
+ ].includes(code) ? codeMessage[result?.statusCode] : result?.data?.message || codeMessage[code || result?.statusCode] || "\u63A5\u53E3\u5F02\u5E38";
31
29
  } catch (error) {
32
30
  msg = codeMessage[result?.statusCode];
33
31
  console.log(error);
@@ -103,8 +101,8 @@ class RequestInstance {
103
101
  }
104
102
  return `${host}/${newUrl}`;
105
103
  };
106
- requestBase = (options)=>{
107
- const { data, header = {}, module, isIgnoreToken, isShowErrorMessage, ...restOptions } = options;
104
+ formatRequestOptions = (options)=>{
105
+ const { header = {}, module, isIgnoreToken, isShowErrorMessage, ...restOptions } = options;
108
106
  const token = taro.getStorageSync(globalSettingDataInstance.store.tokenFieldName || 'token');
109
107
  const newHeader = {
110
108
  ...header
@@ -121,6 +119,17 @@ class RequestInstance {
121
119
  globalDataInstance.toLoginPage();
122
120
  return;
123
121
  }
122
+ return {
123
+ header: newHeader,
124
+ ...restOptions,
125
+ url: this.formatUrl(options.url, module)
126
+ };
127
+ };
128
+ requestBase = (options)=>{
129
+ const { isShowErrorMessage } = options;
130
+ const formattedOptions = this.formatRequestOptions(options);
131
+ if (!formattedOptions) return;
132
+ const { header: newHeader, ...restOptions } = formattedOptions;
124
133
  return taro.request({
125
134
  ...this.commonOptions,
126
135
  ...restOptions,
@@ -128,7 +137,6 @@ class RequestInstance {
128
137
  ...newHeader,
129
138
  ...options?.header || {}
130
139
  },
131
- url: this.formatUrl(options.url, module),
132
140
  success: (result)=>{
133
141
  requestResponseHandle(result, options);
134
142
  options?.success?.(result);
@@ -203,6 +211,95 @@ class RequestInstance {
203
211
  throw error;
204
212
  }
205
213
  };
214
+ downloadFileTask = (options)=>{
215
+ const { isShowErrorMessage } = options;
216
+ const formattedOptions = this.formatRequestOptions(options);
217
+ if (!formattedOptions) return;
218
+ const { header: newHeader, onProgress, ...restOptions } = formattedOptions;
219
+ const downloadTask = taro.downloadFile({
220
+ ...this.commonOptions,
221
+ ...restOptions,
222
+ header: {
223
+ ...newHeader,
224
+ ...options?.header || {}
225
+ },
226
+ success: (result)=>{
227
+ if (200 === result.statusCode) options?.success?.(result);
228
+ else {
229
+ requestResponseHandle(result, options);
230
+ options?.fail?.(result);
231
+ }
232
+ },
233
+ fail: (result)=>{
234
+ if (false !== isShowErrorMessage) globalDataInstance.showMessage({
235
+ content: result.errMsg || "\u8BF7\u6C42\u53D1\u751F\u9519\u8BEF",
236
+ type: 'error'
237
+ });
238
+ options?.fail?.(result);
239
+ }
240
+ });
241
+ if ('function' == typeof onProgress && downloadTask) downloadTask.onProgressUpdate(onProgress);
242
+ return downloadTask;
243
+ };
244
+ downloadFile = (options)=>{
245
+ try {
246
+ return new Promise((resolve, reject)=>{
247
+ this.downloadFileTask({
248
+ ...options,
249
+ success: (result)=>{
250
+ options?.success?.(result);
251
+ resolve(result);
252
+ },
253
+ fail: (result)=>{
254
+ options?.fail?.(result);
255
+ reject(result);
256
+ }
257
+ });
258
+ });
259
+ } catch (error) {
260
+ throw error;
261
+ }
262
+ };
263
+ uploadFileTask = (options)=>{
264
+ const { isShowErrorMessage } = options;
265
+ const formattedOptions = this.formatRequestOptions(options);
266
+ if (!formattedOptions) return;
267
+ const { header: newHeader, onProgress, ...restOptions } = formattedOptions;
268
+ const uploadTask = taro.uploadFile({
269
+ ...this.commonOptions,
270
+ ...restOptions,
271
+ header: {
272
+ ...newHeader,
273
+ ...options?.header || {}
274
+ },
275
+ success: (result)=>{
276
+ requestResponseHandle(result, options);
277
+ options?.success?.(result);
278
+ },
279
+ fail: (result)=>{
280
+ if (false !== isShowErrorMessage) globalDataInstance.showMessage({
281
+ content: result.errMsg || "\u8BF7\u6C42\u53D1\u751F\u9519\u8BEF",
282
+ type: 'error'
283
+ });
284
+ options?.fail?.(result);
285
+ }
286
+ });
287
+ if ('function' == typeof onProgress && uploadTask) uploadTask.onProgressUpdate(onProgress);
288
+ return uploadTask;
289
+ };
290
+ uploadFile = (options)=>new Promise((resolve, reject)=>{
291
+ this.uploadFileTask({
292
+ ...options,
293
+ success: (result)=>{
294
+ options?.success?.(result);
295
+ resolve(result);
296
+ },
297
+ fail: (result)=>{
298
+ options?.fail?.(result);
299
+ reject(result);
300
+ }
301
+ });
302
+ });
206
303
  }
207
304
  const request_request = new RequestInstance();
208
305
  const utils_request = request_request;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "SunLxy <1011771396@qq.com>",
4
4
  "description": "框架组件库",
5
5
  "homepage": "https://github.com/autumn-fairy-tales/fairys-taro-react",
6
- "version": "0.0.3",
6
+ "version": "0.0.5",
7
7
  "main": "lib/index.js",
8
8
  "types": "esm/index.d.ts",
9
9
  "module": "esm/index.js",
@@ -10,6 +10,8 @@ export interface AuthDataInstanceState<T = any> {
10
10
  token?: string;
11
11
  /**权限列表*/
12
12
  permissions?: string[];
13
+ /**菜单权限列表*/
14
+ menusPermissions?: string[];
13
15
  /**数据默认值不使用*/
14
16
  __defaultValue?: string;
15
17
  }
@@ -19,6 +21,7 @@ export class AuthDataInstance<T = any> {
19
21
  userInfo: undefined,
20
22
  token: undefined,
21
23
  permissions: undefined,
24
+ menusPermissions: undefined,
22
25
  });
23
26
 
24
27
  /**
@@ -107,6 +110,46 @@ export class AuthDataInstance<T = any> {
107
110
  }
108
111
  return this.store.permissions || [];
109
112
  }
113
+ /**
114
+ * 设置菜单权限列表
115
+ * @param menusPermissions 菜单权限列表
116
+ */
117
+ set menusPermissions(menusPermissions: string[]) {
118
+ this.store.menusPermissions = menusPermissions;
119
+ if (menusPermissions) {
120
+ Taro.setStorageSync('menusPermissions', JSON.stringify(menusPermissions));
121
+ } else {
122
+ Taro.removeStorageSync('menusPermissions');
123
+ }
124
+ }
125
+ /**
126
+ * 获取菜单权限列表
127
+ * @returns 菜单权限列表
128
+ */
129
+ get menusPermissions(): string[] {
130
+ if (!this.store.menusPermissions) {
131
+ const menusPermissions = Taro.getStorageSync('menusPermissions');
132
+ if (menusPermissions) {
133
+ try {
134
+ this.store.menusPermissions = JSON.parse(menusPermissions);
135
+ } catch (error) {
136
+ console.error('解析菜单权限列表失败', error);
137
+ }
138
+ }
139
+ }
140
+ return this.store.menusPermissions || [];
141
+ }
142
+ /**
143
+ * 判断是否有指定菜单权限
144
+ * @param menuPermission 菜单权限
145
+ * @returns 是否有指定菜单权限
146
+ */
147
+ hasMenuPermission(menuPermission: string): boolean {
148
+ if (!globalSettingDataInstance.store.isEnableAuth) {
149
+ return true;
150
+ }
151
+ return this.menusPermissions.includes(menuPermission);
152
+ }
110
153
 
111
154
  /**
112
155
  * 判断是否有指定权限
@@ -114,6 +157,9 @@ export class AuthDataInstance<T = any> {
114
157
  * @returns 是否有指定权限
115
158
  */
116
159
  hasPermission(permission: string): boolean {
160
+ if (!globalSettingDataInstance.store.isEnableAuth) {
161
+ return true;
162
+ }
117
163
  return this.permissions.includes(permission);
118
164
  }
119
165
  }
@@ -27,23 +27,49 @@ export interface GlobalSettingDataInstanceState {
27
27
  * @default pages/login/index
28
28
  */
29
29
  loginPageRoute?: string;
30
+ /**跳转忽略权限校验的路由*/
31
+ ignoreAuthRoutes?: string[];
32
+ /**路由跳转默认使用authDataInstance中的hasMenuPermission 判断是否有菜单权限*/
33
+ useAuthHasMenuPermission?: boolean;
34
+ /**是否开启权限校验*/
35
+ isEnableAuth?: boolean;
30
36
  /**数据默认值不使用*/
31
37
  __defaultValue?: string;
32
38
  }
33
39
 
34
40
  export class GlobalSettingDataInstance extends ProxyInstanceObjectBase<GlobalSettingDataInstanceState> {
35
- store = proxy<GlobalSettingDataInstanceState>({
41
+ defaultStore: GlobalSettingDataInstanceState = {
36
42
  requestSuccessCode: 200,
37
43
  tokenFieldName: 'token',
38
44
  headerTokenName: 'token',
39
45
  tokenExpiredCode: 401,
40
46
  loginPageRoute: 'pages/login/index',
41
- });
47
+ ignoreAuthRoutes: [],
48
+ useAuthHasMenuPermission: true,
49
+ isEnableAuth: true,
50
+ };
51
+ store = proxy<GlobalSettingDataInstanceState>({ ...this.defaultStore });
42
52
  /**
43
53
  * 扩展全局设置数据状态
44
54
  */
45
55
  extendStore = (state: Partial<GlobalSettingDataInstanceState>) => {
46
- this._setValues(state);
56
+ this._setValues({
57
+ ...this.defaultStore,
58
+ ...state,
59
+ });
60
+ };
61
+ /**
62
+ * 判断是否跳转忽略权限校验的路由
63
+ */
64
+ isIgnoreAuthRoutes = (route: string): boolean => {
65
+ /**处理路由前缀*/
66
+ const _route = route.replace(/^\//, '');
67
+ /**处理登录页面路由前缀*/
68
+ const _loginPageRoute = this.store.loginPageRoute.replace(/^\//, '');
69
+ if (_route === _loginPageRoute) {
70
+ return true;
71
+ }
72
+ return (this.store.ignoreAuthRoutes || []).includes(_route) || (this.store.ignoreAuthRoutes || []).includes(route);
47
73
  };
48
74
  }
49
75
  /**
@@ -1,17 +1,28 @@
1
1
  import Taro from '@tarojs/taro';
2
+ import { globalSettingDataInstance } from 'context/global.setting.data.instance';
3
+ import { authDataInstance } from 'context/auth.data.instance';
2
4
 
3
5
  class NavigateInstance {
4
- /**判断是否已登录(方法需要在项目入口文件中进行挂载)*/
6
+ /**判断是否已登录(方法需要在项目入口文件中进行挂载,如果不挂载,默认使用 authDataInstance.hasMenuPermission 判断是否有菜单权限)*/
5
7
  public isAuth: (url: string) => Promise<boolean> | boolean;
6
-
7
8
  private _isAuth = async (url?: string) => {
8
9
  let isAuthTo = true;
9
- if (url && typeof this.isAuth === 'function') {
10
- isAuthTo = await this.isAuth(url);
10
+ // 判断是否跳转忽略权限校验的路由
11
+ const isIgnoreAuthRoutes = globalSettingDataInstance.isIgnoreAuthRoutes(url);
12
+ // 判断是否使用 authDataInstance中的hasMenuPermission 判断是否有菜单权限
13
+ const useAuthHasMenuPermission = globalSettingDataInstance.store.useAuthHasMenuPermission;
14
+ // 判断是否开启权限校验
15
+ const isEnableAuth = globalSettingDataInstance.store.isEnableAuth;
16
+ let isAuthFunction = this.isAuth;
17
+ if (useAuthHasMenuPermission && typeof isAuthFunction !== 'function' && isEnableAuth) {
18
+ isAuthFunction = authDataInstance.hasMenuPermission;
19
+ }
20
+ if (url && typeof isAuthFunction === 'function' && !isIgnoreAuthRoutes && isEnableAuth) {
21
+ isAuthTo = await isAuthFunction(url);
11
22
  }
12
23
  if (isAuthTo === false) {
13
24
  // 无权访问页面
14
- Taro.showToast({ title: '无权访问', icon: 'none' });
25
+ Taro.showToast({ title: `${url} 无权访问`, icon: 'none' });
15
26
  return false;
16
27
  }
17
28
  return true;
@@ -16,7 +16,7 @@ const codeMessage = {
16
16
  504: 'nginx超时',
17
17
  } as const;
18
18
 
19
- export interface RequestInstanceOptions extends Taro.request.Option<any, any> {
19
+ export interface TaroRequestOption {
20
20
  /**模块名称*/
21
21
  module?: string;
22
22
  /**是否忽略token*/
@@ -25,22 +25,37 @@ export interface RequestInstanceOptions extends Taro.request.Option<any, any> {
25
25
  isShowErrorMessage?: boolean;
26
26
  }
27
27
 
28
+ export interface RequestInstanceOptions extends Taro.request.Option<any, any>, TaroRequestOption {}
29
+ export interface DownloadFileOptions extends Taro.downloadFile.Option, TaroRequestOption {
30
+ /**下载进度回调*/
31
+ onProgress?: Taro.DownloadTask.OnProgressUpdateCallback;
32
+ }
33
+ export interface UploadFileOptions extends Taro.uploadFile.Option, TaroRequestOption {
34
+ /**上传进度回调*/
35
+ onProgress?: Taro.UploadTask.OnProgressUpdateCallback;
36
+ }
28
37
  /**处理提示信息*/
29
- const requestResponseHandle = (result: Taro.request.SuccessCallbackResult<any>, options?: RequestInstanceOptions) => {
38
+ const requestResponseHandle = (
39
+ result:
40
+ | Taro.request.SuccessCallbackResult<any>
41
+ | Taro.downloadFile.FileSuccessCallbackResult
42
+ | Taro.uploadFile.SuccessCallbackResult,
43
+ options?: RequestInstanceOptions,
44
+ ) => {
30
45
  let msg = '';
31
46
  try {
32
47
  const statusCode = result.statusCode;
48
+ // @ts-ignore
33
49
  const code = result?.data?.code;
34
- if (result?.data) {
35
- if (statusCode === 401 || code === 401 || code === globalSettingDataInstance.store.tokenExpiredCode) {
36
- // 权限问题 ,重新登录
37
- msg = '请重新登录';
38
- /**重新跳转登录页面*/
39
- globalDataInstance.toLoginPage();
40
- } else if (![globalSettingDataInstance.store.requestSuccessCode, 200].includes(code)) {
41
- // 提示内容
42
- msg = result?.data?.message || '接口异常';
43
- }
50
+ if (statusCode === 401 || code === 401 || code === globalSettingDataInstance.store.tokenExpiredCode) {
51
+ // 权限问题 ,重新登录
52
+ msg = '请重新登录';
53
+ /**重新跳转登录页面*/
54
+ globalDataInstance.toLoginPage();
55
+ } else if (![globalSettingDataInstance.store.requestSuccessCode, 200].includes(code)) {
56
+ // 提示内容
57
+ // @ts-ignore
58
+ msg = result?.data?.message || codeMessage[code || result?.statusCode] || '接口异常';
44
59
  } else {
45
60
  msg = codeMessage[result?.statusCode];
46
61
  }
@@ -62,7 +77,6 @@ export interface RequestInstanceCreateOptions {
62
77
  * @default {}
63
78
  */
64
79
  commonOptions?: Omit<Taro.request.Option<any, any>, 'url'>;
65
-
66
80
  /**
67
81
  * 请求IP地址
68
82
  * @default ''
@@ -153,11 +167,9 @@ export class RequestInstance {
153
167
  if (!host) {
154
168
  host = this.proxy?.default?.[process.env.NODE_ENV === 'production' ? 'pro' : 'dev'] || '';
155
169
  }
156
-
157
170
  if (!host) {
158
171
  host = this.getHttpPath(url, module);
159
172
  }
160
-
161
173
  return {
162
174
  host,
163
175
  url: _url,
@@ -178,9 +190,8 @@ export class RequestInstance {
178
190
  return `${host}/${newUrl}`;
179
191
  };
180
192
 
181
- /**发送请求,返回 Taro.RequestTask */
182
- requestBase = (options: RequestInstanceOptions) => {
183
- const { data, header = {}, module, isIgnoreToken, isShowErrorMessage, ...restOptions } = options;
193
+ formatRequestOptions = (options: RequestInstanceOptions | DownloadFileOptions | UploadFileOptions) => {
194
+ const { header = {}, module, isIgnoreToken, isShowErrorMessage, ...restOptions } = options;
184
195
  const token = Taro.getStorageSync(globalSettingDataInstance.store.tokenFieldName || 'token');
185
196
  const newHeader = { ...header };
186
197
  if (token) {
@@ -199,6 +210,22 @@ export class RequestInstance {
199
210
  return undefined;
200
211
  }
201
212
  }
213
+
214
+ return {
215
+ header: newHeader,
216
+ ...restOptions,
217
+ url: this.formatUrl(options.url, module),
218
+ };
219
+ };
220
+
221
+ /**发送请求,返回 Taro.RequestTask */
222
+ requestBase = (options: RequestInstanceOptions) => {
223
+ const { isShowErrorMessage } = options;
224
+ const formattedOptions = this.formatRequestOptions(options);
225
+ if (!formattedOptions) {
226
+ return undefined;
227
+ }
228
+ const { header: newHeader, ...restOptions } = formattedOptions;
202
229
  return Taro.request({
203
230
  ...this.commonOptions,
204
231
  ...restOptions,
@@ -206,7 +233,6 @@ export class RequestInstance {
206
233
  ...newHeader,
207
234
  ...(options?.header || {}),
208
235
  },
209
- url: this.formatUrl(options.url, module),
210
236
  success: (result) => {
211
237
  /**处理提示
212
238
  * 使用 global 状态管理
@@ -298,6 +324,119 @@ export class RequestInstance {
298
324
  throw error;
299
325
  }
300
326
  };
327
+
328
+ /**下载文件(返回 Taro.DownloadTask.DownloadTaskPromise ,可显示下载进度)*/
329
+ downloadFileTask = (options: DownloadFileOptions): Taro.DownloadTask.DownloadTaskPromise | undefined => {
330
+ const { isShowErrorMessage } = options;
331
+ const formattedOptions = this.formatRequestOptions(options);
332
+ if (!formattedOptions) {
333
+ return undefined;
334
+ }
335
+ const { header: newHeader, onProgress, ...restOptions } = formattedOptions as DownloadFileOptions;
336
+ const downloadTask = Taro.downloadFile({
337
+ ...this.commonOptions,
338
+ ...restOptions,
339
+ header: {
340
+ ...newHeader,
341
+ ...(options?.header || {}),
342
+ },
343
+ success: (result) => {
344
+ if (result.statusCode === 200) {
345
+ options?.success?.(result);
346
+ } else {
347
+ requestResponseHandle(result, options as any);
348
+ options?.fail?.(result);
349
+ }
350
+ },
351
+ fail: (result) => {
352
+ if (isShowErrorMessage !== false) {
353
+ globalDataInstance.showMessage({
354
+ content: result.errMsg || '请求发生错误',
355
+ type: 'error',
356
+ });
357
+ }
358
+ options?.fail?.(result);
359
+ },
360
+ });
361
+ /**监听下载进度*/
362
+ if (typeof onProgress === 'function' && downloadTask) {
363
+ downloadTask.onProgressUpdate(onProgress);
364
+ }
365
+ return downloadTask;
366
+ };
367
+
368
+ /**下载文件*/
369
+ downloadFile = (options: DownloadFileOptions): Promise<Taro.downloadFile.FileSuccessCallbackResult> => {
370
+ try {
371
+ return new Promise((resolve, reject) => {
372
+ this.downloadFileTask({
373
+ ...options,
374
+ success: (result) => {
375
+ options?.success?.(result);
376
+ resolve(result);
377
+ },
378
+ fail: (result) => {
379
+ options?.fail?.(result);
380
+ reject(result);
381
+ },
382
+ });
383
+ });
384
+ } catch (error) {
385
+ throw error;
386
+ }
387
+ };
388
+
389
+ /**上传文件(返回 Taro.UploadTask.UploadTaskPromise ,可显示上传进度)*/
390
+ uploadFileTask = (options: UploadFileOptions) => {
391
+ const { isShowErrorMessage } = options;
392
+ const formattedOptions = this.formatRequestOptions(options);
393
+ if (!formattedOptions) {
394
+ return undefined;
395
+ }
396
+ const { header: newHeader, onProgress, ...restOptions } = formattedOptions as UploadFileOptions;
397
+ const uploadTask = Taro.uploadFile({
398
+ ...this.commonOptions,
399
+ ...restOptions,
400
+ header: {
401
+ ...newHeader,
402
+ ...(options?.header || {}),
403
+ },
404
+ success: (result) => {
405
+ requestResponseHandle(result, options);
406
+ options?.success?.(result);
407
+ },
408
+ fail: (result) => {
409
+ if (isShowErrorMessage !== false) {
410
+ globalDataInstance.showMessage({
411
+ content: result.errMsg || '请求发生错误',
412
+ type: 'error',
413
+ });
414
+ }
415
+ options?.fail?.(result);
416
+ },
417
+ });
418
+ /**监听上传进度*/
419
+ if (typeof onProgress === 'function' && uploadTask) {
420
+ uploadTask.onProgressUpdate(onProgress);
421
+ }
422
+ return uploadTask;
423
+ };
424
+ /**上传文件*/
425
+ uploadFile = (options: UploadFileOptions): Promise<Taro.uploadFile.SuccessCallbackResult> => {
426
+ return new Promise((resolve, reject) => {
427
+ this.uploadFileTask({
428
+ ...options,
429
+ success: (result) => {
430
+ options?.success?.(result);
431
+ resolve(result);
432
+ },
433
+ fail: (result) => {
434
+ options?.fail?.(result);
435
+ reject(result);
436
+ },
437
+ });
438
+ });
439
+ };
301
440
  }
302
441
 
303
442
  /** 请求*/