Prechádzať zdrojové kódy

feat: contact and invite

Blizzard 1 rok pred
rodič
commit
369ffeec84
23 zmenil súbory, kde vykonal 326 pridanie a 160 odobranie
  1. 33 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/dto/InviteToDeptDTO.java
  2. 1 1
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/Announcement.java
  3. 15 13
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/ContactOuter.java
  4. 20 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/ContactOuterUserVO.java
  5. 19 0
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/ContactOuterVO.java
  6. 5 5
      blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/ProjectStatisticsVO.java
  7. 20 25
      blade-service/wt-okr/src/main/java/com/wtkj/controller/ContactController.java
  8. 6 7
      blade-service/wt-okr/src/main/java/com/wtkj/controller/QrCodeController.java
  9. 0 19
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactDeptMapper.java
  10. 0 13
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactDeptMapper.xml
  11. 22 0
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactOuterMapper.java
  12. 22 0
      blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactOuterMapper.xml
  13. 0 17
      blade-service/wt-okr/src/main/java/com/wtkj/service/IContactDeptService.java
  14. 18 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/IContactOuterService.java
  15. 4 2
      blade-service/wt-okr/src/main/java/com/wtkj/service/IQrcodeService.java
  16. 1 1
      blade-service/wt-okr/src/main/java/com/wtkj/service/ITaskService.java
  17. 0 49
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ContactDeptServiceImpl.java
  18. 29 0
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ContactOuterServiceImpl.java
  19. 1 1
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ProjectServiceImpl.java
  20. 24 3
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/QrcodeServiceImpl.java
  21. 6 4
      blade-service/wt-okr/src/main/java/com/wtkj/service/impl/TaskServiceImpl.java
  22. 40 0
      blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ContactOuterUserWrapper.java
  23. 40 0
      blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ContactOuterWrapper.java

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

@@ -0,0 +1,33 @@
+package com.wtkj.dto;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-25 15:47
+ * @describe
+ */
+@Data
+public class InviteToDeptDTO implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	@JsonSerialize(using = ToStringSerializer.class)
+	@NotNull(message = "createUser can't be null")
+	private Long createUser;
+
+	@NotNull(message = "qrcodeId can't be null")
+	private String qrcodeId;
+
+	@NotNull(message = "type can't be null")
+	private Integer type;
+
+	@NotNull(message = "deptId can't be null")
+	private Long deptId;
+
+}

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

@@ -76,7 +76,7 @@ public class Announcement extends BaseEntity {
 	/**
 	 * 撤销时间
 	 */
-	@TableField("cancelTime")
+	@TableField("cancel_time")
 	private LocalDateTime cancelTime;
 	/**
 	 * 打开方式(组件:component 路由:url)

+ 15 - 13
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/ContactDept.java → blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/ContactOuter.java

@@ -15,29 +15,31 @@ import org.springblade.core.mp.base.BaseEntity;
  * @describe
  */
 @EqualsAndHashCode(callSuper = true)
-@TableName("blade_contacts")
+@TableName("blade_contacts_outer")
 @Data
-public class ContactDept extends BaseEntity {
+public class ContactOuter extends BaseEntity {
 
 	private static final long serialVersionUID = 1L;
 
 	@ApiModelProperty(value = "本机构顶级机构id")
-	@TableField("top_dept")
+	@TableField("top_dept_id")
 	@JsonSerialize(using = ToStringSerializer.class)
-	private Long topDept;
+	private Long topDeptId;
 
-	@ApiModelProperty(value = "联系人顶级机构id")
-	@TableField("related_top_dept")
+	@ApiModelProperty(value = "外部联系人联系人顶级机构id")
+	@TableField("related_dept_id")
 	@JsonSerialize(using = ToStringSerializer.class)
-	private Long relatedTopDept;
+	private Long relatedDeptId;
 
-	@ApiModelProperty(value = "联系人deptId")
-	@TableField("dept_id")
-	@JsonSerialize(using = ToStringSerializer.class)
-	private Long deptId;
 
-	@ApiModelProperty(value = "联系人deptId")
-	@TableField("dept_id")
+	@ApiModelProperty(value = "邀请人")
+	@TableField("user_id")
 	@JsonSerialize(using = ToStringSerializer.class)
 	private Long userId;
+
+
+	@ApiModelProperty(value = "联系人")
+	@TableField("related_user_id")
+	@JsonSerialize(using = ToStringSerializer.class)
+	private Long relatedUserId;
 }

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

@@ -0,0 +1,20 @@
+package com.wtkj.vo;
+
+import com.wtkj.entity.ContactOuter;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.system.user.entity.User;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-25 15:28
+ * @describe
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ContactOuterUserVO extends ContactOuter {
+
+	private static final long serialVersionUID = 1L;
+
+	private User user;
+}

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

@@ -0,0 +1,19 @@
+package com.wtkj.vo;
+
+import com.wtkj.entity.ContactOuter;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-25 15:07
+ * @describe
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ContactOuterVO extends ContactOuter {
+
+	private static final long serialVersionUID = 1L;
+
+	private String deptName;
+}

+ 5 - 5
blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/ProjectStatisticsVO.java

@@ -15,13 +15,13 @@ public class ProjectStatisticsVO implements Serializable {
 
 	private static final long serialVersionUID = 1L;
 
-	private Integer projectCount;
+	private Integer projectCount = 0;
 
-	private BigDecimal totalAmount;
+	private BigDecimal totalAmount = BigDecimal.valueOf(0);
 
-	private BigDecimal contractAmount;
+	private BigDecimal contractAmount = BigDecimal.valueOf(0);
 
-	private Integer todoTask;
+	private Integer todoTask = 0;
 
-	private Integer warns;
+	private Integer warns = 0;
 }

+ 20 - 25
blade-service/wt-okr/src/main/java/com/wtkj/controller/ContactController.java

@@ -2,22 +2,22 @@ package com.wtkj.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import com.wtkj.service.IContactDeptService;
+import com.wtkj.entity.ContactOuter;
+import com.wtkj.service.IContactOuterService;
+import com.wtkj.wrapper.ContactOuterUserWrapper;
+import com.wtkj.wrapper.ContactOuterWrapper;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
-import org.springblade.system.feign.ISysClient;
-import org.springblade.system.vo.DeptVO;
 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;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * @author Blizzard
  * @create at 2023-09-20 11:58
@@ -29,34 +29,29 @@ import java.util.List;
 @Api(value = "联系人模块", tags = "联系人模块")
 public class ContactController {
 
-	private final ISysClient sysClient;
-	private final IContactDeptService contactsService;
+	private final IContactOuterService contactOuterService;
+
 
 	/**
-	 * 本机构下的机构
+	 * 外部联系人
 	 */
-	@GetMapping("/dept-by-parentId")
-	@ApiOperation(value = "内部通讯录or懒加载树形结构", notes = "传入上级机构id")
+	@GetMapping("/outer-dept")
+	@ApiOperation(value = "外部联系人机构分页", notes = "传入分页参数")
 	@ApiOperationSupport(order = 1)
-	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(res);
+	public R address(Query query) {
+		IPage<ContactOuter> page = contactOuterService.selectPage(AuthUtil.getUserId(), Condition.getPage(query));
+		return R.data(ContactOuterWrapper.build().pageVO(page));
 	}
 
-
 	/**
-	 * 外部联系人
+	 * 外部联系人分页
 	 */
-	@GetMapping("/outer-dept")
-	@ApiOperation(value = "外部联系人", notes = "传入登录用户的topDept,分页参数")
+	@GetMapping("/outer-contact")
+	@ApiOperation(value = "外部联系人分页", notes = "传入deptId 分页参数")
 	@ApiOperationSupport(order = 2)
-	public R address(@RequestParam Long topDept, Query query) {
-		IPage<DeptVO> page = contactsService.deptPage(topDept, query);
-		return R.data(page);
+	public R contactPage(@RequestParam Long deptId, Query query) {
+		IPage<ContactOuter> page = contactOuterService.contactPage(deptId, AuthUtil.getUserId(), Condition.getPage(query));
+		return R.data(ContactOuterUserWrapper.build().pageVO(page));
 	}
 
 

+ 6 - 7
blade-service/wt-okr/src/main/java/com/wtkj/controller/QrCodeController.java

@@ -1,15 +1,14 @@
 package com.wtkj.controller;
 
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.wtkj.dto.InviteToDeptDTO;
 import com.wtkj.service.IQrcodeService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.springblade.core.secure.utils.AuthUtil;
 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;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * @author Blizzard
@@ -38,10 +37,10 @@ public class QrCodeController {
 	 * 邀请至机构下
 	 */
 	@GetMapping("/invite-to-dept")
-	@ApiOperation(value = "接受邀请至机构下", notes = "")
+	@ApiOperation(value = "接受邀请至机构下", notes = "type:1 邀请内部联系人 2:外部联系人")
 	@ApiOperationSupport(order = 2)
-	public R inviteToDept(@RequestParam String qrcodeId, @RequestParam Long userId, @RequestParam Long deptId) {
-		return R.status(qrcodeService.inviteToDept(qrcodeId, userId, deptId));
+	public R inviteToDept(@RequestBody InviteToDeptDTO dto) {
+		return R.status(qrcodeService.inviteToDept(dto.getCreateUser(), dto.getType(), dto.getQrcodeId(), AuthUtil.getUserId(), dto.getDeptId()));
 	}
 
 	/**

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

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

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

@@ -1,13 +0,0 @@
-<?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.ContactDeptMapper">
-
-
-    <select id="pageByTopDept" resultType="com.wtkj.entity.ContactDept">
-        select * from blade_contacts where is_deleted = 0 and top_dept = #{param}
-    </select>
-
-    <select id="selectByTopDept" resultType="com.wtkj.entity.ContactDept">
-        select * from blade_contacts where is_deleted = 0 and top_dept = #{param}
-    </select>
-</mapper>

+ 22 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/ContactOuterMapper.java

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

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

@@ -0,0 +1,22 @@
+<?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.ContactOuterMapper">
+
+
+    <select id="pageByTopDept" resultType="com.wtkj.entity.ContactOuter">
+        select * from blade_contacts_outer where is_deleted = 0 and top_dept = #{param}
+    </select>
+
+    <select id="selectByTopDept" resultType="com.wtkj.entity.ContactOuter">
+        select * from blade_contacts_outer where is_deleted = 0 and top_dept = #{param}
+    </select>
+
+    <select id="getPage" resultType="com.wtkj.entity.ContactOuter">
+        select * from blade_contacts_outer where is_deleted = 0 and user_id = #{param1} group by related_dept_id
+    </select>
+
+    <select id="getUserPage" resultType="com.wtkj.entity.ContactOuter">
+        select * from blade_contacts_outer where is_deleted = 0 and related_dept_id = #{param1} and user_id = #{param2}
+        group by related_user_id
+    </select>
+</mapper>

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

@@ -1,17 +0,0 @@
-package com.wtkj.service;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.wtkj.entity.ContactDept;
-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 IContactDeptService extends BaseService<ContactDept> {
-
-	IPage<DeptVO> deptPage(Long topDept, Query query);
-}

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

@@ -0,0 +1,18 @@
+package com.wtkj.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.entity.ContactOuter;
+import org.springblade.core.mp.base.BaseService;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 11:01
+ * @describe
+ */
+public interface IContactOuterService extends BaseService<ContactOuter> {
+
+	IPage<ContactOuter> selectPage(Long userId, IPage<ContactOuter> page);
+
+	IPage<ContactOuter> contactPage(Long deptId, Long userId, IPage<ContactOuter> page);
+}
+

+ 4 - 2
blade-service/wt-okr/src/main/java/com/wtkj/service/IQrcodeService.java

@@ -1,5 +1,7 @@
 package com.wtkj.service;
 
+import com.alibaba.fastjson.JSONObject;
+
 /**
  * @author Blizzard
  * @create at 2023-09-19 17:35
@@ -8,9 +10,9 @@ package com.wtkj.service;
 public interface IQrcodeService {
 
 
-	String createQrcode();
+	JSONObject createQrcode();
 
-	boolean inviteToDept(String qrcodeId, Long userId, Long deptId);
+	boolean inviteToDept(Long createUser, Integer type, String qrcodeId, Long userId, Long deptId);
 
 	boolean inviteToProject(String qrcodeId, Long ownerDept, Long deptId, Long projectId);
 }

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

@@ -76,7 +76,7 @@ public interface ITaskService extends BaseService<Task> {
 	/**
 	 * 项目任务饼图
 	 */
-	List<Map<String, Integer>> projectTaskSummary(Long projectId);
+	List<Map<String, String>> projectTaskSummary(Long projectId);
 
 	/**
 	 * 项目和项目执行人

+ 0 - 49
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ContactDeptServiceImpl.java

@@ -1,49 +0,0 @@
-package com.wtkj.service.impl;
-
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.wtkj.entity.ContactDept;
-import com.wtkj.mapper.ContactDeptMapper;
-import com.wtkj.service.IContactDeptService;
-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 ContactDeptServiceImpl extends BaseServiceImpl<ContactDeptMapper, ContactDept> implements IContactDeptService {
-
-	private final ISysClient sysClient;
-
-
-	@Override
-	public IPage<DeptVO> deptPage(Long topDept, Query query) {
-		IPage<DeptVO> page = new Page<>();
-		List<ContactDept> contacts = baseMapper.selectByTopDept(topDept);
-		if (!CollectionUtils.isEmpty(contacts)) {
-			Set<Long> collect = contacts.stream().map(ContactDept::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;
-	}
-}

+ 29 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/ContactOuterServiceImpl.java

@@ -0,0 +1,29 @@
+package com.wtkj.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.entity.ContactOuter;
+import com.wtkj.mapper.ContactOuterMapper;
+import com.wtkj.service.IContactOuterService;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-19 11:04
+ * @describe
+ */
+@Service
+@AllArgsConstructor
+public class ContactOuterServiceImpl extends BaseServiceImpl<ContactOuterMapper, ContactOuter> implements IContactOuterService {
+
+	@Override
+	public IPage<ContactOuter> selectPage(Long userId, IPage<ContactOuter> page) {
+		return page.setRecords(baseMapper.getPage(userId, page));
+	}
+
+	@Override
+	public IPage<ContactOuter> contactPage(Long deptId, Long userId, IPage<ContactOuter> page) {
+		return page.setRecords(baseMapper.getUserPage(deptId, userId, page));
+	}
+}

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

@@ -238,7 +238,7 @@ public class ProjectServiceImpl extends BaseServiceImpl<ProjectMapper, Project>
 							vo.setContractAmount(reduce);
 						}
 						//待完成任务数量
-						Set<Task> collect = tasks.stream().filter(f -> f.getYear().equals(Integer.valueOf(year)) && f.getIsConfirmed() == 0).collect(Collectors.toSet());
+						Set<Task> collect = tasks.stream().filter(f -> f.getYear() != null && f.getYear().equals(Integer.valueOf(year)) && f.getIsConfirmed() == 0).collect(Collectors.toSet());
 						if (!CollectionUtils.isEmpty(collect)) {
 							vo.setTodoTask(collect.size());
 						}

+ 24 - 3
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/QrcodeServiceImpl.java

@@ -1,14 +1,19 @@
 package com.wtkj.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.wtkj.entity.ContactOuter;
 import com.wtkj.entity.ProjectAuth;
 import com.wtkj.entity.ProjectGroup;
+import com.wtkj.service.IContactOuterService;
 import com.wtkj.service.IProjectAuthService;
 import com.wtkj.service.IProjectGroupService;
 import com.wtkj.service.IQrcodeService;
+import io.seata.spring.annotation.GlobalTransactional;
 import lombok.AllArgsConstructor;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.redis.cache.BladeRedis;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.system.user.feign.IUserClient;
 import org.springframework.stereotype.Service;
@@ -32,24 +37,40 @@ public class QrcodeServiceImpl implements IQrcodeService {
 	private final IUserClient userClient;
 	private final IProjectAuthService projectAuthService;
 	private final IProjectGroupService projectGroupService;
+	private final IContactOuterService contactOuterService;
 
 	@Override
-	public String createQrcode() {
+	public JSONObject createQrcode() {
+		JSONObject res = new JSONObject();
 		String kv = IdWorker.getIdStr();
+		Long userId = AuthUtil.getUserId();
 		redis.setEx(kv, 0, Duration.ofSeconds(expireIn));
-		return kv;
+		res.put("qrcodeId", kv);
+		res.put("createUser", userId);
+		return res;
 	}
 
 	@Override
-	public boolean inviteToDept(String qrcodeId, Long userId, Long deptId) {
+	@GlobalTransactional(rollbackFor = Exception.class)
+	public boolean inviteToDept(Long createUser, Integer type, String qrcodeId, Long userId, Long deptId) {
 		boolean flag = false;
 		boolean exist = isExist(qrcodeId);
 		//二维码可用前提下
 		if (exist) {
+			//1.绑定机构
 			R<Boolean> rpc = userClient.bindUser(userId, deptId);
+			//2.保存外部联系人
 			if (rpc.isSuccess()) {
 				flag = rpc.getData();
 			}
+			if (type == 2) {
+				ContactOuter contact = new ContactOuter();
+				contact.setRelatedDeptId(deptId);
+				contact.setRelatedUserId(userId);
+				contact.setUserId(createUser);
+				contactOuterService.save(contact);
+			}
+
 		}
 		return flag;
 	}

+ 6 - 4
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/TaskServiceImpl.java

@@ -321,8 +321,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 	}
 
 	@Override
-	public List<Map<String, Integer>> projectTaskSummary(Long projectId) {
-		List<Map<String, Integer>> res = new ArrayList<>();
+	public List<Map<String, String>> projectTaskSummary(Long projectId) {
+		List<Map<String, String>> res = new ArrayList<>();
 		//项目下任务执行者的情况
 		Set<Long> userIds = new HashSet<>();
 		List<Task> tasks = this.listByProjectId(projectId);
@@ -337,12 +337,14 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 		}
 		if (!CollectionUtils.isEmpty(userIds)) {
 			userIds.forEach(userId -> {
-				Map<String, Integer> map = new HashMap<>();
+				Map<String, String> map = new HashMap<>();
 				R<User> userR = userClient.userInfoById(userId);
 				if (userR.isSuccess()) {
 					List<Task> tasks1 = this.listByUserAndProject(userId, projectId);
 					if (!CollectionUtils.isEmpty(tasks1)) {
-						map.put(userR.getData().getName(), tasks1.size());
+						map.put("value", String.valueOf(tasks1.size()));
+						map.put("name", userR.getData().getName());
+						//map.put(userR.getData().getName(), tasks1.size());
 						res.add(map);
 					}
 				}

+ 40 - 0
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ContactOuterUserWrapper.java

@@ -0,0 +1,40 @@
+package com.wtkj.wrapper;
+
+import com.wtkj.entity.ContactOuter;
+import com.wtkj.vo.ContactOuterUserVO;
+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.user.entity.User;
+import org.springblade.system.user.feign.IUserClient;
+
+import java.util.Objects;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-25 15:29
+ * @describe
+ */
+public class ContactOuterUserWrapper extends BaseEntityWrapper<ContactOuter, ContactOuterUserVO> {
+
+	private static IUserClient userClient;
+
+	public static ContactOuterUserWrapper build() {
+		userClient = SpringUtil.getBean(IUserClient.class);
+		return new ContactOuterUserWrapper();
+	}
+
+	@Override
+	public ContactOuterUserVO entityVO(ContactOuter entity) {
+		ContactOuterUserVO vo = Objects.requireNonNull(BeanUtil.copy(entity, ContactOuterUserVO.class));
+		Long userId = entity.getRelatedUserId();
+		if (userId != null) {
+			R<User> userR = userClient.userInfoById(userId);
+			if (userR.isSuccess()) {
+				vo.setUser(userR.getData());
+			}
+		}
+		return vo;
+	}
+}

+ 40 - 0
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/ContactOuterWrapper.java

@@ -0,0 +1,40 @@
+package com.wtkj.wrapper;
+
+import com.wtkj.entity.ContactOuter;
+import com.wtkj.vo.ContactOuterVO;
+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 java.util.Objects;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-25 15:07
+ * @describe
+ */
+public class ContactOuterWrapper extends BaseEntityWrapper<ContactOuter, ContactOuterVO> {
+
+	private static ISysClient sysClient;
+
+	public static ContactOuterWrapper build() {
+		sysClient = SpringUtil.getBean(ISysClient.class);
+		return new ContactOuterWrapper();
+	}
+
+	@Override
+	public ContactOuterVO entityVO(ContactOuter entity) {
+		ContactOuterVO vo = Objects.requireNonNull(BeanUtil.copy(entity, ContactOuterVO.class));
+		Long deptId = entity.getRelatedDeptId();
+		if (deptId != null) {
+			R<Dept> deptR = sysClient.getDept(deptId);
+			if (deptR.isSuccess()) {
+				vo.setDeptName(deptR.getData().getDeptName());
+			}
+		}
+		return vo;
+	}
+}