qinzhipeng_v@didiglobal.com 4 år sedan
förälder
incheckning
6b7d78f85c

+ 32 - 0
src/api/requirement.js

@@ -282,3 +282,35 @@ export function scheduleGetHistoryRequireScheduleById(id) {
     method: 'get'
   })
 }
+
+// 显示当前任务可以关联的望岳任务列表
+export function taskListAvailableDpmTask(id) {
+  return request({
+    url: requestIp + `/task/listAvailableDpmTask?id=${id}`,
+    method: 'get'
+  })
+}
+
+// 将任务和望岳的任务建立关联
+export function taskSetTaskRelated(id, task) {
+  return request({
+    url: requestIp + `/task/setTaskRelated?taskId=${id}&dpmTaskId=${task}`,
+    method: 'get'
+  })
+}
+
+// 删除任务关联的望岳任务关系
+export function taskDeleteRelationship(id) {
+  return request({
+    url: requestIp + `/task/deleteRelationship?id=${id}`,
+    method: 'get'
+  })
+}
+
+// 同步排期到望月
+export function taskShowRelatedDpmTask(id) {
+  return request({
+    url: requestIp + `/task/showRelatedDpmTask?id=${id}`,
+    method: 'get'
+  })
+}

+ 106 - 11
src/views/projectManage/components/demand.vue

@@ -30,11 +30,11 @@
         <template slot-scope="scope">
           <div v-if="!scope.row.vsInput" @mouseover="scope.row.vVisible = true" @mouseout="scope.row.vVisible = false">
             <div class="templatName">
-              <div v-if="scope.row.involveAppString !== null" class="involveApp-top-bottom">
-                <span class="el-involveApp">{{ scope.row.involveAppString }}</span>
+              <div class="involveApp-top-bottom">
+                <span class="el-involveApp">{{ scope.row.involveAppString || "" }}</span>
               </div>
               <el-tooltip class="item" effect="dark" :content="scope.row.moduleInfoName" placement="top">
-                <span v-if="scope.row.moduleInfoName !== null">{{ scope.row.moduleInfoName.length >= 24 ? scope.row.moduleInfoName.substring(0,25) + '...' : scope.row.moduleInfoName }}</span>
+                <span v-if="scope.row.moduleInfoName !== null" ref="Simulation">{{ scope.row.moduleInfoName.length >= 24 ? scope.row.moduleInfoName.substring(0,25) + '...' : scope.row.moduleInfoName }}</span>
               </el-tooltip>
             </div>
 
@@ -45,6 +45,12 @@
                 <el-popover placement="bottom" title="开发负责人" width="400" trigger="click">
                   <div class="blueStr" />
                   <search-people :value.sync="form_query.rqmtProposer" :clearable="false" :multiple="false" style="width: 100%;" @change="changeArea" />
+                  <el-input v-model="form_query.rqmtProposer" placeholder="请输入内容" @input="search()" />
+                  <div v-for="(item, index) in memberIDAP" :key="index" class="Layout_space_between involveApp-top-bottom cursorPo">
+                    <span>{{ item.idap }}</span>
+                    <span>{{ item.name }}</span>
+                    <span>{{ item.deptName }}</span>
+                  </div>
                   <span slot="reference" class="cursorPo">开发负责人:{{ scope.row.rdObject.name !== null? scope.row.rdObject.name: '无' }}</span>
                 </el-popover>
               </el-tooltip>
@@ -58,14 +64,43 @@
             </div>
 
             <div class="Layout_space_between">
-              <div><img src="@/assets/home_images/WX20200914-141851@2x.png" alt=""></div>
+              <span v-if="scope.row.isDirectlyFromDpm === 0 || scope.row.isDirectlyFromDpm === 1">
+                <el-tooltip class="item" effect="dark" :content="scope.row.relatedDpmTaskInfo.taskId + scope.row.relatedDpmTaskInfo.name" placement="top">
+                  <img class="cursorPo" src="@/assets/home_images/WX20200914-141851@2x.png" @click="jump(scope.row.dpmUrl)">
+                </el-tooltip>
+                <i v-if="scope.row.isDirectlyFromDpm === 0" class="el-icon-circle-close sty-icon cursorPo" @click="delete_dpl(scope.row.id)" />
+              </span>
+              <el-popover v-if="scope.row.isDirectlyFromDpm === -1" placement="bottom" title="关联望岳任务" width="400" trigger="click">
+                <div class="blueStr" />
+                <div v-for="(item, index) in dplOption" :key="index" class="Layout_space_between involveApp-top-bottom cursorPo" @click="setRelation(item, scope.row.id)">
+                  <span>{{ item.moduleInfoName }}</span>
+                  <span>{{ item.name }}</span>
+                  <span>{{ item.taskId }}</span>
+                </div>
+                <el-button v-if="scope.row.isDirectlyFromDpm === -1" slot="reference" size="mini" type="text" @click.native="getDplList(scope.row.id)">关联望岳</el-button>
+              </el-popover>
+
               <div v-if="locking" v-show="scope.row.vVisible" class="iconEdit">
-                <el-tooltip class="item cursorPo" effect="dark" :content="scope.row.isScheduleLocked === 1? '点击解锁排期' : '点击锁定排期'" placement="top">
+                <el-tooltip class="item cursorPo lineHeight" effect="dark" :content="scope.row.isScheduleLocked === 1? '点击解锁排期' : '点击锁定排期'" placement="top">
                   <div :class="scope.row.isScheduleLocked === 1 ? 'el-icon-lock' : 'el-icon-unlock'" @click="changeSchedule(scope.row)" />
                 </el-tooltip>
-                <i class="el-icon-edit-outline cursorPo" @click="editTask(scope.row)" />
-                <i v-show="scope.row.isScheduleLocked === 0" class="el-icon-circle-plus-outline cursorPo" @click="clickAddScheduling(2,scope.row)" />
-                <i class="el-icon-sort cursorPo deg" @click="clickAddScheduling(2,scope.row)" />
+                <i class="el-icon-edit-outline cursorPo lineHeight" @click="editTask(scope.row)" />
+                <i v-show="scope.row.isScheduleLocked === 0" class="el-icon-circle-plus-outline cursorPo lineHeight" @click="clickAddScheduling(2,scope.row)" />
+                <el-popover v-if="scope.row.isDirectlyFromDpm === 0 || scope.row.isDirectlyFromDpm === 1" placement="bottom" title="同步排期至望岳" width="400" trigger="click">
+                  <div class="blueStr" />
+                  <div class="synchronization">是否需要同步当前任务的排期到望岳<span style="color:#D98A38;"> {{ taskDpl }}</span> ?</div>
+                  <div class="synchronization">以下任务与该望岳任务也关联,排期将一并同步,请知悉!</div>
+                  <div v-for="(item, index) in taskDataList" :key="index" class="Layout_space_between involveApp-top-bottom">
+                    <span>{{ item.taskId }}</span>
+                    <span>{{ item.name }}</span>
+                    <span>{{ item.moduleInfoName }}</span>
+                  </div>
+                  <div align="right" style="margin-top:20px;">
+                    <el-button size="mini" @click="$refs.Simulation.click()">取 消</el-button>
+                    <el-button size="mini" type="primary" @click="dialogVisible = false">确 定</el-button>
+                  </div>
+                  <i slot="reference" class="el-icon-sort cursorPo deg" @click="getTaskList(scope.row)" />
+                </el-popover>
               </div>
             </div>
           </div>
@@ -118,10 +153,11 @@
 </template>
 <script>
 import searchPeople from '@/components/select/searchPeople'
-import { listByRequire } from '@/api/requirement.js'
+import { listByRequire, taskListAvailableDpmTask, taskSetTaskRelated, taskDeleteRelationship, taskShowRelatedDpmTask } from '@/api/requirement.js'
 import scheduleList from '@/views/projectManage/components/scheduleList.vue'
 import '@/styles/PublicStyle/index.scss' // 通用css
 import { configShowTaskStatusEnum } from '@/api/taskIndex'
+import { memberQueryMemberInfoByIDAPorName } from '@/api/projectIndex'
 import { taskUpdate } from '@/api/taskIndex'
 import schedule from '@/views/projectManage/schedule' // 排期锁定弹窗
 import taskDialog from '@/views/projectManage/taskList/dialog/taskDialog' // 任务状态修改(已上线/已提测/已准出)
@@ -143,6 +179,8 @@ export default {
     return {
       requirementId: Number(this.$route.query.id),
       allStatus: [], // task状态
+      taskDataList: [], // 同步排期到望岳的任务
+      memberIDAP: [],
       tableData: [],
       checkAlls: false,
       taskIdObject: {},
@@ -157,6 +195,8 @@ export default {
         dayLength: '',
         peopleList: ''
       }],
+      dplOption: [],
+      taskDpl: '',
       form_query: {},
       nowChangeTask: null, // 当前正在改变的任务对象
       isScheduleLocked: '', //  当前排期的状态
@@ -234,6 +274,21 @@ export default {
       }
     },
 
+    async getDplList(taskId) {
+      const res = await taskListAvailableDpmTask(taskId)
+      if (res.code === 200) {
+        this.dplOption = res.data
+      }
+    },
+
+    async getTaskList(item) {
+      this.taskDpl = item.relatedDpmTaskInfo.taskId + item.relatedDpmTaskInfo.name
+      const res = await taskShowRelatedDpmTask(item.id)
+      if (res.code === 200) {
+        this.taskDataList = res.data
+      }
+    },
+
     async changeStatus(e) { // 状态改变
       if (e.status === 70 || e.status === 90 || e.status === 100) {
         this.taskIdObject = e
@@ -263,6 +318,30 @@ export default {
         return 'cell-grey'
       }
     },
+    async search(val) { // 人员搜索
+      const res = await memberQueryMemberInfoByIDAPorName({ memberIDAP: val })
+      if (res.code === 200) {
+        this.memberIDAP = res.data
+      }
+    },
+    jump(url) {
+      window.open(url, '_blank')
+    },
+    async setRelation(item, taskId) { // 关联望月任务
+      const res = await taskSetTaskRelated(taskId, item.id)
+      if (res.code === 200) {
+        this.listByTask(this.requirementId)
+        this.$refs.Simulation.click()
+        this.$message({ message: '关联成功', type: 'success', offset: 150 })
+      }
+    },
+    async delete_dpl(val) { // task断开和望月的关联
+      const res = await taskDeleteRelationship(val)
+      if (res.code === 200) {
+        this.listByTask(this.requirementId)
+        this.$message({ message: '已取消关联', type: 'success', offset: 150 })
+      }
+    },
     lockingchange() {
       this.locking = true
     },
@@ -369,6 +448,9 @@ export default {
   margin-right: 5px;
   opacity:1;
 }
+.lineHeight {
+  line-height: inherit;
+}
 .cursorPo:hover {
   color:#409EFF;
   cursor: pointer;
@@ -431,9 +513,14 @@ export default {
 >>>.el-table, .el-table__expanded-cell{
   background:rgba(248,248,248,0.6);
 }
+.sty-icon {
+  position: absolute;
+  left: 63px;
+  bottom: 13px;
+  background: #eee;
+  border-radius: 50%;
+}
 .el-involveApp {
-  border:1px solid rgba(64,158,255,1);
-  border-radius:20px;
   font-size:10px;
   font-family:MicrosoftYaHei;
   line-height:12px;
@@ -491,6 +578,14 @@ export default {
   top: 22px;
   left: 15px;
 }
+.synchronization {
+  font-size: 14px;
+  font-family: Microsoft Sans Serif;
+  font-weight: 400;
+  line-height: 25px;
+  color: #333333;
+  opacity: 1;
+}
 </style>
 <style>
  .el-popover__title {

+ 11 - 5
src/views/projectManage/requirement/requirementDetail.vue

@@ -181,11 +181,11 @@
           </div>
           <section class="main-section">
             <div class="required-tips">
-              <span class="tipName"><i class="el-icon-question" /> 帮助提示</span><br>
-              .需求排期是对任务排期的汇总,给需求排期请优先拆解任务;每个任务仅支持一次提测和一次准出,请合理拆解任务后再排期。<br>
-              .需求状态未变更【已排期】前,排期不可锁定;状态变更为【已排期】时,需求排期将被系统自动锁定。<br>
-              .需求排期锁定时,任务排期将全部被锁定;所有任务锁定时,需求排期将被系统自动锁定。<br>
-              .任务锁定时,系统会自动将任务排期及交付时间同步至望岳。若多个任务关联同一个望岳任务,同步时排期会汇总一并同步到望岳,交付时间则按最晚日期同步至望岳。
+              <span class="tipName"><i class="el-icon-question icon-sty" /> 帮助提示</span><br>
+              ·需求排期是对任务排期的汇总,给需求排期请优先拆解任务;每个任务仅支持一次提测和一次准出,请合理拆解任务后再排期。<br>
+              ·需求状态未变更【已排期】前,排期不可锁定;状态变更为【已排期】时,需求排期将被系统自动锁定。<br>
+              ·需求排期锁定时,任务排期将全部被锁定;所有任务锁定时,需求排期将被系统自动锁定。<br>
+              ·任务锁定时,系统会自动将任务排期及交付时间同步至望岳。若多个任务关联同一个望岳任务,同步时排期会汇总一并同步到望岳,交付时间则按最晚日期同步至望岳。
             </div>
             <div class="allTips">
               <el-radio-group v-model="listOrGannt" size="small" style="margin-left: 10px">
@@ -866,6 +866,12 @@ line-height: 20px;
 color: #333333;
 opacity: 1;
 }
+.icon-sty {
+background: #1890FF;
+color:#e0eefd;
+border-color:#e0eefd;
+border-radius: 50%;
+}
 @import '@/styles/detail-pages.scss';
 /deep/.el-button {
   cursor: pointer;