跳转到正文

快速开始

当前实现限制

WorkspaceUserServiceImpl.queryPoByUserIdAndWorkspaceIdqueryPoByWorkspaceIdForOwner 实际调用必取接口,无结果会抛异常。因此首次加入成员会在检查阶段失败,创建空间或默认初始化可能已先写入空间记录。本文的创建、邀请、加入步骤说明接口顺序;需先修正并验证该调用链才能跑通新成员流程。isAdminisOwnercontains 的缺失成员情况也可能抛异常,不能统一当作 false。详见重点文件与方法

本例完成“用户 A 创建空间 → 生成普通成员邀请码 → 用户 B 加入 → 查看成员”的流程。

前提是已有可运行的 EFC Web 应用,已经接好系统用户、登录认证、MyBatis-Plus 数据访问和框架基础 Bean。当前源码基线为 Java 25、Spring Boot 4.1.0,模块版本为 4.1.0-SNAPSHOT,需在项目 Maven 仓库或本地可用。准备两个已存在且可以登录的用户 A、B。

本例是在已有应用上增加工作空间能力。工作空间会传递依赖系统用户、系统账号和登录核心;这些模块所需的用户数据表、认证及运行环境应已就绪。

1. 添加依赖

在应用 POM 中导入 Business BOM,添加 App Controller。已有 BOM 不重复导入。

xml
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.own</groupId>
            <artifactId>springboot-business-dependencies</artifactId>
            <version>4.1.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>com.own.business</groupId>
        <artifactId>springboot-business-workspace-controller-app</artifactId>
    </dependency>
</dependencies>

business 中的自动配置入口 UseBusinessWorkspace 会扫描工作空间服务、Mapper 和已引入的 Controller,无需另写一套接口,也没有 own.workspace.enabled 开关。

空间初始化、加入成员和转让所有权需要 StoreLockManager。如果应用尚未提供 Store 实现,单实例演示可在上述 dependencies 中追加:

xml
<dependency>
    <groupId>com.own.component</groupId>
    <artifactId>springboot-component-store-starter-local</artifactId>
</dependency>

已有 Redis Store 的应用沿用原配置。多实例部署使用共享 Redis Store,不能依靠本地锁实现跨实例防重;参见成员与角色

2. 准备数据表和配置

在应用已有的 MySQL 数据库中执行 工作空间首次建表 SQL,创建以下三张表及查询索引:

数据
own_workspace空间资料
own_workspace_user用户与空间的成员关系
own_workspace_user_invite邀请码与有效期

下载脚本保留当前业务源码的表结构,移除了原脚本的 DROP TABLE。它只用于尚未创建这三张表的数据库,不是已有表的增量迁移,也不会随应用启动自动执行。

沿用现有数据源;未配置时,在应用 application.yml 中按环境填写:

yaml
spring:
  datasource:
    url: ${WORKSPACE_JDBC_URL}
    username: ${WORKSPACE_DB_USERNAME}
    password: ${WORKSPACE_DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver
  main:
    allow-circular-references: true

WORKSPACE_JDBC_URL 使用应用的 MySQL JDBC 地址,应用需已有 MySQL 驱动。当前 WorkspaceServiceImplWorkspaceUserServiceImpl 相互注入;示例允许循环引用以适配当前实现,禁止循环引用的应用应先调整装配关系。

确认已有应用注册了 MapperUtilSystemUserInfoServiceStoreLockManager,并能通过 SessionUserUtil 取得当前登录用户。仅传入请求体中的 userId 不会建立登录身份。

3. 用户 A 创建空间

启动应用,使用已经登录为 A 的 API 客户端访问下列接口。请求地址加上应用域名、端口和实际 context path,认证请求头或 Cookie 沿用应用现有登录协议。

请求:POST /api/app/workspace/Content-Type: application/json

json
{
  "name": "协作演示空间",
  "cover": ""
}

使用一个尚未存在的名称。成功响应的 dataWorkspaceVo;记录 data.id 作为后续 workspaceId。该流程创建普通空间(isDefault=0),并将 A 加为 OWNER

随后调用 POST /api/app/workspace/all,请求体为 {}data 列表中应包含刚创建的空间;接口会使用 A 的会话身份过滤,不需要提交 userId

4. 用户 A 生成邀请

请求:POST /api/app/workspace/user/invite/。将示例 10001 换成上一步返回的空间 ID。

json
{
  "workspaceId": "10001",
  "permission": "MEMBER"
}

成功后从 data.inviteCode 取出邀请码。不填写 expiredTime 时,由服务端设置为当前时间加一天。此接口返回邀请码和邀请信息,前端自行生成分享链接。

角色在 JSON 和路径中使用枚举名,如 MEMBERADMIN,不要使用数据库中的 32 代替。

5. 用户 B 加入并核对结果

切换到已登录为 B 的 API 客户端,访问 POST /api/app/workspace/user/invite/join/{inviteCode},替换为实际邀请码,无需请求体。

成功后调用 POST /api/app/workspace/all,请求体为 {},B 应能看到该空间。A 再访问 POST /api/app/workspace/user/page/workspace/id/{workspaceId}

json
{
  "page": 1,
  "rows": 10
}

响应 data.list 中应有 A 的 OWNER 关系和 B 的 MEMBER 关系;成员 id 是关系记录 ID,userId 才是系统用户 ID。

上述接口同步操作数据库。成功码为 00000,加入操作没有业务数据返回;不要把 data=true 当成成功的必要条件。通用响应及 ID 约定见空间管理

下一步

  • 管理空间及初始化默认空间:阅读空间管理
  • 变更角色、转让所有权或退出:阅读成员与角色
  • 自定义邀请有效期、撤销邀请与处理加入失败:阅读邀请加入

接入现有业务数据时,还需要由应用检查当前用户的空间成员关系,并用空间 ID 限定数据访问范围。