diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/core/ManageAppService.java b/src/main/java/au/com/royalpay/payment/manage/appclient/core/ManageAppService.java index 515113723..dbc27dfa4 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/core/ManageAppService.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/core/ManageAppService.java @@ -76,4 +76,12 @@ public interface ManageAppService { void updateProduct(JSONObject device, ProductBean productBean); void deleteProduct(JSONObject device, String commodity_id); + + void bindAccountEmail(JSONObject device,JSONObject email); + + void updateAccountEmail(JSONObject device,JSONObject codekey); + + void bindAccountPhone(JSONObject device,JSONObject phone); + + void updateAccountPhone(JSONObject device,JSONObject codekey); } 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 9b99846f7..f733aa1a8 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 @@ -169,4 +169,22 @@ public interface RetailAppService { void cancelCouponAccuessLog(String accuess_id, String remark); void submitMaterial(JSONObject material, JSONObject device); + + void bindAccountEmail(JSONObject device,JSONObject email); + + void updateAccountEmail(JSONObject device,JSONObject codekey); + + void bindAccountPhone(JSONObject device,JSONObject phone); + + void updateAccountPhone(JSONObject device,JSONObject codekey); + + /** + * 退款密码 + */ + void verifyRefundPassword(JSONObject device, JSONObject json); + + /** + * 退款密码 + */ + void resetRefundPassword(JSONObject device, JSONObject json); } diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/ManageAppServiceImp.java b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/ManageAppServiceImp.java index c8ee16770..2de0ebf03 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/ManageAppServiceImp.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/ManageAppServiceImp.java @@ -1,5 +1,6 @@ package au.com.royalpay.payment.manage.appclient.core.impls; +import au.com.royalpay.payment.core.exceptions.EmailException; import au.com.royalpay.payment.manage.appclient.beans.AppMerchantBean; import au.com.royalpay.payment.manage.appclient.core.ManageAppService; import au.com.royalpay.payment.manage.bdprize.core.BDPrizeService; @@ -16,26 +17,37 @@ import au.com.royalpay.payment.manage.merchants.beans.ClientAuthFilesInfo; import au.com.royalpay.payment.manage.merchants.beans.ClientRegisterInfo; import au.com.royalpay.payment.manage.merchants.beans.PartnerQuery; import au.com.royalpay.payment.manage.merchants.core.ClientManager; +import au.com.royalpay.payment.manage.notice.core.MailService; import au.com.royalpay.payment.manage.product.beans.ProductBean; import au.com.royalpay.payment.manage.product.core.ClientProduct; import au.com.royalpay.payment.manage.signin.beans.ChangePwdBean; import au.com.royalpay.payment.manage.signin.core.ManagerAccountsService; import au.com.royalpay.payment.manage.signin.core.SignInAccountService; +import au.com.royalpay.payment.manage.support.sms.SmsSender; import au.com.royalpay.payment.tools.device.DeviceSupport; import au.com.royalpay.payment.tools.device.ManageDeviceSupport; import au.com.royalpay.payment.tools.device.support.DeviceRegister; import au.com.royalpay.payment.tools.env.PlatformEnvironment; +import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.ForbiddenException; +import au.com.royalpay.payment.tools.exceptions.ServerErrorException; +import au.com.royalpay.payment.tools.threadpool.RoyalThreadPoolExecutor; import com.alibaba.fastjson.JSONObject; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.ibatis.annotations.Param; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring4.SpringTemplateEngine; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Service @@ -67,6 +79,19 @@ public class ManageAppServiceImp implements ManageAppService { private FinancialBDConfigMapper financialBDConfigMapper; @Resource private ClientProduct clientProduct; + @Resource + private StringRedisTemplate stringRedisTemplate; + @Resource + private MailService mailService; + @Resource + private RoyalThreadPoolExecutor royalThreadPoolExecutor; + @Resource + private SpringTemplateEngine thymeleaf; + @Resource + private SmsSender smsSender; + private final String BIND_MANAGE_EMAIL_PREFIX = "BIND_MANAGE_EMAIL"; + private final String BIND_MANAGE_PHONE_PREFIX = "BIND_MANAGE_PHONE"; + private final int BIND_PHONE_TEMPLID = 126978; @Override @@ -429,4 +454,106 @@ public class ManageAppServiceImp implements ManageAppService { JSONObject manager = managerMapper.findById(device.getString("manager_id")); clientProduct.deleteProduct(manager, commodity_id); } + + @Override + public void bindAccountEmail(JSONObject device, JSONObject email) { + String codeKey = device.getString("manager_id"); + String codeKeyValueRedis = stringRedisTemplate.boundValueOps(getUpdateManageEmailKey(codeKey)).get(); + if(StringUtils.isNotEmpty(codeKeyValueRedis)){ + throw new BadRequestException("Captcha has been sent.Please check your email or try again in 5 minutes."); + } + String codeKeyValue = RandomStringUtils.random(6, false, true); + Context ctx = new Context(); + JSONObject manager = managerMapper.findById(device.getString("manager_id")); + ctx.setVariable("account",manager); + ctx.setVariable("captcha",codeKeyValue); + final String content = thymeleaf.process("mail/account_bind_email.html", ctx); + royalThreadPoolExecutor.execute(() -> { + try { + mailService.sendEmail("Your account is in the process of binding a mailbox", email.getString("contact_email"), + "", content); + } catch (Exception e) { + throw new EmailException("Email Sending Failed", e); + } + }); + stringRedisTemplate.boundValueOps(getUpdateManageEmailKey(codeKey)).set(codeKeyValue+"&"+email.getString("contact_email"), 5, TimeUnit.MINUTES); + } + + @Override + public void updateAccountEmail(JSONObject device, JSONObject params) { + String key = stringRedisTemplate.boundValueOps(getUpdateManageEmailKey(device.getString("manager_id"))).get(); + if(key == null){ + throw new BadRequestException("Captcha has expired"); + } + String captcha = key.split("&")[0]; + String email = key.split("&")[1]; + if(!StringUtils.equals(captcha,params.getString("captcha"))){ + throw new BadRequestException("Verification code is wrong"); + } + JSONObject account = new JSONObject(); + account.put("manager_id",device.getString("manager_id")); + account.put("email",email); + managerMapper.update(account); + deleteManageEmailKey(device.getString("manager_id")); + } + + @Override + public void bindAccountPhone(JSONObject device, JSONObject phone) { + String codeKey = device.getString("manager_id"); + String codeKeyValueRedis = stringRedisTemplate.boundValueOps(getUpdateManagePhoneKey(codeKey)).get(); + if(StringUtils.isNotEmpty(codeKeyValueRedis)){ + throw new BadRequestException("Captcha has been sent.Please check your phone or try again in 5 minutes."); + } + String codeKeyValue = RandomStringUtils.random(6, false, true); + String nationCode = phone.getString("nation_code"); + String phoneNumber = phone.getString("contact_phone"); + ArrayList param = new ArrayList<>(); + param.add("绑定手机号"); + param.add(codeKeyValue); + String expireMin = "5"; + param.add(expireMin); + try { + smsSender.getSender().sendWithParam(nationCode.trim(), phoneNumber, BIND_PHONE_TEMPLID, param, "RoyalPay", "", ""); + } catch (Exception e) { + e.printStackTrace(); + throw new ServerErrorException("Phone number is wrong.Please try again."); + } + stringRedisTemplate.boundValueOps(getUpdateManagePhoneKey(codeKey)).set(codeKeyValue+"&"+nationCode+"&"+phoneNumber, Long.parseLong(expireMin), TimeUnit.MINUTES); + } + + @Override + public void updateAccountPhone(JSONObject device, JSONObject params) { + String key = stringRedisTemplate.boundValueOps(getUpdateManagePhoneKey(device.getString("manager_id"))).get(); + if(key == null){ + throw new BadRequestException("Captcha has expired"); + } + String captcha = key.split("&")[0]; + String nation_code = key.split("&")[1]; + String contact_phone = key.split("&")[2]; + if(!StringUtils.equals(captcha,params.getString("captcha"))){ + throw new BadRequestException("Verification code is wrong"); + } + JSONObject account = new JSONObject(); + account.put("manager_id",device.getString("manager_id")); + account.put("contact_phone",contact_phone); + account.put("nation_code","+" + nation_code); + managerMapper.update(account); + deleteManagePhoneKey(device.getString("manager_id")); + } + + private void deleteManageEmailKey(String codeKey){ + stringRedisTemplate.delete(getUpdateManageEmailKey(codeKey)); + } + + private void deleteManagePhoneKey(String codeKey){ + stringRedisTemplate.delete(getUpdateManagePhoneKey(codeKey)); + } + + private String getUpdateManageEmailKey(String codeKey){ + return BIND_MANAGE_EMAIL_PREFIX+codeKey; + } + + private String getUpdateManagePhoneKey(String codeKey){ + return BIND_MANAGE_PHONE_PREFIX+codeKey; + } } 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 a10a32564..44761a752 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 @@ -1,6 +1,7 @@ package au.com.royalpay.payment.manage.appclient.core.impls; import au.com.royalpay.payment.core.PaymentApi; +import au.com.royalpay.payment.core.exceptions.EmailException; 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; @@ -15,12 +16,7 @@ import au.com.royalpay.payment.manage.mappers.log.*; import au.com.royalpay.payment.manage.mappers.notice.NoticePartnerMapper; import au.com.royalpay.payment.manage.mappers.payment.OrderMapper; import au.com.royalpay.payment.manage.mappers.payment.TransactionMapper; -import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper; -import au.com.royalpay.payment.manage.mappers.system.ClientDeviceTokenMapper; -import au.com.royalpay.payment.manage.mappers.system.ClientMapper; -import au.com.royalpay.payment.manage.mappers.system.ClientSettleDelayConfMapper; -import au.com.royalpay.payment.manage.mappers.system.CustomerMapper; -import au.com.royalpay.payment.manage.mappers.system.ManagerCustomerRelationAlipayMapper; +import au.com.royalpay.payment.manage.mappers.system.*; import au.com.royalpay.payment.manage.merchants.beans.ClientAuthFilesInfo; import au.com.royalpay.payment.manage.merchants.beans.ClientUpdateInfo; import au.com.royalpay.payment.manage.merchants.core.ClientConfigService; @@ -28,6 +24,7 @@ import au.com.royalpay.payment.manage.merchants.core.ClientManager; import au.com.royalpay.payment.manage.merchants.core.ClientModifySupport; import au.com.royalpay.payment.manage.merchants.entity.impls.SwitchPermissionModify; import au.com.royalpay.payment.manage.notice.beans.NoticeInfo; +import au.com.royalpay.payment.manage.notice.core.MailService; import au.com.royalpay.payment.manage.notice.core.NoticeManage; import au.com.royalpay.payment.manage.notice.core.NoticePartner; import au.com.royalpay.payment.manage.openim.core.CustomerServiceService; @@ -40,6 +37,7 @@ import au.com.royalpay.payment.manage.riskbusiness.enums.RiskResultTypeEnum; import au.com.royalpay.payment.manage.signin.beans.ChangePwdBean; import au.com.royalpay.payment.manage.signin.core.SignInAccountService; import au.com.royalpay.payment.manage.signin.core.impls.SignInAccountServiceImpl; +import au.com.royalpay.payment.manage.support.sms.SmsSender; import au.com.royalpay.payment.manage.tradelog.beans.TradeLogQuery; import au.com.royalpay.payment.manage.tradelog.core.TradeLogService; import au.com.royalpay.payment.manage.tradelog.refund.RefundService; @@ -58,7 +56,9 @@ import au.com.royalpay.payment.tools.merchants.beans.QRCodeConfig; import au.com.royalpay.payment.tools.merchants.beans.UpdateSurchargeDTO; 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.PageListUtils; +import au.com.royalpay.payment.tools.utils.PasswordUtils; import au.com.royalpay.payment.tools.utils.QRCodeUtils; import au.com.royalpay.payment.tools.utils.TimeZoneUtils; @@ -69,7 +69,9 @@ import com.github.miemiedev.mybatis.paginator.domain.Order; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; import com.github.miemiedev.mybatis.paginator.domain.PageList; +import com.github.qcloudsms.httpclient.HTTPException; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; @@ -78,9 +80,14 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.slf4j.LoggerFactory; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring4.SpringTemplateEngine; +import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DateFormat; @@ -186,6 +193,19 @@ public class RetailAppServiceImp implements RetailAppService { private RiskBusinessService riskBusinessService; @Resource private RiskUploadService riskUploadService; + @Resource + private MailService mailService; + @Resource + private RoyalThreadPoolExecutor royalThreadPoolExecutor; + @Resource + private SpringTemplateEngine thymeleaf; + @Resource + private StringRedisTemplate stringRedisTemplate; + @Resource + private SmsSender smsSender; + private final String BIND_ACCOUNT_EMAIL_PREFIX = "BIND_ACCOUNT_EMAIL"; + private final String BIND_ACCOUNT_PHONE_PREFIX = "BIND_ACCOUNT_PHONE"; + private final int BIND_PHONE_TEMPLID = 126978; private Map senderMap = new HashMap<>(); private final String fileName[] = { "client_bank_file", "client_id_file", "client_company_file" }; @@ -1900,4 +1920,144 @@ public class RetailAppServiceImp implements RetailAppService { RiskResultTypeEnum.WAIT_FOR_AUDIT.getResultType()); } + @Override + public void bindAccountEmail(JSONObject device, JSONObject email) { + String codeKey = device.getString("account_id"); + String codeKeyValueRedis = stringRedisTemplate.boundValueOps(getUpdateAccountEmailKey(codeKey)).get(); + if(StringUtils.isNotEmpty(codeKeyValueRedis)){ + throw new BadRequestException("Captcha has been sent.Please check your email or try again in 5 minutes."); + } + String codeKeyValue = RandomStringUtils.random(6, false, true); + Context ctx = new Context(); + JSONObject account = clientAccountMapper.findById(device.getString("account_id")); + ctx.setVariable("account",account); + ctx.setVariable("captcha",codeKeyValue); + final String content = thymeleaf.process("mail/account_bind_email.html", ctx); + royalThreadPoolExecutor.execute(() -> { + try { + mailService.sendEmail("Your account is in the process of binding a mailbox", email.getString("contact_email"), + "", content); + } catch (Exception e) { + throw new EmailException("Email Sending Failed", e); + } + }); + stringRedisTemplate.boundValueOps(getUpdateAccountEmailKey(codeKey)).set(codeKeyValue+"&"+email.getString("contact_email"), 5, TimeUnit.MINUTES); + } + + @Override + public void updateAccountEmail(JSONObject device, JSONObject params) { + String key = stringRedisTemplate.boundValueOps(getUpdateAccountEmailKey(device.getString("account_id"))).get(); + if(key == null){ + throw new BadRequestException("Captcha has expired"); + } + String captcha = key.split("&")[0]; + String email = key.split("&")[1]; + if(!StringUtils.equals(captcha,params.getString("captcha"))){ + throw new BadRequestException("Verification code is wrong"); + } + JSONObject account = new JSONObject(); + account.put("account_id",device.getString("account_id")); + account.put("contact_email",email); + clientAccountMapper.update(account); + deleteAccountEmailKey(device.getString("account_id")); + } + + @Override + public void bindAccountPhone(JSONObject device, JSONObject phone) { + String codeKey = device.getString("account_id"); + String codeKeyValueRedis = stringRedisTemplate.boundValueOps(getUpdateAccountPhoneKey(codeKey)).get(); + if(StringUtils.isNotEmpty(codeKeyValueRedis)){ + throw new BadRequestException("Captcha has been sent.Please check your phone or try again in 5 minutes."); + } + String codeKeyValue = RandomStringUtils.random(6, false, true); + String nationCode = phone.getString("nation_code"); + String phoneNumber = phone.getString("contact_phone"); + ArrayList param = new ArrayList<>(); + param.add("绑定手机号"); + param.add(codeKeyValue); + String expireMin = "5"; + param.add(expireMin); + try { + smsSender.getSender().sendWithParam(nationCode.trim(), phoneNumber, BIND_PHONE_TEMPLID, param, "RoyalPay", "", ""); + } catch (Exception e) { + e.printStackTrace(); + throw new ServerErrorException("Phone number is wrong.Please try again."); + } + stringRedisTemplate.boundValueOps(getUpdateAccountPhoneKey(codeKey)).set(codeKeyValue+"&"+nationCode+"&"+phoneNumber, Long.parseLong(expireMin), TimeUnit.MINUTES); + } + + @Override + public void updateAccountPhone(JSONObject device, JSONObject params) { + String key = stringRedisTemplate.boundValueOps(getUpdateAccountPhoneKey(device.getString("account_id"))).get(); + if(key == null){ + throw new BadRequestException("Captcha has expired"); + } + String captcha = key.split("&")[0]; + String nation_code = key.split("&")[1]; + String contact_phone = key.split("&")[2]; + if(!StringUtils.equals(captcha,params.getString("captcha"))){ + throw new BadRequestException("Verification code is wrong"); + } + JSONObject account = new JSONObject(); + account.put("account_id",device.getString("account_id")); + account.put("contact_phone",contact_phone); + account.put("nation_code","+" + nation_code); + clientAccountMapper.update(account); + deleteAccountPhoneKey(device.getString("account_id")); + } + + @Override + public void verifyRefundPassword(JSONObject device, JSONObject json) { + String clientType = device.getString("client_type"); + deviceSupport.findRegister(clientType); + JSONObject clientConfig = clientConfigService.find(device.getIntValue("client_id")); + String needVerifyPassword = json.getString("refund_password"); + String refundPwdSalt = clientConfig.getString("refund_pwd_salt"); + if (!StringUtils.equals(clientConfig.getString("refund_pwd"), PasswordUtils.hashPwd(needVerifyPassword, refundPwdSalt))) { + throw new BadRequestException("Incorrect refund password"); + } + } + + @Override + @Transactional + public void resetRefundPassword(JSONObject device, JSONObject json) { + String clientType = device.getString("client_type"); + deviceSupport.findRegister(clientType); + JSONObject account = clientAccountMapper.findById(device.getString("account_id")); + if (PartnerRole.getRole(account.getIntValue("role")) != PartnerRole.ADMIN) { + throw new BadRequestException("You have no permission"); + } + verifyRefundPassword(device, json); + String newSalt = PasswordUtils.newSalt(); + String newPassWord = json.getString("new_refund_password"); + if (!StringUtils.isNumeric(newPassWord)) { + throw new BadRequestException("Refund password must be pure number"); + } + String newPwdHash = PasswordUtils.hashPwd(newPassWord, newSalt); + if (StringUtils.equals(newPwdHash, PasswordUtils.hashPwd(json.getString("refund_password"), newSalt))) { + throw new BadRequestException("Old and new passwords cannot be duplicated"); + } + JSONObject update = new JSONObject(); + update.put("client_id", device.getIntValue("client_id")); + update.put("refund_pwd", newPwdHash); + update.put("refund_pwd_salt", newSalt); + clientConfigService.update(update); + } + + private void deleteAccountEmailKey(String codeKey){ + stringRedisTemplate.delete(getUpdateAccountEmailKey(codeKey)); + } + + private void deleteAccountPhoneKey(String codeKey){ + stringRedisTemplate.delete(getUpdateAccountPhoneKey(codeKey)); + } + + private String getUpdateAccountEmailKey(String codeKey){ + return BIND_ACCOUNT_EMAIL_PREFIX+codeKey; + } + + private String getUpdateAccountPhoneKey(String codeKey){ + return BIND_ACCOUNT_PHONE_PREFIX+codeKey; + } + } diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/web/ManageAppController.java b/src/main/java/au/com/royalpay/payment/manage/appclient/web/ManageAppController.java index 6ceb58eac..7b1825688 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/web/ManageAppController.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/web/ManageAppController.java @@ -30,6 +30,8 @@ import java.util.Date; import java.util.List; import java.util.Map; +import static au.com.royalpay.payment.tools.CommonConsts.RETAIL_DEVICE; + @AppClientController @RequestMapping("/api/v1.0/manage/app") @@ -200,4 +202,48 @@ public class ManageAppController { manageAppService.deleteProduct(device, commodity_id); } + /** + * 接收关联邮箱的验证码 + * @param device + * @param email contact_email + * @throws Exception + */ + @RequestMapping(value = "/account/email",method = RequestMethod.PUT) + public void bindAccountEmail(@ModelAttribute(CommonConsts.MANAGER_DEVICE) JSONObject device,@RequestBody JSONObject email){ + manageAppService.bindAccountEmail(device,email); + } + + /** + * 关联邮箱 + * @param device + * @param params 验证码 + * @throws Exception + */ + @RequestMapping(value = "/account/email/bind",method = RequestMethod.PUT) + public void updateAccountEmail(@ModelAttribute(CommonConsts.MANAGER_DEVICE) JSONObject device,@RequestBody JSONObject params){ + manageAppService.updateAccountEmail(device,params); + } + + /** + * 接收关联手机的验证码 + * @param device + * @param phone contact_phone + * @throws Exception + */ + @RequestMapping(value = "/account/phone",method = RequestMethod.PUT) + public void bindAccountPhone(@ModelAttribute(CommonConsts.MANAGER_DEVICE) JSONObject device,@RequestBody JSONObject phone) { + manageAppService.bindAccountPhone(device,phone); + } + + /** + * 关联手机 + * @param device + * @param params 验证码 + * @throws Exception + */ + @RequestMapping(value = "/account/phone/bind",method = RequestMethod.PUT) + public void updateAccountPhone(@ModelAttribute(CommonConsts.MANAGER_DEVICE) JSONObject device,@RequestBody JSONObject params){ + manageAppService.updateAccountPhone(device,params); + } + } 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 740cd6c6b..5c65cc6f1 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 @@ -33,7 +33,6 @@ import au.com.royalpay.payment.tools.merchants.beans.UpdateSurchargeDTO; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -644,4 +643,64 @@ public class RetailAppController { return attachmentClient.uploadFile(file,false); } + /** + * 接收关联邮箱的验证码 + * @param device + * @param email contact_email + * @throws Exception + */ + @RequestMapping(value = "/account/email",method = RequestMethod.PUT) + public void bindAccountEmail(@ModelAttribute(RETAIL_DEVICE) JSONObject device,@RequestBody JSONObject email) throws Exception { + retailAppService.bindAccountEmail(device,email); + } + + /** + * 关联邮箱 + * @param device + * @param params 验证码 + * @throws Exception + */ + @RequestMapping(value = "/account/email/bind",method = RequestMethod.PUT) + public void updateAccountEmail(@ModelAttribute(RETAIL_DEVICE) JSONObject device,@RequestBody JSONObject params) throws Exception { + retailAppService.updateAccountEmail(device,params); + } + + /** + * 接收关联手机的验证码 + * @param device + * @param phone contact_phone + * @throws Exception + */ + @RequestMapping(value = "/account/phone",method = RequestMethod.PUT) + public void bindAccountPhone(@ModelAttribute(RETAIL_DEVICE) JSONObject device,@RequestBody JSONObject phone) throws Exception { + retailAppService.bindAccountPhone(device,phone); + } + + /** + * 关联手机 + * @param device + * @param params 验证码 + * @throws Exception + */ + @RequestMapping(value = "/account/phone/bind",method = RequestMethod.PUT) + public void updateAccountPhone(@ModelAttribute(RETAIL_DEVICE) JSONObject device,@RequestBody JSONObject params) throws Exception { + retailAppService.updateAccountPhone(device,params); + } + + /** + * 验证退款密码 + */ + @RequestMapping(value = "/refund/passwd/verify", method = RequestMethod.PUT) + public void verifyRefundPassword(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject json) { + retailAppService.verifyRefundPassword(device, json); + } + + /** + * 重置退款密码 + */ + @RequestMapping(value = "/refund/passwd/reset", method = RequestMethod.PUT) + public void resetRefundPassWord(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject json) { + retailAppService.resetRefundPassword(device, json); + } + } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/NewAccountBean.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/NewAccountBean.java index 4fd5f8981..5df58d16c 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/NewAccountBean.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/NewAccountBean.java @@ -18,15 +18,23 @@ public class NewAccountBean { private String displayName; @JSONField(name = "contact_phone") private String contactPhone; + @JSONField(name = "contact_email") + private String contactEmail; @JSONField(name = "nation_code") private String nation_code = "+61"; private int role = PartnerRole.CASHIER.getCode(); + @JSONField(name = "client_id") + private int clientId; public JSONObject toJson() { JSONObject account = new JSONObject(); account.put("display_name", displayName); account.put("username", getUsername()); account.put("role", role); + account.put("nation_code", nation_code.startsWith("+")?nation_code:"+"+nation_code); + if (contactEmail != null){ + account.put("contact_email", contactEmail); + } if (contactPhone != null){ account.put("contact_phone", contactPhone); } @@ -80,4 +88,20 @@ public class NewAccountBean { public void setNation_code(String nation_code) { this.nation_code = nation_code; } + + public String getContactEmail() { + return contactEmail; + } + + public void setContactEmail(String contactEmail) { + this.contactEmail = contactEmail; + } + + public int getClientId() { + return clientId; + } + + public void setClientId(int clientId) { + this.clientId = clientId; + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java index a8b73985e..848d08917 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java @@ -416,4 +416,16 @@ public interface ClientManager { void partnerCBChannelConfig(String clientMoniker, String channelKey, String channel_id); void addDevice(JSONObject manager, String clientMoniker, JSONObject device); + + /** + * 退款密码 + */ + void verifyRefundPassword(JSONObject account, JSONObject json); + + /** + * 退款密码 + */ + void resetRefundPassword(JSONObject account, JSONObject json); + + void resetRefundPasswordByManage(String clientMoniker,JSONObject manage, JSONObject json); } diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 851f1fe89..712d92b74 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -1351,7 +1351,11 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new InvalidShortIdException(); } checkOrgPermission(manager, client); + if(!client.containsKey("parent_client_id") && client.getBoolean("sub_manage")){ + return clientAccountMapper.partnerAndSubPartnerAccounts(client.getIntValue("client_id")); + } return clientAccountMapper.listPartnerAccounts(client.getIntValue("client_id")); + } @Override @@ -1370,7 +1374,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid accountJson.put("salt", salt); accountJson.put("password_hash", PasswordUtils.hashPwd(account.getPwd(), salt)); accountJson.put("password_aes", PasswordUtils.encryptAESPwd(account.getPwd())); - accountJson.put("client_id", client.getIntValue("client_id")); + accountJson.put("client_id", account.getClientId()==0?client.getIntValue("client_id"):account.getClientId()); accountJson.put("creator", managerType == 1 ? manager.getString("manager_id") : manager.getString("account_id")); accountJson.put("creator_type", managerType); accountJson.put("create_time", new Date()); @@ -1401,8 +1405,14 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid if (clientMoniker != null) { JSONObject client = getClientInfoByMoniker(clientMoniker); Assert.notNull(client); + //父商户全局管理子商户时候,跳过 if (account.getIntValue("client_id") != client.getIntValue("client_id")) { - throw new BadRequestException("error.partner.valid.account_not_match"); + //登录用户所属商户 + JSONObject clientLogin = getClientInfo(account.getIntValue("client_id")); + if(!(client.getBoolean("sub_manage") && + clientLogin.containsKey("parent_client_id")?clientLogin.getIntValue("parent_client_id")==client.getIntValue("client_id"):false)){ + throw new BadRequestException("error.partner.valid.account_not_match"); + } } checkOrgPermission(manager, client); } @@ -2200,6 +2210,57 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid clientDeviceMapper.save(newDevice); } + @Override + public void verifyRefundPassword(JSONObject account, JSONObject json) { + JSONObject clientConfig = clientConfigMapper.find(account.getIntValue("client_id")); + String needVerifyPassword = json.getString("refund_password"); + String refundPwdSalt = clientConfig.getString("refund_pwd_salt"); + if (!StringUtils.equals(clientConfig.getString("refund_pwd"), PasswordUtils.hashPwd(needVerifyPassword, refundPwdSalt))) { + throw new BadRequestException("Incorrect refund password"); + } + } + + @Override + public void resetRefundPassword(JSONObject account, JSONObject json) { + if (PartnerRole.getRole(account.getIntValue("role")) != PartnerRole.ADMIN) { + throw new BadRequestException("You have no permission"); + } + verifyRefundPassword(account, json); + String newSalt = PasswordUtils.newSalt(); + String newPassWord = json.getString("new_refund_password"); + if (!StringUtils.isNumeric(newPassWord)) { + throw new BadRequestException("Refund password must be pure number"); + } + String newPwdHash = PasswordUtils.hashPwd(newPassWord, newSalt); + if (StringUtils.equals(newPwdHash, PasswordUtils.hashPwd(json.getString("refund_password"), newSalt))) { + throw new BadRequestException("Old and new passwords cannot be duplicated"); + } + JSONObject update = new JSONObject(); + update.put("client_id", account.getIntValue("client_id")); + update.put("refund_pwd", newPwdHash); + update.put("refund_pwd_salt", newSalt); + clientConfigMapper.update(update); + } + + @Override + public void resetRefundPasswordByManage(String clientMoniker,JSONObject manage, JSONObject json) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } + JSONObject update = new JSONObject(); + update.put("client_id", client.getIntValue("client_id")); + String newPassWord = json.getString("new_refund_password"); + if (!StringUtils.isNumeric(newPassWord)) { + throw new BadRequestException("Refund password must be pure number"); + } + String newSalt = PasswordUtils.newSalt(); + String newPwdHash = PasswordUtils.hashPwd(newPassWord, newSalt); + update.put("refund_pwd", newPwdHash); + update.put("refund_pwd_salt", newSalt); + clientConfigMapper.update(update); + } + @Override public void updateDevie(JSONObject manager, String clientMoniker, String devId, String remark) { JSONObject client = getClientInfoByMoniker(clientMoniker); diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java index 4bf424235..0bc839508 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java @@ -272,6 +272,17 @@ public class PartnerManageController { clientManager.switchPermission(manager, clientMoniker, "common_sub_merchant_id", pass.getBooleanValue("allow")); } + /** + * 父商户全局管理子商户 + * @param clientMoniker + * @param pass + * @param manager + */ + @ManagerMapping(value = "/{clientMoniker}/sub_manage", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR}) + public void switchSubManage(@PathVariable String clientMoniker, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.switchPermission(manager, clientMoniker, "sub_manage", pass.getBooleanValue("allow")); + } + @ManagerMapping(value = "/{clientMoniker}/channels/{channel}/permission", method = RequestMethod.PUT, role = {ManagerRole.SERVANT, ManagerRole.DEVELOPER}) public void switchChannelPermission(@PathVariable String clientMoniker, @PathVariable String channel, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.switchChannelPermission(manager, clientMoniker, channel, pass.getBooleanValue("allow")); @@ -302,6 +313,12 @@ public class PartnerManageController { clientManager.switchPermission(manager, clientMoniker, "enable_pre_refund", pass.getBooleanValue("allow")); } + @ManagerMapping(value = "/{clientMoniker}/reset/refund_pwd", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN, ManagerRole.DEVELOPER}) + public void changeRefundPwd(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@RequestBody JSONObject config) { + clientManager.resetRefundPasswordByManage(clientMoniker, manager, config); + } + + @ManagerMapping(value = "/{clientMoniker}/payment_page_version", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.BD_USER}) public void changePaymentPage(@PathVariable String clientMoniker, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.changePaymentPage(manager, clientMoniker, pass.getString("paypad_version")); diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java index 64058ab27..d59eb9d62 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerViewController.java @@ -283,6 +283,12 @@ public class PartnerViewController { clientManager.updateRefundPwd(account, req.getString("pwd")); } + @PartnerMapping(value = "/refund_pwd_new", method = RequestMethod.PUT, roles = {PartnerRole.ADMIN}) + @ResponseBody + public void updateRefundPwdNew(@ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject account, @RequestBody JSONObject req) { + clientManager.resetRefundPassword(account, req); + } + @PartnerMapping(value = "/trade_logs", method = RequestMethod.GET) @ResponseBody public JSONObject listTradeLogs(@ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject account, TradeLogQuery query) throws Exception { diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/beans/ManagerInfo.java b/src/main/java/au/com/royalpay/payment/manage/signin/beans/ManagerInfo.java index fafd02ee3..602fbfab5 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/beans/ManagerInfo.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/beans/ManagerInfo.java @@ -24,6 +24,8 @@ public class ManagerInfo { @Email private String email; private String phone; + @JSONField(name = "nation_code") + private String nationCode; private String wechat; private boolean admin; private boolean operator; @@ -58,6 +60,7 @@ public class ManagerInfo { } account.put("email", email); account.put("phone", phone); + account.put("nation_code", "+"+nationCode); account.put("wechat", wechat); int role = 0; if (admin) { @@ -296,4 +299,12 @@ public class ManagerInfo { public void setSalesmanager(boolean salesmanager) { this.salesmanager = salesmanager; } + + public String getNationCode() { + return nationCode; + } + + public void setNationCode(String nationCode) { + this.nationCode = nationCode; + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/core/ManagerAccountsService.java b/src/main/java/au/com/royalpay/payment/manage/signin/core/ManagerAccountsService.java index 9cfe39363..1a61042f1 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/core/ManagerAccountsService.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/core/ManagerAccountsService.java @@ -27,4 +27,6 @@ public interface ManagerAccountsService { JSONObject getBDConfig(String bd_id); List listServants(JSONObject loginManager); -} \ No newline at end of file + + void resetPwd(JSONObject account,String password); +} 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 e9b82b21e..4802fe677 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 @@ -3,6 +3,7 @@ package au.com.royalpay.payment.manage.signin.core; import au.com.royalpay.payment.manage.signin.beans.ChangePwdBean; import au.com.royalpay.payment.manage.signin.beans.LoginInfo; import com.alibaba.fastjson.JSONObject; +import org.springframework.web.servlet.ModelAndView; /** * Created by yixian on 2016-06-29. @@ -15,6 +16,10 @@ public interface SignInAccountService { JSONObject getClient(String accountId); + JSONObject getClientByUsername(String username); + + JSONObject getManagerByUsername(String username); + void clearAccountCache(String accountId); JSONObject managerLoginCheck(LoginInfo loginInfo); @@ -40,4 +45,16 @@ public interface SignInAccountService { String ForgetPassword(String partner_code) throws Exception; void changePasswordByEmail(String codeValue, String login_id, String newPassword); + + void getClientResetPwdCode(JSONObject account,String type); + + void getManagerResetPwdCode(JSONObject account,String type); + + void verifyClientCaptcha(JSONObject account, String captcha); + + void verifyManagerCaptcha(JSONObject account, String captcha); + + void deleteClientCodeKey(String codekey); + + void deleteManagerCodeKey(String codekey); } diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/ManagerAccountServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/ManagerAccountServiceImpl.java index 078087413..410aeb123 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/ManagerAccountServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/core/impls/ManagerAccountServiceImpl.java @@ -11,6 +11,7 @@ import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.NotFoundException; import au.com.royalpay.payment.tools.permission.enums.ManagerRole; +import au.com.royalpay.payment.tools.utils.PasswordUtils; import com.alibaba.fastjson.JSONObject; import com.github.miemiedev.mybatis.paginator.domain.Order; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; @@ -149,6 +150,15 @@ public class ManagerAccountServiceImpl implements ManagerAccountsService { return managerMapper.listServants(ManagerRole.SERVANT.getMask()); } + @Override + public void resetPwd(JSONObject account, String password) { + String salt = PasswordUtils.newSalt(); + account.put("salt", salt); + account.put("password_hash", PasswordUtils.hashPwd(password, salt)); + managerMapper.update(account); + signInAccountService.clearManager(account.getString("manager_id")); + } + private void checkOrg(JSONObject loginManager,JSONObject manager){ if (loginManager.getInteger("org_id")!=null){ List orgs = orgMapper.listOrgAndChild(loginManager.getIntValue("org_id")); 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 81159d1fd..407e709e3 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 @@ -1,5 +1,6 @@ package au.com.royalpay.payment.manage.signin.core.impls; +import au.com.royalpay.payment.core.exceptions.EmailException; import au.com.royalpay.payment.core.exceptions.InvalidShortIdException; import au.com.royalpay.payment.manage.device.core.DeviceManager; import au.com.royalpay.payment.manage.management.sysconfig.core.PermissionManager; @@ -17,26 +18,33 @@ import au.com.royalpay.payment.manage.signin.core.SignInAccountService; import au.com.royalpay.payment.manage.signin.core.SignInStatusManager; import au.com.royalpay.payment.manage.signin.events.ClientLoginEvent; import au.com.royalpay.payment.manage.signin.events.ManagerLoginEvent; +import au.com.royalpay.payment.manage.support.sms.SmsSender; import au.com.royalpay.payment.manage.system.core.PermissionClientModulesService; import au.com.royalpay.payment.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.env.RequestEnvironment; import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.ForbiddenException; +import au.com.royalpay.payment.tools.exceptions.ServerErrorException; import au.com.royalpay.payment.tools.locale.LocaleSupport; import au.com.royalpay.payment.tools.permission.enums.ManagerRole; +import au.com.royalpay.payment.tools.threadpool.RoyalThreadPoolExecutor; import au.com.royalpay.payment.tools.utils.PasswordUtils; import com.alibaba.fastjson.JSONObject; +import com.sun.xml.internal.bind.v2.TODO; +import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import org.springframework.web.servlet.ModelAndView; import org.thymeleaf.context.Context; import org.thymeleaf.spring4.SpringTemplateEngine; @@ -44,6 +52,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.annotation.Resource; @@ -79,6 +88,15 @@ public class SignInAccountServiceImpl implements SignInAccountService, Applicati private SysCustomerServiceMapper sysCustomerServiceMapper; @Resource private PermissionClientModulesService permissionClientModulesService; + @Resource + private RoyalThreadPoolExecutor royalThreadPoolExecutor; + @Resource + private StringRedisTemplate stringRedisTemplate; + @Resource + private SmsSender smsSender; + private final String RESET_CLIENT_ACCOUNT_PREFIX = "RESET_CLIENT_ACCOUNT"; + private final String RESET_MANAGER_ACCOUNT_PREFIX = "RESET_MANAGER_ACCOUNT"; + private final int RESET_PASSWORD_TEMPLID = 126978; private ApplicationEventPublisher publisher; private static final List tags = new ArrayList<>(); @@ -172,6 +190,20 @@ public class SignInAccountServiceImpl implements SignInAccountService, Applicati return account; } + @Override + public JSONObject getClientByUsername(String username) { + JSONObject account = clientAccountMapper.findByUsername(username); + Assert.notNull(account, "Username is not exists!"); + return account; + } + + @Override + public JSONObject getManagerByUsername(String username) { + JSONObject account = managerMapper.findAvailableByLoginId(username); + Assert.notNull(account, "Username is not exists!"); + return account; + } + @Override @CacheEvict(value = ":login:clients:", key = "''+#accountId") public void clearAccountCache(String accountId) { @@ -454,4 +486,145 @@ public class SignInAccountServiceImpl implements SignInAccountService, Applicati account.put("is_password_expired", 0); clientAccountMapper.update(account); } + + @Override + public void getClientResetPwdCode(JSONObject account,String type) { + if(StringUtils.equals(type,"email") && !account.containsKey("contact_email")){ + throw new BadRequestException("Your account is not bound to your mailbox!"); + } + if(StringUtils.equals(type,"phone") && !account.containsKey("contact_phone") && !account.containsKey("nation_code")){ + throw new BadRequestException("Your account is not bound to your phone!"); + } + String accountId = account.getString("account_id"); + String codeKeyValueRedis = stringRedisTemplate.boundValueOps(getResetClientAccountKey(accountId)).get(); + if(StringUtils.isNotEmpty(codeKeyValueRedis)){ + throw new BadRequestException("Captcha has been sent.Please check your "+type+" or try again in 5 minutes."); + } + String codeKeyValue = RandomStringUtils.random(6, false, true); + switch(type){ + case "email": + Context ctx = new Context(); + ctx.setVariable("account",account); + ctx.setVariable("captcha",codeKeyValue); + final String content = thymeleaf.process("mail/account_reset_email.html", ctx); + royalThreadPoolExecutor.execute(() -> { + try { + mailService.sendEmail("Reset your password", account.getString("contact_email"), + "", content); + } catch (Exception e) { + throw new EmailException("Email Sending Failed", e); + } + }); + break; + case "phone": + ArrayList param = new ArrayList<>(); + param.add("密码重置服务"); + param.add(codeKeyValue); + String expireMin = "5"; + param.add(expireMin); + try { + smsSender.getSender().sendWithParam(account.getString("nation_code").trim(), account.getString("contact_phone"), RESET_PASSWORD_TEMPLID, param, "RoyalPay", "", ""); + } catch (Exception e) { + e.printStackTrace(); + throw new ServerErrorException("Phone number is wrong.Please try again."); + } + break; + } + stringRedisTemplate.boundValueOps(getResetClientAccountKey(accountId)).set(codeKeyValue,5, TimeUnit.MINUTES); + } + + @Override + public void getManagerResetPwdCode(JSONObject account, String type) { + if(StringUtils.equals(type,"email") && !account.containsKey("email")){ + throw new BadRequestException("Your account is not bound to your mailbox!"); + } + if(StringUtils.equals(type,"phone") && !account.containsKey("phone") && !account.containsKey("nation_code")){ + throw new BadRequestException("Your account is not bound to your phone!"); + } + String managerId = account.getString("manager_id"); + String codeKeyValueRedis = stringRedisTemplate.boundValueOps(getResetManagerAccountKey(managerId)).get(); + if(StringUtils.isNotEmpty(codeKeyValueRedis)){ + throw new BadRequestException("Captcha has been sent.Please check your "+type+" or try again in 5 minutes."); + } + String codeKeyValue = RandomStringUtils.random(6, false, true); + switch(type){ + case "email": + Context ctx = new Context(); + ctx.setVariable("account",account); + ctx.setVariable("captcha",codeKeyValue); + final String content = thymeleaf.process("mail/account_reset_email.html", ctx); + royalThreadPoolExecutor.execute(() -> { + try { + mailService.sendEmail("Reset your password", account.getString("email"), + "", content); + } catch (Exception e) { + throw new EmailException("Email Sending Failed", e); + } + }); + break; + case "phone": + ArrayList param = new ArrayList<>(); + param.add("密码重置服务"); + param.add(codeKeyValue); + String expireMin = "5"; + param.add(expireMin); + try { + smsSender.getSender().sendWithParam(account.getString("nation_code").trim(), account.getString("phone"), RESET_PASSWORD_TEMPLID, param, "RoyalPay", "", ""); + } catch (Exception e) { + e.printStackTrace(); + throw new ServerErrorException("Phone number is wrong.Please try again."); + } + break; + } + stringRedisTemplate.boundValueOps(getResetManagerAccountKey(managerId)).set(codeKeyValue,5, TimeUnit.MINUTES); + } + + @Override + public void verifyClientCaptcha(JSONObject account, String captcha) { + String captchaRedis = stringRedisTemplate.boundValueOps(getResetClientAccountKey(account.getString("account_id"))).get(); + if(StringUtils.isBlank(captchaRedis)){ + throw new BadRequestException("Captcha has expired"); + } + if(StringUtils.equals(captcha,captchaRedis)){ + throw new BadRequestException("Captcha is wrong"); + } + } + + @Override + public void verifyManagerCaptcha(JSONObject account, String captcha) { + String captchaRedis = stringRedisTemplate.boundValueOps(getResetManagerAccountKey(account.getString("manager_id"))).get(); + if(StringUtils.isBlank(captchaRedis)){ + throw new BadRequestException("Captcha has expired"); + } + if(StringUtils.equals(captcha,captchaRedis)){ + throw new BadRequestException("Captcha is wrong"); + } + } + + @Override + public void deleteClientCodeKey(String codekey) { + deleteClientAccountKey(codekey); + } + + @Override + public void deleteManagerCodeKey(String codekey) { + deleteManagerAccountKey(codekey); + } + + private void deleteClientAccountKey(String codeKey){ + stringRedisTemplate.delete(getResetClientAccountKey(codeKey)); + } + + private void deleteManagerAccountKey(String codeKey){ + stringRedisTemplate.delete(getResetManagerAccountKey(codeKey)); + } + + private String getResetClientAccountKey(String codeKey){ + return RESET_CLIENT_ACCOUNT_PREFIX + codeKey; + } + + private String getResetManagerAccountKey(String codeKey){ + return RESET_MANAGER_ACCOUNT_PREFIX + codeKey; + } + } diff --git a/src/main/java/au/com/royalpay/payment/manage/signin/web/SignInController.java b/src/main/java/au/com/royalpay/payment/manage/signin/web/SignInController.java index fbf656118..f70c16934 100644 --- a/src/main/java/au/com/royalpay/payment/manage/signin/web/SignInController.java +++ b/src/main/java/au/com/royalpay/payment/manage/signin/web/SignInController.java @@ -1,5 +1,7 @@ package au.com.royalpay.payment.manage.signin.web; +import au.com.royalpay.payment.manage.merchants.core.ClientManager; +import au.com.royalpay.payment.manage.signin.core.*; import au.com.royalpay.payment.tools.permission.consumer.ConsumersAction; import com.google.code.kaptcha.Producer; @@ -10,11 +12,6 @@ import au.com.royalpay.payment.manage.signin.beans.ChangePwdBean; import au.com.royalpay.payment.manage.signin.beans.FindPwdBean; import au.com.royalpay.payment.manage.signin.beans.LoginInfo; import au.com.royalpay.payment.manage.signin.beans.TodoNotice; -import au.com.royalpay.payment.manage.signin.core.ClientLoginLogRepository; -import au.com.royalpay.payment.manage.signin.core.ManagerLoginLogRepository; -import au.com.royalpay.payment.manage.signin.core.ManagerTodoNoticeProvider; -import au.com.royalpay.payment.manage.signin.core.SignInAccountService; -import au.com.royalpay.payment.manage.signin.core.SignInStatusManager; import au.com.royalpay.payment.tools.CommonConsts; import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApi; import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApiProvider; @@ -69,6 +66,11 @@ public class SignInController { private Producer captchaProducer; @Resource private ManagerTodoNoticeProvider[] managerTodoNoticeProviders; + @Resource + private ClientManager clientManager; + + @Resource + private ManagerAccountsService managerAccountsService; @Resource private MpWechatApiProvider mpWechatApiProvider; @@ -371,4 +373,52 @@ public class SignInController { HttpUtils.setCookie(response, "CustomerID", statusKey,false); return result; } + + /** + * 商户重置密码,发送验证码 + * @param username 用户名 + * @param type email或者phone + */ + @RequestMapping(value = "/client/reset_pwd/{type}/{username}", method = RequestMethod.PUT) + public void resetMerchantPwd(@PathVariable("username") String username,@PathVariable("type") String type) { + JSONObject account = signInAccountService.getClientByUsername(username); + signInAccountService.getClientResetPwdCode(account,type); + } + + + /** + * 商户重置密码 + * @param info + */ + @RequestMapping(value = "/client/reset_pwd", method = RequestMethod.PUT) + public void resetClientPwd(@RequestBody LoginInfo info) { + JSONObject account = signInAccountService.getClientByUsername(info.getLoginId()); + signInAccountService.verifyClientCaptcha(account, info.getVerifyCode()); + clientManager.resetAccountPwd(null, null, account.getString("account_id"), info.getPassword()); + signInAccountService.deleteClientCodeKey(account.getString("account_id")); + } + + /** + * 运营重置密码,发送验证码 + * @param username 用户名 + * @param type email或者phone + */ + @RequestMapping(value = "/manager/reset_pwd/{type}/{username}", method = RequestMethod.PUT) + public void resetManagerPwd(@PathVariable("username") String username,@PathVariable("type") String type) { + JSONObject account = signInAccountService.getManagerByUsername(username); + signInAccountService.getClientResetPwdCode(account,type); + } + + + /** + * 运营重置密码 + * @param info + */ + @RequestMapping(value = "/manager/reset_pwd", method = RequestMethod.PUT) + public void resetManagerPwd(@RequestBody LoginInfo info) { + JSONObject account = signInAccountService.getManagerByUsername(info.getLoginId()); + signInAccountService.verifyManagerCaptcha(account, info.getVerifyCode()); + managerAccountsService.resetPwd(account, info.getPassword()); + signInAccountService.deleteManagerCodeKey(account.getString("manager_id")); + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/tradelog/refund/impls/RefundServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/tradelog/refund/impls/RefundServiceImpl.java index 33c191e34..1ace7eb97 100644 --- a/src/main/java/au/com/royalpay/payment/manage/tradelog/refund/impls/RefundServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/tradelog/refund/impls/RefundServiceImpl.java @@ -76,8 +76,16 @@ public class RefundServiceImpl implements RefundService, ApplicationEventPublish public JSONObject checkOrderRefundAmount(String orderId, JSONObject account) { JSONObject order = orderMapper.getOrderDetail(orderId); if (account != null) { + JSONObject client = clientMapper.findClient(account.getIntValue("client_id")); + ////父商户全局管理子商户时候,跳过 if (account.getIntValue("client_id") != order.getIntValue("client_id")) { - throw new ForbiddenException("Order is not belong to your shop/merchant"); + JSONObject clientOrder = clientMapper.findClient(order.getIntValue("client_id")); + if(!(client.getBoolean("sub_manage") && + clientOrder.containsKey("parent_client_id")?clientOrder.getIntValue("parent_client_id")==client.getIntValue("client_id"):false)){ + throw new ForbiddenException("Order is not belong to your shop/merchant"); + } + + } } Assert.notNull(order, "Order Not Exists"); diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.xml index 36b3ceab0..f45bde063 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClientAccountMapper.xml @@ -18,9 +18,10 @@ - \ No newline at end of file + diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ManagerMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ManagerMapper.xml index ca1174a32..c6d046fd4 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ManagerMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ManagerMapper.xml @@ -14,6 +14,7 @@ SELECT m.manager_id, m.org_id, m.display_name, + SUBSTRING(m.nation_code,2) nation_code, m.username,m.role,m.is_valid,m.create_time,m.last_login,o.name org_name, m.email,m.phone,m.wechat,m.wx_openid, co.headimg, @@ -102,4 +103,4 @@ - \ No newline at end of file + diff --git a/src/main/resources/templates/mail/account_bind_email.html b/src/main/resources/templates/mail/account_bind_email.html new file mode 100644 index 000000000..1827a0811 --- /dev/null +++ b/src/main/resources/templates/mail/account_bind_email.html @@ -0,0 +1,31 @@ + +Dear : +

+ Your account() is in the process of binding a mailbox, the verification code is ,valid within 5 minutes. +

+尊敬的,您好: +

+ 您的账户()正在进行绑定邮箱的操作,验证码是,5分钟内有效。 +

+
+

Best Regards

+

+
+ Contact Us
+ Email:
+ info@royalpay.com.au
+ Tel:
+ 1300 10 77 50
+
+ Service WeChat Account:
+
+ Level 14, 383 Kent Street, Sydney NSW 2000
+
+ Level 11, 15 William Street, Melbourne VIC 3000 +

+

Tunnel Show Pty Ltd trading as RoyalPay
+ Representative of AFSL licensee 448066 +

+ diff --git a/src/main/resources/templates/mail/account_reset_email.html b/src/main/resources/templates/mail/account_reset_email.html new file mode 100644 index 000000000..3e390651e --- /dev/null +++ b/src/main/resources/templates/mail/account_reset_email.html @@ -0,0 +1,34 @@ + +Dear : +

+ You are requesting a password reset service with a verification code of , valid for 5 minutes. Please do not provide this verification code to anyone. +

+

+ Reset Password > +

+尊敬的,您好: +

+ 您正在申请密码重置服务,验证码为,5分钟内有效,请勿向任何人提供此验证码。 +

+
+

Best Regards

+

+
+ Contact Us
+ Email:
+ info@royalpay.com.au
+ Tel:
+ 1300 10 77 50
+
+ Service WeChat Account:
+
+ Level 14, 383 Kent Street, Sydney NSW 2000
+
+ Level 11, 15 William Street, Melbourne VIC 3000 +

+

Tunnel Show Pty Ltd trading as RoyalPay
+ Representative of AFSL licensee 448066 +

+ diff --git a/src/main/ui/index.html b/src/main/ui/index.html index cf0a6eaa8..32c38e369 100644 --- a/src/main/ui/index.html +++ b/src/main/ui/index.html @@ -1003,7 +1003,7 @@ margin-bottom: 10%;"/> -
  • +
  • Accounts diff --git a/src/main/ui/static/config/managers/manager.js b/src/main/ui/static/config/managers/manager.js index e9dac8f34..9d3895d65 100644 --- a/src/main/ui/static/config/managers/manager.js +++ b/src/main/ui/static/config/managers/manager.js @@ -142,6 +142,7 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) { app.controller('newManagerDialogCtrl', ['$scope', '$http', function ($scope, $http) { $scope.params = {}; $scope.manager = {}; + $scope.manager.nation_code = 61; if(($scope.currentUser.role & parseInt('1000000000000', 2)) > 0 && $scope.currentUser.org_id){ var params = angular.copy($scope.params); params.org_id = $scope.currentUser.org_id; @@ -209,4 +210,4 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) { } }]); return app; -}); \ No newline at end of file +}); diff --git a/src/main/ui/static/config/managers/templates/modify.html b/src/main/ui/static/config/managers/templates/modify.html index 46b4a356a..26741b752 100644 --- a/src/main/ui/static/config/managers/templates/modify.html +++ b/src/main/ui/static/config/managers/templates/modify.html @@ -37,8 +37,30 @@
    - +
    +
    +
    +
    +
    + +
    + +
    +

    Required + Field

    +

    Less + Than 3 Characters

    +
    +
    +
    + +
    +
    @@ -130,4 +152,4 @@
    -
    \ No newline at end of file + diff --git a/src/main/ui/static/config/managers/templates/new_manager.html b/src/main/ui/static/config/managers/templates/new_manager.html index 9c8ca94d7..706c5cb38 100644 --- a/src/main/ui/static/config/managers/templates/new_manager.html +++ b/src/main/ui/static/config/managers/templates/new_manager.html @@ -43,8 +43,30 @@
    - +
    +
    +
    +
    +
    + +
    + +
    +

    Required + Field

    +

    Less + Than 3 Characters

    +
    +
    +
    + +
    +
    @@ -140,4 +162,4 @@
    -
    \ No newline at end of file + diff --git a/src/main/ui/static/payment/partner/client-account.js b/src/main/ui/static/payment/partner/client-account.js index 68731f4c2..6cea49371 100644 --- a/src/main/ui/static/payment/partner/client-account.js +++ b/src/main/ui/static/payment/partner/client-account.js @@ -13,10 +13,16 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) { $stateProvider.state('accounts', { url: '/accounts', templateUrl: '/static/payment/partner/templates/client_accounts.html', - controller: 'clientAccountsCtrl' + controller: 'clientAccountsCtrl', + resolve: { + partner: ['$http', function ($http) { + return $http.get('/client/partner_info'); + }] + } }) }]); - app.controller('clientAccountsCtrl', ['$scope', '$http', '$uibModal', 'commonDialog', function ($scope, $http, $uibModal, commonDialog) { + app.controller('clientAccountsCtrl', ['$scope', '$http', '$uibModal', 'commonDialog','partner', function ($scope, $http, $uibModal, commonDialog,partner) { + $scope.partner = partner.data; $scope.loadAccounts = function () { $http.get('/client/partner_info/accounts').then(function (resp) { $scope.accounts = resp.data; @@ -28,7 +34,12 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) { $uibModal.open({ templateUrl: '/static/payment/partner/templates/add_partner_account_dialog.html', controller: 'clientAddAccountCtrl', - backdrop: false + backdrop: false, + resolve: { + partner: ['$http', function ($http) { + return $http.get('/client/partner_info'); + }] + } }).result.then(function () { $scope.loadAccounts(); }) @@ -91,8 +102,16 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) { }); }; }]); - app.controller('clientAddAccountCtrl', ['$scope', '$http', function ($scope, $http) { + app.controller('clientAddAccountCtrl', ['$scope', '$http','partner', function ($scope, $http, partner) { + $scope.loadSubPartners = function () { + $http.get('/client/partner_info/sub_partners').then(function (resp) { + $scope.subPartners = resp.data; + }) + }; + $scope.partner = partner.data; + $scope.loadSubPartners(); $scope.account = {role: 3}; + $scope.account.nation_code = 61; $scope.partnerRoles = partnerRoles; $scope.saveAccount = function (form) { if (form.$invalid) { @@ -122,4 +141,4 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) { } }]); return app; -}); \ No newline at end of file +}); diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index bc32e68d6..a31f477fb 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -1428,6 +1428,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter $scope.ctrl.editAliSubMerchant = false; $scope.ctrl.editMaxOrderAmount = false; $scope.ctrl.editOrderExpiryConfig = false; + $scope.ctrl.editRefundPwd = false; }) }; $scope.qrConfig = {currency: 'AUD'}; @@ -1500,6 +1501,13 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }) }; + $scope.resetRefundPwd = function (config) { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/reset/refund_pwd', {new_refund_password: config}).then(function () { + $scope.loadPartnerPaymentInfo(); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }) + }; $scope.updateClientQRCodePaySurCharge = function () { if (!$scope.paymentInfo) { @@ -1671,6 +1679,26 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }) }) }; + + $scope.switchSubManage = function () { + if (!$scope.paymentInfo) { + return; + } + if (!$scope.init.sub_manage) { + $scope.init.sub_manage = true; + return; + } + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/sub_manage', {allow: $scope.paymentInfo.sub_manage}).then(function () { + $scope.loadPartnerPaymentInfo(); + }, function (resp) { + commonDialog.alert({ + title: 'Failed to change Sub Partners Manage status', + content: resp.data.message, + type: 'error' + }) + }) + }; + var info = []; $scope.decideCompliance = function (name) { var keywords = ['education','financial' ,'train','immigrant','invest', @@ -2500,6 +2528,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter app.controller('partnerAddAccountDialogCtrl', ['$scope', '$http', 'partner', function ($scope, $http, partner) { $scope.account = {role: 1}; $scope.partnerRoles = partnerRoles; + $scope.account.nation_code = 61; $scope.saveAccount = function (form) { if (form.$invalid) { angular.forEach(form, function (item, key) { diff --git a/src/main/ui/static/payment/partner/partner.js b/src/main/ui/static/payment/partner/partner.js index 3b1dc7ccc..c31a2938e 100644 --- a/src/main/ui/static/payment/partner/partner.js +++ b/src/main/ui/static/payment/partner/partner.js @@ -344,6 +344,16 @@ define(['angular', 'decimal', 'uiRouter', 'ngBootSwitch', 'ngFileUpload','uiBoot }; }]); + app.controller('clientResetRefundPwdDialogCtrl', ['$scope', '$http', function ($scope, $http) { + $scope.updateRefundPwd = function (refundPwd) { + $scope.errmsg = null; + $http.put('/client/partner_info/refund_pwd_new', refundPwd).then(function () { + $scope.$close(); + }, function (resp) { + $scope.errmsg = resp.data.message; + }) + } + }]); app.controller('clientComplianceFilesCtrl', ['$scope', '$http', '$rootScope', 'commonDialog', '$state', 'Upload', 'file', function ($scope, $http, $rootScope, commonDialog, $state, Upload, file) { $scope.file = file.data || {}; @@ -551,7 +561,7 @@ define(['angular', 'decimal', 'uiRouter', 'ngBootSwitch', 'ngFileUpload','uiBoot }; }]); - app.controller('clientPaymentInfoCtrl', ['$scope', '$http', '$state', 'commonDialog', function ($scope, $http, $state, commonDialog) { + app.controller('clientPaymentInfoCtrl', ['$scope', '$http', '$state', 'commonDialog','$uibModal', function ($scope, $http, $state, commonDialog, $uibModal) { $scope.paymentInfo = $scope.partner; $scope.old_customer_surcharge_rate = angular.copy($scope.partner.customer_surcharge_rate); $scope.qrConfig = {currency: 'AUD'}; @@ -567,6 +577,22 @@ define(['angular', 'decimal', 'uiRouter', 'ngBootSwitch', 'ngFileUpload','uiBoot } }; + $scope.resetRefundPwd = function (account) { + $uibModal.open({ + templateUrl: '/static/payment/partner/templates/partner_reset_refund_pwd_dialog.html', + controller: 'clientResetRefundPwdDialogCtrl', + backdrop: false, + size: 'sm', + resolve: { + account: function () { + return account; + } + } + }).result.then(function () { + commonDialog.alert({title: 'Success!', content: 'Refund Password Changed Successfully', type: 'success'}) + }) + }; + $scope.clientCopyCBBannkPayLink = function() { var e=document.getElementById("c-cpcbbankpay"); e.select(); diff --git a/src/main/ui/static/payment/partner/templates/add_partner_account_dialog.html b/src/main/ui/static/payment/partner/templates/add_partner_account_dialog.html index a2030f11a..a243f4401 100644 --- a/src/main/ui/static/payment/partner/templates/add_partner_account_dialog.html +++ b/src/main/ui/static/payment/partner/templates/add_partner_account_dialog.html @@ -36,14 +36,59 @@

    password is required

    +
    + +
    +
    +
    +
    +
    + +
    + +
    +

    Required + Field

    +

    Less + Than 3 Characters

    +
    +
    +
    + +
    +

    contact phone is required

    +
    +
    +
    + +
    +
    + + +
    +

    contact email is required

    +
    +
    +
    + + +
    \ No newline at end of file + diff --git a/src/main/ui/static/payment/partner/templates/client_accounts.html b/src/main/ui/static/payment/partner/templates/client_accounts.html index 4937ebc80..bed27833f 100644 --- a/src/main/ui/static/payment/partner/templates/client_accounts.html +++ b/src/main/ui/static/payment/partner/templates/client_accounts.html @@ -31,6 +31,9 @@ Display Name Role WeChat + Email + Country Code + Phone Payment Notice Refund Approver Operations @@ -38,7 +41,10 @@ - + {{account.username}} + + @@ -50,6 +56,9 @@ + + + @@ -77,4 +86,4 @@ - \ No newline at end of file + diff --git a/src/main/ui/static/payment/partner/templates/client_payment_info.html b/src/main/ui/static/payment/partner/templates/client_payment_info.html index 1eff787e8..c9b266d21 100644 --- a/src/main/ui/static/payment/partner/templates/client_payment_info.html +++ b/src/main/ui/static/payment/partner/templates/client_payment_info.html @@ -385,6 +385,13 @@ switch-change="toggleRequireRemark()"> + diff --git a/src/main/ui/static/payment/partner/templates/partner_payment_info.html b/src/main/ui/static/payment/partner/templates/partner_payment_info.html index 4058906d1..874056b74 100644 --- a/src/main/ui/static/payment/partner/templates/partner_payment_info.html +++ b/src/main/ui/static/payment/partner/templates/partner_payment_info.html @@ -184,6 +184,12 @@ +
    + +
    + +
    +
    @@ -488,6 +494,30 @@ switch-change="togglePreRefund()"> + +
    + +
    +

    + +

    +
    + +
    + +
    +
    + +
    +
    +
    +
    diff --git a/src/main/ui/static/payment/partner/templates/partner_reset_refund_pwd_dialog.html b/src/main/ui/static/payment/partner/templates/partner_reset_refund_pwd_dialog.html new file mode 100644 index 000000000..7d62d3386 --- /dev/null +++ b/src/main/ui/static/payment/partner/templates/partner_reset_refund_pwd_dialog.html @@ -0,0 +1,25 @@ + + + diff --git a/src/main/ui/static/payment/tradelog/templates/partner_trade_logs.html b/src/main/ui/static/payment/tradelog/templates/partner_trade_logs.html index cfa701647..6911aedda 100644 --- a/src/main/ui/static/payment/tradelog/templates/partner_trade_logs.html +++ b/src/main/ui/static/payment/tradelog/templates/partner_trade_logs.html @@ -361,7 +361,7 @@ ng-click="releasePreAuth(trade.order_id)" title="Release Pre-Authorization"> -