浏览代码

Merge remote-tracking branch 'origin/xiaoman'

yzc 1 年之前
父节点
当前提交
382534fe02
共有 40 个文件被更改,包括 3187 次插入2 次删除
  1. 4 0
      hx-admin/src/main/java/com/fjhx/admin/BytesailingApplication.java
  2. 30 0
      hx-customer/src/main/java/com/fjhx/customer/contants/XiaomanContant.java
  3. 103 0
      hx-customer/src/main/java/com/fjhx/customer/controller/xiaoman/XiaomanCustomerController.java
  4. 68 0
      hx-customer/src/main/java/com/fjhx/customer/controller/xiaoman/XiaomanCustomerInfoJsonController.java
  5. 42 0
      hx-customer/src/main/java/com/fjhx/customer/entity/customer/po/Customer.java
  6. 17 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerDto.java
  7. 17 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerInfoJsonDto.java
  8. 17 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerInfoJsonSelectDto.java
  9. 17 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerSelectDto.java
  10. 34 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/po/XiaomanConfig.java
  11. 97 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/po/XiaomanCustomer.java
  12. 34 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/po/XiaomanCustomerInfoJson.java
  13. 25 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/CustomerApiVo.java
  14. 301 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/CustomerInfoVo.java
  15. 31 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/CustomerListApiVo.java
  16. 16 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaoManTokenVO.java
  17. 17 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaomanCustomerInfoJsonVo.java
  18. 17 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaomanCustomerVo.java
  19. 78 0
      hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaomanUpdateInfoVO.java
  20. 117 0
      hx-customer/src/main/java/com/fjhx/customer/handle/HandleXiaomanData.java
  21. 125 0
      hx-customer/src/main/java/com/fjhx/customer/handle/R.java
  22. 120 0
      hx-customer/src/main/java/com/fjhx/customer/handle/aaa.json
  23. 92 0
      hx-customer/src/main/java/com/fjhx/customer/handle/bbb.json
  24. 549 0
      hx-customer/src/main/java/com/fjhx/customer/handle/ccc.json
  25. 67 0
      hx-customer/src/main/java/com/fjhx/customer/initializers/XiaomanInitializers.java
  26. 15 0
      hx-customer/src/main/java/com/fjhx/customer/mapper/xiaoman/XiaomanConfigMapper.java
  27. 26 0
      hx-customer/src/main/java/com/fjhx/customer/mapper/xiaoman/XiaomanCustomerInfoJsonMapper.java
  28. 32 0
      hx-customer/src/main/java/com/fjhx/customer/mapper/xiaoman/XiaomanCustomerMapper.java
  29. 114 0
      hx-customer/src/main/java/com/fjhx/customer/service/customer/impl/XiaomanConfigServiceImpl.java
  30. 29 0
      hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanApiService.java
  31. 20 0
      hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanConfigService.java
  32. 46 0
      hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanCustomerInfoJsonService.java
  33. 58 0
      hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanCustomerService.java
  34. 337 0
      hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/impl/XiaomanApiServiceImpl.java
  35. 59 0
      hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/impl/XiaomanCustomerInfoJsonServiceImpl.java
  36. 342 0
      hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/impl/XiaomanCustomerServiceImpl.java
  37. 19 2
      hx-customer/src/main/resources/mapper/customer/CustomerMapper.xml
  38. 5 0
      hx-customer/src/main/resources/mapper/customer/XiaomanConfigMapper.xml
  39. 12 0
      hx-customer/src/main/resources/mapper/xiaoman/XiaomanCustomerInfoJsonMapper.xml
  40. 38 0
      hx-customer/src/main/resources/mapper/xiaoman/XiaomanCustomerMapper.xml

+ 4 - 0
hx-admin/src/main/java/com/fjhx/admin/BytesailingApplication.java

@@ -3,9 +3,13 @@ package com.fjhx.admin;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 @Slf4j
 @SpringBootApplication(scanBasePackages = "com.fjhx.**")
+@EnableScheduling
+@EnableAsync
 public class BytesailingApplication {
 
     public static void main(String[] args) {

+ 30 - 0
hx-customer/src/main/java/com/fjhx/customer/contants/XiaomanContant.java

@@ -0,0 +1,30 @@
+package com.fjhx.customer.contants;
+
+public class XiaomanContant {
+    /**客户全量列表**/
+    public static final String ALL_CUSTOMER_API_URL = "https://api-sandbox.xiaoman.cn/v1/company/list";
+    /**客户数据查询**/
+    public static final String CUSTOMER_DETAIL_API_URL = "https://api-sandbox.xiaoman.cn/v1/company/info";
+    /** 客户更新列表**/
+    public static final String GET_UPDATE_CUSTOMER_API_URL = "https://api-sandbox.xiaoman.cn/v1/company/updates";
+    /**客户状态,客户分组,公海分组,客户来源下拉框数据**/
+    public static final String SELECTOR_API_URL = "https://api-sandbox.xiaoman.cn/v1/company/fields/selector";
+
+    /** 客户数据更新**/
+    public static final String UPDATE_INFO_API_URL = "https://api-sandbox.xiaoman.cn/v1/company/pushCompanyAndCustomers";
+
+    /**任务状态redis key**/
+    public static final String TASK_STATUS_KEY = "all_customer:task_status_key";
+    public static final String TASK_STATUS_VALUE = "start_task";
+    /**任务进度说明redis key**/
+    public static final String TASK_STATUS_DESC_KEY = "all_customer:task_status_desc_key";
+
+    /**延迟删除key的时间(秒)-> 5个小时 (一般给跑到一半项目被强行关掉后做最后的处理用)**/
+//    public static final int DELAY_DELETE_KEY_TIME = 18000;
+    public static final int DELAY_DELETE_KEY_TIME = 300;
+
+
+    public static final int PAGE_SIZE = 500;
+    public static final String TENANT_ID = "ehsd";
+
+}

+ 103 - 0
hx-customer/src/main/java/com/fjhx/customer/controller/xiaoman/XiaomanCustomerController.java

@@ -0,0 +1,103 @@
+package com.fjhx.customer.controller.xiaoman;
+
+import com.fjhx.customer.service.xiaoman.XiaomanApiService;
+import com.ruoyi.common.core.domain.AjaxResult;
+import org.springframework.web.bind.annotation.*;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerVo;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerSelectDto;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerDto;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import com.fjhx.customer.service.xiaoman.XiaomanCustomerService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * <p>
+ * 小满客户表 前端控制器
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@RestController
+@RequestMapping("/xiaomanCustomer")
+public class XiaomanCustomerController {
+
+
+    @Autowired
+    private XiaomanCustomerService xiaomanCustomerService;
+
+    /**
+     * 小满客户表列表
+     */
+    @PostMapping("/list")
+    public List<XiaomanCustomerVo> list(@RequestBody XiaomanCustomerSelectDto dto) {
+        return xiaomanCustomerService.getList(dto);
+    }
+
+    /**
+     * 小满客户表分页
+     */
+    @PostMapping("/page")
+    public Page<XiaomanCustomerVo> page(@RequestBody XiaomanCustomerSelectDto dto) {
+        return xiaomanCustomerService.getPage(dto);
+    }
+
+    /**
+     * 小满客户表明细
+     */
+    @PostMapping("/detail")
+    public XiaomanCustomerVo detail(@RequestBody BaseSelectDto dto) {
+        return xiaomanCustomerService.detail(dto.getId());
+    }
+
+    /**
+     * 小满客户表新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody XiaomanCustomerDto xiaomanCustomerDto) {
+        xiaomanCustomerService.add(xiaomanCustomerDto);
+    }
+
+    /**
+     * 小满客户表编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody XiaomanCustomerDto xiaomanCustomerDto) {
+        xiaomanCustomerService.edit(xiaomanCustomerDto);
+    }
+
+    /**
+     * 小满客户表删除
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody BaseSelectDto dto) {
+        xiaomanCustomerService.delete(dto.getId());
+    }
+    /**
+     * 小满客户表删除
+     */
+    @PostMapping("/initAllList")
+    public AjaxResult initAllList() {
+        try {
+            xiaomanCustomerService.initAllList();
+            return AjaxResult.success();
+        }catch (Exception e){
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 小满客户表删除
+     */
+    @PostMapping("/updateList")
+    public void updateList() {
+        xiaomanCustomerService.updateList();
+    }
+
+}

+ 68 - 0
hx-customer/src/main/java/com/fjhx/customer/controller/xiaoman/XiaomanCustomerInfoJsonController.java

@@ -0,0 +1,68 @@
+package com.fjhx.customer.controller.xiaoman;
+
+import org.springframework.web.bind.annotation.*;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerInfoJsonVo;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerInfoJsonSelectDto;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerInfoJsonDto;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import com.fjhx.customer.service.xiaoman.XiaomanCustomerInfoJsonService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+/**
+ * <p>
+ * 小满客户详情表 前端控制器
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@RestController
+@RequestMapping("/xiaomanCustomerInfoJson")
+public class XiaomanCustomerInfoJsonController {
+
+    @Autowired
+    private XiaomanCustomerInfoJsonService xiaomanCustomerInfoJsonService;
+
+    /**
+     * 小满客户详情表分页
+     */
+    @PostMapping("/page")
+    public Page<XiaomanCustomerInfoJsonVo> page(@RequestBody XiaomanCustomerInfoJsonSelectDto dto) {
+        return xiaomanCustomerInfoJsonService.getPage(dto);
+    }
+
+    /**
+     * 小满客户详情表明细
+     */
+    @PostMapping("/detail")
+    public XiaomanCustomerInfoJsonVo detail(@RequestBody BaseSelectDto dto) {
+        return xiaomanCustomerInfoJsonService.detail(dto.getId());
+    }
+
+    /**
+     * 小满客户详情表新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody XiaomanCustomerInfoJsonDto xiaomanCustomerInfoJsonDto) {
+        xiaomanCustomerInfoJsonService.add(xiaomanCustomerInfoJsonDto);
+    }
+
+    /**
+     * 小满客户详情表编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody XiaomanCustomerInfoJsonDto xiaomanCustomerInfoJsonDto) {
+        xiaomanCustomerInfoJsonService.edit(xiaomanCustomerInfoJsonDto);
+    }
+
+    /**
+     * 小满客户详情表删除
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody BaseSelectDto dto) {
+        xiaomanCustomerInfoJsonService.delete(dto.getId());
+    }
+
+}

+ 42 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/customer/po/Customer.java

@@ -2,6 +2,7 @@ package com.fjhx.customer.entity.customer.po;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ruoyi.common.core.domain.BasePo;
 import lombok.Getter;
 import lombok.Setter;
@@ -144,4 +145,45 @@ public class Customer extends BasePo {
      */
     private Date lastFollowTime;
 
+    /**
+     * 小满客户表客户ID
+     */
+    private Long companyId;
+
+    /**
+     * 小满客户简称
+     */
+    private String shortName;
+
+    /**
+     * 小满公司网站
+     */
+    private String homepage;
+    /**
+     * 小满公司网站
+     */
+    private Long scaleId;
+
+    /**
+     * 小满传真
+     */
+    private String fax;
+
+    /**
+     * 小满电话区号
+     */
+    private String telAreaCode;
+    /**
+     * 小满电话
+     */
+    private String tel;
+    /**
+     * 小满备注
+     */
+    private String remark;
+    /**
+     * 小满国家
+     */
+    private String countryName;
+
 }

+ 17 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.customer.entity.xiaoman.dto;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomer;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小满客户表新增编辑入参实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class XiaomanCustomerDto extends XiaomanCustomer {
+
+}

+ 17 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerInfoJsonDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.customer.entity.xiaoman.dto;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomerInfoJson;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小满客户详情表新增编辑入参实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class XiaomanCustomerInfoJsonDto extends XiaomanCustomerInfoJson {
+
+}

+ 17 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerInfoJsonSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.customer.entity.xiaoman.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小满客户详情表列表查询入参实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class XiaomanCustomerInfoJsonSelectDto extends BaseSelectDto {
+
+}

+ 17 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/dto/XiaomanCustomerSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.customer.entity.xiaoman.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小满客户表列表查询入参实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class XiaomanCustomerSelectDto extends BaseSelectDto {
+
+}

+ 34 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/po/XiaomanConfig.java

@@ -0,0 +1,34 @@
+package com.fjhx.customer.entity.xiaoman.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Getter
+@Setter
+@TableName("xiaoman_config")
+public class XiaomanConfig extends BaseIdPo {
+
+    private String clientId;
+    private String clientSecret;
+    private String username;
+    private String password;
+    private String scope;
+    private String grantType;
+
+    private String accessToken;
+    private String refreshToken;
+    /**过期时间**/
+    private Date expireTime;
+    /**过期时间**/
+    private Date lastTokenTime;
+    /**全量更新标志**/
+    private int allUpdateFlag;
+
+    private String tokenUrl;
+    private String refreshTokenUrl;
+
+}

+ 97 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/po/XiaomanCustomer.java

@@ -0,0 +1,97 @@
+package com.fjhx.customer.entity.xiaoman.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 小满客户表
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+@TableName("xiaoman_customer")
+public class XiaomanCustomer {
+
+    /**
+     * 公司客户ID
+     */
+    @JsonProperty("company_id")
+    @TableId(value = "company_id", type = IdType.ASSIGN_ID)
+    private Long companyId;
+
+    /**
+     * 小满用户ID
+     */
+    @JsonProperty("user_id")
+    private String userId;
+
+    /**
+     * 公司名称
+     */
+
+    @JsonProperty("name")
+    private String name;
+
+    /**
+     * 公司简称
+     */
+    @JsonProperty("short_name")
+    private String shortName;
+
+    /**
+     * 客户代码
+     */
+    @JsonProperty("serial_id")
+    private String serialId;
+
+    /**
+     * 最近更新时间
+     */
+    @JsonProperty("order_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
+    private Date orderTime;
+
+    /**
+     * 公司建档时间
+     */
+    @JsonProperty("create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
+    private Date createTime;
+
+    /**
+     * 公司更新时间
+     */
+    @JsonProperty("update_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
+    private Date updateTime;
+
+    /**
+     * 存档类型
+     */
+    @JsonProperty("archive_type")
+    private String archiveType;
+
+    /**
+     * 公司修改时间
+     */
+    @JsonProperty("edit_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
+    private Date editTime;
+
+    /**
+     * 客户表客户Id
+     */
+    private Long customerId;
+
+}

+ 34 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/po/XiaomanCustomerInfoJson.java

@@ -0,0 +1,34 @@
+package com.fjhx.customer.entity.xiaoman.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 小满客户详情表
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+@TableName("xiaoman_customer_info_json")
+public class XiaomanCustomerInfoJson {
+
+    /**
+     * 公司客户ID
+     */
+    @TableId(value = "company_id", type = IdType.ASSIGN_ID)
+    private Long companyId;
+
+    /**
+     * 公司客户详情
+     */
+    private String json;
+
+}

+ 25 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/CustomerApiVo.java

@@ -0,0 +1,25 @@
+package com.fjhx.customer.entity.xiaoman.vo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomer;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 小满客户表列表查询返回值实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class CustomerApiVo extends XiaomanCustomer {
+
+    @JsonProperty("create_user")
+    private Long createUser;
+    @JsonProperty("last_edit_user")
+    private Long lastEditUser;
+}

+ 301 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/CustomerInfoVo.java

@@ -0,0 +1,301 @@
+package com.fjhx.customer.entity.xiaoman.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class CustomerInfoVo {
+
+    @JsonProperty("company_id")
+    private long companyId;
+
+    @JsonProperty("serial_id")
+    private String serialId;
+
+    @JsonProperty("user_id")
+    private List<String> userId;
+
+    @Data
+    public static class Owner {
+        @JsonProperty("user_id")
+        private String userId;
+
+        @JsonProperty("avatar")
+        private String avatar;
+
+        @JsonProperty("name")
+        private String name;
+
+        @JsonProperty("nickname")
+        private String nickname;
+    }
+
+    @JsonProperty("owner")
+    private List<Owner> owner;
+
+    @JsonProperty("create_user")
+    private long createUser;
+
+    @Data
+    public static class LastOwnerInfo {
+        @JsonProperty("nickname")
+        private String nickname;
+
+        @JsonProperty("user_id")
+        private long userId;
+
+        @JsonProperty("avatar")
+        private String avatar;
+    }
+
+    @JsonProperty("last_owner_info")
+    private LastOwnerInfo lastOwnerInfo;
+
+    @JsonProperty("pool_id")
+    private int poolId;
+
+    @JsonProperty("pool_name")
+    private String poolName;
+
+    @JsonProperty("private_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
+    private Date privateTime;
+
+    @JsonProperty("public_time")
+    private String publicTime;
+
+    @JsonProperty("release_count")
+    private int releaseCount;
+
+    @JsonProperty("edit_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
+    private Date editTime;
+
+    @JsonProperty("main_lead_id")
+    private long mainLeadId;
+
+    @JsonProperty("lead_name")
+    private String leadName;
+
+    @JsonProperty("origin")
+    private String origin;
+
+    @JsonProperty("origin_name")
+    private String originName;
+
+    @JsonProperty("tag")
+    private List<Tag> tag;
+
+    @JsonProperty("client_tag_list")
+    private List<String> clientTagList;
+
+    public static class SourceDetail {
+        @JsonProperty("alibaba_store_info")
+        private List<AlibabaStoreInfo> alibabaStoreInfo;
+
+        @JsonProperty("site_info")
+        private List<String> siteInfo;
+
+    }
+
+    @JsonProperty("source_detail")
+    private SourceDetail sourceDetail;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("short_name")
+    private String shortName;
+
+    @JsonProperty("origin_list")
+    private List<String> originList;
+
+    @JsonProperty("biz_type")
+    private String bizType;
+
+    // 嵌套的内部类
+    @Data
+    public static class AlibabaStoreInfo {
+        @JsonProperty("store_id")
+        private String storeId;
+
+        @JsonProperty("store_name")
+        private String storeName;
+
+        @JsonProperty("enable_flag")
+        private String enableFlag;
+
+        @JsonProperty("oauth_flag")
+        private String oauthFlag;
+
+        @JsonProperty("sync_customer_flag")
+        private String syncCustomerFlag;
+
+    }
+
+
+    @JsonProperty("annual_procurement")
+    private int annualProcurement;
+
+    @JsonProperty("country")
+    private String country;
+
+    @JsonProperty("intention_level")
+    private int intentionLevel;
+
+    @JsonProperty("province")
+    private String province;
+
+    @JsonProperty("timezone")
+    private String timezone;
+
+    @JsonProperty("city")
+    private String city;
+
+    @JsonProperty("scale_id")
+    private Long scaleId;
+
+    @JsonProperty("trail_status")
+    private String trailStatus;
+
+    @JsonProperty("homepage")
+    private String homepage;
+
+    @JsonProperty("fax")
+    private String fax;
+
+    @JsonProperty("tel_area_code")
+    private String telAreaCode;
+
+    @JsonProperty("tel")
+    private String tel;
+
+    @JsonProperty("address")
+    private String address;
+
+    @JsonProperty("remark")
+    private String remark;
+
+    @JsonProperty("category_ids")
+    private List<Integer> categoryIds;
+
+    @JsonProperty("create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
+    private Date createTime;
+
+    @JsonProperty("customers")
+    private List<Customer> customers;
+
+    @JsonProperty("country_name")
+    private String countryName;
+
+    @Data
+    public static class Customer {
+        @JsonProperty("customer_id")
+        private long customerId;
+
+        @JsonProperty("company_id")
+        private long companyId;
+
+        @JsonProperty("name")
+        private String name;
+
+        @JsonProperty("email")
+        private String email;
+
+        @JsonProperty("gender")
+        private int gender;
+
+        @JsonProperty("remark")
+        private String remark;
+
+        @JsonProperty("birth")
+        private String birth;
+
+        @JsonProperty("post_grade")
+        private int postGrade;
+
+        @JsonProperty("post")
+        private String post;
+
+        @JsonProperty("image_list")
+        private List<ImageInfo> imageList;
+
+        @JsonProperty("contact")
+        private List<Contact> contact;
+
+        @JsonProperty("main_customer_flag")
+        private int mainCustomerFlag;
+
+        @JsonProperty("tel_area_code")
+        private String telAreaCode;
+
+        @JsonProperty("tel")
+        private String tel;
+
+    }
+
+    @Data
+    public static class ImageInfo {
+        @JsonProperty("file_id")
+        private long fileId;
+
+        @JsonProperty("file_name")
+        private String fileName;
+
+        @JsonProperty("file_size")
+        private String fileSize;
+
+        @JsonProperty("file_path")
+        private String filePath;
+
+        @JsonProperty("file_preview_url")
+        private String filePreviewUrl;
+    }
+
+
+    @Data
+    public static class Contact {
+
+        @JsonProperty("type")
+        private String type;
+
+        @JsonProperty("value")
+        private String value;
+    }
+
+
+    @Data
+    public static class Tag {
+
+        @JsonProperty("tag_color")
+        private String tagColor;
+
+        @JsonProperty("tag_id")
+        private String tagId;
+
+        @JsonProperty("tag_name")
+        private String tagName;
+
+        @JsonProperty("user_id")
+        private String userId;
+
+        @JsonProperty("system_flag")
+        private String systemFlag;
+
+        @JsonProperty("create_time")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        private Date createTime;
+
+        @JsonProperty("user_info")
+        private List<Object> userInfo;
+
+    }
+
+
+
+}

+ 31 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/CustomerListApiVo.java

@@ -0,0 +1,31 @@
+package com.fjhx.customer.entity.xiaoman.vo;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomer;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 小满客户表列表查询返回值实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class CustomerListApiVo {
+    List<CustomerApiVo> list = new ArrayList<>();
+
+
+    /**
+     * 总条数
+     */
+    public int totalItem;
+
+    /**
+     * 条数
+     */
+    public int count;
+}

+ 16 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaoManTokenVO.java

@@ -0,0 +1,16 @@
+package com.fjhx.customer.entity.xiaoman.vo;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class XiaoManTokenVO {
+    @JSONField(name = "access_token")
+    private String accessToken;
+    @JSONField(name = "refresh_token")
+    private String refreshToken;
+    @JSONField(name = "expires_in")
+    private int expiresIn;
+}

+ 17 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaomanCustomerInfoJsonVo.java

@@ -0,0 +1,17 @@
+package com.fjhx.customer.entity.xiaoman.vo;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomerInfoJson;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小满客户详情表列表查询返回值实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class XiaomanCustomerInfoJsonVo extends XiaomanCustomerInfoJson {
+
+}

+ 17 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaomanCustomerVo.java

@@ -0,0 +1,17 @@
+package com.fjhx.customer.entity.xiaoman.vo;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomer;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 小满客户表列表查询返回值实体
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Getter
+@Setter
+public class XiaomanCustomerVo extends XiaomanCustomer {
+
+}

+ 78 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/xiaoman/vo/XiaomanUpdateInfoVO.java

@@ -0,0 +1,78 @@
+package com.fjhx.customer.entity.xiaoman.vo;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author hj
+ * @date 202404089:45
+ */
+@Data
+public class XiaomanUpdateInfoVO {
+    //公司客户ID (创建时无需设置,更新时需要设置)
+    @JSONField(name = "company_id")
+    private Long companyId;
+    //客户编号id->客户表customer_code
+    @JSONField(name = "serial_id")
+    private String serialId;
+    //客户名称
+    private String name;
+    //客户简称
+    @JSONField(name = "short_name")
+    private String shortName;
+    //网站主页
+    private String homepage;
+    //传真
+    private Long fax;
+    //客户电话区号
+    @JSONField(name = "tel_area_code")
+    private Long telAreaCode;
+    //客户电话
+    private Long tel;
+    //地址
+    private String address;
+    //备注
+    private String remark;
+    //客户联系人
+    private List<Customer> customers;
+    //客户公海分组ID,默认为0
+    @JSONField(name = "pool_id")
+    private Integer poolId;
+    //客户来源ID
+    @JSONField(name = "origin_list")
+    private List<Long> originList;
+    //客户状态ID
+    @JSONField(name = "trail_status")
+    private Long trailStatus;
+
+    @Data
+    public static class Customer {
+        //客户名称
+        private String name;
+        //客户简称
+        private String email;
+        //主要联系人设置标志
+        @JSONField(name = "main_customer_flag")
+        private String mainCustomerFlag;
+        //客户联系人职位
+        private String post;
+        //客户联系人备注
+        private String remark;
+        //客户联系人生日
+        private String birth;
+        //客户联系人电话区号
+        @JSONField(name = "tel_area_code")
+        private Long telAreaCode;
+        //客户联系人电话
+        private Long tel;
+        private String qq;
+        private String linkedin;
+        private String skype;
+        private String whatsapp;
+        private String facebook;
+        private String wechat;
+        private String twitter;
+    }
+}

+ 117 - 0
hx-customer/src/main/java/com/fjhx/customer/handle/HandleXiaomanData.java

@@ -0,0 +1,117 @@
+package com.fjhx.customer.handle;
+
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerSelectDto;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanConfig;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fjhx.customer.contants.XiaomanContant;
+import com.fjhx.customer.entity.xiaoman.vo.*;
+import com.fjhx.customer.service.xiaoman.XiaomanCustomerService;
+import com.fjhx.tenant.entity.dict.dto.DictTenantDataSelectDto;
+import com.fjhx.tenant.entity.dict.po.DictTenantData;
+import com.fjhx.tenant.entity.dict.vo.DictTenantDataVo;
+import com.fjhx.tenant.service.dict.DictTenantDataService;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.fjhx.customer.service.xiaoman.XiaomanConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class HandleXiaomanData {
+    private static XiaomanConfigService xiaomanConfigService = SpringUtils.getBean(XiaomanConfigService.class);
+    private static XiaomanCustomerService xiaomanCustomerService = SpringUtils.getBean(XiaomanCustomerService.class);
+    private static StringRedisTemplate redisTemplate = SpringUtils.getBean(StringRedisTemplate.class);
+    private static DictTenantDataService dictTenantDataService = SpringUtils.getBean(DictTenantDataService.class);
+
+    public static void main(String[] args) {
+        String filePath = "D:\\java_conding\\erhong\\hx-customer\\src\\main\\java\\com\\fjhx\\customer\\handle\\bbb.json";
+        String jsonData = "";
+
+        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
+            String line;
+            while ((line = br.readLine()) != null) {
+                jsonData += line;
+            }
+            handleDate(jsonData, new TypeReference<R<CustomerInfoVo>>() { });
+//            handleAllCustomer(jsonData);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 处理-小满用户
+     * @param res
+     * @param allCustomer
+     * @return
+     */
+    public static CustomerListApiVo handleAllCustomer(String res,Set<Long> allCustomer){
+        //反序列化对象
+        CustomerListApiVo customerListApiVo = handleDate(res, new TypeReference<R<CustomerListApiVo>>() { });
+        //判断列表是否为空
+        if (!customerListApiVo.getList().isEmpty()){
+            //保存或修改
+            xiaomanCustomerService.handleSaveOrUpdate(customerListApiVo.getList(),allCustomer);
+        }
+        return customerListApiVo;
+    }
+
+
+    /**
+     * 反序列化
+     * @param res
+     * @param typeReference
+     * @param <T>
+     * @return
+     */
+    public static <T> T handleDate(String res, TypeReference<R<T>> typeReference) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        try {
+            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            R<T> result = objectMapper.readValue(res, typeReference);
+            if (result.isOk()) {
+                return result.getData();
+            }
+            return null;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////小满api接口////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+}

+ 125 - 0
hx-customer/src/main/java/com/fjhx/customer/handle/R.java

@@ -0,0 +1,125 @@
+package com.fjhx.customer.handle;
+
+
+import java.io.Serializable;
+
+public class R<T> implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 成功 */
+    public static final int SUCCESS = 200;
+
+    /** 失败 */
+    public static final int FAIL = 500;
+
+    private int code;
+
+    private String message;
+
+    private T data;
+
+    public String now;
+
+
+    public static <T> R<T> ok()
+    {
+        return restResult(null, SUCCESS, null);
+    }
+
+    public static <T> R<T> ok(T data)
+    {
+        return restResult(data, SUCCESS, null);
+    }
+
+    public static <T> R<T> ok(T data, String message)
+    {
+        return restResult(data, SUCCESS, message);
+    }
+
+    public static <T> R<T> fail()
+    {
+        return restResult(null, FAIL, null);
+    }
+
+    public static <T> R<T> fail(String message)
+    {
+        return restResult(null, FAIL, message);
+    }
+
+    public static <T> R<T> fail(T data)
+    {
+        return restResult(data, FAIL, null);
+    }
+
+    public static <T> R<T> fail(T data, String message)
+    {
+        return restResult(data, FAIL, message);
+    }
+
+    public static <T> R<T> fail(int code, String message)
+    {
+        return restResult(null, code, message);
+    }
+
+    private static <T> R<T> restResult(T data, int code, String message)
+    {
+        R<T> apiResult = new R<>();
+        apiResult.setCode(code);
+        apiResult.setData(data);
+        apiResult.setMessage(message);
+        return apiResult;
+    }
+
+    public int getCode()
+    {
+        return code;
+    }
+
+    public void setCode(int code)
+    {
+        this.code = code;
+    }
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public void setMessage(String message)
+    {
+        this.message = message;
+    }
+
+    public T getData()
+    {
+        return data;
+    }
+
+    public void setData(T data)
+    {
+        this.data = data;
+    }
+
+    public static <T> Boolean isError(R<T> ret)
+    {
+        return !isSuccess(ret);
+    }
+
+    public static <T> Boolean isSuccess(R<T> ret)
+    {
+        return R.SUCCESS == ret.getCode();
+    }
+
+    public boolean isOk() {
+        return R.SUCCESS == code;
+    }
+
+    public String getNow() {
+        return now;
+    }
+
+    public void setNow(String now) {
+        this.now = now;
+    }
+}

+ 120 - 0
hx-customer/src/main/java/com/fjhx/customer/handle/aaa.json

@@ -0,0 +1,120 @@
+{
+  "code": 200,
+  "message": "success",
+  "now": "2024-04-06 22:37:30",
+  "data": {
+    "list": [
+      {
+        "company_id": 14203706522664,
+        "name": "lamyfay",
+        "short_name": "",
+        "serial_id": "73725",
+        "order_time": "2024-03-30 07:07:45",
+        "create_time": "2023-12-14 13:12:07",
+        "update_time": "2024-04-06 19:15:24",
+        "edit_time": "2024-04-06 19:15:24",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 14203738273951,
+        "name": "Globel traders",
+        "short_name": "",
+        "serial_id": "73927",
+        "order_time": "2024-03-21 19:00:24",
+        "create_time": "2023-12-14 13:13:07",
+        "update_time": "2024-04-06 19:15:17",
+        "edit_time": "2024-04-06 19:15:17",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 18246876705558,
+        "name": "ADIBAADCADI DREAMZZ",
+        "short_name": "",
+        "serial_id": "86650",
+        "order_time": "2024-04-06 19:14:35",
+        "create_time": "2024-03-23 14:40:59",
+        "update_time": "2024-04-06 19:14:35",
+        "edit_time": "2024-04-06 19:14:35",
+        "user_id": "{56322072}"
+      },
+      {
+        "company_id": 14199321404156,
+        "name": "KAME",
+        "short_name": "",
+        "serial_id": "48731",
+        "order_time": "2024-04-06 19:12:56",
+        "create_time": "2023-12-14 11:05:21",
+        "update_time": "2024-04-06 19:12:56",
+        "edit_time": "2024-04-06 19:12:56",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 14204005293537,
+        "name": "3Paleo5 LLC",
+        "short_name": "",
+        "serial_id": "75824",
+        "order_time": "2024-03-21 19:07:55",
+        "create_time": "2023-12-14 13:22:55",
+        "update_time": "2024-04-06 19:12:37",
+        "edit_time": "2024-04-06 19:12:37",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 14123845623072,
+        "name": "AJS Supplies",
+        "short_name": "",
+        "serial_id": "8871",
+        "order_time": "2024-03-21 18:22:25",
+        "create_time": "2023-12-12 16:06:43",
+        "update_time": "2024-04-06 19:10:59",
+        "edit_time": "2024-04-06 19:10:59",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 14122778058183,
+        "name": "hammers",
+        "short_name": "",
+        "serial_id": "4786",
+        "order_time": "2024-04-06 19:09:20",
+        "create_time": "2023-12-12 15:43:23",
+        "update_time": "2024-04-06 19:09:20",
+        "edit_time": "2024-04-06 19:09:20",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 14162263762410,
+        "name": "Nismo kod kuce",
+        "short_name": "",
+        "serial_id": "24437",
+        "order_time": "2024-03-22 18:27:02",
+        "create_time": "2023-12-13 14:34:36",
+        "update_time": "2024-04-06 19:08:25",
+        "edit_time": "2024-04-06 19:08:25",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 14197417631231,
+        "name": "Inspiral Balllet",
+        "short_name": "",
+        "serial_id": "37487",
+        "order_time": "2024-03-22 18:19:57",
+        "create_time": "2023-12-14 10:28:35",
+        "update_time": "2024-04-06 19:04:29",
+        "edit_time": "2024-04-06 19:04:29",
+        "user_id": "{}"
+      },
+      {
+        "company_id": 14127323759259,
+        "name": "No Company Name_10042229155",
+        "short_name": "",
+        "serial_id": "22124",
+        "order_time": "2024-03-21 18:21:59",
+        "create_time": "2023-12-12 17:21:18",
+        "update_time": "2024-04-06 19:03:59",
+        "edit_time": "2024-04-06 19:03:59",
+        "user_id": "{}"
+      }
+    ],
+    "totalItem": 108
+  }
+}

+ 92 - 0
hx-customer/src/main/java/com/fjhx/customer/handle/bbb.json

@@ -0,0 +1,92 @@
+{
+  "code": 200,
+  "message": "success",
+  "now": "2024-04-06 20:17:16",
+  "data": {
+    "company_id": 18846628768390,
+    "serial_id": "86795",
+    "user_id": [
+      "56322068"
+    ],
+    "owner": [
+      {
+        "user_id": "56322068",
+        "avatar": "https://v4client.oss-cn-hangzhou.aliyuncs.com/other/img/56322068/1a2df65fa32a4ee0a6b637c0ca6b3f4b29582e092cbd79b9a49536ccb82fa3fe.png",
+        "name": "Cici",
+        "nickname": "Cici"
+      }
+    ],
+    "create_user": 56322068,
+    "last_owner_info": {
+      "nickname": "无",
+      "user_id": 0,
+      "avatar": ""
+    },
+    "pool_id": 0,
+    "pool_name": "",
+    "private_time": "2024-04-05 17:39:57",
+    "public_time": "",
+    "release_count": 0,
+    "edit_time": "2024-04-06 18:23:46",
+    "main_lead_id": 0,
+    "lead_name": "",
+    "origin": "TM咨询",
+    "origin_name": "TM咨询",
+    "tag": [],
+    "client_tag_list": [],
+    "source_detail": {
+      "alibaba_store_info": [
+        {
+          "store_id": "215261497",
+          "store_name": "福州尔泓商贸有限公司",
+          "enable_flag": "1",
+          "oauth_flag": "1",
+          "sync_customer_flag": "1"
+        }
+      ],
+      "site_info": []
+    },
+    "name": "CLP Trading GmbH",
+    "short_name": "",
+    "origin_list": [
+      "TM咨询"
+    ],
+    "biz_type": "",
+    "annual_procurement": 0,
+    "country": "DE",
+    "intention_level": 0,
+    "province": "",
+    "timezone": "1",
+    "city": "",
+    "scale_id": 0,
+    "trail_status": "无",
+    "homepage": "",
+    "fax": "",
+    "tel_area_code": "",
+    "tel": "",
+    "address": "",
+    "remark": "",
+    "category_ids": [],
+    "create_time": "2024-04-05 17:39:57",
+    "customers": [
+      {
+        "customer_id": 18846628830511,
+        "company_id": 18846628768390,
+        "name": "Camon Ye",
+        "email": "",
+        "gender": 0,
+        "remark": "",
+        "birth": "",
+        "post_grade": 1,
+        "post": "",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 1,
+        "tel_area_code": "",
+        "tel": ""
+      }
+    ],
+    "14200691088213": "",
+    "country_name": "德国"
+  }
+}

+ 549 - 0
hx-customer/src/main/java/com/fjhx/customer/handle/ccc.json

@@ -0,0 +1,549 @@
+{
+  "code": 200,
+  "message": "success",
+  "now": "2024-04-06 23:01:02",
+  "data": {
+    "company_id": 17802838208969,
+    "serial_id": "86480",
+    "user_id": [
+      "56322068"
+    ],
+    "owner": [
+      {
+        "user_id": "56322068",
+        "avatar": "https:\\/\\/v4client.oss-cn-hangzhou.aliyuncs.com\\/other\\/img\\/56322068\\/1a2df65fa32a4ee0a6b637c0ca6b3f4b29582e092cbd79b9a49536ccb82fa3fe.png",
+        "name": "Cici",
+        "nickname": "Cici"
+      }
+    ],
+    "create_user": 56322068,
+    "last_owner_info": {
+      "nickname": "无",
+      "user_id": 0,
+      "avatar": ""
+    },
+    "pool_id": 0,
+    "pool_name": "",
+    "private_time": "2024-03-14 10:47:26",
+    "public_time": "",
+    "release_count": 0,
+    "edit_time": "2024-03-14 10:47:26",
+    "main_lead_id": 0,
+    "lead_name": "",
+    "origin": "OKKI Leads",
+    "origin_name": "OKKI Leads",
+    "tag": [],
+    "client_tag_list": [],
+    "source_detail": {
+      "alibaba_store_info": [],
+      "site_info": []
+    },
+    "name": "Swan Brand",
+    "short_name": "",
+    "origin_list": [
+      "OKKI Leads"
+    ],
+    "biz_type": "",
+    "annual_procurement": 0,
+    "country": "GB",
+    "intention_level": 0,
+    "province": "",
+    "timezone": "0",
+    "city": "",
+    "scale_id": 0,
+    "trail_status": "无",
+    "homepage": "http:\\/\\/www.swan-brand.co.uk",
+    "fax": "",
+    "tel_area_code": "44",
+    "tel": "161-934-2240",
+    "address": "P.O. Box 3117,Stoke-on-Trent,Stoke-on-Trent,ST4 9GD,United Kingdom of Great Britain and Northern Ireland",
+    "remark": "",
+    "category_ids": [],
+    "create_time": "2024-03-14 10:47:26",
+    "customers": [
+      {
+        "customer_id": 17802837442234,
+        "company_id": 17802838208969,
+        "name": "Veronica Davidson",
+        "email": "veronica@swan-brand.co.uk",
+        "gender": 0,
+        "remark": "",
+        "birth": "",
+        "post_grade": 0,
+        "post": "Lingerie\\/jewellery Buyer Manager",
+        "image_list": [],
+        "contact": [
+          {
+            "type": "facebook",
+            "value": "https:\\/\\/www.facebook.com\\/teasmade"
+          },
+          {
+            "type": "twitter",
+            "value": "https:\\/\\/twitter.com\\/swanteasmade"
+          },
+          {
+            "type": "instagram",
+            "value": "https:\\/\\/instagram.com\\/swanbranduk"
+          },
+          {
+            "type": "youtube",
+            "value": "https:\\/\\/youtube.com\\/user\\/SwanTeasmade"
+          }
+        ],
+        "main_customer_flag": 1,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838209030,
+        "company_id": 17802838208969,
+        "name": "Paul Simpson",
+        "email": "paul@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "National Account Manager",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838209110,
+        "company_id": 17802838208969,
+        "name": "Katie Lindop",
+        "email": "katie@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "Sales Coordinator",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838209172,
+        "company_id": 17802838208969,
+        "name": "Meda Delf",
+        "email": "meda@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "Social Media Placement",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838209269,
+        "company_id": 17802838208969,
+        "name": "David Foulstone",
+        "email": "david@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "Marketing Manager",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838209351,
+        "company_id": 17802838208969,
+        "name": "Tony Druce",
+        "email": "tony@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "Business Development Manager",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838209440,
+        "company_id": 17802838208969,
+        "name": "Emma Cork",
+        "email": "emma@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "Administrator",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838209494,
+        "company_id": 17802838208969,
+        "name": "Michael Tan",
+        "email": "michael.tan@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "Head Of Procurement",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565475,
+        "company_id": 17802838208969,
+        "name": "David Foulstone",
+        "email": "david.foulstone@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565599,
+        "company_id": 17802838208969,
+        "name": "Emily Turner",
+        "email": "emily@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565651,
+        "company_id": 17802838208969,
+        "name": "Cj Williams",
+        "email": "cj@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565747,
+        "company_id": 17802838208969,
+        "name": "Harriet Neal",
+        "email": "sales@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565812,
+        "company_id": 17802838208969,
+        "name": "Claire Massey",
+        "email": "claire@sourcingpartner.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565866,
+        "company_id": 17802838208969,
+        "name": "James Ecclestone",
+        "email": "james.ecclestone@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565917,
+        "company_id": 17802838208969,
+        "name": "Jade Loftus",
+        "email": "jade.loftus@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838565969,
+        "company_id": 17802838208969,
+        "name": "Harry Thomson",
+        "email": "harry@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838566008,
+        "company_id": 17802838208969,
+        "name": "loyalty",
+        "email": "loyalty@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838611014,
+        "company_id": 17802838208969,
+        "name": "affiliate",
+        "email": "affiliate@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838642036,
+        "company_id": 17802838208969,
+        "name": "katie.lindop",
+        "email": "katie.lindop@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988029,
+        "company_id": 17802838208969,
+        "name": "kayleigh.baddeley",
+        "email": "kayleigh.baddeley@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988095,
+        "company_id": 17802838208969,
+        "name": "paypal",
+        "email": "paypal@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988141,
+        "company_id": 17802838208969,
+        "name": "ebay",
+        "email": "ebay@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988187,
+        "company_id": 17802838208969,
+        "name": "vincent",
+        "email": "vincent@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988302,
+        "company_id": 17802838208969,
+        "name": "kayleigh",
+        "email": "kayleigh@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988349,
+        "company_id": 17802838208969,
+        "name": "fearne",
+        "email": "fearne@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988393,
+        "company_id": 17802838208969,
+        "name": "holly.cartlidge",
+        "email": "holly.cartlidge@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988434,
+        "company_id": 17802838208969,
+        "name": "emily.brown",
+        "email": "emily.brown@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988488,
+        "company_id": 17802838208969,
+        "name": "customerservice",
+        "email": "customerservice@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      },
+      {
+        "customer_id": 17802838988520,
+        "company_id": 17802838208969,
+        "name": "info",
+        "email": "info@swan-brand.co.uk",
+        "gender": 0,
+        "remark": null,
+        "birth": "",
+        "post_grade": 0,
+        "post": "--",
+        "image_list": [],
+        "contact": [],
+        "main_customer_flag": 0,
+        "tel_area_code": "",
+        "tel": ""
+      }
+    ],
+    "14200691088213": "",
+    "country_name": "英国"
+  }
+}

+ 67 - 0
hx-customer/src/main/java/com/fjhx/customer/initializers/XiaomanInitializers.java

@@ -0,0 +1,67 @@
+package com.fjhx.customer.initializers;
+
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanConfig;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanUpdateInfoVO;
+import com.fjhx.customer.handle.HandleXiaomanData;
+import com.fjhx.customer.service.xiaoman.XiaomanApiService;
+import com.fjhx.customer.service.xiaoman.XiaomanConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+@Component
+@Slf4j
+public class XiaomanInitializers {
+
+    @Resource
+    private XiaomanConfigService xiaomanConfigService;
+    @Resource
+    private XiaomanApiService xiaomanApiService;
+
+    @PostConstruct
+    public void dataInitializer() {
+        // 初始化数据的代码
+        log.info("XiaomanInitializers dataInitializer");
+        //刷新token
+        refreshToken();
+        //获取全量数据
+        try {
+            xiaomanApiService.initAllList();
+        } catch (Exception e) {
+            log.error("获取小满全量数据异常", e);
+        }
+    }
+
+
+    @Scheduled(cron = "0 0/30 * * * ? ")
+    void refreshToken(){
+        //如果过期时间是空的,就获取新的token
+        XiaomanConfig config = xiaomanConfigService.getConfig();
+
+        Date expireTime = config.getExpireTime();
+        if(ObjectUtil.isNull(expireTime) || StrUtil.isBlank(config.getRefreshToken())) {
+            xiaomanConfigService.getToken(config);
+        } else {
+            //如果过期时间减去当前时间小于110分钟,则要刷新token
+            long between = DateUtil.between(DateUtil.date(), expireTime, DateUnit.MINUTE, false);
+            if(between <= 70){
+                xiaomanConfigService.refreshToken(config);
+            }
+        }
+    }
+
+
+
+
+}

+ 15 - 0
hx-customer/src/main/java/com/fjhx/customer/mapper/xiaoman/XiaomanConfigMapper.java

@@ -0,0 +1,15 @@
+package com.fjhx.customer.mapper.xiaoman;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanConfig;
+
+
+/**
+ * <p>
+ * 小满配置表 Mapper 接口
+ * </p>
+ *
+ */
+public interface XiaomanConfigMapper extends BaseMapper<XiaomanConfig> {
+
+}

+ 26 - 0
hx-customer/src/main/java/com/fjhx/customer/mapper/xiaoman/XiaomanCustomerInfoJsonMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.customer.mapper.xiaoman;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomerInfoJson;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerInfoJsonVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 小满客户详情表 Mapper 接口
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+public interface XiaomanCustomerInfoJsonMapper extends BaseMapper<XiaomanCustomerInfoJson> {
+
+    /**
+     * 小满客户详情表分页
+     */
+    Page<XiaomanCustomerInfoJsonVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<XiaomanCustomerInfoJson> wrapper);
+
+}

+ 32 - 0
hx-customer/src/main/java/com/fjhx/customer/mapper/xiaoman/XiaomanCustomerMapper.java

@@ -0,0 +1,32 @@
+package com.fjhx.customer.mapper.xiaoman;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomer;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 小满客户表 Mapper 接口
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+public interface XiaomanCustomerMapper extends BaseMapper<XiaomanCustomer> {
+
+    /**
+     * 小满客户表列表
+     */
+    List<XiaomanCustomerVo> getList(@Param("ew") IWrapper<XiaomanCustomer> wrapper);
+
+    /**
+     * 小满客户表分页
+     */
+    Page<XiaomanCustomerVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<XiaomanCustomer> wrapper);
+
+}

+ 114 - 0
hx-customer/src/main/java/com/fjhx/customer/service/customer/impl/XiaomanConfigServiceImpl.java

@@ -0,0 +1,114 @@
+package com.fjhx.customer.service.customer.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.Header;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanConfig;
+import com.fjhx.customer.entity.xiaoman.vo.XiaoManTokenVO;
+import com.fjhx.customer.mapper.xiaoman.XiaomanConfigMapper;
+import com.fjhx.customer.service.xiaoman.XiaomanConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 小满配置表 服务实现类
+ * </p>
+ *
+ */
+@Service
+@Slf4j
+public class XiaomanConfigServiceImpl extends ServiceImpl<XiaomanConfigMapper, XiaomanConfig> implements XiaomanConfigService {
+
+    @Override
+    public void getToken(XiaomanConfig config) {
+        getXiaomanToken(config);
+    }
+
+    @Override
+    public void refreshToken(XiaomanConfig config) {
+        refreshXiaomanToken(config);
+    }
+
+    /**
+     * 刷新小满token
+     *
+     * @param config
+     */
+    private void refreshXiaomanToken(XiaomanConfig config) {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("client_id", config.getClientId());
+        jsonObject.put("client_secret", config.getClientSecret());
+        jsonObject.put("grant_type", "refresh_token");
+        jsonObject.put("refresh_token", config.getRefreshToken());
+        XiaoManTokenVO token = getToken(config, jsonObject.toJSONString(), config.getRefreshTokenUrl());
+        updateConfig(config, token);
+    }
+
+    /**
+     * 获取小满token
+     *
+     * @param config
+     */
+    private void getXiaomanToken(XiaomanConfig config) {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("client_id", config.getClientId());
+        jsonObject.put("client_secret", config.getClientSecret());
+        jsonObject.put("grant_type", "password");
+        jsonObject.put("scope", config.getScope());
+        jsonObject.put("username", config.getUsername());
+        jsonObject.put("password", config.getPassword());
+        String body = jsonObject.toJSONString();
+        XiaoManTokenVO token = getToken(config, body, config.getTokenUrl());
+        updateConfig(config, token);
+    }
+
+    private void updateConfig(XiaomanConfig config, XiaoManTokenVO token) {
+        config.setAccessToken(token.getAccessToken());
+        config.setRefreshToken(token.getRefreshToken());
+        config.setExpireTime(DateUtil.offsetSecond(DateUtil.date(), token.getExpiresIn()));
+        config.setLastTokenTime(DateUtil.date());
+        this.updateById(config);
+    }
+
+    public static XiaoManTokenVO getToken(XiaomanConfig config, String body, String url){
+        String s = HttpUtil.buildBasicAuth(config.getUsername(), config.getPassword(), Charset.forName("UTF-8"));
+        Map<String, String> headers = new HashMap<>();
+        headers.put(Header.AUTHORIZATION.getValue(), s);
+        log.info("请求地址{},请求参数:{}", url, body);
+        String respond = HttpUtil.createPost(url).timeout(5000).body(body).charset(Charset.forName("UTF-8")).addHeaders(headers).execute().body();
+        log.info("请求返回结果:{}", respond);
+
+        XiaoManTokenVO xiaoManTokenVO;
+        try {
+            xiaoManTokenVO = JSON.parseObject(respond, XiaoManTokenVO.class);
+        } catch (Exception e) {
+            log.error("请求小满token失败,返回结果:{}", respond);
+            throw new RuntimeException("请求小满token失败");
+        }
+        return xiaoManTokenVO;
+    }
+
+
+    @Override
+    public XiaomanConfig getConfig() {
+        List<XiaomanConfig> list = this.list();
+        if (CollectionUtil.isEmpty(list)) {
+            throw new RuntimeException("小满配置表数据为空");
+        } else if (list.size() > 1) {
+            throw new RuntimeException("小满配置表数据大于1条");
+        }
+        return list.get(0);
+    }
+}

+ 29 - 0
hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanApiService.java

@@ -0,0 +1,29 @@
+package com.fjhx.customer.service.xiaoman;
+
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanUpdateInfoVO;
+
+public interface XiaomanApiService {
+
+    /**
+     * 初始化所有客户列表
+     * @author hj
+     * @date 2024/4/8 22:20
+     */
+    void initAllList();
+
+
+    boolean setNxWithExpiration(String key, String value, long expireTime);
+
+    String getCustomerDetail(Long companyId);
+
+
+    void updateList();
+
+    @DSTransactional
+    void getSelectorData();
+
+    void updateXiaomanData(XiaomanUpdateInfoVO xiaomanUpdateInfoVO);
+
+    void dealCustomerTagDict(String label,String key);
+}

+ 20 - 0
hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanConfigService.java

@@ -0,0 +1,20 @@
+package com.fjhx.customer.service.xiaoman;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanConfig;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 小满配置表 服务类
+ * </p>
+ *
+ */
+public interface XiaomanConfigService extends BaseService<XiaomanConfig> {
+
+    void getToken(XiaomanConfig config);
+
+    void refreshToken(XiaomanConfig config);
+
+    XiaomanConfig getConfig();
+}

+ 46 - 0
hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanCustomerInfoJsonService.java

@@ -0,0 +1,46 @@
+package com.fjhx.customer.service.xiaoman;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomerInfoJson;
+import com.ruoyi.common.core.service.BaseService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerInfoJsonVo;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerInfoJsonSelectDto;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerInfoJsonDto;
+
+
+/**
+ * <p>
+ * 小满客户详情表 服务类
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+public interface XiaomanCustomerInfoJsonService  {
+
+    /**
+     * 小满客户详情表分页
+     */
+    Page<XiaomanCustomerInfoJsonVo> getPage(XiaomanCustomerInfoJsonSelectDto dto);
+
+    /**
+     * 小满客户详情表明细
+     */
+    XiaomanCustomerInfoJsonVo detail(Long id);
+
+    /**
+     * 小满客户详情表新增
+     */
+    void add(XiaomanCustomerInfoJsonDto xiaomanCustomerInfoJsonDto);
+
+    /**
+     * 小满客户详情表编辑
+     */
+    void edit(XiaomanCustomerInfoJsonDto xiaomanCustomerInfoJsonDto);
+
+    /**
+     * 小满客户详情表删除
+     */
+    void delete(Long id);
+
+}

+ 58 - 0
hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/XiaomanCustomerService.java

@@ -0,0 +1,58 @@
+package com.fjhx.customer.service.xiaoman;
+
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomer;
+import com.fjhx.customer.entity.xiaoman.vo.CustomerApiVo;
+import com.ruoyi.common.core.service.BaseService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerVo;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerSelectDto;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerDto;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * <p>
+ * 小满客户表 服务类
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+public interface XiaomanCustomerService  {
+
+    /**
+     * 小满客户表列表
+     */
+    List<XiaomanCustomerVo> getList(XiaomanCustomerSelectDto dto);
+
+    /**
+     * 小满客户表分页
+     */
+    Page<XiaomanCustomerVo> getPage(XiaomanCustomerSelectDto dto);
+
+    /**
+     * 小满客户表明细
+     */
+    XiaomanCustomerVo detail(Long id);
+
+    /**
+     * 小满客户表新增
+     */
+    void add(XiaomanCustomerDto xiaomanCustomerDto);
+
+    /**
+     * 小满客户表编辑
+     */
+    void edit(XiaomanCustomerDto xiaomanCustomerDto);
+
+    /**
+     * 小满客户表删除
+     */
+    void delete(Long id);
+
+    void handleSaveOrUpdate(List<CustomerApiVo> customerApiVoList, Set<Long> allCustomer);
+
+    void initAllList();
+    void updateList();
+}

+ 337 - 0
hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/impl/XiaomanApiServiceImpl.java

@@ -0,0 +1,337 @@
+package com.fjhx.customer.service.xiaoman.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.customer.contants.XiaomanContant;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerSelectDto;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanConfig;
+import com.fjhx.customer.entity.xiaoman.vo.CustomerListApiVo;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerVo;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanUpdateInfoVO;
+import com.fjhx.customer.handle.HandleXiaomanData;
+import com.fjhx.customer.service.xiaoman.XiaomanApiService;
+import com.fjhx.customer.service.xiaoman.XiaomanConfigService;
+import com.fjhx.customer.service.xiaoman.XiaomanCustomerService;
+import com.fjhx.tenant.entity.dict.dto.DictTenantDataSelectDto;
+import com.fjhx.tenant.entity.dict.po.DictTenantData;
+import com.fjhx.tenant.entity.dict.vo.DictTenantDataVo;
+import com.fjhx.tenant.service.dict.DictTenantDataService;
+import com.ruoyi.common.utils.SecurityUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+public class XiaomanApiServiceImpl implements XiaomanApiService {
+    @Resource
+    XiaomanConfigService xiaomanConfigService;
+    @Resource
+    StringRedisTemplate stringRedisTemplate;
+    @Resource
+    XiaomanCustomerService xiaomanCustomerService;
+    @Resource
+    DictTenantDataService dictTenantDataService;
+
+//    @DSTransactional
+    @Override
+    @Async
+    public void initAllList() {
+        boolean result = setNxWithExpiration(XiaomanContant.TASK_STATUS_KEY, XiaomanContant.TASK_STATUS_VALUE, XiaomanContant.DELAY_DELETE_KEY_TIME);
+        if (!result) {
+            String mes = stringRedisTemplate.opsForValue().get(XiaomanContant.TASK_STATUS_DESC_KEY);
+            throw new RuntimeException(StrUtil.isBlank(mes)? "全量更新正在进行中" : mes);
+        }
+        stringRedisTemplate.opsForValue().set(XiaomanContant.TASK_STATUS_DESC_KEY, "全量更新正在进行中");
+        try {
+            getSelectorData();
+
+            XiaomanConfig config = xiaomanConfigService.getConfig();
+            String token = config.getAccessToken();
+            List<XiaomanCustomerVo> list = xiaomanCustomerService.getList(new XiaomanCustomerSelectDto());
+            Set<Long> collect = list.stream().map(XiaomanCustomerVo::getCompanyId).collect(Collectors.toSet());
+            int pageIndex = 1;
+            int totalPage;
+            do {
+                String str = getData(XiaomanContant.ALL_CUSTOMER_API_URL, token, initPageParams(pageIndex));
+                CustomerListApiVo customerListApiVo = HandleXiaomanData.handleAllCustomer(str, collect);
+                int totalItem = customerListApiVo.getTotalItem();
+                totalPage = (totalItem / XiaomanContant.PAGE_SIZE) + (totalItem % XiaomanContant.PAGE_SIZE > 0 ? 1 : 0);
+                pageIndex++;
+            } while (pageIndex <= totalPage);
+        } catch (Exception e) {
+            e.printStackTrace();
+            stringRedisTemplate.delete(XiaomanContant.TASK_STATUS_KEY);
+            stringRedisTemplate.opsForValue().set(XiaomanContant.TASK_STATUS_DESC_KEY, "全量更新出现异常,已停止");
+            return;
+        }
+        stringRedisTemplate.delete(XiaomanContant.TASK_STATUS_KEY);
+        stringRedisTemplate.opsForValue().set(XiaomanContant.TASK_STATUS_DESC_KEY, "全量更新完成,完成时间:" + DateUtil.now());
+    }
+
+    /**
+     * 设置key-value并设置过期时间
+     * @author hj
+     * @date 2024/4/6 21:14
+     * @param key
+     * @param value
+     * @param seconds
+     * @return boolean
+     */
+    @Override
+    public boolean setNxWithExpiration(String key, String value, long seconds) {
+        Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(key, value);
+        if (result != null && result) {
+            // 设置过期时间
+            stringRedisTemplate.expire(key, seconds, TimeUnit.SECONDS);
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * 获取客户详情
+     * @author hj
+     * @date 2024/4/6 21:38
+     * @param companyId
+     */
+    @Override
+    public String getCustomerDetail(Long companyId){
+        XiaomanConfig config = xiaomanConfigService.getConfig();
+        String token = config.getAccessToken();
+        Map<String, Object> params = new HashMap<>();
+        params.put("company_id", companyId);
+        params.put("format", "1");
+        return getData(XiaomanContant.CUSTOMER_DETAIL_API_URL, token, params);
+    }
+
+
+    /**
+     * 客户更新列表
+     * @author hj
+     * @date 2024/4/6 21:54
+     */
+    @Override
+    @Async
+    public void updateList(){
+        try {
+            //先更新一下数据字典
+            getSelectorData();
+
+            XiaomanConfig config = xiaomanConfigService.getConfig();
+            String token = config.getAccessToken();
+            List<XiaomanCustomerVo> list = xiaomanCustomerService.getList(new XiaomanCustomerSelectDto());
+            Set<Long> collect = list.stream().map(XiaomanCustomerVo::getCompanyId).collect(Collectors.toSet());
+            int pageIndex = 1;
+            int totalPage;
+            do {
+                Map<String, Object> params = initPageParams(pageIndex);
+                String nowStr = DateUtil.offsetHour(DateUtil.date(), 1).toString("yyyy-MM-dd HH:00:00");
+                params.put("start_time", DateUtil.parse(nowStr).offset(DateField.HOUR, -8).toString("yyyy-MM-dd HH:00:00"));
+                params.put("end_time", nowStr);
+                String str = getData(XiaomanContant.GET_UPDATE_CUSTOMER_API_URL, token, params);
+                CustomerListApiVo customerListApiVo = HandleXiaomanData.handleAllCustomer(str, collect);
+                int totalItem = customerListApiVo.getTotalItem();
+                totalPage = (totalItem / XiaomanContant.PAGE_SIZE) + (totalItem % XiaomanContant.PAGE_SIZE > 0 ? 1 : 0);
+                pageIndex++;
+            } while (pageIndex <= totalPage);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    private static final Map<String, String> SELECTOR_KEY = new HashMap(){{
+        put("trail_status", "customer_status");
+        put("origin", "customer_source");
+    }};
+
+
+    /**
+     * 获取下拉框字典数据
+     * @author hj
+     * @date 2024/4/7 10:51
+     */
+    @DSTransactional
+    @Override
+    public void getSelectorData() {
+        XiaomanConfig config = xiaomanConfigService.getConfig();
+        String token = config.getAccessToken();
+        Map<String, Object> params = new HashMap<>();
+        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+        SecurityUtils.setTenantId(XiaomanContant.TENANT_ID);
+        SELECTOR_KEY.forEach((k, v) -> {
+            params.put("field", k);
+            String str = getData(XiaomanContant.SELECTOR_API_URL, token, params);
+            JSONObject jsonObject = JSONObject.parseObject(str);
+            DictTenantDataSelectDto dictTenantDataSelectDto = new DictTenantDataSelectDto();
+            dictTenantDataSelectDto.setDictCode(v);
+            List<DictTenantDataVo> dictTenantDataServiceList = dictTenantDataService.getList(dictTenantDataSelectDto);
+            Map<String, DictTenantData> collect = dictTenantDataServiceList.stream().collect(Collectors.toMap(DictTenantDataVo::getDictValue, o-> BeanUtil.copyProperties(o, DictTenantData.class)));
+            JSONArray data = jsonObject.getJSONArray("data");
+            if("trail_status".equals(k)){
+                dealCustomerStatusDict(data, collect);
+            } else if("origin".equals(k)){
+                dealCustomerSourceDict(data, collect);
+            }
+            log.info("获取小满下拉框字典数据:{}", jsonObject);
+        });
+        SecurityUtils.clearTenantId();
+        DynamicDataSourceContextHolder.poll();
+    }
+
+
+
+
+
+
+
+    private static Map<String, Object> initPageParams(int page) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("start_index", page);
+        params.put("count", XiaomanContant.PAGE_SIZE);
+        return params;
+    }
+
+
+    private static String getData(String url, String token, Map<String, Object> params) {
+        String res = HttpUtil.createGet(url).header("Authorization", "Bearer " + token).form(params).execute().body();
+        JSONObject jsonObject = JSONObject.parseObject(res);
+        String error = jsonObject.getString("error");
+        if (StrUtil.isNotBlank(error)) {
+            throw new RuntimeException("获取小满数据异常:" + error);
+        }
+        return res;
+    }
+
+
+    @Override
+    public void updateXiaomanData(XiaomanUpdateInfoVO xiaomanUpdateInfoVO){
+        if (ObjectUtil.isNull(xiaomanUpdateInfoVO)){
+            throw new RuntimeException("数据为空");
+        }
+        if (StrUtil.isBlank(xiaomanUpdateInfoVO.getName())){
+            throw new RuntimeException("客户名称为空");
+        }
+        xiaomanUpdateInfoVO.setPoolId(0);
+        List<XiaomanUpdateInfoVO.Customer> customers = xiaomanUpdateInfoVO.getCustomers();
+        if (CollectionUtil.isEmpty(customers)){
+            throw new RuntimeException("客户联系人为空");
+        }
+        for (XiaomanUpdateInfoVO.Customer customer : customers) {
+            if (StrUtil.isBlank(customer.getName())){
+                throw new RuntimeException("客户联系人名称存在为空");
+            }
+            if (StrUtil.isBlank(customer.getEmail())){
+                throw new RuntimeException("客户联系人email存在为空");
+            }
+            customer.setMainCustomerFlag("0");
+        }
+        xiaomanUpdateInfoVO.setCustomers(customers);
+
+
+        String body = JSON.toJSONString(xiaomanUpdateInfoVO);
+        XiaomanConfig config = xiaomanConfigService.getConfig();
+        String token = config.getAccessToken();
+        updateInfoData(token, body);
+    }
+
+
+
+
+
+    public static void updateInfoData(String token, String body){
+        String res = HttpUtil.createPost(XiaomanContant.UPDATE_INFO_API_URL).header("Authorization", "Bearer " + token).body(body).execute().body();
+        JSONObject jsonObject = JSONObject.parseObject(res);
+        String error = jsonObject.getString("error");
+        if (StrUtil.isNotBlank(error)) {
+            throw new RuntimeException("获取小满数据异常:" + error);
+        }
+    }
+
+
+
+
+    private void dealCustomerSourceDict(JSONArray data, Map<String, DictTenantData> collect) {
+        List<DictTenantData> list = new ArrayList<>();
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject jsonObject = data.getJSONObject(i);
+            String label = jsonObject.getString("origin_name");
+            String key = jsonObject.getString("origin_id");
+            boolean result = collect.containsKey(label);
+            if(!result){
+                DictTenantData dictTenantData = new DictTenantData();
+                dictTenantData.setDictCode("customer_source");
+                dictTenantData.setDictValue(label);
+                dictTenantData.setDictKey(key);
+                dictTenantData.setTenantId(XiaomanContant.TENANT_ID);
+                dictTenantData.setSort(100);
+                list.add(dictTenantData);
+            }else {
+                DictTenantData dictTenantData = collect.get(label);
+                dictTenantData.setDictKey(key);
+                dictTenantDataService.updateById(dictTenantData);
+            }
+        }
+        if (!list.isEmpty()){
+            dictTenantDataService.saveBatch(list);
+        }
+    }
+
+    private void dealCustomerStatusDict(JSONArray data, Map<String, DictTenantData> collect) {
+        List<DictTenantData> list = new ArrayList<>();
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject jsonObject = data.getJSONObject(i);
+            String label = jsonObject.getString("status_name");
+            String key = jsonObject.getString("status_id");
+            boolean result = collect.containsKey(label);
+            if(!result){
+                DictTenantData dictTenantData = new DictTenantData();
+                dictTenantData.setDictCode("customer_status");
+                dictTenantData.setDictValue(label);
+                dictTenantData.setDictKey(key);
+                dictTenantData.setTenantId(XiaomanContant.TENANT_ID);
+                dictTenantData.setSort(100);
+                list.add(dictTenantData);
+            }else {
+                DictTenantData dictTenantData = collect.get(label);
+                dictTenantData.setDictKey(key);
+                dictTenantDataService.updateById(dictTenantData);
+            }
+        }
+        if (!list.isEmpty()){
+            dictTenantDataService.saveBatch(list);
+        }
+    }
+
+    @Override
+    public void dealCustomerTagDict(String label,String key) {
+
+        DictTenantData dictTenantData = new DictTenantData();
+        dictTenantData.setDictCode("customer_tag");
+        dictTenantData.setDictValue(label);
+        dictTenantData.setDictKey(key);
+        dictTenantData.setTenantId(XiaomanContant.TENANT_ID);
+        dictTenantData.setSort(100);
+        dictTenantDataService.save(dictTenantData);
+
+    }
+}

+ 59 - 0
hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/impl/XiaomanCustomerInfoJsonServiceImpl.java

@@ -0,0 +1,59 @@
+package com.fjhx.customer.service.xiaoman.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomerInfoJson;
+import com.fjhx.customer.mapper.xiaoman.XiaomanCustomerInfoJsonMapper;
+import com.fjhx.customer.service.xiaoman.XiaomanCustomerInfoJsonService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerInfoJsonVo;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerInfoJsonSelectDto;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerInfoJsonDto;
+import cn.hutool.core.bean.BeanUtil;
+
+import static com.ruoyi.common.utils.wrapper.IWrapper.getWrapper;
+
+
+/**
+ * <p>
+ * 小满客户详情表 服务实现类
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Service
+public class XiaomanCustomerInfoJsonServiceImpl extends ServiceImpl<XiaomanCustomerInfoJsonMapper, XiaomanCustomerInfoJson> implements XiaomanCustomerInfoJsonService {
+
+    @Override
+    public Page<XiaomanCustomerInfoJsonVo> getPage(XiaomanCustomerInfoJsonSelectDto dto) {
+        IWrapper<XiaomanCustomerInfoJson> wrapper = getWrapper();
+        Page<XiaomanCustomerInfoJsonVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        return page;
+    }
+
+    @Override
+    public XiaomanCustomerInfoJsonVo detail(Long id) {
+        XiaomanCustomerInfoJson XiaomanCustomerInfoJson = this.getById(id);
+        XiaomanCustomerInfoJsonVo result = BeanUtil.toBean(XiaomanCustomerInfoJson, XiaomanCustomerInfoJsonVo.class);
+        return result;
+    }
+
+    @Override
+    public void add(XiaomanCustomerInfoJsonDto xiaomanCustomerInfoJsonDto) {
+        this.save(xiaomanCustomerInfoJsonDto);
+    }
+
+    @Override
+    public void edit(XiaomanCustomerInfoJsonDto xiaomanCustomerInfoJsonDto) {
+        this.updateById(xiaomanCustomerInfoJsonDto);
+    }
+
+    @Override
+    public void delete(Long id) {
+        this.removeById(id);
+    }
+
+}

+ 342 - 0
hx-customer/src/main/java/com/fjhx/customer/service/xiaoman/impl/XiaomanCustomerServiceImpl.java

@@ -0,0 +1,342 @@
+package com.fjhx.customer.service.xiaoman.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.customer.contants.XiaomanContant;
+import com.fjhx.customer.entity.customer.po.Customer;
+import com.fjhx.customer.entity.customer.po.CustomerUser;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomer;
+import com.fjhx.customer.entity.xiaoman.po.XiaomanCustomerInfoJson;
+import com.fjhx.customer.entity.xiaoman.vo.CustomerApiVo;
+import com.fjhx.customer.entity.xiaoman.vo.CustomerInfoVo;
+import com.fjhx.customer.handle.HandleXiaomanData;
+import com.fjhx.customer.handle.R;
+import com.fjhx.customer.mapper.xiaoman.XiaomanCustomerMapper;
+import com.fjhx.customer.service.customer.CustomerService;
+import com.fjhx.customer.service.customer.CustomerUserService;
+import com.fjhx.customer.service.xiaoman.XiaomanApiService;
+import com.fjhx.customer.service.xiaoman.XiaomanCustomerService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.tenant.entity.dict.vo.DictTenantDataVo;
+import com.fjhx.tenant.utils.DictUtils;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.service.impl.SysUserServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerVo;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerSelectDto;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.fjhx.customer.entity.xiaoman.dto.XiaomanCustomerDto;
+import cn.hutool.core.bean.BeanUtil;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static com.ruoyi.common.utils.wrapper.IWrapper.getWrapper;
+
+/**
+ * <p>
+ * 小满客户表 服务实现类
+ * </p>
+ *
+ * @author lqh
+ * @since 2024-04-06
+ */
+@Service
+public class XiaomanCustomerServiceImpl extends ServiceImpl<XiaomanCustomerMapper, XiaomanCustomer> implements XiaomanCustomerService {
+
+    @Resource
+    private XiaomanCustomerInfoJsonServiceImpl xiaomanCustomerInfoJsonService;
+
+    @Resource
+    private CustomerService customerService;
+
+    @Resource
+    private CustomerUserService customerUserService;
+
+    @Resource
+    private SysUserServiceImpl sysUserService;
+    @Resource
+    private XiaomanApiService xiaomanApiService;
+
+    @Override
+    public List<XiaomanCustomerVo> getList(XiaomanCustomerSelectDto dto) {
+        IWrapper<XiaomanCustomer> wrapper = getWrapper();
+        if(ObjectUtil.isNotEmpty(dto.getKeyword())){
+            wrapper.and(q->q.like("xc",XiaomanCustomer::getCompanyId,dto.getKeyword()))
+                    .or().like("xc",XiaomanCustomer::getCustomerId,dto.getKeyword())
+                    .or().like("xc",XiaomanCustomer::getName,dto.getKeyword())
+                    .or().like("xc",XiaomanCustomer::getShortName,dto.getKeyword())
+            ;
+        }
+        wrapper.orderByDesc("xc", XiaomanCustomer::getCompanyId);
+        List<XiaomanCustomerVo> list = this.baseMapper.getList(wrapper);
+        return list;
+    }
+
+    @Override
+    public Page<XiaomanCustomerVo> getPage(XiaomanCustomerSelectDto dto) {
+        IWrapper<XiaomanCustomer> wrapper = getWrapper();
+        wrapper.orderByDesc("xc", XiaomanCustomer::getCompanyId);
+        Page<XiaomanCustomerVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        return page;
+    }
+
+    @Override
+    public XiaomanCustomerVo detail(Long id) {
+        XiaomanCustomer XiaomanCustomer = this.getById(id);
+        XiaomanCustomerVo result = BeanUtil.toBean(XiaomanCustomer, XiaomanCustomerVo.class);
+        return result;
+    }
+
+    @Override
+    public void add(XiaomanCustomerDto xiaomanCustomerDto) {
+        this.save(xiaomanCustomerDto);
+    }
+
+    @Override
+    public void edit(XiaomanCustomerDto xiaomanCustomerDto) {
+        this.updateById(xiaomanCustomerDto);
+    }
+
+    @Override
+    public void delete(Long id) {
+        this.removeById(id);
+    }
+
+    @Override
+    public void handleSaveOrUpdate(List<CustomerApiVo> customerApiVoList, Set<Long> allCustomer) {
+        List<XiaomanCustomer> xiaomanCustomerList = new ArrayList<>(customerApiVoList);
+        for (XiaomanCustomer customer : xiaomanCustomerList){
+            try {
+                if (allCustomer.contains(customer.getCompanyId())){
+
+                    String customerDetailJson = xiaomanApiService.getCustomerDetail(customer.getCompanyId());
+                    XiaomanCustomerInfoJson xiaomanCustomerInfoJson = new XiaomanCustomerInfoJson();
+                    xiaomanCustomerInfoJson.setCompanyId(customer.getCompanyId());
+                    xiaomanCustomerInfoJson.setJson(customerDetailJson);
+                    xiaomanCustomerInfoJsonService.updateById(xiaomanCustomerInfoJson);
+                    CustomerInfoVo infoVo = HandleXiaomanData.handleDate(customerDetailJson, new TypeReference<R<CustomerInfoVo>>() {
+                    });
+                    Long s = customerConversion(infoVo);
+                    customer.setCustomerId(s);
+                    updateById(customer);
+                }else {
+
+                    String customerDetailJson = xiaomanApiService.getCustomerDetail(customer.getCompanyId());
+                    XiaomanCustomerInfoJson xiaomanCustomerInfoJson = new XiaomanCustomerInfoJson();
+                    xiaomanCustomerInfoJson.setCompanyId(customer.getCompanyId());
+                    xiaomanCustomerInfoJson.setJson(customerDetailJson);
+                    xiaomanCustomerInfoJsonService.save(xiaomanCustomerInfoJson);
+
+                    CustomerInfoVo infoVo = HandleXiaomanData.handleDate(customerDetailJson, new TypeReference<R<CustomerInfoVo>>() {
+                    });
+                    //小满客户 =》 客户
+                    Long s = customerConversion(infoVo);
+                    customer.setCustomerId(s);
+                    save(customer);
+                    System.out.println("2");
+                }
+            }catch (Exception e){
+               e.printStackTrace();
+            }
+        }
+
+
+    }
+
+    /**
+     * 小满客户 =》 客户
+     * @param vo
+     */
+    public Long customerConversion(CustomerInfoVo vo) {
+        SecurityUtils.setTenantId(XiaomanContant.TENANT_ID);
+        List<Customer> list = customerService.lambdaQuery()
+                .eq(StringUtils.isNotEmpty(vo.getName()), Customer::getName, vo.getName())
+                .or()
+                .eq(StringUtils.isNotEmpty(vo.getShortName()), Customer::getName, vo.getShortName())
+                .or()
+                .eq(Objects.nonNull(vo.getCompanyId()), Customer::getCompanyId, vo.getCompanyId())
+                .list();
+
+        if (!list.isEmpty()){
+            for (Customer customer :list){
+                //小满公司ID
+                customer.setCompanyId(vo.getCompanyId());
+                //公司编号
+                customer.setCustomerCode(vo.getSerialId());
+                //业务员ID
+                if (!vo.getOwner().isEmpty()){
+                    DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+                    SysUser sysUser = sysUserService.lambdaQuery().eq(SysUser::getNickNameEn, vo.getOwner().get(0).getName()).one();
+                    if (Objects.nonNull(sysUser)){
+                        customer.setUserId(sysUser.getUserId());
+                    }
+                    DynamicDataSourceContextHolder.poll();
+                }
+                //TODO 标签tag  customer_tag
+                if (!vo.getTag().isEmpty()){
+                    Set<String> tags = new HashSet<>();
+                    vo.getTag().forEach(x->{
+                        List<DictTenantDataVo> customerTag = DictUtils.getDictList("customer_tag");
+                        AtomicReference<String> key  = new AtomicReference<>("");
+                        customerTag.forEach(tag ->{
+                            if (tag.getDictValue().equals(x.getTagName())){
+                                key.set(tag.getDictKey());
+                            }
+                        });
+                        if (StringUtils.isNull(key)){
+                            xiaomanApiService.dealCustomerTagDict(x.getTagName(),x.getTagId());
+                            tags.add(x.getTagId());
+                        }else {
+                            tags.add(String.valueOf(key));
+                        }
+
+                    });
+                    customer.setTag(String.join(",",tags));
+                }
+
+                //客户名称
+                customer.setName(vo.getName());
+                //客户简称
+                customer.setShortName(vo.getShortName());
+
+                if (!vo.getOriginList().isEmpty()){
+                    List<DictTenantDataVo> customerSource = DictUtils.getDictList("customer_source");
+                    Set<String> sources = new HashSet<>();
+                    vo.getOriginList().forEach(x->{
+                        customerSource.forEach(tag ->{
+                            if (tag.getDictValue().equals(x)){
+                                sources.add(tag.getDictKey());
+                            }
+                        });
+                    });
+                    customer.setSource(String.join(",",sources));
+                }
+
+
+                //客户规模
+                customer.setScaleId(vo.getScaleId());
+
+                if (StringUtils.isNotEmpty(vo.getTrailStatus())){
+                    AtomicReference<String> status = new AtomicReference<>("");
+                    List<DictTenantDataVo> customerSource = DictUtils.getDictList("customer_status");
+                        customerSource.forEach(tag ->{
+                            if (tag.getDictValue().equals(vo.getTrailStatus())){
+                                status.set(tag.getDictKey());
+                            }
+                        });
+                    customer.setStatus(String.valueOf(status));
+                }
+
+
+
+                //公司网址
+                customer.setHomepage(vo.getHomepage());
+                //小满传真
+                customer.setFax(vo.getFax());
+                //小满电话区号
+                customer.setTelAreaCode(vo.getTelAreaCode());
+                //小满电话
+                customer.setTel(vo.getTel());
+                //小满备注
+                customer.setRemark(vo.getRemark());
+
+
+                //联系人
+                if (!vo.getCustomers().isEmpty()){
+                    Map<String, CustomerUser> collect = customerUserService.lambdaQuery()
+                            .eq(CustomerUser::getCustomerId, customer.getId())
+                            .list().stream().collect(Collectors.toMap(CustomerUser::getEmail, Function.identity()));
+                    //1、小满客户的联系人email为空,不做同步
+                    //2、小满客户的联系人email与客户表联系人相匹配,以小满为主修改联系人信息
+                    //3、小满客户的联系人email与客户表联系人不匹配,以小满为主新增联系人信息
+                    for (CustomerInfoVo.Customer cus  :vo.getCustomers()){
+                        if (StringUtils.isNotEmpty(cus.getEmail())){
+                            //如果email匹配成功新增 ,以小满为主修改客户信息
+                            if (collect.containsKey(cus.getEmail()) ){
+                                CustomerUser customerUser = collect.get(cus.getEmail());
+                                customerUser.setName(cus.getName());
+                                customerUser.setEmail(cus.getEmail());
+                                List<Map> maps = new ArrayList<>();
+                                if (! cus.getContact().isEmpty()) {
+                                    for (CustomerInfoVo.Contact contact : cus.getContact()) {
+                                        Map map1 = new HashMap();
+                                        map1.put("type", contact.getType());
+                                        map1.put("contactNo", contact.getValue());
+                                        maps.add(map1);
+                                    }
+                                }else {
+                                    Map map1 = new HashMap();
+                                    map1.put("type", "");
+                                    map1.put("contactNo", "");
+                                    maps.add(map1);
+                                }
+                                customerUser.setPhone(cus.getTel());
+                                customerUser.setContactJson(JSON.toJSONString(maps));
+                                customerUserService.updateById(customerUser);
+                            }else {
+                                CustomerUser customerUser = new CustomerUser();
+                                customerUser.setCustomerId(customer.getId());
+                                customerUser.setName(cus.getName());
+                                customerUser.setEmail(cus.getEmail());
+                                List<Map> maps = new ArrayList<>();
+                                if (! cus.getContact().isEmpty()){
+                                    for (CustomerInfoVo.Contact contact : cus.getContact()) {
+                                        Map map1 = new HashMap();
+                                        map1.put("type", contact.getType());
+                                        map1.put("contactNo", contact.getValue());
+                                        maps.add(map1);
+                                    }
+                                }else{
+                                    Map map1 = new HashMap();
+                                    map1.put("type", "");
+                                    map1.put("contactNo", "");
+                                    maps.add(map1);
+                                }
+                                customerUser.setPhone(cus.getTel());
+                                customerUser.setContactJson(JSON.toJSONString(maps));
+                                customerUserService.save(customerUser);
+
+                                //新增后添加至map中
+                                collect.put(customerUser.getEmail(),customerUser);
+                            }
+                        }
+
+                    }
+
+
+                }
+                customer.setCountryName(vo.getCountryName());
+                customerService.updateById(customer);
+            }
+
+        }
+
+        SecurityUtils.clearTenantId();
+        if (!list.isEmpty()) {
+            Long collect = list.stream().map(Customer::getId).collect(Collectors.toList()).get(0);
+            return collect;
+        }else {
+            return null;
+        }
+
+    }
+
+    @Override
+    public void initAllList() {
+        xiaomanApiService.initAllList();
+    }
+    @Override
+    public void updateList() {
+        xiaomanApiService.updateList();
+    }
+}

+ 19 - 2
hx-customer/src/main/resources/mapper/customer/CustomerMapper.xml

@@ -22,7 +22,16 @@
             c.create_time,
             c.update_user,
             c.update_time,
-            c.tag
+            c.tag,
+            c.company_id,
+            c.short_name,
+            c.homepage,
+            c.scale_id,
+            c.fax,
+            c.tel_area_code,
+            c.tel,
+            c.remark,
+            c.country_name
         from customer c
             ${ew.customSqlSegment}
     </select>
@@ -45,7 +54,15 @@
             c.create_time,
             c.update_user,
             c.update_time,
-            c.tag
+            c.tag,
+            c.company_id,
+            c.short_name,
+            c.homepage,
+            c.scale_id,
+            c.fax,
+            c.tel_area_code,
+            c.tel,
+            c.country_name
         from customer c
             ${ew.customSqlSegment}
     </select>

+ 5 - 0
hx-customer/src/main/resources/mapper/customer/XiaomanConfigMapper.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.fjhx.customer.mapper.xiaoman.XiaomanConfigMapper">
+
+</mapper>

+ 12 - 0
hx-customer/src/main/resources/mapper/xiaoman/XiaomanCustomerInfoJsonMapper.xml

@@ -0,0 +1,12 @@
+<?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.fjhx.customer.mapper.xiaoman.XiaomanCustomerInfoJsonMapper">
+    <select id="getPage" resultType="com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerInfoJsonVo">
+        select
+            xcij.company_id,
+            xcij.json
+        from xiaoman_customer_info_json xcij
+            ${ew.customSqlSegment}
+    </select>
+
+</mapper>

+ 38 - 0
hx-customer/src/main/resources/mapper/xiaoman/XiaomanCustomerMapper.xml

@@ -0,0 +1,38 @@
+<?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.fjhx.customer.mapper.xiaoman.XiaomanCustomerMapper">
+    <select id="getList" resultType="com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerVo">
+        select
+            xc.company_id,
+            xc.user_id,
+            xc.name,
+            xc.short_name,
+            xc.serial_id,
+            xc.order_time,
+            xc.create_time,
+            xc.update_time,
+            xc.archive_type,
+            xc.edit_time,
+            xc.customer_id
+        from xiaoman_customer xc
+            ${ew.customSqlSegment}
+    </select>
+
+    <select id="getPage" resultType="com.fjhx.customer.entity.xiaoman.vo.XiaomanCustomerVo">
+        select
+            xc.company_id,
+            xc.user_id,
+            xc.name,
+            xc.short_name,
+            xc.serial_id,
+            xc.order_time,
+            xc.create_time,
+            xc.update_time,
+            xc.archive_type,
+            xc.edit_time,
+            xc.customer_id
+        from xiaoman_customer xc
+            ${ew.customSqlSegment}
+    </select>
+
+</mapper>