feat: 优化首页展示页面

This commit is contained in:
NiceAsiv 2024-08-21 13:31:19 +08:00
parent f76bca6b66
commit 7029903e43
10 changed files with 310 additions and 125 deletions

View File

@ -7,7 +7,7 @@ import boxen, { type Options as BoxenOptions } from "boxen";
dayjs.extend(duration);
const welcomeMessage = gradientString("cyan", "magenta").multiline(
`您好! 欢迎使用 pure-admin 开源项目\n我们为您精心准备了下面两个贴心的保姆级文档\nhttps://pure-admin.github.io/pure-admin-doc\nhttps://pure-admin-utils.netlify.app`
`保姆级文档\nhttps://pure-admin.github.io/pure-admin-doc\nhttps://pure-admin-utils.netlify.app`
);
const boxenOptions: BoxenOptions = {

Binary file not shown.

View File

@ -0,0 +1,11 @@
@font-face {
font-family: "AlibabaPuHuiTi";
src: url("@/assets/fonts/Alibaba_PuHuiTi_Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
font-display: swap;
}
body {
font-family: "AlibabaPuHuiTi", sans-serif;
}

View File

@ -0,0 +1,14 @@
.el-button--small:not(.el-button--text),
.el-radio-button--small .el-radio-button__inner {
padding: 8px 16px;
font-size: 14px;
}
.el-button--text {
padding: 0;
font-size: 14px;
}
.el-button--default {
border-color: #d0d0d0;
}

View File

@ -22,6 +22,10 @@ import "element-plus/dist/index.css";
import "./assets/iconfont/iconfont.js";
import "./assets/iconfont/iconfont.css";
//导入全局字体
import "@/assets/fonts/global.css";
import "@/assets/scss/reset.scss"; // Import global CSS reset file
const app = createApp(App);
// 自定义指令

View File

View File

@ -0,0 +1,164 @@
<template>
<div class="vulnerability-card">
<el-scrollbar
class="top-scrollbar"
wrap-class="scrollbar-wrapper"
height="300px"
>
<div v-for="alert in alerts" :key="alert.id" class="alert">
<div class="alert-header" @click="toggleAlert(alert.id)">
<div class="alert-title">{{ alert.cve }}</div>
<span class="alert-release-date">
发布于 {{ daysSinceRelease(alert.date) }} 天前
</span>
<div class="alert-date">{{ alert.date }}</div>
</div>
<div v-if="alert.isOpen" class="alert-details">
<el-table :data="alert.components">
<el-table-column prop="name" label="组件名称" />
<el-table-column prop="version" label="版本" />
<el-table-column label="受影响项目">
<template v-slot="scope">
<a href="#">{{ scope.row.affectedProjects }}</a>
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-scrollbar>
</div>
</template>
<script>
export default {
data() {
return {
alerts: [
{
id: 1,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: true,
components: [
{ name: "busybox", version: "1.1.4", affectedProjects: 5 },
{ name: "busybox", version: "1.1.4", affectedProjects: 5 }
]
},
{
id: 2,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 3,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 4,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 5,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 6,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 7,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 8,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 9,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
},
{
id: 10,
cve: "CVE-123456",
date: "2023-04-06, 12:45 pm",
isOpen: false,
components: []
}
]
};
},
methods: {
toggleAlert(id) {
const alert = this.alerts.find(alert => alert.id === id);
alert.isOpen = !alert.isOpen;
},
daysSinceRelease(date) {
return Math.floor((new Date() - new Date(date)) / (1000 * 60 * 60 * 24));
}
}
};
</script>
<style scoped>
.vulnerability-card {
width: 100%;
padding: 16px;
border: 1px solid #e2e8f0;
border-radius: 8px;
}
.alert {
padding-top: 12px;
margin-bottom: 12px;
border-top: 1px solid #e2e8f0;
}
.alert-header {
display: flex;
justify-content: space-between;
cursor: pointer;
}
.alert-title {
font-size: 14px;
font-weight: bold;
}
.alert-date {
font-size: 12px;
color: #4a5568;
}
.alert-release-date {
font-size: 12px;
color: #4a5568;
}
.alert-details {
margin-top: 8px;
font-size: 12px;
}
</style>

View File

@ -9,7 +9,7 @@ import {
Tooltip,
Legend
} from "chart.js";
import Card from "@/components/Card/Card.vue";
import VulnerabilityCard from "@/views/dashboard/components/VulnerabilityCard.vue";
ChartJS.register(BarElement, CategoryScale, LinearScale, Tooltip, Legend);
const projectInfo = ref({
@ -18,24 +18,23 @@ const projectInfo = ref({
scanTimes: 10,
scanFiles: 62655
});
const vulnerabilities = ref([
{ id: "CVE-2024-9999", description: "发生堆缓冲区溢出攻击" },
{ id: "CVE-123456", description: "发布在一天之前 2024-7-23 11:44" }
]);
const recentScansData = ref({
labels: ["一月", "二月", "三月", "四月", "五月"],
datasets: [
{
label: "软件成分分析",
backgroundColor: "#72a4d2",
data: [613, 448, 540, 652, 977]
backgroundColor: "#ff6384",
data: [20, 42, 37, 45, 54]
},
{
label: "静态代码扫描(SAST)",
backgroundColor: "#8cd17d",
data: [138, 936, 777, 590, 54]
label: "Fuzz测试",
backgroundColor: "#36a2eb",
data: [12, 23, 34, 45, 56]
},
{
label: "静态代码分析",
backgroundColor: "#33bb33",
data: [32, 45, 23, 54, 32]
}
]
});
@ -71,101 +70,125 @@ const appRankingData = ref({
}
]
});
const radio3 = ref("静态代码分析");
</script>
<!--<template>-->
<!-- <div class="dashboard">-->
<!-- <h1>软件安全赋能平台</h1>-->
<!-- <div class="status-overview">-->
<!-- <div class="project-info">-->
<!-- <h2>项目信息</h2>-->
<!-- <div class="info-box">-->
<!-- <p>项目数量(): {{ projectInfo.projects }}</p>-->
<!-- <p>仓库数量(): {{ projectInfo.repositories }}</p>-->
<!-- <p>扫描次数: {{ projectInfo.scanTimes }}</p>-->
<!-- <p>扫描文件数量: {{ projectInfo.scanFiles }}</p>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="vulnerabilities">-->
<!-- <h2>最新漏洞与补丁提示</h2>-->
<!-- <ul>-->
<!-- <li v-for="vulnerability in vulnerabilities" :key="vulnerability.id">-->
<!-- {{ vulnerability.id }}: {{ vulnerability.description }}-->
<!-- </li>-->
<!-- </ul>-->
<!-- </div>-->
<!-- <div class="recent-scans">-->
<!-- <h2>近期扫描趋势</h2>-->
<!-- <Bar :data="recentScansData" />-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="details">-->
<!-- <div class="issues-ranking">-->
<!-- <h2>违规问题排行</h2>-->
<!-- <Bar :data="issuesRankingData" />-->
<!-- </div>-->
<!-- <div class="app-ranking">-->
<!-- <h2>违规应用排行</h2>-->
<!-- <Bar :data="appRankingData" />-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!--</template>-->
<template>
<div class="dashboard">
<div class="grid-container">
<Card title="项目信息">
<div class="info-box">
<p>项目数量(): {{ projectInfo.projects }}</p>
<p>仓库数量(): {{ projectInfo.repositories }}</p>
<p>扫描次数: {{ projectInfo.scanTimes }}</p>
<p>扫描文件数量: {{ projectInfo.scanFiles }}</p>
</div>
</Card>
<Card title="最新漏洞与补丁提示">
<ul>
<li v-for="vulnerability in vulnerabilities" :key="vulnerability.id">
{{ vulnerability.id }}: {{ vulnerability.description }}
</li>
</ul>
</Card>
<Card title="近期扫描趋势">
<Bar :data="recentScansData" />
</Card>
<Card title="违规问题排行">
<Bar :data="issuesRankingData" />
</Card>
<Card title="违规应用排行">
<Bar :data="appRankingData" />
</Card>
<el-row :gutter="10">
<el-col :span="8">
<el-card class="top-card">
<div class="card-title">应用信息</div>
<div class="app-info">
<div class="app-card">
<div class="right-info">
<div class="proj">项目数量()</div>
<div
class="proj-num"
style=" font-size: 14px; font-weight: bold;color: #47f"
>
{{ projectInfo.projects }}
</div>
</div>
</div>
<div class="app-card">
<div class="right-info">
<div class="repo">仓库数量()</div>
<div
class="repo-num"
style=" font-size: 14px; font-weight: bold;color: #87f"
>
{{ projectInfo.repositories }}
</div>
</div>
</div>
<div class="app-card">
<div class="right-info">
<div class="scan">扫描次数()</div>
<div
class="scan-num"
style=" font-size: 14px; font-weight: bold;color: #f83"
>
{{ projectInfo.scanTimes }}
</div>
</div>
</div>
<div class="app-card">
<div class="right-info">
<div class="file">扫描文件数量()</div>
<div
class="file-num"
style=" font-size: 14px; font-weight: bold;color: #3b6"
>
{{ projectInfo.scanFiles }}
</div>
</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="top-card">
<div class="card-title">最新漏洞与补丁提示</div>
<vulnerability-card />
</el-card>
</el-col>
<el-col :span="8">
<el-card class="top-card">
<div class="card-title">近期扫描趋势</div>
<Bar :data="recentScansData" />
</el-card>
</el-col>
</el-row>
<div style="margin: 6px 0 2px">
<el-radio-group v-model="radio3" size="small">
<el-radio-button label="静态代码分析" />
<el-radio-button label="架构一致性" />
<el-radio-button label="软件物料" />
</el-radio-group>
</div>
</div>
</template>
<style scoped lang="scss">
.dashboard {
padding: 20px;
background-color: #f4f5f7;
.dashboard >>> .el-card {
margin-bottom: 8px;
}
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 10px; /* Reduce the gap to make cards closer */
.top-card {
width: 100%;
height: 30vh;
margin-bottom: 8px;
}
.info-box p {
margin: 10px 0;
.card-title {
margin-bottom: 0 !important;
font-weight: 600;
}
ul {
padding: 0;
list-style: none;
.app-info {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: space-between;
}
ul li {
padding: 10px;
margin-bottom: 5px; /* Reduce margin for a tighter look */
background: #f2f2f2;
border-radius: 4px;
.app-card {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: calc(50% - 5px);
height: 10vh;
padding: 0.3vw;
margin-top: 6px;
margin-bottom: 4px;
background-color: #fff;
border: 1px solid #dde;
border-radius: 6px;
}
.app-card > .right-info {
width: 140px;
font-size: 14px;
}
</style>

View File

@ -14,28 +14,6 @@
</el-col>
</el-row>
</el-card>
<!-- <el-row :gutter="20" class="stats-row">-->
<!-- <el-col :span="8">-->
<!-- <div class="stats-card">-->
<!-- <h3>组件版本数</h3>-->
<!-- <div ref="componentVersionsChart" class="chart-container" />-->
<!-- </div>-->
<!-- </el-col>-->
<!-- <el-col :span="8">-->
<!-- <div class="stats-card">-->
<!-- <h3>安全漏洞</h3>-->
<!-- <div ref="securityIssuesChart" class="chart-container" />-->
<!-- </div>-->
<!-- </el-col>-->
<!-- <el-col :span="8">-->
<!-- <div class="stats-card">-->
<!-- <h3>有许可证的组件版本数</h3>-->
<!-- <div ref="licensedVersionsChart" class="chart-container" />-->
<!-- </div>-->
<!-- </el-col>-->
<!-- </el-row>-->
<el-tabs v-model="activeTab">
<el-tab-pane label="软件依赖成分分析" name="1">
<el-row :gutter="20">
@ -59,7 +37,7 @@
<el-table-column prop="lowRisk" label="低危" />
</el-table>
</el-tab-pane>
<el-tab-pane label="源代码静态检测" name="2">
<el-tab-pane label="Fuzzing扫描" name="2">
<!-- 这里可以添加源代码静态检测的内容 -->
</el-tab-pane>
</el-tabs>

View File

@ -1,9 +0,0 @@
<script setup lang="ts">
defineOptions({
name: "Welcome"
});
</script>
<template>
<h1>软件安全赋能平台</h1>
</template>