|
@@ -4,11 +4,13 @@
|
|
|
<el-table v-if="tableHeader === false" max-height="38px" :data="datas" class="tableHeader" border size="mini" :header-cell-style="{ background: 'rgba(247,247,247,1)', color: 'rgb(74, 74, 74)', fontSize: '14px', fontWeight: '500'}" @selection-change="changeCheckout(1)">
|
|
|
<el-table-column v-if="locking" type="selection" width="50" align="center" />
|
|
|
<el-table-column prop="date" label="任务" width="300" />
|
|
|
+ <el-table-column prop="taskStatus" label="任务状态" width="200" />
|
|
|
<el-table-column prop="type" label="类型" min-width="70" />
|
|
|
<el-table-column prop="desc" label="描述" min-width="150" />
|
|
|
<el-table-column prop="seperateDaysNoHoliday" label="排期" min-width="160" />
|
|
|
<el-table-column prop="dayLength" label="时长" min-width="50" />
|
|
|
<el-table-column prop="peopleList" label="参与人员" min-width="150" />
|
|
|
+ <el-table-column prop="dayLength" label="关联任务" min-width="100" />
|
|
|
<el-table-column label="操作" width="120" />
|
|
|
</el-table>
|
|
|
<div v-if="tableHeader === true" class="Layout_space_between" style="height: 40px;;border: 1px solid #EBEEF5;">
|
|
@@ -26,31 +28,105 @@
|
|
|
<el-table-column v-if="locking" type="selection" width="50" align="center" />
|
|
|
<el-table-column label="任务" width="300" align="left">
|
|
|
<template slot-scope="scope">
|
|
|
- <div v-if="!scope.row.vsInput">
|
|
|
+ <div v-if="!scope.row.vsInput" @mouseover="scope.row.vVisible = true" @mouseout="scope.row.vVisible = false">
|
|
|
<div class="templatName">
|
|
|
+ <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>{{ scope.row.moduleInfoName === null ? "" : scope.row.moduleInfoName.substring(0,9) }}</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>
|
|
|
- <span v-if="scope.row.involveAppString !== null" class="el-involveApp">{{ scope.row.involveAppString }}</span>
|
|
|
</div>
|
|
|
|
|
|
- <div class="Layout_space_between" @mouseover="scope.row.vVisible = true" @mouseout="scope.row.vVisible = false">
|
|
|
- <div class="Layout_flex_start">
|
|
|
- <div class="templatTaskName cursorPo" @click="clickTemplatTaskName(scope.row.id)">{{ scope.row.name }}</div>
|
|
|
- <el-tooltip v-if="locking" class="item" effect="dark" :content="scope.row.isScheduleLocked === 1? '点击解锁排期' : '点击锁定排期'" placement="top">
|
|
|
+ <div class="templatTaskName cursorPo" @click="clickTemplatTaskName(scope.row.id)">{{ scope.row.name }}</div>
|
|
|
+
|
|
|
+ <div class="templatCreator">
|
|
|
+ <el-tooltip class="item" effect="dark" content="点击修改" placement="top">
|
|
|
+ <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>
|
|
|
+ <el-tooltip class="item" effect="dark" content="点击修改" placement="top">
|
|
|
+ <el-popover placement="bottom" title="测试负责人" width="400" class="iconPadding" trigger="click">
|
|
|
+ <div class="blueStr" />
|
|
|
+ <search-people :value.sync="form_query.rqmtProposer" :clearable="false" :multiple="false" style="width: 100%;" @change="changeArea" />
|
|
|
+ <span slot="reference" class="cursorPo">测试负责人: {{ scope.row.qaObject.name !== null ? scope.row.qaObject.name: '无' }}</span>
|
|
|
+ </el-popover>
|
|
|
+ </el-tooltip>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="Layout_space_between">
|
|
|
+ <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 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 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 v-if="locking" v-show="scope.row.vVisible" class="iconEdit"><i class="el-icon-edit-outline iconPadding cursorPo" @click="editTask(scope.row)" /> <i v-show="scope.row.isScheduleLocked === 0" class="el-icon-circle-plus-outline cursorPo" @click="clickAddScheduling(2,scope.row)" /></div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="templatCreator">
|
|
|
- 开发负责人:{{ scope.row.rdObject.name !== null? scope.row.rdObject.name: '无' }} 测试负责人: {{ scope.row.qaObject.name !== null?scope.row.qaObject.name: '无' }}
|
|
|
</div>
|
|
|
</div>
|
|
|
<el-input v-if="scope.row.vsInput" ref="taskName" v-model="taskName" type="textarea" rows="4" placeholder="请输入内容" maxlength="150" show-word-limit @blur="changeTaskName(scope.row)" />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
+ <el-table-column width="200" 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,
|
|
|
+ 'public_btn':scope.row.status!==10 || scope.row.status!==40 || scope.row.status!==20 || scope.row.status!==30,
|
|
|
+ 'public_btn1':scope.row.status===40,
|
|
|
+ 'public_btn2':scope.row.status===10,
|
|
|
+ 'public_btn3':scope.row.status===20 || scope.row.status===30
|
|
|
+ }"
|
|
|
+ size="mini"
|
|
|
+ @change="changeStatus(scope.row)"
|
|
|
+ >
|
|
|
+ <el-option v-for="item in scope.row.availableStatusList" :key="item.code" :label="item.name" :value="item.code" />
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="任" style="padding: 20px;">
|
|
|
<template slot-scope="scope">
|
|
|
<schedule-list :id="scope.row.id" ref="taskSchedule" :locking="locking" :select-task-list="taskList" :required-list="taskScheduleLists(scope.row.id)" @listByTask="listByTask(requirementId)" />
|
|
@@ -70,19 +146,27 @@
|
|
|
|
|
|
<!-- 排期锁定弹窗 -->
|
|
|
<schedule ref="ScheduleEvent" :visible.sync="scheduleVisble" :name="'任务'" :is-schedule-locked="isScheduleLocked" :require-id="Number(taskId)" @updataData="listByTask(requirementId)" />
|
|
|
- <!-- 排期锁定弹窗 -->
|
|
|
+ <!-- 排期锁定弹窗 -->
|
|
|
+
|
|
|
+ <task-dialog v-if="showTaskDialog" :show.sync="showTaskDialog" :task-id="taskIdObject.id" :status-name="taskIdObject.statusString" @getList="listByTask(requirementId)" />
|
|
|
</div>
|
|
|
</template>
|
|
|
<script>
|
|
|
-import { listByRequire } from '@/api/requirement.js'
|
|
|
+import searchPeople from '@/components/select/searchPeople'
|
|
|
+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' // 任务状态修改(已上线/已提测/已准出)
|
|
|
export default {
|
|
|
components: {
|
|
|
scheduleList,
|
|
|
- schedule
|
|
|
+ schedule,
|
|
|
+ searchPeople,
|
|
|
+ taskDialog
|
|
|
},
|
|
|
props: {
|
|
|
requiredList: {
|
|
@@ -94,8 +178,13 @@ export default {
|
|
|
data() {
|
|
|
return {
|
|
|
requirementId: Number(this.$route.query.id),
|
|
|
+ allStatus: [], // task状态
|
|
|
+ taskDataList: [], // 同步排期到望岳的任务
|
|
|
+ memberIDAP: [],
|
|
|
tableData: [],
|
|
|
checkAlls: false,
|
|
|
+ taskIdObject: {},
|
|
|
+ showTaskDialog: false,
|
|
|
taskScheduleList: [],
|
|
|
scheduleList: [],
|
|
|
datas: [{
|
|
@@ -106,6 +195,10 @@ export default {
|
|
|
dayLength: '',
|
|
|
peopleList: ''
|
|
|
}],
|
|
|
+ dplOption: [],
|
|
|
+ taskDpl: '',
|
|
|
+ form_query: {},
|
|
|
+ nowChangeTask: null, // 当前正在改变的任务对象
|
|
|
isScheduleLocked: '', // 当前排期的状态
|
|
|
taskId: '', // taskID
|
|
|
scheduleVisble: false, // 排期锁定
|
|
@@ -149,6 +242,9 @@ export default {
|
|
|
immediate: true
|
|
|
}
|
|
|
},
|
|
|
+ created() {
|
|
|
+ this.configShowTaskStatusEnum()
|
|
|
+ },
|
|
|
methods: {
|
|
|
async listByTask(id) { // 获取排期列表
|
|
|
this.taskList = []
|
|
@@ -171,11 +267,81 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ async configShowTaskStatusEnum() {
|
|
|
+ const res = await configShowTaskStatusEnum(localStorage.getItem('bizId'))
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.allStatus = res.data.taskStatus
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ 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
|
|
|
+ this.allStatus.map(item => {
|
|
|
+ item.code === e.status ? this.taskIdObject.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.listByTask(this.requirementId)
|
|
|
+ this.$message({ message: '修改成功', type: 'success', offset: 150 })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
addClass({ row, column, rowIndex, columnIndex }) {
|
|
|
- if (columnIndex === 2) {
|
|
|
+ if (columnIndex === 3) {
|
|
|
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
|
|
|
},
|
|
@@ -227,6 +393,9 @@ export default {
|
|
|
this.$refs.taskName.focus()
|
|
|
})
|
|
|
},
|
|
|
+ changeArea(value) {
|
|
|
+ console.log(value, 'cdsncjds')
|
|
|
+ },
|
|
|
changeCheckout(rows) {
|
|
|
if (rows) {
|
|
|
this.tableData.forEach(row => {
|
|
@@ -279,6 +448,9 @@ export default {
|
|
|
margin-right: 5px;
|
|
|
opacity:1;
|
|
|
}
|
|
|
+.lineHeight {
|
|
|
+ line-height: inherit;
|
|
|
+}
|
|
|
.cursorPo:hover {
|
|
|
color:#409EFF;
|
|
|
cursor: pointer;
|
|
@@ -308,10 +480,10 @@ export default {
|
|
|
opacity:1;
|
|
|
}
|
|
|
.iconEdit {
|
|
|
- width:67px;
|
|
|
+ width:100px;
|
|
|
background:rgba(245,245,245,1);
|
|
|
opacity:1;
|
|
|
- padding: 0 10px;
|
|
|
+ padding: 2px 10px;
|
|
|
border-radius:20px;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
@@ -321,8 +493,13 @@ export default {
|
|
|
display: none;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+.involveApp-top-bottom {
|
|
|
+ margin: 10px 0;
|
|
|
+}
|
|
|
+
|
|
|
.iconPadding {
|
|
|
- margin-right: 5px;
|
|
|
+ margin-left: 5px;
|
|
|
}
|
|
|
.schedule-list {
|
|
|
/deep/ .el-table td {
|
|
@@ -336,14 +513,18 @@ 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;
|
|
|
padding: 0 5px;
|
|
|
- margin-left: 5px;
|
|
|
color:rgba(64,158,255,1);
|
|
|
opacity:1;
|
|
|
}
|
|
@@ -356,9 +537,61 @@ export default {
|
|
|
color:rgba(102,102,102,1);
|
|
|
opacity:1;
|
|
|
}
|
|
|
-
|
|
|
+@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;
|
|
|
+ }
|
|
|
+}
|
|
|
+.status0 {
|
|
|
+ @include setStatus(#409EFF)
|
|
|
+}
|
|
|
+.status1{
|
|
|
+ @include setStatus(#FF8952)
|
|
|
+}
|
|
|
+.status2 {
|
|
|
+ @include setStatus(#7ED321)
|
|
|
+}
|
|
|
+.deg {
|
|
|
+ transform:rotate(90deg);
|
|
|
+ -ms-transform:rotate(-90deg); /* Internet Explorer 9*/
|
|
|
+ -moz-transform:rotate(-90deg); /* Firefox */
|
|
|
+ -webkit-transform:rotate(-90deg); /* Safari 和 Chrome */
|
|
|
+ -o-transform:rotate(-90deg); /* Opera */
|
|
|
+}
|
|
|
+.blueStr {
|
|
|
+ width:4px;
|
|
|
+ height:17px;
|
|
|
+ background:#409EFF;
|
|
|
+ border-radius:1px;
|
|
|
+ position: absolute;
|
|
|
+ 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 {
|
|
|
+ color: #333333;
|
|
|
+ padding-left: 10px;
|
|
|
+}
|
|
|
.cell-grey .cell {
|
|
|
padding: 0 !important;
|
|
|
}
|