[插件] 社区银行(community_bank)插件发布。

👑Lv.11 元老 🌏 正式会员
2026-09-30 21:30:30

版本:1.0.0 | 作者:FlintHub |

功能:把闲置的核心积分存入社区银行,按分段日息计息、随时存取; 利息只记在银行余额里,取款时才动核心积分(减少跨库写)。

定位:社区银行只负责积分 —— 进出全部是核心积分,银行余额只是「积分的一种存储形态」, 与支付、充值、提现无关。


一、功能简介

1.1 前台

页面 路径 说明
社区银行 /bank 未开户显示开户卡片;已开户显示余额、当前日息、存取款表单、利率表、最近流水
我的流水 /bank/log 分页列表(每页 LOG_PER_PAGE = 30 条),含时间/类型/金额/余额/备注
存款排行 /bank/rank 公开页,取余额 > 0 的前 RANK_LIMIT = 20 名,前三名有奖牌样式,本人行高亮

存取款为同步表单提交(PRG 模式):POST 处理完 → redirect('/bank'), 避免刷新重复提交。所有写操作走核心 Csrf::verifyOrDie()。

1.2 后台(/admin/community-bank)

单页五分区,靠页内 .admin-tabs 互跳(?tab=overview|rates|accounts|log|settings):

分区 参数 说明
总览 ?tab=overview 统计卡(账户数 / 存款总额 / 累计存入 / 累计利息 / 冻结数)+ 对账表
利率 ?tab=rates 分段利率档位增删改(min / max / 日利率 %),全量替换保存
账户 ?tab=accounts 账户列表 + 冻结/解冻 + <details> 内嵌手工调账(±余额,只动银行余额)
流水 ?tab=log 全站流水(每页 ADMIN_PER_PAGE = 50 条)
设置 ?tab=settings 总开关 / 开户费 / 单次最少存入 / 单户余额上限

⚠️ 后台所有 markup 必须留在 <main class="admin-content"> 内 —— 核心表单/按钮/alert 样式 全是 .admin-content 作用域(admin.css:237-306),放到 </main> 之后就是「弹出页没有 UI」且零日志。


二、目录结构

plugins/community_bank/
├── plugin.json                  # 插件清单(5 个钩子 + admin_url=/admin/community-bank)
├── Plugin.php                   # 主类:建表/迁移、设置、利率、账户、存取、惰性计息、对账、排行
├── FrontController.php          # 前台:/bank 首页 / 开户 / 存取 / 流水 / 排行
├── AdminController.php          # 后台:五分区 + 4 个写操作(继承 Admin\BaseController)
├── hook/
│   ├── init_after.php           # 幂等建表兜底(版本化 marker 门控)
│   ├── route_register.php       # 前台路由(6 条)
│   ├── admin_route_register.php # 后台路由(5 条,不写 /admin 前缀)
│   ├── nav_plugin_links.php     # 「应用」入口(左栏 + 顶栏,双触发)
│   └── route_after_dispatch.php # ★ 惰性计息(每请求触发 → 零查询短路节流)
├── views/                       # 4 个视图:index.php / log.php / rank.php / admin.php
├── assets/                      # style.css(前台)/ admin.css(后台)/ script.js(分区切换 + 利率增删行)
├── lang/                        # zh / en / zh_tw(各 140 键,键集合与键序零差异)
└── data/                        # 独立库 + 建表 marker(自动生成 .htaccess / web.config 防 Web 访问)

三、数据表(插件独立库)

库文件:plugins/community_bank/data/community_bank.sqlite

表 用途 关键字段
cb_accounts 账户主表(也是余额台账) user_id(PK) / balance / total_deposited / last_accrual_at / opened_at / status
cb_transactions 银行余额变动流水 user_id / type / amount(±) / balance_after / memo / created_at
cb_rates 分段利率档位 min_amount / max_amount(-1=上不封顶) / daily_bp(万分之一) / sort_order
cb_settings 插件设置 KV k(PK) / v

索引(activate() 内、CREATE TABLE 之后建): idx_cbt_user (user_id, id DESC) / idx_cbt_all (id DESC) / idx_cba_balance (balance DESC)

账户状态:1 正常 | 0 冻结(status <> 1 一律拒绝存取与计息)

流水类型(type 列 → i18n txn_*):

type 含义 amount 符号
deposit 存入 +
withdraw 取出 −
withdraw_rollback 取出回滚(补偿) +
interest 利息 +
adjust 管理员调账 ±

⚠️ 金额一律以整数积分存储,杜绝浮点误差。 ⚠️ 开户费不写这张表 —— 理由见 §5.4。

默认利率档位(站长拍板口径,seedDefaults() 仅在 cb_rates 空表时写入):

存款区间 日利率 bp
0 ~ 999 0.08% 8
1000 ~ 4999 0.03% 3
≥ 5000 0.01% 1

默认设置(Plugin::defaults()):enabled=1 / open_fee=0 / min_deposit=1 / max_balance=0(不限)


四、路由清单

4.1 前台(hook/route_register.php)

方法 路径 鉴权
GET /bank 登录
POST /bank/open 登录 → CSRF
POST /bank/deposit 登录 → CSRF
POST /bank/withdraw 登录 → CSRF
GET /bank/log 登录
GET /bank/rank 公开(无需登录)

4.2 后台(hook/admin_route_register.php,不写 /admin 前缀)

⚠️ 核心已在 admin 分组内注册,插件再写 /admin 会 404(规范 §11.22)。 plugin.json 的 admin_url = /admin/community-bank(含前缀),两边拼起来才是最终 URL。

方法 路径(不含前缀) 动作
GET /community-bank 五分区首页(?tab= 切换)
POST /community-bank/rates/save 利率档位全量保存
POST /community-bank/settings/save 设置保存
POST /community-bank/account/status 冻结 / 解冻
POST /community-bank/account/adjust 手工调账(±)
最后由 flinthub 于 2026-10-01 11:49 编辑
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 浏览 79 次 | 回复 14 次

全部回复 (14)

👑Lv.11 元老 🌏 正式会员
2026-09-30 21:58:45

插件已修复,已下载的请重新下载覆盖。

轻量级、高性能、零 MySQL 依赖的PHP社区系统。
#1 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-09-30 22:25:41
先看 LICENSE——帖子通篇没提
#2 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-09-30 23:16:51
利息惰性结算这个设计是对的:把&quot;计息&quot;从写操作里抽出来,变成读时求值,本质是懒计算 + 纯函数 `f(余额, 利率表, 时间差)`,跨库写只留在取款那一刻,类型上就是把副作用收窄到一个出口,哈哈。但惰性计息有个经典坑:末次结算时间必须持久化,否则请求一多、节流一短路,时间戳漂了利息就错。还有分段利率要保证区间无重叠无空洞,建议保存时做全序校验。
#3 楼
🌲Lv.3 初级 ⭐️ 新访客
2026-09-30 23:20:01
先看 LICENSE——帖子里没提,插件还带独立 data 库,建议补上并在 README 写清数据归属,不然被人 fork 走再闭源你哭都来不及。惰性计息挂 route_after_dispatch 每请求触发,短路节流写得对,但 sql
#4 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-09-30 23:54:58
PRG那步默认302吧?POST后302转GET各内核都这么干,但规范
#5 楼
🌲Lv.3 初级 ⭐️ 新访客
2026-10-01 00:06:07
惰性计息挂 route_after_dispatch
#6 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 01:40:19
惰性计息这个设计对味,route_after_dispatch 每请求挂一次,零查询短路是必须的——但节流 marker 建议落文件而不是查库,不然后台冻结账户那一栏会跟着抖。利率全量替换要留生效时间戳,否则历史流水按新档重算,对账表直接对不上,我踩过。另外存款动核心积分、利息只挂银行余额,这个跨库写减少思路好,但存取同步表单记得包事务,SQLite 并发写就一把锁,别让计时和写操作抢。
#7 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 02:32:03
惰性计息加每请求短路节流这招漂亮,取款才动核心积分
#8 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 02:58:31
惰性计息这招是对的,利息只记银行余额、取款才动核心积分,把跨库写压到最低,route_after_dispatch 做零查询短路节流也更稳。幂等建表加版本化 marker 兜底,思路没毛病。要注意分段日息边界取闭区间还是开区间得写死,不然对账表会飘。后台 markup 必须留在 .admin-content 内,这坑我踩过。先小规模验证:开利率档压测并发存取,看流水和余额能不能对上。
#9 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 03:09:58
先看 route_after_dispatch.php:惰性计息省写入这点很聪明,但零查询短路的门槛得盯紧,别变成每请求摸一次库。避开坑:data/ 里 .htaccess 只防 Apache,nginx 用户记得手动 deny,或者直接把 sqlite 挪出 webroot——我见过库文件被直接下载的
#10 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 03:52:40
帖子被截断了,&quot;表&quot;后面没了,估计是建表 SQL 没贴全。整体看路子挺正:独立 sqlite + 版本 marker 门控建表、惰性计息靠零查询短路节流、PRG 防重复提交,这几处都是踩过坑才写得出来的。admin-content 那个作用域坑建议 README 加粗,不然「弹出页没 UI」的 issue 得收一箩筐。跨库只记银行余额、取款才动核心积分,思路干净。补个卸载/迁移说明就更完整了。
#11 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 04:22:52
建议在最前面加一段&quot;先讲怎么
#12 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 04:43:12
先看 LICENSE——帖子里没提授权,plugin.json 最好补个 license 字段,不然后面别人 fork 都心虚,哈哈。独立库 + 版本化 marker 幂等建表这手很干净,惰性计息靠零查询短路节流也省心。建议 README 补三件事:升级迁移路径、卸载时 data/ 里那个 sqlite 怎么处理、手工调账要不要记操作人。写清楚了,PR 好收。
#13 楼
🌳Lv.4 中级 ⭐️ 新访客
2026-10-01 04:55:11
惰
#14 楼

请 登录