ソースを参照

Merge remote-tracking branch 'origin/master'

yusm 5 ヶ月 前
コミット
47234c008d
14 ファイル変更551 行追加176 行削除
  1. 5 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/moduleList/moduleList.vue
  2. 251 15
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/tasks/addEditor.vue
  3. 9 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/utility/defaultData.js
  4. 25 22
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/VisitPlanController.java
  5. 13 3
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/VisitPlan.java
  6. 3 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/VisitPlanMapper.java
  7. 19 13
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java
  8. 114 101
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/VisitPlanServiceImpl.java
  9. 3 5
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/TaskThreadPool.java
  10. 5 5
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanDelayHandler.java
  11. 3 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanInit.java
  12. 70 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanTask.java
  13. 15 4
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/util/DateTimeUtil.java
  14. 16 3
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/VisitPlanMapper.xml

+ 5 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/moduleList/moduleList.vue

@@ -158,7 +158,11 @@ function edit(row) {
   const formJson = fixedData.formJson[queryParameters.value.key] || []
   const formList = resetListData(formJson?.list)
   const filedObj = getListFieldKey(formList, row)
-  toAddEditor({ ...filedObj, id: row.id })
+  let other = {}
+  if(queryParameters.value.key == 'tasks') {
+    other = { ...row }
+  }
+  toAddEditor({ ...other, ...filedObj, id: row.id })
 }
 
 // 转移事件

+ 251 - 15
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/tasks/addEditor.vue

@@ -54,12 +54,104 @@
             </template>
           </van-field>
         </template>
-        <van-field v-model="vantFormVal.contactsId" name="contactsId" label="联系人" placeholder="请选择" is-link readonly :disabled="contactDisabled" v-if="fixedFieldTaskType.find(v => v.value == (vantFormVal.taskType || '1'))?.show"
-          class="resetStyles" @click="showSelectionBox('contactsId', allContactsList)">
+        <van-field v-model="vantFormVal.contactsId" name="contactsId" label="联系人" placeholder="请选择" is-link readonly
+          :disabled="contactDisabled"
+          v-if="fixedFieldTaskType.find(v => v.value == (vantFormVal.taskType || '1'))?.show" class="resetStyles"
+          @click="showSelectionBox('contactsId', allContactsList)">
           <template #input v-if="vantFormVal.contactsId">
             {{ vantFormVal.contactsIdName }}
           </template>
         </van-field>
+        <van-field v-model="vantFormVal.executorId" name="executorId" label="执行人" placeholder="请选择" is-link readonly class="resetStyles"
+          @click="showSelectionBox('executorId', allContactsList)">
+          <template #input v-if="vantFormVal.executorIdName && vantFormVal.executorIdName.length > 0">
+            <TranslationComponent :openId="vantFormVal.executorIdName" />
+          </template>
+        </van-field>
+        <van-field name="isRepeat" label="重复提醒" class="resetStyles">
+          <template #input>
+            <van-switch v-model="vantFormVal.isRepeat" size="small" />
+          </template>
+        </van-field>
+        <!-- 重复提醒 -->
+        <template v-if="vantFormVal.isRepeat">
+          <van-field v-model="vantFormVal.repeatType" name="repeatType" label="重复类型" placeholder="请选择" is-link readonly
+            class="resetStyles" @click="showSelectionBox('repeatType', fixedFieldRepetitiveType)">
+            <template #input v-if="vantFormVal.repeatType">
+              {{ vantFormVal.repeatTypeName }}
+            </template>
+          </van-field>
+          <template v-if="[0, 1, 2, 3, '0', '1', '2', '3'].includes(vantFormVal.repeatType)">
+            <van-field v-model="vantFormVal.repeatDesignSameday" type="digit" name="repeatDesignSameday" label="每"
+              class="resetStyles" v-if="vantFormVal.repeatType == 3">
+              <template #input>
+                <van-stepper v-model="vantFormVal.repeatDesignSameday" :min="0" button-size="1.2rem" theme="round"
+                  integer class="mr-2" />
+              </template>
+              <template #extra> 天 </template>
+            </van-field>
+            <van-field name="endType" label="结束" class="resetStyles">
+              <template #input>
+                <van-radio-group v-model="vantFormVal.endType" direction="horizontal" class="flex flex-col"
+                  @change="radiogroupChange">
+                  <van-radio name="1"><span
+                      :class="vantFormVal.endType == 1 ? 'themeTextColor' : ''">永不</span></van-radio>
+                  <van-radio name="2" class="mt-3">
+                    <van-stepper v-model="vantFormVal.repeatEndCount" :disabled="vantFormVal.endType != 2" :min="0"
+                      button-size="1.2rem" theme="round" integer class="mr-2" />
+                    次数以后
+                  </van-radio>
+                  <van-radio name="3" class="mt-3">
+                    <div class="flex items-center">
+                      <van-field label="日期" is-link readonly :disabled="vantFormVal.endType != 3" class="selectField"
+                        placeholder="请选择" @click="vantFormVal.endType == 3 && showDatePickerBox('repeatEndDate')">
+                        <template #input v-if="vantFormVal.repeatEndDate">
+                          {{ vantFormVal.repeatEndDate }}
+                        </template>
+                      </van-field>
+                      以后
+                    </div>
+                  </van-radio>
+                </van-radio-group>
+              </template>
+            </van-field>
+          </template>
+          <template v-if="[4, '4'].includes(vantFormVal.repeatType)">
+            <div class="flex items-center justify-between px-8 pt-3">
+              <div>自定义日期</div>
+              <div><van-icon name="add-o" class="ml-2 themeTextColor" size="1.3rem" @click="addCustomeDateItem()" /></div>
+            </div>
+            <van-cell-group inset class="additionalCoAuthorship">
+              <template v-for="(item, index) in customeDate">
+                <van-cell :title="`第${index + 1}次重复在`">
+                  <template #default>
+                    <div class="flex items-center justify-end">
+                      <van-stepper v-model="item.value" :min="0" button-size="1.2rem" theme="round" integer
+                        class="mr-2" />
+                      之后
+                      <van-icon name="delete-o" class="ml-2 text-[red]" size="1.3rem"  @click="deleteCustomeDateItem(index)" />
+                    </div>
+                  </template>
+                </van-cell>
+              </template>
+            </van-cell-group>
+          </template>
+        </template>
+
+
+        <van-field label="开始时间" name="startDate" is-link readonly class="resetStyles" placeholder="请选择"
+          @click="showDatePickerBox('startDate')">
+          <template #input v-if="vantFormVal.startDate">
+            {{ vantFormVal.startDate }}
+          </template>
+        </van-field>
+        <van-field label="结束时间" name="endDate" is-link readonly class="resetStyles" placeholder="请选择"
+          @click="showDatePickerBox('endDate')">
+          <template #input v-if="vantFormVal.endDate">
+            {{ vantFormVal.endDate }}
+          </template>
+        </van-field>
+        <div></div>
       </van-form>
       <CustomerForm ref="formFormRef" :formJson="formJson" :formValue="formVal"></CustomerForm>
     </div>
@@ -71,9 +163,14 @@
 
     <!-- 选择器 -->
     <div>
-      <!-- 正常下拉框选择 -->
+      <!-- 下拉框选择 -->
       <van-popup v-model:show="showSelectionFlag" destroy-on-close position="bottom" :style="{ height: '80%' }">
-        <PullDownSelector :options="showSelectionArray" :doYouNeedTranslation="false" @change="selectChange" />
+        <PullDownSelector :options="showSelectionArray" :doYouNeedTranslation="false" @change="selectChange" :multiple-choice="selectMultipleChoice" />
+      </van-popup>
+
+      <!-- 选择日期 -->
+      <van-popup v-model:show="showDatePicker" destroy-on-close position="bottom" :style="{ height: '50%' }">
+        <van-date-picker v-model="showDatePickerVal" @confirm="showPickerConfirm" @cancel="showDatePicker = false" />
       </van-popup>
     </div>
   </div>
@@ -82,12 +179,16 @@
 <script setup>
 import { ref, onActivated, computed } from 'vue';
 import { useLifecycle } from '@hooks/useCommon.js';
-import { fixedFieldTaskType, fixedFieldPriority } from '@utility/defaultData.js';
-import { GET_ALL_CUSTOMERSLIST, GET_ALL_BUSINESS_OPPORTUNITIES, GET_SALES_ORDER_LIST, GET_OBTAIN_ALL_CLUES, GET_CONTACTS_WITH_MORE_I_DS } from "@hooks/useApi";
+import { fixedFieldTaskType, fixedFieldPriority, fixedFieldRepetitiveType } from '@utility/defaultData.js';
+import { GET_ALL_CUSTOMERSLIST, GET_ALL_BUSINESS_OPPORTUNITIES, GET_SALES_ORDER_LIST, GET_OBTAIN_ALL_CLUES, GET_CONTACTS_WITH_MORE_I_DS, TASK_ADD_EDIT } from "@hooks/useApi";
 import requests from "@common/requests";
+import useToast from "@hooks/useToast"
+import dayjs from 'dayjs';
 import PullDownSelector from '@components/common/pullDownSelector.vue'
 import CustomerForm from '@components/common/formForm/formView.vue'
+import TranslationComponent from '@components/common/translationComponent.vue';
 
+const { toastText, toastSuccess, toastFail, toastLoading } = useToast()
 const props = defineProps({
   formJson: { required: true },
   formValue: { required: true },
@@ -96,7 +197,11 @@ const props = defineProps({
 const formFormRef = ref(null)
 const vantFormVal = ref({
   taskType: 0,
-  taskTypeName: '客户'
+  taskTypeName: '客户',
+  endType: '1',
+  repeatEndCount: 0,
+  repeatType: 0,
+  repeatTypeName: '每天'
 })
 const formVal = ref({})
 const allBusinessOpportunities = ref([])
@@ -107,11 +212,25 @@ const allContactsList = ref([])
 const showSelectionFlag = ref(false)
 const showSelectionFiled = ref([])
 const showSelectionArray = ref([])
+const showDatePicker = ref(false)
+const showDatePickerVal = ref(dayjs().format("YYYY-MM-DD").split("-"))
+const showDatePickerFiled = ref('')
+const customeDate = ref([])
+const selectMultipleChoice = ref(false)
 const taskTypeFiled = ['customId', 'businessOpportunityId', 'orderId', 'clueId']
 
 const contactDisabled = computed(() => {
   const taskType = vantFormVal.value?.taskType
-  if(!taskType && taskType != 0) {
+  if (!taskType && taskType != 0) {
+    return true
+  }
+  if(taskType == 0 && !vantFormVal.value.customId) {
+    return true
+  }
+  if(taskType == 1 && !vantFormVal.value.businessOpportunityId) {
+    return true
+  }
+  if(taskType == 2 && !vantFormVal.value.orderId) {
     return true
   }
   return false
@@ -119,18 +238,56 @@ const contactDisabled = computed(() => {
 
 function onSubmit() {
   formFormRef.value.getJsonData().then((res) => {
-    console.log('表单验证成功', res, JSON.stringify(res));
+    const formValue = {
+      ...vantFormVal.value,
+      ...formVal.value,
+      ...res.data,
+      repeatDesignDay: customeDate.value.map(item => item.value).join(','),
+      executorId: vantFormVal.value.executorId,
+      isRepeat: vantFormVal.value.isRepeat ? 1 : 0
+    }
+    console.log('formValue', formValue)
+    toastLoading('保存中')
+    requests.post(TASK_ADD_EDIT, { ...formValue }).then(() => {
+      toastSuccess('保存成功')
+      setTimeout(() => {
+        history.back();
+      }, 2000)
+    }).finally(() => {
+
+    })
   })
 }
 
+function showPickerConfirm({ selectedValues }) {
+  vantFormVal.value[showDatePickerFiled.value] = selectedValues.join('-')
+  showDatePicker.value = false
+}
+
+function showDatePickerBox(filed) {
+  const dateVal = vantFormVal.value[filed] ? vantFormVal.value[filed] : dayjs().format("YYYY-MM-DD")
+  showDatePickerFiled.value = filed
+  showDatePickerVal.value = dateVal.split("-")
+  showDatePicker.value = true
+}
+
 function selectChange(value, label) {
   if (taskTypeFiled.includes(showSelectionFiled.value)) {
     const item = fixedFieldTaskType.find(item => item.value == vantFormVal.value.taskType)
-    console.log(item, value, )
+    console.log(item, value,)
     if (item && item.show) {
       getContactData(showSelectionFiled.value, value)
     }
   }
+  if(showSelectionFiled.value == 'repeatType') {
+    vantFormVal.value = {
+      ...vantFormVal.value,
+      endType: 0,
+      repeatEndCount: 0,
+      repeatEndDate: null
+    }
+    customeDate.value = []
+  }
   vantFormVal.value[showSelectionFiled.value] = value
   vantFormVal.value[`${showSelectionFiled.value}Name`] = label
   showSelectionFlag.value = false
@@ -146,11 +303,37 @@ function showSelectionBox(filed, list = [], event) {
     vantFormVal.value.contactsId = ''
     vantFormVal.value[`contactsIdName`] = ''
   }
+  selectMultipleChoice.value = filed == 'executorId' ? true : false
   showSelectionFiled.value = filed
-  showSelectionArray.value = list
+  showSelectionArray.value = filed == 'executorId' ? [] : list
   showSelectionFlag.value = true
 }
 
+function addCustomeDateItem() {
+  customeDate.value.push({ value: null })
+}
+
+function deleteCustomeDateItem(index) {
+  customeDate.value.splice(index, 1)
+}
+
+function radiogroupChange(val) {
+  switch (val) {
+    case 1:
+      vantFormVal.value.repeatEndDate = ''
+      vantFormVal.value.repeatEndCount = null
+      break;
+    case 2:
+      vantFormVal.value.repeatEndDate = ''
+      break;
+    case 3:
+      vantFormVal.value.repeatEndCount = null
+      break;
+    default:
+      break;
+  }
+}
+
 function getContactData(filed, value) {
   const urlType = {
     'customId': 'customerId',
@@ -165,7 +348,7 @@ function getContactData(filed, value) {
         value: item.id,
       }
     })
-    if(!allContactsList.value.length) {
+    if (!allContactsList.value.length) {
       list = [{}]
     }
     allContactsList.value = list
@@ -207,13 +390,54 @@ function getAllListData() {
   })
 }
 
+function initializeData() {
+  const row = props.formValue
+  if(!row.id) {
+    vantFormVal.value = {
+      taskType: 0,
+      taskTypeName: '客户',
+      endType: '1',
+      repeatEndCount: 0,
+      repeatType: 0,
+      repeatTypeName: '每天'
+    }
+    formVal.value = props.formValue
+    customeDate.value = []
+    return
+  }
+
+  const { id, taskName, priority, taskType, customId, customName, businessOpportunityId, businessOpportunityName, orderId, orderName, clueId, clueNme, contactsId, contactsName
+  , taskExecutors, isRepeat, repeatType, repeatDesignSameday, endType, repeatEndCount, repeatEndDate, repeatDesignDay, executorId, startDate, endDate } = row
+  vantFormVal.value = {
+    id, taskName, priority, taskType, customId, businessOpportunityId, orderId, clueId, contactsId, executorId, repeatType, repeatDesignSameday, endType, repeatEndCount, repeatEndDate, startDate, endDate,
+    isRepeat: isRepeat == 1 ? true : false,
+    executorIdName: taskExecutors || [],
+    contactsIdName: contactsName,
+    clueIdNme: clueNme,
+    orderIdName: orderName,
+    customIdName: customName,
+    businessOpportunityIdName: businessOpportunityName,
+    priorityName: fixedFieldPriority.find(item => item.value == priority)?.label || '',
+    taskTypeName: fixedFieldTaskType.find(item => item.value == taskType)?.label || '',
+    repeatTypenName: fixedFieldRepetitiveType.find(item => item.value == repeatType)?.label || ''
+  }
+
+  const list = repeatDesignDay && repeatDesignDay.split(',') || []
+  customeDate.value = (list || []).map(item => {
+    return {
+      value: item
+    }
+  })
+  formVal.value = props.formValue
+}
+
 useLifecycle({
   load: () => {
-    formVal.value = props.formValue
+    initializeData()
     getAllListData()
   },
   init: () => {
-    formVal.value = props.formValue
+    initializeData()
     getAllListData()
   }
 });
@@ -224,5 +448,17 @@ onActivated(() => {
 </script>
 
 <style lang='scss' scoped>
-/* 样式代码 */
+.selectField {
+  padding: 0;
+  width: 12rem;
+  margin-right: 4px;
+}
+
+.selectField :deep(.van-cell__title) {
+  width: 4rem;
+}
+
+.additionalCoAuthorship {
+  border-bottom: 1px solid #EBEDF0
+}
 </style>

+ 9 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/utility/defaultData.js

@@ -41,4 +41,13 @@ export const fixedFieldStatusArray = [
   { label: "审核通过", value: "0", color: "color:#67c23a;" },
   { label: "待审核", value: "1", color: "color:#e6a23c;" },
   { label: "已驳回", value: "2", color: "color:#f56c6c;" },
+]
+
+// 任务重复类型
+export const fixedFieldRepetitiveType = [
+  { label: "每天", value: 0 },
+  { label: "每周", value: 1 },
+  { label: "每月", value: 2 },
+  { label: "自定义周期", value: 3 },
+  { label: "自定义日期", value: 4 },
 ]

+ 25 - 22
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/VisitPlanController.java

@@ -2,16 +2,16 @@ 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 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;
 import java.util.Date;
-import java.util.concurrent.TimeUnit;
 
 @RestController
 @RequestMapping("/visitPlan")
@@ -132,22 +132,25 @@ public class VisitPlanController {
 
 
 
-
-
-    @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;
-    }
+//    @GetMapping("/getDelayQueue")
+//    public HttpRespMsg getDelayQueue(HttpServletRequest request) {
+//        HttpRespMsg httpRespMsg = new HttpRespMsg();
+//        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+//        Map<String,Object> map = new HashMap<>();
+//        map.put("queue",tool.getAll());
+//        map.put("size",tool.getSize());
+//        httpRespMsg.setData(map);
+//        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;
+//    }
 }

+ 13 - 3
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/VisitPlan.java

@@ -55,9 +55,9 @@ public class VisitPlan extends Model<VisitPlan> {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
     private Date remindTime;
 
-    /**是否达到提醒时间 0未到 1已到 2不需要提醒*/
-    @TableField(value = "remind_state")
-    private Integer remindState;
+    /**是否达到提醒时间 0未到 1已到 2不需要提醒【废弃】*/
+//    @TableField(value = "remind_state")
+//    private Integer remindState;
 
     /**完成状态 0未完成 1已完成*/
     @TableField(value = "finish_state")
@@ -66,4 +66,14 @@ public class VisitPlan extends Model<VisitPlan> {
     /**创建人*/
     @TableField(value = "create_by")
     private String createBy;
+    /**最终提醒时间[计算后]*/
+    @TableField(value = "final_remind_time")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    private Date finalRemindTime;
+    /**
+     * 企业微信用户openuserid
+     */
+    @TableField("corpwx_userid")
+    private String corpwxUserid;
 }

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

@@ -8,6 +8,7 @@ import com.management.platform.entity.vo.VisitPlanDetailVO;
 import com.management.platform.entity.vo.VisitPlanVO;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.Date;
 import java.util.List;
 
 public interface VisitPlanMapper extends BaseMapper<VisitPlan> {
@@ -16,4 +17,6 @@ public interface VisitPlanMapper extends BaseMapper<VisitPlan> {
     List<VisitPlanVO> getListVisitPlan(@Param("query")QueryVisitPlanDTO query);
 
     VisitPlanDetailVO getDetail(@Param("planId") Long planId);
+
+    List<VisitPlan> getMinuteVisitPlans(@Param("queryDate") Date queryDate);
 }

+ 19 - 13
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java

@@ -143,12 +143,12 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
                 return msg;
             }
 
-            if (custom.getContactsName() != null && contactsMapper.selectCount(new QueryWrapper<Contacts>()
-                    .eq("name", custom.getContactsName())
-            ) == 0) {
-                msg.setError("此联系人不存在");
-                return msg;
-            }
+//            if (custom.getContactsName() != null && contactsMapper.selectCount(new QueryWrapper<Contacts>()
+//                    .eq("name", custom.getContactsName())
+//            ) == 0) {
+//                msg.setError("此联系人不存在");
+//                return msg;
+//            }
             custom.setCreateTime(new Date());
             custom.setCreatorId(user.getId());
             custom.setIsDelete(0);
@@ -160,13 +160,19 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
             actionLog.setUserId(user.getId());
             actionLog.setItemId(custom.getId());
             actionLogMapper.insert(actionLog);
-            if (custom.getCustomName() != null && custom.getCustomName() != "" && custom.getTelPhone() != "" && custom.getTelPhone() != null) {
-                Contacts contacts = contactsMapper.selectOne(new QueryWrapper<Contacts>().eq("name", custom.getCustomName()).eq("phone", custom.getTelPhone()));
-                if (contacts != null) {
-                    contacts.setCustomId(custom.getId());
-                    contactsMapper.update(contacts, new UpdateWrapper<Contacts>().eq("id", contacts.getId()));
-                }
-            }
+//            if (custom.getCustomName() != null && custom.getCustomName() != "" && custom.getTelPhone() != "" && custom.getTelPhone() != null) {
+//                Contacts contacts = contactsMapper.selectOne(new QueryWrapper<Contacts>().eq("name", custom.getCustomName()).eq("phone", custom.getTelPhone()));
+//                if (contacts != null) {
+//                    contacts.setCustomId(custom.getId());
+//                    contactsMapper.update(contacts, new UpdateWrapper<Contacts>().eq("id", contacts.getId()));
+//                }else{
+//                    contacts.setCustomId(custom.getId());
+//                    contacts.setCompanyId(user.getCompanyId());
+//                    contacts.setCreatorId(user.getId());
+////                    contacts.setPhone()
+////                    contactsMapper.insert()
+//                }
+//            }
         }
         msg.setMsg("操作成功");
         return msg;

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

@@ -9,17 +9,14 @@ import com.management.platform.entity.vo.VisitPlanDetailVO;
 import com.management.platform.entity.vo.VisitPlanVO;
 import com.management.platform.mapper.*;
 import com.management.platform.service.VisitPlanService;
-import com.management.platform.time.VisitPlanDelayHandler;
-import com.management.platform.time.VisitPlanDelayItem;
+import com.management.platform.util.DateTimeUtil;
 import com.management.platform.util.HttpRespMsg;
 import org.apache.commons.collections.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -29,9 +26,9 @@ import java.util.stream.Collectors;
 public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan> implements VisitPlanService {
 
 
-    @Autowired
-    @Qualifier(value = "VisitPlanThreadPool")
-    ThreadPoolTaskExecutor threadPoolTaskExecutor;
+//    @Autowired
+//    @Qualifier(value = "VisitPlanThreadPool")
+//    ThreadPoolTaskExecutor threadPoolTaskExecutor;
 
 
     @Resource
@@ -82,16 +79,21 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
 
         if(null != visitPlan.getId()){
             //修改
-            Date visitTime = visitPlanMapper.selectById(visitPlan.getId()).getVisitTime();
-            long milliCosts = visitTime.getTime() - now.getTime();
-            if(milliCosts > 30 * 60 * 1000){
+            VisitPlan oldPlan = visitPlanMapper.selectById(visitPlan.getId());
+            if(1 == oldPlan.getFinishState()){
+                httpRespMsg.setError("无法修改已完成的计划");
+                return httpRespMsg;
+            }
+            Date oldVisitTime = oldPlan.getVisitTime();
+            long milliCosts = oldVisitTime.getTime() - now.getTime();
+            if(milliCosts <= 30 * 60 * 1000){
                 httpRespMsg.setError("原拜访时间为近半小时内的数据无法修改");
                 return httpRespMsg;
             }
-            Long delayTime = 0L;
-            Long startTimeMilliSec = 0L;
-            Long endTimeMilliSec = 0L;
-            boolean timeTypeCheck = false;
+//            Long delayTime = 0L;
+//            Long startTimeMilliSec = 0L;
+//            Long endTimeMilliSec = 0L;
+//            boolean timeTypeCheck = false;
             if(-1 == visitPlan.getRemindType()){
                 //重新计算delayTime 自定义时间-当前时间
                 if(visitPlan.getRemindTime().before(now)
@@ -99,46 +101,57 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
                     httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
                     return httpRespMsg;
                 }
-                //毫秒
-                startTimeMilliSec = now.getTime();
-                endTimeMilliSec = visitPlan.getRemindTime().getTime();
-                delayTime = endTimeMilliSec - startTimeMilliSec;
-                timeTypeCheck = true;
+                visitPlan.setFinalRemindTime(visitPlan.getRemindTime());
+//                //毫秒
+//                startTimeMilliSec = now.getTime();
+//                endTimeMilliSec = visitPlan.getRemindTime().getTime();
+//                delayTime = endTimeMilliSec - startTimeMilliSec;
+//                timeTypeCheck = true;
             } else if (timeTypeDict.getName().equals("不提醒")) {
                 //不加入队列,不需要提醒
-                visitPlan.setRemindState(2);
+//                visitPlan.setRemindState(2);
+                visitPlan.setFinalRemindTime(null);
             }else{
-                startTimeMilliSec = now.getTime();
-                endTimeMilliSec = visitPlan.getVisitTime().getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;
-                if(endTimeMilliSec < startTimeMilliSec){
+//                long startTimeMilliSec = now.getTime();
+//                long endTimeMilliSec = visitPlan.getVisitTime().getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;
+//                if(endTimeMilliSec < startTimeMilliSec){
+//                    httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
+//                    return httpRespMsg;
+//                }
+//                delayTime = endTimeMilliSec-startTimeMilliSec;
+//                timeTypeCheck=true;
+                LocalDateTime newVisitTime = DateTimeUtil.cusDateToLocalDateTime(visitPlan.getVisitTime());
+                LocalDateTime newRemindTime = newVisitTime.minusSeconds(Long.parseLong(timeTypeDict.getExt1()));
+                if(newRemindTime.isBefore(LocalDateTime.now())){
                     httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
                     return httpRespMsg;
                 }
-                delayTime = endTimeMilliSec-startTimeMilliSec;
-                timeTypeCheck=true;
+                visitPlan.setFinalRemindTime(DateTimeUtil.cusLocalDateTimeToDate(newRemindTime));
+
             }
 
             visitPlanMapper.updateById(visitPlan);
-            VisitPlan newPlan = visitPlanMapper.selectById(visitPlan.getId());//前端某些字段不传,以防万一
-
-            //从队列中取出,并重新计算时间入队列
-            if(timeTypeCheck){
-                VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
-                tool.removeIfExist(visitPlan.getId());
-                VisitPlanDelayItem item = new VisitPlanDelayItem(delayTime
-                        ,startTimeMilliSec
-                        ,endTimeMilliSec
-                        ,newPlan.getId(),newPlan);
-                tool.addItem(item);
-            }
+//            VisitPlan newPlan = visitPlanMapper.selectById(visitPlan.getId());//前端某些字段不传,以防万一
+//
+//            //从队列中取出,并重新计算时间入队列
+//            if(timeTypeCheck){
+//                VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+//                tool.removeIfExist(visitPlan.getId());
+//                VisitPlanDelayItem item = new VisitPlanDelayItem(delayTime
+//                        ,startTimeMilliSec
+//                        ,endTimeMilliSec
+//                        ,newPlan.getId(),newPlan);
+//                tool.addItem(item);
+//            }
 
         }else{
             //新增
             visitPlan.setCompanyId(user.getCompanyId());
-            Long delayTime = 0L;
-            Long startTimeMilliSec = 0L;
-            Long endTimeMilliSec = 0L;
-            boolean timeTypeCheck = false;
+            visitPlan.setCorpwxUserid(user.getCorpwxUserid());
+//            Long delayTime = 0L;
+//            Long startTimeMilliSec = 0L;
+//            Long endTimeMilliSec = 0L;
+//            boolean timeTypeCheck = false;
             if(-1 == visitPlan.getRemindType()){
                 //重新计算delayTime 自定义时间-当前时间
                 if(visitPlan.getRemindTime().before(now)
@@ -146,23 +159,33 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
                     httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
                     return httpRespMsg;
                 }
-                //毫秒
-                startTimeMilliSec = now.getTime();
-                endTimeMilliSec = visitPlan.getRemindTime().getTime();
-                delayTime = endTimeMilliSec - startTimeMilliSec;
-                timeTypeCheck = true;
+//                //毫秒
+//                startTimeMilliSec = now.getTime();
+//                endTimeMilliSec = visitPlan.getRemindTime().getTime();
+//                delayTime = endTimeMilliSec - startTimeMilliSec;
+//                timeTypeCheck = true;
+                visitPlan.setFinalRemindTime(visitPlan.getRemindTime());
             } else if (timeTypeDict.getName().equals("不提醒")) {
                 //不加入队列,不需要提醒
-                visitPlan.setRemindState(2);
+//                visitPlan.setRemindState(2);
             }else{
-                startTimeMilliSec = now.getTime();
-                endTimeMilliSec = visitPlan.getVisitTime().getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;
-                if(endTimeMilliSec < startTimeMilliSec){
+//                startTimeMilliSec = now.getTime();
+//                endTimeMilliSec = visitPlan.getVisitTime().getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;
+//                if(endTimeMilliSec < startTimeMilliSec){
+//                    httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
+//                    return httpRespMsg;
+//                }
+//                delayTime = endTimeMilliSec-startTimeMilliSec;
+//                timeTypeCheck=true;
+
+                LocalDateTime newVisitTime = DateTimeUtil.cusDateToLocalDateTime(visitPlan.getVisitTime());
+                LocalDateTime newRemindTime = newVisitTime.minusSeconds(Long.parseLong(timeTypeDict.getExt1()));
+                if(newRemindTime.isBefore(LocalDateTime.now())){
                     httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
                     return httpRespMsg;
                 }
-                delayTime = endTimeMilliSec-startTimeMilliSec;
-                timeTypeCheck=true;
+                visitPlan.setFinalRemindTime(DateTimeUtil.cusLocalDateTimeToDate(newRemindTime));
+
             }
 
             Custom custom = customMapper.selectById(visitPlan.getCustomId());
@@ -170,19 +193,19 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
             visitPlan.setCreateBy(user.getId());
             visitPlanMapper.insert(visitPlan);
 
-            //加入执行队列
-            if(timeTypeCheck){
-                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);
-            }
+//            //加入执行队列
+//            if(timeTypeCheck){
+//                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;
     }
@@ -191,12 +214,12 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
     public HttpRespMsg finishVisitPlan(Long planId, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
 
-        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
-        tool.removeIfExist(planId);
+//        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+//        tool.removeIfExist(planId);
 
         //完成计划则修改:1、是否到达提醒时间为不需要提醒 2、完成状态为 已完成
         visitPlanMapper.update(null,new LambdaUpdateWrapper<VisitPlan>()
-                        .set(VisitPlan::getRemindState, 2)
+//                        .set(VisitPlan::getRemindState, 2)
                         .set(VisitPlan::getFinishState,1)
                 .eq(VisitPlan::getId,planId)
         );
@@ -219,6 +242,16 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
             return httpRespMsg;
         }
         VisitPlan taskPlan = visitPlanMapper.selectById(planId);
+        if(1 == taskPlan.getFinishState()){
+            httpRespMsg.setError("无法修改已完成的计划");
+            return httpRespMsg;
+        }
+        Date oldVisitTime = taskPlan.getVisitTime();
+        long milliCosts = oldVisitTime.getTime() - now.getTime();
+        if(milliCosts <= 30 * 60 * 1000){
+            httpRespMsg.setError("原拜访时间为近半小时内的数据无法修改");
+            return httpRespMsg;
+        }
         SysDict timeTypeDict = null;
         if(-1 != taskPlan.getRemindType()){
             timeTypeDict = sysDictMapper.selectOne(new LambdaQueryWrapper<SysDict>()
@@ -228,51 +261,31 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
             );
         }
 
-
-        Long delayTime = 0L;
-        Long startTimeMilliSec = 0L;
-        Long endTimeMilliSec = 0L;
-        boolean timeTypeCheck = false;
         taskPlan.setVisitTime(newVisitTime);
         if(-1 == taskPlan.getRemindType()){
-            //重新计算delayTime 自定义时间-当前时间
             if(taskPlan.getRemindTime().before(now)
                     || taskPlan.getRemindTime().after(newVisitTime)){
                 httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
                 return httpRespMsg;
             }
-            //毫秒
-            startTimeMilliSec = now.getTime();
-            endTimeMilliSec = taskPlan.getRemindTime().getTime();
-            delayTime = endTimeMilliSec - startTimeMilliSec;
-            timeTypeCheck=true;
+            taskPlan.setFinalRemindTime(taskPlan.getRemindTime());
+
         }else if (timeTypeDict.getName().equals("不提醒")){
             //不加入队列,不修改状态,只修改拜访时间
+            taskPlan.setFinalRemindTime(null);
         }else{
-            startTimeMilliSec = now.getTime();
-            endTimeMilliSec = newVisitTime.getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;
-            if(endTimeMilliSec < startTimeMilliSec){
+            LocalDateTime newVisitLocalTime = DateTimeUtil.cusDateToLocalDateTime(taskPlan.getVisitTime());
+            LocalDateTime newRemindTime = newVisitLocalTime.minusSeconds(Long.parseLong(timeTypeDict.getExt1()));
+            if(newRemindTime.isBefore(LocalDateTime.now())){
                 httpRespMsg.setError("提醒时间不能在当前时段之前或拜访时间之后");
                 return httpRespMsg;
             }
-            delayTime = endTimeMilliSec-startTimeMilliSec;
-            timeTypeCheck=true;
-        }
-
-        //删除队列
-        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
-        tool.removeIfExist(planId);
-        //重新添加
-        if(timeTypeCheck){
-            VisitPlanDelayItem item = new VisitPlanDelayItem(delayTime
-                    ,startTimeMilliSec
-                    ,endTimeMilliSec
-                    ,taskPlan.getId(),taskPlan);
-            tool.addItem(item);
+            taskPlan.setFinalRemindTime(DateTimeUtil.cusLocalDateTimeToDate(newRemindTime));
         }
 
         visitPlanMapper.update(null,new LambdaUpdateWrapper<VisitPlan>()
                 .set(VisitPlan::getVisitTime,newVisitTime)
+                        .set(VisitPlan::getFinalRemindTime,taskPlan.getFinalRemindTime())
                 .eq(VisitPlan::getId,planId)
         );
 
@@ -287,9 +300,9 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
             httpRespMsg.setError("用户不存在");
             return httpRespMsg;
         }
-        //删除队列
-        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
-        tool.removeIfExist(planId);
+//        //删除队列
+//        VisitPlanDelayHandler tool = new VisitPlanDelayHandler();
+//        tool.removeIfExist(planId);
 
         //删除数据
         visitPlanMapper.delete(new LambdaQueryWrapper<VisitPlan>()
@@ -324,7 +337,7 @@ public class VisitPlanServiceImpl extends ServiceImpl<VisitPlanMapper, VisitPlan
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         VisitPlanDetailVO detailVO = visitPlanMapper.getDetail(planId);
         List<Contacts> contacts = contactsMapper.selectList(new LambdaQueryWrapper<Contacts>()
-                .eq(Contacts::getCustomId, detailVO.getCustomId()));
+                .eq(Contacts::getCustomId, detailVO.getCustomId()).orderByDesc(Contacts::getCreateTime));
         detailVO.setContacts(contacts);
         httpRespMsg.setData(detailVO);
         return httpRespMsg;

+ 3 - 5
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/TaskThreadPool.java

@@ -1,12 +1,10 @@
 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
+//@Configuration
 public class TaskThreadPool {
 
     private static final int corePoolSize = 3;
@@ -14,7 +12,7 @@ public class TaskThreadPool {
     private static final int keepAliveSeconds = 20;
     private static final int queueCapacity = 10;
 
-    @Bean(value="VisitPlanThreadPool")
+//    @Bean(value="VisitPlanThreadPool")
     public ThreadPoolTaskExecutor VisitPlanThreadPool() {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         executor.setCorePoolSize(corePoolSize);
@@ -26,7 +24,7 @@ public class TaskThreadPool {
         // rejection-policy:当pool已经达到max size的时候,如何处理新任务
         // DiscardOldestPolicy 抛弃队列中等待最久的  新任务插入队列
         // CallerRunsPolicy 线程池满后调用当前线程处理任务 适合当前场景
-        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
         executor.initialize();
         return executor;
     }

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

@@ -1,7 +1,6 @@
 package com.management.platform.time;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.management.platform.entity.User;
 import com.management.platform.entity.VisitPlan;
 import com.management.platform.entity.WxCorpInfo;
@@ -69,16 +68,17 @@ public class VisitPlanDelayHandler implements Runnable{
             }
 //            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             //到达提醒时间,则修改 是否到达提醒时间为 已到
-            visitPlanService.update(new LambdaUpdateWrapper<VisitPlan>()
-                            .set(VisitPlan::getRemindState,1)
-                    .eq(VisitPlan::getId, visitPlan.getId())
-            );
+//            visitPlanService.update(new LambdaUpdateWrapper<VisitPlan>()
+//                            .set(VisitPlan::getRemindState,1)
+//                    .eq(VisitPlan::getId, visitPlan.getId())
+//            );
 //            System.out.println("修改时间: "+format.format(new Date()));
             //发送企微消息通知
             String createById = item.getVisitPlan().getCreateBy();
             User user = userMapper.selectById(createById);
             WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
             if (wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                // getCorpwxUserid  以 | 隔开 可分割开放
                 wxCorpInfoService.sendWXCorpMsg(wxCorpInfo,user.getCorpwxUserid(),"访客计划提醒",null, WxCorpInfoServiceImpl.TEXT_CARD_MSG_VISIT_PLAN);
             }
         } catch (InterruptedException e) {

+ 3 - 4
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanInit.java

@@ -13,7 +13,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.util.Date;
@@ -21,7 +20,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-@Component
+//@Component
 public class VisitPlanInit implements ApplicationRunner {
 
     @Resource
@@ -43,7 +42,7 @@ public class VisitPlanInit implements ApplicationRunner {
         System.out.println("====开始访客计划初始化=====");
         Date now = new Date();
         List<VisitPlan> visitPlans = visitPlanMapper.selectList(new LambdaQueryWrapper<VisitPlan>()
-                .ne(VisitPlan::getRemindState, 2)
+//                .ne(VisitPlan::getRemindState, 2)
                 .eq(VisitPlan::getFinishState, 0)
                 .gt(VisitPlan::getVisitTime, now)
         );
@@ -101,7 +100,7 @@ public class VisitPlanInit implements ApplicationRunner {
 
                         if(timeTypeDict.getName().equals("不提醒")){
                             //不加入队列,不需要提醒
-                            visitPlan.setRemindState(2);
+//                            visitPlan.setRemindState(2);
                         }else{
                             startTimeMilliSec = now.getTime();
                             endTimeMilliSec = visitPlan.getVisitTime().getTime()-Integer.parseInt(timeTypeDict.getExt1()) * 1000L;

+ 70 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/time/VisitPlanTask.java

@@ -0,0 +1,70 @@
+package com.management.platform.time;
+
+import com.management.platform.entity.VisitPlan;
+import com.management.platform.entity.WxCorpInfo;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.mapper.VisitPlanMapper;
+import com.management.platform.mapper.WxCorpInfoMapper;
+import com.management.platform.service.VisitPlanService;
+import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.service.impl.WxCorpInfoServiceImpl;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Component
+@EnableScheduling
+public class VisitPlanTask {
+    @Resource
+    private VisitPlanService visitPlanService;
+
+    @Resource
+    private VisitPlanMapper visitPlanMapper;
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    private WxCorpInfoService wxCorpInfoService;
+    @Resource
+    private UserMapper userMapper ;
+
+    @Scheduled(cron = "0 0/1 * * * *")
+    public void checkRemindMessage() {
+        Date now = new Date();
+        System.out.println("===开始检查该分钟需提醒的访客计划==="+now);
+        List<VisitPlan> visitPlans = visitPlanMapper.getMinuteVisitPlans(now);
+        System.out.println("需提醒计划数量为: "+visitPlans.size());
+        List<WxCorpInfo> wxCorpInfos = wxCorpInfoMapper.selectList(null);
+        Map<Integer, WxCorpInfo> companyWXCorpMap = new HashMap<>();
+        if(CollectionUtils.isNotEmpty(wxCorpInfos)){
+            companyWXCorpMap = wxCorpInfos.stream().collect(Collectors.toMap(WxCorpInfo::getCompanyId,t->t));
+        }
+        if(CollectionUtils.isNotEmpty(visitPlans)){
+            Map<Integer, List<VisitPlan>> companyPlanMap = visitPlans.stream().collect(Collectors.groupingBy(VisitPlan::getCompanyId));
+            for (Map.Entry<Integer, List<VisitPlan>> entry : companyPlanMap.entrySet()) {
+                Integer companyId = entry.getKey();
+                WxCorpInfo wxCorpInfo =companyWXCorpMap.getOrDefault(companyId,null);
+                List<VisitPlan> planList = entry.getValue();
+                List<String> wxIds = planList.stream().filter(t -> StringUtils.isNotBlank(t.getCorpwxUserid())).map(VisitPlan::getCorpwxUserid)
+                        .collect(Collectors.toList());
+                String join = StringUtils.join(wxIds, '|');
+                if (wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1&&StringUtils.isNotBlank(join)){
+                    // getCorpwxUserid  以 | 隔开 可分割开放
+                    wxCorpInfoService.sendWXCorpMsg(wxCorpInfo,join,"访客计划提醒",null, WxCorpInfoServiceImpl.TEXT_CARD_MSG_VISIT_PLAN);
+                }
+
+            }
+        }
+        System.out.println("===检查该分钟需提醒的访客计划结束===");
+    }
+
+
+}

+ 15 - 4
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/util/DateTimeUtil.java

@@ -1,12 +1,8 @@
 package com.management.platform.util;
 
-import org.apache.tomcat.jni.Local;
-
 import java.math.BigDecimal;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
-import java.time.temporal.TemporalAccessor;
-import java.util.Arrays;
 import java.util.Date;
 
 public class DateTimeUtil {
@@ -69,6 +65,21 @@ public class DateTimeUtil {
         return date;
     }
 
+    public static LocalDateTime cusDateToLocalDateTime(Date date) {
+        if(null == date){
+            return null;
+        }
+        return date.toInstant().atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
+    }
+
+    public static Date cusLocalDateTimeToDate(LocalDateTime localDateTime) {
+        if(null == localDateTime){
+            return null;
+        }
+        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
+        return Date.from(zonedDateTime.toInstant());
+    }
+
     public static void main(String[] args) {
         LocalDate localDate = LocalDate.now();
         System.out.println(localDate);

+ 16 - 3
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/VisitPlanMapper.xml

@@ -3,13 +3,18 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.management.platform.mapper.VisitPlanMapper">
 
+    <sql id="baseColumns">
+        id, plan_name, custom_id, custom_name, incharger_id, visit_goal, visit_time, remark, remind_type
+          , remind_time, finish_state, create_by, company_id,final_remind_time,corpwx_userid
+    </sql>
+
     <select id="getPageVisitPlan" resultType="com.management.platform.entity.vo.VisitPlanVO">
         select vs.id, vs.plan_name, vs.custom_id, vs.custom_name
              , vs.incharger_id, u.name as inchargerName
              , vs.visit_goal,sd1.name as visitGoalName
              , vs.visit_time, vs.remark
              , vs.remind_type, case remind_type when -1 then '自定义时间' else sd2.name end as remindTypeName
-             ,vs.remind_time, vs.remind_state, vs.finish_state
+             ,vs.remind_time,  vs.finish_state
              , vs.create_by
         from visit_plan vs
                  left join user u on vs.incharger_id = u.id
@@ -23,7 +28,7 @@
              , vs.visit_goal,sd1.name as visitGoalName
              , vs.visit_time, vs.remark
              , vs.remind_type, case remind_type when -1 then '自定义时间' else sd2.name end as remindTypeName
-             ,vs.remind_time, vs.remind_state, vs.finish_state
+             ,vs.remind_time, vs.finish_state
              , vs.create_by,c.tel_phone
         from visit_plan vs
                  left join user u on vs.incharger_id = u.id
@@ -31,6 +36,7 @@
                  left join (select * from sys_dict where code = 'RemindType') sd2 on vs.remind_type = sd2.id
                  left join custom c on vs.custom_id = c.id
         where vs.create_by = #{query.userId} and date_format(vs.visit_time,'%Y-%m-%d') = #{query.calenderDate}
+        order by vs.visit_time asc
     </select>
     <select id="getDetail" resultType="com.management.platform.entity.vo.VisitPlanDetailVO">
         select vs.id, vs.plan_name, vs.custom_id, vs.custom_name
@@ -38,7 +44,7 @@
              , vs.visit_goal,sd1.name as visitGoalName
              , vs.visit_time, vs.remark
              , vs.remind_type, case remind_type when -1 then '自定义时间' else sd2.name end as remindTypeName
-             ,vs.remind_time, vs.remind_state, vs.finish_state
+             ,vs.remind_time,  vs.finish_state
              , vs.create_by,c.tel_phone
         from visit_plan vs
                  left join user u on vs.incharger_id = u.id
@@ -47,4 +53,11 @@
                  left join custom c on vs.custom_id = c.id
         where vs.id = #{planId}
     </select>
+    <select id="getMinuteVisitPlans" resultType="com.management.platform.entity.VisitPlan">
+        select <include refid="baseColumns"></include>
+        from visit_plan
+        where
+        finish_state != 1
+        and date_format(final_remind_time,'%Y-%m-%d %H:%i')=date_format(#{queryDate},'%Y-%m-%d %H:%i')
+    </select>
 </mapper>