فهرست منبع

feat: project group

Blizzard 1 سال پیش
والد
کامیت
cd1a5cd068
31فایلهای تغییر یافته به همراه740 افزوده شده و 59 حذف شده
  1. 33 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/dto/ProjectTaskPageDTO.java
  2. 33 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/Contacts.java
  3. 37 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/ProjectGroup.java
  4. 8 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/ProjectStage.java
  5. 0 23
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/TaskToExecute.java
  6. 2 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/FileAndFolderVO.java
  7. 2 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/MyTaskStatistics.java
  8. 28 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/ProjectGroupVO.java
  9. 2 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/TaskVO.java
  10. 6 1
      blade-service/wt-okr/src/main/java/com/wtkj/config/MagicValue.java
  11. 28 0
      blade-service/wt-okr/src/main/java/com/wtkj/config/NacosConfigValue.java
  12. 28 12
      blade-service/wt-okr/src/main/java/com/wtkj/controller/CommonController.java
  13. 32 4
      blade-service/wt-okr/src/main/java/com/wtkj/controller/ProjectController.java
  14. 57 0
      blade-service/wt-okr/src/main/java/com/wtkj/controller/QrCodeController.java
  15. 9 5
      blade-service/wt-okr/src/main/java/com/wtkj/controller/TaskController.java
  16. 19 0
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactsMapper.java
  17. 13 0
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactsMapper.xml
  18. 17 0
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ProjectGroupMapper.java
  19. 14 0
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ProjectGroupMapper.xml
  20. 18 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/IContactsService.java
  21. 17 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/IProjectGroupService.java
  22. 16 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/IQrcodeService.java
  23. 9 2
      blade-service/wt-okr/src/main/java/com/wtkj/service/ITaskService.java
  24. 7 4
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/AsyncServiceImpl.java
  25. 53 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ContactsServiceImpl.java
  26. 45 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ProjectGroupServiceImpl.java
  27. 95 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/QrcodeServiceImpl.java
  28. 31 5
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/TaskServiceImpl.java
  29. 1 0
      blade-service/wt-okr/src/main/java/com/wtkj/wrapper/FileAndFolderWrapper.java
  30. 68 0
      blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ProjectGroupWrapper.java
  31. 12 3
      blade-service/wt-okr/src/main/java/com/wtkj/wrapper/TaskWrapper.java

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

@@ -0,0 +1,33 @@
+package com.wtkj.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 09:50
+ * @describe
+ */
+@Data
+public class ProjectTaskPageDTO implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@NotNull(message = "projectId can't be null")
+	private Long projectId;
+
+	private String name;
+
+	private Long orgDeptId;
+
+	private Integer taskStatus;
+
+	@NotNull(message = "current can't be null")
+	private Integer current;
+
+	@NotNull(message = "size can't be null")
+	private Integer size;
+
+}

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

@@ -0,0 +1,33 @@
+package com.wtkj.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 10:00
+ * @describe
+ */
+@EqualsAndHashCode(callSuper = true)
+@TableName("blade_contacts")
+@Data
+public class Contacts extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty(value = "顶级机构id")
+	@TableField("top_dept")
+	@JsonSerialize(using = ToStringSerializer.class)
+	private Long topDept;
+
+	@ApiModelProperty(value = "关联机构的顶级机构id")
+	@TableField("related_top_dept")
+	@JsonSerialize(using = ToStringSerializer.class)
+	private Long relatedTopDept;
+}

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

@@ -0,0 +1,37 @@
+package com.wtkj.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 21:22
+ * @describe
+ */
+@EqualsAndHashCode(callSuper = true)
+@TableName("blade_project_group")
+@Data
+public class ProjectGroup extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	@TableField("project_id")
+	@ApiModelProperty(value = "项目id")
+	private Long projectId;
+
+	@TableField("invite_dept")
+	@ApiModelProperty(value = "发起邀请的机构")
+	private Long inviteDept;
+
+	@TableField("be_invited_dept")
+	@ApiModelProperty(value = "接受邀请的机构")
+	private Long beInvitedDept;
+
+	@TableField("user_id")
+	@ApiModelProperty(value = "接受邀请的用户")
+	private Long userId;
+}

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

@@ -10,6 +10,7 @@ import lombok.EqualsAndHashCode;
 import org.springblade.core.mp.base.BaseEntity;
 
 import javax.validation.constraints.NotNull;
+import java.util.Date;
 
 /**
  * @author Blizzard
@@ -36,4 +37,11 @@ public class ProjectStage extends BaseEntity {
 	@NotNull(message = "sort不可为空")
 	private Integer sort;
 
+	@TableField("start_time")
+	@ApiModelProperty("阶段周期开始时间")
+	private Date startTime;
+
+	@TableField("end_time")
+	@ApiModelProperty("阶段周期结束时间")
+	private Date endTime;
 }

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

@@ -1,23 +0,0 @@
-package com.wtkj.entity;
-
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.springblade.core.mp.base.BaseEntity;
-
-/**
- * @author Blizzard
- * @create at 2023-09-15 15:03
- * @describe
- */
-@EqualsAndHashCode(callSuper = true)
-@Data
-@TableName("blade_task_to_execute")
-public class TaskToExecute extends BaseEntity {
-
-	private static final long serialVersionUID = 1L;
-
-	private Long taskId;
-
-
-}

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

@@ -30,6 +30,8 @@ public class FileAndFolderVO extends FileAndFolder {
 
 	private String volume;
 
+	private String suffix;
+
 	private String url;
 
 	private Set<User> readUsers;

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

@@ -23,6 +23,8 @@ public class MyTaskStatistics implements Serializable {
 
 	private Integer toConfirmed = 0;
 
+	private Integer timeToConfirm = 0;
+
 	private Integer todayToExpire = 0;
 
 	private Integer overdueComplete = 0;

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

@@ -0,0 +1,28 @@
+package com.wtkj.vo;
+
+import com.wtkj.entity.ProjectGroup;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.system.user.entity.User;
+
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-20 09:30
+ * @describe
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProjectGroupVO extends ProjectGroup {
+
+	private static final long serialVersionUID = 1L;
+
+	private String deptName;
+
+	private Integer size;
+
+	private List<User> users;
+
+
+}

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

@@ -18,6 +18,8 @@ import java.util.List;
 public class TaskVO extends Task {
 	private static final long serialVersionUID = 1L;
 
+	private String projectName;
+
 	private User projectManagerUser;
 
 	private String dispatchUintName;

+ 6 - 1
blade-service/wt-okr/src/main/java/com/wtkj/config/MagicValue.java

@@ -15,7 +15,12 @@ public interface MagicValue {
 	/**
 	 * 服务机构管理员
 	 */
-	String STAFF_ADMIN = "admin";
+	String STAFF_ADMIN = "staff_admin";
+
+	/**
+	 * 服务机构次级管理员
+	 */
+	String STAFF_SECOND_ADMIN = "staff_second_admin";
 
 	Integer ZERO = 0;
 

+ 28 - 0
blade-service/wt-okr/src/main/java/com/wtkj/config/NacosConfigValue.java

@@ -0,0 +1,28 @@
+package com.wtkj.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 11:08
+ * @describe nacos配置中心读取 配置
+ */
+@Configuration
+public class NacosConfigValue {
+
+
+	public static long expireIn;
+
+	public static long scanCount;
+
+	@Value("${qrcode.expireIn}")
+	public void setExpireIn(Long expireIn) {
+		NacosConfigValue.expireIn = expireIn;
+	}
+
+	@Value("${qrcode.scanCount}")
+	public void setScanCount(Long scanCount) {
+		NacosConfigValue.scanCount = scanCount;
+	}
+}

+ 28 - 12
blade-service/wt-okr/src/main/java/com/wtkj/controller/CommonController.java

@@ -1,19 +1,22 @@
 package com.wtkj.controller;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.wtkj.entity.DeptToDept;
+import com.wtkj.service.IContactsService;
 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.mp.support.Query;
 import org.springblade.core.tool.api.R;
 import org.springblade.system.entity.Dept;
 import org.springblade.system.feign.ISysClient;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
-import org.springframework.util.CollectionUtils;
+import org.springblade.system.vo.DeptVO;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
@@ -34,6 +37,7 @@ public class CommonController {
 	private final IDeptToDeptService deptToDeptService;
 	private final ISysClient sysClient;
 	private final IUserClient userClient;
+	private final IContactsService contactsService;
 
 	/**
 	 * 当前登录用户信息
@@ -69,24 +73,36 @@ public class CommonController {
 	 * 本机构下的机构
 	 */
 	@GetMapping("/dept-by-parentId")
-	@ApiOperation(value = "机构下的子机构", notes = "传入上级机构id")
+	@ApiOperation(value = "内部通讯录or懒加载树形结构", notes = "传入上级机构id")
 	@ApiOperationSupport(order = 4)
-	public R<List<Dept>> deptList(@RequestParam Long parentId) {
-		List<Dept> result = new ArrayList<>();
-		R<List<Dept>> rpc = sysClient.getDeptChildByParentId(parentId);
-		if (rpc.isSuccess() && !CollectionUtils.isEmpty(rpc.getData())) {
-			result.addAll(rpc.getData());
+	public R<List<DeptVO>> deptList(@RequestParam Long parentId) {
+		List<DeptVO> res = new ArrayList<>();
+		R<List<DeptVO>> rpc = sysClient.getDeptLazyList(parentId);
+		if (rpc.isSuccess()) {
+			res = rpc.getData();
 		}
-		return R.data(result);
+		return R.data(res);
 	}
 
+
 	/**
-	 * 机构下的
+	 * 外部联系
 	 */
-	@GetMapping("/get-user-list")
+	@GetMapping("/outer-dept")
+	@ApiOperation(value = "外部联系人", notes = "传入登录用户的topDept,分页参数")
 	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "机构下用户列表", notes = "")
-	public R getUserList(@RequestParam Long deptId, String name) {
+	public R address(@RequestParam Long topDept, Query query) {
+		IPage<DeptVO> page = contactsService.deptPage(topDept, query);
+		return R.data(page);
+	}
+
+	/**
+	 * 搜索用户
+	 */
+	@GetMapping("/get-user-list")
+	@ApiOperationSupport(order = 6)
+	@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()) {

+ 32 - 4
blade-service/wt-okr/src/main/java/com/wtkj/controller/ProjectController.java

@@ -4,10 +4,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.wtkj.dto.ProjectPageDTO;
 import com.wtkj.entity.Project;
+import com.wtkj.entity.ProjectGroup;
 import com.wtkj.entity.ProjectStage;
-import com.wtkj.service.IAsyncService;
-import com.wtkj.service.IProjectService;
-import com.wtkj.service.IProjectStageService;
+import com.wtkj.service.*;
+import com.wtkj.vo.MyTaskStatistics;
+import com.wtkj.wrapper.ProjectGroupWrapper;
 import com.wtkj.wrapper.ProjectWrapper;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -38,6 +39,9 @@ public class ProjectController {
 
 	private final IProjectStageService stageService;
 
+	private final ITaskService taskService;
+
+	private final IProjectGroupService projectGroupService;
 	/**
 	 * 创建/修改项目
 	 */
@@ -82,9 +86,33 @@ public class ProjectController {
 	 */
 	@GetMapping("/stage-list")
 	@ApiOperation(value = "项目下的所有阶段", notes = "传入projectId")
-	@ApiOperationSupport(order = 7)
+	@ApiOperationSupport(order = 4)
 	public R<List<ProjectStage>> stageList(Long projectId) {
 		return R.data(stageService.listByProjectId(projectId));
 	}
 
+
+	/**
+	 * 工作台任务统计
+	 */
+	@GetMapping("/task-summary")
+	@ApiOperation(value = "项目任务统计", notes = "传入projectId")
+	@ApiOperationSupport(order = 5)
+	public R<MyTaskStatistics> taskStatistics(@RequestParam Long projectId) {
+		return R.data(taskService.TaskStatistics(projectId, null, null));
+	}
+
+
+	/**
+	 * 项目小组
+	 */
+	@GetMapping("/project-group-mem")
+	@ApiOperation(value = "项目组成员", notes = "传入projectId,competentUnit:主管单位")
+	@ApiOperationSupport(order = 6)
+	public R groupMem(@RequestParam Long projectId, @RequestParam Long competentUnit) {
+		List<ProjectGroup> list = projectGroupService.getGroupByProjectId(projectId, competentUnit);
+		return R.data(ProjectGroupWrapper.build().listVO(list));
+	}
+
+
 }

+ 57 - 0
blade-service/wt-okr/src/main/java/com/wtkj/controller/QrCodeController.java

@@ -0,0 +1,57 @@
+package com.wtkj.controller;
+
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.wtkj.service.IQrcodeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springblade.core.tool.api.R;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 17:25
+ * @describe
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/qrcode")
+@Api(value = "二维码模块", tags = "二维码模块")
+public class QrCodeController {
+
+	private final IQrcodeService qrcodeService;
+
+	/**
+	 * 生成二维码
+	 */
+	@GetMapping("/create-qrcode")
+	@ApiOperation(value = "生成二维码", notes = "")
+	@ApiOperationSupport(order = 1)
+	public R createQrcode() {
+		return R.data(qrcodeService.createQrcode());
+	}
+
+	/**
+	 * 邀请至机构下
+	 */
+	@GetMapping("/invite-to-dept")
+	@ApiOperation(value = "接受邀请至机构下", notes = "")
+	@ApiOperationSupport(order = 2)
+	public R inviteToDept(@RequestParam String qrcodeId, @RequestParam Long userId, @RequestParam Long deptId) {
+		return R.status(qrcodeService.inviteToDept(qrcodeId, userId, deptId));
+	}
+
+	/**
+	 * 邀请至项目组
+	 */
+	@GetMapping("/invite-to-project")
+	@ApiOperation(value = "接受邀请至项目组", notes = "ownerDept:主管单位,deptId:服务商的顶级机构id")
+	@ApiOperationSupport(order = 3)
+	public R inviteToProject(@RequestParam String qrcodeId, @RequestParam Long ownerDept, @RequestParam Long deptId, @RequestParam Long projectId) {
+		return R.status(qrcodeService.inviteToProject(qrcodeId, ownerDept, deptId, projectId));
+	}
+
+}

+ 9 - 5
blade-service/wt-okr/src/main/java/com/wtkj/controller/TaskController.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.wtkj.dto.ProjectTaskPageDTO;
 import com.wtkj.entity.*;
 import com.wtkj.service.*;
 import com.wtkj.vo.*;
@@ -61,7 +62,7 @@ public class TaskController {
 	@ApiOperationSupport(order = 2)
 	@ApiOperation(value = "我的任务统计", notes = "")
 	public R myTask(@RequestParam Integer year, @RequestParam Integer month) {
-		return R.data(taskService.myTaskStatistics(year, month));
+		return R.data(taskService.TaskStatistics(null, year, month));
 	}
 
 	/**
@@ -77,11 +78,14 @@ public class TaskController {
 	/**
 	 * 项目任务列表
 	 */
-	@GetMapping("/project-task-page")
+	@PostMapping("/project-task-page")
 	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "项目任务列表", notes = "传入projectId,分页参数")
-	public R<IPage<TaskVO>> projectTask(@RequestParam Long projectId, Query query) {
-		IPage<Task> page = taskService.projectTaskPage(projectId, Condition.getPage(query));
+	@ApiOperation(value = "项目任务列表", notes = "")
+	public R<IPage<TaskVO>> projectTask(@RequestBody ProjectTaskPageDTO dto) {
+		Query query = new Query();
+		query.setCurrent(dto.getCurrent());
+		query.setSize(dto.getSize());
+		IPage<Task> page = taskService.projectTaskPage(dto, Condition.getPage(query));
 		return R.data(TaskWrapper.build().pageVO(page));
 	}
 

+ 19 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactsMapper.java

@@ -0,0 +1,19 @@
+package com.wtkj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.entity.Contacts;
+
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 11:02
+ * @describe
+ */
+public interface ContactsMapper extends BaseMapper<Contacts> {
+	List<Contacts> pageByTopDept(Long topDept, IPage<Contacts> page);
+
+	List<Contacts> selectByTopDept(Long topDept);
+
+}

+ 13 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactsMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.wtkj.mapper.ContactsMapper">
+
+
+    <select id="pageByTopDept" resultType="com.wtkj.entity.Contacts">
+        select * from blade_contacts where is_deleted = 0 and top_dept = #{param}
+    </select>
+
+    <select id="selectByTopDept" resultType="com.wtkj.entity.Contacts">
+        select * from blade_contacts where is_deleted = 0 and top_dept = #{param}
+    </select>
+</mapper>

+ 17 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/ProjectGroupMapper.java

@@ -0,0 +1,17 @@
+package com.wtkj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wtkj.entity.ProjectGroup;
+
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 21:29
+ * @describe
+ */
+public interface ProjectGroupMapper extends BaseMapper<ProjectGroup> {
+	List<ProjectGroup> selectGroupByProjectId(Long projectId, Long competentUnit);
+
+	List<ProjectGroup> selectUserByBeInvitedDept(Long projectId, Long beInvitedDept);
+}

+ 14 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/ProjectGroupMapper.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.wtkj.mapper.ProjectGroupMapper">
+
+
+    <select id="selectGroupByProjectId" resultType="com.wtkj.entity.ProjectGroup">
+        select * from blade_project_group where is_deleted = 0 and project_id = #{param1} and invite_dept = #{param2}
+    </select>
+
+    <select id="selectUserByBeInvitedDept" resultType="com.wtkj.entity.ProjectGroup">
+        select * from blade_project_group where is_deleted = 0 and project_id = #{param1} and be_invited_dept =
+        #{param2}
+    </select>
+</mapper>

+ 18 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/IContactsService.java

@@ -0,0 +1,18 @@
+package com.wtkj.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.entity.Contacts;
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.mp.support.Query;
+import org.springblade.system.vo.DeptVO;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 11:01
+ * @describe
+ */
+public interface IContactsService extends BaseService<Contacts> {
+	IPage<Contacts> pageByTopDept(Long topDept, IPage<Contacts> page);
+
+	IPage<DeptVO> deptPage(Long topDept, Query query);
+}

+ 17 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/IProjectGroupService.java

@@ -0,0 +1,17 @@
+package com.wtkj.service;
+
+import com.wtkj.entity.ProjectGroup;
+import org.springblade.core.mp.base.BaseService;
+
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 21:30
+ * @describe
+ */
+public interface IProjectGroupService extends BaseService<ProjectGroup> {
+	List<ProjectGroup> getGroupByProjectId(Long projectId, Long competentUnit);
+
+	List<ProjectGroup> getUserByBeInvitedDept(Long projectId, Long beInvitedDept);
+}

+ 16 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/IQrcodeService.java

@@ -0,0 +1,16 @@
+package com.wtkj.service;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 17:35
+ * @describe
+ */
+public interface IQrcodeService {
+
+
+	String createQrcode();
+
+	boolean inviteToDept(String qrcodeId, Long userId, Long deptId);
+
+	boolean inviteToProject(String qrcodeId, Long ownerDept, Long deptId, Long projectId);
+}

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

@@ -1,6 +1,7 @@
 package com.wtkj.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.dto.ProjectTaskPageDTO;
 import com.wtkj.entity.Task;
 import com.wtkj.vo.MyTaskStatistics;
 import org.springblade.core.mp.base.BaseService;
@@ -15,7 +16,7 @@ import java.util.List;
 public interface ITaskService extends BaseService<Task> {
 	boolean submit(Task task);
 
-	IPage<Task> projectTaskPage(Long projectId, IPage<Task> page);
+	IPage<Task> projectTaskPage(ProjectTaskPageDTO dto, IPage<Task> page);
 
 	boolean uploadFile(Long taskId, String ids);
 
@@ -25,9 +26,15 @@ public interface ITaskService extends BaseService<Task> {
 
 	IPage<Task> myTaskPage(Integer type, Integer isGroup, Integer year, Integer month, IPage<Task> page);
 
-	MyTaskStatistics myTaskStatistics(Integer year, Integer month);
+	/**
+	 * 复用  复用
+	 */
+	MyTaskStatistics TaskStatistics(Long projectId, Integer year, Integer month);
+
 
 	List<Task> listByUser(Long userId, Integer year, Integer month);
 
 	boolean deleteTask(List<Long> taskIds);
+
+	List<Task> listByProjectId(Long projectId);
 }

+ 7 - 4
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/AsyncServiceImpl.java

@@ -100,6 +100,7 @@ public class AsyncServiceImpl implements IAsyncService {
 	}
 
 	@Override
+	@Async("asyncPoolTaskExecutor")
 	public void createTaskLog(Task task) {
 		//1.任务日志
 		Long createUser = task.getCreateUser();
@@ -128,7 +129,7 @@ public class AsyncServiceImpl implements IAsyncService {
 						taskLog.setUpdateUser(task.getUpdateUser());
 						taskLog.setCreateTime(DateUtil.now());
 						taskLog.setUpdateTime(DateUtil.now());
-						logs.add(log);
+						logs.add(taskLog);
 					}
 				}
 				if (task.getExecuteDept() != null) {
@@ -143,7 +144,7 @@ public class AsyncServiceImpl implements IAsyncService {
 						taskLog.setUpdateUser(task.getUpdateUser());
 						taskLog.setCreateTime(DateUtil.now());
 						taskLog.setUpdateTime(DateUtil.now());
-						logs.add(log);
+						logs.add(taskLog);
 					}
 				}
 				if (task.getProjectManager() != null) {
@@ -158,7 +159,7 @@ public class AsyncServiceImpl implements IAsyncService {
 						taskLog.setUpdateUser(task.getUpdateUser());
 						taskLog.setCreateTime(DateUtil.now());
 						taskLog.setUpdateTime(DateUtil.now());
-						logs.add(log);
+						logs.add(taskLog);
 					}
 				}
 				if (task.getExecuteUser() != null) {
@@ -179,7 +180,7 @@ public class AsyncServiceImpl implements IAsyncService {
 						taskLog.setUpdateUser(task.getUpdateUser());
 						taskLog.setCreateTime(DateUtil.now());
 						taskLog.setUpdateTime(DateUtil.now());
-						logs.add(log);
+						logs.add(taskLog);
 					}
 				}
 				taskLogService.saveBatch(logs);
@@ -189,6 +190,7 @@ public class AsyncServiceImpl implements IAsyncService {
 	}
 
 	@Override
+	@Async("asyncPoolTaskExecutor")
 	public void updateTask(Integer type, Long userId, Task task) {
 		R<User> userR = userClient.userInfoById(userId);
 		if (userR.isSuccess()) {
@@ -267,6 +269,7 @@ public class AsyncServiceImpl implements IAsyncService {
 	}
 
 	@Override
+	@Async("asyncPoolTaskExecutor")
 	public void submitTaskMessage(Long userId, Task task) {
 		Long createUser = task.getCreateUser();
 		Long projectId = task.getProjectId();

+ 53 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ContactsServiceImpl.java

@@ -0,0 +1,53 @@
+package com.wtkj.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.wtkj.entity.Contacts;
+import com.wtkj.mapper.ContactsMapper;
+import com.wtkj.service.IContactsService;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.system.feign.ISysClient;
+import org.springblade.system.vo.DeptVO;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 11:04
+ * @describe
+ */
+@Service
+@AllArgsConstructor
+public class ContactsServiceImpl extends BaseServiceImpl<ContactsMapper, Contacts> implements IContactsService {
+
+	private final ISysClient sysClient;
+
+	@Override
+	public IPage<Contacts> pageByTopDept(Long topDept, IPage<Contacts> page) {
+		return page.setRecords(baseMapper.pageByTopDept(topDept, page));
+	}
+
+	@Override
+	public IPage<DeptVO> deptPage(Long topDept, Query query) {
+		IPage<DeptVO> page = new Page<>();
+		List<Contacts> contacts = baseMapper.selectByTopDept(topDept);
+		if (!CollectionUtils.isEmpty(contacts)) {
+			Set<Long> collect = contacts.stream().map(Contacts::getRelatedTopDept).filter(Objects::nonNull).collect(Collectors.toSet());
+			String ids = Func.join(collect);
+			R<IPage<DeptVO>> rpc = sysClient.getDeptPage(ids, query);
+			if (rpc.isSuccess()) {
+				page = rpc.getData();
+			}
+		}
+		return page;
+	}
+}

+ 45 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ProjectGroupServiceImpl.java

@@ -0,0 +1,45 @@
+package com.wtkj.service.impl;
+
+import com.wtkj.entity.ProjectGroup;
+import com.wtkj.mapper.ProjectGroupMapper;
+import com.wtkj.service.IProjectGroupService;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.tool.utils.CollectionUtil;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 21:31
+ * @describe
+ */
+@AllArgsConstructor
+@Service
+public class ProjectGroupServiceImpl extends BaseServiceImpl<ProjectGroupMapper, ProjectGroup> implements IProjectGroupService {
+	@Override
+	public List<ProjectGroup> getGroupByProjectId(Long projectId, Long competentUnit) {
+		List<ProjectGroup> res = new ArrayList<>();
+		List<ProjectGroup> list = baseMapper.selectGroupByProjectId(projectId, competentUnit);
+		//机构去重
+		if (!CollectionUtil.isEmpty(list)) {
+			res = list.stream().collect(
+				Collectors.collectingAndThen(
+					Collectors.toCollection(
+						() -> new TreeSet<>(Comparator.comparing(ProjectGroup::getBeInvitedDept))
+					), ArrayList::new)
+			);
+		}
+		return res;
+	}
+
+	@Override
+	public List<ProjectGroup> getUserByBeInvitedDept(Long projectId, Long beInvitedDept) {
+		return baseMapper.selectUserByBeInvitedDept(projectId, beInvitedDept);
+	}
+}

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

@@ -0,0 +1,95 @@
+package com.wtkj.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.wtkj.entity.ProjectAuth;
+import com.wtkj.entity.ProjectGroup;
+import com.wtkj.service.IProjectAuthService;
+import com.wtkj.service.IProjectGroupService;
+import com.wtkj.service.IQrcodeService;
+import lombok.AllArgsConstructor;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.redis.cache.BladeRedis;
+import org.springblade.core.tool.api.R;
+import org.springblade.system.user.feign.IUserClient;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.Duration;
+
+import static com.wtkj.config.NacosConfigValue.expireIn;
+import static com.wtkj.config.NacosConfigValue.scanCount;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 17:35
+ * @describe
+ */
+@AllArgsConstructor
+@Service
+public class QrcodeServiceImpl implements IQrcodeService {
+
+	private final BladeRedis redis;
+	private final IUserClient userClient;
+	private final IProjectAuthService projectAuthService;
+	private final IProjectGroupService projectGroupService;
+
+	@Override
+	public String createQrcode() {
+		String kv = IdWorker.getIdStr();
+		redis.setEx(kv, 0, Duration.ofSeconds(expireIn));
+		return kv;
+	}
+
+	@Override
+	public boolean inviteToDept(String qrcodeId, Long userId, Long deptId) {
+		boolean flag = false;
+		boolean exist = isExist(qrcodeId);
+		//二维码可用前提下
+		if (exist) {
+			R<Boolean> rpc = userClient.bindUser(userId, deptId);
+			if (rpc.isSuccess()) {
+				flag = rpc.getData();
+			}
+		}
+		return flag;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public boolean inviteToProject(String qrcodeId, Long ownerDept, Long deptId, Long projectId) {
+		boolean flag = false;
+		boolean exist = isExist(qrcodeId);
+		if (exist) {
+			//1.权限 2.项目组
+			ProjectAuth auth = new ProjectAuth();
+			auth.setProjectId(projectId);
+			auth.setTopDept(deptId);
+			projectAuthService.save(auth);
+
+			ProjectGroup group = new ProjectGroup();
+			group.setProjectId(projectId);
+			group.setInviteDept(ownerDept);
+			group.setBeInvitedDept(deptId);
+			flag = projectGroupService.save(group);
+		}
+		return flag;
+	}
+
+	/**
+	 * 判断二维码是否有效和是否达到扫描上限
+	 */
+	private boolean isExist(String key) {
+		boolean flag = false;
+		Boolean exists = redis.exists(key);
+		//如果存在
+		if (exists) {
+			Long count = redis.incrBy(key, 1);
+			if (count > scanCount) {
+				throw new ServiceException("二维码只能扫描" + scanCount + "次数");
+			} else {
+				flag = true;
+			}
+		}
+		return flag;
+	}
+}

+ 31 - 5
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/TaskServiceImpl.java

@@ -2,6 +2,7 @@ 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;
@@ -77,9 +78,18 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	}
 
 	@Override
-	public IPage<Task> projectTaskPage(Long projectId, IPage<Task> page) {
+	public IPage<Task> projectTaskPage(ProjectTaskPageDTO dto, IPage<Task> page) {
 		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
-		lqw.eq(Task::getProjectId, projectId);
+		lqw.eq(Task::getProjectId, dto.getProjectId());
+		if (dto.getName() != null) {
+			lqw.like(Task::getTitle, dto.getName());
+		}
+		if (dto.getOrgDeptId() != null) {
+			lqw.eq(Task::getOrgDeptId, dto.getOrgDeptId());
+		}
+		if (dto.getTaskStatus() != null) {
+			lqw.eq(Task::getTaskStatus, dto.getTaskStatus());
+		}
 		lqw.orderByAsc(Task::getTaskStatus);
 		return baseMapper.selectPage(page, lqw);
 	}
@@ -174,10 +184,17 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	}
 
 	@Override
-	public MyTaskStatistics myTaskStatistics(Integer year, Integer month) {
+	public MyTaskStatistics TaskStatistics(Long projectId, Integer year, Integer month) {
 		MyTaskStatistics statistics = new MyTaskStatistics();
 		Long userId = AuthUtil.getUserId();
-		List<Task> tasks = this.listByUser(userId, year, month);
+		List<Task> tasks = null;
+		if (projectId == null) {
+			//个人任务统计
+			tasks = this.listByUser(userId, year, month);
+		} else {
+			//项目下的所有任务
+			tasks = this.listByProjectId(projectId);
+		}
 		if (!CollectionUtils.isEmpty(tasks)) {
 			//全部任务数
 			statistics.setAll(tasks.size());
@@ -222,6 +239,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 		return statistics;
 	}
 
+
 	@Override
 	public List<Task> listByUser(Long userId, Integer year, Integer month) {
 		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
@@ -235,7 +253,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 			wq.eq(Task::getCreateUser, userId);
 			wq.or().like(Task::getExecuteUser, String.valueOf(userId));
 		});
-		lqw.orderByDesc(Task::getCreateTime);
+		lqw.orderByAsc(Task::getEndTime);
 		return this.list(lqw);
 	}
 
@@ -244,4 +262,12 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	public boolean deleteTask(List<Long> taskIds) {
 		return false;
 	}
+
+	@Override
+	public List<Task> listByProjectId(Long projectId) {
+		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
+		lqw.eq(Task::getProjectId, projectId);
+		lqw.orderByAsc(Task::getEndTime);
+		return this.list(lqw);
+	}
 }

+ 1 - 0
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/FileAndFolderWrapper.java

@@ -72,6 +72,7 @@ public class FileAndFolderWrapper extends BaseEntityWrapper<FileAndFolder, FileA
 			if (rpc.isSuccess()) {
 				vo.setVolume(rpc.getData().getVolume());
 				vo.setUrl(rpc.getData().getFilePath());
+				vo.setSuffix(rpc.getData().getSuffix());
 			}
 			//文件阅读人
 			List<Long> userIds = fileReadService.getReadUser(vo.getId());

+ 68 - 0
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ProjectGroupWrapper.java

@@ -0,0 +1,68 @@
+package com.wtkj.wrapper;
+
+import com.wtkj.entity.ProjectGroup;
+import com.wtkj.service.IProjectGroupService;
+import com.wtkj.vo.ProjectGroupVO;
+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.SpringUtil;
+import org.springblade.system.entity.Dept;
+import org.springblade.system.feign.ISysClient;
+import org.springblade.system.user.entity.User;
+import org.springblade.system.user.feign.IUserClient;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-20 09:29
+ * @describe
+ */
+public class ProjectGroupWrapper extends BaseEntityWrapper<ProjectGroup, ProjectGroupVO> {
+
+	private static ISysClient sysClient;
+
+	private static IUserClient userClient;
+
+	private static IProjectGroupService projectGroupService;
+
+	public static ProjectGroupWrapper build() {
+		sysClient = SpringUtil.getBean(ISysClient.class);
+		userClient = SpringUtil.getBean(IUserClient.class);
+		projectGroupService = SpringUtil.getBean(IProjectGroupService.class);
+		return new ProjectGroupWrapper();
+	}
+
+	@Override
+	public ProjectGroupVO entityVO(ProjectGroup entity) {
+		ProjectGroupVO vo = Objects.requireNonNull(BeanUtil.copy(entity, ProjectGroupVO.class));
+		Long projectId = entity.getProjectId();
+		//机构名称
+		Long beInvitedDept = entity.getBeInvitedDept();
+		R<Dept> dept = sysClient.getDept(beInvitedDept);
+		if (dept.isSuccess()) {
+			vo.setDeptName(dept.getData().getDeptName());
+		}
+		//机构下的用户
+		List<ProjectGroup> groups = projectGroupService.getUserByBeInvitedDept(projectId, beInvitedDept);
+		if (!CollectionUtils.isEmpty(groups)) {
+			Set<Long> userIds = groups.stream().map(ProjectGroup::getUserId).collect(Collectors.toSet());
+			List<User> users = new ArrayList<>();
+			userIds.forEach(userId -> {
+				R<User> rpc = userClient.userInfoById(userId);
+				if (rpc.isSuccess()) {
+					users.add(rpc.getData());
+				}
+			});
+			vo.setSize(users.size());
+			vo.setUsers(users);
+		}
+		return vo;
+	}
+}

+ 12 - 3
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/TaskWrapper.java

@@ -1,10 +1,11 @@
 package com.wtkj.wrapper;
 
 import com.wtkj.entity.FileAndFolder;
+import com.wtkj.entity.Project;
 import com.wtkj.entity.Task;
 import com.wtkj.service.IFileAndFolderService;
+import com.wtkj.service.IProjectService;
 import com.wtkj.vo.TaskVO;
-import com.wutong.file.feign.IFileClient;
 import org.springblade.core.mp.support.BaseEntityWrapper;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
@@ -31,23 +32,31 @@ public class TaskWrapper extends BaseEntityWrapper<Task, TaskVO> {
 
 	private static IUserClient userClient;
 	private static ISysClient sysClient;
-	private static IFileClient fileClient;
 	private static IFileAndFolderService fileAndFolderService;
 	private static IDictBizClient dictBizClient;
 
+	private static IProjectService projectService;
+
 
 	public static TaskWrapper build() {
 		userClient = SpringUtil.getBean(IUserClient.class);
 		sysClient = SpringUtil.getBean(ISysClient.class);
-		fileClient = SpringUtil.getBean(IFileClient.class);
 		fileAndFolderService = SpringUtil.getBean(IFileAndFolderService.class);
 		dictBizClient = SpringUtil.getBean(IDictBizClient.class);
+		projectService = SpringUtil.getBean(IProjectService.class);
 		return new TaskWrapper();
 	}
 
 	@Override
 	public TaskVO entityVO(Task entity) {
 		TaskVO vo = Objects.requireNonNull(BeanUtil.copy(entity, TaskVO.class));
+		Long projectId = entity.getProjectId();
+		if (projectId != null) {
+			Project byId = projectService.getById(projectId);
+			if (byId != null) {
+				vo.setProjectName(byId.getName());
+			}
+		}
 		//联系人
 		Long projectManager = vo.getProjectManager();
 		if (projectManager != null) {