当前位置: 首页 > news >正文

基于jeecg-boot的任务甘特图显示

更多功能看演示系统

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、后端代码

获取项目任务相关信息如下:

@Overridepublic 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;//禁止拖放添加Linkgantt.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、效果如下:

相关文章:

基于jeecg-boot的任务甘特图显示

更多功能看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 基于项目的任务显…...

docker export,import后无法运行,如java命令找不到,运行后容器内编码有问题

为什么用docker export呢&#xff0c;&#x1f614;~由于客户环境太恶心了&#xff0c;测试一次更是麻烦&#xff0c;所以什么都得在本地调试完成&#xff0c;争取每次测试上线一次通过才行&#xff0c;说多了都是泪。 由于踩坑几次了&#xff0c;每次都忘记&#xff0c;且每次…...

Web3教程| 什么是地址监控?如何使用地址监控追踪黑客地址?

在当今Web3世界里&#xff0c;保护个人资产安全至关重要。据报道在2023年上半年&#xff0c;Web3领域因黑客攻击事件造成的损失高达4.794亿美元。 此外&#xff0c;10多个公链遭受黑客攻击&#xff0c;其中以太坊链遭受的损失最多&#xff0c;约为2.87亿美元。这些黑客的存在迫…...

flask结合mysql实现用户的添加和获取

1、数据库准备 已经安装好数据库&#xff0c;并且创建数据库和表 create database unicom DEFAULT CHARSET utf8 COLLATE utf8_general_ci; CREATE TABLE admin( id int not null auto_increment primary key, username VARCHAR(16) not null, password VARCHAR(64) not null…...

阿里云服务器配置 内存,cpu等等

实例升配&#xff0c;https://help.aliyun.com/document_detail/25438.html?spma2c4g.11174283.6.780.2cbf4c070oeino#title-a5t-gg2-...

PHP注册、登陆、6套主页-带Thinkphp目录解析-【强撸项目】

强撸项目系列总目录在000集 PHP要怎么学–【思维导图知识范围】 文章目录 本系列校训本项目使用技术 上效果图主页注册&#xff0c;登陆 phpStudy 设置导数据库项目目录如图&#xff1a;代码部分&#xff1a;控制器前台的首页 其它配套页面展示直接给第二套方案的页面吧第三套…...

android Activity设置背景为半透明的时候会显示上一个activity的内容

在弹出PopupWindow时将当前Activity设置成了半透明: WindowManager.LayoutParams lp = this.activity.getWindow().getAttributes();lp.alpha = 0.5f; //0.0-1.0this...

Linux 网络收包流程

哈喽大家好&#xff0c;我是咸鱼 我们在跟别人网上聊天的时候&#xff0c;有没有想过你发送的信息是怎么传到对方的电脑上的 又或者我们在上网冲浪的时候&#xff0c;有没有想过 HTML 页面是怎么显示在我们的电脑屏幕上的 无论是我们跟别人聊天还是上网冲浪&#xff0c;其实…...

flex: 0 0 273px的意思

flex: 0 0 273px; 是一条CSS属性&#xff0c;用于设置flexible box布局&#xff08;flexbox&#xff09;中的flex子项的灵活性和尺寸。 这条属性包含三个值&#xff0c;分别是&#xff1a; flex-grow: 表示弹性增长因子&#xff0c;指定当有多余空间时&#xff0c;子项能够增长…...

helm部署rabbitmq

1.添加rabbitmq仓库并下载包 helm repo add bitnami https://charts.bitnami.com/bitnami helm pull bitnami/rabbitmq --version 10.1.4 tar -zxvf rabbitmq-10.1.4.tgz mv values.yaml values.yaml.back grep -v "#" values.yaml.back > values.yaml2.helm部署…...

Java版Spring Cloud+Spring Boot+Mybatis+uniapp知识付费平台讲解

提供私有化部署&#xff0c;免费售后&#xff0c;专业技术指导&#xff0c;支持PC、APP、H5、小程序多终端同步&#xff0c;支持二次开发定制&#xff0c;源码交付。 Java版知识付费-轻松拥有知识付费平台 多种直播形式&#xff0c;全面满足直播场景需求 公开课、小班课、独…...

编程之舞:流程控制乐章

流程控制语句 1. 复合语句 2. 条件语句2.1 if条件语句2.2 switch多分支语句 3. 循环语句3.1 while循环语句3.2 do...while循环语句3.3 for循环语句 4. 循环控制4.1 break语句4.2 continue语句 5. 实践与练习 1. 复合语句 复合语句是由一对花括号括起来的语句块&#xff0c;可以…...

ChatGPT是否能够进行情感融合和语气调整?

ChatGPT是一种预训练的通用语言模型&#xff0c;具有很强的文本生成和理解能力。在情感融合和语气调整方面&#xff0c;ChatGPT可以通过特定的技术和训练方法实现一定程度的情感表达和语气调整。下面将详细探讨ChatGPT在情感融合和语气调整方面的应用方法和潜力。 1. **情感融…...

C++--动态规划路径问题

1.不同路径 力扣 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从…...

从实践彻底掌握MySQL的主从复制

目录 一、本次所用结构如图---一主多从级联&#xff1a; 二、IP。 三、配置M1&#xff1a; 四、从库M1S1&#xff1a; 五、从库M2配置&#xff1a; 六、 从库M2S1&#xff1a; 一、本次所用结构如图--- 一主多从级联&#xff1a; 二、IP。这里M1S1和M1S2一样的&#xff0…...

机器学习深度学习——线性回归的基本元素

回归用来表示输入输出之间的关系。 用实际例子来解释一下线性回归&#xff1a;根据房屋的面积、房龄来估算房屋价格。为了实现这个预测放假的模型&#xff0c;需要收集一个真实的数据集&#xff0c;该数据集包括了房屋的销售价格、面积和房龄。 在机器学习中&#xff0c;这个数…...

K8S初级入门系列之八-网络

一、前言 本章节我们将了解K8S的相关网络概念&#xff0c;包括K8S的网络通讯原理&#xff0c;以及Service以及相关的概念&#xff0c;包括Endpoint&#xff0c;EndpointSlice&#xff0c;Headless service&#xff0c;Ingress等。 二、网络通讯原理和实现 同一K8S集群&…...

分段@Transactional 坑及失效问题

Transactional 背景&#xff1a;在某些情况下&#xff0c;我们需要分段transaction&#xff0c;在最外面没有transaction&#xff0c;里面分成几个transaction&#xff0c;保证分段是成功的。 问题代码&#xff1a; Service public Order getOrder1(String id) {Optional<Or…...

25、matlab里面的10中优化方法介绍——Opt_Golden法(matlab程序)

1.简述 基本思想 黄金分割法也称为 0.618 法&#xff0c;其基本思想是通过取试探点和进行函数值比较&#xff0c;使包含极小点的搜索区间不断缩短以逼近极小值点。适用于确定区间上的任何单谷函数求极小值的问题。 公式推导 设有定义在[ a , b ] [a,b][a,b]上的单谷函数 φ ( …...

点云拟合球体

前言&#xff1a;在很多情况下&#xff0c;需要根据点云来拟合球体&#xff0c;本博文主要介绍各种方法的拟合情况及优缺点&#xff0c;希望对各位小伙伴有所帮助&#xff01; 目录 1. vtkFitImplicitFunction进行球拟合 2. 四点求解球 1. vtkFitImplicitFunction进行球拟合 …...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...