Browse Source

ADD:所有缺陷树状图展示,bug详情展示,img与点赞点踩

wjj 4 years ago
parent
commit
a888558b6f

+ 17 - 12
src/components/GlobalHeader/RightContent.jsx

@@ -1,11 +1,12 @@
 import { Tooltip, Tag } from 'antd';
 import { QuestionCircleOutlined } from '@ant-design/icons';
-import React, { useEffect,useState } from 'react';
+import React, { useEffect, useState } from 'react';
 import { connect, SelectLang } from 'umi';
 import Avatar from './AvatarDropdown';
 import HeaderSearch from '../HeaderSearch';
 import styles from './index.less';
 import NoticeIconView from './NoticeIconView';
+
 const ENVTagColor = {
   dev: 'orange',
   test: 'green',
@@ -13,9 +14,9 @@ const ENVTagColor = {
 };
 
 const GlobalHeaderRight = (props) => {
-  console.log('right')
-  const { theme, layout,dispatch ,taskName} = props;
-  const [ idInfo,setIdInfo ] = useState({})
+  console.log('right');
+  const { theme, layout, dispatch, taskName } = props;
+  const [idInfo, setIdInfo] = useState({});
   let className = styles.right;
 
   if (theme === 'dark' && layout === 'top') {
@@ -48,12 +49,16 @@ const GlobalHeaderRight = (props) => {
   // },[])
 
 
-  useEffect(()=>{
-    dispatch({
-      type: 'report/getTaskName',
-      payload: { examId: idInfo.examId }
-    });
-  },[dispatch,idInfo.examId])
+  useEffect(() => {
+    console.log('这里发请求了,right');
+    if (idInfo && idInfo.examId) {
+      dispatch({
+        type: 'report/getTaskName',
+        payload: { examId: idInfo.examId },
+      }, [dispatch, idInfo.examId]);
+    }
+  });
+
   return (
     <div className={className}>
       {/*<NoticeIconView />*/}
@@ -63,8 +68,8 @@ const GlobalHeaderRight = (props) => {
   );
 };
 
-export default connect(({ report,settings }) => ({
+export default connect(({ report, settings }) => ({
   theme: settings.navTheme,
   layout: settings.layout,
-  taskName:report.taskName,
+  taskName: report.taskName,
 }))(GlobalHeaderRight);

+ 162 - 0
src/pages/bugs/components/BugDetailModal/index.jsx

@@ -0,0 +1,162 @@
+import { Col, Image, Spin } from 'antd';
+import React, { useEffect, useState } from 'react';
+import { connect } from 'umi';
+import styles from './index.less';
+import { timeToString } from '@/utils/common';
+import {
+  DislikeOutlined, LeftOutlined,
+  LikeOutlined, RightOutlined,
+} from '@ant-design/icons';
+import { recurrent, severity, bug_categories } from '@/pages/edit/components/Step2/const';
+
+const BugItemDetail = (props) => {
+  const { bugItemDetail, dispatch } = props;
+  const [detail, setDetail] = useState({});
+  const [operator, setOperator] = useState(-1);
+
+  const handleChangeImgToLeft = () => {
+    let newDetail = { ...detail };
+    newDetail.left--;
+    newDetail.right--;
+    newDetail['imgArr'] = newDetail['originArr'].slice(newDetail['left'], newDetail['right']);
+    setDetail(newDetail);
+  };
+
+  const handleChangeImgToRight = () => {
+    let newDetail = { ...detail };
+    newDetail.left++;
+    newDetail.right++;
+    newDetail['imgArr'] = newDetail['originArr'].slice(newDetail['left'], newDetail['right']);
+    setDetail(newDetail);
+  };
+
+  const handleOperateIcon = (type) => {
+    if (operator === -1) {
+      //这里的操作是点赞点踩操作
+      setOperator(type);
+      if (type) {
+        //type===1表示点赞
+        dispatch({
+          type: 'editReport/goodForReport',
+          payload: {
+            id: currDetail.id,//被点赞的报告的id
+            report_id: reportCommonInfo.id,
+            user_id: 2,
+            action: 'like',
+          },
+        });
+      } else {
+        dispatch({
+          type: 'editReport/badForReport',
+          payload: {
+            id: currDetail.id,//被点赞的报告的id
+            report_id: reportCommonInfo.id,
+            user_id: 2,
+            action: 'dislike',
+          },
+        });
+      }
+    } else {
+      //这里的操作是取消点赞点踩操作
+      setOperator(-1);
+      if (type) {
+        //type===1表示点赞
+        dispatch({
+          type: 'editReport/cancelGoodForReport',
+          payload: {
+            id: currDetail.id,//被点赞的报告的id
+            report_id: reportCommonInfo.id,
+          },
+        });
+      } else {
+        dispatch({
+          type: 'editReport/cancelBadForReport',
+          payload: {
+            id: currDetail.id,//被点赞的报告的id
+            report_id: reportCommonInfo.id,
+          },
+        });
+      }
+    }
+
+
+  };
+
+  useEffect(() => {
+    if (JSON.stringify(bugItemDetail) !== '{}') {
+      console.log(bugItemDetail);
+      let { detail } = bugItemDetail;
+      detail['originArr'] = detail.img_url ? detail.img_url.split(',') : [];
+      if (detail['originArr'].length >= 3) {
+        //通过更改左右的标记值来更改显示的图片
+        detail['left'] = 0;
+        detail['right'] = 3;
+        detail['imgArr'] = detail['originArr'].slice(detail['left'], detail['right']);
+      } else if (detail['originArr'].length > 0 && detail['originArr'].length < 3) {
+        detail['imgArr'] = detail['originArr'];
+        detail['left'] = 0;
+        detail['right'] = detail['originArr'].length;
+      }
+      setDetail(detail);
+    }
+
+  }, [bugItemDetail]);
+
+  return (
+    detail && detail.id ?
+      <div className={styles.bugItemDetail}>
+        <div className={styles.detailItem}>
+          <span className={styles.detailLabel}>Bug标识:</span>{detail && detail.id || ''}
+        </div>
+        <div className={styles.detailItem}><span
+          className={styles.detailLabel}>Bug题目:</span>{detail && detail.title || ''}
+        </div>
+        <div className={styles.detailItem}><span
+          className={styles.detailLabel}>Bug描述:</span>{detail && detail.description}</div>
+        <div className={styles.detailItem}><span
+          className={styles.detailLabel}>创建时间:</span>{timeToString(detail.create_time_millis)}</div>
+        <div className={styles.detailItem}><span className={styles.detailLabel}>页面路径:</span>{detail.bug_page}
+        </div>
+        <div className={styles.detailItem}><span
+          className={styles.detailLabel}>漏洞分类:</span>{detail.bug_category}</div>
+        <div className={styles.detailItem}><span
+          className={styles.detailLabel}>严重等级:</span>{severity[detail.severity - 1]}</div>
+        <div className={styles.detailItem}><span
+          className={styles.detailLabel}>复现程度:</span>{recurrent[detail.recurrent - 1]}</div>
+        {
+          detail && detail.img_url ? (
+              <div className={`${styles.detailItem} ${styles.detailItemOperator}`}><span
+                className={styles.detailLabel}>Bug截图:</span>
+                <div span={12} className={styles.bugImgList}>
+                  {detail.left > 0 ? <LeftOutlined
+                      onClick={handleChangeImgToLeft} /> :
+                    <div className={styles.switchImgBtn}></div>}
+
+                  {detail.imgArr.map(img => {
+                    return <Image src={img} key={img} />;
+                  })}
+
+                  {detail.right < (detail.originArr.length - 1) ?
+                    <RightOutlined onClick={handleChangeImgToRight} /> :
+                    <div className={styles.switchImgBtn}></div>}
+
+                </div>
+              </div>)
+            : null
+        }
+        <div className={`${styles.detailItem} ${styles.detailItemOperator}`}><span
+          className={styles.detailLabel}>Bug评价:</span>
+          {operator !== 0 ?
+            <LikeOutlined className={`${styles.operatorIcon} ${operator === 1 ? styles.operatorIconActive : ''}`}
+                          onClick={() => handleOperateIcon(1)} /> : null}
+          {operator !== 1 ?
+            <DislikeOutlined className={`${styles.operatorIcon} ${operator === 0 ? styles.operatorIconActive : ''}`}
+                             onClick={() => handleOperateIcon(0)} /> : null}
+        </div>
+      </div> : <Spin />
+  );
+};
+
+export default connect(({ allBugs, editReport }) => ({
+  bugItemDetail: allBugs.bugItemDetail,
+}))(BugItemDetail);

+ 65 - 0
src/pages/bugs/components/BugDetailModal/index.less

@@ -0,0 +1,65 @@
+@import '~antd/es/style/themes/default.less';
+
+.bugItemDetail {
+  .detailItem{
+    height: 50px;
+    line-height: 50px;
+    box-sizing: border-box;
+    padding: 0 20px;
+    border-bottom: 1px solid #eee;
+    font-size: 14px;
+    .detailLabel {
+      width: 90px;
+      line-height: 30px;
+      height: 30px;
+      display: inline-block;
+    }
+    .backIcon {
+      float: right;
+    }
+  }
+  .detailItemOperator {
+    height: auto;
+    padding: 10px 20px;
+    display: flex;
+    .detailLabel {
+      line-height: 80px;
+      height: 80px;
+      display: table-cell;
+      vertical-align: center;
+    }
+    .detailItemImg {
+      display: inline-block;
+    }
+    .operatorIcon {
+      font-size: 30px;
+      margin:15px 30px;
+      border: 1px solid #eee;
+      padding: 9px;
+      height: 52px;
+      border-radius: 8px;
+      &:hover{
+        background-color: #eee;
+      }
+    }
+    .operatorIconActive {
+      color: red;
+    }
+    .switchImgBtn{
+      width: 14px;
+      height: 14px;
+    }
+    .bugImgList {
+      display: flex;
+      img {
+        width: 100px;
+        height: 100px;
+        margin:5px 10px;
+      }
+      span {
+        display: inline-block;
+        margin: 50px 0;
+      }
+    }
+  }
+}

+ 58 - 7
src/pages/bugs/components/BugList/index.jsx

@@ -1,12 +1,47 @@
-import { Button, Result, Descriptions, Statistic } from 'antd';
+import { Pagination } from 'antd';
 import React, { useEffect, useState } from 'react';
 import { connect } from 'umi';
 import styles from './index.less';
+import { treeFilter } from 'enzyme/src/RSTTraversal';
 
 const BugList = (props) => {
-  const { data, dispatch,bugLists,commonId} = props;
+  const { data, dispatch,commonId,bugTreeList} = props;
   const [start,setStart] = useState(0);
   const [page,setPage] = useState('null');
+  const [currentTreeItem,setCurrentTreeItem] = useState([]);
+
+  const onPageChange = (num)=>{
+    console.log('page',num)
+  }
+
+  const handleTreeItemClick = (item)=>{
+    const currItem = bugTreeList.TreeRoot.filter(i=>i[0]===item[0]);
+    setCurrentTreeItem(currItem[0]);
+  }
+
+  useEffect(()=>{
+    bugTreeList.TreeRoot && setCurrentTreeItem(bugTreeList.TreeRoot[0])
+  },[bugTreeList])
+
+  useEffect(()=>{
+    if(JSON.stringify(currentTreeItem)!=='[]'){
+      //获取bug详情信息用于展示
+      dispatch({
+        type: 'editReport/getBugDetail',
+        payload:{
+          id:currentTreeItem[0]
+        }
+      }).then(res => {
+        console.log(res)
+        dispatch({
+          type: 'allBugs/saveBugItemDetail',
+          payload:{
+            ...res
+          }
+        })
+      })
+    }
+  },[currentTreeItem])
 
   useEffect(()=>{
     dispatch({
@@ -18,24 +53,40 @@ const BugList = (props) => {
         page
       }
     })
-  })
+  },[])
 
   return (
     <div>
       <div className={styles.bugList}>
         {
-
+          bugTreeList&&bugTreeList.TreeRoot&&bugTreeList.TreeRoot.map((item,index)=>{
+            return (
+              <div key={item[0]}
+                className={`${styles.bugListItem} ${currentTreeItem[0] === item[0] ? styles.bugListItemActive : ''}`}
+                onClick={()=>{handleTreeItemClick(item)}}>
+                <span className={styles.bugListItemNum}>
+                  树{index+1}:
+                </span>
+                <div className={styles.bugListItemInfo}>
+                  <span className={styles.bugListItemSummary}>
+                  高:{item[2]} 宽:{item[1]} 个数:{item[3]}</span>
+                  <div className={styles.bugListItemTitle}>
+                    {item[5]}
+                  </div>
+                </div>
+              </div>
+            )
+          })
         }
-        <div className={`${styles.bugListItem} ${styles.bugListItemActive}`}>
-          <span className={styles.bugListItemNum}>Bug1:</span>邮箱校验规则不严谨
-        </div>
       </div>
+      <Pagination showQuickJumper defaultCurrent={2} total={bugTreeList.Count} onChange={onPageChange} />
     </div>
   );
 };
 
 export default connect(({ allBugs , editReport}) => ({
   data: allBugs.step,
+  bugTreeList: allBugs.bugTreeList,
   reportCommonInfo: editReport.reportCommonInfo,
   commonId: editReport.commonId,
 }))(BugList);

+ 12 - 0
src/pages/bugs/components/BugList/index.less

@@ -7,8 +7,19 @@
     border-bottom: none;
     border-radius: 7px;
     max-width: 350px;
+    display: flex;
     .bugListItemNum {
       font-weight: bold;
+      display: inline-block;
+      width: 50px;
+    }
+    .bugListItemInfo{
+      .bugListItemSummary {
+
+      }
+      .bugListItemTitle{
+
+      }
     }
   }
   .bugListItem:last-child{
@@ -21,4 +32,5 @@
     background-color: #e6f7ff;
   }
 
+
 }

+ 2 - 6
src/pages/bugs/index.jsx

@@ -5,6 +5,7 @@ import { connect } from 'umi';
 const { Option } = Select;
 
 import BugList from './components/BugList';
+import BugDetailModal from './components/BugDetailModal';
 
 import {
   ApartmentOutlined,
@@ -125,12 +126,7 @@ const AllBugs = (props) => {
             </Col>
             <Col span={8}>
               <div className={styles.bugDetail}>
-                <Row>
-                  <Col span={20}>
-
-                  </Col>
-                  <Col span={4}>热度:1</Col>
-                </Row>
+                <BugDetailModal/>
               </div>
             </Col>
           </Row>

+ 7 - 4
src/pages/bugs/model.js

@@ -6,9 +6,9 @@ import {
 const Model = {
   namespace: 'allBugs',
   state: {
-    allBugList: [],
     reportReview:{},
-    bugTreeList:[]
+    bugTreeList:[],
+    bugItemDetail:{}
   },
   effects: {
     //todo:获取bug总数,点赞、点踩总数
@@ -25,7 +25,6 @@ const Model = {
     * getTreeList({ payload }, { call, put }) {
       const {case_take_id,start,count,page} = payload;
       let res = yield call(getTreeList, case_take_id,start,count,page);
-      console.log(res);
       yield put({
         type: 'saveBugTreeList',
         payload: res,
@@ -39,6 +38,10 @@ const Model = {
     saveBugTreeList(state, { payload }) {
       return { ...state, bugTreeList: payload };
     },
-  },
+    saveBugItemDetail(state, { payload }) {
+      console.log(payload)
+      return { ...state, bugItemDetail: payload };
+    },
+  }
 };
 export default Model;

+ 1 - 1
src/pages/bugs/style.less

@@ -13,5 +13,5 @@
 .bugDetail {
   border: 1px dashed #1890ff;
   border-radius: 8px;
-
+  padding: 10px 20px;
 }

+ 3 - 3
src/pages/edit/components/Step2/index.jsx

@@ -16,7 +16,7 @@ import {
 const { Search } = Input;
 import * as echarts from 'echarts';
 import { recurrent, severity, bug_categories } from './const';
-import { timeToString, getBase64 } from '../../utils';
+import { timeToString, getBase64 } from '@/utils/common';
 
 import BugGuideTree from '../BugGuideTree';
 
@@ -500,7 +500,7 @@ const Step2 = (props) => {
                                 {item.left > 0 ? <LeftOutlined
                                   onClick={() => {
                                     handleChangeImgToLeft(item);
-                                  }} /> : null}
+                                  }} /> : <div className={styles.switchImgBtn}></div>}
 
                                 {item.imgArr.map(img => {
                                   return <Image src={img} key={img} />;
@@ -508,7 +508,7 @@ const Step2 = (props) => {
 
                                 {item.right < (item.originArr.length - 1) ? <RightOutlined onClick={() => {
                                   handleChangeImgToRight(item);
-                                }} /> : null}
+                                }} /> : <div className={styles.switchImgBtn}></div>}
 
                               </Col>)
                             : null}

+ 4 - 0
src/pages/edit/components/Step2/index.less

@@ -149,6 +149,10 @@
         display: inline-block;
         margin: 50px 0;
       }
+      .switchImgBtn{
+        width: 14px;
+        height: 14px;
+      }
     }
   }
 

+ 1 - 1
src/pages/edit/model.js

@@ -50,7 +50,7 @@ const Model = {
       beginTime:"1621945823000",
       endTime:"1624291200000",
       userId:"99222",
-      case_take_id:"3656_3656",
+      case_take_id:"1718_1718",
     },
   },
   effects: {

+ 20 - 0
src/utils/common.js

@@ -0,0 +1,20 @@
+//todo:转化时间戳为 yyyy-MM-dd hh:mm:ss
+export const timeToString = (time)=>{
+  const date = new Date(Number(time));
+  const Y = date.getFullYear() + '-';
+  const M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
+  const D = date.getDate() + ' ';
+  const h = date.getHours() < 10 ? ('0' + date.getHours()) : date.getHours();
+  const m = ':' + (date.getMinutes() < 10 ? ('0' + date.getMinutes()) : date.getMinutes()) + ':';
+  const s = date.getSeconds() < 10 ? ('0' + date.getSeconds()) : date.getSeconds();
+  return Y+M+D+h+m+s;
+}
+
+export const getBase64 = (file)=> {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.readAsDataURL(file);
+    reader.onload = () => resolve(reader.result);
+    reader.onerror = error => reject(error);
+  });
+}