소스 검색

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

seyason 1 년 전
부모
커밋
e5aa10358f
28개의 변경된 파일631개의 추가작업 그리고 147개의 파일을 삭제
  1. 6 0
      fhKeeper/formulahousekeeper/customerBuler-crm/package-lock.json
  2. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/package.json
  3. 28 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/App.vue
  4. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/main.ts
  5. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/analysis/index.vue
  6. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  7. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/index.vue
  8. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/index.vue
  9. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue
  10. 144 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/header/header.vue
  11. 89 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/home copy.vue
  12. 14 71
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/home.vue
  13. 14 47
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/login.vue
  14. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue
  15. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue
  16. 46 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/index.vue
  17. 17 5
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue
  18. 3 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/router/index.ts
  19. 17 5
      fhKeeper/formulahousekeeper/customerBuler-crm/src/store/index.ts
  20. 25 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ContactsController.java
  21. 13 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Contacts.java
  22. 13 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/ContactsVo.java
  23. 8 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/ContactsMapper.java
  24. 7 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/ContactsService.java
  25. 68 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContactsServiceImpl.java
  26. 7 7
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  27. 30 1
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/ContactsMapper.xml
  28. 3 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

+ 6 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/package-lock.json

@@ -10,6 +10,7 @@
       "dependencies": {
         "@element-plus/icons-vue": "^2.3.1",
         "@zmjs/form-design": "^0.1.16",
+        "animate.css": "^4.1.1",
         "axios": "^1.6.7",
         "echarts": "^5.5.0",
         "element-plus": "^2.5.6",
@@ -1138,6 +1139,11 @@
       "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.32.7.tgz",
       "integrity": "sha512-ziv35kaYELFw4suWlotz/Xsl1/1LhWAbwFoD3zIgCgP9gXGECEsAM4GhiB0T0xZdmQjyv6hmAzO280g0+n4vGw=="
     },
+    "node_modules/animate.css": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz",
+      "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
+    },
     "node_modules/ansi-regex": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",

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

@@ -12,6 +12,7 @@
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
     "@zmjs/form-design": "^0.1.16",
+    "animate.css": "^4.1.1",
     "axios": "^1.6.7",
     "echarts": "^5.5.0",
     "element-plus": "^2.5.6",

+ 28 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/App.vue

@@ -1,5 +1,10 @@
 <template>
-  <router-view></router-view>
+  <!-- <router-view></router-view> -->
+  <router-view v-slot="{ Component }">
+    <transition name="ranimate">
+      <component :is="Component" />
+    </transition>
+  </router-view>
 </template>
 
 <script setup lang="ts">
@@ -17,7 +22,7 @@ provide<GlobalPopup>('globalPopup', {
     notificationTiop({
       message: message || '成功',
       type: 'success',
-      title:"提示",
+      title: "提示",
       duration: 2000
     })
   }, //!SECTION 成功
@@ -54,6 +59,26 @@ body,
 .layouts {
   width: 100%;
   height: 100%;
-  overflow: hidden;
+  /* overflow: hidden; */
+  min-width: 650px;
+}
+* {
+  font-family: '微软雅黑';
+}
+/* home 页面的动画 */
+.router_animate-enter-active {
+    animation: slideInLeft 0.5s;
+}
+.router_animate-leave-active {
+    animation: slideOutLeft 0s;
+}
+
+/* app 路由动画 */
+.ranimate-enter-active {
+  animation: fadeIn 1s;
+}
+ 
+.ranimate-leave-active {
+  animation: fadeIn 0s;
 }
 </style>

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/main.ts

@@ -3,6 +3,7 @@ import { createPinia } from 'pinia'
 import ElementPlus from 'element-plus'
 import "./TailWindCss/index.css";
 import 'element-plus/dist/index.css'
+import 'animate.css/animate.min.css' //引入动画
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
 import App from './App.vue'

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/analysis/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    analysis
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    business
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/contacts/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    contacts
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    corpreport
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    customer
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 144 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/header/header.vue

@@ -0,0 +1,144 @@
+<template>
+  <div class="trademark mr-8 flex items-center text-white">
+    <img :src="loginLogin" class="w-10 h-10 mr-4" />
+    <div class="text-nowrap">客户管家</div>
+  </div>
+  <div class=" flex flex-row justify-start items-center text-white flex-1 parentDiv" ref="parentDiv">
+    <div v-for="(routerItem, routerItemIdex) in routerList"
+      :class="`border-b-2 border-transparent hover:border-white p-2 mr-4 cursor-pointer multipleyHeader ${activeRouter?.path === routerItem.path ? 'border-white' : ''}`"
+      :key="routerItem.path" ref="childDivs" v-show="visibleItems.includes(routerItemIdex)">
+      <div v-if="routerItem.children && routerItem.children.length <= 0" @click="setCurrentRouter(routerItem)" class="text-nowrap">
+        {{ routerItem.name }}
+      </div>
+      <div v-else class="flex justify-center items-center">
+        <el-dropdown>
+          <div class="text-white w-full h-full headerText">
+            {{ routerItem.name }}
+            <el-icon class="el-icon--right">
+              <arrow-down />
+            </el-icon>
+          </div>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item v-for="child in routerItem.children" :key="child.path" @click="setCurrentRouter(child)">
+                {{ child.name }}
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+    </div>
+  </div>
+  <div class="flex flex-row justify-start items-center text-white header-right">
+    <el-icon :size="26" class="ml-4 cursor-pointer">
+      <Bell />
+    </el-icon>
+    <div>
+      <img class="w-8 h-8 rounded-full ml-4 cursor-pointer" :src="defaultCover" alt="" @click="logout()">
+    </div>
+    <el-icon :size="26" class="ml-4 cursor-pointer">
+      <Grid />
+    </el-icon>
+  </div>
+</template>
+  
+<script lang="ts" setup>
+import { onMounted, ref, watchEffect } from 'vue';
+import { RouteRecordRaw, useRouter } from 'vue-router';
+import { useStore } from "../../store/index"
+import defaultCover from "../../assets/defaultCover.png";
+import loginLogin from '../../assets/login/login_logo.png'
+const { routers, clearStore } = useStore()
+const router = useRouter();
+const routerList = ref<RouteRecordRaw[]>([]);
+const activeRouter = ref<RouteRecordRaw>();
+
+const visibleItems = ref<number[]>([]);
+const parentDiv = ref<HTMLElement | null>(null);
+
+const updateVisibleItems = () => {
+  const parentWidth = parentDiv.value?.offsetWidth || 10;
+  const canvas = document.createElement('canvas');
+  const context = canvas.getContext('2d');
+
+  let textWidthList: any = [] // 所有文字的宽度
+  let totalWidth = 0;
+  let temporaryIndex: any = []
+  
+  if(context) {
+    context.font = '16px 微软雅黑';
+    textWidthList = routerList.value.map((item: any) => {
+      const metrics = context.measureText(item.name);
+      return Math.ceil(metrics.width) + 32; // 32是padding和margin的宽度
+    })
+  }
+  for(let i in textWidthList) {
+    if(totalWidth + textWidthList[i] > parentWidth) {
+      break;
+    }
+    totalWidth += textWidthList[i];
+    temporaryIndex.push(+i);
+  }
+
+  // 替换最后一个元素
+  let lastIndex = textWidthList.length - 1;
+  temporaryIndex.splice(temporaryIndex.length -1, 1, lastIndex)
+
+  visibleItems.value = temporaryIndex;
+  console.log(visibleItems.value)
+};
+
+const setCurrentRouter = (item: RouteRecordRaw) => {
+  activeRouter.value = item;
+  if (item.children && item.children.length > 0) {
+    router.push({ path: item.children[0].path });
+    return
+  }
+  router.push({ path: item.path });
+};
+const logout = () => {
+  clearStore();
+  router.push({ path: '/login' });
+};
+onMounted(() => {
+  routerList.value = routers;
+  activeRouter.value = routerList.value.find((item) => item.path === router.currentRoute.value.path);
+  console.log("routerList", routerList);
+
+  window.addEventListener('resize', updateVisibleItems);
+  setTimeout(() => {
+    updateVisibleItems();
+  }, 500);
+})
+watchEffect(() => {
+  updateVisibleItems();
+});
+</script>
+  
+<style scoped lang="scss">
+.trademark {
+  font-size: 20px;
+}
+.multipleyHeader {
+  height: 96%;
+  display: flex;
+  align-items: center;
+  text-wrap: nowrap;
+
+  .headerText {
+    font-size: 16px;
+  }
+}
+.parentBox {
+  // max-width: 80%;
+  // min-width: 300px;
+  flex: 1;
+  overflow: hidden;
+}
+.header-right {
+  width: 135px;
+}
+.parentDiv {
+  width: 50%;
+}
+</style>

+ 89 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/home copy.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="w-full h-full">
+    <el-container>
+      <el-header class="bg-sky-800 leading-10 flex flex-row justify-between">
+        <div class=" flex flex-row justify-start items-center text-white flex-1">
+          <div v-for="routerItem in routerList"
+            :class="`border-b-2 border-transparent hover:border-white p-2 mr-4 multipleyHeader ${activeRouter?.path === routerItem.path ? 'border-white' : ''}`"
+            :key="routerItem.path">
+            <div v-if="!routerItem.children" @click="setCurrentRouter(routerItem)">
+              {{ routerItem.name }}
+            </div>
+            <div v-else class="flex justify-center items-center">
+              <el-dropdown>
+                <div class="text-white w-full h-full headerText">
+                  {{ routerItem.name }}
+                  <el-icon class="el-icon--right">
+                    <arrow-down />
+                  </el-icon>
+                </div>
+                <template #dropdown>
+                  <el-dropdown-menu>
+                    <el-dropdown-item v-for="child in routerItem.children"
+                      :key="child.path"
+                      @click="setCurrentRouter(child)">
+                      {{ child.name }}
+                    </el-dropdown-item>
+                  </el-dropdown-menu>
+                </template>
+              </el-dropdown>
+            </div>
+          </div>
+        </div>
+        <div class="flex flex-row justify-start items-center text-white">
+          <el-icon :size="26" class="ml-4 cursor-pointer">
+            <Bell />
+          </el-icon>
+          <div>
+            <img class="w-8 h-8 rounded-full ml-4 cursor-pointer" :src="defaultCover" alt="" @click="logout()">
+          </div>
+          <el-icon :size="26" class="ml-4 cursor-pointer">
+            <Grid />
+          </el-icon>
+        </div>
+      </el-header>
+      <el-main>
+        <router-view />
+      </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { onMounted, ref } from 'vue';
+import { RouteRecordRaw, useRouter } from 'vue-router';
+import { useStore } from "@/store"
+import defaultCover from "@/assets/defaultCover.png";
+const { getRoutersList } = useStore()
+const router = useRouter();
+const routerList = ref<RouteRecordRaw[]>([]);
+const activeRouter = ref<RouteRecordRaw>();
+const setCurrentRouter = (item: RouteRecordRaw) => {
+  activeRouter.value = item;
+  if (item.children && item.children.length > 0) {
+    router.push({ path: item.children[0].path });
+    return
+  }
+  router.push({ path: item.path });
+};
+const logout = () => {
+  router.push({ path: '/login' });
+};
+onMounted(() => {
+  routerList.value = getRoutersList;
+  activeRouter.value = routerList.value.find((item) => item.path === router.currentRoute.value.path);
+  console.log("routerList", routerList);
+})
+
+</script>
+
+<style scoped lang="scss">
+.multipleyHeader {
+  height: 96%;
+  display: flex;
+  align-items: center;
+  .headerText {
+    font-size: 16px;
+  }
+}
+</style>

+ 14 - 71
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/home.vue

@@ -1,89 +1,32 @@
 <template>
   <div class="w-full h-full">
-    <el-container>
+    <el-container class="flex flex-row h-full">
       <el-header class="bg-sky-800 leading-10 flex flex-row justify-between">
-        <div class=" flex flex-row justify-start items-center text-white flex-1">
-          <div v-for="routerItem in routerList"
-            :class="`border-b-2 border-transparent hover:border-white p-2 mr-4 multipleyHeader ${activeRouter?.path === routerItem.path ? 'border-white' : ''}`"
-            :key="routerItem.path">
-            <div v-if="!routerItem.children" @click="setCurrentRouter(routerItem)">
-              {{ routerItem.name }}
-            </div>
-            <div v-else class="flex justify-center items-center">
-              <el-dropdown>
-                <div class="text-white w-full h-full headerText">
-                  {{ routerItem.name }}
-                  <el-icon class="el-icon--right">
-                    <arrow-down />
-                  </el-icon>
-                </div>
-                <template #dropdown>
-                  <el-dropdown-menu>
-                    <el-dropdown-item v-for="child in routerItem.children"
-                      :key="child.path"
-                      @click="setCurrentRouter(child)">
-                      {{ child.name }}
-                    </el-dropdown-item>
-                  </el-dropdown-menu>
-                </template>
-              </el-dropdown>
-            </div>
-          </div>
-        </div>
-        <div class="flex flex-row justify-start items-center text-white">
-          <el-icon :size="26" class="ml-4 cursor-pointer">
-            <Bell />
-          </el-icon>
-          <div>
-            <img class="w-8 h-8 rounded-full ml-4 cursor-pointer" :src="defaultCover" alt="" @click="logout()">
-          </div>
-          <el-icon :size="26" class="ml-4 cursor-pointer">
-            <Grid />
-          </el-icon>
-        </div>
+        <Header></Header>
       </el-header>
       <el-main>
-        <router-view />
+        <!-- <router-view /> -->
+        <router-view v-slot="{ Component }">
+          <transition name="router_animate">
+            <component :is="Component" />
+          </transition>
+        </router-view>
       </el-main>
     </el-container>
   </div>
 </template>
 
 <script lang="ts" setup>
+import Header from '@/pages/header/header.vue'
 import { onMounted, ref } from 'vue';
-import { RouteRecordRaw, useRouter } from 'vue-router';
-import { useStore } from "@/store"
-import defaultCover from "@/assets/defaultCover.png";
-const { getRoutersList } = useStore()
-const router = useRouter();
-const routerList = ref<RouteRecordRaw[]>([]);
-const activeRouter = ref<RouteRecordRaw>();
-const setCurrentRouter = (item: RouteRecordRaw) => {
-  activeRouter.value = item;
-  if (item.children && item.children.length > 0) {
-    router.push({ path: item.children[0].path });
-    return
-  }
-  router.push({ path: item.path });
-};
-const logout = () => {
-  router.push({ path: '/login' });
-};
-onMounted(() => {
-  routerList.value = getRoutersList;
-  activeRouter.value = routerList.value.find((item) => item.path === router.currentRoute.value.path);
-  console.log("routerList", routerList);
-})
 
 </script>
 
 <style scoped lang="scss">
-.multipleyHeader {
-  height: 96%;
-  display: flex;
-  align-items: center;
-  .headerText {
-    font-size: 16px;
-  }
+.el-main {
+  padding: 0;
+  flex: 1;
+  overflow: hidden;
+  background: $backColor;
 }
 </style>

+ 14 - 47
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/login.vue

@@ -49,7 +49,7 @@ import { type FormInstance, type FormRules } from 'element-plus'
 import { useStore } from '@/store/index'
 import { post } from "@/utils/request";
 import { LOGIN } from "./api";
-const { setRouters } = useStore()
+const { setRouters, setValue } = useStore()
 const router = useRouter();
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const ruleFormRef = ref<FormInstance>();
@@ -74,54 +74,21 @@ const login = (formEl: FormInstance | undefined) => {
     }
     loginLoading.value = true;
     console.log(ruleForm.value);
-    globalPopup?.showSuccess();
-    let newRouter = [
-      {
-        path: '/thread',
-        name: '线索'
-      }, {
-        path: "/tasks",
-        name: "任务"
-      }, {
-        path: "/system",
-        name: "系统",
-        children: [
-          {
-            path: "/role",
-            name: "角色管理"
-          }, {
-            path: "/dictionary",
-            name:"系统字典"
-          }
-        ]
-      }
-    ]
-    setRouters(newRouter)
-    setTimeout(() => {
-      loginLoading.value = false;
-      router.push(newRouter[0].path);
-    }, 1000);
-    return
     post(LOGIN, { ...ruleForm.value }).then(res => {
       console.log(res);
-      // if(res.code == 'error') {
-      //   ElMessage.error({
-      //     message: "登录失败",
-      //     type: "error",
-      //     duration: 2000,
-      //   })
-      //   loginLoading.value = false;
-      //   return
-      // }
-      // ElMessage.success({
-      //   message: "登录成功",
-      //   type: "success",
-      //   duration: 2000,
-      // })
-      // setTimeout(() => {
-      //   loginLoading.value = false;
-      // }, 1000)
-      // loginLoading.value = false;
+      if(res.code == 'error') {
+        globalPopup?.showError(res.msg)
+        loginLoading.value = false;
+        return
+      }
+      globalPopup?.showSuccess('登录成功')
+      setValue(res.data, 'userInfo')
+      setValue(res.data?.moduleList, 'routers')
+      setTimeout(() => {
+        loginLoading.value = false;
+        router.push(res.data?.moduleList[0].path);
+      }, 1000)
+      loginLoading.value = false;
     }).catch(err => {
       console.log(err)
       loginLoading.value = false;

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/order/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    order
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    product
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 46 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/index.vue

@@ -1,6 +1,50 @@
 <template>
-  <div>
-    任务
+  <div class="h-full flex">
+    <div class="p-5 w-80 pr-0">
+      <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col">
+        <div class="flex-1 p-3 overflow-y-scroll">
+          <ul>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+            <li>sssss</li>
+          </ul>
+        </div>
+        <div class="w-full flex p-3 shadow-[0_-3px_5px_0px_rgba(0,0,0,0.2)]">
+          <El-button class="w-full">重置</El-Button>
+          <El-button type="primary" class="w-full">搜索</El-Button>
+        </div>
+      </div>
+    </div>
+    <div class="flex-1 p-5">
+      <div class="bg-white w-full h-full p-3 shadow-md rounded-md">222</div>
+    </div>
   </div>
 </template>
 

+ 17 - 5
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue

@@ -1,9 +1,21 @@
 <template>
-<div id="" class="h100">
-    线索文件
-</div>
+  <div class="bg-gray-200 h-full flex">
+    <div class="p-5 w-80 pr-0">
+      <div class="bg-white w-full h-full p-3 shadow-md rounded-md">
+        线索管理
+      </div>
+    </div>
+    <div class="flex-1 bg-gray-200 p-5">
+      <div class="bg-white w-full h-full p-3 shadow-md rounded-md">222</div>
+    </div>
+  </div>
 </template>
+
+
 <script setup lang="ts">
+
 </script>
-<style scoped lang="scss">
-</style>
+
+
+<style scoped></style>
+

+ 3 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/router/index.ts

@@ -48,9 +48,10 @@ router.beforeEach((to, _from, next) => {
   const routerList = useStore().routers;
   const routers = router.getRoutes();
   console.log(routerList, routers);
-  const { setAsyncRoutesMark, asyncRoutesMark } = useStore();
-  const token = true;
+  const { setAsyncRoutesMark, asyncRoutesMark, getToken } = useStore();
+  const token = getToken;
   const skipPath = ["/login", "/register", "/test", "/testEcharts"];
+  console.log(token, '<==== token')
   if (skipPath.includes(to.path)) {
     next();
   } else {

+ 17 - 5
fhKeeper/formulahousekeeper/customerBuler-crm/src/store/index.ts

@@ -1,17 +1,19 @@
 import { defineStore, acceptHMRUpdate } from "pinia";
 import { RouteRecordRaw } from "vue-router";
 export const useStore = defineStore({
-  id: "index",
+  id: "storeInfo",
   state: () => ({
-    userInfo: {}, // 当前的用户信息
+    userInfo: { id: '' }, // 当前的用户信息
     routers: [], // 返回的所有路由
     asyncRoutesMark: false, // 是否添加过路由
   }),
   getters: {
-    // 取值
-    getRoutersList(): RouteRecordRaw[] {
+    getRoutersList(): RouteRecordRaw[] { // 取值
       return this.routers;
-    } 
+    },
+    getToken(): string {
+      return  this.userInfo?.id || ''
+    }
   },
   actions: {
     // 方法
@@ -21,6 +23,16 @@ export const useStore = defineStore({
     setAsyncRoutesMark(val: boolean) {
       this.asyncRoutesMark = val;
     },
+    setValue(val: any, key: 'userInfo' | 'routers' | 'asyncRoutesMark') {
+      this[key] = val;
+    },
+    clearStore() {
+      localStorage.clear();
+      sessionStorage.clear();
+      this.userInfo = { id: '' };
+      this.routers = [];
+      this.asyncRoutesMark = false;
+    }
   },
   persist: true, // 是否持久化
 });

+ 25 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/ContactsController.java

@@ -1,10 +1,19 @@
 package com.management.platform.controller;
 
 
+import com.management.platform.entity.Contacts;
+import com.management.platform.service.ContactsService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * <p>
  *  前端控制器
@@ -17,5 +26,21 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/contacts")
 public class ContactsController {
 
+    @Resource
+    private HttpServletRequest request;
+
+    @Autowired
+    private ContactsService contactsService;
+
+    @RequestMapping("/addContacts")
+    public HttpRespMsg addContacts(@RequestBody Contacts contacts){
+        return contactsService.addContacts(contacts, request);
+    }
+
+    @RequestMapping("/pageContacts")
+    public HttpRespMsg pageContacts(@RequestParam Integer pageIndex, @RequestParam Integer pageSize,String customName, String name, String phone, String ownerName){
+        return contactsService.pageContacts(pageIndex,pageSize,customName,name,phone,ownerName,request);
+    }
+
 }
 

+ 13 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Contacts.java

@@ -3,11 +3,15 @@ package com.management.platform.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
 import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
 
 /**
  * <p>
@@ -15,7 +19,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2024-02-28
+ * @since 2024-03-05
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -96,6 +100,14 @@ public class Contacts extends Model<Contacts> {
     @TableField("is_delete")
     private Integer isDelete;
 
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+    private LocalDateTime createTime;
+
 
     @Override
     protected Serializable pkVal() {

+ 13 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/ContactsVo.java

@@ -0,0 +1,13 @@
+package com.management.platform.entity.vo;
+
+import com.management.platform.entity.Contacts;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class ContactsVo extends Contacts {
+    private String customName;
+    private String ownerName;
+
+}

+ 8 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/ContactsMapper.java

@@ -1,7 +1,13 @@
 package com.management.platform.mapper;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.management.platform.entity.Contacts;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.vo.ContactsVo;
+import com.management.platform.util.HttpRespMsg;
+
+import java.util.Map;
 
 /**
  * <p>
@@ -13,4 +19,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface ContactsMapper extends BaseMapper<Contacts> {
 
+
+    Page<ContactsVo> pageContacts(Page page, Map<String, Object> map);
 }

+ 7 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/ContactsService.java

@@ -2,6 +2,10 @@ package com.management.platform.service;
 
 import com.management.platform.entity.Contacts;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.vo.ContactsVo;
+import com.management.platform.util.HttpRespMsg;
+
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * <p>
@@ -13,4 +17,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ContactsService extends IService<Contacts> {
 
+    HttpRespMsg addContacts(Contacts contacts, HttpServletRequest request);
+
+    HttpRespMsg pageContacts(Integer pageIndex, Integer pageSize, String customName, String name, String phone, String ownerName, HttpServletRequest request);
 }

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

@@ -1,10 +1,28 @@
 package com.management.platform.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.management.platform.entity.Contacts;
+import com.management.platform.entity.User;
+import com.management.platform.entity.vo.ContactsVo;
 import com.management.platform.mapper.ContactsMapper;
+import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.ContactsService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.util.HttpRespMsg;
+import org.apache.ibatis.annotations.Mapper;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -16,5 +34,55 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class ContactsServiceImpl extends ServiceImpl<ContactsMapper, Contacts> implements ContactsService {
+    @Resource
+    private ContactsMapper contactsMapper;
+    @Resource
+    private UserMapper userMapper;
+
+
+
+    @Override
+    @Transactional
+    public HttpRespMsg addContacts(Contacts contacts, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String token = String.valueOf(request.getHeader("Token"));
+        User user = userMapper.selectById(token);
+        Integer companyId = user.getCompanyId();
+
+        LambdaQueryWrapper<Contacts> lqw_contacts = new LambdaQueryWrapper<>();
+        lqw_contacts.eq(Contacts::getCustomId,contacts.getCustomId()).eq(Contacts::getName,contacts.getName());
+        Contacts selectedOne = contactsMapper.selectOne(lqw_contacts);
+        if (selectedOne!=null){
+            httpRespMsg.setError("已存在该客户!");
+        }
+        contacts.setCompanyId(companyId)
+                .setOwnerId(user.getId())//添加时默认
+                .setIsDelete(0)
+                .setCreateTime(LocalDateTime.now());
+        int insert = contactsMapper.insert(contacts);
+        if (insert<=0){
+            httpRespMsg.setError("添加失败!");
+        }
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg pageContacts(Integer pageIndex, Integer pageSize, String customName, String name, String phone, String ownerName, HttpServletRequest request) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("customName", customName);
+        map.put("name", name);
+        map.put("phone", phone);
+        map.put("ownerName", ownerName);
+        String token = String.valueOf(request.getHeader("Token"));
+        User user = userMapper.selectById(token);
+        map.put("companyId",user.getCompanyId());
+        Page<ContactsVo> pageContacts = contactsMapper.pageContacts(new Page(pageIndex, pageSize), map);
+        List<ContactsVo> contactsVoList = pageContacts.getRecords();
+
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setData(contactsVoList);
+        return msg;
+    }
+
 
 }

+ 7 - 7
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -583,13 +583,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         //返回菜单
         List<SysRoleModule> rModules = sysRoleModuleMapper.selectList(new QueryWrapper<SysRoleModule>().eq("role_id", roleId));
         List<Integer> ids = rModules.stream().map(SysRoleModule::getModuleId).collect(Collectors.toList());
-        //项目报告审核模块,如果参与日报的审核,需要自动加上, 或者担任任务分组负责人
-        if (user.isLeader() || user.isHasAuditDept() || (company.getPackageProject() == 1 && taskGroupMapper.selectCount(new QueryWrapper<TaskGroup>().eq("incharger_id", user.getId())) > 0)) {
-            SysModule projectAuditModule = sysModuleMapper.selectOne(new QueryWrapper<SysModule>().eq("name", "项目报告审核"));
-            if (!ids.contains(projectAuditModule.getId())) {
-                ids.add(projectAuditModule.getId());
-            }
-        }
+//        //项目报告审核模块,如果参与日报的审核,需要自动加上, 或者担任任务分组负责人
+//        if (user.isLeader() || user.isHasAuditDept() || (company.getPackageProject() == 1 && taskGroupMapper.selectCount(new QueryWrapper<TaskGroup>().eq("incharger_id", user.getId())) > 0)) {
+//            SysModule projectAuditModule = sysModuleMapper.selectOne(new QueryWrapper<SysModule>().eq("name", "项目报告审核"));
+//            if (!ids.contains(projectAuditModule.getId())) {
+//                ids.add(projectAuditModule.getId());
+//            }
+//        }
 
         List<SysModule> moduleList = sysModuleMapper.selectList(queryWrapper);
 

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

@@ -17,11 +17,40 @@
         <result column="plate4" property="plate4" />
         <result column="plate5" property="plate5" />
         <result column="is_delete" property="isDelete" />
+        <result column="create_time" property="createTime" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_id, name, custom_id, email, phone, owner_id, plate1, plate2, plate3, plate4, plate5, is_delete
+        id, company_id, name, custom_id, email, phone, owner_id, plate1, plate2, plate3, plate4, plate5, is_delete, create_time
     </sql>
+    <select id="pageContacts" parameterType="java.util.Map"  resultType="com.management.platform.entity.vo.ContactsVo">
+        SELECT c.*, cust.custom_name as customName, own.name as ownerName
+        FROM contacts c
+        LEFT JOIN custom cust ON c.custom_id = cust.id
+        LEFT JOIN user own ON c.owner_id = own.id
+        <where>
+            1=1 and c.is_delete=0
+
+            <if test="map.customName != null and map.customName != ''">
+                AND cust.custom_name LIKE CONCAT('%', #{map.customName}, '%')
+            </if>
+            <if test="map.ownerName != null and map.ownerName != ''">
+                AND own.name LIKE CONCAT('%', #{map.ownerName}, '%')
+            </if>
+            <if test="map.phone != null and map.phone != ''">
+                AND c.phone LIKE CONCAT('%', #{map.phone}, '%')
+            </if>
+            <if test="map.name != null and map.name != ''">
+                AND c.name LIKE CONCAT('%', #{map.name}, '%')
+            </if>
+            <if test="map.companyId != null">
+                AND c.company_id=#{map.companyId}
+            </if>
+        </where>
+        order by create_time desc
+
+    </select>
+
 
 </mapper>

+ 3 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -5621,15 +5621,15 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 											if(auditMsg.contains("提交了")){
 												int i = auditMsg.indexOf("提");
 												String substring = auditMsg.substring(0, i);
-												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
+												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"$\\");
 											}else if(auditMsg.contains("审核通过了")){
 												int i = auditMsg.indexOf("审");
 												String substring = auditMsg.substring(0, i);
-												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
+												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"$\\");
 											}else if(auditMsg.contains("驳回了")) {
 												int i = auditMsg.indexOf("驳");
 												String substring = auditMsg.substring(0, i);
-												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"\\$");
+												msg = time+" " + auditMsg.replace(substring,"\\$userName="+corpwxUserId+"$\\");
 											}
 										} else {
 											msg = time+" " + auditMsg;