diff --git a/ruoyi-ui/src/layout/mixin/ResizeHandler.js b/ruoyi-ui/src/layout/mixin/ResizeHandler.js
index b3fc8b2..e8d0df8 100644
--- a/ruoyi-ui/src/layout/mixin/ResizeHandler.js
+++ b/ruoyi-ui/src/layout/mixin/ResizeHandler.js
@@ -1,45 +1,45 @@
-import store from '@/store'
-
-const { body } = document
-const WIDTH = 992 // refer to Bootstrap's responsive design
-
-export default {
- watch: {
- $route(route) {
- if (this.device === 'mobile' && this.sidebar.opened) {
- store.dispatch('app/closeSideBar', { withoutAnimation: false })
- }
- }
- },
- beforeMount() {
- window.addEventListener('resize', this.$_resizeHandler)
- },
- beforeDestroy() {
- window.removeEventListener('resize', this.$_resizeHandler)
- },
- mounted() {
- const isMobile = this.$_isMobile()
- if (isMobile) {
- store.dispatch('app/toggleDevice', 'mobile')
- store.dispatch('app/closeSideBar', { withoutAnimation: true })
- }
- },
- methods: {
- // use $_ for mixins properties
- // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
- $_isMobile() {
- const rect = body.getBoundingClientRect()
- return rect.width - 1 < WIDTH
- },
- $_resizeHandler() {
- if (!document.hidden) {
- const isMobile = this.$_isMobile()
- store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
-
- if (isMobile) {
- store.dispatch('app/closeSideBar', { withoutAnimation: true })
- }
- }
- }
- }
-}
+import store from '@/store'
+
+const { body } = document
+const WIDTH = 992 // refer to Bootstrap's responsive design
+
+export default {
+ watch: {
+ $route(route) {
+ if (this.device === 'mobile' && this.sidebar.opened) {
+ store.dispatch('app/closeSideBar', { withoutAnimation: false })
+ }
+ }
+ },
+ beforeMount() {
+ window.addEventListener('resize', this.$_resizeHandler)
+ },
+ beforeDestroy() {
+ window.removeEventListener('resize', this.$_resizeHandler)
+ },
+ mounted() {
+ const isMobile = this.$_isMobile()
+ if (isMobile) {
+ store.dispatch('app/toggleDevice', 'mobile')
+ store.dispatch('app/closeSideBar', { withoutAnimation: true })
+ }
+ },
+ methods: {
+ // use $_ for mixins properties
+ // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+ $_isMobile() {
+ const rect = body.getBoundingClientRect()
+ return rect.width - 1 < WIDTH
+ },
+ $_resizeHandler() {
+ if (!document.hidden) {
+ const isMobile = this.$_isMobile()
+ store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
+
+ if (isMobile) {
+ store.dispatch('app/closeSideBar', { withoutAnimation: true })
+ }
+ }
+ }
+ }
+}
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index fab45df..da01750 100644
--- a/ruoyi-ui/src/main.js
+++ b/ruoyi-ui/src/main.js
@@ -1,83 +1,83 @@
-import Vue from 'vue'
-
-import Cookies from 'js-cookie'
-
-import Element from 'element-ui'
-import './assets/styles/element-variables.scss'
-
-import '@/assets/styles/index.scss' // global css
-import '@/assets/styles/ruoyi.scss' // ruoyi css
-import App from './App'
-import store from './store'
-import router from './router'
-import directive from './directive' // directive
-import plugins from './plugins' // plugins
-import { download } from '@/utils/request'
-
-import './assets/icons' // icon
-import './permission' // permission control
-import { getDicts } from "@/api/system/dict/data"
-import { getConfigKey } from "@/api/system/config"
-import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"
-// 分页组件
-import Pagination from "@/components/Pagination"
-// 自定义表格工具组件
-import RightToolbar from "@/components/RightToolbar"
-// 富文本组件
-import Editor from "@/components/Editor"
-// 文件上传组件
-import FileUpload from "@/components/FileUpload"
-// 图片上传组件
-import ImageUpload from "@/components/ImageUpload"
-// 图片预览组件
-import ImagePreview from "@/components/ImagePreview"
-// 字典标签组件
-import DictTag from '@/components/DictTag'
-// 字典数据组件
-import DictData from '@/components/DictData'
-
-// 全局方法挂载
-Vue.prototype.getDicts = getDicts
-Vue.prototype.getConfigKey = getConfigKey
-Vue.prototype.parseTime = parseTime
-Vue.prototype.resetForm = resetForm
-Vue.prototype.addDateRange = addDateRange
-Vue.prototype.selectDictLabel = selectDictLabel
-Vue.prototype.selectDictLabels = selectDictLabels
-Vue.prototype.download = download
-Vue.prototype.handleTree = handleTree
-
-// 全局组件挂载
-Vue.component('DictTag', DictTag)
-Vue.component('Pagination', Pagination)
-Vue.component('RightToolbar', RightToolbar)
-Vue.component('Editor', Editor)
-Vue.component('FileUpload', FileUpload)
-Vue.component('ImageUpload', ImageUpload)
-Vue.component('ImagePreview', ImagePreview)
-
-Vue.use(directive)
-Vue.use(plugins)
-DictData.install()
-
-/**
- * If you don't want to use mock-server
- * you want to use MockJs for mock api
- * you can execute: mockXHR()
- *
- * Currently MockJs will be used in the production environment,
- * please remove it before going online! ! !
- */
-
-Vue.use(Element, {
- size: Cookies.get('size') || 'medium' // set element-ui default size
-})
-
-Vue.config.productionTip = false
-
-new Vue({
- el: '#app',
- router,
- store,
- render: h => h(App)
-})
+import Vue from 'vue'
+
+import Cookies from 'js-cookie'
+
+import Element from 'element-ui'
+import './assets/styles/element-variables.scss'
+
+import '@/assets/styles/index.scss' // global css
+import '@/assets/styles/ruoyi.scss' // ruoyi css
+import App from './App'
+import store from './store'
+import router from './router'
+import directive from './directive' // directive
+import plugins from './plugins' // plugins
+import { download } from '@/utils/request'
+
+import './assets/icons' // icon
+import './permission' // permission control
+import { getDicts } from "@/api/system/dict/data"
+import { getConfigKey } from "@/api/system/config"
+import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"
+// 分页组件
+import Pagination from "@/components/Pagination"
+// 自定义表格工具组件
+import RightToolbar from "@/components/RightToolbar"
+// 富文本组件
+import Editor from "@/components/Editor"
+// 文件上传组件
+import FileUpload from "@/components/FileUpload"
+// 图片上传组件
+import ImageUpload from "@/components/ImageUpload"
+// 图片预览组件
+import ImagePreview from "@/components/ImagePreview"
+// 字典标签组件
+import DictTag from '@/components/DictTag'
+// 字典数据组件
+import DictData from '@/components/DictData'
+
+// 全局方法挂载
+Vue.prototype.getDicts = getDicts
+Vue.prototype.getConfigKey = getConfigKey
+Vue.prototype.parseTime = parseTime
+Vue.prototype.resetForm = resetForm
+Vue.prototype.addDateRange = addDateRange
+Vue.prototype.selectDictLabel = selectDictLabel
+Vue.prototype.selectDictLabels = selectDictLabels
+Vue.prototype.download = download
+Vue.prototype.handleTree = handleTree
+
+// 全局组件挂载
+Vue.component('DictTag', DictTag)
+Vue.component('Pagination', Pagination)
+Vue.component('RightToolbar', RightToolbar)
+Vue.component('Editor', Editor)
+Vue.component('FileUpload', FileUpload)
+Vue.component('ImageUpload', ImageUpload)
+Vue.component('ImagePreview', ImagePreview)
+
+Vue.use(directive)
+Vue.use(plugins)
+DictData.install()
+
+/**
+ * If you don't want to use mock-server
+ * you want to use MockJs for mock api
+ * you can execute: mockXHR()
+ *
+ * Currently MockJs will be used in the production environment,
+ * please remove it before going online! ! !
+ */
+
+Vue.use(Element, {
+ size: Cookies.get('size') || 'medium' // set element-ui default size
+})
+
+Vue.config.productionTip = false
+
+new Vue({
+ el: '#app',
+ router,
+ store,
+ render: h => h(App)
+})
diff --git a/ruoyi-ui/src/permission.js b/ruoyi-ui/src/permission.js
index b818358..b66190b 100644
--- a/ruoyi-ui/src/permission.js
+++ b/ruoyi-ui/src/permission.js
@@ -19,19 +19,12 @@ router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
- const isLock = store.getters.isLock
/* has token*/
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else if (isWhiteList(to.path)) {
next()
- } else if (isLock && to.path !== '/lock') {
- next({ path: '/lock' })
- NProgress.done()
- } else if (!isLock && to.path === '/lock') {
- next({ path: '/' })
- NProgress.done()
} else {
if (store.getters.roles.length === 0) {
isRelogin.show = true
diff --git a/ruoyi-ui/src/plugins/auth.js b/ruoyi-ui/src/plugins/auth.js
index 6bcce3f..3b91c14 100644
--- a/ruoyi-ui/src/plugins/auth.js
+++ b/ruoyi-ui/src/plugins/auth.js
@@ -1,60 +1,60 @@
-import store from '@/store'
-
-function authPermission(permission) {
- const all_permission = "*:*:*"
- const permissions = store.getters && store.getters.permissions
- if (permission && permission.length > 0) {
- return permissions.some(v => {
- return all_permission === v || v === permission
- })
- } else {
- return false
- }
-}
-
-function authRole(role) {
- const super_admin = "admin"
- const roles = store.getters && store.getters.roles
- if (role && role.length > 0) {
- return roles.some(v => {
- return super_admin === v || v === role
- })
- } else {
- return false
- }
-}
-
-export default {
- // 验证用户是否具备某权限
- hasPermi(permission) {
- return authPermission(permission)
- },
- // 验证用户是否含有指定权限,只需包含其中一个
- hasPermiOr(permissions) {
- return permissions.some(item => {
- return authPermission(item)
- })
- },
- // 验证用户是否含有指定权限,必须全部拥有
- hasPermiAnd(permissions) {
- return permissions.every(item => {
- return authPermission(item)
- })
- },
- // 验证用户是否具备某角色
- hasRole(role) {
- return authRole(role)
- },
- // 验证用户是否含有指定角色,只需包含其中一个
- hasRoleOr(roles) {
- return roles.some(item => {
- return authRole(item)
- })
- },
- // 验证用户是否含有指定角色,必须全部拥有
- hasRoleAnd(roles) {
- return roles.every(item => {
- return authRole(item)
- })
- }
-}
+import store from '@/store'
+
+function authPermission(permission) {
+ const all_permission = "*:*:*"
+ const permissions = store.getters && store.getters.permissions
+ if (permission && permission.length > 0) {
+ return permissions.some(v => {
+ return all_permission === v || v === permission
+ })
+ } else {
+ return false
+ }
+}
+
+function authRole(role) {
+ const super_admin = "admin"
+ const roles = store.getters && store.getters.roles
+ if (role && role.length > 0) {
+ return roles.some(v => {
+ return super_admin === v || v === role
+ })
+ } else {
+ return false
+ }
+}
+
+export default {
+ // 验证用户是否具备某权限
+ hasPermi(permission) {
+ return authPermission(permission)
+ },
+ // 验证用户是否含有指定权限,只需包含其中一个
+ hasPermiOr(permissions) {
+ return permissions.some(item => {
+ return authPermission(item)
+ })
+ },
+ // 验证用户是否含有指定权限,必须全部拥有
+ hasPermiAnd(permissions) {
+ return permissions.every(item => {
+ return authPermission(item)
+ })
+ },
+ // 验证用户是否具备某角色
+ hasRole(role) {
+ return authRole(role)
+ },
+ // 验证用户是否含有指定角色,只需包含其中一个
+ hasRoleOr(roles) {
+ return roles.some(item => {
+ return authRole(item)
+ })
+ },
+ // 验证用户是否含有指定角色,必须全部拥有
+ hasRoleAnd(roles) {
+ return roles.every(item => {
+ return authRole(item)
+ })
+ }
+}
diff --git a/ruoyi-ui/src/plugins/cache.js b/ruoyi-ui/src/plugins/cache.js
index 4d29dfe..ea8a53f 100644
--- a/ruoyi-ui/src/plugins/cache.js
+++ b/ruoyi-ui/src/plugins/cache.js
@@ -1,79 +1,79 @@
-const sessionCache = {
- set (key, value) {
- if (!sessionStorage) {
- return
- }
- if (key != null && value != null) {
- sessionStorage.setItem(key, value)
- }
- },
- get (key) {
- if (!sessionStorage) {
- return null
- }
- if (key == null) {
- return null
- }
- return sessionStorage.getItem(key)
- },
- setJSON (key, jsonValue) {
- if (jsonValue != null) {
- this.set(key, JSON.stringify(jsonValue))
- }
- },
- getJSON (key) {
- const value = this.get(key)
- if (value != null) {
- return JSON.parse(value)
- }
- return null
- },
- remove (key) {
- sessionStorage.removeItem(key)
- }
-}
-const localCache = {
- set (key, value) {
- if (!localStorage) {
- return
- }
- if (key != null && value != null) {
- localStorage.setItem(key, value)
- }
- },
- get (key) {
- if (!localStorage) {
- return null
- }
- if (key == null) {
- return null
- }
- return localStorage.getItem(key)
- },
- setJSON (key, jsonValue) {
- if (jsonValue != null) {
- this.set(key, JSON.stringify(jsonValue))
- }
- },
- getJSON (key) {
- const value = this.get(key)
- if (value != null) {
- return JSON.parse(value)
- }
- return null
- },
- remove (key) {
- localStorage.removeItem(key)
- }
-}
-
-export default {
- /**
- * 会话级缓存
- */
- session: sessionCache,
- /**
- * 本地缓存
- */
- local: localCache
-}
+const sessionCache = {
+ set (key, value) {
+ if (!sessionStorage) {
+ return
+ }
+ if (key != null && value != null) {
+ sessionStorage.setItem(key, value)
+ }
+ },
+ get (key) {
+ if (!sessionStorage) {
+ return null
+ }
+ if (key == null) {
+ return null
+ }
+ return sessionStorage.getItem(key)
+ },
+ setJSON (key, jsonValue) {
+ if (jsonValue != null) {
+ this.set(key, JSON.stringify(jsonValue))
+ }
+ },
+ getJSON (key) {
+ const value = this.get(key)
+ if (value != null) {
+ return JSON.parse(value)
+ }
+ return null
+ },
+ remove (key) {
+ sessionStorage.removeItem(key)
+ }
+}
+const localCache = {
+ set (key, value) {
+ if (!localStorage) {
+ return
+ }
+ if (key != null && value != null) {
+ localStorage.setItem(key, value)
+ }
+ },
+ get (key) {
+ if (!localStorage) {
+ return null
+ }
+ if (key == null) {
+ return null
+ }
+ return localStorage.getItem(key)
+ },
+ setJSON (key, jsonValue) {
+ if (jsonValue != null) {
+ this.set(key, JSON.stringify(jsonValue))
+ }
+ },
+ getJSON (key) {
+ const value = this.get(key)
+ if (value != null) {
+ return JSON.parse(value)
+ }
+ return null
+ },
+ remove (key) {
+ localStorage.removeItem(key)
+ }
+}
+
+export default {
+ /**
+ * 会话级缓存
+ */
+ session: sessionCache,
+ /**
+ * 本地缓存
+ */
+ local: localCache
+}
diff --git a/ruoyi-ui/src/plugins/index.js b/ruoyi-ui/src/plugins/index.js
index 9bc6eac..d000f2d 100644
--- a/ruoyi-ui/src/plugins/index.js
+++ b/ruoyi-ui/src/plugins/index.js
@@ -1,20 +1,20 @@
-import tab from './tab'
-import auth from './auth'
-import cache from './cache'
-import modal from './modal'
-import download from './download'
-
-export default {
- install(Vue) {
- // 页签操作
- Vue.prototype.$tab = tab
- // 认证对象
- Vue.prototype.$auth = auth
- // 缓存对象
- Vue.prototype.$cache = cache
- // 模态框对象
- Vue.prototype.$modal = modal
- // 下载文件
- Vue.prototype.$download = download
- }
-}
+import tab from './tab'
+import auth from './auth'
+import cache from './cache'
+import modal from './modal'
+import download from './download'
+
+export default {
+ install(Vue) {
+ // 页签操作
+ Vue.prototype.$tab = tab
+ // 认证对象
+ Vue.prototype.$auth = auth
+ // 缓存对象
+ Vue.prototype.$cache = cache
+ // 模态框对象
+ Vue.prototype.$modal = modal
+ // 下载文件
+ Vue.prototype.$download = download
+ }
+}
diff --git a/ruoyi-ui/src/plugins/modal.js b/ruoyi-ui/src/plugins/modal.js
index 99cea2e..92bc1ef 100644
--- a/ruoyi-ui/src/plugins/modal.js
+++ b/ruoyi-ui/src/plugins/modal.js
@@ -1,83 +1,83 @@
-import { Message, MessageBox, Notification, Loading } from 'element-ui'
-
-let loadingInstance
-
-export default {
- // 消息提示
- msg(content) {
- Message.info(content)
- },
- // 错误消息
- msgError(content) {
- Message.error(content)
- },
- // 成功消息
- msgSuccess(content) {
- Message.success(content)
- },
- // 警告消息
- msgWarning(content) {
- Message.warning(content)
- },
- // 弹出提示
- alert(content) {
- MessageBox.alert(content, "系统提示")
- },
- // 错误提示
- alertError(content) {
- MessageBox.alert(content, "系统提示", { type: 'error' })
- },
- // 成功提示
- alertSuccess(content) {
- MessageBox.alert(content, "系统提示", { type: 'success' })
- },
- // 警告提示
- alertWarning(content) {
- MessageBox.alert(content, "系统提示", { type: 'warning' })
- },
- // 通知提示
- notify(content) {
- Notification.info(content)
- },
- // 错误通知
- notifyError(content) {
- Notification.error(content)
- },
- // 成功通知
- notifySuccess(content) {
- Notification.success(content)
- },
- // 警告通知
- notifyWarning(content) {
- Notification.warning(content)
- },
- // 确认窗体
- confirm(content) {
- return MessageBox.confirm(content, "系统提示", {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: "warning",
- })
- },
- // 提交内容
- prompt(content) {
- return MessageBox.prompt(content, "系统提示", {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: "warning",
- })
- },
- // 打开遮罩层
- loading(content) {
- loadingInstance = Loading.service({
- lock: true,
- text: content,
- spinner: "el-icon-loading",
- background: "rgba(0, 0, 0, 0.7)",
- })
- },
- // 关闭遮罩层
- closeLoading() {
- loadingInstance.close()
- }
-}
+import { Message, MessageBox, Notification, Loading } from 'element-ui'
+
+let loadingInstance
+
+export default {
+ // 消息提示
+ msg(content) {
+ Message.info(content)
+ },
+ // 错误消息
+ msgError(content) {
+ Message.error(content)
+ },
+ // 成功消息
+ msgSuccess(content) {
+ Message.success(content)
+ },
+ // 警告消息
+ msgWarning(content) {
+ Message.warning(content)
+ },
+ // 弹出提示
+ alert(content) {
+ MessageBox.alert(content, "系统提示")
+ },
+ // 错误提示
+ alertError(content) {
+ MessageBox.alert(content, "系统提示", { type: 'error' })
+ },
+ // 成功提示
+ alertSuccess(content) {
+ MessageBox.alert(content, "系统提示", { type: 'success' })
+ },
+ // 警告提示
+ alertWarning(content) {
+ MessageBox.alert(content, "系统提示", { type: 'warning' })
+ },
+ // 通知提示
+ notify(content) {
+ Notification.info(content)
+ },
+ // 错误通知
+ notifyError(content) {
+ Notification.error(content)
+ },
+ // 成功通知
+ notifySuccess(content) {
+ Notification.success(content)
+ },
+ // 警告通知
+ notifyWarning(content) {
+ Notification.warning(content)
+ },
+ // 确认窗体
+ confirm(content) {
+ return MessageBox.confirm(content, "系统提示", {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: "warning",
+ })
+ },
+ // 提交内容
+ prompt(content) {
+ return MessageBox.prompt(content, "系统提示", {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: "warning",
+ })
+ },
+ // 打开遮罩层
+ loading(content) {
+ loadingInstance = Loading.service({
+ lock: true,
+ text: content,
+ spinner: "el-icon-loading",
+ background: "rgba(0, 0, 0, 0.7)",
+ })
+ },
+ // 关闭遮罩层
+ closeLoading() {
+ loadingInstance.close()
+ }
+}
diff --git a/ruoyi-ui/src/plugins/tab.js b/ruoyi-ui/src/plugins/tab.js
index 9929de3..f21467d 100644
--- a/ruoyi-ui/src/plugins/tab.js
+++ b/ruoyi-ui/src/plugins/tab.js
@@ -1,75 +1,71 @@
-import store from '@/store'
-import router from '@/router'
-
-export default {
- // 刷新当前tab页签
- refreshPage(obj) {
- const { path, query, matched } = router.currentRoute
- // 防止在重定向过程中重复刷新
- if (path.startsWith('/redirect/')) {
- return Promise.resolve()
- }
- if (obj === undefined) {
- matched.forEach((m) => {
- if (m.components && m.components.default && m.components.default.name) {
- if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
- obj = { name: m.components.default.name, path: path, query: query }
- }
- }
- })
- }
- return store.dispatch('tagsView/delCachedView', obj).then(() => {
- const { path, query } = obj
- router.replace({
- path: '/redirect' + path,
- query: query
- })
- })
- },
- // 关闭当前tab页签,打开新页签
- closeOpenPage(obj) {
- store.dispatch("tagsView/delView", router.currentRoute)
- if (obj !== undefined) {
- return router.push(obj)
- }
- },
- // 关闭指定tab页签
- closePage(obj) {
- if (obj === undefined) {
- return store.dispatch('tagsView/delView', router.currentRoute).then(({ visitedViews }) => {
- const latestView = visitedViews.slice(-1)[0]
- if (latestView) {
- return router.push(latestView.fullPath)
- }
- return router.push('/')
- })
- }
- return store.dispatch('tagsView/delView', obj)
- },
- // 关闭所有tab页签
- closeAllPage() {
- return store.dispatch('tagsView/delAllViews')
- },
- // 关闭左侧tab页签
- closeLeftPage(obj) {
- return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute)
- },
- // 关闭右侧tab页签
- closeRightPage(obj) {
- return store.dispatch('tagsView/delRightTags', obj || router.currentRoute)
- },
- // 关闭其他tab页签
- closeOtherPage(obj) {
- return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute)
- },
- // 添加tab页签
- openPage(title, url, params) {
- const obj = { path: url, meta: { title: title } }
- store.dispatch('tagsView/addView', obj)
- return router.push({ path: url, query: params })
- },
- // 修改tab页签
- updatePage(obj) {
- return store.dispatch('tagsView/updateVisitedView', obj)
- }
-}
+import store from '@/store'
+import router from '@/router'
+
+export default {
+ // 刷新当前tab页签
+ refreshPage(obj) {
+ const { path, query, matched } = router.currentRoute
+ if (obj === undefined) {
+ matched.forEach((m) => {
+ if (m.components && m.components.default && m.components.default.name) {
+ if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
+ obj = { name: m.components.default.name, path: path, query: query }
+ }
+ }
+ })
+ }
+ return store.dispatch('tagsView/delCachedView', obj).then(() => {
+ const { path, query } = obj
+ router.replace({
+ path: '/redirect' + path,
+ query: query
+ })
+ })
+ },
+ // 关闭当前tab页签,打开新页签
+ closeOpenPage(obj) {
+ store.dispatch("tagsView/delView", router.currentRoute)
+ if (obj !== undefined) {
+ return router.push(obj)
+ }
+ },
+ // 关闭指定tab页签
+ closePage(obj) {
+ if (obj === undefined) {
+ return store.dispatch('tagsView/delView', router.currentRoute).then(({ visitedViews }) => {
+ const latestView = visitedViews.slice(-1)[0]
+ if (latestView) {
+ return router.push(latestView.fullPath)
+ }
+ return router.push('/')
+ })
+ }
+ return store.dispatch('tagsView/delView', obj)
+ },
+ // 关闭所有tab页签
+ closeAllPage() {
+ return store.dispatch('tagsView/delAllViews')
+ },
+ // 关闭左侧tab页签
+ closeLeftPage(obj) {
+ return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute)
+ },
+ // 关闭右侧tab页签
+ closeRightPage(obj) {
+ return store.dispatch('tagsView/delRightTags', obj || router.currentRoute)
+ },
+ // 关闭其他tab页签
+ closeOtherPage(obj) {
+ return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute)
+ },
+ // 添加tab页签
+ openPage(title, url, params) {
+ const obj = { path: url, meta: { title: title } }
+ store.dispatch('tagsView/addView', obj)
+ return router.push({ path: url, query: params })
+ },
+ // 修改tab页签
+ updatePage(obj) {
+ return store.dispatch('tagsView/updateVisitedView', obj)
+ }
+}
diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js
index 2dd6e79..42948c6 100644
--- a/ruoyi-ui/src/router/index.js
+++ b/ruoyi-ui/src/router/index.js
@@ -68,18 +68,12 @@ export const constantRoutes = [
children: [
{
path: 'index',
- component: () => import('@/views/index'),
- name: 'Index',
- meta: { title: '首页', icon: 'dashboard', affix: true }
+ component: () => import('@/views/loanPricing/workflow/index'),
+ name: 'LoanPricingWorkflow',
+ meta: { title: '流程列表', icon: 'dashboard', affix: true }
}
]
},
- {
- path: '/lock',
- component: () => import('@/views/lock'),
- hidden: true,
- meta: { title: '锁定屏幕' }
- },
{
path: '/user',
component: Layout,
@@ -167,6 +161,20 @@ export const dynamicRoutes = [
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
}
]
+ },
+ {
+ path: '/loanPricing/workflow-detail',
+ component: Layout,
+ hidden: true,
+ permissions: ['loanPricing:workflow:query'],
+ children: [
+ {
+ path: ':serialNum',
+ component: () => import('@/views/loanPricing/workflow/detail'),
+ name: 'LoanPricingWorkflowDetail',
+ meta: { title: '流程详情', activeMenu: '/loanPricing/workflow' }
+ }
+ ]
}
]
diff --git a/ruoyi-ui/src/settings.js b/ruoyi-ui/src/settings.js
index edfabf7..eb1efa8 100644
--- a/ruoyi-ui/src/settings.js
+++ b/ruoyi-ui/src/settings.js
@@ -1,66 +1,56 @@
-module.exports = {
- /**
- * 网页标题
- */
- title: process.env.VUE_APP_TITLE,
-
- /**
- * 侧边栏主题 深色主题theme-dark,浅色主题theme-light
- */
- sideTheme: 'theme-dark',
-
- /**
- * 系统布局配置
- */
- showSettings: true,
-
- /**
- * 菜单导航模式 1、纯左侧 2、混合(左侧+顶部) 3、纯顶部
- */
- navType: 1,
-
- /**
- * 是否显示 tagsView
- */
- tagsView: true,
-
- /**
- * 持久化标签页
- */
- tagsViewPersist: false,
-
- /**
- * 显示页签图标
- */
- tagsIcon: false,
-
- /**
- * 标签页样式:card 卡片(默认)、chrome 谷歌浏览器风格
- */
- tagsViewStyle: 'card',
-
- /**
- * 是否固定头部
- */
- fixedHeader: true,
-
- /**
- * 是否显示logo
- */
- sidebarLogo: true,
-
- /**
- * 是否显示动态标题
- */
- dynamicTitle: false,
-
- /**
- * 是否显示底部版权
- */
- footerVisible: false,
-
- /**
- * 底部版权文本内容
- */
- footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
-}
+module.exports = {
+ /**
+ * 网页标题
+ */
+ title: process.env.VUE_APP_TITLE,
+
+ /**
+ * 侧边栏主题 深色主题theme-dark,浅色主题theme-light
+ */
+ sideTheme: 'theme-dark',
+
+ /**
+ * 系统布局配置
+ */
+ showSettings: true,
+
+ /**
+ * 菜单导航模式 1、纯左侧 2、混合(左侧+顶部) 3、纯顶部
+ */
+ navType: 1,
+
+ /**
+ * 是否显示 tagsView
+ */
+ tagsView: true,
+
+ /**
+ * 显示页签图标
+ */
+ tagsIcon: false,
+
+ /**
+ * 是否固定头部
+ */
+ fixedHeader: true,
+
+ /**
+ * 是否显示logo
+ */
+ sidebarLogo: true,
+
+ /**
+ * 是否显示动态标题
+ */
+ dynamicTitle: false,
+
+ /**
+ * 是否显示底部版权
+ */
+ footerVisible: false,
+
+ /**
+ * 底部版权文本内容
+ */
+ footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
+}
diff --git a/ruoyi-ui/src/store/getters.js b/ruoyi-ui/src/store/getters.js
index 5545bb1..3680f95 100644
--- a/ruoyi-ui/src/store/getters.js
+++ b/ruoyi-ui/src/store/getters.js
@@ -1,23 +1,21 @@
-const getters = {
- sidebar: state => state.app.sidebar,
- size: state => state.app.size,
- device: state => state.app.device,
- dict: state => state.dict.dict,
- isLock: state => state.lock.isLock,
- lockPath: state => state.lock.lockPath,
- visitedViews: state => state.tagsView.visitedViews,
- cachedViews: state => state.tagsView.cachedViews,
- token: state => state.user.token,
- avatar: state => state.user.avatar,
- id: state => state.user.id,
- name: state => state.user.name,
- nickName: state => state.user.nickName,
- introduction: state => state.user.introduction,
- roles: state => state.user.roles,
- permissions: state => state.user.permissions,
- permission_routes: state => state.permission.routes,
- topbarRouters: state => state.permission.topbarRouters,
- defaultRoutes: state => state.permission.defaultRoutes,
- sidebarRouters: state => state.permission.sidebarRouters
-}
-export default getters
+const getters = {
+ sidebar: state => state.app.sidebar,
+ size: state => state.app.size,
+ device: state => state.app.device,
+ dict: state => state.dict.dict,
+ visitedViews: state => state.tagsView.visitedViews,
+ cachedViews: state => state.tagsView.cachedViews,
+ token: state => state.user.token,
+ avatar: state => state.user.avatar,
+ id: state => state.user.id,
+ name: state => state.user.name,
+ nickName: state => state.user.nickName,
+ introduction: state => state.user.introduction,
+ roles: state => state.user.roles,
+ permissions: state => state.user.permissions,
+ permission_routes: state => state.permission.routes,
+ topbarRouters: state => state.permission.topbarRouters,
+ defaultRoutes: state => state.permission.defaultRoutes,
+ sidebarRouters: state => state.permission.sidebarRouters
+}
+export default getters
diff --git a/ruoyi-ui/src/store/index.js b/ruoyi-ui/src/store/index.js
index 293f5d1..97aaef8 100644
--- a/ruoyi-ui/src/store/index.js
+++ b/ruoyi-ui/src/store/index.js
@@ -1,27 +1,25 @@
-import Vue from 'vue'
-import Vuex from 'vuex'
-import app from './modules/app'
-import lock from './modules/lock'
-import dict from './modules/dict'
-import user from './modules/user'
-import tagsView from './modules/tagsView'
-import permission from './modules/permission'
-import settings from './modules/settings'
-import getters from './getters'
-
-Vue.use(Vuex)
-
-const store = new Vuex.Store({
- modules: {
- app,
- lock,
- dict,
- user,
- tagsView,
- permission,
- settings
- },
- getters
-})
-
-export default store
+import Vue from 'vue'
+import Vuex from 'vuex'
+import app from './modules/app'
+import dict from './modules/dict'
+import user from './modules/user'
+import tagsView from './modules/tagsView'
+import permission from './modules/permission'
+import settings from './modules/settings'
+import getters from './getters'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+ modules: {
+ app,
+ dict,
+ user,
+ tagsView,
+ permission,
+ settings
+ },
+ getters
+})
+
+export default store
diff --git a/ruoyi-ui/src/store/modules/app.js b/ruoyi-ui/src/store/modules/app.js
index a7d7dfa..9f99f39 100644
--- a/ruoyi-ui/src/store/modules/app.js
+++ b/ruoyi-ui/src/store/modules/app.js
@@ -1,66 +1,66 @@
-import Cookies from 'js-cookie'
-
-const state = {
- sidebar: {
- opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
- withoutAnimation: false,
- hide: false
- },
- device: 'desktop',
- size: Cookies.get('size') || 'medium'
-}
-
-const mutations = {
- TOGGLE_SIDEBAR: state => {
- if (state.sidebar.hide) {
- return false
- }
- state.sidebar.opened = !state.sidebar.opened
- state.sidebar.withoutAnimation = false
- if (state.sidebar.opened) {
- Cookies.set('sidebarStatus', 1)
- } else {
- Cookies.set('sidebarStatus', 0)
- }
- },
- CLOSE_SIDEBAR: (state, withoutAnimation) => {
- Cookies.set('sidebarStatus', 0)
- state.sidebar.opened = false
- state.sidebar.withoutAnimation = withoutAnimation
- },
- TOGGLE_DEVICE: (state, device) => {
- state.device = device
- },
- SET_SIZE: (state, size) => {
- state.size = size
- Cookies.set('size', size)
- },
- SET_SIDEBAR_HIDE: (state, status) => {
- state.sidebar.hide = status
- }
-}
-
-const actions = {
- toggleSideBar({ commit }) {
- commit('TOGGLE_SIDEBAR')
- },
- closeSideBar({ commit }, { withoutAnimation }) {
- commit('CLOSE_SIDEBAR', withoutAnimation)
- },
- toggleDevice({ commit }, device) {
- commit('TOGGLE_DEVICE', device)
- },
- setSize({ commit }, size) {
- commit('SET_SIZE', size)
- },
- toggleSideBarHide({ commit }, status) {
- commit('SET_SIDEBAR_HIDE', status)
- }
-}
-
-export default {
- namespaced: true,
- state,
- mutations,
- actions
-}
+import Cookies from 'js-cookie'
+
+const state = {
+ sidebar: {
+ opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
+ withoutAnimation: false,
+ hide: false
+ },
+ device: 'desktop',
+ size: Cookies.get('size') || 'medium'
+}
+
+const mutations = {
+ TOGGLE_SIDEBAR: state => {
+ if (state.sidebar.hide) {
+ return false
+ }
+ state.sidebar.opened = !state.sidebar.opened
+ state.sidebar.withoutAnimation = false
+ if (state.sidebar.opened) {
+ Cookies.set('sidebarStatus', 1)
+ } else {
+ Cookies.set('sidebarStatus', 0)
+ }
+ },
+ CLOSE_SIDEBAR: (state, withoutAnimation) => {
+ Cookies.set('sidebarStatus', 0)
+ state.sidebar.opened = false
+ state.sidebar.withoutAnimation = withoutAnimation
+ },
+ TOGGLE_DEVICE: (state, device) => {
+ state.device = device
+ },
+ SET_SIZE: (state, size) => {
+ state.size = size
+ Cookies.set('size', size)
+ },
+ SET_SIDEBAR_HIDE: (state, status) => {
+ state.sidebar.hide = status
+ }
+}
+
+const actions = {
+ toggleSideBar({ commit }) {
+ commit('TOGGLE_SIDEBAR')
+ },
+ closeSideBar({ commit }, { withoutAnimation }) {
+ commit('CLOSE_SIDEBAR', withoutAnimation)
+ },
+ toggleDevice({ commit }, device) {
+ commit('TOGGLE_DEVICE', device)
+ },
+ setSize({ commit }, size) {
+ commit('SET_SIZE', size)
+ },
+ toggleSideBarHide({ commit }, status) {
+ commit('SET_SIDEBAR_HIDE', status)
+ }
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
diff --git a/ruoyi-ui/src/store/modules/dict.js b/ruoyi-ui/src/store/modules/dict.js
index 8b044b6..7a1b2f0 100644
--- a/ruoyi-ui/src/store/modules/dict.js
+++ b/ruoyi-ui/src/store/modules/dict.js
@@ -1,50 +1,50 @@
-const state = {
- dict: new Array()
-}
-const mutations = {
- SET_DICT: (state, { key, value }) => {
- if (key !== null && key !== "") {
- state.dict.push({
- key: key,
- value: value
- })
- }
- },
- REMOVE_DICT: (state, key) => {
- try {
- for (let i = 0; i < state.dict.length; i++) {
- if (state.dict[i].key == key) {
- state.dict.splice(i, 1)
- return true
- }
- }
- } catch (e) {
- }
- },
- CLEAN_DICT: (state) => {
- state.dict = new Array()
- }
-}
-
-const actions = {
- // 设置字典
- setDict({ commit }, data) {
- commit('SET_DICT', data)
- },
- // 删除字典
- removeDict({ commit }, key) {
- commit('REMOVE_DICT', key)
- },
- // 清空字典
- cleanDict({ commit }) {
- commit('CLEAN_DICT')
- }
-}
-
-export default {
- namespaced: true,
- state,
- mutations,
- actions
-}
-
+const state = {
+ dict: new Array()
+}
+const mutations = {
+ SET_DICT: (state, { key, value }) => {
+ if (key !== null && key !== "") {
+ state.dict.push({
+ key: key,
+ value: value
+ })
+ }
+ },
+ REMOVE_DICT: (state, key) => {
+ try {
+ for (let i = 0; i < state.dict.length; i++) {
+ if (state.dict[i].key == key) {
+ state.dict.splice(i, 1)
+ return true
+ }
+ }
+ } catch (e) {
+ }
+ },
+ CLEAN_DICT: (state) => {
+ state.dict = new Array()
+ }
+}
+
+const actions = {
+ // 设置字典
+ setDict({ commit }, data) {
+ commit('SET_DICT', data)
+ },
+ // 删除字典
+ removeDict({ commit }, key) {
+ commit('REMOVE_DICT', key)
+ },
+ // 清空字典
+ cleanDict({ commit }) {
+ commit('CLEAN_DICT')
+ }
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
+
diff --git a/ruoyi-ui/src/store/modules/lock.js b/ruoyi-ui/src/store/modules/lock.js
deleted file mode 100644
index 14e1bd0..0000000
--- a/ruoyi-ui/src/store/modules/lock.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const LOCK_KEY = 'screen-lock'
-const LOCK_PATH_KEY = 'screen-lock-path'
-
-const lock = {
- namespaced: true,
- state: {
- isLock: JSON.parse(localStorage.getItem(LOCK_KEY) || 'false'),
- lockPath: localStorage.getItem(LOCK_PATH_KEY) || '/index'
- },
- mutations: {
- SET_LOCK(state, status) {
- state.isLock = status
- localStorage.setItem(LOCK_KEY, JSON.stringify(status))
- },
- SET_LOCK_PATH(state, path) {
- state.lockPath = path
- localStorage.setItem(LOCK_PATH_KEY, path)
- }
- },
- actions: {
- // 锁定屏幕,同时记录当前路径
- lockScreen({ commit }, currentPath) {
- commit('SET_LOCK_PATH', currentPath || '/index')
- commit('SET_LOCK', true)
- },
- // 解锁屏幕,清除路径
- unlockScreen({ commit }) {
- commit('SET_LOCK', false)
- commit('SET_LOCK_PATH', '/index')
- }
- }
-}
-
-export default lock
diff --git a/ruoyi-ui/src/store/modules/permission.js b/ruoyi-ui/src/store/modules/permission.js
index 7311f23..b549ef0 100644
--- a/ruoyi-ui/src/store/modules/permission.js
+++ b/ruoyi-ui/src/store/modules/permission.js
@@ -1,122 +1,122 @@
-import auth from '@/plugins/auth'
-import router, { constantRoutes, dynamicRoutes } from '@/router'
-import { getRouters } from '@/api/menu'
-import Layout from '@/layout/index'
-import ParentView from '@/components/ParentView'
-import InnerLink from '@/layout/components/InnerLink'
-
-const permission = {
- state: {
- routes: [],
- addRoutes: [],
- defaultRoutes: [],
- topbarRouters: [],
- sidebarRouters: []
- },
- mutations: {
- SET_ROUTES: (state, routes) => {
- state.addRoutes = routes
- state.routes = constantRoutes.concat(routes)
- },
- SET_DEFAULT_ROUTES: (state, routes) => {
- state.defaultRoutes = constantRoutes.concat(routes)
- },
- SET_TOPBAR_ROUTES: (state, routes) => {
- state.topbarRouters = routes
- },
- SET_SIDEBAR_ROUTERS: (state, routes) => {
- state.sidebarRouters = routes
- },
- },
- actions: {
- // 生成路由
- GenerateRoutes({ commit }) {
- return new Promise(resolve => {
- // 向后端请求路由数据
- getRouters().then(res => {
- const sdata = JSON.parse(JSON.stringify(res.data))
- const rdata = JSON.parse(JSON.stringify(res.data))
- const sidebarRoutes = filterAsyncRouter(sdata)
- const rewriteRoutes = filterAsyncRouter(rdata, false, true)
- const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
- rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
- router.addRoutes(asyncRoutes)
- commit('SET_ROUTES', rewriteRoutes)
- commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
- commit('SET_DEFAULT_ROUTES', sidebarRoutes)
- commit('SET_TOPBAR_ROUTES', sidebarRoutes)
- resolve(rewriteRoutes)
- })
- })
- }
- }
-}
-
-// 遍历后台传来的路由字符串,转换为组件对象
-function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
- return asyncRouterMap.filter(route => {
- if (type && route.children) {
- route.children = filterChildren(route.children)
- }
- if (route.component) {
- // Layout ParentView 组件特殊处理
- if (route.component === 'Layout') {
- route.component = Layout
- } else if (route.component === 'ParentView') {
- route.component = ParentView
- } else if (route.component === 'InnerLink') {
- route.component = InnerLink
- } else {
- route.component = loadView(route.component)
- }
- }
- if (route.children != null && route.children && route.children.length) {
- route.children = filterAsyncRouter(route.children, route, type)
- } else {
- delete route['children']
- delete route['redirect']
- }
- return true
- })
-}
-
-function filterChildren(childrenMap, lastRouter = false) {
- var children = []
- childrenMap.forEach(el => {
- el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path
- if (el.children && el.children.length && el.component === 'ParentView') {
- children = children.concat(filterChildren(el.children, el))
- } else {
- children.push(el)
- }
- })
- return children
-}
-
-// 动态路由遍历,验证是否具备权限
-export function filterDynamicRoutes(routes) {
- const res = []
- routes.forEach(route => {
- if (route.permissions) {
- if (auth.hasPermiOr(route.permissions)) {
- res.push(route)
- }
- } else if (route.roles) {
- if (auth.hasRoleOr(route.roles)) {
- res.push(route)
- }
- }
- })
- return res
-}
-
-export const loadView = (view) => {
- if (process.env.NODE_ENV === 'development') {
- return (resolve) => require([`@/views/${view}`], resolve)
- } else {
- // 使用 import 实现生产环境的路由懒加载
- return () => import(`@/views/${view}`)
- }
-}
-
-export default permission
+import auth from '@/plugins/auth'
+import router, { constantRoutes, dynamicRoutes } from '@/router'
+import { getRouters } from '@/api/menu'
+import Layout from '@/layout/index'
+import ParentView from '@/components/ParentView'
+import InnerLink from '@/layout/components/InnerLink'
+
+const permission = {
+ state: {
+ routes: [],
+ addRoutes: [],
+ defaultRoutes: [],
+ topbarRouters: [],
+ sidebarRouters: []
+ },
+ mutations: {
+ SET_ROUTES: (state, routes) => {
+ state.addRoutes = routes
+ state.routes = constantRoutes.concat(routes)
+ },
+ SET_DEFAULT_ROUTES: (state, routes) => {
+ state.defaultRoutes = constantRoutes.concat(routes)
+ },
+ SET_TOPBAR_ROUTES: (state, routes) => {
+ state.topbarRouters = routes
+ },
+ SET_SIDEBAR_ROUTERS: (state, routes) => {
+ state.sidebarRouters = routes
+ },
+ },
+ actions: {
+ // 生成路由
+ GenerateRoutes({ commit }) {
+ return new Promise(resolve => {
+ // 向后端请求路由数据
+ getRouters().then(res => {
+ const sdata = JSON.parse(JSON.stringify(res.data))
+ const rdata = JSON.parse(JSON.stringify(res.data))
+ const sidebarRoutes = filterAsyncRouter(sdata)
+ const rewriteRoutes = filterAsyncRouter(rdata, false, true)
+ const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
+ rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
+ router.addRoutes(asyncRoutes)
+ commit('SET_ROUTES', rewriteRoutes)
+ commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
+ commit('SET_DEFAULT_ROUTES', sidebarRoutes)
+ commit('SET_TOPBAR_ROUTES', sidebarRoutes)
+ resolve(rewriteRoutes)
+ })
+ })
+ }
+ }
+}
+
+// 遍历后台传来的路由字符串,转换为组件对象
+function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
+ return asyncRouterMap.filter(route => {
+ if (type && route.children) {
+ route.children = filterChildren(route.children)
+ }
+ if (route.component) {
+ // Layout ParentView 组件特殊处理
+ if (route.component === 'Layout') {
+ route.component = Layout
+ } else if (route.component === 'ParentView') {
+ route.component = ParentView
+ } else if (route.component === 'InnerLink') {
+ route.component = InnerLink
+ } else {
+ route.component = loadView(route.component)
+ }
+ }
+ if (route.children != null && route.children && route.children.length) {
+ route.children = filterAsyncRouter(route.children, route, type)
+ } else {
+ delete route['children']
+ delete route['redirect']
+ }
+ return true
+ })
+}
+
+function filterChildren(childrenMap, lastRouter = false) {
+ var children = []
+ childrenMap.forEach(el => {
+ el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path
+ if (el.children && el.children.length && el.component === 'ParentView') {
+ children = children.concat(filterChildren(el.children, el))
+ } else {
+ children.push(el)
+ }
+ })
+ return children
+}
+
+// 动态路由遍历,验证是否具备权限
+export function filterDynamicRoutes(routes) {
+ const res = []
+ routes.forEach(route => {
+ if (route.permissions) {
+ if (auth.hasPermiOr(route.permissions)) {
+ res.push(route)
+ }
+ } else if (route.roles) {
+ if (auth.hasRoleOr(route.roles)) {
+ res.push(route)
+ }
+ }
+ })
+ return res
+}
+
+export const loadView = (view) => {
+ if (process.env.NODE_ENV === 'development') {
+ return (resolve) => require([`@/views/${view}`], resolve)
+ } else {
+ // 使用 import 实现生产环境的路由懒加载
+ return () => import(`@/views/${view}`)
+ }
+}
+
+export default permission
diff --git a/ruoyi-ui/src/store/modules/settings.js b/ruoyi-ui/src/store/modules/settings.js
index 873003f..1e37148 100644
--- a/ruoyi-ui/src/store/modules/settings.js
+++ b/ruoyi-ui/src/store/modules/settings.js
@@ -1,52 +1,50 @@
-import defaultSettings from '@/settings'
-import { useDynamicTitle } from '@/utils/dynamicTitle'
-
-const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, tagsViewStyle, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
-
-const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
-const state = {
- title: '',
- theme: storageSetting.theme || '#409EFF',
- sideTheme: storageSetting.sideTheme || sideTheme,
- showSettings: showSettings,
- navType: storageSetting.navType === undefined ? navType : storageSetting.navType,
- tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
- tagsViewPersist: storageSetting.tagsViewPersist === undefined ? tagsViewPersist : storageSetting.tagsViewPersist,
- tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon,
- tagsViewStyle: storageSetting.tagsViewStyle === undefined ? tagsViewStyle : storageSetting.tagsViewStyle,
- fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
- sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
- dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle,
- footerVisible: storageSetting.footerVisible === undefined ? footerVisible : storageSetting.footerVisible,
- footerContent: footerContent
-}
-const mutations = {
- CHANGE_SETTING: (state, { key, value }) => {
- if (state.hasOwnProperty(key)) {
- state[key] = value
- }
- },
- SET_TITLE: (state, title) => {
- state.title = title
- }
-}
-
-const actions = {
- // 修改布局设置
- changeSetting({ commit }, data) {
- commit('CHANGE_SETTING', data)
- },
- // 设置网页标题
- setTitle({ commit }, title) {
- commit('SET_TITLE', title)
- useDynamicTitle()
- }
-}
-
-export default {
- namespaced: true,
- state,
- mutations,
- actions
-}
-
+import defaultSettings from '@/settings'
+import { useDynamicTitle } from '@/utils/dynamicTitle'
+
+const { sideTheme, showSettings, navType, tagsView, tagsIcon, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
+
+const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
+const state = {
+ title: '',
+ theme: storageSetting.theme || '#409EFF',
+ sideTheme: storageSetting.sideTheme || sideTheme,
+ showSettings: showSettings,
+ navType: storageSetting.navType === undefined ? navType : storageSetting.navType,
+ tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
+ tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon,
+ fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
+ sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
+ dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle,
+ footerVisible: storageSetting.footerVisible === undefined ? footerVisible : storageSetting.footerVisible,
+ footerContent: footerContent
+}
+const mutations = {
+ CHANGE_SETTING: (state, { key, value }) => {
+ if (state.hasOwnProperty(key)) {
+ state[key] = value
+ }
+ },
+ SET_TITLE: (state, title) => {
+ state.title = title
+ }
+}
+
+const actions = {
+ // 修改布局设置
+ changeSetting({ commit }, data) {
+ commit('CHANGE_SETTING', data)
+ },
+ // 设置网页标题
+ setTitle({ commit }, title) {
+ commit('SET_TITLE', title)
+ useDynamicTitle()
+ }
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
+
diff --git a/ruoyi-ui/src/store/modules/tagsView.js b/ruoyi-ui/src/store/modules/tagsView.js
index d3f52fb..5fc011c 100644
--- a/ruoyi-ui/src/store/modules/tagsView.js
+++ b/ruoyi-ui/src/store/modules/tagsView.js
@@ -1,275 +1,228 @@
-import store from '@/store'
-import cache from '@/plugins/cache'
-
-const PERSIST_KEY = 'tags-view-visited'
-
-function isPersistEnabled() {
- return store.state.settings.tagsViewPersist
-}
-
-function saveVisitedViews(views) {
- if (!isPersistEnabled()) return
- const toSave = views.filter(v => !(v.meta && v.meta.affix)).map(v => ({ path: v.path, fullPath: v.fullPath, name: v.name, title: v.title, query: v.query, meta: v.meta }))
- cache.local.setJSON(PERSIST_KEY, toSave)
-}
-
-function loadVisitedViews() {
- return cache.local.getJSON(PERSIST_KEY) || []
-}
-
-function clearVisitedViews() {
- cache.local.remove(PERSIST_KEY)
-}
-
-const state = {
- visitedViews: [],
- cachedViews: [],
- iframeViews: []
-}
-
-const mutations = {
- ADD_IFRAME_VIEW: (state, view) => {
- if (state.iframeViews.some(v => v.path === view.path)) return
- state.iframeViews.push(
- Object.assign({}, view, {
- title: view.meta.title || 'no-name'
- })
- )
- },
- ADD_VISITED_VIEW: (state, view) => {
- if (state.visitedViews.some(v => v.path === view.path)) return
- state.visitedViews.push(
- Object.assign({}, view, {
- title: view.meta.title || 'no-name'
- })
- )
- saveVisitedViews(state.visitedViews)
- },
- ADD_VISITED_VIEW_FIRST: (state, view) => {
- if (state.visitedViews.some(v => v.path === view.path)) return
- state.visitedViews.unshift(
- Object.assign({}, view, {
- title: view.meta.title || 'no-name'
- })
- )
- },
- ADD_CACHED_VIEW: (state, view) => {
- if (state.cachedViews.includes(view.name)) return
- if (view.meta && !view.meta.noCache) {
- state.cachedViews.push(view.name)
- }
- },
- DEL_VISITED_VIEW: (state, view) => {
- for (const [i, v] of state.visitedViews.entries()) {
- if (v.path === view.path) {
- state.visitedViews.splice(i, 1)
- break
- }
- }
- state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
- saveVisitedViews(state.visitedViews)
- },
- DEL_IFRAME_VIEW: (state, view) => {
- state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
- },
- DEL_CACHED_VIEW: (state, view) => {
- const index = state.cachedViews.indexOf(view.name)
- index > -1 && state.cachedViews.splice(index, 1)
- },
-
- DEL_OTHERS_VISITED_VIEWS: (state, view) => {
- state.visitedViews = state.visitedViews.filter(v => {
- return v.meta.affix || v.path === view.path
- })
- state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
- saveVisitedViews(state.visitedViews)
- },
- DEL_OTHERS_CACHED_VIEWS: (state, view) => {
- const index = state.cachedViews.indexOf(view.name)
- if (index > -1) {
- state.cachedViews = state.cachedViews.slice(index, index + 1)
- } else {
- state.cachedViews = []
- }
- },
- DEL_ALL_VISITED_VIEWS: state => {
- // keep affix tags
- const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
- state.visitedViews = affixTags
- state.iframeViews = []
- clearVisitedViews()
- },
- DEL_ALL_CACHED_VIEWS: state => {
- state.cachedViews = []
- },
- UPDATE_VISITED_VIEW: (state, view) => {
- for (let v of state.visitedViews) {
- if (v.path === view.path) {
- v = Object.assign(v, view)
- break
- }
- }
- },
- DEL_RIGHT_VIEWS: (state, view) => {
- const index = state.visitedViews.findIndex(v => v.path === view.path)
- if (index === -1) {
- return
- }
- state.visitedViews = state.visitedViews.filter((item, idx) => {
- if (idx <= index || (item.meta && item.meta.affix)) {
- return true
- }
- const i = state.cachedViews.indexOf(item.name)
- if (i > -1) {
- state.cachedViews.splice(i, 1)
- }
- if(item.meta.link) {
- const fi = state.iframeViews.findIndex(v => v.path === item.path)
- state.iframeViews.splice(fi, 1)
- }
- return false
- })
- saveVisitedViews(state.visitedViews)
- },
- DEL_LEFT_VIEWS: (state, view) => {
- const index = state.visitedViews.findIndex(v => v.path === view.path)
- if (index === -1) {
- return
- }
- state.visitedViews = state.visitedViews.filter((item, idx) => {
- if (idx >= index || (item.meta && item.meta.affix)) {
- return true
- }
- const i = state.cachedViews.indexOf(item.name)
- if (i > -1) {
- state.cachedViews.splice(i, 1)
- }
- if(item.meta.link) {
- const fi = state.iframeViews.findIndex(v => v.path === item.path)
- state.iframeViews.splice(fi, 1)
- }
- return false
- })
- saveVisitedViews(state.visitedViews)
- }
-}
-
-const actions = {
- addView({ dispatch }, view) {
- dispatch('addVisitedView', view)
- dispatch('addCachedView', view)
- },
- addIframeView({ commit }, view) {
- commit('ADD_IFRAME_VIEW', view)
- },
- addVisitedView({ commit }, view) {
- commit('ADD_VISITED_VIEW', view)
- },
- addAffixView({ commit }, view) {
- commit('ADD_VISITED_VIEW_FIRST', view)
- },
- addCachedView({ commit }, view) {
- commit('ADD_CACHED_VIEW', view)
- },
- delView({ dispatch, state }, view) {
- return new Promise(resolve => {
- dispatch('delVisitedView', view)
- dispatch('delCachedView', view)
- resolve({
- visitedViews: [...state.visitedViews],
- cachedViews: [...state.cachedViews]
- })
- })
- },
- delVisitedView({ commit, state }, view) {
- return new Promise(resolve => {
- commit('DEL_VISITED_VIEW', view)
- resolve([...state.visitedViews])
- })
- },
- delIframeView({ commit, state }, view) {
- return new Promise(resolve => {
- commit('DEL_IFRAME_VIEW', view)
- resolve([...state.iframeViews])
- })
- },
- delCachedView({ commit, state }, view) {
- return new Promise(resolve => {
- commit('DEL_CACHED_VIEW', view)
- resolve([...state.cachedViews])
- })
- },
- delOthersViews({ dispatch, state }, view) {
- return new Promise(resolve => {
- dispatch('delOthersVisitedViews', view)
- dispatch('delOthersCachedViews', view)
- resolve({
- visitedViews: [...state.visitedViews],
- cachedViews: [...state.cachedViews]
- })
- })
- },
- delOthersVisitedViews({ commit, state }, view) {
- return new Promise(resolve => {
- commit('DEL_OTHERS_VISITED_VIEWS', view)
- resolve([...state.visitedViews])
- })
- },
- delOthersCachedViews({ commit, state }, view) {
- return new Promise(resolve => {
- commit('DEL_OTHERS_CACHED_VIEWS', view)
- resolve([...state.cachedViews])
- })
- },
- delAllViews({ dispatch, state }, view) {
- return new Promise(resolve => {
- dispatch('delAllVisitedViews', view)
- dispatch('delAllCachedViews', view)
- resolve({
- visitedViews: [...state.visitedViews],
- cachedViews: [...state.cachedViews]
- })
- })
- },
- delAllVisitedViews({ commit, state }) {
- return new Promise(resolve => {
- commit('DEL_ALL_VISITED_VIEWS')
- resolve([...state.visitedViews])
- })
- },
- delAllCachedViews({ commit, state }) {
- return new Promise(resolve => {
- commit('DEL_ALL_CACHED_VIEWS')
- resolve([...state.cachedViews])
- })
- },
- updateVisitedView({ commit }, view) {
- commit('UPDATE_VISITED_VIEW', view)
- },
- delRightTags({ commit }, view) {
- return new Promise(resolve => {
- commit('DEL_RIGHT_VIEWS', view)
- resolve([...state.visitedViews])
- })
- },
- delLeftTags({ commit }, view) {
- return new Promise(resolve => {
- commit('DEL_LEFT_VIEWS', view)
- resolve([...state.visitedViews])
- })
- },
- // 恢复持久化的 tags
- loadPersistedViews({ commit }) {
- const views = loadVisitedViews()
- views.forEach(view => {
- commit('ADD_VISITED_VIEW', view)
- })
- },
-}
-
-export default {
- namespaced: true,
- state,
- mutations,
- actions
-}
+const state = {
+ visitedViews: [],
+ cachedViews: [],
+ iframeViews: []
+}
+
+const mutations = {
+ ADD_IFRAME_VIEW: (state, view) => {
+ if (state.iframeViews.some(v => v.path === view.path)) return
+ state.iframeViews.push(
+ Object.assign({}, view, {
+ title: view.meta.title || 'no-name'
+ })
+ )
+ },
+ ADD_VISITED_VIEW: (state, view) => {
+ if (state.visitedViews.some(v => v.path === view.path)) return
+ state.visitedViews.push(
+ Object.assign({}, view, {
+ title: view.meta.title || 'no-name'
+ })
+ )
+ },
+ ADD_CACHED_VIEW: (state, view) => {
+ if (state.cachedViews.includes(view.name)) return
+ if (view.meta && !view.meta.noCache) {
+ state.cachedViews.push(view.name)
+ }
+ },
+ DEL_VISITED_VIEW: (state, view) => {
+ for (const [i, v] of state.visitedViews.entries()) {
+ if (v.path === view.path) {
+ state.visitedViews.splice(i, 1)
+ break
+ }
+ }
+ state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
+ },
+ DEL_IFRAME_VIEW: (state, view) => {
+ state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
+ },
+ DEL_CACHED_VIEW: (state, view) => {
+ const index = state.cachedViews.indexOf(view.name)
+ index > -1 && state.cachedViews.splice(index, 1)
+ },
+
+ DEL_OTHERS_VISITED_VIEWS: (state, view) => {
+ state.visitedViews = state.visitedViews.filter(v => {
+ return v.meta.affix || v.path === view.path
+ })
+ state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
+ },
+ DEL_OTHERS_CACHED_VIEWS: (state, view) => {
+ const index = state.cachedViews.indexOf(view.name)
+ if (index > -1) {
+ state.cachedViews = state.cachedViews.slice(index, index + 1)
+ } else {
+ state.cachedViews = []
+ }
+ },
+ DEL_ALL_VISITED_VIEWS: state => {
+ // keep affix tags
+ const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
+ state.visitedViews = affixTags
+ state.iframeViews = []
+ },
+ DEL_ALL_CACHED_VIEWS: state => {
+ state.cachedViews = []
+ },
+ UPDATE_VISITED_VIEW: (state, view) => {
+ for (let v of state.visitedViews) {
+ if (v.path === view.path) {
+ v = Object.assign(v, view)
+ break
+ }
+ }
+ },
+ DEL_RIGHT_VIEWS: (state, view) => {
+ const index = state.visitedViews.findIndex(v => v.path === view.path)
+ if (index === -1) {
+ return
+ }
+ state.visitedViews = state.visitedViews.filter((item, idx) => {
+ if (idx <= index || (item.meta && item.meta.affix)) {
+ return true
+ }
+ const i = state.cachedViews.indexOf(item.name)
+ if (i > -1) {
+ state.cachedViews.splice(i, 1)
+ }
+ if(item.meta.link) {
+ const fi = state.iframeViews.findIndex(v => v.path === item.path)
+ state.iframeViews.splice(fi, 1)
+ }
+ return false
+ })
+ },
+ DEL_LEFT_VIEWS: (state, view) => {
+ const index = state.visitedViews.findIndex(v => v.path === view.path)
+ if (index === -1) {
+ return
+ }
+ state.visitedViews = state.visitedViews.filter((item, idx) => {
+ if (idx >= index || (item.meta && item.meta.affix)) {
+ return true
+ }
+ const i = state.cachedViews.indexOf(item.name)
+ if (i > -1) {
+ state.cachedViews.splice(i, 1)
+ }
+ if(item.meta.link) {
+ const fi = state.iframeViews.findIndex(v => v.path === item.path)
+ state.iframeViews.splice(fi, 1)
+ }
+ return false
+ })
+ }
+}
+
+const actions = {
+ addView({ dispatch }, view) {
+ dispatch('addVisitedView', view)
+ dispatch('addCachedView', view)
+ },
+ addIframeView({ commit }, view) {
+ commit('ADD_IFRAME_VIEW', view)
+ },
+ addVisitedView({ commit }, view) {
+ commit('ADD_VISITED_VIEW', view)
+ },
+ addCachedView({ commit }, view) {
+ commit('ADD_CACHED_VIEW', view)
+ },
+ delView({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delVisitedView', view)
+ dispatch('delCachedView', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delVisitedView({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_VISITED_VIEW', view)
+ resolve([...state.visitedViews])
+ })
+ },
+ delIframeView({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_IFRAME_VIEW', view)
+ resolve([...state.iframeViews])
+ })
+ },
+ delCachedView({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_CACHED_VIEW', view)
+ resolve([...state.cachedViews])
+ })
+ },
+ delOthersViews({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delOthersVisitedViews', view)
+ dispatch('delOthersCachedViews', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delOthersVisitedViews({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_OTHERS_VISITED_VIEWS', view)
+ resolve([...state.visitedViews])
+ })
+ },
+ delOthersCachedViews({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_OTHERS_CACHED_VIEWS', view)
+ resolve([...state.cachedViews])
+ })
+ },
+ delAllViews({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delAllVisitedViews', view)
+ dispatch('delAllCachedViews', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delAllVisitedViews({ commit, state }) {
+ return new Promise(resolve => {
+ commit('DEL_ALL_VISITED_VIEWS')
+ resolve([...state.visitedViews])
+ })
+ },
+ delAllCachedViews({ commit, state }) {
+ return new Promise(resolve => {
+ commit('DEL_ALL_CACHED_VIEWS')
+ resolve([...state.cachedViews])
+ })
+ },
+ updateVisitedView({ commit }, view) {
+ commit('UPDATE_VISITED_VIEW', view)
+ },
+ delRightTags({ commit }, view) {
+ return new Promise(resolve => {
+ commit('DEL_RIGHT_VIEWS', view)
+ resolve([...state.visitedViews])
+ })
+ },
+ delLeftTags({ commit }, view) {
+ return new Promise(resolve => {
+ commit('DEL_LEFT_VIEWS', view)
+ resolve([...state.visitedViews])
+ })
+ },
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
diff --git a/ruoyi-ui/src/store/modules/user.js b/ruoyi-ui/src/store/modules/user.js
index e6439e0..6a7b710 100644
--- a/ruoyi-ui/src/store/modules/user.js
+++ b/ruoyi-ui/src/store/modules/user.js
@@ -1,127 +1,125 @@
-import store from '@/store'
-import router from '@/router'
-import { MessageBox, } from 'element-ui'
-import { login, logout, getInfo } from '@/api/login'
-import { getToken, setToken, removeToken } from '@/utils/auth'
-import { isHttp, isEmpty } from "@/utils/validate"
-import defAva from '@/assets/images/profile.jpg'
-
-const user = {
- state: {
- token: getToken(),
- id: '',
- name: '',
- nickName: '',
- avatar: '',
- roles: [],
- permissions: []
- },
-
- mutations: {
- SET_TOKEN: (state, token) => {
- state.token = token
- },
- SET_ID: (state, id) => {
- state.id = id
- },
- SET_NAME: (state, name) => {
- state.name = name
- },
- SET_NICK_NAME: (state, nickName) => {
- state.nickName = nickName
- },
- SET_AVATAR: (state, avatar) => {
- state.avatar = avatar
- },
- SET_ROLES: (state, roles) => {
- state.roles = roles
- },
- SET_PERMISSIONS: (state, permissions) => {
- state.permissions = permissions
- }
- },
-
- actions: {
- // 登录
- Login({ commit }, userInfo) {
- const username = userInfo.username.trim()
- const password = userInfo.password
- const code = userInfo.code
- const uuid = userInfo.uuid
- return new Promise((resolve, reject) => {
- login(username, password, code, uuid).then(res => {
- setToken(res.token)
- commit('SET_TOKEN', res.token)
- store.dispatch('lock/unlockScreen')
- resolve()
- }).catch(error => {
- reject(error)
- })
- })
- },
-
- // 获取用户信息
- GetInfo({ commit, state }) {
- return new Promise((resolve, reject) => {
- getInfo().then(res => {
- const user = res.user
- let avatar = user.avatar || ""
- if (!isHttp(avatar)) {
- avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
- }
- if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
- commit('SET_ROLES', res.roles)
- commit('SET_PERMISSIONS', res.permissions)
- } else {
- commit('SET_ROLES', ['ROLE_DEFAULT'])
- }
- commit('SET_ID', user.userId)
- commit('SET_NAME', user.userName)
- commit('SET_NICK_NAME', user.nickName)
- commit('SET_AVATAR', avatar)
- /* 初始密码提示 */
- if(res.isDefaultModifyPwd) {
- MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
- router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
- }).catch(() => {})
- }
- /* 过期密码提示 */
- if(!res.isDefaultModifyPwd && res.isPasswordExpired) {
- MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
- router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
- }).catch(() => {})
- }
- resolve(res)
- }).catch(error => {
- reject(error)
- })
- })
- },
-
- // 退出系统
- LogOut({ commit, state }) {
- return new Promise((resolve, reject) => {
- logout(state.token).then(() => {
- commit('SET_TOKEN', '')
- commit('SET_ROLES', [])
- commit('SET_PERMISSIONS', [])
- removeToken()
- resolve()
- }).catch(error => {
- reject(error)
- })
- })
- },
-
- // 前端 登出
- FedLogOut({ commit }) {
- return new Promise(resolve => {
- commit('SET_TOKEN', '')
- removeToken()
- resolve()
- })
- }
- }
-}
-
-export default user
+import router from '@/router'
+import { MessageBox, } from 'element-ui'
+import { login, logout, getInfo } from '@/api/login'
+import { getToken, setToken, removeToken } from '@/utils/auth'
+import { isHttp, isEmpty } from "@/utils/validate"
+import defAva from '@/assets/images/profile.jpg'
+
+const user = {
+ state: {
+ token: getToken(),
+ id: '',
+ name: '',
+ nickName: '',
+ avatar: '',
+ roles: [],
+ permissions: []
+ },
+
+ mutations: {
+ SET_TOKEN: (state, token) => {
+ state.token = token
+ },
+ SET_ID: (state, id) => {
+ state.id = id
+ },
+ SET_NAME: (state, name) => {
+ state.name = name
+ },
+ SET_NICK_NAME: (state, nickName) => {
+ state.nickName = nickName
+ },
+ SET_AVATAR: (state, avatar) => {
+ state.avatar = avatar
+ },
+ SET_ROLES: (state, roles) => {
+ state.roles = roles
+ },
+ SET_PERMISSIONS: (state, permissions) => {
+ state.permissions = permissions
+ }
+ },
+
+ actions: {
+ // 登录
+ Login({ commit }, userInfo) {
+ const username = userInfo.username.trim()
+ const password = userInfo.password
+ const code = userInfo.code
+ const uuid = userInfo.uuid
+ return new Promise((resolve, reject) => {
+ login(username, password, code, uuid).then(res => {
+ setToken(res.token)
+ commit('SET_TOKEN', res.token)
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 获取用户信息
+ GetInfo({ commit, state }) {
+ return new Promise((resolve, reject) => {
+ getInfo().then(res => {
+ const user = res.user
+ let avatar = user.avatar || ""
+ if (!isHttp(avatar)) {
+ avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
+ }
+ if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
+ commit('SET_ROLES', res.roles)
+ commit('SET_PERMISSIONS', res.permissions)
+ } else {
+ commit('SET_ROLES', ['ROLE_DEFAULT'])
+ }
+ commit('SET_ID', user.userId)
+ commit('SET_NAME', user.userName)
+ commit('SET_NICK_NAME', user.nickName)
+ commit('SET_AVATAR', avatar)
+ /* 初始密码提示 */
+ if(res.isDefaultModifyPwd) {
+ MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
+ }).catch(() => {})
+ }
+ /* 过期密码提示 */
+ if(!res.isDefaultModifyPwd && res.isPasswordExpired) {
+ MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
+ }).catch(() => {})
+ }
+ resolve(res)
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 退出系统
+ LogOut({ commit, state }) {
+ return new Promise((resolve, reject) => {
+ logout(state.token).then(() => {
+ commit('SET_TOKEN', '')
+ commit('SET_ROLES', [])
+ commit('SET_PERMISSIONS', [])
+ removeToken()
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 前端 登出
+ FedLogOut({ commit }) {
+ return new Promise(resolve => {
+ commit('SET_TOKEN', '')
+ removeToken()
+ resolve()
+ })
+ }
+ }
+}
+
+export default user
diff --git a/ruoyi-ui/src/utils/auth.js b/ruoyi-ui/src/utils/auth.js
index 88d7b6c..08a43d6 100644
--- a/ruoyi-ui/src/utils/auth.js
+++ b/ruoyi-ui/src/utils/auth.js
@@ -1,15 +1,15 @@
-import Cookies from 'js-cookie'
-
-const TokenKey = 'Admin-Token'
-
-export function getToken() {
- return Cookies.get(TokenKey)
-}
-
-export function setToken(token) {
- return Cookies.set(TokenKey, token)
-}
-
-export function removeToken() {
- return Cookies.remove(TokenKey)
-}
+import Cookies from 'js-cookie'
+
+const TokenKey = 'Admin-Token'
+
+export function getToken() {
+ return Cookies.get(TokenKey)
+}
+
+export function setToken(token) {
+ return Cookies.set(TokenKey, token)
+}
+
+export function removeToken() {
+ return Cookies.remove(TokenKey)
+}
diff --git a/ruoyi-ui/src/utils/dict/Dict.js b/ruoyi-ui/src/utils/dict/Dict.js
index e97d794..994f6f7 100644
--- a/ruoyi-ui/src/utils/dict/Dict.js
+++ b/ruoyi-ui/src/utils/dict/Dict.js
@@ -1,82 +1,82 @@
-import Vue from 'vue'
-import { mergeRecursive } from "@/utils/ruoyi"
-import DictMeta from './DictMeta'
-import DictData from './DictData'
-
-const DEFAULT_DICT_OPTIONS = {
- types: [],
-}
-
-/**
- * @classdesc 字典
- * @property {Object} label 标签对象,内部属性名为字典类型名称
- * @property {Object} dict 字段数组,内部属性名为字典类型名称
- * @property {Array.
} _dictMetas 字典元数据数组
- */
-export default class Dict {
- constructor() {
- this.owner = null
- this.label = {}
- this.type = {}
- }
-
- init(options) {
- if (options instanceof Array) {
- options = { types: options }
- }
- const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)
- if (opts.types === undefined) {
- throw new Error('need dict types')
- }
- const ps = []
- this._dictMetas = opts.types.map(t => DictMeta.parse(t))
- this._dictMetas.forEach(dictMeta => {
- const type = dictMeta.type
- Vue.set(this.label, type, {})
- Vue.set(this.type, type, [])
- if (dictMeta.lazy) {
- return
- }
- ps.push(loadDict(this, dictMeta))
- })
- return Promise.all(ps)
- }
-
- /**
- * 重新加载字典
- * @param {String} type 字典类型
- */
- reloadDict(type) {
- const dictMeta = this._dictMetas.find(e => e.type === type)
- if (dictMeta === undefined) {
- return Promise.reject(`the dict meta of ${type} was not found`)
- }
- return loadDict(this, dictMeta)
- }
-}
-
-/**
- * 加载字典
- * @param {Dict} dict 字典
- * @param {DictMeta} dictMeta 字典元数据
- * @returns {Promise}
- */
-function loadDict(dict, dictMeta) {
- return dictMeta.request(dictMeta)
- .then(response => {
- const type = dictMeta.type
- let dicts = dictMeta.responseConverter(response, dictMeta)
- if (!(dicts instanceof Array)) {
- console.error('the return of responseConverter must be Array.')
- dicts = []
- } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
- console.error('the type of elements in dicts must be DictData')
- dicts = []
- }
- dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
- dicts.forEach(d => {
- Vue.set(dict.label[type], d.value, d.label)
- })
- return dicts
- })
-}
+import Vue from 'vue'
+import { mergeRecursive } from "@/utils/ruoyi"
+import DictMeta from './DictMeta'
+import DictData from './DictData'
+
+const DEFAULT_DICT_OPTIONS = {
+ types: [],
+}
+
+/**
+ * @classdesc 字典
+ * @property {Object} label 标签对象,内部属性名为字典类型名称
+ * @property {Object} dict 字段数组,内部属性名为字典类型名称
+ * @property {Array.} _dictMetas 字典元数据数组
+ */
+export default class Dict {
+ constructor() {
+ this.owner = null
+ this.label = {}
+ this.type = {}
+ }
+
+ init(options) {
+ if (options instanceof Array) {
+ options = { types: options }
+ }
+ const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)
+ if (opts.types === undefined) {
+ throw new Error('need dict types')
+ }
+ const ps = []
+ this._dictMetas = opts.types.map(t => DictMeta.parse(t))
+ this._dictMetas.forEach(dictMeta => {
+ const type = dictMeta.type
+ Vue.set(this.label, type, {})
+ Vue.set(this.type, type, [])
+ if (dictMeta.lazy) {
+ return
+ }
+ ps.push(loadDict(this, dictMeta))
+ })
+ return Promise.all(ps)
+ }
+
+ /**
+ * 重新加载字典
+ * @param {String} type 字典类型
+ */
+ reloadDict(type) {
+ const dictMeta = this._dictMetas.find(e => e.type === type)
+ if (dictMeta === undefined) {
+ return Promise.reject(`the dict meta of ${type} was not found`)
+ }
+ return loadDict(this, dictMeta)
+ }
+}
+
+/**
+ * 加载字典
+ * @param {Dict} dict 字典
+ * @param {DictMeta} dictMeta 字典元数据
+ * @returns {Promise}
+ */
+function loadDict(dict, dictMeta) {
+ return dictMeta.request(dictMeta)
+ .then(response => {
+ const type = dictMeta.type
+ let dicts = dictMeta.responseConverter(response, dictMeta)
+ if (!(dicts instanceof Array)) {
+ console.error('the return of responseConverter must be Array.')
+ dicts = []
+ } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
+ console.error('the type of elements in dicts must be DictData')
+ dicts = []
+ }
+ dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
+ dicts.forEach(d => {
+ Vue.set(dict.label[type], d.value, d.label)
+ })
+ return dicts
+ })
+}
diff --git a/ruoyi-ui/src/utils/dict/DictConverter.js b/ruoyi-ui/src/utils/dict/DictConverter.js
index 576ff54..0cf5df8 100644
--- a/ruoyi-ui/src/utils/dict/DictConverter.js
+++ b/ruoyi-ui/src/utils/dict/DictConverter.js
@@ -1,17 +1,17 @@
-import DictOptions from './DictOptions'
-import DictData from './DictData'
-
-export default function(dict, dictMeta) {
- const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS)
- const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS)
- return new DictData(dict[label], dict[value], dict)
-}
-
-/**
- * 确定字典字段
- * @param {DictData} dict
- * @param {...String} fields
- */
-function determineDictField(dict, ...fields) {
- return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f))
-}
+import DictOptions from './DictOptions'
+import DictData from './DictData'
+
+export default function(dict, dictMeta) {
+ const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS)
+ const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS)
+ return new DictData(dict[label], dict[value], dict)
+}
+
+/**
+ * 确定字典字段
+ * @param {DictData} dict
+ * @param {...String} fields
+ */
+function determineDictField(dict, ...fields) {
+ return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f))
+}
diff --git a/ruoyi-ui/src/utils/dict/DictData.js b/ruoyi-ui/src/utils/dict/DictData.js
index 37a60d5..afc763e 100644
--- a/ruoyi-ui/src/utils/dict/DictData.js
+++ b/ruoyi-ui/src/utils/dict/DictData.js
@@ -1,13 +1,13 @@
-/**
- * @classdesc 字典数据
- * @property {String} label 标签
- * @property {*} value 标签
- * @property {Object} raw 原始数据
- */
-export default class DictData {
- constructor(label, value, raw) {
- this.label = label
- this.value = value
- this.raw = raw
- }
-}
+/**
+ * @classdesc 字典数据
+ * @property {String} label 标签
+ * @property {*} value 标签
+ * @property {Object} raw 原始数据
+ */
+export default class DictData {
+ constructor(label, value, raw) {
+ this.label = label
+ this.value = value
+ this.raw = raw
+ }
+}
diff --git a/ruoyi-ui/src/utils/dict/DictMeta.js b/ruoyi-ui/src/utils/dict/DictMeta.js
index 1f695b1..617cc00 100644
--- a/ruoyi-ui/src/utils/dict/DictMeta.js
+++ b/ruoyi-ui/src/utils/dict/DictMeta.js
@@ -1,38 +1,38 @@
-import { mergeRecursive } from "@/utils/ruoyi"
-import DictOptions from './DictOptions'
-
-/**
- * @classdesc 字典元数据
- * @property {String} type 类型
- * @property {Function} request 请求
- * @property {String} label 标签字段
- * @property {String} value 值字段
- */
-export default class DictMeta {
- constructor(options) {
- this.type = options.type
- this.request = options.request
- this.responseConverter = options.responseConverter
- this.labelField = options.labelField
- this.valueField = options.valueField
- this.lazy = options.lazy === true
- }
-}
-
-
-/**
- * 解析字典元数据
- * @param {Object} options
- * @returns {DictMeta}
- */
-DictMeta.parse= function(options) {
- let opts = null
- if (typeof options === 'string') {
- opts = DictOptions.metas[options] || {}
- opts.type = options
- } else if (typeof options === 'object') {
- opts = options
- }
- opts = mergeRecursive(DictOptions.metas['*'], opts)
- return new DictMeta(opts)
-}
+import { mergeRecursive } from "@/utils/ruoyi"
+import DictOptions from './DictOptions'
+
+/**
+ * @classdesc 字典元数据
+ * @property {String} type 类型
+ * @property {Function} request 请求
+ * @property {String} label 标签字段
+ * @property {String} value 值字段
+ */
+export default class DictMeta {
+ constructor(options) {
+ this.type = options.type
+ this.request = options.request
+ this.responseConverter = options.responseConverter
+ this.labelField = options.labelField
+ this.valueField = options.valueField
+ this.lazy = options.lazy === true
+ }
+}
+
+
+/**
+ * 解析字典元数据
+ * @param {Object} options
+ * @returns {DictMeta}
+ */
+DictMeta.parse= function(options) {
+ let opts = null
+ if (typeof options === 'string') {
+ opts = DictOptions.metas[options] || {}
+ opts.type = options
+ } else if (typeof options === 'object') {
+ opts = options
+ }
+ opts = mergeRecursive(DictOptions.metas['*'], opts)
+ return new DictMeta(opts)
+}
diff --git a/ruoyi-ui/src/utils/dict/DictOptions.js b/ruoyi-ui/src/utils/dict/DictOptions.js
index c58bc17..5fd1425 100644
--- a/ruoyi-ui/src/utils/dict/DictOptions.js
+++ b/ruoyi-ui/src/utils/dict/DictOptions.js
@@ -1,51 +1,51 @@
-import { mergeRecursive } from "@/utils/ruoyi"
-import dictConverter from './DictConverter'
-
-export const options = {
- metas: {
- '*': {
- /**
- * 字典请求,方法签名为function(dictMeta: DictMeta): Promise
- */
- request: (dictMeta) => {
- console.log(`load dict ${dictMeta.type}`)
- return Promise.resolve([])
- },
- /**
- * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData
- */
- responseConverter,
- labelField: 'label',
- valueField: 'value',
- },
- },
- /**
- * 默认标签字段
- */
- DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'],
- /**
- * 默认值字段
- */
- DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'],
-}
-
-/**
- * 映射字典
- * @param {Object} response 字典数据
- * @param {DictMeta} dictMeta 字典元数据
- * @returns {DictData}
- */
-function responseConverter(response, dictMeta) {
- const dicts = response.content instanceof Array ? response.content : response
- if (dicts === undefined) {
- console.warn(`no dict data of "${dictMeta.type}" found in the response`)
- return []
- }
- return dicts.map(d => dictConverter(d, dictMeta))
-}
-
-export function mergeOptions(src) {
- mergeRecursive(options, src)
-}
-
-export default options
+import { mergeRecursive } from "@/utils/ruoyi"
+import dictConverter from './DictConverter'
+
+export const options = {
+ metas: {
+ '*': {
+ /**
+ * 字典请求,方法签名为function(dictMeta: DictMeta): Promise
+ */
+ request: (dictMeta) => {
+ console.log(`load dict ${dictMeta.type}`)
+ return Promise.resolve([])
+ },
+ /**
+ * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData
+ */
+ responseConverter,
+ labelField: 'label',
+ valueField: 'value',
+ },
+ },
+ /**
+ * 默认标签字段
+ */
+ DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'],
+ /**
+ * 默认值字段
+ */
+ DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'],
+}
+
+/**
+ * 映射字典
+ * @param {Object} response 字典数据
+ * @param {DictMeta} dictMeta 字典元数据
+ * @returns {DictData}
+ */
+function responseConverter(response, dictMeta) {
+ const dicts = response.content instanceof Array ? response.content : response
+ if (dicts === undefined) {
+ console.warn(`no dict data of "${dictMeta.type}" found in the response`)
+ return []
+ }
+ return dicts.map(d => dictConverter(d, dictMeta))
+}
+
+export function mergeOptions(src) {
+ mergeRecursive(options, src)
+}
+
+export default options
diff --git a/ruoyi-ui/src/utils/dict/index.js b/ruoyi-ui/src/utils/dict/index.js
index d6fdb80..215eb9e 100644
--- a/ruoyi-ui/src/utils/dict/index.js
+++ b/ruoyi-ui/src/utils/dict/index.js
@@ -1,33 +1,33 @@
-import Dict from './Dict'
-import { mergeOptions } from './DictOptions'
-
-export default function(Vue, options) {
- mergeOptions(options)
- Vue.mixin({
- data() {
- if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) {
- return {}
- }
- const dict = new Dict()
- dict.owner = this
- return {
- dict
- }
- },
- created() {
- if (!(this.dict instanceof Dict)) {
- return
- }
- options.onCreated && options.onCreated(this.dict)
- this.dict.init(this.$options.dicts).then(() => {
- options.onReady && options.onReady(this.dict)
- this.$nextTick(() => {
- this.$emit('dictReady', this.dict)
- if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
- this.$options.methods.onDictReady.call(this, this.dict)
- }
- })
- })
- },
- })
-}
+import Dict from './Dict'
+import { mergeOptions } from './DictOptions'
+
+export default function(Vue, options) {
+ mergeOptions(options)
+ Vue.mixin({
+ data() {
+ if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) {
+ return {}
+ }
+ const dict = new Dict()
+ dict.owner = this
+ return {
+ dict
+ }
+ },
+ created() {
+ if (!(this.dict instanceof Dict)) {
+ return
+ }
+ options.onCreated && options.onCreated(this.dict)
+ this.dict.init(this.$options.dicts).then(() => {
+ options.onReady && options.onReady(this.dict)
+ this.$nextTick(() => {
+ this.$emit('dictReady', this.dict)
+ if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
+ this.$options.methods.onDictReady.call(this, this.dict)
+ }
+ })
+ })
+ },
+ })
+}
diff --git a/ruoyi-ui/src/utils/generator/config.js b/ruoyi-ui/src/utils/generator/config.js
index 005140a..7abf227 100644
--- a/ruoyi-ui/src/utils/generator/config.js
+++ b/ruoyi-ui/src/utils/generator/config.js
@@ -1,438 +1,438 @@
-export const formConf = {
- formRef: 'elForm',
- formModel: 'formData',
- size: 'medium',
- labelPosition: 'right',
- labelWidth: 100,
- formRules: 'rules',
- gutter: 15,
- disabled: false,
- span: 24,
- formBtns: true
-}
-
-export const inputComponents = [
- {
- label: '单行文本',
- tag: 'el-input',
- tagIcon: 'input',
- placeholder: '请输入',
- defaultValue: undefined,
- span: 24,
- labelWidth: null,
- style: { width: '100%' },
- clearable: true,
- prepend: '',
- append: '',
- 'prefix-icon': '',
- 'suffix-icon': '',
- maxlength: null,
- 'show-word-limit': false,
- readonly: false,
- disabled: false,
- required: true,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/input'
- },
- {
- label: '多行文本',
- tag: 'el-input',
- tagIcon: 'textarea',
- type: 'textarea',
- placeholder: '请输入',
- defaultValue: undefined,
- span: 24,
- labelWidth: null,
- autosize: {
- minRows: 4,
- maxRows: 4
- },
- style: { width: '100%' },
- maxlength: null,
- 'show-word-limit': false,
- readonly: false,
- disabled: false,
- required: true,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/input'
- },
- {
- label: '密码',
- tag: 'el-input',
- tagIcon: 'password',
- placeholder: '请输入',
- defaultValue: undefined,
- span: 24,
- 'show-password': true,
- labelWidth: null,
- style: { width: '100%' },
- clearable: true,
- prepend: '',
- append: '',
- 'prefix-icon': '',
- 'suffix-icon': '',
- maxlength: null,
- 'show-word-limit': false,
- readonly: false,
- disabled: false,
- required: true,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/input'
- },
- {
- label: '计数器',
- tag: 'el-input-number',
- tagIcon: 'number',
- placeholder: '',
- defaultValue: undefined,
- span: 24,
- labelWidth: null,
- min: undefined,
- max: undefined,
- step: undefined,
- 'step-strictly': false,
- precision: undefined,
- 'controls-position': '',
- disabled: false,
- required: true,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
- }
-]
-
-export const selectComponents = [
- {
- label: '下拉选择',
- tag: 'el-select',
- tagIcon: 'select',
- placeholder: '请选择',
- defaultValue: undefined,
- span: 24,
- labelWidth: null,
- style: { width: '100%' },
- clearable: true,
- disabled: false,
- required: true,
- filterable: false,
- multiple: false,
- options: [{
- label: '选项一',
- value: 1
- }, {
- label: '选项二',
- value: 2
- }],
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/select'
- },
- {
- label: '级联选择',
- tag: 'el-cascader',
- tagIcon: 'cascader',
- placeholder: '请选择',
- defaultValue: [],
- span: 24,
- labelWidth: null,
- style: { width: '100%' },
- props: {
- props: {
- multiple: false
- }
- },
- 'show-all-levels': true,
- disabled: false,
- clearable: true,
- filterable: false,
- required: true,
- options: [{
- id: 1,
- value: 1,
- label: '选项1',
- children: [{
- id: 2,
- value: 2,
- label: '选项1-1'
- }]
- }],
- dataType: 'dynamic',
- labelKey: 'label',
- valueKey: 'value',
- childrenKey: 'children',
- separator: '/',
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/cascader'
- },
- {
- label: '单选框组',
- tag: 'el-radio-group',
- tagIcon: 'radio',
- defaultValue: undefined,
- span: 24,
- labelWidth: null,
- style: {},
- optionType: 'default',
- border: false,
- size: 'medium',
- disabled: false,
- required: true,
- options: [{
- label: '选项一',
- value: 1
- }, {
- label: '选项二',
- value: 2
- }],
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/radio'
- },
- {
- label: '多选框组',
- tag: 'el-checkbox-group',
- tagIcon: 'checkbox',
- defaultValue: [],
- span: 24,
- labelWidth: null,
- style: {},
- optionType: 'default',
- border: false,
- size: 'medium',
- disabled: false,
- required: true,
- options: [{
- label: '选项一',
- value: 1
- }, {
- label: '选项二',
- value: 2
- }],
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/checkbox'
- },
- {
- label: '开关',
- tag: 'el-switch',
- tagIcon: 'switch',
- defaultValue: false,
- span: 24,
- labelWidth: null,
- style: {},
- disabled: false,
- required: true,
- 'active-text': '',
- 'inactive-text': '',
- 'active-color': null,
- 'inactive-color': null,
- 'active-value': true,
- 'inactive-value': false,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/switch'
- },
- {
- label: '滑块',
- tag: 'el-slider',
- tagIcon: 'slider',
- defaultValue: null,
- span: 24,
- labelWidth: null,
- disabled: false,
- required: true,
- min: 0,
- max: 100,
- step: 1,
- 'show-stops': false,
- range: false,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/slider'
- },
- {
- label: '时间选择',
- tag: 'el-time-picker',
- tagIcon: 'time',
- placeholder: '请选择',
- defaultValue: null,
- span: 24,
- labelWidth: null,
- style: { width: '100%' },
- disabled: false,
- clearable: true,
- required: true,
- 'picker-options': {
- selectableRange: '00:00:00-23:59:59'
- },
- format: 'HH:mm:ss',
- 'value-format': 'HH:mm:ss',
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
- },
- {
- label: '时间范围',
- tag: 'el-time-picker',
- tagIcon: 'time-range',
- defaultValue: null,
- span: 24,
- labelWidth: null,
- style: { width: '100%' },
- disabled: false,
- clearable: true,
- required: true,
- 'is-range': true,
- 'range-separator': '至',
- 'start-placeholder': '开始时间',
- 'end-placeholder': '结束时间',
- format: 'HH:mm:ss',
- 'value-format': 'HH:mm:ss',
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
- },
- {
- label: '日期选择',
- tag: 'el-date-picker',
- tagIcon: 'date',
- placeholder: '请选择',
- defaultValue: null,
- type: 'date',
- span: 24,
- labelWidth: null,
- style: { width: '100%' },
- disabled: false,
- clearable: true,
- required: true,
- format: 'yyyy-MM-dd',
- 'value-format': 'yyyy-MM-dd',
- readonly: false,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
- },
- {
- label: '日期范围',
- tag: 'el-date-picker',
- tagIcon: 'date-range',
- defaultValue: null,
- span: 24,
- labelWidth: null,
- style: { width: '100%' },
- type: 'daterange',
- 'range-separator': '至',
- 'start-placeholder': '开始日期',
- 'end-placeholder': '结束日期',
- disabled: false,
- clearable: true,
- required: true,
- format: 'yyyy-MM-dd',
- 'value-format': 'yyyy-MM-dd',
- readonly: false,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
- },
- {
- label: '评分',
- tag: 'el-rate',
- tagIcon: 'rate',
- defaultValue: 0,
- span: 24,
- labelWidth: null,
- style: {},
- max: 5,
- 'allow-half': false,
- 'show-text': false,
- 'show-score': false,
- disabled: false,
- required: true,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/rate'
- },
- {
- label: '颜色选择',
- tag: 'el-color-picker',
- tagIcon: 'color',
- defaultValue: null,
- labelWidth: null,
- 'show-alpha': false,
- 'color-format': '',
- disabled: false,
- required: true,
- size: 'medium',
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/color-picker'
- },
- {
- label: '上传',
- tag: 'el-upload',
- tagIcon: 'upload',
- action: 'https://jsonplaceholder.typicode.com/posts/',
- defaultValue: null,
- labelWidth: null,
- disabled: false,
- required: true,
- accept: '',
- name: 'file',
- 'auto-upload': true,
- showTip: false,
- buttonText: '点击上传',
- fileSize: 2,
- sizeUnit: 'MB',
- 'list-type': 'text',
- multiple: false,
- regList: [],
- changeTag: true,
- document: 'https://element.eleme.cn/#/zh-CN/component/upload'
- }
-]
-
-export const layoutComponents = [
- {
- layout: 'rowFormItem',
- tagIcon: 'row',
- type: 'default',
- justify: 'start',
- align: 'top',
- label: '行容器',
- layoutTree: true,
- children: [],
- document: 'https://element.eleme.cn/#/zh-CN/component/layout'
- },
- {
- layout: 'colFormItem',
- label: '按钮',
- changeTag: true,
- labelWidth: null,
- tag: 'el-button',
- tagIcon: 'button',
- span: 24,
- default: '主要按钮',
- type: 'primary',
- icon: 'el-icon-search',
- size: 'medium',
- disabled: false,
- document: 'https://element.eleme.cn/#/zh-CN/component/button'
- }
-]
-
-// 组件rule的触发方式,无触发方式的组件不生成rule
-export const trigger = {
- 'el-input': 'blur',
- 'el-input-number': 'blur',
- 'el-select': 'change',
- 'el-radio-group': 'change',
- 'el-checkbox-group': 'change',
- 'el-cascader': 'change',
- 'el-time-picker': 'change',
- 'el-date-picker': 'change',
- 'el-rate': 'change'
-}
+export const formConf = {
+ formRef: 'elForm',
+ formModel: 'formData',
+ size: 'medium',
+ labelPosition: 'right',
+ labelWidth: 100,
+ formRules: 'rules',
+ gutter: 15,
+ disabled: false,
+ span: 24,
+ formBtns: true
+}
+
+export const inputComponents = [
+ {
+ label: '单行文本',
+ tag: 'el-input',
+ tagIcon: 'input',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': '',
+ 'suffix-icon': '',
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '多行文本',
+ tag: 'el-input',
+ tagIcon: 'textarea',
+ type: 'textarea',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ autosize: {
+ minRows: 4,
+ maxRows: 4
+ },
+ style: { width: '100%' },
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '密码',
+ tag: 'el-input',
+ tagIcon: 'password',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ 'show-password': true,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': '',
+ 'suffix-icon': '',
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '计数器',
+ tag: 'el-input-number',
+ tagIcon: 'number',
+ placeholder: '',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ min: undefined,
+ max: undefined,
+ step: undefined,
+ 'step-strictly': false,
+ precision: undefined,
+ 'controls-position': '',
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
+ }
+]
+
+export const selectComponents = [
+ {
+ label: '下拉选择',
+ tag: 'el-select',
+ tagIcon: 'select',
+ placeholder: '请选择',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ disabled: false,
+ required: true,
+ filterable: false,
+ multiple: false,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/select'
+ },
+ {
+ label: '级联选择',
+ tag: 'el-cascader',
+ tagIcon: 'cascader',
+ placeholder: '请选择',
+ defaultValue: [],
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ props: {
+ props: {
+ multiple: false
+ }
+ },
+ 'show-all-levels': true,
+ disabled: false,
+ clearable: true,
+ filterable: false,
+ required: true,
+ options: [{
+ id: 1,
+ value: 1,
+ label: '选项1',
+ children: [{
+ id: 2,
+ value: 2,
+ label: '选项1-1'
+ }]
+ }],
+ dataType: 'dynamic',
+ labelKey: 'label',
+ valueKey: 'value',
+ childrenKey: 'children',
+ separator: '/',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/cascader'
+ },
+ {
+ label: '单选框组',
+ tag: 'el-radio-group',
+ tagIcon: 'radio',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ optionType: 'default',
+ border: false,
+ size: 'medium',
+ disabled: false,
+ required: true,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/radio'
+ },
+ {
+ label: '多选框组',
+ tag: 'el-checkbox-group',
+ tagIcon: 'checkbox',
+ defaultValue: [],
+ span: 24,
+ labelWidth: null,
+ style: {},
+ optionType: 'default',
+ border: false,
+ size: 'medium',
+ disabled: false,
+ required: true,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/checkbox'
+ },
+ {
+ label: '开关',
+ tag: 'el-switch',
+ tagIcon: 'switch',
+ defaultValue: false,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ disabled: false,
+ required: true,
+ 'active-text': '',
+ 'inactive-text': '',
+ 'active-color': null,
+ 'inactive-color': null,
+ 'active-value': true,
+ 'inactive-value': false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/switch'
+ },
+ {
+ label: '滑块',
+ tag: 'el-slider',
+ tagIcon: 'slider',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ disabled: false,
+ required: true,
+ min: 0,
+ max: 100,
+ step: 1,
+ 'show-stops': false,
+ range: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/slider'
+ },
+ {
+ label: '时间选择',
+ tag: 'el-time-picker',
+ tagIcon: 'time',
+ placeholder: '请选择',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ 'picker-options': {
+ selectableRange: '00:00:00-23:59:59'
+ },
+ format: 'HH:mm:ss',
+ 'value-format': 'HH:mm:ss',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
+ },
+ {
+ label: '时间范围',
+ tag: 'el-time-picker',
+ tagIcon: 'time-range',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ 'is-range': true,
+ 'range-separator': '至',
+ 'start-placeholder': '开始时间',
+ 'end-placeholder': '结束时间',
+ format: 'HH:mm:ss',
+ 'value-format': 'HH:mm:ss',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
+ },
+ {
+ label: '日期选择',
+ tag: 'el-date-picker',
+ tagIcon: 'date',
+ placeholder: '请选择',
+ defaultValue: null,
+ type: 'date',
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ format: 'yyyy-MM-dd',
+ 'value-format': 'yyyy-MM-dd',
+ readonly: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
+ },
+ {
+ label: '日期范围',
+ tag: 'el-date-picker',
+ tagIcon: 'date-range',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ type: 'daterange',
+ 'range-separator': '至',
+ 'start-placeholder': '开始日期',
+ 'end-placeholder': '结束日期',
+ disabled: false,
+ clearable: true,
+ required: true,
+ format: 'yyyy-MM-dd',
+ 'value-format': 'yyyy-MM-dd',
+ readonly: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
+ },
+ {
+ label: '评分',
+ tag: 'el-rate',
+ tagIcon: 'rate',
+ defaultValue: 0,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ max: 5,
+ 'allow-half': false,
+ 'show-text': false,
+ 'show-score': false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/rate'
+ },
+ {
+ label: '颜色选择',
+ tag: 'el-color-picker',
+ tagIcon: 'color',
+ defaultValue: null,
+ labelWidth: null,
+ 'show-alpha': false,
+ 'color-format': '',
+ disabled: false,
+ required: true,
+ size: 'medium',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/color-picker'
+ },
+ {
+ label: '上传',
+ tag: 'el-upload',
+ tagIcon: 'upload',
+ action: 'https://jsonplaceholder.typicode.com/posts/',
+ defaultValue: null,
+ labelWidth: null,
+ disabled: false,
+ required: true,
+ accept: '',
+ name: 'file',
+ 'auto-upload': true,
+ showTip: false,
+ buttonText: '点击上传',
+ fileSize: 2,
+ sizeUnit: 'MB',
+ 'list-type': 'text',
+ multiple: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/upload'
+ }
+]
+
+export const layoutComponents = [
+ {
+ layout: 'rowFormItem',
+ tagIcon: 'row',
+ type: 'default',
+ justify: 'start',
+ align: 'top',
+ label: '行容器',
+ layoutTree: true,
+ children: [],
+ document: 'https://element.eleme.cn/#/zh-CN/component/layout'
+ },
+ {
+ layout: 'colFormItem',
+ label: '按钮',
+ changeTag: true,
+ labelWidth: null,
+ tag: 'el-button',
+ tagIcon: 'button',
+ span: 24,
+ default: '主要按钮',
+ type: 'primary',
+ icon: 'el-icon-search',
+ size: 'medium',
+ disabled: false,
+ document: 'https://element.eleme.cn/#/zh-CN/component/button'
+ }
+]
+
+// 组件rule的触发方式,无触发方式的组件不生成rule
+export const trigger = {
+ 'el-input': 'blur',
+ 'el-input-number': 'blur',
+ 'el-select': 'change',
+ 'el-radio-group': 'change',
+ 'el-checkbox-group': 'change',
+ 'el-cascader': 'change',
+ 'el-time-picker': 'change',
+ 'el-date-picker': 'change',
+ 'el-rate': 'change'
+}
diff --git a/ruoyi-ui/src/utils/generator/css.js b/ruoyi-ui/src/utils/generator/css.js
index 0d7f075..c1c62e6 100644
--- a/ruoyi-ui/src/utils/generator/css.js
+++ b/ruoyi-ui/src/utils/generator/css.js
@@ -1,18 +1,18 @@
-const styles = {
- 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
- 'el-upload': '.el-upload__tip{line-height: 1.2;}'
-}
-
-function addCss(cssList, el) {
- const css = styles[el.tag]
- css && cssList.indexOf(css) === -1 && cssList.push(css)
- if (el.children) {
- el.children.forEach(el2 => addCss(cssList, el2))
- }
-}
-
-export function makeUpCss(conf) {
- const cssList = []
- conf.fields.forEach(el => addCss(cssList, el))
- return cssList.join('\n')
-}
+const styles = {
+ 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
+ 'el-upload': '.el-upload__tip{line-height: 1.2;}'
+}
+
+function addCss(cssList, el) {
+ const css = styles[el.tag]
+ css && cssList.indexOf(css) === -1 && cssList.push(css)
+ if (el.children) {
+ el.children.forEach(el2 => addCss(cssList, el2))
+ }
+}
+
+export function makeUpCss(conf) {
+ const cssList = []
+ conf.fields.forEach(el => addCss(cssList, el))
+ return cssList.join('\n')
+}
diff --git a/ruoyi-ui/src/utils/generator/render.js b/ruoyi-ui/src/utils/generator/render.js
index f187029..e8640f0 100644
--- a/ruoyi-ui/src/utils/generator/render.js
+++ b/ruoyi-ui/src/utils/generator/render.js
@@ -1,126 +1,126 @@
-import { makeMap } from '@/utils/index'
-
-// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js
-const isAttr = makeMap(
- 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,'
- + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,'
- + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,'
- + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,'
- + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,'
- + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,'
- + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,'
- + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,'
- + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,'
- + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,'
- + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,'
- + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,'
- + 'target,title,type,usemap,value,width,wrap'
-)
-
-function vModel(self, dataObject, defaultValue) {
- dataObject.props.value = defaultValue
-
- dataObject.on.input = val => {
- self.$emit('input', val)
- }
-}
-
-const componentChild = {
- 'el-button': {
- default(h, conf, key) {
- return conf[key]
- },
- },
- 'el-input': {
- prepend(h, conf, key) {
- return {conf[key]}
- },
- append(h, conf, key) {
- return {conf[key]}
- }
- },
- 'el-select': {
- options(h, conf, key) {
- const list = []
- conf.options.forEach(item => {
- list.push()
- })
- return list
- }
- },
- 'el-radio-group': {
- options(h, conf, key) {
- const list = []
- conf.options.forEach(item => {
- if (conf.optionType === 'button') list.push({item.label})
- else list.push({item.label})
- })
- return list
- }
- },
- 'el-checkbox-group': {
- options(h, conf, key) {
- const list = []
- conf.options.forEach(item => {
- if (conf.optionType === 'button') {
- list.push({item.label})
- } else {
- list.push({item.label})
- }
- })
- return list
- }
- },
- 'el-upload': {
- 'list-type': (h, conf, key) => {
- const list = []
- if (conf['list-type'] === 'picture-card') {
- list.push()
- } else {
- list.push({conf.buttonText})
- }
- if (conf.showTip) {
- list.push(只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件
)
- }
- return list
- }
- }
-}
-
-export default {
- render(h) {
- const dataObject = {
- attrs: {},
- props: {},
- on: {},
- style: {}
- }
- const confClone = JSON.parse(JSON.stringify(this.conf))
- const children = []
-
- const childObjs = componentChild[confClone.tag]
- if (childObjs) {
- Object.keys(childObjs).forEach(key => {
- const childFunc = childObjs[key]
- if (confClone[key]) {
- children.push(childFunc(h, confClone, key))
- }
- })
- }
-
- Object.keys(confClone).forEach(key => {
- const val = confClone[key]
- if (key === 'vModel') {
- vModel(this, dataObject, confClone.defaultValue)
- } else if (dataObject[key]) {
- dataObject[key] = val
- } else if (!isAttr(key)) {
- dataObject.props[key] = val
- } else {
- dataObject.attrs[key] = val
- }
- })
- return h(this.conf.tag, dataObject, children)
- },
- props: ['conf']
-}
+import { makeMap } from '@/utils/index'
+
+// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js
+const isAttr = makeMap(
+ 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,'
+ + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,'
+ + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,'
+ + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,'
+ + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,'
+ + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,'
+ + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,'
+ + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,'
+ + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,'
+ + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,'
+ + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,'
+ + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,'
+ + 'target,title,type,usemap,value,width,wrap'
+)
+
+function vModel(self, dataObject, defaultValue) {
+ dataObject.props.value = defaultValue
+
+ dataObject.on.input = val => {
+ self.$emit('input', val)
+ }
+}
+
+const componentChild = {
+ 'el-button': {
+ default(h, conf, key) {
+ return conf[key]
+ },
+ },
+ 'el-input': {
+ prepend(h, conf, key) {
+ return {conf[key]}
+ },
+ append(h, conf, key) {
+ return {conf[key]}
+ }
+ },
+ 'el-select': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ list.push()
+ })
+ return list
+ }
+ },
+ 'el-radio-group': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ if (conf.optionType === 'button') list.push({item.label})
+ else list.push({item.label})
+ })
+ return list
+ }
+ },
+ 'el-checkbox-group': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ if (conf.optionType === 'button') {
+ list.push({item.label})
+ } else {
+ list.push({item.label})
+ }
+ })
+ return list
+ }
+ },
+ 'el-upload': {
+ 'list-type': (h, conf, key) => {
+ const list = []
+ if (conf['list-type'] === 'picture-card') {
+ list.push()
+ } else {
+ list.push({conf.buttonText})
+ }
+ if (conf.showTip) {
+ list.push(只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件
)
+ }
+ return list
+ }
+ }
+}
+
+export default {
+ render(h) {
+ const dataObject = {
+ attrs: {},
+ props: {},
+ on: {},
+ style: {}
+ }
+ const confClone = JSON.parse(JSON.stringify(this.conf))
+ const children = []
+
+ const childObjs = componentChild[confClone.tag]
+ if (childObjs) {
+ Object.keys(childObjs).forEach(key => {
+ const childFunc = childObjs[key]
+ if (confClone[key]) {
+ children.push(childFunc(h, confClone, key))
+ }
+ })
+ }
+
+ Object.keys(confClone).forEach(key => {
+ const val = confClone[key]
+ if (key === 'vModel') {
+ vModel(this, dataObject, confClone.defaultValue)
+ } else if (dataObject[key]) {
+ dataObject[key] = val
+ } else if (!isAttr(key)) {
+ dataObject.props[key] = val
+ } else {
+ dataObject.attrs[key] = val
+ }
+ })
+ return h(this.conf.tag, dataObject, children)
+ },
+ props: ['conf']
+}
diff --git a/ruoyi-ui/src/utils/index.js b/ruoyi-ui/src/utils/index.js
index cac28dc..9375db7 100644
--- a/ruoyi-ui/src/utils/index.js
+++ b/ruoyi-ui/src/utils/index.js
@@ -1,390 +1,390 @@
-import { parseTime } from './ruoyi'
-
-/**
- * 表格时间格式化
- */
-export function formatDate(cellValue) {
- if (cellValue == null || cellValue == "") return ""
- var date = new Date(cellValue)
- var year = date.getFullYear()
- var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
- var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
- var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
- var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
- var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
- return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
-}
-
-/**
- * @param {number} time
- * @param {string} option
- * @returns {string}
- */
-export function formatTime(time, option) {
- if (('' + time).length === 10) {
- time = parseInt(time) * 1000
- } else {
- time = +time
- }
- const d = new Date(time)
- const now = Date.now()
-
- const diff = (now - d) / 1000
-
- if (diff < 30) {
- return '刚刚'
- } else if (diff < 3600) {
- // less 1 hour
- return Math.ceil(diff / 60) + '分钟前'
- } else if (diff < 3600 * 24) {
- return Math.ceil(diff / 3600) + '小时前'
- } else if (diff < 3600 * 24 * 2) {
- return '1天前'
- }
- if (option) {
- return parseTime(time, option)
- } else {
- return (
- d.getMonth() +
- 1 +
- '月' +
- d.getDate() +
- '日' +
- d.getHours() +
- '时' +
- d.getMinutes() +
- '分'
- )
- }
-}
-
-/**
- * @param {string} url
- * @returns {Object}
- */
-export function getQueryObject(url) {
- url = url == null ? window.location.href : url
- const search = url.substring(url.lastIndexOf('?') + 1)
- const obj = {}
- const reg = /([^?&=]+)=([^?&=]*)/g
- search.replace(reg, (rs, $1, $2) => {
- const name = decodeURIComponent($1)
- let val = decodeURIComponent($2)
- val = String(val)
- obj[name] = val
- return rs
- })
- return obj
-}
-
-/**
- * @param {string} input value
- * @returns {number} output value
- */
-export function byteLength(str) {
- // returns the byte length of an utf8 string
- let s = str.length
- for (var i = str.length - 1; i >= 0; i--) {
- const code = str.charCodeAt(i)
- if (code > 0x7f && code <= 0x7ff) s++
- else if (code > 0x7ff && code <= 0xffff) s += 2
- if (code >= 0xDC00 && code <= 0xDFFF) i--
- }
- return s
-}
-
-/**
- * @param {Array} actual
- * @returns {Array}
- */
-export function cleanArray(actual) {
- const newArray = []
- for (let i = 0; i < actual.length; i++) {
- if (actual[i]) {
- newArray.push(actual[i])
- }
- }
- return newArray
-}
-
-/**
- * @param {Object} json
- * @returns {Array}
- */
-export function param(json) {
- if (!json) return ''
- return cleanArray(
- Object.keys(json).map(key => {
- if (json[key] === undefined) return ''
- return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
- })
- ).join('&')
-}
-
-/**
- * @param {string} url
- * @returns {Object}
- */
-export function param2Obj(url) {
- const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
- if (!search) {
- return {}
- }
- const obj = {}
- const searchArr = search.split('&')
- searchArr.forEach(v => {
- const index = v.indexOf('=')
- if (index !== -1) {
- const name = v.substring(0, index)
- const val = v.substring(index + 1, v.length)
- obj[name] = val
- }
- })
- return obj
-}
-
-/**
- * @param {string} val
- * @returns {string}
- */
-export function html2Text(val) {
- const div = document.createElement('div')
- div.innerHTML = val
- return div.textContent || div.innerText
-}
-
-/**
- * Merges two objects, giving the last one precedence
- * @param {Object} target
- * @param {(Object|Array)} source
- * @returns {Object}
- */
-export function objectMerge(target, source) {
- if (typeof target !== 'object') {
- target = {}
- }
- if (Array.isArray(source)) {
- return source.slice()
- }
- Object.keys(source).forEach(property => {
- const sourceProperty = source[property]
- if (typeof sourceProperty === 'object') {
- target[property] = objectMerge(target[property], sourceProperty)
- } else {
- target[property] = sourceProperty
- }
- })
- return target
-}
-
-/**
- * @param {HTMLElement} element
- * @param {string} className
- */
-export function toggleClass(element, className) {
- if (!element || !className) {
- return
- }
- let classString = element.className
- const nameIndex = classString.indexOf(className)
- if (nameIndex === -1) {
- classString += '' + className
- } else {
- classString =
- classString.substr(0, nameIndex) +
- classString.substr(nameIndex + className.length)
- }
- element.className = classString
-}
-
-/**
- * @param {string} type
- * @returns {Date}
- */
-export function getTime(type) {
- if (type === 'start') {
- return new Date().getTime() - 3600 * 1000 * 24 * 90
- } else {
- return new Date(new Date().toDateString())
- }
-}
-
-/**
- * @param {Function} func
- * @param {number} wait
- * @param {boolean} immediate
- * @return {*}
- */
-export function debounce(func, wait, immediate) {
- let timeout, args, context, timestamp, result
-
- const later = function() {
- // 据上一次触发时间间隔
- const last = +new Date() - timestamp
-
- // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
- if (last < wait && last > 0) {
- timeout = setTimeout(later, wait - last)
- } else {
- timeout = null
- // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
- if (!immediate) {
- result = func.apply(context, args)
- if (!timeout) context = args = null
- }
- }
- }
-
- return function(...args) {
- context = this
- timestamp = +new Date()
- const callNow = immediate && !timeout
- // 如果延时不存在,重新设定延时
- if (!timeout) timeout = setTimeout(later, wait)
- if (callNow) {
- result = func.apply(context, args)
- context = args = null
- }
-
- return result
- }
-}
-
-/**
- * This is just a simple version of deep copy
- * Has a lot of edge cases bug
- * If you want to use a perfect deep copy, use lodash's _.cloneDeep
- * @param {Object} source
- * @returns {Object}
- */
-export function deepClone(source) {
- if (!source && typeof source !== 'object') {
- throw new Error('error arguments', 'deepClone')
- }
- const targetObj = source.constructor === Array ? [] : {}
- Object.keys(source).forEach(keys => {
- if (source[keys] && typeof source[keys] === 'object') {
- targetObj[keys] = deepClone(source[keys])
- } else {
- targetObj[keys] = source[keys]
- }
- })
- return targetObj
-}
-
-/**
- * @param {Array} arr
- * @returns {Array}
- */
-export function uniqueArr(arr) {
- return Array.from(new Set(arr))
-}
-
-/**
- * @returns {string}
- */
-export function createUniqueString() {
- const timestamp = +new Date() + ''
- const randomNum = parseInt((1 + Math.random()) * 65536) + ''
- return (+(randomNum + timestamp)).toString(32)
-}
-
-/**
- * Check if an element has a class
- * @param {HTMLElement} elm
- * @param {string} cls
- * @returns {boolean}
- */
-export function hasClass(ele, cls) {
- return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
-}
-
-/**
- * Add class to element
- * @param {HTMLElement} elm
- * @param {string} cls
- */
-export function addClass(ele, cls) {
- if (!hasClass(ele, cls)) ele.className += ' ' + cls
-}
-
-/**
- * Remove class from element
- * @param {HTMLElement} elm
- * @param {string} cls
- */
-export function removeClass(ele, cls) {
- if (hasClass(ele, cls)) {
- const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
- ele.className = ele.className.replace(reg, ' ')
- }
-}
-
-export function makeMap(str, expectsLowerCase) {
- const map = Object.create(null)
- const list = str.split(',')
- for (let i = 0; i < list.length; i++) {
- map[list[i]] = true
- }
- return expectsLowerCase
- ? val => map[val.toLowerCase()]
- : val => map[val]
-}
-
-export const exportDefault = 'export default '
-
-export const beautifierConf = {
- html: {
- indent_size: '2',
- indent_char: ' ',
- max_preserve_newlines: '-1',
- preserve_newlines: false,
- keep_array_indentation: false,
- break_chained_methods: false,
- indent_scripts: 'separate',
- brace_style: 'end-expand',
- space_before_conditional: true,
- unescape_strings: false,
- jslint_happy: false,
- end_with_newline: true,
- wrap_line_length: '110',
- indent_inner_html: true,
- comma_first: false,
- e4x: true,
- indent_empty_lines: true
- },
- js: {
- indent_size: '2',
- indent_char: ' ',
- max_preserve_newlines: '-1',
- preserve_newlines: false,
- keep_array_indentation: false,
- break_chained_methods: false,
- indent_scripts: 'normal',
- brace_style: 'end-expand',
- space_before_conditional: true,
- unescape_strings: false,
- jslint_happy: true,
- end_with_newline: true,
- wrap_line_length: '110',
- indent_inner_html: true,
- comma_first: false,
- e4x: true,
- indent_empty_lines: true
- }
-}
-
-// 首字母大小
-export function titleCase(str) {
- return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
-}
-
-// 下划转驼峰
-export function camelCase(str) {
- return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
-}
-
-export function isNumberStr(str) {
- return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
-}
-
+import { parseTime } from './ruoyi'
+
+/**
+ * 表格时间格式化
+ */
+export function formatDate(cellValue) {
+ if (cellValue == null || cellValue == "") return ""
+ var date = new Date(cellValue)
+ var year = date.getFullYear()
+ var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
+ var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+ var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+ var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
+ var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
+ return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+}
+
+/**
+ * @param {number} time
+ * @param {string} option
+ * @returns {string}
+ */
+export function formatTime(time, option) {
+ if (('' + time).length === 10) {
+ time = parseInt(time) * 1000
+ } else {
+ time = +time
+ }
+ const d = new Date(time)
+ const now = Date.now()
+
+ const diff = (now - d) / 1000
+
+ if (diff < 30) {
+ return '刚刚'
+ } else if (diff < 3600) {
+ // less 1 hour
+ return Math.ceil(diff / 60) + '分钟前'
+ } else if (diff < 3600 * 24) {
+ return Math.ceil(diff / 3600) + '小时前'
+ } else if (diff < 3600 * 24 * 2) {
+ return '1天前'
+ }
+ if (option) {
+ return parseTime(time, option)
+ } else {
+ return (
+ d.getMonth() +
+ 1 +
+ '月' +
+ d.getDate() +
+ '日' +
+ d.getHours() +
+ '时' +
+ d.getMinutes() +
+ '分'
+ )
+ }
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function getQueryObject(url) {
+ url = url == null ? window.location.href : url
+ const search = url.substring(url.lastIndexOf('?') + 1)
+ const obj = {}
+ const reg = /([^?&=]+)=([^?&=]*)/g
+ search.replace(reg, (rs, $1, $2) => {
+ const name = decodeURIComponent($1)
+ let val = decodeURIComponent($2)
+ val = String(val)
+ obj[name] = val
+ return rs
+ })
+ return obj
+}
+
+/**
+ * @param {string} input value
+ * @returns {number} output value
+ */
+export function byteLength(str) {
+ // returns the byte length of an utf8 string
+ let s = str.length
+ for (var i = str.length - 1; i >= 0; i--) {
+ const code = str.charCodeAt(i)
+ if (code > 0x7f && code <= 0x7ff) s++
+ else if (code > 0x7ff && code <= 0xffff) s += 2
+ if (code >= 0xDC00 && code <= 0xDFFF) i--
+ }
+ return s
+}
+
+/**
+ * @param {Array} actual
+ * @returns {Array}
+ */
+export function cleanArray(actual) {
+ const newArray = []
+ for (let i = 0; i < actual.length; i++) {
+ if (actual[i]) {
+ newArray.push(actual[i])
+ }
+ }
+ return newArray
+}
+
+/**
+ * @param {Object} json
+ * @returns {Array}
+ */
+export function param(json) {
+ if (!json) return ''
+ return cleanArray(
+ Object.keys(json).map(key => {
+ if (json[key] === undefined) return ''
+ return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
+ })
+ ).join('&')
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function param2Obj(url) {
+ const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+ if (!search) {
+ return {}
+ }
+ const obj = {}
+ const searchArr = search.split('&')
+ searchArr.forEach(v => {
+ const index = v.indexOf('=')
+ if (index !== -1) {
+ const name = v.substring(0, index)
+ const val = v.substring(index + 1, v.length)
+ obj[name] = val
+ }
+ })
+ return obj
+}
+
+/**
+ * @param {string} val
+ * @returns {string}
+ */
+export function html2Text(val) {
+ const div = document.createElement('div')
+ div.innerHTML = val
+ return div.textContent || div.innerText
+}
+
+/**
+ * Merges two objects, giving the last one precedence
+ * @param {Object} target
+ * @param {(Object|Array)} source
+ * @returns {Object}
+ */
+export function objectMerge(target, source) {
+ if (typeof target !== 'object') {
+ target = {}
+ }
+ if (Array.isArray(source)) {
+ return source.slice()
+ }
+ Object.keys(source).forEach(property => {
+ const sourceProperty = source[property]
+ if (typeof sourceProperty === 'object') {
+ target[property] = objectMerge(target[property], sourceProperty)
+ } else {
+ target[property] = sourceProperty
+ }
+ })
+ return target
+}
+
+/**
+ * @param {HTMLElement} element
+ * @param {string} className
+ */
+export function toggleClass(element, className) {
+ if (!element || !className) {
+ return
+ }
+ let classString = element.className
+ const nameIndex = classString.indexOf(className)
+ if (nameIndex === -1) {
+ classString += '' + className
+ } else {
+ classString =
+ classString.substr(0, nameIndex) +
+ classString.substr(nameIndex + className.length)
+ }
+ element.className = classString
+}
+
+/**
+ * @param {string} type
+ * @returns {Date}
+ */
+export function getTime(type) {
+ if (type === 'start') {
+ return new Date().getTime() - 3600 * 1000 * 24 * 90
+ } else {
+ return new Date(new Date().toDateString())
+ }
+}
+
+/**
+ * @param {Function} func
+ * @param {number} wait
+ * @param {boolean} immediate
+ * @return {*}
+ */
+export function debounce(func, wait, immediate) {
+ let timeout, args, context, timestamp, result
+
+ const later = function() {
+ // 据上一次触发时间间隔
+ const last = +new Date() - timestamp
+
+ // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
+ if (last < wait && last > 0) {
+ timeout = setTimeout(later, wait - last)
+ } else {
+ timeout = null
+ // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
+ if (!immediate) {
+ result = func.apply(context, args)
+ if (!timeout) context = args = null
+ }
+ }
+ }
+
+ return function(...args) {
+ context = this
+ timestamp = +new Date()
+ const callNow = immediate && !timeout
+ // 如果延时不存在,重新设定延时
+ if (!timeout) timeout = setTimeout(later, wait)
+ if (callNow) {
+ result = func.apply(context, args)
+ context = args = null
+ }
+
+ return result
+ }
+}
+
+/**
+ * This is just a simple version of deep copy
+ * Has a lot of edge cases bug
+ * If you want to use a perfect deep copy, use lodash's _.cloneDeep
+ * @param {Object} source
+ * @returns {Object}
+ */
+export function deepClone(source) {
+ if (!source && typeof source !== 'object') {
+ throw new Error('error arguments', 'deepClone')
+ }
+ const targetObj = source.constructor === Array ? [] : {}
+ Object.keys(source).forEach(keys => {
+ if (source[keys] && typeof source[keys] === 'object') {
+ targetObj[keys] = deepClone(source[keys])
+ } else {
+ targetObj[keys] = source[keys]
+ }
+ })
+ return targetObj
+}
+
+/**
+ * @param {Array} arr
+ * @returns {Array}
+ */
+export function uniqueArr(arr) {
+ return Array.from(new Set(arr))
+}
+
+/**
+ * @returns {string}
+ */
+export function createUniqueString() {
+ const timestamp = +new Date() + ''
+ const randomNum = parseInt((1 + Math.random()) * 65536) + ''
+ return (+(randomNum + timestamp)).toString(32)
+}
+
+/**
+ * Check if an element has a class
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ * @returns {boolean}
+ */
+export function hasClass(ele, cls) {
+ return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
+}
+
+/**
+ * Add class to element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function addClass(ele, cls) {
+ if (!hasClass(ele, cls)) ele.className += ' ' + cls
+}
+
+/**
+ * Remove class from element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function removeClass(ele, cls) {
+ if (hasClass(ele, cls)) {
+ const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
+ ele.className = ele.className.replace(reg, ' ')
+ }
+}
+
+export function makeMap(str, expectsLowerCase) {
+ const map = Object.create(null)
+ const list = str.split(',')
+ for (let i = 0; i < list.length; i++) {
+ map[list[i]] = true
+ }
+ return expectsLowerCase
+ ? val => map[val.toLowerCase()]
+ : val => map[val]
+}
+
+export const exportDefault = 'export default '
+
+export const beautifierConf = {
+ html: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'separate',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: false,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ },
+ js: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'normal',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: true,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ }
+}
+
+// 首字母大小
+export function titleCase(str) {
+ return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
+}
+
+// 下划转驼峰
+export function camelCase(str) {
+ return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
+}
+
+export function isNumberStr(str) {
+ return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
+}
+
diff --git a/ruoyi-ui/src/utils/permission.js b/ruoyi-ui/src/utils/permission.js
index 070d6b8..0263bbc 100644
--- a/ruoyi-ui/src/utils/permission.js
+++ b/ruoyi-ui/src/utils/permission.js
@@ -1,47 +1,47 @@
-import store from '@/store'
-
-/**
- * 字符权限校验
- * @param {Array} value 校验值
- * @returns {Boolean}
- */
-export function checkPermi(value) {
- if (value && value instanceof Array && value.length > 0) {
- const permissions = store.getters && store.getters.permissions
- const permissionDatas = value
- const all_permission = "*:*:*"
-
- const hasPermission = permissions.some(permission => {
- return all_permission === permission || permissionDatas.includes(permission)
- })
-
- return hasPermission
-
- } else {
- console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
- return false
- }
-}
-
-/**
- * 角色权限校验
- * @param {Array} value 校验值
- * @returns {Boolean}
- */
-export function checkRole(value) {
- if (value && value instanceof Array && value.length > 0) {
- const roles = store.getters && store.getters.roles
- const permissionRoles = value
- const super_admin = "admin"
-
- const hasRole = roles.some(role => {
- return super_admin === role || permissionRoles.includes(role)
- })
-
- return hasRole
-
- } else {
- console.error(`need roles! Like checkRole="['admin','editor']"`)
- return false
- }
+import store from '@/store'
+
+/**
+ * 字符权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkPermi(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const permissions = store.getters && store.getters.permissions
+ const permissionDatas = value
+ const all_permission = "*:*:*"
+
+ const hasPermission = permissions.some(permission => {
+ return all_permission === permission || permissionDatas.includes(permission)
+ })
+
+ return hasPermission
+
+ } else {
+ console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
+ return false
+ }
+}
+
+/**
+ * 角色权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkRole(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const roles = store.getters && store.getters.roles
+ const permissionRoles = value
+ const super_admin = "admin"
+
+ const hasRole = roles.some(role => {
+ return super_admin === role || permissionRoles.includes(role)
+ })
+
+ return hasRole
+
+ } else {
+ console.error(`need roles! Like checkRole="['admin','editor']"`)
+ return false
+ }
}
\ No newline at end of file
diff --git a/ruoyi-ui/src/utils/scroll-to.js b/ruoyi-ui/src/utils/scroll-to.js
index 709fa57..c5d8e04 100644
--- a/ruoyi-ui/src/utils/scroll-to.js
+++ b/ruoyi-ui/src/utils/scroll-to.js
@@ -1,58 +1,58 @@
-Math.easeInOutQuad = function(t, b, c, d) {
- t /= d / 2
- if (t < 1) {
- return c / 2 * t * t + b
- }
- t--
- return -c / 2 * (t * (t - 2) - 1) + b
-}
-
-// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
-var requestAnimFrame = (function() {
- return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
-})()
-
-/**
- * Because it's so fucking difficult to detect the scrolling element, just move them all
- * @param {number} amount
- */
-function move(amount) {
- document.documentElement.scrollTop = amount
- document.body.parentNode.scrollTop = amount
- document.body.scrollTop = amount
-}
-
-function position() {
- return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
-}
-
-/**
- * @param {number} to
- * @param {number} duration
- * @param {Function} callback
- */
-export function scrollTo(to, duration, callback) {
- const start = position()
- const change = to - start
- const increment = 20
- let currentTime = 0
- duration = (typeof (duration) === 'undefined') ? 500 : duration
- var animateScroll = function() {
- // increment the time
- currentTime += increment
- // find the value with the quadratic in-out easing function
- var val = Math.easeInOutQuad(currentTime, start, change, duration)
- // move the document.body
- move(val)
- // do the animation unless its over
- if (currentTime < duration) {
- requestAnimFrame(animateScroll)
- } else {
- if (callback && typeof (callback) === 'function') {
- // the animation is done so lets callback
- callback()
- }
- }
- }
- animateScroll()
-}
+Math.easeInOutQuad = function(t, b, c, d) {
+ t /= d / 2
+ if (t < 1) {
+ return c / 2 * t * t + b
+ }
+ t--
+ return -c / 2 * (t * (t - 2) - 1) + b
+}
+
+// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
+var requestAnimFrame = (function() {
+ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
+})()
+
+/**
+ * Because it's so fucking difficult to detect the scrolling element, just move them all
+ * @param {number} amount
+ */
+function move(amount) {
+ document.documentElement.scrollTop = amount
+ document.body.parentNode.scrollTop = amount
+ document.body.scrollTop = amount
+}
+
+function position() {
+ return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
+}
+
+/**
+ * @param {number} to
+ * @param {number} duration
+ * @param {Function} callback
+ */
+export function scrollTo(to, duration, callback) {
+ const start = position()
+ const change = to - start
+ const increment = 20
+ let currentTime = 0
+ duration = (typeof (duration) === 'undefined') ? 500 : duration
+ var animateScroll = function() {
+ // increment the time
+ currentTime += increment
+ // find the value with the quadratic in-out easing function
+ var val = Math.easeInOutQuad(currentTime, start, change, duration)
+ // move the document.body
+ move(val)
+ // do the animation unless its over
+ if (currentTime < duration) {
+ requestAnimFrame(animateScroll)
+ } else {
+ if (callback && typeof (callback) === 'function') {
+ // the animation is done so lets callback
+ callback()
+ }
+ }
+ }
+ animateScroll()
+}
diff --git a/ruoyi-ui/src/utils/validate.js b/ruoyi-ui/src/utils/validate.js
index 13b7a15..6a4c0c5 100644
--- a/ruoyi-ui/src/utils/validate.js
+++ b/ruoyi-ui/src/utils/validate.js
@@ -1,114 +1,114 @@
-/**
- * 路径匹配器
- * @param {string} pattern
- * @param {string} path
- * @returns {Boolean}
- */
-export function isPathMatch(pattern, path) {
- const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*\*/g, '.*').replace(/\*/g, '[^\\/]*')
- const regex = new RegExp(`^${regexPattern}$`)
- return regex.test(path)
-}
-
-/**
- * 判断value字符串是否为空
- * @param {string} value
- * @returns {Boolean}
- */
-export function isEmpty(value) {
- if (value == null || value == "" || value == undefined || value == "undefined") {
- return true
- }
- return false
-}
-
-/**
- * 判断url是否是http或https
- * @param {string} url
- * @returns {Boolean}
- */
-export function isHttp(url) {
- return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
-}
-
-/**
- * 判断path是否为外链
- * @param {string} path
- * @returns {Boolean}
- */
-export function isExternal(path) {
- return /^(https?:|mailto:|tel:)/.test(path)
-}
-
-/**
- * @param {string} str
- * @returns {Boolean}
- */
-export function validUsername(str) {
- const valid_map = ['admin', 'editor']
- return valid_map.indexOf(str.trim()) >= 0
-}
-
-/**
- * @param {string} url
- * @returns {Boolean}
- */
-export function validURL(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.,?'\\+&%$#=~_-]+))*$/
- return reg.test(url)
-}
-
-/**
- * @param {string} str
- * @returns {Boolean}
- */
-export function validLowerCase(str) {
- const reg = /^[a-z]+$/
- return reg.test(str)
-}
-
-/**
- * @param {string} str
- * @returns {Boolean}
- */
-export function validUpperCase(str) {
- const reg = /^[A-Z]+$/
- return reg.test(str)
-}
-
-/**
- * @param {string} str
- * @returns {Boolean}
- */
-export function validAlphabets(str) {
- const reg = /^[A-Za-z]+$/
- return reg.test(str)
-}
-
-/**
- * @param {string} email
- * @returns {Boolean}
- */
-export function validEmail(email) {
- const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
- return reg.test(email)
-}
-
-/**
- * @param {string} str
- * @returns {Boolean}
- */
-export function isString(str) {
- return typeof str === 'string' || str instanceof String
-}
-
-/**
- * @param {Array} arg
- * @returns {Boolean}
- */
-export function isArray(arg) {
- if (typeof Array.isArray === 'undefined') {
- return Object.prototype.toString.call(arg) === '[object Array]'
- }
- return Array.isArray(arg)
-}
+/**
+ * 路径匹配器
+ * @param {string} pattern
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isPathMatch(pattern, path) {
+ const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*\*/g, '.*').replace(/\*/g, '[^\\/]*')
+ const regex = new RegExp(`^${regexPattern}$`)
+ return regex.test(path)
+}
+
+/**
+ * 判断value字符串是否为空
+ * @param {string} value
+ * @returns {Boolean}
+ */
+export function isEmpty(value) {
+ if (value == null || value == "" || value == undefined || value == "undefined") {
+ return true
+ }
+ return false
+}
+
+/**
+ * 判断url是否是http或https
+ * @param {string} url
+ * @returns {Boolean}
+ */
+export function isHttp(url) {
+ return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
+}
+
+/**
+ * 判断path是否为外链
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path) {
+ return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUsername(str) {
+ const valid_map = ['admin', 'editor']
+ return valid_map.indexOf(str.trim()) >= 0
+}
+
+/**
+ * @param {string} url
+ * @returns {Boolean}
+ */
+export function validURL(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.,?'\\+&%$#=~_-]+))*$/
+ return reg.test(url)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validLowerCase(str) {
+ const reg = /^[a-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUpperCase(str) {
+ const reg = /^[A-Z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validAlphabets(str) {
+ const reg = /^[A-Za-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} email
+ * @returns {Boolean}
+ */
+export function validEmail(email) {
+ const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+ return reg.test(email)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function isString(str) {
+ return typeof str === 'string' || str instanceof String
+}
+
+/**
+ * @param {Array} arg
+ * @returns {Boolean}
+ */
+export function isArray(arg) {
+ if (typeof Array.isArray === 'undefined') {
+ return Object.prototype.toString.call(arg) === '[object Array]'
+ }
+ return Array.isArray(arg)
+}
diff --git a/ruoyi-ui/src/views/dashboard/BarChart.vue b/ruoyi-ui/src/views/dashboard/BarChart.vue
index 116a431..88e7ef6 100644
--- a/ruoyi-ui/src/views/dashboard/BarChart.vue
+++ b/ruoyi-ui/src/views/dashboard/BarChart.vue
@@ -1,102 +1,102 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/dashboard/LineChart.vue b/ruoyi-ui/src/views/dashboard/LineChart.vue
index cd59f24..702ff73 100644
--- a/ruoyi-ui/src/views/dashboard/LineChart.vue
+++ b/ruoyi-ui/src/views/dashboard/LineChart.vue
@@ -1,135 +1,135 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/dashboard/PanelGroup.vue b/ruoyi-ui/src/views/dashboard/PanelGroup.vue
index 8d3a73b..1a1081f 100644
--- a/ruoyi-ui/src/views/dashboard/PanelGroup.vue
+++ b/ruoyi-ui/src/views/dashboard/PanelGroup.vue
@@ -1,181 +1,181 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/dashboard/PieChart.vue b/ruoyi-ui/src/views/dashboard/PieChart.vue
index 70c6076..63f0d84 100644
--- a/ruoyi-ui/src/views/dashboard/PieChart.vue
+++ b/ruoyi-ui/src/views/dashboard/PieChart.vue
@@ -1,79 +1,79 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/dashboard/RaddarChart.vue b/ruoyi-ui/src/views/dashboard/RaddarChart.vue
index 39d879b..312e018 100644
--- a/ruoyi-ui/src/views/dashboard/RaddarChart.vue
+++ b/ruoyi-ui/src/views/dashboard/RaddarChart.vue
@@ -1,116 +1,116 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/dashboard/mixins/resize.js b/ruoyi-ui/src/views/dashboard/mixins/resize.js
index d26194c..b1e76e9 100644
--- a/ruoyi-ui/src/views/dashboard/mixins/resize.js
+++ b/ruoyi-ui/src/views/dashboard/mixins/resize.js
@@ -1,56 +1,56 @@
-import { debounce } from '@/utils'
-
-export default {
- data() {
- return {
- $_sidebarElm: null,
- $_resizeHandler: null
- }
- },
- mounted() {
- this.initListener()
- },
- activated() {
- if (!this.$_resizeHandler) {
- // avoid duplication init
- this.initListener()
- }
-
- // when keep-alive chart activated, auto resize
- this.resize()
- },
- beforeDestroy() {
- this.destroyListener()
- },
- deactivated() {
- this.destroyListener()
- },
- methods: {
- // use $_ for mixins properties
- // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
- $_sidebarResizeHandler(e) {
- if (e.propertyName === 'width') {
- this.$_resizeHandler()
- }
- },
- initListener() {
- this.$_resizeHandler = debounce(() => {
- this.resize()
- }, 100)
- window.addEventListener('resize', this.$_resizeHandler)
-
- this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
- this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
- },
- destroyListener() {
- window.removeEventListener('resize', this.$_resizeHandler)
- this.$_resizeHandler = null
-
- this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
- },
- resize() {
- const { chart } = this
- chart && chart.resize()
- }
- }
-}
+import { debounce } from '@/utils'
+
+export default {
+ data() {
+ return {
+ $_sidebarElm: null,
+ $_resizeHandler: null
+ }
+ },
+ mounted() {
+ this.initListener()
+ },
+ activated() {
+ if (!this.$_resizeHandler) {
+ // avoid duplication init
+ this.initListener()
+ }
+
+ // when keep-alive chart activated, auto resize
+ this.resize()
+ },
+ beforeDestroy() {
+ this.destroyListener()
+ },
+ deactivated() {
+ this.destroyListener()
+ },
+ methods: {
+ // use $_ for mixins properties
+ // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+ $_sidebarResizeHandler(e) {
+ if (e.propertyName === 'width') {
+ this.$_resizeHandler()
+ }
+ },
+ initListener() {
+ this.$_resizeHandler = debounce(() => {
+ this.resize()
+ }, 100)
+ window.addEventListener('resize', this.$_resizeHandler)
+
+ this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
+ this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ destroyListener() {
+ window.removeEventListener('resize', this.$_resizeHandler)
+ this.$_resizeHandler = null
+
+ this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ resize() {
+ const { chart } = this
+ chart && chart.resize()
+ }
+ }
+}
diff --git a/ruoyi-ui/src/views/error/401.vue b/ruoyi-ui/src/views/error/401.vue
index 9664fba..448b6ec 100644
--- a/ruoyi-ui/src/views/error/401.vue
+++ b/ruoyi-ui/src/views/error/401.vue
@@ -1,88 +1,88 @@
-
-
-
- 返回
-
-
-
-
- 401错误!
-
- 您没有访问权限!
- 对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ 返回
+
+
+
+
+ 401错误!
+
+ 您没有访问权限!
+ 对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/error/404.vue b/ruoyi-ui/src/views/error/404.vue
index 666d27c..96f075c 100644
--- a/ruoyi-ui/src/views/error/404.vue
+++ b/ruoyi-ui/src/views/error/404.vue
@@ -1,233 +1,233 @@
-
-
-
-
-
-
- 404错误!
-
-
- {{ message }}
-
-
- 对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
-
-
- 返回首页
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ 404错误!
+
+
+ {{ message }}
+
+
+ 对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
+
+
+ 返回首页
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue
index 09dd311..259b238 100644
--- a/ruoyi-ui/src/views/index.vue
+++ b/ruoyi-ui/src/views/index.vue
@@ -1,1208 +1,18 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/index_v1.vue b/ruoyi-ui/src/views/index_v1.vue
index 4828d88..d2d2ec6 100644
--- a/ruoyi-ui/src/views/index_v1.vue
+++ b/ruoyi-ui/src/views/index_v1.vue
@@ -1,98 +1,98 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/lock.vue b/ruoyi-ui/src/views/lock.vue
deleted file mode 100644
index d6abf08..0000000
--- a/ruoyi-ui/src/views/lock.vue
+++ /dev/null
@@ -1,375 +0,0 @@
-
-
-
-
-
-
-
{{ currentTime }}
-
{{ currentDate }}
-
-
-
-
-
![]()
-
🔒
-
-
{{ nickName }}
-
系统已锁定,请输入密码解锁
-
-
-
-
-
-
-
{{ errorMsg }}
-
-
-
-
-
-
-
-
-
diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-ui/src/views/login.vue
index 12a2447..228ea43 100644
--- a/ruoyi-ui/src/views/login.vue
+++ b/ruoyi-ui/src/views/login.vue
@@ -1,78 +1,78 @@
-
-
-
- {{title}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
![]()
-
-
- 记住密码
-
-
- 登 录
- 登 录 中...
-
-
- 立即注册
-
-
-
-
-
-
-
-
-
-
-
+ },
+ loginRules: {
+ username: [
+ { required: true, trigger: "blur", message: "请输入您的账号" }
+ ],
+ password: [
+ { required: true, trigger: "blur", message: "请输入您的密码" }
+ ],
+ code: [{ required: true, trigger: "change", message: "请输入验证码" }]
+ },
+ loading: false,
+ // 验证码开关
+ captchaEnabled: true,
+ // 注册开关
+ register: false,
+ redirect: undefined
+ }
+ },
+ watch: {
+ $route: {
+ handler: function(route) {
+ this.redirect = route.query && route.query.redirect
+ },
+ immediate: true
+ }
+ },
+ created() {
+ this.getCode()
+ this.getCookie()
+ },
+ methods: {
+ getCode() {
+ getCodeImg().then(res => {
+ this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
+ if (this.captchaEnabled) {
+ this.codeUrl = "data:image/gif;base64," + res.img
+ this.loginForm.uuid = res.uuid
+ }
+ })
+ },
+ getCookie() {
+ const username = Cookies.get("username")
+ const password = Cookies.get("password")
+ const rememberMe = Cookies.get('rememberMe')
+ this.loginForm = {
+ username: username === undefined ? this.loginForm.username : username,
+ password: password === undefined ? this.loginForm.password : decrypt(password),
+ rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
+ }
+ },
+ handleLogin() {
+ this.$refs.loginForm.validate(valid => {
+ if (valid) {
+ this.loading = true
+ if (this.loginForm.rememberMe) {
+ Cookies.set("username", this.loginForm.username, { expires: 30 })
+ Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 })
+ Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
+ } else {
+ Cookies.remove("username")
+ Cookies.remove("password")
+ Cookies.remove('rememberMe')
+ }
+ this.$store.dispatch("Login", this.loginForm).then(() => {
+ this.$router.push({ path: this.redirect || "/" }).catch(()=>{})
+ }).catch(() => {
+ this.loading = false
+ if (this.captchaEnabled) {
+ this.getCode()
+ }
+ })
+ }
+ })
+ }
+ }
+}
+
+
+
diff --git a/ruoyi-ui/src/views/monitor/cache/index.vue b/ruoyi-ui/src/views/monitor/cache/index.vue
index 531ebb5..cdd92ba 100644
--- a/ruoyi-ui/src/views/monitor/cache/index.vue
+++ b/ruoyi-ui/src/views/monitor/cache/index.vue
@@ -45,7 +45,7 @@
- 缓存统计
+ 命令统计
@@ -54,7 +54,7 @@
- 命中概览
+ 缓存命中概览
@@ -72,8 +72,11 @@ export default {
name: "Cache",
data() {
return {
+ // 统计命令信息
commandstats: null,
+ // 缓存统计
usedmemory: null,
+ // cache信息
cache: {
info: {
cache_type: "IN_MEMORY",
@@ -130,6 +133,7 @@ export default {
}
},
methods: {
+ /** 查缓存询信息 */
getList() {
getCache().then((response) => {
this.cache = this.normalizeCacheData(response.data)
@@ -144,6 +148,7 @@ export default {
this.$modal.closeLoading()
})
},
+ // 打开加载层
openLoading() {
this.$modal.loading("正在加载缓存监控数据,请稍候!")
},
@@ -208,7 +213,6 @@ export default {
if (!this.usedmemory) {
this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons")
}
-
this.commandstats.setOption({
tooltip: {
trigger: "item",
@@ -227,7 +231,6 @@ export default {
}
]
})
-
this.usedmemory.setOption({
tooltip: {
trigger: "axis",
@@ -255,15 +258,10 @@ export default {
}
]
})
-
if (!this.resizeHandler) {
this.resizeHandler = () => {
- if (this.commandstats) {
- this.commandstats.resize()
- }
- if (this.usedmemory) {
- this.usedmemory.resize()
- }
+ this.commandstats && this.commandstats.resize()
+ this.usedmemory && this.usedmemory.resize()
}
window.addEventListener("resize", this.resizeHandler)
}
diff --git a/ruoyi-ui/src/views/monitor/cache/list.vue b/ruoyi-ui/src/views/monitor/cache/list.vue
index ad4a85e..a0d8e88 100644
--- a/ruoyi-ui/src/views/monitor/cache/list.vue
+++ b/ruoyi-ui/src/views/monitor/cache/list.vue
@@ -1,245 +1,253 @@
-
-
-
-
-
-
- 缓存列表
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 键名列表
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 缓存内容
- 清理全部
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/ruoyi-ui/src/views/monitor/druid/index.vue b/ruoyi-ui/src/views/monitor/druid/index.vue
index 59c4b1f..8c3a257 100644
--- a/ruoyi-ui/src/views/monitor/druid/index.vue
+++ b/ruoyi-ui/src/views/monitor/druid/index.vue
@@ -1,15 +1,15 @@
-
-
-
-
+
+
+
+
diff --git a/ruoyi-ui/src/views/monitor/job/detail.vue b/ruoyi-ui/src/views/monitor/job/detail.vue
deleted file mode 100644
index 6ddca24..0000000
--- a/ruoyi-ui/src/views/monitor/job/detail.vue
+++ /dev/null
@@ -1,197 +0,0 @@
-
-
-
-
-
-
-
-
基本信息
-
-
- 日志编号{{ form.jobLogId }}
-
-
-
- 执行状态
- 正常
- 失败
-
-
-
-
-
- 开始时间{{ form.startTime }}
-
-
- 结束时间{{ form.endTime }}
-
-
-
-
- 记录时间{{ form.createTime }}
-
-
- 执行耗时{{ costTime }} 毫秒
-
-
-
-
-
-
-
任务信息
-
-
- 任务名称{{ form.jobName }}
-
-
-
- 任务分组
-
-
-
-
-
-
- 日志信息{{ form.jobMessage }}
-
-
-
-
-
-
-
调用目标
-
-
{{ form.invokeTarget || '(无)' }}
-
-
-
-
-
-
-
-
-
-
-
-
任务配置
-
-
- 任务编号{{ form.jobId }}
-
-
- 任务名称{{ form.jobName }}
-
-
-
-
-
- 任务分组
-
-
-
-
-
- 执行状态
- 正常
- 暂停
-
-
-
-
-
-
-
-
调度信息
-
-
- cron 表达式{{ form.cronExpression }}
-
-
- 下次执行时间{{ parseTime(form.nextValidTime) }}
-
-
-
-
-
- 执行策略
- 默认策略
- 立即执行
- 执行一次
- 放弃执行
-
-
-
-
- 并发执行
- 允许
- 禁止
-
-
-
-
-
-
-
-
执行方法
-
-
{{ form.invokeTarget || '(无)' }}
-
-
-
-
-
-
元信息
-
-
- 创建人{{ form.createBy || '-' }}
-
-
- 创建时间{{ form.createTime }}
-
-
-
-
- 更新人{{ form.updateBy || '-' }}
-
-
- 更新时间{{ form.updateTime || '-' }}
-
-
-
-
- 备注{{ form.remark }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ruoyi-ui/src/views/monitor/job/index.vue b/ruoyi-ui/src/views/monitor/job/index.vue
index 585c98a..783873f 100644
--- a/ruoyi-ui/src/views/monitor/job/index.vue
+++ b/ruoyi-ui/src/views/monitor/job/index.vue
@@ -94,11 +94,7 @@
-
-
- {{ scope.row.jobName }}
-
-
+
@@ -137,6 +133,8 @@
执行一次
+ 任务详细
调度日志
@@ -243,17 +241,61 @@
-
+
+
+
+
+ {{ form.jobId }}
+ {{ form.jobName }}
+
+
+ {{ jobGroupFormat(form) }}
+ {{ form.createTime }}
+
+
+ {{ form.cronExpression }}
+
+
+ {{ parseTime(form.nextValidTime) }}
+
+
+ {{ form.invokeTarget }}
+
+
+
+ 正常
+ 暂停
+
+
+
+
+ 允许
+ 禁止
+
+
+
+
+ 默认策略
+ 立即执行
+ 执行一次
+ 放弃执行
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/monitor/operlog/detail.vue b/ruoyi-ui/src/views/monitor/operlog/detail.vue
deleted file mode 100644
index 362086e..0000000
--- a/ruoyi-ui/src/views/monitor/operlog/detail.vue
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/monitor/operlog/index.vue
index 7bcb40b..6f80177 100644
--- a/ruoyi-ui/src/views/monitor/operlog/index.vue
+++ b/ruoyi-ui/src/views/monitor/operlog/index.vue
@@ -144,7 +144,7 @@
size="mini"
type="text"
icon="el-icon-view"
- @click="handleDetail(scope.row,scope.index)"
+ @click="handleView(scope.row,scope.index)"
v-hasPermi="['monitor:operlog:query']"
>详细
@@ -159,17 +159,58 @@
@pagination="getList"
/>
-