|
@@ -0,0 +1,352 @@
|
|
|
+<template>
|
|
|
+ <!-- 表头 -->
|
|
|
+ <div class="schedule-list">
|
|
|
+ <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="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 label="操作" width="120" />
|
|
|
+ </el-table>
|
|
|
+ <div v-if="tableHeader === true" class="Layout_space_between" style="height: 40px;;border: 1px solid #EBEEF5;">
|
|
|
+ <div class="Layout_flex_start" style="width: 90%">
|
|
|
+ <el-checkbox v-model="checkAlls" style="padding: 17.5px; line-height: 20px; border-right: 1px solid #EBEEF5" @change="changeCheckout(checkAlls)" />
|
|
|
+ <div style="margin: 0 30px 0 10px" class="endCheck"> 已选择 <span style="color:rgba(64,158,255,1) ">{{ taskList.length }}</span> 个</div>
|
|
|
+ <div class="endCheck cursorPo" @click="clickAddScheduling(1)"><i class="el-icon-document" /> 添加排期</div>
|
|
|
+ </div>
|
|
|
+ <div class="endCheck cursorPo" @click="Deselect">取消选择</div>
|
|
|
+ </div>
|
|
|
+ <!-- 表头 -->
|
|
|
+
|
|
|
+ <!-- 任务表格 -->
|
|
|
+ <el-table ref="taskList" :data="tableData" :cell-class-name="addClass" :header-cell-style="{ background: 'rgba(247,247,247,1)', color: 'rgb(74, 74, 74)', fontSize: '14px', fontWeight: '500'}" border :show-header="false" @selection-change="handleSelectionChange">
|
|
|
+ <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 class="templatName">
|
|
|
+ <el-tooltip class="item" effect="dark" :content="scope.row.moduleInfoName" placement="top">
|
|
|
+ <span>{{ scope.row.moduleInfoName === null ? "" : scope.row.moduleInfoName.substring(0,9) }}</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="scope.row.isScheduleLocked === 1 ? 'el-icon-lock' : 'el-icon-unlock'" @click="changeSchedule(scope.row)" />
|
|
|
+ </el-tooltip>
|
|
|
+ </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 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(newID)" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <!-- 任务表格 -->
|
|
|
+
|
|
|
+ <!-- 日期详情 -->
|
|
|
+ <el-row><span class="demandLayout">交付日期:</span><span class="demandeta">{{ dataList.endTime }}</span></el-row>
|
|
|
+ <el-row><span class="demandLayout">排期:</span><span class="demandeta">{{ dataList.startTime || '' }} ~ {{ dataList.endTime }}</span></el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col v-for="(item, index) in scheduleDetail" :key="index" :span="6"><span class="demandLayout">{{ index }}:</span><span class="demandeta">{{ item.startTime }} ~ {{ item.endTime }}</span></el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row><span class="demandLayout">预计上线版本:</span> <span v-for="item in preOnlineVersion" :key="item" class="demandeta">{{ item }}</span></el-row>
|
|
|
+ <!-- 日期详情 -->
|
|
|
+
|
|
|
+ <!-- 排期锁定弹窗 -->
|
|
|
+ <schedule ref="ScheduleEvent" :visible.sync="scheduleVisble" :name="'任务'" :is-schedule-locked="isScheduleLocked" :require-id="Number(taskId)" @updataData="listByTask(newID)" />
|
|
|
+ <!-- 排期锁定弹窗 -->
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import { listByRequire } from '@/api/requirement.js'
|
|
|
+import scheduleList from '@/views/projectManage/components/scheduleList.vue'
|
|
|
+import '@/styles/PublicStyle/index.scss' // 通用css
|
|
|
+import { taskUpdate } from '@/api/taskIndex'
|
|
|
+import schedule from '@/views/projectManage/schedule' // 排期锁定弹窗
|
|
|
+export default {
|
|
|
+ components: {
|
|
|
+ scheduleList,
|
|
|
+ schedule
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ id: {
|
|
|
+ type: [String, Number],
|
|
|
+ default: () => null,
|
|
|
+ required: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ requirementId: Number(this.$route.query.id),
|
|
|
+ tableData: [],
|
|
|
+ checkAlls: false,
|
|
|
+ taskScheduleList: [],
|
|
|
+ scheduleList: [],
|
|
|
+ datas: [{
|
|
|
+ date: '',
|
|
|
+ type: '',
|
|
|
+ desc: '',
|
|
|
+ seperateDaysNoHoliday: '',
|
|
|
+ dayLength: '',
|
|
|
+ peopleList: ''
|
|
|
+ }],
|
|
|
+ newID: '',
|
|
|
+ isScheduleLocked: '', // 当前排期的状态
|
|
|
+ taskId: '', // taskID
|
|
|
+ scheduleVisble: false, // 排期锁定
|
|
|
+ userInformation: localStorage.getItem('username'),
|
|
|
+ userNames: localStorage.getItem('realname'),
|
|
|
+ taskList: [], // 全选list
|
|
|
+ tableHeader: false, // 表头切换
|
|
|
+ taskName: '', // taskname
|
|
|
+ scheduleDetail: {}, // 用例/开发/提测/测试/准出/上线
|
|
|
+ preOnlineVersion: [], // 预计上线版本
|
|
|
+ dataList: {}, // 排期
|
|
|
+ taskScheduleEvent: [], // 排期类型
|
|
|
+ locking: true, // 查看历史记录锁定能
|
|
|
+ isDelete: false // 删除排期操作
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ id: {
|
|
|
+ handler(newV, old) {
|
|
|
+ this.newID = newV
|
|
|
+ this.listByTask(newV)
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async listByTask(id) { // 获取排期列表
|
|
|
+ this.taskList = []
|
|
|
+ this.scheduleVisble = false
|
|
|
+ const res = await listByRequire(id)
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.tableData = res.data.taskDetailList // 任务list
|
|
|
+ this.dataList = res.data // 排期
|
|
|
+ this.scheduleList = res.data.scheduleDetailRespons || []
|
|
|
+ this.scheduleDetail = res.data.timeInfos // 用例/开发/提测/测试/准出/上线
|
|
|
+ this.preOnlineVersion = res.data.preOnlineVersion // 预计上线版本
|
|
|
+ this.taskScheduleEvent = res.data.scheduleDetailRespons // 排期详情
|
|
|
+ this.tableData = this.tableData.map(item => ({
|
|
|
+ ...item,
|
|
|
+ vVisible: false,
|
|
|
+ vsInput: false
|
|
|
+ }))
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ addClass({ row, column, rowIndex, columnIndex }) {
|
|
|
+ if (columnIndex === 2) {
|
|
|
+ return 'cell-grey'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ lockingchange() {
|
|
|
+ this.locking = true
|
|
|
+ },
|
|
|
+ changeSchedule(ele) { // 修改锁定状态
|
|
|
+ if (this.dataList.isScheduleLocked === 1 && ele.isScheduleLocked === 1) {
|
|
|
+ this.$message({ message: '无法解锁,请先变更归属需求的排期状态为未锁定状态!', type: 'error', duration: 3000, offset: 150 })
|
|
|
+ } else {
|
|
|
+ this.isScheduleLocked = ele.isScheduleLocked
|
|
|
+ this.taskId = ele.id
|
|
|
+ this.scheduleVisble = true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async changeTaskName(val) { // 修改taskname
|
|
|
+ val.vsInput = false
|
|
|
+ val.vVisible = false
|
|
|
+ val.name = this.taskName.split(' ').join('').length === 0 ? val.name : this.taskName
|
|
|
+ const taskInfoDO = val
|
|
|
+ const user = { name: this.userNames, ename: this.userInformation, id: '' }
|
|
|
+ const res = await taskUpdate({ taskInfoDO, user })
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$message({ message: '已修改任务名称', type: 'success', duration: 1000, offset: 150 })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ clickAddScheduling(index, ele) { // 模拟调用自组件方法
|
|
|
+ if (index === 2) {
|
|
|
+ this.taskList = []
|
|
|
+ this.taskList.push(ele)
|
|
|
+ }
|
|
|
+ const taskA = []
|
|
|
+ this.taskList.map(item => {
|
|
|
+ if (item.isScheduleLocked === 1) {
|
|
|
+ taskA.push(item.taskIdSting)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (taskA.length !== 0) {
|
|
|
+ this.$message({ message: '任务 ' + taskA + ' 的排期已锁定,请先解锁排期后再添加排期', type: 'warning', offset: 150 })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$refs.taskSchedule.addSchedule()
|
|
|
+ },
|
|
|
+ clickTemplatTaskName(e) { // 任务名称店家跳转
|
|
|
+ const { href } = this.$router.resolve({ name: '任务详情', query: { id: e }})
|
|
|
+ window.open(href, '_blank')
|
|
|
+ },
|
|
|
+ editTask(val) { // 点击修改taskName
|
|
|
+ val.vsInput = true
|
|
|
+ this.taskName = val.name
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.taskName.focus()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ changeCheckout(rows) {
|
|
|
+ if (rows) {
|
|
|
+ this.tableData.forEach(row => {
|
|
|
+ this.$refs.taskList.toggleRowSelection(row, true)
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.$refs.taskList.clearSelection()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ Deselect() { // 取消选择
|
|
|
+ this.taskList.forEach(row => {
|
|
|
+ this.$refs.taskList.clearSelection()// 调用这个方法
|
|
|
+ })
|
|
|
+ this.tableHeader = false
|
|
|
+ this.taskList = []
|
|
|
+ },
|
|
|
+ handleSelectionChange(val) {
|
|
|
+ this.taskList = val
|
|
|
+ this.taskList.length === this.tableData.length ? this.checkAlls = true : this.checkAlls = false
|
|
|
+ if (this.taskList.length > 0) {
|
|
|
+ this.tableHeader = true
|
|
|
+ } else {
|
|
|
+ this.tableHeader = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ taskScheduleLists(id) {
|
|
|
+ for (var key in this.taskScheduleEvent) {
|
|
|
+ if (id === Number(key)) {
|
|
|
+ return this.taskScheduleEvent[key]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.templatName {
|
|
|
+ font-size:12px;
|
|
|
+ font-family:MicrosoftYaHei;
|
|
|
+ line-height:14px;
|
|
|
+ color:rgba(102,102,102,1);
|
|
|
+ opacity:1;
|
|
|
+ margin: 5px 0;
|
|
|
+}
|
|
|
+.templatTaskName {
|
|
|
+ font-size:14px;
|
|
|
+ font-family:MicrosoftYaHei;
|
|
|
+ line-height:23px;
|
|
|
+ color:rgba(51,51,51,1);
|
|
|
+ margin-right: 5px;
|
|
|
+ opacity:1;
|
|
|
+}
|
|
|
+.cursorPo:hover {
|
|
|
+ color:#409EFF;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.templatCreator {
|
|
|
+ font-size:12px;
|
|
|
+ font-family:MicrosoftYaHei;
|
|
|
+ line-height:14px;
|
|
|
+ color:rgba(102,102,102,1);
|
|
|
+ opacity:1;
|
|
|
+ margin: 5px 0;
|
|
|
+}
|
|
|
+.demandLayout {
|
|
|
+ display: inline-block;
|
|
|
+ // width: 100px;
|
|
|
+ margin: 10px 0;
|
|
|
+ font-size:12px;
|
|
|
+ line-height:14px;
|
|
|
+ color:rgba(102,102,102,1);
|
|
|
+ opacity:1;
|
|
|
+}
|
|
|
+.demandeta {
|
|
|
+ font-size:12px;
|
|
|
+ font-family:MicrosoftYaHei;
|
|
|
+ line-height:14px;
|
|
|
+ color:rgba(51,51,51,1);
|
|
|
+ opacity:1;
|
|
|
+}
|
|
|
+.iconEdit {
|
|
|
+ width:67px;
|
|
|
+ background:rgba(245,245,245,1);
|
|
|
+ opacity:1;
|
|
|
+ padding: 0 10px;
|
|
|
+ border-radius:20px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+.tableHeader {
|
|
|
+ >>> .el-table__empty-block{
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+}
|
|
|
+.iconPadding {
|
|
|
+ margin-right: 5px;
|
|
|
+}
|
|
|
+.schedule-list {
|
|
|
+ /deep/ .el-table td {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+.schedule-list {
|
|
|
+ margin: 0 20px;
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+>>>.el-table, .el-table__expanded-cell{
|
|
|
+ background:rgba(248,248,248,0.6);
|
|
|
+}
|
|
|
+.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;
|
|
|
+}
|
|
|
+.endCheck {
|
|
|
+ font-size:14px;
|
|
|
+ font-family:Microsoft Sans Serif;
|
|
|
+ font-weight:400;
|
|
|
+ line-height:16px;
|
|
|
+ margin-right: 10px;
|
|
|
+ color:rgba(102,102,102,1);
|
|
|
+ opacity:1;
|
|
|
+}
|
|
|
+
|
|
|
+</style>
|
|
|
+<style>
|
|
|
+ .cell-grey .cell {
|
|
|
+ padding: 0 !important;
|
|
|
+ }
|
|
|
+.el-tooltip__popper.is-dark {
|
|
|
+ background:rgba(121,132,150,0.8);
|
|
|
+ color: #FFF;
|
|
|
+}
|
|
|
+</style>
|