modify project display

This commit is contained in:
csh 2024-08-26 22:26:28 +08:00
parent 32c3d43d9a
commit 54ac45fdab
3 changed files with 133 additions and 31 deletions

View File

@ -84,7 +84,7 @@ const radio3 = ref("静态代码分析");
<div class="proj">项目数量()</div> <div class="proj">项目数量()</div>
<div <div
class="proj-num" class="proj-num"
style=" font-size: 14px; font-weight: bold;color: #47f" style="font-size: 14px; font-weight: bold; color: #47f"
> >
{{ projectInfo.projects }} {{ projectInfo.projects }}
</div> </div>
@ -95,7 +95,7 @@ const radio3 = ref("静态代码分析");
<div class="repo">仓库数量()</div> <div class="repo">仓库数量()</div>
<div <div
class="repo-num" class="repo-num"
style=" font-size: 14px; font-weight: bold;color: #87f" style="font-size: 14px; font-weight: bold; color: #87f"
> >
{{ projectInfo.repositories }} {{ projectInfo.repositories }}
</div> </div>
@ -106,7 +106,7 @@ const radio3 = ref("静态代码分析");
<div class="scan">扫描次数()</div> <div class="scan">扫描次数()</div>
<div <div
class="scan-num" class="scan-num"
style=" font-size: 14px; font-weight: bold;color: #f83" style="font-size: 14px; font-weight: bold; color: #f83"
> >
{{ projectInfo.scanTimes }} {{ projectInfo.scanTimes }}
</div> </div>
@ -117,7 +117,7 @@ const radio3 = ref("静态代码分析");
<div class="file">扫描文件数量()</div> <div class="file">扫描文件数量()</div>
<div <div
class="file-num" class="file-num"
style=" font-size: 14px; font-weight: bold;color: #3b6" style="font-size: 14px; font-weight: bold; color: #3b6"
> >
{{ projectInfo.scanFiles }} {{ projectInfo.scanFiles }}
</div> </div>

View File

@ -1,11 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref, onMounted } from "vue";
import { http } from "@/utils/http";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { ArrowDown } from "@element-plus/icons-vue";
const showDropdown = ref(false);
const getStatLabel = (key: string): string => { const getStatLabel = (key: string): string => {
const labels: { [key: string]: string } = { const labels: { [key: string]: string } = {
totalProjects: "项目总数", totalProjects: "项目总数",
scanTimes: "扫描次数",
unscanned: "未扫描", unscanned: "未扫描",
outdatedScans: "未更新扫描", outdatedScans: "未更新扫描",
scanned: "已扫描" scanned: "已扫描"
@ -13,15 +16,37 @@ const getStatLabel = (key: string): string => {
return labels[key] || key; return labels[key] || key;
}; };
const formatDate = (dateString: string) => {
const date = new Date(dateString);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const day = date.getDate().toString().padStart(2, "0");
const hour = date.getHours().toString().padStart(2, "0");
const minute = date.getMinutes().toString().padStart(2, "0");
const second = date.getSeconds().toString().padStart(2, "0");
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
};
const projectStats = ref({ const projectStats = ref({
totalProjects: 32, totalProjects: 0,
scanTimes: 9, unscanned: 0,
unscanned: 2, outdatedScans: 0,
outdatedScans: 4, scanned: 0
scanned: 4
}); });
const projects = ref([ interface Project {
name: string;
status: string;
riskLevel: string;
lastUpdate: string;
lastScan: string;
riskDistribution: string;
scanType: string;
scanTime: string;
projectSource: string;
}
const _projects = ref([
{ {
name: "TestProject", name: "TestProject",
status: "已更新", status: "已更新",
@ -35,6 +60,55 @@ const projects = ref([
} }
]); ]);
const projects = ref<Project[]>([]);
const getProjectList = async params => {
var query = new URLSearchParams(params).toString();
var ret = [];
await http
.request<any[]>("get", "/project/api/project/v1/getprojlist?" + query)
.then(resSets => {
// projects.value = res;
for (let i = 0; i < resSets.length; i++) {
ret.push(resSets[i]);
}
});
return ret;
};
const fetchProjects = async () => {
projects.value = [];
var res = await getProjectList({ userUUID: "5" });
var unScanned = 0;
var outdatedScans = 0;
var scanned = 0;
console.log(res);
for (let i = 0; i < res.length; i++) {
if (res[i].lastScanStatus == null) unScanned++;
else if (res[i].lastScanStatus == "outdated") outdatedScans++;
else if (res[i].lastScanStatus == "scanned") scanned++;
projects.value.push({
name: res[i].projectName,
status: res[i].lastScanStatus,
riskLevel: null,
lastUpdate: res[i].lastUpdateTime,
lastScan: res[i].lastScanTime,
riskDistribution: null,
scanType: null,
scanTime: null,
// TODO:
projectSource: null
});
}
projectStats.value.totalProjects = res.length;
projectStats.value.unscanned = unScanned;
projectStats.value.outdatedScans = outdatedScans;
projectStats.value.scanned = scanned;
};
onMounted(async () => {
fetchProjects();
});
const router = useRouter(); const router = useRouter();
const navigateToDetails = () => { const navigateToDetails = () => {
@ -50,7 +124,20 @@ const navigateToDetails = () => {
</div> </div>
</div> </div>
<div class="actions"> <div class="actions">
<button class="btn">+ 新建项目</button> <el-dropdown>
<el-button type="primary" size="large" class="new_btn">
+ 新建项目<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>从文件上传</el-dropdown-item>
<el-dropdown-item>从远程仓库导入</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-button class="refresh_btn" size="large" @click="fetchProjects"
>刷新项目列表</el-button
>
</div> </div>
<div class="filter-container"> <div class="filter-container">
<input type="text" placeholder="选择搜索类型(ID或name或者tags)" /> <input type="text" placeholder="选择搜索类型(ID或name或者tags)" />
@ -60,13 +147,13 @@ const navigateToDetails = () => {
<thead> <thead>
<tr> <tr>
<th>项目名称</th> <th>项目名称</th>
<th>更新状态</th> <th>状态</th>
<th>风险等级</th> <th>风险等级</th>
<th>最近一次更新时间</th>
<th>最近一次扫描时间</th> <th>最近一次扫描时间</th>
<th>风险分布</th> <th>风险分布</th>
<th>扫描类别</th> <th>扫描类别</th>
<th>扫描耗费时间</th> <th>扫描耗费时间</th>
<th>项目地址</th>
<th>项目来源</th> <th>项目来源</th>
<th>扫描</th> <th>扫描</th>
</tr> </tr>
@ -80,19 +167,17 @@ const navigateToDetails = () => {
</td> </td>
<td>{{ project.status }}</td> <td>{{ project.status }}</td>
<td>{{ project.riskLevel }}</td> <td>{{ project.riskLevel }}</td>
<td>{{ project.lastScan }}</td> <td>
{{
project.lastUpdate == null ? null : formatDate(project.lastUpdate)
}}
</td>
<td>
{{ project.lastScan == null ? null : formatDate(project.lastScan) }}
</td>
<td>{{ project.riskDistribution }}</td> <td>{{ project.riskDistribution }}</td>
<td>{{ project.scanType }}</td> <td>{{ project.scanType }}</td>
<td>{{ project.scanTime }}</td> <td>{{ project.scanTime }}</td>
<td>
<a
:href="'https://' + project.projectLink"
target="_blank"
rel="noopener noreferrer"
>
{{ project.projectLink }}
</a>
</td>
<td>{{ project.projectSource }}</td> <td>{{ project.projectSource }}</td>
<td><button class="scan-btn">扫描</button></td> <td><button class="scan-btn">扫描</button></td>
</tr> </tr>
@ -128,13 +213,24 @@ const navigateToDetails = () => {
margin-bottom: 20px; margin-bottom: 20px;
} }
.btn { .new_btn {
padding: 10px 20px;
color: white; color: white;
cursor: pointer;
background: #4caf50; background: #4caf50;
border: none; border: #4caf50;
border-radius: 4px; }
.new_btn:hover {
background: #3e8e41;
}
.refresh_btn {
margin-left: 20px;
color: white;
background: #409eff;
}
.refresh_btn:hover {
background: #2a80eb;
} }
.filter-container { .filter-container {

View File

@ -24,7 +24,13 @@ export default ({ mode }: ConfigEnv): UserConfigExport => {
port: VITE_PORT, port: VITE_PORT,
host: "0.0.0.0", host: "0.0.0.0",
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy // 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {}, proxy: {
"/project/api": {
target: "http://localhost:8866",
changeOrigin: true,
rewrite: path => path.replace(/^\/project\/api/, "")
}
},
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布 // 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
warmup: { warmup: {
clientFiles: ["./index.html", "./src/{views,components}/*"] clientFiles: ["./index.html", "./src/{views,components}/*"]