/* * Copyright 2019-2020 Zheng Jie * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package admin.rest; import admin.annotation.Log; import admin.annotation.rest.AnonymousPostMapping; import admin.config.RsaProperties; import admin.exception.BadRequestException; import admin.modules.system.domain.Job; import admin.modules.system.domain.Role; import admin.modules.system.domain.SysUsersRoles; import admin.modules.system.domain.User; import admin.modules.system.domain.vo.UserPassVo; import admin.modules.system.service.*; import admin.modules.system.service.dto.RoleSmallDto; import admin.modules.system.service.dto.UserDto; import admin.modules.system.service.dto.UserQueryCriteria; import admin.modules.system.service.mapper.UserMapper; import admin.rest.module.UserSyncRep; import admin.rest.module.UserSyncReq; import admin.utils.PageUtil; import admin.utils.RsaUtils; import admin.utils.SecurityUtils; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * @date 2018-11-23 */ @Api(tags = "系统:用户管理") @RestController @RequestMapping("/api/users") @RequiredArgsConstructor @Slf4j public class UserController { private final PasswordEncoder passwordEncoder; private final UserService userService; private final UserMapper userMapper; private final DataService dataService; private final DeptService deptService; private final RoleService roleService; // private final VerifyService verifyService; private final SysUsersRolesService sysUsersRolesService; @Log("导出用户数据") @ApiOperation("导出用户数据") @GetMapping(value = "/download") @PreAuthorize("@el.check('user:list')") public void download(HttpServletResponse response, UserQueryCriteria criteria) throws IOException { userService.download(userService.queryAll(criteria), response); } @Log("查询用户") @ApiOperation("查询用户") @GetMapping @PreAuthorize("@el.check('user:list')") public ResponseEntity<Object> query(UserQueryCriteria criteria, Pageable pageable){ if (!ObjectUtils.isEmpty(criteria.getDeptId())) { criteria.getDeptIds().add(criteria.getDeptId()); criteria.getDeptIds().addAll(deptService.getDeptChildren(criteria.getDeptId(), deptService.findByPid(criteria.getDeptId()))); } // 数据权限 List<Long> dataScopes = dataService.getDeptIds(userService.findByName(SecurityUtils.getCurrentUsername())); // criteria.getDeptIds() 不为空并且数据权限不为空则取交集 if (!CollectionUtils.isEmpty(criteria.getDeptIds()) && !CollectionUtils.isEmpty(dataScopes)){ // 取交集 criteria.getDeptIds().retainAll(dataScopes); if(!CollectionUtil.isEmpty(criteria.getDeptIds())){ return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); } } else { // 否则取并集 criteria.getDeptIds().addAll(dataScopes); criteria.setIsBusiness(0); return new ResponseEntity<>(userService.queryAll(criteria,pageable),HttpStatus.OK); } return new ResponseEntity<>(PageUtil.toPage(null,0),HttpStatus.OK); } @Log("新增用户") @ApiOperation("新增用户") @PostMapping @PreAuthorize("@el.check('user:add')") public ResponseEntity<Object> create(@Validated @RequestBody User resources){ checkLevel(resources); // 默认密码 123456 resources.setPassword(passwordEncoder.encode("123456")); checkRole(resources); userService.create(resources); Set<Role> roles = resources.getRoles(); if (roles!=null){ roles.forEach(i-> { SysUsersRoles usersRoles = new SysUsersRoles(); usersRoles.setRoleId(i.getId()); usersRoles.setUserId(resources.getId()); sysUsersRolesService.save(usersRoles); }); } return new ResponseEntity<>(HttpStatus.CREATED); } @Log("修改用户") @ApiOperation("修改用户") @PutMapping @PreAuthorize("@el.check('user:edit','finance:edit','operate:edit')") public ResponseEntity<Object> update(@Validated(User.Update.class) @RequestBody User resources){ if(hasPhone(resources.getPhone(),resources.getId())){ throw new BadRequestException("电话号码已经存在,请更换"); } checkLevel(resources); checkRole(resources); userService.update(resources); sysUsersRolesService.deleteByUserId(resources.getId()); Set<Role> roles = resources.getRoles(); if (roles!=null){ roles.forEach(i-> { SysUsersRoles usersRoles = new SysUsersRoles(); usersRoles.setRoleId(i.getId()); usersRoles.setUserId(resources.getId()); sysUsersRolesService.save(usersRoles); }); } return new ResponseEntity<>(HttpStatus.OK); } void checkRole(User resources) { int roleId = isChargeUser(resources); if (roleId == 3 || roleId == 4) { if (resources.getJobs() != null && resources.getJobs().size() > 0) { for (Job job : resources.getJobs()) { if (job != null) { resources.setJobId(job.getId()); //查询收费员岗位是否已经被其他收费员占用 if (roleId == 4) { // User user = userService.findByJobId(resources.getJobId()); //新增 // if (user != null && resources != null && resources.getId() == null){ // throw new BadRequestException(String.format("岗位已经被%s占用,请更换", user.getUsername())); // } // //修改 // if (user != null && resources.getId() != null && resources.getId() > 0 && !user.getId().equals(resources.getId())) { // throw new BadRequestException(String.format("岗位已经被%s占用,请更换", user.getUsername())); // } List<User> users = userService.findListByJobId(resources.getJobId()); if (users!=null&&users.size()>=2){ throw new BadRequestException(String.format("存在岗位被两个收费员%s占用,请更换", users.get(0).getUsername()+" "+users.get(1).getUsername())); } } } } //查询收费员岗位是否已经被其他收费员占用 // if (roleId == 4) { // User user = userService.findByJobId(resources.getJobId()); // //新增 // if (user != null && resources != null && resources.getId() == null){ // throw new BadRequestException(String.format("岗位已经被%s占用,请更换", user.getUsername())); // } // //修改 // if (user != null && resources.getId() != null && resources.getId() > 0 && !user.getId().equals(resources.getId())) { // throw new BadRequestException(String.format("岗位已经被%s占用,请更换", user.getUsername())); // } // } }else{ resources.setJobId(0L); } } } boolean hasPhone(String phone,Long uid){ User userDto=userMapper.findByPhone(phone); if(userDto==null) return false; else { if(userDto.getId().equals(uid)) return false; } return true; } /**是否收费员*/ Integer isChargeUser(User resources){ if(resources.getRoles()!=null&&resources.getRoles().size()>0){ for(Role role:resources.getRoles()){ if(role.getId()!=null&&role.getId()==4){ resources.setIsBusiness(1); return 4;//收费 }else if(role.getId()!=null&&role.getId()==3){ resources.setIsBusiness(2); return 3;//巡检 }else{ resources.setIsBusiness(0); return 0; } } } return 0; } @Log("修改用户:个人中心") @ApiOperation("修改用户:个人中心") @PutMapping(value = "center") public ResponseEntity<Object> center(@Validated(User.Update.class) @RequestBody User resources){ if(!resources.getId().equals(SecurityUtils.getCurrentUserId())){ throw new BadRequestException("不能修改他人资料"); } userService.updateCenter(resources); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @Log("删除用户") @ApiOperation("删除用户") @DeleteMapping @PreAuthorize("@el.check('user:del')") public ResponseEntity<Object> delete(@RequestBody Set<Long> ids){ for (Long id : ids) { Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); List<Integer> collect = roleService.findByUsersId(id).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()); if(collect.size()>0){ Integer optLevel = Collections.min(collect); if (currentLevel > optLevel) { throw new BadRequestException("角色权限不足,不能删除:" + userService.findById(id).getUsername()); } } } userService.delete(ids); return new ResponseEntity<>(HttpStatus.OK); } @ApiOperation("修改密码") @PostMapping(value = "/updatePass") public ResponseEntity<Object> updatePass(@RequestBody UserPassVo passVo) throws Exception { String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getOldPass()); String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,passVo.getNewPass()); UserDto user = userService.findByName(SecurityUtils.getCurrentUsername()); if(!passwordEncoder.matches(oldPass, user.getPassword())){ throw new BadRequestException("修改失败,旧密码错误"); } if(passwordEncoder.matches(newPass, user.getPassword())){ throw new BadRequestException("新密码不能与旧密码相同"); } userService.updatePass(user.getUsername(),passwordEncoder.encode(newPass)); return new ResponseEntity<>(HttpStatus.OK); } @ApiOperation("修改头像") @PostMapping(value = "/updateAvatar") public ResponseEntity<Object> updateAvatar(@RequestParam MultipartFile avatar){ return new ResponseEntity<>(userService.updateAvatar(avatar), HttpStatus.OK); } @Log("修改邮箱") @ApiOperation("修改邮箱") @PostMapping(value = "/updateEmail/{code}") public ResponseEntity<Object> updateEmail(@PathVariable String code,@RequestBody User user) throws Exception { String password = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,user.getPassword()); UserDto userDto = userService.findByName(SecurityUtils.getCurrentUsername()); if(!passwordEncoder.matches(password, userDto.getPassword())){ throw new BadRequestException("密码错误"); } // verifyService.validated(CodeEnum.EMAIL_RESET_EMAIL_CODE.getKey() + user.getEmail(), code); userService.updateEmail(userDto.getUsername(),user.getEmail()); return new ResponseEntity<>(HttpStatus.OK); } @Log("庆阳门户用户数据同步") @ApiOperation("庆阳门户用户数据同步") @AnonymousPostMapping(value = "/user/sync") public UserSyncRep sync(@RequestBody UserSyncReq req){ UserSyncRep userSyncRep = new UserSyncRep(); userSyncRep.setCode("0"); userSyncRep.setMsg("成功"); List<UserSyncRep.UserRep> userRepList=new ArrayList<>(); if(req.getUsers()!=null){ log.info("庆阳门户用户数据同步---users:{}", JSONObject.toJSONString(req.getUsers())); List<UserSyncReq.UserVO> users = req.getUsers(); for(UserSyncReq.UserVO userVO:users){ UserSyncRep.UserRep userRep = new UserSyncRep.UserRep(); switch (userVO.getOptType()){ case "CREATE": userRep=syncCreate(userVO); break; case "UPDATE": userRep=syncUpdate(userVO); break; default: break; } if(!ObjectUtils.isEmpty(userRep)){ userRepList.add(userRep); } } } userSyncRep.setData(userRepList); return userSyncRep; } /** * 数据同步创建 * @param userVO * @return */ private UserSyncRep.UserRep syncCreate(UserSyncReq.UserVO userVO){ UserSyncRep.UserRep userRep = new UserSyncRep.UserRep(); //校验是否有相同用户名的用户,有则不同步 User byUsername = userMapper.findByUsername(userVO.getUsername()); if(byUsername!=null) { log.info("门户数据同步已有用户:{}", userVO.getUsername()); userRep.setUserId(userVO.getUserId()); userRep.setReason("门户数据同步已有该用户"); return userRep; } try { log.info("门户数据同步创建用户:{}",userVO.getUsername()); User user = new User(); user.setIsAdmin(true); user.setUsername(userVO.getUsername()); user.setEmail(userVO.getEmail()==null?"": userVO.getEmail()); user.setPhone(userVO.getPhoneNumber()==null?"": userVO.getPhoneNumber()); user.setSyncPassword(userVO.getPassword()); BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String encode = bCryptPasswordEncoder.encode(userVO.getPassword()); user.setPassword(encode); user.setNickName(userVO.getRealName()==null?"": userVO.getRealName()); user.setEnabled(userVO.getIsActive()); userMapper.insert(user); }catch (Exception e){ userRep.setUserId(userVO.getUserId()); userRep.setReason("同步用户信息失败。optType为CREATE"); } return userRep; } /** * 数据同步修改 * @param userVO * @return */ private UserSyncRep.UserRep syncUpdate(UserSyncReq.UserVO userVO){ UserSyncRep.UserRep userRep = new UserSyncRep.UserRep(); return userRep; } /** * 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误 * @param resources / */ private void checkLevel(User resources) { Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); Integer optLevel = roleService.findByRoles(resources.getRoles()); if (currentLevel > optLevel) { throw new BadRequestException("角色权限不足"); } } }