瀏覽代碼

Merge branch 'http_test' into pern

qinzhipeng_v 5 年之前
父節點
當前提交
e162d892d1
共有 27 個文件被更改,包括 1427 次插入244 次删除
  1. 二進制
      src/assets/Unlock.png
  2. 二進制
      src/assets/lock.png
  3. 二進制
      src/assets/锁蓝1.png
  4. 二進制
      src/assets/锁蓝色.png
  5. 10 9
      src/styles/PublicStyle/index.scss
  6. 1 5
      src/views/Platform/presentation/testPresentation.vue
  7. 1 0
      src/views/projectManage/iteration/components/iterationTable.vue
  8. 1 5
      src/views/projectManage/iteration/components/modifySchedule.vue
  9. 1 5
      src/views/projectManage/projectList/components/modifySchedule.vue
  10. 3 2
      src/views/projectManage/projectList/components/scheduleList.vue
  11. 6 15
      src/views/projectManage/projectList/components/taskList.vue
  12. 1 5
      src/views/projectManage/requirement/components/modifySchedule.vue
  13. 11 7
      src/views/projectManage/requirement/components/scheduleList.vue
  14. 5 14
      src/views/projectManage/requirement/components/taskList.vue
  15. 48 21
      src/views/projectManage/requirement/requirementDetail.vue
  16. 3 1
      src/views/projectManage/schedule.vue
  17. 1 5
      src/views/projectManage/taskList/components/modifySchedule.vue
  18. 11 8
      src/views/projectManage/taskList/components/scheduleList.vue
  19. 3 4
      src/views/projectManage/taskList/dialog/taskDialog.vue
  20. 26 19
      src/views/projectManage/taskList/taskViewDetail.vue
  21. 419 0
      src/views/projectManage/version/components/modifySchedule.vue
  22. 255 0
      src/views/projectManage/version/components/scheduleList.vue
  23. 521 0
      src/views/projectManage/version/components/taskList.vue
  24. 79 93
      src/views/projectManage/version/list/index.vue
  25. 1 5
      src/views/workbench/person/components/calenderDetail.vue
  26. 1 6
      src/views/workbench/person/components/calenderList.vue
  27. 19 15
      src/views/workbench/team/components/taskList.vue

二進制
src/assets/Unlock.png


二進制
src/assets/lock.png


二進制
src/assets/锁蓝1.png


二進制
src/assets/锁蓝色.png


+ 10 - 9
src/styles/PublicStyle/index.scss

@@ -314,13 +314,10 @@
 }
 
 // 排期锁定
-.public_image {
-  width: 12.31px;
-  padding-bottom: 2px;
-}
 .SchedulingAside { // 排期变更
   width:270px !important;
-  max-height: 375px;
+  max-height: 276px;
+  overflow-x: hidden;
   .SchedulingDiv {
     display: flex;
     position: relative;
@@ -336,11 +333,11 @@
     display: flex;
     position: absolute;
     z-index: 9;
-    top: 7px;
+    top: 13px;
     background-color: #ffffff;
     .image {
       display: inline-block;
-      width: 8px;
+      width: 12px;
       margin: 0 auto;
       align-self: center;
     }
@@ -353,7 +350,7 @@
     position: absolute;
     left: 9px;
     z-index: 2;
-    top: 7px;
+    top: 13px;
   }
   .btn {
       width:92px;
@@ -366,10 +363,14 @@
   }
 }
  .modifyTime {
+   cursor: pointer;
     color:rgba(153,153,153,1);
   }
   .timeline:hover {
       color:#409EFF !important;
+      .SchedulingTow {
+        border:1px solid #409EFF !important;
+      }
       .modifyTime{
         color:#409EFF !important;
       }
@@ -391,7 +392,7 @@
     line-height:17px;
     color:rgba(51,51,51,1);
     opacity:1;
-    padding: 2px;
+    padding: 10px 2px;
     margin: 0 20px;
     cursor: pointer;
   }

+ 1 - 5
src/views/Platform/presentation/testPresentation.vue

@@ -294,11 +294,7 @@ export default {
       this.$set(this.queryData, 'ClientReport', '')
       this.$set(this.queryData, 'code', '')
       this.restaurants = []
-      let statusList = [3]
-      if (e === 3) {
-        statusList = [1]
-      }
-      taskListCreate({ statusList: statusList, bizId: localStorage.getItem('bizId') }).then(res => {
+      taskListCreate({ bizId: localStorage.getItem('bizId') }).then(res => {
         this.restaurants = res.data.taskInfoList
       })
     },

+ 1 - 0
src/views/projectManage/iteration/components/iterationTable.vue

@@ -30,6 +30,7 @@
       >
         <template slot-scope="scope">
           {{ getType(scope.row.type) }}
+          <div :class="scope.row.isScheduleLocked === 1 ? 'el-icon-lock' : 'el-icon-unlock'" />
         </template>
       </el-table-column>
       <el-table-column

+ 1 - 5
src/views/projectManage/iteration/components/modifySchedule.vue

@@ -51,7 +51,7 @@
             >
               <div class="Layout_space_between">
                 <span>{{ item.name }}</span>
-                <img :src="item.isScheduleLocked === 1 ? lock : Unlock" style="width: 13px;">
+                <div :class="item.isScheduleLocked === 1 ? 'el-icon-lock': 'el-icon-unlock'" />
               </div>
             </el-option>
           </el-select>
@@ -101,8 +101,6 @@ import { taskList } from '@/api/projectIndex'
 import { taskList as allTaskList, configShowTaskEnum } from '@/api/taskIndex'
 import { getSeprateDayInfo, scheduleCreate, scheduleGet, scheduleUpdate, scheduleDelete } from '@/api/projectViewDetails'
 import danger from '@/assets/感叹@2x.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 import '@/styles/PublicStyle/index.scss'
 export default {
   components: {
@@ -139,8 +137,6 @@ export default {
   },
   data() {
     return {
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       dangerImg: danger,
       form_rules: {
         type: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],

+ 1 - 5
src/views/projectManage/projectList/components/modifySchedule.vue

@@ -51,7 +51,7 @@
             >
               <div class="Layout_space_between">
                 <span>{{ item.name }}</span>
-                <img :src="item.isScheduleLocked === 1 ? lock : Unlock" style="width: 13px;">
+                <div :class="item.isScheduleLocked === 1 ? 'el-icon-lock': 'el-icon-unlock'" />
               </div>
             </el-option>
           </el-select>
@@ -102,8 +102,6 @@ import { taskList } from '@/api/projectIndex'
 import { taskList as allTaskList, configShowTaskEnum } from '@/api/taskIndex'
 import { getSeprateDayInfo, scheduleCreate, scheduleGet, scheduleUpdate, scheduleDelete } from '@/api/projectViewDetails'
 import danger from '@/assets/感叹@2x.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 export default {
   components: {
     searchPeople,
@@ -144,8 +142,6 @@ export default {
   },
   data() {
     return {
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       dangerImg: danger,
       form_rules: {
         type: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],

+ 3 - 2
src/views/projectManage/projectList/components/scheduleList.vue

@@ -30,6 +30,7 @@
       >
         <template slot-scope="scope">
           {{ getType(scope.row.type) }}
+          <div :class="scope.row.isScheduleLocked === 0 ? 'el-icon-unlock' : 'el-icon-lock'" />
         </template>
       </el-table-column>
       <el-table-column
@@ -65,8 +66,8 @@
         show-overflow-tooltip
       >
         <template slot-scope="scope">
-          <el-button type="text" size="small" @click="editSchedule(scope.row)">编辑</el-button>
-          <el-button type="text" size="small" @click="deleteSchedule(scope.row)">删除</el-button>
+          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="editSchedule(scope.row)">编辑</el-button>
+          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="deleteSchedule(scope.row)">删除</el-button>
         </template>
       </el-table-column>
 

+ 6 - 15
src/views/projectManage/projectList/components/taskList.vue

@@ -58,7 +58,7 @@
         <template slot-scope="scope">
           <el-select
             v-model="scope.row.status"
-            :class="'status'+scope.row.status"
+            :class="{'status0':scope.row.status===0,'status1':scope.row.status > 0 && scope.row.status <100,'status2':scope.row.status===100,}"
             class="btns"
             size="mini"
             @change="changeStatus(scope.row)"
@@ -89,12 +89,6 @@
     <DailyReport v-if="dialogDailyReport" ref="DailyReport" />
     <ClientReport v-if="dialogClientReport" ref="ClientReport" />
     <taskDialog v-if="showTaskDialog" :show.sync="showTaskDialog" :task-id="taskId.id" :status-name="taskId.statusString" @getList="get_allTask" />
-    <normal-dialog :show-dialog.sync="statusDialog" :title="'状态变更:已上线'" :width="'50%'" @confirm="confirmStatus()">
-      <div class="dialog-change-status">
-        <span>实际上线时间:</span>
-        <el-date-picker v-model="changeStatusDate" type="date" style="width:100%;" placeholder="选择日期" format="yyyy-MM-dd HH:mm:ss" />
-      </div>
-    </normal-dialog>
     <!-- 批量排期 -->
     <modify-schedule
       v-if="visibleSchedule"
@@ -116,11 +110,9 @@ import { taskUpdate } from '@/api/projectViewDetails'
 import { configShowTaskEnum } from '@/api/taskIndex'
 import scheduleList from './scheduleList'
 import modifySchedule from './modifySchedule'
-import normalDialog from '@/components/dialog/normalDialog'
 import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
 export default {
   components: {
-    normalDialog,
     TestReport,
     DailyReport,
     ClientReport,
@@ -147,7 +139,6 @@ export default {
       dialogTestReport: false, // 提测
       dialogDailyReport: false, // 日报
       dialogClientReport: false, // 准出
-      statusDialog: false, // 修改状态弹框
       changeStatusDate: null, // 状态改变时间
       nowChangeTask: null, // 当前正在改变的任务对象
       taskId: '', // 将要修改状态的任务id
@@ -192,7 +183,7 @@ export default {
       isEx ? this.expandArr = this.all_task.map(item => item.id) : this.expandArr = []
     },
     async changeStatus(e) { // 状态改变
-      if (e.status === 2 || e.status === 4 || e.status === 5) {
+      if (e.status === 70 || e.status === 90 || e.status === 100) {
         this.taskId = e
         this.allStatus.map(item => {
           item.code === e.status ? this.taskId.statusString = item.msg : ''
@@ -209,7 +200,7 @@ export default {
         const taskInfoDO = e
         const resTask = await taskUpdate({ taskInfoDO, user })
         if (resTask.code === 200) {
-          this.$message({ message: resTask.msg, type: 'success', offset: 150 })
+          this.$message({ message: '修改成功', type: 'success', offset: 150 })
         }
       }
     },
@@ -219,7 +210,7 @@ export default {
       taskInfoDO.onlineRealTime = this.changeStatusDate
       const resTask = await taskUpdate({ taskInfoDO, user })
       if (resTask.code === 200) {
-        this.$message({ message: resTask.msg, type: 'success', offset: 150 })
+        this.$message({ message: '修改成功', type: 'success', offset: 150 })
       }
     },
     handleSelectionChange(val) { // 任务列表删选操作
@@ -347,10 +338,10 @@ export default {
 .status0 {
   @include setStatus(#409EFF)
 }
-.status1, .status2, .status3, .status4{
+.status1{
   @include setStatus(#FF8952)
 }
-.status5 {
+.status2 {
   @include setStatus(#7ED321)
 }
 .expand i {

+ 1 - 5
src/views/projectManage/requirement/components/modifySchedule.vue

@@ -51,7 +51,7 @@
             >
               <div class="Layout_space_between">
                 <span>{{ item.name }}</span>
-                <img :src="item.isScheduleLocked === 1 ? lock : Unlock" style="width: 13px;">
+                <div :class="item.isScheduleLocked === 1 ? 'el-icon-lock': 'el-icon-unlock'" />
               </div>
             </el-option>
           </el-select>
@@ -101,8 +101,6 @@ import { taskList } from '@/api/projectIndex'
 import { taskList as allTaskList, configShowTaskEnum } from '@/api/taskIndex'
 import { getSeprateDayInfo, scheduleCreate, scheduleGet, scheduleUpdate, scheduleDelete } from '@/api/projectViewDetails'
 import danger from '@/assets/感叹@2x.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 import '@/styles/PublicStyle/index.scss'
 export default {
   components: {
@@ -144,8 +142,6 @@ export default {
   },
   data() {
     return {
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       dangerImg: danger,
       form_rules: {
         type: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],

+ 11 - 7
src/views/projectManage/requirement/components/scheduleList.vue

@@ -20,7 +20,8 @@
       </el-table-column>
       <el-table-column prop="type" label="类型" min-width="100" align="center">
         <template slot-scope="scope">
-          {{ getType(scope.row.type) }} <img class="public_image" :src="scope.row.isScheduleLocked === 0 ? Unlock : lock">
+          {{ scope.row.name }}
+          <div v-show="showunlock" :class="scope.row.isScheduleLocked === 1 ? 'el-icon-lock' : 'el-icon-unlock'" />
         </template>
       </el-table-column>
       <el-table-column prop="desc" label="描述" min-width="150" align="left" show-overflow-tooltip />
@@ -29,8 +30,10 @@
       <el-table-column prop="peopleList" label="参与人员" min-width="150" align="center" />
       <el-table-column label="操作" width="200" align="center">
         <template slot-scope="scope">
-          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="editSchedule(scope.row)">编辑</el-button>
-          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="deleteSchedule(scope.row)">删除</el-button>
+          <div v-if="showunlock">
+            <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="editSchedule(scope.row)">编辑</el-button>
+            <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="deleteSchedule(scope.row)">删除</el-button>
+          </div>
         </template>
       </el-table-column>
 
@@ -63,8 +66,6 @@ import { listByRequire } from '@/api/requirement.js'
 import { listByTask, sortForTask } from '@/api/projectViewDetails'
 import modifySchedule from './modifySchedule'
 import move from '@/assets/麻将@2x.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 import '@/styles/PublicStyle/index.scss' // 通用css
 export default {
   components: {
@@ -105,13 +106,16 @@ export default {
       type: Boolean,
       default: true,
       required: false
+    },
+    showunlock: {
+      type: Boolean,
+      default: false,
+      required: false
     }
   },
   data() {
     return {
       move: move,
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       scheduleList: [],
       scheduleDetail: {},
       visibleSchedule: false,

+ 5 - 14
src/views/projectManage/requirement/components/taskList.vue

@@ -33,7 +33,7 @@
           <div class="expand"><i v-show="allChange" class="el-icon-minus" @click="expandAll(false)" /></div>
         </template>
         <template slot-scope="props">
-          <schedule-list :id="props.row.id" :type-list="taskScheduleEvent" />
+          <schedule-list :id="props.row.id" :showunlock="'true'" :type-list="taskScheduleEvent" />
         </template>
       </el-table-column>
       <el-table-column label="优先级" prop="priority" width="90" sortable align="center">
@@ -58,7 +58,7 @@
         <template slot-scope="scope">
           <el-select
             v-model="scope.row.status"
-            :class="'status'+scope.row.status"
+            :class="{'status0':scope.row.status===0,'status1':scope.row.status > 0 && scope.row.status <100,'status2':scope.row.status===100,}"
             class="btns"
             size="mini"
             @change="changeStatus(scope.row)"
@@ -86,12 +86,6 @@
     <DailyReport v-if="dialogDailyReport" ref="DailyReport" />
     <ClientReport v-if="dialogClientReport" ref="ClientReport" />
     <task-dialog v-if="showTaskDialog" :show.sync="showTaskDialog" :task-id="taskId.id" :status-name="taskId.statusString" @getList="get_allTask" />
-    <normal-dialog :show-dialog.sync="statusDialog" :title="'状态变更:已上线'" :width="'50%'" @confirm="confirmStatus()">
-      <div class="dialog-change-status">
-        <span>实际上线时间:</span>
-        <el-date-picker v-model="changeStatusDate" type="date" style="width:100%;" placeholder="选择日期" format="yyyy-MM-dd HH:mm:ss" />
-      </div>
-    </normal-dialog>
     <!-- 批量排期 -->
     <modify-schedule
       v-if="visibleSchedule"
@@ -112,12 +106,10 @@ import { taskUpdate } from '@/api/projectViewDetails'
 import { configShowTaskEnum } from '@/api/taskIndex'
 import scheduleList from './scheduleList'
 import modifySchedule from './modifySchedule'
-import normalDialog from '@/components/dialog/normalDialog'
 import '@/styles/PublicStyle/index.scss'
 import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
 export default {
   components: {
-    normalDialog,
     TestReport,
     DailyReport,
     ClientReport,
@@ -143,7 +135,6 @@ export default {
       dialogTestReport: false, // 提测
       dialogDailyReport: false, // 日报
       dialogClientReport: false, // 准出
-      statusDialog: false, // 修改状态弹框
       changeStatusDate: null, // 状态改变时间
       nowChangeTask: null, // 当前正在改变的任务对象
       taskId: '', // 将要修改状态的任务id
@@ -185,7 +176,7 @@ export default {
       isEx ? this.expandArr = this.all_task.map(item => item.id) : this.expandArr = []
     },
     async changeStatus(e) { // 状态改变
-      if (e.status === 2 || e.status === 4 || e.status === 5) {
+      if (e.status === 70 || e.status === 90 || e.status === 100) {
         this.taskId = e
         this.allStatus.map(item => {
           item.code === e.status ? this.taskId.statusString = item.msg : ''
@@ -344,10 +335,10 @@ export default {
 .status0 {
   @include setStatus(#409EFF)
 }
-.status1, .status2, .status3, .status4{
+.status1{
   @include setStatus(#FF8952)
 }
-.status5 {
+.status2 {
   @include setStatus(#7ED321)
 }
 .expand i {

+ 48 - 21
src/views/projectManage/requirement/requirementDetail.vue

@@ -3,6 +3,12 @@
     <el-container>
       <el-header class="main-header">
         <div class="top-page-title">
+          <div v-if="form_query.type === 1" class="triangleContainer">
+            <div class="triangleContent">
+              <div class="triangle" />
+              <div class="title">紧 急</div>
+            </div>
+          </div>
           <div class="header-title">
             <span class="title-id">REQUIREMENT-{{ form_query.id }}</span>
             <el-tooltip class="item" effect="dark" :content="form_query.name" placement="bottom">
@@ -116,7 +122,7 @@
             <div class="title-left-name">
               <div>需求计划
                 <el-tooltip class="item" effect="dark" :content="isScheduleLocked === 1? '点击解锁排期' : '点击锁定排期'" placement="top">
-                  <span class="titleStatus" @click="changeSchedule"><img :src="isScheduleLocked === 1 ? lock : Unlock" style="width: 12.31px;display: inline-block; vertical-align: inherit;"> {{ isScheduleLocked === 1 ? '已锁定' : '未锁定' }}</span>
+                  <span class="titleStatus" :class="isScheduleLocked === 1 ? 'el-icon-lock' : 'el-icon-unlock'" @click="changeSchedule"> {{ isScheduleLocked === 1 ? '已锁定' : '未锁定' }}</span>
                 </el-tooltip>
               </div>
             </div><br>
@@ -124,26 +130,24 @@
           <section class="main-section">
             <div class="allTips">
               <div class="tips"><i class="el-icon-warning-outline" />每个任务仅支持一次提测和一次准出,请合理拆解后任务再排期</div><br>
-              <div v-if="BackToTheLatest" class="Scheduling" @click="GetRequireScheduleHistory"><i class="el-icon-refresh" /> 回到最新</div>
-              <div align="left" class="Scheduling" @click="scheduleHiHide"><img :src="scheduling"> 排期变更记录</div>
+              <div class="allTips">
+                <div v-if="BackToTheLatest" class="Scheduling" @click="GetRequireScheduleHistory"><i class="el-icon-refresh" /> 回到最新</div>
+                <div align="left" class="Scheduling" @click="scheduleHiHide"><div class="el-icon-document" /> 排期变更记录</div>
+              </div>
             </div>
           </section>
 
           <el-container>
             <el-main style="padding: 0;">
-              <schedule-list :id="requirementId" ref="ScheduleEvent" :type-list="taskScheduleEvent" :required-list="taskScheduleList" class-name="white" :all="true" :no-move="false" />
+              <schedule-list :id="requirementId" ref="ScheduleEvent" :showunlock="showunlock" :type-list="taskScheduleEvent" :required-list="taskScheduleList" class-name="white" :all="true" :no-move="false" />
             </el-main>
             <el-aside v-if="lockHide" class="SchedulingAside">
               <div v-for="(item, index) in SchedulingContent" :key="index" class="SchedulingDiv" @click="clickScheduling(item)">
-                <div class="SchedulingTow">
-                  <img v-if="item.type === 1" :src="lock" class="image">
-                  <img v-if="item.type === 2" :src="Unlock" class="image">
-                </div>
                 <i v-show="index < SchedulingContent.length - 1" />
                 <div class="timeline">
                   <div class="SchedulingTow" :class="{'vss' : item.id === ScheduId}">
-                    <img v-if="item.type === 2" :src="item.id === ScheduId ? lockblur : lock" class="image">
-                    <img v-if="item.type === 1" :src="item.id === ScheduId ? Unlockblur : Unlock " class="image">
+                    <div v-if="item.operationType === 0" class="el-icon-unlock image" />
+                    <div v-if="item.operationType === 1" class="el-icon-lock image" />
                   </div>
                   <div class="modifyTime">{{ item.modifyTime }}</div>
                   <div>{{ item.operatorObject.name !== null ? item.operatorObject.name : '' }} <span class="btn">{{ item.operation }}</span></div>
@@ -151,7 +155,7 @@
                   <div v-if="item.remark"><span class="modifyTime">{{ '具体描述 : ' }}</span>{{ item.remark }}</div>
                 </div>
               </div>
-              <div v-if="SchedulingContent.length === 0" style="width: 270px; text-align: center;"> 暂无排期变更记录!</div>
+              <div v-if="SchedulingContent.length === 0" style="width: 270px; margin: 50% 20px; text-align: center;"> 暂无排期变更记录!</div>
             </el-aside>
           </el-container>
         </section>
@@ -280,11 +284,6 @@ import tasksList from './components/taskList'
 import dataStatistics from './components/dataStatistics'
 import scheduleList from './components/scheduleList'
 import bugTableDialog from '@/views/projectManage/bugList/details/bugTableDialog' // 缺陷表格
-import scheduling from '@/assets/scheduling.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
-import lockblur from '@/assets/锁蓝1.png' // 排期锁定图标
-import Unlockblur from '@/assets/锁蓝色.png' // 排期锁定图标
 import schedule from '@/views/projectManage/schedule' // 排期锁定弹窗
 export default {
   components: {
@@ -311,15 +310,11 @@ export default {
   },
   data() {
     return {
+      showunlock: true,
       ScheduId: '', // 排期ID
       BackToTheLatest: false, // 回到最新
       LockState: {}, // 锁定状态
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
-      Unlockblur: Unlockblur, // 解锁排期
-      lockblur: lockblur, // 锁定排期
       scheduleVisble: false, // 排期锁定
-      scheduling: scheduling, // 排期变更记录图标
       activeName: '1', // 顶部tab切换
       userInformation: localStorage.getItem('username'),
       userNames: localStorage.getItem('realname'),
@@ -378,10 +373,13 @@ export default {
       const res1 = await listByRequire(this.requirementId)
       this.BackToTheLatest = false // 回到最新
       this.lockHide = false // 隐藏排期变更记录
+      this.showunlock = true
       this.taskScheduleList = res1.data.schedulDetailResponses
       this.isScheduleLocked = res1.data.isScheduleLocked // 锁定状态1锁定0未锁定
+      this.$refs.ScheduleEvent.listByTask(this.requirementId)
     },
     async clickScheduling(ele) {
+      this.showunlock = false
       this.ScheduId = ele.id
       const res = await scheduleGetHistoryScheduleById(ele.id)
       this.taskScheduleList = res.data.schedulDetailResponses
@@ -511,6 +509,7 @@ export default {
     scheduleHiHide() { // 排期变更显示隐藏
       this.lockHide = !this.lockHide
       this.lockHide === false ? this.BackToTheLatest = false : ''
+      this.showunlock = true
     },
     jump(page, id) { // 跳转
       this.$router.push({ name: page, query: { id: id }})
@@ -632,6 +631,34 @@ export default {
   font-size: 14px;
 }
 .vss {
+  color: #409EFF !important;
    border:1px solid #409EFF !important;
 }
+// 左上角紧急样式
+.triangleContainer {
+        height: 60px;
+        background: #fff;
+    }
+    .triangleContent {
+        position: relative;
+    }
+    .triangle {
+        position: absolute;
+        top: -30px;
+        left: -60px;
+        transform: rotate(315deg);
+        border: 30px solid transparent;
+        border-bottom-color: red;
+        font-weight: 600;
+    }
+    .title {
+        position: inherit;
+        right: 28px;
+        top: 4px;
+        transform: rotate(-43deg);
+        font-size: 12px;
+        color: #fff;
+        white-space: nowrap;
+    }
+    // 左上角紧急样式
 </style>

+ 3 - 1
src/views/projectManage/schedule.vue

@@ -47,7 +47,9 @@ export default {
       this.dialogVisible = val
     },
     isScheduleLocked(val) {
-      this.isSchedule = val
+      console.log(val, 'xsxsx')
+      val === null ? this.isSchedule = 0 : this.isSchedule = val
+      // this.isSchedule = val
     },
     name(val) {
       this.codeName = val

+ 1 - 5
src/views/projectManage/taskList/components/modifySchedule.vue

@@ -51,7 +51,7 @@
             >
               <div class="Layout_space_between">
                 <span>{{ item.name }}</span>
-                <img :src="item.isScheduleLocked === 1 ? lock : Unlock" style="width: 13px;">
+                <div :class="item.isScheduleLocked === 1 ? 'el-icon-lock': 'el-icon-unlock'" />
               </div>
             </el-option>
           </el-select>
@@ -100,8 +100,6 @@ import selDatePicker from '@/components/picker/SelDatePicker'
 import { taskList as allTaskList, configShowTaskEnum, taskGet } from '@/api/taskIndex'
 import { getSeprateDayInfo, scheduleCreate, scheduleGet, scheduleUpdate, scheduleDelete } from '@/api/projectViewDetails'
 import danger from '@/assets/感叹@2x.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 import '@/styles/PublicStyle/index.scss'
 export default {
   components: {
@@ -138,8 +136,6 @@ export default {
   },
   data() {
     return {
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       dangerImg: danger,
       form_rules: {
         type: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],

+ 11 - 8
src/views/projectManage/taskList/components/scheduleList.vue

@@ -1,6 +1,5 @@
 <template>
   <div class="schedule-list" :class="className">
-    <!-- <el-col align="right" class="add-schedule"><span @click="addSchedule()"><i class="el-icon-circle-plus-outline" />添加排期</span></el-col> -->
     <el-table
       :id="'schedule-'+id"
       :data="scheduleList"
@@ -30,7 +29,7 @@
       >
         <template slot-scope="scope">
           {{ scope.row.name }}
-          <img class="public_image" :src="scope.row.isScheduleLocked === 0 ? Unlock : lock">
+          <div v-show="showunlock" :class="scope.row.isScheduleLocked === 0 ? 'el-icon-unlock' : 'el-icon-lock'" />
         </template>
       </el-table-column>
       <el-table-column
@@ -66,8 +65,10 @@
         show-overflow-tooltip
       >
         <template slot-scope="scope">
-          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="editSchedule(scope.row)">编辑</el-button>
-          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="deleteSchedule(scope.row)">删除</el-button>
+          <div v-if="showunlock">
+            <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="editSchedule(scope.row)">编辑</el-button>
+            <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="deleteSchedule(scope.row)">删除</el-button>
+          </div>
         </template>
       </el-table-column>
 
@@ -99,8 +100,6 @@ import 'moment/locale/zh-cn'
 import { listByTask, sortForTask } from '@/api/projectViewDetails'
 import modifySchedule from './modifySchedule'
 import move from '@/assets/麻将@2x.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 export default {
   components: {
     modifySchedule
@@ -125,12 +124,15 @@ export default {
       type: String,
       default: '',
       required: false
+    },
+    showunlock: {
+      type: Boolean,
+      default: false,
+      required: false
     }
   },
   data() {
     return {
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       move: move,
       scheduleList: [],
       scheduleDetail: {},
@@ -190,6 +192,7 @@ export default {
           ...item,
           peopleList: item.peopleObjectList.map(item => item.name).join(',')
         }))
+        this.$emit('updataData')
       }
     },
     addSchedule() {

+ 3 - 4
src/views/projectManage/taskList/dialog/taskDialog.vue

@@ -64,7 +64,6 @@ export default {
     statusName: {
       immediate: true,
       handler(statusName) {
-        console.log(statusName, 'ddddd')
         if (statusName === '已提测') {
           this.name = this.measurementTime
           this.codeName = this.measurementTimeName
@@ -95,15 +94,15 @@ export default {
     },
     task_status_uptate(e) {
       if (this.statusName === '已提测') {
-        this.taskData.status = 2
+        this.taskData.status = 70
         this.taskData.launchTestRealTime = e
       }
       if (this.statusName === '已准出') {
-        this.taskData.status = 4
+        this.taskData.status = 90
         this.taskData.testFinishRealTime = e
       }
       if (this.statusName === '已上线') {
-        this.taskData.status = 5
+        this.taskData.status = 100
         this.taskData.onlineRealTime = e
       }
       const taskInfoDO = this.taskData

+ 26 - 19
src/views/projectManage/taskList/taskViewDetail.vue

@@ -116,7 +116,7 @@
             <div class="title-left-name">
               <div>任务计划
                 <el-tooltip class="item" effect="dark" :content="isScheduleLocked === 1? '点击解锁排期' : '点击锁定排期'" placement="top">
-                  <span class="titleStatus" @click="changeSchedule"><img :src="isScheduleLocked === 1 ? lock: Unlock" style="width: 13px;display: inline-block; vertical-align: inherit"> {{ isScheduleLocked === 1 ? '已锁定' : '未锁定' }}</span>
+                  <span class="titleStatus" :class="isScheduleLocked === 1 ? 'el-icon-lock' : 'el-icon-unlock'" @click="changeSchedule"> {{ isScheduleLocked === 1 ? '已锁定' : '未锁定' }}</span>
                 </el-tooltip>
               </div>
             </div>
@@ -129,23 +129,25 @@
                 <span v-if="tips" style="color:#e88792;">当前任务归属的需求计划排期呈锁定状态,当前任务的排期无法同步到需求计划中去,请将归属需求的排期解锁!</span>
               </div>
               <div class="Layout_space_between">
-                <div v-show="BackToTheLatest === false" class="Scheduling" style="margin-right: 160px;" @click="clickBackToTheLatest"><i class="el-icon-refresh" /> 回到最新</div>
-                <div v-show="BackToTheLatest === true" class="Scheduling" style="margin-right: 160px;" @click="clickAddScheduling()"><i class="el-icon-circle-plus-outline" />添加排期</div>
-                <div align="left" class="Scheduling" @click="scheduleHiHide"><img :src="scheduling"> 排期变更记录</div>
+                <div v-show="BackToTheLatest === false" class="Scheduling" style="margin-right: 20px;" @click="clickBackToTheLatest"><i class="el-icon-refresh" /> 回到最新</div>
+                <div v-show="isScheduleLocked === 0">
+                  <div v-show="BackToTheLatest === true" class="Scheduling" style="margin-right: 20px;" @click="clickAddScheduling()"><i class="el-icon-circle-plus-outline" /> 添加排期</div>
+                </div>
+                <div align="left" class="Scheduling" @click="scheduleHiHide"><div class="el-icon-document" /> 排期变更记录</div>
               </div>
             </div>
           </section>
           <el-container>
             <el-main style="padding: 0;">
-              <schedule-list :id="taskId" ref="taskSchedule" :type-list="taskScheduleEvent" class-name="white" />
+              <schedule-list :id="taskId" ref="taskSchedule" :showunlock="showunlock" :type-list="taskScheduleEvent" class-name="white" @updataData="getSchedule" />
             </el-main>
             <el-aside v-if="lockHide" class="SchedulingAside">
               <div v-for="(item, index) in SchedulingContent" :key="index" class="SchedulingDiv" @click="clickScheduling(item)">
                 <i v-show="index < SchedulingContent.length - 1" />
                 <div class="timeline">
                   <div class="SchedulingTow" :class="{'vss' : item.id === ScheduId}">
-                    <img v-if="item.type === 2" :src="item.id === ScheduId ? lockblur : lock" class="image">
-                    <img v-if="item.type === 1" :src="item.id === ScheduId ? Unlockblur : Unlock " class="image">
+                    <div v-if="item.operationType === 0" class="el-icon-unlock image" />
+                    <div v-if="item.operationType === 1" class="el-icon-lock image" />
                   </div>
                   <div class="modifyTime">{{ item.modifyTime }}</div>
                   <div>{{ item.operatorObject.name !== null ? item.operatorObject.name : '' }} <span class="btn">{{ item.operation }}</span></div>
@@ -153,7 +155,7 @@
                   <div v-if="item.remark"><span class="modifyTime">{{ '具体描述 : ' }}</span>{{ item.remark }}</div>
                 </div>
               </div>
-              <div v-if="SchedulingContent.length === 0" style="width: 270px; text-align: center;"> 暂无排期变更记录!</div>
+              <div v-if="SchedulingContent.length === 0" style="width: 270px; margin: 50% 20px; text-align: center;"> 暂无排期变更记录!</div>
             </el-aside>
           </el-container>
         </section>
@@ -284,11 +286,6 @@ import stage1 from '@/assets/detailPage/正常状态.png'
 import stage2 from '@/assets/detailPage/延期状态.png'
 import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
 import bugTableDialog from '@/views/projectManage/bugList/details/bugTableDialog' // 缺陷表格
-import scheduling from '@/assets/scheduling.png'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
-import lockblur from '@/assets/锁蓝1.png' // 排期锁定图标
-import Unlockblur from '@/assets/锁蓝色.png' // 排期锁定图标
 import '@/styles/PublicStyle/index.scss'
 import schedule from '@/views/projectManage/schedule' // 排期锁定弹窗
 export default {
@@ -320,17 +317,13 @@ export default {
   },
   data() {
     return {
+      showunlock: true,
       ScheduId: '', // 排期ID
       LockState: {}, // 锁定状态
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
-      Unlockblur: Unlockblur, // 解锁排期
-      lockblur: lockblur, // 锁定排期
       tips: '', // 后加入需求的任务排期提示
       scheduleVisble: false, // 排期锁定
       isParentRequireScheduleLocked: '',
       BackToTheLatest: true, // 显示添加排期按钮
-      scheduling: scheduling, // 排期变更记录图标
       lockHide: false, // 隐藏排期变更记录
       SchedulingContent: [], // 排期历史变更记录
       stageImg: stage,
@@ -393,14 +386,26 @@ export default {
       this.isScheduleLocked = res1.data.isScheduleLocked
       this.tips = res1.data.tips
       this.isParentRequireScheduleLocked = res1.data.isParentRequireScheduleLocked
+      this.$refs.taskSchedule.listByTask(this.taskId)
+    },
+    async getSchedule() {
+      this.scheduleVisble = false
+      const res = await scheduleGetTaskScheduleHistory(this.taskId)
+      this.SchedulingContent = res.data
+      const res1 = await listByTask(this.taskId)
+      this.isScheduleLocked = res1.data.isScheduleLocked
+      this.tips = res1.data.tips
+      this.isParentRequireScheduleLocked = res1.data.isParentRequireScheduleLocked
     },
     async clickScheduling(ele) {
+      this.showunlock = false
       this.ScheduId = ele.id
       const res = await scheduleGetHistoryScheduleById(ele.id)
       this.taskScheduleEvent = res.data.schedulDetailResponses
       this.BackToTheLatest = false
     },
     clickBackToTheLatest() {
+      this.showunlock = true
       this.BackToTheLatest = true
       this.lockHide = false
       this.$refs.taskSchedule.listByTask(this.taskId)
@@ -486,7 +491,7 @@ export default {
       }
     },
     async updateStatus(e) { // 状态改变
-      if (e.value === 2 || e.value === 4 || e.value === 5) {
+      if (e.status === 70 || e.status === 90 || e.status === 100) {
         this.taskIds = this.form_query
         this.allStatus.map(item => {
           item.code === e.value ? this.taskIds.statusString = e.label : ''
@@ -514,6 +519,7 @@ export default {
     scheduleHiHide() { // 排期变更显示隐藏
       this.lockHide = !this.lockHide
       this.BackToTheLatest = true
+      this.showunlock = true
       this.ScheduId = ''
     },
     childVal(val) {
@@ -710,5 +716,6 @@ export default {
 }
 .vss {
    border:1px solid #409EFF !important;
+   color:#409EFF !important;
 }
 </style>

+ 419 - 0
src/views/projectManage/version/components/modifySchedule.vue

@@ -0,0 +1,419 @@
+<template>
+  <normal-dialog
+    :show-dialog.sync="show"
+    :title="title"
+    :is-default-close="false"
+    :submit-button="isDeleteStatus?'我知道了,删除':'确定'"
+    :buttom-type="isDeleteStatus?'danger':'primary'"
+    width="55%"
+    @confirm="confirmForm()"
+    @cancel="cancel()"
+  >
+    <article v-if="!isDeleteStatus">
+      <el-form ref="form" :model="form" :rules="form_rules" label-width="100px" :label-position="'left'">
+        <el-form-item label="排期类型" prop="type">
+          <el-select v-model="form.type" clearable placeholder="请选择" style="width: 100%" :disabled="disabled">
+            <el-option v-for="item in taskScheduleEvent" :key="item.code" :label="item.msg" :value="item.code" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="参与人员" prop="peopleList">
+          <search-people :value.sync="form.peopleList" :multiple="true" style="width: 100%" :size="'medium'" :disabled="disabled" />
+        </el-form-item>
+        <el-form-item label="排期" prop="dayList">
+          <div v-show="form.dayList.length > 0 ">{{ schedule }}(用时<span class="blue">{{ detailDayList.length }}</span>天)</div>
+          <div v-show="form.dayList.length <= 0 " class="empty-schedule">添加排期</div>
+          <div v-if="!disabled" class="picker-hidden">
+            <sel-date-picker :start-end.sync="form.dayList" :detail-day-list="detailDayList" @getDetailDay="getDetailDay" />
+          </div>
+        </el-form-item>
+        <el-form-item label="描述">
+          <el-input v-model="form.desc" autocomplete="off" placeholder="请输入问题描述内容..." :disabled="disabled" />
+        </el-form-item>
+        <el-form-item label="关联任务" prop="taskList">
+          <el-select
+            v-model="selectTask"
+            filterable
+            remote
+            reserve-keyword
+            placeholder="请输入任务名称或ID"
+            :remote-method="remoteMethod"
+            :loading="loading"
+            style="width: 100%"
+            :disabled="disabled"
+            @change="tasksChange"
+          >
+            <el-option
+              v-for="item in tasksOptions"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+              :disabled="item.isScheduleLocked === 1"
+            >
+              <div class="Layout_space_between">
+                <span>{{ item.name }}</span>
+                <div :class="item.isScheduleLocked === 1 ? 'el-icon-lock': 'el-icon-unlock'" />
+              </div>
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div class="task-list-show">
+        <div v-for="item in tasksDetailList" :key="'task'+item.id" class="task-list-item">
+          <div v-if="item.taskIdSting" class="item-id">{{ item.taskIdSting }}</div>
+          <div v-if="item.taskId" class="item-id">{{ item.taskId }}</div>
+          <div class="item-name"><span>{{ item.name }}</span></div>
+          <div class="item-qa">测试负责人:<span>{{ item.qaObject !== null?item.qaObject.name: '' }}</span></div>
+          <div class="item-rd">开发负责人:<span>{{ item.rdObject !== null?item.rdObject.name: '' }}</span></div>
+          <i class="el-icon-circle-close item-cancel" @click="cancelTask(item.id)" />
+        </div>
+      </div>
+    </article>
+    <article v-if="isDeleteStatus">
+      <div class="danger-img">
+        <img :src="dangerImg">
+      </div>
+      <div class="delete-title">
+        执行删除后,所有关联任务下的此排期均会被删除,并无法恢复,请谨慎操作!
+      </div>
+      <div class="people-list-show">
+        <p>参与人:</p>
+        <span>{{ peopleObjectList.join(',') }}</span>
+      </div>
+      <div class="task-list-show">
+        <p>关联任务:</p>
+        <div v-for="item in tasksDetailList" :key="'task'+item.id" class="task-list-item">
+          <div v-if="item.taskIdSting" class="item-id">{{ item.taskIdSting }}</div>
+          <div v-if="item.taskId" class="item-id">{{ item.taskId }}</div>
+          <div class="item-name"><span>{{ item.name }}</span></div>
+          <div class="item-qa">测试负责人:<span>{{ item.qaObject !== null?item.qaObject.name: '' }}</span></div>
+          <div class="item-rd">开发负责人:<span>{{ item.rdObject !== null?item.rdObject.name: '' }}</span></div>
+        </div>
+      </div>
+    </article>
+  </normal-dialog>
+</template>
+<script>
+const _ = require('lodash')
+import '@/styles/PublicStyle/index.scss'
+import searchPeople from '@/components/select/searchPeople'
+import normalDialog from '@/components/dialog/normalDialog'
+import selDatePicker from '@/components/picker/SelDatePicker'
+import { taskList } from '@/api/projectIndex'
+import { taskList as allTaskList, configShowTaskEnum } from '@/api/taskIndex'
+import { getSeprateDayInfo, scheduleCreate, scheduleGet, scheduleUpdate, scheduleDelete } from '@/api/projectViewDetails'
+import danger from '@/assets/感叹@2x.png'
+export default {
+  components: {
+    searchPeople,
+    normalDialog,
+    selDatePicker
+  },
+  props: {
+    visible: {
+      type: Boolean,
+      default: false,
+      required: true
+    },
+    title: {
+      type: String,
+      default: '新建排期',
+      required: false
+    },
+    detailData: { // 详细日期
+      type: Object,
+      default: () => null,
+      required: false
+    },
+    selectTaskList: { // 已选任务列表
+      type: Array,
+      default: () => [],
+      required: false
+    },
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false
+    },
+    isDelete: {// 是否删除状态
+      type: Boolean,
+      default: false,
+      required: false
+    }
+  },
+  data() {
+    return {
+      dangerImg: danger,
+      form_rules: {
+        type: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],
+        peopleList: [{ required: true, message: '参与人员不能为空', trigger: 'blur' }],
+        dayList: [{ required: true, message: '排期不能为空', trigger: 'blur' }],
+        taskList: [{ required: true, message: '关联任务不能为空', trigger: 'blur' }]
+      },
+      show: this.visible,
+      isDeleteStatus: this.isDelete,
+      taskScheduleEvent: [],
+      form: {
+        bizId: localStorage.getItem('bizId'),
+        type: '',
+        peopleList: [],
+        taskList: [],
+        desc: '',
+        dayList: [] // 日期列表
+      },
+      detailDayList: [], // 详细的日期
+      schedule: '',
+      selectTask: null, // 选择的任务id
+      tasksOptions: [], // 任务下拉选项
+      tasksDetailList: [], // 已有任务项目
+      loading: false,
+      peopleObjectList: [] // 参与人
+    }
+  },
+  watch: {
+    visible: {
+      handler(newV, old) {
+        this.show = newV
+      },
+      immediate: true
+    },
+    detailData: {
+      handler(newV, old) {
+        if (newV) {
+          this.getScheduleData(newV.id)
+        }
+      },
+      immediate: true
+    },
+    selectTaskList: { // 已选择任务列表
+      handler(newV, old) {
+        if (newV && newV.length > 0) {
+          this.tasksOptions = newV
+          this.tasksDetailList = [...newV]
+          this.form.taskList = newV.map(item => item.id)
+        }
+      },
+      immediate: true
+    },
+    title(newV, oldV) {
+      this.title = newV
+    },
+    isDelete: {
+      handler(newV, old) {
+        this.isDeleteStatus = newV
+      },
+      immediate: true,
+      deep: true
+    }
+  },
+  created() {
+    this.getType()
+    this.getNowTask()
+  },
+  methods: {
+    async getScheduleData(id) { // 当有传入的详细信息的时候
+      const res = await scheduleGet(id)
+      let obj
+      if (res.code === 200) {
+        obj = res.data
+      } else {
+        return false
+      }
+      this.form = {
+        id: obj.id,
+        bizId: localStorage.getItem('bizId'),
+        type: obj.type,
+        peopleList: obj.peopleList || [],
+        taskList: obj.taskObjectList.map(item => item.id),
+        desc: obj.desc,
+        dayList: [obj.dayList[0], obj.dayList[obj.dayList.length - 1]] // 日期列表
+      }
+      this.detailDayList = obj.dayList || []
+      this.schedule = obj.seperateDaysNoHoliday
+      this.tasksDetailList = obj.taskObjectList || []
+      this.peopleObjectList = obj.peopleObjectList.map(item => item.name) || []
+    },
+    async getType() {
+      const resEnum = await configShowTaskEnum()
+      if (resEnum.code === 200) {
+        this.taskScheduleEvent = resEnum.data.taskScheduleEvent
+      }
+    },
+    async getNowTask() { // 获取当前项目下任务
+      const res = await taskList({
+        projectId: this.$route.query.id
+      })
+      if (res.code === 200) {
+        this.tasksOptions = res.data
+      }
+    },
+    async remoteMethod(query) { // 远程搜索任务
+      this.loading = true
+      const res = await allTaskList({
+        bizId: Number(localStorage.getItem('bizId')),
+        name: query
+      })
+      if (res.code === 200) {
+        this.loading = false
+        this.tasksOptions = res.data
+      } else {
+        this.loading = false
+      }
+    },
+    tasksChange(id) { // 任务列表变动
+      const isEx = this.tasksDetailList.find(item => item.id === id)
+      if (isEx) {
+        this.$message({ message: '任务已存在', type: 'warning', duration: 1000, offset: 150 })
+        this.selectTask = null
+        return false
+      }
+      const res = this.tasksOptions.find(item => {
+        return item.id === id
+      })
+      this.tasksDetailList.push(res)
+      this.form.taskList.push(res.id)
+      this.selectTask = null
+    },
+    cancelTask(id) { // 删除单个关联任务
+      if (this.disabled) {
+        return false
+      }
+      this.tasksDetailList = this.tasksDetailList.filter(item => item.id !== id)
+      this.form.taskList = this.form.taskList.filter(item => item !== id)
+    },
+    getDetailDay(e) { // 获取详细排期日期
+      this.detailDayList = e
+      this.getSeprateDayInfo(e)
+    },
+    async getSeprateDayInfo(dataArr) { // 获取选中时间中的工作日时间
+      const res = await getSeprateDayInfo(dataArr)
+      if (res.code === 200) {
+        this.schedule = res.data.seperateDaysNoHoliday
+      }
+    },
+    async scheduleCreate(params) { // 创建排期
+      const res = await scheduleCreate(params)
+      if (res.code === 200) {
+        this.$message({ message: '添加成功', type: 'success', duration: 1000, offset: 150 })
+        this.$emit('update')
+        this.cancel()
+      }
+    },
+    async scheduleUpdate(params) { // 更新排期
+      const res = await scheduleUpdate(params)
+      if (res.code === 200) {
+        this.$message({ message: '更新成功', type: 'success', duration: 1000, offset: 150 })
+        this.$emit('update')
+        this.cancel()
+      }
+    },
+    async scheduleDelete() { // 删除排期
+      const res = await scheduleDelete(this.form.id)
+      if (res.code === 200) {
+        this.$message({ message: '删除成功', type: 'success', duration: 1000, offset: 150 })
+        this.$emit('update')
+        this.cancel()
+      }
+    },
+    confirmForm() { // 确认提交表单
+      if (this.isDeleteStatus) {
+        this.scheduleDelete()
+        return
+      }
+      this.$refs['form'].validate((valid) => {
+        if (valid) {
+          const params = _.cloneDeep(this.form)
+          params.dayList = this.detailDayList
+          params.id ? this.scheduleUpdate(params) : this.scheduleCreate(params)
+        }
+      })
+    },
+    cancel() { // 关闭弹框
+      this.show = false
+      this.isDeleteStatus = false
+      this.$emit('update:visible', this.show)
+      this.$emit('update:isDelete', this.isDeleteStatus)
+    }
+  }
+}
+</script>
+<style scoped lang="scss">
+article {
+  max-height: 60vh;
+  overflow: scroll;
+    .blue {
+    color: #409EFF;
+  }
+}
+>>>.el-form {
+  padding: 0 156px 0 60px;
+}
+.picker-hidden {
+  opacity: 0;
+  position: absolute;
+  top: 0;
+}
+.empty-schedule {
+  color:rgba(51,51,51,0.45);
+}
+.task-list-show {
+  width: 100%;
+  padding: 0 60px;
+  .task-list-item {
+    width: 100%;
+    display: flex;
+    margin: 10px 0;
+    .item-id {
+      width: 15%;
+    }
+    .item-name {
+      width: 40%;
+    }
+    .item-qa {
+      width: 20%;
+    }
+    .item-rd {
+      width: 20%;
+    }
+    .item-cancel {
+      font-size: 20px;
+    }
+    div {
+      overflow: hidden;
+      text-overflow:ellipsis;
+      white-space: nowrap;
+    }
+  }
+}
+.danger-img {
+  width: 100%;
+  padding: 0 60px 50px 60px;
+  margin-bottom: 50px;
+  position: relative;
+  img {
+    height: 50px;
+    width: 50px;
+    position: absolute;
+    left: 50%;
+    transform: translate(-50%,0);
+  }
+}
+.delete-title {
+  width: 100%;
+  padding: 0 60px 100px 60px;
+  color: #333B4A;
+  font-size: 18px;
+  text-align: center;
+}
+.people-list-show {
+  width: 100%;
+  padding: 0 60px 50px 60px;
+  p {
+    color: #666666;
+    font-size: 14px;
+    margin-bottom: 20px;
+  }
+  span {
+    color: #333333;
+  }
+}
+</style>

+ 255 - 0
src/views/projectManage/version/components/scheduleList.vue

@@ -0,0 +1,255 @@
+<template>
+  <div class="schedule-list">
+    <!-- <el-col align="right" class="add-schedule"><span @click="addSchedule()"><i class="el-icon-circle-plus-outline" />添加排期</span></el-col> -->
+    <el-table
+      :id="'schedule-'+id"
+      :data="scheduleList"
+      :header-cell-style="{ backgroundColor: 'rgba(232,232,232,0.4)',color: 'rgb(74, 74, 74)', fontSize: '14px', fontWeight: '500'}"
+      :row-style="{'background-color': 'transparent'}"
+      style="width: 100%"
+      show-overflow-tooltip="true"
+      row-key="id"
+    >
+      <el-table-column
+        width="80"
+        align="center"
+      >
+        <template>
+          <el-tooltip class="item" effect="dark" content="代表移动,鼠标选中区域可以向上移动" placement="bottom">
+            <div class="sortable-tip">
+              <img :src="move">
+            </div>
+          </el-tooltip>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="type"
+        label="类型"
+        width="100"
+        align="center"
+      >
+        <template slot-scope="scope">
+          {{ getType(scope.row.type) }}
+          <div :class="scope.row.isScheduleLocked === 0 ? 'el-icon-unlock' : 'el-icon-lock'" />
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="desc"
+        label="描述"
+        min-width="150"
+        align="left"
+        show-overflow-tooltip
+      />
+      <el-table-column
+        prop="seperateDaysNoHoliday"
+        label="排期"
+        min-width="200"
+        align="center"
+        show-overflow-tooltip
+      />
+      <el-table-column
+        prop="dayLength"
+        label="时长"
+        width="50"
+        align="center"
+      />
+      <el-table-column
+        prop="peopleList"
+        label="参与人员"
+        min-width="100"
+        align="center"
+      />
+      <el-table-column
+        label="操作"
+        width="200"
+        align="center"
+        show-overflow-tooltip
+      >
+        <template slot-scope="scope">
+          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="editSchedule(scope.row)">编辑</el-button>
+          <el-button v-if="scope.row.isScheduleLocked === 0" type="text" size="small" @click="deleteSchedule(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+
+    </el-table>
+    <div class="bottom-detail">
+      <el-row>排期总汇:{{ scheduleDetail.startTime | handlerDate }} ~ {{ scheduleDetail.endTime | handlerDate }}</el-row>
+      <el-row v-if="scheduleDetail.preOnlineVersion && scheduleDetail.preOnlineVersion.length>0">
+        <el-col :span="2">预计上线版本:</el-col>
+        <el-col :span="6">
+          <span v-for="item in scheduleDetail.preOnlineVersion" :key="item">{{ item }}</span><br>
+        </el-col>
+      </el-row>
+      <el-row v-else>预计上线版本:</el-row>
+    </div>
+    <modify-schedule
+      v-if="visibleSchedule"
+      :visible.sync="visibleSchedule"
+      :is-delete.sync="isDelete"
+      :detail-data="detailData"
+      :title="DialogTitle"
+      @update="listByTask(id)"
+    />
+  </div>
+</template>
+<script>
+import Sortable from 'sortablejs'
+import moment from 'moment'
+import 'moment/locale/zh-cn'
+import { listByTask, sortForTask } from '@/api/projectViewDetails'
+import modifySchedule from './modifySchedule'
+import move from '@/assets/麻将@2x.png'
+export default {
+  components: {
+    modifySchedule
+  },
+  filters: {
+    handlerDate(val) {
+      return val ? moment(val).format('YYYY-MM-DD') : ''
+    }
+  },
+  props: {
+    id: {
+      type: Number,
+      default: NaN,
+      required: true
+    },
+    typeList: {
+      type: Array,
+      default: () => [],
+      required: false
+    }
+  },
+  data() {
+    return {
+      move: move,
+      scheduleList: [],
+      scheduleDetail: {},
+      visibleSchedule: false,
+      detailData: null,
+      taskScheduleEvent: [], // 排期类型
+      DialogTitle: '新建排期',
+      isDelete: false // 删除排期操作
+    }
+  },
+  watch: {
+    id: {
+      handler(newV, oldV) {
+        this.listByTask(newV)
+      },
+      immediate: true
+    },
+    typeList: {
+      handler(newV, oldV) {
+        this.taskScheduleEvent = newV
+      },
+      immediate: true
+    }
+  },
+  mounted() {
+    this.rowDrop()
+  },
+  methods: {
+    rowDrop() {
+      const tbody = document.querySelector(`#schedule-${this.id} tbody`)
+      const _this = this
+      Sortable.create(tbody, {
+        onEnd({ newIndex, oldIndex }) {
+          const currRow = _this.scheduleList.splice(oldIndex, 1)[0]
+          _this.scheduleList.splice(newIndex, 0, currRow)
+          _this.sortForTask(_this.scheduleList.map(item => item.id))
+        }
+      })
+    },
+    async sortForTask(arr) {
+      const res = await sortForTask(this.id, arr)
+      if (res.code === 200) {
+        this.$message({ message: 'success', type: 'success', duration: 1000, offset: 150 })
+      }
+    },
+    getType(value) {
+      const res = this.taskScheduleEvent.find(item => item.code === value) || {}
+      return res.msg
+    },
+    async listByTask(id) { // 获取排期列表
+      const res = await listByTask(id)
+      if (res.code === 200) {
+        this.scheduleList = res.data.schedulDetailResponses
+        this.scheduleDetail = res.data || {}
+        this.scheduleList = this.scheduleList.map(item => ({
+          ...item,
+          peopleList: item.peopleObjectList.map(item => item.name).join(',')
+        }))
+      }
+    },
+    addSchedule() {
+      this.detailData = null
+      this.DialogTitle = '新建排期'
+      this.visibleSchedule = true
+    },
+    deleteSchedule(row) { // 删除排期
+      this.DialogTitle = '删除排期'
+      this.isDelete = true
+      this.visibleSchedule = true
+      this.detailData = row
+    },
+    editSchedule(row) { // 编辑排期
+      this.DialogTitle = '编辑排期'
+      this.visibleSchedule = true
+      this.detailData = row
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.add-schedule {
+  cursor: pointer;
+  color: #409EFF;
+  font-size: 14px;
+  width: calc(100% - 40px);
+  margin: 0 20px;
+  padding: 20px 0;
+  i {
+    margin-right: 4px;
+  }
+  span {
+    margin-right: 20px;
+  }
+}
+.schedule-list {
+  width: calc(100% - 40px);
+  margin: 0 20px;
+  padding: 0;
+  background:rgba(248,248,248,0.6);
+}
+>>>.el-table, .el-table__expanded-cell{
+  background:rgba(248,248,248,0.6);
+}
+.bottom-detail {
+  font-size: 14px;
+  width: calc(100% - 40px);
+  margin: 0 20px;
+  padding: 20px 0;
+  :first-child {
+    margin-bottom: 10px;
+  }
+}
+.sortable-tip {
+  height: 26px;
+  width: 15px;
+  border-radius:2px;
+  margin: auto;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  img {
+    width: 8px;
+  }
+}
+</style>
+<style>
+.el-tooltip__popper.is-dark {
+  background:rgba(121,132,150,0.8);
+  color: #FFF;
+}
+</style>

+ 521 - 0
src/views/projectManage/version/components/taskList.vue

@@ -0,0 +1,521 @@
+<template>
+  <div>
+    <el-row v-if="!showHeader" class="select-main" type="flex" align="center">
+      <el-col :span="2" class="flex-align-center">
+        <el-checkbox v-model="planChecked" class="plan-checked" @change="changeCheck" />
+      </el-col>
+      <el-col :span="3" class="item-checked">已选择<span style="color: #409EFF">{{ curcentChecked }}</span>个</el-col>
+      <el-col :span="1" class="item-line">|</el-col>
+      <el-col :span="2" class="item-click" @click.native="addSechedule()"><img :src="imgUrl">添加排期</el-col>
+      <el-col :span="2" class="item-click" @click.native="handlePlan('test')"><img :src="imgUrl">提测</el-col>
+      <el-col :span="2" class="item-click" @click.native="handlePlan('allow')"><img :src="imgUrl">准出</el-col>
+      <el-col :span="4" class="item-click" @click.native="handlePlan('daily')"><img :src="imgUrl">建立测试日报</el-col>
+      <el-col :span="4" class="item-click" @click.native="handlePlan('cancel')">取消选择</el-col>
+    </el-row>
+    <el-table
+      ref="planTable"
+      :data="all_task"
+      style="width: 100%;"
+      size="mini"
+      row-key="id"
+      :expand-row-keys="expandArr"
+      :header-cell-style="{ color: 'rgb(74, 74, 74)', fontSize: '14px', fontWeight: '500'}"
+      :row-style="{ fontSize: '14px' }"
+      show-overflow-tooltip="true"
+      :show-header="showHeader"
+      :header-row-style="{height: '50px'}"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column type="expand" width="40">
+        <template slot="header">
+          <div class="expand"><i v-show="!allChange" class="el-icon-plus" @click="expandAll(true)" /></div>
+          <div class="expand"><i v-show="allChange" class="el-icon-minus" @click="expandAll(false)" /></div>
+        </template>
+        <template slot-scope="props">
+          <schedule-list :id="props.row.id" :type-list="taskScheduleEvent" />
+        </template>
+      </el-table-column>
+      <el-table-column label="优先级" prop="priority" width="90" sortable align="center">
+        <template slot-scope="scope" style="text-align: center;">
+          <span class="div_priority" :class="scope.row.priorityString">
+            {{ scope.row.priorityString }}
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="任务名称" width="200" align="left" show-overflow-tooltip>
+        <template slot-scope="scope">
+          <div class="task-main">
+            <span class="task-id">TASK-{{ scope.row.id }}</span>
+            <span class="task-title" @click="link_task(scope.row.id)">{{ scope.row.name }}</span>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="所属模块" width="150" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">{{ scope.row.moduleInfoName }}</template>
+      </el-table-column>
+      <el-table-column label="状态" width="105" align="center">
+        <template slot-scope="scope">
+          <el-select
+            v-model="scope.row.status"
+            :class="{'status0':scope.row.status===0,'status1':scope.row.status > 0 && scope.row.status <100,'status2':scope.row.status===100,}"
+            class="btns"
+            size="mini"
+            @change="changeStatus(scope.row)"
+          >
+            <el-option v-for="item in allStatus" :key="item.code" :label="item.msg" :value="item.code" />
+          </el-select>
+        </template>
+      </el-table-column>
+      <el-table-column label="所属需求" width="200" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">{{ scope.row.requireName }}</template>
+      </el-table-column>
+      <el-table-column label="跟版客户端" width="120" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">{{ scope.row.involveAppString || '无' }}</template>
+      </el-table-column>
+      <el-table-column label="开发负责人" width="100" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">{{ scope.row.rdObject ? scope.row.rdObject.name : '' }}</template>
+      </el-table-column>
+      <el-table-column label="测试负责人" width="100" align="center" show-overflow-tooltip>
+        <template slot-scope="scope">{{ scope.row.qaObject ? scope.row.qaObject.name : '' }}</template>
+      </el-table-column>
+      <el-table-column label="任务进度" min-width="150" align="center">
+        <template slot-scope="scope">
+          <el-progress :percentage="Number(scope.row.rate && scope.row.rate.substring(0,4))" color="#409eff" />
+        </template>
+      </el-table-column>
+    </el-table>
+    <TestReport v-if="dialogTestReport" ref="TestReport" />
+    <DailyReport v-if="dialogDailyReport" ref="DailyReport" />
+    <ClientReport v-if="dialogClientReport" ref="ClientReport" />
+    <taskDialog v-if="showTaskDialog" :show.sync="showTaskDialog" :task-id="taskId.id" :status-name="taskId.statusString" @getList="get_allTask" />
+    <!-- 批量排期 -->
+    <modify-schedule
+      v-if="visibleSchedule"
+      :visible.sync="visibleSchedule"
+      :select-task-list="selectTaskList"
+      title="新建排期"
+      @update="get_allTask()"
+    />
+  </div>
+</template>
+<script>
+import imgUrl from '@/assets/建立档案@2x.png'
+import '@/styles/PublicStyle/index.scss'
+import TestReport from '@/views/Platform/presentation/Templates/TestReport' // 提测
+import DailyReport from '@/views/Platform/presentation/Templates/DailyReport' // 日报
+import ClientReport from '@/views/Platform/presentation/Templates/ClientReport' // 准出
+import { taskList } from '@/api/projectIndex'
+import { taskUpdate } from '@/api/projectViewDetails'
+import { configShowTaskEnum } from '@/api/taskIndex'
+import scheduleList from './scheduleList'
+import modifySchedule from './modifySchedule'
+import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
+export default {
+  components: {
+    TestReport,
+    DailyReport,
+    ClientReport,
+    scheduleList,
+    taskDialog,
+    modifySchedule
+  },
+  data() {
+    return {
+      imgUrl: imgUrl,
+      tableList: [], // 排期bable验证
+      changeData: new Map(),
+      allChange: false, // 是否全展开
+      expandArr: [], // 展开行数组
+      showTaskDialog: false, // 状态弹窗
+      all_task: [], // 任务列表
+      allStatus: [], // 任务所有状态
+      taskScheduleEvent: [], // 排期类型
+      showHeader: true, // 任务列表的表头是否显示
+      curcentList: [], // 当前已选择的列表
+      curcentChecked: 0, // 当前已选择的数量
+      planChecked: false,
+      planHandleType: '', // 任务列表操作类型
+      dialogTestReport: false, // 提测
+      dialogDailyReport: false, // 日报
+      dialogClientReport: false, // 准出
+      changeStatusDate: null, // 状态改变时间
+      nowChangeTask: null, // 当前正在改变的任务对象
+      taskId: '', // 将要修改状态的任务id
+      visibleSchedule: false, // 排期弹框
+      selectTaskList: [] // 已选任务的id
+    }
+  },
+  created() {
+    this.getTaskStatus()
+    this.get_allTask()
+  },
+  methods: {
+    async get_allTask() { // 获取全部任务
+      const res = await taskList({
+        projectId: this.$route.query.id
+      })
+      if (res.code === 200) {
+        this.all_task = res.data
+      }
+    },
+    async getTaskStatus() { // 获取任务状态列表
+      const res = await configShowTaskEnum()
+      if (res.code === 200) {
+        this.allStatus = res.data.taskStatus
+        this.taskScheduleEvent = res.data.taskScheduleEvent || []
+      }
+    },
+    changeCheck(val) {
+      if (val) {
+        this.all_task.forEach(row => {
+          this.$refs.planTable.toggleRowSelection(row, true)
+        })
+      } else {
+        this.$refs.planTable.clearSelection()
+      }
+    },
+    expandAll(isEx) { // 全部展开
+      this.allChange = isEx
+      isEx ? this.expandArr = this.all_task.map(item => item.id) : this.expandArr = []
+    },
+    async changeStatus(e) { // 状态改变
+      if (e.status === 70 || e.status === 90 || e.status === 100) {
+        this.taskId = e
+        this.allStatus.map(item => {
+          item.code === e.status ? this.taskId.statusString = item.msg : ''
+        })
+        this.showTaskDialog = true
+        this.nowChangeTask = e
+        return
+      } else {
+        const user = {
+          name: localStorage.getItem('username'),
+          ename: localStorage.getItem('realname'),
+          id: ''
+        }
+        const taskInfoDO = e
+        const resTask = await taskUpdate({ taskInfoDO, user })
+        if (resTask.code === 200) {
+          this.$message({ message: '修改成功', type: 'success', offset: 150 })
+        }
+      }
+    },
+    async confirmStatus() { // 确认更改状态
+      const user = { name: localStorage.getItem('username'), ename: localStorage.getItem('realname'), id: '' }
+      const taskInfoDO = this.nowChangeTask
+      taskInfoDO.onlineRealTime = this.changeStatusDate
+      const resTask = await taskUpdate({ taskInfoDO, user })
+      if (resTask.code === 200) {
+        this.$message({ message: '修改成功', type: 'success', offset: 150 })
+      }
+    },
+    handleSelectionChange(val) { // 任务列表删选操作
+      this.tableList = []
+      this.tableList = val
+      val.length > 0 ? this.showHeader = false : this.showHeader = true
+      this.curcentChecked = val.length
+      this.curcentList = val
+      if (val.length === this.all_task.length) {
+        this.planChecked = true
+      }
+    },
+    handlePlan(type) { // 任务列表操作
+      this.planHandleType = type
+      switch (type) {
+        case 'test':
+          this.filtrateTest()
+          break
+        case 'allow':
+          this.filtrateAllow()
+          break
+        case 'daily':
+          this.filtrateDaily()
+          break
+        case 'cancel':
+          this.$refs.planTable.clearSelection()
+          break
+      }
+    },
+    addSechedule() { // 添加排期
+      const taskA = []
+      this.tableList.map(item => {
+        if (item.isScheduleLocked === 1) {
+          taskA.push(item.taskIdSting)
+        }
+      })
+      if (taskA.length !== 0) {
+        this.$message({ message: '任务 ' + taskA + ' 的排期已锁定,请先解锁排期后再添加排期', type: 'warning', offset: 150 })
+        return
+      }
+      this.visibleSchedule = true
+      this.selectTaskList = this.curcentList
+    },
+    filtrateTest() { // 提测筛选
+      this.dialogTestReport = true
+      this.$nextTick(() => {
+        this.$refs.TestReport.init(7, this.curcentList.map(item => { return item.id }))
+      })
+    },
+    filtrateAllow() { // 准出筛选
+      this.dialogClientReport = true
+      this.$nextTick(() => {
+        this.$refs.ClientReport.init(7, this.curcentList.map(item => { return item.id }))
+      })
+    },
+    filtrateDaily() { // 建立日报
+      this.dialogDailyReport = true
+      this.$nextTick(() => {
+        this.$refs.DailyReport.init(7, this.curcentList.map(item => { return item.id }))
+      })
+    },
+    link_task(id) { // 跳转到任务详情页
+      this.$router.push({ name: '任务详情', query: { id: id }})
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+@mixin setStatus($color) {
+  input {
+    color:$color;
+    border: 1px solid $color;
+  }
+  >>> .el-select__caret{
+    color:$color;
+  }
+  >>> .el-input__inner{
+    color:$color;
+    border-color: $color;
+  }
+  >>> .el-input__inner:focus {
+    border-color: $color;
+  }
+}
+>>>.el-row .el-col {
+  margin: 10px 0;
+}
+.task-main {
+  display: flex;
+  flex-direction: column;
+  .task-title {
+    cursor: pointer;
+    color: #666666;
+    font-size: 14px;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  .task-id {
+    color: #A7AEBC;
+    font-size: 10px;
+  }
+}
+.P0 {
+  background-color: #F56C6C;
+}
+.P1 {
+  background-color: #FF8952;
+}
+.P2 {
+  background-color: #F5E300;
+}
+.P3 {
+  background-color: #7ED321;
+}
+.P4 {
+  background-color: #61D3B8;
+}
+.P5 {
+  background-color: #69B3FF;
+}
+.P6 {
+  background-color: #BDBDBD;
+}
+.status0 {
+  @include setStatus(#409EFF)
+}
+.status1{
+  @include setStatus(#FF8952)
+}
+.status2 {
+  @include setStatus(#7ED321)
+}
+.expand i {
+  border:1px solid #DCDFE6;
+}
+>>>.el-table__expand-icon{
+  font-size: 14px;
+  .el-icon{
+    margin: 0;
+    transform: translate(-50%, -50%);
+    border:1px solid #DCDFE6;
+  }
+}
+>>>.el-table__expand-icon .el-icon-arrow-right::before{
+  content: "\E6D9";
+}
+>>>.el-table__expand-icon--expanded .el-icon-arrow-right::before{
+  content: "\E6D8";
+}
+>>>.el-table__expand-icon--expanded {
+  transform: rotate(180deg);
+}
+>>>.el-table__expanded-cell {
+  background-color: #FFFFFF;
+  padding: 0;
+}
+>>>.el-table__expanded-cell:hover {
+  background-color: #FFFFFF !important;
+}
+.div_priority {
+  text-align: center;
+  color: #ffffff;
+  padding: inherit;
+  border-radius: 4px;
+  width: 40px;
+  display: inline-block;
+}
+.plan-checked {
+  padding-left: 21px;
+}
+.select-main {
+  height: 50px;
+  border-bottom: 1px solid #DCDFE6;
+  .flex-align-center {
+    display: flex;
+    align-items: center;
+  }
+  .item-checked {
+    width: auto;
+    margin-right: 28px;
+    color: #606266;
+    font-size: 14px;
+    display: flex;
+    align-items: center;
+    justify-content: left;
+    cursor: pointer;
+  }
+  .item-click,.item-line{
+    margin: 0;
+    width: auto;
+    color: #666666;
+    font-size: 14px;
+    display: flex;
+    align-items: center;
+    cursor: pointer;
+    margin-right: 28px;
+    img {
+      height: 13.5px;
+      widows: 13.5px;
+      margin-right: 5px;
+    }
+  }
+  .item-line {
+    color:rgba(102,102,102,0.6);
+  }
+  .cancel {
+    position: absolute;
+    right: 0;
+    top: 50%;
+    transform: translateY(-50%);
+  }
+}
+.descr {
+  display: flex;
+  justify-content: flex-start;
+}
+.planList >>> .el-table th>.cell {
+  padding-left: 14px;
+  padding-right: 14px;
+}
+.dialog-change-status {
+  margin: 2% 3%;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  white-space:nowrap;
+}
+</style>
+<style lang="scss">
+.btns .el-input--suffix .el-input__inner {
+  padding-right: 10px;
+  padding-left: 10px;
+  width: 73px;
+}
+.item{
+  /deep/ input {
+    color: rgb(126, 211, 33);
+    border: 1px solid rgb(126, 211, 33);
+     border-color: rgb(126, 211, 33) !important;
+         font-weight: 900;
+  }
+  /deep/ .el-input__suffix {
+    color: rgb(126, 211, 33) !important;
+    right: 1px;
+  }
+  /deep/ .el-select__caret {
+    color: rgb(126, 211, 33) !important;
+  }
+}
+.item1 {
+  /deep/ input {
+    color: rgb(255, 204, 102);
+     border: 1px solid rgb(255, 204, 102);
+     border-color: rgb(255, 204, 102) !important;
+         font-weight: 900;
+  }
+  /deep/ .el-input__suffix {
+    color: rgb(255, 204, 102) !important;
+    right: 1px;
+  }
+  /deep/ .el-select__caret {
+    color: rgb(255, 204, 102) !important;
+  }
+}
+.item2 {
+  /deep/ input {
+    color: rgb(245, 108, 108);
+    border: 1px solid rgb(245, 108, 108);
+    border-color: rgb(245, 108, 108) !important;
+        font-weight: 900;
+  }
+   /deep/ .el-input__suffix {
+    color: rgb(245, 108, 108) !important;
+    right: 1px;
+  }
+  /deep/ .el-select__caret {
+   color: rgb(245, 108, 108) !important;
+  }
+}
+.item3 {
+  /deep/ input {
+    color: #D675F0;
+    border: 1px solid #D675F0;
+    border-color: #D675F0 !important;
+        font-weight: 900;
+  }
+    /deep/ .el-input__suffix {
+    color: #D675F0 !important;
+    right: 1px;
+  }
+   /deep/ .el-select__caret {
+   color: #D675F0 !important;
+  }
+}
+.item-color {
+  /deep/ input {
+    color: rgb(106, 180, 255);
+    border: 1px solid rgb(106, 180, 255);
+    border-color: rgb(106, 180, 255) !important;
+        font-weight: 900;
+  }
+    /deep/ .el-input__suffix {
+    color: rgb(106, 180, 255) !important;
+    right: 1px;
+  }
+   /deep/ .el-select__caret {
+   color: rgb(106, 180, 255) !important;
+  }
+}
+</style>

+ 79 - 93
src/views/projectManage/version/list/index.vue

@@ -12,15 +12,7 @@
         <el-row>
           <el-col :span="20" style="padding-left:15px">
             <span class="queryName">客户端</span>
-            <el-select
-              v-model="searchForm.clientType"
-              size="small"
-              style="padding-left: 2px;"
-              clearable
-              filterable
-              placeholder="请选择"
-              @change="onChangeClientType(searchForm.clientType);getVersionHomePageList()"
-            >
+            <el-select v-model="searchForm.clientType" size="small" style="padding-left: 2px;" clearable filterable placeholder="请选择" @change="onChangeClientType(searchForm.clientType);getVersionHomePageList()">
               <el-option
                 v-for="item in searchInfo.clients"
                 :key="item.code"
@@ -38,12 +30,7 @@
               placeholder="请选择"
               @change="onChangeVersionType(searchForm.versionType);getVersionHomePageList()"
             >
-              <el-option
-                v-for="item in searchInfo.versions"
-                :key="item.code"
-                :label="item.msg"
-                :value="item.code"
-              />
+              <el-option v-for="item in searchInfo.versions" :key="item.code" :label="item.msg" :value="item.code" />
             </el-select>
           </el-col>
           <el-col :span="4">
@@ -54,85 +41,75 @@
           <time-line :steps="timeLineSteps" />
         </div>
       </el-main>
-      <div class="layout_main version_list_layout_main">
-        <el-row>
-          <el-col :span="24">
-            <el-table
-              v-loading="loading"
-              :data="tableData"
-              style="width: 100%;"
-              highlight-current-row
-              :header-cell-style="{ color: '#4A4A4A', fontSize: '14px', fontWeight: '500' }"
-            >
-              <el-table-column prop="priority" label="优先级" min-width="7%" align="center">
-                <template v-slot="scope">
-                  <div class="div_priority" :style="{background: priorityColors[scope.row.priority%priorityColors.length]}">{{ 'P'+scope.row.priority }}</div>
-                  <div :class="[{ active: isActive=='h' }, { active1: isActive=='l' },{ active1: isActive=='l' }]" />
-                </template>
-              </el-table-column>
-              <el-table-column prop="requirementName" label="需求名称" min-width="33%">
-                <template v-slot="scope">
-                  <div class="biz-id">REQUIREMENT-{{ scope.row.requirementId }}</div>
-                  <div>
-                    <el-tooltip class="item" effect="dark" placement="bottom" :content="scope.row.requirementName" :disabled="scope.row.requirementName.length < 16">
-                      <div style="cursor: pointer;" @click="getToRequirementDetails(scope.row.requirementId)">
-                        {{ getRequirementName(scope.row.requirementName) }}
-                        <!-- <div v-if="scope.row.delay" class="div_requirement_name">{{ searchTitle.version +'版本已延期' }}</div> -->
+      <div class="layout_main version_list_layout_main" style="padding: 1%;">
+        <el-tabs v-model="activeName" @tab-click="handleClick">
+          <el-tab-pane label="需求" name="first">
+            <el-row>
+              <el-col :span="24">
+                <el-table v-loading="loading" :data="tableData" style="width: 100%;" highlight-current-row :header-cell-style="{ color: '#4A4A4A', fontSize: '14px', fontWeight: '500' }">
+                  <el-table-column prop="priority" label="优先级" min-width="7%" align="center">
+                    <template v-slot="scope">
+                      <div class="div_priority" :style="{background: priorityColors[scope.row.priority%priorityColors.length]}">{{ 'P'+scope.row.priority }}</div>
+                      <div :class="[{ active: isActive=='h' }, { active1: isActive=='l' },{ active1: isActive=='l' }]" />
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="requirementName" label="需求名称" min-width="33%">
+                    <template v-slot="scope">
+                      <div class="biz-id">REQUIREMENT-{{ scope.row.requirementId }}</div>
+                      <div>
+                        <el-tooltip class="item" effect="dark" placement="bottom" :content="scope.row.requirementName" :disabled="scope.row.requirementName.length < 16">
+                          <div style="cursor: pointer;" @click="getToRequirementDetails(scope.row.requirementId)">
+                            {{ getRequirementName(scope.row.requirementName) }}
+                            <!-- <div v-if="scope.row.delay" class="div_requirement_name">{{ searchTitle.version +'版本已延期' }}</div> -->
+                          </div>
+                        </el-tooltip>
                       </div>
-                    </el-tooltip>
-                  </div>
-                  <div class="pm-status">
-                    <span>PM:{{ scope.row.pmName }}</span>
-                    <span>状态:{{ versionEnum.requirementStatusMap[scope.row.status] }}</span>
-                  </div>
-                </template>
-              </el-table-column>
-              <!-- <el-table-column prop="bizId" label="业务线" min-width="8%">
-            <template v-slot="scope">
-              {{ versionEnum.bizTypeMap[scope.row.bizId] }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="pmName" label="PM" min-width="10%" />
-          <el-table-column prop="status" label="状态" min-width="8%">
-            <template v-slot="scope">
-              {{ versionEnum.requirementStatusMap[scope.row.status] }}
-            </template>
-          </el-table-column> -->
-              <el-table-column prop="statusInfoCountList" label="任务状态分布" min-width="30%" align="center">
-                <template v-slot="scope">
-                  <version-chart
-                    :chart-id="'taskCount' + scope.$index"
-                    :option="taskOptionList[scope.$index]"
-                    style="position: relative;bottom: 30px"
-                  />
-                </template>
-              </el-table-column>
-              <el-table-column prop="statusInfoHealthyList" label="任务健康分布" min-width="30%" align="center">
-                <template v-slot="scope">
-                  <version-chart
-                    :chart-id="'taskHealthCount' + scope.$index"
-                    :option="taskHealthOptionList[scope.$index]"
-                    style="position: relative;bottom: 30px"
+                      <div class="pm-status">
+                        <span>PM:{{ scope.row.pmName }}</span>
+                        <span>状态:{{ versionEnum.requirementStatusMap[scope.row.status] }}</span>
+                      </div>
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="statusInfoCountList" label="任务状态分布" min-width="30%" align="center">
+                    <template v-slot="scope">
+                      <version-chart
+                        :chart-id="'taskCount' + scope.$index"
+                        :option="taskOptionList[scope.$index]"
+                        style="position: relative;bottom: 30px"
+                      />
+                    </template>
+                  </el-table-column>
+                  <el-table-column prop="statusInfoHealthyList" label="任务健康分布" min-width="30%" align="center">
+                    <template v-slot="scope">
+                      <version-chart
+                        :chart-id="'taskHealthCount' + scope.$index"
+                        :option="taskHealthOptionList[scope.$index]"
+                        style="position: relative;bottom: 30px"
+                      />
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </el-col>
+              <el-col :span="24">
+                <div align="right">
+                  <el-pagination
+                    background
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :current-page="searchForm.curIndex"
+                    :page-size="searchForm.pageSize"
+                    :page-sizes="[15,30,45]"
+                    :total="total"
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
                   />
-                </template>
-              </el-table-column>
-            </el-table>
-          </el-col>
-          <el-col :span="24">
-            <div align="right">
-              <el-pagination
-                background
-                layout="total, sizes, prev, pager, next, jumper"
-                :current-page="searchForm.curIndex"
-                :page-size="searchForm.pageSize"
-                :page-sizes="[15,30,45]"
-                :total="total"
-                @size-change="handleSizeChange"
-                @current-change="handleCurrentChange"
-              />
-            </div>
-          </el-col>
-        </el-row>
+                </div>
+              </el-col>
+            </el-row>
+          </el-tab-pane>
+          <el-tab-pane label="任务" name="second">
+            <tasks-list />
+          </el-tab-pane>
+        </el-tabs>
       </div>
     </div>
   </el-container>
@@ -142,16 +119,19 @@
 import TimeLine from './timeLine'
 import { getEvent } from '@/api/versionsCalendar'
 import { getVersionHomePageList, showAppClientEnum, showVersionEnum } from '@/api/version.js'
+import tasksList from '../components/taskList'
 
 import VersionChart from '@/components/chart/index.vue'
 
 export default {
   components: {
     VersionChart,
-    TimeLine
+    TimeLine,
+    tasksList
   },
   data() {
     return {
+      activeName: 'first', // 默认展示需求
       timeLineSteps: [],
       timeLineShow: false,
       priorityColors: ['#F56C6C', '#FF8952', '#F5E300', '#7ED321', '#61D3B8', '#69B3FF', '#BDBDBD'],
@@ -325,6 +305,12 @@ export default {
       taskHealthOptionList: []
     }
   },
+  created() {
+    this.$store.state.data.status = true
+  },
+  destroyed() {
+    this.$store.state.data.status = false
+  },
   mounted() {
     this.showAppClientEnum()
     this.showVersionEnum()

+ 1 - 5
src/views/workbench/person/components/calenderDetail.vue

@@ -1,7 +1,7 @@
 <template>
   <article v-show="showDetail" ref="show-schedule-detail" class="show-schedule-detail">
     <template v-if="nowDetailData && nowDetailData.origin === 0">
-      <div class="detail-title"><img :src="nowDetailData.isScheduleLocked === 1 ? lock: Unlock" style="width: 13px;padding-bottom: 1px;">【任务排期】{{ nowDetailData.bizName }}. {{ nowDetailData.name }}:{{ nowDetailData.desc }}</div>
+      <div class="detail-title"> <div :class="nowDetailData.isScheduleLocked === 1 ? 'el-icon-lock': 'el-icon-unlock'" />【任务排期】{{ nowDetailData.bizName }}. {{ nowDetailData.name }}:{{ nowDetailData.desc }}</div>
       <div class="detail-time item">
         <div class="label">排期:</div>
         <div>{{ nowDetailData.seperateDaysNoHoliday }}(用时<span>{{ nowDetailData.needDays }}</span>天)</div>
@@ -35,8 +35,6 @@
   </article>
 </template>
 <script>
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 export default {
   filters: {
     arrToString(val) {
@@ -62,8 +60,6 @@ export default {
   },
   data() {
     return {
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       showDetail: this.show,
       nowDetailData: this.data
     }

+ 1 - 6
src/views/workbench/person/components/calenderList.vue

@@ -43,8 +43,7 @@
       <el-table-column label="日程名称" prop="name" width="250" align="center" show-overflow-tooltip>
         <template slot-scope="scope">
           {{ scope.row.name }}
-          <img v-if="scope.row.isScheduleLocked === 1" :src="lock" style="width: 11px;margin-left: 10px;padding-bottom: 1px;">
-          <img v-if="scope.row.isScheduleLocked === 0" :src="Unlock" style="width: 13px;margin-left: 10px;padding-bottom: 1px;">
+          <div :class="scope.row.isScheduleLocked === 1 ? 'el-icon-lock': 'el-icon-unlock'" />
         </template>
       </el-table-column>
       <el-table-column label="日期" min-width="250" align="center" show-overflow-tooltip>
@@ -105,8 +104,6 @@
 <script>
 import moment from 'moment'
 import { queryWorkList, queryIdleList } from '@/api/workSchedule.js'
-import lock from '@/assets/lock.png' // 排期锁定图标
-import Unlock from '@/assets/Unlock.png' // 排期锁定图标
 export default {
   filters: {
     peopleListHandler(val) {
@@ -127,8 +124,6 @@ export default {
   },
   data() {
     return {
-      Unlock: Unlock, // 解锁排期
-      lock: lock, // 锁定排期
       total: 0,
       pages: {
         curIndex: 1,

+ 19 - 15
src/views/workbench/team/components/taskList.vue

@@ -52,7 +52,7 @@
         <template slot-scope="scope">
           <el-select
             v-model="scope.row.status"
-            :class="'status'+scope.row.status"
+            :class="{'status0':scope.row.status===0,'status1':scope.row.status > 0 && scope.row.status <100,'status2':scope.row.status===100,}"
             class="btns"
             size="mini"
             @change="changeStatus(scope.row)"
@@ -92,12 +92,6 @@
     <DailyReport v-if="dialogDailyReport" ref="DailyReport" />
     <ClientReport v-if="dialogClientReport" ref="ClientReport" />
     <taskDialog v-if="showTaskDialog" :show.sync="showTaskDialog" :task-id="taskId.id" :status-name="taskId.statusString" @getList="get_allTask" />
-    <normal-dialog :show-dialog.sync="statusDialog" :title="'状态变更:已上线'" :width="'50%'" @confirm="confirmStatus()">
-      <div class="dialog-change-status">
-        <span>实际上线时间:</span>
-        <el-date-picker v-model="changeStatusDate" type="date" style="width:100%;" placeholder="选择日期" format="yyyy-MM-dd HH:mm:ss" />
-      </div>
-    </normal-dialog>
     <!-- 批量排期 -->
     <modify-schedule
       v-if="visibleSchedule"
@@ -118,11 +112,9 @@ import { taskSelfList, taskTeamList } from '@/api/workSchedule'
 import { taskUpdate } from '@/api/projectViewDetails'
 import { configShowTaskEnum } from '@/api/taskIndex'
 import modifySchedule from '@/views/projectManage/projectList/components/modifySchedule'
-import normalDialog from '@/components/dialog/normalDialog'
 import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
 export default {
   components: {
-    normalDialog,
     TestReport,
     DailyReport,
     ClientReport,
@@ -149,6 +141,7 @@ export default {
   data() {
     return {
       imgUrl: imgUrl,
+      tableList: [], // 排期bable验证
       showTaskDialog: false, // 状态弹窗
       all_task: [], // 任务列表
       allStatus: [], // 任务所有状态
@@ -161,7 +154,6 @@ export default {
       dialogTestReport: false, // 提测
       dialogDailyReport: false, // 日报
       dialogClientReport: false, // 准出
-      statusDialog: false, // 修改状态弹框
       changeStatusDate: null, // 状态改变时间
       nowChangeTask: null, // 当前正在改变的任务对象
       taskId: '', // 将要修改状态的任务id
@@ -240,7 +232,7 @@ export default {
       }
     },
     async changeStatus(e) { // 状态改变
-      if (e.status === 2 || e.status === 4 || e.status === 5) {
+      if (e.status === 70 || e.status === 90 || e.status === 100) {
         this.taskId = e
         this.allStatus.map(item => {
           item.code === e.status ? this.taskId.statusString = item.msg : ''
@@ -257,7 +249,7 @@ export default {
         const taskInfoDO = e
         const resTask = await taskUpdate({ taskInfoDO, user })
         if (resTask.code === 200) {
-          this.$message({ message: resTask.msg, type: 'success', offset: 150 })
+          this.$message({ message: '修改成功', type: 'success', offset: 150 })
           this.get_allTask()
         }
       }
@@ -268,10 +260,12 @@ export default {
       taskInfoDO.onlineRealTime = this.changeStatusDate
       const resTask = await taskUpdate({ taskInfoDO, user })
       if (resTask.code === 200) {
-        this.$message({ message: resTask.msg, type: 'success', offset: 150 })
+        this.$message({ message: '修改成功', type: 'success', offset: 150 })
       }
     },
     handleSelectionChange(val) { // 任务列表删选操作
+      this.tableList = []
+      this.tableList = val
       val.length > 0 ? this.showHeader = false : this.showHeader = true
       this.curcentChecked = val.length
       this.curcentList = val
@@ -297,6 +291,16 @@ export default {
       }
     },
     addSechedule() { // 添加排期
+      const taskA = []
+      this.tableList.map(item => {
+        if (item.isScheduleLocked === 1) {
+          taskA.push(item.taskIdSting)
+        }
+      })
+      if (taskA.length !== 0) {
+        this.$message({ message: '任务 ' + taskA + ' 的排期已锁定,请先解锁排期后再添加排期', type: 'warning', offset: 150 })
+        return
+      }
       this.visibleSchedule = true
       this.selectTaskList = this.curcentList
     },
@@ -387,10 +391,10 @@ export default {
 .status0 {
   @include setStatus(#409EFF)
 }
-.status1, .status2, .status3, .status4{
+.status1{
   @include setStatus(#FF8952)
 }
-.status5 {
+.status2 {
   @include setStatus(#7ED321)
 }
 .search-control {