更多功能看演示系统
gitee源代码地址
后端代码: https://gitee.com/nbacheng/nbcio-boot
前端代码:https://gitee.com/nbacheng/nbcio-vue.git
在线演示(包括H5) : http://122.227.135.243:9888
基于项目的任务显示,最直观的就是甘特图显示,所以今天就说甘特图的显示
经过选择,最终选择dhtmlx-gantt组件,使用最新的8.0.3版本,当然这个组件就是一些高级功能需要付费。
1、后端代码
获取项目任务相关信息如下:
@Override
public Result<?> taskGantt(Map<String, Object> mmap) {
String projectId = MapUtils.getString(mmap, "projectId");
List<Map> listStagesGantt = taskStagesMapper.selectTaskStagesGanttByProjectId(projectId);
List<Map> listTasksGantt = baseMapper.selectTaskGanttByProjectId(projectId);
if (!CollectionUtils.isEmpty(listStagesGantt)) {
if (!CollectionUtils.isEmpty(listTasksGantt)) {
for (Map stagesmap : listStagesGantt) {
for (Map tasksmap : listTasksGantt) {
if (ObjectUtils.isEmpty(tasksmap.get("parent"))) {
tasksmap.replace("parent", stagesmap.get("id"));
}
}
}
Map<String, Object> tasksmap = new HashMap<String, Object>();
listStagesGantt.addAll(listTasksGantt);
tasksmap.put("data", listStagesGantt);
return Result.OK(tasksmap);
} else {
Map<String, Object> tasksmap = new HashMap<String, Object>();
tasksmap.put("data", listStagesGantt);
return Result.OK(tasksmap);
}
} else {
return Result.error("获取不到数据");
}
}
其中用到的两个sql如下,注意下面对日期做了格式转换:
@Select("select id,name as text,null assign_to,null as start_date,null as end_date,sort,null parent from tw_task_stages where project_id = #{projectId} order by sort" )
List<Map> selectTaskStagesGanttByProjectId(@Param("projectId") String projectId);
@Select("select id,name as text,assign_to,DATE_FORMAT(begin_time,'%d-%m-%Y') as start_date,DATE_FORMAT(end_time,'%d-%m-%Y') as end_date, id_num as sort, pid as parent from tw_task where project_id = #{projectId} order by sort")
List<Map> selectTaskGanttByProjectId(@Param("projectId") String projectId);
2、前端代码
<template>
<div class="project-space-gantt">
<div class="project-navigation">
<div class="project-nav-header">
<a-breadcrumb>
<a-breadcrumb-item>
<a>
<a-icon type="home" />
首页
</a>
</a-breadcrumb-item>
</a-breadcrumb>
</div>
<section class="nav-body">
<ul class="nav-wrapper nav nav-underscore pull-left">
<li><a class="app" data-app="tasks" @click="$router.push('/estar/teamwork/space/task/' + id)">任务</a></li>
<li class="app"><a class="app" data-app="works" @click="$router.push('/estar/teamwork/space/files/' + id)">
文件</a>
<li><a class="app" data-app="build" @click="$router.push('/estar/teamwork/space/overview/' + id)">
概览</a>
</li>
<li class=""><a class="app" data-app="build" @click="$router.push('/estar/teamwork/space/features/' + id)">
版本</a>
</li>
<li class="actives"><a class="app" data-app="build"
@click="$router.push('/estar/teamwork/space/gantt/' + id)">
甘特图</a>
</li>
</ul>
</section>
</div>
<wrapper-content :showHeader="false">
<div class="content-wrapper">
<div class="ganntClass" :style="{ height: ganttHeight }" v-loading="ganttLoading">
<div ref="gantt" class="gantt-container" />
</div>
</div>
</wrapper-content>
</div>
</template>
<script>
import {
mapState
} from 'vuex'
import {
getTasksGanttByProjectId
} from "@/api/teamwork/task";
import WrapperContent from '../components/WrapperContent'
import '@/assets/tw/css/theme.less';
import gantt from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
export default {
name: "project-space-gantt",
components: {
WrapperContent
},
data() {
return {
id: this.$route.params.id,
loading: true,
showLoading: false,
loadingMore: false,
//gantt高度
ganttHeight: innerHeight - 50 + 'px',
ganttLoading: false,
projectId: '',
tasksGantt: {
},
}
},
created() {
//清空gantt数据
gantt.clearAll();
this.projectId = this.$route.params.id;
this.getTasksGantt();
},
mounted() {
var that = this;
//本地化
gantt.i18n.setLocale("cn");
//自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务
gantt.config.autosize = false;
//只读模式:打开后不可以操作甘特图
gantt.config.readonly = false;
//是否显示左侧树表格
gantt.config.show_grid = true;
//表格列设置:我们在后台获取数据后,会解析到这个表格列中,这里面会含有很多隐藏列,作用是甘特图中不需要看隐藏列,但当我们获取甘特图的任务时,这些隐藏列会跟随任务方便使用
gantt.config.columns = [{
//最左侧新增符号列,甘特图内置可选使用列
name: 'add',
label: '',
width: '40'
},
{
name: 'text',
label: '任务名称',
tree: true,
width: '150'
},
{
name: 'assign_to',
label: '执行人',
width: '100'
},
{
name: 'start_date',
label: '开始时间',
align: 'center',
width: '90'
},
{
name: 'end_date',
label: '结束时间',
align: 'center',
width: '90'
}
];
//自适应
//gantt.config.fit_tasks = true;
//开启提示:鼠标悬浮在gantt行上显示
gantt.plugins({
tooltip: true
});
gantt.attachEvent('onGanttReady', function() {
var tooltips = gantt.ext.tooltips;
gantt.templates.tooltip_text = function(start, end, task) {
return '任务编号:' + task.id + '<br/>任务:' + task.text + '<br/>执行人:' +
task.assign_to + '<br/>计划开始时间:' + gantt.templates.tooltip_date_format(start) + '<br/>结束时间:' + gantt
.templates.tooltip_date_format(end);
};
});
//禁用双击事件
gantt.config.details_on_dblclick = false;
//关闭所有错误提示信息:gantt有自己的异常消息,如果不关闭可能页面会弹出异常消息
gantt.config.show_errors = false;
//灯箱事件
gantt.attachEvent('onBeforeLightbox', function(task_id) {
//刷新灯箱数据
//gantt.resetLightbox();
//true:打开灯箱
//return true;
//这里调用了自己的页面,没有打开默认灯箱
that.addTask(task_id);
});
//禁止拖动设置任务长度
gantt.attachEvent('onBeforeTaskDrag', function(id, mode, e) {
return false;
});
//禁止拖动任务
gantt.config.drag_move = false;
//禁止拖动任务进度
gantt.config.drag_progress = false;
//禁止拖放添加Link
gantt.config.drag_links = false;
//开启标记
gantt.plugins({
marker: true
});
//标记当前日期
var dateToStr = gantt.date.date_to_str(gantt.config.task_date);
var markerId = gantt.addMarker({
start_date: new Date(),
css: 'today', //标记样式,style中对应
text: 'Today',
title: dateToStr(new Date())
});
gantt.getMarker(markerId);
//设置 scale_unit 属性为 month,以显示月刻度
gantt.config.scale_unit = "month";
//设置 step 属性为 1,以每个月显示一个刻度
gantt.config.step = 1;
//设置 date_scale 属性为 %Y-%m-%d,以显示年月日格式的刻度
gantt.config.date_scale = "%Y-%m-%d";
//设置 scale_date 属性为 gantt.date.monthStart,以从每个月的第一天开始显示刻度。
gantt.config.scale_date = gantt.date.monthStart;
//表头高度
gantt.config.scale_height = 60;
gantt.config.scales = [
{unit: "month", format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
//设置 subscale 属性为一个包含两个刻度的对象,分别为 day 和 week。
gantt.config.subscales = [ // 配置时间
{
unit: "day",
step: 1,
date: "%j %D"
},
];
// 初始化
gantt.init(this.$refs.gantt);
//gantt.clearAll(); // 防止数据缓存问题
//gantt.parse(tasks);
},
methods: {
//获取甘特图数据
getTasksGantt() {
let that = this;
getTasksGanttByProjectId({
projectId: that.id
}).then((res) => {
console.log("getTasksGanttByProjectId res=", res);
this.tasksGantt = res.result;
// 数据解析:将数据解析到gantt列数据中
gantt.parse(this.tasksGantt);
// 刷新数据
gantt.refreshData();
this.ganttLoading = false;
});
},
//自定义新增任务
addTask(taskId) {
var that = this;
this.$nextTick(() => {
that.$refs.taskAdd.init(task, action, parentTask, $this.milestoneOriginalData);
});
//删除任务:每次调用gantt内置新增事件时,gantt会直接新增任务到甘特图中,而我们需要的是自定义新增任务
gantt.deleteTask(taskId);
//灯箱事件必须返回布尔值,这里使用了自定义灯箱返回false,即不打开灯箱
return false;
}
},
}
</script>
<style lang="less">
.project-space-gantt {
.project-navigation {
top: 0px;
z-index: 4;
}
.layout-content {
padding: 0px;
width: 100%;
margin: 0px 0px 0px;
background: initial;
.content-item {
background: #fff;
padding: 0px 0px 0px 0px;
border-radius: 4px;
}
}
.wrapper-main {
padding: 24px 0 12px 0px;
background: initial;
}
}
.gantt-container {
height: 100%;
width: 100%;
}
.ganntClass {
background-color: #fff;
padding: 10px;
border-radius: 4px;
}
//今日标记样式
.today {}
</style>
2、效果如下:文章来源:https://www.toymoban.com/news/detail-604456.html
文章来源地址https://www.toymoban.com/news/detail-604456.html
到了这里,关于基于jeecg-boot的任务甘特图显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!