瀏覽代碼

feat: save project group

Blizzard 1 年之前
父節點
當前提交
d5341c6a89
共有 24 個文件被更改,包括 386 次插入97 次删除
  1. 4 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/dto/ProjectTaskPageDTO.java
  2. 23 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/LineChartData.java
  3. 17 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/LineChartDataSet.java
  4. 4 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/ProjectGroup.java
  5. 5 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/Task.java
  6. 1 2
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/TaskContract.java
  7. 21 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/ProjectStageVO.java
  8. 3 1
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/TaskContractVO.java
  9. 38 43
      blade-service/wt-okr/src/main/java/com/wtkj/controller/CommonController.java
  10. 17 13
      blade-service/wt-okr/src/main/java/com/wtkj/controller/ProjectController.java
  11. 2 0
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/FileAndFolderMapper.java
  12. 4 1
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/FileAndFolderMapper.xml
  13. 1 1
      blade-service/wt-okr/src/main/java/com/wtkj/service/IAsyncService.java
  14. 2 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/IFileAndFolderService.java
  15. 2 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/IProjectStageService.java
  16. 9 8
      blade-service/wt-okr/src/main/java/com/wtkj/service/ITaskService.java
  17. 76 2
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/AsyncServiceImpl.java
  18. 1 1
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/DeptToDeptServiceImpl.java
  19. 5 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/FileAndFolderServiceImpl.java
  20. 36 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ProjectStageServiceImplService.java
  21. 0 1
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/QrcodeServiceImpl.java
  22. 63 18
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/TaskServiceImpl.java
  23. 34 0
      blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ProjectStageWrapper.java
  24. 18 6
      blade-service/wt-okr/src/main/java/com/wtkj/wrapper/TaskContractWrapper.java

+ 4 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/dto/ProjectTaskPageDTO.java

@@ -22,6 +22,10 @@ public class ProjectTaskPageDTO implements Serializable {
 	@JsonSerialize(using = ToStringSerializer.class)
 	private Long projectId;
 
+	@NotNull(message = "stageId can't be null")
+	@JsonSerialize(using = ToStringSerializer.class)
+	private Long stageId;
+
 	private String name;
 
 	@ApiModelProperty(value = "当前登录用户的机构类型")

+ 23 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/LineChartData.java

@@ -0,0 +1,23 @@
+package com.wtkj.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-28 01:12
+ * @describe
+ */
+@Data
+public class LineChartData implements Serializable {
+
+	private String name;
+
+	private String type;
+
+	private List<Map<String, Object>> data;
+}
+

+ 17 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/LineChartDataSet.java

@@ -0,0 +1,17 @@
+package com.wtkj.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-28 01:19
+ * @describe
+ */
+@Data
+public class LineChartDataSet implements Serializable {
+
+	private List<LineChartData> lineChartDataList;
+}

+ 4 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/ProjectGroup.java

@@ -23,6 +23,10 @@ public class ProjectGroup extends BaseEntity {
 	@ApiModelProperty(value = "项目id")
 	private Long projectId;
 
+	@TableField("stage_id")
+	@ApiModelProperty(value = "阶段id")
+	private Long stageId;
+
 	@TableField("invite_dept")
 	@ApiModelProperty(value = "发起邀请的机构")
 	private Long inviteDept;

+ 5 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/Task.java

@@ -31,6 +31,11 @@ public class Task extends BaseEntity {
 	@NotNull(message = "projectId can't be null")
 	private Long projectId;
 
+	@JsonSerialize(using = ToStringSerializer.class)
+	@TableField("stage_id")
+	@NotNull(message = "stageId can't be null")
+	private Long stageId;
+
 	@TableField("title")
 	private String title;
 

+ 1 - 2
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/TaskContract.java

@@ -42,8 +42,7 @@ public class TaskContract extends BaseEntity {
 
 	@TableField("blade_file_id")
 	@ApiModelProperty(value = "文件上传完返回的主键id")
-	@JsonSerialize(using = ToStringSerializer.class)
-	private Long bladeFileId;
+	private String bladeFileId;
 
 	@TableField("amount")
 	@ApiModelProperty(value = "合同金额")

+ 21 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/ProjectStageVO.java

@@ -0,0 +1,21 @@
+package com.wtkj.vo;
+
+import com.wtkj.entity.ProjectStage;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-28 14:20
+ * @describe
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProjectStageVO extends ProjectStage {
+
+	private static final long serialVersionUID = 1L;
+
+	private Integer fileAmount = 0;
+
+
+}

+ 3 - 1
blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/TaskContractVO.java

@@ -5,6 +5,8 @@ import com.wutong.file.vo.FileVO;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.util.List;
+
 /**
  * @author Blizzard
  * @create at 2023-09-18 10:33
@@ -18,6 +20,6 @@ public class TaskContractVO extends TaskContract {
 
 	private String partyB;
 
-	private FileVO fileVO;
+	private List<FileVO> fileVO;
 
 }

+ 38 - 43
blade-service/wt-okr/src/main/java/com/wtkj/controller/CommonController.java

@@ -1,22 +1,16 @@
 package com.wtkj.controller;
 
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import com.wtkj.entity.DeptToDept;
 import com.wtkj.service.IDeptToDeptService;
 import com.wtkj.vo.AuthUserInfo;
-import com.wtkj.wrapper.UserListWrapper;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springblade.core.tool.api.R;
-import org.springblade.system.entity.Dept;
-import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-import java.util.ArrayList;
-import java.util.List;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * @author Blizzard
@@ -42,40 +36,41 @@ public class CommonController {
 		return R.data(deptToDeptService.userInfo());
 	}
 
-	/**
-	 * 新建机构
-	 */
-	@PostMapping("/sava-dept")
-	@ApiOperation(value = "新建政府机构", notes = "传入DeptToDept")
-	@ApiOperationSupport(order = 2)
-	public R<Boolean> createDept(@RequestBody @Valid DeptToDept dept) {
-		return R.status(deptToDeptService.saveOrUpdate(dept));
-	}
-
-	/**
-	 * 机构搜索
-	 */
-	@GetMapping("/get-dept")
-	@ApiOperation(value = "搜索机构", notes = "")
-	@ApiOperationSupport(order = 3)
-	public R<List<Dept>> list(Long topDept, String areaCode, String name, Integer category) {
-		return R.data(deptToDeptService.getDept(topDept, areaCode, name, category));
-	}
-
 
-	/**
-	 * 搜索用户
-	 */
-	@GetMapping("/get-user-list")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "搜索用户", notes = "")
-	public R getUserList(@RequestParam Long deptId, @RequestParam String name) {
-		List<User> list = new ArrayList<>();
-		R<List<User>> rpc = userClient.getDeptUserList(deptId, name);
-		if (rpc.isSuccess()) {
-			list = rpc.getData();
-		}
-		return R.data(UserListWrapper.build().listVO(list));
-	}
+//	/**
+//	 * 新建机构
+//	 */
+//	@PostMapping("/sava-dept")
+//	@ApiOperation(value = "新建政府机构", notes = "传入DeptToDept")
+//	@ApiOperationSupport(order = 2)
+//	public R<Boolean> createDept(@RequestBody @Valid DeptToDept dept) {
+//		return R.status(deptToDeptService.saveOrUpdate(dept));
+//	}
+//
+//	/**
+//	 * 机构搜索
+//	 */
+//	@GetMapping("/get-dept")
+//	@ApiOperation(value = "搜索机构", notes = "")
+//	@ApiOperationSupport(order = 3)
+//	public R<List<Dept>> list(Long topDept, String areaCode, String name, Integer category) {
+//		return R.data(deptToDeptService.getDept(topDept, areaCode, name, category));
+//	}
+//
+//
+//	/**
+//	 * 搜索用户
+//	 */
+//	@GetMapping("/get-user-list")
+//	@ApiOperationSupport(order = 4)
+//	@ApiOperation(value = "搜索用户", notes = "")
+//	public R getUserList(@RequestParam Long deptId, @RequestParam String name) {
+//		List<User> list = new ArrayList<>();
+//		R<List<User>> rpc = userClient.getDeptUserList(deptId, name);
+//		if (rpc.isSuccess()) {
+//			list = rpc.getData();
+//		}
+//		return R.data(UserListWrapper.build().listVO(list));
+//	}
 
 }

+ 17 - 13
blade-service/wt-okr/src/main/java/com/wtkj/controller/ProjectController.java

@@ -8,7 +8,9 @@ import com.wtkj.entity.ProjectGroup;
 import com.wtkj.entity.ProjectStage;
 import com.wtkj.service.*;
 import com.wtkj.vo.MyTaskStatistics;
+import com.wtkj.vo.ProjectStageVO;
 import com.wtkj.wrapper.ProjectGroupWrapper;
+import com.wtkj.wrapper.ProjectStageWrapper;
 import com.wtkj.wrapper.ProjectWrapper;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -87,8 +89,9 @@ public class ProjectController {
 	@GetMapping("/stage-list")
 	@ApiOperation(value = "项目下的所有阶段", notes = "传入projectId")
 	@ApiOperationSupport(order = 4)
-	public R<List<ProjectStage>> stageList(Long projectId) {
-		return R.data(stageService.listByProjectId(projectId));
+	public R<List<ProjectStageVO>> stageList(Long projectId) {
+		List<ProjectStage> projectStages = stageService.listByProjectId(projectId);
+		return R.data(ProjectStageWrapper.build().listVO(projectStages));
 	}
 
 	/**
@@ -98,7 +101,7 @@ public class ProjectController {
 	@ApiOperation(value = "修改项目阶段", notes = "")
 	@ApiOperationSupport(order = 5)
 	public R submitStage(@RequestBody ProjectStage stage) {
-		return R.status(stageService.saveOrUpdate(stage));
+		return R.status(stageService.submit(stage));
 	}
 
 	/**
@@ -108,7 +111,8 @@ public class ProjectController {
 	@ApiOperation(value = "阶段详情", notes = "传入stageId")
 	@ApiOperationSupport(order = 6)
 	public R stageDetail(@RequestParam Long stageId) {
-		return R.data(stageService.getById(stageId));
+		ProjectStage stage = stageService.getById(stageId);
+		return R.data(ProjectStageWrapper.build().entityVO(stage));
 	}
 
 	/**
@@ -144,10 +148,10 @@ public class ProjectController {
 	 * 工作台任务统计
 	 */
 	@GetMapping("/task-summary")
-	@ApiOperation(value = "项目任务统计", notes = "传入projectId")
+	@ApiOperation(value = "项目任务统计", notes = "传入stageId")
 	@ApiOperationSupport(order = 9)
-	public R<MyTaskStatistics> taskStatistics(@RequestParam Long projectId) {
-		return R.data(taskService.taskStatistics(projectId, null, null));
+	public R<MyTaskStatistics> taskStatistics(@RequestParam Long stageId) {
+		return R.data(taskService.taskStatistics(stageId, null, null));
 	}
 
 	/**
@@ -156,8 +160,8 @@ public class ProjectController {
 	@GetMapping("/task-distribution")
 	@ApiOperation(value = "任务分布", notes = "传入projectId")
 	@ApiOperationSupport(order = 10)
-	public R projectTaskSummary(@RequestParam Long projectId) {
-		return R.data(taskService.projectTaskSummary(projectId));
+	public R projectTaskSummary(@RequestParam Long stageId) {
+		return R.data(taskService.projectTaskSummary(stageId));
 	}
 
 	/**
@@ -166,15 +170,15 @@ public class ProjectController {
 	@GetMapping("/task-situation")
 	@ApiOperation(value = "任务进展走势", notes = "传入projectId")
 	@ApiOperationSupport(order = 11)
-	public R projectTaskSituation() {
-		return R.data(null);
+	public R projectTaskSituation(@RequestParam Long stageId) {
+		return R.data(taskService.projectTaskSituation(stageId));
 	}
 
 	@GetMapping("/task-burnout")
 	@ApiOperation(value = "任务燃尽", notes = "传入projectId")
 	@ApiOperationSupport(order = 12)
-	public R projectTaskBurnout() {
-		return R.data(null);
+	public R projectTaskBurnout(@RequestParam Long stageId) {
+		return R.data(taskService.projectTaskBurnout(stageId));
 	}
 
 

+ 2 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/FileAndFolderMapper.java

@@ -25,4 +25,6 @@ public interface FileAndFolderMapper extends BaseMapper<FileAndFolder> {
 	List<FileAndFolder> getChildren(Long stageId, Long parentId);
 
 	List<FileAndFolder> getPage(String projectId, Long stageId, Integer isLatest, IPage<FileAndFolder> page);
+
+	Integer selectFileAmountByStageId(Long stageId);
 }

+ 4 - 1
blade-service/wt-okr/src/main/java/com/wtkj/mapper/FileAndFolderMapper.xml

@@ -36,7 +36,7 @@
     <select id="getChildrenFileList" resultType="com.wtkj.entity.FileAndFolder">
         select * from blade_file_and_folder where is_deleted = 0 and type = 1
         <if test="param1 != null">
-            stage_id = #{param1}
+            and stage_id = #{param1}
         </if>
         <if test="param2 != null">
             and parent_id = #{param2}
@@ -63,4 +63,7 @@
         </if>
         order by create_time desc
     </select>
+    <select id="selectFileAmountByStageId" resultType="java.lang.Integer">
+        select count(id) from blade_file_and_folder where is_deleted = 0 and type = 1 and stage_id = #{param}
+    </select>
 </mapper>

+ 1 - 1
blade-service/wt-okr/src/main/java/com/wtkj/service/IAsyncService.java

@@ -23,7 +23,7 @@ public interface IAsyncService {
 	 */
 	void removeProject(List<Long> projectIds);
 
-	void createTaskLog(Task task);
+	void createTask(Task task);
 
 	//创建任务日志
 	void submitTaskMessage(Long userId, Task task);

+ 2 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/IFileAndFolderService.java

@@ -34,4 +34,6 @@ public interface IFileAndFolderService extends BaseService<FileAndFolder> {
 	List<FileAndFolder> getChildren(Long stageId, Long parentId);
 
 	IPage<FileAndFolder> selectPage(String projectId, Long stageId, Integer isLatest, IPage<FileAndFolder> page);
+
+	Integer getFileAmountByStageId(Long stageId);
 }

+ 2 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/IProjectStageService.java

@@ -12,4 +12,6 @@ import java.util.List;
  */
 public interface IProjectStageService extends BaseService<ProjectStage> {
 	List<ProjectStage> listByProjectId(Long projectId);
+
+	boolean submit(ProjectStage stage);
 }

+ 9 - 8
blade-service/wt-okr/src/main/java/com/wtkj/service/ITaskService.java

@@ -2,6 +2,7 @@ package com.wtkj.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.wtkj.dto.ProjectTaskPageDTO;
+import com.wtkj.entity.LineChartDataSet;
 import com.wtkj.entity.Task;
 import com.wtkj.vo.MyTaskStatistics;
 import org.springblade.core.mp.base.BaseService;
@@ -31,14 +32,14 @@ public interface ITaskService extends BaseService<Task> {
 	/**
 	 * 复用  复用
 	 */
-	MyTaskStatistics taskStatistics(Long projectId, Integer year, Integer month);
+	MyTaskStatistics taskStatistics(Long stageId, Integer year, Integer month);
 
 
 	List<Task> listByUser(Long userId, Integer year, Integer month);
 
 	boolean deleteTask(List<Long> taskIds);
 
-	List<Task> listByProjectId(Long projectId);
+	List<Task> listByStageId(Long stageId);
 
 	Set<Long> getByExecute(Long deptId, String userId);
 
@@ -76,14 +77,14 @@ public interface ITaskService extends BaseService<Task> {
 	/**
 	 * 项目任务饼图
 	 */
-	List<Map<String, String>> projectTaskSummary(Long projectId);
+	List<Map<String, String>> projectTaskSummary(Long stageId);
 
 	/**
 	 * 项目和项目执行人
-	 *
-	 * @param userId
-	 * @param projectId
-	 * @return
 	 */
-	List<Task> listByUserAndProject(Long userId, Long projectId);
+	List<Task> listByUserAndProject(Long userId, Long stageId);
+
+	LineChartDataSet projectTaskSituation(Long stageId);
+
+	LineChartDataSet projectTaskBurnout(Long stageId);
 }

+ 76 - 2
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/AsyncServiceImpl.java

@@ -1,6 +1,8 @@
 package com.wtkj.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.wtkj.entity.*;
+import com.wtkj.mapper.ProjectMapper;
 import com.wtkj.service.*;
 import lombok.AllArgsConstructor;
 import org.springblade.core.secure.BladeUser;
@@ -37,6 +39,8 @@ public class AsyncServiceImpl implements IAsyncService {
 	private final IUserClient userClient;
 	private final ITaskLogService taskLogService;
 	private final IIndexMessageService indexMessageService;
+	private final IProjectGroupService projectGroupService;
+	private final ProjectMapper projectMapper;
 
 	@Override
 	@Async("asyncPoolTaskExecutor")
@@ -49,7 +53,9 @@ public class AsyncServiceImpl implements IAsyncService {
 			List<ProjectStage> stagesList = new ArrayList<>();
 			templateStage.forEach(template -> {
 				//项目的阶段记录表
+				Long id = IdWorker.getId();
 				ProjectStage stage = new ProjectStage();
+				stage.setId(id);
 				stage.setProjectId(project.getId());
 				stage.setName(template.getName());
 				stage.setSort(template.getSort());
@@ -58,6 +64,11 @@ public class AsyncServiceImpl implements IAsyncService {
 				stage.setCreateTime(DateUtil.now());
 				stage.setUpdateTime(DateUtil.now());
 				stage.setUpdateUser(project.getUpdateUser());
+				//添加默认阶段
+				if (template.getSort() == 1) {
+					project.setCurrentStage(id);
+					projectMapper.updateById(project);
+				}
 				stagesList.add(stage);
 			});
 			if (!CollectionUtils.isEmpty(stagesList)) {
@@ -100,7 +111,7 @@ public class AsyncServiceImpl implements IAsyncService {
 
 	@Override
 	@Async("asyncPoolTaskExecutor")
-	public void createTaskLog(Task task) {
+	public void createTask(Task task) {
 		//1.任务日志
 		Long createUser = task.getCreateUser();
 		if (createUser != null) {
@@ -108,6 +119,8 @@ public class AsyncServiceImpl implements IAsyncService {
 			if (userR.isSuccess()) {
 				List<TaskLog> logs = new ArrayList<>();
 				List<ProjectAuth> auths = new ArrayList<>();
+				List<ProjectGroup> groups = new ArrayList<>();
+
 				TaskLog log = new TaskLog();
 				log.setTaskId(task.getId());
 				log.setContent(userR.getData().getName() + " 创建了任务");
@@ -163,9 +176,9 @@ public class AsyncServiceImpl implements IAsyncService {
 						taskLog.setUpdateTime(DateUtil.now());
 						logs.add(taskLog);
 
-						//2.项目权限
 						String deptStr = userR1.getData().getDeptId();
 						if (StringUtil.isNotBlank(deptStr) && orgDeptId != null) {
+							//2.项目权限
 							Long deptId = Func.firstLong(deptStr);
 							ProjectAuth auth = new ProjectAuth();
 							auth.setTopDept(orgDeptId);
@@ -173,7 +186,17 @@ public class AsyncServiceImpl implements IAsyncService {
 							auth.setProjectId(task.getProjectId());
 							auth.setUserId(projectManager);
 							auths.add(auth);
+
+							//3.项目组成员
+							ProjectGroup group = new ProjectGroup();
+							group.setInviteDept(null);
+							group.setProjectId(task.getProjectId());
+							group.setStageId(task.getStageId());
+							group.setBeInvitedDept(orgDeptId);
+							group.setUserId(projectManager);
+							groups.add(group);
 						}
+
 					}
 				}
 				if (StringUtil.isNotBlank(task.getExecuteUser())) {
@@ -194,6 +217,15 @@ public class AsyncServiceImpl implements IAsyncService {
 								auth.setProjectId(task.getProjectId());
 								auth.setUserId(userId);
 								auths.add(auth);
+
+								//项目组成员
+								ProjectGroup group = new ProjectGroup();
+								group.setInviteDept(null);
+								group.setProjectId(task.getProjectId());
+								group.setStageId(task.getStageId());
+								group.setBeInvitedDept(finalOrgDeptId);
+								group.setUserId(userId);
+								groups.add(group);
 							}
 						}
 					});
@@ -228,6 +260,14 @@ public class AsyncServiceImpl implements IAsyncService {
 								auth.setProjectId(task.getProjectId());
 								auth.setUserId(userId);
 								auths.add(auth);
+
+								ProjectGroup group = new ProjectGroup();
+								group.setInviteDept(null);
+								group.setProjectId(task.getProjectId());
+								group.setStageId(task.getStageId());
+								group.setBeInvitedDept(finalOrgDeptId1);
+								group.setUserId(userId);
+								groups.add(group);
 							}
 						}
 					});
@@ -247,6 +287,9 @@ public class AsyncServiceImpl implements IAsyncService {
 				if (!CollectionUtils.isEmpty(auths)) {
 					projectAuthService.saveBatch(auths);
 				}
+				if (!CollectionUtils.isEmpty(groups)) {
+					projectGroupService.saveBatch(groups);
+				}
 			}
 		}
 		// todo 2.任务下发通知
@@ -259,6 +302,8 @@ public class AsyncServiceImpl implements IAsyncService {
 		if (userR.isSuccess()) {
 			List<TaskLog> logs = new ArrayList<>();
 			List<ProjectAuth> auths = new ArrayList<>();
+			List<ProjectGroup> groups = new ArrayList<>();
+
 			Long orgDeptId = task.getOrgDeptId();
 			switch (type) {
 				case 1:
@@ -306,6 +351,7 @@ public class AsyncServiceImpl implements IAsyncService {
 
 						String deptStr = userR1.getData().getDeptId();
 						if (StringUtil.isNotBlank(deptStr) && orgDeptId != null) {
+							//项目权限
 							Long deptId = Func.firstLong(deptStr);
 							ProjectAuth auth = new ProjectAuth();
 							auth.setTopDept(orgDeptId);
@@ -313,6 +359,15 @@ public class AsyncServiceImpl implements IAsyncService {
 							auth.setProjectId(task.getProjectId());
 							auth.setUserId(projectManager);
 							auths.add(auth);
+
+							//项目组
+							ProjectGroup group = new ProjectGroup();
+							group.setInviteDept(null);
+							group.setProjectId(task.getProjectId());
+							group.setStageId(task.getStageId());
+							group.setBeInvitedDept(orgDeptId);
+							group.setUserId(projectManager);
+							groups.add(group);
 						}
 					}
 					break;
@@ -333,6 +388,14 @@ public class AsyncServiceImpl implements IAsyncService {
 								auth.setProjectId(task.getProjectId());
 								auth.setUserId(id);
 								auths.add(auth);
+
+								ProjectGroup group = new ProjectGroup();
+								group.setInviteDept(null);
+								group.setProjectId(task.getProjectId());
+								group.setStageId(task.getStageId());
+								group.setBeInvitedDept(orgDeptId);
+								group.setUserId(id);
+								groups.add(group);
 							}
 						}
 					});
@@ -365,6 +428,14 @@ public class AsyncServiceImpl implements IAsyncService {
 								auth.setProjectId(task.getProjectId());
 								auth.setUserId(id);
 								auths.add(auth);
+
+								ProjectGroup group = new ProjectGroup();
+								group.setInviteDept(null);
+								group.setProjectId(task.getProjectId());
+								group.setStageId(task.getStageId());
+								group.setBeInvitedDept(orgDeptId);
+								group.setUserId(id);
+								groups.add(group);
 							}
 						}
 					});
@@ -384,6 +455,9 @@ public class AsyncServiceImpl implements IAsyncService {
 			if (!CollectionUtils.isEmpty(auths)) {
 				projectAuthService.saveBatch(auths);
 			}
+			if (!CollectionUtils.isEmpty(groups)) {
+				projectGroupService.saveBatch(groups);
+			}
 		}
 	}
 

+ 1 - 1
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/DeptToDeptServiceImpl.java

@@ -53,7 +53,7 @@ public class DeptToDeptServiceImpl extends BaseServiceImpl<DeptToDeptMapper, Dep
 					if (ancestors != null && ancestors.contains(String.valueOf(ZERO))) {
 						List<Long> longList = Func.toLongList(ancestors);
 						if (!CollectionUtils.isEmpty(longList)) {
-							if (longList.size() > 2) {
+							if (longList.size() > 1) {
 								userInfo.setTopDept(longList.get(1));
 							} else {
 								userInfo.setTopDept(Long.valueOf(deptIdStr));

+ 5 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/FileAndFolderServiceImpl.java

@@ -119,6 +119,11 @@ public class FileAndFolderServiceImpl extends BaseServiceImpl<FileAndFolderMappe
 		return page.setRecords(list);
 	}
 
+	@Override
+	public Integer getFileAmountByStageId(Long stageId) {
+		return baseMapper.selectFileAmountByStageId(stageId);
+	}
+
 
 	private List<FileAndFolder> getChildrenByFolderId(ArrayList<FileAndFolder> result, Long stageId, Long parentId) {
 		//文件下的文件和文件夹

+ 36 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ProjectStageServiceImplService.java

@@ -5,8 +5,15 @@ import com.wtkj.mapper.ProjectStageMapper;
 import com.wtkj.service.IProjectStageService;
 import lombok.AllArgsConstructor;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -17,8 +24,37 @@ import java.util.List;
 @Service
 @AllArgsConstructor
 public class ProjectStageServiceImplService extends BaseServiceImpl<ProjectStageMapper, ProjectStage> implements IProjectStageService {
+
+	private final BladeRedis redis;
 	@Override
 	public List<ProjectStage> listByProjectId(Long projectId) {
 		return baseMapper.selectByProjectId(projectId);
 	}
+
+	@Override
+	public boolean submit(ProjectStage stage) {
+		boolean flag = false;
+		if (stage.getId() == null) {
+			flag = this.save(stage);
+		} else {
+			Long id = stage.getId();
+
+			List<LocalDate> dateList = new ArrayList<>();
+			Date startTime = stage.getStartTime();
+			Date endTime = stage.getEndTime();
+			Instant instant = startTime.toInstant();
+			Instant instant1 = endTime.toInstant();
+			LocalDate start = instant.atZone(ZoneId.systemDefault()).toLocalDate();
+			LocalDate end = instant1.atZone(ZoneId.systemDefault()).toLocalDate();
+			while (!start.isAfter(end)) {    //判断是否到达结束日期
+				dateList.add(start);
+				start = start.plusDays(1);  // 加一天
+			}
+			if (!CollectionUtils.isEmpty(dateList)) {
+				redis.set("dateList::" + id, dateList);
+			}
+			flag = this.updateById(stage);
+		}
+		return flag;
+	}
 }

+ 0 - 1
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/QrcodeServiceImpl.java

@@ -91,7 +91,6 @@ public class QrcodeServiceImpl implements IQrcodeService {
 			auth.setUserId(auth.getUserId());
 			projectAuthService.save(auth);
 
-			// todo  联系人
 
 			Project project = projectService.getById(projectId);
 			if (project != null) {

+ 63 - 18
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/TaskServiceImpl.java

@@ -3,19 +3,16 @@ package com.wtkj.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.wtkj.dto.ProjectTaskPageDTO;
-import com.wtkj.entity.FileAndFolder;
-import com.wtkj.entity.Task;
-import com.wtkj.entity.TaskFile;
+import com.wtkj.entity.*;
 import com.wtkj.mapper.TaskMapper;
-import com.wtkj.service.IAsyncService;
-import com.wtkj.service.IFileAndFolderService;
-import com.wtkj.service.ITaskFileService;
-import com.wtkj.service.ITaskService;
+import com.wtkj.service.*;
 import com.wtkj.vo.MyTaskStatistics;
 import com.wutong.file.feign.IFileClient;
 import com.wutong.file.vo.FileVO;
 import lombok.AllArgsConstructor;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.DateUtil;
@@ -27,6 +24,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 /**
@@ -43,19 +41,30 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	private final IFileAndFolderService fileAndFolderService;
 	private final IFileClient fileClient;
 	private final IUserClient userClient;
+	private final IProjectStageService stageService;
+	private final BladeRedis redis;
 
 	@Override
 	public boolean submit(Task task) {
 		boolean flag = false;
 		Long taskId = task.getId();
 		if (taskId == null) {
+			Long stageId = task.getStageId();
+			ProjectStage stage = stageService.getById(stageId);
+			if (stage != null) {
+				Date startTime = stage.getStartTime();
+				Date endTime = stage.getEndTime();
+				if (task.getStartTime().before(startTime) || task.getEndTime().after(endTime)) {
+					throw new ServiceException(String.format("任务时间异常,不可超出当前阶段的起止时间%s-%s", startTime, endTime));
+				}
+			}
 			LocalDate now = LocalDate.now();
 			Integer year = now.getYear();
 			Integer month = now.getMonthValue();
 			task.setYear(year);
 			task.setMonth(month);
 			flag = this.save(task);
-			asyncService.createTaskLog(task);
+			asyncService.createTask(task);
 		} else {
 			//执行的顶级单位
 			Long userId = AuthUtil.getUserId();
@@ -91,6 +100,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	public IPage<Task> projectTaskPage(ProjectTaskPageDTO dto, IPage<Task> page) {
 		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
 		lqw.eq(Task::getProjectId, dto.getProjectId());
+		lqw.eq(Task::getStageId, dto.getStageId());
 		if (dto.getDeptCategory().equals(3)) {
 			//是业主
 			dto.setOrgDeptId(null);
@@ -198,16 +208,16 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	}
 
 	@Override
-	public MyTaskStatistics taskStatistics(Long projectId, Integer year, Integer month) {
+	public MyTaskStatistics taskStatistics(Long stageId, Integer year, Integer month) {
 		MyTaskStatistics statistics = new MyTaskStatistics();
 		Long userId = AuthUtil.getUserId();
 		List<Task> tasks = null;
-		if (projectId == null) {
+		if (stageId == null) {
 			//个人任务统计
 			tasks = this.listByUser(userId, year, month);
 		} else {
 			//项目下的所有任务
-			tasks = this.listByProjectId(projectId);
+			tasks = this.listByStageId(stageId);
 		}
 		if (!CollectionUtils.isEmpty(tasks)) {
 			//全部任务数
@@ -275,9 +285,9 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	}
 
 	@Override
-	public List<Task> listByProjectId(Long projectId) {
+	public List<Task> listByStageId(Long stageId) {
 		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
-		lqw.eq(Task::getProjectId, projectId);
+		lqw.eq(Task::getStageId, stageId);
 		lqw.orderByAsc(Task::getEndTime);
 		return this.list(lqw);
 	}
@@ -329,11 +339,11 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	}
 
 	@Override
-	public List<Map<String, String>> projectTaskSummary(Long projectId) {
+	public List<Map<String, String>> projectTaskSummary(Long stageId) {
 		List<Map<String, String>> res = new ArrayList<>();
 		//项目下任务执行者的情况
 		Set<Long> userIds = new HashSet<>();
-		List<Task> tasks = this.listByProjectId(projectId);
+		List<Task> tasks = this.listByStageId(stageId);
 		if (!CollectionUtils.isEmpty(tasks)) {
 			for (Task task : tasks) {
 				String executeUser = task.getExecuteUser();
@@ -348,7 +358,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 				Map<String, String> map = new HashMap<>();
 				R<User> userR = userClient.userInfoById(userId);
 				if (userR.isSuccess()) {
-					List<Task> tasks1 = this.listByUserAndProject(userId, projectId);
+					List<Task> tasks1 = this.listByUserAndProject(userId, stageId);
 					if (!CollectionUtils.isEmpty(tasks1)) {
 						map.put("value", String.valueOf(tasks1.size()));
 						map.put("name", userR.getData().getName());
@@ -362,11 +372,46 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	}
 
 	@Override
-	public List<Task> listByUserAndProject(Long userId, Long projectId) {
+	public List<Task> listByUserAndProject(Long userId, Long stageId) {
 		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
-		lqw.eq(Task::getProjectId, projectId);
+		lqw.eq(Task::getStageId, stageId);
 		lqw.like(Task::getExecuteUser, String.valueOf(userId));
 		lqw.orderByAsc(Task::getEndTime);
 		return this.list(lqw);
 	}
+
+	@Override
+	public LineChartDataSet projectTaskSituation(Long stageId) {
+		LineChartDataSet set = new LineChartDataSet();
+		List<LineChartData> list = new ArrayList<>();
+		//1.阶段周期
+		List<LocalDate> dateList = redis.get("dateList::" + stageId);
+		if (!CollectionUtils.isEmpty(dateList)) {
+			LineChartData line = new LineChartData();
+			line.setType("line");
+			line.setName("leftTask");
+			List<Map<String, Object>> data = new ArrayList<>();
+			dateList.forEach(date -> {
+				DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 设置日期格
+				String formatDate = date.format(formatter);
+				Map<String, Object> map = new HashMap<>();
+				map.put(formatDate, null);
+			});
+			line.setData(data);
+
+
+			list.add(line);
+		}
+		set.setLineChartDataList(list);
+		return set;
+
+	}
+
+	@Override
+	public LineChartDataSet projectTaskBurnout(Long stageId) {
+		LineChartDataSet set = new LineChartDataSet();
+		List<LineChartData> list = new ArrayList<>();
+		set.setLineChartDataList(list);
+		return set;
+	}
 }

+ 34 - 0
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ProjectStageWrapper.java

@@ -0,0 +1,34 @@
+package com.wtkj.wrapper;
+
+import com.wtkj.entity.ProjectStage;
+import com.wtkj.service.IFileAndFolderService;
+import com.wtkj.vo.ProjectStageVO;
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.SpringUtil;
+
+import java.util.Objects;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-28 14:20
+ * @describe
+ */
+public class ProjectStageWrapper extends BaseEntityWrapper<ProjectStage, ProjectStageVO> {
+
+	private static IFileAndFolderService fileAndFolderService;
+
+	public static ProjectStageWrapper build() {
+		fileAndFolderService = SpringUtil.getBean(IFileAndFolderService.class);
+		return new ProjectStageWrapper();
+	}
+
+	@Override
+	public ProjectStageVO entityVO(ProjectStage entity) {
+		ProjectStageVO vo = Objects.requireNonNull(BeanUtil.copy(entity, ProjectStageVO.class));
+		Long stageId = entity.getId();
+		Integer amount = fileAndFolderService.getFileAmountByStageId(stageId);
+		vo.setFileAmount(amount);
+		return vo;
+	}
+}

+ 18 - 6
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/TaskContractWrapper.java

@@ -7,10 +7,14 @@ import com.wutong.file.vo.FileVO;
 import org.springblade.core.mp.support.BaseEntityWrapper;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.SpringUtil;
+import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.system.entity.Dept;
 import org.springblade.system.feign.ISysClient;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -37,13 +41,21 @@ public class TaskContractWrapper extends BaseEntityWrapper<TaskContract, TaskCon
 		if (rpc.isSuccess()) {
 			vo.setPartyB(rpc.getData().getDeptName());
 		}
-		Long fileId = entity.getBladeFileId();
-		if (fileId != null) {
-			R<FileVO> byId = fileClient.findById(fileId);
-			if (byId.isSuccess()) {
-				vo.setFileVO(byId.getData());
-			}
+
+
+		String bladeFileIds = entity.getBladeFileId();
+		if (StringUtil.isNotBlank(bladeFileIds)) {
+			List<FileVO> files = new ArrayList<>();
+			List<Long> fileIds = Func.toLongList(bladeFileIds);
+			fileIds.forEach(fileId -> {
+				R<FileVO> byId = fileClient.findById(fileId);
+				if (byId.isSuccess()) {
+					files.add(byId.getData());
+				}
+			});
+			vo.setFileVO(files);
 		}
+
 		return vo;
 	}
 }