wangziqian преди 5 години
родител
ревизия
3f1a329b08

+ 8 - 0
src/api/statisticsApi/taskStatistics.js

@@ -81,6 +81,14 @@ export function getTaskUnlockData(data) {
     data
   })
 }
+// 报告统计
+export function getReportSummary(data) {
+  return request({
+    url: TeamManagement + '/task/getReportSummary',
+    method: 'post',
+    data
+  })
+}
 // 缺陷统计
 export function getBugStatisticData(data) {
   return request({

+ 124 - 0
src/views/quality/components/belongRequirementChart.vue

@@ -0,0 +1,124 @@
+<template>
+  <section>
+    <div class="control">
+      <el-row type="flex" align="middle">
+        <el-col :span="4" :offset="20" class="col-flex-end">
+          <div class="bar-pie" :class="[barOrPie==='bar'?'active':'']" @click="changeBarOrPie('bar')">柱状图</div>
+          <div class="bar-pie" :class="[barOrPie==='pie'?'active':'']" @click="changeBarOrPie('pie')">饼图</div>
+        </el-col>
+      </el-row>
+    </div>
+    <div class="chart-contain">
+      <normal-echart v-if="echartsOption" :chart-id="id" :option="echartsOption" />
+    </div>
+  </section>
+</template>
+<script>
+import normalEchart from '@/components/chart/normalEchart'
+export default {
+  components: { normalEchart },
+  props: {
+    id: {
+      type: String,
+      default: 'belong-requirement-chart',
+      required: false
+    },
+    chartData: {
+      type: Object,
+      default: () => null,
+      required: false
+    },
+    activeTab: {
+      type: String,
+      default: '1',
+      required: false
+    }
+  },
+  data() {
+    return {
+      echartsOption: null,
+      barOrPie: 'bar' // 柱状图or饼图
+    }
+  },
+  watch: {
+    chartData: {
+      handler(newV) {
+        this.changeBarOrPie(this.barOrPie)
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  mounted() {
+    this.changeBarOrPie(this.barOrPie)
+  },
+  methods: {
+    statusChange(e) {
+      this.$emit('change')
+    },
+    changeBarOrPie(type) { // 饼图柱状图切换
+      this.barOrPie = type
+      if (!this.chartData) return
+      if (type === 'bar') {
+        this.echartsOption = {
+          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: this.chartData.xaxis, axisLabel: { interval: 0, rotate: 0 }, axisTick: { alignWithLabel: true }}],
+          yAxis: [{ type: 'value', axisLine: { show: false }, splitLine: { lineStyle: { type: 'dashed' }}}],
+          series: [{
+            name: '数量', type: 'bar', barWidth: '20px', data: this.chartData.yaxis[0] && this.chartData.yaxis[0].data || [],
+            itemStyle: { normal: { label: { show: true, formatter: '{c}', position: 'top' }}}
+          }]
+        }
+      } else {
+        const newArr = this.chartData.xaxis.map((item, index) => {
+          return {
+            value: this.chartData.yaxis[0] && this.chartData.yaxis[0].data[index] || null,
+            name: item
+          }
+        })
+        this.echartsOption = {
+          color: ['#1890FF', '#13C2C2', '#2FC25B', '#FACC14', '#F04864', '#8543E0'],
+          grid: { left: '0', right: '0', top: '5%', bottom: '0' },
+          tooltip: { trigger: 'item', formatter: '{a} <br/>{b} : {c} ({d}%)' },
+          legend: { orient: 'vertical', left: 'right', top: 'center', data: this.chartData.xaxis },
+          series: [{
+            name: '数量', type: 'pie', radius: ['45%', '60%'], right: '30%', label: { position: 'outer', alignTo: 'edge', margin: 20 }, data: newArr,
+            itemStyle: { normal: { label: { show: true, formatter: '{b} : {c} ({d}%)' }, labelLine: { show: true }}}
+          }]
+        }
+      }
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.chart-contain {
+  position: relative;
+  height: 400px;
+  width: 84%;
+  margin: 20px auto;
+}
+.control{
+  width: 84%;
+  margin: auto;
+  margin-top: 20px;
+}
+.bar-pie {
+  font-size: 14px;
+  width: 40%;
+  display: inline-block;
+  padding: 6px 10px;
+  margin-left: 5%;
+  color: #50A6FF;
+  border: 1px solid #50A6FF;
+  border-radius: 4px;
+  text-align: center;
+  cursor: pointer;
+}
+.active {
+  color: #ffffff;
+  background: #50A6FF;
+}
+</style>

+ 10 - 4
src/views/quality/components/cycleStatistic.vue

@@ -5,10 +5,11 @@
         <div v-for="(item, index) in chartData" :key="'time'+index" class="repair-item" :class="[Number(item.relativeRatio)<0?'repair-slow':'repair-rise']">
           <div class="repair-item-point" :class="['point'+index]" />
           <span>{{ item.label }}</span>
-          <div class="repair-time">{{ item.countStr }}天</div>
-          <div v-show="Number(item.chainRatio)>=0" class="repair-up">环比:<i class="el-icon-caret-top" /><span>{{ item.chainRatio }}%</span></div>
-          <div v-show="Number(item.chainRatio)<0" class="repair-down">环比:<i class="el-icon-caret-bottom" /><span>{{ item.chainRatio.substring(1,item.chainRatio.length) }}%</span></div>
-          <div v-show="item.chainRatio === '--'" class="repair-up">环比:<span>{{ item.chainRatio }}%</span></div>
+          <div v-if="item.countStr" class="repair-time">{{ item.countStr }}天</div>
+          <div v-if="item.total || item.total === 0" class="repair-time">{{ item.total }}个</div>
+          <div v-show="Number(item[childData])>=0" class="repair-up">环比:<i class="el-icon-caret-top" /><span>{{ item[childData] }}%</span></div>
+          <div v-show="Number(item[childData])<0" class="repair-down">环比:<i class="el-icon-caret-bottom" /><span>{{ item[childData].substring(1,item[childData].length) }}%</span></div>
+          <div v-show="item[childData] === '--'" class="repair-up">环比:<span>{{ item[childData] }}%</span></div>
         </div>
       </div>
     </el-row>
@@ -21,6 +22,11 @@ export default {
       type: Array,
       default: () => [],
       required: false
+    },
+    childData: {
+      type: String,
+      default: 'chainRatio',
+      required: false
     }
   },
   watch: {

+ 0 - 8
src/views/quality/components/updateTable.vue

@@ -1,8 +0,0 @@
-<template>
-  <section />
-</template>
-<script>
-export default {
-
-}
-</script>

+ 7 - 3
src/views/quality/requireStatistics.vue

@@ -122,7 +122,7 @@
         <h3>周期统计<span>(根据排期计算)</span></h3>
         <div class="chart-item-tip">
           <i class="el-icon-warning-outline" />
-          <span>仅统计状态已变更“已排期”且排期不为空的任务</span>
+          <span>仅统计状态已变更“已排期”且排期不为空的需求</span>
         </div>
         <cycle-statistic :chart-data="cycleData" />
       </div>
@@ -130,7 +130,7 @@
         <h3>研发交付周期分布图<span>(根据排期计算)</span></h3>
         <div class="chart-item-tip">
           <i class="el-icon-warning-outline" />
-          <span>仅统计状态已变更“已排期”且排期不为空的任务;横坐标表示任务交付日期,纵坐标代表研发交付周期(研发、联调、上线类型排期的总周期)</span>
+          <span>仅统计状态已变更“已排期”且排期不为空的需求;横坐标表示需求交付日期,纵坐标代表研发交付周期(研发、联调、上线类型排期的总周期)</span>
         </div>
         <development-cycle :chart-data="developmentCycleData" />
       </div>
@@ -373,7 +373,11 @@ export default {
         type: Number(this.activeTab)
       }
       const res = await getRequireRdDeliveryPeriodicData(params)
-      if (res.code === 200) this.developmentCycleData = res.data
+      if (res.code === 200) {
+        res.data.length > 0
+          ? this.developmentCycleData = res.data
+          : this.developmentCycleData = [moment().format('YYYY-MM-DD'), '0']
+      }
     },
     async getDistributeData() { // 获取需求分布图
       const params = {

+ 37 - 1
src/views/quality/taskStatistics.vue

@@ -106,6 +106,10 @@
         <h3>新增趋势图</h3>
         <tendency-chart :chart-data="tendencyData" />
       </div>
+      <div class="chart-item">
+        <h3>所属需求方向分布图</h3>
+        <belong-requirement-chart :chart-data="belongRequirementData" />
+      </div>
       <div class="chart-item">
         <h3>周期统计<span>(根据排期计算)</span></h3>
         <div class="chart-item-tip">
@@ -144,6 +148,10 @@
         <h3>排期发生变更的任务({{ changeTotal }})</h3>
         <change-require-chart :chart-data="changeTaskData" />
       </div>
+      <div class="chart-item">
+        <h3>报告统计</h3>
+        <cycle-statistic :chart-data="reportSummaryData" child-data="relativeRatio" />
+      </div>
       <div class="chart-item">
         <h3>缺陷统计</h3>
         <bug-list :chart-data="bugListData" />
@@ -160,16 +168,19 @@ import {
   getSummary,
   getCumulativeFlowDiagram,
   getTaskCountTrend,
+  getRequirementOrientationDistributeData,
   getTaskPeriodicData,
   getTaskRdDeliveryPeriodicData,
   getDistributeData,
   getStatusStayData,
   getModuleDistributeData,
   getTaskUnlockData,
+  getReportSummary,
   getBugStatisticData
 } from '@/api/statisticsApi/taskStatistics'
 import statusChart from './components/statusChart'
 import tendencyChart from './components/tendencyChart'
+import belongRequirementChart from './components/belongRequirementChart'
 import cycleStatistic from './components/cycleStatistic'
 import developmentCycle from './components/developmentCycle'
 import distributionChart from './components/distributionChart'
@@ -181,6 +192,7 @@ export default {
   components: {
     statusChart,
     tendencyChart,
+    belongRequirementChart,
     cycleStatistic,
     developmentCycle,
     distributionChart,
@@ -206,6 +218,7 @@ export default {
       activeTab: '1', // tab标签
       cumulativeData: null, // 任务状态累计流数据
       tendencyData: null, // 趋势图数据
+      belongRequirementData: null, // 所属需求方向分布图
       cycleData: [], // 周期统计数据
       developmentCycleData: [], // 研发交付周期分布数据
       distributeStatus: 1, // 任务分布图任务状态
@@ -223,6 +236,7 @@ export default {
       moduleDistribute: null, // 模块分布图数据
       changeTaskData: null, // 排期变更任务数据
       changeTotal: 0, // 变更总数
+      reportSummaryData: null, // 报告统计数据
       bugListData: {} // 缺陷统计数据
     }
   },
@@ -276,12 +290,14 @@ export default {
       this.getSummary()
       this.getCumulativeFlowDiagram()
       this.getTaskCountTrend()
+      this.getBelongRequirementData()
       this.getCycleData()
       this.getDevelopmentCycle()
       this.getModuleDistributeData()
       this.getDistributeData()
       this.getStatusStayData()
       this.getTaskUnlockData()
+      this.getReportSummary()
       this.getBugStatisticData()
     },
     setDate(type) { // 日期筛选
@@ -342,6 +358,14 @@ export default {
       const res = await getTaskCountTrend(params)
       if (res.code === 200) this.tendencyData = res.data
     },
+    async getBelongRequirementData() { // 所属需求方向分布图
+      const params = {
+        ...this.globalParams,
+        type: Number(this.activeTab)
+      }
+      const res = await getRequirementOrientationDistributeData(params)
+      if (res.code === 200) this.belongRequirementData = res.data
+    },
     async getCumulativeFlowDiagram() { // 任务状态累计流图
       const params = {
         ...this.globalParams,
@@ -364,7 +388,11 @@ export default {
         type: Number(this.activeTab)
       }
       const res = await getTaskRdDeliveryPeriodicData(params)
-      if (res.code === 200) this.developmentCycleData = res.data
+      if (res.code === 200) {
+        res.data.length > 0
+          ? this.developmentCycleData = res.data
+          : this.developmentCycleData = [moment().format('YYYY-MM-DD'), '0']
+      }
     },
     async getDistributeData() { // 获取任务分布图
       const params = {
@@ -419,6 +447,14 @@ export default {
         })
       }
     },
+    async getReportSummary() { // 报告统计
+      const params = {
+        ...this.globalParams,
+        type: Number(this.activeTab)
+      }
+      const res = await getReportSummary(params)
+      if (res.code === 200) this.reportSummaryData = res.data
+    },
     async getBugStatisticData() { // 缺陷统计
       const params = {
         ...this.globalParams,