疯狂的狮子li
2020-12-11 f56f57a2364ff5cf1279527c2f130aae88b65ce7
Merge branch 'master' of https://gitee.com/y_project/RuoYi-Vue

 Conflicts:
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
 ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
 ruoyi-ui/package.json
 ruoyi-ui/src/assets/styles/ruoyi.scss
 ruoyi-ui/src/assets/styles/sidebar.scss
 ruoyi-ui/src/assets/styles/variables.scss
 ruoyi-ui/src/components/HeaderSearch/index.vue
 ruoyi-ui/src/components/Screenfull/index.vue
 ruoyi-ui/src/layout/components/Settings/index.vue
 ruoyi-ui/src/layout/components/Sidebar/Logo.vue
 ruoyi-ui/src/layout/components/Sidebar/SidebarItem.vue
 ruoyi-ui/src/layout/components/Sidebar/index.vue
 ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue
 ruoyi-ui/src/layout/index.vue
 ruoyi-ui/src/main.js
 ruoyi-ui/src/settings.js
 ruoyi-ui/src/store/modules/settings.js
 ruoyi-ui/src/store/modules/user.js
 ruoyi-ui/src/views/login.vue
 ruoyi-ui/src/views/system/user/index.vue
 ruoyi-ui/src/views/system/user/profile/resetPwd.vue
 ruoyi-ui/src/views/system/user/profile/userInfo.vue
 ruoyi-ui/src/views/tool/gen/editTable.vue
 ruoyi-ui/src/views/tool/gen/index.vue
 ruoyi-ui/vue.config.js
已修改32个文件
已添加2个文件
已重命名2个文件
493 ■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/package.json 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/images/dark.svg 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/images/light.svg 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/images/login-background.jpg 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/images/profile.jpg 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/styles/ruoyi.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/styles/sidebar.scss 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/assets/styles/variables.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/components/HeaderSearch/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/components/Screenfull/index.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/layout/components/Settings/index.vue 133 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/layout/components/Sidebar/Logo.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/layout/components/Sidebar/SidebarItem.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/layout/components/Sidebar/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/layout/index.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/main.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/settings.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/store/modules/settings.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/store/modules/user.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/login.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/cache/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/user/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/user/profile/resetPwd.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/user/profile/userInfo.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/tool/gen/editTable.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/tool/gen/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/vue.config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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.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 @@
    @GetMapping(value = "/type/{dictType}")
    public AjaxResult dictType(@PathVariable String dictType)
    {
        return AjaxResult.success(dictTypeService.selectDictDataByType(dictType));
        List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
        if (StringUtils.isNull(data))
        {
            data = new ArrayList<SysDictData>();
        }
        return AjaxResult.success(data);
    }
    /**
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -127,11 +127,13 @@
        {
            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 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() + "'失败,邮箱账号已存在");
        }
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -877,7 +877,7 @@
     */
    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);
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 @@
     * @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;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
@@ -27,6 +27,14 @@
    public int deleteRoleMenuByRoleId(Long roleId);
    /**
     * æ‰¹é‡åˆ é™¤è§’色菜单关联信息
     *
     * @param ids éœ€è¦åˆ é™¤çš„æ•°æ®ID
     * @return ç»“æžœ
     */
    public int deleteRoleMenu(Long[] ids);
    /**
     * æ‰¹é‡æ–°å¢žè§’色菜单信息
     * 
     * @param roleMenuList è§’色菜单列表
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
@@ -290,8 +290,13 @@
     * @return ç»“æžœ
     */
    @Override
    @Transactional
    public int deleteRoleById(Long roleId)
    {
        // åˆ é™¤è§’色与菜单关联
        roleMenuMapper.deleteRoleMenuByRoleId(roleId);
        // åˆ é™¤è§’色与部门关联
        roleDeptMapper.deleteRoleDeptByRoleId(roleId);
        return roleMapper.deleteRoleById(roleId);
    }
@@ -302,6 +307,7 @@
     * @return ç»“æžœ
     */
    @Override
    @Transactional
    public int deleteRoleByIds(Long[] roleIds)
    {
        for (Long roleId : roleIds)
@@ -313,6 +319,10 @@
                throw new CustomException(String.format("%1$s已分配,不能删除", role.getRoleName()));
            }
        }
        // åˆ é™¤è§’色与菜单关联
        roleMenuMapper.deleteRoleMenu(roleIds);
        // åˆ é™¤è§’色与部门关联
        roleDeptMapper.deleteRoleDept(roleIds);
        return roleMapper.deleteRoleByIds(roleIds);
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -363,6 +363,7 @@
     * @return ç»“æžœ
     */
    @Override
    @Transactional
    public int deleteUserById(Long userId)
    {
        // åˆ é™¤ç”¨æˆ·ä¸Žè§’色关联
@@ -379,12 +380,17 @@
     * @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);
    }
ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
@@ -17,6 +17,13 @@
        delete from sys_role_menu where role_id=#{roleId}
    </delete>
    
    <delete id="deleteRoleMenu" parameterType="Long">
         delete from sys_role_menu where role_id in
         <foreach collection="array" item="roleId" open="(" separator="," close=")">
             #{roleId}
        </foreach>
     </delete>
    <insert id="batchRoleMenu">
        insert into sys_role_menu(role_id, menu_id) values
        <foreach item="item" index="index" collection="list" separator=",">
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",
ruoyi-ui/src/assets/images/dark.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1">
            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
            <feMerge>
                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
                <feMergeNode in="SourceGraphic"></feMergeNode>
            </feMerge>
        </filter>
        <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
        <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
        </filter>
    </defs>
    <g id="配置面板" width="48" height="40" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="setting-copy-2" width="48" height="40" transform="translate(-1190.000000, -136.000000)">
            <g id="Group-8" width="48" height="40" transform="translate(1167.000000, 0.000000)">
                <g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)">
                    <mask id="mask-3" fill="white">
                        <use xlink:href="#path-2"></use>
                    </mask>
                    <g id="Rectangle-18">
                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
                    </g>
                    <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect>
                    <rect id="Rectangle-18" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect>
                </g>
            </g>
        </g>
    </g>
</svg>
ruoyi-ui/src/assets/images/light.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1">
            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
            <feMerge>
                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
                <feMergeNode in="SourceGraphic"></feMergeNode>
            </feMerge>
        </filter>
        <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
        <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
        </filter>
    </defs>
    <g id="配置面板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="setting-copy-2" transform="translate(-1254.000000, -136.000000)">
            <g id="Group-8" transform="translate(1167.000000, 0.000000)">
                <g id="Group-5" filter="url(#filter-1)" transform="translate(89.000000, 137.000000)">
                    <mask id="mask-3" fill="white">
                        <use xlink:href="#path-2"></use>
                    </mask>
                    <g id="Rectangle-18">
                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
                    </g>
                    <rect id="Rectangle-18" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect>
                    <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect>
                </g>
            </g>
        </g>
    </g>
</svg>
ruoyi-ui/src/assets/images/login-background.jpg

ruoyi-ui/src/assets/images/profile.jpg

ruoyi-ui/src/assets/styles/ruoyi.scss
@@ -237,4 +237,4 @@
.top-right-btn {
    position: relative;
    float: right;
}
}
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;
    }
  }
ruoyi-ui/src/assets/styles/variables.scss
@@ -15,6 +15,11 @@
$menuBg:#304156;
$menuHover:#263445;
$sidebarTitle: #ffffff;
$menuLightBg:#ffffff;
$menuLightHover:#f0f1f5;
$sidebarLightTitle: #001529;
$subMenuBg:#1f2d3d;
$subMenuHover:#001528;
@@ -29,7 +34,11 @@
  subMenuActiveText: $subMenuActiveText;
  menuBg: $menuBg;
  menuHover: $menuHover;
  menuLightBg: $menuLightBg;
  menuLightHover: $menuLightHover;
  subMenuBg: $subMenuBg;
  subMenuHover: $subMenuHover;
  sideBarWidth: $sideBarWidth;
  sidebarTitle: $sidebarTitle;
  sidebarLightTitle: $sidebarLightTitle
}
ruoyi-ui/src/components/HeaderSearch/index.vue
@@ -12,7 +12,7 @@
      class="header-search-select"
      @change="change"
    >
      <el-option v-for="item in options" :key="item.path" :value="item" :label="item.title.join(' > ')" />
      <el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
    </el-select>
  </div>
</template>
@@ -167,7 +167,7 @@
    display: inline-block;
    vertical-align: middle;
    /deep/ .el-input__inner {
    ::v-deep .el-input__inner {
      border-radius: 0;
      border: 0;
      padding-left: 0;
ruoyi-ui/src/components/Screenfull/index.vue
@@ -22,11 +22,8 @@
  },
  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 @@
      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)
      }
    }
ruoyi-ui/src/layout/components/Settings/index.vue
@@ -1,12 +1,46 @@
<template>
  <div class="drawer-container">
    <div>
      <h3 class="drawer-title">系统布局配置</h3>
      <div class="setting-drawer-content">
        <div class="setting-drawer-title">
          <h3 class="drawer-title">主题风格设置</h3>
        </div>
        <div class="setting-drawer-block-checbox">
          <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
            <img src="@/assets/images/dark.svg" alt="dark">
            <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
              <i aria-label="图标: check" class="anticon anticon-check">
                <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
                     focusable="false" class="">
                  <path
                    d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
                </svg>
              </i>
            </div>
          </div>
          <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
            <img src="@/assets/images/light.svg" alt="light">
            <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
              <i aria-label="图标: check" class="anticon anticon-check">
                <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true"
                     focusable="false" class="">
                  <path
                    d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
                </svg>
              </i>
            </div>
          </div>
        </div>
      <div class="drawer-item">
        <span>主题颜色</span>
        <theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
        <div class="drawer-item">
          <span>主题颜色</span>
          <theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" />
        </div>
      </div>
      <el-divider/>
      <h3 class="drawer-title">系统布局配置</h3>
      <div class="drawer-item">
        <span>开启 Tags-Views</span>
@@ -36,6 +70,12 @@
    return {}
  },
  computed: {
    theme() {
      return this.$store.state.settings.theme
    },
    sideTheme() {
      return this.$store.state.settings.sideTheme
    },
    fixedHeader: {
      get() {
        return this.$store.state.settings.fixedHeader
@@ -76,33 +116,82 @@
        key: 'theme',
        value: val
      })
    },
    handleTheme(val) {
      this.$store.dispatch('settings/changeSetting', {
        key: 'sideTheme',
        value: val
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.drawer-container {
  padding: 24px;
  font-size: 14px;
  line-height: 1.5;
  word-wrap: break-word;
  .setting-drawer-content {
    .setting-drawer-title {
      margin-bottom: 12px;
      color: rgba(0, 0, 0, .85);
      font-size: 14px;
      line-height: 22px;
      font-weight: bold;
    }
  .drawer-title {
    margin-bottom: 12px;
    color: rgba(0, 0, 0, .85);
    .setting-drawer-block-checbox {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      margin-top: 10px;
      margin-bottom: 20px;
      .setting-drawer-block-checbox-item {
        position: relative;
        margin-right: 16px;
        border-radius: 2px;
        cursor: pointer;
        img {
          width: 48px;
          height: 48px;
        }
        .setting-drawer-block-checbox-selectIcon {
          position: absolute;
          top: 0;
          right: 0;
          width: 100%;
          height: 100%;
          padding-top: 15px;
          padding-left: 24px;
          color: #1890ff;
          font-weight: 700;
          font-size: 14px;
        }
      }
    }
  }
  .drawer-container {
    padding: 24px;
    font-size: 14px;
    line-height: 22px;
  }
    line-height: 1.5;
    word-wrap: break-word;
  .drawer-item {
    color: rgba(0, 0, 0, .65);
    font-size: 14px;
    padding: 12px 0;
  }
    .drawer-title {
      margin-bottom: 12px;
      color: rgba(0, 0, 0, .85);
      font-size: 14px;
      line-height: 22px;
    }
  .drawer-switch {
    float: right
    .drawer-item {
      color: rgba(0, 0, 0, .65);
      font-size: 14px;
      padding: 12px 0;
    }
    .drawer-switch {
      float: right
    }
  }
}
</style>
ruoyi-ui/src/layout/components/Sidebar/Logo.vue
@@ -1,13 +1,13 @@
<template>
  <div class="sidebar-logo-container" :class="{'collapse':collapse}">
  <div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
    <transition name="sidebarLogoFade">
      <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
        <img v-if="logo" :src="logo" class="sidebar-logo">
        <h1 v-else class="sidebar-title">{{ title }} </h1>
        <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
      </router-link>
      <router-link v-else key="expand" class="sidebar-logo-link" to="/">
        <img v-if="logo" :src="logo" class="sidebar-logo">
        <h1 class="sidebar-title">{{ title }} </h1>
        <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
      </router-link>
    </transition>
  </div>
@@ -15,6 +15,7 @@
<script>
import logoImg from '@/assets/logo/logo.png'
import variables from '@/assets/styles/variables.scss'
export default {
  name: 'SidebarLogo',
@@ -24,6 +25,14 @@
      required: true
    }
  },
  computed: {
    variables() {
      return variables;
    },
    sideTheme() {
      return this.$store.state.settings.sideTheme
    }
  },
  data() {
    return {
      title: '若依管理系统',
ruoyi-ui/src/layout/components/Sidebar/SidebarItem.vue
@@ -56,6 +56,9 @@
  },
  methods: {
    hasOneShowingChild(children = [], parent) {
      if (!children) {
        children = [];
      }
      const showingChildren = children.filter(item => {
        if (item.hidden) {
          return false
ruoyi-ui/src/layout/components/Sidebar/index.vue
@@ -1,12 +1,12 @@
<template>
    <div :class="{'has-logo':showLogo}">
    <div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
        <logo v-if="showLogo" :collapse="isCollapse" />
        <el-scrollbar wrap-class="scrollbar-wrapper">
        <el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
            <el-menu
                :default-active="activeMenu"
                :collapse="isCollapse"
                :background-color="variables.menuBg"
                :text-color="variables.menuText"
                :background-color="settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg"
                :text-color="settings.sideTheme === 'theme-dark' ? variables.menuText : 'rgba(0,0,0,.65)'"
                :unique-opened="true"
                :active-text-color="settings.theme"
                :collapse-transition="false"
ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue
@@ -82,7 +82,7 @@
  position: relative;
  overflow: hidden;
  width: 100%;
  /deep/ {
  ::v-deep {
    .el-scrollbar__bar {
      bottom: 0px;
    }
ruoyi-ui/src/layout/index.vue
@@ -1,7 +1,7 @@
<template>
  <div :class="classObj" class="app-wrapper">
    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
    <sidebar class="sidebar-container" />
  <div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
    <sidebar class="sidebar-container" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }" />
    <div :class="{hasTagsView:needTagsView}" class="main-container">
      <div :class="{'fixed-header':fixedHeader}">
        <navbar />
@@ -20,6 +20,7 @@
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
import variables from '@/assets/styles/variables.scss'
export default {
  name: 'Layout',
@@ -34,6 +35,8 @@
  mixins: [ResizeMixin],
  computed: {
    ...mapState({
      theme: state => state.settings.theme,
      sideTheme: state => state.settings.sideTheme,
      sidebar: state => state.app.sidebar,
      device: state => state.app.device,
      showSettings: state => state.settings.showSettings,
@@ -47,6 +50,9 @@
        withoutAnimation: this.sidebar.withoutAnimation,
        mobile: this.device === 'mobile'
      }
    },
    variables() {
      return variables;
    }
  },
  methods: {
ruoyi-ui/src/main.js
@@ -2,8 +2,6 @@
import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui'
import './assets/styles/element-variables.scss'
ruoyi-ui/src/settings.js
@@ -2,6 +2,11 @@
  title: '若依管理系统',
  /**
   * ä¾§è¾¹æ ä¸»é¢˜ æ·±è‰²ä¸»é¢˜theme-dark,浅色主题theme-light
   */
  sideTheme: 'theme-dark',
  /**
   * æ˜¯å¦ç³»ç»Ÿå¸ƒå±€é…ç½®
   */
  showSettings: false,
ruoyi-ui/src/store/modules/settings.js
@@ -1,10 +1,11 @@
import variables from '@/assets/styles/element-variables.scss'
import defaultSettings from '@/settings'
const { showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
const { sideTheme, showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
const state = {
  theme: variables.theme,
  sideTheme: sideTheme,
  showSettings: showSettings,
  tagsView: tagsView,
  fixedHeader: fixedHeader,
ruoyi-ui/src/store/modules/user.js
@@ -51,7 +51,7 @@
      return new Promise((resolve, reject) => {
        getInfo(state.token).then(res => {
          const user = res.user
          const avatar = user.avatar == "" ? require("@/assets/image/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
          const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
          if (res.roles && res.roles.length > 0) { // éªŒè¯è¿”回的roles是否是一个非空数组
            commit('SET_ROLES', res.roles)
            commit('SET_PERMISSIONS', res.permissions)
@@ -66,7 +66,7 @@
        })
      })
    },
    // é€€å‡ºç³»ç»Ÿ
    LogOut({ commit, state }) {
      return new Promise((resolve, reject) => {
ruoyi-ui/src/views/login.vue
@@ -148,7 +148,7 @@
  justify-content: center;
  align-items: center;
  height: 100%;
  background-image: url("../assets/image/login-background.jpg");
  background-image: url("../assets/images/login-background.jpg");
  background-size: cover;
}
.title {
ruoyi-ui/src/views/monitor/cache/index.vue
@@ -123,6 +123,8 @@
            {
              name: "峰值",
              type: "gauge",
              min: 0,
              max: 1000,
              detail: {
                formatter: this.cache.info.used_memory_human,
              },
ruoyi-ui/src/views/system/user/index.vue
@@ -421,14 +421,10 @@
        nickName: [
          { required: true, message: "用户昵称不能为空", trigger: "blur" }
        ],
        deptId: [
          { required: true, message: "归属部门不能为空", trigger: "change" }
        ],
        password: [
          { required: true, message: "用户密码不能为空", trigger: "blur" }
        ],
        email: [
          { required: true, message: "邮箱地址不能为空", trigger: "blur" },
          {
            type: "email",
            message: "'请输入正确的邮箱地址",
@@ -436,7 +432,6 @@
          }
        ],
        phonenumber: [
          { required: true, message: "手机号码不能为空", trigger: "blur" },
          {
            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
            message: "请输入正确的手机号码",
ruoyi-ui/src/views/system/user/profile/resetPwd.vue
@@ -18,6 +18,7 @@
<script>
import { updateUserPwd } from "@/api/system/user";
import Global from "@/layout/components/global.js";
export default {
  data() {
@@ -64,6 +65,7 @@
      });
    },
    close() {
      Global.$emit("removeCache", "closeSelectedTag", this.$route);
      this.$store.dispatch("tagsView/delView", this.$route);
      this.$router.push({ path: "/index" });
    }
ruoyi-ui/src/views/system/user/profile/userInfo.vue
@@ -2,7 +2,7 @@
  <el-form ref="form" :model="user" :rules="rules" label-width="80px">
    <el-form-item label="用户昵称" prop="nickName">
      <el-input v-model="user.nickName" />
    </el-form-item>
    </el-form-item>
    <el-form-item label="手机号码" prop="phonenumber">
      <el-input v-model="user.phonenumber" maxlength="11" />
    </el-form-item>
@@ -24,6 +24,7 @@
<script>
import { updateUserProfile } from "@/api/system/user";
import Global from "@/layout/components/global.js";
export default {
  props: {
@@ -68,6 +69,7 @@
      });
    },
    close() {
      Global.$emit("removeCache", "closeSelectedTag", this.$route);
      this.$store.dispatch("tagsView/delView", this.$route);
      this.$router.push({ path: "/index" });
    }
ruoyi-ui/src/views/tool/gen/editTable.vue
@@ -127,6 +127,7 @@
import { getGenTable, updateGenTable } from "@/api/tool/gen";
import { optionselect as getDictOptionselect } from "@/api/system/dict/type";
import { listMenu as getMenuTreeselect } from "@/api/system/menu";
import Global from "@/layout/components/global.js";
import basicInfoForm from "./basicInfoForm";
import genInfoForm from "./genInfoForm";
import Sortable from 'sortablejs'
@@ -207,6 +208,7 @@
    },
    /** å…³é—­æŒ‰é’® */
    close() {
      Global.$emit("removeCache", "closeSelectedTag", this.$route);
      this.$store.dispatch("tagsView/delView", this.$route);
      this.$router.push({ path: "/tool/gen", query: { t: Date.now()}})
    }
ruoyi-ui/src/views/tool/gen/index.vue
@@ -159,7 +159,7 @@
    <!-- é¢„览界面 -->
    <el-dialog :title="preview.title" :visible.sync="preview.open" width="80%" top="5vh" append-to-body>
      <el-tabs v-model="preview.activeName">
        <el-tab-pane
        <el-tab-pane style="overflow-x: scroll;"
          v-for="(value, key) in preview.data"
          :label="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))"
          :name="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))"
@@ -317,4 +317,4 @@
    }
  }
};
</script>
</script>
ruoyi-ui/vue.config.js
@@ -109,8 +109,8 @@
            })
          config.optimization.runtimeChunk('single'),
          {
             from: path.resolve(__dirname, './public/robots.txt'),//防爬虫文件
             to:'./',//到根目录下
             from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
             to: './', //到根目录下
          }
        }
      )