Commit 5e3ec8d1 authored by killer's avatar killer

增加用户状态

parent 738586df
package cn.quantgroup.user.enums;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.Tuple;
import lombok.Getter;
/**
* 用户状态枚举
* <br>此枚举顺序不能更改,使用到了ordinal</>
*
* @author killer
* @date 2021年12月17日
**/
@Getter
public enum UserStatusEnum {
/** 0 冻结 */
FREEZE,
/** 1 正常启用 */
NORMAL,
/** 2 销户 */
DELETE;
/**
* 校验用户当前是否可用
*
* @param user user
* @return 是否可用
*/
public static Tuple<Boolean, JsonResult<?>> isDisable(User user) {
switch (user.getEnable()) {
case 0: {
return Tuple.of(Boolean.TRUE, JsonResult.buildErrorStateResult("用户账户已冻结", null));
}
case 2: {
return Tuple.of(Boolean.TRUE, JsonResult.buildErrorStateResult("用户账户已销户", null));
}
default:
return Tuple.of(Boolean.FALSE, null);
}
}
/**
* 兼容历史接口入参为boolean值
*
* @param status 入参 true:启动;false:冻结
* @return UserStatus
*/
public static int converter(boolean status) {
if (status) {
return NORMAL.ordinal();
}
return FREEZE.ordinal();
}
}
......@@ -231,4 +231,7 @@ public interface Constants {
*/
String VERIFY_TYPE_QG = "qg";
// -- End -- 验证码常量组
/** 注销用户后再次允许注册时间间隔-天数 */
long DELETE_USER_AGAIN_REGISTER_INTERVAL = 90;
}
package cn.quantgroup.xyqb.controller.external;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.accessable.IpValidator;
import cn.quantgroup.xyqb.aspect.captcha.CaptchaFiniteValidator;
......@@ -394,8 +395,8 @@ public class UserController implements IBaseController {
log.info("修改密码失败,该手机号尚未注册, phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("修改密码失败", null);
}
if (!user.getEnable()) {
log.info("修改密码失败,该用户已禁用, phoneNo:{}", phoneNo);
if (UserStatusEnum.isDisable(user).getKey()) {
log.info("修改密码失败,该用户已冻结或销户, phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("修改密码失败", null);
}
// 验证密码:原密码不存在时,必须为空
......@@ -594,7 +595,7 @@ public class UserController implements IBaseController {
String phoneNo = credentialArr[0];
String pass = credentialArr[1];
User user = userService.findByPhoneWithCache(phoneNo);
if (user == null || !user.getEnable()) {
if (user == null || UserStatusEnum.isDisable(user).getKey()) {
// 向该ipv4添加错误计数器
lockIpv4Service.countErrorByIpv4(clientIp);
// 向该phoneNo添加错误计数器
......@@ -621,7 +622,7 @@ public class UserController implements IBaseController {
private JsonResult loginWithUserId(Long channelId, String appChannel, Long createdFrom, String userId, Merchant merchant, String dimension, HttpServletRequest request) {
//查询用户
User user = userService.findByUuidInDb(userId);
if (Objects.isNull(user) || !user.getEnable()) {
if (Objects.isNull(user) || UserStatusEnum.isDisable(user).getKey()) {
log.error("用户不存在,或者已经注销,userId:{}", userId);
return JsonResult.buildErrorStateResult("登录失败", null);
} else if (!wechatRelateUserIfNecessary(user, request)) {
......
package cn.quantgroup.xyqb.controller.external;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.entity.Merchant;
......@@ -267,7 +268,7 @@ public class WeChatController implements IBaseController {
}
User user = userService.findById(userInfoInDb.getUserId());
// 用户不存在或已注销
if (Objects.isNull(user) || !user.getEnable()) {
if (Objects.isNull(user) || UserStatusEnum.isDisable(user).getKey()) {
// 用户已经微信登录了,但是关联信用钱包用户信息无效,跳转到注册页面
redirectWechatLoginUrlWithoutLogin(response, merchant, userInfoInDb, registerFrom, domain);
return;
......
package cn.quantgroup.xyqb.controller.internal.user;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.aspect.accessable.IpValidator;
import cn.quantgroup.xyqb.aspect.captcha.LoginInterceptor;
import cn.quantgroup.xyqb.controller.IBaseController;
......@@ -96,7 +97,7 @@ public class AppController implements IBaseController {
if (user == null) {
result = JsonResult.buildErrorStateResult(USER_ERROR_OR_PASSWORD_ERROR, null);
} else if (!user.getEnable()) {
} else if (UserStatusEnum.isDisable(user).getKey()) {
result = JsonResult.buildErrorStateResult("登录失败", null);
} else {
Merchant merchant = merchantService.findMerchantByName(key);
......@@ -165,7 +166,7 @@ public class AppController implements IBaseController {
if (user == null) {
return JsonResult.buildErrorStateResult(USER_ERROR_OR_PASSWORD_ERROR, null);
}
if (!user.getEnable()) {
if (UserStatusEnum.isDisable(user).getKey()) {
return JsonResult.buildErrorStateResult("登录失败", null);
}
Merchant merchant = merchantService.findMerchantByName(key);
......@@ -230,7 +231,7 @@ public class AppController implements IBaseController {
if (user == null) {
return JsonResult.buildErrorStateResult(USER_ERROR_OR_PASSWORD_ERROR, null);
}
if (!user.getEnable()) {
if (UserStatusEnum.isDisable(user).getKey()) {
return JsonResult.buildErrorStateResult("登录失败", null);
}
Merchant merchant = merchantService.findMerchantByName(key);
......@@ -334,7 +335,7 @@ public class AppController implements IBaseController {
if (user == null) {
return JsonResult.buildErrorStateResult(USER_ERROR_OR_PASSWORD_ERROR, null);
}
if (!user.getEnable()) {
if (UserStatusEnum.isDisable(user).getKey()) {
return JsonResult.buildErrorStateResult("登录失败", null);
}
//校验租户ID tenantId
......
......@@ -49,6 +49,7 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.*;
......@@ -242,8 +243,8 @@ public class InnerController implements IBaseController {
}
User user = userService.findByUuidWithCache(uuid);
if (null != user) {
if (!user.getEnable()) {
return JsonResult.buildSuccessResult("", null);
if (UserStatusEnum.isDisable(user).getKey()) {
return UserStatusEnum.isDisable(user).getValue();
}
UserDetail userDetail = userDetailService.findByUserId(user.getId());
UserInfo info = new UserInfo(user, userDetail);
......@@ -265,8 +266,8 @@ public class InnerController implements IBaseController {
}
User user = userService.findByPhoneInDb(phone);
if (null != user) {
if (!user.getEnable()) {
return JsonResult.buildSuccessResult("", null);
if (UserStatusEnum.isDisable(user).getKey()) {
return UserStatusEnum.isDisable(user).getValue();
}
UserDetail userDetail = userDetailService.findByUserId(user.getId());
UserInfo info = new UserInfo(user, userDetail);
......@@ -319,10 +320,25 @@ public class InnerController implements IBaseController {
User user = userService.findByPhoneWithCache(phoneNo);
if (user != null) {
//存在已注销
if (!user.getEnable()) {
log.info("用户已经注销,phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("用户已经注销", null);
/* 冻结用户 */
if (UserStatusEnum.FREEZE.ordinal() == user.getEnable()) {
log.info("用户已经冻结,phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("用户已经冻结", null);
}
/* 销户用户 */
if (UserStatusEnum.DELETE.ordinal() == user.getEnable()) {
long deleteDays = DateUtils.diffDayByTimestamp(user.getUpdatedAt());
/* 如果用户销户时间大于90天 用户状态修改为可用 不在执行后续业务逻辑 */
if (Constants.DELETE_USER_AGAIN_REGISTER_INTERVAL < deleteDays) {
log.info("用户[{}]为历史销户用户, 销户时间大于90天, 直接修改状态为启用", phoneNo);
user.setEnable(UserStatusEnum.NORMAL.ordinal());
userService.saveUser(user);
return JsonResult.buildErrorStateResult(null, new UserRet(user));
}
log.info("用户[{}]已销户", phoneNo);
return JsonResult.buildErrorStateResult("用户已经销户", null);
}
// 插入关联数据
......@@ -1057,10 +1073,10 @@ public class InnerController implements IBaseController {
log.info("刷新用户激活状态失败:userId:{},enable:{},user:{}", userId, enable, user);
return false;
}
user.setEnable(enable);
user.setEnable(UserStatusEnum.converter(enable));
log.info("刷新用户激活状态失败:userId:{},enable:{},user:{}", userId, enable, user);
user = userService.saveUser(user);
if (!user.getEnable()) {
if (UserStatusEnum.isDisable(user).getKey()) {
sessionService.deleteByUserId(userId);
sessionService.deleteUserCatch(user);
// 禁用微信
......@@ -1304,7 +1320,7 @@ public class InnerController implements IBaseController {
}
User user = userService.findByPhoneWithCache(phoneNo);
// 检查用户有效性
if (user != null && !user.getEnable()) {
if (user != null && UserStatusEnum.isDisable(user).getKey()) {
log.error("用户不存在,或者已经注销,phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("登录失败", null);
}
......@@ -1376,7 +1392,7 @@ public class InnerController implements IBaseController {
Map validMap = Maps.newHashMap();
validMap.put("valid", flag);
User user = userService.findByPhoneInDb(phoneNo);
if (user != null && user.getEnable()) {
if (user != null && !UserStatusEnum.isDisable(user).getKey()) {
validMap.put("valid", true);
validMap.put("id", user.getId());
validMap.put("uuid", user.getUuid());
......@@ -1555,7 +1571,9 @@ public class InnerController implements IBaseController {
int affectedRows = userService.forbiddenUser(enable, phoneNo);
// 清除缓存,解除微信关联
User user = userService.findByPhoneInDb(phoneNo);
if (null != user && !user.getEnable()) {
/* 这里历史是为冻结使用的 扩展为冻结和销户 */
if (null != user && UserStatusEnum.isDisable(user).getKey()) {
sessionService.deleteByUserId(user.getId());
sessionService.deleteUserCatch(user);
// 禁用微信
......@@ -1597,4 +1615,32 @@ public class InnerController implements IBaseController {
cleanDataService.cleanData();
return JsonResult.buildSuccessResult("已经开始清洗");
}
/**
* 注销用户
*
* @param userId 用户id
* @return 销户结果
*/
@GetMapping("/user/cancellation/{userId}")
public JsonResult<?> cancellation(@NotNull @PathVariable("userId") Long userId) {
log.info("用户[{}], 销户开始", userId);
User user = userService.findById(userId);
if (Objects.isNull(user)) {
return JsonResult.buildErrorStateResult("用户不存在", null);
}
/* 状态改为销户 */
user.setEnable(UserStatusEnum.DELETE.ordinal());
userService.saveUser(user);
/* 清空session */
sessionService.deleteByUserId(user.getId());
/* 清空缓存 */
sessionService.deleteUserCatch(user);
/* 禁用微信 */
wechatService.forbiddenUserWeChat(user.getId());
return JsonResult.buildSuccessResult("用户销户成功", null);
}
}
\ No newline at end of file
package cn.quantgroup.xyqb.controller.middleoffice.login;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.controller.middleoffice.common.VerifyStrategyFactory;
import cn.quantgroup.xyqb.controller.middleoffice.common.VerifyTypeEnum;
import cn.quantgroup.xyqb.entity.User;
......@@ -45,11 +46,9 @@ public class LoginModule implements ILoginModule {
throw new DataException("用户名或密码不正确");
}
}
if (!user.getEnable()) {
//用户不存在
log.info("用户尝试登录,已注销:{}", phoneNo);
//todo 自定义异常
throw new DataException("用户名或密码不正确");
if (UserStatusEnum.isDisable(user).getKey()) {
log.info("用户尝试登录,已冻结或注销:{}", phoneNo);
throw new DataException("用户已冻结或销户");
}
//验证
......
package cn.quantgroup.xyqb.controller.middleoffice.user;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.event.DisableActiveEvent;
import cn.quantgroup.xyqb.model.JsonResult;
......@@ -34,7 +35,10 @@ public class UserController {
//todo 用户不存在,怎么处理
return JsonResult.buildSuccessResult();
}
user.setEnable(true);
if (UserStatusEnum.DELETE.ordinal() == user.getEnable()) {
JsonResult.buildErrorStateResult("用户已销户, 不能启用", null);
}
user.setEnable(UserStatusEnum.NORMAL.ordinal());
userService.saveUser(user);
//通知消息中心
applicationEventPublisher.publishEvent(new DisableActiveEvent(this, user));
......@@ -48,7 +52,10 @@ public class UserController {
//todo 用户不存在,怎么处理
return JsonResult.buildSuccessResult();
}
user.setEnable(false);
if (UserStatusEnum.DELETE.ordinal() == user.getEnable()) {
JsonResult.buildErrorStateResult("用户已销户, 不能冻结", null);
}
user.setEnable(UserStatusEnum.FREEZE.ordinal());
//清理缓存
userService.saveUser(user);
//通知消息中心
......
......@@ -40,7 +40,7 @@ public class User extends BaseEntity implements Serializable {
private String uuid;
@Column(name = "enable")
private Boolean enable;
private Integer enable;
/**
* 是否有密码
......
package cn.quantgroup.xyqb.event;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.service.http.IHttpService;
import com.google.common.collect.ImmutableMap;
......@@ -41,7 +42,7 @@ public class DisableActiveEventListner implements ApplicationListener<DisableAct
String userId = String.valueOf(user.getId());
String phoneNo = user.getPhoneNo();
Boolean enable = user.getEnable();
boolean enable = !UserStatusEnum.isDisable(user).getKey();
String post = httpService.postJson(msgCenter.concat(SMS_MARKET_BLACK_LIST),
ImmutableMap.of("userId", userId,
......
......@@ -33,4 +33,7 @@ public final class Tuple<Key, Value> {
this.value = value;
}
public static <Key, Value> Tuple<Key, Value> of(Key key, Value value) {
return new Tuple<>(key, value);
}
}
package cn.quantgroup.xyqb.model;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail;
import lombok.Data;
......@@ -43,7 +44,7 @@ public class UserFullInfo implements Serializable {
this.registerFrom = user.getRegisteredFrom();
this.password = user.getPassword();
this.uuid = user.getUuid();
this.enable = user.getEnable();
this.enable = !UserStatusEnum.isDisable(user).getKey();
}
if (userDetail != null) {
this.name = userDetail.getName();
......
package cn.quantgroup.xyqb.model;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.entity.User;
import lombok.Data;
......@@ -37,7 +38,7 @@ public class UserRegisterMqMessage implements Serializable {
Long updateTimeStamp = user.getUpdatedAt().getTime();
this.setId(user.getId());
this.setPhoneNo(user.getPhoneNo());
this.setEnable(user.getEnable());
this.setEnable(!UserStatusEnum.isDisable(user).getKey());
this.setRegisteredFrom(user.getRegisteredFrom());
this.setUuid(user.getUuid());
this.setCreatedAt(createTimeStamp);
......
......@@ -3,6 +3,7 @@ package cn.quantgroup.xyqb.model;
import java.io.Serializable;
import java.util.Objects;
import cn.quantgroup.user.enums.UserStatusEnum;
import lombok.Data;
import cn.quantgroup.xyqb.entity.User;
......@@ -51,7 +52,7 @@ public class UserRet implements Serializable {
Long updateTimeStamp = user.getUpdatedAt().getTime();
this.setId(user.getId());
this.setPhoneNo(user.getPhoneNo());
this.setEnable(user.getEnable());
this.setEnable(!UserStatusEnum.isDisable(user).getKey());
this.setPassword(null);
this.hasPassword = Objects.nonNull(user.getPassword()) && !Objects.equals("", user.getPassword());
this.setRegisteredFrom(user.getRegisteredFrom());
......
......@@ -12,6 +12,14 @@ import java.util.List;
*/
public interface IUserRegisterService {
/**
* 用户销户时间超过可再注册时间后再次注册
*
* @param user 用户信息
* @return User
*/
User onceAgainRegister(User user);
User register(Long registerFrom, String phoneNo);
User register(Long registerFrom, String phoneNo, Integer tenantId);
......
package cn.quantgroup.xyqb.service.register.impl;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.entity.Address;
import cn.quantgroup.xyqb.entity.Contact;
......@@ -35,6 +36,14 @@ import java.util.UUID;
@Resource
private IUserService userService;
@Transactional(rollbackFor = Exception.class)
@Override
public User onceAgainRegister(User user){
user.setEnable(UserStatusEnum.NORMAL.ordinal());
userService.saveUser(user);
return user;
}
@Transactional(rollbackFor = Exception.class)
@Override
public User register(Long registerFrom, String phoneNo) {
......@@ -113,7 +122,7 @@ import java.util.UUID;
String uuid = UUID.randomUUID().toString();
User user = new User();
user.setUuid(uuid);
user.setEnable(true);
user.setEnable(UserStatusEnum.NORMAL.ordinal());
user.setPhoneNo(userRegisterParam.getPhoneNo());
Long registerFrom = userRegisterParam.getRegisterFrom();
if (Objects.isNull(registerFrom)) {
......
......@@ -4,6 +4,7 @@ import cn.quantgroup.tech.db.DSType;
import cn.quantgroup.tech.db.TargetDataSource;
import cn.quantgroup.user.enums.BizType;
import cn.quantgroup.user.enums.IncomeRangeEnum;
import cn.quantgroup.user.enums.UserStatusEnum;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.lock.RedisLock;
import cn.quantgroup.xyqb.controller.IBaseController;
......@@ -338,8 +339,9 @@ public class UserServiceImpl implements IUserService, IBaseController {
String dimension, String clickId, HttpServletRequest request, Merchant merchant, String phoneNo, Integer tenantId) {
Boolean register = false;
User user = findByPhoneWithCache(phoneNo);
if (user != null && !user.getEnable()) {
log.info("用户不存在,或者已经注销,phoneNo:{}", phoneNo);
/* 用户已冻结或销户 */
if (user != null && UserStatusEnum.isDisable(user).getKey()) {
log.info("用户已经冻结或销户, 登录失败, phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("登录失败", null);
}
if (user == null) {
......
package cn.quantgroup.xyqb.util;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
......@@ -49,4 +48,16 @@ public class DateUtils {
long now = System.currentTimeMillis();
return (timeStamp - now) / 1000;
}
/**
* 获取距离当前时间的天数
*
* @param timestamp 时间戳
* @return 距离天数
*/
public static long diffDayByTimestamp(Timestamp timestamp) {
Date data = new Date(timestamp.getTime());
Date now = new Date();
return (now.getTime() - data.getTime()) / (24 * 60 * 60 * 1000);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment