package com.mzl.flower.service.system; 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.mzl.flower.config.exception.ValidationException; import com.mzl.flower.config.security.SecurityUtils; import com.mzl.flower.constant.Constants; import com.mzl.flower.dto.request.BindWechatDTO; import com.mzl.flower.dto.request.CreateWechatUserDTO; import com.mzl.flower.dto.request.UserLoginDTO; import com.mzl.flower.dto.request.UserPhoneLoginDTO; import com.mzl.flower.dto.request.customer.UpdateCustomerDTO; import com.mzl.flower.dto.request.system.*; import com.mzl.flower.dto.response.current.CurrentUserDTO; import com.mzl.flower.dto.response.customer.CustomerDTO; import com.mzl.flower.dto.response.system.*; import com.mzl.flower.entity.customer.Customer; import com.mzl.flower.entity.point.CustomerPoint; import com.mzl.flower.entity.system.*; import com.mzl.flower.enums.TrueOrFalseEnum; import com.mzl.flower.mapper.customer.CustomerMapper; import com.mzl.flower.mapper.point.CustomerPointMapper; import com.mzl.flower.mapper.system.*; import com.mzl.flower.service.customer.CustomerService; import com.mzl.flower.service.partner.PartnerService; import com.mzl.flower.service.payment.RedisLockService; import com.mzl.flower.service.point.CustomerPointService; import com.mzl.flower.service.supplier.StationService; import com.mzl.flower.service.supplier.SupplierService; import com.mzl.flower.utils.TreeBuilderUtil; import com.mzl.flower.utils.UUIDGenerator; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import javax.validation.constraints.NotBlank; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; @Service @Transactional @Slf4j public class UserService { @Autowired private UserMapper userMapper; @Autowired private PasswordEncoder passwordEncoder; @Autowired private UserRoleMapper userRoleMapper; @Autowired private MenuMapper menuMapper; @Autowired private PartnerMenuMapper partnerMenuMapper; @Autowired private RoleMenuMapper roleMenuMapper; @Autowired private RoleService roleService; @Autowired private UserWechatMapper wechatMapper; @Autowired private SupplierService supplierService; @Autowired private PartnerService partnerService; @Autowired private CustomerService customerService; @Autowired private EmployeeMapper employeeMapper; @Autowired private CustomerPointMapper customerPointMapper; @Autowired private CustomerMapper customerMapper; @Autowired private StationService stationService; @Autowired RedissonClient redissonClient; public User findUserByOpenId(String openId, String sessionKey, String unionId , String imgUrl, String nickname, String userType) { List userTypes = new ArrayList<>(); userTypes.add(userType); List userList = userMapper.getByOpenID(openId, userTypes); if (CollectionUtils.isEmpty(userList)) { throw new ValidationException("请注册账号后至\"个人中心-绑定微信\"后再使用微信登录"); } User user = userList.get(0); // user.setNickName(nickname); user.setNickName(user.getLoginName()); user.setPicture(imgUrl); user.update(user.getId()); userMapper.updateById(user); UserWechat wechat = wechatMapper.selectOne(new LambdaQueryWrapper() .eq(UserWechat::getOpenId, openId) .eq(UserWechat::getUserId, user.getId())); if (wechat == null) { throw new ValidationException("请至\"个人中心-绑定微信\"后再使用微信登录"); } wechat.setOpenId(openId); wechat.setUnionId(unionId); wechat.setSessionKey(sessionKey); wechatMapper.updateById(wechat); return user; } public void bindWechat(String userId, String openId, String unionId, String sessionKey, BindWechatDTO dto) { // 查看微信是否已经绑定过用户 User user = userMapper.selectById(userId); if (ObjectUtils.isEmpty(user)) { throw new ValidationException("当前用户不存在"); } List userList = wechatMapper.selectUserByOpenId(openId, user.getType()); if (!CollectionUtils.isEmpty(userList)) { throw new ValidationException("该微信已绑定其他账号"); } UserWechat wechat = wechatMapper.selectOne(new LambdaQueryWrapper() .eq(UserWechat::getUserId, userId)); if (wechat == null) { wechat = new UserWechat(); wechat.setId(UUIDGenerator.getUUID()); wechat.setUserId(userId); wechat.setOpenId(openId); wechat.setUnionId(unionId); wechat.setSessionKey(sessionKey); wechat.setRealName(dto.getRealName()); wechatMapper.insert(wechat); } else { wechat.setOpenId(openId); wechat.setUnionId(unionId); wechat.setSessionKey(sessionKey); wechat.setRealName(dto.getRealName()); wechatMapper.updateById(wechat); } } public User getUserByThirdId(String thirdId) { User u = userMapper.selectOne(new QueryWrapper().eq("third_id", thirdId)); if (u == null) { throw new ValidationException("用户不存在"); } return u; } public CurrentUserDTO getCurrentUser() { String userId = SecurityUtils.getUserId(); CurrentUserDTO result = new CurrentUserDTO(); //获取用户信息 User user = getUserById(userId); if (user == null) { throw new ValidationException("用户不存在"); } result.setLoginName(user.getLoginName()); result.setNickName(user.getNickName()); result.setTel(user.getTel()); result.setPicture(user.getPicture()); result.setType(user.getType()); //获取用户角色信息 List roleIds = new ArrayList<>(); List roleList = roleService.getUserRoleList(userId); for (Role role : roleList) { roleIds.add(role.getId()); } result.setRoles(roleIds); //根据用户角色获取用户菜单 List menus = null; if (Constants.USER_TYPE.admin.name().equals(user.getType())) { if (roleIds.contains(Constants.ROLE_SYS_ADMIN)) { menus = menuMapper.selectListOrderBySeq(); } else if (roleIds.size() > 0) { menus = menuMapper.selectOperationList(roleIds); } } else if (Constants.USER_TYPE.partner.name().equals(user.getType())) { menus = partnerMenuMapper.selectListOrderBySeq(); } if (menus != null) { for (MenuTreeDTO menu : menus) { menu.setPath(menu.getMenuHref()); menu.setName(menu.getMenuName()); menu.setLabel(menu.getMenuName()); } menus = (List) TreeBuilderUtil.buildListToTree(menus); } result.setMenus(menus); // List menuList = new ArrayList<>(); // if(roleIds.size() > 0){ // List ls = roleMenuMapper.selectList(new QueryWrapper().in("ROLE_ID", roleIds)); // for(RoleMenu rm : ls){ // menuList.add(rm.getMenuId()); // } // } // result.setMenuList(menuList); result.setId(userId); if (Constants.USER_TYPE.customer.name().equals(user.getType())) { result.setCustomerDTO(customerService.getCurrentCustomer()); //查询积分 CustomerPoint customerPoint = customerPointMapper.selectOne(new LambdaQueryWrapper() .eq(CustomerPoint::getUserId, userId)); if (customerPoint == null) { result.setCurrentPoint(0); } else { Integer currentPoint = customerPoint.getTotalPoint() - customerPoint.getUsedPoint() - customerPoint.getExpiredPoint() - customerPoint.getDeductionPoint(); result.setCurrentPoint(currentPoint >= 0 ? currentPoint : 0); } } else if (Constants.USER_TYPE.supplier.name().equals(user.getType())) { result.setSupplierDTO(supplierService.getCurrentSupplier()); } else if (Constants.USER_TYPE.partner.name().equals(user.getType())) { result.setPartnerDTO(partnerService.getCurrentPartner()); } else if (Constants.USER_TYPE.admin.name().equals(user.getType())) { result.setMainWarehouse(stationService.getMainWarehouse(user.getId())); } result.setBindWechat(wechatMapper.selectCount(new LambdaQueryWrapper() .eq(UserWechat::getUserId, userId)) > 0); return result; } public User getUserById(String id) { return userMapper.selectById(id); } public User loginUser(String username) { return userMapper.loginUser(username); } public User findByLoginName(String loginName, List userTypes) { return userMapper.getActiveUser(loginName, userTypes); } public void updateUserInfo(UserInfoDTO dto) { String id = SecurityUtils.getUserId(); User user = getUserById(id); List userTypes = new ArrayList<>(); userTypes.add(user.getType()); String tel = dto.getTel(); if (StringUtils.isEmpty(user.getTel()) || !user.getTel().equals(tel)) { User u = findByLoginName(tel, userTypes); if (u != null) { throw new ValidationException("手机号已存在"); } user.setTel(dto.getTel()); } user.setPicture(dto.getPicture()); user.setNickName(dto.getNickName()); user.update(id); userMapper.updateById(user); } /** * 新增用户 * * @param dto * @return */ public User addUser(CreateUserDTO dto) { String type = dto.getType(); List userTypes = new ArrayList<>(); userTypes.add(type); String tel = dto.getTel(); User u = findByLoginName(tel, userTypes); if (u != null) { throw new ValidationException("手机号已存在"); } String loginName = dto.getLoginName(); u = findByLoginName(loginName, userTypes); if (u != null) { throw new ValidationException("账号已存在"); } //添加用户 User user = new User(); BeanUtils.copyProperties(dto, user); user.setId(UUIDGenerator.getUUID()); user.setPassword(passwordEncoder.encode(dto.getPassword())); user.setIsSys(Constants.N); user.create(SecurityUtils.getUserId()); userMapper.insert(user); //给用户添加角色 addRole(dto.getRoleIds(), user.getId()); //添加或更新员工信息 addEmployee(dto.getEmployeeDTO(), user.getId()); return user; } private void addEmployee(AddEmployeeDTO dto, String userId) { Employee employee = employeeMapper.selectOne(new LambdaQueryWrapper().eq(Employee::getUserId, userId)); if (employee == null) { employee = new Employee(); BeanUtils.copyProperties(dto, employee); employee.setUserId(userId); employee.create(SecurityUtils.getUserId()); employeeMapper.insert(employee); } else { BeanUtils.copyProperties(dto, employee); employee.setUserId(userId); employee.update(SecurityUtils.getUserId()); employeeMapper.updateById(employee); } } private void addRole(List roleIds, String userId) { if (roleIds != null && roleIds.size() > 0) { for (String roleId : roleIds) { UserRole userRole = new UserRole(); userRole.setId(UUIDGenerator.getUUID()); userRole.setUserId(userId); userRole.setRoleId(roleId); userRoleMapper.insert(userRole); } } } public Page searchUser(SearchUserDTO dto, Page page) { List result = userMapper.searchUser(page, dto); page.setRecords(result); return page; } public UserDetailsDTO getUserDetail(String id) { //获取用户信息 User user = getUserById(id); //获取用户的角色信息 List userRoles = userRoleMapper.selectList( new QueryWrapper().eq("user_id", id) ); List roleIds = new ArrayList<>(); for (UserRole userRole : userRoles) { roleIds.add(userRole.getRoleId()); } UserDetailsDTO result = new UserDetailsDTO(); if (user != null) { BeanUtils.copyProperties(user, result); result.setRoleIds(roleIds); String roleDesc = userMapper.selectUserRoleDesc(id); result.setRoleDesc(roleDesc); Employee employee = employeeMapper.selectOne(new LambdaQueryWrapper().eq(Employee::getUserId, id)); if (employee != null) { EmployeeDTO employeeDTO = new EmployeeDTO(); BeanUtils.copyProperties(employee, employeeDTO); result.setEmployeeDTO(employeeDTO); } } return result; } /** * 更新用户 * * @param dto */ public void updateUser(UpdateUserDTO dto) { String id = dto.getId(); User user = getUserById(id); checkAndSetUserLoginInfo(user, dto.getTel(), dto.getLoginName()); if (StringUtils.isNotBlank(dto.getPassword())) { user.setPassword(passwordEncoder.encode(dto.getPassword())); } BeanUtils.copyProperties(dto, user, "loginName", "tel", "password", "type"); user.update(SecurityUtils.getUserId()); userMapper.updateById(user); if (Constants.USER_TYPE.admin.name().equals(user.getType())) { //删除用户的角色信息 userRoleMapper.delete(new QueryWrapper().eq("user_id", id)); //给用户添加角色 addRole(dto.getRoleIds(), id); } //添加或更新员工信息 addEmployee(dto.getEmployeeDTO(), user.getId()); } private void checkAndSetUserLoginInfo(User user, String tel, String loginName) { List userTypes = new ArrayList<>(); userTypes.add(user.getType()); if (StringUtils.isEmpty(user.getTel()) || !user.getTel().equals(tel)) { User u = findByLoginName(tel, userTypes); if (u != null) { throw new ValidationException("手机号已存在"); } user.setTel(tel); } if (StringUtils.isNotEmpty(loginName)) { if (StringUtils.isEmpty(user.getLoginName()) || !user.getLoginName().equals(loginName)) { User u = findByLoginName(loginName, userTypes); if (u != null) { throw new ValidationException("用户名已存在"); } user.setLoginName(loginName); } } } public void deleteUser(String id) { User user = getUserById(id); user.setDeleted(true); user.update(SecurityUtils.getUserId()); userMapper.updateById(user); } public void resetUserPassword(ResetUserPasswordDTO dto) { User user = getUserById(dto.getUserId()); user.setPassword(passwordEncoder.encode(dto.getPassword())); user.update(SecurityUtils.getUserId()); userMapper.updateById(user); } public void changePassword(ChangePasswordDTO dto) { String userId = SecurityUtils.getUserId(); User user = getUserById(userId); if (StringUtils.isNotBlank(dto.getOldPassword())) { if (!passwordEncoder.matches(dto.getOldPassword(), user.getPassword())) { throw new ValidationException("原密码错误,无权修改"); } } user.setPassword(passwordEncoder.encode(dto.getPassword())); user.update(SecurityUtils.getUserId()); userMapper.updateById(user); } public void setUserStatus(String id, String status) { User user = getUserById(id); user.setStatus(status); user.update(SecurityUtils.getUserId()); userMapper.updateById(user); } public List getCurrentUserMenuTrue() { String userId = SecurityUtils.getUserId(); //获取用户角色信息 List roleIds = new ArrayList<>(); List roleList = roleService.getUserRoleList(userId); for (Role role : roleList) { roleIds.add(role.getId()); } //根据用户角色获取用户菜单 List menus = menuMapper.selectListOrderBySeq(); /*if (roleIds.contains(Constants.ROLE_SYS_ADMIN)) { menus = menuMapper.selectListOrderBySeq(); } else if (roleIds != null && roleIds.size() > 0) { menus = menuMapper.selectOperationList(roleIds); }*/ if (menus != null) { for (MenuTreeDTO menu : menus) { menu.setPath(menu.getMenuHref()); menu.setName(menu.getMenuName()); menu.setLabel(menu.getMenuName()); } menus = (List) TreeBuilderUtil.buildListToTree(menus); } return menus; } public User findByTel(String tel, String userType) { List userTypes = new ArrayList<>(); userTypes.add(userType); return userMapper.getActiveUser(tel, userTypes); } public List getVipGradeUserList(String getVipGrade) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(User::getDeleted, TrueOrFalseEnum.FALSE.isFlag()) .eq(User::getVipGrade, getVipGrade); return userMapper.selectList(queryWrapper); } /** * 查看微信是否已经存在用户 * * @param openId * @param sessionKey * @param unionId * @param userType * @return */ public User getExistUserByOpenId(String openId, String sessionKey, String unionId, String userType) { List userTypes = new ArrayList<>(); userTypes.add(userType); List userList = userMapper.getByOpenID(openId, userTypes); if (!CollectionUtils.isEmpty(userList)) { return userList.get(0); } return null; } public void registWxUser(CreateWechatUserDTO dto) { String RETISTER_KEY = "%s_%s"; RLock lock = redissonClient.getLock(String.format(RETISTER_KEY, dto.getPurePhoneNumber(), dto.getUserType())); try { // 获取锁,最多等待 10 秒,锁自动释放时间 30 秒 if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { try { // 其次查找当前loginName是prephonenume的,userType是customer的用户存在不存在 if (StringUtils.isEmpty(dto.getPurePhoneNumber()) && StringUtils.isEmpty(dto.getPhoneNumber())) { throw new ValidationException("微信获取的电话号码为空!无法注册"); } // 1:查看用户存在不存在 List userTypes = new ArrayList<>(); userTypes.add(dto.getUserType()); User user = findByLoginName(dto.getPurePhoneNumber(), userTypes); if (ObjectUtils.isEmpty(user)) { // 是新用户,需要注册 user = new User(); user.setId(UUIDGenerator.getUUID()); user.setLoginName(dto.getPurePhoneNumber()); user.setTel(dto.getPurePhoneNumber()); user.setNickName(dto.getPurePhoneNumber()); user.setPassword(passwordEncoder.encode("12345678")); user.setType(dto.getUserType()); user.setStatus(Constants.STATUS_ACTIVE); user.setIsSys(Constants.N); user.create(); userMapper.insert(user); // 注册商户信息 UpdateCustomerDTO updateCustomerDTO = new UpdateCustomerDTO(); updateCustomerDTO.setUserId(user.getId()); if (StringUtils.isNotBlank(dto.getPurePhoneNumber())) { updateCustomerDTO.setName("花满芫-" + dto.getPurePhoneNumber().substring(dto.getPurePhoneNumber().length() - 4)); } updateCustomerDTO.setIsMember(true); // 会员 customerService.addOrUpdateCustomer(updateCustomerDTO); } BindWechatDTO wechatDTO = new BindWechatDTO(); wechatDTO.setRealName(dto.getPurePhoneNumber()); bindWechat(user.getId(), dto.getOpenId(), dto.getUnionId(), dto.getSessionKey(), wechatDTO); } finally { lock.unlock(); } } } catch (InterruptedException e) { throw new RuntimeException(e); } } public Page searchUserInfos(SearchUserDTO dto, Page page) { List result = userMapper.searchUserInfo(page, dto); page.setRecords(result); return page; } public User registPhoneUser(UserPhoneLoginDTO dto) { String RETISTER_KEY = "%s_%s"; RLock lock = redissonClient.getLock(String.format(RETISTER_KEY, dto.getUsername(), dto.getUserType())); try { // 获取锁,最多等待 10 秒,锁自动释放时间 30 秒 if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { try { // 其次查找当前loginName是prephonenume的,userType是customer的用户存在不存在 if (StringUtils.isEmpty(dto.getUsername()) && StringUtils.isEmpty(dto.getUsername())) { throw new ValidationException("电话号码为空!无法注册"); } // 1:查看用户存在不存在 List userTypes = new ArrayList<>(); userTypes.add(dto.getUserType()); User user = findByLoginName(dto.getUsername(), userTypes); if (ObjectUtils.isEmpty(user)) { //验证邀请码 if (StringUtils.isNotEmpty(dto.getIntevailCode()) && customerService.checkCode(dto.getIntevailCode())) { throw new ValidationException("无效邀请码"); } // 是新用户,需要注册 user = new User(); user.setId(UUIDGenerator.getUUID()); user.setLoginName(dto.getUsername()); user.setTel(dto.getUsername()); user.setNickName(dto.getUsername()); user.setPassword(passwordEncoder.encode("12345678")); user.setType(dto.getUserType()); user.setStatus(Constants.STATUS_ACTIVE); user.setIsSys(Constants.N); user.create(); userMapper.insert(user); // 注册商户信息 UpdateCustomerDTO updateCustomerDTO = new UpdateCustomerDTO(); updateCustomerDTO.setUserId(user.getId()); updateCustomerDTO.setRegesterCode(dto.getIntevailCode()); //有效邀请码注册成功后赠送1天会员 updateCustomerDTO.setIsMember(true); updateCustomerDTO.setMemberOvertime(LocalDateTime.now().plusDays(180)); //2025-04-25 注释掉,不启用这个功能 // if (!customerService.checkCode(dto.getIntevailCode())) { // updateCustomerDTO.setIsMember(true); // updateCustomerDTO.setMemberOvertime(LocalDateTime.now().plusDays(1)); // } if (StringUtils.isNotBlank(dto.getUsername())) { updateCustomerDTO.setName("智信-" + dto.getUsername().substring(dto.getUsername().length() - 4)); } updateCustomerDTO.setCover("https://hmy-flower.oss-cn-shanghai.aliyuncs.com/8f/8f205ea4618b4ce48d5bd204ae73f075tmp_f0c47a66148245dc17d74563c5939e764273ba583619664d.jpg"); customerService.addOrUpdateCustomer(updateCustomerDTO); //邀请会员权益 //2025-04-25 注释掉,不启用这个功能 // intervialUser(dto.getIntevailCode()); return user; } } finally { lock.unlock(); } } } catch (InterruptedException e) { throw new RuntimeException(e); } return null; } //邀请成功增加用户权益 private void intervialUser(String code) { //按照该邀请码下已有邀请人数做相应的会员有效期增加 Integer InvitatCount = customerMapper.getInvitatCountByCode(code); //根据邀请码查找对应的邀请人员 //1人-3天,3人-15天,5人-30天 Customer customerByCode = customerMapper.findCustomerByInvitationCode(code); if (!ObjectUtils.isEmpty(customerByCode)) { LocalDateTime memberOvertime = customerByCode.getMemberOvertime(); if (!customerByCode.getIsMember()) { memberOvertime = LocalDateTime.now(); } switch (InvitatCount) { case 1: memberOvertime = memberOvertime.plusDays(3); break; case 3: memberOvertime = memberOvertime.plusDays(15); break; case 5: memberOvertime = memberOvertime.plusDays(30); break; } customerByCode.setIsMember(true); customerByCode.setMemberOvertime(memberOvertime); customerService.updateMemberInfo(customerByCode); } } }