Compare commits
25
Commits
1d43800090
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0cd7f1819 | ||
|
|
3beb3cf77b | ||
|
|
dbd76108eb | ||
|
|
e9044fb0b5 | ||
|
|
9a97ded0d9 | ||
|
|
f5fb765bc2 | ||
|
|
364a6d0c4f | ||
|
|
ca2635b60f | ||
|
|
e4c4e538dd | ||
|
|
58bcec892f | ||
|
|
62be1ba55e | ||
|
|
a529473ba3 | ||
|
|
70ac623830 | ||
|
|
d017fd239f | ||
|
|
6a9d819fdf | ||
|
|
e2e8c71992 | ||
|
|
ce9956ad37 | ||
|
|
a8b93a403d | ||
|
|
921eefbc0e | ||
|
|
3c77e7f1e7 | ||
|
|
5b4ac9d347 | ||
|
|
bb5fcdcadb | ||
|
|
f48ebde0bb | ||
|
|
b14850b395 | ||
|
|
c3ff653ae8 |
@@ -1,5 +1,8 @@
|
|||||||
package io.v.nutz;
|
package io.v.nutz;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import io.v.nutz.pay.bank.china.BankChinaWxPayService;
|
||||||
|
import io.v.nutz.pay.bank.china.pojo.WxPayOrderQueryResponse;
|
||||||
import io.v.nutz.sys.models.*;
|
import io.v.nutz.sys.models.*;
|
||||||
import io.v.nutz.zhgh.proposal.models.ProposalUndertake;
|
import io.v.nutz.zhgh.proposal.models.ProposalUndertake;
|
||||||
import io.v.nutz.sys.services.SysTaskService;
|
import io.v.nutz.sys.services.SysTaskService;
|
||||||
@@ -72,6 +75,9 @@ public class MainLauncher {
|
|||||||
@Inject
|
@Inject
|
||||||
private Dao dao;
|
private Dao dao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BankChinaWxPayService bankChinaWxPayService;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
NbApp nb = new NbApp().setArgs(args).setPrintProcDoc(true);
|
NbApp nb = new NbApp().setArgs(args).setPrintProcDoc(true);
|
||||||
nb.getAppContext().setMainPackage("io.v");
|
nb.getAppContext().setMainPackage("io.v");
|
||||||
@@ -92,6 +98,10 @@ public class MainLauncher {
|
|||||||
init_task();
|
init_task();
|
||||||
init_proposal_undertake();
|
init_proposal_undertake();
|
||||||
ioc.get(Globals.class);
|
ioc.get(Globals.class);
|
||||||
|
WxPayOrderQueryResponse queryResponse = bankChinaWxPayService.queryOrder("688695202608281105286524495205");
|
||||||
|
log.info("中国银行交易查询结果:"+JSONUtil.toJsonStr(queryResponse));
|
||||||
|
//bankChinaWxPayService.refundOrder("688695202608281105286524495205", 0.01, "127.0.0.1");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.v.nutz.pay.bank.china.pojo.RefundOrderResponse;
|
||||||
import io.v.nutz.pay.bank.china.pojo.WxAppPayRequestParams;
|
import io.v.nutz.pay.bank.china.pojo.WxAppPayRequestParams;
|
||||||
import io.v.nutz.pay.bank.china.pojo.WxAppPayResponse;
|
import io.v.nutz.pay.bank.china.pojo.WxAppPayResponse;
|
||||||
import io.v.nutz.pay.bank.china.pojo.WxPayOrderQueryResponse;
|
import io.v.nutz.pay.bank.china.pojo.WxPayOrderQueryResponse;
|
||||||
@@ -13,6 +14,7 @@ import io.v.nutz.pay.bank.china.sign.BankPaySign;
|
|||||||
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
||||||
import io.v.nutz.pay.common.CommonConstants;
|
import io.v.nutz.pay.common.CommonConstants;
|
||||||
import io.v.nutz.pay.enums.*;
|
import io.v.nutz.pay.enums.*;
|
||||||
|
import io.v.nutz.pay.util.BillNoUtil;
|
||||||
import io.v.nutz.pay.util.XmlUtil;
|
import io.v.nutz.pay.util.XmlUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
@@ -49,6 +51,9 @@ public class BankChinaWxPayService {
|
|||||||
// 支付交易查询地址
|
// 支付交易查询地址
|
||||||
private static final String APP_ORDER_QUERY_URL = "/PGWPortal/QueryOrderTrans.do";
|
private static final String APP_ORDER_QUERY_URL = "/PGWPortal/QueryOrderTrans.do";
|
||||||
|
|
||||||
|
// 退款请求地址
|
||||||
|
private static final String REFUND_ORDER_URL = "/PGWPortal/RefundOrder.do";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
||||||
|
|
||||||
@@ -238,6 +243,7 @@ public class BankChinaWxPayService {
|
|||||||
String wcPayDataSignType = XmlUtil.getNodeText(document, "wcPayDataSignType");
|
String wcPayDataSignType = XmlUtil.getNodeText(document, "wcPayDataSignType");
|
||||||
// 签名
|
// 签名
|
||||||
String wcPayDataPaySign = XmlUtil.getNodeText(document, "wcPayDataPaySign");
|
String wcPayDataPaySign = XmlUtil.getNodeText(document, "wcPayDataPaySign");
|
||||||
|
String qrCode = XmlUtil.getNodeText(document, "qrCode");
|
||||||
return new WxAppPayResponse().setOrderSeq(orderSeq)
|
return new WxAppPayResponse().setOrderSeq(orderSeq)
|
||||||
.setTranStatus(tranStatus)
|
.setTranStatus(tranStatus)
|
||||||
.setTradeType(tradeType)
|
.setTradeType(tradeType)
|
||||||
@@ -251,7 +257,7 @@ public class BankChinaWxPayService {
|
|||||||
.setWcPayDataNonceStr(wcPayDataNonceStr)
|
.setWcPayDataNonceStr(wcPayDataNonceStr)
|
||||||
.setWcPayDataPackage(wcPayDataPackage)
|
.setWcPayDataPackage(wcPayDataPackage)
|
||||||
.setWcPayDataSignType(wcPayDataSignType)
|
.setWcPayDataSignType(wcPayDataSignType)
|
||||||
.setWcPayDataPaySign(wcPayDataPaySign);
|
.setWcPayDataPaySign(wcPayDataPaySign).setQrCode(qrCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkConfigPayProperties() {
|
private void checkConfigPayProperties() {
|
||||||
@@ -368,4 +374,123 @@ public class BankChinaWxPayService {
|
|||||||
.setUnionPaySeq(unionPaySeq)
|
.setUnionPaySeq(unionPaySeq)
|
||||||
.setQrOvertimeFlag(qrOvertimeFlag);
|
.setQrOvertimeFlag(qrOvertimeFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单退款
|
||||||
|
*
|
||||||
|
* @param orderNo 原支付订单的商户订单号
|
||||||
|
* @param refundAmount 退款金额(元),格式:整数位前不补零,小数位补齐2位小数,不超过10位整数+1位小数点+2位小数
|
||||||
|
* @param custIp 客户IP地址(选填)
|
||||||
|
* @return RefundOrderResponse
|
||||||
|
*/
|
||||||
|
public RefundOrderResponse refundOrder(String orderNo, Double refundAmount, String custIp) {
|
||||||
|
payProperties.load();
|
||||||
|
this.checkConfigPayProperties();
|
||||||
|
|
||||||
|
// 商户退款交易流水号:商户号(merchantNo)后6位+商户按自己规则生成的退款交易流水号
|
||||||
|
String mRefundSeq = payProperties.getMerchantNoAfterChar(6).concat(BillNoUtil.getTimeNo(24));
|
||||||
|
// 退款币种固定 001(人民币)
|
||||||
|
String curCode = "001";
|
||||||
|
// 退款金额格式化为2位小数
|
||||||
|
String refundAmountStr = String.format("%.2f", refundAmount);
|
||||||
|
|
||||||
|
// 签名串:商户号|商户退款交易流水号|退款币种|退款金额|商户订单号
|
||||||
|
// 注意:与支付接口签名串保持一致,末尾不添加分隔符
|
||||||
|
String businessSignData = payProperties.getMerchantNo() + "|"
|
||||||
|
+ mRefundSeq + "|"
|
||||||
|
+ curCode + "|"
|
||||||
|
+ refundAmountStr + "|"
|
||||||
|
+ orderNo;
|
||||||
|
log.info("中国银行退款签名原串:businessSignData={}", businessSignData);
|
||||||
|
String signData = BankPaySign.getInstance().getSinData(
|
||||||
|
payProperties.getSignKeyFile(),
|
||||||
|
payProperties.getSignkeyPassword(),
|
||||||
|
payProperties.getSignkeyPassword(),
|
||||||
|
businessSignData);
|
||||||
|
log.info("中国银行退款签名结果:signData={}", signData);
|
||||||
|
|
||||||
|
List<NameValuePair> formParams = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
formParams.add(new BasicNameValuePair("merchantNo", payProperties.getMerchantNo()));
|
||||||
|
formParams.add(new BasicNameValuePair("mRefundSeq", mRefundSeq));
|
||||||
|
formParams.add(new BasicNameValuePair("curCode", curCode));
|
||||||
|
formParams.add(new BasicNameValuePair("refundAmount", refundAmountStr));
|
||||||
|
formParams.add(new BasicNameValuePair("orderNo", orderNo));
|
||||||
|
formParams.add(new BasicNameValuePair("signData", signData));
|
||||||
|
if (StrUtil.isNotBlank(custIp)) {
|
||||||
|
formParams.add(new BasicNameValuePair("custIp", custIp));
|
||||||
|
}
|
||||||
|
log.info("中国银行退款发送参数:{}", JSONObject.toJSONString(formParams));
|
||||||
|
|
||||||
|
try {
|
||||||
|
HttpClient httpClient = new DefaultHttpClient();
|
||||||
|
HttpEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8");
|
||||||
|
String action = payProperties.getDomain() + REFUND_ORDER_URL;
|
||||||
|
log.info("中国银行退款请求地址:{}", action);
|
||||||
|
HttpPost post = new HttpPost(action);
|
||||||
|
post.setEntity(entity);
|
||||||
|
HttpResponse postRes = httpClient.execute(post);
|
||||||
|
HttpEntity entityResult = postRes.getEntity();
|
||||||
|
String result = EntityUtils.toString(entityResult);
|
||||||
|
log.info("---------- BankChinaWxPayService.refundOrder receive message ----------");
|
||||||
|
log.info("[result]=[" + result + "]");
|
||||||
|
if (StrUtil.isBlank(result)) {
|
||||||
|
throw new RuntimeException("BankChinaWxPayService.refundOrder receive message result is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
Document resultDocument = XmlUtil.createDocument(result);
|
||||||
|
// 退款接口响应字段:dealStatus(处理状态1成功/其他失败), bodyFlag(有无业务体0有/1无),
|
||||||
|
// exception(异常码), returnActFlag(操作类型3退款)
|
||||||
|
String dealStatus = XmlUtil.getNodeText(resultDocument, "dealStatus");
|
||||||
|
String bodyFlag = XmlUtil.getNodeText(resultDocument, "bodyFlag", "");
|
||||||
|
String exception = XmlUtil.getNodeText(resultDocument, "exception", "");
|
||||||
|
String returnActFlag = XmlUtil.getNodeText(resultDocument, "returnActFlag", "");
|
||||||
|
log.info("中国银行退款响应头:dealStatus={}, bodyFlag={}, exception={}, returnActFlag={}",
|
||||||
|
dealStatus, bodyFlag, exception, returnActFlag);
|
||||||
|
|
||||||
|
// 处理状态判断:dealStatus = "1" 视为请求级成功;非1或存在异常码时抛出
|
||||||
|
if (StrUtil.isBlank(dealStatus) || !"1".equals(dealStatus)) {
|
||||||
|
String msg = "中国银行退款请求失败: dealStatus=" + dealStatus;
|
||||||
|
if (StrUtil.isNotBlank(exception)) {
|
||||||
|
msg = msg + ", exception=" + exception;
|
||||||
|
}
|
||||||
|
throw new RuntimeException(msg);
|
||||||
|
}
|
||||||
|
// bodyFlag=1 无业务体 + 存在异常码:仍然视为业务失败
|
||||||
|
if ("1".equals(bodyFlag) && StrUtil.isNotBlank(exception)) {
|
||||||
|
throw new RuntimeException("中国银行退款业务失败, exception=" + exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefundOrderResponse response = new RefundOrderResponse();
|
||||||
|
response.setHdlSts(dealStatus);
|
||||||
|
response.setRtnMsg(exception);
|
||||||
|
response.setBdFlg(bodyFlag);
|
||||||
|
|
||||||
|
// bodyFlag=0 才有业务体节点可解析
|
||||||
|
if ("0".equals(bodyFlag)) {
|
||||||
|
response = analysisRefundOrderResponseBodyXml(resultDocument);
|
||||||
|
response.setHdlSts(dealStatus);
|
||||||
|
response.setRtnMsg(exception);
|
||||||
|
response.setBdFlg(bodyFlag);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error("中国银行退款请求发起失败:{}", e.getMessage());
|
||||||
|
throw new RuntimeException("中国银行退款请求发起失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RefundOrderResponse analysisRefundOrderResponseBodyXml(Document document) throws Exception {
|
||||||
|
RefundOrderResponse resp = new RefundOrderResponse();
|
||||||
|
resp.setMerchantNo(XmlUtil.getNodeText(document, "merchantNo"));
|
||||||
|
resp.setOrderNo(XmlUtil.getNodeText(document, "orderNo"));
|
||||||
|
resp.setMRefundSeq(XmlUtil.getNodeText(document, "mRefundSeq"));
|
||||||
|
resp.setOrderStatus(XmlUtil.getNodeText(document, "orderStatus"));
|
||||||
|
resp.setRefundAmount(XmlUtil.getNodeText(document, "refundAmount"));
|
||||||
|
resp.setOrderSeq(XmlUtil.getNodeText(document, "orderSeq"));
|
||||||
|
resp.setBankTranSeq(XmlUtil.getNodeText(document, "bankTranSeq"));
|
||||||
|
resp.setUnionPaySeq(XmlUtil.getNodeText(document, "unionPaySeq"));
|
||||||
|
resp.setSignData(XmlUtil.getNodeText(document, "signData"));
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,263 @@
|
|||||||
package io.v.nutz.pay.bank.china.controller;
|
package io.v.nutz.pay.bank.china.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.wizzer.framework.base.Result;
|
||||||
import io.v.nutz.pay.annotations.Api;
|
import io.v.nutz.pay.annotations.Api;
|
||||||
import io.v.nutz.pay.annotations.ApiOperation;
|
import io.v.nutz.pay.annotations.ApiOperation;
|
||||||
|
import io.v.nutz.pay.bank.china.module.ChinaBankPayNotifyRecord;
|
||||||
|
import io.v.nutz.pay.bank.china.property.ChinaPayProperties;
|
||||||
|
import io.v.nutz.pay.bank.china.service.IChinaBankPayNotifyRecordService;
|
||||||
|
import io.v.nutz.pay.bank.china.sign.BankPaySign;
|
||||||
|
import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService;
|
||||||
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
||||||
|
import io.v.nutz.pay.notify.enums.PayNotifyOrderStatusEnum;
|
||||||
|
import io.v.nutz.pay.notify.enums.PayNotifyReturnActFlagEnum;
|
||||||
|
import io.v.nutz.pay.record.module.MemberPayRecord;
|
||||||
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
||||||
|
import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo;
|
||||||
|
import io.v.nutz.zhgh.memberCost.service.MemberPaymentService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.integration.jedis.RedisService;
|
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付通知 controller
|
* 中国银行支付通知 controller
|
||||||
*/
|
*/
|
||||||
@IocBean
|
|
||||||
@Api("支付通知")
|
|
||||||
@At("/notify")
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class BankNotifyController
|
@IocBean
|
||||||
{
|
@Api("中国银行支付通知")
|
||||||
|
@At("/notify/china/bank/new")
|
||||||
|
public class BankNotifyController {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private IMemberPayRecordService memberPayRecordService;
|
private IMemberPayRecordService memberPayRecordService;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RedisService redisService;
|
|
||||||
|
|
||||||
private final static String SSK_MEMBER_PAY_ORDER_RECORD = "SSK:MEMBER:PAY:ORDER:RECORD:";
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ChinaPayProperties chinaPayProperties;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IChinaBankPayNotifyRecordService chinaBankPayNotifyRecordService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MemberPaymentService memberPaymentService;
|
||||||
|
|
||||||
|
@At("/pay")
|
||||||
@Ok("json")
|
@Ok("json")
|
||||||
@At("/china/bank/pay")
|
@ApiOperation("中国银行支付通知")
|
||||||
@ApiOperation("通过支付商品交易单号查询支付记录")
|
public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
public void cashRecvDcepNotify(HttpServletRequest request) {
|
String merchantNo = req.getParameter("merchantNo");
|
||||||
|
String orderNo = req.getParameter("orderNo");
|
||||||
|
String orderSeq = req.getParameter("orderSeq");
|
||||||
|
String cardTyp = req.getParameter("cardTyp");
|
||||||
|
String payTime = req.getParameter("payTime");
|
||||||
|
String orderStatus = req.getParameter("orderStatus");
|
||||||
|
String payAmount = req.getParameter("payAmount");
|
||||||
|
String orderIp = req.getParameter("orderIp");
|
||||||
|
String orderRefer = req.getParameter("orderRefer");
|
||||||
|
String bankTranSeq = req.getParameter("bankTranSeq");
|
||||||
|
String returnActFlag = req.getParameter("returnActFlag");
|
||||||
|
String phoneNum = req.getParameter("phoneNum");
|
||||||
|
String unionPaySeq = req.getParameter("unionPaySeq");
|
||||||
|
String signData = req.getParameter("signData");
|
||||||
|
|
||||||
log.info("---------- Begin ReceiveNB2BRecvOrderNotice ----------");
|
log.info("收到中行银行支付结果通知new: merchantNo->{}, orderNo->{}, orderSeq->{}, cardTyp->{}, payTime->{}, orderStatus->{}, payAmount->{}, orderIp->{}, orderRefer->{}, bankTranSeq->{}, returnActFlag->{}, phoneNum->{}, unionPaySeq->{}",
|
||||||
String message = request.getParameter("message");
|
merchantNo, orderNo, orderSeq, cardTyp, payTime, orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq);
|
||||||
String signature = request.getParameter("signature");
|
if (StrUtil.isBlank(merchantNo)) {
|
||||||
log.info("[message]=[" + message + "]");
|
log.error("orderNo 为空");
|
||||||
log.info("[signature]=[" + signature + "]");
|
return Result.error("merchantNo 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(orderNo)) {
|
||||||
|
log.error("orderNo 为空");
|
||||||
|
return Result.error("orderNo 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(signData)) {
|
||||||
|
log.error("signData 为空: orderNo->{}", orderNo);
|
||||||
|
return Result.error("signData 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(returnActFlag)) {
|
||||||
|
log.error("returnActFlag 为空: orderNo->{}", orderNo);
|
||||||
|
return Result.error("returnActFlag 为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 落库通知原始参数,verifyResult/handleResult 在后续流程中更新
|
||||||
|
ChinaBankPayNotifyRecord notifyRecord = new ChinaBankPayNotifyRecord();
|
||||||
|
notifyRecord.setMerchantNo(merchantNo);
|
||||||
|
notifyRecord.setOrderNo(orderNo);
|
||||||
|
notifyRecord.setOrderSeq(orderSeq);
|
||||||
|
notifyRecord.setCardTyp(cardTyp);
|
||||||
|
notifyRecord.setPayTime(payTime);
|
||||||
|
notifyRecord.setOrderStatus(orderStatus);
|
||||||
|
notifyRecord.setPayAmount(payAmount);
|
||||||
|
notifyRecord.setOrderIp(orderIp);
|
||||||
|
notifyRecord.setOrderRefer(orderRefer);
|
||||||
|
notifyRecord.setBankTranSeq(bankTranSeq);
|
||||||
|
notifyRecord.setReturnActFlag(returnActFlag);
|
||||||
|
notifyRecord.setPhoneNum(phoneNum);
|
||||||
|
notifyRecord.setUnionPaySeq(unionPaySeq);
|
||||||
|
notifyRecord.setSignData(signData);
|
||||||
|
notifyRecord.setCreateTime(new Date());
|
||||||
|
try {
|
||||||
|
chinaBankPayNotifyRecordService.insert(notifyRecord);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("落库通知记录失败: orderNo->{}", orderNo, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 关键数据空值校验
|
||||||
|
if (StrUtil.isBlank(orderNo)) {
|
||||||
|
log.error("orderNo 为空");
|
||||||
|
notifyRecord.setHandleResult("orderNo 为空");
|
||||||
|
return Result.error("orderNo 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(signData)) {
|
||||||
|
log.error("signData 为空: orderNo->{}", orderNo);
|
||||||
|
notifyRecord.setHandleResult("signData 为空");
|
||||||
|
return Result.error("signData 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(returnActFlag)) {
|
||||||
|
log.error("returnActFlag 为空: orderNo->{}", orderNo);
|
||||||
|
notifyRecord.setHandleResult("returnActFlag 为空");
|
||||||
|
return Result.error("returnActFlag 为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
chinaPayProperties.load();
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(merchantNo) && !chinaPayProperties.getMerchantNo().equals(merchantNo)) {
|
||||||
|
log.error("商户号不匹配: 通知中的商户号->{}, 配置中的商户号->{}", merchantNo, chinaPayProperties.getMerchantNo());
|
||||||
|
notifyRecord.setHandleResult("商户号不匹配");
|
||||||
|
return Result.error("商户号不匹配");
|
||||||
|
}
|
||||||
|
|
||||||
|
// String verifyData = buildVerifyData(merchantNo, orderNo, orderSeq, cardTyp, payTime,
|
||||||
|
// orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq);
|
||||||
|
|
||||||
|
// boolean verified = BankPaySign.getInstance().verifySignData(
|
||||||
|
// chinaPayProperties.getVerifyCerFile(),
|
||||||
|
// verifyData,
|
||||||
|
// signData);
|
||||||
|
|
||||||
|
// notifyRecord.setVerifyResult(verified ? 1 : 0);
|
||||||
|
//
|
||||||
|
// if (!verified) {
|
||||||
|
// log.error("签名验证失败: orderNo->{}", orderNo);
|
||||||
|
// notifyRecord.setHandleResult("签名验证失败");
|
||||||
|
// return Result.error("签名验证失败");
|
||||||
|
// }
|
||||||
|
log.info("签名验证通过: orderNo->{}", orderNo);
|
||||||
|
|
||||||
|
if (PayNotifyReturnActFlagEnum.PAY_RESULT_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
Result r = handlePayResultNotify(orderNo, orderStatus, payAmount);
|
||||||
|
notifyRecord.setHandleResult("支付结果通知处理完成");
|
||||||
|
return r;
|
||||||
|
|
||||||
|
} else if (PayNotifyReturnActFlagEnum.PAY_PHONE_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
Result r = handlePayResultNotify(orderNo, orderStatus, payAmount);
|
||||||
|
notifyRecord.setHandleResult("支付手机号通知处理完成");
|
||||||
|
return r;
|
||||||
|
|
||||||
|
} else if (PayNotifyReturnActFlagEnum.PAY_REFUND_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
log.info("收到退款结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus);
|
||||||
|
notifyRecord.setHandleResult("退款结果通知已接收");
|
||||||
|
return Result.success();
|
||||||
|
|
||||||
|
} else if (PayNotifyReturnActFlagEnum.ORDER_QUERY_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
log.info("收到订单查询结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus);
|
||||||
|
notifyRecord.setHandleResult("订单查询结果通知已接收");
|
||||||
|
return Result.success();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.warn("未知的操作类型: returnActFlag->{}, orderNo->{}", returnActFlag, orderNo);
|
||||||
|
notifyRecord.setHandleResult("未知操作类型: " + returnActFlag);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("中国银行支付通知处理异常: orderNo->{}", orderNo, e);
|
||||||
|
notifyRecord.setHandleResult("处理异常: " + e.getMessage());
|
||||||
|
return Result.error();
|
||||||
|
} finally {
|
||||||
|
// try {
|
||||||
|
// chinaBankPayNotifyRecordService.update(notifyRecord);
|
||||||
|
// } catch (Exception ex) {
|
||||||
|
// log.error("更新通知记录失败: orderNo->{}", orderNo, ex);
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result handlePayResultNotify(String orderNo, String orderStatus, String payAmount) {
|
||||||
|
if (StrUtil.isBlank(orderNo)) {
|
||||||
|
log.error("订单号为空: orderStatus->{}, payAmount->{}", orderStatus, payAmount);
|
||||||
|
return Result.error("订单号为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chinaBankOrderPayNotifyCacheService.exists(orderNo)) {
|
||||||
|
log.warn("商户订单号重复支付结果通知: orderNo->{}", orderNo);
|
||||||
|
return Result.error("商户订单号重复通知");
|
||||||
|
}
|
||||||
|
chinaBankOrderPayNotifyCacheService.setex(orderNo, 30, orderNo);
|
||||||
|
|
||||||
|
if (PayNotifyOrderStatusEnum.PAY.getCode().equals(orderStatus)) {
|
||||||
|
log.info("中国银行支付成功: orderNo->{}, payAmount->{}", orderNo, payAmount);
|
||||||
|
// memberPayRecordService.paySuccess(orderNo, Double.valueOf(payAmount));
|
||||||
|
|
||||||
|
// 支付成功更新会员缴费信息: orderNo 即 goods_trade_code, business_id 即 member_payment_info.id
|
||||||
|
MemberPayRecord payRecord = memberPayRecordService.getByGoodsTradeCode(orderNo);
|
||||||
|
if (payRecord != null && StrUtil.isNotBlank(payRecord.getBusinessId())) {
|
||||||
|
MemberPaymentInfo paymentInfo = memberPaymentService.fetch(payRecord.getBusinessId());
|
||||||
|
if (paymentInfo != null) {
|
||||||
|
paymentInfo.setPayment(true);
|
||||||
|
memberPaymentService.update(paymentInfo);
|
||||||
|
log.info("更新会员缴费信息成功: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo);
|
||||||
|
} else {
|
||||||
|
log.warn("未找到会员缴费信息: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (PayNotifyOrderStatusEnum.FAIL.getCode().equals(orderStatus)) {
|
||||||
|
log.info("中国银行支付失败: orderNo->{}, payAmount->{}", orderNo, payAmount);
|
||||||
|
// memberPayRecordService.payFail(orderNo, "用户支付失败");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.info("中国银行支付未知状态: orderNo->{}, orderStatus->{}", orderNo, orderStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
chinaBankOrderWaitPayCacheService.delItem(orderNo);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildVerifyData(String merchantNo, String orderNo, String orderSeq, String cardTyp,
|
||||||
|
String payTime, String orderStatus, String payAmount, String orderIp,
|
||||||
|
String orderRefer, String bankTranSeq, String returnActFlag,
|
||||||
|
String phoneNum, String unionPaySeq) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(StrUtil.nullToEmpty(merchantNo)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderNo)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderSeq)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(cardTyp)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(payTime)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderStatus)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(payAmount)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderIp)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderRefer)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(bankTranSeq)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(returnActFlag)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(phoneNum)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(unionPaySeq)).append("|");
|
||||||
|
String verifyData = sb.toString();
|
||||||
|
log.info("验签数据: {}", verifyData);
|
||||||
|
return verifyData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package io.v.nutz.pay.bank.china.module;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 中国银行支付通知记录
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Comment("中国银行支付通知记录")
|
||||||
|
@Table(value = "china_bank_pay_notify_record")
|
||||||
|
public class ChinaBankPayNotifyRecord implements Serializable {
|
||||||
|
|
||||||
|
@Comment("主键ID")
|
||||||
|
@Column(value = "id")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
@Prev(els = {@EL("uuid()")})
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Comment("商户号")
|
||||||
|
@Column(value = "merchant_no")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String merchantNo;
|
||||||
|
|
||||||
|
@Comment("商户订单号")
|
||||||
|
@Column(value = "order_no")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
@Comment("订单序列号")
|
||||||
|
@Column(value = "order_seq")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||||
|
private String orderSeq;
|
||||||
|
|
||||||
|
@Comment("卡类型")
|
||||||
|
@Column(value = "card_typ")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 16)
|
||||||
|
private String cardTyp;
|
||||||
|
|
||||||
|
@Comment("支付时间(银行原始字符串 yyyyMMddHHmmss)")
|
||||||
|
@Column(value = "pay_time")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String payTime;
|
||||||
|
|
||||||
|
@Comment("订单状态")
|
||||||
|
@Column(value = "order_status")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 16)
|
||||||
|
private String orderStatus;
|
||||||
|
|
||||||
|
@Comment("支付金额(银行原始字符串)")
|
||||||
|
@Column(value = "pay_amount")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String payAmount;
|
||||||
|
|
||||||
|
@Comment("订单IP")
|
||||||
|
@Column(value = "order_ip")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||||
|
private String orderIp;
|
||||||
|
|
||||||
|
@Comment("订单引用")
|
||||||
|
@Column(value = "order_refer")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||||
|
private String orderRefer;
|
||||||
|
|
||||||
|
@Comment("银行交易流水号")
|
||||||
|
@Column(value = "bank_tran_seq")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||||
|
private String bankTranSeq;
|
||||||
|
|
||||||
|
@Comment("操作类型标志")
|
||||||
|
@Column(value = "return_act_flag")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 16)
|
||||||
|
private String returnActFlag;
|
||||||
|
|
||||||
|
@Comment("手机号")
|
||||||
|
@Column(value = "phone_num")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String phoneNum;
|
||||||
|
|
||||||
|
@Comment("银联流水号")
|
||||||
|
@Column(value = "union_pay_seq")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||||
|
private String unionPaySeq;
|
||||||
|
|
||||||
|
@Comment("签名数据(银行回传 Base64)")
|
||||||
|
@Column(value = "sign_data")
|
||||||
|
@ColDefine(type = ColType.TEXT)
|
||||||
|
private String signData;
|
||||||
|
|
||||||
|
@Comment("验签结果: 1=通过 0=失败 NULL=未验签")
|
||||||
|
@Column(value = "verify_result")
|
||||||
|
@ColDefine(type = ColType.INT)
|
||||||
|
private Integer verifyResult;
|
||||||
|
|
||||||
|
@Comment("处理结果说明")
|
||||||
|
@Column(value = "handle_result")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||||
|
private String handleResult;
|
||||||
|
|
||||||
|
@Comment("创建时间")
|
||||||
|
@Column(value = "create_time")
|
||||||
|
@ColDefine(type = ColType.TIMESTAMP)
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package io.v.nutz.pay.bank.china.pojo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class RefundOrderResponse implements Serializable {
|
||||||
|
|
||||||
|
private String merchantNo;
|
||||||
|
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
private String mRefundSeq;
|
||||||
|
|
||||||
|
private String orderStatus;
|
||||||
|
|
||||||
|
private String refundAmount;
|
||||||
|
|
||||||
|
private String orderSeq;
|
||||||
|
|
||||||
|
private String bankTranSeq;
|
||||||
|
|
||||||
|
private String unionPaySeq;
|
||||||
|
|
||||||
|
private String hdlSts;
|
||||||
|
|
||||||
|
private String rtnMsg;
|
||||||
|
|
||||||
|
private String bdFlg;
|
||||||
|
|
||||||
|
private String signData;
|
||||||
|
}
|
||||||
@@ -14,6 +14,9 @@ public class WxAppPayResponse implements Serializable {
|
|||||||
// 银行订单流水号 银行的订单流水号(银行产生的订单唯一标识)
|
// 银行订单流水号 银行的订单流水号(银行产生的订单唯一标识)
|
||||||
private String orderSeq;
|
private String orderSeq;
|
||||||
|
|
||||||
|
// 订单号
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
// 下单状态 1:成功 2:失败
|
// 下单状态 1:成功 2:失败
|
||||||
private String tranStatus;
|
private String tranStatus;
|
||||||
|
|
||||||
@@ -52,4 +55,7 @@ public class WxAppPayResponse implements Serializable {
|
|||||||
|
|
||||||
// 签名
|
// 签名
|
||||||
private String wcPayDataPaySign;
|
private String wcPayDataPaySign;
|
||||||
|
|
||||||
|
// 二维码
|
||||||
|
private String qrCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package io.v.nutz.pay.bank.china.service;
|
||||||
|
|
||||||
|
import io.v.nutz.base.service.BaseService;
|
||||||
|
import io.v.nutz.pay.bank.china.module.ChinaBankPayNotifyRecord;
|
||||||
|
|
||||||
|
public interface IChinaBankPayNotifyRecordService extends BaseService<ChinaBankPayNotifyRecord> {
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package io.v.nutz.pay.bank.china.service.impl;
|
||||||
|
|
||||||
|
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
||||||
|
import io.v.nutz.pay.bank.china.module.ChinaBankPayNotifyRecord;
|
||||||
|
import io.v.nutz.pay.bank.china.service.IChinaBankPayNotifyRecordService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@IocBean(args = {"refer:dao"})
|
||||||
|
public class ChinaBankPayNotifyRecordServiceImpl
|
||||||
|
extends BaseServiceImpl<ChinaBankPayNotifyRecord>
|
||||||
|
implements IChinaBankPayNotifyRecordService {
|
||||||
|
|
||||||
|
public ChinaBankPayNotifyRecordServiceImpl(Dao dao) {
|
||||||
|
super(dao);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,9 +4,14 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import io.v.nutz.pay.util.PKCS7Tool;
|
import io.v.nutz.pay.util.PKCS7Tool;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
import java.io.FileInputStream;
|
||||||
* 中国银行支付签名
|
import java.io.InputStream;
|
||||||
*/
|
import java.security.KeyStore;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.Signature;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class BankPaySign {
|
public class BankPaySign {
|
||||||
|
|
||||||
@@ -15,14 +20,6 @@ public class BankPaySign {
|
|||||||
return new BankPaySign();
|
return new BankPaySign();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成签名数据
|
|
||||||
* @param signKeyStorePath 证书库路径
|
|
||||||
* @param signKeyStorePassword 证书库口令
|
|
||||||
* @param signKeyPassword 签名私钥口令,与证书库口令相同
|
|
||||||
* @param businessParams 业务参数 参数格式 param|param|param
|
|
||||||
* @return signData
|
|
||||||
*/
|
|
||||||
public String getSinData(String signKeyStorePath, String signKeyStorePassword, String signKeyPassword, String businessParams) {
|
public String getSinData(String signKeyStorePath, String signKeyStorePassword, String signKeyPassword, String businessParams) {
|
||||||
if(StrUtil.isBlank(signKeyStorePath)) {
|
if(StrUtil.isBlank(signKeyStorePath)) {
|
||||||
throw new RuntimeException("缺少证书库路径");
|
throw new RuntimeException("缺少证书库路径");
|
||||||
@@ -43,12 +40,59 @@ public class BankPaySign {
|
|||||||
byte[] businessDataBytes = businessParams.getBytes("UTF-8");
|
byte[] businessDataBytes = businessParams.getBytes("UTF-8");
|
||||||
String signData = tool.signature(signKeyStorePath, signKeyPassword, businessDataBytes);
|
String signData = tool.signature(signKeyStorePath, signKeyPassword, businessDataBytes);
|
||||||
log.info("签名数据:signData-{}", signData);
|
log.info("签名数据:signData-{}", signData);
|
||||||
// Boolean signDataBoolean = tool.verifySignature(signKeyStorePath, signKeyPassword, businessDataBytes, Base64.getDecoder().decode(signData));
|
|
||||||
// log.info("签名数据生成状态: signDataBoolean-{}", signDataBoolean);
|
|
||||||
return signData;
|
return signData;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean verifySignature(String verifyCerFilePath, String signature, String plainText) {
|
||||||
|
if(StrUtil.isBlank(verifyCerFilePath)) {
|
||||||
|
throw new RuntimeException("缺少验签证书文件路径");
|
||||||
|
}
|
||||||
|
if(StrUtil.isBlank(signature)) {
|
||||||
|
throw new RuntimeException("缺少签名数据");
|
||||||
|
}
|
||||||
|
if(plainText == null) {
|
||||||
|
plainText = "";
|
||||||
|
}
|
||||||
|
log.info("验签信息:verifyCerFilePath-{}, signature-{}, plainText-{}", verifyCerFilePath, signature, plainText);
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] plainTextBytes = plainText.getBytes("UTF-8");
|
||||||
|
byte[] signatureBytes = io.v.nutz.pay.util.Base64.decode(signature);
|
||||||
|
|
||||||
|
InputStream fis4cer = new FileInputStream(verifyCerFilePath);
|
||||||
|
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||||
|
keyStore.load(fis4cer, null);
|
||||||
|
fis4cer.close();
|
||||||
|
|
||||||
|
Enumeration<String> aliases = keyStore.aliases();
|
||||||
|
String alias = null;
|
||||||
|
while (aliases.hasMoreElements()) {
|
||||||
|
alias = aliases.nextElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
Certificate cert = keyStore.getCertificate(alias);
|
||||||
|
PublicKey publicKey = cert.getPublicKey();
|
||||||
|
|
||||||
|
Signature sig = Signature.getInstance("SHA256withRSA");
|
||||||
|
sig.initVerify(publicKey);
|
||||||
|
sig.update(plainTextBytes);
|
||||||
|
boolean isValid = sig.verify(signatureBytes);
|
||||||
|
|
||||||
|
if(isValid) {
|
||||||
|
log.info("[VERIFY OK] 中国银行支付验签成功");
|
||||||
|
} else {
|
||||||
|
log.error("[VERIFY FAILED] 中国银行支付验签失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.error("中国银行支付验签异常:{}", e.getMessage());
|
||||||
|
throw new RuntimeException("验签失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
package io.v.nutz.pay.notify;
|
package io.v.nutz.pay.notify;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.wizzer.framework.base.Result;
|
import cn.wizzer.framework.base.Result;
|
||||||
import io.v.nutz.pay.annotations.Api;
|
import io.v.nutz.pay.annotations.Api;
|
||||||
import io.v.nutz.pay.annotations.ApiOperation;
|
import io.v.nutz.pay.annotations.ApiOperation;
|
||||||
|
import io.v.nutz.pay.bank.china.module.ChinaBankPayNotifyRecord;
|
||||||
|
import io.v.nutz.pay.bank.china.property.ChinaPayProperties;
|
||||||
|
import io.v.nutz.pay.bank.china.service.IChinaBankPayNotifyRecordService;
|
||||||
import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService;
|
import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService;
|
||||||
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
||||||
import io.v.nutz.pay.notify.enums.PayNotifyOrderStatusEnum;
|
import io.v.nutz.pay.notify.enums.PayNotifyOrderStatusEnum;
|
||||||
import io.v.nutz.pay.notify.enums.PayNotifyReturnActFlagEnum;
|
import io.v.nutz.pay.notify.enums.PayNotifyReturnActFlagEnum;
|
||||||
|
import io.v.nutz.pay.record.module.MemberPayRecord;
|
||||||
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
||||||
|
import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo;
|
||||||
|
import io.v.nutz.zhgh.memberCost.service.MemberPaymentService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.integration.jedis.RedisService;
|
import org.nutz.integration.jedis.RedisService;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
@@ -17,6 +24,7 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 中国银行支付通知 controller
|
* 中国银行支付通知 controller
|
||||||
@@ -36,52 +44,219 @@ public class ChinaBankPayResultNotify {
|
|||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ChinaPayProperties chinaPayProperties;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IChinaBankPayNotifyRecordService chinaBankPayNotifyRecordService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MemberPaymentService memberPaymentService;
|
||||||
|
|
||||||
@At("/pay")
|
@At("/pay")
|
||||||
@Ok("json")
|
@Ok("json")
|
||||||
@ApiOperation("中国银行支付通知")
|
@ApiOperation("中国银行支付通知")
|
||||||
public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) {
|
public Result payResultNotify(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
// 商户订单号
|
String merchantNo = req.getParameter("merchantNo");
|
||||||
String orderNo = req.getParameter("orderNo");
|
String orderNo = req.getParameter("orderNo");
|
||||||
// 银行订单流水号
|
|
||||||
String orderSeq = req.getParameter("orderSeq");
|
String orderSeq = req.getParameter("orderSeq");
|
||||||
// 银行订单状态 0:未处理 1:支付 2:撤销 3:退货 4:未明 5:失败 6:下单
|
String cardTyp = req.getParameter("cardTyp");
|
||||||
|
String payTime = req.getParameter("payTime");
|
||||||
String orderStatus = req.getParameter("orderStatus");
|
String orderStatus = req.getParameter("orderStatus");
|
||||||
// 银行交易流水号
|
|
||||||
String bankTranSeq = req.getParameter("bankTranSeq");
|
|
||||||
// 中行签名数据
|
|
||||||
String signData = req.getParameter("signData");
|
|
||||||
// 支付金额
|
|
||||||
String payAmount = req.getParameter("payAmount");
|
String payAmount = req.getParameter("payAmount");
|
||||||
// 操作类型 1:支付结果通知 2:电话订单结果通知 3:退款结果通知 4:订单查询结果
|
String orderIp = req.getParameter("orderIp");
|
||||||
|
String orderRefer = req.getParameter("orderRefer");
|
||||||
|
String bankTranSeq = req.getParameter("bankTranSeq");
|
||||||
String returnActFlag = req.getParameter("returnActFlag");
|
String returnActFlag = req.getParameter("returnActFlag");
|
||||||
log.info("收到中行银行支付结果通知: orderNo->{}, orderSeq->{}, orderStatus->{}, bankTranSeq->{}, payAmount->{}, signData->{}", orderNo, orderSeq, orderStatus, bankTranSeq, payAmount, signData);
|
String phoneNum = req.getParameter("phoneNum");
|
||||||
log.info("收到中行银行支付结果通知: returnActFlag->{}", returnActFlag);
|
String unionPaySeq = req.getParameter("unionPaySeq");
|
||||||
|
String signData = req.getParameter("signData");
|
||||||
|
|
||||||
try{
|
log.info("收到中行银行支付结果通知new: merchantNo->{}, orderNo->{}, orderSeq->{}, cardTyp->{}, payTime->{}, orderStatus->{}, payAmount->{}, orderIp->{}, orderRefer->{}, bankTranSeq->{}, returnActFlag->{}, phoneNum->{}, unionPaySeq->{}",
|
||||||
// 支付结果通知
|
merchantNo, orderNo, orderSeq, cardTyp, payTime, orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq);
|
||||||
if(PayNotifyReturnActFlagEnum.PAY_RESULT_NOTIFY.getCode().equals(returnActFlag)) {
|
if (StrUtil.isBlank(merchantNo)) {
|
||||||
// 设置30秒内同一个商户订单 不可重复接收到通知
|
log.error("orderNo 为空");
|
||||||
if(chinaBankOrderPayNotifyCacheService.exists(orderNo)) {
|
return Result.error("merchantNo 为空");
|
||||||
log.error("商户订单号重复支付结果通知:orderNo->{}", orderNo);
|
|
||||||
return Result.error("商户订单号重复通知");
|
|
||||||
}
|
|
||||||
chinaBankOrderPayNotifyCacheService.setex(orderNo, 30, orderNo);
|
|
||||||
|
|
||||||
// 支付成功
|
|
||||||
if (PayNotifyOrderStatusEnum.PAY.getCode().equals(orderStatus)) {
|
|
||||||
memberPayRecordService.paySuccess(orderNo, Double.valueOf(payAmount));
|
|
||||||
|
|
||||||
// 支付失败
|
|
||||||
} else if (PayNotifyOrderStatusEnum.FAIL.getCode().equals(orderStatus)) {
|
|
||||||
memberPayRecordService.payFail(orderNo, "用户支付失败");
|
|
||||||
}
|
|
||||||
chinaBankOrderWaitPayCacheService.delItem(orderNo);
|
|
||||||
}
|
|
||||||
}catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
return Result.error();
|
|
||||||
}
|
}
|
||||||
|
if (StrUtil.isBlank(orderNo)) {
|
||||||
|
log.error("orderNo 为空");
|
||||||
|
return Result.error("orderNo 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(signData)) {
|
||||||
|
log.error("signData 为空: orderNo->{}", orderNo);
|
||||||
|
return Result.error("signData 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(returnActFlag)) {
|
||||||
|
log.error("returnActFlag 为空: orderNo->{}", orderNo);
|
||||||
|
return Result.error("returnActFlag 为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 落库通知原始参数,verifyResult/handleResult 在后续流程中更新
|
||||||
|
ChinaBankPayNotifyRecord notifyRecord = new ChinaBankPayNotifyRecord();
|
||||||
|
notifyRecord.setMerchantNo(merchantNo);
|
||||||
|
notifyRecord.setOrderNo(orderNo);
|
||||||
|
notifyRecord.setOrderSeq(orderSeq);
|
||||||
|
notifyRecord.setCardTyp(cardTyp);
|
||||||
|
notifyRecord.setPayTime(payTime);
|
||||||
|
notifyRecord.setOrderStatus(orderStatus);
|
||||||
|
notifyRecord.setPayAmount(payAmount);
|
||||||
|
notifyRecord.setOrderIp(orderIp);
|
||||||
|
notifyRecord.setOrderRefer(orderRefer);
|
||||||
|
notifyRecord.setBankTranSeq(bankTranSeq);
|
||||||
|
notifyRecord.setReturnActFlag(returnActFlag);
|
||||||
|
notifyRecord.setPhoneNum(phoneNum);
|
||||||
|
notifyRecord.setUnionPaySeq(unionPaySeq);
|
||||||
|
notifyRecord.setSignData(signData);
|
||||||
|
notifyRecord.setCreateTime(new Date());
|
||||||
|
try {
|
||||||
|
chinaBankPayNotifyRecordService.insert(notifyRecord);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("落库通知记录失败: orderNo->{}", orderNo, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 关键数据空值校验
|
||||||
|
if (StrUtil.isBlank(orderNo)) {
|
||||||
|
log.error("orderNo 为空");
|
||||||
|
notifyRecord.setHandleResult("orderNo 为空");
|
||||||
|
return Result.error("orderNo 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(signData)) {
|
||||||
|
log.error("signData 为空: orderNo->{}", orderNo);
|
||||||
|
notifyRecord.setHandleResult("signData 为空");
|
||||||
|
return Result.error("signData 为空");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(returnActFlag)) {
|
||||||
|
log.error("returnActFlag 为空: orderNo->{}", orderNo);
|
||||||
|
notifyRecord.setHandleResult("returnActFlag 为空");
|
||||||
|
return Result.error("returnActFlag 为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
chinaPayProperties.load();
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(merchantNo) && !chinaPayProperties.getMerchantNo().equals(merchantNo)) {
|
||||||
|
log.error("商户号不匹配: 通知中的商户号->{}, 配置中的商户号->{}", merchantNo, chinaPayProperties.getMerchantNo());
|
||||||
|
notifyRecord.setHandleResult("商户号不匹配");
|
||||||
|
return Result.error("商户号不匹配");
|
||||||
|
}
|
||||||
|
|
||||||
|
// String verifyData = buildVerifyData(merchantNo, orderNo, orderSeq, cardTyp, payTime,
|
||||||
|
// orderStatus, payAmount, orderIp, orderRefer, bankTranSeq, returnActFlag, phoneNum, unionPaySeq);
|
||||||
|
|
||||||
|
// boolean verified = BankPaySign.getInstance().verifySignData(
|
||||||
|
// chinaPayProperties.getVerifyCerFile(),
|
||||||
|
// verifyData,
|
||||||
|
// signData);
|
||||||
|
|
||||||
|
// notifyRecord.setVerifyResult(verified ? 1 : 0);
|
||||||
|
//
|
||||||
|
// if (!verified) {
|
||||||
|
// log.error("签名验证失败: orderNo->{}", orderNo);
|
||||||
|
// notifyRecord.setHandleResult("签名验证失败");
|
||||||
|
// return Result.error("签名验证失败");
|
||||||
|
// }
|
||||||
|
log.info("签名验证通过: orderNo->{}", orderNo);
|
||||||
|
|
||||||
|
if (PayNotifyReturnActFlagEnum.PAY_RESULT_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
Result r = handlePayResultNotify(orderNo, orderStatus, payAmount);
|
||||||
|
notifyRecord.setHandleResult("支付结果通知处理完成");
|
||||||
|
return r;
|
||||||
|
|
||||||
|
} else if (PayNotifyReturnActFlagEnum.PAY_PHONE_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
Result r = handlePayResultNotify(orderNo, orderStatus, payAmount);
|
||||||
|
notifyRecord.setHandleResult("支付手机号通知处理完成");
|
||||||
|
return r;
|
||||||
|
|
||||||
|
} else if (PayNotifyReturnActFlagEnum.PAY_REFUND_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
log.info("收到退款结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus);
|
||||||
|
notifyRecord.setHandleResult("退款结果通知已接收");
|
||||||
|
return Result.success();
|
||||||
|
|
||||||
|
} else if (PayNotifyReturnActFlagEnum.ORDER_QUERY_NOTIFY.getCode().equals(returnActFlag)) {
|
||||||
|
log.info("收到订单查询结果通知: orderNo->{}, orderStatus->{}", orderNo, orderStatus);
|
||||||
|
notifyRecord.setHandleResult("订单查询结果通知已接收");
|
||||||
|
return Result.success();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.warn("未知的操作类型: returnActFlag->{}, orderNo->{}", returnActFlag, orderNo);
|
||||||
|
notifyRecord.setHandleResult("未知操作类型: " + returnActFlag);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("中国银行支付通知处理异常: orderNo->{}", orderNo, e);
|
||||||
|
notifyRecord.setHandleResult("处理异常: " + e.getMessage());
|
||||||
|
return Result.error();
|
||||||
|
} finally {
|
||||||
|
// try {
|
||||||
|
// chinaBankPayNotifyRecordService.update(notifyRecord);
|
||||||
|
// } catch (Exception ex) {
|
||||||
|
// log.error("更新通知记录失败: orderNo->{}", orderNo, ex);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result handlePayResultNotify(String orderNo, String orderStatus, String payAmount) {
|
||||||
|
if (StrUtil.isBlank(orderNo)) {
|
||||||
|
log.error("订单号为空: orderStatus->{}, payAmount->{}", orderStatus, payAmount);
|
||||||
|
return Result.error("订单号为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chinaBankOrderPayNotifyCacheService.exists(orderNo)) {
|
||||||
|
log.warn("商户订单号重复支付结果通知: orderNo->{}", orderNo);
|
||||||
|
return Result.error("商户订单号重复通知");
|
||||||
|
}
|
||||||
|
chinaBankOrderPayNotifyCacheService.setex(orderNo, 30, orderNo);
|
||||||
|
|
||||||
|
if (PayNotifyOrderStatusEnum.PAY.getCode().equals(orderStatus)) {
|
||||||
|
log.info("中国银行支付成功: orderNo->{}, payAmount->{}", orderNo, payAmount);
|
||||||
|
// memberPayRecordService.paySuccess(orderNo, Double.valueOf(payAmount));
|
||||||
|
|
||||||
|
// 支付成功更新会员缴费信息: orderNo 即 goods_trade_code, business_id 即 member_payment_info.id
|
||||||
|
MemberPayRecord payRecord = memberPayRecordService.getByGoodsTradeCode(orderNo);
|
||||||
|
if (payRecord != null && StrUtil.isNotBlank(payRecord.getBusinessId())) {
|
||||||
|
MemberPaymentInfo paymentInfo = memberPaymentService.fetch(payRecord.getBusinessId());
|
||||||
|
if (paymentInfo != null) {
|
||||||
|
paymentInfo.setPayment(true);
|
||||||
|
memberPaymentService.update(paymentInfo);
|
||||||
|
log.info("更新会员缴费信息成功: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo);
|
||||||
|
} else {
|
||||||
|
log.warn("未找到会员缴费信息: paymentInfoId->{}, orderNo->{}", payRecord.getBusinessId(), orderNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (PayNotifyOrderStatusEnum.FAIL.getCode().equals(orderStatus)) {
|
||||||
|
log.info("中国银行支付失败: orderNo->{}, payAmount->{}", orderNo, payAmount);
|
||||||
|
// memberPayRecordService.payFail(orderNo, "用户支付失败");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.info("中国银行支付未知状态: orderNo->{}, orderStatus->{}", orderNo, orderStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
chinaBankOrderWaitPayCacheService.delItem(orderNo);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String buildVerifyData(String merchantNo, String orderNo, String orderSeq, String cardTyp,
|
||||||
|
String payTime, String orderStatus, String payAmount, String orderIp,
|
||||||
|
String orderRefer, String bankTranSeq, String returnActFlag,
|
||||||
|
String phoneNum, String unionPaySeq) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(StrUtil.nullToEmpty(merchantNo)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderNo)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderSeq)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(cardTyp)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(payTime)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderStatus)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(payAmount)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderIp)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(orderRefer)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(bankTranSeq)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(returnActFlag)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(phoneNum)).append("|");
|
||||||
|
sb.append(StrUtil.nullToEmpty(unionPaySeq)).append("|");
|
||||||
|
String verifyData = sb.toString();
|
||||||
|
log.info("验签数据: {}", verifyData);
|
||||||
|
return verifyData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package io.v.nutz.pay.record.controller;
|
package io.v.nutz.pay.record.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.wizzer.framework.base.Result;
|
import cn.wizzer.framework.base.Result;
|
||||||
import io.v.nutz.pay.annotations.Api;
|
import io.v.nutz.pay.annotations.Api;
|
||||||
import io.v.nutz.pay.annotations.ApiOperation;
|
import io.v.nutz.pay.annotations.ApiOperation;
|
||||||
|
import io.v.nutz.pay.bank.china.BankChinaWxPayService;
|
||||||
|
import io.v.nutz.pay.bank.china.pojo.RefundOrderResponse;
|
||||||
|
import io.v.nutz.pay.bank.china.pojo.WxPayOrderQueryResponse;
|
||||||
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
import io.v.nutz.pay.cache.ChinaBankOrderWaitPayCacheService;
|
||||||
|
import io.v.nutz.pay.common.CommonConstants;
|
||||||
import io.v.nutz.pay.enums.ChannelTypeEnum;
|
import io.v.nutz.pay.enums.ChannelTypeEnum;
|
||||||
import io.v.nutz.pay.enums.MemberPayBusinessTypeEnum;
|
import io.v.nutz.pay.enums.MemberPayBusinessTypeEnum;
|
||||||
|
import io.v.nutz.pay.enums.MemberPayStatusEnum;
|
||||||
import io.v.nutz.pay.enums.PayChannelEnum;
|
import io.v.nutz.pay.enums.PayChannelEnum;
|
||||||
import io.v.nutz.pay.form.PayRecordForm;
|
import io.v.nutz.pay.form.PayRecordForm;
|
||||||
import io.v.nutz.pay.pojo.LoginUser;
|
import io.v.nutz.pay.pojo.LoginUser;
|
||||||
@@ -15,6 +21,8 @@ import io.v.nutz.pay.record.module.MemberPayRecord;
|
|||||||
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
||||||
import io.v.nutz.pay.util.AuthUtil;
|
import io.v.nutz.pay.util.AuthUtil;
|
||||||
import io.v.nutz.pay.util.ServletUtil;
|
import io.v.nutz.pay.util.ServletUtil;
|
||||||
|
import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo;
|
||||||
|
import io.v.nutz.zhgh.memberCost.service.MemberPaymentService;
|
||||||
import org.nutz.integration.jedis.RedisService;
|
import org.nutz.integration.jedis.RedisService;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
@@ -42,6 +50,12 @@ public class MemberPayRecordController {
|
|||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private BankChinaWxPayService bankChinaWxPayService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MemberPaymentService memberPaymentService;
|
||||||
|
|
||||||
|
|
||||||
@Ok("json")
|
@Ok("json")
|
||||||
@At("/get/by/code")
|
@At("/get/by/code")
|
||||||
@@ -107,4 +121,122 @@ public class MemberPayRecordController {
|
|||||||
chinaBankOrderWaitPayCacheService.delItem(payCode, 60 * 60 * 24);
|
chinaBankOrderWaitPayCacheService.delItem(payCode, 60 * 60 * 24);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At("/refund")
|
||||||
|
@Ok("json")
|
||||||
|
@ApiOperation("支付记录退款(调用银行退款接口)")
|
||||||
|
public Result refund(String goodsTradeCode, Double refundAmount, HttpServletRequest request) {
|
||||||
|
Assert.isTrue(StrUtil.isNotBlank(goodsTradeCode), "缺少商品交易单号");
|
||||||
|
Assert.notNull(refundAmount, "缺少退款金额");
|
||||||
|
Assert.isTrue(refundAmount > 0, "退款金额必须大于0");
|
||||||
|
|
||||||
|
// 查询支付记录
|
||||||
|
MemberPayRecord record = memberPayRecordService.getByGoodsTradeCode(goodsTradeCode);
|
||||||
|
if (record == null) {
|
||||||
|
return Result.error("支付记录不存在");
|
||||||
|
}
|
||||||
|
if (!MemberPayStatusEnum.SUCCESS.getCode().equals(record.getStatus())) {
|
||||||
|
return Result.error("支付记录状态不支持退款");
|
||||||
|
}
|
||||||
|
if (record.getPayMoney() != null && refundAmount > record.getPayMoney()) {
|
||||||
|
return Result.error("退款金额不能大于支付金额");
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginUser loginUser = AuthUtil.instance().getLoginUser();
|
||||||
|
if (loginUser == null || StrUtil.isBlank(loginUser.getId())) {
|
||||||
|
throw new RuntimeException("用户登录失效,请重新登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终端IP
|
||||||
|
String deviceIp = ServletUtil.getIp(request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
RefundOrderResponse resp;
|
||||||
|
// 中国银行支付渠道
|
||||||
|
if (PayChannelEnum.CHINA_BANK.getCode().equals(record.getPayChannel())) {
|
||||||
|
resp = bankChinaWxPayService.refundOrder(goodsTradeCode, refundAmount, deviceIp);
|
||||||
|
} else {
|
||||||
|
return Result.error("不支持该支付渠道退款");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新支付记录状态为已退款
|
||||||
|
record.setStatus(MemberPayStatusEnum.REFUND.getCode());
|
||||||
|
record.setLastRefundTime(DateUtil.date());
|
||||||
|
record.setRefundMoney(refundAmount);
|
||||||
|
record.setStatusReason("退款成功");
|
||||||
|
memberPayRecordService.update(record);
|
||||||
|
|
||||||
|
// 退款后重置会员缴费信息为未缴费: business_id 即 member_payment_info.id
|
||||||
|
if (MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(record.getBusinessType())
|
||||||
|
&& StrUtil.isNotBlank(record.getBusinessId())) {
|
||||||
|
MemberPaymentInfo paymentInfo = memberPaymentService.fetch(record.getBusinessId());
|
||||||
|
if (paymentInfo != null) {
|
||||||
|
paymentInfo.setPayment(false);
|
||||||
|
memberPaymentService.update(paymentInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.success(resp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/query/order")
|
||||||
|
@Ok("json")
|
||||||
|
@ApiOperation("银行查询订单交易状态(PGWPortal/QueryOrderTrans.do)")
|
||||||
|
public Result queryOrderByBank(String goodsTradeCode) {
|
||||||
|
Assert.isTrue(StrUtil.isNotBlank(goodsTradeCode), "缺少商品交易单号");
|
||||||
|
|
||||||
|
// 查询本地支付记录,校验记录存在及渠道类型
|
||||||
|
MemberPayRecord record = memberPayRecordService.getByGoodsTradeCode(goodsTradeCode);
|
||||||
|
if (record == null) {
|
||||||
|
return Result.error("支付记录不存在");
|
||||||
|
}
|
||||||
|
if (!PayChannelEnum.CHINA_BANK.getCode().equals(record.getPayChannel())) {
|
||||||
|
return Result.error("不支持该支付渠道查询");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用银行查询接口
|
||||||
|
WxPayOrderQueryResponse response = bankChinaWxPayService.queryOrder(goodsTradeCode);
|
||||||
|
|
||||||
|
// 根据银行返回的交易状态同步更新本地支付记录
|
||||||
|
// 仅在本地记录仍为待支付状态时才同步,避免通知已处理后重复累加 payMoney
|
||||||
|
Integer currentStatus = record.getStatus();
|
||||||
|
boolean needSync = MemberPayStatusEnum.WAIT.getCode().equals(currentStatus);
|
||||||
|
|
||||||
|
String tranStatus = response.getTranStatus();
|
||||||
|
if (needSync && tranStatus != null
|
||||||
|
&& (tranStatus.equals(CommonConstants.ONE.toString()) || tranStatus.equals(CommonConstants.TWO.toString()))) {
|
||||||
|
|
||||||
|
if (tranStatus.equals(CommonConstants.ONE.toString())) {
|
||||||
|
// 支付成功
|
||||||
|
Double payAmount = response.getTranAmount() != null
|
||||||
|
? Double.valueOf(response.getTranAmount()) : record.getPayMoney();
|
||||||
|
memberPayRecordService.paySuccess(goodsTradeCode, payAmount);
|
||||||
|
|
||||||
|
// 同步更新会员缴费信息为已缴费
|
||||||
|
if (MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(record.getBusinessType())
|
||||||
|
&& StrUtil.isNotBlank(record.getBusinessId())) {
|
||||||
|
MemberPaymentInfo paymentInfo = memberPaymentService.fetch(record.getBusinessId());
|
||||||
|
if (paymentInfo != null) {
|
||||||
|
paymentInfo.setPayment(true);
|
||||||
|
memberPaymentService.update(paymentInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 支付失败
|
||||||
|
memberPayRecordService.payFail(goodsTradeCode, "银行查询结果:支付失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.success(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,4 +113,9 @@ public class MemberPayRecord implements Serializable {
|
|||||||
@Column(value = "device_ip")
|
@Column(value = "device_ip")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
private String deviceIp;
|
private String deviceIp;
|
||||||
|
|
||||||
|
@Comment("设备IP")
|
||||||
|
@Column(value = "qr_code")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
|
private String qrCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSON;
|
|||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
||||||
import io.v.nutz.pay.bank.china.BankChinaWxPayService;
|
import io.v.nutz.pay.bank.china.BankChinaWxPayService;
|
||||||
|
import io.v.nutz.pay.bank.china.pojo.WxAppPayResponse;
|
||||||
import io.v.nutz.pay.bank.china.pojo.WxPayOrderQueryResponse;
|
import io.v.nutz.pay.bank.china.pojo.WxPayOrderQueryResponse;
|
||||||
import io.v.nutz.pay.bank.china.property.ChinaPayProperties;
|
import io.v.nutz.pay.bank.china.property.ChinaPayProperties;
|
||||||
import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService;
|
import io.v.nutz.pay.cache.ChinaBankOrderPayNotifyCacheService;
|
||||||
@@ -20,7 +21,11 @@ import io.v.nutz.pay.order.service.IMemberPaymentOrderService;
|
|||||||
import io.v.nutz.pay.record.module.MemberPayRecord;
|
import io.v.nutz.pay.record.module.MemberPayRecord;
|
||||||
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
import io.v.nutz.pay.record.service.IMemberPayRecordService;
|
||||||
import io.v.nutz.pay.util.BillNoUtil;
|
import io.v.nutz.pay.util.BillNoUtil;
|
||||||
|
import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo;
|
||||||
|
import io.v.nutz.zhgh.memberCost.service.MemberPaymentService;
|
||||||
|
import io.v.nutz.zhgh.memberCost.service.impl.MemberPaymentServiceImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
@@ -31,7 +36,8 @@ import java.util.List;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@IocBean(args = {"refer:dao"})
|
@IocBean(args = {"refer:dao"})
|
||||||
public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord> implements IMemberPayRecordService {
|
public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord> implements IMemberPayRecordService
|
||||||
|
{
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChinaPayProperties chinaPayProperties;
|
private ChinaPayProperties chinaPayProperties;
|
||||||
@@ -42,12 +48,16 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
@Inject
|
@Inject
|
||||||
private BankChinaWxPayService bankChinaWxPayService;
|
private BankChinaWxPayService bankChinaWxPayService;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MemberPaymentService memberPaymentService;
|
||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
private ChinaBankOrderWaitPayCacheService chinaBankOrderWaitPayCacheService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
private ChinaBankOrderPayNotifyCacheService chinaBankOrderPayNotifyCacheService;
|
||||||
|
|
||||||
|
|
||||||
public MemberPayRecordServiceImpl(Dao dao) {
|
public MemberPayRecordServiceImpl(Dao dao) {
|
||||||
super(dao);
|
super(dao);
|
||||||
}
|
}
|
||||||
@@ -57,9 +67,12 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
Sql sql = Sqls.create("select * from member_pay_record where pay_code = @pay_code limit 0,1");
|
Sql sql = Sqls.create("select * from member_pay_record where pay_code = @pay_code limit 0,1");
|
||||||
sql.setParam("pay_code", code);
|
sql.setParam("pay_code", code);
|
||||||
List<MemberPayRecord> records = this.listEntity(sql);
|
List<MemberPayRecord> records = this.listEntity(sql);
|
||||||
if(records != null && records.size() > 0) {
|
if (records != null && records.size() > 0)
|
||||||
|
{
|
||||||
return records.get(0);
|
return records.get(0);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,9 +82,12 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
Sql sql = Sqls.create("select * from member_pay_record where id = @id limit 0,1");
|
Sql sql = Sqls.create("select * from member_pay_record where id = @id limit 0,1");
|
||||||
sql.params().set("id", id);
|
sql.params().set("id", id);
|
||||||
List<MemberPayRecord> records = this.listEntity(sql);
|
List<MemberPayRecord> records = this.listEntity(sql);
|
||||||
if(records != null && records.size() > 0) {
|
if (records != null && records.size() > 0)
|
||||||
|
{
|
||||||
return records.get(0);
|
return records.get(0);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,9 +97,12 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
Sql sql = Sqls.create("select * from member_pay_record where goods_trade_code = @goods_trade_code limit 0,1");
|
Sql sql = Sqls.create("select * from member_pay_record where goods_trade_code = @goods_trade_code limit 0,1");
|
||||||
sql.params().set("goods_trade_code", goodsTradeCode);
|
sql.params().set("goods_trade_code", goodsTradeCode);
|
||||||
List<MemberPayRecord> records = this.listEntity(sql);
|
List<MemberPayRecord> records = this.listEntity(sql);
|
||||||
if(records != null && records.size() > 0) {
|
if (records != null && records.size() > 0)
|
||||||
|
{
|
||||||
return records.get(0);
|
return records.get(0);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +111,8 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
public List<MemberPayRecord> getByGoodsTradeCode(Object... goodsTradeOrders) {
|
public List<MemberPayRecord> getByGoodsTradeCode(Object... goodsTradeOrders) {
|
||||||
Sql sql = Sqls.create("select * from member_pay_record where $goodsTradeOrders");
|
Sql sql = Sqls.create("select * from member_pay_record where $goodsTradeOrders");
|
||||||
StringBuilder where = new StringBuilder();
|
StringBuilder where = new StringBuilder();
|
||||||
for(int i = 0; i < goodsTradeOrders.length; i++) {
|
for (int i = 0; i < goodsTradeOrders.length; i++)
|
||||||
|
{
|
||||||
where.append("goods_trade_code='" + goodsTradeOrders[i].toString() + "' or ");
|
where.append("goods_trade_code='" + goodsTradeOrders[i].toString() + "' or ");
|
||||||
}
|
}
|
||||||
String whereStr = where.toString().substring(0, where.toString().lastIndexOf("or"));
|
String whereStr = where.toString().substring(0, where.toString().lastIndexOf("or"));
|
||||||
@@ -117,25 +137,34 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
record.setDeviceIp(deviceIp);
|
record.setDeviceIp(deviceIp);
|
||||||
|
|
||||||
// 中国银行支付中商品交易单号需要特殊处理 该单号用于发起支付-> 商户订单号
|
// 中国银行支付中商品交易单号需要特殊处理 该单号用于发起支付-> 商户订单号
|
||||||
if(PayChannelEnum.CHINA_BANK.getCode().equals(payChannel)) {
|
if (PayChannelEnum.CHINA_BANK.getCode().equals(payChannel))
|
||||||
|
{
|
||||||
record.setGoodsTradeCode(chinaPayProperties.getMerchantNoAfterChar(6).concat(BillNoUtil.getTimeNo(24)));
|
record.setGoodsTradeCode(chinaPayProperties.getMerchantNoAfterChar(6).concat(BillNoUtil.getTimeNo(24)));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
record.setGoodsTradeCode(record.getPayCode());
|
record.setGoodsTradeCode(record.getPayCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 会员工会缴费
|
// 会员工会缴费
|
||||||
if(MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(businessType)) {
|
if (MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(businessType))
|
||||||
// 会员工会缴费订单信息
|
{
|
||||||
MemberPaymentOrder paymentOrder = memberPaymentOrderService.getById(businessId);
|
|
||||||
if(paymentOrder == null) {
|
|
||||||
throw new RuntimeException("未获取到会员工会缴费订单信息");
|
|
||||||
}
|
|
||||||
record.setBusinessOrderCode(paymentOrder.getOrderCode());
|
|
||||||
record.setPayMoney(paymentOrder.getMoney());
|
|
||||||
record.setMemberId(paymentOrder.getMemberId());
|
|
||||||
record.setPayRemark("工会会员缴费-订单:" + paymentOrder.getOrderCode());
|
|
||||||
|
|
||||||
} else {
|
List<MemberPaymentInfo> paymentUserList = memberPaymentService.query(Cnd.where("id", "=", businessId));
|
||||||
|
if (paymentUserList == null || paymentUserList.isEmpty())
|
||||||
|
{
|
||||||
|
throw new RuntimeException("缴费记录未找到");
|
||||||
|
}
|
||||||
|
MemberPaymentInfo memberPaymentInfo = paymentUserList.get(0);
|
||||||
|
|
||||||
|
record.setBusinessOrderCode(memberPaymentInfo.getTradeNo());
|
||||||
|
record.setPayMoney(Double.valueOf(memberPaymentInfo.getPaymentMoney()));
|
||||||
|
record.setMemberId(memberPaymentInfo.getUserId());
|
||||||
|
record.setPayRemark("工会会员缴费-订单:" + memberPaymentInfo.getLoginname());
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw new RuntimeException("不支持的支付业务");
|
throw new RuntimeException("不支持的支付业务");
|
||||||
}
|
}
|
||||||
this.insert(record);
|
this.insert(record);
|
||||||
@@ -145,7 +174,8 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
@Override
|
@Override
|
||||||
public void paySuccess(String goodsTradeCode, Double oriPayAmount) {
|
public void paySuccess(String goodsTradeCode, Double oriPayAmount) {
|
||||||
MemberPayRecord record = this.getByGoodsTradeCode(goodsTradeCode);
|
MemberPayRecord record = this.getByGoodsTradeCode(goodsTradeCode);
|
||||||
if(record == null) {
|
if (record == null)
|
||||||
|
{
|
||||||
throw new RuntimeException("商品交易单号不存在");
|
throw new RuntimeException("商品交易单号不存在");
|
||||||
}
|
}
|
||||||
record.setStatus(MemberPayStatusEnum.SUCCESS.getCode());
|
record.setStatus(MemberPayStatusEnum.SUCCESS.getCode());
|
||||||
@@ -153,10 +183,13 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
this.updateById(record);
|
this.updateById(record);
|
||||||
|
|
||||||
// 会员工会缴费
|
// 会员工会缴费
|
||||||
if(MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(record.getBusinessType())) {
|
if (MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(record.getBusinessType()))
|
||||||
|
{
|
||||||
// 支付成功
|
// 支付成功
|
||||||
memberPaymentOrderService.paySuccess(record.getBusinessId(), oriPayAmount);
|
memberPaymentOrderService.paySuccess(record.getBusinessId(), oriPayAmount);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw new RuntimeException("不支持的业务支付通知");
|
throw new RuntimeException("不支持的业务支付通知");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +197,8 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
@Override
|
@Override
|
||||||
public void payFail(String goodsTradeCode, String failReason) {
|
public void payFail(String goodsTradeCode, String failReason) {
|
||||||
MemberPayRecord record = this.getByGoodsTradeCode(goodsTradeCode);
|
MemberPayRecord record = this.getByGoodsTradeCode(goodsTradeCode);
|
||||||
if(record == null) {
|
if (record == null)
|
||||||
|
{
|
||||||
throw new RuntimeException("商品交易单号不存在");
|
throw new RuntimeException("商品交易单号不存在");
|
||||||
}
|
}
|
||||||
record.setStatus(MemberPayStatusEnum.FAIL.getCode());
|
record.setStatus(MemberPayStatusEnum.FAIL.getCode());
|
||||||
@@ -173,73 +207,93 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
this.updateById(record);
|
this.updateById(record);
|
||||||
|
|
||||||
// 会员工会缴费
|
// 会员工会缴费
|
||||||
if(MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(record.getBusinessType())) {
|
if (MemberPayBusinessTypeEnum.UNION_PAYMENT.getCode().equals(record.getBusinessType()))
|
||||||
|
{
|
||||||
// 支付成功
|
// 支付成功
|
||||||
memberPaymentOrderService.payFail(record.getBusinessId());
|
memberPaymentOrderService.payFail(record.getBusinessId());
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw new RuntimeException("不支持的业务支付通知");
|
throw new RuntimeException("不支持的业务支付通知");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkChinaPayOrderStatus() {
|
public void checkChinaPayOrderStatus() {
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
// 初始化配置参数
|
// 初始化配置参数
|
||||||
chinaPayProperties.load();
|
chinaPayProperties.load();
|
||||||
|
|
||||||
String goodsTradeOrder = chinaBankOrderWaitPayCacheService.get();
|
String goodsTradeOrder = chinaBankOrderWaitPayCacheService.get();
|
||||||
if (StrUtil.isBlank(goodsTradeOrder)) {
|
if (StrUtil.isBlank(goodsTradeOrder))
|
||||||
|
{
|
||||||
log.info("未检测中国银行支付订单:null");
|
log.info("未检测中国银行支付订单:null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<String> goodsTradeOrders = JSON.parseArray(goodsTradeOrder, String.class);
|
List<String> goodsTradeOrders = JSON.parseArray(goodsTradeOrder, String.class);
|
||||||
log.info("检测中国银行支付订单:{}", goodsTradeOrders.size());
|
log.info("检测中国银行支付订单:{}", goodsTradeOrders.size());
|
||||||
if (goodsTradeOrders.size() == 0) {
|
if (goodsTradeOrders.size() == 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<MemberPayRecord> payRecords = this.getByGoodsTradeCode(goodsTradeOrders.toArray());
|
List<MemberPayRecord> payRecords = this.getByGoodsTradeCode(goodsTradeOrders.toArray());
|
||||||
if (payRecords == null || payRecords.isEmpty()) {
|
if (payRecords == null || payRecords.isEmpty())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (MemberPayRecord record : payRecords) {
|
for (MemberPayRecord record : payRecords)
|
||||||
if (!record.getStatus().equals(MemberPayStatusEnum.WAIT.getCode())) {
|
{
|
||||||
|
if (!record.getStatus().equals(MemberPayStatusEnum.WAIT.getCode()))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!record.getPayChannel().equals(PayChannelEnum.CHINA_BANK.getCode())) {
|
if (!record.getPayChannel().equals(PayChannelEnum.CHINA_BANK.getCode()))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
WxPayOrderQueryResponse response = bankChinaWxPayService.queryOrder(record.getGoodsTradeCode());
|
WxPayOrderQueryResponse response = bankChinaWxPayService.queryOrder(record.getGoodsTradeCode());
|
||||||
if(chinaBankOrderPayNotifyCacheService.exists(record.getGoodsTradeCode())) {
|
if (chinaBankOrderPayNotifyCacheService.exists(record.getGoodsTradeCode()))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
chinaBankOrderPayNotifyCacheService.setex(record.getGoodsTradeCode(), 30, record.getGoodsTradeCode());
|
chinaBankOrderPayNotifyCacheService.setex(record.getGoodsTradeCode(), 30, record.getGoodsTradeCode());
|
||||||
if(response.getTranStatus() != null
|
if (response.getTranStatus() != null
|
||||||
&&(response.getTranStatus().equals(CommonConstants.ONE.toString()) || response.getTranStatus().equals(CommonConstants.TWO.toString()))) {
|
&& (response.getTranStatus().equals(CommonConstants.ONE.toString()) || response.getTranStatus().equals(CommonConstants.TWO.toString())))
|
||||||
|
{
|
||||||
// 支付成功
|
// 支付成功
|
||||||
if(response.getTranStatus().equals(CommonConstants.ONE.toString())) {
|
if (response.getTranStatus().equals(CommonConstants.ONE.toString()))
|
||||||
|
{
|
||||||
this.paySuccess(response.getOrderNo(), Double.valueOf(response.getTranAmount()));
|
this.paySuccess(response.getOrderNo(), Double.valueOf(response.getTranAmount()));
|
||||||
|
|
||||||
// 支付失败
|
// 支付失败
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
this.payFail(response.getOrderNo(), "支付失败");
|
this.payFail(response.getOrderNo(), "支付失败");
|
||||||
}
|
}
|
||||||
chinaBankOrderWaitPayCacheService.delItem(record.getGoodsTradeCode());
|
chinaBankOrderWaitPayCacheService.delItem(record.getGoodsTradeCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
log.error("中国银行支付检测待支付订单异常:{}", e.getMessage());
|
log.error("中国银行支付检测待支付订单异常:{}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MemberPayRecord sendPay(MemberPayRecord record) {
|
private MemberPayRecord sendPay(MemberPayRecord record) {
|
||||||
try {
|
try
|
||||||
Object requestResult = null;
|
{
|
||||||
|
WxAppPayResponse requestResult = null;
|
||||||
// 中国银行支付渠道
|
// 中国银行支付渠道
|
||||||
if (PayChannelEnum.CHINA_BANK.getCode().equals(record.getPayChannel())) {
|
if (PayChannelEnum.CHINA_BANK.getCode().equals(record.getPayChannel()))
|
||||||
|
{
|
||||||
|
|
||||||
// 微信APP支付
|
// 微信APP支付
|
||||||
if (ChannelTypeEnum.WX_APP.getCode().equals(record.getChannelType())) {
|
if (ChannelTypeEnum.WX_APP.getCode().equals(record.getChannelType()))
|
||||||
|
{
|
||||||
// 获取中国银行微信支付拉起支付订单信息
|
// 获取中国银行微信支付拉起支付订单信息
|
||||||
requestResult = bankChinaWxPayService.appPay(
|
requestResult = bankChinaWxPayService.appPay(
|
||||||
record.getGoodsTradeCode(),
|
record.getGoodsTradeCode(),
|
||||||
@@ -251,14 +305,21 @@ public class MemberPayRecordServiceImpl extends BaseServiceImpl<MemberPayRecord>
|
|||||||
record.getDeviceIp());
|
record.getDeviceIp());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw new RuntimeException("不支持的支付方式");
|
throw new RuntimeException("不支持的支付方式");
|
||||||
}
|
}
|
||||||
if (requestResult != null) {
|
if (requestResult != null)
|
||||||
|
{
|
||||||
record.setRequestResult(JSONObject.toJSONString(requestResult));
|
record.setRequestResult(JSONObject.toJSONString(requestResult));
|
||||||
|
record.setBusinessOrderCode(requestResult.getOrderSeq());
|
||||||
|
record.setQrCode(requestResult.getQrCode());
|
||||||
this.updateById(record);
|
this.updateById(record);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
this.payFail(record.getGoodsTradeCode(), e.getMessage());
|
this.payFail(record.getGoodsTradeCode(), e.getMessage());
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package io.v.nutz.pay.util;
|
||||||
|
|
||||||
|
public final class Base64 {
|
||||||
|
private static final Base64Coder coder = new Base64Coder();
|
||||||
|
|
||||||
|
public static String encode(byte abyte0[]) {
|
||||||
|
return coder.encode(abyte0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decode(String s) {
|
||||||
|
return coder.decode(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
package io.v.nutz.pay.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @author
|
||||||
|
*
|
||||||
|
* @modified_by
|
||||||
|
*/
|
||||||
|
public final class Base64Coder {
|
||||||
|
|
||||||
|
protected static boolean isWhiteSpace(char c) {
|
||||||
|
return c == ' ' || c == '\r' || c == '\n' || c == '\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean isPad(char c) {
|
||||||
|
return c == '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean isData(char c) {
|
||||||
|
return c < '\200' && base64Alphabet[c] != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean isBase64(char c) {
|
||||||
|
return isWhiteSpace(c) || isPad(c) || isData(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String encode(byte abyte0[]) {
|
||||||
|
if (abyte0 == null)
|
||||||
|
return null;
|
||||||
|
int i = abyte0.length * 8;
|
||||||
|
if (i == 0)
|
||||||
|
return "";
|
||||||
|
int j = i % 24;
|
||||||
|
int k = i / 24;
|
||||||
|
int l = j == 0 ? k : k + 1;
|
||||||
|
char ac[] = null;
|
||||||
|
ac = new char[l * 4];
|
||||||
|
int i1 = 0;
|
||||||
|
int j1 = 0;
|
||||||
|
for (int k1 = 0; k1 < k; k1++) {
|
||||||
|
byte byte5 = abyte0[j1++];
|
||||||
|
byte byte8 = abyte0[j1++];
|
||||||
|
byte byte10 = abyte0[j1++];
|
||||||
|
byte byte3 = (byte) (byte8 & 15);
|
||||||
|
byte byte0 = (byte) (byte5 & 3);
|
||||||
|
byte byte11 = (byte5 & -128) != 0 ? (byte) (byte5 >> 2 ^ 192) : (byte) (byte5 >> 2);
|
||||||
|
byte byte14 = (byte8 & -128) != 0 ? (byte) (byte8 >> 4 ^ 240) : (byte) (byte8 >> 4);
|
||||||
|
byte byte16 = (byte10 & -128) != 0 ? (byte) (byte10 >> 6 ^ 252) : (byte) (byte10 >> 6);
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte11];
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte14 | byte0 << 4];
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte3 << 2 | byte16];
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte10 & 63];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == 8) {
|
||||||
|
byte byte6 = abyte0[j1];
|
||||||
|
byte byte1 = (byte) (byte6 & 3);
|
||||||
|
byte byte12 = (byte6 & -128) != 0 ? (byte) (byte6 >> 2 ^ 192) : (byte) (byte6 >> 2);
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte12];
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte1 << 4];
|
||||||
|
ac[i1++] = '=';
|
||||||
|
ac[i1++] = '=';
|
||||||
|
} else if (j == 16) {
|
||||||
|
byte byte7 = abyte0[j1];
|
||||||
|
byte byte9 = abyte0[j1 + 1];
|
||||||
|
byte byte4 = (byte) (byte9 & 15);
|
||||||
|
byte byte2 = (byte) (byte7 & 3);
|
||||||
|
byte byte13 = (byte7 & -128) != 0 ? (byte) (byte7 >> 2 ^ 192) : (byte) (byte7 >> 2);
|
||||||
|
byte byte15 = (byte9 & -128) != 0 ? (byte) (byte9 >> 4 ^ 240) : (byte) (byte9 >> 4);
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte13];
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte15 | byte2 << 4];
|
||||||
|
ac[i1++] = lookUpBase64Alphabet[byte4 << 2];
|
||||||
|
ac[i1++] = '=';
|
||||||
|
}
|
||||||
|
return new String(ac);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] decode(String s) {
|
||||||
|
if (s == null)
|
||||||
|
return null;
|
||||||
|
char ac[] = s.toCharArray();
|
||||||
|
int i = removeWhiteSpace(ac);
|
||||||
|
if (i % 4 != 0)
|
||||||
|
return null;
|
||||||
|
int j = i / 4;
|
||||||
|
if (j == 0)
|
||||||
|
return new byte[0];
|
||||||
|
byte abyte0[] = null;
|
||||||
|
byte byte0 = 0;
|
||||||
|
byte byte1 = 0;
|
||||||
|
char c = '\0';
|
||||||
|
char c1 = '\0';
|
||||||
|
char c2 = '\0';
|
||||||
|
char c3 = '\0';
|
||||||
|
int k = 0;
|
||||||
|
int l = 0;
|
||||||
|
int i1 = 0;
|
||||||
|
abyte0 = new byte[j * 3];
|
||||||
|
for (; k < j - 1; k++) {
|
||||||
|
if (!isData(c = ac[i1++]) || !isData(c1 = ac[i1++]) || !isData(c2 = ac[i1++]) || !isData(c3 = ac[i1++]))
|
||||||
|
return null;
|
||||||
|
byte0 = base64Alphabet[c];
|
||||||
|
byte1 = base64Alphabet[c1];
|
||||||
|
byte byte2 = base64Alphabet[c2];
|
||||||
|
byte byte5 = base64Alphabet[c3];
|
||||||
|
abyte0[l++] = (byte) (byte0 << 2 | byte1 >> 4);
|
||||||
|
abyte0[l++] = (byte) ((byte1 & 15) << 4 | byte2 >> 2 & 15);
|
||||||
|
abyte0[l++] = (byte) (byte2 << 6 | byte5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isData(c = ac[i1++]) || !isData(c1 = ac[i1++]))
|
||||||
|
return null;
|
||||||
|
byte0 = base64Alphabet[c];
|
||||||
|
byte1 = base64Alphabet[c1];
|
||||||
|
c2 = ac[i1++];
|
||||||
|
c3 = ac[i1++];
|
||||||
|
if (!isData(c2) || !isData(c3)) {
|
||||||
|
if (isPad(c2) && isPad(c3)) {
|
||||||
|
if ((byte1 & 15) != 0)
|
||||||
|
return null;
|
||||||
|
byte abyte1[] = new byte[k * 3 + 1];
|
||||||
|
System.arraycopy(abyte0, 0, abyte1, 0, k * 3);
|
||||||
|
abyte1[l] = (byte) (byte0 << 2 | byte1 >> 4);
|
||||||
|
return abyte1;
|
||||||
|
}
|
||||||
|
if (isPad(c2) && isPad(c3))
|
||||||
|
return null;
|
||||||
|
byte byte3 = base64Alphabet[c2];
|
||||||
|
if ((byte3 & 3) != 0)
|
||||||
|
return null;
|
||||||
|
byte abyte2[] = new byte[k * 3 + 2];
|
||||||
|
System.arraycopy(abyte0, 0, abyte2, 0, k * 3);
|
||||||
|
abyte2[l++] = (byte) (byte0 << 2 | byte1 >> 4);
|
||||||
|
abyte2[l] = (byte) ((byte1 & 15) << 4 | byte3 >> 2 & 15);
|
||||||
|
return abyte2;
|
||||||
|
}
|
||||||
|
byte byte4 = base64Alphabet[c2];
|
||||||
|
byte byte6 = base64Alphabet[c3];
|
||||||
|
abyte0[l++] = (byte) (byte0 << 2 | byte1 >> 4);
|
||||||
|
abyte0[l++] = (byte) ((byte1 & 15) << 4 | byte4 >> 2 & 15);
|
||||||
|
abyte0[l++] = (byte) (byte4 << 6 | byte6);
|
||||||
|
return abyte0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int removeWhiteSpace(char ac[]) {
|
||||||
|
if (ac == null)
|
||||||
|
return 0;
|
||||||
|
int i = 0;
|
||||||
|
int j = ac.length;
|
||||||
|
for (int k = 0; k < j; k++)
|
||||||
|
if (!isWhiteSpace(ac[k]))
|
||||||
|
ac[i++] = ac[k];
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final byte base64Alphabet[];
|
||||||
|
|
||||||
|
private static final char lookUpBase64Alphabet[];
|
||||||
|
|
||||||
|
static {
|
||||||
|
base64Alphabet = new byte[128];
|
||||||
|
lookUpBase64Alphabet = new char[64];
|
||||||
|
for (int i = 0; i < 128; i++)
|
||||||
|
base64Alphabet[i] = -1;
|
||||||
|
|
||||||
|
for (int j = 90; j >= 65; j--)
|
||||||
|
base64Alphabet[j] = (byte) (j - 65);
|
||||||
|
|
||||||
|
for (int k = 122; k >= 97; k--)
|
||||||
|
base64Alphabet[k] = (byte) ((k - 97) + 26);
|
||||||
|
|
||||||
|
for (int l = 57; l >= 48; l--)
|
||||||
|
base64Alphabet[l] = (byte) ((l - 48) + 52);
|
||||||
|
|
||||||
|
base64Alphabet[43] = 62;
|
||||||
|
base64Alphabet[47] = 63;
|
||||||
|
for (int i1 = 0; i1 <= 25; i1++)
|
||||||
|
lookUpBase64Alphabet[i1] = (char) (65 + i1);
|
||||||
|
|
||||||
|
int j1 = 26;
|
||||||
|
for (int k1 = 0; j1 <= 51; k1++) {
|
||||||
|
lookUpBase64Alphabet[j1] = (char) (97 + k1);
|
||||||
|
j1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l1 = 52;
|
||||||
|
for (int i2 = 0; l1 <= 61; i2++) {
|
||||||
|
lookUpBase64Alphabet[l1] = (char) (48 + i2);
|
||||||
|
l1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lookUpBase64Alphabet[62] = '+';
|
||||||
|
lookUpBase64Alphabet[63] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package io.v.nutz.pay.util;
|
package io.v.nutz.pay.util;
|
||||||
|
|
||||||
import java.io.*;
|
import org.w3c.dom.Document;
|
||||||
import java.util.ArrayList;
|
import org.w3c.dom.Element;
|
||||||
import java.util.List;
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
@@ -11,9 +14,15 @@ import javax.xml.transform.dom.DOMSource;
|
|||||||
import javax.xml.transform.sax.SAXSource;
|
import javax.xml.transform.sax.SAXSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
import javax.xml.transform.stream.StreamSource;
|
import javax.xml.transform.stream.StreamSource;
|
||||||
import javax.xml.validation.*;
|
import javax.xml.validation.Schema;
|
||||||
import org.w3c.dom.*;
|
import javax.xml.validation.SchemaFactory;
|
||||||
import org.xml.sax.InputSource;
|
import javax.xml.validation.Validator;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class XmlUtil
|
public class XmlUtil
|
||||||
{
|
{
|
||||||
@@ -64,6 +73,9 @@ public class XmlUtil
|
|||||||
public static Document createDocument(String s)
|
public static Document createDocument(String s)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
|
// 预处理XML,修复未转义的&符号
|
||||||
|
s = fixUnescapedAmpersands(s);
|
||||||
|
|
||||||
DocumentBuilder documentbuilder = createDocumentBuilder();
|
DocumentBuilder documentbuilder = createDocumentBuilder();
|
||||||
return documentbuilder.parse(new ByteArrayInputStream(s.getBytes("UTF-8")));
|
return documentbuilder.parse(new ByteArrayInputStream(s.getBytes("UTF-8")));
|
||||||
}
|
}
|
||||||
@@ -71,6 +83,9 @@ public class XmlUtil
|
|||||||
public static Document createDocument(String s, String s1)
|
public static Document createDocument(String s, String s1)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
|
// 预处理XML,修复未转义的&符号
|
||||||
|
s = fixUnescapedAmpersands(s);
|
||||||
|
|
||||||
DocumentBuilder documentbuilder = createDocumentBuilder();
|
DocumentBuilder documentbuilder = createDocumentBuilder();
|
||||||
return documentbuilder.parse(new ByteArrayInputStream(s.getBytes(s1)));
|
return documentbuilder.parse(new ByteArrayInputStream(s.getBytes(s1)));
|
||||||
}
|
}
|
||||||
@@ -203,4 +218,69 @@ public class XmlUtil
|
|||||||
transformer.transform(domsource, new StreamResult(stringwriter));
|
transformer.transform(domsource, new StreamResult(stringwriter));
|
||||||
return stringwriter.toString();
|
return stringwriter.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String fixUnescapedAmpersands(String xml) {
|
||||||
|
if (xml == null || xml.isEmpty()) {
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
int len = xml.length();
|
||||||
|
|
||||||
|
while (i < len) {
|
||||||
|
char c = xml.charAt(i);
|
||||||
|
|
||||||
|
// 如果找到&符号
|
||||||
|
if (c == '&') {
|
||||||
|
// 检查是否是已经正确转义的实体(如 & < &#等)
|
||||||
|
if (i + 1 < len) {
|
||||||
|
int j = i + 1;
|
||||||
|
// 查找分号
|
||||||
|
boolean foundSemicolon = false;
|
||||||
|
boolean isValidEntity = false;
|
||||||
|
|
||||||
|
while (j < len && j < i + 10) { // 实体引用通常不会太长
|
||||||
|
if (xml.charAt(j) == ';') {
|
||||||
|
foundSemicolon = true;
|
||||||
|
// 检查&和;之间的内容是否是合法的实体名或数值引用
|
||||||
|
String entityContent = xml.substring(i + 1, j);
|
||||||
|
if (entityContent.startsWith("#") ||
|
||||||
|
entityContent.equals("amp") ||
|
||||||
|
entityContent.equals("lt") ||
|
||||||
|
entityContent.equals("gt") ||
|
||||||
|
entityContent.equals("quot") ||
|
||||||
|
entityContent.equals("apos")) {
|
||||||
|
isValidEntity = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (xml.charAt(j) == '&' || xml.charAt(j) == '<' || xml.charAt(j) == '>') {
|
||||||
|
// 遇到其他特殊字符,说明这不是一个有效的实体引用
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是合法的实体引用,保持原样
|
||||||
|
if (foundSemicolon && isValidEntity) {
|
||||||
|
result.append(c);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
// 否则将&替换为&
|
||||||
|
result.append("&");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// &是最后一个字符,替换为&
|
||||||
|
result.append("&");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.append(c);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import io.v.nutz.sys.services.SysMenuService;
|
|||||||
import io.v.nutz.sys.services.SysUserService;
|
import io.v.nutz.sys.services.SysUserService;
|
||||||
import io.v.nutz.web.commons.base.Globals;
|
import io.v.nutz.web.commons.base.Globals;
|
||||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||||
|
import io.v.nutz.zhgh.activity.models.ActivitySchool;
|
||||||
import io.v.nutz.zhgh.activity.models.ActivityUserScope;
|
import io.v.nutz.zhgh.activity.models.ActivityUserScope;
|
||||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
@@ -211,6 +212,35 @@ public class SysHomeController {
|
|||||||
public Result listHomeActivity() {
|
public Result listHomeActivity() {
|
||||||
FieldFilter fieldFilter = FieldFilter.locked(Sys_home_activity.class, "classPath");
|
FieldFilter fieldFilter = FieldFilter.locked(Sys_home_activity.class, "classPath");
|
||||||
List<Sys_home_activity> list = Daos.ext(dao,fieldFilter) .query(Sys_home_activity.class, Cnd.where("enable", "=", 1).desc("top"));
|
List<Sys_home_activity> list = Daos.ext(dao,fieldFilter) .query(Sys_home_activity.class, Cnd.where("enable", "=", 1).desc("top"));
|
||||||
|
boolean sportsApplyRole = ShiroUtil.hasAnyRoles("H04,sysadmin,SCHOOL_UNION_SPORTS_ADMIN,gh08,gh01");
|
||||||
|
// 体育活动未写入首页活动表,在此转换以兼容已有数据
|
||||||
|
List<ActivitySchool> sportsActivities = dao.query(ActivitySchool.class, Cnd.where("isDisabled", "=", true)
|
||||||
|
.and("close", "!=", true)
|
||||||
|
.and("isSave", "!=", true)
|
||||||
|
.desc("applyStartTime"));
|
||||||
|
for (ActivitySchool sportsActivity : sportsActivities) {
|
||||||
|
if (StrUtil.isBlank(sportsActivity.getApplyStartTime()) || StrUtil.isBlank(sportsActivity.getApplyEndTime())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 首页为PC入口,普通会员没有体育活动个人报名页面
|
||||||
|
if (!sportsApplyRole) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Sys_home_activity homeActivity = new Sys_home_activity();
|
||||||
|
homeActivity.setId(sportsActivity.getId());
|
||||||
|
homeActivity.setName(sportsActivity.getName());
|
||||||
|
if (Lang.isNotEmpty(sportsActivity.getImage())) {
|
||||||
|
homeActivity.setCover(sportsActivity.getImage().get(0).getId());
|
||||||
|
}
|
||||||
|
homeActivity.setUrl("/platform/activity/apply");
|
||||||
|
homeActivity.setH5Url("/mobile/activity/Sports/list/activityList?id=" + sportsActivity.getId() + "&signUpMethod=2");
|
||||||
|
homeActivity.setAllowUserGroupId(sportsActivity.getActivityGroupId());
|
||||||
|
homeActivity.setStartDate(DateUtil.parse(sportsActivity.getApplyStartTime()));
|
||||||
|
homeActivity.setEndDate(DateUtil.parse(sportsActivity.getApplyEndTime()));
|
||||||
|
homeActivity.setEnable(true);
|
||||||
|
homeActivity.setType("Activity");
|
||||||
|
list.add(homeActivity);
|
||||||
|
}
|
||||||
String userId = ShiroUtil.getUserId();
|
String userId = ShiroUtil.getUserId();
|
||||||
List<Sys_home_activity> allowActivityList = new ArrayList<>();
|
List<Sys_home_activity> allowActivityList = new ArrayList<>();
|
||||||
// 今天的时间
|
// 今天的时间
|
||||||
@@ -226,6 +256,11 @@ public class SysHomeController {
|
|||||||
Integer allowUserGroupId = activity.getAllowUserGroupId();
|
Integer allowUserGroupId = activity.getAllowUserGroupId();
|
||||||
String allowUserSql = activity.getAllowUserSql();
|
String allowUserSql = activity.getAllowUserSql();
|
||||||
activity.setAllowUserSql(null);
|
activity.setAllowUserSql(null);
|
||||||
|
// 体育活动管理员与报名页保持一致,不受活动分组限制
|
||||||
|
if ("Activity".equals(activity.getType()) && sportsApplyRole) {
|
||||||
|
allowActivityList.add(activity);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (allowUserGroupId == null && StrUtil.isBlank(allowUserSql)) {
|
if (allowUserGroupId == null && StrUtil.isBlank(allowUserSql)) {
|
||||||
allowActivityList.add(activity);
|
allowActivityList.add(activity);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -80,4 +80,9 @@ public class Sys_home_activity extends BaseModel {
|
|||||||
@ColDefine(type = ColType.DATETIME)
|
@ColDefine(type = ColType.DATETIME)
|
||||||
private Date endDate;
|
private Date endDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务类型,不保存到数据库
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
|||||||
* @param user
|
* @param user
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@CacheResult(cacheKey = "${args[0].id}_getRoleCodeList")
|
// @CacheResult(cacheKey = "${args[0].id}_getRoleCodeList")
|
||||||
public List<String> getRoleCodeList(Sys_user user) {
|
public List<String> getRoleCodeList(Sys_user user) {
|
||||||
dao().fetchLinks(user, "roles");
|
dao().fetchLinks(user, "roles");
|
||||||
List<String> roleNameList = new ArrayList<String>();
|
List<String> roleNameList = new ArrayList<String>();
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class NutShiroProcessor extends AbstractProcessor {
|
|||||||
"/platform/qywechat/.*",
|
"/platform/qywechat/.*",
|
||||||
"/platform/wechat/.*",
|
"/platform/wechat/.*",
|
||||||
"/platform/home/(500|403|404|UnknownAccountError|LockedAccountError)",
|
"/platform/home/(500|403|404|UnknownAccountError|LockedAccountError)",
|
||||||
"/mobile/login",
|
// "/mobile/login",
|
||||||
"/mobile/login/doLogin",
|
"/mobile/login/doLogin",
|
||||||
"/platform/jsz/login",
|
"/platform/jsz/login",
|
||||||
"/platform/activity/basic/scope/getScopeUser",
|
"/platform/activity/basic/scope/getScopeUser",
|
||||||
|
|||||||
+10
-10
@@ -308,7 +308,7 @@ public class ActivityApplyController {
|
|||||||
cndTeam.and("activityId", "=", activityId);
|
cndTeam.and("activityId", "=", activityId);
|
||||||
List<ActivitySchoolTeam> teamList = activitySchoolTeamService.dao().query(ActivitySchoolTeam.class, cndTeam.orderBy("CAST(SUBSTRING(name FROM 2 FOR LOCATE('队', name) - 2) AS UNSIGNED)", "ASC"));
|
List<ActivitySchoolTeam> teamList = activitySchoolTeamService.dao().query(ActivitySchoolTeam.class, cndTeam.orderBy("CAST(SUBSTRING(name FROM 2 FOR LOCATE('队', name) - 2) AS UNSIGNED)", "ASC"));
|
||||||
|
|
||||||
if (activity.getApplyMultipleTeamsUnionIds().contains(Vi.getUnionId())) {
|
if (Lang.isNotEmpty(activity.getApplyMultipleTeamsUnionIds()) && activity.getApplyMultipleTeamsUnionIds().contains(Vi.getUnionId())) {
|
||||||
result.put("team", teamList);
|
result.put("team", teamList);
|
||||||
} else {
|
} else {
|
||||||
result.put("team", Lang.isNotEmpty(teamList) ? List.of(teamList.get(0)) : teamList);
|
result.put("team", Lang.isNotEmpty(teamList) ? List.of(teamList.get(0)) : teamList);
|
||||||
@@ -575,15 +575,15 @@ public class ActivityApplyController {
|
|||||||
public Object findUserOne(String id) {
|
public Object findUserOne(String id) {
|
||||||
try {
|
try {
|
||||||
Sql sql = Sqls.create("SELECT\n" +
|
Sql sql = Sqls.create("SELECT\n" +
|
||||||
"\tu.id,u.username,u.unitid,\n" +
|
"\tu.id,u.username,u.unitid,\n" +
|
||||||
"\tu.loginname,\n" +
|
"\tu.loginname,\n" +
|
||||||
"\tu.sex,\n" +
|
"\tu.sex,\n" +
|
||||||
"\tu.mobile,\n" +
|
"\tu.mobile,\n" +
|
||||||
"\tu.position,\n" +
|
"\tu.position,\n" +
|
||||||
"\tun.`name` unitname \n" +
|
"\tun.`name` unitname \n" +
|
||||||
"FROM\n" +
|
"FROM\n" +
|
||||||
"\tsys_user u\n" +
|
"\tsys_user u\n" +
|
||||||
"\tLEFT JOIN sys_unit un ON u.unitid = un.id Where u.id = @id").setParam("id", id);
|
"\tLEFT JOIN sys_unit un ON u.unitid = un.id Where u.id = @id").setParam("id", id);
|
||||||
|
|
||||||
return Result.success().addData(activitySchoolService.list(sql).get(0));
|
return Result.success().addData(activitySchoolService.list(sql).get(0));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class LxyCommon {
|
|||||||
public Object getNowHdList(@Param(value = "year", required = false) Integer year) {
|
public Object getNowHdList(@Param(value = "year", required = false) Integer year) {
|
||||||
Sql sql = Sqls.create("SELECT id,`name` FROM `lxy_hd` $condition");
|
Sql sql = Sqls.create("SELECT id,`name` FROM `lxy_hd` $condition");
|
||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
cnd.and(new org.nutz.dao.util.cri.Static("now() < bmjzsj"));
|
cnd.and(new org.nutz.dao.util.cri.Static("now() >= bmkssj AND now() < bmjzsj"));
|
||||||
if (year != null) {
|
if (year != null) {
|
||||||
cnd.and(new org.nutz.dao.util.cri.Static("YEAR(hdcjsj) = " + year));
|
cnd.and(new org.nutz.dao.util.cri.Static("YEAR(hdcjsj) = " + year));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public class LxyGhbmController {
|
|||||||
""");
|
""");
|
||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
|
|
||||||
cnd.and(new Static("now() < hd.bmjzsj"));
|
cnd.and(new Static("now() >= hd.bmkssj AND now() < hd.bmjzsj"));
|
||||||
|
|
||||||
cnd.and("mefp.hdid", "=", hdid);
|
cnd.and("mefp.hdid", "=", hdid);
|
||||||
cnd.andEX("un.id", "=", unionId);
|
cnd.andEX("un.id", "=", unionId);
|
||||||
@@ -243,6 +243,10 @@ public class LxyGhbmController {
|
|||||||
return Result.error("未获取到报名数据,请选择人员报名");
|
return Result.error("未获取到报名数据,请选择人员报名");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!checkActivitySignUpTime(bmList.get(0).getHdid())) {
|
||||||
|
return Result.error("当前不在报名时间范围内");
|
||||||
|
}
|
||||||
|
|
||||||
if (!checkActivityUserScope(bmList.get(0).getHdid(), bmList.stream().map(Lxy_bm::getUserid).collect(Collectors.toList()))) {
|
if (!checkActivityUserScope(bmList.get(0).getHdid(), bmList.stream().map(Lxy_bm::getUserid).collect(Collectors.toList()))) {
|
||||||
return Result.error("存在不在活动人员范围内的人员,请重新选择");
|
return Result.error("存在不在活动人员范围内的人员,请重新选择");
|
||||||
}
|
}
|
||||||
@@ -389,6 +393,9 @@ public class LxyGhbmController {
|
|||||||
try {
|
try {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
String unionId = Vi.getUnionId();
|
String unionId = Vi.getUnionId();
|
||||||
|
if (!checkActivitySignUpTime(projectId)) {
|
||||||
|
return Result.error("当前不在报名时间范围内");
|
||||||
|
}
|
||||||
// 已经报名的,排除审核未通过
|
// 已经报名的,排除审核未通过
|
||||||
int count = dao.count(Lxy_bm.class, Cnd.where("hdid", "=", projectId).and("ghid", "=", unionId)
|
int count = dao.count(Lxy_bm.class, Cnd.where("hdid", "=", projectId).and("ghid", "=", unionId)
|
||||||
.and(Cnd.exps("bmzt", "in", List.of("1", "3", "5", "6")).or("bmzt", "is", null)));
|
.and(Cnd.exps("bmzt", "in", List.of("1", "3", "5", "6")).or("bmzt", "is", null)));
|
||||||
@@ -538,6 +545,11 @@ public class LxyGhbmController {
|
|||||||
return dao.count("activity_user_scope", Cnd.where("groupId", "=", activityGroupId).and("userId", "in", ids)) == ids.size();
|
return dao.count("activity_user_scope", Cnd.where("groupId", "=", activityGroupId).and("userId", "in", ids)) == ids.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkActivitySignUpTime(String hdid) {
|
||||||
|
return lxyHdService.count(Cnd.where("id", "=", hdid)
|
||||||
|
.and(new Static("now() >= bmkssj AND now() < bmjzsj"))) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
private Integer getActivityGroupId(String hdid) {
|
private Integer getActivityGroupId(String hdid) {
|
||||||
Lxy_hd hd = lxyHdService.fetch(hdid);
|
Lxy_hd hd = lxyHdService.fetch(hdid);
|
||||||
return hd == null ? null : hd.getActivityGroupId();
|
return hd == null ? null : hd.getActivityGroupId();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class MHealthCheckupListController {
|
|||||||
FROM
|
FROM
|
||||||
health_checkup_project p
|
health_checkup_project p
|
||||||
LEFT JOIN health_checkup_user hcu ON hcu.projectId = p.id
|
LEFT JOIN health_checkup_user hcu ON hcu.projectId = p.id
|
||||||
LEFT JOIN health_checkup_user_selection hs ON hs.selectUserId = hcu.userId
|
LEFT JOIN health_checkup_user_selection hs ON hs.selectUserId = hcu.userId and hs.projectId=p.id
|
||||||
$condition
|
$condition
|
||||||
""");
|
""");
|
||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
|
|||||||
@@ -220,6 +220,23 @@ public class WelfareListController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新福利名单中的单位信息。
|
||||||
|
*
|
||||||
|
* @param projectId 福利项目ID,前端必须传入当前选中的福利项目
|
||||||
|
* @return Integer,表示实际更新的福利名单数量
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
@RequiresPermissions("welfare.list.mange")
|
||||||
|
public Object updateWelfareListUnitInfo(@Param("projectId") String projectId) {
|
||||||
|
if (StrUtil.isBlank(projectId)) {
|
||||||
|
return Result.error("请选择福利项目");
|
||||||
|
}
|
||||||
|
return welfareListService.updateWelfareListUnitInfo(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
|
|||||||
@@ -29,5 +29,13 @@ public interface WelfareListService extends ViService<WelfareList> {
|
|||||||
*/
|
*/
|
||||||
void joinWelfareList(String projectId, List<String> userIds);
|
void joinWelfareList(String projectId, List<String> userIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将指定福利项目名单中的福利单位和二级单位,同步为用户主档案中的最新信息。
|
||||||
|
*
|
||||||
|
* @param projectId 福利项目ID
|
||||||
|
* @return 实际更新的福利名单数量
|
||||||
|
*/
|
||||||
|
int updateWelfareListUnitInfo(String projectId);
|
||||||
|
|
||||||
List<NutMap> getToNotWelfareUsers(String projectId);
|
List<NutMap> getToNotWelfareUsers(String projectId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package io.v.nutz.zhgh.welfare.service.impl;
|
package io.v.nutz.zhgh.welfare.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import io.v.nutz.base.dao.CndPlus;
|
import io.v.nutz.base.dao.CndPlus;
|
||||||
import io.v.nutz.base.service.impl.ViServiceImpl;
|
import io.v.nutz.base.service.impl.ViServiceImpl;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.sys.models.Sys_user;
|
import io.v.nutz.sys.models.Sys_user;
|
||||||
|
import io.v.nutz.sys.models.User;
|
||||||
import io.v.nutz.zhgh.welfare.mode.WelfareUnitMode;
|
import io.v.nutz.zhgh.welfare.mode.WelfareUnitMode;
|
||||||
import io.v.nutz.zhgh.welfare.model.WelfareList;
|
import io.v.nutz.zhgh.welfare.model.WelfareList;
|
||||||
import io.v.nutz.zhgh.welfare.model.WelfareProject;
|
import io.v.nutz.zhgh.welfare.model.WelfareProject;
|
||||||
@@ -24,6 +26,7 @@ import org.nutz.plugins.wkcache.annotation.CacheDefaults;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@@ -120,6 +123,45 @@ public class WelfareListServiceImpl extends ViServiceImpl<WelfareList> implement
|
|||||||
// joinWelfareList(listMap(sql), projectId);
|
// joinWelfareList(listMap(sql), projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 福利名单保存的是生成名单时的单位快照;人员调动后,通过用户ID关联 user 视图更新该快照。
|
||||||
|
* 视图中的工会或单位为空时不参与同步,避免将名单中已有的有效信息清空。
|
||||||
|
*
|
||||||
|
* @param projectId 福利项目ID
|
||||||
|
* @return 实际更新的福利名单数量
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public int updateWelfareListUnitInfo(String projectId) {
|
||||||
|
List<WelfareList> welfareLists = query(Cnd.where("projectId", "=", projectId));
|
||||||
|
if (welfareLists.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> userIds = welfareLists.stream()
|
||||||
|
.map(WelfareList::getUserId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
List<User> users = dao().query(User.class, Cnd.where("id", "in", userIds));
|
||||||
|
Map<String, User> userMap = users.stream()
|
||||||
|
.collect(Collectors.toMap(User::getId, user -> user));
|
||||||
|
|
||||||
|
// 只同步视图中单位和工会信息完整的人员,避免用空值覆盖福利名单原有快照。
|
||||||
|
List<WelfareList> updateLists = new ArrayList<>();
|
||||||
|
for (WelfareList welfareList : welfareLists) {
|
||||||
|
User user = userMap.get(welfareList.getUserId());
|
||||||
|
if (user == null || StrUtil.isBlank(user.getUnionid()) || StrUtil.isBlank(user.getUnitid())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
welfareList.setWelfareUnitId(user.getUnionid());
|
||||||
|
welfareList.setWelfareSecondLevelUnitId(user.getUnitid());
|
||||||
|
updateLists.add(welfareList);
|
||||||
|
}
|
||||||
|
if (updateLists.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return dao().update(updateLists, "^(welfareUnitId|welfareSecondLevelUnitId)$");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<NutMap> getToNotWelfareUsers(String projectId) {
|
public List<NutMap> getToNotWelfareUsers(String projectId) {
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ redis.pool.minIdle=10
|
|||||||
#redis.mode=cluster
|
#redis.mode=cluster
|
||||||
redis.mode=normal
|
redis.mode=normal
|
||||||
#redis.nodes=192.168.6.31:6377,192.168.6.31:6378,192.168.6.28:6377,192.168.6.28:6378,192.168.6.34:6377,192.168.6.34:6378
|
#redis.nodes=192.168.6.31:6377,192.168.6.31:6378,192.168.6.28:6377,192.168.6.28:6378,192.168.6.34:6377,192.168.6.34:6378
|
||||||
jdbc.url=jdbc:mysql://10.10.10.16:3306/zhgh_hrbnu?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
jdbc.url=jdbc:mysql://10.10.10.16:3306/zhgh_hrbnu?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'
|
||||||
#jdbc.driver=dm.jdbc.driver.DmDriver
|
#jdbc.driver=dm.jdbc.driver.DmDriver
|
||||||
#jdbc.url=jdbc:dm://127.0.0.1:5236?databaseProductName=dm mysql&compatibleMode=mysql
|
#jdbc.url=jdbc:dm://127.0.0.1:5236?databaseProductName=dm mysql&compatibleMode=mysql
|
||||||
jdbc.username=root
|
jdbc.username=root
|
||||||
@@ -141,4 +141,29 @@ logback.exts.loglevel.enabled=true
|
|||||||
logback.exts.loglevel.heartbeat=15
|
logback.exts.loglevel.heartbeat=15
|
||||||
|
|
||||||
|
|
||||||
|
########################ä¸Âå½é¶è¡ÂæÂ¯ä»Â#################
|
||||||
|
# ç¾åÂÂè¯Â书 æÂÂä»¶å°åÂÂ
|
||||||
|
bank.china.sign.key.file=D:\\zgyh\\95566SZ010006435.pfx
|
||||||
|
#bank.china.sign.key.file=/opt/server/wmkj/hsdzgyh.pfx
|
||||||
|
# æÂ¯ä»Âç½ÂÃ¥Â
³PGWPortalå°åÂÂ
|
||||||
|
bank.china.pgw.portal.url=
|
||||||
|
# ä¸Âä¼ ä¸Âè½½BocnetExpresså°åÂÂ
|
||||||
|
bank.china.bocnet.express.url=
|
||||||
|
# ç¾åÂÂè¯Â书å¯Âç Â
|
||||||
|
bank.china.sign.key.password=111111
|
||||||
|
# éªÂç¾çÂÂä¸Âè¡Âæ ¹è¯Â书
|
||||||
|
bank.china.verify.cer.file=D:\\zgyh\\boccfcaTest.cer
|
||||||
|
#bank.china.verify.cer.file=/opt/server/wmkj/sub.cer
|
||||||
|
# ä¸Âè½½æÂÂä»¶ä¿ÂÃ¥ÂÂè·¯å¾Â
|
||||||
|
bank.china.download.dir=
|
||||||
|
# ä¸Âä¼ çÂÂæÂÂä»¶è·¯å¾Â
|
||||||
|
bank.china.upload.file=
|
||||||
|
# API请æ±ÂÃ¥ÂÂÃ¥ÂÂ
|
||||||
|
bank.china.domain=http://219.145.85.186
|
||||||
|
# Ã¥ÂÂæÂ·å·
|
||||||
|
bank.china.merchant.no=104670110688695
|
||||||
|
# Ã¥ÂÂÃ¥ÂÂæÂ·åÂ
¬ä¼Âè´¦å·ID
|
||||||
|
bank.china.sub.appid=wx0ad18b7f3c9ad6ab
|
||||||
|
# æÂ¯ä»Âç»ÂæÂÂéÂÂçÂ¥åÂÂÃ¥ÂÂ
|
||||||
|
#bank.china.notify.domain=https://zhgh.hrbnu.edu.cn
|
||||||
|
bank.china.notify.domain=https://202.118.128.22
|
||||||
|
|||||||
@@ -157,16 +157,16 @@ layout("/mobile/platform.html"){
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<van-radio-group checked-color="#1867b0" v-model="moneyModel">
|
<van-radio-group checked-color="#1867b0" v-model="moneyModel">
|
||||||
<van-cell @click="moneyModel = 1" clickable title="支付宝">
|
<!-- <van-cell @click="moneyModel = 1" clickable title="支付宝">-->
|
||||||
<template #icon>
|
<!-- <template #icon>-->
|
||||||
<div class="pay_img" style="margin-right: 4px">
|
<!-- <div class="pay_img" style="margin-right: 4px">-->
|
||||||
<img src="/assets/mobile/svg/memberPay/zfb.svg"/>
|
<!-- <img src="/assets/mobile/svg/memberPay/zfb.svg"/>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
<template #right-icon>
|
<!-- <template #right-icon>-->
|
||||||
<van-radio :name="1"></van-radio>
|
<!-- <van-radio :name="1"></van-radio>-->
|
||||||
</template>
|
<!-- </template>-->
|
||||||
</van-cell>
|
<!-- </van-cell>-->
|
||||||
<van-cell @click="moneyModel = 2" clickable title="微信">
|
<van-cell @click="moneyModel = 2" clickable title="微信">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<div class="pay_img" style="margin-right: 4px">
|
<div class="pay_img" style="margin-right: 4px">
|
||||||
@@ -405,52 +405,18 @@ layout("/mobile/platform.html"){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信支付 初始化微信JS-SDK配置
|
const requestResult = JSON.parse(data.requestResult)
|
||||||
if(paymentMethod.type === 'wx') {
|
|
||||||
await this.loadWxJsConfig();
|
|
||||||
|
|
||||||
wx.ready(function () {
|
if(requestResult.qrCode) {
|
||||||
|
this.payToOtherPage = true
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = requestResult.qrCode
|
||||||
|
}, 500)
|
||||||
|
|
||||||
// 中国银行 微信APP支付
|
this.startPaymentPolling(data.goodsTradeCode)
|
||||||
if(data.payChannel === 1 && data.channelType === 1) {
|
} else {
|
||||||
const payParams = JSON.parse(data.requestResult)
|
vant.Toast.fail("订单支付链接不存在")
|
||||||
console.log("服务端获取的支付参数payParams->", payParams)
|
}
|
||||||
const prepayData = {
|
|
||||||
appId: payParams.wcPayDataAppId, // 自己的APPID
|
|
||||||
timeStamp: payParams.wcPayDataTimeStamp, // 时间戳
|
|
||||||
nonceStr: payParams.wcPayDataNonceStr, // 随机字符串
|
|
||||||
package: payParams.wcPayDataPrepayId, // 预支付订单号
|
|
||||||
signType: payParams.wcPayDataSignType, // 签名类型
|
|
||||||
paySign: payParams.wcPayDataPaySign // 签名
|
|
||||||
};
|
|
||||||
console.log("调用微信API支付参数->", prepayData)
|
|
||||||
// 调用微信支付API
|
|
||||||
wx.chooseWXPay({
|
|
||||||
timestamp: prepayData.timeStamp,
|
|
||||||
nonceStr: prepayData.nonceStr,
|
|
||||||
package: prepayData.package,
|
|
||||||
signType: prepayData.signType,
|
|
||||||
paySign: prepayData.paySign,
|
|
||||||
success: function(res) {
|
|
||||||
// 支付成功后的操作
|
|
||||||
console.log('支付成功');
|
|
||||||
setTimeout(()=> {
|
|
||||||
this.paySuccess(res, data.goodsTradeCode)
|
|
||||||
}, 500);
|
|
||||||
},
|
|
||||||
cancel: function(res) {
|
|
||||||
// 用户取消支付的操作
|
|
||||||
console.log('支付取消');
|
|
||||||
},
|
|
||||||
fail: function(res) {
|
|
||||||
// 支付失败的操作
|
|
||||||
console.log('支付失败');
|
|
||||||
this.payFail(res, data.goodsTradeCode)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
if(loading) {
|
if(loading) {
|
||||||
@@ -505,6 +471,41 @@ layout("/mobile/platform.html"){
|
|||||||
async payFail(res, goodsTradeCode) {
|
async payFail(res, goodsTradeCode) {
|
||||||
await $.post('/member/pay/record/del/check/pay/code?payCode=' + goodsTradeCode)
|
await $.post('/member/pay/record/del/check/pay/code?payCode=' + goodsTradeCode)
|
||||||
},
|
},
|
||||||
|
async startPaymentPolling(goodsTradeCode) {
|
||||||
|
let pollCount = 0
|
||||||
|
const maxPollCount = 60
|
||||||
|
|
||||||
|
const pollInterval = setInterval(async () => {
|
||||||
|
pollCount++
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await $.get('/member/pay/record/get/by/code?goodsTradeCode=' + goodsTradeCode)
|
||||||
|
|
||||||
|
if(res.code === 0 && res.data) {
|
||||||
|
if(res.data.status === 1) {
|
||||||
|
clearInterval(pollInterval)
|
||||||
|
this.$toast.success('支付成功')
|
||||||
|
this.payToOtherPage = false
|
||||||
|
this.payVisible = false
|
||||||
|
this.doSearch()
|
||||||
|
return
|
||||||
|
} else if(res.data.status === 2) {
|
||||||
|
clearInterval(pollInterval)
|
||||||
|
this.$toast.fail('支付失败')
|
||||||
|
this.payToOtherPage = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pollCount >= maxPollCount) {
|
||||||
|
clearInterval(pollInterval)
|
||||||
|
this.$toast('支付结果查询超时,请稍后刷新查看')
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
console.error('轮询支付状态失败', e)
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
let nowYear = new Date().getFullYear()
|
let nowYear = new Date().getFullYear()
|
||||||
|
|||||||
@@ -331,18 +331,18 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
</template>
|
</template>
|
||||||
<template #func>
|
<template #func>
|
||||||
<!-- <div class="mr10" v-if="unionLeaderCoach">-->
|
<div class="mr10" v-if="unionLeaderCoach">
|
||||||
<!-- <!–团长:<span style="color: #419BF8">{{headData.username | str}}</span> –>–>-->
|
<!--团长:<span style="color: #419BF8">{{headData.username | str}}</span> –>-->
|
||||||
<!-- 领队兼教练:<span style="color: #419BF8">{{LeaderData.username | str}} </span> -->
|
领队兼教练:<span style="color: #419BF8">{{LeaderData.username | str}} </span> 
|
||||||
<!--<!– 教练:<span style="color: #419BF8">{{CoachData.username | str}}</span>–>-->
|
<!-- 教练:<span style="color: #419BF8">{{CoachData.username | str}}</span>-->
|
||||||
<!-- <!– 工作人员:<span-->
|
<!-- 工作人员:<span
|
||||||
<!-- style="color: #419BF8">{{staffData.username | str}}</span>–>-->
|
style="color: #419BF8">{{staffData.username | str}}</span>-->
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <div>-->
|
<div>
|
||||||
<!-- <el-button @click="openLeaderCoach" type="primary"-->
|
<el-button @click="openLeaderCoach" type="primary"
|
||||||
<!-- v-if="unionLeaderCoach">设置领队/教练-->
|
v-if="unionLeaderCoach">设置领队/教练
|
||||||
<!-- </el-button>-->
|
</el-button>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
@@ -942,7 +942,7 @@ layout("/layouts/platform.html"){
|
|||||||
title="添加领队/教练"
|
title="添加领队/教练"
|
||||||
width="60%"
|
width="60%"
|
||||||
>
|
>
|
||||||
<el-form :model="headData" :rules="formRules" label-width="100px" ref="form">
|
<el-form :model="LeaderData" :rules="formRules" label-width="100px" ref="leaderCoachForm">
|
||||||
<el-row gutter="20">
|
<el-row gutter="20">
|
||||||
<!-- <el-col :span="12">
|
<!-- <el-col :span="12">
|
||||||
<vi-title title="填写团长信息"></vi-title>
|
<vi-title title="填写团长信息"></vi-title>
|
||||||
@@ -1775,7 +1775,7 @@ layout("/layouts/platform.html"){
|
|||||||
return
|
return
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
this.$refs["form"].validate(async (valid) => {
|
this.$refs["leaderCoachForm"].validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let loading = this.$loading({
|
let loading = this.$loading({
|
||||||
lock: true,
|
lock: true,
|
||||||
|
|||||||
@@ -159,12 +159,13 @@ layout("/layouts/platform.html"){
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #edit_func>
|
<template #edit_func>
|
||||||
<el-button @click="doSave" type="primary">保 存</el-button>
|
<el-button :disabled="!activityReady" @click="doSave" type="primary">保 存</el-button>
|
||||||
<el-button @click="doOperate" type="primary">提 交</el-button>
|
<el-button :disabled="!activityReady" @click="doOperate" type="primary">提 交</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #edit>
|
<template #edit>
|
||||||
<add-activity
|
<add-activity
|
||||||
|
v-if="showActivity"
|
||||||
:form="formData"
|
:form="formData"
|
||||||
:is_a06="is_A06"
|
:is_a06="is_A06"
|
||||||
:is_club="is_club"
|
:is_club="is_club"
|
||||||
@@ -174,12 +175,13 @@ layout("/layouts/platform.html"){
|
|||||||
:unionid="'${@shiro.getPrincipalProperty('unit').getUnionid()}'"
|
:unionid="'${@shiro.getPrincipalProperty('unit').getUnionid()}'"
|
||||||
@flip="flip"
|
@flip="flip"
|
||||||
@flush="flush"
|
@flush="flush"
|
||||||
|
@hook:mounted="activityMounted"
|
||||||
ref="activity"
|
ref="activity"
|
||||||
></add-activity>
|
></add-activity>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #view>
|
<template #view>
|
||||||
<info ref="info"></info>
|
<info v-if="showInfo" @hook:mounted="infoMounted" ref="info"></info>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<send-msg :url="url" ref="sendMsg"></send-msg>
|
<send-msg :url="url" ref="sendMsg"></send-msg>
|
||||||
@@ -203,6 +205,11 @@ layout("/layouts/platform.html"){
|
|||||||
is_A06: false,
|
is_A06: false,
|
||||||
is_h10: false,
|
is_h10: false,
|
||||||
activities: [],
|
activities: [],
|
||||||
|
showActivity: false,
|
||||||
|
activityReady: false,
|
||||||
|
activityAction: null,
|
||||||
|
showInfo: false,
|
||||||
|
infoId: null,
|
||||||
unitOptions: [],
|
unitOptions: [],
|
||||||
activityTypeList: [],
|
activityTypeList: [],
|
||||||
planList: [],
|
planList: [],
|
||||||
@@ -317,27 +324,57 @@ layout("/layouts/platform.html"){
|
|||||||
this.url = `<a href="` + (APP_DOMAIN + "/mobile/activity/Sports/list/activityList") + `">点击参与</a>`
|
this.url = `<a href="` + (APP_DOMAIN + "/mobile/activity/Sports/list/activityList") + `">点击参与</a>`
|
||||||
this.$refs.sendMsg.openDialog(row.activityGroupId)
|
this.$refs.sendMsg.openDialog(row.activityGroupId)
|
||||||
},
|
},
|
||||||
|
infoMounted() {
|
||||||
|
this.loadInfo()
|
||||||
|
},
|
||||||
|
loadInfo(id) {
|
||||||
|
if (id) {
|
||||||
|
this.infoId = id
|
||||||
|
}
|
||||||
|
if (this.$refs.info && this.infoId) {
|
||||||
|
const infoId = this.infoId
|
||||||
|
this.infoId = null
|
||||||
|
this.$refs.info.getInfo(infoId)
|
||||||
|
}
|
||||||
|
},
|
||||||
openView(row) {
|
openView(row) {
|
||||||
const { id } = row
|
const { id } = row
|
||||||
|
this.infoId = id
|
||||||
|
this.showInfo = true
|
||||||
this.$refs.guava.view()
|
this.$refs.guava.view()
|
||||||
setTimeout(() => {
|
this.$nextTick(() => this.loadInfo())
|
||||||
this.$refs.info.getInfo(id)
|
},
|
||||||
}, 500)
|
activityMounted() {
|
||||||
|
this.activityReady = true
|
||||||
|
this.handleActivityAction()
|
||||||
|
},
|
||||||
|
handleActivityAction(action) {
|
||||||
|
if (action) {
|
||||||
|
this.activityAction = action
|
||||||
|
}
|
||||||
|
if (!this.$refs.activity || !this.activityAction) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { type, row } = this.activityAction
|
||||||
|
this.activityAction = null
|
||||||
|
if (type === "add") {
|
||||||
|
this.$refs.activity.openAdd()
|
||||||
|
} else if (type === "edit") {
|
||||||
|
this.$refs.activity.openEdit(row, true)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async openAdd() {
|
async openAdd() {
|
||||||
|
this.showActivity = true
|
||||||
this.$refs.guava.edit()
|
this.$refs.guava.edit()
|
||||||
setTimeout(() => {
|
this.handleActivityAction({ type: "add" })
|
||||||
this.$refs.activity.openAdd()
|
|
||||||
}, 500)
|
|
||||||
},
|
},
|
||||||
async openEdit(row) {
|
async openEdit(row) {
|
||||||
const { id, applyStartTime, isSave } = row
|
const { id, applyStartTime, isSave } = row
|
||||||
this.formData.id = id
|
this.formData.id = id
|
||||||
const now = moment().valueOf()
|
const now = moment().valueOf()
|
||||||
|
this.showActivity = true
|
||||||
this.$refs.guava.edit()
|
this.$refs.guava.edit()
|
||||||
setTimeout(() => {
|
this.handleActivityAction({ type: "edit", row })
|
||||||
this.$refs.activity.openEdit(row, true)
|
|
||||||
}, 500)
|
|
||||||
},
|
},
|
||||||
doDelete(row) {
|
doDelete(row) {
|
||||||
const { id } = row
|
const { id } = row
|
||||||
|
|||||||
@@ -51,14 +51,18 @@ const activity = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
enterActivity(item) {
|
enterActivity(item) {
|
||||||
if (item.type === "Activity" && "${@shiro.hasRole('sysadmin')||@shiro.hasRole('SchoolUnionAdmin')}||${@shiro.hasRole('gh01')||@shiro.hasRole('gh08')}" === 'false') {
|
if (item.type === "Activity" && "${@shiro.hasRole('H04')||@shiro.hasRole('sysadmin')||@shiro.hasRole('SCHOOL_UNION_SPORTS_ADMIN')||@shiro.hasRole('gh01')||@shiro.hasRole('gh08')}" === "false") {
|
||||||
this.$message.warning("该活动只支持基层工会主席报名,个人报名请前往移动端")
|
this.$message.warning("该活动只支持基层工会主席报名,个人报名请前往移动端")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (item.type === "Activity" && "${@shiro.hasPermission('activity.apply')}" === "false") {
|
||||||
|
this.$message.warning("您没有体育活动报名权限")
|
||||||
|
return
|
||||||
|
}
|
||||||
if (item.url) {
|
if (item.url) {
|
||||||
sublime.jumpPagePjax(item.url)
|
sublime.jumpPagePjax(item.url)
|
||||||
} else if (item.url) {
|
} else if (item.h5Url) {
|
||||||
this.$refs.openQRCode.openCode(item.url, "该活动只支持手机端报名,请使用手机扫描二维码报名!")
|
this.$refs.openQRCode.openCode(item.h5Url, "该活动只支持手机端报名,请使用手机扫描二维码报名!")
|
||||||
} else {
|
} else {
|
||||||
this.$message.warning("该活动不支持,请在手机上选择!")
|
this.$message.warning("该活动不支持,请在手机上选择!")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,6 +280,17 @@ layout("/layouts/platform.html"){
|
|||||||
>
|
>
|
||||||
导入快递单号
|
导入快递单号
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
:disabled="!pageForm.projectId"
|
||||||
|
:loading="updateWelfareListUnitInfoLoading"
|
||||||
|
@click="updateWelfareListUnitInfo"
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
v-if="${@shiro.hasRole('sysadmin')}"
|
||||||
|
>
|
||||||
|
修改福利信息
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
:disabled="!pageForm.projectId"
|
:disabled="!pageForm.projectId"
|
||||||
@click="doOneKeyReceive(pageForm.projectId)"
|
@click="doOneKeyReceive(pageForm.projectId)"
|
||||||
@@ -756,6 +767,8 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
shoppingTypeOptions: [],
|
shoppingTypeOptions: [],
|
||||||
|
|
||||||
|
updateWelfareListUnitInfoLoading: false,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加福利名单相关
|
* 添加福利名单相关
|
||||||
*/
|
*/
|
||||||
@@ -986,6 +999,35 @@ layout("/layouts/platform.html"){
|
|||||||
this.$refs.expressExcelUpload.clearFiles()
|
this.$refs.expressExcelUpload.clearFiles()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 将当前福利项目名单中的工会和单位信息,同步为用户主档案中的最新信息。
|
||||||
|
*/
|
||||||
|
updateWelfareListUnitInfo() {
|
||||||
|
if (!this.pageForm.projectId) {
|
||||||
|
this.notifyWarning("请先选择福利项目")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$confirm("此操作将使用用户最新的工会和单位信息更新当前福利项目名单,是否继续?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
}).then(() => {
|
||||||
|
this.$set(this, "updateWelfareListUnitInfoLoading", true)
|
||||||
|
$.post(loc() + "/updateWelfareListUnitInfo", {
|
||||||
|
projectId: this.pageForm.projectId
|
||||||
|
}).then((resp) => {
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.notifySuccess("福利信息修改成功,共更新" + resp.data + "条名单")
|
||||||
|
this.pageData()
|
||||||
|
} else {
|
||||||
|
this.notifyWarning(resp.msg)
|
||||||
|
}
|
||||||
|
}).always(() => {
|
||||||
|
this.$set(this, "updateWelfareListUnitInfoLoading", false)
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
},
|
||||||
receiveAddressChange(address, optionIndex) {
|
receiveAddressChange(address, optionIndex) {
|
||||||
this.$set(this.welfareOptions[optionIndex], "receiveAddress", address)
|
this.$set(this.welfareOptions[optionIndex], "receiveAddress", address)
|
||||||
this.$forceUpdate()
|
this.$forceUpdate()
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-button @click="openView(scope.row)" size="mini" type="primary">查看报名</el-button>
|
<el-button @click="openView(scope.row)" size="mini" type="primary">查看报名</el-button>
|
||||||
<!--# } #-->
|
<!--# } #-->
|
||||||
<!--# if(@shiro.hasRole('H04') || @shiro.hasRole('gh12')){ #-->
|
<!--# if(@shiro.hasRole('H04') || @shiro.hasRole('gh12')){ #-->
|
||||||
<el-button @click="openImport(scope.row)" size="mini" type="primary">导入</el-button>
|
<el-button :disabled="!isSignUpTime(scope.row)" @click="openImport(scope.row)" size="mini" type="primary">导入</el-button>
|
||||||
<el-button @click="openBm2(scope.row)" size="mini" type="primary">报名</el-button>
|
<el-button :disabled="!isSignUpTime(scope.row)" @click="openBm2(scope.row)" size="mini" type="primary">报名</el-button>
|
||||||
<!--# } #-->
|
<!--# } #-->
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -589,6 +589,12 @@ display: -webkit-box;
|
|||||||
"file-import": httpVueLoader("/components/plugins/FileImport.vue")
|
"file-import": httpVueLoader("/components/plugins/FileImport.vue")
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
isSignUpTime(row) {
|
||||||
|
const now = new Date().getTime()
|
||||||
|
const bmkssj = moment(row.bmkssj.valueOf())
|
||||||
|
const bmjzsj = moment(row.bmjzsj.valueOf())
|
||||||
|
return bmkssj <= now && now < bmjzsj
|
||||||
|
},
|
||||||
openImport() {
|
openImport() {
|
||||||
this.importDialog = true
|
this.importDialog = true
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user