From cd59783e90e00826ccdbe918d87508447bdc6553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E4=B8=83=E5=B9=B4=E5=A4=8F?= <2098833867@qq.com> Date: Tue, 6 Jun 2023 08:46:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=B7=E6=B1=82=E6=8E=A5=E5=8F=A3=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=8C=E6=B7=BB=E5=8A=A0500=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=88=9D=E5=A7=8B=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=8B=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=BF=9E=E6=8E=A5=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E9=80=A0=E6=88=90=E7=9B=B4=E6=8E=A5=E9=80=80=E5=87=BA?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DESLint=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eslintrc/eslint-config.js | 1 + src/components/__tests__/el-svgIcon.test.jsx | 1 + src/hooks/use-permission.ts | 2 - src/permission.ts | 7 +- src/router/index.ts | 5 + src/utils/common-util.ts | 2 +- src/utils/mock-axios-req.ts | 1 + src/utils/request.ts | 39 +-- src/utils/validate.ts | 47 ++-- src/views/error-page/500.vue | 237 +++++++++++++++++++ 10 files changed, 294 insertions(+), 48 deletions(-) create mode 100644 src/views/error-page/500.vue diff --git a/eslintrc/eslint-config.js b/eslintrc/eslint-config.js index 34b37f7..b678dfb 100644 --- a/eslintrc/eslint-config.js +++ b/eslintrc/eslint-config.js @@ -74,6 +74,7 @@ module.exports = defineConfig({ 'prefer-rest-params': 'error', 'prefer-spread': 'error', 'prefer-template': 'error', + 'eslint-comments/no-unlimited-disable': 'off', 'no-redeclare': 'off', '@typescript-eslint/no-redeclare': 'error', diff --git a/src/components/__tests__/el-svgIcon.test.jsx b/src/components/__tests__/el-svgIcon.test.jsx index 238a998..5e6c5a7 100644 --- a/src/components/__tests__/el-svgIcon.test.jsx +++ b/src/components/__tests__/el-svgIcon.test.jsx @@ -1,3 +1,4 @@ +/* eslint-disable */ import { markRaw, nextTick, ref } from 'vue' import { mount } from '@vue/test-utils' import { describe, expect, it, test } from 'vitest' diff --git a/src/hooks/use-permission.ts b/src/hooks/use-permission.ts index 4050e38..8bcf2d3 100644 --- a/src/hooks/use-permission.ts +++ b/src/hooks/use-permission.ts @@ -1,7 +1,6 @@ import NProgress from 'nprogress' import type { RouteRawConfig, RouterTypes, rawConfig } from '~/basic' import type { RouteRecordName } from 'vue-router' -import { RouterView } from 'vue-router' /** * 根据请求,过滤异步路由 * @param:menuList 异步路由数组 @@ -17,7 +16,6 @@ import router, { asyncRoutes, constantRoutes } from '@/router' import 'nprogress/nprogress.css' import { useBasicStore } from '@/store/basic' import { isArray } from 'xe-utils' -import settings from '@/settings' const buttonCodes: Array = [] //按钮权限 interface menuRow { diff --git a/src/permission.ts b/src/permission.ts index 574e2f7..1fc6cab 100644 --- a/src/permission.ts +++ b/src/permission.ts @@ -7,11 +7,14 @@ import { getRouterList } from '@/api/router' //路由进入前拦截 //to:将要进入的页面 vue-router4.0 不推荐使用next() -const whiteList = ['/login', '/404', '/401'] // no redirect whitelist +const whiteList = ['/login', '/404', '/401', '/500'] // no redirect whitelist router.beforeEach(async (to) => { progressStart() document.title = langTitle(to.meta?.title) // i18 page title const basicStore = useBasicStore() + if (to.path === '/500') { + return true + } //1.判断token if (basicStore.token) { if (to.path === '/login') { @@ -36,7 +39,7 @@ router.beforeEach(async (to) => { console.error(`route permission error${e}`) basicStore.resetState() progressClose() - return `/login?redirect=${to.path}` + return `/500?redirect=${to.path}` } } else { return true diff --git a/src/router/index.ts b/src/router/index.ts index 36c0e31..bfc5d92 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -19,6 +19,11 @@ export const constantRoutes: RouterTypes = [ component: () => import('@/views/error-page/401.vue'), hidden: true }, + { + path: '/500', + component: () => import('@/views/error-page/500.vue'), + hidden: true + }, { path: '/', component: Layout, diff --git a/src/utils/common-util.ts b/src/utils/common-util.ts index 4c7bb0e..5b69995 100644 --- a/src/utils/common-util.ts +++ b/src/utils/common-util.ts @@ -13,7 +13,7 @@ export function mobilePhone(str) { /* * 传入一串num四个 一个空格 * */ -export function toSplitNumFor(num, numToSpace) { +export function toSplitNumFor(num) { return num.replace(/(.{4})/g, '$1 ') } // 匹配银行卡号 diff --git a/src/utils/mock-axios-req.ts b/src/utils/mock-axios-req.ts index e6f0a40..bbad06d 100644 --- a/src/utils/mock-axios-req.ts +++ b/src/utils/mock-axios-req.ts @@ -46,6 +46,7 @@ service.interceptors.response.use( } }, (error) => { + // eslint-disable-next-line no-console console.log(`err${error}`) // for debug ElMessage({ message: error.ElMessage, diff --git a/src/utils/request.ts b/src/utils/request.ts index 76e5fb6..e3a7fac 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,6 +1,6 @@ import type { AxiosRequestConfig } from 'axios' import axios from 'axios' -import { ElMessage, ElMessageBox } from 'element-plus' +import { ElMessage } from 'element-plus' import { useBasicStore } from '@/store/basic' //使用axios.create()创建一个axios请求实例 @@ -31,6 +31,8 @@ service.interceptors.request.use( //请求后拦截 service.interceptors.response.use( (res) => { + const type = (res.headers['content-type'] as string) || '' + if (!type.startsWith('application/json')) return res.data const { code } = res.data const successCode = '0,200,20000' const noAuthCode = '401,403' @@ -38,30 +40,39 @@ service.interceptors.response.use( return res.data } else { if (noAuthCode.includes(code) && !location.href.includes('/login')) { - ElMessageBox.confirm('请重新登录', { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - }).then(() => { - useBasicStore().resetStateAndToLogin() - }) + useBasicStore().resetStateAndToLogin() } - return Promise.reject(res.data) + return Promise.reject(new Error(res.data?.msg ?? '未知异常')) } }, //响应报错 (err) => { - ElMessage.error({ - message: err, - duration: 2 * 1000 - }) + const { response } = err + if (response?.status === 401) { + useBasicStore().resetStateAndToLogin() + } else { + const { msg } = response?.data ?? { msg: '未知异常' } + ElMessage.error({ + message: msg || err, + duration: 2 * 1000 + }) + } return Promise.reject(err) } ) + +export const baseUrl: string = (() => { + let port = import.meta.env.VITE_APP_BASE_URL + if (/:\d{1,5}/.test(port)) port = port.match(/(?:\d{1,5})/)?.groups?.port ?? '' + else port = `:${location.port}` + return `${location.protocol}//${location.hostname}${port}` +})() + //导出service实例给页面调用 , config->页面的配置 export default function request(config: AxiosRequestConfig) { return service({ - baseURL: import.meta.env.VITE_APP_BASE_URL, + //baseURL: import.meta.env.VITE_APP_BASE_URL, + baseURL: baseUrl, timeout: 8000, ...config }) diff --git a/src/utils/validate.ts b/src/utils/validate.ts index de01d6d..f79fa3c 100644 --- a/src/utils/validate.ts +++ b/src/utils/validate.ts @@ -42,8 +42,7 @@ export function isName(value) { * @returns {boolean} */ export function isIP(ip) { - const reg = - /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/ + const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/ return reg.test(ip) } @@ -53,8 +52,7 @@ export function isIP(ip) { * @returns {boolean} */ export function isUrl(url) { - const reg = - /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ return reg.test(url) } @@ -124,8 +122,7 @@ export function isObject(arg) { * @returns {boolean} */ export function isPort(str) { - const reg = - /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/ + const reg = /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/ return reg.test(str) } @@ -145,8 +142,7 @@ export function isPhone(str) { * @returns {boolean} */ export function isIdCard(str) { - const reg = - /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/ + const reg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/ return reg.test(str) } @@ -176,13 +172,7 @@ export function isChina(str) { * @returns {boolean} */ export function isBlank(str) { - return ( - str == null || - false || - str === '' || - str.trim() === '' || - str.toLocaleLowerCase().trim() === 'null' - ) + return str == null || false || str === '' || str.trim() === '' || str.toLocaleLowerCase().trim() === 'null' } /** @@ -191,8 +181,7 @@ export function isBlank(str) { * @returns {boolean} */ export function isTel(str) { - const reg = - /^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))?$/ + const reg = /^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))?$/ return reg.test(str) } @@ -210,14 +199,14 @@ export function isNum(str) { * @param cid 18为的身份证号码 * @return Boolean 是否有效 **/ -export function isIdentityNumber(cid) { +export function isIdentityNumber(cid: string) { const arrExp = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] //加权因子 const arrValid = '1 0 X 9 8 7 6 5 4 3 2'.split(' ') //校检码 if (/^\d{17}\d|x$/i.test(cid)) { let sum = 0 for (let i = 0; i < cid.length - 1; i++) { // 对前17位数字与权值乘积求和 - sum += Number.parseInt(cid.substr(i, 1), 10) * arrExp[i] + sum += Number.parseInt(cid.slice(i, i + 1), 10) * arrExp[i] } // 计算模(固定算法) const idx = sum % 11 @@ -253,7 +242,7 @@ export class ElValidate { validate.push({ required: true, trigger: 'blur', - message: isString(canEmpty) ? canEmpty : '请输入文本', + message: isString(canEmpty) ? canEmpty : '请输入文本' }) return validate } @@ -268,11 +257,11 @@ export class ElValidate { { trigger: 'blur', message: '请输入有效的手机号', - validator (rule, value, callback) { + validator(rule, value, callback) { if (/^1[3456789]\d{9}$/g.test(value)) callback() else callback(new Error('无效的手机号')) - }, - }, + } + } ]) } @@ -285,14 +274,14 @@ export class ElValidate { { trigger: 'blur', message: '请输入有效的身份证号', - validator (rule, value, callback) { + validator(rule, value, callback) { if (isIdentityNumber(value)) { callback() } else { callback(new Error('无效的身份证号')) } - }, - }, + } + } ]) } @@ -311,7 +300,7 @@ export class ElValidate { { trigger: 'change', message: lint, - validator (rule, value, callback) { + validator(rule, value, callback) { if (value.length < min) { callback(new Error(`输入文本太短,最少长度为${min}`)) return @@ -321,8 +310,8 @@ export class ElValidate { return } callback() - }, - }, + } + } ]) } diff --git a/src/views/error-page/500.vue b/src/views/error-page/500.vue new file mode 100644 index 0000000..a725343 --- /dev/null +++ b/src/views/error-page/500.vue @@ -0,0 +1,237 @@ + + + + +