diff --git a/src/main/java/com/ynxbd/common/service/UsageCountService.java b/src/main/java/com/ynxbd/common/service/UsageCountService.java new file mode 100644 index 0000000..2f479a7 --- /dev/null +++ b/src/main/java/com/ynxbd/common/service/UsageCountService.java @@ -0,0 +1,31 @@ +package com.ynxbd.common.service; + +import com.ynxbd.common.bean.UsageCountEnum; +import com.ynxbd.common.dao.UsageCountDao; +import com.ynxbd.common.helper.common.ErrorHelper; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class UsageCountService { + + + /** + * [使用人数统计]修改使用人数 + * + * @param usageCountEnum 业务枚举 + * @param isFail 是否成功 + */ + public void updateUsageCount(UsageCountEnum usageCountEnum, String mark, boolean isFail) { + try { + UsageCountDao usageCountDao = new UsageCountDao(); + boolean hasToday = usageCountDao.hasToday(usageCountEnum.SYS, usageCountEnum.SERVICE_CODE); + if (hasToday) { + usageCountDao.updateTodayCount(usageCountEnum.SYS, usageCountEnum.SERVICE_CODE, mark, isFail); + } else { + usageCountDao.insertToday(usageCountEnum.SYS, usageCountEnum.SERVICE_CODE, mark, 1, isFail); + } + } catch (Exception e) { + ErrorHelper.println(e); + } + } +} diff --git a/src/main/java/com/ynxbd/wx/wxfactory/medins/models/CreateOrder.java b/src/main/java/com/ynxbd/wx/wxfactory/medins/models/CreateOrder.java new file mode 100644 index 0000000..142159e --- /dev/null +++ b/src/main/java/com/ynxbd/wx/wxfactory/medins/models/CreateOrder.java @@ -0,0 +1,435 @@ +package com.ynxbd.wx.wxfactory.medins.models; + +import com.google.gson.annotations.SerializedName; +import com.ynxbd.wx.wxfactory.payment.WXPayUtility; +import okhttp3.*; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.List; + +/** + * 医保自费混合收款下单 + */ +public class CreateOrder { + private final String mchid; + private final String certificateSerialNo; + private final PrivateKey privateKey; + private final String wechatPayPublicKeyId; + private final PublicKey wechatPayPublicKey; + + public CreateOrder() { + this.mchid = null; + this.certificateSerialNo = null; + this.privateKey = WXPayUtility.loadPrivateKeyFromPath(null); + this.wechatPayPublicKeyId = null; + this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(null); + } + + public CreateOrder(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) { + this.mchid = mchid; + this.certificateSerialNo = certificateSerialNo; + this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath); + this.wechatPayPublicKeyId = wechatPayPublicKeyId; + this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath); + } + + public String encrypt(String plainText) { + return WXPayUtility.encrypt(this.wechatPayPublicKey, plainText); + } + + private static String HOST = "https://api.mch.weixin.qq.com"; + private static String METHOD = "POST"; + + public CreateOrder.OrderEntity run(String uri, CreateOrder.CreateOrderRequest request) { + String reqBody = WXPayUtility.toJson(request); + + Request.Builder reqBuilder = new Request.Builder().url(HOST + uri); + reqBuilder.addHeader("Accept", "application/json"); + reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId); + reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo, privateKey, METHOD, uri, reqBody)); + reqBuilder.addHeader("Content-Type", "application/json"); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody); + reqBuilder.method(METHOD, requestBody); + Request httpRequest = reqBuilder.build(); + + // 发送HTTP请求 + OkHttpClient client = new OkHttpClient.Builder().build(); + try (Response httpResponse = client.newCall(httpRequest).execute()) { + String respBody = WXPayUtility.extractBody(httpResponse); + if (httpResponse.code() >= 200 && httpResponse.code() < 300) { + // 2XX 成功,验证应答签名 + WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey, + httpResponse.headers(), respBody); + + // 从HTTP应答报文构建返回数据 + return WXPayUtility.fromJson(respBody, CreateOrder.OrderEntity.class); + } else { + throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers()); + } + } catch (IOException e) { + throw new UncheckedIOException("Sending request to " + uri + " failed.", e); + } + } + + public static class CreateOrderRequest { + @SerializedName("mix_pay_type") + public MixPayType mixPayType; + + @SerializedName("order_type") + public OrderType orderType; + + @SerializedName("appid") + public String appid; + + @SerializedName("openid") + public String openid; + + @SerializedName("payer") + public PersonIdentification payer; + + @SerializedName("pay_for_relatives") + public Boolean payForRelatives; + + @SerializedName("relative") + public PersonIdentification relative; + + @SerializedName("out_trade_no") + public String outTradeNo; + + @SerializedName("serial_no") + public String serialNo; + + @SerializedName("pay_order_id") + public String payOrderId; + + @SerializedName("pay_auth_no") + public String payAuthNo; + + @SerializedName("geo_location") + public String geoLocation; + + @SerializedName("city_id") + public String cityId; + + @SerializedName("med_inst_name") + public String medInstName; + + @SerializedName("med_inst_no") + public String medInstNo; + + @SerializedName("med_ins_order_create_time") + public String medInsOrderCreateTime; + + @SerializedName("total_fee") + public Long totalFee; + + @SerializedName("med_ins_gov_fee") + public Long medInsGovFee; + + @SerializedName("med_ins_self_fee") + public Long medInsSelfFee; + + @SerializedName("med_ins_other_fee") + public Long medInsOtherFee; + + @SerializedName("med_ins_cash_fee") + public Long medInsCashFee; + + @SerializedName("wechat_pay_cash_fee") + public Long wechatPayCashFee; + + @SerializedName("cash_add_detail") + public List cashAddDetail; + + @SerializedName("cash_reduce_detail") + public List cashReduceDetail; + + @SerializedName("callback_url") + public String callbackUrl; + + @SerializedName("prepay_id") + public String prepayId; + + @SerializedName("passthrough_request_content") + public String passthroughRequestContent; + + @SerializedName("extends") + public String _extends; + + @SerializedName("attach") + public String attach; + + @SerializedName("channel_no") + public String channelNo; + + @SerializedName("med_ins_test_env") + public Boolean medInsTestEnv; + } + + public static class OrderEntity { + @SerializedName("mix_trade_no") + public String mixTradeNo; + + @SerializedName("mix_pay_status") + public MixPayStatus mixPayStatus; + + @SerializedName("self_pay_status") + public SelfPayStatus selfPayStatus; + + @SerializedName("med_ins_pay_status") + public MedInsPayStatus medInsPayStatus; + + @SerializedName("paid_time") + public String paidTime; + + @SerializedName("passthrough_response_content") + public String passthroughResponseContent; + + @SerializedName("mix_pay_type") + public MixPayType mixPayType; + + @SerializedName("order_type") + public OrderType orderType; + + @SerializedName("appid") + public String appid; + + @SerializedName("openid") + public String openid; + + @SerializedName("pay_for_relatives") + public Boolean payForRelatives; + + @SerializedName("out_trade_no") + public String outTradeNo; + + @SerializedName("serial_no") + public String serialNo; + + @SerializedName("pay_order_id") + public String payOrderId; + + @SerializedName("pay_auth_no") + public String payAuthNo; + + @SerializedName("geo_location") + public String geoLocation; + + @SerializedName("city_id") + public String cityId; + + @SerializedName("med_inst_name") + public String medInstName; + + @SerializedName("med_inst_no") + public String medInstNo; + + @SerializedName("med_ins_order_create_time") + public String medInsOrderCreateTime; + + @SerializedName("total_fee") + public Long totalFee; + + @SerializedName("med_ins_gov_fee") + public Long medInsGovFee; + + @SerializedName("med_ins_self_fee") + public Long medInsSelfFee; + + @SerializedName("med_ins_other_fee") + public Long medInsOtherFee; + + @SerializedName("med_ins_cash_fee") + public Long medInsCashFee; + + @SerializedName("wechat_pay_cash_fee") + public Long wechatPayCashFee; + + @SerializedName("cash_add_detail") + public List cashAddDetail; + + @SerializedName("cash_reduce_detail") + public List cashReduceDetail; + + @SerializedName("callback_url") + public String callbackUrl; + + @SerializedName("prepay_id") + public String prepayId; + + @SerializedName("passthrough_request_content") + public String passthroughRequestContent; + + @SerializedName("extends") + public String _extends; + + @SerializedName("attach") + public String attach; + + @SerializedName("channel_no") + public String channelNo; + + @SerializedName("med_ins_test_env") + public Boolean medInsTestEnv; + + @SerializedName("med_ins_fail_reason") + public String medInsFailReason; + } + + + // 混合支付类型 + public enum MixPayType { + @SerializedName("UNKNOWN_MIX_PAY_TYPE") + UNKNOWN_MIX_PAY_TYPE, // 未知的混合支付类型,会被拦截。 + @SerializedName("CASH_ONLY") + CASH_ONLY, // 只向微信支付下单,没有向医保局下单。包括没有向医保局上传费用明细、预结算。 + @SerializedName("INSURANCE_ONLY") + INSURANCE_ONLY, // 只向医保局下单,没有向微信支付下单。如果医保局分账结果中有自费部份,但由于有减免抵扣,没有向微信支付下单,也是纯医保。 + @SerializedName("CASH_AND_INSURANCE") + CASH_AND_INSURANCE // 向医保局下单,也向微信支付下单。如果医保预结算全部需自费,也属于混合类型。 + } + + public enum OrderType { + @SerializedName("UNKNOWN_ORDER_TYPE") + UNKNOWN_ORDER_TYPE, + @SerializedName("REG_PAY") + REG_PAY, + @SerializedName("DIAG_PAY") + DIAG_PAY, + @SerializedName("COVID_EXAM_PAY") + COVID_EXAM_PAY, + @SerializedName("IN_HOSP_PAY") + IN_HOSP_PAY, + @SerializedName("PHARMACY_PAY") + PHARMACY_PAY, + @SerializedName("INSURANCE_PAY") + INSURANCE_PAY, + @SerializedName("INT_REG_PAY") + INT_REG_PAY, + @SerializedName("INT_RE_DIAG_PAY") + INT_RE_DIAG_PAY, + @SerializedName("INT_RX_PAY") + INT_RX_PAY, + @SerializedName("COVID_ANTIGEN_PAY") + COVID_ANTIGEN_PAY, + @SerializedName("MED_PAY") + MED_PAY + } + + public static class PersonIdentification { + @SerializedName("name") + public String name; + + @SerializedName("id_digest") + public String idDigest; + + @SerializedName("card_type") + public UserCardType cardType; + } + + public static class CashAddEntity { + @SerializedName("cash_add_fee") + public Long cashAddFee; + + @SerializedName("cash_add_type") + public CashAddType cashAddType; + } + + public static class CashReduceEntity { + @SerializedName("cash_reduce_fee") + public Long cashReduceFee; + + @SerializedName("cash_reduce_type") + public CashReduceType cashReduceType; + } + + public enum MixPayStatus { + @SerializedName("UNKNOWN_MIX_PAY_STATUS") + UNKNOWN_MIX_PAY_STATUS, + @SerializedName("MIX_PAY_CREATED") + MIX_PAY_CREATED, + @SerializedName("MIX_PAY_SUCCESS") + MIX_PAY_SUCCESS, + @SerializedName("MIX_PAY_REFUND") + MIX_PAY_REFUND, + @SerializedName("MIX_PAY_FAIL") + MIX_PAY_FAIL + } + + public enum SelfPayStatus { + @SerializedName("UNKNOWN_SELF_PAY_STATUS") + UNKNOWN_SELF_PAY_STATUS, + @SerializedName("SELF_PAY_CREATED") + SELF_PAY_CREATED, + @SerializedName("SELF_PAY_SUCCESS") + SELF_PAY_SUCCESS, + @SerializedName("SELF_PAY_REFUND") + SELF_PAY_REFUND, + @SerializedName("SELF_PAY_FAIL") + SELF_PAY_FAIL, + @SerializedName("NO_SELF_PAY") + NO_SELF_PAY + } + + public enum MedInsPayStatus { + @SerializedName("UNKNOWN_MED_INS_PAY_STATUS") + UNKNOWN_MED_INS_PAY_STATUS, + @SerializedName("MED_INS_PAY_CREATED") + MED_INS_PAY_CREATED, + @SerializedName("MED_INS_PAY_SUCCESS") + MED_INS_PAY_SUCCESS, + @SerializedName("MED_INS_PAY_REFUND") + MED_INS_PAY_REFUND, + @SerializedName("MED_INS_PAY_FAIL") + MED_INS_PAY_FAIL, + @SerializedName("NO_MED_INS_PAY") + NO_MED_INS_PAY + } + + public enum UserCardType { + @SerializedName("UNKNOWN_USER_CARD_TYPE") + UNKNOWN_USER_CARD_TYPE, + @SerializedName("ID_CARD") + ID_CARD, + @SerializedName("HOUSEHOLD_REGISTRATION") + HOUSEHOLD_REGISTRATION, + @SerializedName("FOREIGNER_PASSPORT") + FOREIGNER_PASSPORT, + @SerializedName("MAINLAND_TRAVEL_PERMIT_FOR_TW") + MAINLAND_TRAVEL_PERMIT_FOR_TW, + @SerializedName("MAINLAND_TRAVEL_PERMIT_FOR_MO") + MAINLAND_TRAVEL_PERMIT_FOR_MO, + @SerializedName("MAINLAND_TRAVEL_PERMIT_FOR_HK") + MAINLAND_TRAVEL_PERMIT_FOR_HK, + @SerializedName("FOREIGN_PERMANENT_RESIDENT") + FOREIGN_PERMANENT_RESIDENT + } + + public enum CashAddType { + @SerializedName("DEFAULT_ADD_TYPE") + DEFAULT_ADD_TYPE, + @SerializedName("FREIGHT") + FREIGHT, + @SerializedName("OTHER_MEDICAL_EXPENSES") + OTHER_MEDICAL_EXPENSES + } + + public enum CashReduceType { + @SerializedName("DEFAULT_REDUCE_TYPE") + DEFAULT_REDUCE_TYPE, + @SerializedName("HOSPITAL_REDUCE") + HOSPITAL_REDUCE, + @SerializedName("PHARMACY_DISCOUNT") + PHARMACY_DISCOUNT, + @SerializedName("DISCOUNT") + DISCOUNT, + @SerializedName("PRE_PAYMENT") + PRE_PAYMENT, + @SerializedName("DEPOSIT_DEDUCTION") + DEPOSIT_DEDUCTION + } + +} \ No newline at end of file