2025-03-14 20:03:14 +08:00
|
|
|
|
<template>
|
2025-03-17 15:58:18 +08:00
|
|
|
|
<div class="info-outside w-full">
|
|
|
|
|
|
<div class="info">
|
|
|
|
|
|
<div class="flex items-center justify-start w-full gap-1">
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<img src="@/assets/imgs/jyh/aiIcon.png" />
|
2025-03-17 15:58:18 +08:00
|
|
|
|
<span class="text-base font-medium">AI修复建议:</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div>
|
2025-03-26 17:30:31 +08:00
|
|
|
|
<br />通过AI技术精准诊断漏洞类型,智能匹配多维度定制化修复策略,实现从数据校验、代码加固到权限控制的全链路防御,助力漏洞修复效率提升,全方位保障开源软件使用安全。<br />
|
2025-03-26 17:52:03 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- <ul>-->
|
|
|
|
|
|
<!-- <li v-for="info in infoList">{{ info }}</li>-->
|
|
|
|
|
|
<!-- </ul>-->
|
2025-03-17 15:58:18 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2025-03-14 20:03:14 +08:00
|
|
|
|
<div class="ai-container">
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<template v-if="tableData.length > 0">
|
|
|
|
|
|
<div class="ai-container-card" style="width: 100%" v-for="(rowItem, index) in tableData" :key="index">
|
2025-03-26 20:44:05 +08:00
|
|
|
|
<Panel :expand="rowItem.expand">
|
2025-03-19 21:43:36 +08:00
|
|
|
|
<template #header>
|
|
|
|
|
|
<div class="ai-panel-header">
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<div style="padding: 25px 8px 0px 20px">
|
|
|
|
|
|
<img style="width: 36px; height: 33px" src="@/assets/imgs/jyh/warning.png" />
|
2025-03-14 20:03:14 +08:00
|
|
|
|
</div>
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<div style="width: 100%; padding: 20px 20px 0px 0">
|
2025-03-19 21:43:36 +08:00
|
|
|
|
<div class="ai-panel-header-title">
|
|
|
|
|
|
<div>
|
2025-03-26 17:52:03 +08:00
|
|
|
|
<d-tag color="red-w98" class="mr-1" size="sm">严重</d-tag>
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<span>{{ rowItem.libraryName || '--' }}</span>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</div>
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<div
|
|
|
|
|
|
style="cursor: pointer; display: flex; gap: 8px; align-items: center"
|
2025-03-26 20:44:05 +08:00
|
|
|
|
@click="rowItem.expand = !rowItem.expand"
|
2025-03-21 12:11:57 +08:00
|
|
|
|
>
|
2025-03-26 20:44:05 +08:00
|
|
|
|
<d-icon :name="rowItem.expand ? 'icon-expand-new' : 'icon-drag-new'"></d-icon>
|
|
|
|
|
|
<span>{{ rowItem.expand ? '收起' : '展开' }}</span>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</div>
|
2025-03-14 20:03:14 +08:00
|
|
|
|
</div>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
<div class="ai-panel-header-sub-title">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<span class="weak-text">安全问题</span>
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<span>{{ rowItem.vulnerabilities.length || '--' }}</span>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</div>
|
2025-03-31 15:16:07 +08:00
|
|
|
|
<!-- <div>-->
|
|
|
|
|
|
<!-- <span class="weak-text">修复兼容性</span>-->
|
|
|
|
|
|
<!-- <span>{{ rowItem.vulnerabilities.length || '--' }}</span>-->
|
|
|
|
|
|
<!-- <d-tooltip-->
|
|
|
|
|
|
<!-- position="bottom"-->
|
|
|
|
|
|
<!-- content="这个评分是在比较当前版本和推荐版本之间的差异,并建议修复此组件时的复杂程度。"-->
|
|
|
|
|
|
<!-- >-->
|
|
|
|
|
|
<!-- <img src="@/assets/imgs/jyh/help.png" class="icon-sm" />-->
|
|
|
|
|
|
<!-- </d-tooltip>-->
|
|
|
|
|
|
<!-- <d-tag class="ml-1" type="warning" size="sm">{{'--'}}</d-tag>-->
|
|
|
|
|
|
<!-- </div>-->
|
2025-03-19 21:43:36 +08:00
|
|
|
|
<div>
|
|
|
|
|
|
<span class="weak-text">升级版本</span>
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<span>{{ rowItem.currentVersion || '--' }}</span>
|
|
|
|
|
|
<img src="@/assets/imgs/jyh/ic_digital_power_next_step_@2x.png" class="icon-sm" />
|
2025-04-25 17:51:01 +08:00
|
|
|
|
<span>{{ rowItem.recommendedVersion || '--' }}</span>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</div>
|
2025-03-14 20:03:14 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</template>
|
2025-03-14 20:03:14 +08:00
|
|
|
|
|
2025-03-19 21:43:36 +08:00
|
|
|
|
<template #body>
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<div style="padding: 8px 20px 20px 20px; width: 100%">
|
2025-03-26 20:09:09 +08:00
|
|
|
|
<Table class="jyh-table" :tableConfig="tableConfig" :dataSource="rowItem.vulnerabilities" :libraryName="rowItem.libraryName" :currentVersion="rowItem.currentVersion"/>
|
2025-03-21 12:11:57 +08:00
|
|
|
|
<div class="w-full flex items-center justify-end">
|
|
|
|
|
|
<span>共{{ rowItem.vulnerabilities.length }}条</span>
|
|
|
|
|
|
</div>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</Panel>
|
|
|
|
|
|
</div>
|
2025-03-26 20:44:05 +08:00
|
|
|
|
<div class="mt-20 mb-20 flex justify-end" v-if="tableData.length > 0">
|
|
|
|
|
|
<d-pagination
|
|
|
|
|
|
size="md"
|
|
|
|
|
|
:page-size-options="[10, 20, 50]"
|
|
|
|
|
|
:total="pager.total"
|
|
|
|
|
|
v-model:pageSize="pager.pageSize"
|
|
|
|
|
|
v-model:pageIndex="pager.pageIndex"
|
|
|
|
|
|
:max-items="5"
|
|
|
|
|
|
:can-change-page-size="true"
|
|
|
|
|
|
:can-view-total="true"
|
|
|
|
|
|
total-item-text="总计"
|
|
|
|
|
|
@page-index-change="fetchVulnList()"
|
|
|
|
|
|
@page-size-change="fetchVulnList()"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
<NoData v-else :small="false"></NoData>
|
2025-03-14 20:03:14 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-03-26 17:52:03 +08:00
|
|
|
|
import { defineProps, onMounted, ref } from 'vue';
|
2025-03-14 20:03:14 +08:00
|
|
|
|
import Panel from '@/components/AIRepair/Panel.vue';
|
|
|
|
|
|
import Table from '@/components/AIRepair/Table.vue';
|
2025-03-19 21:43:36 +08:00
|
|
|
|
import NoData from '@/components/NoData/NoData.vue';
|
2025-03-26 17:52:03 +08:00
|
|
|
|
import { getVulnList, remediationSearchRemediations } from '@/api/jyh';
|
|
|
|
|
|
|
2025-03-17 15:58:18 +08:00
|
|
|
|
const infoList = ref([
|
|
|
|
|
|
'当前代码主要风险为易受常见的注入攻击,包括命令注入、SQL注入、表达式注入,针对每种攻击,应提供相应的防范措施,如数据校验、使用安全函数和限制程序权限。',
|
|
|
|
|
|
'相对上一次检查,【提升点】在于代码基础编码问题少了47.8%,问题总数降低29.3%;'
|
2025-03-21 12:11:57 +08:00
|
|
|
|
]);
|
2025-03-17 15:58:18 +08:00
|
|
|
|
|
2025-03-14 20:03:14 +08:00
|
|
|
|
const tableConfig = ref([
|
|
|
|
|
|
{
|
2025-03-19 21:43:36 +08:00
|
|
|
|
field: 'vulnId',
|
2025-03-14 20:03:14 +08:00
|
|
|
|
header: '安全问题编号',
|
|
|
|
|
|
sortable: true,
|
|
|
|
|
|
sortMethod: null
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
2025-03-19 21:43:36 +08:00
|
|
|
|
field: 'vulnType',
|
2025-03-14 20:03:14 +08:00
|
|
|
|
header: '安全问题类型',
|
|
|
|
|
|
sortable: false,
|
2025-03-26 17:52:03 +08:00
|
|
|
|
sortMethod: null,
|
|
|
|
|
|
format: (val) => {
|
|
|
|
|
|
// val小写转大写
|
|
|
|
|
|
return (val || '').toUpperCase();
|
|
|
|
|
|
}
|
2025-03-14 20:03:14 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2025-03-19 21:43:36 +08:00
|
|
|
|
field: 'vulnId',
|
2025-03-14 20:03:14 +08:00
|
|
|
|
header: 'CWE编号',
|
|
|
|
|
|
sortable: false,
|
|
|
|
|
|
sortMethod: null
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
2025-03-19 21:43:36 +08:00
|
|
|
|
field: 'cvssScore',
|
2025-03-14 20:03:14 +08:00
|
|
|
|
header: '分值',
|
|
|
|
|
|
sortable: true,
|
|
|
|
|
|
sortMethod: null
|
2025-03-21 12:11:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
]);
|
2025-03-14 20:03:14 +08:00
|
|
|
|
|
2025-03-26 20:44:05 +08:00
|
|
|
|
|
|
|
|
|
|
const pager = ref({
|
|
|
|
|
|
total: 10,
|
|
|
|
|
|
pageIndex: 1,
|
|
|
|
|
|
pageSize: 10
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-03-26 17:52:03 +08:00
|
|
|
|
const propsData = defineProps(['versionId']);
|
2025-03-14 20:03:14 +08:00
|
|
|
|
|
2025-03-26 17:52:03 +08:00
|
|
|
|
const fetchVulnList = async () => {
|
|
|
|
|
|
const { data } = await remediationSearchRemediations({
|
|
|
|
|
|
// softwareId: 47,
|
|
|
|
|
|
softwareId: propsData.versionId,
|
2025-03-26 20:44:05 +08:00
|
|
|
|
current: pager.value.pageIndex,
|
|
|
|
|
|
size: pager.value.pageSize
|
2025-03-26 17:52:03 +08:00
|
|
|
|
// componentId: '',
|
2025-03-19 21:43:36 +08:00
|
|
|
|
});
|
2025-03-26 17:52:03 +08:00
|
|
|
|
|
|
|
|
|
|
if (data.data.code === 200) {
|
2025-04-22 14:52:34 +08:00
|
|
|
|
tableData.value = data?.data?.data?.records || [];
|
2025-03-26 20:44:05 +08:00
|
|
|
|
pager.value.total = data?.data?.data?.total || 0;
|
2025-03-19 21:43:36 +08:00
|
|
|
|
// pager.value.total = data?.data?.data?.total || [];
|
|
|
|
|
|
}
|
2025-03-21 12:11:57 +08:00
|
|
|
|
};
|
2025-03-26 17:52:03 +08:00
|
|
|
|
|
|
|
|
|
|
const tableData = ref([
|
|
|
|
|
|
// {
|
|
|
|
|
|
// "componentId": 1,
|
|
|
|
|
|
// "libraryName": "Spring Framework",
|
|
|
|
|
|
// "currentVersion": "5.3.26",
|
|
|
|
|
|
// "vulnerabilities": [
|
|
|
|
|
|
// {
|
|
|
|
|
|
// "vulnId": "CVE-2024-12345",
|
|
|
|
|
|
// "severity": "High",
|
|
|
|
|
|
// "vulnType": "Remote Code Execution",
|
|
|
|
|
|
// "cvssScore": 8.5,
|
|
|
|
|
|
// "remediation": {
|
|
|
|
|
|
// "recommendedFix": "Upgrade to version 5.3.27 or later.",
|
|
|
|
|
|
// "patchLink": "https://spring.io/security/advisory/CVE-2024-12345",
|
|
|
|
|
|
// "recommendedVersion": "5.3.27"
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// ]
|
|
|
|
|
|
// },
|
|
|
|
|
|
// {
|
|
|
|
|
|
// "componentId": 2,
|
|
|
|
|
|
// "libraryName": "Log4j",
|
|
|
|
|
|
// "currentVersion": "2.14.0",
|
|
|
|
|
|
// "vulnerabilities": [
|
|
|
|
|
|
// {
|
|
|
|
|
|
// "vulnId": "CVE-2023-67890",
|
|
|
|
|
|
// "severity": "Critical",
|
|
|
|
|
|
// "vulnType": "Information Disclosure",
|
|
|
|
|
|
// "cvssScore": 9.8,
|
|
|
|
|
|
// "remediation": {
|
|
|
|
|
|
// "recommendedFix": "Apply security patch 2.14.1.",
|
|
|
|
|
|
// "patchLink": "https://logging.apache.org/log4j/2.x/security.html",
|
|
|
|
|
|
// "recommendedVersion": "2.14.1"
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// ]
|
|
|
|
|
|
// }
|
|
|
|
|
|
]);
|
2025-03-21 12:11:57 +08:00
|
|
|
|
onMounted(() => {
|
2025-03-26 17:52:03 +08:00
|
|
|
|
fetchVulnList();
|
2025-03-19 21:43:36 +08:00
|
|
|
|
});
|
2025-03-14 20:03:14 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
@import 'devui-theme/styles-var/devui-var.scss';
|
|
|
|
|
|
|
|
|
|
|
|
.ai-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
&-card {
|
|
|
|
|
|
border-top: 2px solid $devui-danger;
|
|
|
|
|
|
background-color: $devui-base-bg;
|
|
|
|
|
|
border-radius: var(--devui-border-radius-card, 8px);
|
2025-03-21 12:11:57 +08:00
|
|
|
|
box-shadow: var(--devui-shadow-length-base, 0 2px 6px 0) var(--devui-light-shadow, rgba(37, 43, 58, 0.12));
|
2025-03-14 20:03:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ai-panel-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
2025-03-15 18:01:29 +08:00
|
|
|
|
height: 80px;
|
2025-03-14 20:03:14 +08:00
|
|
|
|
&-title {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&-sub-title {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
div {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-right: 20px;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
&:not(:last-child)::after {
|
|
|
|
|
|
content: '';
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
right: -10px;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
width: 1px;
|
|
|
|
|
|
background-color: $devui-line;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.weak-text {
|
|
|
|
|
|
color: $devui-text-weak;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.icon-sm {
|
|
|
|
|
|
width: 14px;
|
|
|
|
|
|
height: 14px;
|
|
|
|
|
|
}
|
2025-03-17 15:58:18 +08:00
|
|
|
|
|
|
|
|
|
|
.info-outside {
|
|
|
|
|
|
margin: 20px 0;
|
|
|
|
|
|
padding: 1px;
|
|
|
|
|
|
border-radius: 8px;
|
2025-03-21 12:11:57 +08:00
|
|
|
|
background-image: linear-gradient(
|
2025-03-26 17:52:03 +08:00
|
|
|
|
134.79deg,
|
|
|
|
|
|
#a4f7df 0%,
|
|
|
|
|
|
#a0cefb 21%,
|
|
|
|
|
|
#5f9afe 43%,
|
|
|
|
|
|
#d9b9fc 62%,
|
|
|
|
|
|
#01efbb 73%,
|
|
|
|
|
|
#fbae46 100%
|
2025-03-21 12:11:57 +08:00
|
|
|
|
);
|
2025-03-17 15:58:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info {
|
|
|
|
|
|
padding: 10px 20px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
img {
|
|
|
|
|
|
width: 24px;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
ul {
|
|
|
|
|
|
list-style: disc;
|
|
|
|
|
|
padding-left: 18px;
|
|
|
|
|
|
line-height: 22px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-19 21:43:36 +08:00
|
|
|
|
</style>
|