mirror of
https://gitee.com/dromara/go-view.git
synced 2025-02-23 15:52:49 +08:00
feat: 首页架构
This commit is contained in:
parent
44667a89f0
commit
90e45f6c23
28
src/App.vue
28
src/App.vue
@ -2,8 +2,8 @@
|
|||||||
<n-config-provider
|
<n-config-provider
|
||||||
:locale="zhCN"
|
:locale="zhCN"
|
||||||
:theme="getDarkTheme"
|
:theme="getDarkTheme"
|
||||||
:theme-overrides="getThemeOverrides"
|
|
||||||
:date-locale="dateZhCN"
|
:date-locale="dateZhCN"
|
||||||
|
:theme-overrides="getThemeOverrides"
|
||||||
>
|
>
|
||||||
<app-provider>
|
<app-provider>
|
||||||
<router-view />
|
<router-view />
|
||||||
@ -18,7 +18,7 @@ import {
|
|||||||
dateZhCN,
|
dateZhCN,
|
||||||
darkTheme,
|
darkTheme,
|
||||||
NConfigProvider,
|
NConfigProvider,
|
||||||
GlobalThemeOverrides,
|
GlobalThemeOverrides
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
import { AppProvider } from '@/components/Application'
|
import { AppProvider } from '@/components/Application'
|
||||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||||
@ -26,22 +26,36 @@ import { borderRadius } from '@/settings/designSetting'
|
|||||||
|
|
||||||
const designStore = useDesignStore()
|
const designStore = useDesignStore()
|
||||||
|
|
||||||
|
// 返回暗黑主题
|
||||||
|
const getDarkTheme = computed(() =>
|
||||||
|
designStore.getDarkTheme ? darkTheme : undefined
|
||||||
|
)
|
||||||
|
|
||||||
|
// 主题配置
|
||||||
const getThemeOverrides = computed(
|
const getThemeOverrides = computed(
|
||||||
(): GlobalThemeOverrides => {
|
(): GlobalThemeOverrides => {
|
||||||
return {
|
const commonObj = {
|
||||||
|
common: {
|
||||||
|
borderRadius
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const lightObject = {
|
||||||
|
common: {
|
||||||
|
...commonObj.common
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const dartObject = {
|
||||||
common: {
|
common: {
|
||||||
primaryColor: designStore.appTheme,
|
primaryColor: designStore.appTheme,
|
||||||
borderRadius
|
...commonObj.common
|
||||||
},
|
},
|
||||||
LoadingBar: {
|
LoadingBar: {
|
||||||
colorLoading: designStore.appTheme
|
colorLoading: designStore.appTheme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return designStore.getDarkTheme ? dartObject : lightObject
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const getDarkTheme = computed(() =>
|
|
||||||
designStore.getDarkTheme ? darkTheme : undefined
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
3
src/components/Doc/index.ts
Normal file
3
src/components/Doc/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Doc from './index.vue';
|
||||||
|
|
||||||
|
export { Doc };
|
16
src/components/Doc/index.vue
Normal file
16
src/components/Doc/index.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<n-button quaternary @click="handleClick" title="说明文档">
|
||||||
|
<n-icon size="20" :depth="1">
|
||||||
|
<DocumentTextIcon />
|
||||||
|
</n-icon>
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { openDoc } from '@/utils/page'
|
||||||
|
import { DocumentText as DocumentTextIcon } from '@vicons/ionicons5'
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
openDoc()
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-button quaternary @click="changeTheme">
|
<n-button quaternary @click="changeTheme" title="主题">
|
||||||
<n-icon size="20" :depth="1">
|
<n-icon size="20" :depth="1">
|
||||||
<MoonIcon v-if="designStore.darkTheme" />
|
<MoonIcon v-if="designStore.darkTheme" />
|
||||||
<SunnyIcon v-else />
|
<SunnyIcon v-else />
|
||||||
|
3
src/components/UserInfo/index.ts
Normal file
3
src/components/UserInfo/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import UserInfo from './index.vue';
|
||||||
|
|
||||||
|
export { UserInfo };
|
103
src/components/UserInfo/index.vue
Normal file
103
src/components/UserInfo/index.vue
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<n-dropdown
|
||||||
|
trigger="hover"
|
||||||
|
@select="handleSelect"
|
||||||
|
:show-arrow="true"
|
||||||
|
:options="options"
|
||||||
|
>
|
||||||
|
<n-button quaternary circle>
|
||||||
|
<n-icon size="20" :depth="1">
|
||||||
|
<PersonOutlineIcon v-show="fallback" />
|
||||||
|
</n-icon>
|
||||||
|
<n-avatar
|
||||||
|
v-show="!fallback"
|
||||||
|
round
|
||||||
|
size="small"
|
||||||
|
:src="imageUrl"
|
||||||
|
@error="errorHandle"
|
||||||
|
/>
|
||||||
|
</n-button>
|
||||||
|
</n-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { h, ref } from 'vue'
|
||||||
|
import { NAvatar, NText } from 'naive-ui'
|
||||||
|
import { renderIcon } from '@/utils/index'
|
||||||
|
import { openDoc, logout } from '@/utils/page'
|
||||||
|
import {
|
||||||
|
Person as PersonOutlineIcon,
|
||||||
|
LogOutOutline as LogOutOutlineIcon,
|
||||||
|
DocumentText as DocumentTextIcon
|
||||||
|
} from '@vicons/ionicons5'
|
||||||
|
|
||||||
|
const imageUrl = 'https://www.naiveui.com/assets/naivelogo.93278402.svg'
|
||||||
|
|
||||||
|
// 是否失败
|
||||||
|
const fallback = ref(false)
|
||||||
|
|
||||||
|
// 用户图标渲染
|
||||||
|
const renderUserInfo = () => {
|
||||||
|
return h(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
style: 'display: flex; align-items: center; padding: 8px 12px;'
|
||||||
|
},
|
||||||
|
[
|
||||||
|
h(NAvatar, {
|
||||||
|
round: true,
|
||||||
|
style: 'margin-right: 12px;',
|
||||||
|
src: imageUrl
|
||||||
|
}),
|
||||||
|
h('div', null, [
|
||||||
|
h('div', null, [
|
||||||
|
h(NText, { depth: 2 }, { default: () => '奔跑的面条' })
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: '我的信息',
|
||||||
|
key: 'info',
|
||||||
|
type: 'render',
|
||||||
|
render: renderUserInfo
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'divider',
|
||||||
|
key: 'd1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '说明文档',
|
||||||
|
key: 'doc',
|
||||||
|
icon: renderIcon(DocumentTextIcon)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'divider',
|
||||||
|
key: 'd2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '退出登录',
|
||||||
|
key: 'logout',
|
||||||
|
icon: renderIcon(LogOutOutlineIcon)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 图片渲染错误
|
||||||
|
const errorHandle = (e: Event) => {
|
||||||
|
fallback.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelect = (key: string) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'doc':
|
||||||
|
openDoc()
|
||||||
|
break
|
||||||
|
case 'logout':
|
||||||
|
logout()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,4 +1,4 @@
|
|||||||
import { ResultEnum } from "@/enums/httpEnum"
|
import { ResultEnum } from '@/enums/httpEnum'
|
||||||
|
|
||||||
export enum PageEnum {
|
export enum PageEnum {
|
||||||
// 登录
|
// 登录
|
||||||
@ -13,14 +13,18 @@ export enum PageEnum {
|
|||||||
BASE_HOME = '/project',
|
BASE_HOME = '/project',
|
||||||
BASE_HOME_NAME = 'Project',
|
BASE_HOME_NAME = 'Project',
|
||||||
|
|
||||||
|
// 模板市场
|
||||||
|
BASE_HOME_Template_Market = '/project/templateMarket',
|
||||||
|
BASE_HOME_Template_Market_NAME = 'Project-TemplateMarket',
|
||||||
|
|
||||||
// 错误
|
// 错误
|
||||||
ERROR_PAGE_NAME_403 = 'ErrorPage403',
|
ERROR_PAGE_NAME_403 = 'ErrorPage403',
|
||||||
ERROR_PAGE_NAME_404 = 'ErrorPage404',
|
ERROR_PAGE_NAME_404 = 'ErrorPage404',
|
||||||
ERROR_PAGE_NAME_500 = 'ErrorPage500',
|
ERROR_PAGE_NAME_500 = 'ErrorPage500'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ErrorPageNameMap = new Map([
|
export const ErrorPageNameMap = new Map([
|
||||||
[ResultEnum.NOT_FOUND, PageEnum.ERROR_PAGE_NAME_404],
|
[ResultEnum.NOT_FOUND, PageEnum.ERROR_PAGE_NAME_404],
|
||||||
[ResultEnum.SERVER_FORBIDDEN, PageEnum.ERROR_PAGE_NAME_403],
|
[ResultEnum.SERVER_FORBIDDEN, PageEnum.ERROR_PAGE_NAME_403],
|
||||||
[ResultEnum.SERVER_ERROR, PageEnum.ERROR_PAGE_NAME_500],
|
[ResultEnum.SERVER_ERROR, PageEnum.ERROR_PAGE_NAME_500]
|
||||||
])
|
])
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="go-header">
|
<n-layout-header bordered class="go-header">
|
||||||
<header class="go-header-box">
|
<header class="go-header-box">
|
||||||
<div class="li">
|
<div class="li">
|
||||||
<n-space>
|
<n-space>
|
||||||
@ -8,15 +8,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="ri">
|
<div class="ri">
|
||||||
<n-space>
|
<n-space>
|
||||||
<slot name="right">
|
<slot name="ri-left"> </slot>
|
||||||
<LangSelect />
|
<LangSelect />
|
||||||
<ThemeSelect />
|
<ThemeSelect />
|
||||||
</slot>
|
<slot name="ri-right"> </slot>
|
||||||
</n-space>
|
</n-space>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<n-divider class="go-header-divider" />
|
</n-layout-header>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -30,7 +29,7 @@ import { LangSelect } from '@/components/LangSelect'
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 40px;
|
padding: 0 60px;
|
||||||
height: $--header-height;
|
height: $--header-height;
|
||||||
}
|
}
|
||||||
&-divider {
|
&-divider {
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router'
|
||||||
|
import { PageEnum } from '@/enums/pageEnum'
|
||||||
|
|
||||||
const projectRoutes: RouteRecordRaw = {
|
const projectRoutes: RouteRecordRaw = {
|
||||||
path: '/project',
|
path: PageEnum.BASE_HOME,
|
||||||
name: 'Project',
|
name: PageEnum.BASE_HOME_NAME,
|
||||||
component: () => import('@/views/project/index.vue'),
|
component: () => import('@/views/project/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '项目',
|
title: '项目',
|
||||||
isRoot: true,
|
isRoot: true
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
export default projectRoutes;
|
export default projectRoutes
|
||||||
|
@ -38,7 +38,7 @@ export const appThemeList: string[] = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export const theme = {
|
export const theme = {
|
||||||
//深色主题
|
// 默认是否开启深色主题
|
||||||
darkTheme: true,
|
darkTheme: true,
|
||||||
//系统主题色
|
//系统主题色
|
||||||
appTheme: '#63e2b7',
|
appTheme: '#63e2b7',
|
||||||
@ -46,6 +46,12 @@ export const theme = {
|
|||||||
appThemeList
|
appThemeList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 侧边栏宽度
|
||||||
|
export const asideWidth = '240'
|
||||||
|
|
||||||
|
// 侧边栏缩小后的宽度
|
||||||
|
export const asideCollapsedWidth = '60'
|
||||||
|
|
||||||
// 修改边框圆角
|
// 修改边框圆角
|
||||||
export const borderRadius = '8px'
|
export const borderRadius = '8px'
|
||||||
|
|
||||||
|
4
src/settings/pathConst.ts
Normal file
4
src/settings/pathConst.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// 项目文档地址
|
||||||
|
export const docPath = "http://www.mtruning.club/"
|
||||||
|
|
||||||
|
export const giteeSourceCodePath = "https://gitee.com/MTrun/go-view/"
|
@ -4,7 +4,8 @@ $dark: (
|
|||||||
//背景
|
//背景
|
||||||
background-color: $--color-dark-bg-1,
|
background-color: $--color-dark-bg-1,
|
||||||
//渐变背景
|
//渐变背景
|
||||||
background-image: linear-gradient(120deg, $--color-dark-bg-1 0%, $--color-dark-bg-2 100%),
|
background-image:
|
||||||
|
linear-gradient(120deg, $--color-dark-bg-1 0%, $--color-dark-bg-1 100%),
|
||||||
//毛玻璃
|
//毛玻璃
|
||||||
filter-color: $--filter-color-login-dark
|
filter-color: $--filter-color-login-dark,
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,11 @@ $light: (
|
|||||||
//背景
|
//背景
|
||||||
background_color: $--color-light-fill-3,
|
background_color: $--color-light-fill-3,
|
||||||
//渐变背景
|
//渐变背景
|
||||||
background-image: linear-gradient(120deg, $--color-text-1 0%, $--color-text-1 100%),
|
background-image:
|
||||||
|
linear-gradient(120deg, $--color-text-1 0%, $--color-text-1 100%),
|
||||||
//毛玻璃
|
//毛玻璃
|
||||||
filter-color: $--filter-color-login-light
|
filter-color: $--filter-color-login-light,
|
||||||
|
// 侧边栏
|
||||||
|
aside-bg: #fff,
|
||||||
|
aside-color: rgb(239, 239, 245)
|
||||||
);
|
);
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//获取背景颜色
|
//获取背景颜色
|
||||||
@mixin filter-color($target) {
|
@mixin filter-bg-color($target) {
|
||||||
@include themeify {
|
@include themeify {
|
||||||
background-color: themed($target);
|
background-color: themed($target);
|
||||||
}
|
}
|
||||||
@ -52,3 +52,10 @@
|
|||||||
color: themed($target);
|
color: themed($target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取边框颜色
|
||||||
|
@mixin filter-border-color($target) {
|
||||||
|
@include themeify {
|
||||||
|
border-color: themed($target);
|
||||||
|
}
|
||||||
|
}
|
@ -14,3 +14,31 @@
|
|||||||
border-radius: $--border-radius-base;
|
border-radius: $--border-radius-base;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo 使用 scss 循环写一套完整的
|
||||||
|
// margin
|
||||||
|
.go-mt-0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.go-mb-0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.go-mx-0 {
|
||||||
|
@extend .go-mt-0;
|
||||||
|
@extend .go-mb-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.go-pt-0 {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.go-pb-0 {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.go-px-0 {
|
||||||
|
@extend .go-pt-0;
|
||||||
|
@extend .go-pb-0;
|
||||||
|
}
|
@ -19,7 +19,7 @@ $--color-light-fill-4: #c9cdd4;
|
|||||||
|
|
||||||
// 黑色
|
// 黑色
|
||||||
$--color-dark-black: #000;
|
$--color-dark-black: #000;
|
||||||
$--color-dark-bg-1: #17171a;
|
$--color-dark-bg-1: #18181c;
|
||||||
$--color-dark-bg-2: #232324;
|
$--color-dark-bg-2: #232324;
|
||||||
$--color-dark-bg-3: #2a2a2b;
|
$--color-dark-bg-3: #2a2a2b;
|
||||||
$--color-dark-bg-4: #313132;
|
$--color-dark-bg-4: #313132;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { h } from 'vue'
|
import { h, DefineComponent } from 'vue'
|
||||||
import { NIcon } from 'naive-ui'
|
import { NIcon } from 'naive-ui'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,7 +14,7 @@ export function getUUID(randomLength: number) {
|
|||||||
/**
|
/**
|
||||||
* * render 图标
|
* * render 图标
|
||||||
*/
|
*/
|
||||||
export const renderIcon = (icon: typeof NIcon) => {
|
export const renderIcon = (icon: any) => {
|
||||||
return () => h(NIcon, null, { default: () => h(icon) })
|
return () => h(NIcon, null, { default: () => h(icon) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
import { ResultEnum } from '@/enums/httpEnum'
|
import { ResultEnum } from '@/enums/httpEnum'
|
||||||
import { ErrorPageNameMap } from '@/enums/pageEnum'
|
import { ErrorPageNameMap, PageEnum } from '@/enums/pageEnum'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
import { docPath, giteeSourceCodePath } from '@/settings/pathConst'
|
||||||
/**
|
|
||||||
* * 错误页重定向
|
|
||||||
* @param icon
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const redirectErrorPage = (code: ResultEnum) => {
|
|
||||||
if (!code) return false
|
|
||||||
const pageName = ErrorPageNameMap.get(code)
|
|
||||||
if (!pageName) return false
|
|
||||||
routerTurnByName(pageName)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 根据名字跳转路由
|
* * 根据名字跳转路由
|
||||||
@ -29,3 +18,46 @@ export const routerTurnByName = (pageName: string, isReplace?: boolean) => {
|
|||||||
name: pageName
|
name: pageName
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 错误页重定向
|
||||||
|
* @param icon
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const redirectErrorPage = (code: ResultEnum) => {
|
||||||
|
if (!code) return false
|
||||||
|
const pageName = ErrorPageNameMap.get(code)
|
||||||
|
if (!pageName) return false
|
||||||
|
routerTurnByName(pageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 退出
|
||||||
|
*/
|
||||||
|
export const logout = () => {
|
||||||
|
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 打开项目文档
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
export const openDoc = () => {
|
||||||
|
window.open(docPath, 'blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 打开码云仓库地址
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
export const openGiteeSourceCode = () => {
|
||||||
|
window.open(giteeSourceCodePath, 'blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 新开页面
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
export const openNewWindow = (url: string) => {
|
||||||
|
window.open(url, 'blank')
|
||||||
|
}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 修改主题色
|
||||||
|
* @param themeName 主题名称
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const setHtmlTheme = (themeName?: string) => {
|
export const setHtmlTheme = (themeName?: string) => {
|
||||||
const e = window.document.documentElement
|
const e = window.document.documentElement
|
||||||
if (themeName) {
|
if (themeName) {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<transition-group name="list-complete">
|
<transition-group name="list-complete">
|
||||||
<template v-for="item in bgList" :key="item">
|
<template v-for="item in bgList" :key="item">
|
||||||
<div class="bg-img-box-li list-complete-item">
|
<div class="bg-img-box-li list-complete-item">
|
||||||
<n-collapse-transition :appear="true" :show="show">
|
<n-collapse-transition :appear="true" :show="showBg">
|
||||||
<img :src="getImageUrl(item, 'chart')" alt="chart" />
|
<img :src="getImageUrl(item, 'chart')" alt="chart" />
|
||||||
</n-collapse-transition>
|
</n-collapse-transition>
|
||||||
</div>
|
</div>
|
||||||
@ -141,12 +141,16 @@ const message = useMessage()
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const autoLogin = ref(true)
|
const autoLogin = ref(true)
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
|
const showBg = ref(false)
|
||||||
const designStore = useDesignStore()
|
const designStore = useDesignStore()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
show.value = true
|
show.value = true
|
||||||
|
}, 300)
|
||||||
|
setTimeout(() => {
|
||||||
|
showBg.value = true
|
||||||
}, 100)
|
}, 100)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -274,7 +278,7 @@ $carousel-image-height: 60vh;
|
|||||||
|
|
||||||
&-card {
|
&-card {
|
||||||
@extend .go-background-filter;
|
@extend .go-background-filter;
|
||||||
@include filter-color('filter-color');
|
@include filter-bg-color('filter-color');
|
||||||
box-shadow: 0 0 20px 5px rgba(40, 40, 40, 0.5);
|
box-shadow: 0 0 20px 5px rgba(40, 40, 40, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="go-project">
|
||||||
<h1>首页</h1>
|
<n-layout has-sider position="absolute">
|
||||||
|
<n-space vertical>
|
||||||
|
<Sider />
|
||||||
|
</n-space>
|
||||||
|
<n-layout>
|
||||||
|
<Header />
|
||||||
|
<n-layout
|
||||||
|
class="content-top"
|
||||||
|
position="absolute"
|
||||||
|
:native-scrollbar="false"
|
||||||
|
>
|
||||||
|
<n-layout-content>
|
||||||
|
<router-view></router-view>
|
||||||
|
</n-layout-content>
|
||||||
|
</n-layout>
|
||||||
|
</n-layout>
|
||||||
|
</n-layout>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import { Sider } from './layout/components/Sider'
|
||||||
|
import { Header } from './layout/components/Header/index'
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
@include go(project) {
|
||||||
|
.content-top {
|
||||||
|
top: $--header-height;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
3
src/views/project/layout/components/AsideFooter/index.ts
Normal file
3
src/views/project/layout/components/AsideFooter/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import AsideFooter from './index.vue'
|
||||||
|
|
||||||
|
export { AsideFooter }
|
44
src/views/project/layout/components/AsideFooter/index.vue
Normal file
44
src/views/project/layout/components/AsideFooter/index.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div class="go-aside-footer">
|
||||||
|
<n-divider class="go-mt-0" />
|
||||||
|
<n-space justify="space-around" :wrap="false">
|
||||||
|
<n-button secondary @click="handleDoc">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon size="18">
|
||||||
|
<HelpOutlineIcon />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
<n-text>帮助中心</n-text>
|
||||||
|
</n-button>
|
||||||
|
<n-button secondary @click="handleCode">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon size="18">
|
||||||
|
<CodeSlashIcon />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
<n-text>仓库地址</n-text>
|
||||||
|
</n-button>
|
||||||
|
</n-space>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { openDoc, openGiteeSourceCode } from '@/utils/page'
|
||||||
|
|
||||||
|
import {
|
||||||
|
HelpCircleOutline as HelpOutlineIcon,
|
||||||
|
CodeSlash as CodeSlashIcon
|
||||||
|
} from '@vicons/ionicons5'
|
||||||
|
|
||||||
|
const handleDoc = () => {
|
||||||
|
openDoc()
|
||||||
|
}
|
||||||
|
const handleCode = () => {
|
||||||
|
openGiteeSourceCode()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@include go('aside-footer') {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
3
src/views/project/layout/components/Create/index.ts
Normal file
3
src/views/project/layout/components/Create/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Create from './index.vue'
|
||||||
|
|
||||||
|
export { Create }
|
25
src/views/project/layout/components/Create/index.vue
Normal file
25
src/views/project/layout/components/Create/index.vue
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<n-button v-if="collapsed" ghost type="primary" size="small">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<DuplicateIcon />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
<n-button v-else ghost type="primary" size="large">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<DuplicateIcon />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
<span>
|
||||||
|
新建项目
|
||||||
|
</span>
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Duplicate as DuplicateIcon } from '@vicons/ionicons5'
|
||||||
|
const props = defineProps({
|
||||||
|
collapsed: Boolean
|
||||||
|
})
|
||||||
|
</script>
|
3
src/views/project/layout/components/Header/index.ts
Normal file
3
src/views/project/layout/components/Header/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Header from './index.vue'
|
||||||
|
|
||||||
|
export { Header }
|
13
src/views/project/layout/components/Header/index.vue
Normal file
13
src/views/project/layout/components/Header/index.vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<Header>
|
||||||
|
<template #ri-left>
|
||||||
|
</template>
|
||||||
|
<template #ri-right>
|
||||||
|
<UserInfo />
|
||||||
|
</template>
|
||||||
|
</Header>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Header } from '@/layout/components/Header'
|
||||||
|
import { UserInfo } from '@/components/UserInfo'
|
||||||
|
</script>
|
3
src/views/project/layout/components/Sider/index.ts
Normal file
3
src/views/project/layout/components/Sider/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Sider from './index.vue'
|
||||||
|
|
||||||
|
export { Sider }
|
82
src/views/project/layout/components/Sider/index.vue
Normal file
82
src/views/project/layout/components/Sider/index.vue
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<n-layout-sider
|
||||||
|
class="go-project-layout-sider"
|
||||||
|
bordered
|
||||||
|
inverted
|
||||||
|
collapse-mode="width"
|
||||||
|
:collapsed="collapsed"
|
||||||
|
:native-scrollbar="false"
|
||||||
|
:collapsed-width="asideCollapsedWidth"
|
||||||
|
:width="asideWidth"
|
||||||
|
@collapse="collapsed = true"
|
||||||
|
@expand="collapsed = false"
|
||||||
|
>
|
||||||
|
<div class="go-project-sider-flex">
|
||||||
|
<aside>
|
||||||
|
<n-space vertical class="go-project-sider-top">
|
||||||
|
<Create :collapsed="collapsed" />
|
||||||
|
</n-space>
|
||||||
|
<n-menu
|
||||||
|
:value="menuValue"
|
||||||
|
:options="menuOptions"
|
||||||
|
:collapsed-width="asideCollapsedWidth"
|
||||||
|
:collapsed-icon-size="22"
|
||||||
|
@update:value="handleUpdateValue"
|
||||||
|
/>
|
||||||
|
</aside>
|
||||||
|
<!-- 底部提示 -->
|
||||||
|
<div class="sider-bottom">
|
||||||
|
<AsideFooter />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</n-layout-sider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { Create } from '../Create/index'
|
||||||
|
import { AsideFooter } from '../AsideFooter/index'
|
||||||
|
import { asideWidth, asideCollapsedWidth } from '@/settings/designSetting'
|
||||||
|
import { menuOptionsInit } from './menu'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
const collapsed = ref(false)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const routeRame = computed(() => route.name)
|
||||||
|
const menuValue = ref(routeRame)
|
||||||
|
|
||||||
|
const menuOptions = menuOptionsInit()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$siderHeight: 100vh;
|
||||||
|
|
||||||
|
@include go(project) {
|
||||||
|
&-sider {
|
||||||
|
&-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
&-flex {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: $siderHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-layout-sider {
|
||||||
|
height: $siderHeight;
|
||||||
|
@include filter-bg-color('aside-bg');
|
||||||
|
@include filter-border-color('aside-color');
|
||||||
|
}
|
||||||
|
.content-top {
|
||||||
|
top: $--header-height;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
58
src/views/project/layout/components/Sider/menu.ts
Normal file
58
src/views/project/layout/components/Sider/menu.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { reactive, h } from 'vue'
|
||||||
|
import { renderIcon } from '@/utils'
|
||||||
|
import { RouterLink } from 'vue-router'
|
||||||
|
import { PageEnum } from '@/enums/pageEnum'
|
||||||
|
import { MenuOption, MenuGroupOption } from 'naive-ui'
|
||||||
|
import { FolderOpen as FolderOpenIcon, LogoAppleAppstore as LogoAppleAppstoreIcon, } from '@vicons/ionicons5'
|
||||||
|
|
||||||
|
export const renderMenuLabel = (option: MenuOption | MenuGroupOption) => {
|
||||||
|
return option.label
|
||||||
|
}
|
||||||
|
|
||||||
|
export const menuOptionsInit = () => {
|
||||||
|
return reactive([
|
||||||
|
{
|
||||||
|
key: 'divider-1',
|
||||||
|
type: 'divider'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
label: '我的',
|
||||||
|
key: 'people',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: () =>
|
||||||
|
h(
|
||||||
|
RouterLink,
|
||||||
|
{
|
||||||
|
to: {
|
||||||
|
name: PageEnum.BASE_HOME_NAME
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '全部项目' }
|
||||||
|
),
|
||||||
|
key: PageEnum.BASE_HOME_NAME,
|
||||||
|
icon: renderIcon(FolderOpenIcon)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'divider-1',
|
||||||
|
type: 'divider'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: () =>
|
||||||
|
h(
|
||||||
|
RouterLink,
|
||||||
|
{
|
||||||
|
to: {
|
||||||
|
name: PageEnum.BASE_HOME_NAME
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '模板市场' }
|
||||||
|
),
|
||||||
|
key: 'store',
|
||||||
|
icon: renderIcon(LogoAppleAppstoreIcon)
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
@ -13,12 +13,4 @@ const router = useRouter()
|
|||||||
const goHome = () => {
|
const goHome = () => {
|
||||||
router.replace({ path: '/' })
|
router.replace({ path: '/' })
|
||||||
}
|
}
|
||||||
// onBeforeMount(() => {
|
|
||||||
// const { params, query } = route
|
|
||||||
// const { path } = params
|
|
||||||
// router.replace({
|
|
||||||
// path: '/' + (Array.isArray(path) ? path.join('/') : path),
|
|
||||||
// query
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user