Commit f2b57e46 authored by killer's avatar killer

Merge branch 'dev_deleteUser_20211229_lkw' into release

# Conflicts:
#	src/main/java/cn/quantgroup/xyqb/service/user/IUserService.java
#	src/main/java/cn/quantgroup/xyqb/service/user/impl/UserServiceImpl.java
parents 8d1af00c c1e23eb8
...@@ -232,4 +232,7 @@ public interface Constants { ...@@ -232,4 +232,7 @@ public interface Constants {
*/ */
String VERIFY_TYPE_QG = "qg"; String VERIFY_TYPE_QG = "qg";
// -- End -- 验证码常量组 // -- End -- 验证码常量组
/** 注销用户后再次允许注册时间间隔-天数 */
long DELETE_USER_AGAIN_REGISTER_INTERVAL = 90;
} }
...@@ -187,4 +187,14 @@ public class ExceptionHandlingController implements IBaseController { ...@@ -187,4 +187,14 @@ public class ExceptionHandlingController implements IBaseController {
public JsonResult handelMissingServletRequestParameterException(MissingServletRequestParameterException re) { public JsonResult handelMissingServletRequestParameterException(MissingServletRequestParameterException re) {
return JsonResult.buildErrorStateResult(re.getMessage(), null); return JsonResult.buildErrorStateResult(re.getMessage(), null);
} }
/**
* 用户注册登录异常处理
* @param e 异常
* @return JsonResult<String>
*/
@ExceptionHandler(UserRegisterLoginException.class)
public JsonResult<?> handleUserDeregisterException(UserRegisterLoginException e) {
return JsonResult.buildErrorStateResult(e.getMessage(), null);
}
} }
...@@ -49,6 +49,7 @@ import org.springframework.web.bind.annotation.*; ...@@ -49,6 +49,7 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Min; import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.text.ParseException; import java.text.ParseException;
import java.util.*; import java.util.*;
...@@ -1597,4 +1598,23 @@ public class InnerController implements IBaseController { ...@@ -1597,4 +1598,23 @@ public class InnerController implements IBaseController {
cleanDataService.cleanData(); cleanDataService.cleanData();
return JsonResult.buildSuccessResult("已经开始清洗"); return JsonResult.buildSuccessResult("已经开始清洗");
} }
/**
* 注销用户
*
* @param userId 用户id
* @return 销户结果
*/
@ApiOperation(value = "注销用户", httpMethod = "GET", notes="注销用户")
@GetMapping("/user/delete/{userId}")
public JsonResult<?> deregister(@NotNull @PathVariable("userId") Long userId) {
log.info("用户id[{}], 销户开始", userId);
/* 执行销户 */
userService.deregister(userId);
log.info("用户id[{}], 销户成功", userId);
return JsonResult.buildSuccessResult("用户销户成功", true);
}
} }
\ No newline at end of file
package cn.quantgroup.xyqb.entity;
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
/**
* 销户记录
*
* @author killer
* @date 2021年12月29日
**/
@Getter
@Setter
@ToString
@Builder
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user_deregister_record")
public class UserDeregisterRecord implements Serializable {
private static final long serialVersionUID = -1L;
/** 主建ID */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private Long id;
/** 用户表ID */
@Column(name = "user_id")
private Long userId;
/** 手机号MD5 */
@Column(name = "phone_no")
private String phoneNo;
/** password */
@Column(name = "password")
private String password;
/** 渠道表ID */
@Column(name = "registered_from")
private Long registeredFrom;
/** uuid */
@Column(name = "uuid")
private String uuid;
/** uuid */
@Column(name = "deregister_time")
private Date deregisterTime;
/** 创建时间 */
@Column(name = "created_at")
private Timestamp createdAt;
/** 更新时间 */
@Column(name = "updated_at")
private Timestamp updatedAt;
@PrePersist
public void prePersist() {
Timestamp now = new Timestamp(System.currentTimeMillis());
this.createdAt = now;
this.updatedAt = now;
}
@PreUpdate
public void preUpdate() {
this.updatedAt = new Timestamp(System.currentTimeMillis());
}
}
package cn.quantgroup.xyqb.exception;
/**
* 用户销户异常
*
* @author killer
* @date 2021年12月29日14:31:02
*/
public class UserRegisterLoginException extends RuntimeException {
private static final long serialVersionUID = -1L;
public UserRegisterLoginException(String msg, Throwable t) {
super(msg, t);
}
public UserRegisterLoginException(String msg) {
super(msg);
}
}
package cn.quantgroup.xyqb.repository;
import cn.quantgroup.xyqb.entity.UserDeregisterRecord;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
* 销户 Repository
*
* @author killer
* @date 2021年12月29日12:05:01
*/
public interface IUserDeregisterRecordRepository extends JpaRepository<UserDeregisterRecord, Long> {
/**
* 通过用户手机号md5查询销户记录
*
* @param phoneNo 手机号md5
* @return List<UserDeregisterRecord>
*/
List<UserDeregisterRecord> findByPhoneNo(String phoneNo);
}
...@@ -21,6 +21,7 @@ public interface IUserRepository extends JpaRepository<User, Long>, JpaSpecifica ...@@ -21,6 +21,7 @@ public interface IUserRepository extends JpaRepository<User, Long>, JpaSpecifica
/** /**
* 根据手机号查询用户UUID * 根据手机号查询用户UUID
*
* @param phoneNo - 手机号 * @param phoneNo - 手机号
* @return user表的uuid * @return user表的uuid
*/ */
...@@ -29,6 +30,7 @@ public interface IUserRepository extends JpaRepository<User, Long>, JpaSpecifica ...@@ -29,6 +30,7 @@ public interface IUserRepository extends JpaRepository<User, Long>, JpaSpecifica
/** /**
* 根据身份证号查询用户UUID * 根据身份证号查询用户UUID
*
* @param idNo - 身份证号 * @param idNo - 身份证号
* @return user表的uuid * @return user表的uuid
*/ */
...@@ -51,4 +53,11 @@ public interface IUserRepository extends JpaRepository<User, Long>, JpaSpecifica ...@@ -51,4 +53,11 @@ public interface IUserRepository extends JpaRepository<User, Long>, JpaSpecifica
List<User> findByUuidIn(List<String> uuids); List<User> findByUuidIn(List<String> uuids);
/**
* 根据userId删除用户
*
* @param userId 用户id
*/
void deleteById(Long userId);
} }
...@@ -12,7 +12,6 @@ import static org.springframework.transaction.annotation.Propagation.MANDATORY; ...@@ -12,7 +12,6 @@ import static org.springframework.transaction.annotation.Propagation.MANDATORY;
/** /**
* Created by 11 on 2017/1/18. * Created by 11 on 2017/1/18.
* modify by djh 20200527 http://confluence.quantgroup.cn/pages/viewpage.action?pageId=30657427 * modify by djh 20200527 http://confluence.quantgroup.cn/pages/viewpage.action?pageId=30657427
*
*/ */
public interface IWeChatUserRepository extends JpaRepository<WechatUserInfo, Long> { public interface IWeChatUserRepository extends JpaRepository<WechatUserInfo, Long> {
WechatUserInfo findByOpenIdAndAppName(String openId, String appName); WechatUserInfo findByOpenIdAndAppName(String openId, String appName);
...@@ -37,6 +36,17 @@ public interface IWeChatUserRepository extends JpaRepository<WechatUserInfo, Lon ...@@ -37,6 +36,17 @@ public interface IWeChatUserRepository extends JpaRepository<WechatUserInfo, Lon
@Query(value = "update wechat_userinfo set user_id=null,phone_no='*' where user_id=?1 and app_name=?2", nativeQuery = true) @Query(value = "update wechat_userinfo set user_id=null,phone_no='*' where user_id=?1 and app_name=?2", nativeQuery = true)
int dissociateByUserIdAndAppName(Long userId, String appName); int dissociateByUserIdAndAppName(Long userId, String appName);
/**
* 解除商城用户与小程序和公众号关联关系
*
* @param userId 用户id
* @return 结果
*/
@Transactional(rollbackFor = Exception.class)
@Modifying
@Query(value = "update wechat_userinfo set user_id=null,phone_no='*' where user_id=?1 and app_name in ('xyqb', 'wuxi')", nativeQuery = true)
int forbiddenXyqbAndWuxiUserByUserId(Long userId);
/** /**
* 关联用户 * 关联用户
* *
......
package cn.quantgroup.xyqb.service.register;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDeregisterRecord;
import java.util.List;
/**
* 销户服务
*
* @author killer
* @date 2021年12月29日14:23:53
*/
public interface IUserDeregisterService {
/**
* 通过用户手机号md5查询销户记录
*
* @param phoneNo 手机号md5
* @return List<UserDeregisterRecord>
*/
List<UserDeregisterRecord> queryByPhoneNo(String phoneNo);
/**
* 保存用户销户记录
*
* @param user 用户
*/
void save(User user);
}
package cn.quantgroup.xyqb.service.register.impl;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDeregisterRecord;
import cn.quantgroup.xyqb.repository.IUserDeregisterRecordRepository;
import cn.quantgroup.xyqb.service.register.IUserDeregisterService;
import cn.quantgroup.xyqb.util.encrypt.Md5Util;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* 销户服务实现
*
* @author killer
* @date 2021年12月29日
**/
@Slf4j
@Service
@RequiredArgsConstructor
public class IUserDeregisterServiceImpl implements IUserDeregisterService {
private final IUserDeregisterRecordRepository userDeregisterRecordRepository;
@Override
public List<UserDeregisterRecord> queryByPhoneNo(String phoneNo) {
return userDeregisterRecordRepository.findByPhoneNo(phoneNo);
}
@Override
public void save(User user) {
UserDeregisterRecord build = UserDeregisterRecord.builder()
.userId(user.getId())
.deregisterTime(new Date())
.password(user.getPassword())
.registeredFrom(user.getRegisteredFrom())
.uuid(user.getUuid())
.phoneNo(Md5Util.build(user.getPhoneNo()))
.build();
userDeregisterRecordRepository.save(build);
}
}
...@@ -4,12 +4,17 @@ import cn.quantgroup.xyqb.Constants; ...@@ -4,12 +4,17 @@ import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.entity.Address; import cn.quantgroup.xyqb.entity.Address;
import cn.quantgroup.xyqb.entity.Contact; import cn.quantgroup.xyqb.entity.Contact;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDeregisterRecord;
import cn.quantgroup.xyqb.event.RegisterEvent; import cn.quantgroup.xyqb.event.RegisterEvent;
import cn.quantgroup.xyqb.exception.UserRegisterLoginException;
import cn.quantgroup.xyqb.model.UserRegisterParam; import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.service.register.IUserDeregisterService;
import cn.quantgroup.xyqb.service.register.IUserRegisterService; import cn.quantgroup.xyqb.service.register.IUserRegisterService;
import cn.quantgroup.xyqb.service.user.IUserService; import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.util.DateUtils;
import cn.quantgroup.xyqb.util.PasswordUtil; import cn.quantgroup.xyqb.util.PasswordUtil;
import cn.quantgroup.xyqb.util.TenantUtil; import cn.quantgroup.xyqb.util.TenantUtil;
import cn.quantgroup.xyqb.util.encrypt.Md5Util;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
...@@ -17,9 +22,9 @@ import org.springframework.stereotype.Service; ...@@ -17,9 +22,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.*;
import java.util.Objects;
import java.util.UUID; import static cn.quantgroup.xyqb.Constants.DELETE_USER_AGAIN_REGISTER_INTERVAL;
/** /**
* @author liqing * @author liqing
...@@ -27,7 +32,7 @@ import java.util.UUID; ...@@ -27,7 +32,7 @@ import java.util.UUID;
*/ */
@Service("userRegisterService") @Service("userRegisterService")
@Slf4j @Slf4j
public class UserRegisterServiceImpl implements IUserRegisterService { public class UserRegisterServiceImpl implements IUserRegisterService {
@Resource @Resource
private ApplicationEventPublisher applicationEventPublisher; private ApplicationEventPublisher applicationEventPublisher;
...@@ -35,9 +40,16 @@ import java.util.UUID; ...@@ -35,9 +40,16 @@ import java.util.UUID;
@Resource @Resource
private IUserService userService; private IUserService userService;
@Resource
private IUserDeregisterService userDeregisterService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User register(Long registerFrom, String phoneNo) { public User register(Long registerFrom, String phoneNo) {
/* 用户销户检查 */
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom) .registerFrom(registerFrom)
.phoneNo(phoneNo) .phoneNo(phoneNo)
...@@ -54,6 +66,9 @@ import java.util.UUID; ...@@ -54,6 +66,9 @@ import java.util.UUID;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User register(Long registerFrom, String phoneNo, Integer tenantId) { public User register(Long registerFrom, String phoneNo, Integer tenantId) {
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom) .registerFrom(registerFrom)
.phoneNo(phoneNo) .phoneNo(phoneNo)
...@@ -72,6 +87,9 @@ import java.util.UUID; ...@@ -72,6 +87,9 @@ import java.util.UUID;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId) { public User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId) {
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom) .registerFrom(registerFrom)
.phoneNo(phoneNo) .phoneNo(phoneNo)
...@@ -91,6 +109,9 @@ import java.util.UUID; ...@@ -91,6 +109,9 @@ import java.util.UUID;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId, Integer tenantId) { public User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId, Integer tenantId) {
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom) .registerFrom(registerFrom)
.phoneNo(phoneNo) .phoneNo(phoneNo)
...@@ -142,6 +163,9 @@ import java.util.UUID; ...@@ -142,6 +163,9 @@ import java.util.UUID;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public boolean register(String phoneNo, String password, Long registerFrom, String ip, Long channelId, Long btRegisterChannelId, String dimension) { public boolean register(String phoneNo, String password, Long registerFrom, String ip, Long channelId, Long btRegisterChannelId, String dimension) {
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom) .registerFrom(registerFrom)
.phoneNo(phoneNo).password(password) .phoneNo(phoneNo).password(password)
...@@ -160,6 +184,9 @@ import java.util.UUID; ...@@ -160,6 +184,9 @@ import java.util.UUID;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User register(String phoneNo, Long channelId, Long registerFrom, String appChannel, Long btRegisterChannelId, String dimension) { public User register(String phoneNo, Long channelId, Long registerFrom, String appChannel, Long btRegisterChannelId, String dimension) {
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom) .registerFrom(registerFrom)
.phoneNo(phoneNo) .phoneNo(phoneNo)
...@@ -179,6 +206,9 @@ import java.util.UUID; ...@@ -179,6 +206,9 @@ import java.util.UUID;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User register(String phoneNo, Long channelId, Long registerFrom, String appChannel, Long btRegisterChannelId, String dimension, Integer tenantId) { public User register(String phoneNo, Long channelId, Long registerFrom, String appChannel, Long btRegisterChannelId, String dimension, Integer tenantId) {
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom) .registerFrom(registerFrom)
.phoneNo(phoneNo) .phoneNo(phoneNo)
...@@ -199,6 +229,9 @@ import java.util.UUID; ...@@ -199,6 +229,9 @@ import java.util.UUID;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User register(Long registeredFrom, Long channelId, String phoneNo, String name, String idNo, Address addressObj, String contacts, List<Contact> contactList, Long btRegisterChannelId) { public User register(Long registeredFrom, Long channelId, String phoneNo, String name, String idNo, Address addressObj, String contacts, List<Contact> contactList, Long btRegisterChannelId) {
deregisterCheck(phoneNo);
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registeredFrom) .registerFrom(registeredFrom)
.phoneNo(phoneNo) .phoneNo(phoneNo)
...@@ -218,4 +251,28 @@ import java.util.UUID; ...@@ -218,4 +251,28 @@ import java.util.UUID;
return user; return user;
} }
/**
* 注册校验-销户校验
*
* @param phoneNo 手机号
*/
private void deregisterCheck(String phoneNo) {
List<UserDeregisterRecord> deregisterRecords = userDeregisterService.queryByPhoneNo(Md5Util.build(phoneNo));
/* 获取最新销户记录 */
Optional<UserDeregisterRecord> lastOne = deregisterRecords.stream()
.max(Comparator.comparing(UserDeregisterRecord::getDeregisterTime));
if (!lastOne.isPresent()) {
return;
}
/* 销户时间小于90天不允许再次注册 */
long diffDay = DateUtils.dayDiff(new Date(), lastOne.get().getDeregisterTime());
if (DELETE_USER_AGAIN_REGISTER_INTERVAL >= diffDay) {
throw new UserRegisterLoginException("距离上次销户时间小于90天,无法再次注册");
}
}
} }
...@@ -26,7 +26,7 @@ public interface IUserService { ...@@ -26,7 +26,7 @@ public interface IUserService {
User findByPhoneInDb(String phone); User findByPhoneInDb(String phone);
User findSlaveByPhoneInDb(String phone); User findSlaveByPhoneInDb(String phone);
User findByUuidInDb(String uuid); User findByUuidInDb(String uuid);
...@@ -93,11 +93,12 @@ public interface IUserService { ...@@ -93,11 +93,12 @@ public interface IUserService {
/** /**
* 按照userid 或者 uuid 批量查询 * 按照userid 或者 uuid 批量查询
*
* @param vals * @param vals
* @param type * @param type
* @return * @return
*/ */
List<User> findByUuidsOrUserIds(List<String> vals,Integer type, Integer tenantId); List<User> findByUuidsOrUserIds(List<String> vals, Integer type, Integer tenantId);
/** /**
* 登出 * 登出
...@@ -105,4 +106,11 @@ public interface IUserService { ...@@ -105,4 +106,11 @@ public interface IUserService {
void logout(String token); void logout(String token);
void kdspLogout(Long userId, LoginProperties loginProperties); void kdspLogout(Long userId, LoginProperties loginProperties);
/**
* 通过userId销户
*
* @param userId 用户id
*/
void deregister(Long userId);
} }
...@@ -12,10 +12,12 @@ import cn.quantgroup.xyqb.entity.*; ...@@ -12,10 +12,12 @@ import cn.quantgroup.xyqb.entity.*;
import cn.quantgroup.xyqb.event.PhoneNoUpdateEvent; import cn.quantgroup.xyqb.event.PhoneNoUpdateEvent;
import cn.quantgroup.xyqb.exception.DataException; import cn.quantgroup.xyqb.exception.DataException;
import cn.quantgroup.xyqb.exception.UserNotExistException; import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.exception.UserRegisterLoginException;
import cn.quantgroup.xyqb.model.*; import cn.quantgroup.xyqb.model.*;
import cn.quantgroup.xyqb.repository.IUserHashMappingRepository; import cn.quantgroup.xyqb.repository.IUserHashMappingRepository;
import cn.quantgroup.xyqb.repository.IUserHashPhoneNoIdNoMappingRepository; import cn.quantgroup.xyqb.repository.IUserHashPhoneNoIdNoMappingRepository;
import cn.quantgroup.xyqb.repository.IUserRepository; import cn.quantgroup.xyqb.repository.IUserRepository;
import cn.quantgroup.xyqb.service.register.IUserDeregisterService;
import cn.quantgroup.xyqb.service.register.IUserRegisterService; import cn.quantgroup.xyqb.service.register.IUserRegisterService;
import cn.quantgroup.xyqb.service.session.ISessionService; import cn.quantgroup.xyqb.service.session.ISessionService;
import cn.quantgroup.xyqb.service.user.*; import cn.quantgroup.xyqb.service.user.*;
...@@ -91,6 +93,9 @@ public class UserServiceImpl implements IUserService, IBaseController { ...@@ -91,6 +93,9 @@ public class UserServiceImpl implements IUserService, IBaseController {
@Autowired @Autowired
private ITenantService tenantService; private ITenantService tenantService;
@Autowired
private IUserDeregisterService userDeregisterService;
@Override @Override
// @Cacheable(value = "usercache", key = "'xyqbuser' + #phone", unless = "#result == null", cacheManager = "cacheManager") // @Cacheable(value = "usercache", key = "'xyqbuser' + #phone", unless = "#result == null", cacheManager = "cacheManager")
public User findByPhoneInDb(String phone) { public User findByPhoneInDb(String phone) {
...@@ -115,7 +120,7 @@ public class UserServiceImpl implements IUserService, IBaseController { ...@@ -115,7 +120,7 @@ public class UserServiceImpl implements IUserService, IBaseController {
//校验租户ID //校验租户ID
if (!tenantId.equals(tenantId)) { if (!tenantId.equals(tenantId)) {
users = tenantService.selectUsersByTenantId(users, tenantId); users = tenantService.selectUsersByTenantId(users, tenantId);
}else { } else {
users = tenantService.validationTentIdByTentId(users, tenantId); users = tenantService.validationTentIdByTentId(users, tenantId);
} }
users.forEach(user -> userIdAndPhoneMap.put(user.getId(), user.getPhoneNo())); users.forEach(user -> userIdAndPhoneMap.put(user.getId(), user.getPhoneNo()));
...@@ -356,28 +361,28 @@ public class UserServiceImpl implements IUserService, IBaseController { ...@@ -356,28 +361,28 @@ public class UserServiceImpl implements IUserService, IBaseController {
return JsonResult.buildErrorStateResult("登录时微信关联失败", null); return JsonResult.buildErrorStateResult("登录时微信关联失败", null);
} }
try { try {
String scDeviceId=request.getHeader("scDeviceId"); String scDeviceId = request.getHeader("scDeviceId");
if(!StringUtils.isEmpty(scDeviceId)){ if (!StringUtils.isEmpty(scDeviceId)) {
iSensorsAnalytics.trackSignUp( user.getUuid(),scDeviceId); iSensorsAnalytics.trackSignUp(user.getUuid(), scDeviceId);
} }
String terminal=request.getHeader("terminal"); String terminal = request.getHeader("terminal");
String channel=request.getHeader("channel"); String channel = request.getHeader("channel");
log.info("--------手机号{}-------scDeviceId{},terminal{},channel{},是否注册{}",phoneNo,scDeviceId,terminal,channel,register); log.info("--------手机号{}-------scDeviceId{},terminal{},channel{},是否注册{}", phoneNo, scDeviceId, terminal, channel, register);
if(!StringUtils.isEmpty(terminal)&&"APP".equals(terminal)||!StringUtils.isEmpty(channel)&&("214".equals(channel)||"217".equals(channel))){ if (!StringUtils.isEmpty(terminal) && "APP".equals(terminal) || !StringUtils.isEmpty(channel) && ("214".equals(channel) || "217".equals(channel))) {
if(register){ if (register) {
EventRecord userRecord = EventRecord.builder().setDistinctId(user.getUuid()).isLoginId(Boolean.TRUE) EventRecord userRecord = EventRecord.builder().setDistinctId(user.getUuid()).isLoginId(Boolean.TRUE)
.setEventName("App_RegisterEvent") .setEventName("App_RegisterEvent")
.build(); .build();
iSensorsAnalytics.track(userRecord); iSensorsAnalytics.track(userRecord);
}else { } else {
EventRecord userRecord = EventRecord.builder().setDistinctId(user.getUuid()).isLoginId(Boolean.TRUE) EventRecord userRecord = EventRecord.builder().setDistinctId(user.getUuid()).isLoginId(Boolean.TRUE)
.setEventName("App_LoginEvent") .setEventName("App_LoginEvent")
.build(); .build();
iSensorsAnalytics.track(userRecord); iSensorsAnalytics.track(userRecord);
} }
iSensorsAnalytics.flush(); iSensorsAnalytics.flush();
}else { } else {
log.info("老神策埋点{},{}------------",user.getRegisteredFrom(),user.getUuid()); log.info("老神策埋点{},{}------------", user.getRegisteredFrom(), user.getUuid());
EventRecord userRecord = EventRecord.builder().setDistinctId(user.getUuid()).isLoginId(Boolean.TRUE) EventRecord userRecord = EventRecord.builder().setDistinctId(user.getUuid()).isLoginId(Boolean.TRUE)
.setEventName("PD_WUXIEC_UserLoginVccorCash") .setEventName("PD_WUXIEC_UserLoginVccorCash")
.addProperty("son_channel_id", user.getRegisteredFrom()) .addProperty("son_channel_id", user.getRegisteredFrom())
...@@ -506,14 +511,14 @@ public class UserServiceImpl implements IUserService, IBaseController { ...@@ -506,14 +511,14 @@ public class UserServiceImpl implements IUserService, IBaseController {
List<User> users = userRepository.findByIdIn(collect); List<User> users = userRepository.findByIdIn(collect);
if (!tenantId.equals(TenantUtil.TENANT_DEFAULT)) { if (!tenantId.equals(TenantUtil.TENANT_DEFAULT)) {
return tenantService.selectUsersByTenantId(users, tenantId); return tenantService.selectUsersByTenantId(users, tenantId);
}else { } else {
return tenantService.validationTentIdByTentId(users, tenantId); return tenantService.validationTentIdByTentId(users, tenantId);
} }
} else { //不是1 就是 uuids } else { //不是1 就是 uuids
List<User> users = userRepository.findByUuidIn(vals); List<User> users = userRepository.findByUuidIn(vals);
if (!tenantId.equals(TenantUtil.TENANT_DEFAULT)) { if (!tenantId.equals(TenantUtil.TENANT_DEFAULT)) {
return tenantService.selectUsersByTenantId(users, tenantId); return tenantService.selectUsersByTenantId(users, tenantId);
}else { } else {
return tenantService.validationTentIdByTentId(users, tenantId); return tenantService.validationTentIdByTentId(users, tenantId);
} }
} }
...@@ -530,4 +535,26 @@ public class UserServiceImpl implements IUserService, IBaseController { ...@@ -530,4 +535,26 @@ public class UserServiceImpl implements IUserService, IBaseController {
sessionService.kdspDeleteSession(userId, loginProperties); sessionService.kdspDeleteSession(userId, loginProperties);
} }
@Transactional(rollbackFor = Exception.class)
@Override
public void deregister(Long userId) {
User user = userRepository.findById(userId);
if (Objects.isNull(user)) {
throw new UserRegisterLoginException("用户不存在");
}
/* 保存用户销户记录 */
userDeregisterService.save(user);
/* 删除用户 */
userRepository.deleteById(userId);
/* 清空session */
sessionService.deleteByUserId(user.getId());
/* 清空缓存 */
sessionService.deleteUserCatch(user);
/* 禁用微信 */
wechatService.forbiddenXyqbAndWuxiUserByUserId(user.getId());
}
} }
...@@ -35,7 +35,16 @@ public interface IWechatService { ...@@ -35,7 +35,16 @@ public interface IWechatService {
* @return * @return
*/ */
WechatUserInfo queryByUserId(Long userId); WechatUserInfo queryByUserId(Long userId);
WechatUserInfo queryByUserId(Long userId,String appName);
WechatUserInfo queryByUserId(Long userId, String appName);
int forbiddenUserWeChat(Long userId); int forbiddenUserWeChat(Long userId);
/**
* 通过userId解除商城用户与小程序和公众号关联关系
*
* @param userId 用户id
* @return 禁用结果
*/
int forbiddenXyqbAndWuxiUserByUserId(Long userId);
} }
...@@ -117,20 +117,20 @@ public class WechatServiceImpl implements IWechatService { ...@@ -117,20 +117,20 @@ public class WechatServiceImpl implements IWechatService {
@Override @Override
public WechatUserInfo findWechatUserInfoFromDb(String openId) { public WechatUserInfo findWechatUserInfoFromDb(String openId) {
return weChatUserRepository.findByOpenIdAndAppName(openId,"xyqb"); return weChatUserRepository.findByOpenIdAndAppName(openId, "xyqb");
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public WechatUserInfo saveWechatUserInfo(WechatUserInfo userInfo) { public WechatUserInfo saveWechatUserInfo(WechatUserInfo userInfo) {
log.info("微信信息保存开始:{}",JSON.toJSONString(userInfo)); log.info("微信信息保存开始:{}", JSON.toJSONString(userInfo));
if (Objects.isNull(userInfo) || Objects.isNull(userInfo.getOpenId())) { if (Objects.isNull(userInfo) || Objects.isNull(userInfo.getOpenId())) {
return null; return null;
} }
long count = weChatUserRepository.countByOpenIdAndAppName(userInfo.getOpenId(),"xyqb"); long count = weChatUserRepository.countByOpenIdAndAppName(userInfo.getOpenId(), "xyqb");
if (count > 0) { if (count > 0) {
//注意,这里会抛异常(5000/total),WeChatController中已捕获处理 //注意,这里会抛异常(5000/total),WeChatController中已捕获处理
return weChatUserRepository.findByOpenIdAndAppName(userInfo.getOpenId(),"xyqb"); return weChatUserRepository.findByOpenIdAndAppName(userInfo.getOpenId(), "xyqb");
} }
if (null == userInfo.getPhoneNo()) { if (null == userInfo.getPhoneNo()) {
userInfo.setPhoneNo(""); userInfo.setPhoneNo("");
...@@ -151,9 +151,9 @@ public class WechatServiceImpl implements IWechatService { ...@@ -151,9 +151,9 @@ public class WechatServiceImpl implements IWechatService {
userInfo = userInfo.convertEmoji(); userInfo = userInfo.convertEmoji();
WechatUserInfo wechatUserInfo = weChatUserRepository.save(userInfo); WechatUserInfo wechatUserInfo = weChatUserRepository.save(userInfo);
WechatEventMsg wechatEventMsg = WechatEventMsg.builder() WechatEventMsg wechatEventMsg = WechatEventMsg.builder()
.userId(wechatUserInfo.getUserId()) .userId(wechatUserInfo.getUserId())
.openId(wechatUserInfo.getOpenId()) .openId(wechatUserInfo.getOpenId())
.build(); .build();
applicationEventPublisher.publishEvent(new WechatBindEvent(this, wechatEventMsg)); applicationEventPublisher.publishEvent(new WechatBindEvent(this, wechatEventMsg));
return wechatUserInfo; return wechatUserInfo;
} }
...@@ -166,27 +166,27 @@ public class WechatServiceImpl implements IWechatService { ...@@ -166,27 +166,27 @@ public class WechatServiceImpl implements IWechatService {
return 0; return 0;
} }
// Old - 当前openId的WechatUserInfo // Old - 当前openId的WechatUserInfo
WechatUserInfo wechatUserInfo = weChatUserRepository.findByOpenIdAndAppName(openId,"xyqb"); WechatUserInfo wechatUserInfo = weChatUserRepository.findByOpenIdAndAppName(openId, "xyqb");
if (Objects.nonNull(wechatUserInfo) && Objects.equals(userId, wechatUserInfo.getUserId()) && Objects.equals(openId, wechatUserInfo.getOpenId())) { if (Objects.nonNull(wechatUserInfo) && Objects.equals(userId, wechatUserInfo.getUserId()) && Objects.equals(openId, wechatUserInfo.getOpenId())) {
log.info("微信关联成功:重复关联:跳过:[service]:userId:{},phoneNo:{},openId:{}", userId, phoneNo, openId); log.info("微信关联成功:重复关联:跳过:[service]:userId:{},phoneNo:{},openId:{}", userId, phoneNo, openId);
return 1; return 1;
} }
// 强制解除关联 // 强制解除关联
int dissociate = weChatUserRepository.dissociateUser(openId, userId,"xyqb"); int dissociate = weChatUserRepository.dissociateUser(openId, userId, "xyqb");
if (dissociate < 1) { if (dissociate < 1) {
log.error("微信关联失败:解绑条数<1:[service]:userId:{},phoneNo:{},openId:{}", userId, phoneNo, openId); log.error("微信关联失败:解绑条数<1:[service]:userId:{},phoneNo:{},openId:{}", userId, phoneNo, openId);
throw new WechatRelateUserException("微信关联失败"); throw new WechatRelateUserException("微信关联失败");
} }
int relate = weChatUserRepository.relateUser(userId, Optional.ofNullable(phoneNo).orElse(""), openId,"xyqb"); int relate = weChatUserRepository.relateUser(userId, Optional.ofNullable(phoneNo).orElse(""), openId, "xyqb");
if (relate < 1) { if (relate < 1) {
log.error("微信关联失败:绑定条数<1:[service]:userId:{},phoneNo:{},openId:{}", userId, phoneNo, openId); log.error("微信关联失败:绑定条数<1:[service]:userId:{},phoneNo:{},openId:{}", userId, phoneNo, openId);
throw new WechatRelateUserException("微信关联失败"); throw new WechatRelateUserException("微信关联失败");
} }
WechatEventMsg wechatEventMsg = WechatEventMsg.builder() WechatEventMsg wechatEventMsg = WechatEventMsg.builder()
.userId(userId) .userId(userId)
.openId(openId) .openId(openId)
.build(); .build();
applicationEventPublisher.publishEvent(new WechatBindEvent(this,wechatEventMsg)); applicationEventPublisher.publishEvent(new WechatBindEvent(this, wechatEventMsg));
// Todo : 如果当前openId已关联其他用户,则解绑成功后要注销其登录session -- 考虑后暂时不执行,影响太大 // Todo : 如果当前openId已关联其他用户,则解绑成功后要注销其登录session -- 考虑后暂时不执行,影响太大
log.info("微信关联成功:[service]:userId:{},phoneNo:{},openId:{},dissociate:{},relate:{},Old-WechatUserInfo:{}", userId, phoneNo, openId, dissociate, relate, wechatUserInfo); log.info("微信关联成功:[service]:userId:{},phoneNo:{},openId:{},dissociate:{},relate:{},Old-WechatUserInfo:{}", userId, phoneNo, openId, dissociate, relate, wechatUserInfo);
return relate; return relate;
...@@ -197,7 +197,7 @@ public class WechatServiceImpl implements IWechatService { ...@@ -197,7 +197,7 @@ public class WechatServiceImpl implements IWechatService {
if (!ValidationUtil.validatePhoneNo(phoneNo)) { if (!ValidationUtil.validatePhoneNo(phoneNo)) {
return null; return null;
} }
return weChatUserRepository.findByPhoneNoAndAppName(phoneNo,"xyqb"); return weChatUserRepository.findByPhoneNoAndAppName(phoneNo, "xyqb");
} }
private String getTokenFromWechatServer(String code) { private String getTokenFromWechatServer(String code) {
...@@ -222,30 +222,33 @@ public class WechatServiceImpl implements IWechatService { ...@@ -222,30 +222,33 @@ public class WechatServiceImpl implements IWechatService {
* @param userId - 用户标识 * @param userId - 用户标识
* @return * @return
* @TODO 2021-10-14 修改 findByUserIdAndAppName 为 findFirstByUserIdAndAppNameOrderByCreatedAtDesc, 原因是存在有多个数据情况 * @TODO 2021-10-14 修改 findByUserIdAndAppName 为 findFirstByUserIdAndAppNameOrderByCreatedAtDesc, 原因是存在有多个数据情况
*
*/ */
@Override @Override
public WechatUserInfo queryByUserId(Long userId) { public WechatUserInfo queryByUserId(Long userId) {
return weChatUserRepository.findFirstByUserIdAndAppNameOrderByCreatedAtDesc(userId,"xyqb"); return weChatUserRepository.findFirstByUserIdAndAppNameOrderByCreatedAtDesc(userId, "xyqb");
} }
/** /**
*
* @param userId * @param userId
* @param appName * @param appName
* @return * @return
* @TODO 2021-10-14 修改 findByUserIdAndAppName 为 findFirstByUserIdAndAppNameOrderByCreatedAtDesc, 原因是存在有多个数据情况 * @TODO 2021-10-14 修改 findByUserIdAndAppName 为 findFirstByUserIdAndAppNameOrderByCreatedAtDesc, 原因是存在有多个数据情况
*/ */
public WechatUserInfo queryByUserId(Long userId,String appName){ public WechatUserInfo queryByUserId(Long userId, String appName) {
if(appName==null||"".equals(appName.trim())){ if (appName == null || "".equals(appName.trim())) {
appName = "xyqb"; appName = "xyqb";
} }
return weChatUserRepository.findFirstByUserIdAndAppNameOrderByCreatedAtDesc(userId,appName); return weChatUserRepository.findFirstByUserIdAndAppNameOrderByCreatedAtDesc(userId, appName);
} }
@Override @Override
public int forbiddenUserWeChat(Long userId) { public int forbiddenUserWeChat(Long userId) {
return weChatUserRepository.dissociateByUserIdAndAppName(userId,"xyqb"); return weChatUserRepository.dissociateByUserIdAndAppName(userId, "xyqb");
}
@Override
public int forbiddenXyqbAndWuxiUserByUserId(Long userId) {
return weChatUserRepository.forbiddenXyqbAndWuxiUserByUserId(userId);
} }
} }
package cn.quantgroup.xyqb.util; package cn.quantgroup.xyqb.util;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatter;
...@@ -49,4 +47,15 @@ public class DateUtils { ...@@ -49,4 +47,15 @@ public class DateUtils {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
return (timeStamp - now) / 1000; return (timeStamp - now) / 1000;
} }
/**
* 获取时间差天数
*
* @param bDate begin
* @param eDate end
* @return 时间差天数
*/
public static long dayDiff(Date bDate, Date eDate) {
return ((bDate.getTime() - eDate.getTime()) / (1000 * 3600 * 24));
}
} }
# 销户需求
-- http://confluence.quantgroup.cn/pages/viewpage.action?pageId=61677003
CREATE TABLE `user_deregister_record`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`phone_no` varchar(255) NOT NULL COMMENT '手机号MD5值',
`password` varchar(128) DEFAULT '' NULL COMMENT '密码',
`registered_from` bigint(20) DEFAULT 0 null COMMENT '渠道ID',
`uuid` varchar(64) DEFAULT '' COMMENT 'uuid',
`deregister_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '销户时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`) USING BTREE,
KEY `idx_delete_time` (`deregister_time`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8 COMMENT ='销户记录表';
This diff is collapsed.
This diff is collapsed.
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