datai/docs/design/2026-01-21-003-01-salesforce-multi-system-config-design.md

16 KiB
Raw Blame History

Salesforce 多系统配置设计

元数据

  • 设计编号2026-01-21-003-01
  • 需求编号2026-01-21-003-01
  • 创建时间2026-01-21
  • 创建人SSOT 架构师
  • 状态:待开始
  • 优先级:高

设计概述

本设计文档描述了 Salesforce 多系统配置功能的技术实现方案。该功能支持配置多个不同类型的 Salesforce 系统,支持用户自定义系统类型,支持区分源 org 和目标 org支持同一系统既是源 org 又是目标 org支持配置系统名称、自定义类型、登录方式等支持启用/停用系统,系统配置变更无需审批流程,系统配置无权限限制,密码、安全令牌等敏感信息使用 EncryptUtils 加密存储。

设计目标

  1. 多系统配置:支持配置多个不同类型的 Salesforce 系统
  2. 用户自定义类型:支持用户自定义系统类型(不限于 production/sandbox/developer
  3. 源目标区分:支持区分源 org 和目标 org支持同一系统既是源 org 又是目标 org
  4. 系统管理:支持配置系统名称、自定义类型、登录方式等
  5. 状态管理:支持启用/停用系统
  6. 无审批流程:系统配置变更无需审批流程
  7. 无权限限制:系统配置无权限限制
  8. 敏感信息加密:密码、安全令牌等敏感信息使用 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_configSalesforce 系统配置表)

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 IDAccess Token由 Salesforce 登录后返回)',
  `server_url` VARCHAR(500) NULL COMMENT '服务器 URLInstance 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;
}

业务规则设计

  1. 系统名称唯一性系统名称system_name必须唯一
  2. 用户自定义类型系统类型system_type由用户自定义不限制为固定值
  3. 源目标区分:每个系统可以标记为源 org 或目标 org支持同一系统既是源 org 又是目标 org
  4. 敏感信息加密:密码、安全令牌等敏感信息必须使用 EncryptUtils 加密存储
  5. 无审批流程:系统配置变更无需审批流程
  6. 无权限限制:系统配置无权限限制
  7. 停用系统限制:停用的系统不能用于登录

性能设计

  1. 索引优化为系统名称、系统类型、org 类型、登录类型、状态等字段创建索引
  2. 分页查询:系统配置列表支持分页查询,避免一次性加载大量数据
  3. 缓存策略:系统配置数据可以缓存到 Redis减少数据库查询次数

安全设计

  1. 敏感信息加密:密码、安全令牌等敏感信息使用 EncryptUtils 加密存储
  2. 数据传输安全:使用 HTTPS 协议传输数据
  3. SQL 注入防护:使用 MyBatis 的参数化查询,防止 SQL 注入
  4. XSS 防护:对用户输入进行 XSS 过滤

测试设计

单元测试

  • 测试系统配置的 CRUD 操作
  • 测试敏感信息的加密/解密
  • 测试系统名称唯一性校验
  • 测试源 org / 目标 org 筛选

集成测试

  • 测试系统配置的完整流程
  • 测试与登录功能的集成
  • 测试与缓存功能的集成

依赖关系

  • 依赖 datai-common 模块的 EncryptUtils 工具类
  • 依赖 datai-system 模块的基础功能
  • 依赖 datai-salesforce-common 模块的 Salesforce API 封装

后续扩展

  • 支持系统配置的导入/导出功能
  • 支持系统配置的批量操作
  • 支持系统配置的版本管理
  • 支持系统配置的审批流程(可选)
  • 支持系统配置的权限管理(可选)