hberp/hb_client/src/views/pm/gantt.vue

1460 lines
41 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="chart" ref="chart">
<div class="left" :style="{ width: rightLineX + 'px' }">
<leftMenu
:list="list"
ref="leftMenu"
:BGScrollTop.sync="BGScrollTop"
@TableScrollTop="TableScrollTop"
@handlerRowClick="handlerRowClick"
@handlerGroup="handlerGroup"
@handlerExpand="handlerExpand"
></leftMenu>
<div class="rightLine" :style="{ left: rightLineX + 'px' }"></div>
<div
class="rightLine"
:style="{ left: rightLineX + 'px' }"
ref="rightLine"
@mousedown="rightLineMousedown"
></div>
</div>
<div class="date" :style="{ left: rightLineX + 2 + 'px' }">
<div class="years" v-for="item in allDays" :key="item.year">
<div
class="month"
v-for="(value, key) in item.month[0]"
:key="value + 'zz' + key"
:style="{ width: value.length * currentDaySize.value + 'px' }"
>
<div class="month-top">{{ item.year }}{{ key }}</div>
</div>
</div>
<div class="topMonth" v-if="showFixdTopMonth">{{ fixdTopMonth }}</div>
<div class="allDaysArray">
<div class="alldays">
<div
v-for="(j, index) in days"
:key="index"
class="day"
:style="{ width: currentDaySize.value + 'px' }"
>
<template v-if="currentDaySize.value === 20">
<span
v-if="j.today"
class="dateNum todayDateNum"
style="border-left:1px solid #d7d7d7;"
>
今天
</span>
<span
v-else
class="dateNum"
:style="{
borderLeft: index == 0 ? 'none' : '1px solid #d7d7d7'
}"
:class="{
weekday: j.weekday == 0 || j.weekday == 6,
isHover:
j.width >= currentLineDay.start &&
j.width <= currentLineDay.end
}"
>{{ j.date }}</span>
<span
class="dateBG"
:class="{
weekday2: j.weekday == 0,
weekday1: j.weekday == 6,
today: j.today
}"
:style="{
width: currentDaySize.value + 'px',
height:
j.weekday == 0 || j.weekday == 6 ? lineBGHeight : '0px'
}"
></span>
</template>
<template v-if="currentDaySize.value == 10">
<span
class="dateNum"
:class="{
weekday: j.weekday == 0 || j.weekday == 6,
isHover:
j.width >= currentLineDay.start &&
j.width <= currentLineDay.end,
nodBorder:
j.width >= currentLineDay.start &&
j.width <= currentLineDay.end
}"
>
<div
v-show="
(j.width === currentLineDay.end &&isHover &&j.weekday !== 1) ||
(j.width === currentLineDay.start &&isHover &&j.weekday !== 1) ||
j.weekday === 1
"
style="width:100%;height:100%;"
:style="{
borderLeft: index === 0 ? 'none' : '1px solid #d7d7d7'
}"
>
{{ j.date }}
</div>
</span>
<span
class="dateBG"
:class="{
weekday2: j.weekday === 0,
weekday1: j.weekday === 6,
today: j.today
}"
:style="{
width: currentDaySize.value + 'px',
height:
j.weekday === 0 || j.weekday === 6 ? lineBGHeight : '0px'
}"
></span>
</template>
<template v-if="currentDaySize.value === 2">
<span
class="dateNum"
:class="{
isHover:
j.width >= currentLineDay.start &&
j.width <= currentLineDay.end,
nodBorder:
j.width >= currentLineDay.start &&
j.width <= currentLineDay.end
}"
>
<div
v-show="
(j.width === currentLineDay.end && isHover && j.date !== 1) ||
(j.width === currentLineDay.start &&isHover &&j.date !== 1) ||
j.date === 1
"
style="width:100%;height:100%;font-size:10px!important;"
:style="{
borderLeft: index === 0 ? 'none' : '1px solid #d7d7d7'
}"
>
{{ j.date }}
</div>
</span>
<span
class="dateBG weekday2"
:class="{
today: j.today
}"
style="border-right:none;"
:style="{
width: currentDaySize.value + 'px',
height:
j.weekday === 0 || j.weekday === 6 ? lineBGHeight : '0px'
}"
></span>
</template>
</div>
</div>
<div class="lineBG" @scroll="handlerBGScroll" ref="lineBG">
<template v-for="(item, index) in computedList">
<!--<div :key="item.id" class="tetst">{{item.id}}</div>-->
<div
:ref="'line' + item.id"
:key="item.id + index"
class="line"
:style="{
left: item.left + 'px',
width: item.widthMe + 'px',
top: item.top + 'px'
}"
@mouseover="
lineMouseover(
`line${item.id}`,
$event,
item.id,
item.parentId,
index
)
"
@mouseleave="lineMouseleave"
@mouseenter="
lineMouseenter(
`line${item.id}`,
$event,
item.id,
item.parentId,
index
)
"
>
<slider
v-show="item.type == 1"
:id="item.id"
v-model="item.per"
:min="0"
:max="item.per"
:per1="item.per1"
:disabled="disable"
:widths="item.widthChild"
></slider>
</div>
<div
v-if="item.type == 3"
:key="item.id"
class="group"
:style="{
top: item.top + 'px',
left: item.left + 'px',
width: item.widthMe + 'px'
}"
>
<div class="progress" :style="{ width: item.per + '%' }"></div>
</div>
</template>
</div>
</div>
<div class="toolTip">
<!--<div class="today base" @click="handleGoToday">今天</div>-->
<el-dropdown trigger="click">
<span class="base">
{{this.currentDaySize.label}}
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu
slot="dropdown"
:style="{ left: this.left + 'px !important' }"
>
<el-dropdown-item
v-for="item in currentDaySizeOptions"
:key="item.value + 'ck'"
@click.native="handleSetDaySize(item)"
>
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<transition name="el-zoom-in-center">
<div
v-show="isShowMsg"
:style="{
left: currentProjectMsg.left + 'px',
top: currentProjectMsg.top + 'px'
}"
class="projectMsg"
>
<div class="lineMsg projectName">
{{ currentProjectMsg.name }}
</div>
<div class="lineMsg">
<span class="title">工作周期</span>
<span>{{ currentProjectMsg.allTime }}</span>
</div>
<div class="lineMsg">
<span class="title">当前进度</span>
<span>{{ currentProjectMsg.per }}</span>
</div>
<div class="lineMsg">
<span class="title">合格数量</span>
<span>{{ currentProjectMsg.per1 }}</span>
</div>
<div class="lineMsg">
<span class="title">开始时间</span>
<span>{{ currentProjectMsg.startTime }}</span>
</div>
<div class="lineMsg">
<span class="title">结束时间</span>
<span>{{ currentProjectMsg.endTime }}</span>
</div>
</div>
</transition>
</div>
</div>
</template>
<script>
import slider from "./components/slider";
import leftMenu from "./components/leftMenu";
import {getPlanGantt} from "@/api/srm";
export default {
components: {
slider,
leftMenu,
},
data() {
return {
//当前项是否是子集
disable: true,
isChildren: false,
dialogVal: false,
//title
title: "新建",
//定时器
timer: null,
//leftMenu的右侧伸缩线
rightLineX: 400,
fixdTopMonth: "",
//近三年的所有年月日
allDays: [],
//所有的天数
days: [],
//月数
monthArr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
//项目数据
list: [{
name: "1-1",
ower: "",
per: 8,
per1: 6,
type: "1",
planTime: [1589472000000, 1589817600000],
stoneTime: "",
startTime: 1589472000000,
endTime: 1589817600000,
left: 20000,
widthChild: 200,
widthMe: 200,
top: 55,
id: 1589512287571,
isShow: true,
parentId: 1589512272596
}
],
//当前hover的项目起止时间
currentLineDay: {
start: 0,
end: 0
},
//当前的时间大小
currentDaySize: {
label: "",
value: 20
},
currentDaySizeOptions: [
{
label: "",
value: 20
},
{
label: "",
value: 10
},
{
label: "",
value: 2
}
],
//是否显示信息
isShowMsg: false,
//当前hover的项目信息
currentProjectMsg: {
name: "",
allTime: 0,
per: 0,
per1: 0,
startTime: 0,
endTime: 0,
left: 0,
top: 0
},
isHover: false,
showFixdTopMonth: false,
currentListIndex: "",
//正在编辑的row
editRow: [],
currentRow: null,
// BG滚动高度
BGScrollTop: 0,
// 背景高度
lineBGHeight: 0,
expandArr: []
};
},
created() {
let that = this;
getPlanGantt({}).then(res=>{
if(res.code===200){
debugger;
let arr =[];
let list = res.data.results;
list.forEach(item => {
if (!item.children || item.children.length < 1) {
let startTime = new Date(item.startTime).getTime();
let endTime = new Date(item.endDate).getTime();
let obj=new Object();
obj.name=item.number;
obj.id=item.id;
obj.top=20;
obj.startTime=startTime;
obj.endTime=endTime;
obj.planTime = [startTime,endTime];
obj.per=item.count;
obj.per1=item.count_real;
obj.type=3;
obj.isShow= true;
arr.push(obj);
} else if (item.children && item.children.length >= 1) {
let startTime = new Date(item.start_date).getTime();
let endTime = new Date(item.start_date).getTime();
debugger;
let temp =[];
let parentId = item.id;
let children = item.children;
children.forEach(child => {
let start = new Date(item.start_date).getTime();
let end = new Date(item.end_date).getTime();
let objChild = new Object();
objChild.name = child.number;
objChild.id = child.id;
objChild.top=50;
objChild.parentId=parentId;
objChild.startTime = start;
objChild.endTime = end;
objChild.planTime = [start,end];
objChild.per = child.count;
objChild.per1 = child.count_real;
objChild.type = 1;
objChild.isShow= true;
temp.push(objChild);
});
let obj=new Object();
obj.name=item.number;
obj.id=item.id;
obj.top=20;
obj.startTime=startTime;
obj.endTime=endTime;
obj.planTime = [startTime,endTime];
obj.per=item.count;
obj.per1=item.count_real;
obj.type=3;
obj.children = temp;
obj.isShow= true;
arr.push(obj);
}
that.list = arr;
that.handlerCheckList(arr);
});
console.log(that.list);
}else{
that.$message.error(res.msg);
}
})
},
computed: {
computedList() {
debugger;
console.log(this.list);
let arr = [];
this.list.forEach(item => {
if (!item.children || item.children.length < 1) {
arr.push(item);
} else if (item.children && item.children.length >= 1) {
arr.push(item);
arr = arr.concat(item.children);
}
});
return arr;
},
left() {
return window.innerWidth - 30;
},
//当前年份
currentYear() {
return new Date().getFullYear();
},
//当前月份
currentMonth() {
return new Date().getMonth() + 1;
},
//当前日
currentDay() {
return new Date().getDate();
}
},
methods: {
TableScrollTop(val) {
let lineBG = this.$refs.lineBG;
lineBG.scrollTo(0, val);
// lineBG.scrollTo({
// top: val,
// left: 0,
// behavior: "smooth"
// });
},
handlerBGScroll(e) {
this.BGScrollTop = this.$refs.chart.scrollTop;
},
//过滤导入的数据
handlerCheckList(list) {
list.forEach((item, index) => {
item.planTime = [];
item.left = this.computedTimeWidth(item.startTime);
item.widthMe = item.widthChild = this.computedTimeWidth(item.startTime, item.endTime) ;
item.isShow = true;
if (index - 1 < 0) {
item.top = 15;
if (item.type == 3) {
item.isexpand = true;
if (item.children.length > 0) {
item.children.forEach((k, i) => {
k.planTime = [];
k.top = item.top + i * 40 + 35;
k.isShow = true;
k.left = this.computedTimeWidth(k.startTime);
k.widthMe = k.widthChild = this.computedTimeWidth(
k.startTime,
k.endTime
);
});
}
}
} else {
if (list[index - 1].type == 3) {
item.top =
list[index - 1].top + list[index - 1].children.length * 40 + 40;
if (item.type == 3) {
item.isexpand = true;
if (item.children.length > 0) {
item.children.forEach((z, o) => {
z.planTime = [];
z.top = item.top + o * 40+40;
z.isShow = true;
z.left = this.computedTimeWidth(z.startTime);
z.widthMe = z.widthChild = this.computedTimeWidth(
z.startTime,
z.endTime
);
});
}
}
} else {
item.top = list[index - 1].top + 40;
}
}
});
list.forEach(item => {
if (item.type == 3) {
this.setGroupWidth(item.id, list);
this.setGroupPer(item.id, list);
}
});
this.list = list;
this.setStoneLine(list);
window.scrollTo({
top: 0,
left: 400,
behavior: "smooth"
});
},
//设置左侧leftmenu高亮
handlerSelect(row) {
this.$refs.leftMenu.handlerSelect(row);
},
//分组是否展开
handlerExpand(row, expand) {
let rowIndex = this.list.findIndex(item => {
return item.id == row.id;
});
this.list[rowIndex].expand = expand;
if (
this.list[rowIndex].children &&
this.list[rowIndex].children.length > 0
) {
this.list[rowIndex].children.forEach(k => {
k.isShow = expand;
});
}
this.resetTop(rowIndex, !expand, true);
},
// 根据时间计算距离
computedTimeWidth(startTime, endTime) {
let start = new Date(startTime).getTime();
let end = new Date(endTime).getTime();
let left =
(Math.floor(
start - new Date(`${this.currentYear - 1}/01/01`).getTime()
) /
(1000 * 60 * 60 * 24)) *
this.currentDaySize.value;
let width =
(Math.floor(end - start) / (1000 * 60 * 60 * 24)) *
this.currentDaySize.value +
this.currentDaySize.value;
if (!endTime) {
return left;
} else {
return width;
}
},
//修改后续高度
resetTop(zindex, reduce, isexpand) {
// console.log(zindex, reduce, isexpand);
let num = reduce ? -40 : 40;
if (!reduce && !isexpand) {
// console.log(2);
this.list.forEach((item, index) => {
if (index > zindex) {
item.top = item.top + 40;
if (item.children && item.children.length > 0) {
item.children.forEach((k, i) => {
k.top = item.top + 40 * i + 40;
});
}
}
});
} else {
// console.log(1);
this.list.forEach((item, index) => {
if (index > zindex) {
item.top = item.top + num * this.list[zindex].children.length;
if (item.children && item.children.length > 0) {
item.children.forEach((k, i) => {
k.top = item.top + 40 * i + 40;
});
}
}
});
}
},
retDelTop(zindex, length) {
this.list.forEach((item, index) => {
if (index >= zindex) {
item.top = item.top - 40 * length;
if (item.children && item.children.length > 0) {
item.children.forEach((k, i) => {
k.top = item.top + 40 * i + 40;
});
}
}
});
},
//根据id设置group的宽度
setGroupWidth(id, lists) {
let parent;
if (lists) {
parent = lists.find(item => {
return item.id == id;
});
} else {
parent = this.list.find(item => {
return item.id == id;
});
}
let left = Math.min.apply(
Math,
parent.children.map(o => {
return o.left;
})
);
let arr = [];
parent.children.forEach(item => {
arr.push(item.left + item.widthMe);
});
let width = Math.max.apply(Math, arr);
let widthMe = width - left;
parent.widthMe = parent.widthChild = widthMe;
parent.left = left;
// return parent;
},
// 转为分组
handlerGroup(row) {
let index = this.list.findIndex(item => {
return item.id == row.id;
});
this.list[index].type = "3";
this.list[index].per = 0;
this.list[index].id = new Date().getTime();
this.list[index].left = 0;
this.list[index].widthMe = this.list[index].widthChild = 0;
this.$set(this.list, index, this.list[index]);
},
//leftMenu宽度设置
rightLineMousedown(e) {
let cx = e.clientX;
let result;
document.onmousemove = event => {
result = event.clientX - cx;
if (cx + result <= 441) return;
this.$refs.rightLine.style.left = cx + result + "px";
};
document.onmouseup = () => {
document.onmousemove = document.onmouseup = null;
if (cx + result <= 441) {
this.rightLineX = 441;
return;
}
this.rightLineX = cx + result;
};
},
//rowClick事件
handlerRowClick(row) {
this.currentRow = row;
this.$refs.chart.scrollTo({
top: 0,
left: row.left - 100,
behavior: "smooth"
});
},
//更改daySize
handleSetDaySize(item) {
// console.log(item);
this.currentDaySize = item;
this.days.forEach((item, index) => {
item.width = (index + 1) * this.currentDaySize.value;
});
this.handleScroll();
if (this.currentRow) {
let rs = this.computedList.find(o => {
return o.id == this.currentRow.id;
});
this.$nextTick(() => {
});
}
},
//滑动进度条事件
thunkMousemove() {
this.isShowMsg = false;
},
//滑动进度条事件
thunkMousedown() {
this.isShowMsg = false;
},
//滑动进度条事件
thunkMouseup(per, e, id, parentId) {
// console.log(per, id, parentId);
let cindex = this.computedList.findIndex(z => {
return z.id == id;
});
if (parentId) {
let index = this.list.findIndex(k => {
return k.id == parentId;
});
// console.log(parentId);
this.list.forEach(item => {
if (item.id == parentId) {
// console.log(item, this.list);
item.children.forEach(k => {
if (k.id == id) {
k.per = per;
}
});
}
});
this.setGroupPer(parentId);
this.$set(this.list, index, this.list[index]);
} else {
this.list.forEach(item => {
if (item.id == id) {
item.per = per;
}
});
}
this.checkIsin(`line${id}`, e, id, parentId, cindex);
},
//设置分组百分比
setGroupPer(id, lists) {
let z;
if (lists) {
z = lists.find(o => {
return o.id == id;
});
} else {
z = this.list.find(o => {
return o.id == id;
});
}
let count = 0;
let length = z.children.length;
z.children.forEach(item => {
count = count + (item.per / 100) * (1 / length);
});
z.per = Math.round(count * 100);
},
//回到今天
handleGoToday() {
let s =
Math.round(window.innerWidth / this.currentDaySize.value / 2) *
this.currentDaySize.value - this.rightLineX;
let width =
(Math.floor(
new Date(
`${this.currentYear}/${this.currentMonth}/${this.currentDay}`
).getTime() - new Date(`${this.currentYear - 1}/01/01`).getTime()
) /
(1000 * 60 * 60 * 24)) *
this.currentDaySize.value - s;
window.scrollTo({
top: 0,
left: width,
behavior: "smooth"
});
},
//根据距离计算时间
/**
* @param {Number} width
* @param {Boolean|String} time
*/
computedWithTime(width, time) {
let startTime =
(width / this.currentDaySize.value) * (1000 * 60 * 60 * 24) +
new Date(`${this.currentYear - 1}/01/01`).getTime();
let s = new Date(startTime);
if (time && time == true) {
return s.getTime();
} else if (time && time == "YD") {
return `${s.getFullYear()}/${s.getMonth() + 1}`;
} else {
return `${s.getFullYear()}/${s.getMonth() + 1}/${s.getDate()}`;
}
},
//根据index值和e判断是否在当前line的范围里是否展示时间和msg框
/**
* @param {String} dom ref
* @param {Object} events $event
* @param {Number} id id
* @param {Number} parentId parentId
* @param {Number} index index
*/
checkIsin(dom, events, id, parentId, index) {
let line = this.$refs[dom][0];
let lineTop = parseInt(line.style.top);
let lineDown = lineTop + 16;
let lineLeft = parseInt(line.style.left);
let lineRight = parseInt(this.computedList[index].widthMe) + lineLeft;
if (
events.pageX - this.rightLineX >= lineLeft &&
events.pageX - this.rightLineX <= lineRight &&
events.y - 40 >= lineTop &&
events.y - 40 <= lineDown
) {
this.lineMouseover(dom, events, id, parentId, index);
this.lineMouseenter(dom, events, id, parentId, index);
} else {
this.isShowMsg = false;
this.currentLineDay = {
start: 0,
end: 0
};
}
},
/**
* @param {String} dom ref
* @param {Object} events $event
* @param {Number} id id
* @param {Number} parentId parentId
* @param {Number} index index
*/
//鼠标悬停展示上部日期
lineMouseover(dom, e, id, parentId, index) {
let start =
Math.round(
parseInt(this.$refs[dom][0].style.left) / this.currentDaySize.value
) *
this.currentDaySize.value +
this.currentDaySize.value;
let end =
parseInt(this.$refs[dom][0].style.left) +
parseInt(this.$refs[dom][0].style.width);
end =
Math.round(end / this.currentDaySize.value) * this.currentDaySize.value;
this.currentLineDay = {
start,
end
};
this.isHover = true;
this.handlerSelect(this.computedList[index]);
this.lineMouseenter(dom, e, id, parentId, index);
},
/**
* @param {String} dom ref
* @param {Object} events $event
* @param {Number} id id
* @param {Number} parentId parentId
* @param {Number} index index
*/
//鼠标进入显示当前项目的基本信息框
lineMouseenter(dom, e, id, parentId, index) {
let start =
Math.round(
parseInt(this.$refs[dom][0].style.left) / this.currentDaySize.value
) * this.currentDaySize.value;
let end =
parseInt(this.$refs[dom][0].style.left) +
parseInt(this.$refs[dom][0].style.width);
end =
Math.round(end / this.currentDaySize.value) *
this.currentDaySize.value -
this.currentDaySize.value;
this.currentProjectMsg = {
name: this.computedList[index].name,
allTime: (end - start) / this.currentDaySize.value + 1,
per: this.computedList[index].per,
per1: this.computedList[index].per1,
startTime: this.computedWithTime(start),
endTime: this.computedWithTime(end),
left: e.clientX ,
top: e.clientY + 20
};
/*
* left:
e.clientX + 220 - this.$refs.chart.scrollLeft >= this.$refs.chart.clientWidth
? e.clientX - 220 - 400
: e.clientX ,
* */
this.isShowMsg = true;
},
//鼠标离开信息消失时间显示消失
/**
* @param {Object} e $event
* @param {Boolean} move 是否移动状态
*/
lineMouseleave(e, move) {
if (move) {
this.isShowMsg = false;
this.currentProjectMsg = {
name: "",
allTime: 0,
per: 0,
startTime: 0,
endTime: 0,
left: 0,
top: 0
};
// this.handlerSelect();
return;
}
this.currentLineDay = {
start: 0,
end: 0
};
this.isHover = false;
this.isShowMsg = false;
this.currentProjectMsg = {
name: "",
allTime: 0,
per: 0,
startTime: 0,
endTime: 0,
left: 0,
top: 0
};
this.handlerSelect();
},
//获取近三年的所有天数
getDay() {
this.getAllDate();
},
//判断是否为闰年
/**
* @param {Number} year 传入年份
*/
isLeapYear(year) {
if (year % 4 > 0) {
return true;
}
return false;
},
getAllDate() {
let obj = {};
let arr = [this.currentYear - 1, this.currentYear, this.currentYear + 1];
arr.forEach(item => {
obj.year = item;
obj.days = this.isLeapYear(item) ? 365 : 366;
this.allDays.push(obj);
obj = {};
});
this.checkDate();
},
//根据年份天数创建月份及月份天数数组
checkDate() {
this.allDays.forEach(item => {
item.month = this.handleMonthDay(item.days, item.year);
});
// console.log(this.allDays);
this.allDays.forEach(element => {
if (element.year == this.currentYear) {
element.month[0][this.currentMonth].forEach(k => {
if (k.date == this.currentDay) {
k.today = true;
}
});
}
});
let arr = [];
this.allDays.forEach(item => {
arr = arr.concat(item.month);
});
arr.forEach(item => {
for (var j in item) {
this.days = this.days.concat(item[j]);
}
});
this.days.forEach((item, index) => {
item.width = (index + 1) * this.currentDaySize.value;
});
},
/**
* @param {Number} days
* @param {Number} year
*/
handleMonthDay(days, year) {
let arr = [];
let obj = {};
this.monthArr.forEach(item => {
obj[item] = this.checkMonthDays(item, days);
});
arr.push(obj);
let s = arr[0];
for (let item in s) {
s[item] = this.addNum(s[item], item, year);
}
// console.log(arr);
return arr;
},
/**
* @param {number} num 天数
* @param {number} month 月份
* @param {number} year 年份
*/
addNum(num, month, year) {
let arr = [];
let obj = {};
for (let i = 1; i <= num; i++) {
obj.date = i;
obj.weekday = new Date(`${year}/ ${month} / ${i}`).getDay();
arr.push(obj);
obj = {};
}
return arr;
},
//根据月份返回天数
/**
* @param {Number} month 月份
* @param {Number} days 天数
*/
checkMonthDays(month, days) {
let day;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
// eslint-disable-next-line no-unreachable
break;
case 4:
case 6:
case 9:
case 11:
return 30;
// eslint-disable-next-line no-unreachable
break;
case 2:
day = days == 365 ? 28 : 29;
return day;
// eslint-disable-next-line no-unreachable
break;
}
},
setList() {
/*getPlanGantt().then(res=>{
if(res.code===200){
this.list = res.data.results;
}else{
this.$message.error(res.msg);
}
})*/
},
//设置里程碑线的高度
setStoneLine(isFirst) {
this.$nextTick(() => {
let height = window.getComputedStyle(
document.getElementsByClassName("lineBG")[0]
).height;
this.lineBGHeight = height;
});
},
//顶部固定时间
handleScroll() {
let w = window.scrollX;
if (w <= 62) {
this.showFixdTopMonth = false;
} else {
this.showFixdTopMonth = true;
}
let time = this.computedWithTime(w, "YD");
this.fixdTopMonth = time;
}
},
watch: {
currentDaySize(newValue, oldValue) {
this.list.forEach(item => {
item.left = (item.left / oldValue.value) * newValue.value;
item.widthMe = item.widthChild =
(item.widthMe / oldValue.value) * newValue.value;
if (item.children && item.children.length > 0) {
item.children.forEach(k => {
k.left = (k.left / oldValue.value) * newValue.value;
k.widthMe = k.widthChild =
(k.widthMe / oldValue.value) * newValue.value;
});
}
});
}
},
mounted() {
document.addEventListener("scroll", this.handleScroll);
this.getDay();
this.setList();
this.setStoneLine();
},
beforeDestroy() {
window.removeEventListener("scroll", this.handleScroll);
document.onmousemove = document.onmouseup = null;
}
};
</script>
<style lang="scss" scoped>
.chart {
height: 90vh;
user-select: none;
position: relative;
overflow: hidden;
overflow-x: scroll;
background: #ffffff;
.header {
height: 40px;
position: relative;
.header-left {
margin-left: 10px;
box-sizing: border-box;
padding-top: 5px;
height: 40px;
position: fixed;
top: 0;
left: 0;
background-color: #fff;
}
}
.left {
position: fixed;
/*height: calc(100% - 40px);*/
height: 89vh;
background-color: #fff;
z-index: 999;
// border-right: 1px solid #d7d7d7;
.rightLine {
z-index: 999;
position: absolute;
top: 0;
height: 100%;
width: 2px;
background-color: #d7d7d7;
box-shadow: 4px 2px 12px 0 rgba(0, 0, 0, 0.2);
cursor: col-resize;
&:hover {
background-color: #409eff;
}
}
}
.showCurrentLineDate {
position: fixed;
top: 0;
background-color: #409eff;
color: #fff;
height: 20px;
font-size: 16px;
display: flex;
align-items: center;
justify-content: space-between;
}
.projectMsg {
box-sizing: border-box;
padding: 20px;
position: fixed;
width: 230px;
/*height: 230px;*/
z-index: 12000;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 4px;
border: 1px solid #ebeef5;
.lineMsg {
margin-bottom: 10px;
&.projectName {
font-size: 22px;
color: #333333;
text-align: center;
border-bottom: 1px solid #999999;
}
span {
font-size: 14px;
color: #909090;
}
.title {
margin-right: 5px;
color: #666666
}
}
}
.date {
display: flex;
height: 100%;
position: relative;
/*overflow: scroll;*/
.topMonth {
// width: 100px;
background-color: #fff;
position: fixed;
top: 40px;
height: 21px;
line-height: 21px;
font-size: 12px !important;
font-weight: 600 !important;
color: #909090 !important;
}
.toolTip {
position: fixed;
right: 0;
top: 90px;
z-index: 999;
.base {
display: inline-block;
text-align: center;
height: 30px;
line-height: 30px;
padding: 0 15px;
background-color: #fff;
font-size: 14px;
cursor: pointer;
user-select: none;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
font-weight: 400;
color: #303030;
border-radius: 3px;
box-shadow: 0 3px 12px 0 rgba(48, 48, 48, 0.05),
0 3px 6px 0 rgba(48, 48, 48, 0.1);
margin-right: 20px;
&:hover {
color: #409eff;
}
}
}
.group {
position: absolute;
background-color: #909090 !important;
border: none !important;
border-radius: 0 !important;
height: 14px !important;
line-height: 14px !important;
// margin-top: 5px;
clip-path: polygon(
100% 0,
100% 100%,
calc(100% - 8px) 60%,
8px 60%,
0 100%,
0 0
);
// > div {
// -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
// }
.progress {
// width: 50px;
background-color: #606060 !important;
height: 100%;
}
}
}
.line {
position: absolute;
height: 20px;
background: #abf7f7;
.rightCurDrag {
cursor: e-resize;
width: 10px;
background-color: #000;
height: 16px;
position: absolute;
right: -15px;
transform: translateY(-50%);
top: 50%;
border-radius: 3px;
user-select: none;
}
.leftCurDrag {
cursor: e-resize;
width: 10px;
background-color: #000;
height: 16px !important;
position: absolute;
left: -15px;
transform: translateY(-50%);
top: 50%;
border-radius: 3px;
user-select: none;
}
.stoneLine {
position: absolute;
top: 0px;
left: 50%;
margin-left: -1px;
width: 2px;
background-color: #24b47e;
}
.milestone {
position: absolute;
left: 50%;
// transform: translateX(-50%);
cursor: move;
margin-left: -10px;
width: 20px;
height: 20px;
background-color: #24b47e;
transform: rotate(-45deg);
display: flex;
justify-content: center;
align-items: center;
i {
transform: rotate(45deg);
color: #fff;
z-index: 1;
}
}
}
.years {
display: flex;
height: 100%;
.month {
height: 100%;
.month-top {
height: 21px;
line-height: 21px;
font-size: 12px !important;
font-weight: 600 !important;
color: #909090 !important;
}
}
}
.allDaysArray {
position: absolute;
left: 0px;
top: 21px;
height: calc(100% - 21px);
.alldays {
display: flex;
}
.lineBG {
width: 100%;
height: 100%;
position: relative;
overflow: scroll;
}
.weekday {
color: #c7c7c7;
}
.weekday1 {
border-left: 1px solid #d7d7d7;
background-image: linear-gradient(to bottom, #f8f8f8, #f8f8f8);
}
.weekday2 {
border-right: 1px solid #d7d7d7;
background-image: linear-gradient(to bottom, #f8f8f8, #f8f8f8);
width: 100%;
}
.day {
// width: 40px;
position: relative;
display: inline-block;
height: calc(100% - 21px);
box-sizing: border-box;
text-align: center;
.isHover {
background-color: #409eff;
color: #fff;
}
.nodBorder {
div {
border-left: none !important;
}
}
.dateNum {
font-size: 12px;
line-height: 20px;
display: block;
height: 20px;
// border-left: 1px solid #d7d7d7;
border-bottom: 1px solid #d7d7d7;
box-sizing: border-box;
}
.todayDateNum {
background-color: #f0a100;
color: #fff;
}
.dateBG {
position: absolute;
top: 20px;
left: 0px;
display: block;
// height: 100%;
}
.today {
position: relative;
}
.today::after {
content: "";
height: 100%;
width: 2px;
background-color: #f0a100;
position: absolute;
// left: 20px;
top: 0px;
}
}
}
}
</style>