package com.dsh.guns.modular.system.controller.system; import cn.hutool.crypto.SecureUtil; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.dsh.course.mapper.UserMapper; import com.dsh.guns.config.UserExt; import com.dsh.guns.config.properties.GunsProperties; import com.dsh.guns.core.base.controller.BaseController; import com.dsh.guns.core.base.tips.Tip; import com.dsh.guns.core.common.annotion.BussinessLog; import com.dsh.guns.core.common.annotion.Permission; import com.dsh.guns.core.common.constant.Const; import com.dsh.guns.core.common.constant.dictmap.UserDict; import com.dsh.guns.core.common.constant.factory.ConstantFactory; import com.dsh.guns.core.common.constant.factory.PageFactory; import com.dsh.guns.core.common.constant.state.ManagerStatus; import com.dsh.guns.core.common.exception.BizExceptionEnum; import com.dsh.guns.core.db.Db; import com.dsh.guns.core.exception.GunsException; import com.dsh.guns.core.log.LogObjectHolder; import com.dsh.guns.core.util.SinataUtil; import com.dsh.guns.modular.system.controller.util.MD5; import com.dsh.guns.modular.system.factory.UserFactory; import com.dsh.guns.modular.system.model.*; import com.dsh.guns.modular.system.service.IDeptService; import com.dsh.guns.modular.system.service.IRoleService; import com.dsh.guns.modular.system.service.IStoreService; import com.dsh.guns.modular.system.service.IUserService; import com.dsh.guns.modular.system.transfer.UserDto; import com.dsh.guns.modular.system.util.OBSUploadUtil; import com.dsh.guns.modular.system.util.OssUploadUtil; import com.dsh.guns.modular.system.util.ResultUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.transaction.annotation.Transactional; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.bind.WebDataBinder; import org.springframework.beans.propertyeditors.CustomNumberEditor; import javax.naming.NoPermissionException; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.util.*; import java.util.stream.Collectors; /** * 系统管理员控制器 * * @author fengshuonan * @Date 2017年1月11日 下午1:08:17 */ @Controller @RequestMapping("/mgr") public class UserMgrController extends BaseController { private static String PREFIX = "/system/user/"; /** 多选框未选择时会提交空字符串;将其转换为空值,避免绑定 List 时抛 NumberFormatException。 */ @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true)); } @Autowired private GunsProperties gunsProperties; @Autowired private IUserService userService; @Autowired private IRoleService roleService; @Autowired private IDeptService deptService; /** * 跳转到查看管理员列表的页面 */ @RequestMapping("") public String index(Model model) { model.addAttribute("language",UserExt.getLanguage()); model.addAttribute("isSuperAdmin", "admin".equalsIgnoreCase(UserExt.getUser().getAccount())); return PREFIX + "user.html"; } /** * 跳转到查看管理员列表的页面 */ @RequestMapping("/user_add") public String addView(Model model) { model.addAttribute("role",UserExt.getUser().getObjectType()); model.addAttribute("language",UserExt.getLanguage()); LambdaQueryWrapper roleLambdaQueryWrapper = new LambdaQueryWrapper<>(); if(UserExt.getUser().getObjectType()!=1){ roleLambdaQueryWrapper.eq(Role::getObjId,UserExt.getUser().getObjectId()); } roleLambdaQueryWrapper.eq(Role::getObjType,UserExt.getUser().getObjectType()); List list = roleService.list(roleLambdaQueryWrapper); model.addAttribute("list",list); // 部门列表 List depts = deptService.list(new QueryWrapper<>()); model.addAttribute("depts",depts); model.addAttribute("stores", availableStores()); return PREFIX + "user_add.html"; } private List availableStores() { LambdaQueryWrapper query = new LambdaQueryWrapper().eq(TStore::getState, 1); Integer objectType = UserExt.getUser().getObjectType(); Integer objectId = UserExt.getUser().getObjectId(); if (Integer.valueOf(2).equals(objectType)) { query.eq(TStore::getOperatorId, objectId); } else if (Integer.valueOf(3).equals(objectType)) { query.eq(TStore::getId, objectId); } return storeService.list(query); } /** * 跳转到角色分配页面 */ //@RequiresPermissions("/mgr/role_assign") //利用shiro自带的权限检查 @Permission @RequestMapping("/role_assign/{userId}") public String roleAssign(@PathVariable Integer userId, Model model) { if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } User user = (User) Db.create(UserMapper.class).selectOneByCon("id", userId); model.addAttribute("userId", userId); model.addAttribute("userAccount", user.getAccount()); return PREFIX + "user_roleassign.html"; } /** * 跳转到编辑管理员页面 type=1编辑 type=2 查看详情 */ @Permission @RequestMapping("/user_edit/{userId}/{type}") public String userEdit(@PathVariable Integer userId,@PathVariable Integer type, Model model) { model.addAttribute("role",UserExt.getUser().getObjectType()); if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } assertAuth(userId); User user = this.userService.getById(userId); Role role = roleService.getById(user.getRoleid()); Dept dept = deptService.getById(user.getDeptid()); user.setPhone(maskPhone(user.getPhone())); user.setIdCard(maskIdCard(user.getIdCard())); model.addAttribute(user); if(role==null){ model.addAttribute("roleName", ""); }else { model.addAttribute("roleName", role.getName()); } if(dept==null){ model.addAttribute("deptName",""); }else { model.addAttribute("deptName", dept.getFullname()); } LogObjectHolder.me().set(user); LambdaQueryWrapper roleLambdaQueryWrapper = new LambdaQueryWrapper<>(); if(UserExt.getUser().getObjectType()!=1){ roleLambdaQueryWrapper.eq(Role::getObjId,UserExt.getUser().getObjectId()); } roleLambdaQueryWrapper.eq(Role::getObjType,UserExt.getUser().getObjectType()); List list = roleService.list(roleLambdaQueryWrapper); model.addAttribute("list",list); model.addAttribute("language",UserExt.getLanguage()); // 部门列表 List depts = deptService.list(new QueryWrapper<>()); model.addAttribute("depts",depts); model.addAttribute("stores", availableStores()); // 回显同时兼容新关联表、sys_user 旧归属字段和 t_store.storeStaffId 旧数据。 List selectedStoreIds = userMapper.getStoreIdsByUserId(userId); model.addAttribute("selectedStoreIds", selectedStoreIds.stream() .map(String::valueOf).collect(Collectors.joining(","))); model.addAttribute("type",type); return PREFIX + "user_edit.html"; } /** 编辑页异步读取已关联门店,避免模板渲染集合造成多选回显丢失。 */ @GetMapping("/storeIds/{userId}") @ResponseBody public List getStoreIds(@PathVariable Integer userId) { assertAuth(userId); return userMapper.getStoreIdsByUserId(userId); } /** * 跳转到查看用户详情页面 */ @RequestMapping("/user_info") public String userInfo(Model model) { Integer userId = UserExt.getUser().getId(); if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } User user = this.userService.getById(userId); Role role = roleService.getById(user.getRoleid()); Dept dept = deptService.getById(user.getDeptid()); user.setPhone(maskPhone(user.getPhone())); user.setIdCard(maskIdCard(user.getIdCard())); model.addAttribute(user); model.addAttribute("roleName", role.getName()); if(dept==null){ model.addAttribute("deptName", "无"); }else{ model.addAttribute("deptName", user.getDeptid()==0?"顶级":dept.getFullname()); } LogObjectHolder.me().set(user); return PREFIX + "user_view.html"; } /** * 跳转到修改密码界面 */ @RequestMapping("/user_chpwd") public String chPwd() { return PREFIX + "user_chpwd.html"; } /** * 修改当前用户的密码 */ @RequestMapping("/changePwd") @ResponseBody public Object changePwd(@RequestParam String oldPwd, @RequestParam String newPwd, @RequestParam String rePwd) { if (!newPwd.equals(rePwd)) { throw new GunsException(BizExceptionEnum.TWO_PWD_NOT_MATCH); } Integer userId = UserExt.getUser().getId(); User user = userService.getById(userId); String oldMd5 = MD5.md5(oldPwd); if (user.getPassword().equals(oldMd5)) { String newMd5 = MD5.md5(newPwd); user.setPassword(newMd5); user.updateById(); return SUCCESS_TIP; } else { throw new GunsException(BizExceptionEnum.OLD_PWD_NOT_RIGHT); } } @Autowired private IStoreService storeService; @Autowired private UserMapper userMapper; /** * 查询管理员列表 */ @RequestMapping("/list") @Permission @ResponseBody public List list(String name, String phone, String idCard, Integer isSales, Integer state) { UserQuery userQuery = new UserQuery(); userQuery.setName(name); userQuery.setPhone(phone); userQuery.setIdCard(idCard); userQuery.setIsSales(isSales); userQuery.setStatus(state); // 根据当前登陆人类型来查询员工列表 Integer objectType = UserExt.getUser().getObjectType(); Integer objectId = UserExt.getUser().getObjectId(); switch (objectType){ case 1: // 平台查询所有 List res= userService.searchUsers(userQuery); return res; case 2: // 运营商查询运营商账号的员工和属于该运营商门店的员工 // userQuery.setObjectType(2); // userQuery.setObjectId(objectId); // // 获取属于这个运营商的门店的店长ids // List storeStaffIds = storeService.list(new QueryWrapper().eq("operatorId", objectId) // .ne("state", 3)).stream().map(TStore::getStoreStaffId).collect(Collectors.toList()); // userQuery.setStoreIds(storeStaffIds); // List res1= userService.searchUsers(userQuery); List res1= userService.searchUsers(userQuery); List filteredList = res1.stream() .filter(vo -> Objects.equals(vo.getVersion(), UserExt.getUser().getId())) .collect(Collectors.toList()); // return res1; return filteredList; case 3: // 门店只查询门店员工 TStore store = storeService.getById(objectId); List storeIds = userQuery.getStoreIds(); storeIds.add(store.getStoreStaffId()); List res2= userService.searchUsers(userQuery); return res2; } return new ArrayList<>(); // //创建日期 // String beginTime = null; // String endTime = null; // if (SinataUtil.isNotEmpty(createTime)){ // String[] timeArray = createTime.split(" - "); // beginTime = timeArray[0]; // endTime = timeArray[1]; // } // User user = UserExt.getUser(); // Role role = roleService.getBaseMapper().selectById(user.getRoleid()); // if ("administrator".equals(role.getTips())) { // Page> page = new PageFactory>().defaultPage(); // page.setRecords(userService.getUserListPage(page,null, name, beginTime, endTime, deptid)); // return super.packForBT(page); // } else { // Page> page = new PageFactory>().defaultPage(); // page.setRecords(userService.getUserListPage(page,null, name, beginTime, endTime, deptid)); // return super.packForBT(page); // } } /** * 添加管理员 */ @RequestMapping("/add") @BussinessLog(value = "添加管理员", key = "account", dict = UserDict.class) @Permission(Const.ADMIN_NAME) @ResponseBody @Transactional(rollbackFor = Exception.class) public Object add(@Valid UserDto user, BindingResult result) { if (result.hasErrors()) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } // 手机号既是登录账号,必须在 sys_user 中唯一;使用内容判断,不能使用 != 比较字符串引用。 if (StringUtils.isEmpty(user.getPhone())) { return 5002; } // 已逻辑删除的员工(status=3)不占用手机号,可用同一手机号重新创建员工。 User theUser = userService.getOne(new QueryWrapper() .eq("phone", user.getPhone()) .ne("status", ManagerStatus.DELETED.getCode())); if (theUser != null || userService.getByAccount(user.getPhone()) != null){ return 5001; } // 完善账号信息 user.setPassword(SecureUtil.md5(user.getPassword())); user.setStatus(ManagerStatus.OK.getCode()); user.setCreatetime(new Date()); User objectUser = UserFactory.createUser(user); if (StringUtils.isEmpty(user.getRoleid())){ objectUser.setObjectType(2); }else { objectUser.setObjectType(Integer.valueOf(user.getRoleid())); } objectUser.setObjectId(UserExt.getUser().getObjectId()); objectUser.setRoleid(user.getRoleid()); objectUser.setAccount(user.getPhone()); objectUser.setName(user.getName()); objectUser.setPhone(user.getPhone()); objectUser.setBirthday(user.getBirthday()); objectUser.setDeptid(user.getDeptid()); objectUser.setIdCard(user.getIdCard()); objectUser.setSex(user.getSex()); objectUser.setStatus(1); objectUser.setPassword(SecureUtil.md5("a123456")); objectUser.setCreatetime(new Date()); List assignedStores = new ArrayList(); if (user.getStoreIds() != null && !user.getStoreIds().isEmpty()) { List storeIds = user.getStoreIds().stream().filter(Objects::nonNull).distinct().collect(Collectors.toList()); if (storeIds.isEmpty()) return ResultUtil.error("请选择有效门店"); Integer currentType = UserExt.getUser().getObjectType(); Integer currentObjectId = UserExt.getUser().getObjectId(); for (Integer storeId : storeIds) { TStore store = storeService.getById(storeId); if (store == null || !Integer.valueOf(1).equals(store.getState())) return ResultUtil.error("所选门店不存在或已停用"); if ((Integer.valueOf(2).equals(currentType) && !currentObjectId.equals(store.getOperatorId())) || (Integer.valueOf(3).equals(currentType) && !currentObjectId.equals(store.getId()))) { return ResultUtil.error("所选门店不在当前账号的管理范围内"); } assignedStores.add(store); } // 首个门店同步写入旧字段,保证既有权限、数据查询和登录逻辑无需改造。 TStore primaryStore = assignedStores.get(0); objectUser.setObjectType(3); objectUser.setRoleid("3"); objectUser.setObjectId(primaryStore.getId()); // 运营商添加员工 } else if (UserExt.getUser().getObjectType() == 2){ objectUser.setObjectType(UserExt.getUser().getObjectType()); objectUser.setRoleid("2"); objectUser.setObjectId(UserExt.getUser().getObjectId()); } // 门店添加员工 if (UserExt.getUser().getObjectType() == 3){ objectUser.setObjectType(UserExt.getUser().getObjectType()); objectUser.setRoleid("3"); objectUser.setObjectId(UserExt.getUser().getObjectId()); } objectUser.setVersion(UserExt.getUser().getId()); this.userService.save(objectUser); if (!assignedStores.isEmpty()) { replaceStoreRelations(objectUser.getId(), assignedStores); // 各所选门店同步负责人账号;旧系统仍可通过 storeStaffId 查询主负责人。 for (TStore store : assignedStores) { store.setStoreStaffId(objectUser.getId()); storeService.updateById(store); } } return SUCCESS_TIP; } /** * 修改管理员 * * @throws NoPermissionException */ @RequestMapping("/edit") @BussinessLog(value = "修改管理员", key = "account", dict = UserDict.class) @ResponseBody @Transactional(rollbackFor = Exception.class) public Object edit(@Valid UserDto user, BindingResult result) throws NoPermissionException { if (result.hasErrors()) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } User oldUser = userService.getById(user.getId()); // 判断是否更改电话 if (user.getPhone() != null && user.getPhone().contains("*")) { // The edit view displays a masked phone. Treat an unchanged masked // value as "keep original", never as a value to persist. } else if (!Objects.equals(oldUser.getPhone(), user.getPhone())) { User phone = userService.getOne(new QueryWrapper().eq("phone", user.getPhone())); if (phone == null){ oldUser.setPhone(user.getPhone()); }else{ return 5001; } } oldUser.setName(user.getName()); oldUser.setBirthday(user.getBirthday()); oldUser.setDeptid(user.getDeptid()); if (user.getIdCard() == null || !user.getIdCard().contains("*")) oldUser.setIdCard(user.getIdCard()); oldUser.setSex(user.getSex()); oldUser.setEmail(user.getEmail()); if (user.getAvatar()!=null && (!user.getAvatar().equals(""))) oldUser.setAvatar(user.getAvatar()); if (user.getStoreIds() != null) { List assignedStores = validateStores(user.getStoreIds()); if (assignedStores == null) return ResultUtil.error("所选门店不存在、已停用或不在当前账号管理范围内"); replaceStoreRelations(oldUser.getId(), assignedStores); if (!assignedStores.isEmpty()) { oldUser.setObjectType(3); oldUser.setObjectId(assignedStores.get(0).getId()); oldUser.setRoleid("3"); for (TStore store : assignedStores) { store.setStoreStaffId(oldUser.getId()); storeService.updateById(store); } } } this.userService.updateById(oldUser); return SUCCESS_TIP; } private String maskPhone(String value) { if (value == null) return null; return value.length() <= 7 ? stars(value.length()) : value.substring(0, 3) + "****" + value.substring(7); } private String maskIdCard(String value) { if (value == null) return null; return value.length() <= 10 ? stars(value.length()) : value.substring(0, 6) + stars(value.length() - 10) + value.substring(value.length() - 4); } private String stars(int size) { StringBuilder result = new StringBuilder(); for (int i = 0; i < size; i++) result.append('*'); return result.toString(); } private List validateStores(List storeIds) { List stores = new ArrayList(); Integer currentType = UserExt.getUser().getObjectType(); Integer currentObjectId = UserExt.getUser().getObjectId(); for (Integer storeId : storeIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList())) { TStore store = storeService.getById(storeId); if (store == null || !Integer.valueOf(1).equals(store.getState())) return null; if ((Integer.valueOf(2).equals(currentType) && !currentObjectId.equals(store.getOperatorId())) || (Integer.valueOf(3).equals(currentType) && !currentObjectId.equals(store.getId()))) return null; stores.add(store); } return stores; } /** 每条关联记录单独生成雪花主键,避免 MyBatis foreach 复用同一个绑定变量。 */ private void replaceStoreRelations(Integer userId, List stores) { userMapper.deleteStoreRelations(userId); for (TStore store : stores) { userMapper.insertStoreRelation(IdWorker.getId(), userId, store.getId()); } } /** * 删除管理员(逻辑删除) * Delete administrator (logical deletion) */ @RequestMapping("/delete") @BussinessLog(value = "删除管理员", key = "userId", dict = UserDict.class) @Permission @ResponseBody public Tip delete(@RequestParam Integer userId) { if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } //不能删除超级管理员 //Cannot delete super administrator. if (userId.equals(Const.ADMIN_ID)) { throw new GunsException(BizExceptionEnum.CANT_DELETE_ADMIN); } assertAuth(userId); this.userService.setStatus(userId, ManagerStatus.DELETED.getCode()); return SUCCESS_TIP; } /** * 查看管理员详情 */ @RequestMapping("/view/{userId}") @ResponseBody public User view(@PathVariable Integer userId) { if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } assertAuth(userId); return this.userService.getById(userId); } /** * 重置管理员的密码 */ @RequestMapping("/reset") @BussinessLog(value = "重置管理员密码", key = "userId", dict = UserDict.class) @Permission(Const.ADMIN_NAME) @ResponseBody public Tip reset(@RequestParam Integer userId) { if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } assertAuth(userId); User user = this.userService.getById(userId); user.setPassword(SecureUtil.md5(Const.DEFAULT_PWD)); this.userService.updateById(user); return SUCCESS_TIP; } /** * 冻结用户 */ @RequestMapping("/freeze") @BussinessLog(value = "冻结用户", key = "userId", dict = UserDict.class) @Permission(Const.ADMIN_NAME) @ResponseBody public Tip freeze(@RequestParam Integer userId) { if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } //不能冻结超级管理员 Cannot freeze super administrator. if (userId.equals(Const.ADMIN_ID)) { throw new GunsException(BizExceptionEnum.CANT_FREEZE_ADMIN); } assertAuth(userId); this.userService.setStatus(userId, ManagerStatus.FREEZED.getCode()); return SUCCESS_TIP; } /** * 解除冻结用户 */ @RequestMapping("/unfreeze") @BussinessLog(value = "解除冻结用户", key = "userId", dict = UserDict.class) @Permission(Const.ADMIN_NAME) @ResponseBody public Tip unfreeze(@RequestParam Integer userId) { if (Objects.isNull(userId)) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } assertAuth(userId); this.userService.setStatus(userId, ManagerStatus.OK.getCode()); return SUCCESS_TIP; } /** * 分配角色 */ @RequestMapping("/setRole") @BussinessLog(value = "分配角色", key = "userId,roleIds", dict = UserDict.class) @Permission(Const.ADMIN_NAME) @ResponseBody public Tip setRole(@RequestParam("userId") Integer userId, @RequestParam("roleIds") String roleIds) { if (Objects.isNull(userId) || Objects.isNull(roleIds) ) { throw new GunsException(BizExceptionEnum.REQUEST_NULL); } //不能修改超级管理员 //Cannot modify super administrator if (userId.equals(Const.ADMIN_ID)) { throw new GunsException(BizExceptionEnum.CANT_CHANGE_ADMIN); } assertAuth(userId); this.userService.setRoles(userId, roleIds); return SUCCESS_TIP; } /** * 上传图片 */ @RequestMapping(method = RequestMethod.POST, path = "/uploadImg") @ResponseBody public String uploadImg(@RequestPart("file") MultipartFile picture) { String pictureName = ""; try { pictureName = OssUploadUtil.ossUpload("img/", picture); }catch (Exception e){ e.printStackTrace(); } return pictureName; } /** * 上传图片 */ /** * 上传图片Amis */ @RequestMapping(method = RequestMethod.POST, path = "/uploadImgAmis") @ResponseBody public ResultUtil uploadImgAmis(@RequestPart("file") MultipartFile picture, HttpServletResponse response) { String value = ""; try { value = OssUploadUtil.ossUpload("img/", picture); }catch (Exception e){ e.printStackTrace(); } System.out.println("图片返回地址-------"+value); Map map = new HashMap<>(); map.put("value",value); // return ResultUtil.success(0,map); return ResultUtil.getResult(0,null,null,map); } @RequestMapping(method = RequestMethod.POST, path = "/uploadFile") @ResponseBody public String uploadFile(@RequestPart("file") MultipartFile picture) { String pictureName = ""; try { pictureName = OssUploadUtil.ossUpload("video/", picture); }catch (Exception e){ e.printStackTrace(); } return pictureName; } /** * 判断当前登录的用户是否有操作这个用户的权限 */ private void assertAuth(Integer userId) { // if (ShiroKit.isAdmin()) { // return; // } // List deptDataScope = ShiroKit.getDeptDataScope(); // User user = this.userService.getById(userId); // Integer deptid = user.getDeptid(); // if (deptDataScope.contains(deptid)) { // return; // } else { // throw new GunsException(BizExceptionEnum.NO_PERMITION); // } } }