guhongwei 1 year ago
parent
commit
5b222ac7c7

+ 60 - 0
src/components/user-frame/home.vue

@@ -0,0 +1,60 @@
+<template>
+  <el-container class="main">
+    <el-header :style="{ padding: 0 }"> <component :is="cHeader"></component></el-header>
+    <el-container>
+      <el-aside width="200px" :style="{ 'background-color': '#242f42' }"><component :is="cAside"></component></el-aside>
+      <el-main>
+        <div class="content-box" :class="{ 'content-collapse': collapse }">
+          <el-col :span="24" class="content">
+            <transition name="move" mode="out-in">
+              <el-row>
+                <component :is="cBreadcrumb" :breadcrumbTitle="route.meta.title"></component>
+                <el-col :span="24" class="container" :style="{ padding: '10px 0' }"><router-view :style="testInfo"></router-view></el-col>
+              </el-row>
+            </transition>
+            <el-backtop target=".content"></el-backtop>
+          </el-col>
+        </div>
+      </el-main>
+    </el-container>
+  </el-container>
+</template>
+
+<script setup lang="ts">
+// 组件
+import cHeader from './parts/Header.vue'
+import cAside from './parts/Sidebar.vue'
+import cBreadcrumb from './parts/breadcrumb.vue'
+import { useRoute } from 'vue-router'
+import type { Ref } from 'vue'
+import { ref } from 'vue'
+
+// 路由
+const route = useRoute()
+let collapse: Ref<any> = ref(false)
+const testInfo: Ref<any> = ref({
+  height: '83.8vh',
+  background: '#ffffff',
+  'overflow-x': 'hidden',
+  'overflow-y': 'auto',
+  border: '1px solid #f0f0f0',
+  padding: '10px'
+})
+</script>
+<style scoped lang="scss">
+.main {
+  height: 100vh;
+  background-color: #f0f0f0;
+  .el-header {
+    border-bottom: 1px solid;
+  }
+  .el-aside {
+    height: 93.3vh;
+    overflow-x: auto;
+    overflow-y: auto;
+  }
+  .el-main {
+    padding: 10px;
+  }
+}
+</style>

+ 86 - 0
src/components/user-frame/parts/Header.vue

@@ -0,0 +1,86 @@
+<template>
+  <div id="Header">
+    <el-row>
+      <el-col :span="24" class="main">
+        <el-col :span="24" class="main header">
+          <el-col :span="24" class="one">
+            <el-col :span="12" class="left">
+              <span>
+                <i v-if="!collapse" class="el-icon-s-fold"></i>
+                <i v-else class="el-icon-s-unfold"></i>
+              </span>
+              <span>{{ siteInfo.zhTitle }}-个人中心</span>
+            </el-col>
+            <el-col :span="12" class="right">
+              <el-button type="primary" size="small" @click="toWeb">网站平台</el-button>
+              <span>
+                <el-icon><UserFilled /></el-icon>
+                {{ user && user._id ? user.name || user.title || user.expert_name : '游客' }}
+              </span>
+              <el-button type="danger" size="small" @click="logout">退出登录</el-button>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { siteInfo } from '../../../layout/site'
+import store from '@/stores/counter'
+import type { Ref } from 'vue'
+import { ref } from 'vue'
+import { useRouter } from 'vue-router'
+const router = useRouter()
+let collapse: Ref<any> = ref(false)
+let user: Ref<any> = ref(store.state.user)
+// 网站平台
+const toWeb = () => {
+  let env = import.meta.env.VITE_APP_ENV
+  let path = ''
+  if (env == 'development') path = 'http://localhost:8001/zkzxweb'
+  else path = '/zkzxweb'
+  window.open(path)
+}
+// 退出登录
+const logout = () => {
+  sessionStorage.removeItem('token')
+  router.push('/login')
+}
+</script>
+<style scoped lang="scss">
+.main {
+  background-color: #242f42;
+  .one {
+    height: 60px;
+    border-bottom: 1px solid #f1f1f1;
+    padding: 0 10px;
+    display: flex;
+    .left {
+      line-height: 60px;
+      span {
+        display: inline-block;
+        margin: 0 10px;
+        font-size: 22px;
+        color: #ffffff;
+        font-weight: bold;
+        font-family: cursive;
+      }
+    }
+    .right {
+      text-align: right;
+      padding: 16px 0;
+      span {
+        padding: 0 8px;
+        color: #ffffff;
+        position: relative;
+        top: 1px;
+      }
+      .el-icon {
+        top: 2px;
+      }
+    }
+  }
+}
+</style>

+ 129 - 0
src/components/user-frame/parts/Sidebar.vue

@@ -0,0 +1,129 @@
+<!-- eslint-disable vue/no-deprecated-slot-attribute -->
+<template>
+  <div id="Sidebar">
+    <el-row class="sidebar">
+      <el-col :span="24" class="main">
+        <el-col :span="24" class="one">
+          <el-menu
+            class="sidebar-el-menu"
+            :default-active="onRoutes"
+            unique-opened
+            router
+            :background-color="styleInfo.backColor"
+            :text-color="styleInfo.textColor"
+            :active-text-color="styleInfo.activeColor"
+          >
+            <template v-for="item in items">
+              <template v-if="item.type === '0'">
+                <el-sub-menu :index="item._id" :key="item._id">
+                  <template #title>
+                    <i :class="['iconfont', item.icon]"></i>
+                    <span>{{ item.name }}</span>
+                  </template>
+                  <template v-for="subItem in item.children">
+                    <el-sub-menu v-if="subItem.children && subItem.children.length > 0" :index="subItem._id" :key="subItem._id">
+                      <template #title>
+                        <i :class="['iconfont', subItem.icon]"></i>
+                        <span>{{ subItem.name }}</span>
+                      </template>
+                      <el-menu-item v-for="(threeItem, i) in subItem.children" :key="i" :index="threeItem.path">
+                        <i :class="['iconfont', threeItem.icon]"></i>
+                        <span>{{ threeItem.name }}</span>
+                      </el-menu-item>
+                    </el-sub-menu>
+                    <el-menu-item v-else :index="subItem.path" :key="subItem.path">
+                      <i :class="['iconfont', subItem.icon]"></i>
+                      <span>{{ subItem.name }}</span>
+                    </el-menu-item>
+                  </template>
+                </el-sub-menu>
+              </template>
+              <template v-else>
+                <el-menu-item :index="item.path" :key="item.path">
+                  <i :class="['iconfont', item.icon]"></i>
+                  <span>{{ item.name }}</span>
+                </el-menu-item>
+              </template>
+            </template>
+          </el-menu>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { admin } from '../../../layout/menu'
+import { menuInfo } from '../../../layout/site'
+import { ElMessage } from 'element-plus'
+import store from '@/stores/counter'
+import type { Ref } from 'vue'
+import { ref, onMounted, watch } from 'vue'
+import { useRoute } from 'vue-router'
+import { ModuleStore } from '@common/src/stores/system/module' //模块
+import { RoleStore } from '@common/src/stores/system/role' //模块
+import type { IQueryResult } from '@/util/types.util' //
+const module = ModuleStore()
+const role = RoleStore()
+const route = useRoute()
+let onRoutes = route.path
+let user: Ref<any> = ref({})
+const styleInfo: Ref<any> = ref(menuInfo.info)
+let items: Ref<any> = ref(admin)
+onMounted(async () => {
+  user.value = store.state.user
+})
+
+const getMenu = async () => {
+  let name = import.meta.env.VITE_APP_ROUTER
+  const res: IQueryResult = await module.query({ name: name, is_use: '0' })
+  if (res && res.errcode == '0') {
+    if (res.total > 0) {
+      let moduleInfo = res.data[0]
+      let roleInfo: IQueryResult = await role.um()
+      if (roleInfo.errcode == '0') {
+        if (roleInfo.data) {
+          let menus = roleInfo.data[moduleInfo._id]
+          if (menus && menus.length > 0) {
+            items.value = menus
+          }
+        }
+      }
+    }
+  } else {
+    ElMessage({ message: `${res.errmsg}`, type: 'error' })
+  }
+}
+
+watch(
+  user,
+  (newVal) => {
+    if (newVal && newVal._id) {
+      if (newVal && newVal._id) getMenu()
+      else ElMessage({ message: `暂无用户信息,无法获取菜单信息`, type: 'error' })
+    }
+  },
+  {
+    deep: true
+  }
+)
+</script>
+<style scoped lang="scss">
+.sidebar::-webkit-scrollbar {
+  width: 0;
+}
+.sidebar-el-menu:not(.el-menu--collapse) {
+  width: 201px;
+}
+.sidebar > ul {
+  height: 100%;
+}
+.main {
+  .one {
+    .iconfont {
+      font-size: 18px;
+      margin: 0 5px 0 0;
+    }
+  }
+}
+</style>

+ 23 - 0
src/components/user-frame/parts/breadcrumb.vue

@@ -0,0 +1,23 @@
+<template>
+  <div id="breadcrumb">
+    <el-row>
+      <el-col :span="24" class="crumbs">
+        <el-breadcrumb separator="/">
+          <el-breadcrumb-item> <i class="el-icon-s-grid"></i> {{ breadcrumbTitle }} </el-breadcrumb-item>
+        </el-breadcrumb>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { toRefs } from 'vue'
+// #region 参数传递
+const props = defineProps({
+  breadcrumbTitle: { type: String, default: () => '' }
+})
+const { breadcrumbTitle } = toRefs(props)
+
+// #endregion
+</script>
+<style lang="scss" scoped></style>