655 lines
18 KiB
Vue
Raw Normal View History

<template>
2022-11-22 16:31:07 +08:00
<div style="height: 100%">
<div ref="gantt" style="height: 100%">
<template slot-scope="scope">
<el-popover
popper-class="area_popper"
offset="-150"
trigger="hover"
:open-delay="0"
:close-delay="0"
placement="top"
:disabled="isShowBox"
>
<!-- 提示的文字框显示所有的部门信息 -->
<p class="showText">{{ scope.row.text }}</p>
<!-- 利用三元表达式判断是否超过预期的长度 -->
<!-- <div slot="reference">{{ scope.row.address.length > 20? scope.row.address.slice(0, 20) + '...' : scope.row.address}}</div> -->
</el-popover>
</template>
</div>
</div>
</template>
2022-11-22 16:31:07 +08:00
<script>
import {
addProgressTaskApi, //增加
deleteTaskAlarmApi, //删除
editProgressTaskApi, //编辑
getParentChildListApi, //查询
} from "@/assets/js/api/scheduleInfo";
2023-02-07 10:10:36 +08:00
import $ from 'jquery'
import 'jquery-ui-dist/jquery-ui'
import 'jquery-ui-dist/jquery-ui.min.css'
import { gantt } from "dhtmlx-gantt";
import moment from "moment";
export default {
name: "gantt",
2022-11-22 16:31:07 +08:00
props: {
tasks: {
type: Object,
default() {
return {
data: [],
2022-11-23 16:17:34 +08:00
links: [],
2022-11-22 16:31:07 +08:00
};
},
},
},
data() {
return {
2023-02-07 10:10:36 +08:00
events:[],
2022-11-23 16:17:34 +08:00
dataLinks: [],
title: "",
width: 800,
visible: false,
disablesubmit: false,
2022-11-22 16:31:07 +08:00
projectSn: "", //项目sn
2022-11-23 16:17:34 +08:00
dataList: [], //
};
},
mounted: function () {
//日期格式化
gantt.config.xml_date = "%Y-%m-%d";
//左侧是否自适应
gantt.config.autofit = true;
//左侧宽
2022-11-23 16:17:34 +08:00
gantt.config.grid_width = 1000;
//取消连线
2022-11-22 16:31:07 +08:00
gantt.config.drag_links = true;
//只读
gantt.config.readonly = false;
//右侧显示列名
gantt.config.date_scale = "%Y-%m-%d";
//自动调整图表坐标轴区间用于适配task的长度
gantt.config.fit_tasks = true;
//弹窗宽
gantt.config.wide_form = false;
//汉化
gantt.locale = {
date: {
month_full: [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
],
month_short: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
day_full: [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
],
day_short: ["日", "一", "二", "三", "四", "五", "六"],
},
labels: {
dhx_cal_today_button: "今天",
day_tab: "日",
week_tab: "周",
month_tab: "月",
new_event: "新建日程",
icon_save: "保存",
icon_cancel: "关闭",
icon_details: "详细",
icon_edit: "编辑",
icon_delete: "删除",
confirm_closing: "请确认是否撤销修改!", //Your changes will be lost, are your sure?
confirm_deleting: "是否删除计划?",
2022-11-22 16:31:07 +08:00
section_description: "备注:",
section_time: "计划时间:",
section_time2: "开始时间:",
2023-02-07 10:10:36 +08:00
section_deadline: "实际时间:",
section_type: "类型",
2022-11-22 16:31:07 +08:00
section_text: "任务名称:",
section_color: "颜色:",
2022-11-22 16:31:07 +08:00
//-----
section_status: "完成状态:",
section_progress: "进度比例:",
2022-11-23 16:17:34 +08:00
section_taskTypeId: "任务模式:",
2022-11-22 16:31:07 +08:00
section_taskduration: "任务工期:",
2022-11-05 13:35:16 +08:00
/* grid columns */
column_text: "计划名称",
column_start_date: "开始时间",
column_duration: "持续时间",
column_add: "",
2022-11-22 16:31:07 +08:00
column_id: "",
column_predecessors: "",
column_duration: "",
2022-11-05 13:35:16 +08:00
/* link confirmation */
link: "关联",
confirm_link_deleting: "将被删除",
link_start: " (开始)",
link_end: " (结束)",
type_task: "任务",
type_project: "项目",
type_milestone: "里程碑",
minutes: "分钟",
hours: "小时",
days: "天",
weeks: "周",
months: "月",
years: "年",
},
};
gantt.plugins({ marker: true, tooltip: true }); // 开启marker插件
// 提示框内容
gantt.templates.tooltip_text = function (start, end, task) {
return (
"<b>任务名称:</b>" +
task.text +
"<br/><b>计划开始日期:</b> " +
moment(task.start_date).format("YYYY-MM-DD") +
"<br/><b>计划完成日期:</b> " +
moment(task.end_date).format("YYYY-MM-DD")
);
// "<br/><b>实际开始日期:</b> " + task.actual_start_date +
// "<br/><b>实际完成日期:</b> " + task.actual_end_date
};
2022-11-22 16:31:07 +08:00
//左侧显示列名
gantt.config.columns = [
2022-11-22 16:31:07 +08:00
{ name: "id", label: "id", width: "160", align: "center" },
2022-11-23 16:17:34 +08:00
{
2022-11-22 16:31:07 +08:00
name: "text",
label: "任务名称",
tree: true,
2022-11-23 16:17:34 +08:00
width: "150",
align: "center",
2022-11-22 16:31:07 +08:00
resize: true,
},
{
name: "predecessorIds",
label: "前置任务",
2022-11-23 16:17:34 +08:00
width: "140",
2022-11-22 16:31:07 +08:00
align: "center",
resize: true,
},
{
name: "start_date",
label: "计划开始日期",
align: "center",
width: "100",
resize: true,
},
{
name: "end_date",
label: "计划完成日期",
align: "center",
width: "100",
resize: true,
},
{
2023-02-07 10:10:36 +08:00
name: "planned_start",
2022-11-22 16:31:07 +08:00
label: "实际开始日期",
align: "center",
width: "100",
resize: true,
},
{
2023-02-07 10:10:36 +08:00
name: "planned_end",
2022-11-22 16:31:07 +08:00
label: "实际完成日期",
align: "center",
width: "100",
resize: true,
},
{ name: "duration", label: "任务工期", align: "center" },
{
2022-11-23 16:17:34 +08:00
name: "progressRatio",
2022-11-22 16:31:07 +08:00
label: "进度比例",
align: "center",
resize: true,
template: function (obj) {
return Math.floor(obj.progress * 100).toString() + "%";
},
},
{ name: "add", label: "" },
];
2023-02-07 10:10:36 +08:00
function startDatepicker(node){
return $(node).find("input[name='start']");
}
function endDateInput(node){
return $(node).find("input[name='end']");
}
gantt.form_blocks["datepicker"] = {
render(sns) { //sns - the section's configuration object
return "<div class='gantt-lb-datepicker'>"+
"<input type='text' name='start' placeholder='请选择实际开始时间' style='height:20px;margin:0 0px 0 10px'>"+'-'+
"<input type='text' name='end' placeholder='请选择实际结束时间' style='height:20px'>"+
"</div>";;
},
set_value(node, value, task, section) {
startDatepicker(node).datepicker({
dateFormat: "yy-mm-dd",
onSelect: () => {
}
});
startDatepicker(node).datepicker("setDate", task.planned_start);
endDateInput(node).datepicker({
dateFormat: "yy-mm-dd",
onSelect: function (dateStr) {
// gantt.ext.inlineEditors.save()
}
});
endDateInput(node).datepicker("setDate", task.planned_end);
},
get_value(node, task, section) {
if(task.planned_start && task.planned_end) {
var start = startDatepicker(node).datepicker('getDate');
var end = endDateInput(node).datepicker('getDate');
task.planned_start = start;
task.planned_end = end;
}
// task.duration = gantt.calculateDuration(task);
},
focus(node) {
}
}
//弹出层
2023-02-07 10:10:36 +08:00
gantt.config.lightbox.sections = [
2022-11-22 16:31:07 +08:00
//工程名称
{
name: "text",
height: 30,
map_to: "text",
type: "textarea",
focus: true,
width: 250,
2022-11-22 16:31:07 +08:00
},
//计划开始/结束时间
2022-11-22 16:31:07 +08:00
{
name: "time",
height: 30,
map_to: "auto",
2022-11-22 16:31:07 +08:00
type: "time",
time_format: ["%Y", "%m", "%d"],
},
2023-02-07 10:10:36 +08:00
//实际开始/结束时间
{
name: "deadline",
height: 30,
type: "datepicker",
map_to:"auto",
},
2022-11-22 16:31:07 +08:00
// 完成状态
{
name: "status",
height: 30,
map_to: "status",
type: "select",
options: [
{ key: 1, label: "未开始", color: "#4C87FF" },
{ key: 2, label: "进行中", color: "#54CF8" },
{ key: 3, label: "已完成", color: "#F2D026F" },
2022-11-22 16:31:07 +08:00
],
},
//任务模式
{
2022-11-23 16:17:34 +08:00
name: "taskTypeId",
2022-11-22 16:31:07 +08:00
height: 30,
map_to: "taskTypeId",
type: "select",
options: [
{ key: 1, label: "手动" },
{ key: 2, label: "自动" },
2022-11-22 16:31:07 +08:00
],
},
//任务工期
{
name: "taskduration",
height: 30,
map_to: "duration",
type: "textarea",
focus: true,
},
//进度
{
name: "progress",
height: 30,
map_to: "progress",
type: "textarea",
focus: true,
},
// //颜色
// {
// name: "color",
// height: 30,
// map_to: "color",
// type: "select",
// options: [
// { key: "#4C87FF", label: "紫色" },
// { key: "#54CF8E", label: "绿色" },
// { key: "#F2D026", label: "黄色" },
// { key: "#FF6C7F", label: "水红色" },
// ],
// },
2022-11-22 16:31:07 +08:00
//备注
{
name: "description",
height: 40,
map_to: "remark",
type: "textarea",
},
];
//弹窗标题 日期范围
gantt.templates.task_time = function (start, end, task) {
return (
2023-02-07 10:10:36 +08:00
moment(task.start_date).format("YYYY-MM-DD") +
" - " +
2023-02-07 10:10:36 +08:00
moment(task.end_date).format("YYYY-MM-DD")
);
};
//弹窗标题 计划名称
2022-11-22 16:31:07 +08:00
gantt.templates.task_text = function (start, end, task) {
return task.text;
};
gantt.init(this.$refs.gantt);
let this_ = this;
//添加后触发
gantt.attachEvent("onAfterTaskAdd", function (id, item) {
2022-11-23 16:17:34 +08:00
console.log("添加后触发", this_.dataList);
console.log("添加后触发 item", item);
if (item.parent != 0 && item.parent != null) {
this_.checkLinks(this_.dataList, item.parent);
} else {
console.log("父亲调用");
this_.dataList.forEach((res) => {
this_.dataLinks.push(res.id);
});
}
console.log("添加后触发 predecessorIds 2-- ", this_.dataLinks);
let data = {
children: [],
duration: Number(item.ck),
2022-11-23 16:17:34 +08:00
feedbackList: [],
parentId: item.parent,
predecessorIds: this_.dataLinks.join(","),
progressRatio: item.progress,
remark: item.remark,
startDate: moment(item.start_date).format("YYYY-MM-DD"),//计划开始
status: Number(item.status) - 1,
2022-11-23 16:17:34 +08:00
projectSn: this_.$store.state.projectSn,
createUserId: this_.$store.state.userInfo.userId,
taskName: item.text,
taskTypeId: Number(item.taskTypeId) - 1,
finishDate: moment(item.end_date).format("YYYY-MM-DD"),//计划结束
2023-02-07 10:10:36 +08:00
actualStartDate: moment(item.planned_start).format("YYYY-MM-DD"),//实际开始
actualFinishDate: moment(item.planned_end).format("YYYY-MM-DD"),//实际结束
2022-11-23 16:17:34 +08:00
};
addProgressTaskApi(data).then((res) => {
console.log("添加的数据", res);
this_.getParentChildList();
});
this_.dataLinks = [];
});
//移动进度后触发
gantt.attachEvent("onAfterTaskDrag", function (id, mode, e) {
2022-11-23 16:17:34 +08:00
// console.log("移动进度后触发mode", mode);
// this_.changeTask();
});
//移动任务后触发
gantt.attachEvent("onAfterTaskMove", function (id, parent, tindex) {
2022-11-23 16:17:34 +08:00
// console.log("移动任务后触发", mode);
// this_.changeTask();
});
//删除任务后触发
gantt.attachEvent("onAfterTaskDelete", function (id, item) {
2022-11-23 16:17:34 +08:00
console.log("删除任务后触发,", id);
deleteTaskAlarmApi({ id: id }).then((res) => {
console.log("添加的数据", res);
this_.getParentChildList();
});
});
//修改任务后触发
2023-02-07 10:10:36 +08:00
const onAfterTaskDrag =gantt.attachEvent("onAfterTaskUpdate", function (id, item) {
console.log("修改任务后触发", item);
2022-11-23 16:17:34 +08:00
let data = {
duration: Number(item.ck),
2022-11-23 16:17:34 +08:00
progressRatio: item.progress,
remark: item.remark,
startDate: moment(item.start_date).format("YYYY-MM-DD"),//计划开始
status: Number(item.status) - 1,
2022-11-23 16:17:34 +08:00
id: id,
projectSn: this_.$store.state.projectSn,
createUserId: this_.$store.state.userInfo.userId,
taskName: item.text,
taskTypeId: Number(item.taskTypeId) - 1,
finishDate: moment(item.end_date).format("YYYY-MM-DD"),//计划结束
2023-02-07 10:10:36 +08:00
actualStartDate: moment(item.planned_start).format("YYYY-MM-DD"),//实际开始
actualFinishDate: moment(item.planned_end).format("YYYY-MM-DD"),//实际结束
2022-11-23 16:17:34 +08:00
};
editProgressTaskApi(data).then((res) => {
console.log("修改的数据", res);
this_.getParentChildList();
});
});
2023-02-07 10:10:36 +08:00
this_.events.push(onAfterTaskDrag)
2022-11-22 16:31:07 +08:00
//拖拽任务后触发
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
// console.log("拖拽任务后触发",id, mode, task, original);
});
//保存验证
gantt.attachEvent("onLightboxSave", function (id, item) {
2022-11-23 16:17:34 +08:00
// setTimeout(function () {
item.ck = item.duration;
2022-11-23 16:17:34 +08:00
console.log("保存验证,", item);
// if (!item.taskName) {
// gantt.message({ type: "error", taskName: "请填写任务名称!" });
// return false;
// }
// }, 2000);
return true;
});
},
2022-11-22 16:31:07 +08:00
created() {
this.projectSn = this.$store.state.projectSn;
this.getParentChildList();
},
2023-02-07 10:10:36 +08:00
beforeDestroy () {
this.events.forEach(ele => {
gantt.detachEvent(ele)
})
},
methods: {
2022-11-22 16:31:07 +08:00
//数据格式整理
2023-02-07 10:10:36 +08:00
changeTask(ganttValue) {
2022-11-22 16:31:07 +08:00
// return
2023-02-07 10:10:36 +08:00
const taskCount = ganttValue.length;
let taskData = [];
let openTask = [];
for (let i = 0; i < taskCount; i++) {
let taskOne = {};
2023-02-07 10:10:36 +08:00
const obj = ganttValue[i];
if (obj == null || typeof obj.id === "number") {
2022-11-23 16:17:34 +08:00
continue;
}
2022-11-22 16:31:07 +08:00
taskOne.taskName = obj.taskName;
//打开状态继续打开
if (obj.$open == true) {
openTask.push(obj.id);
}
//整理数据格式
taskOne.id = obj.id;
2022-11-22 16:31:07 +08:00
taskOne.text = obj.taskName || obj.text;
2023-02-07 10:10:36 +08:00
2022-11-22 16:31:07 +08:00
if (obj.startDate != null) {
taskOne.start_date = moment(obj.startDate).format("YYYY-MM-DD");
}
if (obj.finishDate != null) {
taskOne.end_date = moment(obj.finishDate).format("YYYY-MM-DD");
}
if (obj.actualStartDate != null) {
2023-02-07 10:10:36 +08:00
taskOne.planned_start = moment(obj.actualStartDate).format(
2022-11-22 16:31:07 +08:00
"YYYY-MM-DD"
);
}
if (obj.actualFinishDate != null) {
2023-02-07 10:10:36 +08:00
taskOne.planned_end = moment(obj.actualFinishDate).format("YYYY-MM-DD");
2022-11-22 16:31:07 +08:00
}
taskOne.duration = obj.duration;
2022-11-22 16:31:07 +08:00
taskOne.progress = obj.progressRatio;
2022-11-23 16:17:34 +08:00
taskOne.projectSn = obj.projectSn;
2022-11-22 16:31:07 +08:00
taskOne.description = obj.remark;
taskOne.predecessorIds = obj.predecessorIds;
2022-11-23 16:17:34 +08:00
taskOne.parent = obj.parent;
// 0未开始 ,1进行中2已完成
taskOne.color =
obj.status === 0 ? "#ccc" : obj.status === 1 ? "yellow" : "green";
taskOne.status = obj.status + 1;
taskOne.taskTypeId = obj.taskTypeId + 1;
2022-11-23 16:17:34 +08:00
2022-11-22 16:31:07 +08:00
if (obj.parentId) {
taskOne.parent = obj.parentId;
}
2023-02-07 10:10:36 +08:00
if(i == 0) {
console.log("第一条数据结构 ", JSON.stringify(taskOne));
}
taskData.push(taskOne);
}
2022-11-22 16:31:07 +08:00
this.$props.tasks.data = taskData;
//清空数据
gantt.clearAll();
//加载
2022-11-22 16:31:07 +08:00
gantt.parse(this.$props.tasks);
//遍历打开,使之前打开的父级继续打开
openTask.forEach((id) => {
gantt.open(id);
});
},
2022-11-22 16:31:07 +08:00
//获取甘特图父子节点数据
getParentChildList() {
this.tasks.data = [];
2022-11-22 16:31:07 +08:00
getParentChildListApi({ projectSn: this.projectSn }).then((res) => {
2022-11-23 16:17:34 +08:00
this.check(res.result);
this.dataList = res.result;
this.$props.tasks.data = this.tasks.data;
2023-02-07 10:10:36 +08:00
// gantt.parse(this.$props.tasks);
this.changeTask(this.tasks.data);
2022-11-22 16:31:07 +08:00
});
},
2022-11-23 16:17:34 +08:00
check(val) {
let arr = [];
val.forEach((res) => {
this.tasks.data.push(res);
if (res.predecessorIds != "" && res.predecessorIds != null) {
let dataLinks = res.predecessorIds.split(",");
let dataLink = {
source: dataLinks[dataLinks.length - 1],
target: res.id,
type: "1",
};
this.tasks.links.push(dataLink);
}
if (res.children.length >= 1) {
res.children.forEach((restwo) => {
arr.push(restwo);
});
}
});
if (arr.length >= 1) {
this.check(arr);
}
},
checkLinks(val, id) {
let arrLink = [];
val.forEach((res) => {
if (res.id === id) {
console.log(
"找到爸爸了 --" + id + "---- children -" + res.children
);
if (res.children != null && res.children.length >= 1) {
res.children.forEach((resLink) => {
this.dataLinks.push(resLink.id);
});
console.log("找到爸爸了 ,返回的数据 ", this.dataLinks);
}
} else {
if (res.children != null && res.children.length != 0) {
res.children.forEach((resLink) => {
arrLink.push(resLink);
});
}
}
});
if (arrLink.length >= 1) {
this.checkLinks(arrLink, id);
}
},
},
};
</script>
2022-11-22 16:31:07 +08:00
<style lang="less" scoped>
@import "~dhtmlx-gantt/codebase/dhtmlxgantt.css";
::v-deep .gantt_tree_content {
height: 100%;
white-space: nowrap;
min-width: 0;
text-overflow: ellipsis;
overflow: hidden;
cursor: pointer;
}
2023-02-07 10:10:36 +08:00
</style>