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 e490dc2e1..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 @@ -391,9 +416,9 @@ public class ManageAppServiceImp implements ManageAppService { JSONObject manager = managerMapper.findById(device.getString("manager_id")); JSONObject result = new JSONObject(); if (manager.getIntValue("org_id") == 1) { - result.put("url", "https://mpay.royalpay.com.au/app/rules/bd"); + result.put("url", PlatformEnvironment.getEnv().concatUrl("/app/rules/bd")); } else { - result.put("url", "https://mpay.royalpay.com.au/app/rules/org"); + result.put("url", PlatformEnvironment.getEnv().concatUrl("/app/rules/org")); } return result; } @@ -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/bdprize/core/BDPrizeService.java b/src/main/java/au/com/royalpay/payment/manage/bdprize/core/BDPrizeService.java index 55fa181a1..bf5cac476 100644 --- a/src/main/java/au/com/royalpay/payment/manage/bdprize/core/BDPrizeService.java +++ b/src/main/java/au/com/royalpay/payment/manage/bdprize/core/BDPrizeService.java @@ -48,4 +48,10 @@ public interface BDPrizeService { void exportCommissionDetail(String month, String managerId, HttpServletResponse response); List findCommissionList(JSONObject manager); + + List getBDTeamKpiCompletionDegree(String month); + + List getBDProportionByTeamType(String month, String teamType); + + JSONObject getBDKpiByManagerId(String month, String manager_id); } diff --git a/src/main/java/au/com/royalpay/payment/manage/bdprize/core/impls/BDPrizeServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/bdprize/core/impls/BDPrizeServiceImpl.java index 139547af5..96983fe27 100644 --- a/src/main/java/au/com/royalpay/payment/manage/bdprize/core/impls/BDPrizeServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/bdprize/core/impls/BDPrizeServiceImpl.java @@ -46,6 +46,7 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; +import java.util.stream.Collectors; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; @@ -690,6 +691,45 @@ public class BDPrizeServiceImpl implements BDPrizeService { return null; } + @Override + public List getBDTeamKpiCompletionDegree(String month) { + List prizeAmountAndBdTypeList = financialBDPrizeLogMapper.findBdPrizeAmountAndBdType(getReportByMonth(month)); + for (JSONObject prize : prizeAmountAndBdTypeList) { + BigDecimal kpi = financialBDCommissionConfigMapper.findCurrentCommissionMaxAmount(month, prize.getIntValue("bd_type")); + prize.put("kpi", kpi); + prize.put("completionDegree", prize.getBigDecimal("total_amount").divide(kpi,2)); + } + List prizeSort = prizeAmountAndBdTypeList.stream() + .sorted((prize1, prize2) -> prize2.getBigDecimal("completionDegree").compareTo(prize1.getBigDecimal("completionDegree"))) + .collect(Collectors.toList()); + return prizeSort; + } + + @Override + public List getBDProportionByTeamType(String month, String teamType) { + return financialBDConfigMapper.findManagerByTeamType(teamType, getReportByMonth(month)); + } + + @Override + public JSONObject getBDKpiByManagerId(String month, String manager_id) { + return financialBDPrizeLogMapper.findByReportAndBDTotal(getReportByMonth(month), manager_id); + } + + public String getReportByMonth(String month) { + try { + Date mon = DateUtils.parseDate(month, new String[]{"yyyy-MM"}); + month = DateFormatUtils.format(mon, "yyyy-MM"); + } catch (ParseException e) { + throw new BadRequestException("Invalid Month"); + } + + JSONObject report = financialBDPrizeRecordMapper.findByMonth(month); + if (report == null) { + throw new BadRequestException("Report not created"); + } + return report.getString("record_id"); + } + private String financialBdLevel (int level) { switch (level) { case 0: diff --git a/src/main/java/au/com/royalpay/payment/manage/bdprize/web/BDPrizeController.java b/src/main/java/au/com/royalpay/payment/manage/bdprize/web/BDPrizeController.java index 58d8b47ab..b15cedd84 100644 --- a/src/main/java/au/com/royalpay/payment/manage/bdprize/web/BDPrizeController.java +++ b/src/main/java/au/com/royalpay/payment/manage/bdprize/web/BDPrizeController.java @@ -119,4 +119,28 @@ public class BDPrizeController { public void exportCommissionBdUserDetail(@PathVariable String month, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, HttpServletResponse response) { bdPrizeService.exportCommissionDetail(month, manager.getString("manager_id"), response); } + + /** + * 获取BD团队KPI完成度 + */ + @ManagerMapping(value = "/commission/{month}/completion_degree", method = RequestMethod.GET, role = {ManagerRole.DIRECTOR, ManagerRole.ADMIN}) + public List getBDTeamKpiCompletionDegree(@PathVariable String month) { + return bdPrizeService.getBDTeamKpiCompletionDegree(month); + } + + /** + * 团队每个BD的占比 + */ + @ManagerMapping(value = "/commission/{month}/bd_proportion/{teamType}", method = RequestMethod.GET, role = {ManagerRole.DIRECTOR, ManagerRole.ADMIN}) + public List getBDProportionByTeamType(@PathVariable String month, @PathVariable String teamType) { + return bdPrizeService.getBDProportionByTeamType(month, teamType); + } + + /** + * 查询BD KPI + */ + @ManagerMapping(value = "/commission/{month}/bd_user_kpi/{manager_id}", method = RequestMethod.GET, role = {ManagerRole.DIRECTOR, ManagerRole.ADMIN}) + public JSONObject getBDKpiByManagerId(@PathVariable String month, @PathVariable String manager_id) { + return bdPrizeService.getBDKpiByManagerId(month, manager_id); + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/dev/web/TestController.java b/src/main/java/au/com/royalpay/payment/manage/dev/web/TestController.java index bfc731595..b2a5dcaba 100644 --- a/src/main/java/au/com/royalpay/payment/manage/dev/web/TestController.java +++ b/src/main/java/au/com/royalpay/payment/manage/dev/web/TestController.java @@ -335,7 +335,7 @@ public class TestController implements ApplicationEventPublisherAware { } JSONObject order = orderMapper.find(refundOrder.getString("order_id")); Assert.notNull(order); - String channel = order.getString("channel"); + String channel = order.getString("order_channel"); JSONObject res = new JSONObject(); TradeType type = TradeType.fromGatewayNumber(order.getIntValue("gateway")); switch (channel) { diff --git a/src/main/java/au/com/royalpay/payment/manage/management/clearing/core/impl/CleanServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/management/clearing/core/impl/CleanServiceImpl.java index b225324dc..4f7b43440 100644 --- a/src/main/java/au/com/royalpay/payment/manage/management/clearing/core/impl/CleanServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/management/clearing/core/impl/CleanServiceImpl.java @@ -734,11 +734,11 @@ public class CleanServiceImpl implements CleanService, ManagerTodoNoticeProvider JSONObject client = clientManager.getClientInfo(client_id); Assert.notNull(client, "Client not exists"); int parent_client_id = client.getIntValue("parent_client_id"); - - if (client_id != partner.getIntValue("client_id") && parent_client_id != partner.getIntValue("client_id")) { - throw new ForbiddenException("No Permission"); + if (partner.get("client_id") != null) { + if (client_id != partner.getIntValue("client_id") && parent_client_id != partner.getIntValue("client_id")) { + throw new ForbiddenException("No Permission"); + } } - JSONObject clearClient = clearingDetailMapper.listReport(clearingDetailId, client_id); if (clearClient == null) { throw new NotFoundException(); diff --git a/src/main/java/au/com/royalpay/payment/manage/management/clearing/web/CleanLogManagementController.java b/src/main/java/au/com/royalpay/payment/manage/management/clearing/web/CleanLogManagementController.java index 23a43c2b3..3d196aaa0 100644 --- a/src/main/java/au/com/royalpay/payment/manage/management/clearing/web/CleanLogManagementController.java +++ b/src/main/java/au/com/royalpay/payment/manage/management/clearing/web/CleanLogManagementController.java @@ -1,17 +1,16 @@ package au.com.royalpay.payment.manage.management.clearing.web; import au.com.royalpay.payment.manage.management.clearing.core.CleanService; +import au.com.royalpay.payment.manage.permission.manager.PartnerMapping; import au.com.royalpay.payment.tools.permission.enums.ManagerRole; import au.com.royalpay.payment.manage.permission.manager.RequireManager; import au.com.royalpay.payment.manage.tradelog.beans.ClearingLogQuery; import au.com.royalpay.payment.tools.CommonConsts; import com.alibaba.fastjson.JSONObject; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -44,4 +43,10 @@ public class CleanLogManagementController { return cleanService.getSettlementLogs(query, manager); } + @PartnerMapping("/{client_id}/settlement_logs/{clearingDetailId}/export") + public void exportListClearingTransactions(@PathVariable int client_id, @PathVariable String clearingDetailId, + @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject partner, HttpServletResponse resp) { + cleanService.exportListClearingTransactions(client_id, clearingDetailId, partner, resp); + } + } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDCommissionConfigMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDCommissionConfigMapper.java index 4fde4832a..ffb064e72 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDCommissionConfigMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDCommissionConfigMapper.java @@ -6,6 +6,7 @@ import cn.yixblog.support.mybatis.autosql.annotations.SqlType; import com.alibaba.fastjson.JSONObject; import org.apache.ibatis.annotations.Param; +import java.math.BigDecimal; import java.util.List; /** @@ -31,4 +32,6 @@ public interface FinancialBDCommissionConfigMapper { void deleteConfig(@Param("bc_config_id") String configInfo); JSONObject findCurrentCommissionRate(@Param("month") String month, @Param("amount") String amount, @Param("bd_type") int bd_type); + + BigDecimal findCurrentCommissionMaxAmount(@Param("month") String month, @Param("bd_type") int bd_type); } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.java index 8b4c76832..9037c1afc 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.java @@ -37,4 +37,6 @@ public interface FinancialBDConfigMapper { List listBDCity(); JSONObject listCityCommission(@Param("city") String city, @Param("record_id") String record_id); + + List findManagerByTeamType(@Param("bd_type") String bdType, @Param("record_id") String record_id); } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDPrizeLogMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDPrizeLogMapper.java index c49a8cedf..2342a4a73 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDPrizeLogMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/financial/FinancialBDPrizeLogMapper.java @@ -32,7 +32,7 @@ public interface FinancialBDPrizeLogMapper { @AdvanceSelect(addonWhereClause = "prize_type=0") List findByReportAndBD(@Param("record_id") String recordId, @Param("manager_id") String managerId); - @Select("SELECT prize_log_id,record_id,manager_id,bd_name,bd_level,SUM(total_amount) total_amount, " + + @Select("SELECT prize_log_id,record_id,kpi_amount,manager_id,bd_name,bd_level,SUM(total_amount) total_amount, " + "SUM(total_prize) total_prize,SUM(total_donation) total_donation, SUM(send_prize) send_prize, " + "SUM(hold_prize) hold_prize,last_punish,prize_type FROM financial_bd_prize_log fbpl " + "where fbpl.prize_type = 0 and fbpl.record_id = #{record_id} and fbpl.manager_id = #{manager_id} " + @@ -60,4 +60,11 @@ public interface FinancialBDPrizeLogMapper { @AutoSql(type = SqlType.SELECT) List findReportByOne(@Param("record_id") String recordId, @Param("manager_id") String managerId); + + @Select("SELECT c.manager_id, SUM(total_amount) total_amount, c.bd_type\n" + + "FROM financial_bd_prize_log l\n" + + "INNER JOIN financial_bd_config c ON l.manager_id = c.manager_id\n" + + "WHERE prize_type = 1 AND record_id = #{record_id}\n" + + "GROUP BY l.manager_id") + List findBdPrizeAmountAndBdType(@Param("record_id") String recordId); } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.java index 9ee7f24e5..02e44f2c3 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.java @@ -22,6 +22,4 @@ public interface ClearingDistributedSurchargeMapper { List getMonthDetailByClientId(@Param("datefrom") Date datefrom, @Param("dateto") Date dateto); List findTransactionsByDate(JSONObject params); - - } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.java index 627d47cbe..eb598b9b4 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.java @@ -13,6 +13,9 @@ import java.util.List; @AutoMapper(tablename = "financial_surcharge_account_detail", pkName = "detail_id") public interface FinancialSurchargeAccountDetailMapper { + @AutoSql(type = SqlType.SELECT) + JSONObject findByDetailId(@Param("detail_id") String detail_id); + List findDetailsByMonth(@Param("settle_month") String settle_month); List findDetailsByClientId(@Param("client_id") int client_id); @@ -20,9 +23,11 @@ public interface FinancialSurchargeAccountDetailMapper { @AutoSql(type = SqlType.INSERT) void save(JSONObject detail); - List listSettlementDatesInMonth(@Param("month") String month); - + @AutoSql(type = SqlType.UPDATE) + void update(JSONObject detail); + List listSettlementDatesInMonth(@Param("month") String month); + List listSettlementDatesByClientId(@Param("client_id") int client_id); } 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 4c6106903..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 @@ -287,6 +287,8 @@ public interface ClientManager { List getAccountTransactions(JSONObject account,String clientMoniker); + List getAccountDetailByMonths(JSONObject account,String clientMoniker); + List getAccountTransactionsByDate(JSONObject account,String clientMoniker, String date); List getAccountMonthDetails(JSONObject account,String clientMoniker); @@ -414,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 e2e783400..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); @@ -3441,12 +3502,20 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } @Override - public List getAccountTransactionsByDate(JSONObject account, String clientMoniker, String date) { + public List getAccountDetailByMonths(JSONObject account, String clientMoniker) { JSONObject client = getClientInfoByMoniker(clientMoniker); if (client == null) { throw new InvalidShortIdException(); } + return financialSurchargeAccountDetailMapper.listSettlementDatesByClientId(client.getIntValue("client_id")); + } + @Override + public List getAccountTransactionsByDate(JSONObject account, String clientMoniker, String date) { + JSONObject client = getClientInfoByMoniker(clientMoniker); + if (client == null) { + throw new InvalidShortIdException(); + } JSONObject params = new JSONObject(); params.put("client_id", client.getIntValue("client_id")); params.put("year", date.substring(0, 4)); 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 25e7ae85d..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 @@ -195,6 +195,18 @@ public class PartnerViewController { return clientManager.getAccountTransactions(manager, clientMoniker); } + @PartnerMapping(value = "/{clientMoniker}/account/transactions/date", method = RequestMethod.GET, roles = {PartnerRole.ADMIN, PartnerRole.MANAGER}) + @ResponseBody + public List accountTransactionsByDate(@ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject manager, @PathVariable String clientMoniker,@RequestParam String date) { + return clientManager.getAccountTransactionsByDate(manager, clientMoniker, date); + } + + @PartnerMapping(value = "/{clientMoniker}/account/months", method = RequestMethod.GET, roles = {PartnerRole.ADMIN, PartnerRole.MANAGER}) + @ResponseBody + public List getAccountDetailByMonths(@ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject manager, @PathVariable String clientMoniker){ + return clientManager.getAccountDetailByMonths(manager, clientMoniker); + } + @PartnerMapping(value = "/accounts/{accountId}/audit_refund", method = RequestMethod.PUT, roles = PartnerRole.ADMIN) @ResponseBody public void toggleAccountAuditRefund(@PathVariable String accountId, @ModelAttribute(CommonConsts.PARTNER_STATUS) JSONObject account, @RequestBody JSONObject enable) { @@ -271,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/ofei/core/impl/OfeiClientImpl.java b/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiClientImpl.java index 4935aedf5..645afdd93 100644 --- a/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiClientImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiClientImpl.java @@ -5,6 +5,7 @@ import au.com.royalpay.payment.manage.mappers.ofei.TopUpOrderMapper; import au.com.royalpay.payment.manage.ofei.core.OfeiClient; import au.com.royalpay.payment.manage.ofei.enums.OfeiType; import au.com.royalpay.payment.tools.codec.MD5Hash; +import au.com.royalpay.payment.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.ServerErrorException; import au.com.royalpay.payment.tools.fixing.FixedDocumentHelper; @@ -84,7 +85,7 @@ public class OfeiClientImpl implements OfeiClient { params.add(new BasicNameValuePair("sporder_id", orderId)); params.add(new BasicNameValuePair("sporder_time", DateFormatUtils.format(now, "yyyyMMddHHmmss"))); params.add(new BasicNameValuePair("game_userid", phoneNumber)); - params.add(new BasicNameValuePair("ret_url", "https://mpay.royalpay.com.au/ofei/notice/"+orderId)); + params.add(new BasicNameValuePair("ret_url", PlatformEnvironment.getEnv().concatUrl("/ofei/notice/"+orderId))); saveOrder(orderId, now, OfeiType.PHONE.getMask(), price, phoneNumber); HttpRequestGenerator req = initRequest(topUPUrl, signAndEncryptForm(params), RequestMethod.GET); @@ -220,11 +221,11 @@ public class OfeiClientImpl implements OfeiClient { params.add(new BasicNameValuePair("sporder_id", orderId)); params.add(new BasicNameValuePair("sporder_time", DateFormatUtils.format(now, "yyyyMMddHHmmss"))); params.add(new BasicNameValuePair("game_userid", qqNumber)); - params.add(new BasicNameValuePair("ret_url", "https://mpay.royalpay.com.au/ofei/notice/"+orderId)); + params.add(new BasicNameValuePair("ret_url", PlatformEnvironment.getEnv().concatUrl("/ofei/notice/" + orderId))); saveOrder(orderId, now, OfeiType.QB.getMask(), price, qqNumber); HttpRequestGenerator req = initRequest(qbTopUpUrl, signAndEncryptForm(params), RequestMethod.POST); Element respXml = executeRequestXML(req, "ofei QB top up fail"); - handleResponse(orderId, respXml,qqNumber); + handleResponse(orderId, respXml, qqNumber); } diff --git a/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/ActRedPackServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/ActRedPackServiceImpl.java index 85346e19e..833728814 100644 --- a/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/ActRedPackServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/ActRedPackServiceImpl.java @@ -13,6 +13,7 @@ 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; import au.com.royalpay.payment.tools.connections.mpsupport.beans.WechatRedpack; +import au.com.royalpay.payment.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.exceptions.ForbiddenException; import au.com.royalpay.payment.tools.exceptions.NotFoundException; import au.com.royalpay.payment.tools.utils.PageListUtils; @@ -190,7 +191,7 @@ public class ActRedPackServiceImpl implements ActRedPackService { JSONObject prizeDetail = actRedPacketsCustomerOrdersMapper.findLockedPrize(lock, paymentOpenId); BigDecimal luckyMoeny = prizeDetail.getBigDecimal("red_packet_amount"); String redPackOrderId = prizeDetail.getString("red_packet_order_id"); - String notifyUrl = "https://mpay.royalpay.com.au/sys/lucky_money/customer/redpacks/" + redPackOrderId + "/notify"; + String notifyUrl = PlatformEnvironment.getEnv().concatUrl("/sys/lucky_money/customer/redpacks/" + redPackOrderId + "/notify"); JSONObject customerRelation = customerMapper.findCustomerByOpenId(paymentOpenId); if (customerRelation == null) { customerRelation = customerMapper.findCustomerGlobalpayByOpenId(paymentOpenId); diff --git a/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/PartnerLMServiceImp.java b/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/PartnerLMServiceImp.java index 79aa60964..61d123b89 100644 --- a/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/PartnerLMServiceImp.java +++ b/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/PartnerLMServiceImp.java @@ -8,6 +8,7 @@ import au.com.royalpay.payment.manage.mappers.system.CustomerMapper; import au.com.royalpay.payment.manage.merchants.beans.PartnerQuery; import au.com.royalpay.payment.manage.merchants.core.ClientManager; import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApiProvider; +import au.com.royalpay.payment.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.permission.enums.ManagerRole; import au.com.royalpay.payment.manage.redpack.beans.ActTypeEnum; import au.com.royalpay.payment.manage.redpack.beans.RedpackQuery; @@ -263,7 +264,7 @@ public class PartnerLMServiceImp implements PartnerLMService { String sendName = "RoyalPay"; String actName = act.getString("act_name"); String wishing = "恭喜获得ROYALPAY红包奖励"; - String notifyUrl = "https://mpay.royalpay.com.au/sys/lucky_money/partner/" + red_packet_order_id + "notify"; + String notifyUrl = PlatformEnvironment.getEnv().concatUrl("/sys/lucky_money/partner/" + red_packet_order_id + "notify"); WechatRedpack wechatRedpack = new WechatRedpack(); JSONObject customerRelation = customerMapper.findCustomerByOpenId(open_id); diff --git a/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/RedpackServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/RedpackServiceImpl.java index 0d8c28481..2b2be2755 100644 --- a/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/RedpackServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/redpack/core/impls/RedpackServiceImpl.java @@ -13,6 +13,7 @@ import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApi; import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApiProvider; import au.com.royalpay.payment.tools.connections.mpsupport.beans.AlipayRedpack; import au.com.royalpay.payment.tools.connections.mpsupport.beans.WechatRedpack; +import au.com.royalpay.payment.tools.env.PlatformEnvironment; import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.utils.CurrencyAmountUtils; import au.com.royalpay.payment.tools.utils.PageListUtils; @@ -410,7 +411,7 @@ public class RedpackServiceImpl implements RedpackService { String red_packet_order_id = prizeDetail.getString("red_packet_order_id"); String sendName = "RoyalPay皇家支付"; String wishing = "恭喜获得ROYALPAY店长福利红包"; - String notifyUrl = "https://mpay.royalpay.com.au/sys/lucky_money/partner/" + red_packet_order_id + "notify"; + String notifyUrl = PlatformEnvironment.getEnv().concatUrl("/sys/lucky_money/partner/" + red_packet_order_id + "notify"); WechatRedpack wechatRedpack = new WechatRedpack(); JSONObject customerRelation = customerMapper.findCustomerByOpenId(open_id); 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/surchargeAccount/core/SurchargeAccountService.java b/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/core/SurchargeAccountService.java index 1b86f2c97..fb86eaf0a 100644 --- a/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/core/SurchargeAccountService.java +++ b/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/core/SurchargeAccountService.java @@ -11,4 +11,6 @@ public interface SurchargeAccountService { List listSettledDatesInMonth(String mon); + void fillMothsSurcharge(JSONObject manager, String detail_id); + } diff --git a/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/core/impl/SurchargeAccountServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/core/impl/SurchargeAccountServiceImpl.java index cf83bdac9..9d4834288 100644 --- a/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/core/impl/SurchargeAccountServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/core/impl/SurchargeAccountServiceImpl.java @@ -1,9 +1,15 @@ package au.com.royalpay.payment.manage.surchargeAccount.core.impl; import au.com.royalpay.payment.manage.mappers.system.ClearingDistributedSurchargeMapper; +import au.com.royalpay.payment.manage.mappers.system.ClientsSurchargeAccountsMapper; import au.com.royalpay.payment.manage.mappers.system.FinancialSurchargeAccountDetailMapper; import au.com.royalpay.payment.manage.surchargeAccount.core.SurchargeAccountService; import au.com.royalpay.payment.manage.system.core.impl.ClientContractServiceImpl; +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.lock.Locker; +import au.com.royalpay.payment.tools.permission.enums.ManagerRole; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.time.DateFormatUtils; import org.slf4j.Logger; @@ -12,6 +18,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -24,6 +31,10 @@ public class SurchargeAccountServiceImpl implements SurchargeAccountService{ private ClearingDistributedSurchargeMapper clearingDistributedSurchargeMapper; @Resource private FinancialSurchargeAccountDetailMapper financialSurchargeAccountDetailMapper; + @Resource + private Locker locker; + @Resource + private ClientsSurchargeAccountsMapper clientsSurchargeAccountsMapper; Logger logger = LoggerFactory.getLogger(ClientContractServiceImpl.class); @@ -40,27 +51,58 @@ public class SurchargeAccountServiceImpl implements SurchargeAccountService{ Date dateto = monthCal.getTime(); monthCal.set(Calendar.MONTH, (monthCal.get(Calendar.MONTH) - 1)); Date datefrom = monthCal.getTime(); - logger.info("===============Start generator surcharge account month detail===============" + new Date()); List thisMonthDetail = clearingDistributedSurchargeMapper.getMonthDetailByClientId(datefrom, dateto); logger.info("this month details : " + thisMonthDetail.toString()); - for (JSONObject detail : thisMonthDetail) { detail.put("send_mail", 0); detail.put("wx_send", 0); detail.put("settle_month", DateFormatUtils.format(datefrom, "yyyy-MM")); detail.put("create_time", new Date()); + detail.put("is_valid", 0); financialSurchargeAccountDetailMapper.save(detail); } - logger.info("===============generator OVER===============" + new Date()); - } @Override public List listSettledDatesInMonth(String mon) { - List settledDates = financialSurchargeAccountDetailMapper.listSettlementDatesInMonth(mon); + return financialSurchargeAccountDetailMapper.listSettlementDatesInMonth(mon); + } - return settledDates; + @Override + public void fillMothsSurcharge(JSONObject manager, String detail_id) { + if (!(ManagerRole.ADMIN.hasRole(manager.getIntValue("role")) || ManagerRole.OPERATOR.hasRole(manager.getIntValue("role")) || ManagerRole.FINANCIAL_STAFF.hasRole(manager.getIntValue("role")))) { + throw new ForbiddenException("无法执行平账操作,权限不足"); + } + JSONObject detail = financialSurchargeAccountDetailMapper.findByDetailId(detail_id); + if (detail.getBooleanValue("is_valid")) { + throw new BadRequestException("该记录已结清"); + } + if (!locker.lock(detail.getIntValue("client_id") + "_" + detail.getString("settle_month") + "_fill", 120_000)) { + throw new ServerErrorException("Processing task, wait for a moment"); + } + try { + JSONObject surcharge_account = clientsSurchargeAccountsMapper.find(detail.getIntValue("client_id")); + JSONObject transaction = new JSONObject(); + transaction.put("client_id", detail.getIntValue("client_id")); + transaction.put("type", "Credit"); + transaction.put("total_surcharge", BigDecimal.ZERO); + transaction.put("tax_amount", BigDecimal.ZERO); + transaction.put("amount", detail.getBigDecimal("debit_amount").negate()); + transaction.put("post_balance", surcharge_account.getBigDecimal("balance").add(transaction.getBigDecimal("amount"))); + transaction.put("operation", manager.getString("manager_id")); + transaction.put("create_time", new Date()); + transaction.put("remark", detail.getString("settle_month")+"冲正"); + clearingDistributedSurchargeMapper.save(transaction); + + surcharge_account.put("balance", surcharge_account.getBigDecimal("balance").add(transaction.getBigDecimal("amount"))); + clientsSurchargeAccountsMapper.update(surcharge_account); + detail.put("is_valid", 1); + detail.put("operator_id", manager.getString("manager_id")); + financialSurchargeAccountDetailMapper.update(detail); + } finally { + locker.unlock(detail.getIntValue("client_id") + "_" + detail.getString("settle_month") + "_fill"); + } } } diff --git a/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/web/SurchargeAccountController.java b/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/web/SurchargeAccountController.java index 114f4ba4e..ca7729a21 100644 --- a/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/web/SurchargeAccountController.java +++ b/src/main/java/au/com/royalpay/payment/manage/surchargeAccount/web/SurchargeAccountController.java @@ -19,7 +19,6 @@ import java.util.List; @RestController public class SurchargeAccountController { - @Resource private SurchargeAccountService surchargeAccountService; @@ -27,4 +26,9 @@ public class SurchargeAccountController { public List surchargeAccountSettledDates(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String month) { return surchargeAccountService.listSettledDatesInMonth(month); } + + @ManagerMapping(value = "/fill/{detail_id}", role = {ManagerRole.ADMIN, ManagerRole.OPERATOR, ManagerRole.FINANCIAL_STAFF}, method = RequestMethod.PUT) + public void fillMothsSurcharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String detail_id) { + surchargeAccountService.fillMothsSurcharge(manager, detail_id); + } } diff --git a/src/main/java/au/com/royalpay/payment/manage/task/SurchargeAccountMonthTask.java b/src/main/java/au/com/royalpay/payment/manage/task/SurchargeAccountMonthTask.java index 4897b1e2b..eaa7e9031 100644 --- a/src/main/java/au/com/royalpay/payment/manage/task/SurchargeAccountMonthTask.java +++ b/src/main/java/au/com/royalpay/payment/manage/task/SurchargeAccountMonthTask.java @@ -16,10 +16,7 @@ public class SurchargeAccountMonthTask { @Resource private SurchargeAccountService surchargeAccountService; - - - - @Scheduled(cron = "0 30 6 1 * ?") + @Scheduled(cron = "0 30 23 1 * ?") public void generateSurchargeAccountDetail() { synchronizedScheduler.executeProcess("manage_task:generateSurchargeAccountMonth", 120_000, () -> surchargeAccountService.generatorMonthDetail()); 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/analysis/mappers/CustomerAndOrdersStatisticsMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/analysis/mappers/CustomerAndOrdersStatisticsMapper.xml index 7b1ee8337..1f6968ad9 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/analysis/mappers/CustomerAndOrdersStatisticsMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/analysis/mappers/CustomerAndOrdersStatisticsMapper.xml @@ -315,27 +315,39 @@ - s.client_id != 0 + s.client_id != 0 and c.is_valid=1 and c.client_id in (SELECT b.client_id FROM sys_client_bd b INNER JOIN financial_bd_config c ON c.manager_id=b.bd_id diff --git a/src/main/resources/au/com/royalpay/payment/manage/analysis/mappers/TransactionAnalysisMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/analysis/mappers/TransactionAnalysisMapper.xml index 4d2ce0961..58fd889e6 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/analysis/mappers/TransactionAnalysisMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/analysis/mappers/TransactionAnalysisMapper.xml @@ -804,11 +804,11 @@ + \ No newline at end of file diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.xml index 637cd471f..214a67c88 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/financial/FinancialBDConfigMapper.xml @@ -82,4 +82,47 @@ AND fbpl.prize_type <> 1 ]]> + + \ No newline at end of file diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.xml index 99897a8f2..5632543bf 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/ClearingDistributedSurchargeMapper.xml @@ -4,8 +4,10 @@ - \ No newline at end of file + diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.xml index 6976f1a2c..9c7522d7e 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/system/FinancialSurchargeAccountDetailMapper.xml @@ -20,8 +20,19 @@ SELECT d.*,c.client_moniker,c.short_name,c.company_name,s.balance FROM financial_surcharge_account_detail d INNER JOIN sys_clients c ON c.client_id=d.client_id LEFT JOIN sys_clients_surcharge_accounts s ON s.client_id = d.client_id - WHERE d.settle_month= #{month} + WHERE + d.settle_month= #{month} ORDER BY s.balance ASC ]]> + \ 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/manage.html b/src/main/ui/manage.html index 38d1a8ee3..b48bb960b 100644 --- a/src/main/ui/manage.html +++ b/src/main/ui/manage.html @@ -608,6 +608,11 @@ margin-bottom: 10%;"/> 商户欠款|Pre Refund
  • +
  • + + 后付费收款 + +
  • @@ -771,6 +776,11 @@ margin-bottom: 10%;"/> BD提成|BD Commissions +
  • + + BD数据分析|BD Data Analysis + +
  • BD绩效设置 diff --git a/src/main/ui/static/activity/encourage/encourage.js b/src/main/ui/static/activity/encourage/encourage.js index aa5d19358..40addabc7 100644 --- a/src/main/ui/static/activity/encourage/encourage.js +++ b/src/main/ui/static/activity/encourage/encourage.js @@ -29,6 +29,7 @@ define(['angular', 'uiRouter'], function (angular) { $scope.loadEvents(); $scope.newEvent = function () { $uibModal.open({ + backdrop: 'static', keyboard: false, templateUrl: '/static/activity/encourage/templates/encourage_modify.html', controller: 'newEncourageEventCtrl' }).result.then(function () { @@ -145,6 +146,7 @@ define(['angular', 'uiRouter'], function (angular) { $scope.loadUseLogs(1); $scope.modifyEvent = function () { $uibModal.open({ + backdrop: 'static', keyboard: false, templateUrl: '/static/activity/encourage/templates/encourage_modify.html', controller: 'modifyEventCtrl', resolve: { diff --git a/src/main/ui/static/analysis/bd-prize-analysis.js b/src/main/ui/static/analysis/bd-prize-analysis.js new file mode 100644 index 000000000..b14e9fc47 --- /dev/null +++ b/src/main/ui/static/analysis/bd-prize-analysis.js @@ -0,0 +1,364 @@ +define(['angular', 'uiBootstrap', 'uiRouter'], function (angular) { + 'use strict'; + var app = angular.module('bdPrizeDataAnalysis', ['ui.bootstrap', 'ui.router']); + + app.config(['$stateProvider', function ($stateProvider) { + $stateProvider.state('analysis_bd.bd_data_analysis', { + url: '/bd_data_analysis', + templateUrl: '/static/config/bdprize/templates/bd_data_analysis.html', + controller: 'bdPrizeDataAnalysisCtrl' + }) + }]); + app.controller('bdPrizeDataAnalysisCtrl', ['$scope', '$filter', '$http', function ($scope, $filter, $http) { + $scope.bdprize = {}; + $scope.getBDTeamKpi = function (month) { + $http.get('/sys/bd_prize/commission/'+ month +'/completion_degree').then(function (resp) { + $scope.BDTeamKpi = $scope.getBDTeamKpiEcharts(resp.data); + if (resp.data) { + $scope.getBdProportion(resp.data[0].bd_type); + } + }); + }; + + $scope.getBdProportion = function (teamType) { + $http.get('/sys/bd_prize/commission/'+ $scope.month +'/bd_proportion/' + teamType).then(function (resp) { + $scope.bdProportion = $scope.getBdAmountProportion(resp.data, teamType); + $scope.bdProportionData = resp.data; + if (resp.data) { + $scope.getBdKpiCompletionDegree(resp.data[0].manager_id); + } + }) + }; + $scope.getBdKpiCompletionDegree = function(manager_id) { + $http.get('/sys/bd_prize/commission/'+ $scope.month +'/bd_user_kpi/' + manager_id).then(function (resp) { + $scope.bdKpi = $scope.getBdKpi(resp.data); + $scope.bdKpiData = resp.data; + }) + }; + $scope.bdTeamKpiEcharts = function (chart) { + chart.on('click', function (params) { + $scope.getBdProportion($scope.BDTeamKpiData[params.seriesIndex].bd_type); + }) + }; + $scope.bdProportionEcharts = function(chart) { + chart.on('click', function (params) { + var managerId = $scope.bdProportionData[params.dataIndex].manager_id; + $scope.getBdKpiCompletionDegree(managerId); + }) + }; + + $scope.selectBdPrizeAnalysis = function () { + var month = $filter('date')(new Date(), 'yyyy-MM'); + if ($scope.bdprize.month) { + month = $filter('date')($scope.bdprize.month, 'yyyy-MM'); + } + $scope.month = month; + $scope.getBDTeamKpi(month); + }; + $scope.selectBdPrizeAnalysis(); + $scope.getBDTeamKpiEcharts = function(data){ + var BDTeamKpi = { + tooltip : { + formatter: "{a}
    {c} {b}" + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + series : [ + { + name:'KPI', + type:'gauge', + z: 3, + min:0, + max:100, + splitNumber:10, + axisLine: { // 坐标轴线 + lineStyle: { // 属性lineStyle控制线条样式 + width: 10 + } + }, + axisTick: { // 坐标轴小标记 + length :15, // 属性length控制线长 + lineStyle: { // 属性lineStyle控制线条样式 + color: 'auto' + } + }, + splitLine: { // 分隔线 + length :20, // 属性length控制线长 + lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 + color: 'auto' + } + }, + title : { + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder', + fontSize: 20, + fontStyle: 'italic' + } + }, + detail : { + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder' + } + }, + data:[{value: 0, name: '完成度'}] + }, + { + name:'KPI', + type:'gauge', + center : ['25%', '55%'], // 默认全局居中 + radius : '50%', + min:0, + max:100, + endAngle:45, + splitNumber:10, + axisLine: { // 坐标轴线 + lineStyle: { // 属性lineStyle控制线条样式 + width: 8 + } + }, + axisTick: { // 坐标轴小标记 + length :12, // 属性length控制线长 + lineStyle: { // 属性lineStyle控制线条样式 + color: 'auto' + } + }, + splitLine: { // 分隔线 + length :20, // 属性length控制线长 + lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 + color: 'auto' + } + }, + pointer: { + width:5 + }, + title : { + offsetCenter: [0, '-30%'], // x, y,单位px + }, + detail : { + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder' + } + }, + data:[{value: 0, name: ''}] + }, + { + name:'KPI', + type:'gauge', + center : ['75%', '55%'], // 默认全局居中 + radius : '50%', + min:0, + max:100, + startAngle:135, + endAngle:-45, + splitNumber:10, + axisLine: { // 坐标轴线 + lineStyle: { // 属性lineStyle控制线条样式 + width: 8 + } + }, + axisTick: { // 坐标轴小标记 + length :12, // 属性length控制线长 + lineStyle: { // 属性lineStyle控制线条样式 + color: 'auto' + } + }, + splitLine: { // 分隔线 + length :20, // 属性length控制线长 + lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 + color: 'auto' + } + }, + pointer: { + width:5 + }, + title : { + offsetCenter: [0, '-30%'], // x, y,单位px + }, + detail : { + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder' + } + }, + data:[{value: 0, name: ''}] + } + ] + }; + angular.forEach(data, function(data, index){ + data["team_name"] = $scope.filterBdType(data.bd_type); + BDTeamKpi.series[index].data[0] = {"value":(data.completionDegree*100).toFixed(2), + "name":$scope.filterBdType(data.bd_type)} + }); + $scope.BDTeamKpiData = data; + return BDTeamKpi; + }; + $scope.getBdAmountProportion = function(data, teamType) { + var bdProportion = { + title : { + text: 'BD总金额分布', + x:'center' + }, + tooltip : { + trigger: 'item', + formatter: "{a}
    {b} : {c} ({d}%)" + }, + legend: { + orient : 'vertical', + x : 'left', + data:[] + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + dataView : {show: true, readOnly: false}, + magicType : { + show: true, + type: ['pie', 'funnel'], + option: { + funnel: { + x: '25%', + width: '50%', + funnelAlign: 'left', + max: 1548 + } + } + }, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + series : [ + { + type:'pie', + radius : '55%', + center: ['50%', '60%'], + data:[ + + ] + } + ] + }; + angular.forEach(data, function(data, index){ + bdProportion.legend.data.push(data.bd_name); + bdProportion.series[0].data.push({"value": data.total_amount, "name": data.bd_name}) + }); + bdProportion.title.text = $scope.filterBdType(teamType) + " BD总金额分布"; + return bdProportion; + }; + $scope.getBdKpi = function(data) { + var bdKpi = { + tooltip : { + formatter: "{a}
    {b} : {c}%" + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + series : [ + { + name:'业务指标', + type:'gauge', + startAngle: 180, + endAngle: 0, + center : ['50%', '90%'], // 默认全局居中 + radius : 320, + axisLine: { // 坐标轴线 + lineStyle: { // 属性lineStyle控制线条样式 + width: 200 + } + }, + axisTick: { // 坐标轴小标记 + splitNumber: 10, // 每份split细分多少段 + length :12, // 属性length控制线长 + }, + axisLabel: { // 坐标轴文本标签,详见axis.axisLabel + formatter: function(v){ + switch (v+''){ + case '10': return '低'; + case '50': return '中'; + case '90': return '高'; + default: return ''; + } + }, + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#fff', + fontSize: 15, + fontWeight: 'bolder' + } + }, + pointer: { + width:10, + length: '80%', + color: 'rgba(0, 0, 0, 0.8)' + }, + title : { + show : true, + offsetCenter: [0, '-60%'], // x, y,单位px + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#fff', + fontSize: 30 + } + }, + detail : { + show : true, + backgroundColor: 'rgba(0,0,0,0)', + borderWidth: 0, + borderColor: '#ccc', + width: 100, + height: 40, + offsetCenter: [0, -40], // x, y,单位px + formatter:'{value}%', + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontSize : 50 + } + }, + data:[{value: 0, name: '完成率'}] + } + ] + }; + bdKpi.series[0].data[0] = {"value":(data.total_amount/data.kpi_amount*100).toFixed(2),"name":data.bd_name + "完成度"}; + return bdKpi; + } + $scope.filterBdType = function (type) { + switch (type) { + case 1: + return 'Sydney'; + case 2: + return 'KA Manager'; + case 6: + return 'Melbourne'; + case 7: + return 'KA Manager'; + } + } + }]); + app.filter('financialBdLevel', function () { + return function (level) { + switch (level) { + case 0: + return 'Leader'; + case 1: + return 'Junior'; + case 2: + return 'Intermediate'; + case 3: + return 'Senior'; + default: + return 'Unknown'; + } + } + }); + + return app; +}); \ No newline at end of file diff --git a/src/main/ui/static/analysis/templates/trans_analysis.html b/src/main/ui/static/analysis/templates/trans_analysis.html index c8d163dd7..cee216777 100644 --- a/src/main/ui/static/analysis/templates/trans_analysis.html +++ b/src/main/ui/static/analysis/templates/trans_analysis.html @@ -6,6 +6,11 @@ .cen table th { text-align: center; } + + .channel .col-sm-2 { + border: 1px solid #d2d6de; + border-left: 0; + } + +
    RPay+
    -
    - +
    +
    + +
    Yeepay
    -
    - +
    +
    + +
    LakalaPay
    -
    - +
    +
    + +
    diff --git a/src/main/ui/static/analysis/templates/trans_analysis_monthly.html b/src/main/ui/static/analysis/templates/trans_analysis_monthly.html index f4c2f8acd..fa5a95243 100644 --- a/src/main/ui/static/analysis/templates/trans_analysis_monthly.html +++ b/src/main/ui/static/analysis/templates/trans_analysis_monthly.html @@ -6,6 +6,11 @@ .cen table th { text-align: center; } + + .channel .col-sm-2 { + border: 1px solid #d2d6de; + border-left: 0; + } -
    - +
    diff --git a/src/main/ui/static/payment/surchargeaccount/partner-surcharge-account.js b/src/main/ui/static/payment/surchargeaccount/partner-surcharge-account.js index 161f419fc..c122470b7 100644 --- a/src/main/ui/static/payment/surchargeaccount/partner-surcharge-account.js +++ b/src/main/ui/static/payment/surchargeaccount/partner-surcharge-account.js @@ -21,18 +21,16 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func controller: 'surchargeAccountMonthCtrl' }) }]); - app.controller('clientSurchargeAccountCtrl', ['$scope', '$http','$state','$filter', 'commonDialog','partner', function ($scope, $http,$state,$filter, commonDialog, partner) { + app.controller('clientSurchargeAccountCtrl', ['$scope', '$http','$state','$filter', 'commonDialog','partner','$uibModal', function ($scope, $http,$state,$filter, commonDialog, partner,$uibModal) { $scope.partner = angular.copy(partner.data); $scope.getBalance = function () { $scope.surcharge = {}; - if ($scope.partner.surcharge_mode != undefined && $scope.partner.surcharge_mode == "distributed") { $http.get('/client/partner_info/' + $scope.partner.client_moniker + '/surcharge_account').then(function (resp) { $scope.surcharge = resp.data; }) - } }; @@ -45,10 +43,36 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func $scope.getBalance(); $scope.getTransactions(); + $scope.getDetailByMonths = function () { + $http.get('/client/partner_info/' + $scope.partner.client_moniker + '/account/months').then(function (resp) { + $scope.report = resp.data; + }) + }; + $scope.getDetailByMonths(); + $scope.surchargeAccountDetail = function (client_moniker,mon) { + $uibModal.open({ + templateUrl: '/static/payment/surchargeaccount/templates/client_surcharge_account_dialog.html', + controller: 'accountDetailCtrl', + size: 'lg', + resolve: { + client_moniker: function () { + return client_moniker; + }, + month: function () { + return mon; + }, + transactions: ['$http', function ($http) { + return $http.get('/client/partner_info/' + client_moniker + '/account/transactions/date?date=' + mon); + }] + } + }); + }; + + }]); - app.controller('surchargeAccountMonthCtrl', ['$scope', '$http', '$filter', '$timeout', '$uibModal', 'commonDialog', 'chartParser', - function ($scope, $http, $filter, $timeout, $uibModal, commonDialog, chartParser) { + app.controller('surchargeAccountMonthCtrl', ['$scope', '$http', '$filter', '$timeout', '$uibModal', 'commonDialog', 'chartParser','$sce', + function ($scope, $http, $filter, $timeout, $uibModal, commonDialog, chartParser, $sce) { $scope.params = {year: new Date().getFullYear()}; $scope.availableYears = [new Date().getFullYear() - 1, new Date().getFullYear()]; $scope.initMonth = function (year) { @@ -67,7 +91,6 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func return start <= mon && end >= mon }; $scope.loadReport = function (mon) { - $http.get('/sys/surcharge_account/month/' + mon + '/settled_dates').then(function (resp) { $scope.report = { month: mon, @@ -97,6 +120,25 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func $scope.loadReport($scope.report.month); }); }; + $scope.fillMonthsSurcharge = function (details) { + var contentHtml = $sce.trustAsHtml('即将为[' + details.short_name + ']冲正,请确认商户信息'); + + commonDialog.confirm({ + title: '后付费账户冲正', + content: '', + choises: [{label: 'OK', className: 'btn-success', key: '1'}, + {label: 'Cancel', className: 'btn-danger', key: '2', dismiss: true}], + contentHtml: contentHtml + }).then(function () { + $http.put('/sys/surcharge_account/fill/' + details.detail_id).then(function () { + commonDialog.alert({title: 'Success', content: '冲正成功', type: 'success'}); + $scope.loadReport($scope.report.month); + }, function (resp) { + commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'}); + }); + }) + + }; diff --git a/src/main/ui/static/payment/surchargeaccount/templates/account_month_logs.html b/src/main/ui/static/payment/surchargeaccount/templates/account_month_logs.html index 2b2a39c8b..acc93428d 100644 --- a/src/main/ui/static/payment/surchargeaccount/templates/account_month_logs.html +++ b/src/main/ui/static/payment/surchargeaccount/templates/account_month_logs.html @@ -46,26 +46,38 @@ 商户编号 Short Name + Total Surcharge 充值总额 支出总额 - 余额 + 是否结清 + 操作 - - - - - - {{details.balance|currency:'$'}} - {{details.balance|currency:'$'}} + +
    + - + + + + + + 已结清 + 未付款 + + + + + + + diff --git a/src/main/ui/static/payment/surchargeaccount/templates/client_surcharge_account.html b/src/main/ui/static/payment/surchargeaccount/templates/client_surcharge_account.html index 184c4becb..43e3e0e12 100644 --- a/src/main/ui/static/payment/surchargeaccount/templates/client_surcharge_account.html +++ b/src/main/ui/static/payment/surchargeaccount/templates/client_surcharge_account.html @@ -1,4 +1,3 @@ -

    Client Surcharge Account @@ -14,40 +13,31 @@
    -
    +

    {{surcharge.balance|currency:'AUD'}}

    - - - - - + + + + + - - - - - - - + + + + + + +
    -
    @@ -112,3 +102,46 @@

    +
    +

    + 每月手续费 +

    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + +
    清算月份Total Surcharge支出总额是否结清操作
    + 已结清 + 未付款 + + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/main/ui/static/payment/surchargeaccount/templates/client_surcharge_account_dialog.html b/src/main/ui/static/payment/surchargeaccount/templates/client_surcharge_account_dialog.html new file mode 100644 index 000000000..acf867ea1 --- /dev/null +++ b/src/main/ui/static/payment/surchargeaccount/templates/client_surcharge_account_dialog.html @@ -0,0 +1,39 @@ + + diff --git a/src/main/ui/static/payment/surchargeaccount/templates/partner_surcharge_account_dialog.html b/src/main/ui/static/payment/surchargeaccount/templates/partner_surcharge_account_dialog.html index 43d081316..8ebfc3457 100644 --- a/src/main/ui/static/payment/surchargeaccount/templates/partner_surcharge_account_dialog.html +++ b/src/main/ui/static/payment/surchargeaccount/templates/partner_surcharge_account_dialog.html @@ -78,7 +78,12 @@ - + + {{tr.remark}} + + + + 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"> - diff --git a/src/main/ui/static/risk/risk.js b/src/main/ui/static/risk/risk.js index 8bfe25bf8..8d84298cd 100644 --- a/src/main/ui/static/risk/risk.js +++ b/src/main/ui/static/risk/risk.js @@ -262,6 +262,7 @@ define(['angular', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootS }; $scope.addAttention = function () { $uibModal.open({ + backdrop: 'static', keyboard: false, templateUrl: '/static/risk/templates/risk_add.html', controller: 'newRiskCtrl' }).result.then(function () { @@ -271,6 +272,7 @@ define(['angular', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootS $scope.editAttention = function (attention) { $uibModal.open({ + backdrop: 'static', keyboard: false, templateUrl: '/static/risk/templates/risk_merchant_edit.html', controller: 'editRiskCtrl', resolve:{ @@ -331,6 +333,7 @@ define(['angular', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootS }; $scope.save = function () { $uibModal.open({ + backdrop: 'static', keyboard: false, templateUrl: '/static/risk/templates/new_customer_blacklist.html', controller: 'newCustomerBlackListCtrl' }).result.then(function () { diff --git a/src/main/ui/static/risk/templates/new_customer_blacklist.html b/src/main/ui/static/risk/templates/new_customer_blacklist.html index 02e032830..2933fb637 100644 --- a/src/main/ui/static/risk/templates/new_customer_blacklist.html +++ b/src/main/ui/static/risk/templates/new_customer_blacklist.html @@ -19,6 +19,9 @@
    +
    + +
    diff --git a/src/main/ui/static/templates/cbpay/css/gateway_test.css b/src/main/ui/static/templates/cbpay/css/gateway_test.css new file mode 100644 index 000000000..c47e011fb --- /dev/null +++ b/src/main/ui/static/templates/cbpay/css/gateway_test.css @@ -0,0 +1,229 @@ +.gateway-background { + width:100%; + height:100%; + /*position: fixed;*/ + background: url("../img/gateway_bg.png") no-repeat center center fixed;; + top: 0; + bottom: 0; + right: 0; + left: 0; + z-index: -1; + overflow-y: auto; + /*background-size:100% 100%;*/ + display: flex; + justify-content: center; + align-items: center; + align-content: center; + flex-direction: column; + background-size: cover; +} + +.head-bar{ + display: inline; + text-align: center; +} +.head-bar img{ + width: 500px; + height: 40px; + top: 60px; + margin-top: 40px; +} + +.order-box{ + height: 620px; + width: 800px; + /*margin: 2% auto;*/ + /*box-shadow: 0px 0px 25px 0px rgba(0,0,0,0.21);*/ +} + +.order-box-bank{ + height: 600px; + width: 800px; + /*margin: 2% auto;*/ + /*box-shadow: 0px 0px 25px 0px rgba(0,0,0,0.21);*/ +} + +.order-box:after{ + content:''; + display:block; + clear:both; +} +.order-box .left{ + display: inline; + opacity: 0.84; + background: #f06010; + width:40%; + float: left; + height: 100%; + text-align: center; +} +/*.order-box .left .m-logo{*/ +/*background: #FFFFFF;*/ +/*border-radius: 100px;*/ +/*width: 120px;*/ +/*height: 120px;*/ +/*margin-top: 15%;*/ +/*display: inline-block;*/ +/*}*/ +.m-logo{ + line-height: 100px; +} +.m-logo img{ + width: 100px; + padding: 10px; +} +.short-name{ + margin-top: 40px; + font-family: MicrosoftYaHei; + font-size: 18px; +} +.intro{ + margin: 100px 0 50px; + color: #FFFFFF; +} +.order-box .right{ + display: inline; + background: #FFFFFF; + width:60%; + float: right; + height: 80%; + padding: 20px 40px; +} +.order-box .right-bank{ + display: inline; + background: #FFFFFF; + width:60%; + float: right; + height: 130%; + padding: 20px 40px; +} +.order-box .brand{ + display: inline; + background: #f06010 ; + width:60%; + float: right; + height: 20%; + vertical-align: middle; + text-align: center; +} + +.order-box .brand-bank{ + display: inline; + background: #f06010 ; + width:60%; + float: right; + height: 10%; + vertical-align: middle; + text-align: center; +} + +.order-box .brand img{ + width: 246px; + height: 51px; + margin-top: 7% +} + +.order-box .brand-bank img{ + width: 246px; + height: 51px; + margin-top: 2% +} + +.order-box .right .title { + font-family: PingFang-SC-Medium; + font-size: 20px; + color: #434343; + letter-spacing: 0px; + padding-bottom: 10px; + padding-top: 20px; +} +.order-box .right input { + background-color: #EEEEEE; + border: none; + outline: none; + height: 45px; +} +.order-box .right .form_margin { + +} +.order-box .right .form_input { + height: 45px; +} +.footer-bottom{ + font-family: PingFangSC-Regular; + color: #FFFFFF; + letter-spacing: 0px; + margin-top: 50px; +} + +.footer-bottom-success{ + margin-top: 60px; + color: #444444; +} + +.warning{ + font-size: x-small; + color: #f06010; +} +.submit{ + color: #fff; + background-color: #f06010; + border-color: #f06010; +} +/*成功页*/ +.order-box .success-logo{ + text-align: center; + height: 150px; + background: #F0F3FA; + line-height: 150px; + font-family: PingFangSC-Regular; + font-size: 22px; + color: #444444; + letter-spacing: 0px; + +} + +.order-info{ + padding: 50px 100px; + font-family: PingFangSC-Regular; + font-size: 17px; + color: #444444; + letter-spacing: 0px; +} + +@media(max-width:800px){ + .order-box{ + width:100%; + } + .order-info{ + padding:50px 10px; + } +} + +.gateway-background .modal { + background-color: rgba(0,0,0,.8); +} + +.gateway-background .modal-dialog { + height: 100vh; + display: flex; + justify-content: center; + align-items: center; + align-content: center; +} +.surcharge{ + font-size: 0.8em; + color: #909090; +} +.exchange{ + font-size: 0.8em; + color: #909090; +} +.div-inline { + display: inline; + width: 50%; +} +.div-inline-select { + text-align: center; + text-align-last: center; +} diff --git a/src/main/ui/static/templates/cbpay/yeepay/v1/gateway_jsapi_test.js b/src/main/ui/static/templates/cbpay/yeepay/v1/gateway_jsapi_test.js new file mode 100644 index 000000000..87c615860 --- /dev/null +++ b/src/main/ui/static/templates/cbpay/yeepay/v1/gateway_jsapi_test.js @@ -0,0 +1,243 @@ +var num = function(obj){ + obj.value = obj.value.replace(/[^\d.]/g,""); //清除"数字"和"."以外的字符 + obj.value = obj.value.replace(/^\./g,""); //验证第一个字符是数字 + obj.value = obj.value.replace(/\.{2,}/g,"."); //只保留第一个, 清除多余的 + obj.value = obj.value.replace(".","$#$").replace(/\./g,"").replace("$#$","."); + obj.value = obj.value.replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3'); //只能输入两个小数 + + var surchargeData = calculateSurcharge(obj.value-0); + var surchargeAmount = Decimal.add(surchargeData.surcharge,surchargeData.tax); + var currency = '$'; + if($('#select_currency').val()=='CNY'){ + currency = '¥'; + } + $('#surchargeAmount').html(currency+surchargeAmount+''); + $('#totalAmount').html(currency+surchargeData.newPrice+''); + if(surchargeAmount+0==0 || !window.c4surcharge){ + $('.surcharge').hide(); + }else { + $('.surcharge').show(); + } + +}; +var bankList = [ + {label:'邮政储蓄银行',value:'BANK_CARD-B2C-POST-P2P'}, + {label:'深圳发展银行',value:'BANK_CARD-B2C-SDB-P2P'}, + {label:'民生银行',value:'BANK_CARD-B2C-CMBC-P2P'}, + {label:'北京银行',value:'BANK_CARD-B2C-BCCB-P2P'}, + {label:'上海银行',value:'BANK_CARD-B2C-SHB-P2P'}, + {label:'招商银行',value:'BANK_CARD-B2C-CMBCHINA-P2P'}, + {label:'中信银行',value:'BANK_CARD-B2C-ECITIC-P2P'}, + {label:'浦发银行',value:'BANK_CARD-B2C-SPDB-P2P'}, + {label:'兴业银行',value:'BANK_CARD-B2C-CIB-P2P'}, + {label:'华夏银行',value:'BANK_CARD-B2C-HXB-P2P'}, + {label:'农业银行',value:'BANK_CARD-B2C-ABC-P2P'}, + {label:'广发银行',value:'BANK_CARD-B2C-GDB-P2P'}, + {label:'工商银行',value:'BANK_CARD-B2C-ICBC-P2P'}, + {label:'中国银行',value:'BANK_CARD-B2C-BOC-P2P'}, + {label:'交通银行',value:'BANK_CARD-B2C-BOCO-P2P'}, + {label:'建设银行',value:'BANK_CARD-B2C-CCB-P2P'}, + {label:'平安银行',value:'BANK_CARD-B2C-PINGANBANK-P2P'}, + {label:'光大银行',value:'BANK_CARD-B2C-CEB-P2P'} +]; +var select = $("select#bank-select"); +if (select.val() != "") + select.prev().hide(); +select.bind("change", function () { + if ($(this).val() != "") { + $(this).prev().hide(); + } +}); +function loadBankSelect() { + var bankId = document.getElementById("bank-select"); + for (var i = 0; i < bankList.length; i++) { + var bank = bankList[i]; + var op = document.createElement("option"); + op.setAttribute("value", bank.value); + op.setAttribute("label", bank.label); + bankId.appendChild(op); + } +} +var bank = function (obj) { + obj.value = obj.value.replace(/\s/g, '').replace(/(.{4})/g, "$1 "); +}; + +var reg = /^[0-9]{14,19}$/i; +function checkNum() { + var bankNum = document.getElementById("bank-num").value; + bankNum = bankNum.replace(/\s+/g,""); + if (!(reg.test(bankNum))) { + alert("银行号有误"); + document.getElementById('bank-num').focus(); + document.getElementById('bank-num').style.border = "1px solid #CDC28D"; + return false; + } + document.getElementById('bank-num').style.border = ""; + + return true; + +}; + +function onChange(str,num) { + if (str.length == num) { + return true; + } + return false; +} + + + +$(document).ready(function () { + $('.surcharge').hide(); + var payUrl = window.location.href; + $.cookie("payURL",payUrl,{ expires: 1,path:'/' }); + loadBankSelect(); + + $('#bank-num').bind('keydown', function (e) { + var key = e.which; + var bankNum = $('#bank-num').val(); + + if (bankNum.substring(bankNum.length-1,bankNum.length)==' ' && key == 8) { + $('#bank-num').val(bankNum.substring(0,bankNum.length-2)); + } + + }); + + $('#gateway').click(function() { + if($(this).prop("checked")==true){ + $('.gateway').removeClass("hidden"); + $('#yeepay-order').addClass("order-box-bank"); + $('#yeepay-brand').addClass("brand-bank"); + $('#yeepay-right').addClass("right-bank"); + }else{ + $('.gateway').addClass("hidden"); + $('#yeepay-order').removeClass("order-box-bank"); + $('#yeepay-brand').removeClass("brand-bank"); + $('#yeepay-right').removeClass("right-bank"); + } + + }); + + var customer_id = ""||$.cookie("CustomerID"); + if (customer_id==null||customer_id == ""){ + getQrcode(); + } + function getQrcode(){ + $.ajax({ + url: '/global/userstatus/customer_wechat_qrcode', + method: 'get', + dataType: 'json', + success: function (data) { + $('#qrmodal').find('img#qrimg').attr('src', data.code_img); + $('#qrmodal').show(); + setTimeout(function () { + checkQRStatus(data.code_id) + }, 2000); + }, + error: function (jqXHR) { + alert(jqXHR.responseJSON.message); + } + }) + } + function checkQRStatus(codeId) { + $.ajax({ + url: '/global/userstatus/customer_wechat_qrcode/' + codeId + '/check', + method: 'get', + success: function (data) { + $('#qrmodal').hide(); + customer_id = $.cookie("CustomerID"); + }, + error: function () { + setTimeout(function () { + checkQRStatus(codeId) + }, 2000) + } + }) + } + $('input').keypress(function (evt) { + if (evt.keyCode == 13) { + $('#login-btn').click(); + } + }); + $('#commit-btn').click(function () { + + var price = $('#price').val(); + if (price == null || price.length == 0) { + alert('请填写订单金额'); + return; + } + var product = $('#product').val(); + if (product == null || product.length == 0) { + alert('请填写真实的商品名称'); + return; + } + + var select_currency = $('#select_currency').val(); + var remark = $('#remark').val(); + + var payName = $('#name').val(); + + var cardNum = $('#card-num').val(); + + var bankNum = ($('#bank-num').val()).replace(/\s+/g,""); + + var bankSelect = $('#bank-select').val(); + + var phone = $('#phone').val(); + var jsonData = {user_id:customer_id,price:price,product_name:product,description:remark,currency: select_currency}; + if($('#gateway').prop('checked') == true){ + if (payName == null || onChange(payName,0)) { + alert('请填写支付人姓名'); + return; + } + if (cardNum == null || onChange(cardNum,0) || !onChange(cardNum,18)) { + alert('身份证号有误'); + return; + } + if (bankNum == null || onChange(bankNum,0)) { + alert('请填写银行卡号'); + return; + } + if (bankSelect == null || onChange(bankSelect,0)) { + alert('请选择支付银行'); + return; + } + if (phone == null || !onChange(phone,11)) { + alert('手机号码有误'); + return; + } + jsonData = {user_id:customer_id,price:price,product_name:product,description:remark,currency: select_currency, + payer_name: payName,payer_identity_card: cardNum,card_number: bankNum,bank_id: bankSelect,phone:phone}; + } + + var commit = confirm("是否确认提交支付"); + if (commit){ + $('#commit-btn').addClass('hidden'); + $('#commit-btn-loading').removeClass('hidden'); + $.ajax({ + url: '/api/v1.0/yeepay/partners/'+window.client_moniker+'/share', + method: 'put', + data: JSON.stringify(jsonData), + contentType: 'application/json', + dataType: 'json', + success: function (res) { + if(res.return_code != 'SUCCESS'){ + alert(res.message); + $('#commit-btn').removeClass('hidden'); + $('#commit-btn-loading').addClass('hidden'); + }else { + location.href = res.pay_url+'?'+res.sign_url; + } + }, + error: function (jqXHR) { + alert(JSON.parse(jqXHR.responseText).message); + $('#commit-btn').removeClass('hidden'); + $('#commit-btn-loading').addClass('hidden'); + } + }) + } else { + $('#commit-btn').removeClass('hidden'); + $('#commit-btn-loading').addClass('hidden'); + } + }); +})