可信代码库-代码质量检测接口对接
This commit is contained in:
@@ -452,3 +452,35 @@ export function fetchUpdateRecommendQuestions(data) {
|
|||||||
data: 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'),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ const getQuestionHistory = async () => {
|
|||||||
// Message.error(data.error||'接口异常!')
|
// Message.error(data.error||'接口异常!')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Message.error('请先登录!')
|
// Message.error('请先登录!')
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const getQuestionCollection = async () => {
|
const getQuestionCollection = async () => {
|
||||||
@@ -473,7 +473,7 @@ const getQuestionCollection = async () => {
|
|||||||
// Message.error(data.error||'接口异常!')
|
// Message.error(data.error||'接口异常!')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Message.error('请先登录!')
|
// Message.error('请先登录!')
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="code">
|
||||||
<pre class="pre-code"><code :data-ln-start-from="1">
|
<pre class="pre-code"><code :class="[codeIndex]" :data-ln-start-from="lineNumber">
|
||||||
<span v-html="renderCode(fixed_code)"></span>
|
<span v-html="renderCode(fixed_code)"></span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</div>
|
</div>
|
||||||
@@ -11,16 +11,24 @@
|
|||||||
import hljs from 'highlight.js';
|
import hljs from 'highlight.js';
|
||||||
import 'highlight.js/styles/rainbow.css'; // 引入样式
|
import 'highlight.js/styles/rainbow.css'; // 引入样式
|
||||||
import {lineNumbersBlock} from "@/utils/highlightjs-line-numbers";
|
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) => {
|
const renderCode = (code, num = 1) => {
|
||||||
return hljs.highlightAuto(code).value;
|
return hljs.highlightAuto(code).value;
|
||||||
};
|
};
|
||||||
// 显示代码行数
|
// 显示代码行数
|
||||||
const updateLineNumbers = () => {
|
const updateLineNumbers = () => {
|
||||||
|
debugger
|
||||||
// 搜索pre、code元素进行高亮和行号添加
|
// 搜索pre、code元素进行高亮和行号添加
|
||||||
let blocks = document.querySelectorAll('pre code');
|
let blocks = document.querySelectorAll('.' + codeIndex);
|
||||||
console.log(blocks)
|
console.log(blocks)
|
||||||
blocks.forEach((block) => {
|
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>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<Card simple class="jyh-card mb-4">
|
<Card simple class="jyh-card mb-4">
|
||||||
<d-row class="mb-3">
|
<d-row class="mb-3">
|
||||||
<d-col :span="8">
|
<d-col :span="16">
|
||||||
<span class="card-key width-140">问题数<d-icon style="color: grey" name="icon-info-o" size="12px" />
|
<span class="card-key width-140">问题数<d-icon style="color: grey; margin-left: 4px" name="icon-info-o" size="12px" />
|
||||||
</span>
|
</span>
|
||||||
<span class="card-val">{{ ReleaseInfo?.basicInfo?.softwareName || '--' }}</span>
|
<span class="card-val">{{ QualityTaskOverview?.issueCount || '--' }}</span>
|
||||||
</d-col>
|
</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-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>
|
<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">{{ ReleaseInfo?.basicInfo?.mainLanguageType || '--' }}</span>
|
|
||||||
</d-col>
|
</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 || '--' }}</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 || '--' }}</span>-->
|
||||||
|
<!-- </d-col>-->
|
||||||
</d-row>
|
</d-row>
|
||||||
<d-row>
|
<d-row>
|
||||||
<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>
|
|
||||||
</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-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>
|
||||||
<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-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?.cyclomaticComplexityPerMethod || '--' }}</span>
|
||||||
</d-col>
|
</d-col>
|
||||||
</d-row>
|
</d-row>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -42,8 +42,8 @@
|
|||||||
<div style="width: 100%; padding: 20px 20px 0px 0">
|
<div style="width: 100%; padding: 20px 20px 0px 0">
|
||||||
<div class="ai-panel-header-title">
|
<div class="ai-panel-header-title">
|
||||||
<div>
|
<div>
|
||||||
<d-tag color="red-w98" class="mr-1" size="sm">--</d-tag>
|
<!-- <d-tag color="red-w98" class="mr-1" size="sm">--</d-tag>-->
|
||||||
<span>{{ rowItem.libraryName || '--' }}</span>
|
<span>{{ rowItem.defectCheckerName || '--' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style="cursor: pointer; display: flex; gap: 8px; align-items: center"
|
style="cursor: pointer; display: flex; gap: 8px; align-items: center"
|
||||||
@@ -51,20 +51,30 @@
|
|||||||
>
|
>
|
||||||
<div style="margin-right: 8px">
|
<div style="margin-right: 8px">
|
||||||
<span style="margin-right: 4px" class="weak-text">问题发现时间</span>
|
<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>
|
||||||
<div style="margin-right: 8px">
|
<div style="margin-right: 8px">
|
||||||
<span style="margin-right: 4px" class="weak-text">修改点个数</span>
|
<span style="margin-right: 4px" class="weak-text">缺陷级别</span>
|
||||||
<span>{{ rowItem.vulnerabilities.length || '--' }}</span>
|
<d-tag :color="levelMap[rowItem.defectLevel]?.color" size="sm">{{
|
||||||
|
levelMap[rowItem.defectLevel]?.text || '--'
|
||||||
|
}}</d-tag>
|
||||||
|
<!-- <span>{{ defectLevelMap[rowItem.defectLevel] || '--' }}</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] || '--' }}</span>-->
|
||||||
</div>
|
</div>
|
||||||
<d-icon :name="rowItem.expand ? 'icon-expand-new' : 'icon-drag-new'"></d-icon>
|
<d-icon :name="rowItem.expand ? 'icon-expand-new' : 'icon-drag-new'"></d-icon>
|
||||||
<span>{{ rowItem.expand ? '收起' : '展开' }}</span>
|
<span>{{ rowItem.expand ? '收起' : '展开' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ai-panel-header-sub-title">
|
<div style="margin-top: 6px" class="ai-panel-header-sub-title">
|
||||||
<div>
|
<div>
|
||||||
<span class="weak-text">待处理 </span>
|
<span class="weak-text">文件路径 </span>
|
||||||
<span>{{ rowItem.vulnerabilities.length || '--' }}</span>
|
<a class="devui-link">{{ rowItem.filePath || '--' }}</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div>-->
|
<!-- <div>-->
|
||||||
<!-- <span class="weak-text">修复兼容性</span>-->
|
<!-- <span class="weak-text">修复兼容性</span>-->
|
||||||
@@ -77,12 +87,12 @@
|
|||||||
<!-- </d-tooltip>-->
|
<!-- </d-tooltip>-->
|
||||||
<!-- <d-tag class="ml-1" type="warning" size="sm">{{'--'}}</d-tag>-->
|
<!-- <d-tag class="ml-1" type="warning" size="sm">{{'--'}}</d-tag>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<div>
|
<!-- <div>-->
|
||||||
<span class="weak-text">负责人</span>
|
<!-- <span class="weak-text">负责人</span>-->
|
||||||
<span>{{ rowItem.currentVersion || '--' }}</span>
|
<!-- <span>{{ rowItem.currentVersion || '--' }}</span>-->
|
||||||
<!-- <img src="@/assets/imgs/jyh/ic_digital_power_next_step_@2x.png" class="icon-sm" />-->
|
<!--<!– <img src="@/assets/imgs/jyh/ic_digital_power_next_step_@2x.png" class="icon-sm" />–>-->
|
||||||
<!-- <span>{{ rowItem.recommendedVersion || '--' }}</span>-->
|
<!--<!– <span>{{ rowItem.recommendedVersion || '--' }}</span>–>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,7 +100,7 @@
|
|||||||
|
|
||||||
<template #body>
|
<template #body>
|
||||||
<div style="padding: 8px 20px 20px 20px; width: 100%">
|
<div style="padding: 8px 20px 20px 20px; width: 100%">
|
||||||
<Code />
|
<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"/>-->
|
<!-- <Table class="jyh-table" :tableConfig="tableConfig" :dataSource="rowItem.vulnerabilities" :libraryName="rowItem.libraryName" :currentVersion="rowItem.currentVersion"/>-->
|
||||||
<!-- <div class="w-full flex items-center justify-end">-->
|
<!-- <div class="w-full flex items-center justify-end">-->
|
||||||
<!-- <span>共{{ rowItem.vulnerabilities.length }}条</span>-->
|
<!-- <span>共{{ rowItem.vulnerabilities.length }}条</span>-->
|
||||||
@@ -102,7 +112,7 @@
|
|||||||
<div class="mt-20 mb-20 flex justify-end" v-if="tableData.length > 0">
|
<div class="mt-20 mb-20 flex justify-end" v-if="tableData.length > 0">
|
||||||
<d-pagination
|
<d-pagination
|
||||||
size="md"
|
size="md"
|
||||||
:page-size-options="[10, 20, 50]"
|
:page-size-options="[5, 10, 20]"
|
||||||
:total="pager.total"
|
:total="pager.total"
|
||||||
v-model:pageSize="pager.pageSize"
|
v-model:pageSize="pager.pageSize"
|
||||||
v-model:pageIndex="pager.pageIndex"
|
v-model:pageIndex="pager.pageIndex"
|
||||||
@@ -110,8 +120,8 @@
|
|||||||
:can-change-page-size="true"
|
:can-change-page-size="true"
|
||||||
:can-view-total="true"
|
:can-view-total="true"
|
||||||
total-item-text="总计"
|
total-item-text="总计"
|
||||||
@page-index-change="fetchVulnList()"
|
@page-index-change="fetchQualityDefectPage()"
|
||||||
@page-size-change="fetchVulnList()"
|
@page-size-change="fetchQualityDefectPage()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -124,8 +134,25 @@ import { defineProps, onMounted, ref } from 'vue';
|
|||||||
import Panel from '@/components/AIRepair/Panel.vue';
|
import Panel from '@/components/AIRepair/Panel.vue';
|
||||||
import Table from '@/components/AIRepair/Table.vue';
|
import Table from '@/components/AIRepair/Table.vue';
|
||||||
import NoData from '@/components/NoData/NoData.vue';
|
import NoData from '@/components/NoData/NoData.vue';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
import Code from './Code.vue';
|
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([
|
const infoList = ref([
|
||||||
'当前代码主要风险为易受常见的注入攻击,包括命令注入、SQL注入、表达式注入,针对每种攻击,应提供相应的防范措施,如数据校验、使用安全函数和限制程序权限。',
|
'当前代码主要风险为易受常见的注入攻击,包括命令注入、SQL注入、表达式注入,针对每种攻击,应提供相应的防范措施,如数据校验、使用安全函数和限制程序权限。',
|
||||||
@@ -167,39 +194,56 @@ const tableConfig = ref([
|
|||||||
const pager = ref({
|
const pager = ref({
|
||||||
total: 0,
|
total: 0,
|
||||||
pageIndex: 1,
|
pageIndex: 1,
|
||||||
pageSize: 10
|
pageSize: 5
|
||||||
});
|
});
|
||||||
|
|
||||||
const propsData = defineProps(['versionId']);
|
const propsData = defineProps(['versionId']);
|
||||||
|
|
||||||
const fetchVulnList = async () => {
|
|
||||||
const { data } = await remediationSearchRemediations({
|
const QualityTaskOverview = ref({});
|
||||||
|
const fetchQualityTaskOverview = async () => {
|
||||||
|
const { data } = await qualityTaskOverview({
|
||||||
// softwareId: 47,
|
// softwareId: 47,
|
||||||
softwareId: propsData.versionId,
|
softwareId: propsData.versionId,
|
||||||
current: pager.value.pageIndex,
|
pageNum: pager.value.pageIndex,
|
||||||
size: pager.value.pageSize
|
pageSize: pager.value.pageSize
|
||||||
// componentId: '',
|
// componentId: '',
|
||||||
});
|
});
|
||||||
|
debugger
|
||||||
if (data.data.code === 200) {
|
if (data.code === 200) {
|
||||||
tableData.value = data?.data?.data?.records || [];
|
QualityTaskOverview.value = data?.data;
|
||||||
pager.value.total = data?.data?.data?.total || 0;
|
|
||||||
// pager.value.total = data?.data?.data?.total || [];
|
// 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([
|
const tableData = ref([]);
|
||||||
{
|
|
||||||
"componentId": 1,
|
|
||||||
"libraryName": "",
|
|
||||||
"currentVersion": "",
|
|
||||||
|
|
||||||
expand: true,
|
|
||||||
"vulnerabilities": [ ]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// fetchVulnList();
|
fetchQualityTaskOverview();
|
||||||
|
fetchQualityDefectPage();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user