Przeglądaj źródła

feature: 医疗行业数据同步集成方案接入,提供接口

Walker 2 lat temu
rodzic
commit
84e664e9cb

+ 20 - 7
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/EmptyApplication.java

@@ -2,7 +2,12 @@ package com.ywt.alipaympapi;
 
 import com.alipay.easysdk.factory.Factory;
 import com.alipay.easysdk.kernel.Config;
+import com.ywt.alipaympapi.core.utils.BizUtil;
+import com.ywt.alipaympapi.core.utils.Checker;
 import com.ywt.alipaympapi.models.Constants;
+import com.ywt.alipaympapi.models.auth.AlipayMpCfg;
+import com.ywt.alipaympapi.models.enums.TerminalEnum;
+import com.ywt.core.exception.AppMessageException;
 import com.ywt.rpc.core.RestServerStarter;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -22,7 +27,7 @@ public class EmptyApplication {
 
     /**
      * 初始化 alipay-easy-sdk
-     * FIXME: 后续扩展多医院需要将 pk & apk 配置化
+     * TODO: 后续扩展多医院需要将 pk & apk 配置化
      */
     private static void initAlipayEasySdk() {
         Config config = new Config();
@@ -30,11 +35,19 @@ public class EmptyApplication {
         config.gatewayHost = "openapi.alipay.com";
         config.signType = "RSA2";
 
-        config.appId = Constants.ALIPAYMP_APPID_NFYYBYFY;
-        // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中
-        config.merchantPrivateKey = Constants.MERCHANT_PRIVATE_KEY;
-        // 注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可
-        config.alipayPublicKey = Constants.ALIPAY_PUBLIC_KEY;
-        Factory.setOptions(config);
+        try {
+            AlipayMpCfg cfg = BizUtil.getCfg(TerminalEnum.NFYYBYFY_ALIPAY_MP.getValue());
+            config.appId = Checker.getStringValue(cfg.getAppId());
+            // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中
+            config.merchantPrivateKey = Checker.getStringValue(cfg.getMerchantPrivateKey());
+            // 注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可
+            config.alipayPublicKey = Checker.getStringValue(cfg.getPublicKey());
+            Factory.setOptions(config);
+        } catch (AppMessageException e) {
+            System.out.println("EmptyApplication#initAlipayEasySdk(): 获取配置失败" + e.getMessage());
+            e.printStackTrace();
+        }
+
+
     }
 }

+ 33 - 0
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/core/utils/BizUtil.java

@@ -2,10 +2,12 @@ package com.ywt.alipaympapi.core.utils;
 
 import com.ywt.alipaympapi.core.ConstantDef;
 import com.ywt.alipaympapi.models.Constants;
+import com.ywt.alipaympapi.models.auth.AlipayMpCfg;
 import com.ywt.alipaympapi.models.checkIn.CheckInConstants;
 import com.ywt.alipaympapi.models.enums.TerminalEnum;
 import com.ywt.alipaympapi.models.union_reg.HospitalCustomInfo;
 import com.ywt.alipaympapi.web.interceptors.WebAppContext;
+import com.ywt.core.exception.AppMessageException;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -248,4 +250,35 @@ public final class BizUtil {
         i.setAreaName(area);
         return i;
     }
+
+    /**
+     * 根据终端获取不同小程序的配置
+     * TODO: 后续多医院支持需要改成配置化
+     */
+    public static AlipayMpCfg getCfg(int terminal) throws AppMessageException {
+        if (TerminalEnum.valueOf(terminal) == TerminalEnum.NFYYBYFY_ALIPAY_MP) {
+            return getCfg4Nfyybyfy();
+        }
+        throw new AppMessageException(String.format("Unsupported terminal %d", terminal));
+    }
+
+    // 获取所有支持的小程序配置
+    public static List<AlipayMpCfg> getAllCfgs() {
+        List<AlipayMpCfg> list = new ArrayList<>();
+        list.add(getCfg4Nfyybyfy());
+        return list;
+    }
+
+    // 白云分院小程序配置数据
+    private static AlipayMpCfg getCfg4Nfyybyfy() {
+        AlipayMpCfg cfg = new AlipayMpCfg();
+        cfg.setAppId(Constants.ALIPAYMP_APPID_NFYYBYFY);
+        cfg.setSaasSecurityKey(Constants.ALIPAYMP_SAAS_SEC_KEY_NFYYBYFY);
+        cfg.setIsvPid(Constants.ALIPAYMP_ISV_PID_NFYYBYFY);
+        cfg.setMerchantPrivateKey(Constants.MERCHANT_PRIVATE_KEY_NFYYBYFY);
+        cfg.setPublicKey(Constants.ALIPAY_PUBLIC_KEY_NFYYBYFY);
+        cfg.setHospitalId(Constants.HOSPITAL_ID_NFYYBYFY);
+        cfg.setTerminal(TerminalEnum.NFYYBYFY_ALIPAY_MP.getValue());
+        return cfg;
+    }
 }

+ 13 - 5
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/face/impl/AlipayService.java

@@ -4,11 +4,17 @@ import com.alipay.api.AlipayClient;
 import com.alipay.api.AlipayRequest;
 import com.alipay.api.AlipayResponse;
 import com.alipay.api.DefaultAlipayClient;
+import com.ywt.alipaympapi.core.utils.BizUtil;
+import com.ywt.alipaympapi.core.utils.Checker;
 import com.ywt.alipaympapi.face.IAlipayService;
 import com.ywt.alipaympapi.models.Constants;
+import com.ywt.alipaympapi.models.auth.AlipayMpCfg;
+import com.ywt.core.exception.AppMessageException;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
+import java.util.List;
+
 /**
  * 支付宝服务实现
  */
@@ -49,13 +55,15 @@ public class AlipayService implements IAlipayService {
     }
 
     /**
-     * 构造 AlipayClient,调用 AlipaySDK。有些业务场景(如“智能”消息)下用 EasySDK 调不通,只能使用普通 SDK
+     * 根据 appId 构造 AlipayClient,调用 AlipaySDK。有些业务场景(如“智能”消息)下用 EasySDK 调不通,只能使用普通 SDK
      * @param appId 小程序 appId
-     * FIXME: 后续扩展多医院需要将 pk & apk 配置化
      */
-    public AlipayClient getAlipayClient(String appId) {
-        String pk = Constants.MERCHANT_PRIVATE_KEY;
-        String apk = Constants.ALIPAY_PUBLIC_KEY;
+    public AlipayClient getAlipayClient(String appId) throws AppMessageException {
+        List<AlipayMpCfg> cfgs = BizUtil.getAllCfgs();
+        AlipayMpCfg cfg = cfgs.stream().filter(i -> Checker.getStringValue(i.getAppId()).equals(appId)).findFirst().orElse(null);
+        if (cfg == null) throw new AppMessageException("配置有误,找不到 appId " + appId);
+        String pk = Checker.getStringValue(cfg.getMerchantPrivateKey());
+        String apk = Checker.getStringValue(cfg.getPublicKey());
         //实例化客户端
         return new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", appId, pk, "json", "UTF-8", apk, "RSA2");
     }

+ 6 - 2
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/models/Constants.java

@@ -12,9 +12,11 @@ public class Constants {
 
     public static final int TAIHE_HOSPITAL_ID = 12;
 
+    // 支付宝小程序配置常量
     public static final String ALIPAYMP_APPID_NFYYBYFY = "2021003141662056";
-    public static final String MERCHANT_PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTrydAgG5HUwvoYE6L4WFlgIhX2fKPEFvlpDyCremBPk5Zp3OMpoj3cfcd36Im/0MndQII90hErcRqfUEPJhw+F2CSBpxkLTb/7J1iRyUiKjv5G+24qG4FQIo/yc0o7xQsNLJR7McbS3ROuuPg1jN5qL8XKCPxCHEL5QzzJCVp+Jz+GKeGYPPmPdALC1nxgOKjYjpJrwOGtaU+7WuaB9SVz98xU3FocLFDTqE0MCQySOxxB0CZgBEPahp2l2B6FcMBoRok2p1ODIlN1ihfEEIrAU9rmso7swxEo65oaCuZu/bkH1FvmcayjMJ0xBir8pBh96tKt8loU++LY9y1rq6tAgMBAAECggEAAqvUJ/k26wl+PflxJEy8yOYdUlZ6vBltv3EaHmAJcUsS/Aij6aN0WQMEJklbJ3jTJR1R4EEWlV9H+jwIZSOK+bGb01vn/0+ewQ4AUmwpaMv1o8gZcNoXQVO2KuXmA904ePJVSbleLdb+6btsArtRPPjHKIimI3WCz66dQjgzjKnDloaaDIrx6bi3J0GOxzRGfMTMTuqhr6cm1OWCgSIFK+jTj61o7eIx1ZYY3OorApS9Q5CF3OHAXn6ignBxdvuyzDfA9VNMihrnuDcWy674mMOciu6TYx4Y0nwpFedKU29uR5Scgr0DGQFeLBSZmyd5kblDTu/CF5sFK5kr7H2pYQKBgQD3guHqAeObnItkmLdJfOkdfcoSmS5UZeyyyaJitjCbUGydJPUA8RipYKCM4rhRQYZvyIWwo52BahhzwGrp+3gdQWOQ6SRVXZXQVwsvWfkWaVkgRxeM0GASsFAnSjoHEEfRNifWRPcCSzSrvr0W+X7Wjc9XSiafOaKPuJeyTrVHiQKBgQDa8ba3l1/L2q6+al6UFsgn4WeIDHVaiDnIp1W+tT7UYPBEraedke1SjjGACfOrFfvNW35Vo6nV1olekB0D1AB2alLXN0x0swjit2TRKHOj8eH5uzplcktBNygDicnG09JW5RnQL21D7xf01L5b2lv52DvR7anrikkf3TdrNAbBBQKBgESm9wazU3CcMUXL3jrx/K8DbwNNnb4nL0pAB1yd8EmEOzwzPgnu1cpVVPL/B+Tx6dojooFmQI/e371rh7wy1hQ3SOiu4jcTaDSLkDyoFiETQ3digLO8MIm+gd0EB6hh6amr/cy/AEyQk6F3nHc86OOWHga2OJQ9pkt7BgidMEcRAoGBAKE9MVqzWBFA0z/YBh75SB5WmXBP/HzXpfZnhXYU9Fhjq45odPBN74DExx+MNK7iWbY6kyduiDy66h+B8lxHXK/YTXnBd8TZtMmCVfTS3Zb3I3xOrgrXySQWApnYd4i9pkHoJsJyqv1Er1fW9PmgLewpmqRXarPT+1ZEC/QfNHohAoGBAOpKX5QeQfk3x9ae6Wtvuw5hdF0aPaWpimPAFion5jqINoJc13gMo1YhU2eUMwvw8kkB/edvAp12EFRb7Esza4ZXc7uDWnYMPh8Wx8iHBEKxpUneNADmxpo2LXO+AXE4ZgIojeUSYPAGSHb16uG15lxamLqlLIJ44FR+1F86jk4L";
-    public static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtUtjYn+V60um6GVF0ezsI4NCI8QAiM8BT7SQda3RDzIssPbU5U3GJo/5bbu+k+pOpCOUlGVve2VoO+AXMWizCA8U/RleN7fNE09yw7RdLfLssNp6J4zGfBHQBWMiTrJvGZ4LzZHiwJgf28CGwcovjAK6M8bjF30k5ChQ8YIi+YYuer8yae7XfORLiSTByakglURlVUZF7QgbLph9i/OBk83HribZh+B/n97vavrAUyTjbDE3TMsINsAfMSY1omweXuvqjndYI+XmiBM4nBPHlPsXEeaF9TE8LuIqWm5mnRKWa/0I31RkE+W19tFUx5mF3oHw6SvyVuUQVx0HWGIPKQIDAQAB";
+    public static final String ALIPAYMP_ISV_PID_NFYYBYFY = "2088441568067687";
+    public static final String MERCHANT_PRIVATE_KEY_NFYYBYFY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTrydAgG5HUwvoYE6L4WFlgIhX2fKPEFvlpDyCremBPk5Zp3OMpoj3cfcd36Im/0MndQII90hErcRqfUEPJhw+F2CSBpxkLTb/7J1iRyUiKjv5G+24qG4FQIo/yc0o7xQsNLJR7McbS3ROuuPg1jN5qL8XKCPxCHEL5QzzJCVp+Jz+GKeGYPPmPdALC1nxgOKjYjpJrwOGtaU+7WuaB9SVz98xU3FocLFDTqE0MCQySOxxB0CZgBEPahp2l2B6FcMBoRok2p1ODIlN1ihfEEIrAU9rmso7swxEo65oaCuZu/bkH1FvmcayjMJ0xBir8pBh96tKt8loU++LY9y1rq6tAgMBAAECggEAAqvUJ/k26wl+PflxJEy8yOYdUlZ6vBltv3EaHmAJcUsS/Aij6aN0WQMEJklbJ3jTJR1R4EEWlV9H+jwIZSOK+bGb01vn/0+ewQ4AUmwpaMv1o8gZcNoXQVO2KuXmA904ePJVSbleLdb+6btsArtRPPjHKIimI3WCz66dQjgzjKnDloaaDIrx6bi3J0GOxzRGfMTMTuqhr6cm1OWCgSIFK+jTj61o7eIx1ZYY3OorApS9Q5CF3OHAXn6ignBxdvuyzDfA9VNMihrnuDcWy674mMOciu6TYx4Y0nwpFedKU29uR5Scgr0DGQFeLBSZmyd5kblDTu/CF5sFK5kr7H2pYQKBgQD3guHqAeObnItkmLdJfOkdfcoSmS5UZeyyyaJitjCbUGydJPUA8RipYKCM4rhRQYZvyIWwo52BahhzwGrp+3gdQWOQ6SRVXZXQVwsvWfkWaVkgRxeM0GASsFAnSjoHEEfRNifWRPcCSzSrvr0W+X7Wjc9XSiafOaKPuJeyTrVHiQKBgQDa8ba3l1/L2q6+al6UFsgn4WeIDHVaiDnIp1W+tT7UYPBEraedke1SjjGACfOrFfvNW35Vo6nV1olekB0D1AB2alLXN0x0swjit2TRKHOj8eH5uzplcktBNygDicnG09JW5RnQL21D7xf01L5b2lv52DvR7anrikkf3TdrNAbBBQKBgESm9wazU3CcMUXL3jrx/K8DbwNNnb4nL0pAB1yd8EmEOzwzPgnu1cpVVPL/B+Tx6dojooFmQI/e371rh7wy1hQ3SOiu4jcTaDSLkDyoFiETQ3digLO8MIm+gd0EB6hh6amr/cy/AEyQk6F3nHc86OOWHga2OJQ9pkt7BgidMEcRAoGBAKE9MVqzWBFA0z/YBh75SB5WmXBP/HzXpfZnhXYU9Fhjq45odPBN74DExx+MNK7iWbY6kyduiDy66h+B8lxHXK/YTXnBd8TZtMmCVfTS3Zb3I3xOrgrXySQWApnYd4i9pkHoJsJyqv1Er1fW9PmgLewpmqRXarPT+1ZEC/QfNHohAoGBAOpKX5QeQfk3x9ae6Wtvuw5hdF0aPaWpimPAFion5jqINoJc13gMo1YhU2eUMwvw8kkB/edvAp12EFRb7Esza4ZXc7uDWnYMPh8Wx8iHBEKxpUneNADmxpo2LXO+AXE4ZgIojeUSYPAGSHb16uG15lxamLqlLIJ44FR+1F86jk4L";
+    public static final String ALIPAY_PUBLIC_KEY_NFYYBYFY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtUtjYn+V60um6GVF0ezsI4NCI8QAiM8BT7SQda3RDzIssPbU5U3GJo/5bbu+k+pOpCOUlGVve2VoO+AXMWizCA8U/RleN7fNE09yw7RdLfLssNp6J4zGfBHQBWMiTrJvGZ4LzZHiwJgf28CGwcovjAK6M8bjF30k5ChQ8YIi+YYuer8yae7XfORLiSTByakglURlVUZF7QgbLph9i/OBk83HribZh+B/n97vavrAUyTjbDE3TMsINsAfMSY1omweXuvqjndYI+XmiBM4nBPHlPsXEeaF9TE8LuIqWm5mnRKWa/0I31RkE+W19tFUx5mF3oHw6SvyVuUQVx0HWGIPKQIDAQAB";
     public static final String ALIPAYMP_SAAS_SEC_KEY_NFYYBYFY = "LdYnclVYOKdN5NRDbTDVyXbQiBQiysOQ";
 
     public static final String DOCTOR_AVATAR_URL = "http://ywt-image.oss-cn-shenzhen.aliyuncs.com/doctor/avatar/default.png?x-oss-process=image/resize,h_180,w_180";
@@ -23,4 +25,6 @@ public class Constants {
 
     // 支付宝 accessToken Redis key,第一个参数是 appId,第二个参数 alipayUid
     public static final String RK_ACCESS_TOKEN = "ALI_TOKEN_%s_%s";
+    // 支付宝接口调用成功状态码
+    public static final String ALIPAY_SUCCESS_CODE = "10000";
 }

+ 5 - 0
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/models/auth/AlipayMpCfg.java

@@ -10,4 +10,9 @@ import lombok.Data;
 public class AlipayMpCfg {
     private String appId; // 支付宝小程序 appId
     private String saasSecurityKey; // 支付宝小程序管理后台的 SecurityKey
+    private String isvPid;
+    private String merchantPrivateKey;
+    private String publicKey;
+    private int hospitalId;
+    private int terminal;
 }

+ 18 - 0
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/models/dev/UploadDeptInfo.java

@@ -0,0 +1,18 @@
+package com.ywt.alipaympapi.models.dev;
+
+import lombok.Data;
+
+/**
+ * @author Walker
+ * Created on 2022/10/17
+ */
+@Data
+public class UploadDeptInfo {
+    private String departmentName;
+    private String departmentId;
+    private String departmentType;
+    private String hospitalName;
+    private String subHospitalName;
+    private String deptCode;
+    private String hospitalId;
+}

+ 21 - 0
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/models/dev/UploadDoctorInfo.java

@@ -0,0 +1,21 @@
+package com.ywt.alipaympapi.models.dev;
+
+import lombok.Data;
+
+/**
+ * @author Walker
+ * Created on 2022/10/17
+ */
+@Data
+public class UploadDoctorInfo {
+    private String doctorName; // 医生姓名
+    private String doctorId; // 医生 id
+    private String doctorTitle; // 医生职称
+    private String doctorIntro; // 医生介绍
+    private String doctorSpecialty; // 医生擅长
+
+    private String doctorCode;
+    private String deptId; // 出诊科室信息
+    private String deptCode;
+    private String hospitalId;
+}

+ 23 - 0
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/models/dev/UploadHospitalInfo.java

@@ -0,0 +1,23 @@
+package com.ywt.alipaympapi.models.dev;
+
+import lombok.Data;
+
+/**
+ * @author Walker
+ * Created on 2022/10/17
+ */
+@Data
+public class UploadHospitalInfo {
+    private String hospitalName;
+    private String hospitalId;
+    private String hospitalAlias;
+    private String hospitalProvince;
+    private String hospitalCity;
+    private String hospitalDistrict;
+    private String hospitalAddr;
+    private String hospitalLgt;
+    private String hospitalLat;
+    private String hospitalType;
+    private String hospitalGrade;
+    private String hospitalLogo;
+}

+ 16 - 0
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/models/dev/UploadInfoReq.java

@@ -0,0 +1,16 @@
+package com.ywt.alipaympapi.models.dev;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Walker
+ * Created on 2022/10/17
+ */
+@Data
+public class UploadInfoReq<T> {
+    private int terminal;
+    private List<T> list;
+
+}

+ 1 - 10
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/service/AuthService.java

@@ -41,14 +41,5 @@ public class AuthService {
         return resp;
     }
 
-    public AlipayMpCfg getCfg(int terminal) throws AppMessageException {
-        AlipayMpCfg cfg = new AlipayMpCfg();
-        if (TerminalEnum.valueOf(terminal) == TerminalEnum.NFYYBYFY_ALIPAY_MP) {
-            // TODO: 后续多医院支持需要改成配置化
-            cfg.setAppId(Constants.ALIPAYMP_APPID_NFYYBYFY);
-            cfg.setSaasSecurityKey(Constants.ALIPAYMP_SAAS_SEC_KEY_NFYYBYFY);
-            return cfg;
-        }
-        throw new AppMessageException(String.format("Unsupported terminal %d", terminal));
-    }
+
 }

+ 2 - 3
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/service/MessageService.java

@@ -92,10 +92,9 @@ public class MessageService {
      */
     public void sendRegMsg(int orderId, String orderNo, String alipayUid, String orderCreateTime, String orderAmountStr,
                            String tradeNo, String hospitalName, String deptName, String doctorName, String doctorId,
-                           String patientName, String regDate, String deptLoc, String appId, String merchantOrderStatus) throws AppMessageException {
+                           String patientName, String regDate, String deptLoc, String appId, String merchantOrderStatus,
+                           String isvPid) throws AppMessageException {
         CheckUtil.ensureNotEmpty(deptLoc, "科室位置不能为空");
-        // ISV的PID,支付宝id(2088 开头)。同一家ISV 请保持一致!
-        String isvPid = "2088441568067687";
         // 医院登记号
         String hospRegId = "352790440111410131";
         // 小程序跳转路径

+ 1 - 1
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/web/controller/AuthController.java

@@ -49,7 +49,7 @@ public class AuthController {
             String ip = WebAppContext.current().getIP();
             String ticket = reqData.getTicket();
             CheckUtil.ensureNotEmpty(ticket, "ticket 不能为空");
-            AlipayMpCfg cfg = authService.getCfg(terminal);
+            AlipayMpCfg cfg = BizUtil.getCfg(terminal);
             // 获取用户信息
             GetAlipayUserInfoReq req = new GetAlipayUserInfoReq();
             req.setTicket(ticket);

+ 189 - 2
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/web/controller/DevController.java

@@ -1,14 +1,28 @@
 package com.ywt.alipaympapi.web.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.alipay.easysdk.factory.Factory;
+import com.alipay.easysdk.util.generic.models.AlipayOpenApiGenericResponse;
+import com.ywt.alipaympapi.core.utils.BizUtil;
+import com.ywt.alipaympapi.core.utils.CheckUtil;
+import com.ywt.alipaympapi.core.utils.Checker;
+import com.ywt.alipaympapi.core.utils.StringHelper;
+import com.ywt.alipaympapi.models.Constants;
+import com.ywt.alipaympapi.models.auth.AlipayMpCfg;
+import com.ywt.alipaympapi.models.dev.*;
 import com.ywt.core.Anonymous;
+import com.ywt.core.exception.AppMessageException;
+import com.ywt.model.Code;
 import com.ywt.model.PageVO;
 import com.ywt.model.Pagination;
 import com.ywt.model.ResponseVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @author Walker
@@ -25,9 +39,182 @@ public class DevController {
         PageVO<String> page = new PageVO<>(pagination, new ArrayList<>());
         return ResponseVO.success(page);
     }
+
     @Anonymous(enable = true)
     @RequestMapping(value = {"/eptList"}, method = RequestMethod.POST)
     public @ResponseBody ResponseVO<List<String>> eptList() {
         return ResponseVO.success(new ArrayList<>());
     }
+
+    /**
+     * <a href="https://opendocs.alipay.com/pre-apis/02x1v3">医疗行业医院数据上传</a>
+     * 单次上传最多支持100条记录,如果超过请分批上传
+     */
+    @Anonymous(enable = true)
+    @RequestMapping(value = {"/uploadHospInfo"}, method = RequestMethod.POST)
+    public @ResponseBody ResponseVO<String> uploadHospInfo(@RequestBody UploadInfoReq<UploadHospitalInfo> data) {
+        try {
+            int terminal = data.getTerminal();
+            AlipayMpCfg cfg = BizUtil.getCfg(terminal);
+            String appId = cfg.getAppId();
+            String isvPid = cfg.getIsvPid();
+            CheckUtil.ensureNotEmpty(appId, "appId 不能为空");
+            CheckUtil.ensureNotEmpty(isvPid, "isvPid 不能为空");
+            Map<String, Object> bizParam = new HashMap<>();
+            bizParam.put("hospital_list", data.getList().stream()
+                    .map(d -> {
+                        Map<String, String> map = new HashMap<>();
+                        map.put("hospital_name", Checker.getStringValue(d.getHospitalName()));
+                        map.put("hospital_id", Checker.getStringValue(d.getHospitalId()));
+                        map.put("hospital_alias", Checker.getStringValue(d.getHospitalAlias()));
+                        map.put("hospital_province", Checker.getStringValue(d.getHospitalProvince()));
+                        map.put("hospital_city", Checker.getStringValue(d.getHospitalCity()));
+                        map.put("hospital_district", Checker.getStringValue(d.getHospitalDistrict()));
+                        map.put("hospital_addr", Checker.getStringValue(d.getHospitalAddr()));
+                        map.put("hospital_lgt", Checker.getStringValue(d.getHospitalLgt()));
+                        map.put("hospital_lat", Checker.getStringValue(d.getHospitalLat()));
+                        map.put("hospital_type", Checker.getStringValue(d.getHospitalType()));
+                        map.put("hospital_grade", Checker.getStringValue(d.getHospitalGrade()));
+                        map.put("hospital_logo", Checker.getStringValue(d.getHospitalLogo()));
+                        return map;
+                    })
+                    .collect(Collectors.toList()));
+            bizParam.put("isv_pid", isvPid);
+            bizParam.put("request_id", UUID.randomUUID().toString());
+            log.info("DevController#uploadHospInfo Request: {}", bizParam);
+            AlipayOpenApiGenericResponse response = Factory.Util.Generic().execute("alipay.commerce.medical.industrydata.hospital.upload", null, bizParam);
+            log.info("DevController#uploadHospInfo Response: {}", JSON.toJSONString(response));
+            if (Constants.ALIPAY_SUCCESS_CODE.equals(response.getCode()))
+                return ResponseVO.success(Checker.getStringValue(response.getMsg()));
+            return ResponseVO.fail(Code.RESP_CODE_PARAM_ERROR, StringHelper.isNullOrEmpty(response.getSubMsg()) ? Checker.getStringValue(response.getMsg()) : response.getSubMsg());
+        } catch (AppMessageException e) {
+            log.error("DevController#uploadHospInfo(): {}", e.getMessage());
+            return ResponseVO.fail(Code.RESP_CODE_PARAM_ERROR, e.getMessage());
+        } catch (Exception e) {
+            log.error("DevController#uploadHospInfo(): {}", e.getMessage(), e);
+            return ResponseVO.fail(Code.RESP_CODE_APP_EXCEPTION, e.getMessage());
+        }
+    }
+
+    /**
+     * <a href="https://opendocs.alipay.com/pre-apis/02x1v2">医院科室信息上传接口</a>
+     * 单次上传最多支持100条记录,如果超过请分批上传
+     */
+    @Anonymous(enable = true)
+    @RequestMapping(value = {"/uploadDeptInfo"}, method = RequestMethod.POST)
+    public @ResponseBody ResponseVO<String> uploadDeptInfo(@RequestBody UploadInfoReq<UploadDeptInfo> data) {
+        Map<String, Object> bizParam = new HashMap<>();
+        try {
+            int terminal = data.getTerminal();
+            AlipayMpCfg cfg = BizUtil.getCfg(terminal);
+            String appId = cfg.getAppId();
+            String isvPid = cfg.getIsvPid();
+            CheckUtil.ensureNotEmpty(appId, "appId 不能为空");
+            CheckUtil.ensureNotEmpty(isvPid, "isvPid 不能为空");
+            List<UploadDeptInfo> list = data.getList();
+            if (Checker.isNone(list)) throw new AppMessageException("数据为空");
+            bizParam.put("department_list", list.stream()
+                    .map(d -> {
+                        Map<String, String> map = new HashMap<>();
+                        String deptCode = Checker.getStringValue(d.getDeptCode());
+                        String departmentName = Checker.getStringValue(d.getDepartmentName());
+                        String departmentId = Checker.getStringValue(d.getDepartmentId());
+                        String departmentType = Checker.getStringValue(d.getDepartmentType());
+                        String hospitalName = Checker.getStringValue(d.getHospitalName());
+                        String subHospitalName = Checker.getStringValue(d.getSubHospitalName());
+                        String hospitalId = Checker.getStringValue(d.getHospitalId());
+                        map.put("department_name", departmentName);
+                        map.put("department_id", departmentId);
+                        map.put("department_type", departmentType); // 一级二级科室
+                        map.put("hospital_name", hospitalName); // 科室所属医院名称
+                        String pathParam = "";
+                        try {
+                            pathParam = URLEncoder.encode(String.format("?depCode=%s&departmentId=%s&header=show&hospitalId=%s&pageType=hospital-num-source&title=%s(%s)",
+                                    deptCode, departmentId, hospitalId, departmentName, subHospitalName), "utf-8");
+                        } catch (UnsupportedEncodingException e) {
+                            log.error("DevController#uploadDeptInfo UnsupportedEncodingException: {}", e.getMessage(), e);
+                        }
+                        map.put("department_url", String.format("alipays://platformapi/startapp?appId=%s&page=antbuilder/industry/hospitalV2/pages/page-no-pull/index%s", appId, pathParam)); // 科室挂号服务跳转
+                        return map;
+                    })
+                    .collect(Collectors.toList()));
+            bizParam.put("isv_pid", isvPid);
+            bizParam.put("request_id", UUID.randomUUID().toString());
+            log.info("DevController#uploadDeptInfo Request: {}", bizParam);
+            AlipayOpenApiGenericResponse response = Factory.Util.Generic().execute("alipay.commerce.medical.industrydata.department.upload", null, bizParam);
+            log.info("DevController#uploadDeptInfo Response: {}", JSON.toJSONString(response));
+            if (Constants.ALIPAY_SUCCESS_CODE.equals(response.getCode()))
+                return ResponseVO.success(Checker.getStringValue(response.getMsg()));
+            return ResponseVO.fail(Code.RESP_CODE_PARAM_ERROR, StringHelper.isNullOrEmpty(response.getSubMsg()) ? Checker.getStringValue(response.getMsg()) : response.getSubMsg());
+        } catch (AppMessageException e) {
+            log.error("DevController#uploadDeptInfo(): {}", e.getMessage());
+            return ResponseVO.fail(Code.RESP_CODE_PARAM_ERROR, e.getMessage());
+        } catch (Exception e) {
+            log.error("DevController#uploadDeptInfo(): {}", e.getMessage(), e);
+            return ResponseVO.fail(Code.RESP_CODE_APP_EXCEPTION, e.getMessage());
+        }
+    }
+    /**
+     * <a href="https://opendocs.alipay.com/pre-apis/02x1v1">医生信息上传接口</a>
+     * 单次上传最多支持100条记录,如果超过请分批上传
+     */
+    @Anonymous(enable = true)
+    @RequestMapping(value = {"/uploadDoctorInfo"}, method = RequestMethod.POST)
+    public @ResponseBody ResponseVO<String> uploadDoctorInfo(@RequestBody UploadInfoReq<UploadDoctorInfo> data) {
+        Map<String, Object> bizParam = new HashMap<>();
+        try {
+            int terminal = data.getTerminal();
+            AlipayMpCfg cfg = BizUtil.getCfg(terminal);
+            String appId = cfg.getAppId();
+            String isvPid = cfg.getIsvPid();
+            CheckUtil.ensureNotEmpty(appId, "appId 不能为空");
+            CheckUtil.ensureNotEmpty(isvPid, "isvPid 不能为空");
+            List<UploadDoctorInfo> list = data.getList();
+            if (Checker.isNone(list)) throw new AppMessageException("数据为空");
+            bizParam.put("doctor_list", list.stream()
+                    .map(d -> {
+                        Map<String, String> map = new HashMap<>();
+                        String doctorName = Checker.getStringValue(d.getDoctorName());
+                        String doctorId = Checker.getStringValue(d.getDoctorId());
+                        String doctorTitle = Checker.getStringValue(d.getDoctorTitle());
+                        String doctorIntro = Checker.getStringValue(d.getDoctorIntro());
+                        String doctorSpecialty = Checker.getStringValue(d.getDoctorSpecialty());
+                        String doctorCode = Checker.getStringValue(d.getDoctorCode());
+                        String deptId = Checker.getStringValue(d.getDeptId());
+                        String deptCode = Checker.getStringValue(d.getDeptCode());
+                        String hospitalId = Checker.getStringValue(d.getHospitalId());
+                        map.put("doctor_name", doctorName);
+                        map.put("doctor_id", doctorId);
+                        map.put("academic_title", doctorTitle);
+                        map.put("doctor_introduction", doctorIntro);
+                        map.put("skilled_disease_desc", doctorSpecialty);
+                        String pathParam = "";
+                        try {
+                            pathParam = URLEncoder.encode(String.format("?depCode=%s&depId=%s&doctorCode=%s&doctorId=%s&header=show&hospitalId=%s&pageType=doctor-page&title=医生主页",
+                                    deptCode, deptId, doctorCode, doctorId, hospitalId), "utf-8");
+                        } catch (UnsupportedEncodingException e) {
+                            log.error("DevController#uploadDoctorInfo UnsupportedEncodingException: {}", e.getMessage(), e);
+                        }
+                        map.put("doctor_url", String.format("alipays://platformapi/startapp?appId=%s&page=antbuilder/industry/hospitalV2/pages/page-no-pull/index%s", appId, pathParam));
+                        return map;
+                    })
+                    .collect(Collectors.toList()));
+            bizParam.put("isv_pid", isvPid);
+            bizParam.put("request_id", UUID.randomUUID().toString());
+            log.info("DevController#uploadDoctorInfo Request: {}", bizParam);
+            AlipayOpenApiGenericResponse response = Factory.Util.Generic().execute("alipay.commerce.medical.industrydata.doctor.upload", null, bizParam);
+            log.info("DevController#uploadDoctorInfo Response: {}", JSON.toJSONString(response));
+            if (Constants.ALIPAY_SUCCESS_CODE.equals(response.getCode()))
+                return ResponseVO.success(Checker.getStringValue(response.getMsg()));
+            return ResponseVO.fail(Code.RESP_CODE_PARAM_ERROR, StringHelper.isNullOrEmpty(response.getSubMsg()) ? Checker.getStringValue(response.getMsg()) : response.getSubMsg());
+        } catch (AppMessageException e) {
+            log.error("DevController#uploadDoctorInfo(): {}", e.getMessage());
+            return ResponseVO.fail(Code.RESP_CODE_PARAM_ERROR, e.getMessage());
+        } catch (Exception e) {
+            log.error("DevController#uploadDoctorInfo(): {}", e.getMessage(), e);
+            return ResponseVO.fail(Code.RESP_CODE_APP_EXCEPTION, e.getMessage());
+        }
+    }
+
+
 }

+ 4 - 6
onemini-hospital-empty/src/main/java/com/ywt/alipaympapi/web/controller/MsgController.java

@@ -2,7 +2,6 @@ package com.ywt.alipaympapi.web.controller;
 
 import com.ywt.alipaympapi.core.utils.BizUtil;
 import com.ywt.alipaympapi.core.utils.Checker;
-import com.ywt.alipaympapi.models.BaseResponse2;
 import com.ywt.alipaympapi.models.auth.AlipayMpCfg;
 import com.ywt.alipaympapi.models.msg.SendRegMsgReq;
 import com.ywt.alipaympapi.service.AuthService;
@@ -23,9 +22,6 @@ import org.springframework.web.bind.annotation.*;
 @RequestMapping({"/msg"})
 public class MsgController {
     @Autowired
-    AuthService authService;
-
-    @Autowired
     MessageService messageService;
 
     @Anonymous(enable = true)
@@ -49,10 +45,12 @@ public class MsgController {
             int hospitalId = Checker.getIntegerValue(reqData.getHospitalId());
             int alipayMpTerminal = BizUtil.getAlipayMpTerminalIdByHospitalId(hospitalId);
             String merchantOrderStatus = Checker.getStringValue(reqData.getMerchantOrderStatus());
-            AlipayMpCfg cfg = authService.getCfg(alipayMpTerminal);
+            AlipayMpCfg cfg = BizUtil.getCfg(alipayMpTerminal);
             String appId = cfg.getAppId();
+            // ISV的PID,支付宝id(2088 开头)。同一家ISV 请保持一致!
+            String isvPid = cfg.getIsvPid();
             messageService.sendRegMsg(orderId, orderNo, alipayUid, orderCreateTime, orderAmountStr, tradeNo, hospitalName, deptName,
-                    doctorName, doctorId, patientName, regDate, deptLoc, appId, merchantOrderStatus);
+                    doctorName, doctorId, patientName, regDate, deptLoc, appId, merchantOrderStatus, isvPid);
             return baseResponse.succeed();
         } catch (AppMessageException appMessageException) {
             return baseResponse.error(appMessageException.getMessage());