bzkf3 2 lat temu
rodzic
commit
bac860c81e

+ 18 - 0
src/components/AppLink/index.vue

@@ -0,0 +1,18 @@
+<script setup lang="ts">
+import { useRouter } from 'vue-router'
+import { isExternal } from '~/utils/validate'
+const props = defineProps<{ to: string }>()
+const router = useRouter()
+const linkTo = () => {
+  router.push({ name: props.to })
+}
+</script>
+
+<template>
+  <a v-if="isExternal(props.to)" :href="props.to" target="_blank">
+    <slot />
+  </a>
+  <div v-else @click="linkTo">
+    <slot />
+  </div>
+</template>

+ 12 - 0
src/layout/app/components/AppHeader/index.vue

@@ -0,0 +1,12 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+// import { user } from '~/store/user';
+const APP_TITLE = ref(document.title)
+</script>
+
+<template>
+  <div class="header w-full h-50px leading-50px line px-8 text-xl text-white tracking-wider flex justify-between items-center">
+    <div>{{ APP_TITLE }}</div>
+    <!-- <div class="text-sm">{{ user.user_realname }}</div> -->
+  </div>
+</template>

+ 61 - 0
src/layout/app/components/AppSider/MenuItem.vue

@@ -0,0 +1,61 @@
+<script setup lang="ts">
+import type { RouteRecordRaw } from 'vue-router'
+import Item from './item.vue'
+import MenuItem from './MenuItem.vue'
+
+const props = defineProps<{
+  item: RouteRecordRaw
+}>()
+
+const currentRoute: RouteRecordRaw = props.item
+const showRoute = ref<RouteRecordRaw>(currentRoute)
+
+const showMode = ref<number>(0)
+
+function filterShowChild(children?: RouteRecordRaw[]): RouteRecordRaw[] {
+  if (Array.isArray(children)) {
+    const temp = children // .filter(child => !child.meta.hidden).sort((a, b) => a.meta.sort - b.meta.sort)
+    if (temp.length === 1 && Array.isArray(temp[0].children))
+      return filterShowChild(temp[0].children)
+
+    return temp
+  }
+  else {
+    return []
+  }
+}
+const currentRouteShowChildren = filterShowChild(currentRoute.children)
+
+if (currentRouteShowChildren.length === 0) {
+  showMode.value = 1
+}
+else if (currentRouteShowChildren.length === 1) {
+  showRoute.value = currentRouteShowChildren[0]
+  showMode.value = 1
+}
+else {
+  showMode.value = 2
+}
+</script>
+
+<template>
+  <template v-if="!item?.meta?.hidden">
+    <template v-if="showMode === 1">
+      <AppLink :to="showRoute.name">
+        <el-menu-item :index="showRoute.name">
+          <Item :icon="showRoute?.meta?.icon" :title="showRoute?.meta?.title || showRoute.name" />
+        </el-menu-item>
+      </AppLink>
+    </template>
+
+    <template v-if="showMode === 2">
+      <el-sub-menu :index="showRoute.name">
+        <template #title>
+          <Item :icon="showRoute?.meta?.icon" :title="showRoute?.meta?.title" />
+        </template>
+
+        <MenuItem v-for="route in showRoute.children" :key="route.name" :item="route || showRoute.name" />
+      </el-sub-menu>
+    </template>
+  </template>
+</template>

+ 20 - 0
src/layout/app/components/AppSider/index.vue

@@ -0,0 +1,20 @@
+<script setup lang="ts">
+import type { RouteRecordRaw } from 'vue-router'
+import MenuItem from './MenuItem.vue'
+const router = useRouter()
+// const route = useRoute()
+// console.log('router : ', router)
+const allRoutes = (router.options.routes).find((route: RouteRecordRaw) => route.name === ('back'))!.children
+
+// computed(() => {
+//   const routes: RouteRecordDetailRaw[] = JSON.parse(sessionStorage.getItem('routes') as string)
+//   return routes.sort((a, b) => a.meta.sort - b.meta.sort)
+// })
+// console.log('allRoutes : ', allRoutes)
+</script>
+
+<template>
+  <el-menu class="h-full border-none">
+    <MenuItem v-for="route in allRoutes" :key="route.name" :item="route" />
+  </el-menu>
+</template>

+ 10 - 0
src/layout/app/components/AppSider/item.vue

@@ -0,0 +1,10 @@
+<script setup lang="ts">
+const props = defineProps<{
+  icon?: string
+  title?: string
+}>()
+</script>
+
+<template>
+  <span>{{ props.title }}</span>
+</template>

+ 32 - 0
src/layout/app/index.vue

@@ -0,0 +1,32 @@
+<script setup lang="ts">
+import AppHeader from './components/AppHeader/index.vue'
+import AppSider from './components/AppSider/index.vue'
+
+// import Breadcrumb from '~/components/Breadcrumb/index.vue';
+// import AppMain from './components/AppMain/index.vue';
+</script>
+
+<template>
+  <div class="flex flex-col w-screen h-screen">
+    <header class="w-full flex-none bg-hex-265CD4">
+      <AppHeader />
+    </header>
+    <div class="w-full flex-auto flex flex-row overflow-hidden relative">
+      <aside class="w-210px flex-none h-full border">
+        <el-scrollbar view-class="h-full">
+          <AppSider />
+        </el-scrollbar>
+      </aside>
+      <div class="divide-x" />
+      <main class="flex-auto flex flex-col overflow-hidden">
+        <div class="w-full h-full">
+          <!-- <Breadcrumb class="flex-none mb-4"></Breadcrumb> -->
+
+          <el-scrollbar always wrap-class="w-full h-full box-border" view-class="relative h-full flex flex-col p-4">
+            <router-view />
+          </el-scrollbar>
+        </div>
+      </main>
+    </div>
+  </div>
+</template>

+ 21 - 0
src/layout/loading/index.vue

@@ -0,0 +1,21 @@
+<script setup lang="ts">
+import { useRouter } from 'vue-router'
+import { watch } from 'vue'
+import { app_ready, app_routes } from '~/store/app'
+
+const router = useRouter()
+watch(
+  () => app_ready.value,
+  (val) => {
+    if (val)
+      router.push({ name: app_routes.value?.[0]?.name })
+  },
+  {
+    immediate: true,
+  },
+)
+</script>
+
+<template>
+  <div :loading="true" class="w-screen h-screen" />
+</template>

+ 9 - 0
src/pages/back.vue

@@ -0,0 +1,9 @@
+<template>
+  <router-view />
+</template>
+
+<route lang="json">
+{
+  "redirect": "/back/ymgl"
+}
+</route>

+ 15 - 0
src/pages/back/ymgl.vue

@@ -0,0 +1,15 @@
+<script setup lang='ts'>
+import layout from '~/layout/app/index.vue'
+</script>
+
+<template>
+  <layout />
+</template>
+
+<route lang="json">
+{
+  "meta": {
+    "title": "页面管理"
+  }
+}
+</route>

+ 15 - 0
src/pages/back/ymgl/ymuixg.vue

@@ -0,0 +1,15 @@
+<script setup lang='ts'>
+
+</script>
+
+<template>
+  <div>ymuisz</div>
+</template>
+
+<route lang="json">
+{
+  "meta": {
+    "title": "页面UI管理"
+  }
+}
+</route>

+ 15 - 0
src/pages/back/ymgl/zxgl.vue

@@ -0,0 +1,15 @@
+<script setup lang='ts'>
+
+</script>
+
+<template>
+  <div>zxgl</div>
+</template>
+
+<route lang="json">
+{
+  "meta": {
+    "title": "资讯管理"
+  }
+}
+</route>

+ 3 - 0
src/pages/front.vue

@@ -0,0 +1,3 @@
+<template>
+  <router-view />
+</template>

+ 7 - 0
src/utils/validate.ts

@@ -0,0 +1,7 @@
+/**
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path: string) {
+  return /^(https?:|mailto:|tel:)/.test(path)
+}

+ 5 - 0
volar.config.ts

@@ -0,0 +1,5 @@
+import route from 'volar-plugin-vue-router'
+
+export default {
+  plugins: [route()],
+}