package com.jilongda.manage.authority.controller; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ImportParams; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.xiaoymin.knife4j.core.util.StrUtil; import com.jilongda.common.model.TDept; import com.jilongda.common.redis.RedisAutoTemplate; import com.jilongda.common.utils.CodeGenerateUtils; import com.jilongda.manage.authority.dto.ResetPasswordDTO; import com.jilongda.manage.authority.dto.SecUserDTO; import com.jilongda.manage.authority.dto.SecUserRoleDTO; import com.jilongda.manage.authority.dto.SecUsersDTO; import com.jilongda.manage.authority.model.SecResources; import com.jilongda.manage.authority.model.SecRole; import com.jilongda.manage.authority.model.SecUser; import com.jilongda.manage.authority.model.SecUserRole; import com.jilongda.manage.authority.query.SecUserLowerQuery; import com.jilongda.manage.authority.service.SecResourcesService; import com.jilongda.manage.authority.service.SecRoleService; import com.jilongda.manage.authority.service.SecUserRoleService; import com.jilongda.manage.authority.service.SecUserService; import com.jilongda.manage.authority.vo.SecResourceVO; import com.jilongda.manage.authority.vo.SecUsersVO; import com.jilongda.manage.model.TOptometrist; import com.jilongda.manage.query.TOptometristQuery; import com.jilongda.manage.utils.LoginInfoUtil; import com.jilongda.manage.utils.UserUtil; import com.jilongda.common.basic.ApiResult; import com.jilongda.common.basic.Constant; import com.jilongda.common.basic.PageInfo; import com.jilongda.common.exception.ServiceException; import com.jilongda.common.log.OperationLog; import com.jilongda.common.utils.ImportExcelUtil; import com.jilongda.common.utils.WebUtils; import com.jilongda.manage.vo.UserAddListVO; import com.jilongda.manage.vo.UserLevelVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** *

* 前端控制器 *

* * @author xiaochen * @since 2022-06-08 */ @Api(tags = "用户管理") @RestController @Slf4j @RequestMapping("/sec-user") public class SecUserController { private final SecUserService secUserService; private final SecRoleService secRoleService; private final SecResourcesService secResourcesService; private final PasswordEncoder passwordEncoder; private final UserUtil userUtil; private final SecUserRoleService secUserRoleService; private final LoginInfoUtil loginInfoUtil; private final RedisAutoTemplate redisAutoTemplate; @Autowired public SecUserController(SecUserService secUserService, SecRoleService secRoleService, SecResourcesService secResourcesService, PasswordEncoder passwordEncoder, UserUtil userUtil, SecUserRoleService secUserRoleService, LoginInfoUtil loginInfoUtil, RedisAutoTemplate redisAutoTemplate) { this.secUserService = secUserService; this.secRoleService = secRoleService; this.secResourcesService = secResourcesService; this.passwordEncoder = passwordEncoder; this.userUtil = userUtil; this.secUserRoleService = secUserRoleService; this.loginInfoUtil = loginInfoUtil; this.redisAutoTemplate = redisAutoTemplate; } /*@ApiOperation(value = "获取用户的资源(菜单及功能)-有层级", notes = "获取用户的资源(菜单及功能)-有层级") @GetMapping("resources/{uid}") public ApiResult> userResources(@PathVariable String uid) { // List sysResourceVos = secUserService.selectUserResourcesTag(uid); List sysResourceVos = secUserService.getResourceTag(uid); return ApiResult.success(sysResourceVos); }*/ @ApiOperation(value = "获取用户的资源(菜单及功能)-有层级", notes = "获取用户的资源(菜单及功能)-有层级") @GetMapping("/resources") public ApiResult> userResources() { // List sysResourceVos = secUserService.selectUserResourcesTag(uid); SecUser secUser = userUtil.getSecUser(); Assert.isTrue(Objects.nonNull(secUser), "当前用户异常,请联系管理员"); List sysResourceVos = secUserService.getResourceTag(secUser.getId()); return ApiResult.success(sysResourceVos); } @ApiOperation(value = "获取用户字典", notes = "获取用户字典") @GetMapping("/dist") public ApiResult> dist() { List users = secUserService.list(Wrappers.lambdaQuery(SecUser.class).ne(SecUser::getAccount, Constant.ADMIN)); return ApiResult.success(users); } @ApiOperation(value = "获取用户的资源(菜单及功能)--- 无层级", notes = "获取用户的资源(菜单及功能)--无层级") @GetMapping("/resources/nolevel/{uid}") public ApiResult> nolevel(@PathVariable Long uid) { List sysResources = secResourcesService.getSecResourcesMapper().selectResourceByUid(uid); return ApiResult.success(sysResources); } @ApiOperation(value = "获取用户信息", notes = "获取用户信息") @GetMapping("/userinfo/{uid}") public ApiResult> userinfo(@PathVariable Long uid) { Map map = new HashMap<>(2); SecUser secUser = secUserService.getById(uid); // String prefixByUser = salesTierService.getPrefixByUser(secUser.getPersonnelStructureId()); // secUser.setChildrenPrefix(prefixByUser); secUser.setPassword(null); map.put("userinfo", secUser); // 角色信息 == 应关联查询,排除为删除状态的 List sysRoles = secRoleService.getSecRoleMapper().selectRolesByUid(uid); List roleIds = sysRoles.stream().map(SecRole::getId).distinct().collect(Collectors.toList()); map.put("roleIds", roleIds); return ApiResult.success(map); } @ApiOperation("查询-获取用户列表") @PostMapping("/getSysUserList") public ApiResult> getSysUserList(@RequestBody SecUsersDTO dto) { return ApiResult.success(secUserService.getSysUserList(dto)); } @ApiOperation("查询-获取用户列表-不分页") @PostMapping("/getSysUserListNotPage") public ApiResult> getSysUserListNotPage() { return ApiResult.success(secUserService.queryList()); } @OperationLog(operType = "新增或编辑", operDesc = "新增或编辑用户", operModul = "用户") @ApiOperation("新增-编辑-新增或编辑用户") @PostMapping("/addOrUpdateUser") public ApiResult addOrUpdateUser(@Validated @RequestBody SecUserDTO dto) { secUserService.addOrUpdateUser(dto); return ApiResult.success(); } @ApiOperation(value = "通过门店id查询验光师列表") @GetMapping(value = "/queryListByStoreId") public ApiResult> queryListByStoreId(@RequestParam Integer storeId) { List secUsers = secUserService.list(Wrappers.lambdaQuery(SecUser.class) .eq(SecUser::getStoreId,storeId)); return ApiResult.success(secUsers); } @OperationLog(operType = "重置", operDesc = "重置密码", operModul = "用户") @ApiOperation("重置(修改)密码 不传密码为重置(123456),传密码为修改") @PostMapping("/resetPassword") public ApiResult resetPassword(@Validated @RequestBody ResetPasswordDTO dto) { // 账号查询用户 SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class) .eq(SecUser::getAccount, dto.getAccount())); Assert.isTrue(Objects.nonNull(secUser), "该账号不存在"); if (StrUtil.isNotBlank(dto.getPassword())) { // 根据加密算法加密用户输入的密码,然后和数据库中保存的密码进行比较 if (!this.passwordEncoder.matches(dto.getOldPassword(), secUser.getPassword())) { throw new BadCredentialsException("输入原密码不正确"); } // 修改密码 secUser.setPassword(passwordEncoder.encode(dto.getPassword())); } else { // 重置密码 secUser.setPassword(passwordEncoder.encode(Constant.DEF_PASSWORD)); } secUserService.updateById(secUser); return ApiResult.success(); } @OperationLog(operType = "修改", operDesc = "密码修改", operModul = "用户") @ApiOperation("首页密码修改") @PostMapping("/pageResetPassword") public ApiResult pageResetPassword(@Validated @RequestBody ResetPasswordDTO dto) { // 账号查询用户 SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class) .eq(SecUser::getAccount, dto.getAccount())); Assert.isTrue(Objects.nonNull(secUser), "该账号不存在"); // 校验短信验证码 String str = redisAutoTemplate.getStr(secUser.getPhone()); if(!StringUtils.hasLength(str)){ return ApiResult.failed("验证码已过期!"); } if(!str.equals(dto.getCode())){ return ApiResult.failed("验证码有误!"); } if (StrUtil.isNotBlank(dto.getPassword())) { // 根据加密算法加密用户输入的密码,然后和数据库中保存的密码进行比较 if (!this.passwordEncoder.matches(dto.getOldPassword(), secUser.getPassword())) { throw new BadCredentialsException("输入原密码不正确"); } // 修改密码 secUser.setPassword(passwordEncoder.encode(dto.getPassword())); } else { // 重置密码 secUser.setPassword(passwordEncoder.encode(Constant.DEF_PASSWORD)); } secUserService.updateById(secUser); return ApiResult.success(); } @OperationLog(operType = "启用禁用", operDesc = "系统用户启用禁用", operModul = "用户") @ApiOperation("系统用户启用禁用 state(0,1) 非0 则为禁用") @PutMapping("/state/{id}/{state}") public ApiResult state(@PathVariable("id") Long id, @PathVariable("state") Boolean state) { SecUser secUser = secUserService.getById(id); if (secUser == null) { return ApiResult.failed(500, "该用户不存在"); } secUser.setState(state); secUserService.updateById(secUser); return ApiResult.success(); } @OperationLog(operType = "删除", operDesc = "删除用户", operModul = "用户") @ApiOperation(value = "删除-删除用户", notes = "删除用户") @DeleteMapping("del/{uid}") public ApiResult delUser(@PathVariable Long uid) { SecUser secUser = secUserService.getById(uid); if (Constant.ADMIN.equals(secUser.getAccount())) { return ApiResult.failed(500, "超级管理员不可删除"); } secUserService.removeById(uid); return ApiResult.success(); } @OperationLog(operType = "批量删除", operDesc = "批量删除用户", operModul = "用户") @ApiOperation(value = "批量删除-删除用户", notes = "批量删除用户") @DeleteMapping("batch-del") public ApiResult batchDelUser(@RequestBody List uids) { for (Long uid : uids) { delUser(uid); } return ApiResult.success(); } @Transactional(rollbackFor = Exception.class) @OperationLog(operType = "新增", operDesc = "人员绑定角色", operModul = "用户") @ApiOperation(value = "人员绑定角色", notes = "人员绑定角色") @PutMapping("userBindRole") public ApiResult userBindRole(@RequestBody SecUserRoleDTO dto) { List userIds = dto.getUserIds(); Assert.isTrue(CollectionUtils.isNotEmpty(userIds), "请选择用户"); // 删除该用户所有的角色 secUserRoleService.remove(Wrappers.lambdaQuery(SecUserRole.class) .eq(SecUserRole::getRoleId, dto.getRoleId())); long count = secUserRoleService.count(Wrappers.lambdaQuery(SecUserRole.class) .in(SecUserRole::getUserId, userIds)); if (count > 0) { throw new ServiceException(500, "选中用户中已有用户关联其他角色,请重新选择!"); } List secUserRoles = new ArrayList<>(userIds.size()); for (Long userId : userIds) { SecUserRole secUserRole = new SecUserRole(); secUserRole.setUserId(userId); secUserRole.setRoleId(dto.getRoleId()); secUserRoles.add(secUserRole); } secUserRoleService.saveBatch(secUserRoles); return ApiResult.success(); } @ApiOperation(value = "KAM查看用户下级", notes = "KAM查看用户下级") @PostMapping("queryLower") public ApiResult> queryLower(@RequestBody SecUserLowerQuery query) { PageInfo secUserPageInfo = secUserService.queryLower(query); return ApiResult.success(secUserPageInfo); } @ApiOperation(value = "用户导入模板") @GetMapping("/import-template") public void importProduct() { List secUserExcels = new ArrayList<>(); Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("用户导入模板", "用户导入模板"), SecUser.class, secUserExcels); HttpServletResponse response = WebUtils.response(); ServletOutputStream outputStream = null; try { String fileName = URLEncoder.encode("用户导入模板.xls", "utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); outputStream = response.getOutputStream(); workbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); log.error("用户导入模板下载失败!"); } finally { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } @ApiOperation(value = "用户导入") @PostMapping("/import-user") public ApiResult importUser(@RequestParam("file") MultipartFile file) { ImportParams params = new ImportParams(); params.setTitleRows(1);//标题行数 params.setHeadRows(1); //表头行数 try { InputStream inputStream = file.getInputStream(); List secUserList = ExcelImportUtil.importExcel(inputStream, SecUser.class, params); secUserList = secUserList.stream().filter(user -> StringUtils.hasLength(user.getAccount())).collect(Collectors.toList()); for (SecUser secUser : secUserList) { log.info("人员数据密码加密处理=========:{}", secUser); String s = secUser.getAccount().replaceAll("\n", ""); Pattern p = Pattern.compile("\\s*|\t|\r|\n"); Matcher m = p.matcher(s); s = m.replaceAll(""); secUser.setAccount(s); // 密码加密 secUser.setPassword(passwordEncoder.encode(secUser.getPassword())); } log.info("人员数据处理完毕=========:{}", secUserList); List errors = new ArrayList<>(); // 去除 listSysRoles 中重复的数据 for (int i = 0; i < secUserList.size(); i++) { String accountI = secUserList.get(i).getAccount(); for (int j = i + 1; j < secUserList.size(); j++) { String accountJ = secUserList.get(j).getAccount(); // 发现重复数据 if (accountI.equals(accountJ)) { errors.add("第 " + (j + 1) + " 行的 account 值:" + accountI + " 已存在,忽略导入"); secUserList.remove(j); break; } } } // 去掉 sql 中的重复数据 Integer errorLines = 0; Integer successLines = 0; // List lis1t = ImportExcelUtil.importDateSave(secUserList, SecUser.class, errors, Constant.PHONE_UNI); for (int i = 0; i < secUserList.size(); i++) { try { log.info("保存前=================================="); boolean save = secUserService.save(secUserList.get(i)); log.info("保存后=================================="); if (!save) { throw new Exception(Constant.PHONE_UNI); } } catch (Exception e) { String message = e.getMessage().toLowerCase(); int lineNumber = i + 1; // 通过索引名判断出错信息 if (message.contains(Constant.PRODUCT_NUMBER_UNI)) { errors.add("第 " + lineNumber + " 行:商品编号已经存在,忽略导入。"); } else if (message.contains(Constant.PHONE_UNI)) { errors.add("第 " + lineNumber + " 行:人员手机号已经存在,忽略导入。"); } else if (message.contains(Constant.SHOP_NUMBER_UNI)) { errors.add("第 " + lineNumber + " 行:门店编号已经存在,忽略导入。"); } else if (message.contains(Constant.SHOP_OWN_NUMBER_UNI)) { errors.add("第 " + lineNumber + " 行:门店系统生成编号已经存在,忽略导入。"); } else { errors.add("第 " + lineNumber + " 行:未知错误,忽略导入"); log.error(e.getMessage(), e); } } } errorLines += errors.size(); successLines += (secUserList.size() - errorLines); ApiResult stringApiResult = ImportExcelUtil.importReturnMsg(errorLines, successLines, errors); log.info(stringApiResult.getMsg()); return stringApiResult; } catch (Exception e) { log.error("用户导入失败!" + e.getMessage()); } return ApiResult.success(); } }