diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java index 0bf2bc337..91bd67db2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; @@ -19,6 +20,7 @@ import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.service.ISysDictDataService; import com.ruoyi.system.service.ISysDictTypeService; @@ -73,7 +75,12 @@ public class SysDictDataController extends BaseController @GetMapping(value = "/type/{dictType}") public AjaxResult dictType(@PathVariable String dictType) { - return AjaxResult.success(dictTypeService.selectDictDataByType(dictType)); + List data = dictTypeService.selectDictDataByType(dictType); + if (StringUtils.isNull(data)) + { + data = new ArrayList(); + } + return AjaxResult.success(data); } /** diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java index 95bcfbe77..02346f12d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -127,11 +127,13 @@ public class SysUserController extends BaseController { return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); } - else if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + else if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); } - else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } @@ -149,11 +151,13 @@ public class SysUserController extends BaseController public AjaxResult edit(@Validated @RequestBody SysUser user) { userService.checkUserAllowed(user); - if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) { return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); } - else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) { return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index bf77d93aa..62c0439ae 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -877,7 +877,7 @@ public class ExcelUtil */ private Object getValue(Object o, String name) throws Exception { - if (StringUtils.isNotEmpty(name)) + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) { Class clazz = o.getClass(); Field field = clazz.getDeclaredField(name); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java index 75dea0862..7e180ab7c 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -1,6 +1,8 @@ package com.ruoyi.framework.aspectj; import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Iterator; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -210,8 +212,31 @@ public class LogAspect * @param o 对象信息。 * @return 如果是需要过滤的对象,则返回true;否则返回false。 */ + @SuppressWarnings("rawtypes") public boolean isFilterObject(final Object o) { + Class clazz = o.getClass(); + if (clazz.isArray()) + { + return clazz.getComponentType().isAssignableFrom(MultipartFile.class); + } + else if (Collection.class.isAssignableFrom(clazz)) + { + Collection collection = (Collection) o; + for (Iterator iter = collection.iterator(); iter.hasNext();) + { + return iter.next() instanceof MultipartFile; + } + } + else if (Map.class.isAssignableFrom(clazz)) + { + Map map = (Map) o; + for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) + { + Map.Entry entry = (Map.Entry) iter.next(); + return entry.getValue() instanceof MultipartFile; + } + } return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse; } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java index 5a2b90109..fccdbf09f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java @@ -26,6 +26,14 @@ public interface SysRoleMenuMapper */ public int deleteRoleMenuByRoleId(Long roleId); + /** + * 批量删除角色菜单关联信息 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteRoleMenu(Long[] ids); + /** * 批量新增角色菜单信息 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java index ad91b7140..227147213 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java @@ -290,8 +290,13 @@ public class SysRoleServiceImpl implements ISysRoleService * @return 结果 */ @Override + @Transactional public int deleteRoleById(Long roleId) { + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenuByRoleId(roleId); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDeptByRoleId(roleId); return roleMapper.deleteRoleById(roleId); } @@ -302,6 +307,7 @@ public class SysRoleServiceImpl implements ISysRoleService * @return 结果 */ @Override + @Transactional public int deleteRoleByIds(Long[] roleIds) { for (Long roleId : roleIds) @@ -313,6 +319,10 @@ public class SysRoleServiceImpl implements ISysRoleService throw new CustomException(String.format("%1$s已分配,不能删除", role.getRoleName())); } } + // 删除角色与菜单关联 + roleMenuMapper.deleteRoleMenu(roleIds); + // 删除角色与部门关联 + roleDeptMapper.deleteRoleDept(roleIds); return roleMapper.deleteRoleByIds(roleIds); } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 8a4c12aa0..b48a7de00 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -363,6 +363,7 @@ public class SysUserServiceImpl implements ISysUserService * @return 结果 */ @Override + @Transactional public int deleteUserById(Long userId) { // 删除用户与角色关联 @@ -379,12 +380,17 @@ public class SysUserServiceImpl implements ISysUserService * @return 结果 */ @Override + @Transactional public int deleteUserByIds(Long[] userIds) { for (Long userId : userIds) { checkUserAllowed(new SysUser(userId)); } + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); return userMapper.deleteUserByIds(userIds); } diff --git a/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml index 532b5e567..d3248655c 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -17,6 +17,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" delete from sys_role_menu where role_id=#{roleId} + + delete from sys_role_menu where role_id in + + #{roleId} + + + insert into sys_role_menu(role_id, menu_id) values diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 4f46a637d..14b1df8b4 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -9,11 +9,7 @@ "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", - "test:unit": "jest --clearCache && vue-cli-service test:unit", - "test:ci": "npm run lint && npm run test:unit", - "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", - "new": "plop" + "lint": "eslint --ext .js,.vue src" }, "husky": { "hooks": { @@ -41,59 +37,44 @@ }, "dependencies": { "@riophae/vue-treeselect": "0.4.0", - "axios": "0.18.1", - "clipboard": "2.0.4", - "core-js": "3.6.5", - "echarts": "4.2.1", + "axios": "0.21.0", + "clipboard": "2.0.6", + "core-js": "3.8.1", + "echarts": "4.9.0", "element-ui": "2.14.1", - "file-saver": "2.0.1", - "js-beautify": "1.10.2", - "fuse.js": "3.4.4", - "js-cookie": "2.2.0", + "file-saver": "2.0.4", + "fuse.js": "6.4.3", + "js-beautify": "1.13.0", + "js-cookie": "2.2.1", "jsencrypt": "3.0.0-rc.1", - "normalize.css": "7.0.0", "nprogress": "0.2.0", - "path-to-regexp": "2.4.0", - "screenfull": "4.2.0", - "sortablejs": "1.8.4", - "vue": "2.6.10", - "vue-count-to": "1.0.13", + "path-to-regexp": "6.2.0", "quill": "1.3.7", - "vue-cropper": "0.4.9", - "vue-router": "3.0.2", - "vue-splitpane": "1.0.4", - "vuedraggable": "2.20.0", - "vuex": "3.1.0" + "screenfull": "5.0.2", + "sortablejs": "1.10.2", + "vue": "2.6.12", + "vue-count-to": "1.0.13", + "vue-cropper": "0.5.5", + "vue-router": "3.4.9", + "vuedraggable": "2.24.3", + "vuex": "3.6.0" }, "devDependencies": { - "@vue/cli-plugin-babel": "4.4.4", - "@vue/cli-plugin-eslint": "4.4.4", - "@vue/cli-plugin-unit-jest": "4.4.4", - "@vue/cli-service": "4.4.4", - "@vue/test-utils": "1.0.0-beta.29", - "autoprefixer": "9.5.1", + "@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-jest": "23.6.0", - "babel-plugin-dynamic-import-node": "2.3.3", - "chalk": "2.4.2", - "chokidar": "2.1.5", + "chalk": "4.1.0", "connect": "3.6.6", - "eslint": "6.7.2", - "eslint-plugin-vue": "6.2.2", - "html-webpack-plugin": "3.2.0", - "husky": "1.3.1", - "lint-staged": "8.1.5", - "mockjs": "1.0.1-beta3", - "plop": "2.3.0", - "runjs": "4.3.2", - "node-sass": "4.14.1", - "sass-loader": "8.0.2", - "script-ext-html-webpack-plugin": "2.1.3", - "script-loader": "0.7.2", - "serve-static": "1.13.2", - "svg-sprite-loader": "4.1.3", - "svgo": "1.2.0", - "vue-template-compiler": "2.6.10" + "eslint": "7.15.0", + "eslint-plugin-vue": "7.2.0", + "lint-staged": "10.5.3", + "sass": "1.30.0", + "runjs": "4.4.2", + "sass-loader": "10.1.0", + "script-ext-html-webpack-plugin": "2.1.5", + "svg-sprite-loader": "5.1.1", + "vue-template-compiler": "2.6.12" }, "engines": { "node": ">=8.9", diff --git a/ruoyi-ui/src/assets/images/dark.svg b/ruoyi-ui/src/assets/images/dark.svg new file mode 100644 index 000000000..36b58b5b8 --- /dev/null +++ b/ruoyi-ui/src/assets/images/dark.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-ui/src/assets/images/light.svg b/ruoyi-ui/src/assets/images/light.svg new file mode 100644 index 000000000..efd52c67d --- /dev/null +++ b/ruoyi-ui/src/assets/images/light.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-ui/src/assets/image/login-background.jpg b/ruoyi-ui/src/assets/images/login-background.jpg similarity index 100% rename from ruoyi-ui/src/assets/image/login-background.jpg rename to ruoyi-ui/src/assets/images/login-background.jpg diff --git a/ruoyi-ui/src/assets/image/profile.jpg b/ruoyi-ui/src/assets/images/profile.jpg similarity index 100% rename from ruoyi-ui/src/assets/image/profile.jpg rename to ruoyi-ui/src/assets/images/profile.jpg diff --git a/ruoyi-ui/src/assets/styles/ruoyi.scss b/ruoyi-ui/src/assets/styles/ruoyi.scss index d8c6d611d..b1a166150 100644 --- a/ruoyi-ui/src/assets/styles/ruoyi.scss +++ b/ruoyi-ui/src/assets/styles/ruoyi.scss @@ -237,4 +237,4 @@ .top-right-btn { position: relative; float: right; -} \ No newline at end of file +} diff --git a/ruoyi-ui/src/assets/styles/sidebar.scss b/ruoyi-ui/src/assets/styles/sidebar.scss index e7464c66b..0eb8e78dc 100644 --- a/ruoyi-ui/src/assets/styles/sidebar.scss +++ b/ruoyi-ui/src/assets/styles/sidebar.scss @@ -8,6 +8,7 @@ } .sidebar-container { + -webkit-transition: width .28s; transition: width 0.28s; width: $sideBarWidth !important; background-color: $menuBg; @@ -19,6 +20,8 @@ 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 { @@ -73,17 +76,25 @@ .submenu-title-noDropdown, .el-submenu__title { &:hover { - background-color: $menuHover !important; + background-color: rgba(0, 0, 0, 0.06) !important; } } - .is-active>.el-submenu__title { + & .theme-dark .is-active > .el-submenu__title { color: $subMenuActiveText !important; } & .nest-menu .el-submenu>.el-submenu__title, & .el-submenu .el-menu-item { min-width: $sideBarWidth !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: $subMenuBg !important; &:hover { @@ -190,7 +201,7 @@ .el-menu-item { &:hover { // you can use $subMenuHover - background-color: $menuHover !important; + background-color: rgba(0, 0, 0, 0.06) !important; } } diff --git a/ruoyi-ui/src/assets/styles/variables.scss b/ruoyi-ui/src/assets/styles/variables.scss index 5688f25b5..452a1ece0 100644 --- a/ruoyi-ui/src/assets/styles/variables.scss +++ b/ruoyi-ui/src/assets/styles/variables.scss @@ -15,6 +15,11 @@ $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 $menuBg:#304156; $menuHover:#263445; +$sidebarTitle: #ffffff; + +$menuLightBg:#ffffff; +$menuLightHover:#f0f1f5; +$sidebarLightTitle: #001529; $subMenuBg:#1f2d3d; $subMenuHover:#001528; @@ -29,7 +34,11 @@ $sideBarWidth: 200px; subMenuActiveText: $subMenuActiveText; menuBg: $menuBg; menuHover: $menuHover; + menuLightBg: $menuLightBg; + menuLightHover: $menuLightHover; subMenuBg: $subMenuBg; subMenuHover: $subMenuHover; sideBarWidth: $sideBarWidth; + sidebarTitle: $sidebarTitle; + sidebarLightTitle: $sidebarLightTitle } diff --git a/ruoyi-ui/src/components/HeaderSearch/index.vue b/ruoyi-ui/src/components/HeaderSearch/index.vue index 3b4790d01..67f6c309a 100644 --- a/ruoyi-ui/src/components/HeaderSearch/index.vue +++ b/ruoyi-ui/src/components/HeaderSearch/index.vue @@ -12,7 +12,7 @@ class="header-search-select" @change="change" > - + @@ -167,7 +167,7 @@ export default { display: inline-block; vertical-align: middle; - /deep/ .el-input__inner { + ::v-deep .el-input__inner { border-radius: 0; border: 0; padding-left: 0; diff --git a/ruoyi-ui/src/components/Screenfull/index.vue b/ruoyi-ui/src/components/Screenfull/index.vue index 260c90de5..d4e539c26 100644 --- a/ruoyi-ui/src/components/Screenfull/index.vue +++ b/ruoyi-ui/src/components/Screenfull/index.vue @@ -22,11 +22,8 @@ export default { }, methods: { click() { - if (!screenfull.enabled) { - this.$message({ - message: 'you browser can not work', - type: 'warning' - }) + if (!screenfull.isEnabled) { + this.$message({ message: '你的浏览器不支持全屏', type: 'warning' }) return false } screenfull.toggle() @@ -35,12 +32,12 @@ export default { this.isFullscreen = screenfull.isFullscreen }, init() { - if (screenfull.enabled) { + if (screenfull.isEnabled) { screenfull.on('change', this.change) } }, destroy() { - if (screenfull.enabled) { + if (screenfull.isEnabled) { screenfull.off('change', this.change) } } diff --git a/ruoyi-ui/src/layout/components/Settings/index.vue b/ruoyi-ui/src/layout/components/Settings/index.vue index 90d99df52..9d42790a6 100644 --- a/ruoyi-ui/src/layout/components/Settings/index.vue +++ b/ruoyi-ui/src/layout/components/Settings/index.vue @@ -1,13 +1,47 @@