소스 검색

客户管家修改项

zhouyy 5 달 전
부모
커밋
f72801a212
22개의 변경된 파일960개의 추가작업 그리고 12개의 파일을 삭제
  1. 14 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/config/DefaultCommonModuleConfig.java
  2. 43 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/UserCommonModuleController.java
  3. 144 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/VisitPlanController.java
  4. 11 5
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Contacts.java
  5. 13 6
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/SysDict.java
  6. 37 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/UserCommonModule.java
  7. 60 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/VisitPlan.java
  8. 3 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/SysModuleMapper.java
  9. 11 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/UserCommonModuleMapper.java
  10. 7 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/VisitPlanMapper.java
  11. 15 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/UserCommonModuleService.java
  12. 20 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/VisitPlanService.java
  13. 147 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/UserCommonModuleServiceImpl.java
  14. 242 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/VisitPlanServiceImpl.java
  15. 24 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/ApplicationContextHelperUtil.java
  16. 34 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/TaskThreadPool.java
  17. 67 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanDelayHandler.java
  18. 44 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanDelayItem.java
  19. 2 0
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/application.yml
  20. 2 1
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/ContactsMapper.xml
  21. 8 0
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/SysModuleMapper.xml
  22. 12 0
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/UserCommonModuleMapper.xml

+ 14 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/config/DefaultCommonModuleConfig.java

@@ -0,0 +1,14 @@
+package com.management.platform.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "defaultcommonmodules")
+public class DefaultCommonModuleConfig {
+    private List<String> path;
+}

+ 43 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/UserCommonModuleController.java

@@ -0,0 +1,43 @@
+package com.management.platform.controller;
+
+import com.management.platform.service.UserCommonModuleService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/userCommonModule")
+public class UserCommonModuleController {
+
+    @Resource
+    private UserCommonModuleService userCommonModuleService;
+
+    @PostMapping("/getCommonModules")
+    private HttpRespMsg getCommonModules(HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg = userCommonModuleService.getCommonModules(request);
+        return httpRespMsg;
+    }
+
+    @PostMapping("/addCommonModule")
+    private HttpRespMsg addCommonModule(@RequestParam("moduleId")Integer moduleId,HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg = userCommonModuleService.addCommonModule(moduleId,request);
+        return httpRespMsg;
+    }
+
+    @PostMapping("/delCommonModules")
+    private HttpRespMsg delCommonModules(@RequestParam("moduleId")String moduleIds,HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg = userCommonModuleService.delCommonModules(moduleIds,request);
+        return httpRespMsg;
+    }
+
+
+
+}

+ 144 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/VisitPlanController.java

@@ -0,0 +1,144 @@
+package com.management.platform.controller;
+
+import com.management.platform.entity.VisitPlan;
+import com.management.platform.service.VisitPlanService;
+import com.management.platform.time.VisitPlanDelayHandler;
+import com.management.platform.time.VisitPlanDelayItem;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("/visitPlan")
+public class VisitPlanController {
+
+    @Resource
+    private VisitPlanService visitPlanService;
+
+    /***
+     * 新增拜访计划
+     * @param planName
+     * @param customId
+     * @param customName
+     * @param inchargerId
+     * @param visitGoal
+     * @param visitTime
+     * @param remark
+     * @param remindType
+     * @param remindTime
+     * @param request
+     * @return
+     */
+    @PostMapping("/addVisitPlan")
+    public HttpRespMsg testTask(
+            @RequestParam("planName") String planName,
+            @RequestParam("customId") Integer customId,
+            @RequestParam("customName") String customName,
+            @RequestParam("inchargerId") String inchargerId,
+            @RequestParam("visitGoal") Integer visitGoal,
+            @RequestParam("visitTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date visitTime,
+            @RequestParam("remark") String remark,
+            @RequestParam("remindType") Integer remindType,
+            @RequestParam(value = "remindTime",required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date remindTime
+            , HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        VisitPlan visitPlan = new VisitPlan();
+        visitPlan.setPlanName(planName);
+        visitPlan.setCustomId(customId);
+        visitPlan.setCustomName(customName);
+        visitPlan.setInchargerId(inchargerId);
+        visitPlan.setVisitGoal(visitGoal);
+        visitPlan.setVisitTime(visitTime);
+        visitPlan.setRemark(remark);
+        visitPlan.setRemindType(remindType);
+        visitPlan.setRemindTime(remindTime);
+        httpRespMsg = visitPlanService.addVisitPlan(visitPlan,request);
+
+        return httpRespMsg;
+    }
+
+
+    /***
+     * 完成拜访计划
+     * @param planId
+     * @param request
+     * @return
+     */
+    @PostMapping("/finishVisitPlan")
+    public HttpRespMsg finishVisitPlan(@RequestParam("planId") Long planId, HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg = visitPlanService.finishVisitPlan(planId,request);
+        return httpRespMsg;
+    }
+
+    /***
+     * 延迟拜访时间
+     * @param planId
+     * @param visitTime
+     * @param request
+     * @return
+     */
+    @PostMapping("/delayVisitPlan")
+    public HttpRespMsg delayVisitPlan(@RequestParam("planId") Long planId
+            ,@RequestParam("visitTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date visitTime
+            , HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg=visitPlanService.delayVisitPlan(planId,visitTime,request);
+        return httpRespMsg;
+    }
+
+
+    /***
+     * 删除拜访计划
+     * @param planId
+     * @param request
+     * @return
+     */
+    @PostMapping("/delVisitPlan")
+    public HttpRespMsg delVisitPlan(@RequestParam("planId") Long planId, HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg = visitPlanService.delVisitPlan(planId,request);
+        return httpRespMsg;
+    }
+
+    /***
+     * 获取分页数据
+     * @param pageIndex
+     * @param pageSize
+     * @param calenderTime
+     * @param request
+     * @return
+     */
+    @PostMapping("/getPageVisitPlan")
+    public HttpRespMsg getPageVisitPlan(@RequestParam Integer pageIndex
+            , @RequestParam Integer pageSize
+            ,@RequestParam("calenderTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date calenderTime
+            ,HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg = visitPlanService.getPageVisitPlan(pageIndex,pageSize,calenderTime,request);
+        return httpRespMsg;
+    }
+
+
+    @GetMapping("/getDelayQueue")
+    public HttpRespMsg getDelayQueue(HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+        httpRespMsg.setData(tool.getAll());
+        Object[] all =  tool.getAll();
+        for (Object obj : all) {
+            VisitPlanDelayItem item = (VisitPlanDelayItem) obj;
+            long delay = item.getDelay(TimeUnit.SECONDS);
+            System.out.println("item== "+item.getVisitPlan().getPlanName()
+                    +",delayTime=== "+item.getDelayTime()
+            +",delay=== "+delay
+            );
+        }
+        return httpRespMsg;
+    }
+}

+ 11 - 5
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Contacts.java

@@ -1,18 +1,18 @@
 package com.management.platform.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.extension.activerecord.Model;
-import com.baomidou.mybatisplus.annotation.TableId;
-import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
-import java.io.Serializable;
-
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
 /**
  * <p>
  * 
@@ -144,6 +144,12 @@ public class Contacts extends Model<Contacts> {
     @TableField("plate5")
     private String plate5;
 
+    /**
+     * 是否为常用联系人 0否1是
+     */
+    @TableField("is_frequent")
+    private Integer isFrequent;
+
 
     @Override
     protected Serializable pkVal() {

+ 13 - 6
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/SysDict.java

@@ -1,19 +1,19 @@
 package com.management.platform.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.extension.activerecord.Model;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-
 /**
  * <p>
  * 
@@ -53,6 +53,13 @@ public class SysDict extends Model<SysDict> {
     @TableField("company_id")
     private Integer companyId;
 
+    @TableField("ext1")
+    private String ext1;
+    @TableField("ext2")
+    private String ext2;
+    @TableField("ext3")
+    private String ext3;
+
 
     @Override
     protected Serializable pkVal() {

+ 37 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/UserCommonModule.java

@@ -0,0 +1,37 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class UserCommonModule extends Model<UserCommonModule> {
+    private static final long serialVersionUID=1L;
+    /**主键id*/
+    @TableId(value = "id",type = IdType.AUTO)
+    private Long id;
+    /**用户id*/
+    @TableField("user_id")
+    private String userId;
+    /**公司id*/
+    @TableField("company_id")
+    private Integer companyId;
+    /**模块id*/
+    @TableField("module_id")
+    private Integer moduleId;
+    /**排序*/
+    @TableField("seq")
+    private Integer seq;
+    /**创建时间*/
+    @TableField("create_time")
+    private Date createTime;
+
+}

+ 60 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/VisitPlan.java

@@ -0,0 +1,60 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class VisitPlan extends Model<VisitPlan> {
+    private static final long serialVersionUID=1L;
+    /**主键id*/
+    @TableId(value = "id",type = IdType.AUTO)
+    private Long id;
+    /**计划名称*/
+    @TableField(value = "plan_name")
+    private String planName;
+    /**客户id*/
+    @TableField(value = "custom_id")
+    private Integer customId;
+    /**客户名称*/
+    @TableField(value = "custom_name")
+    private String customName;
+    /**负责人id(user表)*/
+    @TableField(value = "incharger_id")
+    private String inchargerId;
+    /**拜访目的 字典表id*/
+    @TableField(value = "visit_goal")
+    private Integer visitGoal;
+    /**拜访时间*/
+    @TableField(value = "visit_time")
+    private Date visitTime;
+    /**备注*/
+    @TableField(value = "remark")
+    private String remark;
+    /**提醒类型  字典表id,对应字典项name类型名称 ex1时间[秒]*/
+    @TableField(value = "remind_type")
+    private Integer remindType;
+    /**提醒时间[自定义时间时再填充]*/
+    @TableField(value = "remind_time")
+    private Date remindTime;
+
+    /**是否达到提醒时间 0未到 1已到 2不需要提醒*/
+    @TableField(value = "remind_state")
+    private Integer remindState;
+
+    /**完成状态 0未完成 1已完成*/
+    @TableField(value = "finish_state")
+    private Integer finishState;
+
+    /**创建人*/
+    @TableField(value = "create_by")
+    private String createBy;
+}

+ 3 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/SysModuleMapper.java

@@ -3,6 +3,8 @@ package com.management.platform.mapper;
 import com.management.platform.entity.SysModule;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 
+import java.util.List;
+
 /**
  * <p>
  * 菜单表 Mapper 接口
@@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface SysModuleMapper extends BaseMapper<SysModule> {
 
+    List<SysModule> getModuleByRole(Integer roleId);
 }

+ 11 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/UserCommonModuleMapper.java

@@ -0,0 +1,11 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.UserCommonModule;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface UserCommonModuleMapper extends BaseMapper<UserCommonModule> {
+    void insertBatch(@Param("toAddList") List<UserCommonModule> toAddList);
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/VisitPlanMapper.java

@@ -0,0 +1,7 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.VisitPlan;
+
+public interface VisitPlanMapper extends BaseMapper<VisitPlan> {
+}

+ 15 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/UserCommonModuleService.java

@@ -0,0 +1,15 @@
+package com.management.platform.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.UserCommonModule;
+import com.management.platform.util.HttpRespMsg;
+
+import javax.servlet.http.HttpServletRequest;
+
+public interface UserCommonModuleService extends IService<UserCommonModule> {
+    HttpRespMsg getCommonModules(HttpServletRequest request);
+
+    HttpRespMsg addCommonModule(Integer moduleId,HttpServletRequest request);
+
+    HttpRespMsg delCommonModules(String moduleIds, HttpServletRequest request);
+}

+ 20 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/VisitPlanService.java

@@ -0,0 +1,20 @@
+package com.management.platform.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.VisitPlan;
+import com.management.platform.util.HttpRespMsg;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+public interface VisitPlanService extends IService<VisitPlan> {
+    HttpRespMsg addVisitPlan(VisitPlan visitPlan, HttpServletRequest request);
+
+    HttpRespMsg finishVisitPlan(Long planId, HttpServletRequest request);
+
+    HttpRespMsg delayVisitPlan(Long planId, Date visitTime, HttpServletRequest request);
+
+    HttpRespMsg delVisitPlan(Long planId, HttpServletRequest request);
+
+    HttpRespMsg getPageVisitPlan(Integer pageIndex, Integer pageSize, Date calenderTime, HttpServletRequest request);
+}

+ 147 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/UserCommonModuleServiceImpl.java

@@ -0,0 +1,147 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.config.DefaultCommonModuleConfig;
+import com.management.platform.entity.SysModule;
+import com.management.platform.entity.SysRoleModule;
+import com.management.platform.entity.User;
+import com.management.platform.entity.UserCommonModule;
+import com.management.platform.mapper.SysModuleMapper;
+import com.management.platform.mapper.SysRoleModuleMapper;
+import com.management.platform.mapper.UserCommonModuleMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.UserCommonModuleService;
+import com.management.platform.util.HttpRespMsg;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class UserCommonModuleServiceImpl extends ServiceImpl<UserCommonModuleMapper, UserCommonModule> implements UserCommonModuleService {
+
+    @Resource
+    private UserCommonModuleMapper userCommonModuleMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Resource
+    private SysRoleModuleMapper sysRoleModuleMapper;
+
+    @Resource
+    private SysModuleMapper sysModuleMapper;
+
+    @Resource
+    private DefaultCommonModuleConfig defaultCommonModuleConfig;
+
+    @Override
+    @Transactional
+    public HttpRespMsg getCommonModules(HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user= userMapper.selectById(request.getHeader("token"));
+        if(null == user){
+            httpRespMsg.setError("用户不存在");
+            return httpRespMsg;
+        }
+        List<UserCommonModule> commonModules = userCommonModuleMapper.selectList(new LambdaQueryWrapper<UserCommonModule>()
+                .eq(UserCommonModule::getUserId, user.getId()).orderByAsc(UserCommonModule::getSeq)
+        );
+        if(CollectionUtils.isEmpty(commonModules)){
+            List<String> list = defaultCommonModuleConfig.getPath();
+            List<SysModule> sysModules = sysModuleMapper.getModuleByRole(user.getRoleId());
+            List<SysModule> resModule = sysModules.stream()
+                    .filter(t -> list.contains(t.getPath()))
+                    .sorted(Comparator.comparing(SysModule::getName))
+                    .collect(Collectors.toList());
+            if(CollectionUtils.isNotEmpty(resModule)){
+                int index = 1;
+                List<UserCommonModule> toAddList = new ArrayList<>();
+                for (SysModule sysModule : resModule) {
+                    UserCommonModule tmpCommon = new UserCommonModule();
+                    tmpCommon.setSeq(index);
+                    tmpCommon.setUserId(user.getId());
+                    tmpCommon.setCompanyId(user.getCompanyId());
+                    tmpCommon.setModuleId(sysModule.getId());
+                    toAddList.add(tmpCommon);
+                    index++;
+                }
+                if(CollectionUtils.isNotEmpty(toAddList)){
+                    userCommonModuleMapper.insertBatch(toAddList);
+                }
+            }
+        }
+        httpRespMsg.setData(commonModules);
+        return httpRespMsg;
+    }
+
+    @Override
+    @Transactional
+    public HttpRespMsg addCommonModule(Integer moduleId,HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user= userMapper.selectById(request.getHeader("token"));
+        if(null == user){
+            httpRespMsg.setError("用户不存在");
+            return httpRespMsg;
+        }
+        //是否已存在
+        Integer count = userCommonModuleMapper.selectCount(new LambdaQueryWrapper<UserCommonModule>()
+                .eq(UserCommonModule::getModuleId, moduleId)
+                .eq(UserCommonModule::getUserId, user.getId())
+        );
+        if(count > 0){
+            httpRespMsg.setError("已有该常用模块");
+            return httpRespMsg;
+        }
+        //是否有权限
+        Integer roleModuleCount = sysRoleModuleMapper.selectCount(new LambdaQueryWrapper<SysRoleModule>()
+                .eq(SysRoleModule::getModuleId, moduleId)
+                .eq(SysRoleModule::getRoleId, user.getRole())
+        );
+        if(roleModuleCount <= 0){
+            httpRespMsg.setError("无该模块权限");
+            return httpRespMsg;
+        }
+        //计算seq
+        UserCommonModule lastModule = userCommonModuleMapper.selectOne(new LambdaQueryWrapper<UserCommonModule>()
+                .eq(UserCommonModule::getUserId, user.getId())
+                .orderByDesc(UserCommonModule::getSeq)
+                .last("limit 1")
+        );
+        UserCommonModule entity = new UserCommonModule();
+        entity.setModuleId(moduleId);
+        entity.setUserId(user.getId());
+        entity.setCompanyId(user.getCompanyId());
+        entity.setSeq(null==lastModule?1:lastModule.getSeq()+1);
+        userCommonModuleMapper.insert(entity);
+        return httpRespMsg;
+    }
+
+    @Override
+    @Transactional
+    public HttpRespMsg delCommonModules(String moduleIds, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user= userMapper.selectById(request.getHeader("token"));
+        if(null == user){
+            httpRespMsg.setError("用户不存在");
+            return httpRespMsg;
+        }
+        String[] split = moduleIds.split(",");
+        List<Integer> collect = Arrays.stream(split).map(Integer::parseInt).collect(Collectors.toList());
+        userCommonModuleMapper.delete(new LambdaQueryWrapper<UserCommonModule>()
+                .eq(UserCommonModule::getUserId, user.getId())
+                .in(UserCommonModule::getModuleId,collect)
+        );
+        return httpRespMsg;
+    }
+
+
+}

+ 242 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/VisitPlanServiceImpl.java

@@ -0,0 +1,242 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.entity.SysDict;
+import com.management.platform.entity.User;
+import com.management.platform.entity.VisitPlan;
+import com.management.platform.mapper.SysDictMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.mapper.VisitPlanMapper;
+import com.management.platform.service.VisitPlanService;
+import com.management.platform.time.VisitPlanDelayHandler;
+import com.management.platform.time.VisitPlanDelayItem;
+import com.management.platform.util.HttpRespMsg;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Service
+public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan> implements VisitPlanService {
+
+
+    @Resource
+    ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+
+    @Resource
+    private VisitPlanMapper visitPlanMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Resource
+    private SysDictMapper sysDictMapper;
+
+    @Override
+    public HttpRespMsg addVisitPlan(VisitPlan visitPlan, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        Date now = new Date();
+        User user= userMapper.selectById(request.getHeader("token"));
+        if(null == user){
+            httpRespMsg.setError("用户不存在");
+            return httpRespMsg;
+        }
+
+        if(visitPlan.getVisitTime().before(now)){
+            httpRespMsg.setError("拜访时间不能在当前时段之前");
+            return httpRespMsg;
+        }
+
+        List<SysDict> remindTypeList = sysDictMapper.selectList(new LambdaQueryWrapper<SysDict>()
+                .eq(SysDict::getCode, "RemindType")
+                .eq(SysDict::getCompanyId, user.getCompanyId())
+        );
+        if(CollectionUtils.isEmpty(remindTypeList)){
+            httpRespMsg.setError("公司未设置提醒类型字典项,请联系管理员");
+            return httpRespMsg;
+        }
+        Map<Integer, SysDict> timeTypeMap = remindTypeList.stream().collect(Collectors.toMap(SysDict::getId, t->t));
+        SysDict timeTypeDict = timeTypeMap.get(visitPlan.getRemindType());
+        if(null == timeTypeDict){
+            httpRespMsg.setError("提醒类型不存在,请重新填写");
+            return httpRespMsg;
+        }
+
+        Long delayTime = 0L;
+        Long startTimeMilliSec = 0L;
+        Long endTimeMilliSec = 0L;
+        if(timeTypeDict.getName().equals("不提醒")){
+            //不加入队列,不需要提醒
+            visitPlan.setRemindState(2);
+        } else if (timeTypeDict.getName().equals("自定义时间")) {
+            //重新计算delayTime 自定义时间-当前时间
+            if(visitPlan.getRemindTime().before(now)
+                    || visitPlan.getRemindTime().after(visitPlan.getVisitTime())){
+                httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
+                return httpRespMsg;
+            }
+            //毫秒
+            startTimeMilliSec = now.getTime();
+            endTimeMilliSec = visitPlan.getRemindTime().getTime();
+            delayTime = endTimeMilliSec - startTimeMilliSec;
+        }else{
+            startTimeMilliSec = now.getTime();
+            endTimeMilliSec = visitPlan.getVisitTime().getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;
+            if(endTimeMilliSec < startTimeMilliSec){
+                httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
+                return httpRespMsg;
+            }
+            delayTime = endTimeMilliSec-startTimeMilliSec;
+        }
+
+        visitPlan.setCreateBy(user.getId());
+        visitPlanMapper.insert(visitPlan);
+
+        //加入执行队列
+        if(!timeTypeDict.getName().equals("不提醒")){
+            VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+            VisitPlan taskPlan = visitPlanMapper.selectById(visitPlan.getId());
+            VisitPlanDelayItem item = new VisitPlanDelayItem(delayTime
+                    ,startTimeMilliSec
+                    ,endTimeMilliSec
+                    ,taskPlan.getId(),taskPlan);
+            tool.addItem(item);
+            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            System.out.println("当前时间: "+format.format(new Date()));
+            threadPoolTaskExecutor.execute(tool);
+        }
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg finishVisitPlan(Long planId, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+
+        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+        tool.removeIfExist(planId);
+
+        //完成计划则修改:1、是否到达提醒时间为不需要提醒 2、完成状态为 已完成
+        visitPlanMapper.update(null,new LambdaUpdateWrapper<VisitPlan>()
+                        .set(VisitPlan::getRemindState, 2)
+                        .set(VisitPlan::getFinishState,1)
+                .eq(VisitPlan::getId,planId)
+        );
+
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg delayVisitPlan(Long planId, Date newVisitTime, HttpServletRequest request) {
+        //删除原队列,计算时间后重新纳入队列
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        Date now = new Date();
+        User user= userMapper.selectById(request.getHeader("token"));
+        if(null == user){
+            httpRespMsg.setError("用户不存在");
+            return httpRespMsg;
+        }
+        if(newVisitTime.before(now)){
+            httpRespMsg.setError("拜访时间不能在当前时段之前");
+            return httpRespMsg;
+        }
+        VisitPlan taskPlan = visitPlanMapper.selectById(planId);
+        SysDict timeTypeDict = sysDictMapper.selectOne(new LambdaQueryWrapper<SysDict>()
+                .eq(SysDict::getCode, "RemindType")
+                .eq(SysDict::getId, taskPlan.getRemindType())
+                .eq(SysDict::getCompanyId, user.getCompanyId())
+        );
+
+        Long delayTime = 0L;
+        Long startTimeMilliSec = 0L;
+        Long endTimeMilliSec = 0L;
+        taskPlan.setVisitTime(newVisitTime);
+        if(timeTypeDict.getName().equals("不提醒")){
+            //不加入队列,不修改状态,只修改拜访时间
+        } else if (timeTypeDict.getName().equals("自定义时间")) {
+            //重新计算delayTime 自定义时间-当前时间
+            if(taskPlan.getRemindTime().before(now)
+                    || taskPlan.getRemindTime().after(newVisitTime)){
+                httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
+                return httpRespMsg;
+            }
+            //毫秒
+            startTimeMilliSec = now.getTime();
+            endTimeMilliSec = taskPlan.getRemindTime().getTime();
+            delayTime = endTimeMilliSec - startTimeMilliSec;
+        }else{
+            startTimeMilliSec = now.getTime();
+            endTimeMilliSec = newVisitTime.getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;
+            if(endTimeMilliSec < startTimeMilliSec){
+                httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
+                return httpRespMsg;
+            }
+            delayTime = endTimeMilliSec-startTimeMilliSec;
+        }
+
+        //删除队列
+        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+        tool.removeIfExist(planId);
+        //重新添加
+        VisitPlanDelayItem item = new VisitPlanDelayItem(delayTime
+                ,startTimeMilliSec
+                ,endTimeMilliSec
+                ,taskPlan.getId(),taskPlan);
+        tool.addItem(item);
+
+        visitPlanMapper.update(null,new LambdaUpdateWrapper<VisitPlan>()
+                .set(VisitPlan::getVisitTime,newVisitTime)
+                .eq(VisitPlan::getId,planId)
+        );
+
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg delVisitPlan(Long planId, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user= userMapper.selectById(request.getHeader("token"));
+        if(null == user){
+            httpRespMsg.setError("用户不存在");
+            return httpRespMsg;
+        }
+        //删除队列
+        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+        tool.removeIfExist(planId);
+
+        //删除数据
+        visitPlanMapper.delete(new LambdaQueryWrapper<VisitPlan>()
+                .eq(VisitPlan::getId,planId)
+        );
+
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg getPageVisitPlan(Integer pageIndex, Integer pageSize, Date calenderTime, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user= userMapper.selectById(request.getHeader("token"));
+        if(null == user){
+            httpRespMsg.setError("用户不存在");
+            return httpRespMsg;
+        }
+        IPage<VisitPlan> page = new Page<>(pageIndex,pageSize);
+        page = visitPlanMapper.selectPage(page, new LambdaQueryWrapper<VisitPlan>()
+                .eq(VisitPlan::getVisitTime, calenderTime)
+                .eq(VisitPlan::getCreateBy, user.getId())
+        );
+        httpRespMsg.setData(page);
+        return httpRespMsg;
+    }
+}

+ 24 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/ApplicationContextHelperUtil.java

@@ -0,0 +1,24 @@
+package com.management.platform.time;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ApplicationContextHelperUtil implements ApplicationContextAware {
+    private static ApplicationContext applicationContext;
+    @Override
+    public void setApplicationContext( ApplicationContext applicationContext1 ) throws BeansException {
+        applicationContext = applicationContext1;
+    }
+
+    public static ApplicationContext getApplicationContext(){
+        return applicationContext;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getBean(Class<T> clazz) {
+        return (T) applicationContext.getBean(clazz);
+    }
+}

+ 34 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/TaskThreadPool.java

@@ -0,0 +1,34 @@
+package com.management.platform.time;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+public class TaskThreadPool {
+
+    private static final int corePoolSize = 3;
+    private static final int maxPoolSize = 3;
+    private static final int keepAliveSeconds = 20;
+    private static final int queueCapacity = 10;
+
+    @Bean(value="VisitPlanThreadPool")
+    public ThreadPoolTaskExecutor VisitPlanThreadPool() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(corePoolSize);
+        executor.setMaxPoolSize(maxPoolSize);
+        executor.setQueueCapacity(queueCapacity);
+        executor.setKeepAliveSeconds(keepAliveSeconds);
+        executor.setThreadNamePrefix("VisitPlan-");
+
+        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
+        // DiscardOldestPolicy 抛弃队列中等待最久的  新任务插入队列
+        // CallerRunsPolicy 线程池满后调用当前线程处理任务 适合当前场景
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        executor.initialize();
+        return executor;
+    }
+
+}

+ 67 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanDelayHandler.java

@@ -0,0 +1,67 @@
+package com.management.platform.time;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.management.platform.entity.VisitPlan;
+import com.management.platform.service.VisitPlanService;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.concurrent.DelayQueue;
+
+public class VisitPlanDelayHandler implements Runnable{
+
+    private final static DelayQueue<VisitPlanDelayItem> VISIT_PLAN_DELAY_QUEUE = new DelayQueue<>();
+
+
+    private VisitPlanService visitPlanService =
+            (VisitPlanService) ApplicationContextHelperUtil.getBean(VisitPlanService.class);
+
+
+    public void addItem(VisitPlanDelayItem item) {
+        VISIT_PLAN_DELAY_QUEUE.offer(item);
+    }
+
+    public VisitPlanDelayItem takeItem() throws InterruptedException {
+        return VISIT_PLAN_DELAY_QUEUE.take();
+    }
+
+    public int getSize(){
+        return VISIT_PLAN_DELAY_QUEUE.size();
+    }
+
+    public Object[] getAll(){
+        return VISIT_PLAN_DELAY_QUEUE.toArray();
+    }
+
+    public Boolean removeIfExist(Long id){
+        return VISIT_PLAN_DELAY_QUEUE.removeIf(r -> r.getPlanId().equals(id));
+    }
+
+
+    @Override
+    public void run() {
+        try {
+            VisitPlanDelayItem item = VISIT_PLAN_DELAY_QUEUE.take();
+            VisitPlan visitPlan = item.getVisitPlan();
+            if(visitPlan == null && item.getPlanId() == null){
+                System.out.println("拜访计划通过延时队列--计划为空");
+                return;
+            }
+            System.out.println("拜访计划通过延时队列 --计划id== "+visitPlan.getId()+",name== "
+                    +visitPlan.getPlanName());
+            if(visitPlanService == null){
+                System.out.println("visitPlanService 未初始化");
+                return;
+            }
+            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            //到达提醒时间,则修改 是否到达提醒时间为 已到
+            visitPlanService.update(new LambdaUpdateWrapper<VisitPlan>()
+                            .set(VisitPlan::getRemindState,1)
+                    .eq(VisitPlan::getId, visitPlan.getId())
+            );
+            System.out.println("修改时间: "+format.format(new Date()));
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 44 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanDelayItem.java

@@ -0,0 +1,44 @@
+package com.management.platform.time;
+
+import com.management.platform.entity.VisitPlan;
+import lombok.Data;
+
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
+
+@Data
+public class VisitPlanDelayItem implements Delayed {
+    /**延迟时长 毫秒 [暂时无用]*/
+    private Long delayTime;
+    /**开始时刻  [暂时无用]*/
+    private Long startTimeMilliSec;
+    private Long endTimeMilliSec; // 结束时刻
+    private Long planId;
+    private VisitPlan visitPlan;
+
+    public VisitPlanDelayItem(Long delayTime, Long startTimeMilliSec, Long endTimeMilliSec, Long planId, VisitPlan visitPlan) {
+        this.delayTime = delayTime;
+        this.startTimeMilliSec = startTimeMilliSec;
+        this.endTimeMilliSec = endTimeMilliSec;
+        this.planId = planId;
+        this.visitPlan = visitPlan;
+    }
+
+    @Override
+    //到激活日期的--剩余时间,时间单位由单位参数指定
+    public long getDelay(TimeUnit unit) {
+        long diff = endTimeMilliSec - System.currentTimeMillis();
+        return TimeUnit.MILLISECONDS.toMillis(diff);
+    }
+
+    @Override
+    //队列里元素的排序依据
+    public int compareTo(Delayed o) {
+        if (this.endTimeMilliSec < ((VisitPlanDelayItem) o).endTimeMilliSec) {
+            return -1;
+        } else if (this.endTimeMilliSec > ((VisitPlanDelayItem) o).endTimeMilliSec) {
+            return 1;
+        }
+        return 0;
+    }
+}

+ 2 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/resources/application.yml

@@ -172,3 +172,5 @@ sftp:
   user: root
   password: Huoshi@2022
 
+defaultcommonmodules:
+  path: [/customer,/contacts,/tasks]

+ 2 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/ContactsMapper.xml

@@ -23,11 +23,12 @@
         <result column="plate3" property="plate3" />
         <result column="plate4" property="plate4" />
         <result column="plate5" property="plate5" />
+        <result column="is_frequent" property="isFrequent"></result>
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_id, sex, name, custom_id, email, phone, owner_id, creator_id, address, remark, is_delete, create_time, position, plate1, plate2, plate3, plate4, plate5
+        id, company_id, sex, name, custom_id, email, phone, owner_id, creator_id, address, remark, is_delete, create_time, position, plate1, plate2, plate3, plate4, plate5, is_frequent
     </sql>
 
     <select id="pageContacts" parameterType="java.util.Map"  resultType="com.management.platform.entity.vo.ContactsVo">

+ 8 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/SysModuleMapper.xml

@@ -30,5 +30,13 @@
     <sql id="Base_Column_List">
         id, name, path, parent_id, icon, orderitem, is_menu, use_state, package_time, package_project, package_oa, package_expense, package_customer, package_engineering, package_contract, package_etimecard, report_workflow, package_finance, need_dept_audit, package_provider
     </sql>
+    <select id="getModuleByRole" resultType="com.management.platform.entity.SysModule">
+        select sm.id,srm.module_id,sm.name,sm.path
+        from sys_role_module srm
+                 left join sys_module sm on sm.id = srm.module_id
+        where srm.role_id = #{roleId}
+          and sm.parent_id is null and sm.use_state = 0
+        order by orderitem
+    </select>
 
 </mapper>

+ 12 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/UserCommonModuleMapper.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.management.platform.mapper.UserCommonModuleMapper">
+
+    <insert id="insertBatch">
+        insert into user_common_module(user_id, company_id, module_id, seq, create_time) VALUES
+        <foreach collection="toAddList" item="toAdd" separator=",">
+            (#{toAdd.userId},#{toAdd.companyId},#{toAdd.moduleId},#{toAdd.seq},now())
+        </foreach>
+    </insert>
+</mapper>