Browse Source

新对接的星级回传

dchen 2 months ago
parent
commit
0271687410

+ 8 - 2
src/main/java/com/tiangua/star/enmus/CommercialCallBackReadyEnum.java

@@ -4,9 +4,15 @@ import com.tiangua.kirin.api.StringCodeable;
 import com.tiangua.kirin.utils.EnumUtils;
 
 public enum CommercialCallBackReadyEnum implements StringCodeable {
-
+    Commercial_Test("2336", "1778fd4985a9240809111258business", "http://rcw.notify.succtime.com/customerNotify/getCustomerInfo"),
     Commercial_ONE("4330", "445759631851840business", "http://rcw.notify.succtime.com/customerNotify/getCustomerInfo"),
-    Commercial_Test("2336", "1778fd4985a9240809111258business", "http://rcw.notify.succtime.com/customerNotify/getCustomerInfo");
+    Commercial_SXRKX("4337", "9ae00be7593b250325033922business", " https://api.hzy-group.com.cn/sem_feedback/list.html"),//山西瑞凯鑫
+//    Commercial_XJZZ("4344", "fe6ad6de6085250326042152business", " https://xjzzzr-bam.kaifa.fun/api/Clue/batchLevel/139"),//新疆智卓
+    Commercial_FOSHAN("4178", "b940cdbc383c250225105128business", "http://myjs.crmxt.vip/api/customer.callback/index"),//佛山市创智盈通企业管理有限公司
+    Commercial_CHONGQINGZC("4181", "e955dd0c3177250225021000business", "https://api.zhudaicms.com/api/stars_back.html?brand=1263&orgid=41812&d=1696580106;https://api.zhudaicms.com/api/stars_back.html?brand=1263&orgid=4181&d=1696580106"),//4181重庆众诚 两个星级
+    Commercial_BJQN("3781", "1059819706ac240813041124business", "https://api.zhudaicms.com/api/stars_back.html?brand=1556&orgid=%E6%83%A0%E8%9E%8D%E9%92%B1%E5%8C%85&d=1721903031"),//北京签牛企业管理咨询有限公司
+    Commercial_NBHX("4303", "a3c7888a1d91250313094409business", "https://api.zhudaicms.com/api/stars_back.html?brand=1280&orgid=4303&d=1700188876"),//宁波垣信信息科技有限公司
+    Commercial_HZ("4212", "496f0859cfe3250228102712business", "https://api.zhudaicms.com/api/stars_back.html?brand=1663&orgid=4212&d=1736049235");//杭州聚壹融商务信息咨询有限公司
 
     private String code;
     private String busid;

+ 211 - 23
src/main/java/com/tiangua/star/service/impl/CasllBackDataProcessor.java

@@ -5,34 +5,25 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.tiangua.star.enmus.CommercialCallBackReadyEnum;
 import com.tiangua.star.model.CustomerFollowup;
-import com.tiangua.star.model.UserStarFollowCallbackParam;
 import com.tiangua.star.model.XdOrderDto;
-import com.tiangua.star.model.XinLuUserStarCallbackParam;
 import com.tiangua.star.service.CallBackService;
-import com.tiangua.star.service.XinLuService;
 import com.tiangua.star.util.HttpClientThreeUtil;
+import com.tiangua.star.util.SignUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.utils.URIBuilder;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
-import javax.annotation.PostConstruct;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
+import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.stream.Collectors;
 
 @Service
@@ -65,19 +56,87 @@ public class CasllBackDataProcessor implements CallBackService {
             return;
         }
 
-        for (String busiId : callBackMap.keySet()) {
-            CommercialCallBackReadyEnum commercialCallBackReadyEnum = CommercialCallBackReadyEnum.of(busiId);
+        for (String productBizId : callBackMap.keySet()) {
+            CommercialCallBackReadyEnum commercialCallBackReadyEnum = CommercialCallBackReadyEnum.of(productBizId);
             if (commercialCallBackReadyEnum != null) {
                 switch (commercialCallBackReadyEnum) {
                     case Commercial_ONE:
-                        log.info("开始处理机构id:{}", busiId);
-                        List<String> md5List = callBackMap.get(busiId);
+                        List<String> md5List = callBackMap.get(productBizId);
+                        log.info("开始处理机构id:{},当日订单数:{},条数:{}", productBizId,md5List,md5List.size());
                         if (CollectionUtils.isEmpty(md5List)) {
                             return;
                         }
                         sendGetRequest(CommercialCallBackReadyEnum.Commercial_ONE.getCode(),
                                 CommercialCallBackReadyEnum.Commercial_ONE.getBusid(),commercialCallBackReadyEnum.getUrl(),md5List);
                         break;
+
+                    case Commercial_HZ:
+                        List<String> md5ListHz = callBackMap.get(productBizId);
+                        log.info("开始处理机构id:{},杭州聚壹融商务信息咨询有限公司 当日订单数:{},条数:{}", productBizId,md5ListHz,md5ListHz.size());
+                        if (CollectionUtils.isEmpty(md5ListHz)) {
+                            return;
+                        }
+                        sendGetRequestHz(commercialCallBackReadyEnum.getCode(),
+                                commercialCallBackReadyEnum.getBusid(),commercialCallBackReadyEnum.getUrl(),"杭州聚壹融商务信息咨询有限公司");
+                        break;
+                    case Commercial_NBHX:
+                        List<String> md5ListNBHX = callBackMap.get(productBizId);
+                        log.info("开始处理机构id:{},宁波垣信信息科技有限公司 当日订单数:{},条数:{}", productBizId,md5ListNBHX,md5ListNBHX.size());
+                        if (CollectionUtils.isEmpty(md5ListNBHX)) {
+                            return;
+                        }
+                        sendGetRequestHz(commercialCallBackReadyEnum.getCode(),
+                                commercialCallBackReadyEnum.getBusid(),commercialCallBackReadyEnum.getUrl(),"宁波垣信信息科技有限公司");
+                        break;
+                    case Commercial_BJQN:
+                        List<String> md5ListBJQN = callBackMap.get(productBizId);
+                        log.info("开始处理机构id:{},北京签牛企业管理咨询有限公司 当日订单数:{},条数:{}", productBizId,md5ListBJQN,md5ListBJQN.size());
+                        if (CollectionUtils.isEmpty(md5ListBJQN)) {
+                            return;
+                        }
+                        sendGetRequestHz(commercialCallBackReadyEnum.getCode(),
+                                commercialCallBackReadyEnum.getBusid(),commercialCallBackReadyEnum.getUrl(),"北京签牛企业管理咨询有限公司");
+                        break;
+                    case Commercial_FOSHAN:
+                        List<String> md5ListFS = callBackMap.get(productBizId);
+                        log.info("开始处理机构id:{},佛山市创智盈通企业管理有限公司 当日订单数:{},条数:{}", productBizId,md5ListFS,md5ListFS.size());
+                        if (CollectionUtils.isEmpty(md5ListFS)) {
+                            return;
+                        }
+                        sendGetRequestFoShan(commercialCallBackReadyEnum.getCode(),
+                                commercialCallBackReadyEnum.getBusid(),commercialCallBackReadyEnum.getUrl(), md5ListFS);
+                        break;
+                    case Commercial_SXRKX:
+                        List<String> md5ListSXRKX = callBackMap.get(productBizId);
+                        log.info("开始处理机构id:{},山西瑞凯鑫 当日订单数:{},条数:{}", productBizId,md5ListSXRKX,md5ListSXRKX.size());
+                        if (CollectionUtils.isEmpty(md5ListSXRKX)) {
+                            return;
+                        }
+                        sendGetRequestSXRKX(commercialCallBackReadyEnum.getCode(),
+                                commercialCallBackReadyEnum.getBusid(),commercialCallBackReadyEnum.getUrl());
+                        break;
+//                    case Commercial_XJZZ:
+//                        List<String> md5ListXJZZ = callBackMap.get(busiId);
+//                        log.info("开始处理机构id:{},当日订单数:{},条数:{}", busiId,md5ListXJZZ,md5ListXJZZ.size());
+//                        if (CollectionUtils.isEmpty(md5ListXJZZ)) {
+//                            return;
+//                        }
+//                        sendGetRequestSXRKX(commercialCallBackReadyEnum.getCode(),
+//                                commercialCallBackReadyEnum.getBusid(),commercialCallBackReadyEnum.getUrl());
+//                        break;
+                    case Commercial_CHONGQINGZC:
+                        List<String> md5ListCq = callBackMap.get(productBizId);
+                        log.info("开始处理机构id:{},重庆众诚 当日订单数:{},条数:{}", productBizId,md5ListCq,md5ListCq.size());
+                        if (CollectionUtils.isEmpty(md5ListCq)) {
+                            return;
+                        }
+                        String url = commercialCallBackReadyEnum.getUrl();
+                        String[] split = url.split(";");
+                        for (String urlTemp : split) {
+                            sendGetRequestHz(commercialCallBackReadyEnum.getCode(),
+                                    commercialCallBackReadyEnum.getBusid(),urlTemp,"重庆众诚");
+                        }
+                        break;
 //                    case Commercial_Test:
 //                        log.info("开始处理机构id:{}", busiId);
 //                        List<String> md5List2 = callBackMap.get(busiId);
@@ -96,6 +155,135 @@ public class CasllBackDataProcessor implements CallBackService {
 
     }
 
+
+    private void sendGetRequestSXRKX(String productBizId,String busiId,String url){
+        JSONObject param = SignUtil.generateSign(81, 43, "730969D3F673BA42432C574378B9A8F1");
+        log.info("busiId:{},:山西瑞凯鑫 url:{} ,jsonString:{}" ,busiId, url,param);
+        String responseStr = HttpClientThreeUtil.post(url, JSON.toJSONString(param));
+        JSONObject jsonObject = JSON.parseObject(responseStr);
+        List<CustomerFollowup> followupList = new ArrayList<>();
+        if (jsonObject.getIntValue("code") == 0) {
+            JSONObject data = jsonObject.getJSONObject("data");
+            JSONArray list = data.getJSONArray("list");
+            if (CollectionUtils.isEmpty(list)) {
+                log.info("busiId:{} 山西瑞凯鑫 list为空 没有星级数据", busiId);
+                return;
+            }
+            for (int i = 0; i < list.size(); i++) {
+                JSONObject item = list.getJSONObject(i);
+                CustomerFollowup customerFollowup = new CustomerFollowup();
+                customerFollowup.setBusiId(busiId);
+                customerFollowup.setProductBizId(Integer.parseInt(productBizId));
+                customerFollowup.setCustomerName(item.getString("name"));
+                customerFollowup.setStarLevel(new BigDecimal(item.getIntValue("stars")));
+                customerFollowup.setFollowStatus(item.getString("statusStr"));
+                customerFollowup.setFollowRemark(item.getString("remark"));
+                String mobile = item.getString("mobile");
+                if (StringUtils.isEmpty(mobile)) {
+                    log.error("busiId:{} 山西瑞凯鑫 手机号为空",busiId);
+                    continue;
+                }
+                customerFollowup.setPhoneMd5(DigestUtils.md5Hex(mobile));
+                customerFollowup.setFollowTime(new Date());
+                followupList.add(customerFollowup);
+            }
+        }
+        if (CollectionUtils.isEmpty(followupList)) {
+            log.info("busiId:{} 山西瑞凯鑫 无星级数据", busiId);
+            return;
+        }
+        log.info("busiId:{} 山西瑞凯鑫 处理数据条:{}", busiId, followupList.size());
+        handleMappedData(busiId,followupList);
+    }
+
+    private void sendGetRequestFoShan(String productBizId,String busiId,String url,List<String> md5ListFS){
+        List<Map<String, String>> jsonList = new ArrayList<>();
+        for (String md5 : md5ListFS) {
+            Map<String, String> map = new HashMap<>();
+            map.put("source", "hr");
+            map.put("mobile_md5", md5);
+            jsonList.add(map);
+        }
+        String jsonString = JSON.toJSONString(jsonList);
+        log.info("busiId:{},:佛山市创智盈通企业管理有限公司 jsonString:{}" ,busiId, jsonString);
+
+        String responseStr = HttpClientThreeUtil.post(url, jsonString);
+        JSONObject response = JSON.parseObject(responseStr);
+        String code = response.getString("code");
+        if (!"200".equals(code)) {
+            log.info("佛山市创智盈通企业管理有限公司 返回数据错误: " + response.getString("msg"));
+            return ;
+        }
+        JSONArray dataArray = response.getJSONArray("data");
+        List<CustomerFollowup> followupList = new ArrayList<>();
+        if (CollectionUtils.isEmpty(dataArray)) {
+            log.info("busiId:{},:佛山市创智盈通企业管理有限公司 今天没有星级数据",busiId);
+            return;
+        }
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject obj = dataArray.getJSONObject(i);
+            CustomerFollowup followup = new CustomerFollowup();
+            followup.setPhoneMd5(obj.getString("mobile_md5"));
+            followup.setBusiId(busiId);
+            followup.setProductBizId(Integer.parseInt(productBizId));
+            followup.setFollowTime(new Date());
+            followup.setSourceType(3);
+            String star = obj.getString("industry");
+            if (StringUtils.isEmpty(star)) {
+                log.info("busiId:{} 佛山创智盈通企业管理有限公司 mobile_md5{} 没有填星级:", busiId, followup.getPhoneMd5());
+                continue;
+            } else {
+                followup.setStarLevel(new BigDecimal(star));
+            }
+            followupList.add(followup);
+        }
+
+        if (CollectionUtils.isEmpty(followupList)) {
+            log.info("busiId:{} 佛山创智盈通企业管理有限公司 无星级数据", busiId);
+            return;
+        }
+        log.info("busiId:{} 佛山创智盈通企业管理有限公司 处理数据条:{}", busiId, followupList.size());
+        handleMappedData(busiId,followupList);
+
+    }
+
+    //https://api.zhudaicms.com/ 通用
+    private void sendGetRequestHz(String productBizId,String busiId,String url,String companyName){
+        String responseStr = HttpClientThreeUtil.get(url,null);
+        JSONObject response = JSON.parseObject(responseStr);
+        String code = response.getString("code");
+        if (!"101".equals(code)) {
+            log.info("busiId:{},companyName {},24h返回数据错误: {},{}" ,busiId,companyName,
+                    response.getString("msg"),response.getString("code"));
+            return;
+        }
+
+        JSONArray dataArray = response.getJSONArray("data");
+        List<CustomerFollowup> followupList = new ArrayList<>();
+
+        // 遍历 data 数组,创建实体对象并设置对应字段
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject obj = dataArray.getJSONObject(i);
+            CustomerFollowup followup = new CustomerFollowup();
+            followup.setBusiId(busiId);
+            followup.setProductBizId(Integer.parseInt(productBizId));
+            followup.setPhoneMd5(obj.getString("md5mobile"));
+            followup.setStarLevel(new BigDecimal(obj.getString("stars")));
+            followup.setSourceType(3);
+            followup.setFollowTime(new Date());
+            followupList.add(followup);
+        }
+        if (CollectionUtils.isEmpty(followupList)) {
+            log.info("busiId:{} companyName:{},没有24h星级数据", busiId,companyName);
+            return;
+        }
+        log.info("busiId:{} companyName:{} 处理数据条:{}", busiId, companyName,followupList.size());
+        handleMappedData(busiId,followupList);
+
+    }
+
+
     private void sendGetRequest(String productBizId,String busiId,String url,List<String> md5s){
         List<CustomerFollowup> list = new ArrayList<>();
         JSONObject map = new JSONObject();
@@ -134,15 +322,15 @@ public class CasllBackDataProcessor implements CallBackService {
             }
         }
         log.info("busiId:{} 处理数据条:{}", busiId, list.size());
-        handleMappedData(list);
+        handleMappedData(busiId,list);
     }
 
 
 
-    private void handleMappedData(List<CustomerFollowup> data) {
-        log.info("【CasllBackDataProcessor】成功处理 {} 条映射数据 明细:{}", data.size(), data);
+    private void handleMappedData(String busiId,List<CustomerFollowup> data) {
+        log.info("busiId:{} 【CasllBackDataProcessor】成功处理 {} 条映射数据 明细:{}",busiId, data.size(), data);
             String post = HttpClientThreeUtil.post(url, JSON.toJSONString(data));
-        log.info("【CasllBackDataProcessor】post结果:{}", post);
+        log.info("busiId:{}【CasllBackDataProcessor】post结果:{}",busiId, post);
     }
 
 

+ 163 - 0
src/main/java/com/tiangua/star/util/SignUtil.java

@@ -0,0 +1,163 @@
+package com.tiangua.star.util;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.security.MessageDigest;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class SignUtil {
+
+    /**
+     * 生成签名,startTime 为当前 Unix 时间戳(秒),endTime 为 8 小时后的时间戳。
+     *
+     * @param sid   请求参数 sid
+     * @param brand 请求参数 brand
+     * @param key   加密密钥
+     * @return 计算得到的 MD5 签名字符串
+     */
+    public static JSONObject generateSign(int sid, int brand, String key) {
+        // 获取当前 Unix 时间戳(秒)
+        long currentTimestamp = System.currentTimeMillis() / 1000;
+        // 8小时后的 Unix 时间戳
+        long endTimestamp = currentTimestamp + 8 * 3600;
+
+        // 使用 TreeMap 自动按 key 的自然顺序排序
+        Map<String, String> requestData = new TreeMap<>();
+        requestData.put("sid", String.valueOf(sid));
+        requestData.put("brand", String.valueOf(brand));
+        requestData.put("startTime", String.valueOf(currentTimestamp));
+        requestData.put("endTime", String.valueOf(endTimestamp));
+        System.out.println(requestData);
+        // 拼接 key=value 的字符串,多个参数之间用 &
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : requestData.entrySet()) {
+            sb.append(entry.getKey())
+              .append("=")
+              .append(entry.getValue())
+              .append("&");
+        }
+        // 去掉末尾的 & 符号
+        if (sb.length() > 0) {
+            sb.deleteCharAt(sb.length() - 1);
+        }
+
+        // 拼接密钥
+        String dataToHash = sb.toString() + key;
+        String sign = md5(dataToHash);
+
+        JSONObject json = new JSONObject();
+        json.put("sid", sid);
+        json.put("brand", brand);
+        json.put("startTime", currentTimestamp);
+        json.put("endTime", endTimestamp);
+        json.put("sign", sign);
+
+        return json;
+    }
+
+    /**
+     * 计算字符串的 MD5 值(小写)
+     *
+     * @param input 待加密字符串
+     * @return MD5 加密后的字符串
+     */
+    public static String md5(String input) {
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] messageDigest = md.digest(input.getBytes("UTF-8"));
+            // 将字节数组转换为十六进制字符串
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : messageDigest) {
+                String hex = Integer.toHexString(0xff & b);
+                if (hex.length() == 1) {
+                    hexString.append('0');
+                }
+                hexString.append(hex);
+            }
+            return hexString.toString();
+        } catch (Exception e) {
+            throw new RuntimeException("MD5 加密失败", e);
+        }
+    }
+
+    /**
+     * 生成签名,包含 sid、brand 和 mobile 参数
+     *
+     * @param sid    请求参数 sid
+     * @param brand  请求参数 brand
+     * @param mobile 请求参数 mobile 数组
+     * @param key    密钥
+     * @return 计算得到的 MD5 签名字符串
+     */
+    public static String generateSignWithMobile(int sid, int brand, String[] mobile, String key) {
+        // 使用 TreeMap 自动按 key 的自然顺序排序
+        Map<String, String> requestData = new TreeMap<>();
+        requestData.put("sid", String.valueOf(sid));
+        requestData.put("brand", String.valueOf(brand));
+        // 如果 mobile 为数组,则使用逗号连接各个手机号
+        String mobileStr = String.join(",", mobile);
+        requestData.put("mobile", mobileStr);
+
+        // 拼接所有参数为 "key=value" 格式,参数之间使用 &
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : requestData.entrySet()) {
+            sb.append(entry.getKey())
+                    .append("=")
+                    .append(entry.getValue())
+                    .append("&");
+        }
+        // 去掉末尾的 & 符号
+        if (sb.length() > 0) {
+            sb.deleteCharAt(sb.length() - 1);
+        }
+
+        // 拼接密钥
+        String dataToHash = sb.toString() + key;
+        // 计算 MD5 签名并返回
+        return md5(dataToHash);
+    }
+
+    /**
+     * 计算字符串的 MD5 值(小写)
+     *
+     * @param input 待加密字符串
+     * @return MD5 加密后的字符串
+     */
+    public static String md52(String input) {
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] messageDigest = md.digest(input.getBytes("UTF-8"));
+            // 将字节数组转换为十六进制字符串
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : messageDigest) {
+                String hex = Integer.toHexString(0xff & b);
+                if (hex.length() == 1) {
+                    hexString.append('0');
+                }
+                hexString.append(hex);
+            }
+            return hexString.toString();
+        } catch (Exception e) {
+            throw new RuntimeException("MD5 加密失败", e);
+        }
+    }
+
+    // 测试方法
+    public static void main(String[] args) {
+        int sid = 81;
+        int brand = 43;
+        String key = "730969D3F673BA42432C574378B9A8F1";
+
+        JSONObject sign = generateSign(sid, brand, key);
+        System.out.println("生成的签名: " + sign);
+
+//        int sid = 81;
+//        int brand = 43;
+//        String[] mobile = {"13303412254", "18763878111"};
+//        String key = "730969D3F673BA42432C574378B9A8F1";
+//
+//        String sign = generateSignWithMobile(sid, brand, mobile, key);
+//        System.out.println("生成的签名: " + sign);
+    }
+}