573 lines
17 KiB
Vue
573 lines
17 KiB
Vue
<template>
|
||
<div class="home-page">
|
||
<!-- 主布局:左右两栏 -->
|
||
<a-row :gutter="24">
|
||
<!-- 左侧栏:实例、数据、常见问题 -->
|
||
<a-col :span="16">
|
||
<!-- 实例卡片 -->
|
||
<a-card title="实例" :bordered="false" class="card">
|
||
<a-row :gutter="32" align="middle">
|
||
<!-- 第一栏:容器实例和运行中 -->
|
||
<a-col :span="8">
|
||
<div class="stats-column">
|
||
<div class="stats-row">
|
||
<div class="stat-item">
|
||
<div class="stat-label">容器实例</div>
|
||
<div class="stat-value">{{ userInfo.caseNum }}</div>
|
||
</div>
|
||
<div class="stat-item">
|
||
<div class="stat-label">运行中</div>
|
||
<div class="stat-value">0</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</a-col>
|
||
|
||
<!-- 第二栏:即将到期和即将释放 -->
|
||
<a-col :span="8">
|
||
<div class="stats-column">
|
||
<div class="vertical-divider"></div>
|
||
<div class="stats-row">
|
||
<div class="stat-item">
|
||
<div class="stat-label">
|
||
<span>即将到期</span>
|
||
<a-tooltip title="7天内到期的实例数量">
|
||
<QuestionCircleOutlined class="tooltip-icon" />
|
||
</a-tooltip>
|
||
</div>
|
||
<div class="stat-value orange">0</div>
|
||
</div>
|
||
<div class="stat-item">
|
||
<div class="stat-label">
|
||
<span>即将释放</span>
|
||
<a-tooltip title="3天内即将释放的实例数量">
|
||
<QuestionCircleOutlined class="tooltip-icon" />
|
||
</a-tooltip>
|
||
</div>
|
||
<div class="stat-value orange">0</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</a-col>
|
||
|
||
<!-- 第三栏:预警设置 -->
|
||
<a-col :span="8">
|
||
<div class="stats-column">
|
||
<div class="vertical-divider"></div>
|
||
<div class="warning-row">
|
||
<!-- 到期释放短信预警 -->
|
||
<div class="warning-module">
|
||
<div class="warning-label">
|
||
<span>到期释放</span>
|
||
<a-tooltip title="开启后,实例到期前会发送短信提醒">
|
||
<QuestionCircleOutlined class="tooltip-icon" />
|
||
</a-tooltip>
|
||
</div>
|
||
<div class="warning-controls">
|
||
<a-switch v-model:checked="switch1" size="small" />
|
||
<div class="warning-status">{{ switch1 ? '已开启' : '未开启' }}</div>
|
||
</div>
|
||
<div class="warning-actions">
|
||
<a-button type="link" size="small">发送记录</a-button>
|
||
<a-button type="link" size="small" danger>去绑定邮箱</a-button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 余额不足短信预警 -->
|
||
<div class="warning-module">
|
||
<div class="warning-label">
|
||
<span>余额不足</span>
|
||
<a-tooltip title="开启后,余额不足时会发送短信提醒">
|
||
<QuestionCircleOutlined class="tooltip-icon" />
|
||
</a-tooltip>
|
||
</div>
|
||
<div class="warning-controls">
|
||
<a-switch v-model:checked="switch2" size="small" />
|
||
<div class="warning-status">{{ switch2 ? '已开启' : '未开启' }}</div>
|
||
</div>
|
||
<!-- 无操作按钮 -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</a-col>
|
||
</a-row>
|
||
</a-card>
|
||
|
||
<!-- 数据卡片 -->
|
||
<!-- <a-card title="数据" :bordered="false" class="card margin-top">
|
||
<a-row type="flex" align="middle" style="height: 100%;">
|
||
<a-col :span="8">
|
||
<div class="data-column">
|
||
<div class="data-label">容器实例数据盘</div>
|
||
<div class="data-value">付费扩容容量</div>
|
||
<div class="data-unit">0 <span class="data-gb">GB</span></div>
|
||
</div>
|
||
</a-col>
|
||
<a-col :span="8">
|
||
<div class="data-column">
|
||
<div class="vertical-divider"></div>
|
||
<div class="data-label">镜像</div>
|
||
<div class="data-value">付费容量</div>
|
||
<div class="data-unit">0 <span class="data-gb">GB</span></div>
|
||
</div>
|
||
</a-col>
|
||
<a-col :span="8">
|
||
<div class="data-column">
|
||
<div class="vertical-divider"></div>
|
||
<div class="data-label">文件存储</div>
|
||
<div class="data-value">付费容量</div>
|
||
<div class="data-unit">0 <span class="data-gb">GB</span></div>
|
||
</div>
|
||
</a-col>
|
||
</a-row>
|
||
</a-card> -->
|
||
|
||
<!-- 常见问题卡片 -->
|
||
<a-card title="常见问题" :bordered="false" class="card margin-top">
|
||
<a-list item-layout="horizontal" :data-source="faqList">
|
||
<template #renderItem="{ item }">
|
||
<a-list-item class="faq-item">
|
||
<a-list-item-meta>
|
||
<template #title>
|
||
<a :href="item.path" target="_blank" class="faq-title" style="color: #999;">{{ item.question }}</a>
|
||
</template>
|
||
</a-list-item-meta>
|
||
</a-list-item>
|
||
</template>
|
||
</a-list>
|
||
<div class="more-container">
|
||
<a-button type="link" class="more-btn" @click="goToDocument()">查看更多问题</a-button>
|
||
</div>
|
||
</a-card>
|
||
</a-col>
|
||
|
||
<!-- 右侧栏:用户信息 + 费用信息 -->
|
||
<a-col :span="8">
|
||
<!-- 用户信息卡片 -->
|
||
<a-card :bordered="false" class="card">
|
||
<div class="user-info">
|
||
<div class="user-name">{{ userInfo.userName }}</div>
|
||
<a-tag color="orange">{{ userInfo.accountType === 'USER' ? '个人认证' : '企业认证' }}</a-tag>
|
||
</div>
|
||
<div class="user-member">
|
||
<UserOutlined class="member-icon" />
|
||
<span>炼丹会员<span style="color: #999;">(23天后到期)</span></span>
|
||
</div>
|
||
<div class="member-actions">
|
||
<a-button type="link" class="member-btn">认证学生升级炼丹会员</a-button>
|
||
<a-button type="link" class="member-btn">等级与会员福利</a-button>
|
||
</div>
|
||
<div class="growth">
|
||
<div class="growth-title">成长值</div>
|
||
<a-progress :percent="10" status="active" strokeColor="#d46b08" />
|
||
<div class="growth-text">距离升级还需90成长值 <a href="#">升级攻略</a></div>
|
||
<a-button type="link" class="growth-btn">进入成长值主页></a-button>
|
||
</div>
|
||
</a-card>
|
||
|
||
<!-- 费用信息卡片 -->
|
||
<a-card :bordered="false" class="card margin-top">
|
||
<div class="fee-header">
|
||
<div class="fee-title">我的余额</div>
|
||
<a-button type="primary" size="small" danger>去充值</a-button>
|
||
</div>
|
||
<div class="fee-info">
|
||
<div class="fee-item">
|
||
<span>可用:</span>
|
||
<span class="fee-value">¥{{ userInfo.noFreezeBalace }}</span>
|
||
<span class="fee-divider">|</span>
|
||
<span>冻结:</span>
|
||
<span class="fee-value">¥{{ userInfo.freezeBalace }}</span>
|
||
</div>
|
||
<div class="fee-item">
|
||
<GiftOutlined class="fee-icon" />
|
||
<span>代金券</span>
|
||
<span class="fee-value">¥0.00</span>
|
||
</div>
|
||
<div class="fee-item">
|
||
<TagOutlined class="fee-icon" />
|
||
<span>优惠券</span>
|
||
<span class="fee-value">暂无</span>
|
||
</div>
|
||
<div class="fee-item">
|
||
<CreditCardOutlined class="fee-icon" />
|
||
<span>授信</span>
|
||
<span class="fee-value">暂无</span>
|
||
</div>
|
||
</div>
|
||
<a-divider />
|
||
<div class="fee-links">
|
||
<a-button type="link" class="fee-link">我的订单></a-button>
|
||
<a-button type="link" class="fee-link">我的账单></a-button>
|
||
<a-button type="link" class="fee-link">我的代金券></a-button>
|
||
<a-button type="link" class="fee-link">开发票></a-button>
|
||
</div>
|
||
</a-card>
|
||
</a-col>
|
||
</a-row>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref,onBeforeMount } from 'vue'
|
||
import {
|
||
UserOutlined,
|
||
GiftOutlined,
|
||
TagOutlined,
|
||
CreditCardOutlined,
|
||
QuestionCircleOutlined
|
||
} from '@ant-design/icons-vue'
|
||
import { on } from 'events'
|
||
|
||
|
||
// 实例卡片的开关状态
|
||
const switch1 = ref(true)
|
||
const switch2 = ref(false)
|
||
const userInfo=ref<any>({})
|
||
onBeforeMount(() => {
|
||
userInfo.value = JSON.parse(localStorage.getItem('userInfo') || '{}');
|
||
console.log(userInfo.value)
|
||
})
|
||
// 常见问题列表
|
||
const faqList = ref([
|
||
{ id: 1, question: '如何选择GPU?',path:'/document/select' },
|
||
{ id: 2, question: '如何快速开始?',path:'/document/start' },
|
||
{ id: 3, question: '学术资源加速?',path:'/document/study' },
|
||
{ id: 4, question: '容器示例?',path:'/document/summary' },
|
||
])
|
||
const goToDocument = () => {
|
||
window.open('/document', '_blank');
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.home-page {
|
||
padding: 15px;
|
||
background: #fff;
|
||
// min-height: 100vh;
|
||
}
|
||
|
||
.card {
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
background: #fff;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.margin-top {
|
||
margin-top: 20px;
|
||
}
|
||
|
||
/* 实例卡片样式 */
|
||
.stats-column {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 100%;
|
||
position: relative;
|
||
margin-top: -10px;
|
||
}
|
||
|
||
.vertical-divider {
|
||
width: 1px;
|
||
height: 80px;
|
||
background: #e8e8e8;
|
||
margin: 0 16px;
|
||
}
|
||
|
||
.stats-row {
|
||
display: flex;
|
||
gap: 10px;
|
||
/* 从 32px 减小 */
|
||
align-items: flex-start;
|
||
width: 100%;
|
||
}
|
||
|
||
.stat-item {
|
||
text-align: center;
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: 14px;
|
||
color: #666;
|
||
margin-bottom: 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
.stat-value {
|
||
font-size: 24px;
|
||
font-weight: 600;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.orange {
|
||
color: #fa8c16;
|
||
}
|
||
|
||
.tooltip-icon {
|
||
color: #bfbfbf;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.tooltip-icon:hover {
|
||
color: #1890ff;
|
||
}
|
||
|
||
/* 预警设置样式 */
|
||
.warning-row {
|
||
display: flex;
|
||
flex-direction: row;
|
||
gap: 16px;
|
||
/* 模块间距 */
|
||
width: 100%;
|
||
/* align-items: flex-start; */
|
||
margin-top: 30px;
|
||
}
|
||
|
||
.warning-module {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
font-size: 12px;
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
.warning-item {
|
||
flex: 1;
|
||
min-width: 0;
|
||
/* 防止内容撑开 */
|
||
}
|
||
|
||
.warning-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
/* 更紧凑 */
|
||
font-size: 12px;
|
||
}
|
||
|
||
.warning-label {
|
||
font-size: 14px;
|
||
color: #666;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.warning-controls {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
flex-wrap: nowrap;
|
||
}
|
||
|
||
.warning-status {
|
||
font-size: 11px;
|
||
color: #999;
|
||
min-width: 36px;
|
||
}
|
||
|
||
.warning-actions {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.warning-actions .ant-btn {
|
||
padding: 0;
|
||
height: auto;
|
||
font-size: 12px;
|
||
text-align: left;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 数据卡片样式 */
|
||
.data-column {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100%;
|
||
padding: 12px 0;
|
||
position: relative;
|
||
}
|
||
|
||
.data-column .vertical-divider {
|
||
position: absolute;
|
||
left: 12px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
}
|
||
|
||
.data-label {
|
||
font-size: 14px;
|
||
color: #333;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.data-value {
|
||
font-size: 14px;
|
||
color: #999;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.data-unit {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #1890ff;
|
||
font-weight: 600;
|
||
.data-gb {
|
||
font-size: 12px;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.faq-item {
|
||
padding: 5px 0;
|
||
border-bottom: 0px solid #fff;
|
||
}
|
||
|
||
.faq-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.faq-title {
|
||
color: #1890ff;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.faq-title:hover {
|
||
color: #40a9ff;
|
||
}
|
||
|
||
.more-container {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-top: 16px;
|
||
}
|
||
|
||
.more-btn {
|
||
color: #1890ff;
|
||
}
|
||
|
||
.user-info {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.user-name {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.user-member {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
color: #333;
|
||
}
|
||
|
||
.member-icon {
|
||
color: #faad14;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.member-actions {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.member-btn {
|
||
display: block;
|
||
margin-top: 4px;
|
||
color: #1890ff;
|
||
padding: 0;
|
||
height: auto;
|
||
}
|
||
|
||
.growth {
|
||
margin-top: 20px;
|
||
padding-top: 16px;
|
||
border-top: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.growth-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.growth-text {
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin: 8px 0;
|
||
}
|
||
|
||
.growth-btn {
|
||
padding: 0;
|
||
height: auto;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.fee-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.fee-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.fee-info {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.fee-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.fee-icon {
|
||
color: #faad14;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.fee-value {
|
||
color: #1890ff;
|
||
margin-left: 4px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.fee-divider {
|
||
margin: 0 8px;
|
||
color: #d9d9d9;
|
||
}
|
||
|
||
.fee-links {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 5px;
|
||
}
|
||
|
||
.fee-link {
|
||
padding: 0;
|
||
height: auto;
|
||
color: #1890ff;
|
||
}
|
||
</style> |