Merge branch 'develop'

master
kira 6 years ago
commit df8bc6de69

@ -106,60 +106,7 @@
* @apiError (ERROR_CODE) ORDER_NOT_EXIST 订单不存在 * @apiError (ERROR_CODE) ORDER_NOT_EXIST 订单不存在
* @apiError (ERROR_CODE) ORDER_MISMATCH 订单号与商户不匹配 * @apiError (ERROR_CODE) ORDER_MISMATCH 订单号与商户不匹配
*/ */
/**
* @api {PUT} /api/v1.0/h5_payment/partners/{partner_code}/orders/{order_id} 创建H5支付单
* @apiName NewMobileH5Pay
* @apiGroup MobileH5
* @apiVersion 1.0.0
* @apiDescription
* <b>注意微信H5支付接口必须单独申请腾讯批复后方可使用有需要的商户请联系RoyalPay客服支付宝无此限制</b><br>
* H5支付适用场景为移动端App或者手机自带浏览器进行支付用户下单后浏览器跳转至微信支付页面并自动拉起微信/支付宝客户端完成支付<br>
* 返回值包括跳转支付地址跳转支付页需要带上签名信息
* 货币类型如果是CNY注意通过汇率转换后不得低于0.01AUD否则订单可以创建成功但支付时会报金额不合法错误<br>
* <img src="img/h5_api_payment.jpg">
* @apiHeader Accept application/json
* @apiHeader Content-Type application/json
* @apiParam (PathVariable) {String} partner_code 必填商户编码由4位大写字母或数字构成
* @apiParam (PathVariable) {String} order_id 必填商户支付订单号要求同一商户唯一
* @apiUse Sign
* @apiParam (JSON) {String} description 必填订单标题最大长度128字符超出自动截取
* @apiParam (JSON) {int} price 必填金额单位为货币最小单位例如使用100表示AUD1.00
* @apiParam (JSON) {String=AUD,CNY} currency=AUD 币种代码
* @apiParam (JSON) {String=Alipay,Wechat} channel 支付渠道大小写敏感
* @apiParam (JSON) {String} notify_url 支付通知url详见支付通知api不填则不会推送支付通知
* @apiParam (JSON) {String} operator 操作人员标识
*
* @apiSuccess {String} return_code 执行结果
* @apiSuccess {String} result_code SUCCESS表示创建订单成功EXISTS表示订单已存在
* @apiSuccess {String} partner_code 商户编码
* @apiSuccess {String} channel 支付渠道
* @apiSuccess {String} full_name 商户注册全名
* @apiSuccess {String} partner_name 商户名称
* @apiSuccess {String} order_id RoyalPay订单ID同时也是微信订单ID最终支付成功的订单ID可能不同
* @apiSuccess {String} partner_order_id 商户订单ID
* @apiSuccess {String} pay_url 跳转URL
*
* @apiUse GlobalError
* @apiError (ERROR_CODE) ORDER_MISMATCH 订单号与商户不匹配
* @apiError (ERROR_CODE) ORDER_PAID 订单已支付
*
*/
/**
* @api {GET} /api/v1.0/h5_payment/partners/{partner_code}/orders/{order_id}/pay H5支付跳转页
* @apiName MobileH5Pay
* @apiDescription 必须先调用创建H5支付订单接口再进行跳转
* 建议在用户回调到对应页时通过后台查询订单状态接口确认订单的支付状态
* @apiVersion 1.0.0
* @apiGroup MobileH5
* @apiParam (PathVariable) {String} partner_code 必填商户编码由4位大写字母或数字构成
* @apiParam (PathVariable) {String} order_id 必填商户支付订单号要求已预先创建
* @apiUse Sign
* @apiParam (QueryParam) {String} redirect 必填支付成功后跳转页面回调时会带上签名参数用于校验
*
* @apiUse GlobalError
* @apiError (ERROR_CODE) ORDER_NOT_EXIST 订单不存在
* @apiError (ERROR_CODE) ORDER_MISMATCH 订单号与商户不匹配
*/
/** /**
* @api {PUT} /api/v1.0/jsapi_gateway/partners/{partner_code}/orders/{order_id} 创建JSAPI订单 * @api {PUT} /api/v1.0/jsapi_gateway/partners/{partner_code}/orders/{order_id} 创建JSAPI订单

@ -109,62 +109,7 @@
* @apiError (ERROR_CODE) ORDER_NOT_EXIST Order does not exist * @apiError (ERROR_CODE) ORDER_NOT_EXIST Order does not exist
* @apiError (ERROR_CODE) ORDER_MISMATCH Order is not belong to this partner * @apiError (ERROR_CODE) ORDER_MISMATCH Order is not belong to this partner
*/ */
/**
* @api {PUT} /api/v1.0/h5_payment/partners/{partner_code}/orders/{order_id} Create H5 Payment
* @apiName NewMobileH5Pay
* @apiGroup MobileH5
* @apiVersion 1.0.0
* @apiDescription
* <b>WarningH5 Payment socket requires application separately and requires agreement from Tencent. Merchants who needs this socket please contact RoyalPay first.
* Alipay has no limit at the moment.</b><br>
* H5 Payment is used for payment in Webpage or App on mobile outside WeChat or Alipay App. The browser would redirect to a webpage from WeChat or Alipay and call the App to finish the payment.<br>
* Return value contains a payment page. Partners shall guide users to redirect to this page. Sign params are required.
* If the currency is CNY, equivalent AUD amount shall never less than 0.01AUD,
* otherwise user will get Invalid Amount Error from WeChat when making the payment.<br>
* <img src="img/h5_api_payment.jpg">
* @apiHeader Accept application/json
* @apiHeader Content-Type application/json
* @apiParam (PathVariable) {String} partner_code Required, Partner code
* @apiParam (PathVariable) {String} order_id Required, Partner order id
* @apiUse Sign
* @apiParam (JSON) {String} description Required, Order description
* @apiParam (JSON) {int} price Required, Price of the order. Use the base unit of the currency.
* @apiParam (JSON) {String=AUD,CNY} currency=AUD currency
* @apiParam (JSON) {String=Alipay,Wechat} channel Payment channel, case sensitive
* @apiParam (JSON) {String} notify_url System will call the notify url if provided when the payment succeeds
* @apiParam (JSON) {String} operator Note for the operator who created this order.
*
* @apiSuccess {String} return_code Execution result
* @apiSuccess {String} result_code SUCCESS means order created successfully, EXISTS means order has already existed.
* @apiSuccess {String} partner_code Partner code
* @apiSuccess {String} channel Payment channel
* @apiSuccess {String} full_name Partner's full company name when registered
* @apiSuccess {String} partner_name Partner's name
* @apiSuccess {String} order_id Order id in RoyalPay, which is also WeChat order id.
* @apiSuccess {String} partner_order_id Partner order id
* @apiSuccess {String} pay_url Payment page in RoyalPay.
*
* @apiUse GlobalError
* @apiError (ERROR_CODE) ORDER_MISMATCH Order is not belong to this partner
* @apiError (ERROR_CODE) ORDER_PAID Order has already been paid
*
*/
/**
* @api {GET} /api/v1.0/h5_payment/partners/{partner_code}/orders/{order_id}/pay H5 Payment Page
* @apiName MobileH5Pay
* @apiDescription This page mush be called after payment order has been created.
* When jumping back to redirection URL, it is recommended to call the order query API to make sure the payment has succeeded.
* @apiVersion 1.0.0
* @apiGroup MobileH5
* @apiParam (PathVariable) {String} partner_code Required, Partner code
* @apiParam (PathVariable) {String} order_id Required, Partner order id. It shall have already been created
* @apiUse Sign
* @apiParam (QueryParam) {String} redirect Required, Redirect url when payment succeeded. Contain sign parameters for validation.
*
* @apiUse GlobalError
* @apiError (ERROR_CODE) ORDER_NOT_EXIST Order does not exist
* @apiError (ERROR_CODE) ORDER_MISMATCH Order is not belong to this partner
*/
/** /**
* @api {PUT} /api/v1.0/jsapi_gateway/partners/{partner_code}/orders/{order_id} Create JSAPI Payment Order * @api {PUT} /api/v1.0/jsapi_gateway/partners/{partner_code}/orders/{order_id} Create JSAPI Payment Order

@ -6,4 +6,6 @@ public interface HfUpdateService {
String updateStatus(); String updateStatus();
String rpayUpdate();
} }

@ -1,5 +1,6 @@
package au.com.royalpay.payment.manage.dev.core.impl; package au.com.royalpay.payment.manage.dev.core.impl;
import au.com.royalpay.payment.channels.rpay.runtime.RpayApi;
import au.com.royalpay.payment.manage.dev.core.HfUpdateService; import au.com.royalpay.payment.manage.dev.core.HfUpdateService;
import au.com.royalpay.payment.manage.mappers.system.ClientConfigMapper; import au.com.royalpay.payment.manage.mappers.system.ClientConfigMapper;
import au.com.royalpay.payment.manage.mappers.system.ClientMapper; import au.com.royalpay.payment.manage.mappers.system.ClientMapper;
@ -9,6 +10,8 @@ import au.com.royalpay.payment.tools.env.PlatformEnvironment;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@ -23,6 +26,10 @@ public class HfUpdateImpl implements HfUpdateService {
private MpWechatApiProvider mpWechatApiProvider; private MpWechatApiProvider mpWechatApiProvider;
@Resource @Resource
private ClientConfigMapper clientConfigMapper; private ClientConfigMapper clientConfigMapper;
@Resource
private RpayApi rpayApi;
private Logger logger = LoggerFactory.getLogger(getClass());
@Override @Override
public String updateStatus() { public String updateStatus() {
@ -41,4 +48,19 @@ public class HfUpdateImpl implements HfUpdateService {
}); });
return "ok"; return "ok";
} }
@Override
public String rpayUpdate() {
List<JSONObject> clientIds = clientMapper.findByrpayNotNull();
StringBuffer sb = new StringBuffer();
clientIds.forEach(dbResult -> {
try {
rpayApi.modifySurchargeConfig(dbResult);
} catch (Exception e) {
sb.append("【" + dbResult.getString("client_moniker") + "】、");
}
});
logger.info("test for update rpay clearing date,fail + " + sb.toString());
return "ok";
}
} }

@ -17,6 +17,7 @@ import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.Date; import java.util.Date;
@ -76,6 +77,20 @@ public class ManualServiceimpl implements ManualService {
cleanDays = wechatRate.getIntValue("c_clean_days"); cleanDays = wechatRate.getIntValue("c_clean_days");
} }
int finalCleanDays = cleanDays; int finalCleanDays = cleanDays;
modifyClientRates(finalCleanDays,clientRates,client_id,p.getString("client_moniker"));
});
});
logger.info("end doing client postpone");
}
@Transactional
public void modifyClientRates(int finalCleanDays,List<JSONObject> clientRates,int client_id,String client_moniker) {
Date now = new Date();
Date tomorrow = DateUtils.addDays(now, 1);
Date yearTomorrow = DateUtils.addYears(tomorrow, 1);
clientRates.forEach(o -> { clientRates.forEach(o -> {
JSONObject record = clientRateMapper.latestExpiryConfig(client_id, o.getString("rate_name")); JSONObject record = clientRateMapper.latestExpiryConfig(client_id, o.getString("rate_name"));
record.remove("client_rate_id"); record.remove("client_rate_id");
@ -93,10 +108,6 @@ public class ManualServiceimpl implements ManualService {
} }
}); });
clientModifySupport.processClientConfigModify(new SwitchPermissionModify(null, p.getString("client_moniker"), "tax_in_surcharge", false)); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(null, client_moniker, "tax_in_surcharge", false));
});
});
logger.info("end doing client postpone");
} }
} }

@ -4,6 +4,7 @@ import au.com.royalpay.payment.channels.alipay.config.AlipayEnvironment;
import au.com.royalpay.payment.channels.alipay.runtime.AlipayClient; import au.com.royalpay.payment.channels.alipay.runtime.AlipayClient;
import au.com.royalpay.payment.channels.bestpay.runtime.BestPayClient; import au.com.royalpay.payment.channels.bestpay.runtime.BestPayClient;
import au.com.royalpay.payment.channels.jd.runtime.JDClient; import au.com.royalpay.payment.channels.jd.runtime.JDClient;
import au.com.royalpay.payment.channels.rpay.runtime.RpayClient;
import au.com.royalpay.payment.channels.wechat.runtime.WxPayClient; import au.com.royalpay.payment.channels.wechat.runtime.WxPayClient;
import au.com.royalpay.payment.core.PaymentApi; import au.com.royalpay.payment.core.PaymentApi;
import au.com.royalpay.payment.core.exceptions.InvalidShortIdException; import au.com.royalpay.payment.core.exceptions.InvalidShortIdException;
@ -96,6 +97,8 @@ public class TestController implements ApplicationEventPublisherAware {
@Resource @Resource
private JDClient jdClient; private JDClient jdClient;
@Resource @Resource
private RpayClient rpayClient;
@Resource
private TradeLogService tradeLogService; private TradeLogService tradeLogService;
@Resource @Resource
private RetailAppService retailAppService; private RetailAppService retailAppService;
@ -292,6 +295,11 @@ public class TestController implements ApplicationEventPublisherAware {
xmlStr = XmlFormatUtils.formatXml(elem); xmlStr = XmlFormatUtils.formatXml(elem);
res.put("xml", xmlStr); res.put("xml", xmlStr);
break; break;
case "Rpay":
JSONObject orderInfo = rpayClient.queryOrderStatus(orderId);
String rpayjson = JSON.toJSONString(orderInfo, SerializerFeature.PrettyFormat);
res.put("xml", rpayjson);
break;
default: default:
throw new BadRequestException("Not Support channel:" + channel); throw new BadRequestException("Not Support channel:" + channel);
} }
@ -403,4 +411,9 @@ public class TestController implements ApplicationEventPublisherAware {
public String hfClearAmount() { public String hfClearAmount() {
return hfUpdateService.updateStatus(); return hfUpdateService.updateStatus();
} }
@ManagerMapping(value = "/rpayUpdate", method = RequestMethod.PUT, role = ManagerRole.DEVELOPER)
public String rpayUpdateClearing() {
return hfUpdateService.rpayUpdate();
}
} }

@ -102,4 +102,6 @@ public interface ClientMapper {
@AutoSql(type = SqlType.UPDATE) @AutoSql(type = SqlType.UPDATE)
void updateRpayEnterpriseId(@Param("client_id") int clientId, @Param("rpay_enterprise_id") String rpayEnterpriseId); void updateRpayEnterpriseId(@Param("client_id") int clientId, @Param("rpay_enterprise_id") String rpayEnterpriseId);
List<JSONObject> findByrpayNotNull();
} }

@ -23,6 +23,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -340,4 +341,5 @@ public interface ClientManager {
void updateAllPartnerPassword(String clientMoniker, List<String> emails); void updateAllPartnerPassword(String clientMoniker, List<String> emails);
void postponeClientRate(Date now, Date yearTomorrow, String expireDate, JSONObject client);
} }

@ -84,7 +84,6 @@ import au.com.royalpay.payment.manage.support.sms.SmsSender;
import au.com.royalpay.payment.manage.system.core.ClientContractService; import au.com.royalpay.payment.manage.system.core.ClientContractService;
import au.com.royalpay.payment.manage.system.core.MailGunService; import au.com.royalpay.payment.manage.system.core.MailGunService;
import au.com.royalpay.payment.manage.tradelog.beans.TradeLogQuery; import au.com.royalpay.payment.manage.tradelog.beans.TradeLogQuery;
import au.com.royalpay.payment.tools.CommonConsts;
import au.com.royalpay.payment.tools.connections.attachment.core.AttachmentClient; import au.com.royalpay.payment.tools.connections.attachment.core.AttachmentClient;
import au.com.royalpay.payment.tools.connections.mpsupport.MpWechatApi; 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.MpWechatApiProvider;
@ -124,6 +123,7 @@ import com.github.miemiedev.mybatis.paginator.domain.PageList;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
@ -1576,6 +1576,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
} }
@Override @Override
@Transactional
public void newConfigRate(JSONObject manager, String clientMoniker, JSONObject config) { public void newConfigRate(JSONObject manager, String clientMoniker, JSONObject config) {
JSONObject client = getClientInfoByMoniker(clientMoniker); JSONObject client = getClientInfoByMoniker(clientMoniker);
if (client == null) { if (client == null) {
@ -1636,6 +1637,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
} }
@Override @Override
@Transactional
public void modifyRateConfig(JSONObject manager, String clientMoniker, int rateId, ClientRateConfig config) { public void modifyRateConfig(JSONObject manager, String clientMoniker, int rateId, ClientRateConfig config) {
JSONObject client = getClientInfoByMoniker(clientMoniker); JSONObject client = getClientInfoByMoniker(clientMoniker);
if (client == null) { if (client == null) {
@ -3195,12 +3197,14 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
} }
@Override @Override
@Transactional
public void setSkipClearing(JSONObject account, String clientMoniker, Boolean skip_clearing) { public void setSkipClearing(JSONObject account, String clientMoniker, Boolean skip_clearing) {
JSONObject client = getClientInfoByMoniker(clientMoniker); JSONObject client = getClientInfoByMoniker(clientMoniker);
if (client == null) { if (client == null) {
throw new InvalidShortIdException(); throw new InvalidShortIdException();
} }
clientModifySupport.processClientConfigModify(new SwitchPermissionModify(account, clientMoniker, "skip_clearing", skip_clearing)); clientModifySupport.processClientConfigModify(new SwitchPermissionModify(account, clientMoniker, "skip_clearing", skip_clearing));
client.put("skip_clearing", skip_clearing);
rpayApi.switchMerchantSettle(client); rpayApi.switchMerchantSettle(client);
} }
@ -3976,6 +3980,75 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
} }
private void sendClientPostponeNotify(JSONObject account, String newExpireDate) {
JSONObject client = getClientInfo(account.getIntValue("client_id"));
try {
if (StringUtils.isEmpty(account.getString("wechat_openid"))) {
return;
}
MpWechatApi api = mpWechatApiProvider.getApiFromOpenId(account.getString("wechat_openid"));
if (api != null) {
String templateId = api.getTemplateId("client-postpone");
if (templateId != null) {
TemplateMessage notice = initClientMessage(client, newExpireDate, account.getString("wechat_openid"), templateId);
api.sendTemplateMessage(notice);
}
}
} catch (Exception e) {
logger.error("Sending Notify failure", e);
}
}
@Override
@Transactional
public void postponeClientRate(Date now, Date yearTomorrow, String expireDate, JSONObject client) {
int client_id = client.getIntValue("client_id");
List<JSONObject> adminAccounts = clientAccountMapper.listAdminAccounts(client_id);
List<JSONObject> clientRates = clientRateMapper.maxChannelExpiryTime(client_id, null);
JSONObject wechatRate = clientRateMapper.latestChannelCleanDays("Wechat", client.getIntValue("client_id"));
int cleanDays = 1;
if (wechatRate.getInteger("clean_days") != null) {
cleanDays = wechatRate.getIntValue("clean_days");
} else {
cleanDays = wechatRate.getIntValue("c_clean_days");
}
int finalCleanDays = cleanDays;
for (JSONObject o : clientRates) {
JSONObject record = clientRateMapper.latestExpiryConfig(client_id, o.getString("rate_name"));
record.remove("client_rate_id");
record.put("active_time", now);
record.put("manager_id", 0);
record.put("expiry_time", yearTomorrow);
record.put("create_time", now);
record.put("update_time", now);
record.put("clean_days", finalCleanDays);
record.put("manager_name", "System");
record.put("remark", "费率到期系统自动延期1年");
clientRateMapper.saveRate(record);
if ("Rpay".equals(o.getString("rate_name"))) {
rpayApi.modifySurchargeConfig(clientMapper.findClient(client_id));
}
}
clientModifySupport.processClientConfigModify(new SwitchPermissionModify(null, client.getString("client_moniker"), "tax_in_surcharge", false));
adminAccounts.forEach(o -> {
sendClientPostponeNotify(o, expireDate);
});
}
private TemplateMessage initClientMessage(JSONObject client, String newExpiryDate, String wechatOpenid, String templateId) {
TemplateMessage notice = new TemplateMessage(wechatOpenid, templateId, null);
notice.put("first", "您好您的合同费率已到期根据合同协议系统已自动为您延期1年。", "#ff0000");
notice.put("keyword1", client.getString("short_name") + "(" + client.getString("client_moniker") + ")", "#ff0000");
notice.put("keyword2", newExpiryDate, "#0000ff");
notice.put("remark", "如有疑问请联系RoyalPay", "#000000");
return notice;
}
private void sendTestMerchantPassword(List<JSONObject> accounts, List<String> emails) { private void sendTestMerchantPassword(List<JSONObject> accounts, List<String> emails) {
Context ctx = new Context(); Context ctx = new Context();
ctx.setVariable("accounts", accounts); ctx.setVariable("accounts", accounts);

@ -1,13 +1,8 @@
package au.com.royalpay.payment.manage.task; package au.com.royalpay.payment.manage.task;
import au.com.royalpay.payment.channels.rpay.runtime.RpayApi;
import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper;
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.ClientRateMapper;
import au.com.royalpay.payment.manage.mappers.system.ManagerMapper; import au.com.royalpay.payment.manage.mappers.system.ManagerMapper;
import au.com.royalpay.payment.manage.merchants.core.ClientManager; 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.tools.connections.mpsupport.MpWechatApi; 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.MpWechatApiProvider;
import au.com.royalpay.payment.tools.connections.mpsupport.beans.TemplateMessage; import au.com.royalpay.payment.tools.connections.mpsupport.beans.TemplateMessage;
@ -23,12 +18,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -47,17 +39,9 @@ public class PostponeClientTask {
@Resource @Resource
private ClientManager clientManager; private ClientManager clientManager;
@Resource @Resource
private ClientAccountMapper clientAccountMapper;
@Resource
private ManagerMapper managerMapper; private ManagerMapper managerMapper;
@Resource @Resource
private SynchronizedScheduler synchronizedScheduler; private SynchronizedScheduler synchronizedScheduler;
@Resource
private ClientModifySupport clientModifySupport;
@Resource
private RpayApi rpayApi;
@Resource
private ClientMapper clientMapper;
@Scheduled(cron = "0 30 8 * * ?") @Scheduled(cron = "0 30 8 * * ?")
public void postponeClient() { public void postponeClient() {
@ -67,78 +51,25 @@ public class PostponeClientTask {
Date yearTomorrow = DateUtils.addYears(tomorrow, 1); Date yearTomorrow = DateUtils.addYears(tomorrow, 1);
String expireDate = DateFormatUtils.format(yearTomorrow, "yyyy-MM-dd"); String expireDate = DateFormatUtils.format(yearTomorrow, "yyyy-MM-dd");
List<JSONObject> expiryClient = clientRateMapper.getAllExpiry(now); List<JSONObject> expiryClient = clientRateMapper.getAllExpiry(now);
StringBuilder sb = new StringBuilder();
if (CollectionUtils.isEmpty(expiryClient)) { if (CollectionUtils.isEmpty(expiryClient)) {
return; return;
} }
Map<Integer, JSONObject> expiryClients = new HashMap<>(); for (JSONObject client : expiryClient) {
expiryClient.forEach(p -> {
expiryClients.put(p.getInteger("client_id"), p);
});
expiryClients.values().forEach(p -> {
int client_id = p.getIntValue("client_id");
List<JSONObject> adminAccounts = clientAccountMapper.listAdminAccounts(client_id);
List<JSONObject> clientRates = clientRateMapper.maxChannelExpiryTime(client_id, null);
JSONObject wechatRate = clientRateMapper.latestChannelCleanDays("Wechat", p.getIntValue("client_id"));
int cleanDays = 1;
if (wechatRate.getInteger("clean_days") != null) {
cleanDays = wechatRate.getIntValue("clean_days");
} else {
cleanDays = wechatRate.getIntValue("c_clean_days");
}
int finalCleanDays = cleanDays;
clientRates.forEach(o -> {
JSONObject record = clientRateMapper.latestExpiryConfig(client_id, o.getString("rate_name"));
record.remove("client_rate_id");
record.put("active_time", now);
record.put("manager_id", 0);
record.put("expiry_time", yearTomorrow);
record.put("create_time", now);
record.put("update_time", now);
record.put("clean_days", finalCleanDays);
record.put("manager_name", "System");
record.put("remark", "费率到期系统自动延期1年");
clientRateMapper.saveRate(record);
if ("Rpay".equals(o.getString("rate_name"))) {
rpayApi.modifySurchargeConfig(clientMapper.findClient(client_id));
}
});
clientModifySupport.processClientConfigModify(new SwitchPermissionModify(null, p.getString("client_moniker"), "tax_in_surcharge", false));
adminAccounts.forEach(o -> {
sendClientPostponeNotify(o, expireDate);
});
});
sendComplianceNotify(expiryClients, expireDate);
});
}
private void sendClientPostponeNotify(JSONObject account, String newExpireDate) {
JSONObject client = clientManager.getClientInfo(account.getIntValue("client_id"));
try { try {
if (StringUtils.isEmpty(account.getString("wechat_openid"))) { clientManager.postponeClientRate(now, yearTomorrow, expireDate, client);
return; sb.append(client.getString("client_moniker"));
} sb.append("、");
MpWechatApi api = mpWechatApiProvider.getApiFromOpenId(account.getString("wechat_openid")); } catch (Exception ignore) {
if (api != null) { continue;
String templateId = api.getTemplateId("client-postpone");
if (templateId != null) {
TemplateMessage notice = initClientMessage(client, newExpireDate, account.getString("wechat_openid"), templateId);
api.sendTemplateMessage(notice);
}
} }
} catch (Exception e) {
logger.error("Sending Notify failure", e);
} }
sb.deleteCharAt(sb.length() - 1);
sendComplianceNotify(sb, expireDate);
});
} }
private void sendComplianceNotify(Map<Integer, JSONObject> clients, String newExpireDate) { private void sendComplianceNotify(StringBuilder sb, String newExpireDate) {
StringBuffer sb = new StringBuffer();
clients.values().forEach(p -> {
sb.append(p.getString("client_moniker"));
sb.append("、");
});
sb.deleteCharAt(sb.length() - 1);
List<String> compliance = managerMapper.listOpenIdsOfCompliances(); List<String> compliance = managerMapper.listOpenIdsOfCompliances();
compliance.forEach(p -> { compliance.forEach(p -> {
MpWechatApi api = mpWechatApiProvider.getApiFromOpenId(p); MpWechatApi api = mpWechatApiProvider.getApiFromOpenId(p);
@ -147,16 +78,6 @@ public class PostponeClientTask {
}); });
} }
private TemplateMessage initClientMessage(JSONObject client, String newExpiryDate, String wechatOpenid, String templateId) {
TemplateMessage notice = new TemplateMessage(wechatOpenid, templateId, null);
notice.put("first", "您好您的合同费率已到期根据合同协议系统已自动为您延期1年。", "#ff0000");
notice.put("keyword1", client.getString("short_name") + "(" + client.getString("client_moniker") + ")", "#ff0000");
notice.put("keyword2", newExpiryDate, "#0000ff");
notice.put("remark", "如有疑问请联系RoyalPay", "#000000");
return notice;
}
private TemplateMessage initComplianceMessage(String clients, String newExpiryDate, String wechatOpenid, String templateId) { private TemplateMessage initComplianceMessage(String clients, String newExpiryDate, String wechatOpenid, String templateId) {
TemplateMessage notice = new TemplateMessage(wechatOpenid, templateId, null); TemplateMessage notice = new TemplateMessage(wechatOpenid, templateId, null);
notice.put("first", "以下商户据合同费率已经自动延期1年", "#ff0000"); notice.put("first", "以下商户据合同费率已经自动延期1年", "#ff0000");
@ -165,5 +86,4 @@ public class PostponeClientTask {
notice.put("remark", " ", "#000000"); notice.put("remark", " ", "#000000");
return notice; return notice;
} }
} }

@ -365,4 +365,8 @@
<select id="findByhfPayUrlNotNull" resultType="com.alibaba.fastjson.JSONObject"> <select id="findByhfPayUrlNotNull" resultType="com.alibaba.fastjson.JSONObject">
select client_id,client_moniker FROM sys_clients WHERE hf_pay_url != '' select client_id,client_moniker FROM sys_clients WHERE hf_pay_url != ''
</select> </select>
<select id="findByrpayNotNull" resultType="com.alibaba.fastjson.JSONObject">
select * FROM sys_clients WHERE rpay_enterprise_id != ''
</select>
</mapper> </mapper>

@ -113,7 +113,7 @@
sys_client_rates cr sys_client_rates cr
inner join sys_clients c on c.client_id = cr.client_id and c.is_valid = 1 and (c.approve_result = 1 or c.approve_result = 2) inner join sys_clients c on c.client_id = cr.client_id and c.is_valid = 1 and (c.approve_result = 1 or c.approve_result = 2)
GROUP BY GROUP BY
cr.client_id ,cr.rate_name cr.client_id
) a ) a
WHERE WHERE
a.expiry_time < #{expiry_date} a.expiry_time < #{expiry_date}

@ -63,6 +63,10 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
url: '/hfupdate', url: '/hfupdate',
templateUrl: '/static/config/devtools/templates/hfupdate.html', templateUrl: '/static/config/devtools/templates/hfupdate.html',
controller: 'hfupdateCtrl' controller: 'hfupdateCtrl'
}).state('devtools.rpayupdate', {
url: '/rpayupdate',
templateUrl: '/static/config/devtools/templates/rpayupdate.html',
controller: 'rpayupdateCtrl'
}) })
}]); }]);
app.controller('devManualRefundCtrl', ['$scope', '$http', 'commonDialog', function ($scope, $http, commonDialog) { app.controller('devManualRefundCtrl', ['$scope', '$http', 'commonDialog', function ($scope, $http, commonDialog) {
@ -384,6 +388,22 @@ define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
}]); }]);
app.controller('rpayupdateCtrl', ['$scope', '$http','$filter', function ($scope, $http,$filter) {
$scope.selecttotal = true;
$scope.update = function () {
$scope.totalhide = true;
$scope.selecttotal = false;
$http.put('/dev/rpayUpdate').then(function (resp) {
$scope.totalhide = false;
$scope.selecttotal = true;
}, function (resp) {
alert(resp.data.message);
})
}
}]);
return app; return app;
}); });

@ -83,6 +83,10 @@
<i class="fa fa-credit-card-alt"></i> <i class="fa fa-credit-card-alt"></i>
更新HF短连接 更新HF短连接
</a> </a>
<a class="btn btn-app" role="button" ui-sref=".rpayupdate">
<i class="fa fa-credit-card-alt"></i>
更新HF短连接
</a>
</div> </div>
</div> </div>
</section> </section>

@ -0,0 +1,15 @@
<section class="content-header">
<h1>更新Rpay进件费率时间</h1>
<ol class="breadcrumb">
<li>
<i class="fa fa-cog"></i> Basic Config
</li>
<li><a ui-sref="^">Dev Tools</a></li>
<li class="active">rpayupdate</li>
</ol>
</section>
<section class="content">
<div class="box">
<button class="btn btn-primary" ng-click="update()">Update</button> <label ng-hide="selecttotal" style="padding-left: 30px">请稍后</label>
</div>
</section>

@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource; import javax.annotation.Resource;
@SpringBootTest @SpringBootTest
@ActiveProfiles({ "local", "alipay", "wechat", "jd", "bestpay" }) @ActiveProfiles({ "local","rpay", "alipay", "wechat", "jd", "bestpay" })
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
public class PostponeClientTaskTest { public class PostponeClientTaskTest {
@Resource @Resource

Loading…
Cancel
Save