123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- <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 { EncryptId } from '@/utils/crypto-js.js'
- 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: -1,
- 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) {
- if (newV === -1) return
- 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(id) { // 任务名称店家跳转
- const bizId_id = EncryptId(`${this.bizId}_${id}`)
- const { href } = this.$router.resolve({ name: '任务详情', query: { bizId_id: bizId_id }})
- 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>
|