feat:更新依赖组件ICON配置
This commit is contained in:
parent
5acb144b21
commit
cde38eaa17
@ -32,6 +32,7 @@
|
|||||||
"@vue/babel-plugin-jsx": "^1.4.0",
|
"@vue/babel-plugin-jsx": "^1.4.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^5.3.4",
|
"vite": "^5.3.4",
|
||||||
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"vue-tsc": "^2.0.24"
|
"vue-tsc": "^2.0.24"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1994
pnpm-lock.yaml
generated
1994
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
BIN
src/assets/images/暂无权限.png
Normal file
BIN
src/assets/images/暂无权限.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
BIN
src/assets/images/暂无纪录.png
Normal file
BIN
src/assets/images/暂无纪录.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
BIN
src/assets/images/暂无项目.png
Normal file
BIN
src/assets/images/暂无项目.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
BIN
src/assets/images/空空如也.png
Normal file
BIN
src/assets/images/空空如也.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
177
src/components/Ls-UI/LsEmpty.vue
Normal file
177
src/components/Ls-UI/LsEmpty.vue
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
<template>
|
||||||
|
<div class="empty-state" :class="[`empty-state--${type}`]">
|
||||||
|
<div class="empty-state__icon" :class="`empty-state__icon--${type}`">
|
||||||
|
<slot name="icon">
|
||||||
|
<img v-if="type === 'no-data'" src="@/assets/images/暂无项目.png">
|
||||||
|
<img v-else-if="type === 'no-permission'" src="@/assets/images/暂无权限.png">
|
||||||
|
<img v-else src="@/assets/images/空空如也.png">
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="empty-state__title">{{ title }}</h3>
|
||||||
|
|
||||||
|
<p class="empty-state__desc" v-if="description">{{ description }}</p>
|
||||||
|
|
||||||
|
<div class="empty-state__action" v-if="$slots.default">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
type EmptyStateType = 'no-data' | 'no-permission' | 'not-opened'
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ElzEmpty',
|
||||||
|
label: '空状态',
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String as () => EmptyStateType,
|
||||||
|
default: 'no-data',
|
||||||
|
validator: (value: string): value is EmptyStateType =>
|
||||||
|
['no-data', 'no-permission', 'not-opened'].includes(value as EmptyStateType)
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ['update:title', 'update:description'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
// const iconComponent = computed(() => {
|
||||||
|
// const icons: Record<EmptyStateType, string> = {
|
||||||
|
// 'no-data': 'el-icon-data-analysis',
|
||||||
|
// 'no-permission': 'el-icon-thumb',
|
||||||
|
// 'not-opened': 'el-icon-receiving'
|
||||||
|
// }
|
||||||
|
// return icons[props.type] || 'el-icon-receiving'
|
||||||
|
// })
|
||||||
|
|
||||||
|
const defaultTitles: Record<EmptyStateType, string> = {
|
||||||
|
'no-data': '暂无数据',
|
||||||
|
'no-permission': '无访问权限',
|
||||||
|
'not-opened': '暂未开通'
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultDescriptions: Record<EmptyStateType, string> = {
|
||||||
|
'no-data': '当前没有找到相关数据',
|
||||||
|
'no-permission': '您没有权限访问此内容',
|
||||||
|
'not-opened': '该功能暂未开通,敬请期待'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default title and description if not provided
|
||||||
|
if (!props.title) {
|
||||||
|
emit('update:title', defaultTitles[props.type])
|
||||||
|
}
|
||||||
|
if (!props.description) {
|
||||||
|
emit('update:description', defaultDescriptions[props.type])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.empty-state {
|
||||||
|
$block: &;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 20px;
|
||||||
|
animation: fadeIn 0.5s ease-in-out;
|
||||||
|
img{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
&__icon {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
animation: bounceIn 0.8s ease-in-out;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--no-data {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--no-permission {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--not-opened {
|
||||||
|
color: #e6a23c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
animation: slideInUp 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__desc {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 1.5;
|
||||||
|
animation: slideInUp 0.6s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__action {
|
||||||
|
margin-top: 24px;
|
||||||
|
animation: slideInUp 0.7s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动画定义
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounceIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
70% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
2
src/components/Ls-UI/REAMME.md
Normal file
2
src/components/Ls-UI/REAMME.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
这里封装的是零枢公共UI组件库,基于vue3 + naive-ui,后面也许会迁移到私服npm包上。
|
||||||
|
如果要封装,请以Ls开头
|
27
src/components/ProjectTitle.vue
Normal file
27
src/components/ProjectTitle.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<header>
|
||||||
|
<svg-icon icon-class="mainproject" width="16" height="16" color="#3D8EFF"></svg-icon>
|
||||||
|
<p class="title">{{ title }}</p>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang='ts'>
|
||||||
|
defineProps<{
|
||||||
|
'title':String
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
<style scoped lang='scss'>
|
||||||
|
header {
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 16px;
|
||||||
|
border-bottom: 1px solid $dashLineColor;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: $titleTextColor;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
52
src/components/SvgIcon.vue
Normal file
52
src/components/SvgIcon.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
class="svg-icon"
|
||||||
|
:style="svgStyle"
|
||||||
|
aria-hidden="true"
|
||||||
|
v-on="$attrs"
|
||||||
|
>
|
||||||
|
<use :xlink:href="iconName" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// SVG 图标名称(对应 assets/icons 目录下的文件名)
|
||||||
|
iconClass: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
// 图标宽度
|
||||||
|
width: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '1em'
|
||||||
|
},
|
||||||
|
// 图标高度
|
||||||
|
height: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '1em'
|
||||||
|
},
|
||||||
|
// 图标颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: 'currentColor'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const iconName = computed(() => `#icon-${props.iconClass}`);
|
||||||
|
const svgStyle = computed(() => ({
|
||||||
|
width: typeof props.width === 'number' ? `${props.width}px` : props.width,
|
||||||
|
height: typeof props.height === 'number' ? `${props.height}px` : props.height,
|
||||||
|
fill: props.color
|
||||||
|
}));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.svg-icon {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
@ -10,13 +10,19 @@ import router from "@/router";
|
|||||||
import naive from 'naive-ui';
|
import naive from 'naive-ui';
|
||||||
import 'vfonts/Lato.css'// 通用字体
|
import 'vfonts/Lato.css'// 通用字体
|
||||||
import 'vfonts/FiraCode.css'// 等宽字体
|
import 'vfonts/FiraCode.css'// 等宽字体
|
||||||
|
import 'virtual:svg-icons-register'; //SVG精灵图册
|
||||||
// 登录授权相关
|
// 登录授权相关
|
||||||
import { createAuth0 } from '@auth0/auth0-vue';
|
import { createAuth0 } from '@auth0/auth0-vue';
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
|
// 全局组件
|
||||||
|
import SvgIcon from '@/components/SvgIcon.vue';
|
||||||
|
import LsComponent from './plugins/globalLsComponents'
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
app.component('svg-icon',SvgIcon); //图标组件
|
||||||
|
app.use(LsComponent); //零枢封装组件
|
||||||
app.use(
|
app.use(
|
||||||
createAuth0({
|
createAuth0({
|
||||||
domain: DO_MAIN,
|
domain: DO_MAIN,
|
||||||
|
20
src/plugins/globalLsComponents.ts
Normal file
20
src/plugins/globalLsComponents.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// src/plugins/globalComponents.ts
|
||||||
|
import type { App } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
install(app: App) {
|
||||||
|
// 使用 import.meta.glob 动态导入所有 Ls 开头的组件
|
||||||
|
const components = import.meta.glob('../components/Ls-UI/Ls*.vue', { eager: true })
|
||||||
|
|
||||||
|
for (const path in components) {
|
||||||
|
const component = components[path] as any
|
||||||
|
// 获取组件名称(去掉路径和扩展名,只保留文件名)
|
||||||
|
const componentName = path
|
||||||
|
.split('/')
|
||||||
|
.pop()
|
||||||
|
?.replace(/\.\w+$/, '') || ''
|
||||||
|
// 注册组件
|
||||||
|
app.component(componentName, component.default || component)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
<div class="header__item">
|
<div class="header__item">
|
||||||
<header>
|
<header>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<img src="@/assets/icons/order.svg">
|
<svg-icon icon-class="order" width="16" height="16" color="#fff"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<p class="title">今日新增订单</p>
|
<p class="title">今日新增订单</p>
|
||||||
</header>
|
</header>
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<div class="header__item">
|
<div class="header__item">
|
||||||
<header>
|
<header>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<img src="@/assets/icons/order.svg">
|
<svg-icon icon-class="order" width="16" height="16" color="#fff"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<p class="title">今日新增陪玩</p>
|
<p class="title">今日新增陪玩</p>
|
||||||
</header>
|
</header>
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<div class="header__item">
|
<div class="header__item">
|
||||||
<header>
|
<header>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<img src="@/assets/icons/money.svg">
|
<svg-icon icon-class="money" width="16" height="16" color="#fff"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<p class="title">今日订单金额</p>
|
<p class="title">今日订单金额</p>
|
||||||
</header>
|
</header>
|
||||||
@ -50,7 +50,7 @@
|
|||||||
<div class="header__item">
|
<div class="header__item">
|
||||||
<header>
|
<header>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<img src="@/assets/icons/order.svg">
|
<svg-icon icon-class="order" width="16" height="16" color="#fff"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<p class="title">今日活跃代理数</p>
|
<p class="title">今日活跃代理数</p>
|
||||||
</header>
|
</header>
|
||||||
@ -66,7 +66,7 @@
|
|||||||
<div class="header__item">
|
<div class="header__item">
|
||||||
<header>
|
<header>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<img src="@/assets/icons/order.svg">
|
<svg-icon icon-class="order" width="16" height="16" color="#fff"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<p class="title">本月订单总数</p>
|
<p class="title">本月订单总数</p>
|
||||||
</header>
|
</header>
|
||||||
@ -85,6 +85,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
$colors: #00b882, #4d76eb, #db4c4d, #dc6333, #897dd7;
|
$colors: #00b882, #4d76eb, #db4c4d, #dc6333, #897dd7;
|
||||||
|
|
||||||
.header__item {
|
.header__item {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@ -125,11 +126,6 @@ $colors: #00b882, #4d76eb, #db4c4d, #dc6333, #897dd7;
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
|
|
||||||
img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<header>
|
<ProjectTitle title="周订单统计" />
|
||||||
<img src="@/assets/icons/mainproject.svg">
|
|
||||||
<p class="title">周订单统计</p>
|
|
||||||
</header>
|
|
||||||
<div class="line" ref="chartRef"></div>
|
<div class="line" ref="chartRef"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
import ProjectTitle from '@/components/ProjectTitle.vue';
|
||||||
|
|
||||||
const chartRef = ref<HTMLElement>();
|
const chartRef = ref<HTMLElement>();
|
||||||
|
|
||||||
@ -166,25 +164,6 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
header {
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 16px;
|
|
||||||
border-bottom: 1px solid $dashLineColor;
|
|
||||||
gap:4px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: $titleTextColor;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.line {
|
.line {
|
||||||
height: 400px;
|
height: 400px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -24,13 +24,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
<n-tab-pane name="the beatles" tab="热门陪玩">
|
<n-tab-pane name="the beatles" tab="热门陪玩">
|
||||||
Hey Jude
|
<LsEmpty type="no-data" title="无数据" description="暂时没有陪玩登记"></LsEmpty>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
</n-tabs>
|
</n-tabs>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import { CheckmarkCircle } from '@vicons/ionicons5'
|
import { CheckmarkCircle } from '@vicons/ionicons5';
|
||||||
|
import LsEmpty from '@/components/Ls-UI/LsEmpty.vue';
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
.panel {
|
.panel {
|
||||||
@ -44,6 +45,7 @@ import { CheckmarkCircle } from '@vicons/ionicons5'
|
|||||||
height: 120px;
|
height: 120px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
header {
|
header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<header>
|
<ProjectTitle title="系统行为日志" />
|
||||||
<img src="@/assets/icons/mainproject.svg">
|
|
||||||
<p class="title">系统行为日志</p>
|
|
||||||
</header>
|
|
||||||
<main>
|
<main>
|
||||||
<n-timeline>
|
<n-timeline>
|
||||||
<n-timeline-item type="success" title="login" content="用户罗澜登录了系统" time="2025-07-05 11:46" />
|
<n-timeline-item type="success" title="login" content="用户罗澜登录了系统" time="2025-07-05 11:46" />
|
||||||
@ -12,27 +9,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
|
import ProjectTitle from '@/components/ProjectTitle.vue';
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
header {
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 16px;
|
|
||||||
border-bottom: 1px solid $dashLineColor;
|
|
||||||
gap: 4px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: $titleTextColor;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
padding:16px;
|
padding:16px;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<header>
|
<ProjectTitle title="近三月经营情况" />
|
||||||
<img src="@/assets/icons/mainproject.svg">
|
|
||||||
<p class="title">近三月陪玩团情况</p>
|
|
||||||
</header>
|
|
||||||
<div class="bar" ref="chartRef"></div>
|
<div class="bar" ref="chartRef"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
import ProjectTitle from '@/components/ProjectTitle.vue';
|
||||||
|
|
||||||
const chartRef = ref<HTMLElement>();
|
const chartRef = ref<HTMLElement>();
|
||||||
|
|
||||||
@ -195,25 +193,6 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
header {
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 16px;
|
|
||||||
border-bottom: 1px solid $dashLineColor;
|
|
||||||
gap: 4px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: $titleTextColor;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar {
|
.bar {
|
||||||
height: 400px;
|
height: 400px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<header>
|
<ProjectTitle title="快捷跳转" />
|
||||||
<img src="@/assets/icons/mainproject.svg">
|
|
||||||
<p class="title">快捷跳转</p>
|
|
||||||
</header>
|
|
||||||
<main>
|
<main>
|
||||||
<div class="icon__item">
|
<div class="icon__item">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
@ -14,27 +11,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
|
import ProjectTitle from '@/components/ProjectTitle.vue';
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
header {
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 16px;
|
|
||||||
border-bottom: 1px solid $dashLineColor;
|
|
||||||
gap: 4px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
color: $titleTextColor;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
@ -14,14 +14,7 @@
|
|||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import {
|
import {
|
||||||
LogOutOutline as HomeIcon,
|
|
||||||
LaptopOutline as WorkIcon,
|
|
||||||
CaretDownOutline,
|
CaretDownOutline,
|
||||||
HomeSharp,
|
|
||||||
PersonCircleSharp,
|
|
||||||
Layers,
|
|
||||||
Settings,
|
|
||||||
Menu
|
|
||||||
} from '@vicons/ionicons5'
|
} from '@vicons/ionicons5'
|
||||||
import { MenuOption, NIcon } from 'naive-ui';
|
import { MenuOption, NIcon } from 'naive-ui';
|
||||||
import { useAppStore } from '@/store/app';
|
import { useAppStore } from '@/store/app';
|
||||||
@ -29,13 +22,14 @@ import { storeToRefs } from 'pinia';
|
|||||||
import { RouterLink } from 'vue-router';
|
import { RouterLink } from 'vue-router';
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const activeKey = ref('default');
|
const activeKey = ref('default');
|
||||||
const { menuApp } = storeToRefs(appStore)
|
const { menuApp } = storeToRefs(appStore);
|
||||||
|
import SvgIcon from '@/components/SvgIcon.vue';
|
||||||
const expandIcon = () => {
|
const expandIcon = () => {
|
||||||
return h(NIcon, null, { default: () => h(CaretDownOutline) })
|
return h(NIcon, null, { default: () => h(CaretDownOutline) })
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderIcon(icon: Component) {
|
function renderIcon(iconClass: string) {
|
||||||
return () => h(NIcon, null, { default: () => h(icon) })
|
return () => h(SvgIcon, { iconClass, width: '16', height: '16' })
|
||||||
}
|
}
|
||||||
const menuOptions: MenuOption[] = [
|
const menuOptions: MenuOption[] = [
|
||||||
{
|
{
|
||||||
@ -53,12 +47,12 @@ const menuOptions: MenuOption[] = [
|
|||||||
{ default: () => '概览' }
|
{ default: () => '概览' }
|
||||||
),
|
),
|
||||||
key: 'default',
|
key: 'default',
|
||||||
icon: renderIcon(HomeSharp)
|
icon: renderIcon('mainproject')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '角色管理',
|
label: '角色管理',
|
||||||
key: 'role',
|
key: 'role',
|
||||||
icon: renderIcon(PersonCircleSharp),
|
icon: renderIcon('mainproject'),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
label: () => h(
|
label: () => h(
|
||||||
@ -74,14 +68,14 @@ const menuOptions: MenuOption[] = [
|
|||||||
{ default: () => '权限分配' }
|
{ default: () => '权限分配' }
|
||||||
),
|
),
|
||||||
key: 'role-auth',
|
key: 'role-auth',
|
||||||
icon: renderIcon(Layers)
|
icon: renderIcon('mainproject')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '系统配置',
|
label: '系统配置',
|
||||||
key: 'system',
|
key: 'system',
|
||||||
icon: renderIcon(Settings),
|
icon:renderIcon('mainproject'),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
label: () => h(
|
label: () => h(
|
||||||
@ -97,7 +91,7 @@ const menuOptions: MenuOption[] = [
|
|||||||
{ default: () => '菜单管理' }
|
{ default: () => '菜单管理' }
|
||||||
),
|
),
|
||||||
key: 'system',
|
key: 'system',
|
||||||
icon: renderIcon(Menu)
|
icon: renderIcon('mainproject')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -106,18 +100,18 @@ const menuOptions: MenuOption[] = [
|
|||||||
<style scoped lang='scss'>
|
<style scoped lang='scss'>
|
||||||
/* 确保菜单项在折叠状态下图标居中 */
|
/* 确保菜单项在折叠状态下图标居中 */
|
||||||
.n-menu-item-content--collapsed {
|
.n-menu-item-content--collapsed {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 添加平滑过渡效果 */
|
/* 添加平滑过渡效果 */
|
||||||
.n-layout-sider {
|
.n-layout-sider {
|
||||||
transition: width 0.3s var(--n-bezier);
|
transition: width 0.9s var(--n-bezier);
|
||||||
height:100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 调整折叠状态下菜单项的样式 */
|
/* 调整折叠状态下菜单项的样式 */
|
||||||
.n-menu .n-menu-item-content--collapsed .n-menu-item-content__icon {
|
.n-menu .n-menu-item-content--collapsed .n-menu-item-content__icon {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -2,12 +2,14 @@ import { defineConfig } from "vite";
|
|||||||
import vue from "@vitejs/plugin-vue";
|
import vue from "@vitejs/plugin-vue";
|
||||||
import { fileURLToPath, URL } from "url";
|
import { fileURLToPath, URL } from "url";
|
||||||
import AutoImport from "unplugin-auto-import/vite";
|
import AutoImport from "unplugin-auto-import/vite";
|
||||||
|
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// ...其他配置
|
// ...其他配置
|
||||||
define: {
|
define: {
|
||||||
'process.env': process.env
|
"process.env": process.env,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
@ -16,22 +18,28 @@ export default defineConfig({
|
|||||||
defaultExportByFilename: true,
|
defaultExportByFilename: true,
|
||||||
dirs: ["./src/api"],
|
dirs: ["./src/api"],
|
||||||
}),
|
}),
|
||||||
|
createSvgIconsPlugin({
|
||||||
|
// 指定需要缓存的图标文件夹
|
||||||
|
iconDirs: [path.resolve(process.cwd(), "src/assets/icons")],
|
||||||
|
// 指定symbolId格式
|
||||||
|
symbolId: "icon-[name]",
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
server:{
|
server: {
|
||||||
proxy:{
|
proxy: {
|
||||||
'/api':{
|
"/api": {
|
||||||
target:'http://localhost:3000/api',
|
target: "http://localhost:3000/api",
|
||||||
changeOrigin:true,
|
changeOrigin: true,
|
||||||
rewrite:(path) => path.replace(/^\api/,'')
|
rewrite: (path) => path.replace(/^\api/, ""),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
additionalData: `@use "@/assets/styles/variable.scss" as *;` // 使用 @use 代替 @import
|
additionalData: `@use "@/assets/styles/variable.scss" as *;`, // 使用 @use 代替 @import
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user