# OpsxSQL 平台配置系统文档 > 本文档详细说明 OpsxSQL 平台的三套配置体系:`system_settings` 系统设置、`audit_rules` 审核规则、`ldap_configs` LDAP 配置。 > > 最后更新:2025-06 --- ## 目录 - [一、配置体系总览](#一配置体系总览) - [二、查询控制 (query)](#二查询控制-query) - [三、审核规则 (audit_rules)](#三审核规则-audit_rules) - [四、数据脱敏 (data_masking)](#四数据脱敏-data_masking) - [五、执行器 (executor)](#五执行器-executor) - [六、Ghost / OSC 在线 DDL (ghost)](#六ghost--osc-在线-ddl-ghost) - [七、安全策略 (security)](#七安全策略-security) - [八、日志清理 (cleanup)](#八日志清理-cleanup) - [九、LDAP 配置 (ldap)](#九ldap-配置-ldap) - [十、未引用 / 待实现配置](#十未引用--待实现配置) - [附录:数据模型](#附录数据模型) --- ## 一、配置体系总览 | 配置体系 | 存储表 | 配置项数 | 用途 | |----------|--------|---------|------| | 系统设置 | `system_settings` | 42 项(7 个分组) | 平台运行参数 | | 审核规则 | `audit_rules` | 34 条(4 种 DB 类型) | SQL 提交审核拦截 | | LDAP 配置 | `ldap_configs` | 独立 CRUD | LDAP 认证集成 | ### system_settings 分组概览 | 分组 | 配置项数 | 有效引用 | 状态 | |------|---------|---------|------| | `query` 查询控制 | 5 | 4 | ⚠️ `query_max_rows_examined` 未引用 | | `security` 安全策略 | 5 | 5 | ✅ 全部有效 | | `data_masking` 数据脱敏 | 2 | 2 | ✅ 全部有效 | | `cleanup` 日志清理 | 4 | 4 | ✅ 全部有效 | | `executor` 执行器 | 4 | 2 | ⚠️ `batch_size`/`backup` 未引用 | | `ghost` 在线 DDL | 13 | 13 | ✅ 全部有效 | | `ldap` LDAP | 9 | 0 | ❌ 全部冗余(LDAP 使用独立 `ldap_configs` 表)| ### 配置读写 API | 操作 | 端点 | 说明 | |------|------|------| | 读取所有设置 | `GET /api/v1/settings` | 按 `group` 字段分组返回 | | 批量更新设置 | `PUT /api/v1/settings` | 接收 `[{key, value}, ...]` 数组 | | 读取审核规则 | `GET /api/v1/audit-rules?db_type=mysql` | 可按 `db_type` 过滤 | 配置均在服务启动时通过 `seedDefaultSettings()` / `seedAuditRules()` 幂等初始化。 --- ## 二、查询控制 (query) 查询控制配置作用于在线查询功能(`instance_detail.go`),限制用户对数据库的查询行为。 | Key | 类型 | 默认值 | 说明 | 引用位置 | |-----|------|--------|------|----------| | `query_limit_max` | number | `1000` | SELECT 查询返回的最大行数,超过自动截断 | `instance_detail.go:525` | | `query_timeout` | number | `30` | 单次查询最长执行时间(秒),超时自动终止 | `instance_detail.go:616-617` | | `query_auto_limit` | boolean | `true` | 用户未写 LIMIT 时自动追加,防止全表扫描 | `instance_detail.go:526` | | `query_dangerous_pattern` | boolean | `true` | 检测不带 WHERE 的 DELETE/UPDATE 等高危操作 | `instance_detail.go:540` | | `query_max_rows_examined` | number | `1000000` | 单次查询允许扫描的最大行数 | ⚠️ **待实现** — 仅 seed 定义 | ### 作用机制 **query_limit_max** — 查询请求中的 `limit` 参数不能超过此值: ```go maxLimit := getSettingInt("query_limit_max", 1000) if input.Limit <= 0 { input.Limit = maxLimit } // ... 后续截断到 maxLimit ``` **query_auto_limit** — 当用户未指定 LIMIT 时,自动追加平台默认上限: ```go autoLimit := getSetting("query_auto_limit", "true") == "true" ``` **query_timeout** — 使用 Go `context.WithTimeout` 实现硬超时: ```go timeoutSec := getSettingInt("query_timeout", 30) ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutSec)*time.Second) ``` **query_dangerous_pattern** — 在执行前检测 SQL 中是否包含高危操作关键字: ```go if getSetting("query_dangerous_pattern", "true") == "true" { for _, pat := range []string{"DELETE FROM", "UPDATE ", "DROP ", "TRUNCATE", "ALTER ", "RENAME "} { // ... 检测并拦截 } } ``` --- ## 三、审核规则 (audit_rules) ### 概述 审核规则存储在 `audit_rules` 表中,在 **工单提交时**(`CreateTicket`)自动触发检查。系统预置 34 条规则,覆盖 MySQL、PostgreSQL、Redis、MongoDB 四种数据库类型。 ### 匹配机制 ``` CreateTicket → 加载 audit_rules WHERE db_type=? AND is_enabled=true → 对每条 SQL 语句逐一匹配 → Pattern 正则匹配 ⟶ value=where_check 时使用字符串检测 ``` **正则匹配流程**(`ticket.go:299-303`): ```go for _, rule := range rules { matched, _ := regexp.MatchString(*rule.Pattern, checkStmt) if matched { /* 规则命中 */ } } ``` **WHERE 特殊检测**(`ticket.go:305-314`): 由于 Go 的 RE2 正则引擎不支持负向前瞻(negative lookahead),无法用正则"匹配不含 WHERE 的 DELETE"。因此采用两步检测: 1. 正则匹配 `DELETE FROM` / `UPDATE ... SET` 等基础模式 2. 若规则 `value` 字段为 `"where_check"`,则用 `strings.Contains(upperSQL, "WHERE")` 判断是否包含 WHERE 子句 3. 包含 WHERE → 跳过(安全);不包含 → 拦截 ### 规则字段说明 | 字段 | 类型 | 说明 | |------|------|------| | `name` | string | 规则名称 | | `description` | text | 规则描述 | | `rule_type` | string | 规则类型:DDL / DML / DCL / DQL / performance / security | | `severity` | string | 严重级别:error / warning / info | | `db_type` | string | 目标数据库类型:mysql / postgresql / redis / mongodb | | `pattern` | text | 正则表达式(RE2 语法) | | `is_enabled` | boolean | 是否启用 | | `message` | string(500) | 命中时的提示消息 | | `value` | string(255) | 处理方式:`reject`(拦截) / `review`(需审核) / `warn`(警告) / `where_check`(WHERE检测) | | `code` | string(50) | 规则编码(预留) | | `config_json` | text | 扩展配置 JSON(预留) | ### MySQL 审核规则(12 条) | 规则名称 | 类型 | 严重级别 | Pattern | Value | 说明 | |----------|------|---------|---------|-------|------| | 禁止 DROP TABLE | DDL | error | `(?i)^\s*DROP\s+TABLE` | reject | 防止数据永久丢失 | | 禁止 DROP DATABASE | DDL | error | `(?i)^\s*DROP\s+DATABASE` | reject | 禁止删库 | | 禁止 TRUNCATE TABLE | DDL | error | `(?i)^\s*TRUNCATE\s+TABLE?` | reject | 请用 DELETE 逐批删除 | | ALTER TABLE 需审核 | DDL | warning | `(?i)^\s*ALTER\s+TABLE` | review | 需审批后执行 | | 禁止 DELETE 无 WHERE | DML | error | `(?i)^\s*DELETE\s+FROM?\s+\S+\s*$` | reject | 必须包含 WHERE 条件 | | 禁止 UPDATE 无 WHERE | DML | error | `(?i)^\s*UPDATE\s+\S+\s+SET\s+.*\s*$` | reject | 必须包含 WHERE 条件 | | SELECT * 建议 | DQL | info | `(?i)^\s*SELECT\s+\*\s+FROM` | warn | 建议明确指定查询字段 | | INSERT 需指定列 | DML | warning | `(?i)^\s*INSERT\s+INTO\s+\S+\s+VALUES` | review | 应明确指定列名 | | 禁止 GRANT ALL | DCL | error | `(?i)^\s*GRANT\s+ALL` | reject | 禁止授予全部权限 | | 大表变更警告 | performance | warning | _(空 pattern)_ | warn | 影响行数大时警告 | | 禁止不带 LIMIT 的 DELETE | DML | warning | `(?i)^\s*DELETE\s+FROM\s+\S+\s+WHERE` | warn | 建议添加 LIMIT 分批删除 | > **注意**:seed 中 MySQL 预置 12 条,实际按 `len(allRules["mysql"])` 计算。上表列出 11 条有明确 pattern 的规则,另含 1 条 "大表变更警告"(无 pattern,作为提示性规则存在)。 ### PostgreSQL 审核规则(7 条) | 规则名称 | 类型 | 严重级别 | Value | 说明 | |----------|------|---------|-------|------| | 禁止 DROP TABLE | DDL | error | reject | 同 MySQL | | 禁止 DROP DATABASE | DDL | error | reject | 同 MySQL | | 禁止 DELETE 无 WHERE | DML | error | reject | 同 MySQL | | 禁止 UPDATE 无 WHERE | DML | error | reject | 同 MySQL | | ALTER TABLE 需审核 | DDL | warning | review | 同 MySQL | | SELECT * 建议 | DQL | info | warn | 同 MySQL | | 禁止 GRANT ALL | DCL | error | reject | 同 MySQL | ### Redis 审核规则(4 条) | 规则名称 | 类型 | 严重级别 | Pattern | Value | 说明 | |----------|------|---------|---------|-------|------| | 禁止 FLUSHALL | DDL | error | `(?i)^FLUSHALL` | reject | 禁止清空所有数据 | | 禁止 FLUSHDB | DDL | error | `(?i)^FLUSHDB` | reject | 清空数据库需审批 | | 禁止 CONFIG | security | error | `(?i)^CONFIG\s` | reject | 配置修改需走审批 | | KEYS 命令警告 | performance | error | `(?i)^KEYS\s` | reject | 生产环境禁止 KEYS,请使用 SCAN | ### MongoDB 审核规则(4 条) | 规则名称 | 类型 | 严重级别 | Pattern | Value | 说明 | |----------|------|---------|---------|-------|------| | 禁止 dropDatabase | DDL | error | `dropDatabase` | reject | 禁止删除数据库 | | 禁止 drop 集合 | DDL | error | `(?i)\.drop\(\)` | reject | 禁止删除集合 | | remove 需带条件 | DML | error | `(?i)remove\(\s*\)` | reject | remove 必须带查询条件 | | updateMany 需审核 | DML | warning | `(?i)updateMany` | review | 批量更新需审批 | --- ## 四、数据脱敏 (data_masking) 数据脱敏功能作用于在线查询返回结果,自动将敏感字段的内容替换为 `***`。 | Key | 类型 | 默认值 | 说明 | 引用位置 | |-----|------|--------|------|----------| | `data_masking_enabled` | boolean | `true` | 全局脱敏开关 | `instance_detail.go:1522-1525` | | `data_masking_sensitive_fields` | string | _(见下方)_ | 全局敏感字段列表(逗号分隔) | `instance_detail.go:1531-1534` | **默认敏感字段列表**: ``` mobile, concat_mobile, email_alias, email, password, ga_key, private_key, secret, secret_key, key_snow, telephone, username, real_name, token, two_factor_secret, content, phone ``` ### 作用机制 `applyDataMasking()` 函数(`instance_detail.go:1520`)执行以下逻辑: 1. 读取 `data_masking_enabled`,若非 `true` 则跳过 2. 读取 `data_masking_sensitive_fields`,按逗号拆分为字段名列表 3. 合并实例级别 `instance.mask_fields` 的字段 4. 遍历查询结果的每一行每一列,若列名(不区分大小写)匹配敏感字段,则将值替换为 `***` **字段匹配方式**:列名包含(contains)敏感字段名即匹配,不区分大小写。 **优先级**:全局敏感字段 ∪ 实例级 `mask_fields`,两者合并生效。 --- ## 五、执行器 (executor) 执行器配置控制工单中 SQL 语句的实际执行行为。 | Key | 类型 | 默认值 | 说明 | 引用位置 | 状态 | |-----|------|--------|------|----------|------| | `executor_timeout` | number | `300` | SQL 执行的最大等待时间(秒) | `ticket.go:725,766` | ✅ 有效 | | `executor_dry_run` | boolean | `true` | 执行前先 EXPLAIN 验证 SQL 语法 | `ticket.go:770` | ✅ 有效 | | `executor_batch_size` | number | `100` | DML 批量执行时每批的行数 | _(无)_ | ⚠️ 待实现 | | `executor_backup` | boolean | `true` | DML 执行前自动备份受影响数据 | _(无)_ | ⚠️ 待实现 | ### 作用机制 **executor_timeout** — 为每个 SQL 语句创建带超时的 context: ```go // OSC (gh-ost) 路径 execTimeout := getSettingInt("executor_timeout", 300) ctx, cancel := context.WithTimeout(context.Background(), time.Duration(execTimeout)*time.Second) // 原生执行路径 execTimeout := getSettingInt("executor_timeout", 300) ctx, cancel := context.WithTimeout(context.Background(), time.Duration(execTimeout)*time.Second) ``` **executor_dry_run** — 对 DDL 语句执行 EXPLAIN 预检查: ```go if getSetting("executor_dry_run", "true") == "true" { ddlPrefixes := []string{"CREATE", "ALTER", "DROP", "TRUNCATE", "RENAME"} // 对每条 DDL 语句执行 EXPLAIN,语法错误则拦截 } ``` --- ## 六、Ghost / OSC 在线 DDL (ghost) Ghost 配置控制 [gh-ost](https://github.com/github/gh-ost) 在线 DDL 变更工具的默认参数。共 13 项配置,全部在 `ghost.go` 的 `applyGhostSettings()` 函数和 OSC 触发逻辑中引用。 ### 基本设置 | Key | 类型 | 默认值 | 说明 | 引用位置 | |-----|------|--------|------|----------| | `ghost_enabled` | boolean | `false` | 启用 gh-ost 在线 DDL 变更工具 | `ticket.go` (OSC 触发判断) | | `ghost_path` | string | `gh-ost` | gh-ost 二进制文件路径 | `ghost.go` (任务创建) | | `ghost_default_mode` | string | `dry_run` | 默认执行模式:`dry_run`(预演) / `execute`(直接执行) | `ghost.go` (任务创建) | | `ghost_osc_priority` | string | `native_first` | OSC 优先级策略:`native_first` / `ghost_first` / `ghost_only` | `ticket.go` (OSC 触发判断) | | `ghost_env_mode` | string | `development` | 环境模式:`development` / `staging` / `production` | `ghost.go` (任务创建) | | `ghost_cloud_type` | string | `self_hosted` | 部署类型:`self_hosted` / `rds` / `cloud` | `ghost.go` (任务创建) | ### 自动触发 | Key | 类型 | 默认值 | 说明 | 引用位置 | |-----|------|--------|------|----------| | `ghost_auto_trigger_rows` | number | `10` | 表行数超过此阈值(万行)自动推荐使用 OSC | `ticket.go` (大表检测) | | `ghost_auto_trigger_ddl` | string | `ADD COLUMN,MODIFY COLUMN,ADD INDEX` | 自动触发 OSC 的 DDL 操作类型列表(逗号分隔) | `ticket.go` (DDL 类型匹配) | ### 性能调优 | Key | 类型 | 默认值 | 说明 | 引用位置 | |-----|------|--------|------|----------| | `ghost_default_chunk_size` | number | `1000` | 每次拷贝的行数 | `ghost.go:387` (`applyGhostSettings`) | | `ghost_max_load` | string | `Threads_running=25` | 超过此负载暂停拷贝 | `ghost.go:391` | | `ghost_critical_load` | string | `Threads_running=50` | 超过此负载立即停止 | `ghost.go:395` | | `ghost_allow_on_master` | boolean | `true` | 是否允许直接在主库运行 gh-ost | `ghost.go:403` | | `ghost_max_lag_millis` | number | `1500` | 从库复制延迟超过此值(ms)暂停拷贝 | `ghost.go:399` | ### 作用机制 **自动触发 OSC 流程**(`ticket.go`): 1. 检查 `ghost_enabled` 是否启用 2. 检查 SQL 是否为 ALTER TABLE 类型 3. 检查 DDL 操作类型是否在 `ghost_auto_trigger_ddl` 列表中 4. 检查目标表行数是否超过 `ghost_auto_trigger_rows`(万) 5. 根据 `ghost_osc_priority` 决定使用原生 ALTER 还是 gh-ost **参数注入流程**(`ghost.go:applyGhostSettings`): ```go func applyGhostSettings(task *ghost.GhOstTask) { task.ChunkSize = getSettingInt("ghost_default_chunk_size", 1000) task.MaxLoad = getSetting("ghost_max_load", "") task.CriticalLoad = getSetting("ghost_critical_load", "") task.MaxLagMillis = getSettingInt("ghost_max_lag_millis", 1500) task.AllowOnMaster = getSetting("ghost_allow_on_master", "true") == "true" } ``` --- ## 七、安全策略 (security) 安全策略配置控制用户登录和认证行为,全部在 `auth.go`(handler)和 `middleware/auth.go` 中引用。 | Key | 类型 | 默认值 | 说明 | 引用位置 | |-----|------|--------|------|----------| | `login_max_attempts` | number | `5` | 连续登录失败达到此次数后锁定账号 | `auth.go:34,365` | | `login_lockout_minutes` | number | `30` | 账号锁定后的持续时长(分钟) | `auth.go:35,366` | | `password_min_length` | number | `8` | 用户密码的最短字符数 | `auth.go` (密码校验) | | `password_require_complex` | boolean | `true` | 要求密码包含大小写字母、数字和特殊字符 | `auth.go` (密码校验) | | `session_timeout_hours` | number | `24` | JWT Token 有效期(小时) | `middleware/auth.go:20` | ### 作用机制 **登录锁定流程**(`auth.go`): 1. 登录时检查 `login_max_attempts` 和 `login_lockout_minutes` 2. 密码错误时调用 `handleFailedLogin()`,递增 `FailedLoginAttempts` 3. 达到 `login_max_attempts` 时,设置 `LockedUntil = now + lockout_minutes` 4. 账号锁定期间拒绝登录,返回剩余锁定时间 **会话超时**(`middleware/auth.go`): ```go func getSessionTimeoutHours() int { // 从 system_settings 读取 session_timeout_hours // 用于 JWT Token 的过期时间计算 } ``` --- ## 八、日志清理 (cleanup) 清理配置控制各类日志和工单数据的自动保留期限。全部在 `ghost.go`(清理定时任务)和 `main.go`(seed)中引用。 | Key | 类型 | 默认值 | 说明 | 引用位置 | |-----|------|--------|------|----------| | `ticket_retention_days` | number | `180` | 超过此天数的已完成/已关闭工单将被清理 | `ghost.go` (清理任务) | | `audit_log_retention_days` | number | `365` | 超过此天数的审计日志将被清理 | `ghost.go` (清理任务) | | `query_history_retention_days` | number | `90` | 超过此天数的查询历史将被清理 | `ghost.go` (清理任务) | | `slow_log_retention_days` | number | `180` | 超过此天数的慢查询日志将被清理 | `ghost.go` (清理任务) | --- ## 九、LDAP 配置 (ldap) ### system_settings 中的 LDAP 配置(⚠️ 冗余) 以下 9 项配置存在于 `system_settings` 表的 `ldap` 分组中,但 **全部未被业务代码引用**。LDAP 功能使用独立的 `ldap_configs` 表进行管理。 | Key | 类型 | 默认值 | 说明 | 状态 | |-----|------|--------|------|------| | `ldap_host` | string | `8.217.205.92` | LDAP 服务器地址 | ❌ 冗余 | | `ldap_port` | string | `389` | LDAP 端口 | ❌ 冗余 | | `ldap_use_ssl` | boolean | `false` | 启用 LDAPS (SSL/TLS) | ❌ 冗余 | | `ldap_bind_dn` | string | `cn=admin,dc=opsx,dc=vip` | 管理员 DN | ❌ 冗余 | | `ldap_base_dn` | string | `dc=opsx,dc=vip` | Base DN | ❌ 冗余 | | `ldap_user_filter` | string | `(objectClass=inetOrgPerson)` | 用户过滤器 | ❌ 冗余 | | `ldap_uid_attr` | string | `uid` | UID 属性 | ❌ 冗余 | | `ldap_mail_attr` | string | `mail` | 邮箱属性 | ❌ 冗余 | | `ldap_cn_attr` | string | `cn` | 显示名属性 | ❌ 冗余 | ### ldap_configs 独立表(实际使用) LDAP 功能通过独立的 `ldap_configs` 表管理,提供完整的 CRUD 功能: | 功能 | API 端点 | 说明 | |------|----------|------| | 配置 CRUD | `/api/v1/ldap-configs` | 增删改查 LDAP 服务器配置 | | 测试连接 | `/api/v1/ldap-configs/:id/test` | 验证 LDAP 服务器连通性 | | OU 管理 | `/api/v1/ldap-configs/:id/ous` | 管理 LDAP 组织单元 | | 用户导入 | `/api/v1/ldap-configs/:id/import` | 从 LDAP 导入用户到平台 | > **建议**:后续版本可清理 `system_settings` 中 `ldap` 分组的冗余配置项,避免维护混淆。 --- ## 十、未引用 / 待实现配置 以下配置项在 `seed.go` 中定义,但在业务代码中 **无实际引用**,标注为"待实现": | Key | 分组 | 默认值 | 预期功能 | 状态 | |-----|------|--------|----------|------| | `executor_batch_size` | executor | `100` | DML 批量执行时每批的行数 | ⚠️ 待实现 | | `executor_backup` | executor | `true` | DML 执行前自动备份受影响数据 | ⚠️ 待实现 | | `query_max_rows_examined` | query | `1000000` | 单次查询允许扫描的最大行数 | ⚠️ 待实现 | | `ldap_host` | ldap | `8.217.205.92` | LDAP 服务器地址 | ❌ 冗余(使用 ldap_configs 表) | | `ldap_port` | ldap | `389` | LDAP 端口 | ❌ 冗余 | | `ldap_use_ssl` | ldap | `false` | 启用 LDAPS | ❌ 冗余 | | `ldap_bind_dn` | ldap | `cn=admin,dc=opsx,dc=vip` | 管理员 DN | ❌ 冗余 | | `ldap_base_dn` | ldap | `dc=opsx,dc=vip` | Base DN | ❌ 冗余 | | `ldap_user_filter` | ldap | `(objectClass=inetOrgPerson)` | 用户过滤器 | ❌ 冗余 | | `ldap_uid_attr` | ldap | `uid` | UID 属性 | ❌ 冗余 | | `ldap_mail_attr` | ldap | `mail` | 邮箱属性 | ❌ 冗余 | | `ldap_cn_attr` | ldap | `cn` | 显示名属性 | ❌ 冗余 | **汇总**: - ⚠️ **待实现**:3 项(`executor_batch_size`、`executor_backup`、`query_max_rows_examined`) - ❌ **冗余**:9 项(`ldap` 分组全部,LDAP 使用独立 `ldap_configs` 表) --- ## 附录:数据模型 ### system_settings 表结构 ```go type SystemSetting struct { ID int `gorm:"primaryKey" json:"id"` Key string `gorm:"size:100;not null" json:"key"` // 唯一配置键 Value string `gorm:"type:text;not null" json:"value"` // 当前值 ValueType string `gorm:"size:20;not null" json:"value_type"` // number / boolean / string Group string `gorm:"size:50;not null" json:"group"` // 分组名 Label string `gorm:"size:100;not null" json:"label"` // 前端显示名 Desc *string `gorm:"type:text" json:"description"` // 配置说明 DefaultValue *string `gorm:"type:text" json:"default_value"` // 默认值 SortOrder int `gorm:"not null" json:"sort_order"` // 组内排序 UpdatedAt *time.Time `json:"updated_at"` } ``` ### audit_rules 表结构 ```go type AuditRule struct { ID int `gorm:"primaryKey" json:"id"` Name string `gorm:"size:100;not null" json:"name"` // 规则名称 Desc *string `gorm:"type:text" json:"description"` // 规则描述 RuleType string `gorm:"size:50;not null" json:"rule_type"` // DDL/DML/DCL/DQL/performance/security Severity *string `gorm:"size:20" json:"severity"` // error/warning/info DBType *string `gorm:"size:20" json:"db_type"` // mysql/postgresql/redis/mongodb Pattern *string `gorm:"type:text" json:"pattern"` // RE2 正则表达式 IsEnabled *bool ` json:"is_enabled"` // 是否启用 Message string `gorm:"size:500;not null" json:"message"` // 命中提示消息 Value *string `gorm:"size:255" json:"value"` // reject/review/warn/where_check Code *string `gorm:"size:50" json:"code"` // 规则编码(预留) ConfigJSON *string `gorm:"type:text;column:config_json" json:"config_json"` // 扩展配置(预留) CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"` UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"` } ``` ### 配置读取辅助函数 ```go // ghost.go — 读取字符串配置 func getSetting(key, fallback string) string { var s model.SystemSetting if model.DB.Where("`key` = ?", key).Take(&s).Error == nil && s.Value != "" { return s.Value } return fallback } // ghost.go — 读取整数配置 func getSettingInt(key string, fallback int) int { // 读取字符串并 strconv.Atoi,失败返回 fallback } ``` --- > **文档维护说明**:新增配置项时,需同步更新 `seed.go` 的 `seedDefaultSettings()` / `seedAuditRules()` 函数及本文档。