Merge branch 'USVT-126' into 'master'

微信用户注册

See merge request usvisatrack/usvisatrack.api.service!9
This commit is contained in:
YuCheng Hu 2022-12-06 17:43:51 +00:00
commit 3eb0c9d64c
9 changed files with 183 additions and 51 deletions

View File

@ -8,8 +8,11 @@ import com.northtecom.visatrack.api.base.web.Status;
import com.northtecom.visatrack.api.controller.vo.*; import com.northtecom.visatrack.api.controller.vo.*;
import com.northtecom.visatrack.api.data.entity.User; import com.northtecom.visatrack.api.data.entity.User;
import com.northtecom.visatrack.api.data.entity.UserChangePassword; import com.northtecom.visatrack.api.data.entity.UserChangePassword;
import com.northtecom.visatrack.api.data.entity.WeChatCallState;
import com.northtecom.visatrack.api.model.entity.wechat.WeChatUser;
import com.northtecom.visatrack.api.service.impl.UserService; import com.northtecom.visatrack.api.service.impl.UserService;
import com.vladmihalcea.hibernate.type.util.ObjectMapperJsonSerializer; import com.northtecom.visatrack.api.service.impl.WeChatService;
import com.northtecom.visatrack.api.util.WeChatUtils;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -28,7 +31,9 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.Optional;
/** /**
* Created with IntelliJ IDEA. * Created with IntelliJ IDEA.
@ -51,13 +56,15 @@ public class AuthController {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final UserService userService; private final UserService userService;
private final WeChatService weChatService;
private final AuthenticationManager authenticationManager; private final AuthenticationManager authenticationManager;
@Autowired @Autowired
public AuthController(ObjectMapper objectMapper, UserService userService, AuthenticationManager authenticationManager, BCryptPasswordEncoder encoder) { public AuthController(ObjectMapper objectMapper, UserService userService, AuthenticationManager authenticationManager, BCryptPasswordEncoder encoder, WeChatService weChatService) {
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
this.userService = userService; this.userService = userService;
this.authenticationManager = authenticationManager; this.authenticationManager = authenticationManager;
this.weChatService = weChatService;
} }
@ -68,8 +75,24 @@ public class AuthController {
log.debug("Register User Request: {}", this.objectMapper.writeValueAsString(registerUserRequest)); log.debug("Register User Request: {}", this.objectMapper.writeValueAsString(registerUserRequest));
registerUserRequest.setPassword(registerUserRequest.getPassword()); registerUserRequest.setPassword(registerUserRequest.getPassword());
WeChatUser weChatUser = null;
Optional<WeChatCallState> weChatCallState;
User user = this.userService.registerUser(registerUserRequest); // Get WeChat user
String weChatCode = registerUserRequest.getWeChatCode();
String weChatState = registerUserRequest.getWeChatState();
if (StringUtils.isNoneEmpty(weChatState, weChatCode)) {
weChatCallState = weChatService.getWeChatCallState(weChatState, weChatCode);
if (weChatCallState.isPresent()) {
weChatUser = WeChatUtils.covertToWeChatUser(weChatCallState.get());
} else {
throw new BaseException(Status.BAD_REQUEST, "Cannot get WeChat User");
}
}
// DO REGISTER
User user = this.userService.registerUser(registerUserRequest, weChatUser);
CustomerUserInfoResponse registerUserInfoResponse = new CustomerUserInfoResponse(); CustomerUserInfoResponse registerUserInfoResponse = new CustomerUserInfoResponse();
registerUserInfoResponse.setUserName(user.getUserName()); registerUserInfoResponse.setUserName(user.getUserName());

View File

@ -49,9 +49,11 @@ public class WeChatController {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final AuthenticationManager authenticationManager;
private final UserService userService; private final UserService userService;
private final WeChatService weChatService; private final WeChatService weChatService;
private final AuthenticationManager authenticationManager;
@Autowired @Autowired
public WeChatController(ObjectMapper objectMapper, UserService userService, AuthenticationManager authenticationManager, BCryptPasswordEncoder encoder, WeChatService weChatService) { public WeChatController(ObjectMapper objectMapper, UserService userService, AuthenticationManager authenticationManager, BCryptPasswordEncoder encoder, WeChatService weChatService) {
@ -83,7 +85,9 @@ public class WeChatController {
@ResponseBody @ResponseBody
@Operation(summary = "微信用户登录授权", description = "使用微信的信息登录用户,并且设置登录成功后的 Token") @Operation(summary = "微信用户登录授权", description = "使用微信的信息登录用户,并且设置登录成功后的 Token")
public UserLoginResponse getWeChatAccessToken(@RequestBody @Valid WeChatTokenizeRequest weChatTokenizeRequest) throws IOException { public UserLoginResponse getWeChatAccessToken(@RequestBody @Valid WeChatTokenizeRequest weChatTokenizeRequest) throws IOException {
WeChatUser weChatUser = weChatService.getWeChatUserInfo(weChatTokenizeRequest);
WeChatUser weChatUser = weChatService.getWeChatUserInfo(weChatTokenizeRequest.getWeChatCode(), weChatTokenizeRequest.getWeChatState());
String weChatOpenId = weChatUser.getOpenId(); String weChatOpenId = weChatUser.getOpenId();
String weChatUnionId = weChatUser.getUnionId(); String weChatUnionId = weChatUser.getUnionId();

View File

@ -25,4 +25,6 @@ public class RegisterUserRequest {
private String email; private String email;
private String nationality; private String nationality;
private Boolean allowReceiveMessage; private Boolean allowReceiveMessage;
private String weChatCode;
private String weChatState;
} }

View File

@ -0,0 +1,42 @@
package com.northtecom.visatrack.api.data.entity;
import com.northtecom.visatrack.api.base.data.BaseEntity;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* WeChat API Call State to get user information and access token
*
* @author YuCheng
*/
@Entity
@Data
@Table(name = "wechat_call_state")
@org.hibernate.annotations.Table(appliesTo = "wechat_call_state", comment = "WeChat Call State")
public class WeChatCallState extends BaseEntity<Long> {
@Column(name = "wechat_state", columnDefinition = "varchar(255) COMMENT 'wechat state'")
private String weChatState;
@Column(name = "wechat_code", columnDefinition = "varchar(255) COMMENT 'wechat code'")
private String weChatCode;
@Column(name = "wechat_access_token", columnDefinition = "TEXT COMMENT 'wechat access token'")
private String weChatAccessToken;
@Column(name = "wechat_openid", columnDefinition = "varchar(255) COMMENT 'wechat openid'")
private String weChatOpenId;
@Column(name = "wechat_unionid", columnDefinition = "varchar(255) COMMENT 'wechat unionid'")
private String weChatUnionId;
@Column(name = "nickname", columnDefinition = "varchar(255) COMMENT 'wechat nickname'")
private String nickName;
@Column(name = "head_img_url", columnDefinition = "varchar(255) COMMENT 'wechat head image url'")
private String headImgURL;
}

View File

@ -0,0 +1,20 @@
package com.northtecom.visatrack.api.data.repository;
import com.northtecom.visatrack.api.data.entity.UserChangePassword;
import com.northtecom.visatrack.api.data.entity.VisaCheckeeCrawlData;
import com.northtecom.visatrack.api.data.entity.WeChatCallState;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.Optional;
/**
* Created with IntelliJ IDEA.
*
* @Author: XieYang
* @Date: 2022/10/11/7:03
* @Description:
*/
public interface WeChatCallStateRepository extends CrudRepository<WeChatCallState, Long> {
Optional<WeChatCallState> findByWeChatStateEqualsAndWeChatCodeEquals(String weChatState, String weChatCode);
}

View File

@ -2,8 +2,10 @@ package com.northtecom.visatrack.api.model.entity.wechat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors;
@Data @Data
@Accessors(chain = true)
public class WeChatUser { public class WeChatUser {
@JsonProperty(value = "openid", required = true) @JsonProperty(value = "openid", required = true)

View File

@ -11,8 +11,10 @@ import com.northtecom.visatrack.api.data.entity.VisaCase;
import com.northtecom.visatrack.api.data.repository.UserChangePasswordRepository; import com.northtecom.visatrack.api.data.repository.UserChangePasswordRepository;
import com.northtecom.visatrack.api.data.repository.UserRepository; import com.northtecom.visatrack.api.data.repository.UserRepository;
import com.northtecom.visatrack.api.data.repository.VisaCaseRepository; import com.northtecom.visatrack.api.data.repository.VisaCaseRepository;
import com.northtecom.visatrack.api.model.entity.wechat.WeChatUser;
import com.northtecom.visatrack.api.service.enums.UserStatus; import com.northtecom.visatrack.api.service.enums.UserStatus;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -57,7 +59,7 @@ public class UserService implements UserDetailsService {
this.jwtUtil = jwtUtil; this.jwtUtil = jwtUtil;
} }
public User registerUser(RegisterUserRequest registerUserRequest) { public User registerUser(RegisterUserRequest registerUserRequest, WeChatUser weChatUser) {
if (checkUserNameIsExist(registerUserRequest.getUserName())) { if (checkUserNameIsExist(registerUserRequest.getUserName())) {
throw new BaseException(Status.BAD_REQUEST, "User Name is already exist"); throw new BaseException(Status.BAD_REQUEST, "User Name is already exist");
@ -75,6 +77,12 @@ public class UserService implements UserDetailsService {
user.setDateRegistered(LocalDateTime.now()); user.setDateRegistered(LocalDateTime.now());
user.setIsEmailVerified(false); user.setIsEmailVerified(false);
user.setEmailVerifiedCode(RandomUtil.randomNumbers(6)); user.setEmailVerifiedCode(RandomUtil.randomNumbers(6));
// SET WeChat User Info by scan QR register
if(ObjectUtils.isNotEmpty(weChatUser)) {
user.setWechatOpenid(weChatUser.getOpenId());
user.setWechatUnionid(weChatUser.getUnionId());
}
User savedUser = userRepository.save(user); User savedUser = userRepository.save(user);
emailService.sendVerifiedEmailToUser(savedUser); emailService.sendVerifiedEmailToUser(savedUser);

View File

@ -3,10 +3,8 @@ package com.northtecom.visatrack.api.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.northtecom.visatrack.api.data.entity.VisaCase; import com.northtecom.visatrack.api.data.entity.VisaCase;
import com.northtecom.visatrack.api.data.repository.CaseVisaReportRepository; import com.northtecom.visatrack.api.data.entity.WeChatCallState;
import com.northtecom.visatrack.api.data.repository.UserRepository; import com.northtecom.visatrack.api.data.repository.*;
import com.northtecom.visatrack.api.data.repository.VisaCaseRepository;
import com.northtecom.visatrack.api.data.repository.VisaCheckeeCrawlDataRepository;
import com.northtecom.visatrack.api.model.entity.wechat.WeChatAccessToken; import com.northtecom.visatrack.api.model.entity.wechat.WeChatAccessToken;
import com.northtecom.visatrack.api.model.entity.wechat.WeChatUser; import com.northtecom.visatrack.api.model.entity.wechat.WeChatUser;
import com.northtecom.visatrack.api.model.request.auth.WeChatTokenizeRequest; import com.northtecom.visatrack.api.model.request.auth.WeChatTokenizeRequest;
@ -18,6 +16,7 @@ import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
/** /**
* Created with IntelliJ IDEA. * Created with IntelliJ IDEA.
@ -30,7 +29,8 @@ import java.io.IOException;
@Slf4j @Slf4j
public class WeChatService { public class WeChatService {
private final VisaCaseRepository visaCaseRepository; private final VisaCaseRepository visaCaseRepository;
private final CaseVisaReportRepository caseVisaReportRepository;
private final WeChatCallStateRepository weChatCallStateRepository;
private final UserRepository userRepository; private final UserRepository userRepository;
private final CrawlService crawlService; private final CrawlService crawlService;
private final VisaCheckeeCrawlDataRepository visaCheckeeCrawlDataRepository; private final VisaCheckeeCrawlDataRepository visaCheckeeCrawlDataRepository;
@ -39,9 +39,9 @@ public class WeChatService {
@Autowired @Autowired
public WeChatService(VisaCaseRepository visaCaseRepository, CaseVisaReportRepository caseVisaReportRepository, UserRepository userRepository, CrawlService crawlService, VisaCheckeeCrawlDataRepository visaCheckeeCrawlDataRepository, ObjectMapper objectMapper) { public WeChatService(VisaCaseRepository visaCaseRepository, WeChatCallStateRepository weChatCallStateRepository, UserRepository userRepository, CrawlService crawlService, VisaCheckeeCrawlDataRepository visaCheckeeCrawlDataRepository, ObjectMapper objectMapper) {
this.visaCaseRepository = visaCaseRepository; this.visaCaseRepository = visaCaseRepository;
this.caseVisaReportRepository = caseVisaReportRepository; this.weChatCallStateRepository = weChatCallStateRepository;
this.userRepository = userRepository; this.userRepository = userRepository;
this.crawlService = crawlService; this.crawlService = crawlService;
this.visaCheckeeCrawlDataRepository = visaCheckeeCrawlDataRepository; this.visaCheckeeCrawlDataRepository = visaCheckeeCrawlDataRepository;
@ -54,39 +54,45 @@ public class WeChatService {
* @param search 搜索参数 * @param search 搜索参数
* @return {@link Page}<{@link VisaCase}> * @return {@link Page}<{@link VisaCase}>
*/ */
public WeChatUser getWeChatUserInfo(WeChatTokenizeRequest weChatTokenizeRequest) { public WeChatUser getWeChatUserInfo(String weChatCode, String weChatState) throws IOException {
OkHttpClient client = new OkHttpClient(); OkHttpClient client = new OkHttpClient();
String response = StringUtils.EMPTY; String response = StringUtils.EMPTY;
WeChatUser weChatUser = null; WeChatUser weChatUser = null;
String weChatCode = weChatTokenizeRequest.getWeChatCode(); response = callWeChatAccessTokenAPI(client, weChatCode, weChatState);
String weChatState = weChatTokenizeRequest.getWeChatState(); WeChatAccessToken weChatAccessToken = objectMapper.readValue(response, WeChatAccessToken.class);
try {
response = callWeChatAccessTokenAPI(client, weChatCode, weChatState);
WeChatAccessToken weChatAccessToken = objectMapper.readValue(response, WeChatAccessToken.class);
String accessToken = weChatAccessToken.getAccessToken(); String accessToken = weChatAccessToken.getAccessToken();
String openId = weChatAccessToken.getOpenId(); String openId = weChatAccessToken.getOpenId();
if(StringUtils.isNoneEmpty(accessToken,openId)) { if (StringUtils.isNoneEmpty(accessToken, openId)) {
response = callWeChatUserInfoAPI(client, accessToken, openId); response = callWeChatUserInfoAPI(client, accessToken, openId);
weChatUser = objectMapper.readValue(response, WeChatUser.class); weChatUser = objectMapper.readValue(response, WeChatUser.class);
log.debug("WeChat NickName - [{}]", weChatUser.getNickname()); log.debug("WeChat NickName - [{}]", weChatUser.getNickname());
} WeChatCallState weChatCallState = new WeChatCallState();
weChatCallState.setWeChatState(weChatState);
} catch (JsonProcessingException e) { weChatCallState.setWeChatCode(weChatCode);
log.error("Get WeChat User Info Error.", e); weChatCallState.setWeChatAccessToken(accessToken);
throw new RuntimeException(e); weChatCallState.setWeChatOpenId(weChatUser.getOpenId());
weChatCallState.setWeChatUnionId(weChatUser.getUnionId());
weChatCallState.setNickName(weChatUser.getNickname());
weChatCallState.setHeadImgURL(weChatUser.getHeadImgURL());
weChatCallStateRepository.save(weChatCallState);
} }
return weChatUser; return weChatUser;
} }
public Optional<WeChatCallState> getWeChatCallState(String weChatState, String weChatCode) {
return weChatCallStateRepository.findByWeChatStateEqualsAndWeChatCodeEquals(weChatState, weChatCode);
}
private String callWeChatAccessTokenAPI(OkHttpClient client, String weChatCode, String weChatState) {
private String callWeChatAccessTokenAPI(OkHttpClient client, String weChatCode, String weChatState) throws IOException {
String responseStr; String responseStr;
String weChatAppId = "wx26e01c2be46730f3"; String weChatAppId = "wx26e01c2be46730f3";
String weChatSecret = "1eef340a999bc71b431dda85e9bffd3a"; String weChatSecret = "1eef340a999bc71b431dda85e9bffd3a";
@ -97,18 +103,12 @@ public class WeChatService {
urlBuilder.addQueryParameter("code", weChatCode); urlBuilder.addQueryParameter("code", weChatCode);
urlBuilder.addQueryParameter("grant_type", "authorization_code"); urlBuilder.addQueryParameter("grant_type", "authorization_code");
try {
Request request = new Request.Builder().url(urlBuilder.build().toString()).build(); Request request = new Request.Builder().url(urlBuilder.build().toString()).build();
Call call = client.newCall(request); Call call = client.newCall(request);
Response response = call.execute(); Response response = call.execute();
responseStr = response.body().string(); responseStr = response.body().string();
} catch (IOException e) {
log.error("Call WeChat get access token error.", e);
throw new RuntimeException(e);
}
return responseStr; return responseStr;
} }
@ -120,7 +120,7 @@ public class WeChatService {
* @param openId * @param openId
* @return * @return
*/ */
private String callWeChatUserInfoAPI(OkHttpClient client, String accessToken, String openId) { private String callWeChatUserInfoAPI(OkHttpClient client, String accessToken, String openId) throws IOException {
String responseStr; String responseStr;
@ -128,17 +128,13 @@ public class WeChatService {
urlBuilder.addQueryParameter("access_token", accessToken); urlBuilder.addQueryParameter("access_token", accessToken);
urlBuilder.addQueryParameter("openid", openId); urlBuilder.addQueryParameter("openid", openId);
try {
Request request = new Request.Builder().url(urlBuilder.build().toString()).build(); Request request = new Request.Builder().url(urlBuilder.build().toString()).build();
Call call = client.newCall(request); Call call = client.newCall(request);
Response response = call.execute(); Response response = call.execute();
responseStr = response.body().string(); responseStr = response.body().string();
} catch (IOException e) {
throw new RuntimeException(e);
}
return responseStr; return responseStr;
} }

View File

@ -0,0 +1,35 @@
/*
* XMLUtils.java
*
* Created on December 6, 2001, 1:21 PM
*/
package com.northtecom.visatrack.api.util;
import com.northtecom.visatrack.api.data.entity.WeChatCallState;
import com.northtecom.visatrack.api.model.entity.wechat.WeChatUser;
import lombok.extern.slf4j.Slf4j;
/**
* Utilities for Email sending
*
* @author YuCheng Hu
*/
@Slf4j
public class WeChatUtils {
/**
* Send Test Email to check config and email sending API
*
* @return
*/
public static WeChatUser covertToWeChatUser(WeChatCallState weChatCallState) {
WeChatUser weChatUser = new WeChatUser();
weChatUser.setOpenId(weChatCallState.getWeChatOpenId())
.setUnionId(weChatCallState.getWeChatUnionId())
.setNickname(weChatCallState.getNickName())
.setHeadImgURL(weChatCallState.getHeadImgURL());
return weChatUser;
}
}