diff --git a/package.json b/package.json index f0c3872de..92e78eb7a 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "dotenv": "4.0.0", "dotenv-expand": "4.2.0", "echarts": "^4.9.0", + "echarts-gl": "^1.1.2", "echarts-wordcloud": "^2.0.0", "editor.md": "^1.5.0", "express": "^4.18.2", diff --git a/src/forge/Component/projectCompass.jsx b/src/forge/Component/projectCompass.jsx new file mode 100644 index 000000000..f6837632e --- /dev/null +++ b/src/forge/Component/projectCompass.jsx @@ -0,0 +1,229 @@ +import React ,{ Fragment, useEffect, useState } from 'react'; +import echarts from 'echarts/lib/echarts' +import 'echarts-gl'; +import { getmaturityAnalyse } from '../api/project' +import { Icon, Popover } from 'antd'; + +function Compass({owner,projectsId}) { + const [mainScore, setMainScore] = useState({}) + + useEffect(()=>{ + getmaturityAnalyse({ owner, repository: projectsId }).then(res => { + if (res.data && res.data.main_score && res.data.main_score.score > 0) { + setMainScore(res.data.main_score) + Init(res.data) + } + }) + },[]) + + function Init(data) { + let huan_val = document.getElementById("compass"); + let myEcharts = echarts.init(huan_val); + + const a = 3; + const n = 3; + const o = false; + + const l = o ? "white" : "#333" + , r = o ? "rgba(255,255,255,0.8)" : "#aaa"; + + let option = { + tooltip: { + textStyle: { + fontWeight: "bolder" + }, + formatter: e => "mock" === e.data.validity ? e.name + ": \u5373\u5c06\u4e0a\u7ebf" : e.data.description + ": " + e.data.value[2] + }, + xAxis3D: { + name: " ", + type: "category", + data: data.main_score.x_axis, + interval: 2, + axisLine: { + lineStyle: { + width: 1, + color: l + } + }, + splitLine: { + show: !0, + interval: a - 1 + }, + axisLabel: { + interval: a - 1, + textStyle: { + color: r, + padding: [10, 10, 0, 0] + } + }, + axisTick: { + interval: a - 1, + length: 1 + } + }, + yAxis3D: { + name: " ", + type: "category", + data: data.main_score.y_axis, + axisLine: { + lineStyle: { + width: 1, + color: l + } + }, + axisTick: { + interval: n - 1, + length: 0 + }, + splitArea: { + show: !0, + areaStyle: { + color: ["rgba(255,247,207,0.5)", "rgba(255,231,231,0.5)", "rgba(226,226,226,0.5)"] + } + }, + axisLabel: { + interval: n - 1, + textStyle: { + color: r, + padding: [10, 0, 0, 0] + } + }, + splitLine: { + show: !0, + interval: n - 1 + } + }, + zAxis3D: { + name: " ", + type: "value", + splitNumber: 4, + axisLine: { + lineStyle: o ? { + width: 1, + opacity: .2, + color: l + } : { + width: .1, + opacity: .5, + color: l + } + }, + splitArea: { + show: !0, + areaStyle: { + color: ["#ffffff", "#ffffff", "#ffffff"] + } + }, + axisLabel: { + show: !1 + }, + axisTick: { + show: !1 + } + }, + grid3D: { + axisLine: { + interval: 1 + }, + axisPointer: { + lineStyle: { + opacity: .2 + }, + label: { + show: !1 + } + }, + splitLine: { + interval: 2 + }, + viewControl: { + projection: "perspective", + zoomSensitivity: 0, + rotateSensitivity: [1, 0], + distance: 280, + alpha: 20, + beta: 25 + }, + top: -40, + right: -10, + boxWidth: 150, + boxDepth: 150, + environment: "none", + light: { + main: { + intensity: .8, + alpha: 50 + }, + ambient: { + intensity: .5 + } + } + }, + series: [{ + type: "bar3D", + data: data.scores, + shading: "realistic", + bevelSize: .1, + bevelSmoothness: 2, + barSize: 13, + label: { + show: !1, + fontSize: 12, + fontWeight: 500, + borderWidth: 1, + color: "#333", + distance: -20, + formatter: function (e) { + for (let t = e.data.description, i = 2, a = Math.ceil(t.length / i), n = "\n", o = 0; o < a; o++) { + let l = o * i + , r = l + i; + n += t.substring(l, r) + "\n" + } + return n + } + }, + itemStyle: { + opacity: .95 + }, + emphasis: { + label: { + show: !1 + }, + itemStyle: { + color: "#FFB800", + opacity: .7 + } + } + }] + }; + myEcharts.setOption(option); + } + + const content = () => { + return
+ 开源健康成熟度评分,评估围绕以下维度对项目展开评估:
+ 稳健性:由安全警告,开发者数量,版本数评分反映。
+ 扩展性:由许可证评分、fork数评分、点赞数评分、关注数评分反映。
+ 维护性:由未解决 issue 和已解决 issue,commit数评分反映。
+
+ 总体成熟度评分
+ 80-100分: 项目成熟,维护良好。
+ 60-80分: 项目稳定,有待改进。
+ 0-60分: 项目成长期,需要加强维护。
+
+ + } + + return( + mainScore.score && mainScore.score > 0 ?
+
+ 开源健康成熟度评分 ({ mainScore.score && mainScore.score.toFixed(2) }) + + + +
+
+
: null + ) +} +export default Compass; \ No newline at end of file diff --git a/src/forge/Information/Pages/JCC/homePage.jsx b/src/forge/Information/Pages/JCC/homePage.jsx index 999876ee7..8faf02091 100644 --- a/src/forge/Information/Pages/JCC/homePage.jsx +++ b/src/forge/Information/Pages/JCC/homePage.jsx @@ -141,7 +141,7 @@ function HeaderPageJCC(props){ { data.introductionImage && - + } } diff --git a/src/forge/Information/Pages/headerPage.jsx b/src/forge/Information/Pages/headerPage.jsx index cc21f1535..654fa1dc7 100644 --- a/src/forge/Information/Pages/headerPage.jsx +++ b/src/forge/Information/Pages/headerPage.jsx @@ -79,8 +79,8 @@ function HeaderPage(props){

{ - data.introductionImage && - + data.introductionImage && + } } diff --git a/src/forge/Information/Pages/headerPagebyCCF.jsx b/src/forge/Information/Pages/headerPagebyCCF.jsx index d73326d70..6aec57866 100644 --- a/src/forge/Information/Pages/headerPagebyCCF.jsx +++ b/src/forge/Information/Pages/headerPagebyCCF.jsx @@ -237,7 +237,7 @@ function HeaderPageCCF(props) { { data.introductionImage && - + } } diff --git a/src/forge/Information/Pages/homepage/component/introduction.jsx b/src/forge/Information/Pages/homepage/component/introduction.jsx index 12a8a3ec8..d41150424 100644 --- a/src/forge/Information/Pages/homepage/component/introduction.jsx +++ b/src/forge/Information/Pages/homepage/component/introduction.jsx @@ -1,6 +1,7 @@ import React , { useEffect, useState } from 'react'; import { getZoneStatistics } from '../../../api'; import '../index.scss'; +import { Carousel } from 'antd'; // 专区简介,文字在左,图在右 // statistics: 是否展示统计区域 @@ -28,11 +29,15 @@ function Introduction({data, statistics=true}) { {firstTitle} ABOUT US -
- {introductionImage && } - {introductionContent && } +
+ {introductionImage && + {introductionImage.split(",").map((item, index) => { + return ; + })} + } + {introductionContent && }
- {statistics &&
+ {statistics &&
{Object.keys(label).map(item=>{ return
{data1[item]}
diff --git a/src/forge/Information/Pages/homepage/component/news.jsx b/src/forge/Information/Pages/homepage/component/news.jsx index 2fa28ee6b..83da8459e 100644 --- a/src/forge/Information/Pages/homepage/component/news.jsx +++ b/src/forge/Information/Pages/homepage/component/news.jsx @@ -131,8 +131,8 @@ function News({data, subTitle, firstDirIntro, secondDirIntro}) { {/* 第一个顺序栏目 */} {firstDir &&

- {firstDir.name} - 更多 + {window.scrollTo(0,450)}}>{firstDir.name} + {window.scrollTo(0,450)}}>更多

{firstDirIntro}
{docListByFirstDir[0] &&
@@ -147,7 +147,9 @@ function News({data, subTitle, firstDirIntro, secondDirIntro}) {
-

{secondDir.name}

+

+ {window.scrollTo(0,450)}}>{secondDir.name} +

{secondDirIntro}

@@ -164,9 +166,9 @@ function News({data, subTitle, firstDirIntro, secondDirIntro}) {
}
-
+ {dirs && !!dirs.length &&
{renderItems()} -
+
}
} diff --git a/src/forge/Information/Pages/homepage/component/partner.jsx b/src/forge/Information/Pages/homepage/component/partner.jsx index cb567561d..9ffd31cc1 100644 --- a/src/forge/Information/Pages/homepage/component/partner.jsx +++ b/src/forge/Information/Pages/homepage/component/partner.jsx @@ -1,6 +1,7 @@ import React , { useEffect, useState } from 'react'; import { getPartnerList } from '../../../api'; import '../index.scss'; +import Nodata from '../../../../Nodata'; function Partner({data}) { const {id, key, homepagePartnersTitle} = data || {}; @@ -46,6 +47,7 @@ function Partner({data}) {

{homepagePartnersTitle}

{gridItems}
+ {list && !list.length && }
} diff --git a/src/forge/Information/Pages/homepage/component/project.jsx b/src/forge/Information/Pages/homepage/component/project.jsx index 5ce2c275e..e3b6cf8c1 100644 --- a/src/forge/Information/Pages/homepage/component/project.jsx +++ b/src/forge/Information/Pages/homepage/component/project.jsx @@ -3,6 +3,43 @@ import '../index.scss'; import { getProjectListByScore, getProjectsTypeLists } from '../../../api'; import { Carousel, Divider, Spin } from 'antd'; import Nodata from '../../../../Nodata'; +import Slider from 'react-slick'; + +export function TypeCarousel({pageSize=4, list=[], typeId, onClick}) { + const setting = { + prevArrow: , + nextArrow: , + afterChange: (currentSlide)=>{onClick(list[currentSlide*pageSize].id)} + } + const pages = [] + for (let i = 0; i < Math.ceil(list.length / pageSize); i++) { + const start = i * pageSize; + const end = start + pageSize; + pages.push(list.slice(start, end)); + } + return + {pages.map((page, index)=>{ + return
+
+ {page.map((item, i) => { + const order = index*pageSize+i + return
{ onClick(item.id) }}> + {/* 项目 */} + + {/* 专项项目 */} + + {order < 9 ? `0${order+1}` : order+1} + + + + {item.name} +
+ })} +
+
+ })} +
+} function Project({ data, subTitle }) { const { id, homepageProjectTitle } = data || {}; @@ -15,7 +52,10 @@ function Project({ data, subTitle }) { const pages = []; useEffect(() => { - id && getProjectsTypeLists(id).then(result => { + id && getProjectsTypeLists(id, { + pageNum: 1, + pageSize: 100, + }).then(result => { if (result) { const rows = result.data.rows; rows[0] && setTypeId(rows[0].id) @@ -52,19 +92,12 @@ function Project({ data, subTitle }) {

{homepageProjectTitle}

{subTitle}

-
- {typeList.slice(0, 3).map((item, index) => { - return
{ setTypeId(item.id); setPage(1) }}> - - {item.name} -
- })} -
+ {setTypeId(id); setPage(1)}}/> {setLoading(true);setPage(current+1)}}> {pages.map((page1, index) => (
-
+
{lists.map((i, index) => { const { extra: { commitCount, contributorsCount, lastWeekScore, scoreChange } } = i || {} const order = page >= 2 ? (page-1)*6+index+1 : index+1; diff --git a/src/forge/Information/Pages/homepage/component/specialProjects.jsx b/src/forge/Information/Pages/homepage/component/specialProjects.jsx index 3947f4132..d4cb4aff7 100644 --- a/src/forge/Information/Pages/homepage/component/specialProjects.jsx +++ b/src/forge/Information/Pages/homepage/component/specialProjects.jsx @@ -3,6 +3,7 @@ import { getSpecialProjectDetail, getSpecialProjectList, getSpecialProjectTypeLi import { Col, Divider, Row, Tag } from 'antd'; import Nodata from '../../../../Nodata'; import '../index.scss'; +import { TypeCarousel } from './project'; function SpecialProjects({data, subTitle}) { const {key, homepageSpecialProjectTitle, id} = data || {}; @@ -15,7 +16,7 @@ function SpecialProjects({data, subTitle}) { useEffect(()=>{ id && getSpecialProjectTypeList(id, { pageNum: 1, - pageSize: 4, + pageSize: 100, }).then(res=>{ if(res){ const rows = res.data.rows; @@ -120,13 +121,13 @@ function SpecialProjects({data, subTitle}) { currentRow.push(
handleItemClick(item.id)} > {index+1}
{item.name}
-
摘要:{item.description}
-

{item.projectLeader}

+
摘要:{item.description}
+

{item.projectLeader}

); @@ -146,7 +147,7 @@ function SpecialProjects({data, subTitle}) {
项目{name}

项目负责人:{projectLeader}

-

奖项:{awards}

+ { awards &&

奖项:{awards}

}

摘要:{description}

@@ -171,18 +172,7 @@ function SpecialProjects({data, subTitle}) {

{homepageSpecialProjectTitle}

{subTitle}

-
- {typeList.map((item, index)=>{ - return
{setTypeId(item.id)}}> - - {index < 9 ? `0${index+1}` : index+1} - - - - {item.name} -
- })} -
+ {setTypeId(id);}}/>
{renderItems()}
{!projectList.length && }
diff --git a/src/forge/Information/Pages/homepage/image/left.png b/src/forge/Information/Pages/homepage/image/left.png new file mode 100644 index 000000000..b41f9df80 Binary files /dev/null and b/src/forge/Information/Pages/homepage/image/left.png differ diff --git a/src/forge/Information/Pages/homepage/image/proType4.png b/src/forge/Information/Pages/homepage/image/proType4.png new file mode 100644 index 000000000..c2002889f Binary files /dev/null and b/src/forge/Information/Pages/homepage/image/proType4.png differ diff --git a/src/forge/Information/Pages/homepage/image/proType4_active.png b/src/forge/Information/Pages/homepage/image/proType4_active.png new file mode 100644 index 000000000..d805f4572 Binary files /dev/null and b/src/forge/Information/Pages/homepage/image/proType4_active.png differ diff --git a/src/forge/Information/Pages/homepage/image/proType5.png b/src/forge/Information/Pages/homepage/image/proType5.png new file mode 100644 index 000000000..2eabb70ca Binary files /dev/null and b/src/forge/Information/Pages/homepage/image/proType5.png differ diff --git a/src/forge/Information/Pages/homepage/image/proType5_active.png b/src/forge/Information/Pages/homepage/image/proType5_active.png new file mode 100644 index 000000000..2e291efe0 Binary files /dev/null and b/src/forge/Information/Pages/homepage/image/proType5_active.png differ diff --git a/src/forge/Information/Pages/homepage/image/right.png b/src/forge/Information/Pages/homepage/image/right.png new file mode 100644 index 000000000..14e5bbac1 Binary files /dev/null and b/src/forge/Information/Pages/homepage/image/right.png differ diff --git a/src/forge/Information/Pages/homepage/index.scss b/src/forge/Information/Pages/homepage/index.scss index db0855268..860cb2729 100644 --- a/src/forge/Information/Pages/homepage/index.scss +++ b/src/forge/Information/Pages/homepage/index.scss @@ -65,6 +65,20 @@ color: #D9D9D9; } } + .intro_1_carousel{ + width: 526px; + float: right; + margin-left: 35px; + .slick-dots li button:before{ + font-size: 10px; + top: -12px; + } + } + .intro_image{ + width: 526px; + height: 272px; + object-fit: scale-down; + } } .news_1_bg{ background-image: url('./image/new1.png'); @@ -147,8 +161,9 @@ } } .pd_desc{ - min-height: 55px; + // min-height: 55px; color: #6B707C; + margin-bottom: 10px; } .pd_tag{ display: flex; @@ -186,7 +201,7 @@ } } .project_1_bg .proTypeBox, .specialProjects_1_bg .proTypeBox{ - width: 280px; + min-width: 275px; height: 63px; background: #F5F6F7; border-radius: 8px; @@ -207,6 +222,12 @@ .icon2{ background-image: url('./image/proType3_active.png'); } + .icon3{ + background-image: url('./image/proType4_active.png'); + } + .icon4{ + background-image: url('./image/proType5_active.png'); + } .s_p_order_1, .s_p_order>img{ display: none; } @@ -225,7 +246,7 @@ background-image: url('./image/s_project7.png'); } } - .icon1, .s_p_order_icon, .icon0, .icon2{ + .s_p_order_icon, .p_1_icon{ width: 22px; height: 22px; background-size: 100% 100%; @@ -239,12 +260,30 @@ background-image: url('./image/proType2.png'); } .icon2{ - width: 25px; - height: 19px; + height: 18px; background-image: url('./image/proType3.png'); } + .icon3{ + width: 24px; + height: 24px; + background-image: url('./image/proType4.png'); + } + .icon4{ + background-image: url('./image/proType5.png'); + } } +.project_1_bg .proTypeBox{ + min-width:200px; + .s_p_order{ + display: none; + } +} +.specialProjects_1_bg .proTypeBox{ + .p_1_icon{ + display: none; + } +} .source_1_bg{ background-color: white; background-image: url('./image/source1.png'); @@ -350,6 +389,7 @@ margin: 0 0 35px 0 !important; } .s_p_detail{ + flex-direction: column; flex: 0 0 calc(33.333% - 20px); background: #FFFFFF; box-shadow: 0px 0px 10px 1px rgba(28,48,175,0.08); diff --git a/src/forge/Main/CoderDepot.jsx b/src/forge/Main/CoderDepot.jsx index 163766edf..1ab7573c7 100644 --- a/src/forge/Main/CoderDepot.jsx +++ b/src/forge/Main/CoderDepot.jsx @@ -26,6 +26,7 @@ import RenderHtml from '../../components/render-html'; import Loadable from 'react-loadable'; import Loading from '../../Loading'; import ProjectPortrait from '../Component/projectPortrait'; +// import ProjectCompass from '../Component/projectCompass'; import imNoneImg from './img/importNone.png'; import moment from 'moment'; @@ -694,6 +695,7 @@ function CoderDepot(props){ /> } + {/* {__CLIENT__ && } */} {/* 贡献者 */} {mirror_status ===0 && } {/* 项目画像: 导入/fork项目不展示, open_portrait后台配置是否开启仓库 */} diff --git a/src/forge/Server/measurement/componet/companyData.jsx b/src/forge/Server/measurement/componet/companyData.jsx index 64a7458dc..5f5c34e24 100644 --- a/src/forge/Server/measurement/componet/companyData.jsx +++ b/src/forge/Server/measurement/componet/companyData.jsx @@ -38,11 +38,21 @@ function CompanyData({ data }){ useEffect(()=>{ if(c1userValue && c1 && c1.length > 0){ - let fil = c1.filter(i=>i.Module === c1userValue); + let fil = c1.filter(i=> i.Module === c1userValue); + const companyArray = Array.from(new Set(fil.map(i => i.Company))); let monthList = fil.map(obj => obj.Month); let valueList = fil.map(obj => obj['Weight Ratio']); setC1Keys(monthList); - setC1Values(valueList); + if(companyArray && companyArray.length>0 && fil.length>0){ + const arr = companyArray.map(item=>{ + let v = fil.filter(i=> i.Company == item); + let valueList = v.map(obj => obj['Weight Ratio']); + return {name :item , type: 'line',stack: 'Total',data:valueList} + }) + setC1Values(arr); + }else{ + setC1Values(valueList); + } } },[c1,c1userValue]) @@ -127,7 +137,7 @@ function CompanyData({ data }){
} - +
{ @@ -145,7 +155,7 @@ function CompanyData({ data }){
} - +
diff --git a/src/forge/Server/measurement/componet/stackImg.jsx b/src/forge/Server/measurement/componet/stackImg.jsx index 67433d209..0a3b12d3f 100644 --- a/src/forge/Server/measurement/componet/stackImg.jsx +++ b/src/forge/Server/measurement/componet/stackImg.jsx @@ -47,14 +47,7 @@ function StackImg({x,values,title,id}){ yAxis: { type: 'value' }, - series: [ - { - name: name, - type: 'line', - stack: 'Total', - data: values - } - ] + series: values }; myEcharts.setOption(option); } diff --git a/src/forge/api/project.js b/src/forge/api/project.js new file mode 100644 index 000000000..bdc48e180 --- /dev/null +++ b/src/forge/api/project.js @@ -0,0 +1,10 @@ +import javaFetch from '../javaFetch'; + +const service = javaFetch(); +export function getmaturityAnalyse(params) { + return service({ + url: `https://testbd.trustie.net/maturityAnalyse/`, + method: 'get', + params: window.location.hostname === 'testforgeplus.trustie.net' ? { ...params, env_url: 'testforgeplus' } : params + }); +} \ No newline at end of file diff --git a/src/forge/iframe.jsx b/src/forge/iframe.jsx index 469aa808c..194339f18 100644 --- a/src/forge/iframe.jsx +++ b/src/forge/iframe.jsx @@ -17,13 +17,27 @@ const Iframe = (props) => { if (!current_user?.login) { history.push("/login?go_page=/hiagent"); } + document.title = "GitLink-AI" }, []) + function iframeLoad() { + let myIframe = document.getElementById("iframe"); + const toastRight = myIframe?.contentWindow?.document?.getElementsByClassName("arco-notification-wrapper-topRight")[0] + const toastTop = myIframe?.contentWindow?.document?.getElementsByClassName("arco-notification-wrapper-top")[0] + if (toastRight) { + toastRight.style.top = '60px' + } + if (toastTop) { + toastTop.style.top = '80px' + } + } + return current_user?.login ? : '' }