Forráskód Böngészése

Merge branch 'tagListModify'

hotchicken1996 1 éve
szülő
commit
17f4e9ba73

+ 1 - 1
client/package.json

@@ -154,4 +154,4 @@
     "node": ">= 16.0.0",
     "pnpm": ">=8.6.0"
   }
-}
+}

+ 5 - 3
client/src/layout/components/TagsView/src/TagsView.vue

@@ -27,7 +27,7 @@ const routers = computed(() => permissionStore.getRouters)
 
 const tagsViewStore = useTagsViewStore()
 
-const visitedViews = computed(() => tagsViewStore.getVisitedViews)
+const visitedViews = computed(() => tagsViewStore.visitedViews)
 
 const affixTagArr = ref<RouteLocationNormalizedLoaded[]>([])
 
@@ -104,8 +104,7 @@ const closeRightTags = () => {
 
 // 跳转到最后一个
 const toLastView = () => {
-  const visitedViews = tagsViewStore.getVisitedViews
-  const latestView = visitedViews.slice(-1)[0]
+  const latestView = unref(visitedViews).slice(-1)[0]
   if (latestView) {
     push(latestView)
   } else {
@@ -525,6 +524,7 @@ $prefix-cls: #{$namespace}-tags-view;
       display: none;
       transform: translate(0, -50%);
     }
+
     &:not(.#{$prefix-cls}__item--affix):hover {
       .#{$prefix-cls}__item--close {
         display: block;
@@ -542,6 +542,7 @@ $prefix-cls: #{$namespace}-tags-view;
     color: var(--el-color-white);
     background-color: var(--el-color-primary);
     border: 1px solid var(--el-color-primary);
+
     .#{$prefix-cls}__item--close {
       :deep(span) {
         color: var(--el-color-white) !important;
@@ -574,6 +575,7 @@ $prefix-cls: #{$namespace}-tags-view;
       color: var(--el-color-white);
       background-color: var(--el-color-primary);
       border: 1px solid var(--el-color-primary);
+
       .#{$prefix-cls}__item--close {
         :deep(span) {
           color: var(--el-color-white) !important;

+ 155 - 125
client/src/store/modules/tagsView.ts

@@ -2,139 +2,169 @@ import router from '@/router'
 import type { RouteLocationNormalizedLoaded } from 'vue-router'
 import { getRawRoute } from '@/utils/routerHelper'
 import { defineStore } from 'pinia'
-import { store } from '../index'
+import { ref, computed } from 'vue'
 import { findIndex } from '@/utils'
 
-export interface TagsViewState {
-  visitedViews: RouteLocationNormalizedLoaded[]
-  cachedViews: Set<string>
+/**
+ * 判断是否为相同路由tag
+ * 判断path同时根据query确定是否相同(兼容详情页多开)
+ * @param currentTag
+ * @param TargetTag
+ */
+export const isSameRouteTag = (
+  currentTag: RouteLocationNormalizedLoaded,
+  TargetTag: RouteLocationNormalizedLoaded
+): boolean => {
+  return currentTag.fullPath === TargetTag.fullPath
 }
 
-export const useTagsViewStore = defineStore('tagsView', {
-  state: (): TagsViewState => ({
-    visitedViews: [],
-    cachedViews: new Set()
-  }),
-  getters: {
-    getVisitedViews(): RouteLocationNormalizedLoaded[] {
-      return this.visitedViews
-    },
-    getCachedViews(): string[] {
-      return Array.from(this.cachedViews)
-    }
-  },
-  actions: {
-    // 新增缓存和tag
-    addView(view: RouteLocationNormalizedLoaded): void {
-      this.addVisitedView(view)
-      this.addCachedView()
-    },
-    // 新增tag
-    addVisitedView(view: RouteLocationNormalizedLoaded) {
-      if (this.visitedViews.some((v) => v.path === view.path)) return
-      if (view.meta?.noTagsView) return
-      this.visitedViews.push(
-        Object.assign({}, view, {
-          title: view.meta?.title || 'no-name'
-        })
-      )
-    },
-    // 新增缓存
-    addCachedView() {
-      const cacheMap: Set<string> = new Set()
-      for (const v of this.visitedViews) {
-        const item = getRawRoute(v)
-        const needCache = !item.meta?.noCache
-        if (!needCache) {
-          continue
-        }
-        const name = item.name as string
-        cacheMap.add(name)
-      }
-      if (Array.from(this.cachedViews).sort().toString() === Array.from(cacheMap).sort().toString())
-        return
-      this.cachedViews = cacheMap
-    },
-    // 删除某个
-    delView(view: RouteLocationNormalizedLoaded) {
-      this.delVisitedView(view)
-      this.delCachedView()
-    },
-    // 删除tag
-    delVisitedView(view: RouteLocationNormalizedLoaded) {
-      for (const [i, v] of this.visitedViews.entries()) {
-        if (v.path === view.path) {
-          this.visitedViews.splice(i, 1)
-          break
-        }
-      }
-    },
-    // 删除缓存
-    delCachedView() {
-      const route = router.currentRoute.value
-      const index = findIndex<string>(this.getCachedViews, (v) => v === route.name)
-      if (index > -1) {
-        this.cachedViews.delete(this.getCachedViews[index])
-      }
-    },
-    // 删除所有缓存和tag
-    delAllViews() {
-      this.delAllVisitedViews()
-      this.delCachedView()
-    },
-    // 删除所有tag
-    delAllVisitedViews() {
-      // const affixTags = this.visitedViews.filter((tag) => tag.meta.affix)
-      this.visitedViews = []
-    },
-    // 删除其他
-    delOthersViews(view: RouteLocationNormalizedLoaded) {
-      this.delOthersVisitedViews(view)
-      this.addCachedView()
-    },
-    // 删除其他tag
-    delOthersVisitedViews(view: RouteLocationNormalizedLoaded) {
-      this.visitedViews = this.visitedViews.filter((v) => {
-        return v?.meta?.affix || v.path === view.path
+/**
+ * 头部tab导航栏store
+ */
+export const useTagsViewStore = defineStore('tagsView', () => {
+  const visitedViews = ref<RouteLocationNormalizedLoaded[]>([])
+  const cachedViews = ref<Set<string>>(new Set())
+  const getCachedViews = computed(() => {
+    return Array.from(cachedViews.value)
+  })
+
+  // 新增缓存和tag
+  const addView = (view: RouteLocationNormalizedLoaded): void => {
+    addVisitedView(view)
+    addCachedView()
+  }
+
+  // 重置缓存和tag(用于tag排序)
+  const allResetView = (views: RouteLocationNormalizedLoaded[]): void => {
+    visitedViews.value = views
+    addCachedView()
+  }
+
+  // 新增tag
+  const addVisitedView = (view: RouteLocationNormalizedLoaded): void => {
+    if (unref(visitedViews).some((v) => isSameRouteTag(v, view))) return
+    if (view.meta?.noTagsView) return
+    visitedViews.value.push(
+      Object.assign({}, view, {
+        title: view.meta?.title || 'no-name'
       })
-    },
-    // 删除左侧
-    delLeftViews(view: RouteLocationNormalizedLoaded) {
-      const index = findIndex<RouteLocationNormalizedLoaded>(
-        this.visitedViews,
-        (v) => v.path === view.path
-      )
-      if (index > -1) {
-        this.visitedViews = this.visitedViews.filter((v, i) => {
-          return v?.meta?.affix || v.path === view.path || i > index
-        })
-        this.addCachedView()
+    )
+  }
+
+  // 新增缓存
+  const addCachedView = (): void => {
+    const cacheMap: Set<string> = new Set()
+    for (const v of unref(visitedViews)) {
+      const item = getRawRoute(v)
+      const needCache = !item.meta?.noCache
+      if (!needCache) {
+        continue
       }
-    },
-    // 删除右侧
-    delRightViews(view: RouteLocationNormalizedLoaded) {
-      const index = findIndex<RouteLocationNormalizedLoaded>(
-        this.visitedViews,
-        (v) => v.path === view.path
-      )
-      if (index > -1) {
-        this.visitedViews = this.visitedViews.filter((v, i) => {
-          return v?.meta?.affix || v.path === view.path || i < index
-        })
-        this.addCachedView()
+      const name = item.name as string
+      cacheMap.add(name)
+    }
+    if (Array.from(visitedViews.value).sort().toString() === Array.from(cacheMap).sort().toString())
+      return
+    cachedViews.value = cacheMap
+  }
+
+  // 更新某tag
+  const updateVisitedView = (view: RouteLocationNormalizedLoaded): void => {
+    for (let v of unref(visitedViews)) {
+      if (v.path === view.path) {
+        v = Object.assign(v, view)
+        break
       }
-    },
-    updateVisitedView(view: RouteLocationNormalizedLoaded) {
-      for (let v of this.visitedViews) {
-        if (v.path === view.path) {
-          v = Object.assign(v, view)
-          break
-        }
+    }
+  }
+
+  // 删除某个
+  const delView = (view: RouteLocationNormalizedLoaded): void => {
+    delVisitedView(view)
+    delCachedView()
+  }
+
+  // 删除tag
+  const delVisitedView = (view: RouteLocationNormalizedLoaded): void => {
+    for (const [i, v] of unref(visitedViews).entries()) {
+      if (v.path === view.path) {
+        visitedViews.value.splice(i, 1)
+        break
       }
     }
   }
-})
 
-export const useTagsViewStoreWithOut = () => {
-  return useTagsViewStore(store)
-}
+  // 删除缓存
+  const delCachedView = (): void => {
+    const route = router.currentRoute.value
+    const index = findIndex<string>(unref(getCachedViews), (v) => v === route.name)
+    if (index > -1) {
+      cachedViews.value.delete(unref(getCachedViews)[index])
+    }
+  }
+
+  // 删除所有缓存和tag
+  const delAllViews = (): void => {
+    delAllVisitedViews()
+    delCachedView()
+  }
+
+  // 删除所有tag
+  const delAllVisitedViews = (): void => {
+    // const affixTags = this.visitedViews.filter((tag) => tag.meta.affix)
+    visitedViews.value = []
+  }
+
+  // 删除多个标签方法
+  const delVisitedViews = (
+    view: RouteLocationNormalizedLoaded,
+    type: 'other' | 'left' | 'right'
+  ): void => {
+    const index = findIndex<RouteLocationNormalizedLoaded>(
+      unref(visitedViews),
+      (v) => v.path === view.path
+    )
+    visitedViews.value = visitedViews.value.filter((v, i) => {
+      return (
+        v?.meta?.affix ||
+        isSameRouteTag(unref(v), view) ||
+        (type === 'other' ? false : type === 'left' ? i > index : i < index)
+      )
+    })
+    addCachedView()
+  }
+
+  // 删除其他
+  const delOthersViews = (view: RouteLocationNormalizedLoaded): void => {
+    delVisitedViews(view, 'other')
+  }
+
+  // 删除左侧
+  const delLeftViews = (view: RouteLocationNormalizedLoaded): void => {
+    delVisitedViews(view, 'left')
+  }
+
+  // 删除右侧
+  const delRightViews = (view: RouteLocationNormalizedLoaded): void => {
+    delVisitedViews(view, 'right')
+  }
+
+  return {
+    visitedViews,
+    cachedViews,
+    getCachedViews,
+    addView,
+    allResetView,
+    addVisitedView,
+    addCachedView,
+    updateVisitedView,
+    delView,
+    delVisitedView,
+    delCachedView,
+    delAllViews,
+    delAllVisitedViews,
+    delOthersViews,
+    delLeftViews,
+    delRightViews
+  }
+})

+ 211 - 183
client/src/views/OaSystem/oaLayout/tagList.vue

@@ -1,109 +1,130 @@
 <template>
   <div class="_tagList">
     <div class="tag-view">
-      <ul>
-        <ContextMenu
-          :ref="itemRefs.set"
-          :schema="[
-            {
-              icon: 'ep:refresh',
-              label: t('common.reload'),
-              disabled: selectedTag?.fullPath !== item.fullPath,
-              command: () => {
-                refreshSelectedTag(item)
+      <draggable
+        class="tags-draggable-list"
+        v-model="visitedViews"
+        item-key="fullPath"
+        ghost-class="draggable-ghost"
+        filter=".unDrag"
+        @end="onDragEnd"
+        :animation="400"
+      >
+        <template #item="{ element: item, index }">
+          <ContextMenu
+            :ref="itemRefs.set"
+            :schema="[
+              {
+                icon: 'ep:refresh',
+                label: t('common.reload'),
+                disabled: selectedTag?.fullPath !== item.fullPath,
+                command: () => {
+                  refreshSelectedTag(item)
+                }
+              },
+              {
+                icon: 'ep:close',
+                label: t('common.closeTab'),
+                disabled: (!!visitedViews?.length && selectedTag?.meta.affix) || index === 0,
+                command: () => {
+                  closeSelectedTag(item)
+                }
+              },
+              {
+                divided: true,
+                icon: 'ep:d-arrow-left',
+                label: t('common.closeTheLeftTab'),
+                disabled:
+                  !!visitedViews?.length &&
+                  (item.fullPath === visitedViews[0].fullPath ||
+                    selectedTag?.fullPath !== item.fullPath),
+                command: () => {
+                  closeLeftTags()
+                }
+              },
+              {
+                icon: 'ep:d-arrow-right',
+                label: t('common.closeTheRightTab'),
+                disabled:
+                  !!visitedViews?.length &&
+                  (item.fullPath === visitedViews[visitedViews.length - 1].fullPath ||
+                    selectedTag?.fullPath !== item.fullPath),
+                command: () => {
+                  closeRightTags()
+                }
+              },
+              {
+                divided: true,
+                icon: 'ep:discount',
+                label: t('common.closeOther'),
+                disabled: selectedTag?.fullPath !== item.fullPath,
+                command: () => {
+                  closeOthersTags()
+                }
               }
-            },
-            {
-              icon: 'ep:close',
-              label: t('common.closeTab'),
-              disabled: !!visitedViews?.length && selectedTag?.meta.affix,
-              command: () => {
-                closeSelectedTag(item)
+            ]"
+            :tag-item="item"
+            :class="[
+              'tag-body',
+              `${prefixCls}__item`,
+              item?.meta?.affix ? `${prefixCls}__item--affix unDrag` : '',
+              {
+                'is-route-tag-active': isActive(item)
               }
-            },
-            {
-              divided: true,
-              icon: 'ep:d-arrow-left',
-              label: t('common.closeTheLeftTab'),
-              disabled:
-                !!visitedViews?.length &&
-                (item.fullPath === visitedViews[0].fullPath ||
-                  selectedTag?.fullPath !== item.fullPath),
-              command: () => {
-                closeLeftTags()
-              }
-            },
-            {
-              icon: 'ep:d-arrow-right',
-              label: t('common.closeTheRightTab'),
-              disabled:
-                !!visitedViews?.length &&
-                (item.fullPath === visitedViews[visitedViews.length - 1].fullPath ||
-                  selectedTag?.fullPath !== item.fullPath),
-              command: () => {
-                closeRightTags()
-              }
-            },
-            {
-              divided: true,
-              icon: 'ep:discount',
-              label: t('common.closeOther'),
-              disabled: selectedTag?.fullPath !== item.fullPath,
-              command: () => {
-                closeOthersTags()
-              }
-            }
-          ]"
-          v-for="(item, index) in visitedViews"
-          :key="index"
-          :tag-item="item"
-          :class="[
-            `${prefixCls}__item`,
-            item?.meta?.affix ? `${prefixCls}__item--affix` : '',
-            {
-              'is-active': isActive(item)
-            }
-          ]"
-          @visible-change="visibleChange"
-        >
-          <li>
-            <router-link :to="{ ...item }" exact v-slot="{ navigate }" v-if="index == 0">
+            ]"
+            @visible-change="visibleChange"
+          >
+            <router-link :to="{ ...item }" exact v-slot="{ navigate }" v-if="index === 0">
               <div class="homeBox" @click="navigate">
-                <div @click="tagsHomeClick()" class="tagsFlex">
-                  <Icon :icon="item.meta.icon || ''" />
-                  <p>{{ item.meta.title }}</p>
-                </div>
+                <Icon :icon="item.meta.icon || ''" :size="18" />
+                <p>{{ item.meta.title }}</p>
               </div>
             </router-link>
             <router-link :to="{ ...item }" exact v-slot="{ navigate }" v-else>
               <div class="fhomeBox" @click="navigate">
-                <div class="tagsFlex">
-                  <div class="pBox">
-                    <p>{{ item.meta.title }}</p>
-                  </div>
-                  <div @click.stop.prevent="closeSelectedTag(item)" class="close">
-                    <span>×</span>
-                  </div>
+                <div class="pBox">
+                  <el-tooltip
+                    effect="dark"
+                    :content="`${item.meta.title}${(item?.query?.name ?? '') !== '' ? `( ${item?.query?.name} )` : ''}`"
+                    placement="top-start"
+                  >
+                    <p>
+                      {{ item.meta.title }}
+                      <!-- 用于多开页面的区分展示(例如详情页)-->
+                      {{ (item?.query?.name ?? '') !== '' ? `(${item?.query?.name})` : '' }}
+                    </p>
+                  </el-tooltip>
+                </div>
+                <div @click.stop.prevent="closeSelectedTag(item)" class="close">
+                  <span>×</span>
                 </div>
               </div>
             </router-link>
-          </li>
-        </ContextMenu>
-      </ul>
+          </ContextMenu>
+        </template>
+      </draggable>
+      <div v-if="(visitedViews?.length ?? 0) > 1" class="all-tags-close" @click="allTagsClose">
+        关闭全部
+      </div>
     </div>
   </div>
 </template>
 <script setup lang="ts">
+import 'vuedraggable'
+import { computed, onMounted, nextTick, ref, watch } from 'vue'
 import { Icon } from '@/components/Icon'
 import type { RouteLocationNormalizedLoaded } from 'vue-router'
 import { useRouter } from 'vue-router'
 import { usePermissionStore } from '@/store/modules/permission'
-import { useTagsViewStore } from '@/store/modules/tagsView'
+import { isSameRouteTag, useTagsViewStore } from '@/store/modules/tagsView'
 import { filterAffixTags } from './helper'
 import { useTemplateRefsList } from '@vueuse/core'
 import { ContextMenu, ContextMenuExpose } from '@/layout/components/ContextMenu'
 import { useI18n } from '@/hooks/web/useI18n'
 import { useDesign } from '@/hooks/web/useDesign'
+import draggable from 'vuedraggable'
+
+const router = useRouter()
 const { getPrefixCls } = useDesign()
 const prefixCls = getPrefixCls('tags-view')
 const { t } = useI18n()
@@ -115,8 +136,11 @@ const tagsViewStore = useTagsViewStore()
 const affixTagArr = ref<RouteLocationNormalizedLoaded[]>([])
 // 所有右键菜单组件的元素
 const itemRefs = useTemplateRefsList<ComponentRef<typeof ContextMenu & ContextMenuExpose>>()
-const visitedViews = computed(() => tagsViewStore.getVisitedViews)
 
+const visitedViews = computed({
+  get: () => tagsViewStore.visitedViews,
+  set: (views) => tagsViewStore.allResetView(views)
+})
 // 初始化tag
 const initTags = () => {
   affixTagArr.value = filterAffixTags(unref(routers))
@@ -165,7 +189,7 @@ const closeLeftTags = () => {
 const closeRightTags = () => {
   tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
 }
-const tagsHomeClick = () => {}
+
 // 新增tag
 const addTags = () => {
   const { name } = unref(currentRoute)
@@ -186,13 +210,12 @@ const closeSelectedTag = (view: RouteLocationNormalizedLoaded) => {
 
 // 是否是当前tag
 const isActive = (route: RouteLocationNormalizedLoaded): boolean => {
-  return route.path === unref(currentRoute).path
+  return isSameRouteTag(route, unref(currentRoute))
 }
 
 // 跳转到最后一个
 const toLastView = () => {
-  const visitedViews = tagsViewStore.getVisitedViews
-  const latestView = visitedViews.slice(-1)[0]
+  const latestView = unref(visitedViews).slice(-1)[0]
   if (latestView) {
     push(latestView)
   } else {
@@ -208,6 +231,20 @@ const toLastView = () => {
   }
 }
 
+// 关闭全部标签
+const allTagsClose = (): void => {
+  visitedViews.value = [unref(visitedViews)[0]]
+  router.replace('/home')
+}
+
+// 拖拽结束事件
+const onDragEnd = (event): void => {
+  // 不允许拖拽到第一项
+  if (event.newIndex === 0) {
+    unref(visitedViews)[0] = unref(visitedViews).splice(1, 1, unref(visitedViews)[0])[0]
+  }
+}
+
 watch(
   () => currentRoute.value,
   () => {
@@ -221,144 +258,135 @@ onMounted(() => {
 })
 </script>
 <style lang="scss" scoped>
-div,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-p,
-ul,
-li {
-  box-sizing: border-box;
-}
 ._tagList {
   width: 100%;
-  height: 36px;
+  padding: 0 12px;
+  height: 54px;
+  background: rgba(255, 255, 255, 0.6);
+  border-radius: 20px;
   display: flex;
   align-items: center;
-  background: rgba(255, 255, 255, 1);
-  border-radius: 10px;
+  color: #2d333c;
+
   .tag-view {
+    display: flex;
+    align-items: center;
     width: 100%;
     height: 100%;
-    ul {
-      width: 100%;
+    padding-right: 10px;
+
+    .tags-draggable-list {
+      width: calc(100% - 64px);
       height: 100%;
       display: flex;
       align-items: center;
-      li {
-        height: 100%;
-        cursor: pointer;
+
+      .tag-body {
+        min-width: 60px;
+        margin-right: 12px;
+
+        &:hover {
+          p,
+          .el-icon {
+            color: #2e77e6;
+          }
+        }
+
+        &.v-tags-view__item--affix {
+          flex-shrink: 0;
+        }
+
         a {
-          display: block;
-          width: auto;
-          height: 100%;
-          border-radius: 10px;
+          width: 100%;
           color: inherit;
           text-decoration: none;
-          padding: 2px;
-          box-sizing: border-box;
         }
-        .homeBox {
-          width: 70px;
-          height: 16px;
+
+        &.is-route-tag-active {
+          .homeBox,
+          .fhomeBox {
+            border: 2px solid #2e77e6;
+
+            p,
+            .el-icon,
+            .close {
+              color: #2e77e6;
+            }
+          }
+        }
+
+        .homeBox,
+        .fhomeBox {
+          height: 42px;
+          padding: 0 20px;
+          background: #eaf0f8;
+          border-radius: 16px;
           opacity: 1;
           display: flex;
           align-items: center;
           justify-content: center;
-          .tagsFlex {
-            width: 100%;
-            height: 100%;
+
+          .el-icon {
+            margin-right: 5px;
+          }
+
+          p {
+            font-size: 17px;
+          }
+
+          .close {
             display: flex;
             align-items: center;
             justify-content: center;
-          }
-          p {
+            flex-shrink: 0;
             margin-left: 5px;
-            font-size: 16px;
+            font-weight: 200;
+            font-size: 24px;
+
+            &:hover {
+              color: #2e77e6;
+            }
           }
         }
+
         .fhomeBox {
-          height: 16px;
-          display: flex;
-          align-items: center;
+          padding-right: 18px;
           justify-content: space-between;
-          padding: 0 15px;
-          border-right: 2px solid rgb(209, 197, 197);
-          .tagsFlex {
-            width: 100%;
-            height: 100%;
-            display: flex;
-            align-items: center;
-            justify-content: space-between;
-          }
+
           .pBox {
+            width: calc(100% - 17px);
             display: flex;
             align-items: center;
             justify-content: center;
+
             p {
-              font-size: 16px;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              white-space: nowrap;
             }
           }
-          .close {
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            width: 12px;
-            height: 12px;
-            background-color: #878b91;
-            border-radius: 50%;
-            margin-left: 10px;
-            span {
-              color: #fff;
-            }
-          }
-          img {
-            cursor: pointer;
-            margin-top: 4px;
-            display: block;
-          }
         }
       }
     }
-  }
-}
 
-::v-deep .router-link-active {
-  // border: 2px solid #2e77e6;
-  p {
-    color: #2e77e6;
-    font-weight: 600;
-  }
-  .el-icon {
-    color: #2e77e6;
-  }
-  .close {
-    background-color: #2e77e6 !important;
-  }
-}
-
-.el-dropdown:hover {
-  p {
-    color: #2e77e6;
-    font-weight: 600;
-  }
-}
+    .all-tags-close {
+      flex-shrink: 0;
+      font-size: 17px;
+      font-weight: 400;
+      color: #121518;
+      cursor: pointer;
 
-.tag-view {
-  ul {
-    .el-dropdown:nth-child(2) {
-      .fhomeBox {
-        border-left: 2px solid rgb(209, 197, 197);
-      }
-    }
-    .el-dropdown:last-child {
-      .fhomeBox {
-        border-right: 0;
+      &:hover {
+        color: #2e77e6;
       }
     }
   }
 }
+
+.draggable-ghost {
+  background: #f7fafc;
+  border: 1px solid #2e77e6;
+  border-radius: 16px;
+  opacity: 0.5;
+}
 </style>

+ 5 - 5
client/src/views/OaSystem/projectCenter/projectBook/myProject.vue

@@ -74,12 +74,12 @@
         <div class="btnBox">
           <el-button type="primary" style="background: #3485ff" @click="searchHandle">
             <img src="@/assets/imgs/OA/search.png" class="mr-8px" alt="" />
-            查询</el-button
-          >
+            查询
+          </el-button>
           <el-button type="primary">
             <img src="@/assets/imgs/OA/open.png" class="mr-8px" alt="" />
-            导出</el-button
-          >
+            导出
+          </el-button>
         </div>
       </div>
     </div>
@@ -219,7 +219,7 @@ const handleCurrentChange = (pageNo: number) => {
 const operateClick = (row: any) => {
   router.push({
     path: 'projectDetail',
-    query: { id: row.id }
+    query: { id: row.id, name: row.xmmc }
   })
 }
 const tableData = ref<Array<any>>([])