diff --git a/src/main/java/com/ynxbd/common/action/test/TestAction.java b/src/main/java/com/ynxbd/common/action/test/TestAction.java index 5671697..bb4bfb1 100644 --- a/src/main/java/com/ynxbd/common/action/test/TestAction.java +++ b/src/main/java/com/ynxbd/common/action/test/TestAction.java @@ -1,26 +1,19 @@ package com.ynxbd.common.action.test; -import com.alibaba.fastjson.JSONObject; import com.ynxbd.common.action.base.BaseAction; import com.ynxbd.common.bean.sms.SmsTempEnum; import com.ynxbd.common.helper.common.DateHelper; -import com.ynxbd.common.helper.common.JsonHelper; import com.ynxbd.common.helper.common.SmsHelper; -import com.ynxbd.common.helper.http.OkHttpHelper; import com.ynxbd.common.result.Result; import com.ynxbd.common.result.ResultEnum; import com.ynxbd.common.result.ServiceException; import com.ynxbd.wx.config.WeChatConfig; -import com.ynxbd.wx.wxfactory.AesWxHelper; import com.ynxbd.wx.wxfactory.WxPayHelper; import com.ynxbd.wx.wxfactory.medical.WxMedConfig; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ObjectUtils; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; import java.util.Date; @@ -112,6 +105,9 @@ public class TestAction extends BaseAction { @Action("sms_test") public Result sms_test() throws ServiceException { + if (WeChatConfig.IS_DEV) { + SmsHelper.sendCode(SmsTempEnum.SMS_257021489.TEMP_CODE, "15559603353"); + } return Result.success(); } diff --git a/src/main/java/com/ynxbd/common/bean/UsageCount.java b/src/main/java/com/ynxbd/common/bean/UsageCount.java new file mode 100644 index 0000000..bcd5fe9 --- /dev/null +++ b/src/main/java/com/ynxbd/common/bean/UsageCount.java @@ -0,0 +1,37 @@ +package com.ynxbd.common.bean; + +// 使用次数统计 + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; + +@Setter +@Getter +@ToString +@NoArgsConstructor +public class UsageCount implements Serializable { + private static final long serialVersionUID = -20260212092100001L; + // id + private Long id; + // 系统类型 + private String sys; + // 系统业务 + private String sysService; + // 创建日期 + private String createDate; + // 最后一次修改时间 + private String updateTime; + // 标记[短信为签名] + private String mark; + // 备注 + private String remark; + // 使用次数 + private Integer usageCount; + // 成功次数 + private Integer failCount; + +} diff --git a/src/main/java/com/ynxbd/common/bean/UsageCountEnum.java b/src/main/java/com/ynxbd/common/bean/UsageCountEnum.java new file mode 100644 index 0000000..ecd1291 --- /dev/null +++ b/src/main/java/com/ynxbd/common/bean/UsageCountEnum.java @@ -0,0 +1,30 @@ +package com.ynxbd.common.bean; + +import lombok.ToString; + +@ToString +public enum UsageCountEnum { + MICRO_SMS("阿里云", "SMS", "阿里云短信"), + TZ_SMS("天助平台", "SMS", "天助平台短信"), + ; + + public final String SYS; + public final String SERVICE_CODE; + public final String NAME; + + UsageCountEnum(String SYS, String SERVICE_CODE, String NAME) { + this.SYS = SYS; + this.SERVICE_CODE = SERVICE_CODE; + this.NAME = NAME; + } + + public static UsageCountEnum toEnum(String serviceCode) { + for (UsageCountEnum item : UsageCountEnum.values()) { + if (item.SERVICE_CODE.equals(serviceCode)) { + return item; + } + } + return null; + } + +} diff --git a/src/main/java/com/ynxbd/common/dao/UsageCountDao.java b/src/main/java/com/ynxbd/common/dao/UsageCountDao.java new file mode 100644 index 0000000..c1b1f05 --- /dev/null +++ b/src/main/java/com/ynxbd/common/dao/UsageCountDao.java @@ -0,0 +1,46 @@ +package com.ynxbd.common.dao; + +import com.ynxbd.common.config.db.DataBase; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class UsageCountDao { + + /** + * 新增数据 + */ + public boolean insertToday(String sys, String sysService, String mark, Integer usageCount, boolean isFail) { + String sql = "insert into usage_count(createDate, updateTime, sys, sysService, mark, usageCount, failCount) values(now(), now(), ?, ?, ?, ?, ?)"; + return DataBase.insert(sql, ps -> { + ps.setString(1, sys); + ps.setString(2, sysService); + ps.setString(3, mark); + ps.setInt(4, usageCount); + ps.setInt(5, (isFail ? 1 : 0)); + }) > 0; + } + + /** + * 今日是否有数据 + */ + public boolean hasToday(String sys, String sysService) { + String sql = "select * from usage_count where createDate = DATE(now()) and sys= ? and sysService = ?"; + return !DataBase.select(sql, String.class, ps -> { + ps.setString(1, sys); + ps.setString(2, sysService); + }).isEmpty(); + } + + /** + * 修改使用次数 + */ + public boolean updateTodayCount(String sys, String sysService, String mark, boolean isFail) { + String failCount = isFail ? "(failCount + 1)" : "failCount"; + String sql = "update usage_count set mark=?, usageCount= (usageCount + 1), failCount= " + failCount + " where createDate= DATE(now()) and sys= ? and sysService = ?"; + return DataBase.update(sql, ps -> { + ps.setString(1, mark); + ps.setString(2, sys); + ps.setString(3, sysService); + }) > 0; + } +} diff --git a/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java b/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java index 4ad2612..24f95d8 100644 --- a/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java +++ b/src/main/java/com/ynxbd/common/helper/common/SmsHelper.java @@ -2,11 +2,13 @@ package com.ynxbd.common.helper.common; import com.aliyun.dysmsapi20170525.models.SendSmsRequest; import com.aliyun.dysmsapi20170525.models.SendSmsResponse; +import com.ynxbd.common.bean.UsageCountEnum; import com.ynxbd.common.bean.sms.SmsTempEnum; import com.ynxbd.common.bean.sms.SmsTemplate; import com.ynxbd.common.config.EhCacheConfig; import com.ynxbd.common.helper.ProperHelper; import com.ynxbd.common.helper.http.OkHttpHelper; +import com.ynxbd.common.service.UsageCountService; import lombok.extern.slf4j.Slf4j; import okhttp3.FormBody; import okhttp3.RequestBody; @@ -45,6 +47,10 @@ public class SmsHelper { } } + public static String getSmsSignName() { + return SmsHelper.SIGN_NAME == null ? null : ("【" + SmsHelper.SIGN_NAME + "】"); + } + /** * 通用-发送短信 * @@ -186,7 +192,10 @@ public class SmsHelper { // {"Message":"签名不合法(不存在或被拉黑)","RequestId":"B929C1F5-0DF6-4678-98B8-118060EFBC96","Code":"isv.SMS_SIGNATURE_ILLEGAL"} String respCode = sendSmsResponse.body.code; String respMessage = sendSmsResponse.body.message; - if (OK.equals(respCode) && OK.equals(respMessage)) { // 发送成功 + boolean isOk = OK.equals(respCode) && OK.equals(respMessage); + + new UsageCountService().updateUsageCount(UsageCountEnum.MICRO_SMS, getSmsSignName(), !isOk); // 人数统计 + if (isOk) { // 发送成功 return true; } @@ -221,6 +230,7 @@ public class SmsHelper { String result = OkHttpHelper.post("https://openapi.danmi.com/textSMS/sendSMS/V1", requestBody, headers -> { headers.add("content-type", "application/x-www-form-urlencoded"); }); + new UsageCountService().updateUsageCount(UsageCountEnum.TZ_SMS, null, true); // 人数统计 log.info("[天助平台] 短信发送 result-{},tel-{},templateId-{},content-{}", result, tel, templateId, content); return result; } diff --git a/src/main/java/com/ynxbd/wx/config/WeChatConfig.java b/src/main/java/com/ynxbd/wx/config/WeChatConfig.java index 6d89db9..2bb6080 100644 --- a/src/main/java/com/ynxbd/wx/config/WeChatConfig.java +++ b/src/main/java/com/ynxbd/wx/config/WeChatConfig.java @@ -41,6 +41,9 @@ public class WeChatConfig { // 判断链接是否有https public static final boolean HAS_HTTPS_BY_BASE_URL; + // 是否为测试环境(默认false) + public static final boolean IS_DEV; + // 医共体配置 public static final boolean IS_ENABLE_GMC; // 是否为医共体主服务 @@ -75,11 +78,12 @@ public class WeChatConfig { PASSWORD = config.getString("wx.password"); DEV_OPEN_IDS = config.getString("wx.dev_open_ids", ""); IS_RECIPE_PREPAY = config.getBoolean("wx.is_recipe_prepay", false); + IS_DEV = config.getBoolean("wx.is_dev", false); // 医共体 IS_ENABLE_GMC = config.getBoolean("wx.gmc.is_enable", false); -// GMC_AUTH_APP_ID = config.getString("wx.gmc.auth_app_id"); -// GMC_AUTH_APP_SECRET = config.getString("wx.gmc.auth_app_secret"); + // GMC_AUTH_APP_ID = config.getString("wx.gmc.auth_app_id"); + // GMC_AUTH_APP_SECRET = config.getString("wx.gmc.auth_app_secret"); GMC_AUTH_DOMAIN = config.getString("wx.gmc.auth_domain"); IS_GMC_SERVER = DOMAIN != null && DOMAIN.equals(GMC_AUTH_DOMAIN); diff --git a/src/main/java/com/ynxbd/wx/servlet/oldpay/QRPayServlet.java b/src/main/java/com/ynxbd/wx/servlet/oldpay/QRPayServlet.java index 2ed87a6..96e168e 100644 --- a/src/main/java/com/ynxbd/wx/servlet/oldpay/QRPayServlet.java +++ b/src/main/java/com/ynxbd/wx/servlet/oldpay/QRPayServlet.java @@ -83,7 +83,7 @@ public class QRPayServlet extends HttpServlet { String productId = notifyInfo.getProductId(); log.info("[Native]扫码支付 收到请求:product_id={}, openid={}", productId, openid); - if (!"XBD".equals(productId)) { + if (!productId.contains("XBD")) { log.info("[Native]扫码支付 不合规则的字符串,不允许支付!product_id={}", productId); HttpHelper.outRespAlert(response, "扫码支付:不合规则的字符串,不允许支付!"); return; diff --git a/src/main/java/com/ynxbd/wx/wxfactory/WxPayHelper.java b/src/main/java/com/ynxbd/wx/wxfactory/WxPayHelper.java index ffd375c..a3f1861 100644 --- a/src/main/java/com/ynxbd/wx/wxfactory/WxPayHelper.java +++ b/src/main/java/com/ynxbd/wx/wxfactory/WxPayHelper.java @@ -186,14 +186,7 @@ public class WxPayHelper { // 额外参数 unifiedorder.setAttach(notifyType); - log.info(appId + "," - + mchId + "," - + nonce + "," - + title + "," - + outTradeNo + "," - + totalFee + "," - + ip + "," - + merchantEnum.NOTIFY_URL); + log.info("【微信】统一下单 {},{},{},{},{},{},{},{}", appId, mchId, nonce, title, outTradeNo, totalFee, ip, merchantEnum.NOTIFY_URL); // 微信统一下单 UnifiedorderResult unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder, mchKey); @@ -372,15 +365,15 @@ public class WxPayHelper { order.setOpenid(openid); order.setBankTransNo(bankTransNo); - // 调用失败 - if (FAIL.equals(micropayResult.getReturn_code())) { // 失败 - log.info("【微信】[盒子支付]失败 outTradeNo={}, bankTransNo={}, returnCode={}, returnMsg={}", outTradeNo, bankTransNo, micropayResult.getReturn_code(), micropayResult.getReturn_msg()); + + if (FAIL.equals(micropayResult.getReturn_code())) { // 调用接口异常 + log.info("【微信】[盒子支付]调用接口异常 outTradeNo={}, bankTransNo={}, returnCode={}, returnMsg={}", outTradeNo, bankTransNo, micropayResult.getReturn_code(), micropayResult.getReturn_msg()); order.setErrorCode(micropayResult.getReturn_code()); order.setErrorMsg(micropayResult.getReturn_msg()); return order; } - if (FAIL.equals(resultCode)) { // 失败 + if (FAIL.equals(resultCode)) { // 返回信息为[失败|等待支付] if (USER_PAYING.equals(errCode)) { // 密码支付 log.info("【微信】[盒子支付]密码支付 outTradeNo={}, msg={}", outTradeNo, errMsg); wxOrder = waitMicoPay(outTradeNo); @@ -390,7 +383,7 @@ public class WxPayHelper { } else { order.setErrorCode(errCode); order.setErrorMsg(errMsg); - log.info("【微信】[盒子支付]失败 outTradeNo={}, bankTransNo={}, errCode={}, errMsg={}", outTradeNo, bankTransNo, errCode, errMsg); + log.info("【微信】[盒子支付]支付失败 outTradeNo={}, bankTransNo={}, errCode={}, errMsg={}", outTradeNo, bankTransNo, errCode, errMsg); return order; } } @@ -420,20 +413,37 @@ public class WxPayHelper { // 等待扫码盒子支付 private static Order waitMicoPay(String outTradeNo) { Order wxOrder; - for (int i = 1; i <= 5; i++) { + long begTime = System.currentTimeMillis(); // 开始时间 + long endTime, takeTime, apiBegTime, apiEndTime; + for (int i = 1; i <= 7; i++) { try { - Thread.sleep(5000 + ((i - 1) * 1500)); // 总共35s + Thread.sleep(3000 + ((i - 1) * 500)); // 总共31.5s=[3, 3.5, 4, 4.5, 5, 5.5, 6] + apiBegTime = System.currentTimeMillis(); // 接口调用开始时间 wxOrder = queryOrder(outTradeNo); + apiEndTime = System.currentTimeMillis(); // 接口调用结束时间 + log.info("【微信】[盒子支付]订单查询[第[{}]次]接口调用耗时:[{}ms] outTradeNo={}", i, (apiEndTime - apiBegTime), outTradeNo); + if (wxOrder.isSuccess()) { + endTime = System.currentTimeMillis(); // 结束时间 + takeTime = (endTime - begTime); + if (takeTime > 15000) { // 耗时超过15s + log.warn("【微信】[盒子支付]支付成功 耗时超过15s[查询[{}]次]耗时:[{}ms] outTradeNo={}", i, takeTime, outTradeNo); + } + log.info("【微信】[盒子支付]支付成功 [查询[{}]次]耗时:[{}ms] outTradeNo={}", i, takeTime, outTradeNo); return wxOrder; } // 支付失败 if (PAY_ERROR.equals(wxOrder.getTradeState())) { - if (i == 1 || i == 2) { - Thread.sleep(i == 2 ? 3000 : 9000); // 等够15s + if (i == 1) { + Thread.sleep(9000); // 等够12s + } else if (i == 2) { + Thread.sleep(6000); // 等够12.5s } + endTime = System.currentTimeMillis(); // 结束时间 + + log.info("【微信】[盒子支付]撤销订单 [查询[{}]次]耗时:[{}ms] outTradeNo={}", i, (endTime - begTime), outTradeNo); // 撤销订单 Order cancelOrder = cancelOrder(wxOrder.getOutTradeNo(), wxOrder.getBankTransNo()); // 撤销成功 @@ -449,7 +459,7 @@ public class WxPayHelper { return wxOrder; } } catch (Exception e) { - e.printStackTrace(); + ErrorHelper.println(e); } } return null; @@ -1199,14 +1209,7 @@ public class WxPayHelper { // 额外参数 unifiedorder.setAttach(notifyType); - log.info(appId + "," - + mchId + "," - + nonce + "," - + title + "," - + outTradeNo + "," - + totalFee + "," - + ip + "," - + notifyUrl); + log.info("【微信】Native下单 {},{},{},{},{},{},{},{}", appId, mchId, nonce, title, outTradeNo, totalFee, ip, notifyUrl); // 微信统一下单 UnifiedorderResult unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder, mchKey); @@ -1234,7 +1237,7 @@ public class WxPayHelper { wxNativePayResult.setPrepayId(prepayId); return wxNativePayResult; } catch (Exception e) { - log.error("【微信】统一下单异常信息:" + e.getMessage()); + log.error("【微信】统一下单异常信息:{}", e.getMessage()); ErrorHelper.println(e); } return null;