可信代码库-代码质量检测接口对接

This commit is contained in:
付民康
2025-06-27 14:15:26 +08:00
parent c1f7cb9025
commit f664d855bf
4 changed files with 167 additions and 68 deletions

View File

@@ -452,3 +452,35 @@ export function fetchUpdateRecommendQuestions(data) {
data: data,
});
}
export function qualityTaskOverview(data) {
const {softwareId} = data;
return axios.request({
url: `/gateway/quality/task-overview/software` + `/${softwareId}`,
method: 'GET',
// headers: {
// Authorization: 'Bearer ' + localStorage.getItem('access_token'),
// }
});
}
export function qualityDefectPage(data) {
const {pageNum,pageSize,softwareId} = data;
return axios.request({
url: `/gateway/quality/defect/page` + `?pageNum=${pageNum}&pageSize=${pageSize}&softwareId=${softwareId}`,
method: 'GET',
// headers: {
// Authorization: 'Bearer ' + localStorage.getItem('access_token'),
// }
});
}
export function loginAccess() {
return axios.request({
url: `/gateway/u-auth/login-access`,
method: 'POST',
data: {},
headers: {
Authorization: 'Bearer ' + localStorage.getItem('access_token'),
}
});
}

View File

@@ -446,7 +446,7 @@ const getQuestionHistory = async () => {
// Message.error(data.error||'接口异常!')
}
} else {
Message.error('请先登录!')
// Message.error('请先登录!')
}
};
const getQuestionCollection = async () => {
@@ -473,7 +473,7 @@ const getQuestionCollection = async () => {
// Message.error(data.error||'接口异常!')
}
} else {
Message.error('请先登录!')
// Message.error('请先登录!')
}
};

View File

@@ -1,6 +1,6 @@
<template>
<div>
<pre class="pre-code"><code :data-ln-start-from="1">
<div class="code">
<pre class="pre-code"><code :class="[codeIndex]" :data-ln-start-from="lineNumber">
<span v-html="renderCode(fixed_code)"></span>
</code></pre>
</div>
@@ -11,16 +11,24 @@
import hljs from 'highlight.js';
import 'highlight.js/styles/rainbow.css'; // 引入样式
import {lineNumbersBlock} from "@/utils/highlightjs-line-numbers";
import { onMounted, defineProps, nextTick,watch } from 'vue';
const fixed_code = '/*'
const props = defineProps(['lineNumber','content'])
const codeIndex = `code${props.content.id}`
const fixed_code = props.content.defectContent + '\t\t'
debugger
const lineNumber = props.content.lineNumber? props.content.lineNumber -1 : 0
const renderCode = (code, num = 1) => {
return hljs.highlightAuto(code).value;
};
// 显示代码行数
const updateLineNumbers = () => {
debugger
// 搜索pre、code元素进行高亮和行号添加
let blocks = document.querySelectorAll('pre code');
let blocks = document.querySelectorAll('.' + codeIndex);
console.log(blocks)
blocks.forEach((block) => {
//高亮
@@ -30,6 +38,21 @@ const updateLineNumbers = () => {
})
}
watch(() => props.content, (newVal) => {
if (newVal && newVal.id) {
nextTick(updateLineNumbers);
}
}, { immediate: true, deep: true });
onMounted(() => {
nextTick(() => {
updateLineNumbers()
})
});
</script>

View File

@@ -1,32 +1,32 @@
<template>
<Card simple class="jyh-card mb-4">
<d-row class="mb-3">
<d-col :span="8">
<span class="card-key width-140">问题数<d-icon style="color: grey" name="icon-info-o" size="12px" />
<d-col :span="16">
<span class="card-key width-140">问题数<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" />
</span>
<span class="card-val">{{ ReleaseInfo?.basicInfo?.softwareName || '--' }}</span>
<span class="card-val">{{ QualityTaskOverview?.issueCount || '--' }}</span>
</d-col>
<d-col :span="8">
<span class="card-key width-140">未解决问题<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>
<span class="card-val">{{ ReleaseInfo?.basicInfo?.softwareVersion || '--' }}</span>
</d-col>
<d-col :span="8">
<span class="card-key width-140">已解决问题数<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>
<span class="card-val">{{ ReleaseInfo?.basicInfo?.mainLanguageType || '--' }}</span>
<d-col :span="16">
<span class="card-key width-140">代码总行<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>
<span class="card-val">{{ QualityTaskOverview?.codeLineTotal || '--' }}</span>
</d-col>
<!-- <d-col :span="8">-->
<!-- <span class="card-key width-140">已忽略问题数<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>-->
<!-- <span class="card-val">{{ QualityTaskOverview?.dismissedCount || '&#45;&#45;' }}</span>-->
<!-- </d-col>-->
<!-- <d-col :span="8">-->
<!-- <span class="card-key width-140">已解决问题数<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>-->
<!-- <span class="card-val">{{ QualityTaskOverview?.solveCount || '&#45;&#45;' }}</span>-->
<!-- </d-col>-->
</d-row>
<d-row>
<d-col :span="8">
<span class="card-key width-140">代码平均复杂度<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>
<span class="card-val">{{ ReleaseInfo?.basicInfo?.developer || '--' }}</span>
</d-col>
<d-col :span="8">
<d-col :span="16">
<span class="card-key width-140">代码重复率<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>
<span class="card-val">{{ ReleaseInfo?.basicInfo?.developer || '--' }}</span>
<span class="card-val">{{ QualityTaskOverview?.duplicationRatio || '--' }}</span>
</d-col>
<d-col :span="8">
<span class="card-key width-140">代码总行数<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>
<span class="card-val">{{ ReleaseInfo?.basicInfo?.developer || '--' }}</span>
<d-col :span="16">
<span class="card-key width-140">代码平均复杂度<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" /></span>
<span class="card-val">{{ QualityTaskOverview?.cyclomaticComplexityPerMethod || '--' }}</span>
</d-col>
</d-row>
</Card>
@@ -42,8 +42,8 @@
<div style="width: 100%; padding: 20px 20px 0px 0">
<div class="ai-panel-header-title">
<div>
<d-tag color="red-w98" class="mr-1" size="sm">--</d-tag>
<span>{{ rowItem.libraryName || '--' }}</span>
<!-- <d-tag color="red-w98" class="mr-1" size="sm">&#45;&#45;</d-tag>-->
<span>{{ rowItem.defectCheckerName || '--' }}</span>
</div>
<div
style="cursor: pointer; display: flex; gap: 8px; align-items: center"
@@ -51,20 +51,30 @@
>
<div style="margin-right: 8px">
<span style="margin-right: 4px" class="weak-text">问题发现时间</span>
<span>{{ rowItem.vulnerabilities.length || '--' }}</span>
<span>{{ dayjs(new Date(rowItem.createdAt)).format('YYYY-MM-DD HH:mm:ss') || '--' }}</span>
</div>
<div style="margin-right: 8px">
<span style="margin-right: 4px" class="weak-text">修改点个数</span>
<span>{{ rowItem.vulnerabilities.length || '--' }}</span>
<span style="margin-right: 4px" class="weak-text">缺陷级别</span>
<d-tag :color="levelMap[rowItem.defectLevel]?.color" size="sm">{{
levelMap[rowItem.defectLevel]?.text || '--'
}}</d-tag>
<!-- <span>{{ defectLevelMap[rowItem.defectLevel] || '&#45;&#45;' }}</span>-->
</div>
<div style="margin-right: 8px">
<span style="margin-right: 4px" class="weak-text">缺陷状态</span>
<d-tag :color="statusMap[rowItem.defectStatus]?.color" size="sm">{{
levelMap[rowItem.defectStatus]?.text || '--'
}}</d-tag>
<!-- <span>{{ defectStatusMap[rowItem.defectStatus] || '&#45;&#45;' }}</span>-->
</div>
<d-icon :name="rowItem.expand ? 'icon-expand-new' : 'icon-drag-new'"></d-icon>
<span>{{ rowItem.expand ? '收起' : '展开' }}</span>
</div>
</div>
<div class="ai-panel-header-sub-title">
<div style="margin-top: 6px" class="ai-panel-header-sub-title">
<div>
<span class="weak-text">待处理 </span>
<span>{{ rowItem.vulnerabilities.length || '--' }}</span>
<span class="weak-text">文件路径 </span>
<a class="devui-link">{{ rowItem.filePath || '--' }}</a>
</div>
<!-- <div>-->
<!-- <span class="weak-text">修复兼容性</span>-->
@@ -77,12 +87,12 @@
<!-- </d-tooltip>-->
<!-- <d-tag class="ml-1" type="warning" size="sm">{{'&#45;&#45;'}}</d-tag>-->
<!-- </div>-->
<div>
<span class="weak-text">负责人</span>
<span>{{ rowItem.currentVersion || '--' }}</span>
<!-- <img src="@/assets/imgs/jyh/ic_digital_power_next_step_@2x.png" class="icon-sm" />-->
<!-- <span>{{ rowItem.recommendedVersion || '&#45;&#45;' }}</span>-->
</div>
<!-- <div>-->
<!-- <span class="weak-text">负责人</span>-->
<!-- <span>{{ rowItem.currentVersion || '&#45;&#45;' }}</span>-->
<!--&lt;!&ndash; <img src="@/assets/imgs/jyh/ic_digital_power_next_step_@2x.png" class="icon-sm" />&ndash;&gt;-->
<!--&lt;!&ndash; <span>{{ rowItem.recommendedVersion || '&#45;&#45;' }}</span>&ndash;&gt;-->
<!-- </div>-->
</div>
</div>
</div>
@@ -90,11 +100,11 @@
<template #body>
<div style="padding: 8px 20px 20px 20px; width: 100%">
<Code />
<!-- <Table class="jyh-table" :tableConfig="tableConfig" :dataSource="rowItem.vulnerabilities" :libraryName="rowItem.libraryName" :currentVersion="rowItem.currentVersion"/>-->
<!-- <div class="w-full flex items-center justify-end">-->
<!-- <span>{{ rowItem.vulnerabilities.length }}</span>-->
<!-- </div>-->
<Code v-if="rowItem.expand" :content="rowItem" :lineNumber="rowItem.lineNumber" />
<!-- <Table class="jyh-table" :tableConfig="tableConfig" :dataSource="rowItem.vulnerabilities" :libraryName="rowItem.libraryName" :currentVersion="rowItem.currentVersion"/>-->
<!-- <div class="w-full flex items-center justify-end">-->
<!-- <span>{{ rowItem.vulnerabilities.length }}</span>-->
<!-- </div>-->
</div>
</template>
</Panel>
@@ -102,7 +112,7 @@
<div class="mt-20 mb-20 flex justify-end" v-if="tableData.length > 0">
<d-pagination
size="md"
:page-size-options="[10, 20, 50]"
:page-size-options="[5, 10, 20]"
:total="pager.total"
v-model:pageSize="pager.pageSize"
v-model:pageIndex="pager.pageIndex"
@@ -110,8 +120,8 @@
:can-change-page-size="true"
:can-view-total="true"
total-item-text="总计"
@page-index-change="fetchVulnList()"
@page-size-change="fetchVulnList()"
@page-index-change="fetchQualityDefectPage()"
@page-size-change="fetchQualityDefectPage()"
/>
</div>
</template>
@@ -124,8 +134,25 @@ import { defineProps, onMounted, ref } from 'vue';
import Panel from '@/components/AIRepair/Panel.vue';
import Table from '@/components/AIRepair/Table.vue';
import NoData from '@/components/NoData/NoData.vue';
import dayjs from 'dayjs';
import Code from './Code.vue';
import { getVulnList, remediationSearchRemediations } from '@/api/jyh';
import { getVulnList, qualityDefectPage, qualityTaskOverview, remediationSearchRemediations } from '@/api/jyh';
import { Message } from 'vue-devui';
// 缺陷级别映射
const levelMap = {
'0': { text: '致命', color: '#ef4444' }, // 红色
'1': { text: '严重', color: '#f97316' }, // 橙色
'2': { text: '一般', color: '#eab308' }, // 黄色
'3': { text: '提示', color: '#10b981' } // 绿色
}
// 缺陷状态映射
const statusMap = {
'0': { text: '未解决', color: '#ef4444' }, // 红色
'1': { text: '已解决', color: '#10b981' }, // 绿色
'2': { text: '已忽略', color: '#9ca3af' } // 灰色
}
const infoList = ref([
'当前代码主要风险为易受常见的注入攻击包括命令注入、SQL注入、表达式注入针对每种攻击应提供相应的防范措施如数据校验、使用安全函数和限制程序权限。',
@@ -167,39 +194,56 @@ const tableConfig = ref([
const pager = ref({
total: 0,
pageIndex: 1,
pageSize: 10
pageSize: 5
});
const propsData = defineProps(['versionId']);
const fetchVulnList = async () => {
const { data } = await remediationSearchRemediations({
const QualityTaskOverview = ref({});
const fetchQualityTaskOverview = async () => {
const { data } = await qualityTaskOverview({
// softwareId: 47,
softwareId: propsData.versionId,
current: pager.value.pageIndex,
size: pager.value.pageSize
pageNum: pager.value.pageIndex,
pageSize: pager.value.pageSize
// componentId: '',
});
if (data.data.code === 200) {
tableData.value = data?.data?.data?.records || [];
pager.value.total = data?.data?.data?.total || 0;
debugger
if (data.code === 200) {
QualityTaskOverview.value = data?.data;
// pager.value.total = data?.data?.data?.total || [];
} else {
// Message.error(data.msg);
}
};
const fetchQualityDefectPage= async () => {
const { data } = await qualityDefectPage({
// softwareId: 47,
softwareId: propsData.versionId,
pageNum: pager.value.pageIndex,
pageSize: pager.value.pageSize
// componentId: '',
});
debugger
if (data.code === 200) {
tableData.value = data?.data?.records.map(i=>{
return {
...i,
expand:true
}
}) || [];
pager.value.total = data?.data?.total || 0;
// pager.value.total = data?.data?.data?.total || [];
} else {
// Message.error(data.msg);
}
};
const tableData = ref([
{
"componentId": 1,
"libraryName": "",
"currentVersion": "",
expand: true,
"vulnerabilities": [ ]
}
]);
const tableData = ref([]);
onMounted(() => {
// fetchVulnList();
fetchQualityTaskOverview();
fetchQualityDefectPage();
});
</script>