Merge branch 'develop'

# Conflicts:
#	src/main/java/au/com/royalpay/payment/manage/appclient/core/impls/ManageAppServiceImp.java
#	src/main/ui/static/payment/partner/templates/add_partner.html
master
taylor.dang 6 years ago
commit d173835b4f

@ -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);
}

@ -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);
}

@ -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<String> 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;
}
}

@ -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<String, AppMsgSender> 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<String> 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;
}
}

@ -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);
}
}

@ -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);
}
}

@ -48,4 +48,10 @@ public interface BDPrizeService {
void exportCommissionDetail(String month, String managerId, HttpServletResponse response);
List<JSONObject> findCommissionList(JSONObject manager);
List<JSONObject> getBDTeamKpiCompletionDegree(String month);
List<JSONObject> getBDProportionByTeamType(String month, String teamType);
JSONObject getBDKpiByManagerId(String month, String manager_id);
}

@ -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<JSONObject> getBDTeamKpiCompletionDegree(String month) {
List<JSONObject> 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<JSONObject> prizeSort = prizeAmountAndBdTypeList.stream()
.sorted((prize1, prize2) -> prize2.getBigDecimal("completionDegree").compareTo(prize1.getBigDecimal("completionDegree")))
.collect(Collectors.toList());
return prizeSort;
}
@Override
public List<JSONObject> 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:

@ -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);
}
/**
* BDKPI
*/
@ManagerMapping(value = "/commission/{month}/completion_degree", method = RequestMethod.GET, role = {ManagerRole.DIRECTOR, ManagerRole.ADMIN})
public List<JSONObject> 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<JSONObject> 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);
}
}

@ -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) {

@ -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();

@ -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);
}
}

@ -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);
}

@ -37,4 +37,6 @@ public interface FinancialBDConfigMapper {
List<JSONObject> listBDCity();
JSONObject listCityCommission(@Param("city") String city, @Param("record_id") String record_id);
List<JSONObject> findManagerByTeamType(@Param("bd_type") String bdType, @Param("record_id") String record_id);
}

@ -32,7 +32,7 @@ public interface FinancialBDPrizeLogMapper {
@AdvanceSelect(addonWhereClause = "prize_type=0")
List<JSONObject> 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<JSONObject> 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<JSONObject> findBdPrizeAmountAndBdType(@Param("record_id") String recordId);
}

@ -22,6 +22,4 @@ public interface ClearingDistributedSurchargeMapper {
List<JSONObject> getMonthDetailByClientId(@Param("datefrom") Date datefrom, @Param("dateto") Date dateto);
List<JSONObject> findTransactionsByDate(JSONObject params);
}

@ -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<JSONObject> findDetailsByMonth(@Param("settle_month") String settle_month);
List<JSONObject> findDetailsByClientId(@Param("client_id") int client_id);
@ -20,9 +23,11 @@ public interface FinancialSurchargeAccountDetailMapper {
@AutoSql(type = SqlType.INSERT)
void save(JSONObject detail);
List<JSONObject> listSettlementDatesInMonth(@Param("month") String month);
@AutoSql(type = SqlType.UPDATE)
void update(JSONObject detail);
List<JSONObject> listSettlementDatesInMonth(@Param("month") String month);
List<JSONObject> listSettlementDatesByClientId(@Param("client_id") int client_id);
}

@ -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;
}
}

@ -287,6 +287,8 @@ public interface ClientManager {
List<JSONObject> getAccountTransactions(JSONObject account,String clientMoniker);
List<JSONObject> getAccountDetailByMonths(JSONObject account,String clientMoniker);
List<JSONObject> getAccountTransactionsByDate(JSONObject account,String clientMoniker, String date);
List<JSONObject> 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);
}

@ -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<JSONObject> getAccountTransactionsByDate(JSONObject account, String clientMoniker, String date) {
public List<JSONObject> 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<JSONObject> 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));

@ -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"));

@ -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<JSONObject> 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<JSONObject> 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 {

@ -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);
}

@ -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);

@ -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);

@ -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);

@ -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;
}
}

@ -27,4 +27,6 @@ public interface ManagerAccountsService {
JSONObject getBDConfig(String bd_id);
List<JSONObject> listServants(JSONObject loginManager);
}
void resetPwd(JSONObject account,String password);
}

@ -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);
}

@ -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<JSONObject> orgs = orgMapper.listOrgAndChild(loginManager.getIntValue("org_id"));

@ -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<String> 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<String> 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<String> 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;
}
}

@ -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 emailphone
*/
@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 emailphone
*/
@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"));
}
}

@ -11,4 +11,6 @@ public interface SurchargeAccountService {
List<JSONObject> listSettledDatesInMonth(String mon);
void fillMothsSurcharge(JSONObject manager, String detail_id);
}

@ -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<JSONObject> 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<JSONObject> listSettledDatesInMonth(String mon) {
List<JSONObject> 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");
}
}
}

@ -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<JSONObject> 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);
}
}

@ -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());

@ -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");

@ -315,27 +315,39 @@
<![CDATA[
select ifnull(sum(CASE WHEN s.channel = 'Alipay' THEN s.total ELSE 0 END),0) alipayamount,
ifnull(sum(CASE WHEN s.channel = 'Alipay' THEN s.orders ELSE 0 END),0) alipay_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'Alipay',TRUE,NULL)),0) alipay_client_count,
ifnull(sum(CASE WHEN s.channel = 'Bestpay' THEN s.total ELSE 0 END),0) bestpayamount,
ifnull(sum(CASE WHEN s.channel = 'Bestpay' THEN s.orders ELSE 0 END),0) bestpay_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'Bestpay',TRUE,NULL)),0) bestpay_client_count,
ifnull(sum(CASE WHEN s.channel = 'Wechat' THEN s.total ELSE 0 END),0) wechatamount,
ifnull(sum(CASE WHEN s.channel = 'Wechat' THEN s.orders ELSE 0 END),0) wechat_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'Wechat',TRUE,NULL)),0) wechat_client_count,
ifnull(sum(CASE WHEN s.channel = 'jd' THEN s.total ELSE 0 END),0) jdamount,
ifnull(sum(CASE WHEN s.channel = 'jd' THEN s.orders ELSE 0 END),0) jd_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'jd',TRUE,NULL)),0) jd_client_count,
ifnull(sum(CASE WHEN s.channel = 'AlipayOnline' THEN s.total ELSE 0 END),0) alipayonlineamount,
ifnull(sum(CASE WHEN s.channel = 'AlipayOnline' THEN s.orders ELSE 0 END),0) alipayonline_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'AlipayOnline',TRUE,NULL)),0) alipayonline_client_count,
ifnull(sum(CASE WHEN s.channel = 'hf' THEN s.total ELSE 0 END),0) hfamount,
ifnull(sum(CASE WHEN s.channel = 'hf' THEN s.orders ELSE 0 END),0) hf_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'hf',TRUE,NULL)),0) hf_client_count,
ifnull(sum(CASE WHEN s.channel = 'Rpay' THEN s.total ELSE 0 END),0) rpayamount,
ifnull(sum(CASE WHEN s.channel = 'Rpay' THEN s.orders ELSE 0 END),0) rpay_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'Rpay',TRUE,NULL)),0) rpay_client_count,
ifnull(sum(CASE WHEN s.channel = 'Yeepay' THEN s.total ELSE 0 END),0) yeepayamount,
ifnull(sum(CASE WHEN s.channel = 'Yeepay' THEN s.orders ELSE 0 END),0) yeepay_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'Yeepay',TRUE,NULL)),0) yeepay_client_count,
ifnull(sum(CASE WHEN s.channel = 'LakalaPay' THEN s.total ELSE 0 END),0) lakalapayamount,
ifnull(sum(CASE WHEN s.channel = 'LakalaPay' THEN s.orders ELSE 0 END),0) lakala_order_count
ifnull(sum(CASE WHEN s.channel = 'LakalaPay' THEN s.orders ELSE 0 END),0) lakala_order_count,
ifnull(COUNT(DISTINCT s.client_id,IF(s.channel = 'LakalaPay',TRUE,NULL)),0) lakala_client_count,
ifnull(sum(s.orders), 0) all_count,
ifnull(sum(s.total), 0) all_amount,
ifnull(COUNT(DISTINCT s.client_id),0) all_client_count
FROM statistics_customer_order s
LEFT JOIN sys_clients c ON c.client_id = s.client_id and c.is_valid=1
LEFT JOIN sys_clients c ON c.client_id = s.client_id
]]>
<where>
s.client_id != 0
s.client_id != 0 and c.is_valid=1
<if test="bd_group!=null">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

@ -804,11 +804,11 @@
<select id="getClientTransaction" resultType="com.alibaba.fastjson.JSONObject">
select
IFNULL(sum(if(l.transaction_type='credit',l.clearing_amount,0)),0) trade_amount,
ifnull(sum(if(l.refund_id>0,l.clearing_amount,0)),0) refund_amount,
ifnull(sum(if(l.transaction_type='Credit',1,0)),0) trade_count,
ifnull(sum(if(l.refund_id>0,1,0)),0) refund_orders
SELECT
IFNULL(sum(if(l.transaction_type='Credit',l.clearing_amount,0)),0) trade_amount,
IFNULL(sum(if(l.transaction_type='Debit',l.clearing_amount,0)),0) refund_amount,
IFNULL(sum(if(l.transaction_type='Credit',1,0)),0) trade_count,
IFNULL(sum(if(l.transaction_type='Debit',1,0)),0) refund_orders
FROM pmt_transactions l
where l.channel!='Settlement' and l.system_generate=0
<if test="client_ids!=null">

@ -23,4 +23,11 @@
AND #{amount} >= COMMISSION_START_AMOUNT
AND #{bd_type} = BD_TYPE
</select>
<select id="findCurrentCommissionMaxAmount" resultType="java.math.BigDecimal">
SELECT ifnull(MAX(commission_start_amount), 1) max_amount
FROM financial_bd_commission_config
WHERE #{month} >= DATE_FORMAT(START_DATE, '%Y-%m')
AND DATE_FORMAT(END_DATE, '%Y-%m') >= #{month}
AND #{bd_type} = BD_TYPE
</select>
</mapper>

@ -82,4 +82,47 @@
AND fbpl.prize_type <> 1
]]>
</select>
<select id="findManagerByTeamType" resultType="com.alibaba.fastjson.JSONObject">
SELECT
config.manager_id,config.bd_name,ifnull(total_amount, 0) total_amount,log.kpi_amount
FROM
(
SELECT
*
FROM
financial_bd_config
WHERE
(
manager_id IN (
SELECT
manager_id
FROM
financial_bd_config c
WHERE
bd_type = #{bd_type}
)
OR bd_group IN (
SELECT
manager_id
FROM
financial_bd_config c
WHERE
bd_type = #{bd_type}
)
)
AND get_prize = 1
) config
LEFT JOIN (
SELECT
manager_id,
SUM(total_amount) total_amount,
kpi_amount
FROM
financial_bd_prize_log l
WHERE
record_id = #{record_id} AND prize_type = 0
group by manager_id
) log ON log.manager_id = config.manager_id
</select>
</mapper>

@ -4,8 +4,10 @@
<select id="getMonthDetailByClientId" resultType="com.alibaba.fastjson.JSONObject">
<![CDATA[
SELECT d.client_id,c.client_moniker,c.company_name,
SUM(IF(d.type='Debit',total_surcharge,-total_surcharge)) total_surcharge,
SUM(IF(d.type='Credit',amount,0)) credit_amount,
SUM(IF(d.type='Debit',amount,0)) debit_amount
SUM(IF(d.type='Debit',amount,0)) debit_amount,
SUM(IF(d.type='Debit',total_surcharge,0)) total_surcharge
FROM log_clearing_distributed_surcharge d INNER JOIN sys_clients c ON c.client_id=d.client_id
WHERE d.create_time >=#{datefrom} AND d.create_time < #{dateto}
AND c.is_valid= 1

@ -18,9 +18,10 @@
</where>
</select>
<select id="partnerAndSubPartnerAccounts" resultType="com.alibaba.fastjson.JSONObject">
SELECT sc.client_moniker, sa.account_id, sa.role, sa.username
SELECT sc.client_moniker,sc.short_name,sc.client_id,sc.parent_client_id, sa.account_id, sa.role, sa.username,sa.contact_phone,sa.contact_email,sa.nation_code,sa.wechat_name,sa.wechat_openid,sa.wxapp_openid,
sa.wx_unionid,sa.wechat_headimg,sa.payment_notice,sa.refund_authorised,sa.display_name
FROM sys_clients sc
INNER JOIN sys_accounts sa ON sc.client_id = sa.client_id AND sa.is_valid = 1
WHERE sc.client_id = #{client_id} OR sc.parent_client_id = #{client_id} AND sc.is_valid = 1
</select>
</mapper>
</mapper>

@ -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
]]>
</select>
<select id="listSettlementDatesByClientId" resultType="com.alibaba.fastjson.JSONObject">
<![CDATA[
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
s.client_id = #{client_id}
ORDER BY s.create_time DESC
]]>
</select>
</mapper>

@ -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 @@
</select>
</mapper>
</mapper>

@ -0,0 +1,31 @@
<html xmlns:th="http://www.thymeleaf.org" lang="zh">
<b>Dear <span th:text="${account.display_name}"></span> :</b>
<p>
Your account(<span th:text="${account.username}"></span>) is in the process of binding a mailbox, the verification code is <u th:text="${captcha}"></u>,valid within 5 minutes.
</p>
<b>尊敬的<span th:text="${account.display_name}"></span>,您好:</b>
<p>
您的账户(<span th:text="${account.username}"></span>)正在进行绑定邮箱的操作,验证码是<u th:text="${captcha}"></u>5分钟内有效。
</p>
<hr>
<h4>Best Regards</h4>
<p>
<img style="width: 120px;height: 120px"
src="https://mpay.royalpay.com.au/static/images/logo_new.jpg"> <br>
Contact Us<br>
Email:<br>
<a href="mailto:info@royalpay.com.au">info@royalpay.com.au</a> <br>
Tel:<br>
1300 10 77 50<br>
<br>
Service WeChat Account:<br>
<img src="https://mpay.royalpay.com.au/static/images/customer_service.jpg"
style="width: 60px"><br>
Level 14, 383 Kent Street, Sydney NSW 2000<br>
<br>
Level 11, 15 William Street, Melbourne VIC 3000
</p>
<p>Tunnel Show Pty Ltd trading as RoyalPay<br>
Representative of AFSL licensee 448066
</p>
</html>

@ -0,0 +1,34 @@
<html xmlns:th="http://www.thymeleaf.org" lang="zh">
<b>Dear <span th:text="${account.display_name}"></span> :</b>
<p>
You are requesting a password reset service with a verification code of <u th:text="${captcha}"></u>, valid for 5 minutes. Please do not provide this verification code to anyone.
</p>
<p>
<a th:href="${url}">Reset Password ></a>
</p>
<b>尊敬的<span th:text="${account.display_name}"></span>,您好:</b>
<p>
您正在申请密码重置服务,验证码为<u th:text="${captcha}"></u>5分钟内有效请勿向任何人提供此验证码。
</p>
<hr>
<h4>Best Regards</h4>
<p>
<img style="width: 120px;height: 120px"
src="https://mpay.royalpay.com.au/static/images/logo_new.jpg"> <br>
Contact Us<br>
Email:<br>
<a href="mailto:info@royalpay.com.au">info@royalpay.com.au</a> <br>
Tel:<br>
1300 10 77 50<br>
<br>
Service WeChat Account:<br>
<img src="https://mpay.royalpay.com.au/static/images/customer_service.jpg"
style="width: 60px"><br>
Level 14, 383 Kent Street, Sydney NSW 2000<br>
<br>
Level 11, 15 William Street, Melbourne VIC 3000
</p>
<p>Tunnel Show Pty Ltd trading as RoyalPay<br>
Representative of AFSL licensee 448066
</p>
</html>

@ -1003,7 +1003,7 @@ margin-bottom: 10%;"/>
<!--&lt;!&ndash;<i class="fa fa-file-image-o"></i> &ndash;&gt;Marketing Materials-->
<!--</a>-->
<!--</li>-->
<li ng-if="(currentUser.client.client_id!=9 && currentUser.client.parent_client_id!=9)&&([1]|withRole)">
<li ng-if="([1]|withRole)">
<a ui-sref="accounts">
<!--<i class="fa fa-users"></i> -->Accounts
</a>

@ -608,6 +608,11 @@ margin-bottom: 10%;"/>
<i class="fa fa-tv"></i> <span>商户欠款|Pre Refund</span>
</a>
</li>
<li ui-sref-active="active">
<a ui-sref="surcharge_account_month">
<i class="fa fa-bell"></i> <span>后付费收款</span>
</a>
</li>
</ul>
</li>
@ -771,6 +776,11 @@ margin-bottom: 10%;"/>
<i class="fa fa-usd"></i> <span>BD提成|BD Commissions</span>
</a>
</li>
<li ui-sref-active="active" ng-if="('bdprize'|withModule)&&(currentUser.org_id==null||currentUser.org_id==1)">
<a ui-sref="analysis_bd.bd_data_analysis" ui-sref-opts="{reload:true}">
<i class="fa fa-usd"></i> <span>BD数据分析|BD Data Analysis</span>
</a>
</li>
<li ui-sref-active="active" ng-if="'10000000001000'|withRole">
<a ng-click="editRateConfig()" style="cursor: pointer">
<i class="fa fa-cog"></i> <span>BD绩效设置</span>

@ -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: {

@ -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} <br/>{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} <br/>{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} <br/>{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;
});

@ -6,6 +6,11 @@
.cen table th {
text-align: center;
}
.channel .col-sm-2 {
border: 1px solid #d2d6de;
border-left: 0;
}
</style>
<!--<section class="content-header">
<h1>Transaction Data</h1>
@ -141,25 +146,35 @@
</div>
</div>
<div class="box box-warning" ng-if="currentUser.org==null">
<div class="box-header with-border">各平台交易总额</div>
<div class="box-body table-responsive">
<div class="box-header with-border">各平台交易总额
<div class="description-text" style="display: inline-block;float: right;">
<label class="description-text text-red">交易金额{{ totalChannelAmount.all_amount|currency: ' $ ' }}</label>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.all_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.all_client_count }}</label>
</div>
</div>
<div class="box-body table-responsive channel">
<div class="row">
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/wechatpay_sign.png"/>Wechat</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.wechatamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.wechatamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.wechat_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.wechat_client_count }}</label>
</div>
</div>
</div>
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/bestpay_sign.png"/>Bestpay</div>
<div class="description-text">
<div class="description-header text-bold"><img src="/static/images/bestpay_sign.png"/>Bestpay</div>
<label class="description-text text-red"
ng-bind="totalChannelAmount.bestpayamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.bestpayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.bestpay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.bestpay_client_count }}</label>
</div>
</div>
@ -167,9 +182,11 @@
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/alipay_sign.png"/>Alipay</div>
<div class="description-text text-red">
<label class="description-text"
ng-bind="totalChannelAmount.alipayamount|currency: ' $ '"></label>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.alipayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.alipay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.alipay_client_count }}</label>
</div>
</div>
@ -177,9 +194,11 @@
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/alipay_sign.png"/>AlipayOnline</div>
<div class="description-text text-red">
<label class="description-text"
ng-bind="totalChannelAmount.alipayonlineamount|currency: ' $ '"></label>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.alipayonlineamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.alipayonline_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.alipayonline_client_count }}</label>
</div>
</div>
@ -187,9 +206,11 @@
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/jd_sign.png"/>JD Pay</div>
<div class="description-text text-red">
<label class="description-text"
ng-bind="totalChannelAmount.jdamount|currency: ' $ '"></label>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.jdamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.jd_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.jd_client_count }}</label>
</div>
</div>
@ -197,37 +218,46 @@
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/hf_sign.png"/>HF Pay</div>
<div class="description-text text-red">
<label class="description-text"
ng-bind="totalChannelAmount.hfamount|currency: ' $ '"></label>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.hfamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.hf_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.hf_client_count }}</label>
</div>
</div>
</div>
<!-- Rpay+显示交易额分析-->
<!-- 显示Rpay+交易额分析-->
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/rpayplus_sign.png"/>RPay+</div>
<div class="description-text text-red">
<label class="description-text"
ng-bind="totalChannelAmount.rpayamount|currency: ' $ '"></label>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.rpayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.rpay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.rpay_client_count }}</label>
</div>
</div>
</div>
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/yeepay_sign.png"/>Yeepay</div>
<div class="description-text text-red">
<label class="description-text"
ng-bind="totalChannelAmount.yeepayamount|currency: ' $ '"></label>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.yeepayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.yeepay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.yeepay_client_count }}</label>
</div>
</div>
</div>
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/lakalapay_sign.png"/>LakalaPay</div>
<div class="description-text text-red">
<label class="description-text"
ng-bind="totalChannelAmount.lakalapayamount|currency: ' $ '"></label>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.lakalapayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.lakala_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.lakala_client_count }}</label>
</div>
</div>
</div>

@ -6,6 +6,11 @@
.cen table th {
text-align: center;
}
.channel .col-sm-2 {
border: 1px solid #d2d6de;
border-left: 0;
}
</style>
<!--<section class="content-header">
<h1>Transaction Data</h1>
@ -110,25 +115,35 @@
</div>
</div>
<div class="box box-warning" ng-if="currentUser.org==null">
<div class="box-header with-border">各平台交易总额</div>
<div class="box-body table-responsive">
<div class="box-header with-border">各平台交易总额
<div class="description-text" style="display: inline-block;float: right;">
<label class="description-text text-red">交易金额{{ totalChannelAmount.all_amount|currency: ' $ ' }}</label>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.all_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.all_client_count }}</label>
</div>
</div>
<div class="box-body table-responsive channel">
<div class="row">
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/wechatpay_sign.png"/>Wechat</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.wechatamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.wechatamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.wechat_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.wechat_client_count }}</label>
</div>
</div>
</div>
<div class="col-sm-2 col-xs-6">
<div class="description-block">
<div class="description-header text-bold"><img src="/static/images/bestpay_sign.png"/>Bestpay</div>
<div class="description-text">
<div class="description-header text-bold"><img src="/static/images/bestpay_sign.png"/>Bestpay</div>
<label class="description-text text-red"
ng-bind="totalChannelAmount.bestpayamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.bestpayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.bestpay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.bestpay_client_count }}</label>
</div>
</div>
@ -138,7 +153,9 @@
<div class="description-header text-bold"><img src="/static/images/alipay_sign.png"/>Alipay</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.alipayamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.alipayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.alipay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.alipay_client_count }}</label>
</div>
</div>
@ -148,7 +165,9 @@
<div class="description-header text-bold"><img src="/static/images/alipay_sign.png"/>AlipayOnline</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.alipayonlineamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.alipayonlineamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.alipayonline_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.alipayonline_client_count }}</label>
</div>
</div>
@ -158,7 +177,9 @@
<div class="description-header text-bold"><img src="/static/images/jd_sign.png"/>JD Pay</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.jdamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.jdamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.jd_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.jd_client_count }}</label>
</div>
</div>
@ -168,7 +189,9 @@
<div class="description-header text-bold"><img src="/static/images/hf_sign.png"/>HF Pay</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.hfamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.hfamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.hf_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.hf_client_count }}</label>
</div>
</div>
</div>
@ -179,7 +202,9 @@
<div class="description-header text-bold"><img src="/static/images/rpayplus_sign.png"/>RPay+</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.rpayamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.rpayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.rpay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.rpay_client_count }}</label>
</div>
</div>
</div>
@ -188,7 +213,9 @@
<div class="description-header text-bold"><img src="/static/images/yeepay_sign.png"/>Yeepay</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.yeepayamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.yeepayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.yeepay_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.yeepay_client_count }}</label>
</div>
</div>
</div>
@ -197,11 +224,14 @@
<div class="description-header text-bold"><img src="/static/images/lakalapay_sign.png"/>LakalaPay</div>
<div class="description-text">
<label class="description-text text-red"
ng-bind="totalChannelAmount.lakalapayamount|currency: ' $ '"></label>
ng-bind="totalChannelAmount.lakalapayamount|currency: ' $ '"></label></br>
<label class="description-text text-red">交易笔数:{{ totalChannelAmount.lakala_order_count }}</label>
<label class="description-text text-red">交易商户数:{{ totalChannelAmount.lakala_client_count }}</label>
</div>
</div>
</div>
</div>
<!-- <table class="table">
<tr>

@ -56,6 +56,13 @@ define(['angular', 'uiBootstrap', 'uiRouter', 'angularEcharts','./transaction/an
$scope.params.begin = currentYearFirstDate;
$scope.doAnalysis(1);
};
$scope.thisMonth = function () {
$scope.params.end = new Date(new Date().getTime() - 24*60*60*1000);
var monthBegin = new Date();
monthBegin.setDate(1);
$scope.params.begin = monthBegin;
$scope.doAnalysis(1);
};
$scope.doAnalysis = function () {
if ($scope.params.channel == 'All') {
$scope.params.channel = null;
@ -93,7 +100,7 @@ define(['angular', 'uiBootstrap', 'uiRouter', 'angularEcharts','./transaction/an
var new_date = new Date(new_year,new_month,1); //取当年当月中的第一天
return new Date(new_date.getTime()-1000*60*60*24);//获取当月最后一天日期
}
$scope.thisYear();
$scope.thisMonth();
var ordersHistoryConfig = {
chart: {
tooltip: {

@ -73,6 +73,7 @@ define(['../app', 'angular'], function (app, angular) {
},
inputText:function (cfg) {
return $uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl:'/static/commons/templates/text_input.html',
size: cfg.size || 'sm',
resolve:{

@ -6,6 +6,7 @@ define(['../app'], function (app) {
app.factory('orderService', ['$uibModal', function ($uibModal) {
function openDetail(url) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/commons/templates/order_detail.html',
controller: 'orderDetailDialogCtrl',
resolve: {

@ -215,4 +215,7 @@
</table>
</div>
</div>
<div class="form-group">
<button class="btn btn-danger" type="button" ng-click="$dismiss()">Cancel</button>
</div>
</div>

@ -113,6 +113,7 @@ define(['angular', '../../analysis/bd/analysis-bd'], function (angular) {
$scope.loadRateConfigs();
$scope.editRateConfig = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/bdprize/templates/rate_config_dialog.html',
controller: 'bdRateConfigCtrl',
resolve: {
@ -126,6 +127,7 @@ define(['angular', '../../analysis/bd/analysis-bd'], function (angular) {
};
$scope.editBDLevels = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/bdprize/templates/bd_level_config_dialog.html',
size: 'lg',
controller: 'bdLevelConfigCtrl'
@ -133,6 +135,7 @@ define(['angular', '../../analysis/bd/analysis-bd'], function (angular) {
};
$scope.editCommissionConfig = function (monModal) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/bdprize/templates/bd_commission_config_dialog.html',
controller: 'bdCommissionConfigCtrl',
size: 'lg',

@ -0,0 +1,78 @@
<div ui-view>
<section class="content-header">
<h1>BD Data Analysis</h1>
<ol class="breadcrumb">
<li><i class="fa fa-usd"></i> Performance</li>
<li class="active">BD Data Analysis</li>
</ol>
</section>
<section class="content">
<div class="box box-danger" ng-if="('10000000000000'|withRole)">
<div class="box-body">
<div class="form-inline">
<div class="form-group">
<input type="text" class="form-control" uib-datepicker-popup="yyyy-MM" ng-model="bdprize.month"
is-open="ctrl.bdprize" datepicker-options="{minMode: 'month'}"
ng-click="ctrl.bdprize=true" placeholder="Select Month"/>
</div>
<button class="btn btn-primary" ng-click="selectBdPrizeAnalysis()" ng-disabled="!bdprize.month">
查询
</button>
</div>
</div>
</div>
<div class="box box-default" ng-if="('1000'|withRole) || ('1000000'|withRole) || ('10000000000000'|withRole)">
<div class="box-header">
团队总KPI完成度
</div>
<div class="box-body">
<div class="chart" style="height: 400px" id="BDTeamKpi" echarts="BDTeamKpi"
chart-setter="bdTeamKpiEcharts($chart)"
ng-class="{nodata:!BDTeamKpiData}"></div>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<td>teamName</td>
<td>kpiAmount</td>
<td>totalAmount</td>
</tr>
</thead>
<tr ng-repeat="data in BDTeamKpiData">
<td ng-bind="data.team_name"></td>
<td ng-bind="data.kpi"></td>
<td ng-bind="data.total_amount"></td>
</tr>
</table>
</div>
</div>
<div class="box box-info">
<div class="box-header">BD占比</div>
<div class="box-body">
<div class="chart" style="height: 400px" id="bdProportion" echarts="bdProportion"
chart-setter="bdProportionEcharts($chart)"
ng-class="{nodata:!bdProportionData}"></div>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<td>bdName</td>
<td>kpiAmount</td>
<td>totalAmount</td>
</tr>
</thead>
<tr ng-repeat="data in bdProportionData">
<td ng-bind="data.bd_name"></td>
<td ng-bind="data.kpi_amount"></td>
<td ng-bind="data.total_amount"></td>
</tr>
</table>
</div>
</div>
<div class="box box-info">
<div class="box-header">BD KPI完成度</div>
<div class="box-body">
<div class="chart" style="height: 400px" id="bdKpi" echarts="bdKpi"
ng-class="{nodata:!bdKpiData}"></div>
</div>
</div>
</section>
</div>

@ -41,6 +41,7 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
$scope.listManagers();
$scope.modifyManager = function (manager) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/managers/templates/modify.html',
controller: 'modifyManagerDialogCtrl',
resolve: {
@ -141,6 +142,7 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
app.controller('newManagerDialogCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.params = {};
$scope.manager = {};
$scope.manager.nation_code = 61;
if(($scope.currentUser.role & parseInt('1000000000000', 2)) > 0 && $scope.currentUser.org_id){
var params = angular.copy($scope.params);
params.org_id = $scope.currentUser.org_id;
@ -208,4 +210,4 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
}
}]);
return app;
});
});

@ -37,8 +37,30 @@
</div>
<div class="form-group">
<label class="control-label" for="phone-input">Phone</label>
<input class="form-control" type="text" id="phone-input" name="phone"
ng-model="manager.phone">
<div>
<div class="col-md-4">
<div class="input-group">
<div class="input-group-addon">+</div>
<input class="form-control" required type="text"
ng-model="manager.nation_code"
name="nation_code" id="nation_code"
maxlength="3" minlength="1"
placeholder="country code">
</div>
<div ng-messages="accountForm.nation_code.$error"
ng-if="accountForm.nation_code.$dirty">
<p class="small text-danger" ng-message="required">Required
Field</p>
<p class="small text-danger" ng-message="maxlength">Less
Than 3 Characters</p>
</div>
</div>
<div class="col-md-8">
<input class="form-control" type="text" id="phone-input" name="phone"
ng-model="manager.phone">
</div>
</div>
</div>
<div class="form-group">
<label class="control-label" for="wechat-input">WeChat Account</label>
@ -130,4 +152,4 @@
<div class="btn-group">
<button class="btn btn-danger" type="button" ng-click="$dismiss()">Cancel</button>
</div>
</div>
</div>

@ -43,8 +43,30 @@
</div>
<div class="form-group" ng-class="{'has-error':accountForm.phone.$invalid && accountForm.phone.$dirty}">
<label class="control-label" for="phone-input">Phone</label>
<input class="form-control" type="text" id="phone-input" name="phone"
ng-model="manager.phone">
<div>
<div class="col-md-4">
<div class="input-group">
<div class="input-group-addon">+</div>
<input class="form-control" required type="text"
ng-model="manager.nation_code"
name="nation_code" id="nation_code"
maxlength="3" minlength="1"
placeholder="country code">
</div>
<div ng-messages="accountForm.nation_code.$error"
ng-if="accountForm.nation_code.$dirty">
<p class="small text-danger" ng-message="required">Required
Field</p>
<p class="small text-danger" ng-message="maxlength">Less
Than 3 Characters</p>
</div>
</div>
<div class="col-md-8">
<input class="form-control" type="text" id="phone-input" name="phone"
ng-model="manager.phone">
</div>
</div>
</div>
<div class="form-group" ng-class="{'has-error':accountForm.wechat.$invalid && accountForm.wechat.$dirty}">
<label class="control-label" for="wechat-input">WeChat Account</label>
@ -140,4 +162,4 @@
<div class="btn-group">
<button class="btn btn-danger" type="button" ng-click="$dismiss()">Cancel</button>
</div>
</div>
</div>

@ -61,6 +61,7 @@ define(['angular', 'static/commons/commons', 'static/commons/angular-ueditor', '
$scope.showNotice = function (notice) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/commons/templates/notice_detail.html',
controller: 'noticePreviewCtrl',
resolve: {

@ -506,6 +506,7 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
$scope.listManagers();
$scope.modifyManager = function (manager) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/managers/templates/modify.html',
controller: 'modifyManagerCtrl',
resolve: {
@ -531,6 +532,7 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
};
$scope.newManager = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/managers/templates/new_manager.html',
controller: 'newManagerCtrl',
resolve: {

@ -275,6 +275,7 @@ define(['angular', 'uiRouter'], function (angular) {
};
$scope.moveFunction = function (func) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/permission_choose_module.html',
controller: 'permissionChooseModuleDialogCtrl',
resolve: {
@ -292,6 +293,7 @@ define(['angular', 'uiRouter'], function (angular) {
};
$scope.editFunctionInfo = function (func) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/func_info_edit.html',
controller: 'permissionFuncEditDialogCtrl',
resolve: {
@ -334,6 +336,7 @@ define(['angular', 'uiRouter'], function (angular) {
$scope.modules = modules.data;
$scope.newModule = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/permission_module_dialog.html',
controller: 'moduleNewCtrl',
resolve: {
@ -347,6 +350,7 @@ define(['angular', 'uiRouter'], function (angular) {
};
$scope.editModule = function (mod) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/permission_module_dialog.html',
controller: 'moduleEditCtrl',
resolve: {
@ -422,6 +426,7 @@ define(['angular', 'uiRouter'], function (angular) {
};
$scope.addUnSub = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/add_mail_unsub.html',
controller: 'addUnSubDialogCtrl',
size: 'sm'
@ -464,6 +469,7 @@ define(['angular', 'uiRouter'], function (angular) {
app.controller('permissionPartnerConfigRootCtrl', ['$scope', '$http', '$uibModal', function ($scope, $http, $uibModal) {
$scope.authorizeRole = function (roleMask) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/permissionPartner_authorize_dialog.html',
controller: 'permissionPartnerAuthorizeDialogCtrl',
size: 'lg',
@ -528,6 +534,7 @@ define(['angular', 'uiRouter'], function (angular) {
};
$scope.moveFunction = function (func) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/permissionPartner_choose_module.html',
controller: 'permissionPartnerChooseModuleDialogCtrl',
resolve: {
@ -545,6 +552,7 @@ define(['angular', 'uiRouter'], function (angular) {
};
$scope.editFunctionInfo = function (func) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/PartnerFunc_info_edit.html',
controller: 'permissionPartnerFuncEditDialogCtrl',
resolve: {
@ -580,6 +588,7 @@ define(['angular', 'uiRouter'], function (angular) {
$scope.modules = modules.data;
$scope.newPartnerModule = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/permissionPartner_module_dialog.html',
controller: 'partnerModuleNewCtrl',
resolve: {
@ -596,6 +605,7 @@ define(['angular', 'uiRouter'], function (angular) {
};
$scope.editPartnerModule = function (mod) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/sysconfigs/templates/permissionPartner_module_dialog.html',
controller: 'partnerModuleEditCtrl',
resolve: {

@ -8,6 +8,12 @@
<div class="form-group">
<button class="btn btn-success pull-right" ng-click="save()">Add</button>
</div>
<div>
<h6></h6>
</div>
<div class="form-group pull-right">
<button class="btn btn-danger" ng-click="$dismiss()">Cancel</button>
</div>
</div>
</div>

File diff suppressed because one or more lines are too long

@ -64,6 +64,7 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
$scope.editRateConfig = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/bdprize/templates/rate_config_dialog.html',
controller: 'bdRateConfigCtrl',
resolve: {
@ -77,6 +78,7 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
};
$scope.editBDLevels = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/config/bdprize/templates/bd_level_config_dialog.html',
controller: 'bdLevelConfigCtrl'
})

@ -821,6 +821,16 @@
</div>
</a>
</div>
<div class="col-sm-2 col-xs-6">
<a ui-sref="surcharge_account_month" ui-sref-opts="{reload:true}">
<div class="description-block">
<img src="/static/images/main_menu/compliance_warning.png"/>
<div class="description-text">
<span>后付费收款</span>
</div>
</div>
</a>
</div>
</div>
</div>
<div class="list-group" ng-if="role=='accountant' || role=='director' || ('1000000000'|withRole)">

@ -182,6 +182,7 @@ define(['angular', 'static/commons/commons', 'uiBootstrap', 'uiRouter', 'ngBootS
$scope.loadTempSubMerchantId(1);
$scope.save = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/payment/merchantid/templates/new_common_sub_merchant_id.html',
controller: 'newCommonSubMerchantIdCtrl'
}).result.then(function () {

@ -15,10 +15,14 @@
<div class="form-group">
<button class="btn btn-primary btn-block" ng-click="saveSubMerchantId()">save</button>
</div>
<div class="form-group">
<button class="btn btn-primary btn-block btn-danger" ng-click="$dismiss()">Cancel</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>

@ -13,10 +13,16 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
$stateProvider.state('accounts', {
url: '/accounts',
templateUrl: '/static/payment/partner/templates/client_accounts.html',
controller: 'clientAccountsCtrl'
controller: 'clientAccountsCtrl',
resolve: {
partner: ['$http', function ($http) {
return $http.get('/client/partner_info');
}]
}
})
}]);
app.controller('clientAccountsCtrl', ['$scope', '$http', '$uibModal', 'commonDialog', function ($scope, $http, $uibModal, commonDialog) {
app.controller('clientAccountsCtrl', ['$scope', '$http', '$uibModal', 'commonDialog','partner', function ($scope, $http, $uibModal, commonDialog,partner) {
$scope.partner = partner.data;
$scope.loadAccounts = function () {
$http.get('/client/partner_info/accounts').then(function (resp) {
$scope.accounts = resp.data;
@ -28,7 +34,12 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
$uibModal.open({
templateUrl: '/static/payment/partner/templates/add_partner_account_dialog.html',
controller: 'clientAddAccountCtrl',
backdrop: false
backdrop: false,
resolve: {
partner: ['$http', function ($http) {
return $http.get('/client/partner_info');
}]
}
}).result.then(function () {
$scope.loadAccounts();
})
@ -91,8 +102,16 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
});
};
}]);
app.controller('clientAddAccountCtrl', ['$scope', '$http', function ($scope, $http) {
app.controller('clientAddAccountCtrl', ['$scope', '$http','partner', function ($scope, $http, partner) {
$scope.loadSubPartners = function () {
$http.get('/client/partner_info/sub_partners').then(function (resp) {
$scope.subPartners = resp.data;
})
};
$scope.partner = partner.data;
$scope.loadSubPartners();
$scope.account = {role: 3};
$scope.account.nation_code = 61;
$scope.partnerRoles = partnerRoles;
$scope.saveAccount = function (form) {
if (form.$invalid) {
@ -122,4 +141,4 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
}
}]);
return app;
});
});

@ -1428,6 +1428,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
$scope.ctrl.editAliSubMerchant = false;
$scope.ctrl.editMaxOrderAmount = false;
$scope.ctrl.editOrderExpiryConfig = false;
$scope.ctrl.editRefundPwd = false;
})
};
$scope.qrConfig = {currency: 'AUD'};
@ -1500,6 +1501,13 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
})
};
$scope.resetRefundPwd = function (config) {
$http.put('/sys/partners/' + $scope.partner.client_moniker + '/reset/refund_pwd', {new_refund_password: config}).then(function () {
$scope.loadPartnerPaymentInfo();
}, function (resp) {
commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'});
})
};
$scope.updateClientQRCodePaySurCharge = function () {
if (!$scope.paymentInfo) {
@ -1671,6 +1679,26 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
})
})
};
$scope.switchSubManage = function () {
if (!$scope.paymentInfo) {
return;
}
if (!$scope.init.sub_manage) {
$scope.init.sub_manage = true;
return;
}
$http.put('/sys/partners/' + $scope.partner.client_moniker + '/sub_manage', {allow: $scope.paymentInfo.sub_manage}).then(function () {
$scope.loadPartnerPaymentInfo();
}, function (resp) {
commonDialog.alert({
title: 'Failed to change Sub Partners Manage status',
content: resp.data.message,
type: 'error'
})
})
};
var info = [];
$scope.decideCompliance = function (name) {
var keywords = ['education','financial' ,'train','immigrant','invest',
@ -2500,6 +2528,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
app.controller('partnerAddAccountDialogCtrl', ['$scope', '$http', 'partner', function ($scope, $http, partner) {
$scope.account = {role: 1};
$scope.partnerRoles = partnerRoles;
$scope.account.nation_code = 61;
$scope.saveAccount = function (form) {
if (form.$invalid) {
angular.forEach(form, function (item, key) {

@ -344,6 +344,16 @@ define(['angular', 'decimal', 'uiRouter', 'ngBootSwitch', 'ngFileUpload','uiBoot
};
}]);
app.controller('clientResetRefundPwdDialogCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.updateRefundPwd = function (refundPwd) {
$scope.errmsg = null;
$http.put('/client/partner_info/refund_pwd_new', refundPwd).then(function () {
$scope.$close();
}, function (resp) {
$scope.errmsg = resp.data.message;
})
}
}]);
app.controller('clientComplianceFilesCtrl', ['$scope', '$http', '$rootScope', 'commonDialog', '$state', 'Upload', 'file', function ($scope, $http, $rootScope, commonDialog, $state, Upload, file) {
$scope.file = file.data || {};
@ -551,7 +561,7 @@ define(['angular', 'decimal', 'uiRouter', 'ngBootSwitch', 'ngFileUpload','uiBoot
};
}]);
app.controller('clientPaymentInfoCtrl', ['$scope', '$http', '$state', 'commonDialog', function ($scope, $http, $state, commonDialog) {
app.controller('clientPaymentInfoCtrl', ['$scope', '$http', '$state', 'commonDialog','$uibModal', function ($scope, $http, $state, commonDialog, $uibModal) {
$scope.paymentInfo = $scope.partner;
$scope.old_customer_surcharge_rate = angular.copy($scope.partner.customer_surcharge_rate);
$scope.qrConfig = {currency: 'AUD'};
@ -567,6 +577,22 @@ define(['angular', 'decimal', 'uiRouter', 'ngBootSwitch', 'ngFileUpload','uiBoot
}
};
$scope.resetRefundPwd = function (account) {
$uibModal.open({
templateUrl: '/static/payment/partner/templates/partner_reset_refund_pwd_dialog.html',
controller: 'clientResetRefundPwdDialogCtrl',
backdrop: false,
size: 'sm',
resolve: {
account: function () {
return account;
}
}
}).result.then(function () {
commonDialog.alert({title: 'Success!', content: 'Refund Password Changed Successfully', type: 'success'})
})
};
$scope.clientCopyCBBannkPayLink = function() {
var e=document.getElementById("c-cpcbbankpay");
e.select();

@ -1048,6 +1048,5 @@
</button>
</div>
</div>
</form>
</form>
</div>

@ -36,14 +36,59 @@
<p class="small text-danger" ng-message="required">password is required</p>
</div>
</div>
<div class="form-group"
ng-class="{'has-error':newAccountForm.contact_phone.$invalid && newAccountForm.contact_phone.$dirty}">
<label class="control-label" for="contact_phone">Contact Phone *</label>
<div class="">
<div class="col-md-4">
<div class="input-group">
<div class="input-group-addon">+</div>
<input class="form-control" required type="text"
ng-model="account.nation_code"
name="nation_code" id="nation_code"
maxlength="3" minlength="1"
placeholder="country code" value="61">
</div>
<div ng-messages="newAccountForm.nation_code.$error"
ng-if="newAccountForm.nation_code.$dirty">
<p class="small text-danger" ng-message="required">Required
Field</p>
<p class="small text-danger" ng-message="maxlength">Less
Than 3 Characters</p>
</div>
</div>
<div class="col-md-8">
<input required type="text" class="form-control" ng-model="account.contact_phone" name="contact_phone"
id="contact_phone">
<div ng-messages="newAccountForm.contact_phone.$error" ng-if="newAccountForm.contact_phone.$dirty">
<p class="small text-danger" ng-message="required">contact phone is required</p>
</div>
</div>
</div>
</div>
<div class="form-group"
ng-class="{'has-error':newAccountForm.contact_email.$invalid && newAccountForm.contact_email.$dirty}">
<label class="control-label" for="contact_email">Contact Email *</label>
<input required type="email" class="form-control" ng-model="account.contact_email" name="contact_email"
id="contact_email">
<div ng-messages="newAccountForm.contact_email.$error" ng-if="newAccountForm.contact_email.$dirty">
<p class="small text-danger" ng-message="required">contact email is required</p>
</div>
</div>
<div class="form-group">
<label class="control-label" for="role-select">Role *</label>
<select class="form-control" id="role-select" ng-model="account.role" ng-options="role.code as role.label for role in partnerRoles"></select>
</div>
<div class="alert alert-danger" ng-if="errmsg" ng-bind="errmsg"></div>
<div class="form-group" ng-if="subPartners!=null && partner.sub_manage">
<label class="control-label" for="sub-select">Sub Merchant</label>
<select class="form-control" id="sub-select" ng-model="account.client_id" ng-options="partner.client_id as partner.short_name for partner in subPartners"></select>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-click="saveAccount(newAccountForm)" type="button">Save Account</button>
<button class="btn btn-danger" ng-click="$dismiss()" type="button">Cancel</button>
</div>
</div>

@ -31,6 +31,9 @@
<th>Display Name</th>
<th>Role</th>
<th>WeChat</th>
<th>Email</th>
<th>Country Code</th>
<th>Phone</th>
<th>Payment Notice</th>
<th>Refund Approver</th>
<th>Operations</th>
@ -38,7 +41,10 @@
</thead>
<tbody>
<tr ng-repeat="account in accounts">
<td ng-bind="account.username"></td>
<td>{{account.username}}
<i class="fa fa-sitemap" ng-if="account.parent_client_id && !partner.parent_client_id"
title="{{account.short_name}}"></i>
</td>
<td ng-bind="account.display_name"></td>
<td>
<select ng-disabled="account.account_id==currentUser.account_id" ng-change="updateAccountRole(account)" ng-model="account.role" ng-options="role.code as role.label for role in partnerRoles" title="Account Role"></select>
@ -50,6 +56,9 @@
<i role="button" class="fa fa-qrcode text-primary" ng-if="!account.wechat_openid" title="Wechat Sign" ng-click="userCheckIn(account)"></i>
<i role="button" class="fa fa-remove text-danger" ng-if="account.wechat_openid" title="Unbind" ng-click="unbindWechat(account)"></i>
</td>
<td ng-bind="account.contact_email"></td>
<td ng-bind="account.nation_code"></td>
<td ng-bind="account.contact_phone"></td>
<td>
<a role="button" class="text-success" ng-click="toggleNotice(account)" ng-if="account.wechat_openid">
<i class="fa" ng-class="{'fa-check-circle-o':account.payment_notice,'fa-circle-o':!account.payment_notice}"></i>
@ -77,4 +86,4 @@
</div>
</div>
</div>
</section>
</section>

@ -385,6 +385,13 @@
switch-change="toggleRequireRemark()">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Reset Refund Password</label>
<div class="col-sm-10">
<a role="button" class="text-primary text-bold" ng-click="resetRefundPwd(account)"><i
class="fa fa-edit"></i></a>
</div>
</div>
</div>
</div>
</div>

@ -184,6 +184,12 @@
</div>
</div>
</div>
<div class="form-group" ng-if="('10'|withRole) && partner.parent_client_id==null">
<label class="col-sm-3 control-label">Sub Partners Manage</label>
<div class="col-xs-9">
<input type="checkbox" ng-model="paymentInfo.sub_manage" bs-switch switch-change="switchSubManage()">
</div>
</div>
</div>
</div>
</div>
@ -488,6 +494,30 @@
switch-change="togglePreRefund()">
</div>
</div>
<div class="form-group" ng-if="('100000000'|withRole)">
<label class="col-sm-2 control-label">Reset Refund Password</label>
<div class="col-sm-9">
<p ng-if="!ctrl.editRefundPwd" class="form-control-static">
<a role="button" ng-click="ctrl.editRefundPwd=true" ng-if="'01'|withRole"><i
class="fa fa-edit"></i></a>
</p>
<div class="input-group" ng-if="ctrl.editRefundPwd">
<input type="text" class="form-control" maxlength="6" ng-model="paymentInfo.new_refund_password">
<div class="input-group-btn">
<button class="btn btn-success"
ng-click="resetRefundPwd(paymentInfo.new_refund_password)">
<i class="fa fa-check"></i>
</button>
</div>
<div class="input-group-btn">
<button class="btn btn-danger" ng-click="ctrl.editRefundPwd=false">
<i class="fa fa-remove"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,25 @@
<div class="modal-header">
<h4>Reset Refund Password</h4>
</div>
<div class="modal-body">
<form novalidate name="resetForm">
<div class="form-group">
<label class="control-label" for="reset-pwd-input">Old Password
*</label>
<input id="old-pwd-input" type="password" maxlength="6" class="form-control" ng-model="refundPwd.refund_password" name="pwd" required>
<p ng-if="resetForm.pwd.$error.required" class="text-danger small">
Required Field</p>
<label class="control-label" for="reset-pwd-input">New Password
*</label>
<input id="reset-pwd-input" type="password" class="form-control" maxlength="6" ng-model="refundPwd.new_refund_password" name="pwd" required>
<p ng-if="resetForm.pwd.$error.required" class="text-danger small">
Required Field</p>
<div class="alert alert-danger" ng-if="errmsg" ng-bind="errmsg"></div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-success" type="button" ng-click="updateRefundPwd(refundPwd)">Submit</button>
<button class="btn btn-danger" type="button" ng-click="$dismiss()">Cancel</button>
</div>

@ -68,6 +68,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
};
$scope.addProduct = function () {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/payment/product/templates/add_product.html',
controller: 'managerAddProductDialogCtrl',
resolve: {
@ -81,6 +82,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
};
$scope.editProduct = function (product) {
$uibModal.open({
backdrop: 'static', keyboard: false,
templateUrl: '/static/payment/product/templates/add_product.html',
controller: 'managerAddProductDialogCtrl',
resolve: {

@ -111,10 +111,15 @@
<!--</div>-->
<!--</div>-->
<!--end 商品二维码-->
<div class="btn-group margin-bottom margin-top">
<button ng-disabled="goodForm.$dirty&&goodForm.$invalid" class="btn btn-success" type="button"
ng-click="save(goodForm)">Save
</button>
<div class="modal-footer">
<div class="btn-group margin-bottom margin-top">
<button ng-disabled="goodForm.$dirty&&goodForm.$invalid" class="btn btn-success" type="button"
ng-click="save(goodForm)">Save
</button>
</div>
<div class="btn-group margin-bottom margin-top">
<button class="btn btn-danger" type="button" ng-click="$dismiss()">Cancel</button>
</div>
</div>
</div>
</div>

@ -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 + ']冲正,<span style="color: red">请确认商户信息</span>');
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'});
});
})
};

@ -46,26 +46,38 @@
<tr>
<th>商户编号</th>
<th>Short Name</th>
<th>Total Surcharge</th>
<th>充值总额</th>
<th>支出总额</th>
<th>余额</th>
<th>是否结清</th>
<!--<th>余额</th>-->
<th>操作</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="details in report.details">
<td ng-bind="details.client_moniker"></td>
<td ng-bind="details.short_name"></td>
<td ng-bind="details.credit_amount|currency:'$'" style="color: green"></td>
<td ng-bind="details.debit_amount|currency:'$'" style="color: red"></td>
<td>
<span ng-if="details.balance>=0" style="color: green">{{details.balance|currency:'$'}}</span>
<span ng-if="details.balance<0" style="color: red">{{details.balance|currency:'$'}}</span>
<td style="vertical-align:middle">
<a class="text-primary" role="button" title="Detail"
ui-sref="partners.detail({clientMoniker:details.client_moniker})">
<span ng-bind="details.client_moniker"></span></a>
</td>
<td>
<td ng-bind="details.short_name" style="vertical-align:middle"></td>
<td ng-bind="details.total_surcharge | currency:'$'"></td>
<td ng-bind="details.credit_amount|currency:'$'" style="color: green;vertical-align:middle" ></td>
<td ng-bind="details.debit_amount|currency:'$'" style="color: red;vertical-align:middle"></td>
<td style="vertical-align:middle">
<span ng-if="details.is_valid">已结清</span>
<span ng-if="!details.is_valid">未付款</span>
</td>
<!--<td>-->
<!--<span ng-if="details.balance>=0" style="color: green">{{details.balance|currency:'$'}}</span>-->
<!--<span ng-if="details.balance<0" style="color: red">{{details.balance|currency:'$'}}</span>-->
<!--</td>-->
<td style="vertical-align:middle">
<!-- 等待邮件和微信推送模板 -->
<!--<a style="cursor: pointer" > 催款</a>-->
<!--<a style="cursor: pointer" ng-click="showDetail()">充值</a>-->
<button class="btn btn-warning" ng-if="!details.is_valid" type="button" ng-click="fillMonthsSurcharge(details)">冲正</button>
<i class="fa fa-bars" style="font-size: 15px;color: #3c8dbc;cursor: pointer;padding-left: 15px" ng-click="surchargeAccountDetail(details.client_moniker,details.settle_month)"></i>
</td>
</tr>

@ -1,4 +1,3 @@
<section class="content-header">
<h1>
Client Surcharge Account
@ -14,40 +13,31 @@
<div class="box box-warning">
<div class="box-header">
<div class="form-horizontal col-sm-8" style="margin-top: 30px">
<div class="form-group" ng-if="partner.surcharge_mode=='distributed'">
<div class="form-group">
<label class="control-label col-xs-4 col-sm-3">手续费账户余额</label>
<div class="col-sm-6" style="font-size: 25px">
<p>{{surcharge.balance|currency:'AUD'}}</p>
</div>
</div>
<!--<div class="form-group" ng-if="partner.surcharge_mode=='distributed'">-->
<!--<label class="control-label col-xs-4 col-sm-3">允许手续费账户欠款</label>-->
<!--<div class="col-sm-6">-->
<!--<input type="checkbox" ng-model="partner.allow_surcharge_credit" bs-switch-->
<!--switch-change="allowSurchargeCredit(partner.allow_surcharge_credit)" switch-readonly="true">-->
<!--</div>-->
<!--<label class="control-label col-xs-4 col-sm-3">允许手续费账户欠款</label>-->
<!--<div class="col-sm-6">-->
<!--<input type="checkbox" ng-model="partner.allow_surcharge_credit" bs-switch-->
<!--switch-change="allowSurchargeCredit(partner.allow_surcharge_credit)" switch-readonly="true">-->
<!--</div>-->
<!--</div>-->
<!--<div class="form-group">-->
<!--<label class="control-label col-xs-4 col-sm-3" style="padding-top:0px">Surcharge Mode:</label>-->
<!--<div class="col-xs-8 col-sm-6">-->
<!--<span class="control-label" ng-bind="partner.surcharge_mode"></span>-->
<!--<p class="text-info">-->
<!--<i class="fa fa-info"></i>启用到收支分离(distributed)模式,将使消费者支付手续费模式失效-->
<!--</p>-->
<!--</div>-->
<!--<label class="control-label col-xs-4 col-sm-3" style="padding-top:0px">Surcharge Mode:</label>-->
<!--<div class="col-xs-8 col-sm-6">-->
<!--<span class="control-label" ng-bind="partner.surcharge_mode"></span>-->
<!--<p class="text-info">-->
<!--<i class="fa fa-info"></i>启用到收支分离(distributed)模式,将使消费者支付手续费模式失效-->
<!--</p>-->
<!--</div>-->
<!--</div>-->
</div>
<div class="col-sm-4" style="text-align: center" ng-if="code_url">
<a class="thumbnail" download ng-href="{{code_url}}" uib-tooltip="Download">
<img ng-src="{{code_url}}">
</a>
<p>
<a ng-href="{{code_url}}" download><i class="fa fa-download"></i> Download Bill QR
Code Image</a>
</p>
</div>
</div>
</div>
<div class="box">
@ -112,3 +102,46 @@
</div>
</div>
</div>
<section class="content-header">
<h1>
每月手续费
</h1>
</section>
<div class="content">
<div class="row">
<div class="box box-warning">
<div class="box-body">
<div class="table-responsive col-sm-12">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>清算月份</th>
<th>Total Surcharge</th>
<th>支出总额</th>
<th>是否结清</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="details in report">
<td ng-bind="details.settle_month"></td>
<td ng-bind="details.total_surcharge | currency:'$'"></td>
<td ng-bind="details.debit_amount|currency:'$'"
style="color: red;vertical-align:middle"></td>
<td style="vertical-align:middle">
<span ng-if="details.is_valid">已结清</span>
<span ng-if="!details.is_valid">未付款</span>
</td>
<td style="vertical-align:middle">
<i class="fa fa-bars"
style="font-size: 15px;color: #3c8dbc;cursor: pointer;padding-left: 15px"
ng-click="surchargeAccountDetail(details.client_moniker,details.settle_month)"></i>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,39 @@
<div class="modal-header">
<h4>Surcharge Account Detail{{partner.client_moniker?'('+partner.client_moniker+')':''}}</h4>
</div>
<div class="modal-body">
<div class="box box-default">
<div class="box-header">Debits</div>
<div class="box-body">
<div class="table-responsive col-sm-12">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Num</th>
<th>Settle Date</th>
<th>Amount</th>
<th>Total Surcharge</th>
<th>Tax Amount</th>
<th>Remark</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tr in transactions|propsFilter:{type:'Debit'}:true">
<td>{{$index+1}}</td>
<td ng-bind="tr.settle_date|date:'yyyy-MM-dd'"></td>
<td ng-bind="tr.amount|currency:'AUD'"></td>
<td ng-bind="tr.total_surcharge|currency:'AUD'"></td>
<td ng-bind="tr.tax_amount|currency:'AUD'"></td>
<td>
{{tr.remark}}
<a ng-href="/client/clean_logs/{{tr.client_id}}/settlement_logs/{{tr.clearing_detail_id}}/export" target="_blank" title="Download">
<i class="fa fa-download"></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

@ -78,7 +78,12 @@
<td ng-bind="tr.amount|currency:'AUD'"></td>
<td ng-bind="tr.total_surcharge|currency:'AUD'"></td>
<td ng-bind="tr.tax_amount|currency:'AUD'"></td>
<td ng-bind="tr.remark"></td>
<td>
{{tr.remark}}
<a ng-href="/sys/clean_logs/{{tr.client_id}}/settlement_logs/{{tr.clearing_detail_id}}/export" target="_blank" title="Download">
<i class="fa fa-download"></i>
</a>
</td>
</tr>
</tbody>
</table>

@ -361,7 +361,7 @@
ng-click="releasePreAuth(trade.order_id)" title="Release Pre-Authorization">
<i class="fa fa-unlock-alt"></i>
</a>
<a role="button" ng-if="trade.status>=5 && trade.confirm_time!=null && trade.clearing_status<2 && trade.client_id==currentUser.client_id && currentUser.client.enable_refund"
<a role="button" ng-if="trade.status>=5 && trade.confirm_time!=null && trade.clearing_status<2 && currentUser.client.enable_refund"
class="text-bold text-danger" ng-click="newPRefund(trade.order_id)"
title="Refund">
<i class="fa fa-undo"></i>

@ -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 () {

@ -19,6 +19,9 @@
<div class="form-group">
<button class="btn btn-primary btn-block" ng-click="addCustomer()">save</button>
</div>
<div class="form-group">
<button class="btn btn-primary btn-block btn-danger" ng-click="$dismiss()">Cancel</button>
</div>
</form>
</div>
</div>

@ -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;
}

@ -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');
}
});
})
Loading…
Cancel
Save