diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development
index 18b2a3ed..c1482767 100644
--- a/ruoyi-ui/.env.development
+++ b/ruoyi-ui/.env.development
@@ -1,11 +1,11 @@
-# 页面标题
-VUE_APP_TITLE = 若依管理系统
-
-# 开发环境配置
-ENV = 'development'
-
-# 若依管理系统/开发环境
-VUE_APP_BASE_API = '/dev-api'
-
-# 路由懒加载
-VUE_CLI_BABEL_TRANSPILE_MODULES = true
+# 页面标题
+VUE_APP_TITLE = 智能作业系统
+
+# 开发环境配置
+ENV = 'development'
+
+# 智能作业系统/开发环境
+VUE_APP_BASE_API = '/dev-api'
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true
diff --git a/ruoyi-ui/.env.production b/ruoyi-ui/.env.production
index cb064ec8..55776496 100644
--- a/ruoyi-ui/.env.production
+++ b/ruoyi-ui/.env.production
@@ -1,8 +1,8 @@
-# 页面标题
-VUE_APP_TITLE = 若依管理系统
-
-# 生产环境配置
-ENV = 'production'
-
-# 若依管理系统/生产环境
-VUE_APP_BASE_API = '/prod-api'
+# 页面标题
+VUE_APP_TITLE = 智能作业系统
+
+# 生产环境配置
+ENV = 'production'
+
+# 智能作业系统/生产环境
+VUE_APP_BASE_API = '/prod-api'
diff --git a/ruoyi-ui/.env.staging b/ruoyi-ui/.env.staging
index a47af9a2..b4042af9 100644
--- a/ruoyi-ui/.env.staging
+++ b/ruoyi-ui/.env.staging
@@ -1,10 +1,10 @@
-# 页面标题
-VUE_APP_TITLE = 若依管理系统
-
-NODE_ENV = production
-
-# 测试环境配置
-ENV = 'staging'
-
-# 若依管理系统/测试环境
-VUE_APP_BASE_API = '/stage-api'
+# 页面标题
+VUE_APP_TITLE = 智能作业系统
+
+NODE_ENV = production
+
+# 测试环境配置
+ENV = 'staging'
+
+# 智能作业系统/测试环境
+VUE_APP_BASE_API = '/stage-api'
diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json
index 6cebf701..1664dd20 100644
--- a/ruoyi-ui/package.json
+++ b/ruoyi-ui/package.json
@@ -1,90 +1,92 @@
-{
- "name": "ruoyi",
- "version": "3.6.1",
- "description": "若依管理系统",
- "author": "若依",
- "license": "MIT",
- "scripts": {
- "dev": "vue-cli-service serve",
- "build:prod": "vue-cli-service build",
- "build:stage": "vue-cli-service build --mode staging",
- "preview": "node build/index.js --preview",
- "lint": "eslint --ext .js,.vue src"
- },
- "husky": {
- "hooks": {
- "pre-commit": "lint-staged"
- }
- },
- "lint-staged": {
- "src/**/*.{js,vue}": [
- "eslint --fix",
- "git add"
- ]
- },
- "keywords": [
- "vue",
- "admin",
- "dashboard",
- "element-ui",
- "boilerplate",
- "admin-template",
- "management-system"
- ],
- "repository": {
- "type": "git",
- "url": "https://gitee.com/y_project/RuoYi-Cloud.git"
- },
- "dependencies": {
- "@riophae/vue-treeselect": "0.4.0",
- "axios": "0.24.0",
- "clipboard": "2.0.8",
- "core-js": "3.25.3",
- "echarts": "4.9.0",
- "element-ui": "2.15.10",
- "file-saver": "2.0.5",
- "fuse.js": "6.4.3",
- "highlight.js": "9.18.5",
- "js-beautify": "1.13.0",
- "js-cookie": "3.0.1",
- "jsencrypt": "3.0.0-rc.1",
- "nprogress": "0.2.0",
- "quill": "1.3.7",
- "screenfull": "5.0.2",
- "sortablejs": "1.10.2",
- "vue": "2.6.12",
- "vue-count-to": "1.0.13",
- "vue-cropper": "0.5.5",
- "vue-meta": "2.4.0",
- "vue-router": "3.4.9",
- "vuedraggable": "2.24.3",
- "vuex": "3.6.0"
- },
- "devDependencies": {
- "@vue/cli-plugin-babel": "4.4.6",
- "@vue/cli-plugin-eslint": "4.4.6",
- "@vue/cli-service": "4.4.6",
- "babel-eslint": "10.1.0",
- "babel-plugin-dynamic-import-node": "2.3.3",
- "chalk": "4.1.0",
- "compression-webpack-plugin": "5.0.2",
- "connect": "3.6.6",
- "eslint": "7.15.0",
- "eslint-plugin-vue": "7.2.0",
- "lint-staged": "10.5.3",
- "runjs": "4.4.2",
- "sass": "1.32.13",
- "sass-loader": "10.1.1",
- "script-ext-html-webpack-plugin": "2.1.5",
- "svg-sprite-loader": "5.1.1",
- "vue-template-compiler": "2.6.12"
- },
- "engines": {
- "node": ">=8.9",
- "npm": ">= 3.0.0"
- },
- "browserslist": [
- "> 1%",
- "last 2 versions"
- ]
-}
+{
+ "name": "ruoyi",
+ "version": "3.6.1",
+ "description": "智能作业系统",
+ "author": "若依",
+ "license": "MIT",
+ "scripts": {
+ "dev": "vue-cli-service serve",
+ "build:prod": "vue-cli-service build",
+ "build:stage": "vue-cli-service build --mode staging",
+ "preview": "node build/index.js --preview",
+ "lint": "eslint --ext .js,.vue src"
+ },
+ "husky": {
+ "hooks": {
+ "pre-commit": "lint-staged"
+ }
+ },
+ "lint-staged": {
+ "src/**/*.{js,vue}": [
+ "eslint --fix",
+ "git add"
+ ]
+ },
+ "keywords": [
+ "vue",
+ "admin",
+ "dashboard",
+ "element-ui",
+ "boilerplate",
+ "admin-template",
+ "management-system"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://gitee.com/y_project/RuoYi-Cloud.git"
+ },
+ "dependencies": {
+ "@riophae/vue-treeselect": "0.4.0",
+ "axios": "0.24.0",
+ "bpmn-js": "^7.2.1",
+ "clipboard": "2.0.8",
+ "core-js": "3.25.3",
+ "echarts": "4.9.0",
+ "element-ui": "2.15.10",
+ "file-saver": "2.0.5",
+ "fuse.js": "6.4.3",
+ "highlight.js": "9.18.5",
+ "js-beautify": "1.13.0",
+ "js-cookie": "3.0.1",
+ "jsencrypt": "3.0.0-rc.1",
+ "nprogress": "0.2.0",
+ "quill": "1.3.7",
+ "screenfull": "5.0.2",
+ "sortablejs": "1.10.2",
+ "vue": "2.6.12",
+ "vue-count-to": "1.0.13",
+ "vue-cropper": "0.5.5",
+ "vue-meta": "2.4.0",
+ "vue-router": "3.4.9",
+ "vuedraggable": "2.24.3",
+ "vuex": "3.6.0",
+ "workflow-bpmn-modeler": "^0.2.8"
+ },
+ "devDependencies": {
+ "@vue/cli-plugin-babel": "4.4.6",
+ "@vue/cli-plugin-eslint": "4.4.6",
+ "@vue/cli-service": "4.4.6",
+ "babel-eslint": "10.1.0",
+ "babel-plugin-dynamic-import-node": "2.3.3",
+ "chalk": "4.1.0",
+ "compression-webpack-plugin": "5.0.2",
+ "connect": "3.6.6",
+ "eslint": "7.15.0",
+ "eslint-plugin-vue": "7.2.0",
+ "lint-staged": "10.5.3",
+ "runjs": "4.4.2",
+ "sass": "1.32.13",
+ "sass-loader": "10.1.1",
+ "script-ext-html-webpack-plugin": "2.1.5",
+ "svg-sprite-loader": "5.1.1",
+ "vue-template-compiler": "2.6.12"
+ },
+ "engines": {
+ "node": ">=8.9",
+ "npm": ">= 3.0.0"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions"
+ ]
+}
diff --git a/ruoyi-ui/src/App.vue b/ruoyi-ui/src/App.vue
index a2c4b872..ba498506 100644
--- a/ruoyi-ui/src/App.vue
+++ b/ruoyi-ui/src/App.vue
@@ -1,28 +1,112 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/api/login.js b/ruoyi-ui/src/api/login.js
index 6b0cda03..c23e7fb2 100644
--- a/ruoyi-ui/src/api/login.js
+++ b/ruoyi-ui/src/api/login.js
@@ -1,61 +1,61 @@
-import request from '@/utils/request'
-
-// 登录方法
-export function login(username, password, code, uuid) {
- return request({
- url: '/auth/login',
- headers: {
- isToken: false
- },
- method: 'post',
- data: { username, password, code, uuid }
- })
-}
-
-// 注册方法
-export function register(data) {
- return request({
- url: '/auth/register',
- headers: {
- isToken: false
- },
- method: 'post',
- data: data
- })
-}
-
-// 刷新方法
-export function refreshToken() {
- return request({
- url: '/auth/refresh',
- method: 'post'
- })
-}
-
-// 获取用户详细信息
-export function getInfo() {
- return request({
- url: '/system/user/getInfo',
- method: 'get'
- })
-}
-
-// 退出方法
-export function logout() {
- return request({
- url: '/auth/logout',
- method: 'delete'
- })
-}
-
-// 获取验证码
-export function getCodeImg() {
- return request({
- url: '/code',
- headers: {
- isToken: false
- },
- method: 'get',
- timeout: 20000
- })
-}
\ No newline at end of file
+import request from '@/utils/request'
+
+// 登录方法
+export function login(username, password, code, uuid) {
+ return request({
+ url: '/system/login',
+ headers: {
+ isToken: false
+ },
+ method: 'post',
+ data: { username, password, code, uuid }
+ })
+}
+
+// 注册方法
+export function register(data) {
+ return request({
+ url: '/system/register',
+ headers: {
+ isToken: false
+ },
+ method: 'post',
+ data: data
+ })
+}
+
+// 刷新方法
+export function refreshToken() {
+ return request({
+ url: '/system/refresh',
+ method: 'post'
+ })
+}
+
+// 获取用户详细信息
+export function getInfo() {
+ return request({
+ url: '/system/user/getInfo',
+ method: 'get'
+ })
+}
+
+// 退出方法
+export function logout() {
+ return request({
+ url: '/system/logout',
+ method: 'delete'
+ })
+}
+
+// 获取验证码
+export function getCodeImg() {
+ return request({
+ url: '/code',
+ headers: {
+ isToken: false
+ },
+ method: 'get',
+ timeout: 20000
+ })
+}
diff --git a/ruoyi-ui/src/api/system/dept.js b/ruoyi-ui/src/api/system/dept.js
deleted file mode 100644
index 9ca69663..00000000
--- a/ruoyi-ui/src/api/system/dept.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import request from '@/utils/request'
-
-// 查询部门列表
-export function listDept(query) {
- return request({
- url: '/system/dept/list',
- method: 'get',
- params: query
- })
-}
-
-// 查询部门列表(排除节点)
-export function listDeptExcludeChild(deptId) {
- return request({
- url: '/system/dept/list/exclude/' + deptId,
- method: 'get'
- })
-}
-
-// 查询部门详细
-export function getDept(deptId) {
- return request({
- url: '/system/dept/' + deptId,
- method: 'get'
- })
-}
-
-// 新增部门
-export function addDept(data) {
- return request({
- url: '/system/dept',
- method: 'post',
- data: data
- })
-}
-
-// 修改部门
-export function updateDept(data) {
- return request({
- url: '/system/dept',
- method: 'put',
- data: data
- })
-}
-
-// 删除部门
-export function delDept(deptId) {
- return request({
- url: '/system/dept/' + deptId,
- method: 'delete'
- })
-}
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/menu.js b/ruoyi-ui/src/api/system/menu.js
index 97258ee6..ece5e81c 100644
--- a/ruoyi-ui/src/api/system/menu.js
+++ b/ruoyi-ui/src/api/system/menu.js
@@ -1,60 +1,60 @@
-import request from '@/utils/request'
-
-// 查询菜单列表
-export function listMenu(query) {
- return request({
- url: '/system/menu/list',
- method: 'get',
- params: query
- })
-}
-
-// 查询菜单详细
-export function getMenu(menuId) {
- return request({
- url: '/system/menu/' + menuId,
- method: 'get'
- })
-}
-
-// 查询菜单下拉树结构
-export function treeselect() {
- return request({
- url: '/system/menu/treeselect',
- method: 'get'
- })
-}
-
-// 根据角色ID查询菜单下拉树结构
-export function roleMenuTreeselect(roleId) {
- return request({
- url: '/system/menu/roleMenuTreeselect/' + roleId,
- method: 'get'
- })
-}
-
-// 新增菜单
-export function addMenu(data) {
- return request({
- url: '/system/menu',
- method: 'post',
- data: data
- })
-}
-
-// 修改菜单
-export function updateMenu(data) {
- return request({
- url: '/system/menu',
- method: 'put',
- data: data
- })
-}
-
-// 删除菜单
-export function delMenu(menuId) {
- return request({
- url: '/system/menu/' + menuId,
- method: 'delete'
- })
-}
\ No newline at end of file
+ import request from '@/utils/request'
+
+// 查询菜单列表
+export function listMenu(query) {
+ return request({
+ url: '/system/menu/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询菜单详细
+export function getMenu(menuId) {
+ return request({
+ url: '/system/menu/' + menuId,
+ method: 'get'
+ })
+}
+
+// 查询菜单下拉树结构
+export function treeselect() {
+ return request({
+ url: '/system/menu/treeselect',
+ method: 'get'
+ })
+}
+
+// 根据角色ID查询菜单下拉树结构
+export function roleMenuTreeselect(roleId) {
+ return request({
+ url: '/system/menu/roleMenuTreeselect/' + roleId,
+ method: 'get'
+ })
+}
+
+// 新增菜单
+export function addMenu(data) {
+ return request({
+ url: '/system/menu',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改菜单
+export function updateMenu(data) {
+ return request({
+ url: '/system/menu',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除菜单
+export function delMenu(menuId) {
+ return request({
+ url: '/system/menu/' + menuId,
+ method: 'delete'
+ })
+}
diff --git a/ruoyi-ui/src/api/system/org.js b/ruoyi-ui/src/api/system/org.js
new file mode 100644
index 00000000..5d46f57b
--- /dev/null
+++ b/ruoyi-ui/src/api/system/org.js
@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 查询机构列表
+export function listSysOrg(query) {
+ return request({
+ url: '/system/org/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询机构列表(排除节点)
+export function listSysOrgExcludeChild(orgId) {
+ return request({
+ url: '/system/org/list/exclude/' + orgId,
+ method: 'get'
+ })
+}
+
+// 查询机构详细
+export function getSysOrg(orgId) {
+ return request({
+ url: '/system/org/' + orgId,
+ method: 'get'
+ })
+}
+
+// 新增机构
+export function addSysOrg(data) {
+ return request({
+ url: '/system/org',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改机构
+export function updateSysOrg(data) {
+ return request({
+ url: '/system/org',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除机构
+export function delSysOrg(orgId) {
+ return request({
+ url: '/system/org/' + orgId,
+ method: 'delete'
+ })
+}
diff --git a/ruoyi-ui/src/api/system/role.js b/ruoyi-ui/src/api/system/role.js
index 528cd186..44bb5bd3 100644
--- a/ruoyi-ui/src/api/system/role.js
+++ b/ruoyi-ui/src/api/system/role.js
@@ -1,119 +1,119 @@
-import request from '@/utils/request'
-
-// 查询角色列表
-export function listRole(query) {
- return request({
- url: '/system/role/list',
- method: 'get',
- params: query
- })
-}
-
-// 查询角色详细
-export function getRole(roleId) {
- return request({
- url: '/system/role/' + roleId,
- method: 'get'
- })
-}
-
-// 新增角色
-export function addRole(data) {
- return request({
- url: '/system/role',
- method: 'post',
- data: data
- })
-}
-
-// 修改角色
-export function updateRole(data) {
- return request({
- url: '/system/role',
- method: 'put',
- data: data
- })
-}
-
-// 角色数据权限
-export function dataScope(data) {
- return request({
- url: '/system/role/dataScope',
- method: 'put',
- data: data
- })
-}
-
-// 角色状态修改
-export function changeRoleStatus(roleId, status) {
- const data = {
- roleId,
- status
- }
- return request({
- url: '/system/role/changeStatus',
- method: 'put',
- data: data
- })
-}
-
-// 删除角色
-export function delRole(roleId) {
- return request({
- url: '/system/role/' + roleId,
- method: 'delete'
- })
-}
-
-// 查询角色已授权用户列表
-export function allocatedUserList(query) {
- return request({
- url: '/system/role/authUser/allocatedList',
- method: 'get',
- params: query
- })
-}
-
-// 查询角色未授权用户列表
-export function unallocatedUserList(query) {
- return request({
- url: '/system/role/authUser/unallocatedList',
- method: 'get',
- params: query
- })
-}
-
-// 取消用户授权角色
-export function authUserCancel(data) {
- return request({
- url: '/system/role/authUser/cancel',
- method: 'put',
- data: data
- })
-}
-
-// 批量取消用户授权角色
-export function authUserCancelAll(data) {
- return request({
- url: '/system/role/authUser/cancelAll',
- method: 'put',
- params: data
- })
-}
-
-// 授权用户选择
-export function authUserSelectAll(data) {
- return request({
- url: '/system/role/authUser/selectAll',
- method: 'put',
- params: data
- })
-}
-
-// 根据角色ID查询部门树结构
-export function deptTreeSelect(roleId) {
- return request({
- url: '/system/role/deptTree/' + roleId,
- method: 'get'
- })
-}
+import request from '@/utils/request'
+
+// 查询角色列表
+export function listRole(query) {
+ return request({
+ url: '/system/role/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询角色详细
+export function getRole(roleId) {
+ return request({
+ url: '/system/role/' + roleId,
+ method: 'get'
+ })
+}
+
+// 新增角色
+export function addRole(data) {
+ return request({
+ url: '/system/role',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改角色
+export function updateRole(data) {
+ return request({
+ url: '/system/role',
+ method: 'put',
+ data: data
+ })
+}
+
+// 角色数据权限
+export function dataScope(data) {
+ return request({
+ url: '/system/role/dataScope',
+ method: 'put',
+ data: data
+ })
+}
+
+// 角色状态修改
+export function changeRoleStatus(roleId, status) {
+ const data = {
+ roleId,
+ status
+ }
+ return request({
+ url: '/system/role/changeStatus',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除角色
+export function delRole(roleId) {
+ return request({
+ url: '/system/role/' + roleId,
+ method: 'delete'
+ })
+}
+
+// 查询角色已授权用户列表
+export function allocatedUserList(query) {
+ return request({
+ url: '/system/role/authUser/allocatedList',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询角色未授权用户列表
+export function unallocatedUserList(query) {
+ return request({
+ url: '/system/role/authUser/unallocatedList',
+ method: 'get',
+ params: query
+ })
+}
+
+// 取消用户授权角色
+export function authUserCancel(data) {
+ return request({
+ url: '/system/role/authUser/cancel',
+ method: 'put',
+ data: data
+ })
+}
+
+// 批量取消用户授权角色
+export function authUserCancelAll(data) {
+ return request({
+ url: '/system/role/authUser/cancelAll',
+ method: 'put',
+ params: data
+ })
+}
+
+// 授权用户选择
+export function authUserSelectAll(data) {
+ return request({
+ url: '/system/role/authUser/selectAll',
+ method: 'put',
+ params: data
+ })
+}
+
+// 根据角色ID查询机构树结构
+export function sysOrgTreeSelect(roleId) {
+ return request({
+ url: '/system/role/orgTree/' + roleId,
+ method: 'get'
+ })
+}
diff --git a/ruoyi-ui/src/api/system/user.js b/ruoyi-ui/src/api/system/user.js
index f2f76ef9..e6495c4e 100644
--- a/ruoyi-ui/src/api/system/user.js
+++ b/ruoyi-ui/src/api/system/user.js
@@ -126,10 +126,10 @@ export function updateAuthRole(data) {
})
}
-// 查询部门下拉树结构
-export function deptTreeSelect() {
+// 查询机构下拉树结构
+export function sysOrgTreeSelect() {
return request({
- url: '/system/user/deptTree',
+ url: '/system/user/orgTree',
method: 'get'
})
}
diff --git a/ruoyi-ui/src/assets/img/banner/bg.png b/ruoyi-ui/src/assets/img/banner/bg.png
new file mode 100644
index 00000000..2a34a0dc
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/bg.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/head_avatar.png b/ruoyi-ui/src/assets/img/banner/head_avatar.png
new file mode 100644
index 00000000..7854a979
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/head_avatar.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/head_bank_logo.png b/ruoyi-ui/src/assets/img/banner/head_bank_logo.png
new file mode 100644
index 00000000..2a2dd33c
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/head_bank_logo.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/header_bg.png b/ruoyi-ui/src/assets/img/banner/header_bg.png
new file mode 100644
index 00000000..6f50cd0b
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/header_bg.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/new_pro.png b/ruoyi-ui/src/assets/img/banner/new_pro.png
new file mode 100644
index 00000000..ec54678a
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/new_pro.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/newpro.png b/ruoyi-ui/src/assets/img/banner/newpro.png
new file mode 100644
index 00000000..df89d2f8
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/newpro.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/pro_hot.png b/ruoyi-ui/src/assets/img/banner/pro_hot.png
new file mode 100644
index 00000000..fa19d82f
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/pro_hot.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/red_black.png b/ruoyi-ui/src/assets/img/banner/red_black.png
new file mode 100644
index 00000000..fbf01723
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/red_black.png differ
diff --git a/ruoyi-ui/src/assets/img/banner/user.png b/ruoyi-ui/src/assets/img/banner/user.png
new file mode 100644
index 00000000..bba9f171
Binary files /dev/null and b/ruoyi-ui/src/assets/img/banner/user.png differ
diff --git a/ruoyi-ui/src/assets/img/home/head_bg_logo.png b/ruoyi-ui/src/assets/img/home/head_bg_logo.png
new file mode 100644
index 00000000..8a250cb4
Binary files /dev/null and b/ruoyi-ui/src/assets/img/home/head_bg_logo.png differ
diff --git a/ruoyi-ui/src/assets/logo-imgs/安全退出icon@2x.png b/ruoyi-ui/src/assets/logo-imgs/安全退出icon@2x.png
new file mode 100644
index 00000000..1b5bd754
Binary files /dev/null and b/ruoyi-ui/src/assets/logo-imgs/安全退出icon@2x.png differ
diff --git a/ruoyi-ui/src/assets/styles/index.scss b/ruoyi-ui/src/assets/styles/index.scss
index 9f536ae8..1caf3ac4 100644
--- a/ruoyi-ui/src/assets/styles/index.scss
+++ b/ruoyi-ui/src/assets/styles/index.scss
@@ -1,191 +1,191 @@
-@import './variables.scss';
-@import './mixin.scss';
-@import './transition.scss';
-@import './element-ui.scss';
-@import './sidebar.scss';
-@import './btn.scss';
-
-body {
- height: 100%;
- -moz-osx-font-smoothing: grayscale;
- -webkit-font-smoothing: antialiased;
- text-rendering: optimizeLegibility;
- font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
-}
-
-label {
- font-weight: 700;
-}
-
-html {
- height: 100%;
- box-sizing: border-box;
-}
-
-#app {
- height: 100%;
-}
-
-*,
-*:before,
-*:after {
- box-sizing: inherit;
-}
-
-.no-padding {
- padding: 0px !important;
-}
-
-.padding-content {
- padding: 4px 0;
-}
-
-a:focus,
-a:active {
- outline: none;
-}
-
-a,
-a:focus,
-a:hover {
- cursor: pointer;
- color: inherit;
- text-decoration: none;
-}
-
-div:focus {
- outline: none;
-}
-
-.fr {
- float: right;
-}
-
-.fl {
- float: left;
-}
-
-.pr-5 {
- padding-right: 5px;
-}
-
-.pl-5 {
- padding-left: 5px;
-}
-
-.block {
- display: block;
-}
-
-.pointer {
- cursor: pointer;
-}
-
-.inlineBlock {
- display: block;
-}
-
-.clearfix {
- &:after {
- visibility: hidden;
- display: block;
- font-size: 0;
- content: " ";
- clear: both;
- height: 0;
- }
-}
-
-aside {
- background: #eef1f6;
- padding: 8px 24px;
- margin-bottom: 20px;
- border-radius: 2px;
- display: block;
- line-height: 32px;
- font-size: 16px;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
- color: #2c3e50;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-
- a {
- color: #337ab7;
- cursor: pointer;
-
- &:hover {
- color: rgb(32, 160, 255);
- }
- }
-}
-
-//main-container全局样式
-.app-container {
- padding: 20px;
-}
-
-.components-container {
- margin: 30px 50px;
- position: relative;
-}
-
-.pagination-container {
- margin-top: 30px;
-}
-
-.text-center {
- text-align: center
-}
-
-.sub-navbar {
- height: 50px;
- line-height: 50px;
- position: relative;
- width: 100%;
- text-align: right;
- padding-right: 20px;
- transition: 600ms ease position;
- background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
-
- .subtitle {
- font-size: 20px;
- color: #fff;
- }
-
- &.draft {
- background: #d0d0d0;
- }
-
- &.deleted {
- background: #d0d0d0;
- }
-}
-
-.link-type,
-.link-type:focus {
- color: #337ab7;
- cursor: pointer;
-
- &:hover {
- color: rgb(32, 160, 255);
- }
-}
-
-.filter-container {
- padding-bottom: 10px;
-
- .filter-item {
- display: inline-block;
- vertical-align: middle;
- margin-bottom: 10px;
- }
-}
-
-//refine vue-multiselect plugin
-.multiselect {
- line-height: 16px;
-}
-
-.multiselect--active {
- z-index: 1000 !important;
-}
+@import './variables.scss';
+@import './mixin.scss';
+@import './transition.scss';
+@import './element-ui.scss';
+@import './sidebar.scss';
+@import './btn.scss';
+
+body {
+ height: 100%;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+ font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+}
+
+label {
+ font-weight: 700;
+}
+
+html {
+ height: 100%;
+ box-sizing: border-box;
+}
+
+#app {
+ height: 100%;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+.no-padding {
+ padding: 0px !important;
+}
+
+.padding-content {
+ padding: 4px 0;
+}
+
+a:focus,
+a:active {
+ outline: none;
+}
+
+a,
+a:focus,
+a:hover {
+ cursor: pointer;
+ color: inherit;
+ text-decoration: none;
+}
+
+div:focus {
+ outline: none;
+}
+
+.fr {
+ float: right;
+}
+
+.fl {
+ float: left;
+}
+
+.pr-5 {
+ padding-right: 5px;
+}
+
+.pl-5 {
+ padding-left: 5px;
+}
+
+.block {
+ display: block;
+}
+
+.pointer {
+ cursor: pointer;
+}
+
+.inlineBlock {
+ display: block;
+}
+
+.clearfix {
+ &:after {
+ visibility: hidden;
+ display: block;
+ font-size: 0;
+ content: " ";
+ clear: both;
+ height: 0;
+ }
+}
+
+aside {
+ background: #eef1f6;
+ padding: 8px 24px;
+ margin-bottom: 20px;
+ border-radius: 2px;
+ display: block;
+ line-height: 32px;
+ font-size: 16px;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+ color: #2c3e50;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ a {
+ color: #337ab7;
+ cursor: pointer;
+
+ &:hover {
+ color: rgb(32, 160, 255);
+ }
+ }
+}
+
+//main-container全局样式
+.app-container {
+ //padding: 20px;
+}
+
+.components-container {
+ margin: 30px 50px;
+ position: relative;
+}
+
+.pagination-container {
+ margin-top: 30px;
+}
+
+.text-center {
+ text-align: center
+}
+
+.sub-navbar {
+ height: 50px;
+ line-height: 50px;
+ position: relative;
+ width: 100%;
+ text-align: right;
+ padding-right: 20px;
+ transition: 600ms ease position;
+ background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
+
+ .subtitle {
+ font-size: 20px;
+ color: #fff;
+ }
+
+ &.draft {
+ background: #d0d0d0;
+ }
+
+ &.deleted {
+ background: #d0d0d0;
+ }
+}
+
+.link-type,
+.link-type:focus {
+ color: #337ab7;
+ cursor: pointer;
+
+ &:hover {
+ color: rgb(32, 160, 255);
+ }
+}
+
+.filter-container {
+ padding-bottom: 10px;
+
+ .filter-item {
+ display: inline-block;
+ vertical-align: middle;
+ margin-bottom: 10px;
+ }
+}
+
+//refine vue-multiselect plugin
+.multiselect {
+ line-height: 16px;
+}
+
+.multiselect--active {
+ z-index: 1000 !important;
+}
diff --git a/ruoyi-ui/src/assets/styles/sidebar.scss b/ruoyi-ui/src/assets/styles/sidebar.scss
index 43d5f9a9..7358c58c 100644
--- a/ruoyi-ui/src/assets/styles/sidebar.scss
+++ b/ruoyi-ui/src/assets/styles/sidebar.scss
@@ -1,227 +1,228 @@
-#app {
-
- .main-container {
- min-height: 100%;
- transition: margin-left .28s;
- margin-left: $base-sidebar-width;
- position: relative;
- }
-
- .sidebarHide {
- margin-left: 0!important;
- }
-
- .sidebar-container {
- -webkit-transition: width .28s;
- transition: width 0.28s;
- width: $base-sidebar-width !important;
- background-color: $base-menu-background;
- height: 100%;
- position: fixed;
- font-size: 0px;
- top: 0;
- bottom: 0;
- left: 0;
- z-index: 1001;
- overflow: hidden;
- -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
- box-shadow: 2px 0 6px rgba(0,21,41,.35);
-
- // reset element-ui css
- .horizontal-collapse-transition {
- transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
- }
-
- .scrollbar-wrapper {
- overflow-x: hidden !important;
- }
-
- .el-scrollbar__bar.is-vertical {
- right: 0px;
- }
-
- .el-scrollbar {
- height: 100%;
- }
-
- &.has-logo {
- .el-scrollbar {
- height: calc(100% - 50px);
- }
- }
-
- .is-horizontal {
- display: none;
- }
-
- a {
- display: inline-block;
- width: 100%;
- overflow: hidden;
- }
-
- .svg-icon {
- margin-right: 16px;
- }
-
- .el-menu {
- border: none;
- height: 100%;
- width: 100% !important;
- }
-
- .el-menu-item, .el-submenu__title {
- overflow: hidden !important;
- text-overflow: ellipsis !important;
- white-space: nowrap !important;
- }
-
- // menu hover
- .submenu-title-noDropdown,
- .el-submenu__title {
- &:hover {
- background-color: rgba(0, 0, 0, 0.06) !important;
- }
- }
-
- & .theme-dark .is-active > .el-submenu__title {
- color: $base-menu-color-active !important;
- }
-
- & .nest-menu .el-submenu>.el-submenu__title,
- & .el-submenu .el-menu-item {
- min-width: $base-sidebar-width !important;
-
- &:hover {
- background-color: rgba(0, 0, 0, 0.06) !important;
- }
- }
-
- & .theme-dark .nest-menu .el-submenu>.el-submenu__title,
- & .theme-dark .el-submenu .el-menu-item {
- background-color: $base-sub-menu-background !important;
-
- &:hover {
- background-color: $base-sub-menu-hover !important;
- }
- }
- }
-
- .hideSidebar {
- .sidebar-container {
- width: 54px !important;
- }
-
- .main-container {
- margin-left: 54px;
- }
-
- .submenu-title-noDropdown {
- padding: 0 !important;
- position: relative;
-
- .el-tooltip {
- padding: 0 !important;
-
- .svg-icon {
- margin-left: 20px;
- }
- }
- }
-
- .el-submenu {
- overflow: hidden;
-
- &>.el-submenu__title {
- padding: 0 !important;
-
- .svg-icon {
- margin-left: 20px;
- }
-
- }
- }
-
- .el-menu--collapse {
- .el-submenu {
- &>.el-submenu__title {
- &>span {
- height: 0;
- width: 0;
- overflow: hidden;
- visibility: hidden;
- display: inline-block;
- }
- }
- }
- }
- }
-
- .el-menu--collapse .el-menu .el-submenu {
- min-width: $base-sidebar-width !important;
- }
-
- // mobile responsive
- .mobile {
- .main-container {
- margin-left: 0px;
- }
-
- .sidebar-container {
- transition: transform .28s;
- width: $base-sidebar-width !important;
- }
-
- &.hideSidebar {
- .sidebar-container {
- pointer-events: none;
- transition-duration: 0.3s;
- transform: translate3d(-$base-sidebar-width, 0, 0);
- }
- }
- }
-
- .withoutAnimation {
-
- .main-container,
- .sidebar-container {
- transition: none;
- }
- }
-}
-
-// when menu collapsed
-.el-menu--vertical {
- &>.el-menu {
- .svg-icon {
- margin-right: 16px;
- }
- }
-
- .nest-menu .el-submenu>.el-submenu__title,
- .el-menu-item {
- &:hover {
- // you can use $subMenuHover
- background-color: rgba(0, 0, 0, 0.06) !important;
- }
- }
-
- // the scroll bar appears when the subMenu is too long
- >.el-menu--popup {
- max-height: 100vh;
- overflow-y: auto;
-
- &::-webkit-scrollbar-track-piece {
- background: #d3dce6;
- }
-
- &::-webkit-scrollbar {
- width: 6px;
- }
-
- &::-webkit-scrollbar-thumb {
- background: #99a9bf;
- border-radius: 20px;
- }
- }
-}
+#app {
+
+ .main-container {
+ transition: margin-left .28s;
+ margin-left: $base-sidebar-width;
+ position: relative;
+ overflow-y: hidden;
+ top: 80px;
+ }
+
+ .sidebarHide {
+ margin-left: 0!important;
+ }
+
+ .sidebar-container {
+ -webkit-transition: width .28s;
+ transition: width 0.28s;
+ width: $base-sidebar-width !important;
+ background-color: $base-menu-background;
+ height: calc(100vh - 80px);
+ position: fixed;
+ font-size: 0px;
+ top: 80px;
+ bottom: 0;
+ left: 0;
+ z-index: 1001;
+ overflow: hidden;
+ -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
+ box-shadow: 2px 0 6px rgba(0,21,41,.35);
+
+ // reset element-ui css
+ .horizontal-collapse-transition {
+ transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
+ }
+
+ .scrollbar-wrapper {
+ overflow-x: hidden !important;
+ }
+
+ .el-scrollbar__bar.is-vertical {
+ right: 0px;
+ }
+
+ .el-scrollbar {
+ height: 100%;
+ }
+
+ &.has-logo {
+ .el-scrollbar {
+ height: calc(100% - 50px);
+ }
+ }
+
+ .is-horizontal {
+ display: none;
+ }
+
+ a {
+ display: inline-block;
+ width: 100%;
+ overflow: hidden;
+ }
+
+ .svg-icon {
+ margin-right: 16px;
+ }
+
+ .el-menu {
+ border: none;
+ height: 100%;
+ width: 100% !important;
+ }
+
+ .el-menu-item, .el-submenu__title {
+ overflow: hidden !important;
+ text-overflow: ellipsis !important;
+ white-space: nowrap !important;
+ }
+
+ // menu hover
+ .submenu-title-noDropdown,
+ .el-submenu__title {
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.06) !important;
+ }
+ }
+
+ & .theme-dark .is-active > .el-submenu__title {
+ color: $base-menu-color-active !important;
+ }
+
+ & .nest-menu .el-submenu>.el-submenu__title,
+ & .el-submenu .el-menu-item {
+ min-width: $base-sidebar-width !important;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.06) !important;
+ }
+ }
+
+ & .theme-dark .nest-menu .el-submenu>.el-submenu__title,
+ & .theme-dark .el-submenu .el-menu-item {
+ background-color: $base-sub-menu-background !important;
+
+ &:hover {
+ background-color: $base-sub-menu-hover !important;
+ }
+ }
+ }
+
+ .hideSidebar {
+ .sidebar-container {
+ width: 54px !important;
+ }
+
+ .main-container {
+ margin-left: 54px;
+ }
+
+ .submenu-title-noDropdown {
+ padding: 0 !important;
+ position: relative;
+
+ .el-tooltip {
+ padding: 0 !important;
+
+ .svg-icon {
+ margin-left: 20px;
+ }
+ }
+ }
+
+ .el-submenu {
+ overflow: hidden;
+
+ &>.el-submenu__title {
+ padding: 0 !important;
+
+ .svg-icon {
+ margin-left: 20px;
+ }
+
+ }
+ }
+
+ .el-menu--collapse {
+ .el-submenu {
+ &>.el-submenu__title {
+ &>span {
+ height: 0;
+ width: 0;
+ overflow: hidden;
+ visibility: hidden;
+ display: inline-block;
+ }
+ }
+ }
+ }
+ }
+
+ .el-menu--collapse .el-menu .el-submenu {
+ min-width: $base-sidebar-width !important;
+ }
+
+ // mobile responsive
+ .mobile {
+ .main-container {
+ margin-left: 0px;
+ }
+
+ .sidebar-container {
+ transition: transform .28s;
+ width: $base-sidebar-width !important;
+ }
+
+ &.hideSidebar {
+ .sidebar-container {
+ pointer-events: none;
+ transition-duration: 0.3s;
+ transform: translate3d(-$base-sidebar-width, 0, 0);
+ }
+ }
+ }
+
+ .withoutAnimation {
+
+ .main-container,
+ .sidebar-container {
+ transition: none;
+ }
+ }
+}
+
+// when menu collapsed
+.el-menu--vertical {
+ &>.el-menu {
+ .svg-icon {
+ margin-right: 16px;
+ }
+ }
+
+ .nest-menu .el-submenu>.el-submenu__title,
+ .el-menu-item {
+ &:hover {
+ // you can use $subMenuHover
+ background-color: rgba(0, 0, 0, 0.06) !important;
+ }
+ }
+
+ // the scroll bar appears when the subMenu is too long
+ >.el-menu--popup {
+ max-height: 100vh;
+ overflow-y: auto;
+
+ &::-webkit-scrollbar-track-piece {
+ background: #d3dce6;
+ }
+
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #99a9bf;
+ border-radius: 20px;
+ }
+ }
+}
diff --git a/ruoyi-ui/src/components/Header.vue b/ruoyi-ui/src/components/Header.vue
new file mode 100644
index 00000000..d91fedfd
--- /dev/null
+++ b/ruoyi-ui/src/components/Header.vue
@@ -0,0 +1,528 @@
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/components/PageTabs.vue b/ruoyi-ui/src/components/PageTabs.vue
new file mode 100644
index 00000000..f2bc80b4
--- /dev/null
+++ b/ruoyi-ui/src/components/PageTabs.vue
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/components/RightFence.vue b/ruoyi-ui/src/components/RightFence.vue
new file mode 100644
index 00000000..d726d449
--- /dev/null
+++ b/ruoyi-ui/src/components/RightFence.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/layout/components/AppMain.vue b/ruoyi-ui/src/layout/components/AppMain.vue
index 25d5a25a..a2bc023a 100644
--- a/ruoyi-ui/src/layout/components/AppMain.vue
+++ b/ruoyi-ui/src/layout/components/AppMain.vue
@@ -1,61 +1,70 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
index c8401c51..18acd318 100644
--- a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
+++ b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
@@ -1,93 +1,93 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/layout/components/Sidebar/index.vue b/ruoyi-ui/src/layout/components/Sidebar/index.vue
index 24fb533b..51d0839f 100644
--- a/ruoyi-ui/src/layout/components/Sidebar/index.vue
+++ b/ruoyi-ui/src/layout/components/Sidebar/index.vue
@@ -1,57 +1,57 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/layout/index.vue b/ruoyi-ui/src/layout/index.vue
index 202cfcd6..241bfa86 100644
--- a/ruoyi-ui/src/layout/index.vue
+++ b/ruoyi-ui/src/layout/index.vue
@@ -1,111 +1,132 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index ebd94b9d..1adcb485 100644
--- a/ruoyi-ui/src/main.js
+++ b/ruoyi-ui/src/main.js
@@ -1,86 +1,88 @@
-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 VueMeta from 'vue-meta'
-// 字典数据组件
-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)
-Vue.use(VueMeta)
-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 global from './plugins/global';
+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 VueMeta from 'vue-meta'
+// 字典数据组件
+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.prototype.$global = global;
+
+// 全局组件挂载
+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)
+Vue.use(VueMeta)
+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/plugins/global.js b/ruoyi-ui/src/plugins/global.js
new file mode 100644
index 00000000..706842d9
--- /dev/null
+++ b/ruoyi-ui/src/plugins/global.js
@@ -0,0 +1,473 @@
+import axios from 'axios'
+const global = {
+ // 表单必输项
+ requiredRule: {
+ required: true,
+ message: '该项为必输项!',
+ trigger: ['blur', 'change'],
+ },
+
+ // 文件上传接口
+ uploadURL: process.env.VUE_APP_BASE_API + 'sys/file/upload',
+
+ //影像平台接口上传接口文件
+ uploadToIcon: process.env.VUE_APP_BASE_API + '/sys/file/uploadToIcon',
+
+ //文件下载
+ downLoadUrl: process.env.VUE_APP_BASE_API + 'sys/file/download?fileId=',
+
+ // 公告文件上传接口
+ uploadToIconSf: process.env.VUE_APP_BASE_API + '/sys/file/upload',
+ // 图片
+ // getPicUrl:'/get/{value}/mg.do'
+ getPicUrl: process.env.VUE_APP_BASE_API + '/sys/file/get/{value}/mg.do',
+
+ // 码值转换
+ getNameByCode: (codeInfo, codeValue, isMult = false) => {
+ if (!codeInfo) {
+ return codeValue
+ }
+ if (!codeValue) {
+ return ''
+ }
+ if (isMult) codeValue = isMult ? codeValue.split(',') : codeValue
+ let codeName = '',
+ codeValues = []
+ for (let i = 0; i < codeInfo.length; i++) {
+ if (Array.isArray(codeValue)) {
+ for (let j = 0; j < codeValue.length; j++) {
+ if (codeValue[j] == codeInfo[i].value) {
+ codeValues.push(codeInfo[i].content)
+ }
+ }
+ } else {
+ if (codeValue == codeInfo[i].value) {
+ codeName = codeInfo[i].content
+ break
+ }
+ }
+ codeName = codeValues.join(',')
+ }
+ return codeName == '' ? codeValue : codeName
+ },
+
+ // 分转元
+ regFenToYuan: val => {
+ let num = Number(val)
+ if (!isNaN(num)) {
+ num = num * 0.01 + ''
+ let reg = num.indexOf('.') > -1 ? /(\d{1,3})(?=(?:\d{3})+\.)/g : /(\d{1,3})(?=(?:\d{3})+$)/g //千分符的正则
+ return num.replace(reg, '$1,')
+ } else {
+ return null
+ }
+ },
+ // 判断字符串是否为空
+ isEmptyStr(str) {
+ if (str == '') return true
+ const regu = '^[ ]+$'
+ const re = new RegExp(regu)
+ return re.test(str)
+ },
+ //文件下载/表格导出
+ downloadFiles(_url, _params, _this, requestFn = 'download') {
+
+ _this.$http[requestFn](_url, _params).then(response => {
+ if (_url === _this.$api.cmApi.exporAllCstInfo) {
+ console.log(response, 'response')
+ // if (response.isOK) {
+ // _this.$message.successs(response.msg)
+ // } else {
+ // _this.$message.error(response.msg)
+ // }
+ } else if (!response.data.code) {
+ let contentDisposition = response.headers['content-disposition']
+ const blob = new Blob([response.data])
+
+ if ('download' in document.createElement('a')) {
+ const elink = document.createElement('a')
+ let fileName = decodeURI(contentDisposition.substring(contentDisposition.indexOf('filename=') + 9, contentDisposition.length));
+ fileName = fileName.replace((/"/g), "");
+ elink.download = fileName
+ elink.style.display = 'none'
+ elink.href = URL.createObjectURL(blob)
+ document.body.appendChild(elink)
+ elink.click()
+ URL.revokeObjectURL(elink.href)
+ document.body.removeChild(elink)
+ } else {
+ navigator.msSaveBlob(blob, fileName)
+ }
+ } else {
+ _this.$message.error(response.msg)
+ }
+ })
+ },
+
+ /* 文件下载/表格导出
+ * 支持影像平台下载
+ */
+ downloadImage(_url, _params, _this, requestFn = 'download') {
+ _this.$http[requestFn](_url, _params).then(response => {
+ if (!response.data.code) {
+ let fileName = response.headers['content-disposition']
+ const blob = new Blob([response.data])
+ if ('download' in document.createElement('a')) {
+ const elink = document.createElement('a')
+ // 公共方法不支持截取,去掉fileName两边的""
+ fileName = fileName.substr(0, fileName.length - 1)
+ let spcStr = (fileName.split('=')[1]).substr(1)
+ elink.download = fileName && decodeURI(spcStr)
+ elink.style.display = 'none'
+ elink.href = URL.createObjectURL(blob)
+ document.body.appendChild(elink)
+ elink.click()
+ URL.revokeObjectURL(elink.href)
+ document.body.removeChild(elink)
+ } else {
+ navigator.msSaveBlob(blob, fileName)
+ }
+ } else {
+ _this.$message.error(response.msg)
+ }
+ })
+ },
+ /**
+ * 每隔几个字符进行添加对应标记
+ * @param {*} str 需要添加标记的字符串
+ * @param {*} vkey 标记
+ * @param {*} vnum 字符个数
+ */
+ strReplace: (str, vnum = 2, vkey = '-') => {
+ if (!str) return ''
+ let result = ''
+ for (var i = 0, len = str.length; i < len; i++) {
+ result += str[i]
+ if (i % vnum == 1) result += vkey
+ }
+ if (result.slice(-1) == vkey) result = result.slice(0, -1)
+ return result
+ },
+ /**
+ * 判断是否是数组
+ */
+ isArrayFn: value => {
+ if (typeof Array.isArray === 'function') {
+ return Array.isArray(value)
+ } else {
+ return Object.prototype.toString.call(value) === '[object Array]'
+ }
+ },
+ /**
+ * isEmpty 判空
+ */
+ isEmpty: str => {
+ let flag = true
+ if (str != null && str != undefined)
+ flag =
+ str
+ .replace(/(^\s*)|(\s*$)/g, '')
+ .replace(/<\/?.+?>/g, '')
+ .replace(/[\r\n]/g, '').length > 0 ?
+ false :
+ true
+ return flag
+ },
+ /**
+ * 时间格式化
+ * @param {*} time 传入的时间
+ */
+ timeFamat(time) {
+ var newTime = new Date(time)
+ var year = newTime.getFullYear() //年
+ var month = newTime.getMonth() + 1 //月
+ var day = newTime.getDate() //日
+
+ var clock = year + '-'
+
+ if (month < 10) clock += '0'
+
+ clock += month + '-'
+
+ if (day < 10) clock += '0'
+
+ clock += day
+
+ return clock
+ },
+ /**
+ * 创建当前时间
+ * @param {*} isTrue 精确到年、月、天标识
+ */
+ createTime: isTrue => {
+ var now = new Date()
+
+ var year = now.getFullYear() //年
+ var month = now.getMonth() + 1 //月
+ var day = now.getDate() //日
+
+ var hh = now.getHours() //时
+ var mm = now.getMinutes() //分
+ var ss = now.getSeconds() //秒
+ if (isTrue == 'year') return year
+
+ var clock = year + '-'
+
+ if (month < 10) clock += '0'
+
+ if (isTrue == 'month') return (clock += month)
+
+ clock += month + '-'
+
+ if (day < 10) clock += '0'
+
+ clock += day
+
+ //精确到天
+ if (isTrue == 'day') return clock
+ clock += clock + ' '
+
+ if (hh < 10) clock += '0'
+
+ clock += hh + ':'
+ if (mm < 10) clock += '0'
+ clock += mm + ':'
+
+ if (ss < 10) clock += '0'
+ clock += ss
+ return clock
+ },
+ //加法
+ NumberAdd: (arg1, arg2, n = 2) => {
+ var r1, r2, m
+ try {
+ r1 = arg1.toString().split('.')[1].length
+ } catch (e) {
+ r1 = 0
+ }
+ try {
+ r2 = arg2.toString().split('.')[1].length
+ } catch (e) {
+ r2 = 0
+ }
+ m = Math.pow(10, Math.max(r1, r2))
+ return ((arg1 * m + arg2 * m) / m).toFixed(n)
+ },
+ //减法
+ NumberSub: (arg1, arg2) => {
+ var r1, r2, m, n
+ try {
+ r1 = arg1.toString().split('.')[1].length
+ } catch (e) {
+ r1 = 0
+ }
+ try {
+ r2 = arg2.toString().split('.')[1].length
+ } catch (e) {
+ r2 = 0
+ }
+ m = Math.pow(10, Math.max(r1, r2))
+ //动态控制精度长度
+ n = r1 >= r2 ? r1 : r2
+ return ((arg1 * m - arg2 * m) / m).toFixed(n)
+ },
+ //乘法
+ NumberMul: (arg1, arg2) => {
+ var m = 0,
+ s1 = arg1.toString(),
+ s2 = arg2.toString()
+ try {
+ m += s1.split('.')[1].length
+ } catch (e) {}
+ try {
+ m += s2.split('.')[1].length
+ } catch (e) {}
+ return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m)
+ },
+
+ //除法
+ NumberDiv: (arg1, arg2) => {
+ var t1 = 0,
+ t2 = 0,
+ r1,
+ r2
+ try {
+ t1 = arg1.toString().split('.')[1].length
+ } catch (e) {}
+ try {
+ t2 = arg2.toString().split('.')[1].length
+ } catch (e) {}
+
+ r1 = Number(arg1.toString().replace('.', ''))
+
+ r2 = Number(arg2.toString().replace('.', ''))
+ return (r1 / r2) * Math.pow(10, t2 - t1)
+ },
+
+ /*
+ 检查数组是否有重复
+ keyName:数组里面的对象的属性名
+ */
+ isArrayRepeat: (arr, keyName) => {
+ let hash = {}
+ if (keyName) {
+ for (let i in arr) {
+ if (hash[arr[i][keyName]]) {
+ return true
+ } else {
+ hash[arr[i][keyName]] = true
+ }
+ }
+ } else {
+ for (let i in arr) {
+ if (hash[arr[i]]) {
+ return true
+ } else {
+ hash[arr[i]] = true
+ }
+ }
+ }
+ return false
+ },
+ /*
+ 异步请求顺序执行
+ _arr:方法名
+ */
+ async getAllFn(_arr, _this) {
+ for (let i = 0; i < _arr.length; i++) {
+ await this.getReqDataFn(_arr[i], _this)
+ }
+ },
+ getReqDataFn(fn, _this) {
+ var p = new Promise(resolve => {
+ _this[fn]()
+ setTimeout(() => {
+ resolve()
+ }, 100)
+ })
+ return p
+ },
+
+ /*
+ 格式化金额数字, 加千分位并保留两位小数
+ params: num(传入的金额)
+ */
+ formatAmountNum: num => {
+ if (num == 0) {
+ return num
+ }
+ if (!num) {
+ return
+ }
+ num = num + ''
+ if (!num.includes('.')) {
+ num += '.'
+ }
+ return num
+ .replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) {
+ return $1 + ','
+ })
+ .replace(/\.$/, '.00')
+ },
+ /**
+ * 时间比较大小
+ */
+ compareDate: (sDate, eDate, isSame = false) => {
+ let st = new Date(sDate)
+ let et = new Date(eDate)
+ let flag = !st && !et ? false : st.getTime() >= et.getTime() ? false : true
+ if (isSame) flag = !st && !et ? false : st.getTime() > et.getTime() ? false : true
+ return flag
+ },
+ /**
+ * 手机号码验证
+ */
+ checkPhoneFn: (mobile) => {
+ let reg = /^0?(13[0-9]|14[5-9]|15[012356789]|166|17[0-8]|18[0-9]|19[0-9])[0-9]{8}$/;
+ return reg.test(mobile)
+ },
+ /**
+ * 将指定日期区间按月份分割
+ * @param {Object} beginDate 开始日期
+ * @param {Object} endDate 结束日期
+ * @return {Array} 分割好的array数组
+ */
+ dateCutByMonth(beginDate, endDate) {
+ //分割好的数组
+ let dateCutList = new Array();
+ let b_date = new Date(beginDate);
+ let e_date = new Date(endDate);
+ //获取各个年份
+ let b_year = parseInt(b_date.getFullYear());
+ let e_year = parseInt(e_date.getFullYear());
+ //获取各个月份
+ let b_month = parseInt(b_date.getMonth()) + 1;
+ let e_month = parseInt(e_date.getMonth()) + 1;
+
+ //获取日期之间相差的月数
+ let month_list = monthList();
+
+ //按月份分割日期
+ for (let i = 0; i < month_list.length; i++) {
+ //当前月开始日期:第一天
+ let i_b_date = new Date(month_list[i]);
+ i_b_date.setDate(1);
+ //当前月最后一天
+ let i_e_date = new Date(month_list[i]);
+ i_e_date.setMonth(i_e_date.getMonth() + 1);
+ i_e_date.setDate(1);
+ i_e_date.setDate(i_e_date.getDate() - 1);
+
+ //第一次循环:开始月份
+ if (i == 0) {
+ let i_e_ymd = dateToString(i_e_date);
+ dateCutList.push([beginDate, i_e_ymd]);
+
+ //除第一次和最后一次循环:中间月份
+ } else if (i != 0 && i != month_list.length - 1) {
+ let i_b_ymd = dateToString(i_b_date);
+ let i_e_ymd = dateToString(i_e_date);
+ dateCutList.push([i_b_ymd, i_e_ymd]);
+ //最后一次循环:结束月份
+ } else if (i == month_list.length - 1) {
+ let i_b_ymd = dateToString(i_b_date);
+ dateCutList.push([i_b_ymd, endDate]);
+ }
+ }
+ return dateCutList;
+ /**
+ * 获取日期区间的月份集合
+ */
+ function monthList() {
+ //相差的月份总数
+ let result = new Array();
+
+ let b = new Date(b_year, b_month - 1, 1);
+ let e = new Date(e_year, e_month - 1, 1);
+ while (b < e) {
+ result.push(b.getFullYear() + "-" + (b.getMonth() + 1));
+ b.setMonth(b.getMonth() + 1);
+ }
+ result.push(e_year + "-" + e_month);
+ return result;
+ }
+ /**
+ * 将日期转换为指定格式的字符串
+ * @param {Date} date 要转换的日期
+ */
+ function dateToString(date) {
+ let month = (date.getMonth() + 1);
+ let day = date.getDate();
+ if (month < 10) {
+ month = '0' + month
+ }
+ if (day < 10) {
+ day = '0' + day
+ }
+ return date.getFullYear() + "-" + (month) + "-" + day;
+ }
+
+ },
+}
+
+export default global
\ No newline at end of file
diff --git a/ruoyi-ui/src/plugins/waterMark.js b/ruoyi-ui/src/plugins/waterMark.js
new file mode 100644
index 00000000..0bb70494
--- /dev/null
+++ b/ruoyi-ui/src/plugins/waterMark.js
@@ -0,0 +1,32 @@
+let style
+let clearWaterMark = () => {
+ if (style) style.remove
+}
+export default function createWaterMark(str,_height) {
+ clearWaterMark()
+ if (!str) return
+ let width = window.parseInt(document.body.clientWidth),
+ canvasWidth = width / window.parseInt(width / 400),
+ fontFamily = window.getComputedStyle(document.body)['font-family'],
+ canvas = document.createElement('canvas')
+ canvas.width = canvasWidth
+ canvas.height = 200
+ let cxt = canvas.getContext('2d')
+ cxt.rotate((-20 * Math.PI) / 180)
+ cxt.font = `18px${fontFamily}`
+ cxt.fillStyle = 'rgba(8,8,8,0.2)'
+ cxt.fillText(str, 50, 200)
+ let imgSrc = canvas.toDataURL('image/png')
+ style = document.createElement('style')
+ style.innerHTML = `.with-watermark:before{
+ content:"";
+ width:100%;
+ pointer-events:none;
+ height:${_height}px;
+ display:block;
+ position:absolute;
+ z-index:99999;
+ background-image:url("${imgSrc}")
+ }`
+ ;(document.head.append || document.head.appendChild).apply(document.head, [style])
+}
diff --git a/ruoyi-ui/src/store/modules/user.js b/ruoyi-ui/src/store/modules/user.js
index 262de9b0..816d5b49 100644
--- a/ruoyi-ui/src/store/modules/user.js
+++ b/ruoyi-ui/src/store/modules/user.js
@@ -1,115 +1,115 @@
-import { login, logout, getInfo, refreshToken } from '@/api/login'
-import { getToken, setToken, setExpiresIn, removeToken } from '@/utils/auth'
-
-const user = {
- state: {
- token: getToken(),
- name: '',
- avatar: '',
- roles: [],
- permissions: []
- },
-
- mutations: {
- SET_TOKEN: (state, token) => {
- state.token = token
- },
- SET_EXPIRES_IN: (state, time) => {
- state.expires_in = time
- },
- SET_NAME: (state, name) => {
- state.name = name
- },
- 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 => {
- let data = res.data
- setToken(data.access_token)
- commit('SET_TOKEN', data.access_token)
- setExpiresIn(data.expires_in)
- commit('SET_EXPIRES_IN', data.expires_in)
- resolve()
- }).catch(error => {
- reject(error)
- })
- })
- },
-
- // 获取用户信息
- GetInfo({ commit, state }) {
- return new Promise((resolve, reject) => {
- getInfo().then(res => {
- const user = res.user
- const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : user.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_NAME', user.userName)
- commit('SET_AVATAR', avatar)
- resolve(res)
- }).catch(error => {
- reject(error)
- })
- })
- },
-
- // 刷新token
- RefreshToken({commit, state}) {
- return new Promise((resolve, reject) => {
- refreshToken(state.token).then(res => {
- setExpiresIn(res.data)
- commit('SET_EXPIRES_IN', res.data)
- resolve()
- }).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 { login, logout, getInfo, refreshToken } from '@/api/login'
+import { getToken, setToken, setExpiresIn, removeToken } from '@/utils/auth'
+
+const user = {
+ state: {
+ token: getToken(),
+ name: '',
+ avatar: '',
+ roles: [],
+ permissions: []
+ },
+
+ mutations: {
+ SET_TOKEN: (state, token) => {
+ state.token = token
+ },
+ SET_EXPIRES_IN: (state, time) => {
+ state.expires_in = time
+ },
+ SET_NAME: (state, name) => {
+ state.name = name
+ },
+ 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 => {
+ let data = res.data
+ setToken(data.access_token)
+ commit('SET_TOKEN', data.access_token)
+ setExpiresIn(data.expires_in)
+ commit('SET_EXPIRES_IN', data.expires_in)
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 获取用户信息
+ GetInfo({ commit, state }) {
+ return new Promise((resolve, reject) => {
+ getInfo().then(res => {
+ const user = res.user
+ const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : user.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_NAME', user.userName)
+ commit('SET_AVATAR', avatar)
+ resolve(res)
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 刷新token
+ RefreshToken({commit, state}) {
+ return new Promise((resolve, reject) => {
+ refreshToken(state.token).then(res => {
+ setExpiresIn(res.data)
+ commit('SET_EXPIRES_IN', res.data)
+ resolve()
+ }).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/views/index.vue b/ruoyi-ui/src/views/index.vue
index 1fe06763..16ad6d1e 100644
--- a/ruoyi-ui/src/views/index.vue
+++ b/ruoyi-ui/src/views/index.vue
@@ -1,875 +1,98 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-ui/src/views/login.vue
index 074fecd3..b19d81eb 100644
--- a/ruoyi-ui/src/views/login.vue
+++ b/ruoyi-ui/src/views/login.vue
@@ -1,219 +1,219 @@
-
-
-
- 若依后台管理系统
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
![]()
-
-
- 记住密码
-
-
- 登 录
- 登 录 中...
-
-
- 立即注册
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ 若依后台管理系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+ 记住密码
+
+
+ 登 录
+ 登 录 中...
+
+
+ 立即注册
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/register.vue b/ruoyi-ui/src/views/register.vue
index d8ec3c18..b6f752b9 100644
--- a/ruoyi-ui/src/views/register.vue
+++ b/ruoyi-ui/src/views/register.vue
@@ -1,209 +1,209 @@
-
-
-
- 若依后台管理系统
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
![]()
-
-
-
-
- 注 册
- 注 册 中...
-
-
- 使用已有账户登录
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ 若依后台管理系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+ 注 册
+ 注 册 中...
+
+
+ 使用已有账户登录
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/system/dept/index.vue b/ruoyi-ui/src/views/system/org/index.vue
similarity index 75%
rename from ruoyi-ui/src/views/system/dept/index.vue
rename to ruoyi-ui/src/views/system/org/index.vue
index 486c56cc..585a7f93 100644
--- a/ruoyi-ui/src/views/system/dept/index.vue
+++ b/ruoyi-ui/src/views/system/org/index.vue
@@ -1,336 +1,336 @@
-
-
-
-
-
-
-
-
-
-
-
-
- 搜索
- 重置
-
-
-
-
-
- 新增
-
-
- 展开/折叠
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ parseTime(scope.row.createTime) }}
-
-
-
-
- 修改
- 新增
- 删除
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{dict.label}}
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 展开/折叠
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/system/role/index.vue b/ruoyi-ui/src/views/system/role/index.vue
index 0681d3d2..65efa569 100644
--- a/ruoyi-ui/src/views/system/role/index.vue
+++ b/ruoyi-ui/src/views/system/role/index.vue
@@ -1,607 +1,607 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 搜索
- 重置
-
-
-
-
-
- 新增
-
-
- 修改
-
-
- 删除
-
-
- 导出
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ parseTime(scope.row.createTime) }}
-
-
-
-
- 修改
- 删除
- handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
-
- 更多
-
-
- 数据权限
- 分配用户
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 权限字符
-
-
-
-
-
-
-
-
- {{dict.label}}
-
-
-
- 展开/折叠
- 全选/全不选
- 父子联动
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 展开/折叠
- 全选/全不选
- 父子联动
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+ handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
+
+ 更多
+
+
+ 数据权限
+ 分配用户
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 权限字符
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue
index 2494fa24..04bc0f06 100644
--- a/ruoyi-ui/src/views/system/user/index.vue
+++ b/ruoyi-ui/src/views/system/user/index.vue
@@ -1,669 +1,669 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 搜索
- 重置
-
-
-
-
-
- 新增
-
-
- 修改
-
-
- 删除
-
-
- 导入
-
-
- 导出
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ parseTime(scope.row.createTime) }}
-
-
-
-
- 修改
- 删除
- handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
-
- 更多
-
-
- 重置密码
- 分配角色
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{dict.label}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 将文件拖到此处,或点击上传
-
-
- 是否更新已经存在的用户数据
-
-
仅允许导入xls、xlsx格式文件。
-
下载模板
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导入
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+ handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
+
+ 更多
+
+
+ 重置密码
+ 分配角色
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 将文件拖到此处,或点击上传
+
+
+ 是否更新已经存在的用户数据
+
+
仅允许导入xls、xlsx格式文件。
+
下载模板
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/system/user/profile/index.vue b/ruoyi-ui/src/views/system/user/profile/index.vue
index ad530f9a..5683d4dd 100644
--- a/ruoyi-ui/src/views/system/user/profile/index.vue
+++ b/ruoyi-ui/src/views/system/user/profile/index.vue
@@ -24,8 +24,8 @@
{{ user.email }}
- 所属部门
- {{ user.dept.deptName }} / {{ postGroup }}
+ 所属机构
+ {{ user.sysOrg.orgName }} / {{ postGroup }}
所属角色
diff --git a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue
index bf6382d3..d97e675c 100644
--- a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue
+++ b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue
@@ -1,299 +1,299 @@
-
-
-
-
-
- 生成模板
-
-
-
-
-
-
-
-
-
-
- 生成包路径
-
-
-
-
-
-
-
-
-
-
-
- 生成模块名
-
-
-
-
-
-
-
-
-
-
-
- 生成业务名
-
-
-
-
-
-
-
-
-
-
-
- 生成功能名
-
-
-
-
-
-
-
-
-
-
-
- 上级菜单
-
-
-
-
-
-
-
-
-
-
-
- 生成代码方式
-
-
-
-
- zip压缩包
- 自定义路径
-
-
-
-
-
-
- 自定义路径
-
-
-
-
-
-
-
- 最近路径快速选择
-
-
-
- 恢复默认的生成基础路径
-
-
-
-
-
-
-
-
-
-
-
-
- 树编码字段
-
-
-
-
-
-
-
-
-
-
-
-
- 树父编码字段
-
-
-
-
-
-
-
-
-
-
-
-
- 树名称字段
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 关联子表的表名
-
-
-
-
-
-
-
-
-
-
-
-
- 子表关联的外键名
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ 生成模板
+
+
+
+
+
+
+
+
+
+
+ 生成包路径
+
+
+
+
+
+
+
+
+
+
+
+ 生成模块名
+
+
+
+
+
+
+
+
+
+
+
+ 生成业务名
+
+
+
+
+
+
+
+
+
+
+
+ 生成功能名
+
+
+
+
+
+
+
+
+
+
+
+ 上级菜单
+
+
+
+
+
+
+
+
+
+
+
+ 生成代码方式
+
+
+
+
+ zip压缩包
+ 自定义路径
+
+
+
+
+
+
+ 自定义路径
+
+
+
+
+
+
+
+ 最近路径快速选择
+
+
+
+ 恢复默认的生成基础路径
+
+
+
+
+
+
+
+
+
+
+
+
+ 树编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树父编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树名称字段
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 关联子表的表名
+
+
+
+
+
+
+
+
+
+
+
+
+ 子表关联的外键名
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js
index 2506c93a..3b1bbe12 100644
--- a/ruoyi-ui/vue.config.js
+++ b/ruoyi-ui/vue.config.js
@@ -1,136 +1,136 @@
-'use strict'
-const path = require('path')
-
-function resolve(dir) {
- return path.join(__dirname, dir)
-}
-
-const CompressionPlugin = require('compression-webpack-plugin')
-
-const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
-
-const port = process.env.port || process.env.npm_config_port || 80 // 端口
-
-// vue.config.js 配置说明
-//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
-// 这里只列一部分,具体配置参考文档
-module.exports = {
- // 部署生产环境和开发环境下的URL。
- // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
- // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
- publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
- // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
- outputDir: 'dist',
- // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
- assetsDir: 'static',
- // 是否开启eslint保存检测,有效值:ture | false | 'error'
- lintOnSave: process.env.NODE_ENV === 'development',
- // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
- productionSourceMap: false,
- // webpack-dev-server 相关配置
- devServer: {
- host: '0.0.0.0',
- port: port,
- open: true,
- proxy: {
- // detail: https://cli.vuejs.org/config/#devserver-proxy
- [process.env.VUE_APP_BASE_API]: {
- target: `http://localhost:8080`,
- changeOrigin: true,
- pathRewrite: {
- ['^' + process.env.VUE_APP_BASE_API]: ''
- }
- }
- },
- disableHostCheck: true
- },
- css: {
- loaderOptions: {
- sass: {
- sassOptions: { outputStyle: "expanded" }
- }
- }
- },
- configureWebpack: {
- name: name,
- resolve: {
- alias: {
- '@': resolve('src')
- }
- },
- plugins: [
- // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
- new CompressionPlugin({
- cache: false, // 不启用文件缓存
- test: /\.(js|css|html)?$/i, // 压缩文件格式
- filename: '[path].gz[query]', // 压缩后的文件名
- algorithm: 'gzip', // 使用gzip压缩
- minRatio: 0.8 // 压缩率小于1才会压缩
- })
- ],
- },
- chainWebpack(config) {
- config.plugins.delete('preload') // TODO: need test
- config.plugins.delete('prefetch') // TODO: need test
-
- // set svg-sprite-loader
- config.module
- .rule('svg')
- .exclude.add(resolve('src/assets/icons'))
- .end()
- config.module
- .rule('icons')
- .test(/\.svg$/)
- .include.add(resolve('src/assets/icons'))
- .end()
- .use('svg-sprite-loader')
- .loader('svg-sprite-loader')
- .options({
- symbolId: 'icon-[name]'
- })
- .end()
-
- config
- .when(process.env.NODE_ENV !== 'development',
- config => {
- config
- .plugin('ScriptExtHtmlWebpackPlugin')
- .after('html')
- .use('script-ext-html-webpack-plugin', [{
- // `runtime` must same as runtimeChunk name. default is `runtime`
- inline: /runtime\..*\.js$/
- }])
- .end()
- config
- .optimization.splitChunks({
- chunks: 'all',
- cacheGroups: {
- libs: {
- name: 'chunk-libs',
- test: /[\\/]node_modules[\\/]/,
- priority: 10,
- chunks: 'initial' // only package third parties that are initially dependent
- },
- elementUI: {
- name: 'chunk-elementUI', // split elementUI into a single package
- priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
- test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
- },
- commons: {
- name: 'chunk-commons',
- test: resolve('src/components'), // can customize your rules
- minChunks: 3, // minimum common number
- priority: 5,
- reuseExistingChunk: true
- }
- }
- })
- config.optimization.runtimeChunk('single'),
- {
- from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
- to: './' //到根目录下
- }
- }
- )
- }
-}
+'use strict'
+const path = require('path')
+
+function resolve(dir) {
+ return path.join(__dirname, dir)
+}
+
+const CompressionPlugin = require('compression-webpack-plugin')
+
+const name = process.env.VUE_APP_TITLE || '智能作业系统' // 网页标题
+
+const port = process.env.port || process.env.npm_config_port || 80 // 端口
+
+// vue.config.js 配置说明
+//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
+// 这里只列一部分,具体配置参考文档
+module.exports = {
+ // 部署生产环境和开发环境下的URL。
+ // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
+ // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
+ publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
+ // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
+ outputDir: 'dist',
+ // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
+ assetsDir: 'static',
+ // 是否开启eslint保存检测,有效值:ture | false | 'error'
+ lintOnSave: process.env.NODE_ENV === 'development',
+ // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
+ productionSourceMap: false,
+ // webpack-dev-server 相关配置
+ devServer: {
+ host: '0.0.0.0',
+ port: port,
+ open: true,
+ proxy: {
+ // detail: https://cli.vuejs.org/config/#devserver-proxy
+ [process.env.VUE_APP_BASE_API]: {
+ target: `http://localhost:9998`,
+ changeOrigin: true,
+ pathRewrite: {
+ ['^' + process.env.VUE_APP_BASE_API]: ''
+ }
+ }
+ },
+ disableHostCheck: true
+ },
+ css: {
+ loaderOptions: {
+ sass: {
+ sassOptions: { outputStyle: "expanded" }
+ }
+ }
+ },
+ configureWebpack: {
+ name: name,
+ resolve: {
+ alias: {
+ '@': resolve('src')
+ }
+ },
+ plugins: [
+ // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
+ new CompressionPlugin({
+ cache: false, // 不启用文件缓存
+ test: /\.(js|css|html)?$/i, // 压缩文件格式
+ filename: '[path].gz[query]', // 压缩后的文件名
+ algorithm: 'gzip', // 使用gzip压缩
+ minRatio: 0.8 // 压缩率小于1才会压缩
+ })
+ ],
+ },
+ chainWebpack(config) {
+ config.plugins.delete('preload') // TODO: need test
+ config.plugins.delete('prefetch') // TODO: need test
+
+ // set svg-sprite-loader
+ config.module
+ .rule('svg')
+ .exclude.add(resolve('src/assets/icons'))
+ .end()
+ config.module
+ .rule('icons')
+ .test(/\.svg$/)
+ .include.add(resolve('src/assets/icons'))
+ .end()
+ .use('svg-sprite-loader')
+ .loader('svg-sprite-loader')
+ .options({
+ symbolId: 'icon-[name]'
+ })
+ .end()
+
+ config
+ .when(process.env.NODE_ENV !== 'development',
+ config => {
+ config
+ .plugin('ScriptExtHtmlWebpackPlugin')
+ .after('html')
+ .use('script-ext-html-webpack-plugin', [{
+ // `runtime` must same as runtimeChunk name. default is `runtime`
+ inline: /runtime\..*\.js$/
+ }])
+ .end()
+ config
+ .optimization.splitChunks({
+ chunks: 'all',
+ cacheGroups: {
+ libs: {
+ name: 'chunk-libs',
+ test: /[\\/]node_modules[\\/]/,
+ priority: 10,
+ chunks: 'initial' // only package third parties that are initially dependent
+ },
+ elementUI: {
+ name: 'chunk-elementUI', // split elementUI into a single package
+ priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
+ test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
+ },
+ commons: {
+ name: 'chunk-commons',
+ test: resolve('src/components'), // can customize your rules
+ minChunks: 3, // minimum common number
+ priority: 5,
+ reuseExistingChunk: true
+ }
+ }
+ })
+ config.optimization.runtimeChunk('single'),
+ {
+ from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
+ to: './' //到根目录下
+ }
+ }
+ )
+ }
+}