diff --git a/pom.xml b/pom.xml index 9d6f39a1..ea644a2f 100644 --- a/pom.xml +++ b/pom.xml @@ -25,13 +25,13 @@ 2.3.3 1.4.7 2.0.53 - 6.6.5 - 2.13.0 + 6.8.1 + 2.19.0 4.1.2 2.3 0.9.1 - 9.0.102 + 9.0.105 1.2.13 5.7.12 5.3.39 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index e575d287..caebb397 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.system; +import java.util.Date; import java.util.List; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; @@ -13,10 +14,14 @@ import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginBody; import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.service.SysLoginService; import com.ruoyi.framework.web.service.SysPermissionService; import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysMenuService; /** @@ -39,6 +44,9 @@ public class SysLoginController @Autowired private TokenService tokenService; + @Autowired + private ISysConfigService configService; + /** * 登录方法 * @@ -79,6 +87,8 @@ public class SysLoginController ajax.put("user", user); ajax.put("roles", roles); ajax.put("permissions", permissions); + ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate())); + ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate())); return ajax; } @@ -94,4 +104,28 @@ public class SysLoginController List menus = menuService.selectMenuTreeByUserId(userId); return AjaxResult.success(menuService.buildMenus(menus)); } + + // 检查初始密码是否提醒修改 + public boolean initPasswordIsModify(Date pwdUpdateDate) + { + Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify")); + return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null; + } + + // 检查密码是否过期 + public boolean passwordIsExpiration(Date pwdUpdateDate) + { + Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays")); + if (passwordValidateDays != null && passwordValidateDays > 0) + { + if (StringUtils.isNull(pwdUpdateDate)) + { + // 如果从未修改过初始密码,直接提醒过期 + return true; + } + Date nowDate = DateUtils.getNowDate(); + return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays; + } + return false; + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java index 89e9bd33..bd1025d1 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java @@ -17,6 +17,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.file.FileUploadUtils; @@ -106,7 +107,8 @@ public class SysProfileController extends BaseController newPassword = SecurityUtils.encryptPassword(newPassword); if (userService.resetUserPwd(userName, newPassword) > 0) { - // 更新缓存用户密码 + // 更新缓存用户密码&密码最后更新时间 + loginUser.getUser().setPwdUpdateDate(DateUtils.getNowDate()); loginUser.getUser().setPassword(newPassword); tokenService.setLoginUser(loginUser); return success(); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java index e43f4cdb..37dbebcd 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java @@ -70,6 +70,9 @@ public class SysUser extends BaseEntity @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) private Date loginDate; + /** 密码最后更新时间 */ + private Date pwdUpdateDate; + /** 部门对象 */ @Excels({ @Excel(name = "部门名称", targetAttr = "deptName"), @@ -248,6 +251,16 @@ public class SysUser extends BaseEntity this.loginDate = loginDate; } + public Date getPwdUpdateDate() + { + return pwdUpdateDate; + } + + public void setPwdUpdateDate(Date pwdUpdateDate) + { + this.pwdUpdateDate = pwdUpdateDate; + } + public SysDept getDept() { return dept; @@ -314,6 +327,7 @@ public class SysUser extends BaseEntity .append("delFlag", getDelFlag()) .append("loginIp", getLoginIp()) .append("loginDate", getLoginDate()) + .append("pwdUpdateDate", getPwdUpdateDate()) .append("createBy", getCreateBy()) .append("createTime", getCreateTime()) .append("updateBy", getUpdateBy()) diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index b9a8081f..63717c54 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -5,24 +5,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -47,7 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.pwd_update_date, u.create_by, u.create_time, u.remark, d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status from sys_user u @@ -203,7 +204,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - update sys_user set password = #{password} where user_name = #{userName} + update sys_user set pwd_update_date = sysdate(), password = #{password} where user_name = #{userName} diff --git a/ruoyi-ui/.eslintignore b/ruoyi-ui/.eslintignore deleted file mode 100644 index 7dd2c2a8..00000000 --- a/ruoyi-ui/.eslintignore +++ /dev/null @@ -1,10 +0,0 @@ -# 忽略build目录下类型为js的文件的语法检查 -build/*.js -# 忽略src/assets目录下文件的语法检查 -src/assets -# 忽略public目录下文件的语法检查 -public -# 忽略当前目录下为js的文件的语法检查 -*.js -# 忽略当前目录下为vue的文件的语法检查 -*.vue \ No newline at end of file diff --git a/ruoyi-ui/.eslintrc.js b/ruoyi-ui/.eslintrc.js deleted file mode 100644 index b321fbe4..00000000 --- a/ruoyi-ui/.eslintrc.js +++ /dev/null @@ -1,199 +0,0 @@ -// ESlint 检查配置 -module.exports = { - root: true, - parserOptions: { - parser: 'babel-eslint', - sourceType: 'module' - }, - env: { - browser: true, - node: true, - es6: true, - }, - extends: ['plugin:vue/recommended', 'eslint:recommended'], - - // add your custom rules here - //it is base on https://github.com/vuejs/eslint-config-vue - rules: { - "vue/max-attributes-per-line": [2, { - "singleline": 10, - "multiline": { - "max": 1, - "allowFirstLine": false - } - }], - "vue/singleline-html-element-content-newline": "off", - "vue/multiline-html-element-content-newline":"off", - "vue/name-property-casing": ["error", "PascalCase"], - "vue/no-v-html": "off", - 'accessor-pairs': 2, - 'arrow-spacing': [2, { - 'before': true, - 'after': true - }], - 'block-spacing': [2, 'always'], - 'brace-style': [2, '1tbs', { - 'allowSingleLine': true - }], - 'camelcase': [0, { - 'properties': 'always' - }], - 'comma-dangle': [2, 'never'], - 'comma-spacing': [2, { - 'before': false, - 'after': true - }], - 'comma-style': [2, 'last'], - 'constructor-super': 2, - 'curly': [2, 'multi-line'], - 'dot-location': [2, 'property'], - 'eol-last': 2, - 'eqeqeq': ["error", "always", {"null": "ignore"}], - 'generator-star-spacing': [2, { - 'before': true, - 'after': true - }], - 'handle-callback-err': [2, '^(err|error)$'], - 'indent': [2, 2, { - 'SwitchCase': 1 - }], - 'jsx-quotes': [2, 'prefer-single'], - 'key-spacing': [2, { - 'beforeColon': false, - 'afterColon': true - }], - 'keyword-spacing': [2, { - 'before': true, - 'after': true - }], - 'new-cap': [2, { - 'newIsCap': true, - 'capIsNew': false - }], - 'new-parens': 2, - 'no-array-constructor': 2, - 'no-caller': 2, - 'no-console': 'off', - 'no-class-assign': 2, - 'no-cond-assign': 2, - 'no-const-assign': 2, - 'no-control-regex': 0, - 'no-delete-var': 2, - 'no-dupe-args': 2, - 'no-dupe-class-members': 2, - 'no-dupe-keys': 2, - 'no-duplicate-case': 2, - 'no-empty-character-class': 2, - 'no-empty-pattern': 2, - 'no-eval': 2, - 'no-ex-assign': 2, - 'no-extend-native': 2, - 'no-extra-bind': 2, - 'no-extra-boolean-cast': 2, - 'no-extra-parens': [2, 'functions'], - 'no-fallthrough': 2, - 'no-floating-decimal': 2, - 'no-func-assign': 2, - 'no-implied-eval': 2, - 'no-inner-declarations': [2, 'functions'], - 'no-invalid-regexp': 2, - 'no-irregular-whitespace': 2, - 'no-iterator': 2, - 'no-label-var': 2, - 'no-labels': [2, { - 'allowLoop': false, - 'allowSwitch': false - }], - 'no-lone-blocks': 2, - 'no-mixed-spaces-and-tabs': 2, - 'no-multi-spaces': 2, - 'no-multi-str': 2, - 'no-multiple-empty-lines': [2, { - 'max': 1 - }], - 'no-native-reassign': 2, - 'no-negated-in-lhs': 2, - 'no-new-object': 2, - 'no-new-require': 2, - 'no-new-symbol': 2, - 'no-new-wrappers': 2, - 'no-obj-calls': 2, - 'no-octal': 2, - 'no-octal-escape': 2, - 'no-path-concat': 2, - 'no-proto': 2, - 'no-redeclare': 2, - 'no-regex-spaces': 2, - 'no-return-assign': [2, 'except-parens'], - 'no-self-assign': 2, - 'no-self-compare': 2, - 'no-sequences': 2, - 'no-shadow-restricted-names': 2, - 'no-spaced-func': 2, - 'no-sparse-arrays': 2, - 'no-this-before-super': 2, - 'no-throw-literal': 2, - 'no-trailing-spaces': 2, - 'no-undef': 2, - 'no-undef-init': 2, - 'no-unexpected-multiline': 2, - 'no-unmodified-loop-condition': 2, - 'no-unneeded-ternary': [2, { - 'defaultAssignment': false - }], - 'no-unreachable': 2, - 'no-unsafe-finally': 2, - 'no-unused-vars': [2, { - 'vars': 'all', - 'args': 'none' - }], - 'no-useless-call': 2, - 'no-useless-computed-key': 2, - 'no-useless-constructor': 2, - 'no-useless-escape': 0, - 'no-whitespace-before-property': 2, - 'no-with': 2, - 'one-var': [2, { - 'initialized': 'never' - }], - 'operator-linebreak': [2, 'after', { - 'overrides': { - '?': 'before', - ':': 'before' - } - }], - 'padded-blocks': [2, 'never'], - 'quotes': [2, 'single', { - 'avoidEscape': true, - 'allowTemplateLiterals': true - }], - 'semi': [2, 'never'], - 'semi-spacing': [2, { - 'before': false, - 'after': true - }], - 'space-before-blocks': [2, 'always'], - 'space-before-function-paren': [2, 'never'], - 'space-in-parens': [2, 'never'], - 'space-infix-ops': 2, - 'space-unary-ops': [2, { - 'words': true, - 'nonwords': false - }], - 'spaced-comment': [2, 'always', { - 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] - }], - 'template-curly-spacing': [2, 'never'], - 'use-isnan': 2, - 'valid-typeof': 2, - 'wrap-iife': [2, 'any'], - 'yield-star-spacing': [2, 'both'], - 'yoda': [2, 'never'], - 'prefer-const': 2, - 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, - 'object-curly-spacing': [2, 'always', { - objectsInObjects: false - }], - 'array-bracket-spacing': [2, 'never'] - } -} diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 99f2bb8c..77996abf 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -8,19 +8,7 @@ "dev": "vue-cli-service serve", "build:prod": "vue-cli-service build", "build:stage": "vue-cli-service build --mode staging", - "preview": "node build/index.js --preview", - "lint": "eslint --ext .js,.vue src" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "src/**/*.{js,vue}": [ - "eslint --fix", - "git add" - ] + "preview": "node build/index.js --preview" }, "keywords": [ "vue", @@ -56,23 +44,17 @@ "vue": "2.6.12", "vue-count-to": "1.0.13", "vue-cropper": "0.5.5", - "vue-meta": "2.4.0", "vue-router": "3.4.9", "vuedraggable": "2.24.3", "vuex": "3.6.0" }, "devDependencies": { "@vue/cli-plugin-babel": "4.4.6", - "@vue/cli-plugin-eslint": "4.4.6", "@vue/cli-service": "4.4.6", - "babel-eslint": "10.1.0", "babel-plugin-dynamic-import-node": "2.3.3", "chalk": "4.1.0", "compression-webpack-plugin": "6.1.2", "connect": "3.6.6", - "eslint": "7.15.0", - "eslint-plugin-vue": "7.2.0", - "lint-staged": "10.5.3", "sass": "1.32.13", "sass-loader": "10.1.1", "script-ext-html-webpack-plugin": "2.1.5", diff --git a/ruoyi-ui/src/App.vue b/ruoyi-ui/src/App.vue index 86d4d48f..29e2c6c9 100644 --- a/ruoyi-ui/src/App.vue +++ b/ruoyi-ui/src/App.vue @@ -10,15 +10,7 @@ import ThemePicker from "@/components/ThemePicker" export default { name: "App", - components: { ThemePicker }, - metaInfo() { - return { - title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title, - titleTemplate: title => { - return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE - } - } - } + components: { ThemePicker } } diff --git a/ruoyi-ui/src/directive/index.js b/ruoyi-ui/src/directive/index.js index 34ca1d96..9a564bad 100644 --- a/ruoyi-ui/src/directive/index.js +++ b/ruoyi-ui/src/directive/index.js @@ -17,7 +17,7 @@ const install = function(Vue) { if (window.Vue) { window['hasRole'] = hasRole window['hasPermi'] = hasPermi - Vue.use(install) // eslint-disable-line + Vue.use(install) } export default install diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue index 14db4d34..258a9474 100644 --- a/ruoyi-ui/src/layout/components/Navbar.vue +++ b/ruoyi-ui/src/layout/components/Navbar.vue @@ -25,23 +25,24 @@ - +
- + {{ nickName }}
个人中心 - - 布局设置 - 退出登录
+ +
+ +
@@ -58,6 +59,7 @@ import RuoYiGit from '@/components/RuoYi/Git' import RuoYiDoc from '@/components/RuoYi/Doc' export default { + emits: ['setLayout'], components: { Breadcrumb, TopNav, @@ -72,17 +74,12 @@ export default { ...mapGetters([ 'sidebar', 'avatar', - 'device' + 'device', + 'nickName' ]), setting: { get() { return this.$store.state.settings.showSettings - }, - set(val) { - this.$store.dispatch('settings/changeSetting', { - key: 'showSettings', - value: val - }) } }, topNav: { @@ -95,6 +92,9 @@ export default { toggleSideBar() { this.$store.dispatch('app/toggleSideBar') }, + setLayout(event) { + this.$emit('setLayout') + }, logout() { this.$confirm('确定注销并退出系统吗?', '提示', { confirmButtonText: '确定', @@ -173,17 +173,25 @@ export default { } .avatar-container { - margin-right: 30px; + margin-right: 0px; + padding-right: 0px; .avatar-wrapper { - margin-top: 5px; + margin-top: 10px; position: relative; .user-avatar { cursor: pointer; - width: 40px; - height: 40px; - border-radius: 10px; + width: 30px; + height: 30px; + border-radius: 50%; + } + + .user-nickname{ + position: relative; + bottom: 10px; + font-size: 14px; + font-weight: bold; } .el-icon-caret-bottom { diff --git a/ruoyi-ui/src/layout/components/Settings/index.vue b/ruoyi-ui/src/layout/components/Settings/index.vue index 39043a06..ada983d3 100644 --- a/ruoyi-ui/src/layout/components/Settings/index.vue +++ b/ruoyi-ui/src/layout/components/Settings/index.vue @@ -1,5 +1,5 @@