diff --git a/client/layout/index.tsx b/client/layout/index.tsx index 83e0ea2..4fcf068 100644 --- a/client/layout/index.tsx +++ b/client/layout/index.tsx @@ -12,7 +12,6 @@ export default class Layout extends React.Component { public render() { const { title, helper, entry, store, children } = this.props; const htmlString = children as string; - return ( diff --git a/client/util/createError.ts b/client/util/createError.ts index 647b469..1eaa97b 100644 --- a/client/util/createError.ts +++ b/client/util/createError.ts @@ -1,11 +1,11 @@ -import { AxiosError } from 'axios'; +import { AxiosError, AxiosResponse } from 'axios'; import { HttpClientResponse } from 'urllib'; -interface ErrorCode { +export interface ErrorCode { [key: number]: string; } -interface ErrorMsg extends Error { +export interface ErrorMsg extends Error { errorCode?: number | string; errorMsg?: string; response?: any; diff --git a/client/util/fp/getWinxinEnv.ts b/client/util/fp/getWinxinEnv.ts index b22b691..dd25c44 100644 --- a/client/util/fp/getWinxinEnv.ts +++ b/client/util/fp/getWinxinEnv.ts @@ -1,4 +1,4 @@ -import utils from 'client/utils'; +import utils from 'client/util'; /** * 获取当前的微信执行环境 @@ -9,19 +9,19 @@ export interface Res { /** * 是否在微信环境 */ - wx: boolean, + wx: boolean; /** * 是否在小程序环境 */ - wxMini: boolean + wxMini: boolean; } function getWinxinEnv(): Promise { let curEnv = { wx: utils.isWeixin(), - wxMini: false - } + wxMini: false, + }; let i = 0; return new Promise((resolve) => { @@ -40,24 +40,24 @@ function getWinxinEnv(): Promise { } // @ts-ignore - if (window.wx && window.wx.miniProgram) { + if (window.wx?.miniProgram) { // @ts-ignore - window.wx.miniProgram.getEnv(res => { + window.wx.miniProgram.getEnv((res) => { if (res.miniprogram) { curEnv.wxMini = true; return resolve(curEnv); } return resolve(curEnv); - }) + }); } else { curEnv.wxMini = false; resolve(curEnv); } - }, 50) + }, 50); } check(); }); } -export default getWinxinEnv; \ No newline at end of file +export default getWinxinEnv; diff --git a/client/util/fp/location.ts b/client/util/fp/location.ts index 4770c5f..799fa01 100644 --- a/client/util/fp/location.ts +++ b/client/util/fp/location.ts @@ -1,5 +1,5 @@ -import http from 'client/utils/http'; -import host from 'client/utils/host'; +import http from 'client/util/http'; +import host from 'client/util/server'; /** * 请求权限 @@ -13,13 +13,13 @@ const getJSApiConfig = (params: any) => { * @param apiList * @returns {*} */ -export function initJSSDK(apiList: any) { +export function initJSSDK(apiList: any): Promise { return new Promise((resolve, reject) => { getJSApiConfig({ - url: window.location.href + url: window.location.href, }) .then((config: any) => { - //@ts-ignore + // @ts-ignore window.wx.config({ debug: false, jsApiList: apiList, @@ -27,22 +27,22 @@ export function initJSSDK(apiList: any) { resolve(); }, fail: () => { - reject({ message: '配置jssdk失败' }); + reject(new Error('配置jssdk失败')); }, complete: () => {}, - ...config.data + ...config.data, }); - //@ts-ignore + // @ts-ignore window.wx.ready(() => { resolve(); }); - //@ts-ignore + // @ts-ignore window.wx.error((res: any) => { - reject({ message: res.errMsg }); + reject(new Error(res.errMsg)); }); }) .catch((e: any) => { - reject({ message: e.message }); + reject(e); }); }); } @@ -51,7 +51,7 @@ export const _getLocationFromWx = () => { return new Promise((resolve, reject) => { initJSSDK(['getLocation']) .then(() => { - //@ts-ignore + // @ts-ignore window.wx.getLocation({ type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02' success: (res: any) => { @@ -59,12 +59,12 @@ export const _getLocationFromWx = () => { const longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。 resolve({ latitude: latitude, - longitude: longitude + longitude: longitude, }); }, fail: (res: any) => { - reject({ message: res.errMsg }); - } + reject(new Error(res.errMsg)); + }, }); }) .catch(reject); @@ -72,32 +72,32 @@ export const _getLocationFromWx = () => { }; const getLocationByGeo = () => { - //@ts-ignore + // @ts-ignore if (!window.BMap) { throw new Error('BMap is not an Object.'); } return new Promise((resolve, reject) => { - //@ts-ignore + // @ts-ignore const geoLocation = new window.BMap.Geolocation(); geoLocation.enableSDKLocation(); geoLocation.getCurrentPosition(function getCurrPos(r: any) { - //@ts-ignore + // @ts-ignore if (this.getStatus() === window.BMAP_STATUS_SUCCESS) { resolve(r); } else { - reject(); + reject(new Error('地图初始化失败')); } }); }); }; const getLocationByIP = () => { - //@ts-ignore + // @ts-ignore if (!window.BMap) { throw new Error('BMap is not an Object.'); } return new Promise((resolve) => { - //@ts-ignore + // @ts-ignore const localCity = new window.BMap.LocalCity(); localCity.get((r: any) => { resolve(r); diff --git a/client/util/fp/prevAppLaunch.ts b/client/util/fp/prevAppLaunch.ts index 59bb13a..69a5b45 100644 --- a/client/util/fp/prevAppLaunch.ts +++ b/client/util/fp/prevAppLaunch.ts @@ -17,11 +17,11 @@ export const prevAppLaunch = async () => { if ('addEventListener' in document) { document.addEventListener( 'DOMContentLoaded', - function() { + () => { // @ts-ignore - window.FastClick && window.FastClick.attach(document.body); + window.FastClick?.attach(document.body); }, - false + false, ); } diff --git a/client/util/fp/typeOf.ts b/client/util/fp/typeOf.ts index f95dc48..1e22bc5 100644 --- a/client/util/fp/typeOf.ts +++ b/client/util/fp/typeOf.ts @@ -4,7 +4,10 @@ */ function typeOf(value: any): string { - return Object.prototype.toString.call(value).split(' ')[1].slice(0, -1) + return Object.prototype.toString + .call(value) + .split(' ')[1] + .slice(0, -1) .replace(/^[A-Z]{1}/, (p: any) => p.toLowerCase()); } diff --git a/client/util/http.ts b/client/util/http.ts new file mode 100644 index 0000000..84f300f --- /dev/null +++ b/client/util/http.ts @@ -0,0 +1,110 @@ +import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; +import createError, { createErrorByError, ErrorMsg } from './createError'; +import { IndexLogin } from 'client/components/BottomBar/entity'; +// @ts-ignore +import each from 'lodash/each'; + +interface req extends AxiosRequestConfig { + requestType?: 'JSONString' | 'paramString' | 'formdata' | 'plainString'; + hasToken?: boolean; + token?: string; +} + +interface ExceptionHandle { + reload?: boolean; +} + +/** + * 请求头信息拦截调整 + */ +axios.interceptors.request.use( + async (config: req): Promise => { + if (!config.timeout) { + config.timeout = 30 * 1000; + } + + /** + * 给每个请求新增时间戳 + */ + config.params = { _s: Date.now(), ...config.params }; + + if (config.token) { + config.headers.Authorization = config.token; + } + return config; + }, +); + +axios.interceptors.response.use( + (response): any => { + let data = response.data; + + if (data) { + if (data.success === false) { + return createError(response as any); + } + + if (Object.prototype.hasOwnProperty.call(data, 'data')) { + data.status = response.status; + return data; + } + + return parseResponse(response); + } + + return createError(response as any); + }, + (error) => { + return createErrorByError(error); + }, +); + +export function get(requestURL: string, config?: req): Promise> { + // @ts-ignore + return axios.get(requestURL, config); +} + +export function post(requestURL: string, params: any, config?: req): Promise> { + // @ts-ignore + return axios.post(requestURL, params, config); +} + +/** + * 如果找不到response.data.data,则将返回格式解析为统一格式 + */ +function parseResponse(response: AxiosResponse): ICommon.ServerResponse { + const code: number = response.status; + const success = true; + const result: string = response.statusText; + const status: number = response.status; + const data = response.data; + + return { code, success, result, data, status }; +} + +function exceptionHandle(error: ErrorMsg, config?: ExceptionHandle) { + const code: number = Number(error.errorCode) || 0; + /** + * 用户未登陆 + */ + if ([401, 40101, 40102, 40103, 40104].includes(code) && config && config.reload) { + // 跳转小程序登录 + handleLoginPage(); + } +} + +const handleLoginPage = () => { + try { + const url = IndexLogin; + // @ts-ignore + wx.miniProgram.navigateTo({ url: `${url}?hasBack=0` }); + } catch (e) {} +}; + +const http = { + get, + post, + exceptionHandle, +}; + +export default http; diff --git a/client/util/index.ts b/client/util/index.ts index 331268a..a10dab4 100644 --- a/client/util/index.ts +++ b/client/util/index.ts @@ -61,37 +61,37 @@ const checkEnv = () => { return new Promise((resolve) => { const ua = window.navigator.userAgent.toLowerCase(); if (/MicroMessenger/i.test(ua)) { - //判断是否是微信环境 - //微信环境 + // 判断是否是微信环境 + // 微信环境 // @ts-ignore - if (window.wx && window.wx.miniProgram) { + if (window.wx?.miniProgram) { // @ts-ignore - window.wx.miniProgram.getEnv(function(res: any) { + window.wx.miniProgram.getEnv((res: any) => { if (res.miniprogram) { // 小程序环境下逻辑 resolve({ miniProgram: true, - wxEnv: true + wxEnv: true, }); } else { resolve({ miniProgram: false, - wxEnv: true + wxEnv: true, }); - //非小程序环境下逻辑 + // 非小程序环境下逻辑 } }); } else { resolve({ miniProgram: false, - wxEnv: true + wxEnv: true, }); } } else { - //非微信环境逻辑 + // 非微信环境逻辑 resolve({ miniProgram: false, - wxEnv: false + wxEnv: false, }); } }); @@ -112,5 +112,5 @@ export default { isSupportSticky, typeOf, prevAppLaunch, - checkEnv + checkEnv, }; diff --git a/client/util/server.ts b/client/util/server.ts index d7d3702..097ca5b 100644 --- a/client/util/server.ts +++ b/client/util/server.ts @@ -9,6 +9,7 @@ import config from '../../config.json'; */ interface HOST { pstn?: string; + passport?: string; [key: string]: any; } @@ -18,7 +19,7 @@ export function setHost() { const proxy = config?.env ? `http://${config?.env || ''}` : 'https://'; const _host = `${proxy}gate.feewee.cn`; - ['pstn'].forEach((sub) => { + ['pstn', 'passport'].forEach((sub) => { server[sub] = `${_host}/${sub}`; }); } diff --git a/client/util/tool/commonApi.ts b/client/util/tool/commonApi.ts index a48e1a9..914f7db 100644 --- a/client/util/tool/commonApi.ts +++ b/client/util/tool/commonApi.ts @@ -1,6 +1,5 @@ import http from 'client/util/http'; -import host from 'client/util/host'; -import { request } from 'client/util/http/interface'; +import host from 'client/util/server'; import _URL from 'client/util/url'; const _url = _URL.current(window.location.href); @@ -9,6 +8,6 @@ const token = _url.query.token as string; /** * 检测是否关注公众号 */ -export function checkFollowOffice(): request.PromiseResp { +export function checkFollowOffice(): Promise> { return http.get(`${host.passport}/getWechatUserInfo/byUserId`, { params: { token } }); } diff --git a/client/util/tool/index.ts b/client/util/tool/index.ts index 4438924..e794c21 100644 --- a/client/util/tool/index.ts +++ b/client/util/tool/index.ts @@ -96,3 +96,29 @@ export const hiddenPhone = (phone: string, length = 4): string => { } return temp; }; + +/** + * 保留两位小数 四舍五入 + * @param n + * @param digit 需要的小数位数 + * @returns + */ +export const toFixed = (n: number, digit: number): string => { + if (typeof n !== 'number') { + throw new Error('n is not a number'); + } + let result = String(Math.round(Math.pow(10, digit) * n) / Math.pow(10, digit)); + if (result.indexOf('.') == -1) { + if (digit != 0) { + result += '.'; + result += new Array(digit + 1).join('0'); + } + } else { + let arr = result.split('.'); + if (arr[1].length < digit) { + arr[1] += new Array(digit - arr[1].length + 1).join('0'); + } + result = arr.join('.'); + } + return result; +}; diff --git a/client/util/tool/mmLocal.ts b/client/util/tool/mmLocal.ts index 690cdbd..ea57c22 100644 --- a/client/util/tool/mmLocal.ts +++ b/client/util/tool/mmLocal.ts @@ -19,7 +19,8 @@ moment.locale('zh-cn', { llll: 'YYYY年MMMD日ddddAh点mm分', }, meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, - meridiemHour(hour: number, meridiem: string) { + meridiemHour(_hour: number, meridiem: string) { + let hour: number = _hour; if (hour === 12) { hour = 0; } diff --git a/typings/common.d.ts b/typings/common.d.ts index 7318046..69d96c8 100644 --- a/typings/common.d.ts +++ b/typings/common.d.ts @@ -32,6 +32,7 @@ declare namespace ICommon { data?: T; code?: number; result?: string; + status?: number; } /**