|
@@ -0,0 +1,457 @@
|
|
|
|
+<template>
|
|
|
|
+ <el-table
|
|
|
|
+ :data="correctData"
|
|
|
|
+ style="width: 100%"
|
|
|
|
+ border
|
|
|
|
+ :header-cell-style="headerCellStyle"
|
|
|
|
+ :span-method="arraySpanMethod"
|
|
|
|
+ size="mini"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column prop="task" :label="stringType" show-overflow-tooltip fixed width="250">
|
|
|
|
+ <template v-slot="scope">
|
|
|
|
+ <div class="set-flex">
|
|
|
|
+ <div class="vertical-line" :style="{'background-color':colorList[scope.$index % 5]}" />
|
|
|
|
+ <!-- <el-color-picker v-model="correctData[scope.$index].task.color" show-alpha></el-color-picker> -->
|
|
|
|
+ <el-tooltip class="item" :disabled="correctData[scope.$index].task.description.length <= 16" effect="light" :content="correctData[scope.$index].task.description" placement="top">
|
|
|
|
+ <div
|
|
|
|
+ class="specail"
|
|
|
|
+ > {{ correctData[scope.$index].task.description.length > 16 ? correctData[scope.$index].task.description.slice(0,16) + '...' : correctData[scope.$index].task.description }} </div>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column
|
|
|
|
+ v-for="(header,index) in headers"
|
|
|
|
+ :key="index"
|
|
|
|
+ :prop="header.version"
|
|
|
|
+ :label="header.version"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column :prop="header.date" :label="header.date">
|
|
|
|
+ <el-table-column :prop="header.date" :label="header.day" width="130">
|
|
|
|
+ <template v-slot="scope">
|
|
|
|
+ <el-popover
|
|
|
|
+ placement="bottom"
|
|
|
|
+ width="250"
|
|
|
|
+ trigger="hover"
|
|
|
|
+ >
|
|
|
|
+ <div>{{ getContent(header.date,scope.row.schedules) ? getContent(header.date,scope.row.schedules).taskName : '' }}</div>
|
|
|
|
+ <div>事件 : {{ getContent(header.date,scope.row.schedules) ? getContent(header.date,scope.row.schedules).event : '' }}</div>
|
|
|
|
+ <div>排期 : {{ getContent(header.date,scope.row.schedules) ? getContent(header.date,scope.row.schedules).schedule : '' }}</div>
|
|
|
|
+ <div>参与人员 : {{ getContent(header.date,scope.row.schedules) ? getContent(header.date,scope.row.schedules).owners.join('、') : '' }}</div>
|
|
|
|
+ <div class="href-location">
|
|
|
|
+ <el-link :underline="false" type="primary" @click="jumpToTask(getContent(header.date,scope.row.schedules) ? getContent(header.date,scope.row.schedules).taskId : '')">前往任务主页<i class="el-icon-d-arrow-right" /></el-link>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ v-if="getContent(header.date,scope.row.schedules)"
|
|
|
|
+ slot="reference"
|
|
|
|
+ :style="{background: colorList[scope.$index % 5]}"
|
|
|
|
+ class="block"
|
|
|
|
+ @click="show(scope)"
|
|
|
|
+ >
|
|
|
|
+ <span> {{ getContent(header.date,scope.row.schedules).taskName + ' : ' + getContent(header.date,scope.row.schedules).event + ' ' }}</span>
|
|
|
|
+ <span v-if="stringType === '任务'">{{ getContent(header.date,scope.row.schedules).owners.join('、') }}</span>
|
|
|
|
+ <!-- <span
|
|
|
|
+ v-for="(owner,ownerIndex) in getContent(header.date,scope.row.schedules) ? getContent(header.date,scope.row.schedules).owners : []"
|
|
|
|
+ :key="ownerIndex"
|
|
|
|
+ >{{owner}}</span> -->
|
|
|
|
+ </div>
|
|
|
|
+ </el-popover>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import dayjs from 'dayjs'
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ props: {
|
|
|
|
+ stringType: {
|
|
|
|
+ type: String,
|
|
|
|
+ default() {
|
|
|
|
+ return '成员'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ tableData: {
|
|
|
|
+ type: Array,
|
|
|
|
+ default() {
|
|
|
|
+ return [
|
|
|
|
+ {
|
|
|
|
+ task: {
|
|
|
|
+ description: '任务1'
|
|
|
|
+ },
|
|
|
|
+ schedules: [
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务1',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-15',
|
|
|
|
+ length: 5,
|
|
|
|
+ owners: ['刘青']
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务1',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-09',
|
|
|
|
+ length: 3,
|
|
|
|
+ owners: ['显调', '志鹏']
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ task: {
|
|
|
|
+ description: '任务2'
|
|
|
|
+ },
|
|
|
|
+ schedules: [
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务2',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-10',
|
|
|
|
+ length: 2,
|
|
|
|
+ owners: ['负责人']
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务2',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-13',
|
|
|
|
+ length: 3,
|
|
|
|
+ owners: ['嘉嘉', '赵杰']
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务2',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-19',
|
|
|
|
+ length: 3,
|
|
|
|
+ owners: ['负责人', '负责人']
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ task: {
|
|
|
|
+ description: '任务3'
|
|
|
|
+ },
|
|
|
|
+ schedules: [
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务3',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-11',
|
|
|
|
+ length: 3,
|
|
|
|
+ owners: ['负责人', '负责人']
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ task: {
|
|
|
|
+ description: '任务3'
|
|
|
|
+ },
|
|
|
|
+ schedules: [
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务3',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-11',
|
|
|
|
+ length: 3,
|
|
|
|
+ owners: ['负责人', '负责人']
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ task: {
|
|
|
|
+ description: '任务3'
|
|
|
|
+ },
|
|
|
|
+ schedules: [
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务3',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-11',
|
|
|
|
+ length: 3,
|
|
|
|
+ owners: ['负责人', '负责人']
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ task: {
|
|
|
|
+ description: '任务3'
|
|
|
|
+ },
|
|
|
|
+ schedules: [
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务3',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-11',
|
|
|
|
+ length: 3,
|
|
|
|
+ owners: ['负责人', '负责人']
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ task: {
|
|
|
|
+ description: '任务4'
|
|
|
|
+ },
|
|
|
|
+ schedules: [
|
|
|
|
+ {
|
|
|
|
+ taskName: '任务4',
|
|
|
|
+ event: '测试用例编写测试',
|
|
|
|
+ schedule: '2010.12.05 - 2019.12.05',
|
|
|
|
+ startDate: '2019-12-12',
|
|
|
|
+ length: 40,
|
|
|
|
+ owners: ['负责人', '负责人']
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ versions: {
|
|
|
|
+ type: Object,
|
|
|
|
+ default() {
|
|
|
|
+ return {
|
|
|
|
+ '2019-12-11': '1.0.0',
|
|
|
|
+ '2019-12-12': '1.0.0',
|
|
|
|
+ '2019-12-16': '1.2.0',
|
|
|
|
+ '2019-12-19': '1.5.0'
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ colorList: ['rgba(255,82,0,0.5)', 'rgba(227,131,247,0.5)', 'rgba(68,190,255,0.5)', 'rgba(122,221,13,0.5)', 'rgba(245,108,108,0.5)'],
|
|
|
|
+ today: '',
|
|
|
|
+ headers: []
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ correctData() {
|
|
|
|
+ const data = JSON.parse(JSON.stringify(this.tableData))
|
|
|
|
+ for (const i in data) {
|
|
|
|
+ if (data[i].schedules.length > 1) {
|
|
|
|
+ let dayCount = 0
|
|
|
|
+ for (let j = 1; j < data[i].schedules.length; j++) {
|
|
|
|
+ dayCount += data[i].schedules[j - 1].length - 1
|
|
|
|
+ data[i].schedules[j].startDate = this.dateMinusDays(
|
|
|
|
+ data[i].schedules[j].startDate,
|
|
|
|
+ dayCount
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return data
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ versions() {
|
|
|
|
+ this.headers = this.createheaders()
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ created() {
|
|
|
|
+ this.today = this.dateFmt('yyyy-MM-dd', new Date())
|
|
|
|
+ this.headers = this.createheaders()
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ createheaders() {
|
|
|
|
+ let minDate
|
|
|
|
+ let maxDate
|
|
|
|
+ for (const i in this.tableData) {
|
|
|
|
+ for (const j in this.tableData[i].schedules) {
|
|
|
|
+ const start = new Date(this.tableData[i].schedules[j].startDate)
|
|
|
|
+ const end = new Date(
|
|
|
|
+ (start / 1000 +
|
|
|
|
+ (86400 * this.tableData[i].schedules[j].length - 1)) *
|
|
|
|
+ 1000
|
|
|
|
+ )
|
|
|
|
+ if (!minDate || minDate.getTime() > start.getTime()) {
|
|
|
|
+ minDate = start
|
|
|
|
+ }
|
|
|
|
+ if (!maxDate || maxDate.getTime() < end.getTime()) {
|
|
|
|
+ maxDate = end
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ const arr = []
|
|
|
|
+ for (
|
|
|
|
+ let i = 0;
|
|
|
|
+ i <= (maxDate.getTime() - minDate.getTime()) / (24 * 60 * 60 * 1000);
|
|
|
|
+ i++
|
|
|
|
+ ) {
|
|
|
|
+ const header = {
|
|
|
|
+ version: '',
|
|
|
|
+ date: '',
|
|
|
|
+ day: ''
|
|
|
|
+ }
|
|
|
|
+ header.date = this.dateAddDays(minDate, i)
|
|
|
|
+ header.day = this.dateToDay(header.date)
|
|
|
|
+ if (typeof this.versions[header.date] !== 'undefined') {
|
|
|
|
+ header.version = this.versions[header.date]
|
|
|
|
+ }
|
|
|
|
+ arr.push(header)
|
|
|
|
+ }
|
|
|
|
+ // console.log(arr)
|
|
|
|
+ return arr
|
|
|
|
+ },
|
|
|
|
+ jumpToTask(e) {
|
|
|
|
+ this.$router.push({ name: '任务查看', query: { id: e }})
|
|
|
|
+ },
|
|
|
|
+ headerCellStyle({ row, column, rowIndex, columnIndex }) {
|
|
|
|
+ if (rowIndex === 0) {
|
|
|
|
+ return {
|
|
|
|
+ 'text-align': 'center',
|
|
|
|
+ 'background': 'transparent'
|
|
|
|
+ // 'border': '0px',
|
|
|
|
+ // 'color': '#000000'
|
|
|
|
+ }
|
|
|
|
+ } else if (column.property === this.today) {
|
|
|
|
+ return {
|
|
|
|
+ 'text-align': 'center',
|
|
|
|
+ 'background': 'transparent',
|
|
|
|
+ 'color': '#F56C6C'
|
|
|
|
+ }
|
|
|
|
+ } else if (dayjs(column.property).day().toString() === '6' || dayjs(column.property).day().toString() === '0') {
|
|
|
|
+ return {
|
|
|
|
+ 'text-align': 'center',
|
|
|
|
+ 'background': 'transparent',
|
|
|
|
+ 'color': '#D8D8D8'
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ return {
|
|
|
|
+ // 'color': '#000000',
|
|
|
|
+ 'background': 'transparent',
|
|
|
|
+ 'text-align': 'center'
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ arraySpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
|
+ if (column.property === '任务') return
|
|
|
|
+ for (const i in row.schedules) {
|
|
|
|
+ if (column.property === row.schedules[i].startDate) {
|
|
|
|
+ return [1, row.schedules[i].length]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ show(scope) {
|
|
|
|
+ console.log(scope)
|
|
|
|
+ },
|
|
|
|
+ getContent(date, schedules) {
|
|
|
|
+ for (const i in schedules) {
|
|
|
|
+ if (date === schedules[i].startDate) {
|
|
|
|
+ return schedules[i]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ dateToDay(dataStr) {
|
|
|
|
+ var strdate = dataStr // 日期字符串
|
|
|
|
+ if (strdate === this.today) { return '今天' }
|
|
|
|
+ var isdate = new Date(strdate) // 把日期字符串转换成日期格式
|
|
|
|
+ let day = ''
|
|
|
|
+ switch (isdate.getDay()) {
|
|
|
|
+ case 1:
|
|
|
|
+ day = '周一'
|
|
|
|
+ break
|
|
|
|
+ case 2:
|
|
|
|
+ day = '周二'
|
|
|
|
+ break
|
|
|
|
+ case 3:
|
|
|
|
+ day = '周三'
|
|
|
|
+ break
|
|
|
|
+ case 4:
|
|
|
|
+ day = '周四'
|
|
|
|
+ break
|
|
|
|
+ case 5:
|
|
|
|
+ day = '周五'
|
|
|
|
+ break
|
|
|
|
+ case 6:
|
|
|
|
+ day = '周六'
|
|
|
|
+ break
|
|
|
|
+ case 0:
|
|
|
|
+ day = '周日'
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ return day
|
|
|
|
+ },
|
|
|
|
+ dateAddDays(dataStr, dayCount) {
|
|
|
|
+ var strdate = dataStr // 日期字符串
|
|
|
|
+ var isdate = new Date(strdate) // 把日期字符串转换成日期格式
|
|
|
|
+ isdate = new Date((isdate / 1000 + 86400 * dayCount) * 1000) // 日期加1天
|
|
|
|
+ var pdate = this.dateFmt('yyyy-MM-dd', isdate) // 把日期格式转换成字符串
|
|
|
|
+ return pdate
|
|
|
|
+ },
|
|
|
|
+ dateMinusDays(dataStr, dayCount) {
|
|
|
|
+ var strdate = dataStr // 日期字符串
|
|
|
|
+ var isdate = new Date(strdate) // 把日期字符串转换成日期格式
|
|
|
|
+ isdate = new Date((isdate / 1000 - 86400 * dayCount) * 1000) // 日期加1天
|
|
|
|
+ var pdate = this.dateFmt('yyyy-MM-dd', isdate) // 把日期格式转换成字符串
|
|
|
|
+ return pdate
|
|
|
|
+ },
|
|
|
|
+ dateFmt(fmt, date) {
|
|
|
|
+ // author: meizz
|
|
|
|
+ var o = {
|
|
|
|
+ 'M+': date.getMonth() + 1, // 月份
|
|
|
|
+ 'd+': date.getDate(), // 日
|
|
|
|
+ 'h+': date.getHours(), // 小时
|
|
|
|
+ 'm+': date.getMinutes(), // 分
|
|
|
|
+ 's+': date.getSeconds(), // 秒
|
|
|
|
+ 'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
|
|
|
|
+ S: date.getMilliseconds() // 毫秒
|
|
|
|
+ }
|
|
|
|
+ if (/(y+)/.test(fmt)) {
|
|
|
|
+ fmt = fmt.replace(
|
|
|
|
+ RegExp.$1,
|
|
|
|
+ (date.getFullYear() + '').substr(4 - RegExp.$1.length)
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ for (var k in o) {
|
|
|
|
+ if (new RegExp('(' + k + ')').test(fmt)) {
|
|
|
|
+ fmt = fmt.replace(
|
|
|
|
+ RegExp.$1,
|
|
|
|
+ RegExp.$1.length === 1
|
|
|
|
+ ? o[k]
|
|
|
|
+ : ('00' + o[k]).substr(('' + o[k]).length)
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return fmt
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="stylus" scoped>
|
|
|
|
+ .href-location >>> .el-link
|
|
|
|
+ margin-top 20px
|
|
|
|
+ opacity 0.8
|
|
|
|
+ font-weight 400
|
|
|
|
+ .set-flex
|
|
|
|
+ display flex
|
|
|
|
+ justify-content center
|
|
|
|
+ align-items center
|
|
|
|
+ .vertical-line
|
|
|
|
+ width 4px
|
|
|
|
+ height 16px
|
|
|
|
+ border-radius 4px
|
|
|
|
+ .specail
|
|
|
|
+ font-size 14px
|
|
|
|
+ margin 2px 0 0 8px
|
|
|
|
+ font-family MicrosoftYaHei
|
|
|
|
+ color rgba(51,59,74,1)
|
|
|
|
+ line-height 35px
|
|
|
|
+ .href-location
|
|
|
|
+ height 35px
|
|
|
|
+ text-align right
|
|
|
|
+ .block
|
|
|
|
+ width 100%
|
|
|
|
+ border-radius 4px
|
|
|
|
+ padding 8px 15px 6px 15px
|
|
|
|
+ overflow hidden //超出的文本隐藏
|
|
|
|
+ text-overflow ellipsis //溢出用省略号显示
|
|
|
|
+ white-space nowrap //溢出不换行
|
|
|
|
+ font-size 13px
|
|
|
|
+ font-weight 400
|
|
|
|
+</style>
|