☰
集团级多租户OA系统:Schema级隔离与跨租户流程实战
2026/10/22 5:11:16 网站建设 项目流程

简介:点狮OA是一套面向集团级企业及多租户SaaS服务场景的开源企业办公系统,专为中大型组织提供可定制化、高扩展性的协同办公解决方案,解决跨子公司流程隔离、权限独立、业务灵活适配等核心管理难题。资源包共2000个文件,以485个Java后端逻辑文件、850个HTML前端页面、414个JS交互脚本及107个CSS样式文件为主体,辅以JSON配置、SQL建表与Python工具脚本,完整覆盖前后端工程结构,压缩包大小37.51MB,代码规范、模块清晰,便于二次开发与系统集成。目前已有175人学习下载,适合具备Java Web开发基础的工程师深入研究多租户架构设计、Flowable流程引擎深度应用(支持并行/会签/回退/转办等全生命周期操作)以及与HRM、CRM、ERP等点狮生态系统的无缝对接实践。

1. 点狮OA:为什么集团级企业宁可自建多租户办公系统,也不用通用SaaS?

你见过这样的场景吗?某制造集团下属12家子公司,财务用A系统、人力用B平台、项目审批走C流程,各公司IT管理员各自为政,数据孤岛深得连集团CIO都查不到一张跨公司差旅报销的完整链路。这时候,有人推来一套“开箱即用”的SaaS办公系统——结果试了三天就卡在权限模型上:总部要能穿透查看所有子公司流程,但子公司A又坚决不允许B公司看到自己的合同审批节点。通用SaaS的RBAC(基于角色的访问控制)在这里直接失效。点狮OA正是为这类矛盾而生:它不是把“多公司入驻”当作营销话术,而是把租户隔离粒度精确到数据库Schema级+业务域配置热插拔+组织树跨租户可见性策略作为底层设计铁律。它不面向中小微企业做标准化交付,而是专为需要“统分结合”治理能力的集团型客户构建——既满足集团统一合规审计、主数据管控、流程协同的要求,又保障各子公司在审批流、表单字段、附件策略上的自治权。如果你正评估是否该放弃公有云SaaS转向私有化多租户方案,这篇笔记就是从零部署点狮OA并跑通首个跨租户审批闭环的实操手记。


2. 搭建点狮OA多租户底座:从源码编译到三节点集群部署

点狮OA采用Spring Cloud Alibaba微服务架构,核心模块包括tenant-core(租户元数据管理)、auth-center(统一认证中心)、workflow-engine(可配置流程引擎)和biz-portal(租户定制化门户)。其多租户能力并非靠Nginx反向代理或应用层简单加租户ID前缀实现,而是深度耦合在数据访问层(DAO)与服务注册发现机制中。这意味着部署时必须同步完成租户注册中心初始化、分布式事务协调器配置、以及跨租户消息路由规则加载三个关键动作。以下步骤基于v3.8.2 LTS版本(2024年Q2稳定分支),所有操作均在CentOS 7.9 + OpenJDK 17 + MySQL 8.0.33环境下验证通过。

2.1 编译源码并确认租户隔离模式参数

点狮OA官方未提供二进制发行包,必须从Git仓库拉取源码后手动构建。关键在于识别其多租户实现模式——它支持SCHEMA(每个租户独立数据库Schema)、SHARDING(共享库+分表)和DISCRIMINATOR(单表+租户字段)三种模式,但仅SCHEMA模式支持完整的跨租户流程协同与审计追溯,这也是集团级客户唯一被支持的生产模式。

# 克隆官方代码仓库(注意:使用企业内网镜像地址,避免公网依赖) git clone https://gitlab.internal/oa/pointlion/pointlion-oa.git cd pointlion-oa # 查看pom.xml中profile定义,确认默认激活schema模式 grep -A 5 "<id>schema</id>" pom.xml # 输出应包含:<activeByDefault>true</activeByDefault> # 构建全量模块(跳过test,生产环境需单独运行集成测试套件) mvn clean package -Pschema -Dmaven.test.skip=true # 检查生成物:target目录下应存在tenant-core-3.8.2.jar等12个独立jar包 ls target/ | grep -E "(tenant|auth|workflow|portal)" | wc -l # 预期输出:12

逻辑说明:-Pschema参数激活Maven Profile,会加载src/main/resources/schema/application-tenant.yml,其中定义tenant.isolation.mode: SCHEMA及tenant.schema.prefix: t_。该前缀将用于后续数据库初始化脚本生成租户专属Schema名(如t_shenzhen_factory)。若误用sharding模式,后续将无法配置跨租户审批节点跳转。

2.2 初始化MySQL多租户元数据库与Schema模板

点狮OA要求MySQL实例预先创建两个库:pointlion_meta(存储所有租户的元信息,如租户ID、Schema名、状态、创建时间)和pointlion_template(作为新租户Schema的克隆模板)。后者必须包含完整表结构但无业务数据,且所有表引擎强制为InnoDB。

-- 创建元数据库(字符集必须为utf8mb4,否则中文租户名会截断) CREATE DATABASE IF NOT EXISTS pointlion_meta CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -- 创建模板库(此库将被克隆为每个租户的实际Schema) CREATE DATABASE IF NOT EXISTS pointlion_template CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -- 执行官方提供的模板SQL(位于docs/sql/template-schema.sql) -- 注意:该脚本会创建27张表,含tenant_info(租户主表)、org_tree(组织树)、flow_definition(流程定义)等核心表 SOURCE /path/to/docs/sql/template-schema.sql;

参数说明:pointlion_template库中的flow_definition表必须包含cross_tenant_support: TINYINT(1) DEFAULT 0字段,该字段决定流程是否允许跨租户流转。默认值为0,需在创建租户时由管理员显式开启。若遗漏此字段,后续配置跨租户审批时前端将报“流程不支持跨域”错误且无日志提示。

2.3 部署三节点高可用集群:Nacos注册中心+Seata事务协调器

点狮OA依赖Nacos作为服务注册与配置中心,同时集成Seata AT模式处理跨服务分布式事务(例如:审批通过后同步更新财务系统和HR系统的操作)。三节点部署是保障租户服务不因单点故障中断的最低要求。

# 下载Nacos v2.3.0(必须匹配点狮OA内置客户端版本) wget https://github.com/alibaba/nacos/releases/download/2.3.0/nacos-server-2.3.0.tar.gz tar -zxvf nacos-server-2.3.0.tar.gz # 修改cluster.conf,配置三节点IP(假设为10.10.1.10, 10.10.1.11, 10.10.1.12) echo "10.10.1.10:8848" > nacos/conf/cluster.conf echo "10.10.1.11:8848" >> nacos/conf/cluster.conf echo "10.10.1.12:8848" >> nacos/conf/cluster.conf # 启动三台Nacos(每台执行) ./nacos/bin/startup.sh -m cluster # 验证集群状态(任一节点执行curl) curl -X GET 'http://10.10.1.10:8848/nacos/v1/ns/operator/metrics' # 返回JSON中应含"raftState":"Leader"和"raftState":"Follower"节点
# 部署Seata Server v1.7.1(与点狮OA的seata-spring-cloud-starter版本严格对应) wget https://github.com/seata/seata/releases/download/v1.7.1/seata-server-1.7.1.tar.gz tar -zxvf seata-server-1.7.1.tar.gz # 修改registry.conf,指向Nacos集群 sed -i 's/localhost:8848/10.10.1.10:8848,10.10.1.11:8848,10.10.1.12:8848/g' seata/conf/registry.conf # 初始化Seata全局事务表(执行一次即可,在pointlion_meta库中) mysql -h10.10.1.10 -uadmin -p pointlion_meta < seata/script/server/db/mysql.sql

关键配置:seata/conf/file.conf中store.mode必须设为db,且store.db.datasource指向pointlion_meta库。这是为了确保所有租户的全局事务日志统一落库,便于集团审计员按租户ID查询跨系统事务链路。若设为file模式,事务日志分散在各节点磁盘,无法实现集中追溯。


3. 创建首个集团租户:从元数据注册到组织树映射

租户创建不是简单的后台表INSERT操作,而是一套原子化工作流:元数据写入 → Schema克隆 → 组织树初始化 → 认证密钥生成 → 门户主题加载。点狮OA提供tenant-admin-cli命令行工具完成全流程,避免人工操作导致状态不一致。

3.1 使用CLI工具注册集团总部租户

tenant-admin-cli是点狮OA配套的轻量级管理工具,无需Java环境,直接执行二进制文件。它通过调用tenant-core暴露的REST API完成租户生命周期管理,并自动校验租户名唯一性、Schema前缀合法性等约束。

# 下载并解压CLI工具(版本必须与服务端一致) wget https://artifactory.internal/oa/cli/tenant-admin-cli-v3.8.2-linux-amd64.tar.gz tar -zxvf tenant-admin-cli-v3.8.2-linux-amd64.tar.gz # 注册集团总部租户(参数含义:-n租户标识符,-d租户显示名,-s Schema前缀,-o组织树根节点名) ./tenant-admin-cli register \ -n "group_headquarters" \ -d "XX集团总部" \ -s "t_group" \ -o "XX集团" # 成功返回示例: # {"code":200,"message":"Tenant created successfully","data":{"tenantId":"tnt-8a9f3c1e","schemaName":"t_group"}}

逻辑说明:该命令实际触发三步操作:1)向pointlion_meta.tenant_info插入记录;2)以pointlion_template为模板,执行CREATE DATABASE t_group CHARACTER SET utf8mb4;3)调用tenant-core内部服务,在t_group库中初始化组织树根节点(org_tree表首条记录parent_id=null)。若中途失败,CLI会自动回滚已执行步骤,保证元数据与物理Schema强一致。

3.2 为子公司创建租户并建立跨组织关系

子公司租户创建需额外指定--parent-tenant-id参数,这将在元数据库中建立父子租户关系,并触发组织树跨租户挂载逻辑。例如:深圳工厂租户需归属集团总部,其组织树将自动继承总部的“集团审批委员会”节点。

# 创建深圳工厂租户,指定父租户为集团总部 ./tenant-admin-cli register \ -n "sz_factory" \ -d "深圳工厂" \ -s "t_sz" \ -o "深圳工厂" \ --parent-tenant-id "tnt-8a9f3c1e" # 创建上海研发中心租户,同样归属集团总部 ./tenant-admin-cli register \ -n "sh_rnd" \ -d "上海研发中心" \ -s "t_sh" \ -o "上海研发中心" \ --parent-tenant-id "tnt-8a9f3c1e"

参数说明:--parent-tenant-id值来自上一步返回的tenantId。该参数不仅建立元数据关系,更关键的是:当深圳工厂员工发起“跨部门技术评审”流程时,流程引擎会自动检索pointlion_meta.tenant_relation表,获取上海研发中心的租户ID,并将审批节点路由至sh_rnd库中的flow_instance表。若遗漏此参数,跨租户流程将无法被目标租户的服务实例消费。

3.3 验证租户隔离与跨租户可见性

租户创建完成后,必须验证两个核心能力:1)数据物理隔离(深圳工厂无法查询上海研发中心的员工信息);2)组织树逻辑可见(集团总部可查看所有子公司的组织架构)。

-- 登录MySQL,切换至深圳工厂Schema USE t_sz; -- 尝试查询上海研发中心的员工表(应返回ERROR 1146: Table 't_sh.sys_user' doesn't exist) SELECT * FROM sys_user LIMIT 1; -- 切换至集团总部Schema USE t_group; -- 查询组织树视图(该视图聚合所有子租户的组织节点,但隐藏敏感字段如身份证号) SELECT node_name, tenant_code, depth FROM org_tree_view WHERE depth = 2; -- 预期输出两行:深圳工厂(tnt-8a9f3c1e)、上海研发中心(tnt-8a9f3c1e)

验证要点:org_tree_view是点狮OA预置的数据库视图,其定义为SELECT node_name, tenant_code, depth FROM t_sz.org_tree UNION ALL SELECT ... FROM t_sh.org_tree。该视图由tenant-core服务在租户注册时动态生成,确保集团管理员无需手动维护跨库查询语句。若视图未生成,检查tenant-core日志中是否出现Failed to generate org_tree_view for tenant group_headquarters错误。


4. 配置跨租户审批流程:从流程建模到节点权限映射

点狮OA的流程引擎支持“租户域”和“全局域”双模式。普通审批(如请假)限定在本租户内流转;而涉及多公司协同的流程(如集团采购招标、跨厂技术标准评审)必须启用全局域,并为每个节点显式配置可操作租户范围。这是区别于通用OA的核心能力。

4.1 在流程设计器中启用全局域并定义跨租户节点

点狮OA提供Web版流程设计器(URL:http://<gateway-ip>/designer),登录集团总部管理员账号后,进入“全局流程模板”菜单。此处创建的流程将被所有租户继承,但各租户可覆盖节点审批人配置。

# 启动流程设计器服务(需单独部署,非tenant-core内置) java -jar flow-designer-3.8.2.jar \ --spring.profiles.active=prod \ --server.port=9001 \ --nacos.server-addr=10.10.1.10:8848

操作路径:

  1. 点击【新建全局流程】→ 流程名称填“集团技术评审”
  2. 拖入“开始节点” → “评审申请”(表单节点,关联tech_review_form)
  3. 拖入“租户选择网关” → 设置条件:${applicant.tenantCode} == 't_sz'→ 分支1:深圳工厂初审
  4. 拖入“跨租户审批节点” → 关键配置:
    • 租户范围:勾选“上海研发中心”、“集团总部”
    • 节点类型:GLOBAL_APPROVAL(非普通APPROVAL)
    • 审批人策略:TENANT_ADMIN(自动指派各租户的管理员)
  5. 发布流程,版本号自动生成V1.0.0-global

逻辑说明:“租户选择网关”是点狮OA特有组件,根据申请人租户ID动态分流。若申请人来自深圳工厂(t_sz),则进入深圳初审环节;若来自上海研发中心(t_sh),则进入上海初审。而“跨租户审批节点”会生成两条独立的审批任务:一条存入t_sh.flow_instance(待上海研发中心管理员处理),另一条存入t_group.flow_instance(待集团总部管理员处理)。两任务状态互不影响,但最终流程实例状态由tenant-core的聚合服务统一计算。

4.2 为跨租户节点配置租户级审批人

全局流程发布后,各租户需在自身管理后台配置具体审批人。此步骤不可跳过,否则跨租户节点将始终处于“待分配”状态。

# 登录深圳工厂租户后台(URL: http://<gateway-ip>/t_sz) # 导航至【流程管理】→【我的流程】→ 找到“集团技术评审 V1.0.0-global” # 点击【配置节点】→ 选择“跨租户审批节点” → 【编辑租户映射】 # 在弹窗中: # - 上海研发中心:选择“张工(技术总监)” # - 集团总部:选择“李总(CTO)” # 保存配置

参数说明:配置保存后,tenant-core会向pointlion_meta.tenant_node_mapping表插入记录,包含flow_version_id、tenant_code、node_id、approver_user_id四字段。当深圳工厂员工提交申请时,流程引擎依据此映射表,精准将任务推送给上海研发中心的张工(用户ID在t_sh.sys_user中)和集团总部的李总(用户ID在t_group.sys_user中)。若未配置,任务将滞留在tenant-core的待分发队列,超时后触发告警。

4.3 触发真实跨租户流程并验证消息路由

使用Postman或curl模拟深圳工厂员工提交评审申请,观察任务是否正确分发至其他租户。

# 构造申请数据(注意:tenantCode必须为t_sz) curl -X POST "http://gateway.internal/api/v1/flow/start" \ -H "Content-Type: application/json" \ -H "X-Tenant-ID: t_sz" \ -d '{ "flowCode": "GROUP_TECH_REVIEW", "version": "V1.0.0-global", "formData": { "projectName": "智能产线二期", "reviewType": "硬件选型", "applicant": "王五" } }' # 检查上海研发中心库的任务表 mysql -h10.10.1.11 -ut_sz -p t_sh -e "SELECT status, assignee FROM flow_instance WHERE flow_code='GROUP_TECH_REVIEW' ORDER BY create_time DESC LIMIT 1" # 预期status='PENDING', assignee='zhanggong' # 检查集团总部库的任务表 mysql -h10.10.1.10 -ut_group -p t_group -e "SELECT status, assignee FROM flow_instance WHERE flow_code='GROUP_TECH_REVIEW' ORDER BY create_time DESC LIMIT 1" # 预期status='PENDING', assignee='lizong'

关键验证点:X-Tenant-ID请求头必须与申请人所在租户一致,否则tenant-core的租户解析过滤器会拒绝请求。若忘记添加此Header,API将返回401 Unauthorized,错误日志显示Tenant context not found for request。这是新手最常踩的坑,务必在Postman中设置全局Header。


5. 多租户运维避坑指南:5个血泪经验总结

部署点狮OA多租户系统过程中,我们踩过不少坑。这些不是文档里写的“注意事项”,而是线上环境真金白银换来的教训。以下5条按发生频率排序,每条都附带定位方法和修复命令。

5.1 现象:新租户登录后首页空白,浏览器控制台报GET /api/tenant/config 404

原因:tenant-core服务未正确加载租户配置,通常因Nacos配置中心中缺少tenant-group_headquarters.yaml配置文件。点狮OA要求每个租户在Nacos中必须有独立配置文件,即使内容为空。
解决:

# 登录Nacos控制台(http://10.10.1.10:8848),进入配置管理 → 新建配置 # Data ID: tenant-group_headquarters.yaml # Group: DEFAULT_GROUP # 配置格式(必须为YAML,不能是Properties): tenant: code: group_headquarters name: XX集团总部 # 发布后重启tenant-core服务

5.2 现象:跨租户流程中,上海研发中心审批通过后,集团总部任务状态仍为PENDING

原因:Seata全局事务未生效,导致t_sh.flow_instance状态更新成功,但t_group.flow_instance更新因事务回滚失败。根本原因是seata-server的store.db.db-type配置为mysql,但实际连接的是MySQL 8.0,需显式指定驱动类。
解决:

# 修改seata/conf/file.conf # 将store.db.driver-class-name = "com.mysql.jdbc.Driver" # 改为store.db.driver-class-name = "com.mysql.cj.jdbc.Driver" # 并添加store.db.url参数中的时区:?serverTimezone=Asia/Shanghai # 重启seata-server

5.3 现象:集团总部管理员在组织树视图中看不到子公司节点

原因:org_tree_view视图未自动重建。点狮OA在租户注册时调用tenant-core的ViewGeneratorService,但该服务依赖nacos.config.server-addr配置,若配置错误则静默失败。
解决:

# 登录tenant-core服务所在服务器,查看日志 grep "ViewGeneratorService" /var/log/tenant-core/app.log # 若出现"Failed to connect to Nacos config server",修正application.yml中: # spring: # cloud: # nacos: # config: # server-addr: 10.10.1.10:8848,10.10.1.11:8848,10.10.1.12:8848 # 重启tenant-core

5.4 现象:使用CLI创建租户时提示Schema t_sz already exists,但MySQL中确无此库

原因:MySQL的lower_case_table_names参数为1(Linux默认),但点狮OA在生成Schema名时未统一转小写,导致t_sz和t_SZ被视为不同库。CLI先检查t_sz不存在,然后执行CREATE DATABASE t_SZ,再检查时发现t_sz仍不存在,循环报错。
解决:

# 临时修改MySQL配置(需重启MySQL) # 在/etc/my.cnf中添加: [mysqld] lower_case_table_names=0 # 重启MySQL后重新执行CLI命令

5.5 现象:流程设计器中保存全局流程后,部分租户后台看不到该流程

原因:租户缓存未刷新。点狮OA为提升性能,将流程定义缓存在各tenant-core节点的Caffeine本地缓存中,TTL为30分钟。新流程发布后,旧节点可能仍返回空列表。
解决:

# 向所有tenant-core节点发送缓存刷新指令(需配置actuator端点) curl -X POST "http://10.10.1.10:8080/actuator/tenant-cache/refresh" curl -X POST "http://10.10.1.11:8080/actuator/tenant-cache/refresh" curl -X POST "http://10.10.1.12:8080/actuator/tenant-cache/refresh" # 或直接重启所有tenant-core服务(影响较小,因有Nacos健康检查)

6. 集团级治理技巧:用租户标签体系实现动态权限收敛

点狮OA的终极价值不在“能跑通跨租户流程”,而在支撑集团级治理策略落地。比如:财务部要求所有子公司采购流程必须经过集团法务审核;人力资源部要求技术岗晋升需集团CTO终审。这些规则不能硬编码在流程中,而应通过租户标签(Tenant Tag)+ 动态策略引擎实现。这是我在线上环境沉淀出的最实用技巧。

6.1 为租户打标:定义可继承的治理属性

租户标签是点狮OA 3.8版本新增特性,允许为租户附加任意Key-Value对,并支持父子继承。标签不参与业务逻辑,但可被流程引擎、权限中心、审计服务读取。

# 使用CLI为集团总部打标(表示其为策略制定者) ./tenant-admin-cli tag set \ --tenant-code group_headquarters \ --key "governance.role" \ --value "POLICY_OWNER" # 为深圳工厂打标(表示其为执行者,且需法务审核) ./tenant-admin-cli tag set \ --tenant-code sz_factory \ --key "procurement.require_legal_review" \ --value "true" # 为上海研发中心打标(表示其技术岗晋升需集团终审) ./tenant-admin-cli tag set \ --tenant-code sh_rnd \ --key "hr.promotion.require_cto_approval" \ --value "true"

逻辑说明:标签存储在pointlion_meta.tenant_tag表,结构为(tenant_code, tag_key, tag_value, inherited_from)。当深圳工厂员工发起采购流程时,流程引擎会自动读取其procurement.require_legal_review标签值,若为true,则在流程定义中动态插入“集团法务审核”节点。该节点不写死在流程图中,而是由策略引擎实时注入,实现规则与流程解耦。

6.2 在流程中引用标签:编写动态节点注入规则

点狮OA的流程引擎支持Groovy脚本扩展。在流程设计器的“全局流程”中,可为任意网关节点添加脚本,根据租户标签决定是否插入审批节点。

// 在“采购申请”节点后的网关中,添加以下Groovy脚本 def tenantCode = execution.getVariable("applicant.tenantCode") def tagService = ApplicationContextUtil.getBean("tenantTagService") def requireLegal = tagService.getTagValue(tenantCode, "procurement.require_legal_review") if ("true".equals(requireLegal)) { // 动态注入集团法务审核节点 execution.setVariable("inject_legal_node", true) return "need_legal_review" } else { return "no_legal_review" }

参数说明:ApplicationContextUtil.getBean是点狮OA封装的Spring上下文工具类,确保在流程执行时能安全获取服务实例。inject_legal_node是流程变量,后续节点可通过${inject_legal_node}判断是否启用。此方式比在流程图中画一堆条件分支更清晰,也避免了流程版本爆炸。

6.3 建立标签治理看板:用SQL快速审计全集团策略覆盖

集团IT部门需定期检查各子公司标签配置是否合规。点狮OA未提供图形化看板,但可通过一条SQL秒级生成审计报告。

-- 生成采购流程法务审核覆盖报告 SELECT t.tenant_code, t.tenant_name, COALESCE(tt.tag_value, 'false') AS require_legal_review, CASE WHEN COALESCE(tt.tag_value, 'false') = 'true' THEN '✅ 已启用' ELSE '❌ 未启用(需整改)' END AS status FROM pointlion_meta.tenant_info t LEFT JOIN pointlion_meta.tenant_tag tt ON t.tenant_code = tt.tenant_code AND tt.tag_key = 'procurement.require_legal_review' WHERE t.status = 'ACTIVE' ORDER BY status DESC;

实战价值:某次季度审计中,我们用此SQL 10秒内发现3家子公司未配置procurement.require_legal_review标签,立即通知其IT负责人补标。若依赖人工登录各租户后台检查,预计耗时2小时以上。这就是基础设施级治理能力带来的效率跃迁。

我坚持在每个新上线的集团客户项目中,第一周必做三件事:1)用CLI批量打标;2)为所有高频流程编写标签注入脚本;3)将上述SQL固化为定时邮件报表。这套组合拳让集团CIO第一次在月度汇报中,用一页PPT说清了“12家子公司采购风控策略执行率100%”。技术的价值从来不是炫技,而是把模糊的管理要求,变成可执行、可验证、可追溯的代码逻辑。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询