本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:暂存20260913/综合设置插件开发计划.md。
综合设置插件开发计划
- 版本:v1.0(草案)
- 日期:2026-08-27
- 状态:待评审,评审通过后按阶段实施
- 定位:把散落在核心代码各处的"边角配置"(积分、限流、附件、长度限制等硬编码值)统一收拢为后台可配置项,并提供一个综合设置管理入口。
一、背景与目标
1.1 背景
FlintHub 已有较完善的后台设置体系(Settings 表 + Settings::get() 缓存 + 多个后台设置页),但存在两类配置分散问题:
- 已可配但分散:28 个设置项分布在 6 个后台页面(基础/系统/模式/显示/邮件/搜索/队列),无统一入口;
- 硬编码不可配:积分值、限流阈值、附件数量上限、长度限制等 20 余处直接写死在控制器/模型中,改一个数值必须改代码,无法在后台调整。
1.2 目标
- 将积分、限流、附件、长度 4 类硬编码配置全部改为读
Settings,后台可配; - 新增综合设置入口(后台侧栏 + 独立页面),集中展示与编辑上述配置;
- 保持兼容:默认值与当前硬编码值完全一致,升级后行为不变;
- 不改表结构(复用
settings 表),无数据迁移。
1.3 非目标(本期不做)
- 不改动现有 6 个设置页的既有项(仅新增综合设置页);
- 不做配置热加载 UI(保存即生效,沿用
Settings::update() + buildCache() 机制); - 不做多站点/多语言值差异化。
二、现状盘点(2026-08-27 全量扫描)
2.1 已在后台可配的设置(28 项)
来源:app/ 全目录正则扫描 Settings::get/update('xxx')。
| 分组 | 配置键 | 引用处数 |
|---|
| 站点基础 | site_name / site_description / site_lang / site_mode / base_path / default_theme / site_closed | 5 / 2 / 1 / 9 / 1 / 2 / 1 |
| 注册与认证 | allow_registration / email_verify_enabled / admin_verify_timeout | 2 / 2 / 4 |
| 分页与首页 | threads_per_page / posts_per_page / blogs_per_page / blog_comments_per_page / home_threads_count / home_blogs_count | 2 / 2 / 1 / 2 / 1 / 1 |
| 功能开关 | message_enabled / enable_gzip / pow_difficulty / queue_mode / search_index_content / cr_review_avatar | 3 / 1 / 1 / 2 / 3 / 1 |
| 归档与扩容 | archive_after_days / bucket_safe_capacity / auto_expand_enabled / auto_expand_threshold / auto_expand_last_at | 2 / 4 / 2 / 1 / 3 |
| 邮件 | mail_*(驱动/主机/端口/用户/密码等,后台邮件设置页) | 多 |
2.2 硬编码、后台不可配的边角(本期收拢对象)
① 积分(3 处)
| 操作 | 当前值 | 代码位置 |
|---|
| 发布主题 | +5 | app/Controllers/PostController.php:148 |
| 回复帖子 | +2 | app/Controllers/ThreadController.php:123 |
| 帖子/回帖被点赞 | +1(给被赞者) | app/Controllers/ApiController.php:77 |
② 限流阈值(13 处)
| 动作标识 | 当前值 | 代码位置 |
|---|
reply | 3 次 / 30s | ThreadController.php:100 |
create_thread | 5 次 / 600s | PostController.php:72 |
search | 8 次 / 30s | SearchController.php:28-30 |
message_send | 10 次 / 60s | MessageController.php:113 |
blog_comment | 10 次 / 60s | BlogController.php:126 |
vote | 30 次 / 60s | ApiController.php:39 |
upload | 5 次 / 60s | ApiController.php:134 |
fetch_image | 20 次 / 60s | ApiController.php:166 |
post_body | 30 次 / 60s | ApiController.php:515 |
login | 20 次 / 900s | AuthController.php:37,71 |
register | 3 次 / 3600s | AuthController.php:177 |
forgot_password | 3 次 / 3600s | AuthController.php:295 |
resend_verify | 3 次 / 3600s | AuthController.php:469 |
③ 附件限制(3 处)
| 项 | 当前值 | 代码位置 |
|---|
| 每帖/每回帖附件数上限 | 10 个 | ThreadController.php:129-131(回帖)/ PostController.php(发帖) |
| 单文件大小上限 | MAX_FILE_SIZE(config.php 常量) | app/Helpers/Upload.php:19 |
| 允许扩展名 | ALLOWED_EXTENSIONS(config.php 常量) | Upload.php |
④ 长度限制(4 处)
| 项 | 当前值 | 代码位置 |
|---|
| 标题最大长度 | 200 | PostController.php(input maxlength)/ 模型 |
| 签名最大长度 | 500 | ProfileController.php:35 |
| 搜索关键词截断 | 100 字符 | app/Helpers/Search.php:25 |
| 标签名称长度 | 1~30 字符(每帖最多 5 个) | app/Helpers/Tag.php:76 |
⑤ config.php 常量(现状:改需改文件,本期纳入"可配映射"评估)
MAX_FILE_SIZE / ALLOWED_EXTENSIONS / POSTS_PER_PAGE / THREADS_PER_PAGE / DEFAULT_THEME / DEFAULT_SITE_NAME / MAIL_* 等。
说明:MAX_FILE_SIZE / ALLOWED_EXTENSIONS 属上传安全边界,建议保留 config.php 为准、后台可覆盖(默认取常量);POSTS_PER_PAGE / THREADS_PER_PAGE 已被 posts_per_page / threads_per_page 设置项覆盖,常量仅作默认值。
三、落地形态方案
3.1 关键技术约束
积分、限流等值目前是硬编码在核心控制器里的(Points::award(..., 5, ...)、RateLimiter::hit('reply', 3, 30))。若要后台可配,核心代码必须改为读 Settings:
Points::award 只有发放后钩子(points_award_after),插件无法拦截/改写已写死的数值;RateLimiter 无钩子机制,阈值只能由调用方传入。
因此无论最终形态叫不叫"插件",都绕不开修改核心控制器——这是本计划的基线事实。
3.2 方案对比
| 维度 | 方案 A:核心后台设置扩展(推荐) | 方案 B:独立插件 |
|---|
| 实现方式 | 新增"综合设置"后台页 + 核心读 Settings | 插件目录 + 后台页,核心仍需配合读 Settings |
| 钩子依赖 | 无 | 插件激活/路由钩子 |
| 生效范围 | 全站,无需插件开关 | 依赖插件启用状态 |
| 维护成本 | 低(一处设置页) | 中(插件生命周期管理) |
| 升级影响 | 核心文件变更(随主版本发布) | 独立发布,需手动更新插件缓存 |
| 结论 | 推荐:插件形态在此场景无额外价值,反而增加维护面 | 备选 |
3.3 推荐落地方案(方案 A 细化)
- 新增后台设置页:
/admin/settings/general(综合设置),侧栏"综合设置"入口; - 配置存储:沿用
settings 表 + Settings::get($key, 默认值),默认值与现硬编码值一致; - 核心改造点(读 Settings 替代硬编码):
| 改造点 | 原硬编码 | 改为 |
|---|
PostController::create | Points::award(..., 5, ...) | Points::award(..., (int)Settings::get('points_thread_create', '5'), ...) |
ThreadController::show 回帖 | Points::award(..., 2, ...) | (int)Settings::get('points_post_create', '2') |
ApiController::vote | Points::award(..., 1, ...) | (int)Settings::get('points_vote_received', '1') |
13 处 RateLimiter::hit/check/isLimited | 字面量 | RateLimiter::hit($action, (int)Settings::get("rate_{$action}_max", 默认), (int)Settings::get("rate_{$action}_window", 默认)) |
| 附件数上限 10 | 字面量 | (int)Settings::get('attachment_max_per_post', '10') |
| 标题 200 / 签名 500 / 搜索 100 / 标签 30 | 字面量 | 对应 Settings 键 |
- config.php 常量:
MAX_FILE_SIZE / ALLOWED_EXTENSIONS 保留常量优先,后台可覆盖(Settings::get('upload_max_size', (string)MAX_FILE_SIZE))。
四、新增配置项全量清单(目标状态)
约定:键名 分组_含义;默认值 = 当前硬编码值(升级零行为变化)。
4.1 积分(points_*)
| 配置键 | 默认值 | 说明 |
|---|
points_thread_create | 5 | 发布主题奖励 |
points_post_create | 2 | 回复帖子奖励 |
points_vote_received | 1 | 帖子/回帖被点赞奖励(给内容作者) |
4.2 限流(rate_*)
| 配置键 | 默认值 | 说明 |
|---|
rate_reply_max / rate_reply_window | 3 / 30 | 回帖 |
rate_create_thread_max / rate_create_thread_window | 5 / 600 | 发帖 |
rate_search_max / rate_search_window | 8 / 30 | 搜索 |
rate_message_send_max / rate_message_send_window | 10 / 60 | 私信 |
rate_blog_comment_max / rate_blog_comment_window | 10 / 60 | 博客评论 |
rate_vote_max / rate_vote_window | 30 / 60 | 投票 |
rate_upload_max / rate_upload_window | 5 / 60 | 上传 |
rate_fetch_image_max / rate_fetch_image_window | 20 / 60 | 远程图片抓取 |
rate_post_body_max / rate_post_body_window | 30 / 60 | 正文展开 |
rate_login_max / rate_login_window | 20 / 900 | 登录 |
rate_register_max / rate_register_window | 3 / 3600 | 注册 |
rate_forgot_password_max / rate_forgot_password_window | 3 / 3600 | 忘记密码 |
rate_resend_verify_max / rate_resend_verify_window | 3 / 3600 | 重发验证邮件 |
4.3 附件(attachment_*)
| 配置键 | 默认值 | 说明 |
|---|
attachment_max_per_post | 10 | 每帖/每回帖附件数上限 |
attachment_max_size | MAX_FILE_SIZE 常量 | 单文件大小上限(字节) |
attachment_allowed_ext | ALLOWED_EXTENSIONS 常量 | 允许扩展名列表 |
4.4 长度(limit_*)
| 配置键 | 默认值 | 说明 |
|---|
limit_thread_title | 200 | 标题最大长度 |
limit_user_signature | 500 | 签名最大长度 |
limit_search_query | 100 | 搜索关键词截断长度 |
limit_tag_name | 30 | 标签名最大长度(1~N 下限固定 1) |
五、分阶段实施计划
每阶段独立可交付、可验证;阶段间无强依赖,可并行或按序推进。
阶段 1:积分可配化(points_*)
- 改动:3 处
Points::award 调用改读 Settings;Points::award 内部增加 points <= 0 拒绝逻辑已具备,无需改动; - 新增设置页字段:积分组(3 个数字输入);
- 验证:发帖 +5 / 回帖 +2 / 被赞 +1 默认不变;后台改值后立即生效(
points_log 记录正确)。
阶段 2:限流可配化(rate_*)
- 改动:13 处
RateLimiter::hit/check/isLimited 调用改读 Settings; - 建议在
RateLimiter 增加静态辅助:RateLimiter::config($action, $defMax, $defWindow) 返回 [max, window],减少各调用点重复 Settings::get 样板; - 新增设置页字段:限流组(13 组 × max/window 数字输入,按动作分组展示);
- 验证:各动作默认阈值不变;调低阈值后连续触发可观察到 429。
阶段 3:附件限制可配化(attachment_*)
- 改动:发帖/回帖附件数上限 10 →
attachment_max_per_post; Upload::file 内 MAX_FILE_SIZE 校验 → Settings::get('attachment_max_size', (string)MAX_FILE_SIZE);- 扩展名白名单 →
attachment_allowed_ext(默认取 ALLOWED_EXTENSIONS 常量解析结果); - 验证:默认行为不变;后台改大小/扩展名/数量后上传校验生效。
阶段 4:长度限制可配化(limit_*)
- 改动:标题 200(PostController 校验 + 前端 maxlength)、签名 500(ProfileController)、搜索截断 100(Search.php)、标签 30(Tag.php)改读 Settings;
- 验证:默认值不变;改小后超长输入被拒。
阶段 5:综合设置后台页 + 侧栏入口
- 新增:
app/Controllers/Admin/SettingsController::general()(或独立 GeneralSettingsController)、视图 admin/settings_general.php、侧栏入口 admin/_sidebar.php; - 路由:
/admin/settings/general(GET 表单 + POST 保存,沿用 Settings::update() + buildCache() + CSRF + 审计日志 + 二次验证); - 分组布局:积分 / 限流 / 附件 / 长度 四个卡片区块,附默认值提示与单位说明;
- 验证:保存后
settings 表写入、缓存重建、页面回显、前台行为即时生效。
阶段 6:回归与打包
- 全量 CLI 回归(
cli/_verify_query_opt.php 36 项)+ 新增设置相关断言; - 同步
update/61/(或下一版本号)升级包 + 更新说明; - 文档归档至本计划目录。
六、涉及文件清单(预估)
| 类别 | 文件 |
|---|
| 控制器(前台) | app/Controllers/PostController.php、ThreadController.php、ApiController.php、AuthController.php、SearchController.php、MessageController.php、BlogController.php、ProfileController.php |
| 辅助类 | app/Helpers/RateLimiter.php(新增 config 辅助)、app/Helpers/Upload.php、app/Helpers/Search.php、app/Helpers/Tag.php |
| 后台 | app/Controllers/Admin/SettingsController.php、app/Views/admin/settings_general.php、app/Views/admin/_sidebar.php、index.php(路由) |
| 前端 | 发帖/编辑视图标题 maxlength(post/create.php、thread/edit.php) |
| 国际化 | lang/zh.php、lang/en.php、lang/zh_tw.php(设置页文案 + 分组标题) |
| 验证 | cli/_verify_query_opt.php(追加断言) |
七、验证方案
- 默认值回归:升级后不修改任何设置,所有行为与现版本完全一致(各阶段 CLI/手工断言);
- 配置生效:后台修改各值后,前台行为即时变化(发帖积分、限流 429、附件拒绝、长度拦截);
- 缓存一致性:
Settings::update() 后 settings_cache.php 重建,Settings::get() 返回新值; - 权限与安全:综合设置页仅管理员可访问(沿用 BaseController + 二次验证 + CSRF);
- 全量回归:
php cli/_verify_query_opt.php 36 项 + 新增设置断言全部通过。
八、风险与注意事项
- 限流可配化的安全边界:登录/注册限流不建议调得过宽,计划中保留默认值;后台设置页对 rate_* 提供合理范围提示(如 window ≥ 1s);
- 附件扩展名白名单:
ALLOWED_EXTENSIONS 属安全边界,后台修改时应提示"仅建议在信任环境放宽"; - 默认值一致性:所有新键默认值 = 现硬编码值,升级零行为变化;若站点已通过改代码定制过这些值,升级前需在后台重新录入;
- RateLimiter 封装:13 处调用点改造时需逐一核对动作标识与默认值,防止误配(可先做
RateLimiter::config() 辅助再批量替换); - 版本与打包:本计划为"核心扩展"形态,随主版本发布;若最终要求插件形态,则需额外处理插件激活/缓存清单(
plugins_cache.json),成本上升。
文档结束。评审通过后按阶段 1→6 顺序实施;每阶段完成即验证、可单独上线。