YM
2024-04-17 1ed69aab3d1c57f5096f57c8d77b396b0c5babe4
menu调整
5个文件已修改
7个文件已添加
546 ■■■■■ 已修改文件
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/header/top-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/menu/biaoqian.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/menu/biji.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/menu/jietu.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/menu/mulu.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/menu/zhishitupu.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/menu/ziyuan.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/main.css 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/layout.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home.vue 381 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -30,6 +30,7 @@
    "moment": "^2.29.4",
    "node-xlsx": "^0.23.0",
    "pinia": "^2.1.7",
    "qiankun": "^2.10.16",
    "style-resources-loader": "^1.5.0",
    "vite-plugin-electron": "^0.15.5",
    "vue": "^3.3.10",
src/assets/images/header/top-bg.png
src/assets/images/menu/biaoqian.png
src/assets/images/menu/biji.png
src/assets/images/menu/jietu.png
src/assets/images/menu/mulu.png
src/assets/images/menu/zhishitupu.png
src/assets/images/menu/ziyuan.png
src/assets/main.css
@@ -5,7 +5,23 @@
  height: 100%;
}
page {
  display: block;
}
}
.imgBox {
  position: relative;
}
.imgBox img {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  margin: auto;
}
src/layout/layout.vue
@@ -1,115 +1,17 @@
<template>
  <div class="layoutBox">
    <div class="menuBox">
      <div :class="['menuItem', activeMenu == index ? 'active' : '']" v-for="(item, index) in menuData" :key="index"
        @click="menuItemClick(index)">
        <div class="menuIcon">
          <el-icon v-if="item.icon == 'FolderOpened'" :size="24">
            <FolderOpened />
          </el-icon>
          <el-icon v-if="item.icon == 'Files'" :size="24">
            <Files />
          </el-icon>
          <el-icon v-if="item.icon == 'Switch'" :size="24">
            <Switch />
          </el-icon>
          <el-icon v-if="item.icon == 'Setting'" :size="24">
            <Setting />
          </el-icon>
        </div>
        <p>{{ item.name }}</p>
      </div>
    </div>
    <div class="pageBox">
      <RouterView />
    </div>
    <RouterView />
  </div>
</template>
<script setup lang="ts">
  import { ref, reactive, watch } from 'vue'
  import { useRouter, RouterView } from 'vue-router'
  const router = useRouter()
  // 菜单
  const menuData = reactive([
    // {
    //   name: '文件',
    //   icon: 'FolderOpened',
    //   router: '/home'
    // },
    {
      name: '传输',
      icon: 'Switch',
      router: '/transmission'
    },
    // {
    //   name: '导出',
    //   icon: 'Files',
    //   router: '/exportTask'
    // },
    {
      name: '设置',
      icon: 'Setting',
      router: '/setting'
    }
  ])
  // 选中菜单
  const activeMenu = ref(0)
  // 监听路由变化,默认选中菜单
  watch(
    () => router.currentRoute.value, (newRoute) => {
      console.log(newRoute.path)
      const index = menuData.findIndex((item) => item.router == newRoute.path)
      activeMenu.value = index > -1 ? index : 0
    }
  )
  // 菜单点击
  const menuItemClick = (index) => {
    activeMenu.value = index
    router.push(menuData[index].router)
  }
import { ref, reactive, watch } from 'vue'
import { useRouter, RouterView } from 'vue-router'
</script>
<style lang="less">
  .layoutBox {
    width: 100%;
    height: 100%;
    display: flex;
    .menuBox {
      width: 80px;
      background-color: #f5f5f6;
      border-right: 1px solid #e6e7e8;
      padding: 10px;
      box-sizing: border-box;
      .menuItem {
        padding: 8px 0;
        text-align: center;
        border-radius: 8px;
        line-height: 1;
        cursor: pointer;
        margin-bottom: 10px;
        &.active,
        &:hover {
          background-color: #e3e3e5;
        }
        .menuIcon {
          margin-bottom: 4px;
        }
      }
    }
    .pageBox {
      flex: 1;
      overflow: auto;
    }
  }
</style>
.layoutBox {
  width: 100%;
  height: 100%;
}
</style>
src/router/index.ts
@@ -1,8 +1,6 @@
import { createRouter, createWebHashHistory } from 'vue-router'
import Layout from '@/layout/layout.vue'
const Transmission = () => import('@/views/transmission.vue')
const ExportTask = () => import('@/views/exportTask.vue')
const Setting = () => import('@/views/setting.vue')
const Home = () => import('@/views/home.vue')
const Login = () => import('@/views/login.vue')
const router = createRouter({
@@ -10,7 +8,7 @@
  routes: [
    {
      path: '/',
      redirect: 'transmission'
      redirect: 'home'
    },
    {
      path: '/login',
@@ -21,29 +19,11 @@
      path: '/',
      component: Layout,
      children: [
        // {
        //   path: '/home',
        //   name: 'home',
        //   meta: { auth: true },
        //   component: Home
        // },
        {
          path: '/transmission',
          name: 'transmission',
          path: '/home',
          name: 'home',
          meta: { auth: true },
          component: Transmission
        },
        {
          path: '/exportTask',
          name: 'exportTask',
          meta: { auth: true },
          component: ExportTask
        },
        {
          path: '/setting',
          name: 'setting',
          meta: { auth: true },
          component: Setting
          component: Home
        }
      ]
    }
src/views/home.vue
@@ -1,281 +1,176 @@
<template>
  <div class="homeBox">
    <div class="herderBox">
      <p>文件</p>
      <div class="viewChangeBox">
        <el-icon :size="16" v-if="viewMode == 0" @click="setViewMode"><Calendar /></el-icon>
        <el-icon :size="16" v-if="viewMode == 1" @click="setViewMode"><Menu /></el-icon>
      </div>
      <div class="search">
        <el-input v-model="searchKey" size="small" placeholder="关键字搜索">
          <template #append>
            <el-button :icon="Search" />
          </template>
        </el-input>
      </div>
    <div class="headerBox">
      <p>数字教材平台</p>
    </div>
    <div class="toolBox">
      <div class="checkBox" v-if="viewMode == 0">
        <el-checkbox
          v-model="checkBoxState.check"
          :indeterminate="checkBoxState.indeterminate"
          @change="handleCheckAllChange"
        />
        <span class="checkText">{{
          checkBoxState.selectCount > 0
            ? `已选 ${checkBoxState.selectCount} 项`
            : `共 ${checkBoxState.totalCount} 项`
        }}</span>
      </div>
      <div class="sortBox" v-if="viewMode == 0">
        <el-dropdown trigger="click" @command="sortChange">
          <span class="sortText">
            <el-icon :size="16"><Sort /></el-icon>
            <span>
              按{{ sortState.fields[sortState.selectFieldIndex].name
              }}{{ sortState.types[sortState.selectTypeIndex].name }}排序
            </span>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item
                v-for="(item, index) in sortState.fields"
                :key="item.value"
                :command="'fields.' + item.value"
              >
                <p>
                  <span>
                    <el-icon v-if="sortState.selectFieldIndex == index" :size="16" color="#409EFF">
                      <Check />
                    </el-icon>
                  </span>
                  <span>{{ item.name }}</span>
                </p>
              </el-dropdown-item>
              <el-dropdown-item
                v-for="(item, index) in sortState.types"
                :key="item.value"
                :divided="index == 0"
                :command="'types.' + item.value"
              >
                <p>
                  <span>
                    <el-icon v-if="sortState.selectTypeIndex == index" :size="16" color="#409EFF">
                      <Check />
                    </el-icon>
                  </span>
                  <span>{{ item.name }}</span>
                </p>
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </div>
    <div class="fileList">
      <div v-if="viewMode == 0" class="blockBox">
        <div class="fileItem" v-for="item in tableData">
          <div class="iconBox">
            <img :src="item.img" alt="" />
    <div class="contentBox">
      <div class="menuBox">
        <div
          :class="['menuItem', activeMenu == index ? 'active' : '']"
          v-for="(item, index) in menuData"
          :key="index"
          @click="menuItemClick(index)"
        >
          <div class="menuIcon imgBox">
            <img :src="item.icon" />
          </div>
          <p class="name">{{ item.name }}</p>
          <p class="time">{{ item.createDate }}</p>
          <p>{{ item.name }}</p>
        </div>
      </div>
      <el-table v-if="viewMode == 1" :data="tableData" style="width: 100%">
        <el-table-column type="selection" width="55" />
        <el-table-column type="index" width="80" />
        <el-table-column prop="name" label="名称" sortable />
        <el-table-column prop="createDate" label="创建时间" width="200" sortable />
        <el-table-column prop="size" label="大小" width="200" sortable />
      </el-table>
      <div class="pageBox"></div>
      <div class="toolBox">
        <el-menu default-active="2" :collapse="isCollapse" @open="handleOpen" @close="handleClose">
          <el-sub-menu index="1">
            <template #title>
              <el-icon><location /></el-icon>
              <span>Navigator One</span>
            </template>
            <el-menu-item-group>
              <template #title><span>Group One</span></template>
              <el-menu-item index="1-1">item one</el-menu-item>
              <el-menu-item index="1-2">item two</el-menu-item>
            </el-menu-item-group>
            <el-menu-item-group title="Group Two">
              <el-menu-item index="1-3">item three</el-menu-item>
            </el-menu-item-group>
            <el-sub-menu index="1-4">
              <template #title><span>item four</span></template>
              <el-menu-item index="1-4-1">item one</el-menu-item>
            </el-sub-menu>
          </el-sub-menu>
          <el-menu-item index="2">
            <el-icon><icon-menu /></el-icon>
            <template #title>Navigator Two</template>
          </el-menu-item>
          <el-menu-item index="3" disabled>
            <el-icon><document /></el-icon>
            <template #title>Navigator Three</template>
          </el-menu-item>
          <el-menu-item index="4">
            <el-icon><setting /></el-icon>
            <template #title>Navigator Four</template>
          </el-menu-item>
        </el-menu>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { Search, Check } from '@element-plus/icons-vue'
import { useRouter, RouterView } from 'vue-router'
const router = useRouter()
import { ref, reactive, watch } from 'vue'
import mulu from '@/assets/images/menu/mulu.png'
import biji from '@/assets/images/menu/biji.png'
import ziyuan from '@/assets/images/menu/ziyuan.png'
import zhishitupu from '@/assets/images/menu/zhishitupu.png'
import jietu from '@/assets/images/menu/jietu.png'
import biaoqian from '@/assets/images/menu/biaoqian.png'
import topbg from '@/assets/images/header/top-bg.png'
// 搜索
const searchKey = ref('')
// 选择框
const checkBoxState = reactive({
  selectCount: 0,
  totalCount: 0,
  check: false,
  indeterminate: false
})
const handleCheckAllChange = (val) => {
  if (val) {
    checkBoxState.check = true
  } else {
    checkBoxState.check = false
// 菜单
const menuData = reactive([
  {
    name: '目录',
    icon: mulu
  },
  {
    name: '笔记',
    icon: biji
  },
  {
    name: '资源',
    icon: ziyuan
  },
  {
    name: '知识图谱',
    icon: zhishitupu
  },
  {
    name: '截图',
    icon: jietu
  },
  {
    name: '标签',
    icon: biaoqian
  }
  checkBoxState.indeterminate = false
])
// 选中菜单
const activeMenu = ref(0)
// // 监听路由变化,默认选中菜单
// watch(
//   () => router.currentRoute.value,
//   (newRoute) => {
//     console.log(newRoute.path)
//     const index = menuData.findIndex((item) => item.router == newRoute.path)
//     activeMenu.value = index > -1 ? index : 0
//   }
// )
// 菜单点击
const menuItemClick = (index) => {
  activeMenu.value = index
}
// 排序
const sortState = reactive({
  fields: [
    {
      name: '名称',
      value: 'Name'
    },
    {
      name: '创建时间',
      value: 'CreateDate'
    },
    {
      name: '文件大小',
      value: 'Size'
    }
  ],
  types: [
    {
      name: '升序',
      value: 'Asc'
    },
    {
      name: '降序',
      value: 'Desc'
    }
  ],
  selectFieldIndex: 1,
  selectTypeIndex: 1
})
const sortChange = (command) => {
  const type = command.split('.')[0]
  const data = command.split('.')[1]
  if (type == 'fields') {
    sortState.selectFieldIndex = sortState.fields.findIndex((item) => item.value == data)
  } else {
    sortState.selectTypeIndex = sortState.types.findIndex((item) => item.value == data)
  }
}
// 视图模式 0:块状视图  1:表格视图
const viewMode = ref(0)
const setViewMode = () => {
  if (viewMode.value == 0) {
    viewMode.value = 1
  } else {
    viewMode.value = 0
  }
}
// 文件列表
const tableData = ref([])
// 右侧工具
const isCollapse = ref(false)
</script>
<style lang="less">
.homeBox {
  width: 100%;
  height: 100%;
  padding: 50px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  .herderBox {
    overflow: hidden;
    margin-bottom: 20px;
  .headerBox {
    height: 48px;
    background-image: url('@/assets/images/header/top-bg.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    padding: 0 20px;
    line-height: 48px;
    p {
      float: left;
      font-size: 20px;
      font-size: 24px;
      color: #ffffff;
      letter-spacing: 2px;
      font-weight: bold;
      line-height: 32px;
    }
    .search {
      float: right;
      margin-right: 20px;
    }
    .viewChangeBox {
      float: right;
      line-height: 32px;
      i {
        cursor: pointer;
        vertical-align: sub;
      }
    }
  }
  .toolBox {
  .contentBox {
    overflow: hidden;
    margin-bottom: 10px;
    line-height: 32px;
    .checkBox {
      float: left;
      .checkText {
        display: inline-block;
        line-height: 32px;
        vertical-align: top;
        margin-left: 8px;
      }
    }
    .sortBox {
      float: right;
      .sortText {
        width: 150px;
        line-height: 32px;
        cursor: pointer;
        i,
        span {
          vertical-align: middle;
        }
      }
    }
  }
  .fileList {
    flex: 1;
    overflow: auto;
    .blockBox {
      overflow: hidden;
      .fileItem {
        width: 140px;
        float: left;
        margin: 20px;
        padding: 15px;
        border-radius: 10px;
        cursor: context-menu;
    display: flex;
    .menuBox {
      width: 80px;
      border-right: 1px solid #e6e7e8;
      padding-bottom: 20px;
      box-sizing: border-box;
      .menuItem {
        text-align: center;
        line-height: 1;
        cursor: pointer;
        padding: 10px 0;
        &.active,
        &:hover {
          background-color: #f1f1f1;
        }
        .iconBox {
          width: 100%;
          height: 140px;
          margin-bottom: 10px;
          position: relative;
          img {
            width: auto;
            height: auto;
            max-width: 100%;
            max-height: 100%;
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            margin: auto;
            border-radius: 6px;
          background-color: #cfebff;
          p {
            color: #0093ff;
          }
        }
        .name {
          display: -webkit-box;
          -webkit-box-orient: vertical;
          -webkit-line-clamp: 2;
          overflow: hidden;
          margin-bottom: 8px;
        }
        .time {
          font-size: 12px;
          color: #999;
        .menuIcon {
          display: inline-block;
          width: 32px;
          height: 32px;
          margin-bottom: 4px;
        }
      }
    }
    .pageBox {
      flex: 1;
      overflow: auto;
    }
  }
}
</style>