1811872455@163.com 1 mesiac pred
rodič
commit
370ed4c44b
28 zmenil súbory, kde vykonal 699 pridanie a 10 odobranie
  1. 4 0
      java/storlead-api/pom.xml
  2. 5 1
      java/storlead-api/src/main/java/com/storlead/api/StorleadTradeApplication.java
  3. 1 1
      java/storlead-crm/storlead-acquisition/src/main/java/com/storlead/crm/acquisition/package-info.java
  4. 31 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/controller/CustomerAiAnalysisController.java
  5. 16 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/dto/CustomerSingleAnalysisRequestDTO.java
  6. 62 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/CustomerAnalysisResultEntity.java
  7. 54 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/CustomerCompanyEntity.java
  8. 100 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/CustomerEntity.java
  9. 88 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/LiaisonEntity.java
  10. 9 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/CustomerAnalysisResultEntityMapper.java
  11. 9 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/CustomerCompanyEntityMapper.java
  12. 9 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/CustomerEntityMapper.java
  13. 9 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/LiaisonEntityMapper.java
  14. 8 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerAiAnalysisService.java
  15. 7 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerAnalysisResultEntityService.java
  16. 7 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerCompanyEntityService.java
  17. 7 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerEntityService.java
  18. 7 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/LiaisonEntityService.java
  19. 190 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerAiAnalysisServiceImpl.java
  20. 13 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerAnalysisResultEntityServiceImpl.java
  21. 13 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerCompanyEntityServiceImpl.java
  22. 11 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerEntityServiceImpl.java
  23. 11 0
      java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/LiaisonEntityServiceImpl.java
  24. 5 0
      java/storlead-crm/storlead-customer/src/main/resources/mapper/CustomerAnalysisResultEntityMapper.xml
  25. 5 0
      java/storlead-crm/storlead-customer/src/main/resources/mapper/CustomerCompanyEntityMapper.xml
  26. 5 0
      java/storlead-crm/storlead-customer/src/main/resources/mapper/CustomerEntityMapper.xml
  27. 5 0
      java/storlead-crm/storlead-customer/src/main/resources/mapper/LiaisonEntityMapper.xml
  28. 8 8
      pom.xml

+ 4 - 0
java/storlead-api/pom.xml

@@ -23,6 +23,10 @@
             <groupId>com.storlead.boot</groupId>
             <groupId>com.storlead.boot</groupId>
             <artifactId>storlead-account-api</artifactId>
             <artifactId>storlead-account-api</artifactId>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>com.storlead.boot</groupId>
+            <artifactId>storlead-customer</artifactId>
+        </dependency>
         <dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
             <artifactId>spring-boot-starter-web</artifactId>

+ 5 - 1
java/storlead-api/src/main/java/com/storlead/api/StorleadTradeApplication.java

@@ -12,7 +12,11 @@ import org.springframework.core.env.Environment;
 import java.net.InetAddress;
 import java.net.InetAddress;
 
 
 @SpringBootApplication(scanBasePackages = "com.storlead")
 @SpringBootApplication(scanBasePackages = "com.storlead")
-@MapperScan({"com.storlead.account.tenant.mapper", "com.storlead.account.system.mapper"})
+@MapperScan({
+        "com.storlead.account.tenant.mapper",
+        "com.storlead.account.system.mapper",
+        "com.storlead.crm.customer.mapper"
+})
 @Slf4j
 @Slf4j
 public class StorleadTradeApplication {
 public class StorleadTradeApplication {
 
 

+ 1 - 1
java/storlead-crm/storlead-acquisition/src/main/java/com/storlead/crm/acquisition/package-info.java

@@ -1,4 +1,4 @@
 /**
 /**
- * 获客。
+ * 获客模块
  */
  */
 package com.storlead.crm.acquisition;
 package com.storlead.crm.acquisition;

+ 31 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/controller/CustomerAiAnalysisController.java

@@ -0,0 +1,31 @@
+package com.storlead.crm.customer.controller;
+
+import com.storlead.crm.customer.dto.CustomerSingleAnalysisRequestDTO;
+import com.storlead.crm.customer.entity.CustomerAnalysisResultEntity;
+import com.storlead.crm.customer.service.CustomerAiAnalysisService;
+import com.storlead.framework.web.assemble.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+@RestController
+@RequestMapping("/customer/analysis")
+@Api(tags = "客户AI分析")
+public class CustomerAiAnalysisController {
+
+    @Resource
+    private CustomerAiAnalysisService customerAiAnalysisService;
+
+    @PostMapping("/single")
+    @ApiOperation("单客户AI分析并保存结果")
+    public Result<Object> analyzeSingle(@RequestBody CustomerSingleAnalysisRequestDTO request) {
+        if (request == null || request.getCustomerId() == null) {
+            return Result.error("customerId不能为空");
+        }
+        CustomerAnalysisResultEntity result = customerAiAnalysisService
+                .analyzeSingleCustomer(request.getCustomerId(), request.getAnalysisScene());
+        return Result.ok(result);
+    }
+}

+ 16 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/dto/CustomerSingleAnalysisRequestDTO.java

@@ -0,0 +1,16 @@
+package com.storlead.crm.customer.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "CustomerSingleAnalysisRequestDTO", description = "单客户AI分析请求")
+public class CustomerSingleAnalysisRequestDTO {
+
+    @ApiModelProperty(value = "客户ID", required = true)
+    private Long customerId;
+
+    @ApiModelProperty(value = "分析场景,默认 potential")
+    private String analysisScene;
+}

+ 62 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/CustomerAnalysisResultEntity.java

@@ -0,0 +1,62 @@
+package com.storlead.crm.customer.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("customer_analysis_result")
+@ApiModel(value = "CustomerAnalysisResultEntity", description = "客户分析结果")
+public class CustomerAnalysisResultEntity extends SysBaseField {
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+    @ApiModelProperty(value = "客户ID")
+    private Long customerId;
+    @ApiModelProperty(value = "分析批次号")
+    private String analysisBatchNo;
+    @ApiModelProperty(value = "分析场景")
+    private String analysisScene;
+    @ApiModelProperty(value = "分析状态")
+    private Integer analysisStatus;
+    @ApiModelProperty(value = "潜力分")
+    private Double potentialScore;
+    @ApiModelProperty(value = "客户等级")
+    private String customerLevel;
+    @ApiModelProperty(value = "置信度")
+    private Double confidence;
+    @ApiModelProperty(value = "优先级")
+    private Integer priority;
+    @ApiModelProperty(value = "核心标签")
+    private String coreTags;
+    @ApiModelProperty(value = "分析摘要")
+    private String reasonSummary;
+    @ApiModelProperty(value = "建议动作")
+    private String suggestedActions;
+    @ApiModelProperty(value = "风险信号")
+    private String riskSignals;
+    @ApiModelProperty(value = "特征快照")
+    private String featureSnapshot;
+    @ApiModelProperty(value = "模型名称")
+    private String modelName;
+    @ApiModelProperty(value = "模型版本")
+    private String modelVersion;
+    @ApiModelProperty(value = "提示词版本")
+    private String promptVersion;
+    @ApiModelProperty(value = "错误码")
+    private String errorCode;
+    @ApiModelProperty(value = "错误信息")
+    private String errorMessage;
+    @ApiModelProperty(value = "建议下次跟进时间")
+    private Date nextFollowUpAt;
+    @ApiModelProperty(value = "分析时间")
+    private Date analysisTime;
+}

+ 54 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/CustomerCompanyEntity.java

@@ -0,0 +1,54 @@
+package com.storlead.crm.customer.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("customer_company")
+@ApiModel(value = "CustomerCompanyEntity", description = "客户企业信息")
+public class CustomerCompanyEntity extends SysBaseField {
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+    @ApiModelProperty(value = "关联客户ID")
+    private Long customerId;
+    @ApiModelProperty(value = "企业名称")
+    private String name;
+    @ApiModelProperty(value = "详细地址")
+    private String address;
+    @ApiModelProperty(value = "企业规模value")
+    private String scaleDictValue;
+    @ApiModelProperty(value = "企业网址")
+    private String website;
+    @ApiModelProperty(value = "其他网址1")
+    private String website1;
+    @ApiModelProperty(value = "其他网址2")
+    private String website2;
+    @ApiModelProperty(value = "其他网址3")
+    private String website3;
+    @ApiModelProperty(value = "所属行业")
+    private String industry;
+    @ApiModelProperty(value = "通信地址")
+    private String communicationAddress;
+    @ApiModelProperty(value = "邮政编码")
+    private String postcode;
+    @ApiModelProperty(value = "传真号码")
+    private String faxNumber;
+    @ApiModelProperty(value = "电子邮箱")
+    private String email;
+    @ApiModelProperty(value = "公司备用邮箱1")
+    private String email1;
+    @ApiModelProperty(value = "公司备用邮箱2")
+    private String email2;
+    @ApiModelProperty(value = "公司备用邮箱3")
+    private String email3;
+    @ApiModelProperty(value = "联系电话")
+    private String telephone;
+}

+ 100 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/CustomerEntity.java

@@ -0,0 +1,100 @@
+package com.storlead.crm.customer.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("customer")
+@ApiModel(value = "CustomerEntity", description = "客户基本信息")
+public class CustomerEntity extends SysBaseField {
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+    @ApiModelProperty(value = "编码")
+    private String dataCode;
+    @ApiModelProperty(value = "客户种类(10客户、11线索)")
+    private Integer customerForm;
+    @ApiModelProperty(value = "是否从线索过来(0否,1是)")
+    private Integer hasFromClue;
+    @ApiModelProperty(value = "是否公海客户(0否,1是)")
+    private Integer hasPublicCustomer;
+    @ApiModelProperty(value = "是否垃圾客户(0否,1是)")
+    private Integer hasGarbageCustomer;
+    @ApiModelProperty(value = "是否重点关注(0否,1是)")
+    private Integer hasFollowCustomer;
+    @ApiModelProperty(value = "客户代码")
+    private String customerCode;
+    @ApiModelProperty(value = "所属大洲")
+    private String continent;
+    @ApiModelProperty(value = "所属国家")
+    private String country;
+    @ApiModelProperty(value = "客户名称")
+    private String customerName;
+    @ApiModelProperty(value = "协作人员ID,逗号分割")
+    private String collaborator;
+    @ApiModelProperty(value = "意向产品ID,逗号分隔")
+    private String intendedProductsIds;
+    @ApiModelProperty(value = "意向产品名称,逗号分隔")
+    private String intendedProductsNames;
+    @ApiModelProperty(value = "线索状态value")
+    private String clueStatusDictValue;
+    @ApiModelProperty(value = "客户状态value")
+    private String customerStatusDictValue;
+    @ApiModelProperty(value = "客户来源value")
+    private String customerSourceDictValue;
+    @ApiModelProperty(value = "客户类型value")
+    private String customerTypeDictValue;
+    @ApiModelProperty(value = "代理合作客户ID")
+    private Long cooperativeCustomerId;
+    @ApiModelProperty(value = "客户等级value")
+    private String customerLevelDictValue;
+    @ApiModelProperty(value = "客户信用等级value")
+    private String customerCreditLevelDictValue;
+    @ApiModelProperty(value = "客户经济性质value")
+    private String customerEconomicNatureDictValue;
+    @ApiModelProperty(value = "助记名称")
+    private String mnemonicName;
+    @ApiModelProperty(value = "备注信息")
+    private String remark;
+    @ApiModelProperty(value = "开户行")
+    private String openingBank;
+    @ApiModelProperty(value = "税号")
+    private String taxNumber;
+    @ApiModelProperty(value = "银行账号")
+    private String bankAccount;
+    @ApiModelProperty(value = "置公原因value")
+    private String reasonPublicCustomerDictValue;
+    @ApiModelProperty(value = "是否有订单(0否,1是)")
+    private Integer hasOrderForm;
+    @ApiModelProperty(value = "最后跟进时间")
+    private Date lastFollowUpTime;
+    @ApiModelProperty(value = "未跟进天数")
+    private Integer noFollowUpDate;
+    @ApiModelProperty(value = "置公日期")
+    private Date publicDate;
+    @ApiModelProperty(value = "置公提醒日期")
+    private Date publicRemindDate;
+    @ApiModelProperty(value = "转垃圾客户日期")
+    private Date garbageDate;
+    @ApiModelProperty(value = "转垃圾客户提醒日期")
+    private Date garbageRemindDate;
+    @ApiModelProperty(value = "清除日期")
+    private Date deleteDate;
+    @ApiModelProperty(value = "清除预警日期")
+    private Date deleteRemindDate;
+    @ApiModelProperty(value = "客户归属时间")
+    private Date ownerTime;
+    @ApiModelProperty(value = "放弃时间")
+    private Date giveUpTime;
+    @ApiModelProperty(value = "前拥有者")
+    private Long formerOwnerBy;
+}

+ 88 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/entity/LiaisonEntity.java

@@ -0,0 +1,88 @@
+package com.storlead.crm.customer.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("liaison")
+@ApiModel(value = "LiaisonEntity", description = "联系人")
+public class LiaisonEntity extends SysBaseField {
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+    @ApiModelProperty(value = "关联客户ID")
+    private Long customerId;
+    @ApiModelProperty(value = "是否首要联系人(0否,1是)")
+    private Integer hasPrimaryLialison;
+    @ApiModelProperty(value = "联系人姓名")
+    private String name;
+    @TableField("`call`")
+    @ApiModelProperty(value = "尊称(0未知,1先生,2女士)")
+    private Integer call;
+    @ApiModelProperty(value = "资源类型")
+    private String resourceType;
+    @ApiModelProperty(value = "资源类型关联ID")
+    private Long resourceTypeId;
+    @ApiModelProperty(value = "联系人角色value")
+    private String liaisonRoleDictValue;
+    @ApiModelProperty(value = "生日")
+    private Date birthday;
+    @ApiModelProperty(value = "部门职务")
+    private String departmentPosition;
+    @ApiModelProperty(value = "手机号码")
+    private String telephone;
+    @ApiModelProperty(value = "电子邮箱")
+    private String email;
+    @ApiModelProperty(value = "备用邮箱1")
+    private String email1;
+    @ApiModelProperty(value = "备用邮箱2")
+    private String email2;
+    @ApiModelProperty(value = "备用邮箱3")
+    private String email3;
+    @ApiModelProperty(value = "传真号码")
+    private String faxNumber;
+    @ApiModelProperty(value = "邮政编码")
+    private String postcode;
+    @ApiModelProperty(value = "联系方式")
+    private String contactInformation;
+    @ApiModelProperty(value = "备注")
+    private String remark;
+    @ApiModelProperty(value = "QQ")
+    private String qq;
+    @ApiModelProperty(value = "Skype")
+    private String skype;
+    @ApiModelProperty(value = "旺旺")
+    private String wangwang;
+    @ApiModelProperty(value = "微信")
+    private String wechat;
+    @ApiModelProperty(value = "Twitter")
+    private String twitter;
+    @ApiModelProperty(value = "LinkedIn")
+    private String linkedin;
+    @ApiModelProperty(value = "Facebook")
+    private String facebook;
+    @ApiModelProperty(value = "Whatsapp")
+    private String whatsapp;
+    @ApiModelProperty(value = "固定电话")
+    private String fixedLineTelephone;
+    @ApiModelProperty(value = "宅电")
+    private String homeElectricity;
+    @ApiModelProperty(value = "详细地址")
+    private String address;
+    @ApiModelProperty(value = "国际区号")
+    private String internationalArea;
+    @ApiModelProperty(value = "最后跟进时间")
+    private Date lastFollowUpTime;
+    @ApiModelProperty(value = "前拥有者")
+    private Long formerOwnerBy;
+}

+ 9 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/CustomerAnalysisResultEntityMapper.java

@@ -0,0 +1,9 @@
+package com.storlead.crm.customer.mapper;
+
+import com.storlead.crm.customer.entity.CustomerAnalysisResultEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CustomerAnalysisResultEntityMapper extends MyBaseMapper<CustomerAnalysisResultEntity> {
+}

+ 9 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/CustomerCompanyEntityMapper.java

@@ -0,0 +1,9 @@
+package com.storlead.crm.customer.mapper;
+
+import com.storlead.crm.customer.entity.CustomerCompanyEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CustomerCompanyEntityMapper extends MyBaseMapper<CustomerCompanyEntity> {
+}

+ 9 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/CustomerEntityMapper.java

@@ -0,0 +1,9 @@
+package com.storlead.crm.customer.mapper;
+
+import com.storlead.crm.customer.entity.CustomerEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CustomerEntityMapper extends MyBaseMapper<CustomerEntity> {
+}

+ 9 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/mapper/LiaisonEntityMapper.java

@@ -0,0 +1,9 @@
+package com.storlead.crm.customer.mapper;
+
+import com.storlead.crm.customer.entity.LiaisonEntity;
+import com.storlead.framework.mybatis.mapper.MyBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface LiaisonEntityMapper extends MyBaseMapper<LiaisonEntity> {
+}

+ 8 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerAiAnalysisService.java

@@ -0,0 +1,8 @@
+package com.storlead.crm.customer.service;
+
+import com.storlead.crm.customer.entity.CustomerAnalysisResultEntity;
+
+public interface CustomerAiAnalysisService {
+
+    CustomerAnalysisResultEntity analyzeSingleCustomer(Long customerId, String analysisScene);
+}

+ 7 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerAnalysisResultEntityService.java

@@ -0,0 +1,7 @@
+package com.storlead.crm.customer.service;
+
+import com.storlead.crm.customer.entity.CustomerAnalysisResultEntity;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+public interface CustomerAnalysisResultEntityService extends MyBaseService<CustomerAnalysisResultEntity> {
+}

+ 7 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerCompanyEntityService.java

@@ -0,0 +1,7 @@
+package com.storlead.crm.customer.service;
+
+import com.storlead.crm.customer.entity.CustomerCompanyEntity;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+public interface CustomerCompanyEntityService extends MyBaseService<CustomerCompanyEntity> {
+}

+ 7 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/CustomerEntityService.java

@@ -0,0 +1,7 @@
+package com.storlead.crm.customer.service;
+
+import com.storlead.crm.customer.entity.CustomerEntity;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+public interface CustomerEntityService extends MyBaseService<CustomerEntity> {
+}

+ 7 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/LiaisonEntityService.java

@@ -0,0 +1,7 @@
+package com.storlead.crm.customer.service;
+
+import com.storlead.crm.customer.entity.LiaisonEntity;
+import com.storlead.framework.mybatis.service.MyBaseService;
+
+public interface LiaisonEntityService extends MyBaseService<LiaisonEntity> {
+}

+ 190 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerAiAnalysisServiceImpl.java

@@ -0,0 +1,190 @@
+package com.storlead.crm.customer.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.storlead.crm.customer.entity.CustomerAnalysisResultEntity;
+import com.storlead.crm.customer.entity.CustomerCompanyEntity;
+import com.storlead.crm.customer.entity.CustomerEntity;
+import com.storlead.crm.customer.entity.LiaisonEntity;
+import com.storlead.crm.customer.service.*;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+@Service
+public class CustomerAiAnalysisServiceImpl implements CustomerAiAnalysisService {
+
+    private static final String AI_ANALYSIS_URL = "http://127.0.0.1:18080/mock/ai/customer/analyze";
+
+    @Resource
+    private CustomerEntityService customerEntityService;
+    @Resource
+    private CustomerCompanyEntityService customerCompanyEntityService;
+    @Resource
+    private LiaisonEntityService liaisonEntityService;
+    @Resource
+    private CustomerAnalysisResultEntityService customerAnalysisResultEntityService;
+
+    @Override
+    public CustomerAnalysisResultEntity analyzeSingleCustomer(Long customerId, String analysisScene) {
+        if (customerId == null) {
+            throw new IllegalArgumentException("customerId不能为空");
+        }
+
+        CustomerEntity customer = customerEntityService.getOne(new LambdaQueryWrapper<CustomerEntity>()
+                .eq(CustomerEntity::getId, customerId)
+                .eq(CustomerEntity::getIsDelete, 0)
+                .last("limit 1"));
+        if (customer == null) {
+            throw new IllegalArgumentException("客户不存在");
+        }
+
+        CustomerCompanyEntity company = customerCompanyEntityService.getOne(new LambdaQueryWrapper<CustomerCompanyEntity>()
+                .eq(CustomerCompanyEntity::getCustomerId, customerId)
+                .eq(CustomerCompanyEntity::getIsDelete, 0)
+                .orderByDesc(CustomerCompanyEntity::getId)
+                .last("limit 1"));
+
+        List<LiaisonEntity> liaisons = liaisonEntityService.list(new LambdaQueryWrapper<LiaisonEntity>()
+                .eq(LiaisonEntity::getCustomerId, customerId)
+                .eq(LiaisonEntity::getIsDelete, 0)
+                .orderByDesc(LiaisonEntity::getHasPrimaryLialison)
+                .orderByDesc(LiaisonEntity::getLastFollowUpTime)
+                .last("limit 5"));
+
+        String scene = StringUtils.defaultIfBlank(analysisScene, "potential");
+        Map<String, Object> requestPayload = buildAiRequest(customer, company, liaisons, scene);
+
+        CustomerAnalysisResultEntity entity = new CustomerAnalysisResultEntity();
+        entity.setCustomerId(customer.getId());
+        entity.setTenantId(customer.getTenantId());
+        entity.setOwnerBy(customer.getOwnerBy());
+        entity.setAnalysisBatchNo(UUID.randomUUID().toString().replace("-", ""));
+        entity.setAnalysisScene(scene);
+        entity.setAnalysisTime(new Date());
+
+        try {
+            @SuppressWarnings("unchecked")
+            Map<String, Object> aiResult = new RestTemplate().postForObject(AI_ANALYSIS_URL, requestPayload, Map.class);
+            if (aiResult == null || aiResult.isEmpty()) {
+                aiResult = buildFallbackResult(customer, company, liaisons);
+            }
+            applyAiResult(entity, aiResult);
+            entity.setAnalysisStatus(1);
+        } catch (Exception e) {
+            Map<String, Object> fallback = buildFallbackResult(customer, company, liaisons);
+            applyAiResult(entity, fallback);
+            entity.setAnalysisStatus(0);
+            entity.setErrorCode("AI_CALL_FAILED");
+            entity.setErrorMessage(e.getMessage());
+        }
+
+        customerAnalysisResultEntityService.save(entity);
+        return entity;
+    }
+
+    private Map<String, Object> buildAiRequest(CustomerEntity customer,
+                                               CustomerCompanyEntity company,
+                                               List<LiaisonEntity> liaisons,
+                                               String scene) {
+        Map<String, Object> payload = new HashMap<>();
+        payload.put("analysisScene", scene);
+        payload.put("customer", customer);
+        payload.put("company", company);
+        payload.put("liaisons", liaisons);
+        return payload;
+    }
+
+    private void applyAiResult(CustomerAnalysisResultEntity entity, Map<String, Object> aiResult) {
+        entity.setPotentialScore(toDouble(aiResult.get("potentialScore"), 50D));
+        entity.setCustomerLevel(String.valueOf(aiResult.getOrDefault("customerLevel", "C")));
+        entity.setConfidence(toDouble(aiResult.get("confidence"), 70D));
+        entity.setPriority(toInteger(aiResult.get("priority"), 3));
+        entity.setCoreTags(String.valueOf(aiResult.getOrDefault("coreTags", "[]")));
+        entity.setReasonSummary(String.valueOf(aiResult.getOrDefault("reasonSummary", "基于客户基础信息自动分析")));
+        entity.setSuggestedActions(String.valueOf(aiResult.getOrDefault("suggestedActions", "[]")));
+        entity.setRiskSignals(String.valueOf(aiResult.getOrDefault("riskSignals", "[]")));
+        entity.setFeatureSnapshot(String.valueOf(aiResult.getOrDefault("featureSnapshot", "{}")));
+        entity.setModelName(String.valueOf(aiResult.getOrDefault("modelName", "mock-ai")));
+        entity.setModelVersion(String.valueOf(aiResult.getOrDefault("modelVersion", "v0")));
+        entity.setPromptVersion(String.valueOf(aiResult.getOrDefault("promptVersion", "p0")));
+        entity.setErrorCode(null);
+        entity.setErrorMessage(null);
+        entity.setNextFollowUpAt(calcNextFollowUpDate());
+    }
+
+    private Map<String, Object> buildFallbackResult(CustomerEntity customer,
+                                                    CustomerCompanyEntity company,
+                                                    List<LiaisonEntity> liaisons) {
+        Map<String, Object> result = new HashMap<>();
+        int score = 40;
+        if (customer.getHasOrderForm() != null && customer.getHasOrderForm() == 1) {
+            score += 20;
+        }
+        if (StringUtils.isNotBlank(customer.getIntendedProductsIds())) {
+            score += 15;
+        }
+        if (company != null && StringUtils.isNotBlank(company.getIndustry())) {
+            score += 10;
+        }
+        if (liaisons != null && !liaisons.isEmpty()) {
+            score += 10;
+        }
+        score = Math.min(score, 95);
+
+        String level;
+        if (score >= 80) {
+            level = "A";
+        } else if (score >= 65) {
+            level = "B";
+        } else if (score >= 50) {
+            level = "C";
+        } else {
+            level = "D";
+        }
+
+        result.put("potentialScore", score);
+        result.put("customerLevel", level);
+        result.put("confidence", 65);
+        result.put("priority", "A".equals(level) ? 1 : ("B".equals(level) ? 2 : 3));
+        result.put("coreTags", "[\"fallback-rule\",\"single-customer\"]");
+        result.put("reasonSummary", "AI接口不可用,已使用本地规则完成潜力分析");
+        result.put("suggestedActions", "[\"建议3日内首次触达\",\"建议补全关键联系人信息\"]");
+        result.put("riskSignals", score < 60 ? "[\"客户潜力偏低\"]" : "[]");
+        result.put("featureSnapshot", "{\"customerId\":" + customer.getId() + "}");
+        result.put("modelName", "fallback-rule-engine");
+        result.put("modelVersion", "rule-v1");
+        result.put("promptVersion", "local");
+        return result;
+    }
+
+    private Date calcNextFollowUpDate() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.DAY_OF_MONTH, 3);
+        return calendar.getTime();
+    }
+
+    private Double toDouble(Object val, Double defaultValue) {
+        if (val == null) {
+            return defaultValue;
+        }
+        try {
+            return Double.parseDouble(String.valueOf(val));
+        } catch (Exception ignored) {
+            return defaultValue;
+        }
+    }
+
+    private Integer toInteger(Object val, Integer defaultValue) {
+        if (val == null) {
+            return defaultValue;
+        }
+        try {
+            return Integer.parseInt(String.valueOf(val));
+        } catch (Exception ignored) {
+            return defaultValue;
+        }
+    }
+}

+ 13 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerAnalysisResultEntityServiceImpl.java

@@ -0,0 +1,13 @@
+package com.storlead.crm.customer.service.impl;
+
+import com.storlead.crm.customer.entity.CustomerAnalysisResultEntity;
+import com.storlead.crm.customer.mapper.CustomerAnalysisResultEntityMapper;
+import com.storlead.crm.customer.service.CustomerAnalysisResultEntityService;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CustomerAnalysisResultEntityServiceImpl
+        extends MyBaseServiceImpl<CustomerAnalysisResultEntityMapper, CustomerAnalysisResultEntity>
+        implements CustomerAnalysisResultEntityService {
+}

+ 13 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerCompanyEntityServiceImpl.java

@@ -0,0 +1,13 @@
+package com.storlead.crm.customer.service.impl;
+
+import com.storlead.crm.customer.entity.CustomerCompanyEntity;
+import com.storlead.crm.customer.mapper.CustomerCompanyEntityMapper;
+import com.storlead.crm.customer.service.CustomerCompanyEntityService;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CustomerCompanyEntityServiceImpl
+        extends MyBaseServiceImpl<CustomerCompanyEntityMapper, CustomerCompanyEntity>
+        implements CustomerCompanyEntityService {
+}

+ 11 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/CustomerEntityServiceImpl.java

@@ -0,0 +1,11 @@
+package com.storlead.crm.customer.service.impl;
+
+import com.storlead.crm.customer.entity.CustomerEntity;
+import com.storlead.crm.customer.mapper.CustomerEntityMapper;
+import com.storlead.crm.customer.service.CustomerEntityService;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CustomerEntityServiceImpl extends MyBaseServiceImpl<CustomerEntityMapper, CustomerEntity> implements CustomerEntityService {
+}

+ 11 - 0
java/storlead-crm/storlead-customer/src/main/java/com/storlead/crm/customer/service/impl/LiaisonEntityServiceImpl.java

@@ -0,0 +1,11 @@
+package com.storlead.crm.customer.service.impl;
+
+import com.storlead.crm.customer.entity.LiaisonEntity;
+import com.storlead.crm.customer.mapper.LiaisonEntityMapper;
+import com.storlead.crm.customer.service.LiaisonEntityService;
+import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service
+public class LiaisonEntityServiceImpl extends MyBaseServiceImpl<LiaisonEntityMapper, LiaisonEntity> implements LiaisonEntityService {
+}

+ 5 - 0
java/storlead-crm/storlead-customer/src/main/resources/mapper/CustomerAnalysisResultEntityMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.storlead.crm.customer.mapper.CustomerAnalysisResultEntityMapper">
+    <!-- 默认 CRUD 由 MyBatis-Plus BaseMapper 提供 -->
+</mapper>

+ 5 - 0
java/storlead-crm/storlead-customer/src/main/resources/mapper/CustomerCompanyEntityMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.storlead.crm.customer.mapper.CustomerCompanyEntityMapper">
+    <!-- 默认 CRUD 由 MyBatis-Plus BaseMapper 提供 -->
+</mapper>

+ 5 - 0
java/storlead-crm/storlead-customer/src/main/resources/mapper/CustomerEntityMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.storlead.crm.customer.mapper.CustomerEntityMapper">
+    <!-- 默认 CRUD 由 MyBatis-Plus BaseMapper 提供 -->
+</mapper>

+ 5 - 0
java/storlead-crm/storlead-customer/src/main/resources/mapper/LiaisonEntityMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.storlead.crm.customer.mapper.LiaisonEntityMapper">
+    <!-- 默认 CRUD 由 MyBatis-Plus BaseMapper 提供 -->
+</mapper>

+ 8 - 8
pom.xml

@@ -7,11 +7,11 @@
         <groupId>org.springframework.boot</groupId>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.7.0</version>
         <version>2.7.0</version>
-        <relativePath/> <!-- 或者默认 -->
+        <relativePath/> <!-- 或者默�-->
     </parent>
     </parent>
 
 
     <groupId>com.storlead.boot</groupId>
     <groupId>com.storlead.boot</groupId>
-    <artifactId>storlead-smarttrade-platform</artifactId>
+    <artifactId>storlead-saas-platform</artifactId>
     <version>1.0</version>
     <version>1.0</version>
     <packaging>pom</packaging>
     <packaging>pom</packaging>
     <name>storlead-smarttrade-platform</name>
     <name>storlead-smarttrade-platform</name>
@@ -28,7 +28,7 @@
         <java.version>11</java.version>
         <java.version>11</java.version>
         <maven.compiler.source>${java.version}</maven.compiler.source>
         <maven.compiler.source>${java.version}</maven.compiler.source>
         <maven.compiler.target>${java.version}</maven.compiler.target>
         <maven.compiler.target>${java.version}</maven.compiler.target>
-        <!--全局�置项目版本�-->
+        <!--全局�置项目版本�->
         <jwt.version>0.9.1</jwt.version>
         <jwt.version>0.9.1</jwt.version>
         <commons.version>2.6</commons.version>
         <commons.version>2.6</commons.version>
         <!-- 表示打包时跳过mvn test -->
         <!-- 表示打包时跳过mvn test -->
@@ -215,7 +215,7 @@
             <version>${io.jsonwebtoken.java.jwt.version}</version>
             <version>${io.jsonwebtoken.java.jwt.version}</version>
         </dependency>
         </dependency>
 
 
-        <!--  jwt 需�,移除会报错  -->
+        <!--  jwt 需�移除会报� -->
         <dependency>
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
             <groupId>io.jsonwebtoken</groupId>
             <artifactId>jjwt</artifactId>
             <artifactId>jjwt</artifactId>
@@ -281,7 +281,7 @@
         <dependency>
         <dependency>
             <groupId>com.alibaba</groupId>
             <groupId>com.alibaba</groupId>
             <artifactId>transmittable-thread-local</artifactId>
             <artifactId>transmittable-thread-local</artifactId>
-            <version>${transmittable.thread.version}</version> <!-- 建议使用最新版本 -->
+            <version>${transmittable.thread.version}</version> <!-- 建议使用最新版�-->
         </dependency>
         </dependency>
 
 
         <!-- mybatis-plus -->
         <!-- mybatis-plus -->
@@ -341,14 +341,14 @@
     <build>
     <build>
         <pluginManagement>
         <pluginManagement>
             <plugins>
             <plugins>
-                <!-- maven-surefire-plugin æ�’件,用于è¿�行å�•元测试ã€-->
-                <!-- 注�,需�使用 3.0.X+,因为�支� Junit 5 版本 -->
+                <!-- maven-surefire-plugin �件,用于�行�元测试�-->
+                <!-- 注�,需�使�3.0.X+,因为�支� Junit 5 版本 -->
                 <plugin>
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-surefire-plugin</artifactId>
                     <artifactId>maven-surefire-plugin</artifactId>
                     <version>${maven-surefire-plugin.version}</version>
                     <version>${maven-surefire-plugin.version}</version>
                 </plugin>
                 </plugin>
-                <!-- maven-compiler-plugin �件,解决 spring-boot-configuration-processor + Lombok + MapStruct 组� -->
+                <!-- maven-compiler-plugin �件,解�spring-boot-configuration-processor + Lombok + MapStruct 组� -->
                 <!-- https://stackoverflow.com/questions/33483697/re-run-spring-boot-configuration-annotation-processor-to-update-generated-metada -->
                 <!-- https://stackoverflow.com/questions/33483697/re-run-spring-boot-configuration-annotation-processor-to-update-generated-metada -->
                 <plugin>
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <groupId>org.apache.maven.plugins</groupId>