菜单布局+首页静态页面绘制

This commit is contained in:
Leo_Ding 2025-11-24 19:09:27 +08:00
parent 41f69742e6
commit fb6e1b0c57
12 changed files with 369 additions and 64 deletions

BIN
src/assets/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
src/assets/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
src/assets/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
src/assets/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
src/assets/avator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/assets/banner1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

BIN
src/assets/banner2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

BIN
src/assets/bottom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

BIN
src/assets/qr.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -57,11 +57,11 @@ const menuItems: MenuItem[] = [
], ],
}, },
{ {
path: '/layout/admin', path: '',
name: '账号', name: '账号',
icon: TeamOutlined, icon: TeamOutlined,
children: [ children: [
{ path: '/layout/admin/account/security', name: '账号安全' }, { path: '/layout/admin/security', name: '账号安全' },
{ path: '/layout/admin/account/history', name: '访问记录' }, { path: '/layout/admin/account/history', name: '访问记录' },
{ path: '/controlPanel/account/security', name: '安全设置' }, { path: '/controlPanel/account/security', name: '安全设置' },
], ],

View File

@ -1,13 +1,255 @@
<!-- src/views/home/index.vue -->
<template> <template>
<div > <div>
<h1>首页 - 独立页面</h1> <div style="height: 550px; overflow: hidden;">
<p>这个页面没有侧边栏</p> <a-carousel :after-change="onChange" style="height: 100%;">
<router-link to="/fileStore" style="color: blue; text-decoration: underline;"> <div class="banner-slide"></div>
点击进入文件存储有侧边栏 <!-- 如果有多张可以 v-for -->
</router-link> </a-carousel>
</div> </div>
</template> <div class="one">
<div>
<h3>GPU选型</h3>
<span>如何选择合适的GPU</span>
</div>
<div>
<h3>开具发票</h3>
<span>简单快速开具发票</span>
</div>
<div>
<h3>新手入门</h3>
<span>简单几步创建实例</span>
</div>
</div>
<div class="two">
<div>
<div>
<div style="margin-bottom: 40px;">
<div class="title">
<span>高性价比的算力服务</span>
</div>
<div class="subtitle">
高性价比+稳定性能算力服务适配多场景热门算力服务如下:
</div>
</div>
<script setup> <div class="list_card">
<div v-for="(value, index) in source" style="padding: 0 10px;text-align: center;font-size: 16px;"
:style="{ 'border-top': `3px solid ${listColor[index]}` }">
<div class="name"
style="font-size: 24px;font-weight: bold;padding: 20px;border-bottom: 1px solid #c9c9c9;text-align: center;">
{{ value.title
}}</div>
<div class="price" style="margin: 30px 0;">
<span style="font-size: 24px;font-weight: bold;color: #5b85fe;">¥{{ value.price }}</span>
<span style="font-size: 12px;">/小时</span>
</div>
<div style="padding-bottom: 40px;line-height: 40px;">
<div>内存{{ value.memory }}</div>
<div>显存{{ value.graphicsMemory }}</div>
<div>GPU{{ value.GPU }}</div>
</div>
</div>
</div>
</div>
<div>
<div style="margin-bottom: 40px;">
<div class="title">
<span>产品优势</span>
</div>
<div class="subtitle">
按需租赁高算力稳定省心更省成本
</div>
</div>
<div class="avatary_list">
<div v-for="item in advantageList">
<img :src="item.img" alt="" srcset="" width="200" height="158">
<div class="title">{{ item.title }}</div>
<div class="subtitle">{{ item.subtitle }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="three"></div>
<div class="footer">
<div class="footer_contain">
<div>
<div style="color: #000000;">服务热线:</div>
<div style="font-size: 36px;font-weight: bold;padding: 20px 0;">400-110-6993</div>
<div>邮箱:service@hzzxxd.com</div>
<div>地址:江苏省南通市崇川区紫琅科技城3号楼</div>
</div>
<div>
<div style="color: #000000;">快速导航</div>
<div>算力中心</div>
<div>云主机</div>
<div>用户文档</div>
</div>
<div style="display: flex;align-items: center;gap: 60px;">
<div style="display: flex;flex-direction: column;align-items: center;">
<img src="@/assets/qr.jpg" alt="" srcset="" width="100">
<div>公众号</div>
</div>
<div style="display: flex;flex-direction: column;align-items: center;">
<img src="@/assets/qr.jpg" alt="" srcset="" width="100">
<div>企业微信</div>
</div>
</div>
</div>
<div
style="border-top: 1px solid #ebe4e4;height: 45px;text-align: center;line-height: 45px;color: #666666;font-size: 14px;">
苏备案号20251124号</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import one from '@/assets/1.png'
import two from '@/assets/2.png'
import three from '@/assets/3.png'
import firth from '@/assets/4.png'
const listColor = ref(['#7ed321', '#21d3c0', '#35a4de'])
const source = ref(
[
{ title: 'NVIDIA A100', price: '3.28', memory: '64GB', graphicsMemory: '40GB', GPU: 1 },
{ title: 'NVIDIA A100', price: '6.56', memory: '128GB', graphicsMemory: '80GB', GPU: 2 },
{ title: 'NVIDIA A100', price: '13.12', memory: '256GB', graphicsMemory: '16GB', GPU: 4 },
]
)
const advantageList = ref(
[
{ img: one, title: '灵活弹性', subtitle: '支持按需、包周期两种计费方式,可以根据使用场景选择。' },
{ img: two, title: '安全保障', subtitle: '提供网络防火墙功能,对公网连接进行严格访问控制' },
{ img: three, title: '方便易用', subtitle: '提供完善的API体系便捷的将云服务器与您的内部监控、运营系统相结合' },
{ img: firth, title: '服务优势', subtitle: '7*24小时服务支持60s之内问题相应机制' },
]
)
const onChange = (current: number) => {
console.log(current);
};
</script> </script>
<style scoped lang="scss">
.banner-slide {
width: 100%;
height:550px;
background: url('@/assets/banner2.png') no-repeat center / cover;
}
.one {
display: flex;
justify-content: space-around;
align-items: center;
background-color: #cfe7fe;
padding: 30px 0;
&>div {
padding: 10;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
& span {
color: #666666
}
}
}
.two {
background-image: linear-gradient(to bottom, #eaf7fc, #f4fafc);
padding-bottom: 80px;
&>div {
width: 1200px;
margin: 0 auto;
.title {
font-size: 28px;
font-weight: 700;
text-align: center;
}
&>div:first-child {
padding: 44px 0;
}
.subtitle {
margin-top: 20px;
color: rgb(153, 153, 153);
text-align: center;
}
.list_card {
margin-top: 30px;
display: flex;
justify-content: space-between;
gap: 20px;
&>div {
flex: 1;
background-color: #ffffff;
line-height: 30px;
transition: all 0.4s cubic-bezier(0.25, 0.1, 0.25, 1);
/* 更长的过渡时间和不同的缓动函数 */
}
&>div:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
}
.avatary_list {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 50px;
&>div {
display: flex;
flex-direction: column;
align-items: center;
}
.title {
color: #59b2f2;
font-size: 18px;
font-weight: bold;
line-height: 30px;
margin-top: 20px;
}
.subtitle {
color: #666666;
}
}
}
}
.three {
height: 180px;
background: url('@/assets/bottom.png') no-repeat center / 100% 100%;
}
.footer {
height: 260px;
background-color: #ffffff;
width: 100%;
.footer_contain {
width: 1200px;
margin: 0 auto;
height: calc(100% - 45px);
display: flex;
justify-content: space-around;
align-items: self-start;
padding: 20px 0;
&>div {
line-height: 30px;
color: #3a3939;
}
}
}
/* For demo */
</style>

View File

@ -1,109 +1,172 @@
<template> <template>
<div class="gx_layout"> <div class="gx_layout">
<div class="gx_layout_header"> <div :class="isHome ? 'gx_layout_header_home' : 'gx_layout_header_noHome'" class="gx_layout_header">
<div class="logo">GxDL算力云</div> <div class="logo">GxDL算力云</div>
<div class="menu"> <div class="menu">
<a-menu <a-menu v-model:selectedKeys="current" :class="isHome?'custom-menu':''" mode="horizontal" :items="leftRoutes"
v-model:selectedKeys="current" @click="({ key }) => handleMenuClick(key)" />
mode="horizontal" <a-menu v-model:selectedKeys="current" mode="horizontal" :class="isHome?'custom-menu':''" :items="rightRoutes"
:items="leftRoutes" @click="({ key }) => handleMenuClick(key)" />
@click="({ key }) => handleMenuClick(key)" </div>
/> <div class="user-info">
<a-menu <a-dropdown>
v-model:selectedKeys="current" <div style="display: flex;align-items: center;justify-content: flex-end;">
mode="horizontal" <a-avatar :size="24" :src="avatar">
:items="rightRoutes" <!-- <template #icon>
@click="({ key }) => handleMenuClick(key)" <UserOutlined />
/> </template> -->
</div> </a-avatar>
<div class="user-info"> <span style="font-size: 14px;padding-left:5px;">管理员</span>
</div>
</div> <template #overlay>
<a-card hoverable style="width: 240px">
<template #cover>
<img alt="example" src="https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png" />
</template>
<a-card-meta title="Europe Street beat">
<template #description>www.instagram.com</template>
</a-card-meta>
<template #actions>
<!-- <setting-outlined key="setting" />
<edit-outlined key="edit" />
<ellipsis-outlined key="ellipsis" /> -->
<a-button block type="text" @click="logout">退出登录</a-button>
</template>
</a-card>
</template>
</a-dropdown>
</div>
</div>
<div class="gx_layout_content">
<router-view />
</div>
</div> </div>
<div class="gx_layout_content">
<router-view />
</div>
</div>
</template> </template>
<script setup> <script setup>
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { UserOutlined } from '@ant-design/icons-vue';
import avatar from '@/assets/avator.png'
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const isHome = ref(true)
// /layout // /layout
const getActiveKeyFromRoute = () => { const getActiveKeyFromRoute = () => {
const path = route.path const path = route.path
if (path.startsWith('/layout')) { if (path.startsWith('/layout')) {
const key = path.replace('/layout', '') || '/home' const key = path.replace('/layout', '') || '/home'
return [key.startsWith('/') ? key : '/' + key] return [key.startsWith('/') ? key : '/' + key]
} }
return ['/home'] return ['/home']
} }
const current = ref(getActiveKeyFromRoute()) const current = ref(getActiveKeyFromRoute())
// 退 // 退
watch(() => route.path, () => { watch(() => route.path, () => {
current.value = getActiveKeyFromRoute() current.value = getActiveKeyFromRoute()
if (current.value == '/home') {
isHome.value = true
} else {
isHome.value = false
}
}) })
// key 使 '/admin' // key 使 '/admin'
const leftRoutes = ref([ const leftRoutes = ref([
{ key: '/home', label: '首页' }, { key: '/home', label: '首页' },
{ key: '/center', label: '算力中心' }, { key: '/center', label: '算力中心' },
{ key: '/yunmain', label: '云主机' } { key: '/yunmain', label: '云主机' }
]) ])
const rightRoutes = ref([ const rightRoutes = ref([
{ key: '/document', label: '用户文档' }, { key: '/document', label: '用户文档' },
{ key: '/admin/home', label: '控制台' } { key: '/admin/home', label: '控制台' }
]) ])
// //
const handleMenuClick = (key) => { const handleMenuClick = (key) => {
// key "/admin" "/layout/admin" // key "/admin" "/layout/admin"
const fullPath = `/layout${key}` const fullPath = `/layout${key}`
router.push(fullPath) router.push(fullPath)
}
const logout = () => {
router.replace('/login')
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.gx_layout{ .gx_layout {
width: 100%; width: 100%;
height:100vh; height: 100vh;
.gx_layout_header{
height: 60px; .gx_layout_header_home {
background: #ffffff; background-color: #cfe7fe;
border-bottom: none;
}
.gx_layout_header_noHome {
border-bottom: 1px solid rgb(216 216 216); border-bottom: 1px solid rgb(216 216 216);
}
.gx_layout_header {
z-index: 999;
width: 100%;
height: 60px;
position: fixed;
top: 0;
left: 0;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0 20px; padding: 0 20px;
flex: 1; flex: 1;
.logo{
.logo {
width: 200px; width: 200px;
} }
.user-info{
.user-info {
width: 100px; width: 100px;
} }
.menu{
.menu {
flex: 1; flex: 1;
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
&>ul:first-child{
&>ul:first-child {
width: 100%; width: 100%;
border-bottom: none; border-bottom: none;
} }
&>ul{
&>ul {
border-bottom: none; border-bottom: none;
} }
} }
} }
.gx_layout_content{
.gx_layout_content {
margin-top: 60px;
height: calc(100% - 60px); height: calc(100% - 60px);
background-color: rgba(240, 240, 240, 1); background-color: rgba(240, 240, 240, 1);
} }
} }
/* 自定义菜单主题 */
.custom-menu {
/* 背景色 */
background: #cfe7fe !important;
}
/* 选中项文字颜色 + 左侧竖条horizontal 模式下是底部横线) */
.custom-menu :deep(.ant-menu-item-selected) {
color: #2563eb !important;
}
/* hover 效果 */
.custom-menu :deep(.ant-menu-item:hover) {
color: #2563eb !important;
}
</style> </style>