From a6ff2403695943a840a6ea8a270542e9417cd9f1 Mon Sep 17 00:00:00 2001
From: misWCL <36293551+misTiger@users.noreply.github.com>
Date: Wed, 7 Aug 2024 11:42:24 +0800
Subject: [PATCH] Feature/server java (#374)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fix: 1. 去除jwt存储password关键信息;token创建逻辑同node,jwt信息实现node和java互通
2. 新增hash256方法,用户注册password加密逻辑同node,实现java端注册的账号登录和node版本互通
* add Workspace,WorkspaceMember,ConvertorConfig
* 删除获取获取jwt信息中的魔法值;处理空指针问题
* add error code
* 常量命名调整
* 1.新增mongodb事件拦截器 MongoEntityInterceptor
2.新增对象转换器 GeneralConvertor
3.新增空间Workspace接口
4.新增空间成员WorkspaceMember接口
* init application-dev.properties
* 删除Status的get set方法
* pom依赖管理
---
lombok.config | 4 +
pom.xml | 6 +
.../engine/common/entity/InitBaseEntity.java | 13 ++
.../engine/common/entity/Status.java | 16 --
.../common/entity/workspace/Workspace.java | 22 ++
.../entity/workspace/WorkspaceMember.java | 24 ++
.../engine/common/enums/RecordStatusEnum.java | 38 ++++
.../engine/common/enums/RoleEmum.java | 31 +++
survey-core/pom.xml | 4 +
.../engine/bean/ConvertorConfig.java | 18 ++
.../engine/bean/GeneralConvertor.java | 89 ++++++++
.../workspace/WorkspaceMemberService.java | 29 +++
.../core/workspace/WorkspaceService.java | 29 +++
.../impl/WorkspaceMemberServiceImpl.java | 84 +++++++
.../workspace/impl/WorkspaceServiceImpl.java | 205 ++++++++++++++++++
.../param/CreateWorkspaceMemberParam.java | 18 ++
.../core/workspace/param/MemberParam.java | 16 ++
.../core/workspace/param/WorkspaceParam.java | 29 +++
.../core/workspace/vo/WorkspaceInfoVO.java | 58 +++++
.../core/workspace/vo/WorkspaceListVO.java | 16 ++
.../workspace/vo/WorkspaceMemberIdVO.java | 15 ++
.../core/workspace/vo/WorkspaceMemberVO.java | 32 +++
.../engine/core/workspace/vo/WorkspaceVO.java | 17 ++
.../engine/repository/MongoRepository.java | 9 +
.../repository/impl/MongoRepositoryImpl.java | 5 +
.../repository/interceptor/MongoConfig.java | 20 ++
.../interceptor/MongoEntityInterceptor.java | 53 +++++
.../controller/WorkspaceController.java | 99 +++++++++
.../controller/WorkspaceMemberController.java | 59 +++++
.../controller/WorkspaceControllerTest.java | 127 +++++++++++
.../WorkspaceMemberControllerTest.java | 71 ++++++
31 files changed, 1240 insertions(+), 16 deletions(-)
create mode 100644 lombok.config
create mode 100644 survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/InitBaseEntity.java
create mode 100644 survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/Workspace.java
create mode 100644 survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/WorkspaceMember.java
create mode 100644 survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RecordStatusEnum.java
create mode 100644 survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RoleEmum.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/bean/ConvertorConfig.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/bean/GeneralConvertor.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceMemberService.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceService.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceMemberServiceImpl.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceServiceImpl.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/CreateWorkspaceMemberParam.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/MemberParam.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/WorkspaceParam.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceInfoVO.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceListVO.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberIdVO.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberVO.java
create mode 100644 survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceVO.java
create mode 100644 survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoConfig.java
create mode 100644 survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoEntityInterceptor.java
create mode 100644 survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceController.java
create mode 100644 survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceMemberController.java
create mode 100644 survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceControllerTest.java
create mode 100644 survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceMemberControllerTest.java
diff --git a/lombok.config b/lombok.config
new file mode 100644
index 00000000..c31ba6bc
--- /dev/null
+++ b/lombok.config
@@ -0,0 +1,4 @@
+lombok.accessors.chain=true
+lombok.equalsAndHashCode.doNotUseGetters=true
+lombok.toString.doNotUseGetters=true
+lombok.equalsAndHashCode.callSuper=SKIP
diff --git a/pom.xml b/pom.xml
index 9c93b1fd..c38fb1c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,6 +34,7 @@
3.14.0
1.2.83
4.4.0
+ 5.5.1
@@ -83,6 +84,11 @@
commons-lang3
${lang3.version}
+
+ net.sf.dozer
+ dozer
+ ${dozer.version}
+
diff --git a/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/InitBaseEntity.java b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/InitBaseEntity.java
new file mode 100644
index 00000000..cd646d5a
--- /dev/null
+++ b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/InitBaseEntity.java
@@ -0,0 +1,13 @@
+package com.xiaojusurvey.engine.common.entity;
+
+import lombok.Data;
+
+/**
+ * @description: InitBaseEntity
+ * @author: wangchenglong
+ * @time: 2024/7/31 17:12
+ */
+@Data
+public class InitBaseEntity extends BaseEntity {
+
+}
diff --git a/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/Status.java b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/Status.java
index aa5c332e..39fad896 100644
--- a/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/Status.java
+++ b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/Status.java
@@ -12,20 +12,4 @@ public class Status implements Serializable {
private String status;
-
- public Long getDate() {
- return date;
- }
-
- public void setDate(Long date) {
- this.date = date;
- }
-
- public String getStatus() {
- return status;
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
}
diff --git a/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/Workspace.java b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/Workspace.java
new file mode 100644
index 00000000..ebbe2755
--- /dev/null
+++ b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/Workspace.java
@@ -0,0 +1,22 @@
+package com.xiaojusurvey.engine.common.entity.workspace;
+
+import com.xiaojusurvey.engine.common.entity.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+/**
+ * @description: 空间
+ * @author: wangchenglong
+ * @time: 2024/7/24 10:50
+ */
+@Document("workspace")
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Data
+public class Workspace extends BaseEntity {
+ private String ownerId;
+ private String name;
+ private String description;
+}
diff --git a/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/WorkspaceMember.java b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/WorkspaceMember.java
new file mode 100644
index 00000000..a4b77653
--- /dev/null
+++ b/survey-common/src/main/java/com/xiaojusurvey/engine/common/entity/workspace/WorkspaceMember.java
@@ -0,0 +1,24 @@
+package com.xiaojusurvey.engine.common.entity.workspace;
+
+import com.xiaojusurvey.engine.common.entity.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+/**
+ * @description: 空间成员
+ * @author: wangchenglong
+ * @time: 2024/7/24 10:51
+ */
+@Document("workspaceMember")
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Data
+public class WorkspaceMember extends BaseEntity {
+ private String userId;
+
+ private String workspaceId;
+
+ private String role;
+}
diff --git a/survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RecordStatusEnum.java b/survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RecordStatusEnum.java
new file mode 100644
index 00000000..c9ce487a
--- /dev/null
+++ b/survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RecordStatusEnum.java
@@ -0,0 +1,38 @@
+package com.xiaojusurvey.engine.common.enums;
+
+/**
+ * @description: 状态类型
+ * @author: wangchenglong
+ * @time: 2024/7/30 16:08
+ */
+public enum RecordStatusEnum {
+
+ // 新建
+ NEW("new"),
+
+ // 编辑
+ EDITING("editing"),
+
+ // 暂停
+ PAUSING("pausing"),
+
+ // 发布
+ PUBLISHED("published"),
+
+ // 删除
+ REMOVED("removed"),
+
+ // 从回收站删除
+ FORCE_REMOVED("forceRemoved");
+
+ private final String statusType;
+
+ RecordStatusEnum(String statusType) {
+ this.statusType = statusType;
+ }
+
+ public String getStatusType() {
+ return this.statusType;
+ }
+
+}
diff --git a/survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RoleEmum.java b/survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RoleEmum.java
new file mode 100644
index 00000000..7d710d1c
--- /dev/null
+++ b/survey-common/src/main/java/com/xiaojusurvey/engine/common/enums/RoleEmum.java
@@ -0,0 +1,31 @@
+package com.xiaojusurvey.engine.common.enums;
+
+/**
+ * @description: 用户角色枚举
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:47
+ */
+public enum RoleEmum {
+
+ USER(0, "user"),
+
+ ADMIN(1, "admin");
+
+ private final Integer state;
+
+ private final String value;
+
+ RoleEmum(Integer state, String value) {
+ this.state = state;
+ this.value = value;
+ }
+
+ public Integer getState() {
+ return this.state;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+}
diff --git a/survey-core/pom.xml b/survey-core/pom.xml
index f565025c..7cee87af 100644
--- a/survey-core/pom.xml
+++ b/survey-core/pom.xml
@@ -34,6 +34,10 @@
spring-boot-starter-web
+ net.sf.dozer
+ dozer
+
+
org.springframework.boot
spring-boot-starter-test
test
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/bean/ConvertorConfig.java b/survey-core/src/main/java/com/xiaojusurvey/engine/bean/ConvertorConfig.java
new file mode 100644
index 00000000..be582f95
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/bean/ConvertorConfig.java
@@ -0,0 +1,18 @@
+package com.xiaojusurvey.engine.bean;
+
+import org.dozer.DozerBeanMapper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @description: net.sf.dozer
+ * @author: wangchenglong
+ * @time: 2024/7/24 22:25
+ */
+@Configuration
+public class ConvertorConfig {
+ @Bean
+ public DozerBeanMapper dozerBeanMapper() {
+ return new DozerBeanMapper();
+ }
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/bean/GeneralConvertor.java b/survey-core/src/main/java/com/xiaojusurvey/engine/bean/GeneralConvertor.java
new file mode 100644
index 00000000..2af53f6b
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/bean/GeneralConvertor.java
@@ -0,0 +1,89 @@
+package com.xiaojusurvey.engine.bean;
+
+
+import org.dozer.Mapper;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @description: 对象转换
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:23
+ */
+@Component
+public class GeneralConvertor {
+
+ @Resource
+ private Mapper mapper;
+
+ /**
+ * List 实体类 转换器
+ *
+ * @param source 原数据
+ * @param clz 转换类型
+ * @param
+ * @param
+ * @return
+ */
+ public List convertor(List source, Class clz) {
+ if (source == null) {
+ return null;
+ }
+ List map = new ArrayList<>();
+ for (S s : source) {
+ map.add(mapper.map(s, clz));
+ }
+ return map;
+ }
+
+
+ /**
+ * Set 实体类 深度转换器
+ *
+ * @param source 原数据
+ * @param clz 目标对象
+ * @param
+ * @param
+ * @return
+ */
+ public Set convertor(Set source, Class clz) {
+ if (source == null) {
+ return null;
+ }
+ Set set = new TreeSet<>();
+ for (S s : source) {
+ set.add(mapper.map(s, clz));
+ }
+ return set;
+ }
+
+ /**
+ * 实体类 深度转换器
+ *
+ * @param source
+ * @param clz
+ * @param
+ * @param
+ * @return
+ */
+ public T convertor(S source, Class clz) {
+ if (source == null) {
+ return null;
+ }
+ return mapper.map(source, clz);
+ }
+
+ public void convertor(Object source, Object object) {
+ mapper.map(source, object);
+ }
+
+ public void copyConvertor(T source, Object object) {
+ mapper.map(source, object);
+ }
+
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceMemberService.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceMemberService.java
new file mode 100644
index 00000000..65a9a452
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceMemberService.java
@@ -0,0 +1,29 @@
+package com.xiaojusurvey.engine.core.workspace;
+
+import com.xiaojusurvey.engine.common.entity.workspace.WorkspaceMember;
+import com.xiaojusurvey.engine.core.workspace.param.CreateWorkspaceMemberParam;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @description:
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:23
+ */
+public interface WorkspaceMemberService {
+
+ List getWorkspaceMembers(String workspaceId, List userId);
+
+ List getWorkspaceMembers(String userId, Integer pageSize, Integer curPage);
+
+ List getWorkspaceMembers(String workspaceId);
+
+ WorkspaceMember getWorkspaceMember(String workspaceId, String userId);
+
+ String create(CreateWorkspaceMemberParam createWorkspaceMemberParam);
+
+ void delete(CreateWorkspaceMemberParam workspaceMemberParam);
+
+ void updateRole(@RequestBody CreateWorkspaceMemberParam createWorkspaceMemberParam);
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceService.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceService.java
new file mode 100644
index 00000000..7279e455
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/WorkspaceService.java
@@ -0,0 +1,29 @@
+package com.xiaojusurvey.engine.core.workspace;
+
+import com.xiaojusurvey.engine.core.workspace.param.WorkspaceParam;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceListVO;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceMemberVO;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * @description:
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:23
+ */
+public interface WorkspaceService {
+
+ String createWorkspace(HttpServletRequest request, @RequestBody WorkspaceParam workspaceParam);
+
+ WorkspaceListVO findAll(HttpServletRequest request, Integer pageSize, Integer curPage, String name);
+
+ WorkspaceMemberVO getWorkspaceInfo(HttpServletRequest request, String workspaceId);
+
+ void update(HttpServletRequest request, @RequestBody WorkspaceParam workspaceParam, String workspaceId);
+
+ void delete(HttpServletRequest request, String workspaceId);
+
+ List findAllByUserId(HttpServletRequest request);
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceMemberServiceImpl.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceMemberServiceImpl.java
new file mode 100644
index 00000000..9787690c
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceMemberServiceImpl.java
@@ -0,0 +1,84 @@
+package com.xiaojusurvey.engine.core.workspace.impl;
+
+import com.xiaojusurvey.engine.bean.GeneralConvertor;
+import com.xiaojusurvey.engine.common.entity.workspace.WorkspaceMember;
+import com.xiaojusurvey.engine.common.enums.RecordStatusEnum;
+import com.xiaojusurvey.engine.core.workspace.WorkspaceMemberService;
+import com.xiaojusurvey.engine.core.workspace.param.CreateWorkspaceMemberParam;
+import com.xiaojusurvey.engine.repository.MongoRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * @description: 空间成员
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:23
+ */
+@Service
+public class WorkspaceMemberServiceImpl implements WorkspaceMemberService {
+
+ @Autowired
+ private MongoRepository mongoRepository;
+
+ @Autowired
+ private GeneralConvertor convertors;
+
+ @Override
+ public List getWorkspaceMembers(String workspaceId, List userId) {
+ return mongoRepository.findList(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceId))
+ .addCriteria(Criteria.where("userId").in(userId)), WorkspaceMember.class);
+ }
+
+ @Override
+ public WorkspaceMember getWorkspaceMember(String workspaceId, String userId) {
+ return mongoRepository.findOne(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceId))
+ .addCriteria(Criteria.where("userId").is(userId)), WorkspaceMember.class);
+ }
+
+ @Override
+ public String create(CreateWorkspaceMemberParam createWorkspaceMemberParam) {
+ WorkspaceMember workspaceMemberDto = convertors.convertor(createWorkspaceMemberParam, WorkspaceMember.class);
+ WorkspaceMember workspaceMember = mongoRepository.save(workspaceMemberDto);
+ return workspaceMember.getId();
+ }
+
+ /**
+ * 查询当前用户参与的空间
+ * @param userId
+ * @return
+ */
+ @Override
+ public List getWorkspaceMembers(String userId, Integer pageSize, Integer curPage) {
+ List workspaceMembers = mongoRepository.page(new Query().addCriteria(Criteria.where("userId").is(userId))
+ .addCriteria(Criteria.where("curStatus.status").ne(RecordStatusEnum.REMOVED.getStatusType()))
+ .with(Sort.by(Sort.Direction.ASC, "createDate")),
+ curPage, pageSize, WorkspaceMember.class);
+ return workspaceMembers;
+ }
+
+ @Override
+ public List getWorkspaceMembers(String workspaceId) {
+ return mongoRepository.findList(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceId))
+ .with(Sort.by(Sort.Direction.ASC, "createDate")), WorkspaceMember.class);
+ }
+
+ @Override
+ public void delete(CreateWorkspaceMemberParam workspaceMemberParam) {
+ mongoRepository.delete(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceMemberParam.getWorkspaceId()))
+ .addCriteria(Criteria.where("userId").is(workspaceMemberParam.getUserId())), WorkspaceMember.class);
+ }
+
+ @Override
+ public void updateRole(@RequestBody CreateWorkspaceMemberParam createWorkspaceMemberParam) {
+ mongoRepository.updateFirst(new Query().addCriteria(Criteria.where("workspaceId").is(createWorkspaceMemberParam.getWorkspaceId()))
+ .addCriteria(Criteria.where("_id").is(createWorkspaceMemberParam.getUserId())),
+ new Update().set("role", createWorkspaceMemberParam.getRole()), WorkspaceMember.class);
+ }
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceServiceImpl.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceServiceImpl.java
new file mode 100644
index 00000000..3f041b2c
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/impl/WorkspaceServiceImpl.java
@@ -0,0 +1,205 @@
+package com.xiaojusurvey.engine.core.workspace.impl;
+
+import com.xiaojusurvey.engine.bean.GeneralConvertor;
+import com.xiaojusurvey.engine.common.constants.RespErrorCode;
+import com.xiaojusurvey.engine.common.entity.InitBaseEntity;
+import com.xiaojusurvey.engine.common.entity.survey.SurveyMeta;
+import com.xiaojusurvey.engine.common.entity.user.User;
+import com.xiaojusurvey.engine.common.entity.workspace.Workspace;
+import com.xiaojusurvey.engine.common.entity.workspace.WorkspaceMember;
+import com.xiaojusurvey.engine.common.enums.RecordStatusEnum;
+import com.xiaojusurvey.engine.common.enums.RoleEmum;
+import com.xiaojusurvey.engine.common.exception.ServiceException;
+import com.xiaojusurvey.engine.core.reslut.IdResult;
+import com.xiaojusurvey.engine.core.workspace.WorkspaceMemberService;
+import com.xiaojusurvey.engine.core.workspace.WorkspaceService;
+import com.xiaojusurvey.engine.core.workspace.param.MemberParam;
+import com.xiaojusurvey.engine.core.workspace.param.WorkspaceParam;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceInfoVO;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceListVO;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceMemberVO;
+import com.xiaojusurvey.engine.repository.MongoRepository;
+import com.xiaojusurvey.engine.repository.interceptor.MongoEntityInterceptor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @description: 空间
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:23
+ */
+@Slf4j
+@Service
+public class WorkspaceServiceImpl implements WorkspaceService {
+
+ @Autowired
+ private MongoRepository mongoRepository;
+
+ @Autowired
+ private GeneralConvertor convertors;
+
+ @Autowired
+ private WorkspaceMemberService memberService;
+
+ @Autowired
+ private MongoEntityInterceptor mongoEntityInterceptor;
+
+ /**
+ * 创建空间
+ * @param request
+ * @param param
+ * @return
+ */
+ @Override
+ public String createWorkspace(HttpServletRequest request, WorkspaceParam param) {
+ Workspace workspace = this.convertors.convertor(param, Workspace.class);
+ User user = (User) request.getAttribute("user");
+ IdResult idResult = new IdResult();
+ idResult.setId(mongoRepository.save(workspace.setOwnerId(user.getId())).getId());
+ if (!CollectionUtils.isEmpty(param.getMembers())) {
+ // 不能重复添加用户
+ List userIds = param.getMembers().stream().map(MemberParam::getUserId).collect(Collectors.toList());
+ List workspaceMembers = memberService.getWorkspaceMembers(idResult.getId(), userIds);
+ if (!CollectionUtils.isEmpty(workspaceMembers)) {
+ throw new ServiceException("不能重复添加用户", RespErrorCode.PARAMETER_ERROR.getCode());
+ }
+ // 用户不存在
+ param.getMembers().stream().forEach(member -> {
+ User memberUser = mongoRepository.findOne(new Query().addCriteria(Criteria.where("_id").is(member.getUserId())), User.class);
+ if (ObjectUtils.isEmpty(memberUser)) {
+ throw new ServiceException("用户id:" + member.getUserId() + "不存在", RespErrorCode.USER_NOT_EXISTS.getCode());
+ }
+ });
+ List members = this.convertors.convertor(param.getMembers(), WorkspaceMember.class);
+ members = members.stream().map(member -> member.setWorkspaceId(idResult.getId())).collect(Collectors.toList());
+ members.add(new WorkspaceMember().setUserId(user.getId()).setWorkspaceId(idResult.getId()).setRole(RoleEmum.ADMIN.getValue()));
+ mongoRepository.batchSave(members, WorkspaceMember.class);
+ }
+ return idResult.getId();
+ }
+
+ /**
+ * 获取空间列表
+ * @param request
+ * @param pageSize
+ * @param curPage
+ * @param name
+ * @return
+ */
+ @Override
+ public WorkspaceListVO findAll(HttpServletRequest request, Integer pageSize, Integer curPage, String name) {
+ curPage -= 1;
+ User user = (User) request.getAttribute("user");
+ // 查询当前用户参与的空间
+ List workspaceMembers = memberService.getWorkspaceMembers(user.getId(), pageSize, curPage);
+ List workspaceInfos = new ArrayList<>();
+ workspaceMembers.stream().forEach(workspaceMember -> {
+ // 成员数量
+ Long count = mongoRepository.count(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceMember.getWorkspaceId())), WorkspaceMember.class);
+ Workspace workspace = mongoRepository.findOne(new Query().addCriteria(Criteria.where("_id").is(workspaceMember.getWorkspaceId())).addCriteria(Criteria.where("curStatus.status").ne(RecordStatusEnum.REMOVED.getStatusType())), Workspace.class);
+ // 问卷数量
+ Long surveyCount = mongoRepository.count(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceMember.getWorkspaceId())), SurveyMeta.class);
+ if (!ObjectUtils.isEmpty(workspace)) {
+ WorkspaceInfoVO convertor = this.convertors.convertor(workspace, WorkspaceInfoVO.class);
+ workspaceInfos.add(convertor.setCurrentUserId(user.getId())
+ .setCurrentUserRole(workspaceMembers.stream().filter(member -> member.getWorkspaceId().equals(workspaceMember.getWorkspaceId())).findFirst().get().getRole())
+ .setMemberTotal(count)
+ .setSurveyTotal(surveyCount)
+ .setOwner(workspace.getOwnerId().equals(user.getId()) ? user.getUsername() : mongoRepository.findOne(new Query().addCriteria(Criteria.where("_id").is(workspace.getOwnerId())), User.class).getUsername())
+ .setOwnerId(workspace.getOwnerId()));
+ }
+ });
+ return new WorkspaceListVO().setData(workspaceInfos).setCount(workspaceMembers.size());
+ }
+
+ @Override
+ public WorkspaceMemberVO getWorkspaceInfo(HttpServletRequest request, String workspaceId) {
+ User user = (User) request.getAttribute("user");
+ Workspace workspace = mongoRepository.findOne(new Query().addCriteria(Criteria.where("_id").is(workspaceId)), Workspace.class);
+ WorkspaceMemberVO workspaceMember = this.convertors.convertor(workspace, WorkspaceMemberVO.class);
+ List workspaceMembers = memberService.getWorkspaceMembers(workspaceId);
+ List members = this.convertors.convertor(workspaceMembers, WorkspaceMemberVO.MembersVO.class);
+ workspaceMember.setCurrentUserId(user.getId()).setMembers(members);
+ workspaceMember.getMembers().forEach(member -> member.setWorkspaceId(workspaceId).setUsername(member.getUserId().equals(user.getId()) ? user.getUsername() : mongoRepository.findOne(new Query().addCriteria(Criteria.where("_id").is(member.getUserId())), User.class).getUsername()));
+ return workspaceMember;
+ }
+
+ @Override
+ public void update(HttpServletRequest request, WorkspaceParam workspaceParam, String workspaceId) {
+ if (CollectionUtils.isEmpty(workspaceParam.getMembers())) {
+ throw new ServiceException("成员不能为空", RespErrorCode.PARAMETER_ERROR.getCode());
+ }
+ // 更新空间信息
+ Workspace convertor = convertors.convertor(workspaceParam, Workspace.class);
+ mongoRepository.updateFirst(new Query().addCriteria(Criteria.where("_id").is(workspaceId)),
+ new Update().set("name", convertor.getName()).set("description", convertor.getDescription()), Workspace.class);
+ // 空间不能没有管理员
+ boolean flag = workspaceParam.getMembers().stream().map(member -> member.getRole()).collect(Collectors.toList()).contains(RoleEmum.ADMIN.getValue());
+ if (!flag) {
+ throw new ServiceException("空间不能没有管理员", RespErrorCode.PARAMETER_ERROR.getCode());
+ }
+ // 不能有重复的userId
+ List userIds = workspaceParam.getMembers().stream().map(member -> member.getUserId()).distinct().collect(Collectors.toList());
+ if (userIds.size() != workspaceParam.getMembers().size()) {
+ throw new ServiceException("不能重复添加用户", RespErrorCode.PARAMETER_ERROR.getCode());
+ }
+ // 删除历史成员
+ List oldWorkspaceUserId = mongoRepository.findList(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceId)), WorkspaceMember.class).stream().map(WorkspaceMember::getUserId).collect(Collectors.toList());
+ oldWorkspaceUserId.removeAll(userIds);
+ mongoRepository.delete(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceId))
+ .addCriteria(Criteria.where("userId").in(oldWorkspaceUserId)), WorkspaceMember.class);
+ // 检查所有成员是否真实存在
+ workspaceParam.getMembers().stream().forEach(member -> {
+ User memberUser = mongoRepository.findOne(new Query().addCriteria(Criteria.where("_id").is(member.getUserId())), User.class);
+ if (ObjectUtils.isEmpty(memberUser)) {
+ throw new ServiceException("用户id:" + member.getUserId() + "不存在", RespErrorCode.USER_NOT_EXISTS.getCode());
+ }
+ // 修改成员信息
+ WorkspaceMember workspaceMember = memberService.getWorkspaceMember(workspaceId, memberUser.getId());
+ if (ObjectUtils.isEmpty(workspaceMember)) {
+ mongoRepository.save(new WorkspaceMember().setUserId(memberUser.getId()).setWorkspaceId(workspaceId).setRole(member.getRole()));
+ } else {
+ if (workspaceMember.getRole() != member.getRole()) {
+ mongoRepository.updateFirst(new Query().addCriteria(Criteria.where("_id").is(workspaceMember.getId()))
+ .addCriteria(Criteria.where("workspaceId").is(workspaceId)), new Update().set("role", member.getRole()), WorkspaceMember.class);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void delete(HttpServletRequest request, String workspaceId) {
+ Workspace workspace = mongoRepository.findOne(new Query().addCriteria(Criteria.where("_id").is(workspaceId)), Workspace.class);
+ // 更新空间状态
+ InitBaseEntity initBaseEntity = mongoEntityInterceptor.updateDocument(workspace.getStatusList());
+ mongoRepository.updateMulti(new Query().addCriteria(Criteria.where("_id").is(workspaceId)),
+ new Update().set("curStatus", initBaseEntity.getCurStatus())
+ .set("statusList", initBaseEntity.getStatusList()), Workspace.class);
+ // 更新空间下的问卷状态
+ mongoRepository.updateMulti(new Query().addCriteria(Criteria.where("workspaceId").is(workspaceId)),
+ new Update().set("curStatus", initBaseEntity.getCurStatus())
+ .set("statusList", initBaseEntity.getStatusList()), SurveyMeta.class);
+ }
+
+ @Override
+ public List findAllByUserId(HttpServletRequest request) {
+ List workspaceMembers = new ArrayList<>();
+ User user = (User) request.getAttribute("user");
+ List workspaces = mongoRepository.findList(new Query().addCriteria(Criteria.where("ownerId").is(user.getId())).with(Sort.by(Sort.Direction.DESC, "createDate")), Workspace.class);
+ workspaces.stream().forEach(workspace -> workspaceMembers.add(this.getWorkspaceInfo(request, workspace.getId())));
+ return workspaceMembers;
+ }
+
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/CreateWorkspaceMemberParam.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/CreateWorkspaceMemberParam.java
new file mode 100644
index 00000000..2aff512c
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/CreateWorkspaceMemberParam.java
@@ -0,0 +1,18 @@
+package com.xiaojusurvey.engine.core.workspace.param;
+
+import lombok.Data;
+
+/**
+ * @description:
+ * @author: wangchenglong
+ * @time: 2024/8/1 11:17
+ */
+@Data
+public class CreateWorkspaceMemberParam {
+
+ private String userId;
+
+ private String role;
+
+ private String workspaceId;
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/MemberParam.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/MemberParam.java
new file mode 100644
index 00000000..4cec3150
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/MemberParam.java
@@ -0,0 +1,16 @@
+package com.xiaojusurvey.engine.core.workspace.param;
+
+import lombok.Data;
+
+/**
+ * @description:
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:44
+ */
+@Data
+public class MemberParam {
+
+ private String userId;
+
+ private String role;
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/WorkspaceParam.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/WorkspaceParam.java
new file mode 100644
index 00000000..211cbea9
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/param/WorkspaceParam.java
@@ -0,0 +1,29 @@
+package com.xiaojusurvey.engine.core.workspace.param;
+
+import com.xiaojusurvey.engine.common.entity.BaseEntity;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @description: 空间Dto
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:37
+ */
+@Data
+public class WorkspaceParam extends BaseEntity {
+ /**
+ * 空间名称
+ */
+ private String name;
+
+ /**
+ * 空间描述
+ */
+ private String description;
+
+ /**
+ * 空间创建者
+ */
+ private List members;
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceInfoVO.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceInfoVO.java
new file mode 100644
index 00000000..2ec15856
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceInfoVO.java
@@ -0,0 +1,58 @@
+package com.xiaojusurvey.engine.core.workspace.vo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @description: 空间信息VO
+ * @author: wangchenglong
+ * @time: 2024/7/25 14:23
+ */
+@Data
+public class WorkspaceInfoVO {
+ /**
+ * 空间 id
+ */
+ @JsonProperty("_id")
+ private String id;
+
+ /**
+ * 所有者id
+ */
+ private String ownerId;
+
+ /**
+ * 所有者用户名
+ */
+ private String owner;
+
+ /**
+ * 空间名称
+ */
+ private String name;
+
+ /**
+ * 空间描述
+ */
+ private String description;
+
+ /**
+ * 当前用户的
+ */
+ private String currentUserId;
+
+ /**
+ * 当前用户的角色,枚举:admin、user
+ */
+ private String currentUserRole;
+
+ /**
+ * 包含的问卷总数
+ */
+ private Long surveyTotal;
+
+ /**
+ * 包含的成员总数
+ */
+ private Long memberTotal;
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceListVO.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceListVO.java
new file mode 100644
index 00000000..1d786b3d
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceListVO.java
@@ -0,0 +1,16 @@
+package com.xiaojusurvey.engine.core.workspace.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @description: 空间信息VO
+ * @author: wangchenglong
+ * @time: 2024/7/25 14:23
+ */
+@Data
+public class WorkspaceListVO {
+ private List data;
+ private Integer count;
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberIdVO.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberIdVO.java
new file mode 100644
index 00000000..583e8578
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberIdVO.java
@@ -0,0 +1,15 @@
+package com.xiaojusurvey.engine.core.workspace.vo;
+
+import lombok.Data;
+
+/**
+ * @description:
+ * @author: wangchenglong
+ * @time: 2024/8/1 14:28
+ */
+@Data
+public class WorkspaceMemberIdVO {
+
+ private String memberId;
+
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberVO.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberVO.java
new file mode 100644
index 00000000..41d17b87
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceMemberVO.java
@@ -0,0 +1,32 @@
+package com.xiaojusurvey.engine.core.workspace.vo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @description:
+ * @author: wangchenglong
+ * @time: 2024/7/25 19:38
+ */
+@Data
+public class WorkspaceMemberVO {
+ private String name;
+ private String description;
+ private String currentUserId;
+ @JsonProperty("_id")
+ private String id;
+ private List members;
+
+
+ @Data
+ public static class MembersVO {
+ @JsonProperty("_id")
+ private String id;
+ private String userId;
+ private String username;
+ private String role;
+ private String workspaceId;
+ }
+}
diff --git a/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceVO.java b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceVO.java
new file mode 100644
index 00000000..22f4a1d8
--- /dev/null
+++ b/survey-core/src/main/java/com/xiaojusurvey/engine/core/workspace/vo/WorkspaceVO.java
@@ -0,0 +1,17 @@
+package com.xiaojusurvey.engine.core.workspace.vo;
+
+import lombok.Data;
+
+/**
+ * @description: 空间VO
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:37
+ */
+@Data
+public class WorkspaceVO {
+ /**
+ * 新建的空间 id
+ */
+ private String workspaceId;
+
+}
diff --git a/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/MongoRepository.java b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/MongoRepository.java
index cc585519..f79738b1 100644
--- a/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/MongoRepository.java
+++ b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/MongoRepository.java
@@ -90,4 +90,13 @@ public interface MongoRepository {
* 多条件分页查询
*/
List page(Query query, int pageIndex, int pageSize, Class entityClass);
+
+ /**
+ * 多条件查询
+ * @param query
+ * @param entityClass
+ * @param
+ * @return
+ */
+ List findList(Query query, Class entityClass);
}
diff --git a/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/impl/MongoRepositoryImpl.java b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/impl/MongoRepositoryImpl.java
index 576b09ae..c2bc586d 100644
--- a/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/impl/MongoRepositoryImpl.java
+++ b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/impl/MongoRepositoryImpl.java
@@ -113,4 +113,9 @@ public class MongoRepositoryImpl implements MongoRepository {
return mongoTemplate.find(query, entityClass);
}
+ @Override
+ public List findList(Query query, Class entityClass) {
+ return mongoTemplate.find(query, entityClass);
+ }
+
}
diff --git a/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoConfig.java b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoConfig.java
new file mode 100644
index 00000000..73718298
--- /dev/null
+++ b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoConfig.java
@@ -0,0 +1,20 @@
+package com.xiaojusurvey.engine.repository.interceptor;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.config.EnableMongoAuditing;
+
+/**
+ * @description: MongoEntityInterceptor
+ * @author: wangchenglong
+ * @time: 2024/7/30 17:36
+ */
+@Configuration
+@EnableMongoAuditing
+public class MongoConfig {
+ @Bean
+ public MongoEntityInterceptor auditEntityMongoListener() {
+ return new MongoEntityInterceptor();
+ }
+
+}
diff --git a/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoEntityInterceptor.java b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoEntityInterceptor.java
new file mode 100644
index 00000000..8c4ec19b
--- /dev/null
+++ b/survey-dal/src/main/java/com/xiaojusurvey/engine/repository/interceptor/MongoEntityInterceptor.java
@@ -0,0 +1,53 @@
+package com.xiaojusurvey.engine.repository.interceptor;
+
+import com.xiaojusurvey.engine.common.entity.BaseEntity;
+import com.xiaojusurvey.engine.common.entity.InitBaseEntity;
+import com.xiaojusurvey.engine.common.entity.Status;
+import com.xiaojusurvey.engine.common.enums.RecordStatusEnum;
+import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
+import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @description: mongodb事件拦截器
+ * @author: wangchenglong
+ * @time: 2024/7/30 16:37
+ * @param
+ */
+@Component
+public class MongoEntityInterceptor extends AbstractMongoEventListener {
+
+ @Override
+ public void onBeforeConvert(BeforeConvertEvent event) {
+ Object entity = event.getSource();
+ long time = System.currentTimeMillis();
+ if (entity instanceof BaseEntity) {
+ String id = ((BaseEntity) entity).getId();
+ if (ObjectUtils.isEmpty(id)) {
+ Status status = new Status().setStatus(RecordStatusEnum.NEW.getStatusType()).setDate(time);
+ ((BaseEntity) entity).setCurStatus(status)
+ .setCreateDate(time).setUpdateDate(time)
+ .setStatusList(Arrays.asList(status));
+ }
+ }
+ }
+
+ /**
+ * 更新操作维护公共字段
+ * @param statusList
+ * @return
+ */
+ public InitBaseEntity updateDocument(List statusList) {
+ long time = System.currentTimeMillis();
+ Status status = new Status().setStatus(RecordStatusEnum.REMOVED.getStatusType()).setDate(time);
+ statusList.add(status);
+ return (InitBaseEntity) new InitBaseEntity().setUpdateDate(time)
+ .setCurStatus(status)
+ .setStatusList(statusList);
+ }
+
+}
diff --git a/survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceController.java b/survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceController.java
new file mode 100644
index 00000000..6888a70a
--- /dev/null
+++ b/survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceController.java
@@ -0,0 +1,99 @@
+package com.xiaojusurvey.engine.controller;
+
+import com.xiaojusurvey.engine.common.rpc.RpcResult;
+import com.xiaojusurvey.engine.common.util.RpcResultUtil;
+import com.xiaojusurvey.engine.core.workspace.WorkspaceService;
+import com.xiaojusurvey.engine.core.workspace.param.WorkspaceParam;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceListVO;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceMemberVO;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * @description: 空间
+ * @author: wangchenglong
+ * @time: 2024/7/24 14:33
+ */
+@RequestMapping("/api/workspace")
+@RestController
+public class WorkspaceController {
+
+ @Autowired
+ private WorkspaceService workspaceService;
+
+ /**
+ * 创建空间
+ * @param request
+ * @param workspaceParam
+ * @return
+ */
+ @PostMapping
+ public RpcResult create(HttpServletRequest request, @RequestBody WorkspaceParam workspaceParam) {
+ return RpcResultUtil.createSuccessResult(new WorkspaceVO().setWorkspaceId(workspaceService.createWorkspace(request, workspaceParam)));
+ }
+
+ /**
+ * 获取空间列表
+ * @param request
+ * @param pageSize
+ * @param curPage
+ * @param name
+ * @return
+ */
+ @GetMapping
+ public RpcResult findAll(HttpServletRequest request, @RequestParam(defaultValue = "10") Integer pageSize,
+ @RequestParam(defaultValue = "1") Integer curPage, String name) {
+ return RpcResultUtil.createSuccessResult(workspaceService.findAll(request, pageSize, curPage, name));
+ }
+
+ /**
+ * 获取空间详情
+ * @param request
+ * @param workspaceId
+ * @return
+ */
+ @GetMapping("/{workspaceId}")
+ public RpcResult getWorkspaceInfo(HttpServletRequest request, @PathVariable String workspaceId) {
+ return RpcResultUtil.createSuccessResult(workspaceService.getWorkspaceInfo(request, workspaceId));
+ }
+
+ /**
+ * 更新空间详情
+ * @param request
+ * @param workspaceId
+ * @param workspaceParam
+ * @return
+ */
+ @PostMapping("/{workspaceId}")
+ public RpcResult> update(HttpServletRequest request, @PathVariable String workspaceId, @RequestBody WorkspaceParam workspaceParam) {
+ workspaceService.update(request, workspaceParam, workspaceId);
+ return RpcResultUtil.createSuccessResult(true);
+ }
+
+ /**
+ * 删除空间
+ * @param request
+ * @param workspaceId
+ * @return
+ */
+ @DeleteMapping("/{workspaceId}")
+ public RpcResult> delete(HttpServletRequest request, @PathVariable String workspaceId) {
+ workspaceService.delete(request, workspaceId);
+ return RpcResultUtil.createSuccessResult(true);
+ }
+
+ /**
+ * 获取空间成员列表
+ * @param request
+ * @return
+ */
+ @GetMapping("/member/list")
+ public RpcResult> getWorkspaceAndMember(HttpServletRequest request) {
+ return RpcResultUtil.createSuccessResult(workspaceService.findAllByUserId(request));
+ }
+
+}
diff --git a/survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceMemberController.java b/survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceMemberController.java
new file mode 100644
index 00000000..0e32ef01
--- /dev/null
+++ b/survey-server/src/main/java/com/xiaojusurvey/engine/controller/WorkspaceMemberController.java
@@ -0,0 +1,59 @@
+package com.xiaojusurvey.engine.controller;
+
+import com.xiaojusurvey.engine.common.rpc.RpcResult;
+import com.xiaojusurvey.engine.common.util.RpcResultUtil;
+import com.xiaojusurvey.engine.core.workspace.WorkspaceMemberService;
+import com.xiaojusurvey.engine.core.workspace.param.CreateWorkspaceMemberParam;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceMemberIdVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @description: 空间空间成员
+ * @author: wangchenglong
+ * @time: 2024/8/1 14:33
+ */
+@RequestMapping("/api/workspaceMember")
+@RestController
+public class WorkspaceMemberController {
+
+ @Autowired
+ private WorkspaceMemberService workspaceMemberService;
+
+ /**
+ * 添加空间成员
+ * @param createWorkspaceMemberParam
+ * @return
+ */
+ @PostMapping
+ public RpcResult create(@RequestBody CreateWorkspaceMemberParam createWorkspaceMemberParam) {
+ return RpcResultUtil.createSuccessResult(new WorkspaceMemberIdVO().setMemberId(workspaceMemberService.create(createWorkspaceMemberParam)));
+ }
+
+ /**
+ * 更新空间成员角色
+ * @param createWorkspaceMemberParam
+ * @return
+ */
+ @PostMapping("/updateRole")
+ public RpcResult> updateRole(@RequestBody CreateWorkspaceMemberParam createWorkspaceMemberParam) {
+ workspaceMemberService.updateRole(createWorkspaceMemberParam);
+ return RpcResultUtil.createSuccessResult(true);
+ }
+
+
+ /**
+ * 删除空间成员
+ * @param workspaceMemberParam
+ * @return
+ */
+ @PostMapping("/deleteMember")
+ public RpcResult> delete(@RequestBody CreateWorkspaceMemberParam workspaceMemberParam) {
+ workspaceMemberService.delete(workspaceMemberParam);
+ return RpcResultUtil.createSuccessResult(true);
+ }
+
+}
diff --git a/survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceControllerTest.java b/survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceControllerTest.java
new file mode 100644
index 00000000..5880f2af
--- /dev/null
+++ b/survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceControllerTest.java
@@ -0,0 +1,127 @@
+package com.xiaojusurvey.engine.controller;
+
+import com.xiaojusurvey.engine.common.rpc.RpcResult;
+import com.xiaojusurvey.engine.core.workspace.WorkspaceService;
+import com.xiaojusurvey.engine.core.workspace.param.WorkspaceParam;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceListVO;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceMemberVO;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceVO;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
+/**
+ * @description: WorkspaceController测试
+ * @author: wangchenglong
+ * @time: 2024/8/1 16:52
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+public class WorkspaceControllerTest {
+
+ @InjectMocks
+ private WorkspaceController workspaceController;
+
+ @Mock
+ private WorkspaceService workspaceService;
+
+ private MockHttpServletRequest mockRequest;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mockRequest = new MockHttpServletRequest();
+ }
+
+ @Test
+ public void testCreateWorkspace() {
+ WorkspaceParam mockWorkspaceParam = new WorkspaceParam();
+ String workspaceId = "123456";
+
+ when(workspaceService.createWorkspace(any(HttpServletRequest.class), any(WorkspaceParam.class)))
+ .thenReturn(workspaceId);
+
+ RpcResult result = workspaceController.create(mockRequest, mockWorkspaceParam);
+
+ assertEquals(true, result.getSuccess());
+ assertEquals(workspaceId, result.getData().getWorkspaceId());
+ }
+
+ @Test
+ public void testFindAllWorkspaces() {
+ int pageSize = 10;
+ int curPage = 1;
+ String name = "TestWorkspace";
+ WorkspaceListVO mockListVO = new WorkspaceListVO();
+
+ when(workspaceService.findAll(any(HttpServletRequest.class), eq(pageSize), eq(curPage), eq(name)))
+ .thenReturn(mockListVO);
+
+ RpcResult result = workspaceController.findAll(mockRequest, pageSize, curPage, name);
+
+ assertEquals(true, result.getSuccess());
+ assertNotNull(result.getData());
+ }
+
+ @Test
+ public void testGetWorkspaceInfo() {
+ String workspaceId = "123456";
+ WorkspaceMemberVO mockMemberVO = new WorkspaceMemberVO();
+
+ when(workspaceService.getWorkspaceInfo(any(HttpServletRequest.class), eq(workspaceId)))
+ .thenReturn(mockMemberVO);
+
+ RpcResult result = workspaceController.getWorkspaceInfo(mockRequest, workspaceId);
+
+ assertEquals(true, result.getSuccess());
+ assertNotNull(result.getData());
+ }
+
+ @Test
+ public void testUpdateWorkspace() {
+ String workspaceId = "123456";
+ WorkspaceParam mockWorkspaceParam = new WorkspaceParam();
+
+ RpcResult> result = workspaceController.update(mockRequest, workspaceId, mockWorkspaceParam);
+
+ assertEquals(true, result.getSuccess());
+ verify(workspaceService, times(1)).update(any(HttpServletRequest.class), eq(mockWorkspaceParam), eq(workspaceId));
+ }
+
+ @Test
+ public void testDeleteWorkspace() {
+ String workspaceId = "123456";
+
+ RpcResult> result = workspaceController.delete(mockRequest, workspaceId);
+
+ assertEquals(true, result.getSuccess());
+ verify(workspaceService, times(1)).delete(any(HttpServletRequest.class), eq(workspaceId));
+ }
+
+ @Test
+ public void testGetWorkspaceAndMemberList() {
+ List mockMemberList = new ArrayList<>();
+
+ when(workspaceService.findAllByUserId(any(HttpServletRequest.class)))
+ .thenReturn(mockMemberList);
+
+ RpcResult> result = workspaceController.getWorkspaceAndMember(mockRequest);
+
+ assertEquals(true, result.getSuccess());
+ assertEquals(mockMemberList, result.getData());
+ }
+
+}
diff --git a/survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceMemberControllerTest.java b/survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceMemberControllerTest.java
new file mode 100644
index 00000000..6ebb6f2d
--- /dev/null
+++ b/survey-server/src/test/java/com/xiaojusurvey/engine/controller/WorkspaceMemberControllerTest.java
@@ -0,0 +1,71 @@
+package com.xiaojusurvey.engine.controller;
+
+import com.xiaojusurvey.engine.common.rpc.RpcResult;
+import com.xiaojusurvey.engine.core.workspace.WorkspaceMemberService;
+import com.xiaojusurvey.engine.core.workspace.param.CreateWorkspaceMemberParam;
+import com.xiaojusurvey.engine.core.workspace.vo.WorkspaceMemberIdVO;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+/**
+ * @description: WorkspaceMemberController 测试
+ * @author: wangchenglong
+ * @time: 2024/8/1 17:23
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+public class WorkspaceMemberControllerTest {
+ @InjectMocks
+ private WorkspaceMemberController workspaceMemberController;
+
+ @Mock
+ private WorkspaceMemberService workspaceMemberService;
+
+ private MockHttpServletRequest mockRequest;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mockRequest = new MockHttpServletRequest();
+ }
+
+ @Test
+ public void testCreateWorkspaceMember() {
+ CreateWorkspaceMemberParam mockParam = new CreateWorkspaceMemberParam();
+ String memberId = "123456";
+
+ when(workspaceMemberService.create(any(CreateWorkspaceMemberParam.class)))
+ .thenReturn(memberId);
+
+ RpcResult result = workspaceMemberController.create(mockParam);
+
+ assertEquals(true, result.getSuccess());
+ assertEquals(memberId, result.getData().getMemberId());
+ }
+
+ @Test
+ public void testUpdateWorkspaceMemberRole() {
+ CreateWorkspaceMemberParam mockParam = new CreateWorkspaceMemberParam();
+
+ RpcResult> result = workspaceMemberController.updateRole(mockParam);
+
+ assertEquals(true, result.getSuccess());
+ }
+
+ @Test
+ public void testDeleteWorkspaceMember() {
+ CreateWorkspaceMemberParam mockParam = new CreateWorkspaceMemberParam();
+
+ RpcResult> result = workspaceMemberController.delete(mockParam);
+
+ assertEquals(true, result.getSuccess());
+ }
+}