Commit ec23e9b6b9bc1fba604b329f0089974923fcc940

Authored by 张志伟
1 parent 56001e24

优化文件

client/layout/index.tsx
@@ -12,7 +12,6 @@ export default class Layout extends React.Component<PropTypes> { @@ -12,7 +12,6 @@ export default class Layout extends React.Component<PropTypes> {
12 public render() { 12 public render() {
13 const { title, helper, entry, store, children } = this.props; 13 const { title, helper, entry, store, children } = this.props;
14 const htmlString = children as string; 14 const htmlString = children as string;
15 -  
16 return ( 15 return (
17 <html> 16 <html>
18 <head> 17 <head>
client/util/createError.ts
1 -import { AxiosError } from 'axios'; 1 +import { AxiosError, AxiosResponse } from 'axios';
2 import { HttpClientResponse } from 'urllib'; 2 import { HttpClientResponse } from 'urllib';
3 3
4 -interface ErrorCode { 4 +export interface ErrorCode {
5 [key: number]: string; 5 [key: number]: string;
6 } 6 }
7 7
8 -interface ErrorMsg extends Error { 8 +export interface ErrorMsg extends Error {
9 errorCode?: number | string; 9 errorCode?: number | string;
10 errorMsg?: string; 10 errorMsg?: string;
11 response?: any; 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,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 function getWinxinEnv(): Promise<Res> { 20 function getWinxinEnv(): Promise<Res> {
21 let curEnv = { 21 let curEnv = {
22 wx: utils.isWeixin(), 22 wx: utils.isWeixin(),
23 - wxMini: false  
24 - } 23 + wxMini: false,
  24 + };
25 let i = 0; 25 let i = 0;
26 26
27 return new Promise((resolve) => { 27 return new Promise((resolve) => {
@@ -40,24 +40,24 @@ function getWinxinEnv(): Promise&lt;Res&gt; { @@ -40,24 +40,24 @@ function getWinxinEnv(): Promise&lt;Res&gt; {
40 } 40 }
41 41
42 // @ts-ignore 42 // @ts-ignore
43 - if (window.wx && window.wx.miniProgram) { 43 + if (window.wx?.miniProgram) {
44 // @ts-ignore 44 // @ts-ignore
45 - window.wx.miniProgram.getEnv(res => { 45 + window.wx.miniProgram.getEnv((res) => {
46 if (res.miniprogram) { 46 if (res.miniprogram) {
47 curEnv.wxMini = true; 47 curEnv.wxMini = true;
48 return resolve(curEnv); 48 return resolve(curEnv);
49 } 49 }
50 return resolve(curEnv); 50 return resolve(curEnv);
51 - }) 51 + });
52 } else { 52 } else {
53 curEnv.wxMini = false; 53 curEnv.wxMini = false;
54 resolve(curEnv); 54 resolve(curEnv);
55 } 55 }
56 - }, 50) 56 + }, 50);
57 } 57 }
58 58
59 check(); 59 check();
60 }); 60 });
61 } 61 }
62 62
63 -export default getWinxinEnv;  
64 \ No newline at end of file 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) =&gt; { @@ -13,13 +13,13 @@ const getJSApiConfig = (params: any) =&gt; {
13 * @param apiList 13 * @param apiList
14 * @returns {*} 14 * @returns {*}
15 */ 15 */
16 -export function initJSSDK(apiList: any) { 16 +export function initJSSDK(apiList: any): Promise<void> {
17 return new Promise((resolve, reject) => { 17 return new Promise((resolve, reject) => {
18 getJSApiConfig({ 18 getJSApiConfig({
19 - url: window.location.href 19 + url: window.location.href,
20 }) 20 })
21 .then((config: any) => { 21 .then((config: any) => {
22 - //@ts-ignore 22 + // @ts-ignore
23 window.wx.config({ 23 window.wx.config({
24 debug: false, 24 debug: false,
25 jsApiList: apiList, 25 jsApiList: apiList,
@@ -27,22 +27,22 @@ export function initJSSDK(apiList: any) { @@ -27,22 +27,22 @@ export function initJSSDK(apiList: any) {
27 resolve(); 27 resolve();
28 }, 28 },
29 fail: () => { 29 fail: () => {
30 - reject({ message: '配置jssdk失败' }); 30 + reject(new Error('配置jssdk失败'));
31 }, 31 },
32 complete: () => {}, 32 complete: () => {},
33 - ...config.data 33 + ...config.data,
34 }); 34 });
35 - //@ts-ignore 35 + // @ts-ignore
36 window.wx.ready(() => { 36 window.wx.ready(() => {
37 resolve(); 37 resolve();
38 }); 38 });
39 - //@ts-ignore 39 + // @ts-ignore
40 window.wx.error((res: any) => { 40 window.wx.error((res: any) => {
41 - reject({ message: res.errMsg }); 41 + reject(new Error(res.errMsg));
42 }); 42 });
43 }) 43 })
44 .catch((e: any) => { 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 = () =&gt; { @@ -51,7 +51,7 @@ export const _getLocationFromWx = () =&gt; {
51 return new Promise((resolve, reject) => { 51 return new Promise((resolve, reject) => {
52 initJSSDK(['getLocation']) 52 initJSSDK(['getLocation'])
53 .then(() => { 53 .then(() => {
54 - //@ts-ignore 54 + // @ts-ignore
55 window.wx.getLocation({ 55 window.wx.getLocation({
56 type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' 56 type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
57 success: (res: any) => { 57 success: (res: any) => {
@@ -59,12 +59,12 @@ export const _getLocationFromWx = () =&gt; { @@ -59,12 +59,12 @@ export const _getLocationFromWx = () =&gt; {
59 const longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 59 const longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
60 resolve({ 60 resolve({
61 latitude: latitude, 61 latitude: latitude,
62 - longitude: longitude 62 + longitude: longitude,
63 }); 63 });
64 }, 64 },
65 fail: (res: any) => { 65 fail: (res: any) => {
66 - reject({ message: res.errMsg });  
67 - } 66 + reject(new Error(res.errMsg));
  67 + },
68 }); 68 });
69 }) 69 })
70 .catch(reject); 70 .catch(reject);
@@ -72,32 +72,32 @@ export const _getLocationFromWx = () =&gt; { @@ -72,32 +72,32 @@ export const _getLocationFromWx = () =&gt; {
72 }; 72 };
73 73
74 const getLocationByGeo = () => { 74 const getLocationByGeo = () => {
75 - //@ts-ignore 75 + // @ts-ignore
76 if (!window.BMap) { 76 if (!window.BMap) {
77 throw new Error('BMap is not an Object.'); 77 throw new Error('BMap is not an Object.');
78 } 78 }
79 return new Promise((resolve, reject) => { 79 return new Promise((resolve, reject) => {
80 - //@ts-ignore 80 + // @ts-ignore
81 const geoLocation = new window.BMap.Geolocation(); 81 const geoLocation = new window.BMap.Geolocation();
82 geoLocation.enableSDKLocation(); 82 geoLocation.enableSDKLocation();
83 geoLocation.getCurrentPosition(function getCurrPos(r: any) { 83 geoLocation.getCurrentPosition(function getCurrPos(r: any) {
84 - //@ts-ignore 84 + // @ts-ignore
85 if (this.getStatus() === window.BMAP_STATUS_SUCCESS) { 85 if (this.getStatus() === window.BMAP_STATUS_SUCCESS) {
86 resolve(r); 86 resolve(r);
87 } else { 87 } else {
88 - reject(); 88 + reject(new Error('地图初始化失败'));
89 } 89 }
90 }); 90 });
91 }); 91 });
92 }; 92 };
93 93
94 const getLocationByIP = () => { 94 const getLocationByIP = () => {
95 - //@ts-ignore 95 + // @ts-ignore
96 if (!window.BMap) { 96 if (!window.BMap) {
97 throw new Error('BMap is not an Object.'); 97 throw new Error('BMap is not an Object.');
98 } 98 }
99 return new Promise((resolve) => { 99 return new Promise((resolve) => {
100 - //@ts-ignore 100 + // @ts-ignore
101 const localCity = new window.BMap.LocalCity(); 101 const localCity = new window.BMap.LocalCity();
102 localCity.get((r: any) => { 102 localCity.get((r: any) => {
103 resolve(r); 103 resolve(r);
client/util/fp/prevAppLaunch.ts
@@ -17,11 +17,11 @@ export const prevAppLaunch = async () =&gt; { @@ -17,11 +17,11 @@ export const prevAppLaunch = async () =&gt; {
17 if ('addEventListener' in document) { 17 if ('addEventListener' in document) {
18 document.addEventListener( 18 document.addEventListener(
19 'DOMContentLoaded', 19 'DOMContentLoaded',
20 - function() { 20 + () => {
21 // @ts-ignore 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,7 +4,10 @@
4 */ 4 */
5 5
6 function typeOf(value: any): string { 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 .replace(/^[A-Z]{1}/, (p: any) => p.toLowerCase()); 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 = () =&gt; { @@ -61,37 +61,37 @@ const checkEnv = () =&gt; {
61 return new Promise<any>((resolve) => { 61 return new Promise<any>((resolve) => {
62 const ua = window.navigator.userAgent.toLowerCase(); 62 const ua = window.navigator.userAgent.toLowerCase();
63 if (/MicroMessenger/i.test(ua)) { 63 if (/MicroMessenger/i.test(ua)) {
64 - //判断是否是微信环境  
65 - //微信环境 64 + // 判断是否是微信环境
  65 + // 微信环境
66 // @ts-ignore 66 // @ts-ignore
67 - if (window.wx && window.wx.miniProgram) { 67 + if (window.wx?.miniProgram) {
68 // @ts-ignore 68 // @ts-ignore
69 - window.wx.miniProgram.getEnv(function(res: any) { 69 + window.wx.miniProgram.getEnv((res: any) => {
70 if (res.miniprogram) { 70 if (res.miniprogram) {
71 // 小程序环境下逻辑 71 // 小程序环境下逻辑
72 resolve({ 72 resolve({
73 miniProgram: true, 73 miniProgram: true,
74 - wxEnv: true 74 + wxEnv: true,
75 }); 75 });
76 } else { 76 } else {
77 resolve({ 77 resolve({
78 miniProgram: false, 78 miniProgram: false,
79 - wxEnv: true 79 + wxEnv: true,
80 }); 80 });
81 - //非小程序环境下逻辑 81 + // 非小程序环境下逻辑
82 } 82 }
83 }); 83 });
84 } else { 84 } else {
85 resolve({ 85 resolve({
86 miniProgram: false, 86 miniProgram: false,
87 - wxEnv: true 87 + wxEnv: true,
88 }); 88 });
89 } 89 }
90 } else { 90 } else {
91 - //非微信环境逻辑 91 + // 非微信环境逻辑
92 resolve({ 92 resolve({
93 miniProgram: false, 93 miniProgram: false,
94 - wxEnv: false 94 + wxEnv: false,
95 }); 95 });
96 } 96 }
97 }); 97 });
@@ -112,5 +112,5 @@ export default { @@ -112,5 +112,5 @@ export default {
112 isSupportSticky, 112 isSupportSticky,
113 typeOf, 113 typeOf,
114 prevAppLaunch, 114 prevAppLaunch,
115 - checkEnv 115 + checkEnv,
116 }; 116 };
client/util/server.ts
@@ -9,6 +9,7 @@ import config from &#39;../../config.json&#39;; @@ -9,6 +9,7 @@ import config from &#39;../../config.json&#39;;
9 */ 9 */
10 interface HOST { 10 interface HOST {
11 pstn?: string; 11 pstn?: string;
  12 + passport?: string;
12 [key: string]: any; 13 [key: string]: any;
13 } 14 }
14 15
@@ -18,7 +19,7 @@ export function setHost() { @@ -18,7 +19,7 @@ export function setHost() {
18 const proxy = config?.env ? `http://${config?.env || ''}` : 'https://'; 19 const proxy = config?.env ? `http://${config?.env || ''}` : 'https://';
19 const _host = `${proxy}gate.feewee.cn`; 20 const _host = `${proxy}gate.feewee.cn`;
20 21
21 - ['pstn'].forEach((sub) => { 22 + ['pstn', 'passport'].forEach((sub) => {
22 server[sub] = `${_host}/${sub}`; 23 server[sub] = `${_host}/${sub}`;
23 }); 24 });
24 } 25 }
client/util/tool/commonApi.ts
1 import http from 'client/util/http'; 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 import _URL from 'client/util/url'; 3 import _URL from 'client/util/url';
5 4
6 const _url = _URL.current(window.location.href); 5 const _url = _URL.current(window.location.href);
@@ -9,6 +8,6 @@ const token = _url.query.token as string; @@ -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 return http.get(`${host.passport}/getWechatUserInfo/byUserId`, { params: { token } }); 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 =&gt; { @@ -96,3 +96,29 @@ export const hiddenPhone = (phone: string, length = 4): string =&gt; {
96 } 96 }
97 return temp; 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(&#39;zh-cn&#39;, { @@ -19,7 +19,8 @@ moment.locale(&#39;zh-cn&#39;, {
19 llll: 'YYYY年MMMD日ddddAh点mm分', 19 llll: 'YYYY年MMMD日ddddAh点mm分',
20 }, 20 },
21 meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, 21 meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
22 - meridiemHour(hour: number, meridiem: string) { 22 + meridiemHour(_hour: number, meridiem: string) {
  23 + let hour: number = _hour;
23 if (hour === 12) { 24 if (hour === 12) {
24 hour = 0; 25 hour = 0;
25 } 26 }
typings/common.d.ts
@@ -32,6 +32,7 @@ declare namespace ICommon { @@ -32,6 +32,7 @@ declare namespace ICommon {
32 data?: T; 32 data?: T;
33 code?: number; 33 code?: number;
34 result?: string; 34 result?: string;
  35 + status?: number;
35 } 36 }
36 37
37 /** 38 /**