Przeglądaj źródła

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper into master

seyason 3 tygodni temu
rodzic
commit
ddab59e679
57 zmienionych plików z 628 dodań i 223 usunięć
  1. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/dqbb.png
  2. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/dqzh.png
  3. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/grzxbjs.png
  4. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/gsmc.png
  5. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/saomiao.jpg
  6. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/sysm.png
  7. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/frw.png
  8. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/frwz.png
  9. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jcp.png
  10. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jcpz.png
  11. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jdd.png
  12. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jddz.png
  13. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jht.png
  14. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jhtz.png
  15. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjh.png
  16. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjhz.png
  17. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjkh.png
  18. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjkhz.png
  19. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jlxr.png
  20. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jlxrz.png
  21. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jsj.png
  22. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jsjz.png
  23. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jxs.png
  24. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jxsz.png
  25. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/yxrq.png
  26. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/yysc.png
  27. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/scss/iframe.scss
  28. 6 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/components/layout/Page.vue
  29. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/hooks/useTheme.js
  30. 2 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/guide.vue
  31. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/business/addEditor.vue
  32. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/business/businessOpportunityStage.vue
  33. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/order/addEditor.vue
  34. 2 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pdfPreview/pdf.vue
  35. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/dataAnalysis.vue
  36. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/quickEntrance.vue
  37. 7 7
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/salesBriefings.vue
  38. 5 5
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/workbench.vue
  39. 29 14
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/index.vue
  40. 75 19
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index copy.vue
  41. 158 129
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index.vue
  42. 5 5
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/visitor/workbench.vue
  43. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/visitorProgram/visitorDetails.vue
  44. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/utility/defaultData.js
  45. 19 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/utility/generalVariables.js
  46. 132 1
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/TaskController.java
  47. 42 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/demo/BeanDiffUtil.java
  48. 85 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/demo/ListDiffUtil.java
  49. 10 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/vo/ExecutorVo.java
  50. 24 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/vo/TaskAllocateVo.java
  51. 0 22
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  52. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  53. 3 3
      fhKeeper/formulahousekeeper/timesheet/src/views/project/project_gantt.vue
  54. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/vueGantt.vue
  55. 2 1
      fhKeeper/formulahousekeeper/timesheet_mld/src/components/taskComponent.vue
  56. 9 1
      fhKeeper/formulahousekeeper/timesheet_mld/src/views/project/gantt.vue
  57. 1 1
      fhKeeper/formulahousekeeper/timesheet_mld/src/views/project/project_gantt.vue

BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/dqbb.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/dqzh.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/grzxbjs.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/gsmc.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/saomiao.jpg


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/sysm.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/frw.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/frwz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jcp.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jcpz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jdd.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jddz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jht.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jhtz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjh.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjhz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjkh.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jjkhz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jlxr.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jlxrz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jsj.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jsjz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jxs.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/whiteNew/jxsz.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/yxrq.png


BIN
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/yysc.png


+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/scss/iframe.scss

@@ -1,4 +1,4 @@
-$themeColor: #0859d6;
+$themeColor: #4F8DE0;
 
 .text-size-small {
   font-size: 12px;

+ 6 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/components/layout/Page.vue

@@ -126,4 +126,10 @@ const goBack = ()=>{
     background: $themeColor;
   }
 }
+
+.headerNoBack {
+  :deep(.van-nav-bar) {
+    background: none !important;
+  }
+}
 </style>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/hooks/useTheme.js

@@ -1,6 +1,6 @@
 /*主题颜色*/
 const color = {
-    primary: '#0859d6' //主体色
+    primary: '#4F8DE0' //主体色
 };
 
 /*获取vant主题变量配置*/

+ 2 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/guide.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="guide-container">
-    <img src="/src/assets/image/gsgj.jpg" alt="">
+    <!-- <img src="/src/assets/image/gsgj.jpg" alt=""> -->
+    <img src="/src/assets/image/saomiao.jpg" alt="">
     <div class="guide-container-text">请长按图片关注</div>
   </div>
 </template>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/business/addEditor.vue

@@ -12,7 +12,7 @@
           <template #foldingRight>
             <div class="flex items-center">
               <van-button icon="plus" color="#FF8B32" size="mini" class="relatedAddButton" @click="addBusinessItemProductList()">添加</van-button>
-              <van-button icon="plus" color="#0859d6" size="mini" class="relatedAddButton" @click.stop="resetBusinessItemProductList(index)" v-if="businessItemProductList.length == 1">重置</van-button>
+              <van-button icon="plus" color="#4F8DE0" size="mini" class="relatedAddButton" @click.stop="resetBusinessItemProductList(index)" v-if="businessItemProductList.length == 1">重置</van-button>
               <van-button icon="plus" color="#EE0A24" size="mini" class="relatedAddButton" @click.stop="deleteBusinessItemProductList(index)" v-if="businessItemProductList.length > 1">删除</van-button>
             </div>
           </template>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/business/businessOpportunityStage.vue

@@ -209,7 +209,7 @@ useLifecycle({
   color: #858585;
 }
 .haveInHand {
-  background: #0859d6;
+  background: #4F8DE0;
   color: #fff;
 }
 .notStartedYet {

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pageComponents/order/addEditor.vue

@@ -13,7 +13,7 @@
             <div class="flex items-center">
               <van-button icon="plus" color="#FF8B32" size="mini" class="relatedAddButton"
                 @click="addBusinessItemProductList()">添加</van-button>
-              <van-button icon="plus" color="#0859d6" size="mini" class="relatedAddButton"
+              <van-button icon="plus" color="#4F8DE0" size="mini" class="relatedAddButton"
                 @click.stop="resetBusinessItemProductList(index)"
                 v-if="businessItemProductList.length == 1">重置</van-button>
               <van-button icon="plus" color="#EE0A24" size="mini" class="relatedAddButton"

+ 2 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pdfPreview/pdf.vue

@@ -8,7 +8,8 @@
 import { onMounted, ref } from 'vue';
 import * as pdfjsLib from 'pdfjs-dist';
 
-const pdfUrl = 'https://crm.ttkuaiban.com/upload/%E6%99%BA%E8%83%BD%E5%AE%A2%E6%88%B7%E7%AE%A1%E5%AE%B6CRM%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%E4%B9%A6.pdf';
+// const pdfUrl = 'https://crm.ttkuaiban.com/upload/%E6%99%BA%E8%83%BD%E5%AE%A2%E6%88%B7%E7%AE%A1%E5%AE%B6CRM%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%E4%B9%A6.pdf';
+const pdfUrl = 'https://crm.ttkuaiban.com/upload/mobileUserManual.pdf';
 const pdfContainer = ref(null); // PDF容器
 const canvasWrapper = ref(null); // canvas容器
 let currentPage = 1; // 当前显示的页码

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/dataAnalysis.vue

@@ -106,7 +106,7 @@ useLifecycle({
           content: '';
           width: 2px;
           border-radius: 10px;
-          background: #0859d6;
+          background: #4F8DE0;
           height: 18px;
           position: absolute;
           left: 0;

+ 2 - 2
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/quickEntrance.vue

@@ -4,7 +4,7 @@
     <div class="smallFontTitle">快捷新建</div>
     <div class="module">
       <div class="module-item" v-for="(item, index) in selectList" :key="index">
-        <div class="module-img"><img :src="getRouterImg(item.path)" alt=""></div>
+        <div class="module-img"><img :src="getRouterImg(item.path, 'newzPng')" alt=""></div>
         <div class="module-text">建{{ item.name }}</div>
         <div class="absolute top-0 right-0" @click="operationEntrance(index, 'delete')">
           <van-icon name="clear" color="#aaaaaa" size="18" />
@@ -15,7 +15,7 @@
     <div class="flex-1 overflow-y-auto">
       <div class="module">
         <div class="module-item" v-for="(item, index) in allList">
-          <div class="module-img"><img :src="getRouterImg(item.path)" alt=""></div>
+          <div class="module-img"><img :src="getRouterImg(item.path, 'newzPng')" alt=""></div>
           <div class="module-text">建{{ item.name }}</div>
           <div class="absolute top-0 right-0" v-if="selectList.length < 4" @click="operationEntrance(index, 'add')">
             <van-icon name="add" color="#1a6afb" size="18" />

+ 7 - 7
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/salesBriefings.vue

@@ -9,7 +9,7 @@
     </div>
 
     <div class="content overflow-hidden transitionEffect"
-      :style="`height: ${expandAndCollapse ? usePxToVwView(user.company.isSimple == 1 ? 180 : 298) : '0'}`">
+      :style="`height: ${expandAndCollapse ? usePxToVwView(user?.company?.isSimple == 1 ? 180 : 298) : '0'}`">
       <div class="flex items-center w-full" >
         <div class="item">
           <img src="/src/assets/image/salesKitkehu.png" class="item-img" />
@@ -22,7 +22,7 @@
             </div>
           </div>
         </div>
-        <div class="item" v-if="user.company.isSimple != 1">
+        <div class="item" v-if="user?.company?.isSimple != 1">
           <img src="/src/assets/image/salesKitlianxir.png" class="item-img" />
           <div class="flex flex-col justify-center text=[#999999]">
             <div>新增联系人</div>
@@ -34,7 +34,7 @@
           </div>
         </div>
 
-        <div class="item" v-if="user.company.isSimple == 1">
+        <div class="item" v-if="user?.company?.isSimple == 1">
           <img src="/src/assets/image/salesKitlishi.png" class="item-img" />
           <div class="flex flex-col justify-center text=[#999999]">
             <div>新增{{ businessLabel }}</div>
@@ -47,7 +47,7 @@
         </div>
       </div>
 
-      <div class="flex items-center w-full" v-if="user.company.isSimple != 1">
+      <div class="flex items-center w-full" v-if="user?.company?.isSimple != 1">
         <div class="item">
           <img src="/src/assets/image/salesKitlishi.png" class="item-img" />
           <div class="flex flex-col justify-center text=[#999999]">
@@ -73,7 +73,7 @@
       </div>
 
       <div class="flex items-center w-full">
-        <div class="item" v-if="user.company.isSimple != 1">
+        <div class="item" v-if="user?.company?.isSimple != 1">
           <img src="/src/assets/image/salesKitjer.png" class="item-img" />
           <div class="flex flex-col justify-center text=[#999999]">
             <div>销售订单金额</div>
@@ -96,7 +96,7 @@
           </div>
         </div>
 
-        <div class="item" v-if="user.company.isSimple == 1">
+        <div class="item" v-if="user?.company?.isSimple == 1">
           <img src="/src/assets/image/salesKitxianshuo.png" class="item-img" />
           <div class="flex flex-col justify-center text=[#999999]">
             <div>新增线索</div>
@@ -109,7 +109,7 @@
         </div>
       </div>
 
-      <div class="flex items-center w-full" v-if="user.company.isSimple != 1">
+      <div class="flex items-center w-full" v-if="user?.company?.isSimple != 1">
         <div class="item">
           <img src="/src/assets/image/salesKitxianshuo.png" class="item-img" />
           <div class="flex flex-col justify-center text=[#999999]">

+ 5 - 5
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/workbench.vue

@@ -30,7 +30,7 @@
             <van-swipe-cell>
               <!-- 拜访计划 -->
               <template v-if="item.calendarType == 1">
-                <div class="bg-[#0859d6] ra6 p-4 mb-4 text-[#fff]" @click="jumpToVisitorDetails(item)">
+                <div class="bg-[#4F8DE0] ra6 p-4 mb-4 text-[#fff]" @click="jumpToVisitorDetails(item)">
                   <div class="w-full flex items-center justify-between">
                     <div class="text-size-in font-bold text-[#fff]">{{ item.planName }}</div>
                     <div :class="`labelTag ${item.finishState == 0 ? 'toBeCompleted' : 'completed'}`">{{ ['未完成',
@@ -127,7 +127,7 @@
             </div>
           </template>
 
-          <div class="w80 bg-[#0859d6] h-28 rounded-md flex flex-col items-center justify-center"
+          <div class="w80 bg-[#4F8DE0] h-28 rounded-md flex flex-col items-center justify-center"
             @click="showCommonForms = true">
             <div class="formImage">
               <img class="w-full h-full" src="/src/assets/image/more.png">
@@ -561,9 +561,9 @@ onActivated(() => {
 }
 
 .primarys {
-  background: rgba($color: #0859d6, $alpha: .1);
-  border-color: #0859d6;
-  color: #0859d6;
+  background: rgba($color: #4F8DE0, $alpha: .1);
+  border-color: #4F8DE0;
+  color: #4F8DE0;
 }
 
 .dangers {

+ 29 - 14
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <Page styleReset="headerClass">
+  <Page styleReset="headerNoBack">
     <template v-slot:headerLeft>
       <div class="homeheaderleft">
         <img src="/src/assets/image/home_logo.png">
@@ -8,12 +8,13 @@
     </template>
 
     <template v-slot:body>
+      <div class="home-theBack"></div>
       <div class="home-theContent">
         <!-- 固定头部 -->
         <div class="home-theContent-title">
           <div class="item" v-for="(item, index) in addQuickList" :key="index">
             <div class="item-img" @click="jumpAdd(item)">
-              <img :src="getRouterImg(item.path)" alt="">
+              <img :src="getRouterImg(item.path, 'newPng')" alt="">
             </div>
             <div class="item-text">建{{ item.name }}</div>
           </div>
@@ -60,16 +61,16 @@
             </div>
           </div>
         </div>
-
+        
         <!-- 弹出层 -->
-        <van-popup v-model:show="showBottom" position="bottom">
-          <div class="bg-[#eceeef]">
-            <div class="w-full text-center bg-white leading-10" @click="quickListShow = true">快捷新建设置</div>
-            <div class="w-full text-center bg-white leading-10 biankuang" @click="modulesListShow = true">常用功能设置</div>
-            <div class="w-full text-center mt-2 text-[red] bg-white leading-10" @click="showBottom = false">取消</div>
+        <van-popup v-model:show="showBottom" position="bottom" :overlay-style="{ backgroundColor: 'rgba(0, 0, 0, 0.4)' }">
+          <div class="bg-[#f6f6fa]">
+            <div class="w-full text-center bg-white block-div" @click="quickListShow = true">快捷新建设置</div>
+            <div class="w-full text-center bg-white block-div biankuang" @click="modulesListShow = true">常用功能设置</div>
+            <div class="w-full text-center mt-4 text-[red] bg-white block-div" @click="showBottom = false">取消</div>
           </div>
         </van-popup>
-
+        
         <!-- 快捷入口设置 -->
         <van-popup v-model:show="quickListShow" position="bottom" :style="{ height: '100%' }" closeable>
           <QuickEntrance :allModulesList="allModulesList" :selectModule="addQuickList" @save-value="refreshData" />
@@ -107,13 +108,12 @@ import CommonFunctions from './component/commonFunctions.vue'
 const { toastText, toastSuccess, toastFail, toastLoading } = useToast()
 const router = useRouterStore()
 const useInfo = useInfoStore()
-const user = useInfo.userInfo
 
 const showBottom = ref(false)
 const quickListShow = ref(false)
 const modulesListShow = ref(false)
 const topContactsList = ref([])
-const allModulesList = [...useInfo.modularList.filter(item => item.path !== '/biReport'), { id: -1, path: '/visitor', name: '访客计划' }]
+const allModulesList = [...(useInfo?.modularList || []).filter(item => item.path !== '/biReport'), { id: -1, path: '/visitor', name: '访客计划' }]
 const addQuickList = ref([])
 const addCommonlyUsedList = ref([])
 
@@ -144,7 +144,7 @@ function getFrequentlyUsedContacts() {
 }
 
 function jumpAdd(rows) {
-  if(rows.path == '/addEditorVisitor') {
+  if(rows.path == '/visitor') {
     router.navigateTo({
       pathName: 'addEditorVisitor',
       success: () => {}
@@ -190,6 +190,7 @@ function refreshData() {
 }
 
 function obtainEnterpriseWeChatParameters(data = {}) {
+  console.log(data, '<=== data')
   const token = data.id
   // const curUrl = window.location.href.split('home')[0]
   const curUrl = window.location.href
@@ -250,7 +251,7 @@ useLifecycle({
     const currentEnvironment = navigator.userAgent.toLowerCase();
     const isCorpWX = currentEnvironment.indexOf("wxwork") > 0 ? true : false
     if (isCorpWX) {
-      obtainEnterpriseWeChatParameters(userInfo.userInfo)
+      obtainEnterpriseWeChatParameters(useInfo.userInfo)
     }
   }
 });
@@ -268,6 +269,14 @@ useLifecycle({
   background-color: $themeColor;
 }
 
+.home-theBack {
+  width: 100%;
+  height: 147px;
+  background: linear-gradient(to top right, rgba($color: $themeColor, $alpha: 0.8), $themeColor, rgba($color: $themeColor, $alpha: 0.8));
+  position: absolute;
+  top: 0;
+}
+
 .homeheaderleft {
   font-size: 20px;
   font-weight: bold;
@@ -288,9 +297,11 @@ useLifecycle({
   height: 100%;
   flex-direction: column;
 
+
   .home-theContent-title {
     padding: 25px;
-    background-color: $themeColor;
+    // background-color: $themeColor;
+    // background: linear-gradient(to top right, #4985e0, $themeColor, #1965db);
     display: flex;
 
     .item {
@@ -373,4 +384,8 @@ useLifecycle({
 .biankuang {
   border-top: 1px solid #eceeef;
 }
+
+.block-div {
+  padding: 14px 0;
+}
 </style>

+ 75 - 19
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index copy.vue

@@ -1,36 +1,68 @@
 <template>
   <Page title="我的" styleReset="backNone">
     <template v-slot:body>
-      <div class="w-full h-full flex flex-col items-center">
-        <div class="headPortrait">
-          <img src="/src/assets/image/camera.png" class="w-full h-full">
-        </div>
-        <div class="flex-1">
-          <div class="xinming">
-            <TranslationComponent :openId="userInfo.userInfo.name" />
+      <div class="w-full h-full flex flex-col">
+        <div class="px-4 py-6 flex justify-between items-center">
+          <div class="flex items-center">
+            <div class="bg-[#065985] text-[#fff] flex items-center justify-center profilePicture">
+              <TranslationComponent :openId="userInfo.userInfo.name" />
+            </div>
+            <div class="ml-8 profilePicture-text">
+              <TranslationComponent :openId="userInfo.userInfo.name" />
+            </div>
           </div>
-          <div class="flex flex-col justify-center text-[#5D5D5D] leading-6">
-            <div class="text-center">公司: {{ userInfo.userInfo?.company?.companyName }}</div>
-            <div class="text-center">角色: {{ userInfo.userInfo?.roleName }}</div>
-
-            <div class="text-center text-[#0859d6] mt-2" @click="applicationMarket()">应用市场</div>
+        </div>
 
-            <div class="text-center text-[#0859d6] mt-8"
-              v-if="userInfo.userInfo.userNameNeedTranslate != '1' && (isCorpWX || isWX)" @click="bindWeiXin">
-              {{ `绑定${isCorpWX ? '企业' : ''}微信` }}
-              (
+        <!-- 列表 -->
+        <div class="bg-white flex justify-between px-6 py-2 mb-1">
+          <div>当前版本</div>
+          <div class="text-[#999]">{{ ['', '专业版本', '旗舰版本'][userInfo.userInfo?.company?.versionControl] }}</div>
+        </div>
+        <div class="bg-white flex justify-between px-6 py-2 mb-1">
+          <div>公司名称</div>
+          <div class="text-[#999]">{{ userInfo.userInfo?.company?.companyName }}</div>
+        </div>
+        <div class="bg-white flex justify-between px-6 py-2 mb-1">
+          <div>账号角色</div>
+          <div class="text-[#999]">{{ userInfo.userInfo?.roleName }}</div>
+        </div>
+        <div class="bg-white flex justify-between px-6 py-2 mb-1" v-if="userInfo.userInfo.userNameNeedTranslate != '1' && (isCorpWX || isWX)" @click="bindWeiXin">
+          <div>{{ `绑定${isCorpWX ? '企业' : ''}微信` }}</div>
+          <div class="text-[#999]">
+            (
               <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid == null) || (isWX && userInfo.userInfo.wxOpenid == null)">未绑定</span>
               <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid != null) || (isWX && userInfo.userInfo.wxOpenid != null)">已绑定</span>
               )
-            </div>
+          </div>
+        </div>
+        <div class="bg-white flex justify-between px-6 py-2 mb-1">
+          <div>有效日期</div>
+          <div class="text-[#999]">{{ userInfo.userInfo?.company?.expirationDate }}</div>
+        </div>
+        <div class="bg-white flex justify-between px-6 py-2 mb-1" @click="instructions()">
+          <div>使用说明</div>
+          <div class="list-imgs">
+            <img src="/src/assets/image/rightArrow.png">
+          </div>
+        </div>
+        <!-- <div class="bg-white flex justify-between px-6 py-2 mb-1">
+          <div>在线客服</div>
+          <div class="list-imgs">
+            <img src="/src/assets/image/rightArrow.png">
+          </div>
+        </div> -->
+        <div class="bg-white flex justify-between px-6 py-2 mb-1" @click="applicationMarket()">
+          <div>应用市场</div>
+          <div class="list-imgs">
+            <img src="/src/assets/image/rightArrow.png">
           </div>
         </div>
 
-        <div class="w-full mb-40 px-24" v-if="!isCorpWX">
+        <!-- 退出登录 -->
+        <div class="w-full mb-40 px-24 mt-20" v-if="!isCorpWX">
           <van-button type="primary" @click="signOut" class="w-full">退出登录</van-button>
         </div>
       </div>
-      <!-- <van-button type="primary" @click="signOut">退出</van-button> -->
     </template>
 
     <template v-slot:footer>
@@ -51,6 +83,12 @@ const userInfo = useInfoStore()
 const isCorpWX = ref(false)
 const isWX = ref(false)
 
+function instructions() {
+  router.navigateTo({
+    pathName: 'pdfPreview',
+  })
+}
+
 function bindWeiXin() {
   //企业微信
   if (isCorpWX.value && userInfo.userInfo.corpwxUserid != null) {
@@ -141,4 +179,22 @@ useLifecycle({
   margin-bottom: 6px;
   text-align: center;
 }
+
+.profilePicture {
+  width: 60px; 
+  height: 60px;
+  border-radius: 50%;
+  font-size: 16px;
+}
+.profilePicture-text {
+  font-size: 16px;
+  color: #065985;
+  font-weight: bold;
+}
+.profilePicture-img {
+  width: 24px;
+}
+.list-imgs {
+  width: 14px;
+}
 </style>

+ 158 - 129
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index.vue

@@ -1,77 +1,78 @@
 <template>
-  <Page title="我的" styleReset="backNone">
-    <template v-slot:body>
-      <div class="w-full h-full flex flex-col">
-        <div class="px-4 py-6 flex justify-between items-center">
-          <div class="flex items-center">
-            <div class="bg-[#065985] text-[#fff] flex items-center justify-center profilePicture">
-              <TranslationComponent :openId="userInfo.userInfo.name" />
-            </div>
-            <div class="ml-8 profilePicture-text">
-              <TranslationComponent :openId="userInfo.userInfo.name" />
-            </div>
+  <div class="personalCenter">
+    <div class="personalCenter-top flex flex-col">
+      <div class="px-4 flex justify-between items-center avatarSection">
+        <div class="flex items-center">
+          <div
+            class="bg-[#fff] text-[#333] flex items-center justify-center profilePicture"
+          >
+            <TranslationComponent :openId="userInfo.userInfo.name" />
           </div>
-          <div class="profilePicture-img">
-            <!-- <img src="/src/assets/image/rightArrow.png"> -->
+          <div class="ml-8 profilePicture-text">
+            <TranslationComponent :openId="userInfo.userInfo.name" /> <br />
+            <div class="jobIdEtc">工号:{{ userInfo.userInfo.jobNumber }}</div>
           </div>
         </div>
-
-        <!-- 列表 -->
-        <div class="bg-white flex justify-between px-6 py-2 mb-1">
-          <div>当前版本</div>
-          <div class="text-[#999]">{{ ['', '专业版本', '旗舰版本'][userInfo.userInfo?.company?.versionControl] }}</div>
+      </div>
+    </div>
+    <div class="flex-1 overflow-y-auto personalCenter-content">
+      <div class="flex flex-row items-center justify-between">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/dqbb.png" alt="" />
+          <div class="list-tile-text">当前版本</div>
         </div>
-        <div class="bg-white flex justify-between px-6 py-2 mb-1">
-          <div>公司名称</div>
-          <div class="text-[#999]">{{ userInfo.userInfo?.company?.companyName }}</div>
+        <div class="list-text">{{ ['', '专业版本', '旗舰版本'][userInfo.userInfo?.company?.versionControl] }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between" v-if="userInfo.userInfo.userNameNeedTranslate != '1' && (isCorpWX || isWX)" @click="bindWeiXin">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/dqbb.png" alt="" />
+          <div class="list-tile-text">{{ `绑定${isCorpWX ? '企业' : ''}微信` }}</div>
         </div>
-        <div class="bg-white flex justify-between px-6 py-2 mb-1">
-          <div>账号角色</div>
-          <div class="text-[#999]">{{ userInfo.userInfo?.roleName }}</div>
+        <div class="list-text">
+          (
+            <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid == null) || (isWX && userInfo.userInfo.wxOpenid == null)">未绑定</span>
+            <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid != null) || (isWX && userInfo.userInfo.wxOpenid != null)">已绑定</span>
+          )
         </div>
-        <div class="bg-white flex justify-between px-6 py-2 mb-1" v-if="userInfo.userInfo.userNameNeedTranslate != '1' && (isCorpWX || isWX)" @click="bindWeiXin">
-          <div>{{ `绑定${isCorpWX ? '企业' : ''}微信` }}</div>
-          <div class="text-[#999]">
-            (
-              <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid == null) || (isWX && userInfo.userInfo.wxOpenid == null)">未绑定</span>
-              <span v-if="(isCorpWX && userInfo.userInfo.corpwxUserid != null) || (isWX && userInfo.userInfo.wxOpenid != null)">已绑定</span>
-              )
-          </div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/gsmc.png" alt="" />
+          <div class="list-tile-text">公司名称</div>
         </div>
-        <div class="bg-white flex justify-between px-6 py-2 mb-1">
-          <div>有效日期</div>
-          <div class="text-[#999]">{{ userInfo.userInfo?.company?.expirationDate }}</div>
+        <div class="list-text">{{ userInfo.userInfo?.company?.companyName }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/dqzh.png" alt="" />
+          <div class="list-tile-text">账号角色</div>
         </div>
-        <div class="bg-white flex justify-between px-6 py-2 mb-1" @click="instructions()">
-          <div>使用说明</div>
-          <div class="list-imgs">
-            <img src="/src/assets/image/rightArrow.png">
-          </div>
+        <div class="list-text">{{ userInfo.userInfo?.roleName }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/yxrq.png" alt="" />
+          <div class="list-tile-text">有效日期</div>
         </div>
-        <!-- <div class="bg-white flex justify-between px-6 py-2 mb-1">
-          <div>在线客服</div>
-          <div class="list-imgs">
-            <img src="/src/assets/image/rightArrow.png">
-          </div>
-        </div> -->
-        <div class="bg-white flex justify-between px-6 py-2 mb-1" @click="applicationMarket()">
-          <div>应用市场</div>
-          <div class="list-imgs">
-            <img src="/src/assets/image/rightArrow.png">
-          </div>
+        <div class="list-text">{{ userInfo.userInfo?.company?.expirationDate }}</div>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3" @click="instructions()">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/sysm.png" alt="" />
+          <div class="list-tile-text">使用说明</div>
         </div>
-
-        <!-- 退出登录 -->
-        <div class="w-full mb-40 px-24 mt-20" v-if="!isCorpWX">
-          <van-button type="primary" @click="signOut" class="w-full">退出登录</van-button>
+        <img src="../../../assets/image/rightArrow.png" class="list-text-img"></img>
+      </div>
+      <div class="flex flex-row items-center justify-between mt-3" @click="applicationMarket()">
+        <div class="list-tile flex">
+          <img src="../../../assets/image/yysc.png" alt="" />
+          <div class="list-tile-text">应用市场</div>
         </div>
+        <img src="../../../assets/image/rightArrow.png" class="list-text-img"></img>
       </div>
-    </template>
-
-    <template v-slot:footer>
-      <Footer />
-    </template>
-  </Page>
+    </div>
+    <div><Footer /></div>
+  </div>
 </template>
 
 <script setup>
@@ -81,15 +82,17 @@ import useRouterStore from "@store/useRouterStore.js";
 import useInfoStore from "@store/useInfoStore.js";
 import Footer from "@components/page/footer.vue";
 
-const router = useRouterStore()
-const userInfo = useInfoStore()
-const isCorpWX = ref(false)
-const isWX = ref(false)
+const router = useRouterStore();
+const userInfo = useInfoStore();
+const isCorpWX = ref(false);
+const isWX = ref(false);
 
 function instructions() {
-  router.navigateTo({
-    pathName: 'pdfPreview',
-  })
+  // router.navigateTo({
+  //   pathName: "pdfPreview",
+  // });
+  // 新窗口打开链接
+  window.open("https://crm.ttkuaiban.com/upload/mobileUserManual.pdf");
 }
 
 function bindWeiXin() {
@@ -102,97 +105,66 @@ function bindWeiXin() {
     return;
   }
 
-  var appId = "wx1c1d8fc81bc073a8";//智能客户管家公众号
-  var url = "https://mobcrm.ttkuaiban.com/api/wechat/bindWeiXin2?userId=" + userInfo.userInfo.id;//工时管家公众号授权回调页面
+  var appId = "wx1c1d8fc81bc073a8"; //智能客户管家公众号
+  var url =
+    "https://mobcrm.ttkuaiban.com/api/wechat/bindWeiXin2?userId=" +
+    userInfo.userInfo.id; //工时管家公众号授权回调页面
   if (isCorpWX.value) {
     appId = "ww4e237fd6abb635af"; //企业微信第三方的SUIT ID
-    url = "https://crm.ttkuaiban.com/api/wxcorp/bindCorpWeiXin?userId=" + userInfo.userInfo.id;//授权回调页面
+    url =
+      "https://crm.ttkuaiban.com/api/wxcorp/bindCorpWeiXin?userId=" +
+      userInfo.userInfo.id; //授权回调页面
   }
 
-  var weixinUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + encodeURI(url) + "&response_type=code&scope=snsapi_base&state=0#wechat_redirect";
+  var weixinUrl =
+    "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +
+    appId +
+    "&redirect_uri=" +
+    encodeURI(url) +
+    "&response_type=code&scope=snsapi_base&state=0#wechat_redirect";
   window.location.href = weixinUrl;
 }
 
 function signOut() {
   router.redirectTo({
-    pathName: 'login',
+    pathName: "login",
     success: () => {
-      localStorage.clear()
-      sessionStorage.clear()
+      localStorage.clear();
+      sessionStorage.clear();
       window.location.reload();
-    }
-  })
+    },
+  });
 }
 
 function judgingTheEnvironment() {
   const currentEnvironment = navigator.userAgent.toLowerCase();
-  isCorpWX.value = currentEnvironment.indexOf("wxwork") > 0 ? true : false
-  isWX.value = currentEnvironment.indexOf("micromessenger") > 0 ? true : false
+  isCorpWX.value = currentEnvironment.indexOf("wxwork") > 0 ? true : false;
+  isWX.value = currentEnvironment.indexOf("micromessenger") > 0 ? true : false;
 }
 
 const applicationMarket = () => {
-  window.location.href = 'https://www.ttkuaiban.com/appMarket.html'
-  // window.open('https://www.ttkuaiban.com/appMarket.html', '_blank'); 
-}
+  window.location.href = "https://www.ttkuaiban.com/appMarket.html";
+  // window.open('https://www.ttkuaiban.com/appMarket.html', '_blank');
+};
 
 useLifecycle({
   load: () => {
-    judgingTheEnvironment()
-  }
+    judgingTheEnvironment();
+  },
 });
 </script>
 
 <style lang="scss" scoped>
-.backNone {
-  background: linear-gradient(to bottom, #E0EFFF, #F8F8F8 30%) !important;
-
-  :deep(.van-nav-bar) {
-    background: none;
-  }
-}
-
-.headPortrait {
-  width: 80px;
-  height: 80px;
-  border-radius: 50%;
-  position: relative;
-  margin-top: 20px;
-  margin-bottom: 10px;
-
-  &::after {
-    content: "";
-    width: 24px;
-    height: 24px;
-    background-image: url('@/assets/image/camera.png');
-    background-size: cover;
-    position: absolute;
-    bottom: 0;
-    right: 0;
-  }
-}
-
-.xinming {
-  color: #000000;
-  font-family: PingFang SC;
-  font-weight: semibold;
-  font-size: 18px;
-  line-height: normal;
-  letter-spacing: 0px;
-  text-align: left;
-  margin-bottom: 6px;
-  text-align: center;
-}
-
 .profilePicture {
-  width: 60px; 
-  height: 60px;
+  width: 70px;
+  height: 70px;
   border-radius: 50%;
   font-size: 16px;
+  font-weight: bold;
 }
 .profilePicture-text {
-  font-size: 16px;
-  color: #065985;
-  font-weight: bold;
+  font-size: 18px;
+  color: #fff;
 }
 .profilePicture-img {
   width: 24px;
@@ -200,4 +172,61 @@ useLifecycle({
 .list-imgs {
   width: 14px;
 }
+.personalCenter {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background-color: #fff;
+}
+.personalCenter-top {
+  width: 100%;
+  height: 180px;
+  background-image: url("../../../assets/image/grzxbjs.png");
+  background-size: cover;
+}
+.avatarSection {
+  padding: 52px 30px 0 30px;
+}
+.jobIdEtc {
+  font-size: 13px;
+  color: #92bdee;
+  margin-top: 4px;
+}
+.personalCenter-content {
+  width: 100%;
+  border-top-left-radius: 15px;
+  border-top-right-radius: 15px;
+  background-color: #fff;
+  position: relative;
+  padding: 20px 26px 0 26px;
+  top: -18px;
+}
+.list-text {
+  color: #A6A6A6;
+  font-weight: medium;
+  font-size: 12px;
+  line-height: normal;
+  position: relative;
+  top: -3px;
+}
+.list-tile {
+  color: #000000;
+  font-weight: medium;
+  font-size: 12px;
+  line-height: normal;
+}
+.list-tile img {
+  width: 28px;
+}
+.list-tile-text{
+  position: relative;
+  top: 2px;
+  margin-left: 10px;
+}
+.list-text-img {
+  width: 16px;
+  position: relative;
+  top: -3px;
+}
 </style>

+ 5 - 5
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/visitor/workbench.vue

@@ -30,7 +30,7 @@
             <van-swipe-cell>
               <!-- 拜访计划 -->
               <template v-if="item.calendarType == 1">
-                <div class="bg-[#0859d6] ra6 p-4 mb-4 text-[#fff]" @click="jumpToVisitorDetails(item)">
+                <div class="bg-[#4F8DE0] ra6 p-4 mb-4 text-[#fff]" @click="jumpToVisitorDetails(item)">
                   <div class="w-full flex items-center justify-between">
                     <div class="text-size-in font-bold text-[#fff]">{{ item.planName }}</div>
                     <div :class="`labelTag ${item.finishState == 0 ? 'toBeCompleted' : 'completed'}`">{{ ['未完成',
@@ -128,7 +128,7 @@
             </div>
           </template>
 
-          <div class="w80 bg-[#0859d6] h-28 rounded-md flex flex-col items-center justify-center"
+          <div class="w80 bg-[#4F8DE0] h-28 rounded-md flex flex-col items-center justify-center"
             @click="showCommonForms = true">
             <div class="formImage">
               <img class="w-full h-full" src="/src/assets/image/more.png">
@@ -562,9 +562,9 @@ onActivated(() => {
 }
 
 .primarys {
-  background: rgba($color: #0859d6, $alpha: .1);
-  border-color: #0859d6;
-  color: #0859d6;
+  background: rgba($color: #4F8DE0, $alpha: .1);
+  border-color: #4F8DE0;
+  color: #4F8DE0;
 }
 
 .dangers {

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/visitorProgram/visitorDetails.vue

@@ -49,7 +49,7 @@
                 <div class="bg-[#F8F8FA] flex justify-between items-center px-6 py-4 mb-3 rounded">
                   <div class="w-3/12">{{ item.name }}</div>
                   <div class="flex-1">{{ item.phone }}</div>
-                  <van-icon name="phone" color="#0859d6" size="1.4rem" />
+                  <van-icon name="phone" color="#4F8DE0" size="1.4rem" />
                 </div>
               </a>
             </template>

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

@@ -33,7 +33,7 @@ export const fixedFieldTaskType = [
 //任务状态
 export const fixedFieldTaskStatus = [
   { label: "未开始", value: "0", type: "info", color: '#B9B9B9' },
-  { label: "进行中", value: "1", type: "primary", color: '#0859d6' },
+  { label: "进行中", value: "1", type: "primary", color: '#4F8DE0' },
   { label: "已完成", value: "2", type: "success", color: '#07C160' },
   { label: "已超时", value: "3", type: "danger", color: '#EE0A24' },
 ];

Plik diff jest za duży
+ 19 - 1
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/utility/generalVariables.js


+ 132 - 1
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/TaskController.java

@@ -6,9 +6,13 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.constant.Constant;
+import com.management.platform.demo.BeanDiffUtil;
+import com.management.platform.demo.ListDiffUtil;
 import com.management.platform.entity.*;
 import com.management.platform.entity.bo.QueryTaskChargePage;
+import com.management.platform.entity.vo.ExecutorVo;
 import com.management.platform.entity.vo.SysRichFunction;
+import com.management.platform.entity.vo.TaskAllocateVo;
 import com.management.platform.entity.vo.UserVO;
 import com.management.platform.mapper.*;
 import com.management.platform.service.*;
@@ -21,6 +25,7 @@ import net.sourceforge.tess4j.ITessAPI;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.poi.hssf.usermodel.*;
 import org.assertj.core.util.Lists;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.transaction.annotation.Transactional;
@@ -204,6 +209,11 @@ public class TaskController {
         int isInsert=0;
         boolean shouldResetAuditStatus = false;
         boolean shouldUpdatetaskDailyAllocate = false;
+        ArrayList<ExecutorVo> newExecutorVos = new ArrayList<>();
+        ArrayList<ExecutorVo> oldExecutorVos = new ArrayList<>();
+        ArrayList<TaskAllocateVo> newTaskAllocateVos = new ArrayList<>();
+        ArrayList<TaskAllocateVo> oldTaskAllocateVos = new ArrayList<>();
+        Integer initTaskStatus=null;//修改任务的时候,任务的初始状态
         List<TaskType> typeList = taskTypeMapper.selectList(new QueryWrapper<TaskType>().eq("company_id", user.getCompanyId()));
         TaskType taskType = typeList.stream().filter(t->t.getId()==task.getTaskPlanType()).findAny().orElse(null);
         if (taskType == null){
@@ -236,6 +246,8 @@ public class TaskController {
             } else {
                 task.setTaskStatus(STATUS_FIRST_CHECK);
             }
+        }else {
+            initTaskStatus=task.getTaskStatus();
         }
         ArrayList<TaskDailyAllocate> allocateArrayList = new ArrayList<>();
         if (!StringUtils.isEmpty(executorListStr)) {
@@ -379,6 +391,9 @@ public class TaskController {
         List<String> msgRecepientList = new ArrayList<>();
         List<Task> needReOrderList = new ArrayList<>();
         StringBuilder taskCommentString=new StringBuilder();
+        StringJoiner joiner=new StringJoiner(",");//任务字段变化的记录
+        StringJoiner joinerExecutor=new StringJoiner(",");//执行人字段变化的记录
+        StringJoiner joinerAllocate=new StringJoiner(",");//分配时间字段变化的记录
         //新建的任务需要计算排序
         if (task.getId() == null) {
             isNew = true;
@@ -406,8 +421,50 @@ public class TaskController {
             if (task.getTaskType()!=null&&task.getTaskType() == 1) {
                 needRecalculateProgress = true;
             }
-        } else {
+        }
+        else {
             Task oldTask = taskService.getById(task.getId());
+            List<BeanDiffUtil.FieldDifference> changes = new BeanDiffUtil<Task>(oldTask, task)
+                    .compare("任务类型", Task::getTaskPlanType)
+                    .compare("所属项目", Task::getProjectId)
+                    .compare("研究中心", Task::getCenterId)
+                    .compare("所属任务分组", Task::getGroupId)
+                    .compare("所属任务列表", Task::getStagesId)
+                    .compare("前置任务", Task::getAheadTid)
+                    .compare("计划内容", Task::getName)
+                    .compare("开始时间", Task::getStartDate)
+                    .compare("截止时间", Task::getEndDate)
+                    .compare("优先级", Task::getTaskLevel)
+                    .compare("详细描述", Task::getTaskDesc)
+                    .getDifferences();
+
+            for (BeanDiffUtil.FieldDifference fieldDifference : changes) {
+                joiner.add(fieldDifference.getFieldName());
+            }
+            if (joiner.length() > 0) {
+                joiner.add("发生了变化");
+            }
+            List<TaskExecutor> executorList = JSONArray.parseArray(executorListStr, TaskExecutor.class);
+            for (TaskExecutor executor : executorList) {
+                ExecutorVo executorVo = new ExecutorVo();
+                BeanUtils.copyProperties(executor, executorVo);
+                newExecutorVos.add(executorVo);
+            }
+
+            for (TaskDailyAllocate dailyAllocate : allocateArrayList) {
+                TaskAllocateVo taskAllocateVo = new TaskAllocateVo();
+                BeanUtils.copyProperties(dailyAllocate, taskAllocateVo);
+                newTaskAllocateVos.add(taskAllocateVo);
+            }
+
+            List<TaskDailyAllocate> allocateList = taskDailyAllocateService.list(new QueryWrapper<TaskDailyAllocate>().eq("task_id", task.getId()));
+            for (TaskDailyAllocate dailyAllocate : allocateList) {
+                TaskAllocateVo taskAllocateVo = new TaskAllocateVo();
+                BeanUtils.copyProperties(dailyAllocate, taskAllocateVo);
+                oldTaskAllocateVos.add(taskAllocateVo);
+            }
+
+
             if (taskType.getNeedAudit()) {
                 if (oldTask.getTaskStatus() == STATUS_CANCEL || oldTask.getTaskStatus() == STATUS_FIRST_REJECT || oldTask.getTaskStatus() == STATUS_SECOND_REJECT) {
                     //重新提交
@@ -422,6 +479,53 @@ public class TaskController {
                 taskService.update(sample, new QueryWrapper<Task>().eq("parent_tid", task.getId()));
             }
             List<TaskExecutor> oldExeList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().eq("task_id", task.getId()));
+            for (TaskExecutor oldExe : oldExeList) {
+                ExecutorVo executorVo = new ExecutorVo();
+                BeanUtils.copyProperties(oldExe, executorVo);
+                oldExecutorVos.add(executorVo);
+            }
+
+            //对比比较执行人是否发生变化
+            if (newExecutorVos.stream().anyMatch(t -> t.getId() == null)) {
+                joinerExecutor.add("执行人发生变化");
+            } else{
+                // 进行比较
+                ListDiffUtil.ListComparisonResult<ExecutorVo> result = ListDiffUtil.compareLists(
+                        oldExecutorVos,
+                        newExecutorVos,
+                        ExecutorVo::getId,
+                        Arrays.asList(
+                                ExecutorVo::getExecutorId,
+                                ExecutorVo::getPlanHours
+                        )
+                );
+                if (!result.getAdded().isEmpty() || !result.getChanged().isEmpty() || !result.getRemoved().isEmpty()) {
+                    joinerExecutor.add("执行人发生变化");
+                }
+            }
+
+            if (newTaskAllocateVos.stream().anyMatch(t -> t.getId() == null)) {
+                joinerAllocate.add("每日分配工时发生变化");
+            }else {
+                // 进行比较
+                ListDiffUtil.ListComparisonResult<TaskAllocateVo> allocateResult = ListDiffUtil.compareLists(
+                        oldTaskAllocateVos,
+                        newTaskAllocateVos,
+                        TaskAllocateVo::getId,
+                        Arrays.asList(
+                                TaskAllocateVo::getUserId,
+                                TaskAllocateVo::getStartTime,
+                                TaskAllocateVo::getEndTime,
+                                TaskAllocateVo::getAllocateDate,
+                                TaskAllocateVo::getWorkHour,
+                                TaskAllocateVo::getOverWorkHour
+                        )
+                );
+                if (!allocateResult.getAdded().isEmpty() || !allocateResult.getChanged().isEmpty() || !allocateResult.getRemoved().isEmpty()) {
+                    joinerAllocate.add("分配每日工时发生变化");
+                }
+            }
+
             CompanyDingding dingding = companyDingdingService.getOne(new LambdaQueryWrapper<CompanyDingding>().eq(CompanyDingding::getCompanyId, user.getCompanyId()));
             //计算需要移除的执行人
             List<Integer> ids = oldExeList.stream().filter(old->!task.getExecutorList().stream().anyMatch(newT->newT.getId()!=null&&newT.getId().equals(old.getId())))
@@ -578,6 +682,33 @@ public class TaskController {
                 taskDailyAllocateService.saveBatch(allocateArrayList);
             }
         } else if (saved&&shouldUpdatetaskDailyAllocate) {
+            if (initTaskStatus==3||initTaskStatus==4){
+                StringJoiner stringJoiner = new StringJoiner(",");
+                if (joiner.length()>0){
+//                    log.info("任务变化内容:"+joiner.toString());
+                    stringJoiner.add(joiner.toString());
+                }
+                if (joinerExecutor.length()>0){
+//                    log.info("执行人变化:"+joinerExecutor.toString());
+                    stringJoiner.add(joinerExecutor.toString());
+                }
+                if (joinerAllocate.length()>0){
+//                    log.info("分配每日工时变化:"+joinerAllocate.toString());
+                    stringJoiner.add(joinerAllocate.toString());
+                }
+                if (stringJoiner.length()>0){
+                    log.info("stringJoiner==>"+stringJoiner.toString());
+                    String msg1="计划:"+task.getName()+",审核人有以下改动:";
+                    Information information = new Information();
+                    information.setType(11);
+                    information.setMsg(msg1+stringJoiner.toString());
+                    information.setJumpType(2);
+                    information.setTaskId(task.getId());
+                    information.setUserId(task.getCreaterId());
+                    information.setTime(LocalDateTime.now());
+                    informationService.save(information);
+                }
+            }
             if (!allocateArrayList.isEmpty()) {
                 taskDailyAllocateService.remove(new QueryWrapper<TaskDailyAllocate>().eq("task_id",task.getId()));
                 taskDailyAllocateService.saveBatch(allocateArrayList);

+ 42 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/demo/BeanDiffUtil.java

@@ -0,0 +1,42 @@
+package com.management.platform.demo;
+
+
+import lombok.Data;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+public class BeanDiffUtil<T> {
+    
+    private final List<FieldDifference> differences = new ArrayList<>();
+    private final T oldObj;
+    private final T newObj;
+
+    public BeanDiffUtil(T oldObj, T newObj) {
+        this.oldObj = oldObj;
+        this.newObj = newObj;
+    }
+
+    public BeanDiffUtil<T> compare(String fieldName, Function<T, ?> extractor) {
+        Object oldValue = extractor.apply(oldObj);
+        Object newValue = extractor.apply(newObj);
+        
+        if (!Objects.equals(oldValue, newValue)) {
+            differences.add(new FieldDifference(fieldName, oldValue, newValue));
+        }
+        return this;
+    }
+
+    public List<FieldDifference> getDifferences() {
+        return differences;
+    }
+
+    @Data
+    public static class FieldDifference {
+        private final String fieldName;
+        private final Object oldValue;
+        private final Object newValue;
+
+    }
+}

+ 85 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/demo/ListDiffUtil.java

@@ -0,0 +1,85 @@
+package com.management.platform.demo;
+
+import lombok.Data;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class ListDiffUtil<T> {
+
+    @Data
+    public static class ListComparisonResult<T> {
+        private final List<T> added;
+        private final List<T> removed;
+        private final List<ElementChange<T>> changed;
+        
+
+    }
+
+    @Data
+    public static class ElementChange<T> {
+        private final T oldElement;
+        private final T newElement;
+        private final List<BeanDiffUtil.FieldDifference> fieldDifferences;
+        
+
+    }
+
+    public static <T> ListComparisonResult<T> compareLists(
+        List<T> oldList, 
+        List<T> newList,
+        Function<T, Object> identityExtractor,
+        List<Function<T, ?>> fieldExtractors) {
+        
+        // 1. 识别新增和删除的元素
+        Map<Object, T> oldMap = oldList.stream()
+            .collect(Collectors.toMap(identityExtractor, e -> e));
+        
+        Map<Object, T> newMap = newList.stream()
+            .collect(Collectors.toMap(identityExtractor, e -> e));
+        
+        List<T> added = newList.stream()
+            .filter(e -> !oldMap.containsKey(identityExtractor.apply(e)))
+            .collect(Collectors.toList());
+        
+        List<T> removed = oldList.stream()
+            .filter(e -> !newMap.containsKey(identityExtractor.apply(e)))
+            .collect(Collectors.toList());
+        
+        // 2. 识别修改的元素
+        List<ElementChange<T>> changed = new ArrayList<>();
+        
+        newList.forEach(newElement -> {
+            Object id = identityExtractor.apply(newElement);
+            if (oldMap.containsKey(id)) {
+                T oldElement = oldMap.get(id);
+                List<BeanDiffUtil.FieldDifference> diffs = compareElements(oldElement, newElement, fieldExtractors);
+                if (!diffs.isEmpty()) {
+                    changed.add(new ElementChange<>(oldElement, newElement, diffs));
+                }
+            }
+        });
+        
+        return new ListComparisonResult<>(added, removed, changed);
+    }
+    
+    private static <T> List<BeanDiffUtil.FieldDifference> compareElements(
+        T oldElement, 
+        T newElement,
+        List<Function<T, ?>> fieldExtractors) {
+        
+        return fieldExtractors.stream()
+            .map(extractor -> {
+                Object oldValue = extractor.apply(oldElement);
+                Object newValue = extractor.apply(newElement);
+                return new BeanDiffUtil.FieldDifference(
+                    extractor.toString(), // 可以用更好的方式获取字段名
+                    oldValue,
+                    newValue
+                );
+            })
+            .filter(diff -> !Objects.equals(diff.getOldValue(), diff.getNewValue()))
+            .collect(Collectors.toList());
+    }
+}

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/vo/ExecutorVo.java

@@ -0,0 +1,10 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+@Data
+public class ExecutorVo {
+    private Integer id;
+    private String executorId;
+    private String planHours;
+}

+ 24 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/vo/TaskAllocateVo.java

@@ -0,0 +1,24 @@
+package com.management.platform.entity.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+@Data
+public class TaskAllocateVo {
+
+    private Integer id;
+    private Integer taskId;
+    private String userId;
+    private LocalTime startTime;
+    private LocalTime endTime;
+    private LocalDate allocateDate;
+    private Double workHour;
+    private Double overWorkHour;
+}

+ 0 - 22
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java

@@ -1816,28 +1816,6 @@ public class DingDingServiceImpl implements DingDingService {
         }
     }
 
-    //通过unionid获取个人手机号
-    private void getUserMobile() throws Exception {
-        com.aliyun.dingtalkcontact_1_0.Client client = createClient();
-        GetUserHeaders getUserHeaders = new GetUserHeaders();
-        getUserHeaders.xAcsDingtalkAccessToken = "<your access token>";
-        try {
-            client.getUserWithOptions("z21HjQliSzpw0Yxxxx", getUserHeaders, new RuntimeOptions());
-        } catch (TeaException err) {
-            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
-                // err 中含有 code 和 message 属性,可帮助开发定位问题
-                bizLogger.error(err.code+":"+err.message);
-            }
-        } catch (Exception _err) {
-            TeaException err = new TeaException(_err.getMessage(), _err);
-            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
-                // err 中含有 code 和 message 属性,可帮助开发定位问题
-                bizLogger.error(err.code+":"+err.message);
-            }
-        }
-    }
-
-
     //将部门id转换为部门层级
     private String convertDepartmentIdToCascade(Integer id) {
         StringBuilder cascade = new StringBuilder();

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -113,7 +113,7 @@
                     <!-- <router-link to="/projectGantt"> -->
                         <el-link type="primary" :underline="false" @click="isganttshow = true">{{ $t('resourceallocation') }}</el-link>
                     <!-- </router-link> -->
-                    <el-dialog v-if="isganttshow" :visible.sync="isganttshow" width="90vw" top="3vh" style="height:96%" class="ganttdialog">
+                    <el-dialog v-if="isganttshow" :visible.sync="isganttshow" fullscreen width="100%" style="height:100%" class="ganttdialog">
                         <projectgantt ref="projectganttRef"></projectgantt>
                     </el-dialog>
                 </el-form-item>

+ 3 - 3
fhKeeper/formulahousekeeper/timesheet/src/views/project/project_gantt.vue

@@ -8,7 +8,7 @@
             <el-radio-button :label="$t('an-xiang-mu-cha-kan')" value="xiangmu"></el-radio-button>
             <el-radio-button :label="$t('zi-yuan-xu-qiu')" value="demand"></el-radio-button>
           </el-radio-group>
-          <el-checkbox v-if="radio1 != $t('zi-yuan-xu-qiu') && user.companyId == 876" v-model="justWaitForMe" style="margin-left: 14px;" @change="selChange()">待我审核</el-checkbox>
+          <!-- <el-checkbox v-if="radio1 != $t('zi-yuan-xu-qiu') && user.companyId == 876" v-model="justWaitForMe" style="margin-left: 14px;" @change="selChange()">待我审核</el-checkbox> -->
         </div>
       </div>
       <!-- 时间段筛选  -->
@@ -85,7 +85,7 @@
     :key="updatakey1" :tasks="tasks"></vueGantt>
 
   <div class="demand-container" v-if="!isDataLoaded">
-    <el-table height="55vh" :loading="demandListLoading" :data="demandList">
+    <el-table height="75vh" :loading="demandListLoading" :data="demandList">
       <el-table-column :label="user.companyId == '7030' ? '项目令号' : $t('Itemno')" prop="projectCode" width="160"></el-table-column>
       <el-table-column :label="$t('headerTop.projectName')" prop="projectName" min-width="240"></el-table-column>
       <el-table-column :label="$t('jin-qi-ri-huo-yue-ren-yuan')" prop="activeUsers" min-width="240">
@@ -650,7 +650,7 @@ export default {
   .left-container {
     overflow: hidden;
     position: relative;
-    height: 60vh;
+    height: 80vh;
   }
   .demand-container{
     overflow: hidden;

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/vueGantt.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-     <el-table :data="treeDataList" height="490px" row-key="id" :key="'1'" show-overflow-tooltip :cell-style="TableCellStyle" size="mini" :span-method="arraySpanMethod" style="width: 100%;margin-bottom: 20px;" border default-expand-all :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
+     <el-table :data="treeDataList" height="80vh" row-key="id" :key="'1'" show-overflow-tooltip :cell-style="TableCellStyle" size="mini" :span-method="arraySpanMethod" style="width: 100%;margin-bottom: 20px;" border default-expand-all :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
         <el-table-column prop="text" :label="$t('lable.name')" width="240" fixed="left" v-if="stafforpro != $t('an-xiang-mu-cha-kan')">
           <template slot-scope="scope">
               <!-- user.userNameNeedTranslate == 1 -->

+ 2 - 1
fhKeeper/formulahousekeeper/timesheet_mld/src/components/taskComponent.vue

@@ -2009,8 +2009,9 @@ export default {
                 for(let userIndex in this.addForm.executorListFront) {
                     const executeList = this.addForm.executorListFront[userIndex].dailyAllocateList
                     const list = executeList.map(item => {
-                        const { startTime, endTime, workHour, overWorkHour, allocateDate } = item
+                        const { startTime, endTime, workHour, overWorkHour, allocateDate, id } = item
                         return {
+                            id: id || '',
                             startTime, endTime, workHour, overWorkHour, allocateDate,
                             taskId: this.addForm.id,
                             userId: this.addForm.executorListFront[userIndex].executorId

+ 9 - 1
fhKeeper/formulahousekeeper/timesheet_mld/src/views/project/gantt.vue

@@ -18,11 +18,12 @@
       :style="`top:${tooltip.y}px;left:${tooltip.x}px;`" 
       class="custom-tooltip-customize"
     >
+      <div><b>类&#8195;&ensp;&nbsp;型:</b> {{ tooltip.task.taskPlanTypeName }}</div>
       <div><b>开始时间:</b> {{ tooltip.task.start_date }}</div>
       <div><b>结束时间:</b> {{ tooltip.task.end_date }}</div>
       <div><b>计划工时:</b> {{ tooltip.task.time }} 小时 ({{ tooltip.task.dayDifference }} 天 )</div>
       <div><b>项目名称:</b> {{ tooltip.task.projectName }}</div>
-      <div><b>计划名称:</b> {{ tooltip.task.planName }}</div>
+      <div><b>任务内容:</b> {{ tooltip.task.planName }}</div>
     </div>
   </div>
 </template>
@@ -46,6 +47,12 @@ export default {
     },
     stafforpro: '',
     valueDate: [],
+    typeList: {
+      type: Array,
+      default() {
+        return []
+      }
+    }
   },
   data() {
     return {
@@ -248,6 +255,7 @@ export default {
             projectName: list[0],
             planName: list[1],
             dayDifference:  d2.diff(d1, 'day'),
+            taskPlanTypeName: this.typeList.find(type => type.id == task.taskPlanType).name
           };
           this.tooltip.x = rect.left + window.scrollX;
           this.tooltip.y = (rect.top - 180) - 10 + window.scrollY;

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet_mld/src/views/project/project_gantt.vue

@@ -221,7 +221,7 @@
           </template>
         </div>
       </div>
-      <gantt ref="ganttTable1" class="left-container" :tasks="tasks" :stafforpro="radio1":valueDate="valueDate":key="updatakey1" @closeBounced="closeBounced":style="`height: 88vh`"
+      <gantt ref="ganttTable1" class="left-container" :tasks="tasks" :stafforpro="radio1":valueDate="valueDate":key="updatakey1" :typeList="typeList" @closeBounced="closeBounced":style="`height: 88vh`"
       ></gantt>
     </div>