展示个人认为有挑战性的前端页面

在这里插入图片描述

import React, { Component } from 'react';
import { observer } from 'mobx-react';
import { toJS } from 'mobx';
import IssueStore from '../../../stores/project/sprintFollow/IssueStore/IssueStore';
import {
  Page, Header, Content, stores, axios,
} from '@choerodon/boot';
import {
  Button, Icon, Select, DatePicker,
  Modal, Input, Form, Tooltip, Table
} from 'choerodon-ui';
import _ from 'lodash';
import './Issue/Issue.scss';
import moment from 'moment';
import { multiple } from '../../../assets/image';
import {getParams, delta2Html} from "../../../common/utils";
import StatusTag from '../../../components/StatusTag/StatusTag';
import TestStatusTags from '../../../components/TestStatusTags/StatusTags';
import DemandStatusTag from '../../../components/DemandStatusTag';

const { AppState } = stores;
const { Option } = Select;
const { RangePicker } = DatePicker;
const FormItem = Form.Item;

const getIssueStatus = (record) => {
  return (
    <Tooltip mouseEnterDelay={0.5} title={`问题状态: ${record.statusMapDTO && record.statusMapDTO.name}`}>
      <StatusTag
        data={record.issueInfosDTO ? record.issueInfosDTO.statusMapDTO : record.statusMapDTO}
        style={{ display: 'inline-block', verticalAlign: 'middle' }}
      />
    </Tooltip>
  );
}

const getExecuteStatus = (status) => {
  return (
    <Tooltip mouseEnterDelay={0.5} >
      <TestStatusTags
        name={status.statusName}
        color={status.statusColor}
      />
    </Tooltip>
  );
}

const DemandStatusName = (record) => {
  return (
    <DemandStatusTag
      record={record}
      style={{ display: 'inline-block', verticalAlign: 'middle' }}
    />
  );
}

const getName = (issue, type) => {
  let dom = null;
  if (issue.summary) {
    dom = issue.summary;
  } else if (issue.cycleName) {
    dom =  issue.cycleName + "/" + issue.folderName;
  } else if (issue.issueInfosDTO) {
    dom = issue.issueInfosDTO.summary;
  }
  const urlParams = AppState.currentMenuType;
  let jumpUrl = '';
  
  return (
    <Tooltip mouseEnterDelay={0.5} placement="topLeft" title={`${dom}`}>
      <span
        className="c7n-Issue-summary" 
        onClick={async () => {
          if (type === 'agile' || issue.typeCode === 'bug') {
            let res = await axios.get(`/agile/v1/projects/${urlParams.id}/issues/${issue.issueId}?organizationId=${urlParams.organizationId}`)
            jumpUrl = `/#/agile/issue?type=project&id=${urlParams.id}&name=${urlParams.name}&organizationId=${urlParams.organizationId}&paramName=${res.issueNum}&paramIssueId=${res.issueId}&paramOpenIssueId=${res.issueId}&paramUrl=/agile/issue-follow`
          } else if (type === 'apply') {
            let res = await axios.get(`/agile/v1/projects/${urlParams.id}/idp/issues/${issue.issueId}?organizationId=${urlParams.organizationId}`)
            jumpUrl = `/#/agile/demand-application?type=project&id=${urlParams.id}&name=${urlParams.name}&organizationId=${urlParams.organizationId}&paramName=${res.issueNum}&paramIssueId=${res.issueId}&paramOpenIssueId=${res.issueId}&paramUrl=/agile/issue-follow`
          } else if (type === 'test') {
            jumpUrl = `/#/testManager/IssueManage/testCase/${issue.issueId}?type=project&id=${urlParams.id}&name=${urlParams.name}&organizationId=${urlParams.organizationId}`
          } else if (type === 'execute') {
            jumpUrl = `/#/testManager/TestExecute/execute/${issue.executeId}?type=project&id=${urlParams.id}&name=${urlParams.name}&organizationId=${urlParams.organizationId}&cycleId=${issue.cycleId}`
          }
          window.open(jumpUrl);
        }}
      >
        {dom}
      </span>
    </Tooltip>
  )
}

// 自定义列宽度
const customColumn = {
  topWidth: '16%',
  oneWidth: '20%',
  twoWidth: '25%',
  threeWidth: '40%'
};


// 获取某一层级的全部要节点
const flattenItem = (staticIssue, staticIndex, type) => {
  let allArr = [];
  let handleIndex = 1;
  const handle = (issue, index) => {
    if (staticIndex === index) {
      allArr.push(issue)
      return false
    }
    let tempIndex = index + 1;
    if (staticIndex > index) {
      issue.child && issue.child.map((item) => {
        handle(item, tempIndex);
      })
    }
  }
  handle(JSON.parse(JSON.stringify(staticIssue)), handleIndex);
  if (type === 'execute') {
    return arrayUnique2(allArr, 'cycleId');
  } else if (type === 'currentExecute') {
    return arrayUnique2(allArr, 'folderName');
  } else {
    return arrayUnique2(allArr, 'issueId');
  }
}

const getArrow = (show, issue) => {
  if (issue.typeCode && issue.typeCode === 'bug') { return null; }
  return !show ? <Icon style={{marginBottom: '10px'}} type="navigate_next" /> : <Icon style={{marginBottom: '10px'}} type="expand_more" />
}

// 返回未展开问题的各种状态
const arrToGroup = (arr, type) => {
  var map = {}, dest = [];
  // 过滤掉缺陷
  let tempArr = [];

  if (type === 'execute') {
    JSON.parse(JSON.stringify(arr)).map((item) => {
      if (item.typeCode === 'bug') {
        return;
      } else {
        tempArr.push({
          ...item,
          ...item.issueInfosDTO.statusMapDTO
        })
      }
    })
  } else {
    JSON.parse(JSON.stringify(arr)).map((item) => {
      if (item.typeCode === 'bug') {
        return;
      } else {
        tempArr.push({
          ...item,
          ...item.statusMapDTO,
        })
      }
    })
  }

  for(var i = 0; i < tempArr.length; i++){
      var ai = tempArr[i];
      if(!map[ai.name]){
          dest.push({
            name: ai.name,
            item: [ai]
          });
          map[ai.name] = ai;
      }else{
          for(var j = 0; j < dest.length; j++){
              var dj = dest[j];
              if(dj.name == ai.name){
                  dj.item.push(ai);
                  break;
              }
          }
      }
  }
  let str = '';
  dest.map((item) => {
    str = str + `${item.name}: ${item.item.length};`
  })
  return (
    <Tooltip mouseEnterDelay={0.5} placement="topLeft" title={`${str}`}>
      <span className="c7n-Issue-summary">
        {str}
      </span>
    </Tooltip>
  );
  
}

// 返回未展开问题的各种状态
const arrToGroupExecute = (arr, executeList) => {
  
  var map = {}, dest = [];
  // 过滤掉缺陷
  let tempArr = [];


  JSON.parse(JSON.stringify(arr)).map((item) => {
    let status = _.find(executeList, { statusId: item.executionStatus })
    tempArr.push({
      ...item,
      ...status,
    })
  })

  for(var i = 0; i < tempArr.length; i++){
      var ai = tempArr[i];
      if(!map[ai.statusName]){
          dest.push({
            statusName: ai.statusName,
            item: [ai]
          });
          map[ai.statusName] = ai;
      }else{
          for(var j = 0; j < dest.length; j++){
              var dj = dest[j];
              if(dj.statusName == ai.statusName){
                  dj.item.push(ai);
                  break;
              }
          }
      }
  }
  let str = '';
  dest.map((item) => {
    str = str + `${item.statusName}: ${item.item.length};`
  })
  return (
    <Tooltip mouseEnterDelay={0.5} placement="topLeft" title={`${str}`}>
      <span className="c7n-Issue-summary">
        {str}
      </span>
    </Tooltip>
  );
  
}

const arrToGroupInBug = (arr) => {
  var map = {}, dest = [];
  // 过滤掉缺陷
  let tempArr = [];

  JSON.parse(JSON.stringify(arr)).map((item) => {
    if (item.issueInfosDTO) {
      tempArr.push({
        ...item,
        ...item.issueInfosDTO.statusMapDTO
      })
    } else {
      tempArr.push({
        ...item,
        ...item.statusMapDTO,
      })
    }
  })


  for(var i = 0; i < tempArr.length; i++){
      var ai = tempArr[i];
      if(!map[ai.name]){
          dest.push({
            name: ai.name,
            item: [ai]
          });
          map[ai.name] = ai;
      }else{
          for(var j = 0; j < dest.length; j++){
              var dj = dest[j];
              if(dj.name == ai.name){
                  dj.item.push(ai);
                  break;
              }
          }
      }
  }
  let str = '';
  dest.map((item) => {
    str = str + `${item.name}: ${item.item.length};`
  })
  return (
    <Tooltip mouseEnterDelay={0.5} placement="topLeft" title={`${str}`}>
      <span className="c7n-Issue-summary">
        {str}
      </span>
    </Tooltip>
  )
}

// 根据数组内的对象的某个参数去重
const arrayUnique2 = (arr, name) => {
  var hash = {};
  return arr.reduce(function (item, next) {
    hash[next[name]] ? '' : hash[next[name]] = true && item.push(next);
    return item;
  }, []);
}

// 获取一个问题的所有的bugs并且去重
const getAllBugs = (staticIssues) => {
  let arr = [];
  const getBugs = (issues) => {
    for (let i in issues) {
      if (issues[i].typeCode === 'bug' || issues[i].defectType) {
        arr.push(issues[i]);
      }
      if (issues[i].child) {
        getBugs(issues[i].child);
      }
    }
  }
  getBugs(JSON.parse(JSON.stringify(staticIssues.child)));
  arr = arrayUnique2(arr, 'issueId')
  return arr;
}

const getStatus = (issue, show, classCount, executeList) => {
  let renderDom = null;
  const styleCount = {
    color: 'black', width: 198, 
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
  }
  const isNotFirst = {
    marginLeft: 50
  }
  const styleFirst = {
    marginLeft: 18
  }
  const bugPL = {
    marginLeft: 70
  }
  if (issue.typeCode && issue.typeCode === 'bug') { return null; }
  if (!issue.child || !issue.child.length) {
    return <div style={{ marginLeft: '18px', padding: '4px 0' }}>-</div>;
  }

  let bugList = getAllBugs(_.cloneDeep(issue));

  if (!show) {
    switch (classCount) {
      case 'one': {
        let twoList = flattenItem(_.cloneDeep(issue), 2);
        // 有测试执行就有测试用例
        let threeList = flattenItem(_.cloneDeep(issue), 3).filter((item) => (item.testExecuteTrackDTOS));
        // 有 cycleId 就证明是测试执行
        let fourList = flattenItem(_.cloneDeep(issue), 4, 'execute').filter((item) => (item.cycleId));
        renderDom = (
          <React.Fragment>
            <div style={{ ...styleCount }}>
              <div>总共:{twoList.length}</div>
              <div>{arrToGroup(twoList)}</div>
            </div>
            <div style={{ ...styleCount, ...isNotFirst }}>
              <div>总共:{threeList.length}</div>
              <div>{arrToGroup(threeList)}</div>
            </div>
            <div style={{ ...styleCount, ...isNotFirst }}>
              <div>总共:{fourList.length}</div>
              <div>{arrToGroupExecute(fourList, executeList)}</div>
            </div>
            <div style={{ ...styleCount, ...isNotFirst, ...bugPL }}>
              <div>总共:{bugList.length}</div>
              <div>{arrToGroupInBug(bugList)}</div>
            </div>
          </React.Fragment>
        );
        break;
      };
      case 'tow': {
        // 有测试执行就有测试用例
        let threeList = flattenItem(_.cloneDeep(issue), 2).filter((item) => (item.testExecuteTrackDTOS));
        // 有 cycleId 就证明是测试执行
        let fourList = flattenItem(_.cloneDeep(issue), 3, 'currentExecute').filter((item) => (item.cycleId));
        renderDom = (
          <React.Fragment>
            <div style={{ ...styleCount }}>
              <div>总共:{threeList.length}</div>
              <div>{arrToGroup(threeList)}</div>
            </div>
            <div style={{ ...styleCount, ...isNotFirst }}>
              <div>总共:{fourList.length}</div>
              <div>{arrToGroupExecute(fourList, executeList)}</div>
            </div>
            <div style={{ ...styleCount, ...isNotFirst, ...bugPL }}>
              <div>总共:{bugList.length}</div>
              <div>{arrToGroupInBug(bugList)}</div>
            </div>
          </React.Fragment>
        );
        break;
      };
      case 'three': {
        // 有 cycleId 就证明是测试执行
        let fourList = flattenItem(_.cloneDeep(issue), 2, 'currentExecute').filter((item) => (item.cycleId));

        renderDom = (
          <React.Fragment>
            <div style={{ ...styleCount }}>
              <div>总共:{fourList.length}</div>
              <div>{arrToGroupExecute(fourList, executeList)}</div>
            </div>
            <div style={{ ...styleCount, ...isNotFirst, ...bugPL }}>
              <div>总共:{bugList.length}</div>
              <div>{arrToGroupInBug(bugList)}</div>
            </div>
          </React.Fragment>
        );
        break;
      };
      case 'four': {
        renderDom = (
          <div style={{ ...styleCount }}>
            <div>总共:{bugList.length}</div>
            <div>{arrToGroupInBug(bugList)}</div>
          </div>
        );
        break;
      };
    }

    return <div style={{ display: 'flex', marginTop: '5px', marginLeft: 18 }}>{renderDom}</div>

  } else {
    return null;
  }
}

let exStatus = [];
let onTestStatus = [];

@observer
class Issue extends Component {

  constructor(props) {
    super(props);
    this.state = {
      // 实现原理,利用第二层开始id不可能一样的问题
      dataList: [],
      showList: [],
      execute: [],
      currentIssue: {
        summary: ''
      }
    }
    this.onlyKey = 0;
  }

  componentDidMount = async () => {
    const urlParams = AppState.currentMenuType;
    let dataList = await this.reload();
    let copyData = this.setShow(dataList);
    let tempShowList = [];
    let execute = await axios.post(`/test/v1/projects/${urlParams.id}/status/query`, {
      projectId: urlParams.id,
      statusType: "CYCLE_CASE"
    });

    let testStatus = await axios.get(`/issue/v1/projects/${urlParams.id}/schemes/query_status_by_project_id?apply_type=test&organizationId=${urlParams.organizationId}`);

    exStatus = execute;
    
    onTestStatus = testStatus;

    dataList.map(() => {
      tempShowList.push(false)
    });
    this.setState({
      dataList: copyData,
      showList: tempShowList,
      execute: execute
    })
  }

  reload = async () => {
    const {issueId} = getParams();
    const urlParams = AppState.currentMenuType;
    let issue = await this.getCurrentIssue();
    
    let treeData = await axios.get(`/test/v1/projects/${urlParams.id}/issueTrack/${issueId}?organizationId=${urlParams.organizationId}`);
    let res = await this.handleDataToTree(issue, treeData);
    return res;
  }

  // 判断是点击故事缺陷进来 还是 点击需求跟踪
  getCurrentIssue = async () => {
    const urlParams = AppState.currentMenuType;
    const {issueId} = getParams();
    let issue = await axios.get(`agile/v1/projects/${urlParams.id}/issues/${issueId}?organizationId=${urlParams.organizationId}`);
    this.setState({ currentIssue: issue });
    return issue;
  }

  // 构造我所需要的树形数据
  handleDataToTree = async (issue, treeData) => {
    if (issue.typeCode === 'issue_apply') {
      // 需求跟踪
      return await this.handleApply(treeData);
    } else {
      // 故事或者缺陷
      let res = await this.handleStoryOrBugs(treeData)
      return res;
    }
  }

  handleApply = async (res) => {
    let data = {};
    let followData = {};
    // 如果需求申请存在就存起来
    if (res.issueApplyTrackDTOList && res.issueApplyTrackDTOList.length) {
      // data是顶层的需求跟踪
      data.applyList = res.issueApplyTrackDTOList;
      data.summary = res.issueApplyTrackDTOList[0].summary;
      data.issueId = res.issueApplyTrackDTOList[0].issueId;
      // 需求跟踪是顶层节点,下面就是需求了,直接把需求绑定到顶层的child
      data.child = res.issueTrackDTOList;
    }
    let resd = await this.handleTreeData([data]);
    return resd;
  }

  handleStoryOrBugs = async (res) => {
    // 虚拟顶层节点
    let data = {};
    let followData = {};
    // 如果需求申请存在就存起来
    if (res.issueApplyTrackDTOList && res.issueApplyTrackDTOList.length) {
      // data是顶层的需求跟踪
      data.applyList = res.issueApplyTrackDTOList;
      data.summary = res.issueApplyTrackDTOList[0].summary;
      data.issueId = res.issueApplyTrackDTOList[0].issueId;
      // 需求跟踪是顶层节点,下面就是需求了,直接把需求绑定到顶层的child
      data.child = res.issueTrackDTOList;
    } else {
      // data是顶层的需求跟踪
      data.applyList = [];
      data.summary = '-';
      data.issueId = '-1';
      // 需求跟踪是顶层节点,下面就是需求了,直接把需求绑定到顶层的child
      data.child = res.issueTrackDTOList;
    }
    let resd = await this.handleTreeData([data]);
    return resd;
  }

  // 将 show 设置为 true, 并且加上一个唯一键
  handleTreeData = async (arr) => {
    for (var i in arr) {
    
      if (arr[i].testCaseTrackDTOList) {
        arr[i].child = arr[i].testCaseTrackDTOList ? arr[i].testCaseTrackDTOList : [];
      }

      if (arr[i].testExecuteTrackDTOS) {
        arr[i].child = arr[i].testExecuteTrackDTOS;
      }

      if (arr[i].defects && arr[i].cycleId) {
        arr[i].child = [];
      }
      
      if (arr[i].child) {
        await this.handleTreeData(arr[i].child)
      }
    }
    return arr;
  }


  // 将 show 设置为 true, 并且加上一个唯一键
  setShow(arr) {
    for (var i in arr) {
      arr[i].show = false;
      this.onlyKey = this.onlyKey + 1;
      arr[i].onlyKey = this.onlyKey;
      if (arr[i].defects && arr[i].child) {
        // 将所有的缺陷绑定到 child
        arr[i].child = arr[i].defects.concat(arr[i].child);
      } else if (arr[i].defects) {
        arr[i].child = arr[i].defects;
      }
      if (arr[i].child) {
        this.setShow(arr[i].child)
      }
    }
    return arr;
  }

  render() {
    const allHeight = 25;
    const { dataList, showList } = this.state;
    const urlParams = AppState.currentMenuType;
    return (
      <Page
        className="c7ntest-report-story"
        service={['agile-service.issue.deleteIssue', 'agile-service.issue.listIssueWithSub']}
      >
        <Header
          title="需求跟踪详情"
          backPath={`/agile/issue-follow?type=project&id=${urlParams.id}&name=${urlParams.name}&category=undefined&organizationId=${urlParams.organizationId}`}
        >

        </Header>

        <Content
          title={this.state.currentIssue.typeCode === "issue_apply" ? `需求申请的“${this.state.currentIssue.summary}”的跟踪报表` : `需求的“${this.state.currentIssue.summary}”的跟踪报表`}
        >
          <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
            <div
              className="c7n-content-issue"
              style={{
                display: 'block',
                position: 'relative',
                padding: '0px 18px',
                overflowY: 'scroll',
              }}
            >
              <div className="issue-follow-detial-container">

                <div>
                  <div className="c7n-table-thead" >
                    <div className="c7n-table-thead-tr" style={{marginLeft: '5px'}}>{'需求申请'} </div>
                    <div className="c7n-table-thead-tr" style={{marginLeft: '190px'}}>{'需求'} </div>
                    <div className="c7n-table-thead-tr" style={{marginLeft: '225px'}}>{'测试用例'} </div>
                    <div className="c7n-table-thead-tr" style={{marginLeft: '185px'}}>{'测试执行'} </div>
                    <div className="c7n-table-thead-tr" style={{marginLeft: '215px'}}>{'缺陷'} </div>
                  </div>
                </div>

                {
                  dataList && dataList.map((item, index) => {
                    const { showList } = this.state;
                    return (
                      <div
                        key={index}
                        className={`
                          issue-follow-detial-container-class
                          issue-follow-detial-container-class-first
                          ${item.typeCode === 'bug' ? 'first-only-bug' : ''}
                        `}
                        style={{width: '1300px'}}
                      >
                        <div
                          className="issue-follow-detial-container-summary"
                        >
                          <div className="issue-follow-detial-container-summary-text">
                            {
                              item && item.applyList && item.applyList.map((record, indexd) => {
                                return (
                                  <div>
                                    {getName(record, 'apply')}
                                    {DemandStatusName(record)}
                                  </div>
                                )
                              })
                            }
                            {!item.applyList.length ? '-' : null }
                          </div>
                        </div>
                        <One record={item} show={true} style={{ marginLeft: '50px' }} />
                      </div>
                    )
                  })
                }
              </div>
            </div>
          </div>
        </Content>
      </Page>
    );
  }
}


class One extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showList: []
    }
  }
  componentDidMount() {
    const { record } = this.props;
    let tempShowList = [];
    record.child && record.child.map(() => {
      tempShowList.push(false)
    })
    this.setState({
      showList: tempShowList
    })
  }

  render() {
    const { record, show, style } = this.props;
    const { showList } = this.state;
    return (
      <div style={{ ...style }}>
        {
          show && record.child && record.child.map((item, index) => {
            return (
              <div className="issue-follow-detial-container-class" key={index} >
                <div
                  className={`
                    issue-follow-detial-container-summary 
                    ${item.typeCode === 'bug' ? 'first-only-bug' : ''}
                  `}
                >
                  { 
                    item.child && item.child.length ? (
                      <span
                        onClick={() => {
                          const { showList } = this.state;
                          showList[index] = !showList[index];
                          this.setState({ showList: showList });
                        }}
                      >
                        {getArrow(showList[index], item)}
                      </span>
                    ) : (
                      <span
                        style={{display: 'inline-block', width: '18px'}}
                      />
                    )
                  }

                  <div>
                    <div className="issue-follow-detial-container-summary-text">{getName(item, 'agile')}</div>
                    {getIssueStatus(item)}
                  </div>
                </div>
                <Tow record={item} show={showList.length ? showList[index] : false} style={{ marginLeft: '50px' }} />
              </div>
            )
          })
        }
        {getStatus(record, show, 'one', exStatus)}
      </div>
    )
  }
}

class Tow extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showList: []
    }
  }
  componentDidMount() {
    const { record } = this.props;
    let tempShowList = [];
    record.child && record.child.map(() => {
      tempShowList.push(false)
    })
    this.setState({
      showList: tempShowList
    })
  }

  render() {
    const { record, show, style } = this.props;
    const { showList } = this.state;
    return (
      <div style={{ ...style }}>
        {
          show && record.child && record.child.map((item, index) => {
            return (
              <div className="issue-follow-detial-container-class" key={index}>
                <div
                  className={`
                    issue-follow-detial-container-summary 
                    ${item.typeCode === 'bug' ? 'second-only-bug' : ''}
                  `}
                >
                  { 
                    item.child && item.child.length ? (
                      <span
                        onClick={() => {
                          const { showList } = this.state;
                          showList[index] = !showList[index];
                          this.setState({ showList: showList });
                        }}
                      >
                        {getArrow(showList[index], item)}
                      </span>
                    ) : (
                      <span
                        style={{display: 'inline-block', width: '18px'}}
                      />
                    )
                  }
                  <div>
                    <div className="issue-follow-detial-container-summary-text">{getName(item, 'test')}</div>
                    {getIssueStatus(item)}
                  </div>
                </div>
                <Three record={item} show={showList.length ? showList[index] : false} style={{ marginLeft: '50px' }} />
              </div>
            )
          })
        }
        {getStatus(record, show, 'tow', exStatus)}
      </div>
    )
  }
}

class Three extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showList: []
    }
  }
  componentDidMount() {
    const { record } = this.props;
    let tempShowList = [];
    record.child && record.child.map(() => {
      tempShowList.push(false)
    })
    this.setState({
      showList: tempShowList
    })
  }

  render() {
    const { record, show, style } = this.props;
    const { showList } = this.state;
    return (
      <div style={{ ...style }}>
        {
          show && record.child && record.child.map((item, index) => {
            const status = _.find(exStatus, { statusId: item.executionStatus })
            return (
              <div
                className={`
                issue-follow-detial-container-summary 
                ${item.typeCode === 'bug' ? 'three-only-bug' : ''}
              `}
                key={index}>
                <div
                  className="issue-follow-detial-container-summary"
                >
                  { 
                    item.child && item.child.length ? (
                      <span
                        onClick={() => {
                          const { showList } = this.state;
                          showList[index] = !showList[index];
                          this.setState({ showList: showList });
                        }}
                      >
                        {getArrow(showList[index], item)}
                      </span>
                    ) : (
                      <span
                        style={{display: 'inline-block', width: '18px'}}
                      />
                    )
                  }
                  <div>
                    <div className="issue-follow-detial-container-summary-text">{getName(item, 'execute')}</div>
                    {status ? getExecuteStatus(status) : getIssueStatus(item)}
                  </div>
                </div>
                <Four record={item} show={showList.length ? showList[index] : false} style={{ marginLeft: '50px' }} />
              </div>
            )
          })
        }
        {getStatus(record, show, 'three', exStatus)}
      </div>
    )
  }
}

class Four extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showList: []
    }
  }
  componentDidMount() {
    const { record } = this.props;
    let tempShowList = [];
    record.child && record.child.map(() => {
      tempShowList.push(false)
    })
    this.setState({
      showList: tempShowList
    })
  }

  render() {
    const { record, show, style } = this.props;
    const { showList } = this.state;
    return (
      <div style={{ ...style }}>
        {
          show && record.child && record.child.map((item, index) => {
            return (
              <div
                className="issue-follow-detial-container-class"
                key={index}
                style={{ marginLeft: 40 }}
              >
                <div className="issue-follow-detial-container-summary">
                  <div>
                    <div className="issue-follow-detial-container-summary-text">{getName(item, 'agile')}</div>
                    {getIssueStatus(item)}
                  </div>
                </div>
              </div>
            )
          })
        }
        {getStatus(record, show, 'four', exStatus)}
      </div>
    )
  }
}

export default Form.create()(Issue);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值