Browse Source

统计-周期数据

wangziqian 5 years ago
parent
commit
414db0c56b

+ 98 - 0
src/views/quality/components/cycleStatistic.vue

@@ -0,0 +1,98 @@
+<template>
+  <section>
+    <el-row type="flex" align="middle">
+      <div class="repair-list">
+        <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.total }}</div>
+          <div v-show="Number(item.relativeRatio)>=0" class="repair-up">环比:<i class="el-icon-caret-top" /><span>{{ item.relativeRatio }}%</span></div>
+          <div v-show="Number(item.relativeRatio)<0" class="repair-down">环比:<i class="el-icon-caret-bottom" /><span>{{ item.relativeRatio.substring(1,item.relativeRatio.length) }}%</span></div>
+          <div v-show="item.relativeRatio === '--'" class="repair-up">环比:<span>{{ item.relativeRatio }}%</span></div>
+        </div>
+      </div>
+    </el-row>
+  </section>
+</template>
+<script>
+export default {
+  props: {
+    chartData: {
+      type: Array,
+      default: () => [],
+      required: false
+    }
+  },
+  watch: {
+    chartData: {
+      handler(newV) {
+        this.chartData = newV
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.repair-list {
+  display: flex;
+  justify-content: space-between;
+  width: 84%;
+  margin: 30px auto 40px;
+  .repair-item {
+    position: relative;
+    width: 15%;
+    font-size: 12px;
+    font-weight: bold;
+    padding: 11px 17px 6px 17px;
+    display: flex;
+    flex-direction: column;
+    color: #909399;
+    background:rgba(255,255,255,1);
+    box-shadow:0px 2px 8px rgba(0,0,0,0.15);
+    border-radius: 4px;
+    .repair-time {
+      color: #303133;
+      font-size: 18px;
+      margin:25px 0;
+    }
+    .repair-item-point {
+      position: absolute;
+      top: 15px;
+      left: 6px;
+      width: 6px;
+      height: 6px;
+      border-radius: 50%;
+    }
+    .point1 {
+      background-color: #1890FF;
+    }
+    .point2 {
+      background-color: #52C41A;
+    }
+    .point3 {
+      background-color: #D675F0;
+    }
+    .point4 {
+      background-color: #ECAD00;
+    }
+  }
+  .repair-rise {
+    background-image: url('../../../../src/assets/defect_images/rise.png');
+    background-size: 100% 100%;
+    background-position: center;
+  }
+  .repair-slow {
+    background-image: url('../../../../src/assets/defect_images/slow.png');
+    background-size: 100% 100%;
+    background-position: center;
+  }
+  .repair-up i , .repair-up span{
+    color:#F32850
+  }
+  .repair-down i, .repair-down span {
+    color:#9FFF39
+  }
+}
+</style>

+ 25 - 24
src/views/quality/components/statusChart.vue

@@ -1,13 +1,13 @@
 <template>
 <template>
-  <div class="chart-contain">
-    <el-row type="flex" align="middle">
-      <el-col :span="4" :offset="18" class="col-flex-end">
-        <div class="pile-line" :class="[pileOrLine==='pile'?'active':'']" @click="changePileOrLine('pile')">堆叠面积图</div>
-        <div class="pile-line" :class="[pileOrLine==='line'?'active':'']" @click="changePileOrLine('line')">折线图</div>
-      </el-col>
-    </el-row>
-    <normal-echart v-if="echartsOption" :chart-id="id" :option="echartsOption" />
-  </div>
+  <section>
+    <div class="control">
+      <div class="pile-line" :class="[pileOrLine==='pile'?'active':'']" @click="changePileOrLine('pile')">堆叠面积图</div>
+      <div class="pile-line" :class="[pileOrLine==='line'?'active':'']" @click="changePileOrLine('line')">折线图</div>
+    </div>
+    <div class="chart-contain">
+      <normal-echart v-if="echartsOption" :chart-id="id" :option="echartsOption" />
+    </div>
+  </section>
 </template>
 </template>
 <script>
 <script>
 import normalEchart from '@/components/chart/normalEchart'
 import normalEchart from '@/components/chart/normalEchart'
@@ -51,9 +51,9 @@ export default {
         },
         },
         legend: {
         legend: {
           data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
           data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
-          left: '7%'
+          left: '0%'
         },
         },
-        grid: { left: '5%', right: '5%', bottom: '5%', top: '10%', containLabel: true },
+        grid: { left: '0%', right: '0%', bottom: '0%', top: '10%', containLabel: true },
         xAxis: [
         xAxis: [
           {
           {
             type: 'category',
             type: 'category',
@@ -120,9 +120,9 @@ export default {
         },
         },
         legend: {
         legend: {
           data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
           data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'],
-          left: '7%'
+          left: '0%'
         },
         },
-        grid: { left: '5%', right: '5%', bottom: '5%', top: '10%', containLabel: true },
+        grid: { left: '0%', right: '0%', bottom: '0%', top: '10%', containLabel: true },
         xAxis: [
         xAxis: [
           {
           {
             type: 'category',
             type: 'category',
@@ -170,21 +170,15 @@ export default {
 }
 }
 </script>
 </script>
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-.chart-contain {
-  position: relative;
-  height: 400px;
-  width: 100%;
-  margin-top: 20px;
-  .col-flex-end {
-    display: flex;
-    justify-content: flex-end;
-  }
+.control {
+  display: flex;
+  justify-content: flex-end;
   .pile-line{
   .pile-line{
     font-size: 14px;
     font-size: 14px;
-    width: 45%;
+    width: 100px;
     display: inline-block;
     display: inline-block;
     padding: 6px 10px;
     padding: 6px 10px;
-    margin-left: 5%;
+    margin-left: 20px;
     color: #50A6FF;
     color: #50A6FF;
     border: 1px solid #50A6FF;
     border: 1px solid #50A6FF;
     border-radius: 4px;
     border-radius: 4px;
@@ -196,4 +190,11 @@ export default {
     background: #50A6FF;
     background: #50A6FF;
   }
   }
 }
 }
+.chart-contain {
+  position: relative;
+  height: 400px;
+  width: 84%;
+  margin: auto;
+  margin-top: 20px;
+}
 </style>
 </style>

+ 67 - 0
src/views/quality/components/tendencyChart.vue

@@ -0,0 +1,67 @@
+<template>
+  <section>
+    <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: 'tendencyChart',
+      required: false
+    },
+    chartData: {
+      type: Object,
+      default: null,
+      required: false
+    }
+  },
+  data() {
+    return {
+      echartsOption: null
+    }
+  },
+  watch: {
+    chartData: {
+      handler(newV) {
+        this.setChart()
+      },
+      immediate: true
+    }
+  },
+  mounted() {
+    this.setChart()
+  },
+  methods: {
+    setChart() {
+      if (!this.chartData) return
+      this.echartsOption = {
+        color: ['#3AA1FF'],
+        tooltip: { trigger: 'axis', axisPointer: { type: 'line' }}, // 默认为直线,可选为:'line' | 'shadow'
+        grid: { left: '0', right: '0', top: '5%', 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: 'line', barWidth: '20px', smooth: true, data: this.chartData.yaxis[0] && this.chartData.yaxis[0].data || [],
+            itemStyle: { normal: { label: { show: true, formatter: '{c}', position: 'top' }}}
+          }
+        ]
+      }
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.chart-contain {
+  position: relative;
+  height: 400px;
+  width: 84%;
+  margin: 20px auto 40px;
+}
+</style>

+ 73 - 10
src/views/quality/requireStatistics.vue

@@ -95,13 +95,34 @@
     <el-main class="charts-main">
     <el-main class="charts-main">
       <div class="chart-item">
       <div class="chart-item">
         <h3>状态累积流量图</h3>
         <h3>状态累积流量图</h3>
-        <el-row type="flex" align="middle">
-          <el-col :span="24">
-            <div class="chart-contain">
-              <status-chart />
-            </div>
-          </el-col>
-        </el-row>
+        <status-chart />
+      </div>
+      <el-tabs v-model="activeName" class="tab-change">
+        <el-tab-pane name="first">
+          <span slot="label" class="tab-item">累计新增</span>
+        </el-tab-pane>
+        <el-tab-pane name="second">
+          <span slot="label" class="tab-item">累计上线</span>
+        </el-tab-pane>
+      </el-tabs>
+      <div class="chart-item">
+        <h3>新增趋势图</h3>
+        <tendency-chart :chart-data="tendencyData" />
+      </div>
+      <div class="chart-item">
+        <h3>周期统计<span>(根据排期计算)</span></h3>
+        <div class="chart-item-tip">
+          <i class="el-icon-warning-outline" />
+          <span>仅统计状态已变更“已排期”且排期不为空的任务</span>
+        </div>
+        <cycle-statistic :chart-data="cycleData" />
+      </div>
+      <div class="chart-item">
+        <h3>研发交付周期分布图<span>(根据排期计算)</span></h3>
+        <div class="chart-item-tip">
+          <i class="el-icon-warning-outline" />
+          <span>仅统计状态已变更“已排期”且排期不为空的任务;横坐标表示任务交付日期,纵坐标代表研发交付周期(研发、联调、上线类型排期的总周期)</span>
+        </div>
       </div>
       </div>
     </el-main>
     </el-main>
   </el-container>
   </el-container>
@@ -112,11 +133,15 @@ moment.locale('zh-cn')
 import { settingQueryBizModuleList } from '@/api/defectManage'
 import { settingQueryBizModuleList } from '@/api/defectManage'
 import { teamQueryTeamInfoList } from '@/api/configure'
 import { teamQueryTeamInfoList } from '@/api/configure'
 import {
 import {
-  getSummary
+  getSummary,
+  getBugCountTrend,
+  getRepairTimeSumData
 } from '@/api/defectStatistics'
 } from '@/api/defectStatistics'
 import statusChart from './components/statusChart'
 import statusChart from './components/statusChart'
+import tendencyChart from './components/tendencyChart'
+import cycleStatistic from './components/cycleStatistic'
 export default {
 export default {
-  components: { statusChart },
+  components: { statusChart, tendencyChart, cycleStatistic },
   data() {
   data() {
     return {
     return {
       bugCountTimeType: 1, // 获取趋缺陷势图数据接口入参:1本周 2本月 3本年
       bugCountTimeType: 1, // 获取趋缺陷势图数据接口入参:1本周 2本月 3本年
@@ -130,7 +155,10 @@ export default {
       stratAndEnd: [], // 开始结束日期
       stratAndEnd: [], // 开始结束日期
       dateType: 'week', // 时间选择类型
       dateType: 'week', // 时间选择类型
       moduleList: [], // 模块列表
       moduleList: [], // 模块列表
-      Summary: [] // 顶部数据
+      Summary: [], // 顶部数据
+      activeName: 'first', // tab标签
+      tendencyData: null, // 趋势图数据
+      cycleData: [] // 周期统计数据
     }
     }
   },
   },
   computed: {
   computed: {
@@ -159,6 +187,8 @@ export default {
   methods: {
   methods: {
     onSubmit() {
     onSubmit() {
       this.getSummary()
       this.getSummary()
+      this.defectTrendTimeChange()
+      this.getCycleData()
     },
     },
     setDate(type) { // 日期筛选
     setDate(type) { // 日期筛选
       let startDate = null
       let startDate = null
@@ -206,6 +236,27 @@ export default {
     async getSummary() { // 获取顶部数据
     async getSummary() { // 获取顶部数据
       const res = await getSummary(this.globalParams)
       const res = await getSummary(this.globalParams)
       if (res.code === 200) this.Summary = res.data || []
       if (res.code === 200) this.Summary = res.data || []
+    },
+    async defectTrendTimeChange() { // 趋势图日期变动
+      const moduleIds = this.defectForm.moduleIds
+      const params = {
+        beginTime: this.stratAndEnd[0] || null,
+        endTime: this.stratAndEnd[1] || null,
+        bizId: Number(localStorage.getItem('bizId')),
+        teamIds: this.defectForm.team || null,
+        moduleIds: moduleIds && moduleIds.length > 0 ? moduleIds : null,
+        timeType: this.bugCountTimeType
+      }
+      const res = await getBugCountTrend(params)
+      if (res.code === 200) this.tendencyData = res.data
+    },
+    async getCycleData() { // 周期统计数据
+      const params = {
+        ...this.globalParams,
+        type: 1
+      }
+      const res = await getRepairTimeSumData(params)
+      if (res.code === 200) this.cycleData = res.data
     }
     }
   }
   }
 }
 }
@@ -221,6 +272,9 @@ export default {
     font-size: 18px;
     font-size: 18px;
     margin: 0;
     margin: 0;
     padding: 0;
     padding: 0;
+    span {
+      color: #666666;
+    }
   }
   }
   .defect-main {
   .defect-main {
     padding: 20px 20px 0 20px;
     padding: 20px 20px 0 20px;
@@ -334,5 +388,14 @@ export default {
   background:#ffffff;
   background:#ffffff;
   margin: 10px;
   margin: 10px;
   border-radius: 4px;
   border-radius: 4px;
+  .tab-change {
+    overflow: hidden;
+    margin-top: 40px;
+  }
+  .chart-item-tip {
+    margin-top: 12px;
+    font-size: 12px;
+    color: #E6A23C;
+  }
 }
 }
 </style>
 </style>