feat(system): 实现基于Session的认证与菜单管理功能
- 菜单图标字段从icon改为vueIcon,适配前端图标组件 - 登录认证方式改为Session认证,使用FormData格式提交数据 - 验证码获取方式改为直接图片URL,防止缓存问题 - 权限验证改为基于Session的用户角色判断 - axios请求配置支持withCredentials,允许携带cookie - 部门管理新增树形结构构建方法 - 菜单管理新增路由地址、组件路径等字段 - 字典管理新增根据字典类型查询数据接口 - 系统配置新增根据配置键查询接口 - 首页控制器新增用户信息和路由信息获取接口- 菜单控制器新增菜单列表、详情、增删改查接口 - 数据库菜单表新增path、component、query、status、vue_icon、is_frame字段master
parent
ffe6ce25df
commit
bbe760abf6
|
|
@ -1,21 +1,21 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// 登录方法
|
// 登录方法 - 基于 Session 认证,使用 FormData 格式
|
||||||
export function login(username, password, code, uuid) {
|
export function login(username, password, code, rememberMe) {
|
||||||
const data = {
|
const formData = new FormData()
|
||||||
username,
|
formData.append('username', username)
|
||||||
password,
|
formData.append('password', password)
|
||||||
code,
|
formData.append('validateCode', code)
|
||||||
uuid
|
formData.append('rememberMe', rememberMe || false)
|
||||||
}
|
|
||||||
return request({
|
return request({
|
||||||
url: '/login',
|
url: '/login',
|
||||||
headers: {
|
headers: {
|
||||||
isToken: false,
|
isToken: false,
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
repeatSubmit: false
|
repeatSubmit: false
|
||||||
},
|
},
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: formData
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,22 +39,10 @@ export function getInfo() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退出方法
|
// 退出方法 - 基于 Session 认证
|
||||||
export function logout() {
|
export function logout() {
|
||||||
return request({
|
return request({
|
||||||
url: '/logout',
|
url: '/logout',
|
||||||
method: 'post'
|
method: 'post'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取验证码
|
|
||||||
export function getCodeImg() {
|
|
||||||
return request({
|
|
||||||
url: '/captchaImage',
|
|
||||||
headers: {
|
|
||||||
isToken: false
|
|
||||||
},
|
|
||||||
method: 'get',
|
|
||||||
timeout: 20000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -3,7 +3,6 @@ import store from './store'
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
import NProgress from 'nprogress'
|
import NProgress from 'nprogress'
|
||||||
import 'nprogress/nprogress.css'
|
import 'nprogress/nprogress.css'
|
||||||
import { getToken } from '@/utils/auth'
|
|
||||||
import { isPathMatch } from '@/utils/validate'
|
import { isPathMatch } from '@/utils/validate'
|
||||||
import { isRelogin } from '@/utils/request'
|
import { isRelogin } from '@/utils/request'
|
||||||
|
|
||||||
|
|
@ -17,43 +16,37 @@ const isWhiteList = (path) => {
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
if (getToken()) {
|
// 基于 Session 认证:通过是否有角色信息来判断登录状态
|
||||||
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
|
const hasRoles = store.getters.roles && store.getters.roles.length > 0
|
||||||
/* has token*/
|
|
||||||
if (to.path === '/login') {
|
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
|
||||||
next({ path: '/' })
|
|
||||||
NProgress.done()
|
if (isWhiteList(to.path)) {
|
||||||
} else if (isWhiteList(to.path)) {
|
// 在免登录白名单,直接进入
|
||||||
next()
|
next()
|
||||||
} else {
|
NProgress.done()
|
||||||
if (store.getters.roles.length === 0) {
|
|
||||||
isRelogin.show = true
|
|
||||||
// 判断当前用户是否已拉取完user_info信息
|
|
||||||
store.dispatch('GetInfo').then(() => {
|
|
||||||
isRelogin.show = false
|
|
||||||
store.dispatch('GenerateRoutes').then(accessRoutes => {
|
|
||||||
// 根据roles权限生成可访问的路由表
|
|
||||||
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
|
||||||
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
store.dispatch('LogOut').then(() => {
|
|
||||||
Message.error(err)
|
|
||||||
next({ path: '/' })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 没有token
|
if (hasRoles) {
|
||||||
if (isWhiteList(to.path)) {
|
// 已有用户信息,放行
|
||||||
// 在免登录白名单,直接进入
|
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
|
// 没有用户信息,尝试获取
|
||||||
NProgress.done()
|
isRelogin.show = true
|
||||||
|
store.dispatch('GetInfo').then(() => {
|
||||||
|
isRelogin.show = false
|
||||||
|
store.dispatch('GenerateRoutes').then(accessRoutes => {
|
||||||
|
// 根据roles权限生成可访问的路由表
|
||||||
|
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
||||||
|
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
||||||
|
})
|
||||||
|
}).catch(err => {
|
||||||
|
// 获取用户信息失败,说明未登录或 Session 已过期
|
||||||
|
store.dispatch('FedLogOut').then(() => {
|
||||||
|
Message.error(err || '未登录或登录超时,请重新登录')
|
||||||
|
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`)
|
||||||
|
NProgress.done()
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { MessageBox, } from 'element-ui'
|
import { MessageBox, } from 'element-ui'
|
||||||
import { login, logout, getInfo } from '@/api/login'
|
import { login, logout, getInfo } from '@/api/login'
|
||||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
|
||||||
import { isHttp, isEmpty } from "@/utils/validate"
|
import { isHttp, isEmpty } from "@/utils/validate"
|
||||||
import defAva from '@/assets/images/profile.jpg'
|
import defAva from '@/assets/images/profile.jpg'
|
||||||
|
|
||||||
const user = {
|
const user = {
|
||||||
state: {
|
state: {
|
||||||
token: getToken(),
|
|
||||||
id: '',
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
nickName: '',
|
nickName: '',
|
||||||
|
|
@ -17,9 +15,6 @@ const user = {
|
||||||
},
|
},
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_TOKEN: (state, token) => {
|
|
||||||
state.token = token
|
|
||||||
},
|
|
||||||
SET_ID: (state, id) => {
|
SET_ID: (state, id) => {
|
||||||
state.id = id
|
state.id = id
|
||||||
},
|
},
|
||||||
|
|
@ -41,16 +36,14 @@ const user = {
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
// 登录
|
// 登录 - 基于 Session 认证,不需要保存 token
|
||||||
Login({ commit }, userInfo) {
|
Login({ commit }, userInfo) {
|
||||||
const username = userInfo.username.trim()
|
const username = userInfo.username.trim()
|
||||||
const password = userInfo.password
|
const password = userInfo.password
|
||||||
const code = userInfo.code
|
const code = userInfo.code
|
||||||
const uuid = userInfo.uuid
|
const rememberMe = userInfo.rememberMe
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login(username, password, code, uuid).then(res => {
|
login(username, password, code, rememberMe).then(res => {
|
||||||
setToken(res.token)
|
|
||||||
commit('SET_TOKEN', res.token)
|
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
|
|
@ -62,14 +55,16 @@ const user = {
|
||||||
GetInfo({ commit, state }) {
|
GetInfo({ commit, state }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getInfo().then(res => {
|
getInfo().then(res => {
|
||||||
const user = res.user
|
// 后端返回的数据在 res.data 中
|
||||||
|
const data = res.data || res
|
||||||
|
const user = data.user
|
||||||
let avatar = user.avatar || ""
|
let avatar = user.avatar || ""
|
||||||
if (!isHttp(avatar)) {
|
if (!isHttp(avatar)) {
|
||||||
avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
|
avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
|
||||||
}
|
}
|
||||||
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
|
||||||
commit('SET_ROLES', res.roles)
|
commit('SET_ROLES', data.roles)
|
||||||
commit('SET_PERMISSIONS', res.permissions)
|
commit('SET_PERMISSIONS', data.permissions)
|
||||||
} else {
|
} else {
|
||||||
commit('SET_ROLES', ['ROLE_DEFAULT'])
|
commit('SET_ROLES', ['ROLE_DEFAULT'])
|
||||||
}
|
}
|
||||||
|
|
@ -78,13 +73,13 @@ const user = {
|
||||||
commit('SET_NICK_NAME', user.nickName)
|
commit('SET_NICK_NAME', user.nickName)
|
||||||
commit('SET_AVATAR', avatar)
|
commit('SET_AVATAR', avatar)
|
||||||
/* 初始密码提示 */
|
/* 初始密码提示 */
|
||||||
if(res.isDefaultModifyPwd) {
|
if(data.isDefaultModifyPwd) {
|
||||||
MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||||
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
/* 过期密码提示 */
|
/* 过期密码提示 */
|
||||||
if(!res.isDefaultModifyPwd && res.isPasswordExpired) {
|
if(!data.isDefaultModifyPwd && data.isPasswordExpired) {
|
||||||
MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||||
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
|
|
@ -96,14 +91,12 @@ const user = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 退出系统
|
// 退出系统 - 基于 Session 认证
|
||||||
LogOut({ commit, state }) {
|
LogOut({ commit, state }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
logout(state.token).then(() => {
|
logout().then(() => {
|
||||||
commit('SET_TOKEN', '')
|
|
||||||
commit('SET_ROLES', [])
|
commit('SET_ROLES', [])
|
||||||
commit('SET_PERMISSIONS', [])
|
commit('SET_PERMISSIONS', [])
|
||||||
removeToken()
|
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
|
|
@ -111,11 +104,11 @@ const user = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 前端 登出
|
// 前端 登出 - 清除状态
|
||||||
FedLogOut({ commit }) {
|
FedLogOut({ commit }) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
commit('SET_TOKEN', '')
|
commit('SET_ROLES', [])
|
||||||
removeToken()
|
commit('SET_PERMISSIONS', [])
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { Notification, MessageBox, Message, Loading } from 'element-ui'
|
import { Notification, MessageBox, Message, Loading } from 'element-ui'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { getToken } from '@/utils/auth'
|
|
||||||
import errorCode from '@/utils/errorCode'
|
import errorCode from '@/utils/errorCode'
|
||||||
import { tansParams, blobValidate } from "@/utils/ruoyi"
|
import { tansParams, blobValidate } from "@/utils/ruoyi"
|
||||||
import cache from '@/plugins/cache'
|
import cache from '@/plugins/cache'
|
||||||
|
|
@ -17,18 +16,17 @@ const service = axios.create({
|
||||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||||
baseURL: process.env.VUE_APP_BASE_API,
|
baseURL: process.env.VUE_APP_BASE_API,
|
||||||
// 超时
|
// 超时
|
||||||
timeout: 10000
|
timeout: 10000,
|
||||||
|
// 允许携带cookie(Session认证必需)
|
||||||
|
withCredentials: true
|
||||||
})
|
})
|
||||||
|
|
||||||
// request拦截器
|
// request拦截器
|
||||||
service.interceptors.request.use(config => {
|
service.interceptors.request.use(config => {
|
||||||
// 是否需要设置 token
|
|
||||||
const isToken = (config.headers || {}).isToken === false
|
|
||||||
// 是否需要防止数据重复提交
|
// 是否需要防止数据重复提交
|
||||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
||||||
if (getToken() && !isToken) {
|
config.headers['X-Requested-With'] = 'H5'
|
||||||
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
// Session 认证依赖 Cookie,无需手动设置 token
|
||||||
}
|
|
||||||
// get请求映射params参数
|
// get请求映射params参数
|
||||||
if (config.method === 'get' && config.params) {
|
if (config.method === 'get' && config.params) {
|
||||||
let url = config.url + '?' + tansParams(config.params)
|
let url = config.url + '?' + tansParams(config.params)
|
||||||
|
|
@ -39,7 +37,7 @@ service.interceptors.request.use(config => {
|
||||||
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
|
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
|
||||||
const requestObj = {
|
const requestObj = {
|
||||||
url: config.url,
|
url: config.url,
|
||||||
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
|
data: (typeof config.data === 'object' && !(config.data instanceof FormData)) ? JSON.stringify(config.data) : config.data,
|
||||||
time: new Date().getTime()
|
time: new Date().getTime()
|
||||||
}
|
}
|
||||||
const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
|
const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
|
||||||
|
|
@ -79,7 +77,7 @@ service.interceptors.response.use(res => {
|
||||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||||
// 二进制数据则直接返回
|
// 二进制数据则直接返回
|
||||||
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
|
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
|
||||||
return res.data
|
return res
|
||||||
}
|
}
|
||||||
if (code === 401) {
|
if (code === 401) {
|
||||||
if (!isRelogin.show) {
|
if (!isRelogin.show) {
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getCodeImg } from "@/api/login"
|
|
||||||
import Cookies from "js-cookie"
|
import Cookies from "js-cookie"
|
||||||
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
||||||
|
|
||||||
|
|
@ -74,10 +73,9 @@ export default {
|
||||||
codeUrl: "",
|
codeUrl: "",
|
||||||
loginForm: {
|
loginForm: {
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "admin123",
|
password: "admin@123",
|
||||||
rememberMe: false,
|
rememberMe: false,
|
||||||
code: "",
|
code: ""
|
||||||
uuid: ""
|
|
||||||
},
|
},
|
||||||
loginRules: {
|
loginRules: {
|
||||||
username: [
|
username: [
|
||||||
|
|
@ -110,13 +108,10 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getCode() {
|
getCode() {
|
||||||
getCodeImg().then(res => {
|
// 基于 Session 认证,直接使用图片 URL,添加时间戳防止缓存
|
||||||
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
|
const timestamp = new Date().getTime()
|
||||||
if (this.captchaEnabled) {
|
this.codeUrl = `${process.env.VUE_APP_BASE_API}/captcha/captchaImage?type=math&s=${timestamp}`
|
||||||
this.codeUrl = "data:image/gif;base64," + res.img
|
this.captchaEnabled = true
|
||||||
this.loginForm.uuid = res.uuid
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
getCookie() {
|
getCookie() {
|
||||||
const username = Cookies.get("username")
|
const username = Cookies.get("username")
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,9 @@
|
||||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||||
>
|
>
|
||||||
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160"></el-table-column>
|
<el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160"></el-table-column>
|
||||||
<el-table-column prop="icon" label="图标" align="center" width="100">
|
<el-table-column prop="vueIcon" label="图标" align="center" width="100">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<svg-icon :icon-class="scope.row.icon" />
|
<svg-icon :icon-class="scope.row.vueIcon" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="orderNum" label="排序" width="60"></el-table-column>
|
<el-table-column prop="orderNum" label="排序" width="60"></el-table-column>
|
||||||
|
|
@ -131,19 +131,19 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12" v-if="form.menuType != 'F'">
|
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||||
<el-form-item label="菜单图标" prop="icon">
|
<el-form-item label="菜单图标" prop="vueIcon">
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
width="460"
|
width="460"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
@show="$refs['iconSelect'].reset()"
|
@show="$refs['iconSelect'].reset()"
|
||||||
>
|
>
|
||||||
<IconSelect ref="iconSelect" @selected="selected" :active-icon="form.icon" />
|
<IconSelect ref="iconSelect" @selected="selected" :active-icon="form.vueIcon" />
|
||||||
<el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly>
|
<el-input slot="reference" v-model="form.vueIcon" placeholder="点击选择图标" readonly>
|
||||||
<svg-icon
|
<svg-icon
|
||||||
v-if="form.icon"
|
v-if="form.vueIcon"
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
:icon-class="form.icon"
|
:icon-class="form.vueIcon"
|
||||||
style="width: 25px;"
|
style="width: 25px;"
|
||||||
/>
|
/>
|
||||||
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
|
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
|
||||||
|
|
@ -353,7 +353,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
// 选择图标
|
// 选择图标
|
||||||
selected(name) {
|
selected(name) {
|
||||||
this.form.icon = name
|
this.form.vueIcon = name
|
||||||
},
|
},
|
||||||
/** 查询菜单列表 */
|
/** 查询菜单列表 */
|
||||||
getList() {
|
getList() {
|
||||||
|
|
|
||||||
|
|
@ -555,4 +555,4 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const CompressionPlugin = require('compression-webpack-plugin')
|
||||||
|
|
||||||
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
||||||
|
|
||||||
const baseUrl = 'http://localhost:8080' // 后端接口
|
const baseUrl = 'http://localhost:28080' // 后端接口
|
||||||
|
|
||||||
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
||||||
|
|
||||||
|
|
@ -38,6 +38,10 @@ module.exports = {
|
||||||
[process.env.VUE_APP_BASE_API]: {
|
[process.env.VUE_APP_BASE_API]: {
|
||||||
target: baseUrl,
|
target: baseUrl,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
// Session 认证需要携带 Cookie
|
||||||
|
cookieDomainRewrite: {
|
||||||
|
'*': ''
|
||||||
|
},
|
||||||
pathRewrite: {
|
pathRewrite: {
|
||||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
@ -48,6 +50,7 @@ public class SysCaptchaController extends BaseController
|
||||||
response.setContentType("image/jpeg");
|
response.setContentType("image/jpeg");
|
||||||
|
|
||||||
String type = request.getParameter("type");
|
String type = request.getParameter("type");
|
||||||
|
type = StringUtils.isEmpty(type) ? "math" : type;
|
||||||
String capStr = null;
|
String capStr = null;
|
||||||
String code = null;
|
String code = null;
|
||||||
BufferedImage bi = null;
|
BufferedImage bi = null;
|
||||||
|
|
|
||||||
|
|
@ -155,4 +155,11 @@ public class SysConfigController extends BaseController
|
||||||
{
|
{
|
||||||
return configService.checkConfigKeyUnique(config);
|
return configService.checkConfigKeyUnique(config);
|
||||||
}
|
}
|
||||||
|
@GetMapping("/configKey/{key}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult queryKey(@PathVariable("key") String key)
|
||||||
|
{
|
||||||
|
return success(configService.selectConfigByKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.system.service.ISysDictTypeService;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
@ -33,7 +37,8 @@ public class SysDictDataController extends BaseController
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysDictDataService dictDataService;
|
private ISysDictDataService dictDataService;
|
||||||
|
@Autowired
|
||||||
|
private ISysDictTypeService dictTypeService;
|
||||||
@RequiresPermissions("system:dict:view")
|
@RequiresPermissions("system:dict:view")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String dictData()
|
public String dictData()
|
||||||
|
|
@ -72,6 +77,22 @@ public class SysDictDataController extends BaseController
|
||||||
mmap.put("dictType", dictType);
|
mmap.put("dictType", dictType);
|
||||||
return prefix + "/add";
|
return prefix + "/add";
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 新增字典类型
|
||||||
|
*/
|
||||||
|
|
||||||
|
@GetMapping("/type/{dictType}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult add(@PathVariable("dictType") String dictType)
|
||||||
|
{
|
||||||
|
|
||||||
|
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
|
||||||
|
if (StringUtils.isNull(data))
|
||||||
|
{
|
||||||
|
data = new ArrayList<SysDictData>();
|
||||||
|
}
|
||||||
|
return success(data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增保存字典类型
|
* 新增保存字典类型
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,11 @@
|
||||||
package com.ruoyi.web.controller.system;
|
package com.ruoyi.web.controller.system;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.servlet.http.Cookie;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.ModelMap;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.RuoYiConfig;
|
||||||
import com.ruoyi.common.constant.ShiroConstants;
|
import com.ruoyi.common.constant.ShiroConstants;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.SysMenu;
|
import com.ruoyi.common.core.domain.entity.SysMenu;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.text.Convert;
|
import com.ruoyi.common.core.text.Convert;
|
||||||
import com.ruoyi.common.utils.CookieUtils;
|
import com.ruoyi.common.utils.CookieUtils;
|
||||||
|
|
@ -25,6 +15,18 @@ import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||||
import com.ruoyi.system.service.ISysConfigService;
|
import com.ruoyi.system.service.ISysConfigService;
|
||||||
import com.ruoyi.system.service.ISysMenuService;
|
import com.ruoyi.system.service.ISysMenuService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页 业务处理
|
* 首页 业务处理
|
||||||
|
|
@ -39,7 +41,6 @@ public class SysIndexController extends BaseController
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysConfigService configService;
|
private ISysConfigService configService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysPasswordService passwordService;
|
private SysPasswordService passwordService;
|
||||||
@GetMapping("/test")
|
@GetMapping("/test")
|
||||||
|
|
@ -178,4 +179,164 @@ public class SysIndexController extends BaseController
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息(供前后端分离的前端调用)
|
||||||
|
*
|
||||||
|
* @return 用户信息、角色、权限
|
||||||
|
*/
|
||||||
|
@GetMapping("/getInfo")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult getInfo()
|
||||||
|
{
|
||||||
|
SysUser user = getSysUser();
|
||||||
|
if (StringUtils.isNull(user))
|
||||||
|
{
|
||||||
|
return AjaxResult.error("未登录或登录超时");
|
||||||
|
}
|
||||||
|
// 角色集合
|
||||||
|
Set<String> roles = user.getRoles().stream().map(SysRole::getRoleKey).collect(Collectors.toSet());
|
||||||
|
// 权限集合
|
||||||
|
Set<String> permissions = menuService.selectPermsByUserId(user.getUserId());
|
||||||
|
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("user", user);
|
||||||
|
data.put("roles", roles);
|
||||||
|
data.put("permissions", permissions);
|
||||||
|
data.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
|
||||||
|
data.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
|
||||||
|
|
||||||
|
return AjaxResult.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取路由信息(供前后端分离的前端调用)
|
||||||
|
*
|
||||||
|
* @return 路由信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/getRouters")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult getRouters()
|
||||||
|
{
|
||||||
|
SysUser user = getSysUser();
|
||||||
|
if (StringUtils.isNull(user))
|
||||||
|
{
|
||||||
|
return AjaxResult.error("未登录或登录超时");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SysMenu> menus = menuService.selectMenusByUser(user);
|
||||||
|
List<Map<String, Object>> routerList = buildRouters(menus);
|
||||||
|
return AjaxResult.success(routerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建前端路由所需格式(简化版,使用现有字段)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> buildRouters(List<SysMenu> menus)
|
||||||
|
{
|
||||||
|
List<Map<String, Object>> routers = new ArrayList<>();
|
||||||
|
for (SysMenu menu : menus)
|
||||||
|
{
|
||||||
|
Map<String, Object> router = new HashMap<>();
|
||||||
|
|
||||||
|
// 基本属性
|
||||||
|
router.put("name", getRouteName(menu));
|
||||||
|
router.put("path", getRouterPath(menu));
|
||||||
|
router.put("hidden", "1".equals(menu.getVisible()));
|
||||||
|
router.put("component", getComponent(menu));
|
||||||
|
|
||||||
|
// 路由元信息
|
||||||
|
router.put("meta", buildMeta(menu));
|
||||||
|
|
||||||
|
// 子路由
|
||||||
|
List<SysMenu> cMenus = menu.getChildren();
|
||||||
|
if (cMenus != null && !cMenus.isEmpty())
|
||||||
|
{
|
||||||
|
router.put("alwaysShow", true);
|
||||||
|
router.put("redirect", "noRedirect");
|
||||||
|
router.put("children", buildRouters(cMenus));
|
||||||
|
}
|
||||||
|
|
||||||
|
routers.add(router);
|
||||||
|
}
|
||||||
|
return routers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建路由元信息
|
||||||
|
*/
|
||||||
|
private Map<String, Object> buildMeta(SysMenu menu)
|
||||||
|
{
|
||||||
|
Map<String, Object> meta = new HashMap<>();
|
||||||
|
meta.put("title", menu.getMenuName());
|
||||||
|
meta.put("icon", menu.getVueIcon());
|
||||||
|
meta.put("noCache", "1".equals(menu.getIsRefresh()));
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取路由名称
|
||||||
|
*/
|
||||||
|
private String getRouteName(SysMenu menu)
|
||||||
|
{
|
||||||
|
// 使用 path 字段作为路由名称,如果没有则使用 menuName
|
||||||
|
String routerName = menu.getPath();
|
||||||
|
if (StringUtils.isEmpty(routerName))
|
||||||
|
{
|
||||||
|
routerName = menu.getMenuName();
|
||||||
|
}
|
||||||
|
// 首字母大写
|
||||||
|
return StringUtils.isNotEmpty(routerName) ? StringUtils.capitalize(routerName) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取路由地址
|
||||||
|
*/
|
||||||
|
private String getRouterPath(SysMenu menu)
|
||||||
|
{
|
||||||
|
// 优先使用 path 字段,如果没有则使用 url 字段
|
||||||
|
String routerPath = menu.getPath();
|
||||||
|
if (StringUtils.isEmpty(routerPath))
|
||||||
|
{
|
||||||
|
routerPath = menu.getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 一级目录需要加 /
|
||||||
|
if (menu.getParentId() == 0 && "M".equals(menu.getMenuType()))
|
||||||
|
{
|
||||||
|
if (!routerPath.startsWith("/"))
|
||||||
|
{
|
||||||
|
routerPath = "/" + routerPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.isNotEmpty(routerPath) ? routerPath : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取组件信息
|
||||||
|
*/
|
||||||
|
private String getComponent(SysMenu menu)
|
||||||
|
{
|
||||||
|
// 目录使用 Layout
|
||||||
|
if ("M".equals(menu.getMenuType()))
|
||||||
|
{
|
||||||
|
if (menu.getParentId() == 0)
|
||||||
|
{
|
||||||
|
return "Layout";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "ParentView";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 菜单使用 url 字段作为组件路径
|
||||||
|
else if ("C".equals(menu.getMenuType()))
|
||||||
|
{
|
||||||
|
String component = menu.getComponent();
|
||||||
|
return StringUtils.isNotEmpty(component) ? component : menu.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Layout";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
|
@ -52,6 +48,15 @@ public class SysMenuController extends BaseController
|
||||||
List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
|
List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
|
||||||
return menuList;
|
return menuList;
|
||||||
}
|
}
|
||||||
|
@RequiresPermissions("system:menu:list")
|
||||||
|
@GetMapping("/list")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult listMenu(SysMenu menu)
|
||||||
|
{
|
||||||
|
Long userId = ShiroUtils.getUserId();
|
||||||
|
List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
|
||||||
|
return AjaxResult.success(menuList);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除菜单
|
* 删除菜单
|
||||||
|
|
@ -73,6 +78,23 @@ public class SysMenuController extends BaseController
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
||||||
return toAjax(menuService.deleteMenuById(menuId));
|
return toAjax(menuService.deleteMenuById(menuId));
|
||||||
}
|
}
|
||||||
|
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
|
||||||
|
@RequiresPermissions("system:menu:remove")
|
||||||
|
@DeleteMapping("/{menuId}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult delete(@PathVariable("menuId") Long menuId)
|
||||||
|
{
|
||||||
|
if (menuService.selectCountMenuByParentId(menuId) > 0)
|
||||||
|
{
|
||||||
|
return AjaxResult.warn("存在子菜单,不允许删除");
|
||||||
|
}
|
||||||
|
if (menuService.selectCountRoleMenuByMenuId(menuId) > 0)
|
||||||
|
{
|
||||||
|
return AjaxResult.warn("菜单已分配,不允许删除");
|
||||||
|
}
|
||||||
|
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
||||||
|
return toAjax(menuService.deleteMenuById(menuId));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增
|
* 新增
|
||||||
|
|
@ -113,6 +135,20 @@ public class SysMenuController extends BaseController
|
||||||
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
||||||
return toAjax(menuService.insertMenu(menu));
|
return toAjax(menuService.insertMenu(menu));
|
||||||
}
|
}
|
||||||
|
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
|
||||||
|
@RequiresPermissions("system:menu:add")
|
||||||
|
@PostMapping()
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult insert(@RequestBody @Validated SysMenu menu)
|
||||||
|
{
|
||||||
|
if (!menuService.checkMenuNameUnique(menu))
|
||||||
|
{
|
||||||
|
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
||||||
|
}
|
||||||
|
menu.setCreateBy(getLoginName());
|
||||||
|
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
||||||
|
return toAjax(menuService.insertMenu(menu));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改菜单
|
* 修改菜单
|
||||||
|
|
@ -124,6 +160,30 @@ public class SysMenuController extends BaseController
|
||||||
mmap.put("menu", menuService.selectMenuById(menuId));
|
mmap.put("menu", menuService.selectMenuById(menuId));
|
||||||
return prefix + "/edit";
|
return prefix + "/edit";
|
||||||
}
|
}
|
||||||
|
@RequiresPermissions("system:menu:edit")
|
||||||
|
@GetMapping("/{menuId}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult query(@PathVariable("menuId") Long menuId)
|
||||||
|
{
|
||||||
|
|
||||||
|
return AjaxResult.success(menuService.selectMenuById(menuId));
|
||||||
|
}
|
||||||
|
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
|
||||||
|
@RequiresPermissions("system:menu:edit")
|
||||||
|
@PutMapping()
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult edit(@RequestBody @Validated SysMenu menu)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!menuService.checkMenuNameUnique(menu))
|
||||||
|
{
|
||||||
|
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
||||||
|
}
|
||||||
|
menu.setUpdateBy(getLoginName());
|
||||||
|
AuthorizationUtils.clearAllCachedAuthorizationInfo();
|
||||||
|
return toAjax(menuService.updateMenu(menu));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改保存菜单
|
* 修改保存菜单
|
||||||
|
|
@ -195,4 +255,17 @@ public class SysMenuController extends BaseController
|
||||||
mmap.put("menu", menuService.selectMenuById(menuId));
|
mmap.put("menu", menuService.selectMenuById(menuId));
|
||||||
return prefix + "/tree";
|
return prefix + "/tree";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取路由信息
|
||||||
|
*
|
||||||
|
* @return 路由信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/getRouters")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult getRouters()
|
||||||
|
{
|
||||||
|
List<SysMenu> menus = menuService.selectMenusByUser(getSysUser());
|
||||||
|
return AjaxResult.success(menus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -363,4 +363,31 @@ public class SysUserController extends BaseController
|
||||||
mmap.put("dept", value==null?new SysDept():value);
|
mmap.put("dept", value==null?new SysDept():value);
|
||||||
return prefix + "/deptTree";
|
return prefix + "/deptTree";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------VUE页面使用---------------------------
|
||||||
|
@RequiresPermissions("system:user:list")
|
||||||
|
@GetMapping("/list")
|
||||||
|
@ResponseBody
|
||||||
|
public TableDataInfo listPage(SysUser user) {
|
||||||
|
startPage();
|
||||||
|
List<SysUser> list = userService.selectUserList(user);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
@RequiresPermissions("system:user:list")
|
||||||
|
@GetMapping("/{userId}")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult query(@PathVariable("userId") Long userId) {
|
||||||
|
return success(userService.selectUserById(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取部门树列表
|
||||||
|
*/
|
||||||
|
@RequiresPermissions("system:user:list")
|
||||||
|
@GetMapping("/deptTree")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult deptTree(SysDept dept) {
|
||||||
|
return success(deptService.selectDeptTreeList(dept));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.ruoyi.common.core.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysMenu;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Treeselect树结构实体类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class TreeSelect implements Serializable
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 节点ID */
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 节点名称 */
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
/** 节点禁用 */
|
||||||
|
private boolean disabled = false;
|
||||||
|
|
||||||
|
/** 子节点 */
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
|
private List<TreeSelect> children;
|
||||||
|
|
||||||
|
public TreeSelect()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeSelect(SysDept dept)
|
||||||
|
{
|
||||||
|
this.id = dept.getDeptId();
|
||||||
|
this.label = dept.getDeptName();
|
||||||
|
this.disabled = StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus());
|
||||||
|
this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeSelect(SysMenu menu)
|
||||||
|
{
|
||||||
|
this.id = menu.getMenuId();
|
||||||
|
this.label = menu.getMenuName();
|
||||||
|
this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel()
|
||||||
|
{
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label)
|
||||||
|
{
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDisabled()
|
||||||
|
{
|
||||||
|
return disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisabled(boolean disabled)
|
||||||
|
{
|
||||||
|
this.disabled = disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TreeSelect> getChildren()
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildren(List<TreeSelect> children)
|
||||||
|
{
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,9 @@ import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门表 sys_dept
|
* 部门表 sys_dept
|
||||||
*
|
*
|
||||||
|
|
@ -53,7 +56,8 @@ public class SysDept extends BaseEntity
|
||||||
|
|
||||||
/** 排除编号 */
|
/** 排除编号 */
|
||||||
private Long excludeId;
|
private Long excludeId;
|
||||||
|
/** 子部门 */
|
||||||
|
private List<SysDept> children = new ArrayList<SysDept>();
|
||||||
public Long getDeptId()
|
public Long getDeptId()
|
||||||
{
|
{
|
||||||
return deptId;
|
return deptId;
|
||||||
|
|
@ -181,6 +185,14 @@ public class SysDept extends BaseEntity
|
||||||
this.excludeId = excludeId;
|
this.excludeId = excludeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<SysDept> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildren(List<SysDept> children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ package com.ruoyi.common.core.domain.entity;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
|
@ -12,6 +15,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
|
@ToString
|
||||||
public class SysMenu extends BaseEntity
|
public class SysMenu extends BaseEntity
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
@ -52,6 +56,23 @@ public class SysMenu extends BaseEntity
|
||||||
/** 菜单图标 */
|
/** 菜单图标 */
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|
||||||
|
/** 路由地址 */
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
|
||||||
|
/** 组件路径 */
|
||||||
|
private String component;
|
||||||
|
|
||||||
|
/** 路由参数 */
|
||||||
|
private String query;
|
||||||
|
|
||||||
|
/** 是否为外链(0是 1否) */
|
||||||
|
private String isFrame;
|
||||||
|
|
||||||
|
/** 菜单状态(0正常 1停用) */
|
||||||
|
private String status;
|
||||||
|
/** 菜单图标 */
|
||||||
|
private String vueIcon;
|
||||||
/** 子菜单 */
|
/** 子菜单 */
|
||||||
private List<SysMenu> children = new ArrayList<SysMenu>();
|
private List<SysMenu> children = new ArrayList<SysMenu>();
|
||||||
|
|
||||||
|
|
@ -181,6 +202,59 @@ public class SysMenu extends BaseEntity
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPath(String path)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getComponent() {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComponent(String component) {
|
||||||
|
this.component = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIsFrame() {
|
||||||
|
return isFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsFrame(String isFrame) {
|
||||||
|
this.isFrame = isFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVueIcon() {
|
||||||
|
return vueIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVueIcon(String vueIcon) {
|
||||||
|
this.vueIcon = vueIcon;
|
||||||
|
}
|
||||||
|
|
||||||
public List<SysMenu> getChildren()
|
public List<SysMenu> getChildren()
|
||||||
{
|
{
|
||||||
return children;
|
return children;
|
||||||
|
|
@ -191,24 +265,5 @@ public class SysMenu extends BaseEntity
|
||||||
this.children = children;
|
this.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
|
||||||
.append("menuId", getMenuId())
|
|
||||||
.append("menuName", getMenuName())
|
|
||||||
.append("parentId", getParentId())
|
|
||||||
.append("orderNum", getOrderNum())
|
|
||||||
.append("url", getUrl())
|
|
||||||
.append("target", getTarget())
|
|
||||||
.append("menuType", getMenuType())
|
|
||||||
.append("visible", getVisible())
|
|
||||||
.append("perms", getPerms())
|
|
||||||
.append("icon", getIcon())
|
|
||||||
.append("createBy", getCreateBy())
|
|
||||||
.append("createTime", getCreateTime())
|
|
||||||
.append("updateBy", getUpdateBy())
|
|
||||||
.append("updateTime", getUpdateTime())
|
|
||||||
.append("remark", getRemark())
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.ruoyi.system.service;
|
package com.ruoyi.system.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.TreeSelect;
|
||||||
import com.ruoyi.common.core.domain.Ztree;
|
import com.ruoyi.common.core.domain.Ztree;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
|
|
@ -114,4 +116,19 @@ public interface ISysDeptService
|
||||||
* @param deptId 部门id
|
* @param deptId 部门id
|
||||||
*/
|
*/
|
||||||
public void checkDeptDataScope(Long deptId);
|
public void checkDeptDataScope(Long deptId);
|
||||||
|
/**
|
||||||
|
* 构建前端所需要树结构
|
||||||
|
*
|
||||||
|
* @param depts 部门列表
|
||||||
|
* @return 树结构列表
|
||||||
|
*/
|
||||||
|
public List<SysDept> buildDeptTree(List<SysDept> depts);
|
||||||
|
/**
|
||||||
|
* 构建前端所需要下拉树结构
|
||||||
|
*
|
||||||
|
* @param depts 部门列表
|
||||||
|
* @return 下拉树结构列表
|
||||||
|
*/
|
||||||
|
public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts);
|
||||||
|
List<TreeSelect> selectDeptTreeList(SysDept dept);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
package com.ruoyi.system.service.impl;
|
package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.TreeSelect;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -325,4 +330,89 @@ public class SysDeptServiceImpl implements ISysDeptService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TreeSelect> selectDeptTreeList(SysDept dept) {
|
||||||
|
List<SysDept> depts = SpringUtils.getAopProxy(this).selectDeptList(dept);
|
||||||
|
return buildDeptTreeSelect(depts);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 构建前端所需要下拉树结构
|
||||||
|
*
|
||||||
|
* @param depts 部门列表
|
||||||
|
* @return 下拉树结构列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts)
|
||||||
|
{
|
||||||
|
List<SysDept> deptTrees = buildDeptTree(depts);
|
||||||
|
return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 构建前端所需要树结构
|
||||||
|
*
|
||||||
|
* @param depts 部门列表
|
||||||
|
* @return 树结构列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<SysDept> buildDeptTree(List<SysDept> depts)
|
||||||
|
{
|
||||||
|
List<SysDept> returnList = new ArrayList<SysDept>();
|
||||||
|
List<Long> tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
|
||||||
|
for (SysDept dept : depts)
|
||||||
|
{
|
||||||
|
// 如果是顶级节点, 遍历该父节点的所有子节点
|
||||||
|
if (!tempList.contains(dept.getParentId()))
|
||||||
|
{
|
||||||
|
recursionFn(depts, dept);
|
||||||
|
returnList.add(dept);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (returnList.isEmpty())
|
||||||
|
{
|
||||||
|
returnList = depts;
|
||||||
|
}
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 递归列表
|
||||||
|
*/
|
||||||
|
private void recursionFn(List<SysDept> list, SysDept t)
|
||||||
|
{
|
||||||
|
// 得到子节点列表
|
||||||
|
List<SysDept> childList = getChildList(list, t);
|
||||||
|
t.setChildren(childList);
|
||||||
|
for (SysDept tChild : childList)
|
||||||
|
{
|
||||||
|
if (hasChild(list, tChild))
|
||||||
|
{
|
||||||
|
recursionFn(list, tChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 得到子节点列表
|
||||||
|
*/
|
||||||
|
private List<SysDept> getChildList(List<SysDept> list, SysDept t)
|
||||||
|
{
|
||||||
|
List<SysDept> tlist = new ArrayList<SysDept>();
|
||||||
|
Iterator<SysDept> it = list.iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
SysDept n = (SysDept) it.next();
|
||||||
|
if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue())
|
||||||
|
{
|
||||||
|
tlist.add(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否有子节点
|
||||||
|
*/
|
||||||
|
private boolean hasChild(List<SysDept> list, SysDept t)
|
||||||
|
{
|
||||||
|
return getChildList(list, t).size() > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,9 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||||
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
|
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (userId==1){
|
||||||
|
permsSet.add("*:*:*");
|
||||||
|
}
|
||||||
return permsSet;
|
return permsSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectMenuVo">
|
<sql id="selectMenuVo">
|
||||||
select menu_id, menu_name, parent_id, order_num, url, target, menu_type, visible, is_refresh, ifnull(perms,'') as perms, icon, create_by, create_time
|
select menu_id, menu_name, parent_id, order_num, url, target, menu_type, visible, is_refresh, ifnull(perms,'') as perms, icon, create_by, create_time ,path,component,query,status,vue_icon,is_frame
|
||||||
from sys_menu
|
from sys_menu
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectMenusByUserId" parameterType="Long" resultMap="SysMenuResult">
|
<select id="selectMenusByUserId" parameterType="Long" resultMap="SysMenuResult">
|
||||||
select distinct m.menu_id, m.parent_id, m.menu_name, m.url, m.visible, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
select distinct m.menu_id, m.parent_id, m.menu_name,m.path,m.component,m.query,m.status,m.vue_icon,m.is_frame, m.url, m.visible, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
||||||
from sys_menu m
|
from sys_menu m
|
||||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||||
left join sys_user_role ur on rm.role_id = ur.role_id
|
left join sys_user_role ur on rm.role_id = ur.role_id
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectMenuNormalAll" resultMap="SysMenuResult">
|
<select id="selectMenuNormalAll" resultMap="SysMenuResult">
|
||||||
select distinct m.menu_id, m.parent_id, m.menu_name, m.url, m.visible, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
select distinct m.menu_id, m.parent_id, m.menu_name, m.url, m.visible,m.path,m.component,m.query,m.status,m.vue_icon,m.is_frame, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
||||||
from sys_menu m
|
from sys_menu m
|
||||||
where m.menu_type in ('M', 'C') and m.visible = 0
|
where m.menu_type in ('M', 'C') and m.visible = 0
|
||||||
order by m.parent_id, m.order_num
|
order by m.parent_id, m.order_num
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectMenuAllByUserId" parameterType="Long" resultMap="SysMenuResult">
|
<select id="selectMenuAllByUserId" parameterType="Long" resultMap="SysMenuResult">
|
||||||
select distinct m.menu_id, m.parent_id, m.menu_name, m.url, m.visible, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
select distinct m.menu_id, m.parent_id, m.menu_name, m.url, m.visible,m.path,m.component,m.query,m.status,m.vue_icon,m.is_frame, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
||||||
from sys_menu m
|
from sys_menu m
|
||||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||||
left join sys_user_role ur on rm.role_id = ur.role_id
|
left join sys_user_role ur on rm.role_id = ur.role_id
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectMenuListByUserId" parameterType="SysMenu" resultMap="SysMenuResult">
|
<select id="selectMenuListByUserId" parameterType="SysMenu" resultMap="SysMenuResult">
|
||||||
select distinct m.menu_id, m.parent_id, m.menu_name, m.url, m.visible, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
select distinct m.menu_id, m.parent_id,m.path,m.component,m.query,m.status,m.vue_icon,m.is_frame, m.menu_name, m.url, m.visible, m.is_refresh, ifnull(m.perms,'') as perms, m.target, m.menu_type, m.icon, m.order_num, m.create_time
|
||||||
from sys_menu m
|
from sys_menu m
|
||||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||||
left join sys_user_role ur on rm.role_id = ur.role_id
|
left join sys_user_role ur on rm.role_id = ur.role_id
|
||||||
|
|
@ -119,7 +119,7 @@
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<select id="selectMenuById" parameterType="Long" resultMap="SysMenuResult">
|
<select id="selectMenuById" parameterType="Long" resultMap="SysMenuResult">
|
||||||
SELECT t.menu_id, t.parent_id, t.menu_name, t.order_num, t.url, t.target, t.menu_type, t.visible, t.is_refresh, t.perms, t.icon, t.remark,
|
SELECT t.menu_id, t.parent_id, t.menu_name, t.order_num, t.url, t.target, t.menu_type, t.visible, t.is_refresh, t.perms, t.icon, t.remark,t.path,t.component,t.query,t.status,t.vue_icon,t.is_frame,
|
||||||
(SELECT menu_name FROM sys_menu WHERE menu_id = t.parent_id) parent_name
|
(SELECT menu_name FROM sys_menu WHERE menu_id = t.parent_id) parent_name
|
||||||
FROM sys_menu t
|
FROM sys_menu t
|
||||||
where t.menu_id = #{menuId}
|
where t.menu_id = #{menuId}
|
||||||
|
|
@ -149,6 +149,12 @@
|
||||||
<if test="icon !=null and icon != ''">icon = #{icon},</if>
|
<if test="icon !=null and icon != ''">icon = #{icon},</if>
|
||||||
<if test="remark != null">remark = #{remark},</if>
|
<if test="remark != null">remark = #{remark},</if>
|
||||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||||
|
<if test="path != null and path != ''">path = #{path},</if>
|
||||||
|
<if test="component != null and component != ''">component = #{component},</if>
|
||||||
|
<if test="isFrame != null and isFrame != ''">is_frame = #{isFrame},</if>
|
||||||
|
<if test="query != null and query != ''">query = #{query},</if>
|
||||||
|
<if test="status != null and status != ''">status = #{status},</if>
|
||||||
|
<if test="vueIcon != null and vueIcon != ''">vue_icon = #{vueIcon},</if>
|
||||||
update_time = sysdate()
|
update_time = sysdate()
|
||||||
</set>
|
</set>
|
||||||
where menu_id = #{menuId}
|
where menu_id = #{menuId}
|
||||||
|
|
@ -169,6 +175,12 @@
|
||||||
<if test="icon != null and icon != ''">icon,</if>
|
<if test="icon != null and icon != ''">icon,</if>
|
||||||
<if test="remark != null and remark != ''">remark,</if>
|
<if test="remark != null and remark != ''">remark,</if>
|
||||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||||
|
<if test="path != null and path != ''">path ,</if>
|
||||||
|
<if test="component != null and component != ''">component ,</if>
|
||||||
|
<if test="isFrame != null and isFrame != ''">is_frame,</if>
|
||||||
|
<if test="query != null and query != ''">query ,</if>
|
||||||
|
<if test="status != null and status != ''">status ,</if>
|
||||||
|
<if test="vueIcon != null and vueIcon != ''">vue_icon,</if>
|
||||||
create_time
|
create_time
|
||||||
)values(
|
)values(
|
||||||
<if test="menuId != null and menuId != 0">#{menuId},</if>
|
<if test="menuId != null and menuId != 0">#{menuId},</if>
|
||||||
|
|
@ -184,6 +196,12 @@
|
||||||
<if test="icon != null and icon != ''">#{icon},</if>
|
<if test="icon != null and icon != ''">#{icon},</if>
|
||||||
<if test="remark != null and remark != ''">#{remark},</if>
|
<if test="remark != null and remark != ''">#{remark},</if>
|
||||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||||
|
<if test="path != null and path != ''"> #{path},</if>
|
||||||
|
<if test="component != null and component != ''">#{component},</if>
|
||||||
|
<if test="isFrame != null and isFrame != ''"> #{isFrame},</if>
|
||||||
|
<if test="query != null and query != ''">#{query},</if>
|
||||||
|
<if test="status != null and status != ''">#{status},</if>
|
||||||
|
<if test="vueIcon != null and vueIcon != ''"> #{vueIcon},</if>
|
||||||
sysdate()
|
sysdate()
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue