Commit ec23e9b6b9bc1fba604b329f0089974923fcc940
1 parent
56001e24
优化文件
Showing
13 changed files
with
195 additions
and
55 deletions
client/layout/index.tsx
client/util/createError.ts
1 | -import { AxiosError } from 'axios'; | |
1 | +import { AxiosError, AxiosResponse } from 'axios'; | |
2 | 2 | import { HttpClientResponse } from 'urllib'; |
3 | 3 | |
4 | -interface ErrorCode { | |
4 | +export interface ErrorCode { | |
5 | 5 | [key: number]: string; |
6 | 6 | } |
7 | 7 | |
8 | -interface ErrorMsg extends Error { | |
8 | +export interface ErrorMsg extends Error { | |
9 | 9 | errorCode?: number | string; |
10 | 10 | errorMsg?: string; |
11 | 11 | response?: any; | ... | ... |
client/util/fp/getWinxinEnv.ts
1 | -import utils from 'client/utils'; | |
1 | +import utils from 'client/util'; | |
2 | 2 | |
3 | 3 | /** |
4 | 4 | * 获取当前的微信执行环境 |
... | ... | @@ -9,19 +9,19 @@ export interface Res { |
9 | 9 | /** |
10 | 10 | * 是否在微信环境 |
11 | 11 | */ |
12 | - wx: boolean, | |
12 | + wx: boolean; | |
13 | 13 | |
14 | 14 | /** |
15 | 15 | * 是否在小程序环境 |
16 | 16 | */ |
17 | - wxMini: boolean | |
17 | + wxMini: boolean; | |
18 | 18 | } |
19 | 19 | |
20 | 20 | function getWinxinEnv(): Promise<Res> { |
21 | 21 | let curEnv = { |
22 | 22 | wx: utils.isWeixin(), |
23 | - wxMini: false | |
24 | - } | |
23 | + wxMini: false, | |
24 | + }; | |
25 | 25 | let i = 0; |
26 | 26 | |
27 | 27 | return new Promise((resolve) => { |
... | ... | @@ -40,24 +40,24 @@ function getWinxinEnv(): Promise<Res> { |
40 | 40 | } |
41 | 41 | |
42 | 42 | // @ts-ignore |
43 | - if (window.wx && window.wx.miniProgram) { | |
43 | + if (window.wx?.miniProgram) { | |
44 | 44 | // @ts-ignore |
45 | - window.wx.miniProgram.getEnv(res => { | |
45 | + window.wx.miniProgram.getEnv((res) => { | |
46 | 46 | if (res.miniprogram) { |
47 | 47 | curEnv.wxMini = true; |
48 | 48 | return resolve(curEnv); |
49 | 49 | } |
50 | 50 | return resolve(curEnv); |
51 | - }) | |
51 | + }); | |
52 | 52 | } else { |
53 | 53 | curEnv.wxMini = false; |
54 | 54 | resolve(curEnv); |
55 | 55 | } |
56 | - }, 50) | |
56 | + }, 50); | |
57 | 57 | } |
58 | 58 | |
59 | 59 | check(); |
60 | 60 | }); |
61 | 61 | } |
62 | 62 | |
63 | -export default getWinxinEnv; | |
64 | 63 | \ No newline at end of file |
64 | +export default getWinxinEnv; | ... | ... |
client/util/fp/location.ts
1 | -import http from 'client/utils/http'; | |
2 | -import host from 'client/utils/host'; | |
1 | +import http from 'client/util/http'; | |
2 | +import host from 'client/util/server'; | |
3 | 3 | |
4 | 4 | /** |
5 | 5 | * 请求权限 |
... | ... | @@ -13,13 +13,13 @@ const getJSApiConfig = (params: any) => { |
13 | 13 | * @param apiList |
14 | 14 | * @returns {*} |
15 | 15 | */ |
16 | -export function initJSSDK(apiList: any) { | |
16 | +export function initJSSDK(apiList: any): Promise<void> { | |
17 | 17 | return new Promise((resolve, reject) => { |
18 | 18 | getJSApiConfig({ |
19 | - url: window.location.href | |
19 | + url: window.location.href, | |
20 | 20 | }) |
21 | 21 | .then((config: any) => { |
22 | - //@ts-ignore | |
22 | + // @ts-ignore | |
23 | 23 | window.wx.config({ |
24 | 24 | debug: false, |
25 | 25 | jsApiList: apiList, |
... | ... | @@ -27,22 +27,22 @@ export function initJSSDK(apiList: any) { |
27 | 27 | resolve(); |
28 | 28 | }, |
29 | 29 | fail: () => { |
30 | - reject({ message: '配置jssdk失败' }); | |
30 | + reject(new Error('配置jssdk失败')); | |
31 | 31 | }, |
32 | 32 | complete: () => {}, |
33 | - ...config.data | |
33 | + ...config.data, | |
34 | 34 | }); |
35 | - //@ts-ignore | |
35 | + // @ts-ignore | |
36 | 36 | window.wx.ready(() => { |
37 | 37 | resolve(); |
38 | 38 | }); |
39 | - //@ts-ignore | |
39 | + // @ts-ignore | |
40 | 40 | window.wx.error((res: any) => { |
41 | - reject({ message: res.errMsg }); | |
41 | + reject(new Error(res.errMsg)); | |
42 | 42 | }); |
43 | 43 | }) |
44 | 44 | .catch((e: any) => { |
45 | - reject({ message: e.message }); | |
45 | + reject(e); | |
46 | 46 | }); |
47 | 47 | }); |
48 | 48 | } |
... | ... | @@ -51,7 +51,7 @@ export const _getLocationFromWx = () => { |
51 | 51 | return new Promise((resolve, reject) => { |
52 | 52 | initJSSDK(['getLocation']) |
53 | 53 | .then(() => { |
54 | - //@ts-ignore | |
54 | + // @ts-ignore | |
55 | 55 | window.wx.getLocation({ |
56 | 56 | type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' |
57 | 57 | success: (res: any) => { |
... | ... | @@ -59,12 +59,12 @@ export const _getLocationFromWx = () => { |
59 | 59 | const longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 |
60 | 60 | resolve({ |
61 | 61 | latitude: latitude, |
62 | - longitude: longitude | |
62 | + longitude: longitude, | |
63 | 63 | }); |
64 | 64 | }, |
65 | 65 | fail: (res: any) => { |
66 | - reject({ message: res.errMsg }); | |
67 | - } | |
66 | + reject(new Error(res.errMsg)); | |
67 | + }, | |
68 | 68 | }); |
69 | 69 | }) |
70 | 70 | .catch(reject); |
... | ... | @@ -72,32 +72,32 @@ export const _getLocationFromWx = () => { |
72 | 72 | }; |
73 | 73 | |
74 | 74 | const getLocationByGeo = () => { |
75 | - //@ts-ignore | |
75 | + // @ts-ignore | |
76 | 76 | if (!window.BMap) { |
77 | 77 | throw new Error('BMap is not an Object.'); |
78 | 78 | } |
79 | 79 | return new Promise((resolve, reject) => { |
80 | - //@ts-ignore | |
80 | + // @ts-ignore | |
81 | 81 | const geoLocation = new window.BMap.Geolocation(); |
82 | 82 | geoLocation.enableSDKLocation(); |
83 | 83 | geoLocation.getCurrentPosition(function getCurrPos(r: any) { |
84 | - //@ts-ignore | |
84 | + // @ts-ignore | |
85 | 85 | if (this.getStatus() === window.BMAP_STATUS_SUCCESS) { |
86 | 86 | resolve(r); |
87 | 87 | } else { |
88 | - reject(); | |
88 | + reject(new Error('地图初始化失败')); | |
89 | 89 | } |
90 | 90 | }); |
91 | 91 | }); |
92 | 92 | }; |
93 | 93 | |
94 | 94 | const getLocationByIP = () => { |
95 | - //@ts-ignore | |
95 | + // @ts-ignore | |
96 | 96 | if (!window.BMap) { |
97 | 97 | throw new Error('BMap is not an Object.'); |
98 | 98 | } |
99 | 99 | return new Promise((resolve) => { |
100 | - //@ts-ignore | |
100 | + // @ts-ignore | |
101 | 101 | const localCity = new window.BMap.LocalCity(); |
102 | 102 | localCity.get((r: any) => { |
103 | 103 | resolve(r); | ... | ... |
client/util/fp/prevAppLaunch.ts
... | ... | @@ -17,11 +17,11 @@ export const prevAppLaunch = async () => { |
17 | 17 | if ('addEventListener' in document) { |
18 | 18 | document.addEventListener( |
19 | 19 | 'DOMContentLoaded', |
20 | - function() { | |
20 | + () => { | |
21 | 21 | // @ts-ignore |
22 | - window.FastClick && window.FastClick.attach(document.body); | |
22 | + window.FastClick?.attach(document.body); | |
23 | 23 | }, |
24 | - false | |
24 | + false, | |
25 | 25 | ); |
26 | 26 | } |
27 | 27 | ... | ... |
client/util/fp/typeOf.ts
... | ... | @@ -4,7 +4,10 @@ |
4 | 4 | */ |
5 | 5 | |
6 | 6 | function typeOf(value: any): string { |
7 | - return Object.prototype.toString.call(value).split(' ')[1].slice(0, -1) | |
7 | + return Object.prototype.toString | |
8 | + .call(value) | |
9 | + .split(' ')[1] | |
10 | + .slice(0, -1) | |
8 | 11 | .replace(/^[A-Z]{1}/, (p: any) => p.toLowerCase()); |
9 | 12 | } |
10 | 13 | ... | ... |
client/util/http.ts
0 → 100644
1 | +import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; | |
2 | +import createError, { createErrorByError, ErrorMsg } from './createError'; | |
3 | +import { IndexLogin } from 'client/components/BottomBar/entity'; | |
4 | +// @ts-ignore | |
5 | +import each from 'lodash/each'; | |
6 | + | |
7 | +interface req extends AxiosRequestConfig { | |
8 | + requestType?: 'JSONString' | 'paramString' | 'formdata' | 'plainString'; | |
9 | + hasToken?: boolean; | |
10 | + token?: string; | |
11 | +} | |
12 | + | |
13 | +interface ExceptionHandle { | |
14 | + reload?: boolean; | |
15 | +} | |
16 | + | |
17 | +/** | |
18 | + * 请求头信息拦截调整 | |
19 | + */ | |
20 | +axios.interceptors.request.use( | |
21 | + async (config: req): Promise<req> => { | |
22 | + if (!config.timeout) { | |
23 | + config.timeout = 30 * 1000; | |
24 | + } | |
25 | + | |
26 | + /** | |
27 | + * 给每个请求新增时间戳 | |
28 | + */ | |
29 | + config.params = { _s: Date.now(), ...config.params }; | |
30 | + | |
31 | + if (config.token) { | |
32 | + config.headers.Authorization = config.token; | |
33 | + } | |
34 | + return config; | |
35 | + }, | |
36 | +); | |
37 | + | |
38 | +axios.interceptors.response.use( | |
39 | + (response): any => { | |
40 | + let data = response.data; | |
41 | + | |
42 | + if (data) { | |
43 | + if (data.success === false) { | |
44 | + return createError(response as any); | |
45 | + } | |
46 | + | |
47 | + if (Object.prototype.hasOwnProperty.call(data, 'data')) { | |
48 | + data.status = response.status; | |
49 | + return data; | |
50 | + } | |
51 | + | |
52 | + return parseResponse(response); | |
53 | + } | |
54 | + | |
55 | + return createError(response as any); | |
56 | + }, | |
57 | + (error) => { | |
58 | + return createErrorByError(error); | |
59 | + }, | |
60 | +); | |
61 | + | |
62 | +export function get<T>(requestURL: string, config?: req): Promise<ICommon.ServerResponse<T>> { | |
63 | + // @ts-ignore | |
64 | + return axios.get(requestURL, config); | |
65 | +} | |
66 | + | |
67 | +export function post<T>(requestURL: string, params: any, config?: req): Promise<ICommon.ServerResponse<T>> { | |
68 | + // @ts-ignore | |
69 | + return axios.post(requestURL, params, config); | |
70 | +} | |
71 | + | |
72 | +/** | |
73 | + * 如果找不到response.data.data,则将返回格式解析为统一格式 | |
74 | + */ | |
75 | +function parseResponse<T>(response: AxiosResponse): ICommon.ServerResponse<T> { | |
76 | + const code: number = response.status; | |
77 | + const success = true; | |
78 | + const result: string = response.statusText; | |
79 | + const status: number = response.status; | |
80 | + const data = response.data; | |
81 | + | |
82 | + return { code, success, result, data, status }; | |
83 | +} | |
84 | + | |
85 | +function exceptionHandle(error: ErrorMsg, config?: ExceptionHandle) { | |
86 | + const code: number = Number(error.errorCode) || 0; | |
87 | + /** | |
88 | + * 用户未登陆 | |
89 | + */ | |
90 | + if ([401, 40101, 40102, 40103, 40104].includes(code) && config && config.reload) { | |
91 | + // 跳转小程序登录 | |
92 | + handleLoginPage(); | |
93 | + } | |
94 | +} | |
95 | + | |
96 | +const handleLoginPage = () => { | |
97 | + try { | |
98 | + const url = IndexLogin; | |
99 | + // @ts-ignore | |
100 | + wx.miniProgram.navigateTo({ url: `${url}?hasBack=0` }); | |
101 | + } catch (e) {} | |
102 | +}; | |
103 | + | |
104 | +const http = { | |
105 | + get, | |
106 | + post, | |
107 | + exceptionHandle, | |
108 | +}; | |
109 | + | |
110 | +export default http; | ... | ... |
client/util/index.ts
... | ... | @@ -61,37 +61,37 @@ const checkEnv = () => { |
61 | 61 | return new Promise<any>((resolve) => { |
62 | 62 | const ua = window.navigator.userAgent.toLowerCase(); |
63 | 63 | if (/MicroMessenger/i.test(ua)) { |
64 | - //判断是否是微信环境 | |
65 | - //微信环境 | |
64 | + // 判断是否是微信环境 | |
65 | + // 微信环境 | |
66 | 66 | // @ts-ignore |
67 | - if (window.wx && window.wx.miniProgram) { | |
67 | + if (window.wx?.miniProgram) { | |
68 | 68 | // @ts-ignore |
69 | - window.wx.miniProgram.getEnv(function(res: any) { | |
69 | + window.wx.miniProgram.getEnv((res: any) => { | |
70 | 70 | if (res.miniprogram) { |
71 | 71 | // 小程序环境下逻辑 |
72 | 72 | resolve({ |
73 | 73 | miniProgram: true, |
74 | - wxEnv: true | |
74 | + wxEnv: true, | |
75 | 75 | }); |
76 | 76 | } else { |
77 | 77 | resolve({ |
78 | 78 | miniProgram: false, |
79 | - wxEnv: true | |
79 | + wxEnv: true, | |
80 | 80 | }); |
81 | - //非小程序环境下逻辑 | |
81 | + // 非小程序环境下逻辑 | |
82 | 82 | } |
83 | 83 | }); |
84 | 84 | } else { |
85 | 85 | resolve({ |
86 | 86 | miniProgram: false, |
87 | - wxEnv: true | |
87 | + wxEnv: true, | |
88 | 88 | }); |
89 | 89 | } |
90 | 90 | } else { |
91 | - //非微信环境逻辑 | |
91 | + // 非微信环境逻辑 | |
92 | 92 | resolve({ |
93 | 93 | miniProgram: false, |
94 | - wxEnv: false | |
94 | + wxEnv: false, | |
95 | 95 | }); |
96 | 96 | } |
97 | 97 | }); |
... | ... | @@ -112,5 +112,5 @@ export default { |
112 | 112 | isSupportSticky, |
113 | 113 | typeOf, |
114 | 114 | prevAppLaunch, |
115 | - checkEnv | |
115 | + checkEnv, | |
116 | 116 | }; | ... | ... |
client/util/server.ts
... | ... | @@ -9,6 +9,7 @@ import config from '../../config.json'; |
9 | 9 | */ |
10 | 10 | interface HOST { |
11 | 11 | pstn?: string; |
12 | + passport?: string; | |
12 | 13 | [key: string]: any; |
13 | 14 | } |
14 | 15 | |
... | ... | @@ -18,7 +19,7 @@ export function setHost() { |
18 | 19 | const proxy = config?.env ? `http://${config?.env || ''}` : 'https://'; |
19 | 20 | const _host = `${proxy}gate.feewee.cn`; |
20 | 21 | |
21 | - ['pstn'].forEach((sub) => { | |
22 | + ['pstn', 'passport'].forEach((sub) => { | |
22 | 23 | server[sub] = `${_host}/${sub}`; |
23 | 24 | }); |
24 | 25 | } | ... | ... |
client/util/tool/commonApi.ts
1 | 1 | import http from 'client/util/http'; |
2 | -import host from 'client/util/host'; | |
3 | -import { request } from 'client/util/http/interface'; | |
2 | +import host from 'client/util/server'; | |
4 | 3 | import _URL from 'client/util/url'; |
5 | 4 | |
6 | 5 | const _url = _URL.current(window.location.href); |
... | ... | @@ -9,6 +8,6 @@ const token = _url.query.token as string; |
9 | 8 | /** |
10 | 9 | * 检测是否关注公众号 |
11 | 10 | */ |
12 | -export function checkFollowOffice(): request.PromiseResp<boolean> { | |
11 | +export function checkFollowOffice(): Promise<ICommon.ServerResponse<boolean>> { | |
13 | 12 | return http.get(`${host.passport}/getWechatUserInfo/byUserId`, { params: { token } }); |
14 | 13 | } | ... | ... |
client/util/tool/index.ts
... | ... | @@ -96,3 +96,29 @@ export const hiddenPhone = (phone: string, length = 4): string => { |
96 | 96 | } |
97 | 97 | return temp; |
98 | 98 | }; |
99 | + | |
100 | +/** | |
101 | + * 保留两位小数 四舍五入 | |
102 | + * @param n | |
103 | + * @param digit 需要的小数位数 | |
104 | + * @returns | |
105 | + */ | |
106 | +export const toFixed = (n: number, digit: number): string => { | |
107 | + if (typeof n !== 'number') { | |
108 | + throw new Error('n is not a number'); | |
109 | + } | |
110 | + let result = String(Math.round(Math.pow(10, digit) * n) / Math.pow(10, digit)); | |
111 | + if (result.indexOf('.') == -1) { | |
112 | + if (digit != 0) { | |
113 | + result += '.'; | |
114 | + result += new Array(digit + 1).join('0'); | |
115 | + } | |
116 | + } else { | |
117 | + let arr = result.split('.'); | |
118 | + if (arr[1].length < digit) { | |
119 | + arr[1] += new Array(digit - arr[1].length + 1).join('0'); | |
120 | + } | |
121 | + result = arr.join('.'); | |
122 | + } | |
123 | + return result; | |
124 | +}; | ... | ... |
client/util/tool/mmLocal.ts
... | ... | @@ -19,7 +19,8 @@ moment.locale('zh-cn', { |
19 | 19 | llll: 'YYYY年MMMD日ddddAh点mm分', |
20 | 20 | }, |
21 | 21 | meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, |
22 | - meridiemHour(hour: number, meridiem: string) { | |
22 | + meridiemHour(_hour: number, meridiem: string) { | |
23 | + let hour: number = _hour; | |
23 | 24 | if (hour === 12) { |
24 | 25 | hour = 0; |
25 | 26 | } | ... | ... |