Commit 25378ce4ce4adb3fb7250d2b3aea70b2fbda4fe6

Authored by 游瑞烽
1 parent 04833bf4

1.加入系统角色、用户的概念 如超级管理员、root(系统内置角色、用户用来维护最基础系统操作,不可被删除)和现有的层级权限结构契合

2.加入密码重置功能(超级管理员角色独有)
src/main/java/com/bsth/controller/sys/RoleController.java
... ... @@ -68,4 +68,14 @@ public class RoleController extends BaseController<Role, Integer>{
68 68 public Map<String, Object> roleInfo(@RequestParam Integer id){
69 69 return roleService.roleInfo(id);
70 70 }
  71 +
  72 + /**
  73 + * 检查操作合法性 操作的是否是下级角色
  74 + * @param operationRoleId 下级角色Id
  75 + * @return
  76 + */
  77 + @RequestMapping(value = "/checkOperationLegality")
  78 + public boolean checkOperationLegality(@RequestParam Integer operationRoleId){
  79 + return roleService.checkOperationLegality(operationRoleId);
  80 + }
71 81 }
... ...
src/main/java/com/bsth/controller/sys/UserController.java
... ... @@ -260,6 +260,15 @@ public class UserController extends BaseController&lt;SysUser, Integer&gt; {
260 260 public String changePWD(@RequestParam String oldPWD, @RequestParam String newPWD, @RequestParam String cnewPWD) {
261 261 SysUser sysUser = SecurityUtils.getCurrentUser();
262 262 String msg = "";
  263 +
  264 + //解密RSA
  265 + try{
  266 + oldPWD = (RSAUtils.decryptBase64(oldPWD));
  267 + newPWD = (RSAUtils.decryptBase64(newPWD));
  268 + cnewPWD = (RSAUtils.decryptBase64(cnewPWD));
  269 + }catch (RuntimeException e) {
  270 + return "网络延迟,解密失败,请重新添加!";
  271 + }
263 272 if (new BCryptPasswordEncoder(4).matches(oldPWD, sysUser.getPassword())) {
264 273 if (oldPWD.equals(newPWD)) {
265 274 msg = "新密码不能跟原始密码一样!";
... ... @@ -282,8 +291,16 @@ public class UserController extends BaseController&lt;SysUser, Integer&gt; {
282 291 return sysUserService.register(u);
283 292 }
284 293  
  294 + // 查询用户下所有下级角色
285 295 @RequestMapping(value = "/all_distinct")
286 296 public List<SysUser> findAll_distinct() {
287 297 return sysUserService.findAll_distinct();
288 298 }
  299 +
  300 + // 重置密码
  301 + @RequestMapping(value = "/resetPassword", method = RequestMethod.POST)
  302 + public Map<String, Object> resetPassword(@RequestParam Integer id) {
  303 + return sysUserService.resetPassword(id);
  304 + }
  305 +
289 306 }
... ...
src/main/java/com/bsth/service/sys/RoleService.java
1 1 package com.bsth.service.sys;
2 2  
3   -import java.util.List;
4   -import java.util.Map;
5   -
6 3 import com.bsth.entity.sys.Role;
7   -import com.bsth.entity.sys.SysUser;
8 4 import com.bsth.service.BaseService;
9 5  
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
10 9 public interface RoleService extends BaseService<Role, Integer>{
11 10  
12 11 Map<String, Object> findSubordinate();
... ... @@ -18,4 +17,6 @@ public interface RoleService extends BaseService&lt;Role, Integer&gt;{
18 17 Map<String, Object> roleInfo(Integer id);
19 18  
20 19 List<Role> findAllByIds(String ids);
  20 +
  21 + boolean checkOperationLegality(Integer operationRoleId);
21 22 }
... ...
src/main/java/com/bsth/service/sys/SysUserService.java
... ... @@ -2,6 +2,7 @@ package com.bsth.service.sys;
2 2  
3 3 import com.bsth.entity.sys.SysUser;
4 4 import com.bsth.service.BaseService;
  5 +import org.springframework.web.bind.annotation.RequestParam;
5 6  
6 7 import java.util.List;
7 8 import java.util.Map;
... ... @@ -17,4 +18,6 @@ public interface SysUserService extends BaseService&lt;SysUser, Integer&gt;{
17 18 Map<String,Object> register(SysUser u);
18 19  
19 20 List<SysUser> findAll_distinct();
  21 +
  22 + Map<String, Object> resetPassword(@RequestParam Integer id);
20 23 }
... ...
src/main/java/com/bsth/service/sys/impl/RoleServiceImpl.java
... ... @@ -96,8 +96,10 @@ public class RoleServiceImpl extends BaseServiceImpl&lt;Role, Integer&gt; implements
96 96 // ComparatorSysrole(rootlist);
97 97 map.put("list", rsRoleList);
98 98 map.put("status", ResponseCode.SUCCESS);
  99 + map.put("msg", "成功");
99 100 } catch (Exception e) {
100 101 map.put("status", ResponseCode.ERROR);
  102 + map.put("msg", e);
101 103 logger.error("error",e);
102 104 }
103 105 return map;
... ... @@ -282,4 +284,12 @@ public class RoleServiceImpl extends BaseServiceImpl&lt;Role, Integer&gt; implements
282 284 public List<Role> findAllByIds(String ids) {
283 285 return roleRepository.findAllById(ids);
284 286 }
  287 +
  288 + @Override
  289 + public boolean checkOperationLegality(Integer operationRoleId){
  290 + boolean isLegality = false;
  291 + Map<String, Object> roleMap = findSubordinate();
  292 + isLegality = (roleMap.get(operationRoleId) == null ? true:false );
  293 + return isLegality;
  294 + }
285 295 }
... ...
src/main/java/com/bsth/service/sys/impl/SysUserServiceImpl.java
1 1 package com.bsth.service.sys.impl;
2 2  
3   -import com.alibaba.fastjson.JSONArray;
4 3 import com.bsth.common.ResponseCode;
  4 +import com.bsth.controller.sys.util.RSAUtils;
5 5 import com.bsth.entity.sys.Role;
6 6 import com.bsth.entity.sys.SysUser;
7 7 import com.bsth.repository.sys.SysUserRepository;
... ... @@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
16 16 import org.springframework.beans.factory.annotation.Autowired;
17 17 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
18 18 import org.springframework.stereotype.Service;
  19 +import org.springframework.web.bind.annotation.RequestParam;
19 20  
20 21 import java.util.ArrayList;
21 22 import java.util.HashMap;
... ... @@ -65,20 +66,45 @@ public class SysUserServiceImpl extends BaseServiceImpl&lt;SysUser, Integer&gt; implem
65 66 @Override
66 67 public Map<String, Object> register(SysUser u) {
67 68 Map<String, Object> rs = new HashMap();
68   - try{
69   - //检查用户名是否存在
70   - if(findByUserName(u.getUserName()) != null){
  69 + boolean isLegality = false;
  70 + Iterator<Role> itRole = u.getRoles().iterator();
  71 + Role ro = new Role();
  72 + while(itRole.hasNext()){//判断是否有下一个
  73 + ro = itRole.next();
  74 + if(roleService.checkOperationLegality(ro.getId())){
  75 + isLegality = true;
  76 + } else {
71 77 rs.put("status", ResponseCode.ERROR);
72   - rs.put("msg", "用户名" + u.getUserName() + "已存在!");
  78 + rs.put("msg", "用户权限不够,请联系管理员!");
  79 + return rs;
73 80 }
74   - else{
75   - u.setPassword(new BCryptPasswordEncoder(4).encode(u.getPassword()));
76   - rs = super.save(u);
  81 + }
  82 + if(isLegality){
  83 + try{
  84 + //解密RSA
  85 + try{
  86 + u.setUserName(RSAUtils.decryptBase64(u.getUserName()));
  87 + u.setPassword(RSAUtils.decryptBase64(u.getPassword()));
  88 + }catch (RuntimeException e) {
  89 + rs.put("msg", "网络延迟,解密失败,请重新添加!");
  90 + }
  91 + //检查用户名是否存在
  92 + if(findByUserName(u.getUserName()) != null){
  93 + rs.put("status", ResponseCode.ERROR);
  94 + rs.put("msg", "用户名" + u.getUserName() + "已存在!");
  95 + }
  96 + else{
  97 + u.setPassword(new BCryptPasswordEncoder(4).encode(u.getPassword()));
  98 + rs = super.save(u);
  99 + }
  100 + }catch (Exception e){
  101 + logger.error("", e);
  102 + rs.put("status", ResponseCode.ERROR);
  103 + rs.put("msg", e.getMessage());
77 104 }
78   - }catch (Exception e){
79   - logger.error("", e);
  105 + }else {
80 106 rs.put("status", ResponseCode.ERROR);
81   - rs.put("msg", e.getMessage());
  107 + rs.put("msg", "用户权限不够,请联系管理员!");
82 108 }
83 109 return rs;
84 110 }
... ... @@ -122,8 +148,36 @@ public class SysUserServiceImpl extends BaseServiceImpl&lt;SysUser, Integer&gt; implem
122 148 } catch (Exception e){
123 149 logger.error("error", e);
124 150 }
125   -
126   -
127 151 return rsList;
128 152 }
  153 +
  154 + @Override
  155 + public Map<String, Object> resetPassword(@RequestParam Integer id){
  156 + Map<String, Object> rs = new HashMap();
  157 + try{
  158 + // 获取当前用户
  159 + SysUser user = SecurityUtils.getCurrentUser();
  160 + Iterator<Role> itRole = user.getRoles().iterator();
  161 + Role ro = new Role();
  162 + boolean Legality = false;
  163 + while(itRole.hasNext()){//判断是否有下一个
  164 + ro = itRole.next();
  165 + if(ro.getLevel() == 1)
  166 + Legality = true;
  167 + }
  168 + if(Legality){
  169 + sysUserRepository.changePWD(id,new BCryptPasswordEncoder(4).encode("123456"));
  170 + rs.put("status", ResponseCode.SUCCESS);
  171 + rs.put("msg", "密码重置成功!");
  172 + }else {
  173 + rs.put("status", ResponseCode.ERROR);
  174 + rs.put("msg", "您不是超级管理员无权限重置其他用户密码");
  175 + }
  176 + }catch (Exception e){
  177 + logger.error("", e);
  178 + rs.put("status", ResponseCode.ERROR);
  179 + rs.put("msg", e.getMessage());
  180 + }
  181 + return rs;
  182 + }
129 183 }
... ...
src/main/resources/static/index.html
... ... @@ -630,9 +630,11 @@
630 630 <script
631 631 src="http://webapi.amap.com/maps?v=1.3&key=16cb1c5043847e09ef9edafdd77befda"
632 632 data-exclude=1></script>
633   -<!-- echarts4 误删 -->
  633 +<!-- echarts4 -->
634 634 <script src="/metronic_v4.5.4/plugins/echarts4/echarts.min.js"></script>
635 635 <script src="/real_control_v2/assets/plugins/perfect-scrollbar/perfect-scrollbar.jquery.js" merge="plugins"></script>
  636 +<!-- RSA加密 -->
  637 +<script src="/assets/plugins/jsencrypt.min.js"></script>
636 638  
637 639 </body>
638 640 </html>
639 641 \ No newline at end of file
... ...
src/main/resources/static/pages/permission/user/add.html
... ... @@ -42,7 +42,7 @@
42 42 <label class="col-md-3 control-label">密码</label>
43 43 <div class="col-md-4">
44 44 <input type="password" class="form-control" id="password" name="password" >
45   - <span class="help-block"> 请输入6位以上密码</span>
  45 + <!--<span class="help-block"> 请输入6位以上密码</span>-->
46 46 </div>
47 47 </div>
48 48 <div class="form-group">
... ... @@ -62,7 +62,7 @@
62 62 <div class="form-group">
63 63 <label class="col-md-3 control-label">角色</label>
64 64 <div class="col-md-4">
65   - <select class="form-control" id="role" name="role" style="width: 160px;" multiple="multiple">
  65 + <select class="form-control" id="role" name="roles[]" style="width: 160px;" multiple="multiple">
66 66  
67 67 </select>
68 68 </div>
... ... @@ -100,18 +100,46 @@
100 100 });
101 101 });*/
102 102  
103   - // 查询下级角色
  103 + // 查询下级角色
104 104 $.get('/role/findSubordinate', function (rs) {
105 105 if(rs.status == "SUCCESS"){
  106 + if(rs.list.length < 1){
  107 + loadPage('/pages/permission/role/add.html');
  108 + layer.open({
  109 + // type: 2,
  110 + content: '用户需要有下级角色才能添加用户!',
  111 + title: '请添加下级角色',
  112 + shift: 5,
  113 + scrollbar: false
  114 + });
  115 + return;
  116 + }
  117 +
106 118 $.each(rs.list,function(i,obj){
107 119 $("#role").append("<option value='"+obj.id+"'>"+obj.roleName+"</option>");
108 120 });
  121 + }else {
  122 + loadPage('/pages/permission/role/list.html');
  123 + layer.open({
  124 + // type: 2,
  125 + content: rs.msg,
  126 + title: "用户的下级角色有问题",
  127 + shift: 5,
  128 + scrollbar: false
  129 + });
109 130 }
110 131 });
  132 +
111 133  
112 134 var form = $('#user_add_form');
113 135 var error = $('.alert-danger', form);
114   -
  136 +
  137 + $.validator.addMethod("passwordrule", function(value, element) {
  138 + //var userblank = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*?[#?!@$%^&*-]).{8,16}$/;
  139 + var userblank = /^(?=.*[a-zA-Z])(?=.*\d).{8,16}$/;
  140 + return this.optional(element) ||(userblank.test(value));
  141 + }, "需包含字母、数字的8-16位字符");
  142 +
115 143 //表单 validate
116 144 form.validate({
117 145 errorElement : 'span',
... ... @@ -128,13 +156,14 @@
128 156 },
129 157 'password' : {
130 158 required : true,
131   - minlength: 6,
132   - maxlength: 25
  159 + minlength: 8,
  160 + maxlength: 16,
  161 + passwordrule: true
133 162 },
134 163 'cfmPassword' : {
135   - equalTo: '#password'
  164 + equalTo: '#password',
136 165 },
137   - 'role' : {
  166 + 'roles' : {
138 167 required : true,
139 168 minlength: 1
140 169 }
... ... @@ -160,6 +189,21 @@
160 189 var params = form.serializeJSON();
161 190 error.hide();
162 191  
  192 + var keys;
  193 + $.ajax({
  194 + url: "/user/login/jCryptionKey?t="+Math.random(),
  195 + type: "Get",
  196 + async:false,
  197 + data: null,
  198 + success: function(data) {
  199 + keys = data.publickey;
  200 + }
  201 + });
  202 + //RSA加密
  203 + var encrypt = new JSEncrypt();
  204 + encrypt.setPublicKey(keys);
  205 + params.userName = encrypt.encrypt(params.userName);
  206 + params.password = encrypt.encrypt(params.password);
163 207 $.ajax({
164 208 url: '/user/register',
165 209 type: 'POST',
... ... @@ -178,27 +222,6 @@
178 222 }
179 223 }
180 224 });
181   - /*$get('/user/all', {userName_eq: params.userName}, function(list){
182   - if(!list || list.length == 0){
183   - console.log(params);
184   - $.ajax({
185   - url: '/user',
186   - type: 'POST',
187   - traditional: true,
188   - data: params,
189   - success: function(res){
190   - layer.msg('添加用户成功.');
191   - loadPage('list.html');
192   - }
193   - });
194   - /!* $post('/user', params, function(res){
195   - layer.msg('添加用户成功.');
196   - loadPage('list.html');
197   - }); *!/
198   - }
199   - else
200   - layer.alert('用户【' + params.userName + '】已存在', {icon: 2, title: '提交被拒绝'});
201   - });*/
202 225 }
203 226 });
204 227 });
... ...
src/main/resources/static/pages/permission/user/changePWD.html
... ... @@ -97,6 +97,22 @@ $(function(){
97 97 var params = form.serializeJSON();
98 98 error.hide();
99 99  
  100 + var keys;
  101 + $.ajax({
  102 + url: "/user/login/jCryptionKey?t="+Math.random(),
  103 + type: "Get",
  104 + async:false,
  105 + data: null,
  106 + success: function(data) {
  107 + keys = data.publickey;
  108 + }
  109 + });
  110 + //RSA加密
  111 + var encrypt = new JSEncrypt();
  112 + encrypt.setPublicKey(keys);
  113 + params.oldPWD = encrypt.encrypt(params.oldPWD);
  114 + params.newPWD = encrypt.encrypt(params.newPWD);
  115 + params.cnewPWD = encrypt.encrypt(params.cnewPWD);
100 116 $.ajax({
101 117 url: '/user/changePWD',
102 118 type: 'POST',
... ...
src/main/resources/static/pages/permission/user/list.html
... ... @@ -64,7 +64,7 @@
64 64 <td>
65 65 <button class="btn btn-sm green btn-outline filter-submit margin-bottom" >
66 66 <i class="fa fa-search"></i> 搜索</button>
67   -
  67 +
68 68 <button class="btn btn-sm red btn-outline filter-cancel">
69 69 <i class="fa fa-times"></i> 重置</button>
70 70 </td>
... ... @@ -117,6 +117,9 @@
117 117 <a class="btn btn-sm blue btn-outline" href="edit.html?no={{obj.id}}" data-pjax><i class="fa fa-edit"></i> 编辑</a>
118 118 <!--<button type="button" class="btn btn-sm line_allot_btn" data-id="{{obj.id}}">线调线路分配</button>-->
119 119 {{/if}}
  120 + {{if obj.isAdmin}}
  121 + <a class="btn btn-sm red btn-outline reset_password" data-id="{{obj.id}}" data-name="{{obj.userName}}" data-pjax><i class="fa fa-undo"></i> 重置密码</a>
  122 + {{/if}}
120 123 </td>
121 124 </tr>
122 125 {{/each}}
... ... @@ -130,15 +133,49 @@
130 133 <script>
131 134 $(function(){
132 135 var page = 0, initPagination;
133   - var user;
  136 + var user,isAdmin = false;
134 137 var icheckOptions = {
135 138 checkboxClass: 'icheckbox_flat-blue',
136 139 increaseArea: '20%'
137 140 };
138 141 $.get('/user/getCurrentUser', function(data) {
139 142 user = data;
  143 + var roles = user.roles;
  144 + $.each(roles,function () {
  145 + if(this.level == 1)
  146 + isAdmin = true;
  147 + })
  148 +
140 149 });
  150 +
141 151 setTimeout(function () {
  152 + $(document).on('click', 'a.reset_password', function () {
  153 + var id = $(this).data('id');
  154 + var name = $(this).data('name');
  155 + swal({
  156 + title: "重装密码",
  157 + text: "将登录名为"+name+"的用户,密码重置为默认密码!",
  158 + type: "warning",
  159 + showCancelButton: true,
  160 + confirmButtonColor: "#DD6B55",
  161 + confirmButtonText: "重置",
  162 + cancelButtonText: "取消",
  163 + closeOnConfirm: false },
  164 + function(){
  165 + $.post('/user/resetPassword',{'id':id},function(result){
  166 + if(result.status=='SUCCESS') {
  167 + // 弹出添加成功提示消息
  168 + swal("登录名为"+name+"的用户密码重置成功!", "success");
  169 + } else if(result.status=='ERROR') {
  170 + // 弹出添加失败提示消息
  171 + swal("重置失败!", result.msg+",请联系开发人员!", "ERROR");
  172 + }
  173 + // loadPage('list.html');
  174 + // 发布后刷新页面
  175 + jsDoQuery(getParams(), true);
  176 + });
  177 + });
  178 + });
142 179 jsDoQuery(null,true);
143 180  
144 181 //重置
... ... @@ -147,45 +184,63 @@ $(function(){
147 184 jsDoQuery(null, true);
148 185 });
149 186  
  187 + function getParams() {
  188 + var cells = $('tr.filter')[0].cells
  189 + ,params = {}
  190 + ,name;
  191 + $.each(cells, function(i, cell){
  192 + var items = $('input,select', cell);
  193 + for(var j = 0, item; item = items[j++];){
  194 + name = $(item).attr('name');
  195 + if(name){
  196 + params[name] = $(item).val();
  197 + }
  198 + }
  199 + });
  200 + return params;
  201 + }
  202 +
150 203 //提交
151 204 $('tr.filter .filter-submit').on('click', function(){
152   - var cells = $('tr.filter')[0].cells
153   - ,params = {}
154   - ,name;
155   - $.each(cells, function(i, cell){
156   - var items = $('input,select', cell);
157   - for(var j = 0, item; item = items[j++];){
158   - name = $(item).attr('name');
159   - if(name){
160   - params[name] = $(item).val();
161   - }
162   - }
163   - });
164   - page = 0;
165   - jsDoQuery(params, true);
  205 + jsDoQuery(getParams(), true);
166 206 });
167 207  
168 208 /*
169 209 * 获取数据 p: 要提交的参数, pagination: 是否重新分页
170 210 */
171 211 function jsDoQuery(p, pagination){
  212 + var roles = new Map();
  213 + // 查询下级角色
  214 + $.ajax({
  215 + url: "/role/findSubordinate",
  216 + type: "Get",
  217 + async:false,
  218 + data: null,
  219 + success: function (rs) {
  220 + if(rs.status == "SUCCESS"){
  221 + $.each(rs.list,function(i,obj){
  222 + roles[obj.id] = obj;
  223 + });
  224 + }
  225 + }
  226 + });
172 227 var params = {};
173 228 if(p)
174 229 params = p;
175 230 //更新时间排序
176 231 params['order'] = 'lastLoginDate';
177 232 params['page'] = page;
178   - params['roles[0].pic_ne'] = 1;
  233 + // params['id_eq'] = "1";
179 234 var i = layer.load(2);
180 235 $get('/user' ,params, function(data){
181 236 var list = data.content;
182   - var errorList=[];
183 237 $.each(list, function(i, obj) {
184   - if(obj.roles[0].level > user.roles[0].level){
  238 + if(roles[obj.roles[0].id] != null && roles[obj.roles[0].id] != undefined){
185 239 obj.isEdit = 0;
186 240 } else{
187 241 obj.isEdit = 1;
188 242 }
  243 + obj.isAdmin = isAdmin;
189 244 obj.lastLoginDate = moment(obj.lastLoginDate).format("YYYY-MM-DD HH:mm:ss");
190 245 });
191 246  
... ...