This commit is contained in:
黄心宇 2024-06-06 15:59:56 +08:00
parent aa509ef613
commit 5c15094344
4 changed files with 141 additions and 13 deletions

View File

@ -1,10 +1,11 @@
import fetch from './fetch';
// 获取列表
export function getList(facets) {
export function getList(params) {
return fetch({
url: `/api/issues/search?components=kingchanx-fluid-cloudnative_fluid&s=FILE_LINE&issueStatuses=CONFIRMED%2COPEN&ps=100&facets=${ facets }&additionalFields=_all&timeZone=Asia%2FShanghai`,
url: `/api/issues/search?components=kingchanx-fluid-cloudnative_fluid&s=FILE_LINE&issueStatuses=CONFIRMED%2COPEN&ps=100&&additionalFields=_all&timeZone=Asia%2FShanghai`,
method: 'get',
params
});
}

View File

@ -178,6 +178,7 @@
display: flex;
.left-content {
width: 218px;
flex-shrink: 0;
.filter-title {
font-weight: bold;
font-size: 17px;
@ -186,15 +187,19 @@
}
.filter-item {
padding: 0 20px;
margin: 2px 0;
display: flex;
justify-content: space-between;
align-items: center;
height: 54px;
height: 50px;
cursor: pointer;
&:hover {
background: #466bff0c;
}
}
.selected-item {
background: #466bff17;
}
.ant-divider {
margin: 20px;
width: auto;
@ -239,6 +244,7 @@
font-weight: bold;
font-size: 15px;
color: #111010;
word-break: break-word;
span:nth-of-type(1) {
font-weight: 400;
font-size: 14px;
@ -255,5 +261,44 @@
}
.total-info {
padding: 20px;
.info-list {
display: flex;
.total-item {
display: flex;
flex-direction: column;
min-height: 53px;
font-weight: 400;
font-size: 15px;
color: #525151;
> span:nth-child(2) {
font-weight: bold;
font-size: 18px;
color: #111010;
}
.item-more {
font-weight: 400;
font-size: 12px;
color: #525151;
span {
color: #466AFF;
}
}
}
.total-item:not(:last-child) {
margin-right: 40px;
}
.total-item:nth-child(n + 2) {
margin-left: 64px;
position: relative;
&::after {
position: absolute;
left: -40px;
content: '';
width: 0px;
height: 53px;
border-left: 1px solid rgba(187,189,197,0.61);
}
}
}
}
}

View File

@ -4,6 +4,7 @@ import './detail.scss';
import ProblemDetail from "./component/ProblemDetail";
import { issueType, issueTypeKeys, maintainability } from "../constants/quality"
import { Divider } from 'antd';
import { formatNumber } from '../../Utils/utils'
function issueList(props){
const [ issues, setIssues ] = useState({});
@ -12,7 +13,10 @@ function issueList(props){
const [ listFilter, setListFilter ] = useState({});
const [ selectedIssue, setSelectedIssue ] = useState(null);
const [ detailVisible, setDetailVisible ] = useState(true);
const [ issueInfo, setIssueInfo ] = useState(null);
const [ issueInfo, setIssueInfo ] = useState({});
const [ selectedType, setSelectedType ] = useState([]);
const [ selectedSeverity, setSelectedSeverity ] = useState([]);
const [ selectedTag, setSelectedTag ] = useState([]);
const { projectDetail } = props;
const metricKeys = 'lines,coverage,lines_to_cover,duplicated_lines_density,maintainability_issues,vulnerabilities,bugs,code_smells'
const facets = 'impactSeverities,tags,types'
@ -38,7 +42,17 @@ function issueList(props){
});
setBaseData(result)
})
getList(facets).then(res => {
getIssueList()
}, [projectDetail])
function getIssueList() {
let params = {
facets: facets,
types: selectedType.join(','),
impactSeverities: selectedSeverity.join(','),
tags: selectedTag.join(','),
}
getList(params).then(res => {
let issues = res.issues
let issuesHandled = {}
issues.forEach(e => {
@ -52,12 +66,15 @@ function issueList(props){
res.facets.forEach(e => {
filter[e.property] = e.values
})
console.log(filter);
setListFilter(filter)
setBaseInfo(res)
setIssues(issuesHandled)
})
}, [projectDetail])
}
useEffect(() => {
getIssueList()
},[selectedType, selectedSeverity, selectedTag])
function detail(e) {
setSelectedIssue(e)
@ -66,13 +83,66 @@ function issueList(props){
setDetailVisible(true)
})
}
function selectType(e) {
let index = selectedType.indexOf(e)
if (index > -1) {
selectedType.splice(index, 1)
setSelectedType([...selectedType])
} else {
setSelectedType([...selectedType, e])
}
}
function selectSeverity(e) {
let index = selectedSeverity.indexOf(e)
if (index > -1) {
selectedSeverity.splice(index, 1)
setSelectedSeverity([...selectedSeverity])
} else {
setSelectedSeverity([...selectedSeverity, e])
}
}
function selectTags(e) {
let index = selectedTag.indexOf(e)
if (index > -1) {
selectedTag.splice(index, 1)
setSelectedTag([...selectedTag])
} else {
setSelectedTag([...selectedTag, e])
}
}
return <div className="issue-total">
<ProblemDetail visible={detailVisible} issue={selectedIssue} issueDetail={issueInfo} onClose={() => setDetailVisible(false)}></ProblemDetail>
<div className="container total-info">
<p>代码分析结果</p>
<div>
<div className="info-list">
<div className="total-item">
<span>Bugs</span>
<span>{ baseData.bugs }</span>
</div>
<div className="total-item">
<span>漏洞</span>
<span>{ formatNumber(baseData.vulnerabilities) }</span>
</div>
<div className="total-item">
<span>异味</span>
<span>{ formatNumber(baseData.code_smells) }</span>
</div>
<div className="total-item">
<span>重复率</span>
<span>{ baseData.duplicated_lines_density }% <span className="item-more">代码<span>{ formatNumber(baseData.lines) }</span></span></span>
</div>
<div className="total-item">
<span>覆盖率</span>
<span>{ baseData.coverage }% <span className="item-more">代码<span>{ formatNumber(baseData.lines_to_cover) }</span></span></span>
</div>
<div className="total-item">
<span>代码行数</span>
<span>{ baseData.lines && baseData.lines.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") }</span>
</div>
</div>
</div>
{issues && <p>发现{ baseInfo.total }个问题</p>}
@ -80,11 +150,11 @@ function issueList(props){
<div className="container left-content">
<div className="type">
<div className="filter-title">
<span>问题类型</span>
<span>问题类型 {}</span>
</div>
{
listFilter.types && listFilter.types.map(e => (
<div className="filter-item" key={e.val}>
<div className={`filter-item${ selectedType.includes(e.val) ? ' selected-item' : '' }`} key={e.val} onClick={() => selectType(e.val)}>
<span>{ issueType[e.val] }</span>
<span>{ e.count }</span>
</div>))
@ -97,7 +167,7 @@ function issueList(props){
</div>
{
listFilter.impactSeverities && listFilter.impactSeverities.map(e => (
<div className="filter-item" key={e.val}>
<div className={`filter-item${ selectedSeverity.includes(e.val) ? ' selected-item' : '' }`} key={e.val} onClick={() => selectSeverity(e.val)}>
<span>{ maintainability[e.val] }</span>
<span>{ e.count }</span>
</div>))
@ -110,7 +180,7 @@ function issueList(props){
</div>
{
listFilter.tags && listFilter.tags.map(e => (
<div className="filter-item" key={e.val}>
<div className={`filter-item${ selectedTag.includes(e.val) ? ' selected-item' : '' }`} key={e.val} onClick={() => selectTags(e.val)}>
<span>{ e.val }</span>
<span>{ e.count }</span>
</div>))

12
src/forge/Utils/utils.js Normal file
View File

@ -0,0 +1,12 @@
export function formatNumber(num) {
if (num === undefined || num === null) return
if (num >= 1e9) {
return (num / 1e9).toFixed(1) + 'B'; // 十亿
} else if (num >= 1e6) {
return (num / 1e6).toFixed(1) + 'M'; // 百万
} else if (num >= 1e3) {
return (num / 1e3).toFixed(1) + 'K'; // 千
} else {
return num.toString(); // 小于 1000 的数字原样返回
}
}