16 KiB
16 KiB
Salesforce 多系统配置设计
元数据
- 设计编号:2026-01-21-003-01
- 需求编号:2026-01-21-003-01
- 创建时间:2026-01-21
- 创建人:SSOT 架构师
- 状态:待开始
- 优先级:高
设计概述
本设计文档描述了 Salesforce 多系统配置功能的技术实现方案。该功能支持配置多个不同类型的 Salesforce 系统,支持用户自定义系统类型,支持区分源 org 和目标 org(支持同一系统既是源 org 又是目标 org),支持配置系统名称、自定义类型、登录方式等,支持启用/停用系统,系统配置变更无需审批流程,系统配置无权限限制,密码、安全令牌等敏感信息使用 EncryptUtils 加密存储。
设计目标
- 多系统配置:支持配置多个不同类型的 Salesforce 系统
- 用户自定义类型:支持用户自定义系统类型(不限于 production/sandbox/developer)
- 源目标区分:支持区分源 org 和目标 org,支持同一系统既是源 org 又是目标 org
- 系统管理:支持配置系统名称、自定义类型、登录方式等
- 状态管理:支持启用/停用系统
- 无审批流程:系统配置变更无需审批流程
- 无权限限制:系统配置无权限限制
- 敏感信息加密:密码、安全令牌等敏感信息使用 EncryptUtils 加密存储
架构设计
系统架构
┌─────────────────────────────────────────────────────────────────┐
│ Controller 层 │
│ DataiSfSystemConfigController │
│ - 添加系统配置 │
│ - 编辑系统配置 │
│ - 删除系统配置 │
│ - 查询系统配置列表 │
│ - 查询系统配置详情 │
│ - 启用/停用系统 │
│ - 查询源 org 列表 │
│ - 查询目标 org 列表 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Service 层 │
│ IDataiSfSystemConfigService │
│ DataiSfSystemConfigServiceImpl │
│ - 系统配置 CRUD 操作 │
│ - 敏感信息加密/解密 │
│ - 系统名称唯一性校验 │
│ - 源 org / 目标 org 筛选 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Mapper 层 │
│ DataiSfSystemConfigMapper │
│ - 数据库 CRUD 操作 │
│ - 分页查询 │
│ - 条件筛选查询 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 数据库层 │
│ datai_sf_system_config (Salesforce 系统配置表) │
└─────────────────────────────────────────────────────────────────┘
模块设计
datai-salesforce-auth
├─ controller
│ └─ DataiSfSystemConfigController (系统配置控制器)
├─ service
│ ├─ IDataiSfSystemConfigService (系统配置服务接口)
│ └─ impl
│ └─ DataiSfSystemConfigServiceImpl (系统配置服务实现)
├─ mapper
│ └─ DataiSfSystemConfigMapper (系统配置 Mapper)
├─ model
│ ├─ domain
│ │ └─ DataiSfSystemConfig (系统配置实体)
│ ├─ dto
│ │ └─ DataiSfSystemConfigDto (系统配置 DTO)
│ └─ vo
│ └─ DataiSfSystemConfigVo (系统配置 VO)
└─ resources
└─ mapper
└─ auth
└─ DataiSfSystemConfigMapper.xml (MyBatis XML)
数据库设计
表结构
datai_sf_system_config(Salesforce 系统配置表)
CREATE TABLE `datai_sf_system_config` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`system_name` VARCHAR(100) NOT NULL COMMENT '系统名称(唯一)',
`system_type` VARCHAR(50) NOT NULL COMMENT '系统类型(用户自定义)',
`org_type` CHAR(1) NOT NULL COMMENT '组织类型(S=源 org T=目标 org,可同时选中)',
`login_type` VARCHAR(20) NOT NULL COMMENT '登录类型(oauth2/session_id/cli)',
`client_id` VARCHAR(255) NULL COMMENT 'OAuth 客户端 ID',
`client_secret` VARCHAR(500) NULL COMMENT 'OAuth 客户端密钥(使用 EncryptUtils 加密存储)',
`username` VARCHAR(100) NULL COMMENT '用户名',
`password` VARCHAR(500) NULL COMMENT '密码(使用 EncryptUtils 加密存储)',
`security_token` VARCHAR(500) NULL COMMENT '安全令牌(使用 EncryptUtils 加密存储)',
`session_id` VARCHAR(500) NULL COMMENT 'Session ID(Access Token,由 Salesforce 登录后返回)',
`server_url` VARCHAR(500) NULL COMMENT '服务器 URL(Instance URL)',
`access_token` VARCHAR(500) NULL COMMENT '访问令牌(Session ID)',
`refresh_token` VARCHAR(500) NULL COMMENT '刷新令牌',
`token_expires_at` DATETIME NULL COMMENT '令牌过期时间',
`sf_user_id` VARCHAR(100) NULL COMMENT 'Salesforce 用户 ID(用于缓存键)',
`user_id` VARCHAR(100) NULL COMMENT '用户 ID',
`org_id` VARCHAR(100) NULL COMMENT '组织 ID',
`org_name` VARCHAR(200) NULL COMMENT '组织名称',
`status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
`sort_order` INT NULL COMMENT '排序',
`create_by` VARCHAR(64) NOT NULL COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` VARCHAR(64) NOT NULL COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE COMMENT '主键索引',
UNIQUE INDEX `uk_system_name` (`system_name`) USING BTREE COMMENT '唯一约束',
INDEX `idx_system_type` (`system_type`) USING BTREE COMMENT '普通索引',
INDEX `idx_org_type` (`org_type`) USING BTREE COMMENT '普通索引',
INDEX `idx_login_type` (`login_type`) USING BTREE COMMENT '普通索引',
INDEX `idx_status` (`status`) USING BTREE COMMENT '普通索引'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'Salesforce 系统配置表' ROW_FORMAT = DYNAMIC;
索引设计
- 主键索引:
id- 主键索引 - 唯一索引:
uk_system_name- 系统名称唯一约束 - 普通索引:
idx_system_type- 系统类型索引idx_org_type- 组织类型索引idx_login_type- 登录类型索引idx_status- 状态索引
接口设计
Controller 层接口
DataiSfSystemConfigController
@RestController
@RequestMapping("/api/salesforce/system/config")
@Api(tags = "Salesforce 系统配置管理")
public class DataiSfSystemConfigController {
/**
* 添加系统配置
*/
@PostMapping
public AjaxResult add(@RequestBody DataiSfSystemConfigDto config);
/**
* 编辑系统配置
*/
@PutMapping("/{id}")
public AjaxResult edit(@PathVariable Long id, @RequestBody DataiSfSystemConfigDto config);
/**
* 删除系统配置
*/
@DeleteMapping("/{id}")
public AjaxResult remove(@PathVariable Long id);
/**
* 查询系统配置列表
*/
@GetMapping("/list")
public TableDataInfo list(DataiSfSystemConfigDto config);
/**
* 查询系统配置详情
*/
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id);
/**
* 启用系统
*/
@PutMapping("/{id}/enable")
public AjaxResult enable(@PathVariable Long id);
/**
* 停用系统
*/
@PutMapping("/{id}/disable")
public AjaxResult disable(@PathVariable Long id);
/**
* 查询源 org 列表
*/
@GetMapping("/source")
public TableDataInfo listSource();
/**
* 查询目标 org 列表
*/
@GetMapping("/target")
public TableDataInfo listTarget();
}
Service 层接口
IDataiSfSystemConfigService
public interface IDataiSfSystemConfigService {
/**
* 查询系统配置
*/
DataiSfSystemConfig selectDataiSfSystemConfigById(Long id);
/**
* 查询系统配置列表
*/
List<DataiSfSystemConfig> selectDataiSfSystemConfigList(DataiSfSystemConfig config);
/**
* 新增系统配置
*/
int insertDataiSfSystemConfig(DataiSfSystemConfig config);
/**
* 修改系统配置
*/
int updateDataiSfSystemConfig(DataiSfSystemConfig config);
/**
* 批量删除系统配置
*/
int deleteDataiSfSystemConfigByIds(Long[] ids);
/**
* 删除系统配置
*/
int deleteDataiSfSystemConfigById(Long id);
/**
* 校验系统名称是否唯一
*/
boolean checkSystemNameUnique(DataiSfSystemConfig config);
/**
* 查询源 org 列表
*/
List<DataiSfSystemConfig> selectSourceOrgList();
/**
* 查询目标 org 列表
*/
List<DataiSfSystemConfig> selectTargetOrgList();
}
核心逻辑设计
敏感信息加密/解密
public class DataiSfSystemConfigServiceImpl implements IDataiSfSystemConfigService {
@Autowired
private EncryptUtils encryptUtils;
@Override
public int insertDataiSfSystemConfig(DataiSfSystemConfig config) {
encryptSensitiveFields(config);
return dataiSfSystemConfigMapper.insertDataiSfSystemConfig(config);
}
@Override
public int updateDataiSfSystemConfig(DataiSfSystemConfig config) {
encryptSensitiveFields(config);
return dataiSfSystemConfigMapper.updateDataiSfSystemConfig(config);
}
@Override
public DataiSfSystemConfig selectDataiSfSystemConfigById(Long id) {
DataiSfSystemConfig config = dataiSfSystemConfigMapper.selectDataiSfSystemConfigById(id);
if (config != null) {
decryptSensitiveFields(config);
}
return config;
}
private void encryptSensitiveFields(DataiSfSystemConfig config) {
if (StringUtils.isNotEmpty(config.getClientSecret())) {
config.setClientSecret(EncryptUtils.encrypt(config.getClientSecret()));
}
if (StringUtils.isNotEmpty(config.getPassword())) {
config.setPassword(EncryptUtils.encrypt(config.getPassword()));
}
if (StringUtils.isNotEmpty(config.getSecurityToken())) {
config.setSecurityToken(EncryptUtils.encrypt(config.getSecurityToken()));
}
}
private void decryptSensitiveFields(DataiSfSystemConfig config) {
if (StringUtils.isNotEmpty(config.getClientSecret())) {
config.setClientSecret(EncryptUtils.decrypt(config.getClientSecret()));
}
if (StringUtils.isNotEmpty(config.getPassword())) {
config.setPassword(EncryptUtils.decrypt(config.getPassword()));
}
if (StringUtils.isNotEmpty(config.getSecurityToken())) {
config.setSecurityToken(EncryptUtils.decrypt(config.getSecurityToken()));
}
}
}
系统名称唯一性校验
@Override
public boolean checkSystemNameUnique(DataiSfSystemConfig config) {
Long configId = StringUtils.isNull(config.getId()) ? -1L : config.getId();
DataiSfSystemConfig info = dataiSfSystemConfigMapper.selectDataiSfSystemConfigBySystemName(config.getSystemName());
if (StringUtils.isNotNull(info) && !info.getId().equals(configId)) {
return false;
}
return true;
}
源 org / 目标 org 筛选
@Override
public List<DataiSfSystemConfig> selectSourceOrgList() {
DataiSfSystemConfig query = new DataiSfSystemConfig();
query.setOrgType("S");
query.setStatus("0");
List<DataiSfSystemConfig> list = dataiSfSystemConfigMapper.selectDataiSfSystemConfigList(query);
list.forEach(this::decryptSensitiveFields);
return list;
}
@Override
public List<DataiSfSystemConfig> selectTargetOrgList() {
DataiSfSystemConfig query = new DataiSfSystemConfig();
query.setOrgType("T");
query.setStatus("0");
List<DataiSfSystemConfig> list = dataiSfSystemConfigMapper.selectDataiSfSystemConfigList(query);
list.forEach(this::decryptSensitiveFields);
return list;
}
业务规则设计
- 系统名称唯一性:系统名称(system_name)必须唯一
- 用户自定义类型:系统类型(system_type)由用户自定义,不限制为固定值
- 源目标区分:每个系统可以标记为源 org 或目标 org,支持同一系统既是源 org 又是目标 org
- 敏感信息加密:密码、安全令牌等敏感信息必须使用 EncryptUtils 加密存储
- 无审批流程:系统配置变更无需审批流程
- 无权限限制:系统配置无权限限制
- 停用系统限制:停用的系统不能用于登录
性能设计
- 索引优化:为系统名称、系统类型、org 类型、登录类型、状态等字段创建索引
- 分页查询:系统配置列表支持分页查询,避免一次性加载大量数据
- 缓存策略:系统配置数据可以缓存到 Redis,减少数据库查询次数
安全设计
- 敏感信息加密:密码、安全令牌等敏感信息使用 EncryptUtils 加密存储
- 数据传输安全:使用 HTTPS 协议传输数据
- SQL 注入防护:使用 MyBatis 的参数化查询,防止 SQL 注入
- XSS 防护:对用户输入进行 XSS 过滤
测试设计
单元测试
- 测试系统配置的 CRUD 操作
- 测试敏感信息的加密/解密
- 测试系统名称唯一性校验
- 测试源 org / 目标 org 筛选
集成测试
- 测试系统配置的完整流程
- 测试与登录功能的集成
- 测试与缓存功能的集成
依赖关系
- 依赖
datai-common模块的EncryptUtils工具类 - 依赖
datai-system模块的基础功能 - 依赖
datai-salesforce-common模块的 Salesforce API 封装
后续扩展
- 支持系统配置的导入/导出功能
- 支持系统配置的批量操作
- 支持系统配置的版本管理
- 支持系统配置的审批流程(可选)
- 支持系统配置的权限管理(可选)