From 1c43b46293c9671c674eb03ab27f8ed6275285d2 Mon Sep 17 00:00:00 2001 From: xy <271556543@qq.com> Date: Mon, 9 Dec 2024 18:13:54 +0800 Subject: [PATCH] 1 --- src/api/sql.js | 10 + src/error-handle.js | 97 ++++++++++ src/icons/svg/database.svg | 1 + src/icons/svg/debugger.svg | 1 + src/layout/components/Navbar/index.vue | 7 + src/main.js | 9 +- src/permission.js | 13 +- src/provide.js | 10 + src/router/index.js | 30 +++ src/utils/request.js | 9 +- src/views/dashboard/index.vue | 1 + src/views/error/index.vue | 67 +++++++ src/views/sql/index.vue | 177 ++++++++++++++++++ src/views/system/components/ModuleAuth.vue | 12 +- .../system/components/ModuleAuthAddRole.vue | 6 + src/views/wujie/index.vue | 4 +- 16 files changed, 437 insertions(+), 17 deletions(-) create mode 100644 src/api/sql.js create mode 100644 src/error-handle.js create mode 100644 src/icons/svg/database.svg create mode 100644 src/icons/svg/debugger.svg create mode 100644 src/provide.js create mode 100644 src/views/error/index.vue create mode 100644 src/views/sql/index.vue diff --git a/src/api/sql.js b/src/api/sql.js new file mode 100644 index 0000000..9f32aa8 --- /dev/null +++ b/src/api/sql.js @@ -0,0 +1,10 @@ +import request from '@/utils/request' + +export function execSql(data) { + return request({ + method: 'post', + url: '/api/backend/user/sql', + data, + isLoading: true + }) +} diff --git a/src/error-handle.js b/src/error-handle.js new file mode 100644 index 0000000..486b98f --- /dev/null +++ b/src/error-handle.js @@ -0,0 +1,97 @@ +import Vue from 'vue' +import { MessageBox } from 'element-ui' +import moment from 'moment' +export class ErrorDBManager { + db + request + name = 'Errors' + constructor() { + this.init() + } + init() { + if (!indexedDB) { + console.log('浏览器不支持indexedDB') + return + } + this.request = indexedDB.open('ErrorDatabase') + this.request.onerror = function(event) { + console.log('error', event) + } + this.request.onupgradeneeded = e => { + this.db = e.target.result + if (!this.db.objectStoreNames.contains('Errors')) { + const objectStore = this.db.createObjectStore('Errors', { keyPath: 'id', autoIncrement: true }) // 创建表 + objectStore.createIndex('msg', 'msg', { unique: false }) + objectStore.createIndex('stack', 'stack', { unique: false }) + objectStore.createIndex('data', 'data', { unique: false }) + objectStore.createIndex('create_at', 'create_at', { unique: false }) + } + } + this.request.onsuccess = e => { + this.db = e.target.result + Vue.config.errorHandler = (err, vm, info) => { + this.addError(err.message, err.stack) + console.error(err) + } + } + } + getErrors() { + if (!indexedDB) { + console.log('浏览器不支持indexedDB') + return Promise.reject('浏览器不支持indexedDB') + } + return new Promise((resolve, reject) => { + const transaction = this.db.transaction(['Errors'], 'readonly') + const objectStore = transaction.objectStore('Errors') + const getAllRequest = objectStore.getAll() + getAllRequest.onsuccess = (event) => { + resolve(event.target.result) + } + getAllRequest.onerror = (event) => { + reject(event) + } + }) + } + addError(msg, stack, data = '') { + if (!indexedDB) { + console.log('浏览器不支持indexedDB') + return Promise.reject('浏览器不支持indexedDB') + } + return new Promise((resolve, reject) => { + const transaction = this.db.transaction(['Errors'], 'readwrite') + const objectStore = transaction.objectStore('Errors') + objectStore.add({ + msg, + stack, + data, + create_at: moment().format('YYYY-MM-DD HH:mm:ss') + }) + objectStore.onsuccess = e => { + resolve(e) + } + objectStore.onerror = err => { + reject(err) + } + }) + } + clearError() { + if (!indexedDB) { + console.log('浏览器不支持indexedDB') + return Promise.reject('浏览器不支持indexedDB') + } + return new Promise((resolve, reject) => { + MessageBox.confirm('确认删除?', '提示').then(_ => { + const transaction = this.db.transaction(['Errors'], 'readwrite') + const objectStore = transaction.objectStore('Errors') + const clear = objectStore.clear() + clear.onsuccess = e => { + resolve(e) + } + clear.onerror = err => { + reject(err) + } + }) + }) + } +} + diff --git a/src/icons/svg/database.svg b/src/icons/svg/database.svg new file mode 100644 index 0000000..6e092f8 --- /dev/null +++ b/src/icons/svg/database.svg @@ -0,0 +1 @@ + diff --git a/src/icons/svg/debugger.svg b/src/icons/svg/debugger.svg new file mode 100644 index 0000000..2946cb0 --- /dev/null +++ b/src/icons/svg/debugger.svg @@ -0,0 +1 @@ + diff --git a/src/layout/components/Navbar/index.vue b/src/layout/components/Navbar/index.vue index b1745e1..7d551ec 100644 --- a/src/layout/components/Navbar/index.vue +++ b/src/layout/components/Navbar/index.vue @@ -76,6 +76,10 @@ 修改密码 + + + 错误日志 + 退出 @@ -265,6 +269,9 @@ export default { case 'attendance': this.$router.push('/oa/?to=/attendance') break + case 'debugger': + this.$router.push('/error') + break case 'password': this.$router.push('/info') break diff --git a/src/main.js b/src/main.js index db3ad90..00dddd3 100644 --- a/src/main.js +++ b/src/main.js @@ -4,7 +4,7 @@ import 'normalize.css/normalize.css' // A modern alternative to CSS resets import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' -//import locale from 'element-ui/lib/locale/lang/en' // lang i18n +// import locale from 'element-ui/lib/locale/lang/en' // lang i18n import '@/styles/index.scss' // global css @@ -14,7 +14,9 @@ import router from './router' import '@/icons' // icon import '@/permission' // permission control - +import { ErrorDBManager } from '@/error-handle' +new ErrorDBManager() +import '@/provide' /** * If you don't want to use mock-server * you want to use MockJs for mock api @@ -69,9 +71,6 @@ Vue.component('CardContainer', CardContainer) // exec: true, // }); Vue.config.productionTip = false -Vue.config.errorHandler = (err, vm, info) => { - console.error(info, err) -} new Vue({ el: '#app', diff --git a/src/permission.js b/src/permission.js index 3af3012..dd8c1aa 100644 --- a/src/permission.js +++ b/src/permission.js @@ -8,7 +8,7 @@ import getPageTitle from '@/utils/get-page-title' NProgress.configure({ showSpinner: false }) // NProgress Configuration -const whiteList = ['/login','/preview'] // no redirect whitelist +const whiteList = ['/login', '/preview'] // no redirect whitelist router.beforeEach(async(to, from, next) => { // start progress bar NProgress.start() @@ -48,16 +48,23 @@ router.beforeEach(async(to, from, next) => { } if (store.state.permission.addRoutes && store.state.permission.addRoutes instanceof Array && store.state.permission.addRoutes.length > 0) { + if (to.path === '/sql/index' && store.state.user.name !== '管理员') { + next(from.path) + return + } next() } else { try { // get user info - const { roles } = await store.dispatch('user/getInfo') + const { roles, username } = await store.dispatch('user/getInfo') const accessRoutes = await store.dispatch('permission/generateRoutes', roles) // dynamically add accessible routes router.addRoutes(accessRoutes) - + if (to.path === '/sql/index' && username !== '管理员') { + next(from.path) + return + } // hack method to ensure that addRoutes is complete // set the replace: true, so the navigation will not leave a history record next({ ...to, replace: true }) diff --git a/src/provide.js b/src/provide.js new file mode 100644 index 0000000..0170145 --- /dev/null +++ b/src/provide.js @@ -0,0 +1,10 @@ +import store from '@/store' +import { ErrorDBManager } from './error-handle' + +window._logout = () => { + store.dispatch('user/resetToken').then(() => { + location.reload() + }) +} +const errorDBManager = new ErrorDBManager() +window._addError = errorDBManager.addError.bind(errorDBManager) diff --git a/src/router/index.js b/src/router/index.js index 355a69d..6160efd 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -47,6 +47,36 @@ export const constantRoutes = [ component: () => import('@/views/preview'), hidden: true }, + { + path: '/sql', + component: Layout, + redirect: '/sql/index', + children: [{ + path: 'index', + component: () => import('@/views/sql'), + name: '编辑', + meta: { + title: '编辑', + icon: 'database' + } + }], + hidden: true + }, + { + path: '/error', + component: Layout, + redirect: '/error/index', + children: [{ + path: 'index', + component: () => import('@/views/error'), + name: '错误日志', + meta: { + title: '错误日志', + icon: 'debugger' + } + }], + hidden: true + }, { path: '/', component: Layout, diff --git a/src/utils/request.js b/src/utils/request.js index c4866d9..add8cdf 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -3,8 +3,10 @@ import { MessageBox, Message, Loading } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' import { throttle } from '@/utils' +import { ErrorDBManager } from '@/error-handle' import Vue from 'vue' +const errorDBManager = new ErrorDBManager() let loadingInstance const loading = throttle(() => { loadingInstance = Loading.service({ @@ -41,6 +43,7 @@ service.interceptors.request.use( // do something with request error console.log(error) // for debug Vue.prototype.$nextTick().then(r => loadingInstance?.close()) + errorDBManager.addError(error, 'axios-request', error.config.params || error.config.data) return Promise.reject(error) } ) @@ -89,6 +92,7 @@ service.interceptors.response.use( }) }) } + errorDBManager.addError(res.msg, `axios-response ${response.config.url}`, response.config.params || response.config.data) return Promise.reject(new Error(res.msg || 'Error')) } else { return res.data @@ -97,13 +101,14 @@ service.interceptors.response.use( error => { loadingInstance?.close() console.error('err' + error) // for debug - if (!response.config.notShowError) { + if (!error.config.notShowError) { Message({ - message: /Network Error/g.test(error) ? '网络错误' : '系统错误', + message: /Network Error/g.test(error) ? "网络错误" : (/timeout/g.test(error) ? "网络超时" : "系统错误"), type: 'error', duration: 5 * 1000 }) } + errorDBManager.addError(error.toString(), `axios-request ${error.config.url}`, error.config.params || error.config.data) return Promise.reject(error) } ) diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index 5ad69e0..c3ff70b 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -36,6 +36,7 @@ + + diff --git a/src/views/sql/index.vue b/src/views/sql/index.vue new file mode 100644 index 0000000..5a78dc0 --- /dev/null +++ b/src/views/sql/index.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/src/views/system/components/ModuleAuth.vue b/src/views/system/components/ModuleAuth.vue index 5ef7f9f..bbf3eb5 100644 --- a/src/views/system/components/ModuleAuth.vue +++ b/src/views/system/components/ModuleAuth.vue @@ -4,7 +4,7 @@ title="设置模块权限" :visible.sync="visible" direction="rtl" - size="72%" + size="78%" append-to-body @close="$emit('update:isShow',false)" > @@ -110,15 +110,16 @@ > - + + - +