完整的来了,花了不少时间,希望采纳。
<template>
<div class="hello">
<el-table :data="tableData" :span-method="objectSpanMethod" border
:header-cell-style="{ 'text-align': 'center', background: '#f3f6fd' }" :cell-style="{ 'text-align': 'center' }">
<el-table-column prop="memberName" label="人员" width="100"></el-table-column>
<el-table-column prop="projectTitle" label="项目名称" width="200"></el-table-column>
<el-table-column prop="projectRole" label="角色" width="100"></el-table-column>
<el-table-column prop="statusName" label="项目阶段" width="100">
<template slot-scope="scope">
<div class="circle" :class="scope.row.statusClass"></div>{{ scope.row.statusName }}
</template>
</el-table-column>
<el-table-column prop="dateStart" label="甘特图">
<template slot="header">
<div :span="24">{{ month.substr(5, 2) + '/' + month.substr(0, 4) }}</div>
<div :span="24" class="gantt-header-days">
<table>
<tr>
<td v-for="day in dayList" :key="day.getDate()" :style="'width: ' + 100/dayList.length + '%'">{{ day.getDate() }}</td>
</tr>
</table>
</div>
</template>
<template slot-scope="scope" v-if="scope.row.middleWidth >= 0">
<div class="gantt">
<div class="gantt-back">
<table>
<tr>
<td :style="'width: ' + scope.row.leftWidth + '%'"></td>
<td :style="'width: ' + scope.row.middleWidth + '%'" :class="scope.row.statusClass">
</td>
<td></td>
</tr>
</table>
</div>
<div class="gantt-title">
<table>
<tr>
<td :style="'width: ' + scope.row.leftWidth + '%'"></td>
<td>{{ scope.row.dateLable }}</td>
</tr>
</table>
</div>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'TableTest2',
props: {
msg: String
},
data() {
return {
tableData: [],
month: '',
dayList: []
}
},
created: function () {
this.month = '2023-12';
// 当月第一天
let firstDay = new Date(this.month + '-01');
// 当月最后一天
let lastDay = new Date(firstDay.getFullYear(), firstDay.getMonth() + 1, 0);
this.dayList = [];
let date = firstDay;
while (date.getTime() <= lastDay.getTime()) {
this.dayList.push(date);
date = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
}
console.log(firstDay, lastDay, this.dayList);
let data = {
dupRecflag: null,
firstResult: 0,
limit: 1000000,
maxResult: 1000000,
message: "查询成功!",
pageStart: 0,
receiveflag: null,
root: [
{
auditProjectList: [
{
dateEnd: "2024-01-02",
dateStart: "2022-04-01",
id: 1498,
memberId: "15507",
memberName: "温总",
memberRole: "组员",
showDateEnd: null,
showDateStart: "2024-01-01",
statusDict: 6,
statusName: "整改",
title: "test_20210806_17:14",
},
{
dateEnd: "2023-12-05",
dateStart: "2023-12-01",
id: 2747,
memberId: "15507",
memberName: "温总",
memberRole: "组长",
showDateEnd: null,
showDateStart: null,
statusDict: 2,
statusName: "立项",
title: "总部常规稽核2024",
},
],
memberId: "15507",
memberName: "温总",
},
{
auditProjectList: [
{
dateEnd: "2023-12-07",
dateStart: "2023-12-07",
id: 2747,
memberId: "13616",
memberName: "陈玉",
memberRole: "组员",
showDateEnd: null,
showDateStart: null,
statusDict: 2,
statusName: "立项",
title: "总部常规稽核2024",
},
],
memberId: "13616",
memberName: "陈玉",
},
{ auditProjectList: null, memberId: "33672", memberName: "董事长" },
{
auditProjectList: [
{
dateEnd: "2024-01-03",
dateStart: "2024-01-03",
id: 2747,
memberId: "14236",
memberName: "李丽",
memberRole: "组员",
showDateEnd: null,
showDateStart: null,
statusDict: 2,
statusName: "立项",
title: "总部常规稽核2024",
},
],
memberId: "14236",
memberName: "李丽",
},
{ auditProjectList: null, memberId: "10614", memberName: "周小龙" },
{ auditProjectList: null, memberId: "13226", memberName: "陈伯" },
{
auditProjectList: [
{
dateEnd: "2024-01-02",
dateStart: "2022-04-01",
id: 1498,
memberId: "22361",
memberName: "周捷",
memberRole: "组员",
showDateEnd: null,
showDateStart: "2024-01-01",
statusDict: 6,
statusName: "整改",
title: "test_20210806_17:14",
},
{
dateEnd: "2024-01-03",
dateStart: "2024-01-03",
id: 2747,
memberId: "22361",
memberName: "周捷",
memberRole: "组员",
showDateEnd: null,
showDateStart: null,
statusDict: 2,
statusName: "立项",
title: "总部常规稽核2024",
},
],
memberId: "22361",
memberName: "周捷",
},
],
start: 0,
success: true,
totalProperty: 0,
};
this.tableData = this.transformData(data);
},
methods: {
transformData(srcData) {
let targetData = [];
srcData.root.forEach(member => {
let memberData = [];
if (member.auditProjectList && member.auditProjectList.length > 0) {
member.auditProjectList.forEach(project => {
let startDateTime = new Date(project.dateStart + ' 00:00:00').getTime();
let endDateTime = new Date(project.dateEnd + ' 00:00:00').getTime();
let dateLable = '立项:' + project.dateStart.substr(5, 2) + '月' + project.dateStart.substr(8, 2) + '日'
+ ',提交报告:' + project.dateEnd.substr(5, 2) + '月' + project.dateEnd.substr(8, 2) + '日';
let startPosition = -1;
let endPosition = -1;
for (let i = 0; i < this.dayList.length; i++) {
if (startPosition === -1 && startDateTime <= this.dayList[i].getTime()) {
startPosition = i;
}
if (endDateTime >= this.dayList[i].getTime()) {
endPosition = i;
}
}
memberData.push({
memberId: member.memberId,
memberName: member.memberName,
projectId: project.id,
projectTitle: project.title,
projectRole: project.memberRole,
statusDict: project.statusDict,
statusName: project.statusName,
statusClass: this.getStatusColorClass(project.statusDict),
dateLable,
leftWidth: startPosition / this.dayList.length * 100,
middleWidth: (endPosition + 1 - startPosition) / this.dayList.length * 100
});
});
} else {
memberData.push({
memberId: member.memberId,
memberName: member.memberName
});
}
memberData[0].span = {
rowspan: memberData.length,
colspan: 1
};
targetData = targetData.concat(memberData);
});
return targetData;
},
objectSpanMethod({ row, columnIndex }) {
if (columnIndex === 0) {
if (row.span) {
return row.span;
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
},
getStatusColorClass(statusDict) {
switch (statusDict) {
case 2:
return 'success';
case 6:
return 'warning';
default:
return 'info';
}
}
}
}
</script>
<style>
.success {
background-color: green;
}
.warning {
background-color: yellow;
}
.info {
background-color: blue;
}
.gantt-header-days {
width: 100%;
}
.gantt-header-days table {
width: 100%;
}
.gantt-header-days table tr {
background-color: transparent;
}
.gantt {
width: 100%;
height: 40px;
position: relative;
}
.gantt-back {
z-index: 1;
width: 100%;
height: 30px;
left: 0px;
top: 5px;
position: absolute;
}
.gantt-back table {
border: 1;
width: 100%;
}
.gantt-back table td {
border: 1;
height: 30px;
}
.gantt-title {
z-index: 2;
width: 100%;
height: 20px;
left: 0px;
top: 10px;
position: absolute;
}
.gantt-title table {
border: 0;
width: 100%;
}
.gantt-title table tr {
background-color: transparent;
color: black;
text-align: left;
}
div.circle {
margin: auto;
width: 20px;
height: 20px;
border-radius: 10px;
}
</style>