Forráskód Böngészése

团队工作台,任务,需求统计

wangziqian 4 éve
szülő
commit
90297da7fe

+ 50 - 0
src/api/workSchedule.js

@@ -158,3 +158,53 @@ export function taskTeamList(data) {
     data
   })
 }
+// 添加统计后接口----------------------T------------------------------------------
+
+// 需求头部统计数据,数据里返idList(团队)
+export function getTeamRequireSummary(data) {
+  return request({
+    url: TeamManagement + `/workbench/team/getRequireSummary`,
+    method: 'post',
+    data
+  })
+}
+// 需求按状态统计数据,数据里返idList(团队)
+export function getTeamRequireDisData(data) {
+  return request({
+    url: TeamManagement + `/workbench/team/getRequireDisDataByStatus`,
+    method: 'post',
+    data
+  })
+}
+// 任务头部统计数据,数据里返idList(团队)
+export function getTeamTaskSummary(data) {
+  return request({
+    url: TeamManagement + `/workbench/team/getTaskSummary`,
+    method: 'post',
+    data
+  })
+}
+// 任务按状态统计数据,数据里返idList(团队)
+export function getTeamTaskDisData(data) {
+  return request({
+    url: TeamManagement + `/workbench/team/getTaskDisDataByStatus`,
+    method: 'post',
+    data
+  })
+}
+// 缺陷头部统计数据,数据里返(团队)
+export function getTeamBugSummary(data) {
+  return request({
+    url: TeamManagement + `/workbench/team/getBugSummary`,
+    method: 'post',
+    data
+  })
+}
+// 缺陷按状态统计数据,数据里返idList(团队)
+export function getTeamBugDisDataBy(data) {
+  return request({
+    url: TeamManagement + `/workbench/team/getBugDisDataByStatus`,
+    method: 'post',
+    data
+  })
+}

+ 78 - 26
src/views/workbench/components/statisticsSection.vue

@@ -5,21 +5,16 @@
         <div class="statistics-data">
           <h2>{{ title }}统计</h2>
           <div class="data-main">
-            <div class="data-item">
-              <label>交付已延期</label>
-              <div class="number">1</div>
+            <div v-for="(item,index) in statisticsList" :key="title+'-statistics-'+index" class="data-item" @click="changeData(item.idList,item.label)">
+              <label>{{ item.label }}</label>
+              <div class="number">{{ item.total }}</div>
             </div>
-            <div class="data-item" />
-            <div class="data-item" />
-            <div class="data-item" />
-            <div class="data-item" />
-            <div class="data-item" />
           </div>
         </div>
         <div v-if="title !=='缺陷'" class="statistics-chart">
           <h2>未上线{{ title }}状态分布</h2>
           <div class="chart-contain">
-            <normal-echart v-if="echartsOption" :chart-id="type+title" :option="echartsOption" />
+            <normal-echart v-if="echartsOption" :chart-id="type+title" :option="echartsOption" @onClick="chartChange" />
           </div>
         </div>
         <div v-if="title ==='缺陷'" class="statistics-chart">
@@ -29,10 +24,10 @@
           </div>
           <div class="two-chart-contain">
             <div class="chart-contain">
-              <normal-echart v-if="echartsOption" :chart-id="type+title+'1'" :option="echartsOption" />
+              <normal-echart v-if="echartsOption" :chart-id="type+title+'1'" :option="echartsOption" @onClick="chartChange" />
             </div>
             <div class="chart-contain">
-              <normal-echart v-if="echartsOption" :chart-id="type+title+'2'" :option="echartsOption2" />
+              <normal-echart v-if="echartsOption2" :chart-id="type+title+'2'" :option="echartsOption2" @onClick="chartChange" />
             </div>
           </div>
         </div>
@@ -65,7 +60,7 @@ export default {
     },
     type: { // 个人还是团队
       type: String,
-      default: 'person',
+      default: 'team',
       required: false
     },
     title: {
@@ -82,6 +77,7 @@ export default {
   data() {
     return {
       show: true,
+      statisticsList: [],
       echartsOption: null,
       echartsOption2: null,
       tips: {
@@ -105,33 +101,86 @@ export default {
   watch: {
     searchForm: {
       handler(newV) {
-
+        this.initData()
+      },
+      deep: true,
+      immediate: true
+    },
+    title: {
+      handler(newV) {
+        this.initData()
       },
-      deep: true
+      immediate: true
     }
   },
   methods: {
-    initData() {
+    initData() { // 初始化
       if (this.requestObj) {
         const { requestData, requestChart } = this.requestObj
         this.getData(requestData)
-        this.getChart(requestChart)
+        if (this.title === '缺陷') {
+          this.getChart(requestChart, '3')
+          this.getChart(requestChart, '5')
+        } else {
+          this.getChart(requestChart)
+        }
       }
     },
-    async getData(requestUrl) {
-      const res = await requestUrl()
+    async getData(requestUrl) { // 获取顶部数据
+      const res = await requestUrl({ teamSearchInfo: this.searchForm })
+      if (res.code === 200) {
+        this.statisticsList = res.data || []
+        console.log(res.data)
+        this.changeData(this.statisticsList[0].idList, this.statisticsList[0].label)
+      }
     },
-    async getChart(requestUrl) {
-      const res = await requestUrl()
+    async getChart(requestUrl, type) { // 获取图表数据
+      if (type) {
+        const res = await requestUrl({ teamSearchInfo: this.searchForm, type: type })
+        if (type === '3') {
+          this.echartsOption = this.setChart(res.data)
+        } else if (type === '5') {
+          this.echartsOption2 = this.setChart(res.data)
+        }
+      } else {
+        const res = await requestUrl({ teamSearchInfo: this.searchForm })
+        this.echartsOption = this.setChart(res.data)
+      }
     },
-    changeData() {
-      this.$emit('change', this.title)
+    setChart(chartData) { // 设置图表options
+      const childArr = chartData.xaxis.map((item, index) => {
+        return {
+          value: chartData.yaxis[0] && chartData.yaxis[0].data[index] || null,
+          idList: chartData.yaxis[0] && chartData.yaxis[0].idList[index] || []
+        }
+      })
+      const option = {
+        color: ['#3AA1FF'],
+        tooltip: { trigger: 'axis', axisPointer: { type: 'line' }}, // 默认为直线,可选为:'line' | 'shadow'
+        grid: { left: '0', right: '0', top: '10%', bottom: '0', containLabel: true },
+        xAxis: [{ type: 'category', data: chartData.xaxis, axisLabel: { interval: 0, rotate: 15 }, axisTick: { alignWithLabel: true }}],
+        yAxis: [{ type: 'value', axisLine: { show: false }, splitLine: { lineStyle: { type: 'dashed' }}}],
+        series: [{
+          name: '数量', type: 'bar', barWidth: '20px', data: childArr,
+          itemStyle: { normal: { label: { show: true, formatter: '{c}', position: 'top' }}}
+        }]
+      }
+      return option
+    },
+    chartChange(params) { // 点击图表产生触发列表更改
+      this.changeData(params.data.idList, params.name)
+    },
+    changeData(idList, name) { // 点击顶部数据触发列表更改
+      this.$emit('change', this.title, idList, name)
     }
   }
 }
 </script>
 
 <style scoped lang="scss">
+.color-red {
+  color:#E02020;
+}
 .drawer-statistics {
   position: relative;
   width: 100%;
@@ -155,7 +204,7 @@ export default {
   height: 474px;
   padding: 27px 35px;
   display: grid;
-  grid-template-columns: repeat(2,50%);
+  grid-template-columns: 40% 60%;
   h2 {
     color: #333333;
     font-size: 16px;
@@ -173,6 +222,7 @@ export default {
     grid-row-gap: 20px;
   }
   .data-item {
+    cursor:pointer;
     box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.2);
     border-radius: 5px;
     display: grid;
@@ -194,17 +244,19 @@ export default {
   .two-title {
     width: 100%;
     display: grid;
-    grid-template-columns: repeat(2,50%);
+    grid-template-columns: repeat(2,47.5%);
+    grid-column-gap: 5%;
   }
   .two-chart-contain {
     width: 100%;
     height: 100%;
     display: grid;
-    grid-template-columns: repeat(2,50%);
+    grid-template-columns: repeat(2,47.5%);
+    grid-column-gap: 5%;
   }
   .chart-contain {
     width: 100%;
-    height: 350px;
+    height: 380px;
   }
 }
 .drawer-statistics:after {

+ 4 - 2
src/views/workbench/mixins/websocket.js

@@ -21,7 +21,7 @@ export default {
   },
   methods: {
     initWebSocket() { // 初始化weosocket
-      const wsUri = 'ws://123.207.136.134:9010/ajaxchattest'
+      const wsUri = 'ws://172.23.141.110:8980/self/remind?ename=' + localStorage.getItem('username')
       this.websock = new WebSocket(wsUri)
       this.websock.onmessage = this.websocketonmessage
       this.websock.onopen = this.websocketonopen
@@ -29,6 +29,7 @@ export default {
       this.websock.onclose = this.websocketclose
     },
     websocketonopen() { // 连接建立之后执行send方法发送数据
+
     },
     websocketonerror() { // 连接建立失败重连
       this.initWebSocket()
@@ -37,7 +38,8 @@ export default {
       this.websock.send(Data)
     },
     websocketonmessage(e) { // 数据接收
-      this.responesData = e.data
+      this.responesData = JSON.parse(e.data)
+      // console.log(this.responesData)
     },
     websocketclose(e) { // 关闭
       this.websock.close()

+ 2 - 0
src/views/workbench/person/index.vue

@@ -193,6 +193,7 @@ import projectList from '@/views/workbench/team/components/projectList'
 import needsList from '@/views/workbench/team/components/needsList'
 import taskList from '@/views/workbench/team/components/taskList'
 import bugTableList from '@/views/workbench/bugTableList.vue'
+import websocket from '@/views/workbench/mixins/websocket'
 
 export default {
   components: {
@@ -212,6 +213,7 @@ export default {
       controlDe: () => this.controlDe
     }
   },
+  mixins: [websocket],
   data() {
     return {
       activeName: '1', // 顶部导航栏

+ 29 - 59
src/views/workbench/team/components/needsList.vue

@@ -1,10 +1,7 @@
 <template>
   <div>
-    <div class="search-control">
-      <span :class="{'color-blue': status===null}" @click="setStatus(null)">全部</span>
-      <span :class="{'color-blue': status===1}" @click="setStatus(1)">进行中的需求</span>
-      <span :class="{'color-blue': status===0}" @click="setStatus(0)">未开始的需求</span>
-      <span :class="{'color-blue': status===2}" @click="setStatus(2)">已上线的需求</span>
+    <div class="table-top">
+      <label>{{ name }}的需求</label>
       <span class="new-tab-open">
         <el-switch
           v-model="newTabOpen"
@@ -91,7 +88,7 @@
     </el-table>
     <div align="right">
       <el-pagination
-        :page-sizes="[15, 30, 45, total]"
+        :page-sizes="[10, 20, 30, total]"
         :current-page.sync="pages.curIndex"
         :page-size="pages.pageSize"
         background
@@ -104,28 +101,19 @@
   </div>
 </template>
 <script>
-import {
-  requirementSelfList,
-  requirementTeamList
-} from '@/api/workSchedule'
-import { configShowRequireStatusEnum, updateRequirementStatus } from '@/api/requirement'
+import { configShowRequireStatusEnum, updateRequirementStatus, getRequirement } from '@/api/requirement'
 import extraUrgent from '@/assets/extraUrgent.png'
 export default {
   props: {
-    searchForm: {
-      type: Object,
-      default: () => {
-        return {
-          teamId: null,
-          bizId: null
-        }
-      },
+    idList: {
+      type: Array,
+      default: () => [],
       required: true
     },
-    type: {
+    name: {
       type: String,
-      default: 'person',
-      required: true
+      default: '',
+      required: false
     }
   },
   data() {
@@ -135,29 +123,26 @@ export default {
       needsDataList: [], // 需求列表
       allStatus: [], // 状态列表
       pages: {
-        pageSize: 15,
+        pageSize: 10,
         curIndex: 1
       },
-      total: 0,
-      status: null // 列表状态
+      total: 0
     }
   },
   watch: {
-    searchForm: {
+    idList: {
       handler(newV) {
         this.getNeedsList()
       },
       deep: true
     },
-    type: {
-      handler(newV) {
-        this.getNeedsList()
-      }
+    name: {
+      handler(newV) {},
+      immediate: true
     }
   },
   created() {
     this.getTaskStatus()
-    this.getNeedsList()
   },
   methods: {
     setStatus(val) {
@@ -179,26 +164,16 @@ export default {
         this.allStatus = []
         this.allStatus = res1.data.requirementStatus
       }
-      // const res = await showRequirementEnum()
-      // if (res.code === 200) {
-      //   this.allStatus = res.data.requirementStatus
-      // }
     },
     async getNeedsList() { // 获取需求列表
-      const params = {
-        teamSearchInfo: this.searchForm,
-        status: this.status,
-        pageInfoDO: this.pages
-      }
-      let res = null
-      if (this.type === 'person') {
-        res = await requirementSelfList(params)
-      } else if (this.type === 'team') {
-        res = await requirementTeamList(params)
+      if (this.idList.length === 0) {
+        this.needsDataList = []
+        return
       }
+      const res = await getRequirement({ ids: this.idList, ...this.pages })
       if (res && res.code === 200) {
-        this.needsDataList = res.data
-        this.total = res.total
+        this.needsDataList = res.data.list
+        this.total = res.data.total
       }
     },
     async changeStatus(e) { // 状态改变
@@ -240,9 +215,13 @@ export default {
 >>>.el-row .el-col {
   margin: 10px 0;
 }
-.new-tab-open {
-  position: absolute;
-  right: 0px;
+.table-top {
+  color: #333333;
+  font-size: 16px;
+  width: 100%;
+  padding: 10px 15px 0 15px;
+  display: flex;
+  justify-content: space-between;
 }
 .color-blue {
 	color:#409EFF;
@@ -308,15 +287,6 @@ export default {
   background: rgba(245,108,108,0.17);
   color: rgba(245,108,108,1);
 }
-.search-control {
-	padding: 30px 17px 0;
-	color: #333B4A;
-	font-size: 14px;
-	span {
-		margin-right: 35px;
-		cursor: pointer;
-	}
-}
 .div_priority {
   text-align: center;
   color: #ffffff;

+ 24 - 46
src/views/workbench/team/components/taskList.vue

@@ -1,10 +1,7 @@
 <template>
   <div>
-    <div class="search-control">
-      <span :class="{'color-blue': status===null}" @click="setStatus(null)">全部</span>
-      <span :class="{'color-blue': status===1}" @click="setStatus(1)">进行中的任务</span>
-      <span :class="{'color-blue': status===0}" @click="setStatus(0)">未开始的任务</span>
-      <span :class="{'color-blue': status===2}" @click="setStatus(2)">已上线的任务</span>
+    <div class="table-top">
+      <label>{{ name }}的任务</label>
       <span class="new-tab-open">
         <el-switch
           v-model="newTabOpen"
@@ -139,9 +136,8 @@ import '@/styles/PublicStyle/index.scss'
 import TestReport from '@/views/reportManagement/components/TestingReport' // 提测
 import DailyReport from '@/views/reportManagement/components/DailyReport' // 日报
 import ReleaseReport from '@/views/reportManagement/components/ReleaseReport' // 准出
-import { taskSelfList, taskTeamList } from '@/api/workSchedule'
 import { taskUpdate } from '@/api/projectViewDetails'
-import { configShowTaskEnum, configShowTaskStatusEnum } from '@/api/taskIndex'
+import { configShowTaskEnum, configShowTaskStatusEnum, taskList } from '@/api/taskIndex'
 import modifySchedule from '@/views/projectManage/projectList/components/modifySchedule'
 import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
 import { dailyReportCheckStatus, reportreleaseCheckStatus, reportdelivertestCheckStatus } from '@/api/reportTemplate'
@@ -154,20 +150,15 @@ export default {
     modifySchedule
   },
   props: {
-    searchForm: {
-      type: Object,
-      default: () => {
-        return {
-          teamId: null,
-          bizId: null
-        }
-      },
+    idList: {
+      type: Array,
+      default: () => [],
       required: true
     },
-    type: {
+    name: {
       type: String,
-      default: 'person',
-      required: true
+      default: '',
+      required: false
     }
   },
   data() {
@@ -201,21 +192,19 @@ export default {
     }
   },
   watch: {
-    searchForm: {
+    idList: {
       handler(newV) {
         this.get_allTask()
       },
       deep: true
     },
-    type: {
-      handler(newV) {
-        this.get_allTask()
-      }
+    name: {
+      handler(newV) {},
+      immediate: true
     }
   },
   created() {
     this.getTaskStatus()
-    this.get_allTask()
   },
   methods: {
     setStatus(val) {
@@ -232,17 +221,11 @@ export default {
       this.get_allTask()
     },
     async get_allTask() { // 获取全部任务
-      const params = {
-        teamSearchInfo: this.searchForm,
-        status: this.status,
-        pageInfoDO: this.pages
-      }
-      let res = null
-      if (this.type === 'person') {
-        res = await taskSelfList(params)
-      } else if (this.type === 'team') {
-        res = await taskTeamList(params)
+      if (this.idList.length === 0) {
+        this.all_task = []
+        return
       }
+      const res = await taskList({ ids: this.idList, ...this.pages })
       if (res && res.code === 200) {
         this.all_task = res.data
         this.total = res.total
@@ -423,9 +406,13 @@ export default {
 >>>.el-row .el-col {
   margin: 10px 0;
 }
-.new-tab-open {
-  position: absolute;
-  right: 0px;
+.table-top {
+  color: #333333;
+  font-size: 16px;
+  width: 100%;
+  padding: 10px 15px 0 15px;
+  display: flex;
+  justify-content: space-between;
 }
 .task-main {
   display: flex;
@@ -476,15 +463,6 @@ export default {
 .status2 {
   @include setStatus(#7ED321)
 }
-.search-control {
-	padding: 30px 17px 0;
-	color: #333B4A;
-	font-size: 14px;
-	span {
-		margin-right: 35px;
-		cursor: pointer;
-	}
-}
 .expand i {
   border:1px solid #DCDFE6;
 }

+ 79 - 14
src/views/workbench/team/index.vue

@@ -33,13 +33,13 @@
           <el-tab-pane label="团队日程" name="1" />
           <el-tab-pane label="项目" name="2" />
           <el-tab-pane name="3">
-            <span slot="label">需求<div class="tips" /> </span>
+            <span slot="label">需求<div v-show="tabTips.require" class="tips" /> </span>
           </el-tab-pane>
           <el-tab-pane name="4">
-            <span slot="label">任务<div class="tips" /> </span>
+            <span slot="label">任务<div v-show="tabTips.task" class="tips" /> </span>
           </el-tab-pane>
           <el-tab-pane name="5">
-            <span slot="label"><span style="margin-right: 5px">缺陷</span> <div class="tips-last" /> </span>
+            <span slot="label"><span style="margin-right: 5px">缺陷</span> <div v-show="tabTips.bug" class="tips-last" /> </span>
           </el-tab-pane>
         </el-tabs>
       </div>
@@ -93,17 +93,46 @@
     </el-container>
     <el-container v-if="activeName === '3'">
       <section class="main-section">
-        <statistics-section :search-form="searchForm" @change="changeData" />
-        <needs-list ref="needs-list" :search-form="searchForm" type="team" />
+        <statistics-section
+          :search-form="searchForm"
+          type="team"
+          title="需求"
+          :request-obj="{
+            requestData:getTeamRequireSummary,
+            requestChart:getTeamRequireDisData
+          }"
+          @change="changeData"
+        />
+        <needs-list :name="listName.requireList" :id-list="idList.requireList" />
       </section>
     </el-container>
     <el-container v-if="activeName === '4'">
       <section class="main-section">
-        <task-list :search-form="searchForm" type="team" />
+        <statistics-section
+          :search-form="searchForm"
+          type="team"
+          title="任务"
+          :request-obj="{
+            requestData:getTeamTaskSummary,
+            requestChart:getTeamTaskDisData
+          }"
+          @change="changeData"
+        />
+        <task-list :name="listName.taskList" :id-list="idList.taskList" />
       </section>
     </el-container>
-    <el-container v-show="activeName === '5'">
+    <el-container v-if="activeName === '5'">
       <section class="main-section">
+        <statistics-section
+          :search-form="searchForm"
+          type="team"
+          title="缺陷"
+          :request-obj="{
+            requestData:getTeamBugSummary,
+            requestChart:getTeamBugDisDataBy
+          }"
+          @change="changeData"
+        />
         <bugTableList ref="bugTableDialog" :name="'团队'" :team-id="searchForm.teamId" :biz-id="searchForm.bizId" />
       </section>
     </el-container>
@@ -138,7 +167,18 @@
 <script>
 import moment from 'moment'
 import { settingGetBizList } from '@/api/defectManage'
-import { queryTeamInfoList, queryTeamWorkListByTime, deleteSelfSchedule, queryTeamMember } from '@/api/workSchedule'
+import {
+  queryTeamInfoList,
+  queryTeamWorkListByTime,
+  deleteSelfSchedule,
+  queryTeamMember,
+  getTeamRequireSummary,
+  getTeamRequireDisData,
+  getTeamTaskSummary,
+  getTeamTaskDisData,
+  getTeamBugSummary,
+  getTeamBugDisDataBy
+} from '@/api/workSchedule'
 import { scheduleDelete } from '@/api/projectViewDetails'
 import modifySchedule from '@/views/projectManage/projectList/components/modifySchedule'
 import ganntViews from '@/views/workbench/team/components/ganntViews'
@@ -150,7 +190,6 @@ import needsList from '@/views/workbench/team/components/needsList'
 import taskList from '@/views/workbench/team/components/taskList'
 import bugTableList from '@/views/workbench/bugTableList.vue'
 import statisticsSection from '@/views/workbench/components/statisticsSection'
-import websocket from '@/views/workbench/mixins/websocket'
 
 export default {
   components: {
@@ -165,7 +204,6 @@ export default {
     taskList,
     statisticsSection
   },
-  mixins: [websocket],
   data() {
     return {
       activeName: '1', // 顶部导航栏
@@ -219,7 +257,28 @@ export default {
         'rgba(86,68,93,0.2)', 'rgba(111,33,8,0.2)', 'rgba(192,53,70,0.2)', 'rgba(92,25,107,0.2)', 'rgba(73,10,61,0.2)',
         'rgba(189,21,80,0.2)', 'rgba( 31,78,95,0.2)', 'rgba(241,0,229,0.2)', 'rgba(114,0,218,0.2)', 'rgba(70,14,68,0.2)'
       ],
-      mapMemberColor: new Map()// 人员对应颜色表
+      mapMemberColor: new Map(), // 人员对应颜色表
+      tabTips: { // 顶部tab红点提示
+        require: true,
+        task: true,
+        bug: true
+      },
+      idList: {// 所选项的idList
+        requireList: [],
+        taskList: [],
+        bugList: []
+      },
+      listName: {
+        requireList: '',
+        taskList: '',
+        bugList: ''
+      },
+      getTeamRequireSummary: getTeamRequireSummary, // 需求头部统计数据接口
+      getTeamRequireDisData: getTeamRequireDisData, // 需求按状态统计数据接口
+      getTeamTaskSummary: getTeamTaskSummary, // 任务头部统计数据接口
+      getTeamTaskDisData: getTeamTaskDisData, // 任务按状态统计数据接口
+      getTeamBugSummary: getTeamBugSummary, // 缺陷头部统计数据接口
+      getTeamBugDisDataBy: getTeamBugDisDataBy// 缺陷按状态统计数据接口
     }
   },
   watch: {
@@ -243,7 +302,7 @@ export default {
   },
   methods: {
     handleClick() {
-      if (this.activeName === '5') {
+      if (this.activeName === '5' && this.$refs.bugTableDialog) {
         this.$refs.bugTableDialog.bugGetTableList('团队', { teamId: this.searchForm.teamId, bizId: this.searchForm.bizId })
       }
     },
@@ -427,9 +486,15 @@ export default {
         })
       }
     },
-    changeData(e) { // 数据变更
+    changeData(e, idList, name) { // 数据变更
       if (e === '需求') {
-        this.$refs['needs-list'].getNeedsList()
+        this.idList.requireList = idList
+        this.listName.requireList = name
+      } else if (e === '任务') {
+        this.idList.taskList = idList
+        this.listName.taskList = name
+      } else if (e === '缺陷') {
+        this.handleClick()
       }
     }
   }