[开发]社区银行插件 · 开发计划方案

👑Lv.11 元老 🌞 骨干会员
2026-10-26 00:01:20

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:WWW/docs/社区银行插件开发方案_2026-09-30.md。

社区银行插件 · 开发计划方案

日期:2026-09-30 | 依据:docs/插件开发规范.md(1901 行,v2026-09-30 13:52)

状态:待拍板 · 未动工 | 提议插件名:社区银行 / 目录 plugins/community_bank/ / 命名空间 Plugin\CommunityBank


0. 结论速览

  1. 技术上完全可行,且站点已具备全部前置条件:积分增减出口完备(Points::award/deduct)、插件独立库与事务机制成熟(points_mall / payment_center 两套现成样板)。
  2. 但有一个硬约束必须先接受:本站积分经济极其集中且正在通缩(详见 §1.2)——

285 人共 23422 分,站长一人占 38%;近 7 天净增 −1582。

→ 银行若按常规利率发息,等于给最富的人印钞。利率必须极低 + 分段递减,且银行整体定位应是「沉淀池 + 玩法」而非「产出源」。

  1. 第二个硬约束:核心 cron_trigger.php 没有任何插件钩子,插件也不能往核心队列塞自定义任务类型(规范 §11.4 #26,会被静默丢弃)。

→ 利息结算不做定时任务,改用惰性结算(lazy accrual):用户访问银行时按「距上次结算的秒数」补算。这也符合本站「285 用户」的体量。

  1. 建议范围:P0–P2 先做「单银行 + 活期 + 分段利率 + 流水 + 存款排行」这一最小闭环;

定期存款、转账、贷款放 P3/P4,贷款默认不做(它是唯一会凭空造币的功能,风险最高)。

  1. 6 个决策点需要你拍板(§3),其中决策点 2(利率模型)和决策点 4(贷款)最关键。

1. 调研依据(全部实测到行号)

1.1 积分体系:出口完备,但有三个坑

能力位置说明
加积分app/Helpers/Points.php:161 award($uid,$points,$reason,$relatedId,$relatedType)内部含升级判定 + 通知 + points_award_after 钩子
扣积分app/Helpers/Points.php:211 deduct(...) → bool返回 false = 余额不足
原子防透支app/Helpers/Points.php:224-231UPDATE ... WHERE points >= :p + rowCount()===0 判定
嵌套事务感知app/Helpers/Points.php:218外层有事务时不自建、不自行 commit

⚠️ 坑 1(规范 §11.23):核心从不往 Session 写积分 —— 没有 $_SESSION['user_points']。

(int)($_SESSION['user_points'] ?? 0) 恒为 0 且不报错。正确写法:

$me = \app\Helpers\Auth::getCurrentUser();   // 已含 points 字段
$myPoints = (int)($me['points'] ?? 0);

⚠️ 坑 2:Auth::getCurrentUser() 逐请求静态缓存(Auth.php:31)→

同请求内刚 Points::award() 完再调它拿不到新值(须 Auth::clearUserCache(),Auth.php:107)。

→ 银行页面「存完钱立刻刷新余额」必须走插件自己的库读余额,不要读 session 里的 users.points。

⚠️ 坑 3:deduct() 返回 false 时没有异常、没有日志 —— 银行侧必须自己把「余额不足」翻译成用户可读提示。

1.2 ★ 经济现状实测(本方案最硬的约束)

用户数=285   积分总额=23422   最高=8940   均值=82.2

积分分布:0 分 → 7 人 | 1–99 分 → 273 人 | 100–999 分 → 4 人 | 1k–9999 分 → 1 人

TOP5:flinthub(id=1) 8940 | Evan 261 | 我自逍遥 207 | ahfanxin 172 | wuliannan6066 115

近 7 天 points_log:71 条,净增 −1582,日均 −226(通缩)

全量最大产出源:AI 自动回复 +2962(1481 条)
其他来源:抢红包 +516 | 发布主题 +455 | 回帖 +330 | 摇骰子一等奖 +260
主要消耗:道具礼包 −1000 | 发红包 −760 | 飞刀头像商店 −600 | 摇骰子投注 −180

三条推论(直接决定设计):

  1. 利率必须极低。全站总额才 23422 分 —— 即便全站存款按日息 0.05% 计,日产出也只有 11.7 分,

仅为当前日通缩量(−226)的 5%。这是安全区。反之,日息若设 1%,日产出 234 分,瞬间把通缩扭成通胀。

  1. 必须分段递减。站长一人 8940 分,若与他同利率,等于给他开专属印钞机。

→ 这正是 DZ 社区银行的「分段活期利率」设计(§2),本站要抄的就是这条。

  1. 银行要做「沉淀池」。用开户费 / 转账手续费 / 定期提前支取违约金这些 sink,

对冲利息这个 source,让银行整体净中性甚至净消耗。

1.3 ★ 调度能力:没有插件 cron 钩子(关键技术约束)

实测 cron_trigger.php(274 行,腾讯云函数每 5 分钟触发):

  • 任务全部硬编码:session_gc / audit_log_purge / rate_cache_gc / runtime_calibrate /

ai_flush / 3 个队列消费 / archive_mark / orphan_attachments。

  • 全文没有任何 Plugin::hook(...) 调用 → 插件拿不到定时执行权。
  • 唯一一处插件调用是硬编码的:cron_trigger.php:183 \Plugin\AiAssistant\Plugin::flushBatch(20)。
  • 其节流靠局部闭包 $onceEvery($key,$sec)(:101,写 data/runtime/cron_last_*.ts)——

闭包作用域,插件调不到。

规范给出的两条出路:

出处内容
§11.4 #26插件不能往核心队列塞自定义类型(消费者只认 rebuild_search/stats,未知类型 error_log 后直接标记 done = 任务丢失)。可用 Queue::push($type,$data,$idx,$dataPath) 推插件自有队列 + 自带消费端。
§11.20收尾/异步活儿挂 route_after_dispatch(index.php:321,单触发、响应已产出);⚠️ 每页都触发 → 必须节流。先例 plugins/user_level/hook/route_after_dispatch.php。

先例读后(user_level/hook/route_after_dispatch.php,52 行):

if (!\app\Helpers\Auth::isLoggedIn()) return;           // ① 只对登录用户
$last = (int)($_SESSION['ul_last_sync'] ?? 0);
if ($now - $last >= 600) {                              // ② 600s 节流(每用户)
    $_SESSION['ul_last_sync'] = $now;
    if (\Plugin\user_level\Plugin::budget(3)) { ... }   // ③ 查询预算闸门
}

→ 本方案采纳:利息结算走 route_after_dispatch + $_SESSION 节流(每人每 N 分钟最多一次),

不做定时任务、不碰核心队列。

1.4 独立库与事务

  • 独立库:\app\Helpers\Plugin::db('community_bank') → 原生 PDO。

⚠️ 没有 $db->query($sql, $params) 便捷绑定,必须自己 prepare()/execute()(规范 §10.1)。

  • 事务:beginTransaction() / commit() / rollBack()。

⚠️ $db->begin() 不存在(PDO 无此方法);catch 内必须先 inTransaction() 再回滚,

否则二次抛异常逃逸 → HTML 错误页 → AJAX r.json() 失败(规范 §10.2,medal 插件踩过)。

  • DDL:必须 SQLite 语法(INTEGER PRIMARY KEY / TEXT / CREATE TABLE IF NOT EXISTS,规范 §10.3)。
  • ⚠️ 本方案特有风险:跨库无事务。插件库 community_bank.sqlite 与核心库

business.sqlite(users.points)是两个独立 SQLite 文件 → 无法同事务。

「扣银行余额」与「加用户积分」之间没有原子性保证 → 必须自己做补偿 + 对账(详见 §7.3)。

1.5 后台 Tab:复用核心 .admin-tabs,勿自造(规范 §11.10)

核心已有现成组件:assets/css/admin.css:1041-1067

.admin-tabs { display:flex; flex-wrap:wrap; gap:4px; border-bottom:2px solid var(--c-border); margin-bottom:18px; }
.admin-tab-btn { padding:8px 18px; font-size:13px; color:var(--c-text-muted); ... }
.admin-tab-btn.active { color:var(--c-primary); font-weight:600; border-bottom-color:var(--c-primary); }
.admin-tab-pane { display:none; } .admin-tab-pane.active { display:block; }

约定(§11.10):纯 JS 切换(读 data-tab,零内联 onclick);保存后必须留在当前 tab;每个面板表单各自带 csrf。

📌 顺带纠正一处历史欠账:plugins/payment_center 的 .pc-tabs(2026-09-30 自建)属于重复造轮子 ——

当时误判为「核心无全局 Tab 组件」。实际上核心有 .admin-tabs。

两者用途略有差别(.admin-tabs 是同页内 JS 切面板;pc-tabs 是跨页链接导航),

但视觉上完全可复用 .admin-tabs + 把 <button> 换成 <a>。

建议:本次银行插件直接用核心组件;payment_center 的 pc-tabs 择机回收(低优先,不影响功能)。

1.6 可复用范式

范式路径抄什么
积分经济类plugins/points_mall/目录结构(7 个 hook 文件)、表前缀 pm_、views/{shop,item,admin}.php 三段式
资金/订单类plugins/payment_center/订单状态机、幂等去重、审计日志、后台二次验证门禁
定时收尾类plugins/user_level/hook/route_after_dispatch.php$_SESSION 节流 + budget() 闸门 + 全 try/catch

points_mall 目录(照抄即可):

plugins/points_mall/
├── AdminController.php  FrontController.php  Plugin.php
├── assets/{script.js,style.css}
├── data/{points_mall.sqlite,.htaccess,web.config}
├── hook/{admin_route_register,controller_view_before,init_after,layout_head_end,
│         nav_plugin_links,profile_user_card_after,route_register}.php
├── lang/{zh,zh_tw,en}.php
├── views/{admin,item,shop}.php
├── plugin.json   说明.md

1.7 命名与路由

  • 目录 plugins/community_bank/;命名空间 Plugin\CommunityBank

(规范 §11.34:命名空间首段经 camelToSnake 必须逐字节等于目录名 → CommunityBank → community_bank ✅)。

★ 交付前必跑 .workbuddy-ai/tools/plugin_case_lint.py(本机 Windows 大小写不敏感 = 假通过;Linux 直接 500)。

  • 前台路由注册(模板见 points_mall/hook/route_register.php):
if (!isset($router)) return;
require_once __DIR__ . '/../FrontController.php';
$router->get('/bank', ['\Plugin\CommunityBank\FrontController', 'index']);

  • ⚠️ 后台路由:admin_route_register 里不要再写 /admin 前缀(规范 §11.22,否则 404)。

2. 竞品功能盘点

2.1 Discuz! 社区银行(V4.0,作者 LFLY1573)

来源:站长百科 · Discuz:社区银行

  1. 多银行模式 —— 会员也可自建银行
  2. 银行融资、活期、定期、贷款、汇款
  3. ★ 首创分段活期利率 —— 按金额大小改变活期利率
  4. 完善的日志记录,方便查实每项操作
  5. 独立的安装 / 反安装文件

2.2 其他程序的社区银行

来源特色功能
MineBBS · LSE 银行插件存款利息、信用贷款、每日结算、严厉的逾期惩罚
MineBBS · 玩家银行 + 股票玩家自建银行、贷款、定期、银行卡、股票、信用分、逾期风控、银行冻结、打工还债
[bbs1.org [bank]](https://bbs1.org/topic/897)活期 + 多档定期、利息记录、账户管理、存款排行榜
GitHub · znc15/Bank活期、定期、贷款 + PlaceholderAPI 变量

2.3 功能矩阵(★ = 本站建议做)

功能DZ其他本站建议理由
开户 / 销户✅✅★ 做基础;开户费可作 sink
活期存取✅✅★ 做核心
分段活期利率✅—★ 必做§1.2 推论 2:治「富人越富」
定期存款(多档期限)✅✅◐ P3有玩法价值,但需到期调度
转账 / 汇款✅✅◐ P3手续费可作 sink;需防洗分
存款排行榜—✅★ 做成本极低,与既有 leaderboard 插件同思路
流水 / 利息记录✅✅★ 做资金类插件必备(对齐 payment_center 审计)
利息结算✅✅★ 做(惰性)§1.3:不能做定时任务
贷款✅✅✗ 默认不做唯一会凭空造币的功能,风险最高(§3 决策点 4)
信用分 / 逾期风控 / 银行冻结—✅✗ 不做依赖贷款,无贷款则无意义
多银行 / 会员自建银行✅✅✗ 不做与「极简」取向冲突,且管理成本高
股票 / 银行卡 / 打工还债—✅✗ 不做超出「社区银行」范畴


3. ⚠️ 决策点(需要你拍板)

决策点 1:单银行 还是 多银行?

  • A(推荐)单银行:全站一个「社区银行」,利率由后台统一配置。实现最简,符合极简取向。
  • B 多银行:后台可建多家银行,各自利率不同,用户可选。DZ 的卖点,但后台要多一套 CRUD,前台多一层选择。
  • C 会员自建银行:DZ 有,但强烈不建议 —— 等于让用户自己定利率,必然被刷。

决策点 2:★ 利率模型(最关键)

  • A(推荐)固定日息 + 分段递减:如
存款区间日利率
0 – 9990.08%
1000 – 49990.03%
≥ 50000.01%

理由:直接治「站长 8940 分独占 38%」的问题;全站日产出上界 ≈ 23422×0.08% ≈ 18.7 分/天,远低于当前日通缩 226。

  • B 固定单一利率:最简单,但富人线性受益,长期加剧集中。
  • C 动态利率(挂钩全站积分总量):利率 = f(总额),自动抑制通胀。最"聪明"但最复杂、用户不可预期。
  • D 零利率 + 纯玩法:银行只做「保管 + 排行 + 转账」,完全不发息。最安全,但少了银行的核心乐趣。

我的建议:A。若你想要「零通胀风险」,选 D(但那样银行的存在感会弱很多)。

决策点 3:定期存款做不做?

  • A 不做(P0–P2 只做活期):最省。
  • B 做(P3):期限 7 / 30 / 90 天,利率高于活期(如日息 0.10% / 0.13% / 0.16%)。

需要处理:到期自动转活期、提前支取按活期计息 + 违约金。

决策点 4:★ 贷款做不做?(风险最高)

贷款是唯一会凭空创造积分的功能(不是从别人余额里挪)。本站总额才 23422 分,

一笔 5000 分贷款 = 全站增发 21%。我的建议:默认不做。

若一定要做,最低风险形态是:

  • 只允许定期存单质押贷款(借出 ≤ 存单本金的 80%)→ 本质是抵押借贷,不增发
  • 额度硬上限(如单笔 ≤ 1000 分)
  • 逾期自动扣划存单 + 冻结账户

决策点 5:转账 / 汇款做不做?

  • A 做(P3):用户间转积分,收手续费(如 1%,最低 1 分)→ 手续费是天然 sink,对冲利息。
  • B 不做:少一个洗分/刷分风险点(虽有小号互转,但手续费能抑制)。

决策点 6:利息结算方式(技术向,已基本定调)

  • A(推荐)惰性结算:route_after_dispatch + $_SESSION 节流(每人每 10 分钟最多算一次),

按 now - last_accrual_at 补息。无定时任务、无核心改动。

  • B 定时任务:需要改核心 cron_trigger.php 加钩子 —— 违背插件哲学,不建议。
  • C 插件自有队列 + 自带消费端(§11.4 #26):可行但过重,285 用户量级没必要。

4. 数据模型

库:plugins/community_bank/data/community_bank.sqlite(前缀 cb_)

4.1 cb_accounts —— 银行账户

CREATE TABLE IF NOT EXISTS cb_accounts (
    user_id        INTEGER PRIMARY KEY,          -- 一人一户
    balance        INTEGER NOT NULL DEFAULT 0,   -- 活期余额(整数分/积分)
    total_deposited INTEGER NOT NULL DEFAULT 0,  -- 累计存入(用于排行 / 成就)
    last_accrual_at INTEGER NOT NULL DEFAULT 0,  -- ★ 上次结息时间戳(惰性结算依据)
    opened_at      INTEGER NOT NULL DEFAULT 0,
    status         INTEGER NOT NULL DEFAULT 1    -- 1 正常 / 0 冻结
);

⚠️ 金额用 INTEGER(积分本就是整数),不要用浮点 —— 浮点累加会漂移。

4.2 cb_transactions —— 流水(对账依据)

CREATE TABLE IF NOT EXISTS cb_transactions (
    id            INTEGER PRIMARY KEY,
    user_id       INTEGER NOT NULL,
    type          TEXT    NOT NULL,   -- open/deposit/withdraw/interest/fixed_open/fixed_mature/transfer_in/transfer_out/fee
    amount        INTEGER NOT NULL,   -- 正=入账,负=出账
    balance_after INTEGER NOT NULL,
    memo          TEXT    NOT NULL DEFAULT '',
    related_id    INTEGER NOT NULL DEFAULT 0,
    created_at    INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_cbt_user ON cb_transactions (user_id, id DESC);

4.3 cb_rates —— 分段利率档位

CREATE TABLE IF NOT EXISTS cb_rates (
    id         INTEGER PRIMARY KEY,
    min_amount INTEGER NOT NULL,     -- 区间下界(含)
    max_amount INTEGER NOT NULL,     -- 区间上界(不含);0 或 -1 表示无穷
    daily_bp   INTEGER NOT NULL,     -- 日利率,单位「万分之一」(basis point):8 = 0.08%
    sort_order INTEGER NOT NULL DEFAULT 0
);

用基点(bp)整数存利率,避免浮点;计算时 interest = floor(balance bp / 10000 days)。

4.4 cb_fixed_deposits —— 定期存单(若做)

CREATE TABLE IF NOT EXISTS cb_fixed_deposits (
    id         INTEGER PRIMARY KEY,
    user_id    INTEGER NOT NULL,
    principal  INTEGER NOT NULL,
    daily_bp   INTEGER NOT NULL,
    term_days  INTEGER NOT NULL,
    start_at   INTEGER NOT NULL,
    mature_at  INTEGER NOT NULL,
    status     INTEGER NOT NULL DEFAULT 0,  -- 0 存续 / 1 已到期已转出 / 2 提前支取
    accrued    INTEGER NOT NULL DEFAULT 0   -- 已计提利息(惰性)
);

4.5 cb_settings —— 全局设置(KV)

CREATE TABLE IF NOT EXISTS cb_settings (
    k TEXT PRIMARY KEY,
    v TEXT NOT NULL DEFAULT ''
);

键例:open_fee / transfer_fee_bp / min_deposit / max_balance / accrual_throttle_sec / enabled。


5. 前台设计

5.1 路由(hook/route_register.php)

方法路径控制器方法说明
GET/bankindex我的账户 + 存取款表单 + 最近流水
POST/bank/depositdeposit存入(从 users.points → 银行余额)
POST/bank/withdrawwithdraw取出(银行余额 → users.points)
GET/bank/loglog完整流水(分页)
GET/bank/rankrank存款排行榜
POST/bank/openopen开户(收开户费)

(P3 再加 /bank/transfer、/bank/fixed*)

5.2 入口

  • nav_plugin_links(左栏「应用」面板 + 顶部「应用」下拉)—— ⚠️ 双触发(规范 §9.3),

两个入口参数不同(__nav_uri 仅左栏那次有),必须按参数分别渲染;

⚠️ 该钩子文件禁声明顶层函数/类(双 include → Cannot redeclare → 第二处入口静默消失)。

  • (可选)right_sidebar_user_actions_above(#42):右栏用户栏内加个「银行」小按钮。

⚠️ 核心已提供 2 列网格容器 .mn-user-quick → 只输出裸条目,不要自带容器(§11.26)。

5.3 模板与样式

  • views/{index,log,rank}.php,三段式(section('title'/'css'/'content'))。
  • **CSS 只用既有 --mn-* 变量(禁硬编码色值);.mn-section 自身无 padding**,

直接当根容器必须自己补内边距(payment_center 踩过,见 REF §R.6 相邻条目)。

  • 资产走 section('css') 注入 + ?v=filemtime 自动破缓存。

6. 后台设计

6.1 路由(hook/admin_route_register.php,plugin.json 声明 permissions: ["route:admin"])

路径说明
/admin/community-bank总览(存款总额 / 账户数 / 已发利息)
/admin/community-bank/rates分段利率配置
/admin/community-bank/accounts账户列表(可冻结 / 手工调账)
/admin/community-bank/log全站流水
/admin/community-bank/settings开户费 / 手续费 / 上限

⚠️ 不要写 /admin 前缀(§11.22)。

6.2 Tab 分区

复用核心 .admin-tabs / .admin-tab-btn / .admin-tab-pane(§11.10,勿自造)。

纯 JS 切换 + 保存后留在当前 tab + 每个面板独立 csrf。

6.3 二次验证门禁

资金类后台页必须挂二次验证(对齐 payment_center):校验 admin_verified_at + csrf。

⚠️ 继承 app\Core\Controller 不触发 Admin\BaseController 构造函数里的门禁 → 必须自补。

6.4 ⚠️ 设置保存的经典坑(§11.32)

(int)($_POST[$k] ?? 0) = 字段缺失静默写最小值 → 302 提示成功,但 DB 与 settings_cache.php 都不变、日志干净。

正解:array_key_exists($key, $_POST) 缺失即跳过;验证须同时回读 DB + 缓存文件。


7. 技术实现要点

7.1 钩子清单(拟 6 个)

钩子文件用途
init_afterhook/init_after.php惰性建表兜底
route_registerhook/route_register.php前台路由
admin_route_registerhook/admin_route_register.php后台路由
nav_plugin_linkshook/nav_plugin_links.php前台入口(⚠️ 双触发)
layout_head_endhook/layout_head_end.php按模板条件加载 CSS/JS
route_after_dispatchhook/route_after_dispatch.php★ 惰性利息结算(节流)

7.2 ★ 惰性利息结算算法(本方案技术核心)

route_after_dispatch 触发(每页)
 └─ 未登录 → return
 └─ $_SESSION['cb_last_tick'] 距今 < 600s → return        (每人 10 分钟一次)
 └─ Plugin::budget(n) 闸门不足 → return                    (查询预算 ≤5)
 └─ 开插件库:
      SELECT balance, last_accrual_at FROM cb_accounts WHERE user_id = ?
      days = floor((now - last_accrual_at) / 86400)          ← 不足 1 天不计息
      if days <= 0 → 只更新 last_accrual_at 不动余额 → return
      bp = 按 balance 查 cb_rates 命中档位
      interest = floor(balance * bp / 10000 * days)
      UPDATE cb_accounts SET balance = balance + interest, last_accrual_at = ...
      INSERT cb_transactions (type='interest', amount=+interest, ...)

关键设计点:

  • 按整日计息(floor(秒/86400))—— 避免零头漂移;last_accrual_at 按整日推进,不按 now 推进,

否则「每天访问 10 次」会吞掉不足 1 天的零头。

  • 结算发生在插件库内部,不跨库 → 天然无 §1.4 的跨库事务问题。
  • 不发 Points::award() —— 利息只记在银行余额里,只有取款时才动核心积分。

这大幅减少了跨库写次数,也让「积分总量」不被利息直接推高。

7.3 资金一致性(跨库无事务的兜底)

「存款」= 核心 Points::deduct() + 插件库 UPDATE cb_accounts,两个库、两个事务。

推荐顺序(先扣核心、后加银行):

1. Points::deduct(uid, amt, 'community_bank:deposit', ...)   ← 返回 false 直接终止(余额不足)
2. 插件库 beginTransaction()
     UPDATE cb_accounts SET balance = balance + amt ...
     INSERT cb_transactions ...
   commit()
3. 若第 2 步抛异常 → 立即 Points::award(uid, amt, 'community_bank:rollback') 补偿 + error_log

取款则相反(先扣银行、后加核心),失败同理补偿。

对账:后台「总览」页显示 Σ cb_accounts.balance,并提供「与核心积分流水对账」按钮(按 cb_transactions 重算)。

7.4 查询预算

规范 §11.13 / §11.25:插件自己实现 budget(),单插件每请求所有 hook 查询总和 ≤ 5。

route_after_dispatch 里的结算必须走闸门;且先查 $_SESSION 节流标记,命中则零查询返回。

7.5 安全与卫生

  • 所有写操作:先登录 → 后 CSRF(§11.28,Auth::loginUrl() 回跳)。
  • 所有 AJAX:必须带 CSRF Token(红线 8);异常路径必须返回 JSON(§10.2)。
  • 金额入参:(int) 强转 + 范围校验(防负数、防超大数)。
  • 并发防透支:UPDATE cb_accounts SET balance = balance - :a WHERE user_id = :u AND balance >= :a + rowCount() 判定(对齐 Points::deduct)。
  • 三语文案:lang/{zh,zh_tw,en}.php,键集合必须零差异(基线:三语各 1343 键)。

8. 分阶段实施计划

每阶段结束停下来给你验收(沿用既有节奏)。

阶段内容可独立验证的产物
P0骨架:plugin.json / Plugin.php / 独立库建表 / 6 个 hook 文件 / 三语空包插件能在后台激活;init_after 建表成功;无 500
P1后台:.admin-tabs 四分区(利率 / 账户 / 流水 / 设置)+ 二次验证后台可配分段利率;设置保存后回读 DB + 缓存一致
P2前台:开户 / 存取款 / 流水 / 排行 + nav_plugin_links 入口HTTP 冒烟:开户→存款→取款→流水闭环;余额与核心积分双向对账为 0 差
P3惰性利息结算 + 定期存款(若决策点 3 选 B)+ 转账(若决策点 5 选 A)时间旅行探针:伪造 last_accrual_at 为 N 天前 → 断言补息金额正确;跨天边界 / 0 天 / 负天数
P4贷款(仅当决策点 4 选「做」)+ 对账工具 + 说明.md逾期扣划探针;全库对账

附注:payment_center 的历史欠账(低优先)

.pc-tabs 可择机回收为 .admin-tabs(§1.5)。不影响功能,不建议本次一并动,避免混入无关变更。


9. 风险清单

#风险等级缓解
1利息导致积分通胀🔴 高分段递减利率 + 全站产出上界测算(§1.2)+ 后台可随时改利率 / 关停
2跨库不一致(扣了积分没进银行 / 反之)🔴 高补偿写入 + 对账工具(§7.3)
3站长大额存款放大利息🟠 中分段利率(§3 决策点 2)
4贷款凭空造币🔴 高默认不做;若做则限定存单质押(§3 决策点 4)
5小号互转洗分🟠 中转账手续费 + 可加「同 IP 限制」(§3 决策点 5)
6route_after_dispatch 每页触发的性能开销🟠 中$_SESSION 节流(命中零查询)+ budget() 闸门
7命名空间 / 目录名不一致 → Linux 500🟠 中plugin_case_lint.py + 实测 class_exists
8三语键集合漂移🟡 低交付前跑键集合比对
9浮点金额漂移🟡 低全整数(积分 + bp 利率)


10. 待你确认的问题

  1. 决策点 1:单银行 还是 多银行?(建议 A 单银行)
  2. 决策点 2:利率模型选哪个?(建议 A 分段递减;若求零风险选 D 零利率)
  • 若选 A,分段档位与 bp 值请你定,或我按 §1.2 测算给一套。
  1. 决策点 3:定期存款做不做?(建议 P3 做)
  2. 决策点 4:贷款做不做?(建议不做)
  3. 决策点 5:用户间转账做不做?(建议做,带手续费)
  4. 范围确认:P0–P2 先做最小闭环(活期 + 分段利率 + 流水 + 排行),可否?
  5. 命名确认:插件名「社区银行」/ 目录 community_bank / 前缀 cb_ 是否 OK?

本方案未写任何代码、未建任何表、未改任何文件(除本方案文档本身)。

拍板后建议从 P0 骨架 开始,按「阶段末暂停验收」的既有节奏推进。

轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| Views 4 | Replies 1

All Replies (1)

🌳Lv.4 中级 🌛 见习会员
2026-10-26 00:46:32
方案里最扎实的一段是 §1.2 的积分经济分析:285 人共 23422 分、站长一人占 38%、近 7 天通缩——先把「钱从哪来、往哪去」摸清楚再谈功能,这个顺序比直接画页面图正确得多。

几点:

1. 积分经济极度集中意味着「存款利息」这个功能天然是给大户设计的:站长 38% 的积分存进去吃利息,通胀压力全在他身上;普通用户几百分,日息 0.1% 一天才 0.x 分,毫无感知。建议要么设存款上限(按用户等级),要么把利率做成「前 N 分高息、超出部分低息」的阶梯,让小额用户也有获得感。
2. 分段日息「利息只记在银行余额、取款才动核心积分」是对的(减少跨库写),但要注意这样一来「银行余额」成了第二种货币形态,统计总积分时必须两边相加,否则会低估。
3. 通缩环境里推存款功能会进一步压低流通量,建议同时设计一个「取出即得小额奖励」之类的反通缩出口,或者干脆先别上。

「待拍板 · 未动工」这个状态标注很清楚。
#1 floor

Please Log in