wenbobowen 4 éve
szülő
commit
e76c945c06
33 módosított fájl, 1207 hozzáadás és 248 törlés
  1. 10 0
      src/App.vue
  2. 60 0
      src/api/onlineproblem.js
  3. 8 2
      src/components/formInput/index.vue
  4. 1 0
      src/components/headTitle/index.vue
  5. 38 0
      src/components/model/index.vue
  6. 17 2
      src/components/newLayout/Main.vue
  7. 44 3
      src/components/searchHeader/index.vue
  8. 15 4
      src/components/select/selectTeam.vue
  9. 55 0
      src/utils/options.js
  10. 8 0
      src/utils/util.js
  11. 10 7
      src/views/projectManage/bugList/bugindex.vue
  12. 90 2
      src/views/projectManage/components/demand.vue
  13. 182 0
      src/views/projectManage/components/onlineTime.vue
  14. 35 58
      src/views/projectManage/onlineproblem/component/chart.vue
  15. 24 9
      src/views/projectManage/onlineproblem/component/header/index.vue
  16. 22 12
      src/views/projectManage/onlineproblem/component/list.vue
  17. 20 6
      src/views/projectManage/onlineproblem/component/mainTitle.vue
  18. 2 0
      src/views/projectManage/onlineproblem/create/component/base.vue
  19. 13 4
      src/views/projectManage/onlineproblem/create/component/makeBetterList.vue
  20. 62 23
      src/views/projectManage/onlineproblem/create/index.vue
  21. 13 20
      src/views/projectManage/onlineproblem/detial/component/base.vue
  22. 109 0
      src/views/projectManage/onlineproblem/detial/component/makeBetterView.vue
  23. 245 23
      src/views/projectManage/onlineproblem/detial/index.vue
  24. 32 8
      src/views/projectManage/onlineproblem/index.vue
  25. 7 0
      src/views/projectManage/taskList/components/reportList.vue
  26. 6 41
      src/views/projectManage/taskList/components/scheduleList.vue
  27. 25 18
      src/views/projectManage/taskList/taskIndex.vue
  28. 35 3
      src/views/projectManage/taskList/taskViewDetail.vue
  29. 3 0
      src/views/quality/components/cycleStatistic.vue
  30. 4 1
      src/views/reportManagement/components/DailyReport.vue
  31. 4 1
      src/views/reportManagement/components/ReleaseReport.vue
  32. 4 1
      src/views/reportManagement/components/TestingReport.vue
  33. 4 0
      src/views/reportManagement/testPresentation.vue

+ 10 - 0
src/App.vue

@@ -33,8 +33,18 @@ export default {
   created() {
     this.initRoutes()
     this.initOmegaTracker()
+    // this.settingUserGetBiz()
   },
   methods: {
+    // async settingUserGetBiz() { // 刷新页面
+    //   if (this.$store.state.global.bizId === -1) {
+    //     const res = await settingUserGetBiz()
+    //     if (res.code === 200) {
+    //       console.log(res.data)
+    //       this.$store.dispatch('global/setBizId', res.data.bizId)
+    //     }
+    //   }
+    // },
     initOmegaTracker() {
       try {
         window.log = OmegaTracker.getTracker(config)

+ 60 - 0
src/api/onlineproblem.js

@@ -41,3 +41,63 @@ export function getDetial(data) {
     method: 'get'
   })
 }
+
+export function getChartData(data) {
+  return request({
+    url: TeamManagement + '/onlineProblem/statistics',
+    method: 'post',
+    data
+  })
+}
+
+export function getChartListData(data) {
+  return request({
+    url: TeamManagement + '/onlineProblem/statisticsDetail',
+    method: 'post',
+    data
+  })
+}
+
+export function updateOnlineProblem(data) {
+  return request({
+    url: TeamManagement + '/onlineProblem/updateProblem',
+    method: 'post',
+    data
+  })
+}
+
+export function deleteProblem(data) {
+  return request({
+    url: TeamManagement + '/onlineProblem/delete',
+    method: 'post',
+    data
+  })
+}
+
+// 获取评论列表
+export function getCommentList(data) {
+  return request({
+    url: TeamManagement + `/comment/list`,
+    method: 'post',
+    data
+  })
+}
+
+// 创建评论列表/comment/create
+export function createComment(data) {
+  return request({
+    url: TeamManagement + `/comment/create`,
+    method: 'post',
+    data
+  })
+}
+
+// 获取变更记录列表
+export function getRecordList(data) {
+  return request({
+    url: TeamManagement + `/operationLog/checkList`,
+    method: 'post',
+    data
+  })
+}
+

+ 8 - 2
src/components/formInput/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="formInput Layout">
+  <div class="formInput" :style="layoutStyles">
     <span class="title" :style="!requried && { ...styles, paddingLeft: '12px' }">
       <span v-if="requried" class="mustInput">*</span>
       {{ title }}
@@ -75,7 +75,6 @@
   </div>
 </template>
 <script>
-import '@/views/projectManage/publicCss/index.css'
 export default {
   props: {
     value: defaultStatus,
@@ -88,6 +87,11 @@ export default {
       default: 'input',
       required: false
     },
+    layoutStyles: {
+      type: Object,
+      default: () => ({ alignItems: 'center' }),
+      required: false
+    },
     multiple: {
       type: Boolean,
       default: false,
@@ -134,6 +138,8 @@ export default {
 </script>
 <style scoped lang="scss">
 .formInput {
+  display: flex;
+  justify-content: space-between;
   .title {
     // display: inline-block;
     min-width: 153px;

+ 1 - 0
src/components/headTitle/index.vue

@@ -4,6 +4,7 @@
     <div class="title-left-name">{{ title }}</div>
     <div v-if="openBtn" class="editBtn">
       <i :class="icon" @click="$emit('handle')" />
+      <slot name="handleSlot" />
     </div>
   </div>
 </template>

+ 38 - 0
src/components/model/index.vue

@@ -0,0 +1,38 @@
+<template>
+  <el-dialog :title="title" class="wb-model" :visible.sync="visible" width="500px" :before-close="() => $emit('handleClose')">
+    <div class="blueStripe" />
+    <slot name="content" />
+    <span slot="footer" class="dialog-footer">
+      <el-button size="small" @click="$emit('handleClose')">取 消</el-button>
+      <el-button size="small" type="primary" @click="$emit('handleOk')">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  props: {
+    visible: { type: Boolean, default: false },
+    title: { type: String, default: '' }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.wb-model {
+  /deep/ .el-dialog__title {
+    line-height: 24px;
+    font-size: 18px;
+    color: #303133;
+    padding-left: 10px;
+	}
+	.blueStripe {
+		width:4px;
+		height:17px;
+		background:#409EFF;
+		border-radius:1px;
+		position: absolute;
+		top: 23px;
+		left: 20px;
+	}
+}
+</style>

+ 17 - 2
src/components/newLayout/Main.vue

@@ -8,7 +8,7 @@
       'no-sidebar': !showNavTag
     }"
   >
-    <div class="main-wrapper" @click="listenClick">
+    <div v-if="showpage" class="main-wrapper" @click="listenClick">
       <router-view />
     </div>
   </div>
@@ -21,7 +21,8 @@ import { settingGetBizList, settingUserGetBiz } from '@/api/projectIndex'
 export default {
   data() {
     return {
-      bizIdList: [] // 业务线列表
+      bizIdList: [], // 业务线列表
+      showpage: false
     }
   },
   computed: {
@@ -35,7 +36,21 @@ export default {
       immediate: true
     }
   },
+  created() {
+    this.settingUserGetBiz()
+  },
   methods: {
+    async settingUserGetBiz() { // 刷新页面
+      if (this.$store.state.global.bizId === -1) {
+        const res = await settingUserGetBiz()
+        if (res.code === 200) {
+          this.showpage = true
+          this.$store.dispatch('global/setBizId', res.data.bizId)
+        }
+      } else {
+        this.showpage = true
+      }
+    },
     // 获取业务线列表
     async settingGetBizList() {
       const res = await settingGetBizList({})

+ 44 - 3
src/components/searchHeader/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="searchHeader">
     <div class="defaultBox Layout">
-      <div class="content">
+      <div class="content mt12">
         <searchBox
           :list="data.default"
           @change="$emit('search')"
@@ -25,7 +25,7 @@
           style="margin-right: 8px; width: 100px"
           @change="$emit('search', 'month', month)"
         >
-          <el-option v-for="(m, index) in monthList" :key="index" :label="m" :value="m" />
+          <el-option v-for="(m, index) in monthList" :key="index" :label="m.label" :value="m.value" />
         </el-select>
       </div>
       <div class="btn" @click="showMoreHandle">{{ goodName }}</div>
@@ -68,7 +68,45 @@ export default {
       showMore: false,
       renderList: this.list || {},
       yearList: [],
-      monthList: ['全部', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
+      monthList: [
+        {
+          label: '全部',
+          value: '0'
+        }, {
+          label: '01',
+          value: '01'
+        }, {
+          label: '02',
+          value: '02'
+        }, {
+          label: '03',
+          value: '03'
+        }, {
+          label: '04',
+          value: '04'
+        }, {
+          label: '05',
+          value: '05'
+        }, {
+          label: '06',
+          value: '06'
+        }, {
+          label: '07',
+          value: '07'
+        }, {
+          label: '09',
+          value: '09'
+        }, {
+          label: '10',
+          value: '10'
+        }, {
+          label: '11',
+          value: '11'
+        }, {
+          label: '12',
+          value: '12'
+        }
+      ],
       year: new Date().getFullYear(),
       month: new Date().getMonth() + 1
     }
@@ -162,5 +200,8 @@ export default {
       padding-right: 16px;
     }
   }
+  .mt12 {
+    margin-top: 12px;
+  }
 }
 </style>

+ 15 - 4
src/components/select/selectTeam.vue

@@ -25,7 +25,16 @@
 import { teamQueryTeamInfo } from '@/api/onlineproblem'
 export default {
   props: {
-    value: defaultStatus,
+    value: {
+      type: [String, Number, Array, Object],
+      default: '123',
+      requried: false
+    },
+    name: {
+      type: [String, Number, Array, Object],
+      default: '232',
+      requried: false
+    },
     size: {
       type: String,
       default: 'small',
@@ -80,15 +89,17 @@ export default {
   },
   data() {
     return {
-      searchValue: this.value,
+      searchValue: this.name,
       loadStatus: this.loading,
       options: [],
       val: this.value
     }
   },
-
   mounted() {
-    this.remoteMethod()
+    this.$nextTick(() => {
+      console.log(this.value, this.name)
+      this.remoteMethod()
+    })
   },
   methods: {
     async remoteMethod(q = this.searchValue) {

+ 55 - 0
src/utils/options.js

@@ -0,0 +1,55 @@
+export function getBarOption(xAxis, data) {
+  return {
+    'color': ['#3AA1FF'],
+    'tooltip': {
+      'trigger': 'axis',
+      'axisPointer': {
+        'type': 'line'
+      }
+    },
+    'grid': {
+      'left': '5%',
+      'right': '5%',
+      'top': '10%',
+      'bottom': '10%',
+      'containLabel': true
+    },
+    'xAxis': [{
+      'type': 'category',
+      'data': xAxis,
+      'axisLabel': {
+        'interval': 0,
+        'rotate': 40
+      },
+      'axisTick': {
+        'alignWithLabel': true
+      }
+    }],
+    'yAxis': [{
+      'type': 'value',
+      'axisLine': {
+        'show': false
+      },
+      'splitLine': {
+        'lineStyle': {
+          'type': 'dashed'
+        }
+      }
+    }],
+    'series': [{
+      'name': null,
+      'type': 'bar',
+      'barWidth': '20px',
+      'data': data,
+      'itemStyle': {
+        'normal': {
+          'label': {
+            'show': true,
+            'formatter': '{c}',
+            'position': 'top'
+          }
+        }
+      }
+    }]
+  }
+}

+ 8 - 0
src/utils/util.js

@@ -0,0 +1,8 @@
+export function isUrl(url) {
+  const Reg = /(http|https):\/\/([\w.]+\/?)\S*/
+  if (Reg.test(url)) {
+    return true
+  } else {
+    return false
+  }
+}

+ 10 - 7
src/views/projectManage/bugList/bugindex.vue

@@ -195,9 +195,7 @@
                     </div>
                     <div class="Layout marginLeft">
                       <div class="queryName">开发修复时长</div>
-                      <el-select v-model="formInline.devRepairTime" size="small" clearable filterable placeholder="请选择" @change="changeSelect()">
-                        <el-option v-for="item in bugDevRepairTimeList" :key="item.code" :label="item.name" :value="item.code" />
-                      </el-select>
+                      <el-cascader v-model="formInline.devRepairTime" :options="bugDevRepairTimeList" clearable filterable size="small" placeholder="请选择" @change="changeSelect()" />
                     </div>
                   </div>
                   <div style="margin: 1.5% 0;" class="flex_start">
@@ -404,10 +402,15 @@ export default {
       if (!this.stratAndEnd) {
         this.stratAndEnd = []
       }
-      this.formInline.createStartTime = this.stratAndEnd[0] || null
-      this.formInline.createEndTime = this.stratAndEnd[1] || null
-      this.indexPage = this.formInline
-      this.$refs.bugTableDialog.bugGetTableList(this.formInline, true)
+      const fromData = { ...this.formInline }
+      if (this.formInline.devRepairTime) {
+        fromData.devRepairTimeType = this.formInline.devRepairTime[0]
+        fromData.devRepairTime = this.formInline.devRepairTime[1]
+      }
+      fromData.createStartTime = this.stratAndEnd[0] || null
+      fromData.createEndTime = this.stratAndEnd[1] || null
+      this.indexPage = fromData
+      this.$refs.bugTableDialog.bugGetTableList(fromData, true)
     },
     curIndexs(e) { // 返回查询和分页  导出功能使用
       this.indexPage.bizId = e.bizId

+ 90 - 2
src/views/projectManage/components/demand.vue

@@ -158,7 +158,7 @@
     <el-row>
       <span class="demandLayout">排期:</span>
       <span class="demandeta">{{ dataList.startTime || '' }} ~ {{ dataList.endTime }}</span>
-      <span style="color: #999999; font-size: 14px;">{{ '(' + dataList.scheduleTimeAnnotation.所有 + ')' }}</span>
+      <span v-if="dataList.scheduleTimeAnnotation" style="color: #999999; font-size: 14px;">{{ '(' + dataList.scheduleTimeAnnotation.所有 + ')' }}</span>
     </el-row>
     <el-row :gutter="20">
       <el-col v-for="(item, index) in scheduleDetail" :key="index" :span="12">
@@ -169,7 +169,30 @@
     </el-row>
     <el-row>
       <span class="demandLayout">预计上线版本:</span>
-      <span v-for="item in preOnlineVersion" :key="item" class="demandeta"> {{ item }} </span>
+      <span v-if="preOnlineVersion && preOnlineVersion.length > 0">
+        <span v-for="item in dataList.preOnlineVersionInfos" :key="item.id">
+          <el-popover placement="top" width="200" trigger="click" class="test">
+            <div class="popover-title">版本时间轴</div>
+            <div class="timeline-soll">
+              <div v-for="(i, y) in timeline" :key="y" class="dateTime-flexStart">
+                <div style="width: 24px">
+                  <span class="circular" />
+                  <div v-show="y < timeline.length - 1" class="qz-timeline" />
+                </div>
+                <div class="qz-over-hidden">
+                  <el-tooltip v-if="i.name.length + i.version.length > 10" class="item" effect="dark" :content="i.name + i.version" placement="right">
+                    <span class="version">{{ i.name }}{{ i.version }}</span>
+                  </el-tooltip>
+                  <span v-else class="version">{{ i.name + i.version }}</span><br>
+                  <span class="createTime">{{ i.endTime }}</span>
+                </div>
+              </div>
+            </div>
+            <span slot="reference" class="onlineVersion online" @click="getEventList(item.id)"> {{ item.appName + " " + item.version }} </span>
+          </el-popover>
+        </span>
+      </span>
+      <!-- <span v-for="item in preOnlineVersion" :key="item" class="demandeta"> {{ item }} </span> -->
       <el-tooltip class="item" effect="dark" content="版本有问题?点击触发重新计算!" placement="right">
         <svg-icon :icon-class="icon_problem ? 'problem1' : 'problem'" class="cursorPo" @mouseenter="icon_problem = true" @mouseleave="icon_problem = false" @click="requirementUpdatePreOnlineVersion" />
       </el-tooltip>
@@ -196,6 +219,7 @@ import { taskUpdates } from '@/api/projectViewDetails'
 import { memberQueryMemberInfoByIDAPorName } from '@/api/projectIndex'
 import schedule from '@/views/projectManage/schedule' // 排期锁定弹窗
 import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
+import { getEvent } from '@/api/versionsCalendar'
 export default {
   components: {
     scheduleList,
@@ -231,6 +255,7 @@ export default {
       showTaskDialog: false,
       taskScheduleList: [],
       scheduleList: [],
+      timeline: [],
       datas: [{
         date: '',
         type: '',
@@ -351,6 +376,12 @@ export default {
       }
     },
 
+    getEventList(ele) {
+      getEvent(ele).then(response => {
+        this.timeline = response.data
+      })
+    },
+
     async changeStatus(e) { // 状态改变
       if (e.status === 70 || e.status === 90 || e.status === 100) {
         this.taskIdObject = e
@@ -713,3 +744,60 @@ export default {
   color: #FFF;
 }
 </style>
+<style lang="scss" scoped>
+.version {
+  white-space: nowrap;
+  font-size: 12px;
+  color: #333333;
+}
+.qz-over-hidden {
+  width: 144px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.createTime {
+  font-size: 12px;
+  color: #999999;
+}
+.timeline-soll {
+  width: 100%;
+  height: 245px;
+  overflow: hidden;
+  overflow-y: auto;
+  padding-right: 15px;
+}
+.qz-timeline {
+  width: 0px;
+  height: calc(100% + 8px);
+  border: 1px solid #E5E5E5;
+  position: relative;
+  top: -8px;
+  left: 8px;
+}
+.dateTime-flexStart {
+  display: flex;
+  justify-content: flex-start;
+  margin-bottom: 20px;
+
+}
+.circular {
+  width: 8px;
+  height: 8px;
+  margin: 5px;
+  display: inline-block;
+  border: 1px solid #60AEFF;
+  border-radius: 50%;
+}
+.popover-title {
+  font-size: 14px;
+  font-family: Microsoft Sans Serif;
+  font-weight: 400;
+  margin: 0 0 20px;
+  color: #333333;
+  text-align: center;
+}
+.online:hover {
+  color: #409EFF;
+  cursor: pointer;
+}
+</style>

+ 182 - 0
src/views/projectManage/components/onlineTime.vue

@@ -0,0 +1,182 @@
+<template>
+  <div class="bottom-detail">
+    <el-row>交付日期:{{ scheduleDetail.endTime }}</el-row>
+    <el-row class="date-laout">排期:{{ scheduleDetail.startTime | handlerDate }} ~ {{ scheduleDetail.endTime | handlerDate }}
+      <span v-if="scheduleDetail.scheduleTimeAnnotation" style="color: #999999; font-size: 14px;">
+        {{ '(' + scheduleDetail.scheduleTimeAnnotation.所有 + ')' }}
+      </span>
+    </el-row>
+    <el-row>预计上线版本:
+      <span v-if="scheduleDetail.preOnlineVersion && scheduleDetail.preOnlineVersion.length > 0">
+        <span v-for="item in scheduleDetail.preOnlineVersionInfos" :key="item.id">
+          <el-popover placement="top" width="200" trigger="click" class="test">
+            <div class="popover-title">版本时间轴</div>
+            <div class="timeline-soll">
+              <div v-for="(i, y) in timeline" :key="y" class="dateTime-flexStart">
+                <div style="width: 24px">
+                  <span class="circular" />
+                  <div v-show="y < timeline.length - 1" class="qz-timeline" />
+                </div>
+                <div class="qz-over-hidden">
+                  <el-tooltip v-if="i.name.length + i.version.length > 10" class="item" effect="dark" :content="i.name + i.version" placement="right">
+                    <span class="version">{{ i.name }}{{ i.version }}</span>
+                  </el-tooltip>
+                  <span v-else class="version">{{ i.name + i.version }}</span><br>
+                  <span class="createTime">{{ i.endTime }}</span>
+                </div>
+              </div>
+            </div>
+            <span slot="reference" class="onlineVersion" @click="getEventList(item.id)"> {{ item.appName + " " + item.version }} </span>
+          </el-popover>
+        </span>
+      </span>
+      <el-tooltip class="item" effect="dark" content="版本有问题?点击触发重新计算!" placement="right">
+        <svg-icon :icon-class="icon_problem ? 'problem1' : 'problem'" style="cursor: pointer;" @mouseenter="icon_problem = true" @mouseleave="icon_problem = false" @click="taskUpdatePreOnlineVersion" />
+      </el-tooltip>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { taskUpdatePreOnlineVersion } from '@/api/taskIndex.js'
+import { analysisBizId_id } from '@/utils/crypto-js.js'
+import { getEvent } from '@/api/versionsCalendar'
+import moment from 'moment'
+export default {
+  filters: {
+    handlerDate(val) {
+      return val ? moment(val).format('YYYY-MM-DD') : ''
+    }
+  },
+  props: {
+    data: { type: Object, required: true }
+  },
+  data() {
+    return {
+      scheduleDetail: this.data,
+      icon_problem: false,
+      timeline: [],
+      activities: [{
+        name: '开发',
+        endTime: '2018-04-03',
+        version: 'large'
+      }, {
+        name: '开发',
+        endTime: '2018-04-03',
+        version: 'large'
+      }, {
+        name: '开发',
+        endTime: '2018-04-03',
+        version: 'large'
+      }, {
+        name: '开发',
+        endTime: '2018-04-03',
+        version: 'large'
+      }]
+    }
+  },
+  watch: {
+    data: {
+      handler(newV) {
+        this.scheduleDetail = newV
+      },
+      deep: true
+    }
+  },
+  methods: {
+    async taskUpdatePreOnlineVersion() {
+      const bizId_id = analysisBizId_id(this.$route.query.bizId_id)
+      const res = await taskUpdatePreOnlineVersion(bizId_id[0])
+      if (res.code === 200) {
+        this.$emit('update')
+        this.$message({ message: '预计上线版本重新计算中,请稍后刷新页面查看!', type: 'success', offset: 150 })
+      }
+    },
+    getEventList(ele) {
+      getEvent(ele).then(response => {
+        this.timeline = response.data
+      })
+    }
+  }
+
+}
+</script>
+
+<style lang="scss" scoped>
+.bottom-detail {
+  font-size: 14px;
+  width: calc(100% - 40px);
+  padding-top: 20px;
+}
+
+.el-timeline {
+  margin: 0;
+  font-size: 14px;
+  list-style: none;
+  padding: 0px;
+}
+.date-laout {
+  margin: 15px 0;
+}
+.onlineVersion:hover {
+  cursor: pointer;
+  color: #409eff;
+}
+.popover-title {
+  font-size: 14px;
+  font-family: Microsoft Sans Serif;
+  font-weight: 400;
+  margin: 0 0 20px;
+  color: #333333;
+  text-align: center;
+}
+.el-timeline-item__content {
+  font-size: 12px;
+  color: #303133;
+}
+.version {
+  white-space: nowrap;
+  font-size: 12px;
+  color: #333333;
+}
+.qz-over-hidden {
+  width: 144px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.createTime {
+  font-size: 12px;
+  color: #999999;
+}
+.timeline-soll {
+  width: 100%;
+  height: 245px;
+  overflow: hidden;
+  overflow-y: auto;
+  padding-right: 15px;
+}
+.qz-timeline {
+  width: 0px;
+  height: calc(100% + 8px);
+  border: 1px solid #E5E5E5;
+  position: relative;
+  top: -8px;
+  left: 8px;
+}
+</style>
+<style lang="scss" scoped>
+.dateTime-flexStart {
+  display: flex;
+  justify-content: flex-start;
+  margin-bottom: 20px;
+
+}
+.circular {
+  width: 8px;
+  height: 8px;
+  margin: 5px;
+  display: inline-block;
+  border: 1px solid #60AEFF;
+  border-radius: 50%;
+}
+</style>

+ 35 - 58
src/views/projectManage/onlineproblem/component/chart.vue

@@ -21,15 +21,28 @@
         <el-option v-for="(y, index) in yearList" :key="index" :label="y" :value="y" />
       </el-select>
     </div>
-    <normal-echart :chart-id="'chartThird'" :option="echartsOption3" @onClick="changeList" />
+    <normal-echart v-if="echartsOption3" :chart-id="'chartThird'" :option="echartsOption3" @onClick="changeList" />
   </div>
 </template>
 <script>
 import normalEchart from '@/components/chart/normalEchart'
+import { getBarOption } from '@/utils/options'
 export default {
   components: {
     normalEchart
   },
+  props: {
+    data: {
+      type: Object,
+      default: () => {},
+      required: true
+    },
+    chartSearchData: {
+      type: Object,
+      default: null,
+      required: true
+    }
+  },
   data() {
     return {
       dataListType: [
@@ -39,73 +52,37 @@ export default {
       ],
       yearList: [],
       year: '',
-      type: '0'
-      // echartsOption3:{
-      //   "color": ["#3AA1FF"],
-      //   "tooltip": {
-      //     "trigger": "axis",
-      //     "axisPointer": {
-      //       "type": "line"
-      //     }
-      //   },
-      //   "grid": {
-      //     "left": "5%",
-      //     "right": "5%",
-      //     "top": "10%",
-      //     "bottom": "10%",
-      //     "containLabel": true
-      //   },
-      //   "xAxis": [{
-      //     "type": "category",
-      //     "data": ["待修复", "待测试", "未完成", "已完成", "Reopen", "Hold"],
-      //     "axisLabel": {
-      //       "interval": 0,
-      //       "rotate": 40
-      //     },
-      //     "axisTick": {
-      //       "alignWithLabel": true
-      //     }
-      //   }],
-      //   "yAxis": [{
-      //     "type": "value",
-      //     "axisLine": {
-      //       "show": false
-      //     },
-      //     "splitLine": {
-      //       "lineStyle": {
-      //         "type": "dashed"
-      //       }
-      //     }
-      //   }],
-      //   "series": [{
-      //     "name": null,
-      //     "type": "bar",
-      //     "barWidth": "20px",
-      //     "data": [1, 0, 0, 0, 0, 0],
-      //     "itemStyle": {
-      //       "normal": {
-      //         "label": {
-      //           "show": true,
-      //           "formatter": "{c}",
-      //           "position": "top"
-      //         }
-      //       }
-      //     }
-      //   }]
-      // }
+      type: '0',
+      echartsOption3: null
+    }
+  },
+  watch: {
+    data: {
+      handler(newV) {
+        this.echartsOption3 = getBarOption(newV.xaxis, newV.data)
+      },
+      immediate: true
+    },
+    chartSearchData: {
+      handler(newV) {
+        this.year = newV.year
+        this.type = newV.type
+      },
+      immediate: true
     }
   },
   mounted() {
     const d = new Date()
+    const { data, xaxis } = this.data
     const nowYear = d.getFullYear()
     for (let i = 0; i <= nowYear - 2020; i++) {
-      this.yearList.unshift(2020 + i)
+      this.yearList.unshift('' + (2020 + i))
     }
-    this.year = nowYear
+    this.echartsOption3 = getBarOption(xaxis, data)
   },
   methods: {
     changeList(data) {
-      console.log(data)
+      this.$emit('changeList', data.data.code)
     }
   }
 }

+ 24 - 9
src/views/projectManage/onlineproblem/component/header/index.vue

@@ -4,24 +4,28 @@
       <mainTitle
         title="线上问题"
         btn-text="新建问题"
+        :tab-show="true"
         @btn-handle="create"
         @change-tab="changeTab"
       />
       <searchHeader
-        v-if="nowTab === 'list'"
+        v-show="nowTab === 'list'"
         :data="renderList"
         @search="search"
         @changeShowMore="changeShowMore"
       />
       <div v-if="nowTab === 'charts'" style="height:324px;">
-        <chart />
+        <chart
+          :data="chartData"
+          :chart-search-data="chartSearchData"
+          @search="(key, value) => $emit('chartSearch', key, value)"
+          @changeList="(code) => $emit('chartChangeList', code)"
+        />
       </div>
     </div>
   </div>
 </template>
 <script>
-import { getlist } from '@/api/onlineproblem'
-
 import searchHeader from '@/components/searchHeader'
 import searchData from './searchData'
 import mainTitle from '../mainTitle'
@@ -32,6 +36,18 @@ export default {
     mainTitle,
     chart
   },
+  props: {
+    chartData: {
+      type: Object,
+      default: null,
+      required: false
+    },
+    chartSearchData: {
+      type: Object,
+      default: null,
+      required: true
+    }
+  },
   data() {
     return {
       renderList: searchData,
@@ -52,7 +68,9 @@ export default {
   methods: {
     changeTab(e) {
       this.nowTab = e
-      this.$emit('change-tab', e)
+      if (this.nowTab === 'charts') {
+        this.$emit('chartSearch')
+      }
     },
     changeShowMore(e) {
       console.log(e)
@@ -62,7 +80,6 @@ export default {
       this.$router.push({ name: '质惠新建线上问题' })
     },
     async search(key, value) {
-      console.log(this.renderList, this.showMore)
       const data = {}
       this.renderList.default.map(t => t.map(g => {
         data[g.key] = g.value
@@ -77,9 +94,7 @@ export default {
       }
       data.year = '' + this.year
       data.month = this.month
-      console.log(data)
-      const res = await getlist(data)
-      this.$emit('listChange', res.data)
+      this.$emit('listSearch', data)
     }
   }
 }

+ 22 - 12
src/views/projectManage/onlineproblem/component/list.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <div v-for="item in data" :key="item.date" class="list">
-      <div class="time">{{ item.date }}</div>
+      <div class="tableTitle">{{ item.date }}</div>
       <el-table
         v-loading="table_loading"
         :data="item.data"
@@ -12,21 +12,23 @@
         size="small"
         show-overflow-tooltip="true"
       >
-        <el-table-column label="优先级" width="100" prop="priority" sortable align="center" fixed>
+        <el-table-column label="优先级" width="105" prop="priority" sortable align="right">
           <template slot-scope="scope">
-            <div class="div_priority" :style="{background: priorityColors[scope.row.priority]}">{{ scope.row.priorityName }}</div>
+            <span class="div_priority" :style="{background: priorityColors[scope.row.priority]}">{{ scope.row.priorityName }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="标题" min-width="230" prop="title" show-overflow-tooltip align="center">
+        <el-table-column label="标题" min-width="200" show-overflow-tooltip align="left">
           <template slot-scope="scope">
-            <div class="title" @click.stop="gotoDetail(scope.row)">
+            <span class="title" @click.stop="gotoDetail(scope.row)">
               {{ scope.row.title }}
-            </div>
+            </span>
           </template>
         </el-table-column>
-        <el-table-column label="责任团队" min-width="180" prop="teamName" show-overflow-tooltip align="center" />
+        <el-table-column label="责任团队" min-width="150" prop="teamName" show-overflow-tooltip align="center" />
         <el-table-column label="复盘链接" show-overflow-tooltip align="center">
-          <template slot-scope="scope">{{ scope.row.replayUrl }}</template>
+          <template slot-scope="scope">
+            <i class="el-icon-link" @click="goto(scope.row.replayUrl)" />
+          </template>
         </el-table-column>
         <el-table-column label="改进项已完成" min-width="130" show-overflow-tooltip align="center">
           <template slot="header">
@@ -40,11 +42,11 @@
         <el-table-column label="是否星辰花定级" min-width="130" show-overflow-tooltip align="center">
           <template slot-scope="scope">{{ scope.row.isGrading ? '是' : '否' }}</template>
         </el-table-column>
-        <el-table-column label="影响面" min-width="150" show-overflow-tooltip align="center">
+        <el-table-column label="影响面" min-width="120" show-overflow-tooltip align="center">
           <template slot-scope="scope">{{ scope.row.influenceSurfaceName }}</template>
         </el-table-column>
         <el-table-column label="发生时间" min-width="150" prop="happenDate" show-overflow-tooltip align="center" />
-        <el-table-column label="创建人" min-width="130" prop="creatorName" show-overflow-tooltip align="center" />
+        <el-table-column label="创建人" prop="creatorName" show-overflow-tooltip align="center" />
       </el-table>
     </div>
   </div>
@@ -81,31 +83,39 @@ export default {
         }
       })
       window.open(href, '_blank')
+    },
+    goto(url) {
+      window.open(url, '_blank')
     }
   }
 }
 </script>
 <style lang="scss" scoped>
 .list {
-  .time{
+  .tableTitle{
     color: #333;
     font-size: 16px;
-    padding: 16px 10px;
+    padding: 16px 30px;
     background: #fff;
+    font-weight: 700;
   }
   .title {
     &:hover {
       color: #409eff;
       cursor: pointer;
+      background: #f5f7fa;
     }
   }
   .div_priority {
+    display: inline-block;
+    text-align: center;
     width: 38px;
     height: 24px;
     line-height: 24px;
     font-size: 14px;
     color: #fff;
     border-radius: 4px;
+    margin-right: 30px;
   }
 }
 </style>

+ 20 - 6
src/views/projectManage/onlineproblem/component/mainTitle.vue

@@ -1,9 +1,9 @@
 <template>
-  <div class="mainTitle">
+  <div class="wb-mainTitle">
     <div class="stylus-title">
       <div class="titleBox">
         <span style="font-size: 22px;letter-spacing: 1px;font-weight: 600;color: #333b4a;padding-left: 15px;">{{ title }}</span>
-        <div class="radio">
+        <div v-if="tabShow" class="radio">
           <el-radio-group v-model="tabPosition" size="small" @change="changeTab">
             <el-radio-button label="list" class="list">
               <svg-icon
@@ -39,6 +39,11 @@ export default {
       type: String,
       default: '',
       required: true
+    },
+    tabShow: {
+      type: Boolean,
+      default: false,
+      required: false
     }
   },
   data() {
@@ -55,14 +60,23 @@ export default {
   }
 }
 </script>
-<style scoped lang="scss">
-.mainTitle {
+<style lang="scss">
+.wb-mainTitle {
   .titleBox {
     display: flex;
     .radio {
       margin-left: 18px;
-      :global(.el-radio-button__inner:hover) {
-        color: none;
+      .el-radio-button__inner {
+        &:hover {
+          color: #606266;
+        }
+      }
+      .is-active {
+        .el-radio-button__inner {
+          &:hover {
+            color: #fff;
+          }
+        }
       }
     }
   }

+ 2 - 0
src/views/projectManage/onlineproblem/create/component/base.vue

@@ -7,8 +7,10 @@
         :title="d.name"
         :type="d.type"
         :option="d.option"
+        :multiple="d.multiple"
         :value="data[d.key]"
         :requried="d.requried"
+        :layout-styles="{ alignItems: 'top'}"
         @onChange="(e) => $emit('onChange', d.key, e )"
         @remoteMethod="(e) => remoteMethod(d.key, e, d.utilName)"
       />

+ 13 - 4
src/views/projectManage/onlineproblem/create/component/makeBetterList.vue

@@ -20,6 +20,7 @@
             :type="d.type"
             :option="d.option"
             :value="item[d.key]"
+            :multiple="d.multiple"
             :requried="false"
             :has-slot="d.hasSlot"
             :styles="{ minWidth: '110px' }"
@@ -41,9 +42,15 @@
           <span class="title">
             进度
           </span>
-          <input v-model="item.progress" class="number" type="number">
+          <input
+            v-model="item.progress"
+            :min="1"
+            :max="100"
+            class="number"
+            type="number"
+          >
           %
-          <span class="brandColor pointer" @click="item.progress='100'">
+          <span class="brandColor pointer" @click="(e) => onChange('progress', '100', index)">
             <i class="icon" :class="item.progress === '100' ? 'el-icon-success': 'el-icon-circle-check'" />
             标记为已完成
           </span>
@@ -66,6 +73,7 @@
 <script>
 import formInput from '@/components/formInput'
 import { getPerson } from '@/api/onlineproblem'
+import '@/views/projectManage/publicCss/index.css'
 export default {
   components: {
     formInput
@@ -88,7 +96,7 @@ export default {
           key: 'leader',
           type: 'remoteSelect',
           utilName: 'getPerson',
-          multiple: false,
+          multiple: true,
           placeholder: '请选择责任人',
           hasSlot: true,
           default: '',
@@ -105,9 +113,10 @@ export default {
     async remoteMethod(key, q, utilName) {
       if (utilName === 'getPerson') {
         const res = await getPerson({ memberIDAP: q })
+        const personData = res.data || []
         this.renderFromData.map(t => t.map(g => {
           if (g.key === key) {
-            g.option = res.data.map(t => ({
+            g.option = personData.map(t => ({
               ...t,
               value: t.idap,
               label: t.name

+ 62 - 23
src/views/projectManage/onlineproblem/create/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="create main-section">
     <mainTitle title="新建线上问题" />
-    <div class="content">
+    <div class="content mt15 ml15">
       <header class="header">
         <headTitle title="基础信息" />
       </header>
@@ -9,7 +9,7 @@
         <baseBox :data="baseData" @onChange="(key, value) => change('baseData', key, value)" />
       </div>
       <header class="header">
-        <headTitle title="复盘" icon="el-icon-link" :open-btn="true" @handle="linkHandle" />
+        <headTitle title="复盘" icon="el-icon-link" :open-btn="true" @handle="addLinkModelvisible = true" />
       </header>
       <div class="content">
         <!-- 复盘 -->
@@ -26,7 +26,7 @@
       <header class="header">
         <headTitle title="改进项" />
       </header>
-      <div class="content">
+      <div class="content makeBetterWrap">
         <makeBetterList
           :list="improvements"
           @addHandle="addMakeBetterList"
@@ -41,41 +41,50 @@
         创建
       </el-button>
     </div>
+    <model
+      title="复盘链接"
+      :visible="addLinkModelvisible"
+      @handleClose="addLinkModelvisible = false"
+      @handleOk="addLinkModelvisible = false"
+    >
+      <div slot="content" class="replayLink">
+        <div class="name">复盘链接:</div>
+        <el-input
+          v-model="replayUrl"
+          size="small"
+          clearable
+          placeholder="请输入复盘链接"
+        />
+      </div>
+    </model>
   </div>
 </template>
 <script>
-import {
-  create
-} from '@/api/onlineproblem'
+import { create } from '@/api/onlineproblem'
 import mainTitle from '../component/mainTitle'
 import headTitle from '@/components/headTitle'
 import baseBox from './component/base'
 import makeBetterList from './component/makeBetterList'
 import normalArea from '@/components/input/normalArea' // 富文本
 import 'tinymce/plugins/table'// 插入表格插件
+import baseForm from './component/renderBase'
+import model from '@/components/model'
 export default {
   components: {
     mainTitle,
     headTitle,
     baseBox,
     makeBetterList,
-    normalArea
+    normalArea,
+    model
   },
   data() {
     return {
       baseData: {},
       replayDesc: '',
-      improvements: [{
-        finishTime: '2020-01-12 11:11:11',
-        leader: 'renwu',
-        name: 'mingzi',
-        progress: 30
-      }, {
-        finishTime: '2020-01-12 11:11:11',
-        leader: 'renwu',
-        name: 'mingzi',
-        progress: 30
-      }]
+      replayUrl: '',
+      improvements: [{}],
+      addLinkModelvisible: false
     }
   },
   methods: {
@@ -85,6 +94,19 @@ export default {
     },
     async createHandle() {
       console.log('create:', { ...this.baseData, replayDesc: this.replayDesc, improvements: this.improvements })
+      const notInput = []
+      baseForm.map(t => t.map(g => {
+        if (g.requried && !Object.keys(this.baseData).includes(g.key)) {
+          notInput.push(g.name)
+        }
+      }))
+      if (notInput.length > 0) {
+        this.$message({
+          message: `${notInput.join(',')}不能为空。`,
+          type: 'error'
+        })
+        return
+      }
       const res = await create({
         ...this.baseData,
         bizId: this.$store.state.global.bizId,
@@ -92,10 +114,9 @@ export default {
         improvements: this.improvements
       })
       console.log(res)
-      this.$router.push({ name: '线上问题 ' })
-    },
-    linkHandle() {
-      console.log('link')
+      if (res.code === 200) {
+        this.$router.push({ name: '线上问题 ' })
+      }
     },
     addMakeBetterList() {
       this.improvements.push({})
@@ -103,6 +124,7 @@ export default {
     delMakeBetterList(index) {
       this.improvements.splice(index, 1)
     },
+    // 只有改进项会有index
     change(type, key, value, index) {
       if (index !== undefined) {
         const data = [...this[type]]
@@ -119,6 +141,12 @@ export default {
 @import '@/styles/detail-pages.scss';
 .create{
   padding: 16px 20px;
+  .mt15 {
+    margin-top: 15px;
+  }
+  .ml15 {
+    margin-left: 15px;
+  }
   &.main-section {
     @include main-section;
   }
@@ -126,14 +154,25 @@ export default {
     margin-top: 5px;
   }
   .content {
-    width: 80%;
+    width: 890px;
     margin-bottom: 46px;
+    &.makeBetterWrap {
+      margin-top: 15px;
+    }
   }
   .control {
     width: 100%;
     text-align: right;
     padding: 0px 20px 20px 0px;
   }
+  .replayLink {
+    display: flex;
+    justify-content: center;
+    .name {
+      width:100px;
+      line-height: 32px;
+    }
+  }
 }
 
 </style>

+ 13 - 20
src/views/projectManage/onlineproblem/detial/component/base.vue

@@ -62,8 +62,8 @@
         <over-click id="teamId-select" @overMouse="changeArea">
           <template slot="active">
             <selectTeam
-              :value="data.teamName"
-              :model="form_data.teamName"
+              :value="data.teamId"
+              :name="data.teamName"
               @onChange="(e) => onChange('teamId', e)"
             />
           </template>
@@ -76,7 +76,7 @@
         <over-click id="influenceSurface-select" @overMouse="changeArea">
           <template slot="active">
             <el-select
-              v-model="form_data.influenceSurface"
+              v-model="data.influenceSurface"
               :size="size"
               :multiple="true"
               clearable
@@ -88,7 +88,7 @@
             </el-select>
           </template>
           <template slot="overMouse">
-            <span>{{ data.influenceSurface }}</span>
+            <span>{{ data.influenceSurfaceName }}</span>
           </template>
         </over-click>
       </el-form-item>
@@ -96,7 +96,7 @@
         <over-click id="influenceDesc-select" @overMouse="changeArea">
           <template slot="active">
             <el-input
-              v-model="form_data.influenceDesc"
+              v-model="data.influenceDesc"
               size="small"
               clearable
               style="width:100% !important;"
@@ -113,8 +113,9 @@
         <over-click id="closedLoopTime-select" @overMouse="changeArea">
           <template slot="active">
             <el-input-number
-              v-model="form_data.closedLoopTime"
+              v-model="data.closedLoopTime"
               :size="size"
+              :min="1"
               style="width:194px"
               placeholder="请填写闭环时长"
               @change="(e) => onChange('closedLoopTime', e)"
@@ -129,8 +130,9 @@
         <over-click id="slaNotAvailableTime-select" @overMouse="changeArea">
           <template slot="active">
             <el-input-number
-              v-model="form_data.slaNotAvailableTime"
+              v-model="data.slaNotAvailableTime"
               :size="size"
+              :min="1"
               style="width:194px"
               placeholder="请填写闭环时长"
               @change="(e) => onChange('slaNotAvailableTime', e)"
@@ -145,7 +147,7 @@
         <over-click id="desc-select" @overMouse="changeArea">
           <template slot="active">
             <el-input
-              v-model="form_data.desc"
+              v-model="data.desc"
               :size="size"
               type="textarea"
               placeholder="请填写描述"
@@ -200,21 +202,12 @@ export default {
       ]
     }
   },
-  mounted() {
-  },
   methods: {
     onChange(key, value) {
-      console.log(value)
-      console.log(this.form_data, this.data)
-      if (key === 'teamId') {
-        this.form_data[key] = value
-      }
-      // fromdata更新上去在换新的data
-      this.data[key] = value
+      this.$emit('change', key, value)
     },
     changeArea() {
-      // 发送请求
-      console.log(this.form_data)
+      this.$emit('update')
     }
   }
 }
@@ -234,7 +227,7 @@ export default {
       }
     }
     >>>.el-form-item__content {
-      width: calc(100% - 125px);
+      width: calc(100% - 340px);
       color: #333333;
       font-size: 14px;
     }

+ 109 - 0
src/views/projectManage/onlineproblem/detial/component/makeBetterView.vue

@@ -0,0 +1,109 @@
+<template>
+  <div class="makeBetterView">
+    <div v-for="(item, index) in list" :key="index" class="list">
+      <div class="desc">
+        <span class="NO">{{ index + 1 }}</span>
+        <span class="name">{{ item.name }}</span>
+      </div>
+      <div class="formWrap">
+        <div class="formLine">
+          <div class="formcontent">
+            <span class="name">责任人:</span>
+            <span class="value">{{ item.leader }}</span>
+          </div>
+          <div class="formcontent">
+            <span class="name">计划完成时间:</span>
+            <span class="value">{{ item.finishTime }}</span>
+          </div>
+          <div class="formcontent">
+            <span class="name">进度:</span>
+            <span class="value">{{ item.progress }}%</span>
+          </div>
+        </div>
+      </div>
+      <div class="overIcon">
+        <span class="brandColor pointer">
+          <!-- <svg-icon icon-class="del" class="icon" /> -->
+          <i class="icon" :class="item.progress === '100' ? 'el-icon-success': ''" />
+        </span>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    list: {
+      type: Array,
+      default: () => [{}],
+      requried: false
+    }
+  },
+  data() {
+    return {
+      size: 'small',
+      val: '',
+      data: {}
+    }
+  }
+}
+</script>
+<style scoped lang="scss">
+.makeBetterView {
+  .brandColor {
+    color: #1890FF;
+  }
+  .pointer {
+    cursor: pointer;
+  }
+  .list{
+    position: relative;
+    margin-bottom: 15px;
+    // width: calc(100% - 190px);
+    .overIcon {
+      position: absolute;
+      top: 2px;
+      right: -30px;
+    }
+    .desc {
+      padding-left: 12px;
+      display: flex;
+      .NO {
+        display: inline-block;
+        width: 14px;
+        height: 14px;
+        line-height: 12px;
+        font-size: 12px;
+        text-align: center;
+        border: 1px solid #1890FF;
+        background: #1890FF;
+        border-radius: 50%;
+        margin-right: 5px;
+        color: #fff;
+        margin-top: 4px;
+      }
+      .name {
+        word-break:break-all;
+        word-wrap:break-word;
+      }
+    }
+    .formWrap {
+      padding-left: 16px;
+      .formLine {
+        margin-top: 8px;
+        .formcontent {
+          display: inline-block;
+          margin-right: 20px;
+          margin-left: 14px;
+          .name {
+            color: #666;
+          }
+          .value {
+            color: #333;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 245 - 23
src/views/projectManage/onlineproblem/detial/index.vue

@@ -1,48 +1,161 @@
 <template>
-  <div class="op-detial">
+  <div class="wb-op-detial">
     <div class="content headerH1">
-      <div>
-        {{ form_data.title }}
+      <div style="width: 70%">
+        <el-input
+          v-if="form_data"
+          v-model="form_data.title"
+          size="small"
+          clearable
+          class="title"
+          style="width:100% !important;"
+          placeholder="请输入标题"
+          @change="(e) => onChange('title', e)"
+          @blur="update"
+        />
       </div>
-      <i class="el-icon-delete icon" />
+      <i class="el-icon-delete icon" @click="deleteHandle" />
     </div>
     <div class="content base">
-      <baseContent :data="form_data" />
+      <baseContent
+        v-if="form_data"
+        :data="form_data"
+        @update="update"
+        @change="onChange"
+      />
     </div>
-    <div class="content replay">
+    <div class="content">
       <header class="headerH2">
-        <headTitle title="复盘" icon="el-icon-link" :open-btn="true" @handle="linkHandle" />
+        <headTitle title="复盘" :open-btn="true">
+          <span slot="handleSlot">
+            <!-- 如果设置过url -->
+            <el-popover
+              v-if="form_data.replayUrl"
+              placement="bottom-start"
+              trigger="click"
+            >
+              <el-button-group>
+                <el-button :size="size" type="info" plain @click="goto(form_data.replayUrl)">访问链接</el-button>
+                <el-button :size="size" type="info" plain @click="editReplayUrl">编辑</el-button>
+                <el-button :size="size" type="info" plain @click="() => changeReplayUrl('')">取消链接</el-button>
+              </el-button-group>
+              <i slot="reference" class="el-icon-link" />
+            </el-popover>
+            <!-- 如果没有设置url -->
+            <i v-else class="el-icon-link" @click="editReplayUrl" />
+          </span>
+        </headTitle>
       </header>
-      <div>
+      <div v-if="form_data">
         <text-area
           :id="'pro-desc'"
           :value.sync="form_data.replayDesc"
           :empty-text="'点击'"
           :input-button="'添加复盘内容'"
           :styles="{ padding: '12px 0 20px 0' }"
-          @change="changeReplay"
+          @change="(e) => onChange('replayDesc', e)"
+        />
+      </div>
+    </div>
+    <div class="content">
+      <header class="headerH2">
+        <headTitle title="改进项" :icon="makeBetterEdit ? '' : 'el-icon-edit'" :open-btn="true" @handle="makeBetterEdit = true">
+          <span slot="handleSlot">
+            <!-- <i class="el-icon-edit" @click="$emit('handle')" /> -->
+            <!-- <span></span> -->
+            <span v-show="makeBetterEdit" @click="makeBetterEdit = false">111</span>
+          </span>
+        </headTitle>
+      </header>
+      <div v-if="form_data" class="makeBetter">
+        <!-- edit -->
+        <make-better-list
+          v-show="makeBetterEdit"
+          :list="improvements"
+          @addHandle="addMakeBetterList"
+          @delHandle="delMakeBetterList"
+          @onChange="(key, value, index) => change('improvements', key, value, index)"
+        />
+        <!-- view -->
+        <make-better-view
+          v-show="!makeBetterEdit"
+          :list="improvements"
+          @addHandle="addMakeBetterList"
+          @delHandle="delMakeBetterList"
+          @onChange="(key, value, index) => change('improvements', key, value, index)"
         />
       </div>
     </div>
+    <div class="content ">
+      <header class="headerH2">
+        <headTitle title="动态" />
+      </header>
+      <actionDynamic :comments="commentlist" :change-record="changeRecordList" @addComment="createCommentHandle" />
+    </div>
+    <model
+      title="复盘链接"
+      :visible="addLinkModelvisible"
+      @handleClose="addLinkModelvisible = false"
+      @handleOk="() => changeReplayUrl(replayUrl)"
+    >
+      <div slot="content" class="replayLink">
+        <div class="name">复盘链接:</div>
+        <el-input
+          v-model="replayUrl"
+          size="small"
+          clearable
+          placeholder="请输入复盘链接"
+        />
+      </div>
+    </model>
   </div>
 </template>
 <script>
-import { getDetial } from '@/api/onlineproblem'
+import {
+  getDetial,
+  updateOnlineProblem,
+  deleteProblem,
+  getCommentList,
+  createComment,
+  getRecordList
+} from '@/api/onlineproblem'
+import { isUrl } from '@/utils/util'
+import model from '@/components/model'
+import actionDynamic from '@/components/actionDynamic'
 import baseContent from './component/base'
 import headTitle from '@/components/headTitle'
 import textArea from '@/components/input/textArea' // 富文本
+import makeBetterList from '../create/component/makeBetterList'
+import makeBetterView from './component/makeBetterView'
 import 'tinymce/plugins/table'// 插入表格插件
 export default {
   components: {
     baseContent,
     textArea,
-    headTitle
+    headTitle,
+    makeBetterList,
+    makeBetterView,
+    model,
+    actionDynamic
   },
   data() {
     return {
+      size: 'small',
+      addLinkModelvisible: false,
       id: this.$route.query.id,
-      // data: '',
-      form_data: { pm: 'wenbobowen', replayDesc: '' }
+      form_data: {},
+      replayUrl: '',
+      updateData: {},
+      makeBetterEdit: false,
+      improvements: [{}],
+      commentlist: [{
+        commentInfo: {
+          name: 1111
+        }
+      }], // 评价列表
+      changeRecordList: [{
+        remark: 111
+      }] // 变更记录列表
     }
   },
   mounted() {
@@ -51,20 +164,115 @@ export default {
   methods: {
     async search() {
       const res = await getDetial({ id: this.id })
-      console.log(res)
-      this.form_data = res.data
+      if (res.code === 200) {
+        this.form_data = { ...res.data }
+        this.copy_form_data = { ...res.data }
+        this.replayUrl = res.data.replayUrl || ''
+      }
     },
-    linkHandle() {
-
+    goto(url) {
+      window.open(url, '_blank')
+    },
+    changeReplayUrl(value) {
+      if (value) {
+        if (!isUrl(value)) {
+          this.$message({
+            message: '请输入正确的复盘链接(以http或者https开头)',
+            type: 'error'
+          })
+          return
+        }
+      }
+      this.updateData = { replayUrl: value }
+      this.update()
+    },
+    editReplayUrl() {
+      this.replayUrl = this.form_data.replayUrl || ''
+      this.addLinkModelvisible = true
+    },
+    async onChange(key, value) {
+      //  确保每次更新一项
+      this.updateData = { [key]: value }
+    },
+    async update() {
+      const res = await updateOnlineProblem({ ...this.updateData, id: this.form_data.id })
+      if (res.code === 200) {
+        this.search()
+      } else {
+        this.form_data = { ...this.copy_form_data }
+      }
+    },
+    addMakeBetterList() {
+      this.improvements.push({})
+    },
+    delMakeBetterList(index) {
+      this.improvements.splice(index, 1)
+    },
+    change(type, key, value, index) {
+      if (index !== undefined) {
+        const data = [...this[type]]
+        data[index][key] = value
+        this[type] = [...data]
+      } else {
+        this[type] = { ...this[type], ...{ [key]: value }}
+      }
+    },
+    async deleteHandle() {
+      const { id } = this.form_data
+      const res = await deleteProblem({ id })
+      if (res.code === 200) {
+        this.$message({
+          message: '删除成功',
+          type: 'success'
+        })
+        this.$router.push({ name: '线上问题 ' })
+      } else {
+        this.$message({
+          message: '删除失败',
+          type: 'error'
+        })
+      }
+    },
+    // 获取评价列表
+    async getCommentList() {
+      const res = await getCommentList({ type: 5, joinId: this.taskId })
+      if (res.code === 200) {
+        this.commentlist = res.data
+      }
     },
-    changeReplay() {
 
+    // 获取变更记录
+    async getRecordList() {
+      const res = await getRecordList({ checkListId: this.checkListId })
+      if (res.code === 200) {
+        this.changeRecordList = res.data
+      }
+    },
+    // 添加评论
+    async createCommentHandle(content, callback) {
+      const commentInfo = {
+        joinId: this.form_data.id,
+        content,
+        type: 5,
+        fatherId: 0,
+        name: this.userNames,
+        email: this.userInformation
+      }
+      const user = { name: this.userNames, ename: this.userInformation, id: '' }
+      const res = await createComment({ commentInfo, user })
+      if (res.code === 200) {
+        this.$message({ message: '评论成功', type: 'success', duration: 1000, offset: 150 })
+        this.getCommentList()
+        callback()
+      } else {
+        this.$message.warning(res.msg)
+      }
     }
   }
 }
 </script>
-<style scoped lang="scss">
-.op-detial {
+<style lang="scss">
+.wb-op-detial {
   padding: 0 10px 10px 10px;
   .content {
     background-color: #fff;
@@ -72,13 +280,27 @@ export default {
     overflow: hidden;
     margin-bottom: 10px;
     padding: 16px 20px;
+    .makeBetter {
+      width: calc(100% - 190px);
+      padding: 12px 0px 20px 0px
+    }
   }
   .headerH1 {
-    color: #444;
-    font-size: 22px;
-    font-weight: 600;
     display: flex;
     justify-content: space-between;
+    .title {
+      color: #444;
+      font-size: 22px;
+      font-weight: 600;
+      margin-left: -15px;
+      cursor: pointer;
+      .el-input__inner {
+        border-color: transparent;
+        &:hover {
+          border-color: #DCDFE6;
+        }
+      }
+    }
     .icon {
       font-size: 20px;
       color: #6f7c93;

+ 32 - 8
src/views/projectManage/onlineproblem/index.vue

@@ -1,12 +1,19 @@
 <template>
   <div class="onlineproblem">
-    <Header @change-tab="changeTab" @listChange="listChange" />
+    <Header
+      :chart-data="chartData"
+      :chart-search-data="chartSearchData"
+      @listSearch="listSearch"
+      @chartSearch="(key, value) => chartSearch(key, value)"
+      @chartChangeList="(code) => chartChangeList(code)"
+    />
     <div class="content">
       <list :data="dataList" />
     </div>
   </div>
 </template>
 <script>
+import { getlist, getChartData, getChartListData } from '@/api/onlineproblem'
 import Header from './component/header'
 import list from './component/list'
 export default {
@@ -16,17 +23,34 @@ export default {
   },
   data() {
     return {
-      nowTab: 'list',
-      dataList: []
+      dataList: [],
+      chartData: {},
+      chartSearchData: {
+        type: '0',
+        year: '' + new Date().getFullYear()
+      }
     }
   },
   methods: {
-    changeTab(e) {
-      console.log(e)
-      this.nowTab = e
+    async listSearch(data) {
+      const res = await getlist(data)
+      this.dataList = res.data.list || []
     },
-    listChange(data) {
-      this.dataList = data.list || []
+    async chartSearch(key, value) {
+      if (key) {
+        this.chartSearchData[key] = value
+      }
+      const chartData = await getChartData(this.chartSearchData)
+      this.chartData = chartData.data
+      this.chartListSearch(chartData.data.data[0].code)
+    },
+    async chartListSearch(code) {
+      const chartList = await getChartListData({ ...this.chartSearchData, ...{ code }})
+      this.dataList = [chartList.data] || []
+    },
+    chartChangeList(code) {
+      this.chartSearchData = { ...this.chartSearchData, ...{ code }}
+      this.chartListSearch(code)
     }
   }
 }

+ 7 - 0
src/views/projectManage/taskList/components/reportList.vue

@@ -157,6 +157,7 @@
           <el-table-column label="标题名称" min-width="120">
             <template slot-scope="scope">
               <a href="javascript:void(0)" style="color:#20a0ff" @click="releaseDataStatus ? OldDaily(scope.row ,'准出报告') : toReportView(scope.row, 1)">{{ scope.row.reportName }}</a>
+              <div v-if="scope.row.passStatus === 1" class="passStatus1">不通过</div>
             </template>
           </el-table-column>
           <el-table-column label="状态" min-width="100" align="center">
@@ -604,4 +605,10 @@ export default {
 .task-report-btn {
   margin-right: 30px;
 }
+.passStatus {
+  color:rgba(126,211,33,1);
+}
+.passStatus1 {
+  color:red;
+}
 </style>

+ 6 - 41
src/views/projectManage/taskList/components/scheduleList.vue

@@ -102,18 +102,9 @@
       </el-table-column>
 
     </el-table>
-    <div class="bottom-detail">
-      <el-row>交付日期:{{ scheduleDetail.endTime }}</el-row>
-      <el-row>排期:{{ scheduleDetail.startTime | handlerDate }} ~ {{ scheduleDetail.endTime | handlerDate }} <span style="color: #999999; font-size: 14px;">{{ '(' + scheduleDetail.scheduleTimeAnnotation ? '' : scheduleDetail.scheduleTimeAnnotation.所有 + ')' }}</span></el-row>
-      <el-row>预计上线版本:
-        <span v-if="scheduleDetail.preOnlineVersion && scheduleDetail.preOnlineVersion.length > 0">
-          <span v-for="item in scheduleDetail.preOnlineVersion" :key="item">{{ item }}</span>
-        </span>
-        <el-tooltip class="item" effect="dark" content="版本有问题?点击触发重新计算!" placement="right">
-          <svg-icon :icon-class="icon_problem ? 'problem1' : 'problem'" style="cursor: pointer;" @mouseenter="icon_problem = true" @mouseleave="icon_problem = false" @click="taskUpdatePreOnlineVersion" />
-        </el-tooltip>
-      </el-row>
-    </div>
+    <!-- 交付日期 排期 预计上线版本 -->
+    <online-date :data="scheduleDetail" @update="listByTask(taskId)" />
+    <!-- 交付日期 排期 预计上线版本 -->
     <modify-schedule
       v-if="visibleSchedule"
       :visible.sync="visibleSchedule"
@@ -126,23 +117,18 @@
   </div>
 </template>
 <script>
-import { taskUpdatePreOnlineVersion } from '@/api/taskIndex.js'
 import { EncryptId } from '@/utils/crypto-js.js'
 import { mapGetters } from 'vuex'
 import Sortable from 'sortablejs'
-import moment from 'moment'
 import 'moment/locale/zh-cn'
 import { listByTask, sortForTask } from '@/api/projectViewDetails'
 import modifySchedule from '@/views/projectManage/projectList/components/modifySchedule'
 import move from '@/assets/麻将@2x.png'
+import onlineDate from '@/views/projectManage/components/onlineTime.vue'
 export default {
   components: {
-    modifySchedule
-  },
-  filters: {
-    handlerDate(val) {
-      return val ? moment(val).format('YYYY-MM-DD') : ''
-    }
+    modifySchedule,
+    onlineDate
   },
   props: {
     id: {
@@ -170,7 +156,6 @@ export default {
     return {
       taskId: '',
       move: move,
-      icon_problem: false,
       scheduleList: [],
       scheduleDetail: {},
       visibleSchedule: false,
@@ -222,17 +207,6 @@ export default {
         this.$message({ message: '移动成功', type: 'success', duration: 1000, offset: 150 })
       }
     },
-    async taskUpdatePreOnlineVersion() {
-      const res = await taskUpdatePreOnlineVersion(this.taskId)
-      if (res.code === 200) {
-        this.listByTask(this.taskId)
-        this.$message({ message: '预计上线版本重新计算中,请稍后刷新页面查看!', type: 'success', offset: 150 })
-      }
-    },
-    // getType(value) {
-    //   const res = this.taskScheduleEvent.find(item => item.code === value) || {}
-    //   return res.msg
-    // },
     async listByTask(id) { // 获取排期列表
       this.taskId = id
       const res = await listByTask(id)
@@ -302,15 +276,6 @@ export default {
     background: #ffffff !important;
   }
 }
-.bottom-detail {
-  font-size: 14px;
-  width: calc(100% - 40px);
-  margin: 0 20px;
-  padding: 20px 0;
-  :nth-child(2) {
-    margin: 10px 0;
-  }
-}
 .sortable-tip {
   height: 26px;
   width: 15px;

+ 25 - 18
src/views/projectManage/taskList/taskIndex.vue

@@ -86,7 +86,7 @@
             <el-form :model="form_task" class="flex_start">
               <div class="Layout">
                 <div class="queryName">模块</div>
-                <el-cascader v-model="form_task.moduleIds" size="small" clearable collapse-tags :props="props" :options="business_platform_Modular" placeholder="请选择" style="width:77% !important;" @click.native="bugDataGet" />
+                <el-cascader v-model="form_task.moduleIds" size="small" clearable collapse-tags :props="props" :options="business_platform_Modular" placeholder="请选择" style="width:77% !important;" />
               </div>
               <div class="Layout marginLeft">
                 <div class="queryName">状态</div>
@@ -292,7 +292,12 @@ export default {
       },
       newTabOpen: true, // 是否新的tab页打开
       header_show: true,
-      props: { multiple: true },
+      props: {
+        value: 'id',
+        label: 'moduleName',
+        children: 'childModules',
+        multiple: true
+      },
       isFromDpmList: [{ id: true, name: '是' }, { id: false, name: '否' }],
       priorityColors: ['#F56C6C', '#FF8952', '#F5E300', '#7ED321', '#61D3B8', '#69B3FF', '#BDBDBD'],
       arr_priority: [{ value: 0, name: 'P0' }, { value: 1, name: 'P1' }, { value: 2, name: 'P2' }, { value: 3, name: 'P3' }],
@@ -319,6 +324,7 @@ export default {
       currentPage: 0,
       DetailedScreening: false,
       total: 0,
+      biz: '',
       isToOne: true,
       loading: false,
       table_loading: false,
@@ -342,6 +348,11 @@ export default {
     this.get_taskSelect()
     this.$store.state.data.status = true
   },
+  mounted() {
+    this.$nextTick(() => {
+      this.bugDataGet()
+    })
+  },
   destroyed() {
     this.$store.state.data.status = false
   },
@@ -492,23 +503,19 @@ export default {
       }
     },
     bugDataGet() { // 所属模块
-      settingQueryBizModuleList(this.bizId).then(res => {
-        this.business_platform_Modular = res.data.map(item => ({
-          ...item,
-          value: item.id,
-          label: item.moduleName,
-          children: item.childModules.length === 0 ? null : item.childModules.map(item1 => ({
-            ...item1,
-            value: item1.id,
-            label: item1.moduleName,
-            children: item1.childModules.length === 0 ? null : item1.childModules.map(item2 => ({
-              ...item2,
-              value: item2.id,
-              label: item2.moduleName
-            }))
-          }))
-        }))
+      this.biz = this.bizId
+      if (this.bizId === -1) {
+        this.biz = this.$store.state.global.bizId
+      }
+      settingQueryBizModuleList(this.biz).then(res => {
+        this.business_platform_Modular = this.getRequireData(res.data)
       })
+    },
+    getRequireData(data) {
+      for (let i = 0; i < data.length; i++) {
+        data[i].childModules && data[i].childModules.length < 1 ? delete data[i].childModules : this.getRequireData(data[i].childModules)
+      }
+      return data
     }
   }
 }

+ 35 - 3
src/views/projectManage/taskList/taskViewDetail.vue

@@ -230,6 +230,20 @@
           <el-container>
             <el-main style="padding: 0;">
               <schedule-list :id="taskId" ref="taskSchedule" :showunlock="showunlock" :type-list="taskScheduleEvent" class-name="white" @updataData="getSchedule" />
+              <div v-if="form_query.status >= 70" class="border-top">
+                <el-divider />
+                <el-form :inline="true" :model="form_query" class="Layout_space_start" label-position="left" label-width="110px">
+                  <el-form-item v-if="form_query.status >= 70" label="实际提测时间">
+                    <el-date-picker v-model="form_query.launchTestRealTime" type="date" :clearable="false" placeholder="请选择" format="yyyy.MM.dd" value-format="yyyy-MM-dd" style="width: 100%;" size="small" @change="setChangeArea(2)" />
+                  </el-form-item>
+                  <el-form-item v-if="form_query.status >= 90" label="实际准出时间:">
+                    <el-date-picker v-model="form_query.testFinishRealTime" type="date" :clearable="false" placeholder="请选择" format="yyyy.MM.dd" value-format="yyyy-MM-dd" style="width: 100%;" size="small" @change="setChangeArea(2)" />
+                  </el-form-item>
+                  <el-form-item v-if="form_query.status >= 100" label="实际上线时间:">
+                    <el-date-picker v-model="form_query.onlineRealTime" type="date" :clearable="false" placeholder="请选择" format="yyyy.MM.dd" value-format="yyyy-MM-dd" style="width: 100%;" size="small" @change="setChangeArea(2)" />
+                  </el-form-item>
+                </el-form>
+              </div>
             </el-main>
             <el-aside v-if="lockHide" class="SchedulingAside">
               <div v-for="(item, index) in SchedulingContent" :key="index" class="SchedulingDiv" @click="clickScheduling(item)">
@@ -324,7 +338,6 @@
 
       <!-- 发布 -->
       <el-container v-if="activeName === '6'" class="is-vertical">
-        <!-- <section class="main-section contain"> -->
         <publishTask
           v-if="loaded"
           :task-id="form_query.id"
@@ -332,7 +345,6 @@
           :user-names="userNames"
           :user-information="userInformation"
         />
-        <!-- </section> -->
       </el-container>
       <!-- 发布 -->
 
@@ -629,6 +641,14 @@ export default {
       this.lockHide = false
       this.$refs.taskSchedule.listByTask(this.taskId)
     },
+    async setChangeArea(e) {
+      const user = { name: localStorage.getItem('username'), ename: localStorage.getItem('realname'), id: '' }
+      const taskInfoDO = this.form_query
+      const resTask = await taskUpdate({ taskInfoDO, user })
+      if (resTask.code === 200) {
+        this.$message({ message: '修改成功', type: 'success', offset: 150 })
+      }
+    },
     changeSchedule() { // 修改锁定状态
       if (this.isParentRequireScheduleLocked === 1) {
         this.$message({ message: '无法解锁,请先变更归属需求的排期状态为未锁定状态!', type: 'error', duration: 3000, offset: 150 })
@@ -920,6 +940,18 @@ export default {
 }
 </script>
 <style scoped lang="scss">
+.border-top {
+  margin: 0 20px;
+  >>>.el-form-item {
+    margin: 0 30px  10px 0;
+  }
+  >>>.el-divider--horizontal {
+    display: block;
+    height: 1px;
+    width: 100%;
+    margin: 10px 0;
+  }
+}
 @import '@/styles/detail-pages.scss';
 /deep/.el-button {
   cursor: pointer;
@@ -977,7 +1009,7 @@ export default {
   .task-help-tips {
     display: flex;
     flex-direction: column;
-    margin: 0 20px;
+    margin: 0 10px;
     padding: 20px 13px;
     border-radius: 4px;
     background-color: rgba(64, 158, 255,0.1);

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

@@ -47,6 +47,9 @@
             <span v-if="item.count > 0">
               /<span class="reject">打回{{ item.count }}个</span>
             </span>
+            <span v-if=" item.label === '准出报告' && item.refuse > 0">
+              /<span class="reject">不通过{{ item.refuse }}个</span>
+            </span>
           </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>

+ 4 - 1
src/views/reportManagement/components/DailyReport.vue

@@ -71,7 +71,7 @@
       <el-button v-if="newDailyTemplate" size="small" type="primary" @click="getCreateData">保存, 下一步</el-button>
       <!-- 第三步 -->
       <el-button v-if="dailyPreview" size="small" type="primary" @click="sendReportReturn">上一步</el-button>
-      <el-button v-if="dailyPreview" size="small" type="primary" @click="sendReport">发送</el-button>
+      <el-button v-if="dailyPreview" size="small" type="primary" :loading="loading" @click="sendReport">发送</el-button>
     </div>
 
   </el-dialog>
@@ -100,6 +100,7 @@ export default {
       fromData: {
         radio: 0
       },
+      loading: false,
       newDailyTemplate: false, // 新建日报模版
       reportTamplate: false, // new模版
       dailyPreview: false, // 日报预览
@@ -278,10 +279,12 @@ export default {
     },
 
     sendReport() { // 截图
+      this.loading = true
       this.$refs.dailyPreview.sendReport()
     },
 
     handleClose() {
+      this.loading = false
       this.dialogDaliy = false
       this.updateDaily = false
       this.showOne = false // 隐藏第一步

+ 4 - 1
src/views/reportManagement/components/ReleaseReport.vue

@@ -69,7 +69,7 @@
       <el-button v-if="newDailyTemplate" size="small" type="primary" @click="getCreateData">保存, 下一步</el-button>
       <!-- 第三步 -->
       <el-button v-if="dailyPreview" size="small" type="primary" @click="sendReportReturn">上一步</el-button>
-      <el-button v-if="dailyPreview" size="small" type="primary" @click="sendReport">发送</el-button>
+      <el-button v-if="dailyPreview" size="small" type="primary" :loading="loading" @click="sendReport">发送</el-button>
     </div>
 
   </el-dialog>
@@ -95,6 +95,7 @@ export default {
       modelId: '', // 下一步选择的模版id
       selectTemplate: [],
       tipName: '创建',
+      loading: false,
       fromData: {
         radio: 0
       },
@@ -260,10 +261,12 @@ export default {
     },
 
     sendReport() { // 截图
+      this.loading = true
       this.$refs.dailyPreview.sendReport()
     },
 
     handleClose() {
+      this.loading = false
       this.dialogDaliy = false
       this.updateDaily = false
       this.showOne = false // 隐藏第一步

+ 4 - 1
src/views/reportManagement/components/TestingReport.vue

@@ -69,7 +69,7 @@
       <el-button v-if="newDailyTemplate" size="small" type="primary" @click="getCreateData">保存, 下一步</el-button>
       <!-- 第三步 -->
       <el-button v-if="dailyPreview" size="small" type="primary" @click="sendReportReturn">上一步</el-button>
-      <el-button v-if="dailyPreview" size="small" type="primary" @click="sendReport">发送</el-button>
+      <el-button v-if="dailyPreview" size="small" type="primary" :loading="loading" @click="sendReport">发送</el-button>
     </div>
 
   </el-dialog>
@@ -94,6 +94,7 @@ export default {
       modelId: '', // 下一步选择的模版id
       selectTemplate: [], // 模版option
       tipName: '创建',
+      loading: false,
       fromData: {
         radio: 1
       },
@@ -278,10 +279,12 @@ export default {
     },
 
     sendReport() { // 截图
+      this.loading = true
       this.$refs.dailyPreview.sendReport()
     },
 
     handleClose() {
+      this.loading = false
       this.dialogDaliy = false
       this.updateDaily = false
       this.reportTamplate = false

+ 4 - 0
src/views/reportManagement/testPresentation.vue

@@ -26,6 +26,7 @@
           <el-table-column label="报告名称" min-width="280" show-overflow-tooltip>
             <template slot-scope="scope">
               <a v-if="title === '测试日报' || title === '准出报告'" href="javascript:void(0)" style="color:#20a0ff" @click="history ? toReportView(scope.row) : OldDaily(scope.row)">{{ scope.row.reportName }}</a>
+              <div v-if="title === '准出报告' && scope.row.passStatus === 1" class="passStatus1">不通过</div>
               <a v-if="title === '提测报告'" href="javascript:void(0)" style="color:#20a0ff" @click="history ? toReportView(scope.row) : OldDaily(scope.row)">{{ history ? scope.row.reportName : scope.row.name }}</a>
               <div v-if="title === '提测报告' && scope.row.returnReason" style="color: red;">打回报告:{{ scope.row.returnReason }}</div>
             </template>
@@ -646,6 +647,9 @@ export default {
     margin-right: 20px;
   }
 }
+.passStatus1 {
+  color:red;
+}
 </style>
 <style lang="stylus">
 .el-tabs__nav-wrap::after {