|
@@ -0,0 +1,143 @@
|
|
|
|
+package com.ywt.alipaympapi.service;
|
|
|
|
+
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.alipay.api.AlipayApiException;
|
|
|
|
+import com.alipay.api.domain.CommerceAppUploadRequestContent;
|
|
|
|
+import com.alipay.api.request.AlipayCommerceAppAuthUploadRequest;
|
|
|
|
+import com.alipay.api.response.AlipayCommerceAppAuthUploadResponse;
|
|
|
|
+import com.alipay.easysdk.base.oauth.models.AlipaySystemOauthTokenResponse;
|
|
|
|
+import com.alipay.easysdk.factory.Factory;
|
|
|
|
+import com.ywt.alipaympapi.core.utils.CheckUtil;
|
|
|
|
+import com.ywt.alipaympapi.face.impl.AlipayService;
|
|
|
|
+import com.ywt.alipaympapi.models.Constants;
|
|
|
|
+import com.ywt.core.exception.AppMessageException;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.tomcat.util.bcel.Const;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+import redis.clients.jedis.JedisCommands;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 支付宝“智能”消息服务
|
|
|
|
+ * 参考文档 <a href="https://opendocs.alipay.com/pre-open/01odaz">医疗小程序智能消息推送接入方案</a>
|
|
|
|
+ *
|
|
|
|
+ * @author Walker
|
|
|
|
+ * Created on 2022/9/28
|
|
|
|
+ */
|
|
|
|
+@Slf4j
|
|
|
|
+@Service
|
|
|
|
+public class MessageService {
|
|
|
|
+ @Autowired
|
|
|
|
+ AlipayService alipayService;
|
|
|
|
+ @Autowired
|
|
|
|
+ JedisCommands jedisCommands;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 小程序用 authCode 换取 accessToken
|
|
|
|
+ */
|
|
|
|
+ public String getAccessToken(String authCode) {
|
|
|
|
+ String accessToken = "";
|
|
|
|
+ try {
|
|
|
|
+ AlipaySystemOauthTokenResponse response = Factory.Base.OAuth().getToken(authCode);
|
|
|
|
+ log.info("MessageService#getAccessToken(authCode={} ):\n {}", authCode, JSON.toJSONString(response));
|
|
|
|
+ accessToken = response.getAccessToken();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("MessageService#getAccessToken(authCode={} ):\n {}", authCode, e.getMessage(), e);
|
|
|
|
+ }
|
|
|
|
+ return accessToken;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 发送“智能”消息
|
|
|
|
+ *
|
|
|
|
+ * @param appId 小程序 appId
|
|
|
|
+ * @param alipayUid 支付宝用户 id
|
|
|
|
+ * @param jsonBody 业务参数,具体根据业务类型按照文档拼接
|
|
|
|
+ */
|
|
|
|
+ public void sendIntelliMsg(String appId, String alipayUid, JSONObject jsonBody) {
|
|
|
|
+ try {
|
|
|
|
+ String rk = String.format(Constants.RK_ACCESS_TOKEN, appId, alipayUid);
|
|
|
|
+ String accessToken = jedisCommands.get(rk);
|
|
|
|
+ CheckUtil.ensureNotEmpty(accessToken, rk + " 无法获取 accessToken");
|
|
|
|
+ AlipayCommerceAppAuthUploadRequest request = new AlipayCommerceAppAuthUploadRequest();
|
|
|
|
+ request.setServiceName("alipay.commerce.app.data");//应用服务名称 固定值 String(256) 不可空
|
|
|
|
+ request.setTargetId("2088441565011410"); //目标用户 String(64) 签约商家 PID 不可空
|
|
|
|
+
|
|
|
|
+ CommerceAppUploadRequestContent content = new CommerceAppUploadRequestContent(); //服务数据参数
|
|
|
|
+ content.setTenantAppId("20220815114100017389"); //租户应 用ID String(64) 支付宝分配 不可空
|
|
|
|
+ content.setActivityId("upload_hospital_order"); //业务流程ID String(64) 不可空 此处固定为“upload_hospital_order”
|
|
|
|
+
|
|
|
|
+ content.setBody(JSONObject.toJSONString(jsonBody));
|
|
|
|
+ request.setContent(content);
|
|
|
|
+ log.info("MessageService#sendIntelliMsg(appId={}, accessToken={} ): 入参:{}", appId, accessToken, JSON.toJSONString(request));
|
|
|
|
+
|
|
|
|
+ AlipayCommerceAppAuthUploadResponse response = alipayService.getAlipayClient(appId).execute(request, accessToken);
|
|
|
|
+ log.info("MessageService#sendIntelliMsg(appId={}, accessToken={} ): 响应:{}", appId, accessToken, JSON.toJSONString(response));
|
|
|
|
+ } catch (AppMessageException e) {
|
|
|
|
+ log.error("MessageService#sendIntelliMsg(): 业务异常:{}", e.getMessage());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("MessageService#sendIntelliMsg(appId={} , jsonBody={} , alipayUid={} ):\n {}", appId, jsonBody, alipayUid, e.getMessage(), e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 发送预约挂号成功消息
|
|
|
|
+ */
|
|
|
|
+ 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) throws AppMessageException {
|
|
|
|
+ CheckUtil.ensureNotEmpty(deptLoc, "科室位置不能为空");
|
|
|
|
+ // ISV的PID,支付宝id(2088 开头)。同一家ISV 请保持一致!
|
|
|
|
+ String isvPid = "2088441568067687";
|
|
|
|
+ // 医院登记号
|
|
|
|
+ String hospRegId = "352790440111410131";
|
|
|
|
+ // 小程序跳转路径
|
|
|
|
+ String mpPath = String.format("alipays://platformapi/startapp?appId=%s&page=antbuilder/industry/hospitalV2/pages/page-no-pull/index&query=header=show&orderId=%d&pageType=appointment-result&title=挂号详情", appId, orderId);
|
|
|
|
+ JSONObject jsonBody = new JSONObject(); //业务流程参数 String(6000) 业务流程请求参数说明
|
|
|
|
+ jsonBody.put("out_biz_no", orderNo);//医院预约单订单号 唯一不重复(同一 家 ISV 接入的所有 医院的挂号单、检 查号、医药单都不 可重复) String(128)
|
|
|
|
+ jsonBody.put("partner_id", isvPid); //ISV的PID,支付宝id(2088 开头)。同一家ISV 请保持一致!
|
|
|
|
+ jsonBody.put("buyer_id", alipayUid);//就诊人 id,授权 人id 就诊人在支付宝平 台的 2088 开头 16 位id
|
|
|
|
+ jsonBody.put("tiny_app_id", appId);//医院在支付宝的小 程序id
|
|
|
|
+ jsonBody.put("order_create_time", orderCreateTime);//订单创建时间
|
|
|
|
+ jsonBody.put("order_modified_time", orderCreateTime);//订单修改时间
|
|
|
|
+ jsonBody.put("amount", orderAmountStr);//订单金额
|
|
|
|
+ jsonBody.put("pay_amount", orderAmountStr);//支付金额
|
|
|
|
+ jsonBody.put("trade_no", tradeNo);//支付宝交易号
|
|
|
|
+ jsonBody.put("order_type", "HOSPITAL_ORDER"); // 固定为 HOSPITAL_ORDER
|
|
|
|
+ jsonBody.put("out_biz_type", "HOSPITAL_APPOINTMENT"); // 固定值 HOSPITAL_APPOINTMENT
|
|
|
|
+ jsonBody.put("merchant_order_status", "MERCHANT_PREORDER_SUCCESS"); //状态 String(64) 枚举详见文档
|
|
|
|
+ JSONArray itemOrderList = new JSONArray();
|
|
|
|
+ JSONObject itemOrder = new JSONObject();
|
|
|
|
+ itemOrder.put("item_name", "预约挂号");//商品名称
|
|
|
|
+ itemOrder.put("quantity", "1");//商品数量
|
|
|
|
+ itemOrder.put("sku_id", "1"); //商品 skuId
|
|
|
|
+ itemOrder.put("unit_price", orderAmountStr);//商品单价
|
|
|
|
+ itemOrderList.add(itemOrder);
|
|
|
|
+ jsonBody.put("item_order_list", itemOrderList);
|
|
|
|
+
|
|
|
|
+ JSONObject extInfo = new JSONObject();
|
|
|
|
+ extInfo.put("hospital", hospitalName);//医院名称
|
|
|
|
+ extInfo.put("hospital_register_id", hospRegId);//医院登记号
|
|
|
|
+ extInfo.put("department", deptName);//就诊科室
|
|
|
|
+ extInfo.put("dept_num", "");//诊室编号
|
|
|
|
+ extInfo.put("dept_loc", deptLoc);//科室位置
|
|
|
|
+ extInfo.put("navigation", "");//导航地址
|
|
|
|
+ extInfo.put("doctor", doctorName);//医生名称
|
|
|
|
+ extInfo.put("doctor_rank", "");//医生职级
|
|
|
|
+ extInfo.put("doctor_id", doctorId);//医生 id
|
|
|
|
+ extInfo.put("doctor_avatar", "");//医生头像 url
|
|
|
|
+ extInfo.put("patient", patientName);//就诊人 必须与 buy_id 对 应的姓名一致
|
|
|
|
+ extInfo.put("scheduled_time", regDate);//预约时间
|
|
|
|
+ extInfo.put("take_num_url", "");//取号入口
|
|
|
|
+ extInfo.put("take_num_password", "");//取号密码
|
|
|
|
+ extInfo.put("call_num_url", "");//叫号进度入口
|
|
|
|
+ extInfo.put("medical_order_id", "");//就诊单id
|
|
|
|
+ extInfo.put("medical_num", "");//就诊/检 查序号
|
|
|
|
+ extInfo.put("merchant_order_link_page", mpPath);//订单链接
|
|
|
|
+ jsonBody.put("ext_info", extInfo);
|
|
|
|
+
|
|
|
|
+ sendIntelliMsg(appId, alipayUid, jsonBody);
|
|
|
|
+ }
|
|
|
|
+}
|