Commit d491a5c4 authored by 技术部-任文超's avatar 技术部-任文超

Merge branch 'hotfix/fastlogin' into 'master'

loginFaster~



See merge request !20
parents 2644b447 c5a9aa77
package cn.quantgroup.xyqb.config.event;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.support.TaskUtils;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@Configuration
public class EventConfig {
@Bean
public ApplicationEventMulticaster applicationEventMulticaster(Executor taskExecutor) {
SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster();
simpleApplicationEventMulticaster.setTaskExecutor(taskExecutor);
simpleApplicationEventMulticaster.setErrorHandler(TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER);
return simpleApplicationEventMulticaster;
}
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
poolTaskExecutor.setCorePoolSize(10);
poolTaskExecutor.setMaxPoolSize(50);
poolTaskExecutor.setQueueCapacity(100);
poolTaskExecutor.setThreadNamePrefix("Spring-UserLogin-Event-");
poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
poolTaskExecutor.setRejectedExecutionHandler(new RejectedHandler());
poolTaskExecutor.initialize();
return poolTaskExecutor;
}
public static class RejectedHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
log.error("rejected : {}", r);
}
}
}
package cn.quantgroup.xyqb.config.http; package cn.quantgroup.xyqb.config.http;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.format.FormatterRegistry; import org.springframework.format.FormatterRegistry;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
@Component @Component
public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter { public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {
...@@ -13,4 +20,19 @@ public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter { ...@@ -13,4 +20,19 @@ public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {
registry.addConverterFactory(new IntegerToEnumConverterFactory()); registry.addConverterFactory(new IntegerToEnumConverterFactory());
} }
/**
* 快速校验参数. 第一个出错后面的不用再校验了
* @return
*/
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
.addProperty("hibernate.validator.fail_fast", "true")
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
postProcessor.setValidator(validator);
return postProcessor;
}
} }
\ No newline at end of file
...@@ -15,6 +15,10 @@ import org.springframework.web.bind.annotation.ResponseStatus; ...@@ -15,6 +15,10 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;
/** /**
* Created by Miraculous on 15/7/6. * Created by Miraculous on 15/7/6.
...@@ -92,4 +96,16 @@ public class ExceptionHandlingController implements IBaseController { ...@@ -92,4 +96,16 @@ public class ExceptionHandlingController implements IBaseController {
LOGGER.error("[exception][global_exception]接口异常 URI:{}, registerFrom:{},error={}", uri, registerFrom, e); LOGGER.error("[exception][global_exception]接口异常 URI:{}, registerFrom:{},error={}", uri, registerFrom, e);
return EXCEPTION_RESULT; return EXCEPTION_RESULT;
} }
@ExceptionHandler(ValidationException.class)
public JsonResult validException(ValidationException exception) {
ConstraintViolationException exs = (ConstraintViolationException) exception;
Set<ConstraintViolation<?>> constraintViolations = exs.getConstraintViolations();
if (constraintViolations.isEmpty()) {
LOGGER.error("这里出了个错....", exception.getMessage());
return null;
}
String message = constraintViolations.iterator().next().getMessage();
return JsonResult.buildErrorStateResult(message, null);
}
} }
...@@ -20,6 +20,7 @@ import cn.quantgroup.xyqb.service.user.vo.UserDetailVO; ...@@ -20,6 +20,7 @@ import cn.quantgroup.xyqb.service.user.vo.UserDetailVO;
import cn.quantgroup.xyqb.service.wechat.IWechatService; import cn.quantgroup.xyqb.service.wechat.IWechatService;
import cn.quantgroup.xyqb.util.*; import cn.quantgroup.xyqb.util.*;
import cn.quantgroup.xyqb.util.encrypt.MD5Util; import cn.quantgroup.xyqb.util.encrypt.MD5Util;
import cn.quantgroup.xyqb.validator.ChineseName;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
...@@ -35,9 +36,11 @@ import org.apache.commons.lang3.math.NumberUtils; ...@@ -35,9 +36,11 @@ import org.apache.commons.lang3.math.NumberUtils;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Min;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.text.ParseException; import java.text.ParseException;
...@@ -51,6 +54,7 @@ import java.util.stream.Collectors; ...@@ -51,6 +54,7 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/innerapi") @RequestMapping("/innerapi")
@Validated
public class InnerController implements IBaseController { public class InnerController implements IBaseController {
@Autowired @Autowired
...@@ -89,7 +93,7 @@ public class InnerController implements IBaseController { ...@@ -89,7 +93,7 @@ public class InnerController implements IBaseController {
}; };
@RequestMapping("/user/search/phoneNo") @RequestMapping("/user/search/phoneNo")
@ApiOperation(httpMethod = "POST", value = "根据手机号查询用户信息") @ApiOperation(httpMethod = "GET", value = "根据手机号查询用户信息")
public JsonResult findByPhoneNo(String phoneNo) { public JsonResult findByPhoneNo(String phoneNo) {
User user = userService.findByPhoneInDb(phoneNo); User user = userService.findByPhoneInDb(phoneNo);
if (user == null) { if (user == null) {
...@@ -222,12 +226,15 @@ public class InnerController implements IBaseController { ...@@ -222,12 +226,15 @@ public class InnerController implements IBaseController {
*/ */
@RequestMapping("/user_detail/save") @RequestMapping("/user_detail/save")
@ApiOperation(httpMethod = "POST", value = "填写用户详情") @ApiOperation(httpMethod = "POST", value = "填写用户详情")
public JsonResult saveUserDetail(Long userId, String phoneNo, String name, String idNo, public JsonResult saveUserDetail(@Min(value = 1, message = "用户id为空") @RequestParam Long userId,
String phoneNo,
@ChineseName @RequestParam String name,
String idNo,
String email, String qq) { String email, String qq) {
log.info("保存用户详细信息,[saveUserDetail] userId:{},phoneNo:{},name:{},idNo:{},email:{},qq:{}", userId, phoneNo, name, idNo, email, qq); log.info("保存用户详细信息,[saveUserDetail] userId:{},phoneNo:{},name:{},idNo:{},email:{},qq:{}", userId, phoneNo, name, idNo, email, qq);
//参数验证 //参数验证
if (userId == null || userId == 0L) { if (Objects.isNull(userId)) {
return JsonResult.buildErrorStateResult("用户id为空.", null); return JsonResult.buildErrorStateResult("userId为空.", null);
} }
if (StringUtils.isBlank(phoneNo)) { if (StringUtils.isBlank(phoneNo)) {
return JsonResult.buildErrorStateResult("用户手机号为空.", null); return JsonResult.buildErrorStateResult("用户手机号为空.", null);
...@@ -238,16 +245,9 @@ public class InnerController implements IBaseController { ...@@ -238,16 +245,9 @@ public class InnerController implements IBaseController {
if (StringUtils.isBlank(idNo)) { if (StringUtils.isBlank(idNo)) {
return JsonResult.buildErrorStateResult("用户身份证为空.", null); return JsonResult.buildErrorStateResult("用户身份证为空.", null);
} }
if (!ValidationUtil.validateChinese(name)) { IdCardInfo info = idCardService.getIdCardInfo(idNo);
return JsonResult.buildErrorStateResult("用户姓名错误", null);
}
IdCardInfo info = null;
try {
info = idCardService.getIdCardInfo(idNo);
} catch (ParseException ex) {
log.error("用户身份证号错误, idNo: {}", idNo);
}
if (Objects.isNull(info) || !info.isValid()) { if (Objects.isNull(info) || !info.isValid()) {
log.error("用户身份证号错误,userId:{},idNo: {}", userId, idNo);
return JsonResult.buildErrorStateResult("身份证号码错误", null); return JsonResult.buildErrorStateResult("身份证号码错误", null);
} }
User user = userService.findById(userId); User user = userService.findById(userId);
...@@ -979,20 +979,16 @@ public class InnerController implements IBaseController { ...@@ -979,20 +979,16 @@ public class InnerController implements IBaseController {
String district, String district,
String address, String address,
String contacts, @RequestParam(defaultValue = "0", required = false) Long btRegisterChannelId) { String contacts, @RequestParam(defaultValue = "0", required = false) Long btRegisterChannelId) {
log.info("[/innerapi/user/save_multi]保存用户、联系人、地址信息:registeredFrom:[{}], phoneNo[{}],name[{}],idNo[{}],provinceCode[{}],cityCode[{}],districtCode[{}]," +
"address[{}],contacts[{}]", registeredFrom, phoneNo, name, idNo, provinceCode, cityCode, districtCode, address, contacts);
if (!NumberUtils.isDigits(registeredFrom)) { if (!NumberUtils.isDigits(registeredFrom)) {
return JsonResult.buildErrorStateResult("注册渠道异常.", null); return JsonResult.buildErrorStateResult("注册渠道异常.", null);
} }
if (!ValidationUtil.validatePhoneNo(phoneNo)) { if (!ValidationUtil.validatePhoneNo(phoneNo)) {
return JsonResult.buildErrorStateResult("手机号异常.", null); return JsonResult.buildErrorStateResult("手机号异常.", null);
} }
if (StringUtils.isBlank(name)) { if (StringUtils.isBlank(name)) {
return JsonResult.buildErrorStateResult("用户名异常.", null); return JsonResult.buildErrorStateResult("用户名异常.", null);
} }
boolean isIdCard = true; boolean isIdCard;
try { try {
isIdCard = idCardService.isIdCardValid(idNo); isIdCard = idCardService.isIdCardValid(idNo);
} catch (ParseException e) { } catch (ParseException e) {
...@@ -1002,7 +998,6 @@ public class InnerController implements IBaseController { ...@@ -1002,7 +998,6 @@ public class InnerController implements IBaseController {
return JsonResult.buildErrorStateResult("用户身份证号异常.", null); return JsonResult.buildErrorStateResult("用户身份证号异常.", null);
} }
Address addressObj = null; Address addressObj = null;
//地址信息,同时存在provinceCode和address时才校验地址信息 //地址信息,同时存在provinceCode和address时才校验地址信息
if (StringUtils.isNotEmpty(provinceCode) && StringUtils.isNotEmpty(address)) { if (StringUtils.isNotEmpty(provinceCode) && StringUtils.isNotEmpty(address)) {
...@@ -1038,7 +1033,6 @@ public class InnerController implements IBaseController { ...@@ -1038,7 +1033,6 @@ public class InnerController implements IBaseController {
addressObj.setAddress(address); addressObj.setAddress(address);
} }
channelId = MoreObjects.firstNonNull(channelId, "-1"); channelId = MoreObjects.firstNonNull(channelId, "-1");
// 验证用户是否已存在 // 验证用户是否已存在
User user = userService.findByPhoneInDb(phoneNo); User user = userService.findByPhoneInDb(phoneNo);
...@@ -1046,29 +1040,25 @@ public class InnerController implements IBaseController { ...@@ -1046,29 +1040,25 @@ public class InnerController implements IBaseController {
return JsonResult.buildErrorStateResult("用户已存在,手机号被占用", null); return JsonResult.buildErrorStateResult("用户已存在,手机号被占用", null);
} }
user = userRegisterService.register(Long.valueOf(registeredFrom), Long.valueOf(channelId), phoneNo, name, idNo, addressObj, contacts, btRegisterChannelId); List<Contact> contactList = null;
// 目前对空白字符串和null值容错,因是api调用,不考虑对非法格式容错(会阻断注册)
if (StringUtils.isNotBlank(contacts)) {
contactList = JSONObject.parseObject(contacts, new TypeReference<List<Contact>>(){});
for (Contact contact : contactList) {
contact.setRelation(contact.getRelation() == null ? Relation.OTHER : contact.getRelation());
Tuple<String, Boolean> stringBooleanTuple = contact.validAndResult();
if (!stringBooleanTuple.getValue()) {
return JsonResult.buildErrorStateResult(stringBooleanTuple.getKey(), null);
}
}
}
user = userRegisterService.register(Long.valueOf(registeredFrom), Long.valueOf(channelId), phoneNo, name, idNo, addressObj, contacts, contactList, btRegisterChannelId);
UserRet userRet = new UserRet(user); UserRet userRet = new UserRet(user);
return JsonResult.buildSuccessResult(null, userRet); return JsonResult.buildSuccessResult(null, userRet);
} }
@RequestMapping("/user/register")
@ApiOperation(value = "用户注册", httpMethod = "POST")
public JsonResult register(String phoneNo, String password, Long channelId) {
if (!ValidationUtil.validatePhoneNo(phoneNo)) {
return JsonResult.buildErrorStateResult("手机号不正确", null);
}
log.info("[/innerapi/user/register]channelId={},ip={}", channelId, getIp());
User user = userService.findByPhoneInDb(phoneNo);
if (user == null) {
user = userRegisterService.register(phoneNo, StringUtils.defaultString(password, ""), channelId);
}
if (user == null) {
return JsonResult.buildErrorStateResult("注册失败", null);
}
return JsonResult.buildSuccessResult(null, new UserRet(user));
}
//根据日期时间段查询新注册用户信息并返回 //根据日期时间段查询新注册用户信息并返回
@RequestMapping("/contract/queryRegisterUsers") @RequestMapping("/contract/queryRegisterUsers")
@ApiOperation(value = "根据日期时间段查询新注册用户信息并返回", httpMethod = "POST") @ApiOperation(value = "根据日期时间段查询新注册用户信息并返回", httpMethod = "POST")
......
...@@ -3,33 +3,35 @@ package cn.quantgroup.xyqb.controller.external.user; ...@@ -3,33 +3,35 @@ package cn.quantgroup.xyqb.controller.external.user;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail; import cn.quantgroup.xyqb.entity.UserDetail;
import cn.quantgroup.xyqb.model.IdCardInfo; import cn.quantgroup.xyqb.model.IdCardInfo;
import cn.quantgroup.xyqb.model.IdType;
import cn.quantgroup.xyqb.model.JsonResult; import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.UserModel; import cn.quantgroup.xyqb.model.UserModel;
import cn.quantgroup.xyqb.service.auth.IIdCardService; import cn.quantgroup.xyqb.service.auth.IIdCardService;
import cn.quantgroup.xyqb.service.user.IUserDetailService; import cn.quantgroup.xyqb.service.user.IUserDetailService;
import cn.quantgroup.xyqb.service.user.IUserService; import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.util.ValidationUtil; import cn.quantgroup.xyqb.util.ValidationUtil;
import cn.quantgroup.xyqb.validator.ChineseName;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException; import java.sql.Timestamp;
import java.util.Objects; import java.util.Objects;
/** /**
* 同步用户数据,第三方模块访问时 * 同步用户数据,第三方模块访问时
* Created by Miraculous on 15/12/29. * Created by Miraculous on 15/12/29.
*/ */
@Slf4j
@RestController @RestController
@RequestMapping("/api/sync") @RequestMapping("/api/sync")
public class SyncUserController { public class SyncUserController {
private static final Logger LOGGER = LoggerFactory.getLogger(SyncUserController.class); private static final String KEY = "abc1234";
@Autowired @Autowired
private IUserService userService; private IUserService userService;
@Autowired @Autowired
...@@ -38,66 +40,56 @@ public class SyncUserController { ...@@ -38,66 +40,56 @@ public class SyncUserController {
private IIdCardService idCardService; private IIdCardService idCardService;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
@RequestMapping("/user")
public JsonResult fetchUser(String key, String phoneNo) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key)) {
return JsonResult.buildErrorStateResult(null, null);
}
if (StringUtils.isEmpty(phoneNo)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByPhoneInDb(phoneNo);
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
}
UserDetail detail = userDetailService.findByUserId(user.getId());
if (null == detail) {
// FIXME: 16/4/15 前期不对身份证强制要求.后期对修改
// return JsonResult.buildErrorStateResult(null, null);
}
UserModel userModel = new UserModel(user, detail);
return JsonResult.buildSuccessResult(null, userModel);
}
@RequestMapping("/save_detail") @RequestMapping("/save_detail")
public JsonResult saveUserDetail(String key, UserDetail userDetail) { @ApiOperation(httpMethod = "POST", value = "保存/更新用户实名信息")
if (StringUtils.isEmpty(key) || !"abc1234".equals(key) || Objects.isNull(userDetail) || StringUtils.isBlank(userDetail.getPhoneNo())) { public JsonResult saveUserDetail(String key, String phoneNo, String idNo,
@ChineseName @RequestParam String name) {
if (!Objects.equals(KEY, key)) {
return JsonResult.buildErrorStateResult(null, null); return JsonResult.buildErrorStateResult(null, null);
} }
if (!ValidationUtil.validateChinese(userDetail.getName())) { if (!ValidationUtil.validatePhoneNo(phoneNo)) {
return JsonResult.buildErrorStateResult("姓名错误", null); log.error("手机号错误,phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("手机号错误", phoneNo);
} }
IdCardInfo info = null; if (!ValidationUtil.validateChinese(name)) {
try { log.error("姓名错误,name:{}", name);
info = idCardService.getIdCardInfo(userDetail.getIdNo()); return JsonResult.buildErrorStateResult("姓名错误", name);
} catch (ParseException ex) {
LOGGER.error("身份证号错误, idNo: {}", userDetail.getIdNo());
return JsonResult.buildErrorStateResult("身份证号码错误", null);
} }
IdCardInfo info = idCardService.getIdCardInfo(idNo);
if (Objects.isNull(info) || !info.isValid()) { if (Objects.isNull(info) || !info.isValid()) {
return JsonResult.buildErrorStateResult("身份证号码错误", null); log.error("身份证号错误,idNo:{}", idNo);
return JsonResult.buildErrorStateResult("身份证号码错误", idNo);
} }
String phoneNo = userDetail.getPhoneNo();
User user = userService.findByPhoneWithCache(phoneNo); User user = userService.findByPhoneWithCache(phoneNo);
if (Objects.isNull(user)) { if (Objects.isNull(user)) {
return JsonResult.buildErrorStateResult(null, null); log.error("用户不存在,phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("用户不存在", phoneNo);
}
Timestamp now = new Timestamp(System.currentTimeMillis());
/* 保存或更新 */
UserDetail userDetail = userDetailService.findByUserId(user.getId());
if (Objects.isNull(userDetail)) {
userDetail = new UserDetail();
userDetail.setCreatedAt(now);
} }
userDetail.setUserId(user.getId()); userDetail.setUserId(user.getId());
/* userDetail.setIdNo(idNo);
* 如果已存在记录,则更新 userDetail.setPhoneNo(phoneNo);
*/ userDetail.setUpdatedAt(now);
UserDetail theUserDetail = userDetailService.findByUserId(user.getId()); userDetail.setName(name);
if (Objects.isNull(theUserDetail)) { userDetail.setGender(info.getGender());
theUserDetail = userDetailService.findByPhoneNo(phoneNo); userDetail.setIdType(IdType.ID_CARD);
// 按手机号查出记录,如果userId非空,说明是存疑数据或是其他用户的信息,停止修改操作,返回失败 userDetail.setIsAuthenticated(false);
if (Objects.nonNull(theUserDetail) && Objects.nonNull(theUserDetail.getUserId())) { try {
return JsonResult.buildErrorStateResult("手机号已使用.", null); userDetailService.saveUserDetail(userDetail);
} } catch (DataIntegrityViolationException ex) {
return JsonResult.buildSuccessResult("", null);
} }
/*
* 如果已存在记录,则更新
*/
UserDetail theUserDetail = userDetailService.findByUserId(user.getId());
if (Objects.isNull(theUserDetail)) { if (Objects.isNull(theUserDetail)) {
userDetail.setId(null); userDetail.setId(null);
} else { } else {
...@@ -107,9 +99,24 @@ public class SyncUserController { ...@@ -107,9 +99,24 @@ public class SyncUserController {
return JsonResult.buildSuccessResult(null, null); return JsonResult.buildSuccessResult(null, null);
} }
@RequestMapping("/user")
@ApiOperation(httpMethod = "POST", value = "查询用户详情")
public JsonResult fetchUser(String key, String phoneNo) {
if (!Objects.equals(KEY, key) || !ValidationUtil.validatePhoneNo(phoneNo)) {
return JsonResult.buildErrorStateResult(null, null);
}
User user = userService.findByPhoneInDb(phoneNo);
if (Objects.isNull(user)) {
return JsonResult.buildErrorStateResult(null, null);
}
UserDetail detail = userDetailService.findByUserId(user.getId());
UserModel userModel = new UserModel(user, detail);
return JsonResult.buildSuccessResult(null, userModel);
}
@RequestMapping("/user_uuid") @RequestMapping("/user_uuid")
public JsonResult fetchUserByUuid(String key, String uuid) { public JsonResult fetchUserByUuid(String key, String uuid) {
if (StringUtils.isEmpty(key) || !"abc1234".equals(key)) { if (StringUtils.isEmpty(key) || !KEY.equals(key)) {
return JsonResult.buildErrorStateResult(null, null); return JsonResult.buildErrorStateResult(null, null);
} }
if (StringUtils.isEmpty(uuid)) { if (StringUtils.isEmpty(uuid)) {
...@@ -120,10 +127,6 @@ public class SyncUserController { ...@@ -120,10 +127,6 @@ public class SyncUserController {
return JsonResult.buildErrorStateResult(null, null); return JsonResult.buildErrorStateResult(null, null);
} }
UserDetail detail = userDetailService.findByUserId(user.getId()); UserDetail detail = userDetailService.findByUserId(user.getId());
if (null == detail) {
// FIXME: 16/4/15 前期不对身份证强制要求.后期对修改
// return JsonResult.buildErrorStateResult(null, null);
}
UserModel userModel = new UserModel(user, detail); UserModel userModel = new UserModel(user, detail);
return JsonResult.buildSuccessResult(null, userModel); return JsonResult.buildSuccessResult(null, userModel);
} }
......
...@@ -9,86 +9,82 @@ import cn.quantgroup.xyqb.model.JsonResult; ...@@ -9,86 +9,82 @@ import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.service.auth.IIdCardService; import cn.quantgroup.xyqb.service.auth.IIdCardService;
import cn.quantgroup.xyqb.service.user.IUserDetailService; import cn.quantgroup.xyqb.service.user.IUserDetailService;
import cn.quantgroup.xyqb.util.ValidationUtil; import cn.quantgroup.xyqb.util.ValidationUtil;
import org.slf4j.Logger; import cn.quantgroup.xyqb.validator.ChineseName;
import org.slf4j.LoggerFactory; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.text.ParseException;
import java.util.Objects; import java.util.Objects;
/** /**
* Created by Miraculous on 2017/1/3. * Created by Miraculous on 2017/1/3.
*/ */
@Slf4j
@RestController @RestController
@RequestMapping("/user_detail") @RequestMapping("/user_detail")
@Validated
public class UserDetailController implements IBaseController { public class UserDetailController implements IBaseController {
private static final Logger LOGGER = LoggerFactory.getLogger(UserDetailController.class);
@Autowired @Autowired
private IUserDetailService userDetailService; private IUserDetailService userDetailService;
@Autowired @Autowired
private IIdCardService idCardService; private IIdCardService idCardService;
private static final Long MAX_COUNTER = 1L;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
/**
* 保存/更新用户实名信息
* 注:
* 本接口会验证用户登录状态,仅用于用户个人补全实名信息操作
* 产品逻辑是不允许用户重复设置实名信息的,但历史存在导流数据创建不完整实名信息的场景(可理解为和渠道有关)
* 故此本处保留修改逻辑,仍依赖业务端控制产品行为
*
* @param idNo
* @param name
* @return
*/
@RequestMapping("/save") @RequestMapping("/save")
public JsonResult saveUserdetail(String idNo, String name) { @ApiOperation(httpMethod = "POST", value = "保存/更新用户实名信息")
public JsonResult saveUserdetail(String idNo,
@ChineseName @RequestParam String name) {
if (!ValidationUtil.validateChinese(name)) {
log.error("姓名错误,name:{}", name);
return JsonResult.buildErrorStateResult("姓名错误", null);
}
User user = getCurrentUserFromRedis();
if (user == null) {
return JsonResult.buildErrorStateResult("系统错误", null);
}
IdCardInfo info = idCardService.getIdCardInfo(idNo);
if (info == null || !info.isValid()) {
log.error("身份证号错误,userId:{}, idNo: {}", user.getId(), idNo);
return JsonResult.buildErrorStateResult("身份证号码错误", null);
}
Timestamp now = new Timestamp(System.currentTimeMillis());
/* 保存或更新 */
UserDetail userDetail = userDetailService.findByUserId(user.getId());
if (Objects.isNull(userDetail)) {
userDetail = new UserDetail();
userDetail.setCreatedAt(now);
}
userDetail.setIdNo(idNo);
userDetail.setPhoneNo(user.getPhoneNo());
userDetail.setUserId(user.getId());
userDetail.setUpdatedAt(now);
userDetail.setName(name);
userDetail.setGender(info.getGender());
userDetail.setIdType(IdType.ID_CARD);
userDetail.setIsAuthenticated(false);
try { try {
if (!ValidationUtil.validateChinese(name)) { userDetailService.saveUserDetail(userDetail);
return JsonResult.buildErrorStateResult("姓名错误", null); } catch (DataIntegrityViolationException ex) {
}
IdCardInfo info = idCardService.getIdCardInfo(idNo);
if (!info.isValid()) {
return JsonResult.buildErrorStateResult("身份证号码错误", null);
}
User user = getCurrentUserFromRedis();
if (user == null) {
return JsonResult.buildErrorStateResult("系统错误", null);
}
Timestamp now = new Timestamp(System.currentTimeMillis());
/*
* 如果已存在记录,则更新
*/
UserDetail userDetail = userDetailService.findByUserId(user.getId());
if (Objects.isNull(userDetail)) {
userDetail = userDetailService.findByPhoneNo(user.getPhoneNo());
// 按手机号查出记录,如果userId非空,说明是存疑数据或是其他用户的信息,停止修改操作,返回失败
if (Objects.nonNull(userDetail) && Objects.nonNull(userDetail.getUserId())) {
return JsonResult.buildErrorStateResult("手机号已使用.", null);
}
}
if (Objects.isNull(userDetail)) {
userDetail = new UserDetail();
userDetail.setCreatedAt(now);
}
userDetail.setIdNo(idNo);
userDetail.setPhoneNo(user.getPhoneNo());
userDetail.setUserId(user.getId());
userDetail.setUpdatedAt(now);
userDetail.setName(name);
userDetail.setGender(info.getGender());
userDetail.setEmail("");
userDetail.setIdType(IdType.ID_CARD);
userDetail.setIsAuthenticated(false);
userDetail.setQq("");
try {
userDetailService.saveUserDetail(userDetail);
} catch (DataIntegrityViolationException ex) {
return JsonResult.buildSuccessResult("", null);
}
return JsonResult.buildSuccessResult("", null); return JsonResult.buildSuccessResult("", null);
} catch (ParseException ex) {
LOGGER.error("身份证号错误, idNo: {}", idNo);
return JsonResult.buildErrorStateResult("身份证号码错误", null);
} }
return JsonResult.buildSuccessResult("", null);
} }
} }
package cn.quantgroup.xyqb.entity; package cn.quantgroup.xyqb.entity;
import cn.quantgroup.user.enums.Relation; import cn.quantgroup.user.enums.Relation;
import cn.quantgroup.xyqb.model.Tuple;
import cn.quantgroup.xyqb.util.ValidationUtil; import cn.quantgroup.xyqb.util.ValidationUtil;
import lombok.Data; import lombok.Data;
...@@ -43,4 +44,16 @@ public class Contact implements Serializable { ...@@ -43,4 +44,16 @@ public class Contact implements Serializable {
return (ValidationUtil.validatePhoneNo(this.phoneNo) && ValidationUtil.validateChinese(this.name)); return (ValidationUtil.validatePhoneNo(this.phoneNo) && ValidationUtil.validateChinese(this.name));
} }
public Tuple<String, Boolean> validAndResult() {
boolean phoneValidRes = ValidationUtil.validatePhoneNo(this.phoneNo);
if (!phoneValidRes) {
return new Tuple<>("手机号错误", false);
}
boolean nameValid = ValidationUtil.validateChinese(this.name);
if (!nameValid) {
return new Tuple<>("姓名错误", false);
}
return new Tuple<>("", true);
}
} }
package cn.quantgroup.xyqb.entity; package cn.quantgroup.xyqb.entity;
import cn.quantgroup.motan.retbean.XUser;
import cn.quantgroup.xyqb.config.http.Timestamp2LongConverter; import cn.quantgroup.xyqb.config.http.Timestamp2LongConverter;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import lombok.Getter; import lombok.Getter;
...@@ -20,6 +19,7 @@ import java.sql.Timestamp; ...@@ -20,6 +19,7 @@ import java.sql.Timestamp;
@Entity @Entity
@Table(name = "user", uniqueConstraints = @UniqueConstraint(columnNames = "phone_no")) @Table(name = "user", uniqueConstraints = @UniqueConstraint(columnNames = "phone_no"))
public class User implements Serializable { public class User implements Serializable {
private static final long serialVersionUID = -1L;
@Id @Id
@Column(name = "id") @Column(name = "id")
...@@ -54,21 +54,6 @@ public class User implements Serializable { ...@@ -54,21 +54,6 @@ public class User implements Serializable {
@Column(name = "updated_at") @Column(name = "updated_at")
@JSONField(serializeUsing = Timestamp2LongConverter.class) @JSONField(serializeUsing = Timestamp2LongConverter.class)
private Timestamp updatedAt; private Timestamp updatedAt;
private static final long serialVersionUID = -1L;
public XUser toXUser() {
XUser xUser = new XUser();
xUser.setId(this.getId());
xUser.setPassword(this.getPassword());
xUser.setRegisteredFrom(this.getRegisteredFrom());
xUser.setUuid(this.getUuid());
xUser.setEnable(this.getEnable());
xUser.setPhoneNo(this.getPhoneNo());
xUser.setUpdatedAt(this.getUpdatedAt());
xUser.setCreatedAt(this.getCreatedAt());
return xUser;
}
} }
package cn.quantgroup.xyqb.entity; package cn.quantgroup.xyqb.entity;
import cn.quantgroup.xyqb.util.EmojiUtil;
import lombok.Data; import lombok.Data;
import org.springframework.beans.BeanUtils;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
...@@ -44,4 +46,16 @@ public class WechatUserInfo implements Serializable { ...@@ -44,4 +46,16 @@ public class WechatUserInfo implements Serializable {
private Timestamp createdAt = new Timestamp(System.currentTimeMillis()); private Timestamp createdAt = new Timestamp(System.currentTimeMillis());
@Column(name = "updated_at") @Column(name = "updated_at")
private Timestamp updatedAt = new Timestamp(System.currentTimeMillis()); private Timestamp updatedAt = new Timestamp(System.currentTimeMillis());
public WechatUserInfo convertEmoji() {
WechatUserInfo wechatUserInfo = new WechatUserInfo();
BeanUtils.copyProperties(this, wechatUserInfo);
wechatUserInfo.setNickName(EmojiUtil.filterUnicode4(this.getNickName()));
wechatUserInfo.setProvince(EmojiUtil.filterUnicode4(this.getProvince()));
wechatUserInfo.setCity(EmojiUtil.filterUnicode4(this.getCity()));
wechatUserInfo.setCountry(EmojiUtil.filterUnicode4(this.getCountry()));
return wechatUserInfo;
}
} }
package cn.quantgroup.xyqb.event;
import cn.quantgroup.xyqb.entity.Address;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.repository.IAddressRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
/**
* 注册成功后保存地址
*
* @author ag
*/
@Component
public class AddressRegisteredEventListener implements ApplicationListener<RegisterEvent> {
@Autowired
private IAddressRepository addressRepository;
@Override
public void onApplicationEvent(RegisterEvent event) {
UserRegisterParam userRegisterParam = event.getUserRegisterParam();
Address address = userRegisterParam.getAddress();
if (address == null) {
return;
}
User user = userRegisterParam.getUser();
address.setUserId(user.getId());
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
address.setCreatedAt(currentTime);
address.setUpdateAt(currentTime);
addressRepository.save(address);
}
}
package cn.quantgroup.xyqb.event;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserBtRegister;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.service.user.IUserBtRegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
import java.util.Objects;
@Component
public class BtRegisteredEventListener implements ApplicationListener<RegisterEvent> {
@Autowired
private IUserBtRegisterService userBtRegisterService;
@Override
public void onApplicationEvent(RegisterEvent event) {
UserRegisterParam userRegisterParam = event.getUserRegisterParam();
Long channelId = userRegisterParam.getChannelId();
User user = userRegisterParam.getUser();
Long btRegisterChannelId = userRegisterParam.getBtRegisterChannelId();
if (Objects.isNull(user) || !Objects.equals(channelId, Constants.Channel.BAITIAO)) {
return;
}
UserBtRegister userBtRegister = new UserBtRegister();
userBtRegister.setUserId(user.getId());
if (null == btRegisterChannelId) {
userBtRegister.setRegisterBtMerchantId(0L);
} else {
userBtRegister.setRegisterBtMerchantId(btRegisterChannelId);
}
userBtRegister.setIsActive(true);
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
userBtRegister.setCreatedAt(currentTime);
userBtRegister.setUpdatedAt(currentTime);
userBtRegisterService.save(userBtRegister);
}
}
package cn.quantgroup.xyqb.event;
import cn.quantgroup.xyqb.entity.Contact;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.repository.IContactRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
* 注册成功后, 保存联系人
*
* @author ag
*/
@Component
public class ContactRegisteredEventListener implements ApplicationListener<RegisterEvent> {
@Autowired
private IContactRepository contactRepository;
@Override
public void onApplicationEvent(RegisterEvent event) {
UserRegisterParam userRegisterParam = event.getUserRegisterParam();
List<Contact> contactList = userRegisterParam.getContactList();
User user = userRegisterParam.getUser();
if (CollectionUtils.isEmpty(contactList)) {
return;
}
contactList.forEach(contact -> contact.setUserId(user.getId()));
contactRepository.save(contactList);
}
}
package cn.quantgroup.xyqb.event;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail;
import cn.quantgroup.xyqb.model.IdCardInfo;
import cn.quantgroup.xyqb.model.IdType;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.service.auth.IIdCardService;
import cn.quantgroup.xyqb.service.user.IUserDetailService;
import cn.quantgroup.xyqb.util.ValidationUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
@Slf4j
@Component
public class DetailRegisteredEventListener implements ApplicationListener<RegisterEvent> {
@Autowired
private IIdCardService idCardService;
@Autowired
private IUserDetailService userDetailService;
@Override
public void onApplicationEvent(RegisterEvent event) {
UserRegisterParam userRegisterParam = event.getUserRegisterParam();
User user = userRegisterParam.getUser();
if (StringUtils.isAnyBlank(userRegisterParam.getIdNo(), userRegisterParam.getName()) ||
!ValidationUtil.validateChinese(userRegisterParam.getName())) {
return;
}
String phoneNo = userRegisterParam.getPhoneNo();
String name = userRegisterParam.getName();
String idNo = userRegisterParam.getIdNo();
IdCardInfo cardInfo = idCardService.getIdCardInfo(idNo);
if (cardInfo == null || !cardInfo.isValid()) {
log.info("用户身份证号验证失败,userId:{},idNo:{}", user.getId(), idNo);
return;
}
UserDetail userDetail = new UserDetail();
userDetail.setIdNo(cardInfo.getIdNo());
userDetail.setPhoneNo(phoneNo);
userDetail.setName(name);
userDetail.setIdType(IdType.ID_CARD);
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
userDetail.setCreatedAt(currentTime);
userDetail.setUpdatedAt(currentTime);
userDetail.setUserId(user.getId());
userDetail.setGender(cardInfo.getGender());
userDetailService.saveUserDetail(userDetail);
}
}
package cn.quantgroup.xyqb.event;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.exception.PushUserToLkbException;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.service.user.ILkbUserService;
import cn.quantgroup.xyqb.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 注册成功之后lkb
*
* @author ag
*/
@Slf4j
@Component
public class LkbRegisteredEventListener implements ApplicationListener<RegisterEvent> {
@Autowired
private ILkbUserService lkbUserService;
//todo 这里重试机制补齐
@Override
public void onApplicationEvent(RegisterEvent event) {
UserRegisterParam userRegisterParam = event.getUserRegisterParam();
User user = userRegisterParam.getUser();
String uuid = user.getUuid();
boolean pushResult = lkbUserService.pushUser(uuid, userRegisterParam.getPhoneNo(),
userRegisterParam.getName(), userRegisterParam.getIdNo());
if (!pushResult) {
log.error("[userRegisterHandler][baseUserRegisterHandler]同步用户至Lkb出错,userRegisterParam:{}", JsonUtil.toJson(userRegisterParam));
throw new PushUserToLkbException("同步用户至Lkb出错");
}
}
}
package cn.quantgroup.xyqb.event;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.util.MqUtils;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 发mq, 目前只有数据可视化分析系统需要这个
*
* @author ag
*/
@Component
public class MQRegisteredEventListener implements ApplicationListener<RegisterEvent> {
@Override
public void onApplicationEvent(RegisterEvent event) {
UserRegisterParam userRegisterParam = event.getUserRegisterParam();
if (!userRegisterParam.isSendSuccessMq()) {
return;
}
Long channelId = userRegisterParam.getChannelId();
String dimension = userRegisterParam.getDimension();
User user = userRegisterParam.getUser();
if (user != null) {
MqUtils.sendRegisterMessage(channelId, dimension, user);
}
}
}
package cn.quantgroup.xyqb.event;
import cn.quantgroup.xyqb.model.UserRegisterParam;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;
/**
* 注册成功发送事件
*
* @author ag
*/
@Getter
@Setter
public class RegisterEvent extends ApplicationEvent {
private UserRegisterParam userRegisterParam;
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public RegisterEvent(Object source) {
super(source);
}
public RegisterEvent(Object source, UserRegisterParam userRegisterParam) {
super(source);
this.userRegisterParam = userRegisterParam;
}
}
package cn.quantgroup.xyqb.model; package cn.quantgroup.xyqb.model;
import cn.quantgroup.xyqb.entity.Address; import cn.quantgroup.xyqb.entity.Address;
import cn.quantgroup.xyqb.entity.Contact;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.List;
/** /**
* Created by liqing on 2017/12/4 0004. * Created by liqing on 2017/12/4 0004.
*/ */
...@@ -30,8 +33,11 @@ public class UserRegisterParam { ...@@ -30,8 +33,11 @@ public class UserRegisterParam {
private Address address; // 地址 private Address address; // 地址
private String contacts; // 联系人 private String contacts; // 联系人
private User user; // 注册生成的用户,也是返回结果 private User user; // 注册生成的用户,也是返回结果
/** ======数据部分结束====== */
private List<Contact> contactList;
/**
* ======数据部分结束======
*/
/** /**
* ======流程控制部分开始====== * ======流程控制部分开始======
*/ */
......
...@@ -11,7 +11,7 @@ public interface IIdCardService { ...@@ -11,7 +11,7 @@ public interface IIdCardService {
boolean isIdCardValid(String idCard) throws ParseException; boolean isIdCardValid(String idCard) throws ParseException;
IdCardInfo getIdCardInfo(String idCardStr) throws ParseException; IdCardInfo getIdCardInfo(String idCardStr);
// 当身份证不合法,直接抛出异常。 // 当身份证不合法,直接抛出异常。
IdCardInfo getIdCardInfoWithExceptions(String idCardStr) throws ParseException; IdCardInfo getIdCardInfoWithExceptions(String idCardStr) throws ParseException;
......
...@@ -4,6 +4,7 @@ import cn.quantgroup.xyqb.exception.IdCardException; ...@@ -4,6 +4,7 @@ import cn.quantgroup.xyqb.exception.IdCardException;
import cn.quantgroup.xyqb.model.Gender; import cn.quantgroup.xyqb.model.Gender;
import cn.quantgroup.xyqb.model.IdCardInfo; import cn.quantgroup.xyqb.model.IdCardInfo;
import cn.quantgroup.xyqb.service.auth.IIdCardService; import cn.quantgroup.xyqb.service.auth.IIdCardService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -17,6 +18,7 @@ import java.util.regex.Pattern; ...@@ -17,6 +18,7 @@ import java.util.regex.Pattern;
/** /**
* Created by Miraculous on 15/7/10. * Created by Miraculous on 15/7/10.
*/ */
@Slf4j
@Service @Service
public class IdCardServiceImpl implements IIdCardService { public class IdCardServiceImpl implements IIdCardService {
...@@ -125,7 +127,7 @@ public class IdCardServiceImpl implements IIdCardService { ...@@ -125,7 +127,7 @@ public class IdCardServiceImpl implements IIdCardService {
} }
@Override @Override
public IdCardInfo getIdCardInfo(String idCardStr) throws ParseException { public IdCardInfo getIdCardInfo(String idCardStr){
IdCardInfo cardInfo = new IdCardInfo(); IdCardInfo cardInfo = new IdCardInfo();
cardInfo.setIsValid(false); cardInfo.setIsValid(false);
if (idCardStr == null) { if (idCardStr == null) {
...@@ -157,7 +159,15 @@ public class IdCardServiceImpl implements IIdCardService { ...@@ -157,7 +159,15 @@ public class IdCardServiceImpl implements IIdCardService {
return cardInfo; return cardInfo;
} }
GregorianCalendar gc = new GregorianCalendar(); GregorianCalendar gc = new GregorianCalendar();
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr); Date date;
try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
} catch (ParseException e) {
//这里根本不会出错好么.万一哪个脑抽改了上面的, 就出错了
log.error("解析日期异常...", e);
return null;
}
if (gc.get(Calendar.YEAR) - year > 150 || gc.getTime().getTime() - date.getTime() < 0) { if (gc.get(Calendar.YEAR) - year > 150 || gc.getTime().getTime() - date.getTime() < 0) {
return cardInfo; return cardInfo;
} }
......
package cn.quantgroup.xyqb.service.register; package cn.quantgroup.xyqb.service.register;
import cn.quantgroup.xyqb.entity.Address; import cn.quantgroup.xyqb.entity.Address;
import cn.quantgroup.xyqb.entity.Contact;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.UserRegisterParam; import cn.quantgroup.xyqb.model.UserRegisterParam;
import java.util.List;
/** /**
* Created by liqing on 2017/12/4 0004. * @author liqing
* @date 2017/12/4 0004
*/ */
public interface IUserRegisterService { public interface IUserRegisterService {
...@@ -41,16 +45,6 @@ public interface IUserRegisterService { ...@@ -41,16 +45,6 @@ public interface IUserRegisterService {
*/ */
User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId); User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId, Long btRegisterChannelId);
/**
* 替换InnerController里的userService.registerAndReturn
* /innerapi/user/register
*
* @param phoneNo
* @param password
* @param registerFrom
* @return
*/
User register(String phoneNo, String password, Long registerFrom);
/** /**
* 替换UserController.register里的userService.register * 替换UserController.register里的userService.register
...@@ -89,18 +83,7 @@ public interface IUserRegisterService { ...@@ -89,18 +83,7 @@ public interface IUserRegisterService {
* @author jinsong.zhu 2018年05月16日14:22:13 * @author jinsong.zhu 2018年05月16日14:22:13
* 处理对address和contact的非必要兼容 * 处理对address和contact的非必要兼容
*/ */
User register(Long registeredFrom, Long channelId, String phoneNo, String name, String idNo, Address addressObj, String contacts, Long btRegisterChannelId); User register(Long registeredFrom, Long channelId, String phoneNo, String name, String idNo, Address addressObj, String contacts, List<Contact> contactList, Long btRegisterChannelId);
/**
* 替换MotanUserServiceImpl.appLoginAndFetchLoginInfo和MotanUserServiceImpl.appLogin里的register
*
* @param registerFrom
* @param phoneNo
* @param idNo
* @param name
* @param channelId
* @return
*/
User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId);
} }
package cn.quantgroup.xyqb.service.register.impl; package cn.quantgroup.xyqb.service.register.impl;
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.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.event.RegisterEvent;
import cn.quantgroup.xyqb.model.UserRegisterParam; import cn.quantgroup.xyqb.model.UserRegisterParam;
import cn.quantgroup.xyqb.service.register.AbstractUserRegisterService; import cn.quantgroup.xyqb.service.register.AbstractUserRegisterService;
import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.util.PasswordUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/** /**
* Created by liqing on 2017/12/4 0004. * @author liqing
* @date 2017/12/4 0004
*/ */
@Service("userRegisterService") @Service("userRegisterService")
@Slf4j @Slf4j
public class UserRegisterServiceImpl extends AbstractUserRegisterService { public class UserRegisterServiceImpl extends AbstractUserRegisterService {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Autowired
private IUserService userService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public User registerDefault(UserRegisterParam userRegisterParam) { public User registerDefault(UserRegisterParam userRegisterParam) {
...@@ -36,20 +56,42 @@ public class UserRegisterServiceImpl extends AbstractUserRegisterService { ...@@ -36,20 +56,42 @@ public class UserRegisterServiceImpl extends AbstractUserRegisterService {
.generateRandomPwd(true).sendSuccessSms(true).sendAppSms(true) .generateRandomPwd(true).sendSuccessSms(true).sendAppSms(true)
.sendSuccessMq(true) .sendSuccessMq(true)
.build(); .build();
return registerDefault(userRegisterParam); User user = saveUser(userRegisterParam);
applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
return user;
} }
@Transactional(rollbackFor = Exception.class) private User saveUser(UserRegisterParam userRegisterParam) {
@Override String uuid = UUID.randomUUID().toString();
public User register(String phoneNo, String password, Long registerFrom) { User user = new User();
UserRegisterParam userRegisterParam = UserRegisterParam.builder() user.setUuid(uuid);
.registerFrom(registerFrom).phoneNo(phoneNo).password(password) user.setEnable(true);
.generateRandomPwd(false).sendSuccessSms(true).sendAppSms(true) user.setPhoneNo(userRegisterParam.getPhoneNo());
.sendSuccessMq(true) Long registerFrom = userRegisterParam.getRegisterFrom();
.build(); if (Objects.isNull(registerFrom)) {
return registerDefault(userRegisterParam); registerFrom = 1L;
}
Long channelId = userRegisterParam.getChannelId();
if (Objects.equals(channelId, 222L)) {
user.setRegisteredFrom(channelId);
} else {
user.setRegisteredFrom(registerFrom);
}
String password = StringUtils.defaultString(userRegisterParam.getPassword(), "");
// 如果需要生成随机密码
if (userRegisterParam.isGenerateRandomPwd()) {
password = PasswordUtil.generateRandomPwd(Constants.RANDOM_PWD_LEN);
}
user.setPassword(PasswordUtil.MD5(password.toLowerCase() + Constants.PASSWORD_SALT));
Timestamp currentTime = new Timestamp(System.currentTimeMillis());
user.setUpdatedAt(currentTime);
user.setCreatedAt(currentTime);
user = userService.saveUser(user);
userRegisterParam.setUser(user);
return user;
} }
@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) {
...@@ -60,7 +102,8 @@ public class UserRegisterServiceImpl extends AbstractUserRegisterService { ...@@ -60,7 +102,8 @@ public class UserRegisterServiceImpl extends AbstractUserRegisterService {
.generateRandomPwd(false).sendSuccessSms(true).sendAppSms(true) .generateRandomPwd(false).sendSuccessSms(true).sendAppSms(true)
.sendSuccessMq(true) .sendSuccessMq(true)
.build(); .build();
User user = registerDefault(userRegisterParam); User user = saveUser(userRegisterParam);
applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
return user != null; return user != null;
} }
...@@ -74,32 +117,26 @@ public class UserRegisterServiceImpl extends AbstractUserRegisterService { ...@@ -74,32 +117,26 @@ public class UserRegisterServiceImpl extends AbstractUserRegisterService {
.generateRandomPwd(true).sendSuccessSms(true).sendAppSms(true) .generateRandomPwd(true).sendSuccessSms(true).sendAppSms(true)
.sendSuccessMq(true) .sendSuccessMq(true)
.build(); .build();
return registerDefault(userRegisterParam); User user = saveUser(userRegisterParam);
applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
return user;
} }
@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, Long btRegisterChannelId) { public User register(Long registeredFrom, Long channelId, String phoneNo, String name, String idNo, Address addressObj, String contacts, List<Contact> contactList, Long btRegisterChannelId) {
UserRegisterParam userRegisterParam = UserRegisterParam.builder() UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registeredFrom).phoneNo(phoneNo).idNo(idNo).name(name) .registerFrom(registeredFrom).phoneNo(phoneNo).idNo(idNo).name(name)
.channelId(channelId) .channelId(channelId)
.btRegisterChannelId(btRegisterChannelId) .btRegisterChannelId(btRegisterChannelId)
.address(addressObj).contacts(contacts) .address(addressObj).contacts(contacts)
.contactList(contactList)
.generateRandomPwd(true).sendSuccessSms(true).sendAppSms(true) .generateRandomPwd(true).sendSuccessSms(true).sendAppSms(true)
.sendSuccessMq(true) .sendSuccessMq(true)
.build(); .build();
return registerExt(userRegisterParam); User user = saveUser(userRegisterParam);
applicationEventPublisher.publishEvent(new RegisterEvent(this, userRegisterParam));
return user;
} }
@Transactional(rollbackFor = Exception.class)
@Override
public User register(Long registerFrom, String phoneNo, String idNo, String name, Long channelId) {
UserRegisterParam userRegisterParam = UserRegisterParam.builder()
.registerFrom(registerFrom).phoneNo(phoneNo).idNo(idNo).name(name)
.channelId(channelId)
.generateRandomPwd(true).sendSuccessSms(true).sendAppSms(true)
.sendSuccessMq(true)
.build();
return registerDefault(userRegisterParam);
}
} }
...@@ -25,7 +25,6 @@ import org.springframework.stereotype.Service; ...@@ -25,7 +25,6 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -183,13 +182,12 @@ public class UserDetailServiceImpl implements IUserDetailService { ...@@ -183,13 +182,12 @@ public class UserDetailServiceImpl implements IUserDetailService {
UserDetail userDetail = userDetailRepository.findByPhoneNo(phoneNo); UserDetail userDetail = userDetailRepository.findByPhoneNo(phoneNo);
if (null != userDetail) { if (null != userDetail) {
if (StringUtils.isNotBlank(idNo)) { if (StringUtils.isNotBlank(idNo)) {
try { IdCardInfo idCardInfo = idCardService.getIdCardInfo(idNo);
IdCardInfo idCardInfo = idCardService.getIdCardInfo(idNo); if (idCardInfo == null || !idCardInfo.isValid()) {
return userDetailRepository.updateIdNoByPhoneNo(idCardInfo.getIdNo(), Optional.ofNullable(idCardInfo.getGender()).orElse(Gender.UNKNOWN).ordinal(), phoneNo); LOGGER.error("用户的身份证错误,phoneNo:{},idNo:{}", phoneNo, idNo);
} catch (ParseException e) {
LOGGER.error("用户的身份证错误,phoneNo:{},e:{}", phoneNo, e);
return 0; return 0;
} }
return userDetailRepository.updateIdNoByPhoneNo(idCardInfo.getIdNo(), Optional.ofNullable(idCardInfo.getGender()).orElse(Gender.UNKNOWN).ordinal(), phoneNo);
} }
if (StringUtils.isNotBlank(name) && ValidationUtil.validateChinese(name)) { if (StringUtils.isNotBlank(name) && ValidationUtil.validateChinese(name)) {
return userDetailRepository.updateNameByPhoneNo(name, phoneNo); return userDetailRepository.updateNameByPhoneNo(name, phoneNo);
......
...@@ -52,20 +52,8 @@ public class UserServiceImpl implements IUserService { ...@@ -52,20 +52,8 @@ public class UserServiceImpl implements IUserService {
return Maps.newHashMap(); return Maps.newHashMap();
} }
Map<Long, String> userIdAndPhoneMap = Maps.newHashMap(); Map<Long, String> userIdAndPhoneMap = Maps.newHashMap();
int pageSize = 1000; List<User> users = userRepository.findByIdIn(userIds);
int idSize = userIds.size(); users.forEach(user -> userIdAndPhoneMap.put(user.getId(), user.getPhoneNo()));
for (int i = 0; i < idSize; i += pageSize) {
List<Long> subList = userIds.subList(i, Math.min(idSize, i + pageSize));
List<User> users = userRepository.findByIdIn(subList);
users.stream().forEach(user -> userIdAndPhoneMap.put(user.getId(), user.getPhoneNo()));
if (i + pageSize < idSize) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
log.error("线程sleep失败", e);
}
}
}
return userIdAndPhoneMap; return userIdAndPhoneMap;
} }
...@@ -150,11 +138,11 @@ public class UserServiceImpl implements IUserService { ...@@ -150,11 +138,11 @@ public class UserServiceImpl implements IUserService {
public List<UserInfo> findUserInfosByPhones(List<String> phones) { public List<UserInfo> findUserInfosByPhones(List<String> phones) {
List<User> users = findByPhones(phones); List<User> users = findByPhones(phones);
if(CollectionUtils.isEmpty(phones)){ if (CollectionUtils.isEmpty(phones)) {
return Collections.emptyList(); return Collections.emptyList();
} }
List<UserDetail> userDetails= userDetailService.findByPhones(phones); List<UserDetail> userDetails = userDetailService.findByPhones(phones);
if (!CollectionUtils.isEmpty(users)) { if (!CollectionUtils.isEmpty(users)) {
Map<Long, User> userMap = Maps.newHashMapWithExpectedSize(users.size()); Map<Long, User> userMap = Maps.newHashMapWithExpectedSize(users.size());
......
...@@ -131,19 +131,20 @@ public class WechatServiceImpl implements IWechatService { ...@@ -131,19 +131,20 @@ public class WechatServiceImpl implements IWechatService {
if (null == userInfo.getPhoneNo()) { if (null == userInfo.getPhoneNo()) {
userInfo.setPhoneNo(""); userInfo.setPhoneNo("");
} }
// 微信用户首次登录界面, 首先保存userInfo, 跳入到微信注册登录界面 // // 微信用户首次登录界面, 首先保存userInfo, 跳入到微信注册登录界面
// 替换所有,UTF-8编码时4字节的Emoji表情字符 // // 替换所有,UTF-8编码时4字节的Emoji表情字符
String nickName = EmojiUtil.filterUnicode4(userInfo.getNickName()); // String nickName = EmojiUtil.filterUnicode4(userInfo.getNickName());
userInfo.setNickName(nickName); // userInfo.setNickName(nickName);
// 替换所有,UTF-8编码时4字节的Emoji表情字符 // // 替换所有,UTF-8编码时4字节的Emoji表情字符
String country = EmojiUtil.filterUnicode4(userInfo.getCountry()); // String country = EmojiUtil.filterUnicode4(userInfo.getCountry());
userInfo.setCountry(country); // userInfo.setCountry(country);
// 替换所有,UTF-8编码时4字节的Emoji表情字符 // // 替换所有,UTF-8编码时4字节的Emoji表情字符
String prvince = EmojiUtil.filterUnicode4(userInfo.getProvince()); // String prvince = EmojiUtil.filterUnicode4(userInfo.getProvince());
userInfo.setProvince(prvince); // userInfo.setProvince(prvince);
// 替换所有,UTF-8编码时4字节的Emoji表情字符 // // 替换所有,UTF-8编码时4字节的Emoji表情字符
String city = EmojiUtil.filterUnicode4(userInfo.getCity()); // String city = EmojiUtil.filterUnicode4(userInfo.getCity());
userInfo.setCity(city); // userInfo.setCity(city);
userInfo = userInfo.convertEmoji();
return weChatUserRepository.save(userInfo); return weChatUserRepository.save(userInfo);
} }
......
package cn.quantgroup.xyqb.validator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ChineseNameValidator.class)
public @interface ChineseName {
/**
* 出错提示
*
* @return
*/
String message() default "用户姓名错误";
/**
* 啥玩意?
*
* @return
*/
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
package cn.quantgroup.xyqb.validator;
import cn.quantgroup.xyqb.util.ValidationUtil;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 中文姓名验证器, <ChineseName,String> String 对应的是可以对哪些类型校验
*
* @author ag
*/
public class ChineseNameValidator implements ConstraintValidator<ChineseName, String> {
/**
* 这个方法在初始化的时候调用. 如果配置错了, 你可以抛一个异常. 启动就报错了
*
* @param constraint
*/
@Override
public void initialize(ChineseName constraint) {
}
/**
* 这....true = 校验通过. false = 校验失败
*
* @param userName 就是那个String
* @param context
* @return
*/
@Override
public boolean isValid(String userName, ConstraintValidatorContext context) {
return ValidationUtil.validateChinese(userName);
}
}
/*
*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
package springfox.documentation.schema;
import com.fasterxml.jackson.annotation.JsonValue;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import org.springframework.core.annotation.AnnotationUtils;
import springfox.documentation.service.AllowableListValues;
import springfox.documentation.service.AllowableValues;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.Lists.transform;
import static java.util.Arrays.asList;
/**
* 增加对enum name 的支持
*/
public class Enums {
private Enums() {
throw new UnsupportedOperationException();
}
public static AllowableValues allowableValues(Class<?> type) {
if (type.isEnum()) {
List<String> enumValues = getEnumValues(type);
return new AllowableListValues(enumValues, "LIST");
}
return null;
}
static List<String> getEnumValues(final Class<?> subject) {
return transformUnique(subject.getEnumConstants(), new Function<Object, String>() {
@Override
public String apply(Object input) {
Optional<String> jsonValue = findJsonValueAnnotatedMethod(input)
.transform(evaluateJsonValue(input));
if (jsonValue.isPresent() && !isNullOrEmpty(jsonValue.get())) {
return jsonValue.get();
}
return ((Enum) input).name();
}
});
}
@SuppressWarnings("PMD")
private static Function<Method, String> evaluateJsonValue(final Object enumConstant) {
return new Function<Method, String>() {
@Override
public String apply(Method input) {
try {
return input.invoke(enumConstant).toString();
} catch (Exception ignored) {
}
return "";
}
};
}
private static <E> List<String> transformUnique(E[] values, Function<E, String> mapper) {
List<String> nonUniqueValues = transform(asList(values), mapper);
Set<String> uniqueValues = new LinkedHashSet<String>(nonUniqueValues);
return new ArrayList<String>(uniqueValues);
}
private static Optional<Method> findJsonValueAnnotatedMethod(Object enumConstant) {
for (Method each : enumConstant.getClass().getMethods()) {
JsonValue jsonValue = AnnotationUtils.findAnnotation(each, JsonValue.class);
if (jsonValue != null && jsonValue.value()) {
return Optional.of(each);
}
}
return Optional.absent();
}
public static AllowableValues emptyListValuesToNull(AllowableListValues values) {
if (!values.getValues().isEmpty()) {
return values;
}
return null;
}
}
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