Merge branch 'develop'

master
yangkai 6 years ago
commit f324751ed6

@ -8,6 +8,8 @@ import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletResponse;
/**
* Created by yixian on 2017-02-07.
*/
@ -40,4 +42,6 @@ public interface BDPrizeService {
void deleteCommConfig(String config_id);
void updateBdKpiConfig(List<JSONObject> configs, JSONObject manager)throws ParseException;
void exportCommissionMonth(String month, HttpServletResponse response) throws Exception;
}

@ -5,12 +5,7 @@ import au.com.royalpay.payment.manage.bdprize.core.BDPrizeService;
import au.com.royalpay.payment.manage.bdprize.support.BDPrizeCalculator;
import au.com.royalpay.payment.manage.bdprize.support.impls.BDPrizeCalculatorDefaultImpl;
import au.com.royalpay.payment.manage.bdprize.support.impls.DefaultClientWithBDAwayDeterminor;
import au.com.royalpay.payment.manage.mappers.financial.FinancialBDCommissionConfigMapper;
import au.com.royalpay.payment.manage.mappers.financial.FinancialBDConfigMapper;
import au.com.royalpay.payment.manage.mappers.financial.FinancialBDPrizeDetailMapper;
import au.com.royalpay.payment.manage.mappers.financial.FinancialBDPrizeLogMapper;
import au.com.royalpay.payment.manage.mappers.financial.FinancialBDPrizeRecordMapper;
import au.com.royalpay.payment.manage.mappers.financial.FinancialBDRateConfigMapper;
import au.com.royalpay.payment.manage.mappers.financial.*;
import au.com.royalpay.payment.manage.mappers.payment.TransactionMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientBDMapper;
import au.com.royalpay.payment.manage.mappers.system.ManagerMapper;
@ -27,6 +22,11 @@ import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,6 +34,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@ -44,6 +45,7 @@ import java.util.GregorianCalendar;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
/**
* Created by yixian on 2017-02-07.
@ -74,6 +76,8 @@ public class BDPrizeServiceImpl implements BDPrizeService {
@Resource
private FinancialBDCommissionConfigMapper financialBDCommissionConfigMapper;
@Resource
private FinancialLeaderPrizeLogMapper financialLeaderPrizeLogMapper;
@Value("${app.backup-app:false}")
private boolean backupSystem;
@ -239,54 +243,88 @@ public class BDPrizeServiceImpl implements BDPrizeService {
// cityPrizeLog.put("total_prize", total_prize);
// }
// report.put("cityPrizeLogs", cityPrizeLog);
List<JSONObject> leaderPrizeLog = financialLeaderPrizeLogMapper.listLeaderPrizeLog(report.getString("record_id"));
if (leaderPrizeLog.size() > 0) {
for (JSONObject prizeLog : leaderPrizeLog) {
if (prizeLog.getIntValue("bd_type") == 3) {
report.put("sydneyPrizeLog", prizeLog);
}
if (prizeLog.getIntValue("bd_type") == 4) {
report.put("directPrizeLogs", prizeLog);
}
if (prizeLog.getIntValue("bd_type") == 5) {
report.put("ngDepartmentPrizeLog", prizeLog);
}
}
return report;
}
//bd_type=3 悉尼分公司经理 悉尼销售组和大客户组流水提成
JSONObject sydneyPrizeLog = new JSONObject();
BigDecimal sydneyAmount = transactionMapper.TotalAmountForSydneyGMPrize(monthDate.getYear(), monthDate.getMonthOfYear());
sydneyPrizeLog.put("total_amount",sydneyAmount);
JSONObject sydneyGMRate = financialBDCommissionConfigMapper.findCurrentCommissionRate(month, sydneyAmount.toString(), 3);
if (sydneyGMRate == null) {
sydneyPrizeLog.put("total_prize", 0.00);
} else {
BigDecimal sydney_commission_rate = new BigDecimal(sydneyGMRate.getString("commission_rate"));
BigDecimal total_prize = sydneyAmount.multiply(sydney_commission_rate.divide(percent)).setScale(2, BigDecimal.ROUND_DOWN);
sydneyPrizeLog.put("total_prize", total_prize);
if (!locker.lock(report.getString("record_id"), 300_000)) {
throw new ServerErrorException("Processing task, wait for a moment");
}
report.put("sydneyPrizeLog", sydneyPrizeLog);
//COO & NJ commission
JSONObject params = new JSONObject();
params.put("begin", TimeZoneUtils.beginDate(TimeZoneUtils.getFirstDay(monthDate.toString())));
params.put("end", TimeZoneUtils.getPerFirstDayOfMonth(TimeZoneUtils.getLastDay(monthDate.toString())));
BigDecimal totalprize = transactionAnalysisMapper.analysisTotalAmount(params);
try {
List<JSONObject> prizeLogList = new ArrayList<>();
JSONObject sydneyPrizeLog = new JSONObject();
BigDecimal sydneyAmount = transactionMapper.TotalAmountForSydneyGMPrize(monthDate.getYear(), monthDate.getMonthOfYear());
sydneyPrizeLog.put("total_amount",sydneyAmount);
sydneyPrizeLog.put("bd_type", 3);
JSONObject sydneyGMRate = financialBDCommissionConfigMapper.findCurrentCommissionRate(month, sydneyAmount.toString(), 3);
if (sydneyGMRate == null) {
sydneyPrizeLog.put("total_prize", 0.00);
} else {
BigDecimal sydney_commission_rate = new BigDecimal(sydneyGMRate.getString("commission_rate"));
BigDecimal total_prize = sydneyAmount.multiply(sydney_commission_rate.divide(percent)).setScale(2, BigDecimal.ROUND_DOWN);
sydneyPrizeLog.put("total_prize", total_prize);
}
report.put("sydneyPrizeLog", sydneyPrizeLog);
prizeLogList.add(sydneyPrizeLog);
//COO & NJ commission
JSONObject params = new JSONObject();
params.put("begin", TimeZoneUtils.beginDate(TimeZoneUtils.getFirstDay(monthDate.toString())));
params.put("end", TimeZoneUtils.getPerFirstDayOfMonth(TimeZoneUtils.getLastDay(monthDate.toString())));
BigDecimal totalprize = transactionAnalysisMapper.analysisTotalAmount(params);
JSONObject directPrizeLogs = new JSONObject();
directPrizeLogs.put("total_amount", totalprize);
directPrizeLogs.put("bd_type", 4);
JSONObject rate = financialBDCommissionConfigMapper.findCurrentCommissionRate(month, totalprize.toString(), 4);
if (rate == null) {
directPrizeLogs.put("total_prize", 0.00);
} else {
BigDecimal _commission_rate = new BigDecimal(rate.getString("commission_rate"));
BigDecimal _total_amount = new BigDecimal(directPrizeLogs.getString("total_amount"));
BigDecimal total_prize = _total_amount.multiply(_commission_rate.divide(percent)).setScale(2, BigDecimal.ROUND_DOWN);
directPrizeLogs.put("total_prize", total_prize);
}
report.put("directPrizeLogs", directPrizeLogs);
prizeLogList.add(directPrizeLogs);
JSONObject ngDepartmentPrizeLog = new JSONObject();
ngDepartmentPrizeLog.put("total_amount", totalprize);
ngDepartmentPrizeLog.put("bd_type", 5);
JSONObject ngRate = financialBDCommissionConfigMapper.findCurrentCommissionRate(month, totalprize.toString(), 5);
if (ngRate == null) {
ngDepartmentPrizeLog.put("total_prize", 0.00);
} else {
BigDecimal ng_commission_rate = new BigDecimal(ngRate.getString("commission_rate"));
BigDecimal ng_total_prize = totalprize.multiply(ng_commission_rate.divide(percent)).setScale(2, BigDecimal.ROUND_DOWN);
ngDepartmentPrizeLog.put("total_prize", ng_total_prize);
}
report.put("ngDepartmentPrizeLog", ngDepartmentPrizeLog);
prizeLogList.add(ngDepartmentPrizeLog);
JSONObject directPrizeLogs = new JSONObject();
directPrizeLogs.put("total_amount", totalprize);
JSONObject rate = financialBDCommissionConfigMapper.findCurrentCommissionRate(month, totalprize.toString(), 4);
if (rate == null) {
directPrizeLogs.put("total_prize", 0.00);
} else {
BigDecimal _commission_rate = new BigDecimal(rate.getString("commission_rate"));
BigDecimal _total_amount = new BigDecimal(directPrizeLogs.getString("total_amount"));
BigDecimal total_prize = _total_amount.multiply(_commission_rate.divide(percent)).setScale(2, BigDecimal.ROUND_DOWN);
directPrizeLogs.put("total_prize", total_prize);
for (JSONObject prizeLog : prizeLogList) {
prizeLog.put("record_id", report.getString("record_id"));
prizeLog.put("create_time", new Date());
financialLeaderPrizeLogMapper.save(prizeLog);
}
return report;
} finally {
locker.unlock(report.getString("record_id"));
}
report.put("directPrizeLogs", directPrizeLogs);
JSONObject ngDepartmentPrizeLog = new JSONObject();
ngDepartmentPrizeLog.put("total_amount", totalprize);
JSONObject ngRate = financialBDCommissionConfigMapper.findCurrentCommissionRate(month, totalprize.toString(), 5);
if (ngRate == null) {
ngDepartmentPrizeLog.put("total_prize", 0.00);
} else {
BigDecimal ng_commission_rate = new BigDecimal(ngRate.getString("commission_rate"));
BigDecimal ng_total_prize = totalprize.multiply(ng_commission_rate.divide(percent)).setScale(2, BigDecimal.ROUND_DOWN);
ngDepartmentPrizeLog.put("total_prize", ng_total_prize);
}
report.put("ngDepartmentPrizeLog", ngDepartmentPrizeLog);
return report;
}
@Override
@ -469,4 +507,136 @@ public class BDPrizeServiceImpl implements BDPrizeService {
financialBDConfigMapper.updateBDConfig(config);
}
}
@Override
public void exportCommissionMonth(String month, HttpServletResponse resp) throws Exception {
OutputStream ous = null;
JSONObject report = findReport(month);
if (report != null) {
List<JSONObject> logs = (List<JSONObject>) report.get("logs");
resp.setContentType("application/octet-stream;");
resp.addHeader("Content-Disposition", "attachment; filename=" + "BD_Commission_Info_" + month + ".xls");
ous = resp.getOutputStream();
HSSFWorkbook wb = new HSSFWorkbook();
Cell cell = null;
HSSFFont font = wb.createFont();
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
font.setFontHeightInPoints((short) 10);
CellStyle titleStyle = wb.createCellStyle();
titleStyle.setFont(font);
HSSFCellStyle style = wb.createCellStyle();
//设置背景颜色
style.setFillForegroundColor(HSSFColor.RED.index);
//solid 填充 foreground 前景色
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
Sheet sheet = wb.createSheet("BD_Commission_Info_" + month);
sheet.setDefaultColumnWidth(20);
int rowNum = 0;
Row row = sheet.createRow(rowNum);
//bd and manager
String[] BDTitle = {"BD Name","KPI", "BD Level", "Transaction Amount", "Total Commission","Send Commission", "Hold prize", "Prize Type"};
for (int i = 0; i < BDTitle.length; i++) {
cell = row.createCell(i, Cell.CELL_TYPE_STRING);
cell.setCellStyle(titleStyle);
cell.setCellValue(BDTitle[i]);
}
for (JSONObject log : logs) {
row = sheet.createRow(++rowNum);
row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue(log.getString("bd_name"));
row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(log.getBigDecimal("kpi_amount")==null?BigDecimal.ZERO.toPlainString():log.getBigDecimal("kpi_amount").toPlainString());
row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(financialBdLevel(log.getIntValue("bd_level")));
row.createCell(3, Cell.CELL_TYPE_STRING).setCellValue(log.getBigDecimal("total_amount").toPlainString());
row.createCell(4, Cell.CELL_TYPE_STRING).setCellValue(log.getBigDecimal("total_prize").toPlainString());
row.createCell(5, Cell.CELL_TYPE_STRING).setCellValue(log.getBigDecimal("send_prize").toPlainString());
row.createCell(6, Cell.CELL_TYPE_STRING).setCellValue(log.getBigDecimal("hold_prize").toPlainString());
if (log.getIntValue("prize_type") == 0) {
row.createCell(7, Cell.CELL_TYPE_STRING).setCellValue("BD");
}
if (log.getIntValue("prize_type") == 1) {
row.createCell(7, Cell.CELL_TYPE_STRING).setCellValue("Group");
}
if (!log.getBoolean("is_valid")) {
for (int i = 0; i <= 7; i++) {
row.getCell(i).setCellStyle(style);
}
}
}
//analysis
String[] analysisTitle = {"month", "Total Commission", "Total Send", "Total Hold", "Total Fund"};
row = sheet.createRow(++rowNum);
for (int i = 0; i < analysisTitle.length; i++) {
cell = row.createCell(i, Cell.CELL_TYPE_STRING);
cell.setCellStyle(titleStyle);
cell.setCellValue(analysisTitle[i]);
}
row = sheet.createRow(++rowNum);
row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue(month);
row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(report.getBigDecimal("total_prize").toPlainString());
row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(report.getBigDecimal("total_send_prize").toPlainString());
row.createCell(3, Cell.CELL_TYPE_STRING).setCellValue(report.getBigDecimal("total_hold_prize").toPlainString());
row.createCell(4, Cell.CELL_TYPE_STRING).setCellValue(report.getBigDecimal("total_donation").toPlainString());
//channel
String[] channelTitle = {"channel", "BD Total Commission", "BD Total Send", "BD Total Hold", "BD Total Fund"};
row = sheet.createRow(++rowNum);
for (int i = 0; i < channelTitle.length; i++) {
cell = row.createCell(i, Cell.CELL_TYPE_STRING);
cell.setCellStyle(titleStyle);
cell.setCellValue(channelTitle[i]);
}
for (String channel: channels) {
JSONObject channelReport = report.getJSONObject(channel + "Report");
if (channelReport != null) {
row = sheet.createRow(++rowNum);
row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue(channel);
row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(channelReport.getBigDecimal("total_prize").toPlainString());
row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(channelReport.getBigDecimal("total_send_prize").toPlainString());
row.createCell(3, Cell.CELL_TYPE_STRING).setCellValue(channelReport.getBigDecimal("total_hold_prize").toPlainString());
row.createCell(4, Cell.CELL_TYPE_STRING).setCellValue(channelReport.getBigDecimal("total_donation").toPlainString());
}
}
//Sydney GM & COO & NJ commission
String[] GMTitle = {"name", "Transaction Amount", "Total Commission"};
row = sheet.createRow(++rowNum);
for (int i = 0; i < GMTitle.length; i++) {
cell = row.createCell(i, Cell.CELL_TYPE_STRING);
cell.setCellStyle(titleStyle);
cell.setCellValue(GMTitle[i]);
}
JSONObject sydneyPrizeLog = report.getJSONObject("sydneyPrizeLog");
row = sheet.createRow(++rowNum);
row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue("Sydney GM");
row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(sydneyPrizeLog.getBigDecimal("total_amount").toPlainString());
row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(sydneyPrizeLog.getBigDecimal("total_prize").toPlainString());
JSONObject ngDepartmentPrizeLog = report.getJSONObject("ngDepartmentPrizeLog");
row = sheet.createRow(++rowNum);
row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue("NJ Department");
row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(ngDepartmentPrizeLog.getBigDecimal("total_amount").toPlainString());
row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(ngDepartmentPrizeLog.getBigDecimal("total_prize").toPlainString());
JSONObject directPrizeLogs = report.getJSONObject("directPrizeLogs");
row = sheet.createRow(++rowNum);
row.createCell(0, Cell.CELL_TYPE_STRING).setCellValue("COO");
row.createCell(1, Cell.CELL_TYPE_STRING).setCellValue(directPrizeLogs.getBigDecimal("total_amount").toPlainString());
row.createCell(2, Cell.CELL_TYPE_STRING).setCellValue(directPrizeLogs.getBigDecimal("total_prize").toPlainString());
wb.write(ous);
ous.flush();
}
}
private String financialBdLevel (int level) {
switch (level) {
case 0:
return "Leader";
case 1:
return "Junior";
case 2:
return "Intermediate";
case 3:
return "Senior";
default:
return "Unknown";
}
}
}

@ -15,10 +15,12 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
/**
* Created by yixian on 2017-02-07.
@ -97,4 +99,9 @@ public class BDPrizeController {
public void updatKpiConfig(@PathVariable String month , @RequestBody List<JSONObject> info , @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) throws ParseException {
bdPrizeService.updateBdKpiConfig(info,manager);
}
@ManagerMapping(value = "/commission/export/{month}",method = RequestMethod.GET, role = {ManagerRole.SALES_MANAGER, ManagerRole.FINANCIAL_STAFF,ManagerRole.DIRECTOR, ManagerRole.ADMIN})
public void exportCommissionMonth(@PathVariable String month, HttpServletResponse response) throws Exception {
bdPrizeService.exportCommissionMonth(month, response);
}
}

@ -0,0 +1,11 @@
package au.com.royalpay.payment.manage.management.sysconfig.core;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
public interface SysPaymentConfig {
List<JSONObject> getPaymentChannel();
void updatePaymentChannel(JSONObject manager, String channel, int type);
}

@ -0,0 +1,34 @@
package au.com.royalpay.payment.manage.management.sysconfig.core.impls;
import au.com.royalpay.payment.manage.management.sysconfig.core.SysPaymentConfig;
import au.com.royalpay.payment.manage.mappers.system.RateMapper;
import au.com.royalpay.payment.manage.mappers.system.SysChannelConfigMapper;
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
public class SysPaymentConfigImpl implements SysPaymentConfig {
@Resource
private SysChannelConfigMapper sysChannelConfigMapper;
@Override
public List<JSONObject> getPaymentChannel() {
return sysChannelConfigMapper.selectAll();
}
@Override
public void updatePaymentChannel(JSONObject manager, String channel, int type) {
JSONObject paymentConfig = sysChannelConfigMapper.find(channel, type);
if (paymentConfig == null) {
throw new BadRequestException("不存在该快捷通道");
}
Date lastUpdateTime = new Date();
sysChannelConfigMapper.updatePaymentConfig(channel, type, lastUpdateTime, manager.getString("display_name"), false);
sysChannelConfigMapper.updatePaymentConfig(channel, type, lastUpdateTime, manager.getString("display_name"), true);
}
}

@ -1,17 +1,15 @@
package au.com.royalpay.payment.manage.management.sysconfig.web;
import au.com.royalpay.payment.manage.management.sysconfig.core.ClearDateManager;
import au.com.royalpay.payment.manage.management.sysconfig.core.SysPaymentConfig;
import au.com.royalpay.payment.manage.permission.manager.ManagerMapping;
import au.com.royalpay.payment.tools.CommonConsts;
import au.com.royalpay.payment.tools.env.SysConfigManager;
import au.com.royalpay.payment.tools.permission.enums.ManagerRole;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
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 java.util.List;
@ -27,6 +25,8 @@ public class SysConfigController {
private SysConfigManager sysConfigManager;
@Resource
private ClearDateManager clearDateManager;
@Resource
private SysPaymentConfig sysPaymentConfig;
@ManagerMapping(value = "/base", method = RequestMethod.GET)
public JSONObject getBaseConfig() {
@ -48,8 +48,13 @@ public class SysConfigController {
clearDateManager.setMonthClearDays(monthPattern, days);
}
@ManagerMapping(value = "/payment/config", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.FINANCIAL_STAFF, ManagerRole.OPERATOR})
public List<JSONObject> selectPaymentChannel() {
return sysPaymentConfig.getPaymentChannel();
}
public static void main(String[] args) {
System.out.println("asd".equals(null));
@ManagerMapping(value = "/payment/{channel}/config/{type}", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.FINANCIAL_STAFF, ManagerRole.OPERATOR})
public void updatePaymentChannel(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String channel, @PathVariable int type) {
sysPaymentConfig.updatePaymentChannel(manager, channel, type);
}
}

@ -0,0 +1,19 @@
package au.com.royalpay.payment.manage.mappers.financial;
import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper;
import cn.yixblog.support.mybatis.autosql.annotations.AutoSql;
import cn.yixblog.support.mybatis.autosql.annotations.SqlType;
import com.alibaba.fastjson.JSONObject;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@AutoMapper(tablename = "financial_leader_prize_log", pkName = "leader_prize_log")
public interface FinancialLeaderPrizeLogMapper {
@AutoSql(type = SqlType.SELECT)
List<JSONObject> listLeaderPrizeLog(@Param(value = "record_id") String record_id);
@AutoSql(type = SqlType.INSERT)
void save(JSONObject prizeLog);
}

@ -30,4 +30,12 @@ public interface CouponAccuessLogMapper {
List<JSONObject> findCouponByOrderId(@Param("order_id") String order_id);
PageList<JSONObject> getCouponAccuessLog(@Param("client_id")int client_id, @Param("keyword")String keyword, PageBounds pageBounds);
@AutoSql(type = SqlType.SELECT)
@AdvanceSelect(addonWhereClause = "is_valid = 0")
List<JSONObject> findAccuessLogByOrderId(@Param("order_id") String order_id, PageBounds pageBounds);
@AutoSql(type = SqlType.SELECT)
@AdvanceSelect(addonWhereClause = "is_valid = 1")
List<JSONObject> findUsedCouponByOrderIdList(@Param("order_id") String order_id);
}

@ -0,0 +1,24 @@
package au.com.royalpay.payment.manage.mappers.system;
import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper;
import cn.yixblog.support.mybatis.autosql.annotations.AutoSql;
import cn.yixblog.support.mybatis.autosql.annotations.SqlType;
import com.alibaba.fastjson.JSONObject;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
@AutoMapper(tablename = "cb_channel_config",pkName = "channel_id")
public interface SysChannelConfigMapper {
@AutoSql(type = SqlType.SELECT)
List<JSONObject> selectAll();
@AutoSql(type = SqlType.SELECT)
JSONObject find(@Param(value = "channel_id") String channel, @Param(value = "type") int type);
void updatePaymentConfig(@Param(value = "channel_id") String channel, @Param(value = "type") int type, @Param(value = "last_update_date")Date lastUpdateDate,
@Param(value = "last_update_by")String lastUpdateBy, @Param(value = "is_valid") boolean is_valid);
JSONObject findOne(@Param(value = "type") int type);
}

@ -271,7 +271,7 @@ public interface ClientManager {
void updateAppClient(JSONObject account,int client_id, AppClientBean appClientBean);
void setSkipClearing(JSONObject account,String clientMoniker, Boolean skip_clearing);
void setSkipClearing(JSONObject account,String clientMoniker, Boolean skip_clearing,String remark);
void enableGatewayUpgrade(JSONObject account,String clientMoniker, boolean gatewayUpgrade);
@ -369,4 +369,13 @@ public interface ClientManager {
JSONObject comListPartnerSelection(JSONObject manager, PartnerQuery query);
List<JSONObject> getClientBySimpleQuery(JSONObject param);
void switchPaymentConfig(String clientMoniker, HttpServletResponse response) throws IOException;
@Transactional
void switchCBBankLink(JSONObject manager, String clientMoniker, boolean allow);
String cbBankPayLink(String clientMoniker);
void switchPaymentConfigPC(String clientMoniker, HttpServletResponse response) throws IOException;
}

@ -27,25 +27,7 @@ import au.com.royalpay.payment.manage.mappers.log.LogSettleMailMapper;
import au.com.royalpay.payment.manage.mappers.payment.TransactionMapper;
import au.com.royalpay.payment.manage.mappers.redpack.ActClientInvitationCodeMapper;
import au.com.royalpay.payment.manage.mappers.risk.RiskAttentionMerchantsMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientApplyMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientAuditProcessMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientBDMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientBankAccountMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientConfigMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientDeviceMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientFilesMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientRateMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientsContractMapper;
import au.com.royalpay.payment.manage.mappers.system.CommoditiesMapper;
import au.com.royalpay.payment.manage.mappers.system.MailSendMapper;
import au.com.royalpay.payment.manage.mappers.system.MailUnsubMapper;
import au.com.royalpay.payment.manage.mappers.system.ManagerMapper;
import au.com.royalpay.payment.manage.mappers.system.OrgMapper;
import au.com.royalpay.payment.manage.mappers.system.PermissionPartnerModuleMapper;
import au.com.royalpay.payment.manage.mappers.system.SysRpayMerchantApplyMapper;
import au.com.royalpay.payment.manage.mappers.system.SysWxMerchantApplyMapper;
import au.com.royalpay.payment.manage.mappers.system.*;
import au.com.royalpay.payment.manage.merchants.beans.ActivityPosterBuilder;
import au.com.royalpay.payment.manage.merchants.beans.BankAccountInfo;
import au.com.royalpay.payment.manage.merchants.beans.ClientAuthFilesInfo;
@ -313,6 +295,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
private PermissionPartnerManagerImpl permissionPartnerManagerImpl;
@Resource
private RiskAttentionMerchantsMapper riskAttentionMerchantsMapper;
@Resource
private SysChannelConfigMapper sysChannelConfigMapper;
@Resource
private SmsSender smsSender;
@ -445,6 +429,10 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
String yeepayQrcodeUrl = PlatformEnvironment.getEnv().concatUrl("/api/v1.0/yeepay/partners/" + client.getString("client_moniker") + "/jump/app");
client.put("yeepayQrcodeUrl", QRCodeUtils.qrcodeImageCode(yeepayQrcodeUrl, 250, true));
}
if (client.getString("cb_bankpay_url") != null) {
String cbBankPayQrcodeUrl = PlatformEnvironment.getEnv().concatUrl("/sys/partners/" + client.getString("client_moniker") + "/cb_bankpay/link");
client.put("cbBankPayQrcodeUrl", QRCodeUtils.qrcodeImageCode(cbBankPayQrcodeUrl, 250, true));
}
return client;
}
@ -1244,7 +1232,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
@Override
public void switchChannelPermission(JSONObject manager, String clientMoniker, String channel, boolean allow) {
for (PaymentChannelApi channelApi : channels) {
if (channelApi.channel().equalsIgnoreCase(channel)) {
if (channelApi.channel().equalsIgnoreCase(channel) || "CB_BankPay".equalsIgnoreCase(channel)) {
JSONObject client = getClientInfoByMoniker(clientMoniker);
if (client == null) {
throw new NotFoundException("Client Not Exists");
@ -1553,6 +1541,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
for (PaymentChannelApi channel : channels) {
rates.addAll(merchantInfoProvider.listClientRates(clientId, new Date(), channel.channel(), includingInactive));
}
rates.addAll(merchantInfoProvider.listClientRates(clientId, new Date(), "CB_BankPay", includingInactive));
if (!rates.isEmpty()) {
try {
for (JSONObject rate : rates) {
@ -1624,20 +1613,22 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
checkAddRate(config, "AlipayOnline", "alipayonline_rate_value", org, "min_alipayonline_rate");
checkAddRate(config, "Bestpay", "bestpay_rate_value", org, "min_bestpay_rate");
checkAddRate(config, "jd", "jd_rate_value", org, "min_jd_rate");
checkAddRate(config, "hf", "hf_rate_value", org, "min_hf_rate");
// checkAddRate(config, "hf", "hf_rate_value", org, "min_hf_rate");
checkAddRate(config, "Rpay", "Rpay_rate_value", org, "min_Rpay_rate");
checkAddRate(config, "Yeepay", "yeepay_rate_value", org, "min_yeepay_rate");
// checkAddRate(config, "Yeepay", "yeepay_rate_value", org, "min_yeepay_rate");
checkAddRate(config, "CB_BankPay", "min_cb_bankpay_value", org, "min_cb_bankpay_rate");
configNewClientRate(config, clientId, "Wechat", "wechat_rate_value", org, "min_wechat_rate");
configNewClientRate(config, clientId, "Alipay", "alipay_rate_value", org, "min_alipay_rate");
configNewClientRate(config, clientId, "AlipayOnline", "alipayonline_rate_value", org, "min_alipayonline_rate");
configNewClientRate(config, clientId, "Bestpay", "bestpay_rate_value", org, "min_bestpay_rate");
configNewClientRate(config, clientId, "jd", "jd_rate_value", org, "min_jd_rate");
configNewClientRate(config, clientId, "hf", "hf_rate_value", org, "min_hf_rate");
// configNewClientRate(config, clientId, "hf", "hf_rate_value", org, "min_hf_rate");
configNewClientRate(config, clientId, "Rpay", "Rpay_rate_value", org, "min_Rpay_rate");
configNewClientRate(config, clientId, "Yeepay", "yeepay_rate_value", org, "min_yeepay_rate");
// configNewClientRate(config, clientId, "Yeepay", "yeepay_rate_value", org, "min_yeepay_rate");
configNewClientRate(config, clientId, "CB_BankPay", "cb_bankpay_rate_value", org, "min_cb_bankpay_rate");
//todo 暂不更新Rpay+ 费率信息
rpayApi.modifySurchargeConfig(client);
//rpayApi.modifySurchargeConfig(client);
}
@ -3234,12 +3225,23 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
@Override
@Transactional
public void setSkipClearing(JSONObject account, String clientMoniker, Boolean skip_clearing) {
public void setSkipClearing(JSONObject account, String clientMoniker, Boolean skip_clearing,String remark) {
JSONObject client = getClientInfoByMoniker(clientMoniker);
if (client == null) {
throw new InvalidShortIdException();
}
clientModifySupport.processClientConfigModify(new SwitchPermissionModify(account, clientMoniker, "skip_clearing", skip_clearing));
if (!skip_clearing) {
if ("".equals(remark) || remark==null){
throw new ServerErrorException("请填写关闭清算原因");
}
JSONObject clientConfig = clientConfigMapper.find(client.getIntValue("client_id"));
clientConfig.put("skip_settle_remark", remark);
clientConfigMapper.update(clientConfig);
}
client.put("skip_clearing", skip_clearing);
if (client.getString("rpay_enterprise_id") != null) {
rpayApi.switchMerchantSettle(client);
@ -4257,6 +4259,65 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
return PageListUtils.buildPageListResult(partners);
}
@Override
public void switchPaymentConfig(String clientMoniker, HttpServletResponse response) throws IOException {
JSONObject client = clientMapper.findClientByMoniker(clientMoniker);
if (client == null) {
throw new BadRequestException("partner code is not exists!");
}
JSONObject paymentConfig = sysChannelConfigMapper.findOne(1);
if (paymentConfig == null) {
throw new BadRequestException("服务商未开启快捷支付");
}
response.sendRedirect(String.format(PlatformEnvironment.getEnv().concatUrl(paymentConfig.getString("path")), clientMoniker));
}
@Override
public void switchCBBankLink(JSONObject manager, String clientMoniker, boolean allow) {
JSONObject client = getClientInfoByMoniker(clientMoniker);
if (client == null) {
throw new InvalidShortIdException();
}
checkOrgPermission(manager, client);
if (StringUtils.isEmpty(client.getString("cb_bankpay_url"))) {
String longUrl = PlatformEnvironment.getEnv().concatUrl("/sys/partners/" + client.getString("client_moniker") + "/cb_bankpay/link/pc");
String cb_bankpay_url = getCBBankShortLink(longUrl);
client.put("cb_bankpay_url", cb_bankpay_url);
client.put("enable_cb_bankpay_link", allow);
clientMapper.update(client);
} else {
client.put("enable_cb_bankpay_link", allow);
clientMapper.update(client);
}
}
@Override
public String cbBankPayLink(String clientMoniker) {
JSONObject client = clientMapper.findClientByMoniker(clientMoniker);
if (client == null) {
throw new BadRequestException("partner code is not exists!");
}
JSONObject paymentConfig = sysChannelConfigMapper.findOne(1);
if (paymentConfig == null) {
throw new BadRequestException("服务商未开启快捷支付");
}
return String.format(PlatformEnvironment.getEnv().concatUrl(paymentConfig.getString("path")), clientMoniker);
}
@Override
public void switchPaymentConfigPC(String clientMoniker, HttpServletResponse response) throws IOException {
JSONObject client = clientMapper.findClientByMoniker(clientMoniker);
if (client == null) {
throw new BadRequestException("partner code is not exists!");
}
JSONObject paymentConfig = sysChannelConfigMapper.findOne(1);
if (paymentConfig == null) {
throw new BadRequestException("服务商未开启快捷支付");
}
String path = paymentConfig.getString("path");
path = path.replaceAll("app","pc");
response.sendRedirect(String.format(PlatformEnvironment.getEnv().concatUrl(path), clientMoniker));
}
private TemplateMessage initClientMessage(JSONObject client, String newExpiryDate, String wechatOpenid, String templateId) {
TemplateMessage notice = new TemplateMessage(wechatOpenid, templateId, null);
@ -4281,4 +4342,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
}).start();
}
private String getCBBankShortLink(String longUrl) {
MpWechatApi api = mpWechatApiProvider.getNewPaymentApi();
return api.registerShortUrl(longUrl);
}
}

@ -367,7 +367,7 @@ public class PartnerManageController {
@ManagerMapping(value = "/{clientMoniker}/skip_clearing", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR, ManagerRole.FINANCIAL_STAFF})
public void skipClearing(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject skip_clearing) {
clientManager.setSkipClearing(manager,clientMoniker, skip_clearing.getBooleanValue("skip_clearing"));
clientManager.setSkipClearing(manager,clientMoniker, skip_clearing.getBooleanValue("skip_clearing"),skip_clearing.getString("remark"));
}
@ManagerMapping(value = "/{clientMoniker}/settle_hour", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR, ManagerRole.SERVANT, ManagerRole.FINANCIAL_STAFF})
@ -621,4 +621,24 @@ public class PartnerManageController {
return clientManager.comListPartnerSelection(manager, query);
}
@RequestMapping(value = "/{clientMoniker}/cb_bankpay/link", method = RequestMethod.GET)
public void switchPaymentWay(@PathVariable String clientMoniker, HttpServletResponse response) throws IOException {
clientManager.switchPaymentConfig(clientMoniker, response);
}
@ManagerMapping(value = "/{clientMoniker}/cb_bankpay", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR})
public void switchCBBankPayLinkPermission(@PathVariable String clientMoniker, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) {
clientManager.switchCBBankLink(manager, clientMoniker, pass.getBooleanValue("allow"));
}
@RequestMapping(value = "/{clientMoniker}/jump/link", method = RequestMethod.GET)
public String jumpCBBankPayLink(@PathVariable String clientMoniker) {
return clientManager.cbBankPayLink(clientMoniker);
}
@RequestMapping(value = "/{clientMoniker}/cb_bankpay/link/pc", method = RequestMethod.GET)
public void switchPaymentWayPC(@PathVariable String clientMoniker, HttpServletResponse response) throws IOException {
clientManager.switchPaymentConfigPC(clientMoniker, response);
}
}

@ -30,6 +30,7 @@ public class OrgInfo {
private Double jd_rate_value;
private Double hf_rate_value;
private Double yeepay_rate_value;
private Double cb_bankpay_rate_value;
private int is_valid;
private String search_text;
private int page = 1;
@ -44,6 +45,7 @@ public class OrgInfo {
private Double min_alipayonline_rate;
private Double min_hf_rate;
private Double min_yeepay_rate;
private Double min_cb_bankpay_rate;
private String state;
private String senior_parent_org_id;
@ -341,4 +343,20 @@ public class OrgInfo {
public void setMin_yeepay_rate(Double min_yeepay_rate) {
this.min_yeepay_rate = min_yeepay_rate;
}
public Double getCb_bankpay_rate_value() {
return cb_bankpay_rate_value;
}
public void setCb_bankpay_rate_value(Double cb_bankpay_rate_value) {
this.cb_bankpay_rate_value = cb_bankpay_rate_value;
}
public Double getMin_cb_bankpay_rate() {
return min_cb_bankpay_rate;
}
public void setMin_cb_bankpay_rate(Double min_cb_bankpay_rate) {
this.min_cb_bankpay_rate = min_cb_bankpay_rate;
}
}

@ -0,0 +1,194 @@
package au.com.royalpay.payment.manage.processors;
import au.com.royalpay.payment.core.PaymentApi;
import au.com.royalpay.payment.core.beans.PreOrderRequest;
import au.com.royalpay.payment.core.beans.coupon.CouponInfo;
import au.com.royalpay.payment.core.events.PaymentFinishedEvent;
import au.com.royalpay.payment.core.events.RefundSendEvent;
import au.com.royalpay.payment.core.processors.PaymentProcessor;
import au.com.royalpay.payment.manage.mappers.log.CouponAccuessLogMapper;
import au.com.royalpay.payment.tools.CommonConsts;
import au.com.royalpay.payment.tools.env.PlatformEnvironment;
import au.com.royalpay.payment.tools.env.SysConfigManager;
import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider;
import au.com.royalpay.payment.tools.utils.CurrencyAmountUtils;
import cn.yixblog.platform.http.HttpRequestGenerator;
import cn.yixblog.platform.http.HttpRequestResult;
import com.alibaba.fastjson.JSONObject;
import com.github.miemiedev.mybatis.paginator.domain.Order;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.util.UriComponentsBuilder;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Service
public class CtripCouponOnlyLogProcessor implements PaymentProcessor {
// todo 重构逻辑
private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
private static final String COUPON_ID = "CTRIP_COUPON_ONLY_LOG";
@Value("${app.customer.host}")
private String CUSTOMER_HOST;
@Value("${customer.app.appid}")
private String CUSTOMER_APP_ID;
@Value("${customer.app.auth-code}")
private String CUSTOMER_AUTH_CODE;
@Resource
private MerchantInfoProvider merchantInfoProvider;
@Resource
private SysConfigManager sysConfigManager;
@Resource
private CouponAccuessLogMapper payCouponAccuessLogMapper;
@Resource
private PaymentApi paymentApi;
@Override
public String processorId() {
return COUPON_ID + "_USE";
}
@Override
public void handleBeforeOrderSending(PreOrderRequest paymentInfo, JSONObject order) {
JSONObject tmpEle = paymentInfo.getTmpEle();
if (tmpEle == null) {
return;
}
if (StringUtils.isEmpty(tmpEle.getString("ctrip_coupon_id"))) {
return;
}
if (!isOnlyLogMerchant(order.getIntValue("client_id"))) {
return;
}
JSONObject couponInfo = getPreOrderCoupon(tmpEle.getString("ctrip_coupon_id"), order.getIntValue("client_id"));
if (couponInfo == null) {
return;
}
BigDecimal payFee = paymentInfo.getTotalFee();
BigDecimal exchange = paymentApi.channelApi(paymentInfo.getChannel()).queryExchangeRateDecimal(paymentInfo.getClientId());
if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) {
payFee = CurrencyAmountUtils.scale(payFee.divide(exchange,2, BigDecimal.ROUND_HALF_UP), PlatformEnvironment.getEnv().getForeignCurrency());
}
BigDecimal couponCondition = couponInfo.getBigDecimal("condition") == null ? BigDecimal.ZERO
: couponInfo.getBigDecimal("condition");
if (payFee.compareTo(couponCondition) < 0) {
return;
}
JSONObject couponAccuessLog = new JSONObject();
couponAccuessLog.put("client_id",order.getIntValue("client_id"));
couponAccuessLog.put("customer_openid","创建订单时无");
couponAccuessLog.put("creation_date",new Date());
couponAccuessLog.put("order_id",order.getString("order_id"));
couponAccuessLog.put("coupon_id","CTRIP_"+tmpEle.getString("ctrip_coupon_id"));
//携程满减
if (StringUtils.equals(couponInfo.getString("type"), "31")) {
BigDecimal actureAmount = couponInfo.getBigDecimal("acture_amount");
if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) {
actureAmount = CurrencyAmountUtils.scale(couponInfo.getBigDecimal("acture_amount").multiply(exchange), PlatformEnvironment.getEnv().getForeignCurrency());
}
couponAccuessLog.put("coupon_deal_amount", actureAmount);
}
//携程折扣
if (StringUtils.equals(couponInfo.getString("type"), "32")) {
BigDecimal couponDiscount = couponInfo.getBigDecimal("discount").divide(CommonConsts.HUNDRED, 4, BigDecimal.ROUND_HALF_UP);
BigDecimal couponDealAmount = CurrencyAmountUtils.scale(couponDiscount.multiply(paymentInfo.getTotalFee()), PlatformEnvironment.getEnv().getForeignCurrency());
couponAccuessLog.put("coupon_deal_amount", couponDealAmount);
}
couponAccuessLog.put("currency", order.getString("currency"));
couponAccuessLog.put("min_pay_amount", couponCondition);
payCouponAccuessLogMapper.save(couponAccuessLog);
}
@Override
public void handleAfterOrderPaid(PaymentFinishedEvent finishedEvent) {
JSONObject order = finishedEvent.getOrder();
String orderId = order.getString("order_id");
List<JSONObject> accuessCouponLogs = payCouponAccuessLogMapper.findAccuessLogByOrderId(orderId, new PageBounds(Order.formString("last_update_date.desc")));
if (accuessCouponLogs != null&&accuessCouponLogs.size()>0) {
if (!isOnlyLogMerchant(order.getIntValue("client_id"))) {
return;
}
JSONObject accuessCouponLog = accuessCouponLogs.get(0);
String couponLogId = accuessCouponLog.getString("coupon_id");
logger.info("订单 [" + orderId + "]成功使用Ctrip卡券=======>[" + couponLogId + "]");
accuessCouponLog.put("is_valid", 1);
accuessCouponLog.put("last_update_date", new Date());
accuessCouponLog.put("customer_openid",order.getString("customer_id"));
payCouponAccuessLogMapper.update(accuessCouponLog);
}
}
@Override
public void registerCoupon(JSONObject client, String customerOpenId, String channel, List<CouponInfo> coupons) {
return;
}
@Override
public void handleAfterRefund(RefundSendEvent event) {
//do nothing
JSONObject refundOrder = event.getRefundOrder();
String orderId = refundOrder.getString("order_id");
List<JSONObject> accuessCouponLogs = payCouponAccuessLogMapper.findUsedCouponByOrderIdList(orderId);
if (accuessCouponLogs != null&& accuessCouponLogs.size()>0) {
if (!isOnlyLogMerchant(refundOrder.getIntValue("client_id"))) {
return;
}
JSONObject accuessCouponLog = accuessCouponLogs.get(0);
accuessCouponLog.put("is_valid", 0);
accuessCouponLog.put("last_update_date", new Date());
accuessCouponLog.put("refund_id",refundOrder.getString("refund_id"));
payCouponAccuessLogMapper.update(accuessCouponLog);
}
}
@Override
public String registerBanner(JSONObject client, String channel) {
return null;
}
// 使用券的信息
private JSONObject getPreOrderCoupon(String couponLogId,int clientId) {
JSONObject client = merchantInfoProvider.getClientInfo(clientId);
String timestamp = System.currentTimeMillis() + "";
String base = CUSTOMER_APP_ID + timestamp + CUSTOMER_AUTH_CODE;
String sign = DigestUtils.sha256Hex(base).toLowerCase();
String uri = UriComponentsBuilder.fromHttpUrl(CUSTOMER_HOST + "coupon/" + couponLogId + "/couponLogInfo").queryParam("appid", CUSTOMER_APP_ID)
.queryParam("timestamp", timestamp).queryParam("sign", sign).queryParam("client_moniker", client.getString("client_moniker")).toUriString();
HttpRequestGenerator gen = new HttpRequestGenerator(uri, RequestMethod.GET);
try {
HttpRequestResult result = gen.execute();
if (result.isSuccess()) {
return result.getResponseContentJSONObj();
}
} catch (Exception ignored) {
logger.error("积分商城优惠券 [" + couponLogId + "]使用失败");
ignored.printStackTrace();
}
return null;
}
private boolean isOnlyLogMerchant(int clientId) {
JSONObject client = merchantInfoProvider.getClientInfo(clientId);
JSONObject sysConfig = sysConfigManager.getSysConfig();
if (sysConfig.getString("ctrip_coupon_only_log_merchant_list").contains(client.getString("client_moniker"))) {
return true;
}
return false;
}
}

@ -0,0 +1,266 @@
package au.com.royalpay.payment.manage.processors;
import au.com.royalpay.payment.core.PaymentApi;
import au.com.royalpay.payment.core.TransactionService;
import au.com.royalpay.payment.core.beans.PaymentQueryResult;
import au.com.royalpay.payment.core.beans.PreOrderRequest;
import au.com.royalpay.payment.core.beans.coupon.CouponInfo;
import au.com.royalpay.payment.core.events.PaymentFinishedEvent;
import au.com.royalpay.payment.core.events.RefundSendEvent;
import au.com.royalpay.payment.core.mappers.PmtOrderMapper;
import au.com.royalpay.payment.core.processors.PaymentProcessor;
import au.com.royalpay.payment.manage.mappers.log.CouponAccuessLogMapper;
import au.com.royalpay.payment.tools.CommonConsts;
import au.com.royalpay.payment.tools.env.PlatformEnvironment;
import au.com.royalpay.payment.tools.env.SysConfigManager;
import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider;
import au.com.royalpay.payment.tools.utils.CurrencyAmountUtils;
import cn.yixblog.platform.http.HttpRequestGenerator;
import cn.yixblog.platform.http.HttpRequestResult;
import com.alibaba.fastjson.JSONObject;
import com.github.miemiedev.mybatis.paginator.domain.Order;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.util.UriComponentsBuilder;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Service
public class CtripCouponProvideProcessor implements PaymentProcessor {
// todo 重构逻辑
private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
private static final String COUPON_ID = "CTRIP_COUPON";
@Value("${app.customer.host}")
private String CUSTOMER_HOST;
@Value("${customer.app.appid}")
private String CUSTOMER_APP_ID;
@Value("${customer.app.auth-code}")
private String CUSTOMER_AUTH_CODE;
@Resource
private MerchantInfoProvider merchantInfoProvider;
@Resource
private SysConfigManager sysConfigManager;
@Resource
private CouponAccuessLogMapper payCouponAccuessLogMapper;
@Resource
private PaymentApi paymentApi;
@Resource
private PmtOrderMapper pmtOrderMapper;
@Resource
private TransactionService transactionService;
@Override
public String processorId() {
return COUPON_ID + "_USE";
}
@Override
public void handleBeforeOrderSending(PreOrderRequest paymentInfo, JSONObject order) {
/*if (order.getIntValue("client_id") != 9) {
return;
}*/
JSONObject tmpEle = paymentInfo.getTmpEle();
if (tmpEle == null) {
return;
}
if (StringUtils.isEmpty(tmpEle.getString("ctrip_coupon_id"))) {
return;
}
logger.info("tmpEle:" + tmpEle.toJSONString());
if (isOnlyLogMerchant(order.getIntValue("client_id"))) {
return;
}
JSONObject couponInfo = getPreOrderCoupon(tmpEle.getString("ctrip_coupon_id"), order.getIntValue("client_id"));
if (couponInfo == null) {
return;
}
BigDecimal payFee = paymentInfo.getTotalFee();
BigDecimal exchange = paymentApi.channelApi(paymentInfo.getChannel()).queryExchangeRateDecimal(paymentInfo.getClientId());
if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) {
payFee = CurrencyAmountUtils.scale(payFee.divide(exchange,2, BigDecimal.ROUND_HALF_UP), PlatformEnvironment.getEnv().getForeignCurrency());
}
BigDecimal couponCondition = couponInfo.getBigDecimal("condition") == null ? BigDecimal.ZERO
: couponInfo.getBigDecimal("condition");
if (payFee.compareTo(couponCondition) < 0) {
return;
}
JSONObject couponAccuessLog = new JSONObject();
couponAccuessLog.put("client_id",order.getIntValue("client_id"));
couponAccuessLog.put("customer_openid","创建订单时无");
couponAccuessLog.put("creation_date",new Date());
couponAccuessLog.put("order_id",order.getString("order_id"));
couponAccuessLog.put("coupon_id","CTRIP_"+tmpEle.getString("ctrip_coupon_id"));
BigDecimal currentDiscount = paymentInfo.getDiscount();
//携程满减
if (StringUtils.equals(couponInfo.getString("type"), "31")) {
BigDecimal actureAmount = couponInfo.getBigDecimal("acture_amount");
if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) {
actureAmount = CurrencyAmountUtils.scale(couponInfo.getBigDecimal("acture_amount").multiply(exchange), PlatformEnvironment.getEnv().getForeignCurrency());
}
paymentInfo.setDiscount(currentDiscount.add(actureAmount));
couponAccuessLog.put("coupon_deal_amount", actureAmount);
}
//携程折扣
if (StringUtils.equals(couponInfo.getString("type"), "32")) {
BigDecimal couponDiscount = couponInfo.getBigDecimal("discount").divide(CommonConsts.HUNDRED, 4, BigDecimal.ROUND_HALF_UP);
BigDecimal couponDealAmount = CurrencyAmountUtils.scale(couponDiscount.multiply(paymentInfo.getTotalFee()), PlatformEnvironment.getEnv().getForeignCurrency());
paymentInfo.setDiscount(currentDiscount.add(couponDealAmount));
couponAccuessLog.put("coupon_deal_amount", couponDealAmount);
}
couponAccuessLog.put("currency", order.getString("currency"));
couponAccuessLog.put("min_pay_amount", couponCondition);
payCouponAccuessLogMapper.save(couponAccuessLog);
JSONObject updateOrder = new JSONObject();
BigDecimal customerPay = paymentInfo.getUserPayAmount();
updateOrder.put("customer_payment_amount", customerPay);
BigDecimal couponDiscount = paymentInfo.getDiscount();
updateOrder.put("coupon_payment_amount", couponDiscount);
updateOrder.put("order_id", paymentInfo.getOrderId());
pmtOrderMapper.update(updateOrder);
order.put("customer_payment_amount", customerPay);
order.put("coupon_payment_amount", couponDiscount);
}
@Override
public void handleAfterOrderPaid(PaymentFinishedEvent finishedEvent) {
JSONObject order = finishedEvent.getOrder();
/*if (order.getIntValue("client_id") != 9) {
return;
}*/
String orderId = order.getString("order_id");
List<JSONObject> accuessCouponLogs = payCouponAccuessLogMapper.findAccuessLogByOrderId(orderId, new PageBounds(Order.formString("last_update_date.desc")));
if (accuessCouponLogs != null&&accuessCouponLogs.size()>0) {
if (isOnlyLogMerchant(order.getIntValue("client_id"))) {
return;
}
JSONObject accuessCouponLog = accuessCouponLogs.get(0);
String couponLogId = accuessCouponLog.getString("coupon_id");
logger.info("订单 [" + orderId + "]成功使用Ctrip卡券=======>[" + couponLogId + "]");
//传入流水
JSONObject useCoupontrans = new JSONObject();
useCoupontrans.put("org_id", order.getIntValue("org_id"));
useCoupontrans.put("system_transaction_id", accuessCouponLog.getString("accuess_id"));
useCoupontrans.put("order_id", order.getString("order_id"));
useCoupontrans.put("client_id", order.getIntValue("client_id"));
useCoupontrans.put("transaction_currency", order.getString("currency"));
if (StringUtils.equals(order.getString("currency"), "CNY")) {
useCoupontrans.put("cny_amount", accuessCouponLog.getBigDecimal("coupon_deal_amount"));
}
useCoupontrans.put("clearing_currency", PlatformEnvironment.getEnv().getForeignCurrency());
useCoupontrans.put("clearing_amount", accuessCouponLog.getBigDecimal("coupon_deal_amount"));
useCoupontrans.put("transaction_amount", accuessCouponLog.getBigDecimal("coupon_deal_amount"));
useCoupontrans.put("exchange_rate", finishedEvent.getExchangeRate());
useCoupontrans.put("channel", order.getString("channel"));
useCoupontrans.put("transaction_type", "Credit");
PaymentQueryResult pay = finishedEvent.getPaymentQueryResult();
useCoupontrans.put("transaction_time", pay.getPayTime());
useCoupontrans.put("clearing_status", 0);
useCoupontrans.put("system_generate", 1);
useCoupontrans.put("remark", "Ctrip Coupon from Customer:" + couponLogId);
accuessCouponLog = payCouponAccuessLogMapper.findAccuessLogByOrderId(orderId,new PageBounds(Order.formString("last_update_date.desc"))).get(0);
if (accuessCouponLog != null) {
transactionService.saveTransaction(useCoupontrans);
accuessCouponLog.put("is_valid", 1);
accuessCouponLog.put("last_update_date", new Date());
accuessCouponLog.put("transaction_id", useCoupontrans.getString("transaction_id"));
accuessCouponLog.put("customer_openid",order.getString("customer_id"));
payCouponAccuessLogMapper.update(accuessCouponLog);
}
}
}
@Override
public void registerCoupon(JSONObject client, String customerOpenId, String channel, List<CouponInfo> coupons) {
return;
}
@Override
public void handleAfterRefund(RefundSendEvent event) {
//do nothing
JSONObject refundOrder = event.getRefundOrder();
/*if (refundOrder.getIntValue("client_id") != 9) {
return;
}*/
logger.info("积分商城携程优惠券开始退款");
String orderId = refundOrder.getString("order_id");
List<JSONObject> accuessCouponLogs = payCouponAccuessLogMapper.findUsedCouponByOrderIdList(orderId);
if (accuessCouponLogs != null&& accuessCouponLogs.size()>0) {
if (isOnlyLogMerchant(refundOrder.getIntValue("client_id"))) {
return;
}
JSONObject accuessCouponLog = accuessCouponLogs.get(0);
JSONObject trans = transactionService.findTransaction(accuessCouponLog.getString("transaction_id"));
if (trans != null) {
logger.info("正在退款的券的初始信息" + trans.toJSONString());
trans.remove("transaction_id");
trans.put("transaction_type", "Debit");
String coupon_id = accuessCouponLog.getString("coupon_id");
trans.put("refund_id", refundOrder.getString("refund_id"));
trans.put("transaction_time", new Date());
trans.put("remark", "Refund for Customer Ctrip Coupon:" + coupon_id);
logger.info("正在退款的券的信息" + trans.toJSONString());
transactionService.saveTransaction(trans);
logger.error("订单[" + orderId + "]发送全额退款,携程优惠券【" + coupon_id + "】转为Debit");
accuessCouponLog.put("transaction_refund_id", trans.getString("transaction_id"));
accuessCouponLog.put("refund_id", refundOrder.getString("refund_id"));
accuessCouponLog.put("is_valid", 0);
accuessCouponLog.put("last_update_date", new Date());
payCouponAccuessLogMapper.update(accuessCouponLog);
}
}
}
@Override
public String registerBanner(JSONObject client, String channel) {
return null;
}
// 使用券的信息
private JSONObject getPreOrderCoupon(String couponLogId,int clientId) {
JSONObject client = merchantInfoProvider.getClientInfo(clientId);
String timestamp = System.currentTimeMillis() + "";
String base = CUSTOMER_APP_ID + timestamp + CUSTOMER_AUTH_CODE;
String sign = DigestUtils.sha256Hex(base).toLowerCase();
String uri = UriComponentsBuilder.fromHttpUrl(CUSTOMER_HOST + "coupon/" + couponLogId + "/couponLogInfo").queryParam("appid", CUSTOMER_APP_ID)
.queryParam("timestamp", timestamp).queryParam("sign", sign).queryParam("client_moniker", client.getString("client_moniker")).toUriString();
HttpRequestGenerator gen = new HttpRequestGenerator(uri, RequestMethod.GET);
try {
HttpRequestResult result = gen.execute();
if (result.isSuccess()) {
return result.getResponseContentJSONObj();
}
} catch (Exception ignored) {
logger.error("积分商城优惠券 [" + couponLogId + "]使用失败");
ignored.printStackTrace();
}
return null;
}
private boolean isOnlyLogMerchant(int clientId) {
JSONObject client = merchantInfoProvider.getClientInfo(clientId);
JSONObject sysConfig = sysConfigManager.getSysConfig();
if (sysConfig.getString("ctrip_coupon_only_log_merchant_list").contains(client.getString("client_moniker"))) {
return true;
}
return false;
}
}

@ -126,6 +126,8 @@ public interface RiskBusinessService {
*/
JSONObject getRiskEventMaterialsRemark(String riskId);
void banRiskEvent(String riskId);
JSONObject riskEventMaterialPass(JSONObject params, JSONObject manager);
JSONObject updateIsSendClient(String riskId);

@ -335,7 +335,7 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
}
private void setRiskOrders(JSONObject params){
if(StringUtils.isNotBlank(params.getString("order_ids"))){
if(StringUtils.isNotBlank(params.getString("real_order_ids"))){
String riskId = params.getString("risk_id");
String orderIds = params.getString("real_order_ids");
for(String orderId : orderIds.split(",")){
@ -980,6 +980,14 @@ public class RiskBusinessServiceImpl implements RiskBusinessService, ManagerTodo
return result;
}
@Override
public void banRiskEvent(String riskId) {
JSONObject params = new JSONObject();
params.put("risk_id",riskId);
params.put("is_valid",0);
riskEventMapper.update(params);
}
@Transactional
@Override
public JSONObject riskEventMaterialPass(JSONObject params, JSONObject manager) {

@ -151,6 +151,11 @@ public class RiskBusinessController {
riskBusinessService.sendUrgeEmail(risk_id);
}
@RequestMapping(value = "/ban/{risk_id}",method = RequestMethod.DELETE)
public void banEvent(@PathVariable String risk_id){
riskBusinessService.banRiskEvent(risk_id);
}
@GetMapping(value = "/partners")
public List<JSONObject> getPartners(PartnerQuery partnerQuery) {
JSONObject param = partnerQuery.toJsonParam();

@ -11,7 +11,8 @@
r.*,l.kpi_amount,
sum(total_prize) total_prize,
sum(send_prize) total_send_prize,
sum(total_donation) total_donation
sum(total_donation) total_donation,
sum(hold_prize) total_hold_prize
FROM financial_bd_prize_records r
INNER JOIN financial_bd_prize_log l ON l.record_id = r.record_id
WHERE r.month = #{month}
@ -20,7 +21,8 @@
SELECT
sum(total_prize) total_prize,
sum(send_prize) total_send_prize,
sum(total_donation) total_donation
sum(total_donation) total_donation,
sum(hold_prize) total_hold_prize
FROM financial_bd_prize_log
WHERE record_id = #{record_id}
AND channel = #{channel}

@ -51,6 +51,7 @@
ON sc.client_id = scb.client_id
</if>
<where>
re.is_valid = 1
<if test="risk_id != null">
AND re.risk_id = #{risk_id}
</if>
@ -175,6 +176,7 @@
ON re.risk_id = ro.risk_id
</if>
<where>
re.is_valid = 1
<if test="risk_id != null">
AND re.risk_id = #{risk_id}
</if>
@ -257,6 +259,7 @@
) ro
ON re.risk_id = ro.risk_id
<where>
re.is_valid = 1
<if test="risk_id != null">
AND re.risk_id = #{risk_id}
</if>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="au.com.royalpay.payment.manage.mappers.system.SysChannelConfigMapper">
<update id="updatePaymentConfig">
update cb_channel_config
SET is_valid = #{is_valid},last_update_by = #{last_update_by},last_update_date = #{last_update_date}
<where>
type = #{type}
<if test="is_valid">
and channel_id = #{channel_id}
</if>
<if test="!is_valid">
and channel_id != #{channel_id}
</if>
</where>
</update>
<select id="findOne" resultType="com.alibaba.fastjson.JSONObject">
select * from cb_channel_config where is_valid = 1 and type = #{type} limit 1;
</select>
</mapper>

@ -292,6 +292,20 @@ define(['angular', 'jquery', 'uiRouter', './monitoring/analysis-monitoring'],
orderChannel = null;
}
$scope.deleteRiskEvent = function () {
commonDialog.confirm({
title: 'Delete This Risk Event',
content: 'Are you sure to delete this risk event?'
}).then(function () {
$http.delete('/risk/business/ban/' + $scope.riskEvent.risk_id).then(function () {
$state.go('analysis_monitoring.risk_business');
commonDialog.alert({title: 'Delete', content: 'Risk Event Already Disabled', type: 'error'});
}, function (resp) {
commonDialog.alert({title: 'Error', content: resp.data.message, type: 'error'});
})
})
};
/**
* order_ids在指定位置换行
* @param str

@ -9,6 +9,9 @@
<i class="fa fa-arrow-right" aria-hidden="true" style="margin-top: 5px" ng-if="riskEvent.process_logs.length > ($index + 1)"></i>
</small>
</div>
<div class="btn-group pull-right" role="group" aria-label="..." ng-if="'10000000000'|withRole">
<button type="button" class="btn btn-danger" ng-click="deleteRiskEvent()">Delete</button>
</div>
</div>
<div class="row">
<div class="col-sm-12">

@ -141,6 +141,9 @@ define(['angular', '../../analysis/bd/analysis-bd'], function (angular) {
}
}
})
};
$scope.exportCommission = function (monModal) {
location.href = '/sys/bd_prize/commission/export/' + monModal;
}
}]);
app.controller('bdRateConfigCtrl', ['$scope', '$http', 'rates', function ($scope, $http, rates) {

@ -49,18 +49,20 @@
</div>
<div class="box-body">
<div class="row">
<div class="col-xs-2" ng-repeat="mon in months">
<div class="col-xs-2" style="text-align: center" ng-repeat="mon in months">
<a ng-if="hasReport(mon) && (('10000000000000'|withRole)||('1000'|withRole))">
<h2 ROLE="button" class="text-success" ui-sref=".month_report({month:mon})" ng-bind="mon.substring(5,7)"></h2>
<span class="fa fa-edit btn" ng-click="editCommissionConfig(mon)">Commission</span>
<span class="fa fa-edit btn" ng-click="editCommissionConfig(mon)"></span>
<span class="fa fa-download btn" ng-click="exportCommission(mon)"></span>
</a>
<a ng-if="hasReport(mon) && ('100'|withRole) && (!('1000'|withRole))">
<h2 ROLE="button" class="text-success" ui-sref=".bd_detail({month:mon})" ng-bind="mon.substring(5,7)"></h2>
<span class="fa fa-edit btn" ng-click="editCommissionConfig(mon)">Commission</span>
<span class="fa fa-edit btn" ng-click="editCommissionConfig(mon)"></span>
<span class="fa fa-download btn" ng-click="exportCommission(mon)"></span>
</a>
<a ng-if="!hasReport(mon)">
<h2 ROLE="button" class="text-gray" ng-bind="mon.substring(5,7)"></h2>
<span class="fa fa-edit btn" ng-click="editCommissionConfig(mon)">Commission</span>
<span class="fa fa-edit btn" ng-click="editCommissionConfig(mon)"></span>
</a>
</div>
</div>

@ -179,7 +179,7 @@
</div>
</div>
</div>
<div class="form-group"
<!--<div class="form-group"
ng-class="{'has-error':org_form.hf_rate_value.$invalid && org_form.hf_rate_value.$dirty}">
<label class="control-label col-sm-2" for="hf_rate_value_input">HF Rate *</label>
<div class="col-sm-8">
@ -190,8 +190,8 @@
<span class="input-group-addon">%</span>
</div>
</div>
</div>
<div class="form-group"
</div>-->
<!--<div class="form-group"
ng-class="{'has-error':org_form.yeepay_rate_value.$invalid && org_form.yeepay_rate_value.$dirty}">
<label class="control-label col-sm-2" for="yeepay_rate_value_input">Yeepay Rate *</label>
<div class="col-sm-8">
@ -202,6 +202,18 @@
<span class="input-group-addon">%</span>
</div>
</div>
</div>-->
<div class="form-group"
ng-class="{'has-error':org_form.cb_bankpay_rate_value.$invalid && org_form.cb_bankpay_rate_value.$dirty}">
<label class="control-label col-sm-2" for="cb_bankpay_rate_value_input">CB BankPay Rate *</label>
<div class="col-sm-8">
<div class="input-group">
<input class="form-control" type="number" ng-model="org.cb_bankpay_rate_value"
id="cb_bankpay_rate_value_input" name="cb_bankpay_rate_value"
max="100" min="0">
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
@ -267,7 +279,7 @@
</div>
</div>
</div>
<div class="form-group"
<!--<div class="form-group"
ng-class="{'has-error':org_form.min_hf_rate.$invalid && org_form.min_hf_rate.$dirty}">
<label class="control-label col-sm-2" for="min_hf_rate_input">Min HF Rate *</label>
<div class="col-sm-8">
@ -278,8 +290,8 @@
<span class="input-group-addon">%</span>
</div>
</div>
</div>
<div class="form-group"
</div>-->
<!--<div class="form-group"
ng-class="{'has-error':org_form.min_yeepay_rate.$invalid && org_form.min_yeepay_rate.$dirty}">
<label class="control-label col-sm-2" for="min_yeepay_rate_input">Min Yeepay Rate *</label>
<div class="col-sm-8">
@ -290,6 +302,18 @@
<span class="input-group-addon">%</span>
</div>
</div>
</div>-->
<div class="form-group"
ng-class="{'has-error':org_form.min_cb_bankpay_rate.$invalid && org_form.min_cb_bankpay_rate.$dirty}">
<label class="control-label col-sm-2" for="min_cb_bankpay_rate_input">Min CB BankPay Rate *</label>
<div class="col-sm-8">
<div class="input-group">
<input class="form-control" type="number" ng-model="org.min_cb_bankpay_rate"
id="min_cb_bankpay_rate_input" name="min_cb_bankpay_rate_rate" max="100"
min="0" required>
<span class="input-group-addon">%</span>
</div>
</div>
</div>
</div>
</div>

@ -152,7 +152,7 @@
<span class="input-group-addon form-control-span">%</span>
</div>
</div>
<div class="form-group" ng-class="{'has-error':org_form.hf_rate_value.$invalid && org_form.hf_rate_value.$dirty}">
<!--<div class="form-group" ng-class="{'has-error':org_form.hf_rate_value.$invalid && org_form.hf_rate_value.$dirty}">
<label class="control-label col-sm-2" for="hf_rate_value_input">HF Rate *</label>
<div class="col-sm-8">
<input class="form-control form-control-float" type="number" ng-model="org.hf_rate_value" id="hf_rate_value_input" name="hf_rate_value" max="100" min="0">
@ -165,6 +165,13 @@
<input class="form-control form-control-float" type="number" ng-model="org.yeepay_rate_value" id="yeepay_rate_value_input" name="yeepay_rate_value" max="100" min="0">
<span class="input-group-addon form-control-span">%</span>
</div>
</div>-->
<div class="form-group" ng-class="{'has-error':org_form.cb_bankpay_rate_value.$invalid && org_form.cb_bankpay_rate_value.$dirty}">
<label class="control-label col-sm-2" for="cb_bankpay_rate_value_input">CB BankPay Rate *</label>
<div class="col-sm-8">
<input class="form-control form-control-float" type="number" ng-model="org.cb_bankpay_rate_value" id="cb_bankpay_rate_value_input" name="cb_bankpay_rate_value" max="100" min="0">
<span class="input-group-addon form-control-span">%</span>
</div>
</div>
</div>
@ -218,7 +225,7 @@
<span class="input-group-addon form-control-span">%</span>
</div>
</div>
<div class="form-group"
<!--<div class="form-group"
ng-class="{'has-error':org_form.min_hf_rate.$invalid && org_form.min_hf_rate.$dirty}">
<label class="control-label col-sm-2" for="min_hf_rate_input">Min HF Rate *</label>
<div class="col-sm-8">
@ -235,6 +242,15 @@
id="min_yeepay_rate_input" name="min_yeepay_rate" max="100" min="0">
<span class="input-group-addon form-control-span">%</span>
</div>
</div>-->
<div class="form-group"
ng-class="{'has-error':org_form.min_cb_bankpay_rate.$invalid && org_form.min_cb_bankpay_rate.$dirty}">
<label class="control-label col-sm-2" for="min_yeepay_rate_input">Min CB BankPay Rate *</label>
<div class="col-sm-8">
<input class="form-control form-control-float" type="number" ng-model="org.min_cb_bankpay_rate"
id="min_cb_bankpay_rate_input" name="min_cb_bankpay_rate" max="100" min="0">
<span class="input-group-addon form-control-span">%</span>
</div>
</div>
</div>
</div>

@ -13,6 +13,10 @@ define(['angular', 'uiRouter'], function (angular) {
url: '/basic',
templateUrl: '/static/config/sysconfigs/templates/basic.html',
controller: 'basicConfigCtrl'
}).state('sysconfig.payment_bankpay_config', {
url: '/payment',
templateUrl: '/static/config/sysconfigs/templates/payment_bankpay_config.html',
controller: 'paymentChannelConfigCtrl'
}).state('permission', {
url: '/permission',
templateUrl: '/static/config/sysconfigs/templates/permission_config.html',
@ -66,6 +70,51 @@ define(['angular', 'uiRouter'], function (angular) {
}]);
app.controller('paymentChannelConfigCtrl', ['$scope', '$http', 'commonDialog', function ($scope, $http, commonDialog) {
$scope.loadPaymentChannel = function () {
$scope.cb_bankpay_channel = null;
$scope.pay_channel = null;
$scope.cb_bankpay = [];
$scope.pay = [];
$http.get('/sysconfig/payment/config').then(function (resp) {
resp.data.forEach(function (channel) {
if (channel.type === 1) {
if (channel.is_valid) {
$scope.cb_bankpay_channel = channel.channel_id;
}
$scope.cb_bankpay.push(channel);
}
if (channel.type === 2) {
if (channel.is_valid) {
$scope.pay_channel = channel.channel_id;
}
$scope.pay.push(channel);
}
})
})
};
$scope.loadPaymentChannel();
$scope.updatePaymentConfig = function (type,channel) {
if (channel == null) {
commonDialog.alert({type: 'error', title: 'Error', content: '支付通道不能为空'});
return;
}
commonDialog.confirm({
title: 'Confirm',
content: '你确定要将支付通道更改为:' + channel
}).then(function () {
$http.put('/sysconfig/payment/'+ channel + '/config/' + type).then(function (resp) {
commonDialog.alert({type: 'success', title: 'Success', content: '修改成功'});
$scope.loadPaymentChannel();
}, function (resp) {
commonDialog.alert({type: 'error', title: 'Error', content: resp.data.message});
$scope.loadPaymentChannel();
});
})
}
}]);
app.controller('servantsConfigCtrl', ['$scope','$http','commonDialog', function ($scope,$http,commonDialog) {
$scope.ctrl={};
$scope.loadServants = function () {

@ -0,0 +1,40 @@
<section class="content-header">
<h1>Basic Config</h1>
<ol class="breadcrumb">
<li>
<a ui-sref="^"><i class="fa fa-cog"></i> System Config</a>
</li>
<li>Payment BankPay Config</li>
</ol>
</section>
<div class="content">
<div class="row">
<div class="col-sm-12">
<div class="box-solid">
<div class="box box-warning">
<div class="box-header">
<form role="form" style="margin:0px auto;width: 50%">
<div class="form-group" >
<label>快捷通道</label>
<select class="form-control" name="industry" ng-change="updatePaymentConfig(1,cb_bankpay_channel)"
ng-model="cb_bankpay_channel"
id="cbbankpay-input" required
ng-options="channel.channel_id as channel.channel_name for channel in cb_bankpay">
<option value="">请选择</option>
</select>
<label>网银通道</label>
<select class="form-control" name="industry" ng-change="updatePaymentConfig(2,pay_channel)"
ng-model="pay_channel"
id="-input" required
ng-options="channel.channel_id as channel.channel_name for channel in pay">
<option value="">请选择</option>
</select>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>

@ -35,10 +35,10 @@
<!--Servants Config-->
<!--</a>-->
<!--<a class="btn btn-app" role="button" ui-sref=".payment_config">
<a class="btn btn-app" role="button" ui-sref=".payment_bankpay_config">
<i class="fa fa-edit"></i>
Payment Config
</a>-->
</a>
</div>
</div>
</section>

@ -1318,6 +1318,16 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
commonDialog.alert({title: 'Error', content: '您的浏览器不支持!', type: 'error'});
}
};
$scope.copyCBBankPayLink = function() {
var e=document.getElementById("cpcbbankpay");
e.select();
var successful = document.execCommand("Copy");
if (successful) {
commonDialog.alert({title: 'Success', content: '已复制到剪切板!', type: 'success'});
}else {
commonDialog.alert({title: 'Error', content: '您的浏览器不支持!', type: 'error'});
}
};
$scope.loadPartnerPaymentInfo = function () {
$http.get('/sys/partners/' + $scope.partner.client_moniker).then(function (resp) {
$scope.paymentInfo = resp.data;
@ -1624,6 +1634,21 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
})
};
$scope.toggleCBBankPayLink = function () {
if (!$scope.paymentInfo) {
return;
}
$http.put('/sys/partners/' + $scope.partner.client_moniker + '/cb_bankpay', {allow: $scope.paymentInfo.enable_cb_bankpay_link}).then(function () {
$scope.loadPartnerPaymentInfo();
}, function (resp) {
commonDialog.alert({
title: 'Failed to change cb_bankpay permission status',
content: resp.data.message,
type: 'error'
});
})
};
$scope.toggleGatewayEmailNotice = function (channel) {
if (!$scope.paymentInfo) {
return;
@ -1887,7 +1912,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
$scope.loadSubClients();
}]);
app.controller('partnerRatesCtrl', ['$scope', '$rootScope', '$http', '$uibModal', 'commonDialog', function ($scope, $rootScope, $http, $uibModal, commonDialog) {
app.controller('partnerRatesCtrl', ['$scope', '$rootScope', '$http', '$uibModal', 'commonDialog','$sce', function ($scope, $rootScope, $http, $uibModal, commonDialog,$sce) {
$scope.bankCtrl = {edit: true, rate_name: 'Wechat'};
$scope.init = {skip_clearing:false,tax_in_surcharge:false,customer_tax_free:false};
$scope.getBankAccount = function () {
@ -1906,19 +1931,39 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
})
});
};
$scope.skipClearing = function (skipClearing) {
if (!$scope.init.skip_clearing) {
$scope.init.skip_clearing = true;
return;
}
commonDialog.confirm({
title: 'Warning',
content: 'This operation will switch skip clearing status. Are you sure?'
}).then(function () {
$http.put('/sys/partners/' + $scope.partner.client_moniker + '/skip_clearing', {skip_clearing: skipClearing}).then(function (resp) {
$scope.getBankAccount();
});
})
if (!skipClearing) {
commonDialog.confirm({
title: 'Warning',
content: 'This operation will switch skip clearing status. Are you sure?'
}).then(function () {
commonDialog.inputText({title: '请输入关闭跳过清算的原因'}).then(function (text) {
$http.put('/sys/partners/' + $scope.partner.client_moniker + '/skip_clearing', {
skip_clearing: skipClearing,
remark: text
}).then(function (resp) {
$scope.getBankAccount();
});
});
})
}else{
commonDialog.confirm({
title: 'Warning',
content: 'This operation will switch skip clearing status. Are you sure?',
// contentHtml: $sce.trustAsHtml('This operation will switch skip clearing status. Are you sure?<input ng-model="remark"></input>')
}).then(function () {
$http.put('/sys/partners/' + $scope.partner.client_moniker + '/skip_clearing', {skip_clearing: skipClearing}).then(function (resp) {
$scope.getBankAccount();
});
})
}
};
$scope.taxInSurcharge = function (taxInSurcharge) {
if (!$scope.init.tax_in_surcharge) {
@ -2067,6 +2112,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
$scope.rate.hf_rate_value = parseFloat($scope.sysRateConfig.t1.HFpay);
$scope.rate.Rpay_rate_value = parseFloat($scope.sysRateConfig.t1.Rpay);
$scope.rate.yeepay_rate_value = parseFloat($scope.sysRateConfig.t1.Yeepay);
$scope.rate.cb_bankpay_rate_value = parseFloat($scope.sysRateConfig.t1.CB_Bankpay);
$scope.rate.transaction_fee = 0;
break;
}
@ -2079,6 +2125,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
$scope.rate.hf_rate_value = parseFloat($scope.sysRateConfig.t2.HFpay);
$scope.rate.Rpay_rate_value = parseFloat($scope.sysRateConfig.t2.Rpay);
$scope.rate.yeepay_rate_value = parseFloat($scope.sysRateConfig.t2.Yeepay);
$scope.rate.cb_bankpay_rate_value = parseFloat($scope.sysRateConfig.t2.CB_Bankpay);
$scope.rate.transaction_fee = 0;
break;
}
@ -2091,6 +2138,7 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter
$scope.rate.hf_rate_value = parseFloat($scope.sysRateConfig.t3.HFpay);
$scope.rate.Rpay_rate_value = parseFloat($scope.sysRateConfig.t3.Rpay);
$scope.rate.yeepay_rate_value = parseFloat($scope.sysRateConfig.t3.Yeepay);
$scope.rate.cb_bankpay_rate_value = parseFloat($scope.sysRateConfig.t3.CB_Bankpay);
$scope.rate.transaction_fee = 0;
break;
}

@ -170,9 +170,10 @@
<li role="presentation" ng-class="{active:bankCtrl.rate_name=='AlipayOnline'}"><a role="button" ng-click="bankCtrl.rate_name='AlipayOnline'">Alipay(Online)</a></li>
<li role="presentation" ng-class="{active:bankCtrl.rate_name=='Bestpay'}"><a role="button" ng-click="bankCtrl.rate_name='Bestpay'">Bestpay</a></li>
<li role="presentation" ng-class="{active:bankCtrl.rate_name=='jd'}"><a role="button" ng-click="bankCtrl.rate_name='jd'">JDpay</a></li>
<li role="presentation" ng-class="{active:bankCtrl.rate_name=='hf'}"><a role="button" ng-click="bankCtrl.rate_name='hf'">HFpay</a></li>
<!--<li role="presentation" ng-class="{active:bankCtrl.rate_name=='hf'}"><a role="button" ng-click="bankCtrl.rate_name='hf'">HFpay</a></li>-->
<li role="presentation" ng-class="{active:bankCtrl.rate_name=='Rpay'}"><a role="button" ng-click="bankCtrl.rate_name='Rpay'">Rpay+</a></li>
<li role="presentation" ng-class="{active:bankCtrl.rate_name=='Yeepay'}"><a role="button" ng-click="bankCtrl.rate_name='Yeepay'">Yeepay</a></li>
<!--<li role="presentation" ng-class="{active:bankCtrl.rate_name=='Yeepay'}"><a role="button" ng-click="bankCtrl.rate_name='Yeepay'">Yeepay</a></li>-->
<li role="presentation" ng-class="{active:bankCtrl.rate_name=='CB_BankPay'}"><a role="button" ng-click="bankCtrl.rate_name='CB_BankPay'" ng-if="sysconfig.active_channels.indexOf('CB_BankPay')!=-1">CB_BankPay</a></li>
</ul>
<div class="table-responsive">
<table class="table table-bordered">

@ -112,7 +112,7 @@
</div>
</div>
<div class="form-group"
<!--<div class="form-group"
ng-class="{'has-error':rate_form.hf_rate_value.$invalid && rate_form.hf_rate_value.$dirty}">
<label class="control-label col-sm-4" for="hf_rate_value_input">HF Rate Value</label>
<div class="col-sm-6">
@ -134,7 +134,7 @@
</div>
</div>
</div>
</div>-->
<div class="form-group"
ng-class="{'has-error':rate_form.Rpay_rate_value.$invalid && rate_form.Rpay_rate_value.$dirty}">
@ -160,7 +160,7 @@
</div>
</div>
<div class="form-group"
<!--<div class="form-group"
ng-class="{'has-error':rate_form.yeepay_rate_value.$invalid && rate_form.yeepay_rate_value.$dirty}">
<label class="control-label col-sm-4" for="yeepay_rate_value_input">Yeepay Rate Value</label>
<div class="col-sm-6">
@ -181,6 +181,30 @@
</div>
</div>
</div>
</div>-->
<!--快捷支付费率-->
<div class="form-group"
ng-class="{'has-error':rate_form.cb_bankpay_rate_value.$invalid && rate_form.cb_bankpay_rate_value.$dirty}">
<label class="control-label col-sm-4" for="cb_bankpay_rate_value_input">CB BankPay Rate Value</label>
<div class="col-sm-6">
<div class="input-group">
<input type="number" name="cb_bankpay_rate_value" stringToNumber2 class="form-control" ng-model="rate.cb_bankpay_rate_value"
min="0.6" max="5.0" step="0.1" id="cb_bankpay_rate_value_input" required>
<div class="input-group-addon">%</div>
</div>
<div ng-messages="rate_form.cb_bankpay_rate_value.$error" ng-if="rate_form.cb_bankpay_rate_value.$dirty">
<div class="small text-danger" ng-message="max">
<i class="glyphicon glyphicon-alert"></i> No more than 5.0%
</div>
<div class="small text-danger" ng-message="min">
<i class="glyphicon glyphicon-alert"></i> No less than 0.6%
</div>
<div class="small text-danger" ng-message="required">
<i class="glyphicon glyphicon-alert"></i> Required Field
</div>
</div>
</div>
</div>

@ -211,7 +211,7 @@
<input type="checkbox" ng-model="paymentInfo.enable_jd" bs-switch switch-change="toggleChannel('jd')">
</div>
</div>
<div class="form-group col-sm-4">
<!--<div class="form-group col-sm-4">
<label class="col-xs-6 control-label">HF|汇付</label>
<div class="col-xs-6">
<input type="checkbox" ng-model="paymentInfo.enable_hf" bs-switch switch-change="toggleChannel('hf')">
@ -222,6 +222,12 @@
<div class="col-xs-6">
<input type="checkbox" ng-model="paymentInfo.enable_yeepay" bs-switch switch-change="toggleChannel('yeepay')">
</div>
</div>-->
<div class="form-group col-sm-4">
<label class="col-xs-6 control-label">CB BankPay|快捷支付</label>
<div class="col-xs-6">
<input type="checkbox" ng-model="paymentInfo.enable_cb_bankpay" bs-switch switch-change="toggleChannel('cb_bankpay')">
</div>
</div>
</div>
@ -345,7 +351,7 @@
</p>
</div>
</div>
<hr>
<!--<hr>
<div class="form-group">
<label class="col-sm-2 control-label">HF Pay Link</label>
<div class="col-sm-10">
@ -390,6 +396,30 @@
<div class="col-sm-10">
<input type="checkbox" ng-model="paymentInfo.enable_yeepay_email_notice" bs-switch switch-change="toggleGatewayEmailNotice('yeepay')">
</div>
</div>-->
</div>
</div>
</div>
<div class="panel panel-default" ng-if="paymentInfo.enable_cb_bankpay">
<div class="panel-heading">CB Bank Payment</div>
<div class="panel-body">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">CB Bank Pay Link</label>
<div class="col-sm-10">
<input type="checkbox" ng-model="paymentInfo.enable_cb_bankpay_link" bs-switch ng-change="toggleCBBankPayLink()">
&nbsp;&nbsp;<a href={{paymentInfo.cb_bankpay_url}} target="_Blank"><span ng-if="paymentInfo.enable_cb_bankpay_link">{{paymentInfo.cb_bankpay_url}}</span></a>
<i ng-if="paymentInfo.enable_cb_bankpay_link" class="fa fa-clipboard margin-r-5" style="cursor: pointer" ng-click="copyCBBankPayLink()"></i>
<input ng-if="paymentInfo.enable_cb_bankpay_link" style="opacity: 0" id="cpcbbankpay" value={{paymentInfo.cb_bankpay_url}} readonly>
</div>
</div>
<div class="form-group" ng-if="paymentInfo.enable_cb_bankpay && paymentInfo.enable_cb_bankpay_link">
<label class="col-sm-2 control-label">CB Bank Pay QR Code</label>
<img ng-src="{{paymentInfo.cbBankPayQrcodeUrl}}" class="img-responsive" />
<div>
&nbsp;&nbsp;<span style="padding-left: 19.2%;font-size:9px;">仅支持微信客户端扫描</span>
</div>
</div>
</div>
</div>

@ -62,7 +62,21 @@ $(function () {
updatePrice();
}
});
$('.cb_bankpay').click(function () {
$.ajax({
url: '/sys/partners/' + window.client_moniker + '/jump/link',
method: 'GET',
success: function (res) {
location.href = res;
},
error: function (resp) {
var config = {
template: resp
};
showWeuiDialog(config);
}
})
});
$('#key_B').bind('touchstart', function () {
backspace();
});

Loading…
Cancel
Save