فهرست منبع

Merge remote-tracking branch 'origin/master'

yusm 1 هفته پیش
والد
کامیت
dee7682dc0
22فایلهای تغییر یافته به همراه418 افزوده شده و 121 حذف شده
  1. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/package.json
  2. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/businessNew.png
  3. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/contactsNew.png
  4. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/contractNew.png
  5. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/customerNew.png
  6. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/orderNew.png
  7. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/productNew.png
  8. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/tasksNew.png
  9. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/module/threadNew.png
  10. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/assets/image/rightArrow.png
  11. 28 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pdfPreview/index.vue
  12. 102 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pdfPreview/pdf.vue
  13. 4 4
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/component/workbench.vue
  14. 14 1
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/home/index.vue
  15. 144 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index copy.vue
  16. 78 19
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/my/index.vue
  17. 22 7
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/work/index.vue
  18. 5 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/router.js
  19. 8 0
      fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/utility/generalVariables.js
  20. 9 86
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/DataCollectTask.java
  21. 2 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  22. 1 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/package.json

@@ -14,6 +14,7 @@
     "axios": "^1.6.7",
     "dayjs": "^1.11.13",
     "echarts": "^5.5.1",
+    "pdfjs-dist": "^2.6.347",
     "pinia": "^2.1.7",
     "pinia-plugin-persist": "^1.0.0",
     "vant": "^4.5.0",

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


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


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


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


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


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


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


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


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


+ 28 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pdfPreview/index.vue

@@ -0,0 +1,28 @@
+<template>
+  <Page title="PDF预览" styleReset="backNone">
+    <template v-slot:body>
+      <pdf></pdf>
+    </template>
+  </Page>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import pdf from './pdf.vue';
+</script>
+
+<style scoped>
+.pdf-container {
+  width: 100%;
+  height: 100%;  /* 高度占满视口 */
+  overflow: hidden;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.vue-pdf {
+  max-width: 100%;  /* 最大宽度为100% */
+  max-height: 100%;  /* 最大高度为100% */
+}
+</style>

+ 102 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/pdfPreview/pdf.vue

@@ -0,0 +1,102 @@
+<template>
+  <div ref="pdfContainer" class="pdF-container" @scroll="onScroll">
+    <div ref="canvasWrapper" class="canvas-wrapper"></div>
+  </div>
+</template>
+
+<script setup>
+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 pdfContainer = ref(null); // PDF容器
+const canvasWrapper = ref(null); // canvas容器
+let currentPage = 1; // 当前显示的页码
+const totalPages = ref(0); // PDF 总页数
+const pageHeight = 1000; // 每个页面的高度,用于判断是否需要加载新页面
+let loadedPages = new Set(); // 存储已加载的页面编号
+
+onMounted(() => {
+  console.log(pdfjsLib.version);
+  // 设置 pdf.js 的 workerSrc
+  pdfjsLib.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.worker.min.js`;
+
+  // 加载 PDF 文件
+  pdfjsLib.getDocument(pdfUrl).promise.then((pdf) => {
+    console.log('PDF loaded', pdf.numPages);
+    totalPages.value = pdf.numPages;
+
+    // 初始化页面加载
+    loadPagesInView();
+  }).catch((error) => {
+    console.error('Error loading PDF:', error);
+  });
+});
+
+// 滚动事件处理函数
+function onScroll() {
+  loadPagesInView();
+}
+
+// 加载当前可视区域的页面
+function loadPagesInView() {
+  const container = pdfContainer.value;
+  const scrollTop = container.scrollTop; // 获取当前滚动位置
+  const containerHeight = container.clientHeight; // 容器的可视区域高度
+
+  // 计算可见区域的开始和结束页码
+  const startPage = Math.floor(scrollTop / pageHeight) + 1;
+  const endPage = Math.ceil((scrollTop + containerHeight) / pageHeight);
+
+  // 加载可见范围内的页面
+  for (let pageNum = startPage; pageNum <= endPage; pageNum++) {
+    if (!loadedPages.has(pageNum)) {
+      loadedPages.add(pageNum); // 标记该页已经加载
+      loadPage(pageNum); // 加载该页
+    }
+  }
+}
+
+// 加载指定页码的PDF页面
+async function loadPage(pageNum) {
+  const pdf = await pdfjsLib.getDocument(pdfUrl).promise; // 获取 PDF 文档对象
+  const page = await pdf.getPage(pageNum);
+  
+  const canvas = document.createElement('canvas');
+  const context = canvas.getContext('2d');
+  const scale = 2;  // 设置缩放比例
+  const viewport = page.getViewport({ scale });
+
+  // 设置 canvas 大小
+  canvas.height = viewport.height;
+  canvas.width = viewport.width;
+
+  // 渲染页面
+  await page.render({
+    canvasContext: context,
+    viewport: viewport
+  }).promise;
+  
+  console.log('Page rendered', pageNum);
+  
+  // 将渲染后的 canvas 添加到容器中
+  canvasWrapper.value.appendChild(canvas);
+}
+</script>
+
+<style scoped>
+.pdF-container {
+  height: 100%;
+  overflow-y: auto; /* 支持垂直滚动 */
+}
+
+.canvas-wrapper {
+  display: block;
+  width: 100%;
+}
+
+canvas {
+  margin-bottom: 10px;
+  border: 1px solid #ccc;
+}
+</style>

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

@@ -127,7 +127,7 @@
             </div>
           </template>
 
-          <div class="w80 bg-[#357AF4] h-28 rounded-md flex flex-col items-center justify-center"
+          <div class="w80 bg-[#075985] 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">
@@ -224,7 +224,7 @@ const router = useRouterStore()
 const useInfo = useInfoStore()
 const user = useInfo.userInfo
 const { toastText, toastSuccess, toastFail, toastLoading } = useToast()
-const expandAndCollapse = ref(true)
+const expandAndCollapse = ref(false)
 const calendarHeight = ref(0)
 const calendarRef = ref()
 const dateConditions = ref(dayjs().format('YYYY-MM-DD'))
@@ -389,7 +389,7 @@ function jumpToAddNewVisitors(row) {
 
 function returnImageAddress(rows) {
   const row = routingInfos[rows.path.replace('/', '')]
-  return row.homeImage
+  return row && row.homeImage
 }
 
 function expandAndCollapseClick() {
@@ -408,7 +408,7 @@ function processForms() {
 
   commonExpressionsHaveBeenNodded.value = allFormList.filter(item =>
     !selectedForm.some(arrItem => arrItem.path === item.path)
-  )
+  ).filter(item => item.path !== '/biReport')
 }
 
 function getVisitorPlan() {

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

@@ -14,9 +14,13 @@
       <div class="w-full h-full flex flex-col overflow-hidden">
         <!-- 头部 -->
         <div class="custom-tabs rounded-b-lg z-10">
-          <div class="custom-tabs-box text-size-in custom-tabs-rad flex items-center overflow-hidden">
+          <!-- <div class="custom-tabs-box text-size-in custom-tabs-rad flex items-center overflow-hidden">
             <div :class="`w-1/2 h-full rounded-r-lg items-justify-center ${homepageType == 'workbench' ? 'themeTextColor bg-white font-bold' : ''}`" @click="homepageType = 'workbench'">工作台</div>
             <div :class="`w-1/2 h-full rounded-l-lg items-justify-center ${homepageType == 'dataAnalysis' ? 'themeTextColor bg-white font-bold' : ''}`" @click="homepageType = 'dataAnalysis'">数据分析</div>
+          </div> -->
+          <div class="flex items-center">
+            <div :class="`mr-6 pb-2 relative ${homepageType == 'workbench' ? 'tabAction' : ''}`" @click="homepageType = 'workbench'">工作台</div>
+            <div :class="`mr-6 pb-2 relative ${homepageType == 'dataAnalysis' ? 'tabAction' : ''}`" @click="homepageType = 'dataAnalysis'">数据分析</div>
           </div>
         </div>
         <!-- 内容 -->
@@ -220,4 +224,13 @@ useLifecycle({
 .topTitle {
   top: 14px;
 }
+.tabAction::after {
+  content: '';
+  position: absolute;
+  width: 100%;
+  height: 2px;
+  background: #fff;
+  bottom: 0;
+  left: 0;
+}
 </style>

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

@@ -0,0 +1,144 @@
+<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>
+          <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-[#075985] mt-2" @click="applicationMarket()">应用市场</div>
+
+            <div class="text-center text-[#075985] mt-8"
+              v-if="userInfo.userInfo.userNameNeedTranslate != '1' && (isCorpWX || isWX)" @click="bindWeiXin">
+              {{ `绑定${isCorpWX ? '企业' : ''}微信` }}
+              (
+              <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="w-full mb-40 px-24" 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>
+      <Footer />
+    </template>
+  </Page>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { useLifecycle } from "@hooks/useCommon.js";
+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)
+
+function bindWeiXin() {
+  //企业微信
+  if (isCorpWX.value && userInfo.userInfo.corpwxUserid != null) {
+    return;
+  }
+  //微信
+  else if (isWX.value && userInfo.userInfo.wxOpenid != null) {
+    return;
+  }
+
+  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;//授权回调页面
+  }
+
+  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',
+    success: () => {
+      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
+}
+
+const applicationMarket = () => {
+  window.location.href = 'https://www.ttkuaiban.com/appMarket.html'
+  // window.open('https://www.ttkuaiban.com/appMarket.html', '_blank'); 
+}
+
+useLifecycle({
+  load: () => {
+    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;
+}
+</style>

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

@@ -1,36 +1,71 @@
 <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-[#075985] mt-2" @click="applicationMarket()">应用市场</div>
+          <div class="profilePicture-img">
+            <!-- <img src="/src/assets/image/rightArrow.png"> -->
+          </div>
+        </div>
 
-            <div class="text-center text-[#075985] 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 +86,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 +182,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>

+ 22 - 7
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/pages/tabbar/work/index.vue

@@ -1,12 +1,16 @@
 <template>
   <Page title="工作">
     <template v-slot:body>
-      <div class="w-full h-full">
+      <div class="w-full h-[96%]">
         <div class="workLayout" @click.stop>
-          <div class="text-gray-950 text-center modulistImage" v-for="(item) in moduleList" :key="item.id"
+          <!-- <div class="text-gray-950 text-center modulistImage" v-for="(item) in moduleList" :key="item.id"
             @click.stop="toModuleList(item)">
             <img :src="returnImageAddress(item)"  />
             <div class="modulistText">{{ item.name }}</div>
+          </div> -->
+          <div class="text-gray-950 text-center modulistImage flex flex-col items-center justify-center" v-for="(item) in moduleList" :key="item.id" @click.stop="toModuleList(item)">
+            <img :src="returnImageAddress(item)"  />
+            <div class="modulistTextNew">{{ item.name }}</div>
           </div>
         </div>
       </div>
@@ -44,7 +48,8 @@ function toModuleList(item) {
 
 function returnImageAddress(rows) {
   const row = routingInfos[rows.path.replace('/', '')]
-  return row?.moduleImage
+  // return row?.moduleImage
+  return row?.moduleImageNew
 }
 
 useLifecycle({
@@ -58,20 +63,30 @@ useLifecycle({
   margin: 20px;
   padding-bottom: 20px;
   overflow: auto;
-  background-color: #fff;
   border-radius: 8px;
   display: flex;
   flex-wrap: wrap;
 }
 .modulistImage {
   width: 140px;
-  height: 140px;
+  height: 110px;
   position: relative;
   margin-left: 18px;
   margin-top: 18px;
+  background: #fff;
+  border-radius: 10px;
   img {
-    width: 100%;
-    height: 100%;
+    width: 40px;
+    height: 40px;
+  }
+  // img {
+  //   width: 100%;
+  //   height: 100%;
+  // }
+
+  .modulistTextNew {
+    margin-top: 8px;
+    font-size: 16px;
   }
 
   .modulistText {

+ 5 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/router.js

@@ -57,6 +57,11 @@ const routes = [
         name: 'visitorDetails',
         meta: { title: '访客计划详情' },
         component: () => import("@pages/visitorProgram/visitorDetails.vue"),
+    }, {
+        path: '/pdfPreview',
+        name: 'pdfPreview',
+        meta: { title: 'PDF预览' },
+        component: () => import("@pages/pdfPreview/index.vue"),
     }, {
         path: '/:pathMatch(.*)*',
         name: 'notFound',

+ 8 - 0
fhKeeper/formulahousekeeper/customerBuler-crm-h5/src/utility/generalVariables.js

@@ -15,6 +15,7 @@ export const routingInfos = {
     topMountedInterface: TOP_OF_BUSINESS_OPPORTUNITIES, // 顶置接口
     cancelTheTopMountedInterface: CANCEL_THE_TOP_PLACEMENT_OF_BUSINESS_OPPORTUNITIES, // 取消顶置接口
     homeImage: new URL('/src/assets/image/module/min_business.png', import.meta.url).href, // 首页图片
+    moduleImageNew: new URL('/src/assets/image/module/businessNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/business.png', import.meta.url).href, // 模块图片
     searchFiled: { search: 'name' }, // 搜索字段
     image: '', // 图片
@@ -36,6 +37,7 @@ export const routingInfos = {
     topMountedInterface: TOP_OF_CLUES,
     cancelTheTopMountedInterface: CANCEL_THE_TOP_PLACEMENT_OF_CLUES,
     homeImage: new URL('/src/assets/image/module/min_thread.png', import.meta.url).href,
+    moduleImageNew: new URL('/src/assets/image/module/threadNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/thread.png', import.meta.url).href,
     searchFiled: { search: 'clueName' },
     image: '',
@@ -57,6 +59,7 @@ export const routingInfos = {
     topMountedInterface: CUSTOMER_TOP_MOUNTED,
     cancelTheTopMountedInterface: CUSTOMER_CANCELS_TOP_PLACEMENT,
     homeImage: new URL('/src/assets/image/module/min_customer.png', import.meta.url).href,
+    moduleImageNew: new URL('/src/assets/image/module/customerNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/customer.png', import.meta.url).href,
     searchFiled: { search: 'customName' },
     image: '',
@@ -78,6 +81,7 @@ export const routingInfos = {
     topMountedInterface: CONTACT_TOP,
     cancelTheTopMountedInterface: CONTACT_PERSON_CANCELS_TOP_PLACEMENT,
     homeImage: new URL('/src/assets/image/module/min_contacts.png', import.meta.url).href,
+    moduleImageNew: new URL('/src/assets/image/module/contactsNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/contacts.png', import.meta.url).href,
     searchFiled: { search: 'name' },
     image: '',
@@ -99,6 +103,7 @@ export const routingInfos = {
     topMountedInterface: TASK_TOP,
     cancelTheTopMountedInterface: TASK_CANCELLATION_TOP,
     homeImage: new URL('/src/assets/image/module/min_tasks.png', import.meta.url).href,
+    moduleImageNew: new URL('/src/assets/image/module/tasksNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/tasks.png', import.meta.url).href,
     searchFiled: { search: 'taskName' },
     image: '',
@@ -120,6 +125,7 @@ export const routingInfos = {
     topMountedInterface: TOP_MOUNTED_PRODUCT,
     cancelTheTopMountedInterface: CANCEL_THE_TOP_PLACEMENT_OF_THE_PRODUCT,
     homeImage: new URL('/src/assets/image/module/min_product.png', import.meta.url).href,
+    moduleImageNew: new URL('/src/assets/image/module/productNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/product.png', import.meta.url).href,
     searchFiled: { search: 'productName' },
     image: '',
@@ -141,6 +147,7 @@ export const routingInfos = {
     topMountedInterface: TOP_OF_THE_CONTRACT,
     cancelTheTopMountedInterface: CONTRACT_CANCELLATION_WITH_TOP_PLACEMENT,
     homeImage: new URL('/src/assets/image/module/min_contract.png', import.meta.url).href,
+    moduleImageNew: new URL('/src/assets/image/module/contractNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/contract.png', import.meta.url).href,
     searchFiled: { search: 'name' },
     image: '',
@@ -162,6 +169,7 @@ export const routingInfos = {
     topMountedInterface: SALES_ORDER_TOP_PLACEMENT,
     cancelTheTopMountedInterface: CANCEL_THE_TOP_PLACEMENT_OF_THE_SALES_ORDER,
     homeImage: new URL('/src/assets/image/module/min_order.png', import.meta.url).href,
+    moduleImageNew: new URL('/src/assets/image/module/orderNew.png', import.meta.url).href,
     moduleImage: new URL('/src/assets/image/module/order.png', import.meta.url).href,
     searchFiled: { search: 'orderName' },
     image: '',

+ 9 - 86
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/DataCollectTask.java

@@ -35,7 +35,9 @@ public class DataCollectTask {
 
     @Value("${configEnv.isDev}")
     public boolean isDev;
-
+    //是否是私有化部署
+    @Value("${configEnv.isPrivateDeploy}")
+    boolean isPrivateDeploy;
     @Resource
     private UserFvTimeMapper userFvTimeMapper;
     @Resource
@@ -93,6 +95,7 @@ public class DataCollectTask {
     @Async
     public void caDayTisTask(){
         if(isDev){return;}
+        if(isPrivateDeploy) return;
         LocalDate nowDate = LocalDate.now();
         int today = nowDate.getMonthValue();
         int lastDay = Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
@@ -207,6 +210,7 @@ public class DataCollectTask {
     @Async
     public void sqlServerTask() {
         if(isDev){return;}
+        if(isPrivateDeploy) return;
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL+"/dataCollect/getSqlServerDataSum";
         String listUrl = PREFIX_URL+"/dataCollect/getSqlServerDataList";
@@ -291,6 +295,7 @@ public class DataCollectTask {
 //@Scheduled(cron = "0 42 16 * * ?")
     public void workDayTask(){
         if(isDev){return;}
+        if(isPrivateDeploy) return;
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL+"/dataCollect/getWorkDayDataSum";
         String listUrl = PREFIX_URL+"/dataCollect/getWorkDayDataList";
@@ -383,6 +388,7 @@ public class DataCollectTask {
     @Async
     public void leaveSheetTask(){
         if(isDev){return;}
+        if(isPrivateDeploy) return;
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL + "/dataCollect/getLeaveSheetDataSum";
         String listUrl = PREFIX_URL + "/dataCollect/getLeaveSheetDataList";
@@ -552,96 +558,12 @@ public class DataCollectTask {
         }
     }
 
-//    @Scheduled(cron = "0 30 2 * * ?")
-//@Scheduled(cron = "0 46 15 * * ?")
-//    @Async
-    public void sqlServerProjectTypeTask() {
-        if(isDev){return;}
-        RestTemplate restTemplate = new RestTemplate();
-        String sumUrl = PREFIX_URL+"/dataCollect/getSqlServerProjectTypeDataSum";
-        String listUrl = PREFIX_URL+"/dataCollect/getSqlServerProjectTypeDataList";
-
-        try {
-            ResponseEntity<String> sumResponse = restTemplate.exchange(
-                    sumUrl,
-                    HttpMethod.GET,
-                    null,
-                    String.class
-            );
-            Integer totalNum = 0;
-            if (sumResponse.getStatusCode() == HttpStatus.OK) {
-                totalNum = Integer.parseInt(sumResponse.getBody());
-            } else {
-                System.out.println("请求失败,状态码: " + sumResponse.getStatusCode());
-            }
-            if(totalNum > 0){
-                int pageSize = 1000;
-                int offset = 0;
-                List<ProjectCategory> toAddList = new ArrayList<>();
-                List<ProjectCategory> toUpdateList = new ArrayList<>();
-                while (offset < totalNum) {
-                    HttpHeaders headers = new HttpHeaders();
-                    headers.setContentType(MediaType.APPLICATION_JSON);
-                    Map<String, Object> requestBody = new HashMap<>();
-                    requestBody.put("pageNo", offset);
-                    requestBody.put("pageSize", pageSize);
-                    HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, headers);
-                    ResponseEntity<List<String>> listResponse = restTemplate.exchange(
-                            listUrl,
-                            HttpMethod.POST,
-                            requestEntity,
-                            new  ParameterizedTypeReference<List<String>>(){}
-                    );
-                    if (listResponse.getStatusCode() == HttpStatus.OK) {
-                        List<String> dataList = listResponse.getBody();
-                        List<ProjectCategory> tmpList = new ArrayList<>();
-                        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(dataList)){
-                            List<String> existIds = projectCategoryMapper.getExistIds(dataList,specialCompanyId);
-                            if(!CollectionUtils.isEmpty(existIds)){
-                                for (String name : dataList) {
-                                    ProjectCategory tmp = new ProjectCategory();
-                                    tmp.setName(name);
-                                    tmp.setCompanyId(specialCompanyId);
-                                    tmpList.add(tmp);
-                                }
-                                toUpdateList.addAll(tmpList.stream().filter(t -> existIds.contains(t.getName())).collect(Collectors.toList()));
-                                toAddList.addAll(tmpList.stream().filter(t -> !existIds.contains(t.getName())).collect(Collectors.toList()));
-                            }else{
-                                for (String name : dataList) {
-                                    ProjectCategory tmp = new ProjectCategory();
-                                    tmp.setName(name);
-                                    tmp.setCompanyId(specialCompanyId);
-                                    tmpList.add(tmp);
-                                }
-                                toAddList.addAll(tmpList);
-                            }
-                            if(!CollectionUtils.isEmpty(toAddList)){
-                                projectCategoryMapper.batchInsert(toAddList);
-                            }
-                            if(!CollectionUtils.isEmpty(toUpdateList)){
-                                for (ProjectCategory projectCategory : toUpdateList) {
-                                    projectCategoryMapper.updateById(projectCategory);
-                                }
-                            }
-                            toUpdateList.clear();
-                            toAddList.clear();
-                        }
-                    }
-                    offset += pageSize;
-                }
-            }
-        } catch (Exception e) {
-            System.out.println("请求发生异常: " + e.getMessage());
-            e.printStackTrace();
-        }
-
-    }
-
     @Scheduled(cron = "0 30 3 * * ?")
 //@Scheduled(cron = "0 12 16 * * ?")
     @Async
     public void sqlServerProjectTask() {
         if(isDev){return;}
+        if(isPrivateDeploy) return;
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL+"/dataCollect/getSqlServerProjectDataSum";
         String listUrl = PREFIX_URL+"/dataCollect/getSqlServerProjectDataList";
@@ -816,6 +738,7 @@ public class DataCollectTask {
     @Async
     public void businessTripTask(){
         if(isDev){return;}
+        if(isPrivateDeploy) return;
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL+"/dataCollect/getBusinessTripDataSum";
         String listUrl = PREFIX_URL+"/dataCollect/getBusinessTripDataList";

+ 2 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml

@@ -18,9 +18,6 @@ spring:
     url: jdbc:mysql://1.94.62.58:17089/man_mld?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
     username: root
     password: P011430@Huoshi*
-#    url: jdbc:mysql://47.100.37.243:7644/man_hour_manager?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
-#    username: root
-#    password: Ziyu20141026!@@
     hikari:
       maximum-pool-size: 60
       minimum-idle: 10
@@ -167,6 +164,8 @@ configEnv:
   isDev: true
   # 是否是私有化部署,企业内部应用
   isPrivateDeploy: false
+  # 是否是saas生产环境
+  isSaasProd: false
 
 privateDeployURL:
   pcUrl: http://dev.huoshishanxin.com/#/

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -1143,7 +1143,7 @@ export default {
                 this.getProjectProfessions(this.form.domains[this.clickIndex], index);
             }
             //获取任务分组
-            this.getTaskGroups(this.form.domains[this.clickIndex], this.clickIndex);
+            this.getTaskGroups(this.form.domains[flag ? index : this.clickIndex], this.clickIndex);
 
             // 获取1相关维度
             this.getTaskList(domainItem)