Sfoglia il codice sorgente

推送微走取消订单接口
客户详情ai处理

lk 2 giorni fa
parent
commit
7abb950613

+ 20 - 12
fs-admin/src/main/java/com/fs/task/CrmCustomerAiProcessingTask.java

@@ -94,21 +94,29 @@ public class CrmCustomerAiProcessingTask {
         String threadName = Thread.currentThread().getName();
         long batchStartTime = System.currentTimeMillis();
 
-        try {
+//        try {
             log.info("线程 {} 开始处理批次, 数据量: {}", threadName, batch.size());
 
             // 示例:处理每条数据
             for (Map<String, String> data : batch) {
                 // 获取数据
-                String customerId = data.get("customerId");
+                Long customerId = Long.valueOf(data.get("customerId"));
                 String dataJson = data.get("data");
-                String logId = data.get("logId");
-                //todo 业务!!!!!!1.ai沟通总结2.流失风险等级3.沟通摘要4.客户画像8.客户关注点9.客户意向度 //都要异步处理
+                Long logId = Long.valueOf(data.get("logId"));
+                //todo 业务!!!!!!2.流失风险等级8.9.客户意向度 //都要异步处理
+                //客户画像
                 crmCustomerAnalyzeService.aiGeneratedCustomerPortrait(customerId,dataJson,logId);
+                //沟通总结
+                crmCustomerAnalyzeService.aiCommunicationSummary(customerId,dataJson,logId);
+                //沟通摘要
+                crmCustomerAnalyzeService.aiCommunicationAbstract(customerId,dataJson,logId);
+//                //流失风险等级 //ai暂时未提供,等ai提供
+                crmCustomerAnalyzeService.aiAttritionLevel(customerId,dataJson,logId);
+                //客户关注点
+                crmCustomerAnalyzeService.aiCustomerFocus(customerId,dataJson,logId);
+                //客户意向度
+                crmCustomerAnalyzeService.aiIntentionDegree(customerId,dataJson,logId);
 
-
-                // 模拟业务处理
-                Thread.sleep(10);
             }
 
             long costTime = System.currentTimeMillis() - batchStartTime;
@@ -116,11 +124,11 @@ public class CrmCustomerAiProcessingTask {
             log.info("线程 {} 批次处理完成, 数据量: {}, 耗时: {}ms",
                     threadName, batch.size(), costTime);
 
-        } catch (Exception e) {
-            failCount.addAndGet(batch.size());
-            log.error("线程 {} 批次处理失败, 数据量: {}", threadName, batch.size(), e);
-            throw new RuntimeException("批次处理失败", e);
-        }
+//        } catch (Exception e) {
+//            failCount.addAndGet(batch.size());
+//            log.error("线程 {} 批次处理失败, 数据量: {}", threadName, batch.size(), e);
+//            throw new RuntimeException("批次处理失败", e);
+//        }
     }
     /**
      * 处理失败的数据

+ 16 - 1
fs-company/src/main/java/com/fs/company/controller/crm/CrmCustomerAnalyzeController.java

@@ -1,6 +1,9 @@
 package com.fs.company.controller.crm;
 
 import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.crm.param.PolishingScriptParam;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -22,7 +25,7 @@ import com.fs.common.core.page.TableDataInfo;
 
 /**
  * 客户聊天记录分析Controller
- * 
+ *
  * @author fs
  * @date 2026-03-24
  */
@@ -112,4 +115,16 @@ public class CrmCustomerAnalyzeController extends BaseController
     {
         return toAjax(crmCustomerAnalyzeService.deleteCrmCustomerAnalyzeByIds(ids));
     }
+
+    /**
+     * 话术润色
+     */
+    @PreAuthorize("@ss.hasPermi('crm:analyze:polishingScript')")
+    @Log(title = "话术润色", businessType = BusinessType.INSERT)
+    @PostMapping("/polishingScript")
+    public R polishingScript(@RequestBody PolishingScriptParam param)
+    {
+        return R.ok().put("data",crmCustomerAnalyzeService.polishingScript(param));
+    }
+
 }

+ 1 - 1
fs-service/src/main/java/com/fs/crm/mapper/CrmCustomerAnalyzeMapper.java

@@ -62,7 +62,7 @@ public interface CrmCustomerAnalyzeMapper extends BaseMapper<CrmCustomerAnalyze>
 
     CrmCustomerAnalyze selectLatestOne(@Param("customerId") Long customerId);
 
-    int updateCustomerPortrait(@Param("customerId") Long customerId,@Param("customerPortrait") String customerPortrait);
+    int updateCustomerPortrait(CrmCustomerAnalyze crmCustomerAnalyze);
 
     List<CrmCustomerAnalyze> selectCrmCustomerAnalyzeListAll(CrmCustomerAnalyze crmCustomerAnalyze);
 }

+ 35 - 0
fs-service/src/main/java/com/fs/crm/param/PolishingScriptParam.java

@@ -0,0 +1,35 @@
+package com.fs.crm.param;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.util.Map;
+
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Api(value = "话术润色参数")
+public class PolishingScriptParam {
+    /**
+     * 聊天内容
+     */
+    @ApiModelProperty(value = "聊天内容")
+    private String content;
+
+    /**
+     * 客户画像
+     */
+    @ApiModelProperty(value = "客户画像")
+    private Map<String,String> portrait;
+
+    /**
+     * 聊天id,时间戳
+     */
+    @ApiModelProperty(value = "聊天id,时间戳")
+    private String chatId;
+}

+ 16 - 1
fs-service/src/main/java/com/fs/crm/service/ICrmCustomerAnalyzeService.java

@@ -3,6 +3,7 @@ package com.fs.crm.service;
 import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.crm.domain.CrmCustomerAnalyze;
+import com.fs.crm.param.PolishingScriptParam;
 
 /**
  * 客户聊天记录分析Service接口
@@ -59,7 +60,21 @@ public interface ICrmCustomerAnalyzeService extends IService<CrmCustomerAnalyze>
      */
     int deleteCrmCustomerAnalyzeById(Long id);
 
-    void aiGeneratedCustomerPortrait(String customerId, String dataJson,String logId);
+    void aiGeneratedCustomerPortrait(Long customerId, String dataJson,Long logId);
+
+    void aiCommunicationSummary(Long customerId, String dataJson, Long logId);
+
+    void aiCommunicationAbstract(Long customerId, String dataJson, Long logId);
+
+    void aiAttritionLevel(Long customerId, String dataJson, Long logId);
+
+    void aiCustomerFocus(Long customerId, String dataJson, Long logId);
+
+    String polishingScript(PolishingScriptParam param);
+
+    void aiIntentionDegree(Long customerId, String dataJson, Long logId);
 
     List<CrmCustomerAnalyze> selectCrmCustomerAnalyzeListAll(CrmCustomerAnalyze crmCustomerAnalyze);
+
+    String aiIntentionDegree(String content , Long chatId);
 }

+ 305 - 14
fs-service/src/main/java/com/fs/crm/service/impl/CrmCustomerAnalyzeServiceImpl.java

@@ -13,17 +13,17 @@ import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.utils.DateUtils;
 import com.fs.crm.domain.CrmCustomerAnalyze;
 import com.fs.crm.mapper.CrmCustomerAnalyzeMapper;
+import com.fs.crm.param.PolishingScriptParam;
 import com.fs.crm.service.ICrmCustomerAnalyzeService;
 import com.fs.crm.utils.CrmCustomerAiTagUtil;
 import com.fs.system.mapper.SysDictDataMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -35,6 +35,7 @@ import java.util.stream.Collectors;
 @Service
 public class CrmCustomerAnalyzeServiceImpl extends ServiceImpl<CrmCustomerAnalyzeMapper, CrmCustomerAnalyze> implements ICrmCustomerAnalyzeService {
 
+    private static final Logger log = LoggerFactory.getLogger(CrmCustomerAnalyzeServiceImpl.class);
     @Autowired
     private SysDictDataMapper sysDictDataMapper;
     /**
@@ -114,9 +115,11 @@ public class CrmCustomerAnalyzeServiceImpl extends ServiceImpl<CrmCustomerAnalyz
     //ai获取客户画像
     @Override
     @Async
-    public void aiGeneratedCustomerPortrait(String customerId, String dataJson,String logId) {
-        Map<String, Object> stringObjectMap = buildRequestParam(Long.valueOf(customerId), dataJson);
-        R aiResponse = CrmCustomerAiTagUtil.callAiService(stringObjectMap, Long.valueOf(logId));
+    public void aiGeneratedCustomerPortrait(Long customerId, String dataJson,Long logId) {
+        Map<String, Object> stringObjectMap = buildRequestParam(customerId, dataJson);
+        stringObjectMap.put("modelType","客户画像");
+        log.info("请求参数:{}", stringObjectMap);
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(stringObjectMap, logId);
 
         JSONObject root = JSON.parseObject(JSONUtil.toJsonStr(aiResponse));
 
@@ -147,7 +150,247 @@ public class CrmCustomerAnalyzeServiceImpl extends ServiceImpl<CrmCustomerAnalyz
         }
 
         if (userInfo != null) {
-            baseMapper.updateCustomerPortrait(Long.valueOf(customerId),userInfo.toString());
+            CrmCustomerAnalyze crmCustomerAnalyze = new CrmCustomerAnalyze();
+            crmCustomerAnalyze.setCustomerId(customerId);
+            crmCustomerAnalyze.setCustomerPortraitJson(userInfo.toString());
+            baseMapper.updateCustomerPortrait(crmCustomerAnalyze);
+        }
+    }
+
+    @Override
+    @Async
+    public void aiCommunicationSummary(Long customerId, String dataJson, Long logId) {
+        Map<String, Object> stringObjectMap = buildRequestParam(customerId, dataJson);
+        stringObjectMap.put("modelType","沟通总结");
+        log.info("请求参数:{}", stringObjectMap);
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(stringObjectMap, logId);
+        JSONObject root = JSON.parseObject(JSONUtil.toJsonStr(aiResponse));
+        System.out.println(aiResponse);
+// 获取 data.responseData
+        JSONArray responseData = root.getJSONObject("data").getJSONArray("responseData");
+
+        JSONArray summary = null;
+
+// 遍历 responseData
+        for (int i = 0; i < responseData.size(); i++) {
+            JSONObject node = responseData.getJSONObject(i);
+            JSONArray historyPreview = node.getJSONArray("historyPreview");
+
+            if (historyPreview != null) {
+                for (int j = 0; j < historyPreview.size(); j++) {
+                    JSONObject historyItem = historyPreview.getJSONObject(j);
+
+                    // 找到 obj 为 "AI" 的项
+                    if ("AI".equals(historyItem.getString("obj"))) {
+                        String valueStr = historyItem.getString("value");
+                        JSONObject valueObj = JSON.parseObject(valueStr);
+                        summary = valueObj.getJSONArray("tagInfos");
+                        break;
+                    }
+                }
+            }
+            if (summary != null) break;
+        }
+        StringBuilder summaryText = new StringBuilder();
+        if (summary!= null && !summary.isEmpty()) {
+            for (int i = 0; i < summary.size(); i++) {
+                summaryText.append(summary.get(i)).append(",");
+            }
+            summaryText.delete(summaryText.length()-1,summaryText.length());
+            CrmCustomerAnalyze crmCustomerAnalyze = new CrmCustomerAnalyze();
+            crmCustomerAnalyze.setCustomerId(customerId);
+            crmCustomerAnalyze.setCommunicationSummary(summaryText.toString());
+            baseMapper.updateCustomerPortrait(crmCustomerAnalyze);
+        }
+    }
+
+    @Override
+    @Async
+    public void aiCommunicationAbstract(Long customerId, String dataJson, Long logId) {
+        Map<String, Object> stringObjectMap = buildRequestParam(customerId, dataJson);
+        stringObjectMap.put("modelType","沟通摘要");
+        log.info("请求参数:{}", stringObjectMap);
+
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(stringObjectMap, logId);
+        JSONObject root = JSON.parseObject(JSONUtil.toJsonStr(aiResponse));
+
+// 获取 data.responseData
+        JSONArray responseData = root.getJSONObject("data").getJSONArray("responseData");
+
+        String summary = null;
+
+// 遍历 responseData
+        for (int i = 0; i < responseData.size(); i++) {
+            JSONObject node = responseData.getJSONObject(i);
+            JSONArray historyPreview = node.getJSONArray("historyPreview");
+
+            if (historyPreview != null) {
+                for (int j = 0; j < historyPreview.size(); j++) {
+                    JSONObject historyItem = historyPreview.getJSONObject(j);
+
+                    // 找到 obj 为 "AI" 的项
+                    if ("AI".equals(historyItem.getString("obj"))) {
+                        String valueStr = historyItem.getString("value");
+                        JSONObject valueObj = JSON.parseObject(valueStr);
+                        summary = valueObj.getString("userContent");
+                        break;
+                    }
+                }
+            }
+            if (summary != null) break;
+        }
+        if (summary != null){
+            CrmCustomerAnalyze c = new CrmCustomerAnalyze();
+            c.setCustomerId(customerId);
+            c.setCommunicationAbstract(summary);
+            baseMapper.updateCustomerPortrait(c);
+        }
+    }
+
+    @Override
+    @Async
+    public void aiAttritionLevel(Long customerId, String dataJson, Long logId) {
+        Map<String, Object> stringObjectMap = buildRequestParam(customerId, dataJson);
+        stringObjectMap.put("modelType","流失风险等级");
+        log.info("请求参数:{}", stringObjectMap);
+
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(stringObjectMap, logId);
+        JSONObject root = JSON.parseObject(JSONUtil.toJsonStr(aiResponse));
+
+// 获取 data.responseData
+        JSONArray responseData = root.getJSONObject("data").getJSONArray("responseData");
+
+        String summary = null;
+
+// 遍历 responseData
+        for (int i = 0; i < responseData.size(); i++) {
+            JSONObject node = responseData.getJSONObject(i);
+            JSONArray historyPreview = node.getJSONArray("historyPreview");
+
+            if (historyPreview != null) {
+                for (int j = 0; j < historyPreview.size(); j++) {
+                    JSONObject historyItem = historyPreview.getJSONObject(j);
+
+                    // 找到 obj 为 "AI" 的项
+                    if ("AI".equals(historyItem.getString("obj"))) {
+                        String valueStr = historyItem.getString("value");
+                        JSONObject valueObj = JSON.parseObject(valueStr);
+                        summary = valueObj.getString("tagInfos");
+                        break;
+                    }
+                }
+            }
+            if (summary != null) break;
+        }
+        if (summary != null){
+            //todo 响应处理
+        }
+    }
+
+    @Override
+    @Async
+    public void aiCustomerFocus(Long customerId, String dataJson, Long logId) {
+        Map<String, Object> stringObjectMap = buildRequestParam(customerId, dataJson);
+        stringObjectMap.put("modelType","客户关注点");
+        log.info("请求参数:{}", stringObjectMap);
+
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(stringObjectMap, logId);
+        System.out.println(aiResponse);
+        JSONObject root = JSON.parseObject(JSONUtil.toJsonStr(aiResponse));
+
+// 获取 data.responseData
+        JSONArray responseData = root.getJSONObject("data").getJSONArray("responseData");
+
+        JSONArray summary = null;
+
+// 遍历 responseData
+        for (int i = 0; i < responseData.size(); i++) {
+            JSONObject node = responseData.getJSONObject(i);
+            JSONArray historyPreview = node.getJSONArray("historyPreview");
+
+            if (historyPreview != null) {
+                for (int j = 0; j < historyPreview.size(); j++) {
+                    JSONObject historyItem = historyPreview.getJSONObject(j);
+
+                    // 找到 obj 为 "AI" 的项
+                    if ("AI".equals(historyItem.getString("obj"))) {
+                        String valueStr = historyItem.getString("value");
+                        JSONObject valueObj = JSON.parseObject(valueStr);
+                        summary = valueObj.getJSONArray("userContent");
+                        break;
+                    }
+                }
+            }
+            if (summary != null) break;
+        }
+        if (summary != null){
+            List<String> list = new ArrayList<String>();
+            summary.forEach(o->{
+                JSONObject jsonObject = (JSONObject) o;
+                list.add(jsonObject.getString("tagName"));
+            });
+            CrmCustomerAnalyze crmCustomerAnalyze = new CrmCustomerAnalyze();
+            crmCustomerAnalyze.setCustomerId(customerId);
+            crmCustomerAnalyze.setCustomerFocusJson(list.toString());
+            baseMapper.updateCustomerPortrait(crmCustomerAnalyze);
+        }
+    }
+
+    @Override
+    public String polishingScript(PolishingScriptParam param) {
+        Map<String, Object> requestParam = new HashMap<>();
+        requestParam.put("history", param.getContent());
+        requestParam.put("modelType","话术润色");
+        requestParam.putAll(param.getPortrait());
+
+        // 设置其他参数
+        requestParam.put("tagInfos", Collections.emptyList());
+        requestParam.put("isRepository", "");
+        requestParam.put("userContent", "");
+        requestParam.put("aiContent", "");
+        requestParam.put("likeRatio", "");
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(requestParam, Long.valueOf(param.getChatId()));
+        System.out.println(aiResponse);
+        return "";
+    }
+
+    @Override
+    public void aiIntentionDegree(Long customerId, String dataJson, Long logId) {
+        Map<String, Object> stringObjectMap = buildRequestParam(customerId, dataJson);
+        stringObjectMap.put("modelType","客户意向度");
+        log.info("请求参数:{}", stringObjectMap);
+
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(stringObjectMap, logId);
+        System.out.println(aiResponse);
+        JSONObject root = JSON.parseObject(JSONUtil.toJsonStr(aiResponse));
+
+// 获取 data.responseData
+        JSONArray responseData = root.getJSONObject("data").getJSONArray("responseData");
+
+        JSONArray summary = null;
+
+// 遍历 responseData
+        for (int i = 0; i < responseData.size(); i++) {
+            JSONObject node = responseData.getJSONObject(i);
+            JSONArray historyPreview = node.getJSONArray("historyPreview");
+
+            if (historyPreview != null) {
+                for (int j = 0; j < historyPreview.size(); j++) {
+                    JSONObject historyItem = historyPreview.getJSONObject(j);
+
+                    // 找到 obj 为 "AI" 的项
+                    if ("AI".equals(historyItem.getString("obj"))) {
+                        String valueStr = historyItem.getString("value");
+                        JSONObject valueObj = JSON.parseObject(valueStr);
+                        summary = valueObj.getJSONArray("userContent");
+                        break;
+                    }
+                }
+            }
+            if (summary != null) break;
+        }
+        if (summary != null) {
+            //todo 响应处理
         }
     }
 
@@ -156,6 +399,57 @@ public class CrmCustomerAnalyzeServiceImpl extends ServiceImpl<CrmCustomerAnalyz
         return baseMapper.selectCrmCustomerAnalyzeListAll(crmCustomerAnalyze);
     }
 
+    @Override
+    public String aiIntentionDegree(String content, Long chatId) {
+        Map<String, Object> requestParam = new HashMap<>();
+
+        // 获取各类数据
+        requestParam.put("history", content);
+
+        // 设置其他参数
+        requestParam.put("tagInfos", Collections.emptyList());
+        requestParam.put("isRepository", "");
+        requestParam.put("userContent", "");
+        requestParam.put("aiContent", "");
+        requestParam.put("likeRatio", "");
+        requestParam.put("modelType","客户意向度");
+        log.info("请求参数:{}", requestParam);
+
+        R aiResponse = CrmCustomerAiTagUtil.callAiService(requestParam, chatId);
+        System.out.println(aiResponse);
+        JSONObject root = JSON.parseObject(JSONUtil.toJsonStr(aiResponse));
+
+// 获取 data.responseData
+        JSONArray responseData = root.getJSONObject("data").getJSONArray("responseData");
+
+        JSONArray summary = null;
+
+// 遍历 responseData
+        for (int i = 0; i < responseData.size(); i++) {
+            JSONObject node = responseData.getJSONObject(i);
+            JSONArray historyPreview = node.getJSONArray("historyPreview");
+
+            if (historyPreview != null) {
+                for (int j = 0; j < historyPreview.size(); j++) {
+                    JSONObject historyItem = historyPreview.getJSONObject(j);
+
+                    // 找到 obj 为 "AI" 的项
+                    if ("AI".equals(historyItem.getString("obj"))) {
+                        String valueStr = historyItem.getString("value");
+                        JSONObject valueObj = JSON.parseObject(valueStr);
+                        summary = valueObj.getJSONArray("userContent");
+                        break;
+                    }
+                }
+            }
+            if (summary != null) break;
+        }
+        if (summary != null) {
+            //todo 响应处理
+        }
+        return null;
+    }
+
     private Map<String, Object> buildRequestParam(Long customerId,
                                                          String communication) {
         Map<String, Object> requestParam = new HashMap<>();
@@ -169,7 +463,7 @@ public class CrmCustomerAnalyzeServiceImpl extends ServiceImpl<CrmCustomerAnalyz
             likeRatio = (String) userInfo.remove("likeRatio");
         }
         // 合并数据
-        requestParam.putAll(history);
+        requestParam.put("history",communication);
         requestParam.putAll(userInfo);
 
         // 设置其他参数
@@ -178,7 +472,6 @@ public class CrmCustomerAnalyzeServiceImpl extends ServiceImpl<CrmCustomerAnalyz
         requestParam.put("userContent", "");
         requestParam.put("aiContent", "");
         requestParam.put("likeRatio", likeRatio);
-        requestParam.put("modelType","客户画像");
 
         return requestParam;
     }
@@ -189,16 +482,14 @@ public class CrmCustomerAnalyzeServiceImpl extends ServiceImpl<CrmCustomerAnalyz
 //        userInfo.put("name", crmCustomerAnalyze.getCustomerName()==null?"" : crmCustomerAnalyze.getCustomerName());
         List<SysDictData> portraits = sysDictDataMapper.selectDictDataByType(AI_PORTRAIT);
         List<String> dictValue = portraits.stream().map(SysDictData::getDictValue).collect(Collectors.toList());
-        Map<String, String> portraitMap = portraits.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
+//        Map<String, String> portraitMap = portraits.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
 
         if (crmCustomerAnalyze.getCustomerPortraitJson() != null){
             Map<String, String> portraitList = JSON.parseObject(
                     crmCustomerAnalyze.getCustomerPortraitJson(),
                     new TypeReference<Map<String, String>>() {}
             );
-            portraitList.forEach((k, v)->{
-                if(ObjectUtil.isNotEmpty(portraitMap.get(k)))userInfo.put(portraitMap.get(k),v);
-            });
+            userInfo.putAll(portraitList);
 
         }else {
             dictValue.forEach(o->{

+ 16 - 7
fs-service/src/main/java/com/fs/crm/utils/CrmCustomerAiTagUtil.java

@@ -31,6 +31,8 @@ import com.fs.fastgptApi.param.ChatParam;
 import com.fs.fastgptApi.service.ChatService;
 import com.fs.hisapi.util.MapUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
@@ -54,9 +56,17 @@ public class CrmCustomerAiTagUtil {
 
     private static String APP_KEY;
 
+    // 1. 声明静态变量
+    private static RedisTemplate redisTemplate;
+
+    // 2. 注入实例到非静态变量
+    @Autowired
+    @Qualifier("redisTemplate")
+    private RedisTemplate redisTemplateInstance;
     @PostConstruct
     public void initStatic() {
         APP_KEY = this.appKey;
+        redisTemplate = this.redisTemplateInstance;
     }
 
     public static List<CrmCustomerAiTagVo> getCrmCustomerAiTag(CrmCustomerAiTagParam content) throws JsonProcessingException {
@@ -77,7 +87,7 @@ public class CrmCustomerAiTagUtil {
         List<CrmCustomerAiTagVo> results = parseAiResponse(aiResponse, customerId);
 
         // 5. 异步保存到Redis,后续调用ai分析其他数据 //暂时只传聊天记录
-        saveToRedisAsync(customerId, (String) requestParam.get("history"),logId);
+        saveToRedisAsync(customerId,  requestParam.get("history").toString(),logId);
         return results;
     }
     private static void saveToRedisAsync(Long customerId, String aiResponse, Long logId) {
@@ -90,8 +100,6 @@ public class CrmCustomerAiTagUtil {
                 dataMap.put("logId", logId);
                 dataMap.put("timestamp", System.currentTimeMillis());
 
-                RedisTemplate<String, Object> redisTemplate = SpringUtils.getBean(RedisTemplate.class);
-
                 // 存储队列索引
                 redisTemplate.opsForList().rightPush(CRM_AI_REDIS_KEY, dataMap);
 
@@ -382,10 +390,11 @@ public class CrmCustomerAiTagUtil {
             }
         });
         if (!maps.isEmpty()){
-            CrmCustomerAnalyze crmCustomerInfo = new CrmCustomerAnalyze();
-            crmCustomerInfo.setCustomerId(Long.valueOf(customerId));
-            crmCustomerInfo.setAiChatRecord(JSONUtil.toJsonStr(maps));
-            SpringUtils.getBean(CrmCustomerAnalyzeMapper.class).insertCrmCustomerAnalyze(crmCustomerInfo);
+            CrmCustomerAnalyzeMapper bean = SpringUtils.getBean(CrmCustomerAnalyzeMapper.class);
+            CrmCustomerAnalyze crmCustomerAnalyze = bean.selectLatestOne(Long.valueOf(customerId));
+            crmCustomerAnalyze.setAiChatRecord(JSONUtil.toJsonStr(maps));
+            crmCustomerAnalyze.setCreateTime(new Date());
+            bean.insertCrmCustomerAnalyze(crmCustomerAnalyze);
         }
 
         return result;

+ 25 - 1
fs-service/src/main/java/com/fs/erp/utils/WeizouApiClient.java

@@ -1,6 +1,7 @@
 package com.fs.erp.utils;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fs.common.utils.CloudHostUtils;
 import com.fs.erp.domain.WeizouApiPushOrderParam;
 import lombok.extern.slf4j.Slf4j;
 import okhttp3.*;
@@ -48,6 +49,8 @@ public class WeizouApiClient {
 
     @Value("${weizou.appSecret:a6cd645383a3405d842ce00da106ded0}")
     private String appSecretInstance;
+    @Value("${weizou.createName:wz_5dd9126f39b84ae096a0e18ea313559a}")
+    private String createName;
     // 3. @PostConstruct 将实例赋值给静态变量
     @PostConstruct
     public void initStatic() {
@@ -56,6 +59,7 @@ public class WeizouApiClient {
         BASE_URL = this.baseUrlInstance;
         APP_ID = this.appIdInstance;
         APP_SECRET = this.appSecretInstance;
+        CREATE_NAME = this.createName;
         log.info("配置加载完成:BASE_URL={}, APP_ID={}", BASE_URL, APP_ID);
     }
 
@@ -63,6 +67,7 @@ public class WeizouApiClient {
     // TODO: 替换为平台提供的实际应用ID和密钥
     private static  String APP_ID ;
     private static  String APP_SECRET;
+    private static String CREATE_NAME;
 
     private static final String WEIZOU_API_CLIENT_KEY = "weizou:api:client:key";
 
@@ -156,7 +161,7 @@ public class WeizouApiClient {
      */
     public static String pushOrder(WeizouApiPushOrderParam orderData) throws IOException {
         String token = getAccessToken();
-
+        orderData.setCreateName(CREATE_NAME);
         String orderJson = objectMapper.writeValueAsString(orderData);
 
         Request request = new Request.Builder()
@@ -176,6 +181,25 @@ public class WeizouApiClient {
         }
     }
 
+    public static String cancelOrder(Map<String, Object> orderData) throws IOException {
+        String token = getAccessToken();
+        String orderJson = objectMapper.writeValueAsString(orderData);
+
+        Request request = new Request.Builder()
+                .url(BASE_URL + "/cs/api/storeOrder/thirdParty/cancel")
+                .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), orderJson))
+                .addHeader("Content-Type", "application/json")
+                .addHeader("token", token) // 假设使用Bearer Token
+                // TODO: 根据文档添加其他必要的Headers
+                .build();
+        try (Response response = httpClient.newCall(request).execute()) {
+            if (!response.isSuccessful()) {
+                log.error("取消失败:"+response.code()+response.message());
+                throw new IOException("订单推送失败,HTTP状态码: " + response.code());
+            }
+            return response.body().string();
+        }
+    }
     // ========== 内部辅助类 ==========
 
     /**

+ 14 - 1
fs-service/src/main/resources/mapper/crm/CrmCustomerAnalyzeMapper.xml

@@ -114,7 +114,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
     <update id="updateCustomerPortrait">
         update crm_customer_analyze
-        set customer_portrait_json = #{customerPortrait}
+        <set>
+            <if test="customerPortraitJson != null and customerPortraitJson != ''">
+                customer_portrait_json = #{customerPortraitJson},
+            </if>
+            <if test="communicationSummary != null and communicationSummary != ''">
+                communication_summary = #{communicationSummary},
+            </if>
+            <if test="communicationAbstract != null and communicationAbstract != ''">
+                communication_abstract = #{communicationAbstract},
+            </if>
+            <if test="customerFocusJson != null and customerFocusJson != ''">
+                customer_focus_json = #{customerFocusJson},
+            </if>
+        </set>
         where customer_id = #{customerId}
         ORDER BY create_time DESC
         LIMIT 1

+ 3 - 1
fs-service/src/main/resources/mapper/crm/CrmCustomerMapper.xml

@@ -554,6 +554,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             id,customer_id,name,sex,age,address,habits,illness_time,body,study,course_status,course,family,family_disease,disease,is_line,
             talk,user_type,is_self,intensify,is_cold,cold_body,sweat,other,toilet,eat,menses,medicine,constitution,recommend_medicine,
             consult_product,is_buy,buy_product,create_time,update_time,reply_time,product_talk,disease_talk,channel_type
-        FROM crm_customer_info;
+        FROM crm_customer_info
+        where
+            customer_id = #{customerId};
     </select>
 </mapper>