From 812b2474d61a461646fd638c0539bb3d06387bda Mon Sep 17 00:00:00 2001 From: "taylor.dang" Date: Tue, 21 Apr 2020 18:11:34 +0800 Subject: [PATCH] =?UTF-8?q?[Y]=20apple=20=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../appclient/beans/AppleLoginBean.java | 28 +++++ .../appclient/core/RetailAppService.java | 11 +- .../core/impls/RetailAppServiceImp.java | 108 ++++++++++++------ .../appclient/web/RetailAppController.java | 49 +++++--- .../web/RetailValidationController.java | 91 ++++++++++----- .../mappers/system/ClientAccountMapper.java | 17 ++- .../signin/core/SignInAccountService.java | 2 + .../signin/core/SignInStatusManager.java | 3 + .../core/impls/SignInAccountServiceImpl.java | 13 ++- .../core/impls/SignInStatusManagerImpl.java | 70 ++++++++---- 11 files changed, 282 insertions(+), 112 deletions(-) create mode 100644 src/main/java/au/com/royalpay/payment/manage/appclient/beans/AppleLoginBean.java diff --git a/pom.xml b/pom.xml index 5c1bb14a2..d469de5c8 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 manage - 2.2.5 + 2.2.6 UTF-8 1.8.0 diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/beans/AppleLoginBean.java b/src/main/java/au/com/royalpay/payment/manage/appclient/beans/AppleLoginBean.java new file mode 100644 index 000000000..34f3474e7 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/beans/AppleLoginBean.java @@ -0,0 +1,28 @@ +package au.com.royalpay.payment.manage.appclient.beans; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotEmpty; + +/** + * @author taylor.dang + * @date 2020-04-20 21:26 + */ +@Getter +@Setter +public class AppleLoginBean { + @JSONField(name = "identityToken") + @NotEmpty + private String identityToken; + @JSONField(name = "user") + @NotEmpty + private String user; + @JSONField(name = "devId") + @NotEmpty + private String devId; + @JSONField(name = "authorizationCode") + @NotEmpty + private String authorizationCode; +} diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/core/RetailAppService.java b/src/main/java/au/com/royalpay/payment/manage/appclient/core/RetailAppService.java index 0f2e8bdf9..df98abc54 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/core/RetailAppService.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/core/RetailAppService.java @@ -1,9 +1,6 @@ package au.com.royalpay.payment.manage.appclient.core; -import au.com.royalpay.payment.manage.appclient.beans.AppClientBean; -import au.com.royalpay.payment.manage.appclient.beans.AppPaymentConfigBean; -import au.com.royalpay.payment.manage.appclient.beans.AppQueryBean; -import au.com.royalpay.payment.manage.appclient.beans.RetailAppMessage; +import au.com.royalpay.payment.manage.appclient.beans.*; import au.com.royalpay.payment.manage.merchants.beans.ClientAuthFilesInfo; import au.com.royalpay.payment.manage.merchants.beans.ClientKycFilesInfo; import au.com.royalpay.payment.manage.merchants.beans.ClientUpdateInfo; @@ -201,6 +198,8 @@ public interface RetailAppService { void updateLoginClientAccountPhone(JSONObject account,String contactPhone, String nationCode); void updateLoginClientAccountOpenId(JSONObject client,JSONObject params); + + void updateLoginClientAccountAppleId(JSONObject client,JSONObject params); /** * 退款密码 */ @@ -251,6 +250,10 @@ public interface RetailAppService { JSONObject bindAccountWechat(JSONObject device, JSONObject params); + JSONObject unbindAccountApple(JSONObject device); + + JSONObject bindAccountApple(JSONObject device, AppleLoginBean appleLoginBean); + JSONObject getAccountBindInfos(JSONObject device); JSONObject postAppMessage(JSONObject device, RetailAppMessage message); diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java index 67690a50f..19e4fc2f2 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/RetailAppServiceImp.java @@ -6,10 +6,7 @@ import au.com.royalpay.payment.core.exceptions.InvalidShortIdException; import au.com.royalpay.payment.manage.activities.app_index.core.AppActService; import au.com.royalpay.payment.manage.analysis.mappers.CustomerAndOrdersStatisticsMapper; import au.com.royalpay.payment.manage.analysis.mappers.TransactionAnalysisMapper; -import au.com.royalpay.payment.manage.appclient.beans.AppClientBean; -import au.com.royalpay.payment.manage.appclient.beans.AppPaymentConfigBean; -import au.com.royalpay.payment.manage.appclient.beans.AppQueryBean; -import au.com.royalpay.payment.manage.appclient.beans.RetailAppMessage; +import au.com.royalpay.payment.manage.appclient.beans.*; import au.com.royalpay.payment.manage.appclient.core.RetailAppService; import au.com.royalpay.payment.manage.appclient.extend.GatewayOAuthRegister; import au.com.royalpay.payment.manage.cashback.core.CashbackService; @@ -73,6 +70,8 @@ import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider; import au.com.royalpay.payment.tools.permission.enums.PartnerRole; import au.com.royalpay.payment.tools.threadpool.RoyalThreadPoolExecutor; import au.com.royalpay.payment.tools.utils.*; +import au.com.royalpay.payment.tools.utils.apple.AppleAuthUtils; +import au.com.royalpay.payment.tools.utils.apple.UserClaim; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -1782,7 +1781,7 @@ public class RetailAppServiceImp implements RetailAppService { if (geekShowActVersion(device.getString("version"))) { newActs.add(act); } - }else { + } else { newActs.add(act); } } @@ -2322,6 +2321,14 @@ public class RetailAppServiceImp implements RetailAppService { clientAccountMapper.update(updateAccount); } + @Override + public void updateLoginClientAccountAppleId(JSONObject account, JSONObject params) { + JSONObject updateAccount = new JSONObject(); + updateAccount.put("account_id", account.getString("account_id")); + updateAccount.put("apple_userid", params.getString("apple_userid")); + clientAccountMapper.update(updateAccount); + } + @Override public JSONObject unbindAccountPhone(JSONObject device, JSONObject params) { String codeKeyValueRedis = stringRedisTemplate.boundValueOps(getUpdateAccountPhoneKey(device.getString("account_id"))).get(); @@ -2379,6 +2386,36 @@ public class RetailAppServiceImp implements RetailAppService { return result; } + @Override + public JSONObject unbindAccountApple(JSONObject device) { + JSONObject account = new JSONObject(); + account.put("account_id", device.getString("account_id")); + account.put("apple_userid", null); + clientAccountMapper.update(account); + JSONObject result = new JSONObject(); + result.put("status", "success"); + return result; + } + + @Override + public JSONObject bindAccountApple(JSONObject device, AppleLoginBean appleLoginBean) { + UserClaim userClaim = AppleAuthUtils.verifyIdentifyToken(appleLoginBean.getIdentityToken()); + if (!StringUtils.equalsIgnoreCase(userClaim.getSub(), appleLoginBean.getUser())) { + throw new ForbiddenException("apple userinfo is error"); + } + JSONObject account = clientAccountMapper.findByAppleUserId(userClaim.getSub()); + if (account != null) { + throw new BadRequestException("Apple UserID has been bound to other accounts, please unbind it before binding"); + } + JSONObject updateAccount = new JSONObject(); + updateAccount.put("account_id", device.getString("account_id")); + updateAccount.put("apple_userid", userClaim.getSub()); + clientAccountMapper.update(updateAccount); + JSONObject result = new JSONObject(); + result.put("status", "success"); + return result; + } + @Override public JSONObject getAccountBindInfos(JSONObject device) { JSONObject account = clientAccountMapper.findById(device.getString("account_id")); @@ -2391,6 +2428,7 @@ public class RetailAppServiceImp implements RetailAppService { result.put("nation_code", account.getString("nation_code")); } result.put("wechat_bind_status", account.containsKey("wx_unionid")); + result.put("apple_bind_status", account.containsKey("apple_userid")); if (account.containsKey("wx_unionid")) { result.put("wechat_name", account.getString("wechat_name")); } @@ -2536,7 +2574,7 @@ public class RetailAppServiceImp implements RetailAppService { } JSONObject compliance = clientComplianceCompanyMapper.findFileByClientId(account.getIntValue("client_id")); if (compliance != null) { - if (compliance.getIntValue("status")==0 || compliance.getIntValue("status")==1) { + if (compliance.getIntValue("status") == 0 || compliance.getIntValue("status") == 1) { authFileStatus.put("client_less_file", false); } } @@ -2555,14 +2593,14 @@ public class RetailAppServiceImp implements RetailAppService { authFileStatus.put("content", messageSource.getMessage("client.auth.file.title", null, RequestEnvironment.getLocale())); List supplement_array = new ArrayList<>(); - JSONObject complianceFilesNotice = complianceFilesNotice(client,account); - JSONObject kycFilesNotice = kycFilesNotice(client,account); - - if(complianceFilesNotice != null && kycFilesNotice != null){ - if( !kycFilesNotice.getBoolean("client_less_file") && !complianceFilesNotice.getBoolean("client_less_file")){ - authFileStatus.put("isNeedShowKycAlert",false); - }else{ - authFileStatus.put("isNeedShowKycAlert",true); + JSONObject complianceFilesNotice = complianceFilesNotice(client, account); + JSONObject kycFilesNotice = kycFilesNotice(client, account); + + if (complianceFilesNotice != null && kycFilesNotice != null) { + if (!kycFilesNotice.getBoolean("client_less_file") && !complianceFilesNotice.getBoolean("client_less_file")) { + authFileStatus.put("isNeedShowKycAlert", false); + } else { + authFileStatus.put("isNeedShowKycAlert", true); } } if (PartnerRole.getRole(account.getIntValue("role")) == PartnerRole.CASHIER) { @@ -2652,20 +2690,20 @@ public class RetailAppServiceImp implements RetailAppService { complianceFilesNotice.put("auth_type", FilesAuthTypeEnum.COMPLIANCE.getAuthType()); complianceFilesNotice.put("type", messageSource.getMessage("client.auth.file.compliance.type", null, RequestEnvironment.getLocale())); - complianceFilesNotice.put("client_less_file",complianceFileStatus.getBoolean("client_less_file")); - if(compliance != null){ - if (compliance.getIntValue("status")==0 || compliance.getIntValue("status")==1) { + complianceFilesNotice.put("client_less_file", complianceFileStatus.getBoolean("client_less_file")); + if (compliance != null) { + if (compliance.getIntValue("status") == 0 || compliance.getIntValue("status") == 1) { complianceFilesNotice.put("client_less_file", false); } - if(complianceFileStatus.getBoolean("client_less_file")){ - complianceFilesNotice.put("client_refuse_reason",compliance.getString("description")); + if (complianceFileStatus.getBoolean("client_less_file")) { + complianceFilesNotice.put("client_refuse_reason", compliance.getString("description")); } - complianceFilesNotice.put("status",compliance.getString("status")); - complianceFilesNotice.put( "status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(compliance.getIntValue("status")) ); - }else if( !complianceFileStatus.getBoolean("client_less_file")){ - complianceFilesNotice.put( "status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(1) ); - }else{ - complianceFilesNotice.put( "status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(-1) ); + complianceFilesNotice.put("status", compliance.getString("status")); + complianceFilesNotice.put("status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(compliance.getIntValue("status"))); + } else if (!complianceFileStatus.getBoolean("client_less_file")) { + complianceFilesNotice.put("status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(1)); + } else { + complianceFilesNotice.put("status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(-1)); } complianceFilesNotice.put("status_type_description", messageSource.getMessage("client.auth.file.status." + complianceFilesNotice.getString("status_type").toLowerCase(), null, RequestEnvironment.getLocale())); return complianceFilesNotice; @@ -2683,15 +2721,15 @@ public class RetailAppServiceImp implements RetailAppService { kycFilesNotice.put("auth_type", FilesAuthTypeEnum.KYC.getAuthType()); kycFilesNotice.put("type", messageSource.getMessage("client.auth.file.kyc.type", null, RequestEnvironment.getLocale())); - kycFilesNotice.put("client_less_file",kycFileStatus.getBoolean("client_less_file")); - if(compliance != null){ - if(kycFilesNotice.getBoolean("client_less_file")){ - kycFilesNotice.put("client_refuse_reason",compliance.getString("description")); + kycFilesNotice.put("client_less_file", kycFileStatus.getBoolean("client_less_file")); + if (compliance != null) { + if (kycFilesNotice.getBoolean("client_less_file")) { + kycFilesNotice.put("client_refuse_reason", compliance.getString("description")); } - kycFilesNotice.put("status",compliance.getString("status")); - kycFilesNotice.put( "status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(compliance.getIntValue("status")) ); - }else{ - kycFilesNotice.put( "status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(-1) ); + kycFilesNotice.put("status", compliance.getString("status")); + kycFilesNotice.put("status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(compliance.getIntValue("status"))); + } else { + kycFilesNotice.put("status_type", FilesAuthStatusEnum.STATUS.getAuthStatus(-1)); } kycFilesNotice.put("status_type_description", messageSource.getMessage("client.auth.file.status." + kycFilesNotice.getString("status_type").toLowerCase(), null, RequestEnvironment.getLocale())); return kycFilesNotice; @@ -3103,7 +3141,7 @@ public class RetailAppServiceImp implements RetailAppService { int clientId = account.getIntValue("client_id"); JSONObject displayInfo = actPartnerReadMapper.displayInfo(actId, clientId, accountId); if (displayInfo == null) { - displayInfo = new JSONObject(){{ + displayInfo = new JSONObject() {{ put("display_client_id", UUID.randomUUID().toString()); put("act_id", actId); put("client_id", clientId); @@ -3117,7 +3155,7 @@ public class RetailAppServiceImp implements RetailAppService { int accountDisplayCount = displayInfo.getIntValue("display_count"); if (accountDisplayCount < displayCount) { displayInfo.put("last_read_time", new Date()); - displayInfo.put("display_count", (accountDisplayCount+1)); + displayInfo.put("display_count", (accountDisplayCount + 1)); actPartnerReadMapper.update(displayInfo); return false; } diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java b/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java index 24810e092..d92cf4dd7 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java @@ -3,10 +3,7 @@ package au.com.royalpay.payment.manage.appclient.web; import au.com.royalpay.payment.core.exceptions.ParamInvalidException; import au.com.royalpay.payment.manage.activities.app_index.core.AppActService; import au.com.royalpay.payment.manage.activities.monsettledelay.core.ActMonDelaySettleService; -import au.com.royalpay.payment.manage.appclient.beans.AppClientBean; -import au.com.royalpay.payment.manage.appclient.beans.AppPaymentConfigBean; -import au.com.royalpay.payment.manage.appclient.beans.AppQueryBean; -import au.com.royalpay.payment.manage.appclient.beans.RetailAppMessage; +import au.com.royalpay.payment.manage.appclient.beans.*; import au.com.royalpay.payment.manage.appclient.core.RetailAppService; import au.com.royalpay.payment.manage.bill.bean.NewBillBean; import au.com.royalpay.payment.manage.bill.bean.QueryBillBean; @@ -206,7 +203,7 @@ public class RetailAppController { @GetMapping("/notice/unread") public List latestNotice(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { - return retailAppService.getLatestNotice(device,device.getIntValue("client_id")); + return retailAppService.getLatestNotice(device, device.getIntValue("client_id")); } /* 消息模块end */ @@ -774,32 +771,53 @@ public class RetailAppController { * @throws Exception */ @PutMapping("/account/phone/unbind") - public JSONObject unbindAccountPhone(@ModelAttribute(RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject params) throws Exception { + public JSONObject unbindAccountPhone(@ModelAttribute(RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject params) throws Exception { return retailAppService.unbindAccountPhone(device, params); } /** * 微信绑定 - * @param device + * + * @param device * @param params */ @PutMapping("/account/wechat/bind") - public JSONObject bindAccountWechat(@ModelAttribute(RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject params){ - return retailAppService.bindAccountWechat(device,params); + public JSONObject bindAccountWechat(@ModelAttribute(RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject params) { + return retailAppService.bindAccountWechat(device, params); } /** * 微信解绑 + * * @param device */ @PutMapping("/account/wechat/unbind") - public JSONObject unbindAccountWechat(@ModelAttribute(RETAIL_DEVICE) JSONObject device){ + public JSONObject unbindAccountWechat(@ModelAttribute(RETAIL_DEVICE) JSONObject device) { return retailAppService.unbindAccountWechat(device); } + /** + * Apple绑定 + * + * @param device + */ + @PutMapping("/account/apple/bind") + public JSONObject bindAccountApple(@ModelAttribute(RETAIL_DEVICE) JSONObject device, @Valid @RequestBody AppleLoginBean appleLoginBean) { + return retailAppService.bindAccountApple(device, appleLoginBean); + } + /** + * Apple解绑 + * + * @param device + */ + @PutMapping("/account/apple/unbind") + public JSONObject unbindAccountApple(@ModelAttribute(RETAIL_DEVICE) JSONObject device) { + return retailAppService.unbindAccountApple(device); + } + /** * 验证退款密码 @@ -918,9 +936,9 @@ public class RetailAppController { * @param device */ @PostMapping("/client/kyc_auth_file") - public JSONObject uploadKycAuthFiles(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestParam MultipartFile file, @RequestParam("fileType") String fileType)throws Exception{ + public JSONObject uploadKycAuthFiles(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestParam MultipartFile file, @RequestParam("fileType") String fileType) throws Exception { JSONObject fileInfo = attachmentClient.uploadFile(file, false); - retailAppService.uploadKycAuthFilesForApp(device, fileInfo,fileType); + retailAppService.uploadKycAuthFilesForApp(device, fileInfo, fileType); return fileInfo; } @@ -930,7 +948,7 @@ public class RetailAppController { * @param device */ @PostMapping("/client/auth_file/commit_to_kyc") - public void commitToKycAuthFiles(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device,@RequestBody JSONObject params) { + public void commitToKycAuthFiles(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject params) { retailAppService.commitAuthFilesToKyc(device, params); } @@ -960,12 +978,13 @@ public class RetailAppController { /** * 登录用户绑定信息(手机、第三方) + * * @param device * @return */ @GetMapping("/client/account/bind/infos") - public JSONObject findClientAccountBindStatusInfos(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device){ - return retailAppService.getAccountBindInfos(device); + public JSONObject findClientAccountBindStatusInfos(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { + return retailAppService.getAccountBindInfos(device); } } diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailValidationController.java b/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailValidationController.java index 909e0ab93..54fb00fff 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailValidationController.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailValidationController.java @@ -1,5 +1,6 @@ package au.com.royalpay.payment.manage.appclient.web; +import au.com.royalpay.payment.manage.appclient.beans.AppleLoginBean; import au.com.royalpay.payment.manage.appclient.beans.RetailLoginInfo; import au.com.royalpay.payment.manage.appclient.core.ManageAppService; import au.com.royalpay.payment.manage.appclient.core.RetailAppService; @@ -138,6 +139,35 @@ public class RetailValidationController implements ApplicationEventPublisherAwar return res; } + @PostMapping("/apple_signin") + public JSONObject mchAppleSignIn(@Valid @RequestBody AppleLoginBean appleLoginBean) { + return signInStatusManager.mchAppleSignIn(appleLoginBean); + } + + /** + * 微信绑定登录账号 + * + * @param params + * @return + */ + @PostMapping("/login/apple_bind") + public JSONObject appleLoginBind(@RequestBody JSONObject params) { + LoginInfo loginInfo = new LoginInfo(); + loginInfo.setLoginId(params.getString("loginId")); + loginInfo.setPassword(params.getString("password")); + String signKey = signInStatusManager.verifyClientAccountLogin(loginInfo, "apple"); + JSONObject account = signInStatusManager.getCurrentClient(signKey); + retailAppService.updateLoginClientAccountAppleId(account, params); + account = JSON.parseObject(account.toJSONString()); + JSONObject result = new JSONObject(); + account.put("sign_key", signKey); + result.put("account", account); + result.put("bind_status", true); + result.put("status", "success"); + this.publisher.publishEvent(new ClientLoginEvent(this, account.getIntValue("client_id"), account.getString("account_id"), RequestEnvironment.getClientIp(), "wechat")); + return result; + } + @GetMapping("/captcha") public JSONObject getCaptchaForDevice(@RequestParam(defaultValue = "false") boolean imgurl) throws IOException { String capText = RandomStringUtils.random(4, false, true); @@ -186,9 +216,9 @@ public class RetailValidationController implements ApplicationEventPublisherAwar @PostMapping("/send/{phone_number}/verify_code") @ResponseBody public JSONObject sendLoginMobileVerifyCode(@PathVariable("phone_number") String phoneNumber, - @RequestParam("nation_code") @NotEmpty(message = "nation code can't be null") String nationCode, - HttpServletRequest request) { - simpleClientApplyService.getAndSendLoginSmsCode(phoneNumber, nationCode, request); + @RequestParam("nation_code") @NotEmpty(message = "nation code can't be null") String nationCode, + HttpServletRequest request) { + simpleClientApplyService.getAndSendLoginSmsCode(phoneNumber, nationCode, request); return new JSONObject(); } @@ -201,58 +231,59 @@ public class RetailValidationController implements ApplicationEventPublisherAwar */ @PostMapping("/login/verify/{contact_phone}/verify_code") public JSONObject verifyLoginMobileCode(@PathVariable("contact_phone") String contactPhone, - @RequestParam("nation_code") @NotEmpty(message = "nation code can't be null") String nationCode, - @RequestBody JSONObject params, - @ModelAttribute(CommonConsts.MANAGER_DEVICE) JSONObject device, + @RequestParam("nation_code") @NotEmpty(message = "nation code can't be null") String nationCode, + @RequestBody JSONObject params, + @ModelAttribute(CommonConsts.MANAGER_DEVICE) JSONObject device, Errors errors) { HttpUtils.handleValidErrors(errors); JSONObject result = new JSONObject(); simpleClientApplyService.verifyLoginSMSCode(params.getString("verify_code"), contactPhone); String signKey = signInStatusManager.getClientInfoByPhoneStatusKey(contactPhone, nationCode); - if(signKey!=null){ + if (signKey != null) { JSONObject account = signInStatusManager.getCurrentClient(signKey); account = JSON.parseObject(account.toJSONString()); if (params.getString("devId") != null) { deviceSupport.validDeviceWithClient(account, params.getString("devId")); } account.put("sign_key", signKey); - result.put("account",account); - result.put("status","success"); + result.put("account", account); + result.put("status", "success"); result.put("bind_status", true); this.publisher.publishEvent(new ClientLoginEvent(this, account.getIntValue("client_id"), account.getString("account_id"), RequestEnvironment.getClientIp(), "MOBILE")); - }else{ - result.put("status","success"); + } else { + result.put("status", "success"); result.put("bind_status", false); - result.put("contact_phone",contactPhone); - result.put("nation_code",nationCode); + result.put("contact_phone", contactPhone); + result.put("nation_code", nationCode); } return result; } /** * 手机登录-绑定账号 + * * @param contactPhone * @param nationCode * @param params */ @PostMapping("/login/mobile/{contact_phone}/bind") - public JSONObject mobileLoginBind(@PathVariable("contact_phone")String contactPhone, - @RequestParam("nation_code") @NotEmpty(message = "nation code can't be null") String nationCode, - @RequestBody JSONObject params, - Errors errors){ + public JSONObject mobileLoginBind(@PathVariable("contact_phone") String contactPhone, + @RequestParam("nation_code") @NotEmpty(message = "nation code can't be null") String nationCode, + @RequestBody JSONObject params, + Errors errors) { HttpUtils.handleValidErrors(errors); LoginInfo loginInfo = new LoginInfo(); loginInfo.setLoginId(params.getString("loginId")); loginInfo.setPassword(params.getString("password")); - String signKey = signInStatusManager.verifyClientAccountLogin(loginInfo,"phone"); - signInStatusManager.verifyClientLoginPhoneBindCode(contactPhone,nationCode); + String signKey = signInStatusManager.verifyClientAccountLogin(loginInfo, "phone"); + signInStatusManager.verifyClientLoginPhoneBindCode(contactPhone, nationCode); JSONObject account = signInStatusManager.getCurrentClient(signKey); - retailAppService.updateLoginClientAccountPhone(account, contactPhone,nationCode); + retailAppService.updateLoginClientAccountPhone(account, contactPhone, nationCode); account.put("sign_key", signKey); account = JSON.parseObject(account.toJSONString()); JSONObject result = new JSONObject(); - result.put("account",account); + result.put("account", account); result.put("bind_status", true); this.publisher.publishEvent(new ClientLoginEvent(this, account.getIntValue("client_id"), account.getString("account_id"), RequestEnvironment.getClientIp(), "MOBILE")); return result; @@ -260,6 +291,7 @@ public class RetailValidationController implements ApplicationEventPublisherAwar /** * 商戶端App微信授权登录 + * * @param params * @return */ @@ -268,7 +300,7 @@ public class RetailValidationController implements ApplicationEventPublisherAwar Errors errors) { HttpUtils.handleValidErrors(errors); JSONObject account = signInStatusManager.clientAppWechatSignIn(params.getString("code")); - if(!account.getBoolean("bind_status")){ + if (!account.getBoolean("bind_status")) { deviceSupport.validDeviceWithClient(account, params.getString("app_openid")); return account; } @@ -278,26 +310,27 @@ public class RetailValidationController implements ApplicationEventPublisherAwar /** * 微信绑定登录账号 + * * @param params * @return */ @PostMapping("/login/wechat_bind") - public JSONObject wechatLoginBind(@RequestBody JSONObject params){ + public JSONObject wechatLoginBind(@RequestBody JSONObject params) { LoginInfo loginInfo = new LoginInfo(); loginInfo.setLoginId(params.getString("loginId")); loginInfo.setPassword(params.getString("password")); - String signKey = signInStatusManager.verifyClientAccountLogin(loginInfo,"wechat"); + String signKey = signInStatusManager.verifyClientAccountLogin(loginInfo, "wechat"); JSONObject wechatInfo = signInStatusManager.verifyClientLoginWechatBindCode(params.getString("wechat_openid")); JSONObject account = signInStatusManager.getCurrentClient(signKey); - params.put("nick_name",wechatInfo.getString("nick_name")); - params.put("union_id",wechatInfo.getString("union_id")); - retailAppService.updateLoginClientAccountOpenId(account,params); + params.put("nick_name", wechatInfo.getString("nick_name")); + params.put("union_id", wechatInfo.getString("union_id")); + retailAppService.updateLoginClientAccountOpenId(account, params); account = JSON.parseObject(account.toJSONString()); JSONObject result = new JSONObject(); account.put("sign_key", signKey); - result.put("account",account); + result.put("account", account); result.put("bind_status", true); - result.put("status","success"); + result.put("status", "success"); this.publisher.publishEvent(new ClientLoginEvent(this, account.getIntValue("client_id"), account.getString("account_id"), RequestEnvironment.getClientIp(), "wechat")); return result; } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.java index 854e38c19..fc868bd32 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.java @@ -28,7 +28,7 @@ public interface ClientAccountMapper { @AutoSql(SqlType.SELECT) @AdvanceSelect(addonWhereClause = "is_valid=1") - List findByPhone(@Param("contact_phone") String contact_phone,@Param("nation_code")String nation_code); + List findByPhone(@Param("contact_phone") String contact_phone, @Param("nation_code") String nation_code); @AutoSql(SqlType.SELECT) JSONObject findDetail(@Param("account_id") String accountId); @@ -51,6 +51,10 @@ public interface ClientAccountMapper { @AdvanceSelect(addonWhereClause = "is_valid=1", excludeColumns = {"salt", "password_hash"}) JSONObject findByAppOpenId(@Param("wxapp_openid") String openId); + @AutoSql(SqlType.SELECT) + @AdvanceSelect(addonWhereClause = "is_valid=1", excludeColumns = {"salt", "password_hash"}) + JSONObject findByAppleUserId(@Param("apple_userid") String appleUserId); + @AutoSql(SqlType.SELECT) @AdvanceSelect(addonWhereClause = "is_valid=1", excludeColumns = {"salt", "password_hash"}) JSONObject findByWxUnioinId(@Param("wx_unionid") String wx_unionid); @@ -85,22 +89,23 @@ public interface ClientAccountMapper { /** * 获取绑定微信的最新账号 + * * @param unionId * @return */ - JSONObject findOneByUnionIdAndCreateTimeDesc(@Param("wx_unionid")String unionId); + JSONObject findOneByUnionIdAndCreateTimeDesc(@Param("wx_unionid") String unionId); - JSONObject findOneByPhoneAndCreateTimeDesc(@Param("contact_phone")String contactPhone,@Param("nation_code")String nationCode); + JSONObject findOneByPhoneAndCreateTimeDesc(@Param("contact_phone") String contactPhone, @Param("nation_code") String nationCode); @AutoSql(SqlType.SELECT) @AdvanceSelect(addonWhereClause = "is_valid=1", excludeColumns = {"salt", "password_hash"}) - List findByWechatOpenId(@Param("wechat_openid")String openid); + List findByWechatOpenId(@Param("wechat_openid") String openid); @AutoSql(SqlType.SELECT) @AdvanceSelect(addonWhereClause = "is_valid=1", excludeColumns = {"salt", "password_hash"}) - List findByWechatUnionId(@Param("wx_unionid")String unionId); + List findByWechatUnionId(@Param("wx_unionid") String unionId); @AutoSql(SqlType.SELECT) - JSONObject findRSvcClientInfo(@Param("account_id")String accountId); + JSONObject findRSvcClientInfo(@Param("account_id") String accountId); } diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInAccountService.java b/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInAccountService.java index 7e44371cd..5cc63f8a7 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInAccountService.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInAccountService.java @@ -48,6 +48,8 @@ public interface SignInAccountService { JSONObject clientWechatAppSignIn(String openId); + JSONObject clientAppleSignIn(String appleUserId); + JSONObject clientWechatAppSignInByUnionId(String unionId); String ForgetPassword(String partner_code) throws Exception; diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInStatusManager.java b/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInStatusManager.java index 94ada22e5..b6ef0c88e 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInStatusManager.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/core/SignInStatusManager.java @@ -1,5 +1,6 @@ package au.com.royalpay.payment.manage.signin.core; +import au.com.royalpay.payment.manage.appclient.beans.AppleLoginBean; import au.com.royalpay.payment.manage.signin.beans.LoginInfo; import com.alibaba.fastjson.JSONObject; import org.springframework.web.servlet.ModelAndView; @@ -50,6 +51,8 @@ public interface SignInStatusManager { JSONObject partnerWechatAppSignIn(String code); + JSONObject mchAppleSignIn(AppleLoginBean appleLoginBean); + String clientWechatSignIn(String openid); JSONObject newClientWechatSignInQRCode(); diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInAccountServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInAccountServiceImpl.java index 47176c010..d8d6fd340 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInAccountServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInAccountServiceImpl.java @@ -394,6 +394,17 @@ public class SignInAccountServiceImpl implements SignInAccountService, Applicati return account; } + @Override + public JSONObject clientAppleSignIn(String appleUserId) { + JSONObject account = clientAccountMapper.findByAppleUserId(appleUserId); + if (account == null) { + return null; + } + publisher.publishEvent( + new ClientLoginEvent(this, account.getIntValue("client_id"), account.getString("account_id"), RequestEnvironment.getClientIp(), "wechat")); + return account; + } + @Override public JSONObject clientWechatAppSignInByUnionId(String unionId) { if (StringUtils.isBlank(unionId) || unionId == "" || unionId == null) { @@ -498,7 +509,7 @@ public class SignInAccountServiceImpl implements SignInAccountService, Applicati "company_phone", "suburb", "postcode", "state", "contact_person", "contact_phone", "contact_email", "short_name", "logo_url", "enable_refund", "enable_refund_auth", "retail_surcharge", "require_custinfo", "require_remark", "logo_thumbnail", "creator", "create_time", "approver", "approve_result", "approve_time", "open_status", "timezone", "has_children", "source", "customer_surcharge_rate", "enable_alipay", "enable_wechat", - "enable_bestpay", "manual_settle", "skip_clearing", "mail_confirm", "surcharge_mode", "company_photo", "store_photo", "company_website", "contact_job", "sub_manage","enable_rpaypmt_card","enable_rpaypmt_dd"}; + "enable_bestpay", "manual_settle", "skip_clearing", "mail_confirm", "surcharge_mode", "company_photo", "store_photo", "company_website", "contact_job", "sub_manage", "enable_rpaypmt_card", "enable_rpaypmt_dd"}; for (String col : columns) { simpleClient.put(col, client.get(col)); } diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInStatusManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInStatusManagerImpl.java index 2acc88797..0f9952ecc 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInStatusManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/SignInStatusManagerImpl.java @@ -1,5 +1,6 @@ package au.com.royalpay.payment.manage.signin.core.impls; +import au.com.royalpay.payment.manage.appclient.beans.AppleLoginBean; import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper; import au.com.royalpay.payment.manage.signin.beans.LoginInfo; import au.com.royalpay.payment.manage.signin.core.SignInAccountService; @@ -10,6 +11,8 @@ import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.ForbiddenException; import au.com.royalpay.payment.tools.permission.enums.ManagerRole; import au.com.royalpay.payment.tools.utils.QRCodeUtils; +import au.com.royalpay.payment.tools.utils.apple.AppleAuthUtils; +import au.com.royalpay.payment.tools.utils.apple.UserClaim; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; @@ -38,7 +41,7 @@ public class SignInStatusManagerImpl implements SignInStatusManager { @Resource private ClientAccountMapper clientAccountMapper; private final String CLIENT_LOGIN_WECHAT_BIND_PREFIX = "CLIENT_LOGIN_WECHAT_BIND_PREFIX"; - private final String CLIENT_LOGIN_PHONE_BIND_PREFIX = "CLIENT_LOGIN_PHONE_BIND_PREFIX"; + private final String CLIENT_LOGIN_PHONE_BIND_PREFIX = "CLIENT_LOGIN_PHONE_BIND_PREFIX"; @Override public JSONObject getCurrentManager(String statusKey) { @@ -63,9 +66,7 @@ public class SignInStatusManagerImpl implements SignInStatusManager { return null; } op.expire(30, TimeUnit.MINUTES); - - JSONObject account = signInAccountService.getClient(accountId); - return account; + return signInAccountService.getClient(accountId); } private String partnerLoginRedisKey(String statusKey) { @@ -86,7 +87,7 @@ public class SignInStatusManagerImpl implements SignInStatusManager { JSONObject account = clientAccountMapper.findOneByPhoneAndCreateTimeDesc(phone, "+" + nationCode); if (account == null) { String expireMin = "5"; - stringRedisTemplate.boundValueOps(getClientLoginPhoneBindRedisKey(phone,nationCode)).set(phone, Long.parseLong(expireMin), TimeUnit.MINUTES); + stringRedisTemplate.boundValueOps(getClientLoginPhoneBindRedisKey(phone, nationCode)).set(phone, Long.parseLong(expireMin), TimeUnit.MINUTES); return null; } stringRedisTemplate.boundValueOps(partnerLoginRedisKey(statusKey)).set(account.getString("account_id") + "", 30, TimeUnit.MINUTES); @@ -99,11 +100,14 @@ public class SignInStatusManagerImpl implements SignInStatusManager { @Override public String verifyClientAccountLogin(LoginInfo loginInfo, String verfiyType) { - JSONObject account = signInAccountService.clientAccountCheck(loginInfo);; + JSONObject account = signInAccountService.clientAccountCheck(loginInfo); if ("phone".equals(verfiyType)) { if (account.containsKey("contact_phone")) { throw new BadRequestException("The account has been linked to the phone number!"); } + } else if (StringUtils.equalsIgnoreCase("apple", verfiyType) + && StringUtils.isNotEmpty(account.getString("apple_userid"))) { + throw new BadRequestException("The account has been binded and exist appleId!"); } else { if (account.containsKey("wechat_openid")) { throw new BadRequestException("The account has been linked to the wechat!"); @@ -286,6 +290,31 @@ public class SignInStatusManagerImpl implements SignInStatusManager { return account; } + @Override + public JSONObject mchAppleSignIn(AppleLoginBean appleLoginBean) { + UserClaim userClaim = AppleAuthUtils.verifyIdentifyToken(appleLoginBean.getIdentityToken()); + if (!StringUtils.equalsIgnoreCase(userClaim.getSub(), appleLoginBean.getUser())) { + throw new ForbiddenException("apple userinfo is error"); + } + JSONObject account = signInAccountService.clientAppleSignIn(userClaim.getSub()); + if (account == null || account.isEmpty()) { + return new JSONObject() {{ + put("apple_userid", userClaim.getSub()); + put("bind_status", false); + }}; + } + String statusKey = newStatusKey(); + JSONObject result = new JSONObject(); + stringRedisTemplate.boundValueOps(partnerLoginRedisKey(statusKey)).set(account.getString("account_id") + "", 30, TimeUnit.MINUTES); + account = getCurrentClient(statusKey); + account.put("sign_key", statusKey); + result.put("account", account); + account.put("apple_userid", userClaim.getSub()); + result.put("bind_status", true); + result.put("status", "success"); + return result; + } + @Override public String clientWechatSignIn(String openid) { JSONObject account = signInAccountService.clientWechatSignIn(openid); @@ -391,21 +420,21 @@ public class SignInStatusManagerImpl implements SignInStatusManager { @Override public JSONObject clientAppWechatSignIn(String code) { JSONObject user = mpClientAppWechatApiProvider.getApi("merchant-app").appLoginUser(code); - if(user==null){ + if (user == null) { throw new BadRequestException("WeChat users do not exist"); } String unionId = user.getString("unionid"); String openId = user.getString("openid"); JSONObject account = signInAccountService.clientWechatOneSignIn(unionId); if (account == null) { - JSONObject wechatUserInfo = mpClientAppWechatApiProvider.getApi("merchant-app").appUserInfo(openId,user.getString("access_token")); + JSONObject wechatUserInfo = mpClientAppWechatApiProvider.getApi("merchant-app").appUserInfo(openId, user.getString("access_token")); JSONObject res = new JSONObject(); String nickName = wechatUserInfo.getString("nickname"); res.put("bind_status", false); res.put("app_openid", openId); res.put("status", "success"); String expireMin = "5"; - stringRedisTemplate.boundValueOps(getClientLoginWechatBindRedisKey(openId)).set(openId+"&"+nickName+"&"+unionId, Long.parseLong(expireMin), TimeUnit.MINUTES); + stringRedisTemplate.boundValueOps(getClientLoginWechatBindRedisKey(openId)).set(openId + "&" + nickName + "&" + unionId, Long.parseLong(expireMin), TimeUnit.MINUTES); return res; } String statusKey = newStatusKey(); @@ -413,20 +442,20 @@ public class SignInStatusManagerImpl implements SignInStatusManager { stringRedisTemplate.boundValueOps(partnerLoginRedisKey(statusKey)).set(account.getString("account_id") + "", 30, TimeUnit.MINUTES); account = getCurrentClient(statusKey); account.put("sign_key", statusKey); - result.put("account",account); + result.put("account", account); result.put("app_openid", unionId); result.put("bind_status", true); result.put("status", "success"); return result; } - private String getClientLoginWechatBindRedisKey(String openId){ - return "login:"+":"+CLIENT_LOGIN_WECHAT_BIND_PREFIX + "&"+openId; + private String getClientLoginWechatBindRedisKey(String openId) { + return "login:" + ":" + CLIENT_LOGIN_WECHAT_BIND_PREFIX + "&" + openId; } @Override - public JSONObject verifyClientLoginWechatBindCode(String openId){ + public JSONObject verifyClientLoginWechatBindCode(String openId) { String rediskey = getClientLoginWechatBindRedisKey(openId); String codeValue = stringRedisTemplate.boundValueOps(rediskey).get(); if (codeValue == null || !codeValue.split("&")[0].equals(openId)) { @@ -435,18 +464,18 @@ public class SignInStatusManagerImpl implements SignInStatusManager { String nickName = codeValue.split("&")[1]; String unionId = codeValue.split("&")[2]; stringRedisTemplate.delete(rediskey); - return new JSONObject(){{ - put("nick_name",nickName); - put("union_id",unionId); + return new JSONObject() {{ + put("nick_name", nickName); + put("union_id", unionId); }}; } - private String getClientLoginPhoneBindRedisKey(String phone,String nationCode){ - return "login:"+CLIENT_LOGIN_PHONE_BIND_PREFIX + "&"+nationCode+"&"+phone; + private String getClientLoginPhoneBindRedisKey(String phone, String nationCode) { + return "login:" + CLIENT_LOGIN_PHONE_BIND_PREFIX + "&" + nationCode + "&" + phone; } - public void verifyClientLoginPhoneBindCode(String phone,String nationCode){ - String rediskey = getClientLoginPhoneBindRedisKey(phone,nationCode); + public void verifyClientLoginPhoneBindCode(String phone, String nationCode) { + String rediskey = getClientLoginPhoneBindRedisKey(phone, nationCode); String codeValue = stringRedisTemplate.boundValueOps(rediskey).get(); if (codeValue == null || !codeValue.equals(phone)) { throw new BadRequestException("The phone number is for application binding"); @@ -455,7 +484,6 @@ public class SignInStatusManagerImpl implements SignInStatusManager { } - private void lockRandomCodeId(String codeId) { stringRedisTemplate.boundValueOps(redisPrefix + "partner_signin" + codeId).set(codeId, 30, TimeUnit.SECONDS); }