开源度量-子维度接口
This commit is contained in:
parent
939dd0b59c
commit
b1ee7c1bd0
|
@ -80,20 +80,7 @@ module.exports = function(proxy, allowedHost) {
|
|||
disableDotRule: true,
|
||||
},
|
||||
public: allowedHost,
|
||||
proxy:{
|
||||
"/api/OSS_Health_Measuring":{
|
||||
target: 'http://60.205.224.11:8060',
|
||||
changeOrigin: true,
|
||||
},
|
||||
"/api/OHM_can_get":{
|
||||
target: 'http://60.205.224.11:8060',
|
||||
changeOrigin: true,
|
||||
},
|
||||
"/api":{
|
||||
target: "https://testforgeplus.trustie.net",
|
||||
changeOrigin: true,
|
||||
}
|
||||
},
|
||||
proxy,
|
||||
before(app) {
|
||||
// This lets us open files from the runtime error overlay.
|
||||
app.use(errorOverlayMiddleware());
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 20 KiB |
|
@ -46,11 +46,11 @@ function ServerIndex(props){
|
|||
return(
|
||||
<div className="panels">
|
||||
<Switch {...props}>
|
||||
{/* <Route path="/:owner/:projectsId/service/measurement/:type"
|
||||
<Route path="/:owner/:projectsId/service/measurement/:type"
|
||||
render={
|
||||
(p) => (<MeasurementDetail {...props} {...p}/>)
|
||||
}
|
||||
></Route> */}
|
||||
></Route>
|
||||
<Route path="/:owner/:projectsId/service/reposyncer"
|
||||
render={
|
||||
() => (<Reposyncer {...props}/>)
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
import fetch from './fetch';
|
||||
|
||||
|
||||
export function getMainScore(owner,repo) {
|
||||
return fetch({
|
||||
url: `/api/OSS_Health_Measuring/${owner}/${repo}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function getChange(owner,repo) {
|
||||
return fetch({
|
||||
url: `/api/OHM_can_get/${owner}/${repo}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
import React, { useEffect , useState } from 'react';
|
||||
import { Table } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import "../index.scss";
|
||||
import { fieldData , thirdData , subField } from '../config';
|
||||
|
||||
function Radar({data , subCardIndex}){
|
||||
function Indicator({owner , projectsId , data , subCardIndex}){
|
||||
const [ dataSource , setDataSource ] = useState([]);
|
||||
|
||||
|
||||
|
@ -20,8 +21,8 @@ function Radar({data , subCardIndex}){
|
|||
title: "指标名称",
|
||||
dataIndex: "name",
|
||||
render:(value)=>{
|
||||
// return(<a className='color-blue'>{fieldData[value]}</a>)
|
||||
return fieldData[value]
|
||||
return(<Link to={`/${owner}/${projectsId}/service/measurement/${value}`} className='color-blue'>{fieldData[value]}</Link>)
|
||||
// return fieldData[value]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -42,4 +43,4 @@ function Radar({data , subCardIndex}){
|
|||
<Table columns={column} dataSource={dataSource} pagination={false} size='small' className='smalltable'/>
|
||||
)
|
||||
}
|
||||
export default Radar;
|
||||
export default Indicator;
|
|
@ -15,7 +15,6 @@ function Radar({data, subCardIndex}){
|
|||
v = v.concat(i.InitialScore)
|
||||
return {name:fieldData[i.name],max:100}
|
||||
})
|
||||
console.log(d,v);
|
||||
setValues(v);
|
||||
setTitles(d);
|
||||
}
|
||||
|
@ -31,22 +30,44 @@ function Radar({data, subCardIndex}){
|
|||
var huan_val = document.getElementById("radar");
|
||||
var myEcharts = echarts.init(huan_val);
|
||||
let option = {
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
title: {
|
||||
text: ''
|
||||
},
|
||||
color:['#5871FF',"#FFBE38"],
|
||||
radar: {
|
||||
// shape: 'circle',
|
||||
indicator: titles
|
||||
indicator: titles,
|
||||
radius:'50%',
|
||||
// splitLine:{
|
||||
// lineStyle:{
|
||||
// color:'#11B0D3',
|
||||
// opacity: 0.2
|
||||
// },
|
||||
// },
|
||||
// axisLine:{
|
||||
// lineStyle:{
|
||||
// color:'#11B0D3',
|
||||
// opacity: 0.2
|
||||
// },
|
||||
// },
|
||||
// splitArea:{
|
||||
// areaStyle:{
|
||||
// color: 'none',
|
||||
// }
|
||||
// },
|
||||
nameGap: 3,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Budget vs spending',
|
||||
name: '',
|
||||
type: 'radar',
|
||||
data: [
|
||||
{
|
||||
value: values,
|
||||
name: 'Allocated Budget'
|
||||
name: ''
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -55,7 +76,7 @@ function Radar({data, subCardIndex}){
|
|||
myEcharts.setOption(option);
|
||||
}
|
||||
return(
|
||||
<div id="radar" style={{height:"200px",width:"40%"}}></div>
|
||||
<div id="radar" style={{height:"300px",width:"45%"}}></div>
|
||||
)
|
||||
}
|
||||
export default Radar;
|
|
@ -1,8 +1,10 @@
|
|||
import React ,{useEffect, useState} from 'react';
|
||||
import { Breadcrumb , Select } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import "./index.scss";
|
||||
import LineStack from './componet/stack';
|
||||
import { scoreComp , firstData , secondData } from './config';
|
||||
import axios from 'axios';
|
||||
|
||||
const dimensionData = {
|
||||
开发质量: ['Commit message质量', 'Issue数量', 'Commit 数量'],
|
||||
|
@ -20,12 +22,27 @@ function Dimension(props){
|
|||
const [ dimensions , setDimensions] = useState([]);
|
||||
const [dValue, setDValue] = useState('');
|
||||
|
||||
useEffect(()=>{
|
||||
Init();
|
||||
},[type])
|
||||
|
||||
useEffect(()=>{
|
||||
if(seconds){
|
||||
setSValue(seconds[0]);
|
||||
}
|
||||
},[seconds])
|
||||
|
||||
function Init(){
|
||||
const url = `/v1/${owner}/${projectsId}/oss_health_measuring/keyid`;
|
||||
axios(url,{params:{
|
||||
key_id:type
|
||||
}}).then(res=>{
|
||||
if(res && res.data){
|
||||
console.log(res.data);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(sValue){
|
||||
let arr = dimensionData[sValue];
|
||||
|
@ -38,7 +55,7 @@ function Dimension(props){
|
|||
return(
|
||||
<div>
|
||||
<Breadcrumb separator=">">
|
||||
<Breadcrumb.Item href={`/${owner}/${projectsId}/service/measurement`}>首页</Breadcrumb.Item>
|
||||
<Breadcrumb.Item><Link className="color-blue" to={`/${owner}/${projectsId}/service/measurement`}>首页</Link></Breadcrumb.Item>
|
||||
<Breadcrumb.Item>开发活动</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className='headBox font-16 pl15 mt20 df pr30 mb30'>
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import javaFetch from "./javaFetch";
|
||||
// let settings = localStorage && localStorage.chromesetting && localStorage.chromesetting !=="undefined" && JSON.parse(localStorage.chromesetting);
|
||||
// let actionUrl = settings && settings.common.softbot;
|
||||
let actionUrl = 'http://60.205.224.11:8060';
|
||||
|
||||
const service = javaFetch("");
|
||||
export const httpUrl = actionUrl;
|
||||
export default service;
|
|
@ -10,11 +10,13 @@ import person from '../img/person.png';
|
|||
import Rader from './componet/radar';
|
||||
import Indicator from './componet/indicator';
|
||||
import { scoreComp , field , firstData , colorsField, secondData , subField , thirdData } from './config';
|
||||
import { getMainScore , getChange } from './api';
|
||||
import axios from "axios";
|
||||
import cookie from 'react-cookies';
|
||||
// import res from './xiuos.json';
|
||||
|
||||
|
||||
function Index(props){
|
||||
const [ dataLoading , setDataLoading ] = useState(true);
|
||||
const [cardIndex, setCardIndex] = useState(firstData[0]);
|
||||
const [ subCardIndex, setSubCardIndex] = useState(1);
|
||||
const [ loading , setLoading ] = useState(false);
|
||||
|
@ -33,34 +35,50 @@ function Index(props){
|
|||
let interval = undefined;
|
||||
const count = useRef();
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
if(owner && projectsId){
|
||||
checkData();
|
||||
console.log(cookie.load("opensource"));
|
||||
if(cookie.load("opensource") && cookie.load("opensource")===`${owner}_${projectsId}`){
|
||||
getReportStart();
|
||||
}else{
|
||||
checkData();
|
||||
}
|
||||
}
|
||||
},[owner,projectsId])
|
||||
|
||||
// 根据接口判断是否已经生成数据报告
|
||||
async function checkData(){
|
||||
getChange(owner,projectsId).then(res=>{
|
||||
if(res && res.statue === "YES"){
|
||||
const url = `/v1/${owner}/${projectsId}/oss_health_measuring/can_get`;
|
||||
axios(url).then(res=>{
|
||||
if(res && res.data && res.data.statue === "YES"){
|
||||
Init();
|
||||
clearInterval(interval);
|
||||
cookie.remove("opensource");
|
||||
}else if(res && res.data && res.data.statue === "NO"){
|
||||
setDataLoading(false);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取接口,整个页面数据都从此接口返回
|
||||
// 获取数据接口
|
||||
function Init(){
|
||||
getMainScore(owner,projectsId).then(res=>{
|
||||
if(res){
|
||||
setDatas(res);
|
||||
setScoreNormal(res && res.score);
|
||||
getlist(res && res.score);
|
||||
const url = `/v1/${owner}/${projectsId}/oss_health_measuring/keyid`;
|
||||
axios(url,{params:{
|
||||
key_id:"score"
|
||||
}}).then(res=>{
|
||||
if(res && res.data){
|
||||
let data = res.data;
|
||||
setTimeout(()=>{setDataLoading(false)},300);
|
||||
setDatas(data);
|
||||
setScoreNormal(data);
|
||||
getlist(data);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 开始体验,定时调用接口
|
||||
function getReportStart(){
|
||||
|
||||
setLoading(true);
|
||||
count.current = 20;
|
||||
checkData();
|
||||
|
@ -73,7 +91,7 @@ function Index(props){
|
|||
} else {
|
||||
//倒计时结束,提示繁忙
|
||||
clearInterval(interval);
|
||||
setLoading(true);
|
||||
setLoading(false);
|
||||
props.showNotification("当前服务繁忙,请稍后再试");
|
||||
}
|
||||
}, 30000)
|
||||
|
@ -126,19 +144,20 @@ function Index(props){
|
|||
return(
|
||||
<div>
|
||||
<div class="headBox font-16 pl15">开源软件健康度量服务</div>
|
||||
{ dataLoading && <Spin><div style={{minHeight:400,width:"100%"}}></div></Spin>}
|
||||
{
|
||||
!datas &&
|
||||
!dataLoading && !datas &&
|
||||
<div class="nullStoreBox mt25">
|
||||
<img src={Logo} class="loBox mt50" />
|
||||
<p class="font-22 mt10">欢迎使用开源软件健康度量服务</p>
|
||||
<div class="introBox font-15">开源软件健康度量服务是一种代码库分析工具,旨在通过深入分析代码库的关键活动数据来评估开源项目的健康状况。该服务通过收集和分析代码库中的贡献者、提交(commit)、合并请求(pullRequest)、疑修(issue)等数据指标,为项目开发者、维护者提供了一个全面的项目健康报告</div>
|
||||
<div class="borBox"></div>
|
||||
{!loading && <Button type="primary" onClick={()=>{getReportStart()}}>开始体验</Button> }
|
||||
{!loading && <Button type="primary" onClick={()=>{cookie.save("opensource",`${owner}_${projectsId}`,{ expires: new Date(new Date().getTime() + 24 * 3600 * 1000),path:`/` });getReportStart();}}>开始体验</Button> }
|
||||
{ loading && <div><Spin /><span className="ml5 color-blue">服务报告生成中...</span></div> }
|
||||
</div>
|
||||
}
|
||||
{
|
||||
datas &&
|
||||
!dataLoading && datas &&
|
||||
<div className="scorePanel">
|
||||
{
|
||||
scoreNormal &&
|
||||
|
@ -224,7 +243,7 @@ function Index(props){
|
|||
<div className="echartData">
|
||||
<Rader data={fieldDatas} subCardIndex={subCardIndex}/>
|
||||
<div style={{width:"50%"}}>
|
||||
<Indicator data={fieldDatas} subCardIndex={subCardIndex}/>
|
||||
<Indicator data={fieldDatas} subCardIndex={subCardIndex} owner={owner} projectsId={projectsId}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
import { notification ,message} from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
// export const TokenKey = 'autologin_trustie';
|
||||
|
||||
export default function javaFetch(actionUrl){
|
||||
if (window.location.href.indexOf('localhost') < 0) {
|
||||
axios.defaults.withCredentials = true;
|
||||
}
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: actionUrl,
|
||||
timeout: 1800000, // 请求超时时间
|
||||
});
|
||||
|
||||
// request拦截器
|
||||
// service.interceptors.request.use(config => {
|
||||
// if (cookie.load(TokenKey)) {
|
||||
// config.headers['Authorization'] = cookie.load(TokenKey); // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
// }
|
||||
// if (window.location.port === "3007") {
|
||||
// // 模拟token为登录用户
|
||||
// const token = cookie.load(TokenKey);
|
||||
// if (config.url.indexOf('?') === -1) {
|
||||
// config.url = `${config.url}?token=${token}`;
|
||||
// } else {
|
||||
// config.url = `${config.url}&token=${token}`;
|
||||
// }
|
||||
// }
|
||||
// return config;
|
||||
// }, error => {
|
||||
// console.log(error);
|
||||
// });
|
||||
// respone拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const res = response||{};
|
||||
if (res.status === 400) {
|
||||
message.error(res.data.message || '操作失败');
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 401) {
|
||||
message.error(res.data.message || '登录信息已过期');
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 403) {
|
||||
message.error(res.data.message || '无权限!');
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 40001) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: '账户或密码错误!',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (response.status !== 200 && res.status !== 200) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message,
|
||||
});
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
let res = error.response||{};
|
||||
if (res.status === 400) {
|
||||
message.error(res.data.message || '操作失败');
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 401) {
|
||||
message.error(res.data.message || '登录信息已过期');
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 403) {
|
||||
message.error(res.data.message || '无权限!');
|
||||
return Promise.reject('error');
|
||||
}
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: error.message,
|
||||
});
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
return service;
|
||||
}
|
Loading…
Reference in New Issue