|
@@ -1,4 +1,4 @@
|
|
|
-import { Table, Tag, Row, Col, Image,Button } from 'antd';
|
|
|
+import { Table, Tag, Row, Col, Image, Button } from 'antd';
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
import { connect } from 'umi';
|
|
|
import styles from './index.less';
|
|
@@ -7,12 +7,25 @@ import {
|
|
|
RollbackOutlined,
|
|
|
} from '@ant-design/icons';
|
|
|
import { recurrent, severity, bug_categories } from '../Step2/const';
|
|
|
+import * as echarts from 'echarts';
|
|
|
+
|
|
|
+//这里只能放在 pages/edit/assets中作为路径显示
|
|
|
+const imgArr = ['noArrived.png', 'yellowFlag.png', 'redFlag.png', 'recPage.png']
|
|
|
|
|
|
const BugGuideTree = (props) => {
|
|
|
- const { dispatch, pathInfo, recommendPath, bugRecommendList } = props;
|
|
|
+ const { dispatch, pathInfo, recommendPath, bugRecommendList, categories } = props;
|
|
|
+ const allPath = pathInfo.all; //所有已发现bug
|
|
|
+ const userPath = pathInfo.self; //我的bug
|
|
|
+ const { page, info } = recommendPath;
|
|
|
+
|
|
|
+ let jsonPath={};
|
|
|
+ let timer = null;
|
|
|
|
|
|
const [showTable, setShowTable] = useState(true);
|
|
|
const [currDetail, setCurrDetail] = useState({});
|
|
|
+ const [treeHeight, setTreeHeight] = useState(600);
|
|
|
+ const [treeHeightNum, setTreeHeightNum] = useState(0);
|
|
|
+
|
|
|
const columns = [
|
|
|
{
|
|
|
title: '标题',
|
|
@@ -48,7 +61,6 @@ const BugGuideTree = (props) => {
|
|
|
},
|
|
|
},
|
|
|
];
|
|
|
-
|
|
|
const handleClickTableRow = (item) => {
|
|
|
dispatch({
|
|
|
type: 'editReport/getBugDetail',
|
|
@@ -60,30 +72,304 @@ const BugGuideTree = (props) => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- const handleClickBack = ()=>{
|
|
|
+ const handleClickBack = () => {
|
|
|
setCurrDetail({});
|
|
|
+ };
|
|
|
+
|
|
|
+ const initChartData = () => {
|
|
|
+ const data = categories;
|
|
|
+ const str = JSON.stringify(data);
|
|
|
+ const str2 = str.replace(/item/g, 'name');
|
|
|
+ const json = {};
|
|
|
+ json['name'] = 'web';
|
|
|
+ json['children'] = JSON.parse(str2);
|
|
|
+ jsonPath = json;
|
|
|
+ getHeight(jsonPath.children);
|
|
|
+ setTreeHeightNum(Math.max(treeHeightNum, 600));
|
|
|
+ setTreeHeight(Math.max(treeHeightNum, 600));
|
|
|
+ };
|
|
|
+
|
|
|
+ const getHeight = (items) => {
|
|
|
+ items.forEach(item => {
|
|
|
+ if (item.children) {
|
|
|
+ getHeight(item.children);
|
|
|
+ } else {
|
|
|
+ setTreeHeightNum(treeHeightNum + 25);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const setRecPage = (page)=> {
|
|
|
+ let flag = 0;
|
|
|
+ let style;
|
|
|
+ timer = setInterval(() => {
|
|
|
+ if (flag === 1) {
|
|
|
+ style = 'image://' + require('../../assets/' + imgArr[0]);
|
|
|
+ flag = 0;
|
|
|
+ } else {
|
|
|
+ style = 'image://' + require('../../assets/' + imgArr[3]);
|
|
|
+ flag = 1;
|
|
|
+ }
|
|
|
+ initItemRecursionRecPage(jsonPath.children, page, style);
|
|
|
+ const myChart = echarts.init(document.getElementById('myChart'));
|
|
|
+ // console.log(document.getElementById('myChart'))
|
|
|
+ myChart.setOption({series: [{data: [jsonPath]}]});
|
|
|
+ }, 2000);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ const initItemRecursion = (items)=> {
|
|
|
+ if (items !== undefined) {
|
|
|
+ items.forEach(item => {
|
|
|
+ item['value'] = 0;
|
|
|
+ item['symbol'] = 'image://' + require('../../assets/' + imgArr[0]);
|
|
|
+ item['category'] = 0;
|
|
|
+ // 已经发现Bug的页面
|
|
|
+ for (let p in allPath) {
|
|
|
+ if (item.name === p) {
|
|
|
+ item.value += allPath[p];
|
|
|
+ item.category = 1;
|
|
|
+ item.symbol = 'image://' + require('../../assets/' + imgArr[1]);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //个人发现bug的页面
|
|
|
+ for (let p in userPath) {
|
|
|
+ if (item.name === p) {
|
|
|
+ //this.nodes[i].value = userPath.p;
|
|
|
+ item.category = 2;
|
|
|
+ item.symbol = 'image://' + require('../../assets/' + imgArr[2]);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (item.children) {
|
|
|
+ initItemRecursion(item.children);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const initItemRecursionRecPage = (items, page, style)=> {
|
|
|
+ if (items !== undefined) {
|
|
|
+ items.forEach(item => {
|
|
|
+ for (let j = 0; j < (page&&page.length) || 0; j++) {
|
|
|
+ if (item.name === page[j]) {
|
|
|
+ item['symbol'] = style;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (item.children) {
|
|
|
+ initItemRecursionRecPage(item.children, page, style);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const initEcharts = ()=>{
|
|
|
+ let item_color = 'rgba(226,245,240,1)';
|
|
|
+ let border_color = 'rgba(0,0,0,0.9)';
|
|
|
+ let legendCategories = [
|
|
|
+ {
|
|
|
+ 'name': '暂无Bug',
|
|
|
+ 'icon': 'image://' + require('../../assets/' + imgArr[0]),
|
|
|
+ 'itemStyle': { 'normal': { 'color': item_color, 'borderColor': border_color } },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ 'name': '已有Bug',
|
|
|
+ 'icon': 'image://' + require('../../assets/' + imgArr[1]),
|
|
|
+ 'itemStyle': { 'normal': { 'color': item_color, 'borderColor': border_color } },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ 'name': '我的Bug',
|
|
|
+ 'icon': 'image://' + require('../../assets/' + imgArr[2]),
|
|
|
+ 'itemStyle': { 'normal': { 'color': item_color, 'borderColor': border_color } },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ 'name': '推荐页面',
|
|
|
+ 'icon': 'image://' + require('../../assets/' + imgArr[3]),
|
|
|
+ 'itemStyle': { 'normal': { 'color': item_color, 'borderColor': border_color } },
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
+ let option2 = {
|
|
|
+ legend: { //配置legend,这里的data,要对应type为‘bar’的series数据项的‘name’名称,作为图例的说明
|
|
|
+ data: legendCategories,
|
|
|
+ selecedMode: false, //图例禁止点击
|
|
|
+ top: '5%',
|
|
|
+ left: '3%',
|
|
|
+ itemWidth: 10,
|
|
|
+ itemHeight: 10,
|
|
|
+ orient: 'vertical',
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ triggerOn: 'mousemove',
|
|
|
+ formatter: function(params) {
|
|
|
+ if (params.data.category === 2) {
|
|
|
+ return params.name + '<br>' + '我发现/所有: ' + userPath[params.name] + '/' + params.value;
|
|
|
+ } else if (params.data.category === 1) {
|
|
|
+ return params.name + '<br>' + '我发现/所有: 0/' + params.value;
|
|
|
+ } else {
|
|
|
+ return '还未有人在该页面发现Bug,努力寻找第一个Bug吧!';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ z: 1, //grid作为柱状图的坐标系,其层级要和仪表图层级不同,同时隐藏
|
|
|
+ show: false,
|
|
|
+ left: '-30%',
|
|
|
+ right: '4%',
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true,
|
|
|
+ splitLine: {
|
|
|
+ show: false, //隐藏分割线
|
|
|
+ },
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ xAxis: [ //这里有很多的show,必须都设置成不显示
|
|
|
+ {
|
|
|
+ type: 'category',
|
|
|
+ data: [],
|
|
|
+ axisLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ splitArea: {
|
|
|
+ interval: 'auto',
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+
|
|
|
+ yAxis: [ //这里有很多的show,必须都设置成不显示
|
|
|
+ {
|
|
|
+ type: 'value',
|
|
|
+ axisLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'tree',
|
|
|
+ name: 'tree1',
|
|
|
+ data: [pathInfo],
|
|
|
+ categories: legendCategories,
|
|
|
+ top: '5%',
|
|
|
+ left: '9%',
|
|
|
+ bottom: '1%',
|
|
|
+ right: '15%',
|
|
|
+
|
|
|
+ symbolSize: 12,
|
|
|
+
|
|
|
+ label: {
|
|
|
+ normal: {
|
|
|
+ position: 'left',
|
|
|
+ verticalAlign: 'middle',
|
|
|
+ align: 'right',
|
|
|
+ fontSize: 9,
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ leaves: {
|
|
|
+ label: {
|
|
|
+ normal: {
|
|
|
+ position: 'right',
|
|
|
+ verticalAlign: 'middle',
|
|
|
+ align: 'left',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ expandAndCollapse: true,
|
|
|
+ initialTreeDepth: 4,
|
|
|
+ animationDuration: 550,
|
|
|
+ animationDurationUpdate: 750,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: legendCategories[0].name,
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: '60%', //不显示,可以随便设置
|
|
|
+ data: [0],
|
|
|
+ itemStyle: {
|
|
|
+ normal: {
|
|
|
+ color: '#41C468', //这里的图例要注意,颜色设置和仪表盘的颜色对应起来
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: legendCategories[1].name,
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: '60%',
|
|
|
+ data: [0],
|
|
|
+ itemStyle: {
|
|
|
+ normal: {
|
|
|
+ color: '#70C1B3',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: legendCategories[2].name,
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: '60%',
|
|
|
+ data: [0],
|
|
|
+ itemStyle: {
|
|
|
+ normal: {
|
|
|
+ color: '#00A1E9',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: legendCategories[3].name,
|
|
|
+ type: 'bar',
|
|
|
+ barWidth: '60%',
|
|
|
+ data: [0],
|
|
|
+ itemStyle: {
|
|
|
+ normal: {
|
|
|
+ color: '#00A1E9',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ const chart = echarts.init(document.getElementById('myChart'));
|
|
|
+ chart.setOption(option2);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
useEffect(() => {
|
|
|
+ initChartData();
|
|
|
+ initItemRecursion(jsonPath.children);
|
|
|
+ initEcharts(info);
|
|
|
+ setRecPage(page);
|
|
|
+ }, [pathInfo.all,pathInfo.self,jsonPath.children,info,page]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
if (JSON.stringify(currDetail) !== '{}') {
|
|
|
setShowTable(false);
|
|
|
- }else{
|
|
|
- console.log(currDetail)
|
|
|
- setShowTable(true)
|
|
|
+ } else {
|
|
|
+ setShowTable(true);
|
|
|
}
|
|
|
}, [currDetail]);
|
|
|
|
|
|
return (
|
|
|
<Row gutter={10}>
|
|
|
- <Col span={12}>
|
|
|
- <div id="myChart"></div>
|
|
|
+ <Col span={14}>
|
|
|
+ <div id="myChart" style={{ height: treeHeight }}></div>
|
|
|
</Col>
|
|
|
{
|
|
|
- showTable ? <Col span={12}>
|
|
|
+ showTable ? <Col span={10}>
|
|
|
<div className={styles.myTable}>
|
|
|
<Table columns={columns}
|
|
|
rowKey={record => record.id}
|
|
|
dataSource={bugRecommendList}
|
|
|
+ pagination={{ pageSize: 8 }}
|
|
|
onRow={record => {
|
|
|
return {
|
|
|
onClick: event => {
|
|
@@ -93,12 +379,14 @@ const BugGuideTree = (props) => {
|
|
|
}} />
|
|
|
</div>
|
|
|
</Col> :
|
|
|
- <Col span={12}>
|
|
|
+ <Col span={10}>
|
|
|
<div className={styles.myTableItemDetail}>
|
|
|
<div className={styles.detailItem}>
|
|
|
<span className={styles.detailLabel}>Bug 标识:</span>{currDetail.id}
|
|
|
<span className={styles.backIcon}>
|
|
|
- <Button><RollbackOutlined onClick={()=>{handleClickBack()}}/></Button>
|
|
|
+ <Button><RollbackOutlined onClick={() => {
|
|
|
+ handleClickBack();
|
|
|
+ }} /></Button>
|
|
|
</span>
|
|
|
</div>
|
|
|
<div className={styles.detailItem}><span className={styles.detailLabel}>Bug 题目:</span>{currDetail.title}
|
|
@@ -125,17 +413,15 @@ const BugGuideTree = (props) => {
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
</Col>
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
</Row>
|
|
|
);
|
|
|
};
|
|
|
|
|
|
export default connect(({ editReport }) => ({
|
|
|
pathInfo: editReport.pathInfo,
|
|
|
+ categories: editReport.categories,
|
|
|
recommendPath: editReport.recommendPath,
|
|
|
bugRecommendList: editReport.bugRecommendList,
|
|
|
}))(BugGuideTree);
|