Browse Source

开放接口

叶君翔 3 years ago
parent
commit
2783755f99

+ 6 - 1
doc/open_api.sql

@@ -9,4 +9,9 @@ CREATE TABLE `lb_shop_delivery_disable` (
   `deleted` tinyint(2) unsigned DEFAULT '0' COMMENT '0:未删除,1:已删除',
   PRIMARY KEY (`id`),
   KEY `idx_shop_id` (`shop_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='门店屏蔽运力表';
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='门店屏蔽运力表';
+
+
+-- 应用表增加通知字段
+ALTER TABLE `lb_app_info` ADD COLUMN `store_status_notify_url` varchar(255) DEFAULT NULL COMMENT '门店状态通知接口';
+ALTER TABLE `lb_app_info` ADD COLUMN `order_status_notify_url` varchar(255) DEFAULT NULL COMMENT '订单状态通知接口';

+ 14 - 0
lb-app/src/main/java/com/ydd/app/service/OpenApiNotifyService.java

@@ -0,0 +1,14 @@
+package com.ydd.app.service;
+
+import com.ydd.app.vo.StoreStatusNotifyVo;
+
+/**
+ *  通知接口
+ * @author 叶君翔
+ * @date 2022/04/13 10:14
+ */
+public interface OpenApiNotifyService {
+
+    String storeStatus(StoreStatusNotifyVo storeStatusNotifyVo);
+
+}

+ 74 - 0
lb-app/src/main/java/com/ydd/app/service/impl/OpenApiNotifyServiceImpl.java

@@ -0,0 +1,74 @@
+package com.ydd.app.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.parser.Feature;
+import com.ydd.app.service.OpenApiNotifyService;
+import com.ydd.app.vo.StoreStatusNotifyVo;
+import com.ydd.common.enums.ResponseResultCodeEnum;
+import com.ydd.common.utils.http.HttpUtils;
+import com.ydd.common.utils.sign.SignatureUtil;
+import com.ydd.ecloud.core.utils.JsonMapper;
+import com.ydd.module.domain.AppInfo;
+import com.ydd.module.expection.CustomAppException;
+import com.ydd.module.service.IAppInfoService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Set;
+
+/**
+ *  通知接口
+ * @author 叶君翔
+ * @date 2022/04/13 10:15
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+public class OpenApiNotifyServiceImpl implements OpenApiNotifyService {
+
+    private final IAppInfoService iAppInfoService;
+
+    @Override
+    public String storeStatus(StoreStatusNotifyVo storeStatusNotifyVo) {
+        storeStatusNotifyVo.setTimeStamp(System.currentTimeMillis());
+        String json = JsonMapper.nonNullMapper().toJson(storeStatusNotifyVo);
+        HashMap<String, String> signParam = JSON.parseObject(json, LinkedHashMap.class, Feature.OrderedField);
+        Set<String> exclude = new HashSet<>();
+        exclude.add("sign");
+        AppInfo appInfo = iAppInfoService.getByAppId(storeStatusNotifyVo.getAppId());
+        if (appInfo == null) {
+            throw new CustomAppException("应用不存在");
+        }
+        String sign = null;
+        try {
+            sign = SignatureUtil.getRequestMD5Sign(signParam, exclude, appInfo.getAppSecret());
+        } catch (UnsupportedEncodingException e) {
+            log.error("获取签名失败: {}", e.getMessage());
+            e.printStackTrace();
+        }
+        storeStatusNotifyVo.setSign(sign);
+        String storeStatusNotifyVoStr = JSONObject.toJSONString(storeStatusNotifyVo);
+        try {
+            storeStatusNotifyVoStr = URLEncoder.encode(storeStatusNotifyVoStr,"utf-8");
+            log.info("门店状态同步请求参数: {}", storeStatusNotifyVoStr);
+            String resp = HttpUtils.sendPost(appInfo.getStoreStatusNotifyUrl(), storeStatusNotifyVoStr);
+            log.info("门店状态同步返回结果: {}", resp);
+            // 若未收到响应, 则继续推送
+            if (!ResponseResultCodeEnum.SUCCESS.getMessage().equals(resp)) {
+                // todo: 未收到响应开启重试机制
+            }
+        } catch (UnsupportedEncodingException e) {
+            log.error("获取签名失败: {}", e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 28 - 0
lb-app/src/main/java/com/ydd/app/vo/StoreStatusNotifyVo.java

@@ -0,0 +1,28 @@
+package com.ydd.app.vo;
+
+import com.ydd.app.dto.BaseDto;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 门店状态通知参数
+ * @author 叶君翔
+ * @date 2022/04/13 11:14
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class StoreStatusNotifyVo extends BaseDto {
+
+    private String shopCode;
+
+    private Integer deliveryId;
+
+    private Integer status;
+
+    private String failMsg;
+
+}

+ 44 - 4
lb-common/src/main/java/com/ydd/common/utils/sign/SignatureUtil.java

@@ -1,11 +1,12 @@
 package com.ydd.common.utils.sign;
 
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.StringUtils;
 
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.*;
 
 /**
  * @author 叶君翔
@@ -63,4 +64,43 @@ public class SignatureUtil {
         return sign.equals(signature);
     }
 
+    /**
+     * 获取签名
+     * @param paramMap 参数
+     * @param excludeSignParams 无需参与签名的参数
+     * @return 签名结果
+     * @throws UnsupportedEncodingException
+     */
+    public static String getRequestMD5Sign(Map<String, String> paramMap, Set<String> excludeSignParams, String appSecret) throws UnsupportedEncodingException {
+        if (paramMap == null || paramMap.isEmpty()) {
+            log.warn("待签名参数map为空!");
+            return null;
+        }
+        String str2Sign = buildRequestParam4Sign(paramMap, excludeSignParams, appSecret);
+        String result = DigestUtils.md5Hex(str2Sign).toUpperCase();
+        log.info("签名结果:{}", result);
+        return result.toUpperCase();
+    }
+
+    private static String buildRequestParam4Sign(Map<String, String> paramMap, Set<String> excludeSignParams, String appSecret) throws UnsupportedEncodingException {
+        Set<String> keySet = paramMap.keySet();
+        StringBuilder param = new StringBuilder(20 * keySet.size());
+        List<String> keyList = new ArrayList<>(keySet);
+        Collections.sort(keyList);
+        for (String key : keyList) {
+            if (excludeSignParams != null && excludeSignParams.contains(key)) {
+                continue;
+            }
+            Object value = paramMap.get(key);
+            // 排除值为空的数据
+            if (value == null || StringUtils.isEmpty(value.toString())) {
+                continue ;
+            }
+            param.append(URLEncoder.encode(key, "UTF-8")).append("=").append(value).append("&");
+        }
+        log.info("不包含appSecret签名原始串:{}", param.toString());
+        param.append("appSecret").append("=").append(URLEncoder.encode(appSecret, "UTF-8"));
+        return param.toString();
+    }
+
 }

+ 6 - 0
lb-module/src/main/java/com/ydd/module/domain/AppInfo.java

@@ -43,6 +43,12 @@ public class AppInfo implements Serializable {
     @Excel(name = "appSecret")
     private String appSecret;
 
+    // 门店状态通知
+    private String storeStatusNotifyUrl;
+
+    // 订单状态通知
+    private String orderStatusNotifyUrl;
+
     /** 创建时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")