Selaa lähdekoodia

提交headers

Lijy 1 vuosi sitten
vanhempi
commit
4d0430c0a6

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

@@ -0,0 +1,127 @@
+<template>
+  <div class=" flex flex-row justify-start items-center text-white flex-1 parentBox" 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">
+    <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";
+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">
+.multipleyHeader {
+  height: 96%;
+  display: flex;
+  align-items: center;
+
+  .headerText {
+    font-size: 16px;
+  }
+}
+.parentBox {
+  max-width: 80%;
+  overflow: hidden;
+}
+</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;

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

@@ -1,9 +1,83 @@
 <template>
-<div id="" class="h100">
-    线索文件
-</div>
+  <div ref="parentDiv" class="parent">
+    <div v-for="(item, index) in items" :key="index" v-show="visibleItems.includes(index)" class="child">
+      {{ item.content }}
+    </div>
+  </div>
 </template>
+
+
 <script setup lang="ts">
+import { ref, onMounted, watchEffect } from 'vue';
+
+// 假设这是你的数据
+const items = ref([
+  { content: 'Item1' },
+  { content: 'Item2' },
+  { content: 'Item3' },
+  { content: 'Item4' },
+  { content: 'Item5' },
+  { content: 'Item6' },
+  { content: 'Item7' },
+  { content: 'Item9' },
+  { content: 'Item10' },
+  { content: 'Item11' },
+  { content: 'Item12' },
+  { content: 'Item13' },
+  // 添加更多项...
+]);
+
+// 用于存储可见项的索引
+const visibleItems = ref<number[]>([]);
+
+// 父div和子div的引用
+const parentDiv = ref<HTMLElement | null>(null);
+
+// 计算并更新可见项
+const updateVisibleItems = () => {
+  if (!parentDiv.value) return;
+  
+  let totalWidth = 0;
+  const children:any = parentDiv.value.children;
+  visibleItems.value = [];
+
+  for (let i = 0; i < children.length; i++) {
+    const childWidth = children[i].offsetWidth + parseInt(getComputedStyle(children[i]).marginRight, 16);
+    
+    // console.log(parentDiv.value.offsetWidth, '<=== parentDiv.value.offsetWidth')
+    // console.log(totalWidth, childWidth, '<=== ')
+
+    if (totalWidth + childWidth > parentDiv.value.offsetWidth) break;
+    
+    totalWidth += childWidth;
+    visibleItems.value.push(i);
+    // console.log('执行语法', visibleItems.value)
+  }
+};
+
+// 组件挂载后和窗口大小改变时更新可见项
+onMounted(() => {
+  updateVisibleItems();
+  window.addEventListener('resize', updateVisibleItems);
+});
+
+watchEffect(() => {
+  updateVisibleItems();
+});
 </script>
-<style scoped lang="scss">
-</style>
+
+
+<style scoped>
+.parent {
+  display: flex;
+  overflow: hidden;
+  width: 100%; /* 可以根据实际情况调整 */
+}
+
+.child {
+  margin-right: 10px; /* 根据实际情况调整 */
+  padding: 5px; /* 根据实际情况调整 */
+  text-wrap: nowrap;
+}
+</style>
+

+ 10 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/store/index.ts

@@ -21,6 +21,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 = {};
+      this.routers = [];
+      this.asyncRoutesMark = false;
+    }
   },
   persist: true, // 是否持久化
 });