MaterialUserServiceImpl.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. package com.backendsys.modules.material.service.impl;
  2. import cn.hutool.core.convert.Convert;
  3. import cn.hutool.core.util.RandomUtil;
  4. import cn.hutool.core.bean.BeanUtil;
  5. import cn.hutool.json.JSONUtil;
  6. import com.backendsys.exception.CustException;
  7. import com.backendsys.modules.common.config.redis.utils.RedisUtil;
  8. import com.backendsys.modules.common.config.security.entity.SecurityUserInfo;
  9. import com.backendsys.modules.common.config.security.utils.CaptchaUtil;
  10. import com.backendsys.modules.common.config.security.utils.JwtUtil;
  11. import com.backendsys.modules.common.config.security.utils.LockStatusUtil;
  12. import com.backendsys.modules.common.config.security.utils.SecurityUtil;
  13. import com.backendsys.modules.material.entity.MaterialAudit;
  14. import com.backendsys.modules.material.entity.MaterialUser;
  15. import com.backendsys.modules.material.service.MaterialUserService;
  16. import com.backendsys.modules.sse.entity.SseResponse;
  17. import com.backendsys.modules.sse.entity.SseResponseEnum;
  18. import com.backendsys.modules.sse.utils.SseUtil;
  19. import com.backendsys.modules.system.dao.SysUserDao;
  20. import com.backendsys.modules.system.dao.SysUserInfoDao;
  21. import com.backendsys.modules.system.dao.SysUserRoleDao;
  22. import com.backendsys.modules.system.dao.SysUserRoleRelationDao;
  23. import com.backendsys.modules.system.entity.*;
  24. import com.backendsys.modules.system.service.SysAuthService;
  25. import com.backendsys.modules.system.service.SysCommonService;
  26. import com.backendsys.modules.system.service.SysUserIntegralService;
  27. import com.backendsys.modules.system.service.SysUserService;
  28. import com.backendsys.modules.system.utils.UserUtil;
  29. import com.backendsys.utils.response.PageEntity;
  30. import com.backendsys.utils.response.PageInfoResult;
  31. import com.backendsys.utils.v2.PageUtils;
  32. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  33. import org.springframework.beans.factory.annotation.Autowired;
  34. import org.springframework.beans.factory.annotation.Value;
  35. import org.springframework.core.env.Environment;
  36. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  37. import org.springframework.stereotype.Service;
  38. import org.springframework.transaction.annotation.Transactional;
  39. import java.util.Arrays;
  40. import java.util.LinkedHashMap;
  41. import java.util.List;
  42. import java.util.Map;
  43. @Service
  44. public class MaterialUserServiceImpl implements MaterialUserService {
  45. @Autowired
  46. private UserUtil userUtil;
  47. @Autowired
  48. private SseUtil sseUtil;
  49. @Value("${spring.application.name}")
  50. private String APPLICATION_NAME;
  51. @Value("${tencent.sms.debug}")
  52. private String SMS_DEBUG;
  53. @Autowired
  54. private Environment env;
  55. @Autowired
  56. private LockStatusUtil lockStatusUtil;
  57. @Autowired
  58. private CaptchaUtil captchaUtil;
  59. @Autowired
  60. private RedisUtil redisUtil;
  61. @Autowired
  62. private SysUserDao sysUserDao;
  63. @Autowired
  64. private SysUserInfoDao sysUserInfoDao;
  65. @Autowired
  66. private SysUserRoleDao sysUserRoleDao;
  67. @Autowired
  68. private SysUserRoleRelationDao sysUserRoleRelationDao;
  69. @Autowired
  70. private SysAuthService sysAuthService;
  71. @Autowired
  72. private SysUserService sysUserService;
  73. @Autowired
  74. private SysCommonService sysCommonService;
  75. @Autowired
  76. private SysUserIntegralService sysUserIntegralService;
  77. /**
  78. * 获取素材用户列表 ({ invite_code = Material })
  79. */
  80. @Override
  81. public PageEntity selectMaterialUserList(String phone, Long role_id) {
  82. PageUtils.startPage(); // 分页
  83. SysUserDTO sysUserDTO = new SysUserDTO();
  84. sysUserDTO.setPhone(phone);
  85. sysUserDTO.setInvite_code("Material");
  86. if (role_id != null) {
  87. sysUserDTO.setRole_id(Arrays.asList(role_id));
  88. }
  89. List<SysUserInfo> user_info_list = sysUserInfoDao.selectUserList(sysUserDTO);
  90. return new PageInfoResult(user_info_list).toEntity();
  91. }
  92. /**
  93. * 获取素材用户角色列表
  94. */
  95. @Override
  96. public List<SysUserRole> selectMaterialUserRoleList() {
  97. LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
  98. wrapper.likeRight(SysUserRole::getRole_sign, "MATERIAL");
  99. wrapper.orderByAsc(SysUserRole::getSort);
  100. List<SysUserRole> list = sysUserRoleDao.selectList(wrapper);
  101. return list;
  102. }
  103. /**
  104. * 审核素材用户
  105. */
  106. @Override
  107. @Transactional(rollbackFor = Exception.class)
  108. public Map<String, Object> auditMaterialUser(MaterialAudit materialAudit) {
  109. // 判断是否为素材用户 / 用户是否存在
  110. SysUserInfo entity = new SysUserInfo();
  111. entity.setUser_id(materialAudit.getUser_id());
  112. entity.setInvite_code("Material");
  113. SysUserInfo userInfo = sysUserService.selectUserInfo(entity);
  114. if (userInfo == null) throw new CustException("用户不存在");
  115. // 判断用户是否待审核状态 (-1审核拒绝, 1待审核, 2审核通过)
  116. if (materialAudit.getUser_id() == SecurityUtil.getUserId()) throw new CustException("不能审核自己");
  117. // [DB] 获取素材用户角色ID集合
  118. List<SysUserRole> role_list = selectMaterialUserRoleList();
  119. List<Long> role_ids = role_list.stream().map(SysUserRole::getRole_id).toList();
  120. if (!role_ids.contains(materialAudit.getRole_id())) throw new CustException("必须指定素材用户角色");
  121. // [DB] 更新用户信息-审核状态/用户状态
  122. LambdaQueryWrapper<SysUserInfo> wrapper = new LambdaQueryWrapper<>();
  123. wrapper.eq(SysUserInfo::getUser_id, materialAudit.getUser_id());
  124. wrapper.eq(SysUserInfo::getInvite_code, "Material");
  125. //
  126. userInfo.setAudit_status(materialAudit.getAudit_status());
  127. userInfo.setAudit_note("素材管理审核通过");
  128. userInfo.setStatus(materialAudit.getStatus());
  129. sysUserInfoDao.update(userInfo, wrapper);
  130. // // 如果是禁用状态,则清除该用户的登录信息
  131. // if (materialAudit.getStatus() == -1) {
  132. // sysUserService.kickUser(materialAudit.getUser_id());
  133. // }
  134. // [DB] 更新用户与角色关系 (先删,后增)
  135. LambdaQueryWrapper<SysUserRoleRelation> wrapperRoleRelation = new LambdaQueryWrapper<>();
  136. wrapperRoleRelation.eq(SysUserRoleRelation::getUser_id, materialAudit.getUser_id());
  137. sysUserRoleRelationDao.delete(wrapperRoleRelation);
  138. sysUserRoleRelationDao.insertBatch(materialAudit.getUser_id(), Arrays.asList(materialAudit.getRole_id()));
  139. // [2025-08-18] 需求:后台加白后,前台踢掉用户,强制让该用户重新登录;
  140. // https://www.tapd.cn/tapd_fe/61244365/story/detail/1161244365001000497
  141. sysUserService.kickUser(materialAudit.getUser_id());
  142. // // 重置的过期时间直接给7天
  143. // Long tokenDurationMilliseconds = userUtil.getTokenDuration(true);
  144. // Integer tokenDurationHours = Convert.toInt(tokenDurationMilliseconds / 3600000L);
  145. // // 实时更新缓存: 用户信息
  146. // SysUserInfo userInfoLasest = sysUserService.selectUserInfo(entity);
  147. // // 赋加缓存时间 { token_expiration }
  148. // SysUserInfo userInfoLasestCatch = userUtil.syncUpdateUserCatch(userInfoLasest, tokenDurationHours, true);
  149. // // 发送SSE消息到前端
  150. // sseUtil.send(userInfoLasestCatch.getUser_id(), new SseResponse(SseResponseEnum.SYSTEM_USER_UPDATE, userInfoLasestCatch).toJsonStr());
  151. return Map.of("user_id", materialAudit.getUser_id());
  152. }
  153. // 注册素材用户 (手机号注册)
  154. @Override
  155. @Transactional(rollbackFor = Exception.class)
  156. public Map<String, Object> registerMaterialUser(MaterialUser materialUser) {
  157. // 判断是否允许注册
  158. // [系统配置] 是否允许系统用户注册
  159. Boolean SYSTEM_USER_ALLOW_REGISTER = Convert.toBool(sysCommonService.getCommonByTag("SYSTEM_USER_ALLOW_REGISTER"));
  160. if (!SYSTEM_USER_ALLOW_REGISTER) throw new CustException("系统已禁止注册");
  161. String phone = materialUser.getPhone();
  162. Integer phoneAreaCode = materialUser.getPhone_area_code();
  163. Integer phoneValidCode = materialUser.getPhone_valid_code();
  164. String activeProfile = env.getActiveProfiles()[0];
  165. //if (!"local".equals(activeProfile)) {
  166. // // 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
  167. // lockStatusUtil.checkLockStatus(APPLICATION_NAME + "-register-error", phone);
  168. // // 判断图形验证码是否正确
  169. // if (!captchaUtil.isCaptchaValid(captcha, httpRequestUtil.getKaptchaKey())) {
  170. // loginFail("验证码错误", username, false);
  171. // return null;
  172. // }
  173. //}
  174. // 判断短信验证码是否正确
  175. if (!"local".equals(activeProfile)) {
  176. String redisKey = APPLICATION_NAME + "-sms-" + phone;
  177. Integer smsCode = redisUtil.getCacheObject(redisKey);
  178. // 判断是否发送验证码
  179. if ("false".equals(SMS_DEBUG) && smsCode == null) throw new CustException("请先发送短信验证码");
  180. // 判断短信验证码是否错误
  181. if ("false".equals(SMS_DEBUG) && !smsCode.equals(phoneValidCode)) sysAuthService.loginFail("短信验证码错误", phone, true);
  182. }
  183. // [查询] 判断手机号是否存在 (如果存在就直接登录,返回Token)
  184. LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
  185. queryWrapper.eq(SysUser::getPhone, phone).eq(SysUser::getPhone_area_code, phoneAreaCode);
  186. SysUser sysUserDetail = sysUserDao.selectOne(queryWrapper);
  187. if (sysUserDetail != null) {
  188. // [已注册] 返回登录信息 (并且7天免登录)
  189. SysUserInfo sysUserInfo = sysAuthService.loginSuccess(sysUserDetail.getId(), true);
  190. Map<String, Object> response = BeanUtil.beanToMap(sysUserInfo);
  191. response.put("is_register", false);
  192. return response;
  193. //
  194. } else {
  195. // [未注册] 通过校验并注册 (注册成功后,返回登录信息)
  196. // 注册
  197. SysUserDTO registerEntity = new SysUserDTO();
  198. registerEntity.setUsername(phone);
  199. registerEntity.setPhone(phone);
  200. registerEntity.setPhone_area_code(phoneAreaCode);
  201. registerEntity.setInvite_code("Material");
  202. // 注册时,使用 [素材游客] 权限 (MATERIAL_GUEST)
  203. String role_sign = "MATERIAL_GUEST";
  204. LambdaQueryWrapper<SysUserRole> wrapperRole = new LambdaQueryWrapper<>();
  205. wrapperRole.eq(SysUserRole::getRole_sign, role_sign);
  206. SysUserRole roleDetail = sysUserRoleDao.selectOne(wrapperRole);
  207. registerEntity.setRole_id(Arrays.asList(roleDetail.getRole_id()));
  208. // 注册时,审核状态为 待审核 (-1拒绝, 1待审核, 2审核通过)
  209. registerEntity.setAudit_status(2);
  210. // 随机昵称 (6位)
  211. registerEntity.setNickname("用户" + RandomUtil.randomStringUpper(6));
  212. // 创建用户
  213. sysUserDao.insertUser(registerEntity);
  214. // 初始化用户积分
  215. sysUserIntegralService.init(registerEntity.getId());
  216. // [DB] 查询用户信息
  217. SysUserInfo sysUserInfo = sysAuthService.loginSuccess(registerEntity.getId(), true);
  218. Map<String, Object> response = BeanUtil.beanToMap(sysUserInfo);
  219. response.put("is_register", true);
  220. return response;
  221. }
  222. }
  223. }