fix: 修复项目画像bug

This commit is contained in:
lilan 2025-06-05 15:55:20 +08:00
parent cdac4f317e
commit a280288e89
35 changed files with 134 additions and 41 deletions

View File

@ -202,7 +202,7 @@
"eslintConfig": { "eslintConfig": {
"extends": "react-app" "extends": "react-app"
}, },
"proxy": "http://172.20.32.202:4000", "proxy": "http://172.20.32.203:4000",
"port": "3007", "port": "3007",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.23.6", "@babel/core": "^7.23.6",

View File

@ -102,9 +102,9 @@ function Radar({owner,projectsId, history}) {
<div className='halfs'> <div className='halfs'>
<div className="font-16 color-ooo hoverA mb20"> <div className="font-16 color-ooo hoverA mb20">
项目画像 项目画像
<Popover content={content}> {/* <Popover content={content}>
<Icon type="question-circle" theme="filled" className="color-blue ml10 pointer"/> <Icon type="question-circle" theme="filled" className="color-blue ml10 pointer"/>
</Popover> </Popover> */}
</div> </div>
<div id="projectPortrait" style={{height:"230px"}}></div> <div id="projectPortrait" style={{height:"230px"}}></div>
</div> </div>

View File

@ -20,6 +20,12 @@
color:#333333; color:#333333;
font-size:16px; font-size:16px;
span {
display: inline-block; /* 或者使用 flex, grid 等布局 */
background-image: linear-gradient(99.89deg,#456aff 11.08%,#b45dff 93.64%);
background-clip: text;
color: transparent; /* 确保文字颜色透明,这样背景图片就会显示 */
}
img { img {
height: 59px; height: 59px;
position: relative; position: relative;
@ -59,12 +65,13 @@
border:1px solid; border:1px solid;
border-color:#ffffff; border-color:#ffffff;
border-radius:3px 3px 0px 0px; border-radius:3px 3px 0px 0px;
background:rgba(114, 163, 254, 0.9);
} }
.scoreValue{ .scoreValue{
position: relative; position: relative;
display: block; display: block;
width: 400px; width: 320px;
height: 200px; height: 160px;
text-align: center; text-align: center;
margin: 0px auto; margin: 0px auto;
.s_content{ .s_content{
@ -129,7 +136,7 @@
color: #181818; color: #181818;
} }
.progress{ .progress{
width: 280px; width: 260px;
height: 16px; height: 16px;
background: rgba(255, 255, 255, 0.33); background: rgba(255, 255, 255, 0.33);
position: relative; position: relative;
@ -153,16 +160,16 @@
} }
.subDetail { .subDetail {
margin-top: 90px; margin-top: 90px;
padding-bottom: 150px; padding-bottom: 90px;
} }
.subScore { .subScore {
background-image: url(./img/total_bj.png); background-image: url(./img/total_text_bj.png);
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
width:1200px; width:1200px;
.typeValue{ .typeValue{
line-height:40px; line-height:40px;
font-size: 22px; font-size: 17px;
color: #181818; color: #181818;
text-align: center; text-align: center;
padding: 45px 0 30px; padding: 45px 0 30px;
@ -177,7 +184,7 @@
.subContent { .subContent {
background-image: url(./img/sub_content_bj.png); background-image: url(./img/sub_content_bj.png);
background-size: 100% 100%; background-size: 100% auto;
background-repeat: no-repeat; background-repeat: no-repeat;
padding-top: 40px; padding-top: 40px;
@ -245,6 +252,48 @@
.community_impact_fork { .community_impact_fork {
background-image: url('./img/community_impact_fork.png'); background-image: url('./img/community_impact_fork.png');
} }
.project_maturity_complete_issue {
background-image: url('./img/project_maturity_complete_issue.png');
}
.project_maturity_pullrequest {
background-image: url('./img/project_maturity_pullrequest.png');
}
.project_maturity_project_create_day {
background-image: url('./img/project_maturity_project_create_day.png');
}
.health_issue {
background-image: url('./img/health_issue.png');
}
.health_pullrequest {
background-image: url('./img/health_pullrequest.png');
}
.health_code {
background-image: url('./img/health_code.png');
}
.health_license {
background-image: url('./img/health_license.png');
}
.team_impact_member {
background-image: url('./img/team_impact_member.png');
}
.team_impact_recent_member {
background-image: url('./img/team_impact_recent_member.png');
}
.team_impact_issue_assigner {
background-image: url('./img/team_impact_issue_assigner.png');
}
.develop_activity_commit {
background-image: url('./img/develop_activity_commit.png');
}
.develop_activity_issue {
background-image: url('./img/develop_activity_issue.png');
}
.develop_activity_pullrequest {
background-image: url('./img/develop_activity_pullrequest.png');
}
.develop_activity_release {
background-image: url('./img/develop_activity_release.png');
}
&.active{ &.active{
background-image: url('./img/btn_active_bj.png'); background-image: url('./img/btn_active_bj.png');
@ -260,6 +309,48 @@
.community_impact_fork { .community_impact_fork {
background-image: url('./img/community_impact_fork_active.png'); background-image: url('./img/community_impact_fork_active.png');
} }
.project_maturity_complete_issue {
background-image: url('./img/project_maturity_complete_issue_active.png');
}
.project_maturity_pullrequest {
background-image: url('./img/project_maturity_pullrequest_active.png');
}
.project_maturity_project_create_day {
background-image: url('./img/project_maturity_project_create_day_active.png');
}
.health_issue {
background-image: url('./img/health_issue_active.png');
}
.health_pullrequest {
background-image: url('./img/health_pullrequest_active.png');
}
.health_code {
background-image: url('./img/health_code_active.png');
}
.health_license {
background-image: url('./img/health_license_active.png');
}
.team_impact_member {
background-image: url('./img/team_impact_member_active.png');
}
.team_impact_recent_member {
background-image: url('./img/team_impact_recent_member_active.png');
}
.team_impact_issue_assigner {
background-image: url('./img/team_impact_issue_assigner_active.png');
}
.develop_activity_commit {
background-image: url('./img/develop_activity_commit_active.png');
}
.develop_activity_issue {
background-image: url('./img/develop_activity_issue_active.png');
}
.develop_activity_pullrequest {
background-image: url('./img/develop_activity_pullrequest_active.png');
}
.develop_activity_release {
background-image: url('./img/develop_activity_release_active.png');
}
} }
&:hover{ &:hover{
background-image: url('./img/btn_active_bj.png'); background-image: url('./img/btn_active_bj.png');

View File

@ -11,8 +11,8 @@ export const typeName = {
// 项目画像分类描述文字 // 项目画像分类描述文字
export const typeDetail = { export const typeDetail = {
community_impact: '社区影响力分析旨在量化评估开源项目在开源社区中的受欢迎程度和传播能力,为项目管理者、开发者和社区组织者提供决策依据。通过项目关注度、项目收藏度、项目派生度三个关键指标,综合评估项目的社区影响力,帮助项目团队了解项目在社区中的地位和发展趋势,从而采取相应的策略提升项目的社区影响力。', community_impact: '社区影响力分析旨在量化开源项目在开源社区中的受欢迎程度和传播能力,为项目管理者、开发者和社区成员提供参考依据。通过项目关注度、项目收藏度、项目派生度三个关键指标进行综合评估,帮助项目团队了解项目在社区中的地位和发展趋势。',
project_maturity: '项目成熟度旨在通过量化项目的开发活动和任务管理数据,为项目管理者、开发者和社区组织者提供一个客观、全面的评估框架,综合反映项目的稳定性和可靠性。通过对项目解决任务量、累计开发活动量、项目有效开发年龄等指标的评估,不仅有助于项目团队内部的管理和优化,还能为社区资源的合理分配提供重要依据,确保有限的资源能够优先投入到那些具有潜力和成熟度的项目中。', project_maturity: '项目成熟度旨在通过量化项目的开发活动和任务管理数据,为项目管理者、开发者和社区组织者提供一个客观、全面的评估框架。通过对项目解决任务量、累计开发活动量、项目有效开发年龄等指标的评估,不仅有助于项目团队内部的管理和优化,还能为社区资源的合理分配提供重要依据。',
project_health: '项目健康度统计通过评估项目源代码质量和开发过程效率,如任务过程效率分析、代码过程效率分析、代码质量分析、项目许可证分析等指标,展示项目的健康状况,帮助用户及时发现潜在问题,采取相应的改进措施,确保项目的顺利进行。', project_health: '项目健康度统计通过评估项目源代码质量和开发过程效率,如任务过程效率分析、代码过程效率分析、代码质量分析、项目许可证分析等指标,展示项目的健康状况,帮助用户及时发现潜在问题,采取相应的改进措施,确保项目的顺利进行。',
team_impact: '团队健康度统计分析功能通过对团队稳定性、新人增长率、任务均衡度等指标的评估,展示项目团队的健康状况和协作能力,为团队管理和优化提供参考,帮助提升团队的整体效能和可持续发展能力。', team_impact: '团队健康度统计分析功能通过对团队稳定性、新人增长率、任务均衡度等指标的评估,展示项目团队的健康状况和协作能力,为团队管理和优化提供参考,帮助提升团队的整体效能和可持续发展能力。',
develop_activity: '开发活跃度统计分析功能通过评估代码提交度、缺陷反馈度、代码合并请求率、版本发布率等指标,展示项目的开发活跃度和团队的活跃程度,帮助用户了解项目的开发动态,及时发现开发过程中的问题,采取相应的措施进行调整。', develop_activity: '开发活跃度统计分析功能通过评估代码提交度、缺陷反馈度、代码合并请求率、版本发布率等指标,展示项目的开发活跃度和团队的活跃程度,帮助用户了解项目的开发动态,及时发现开发过程中的问题,采取相应的措施进行调整。',
@ -73,25 +73,25 @@ export const subTypeDetail = {
health_issue: { health_issue: {
name: '任务过程效率分析', name: '任务过程效率分析',
// 权重百分比 // 权重百分比
WeightedScore: 10, WeightedScore: 40,
remark: '任务过程效率分析衡量项目在 Issue 处理上的效能,通过已解决 Issue 数量与 Issue 总数的相对比例来评估团队响应问题和修复缺陷的效率。较高的解决率表明项目具备良好的问题跟踪和响应机制,能够有效管理用户反馈和开发任务;而持续优化的解决流程则有助于提升社区参与度和项目可靠性。通过监控 Issue 的解决周期和分布,可以识别协作瓶颈,优化任务分配和优先级策略。' remark: '任务过程效率分析衡量项目在 Issue 处理上的效能,通过已解决 Issue 数量与 Issue 总数的相对比例来评估团队响应问题和修复缺陷的效率。较高的解决率表明项目具备良好的问题跟踪和响应机制,能够有效管理用户反馈和开发任务;而持续优化的解决流程则有助于提升社区参与度和项目可靠性。通过监控 Issue 的解决周期和分布,可以识别协作瓶颈,优化任务分配和优先级策略。'
}, },
health_pullrequest: { health_pullrequest: {
name: '代码过程效率分析', name: '代码过程效率分析',
// 权重百分比 // 权重百分比
WeightedScore: 10, WeightedScore: 40,
remark: '代码过程效率析是指项目中已合并的代码提交请求数量与总代码提交请求数量的比例加权评估项目处理代码贡献的效率水平。该指标既反映了团队审查和合并PR的及时性也体现了项目对代码质量的把控能力。较高的合并率表明项目建立了流畅的协作机制能够有效整合社区开发力量同时合理的PR筛选机制也保障了代码质量。通过持续跟踪这一指标项目可以优化代码审查流程在开发效率和质量控制之间取得更好平衡。' remark: '代码过程效率析是指项目中已合并的代码提交请求数量与总代码提交请求数量的比例加权评估项目处理代码贡献的效率水平。该指标既反映了团队审查和合并PR的及时性也体现了项目对代码质量的把控能力。较高的合并率表明项目建立了流畅的协作机制能够有效整合社区开发力量同时合理的PR筛选机制也保障了代码质量。通过持续跟踪这一指标项目可以优化代码审查流程在开发效率和质量控制之间取得更好平衡。'
}, },
health_code: { health_code: {
name: '代码质量分析', name: '代码质量分析',
// 权重百分比 // 权重百分比
WeightedScore: 40, WeightedScore: 10,
remark: '代码质量分析是评估项目代码健壮性和可维护性的核心指标,通过静态代码分析直接反映项目的代码质量水平和长期可维护性,高质量的代码表现为较低的缺陷密度、以及一致的编码风格。持续监控代码质量有助于及时发现潜在问题,优化架构设计,并确保项目在快速迭代过程中保持技术可靠性。' remark: '代码质量分析是评估项目代码健壮性和可维护性的核心指标,通过静态代码分析直接反映项目的代码质量水平和长期可维护性,高质量的代码表现为较低的缺陷密度、以及一致的编码风格。持续监控代码质量有助于及时发现潜在问题,优化架构设计,并确保项目在快速迭代过程中保持技术可靠性。'
}, },
health_license: { health_license: {
name: '项目许可证分析', name: '项目许可证分析',
// 权重百分比 // 权重百分比
WeightedScore: 40, WeightedScore: 10,
remark: '开源许可证分析是评估项目合规性与协作开放性的关键指标,通过检测项目是否包含标准化开源许可证来判定其法律完备性。该指标反映了项目团队对知识产权管理的专业程度,以及项目参与商业生态的合规能力。通过该分析可识别项目在合规治理方面的成熟度,为后续生态化发展奠定法律基础。' remark: '开源许可证分析是评估项目合规性与协作开放性的关键指标,通过检测项目是否包含标准化开源许可证来判定其法律完备性。该指标反映了项目团队对知识产权管理的专业程度,以及项目参与商业生态的合规能力。通过该分析可识别项目在合规治理方面的成熟度,为后续生态化发展奠定法律基础。'
} }
}, },
@ -143,4 +143,4 @@ export const subTypeDetail = {
} }
} }
export const colors = ['#466aff', '#c566fe', '#fdcd00'] export const colors = ['#466aff', '#c566fe', '#fdcd00', '#00B9FD']

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -77,6 +77,8 @@ function PortraitDetail(props) {
function InitGauge(num) { function InitGauge(num) {
var huan_val = document.getElementById("scoreValue"); var huan_val = document.getElementById("scoreValue");
var myEcharts = echarts.init(huan_val); var myEcharts = echarts.init(huan_val);
//
const persent = (num / 100).toFixed(2)
let option = { let option = {
series: [ series: [
{ {
@ -84,35 +86,40 @@ function PortraitDetail(props) {
startAngle: 180, startAngle: 180,
endAngle: 0, endAngle: 0,
center: ['50%', '90%'], center: ['50%', '90%'],
radius: '160px', radius: '120px',
min: 0, min: 0,
max: 100, max: 100,
// //
splitNumber: 5, splitNumber: 5,
itemStyle: {
color: '#39c5dc'
},
axisLine: { axisLine: {
show: false, show: true,
roundCap: true,
lineStyle: { lineStyle: {
width: 10, width: 10,
color: [ color: [
[0.25, '#da6fe6'], // [0.25, '#da6fe6'],
[0.5, '#d8c064'], // [0.5, '#d8c064'],
[0.75, '#85d586'], // [0.75, '#85d586'],
[1, '#3ec7d7'] [persent, '#39c5dc'],
[1, 'rgba(255,255,255,0.3)']
] ]
} }
}, },
//
pointer: { pointer: {
show: true, show: true,
// icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
length: '50%', length: '50%',
width: 5, width: 5,
itemStyle: { itemStyle: {
color: 'auto' color: '#39c5dc'
} }
}, },
// 线 // 线
axisTick: { axisTick: {
length: 10, length: 12,
lineStyle: { lineStyle: {
color: 'auto', color: 'auto',
width: 2 width: 2
@ -120,7 +127,7 @@ function PortraitDetail(props) {
}, },
// 线 // 线
splitLine: { splitLine: {
length: 15, length: 12,
lineStyle: { lineStyle: {
color: 'auto', color: 'auto',
width: 3 width: 3
@ -148,14 +155,9 @@ function PortraitDetail(props) {
valueAnimation: true, valueAnimation: true,
color: '#FFF' color: '#FFF'
}, },
progress: {
show: true,
roundCap: true,
},
data: [ data: [
{ {
value: num, value: num
name: typeName[type]
} }
] ]
} }
@ -189,7 +191,7 @@ function PortraitDetail(props) {
</div> </div>
</span> */} </span> */}
<div className="scoreValue" id="scoreValue"></div> <div className="scoreValue" id="scoreValue"></div>
<p className="scoreTitle mt15 mb15">本项目{typeName[type]}</p> <p className="scoreTitle mt15 mb15">{typeName[type]}</p>
<p className="scoreText">{typeDetail[type]}</p> <p className="scoreText">{typeDetail[type]}</p>
</div> </div>
{ {

View File

@ -15,13 +15,13 @@ const axiosInstance = axios.create({
}); });
axiosInstance.interceptors.request.use( axiosInstance.interceptors.request.use(
config => { config => {
if (window.location.port === "3007") { // if (window.location.port === "3007") {
if (config.url.indexOf('?') === -1) { // if (config.url.indexOf('?') === -1) {
config.url = `${config.url}?debug=admin`; // config.url = `${config.url}?debug=admin`;
} else { // } else {
config.url = `${config.url}&debug=admin`; // config.url = `${config.url}&debug=admin`;
} // }
} // }
return config; return config;
}, },
err => { err => {