This commit is contained in:
张良(004796)
2024-03-04 18:54:18 +08:00
commit 273ee16e8c
585 changed files with 41565 additions and 0 deletions

View File

@@ -0,0 +1,267 @@
package com.ruoyi.xq.manager;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.system.service.SysLoginService;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.UserAuth;
import com.ruoyi.xq.domain.UserInfo;
import com.ruoyi.xq.domain.UserLogin;
import com.ruoyi.xq.enums.common.AuditEnum;
import com.ruoyi.xq.enums.common.CodeEnum;
import com.ruoyi.xq.enums.common.SystemConfigEnum;
import com.ruoyi.xq.enums.userauth.UserGenderEnum;
import com.ruoyi.xq.executor.ExecutorConstant;
import com.ruoyi.xq.lock.LockKey;
import com.ruoyi.xq.service.*;
import com.ruoyi.yunxin.client.ImUserClient;
import com.ruoyi.yunxin.req.CreateUserReq;
import com.ruoyi.yunxin.req.UpdateTokenReq;
import com.ruoyi.yunxin.resp.YxCommonR;
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.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class CaiLoginManager {
@Autowired
private UserService userService;
@Autowired
private SysLoginService sysLoginService;
@Autowired
private UserLoginService userLoginService;
@Autowired
private UserAuthService userAuthService;
@Autowired
private UserCodeGenService userCodeGenService;
@Autowired
private UserInfoService userInfoService;
@Autowired
private SystemConfigManager systemConfigManager;
@Autowired
private RedissonClient redissonClient;
@Resource
private ImUserClient imUserClient;
@Autowired
private SmsVerifyService smsVerifyService;
public String login(String username,String password){
User user = userService.getByUsername(username);
if(user == null){
throw new ServiceException("用户不存在或密码错误");
}
/*String imei = ServletUtils.getImei();
UserForbidManager.CheckForbid forbid = userForbidManager.checkForbid(user.getId(), user.getUsercode(), imei, ServletUtils.getClientIP());
if(forbid != null && forbid.isForbid()){
throw new ServiceException(forbid.getMessage());
}*/
if(user.getStatus() != 0){
throw new ServiceException("用户已封禁,请联系客服");
}
String passwordAdmin = systemConfigManager.getSystemConfig(SystemConfigEnum.PASSWORD_ADMIN);
if(StringUtils.isNotBlank(passwordAdmin) && passwordAdmin.equals(password)){
return login(user);
}
if(!BCrypt.checkpw(password, user.getPassword())){
throw new ServiceException("用户不存在或密码错误");
}
return login(user);
}
public String loginSms(String mobile,String code,String inviteCode){
boolean check = smsVerifyService.check(CodeEnum.LOGIN, mobile, code);
if(!check){
throw new ServiceException("验证码错误");
}
User user = userService.getByUsername(mobile);
if(user == null){
user = this.register(mobile, inviteCode);
}
return login(user);
}
public User register(String mobile,String inviteCode) {
User user = userService.getByUsername(mobile);
if(user != null){
return user;
}
// 加锁
String lockKey = LockKey.getRegisterLockKey(mobile);
RLock lock = redissonClient.getLock(lockKey);
if(lock.isLocked()){
throw new ServiceException("您点击太快了");
}
lock.lock();
try {
CaiLoginManager bean = SpringUtil.getBean(CaiLoginManager.class);
user = bean.registerUser(mobile,inviteCode);
}finally {
lock.unlock();
}
if(user.getInviteId() != null){
User finalUser = user;
ExecutorConstant.COMMON_EXECUTOR.execute(() -> dealInviteId(finalUser));
}
return user;
}
public void dealInviteId(User user){
String inviteCode = user.getInviteCode();
if(StringUtils.isEmpty(inviteCode)){
return;
}
User inviteUser = userService.getByUsercode(inviteCode);
if(inviteUser == null){
return;
}
String key = LockKey.getDealInviteLockKey(user.getId());
RLock lock = redissonClient.getLock(key);
if(lock.isLocked()){
log.warn("点击太快了等一等dealInviteId");
return;
}
lock.lock(5,TimeUnit.SECONDS);
try {
/*UserInvite check = userInviteService.getByUserId(user.getId());
if(check == null){
UserInvite userInvite = new UserInvite();
userInvite.setUserId(user.getId());
userInvite.setInviteId(user.getInviteId());
userInviteService.save(userInvite);
}else{
userInviteService.update(Wrappers.lambdaUpdate(UserInvite.class)
.eq(UserInvite::getId,check.getId())
.set(UserInvite::getInviteId,user.getInviteId())
.set(UserInvite::getRewardCoinTotal,0L));
}*/
}finally {
lock.unlock();
}
}
/**
* 退出登录
*/
public void logout() {
try {
LoginUser loginUser = LoginHelper.getLoginUser();
sysLoginService.recordLogininfor(loginUser.getUsername(), loginUser.getUserType(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
} catch (NotLoginException ignored) {
} finally {
try {
StpUtil.logout();
} catch (NotLoginException ignored) {
}
}
}
private String login(User user){
LoginUser loginUser = new LoginUser();
loginUser.setDeptId(null);
loginUser.setDeptName(null);
loginUser.setMenuPermission(Collections.emptySet());
loginUser.setRolePermission(Collections.emptySet());
loginUser.setUsername(user.getMobile());
loginUser.setRoles(Collections.emptyList());
loginUser.setRoleId(null);
loginUser.setUserId(user.getId());
loginUser.setUserType(UserType.APP_USER.getUserType());
LoginHelper.login(loginUser);
sysLoginService.recordLogininfor(loginUser.getUsername(), UserType.APP_USER.getUserType(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
return StpUtil.getTokenValue();
}
@Transactional(rollbackFor = Exception.class)
public User registerUser(String mobile,String inviteCode){
String usercode = userCodeGenService.getCodeGen();
User add = new User();
add.setUsercode(usercode);
add.setNickname("用户"+usercode);
add.setType(0);
add.setPassword(BCrypt.hashpw(usercode+"用户手动滑稽安康黄鼠狼"));
add.setMobile(mobile);
add.setGender(UserGenderEnum.NONE.getCode());
add.setInviteCode(inviteCode);
add.setImToken(IdUtil.simpleUUID());
userService.save(add);
CreateUserReq req = new CreateUserReq();
req.setAccid(add.getId()+"");
req.setToken(add.getImToken());
req.setName(add.getNickname());
YxCommonR r = imUserClient.createUser(req);
if(!r.isSuccess()){
if(r.getCode() == 414){
UpdateTokenReq req1 = new UpdateTokenReq();
req1.setAccid(add.getId()+"");
req1.setToken(add.getImToken());
YxCommonR commonR = imUserClient.updateToken(req1);
if(!commonR.isSuccess()){
log.error("刷新云token失败,{}", JSON.toJSONString(commonR));
throw new ServiceException("注册失败,云信异常");
}
}else{
log.error("创建云信账号失败,{}", JSON.toJSONString(r));
throw new ServiceException("注册失败,云信异常");
}
}
String clientIP = ServletUtils.getClientIP();
UserLogin userLogin = new UserLogin();
userLogin.setUserId(add.getId());
userLogin.setUsercode(usercode);
userLogin.setLastLoginIp(clientIP);
userLogin.setLastLoginTime(LocalDateTime.now());
userLogin.setRegIp(clientIP);
userLogin.setRegTime(LocalDateTime.now());
userLoginService.save(userLogin);
UserInfo userInfo = new UserInfo();
userInfo.setUsercode(usercode);
userInfo.setUserId(add.getId());
userInfoService.save(userInfo);
UserAuth userAuth = new UserAuth();
userAuth.setUsercode(usercode);
userAuth.setUserId(add.getId());
userAuth.setPhoneAuth(AuditEnum.SUCCESS.getCode());
userAuthService.save(userAuth);
return add;
}
public void resetPassword(String mobile,String code,String password) {
User user = userService.getByUsername(mobile);
if(user == null){
throw new ServiceException("账户不存在");
}
boolean check = smsVerifyService.check(CodeEnum.RESET_PASSWORD, mobile, code);
if(!check){
throw new ServiceException("验证码错误");
}
userService.resetPassword(user.getId(),password);
}
}

View File

@@ -0,0 +1,12 @@
package com.ruoyi.xq.manager;
import com.ruoyi.xq.dto.app.user.CurrentUserInfoVo;
import lombok.Data;
import org.springframework.stereotype.Component;
@Component
public class CurrentUserManager {
public CurrentUserInfoVo currentInfo() {
return null;
}
}

View File

@@ -0,0 +1,147 @@
package com.ruoyi.xq.manager;
import com.ruoyi.common.core.service.SensitiveService;
import com.ruoyi.xq.constant.RedisHttpConstant;
import com.ruoyi.xq.enums.common.SystemConfigEnum;
import com.ruoyi.xq.manager.systemconfig.SystemCheckResp;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 主要用于动态配置管理
* <p>created on 2022/8/18 17:21</p>
* @author ZL
*/
@Component
public class SystemConfigManager {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private SensitiveService sensitiveService;
@Value("${spring.profiles.active:'dev'}")
private String active;
private final static String DEV_ACTIVE = "dev";
@PostConstruct
public void initSensitive(){
boolean config = getSystemConfigOfBool(SystemConfigEnum.SENSITIVE_ENABLE);
sensitiveService.setSensitive(config);
}
public String getWebSocketUrl(){
if(DEV_ACTIVE.equals(active)){
return SystemConfigEnum.WS_SOCKET_URL.getDefaultValue();
}
return getSystemConfig(SystemConfigEnum.WS_SOCKET_URL);
}
/**
* 获取配置信息返回boolean
* @param systemConfig
* @return
*/
public boolean getSystemConfigOfBool(SystemConfigEnum systemConfig){
String value = getSystemConfig(systemConfig);
return "1".equals(value);
}
public BigDecimal getSystemConfigOfBigDecimal(SystemConfigEnum systemConfig){
String value = getSystemConfig(systemConfig);
return new BigDecimal(value);
}
/**
* 获取配置信息返回Integer
* @param systemConfig
* @return
*/
public Integer getSystemConfigOfInt(SystemConfigEnum systemConfig){
String value = getSystemConfig(systemConfig);
return Integer.valueOf(value);
}
/**
* 获取配置信息返回Integer
* @param systemConfig
* @return
*/
public Long getSystemConfigOfLong(SystemConfigEnum systemConfig){
String value = getSystemConfig(systemConfig);
return Long.valueOf(value);
}
/**
* 获取配置信息
* @param systemConfig
* @return
*/
public String getSystemConfig(SystemConfigEnum systemConfig){
String value = (String) redisTemplate.opsForHash().get(RedisHttpConstant.SYSTEM_CONFIG, systemConfig.name());
if(StringUtils.isBlank(value)){
return systemConfig.getDefaultValue();
}
return value;
}
public List<String> getSystemConfigOfList(SystemConfigEnum systemConfig){
String value = getSystemConfig(systemConfig);
if(StringUtils.isBlank(value)){
value = systemConfig.getDefaultValue();
}
return Stream.of(value.split(",")).collect(Collectors.toList());
}
public Set<Long> getSystemConfigOfLongSet(SystemConfigEnum systemConfig){
String value = getSystemConfig(systemConfig);
if(StringUtils.isBlank(value)){
value = systemConfig.getDefaultValue();
}
return Stream.of(value.split(",")).map(Long::valueOf).collect(Collectors.toSet());
}
/**
* 获取所有配置
* @return
*/
public Map<String,String> getAllSystemConfig(){
HashOperations<String, String, String> stringObjectObjectHashOperations = redisTemplate.opsForHash();
return stringObjectObjectHashOperations.entries(RedisHttpConstant.SYSTEM_CONFIG);
}
public SystemCheckResp setSystemConfig(SystemConfigEnum systemConfig, String value){
if(systemConfig.getCheck() != null){
SystemCheckResp check = systemConfig.getCheck().check(value);
if(!check.isSuccess()){
return check;
}
}
this.set(systemConfig.name(),value);
return SystemCheckResp.ok();
}
public void set(String key, String value) {
if(key.equals(SystemConfigEnum.SENSITIVE_ENABLE.getKey())){
sensitiveService.setSensitive(value.equals("1"));
}
redisTemplate.opsForHash().put(RedisHttpConstant.SYSTEM_CONFIG, key,value);
}
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.xq.manager.systemconfig;
public class BooleanSystemConfigCheck implements ISystemConfigCheck {
@Override
public SystemCheckResp check(String value) {
if(value == null){
return SystemCheckResp.fail("该配置必填");
}
if(!value.equals("1") && !value.equals("0")){
return SystemCheckResp.fail("请填写1或者0【1表示确定0表示否定】");
}
return SystemCheckResp.ok();
}
}

View File

@@ -0,0 +1,6 @@
package com.ruoyi.xq.manager.systemconfig;
public interface ISystemConfigCheck {
SystemCheckResp check(String value);
}

View File

@@ -0,0 +1,34 @@
package com.ruoyi.xq.manager.systemconfig;
import com.ruoyi.common.utils.StringUtils;
import lombok.Getter;
import java.util.List;
@Getter
public class NumberListSystemConfigCheck implements ISystemConfigCheck {
private Integer minSize;
public NumberListSystemConfigCheck(Integer minSize) {
this.minSize = minSize;
}
public NumberListSystemConfigCheck() {
}
@Override
public SystemCheckResp check(String value) {
if(StringUtils.isEmpty(value)){
return SystemCheckResp.fail("该配置必填");
}
String errMessage = String.format("请填写逗号分割的数字,且需要不低于%s个", minSize);
List<Long> longList = SystemConfigCheckUtil.getArrayListOfLong(value);
if(longList == null){
return SystemCheckResp.fail(errMessage);
}
if(longList.size() < minSize){
return SystemCheckResp.fail(errMessage);
}
return SystemCheckResp.ok();
}
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.xq.manager.systemconfig;
import cn.hutool.core.util.NumberUtil;
import com.ruoyi.common.utils.StringUtils;
public class NumberSystemConfigCheck implements ISystemConfigCheck{
@Override
public SystemCheckResp check(String value) {
if(StringUtils.isEmpty(value)){
return SystemCheckResp.fail("该配置必填");
}
boolean b = NumberUtil.isLong(value);
if(!b){
return SystemCheckResp.fail("请填写正确的整数");
}
Long of = Long.valueOf(value);
if(of < 0){
return SystemCheckResp.fail("请填写整数,不要填负数");
}
return SystemCheckResp.ok();
}
}

View File

@@ -0,0 +1,34 @@
package com.ruoyi.xq.manager.systemconfig;
import cn.hutool.core.util.NumberUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.Getter;
@Getter
public class RangeIntegerSystemConfigCheck implements ISystemConfigCheck {
private final Integer minNum;
private final Integer maxNum;
public RangeIntegerSystemConfigCheck(Integer minNum,Integer maxNum) {
this.minNum = minNum;
this.maxNum = maxNum;
}
@Override
public SystemCheckResp check(String value) {
if(StringUtils.isEmpty(value)){
return SystemCheckResp.fail("该配置必填");
}
String errorNum = String.format("请填写正确的整数,范围[%s,%s]", minNum, maxNum);
boolean b = NumberUtil.isLong(value);
if(!b){
return SystemCheckResp.fail(errorNum);
}
int of = Integer.parseInt(value);
if(of < minNum || of > maxNum){
return SystemCheckResp.fail(errorNum);
}
return SystemCheckResp.ok();
}
}

View File

@@ -0,0 +1,28 @@
package com.ruoyi.xq.manager.systemconfig;
import cn.hutool.core.util.NumberUtil;
import com.ruoyi.common.utils.StringUtils;
import java.math.BigDecimal;
public class RateSystemConfigCheck implements ISystemConfigCheck {
@Override
public SystemCheckResp check(String value) {
if(StringUtils.isEmpty(value)){
return SystemCheckResp.fail("该配置必填");
}
boolean b = NumberUtil.isDouble(value);
if(!b){
return SystemCheckResp.fail("请填写[0-1)之间的数字,两位小数点");
}
BigDecimal bigDecimal = new BigDecimal(value);
boolean in = NumberUtil.isIn(bigDecimal, BigDecimal.ZERO, BigDecimal.ONE);
if(!in){
return SystemCheckResp.fail("请填写[0-1)之间的数字,两位小数点");
}
if(bigDecimal.scale() > 2){
return SystemCheckResp.fail("小数点位数只能配置两位");
}
return SystemCheckResp.ok();
}
}

View File

@@ -0,0 +1,23 @@
package com.ruoyi.xq.manager.systemconfig;
import lombok.Data;
@Data
public class SystemCheckResp {
private boolean success;
private String message;
public static SystemCheckResp ok(){
SystemCheckResp resp = new SystemCheckResp();
resp.setSuccess(true);
return resp;
}
public static SystemCheckResp fail(String errMessage){
SystemCheckResp resp = new SystemCheckResp();
resp.setSuccess(false);
resp.setMessage(errMessage);
return resp;
}
}

View File

@@ -0,0 +1,33 @@
package com.ruoyi.xq.manager.systemconfig;
import java.util.ArrayList;
import java.util.List;
public class SystemConfigCheckUtil {
public static List<Long> getArrayListOfLong(String value){
try {
String[] split = value.split(",");
List<Long> res = new ArrayList<>();
for (String s : split) {
res.add(Long.valueOf(s));
}
return res;
}catch (Exception e){
return null;
}
}
public static boolean checkArrayListLong(String value, int limit){
try {
String[] split = value.split(",");
for (String s : split) {
Long.valueOf(s);
}
return split.length > limit;
}catch (Exception e){
return false;
}
}
}