From 9585f6dd3995b3502e2f1169eba13d1863e9e767 Mon Sep 17 00:00:00 2001 From: wangna0328 <3402195679@qq.com> Date: Wed, 13 Aug 2025 14:39:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E7=94=98=E7=89=B9=E5=9B=BE?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E6=8E=A5=E5=8F=A3=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dite/znpt/domain/vo/GanttChartReq.java | 45 ++ .../dite/znpt/domain/vo/GanttChartResp.java | 91 ++++ .../dite/znpt/mapper/ProjectTaskMapper.java | 2 + .../dite/znpt/service/GanttChartService.java | 55 ++ .../service/impl/GanttChartServiceImpl.java | 486 ++++++++++++++++++ .../web/controller/GanttChartController.java | 61 +++ 6 files changed, 740 insertions(+) create mode 100644 core/src/main/java/com/dite/znpt/domain/vo/GanttChartReq.java create mode 100644 core/src/main/java/com/dite/znpt/domain/vo/GanttChartResp.java create mode 100644 core/src/main/java/com/dite/znpt/service/GanttChartService.java create mode 100644 core/src/main/java/com/dite/znpt/service/impl/GanttChartServiceImpl.java create mode 100644 web/src/main/java/com/dite/znpt/web/controller/GanttChartController.java diff --git a/core/src/main/java/com/dite/znpt/domain/vo/GanttChartReq.java b/core/src/main/java/com/dite/znpt/domain/vo/GanttChartReq.java new file mode 100644 index 0000000..7e96367 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/domain/vo/GanttChartReq.java @@ -0,0 +1,45 @@ +package com.dite.znpt.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDate; + +/** + * 甘特图查询请求类 + */ +@Data +@ApiModel(value = "GanttChartReq", description = "甘特图查询请求") +public class GanttChartReq { + + @ApiModelProperty("项目ID") + private String projectId; + + @ApiModelProperty("任务组ID") + private String taskGroupId; + + @ApiModelProperty("任务状态") + private Integer status; + + @ApiModelProperty("负责人ID") + private String mainUserId; + + @ApiModelProperty("开始时间范围-开始") + private LocalDate startDateFrom; + + @ApiModelProperty("开始时间范围-结束") + private LocalDate startDateTo; + + @ApiModelProperty("结束时间范围-开始") + private LocalDate endDateFrom; + + @ApiModelProperty("结束时间范围-结束") + private LocalDate endDateTo; + + @ApiModelProperty("是否包含已完成任务") + private Boolean includeCompleted = true; + + @ApiModelProperty("是否只显示逾期任务") + private Boolean overdueOnly = false; +} diff --git a/core/src/main/java/com/dite/znpt/domain/vo/GanttChartResp.java b/core/src/main/java/com/dite/znpt/domain/vo/GanttChartResp.java new file mode 100644 index 0000000..69e38a0 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/domain/vo/GanttChartResp.java @@ -0,0 +1,91 @@ +package com.dite.znpt.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDate; +import java.util.List; + +/** + * 甘特图数据响应类 + */ +@Data +@ApiModel(value = "GanttChartResp", description = "甘特图数据响应") +public class GanttChartResp { + + @ApiModelProperty("任务ID") + private String taskId; + + @ApiModelProperty("任务名称") + private String taskName; + + @ApiModelProperty("任务编号") + private String taskCode; + + @ApiModelProperty("上级任务ID") + private String parentTaskId; + + @ApiModelProperty("任务组ID") + private String taskGroupId; + + @ApiModelProperty("任务组名称") + private String taskGroupName; + + @ApiModelProperty("计划开始时间") + private LocalDate planStartDate; + + @ApiModelProperty("计划结束时间") + private LocalDate planEndDate; + + @ApiModelProperty("实际开始时间") + private LocalDate actualStartDate; + + @ApiModelProperty("实际结束时间") + private LocalDate actualEndDate; + + @ApiModelProperty("任务状态:0未开始,1进行中,2已结束") + private Integer status; + + @ApiModelProperty("任务状态描述") + private String statusDesc; + + @ApiModelProperty("是否逾期:0未逾期,1已逾期") + private Integer overdueStatus; + + @ApiModelProperty("任务负责人ID") + private String mainUserId; + + @ApiModelProperty("任务负责人姓名") + private String mainUserName; + + @ApiModelProperty("任务参与人") + private String userIds; + + @ApiModelProperty("任务参与人姓名列表") + private List participantNames; + + @ApiModelProperty("进度百分比") + private Integer progress; + + @ApiModelProperty("任务层级") + private Integer level; + + @ApiModelProperty("任务在时间轴上的位置(天数)") + private Integer position; + + @ApiModelProperty("任务持续时间(天数)") + private Integer duration; + + @ApiModelProperty("子任务列表") + private List children; + + @ApiModelProperty("任务备注") + private String remark; + + @ApiModelProperty("项目ID") + private String projectId; + + @ApiModelProperty("项目名称") + private String projectName; +} diff --git a/core/src/main/java/com/dite/znpt/mapper/ProjectTaskMapper.java b/core/src/main/java/com/dite/znpt/mapper/ProjectTaskMapper.java index afb1d09..4101f84 100644 --- a/core/src/main/java/com/dite/znpt/mapper/ProjectTaskMapper.java +++ b/core/src/main/java/com/dite/znpt/mapper/ProjectTaskMapper.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dite.znpt.domain.entity.ProjectTaskEntity; import com.dite.znpt.domain.vo.ProjectTaskListReq; import com.dite.znpt.domain.vo.ProjectTaskResp; +import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -13,6 +14,7 @@ import java.util.List; * @date 2025/06/24 16:44 * @Description: 项目任务信息表数据库访问层 */ +@Mapper public interface ProjectTaskMapper extends BaseMapper { List queryBySelective(ProjectTaskListReq projectTaskReq); diff --git a/core/src/main/java/com/dite/znpt/service/GanttChartService.java b/core/src/main/java/com/dite/znpt/service/GanttChartService.java new file mode 100644 index 0000000..d3e1c26 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/service/GanttChartService.java @@ -0,0 +1,55 @@ +package com.dite.znpt.service; + +import com.dite.znpt.domain.vo.GanttChartReq; +import com.dite.znpt.domain.vo.GanttChartResp; + +import java.util.List; + +/** + * 甘特图服务接口 + */ +public interface GanttChartService { + + /** + * 获取项目甘特图数据 + * + * @param req 查询条件 + * @return 甘特图数据列表 + */ + List getGanttChartData(GanttChartReq req); + + /** + * 获取项目甘特图统计信息 + * + * @param projectId 项目ID + * @return 统计信息 + */ + Object getGanttChartStatistics(String projectId); + + /** + * 获取项目甘特图时间轴信息 + * + * @param projectId 项目ID + * @return 时间轴信息 + */ + Object getGanttChartTimeline(String projectId); + + /** + * 更新任务进度 + * + * @param taskId 任务ID + * @param progress 进度百分比 + * @return 是否成功 + */ + boolean updateTaskProgress(String taskId, Integer progress); + + /** + * 拖拽更新任务时间 + * + * @param taskId 任务ID + * @param startDate 开始时间 + * @param endDate 结束时间 + * @return 是否成功 + */ + boolean updateTaskTime(String taskId, String startDate, String endDate); +} diff --git a/core/src/main/java/com/dite/znpt/service/impl/GanttChartServiceImpl.java b/core/src/main/java/com/dite/znpt/service/impl/GanttChartServiceImpl.java new file mode 100644 index 0000000..e1f8f44 --- /dev/null +++ b/core/src/main/java/com/dite/znpt/service/impl/GanttChartServiceImpl.java @@ -0,0 +1,486 @@ +package com.dite.znpt.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.dite.znpt.domain.entity.ProjectTaskEntity; +import com.dite.znpt.domain.entity.UserEntity; +import com.dite.znpt.domain.vo.GanttChartReq; +import com.dite.znpt.domain.vo.GanttChartResp; +import com.dite.znpt.mapper.ProjectTaskMapper; +import com.dite.znpt.service.GanttChartService; +import com.dite.znpt.service.UserService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.util.*; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.stream.Collectors; + +/** + * 甘特图服务实现类 + */ +@Service +@RequiredArgsConstructor +public class GanttChartServiceImpl implements GanttChartService { + + private final ProjectTaskMapper projectTaskMapper; + private final UserService userService; + + @Override + public List getGanttChartData(GanttChartReq req) { + // 查询所有任务 + QueryWrapper queryWrapper = new QueryWrapper<>(); + + if (StrUtil.isNotBlank(req.getProjectId())) { + queryWrapper.eq("project_id", req.getProjectId()); + } + if (StrUtil.isNotBlank(req.getTaskGroupId())) { + queryWrapper.eq("task_group_id", req.getTaskGroupId()); + } + if (req.getStatus() != null) { + queryWrapper.eq("status", req.getStatus()); + } + if (StrUtil.isNotBlank(req.getMainUserId())) { + queryWrapper.eq("main_user_id", req.getMainUserId()); + } + if (req.getStartDateFrom() != null) { + queryWrapper.ge("plan_start_date", req.getStartDateFrom()); + } + if (req.getStartDateTo() != null) { + queryWrapper.le("plan_start_date", req.getStartDateTo()); + } + if (req.getEndDateFrom() != null) { + queryWrapper.ge("plan_end_date", req.getEndDateFrom()); + } + if (req.getEndDateTo() != null) { + queryWrapper.le("plan_end_date", req.getEndDateTo()); + } + if (req.getOverdueOnly() != null && req.getOverdueOnly()) { + queryWrapper.eq("overdue_status", 1); + } + if (req.getIncludeCompleted() != null && !req.getIncludeCompleted()) { + queryWrapper.ne("status", 2); + } + + queryWrapper.orderByAsc("plan_start_date"); + + List taskList = projectTaskMapper.selectList(queryWrapper); + + // 获取用户信息 + final Set userIds = new HashSet<>(); + taskList.forEach(task -> { + if (StrUtil.isNotBlank(task.getMainUserId())) { + userIds.add(task.getMainUserId()); + } + if (StrUtil.isNotBlank(task.getUserIds())) { + userIds.addAll(Arrays.asList(task.getUserIds().split(","))); + } + }); + + final Map userMap = new HashMap<>(); + if (CollUtil.isNotEmpty(userIds)) { + List users = userService.listByIds(userIds); + userMap.putAll(users.stream().collect(Collectors.toMap(UserEntity::getUserId, user -> user))); + } + + // 批量获取项目时间范围,避免重复查询 + final Map projectStartDates = new HashMap<>(); + if (StrUtil.isNotBlank(req.getProjectId())) { + // 如果指定了项目ID,直接获取该项目的时间范围 + LocalDate projectStart = getProjectStartDate(req.getProjectId()); + projectStartDates.put(req.getProjectId(), projectStart); + } else { + // 如果没有指定项目ID,获取所有相关项目的时间范围 + Set projectIds = taskList.stream() + .map(ProjectTaskEntity::getProjectId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + for (String projectId : projectIds) { + LocalDate projectStart = getProjectStartDate(projectId); + projectStartDates.put(projectId, projectStart); + } + } + + // 转换为甘特图数据 + List ganttData = taskList.stream().map(task -> { + GanttChartResp resp = BeanUtil.copyProperties(task, GanttChartResp.class); + + // 设置状态描述 + switch (task.getStatus()) { + case 0: + resp.setStatusDesc("未开始"); + break; + case 1: + resp.setStatusDesc("进行中"); + break; + case 2: + resp.setStatusDesc("已结束"); + break; + default: + resp.setStatusDesc("未知"); + } + + // 设置负责人姓名 + if (StrUtil.isNotBlank(task.getMainUserId()) && userMap.containsKey(task.getMainUserId())) { + resp.setMainUserName(userMap.get(task.getMainUserId()).getName()); + } + + // 设置参与人姓名列表 + if (StrUtil.isNotBlank(task.getUserIds())) { + List participantNames = Arrays.stream(task.getUserIds().split(",")) + .filter(userId -> userMap.containsKey(userId)) + .map(userId -> userMap.get(userId).getName()) + .collect(Collectors.toList()); + resp.setParticipantNames(participantNames); + } + + // 计算进度(这里可以根据实际业务逻辑调整) + if (task.getStatus() == 2) { + resp.setProgress(100); + } else if (task.getStatus() == 1) { + resp.setProgress(50); // 默认进度,实际应该从数据库字段获取 + } else { + resp.setProgress(0); + } + + // 计算任务在时间轴上的位置和持续时间 + LocalDate projectStart = projectStartDates.get(task.getProjectId()); + if (projectStart != null && task.getPlanStartDate() != null) { + int position = (int) ChronoUnit.DAYS.between(projectStart, task.getPlanStartDate()); + resp.setPosition(position); + } + + // 计算任务持续时间 + if (task.getPlanStartDate() != null && task.getPlanEndDate() != null) { + int duration = (int) ChronoUnit.DAYS.between(task.getPlanStartDate(), task.getPlanEndDate()) + 1; + resp.setDuration(duration); + } else { + resp.setDuration(1); // 默认持续1天 + } + + return resp; + }).collect(Collectors.toList()); + + // 构建树形结构 + return buildTreeStructure(ganttData); + } + + @Override + public Object getGanttChartStatistics(String projectId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("project_id", projectId); + + List taskList = projectTaskMapper.selectList(queryWrapper); + + Map statistics = new HashMap<>(); + statistics.put("totalTasks", taskList.size()); + statistics.put("notStarted", (int) taskList.stream().filter(task -> task.getStatus() == 0).count()); + statistics.put("inProgress", (int) taskList.stream().filter(task -> task.getStatus() == 1).count()); + statistics.put("completed", (int) taskList.stream().filter(task -> task.getStatus() == 2).count()); + statistics.put("overdue", (int) taskList.stream().filter(task -> task.getOverdueStatus() == 1).count()); + + // 计算总体进度 + if (taskList.size() > 0) { + final double avgProgress = taskList.stream() + .mapToInt(task -> { + if (task.getStatus() == 2) return 100; + else if (task.getStatus() == 1) return 50; + else return 0; + }) + .average() + .orElse(0.0); + statistics.put("overallProgress", Math.round(avgProgress)); + } else { + statistics.put("overallProgress", 0); + } + + return statistics; + } + + @Override + public Object getGanttChartTimeline(String projectId) { + if (StrUtil.isBlank(projectId)) { + return null; + } + + LocalDate projectStartDate = getProjectStartDate(projectId); + LocalDate projectEndDate = getProjectEndDate(projectId); + + Map timeline = new HashMap<>(); + timeline.put("projectId", projectId); + timeline.put("startDate", projectStartDate); + timeline.put("endDate", projectEndDate); + timeline.put("totalDays", ChronoUnit.DAYS.between(projectStartDate, projectEndDate) + 1); + + // 计算时间轴上的关键时间点(比如每周、每月) + List> timePoints = new ArrayList<>(); + LocalDate currentDate = projectStartDate; + + while (!currentDate.isAfter(projectEndDate)) { + Map timePoint = new HashMap<>(); + timePoint.put("date", currentDate); + timePoint.put("dayOfWeek", currentDate.getDayOfWeek().getDisplayName(java.time.format.TextStyle.SHORT, java.util.Locale.CHINESE)); + timePoint.put("isWeekend", currentDate.getDayOfWeek().getValue() >= 6); + timePoints.add(timePoint); + + currentDate = currentDate.plusDays(1); + } + + timeline.put("timePoints", timePoints); + + return timeline; + } + + @Override + public boolean updateTaskProgress(String taskId, Integer progress) { + ProjectTaskEntity task = projectTaskMapper.selectById(taskId); + if (task == null) { + return false; + } + + // 更新进度 + // 这里需要根据实际业务逻辑添加进度字段 + // task.setProgress(progress); + + // 根据进度更新状态 + if (progress >= 100) { + task.setStatus(2); // 已完成 + task.setActualEndDate(LocalDate.now()); + } else if (progress > 0) { + task.setStatus(1); // 进行中 + if (task.getActualStartDate() == null) { + task.setActualStartDate(LocalDate.now()); + } + } + + return projectTaskMapper.updateById(task) > 0; + } + + @Override + public boolean updateTaskTime(String taskId, String startDate, String endDate) { + ProjectTaskEntity task = projectTaskMapper.selectById(taskId); + if (task == null) { + return false; + } + + final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate newStartDate = null; + LocalDate newEndDate = null; + + try { + if (StrUtil.isNotBlank(startDate)) { + newStartDate = LocalDate.parse(startDate, formatter); + } + if (StrUtil.isNotBlank(endDate)) { + newEndDate = LocalDate.parse(endDate, formatter); + } + } catch (DateTimeParseException e) { + return false; // 日期格式错误 + } + + // 验证时间约束 + if (!validateTaskTimeConstraints(task, newStartDate, newEndDate)) { + return false; + } + + // 更新任务时间 + if (newStartDate != null) { + task.setPlanStartDate(newStartDate); + } + if (newEndDate != null) { + task.setPlanEndDate(newEndDate); + } + + // 更新逾期状态 + updateOverdueStatus(task); + + return projectTaskMapper.updateById(task) > 0; + } + + /** + * 构建树形结构 + */ + private List buildTreeStructure(List allTasks) { + final Map taskMap = allTasks.stream() + .collect(Collectors.toMap(GanttChartResp::getTaskId, task -> task)); + + final List rootTasks = new ArrayList<>(); + + for (GanttChartResp task : allTasks) { + if (StrUtil.isBlank(task.getParentTaskId())) { + // 根任务 + task.setLevel(0); + rootTasks.add(task); + } else { + // 子任务 + GanttChartResp parentTask = taskMap.get(task.getParentTaskId()); + if (parentTask != null) { + task.setLevel(parentTask.getLevel() + 1); + if (parentTask.getChildren() == null) { + parentTask.setChildren(new ArrayList<>()); + } + parentTask.getChildren().add(task); + } + } + } + + return rootTasks; + } + + /** + * 获取项目开始时间 + * 从项目任务中计算最早的计划开始时间作为项目开始时间 + */ + private LocalDate getProjectStartDate(String projectId) { + if (StrUtil.isBlank(projectId)) { + return LocalDate.now().minusDays(30); // 默认值 + } + + // 查询项目中所有任务的计划开始时间,取最早的时间 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("project_id", projectId) + .isNotNull("plan_start_date") + .orderByAsc("plan_start_date") + .last("LIMIT 1"); + + ProjectTaskEntity earliestTask = projectTaskMapper.selectOne(queryWrapper); + + if (earliestTask != null && earliestTask.getPlanStartDate() != null) { + return earliestTask.getPlanStartDate(); + } + + // 如果没有找到有效的开始时间,返回当前时间减去30天作为默认值 + return LocalDate.now().minusDays(30); + } + + /** + * 获取项目结束时间 + * 从项目任务中计算最晚的计划结束时间作为项目结束时间 + */ + private LocalDate getProjectEndDate(String projectId) { + if (StrUtil.isBlank(projectId)) { + return LocalDate.now().plusDays(30); // 默认值 + } + + // 查询项目中所有任务的计划结束时间,取最晚的时间 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("project_id", projectId) + .isNotNull("plan_end_date") + .orderByDesc("plan_end_date") + .last("LIMIT 1"); + + ProjectTaskEntity latestTask = projectTaskMapper.selectOne(queryWrapper); + + if (latestTask != null && latestTask.getPlanEndDate() != null) { + return latestTask.getPlanEndDate(); + } + + // 如果没有找到有效的结束时间,返回当前时间加上30天作为默认值 + return LocalDate.now().plusDays(30); + } + + /** + * 获取项目时间范围 + * 返回项目的开始时间和结束时间 + */ + private Map getProjectTimeRange(String projectId) { + Map timeRange = new HashMap<>(); + timeRange.put("startDate", getProjectStartDate(projectId)); + timeRange.put("endDate", getProjectEndDate(projectId)); + return timeRange; + } + + /** + * 批量获取项目时间范围 + * 通过一次查询获取多个项目的时间范围,提高性能 + */ + private Map> getBatchProjectTimeRanges(Set projectIds) { + Map> timeRanges = new HashMap<>(); + + for (String projectId : projectIds) { + Map timeRange = getProjectTimeRange(projectId); + timeRanges.put(projectId, timeRange); + } + + return timeRanges; + } + + /** + * 计算任务进度 + */ + private Integer calculateProgress(ProjectTaskEntity task) { + if (task.getStatus() == 2) return 100; // 已完成 + else if (task.getStatus() == 1) return 50; // 进行中 + else return 0; // 未开始 + } + + /** + * 计算任务持续时间 + */ + private Integer calculateDuration(ProjectTaskEntity task) { + if (task.getPlanStartDate() != null && task.getPlanEndDate() != null) { + return (int) ChronoUnit.DAYS.between(task.getPlanStartDate(), task.getPlanEndDate()) + 1; + } + return 1; + } + + /** + * 计算任务在时间轴上的位置 + */ + private Integer calculatePosition(ProjectTaskEntity task) { + LocalDate projectStart = getProjectStartDate(task.getProjectId()); + if (task.getPlanStartDate() != null && projectStart != null) { + return (int) ChronoUnit.DAYS.between(projectStart, task.getPlanStartDate()); + } + return 0; + } + + /** + * 验证任务时间约束 + */ + private boolean validateTaskTimeConstraints(ProjectTaskEntity task, + LocalDate newStartDate, + LocalDate newEndDate) { + // 验证子任务不能早于父任务开始 + if (StrUtil.isNotBlank(task.getParentTaskId())) { + ProjectTaskEntity parentTask = projectTaskMapper.selectById(task.getParentTaskId()); + if (parentTask != null && newStartDate != null) { + if (newStartDate.isBefore(parentTask.getPlanStartDate())) { + return false; + } + } + } + + // 验证结束时间不能早于开始时间 + if (newStartDate != null && newEndDate != null) { + if (newEndDate.isBefore(newStartDate)) { + return false; + } + } + + return true; + } + + /** + * 更新逾期状态 + */ + private void updateOverdueStatus(ProjectTaskEntity task) { + if (task.getPlanEndDate() != null && + task.getPlanEndDate().isBefore(LocalDate.now()) && + task.getStatus() != 2) { + task.setOverdueStatus(1); // 标记为逾期 + } else { + task.setOverdueStatus(0); + } + } +} diff --git a/web/src/main/java/com/dite/znpt/web/controller/GanttChartController.java b/web/src/main/java/com/dite/znpt/web/controller/GanttChartController.java new file mode 100644 index 0000000..6da8f57 --- /dev/null +++ b/web/src/main/java/com/dite/znpt/web/controller/GanttChartController.java @@ -0,0 +1,61 @@ +package com.dite.znpt.web.controller; + +import com.dite.znpt.domain.Result; +import com.dite.znpt.domain.vo.GanttChartReq; +import com.dite.znpt.domain.vo.GanttChartResp; +import com.dite.znpt.service.GanttChartService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 甘特图控制器 + */ +@Api(tags = "甘特图管理") +@RestController +@RequestMapping("/gantt-chart") +public class GanttChartController { + + @Resource + private GanttChartService ganttChartService; + + @ApiOperation(value = "获取项目甘特图数据", httpMethod = "GET") + @GetMapping("/data") + public Result> getGanttChartData(GanttChartReq req) { + List data = ganttChartService.getGanttChartData(req); + return Result.ok(data); + } + + @ApiOperation(value = "获取项目甘特图统计信息", httpMethod = "GET") + @GetMapping("/statistics/{projectId}") + public Result getGanttChartStatistics(@PathVariable String projectId) { + Object statistics = ganttChartService.getGanttChartStatistics(projectId); + return Result.ok(statistics); + } + + @ApiOperation(value = "获取项目甘特图时间轴信息", httpMethod = "GET") + @GetMapping("/timeline/{projectId}") + public Result getGanttChartTimeline(@PathVariable String projectId) { + Object timeline = ganttChartService.getGanttChartTimeline(projectId); + return Result.ok(timeline); + } + + @ApiOperation(value = "更新任务进度", httpMethod = "PUT") + @PutMapping("/progress/{taskId}") + public Result updateTaskProgress(@PathVariable String taskId, @RequestParam Integer progress) { + boolean success = ganttChartService.updateTaskProgress(taskId, progress); + return Result.ok(success); + } + + @ApiOperation(value = "拖拽更新任务时间", httpMethod = "PUT") + @PutMapping("/time/{taskId}") + public Result updateTaskTime(@PathVariable String taskId, + @RequestParam(required = false) String startDate, + @RequestParam(required = false) String endDate) { + boolean success = ganttChartService.updateTaskTime(taskId, startDate, endDate); + return Result.ok(success); + } +}