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

@ -1,11 +1,14 @@
<script setup lang="ts">
import { ref } from "vue";
import { ref, onMounted } from "vue";
import { http } from "@/utils/http";
import { useRouter } from "vue-router";
import { ArrowDown } from "@element-plus/icons-vue";
const showDropdown = ref(false);
const getStatLabel = (key: string): string => {
const labels: { [key: string]: string } = {
totalProjects: "项目总数",
scanTimes: "扫描次数",
unscanned: "未扫描",
outdatedScans: "未更新扫描",
scanned: "已扫描"
@ -13,15 +16,37 @@ const getStatLabel = (key: string): string => {
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({
totalProjects: 32,
scanTimes: 9,
unscanned: 2,
outdatedScans: 4,
scanned: 4
totalProjects: 0,
unscanned: 0,
outdatedScans: 0,
scanned: 0
});
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",
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 navigateToDetails = () => {
@ -50,7 +124,20 @@ const navigateToDetails = () => {
</div>
</div>
<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 class="filter-container">
<input type="text" placeholder="选择搜索类型(ID或name或者tags)" />
@ -60,13 +147,13 @@ const navigateToDetails = () => {
<thead>
<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>
</tr>
@ -80,19 +167,17 @@ const navigateToDetails = () => {
</td>
<td>{{ project.status }}</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.scanType }}</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><button class="scan-btn">扫描</button></td>
</tr>
@ -128,13 +213,24 @@ const navigateToDetails = () => {
margin-bottom: 20px;
}
.btn {
padding: 10px 20px;
.new_btn {
color: white;
cursor: pointer;
background: #4caf50;
border: none;
border-radius: 4px;
border: #4caf50;
}
.new_btn:hover {
background: #3e8e41;
}
.refresh_btn {
margin-left: 20px;
color: white;
background: #409eff;
}
.refresh_btn:hover {
background: #2a80eb;
}
.filter-container {

View File

@ -24,7 +24,13 @@ export default ({ mode }: ConfigEnv): UserConfigExport => {
port: VITE_PORT,
host: "0.0.0.0",
// 本地跨域代理 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: {
clientFiles: ["./index.html", "./src/{views,components}/*"]