本项目架构决策与任务规划由 AI 项目经理产出、编码由 AI 完成、人类负责拍板决策与验收测试。但它不是「无人审查的 AI 吐码」:高度规范化的架构基线(ADR + 黄金样板)+ 代码生成器 + 可复现的保真回归(tests/generator-baseline/verify.sh)+ 全程安全基线,正是支撑 AI 协作产出一致、安全、可维护代码的基础设施。换句话说——这个项目本身,就是「如何让 AI 稳定产出生产级代码」的一份可运行答卷(质量自证机制见下方「核心特性」与「安全特性」章节)。
项目地址:https://github.com/BenXinAdmin-PHP/benxin-admin-server
✨ 核心特性
🏗️ 代码生成器护城河
一条 php think bx:make 从表结构直出全栈产物:后端四件套(Model / Controller / Service / Validate)+ 路由 + 菜单权限 seeder + 前端列表页 / 编辑表单 / 分配弹窗 / API 薄壳。覆盖三类范式——纯 CRUD、树形(递归 CTE 或内存建树)、授权链路(角色分配菜单 + Casbin 同步 + 事务回滚);数据权限(五档)作为横切能力贯穿其中(任何模块按需挂 applyDataScope,非独立复刻范式)。「生成 == 手写黄金样板」逐字保真,回归基线随仓可复现:bash tests/generator-baseline/verify.sh。
🍖 吃狗粮闭环
生成器不是玩具——真实业务(内容、系统公告等)就是 bx:make 生成的。「先手写黄金样板 → 暴露缺口回炉生成器 → 业务模块零手工自动复刻」闭环成立:例如富文本净化能力,手写内容模块沉淀 → 回炉进生成器 → 系统公告模块自动复用,零手工接线。
🔐 安全基线全程贯穿
JWT 双 guard 物理隔离、Casbin RBAC、数据权限五档、三方密钥 AES 入库、富文本 XSS 净化、上传双重校验、支付回调四件套、多维限流防刷——每项均已落地并过模块级验收,系统化清单见下方「🔐 安全特性」章节。
🎨 资源合规·可放心商用
全程未嵌入任何商业付费字库(正文系统字体栈、零嵌入,需品牌字仅用 OFL 开源字体如思源黑体/MiSans/Inter);图标仅用 Element Plus Icons(MIT)/ wot-design-uni 内置 / Iconify 开源集(Remix Apache-2.0 / Tabler MIT / Lucide ISC);图片仅自有 / CC0 / 框架默认。配合 Apache-2.0 + 依赖零 AGPL/GPL/SSPL 传染,整套底座可直接用于商业项目,无字库 / 图标 / 依赖授权风险。
📱 全栈三端
ThinkPHP 8 后端 + Vue 3 / Element Plus 后台 + uni-app C 端(一套代码出微信小程序 + H5)。C 端懒登录:用到核心业务前不强制登录,登录即注册,微信 + 手机号缺一不可。
🧩 通用业务底座
内容 CMS(分类树 / 内容 / 广告位 + 富文本净化)+ 微信能力(access_token 中心化缓存 / code2session / 网页 oauth)+ 支付框架(yansongda/pay,订单状态机 / 退款 / 事件解耦)+ 消息(短信渠道 / 验证码 / 系统公告)。具体业务作闭源上层叠加,不进本仓(守开源边界)。
🛠 技术栈
Valkey lcobucci/jwt yansongda/pay
依赖协议全部可商用、无 AGPL/GPL 传染。
🗂 架构概览
三个独立仓库,均 Gitee + GitHub 双开双推:后端(本仓,含代码生成器)/ 后台前端 benxin-admin-web / C 端 benxin-admin-uniapp。
app/
├── common/ # 公共层:基类 / 中间件 / 异常 / 库
│ ├── base/ # BxController / BxModel / BxService / BxValidate(黄金样板四件套基类)
│ ├── middleware/ # RequestLog / Cors / JwtAuth / CasbinAuth / OperLog
│ ├── library/ # BxJwt / Result / ErrorCode / ConfigCrypt / BxCache / 微信·支付·短信
│ └── service/ # CasbinService / BxPay / SmsCodeService / UserAuthService
├── admin/ # 后台应用,对外前缀 /admin
└── api/ # C 端应用,对外前缀 /api
config/ · database/{migrations,seeds} · public/
extend/generator/ # 代码生成器(stub + 元数据 → 全栈产物)
tests/generator-baseline/ # 生成器保真回归基线 + verify.sh
docs/ARCHITECTURE.md # 架构基线与全部约定(权威文档)
docker-compose.yml # 仅 MySQL + Valkey
统一返回(业务码风格 A):{ "code":0, "msg":"success", "data":null, "request_id":"uuid", "timestamp":… },code=0 成功;HTTP 默认 200,结果以 code 为准(鉴权类允许 401)。错误码段见 docs/ARCHITECTURE.md §6.2。
🚀 快速开始
# 1. 安装依赖(生产 PHP 8.4)
composer install
# 2. 环境变量
cp .env.example .env
# 必填:SUPER_ADMIN_INIT_PWD(超管初始密码)
# JWT_ADMIN_SECRET / JWT_API_SECRET(openssl rand -hex 32)
# CONFIG_CRYPT_KEY(三方密钥 AES 入库密钥,openssl rand -hex 32)
# 3. 启动本地依赖(仅 MySQL:3308 + Valkey:6380,建议 Mac OrbStack)
docker compose up -d
# 4. 建表 + 业务种子(超管 / 菜单 / 字典 / Casbin / 各模块 perms)
php think migrate:run
php think seed:run
# 5. 起服务(独占 8801)
php think run -p 8801
curl http://127.0.0.1:8801/admin/v1/ping # -> {"code":0,"msg":"pong",...}
上面是方式一:Docker 依赖(默认)——只把 MySQL + Valkey 跑在容器里(建议 Mac OrbStack),PHP/框架仍跑本机。不想装 Docker 也可走下面的方式二。
方式二:本地裸装依赖(不用 Docker)
不依赖 Docker,把 MySQL 8 与 Valkey(或 Redis,协议兼容)直接装在本机。生产环境本就是裸机 + 宝塔 + SafeLine(见 §12 / docs/ARCHITECTURE.md),裸装即贴近生产形态。
# 1. 本地安装并启动依赖(任选其一的安装方式)
# MySQL 8:建库 benxin_admin(utf8mb4),建账号或用 root
# Valkey(推荐,BSD-3)或 Redis(协议兼容,二选一即可)
# macOS 示例:brew install mysql valkey && brew services start mysql && brew services start valkey
# 2. 环境变量:指向本地实例(裸装走默认端口 3306 / 6379)
cp .env.example .env
# .env.example 默认是 Docker 方式的端口(MySQL 3308 / Valkey 6380),裸装请改回默认:
# DB_HOST=127.0.0.1 DB_PORT=3306 DB_NAME=benxin_admin DB_USER/DB_PASS=<你的账号>
# REDIS_HOST=127.0.0.1 REDIS_PORT=6379 REDIS_PASSWORD=<如设了密码>
# 端口以 .env 为准;二者差异只在 DB_PORT/REDIS_PORT,其余键名一致。
# 仍必填:SUPER_ADMIN_INIT_PWD / JWT_ADMIN_SECRET / JWT_API_SECRET / CONFIG_CRYPT_KEY(同方式一)
# 3. 安装 PHP 依赖(生产 PHP 8.4 直接装;本地若为 PHP 8.1~8.3 临时忽略平台校验)
composer install # 生产 PHP 8.4
# composer install --ignore-platform-req=php # 本地 PHP 8.2 妥协,生产无此项
# 4. 建表 + 业务种子(超管 / 菜单 / 字典 / Casbin / 各模块 perms)
php think migrate:run
php think seed:run
# 5. 起服务(独占 8801)
php think run -p 8801
curl http://127.0.0.1:8801/admin/v1/ping # -> {"code":0,"msg":"pong",...}
随后登录与首登改密同方式一,见下方 **首次登录后台**。
🔴 安全必读
SUPER_ADMIN_INIT_PWD不设则不创建超管账号——本底座无任何默认弱口令,部署者必须显式设置强密码(超管admin密码即此值,Argon2id 入库;首登后请立即改密)。**生产务必 APP_DEBUG=false**(.env.example已默认 false)——调试探针与测试种子均靠它守门,生产不暴露。三方密钥(支付 / 短信 / OSS)AES 加密入库、不进仓库; .env已在.gitignore,严禁提交真实密钥。
📦 素材上传 / 存储部署
素材模块(bx_resource)的本地落点、安全加固、大文件 php.ini 配置、云存储 / VOD 开通,统一见下方专章 **素材存储部署指南**。
首次登录后台
部署前 .env必设SUPER_ADMIN_INIT_PWD=<强密码>——不设则不创建超管账号、无法登录(防默认弱口令的设计)。php think seed:run用该密码创建超管账号:用户名 **admin**、角色super_admin、Argon2id 加密。启动后台前端(benxin-admin-web,baseURL → 8801),用用户名 admin+ 上述密码登录;首登后请立即在后台改密。登录契约: POST /admin/v1/login→{ access_token, refresh_token, token_type, expires_in, refresh_expires_in }(§7)。C 端(uni-app)为懒登录:微信小程序 wx.login+getPhoneNumber/ H5 公众号 oauth+短信验证码,登录即注册,无需账号密码。
后台前端 / C 端起步见各自仓 README,VITE_API_BASE(_URL) 默认指向 http://127.0.0.1:8801。
依赖容器默认映射宿主机 MySQL 3308 / Valkey 6380(避开本机原生 3306 / 6379),容器内仍 3306/6379;无冲突可在 .env改回。本地若为 PHP 8.1~8.3,临时 composer install --ignore-platform-req=php(仅本地妥协,生产无此项)。首次起容器后再改 DB_PORT/账号需docker compose down -v清卷重起,让 MySQL 按新.env重新初始化。
🗄 素材存储部署指南
素材模块(
bx_resource)的部署运维须知:默认纯本地零配置即可完整跑通;云存储 / VOD 全是可选扩展,本底座不默认强依赖任何付费云服务(守开源边界)。
本地存储(默认,零配置)
物理落点:本地素材存项目根 storage/目录(root_path()/storage,在 Web 根public/之外,URL 无法直链、不可执行);上传文件 uuid 重命名(防穿越 / 覆盖 / 伪装可执行),realpath校验防目录穿越。受控取流:素材访问统一走后端鉴权取流路由 GET /admin/v1/resources/:id/raw(CasbinAuth+system:resource:list权限),不裸公网直链;文件管理模块同理GET /admin/v1/files/:id/raw。默认即用:不配任何云即完整可用——素材分类树 + 全类型上传 / 取流 / 批量删开箱即跑。
安全配置(部署侧加固,§8 安全基线落地)
目录隔离(第二道防线):
storage/必须在public/之外。生产 Nginx 确保storage/不暴露为静态目录、不解析 PHP——即便上传白名单已拦可执行文件,目录隔离仍是兜底。示例:# 站点根指向 public/,素材目录 storage/ 在其外,URL 天然不可达
root /path/to/benxin-admin-server/public;
# 双保险:显式拒绝 storage/ 直链(即便误把目录纳入可达范围)
location ^~ /storage/ { deny all; return 404; }
# PHP 仅在 public 内解析;storage/ 不经 fastcgi,绝不执行
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}目录权限:
storage/对 PHP 进程可读写、不可执行。上传白名单(程序行为,恒生效):按
media_type分组的扩展名白名单(非黑名单)+finfo真实 MIME 双重校验 +PERMANENT_DENY黑名单恒覆盖配置——php / phtml / phar / exe / sh / bat / js / mjs / html / htm / svg / jsp / asp / ...等可执行或可内联脚本类型永久排除,即便管理员误配白名单也拒绝。切勿尝试在配置里放开这些可执行扩展名。
大文件上传配置
素材的 local / 七牛 / 阿里 OSS 上传走服务端中转,受 PHP 上传限额约束。PHP 默认 post_max_size=8M / upload_max_filesize=2M 偏小,中大文件(视频、大图)会在进入应用前被 PHP 拒绝。素材 app 层上限为 100MB(ResourceService::MAX_SIZE),生产需调大 php.ini(值 ≥ 100MB,超限请求才会走到 app 层返回 422,而非被 PHP 直接拒):
post_max_size = 100M
upload_max_filesize = 100M
改后重启 PHP / php think run;裸机 + 宝塔在面板「PHP → 配置修改」处调post_max_size/upload_max_filesize。前端常量对齐:web 端有上传前大小预判常量 RESOURCE_MAX_UPLOAD_MB(src/api/resource.ts,当前 100,已与 app 层 100MB 对齐);若调整 app 层 / php.ini 上限,请同步改该常量,否则前端会按旧值提前拦截。大视频推荐 VOD 客户端直传:开通腾讯云 VOD 后,大视频由浏览器经官方 SDK 直传腾讯云、不经 PHP / 服务端中转,无 php.ini 限额;服务端中转(local / OSS / 七牛)始终受其约束。
PHP 生产安全配置(display_errors / APP_DEBUG)
生产两道「错误不进响应体」的配置,防信息泄露 + 防响应被 PHP 错误污染。与上节「大文件上传配置」互补:即便 php 限额拒绝大文件,本节配置确保响应不被 warning 污染(前端能正确解析为失败、而非拿到脏数据)。
① display_errors(生产必关)
开发环境 display_errors=On 方便调试(错误直接显示),但生产必须 Off:否则错误信息(文件路径 / SQL / 框架版本 / 调用栈)会暴露给访问者(信息泄露漏洞),且 PHP warning / notice 文字会被打印进 HTTP 响应体、污染 JSON 响应(前端拿到脏数据)。生产 php.ini:
display_errors = Off ; 错误不输出到响应(生产必关)
log_errors = On ; 错误改记日志,运维查日志排查
error_log = /path/to/php-error.log
裸机 + 宝塔:面板「软件商店 → PHP → 配置修改」处改 display_errors / log_errors。
② APP_DEBUG(生产关闭)
生产 .env 须 APP_DEBUG=false(已列为「安全特性 → 生产基线」):ThinkPHP 调试模式关闭后,异常经全局异常处理器统一转 {code,msg} 信封,不吐原始错误页 / 调用栈。
APP_DEBUG=false
与素材模块的关联:素材的 local / 七牛 / OSS 服务端中转上传受 php 限额约束(见上节「大文件上传配置」);即便大文件被 php 限额拒绝,display_errors=Off 也确保响应不被 warning 污染——配合前端拦截器「脏响应如实失败」加固(web 端已落地),构成两层防御:PHP 侧让错误根本不进响应(治本)、前端侧让任何来源的脏响应如实失败(治标但稳)。大文件优先走 VOD 客户端直传(不经 PHP、无 php 限额)或调大 php 限额(均见上节)。
云存储 / VOD 开通(可选扩展,默认关闭)
★ 云存储(阿里 OSS / 七牛)与 VOD(腾讯云)全是默认关闭的可选扩展,纯本地零配置即可完整跑通素材管理。开通在后台 「参数配置」(
group=storage) 配 driver + 密钥(敏感项 AES 加密入库,展示脱敏)。
按 media_type真路由(缺省全local):图片 → 七牛、文档 / 压缩包 → 阿里 OSS、音视频 → 本地或腾讯 VOD。未开通自动回退 local:选了云 driver 但对应必填配置不全,自动回退 local并Log::warning,不影响默认使用(配置不全不挂)。签名 URL:云资源走私有 bucket + 带有效期签名 URL(默认 3600s,实时签发、过期失效,故不缓存落库),不裸公网直链。
已落地的 bx_config 配置项(group=storage):
storage_driver_image=qiniuqiniu_access_keyqiniu_secret_key / qiniu_bucket / qiniu_domain(可选 qiniu_url_expire,默认 3600)storage_driver_document=ossstorage_driver_archive=ossoss_access_key_idoss_access_key_secret / oss_endpoint / oss_bucket(可选 oss_url_expire,默认 3600)storage_driver_video=vod_txstorage_driver_audio=vod_txvod_tx_secret_idvod_tx_secret_key / vod_tx_sub_app_id(齐全才视「已开通」)+ vod_tx_callback_key(回调验签)/ vod_tx_procedure(转码模板)
VOD 真实接入提示:需配真实腾讯云凭据 + 转码回调域名;转码回调走共享密钥验签( vod_tx_callback_key),真实接入可按业务扩展 ConfirmEvents。PlayAuth 防盗链播放留上层业务扩展(v1 仅返回播放 URL)。
⚙️ 代码生成器
# 1) 建好目标表(migration) 2) 可选配模块元数据 extend/generator/configs/<m>.php
# 3) 生成(--output 指向独立目录便于 diff 验收;缺省落真实 app 路径,前端产物落 output/ 人工 copy)
php think bx:make bx_post --config=extend/generator/configs/post.php --output=runtime/generated/post --dry-run
php think bx:make bx_post --config=extend/generator/configs/post.php # 落地(默认不覆盖,加 --force 覆盖)
# 保真回归(防污染硬门):重生成八标的与基线逐字比对(仅 @date 差)
bash tests/generator-baseline/verify.sh # 全 ✓ 即「生成 == 黄金样板」
产物 = 后端四件套 + 路由片段 + 菜单 perms seeder + 前端列表/表单/分配弹窗/api 薄壳。八个黄金样板标的(post/role/menu/dept/admin/dict/config/file)的保真基线在 tests/generator-baseline/,clone 即可复现回归。
🔐 安全特性
以下每项均已落地并过模块级验收:
认证:JWT 双令牌(access + refresh),后台 / C 端双 guard 物理隔离(独立密钥 + aud+ Valkey 独立黑白名单命名空间);登出黑名单、refresh 白名单。CSRF:Bearer Token 置于 Authorization头 + 无 Cookie 会话(token 存 storage 非 cookie),跨站请求无法自动携带凭据,CSRF 天然免疫;H5 微信 oauth 登录流额外用随机state(写 Valkey 短 TTL、回调比对)防登录 CSRF。授权:Casbin RBAC(粒度到接口 / 按钮);数据权限五档(全部 / 本部门 / 本部门及以下递归 CTE / 仅本人 / 自定义),多角色取最宽。 密钥:三方密钥 AES-256 入库、密钥置 .env不进仓库、展示脱敏;git 全历史 0 凭据泄露(pickaxe 核验)。数据:全程 ORM 参数化、字段白名单防批量赋值、软删唯一键不可复用。 XSS 防护:富文本后端 HtmlPurifier 白名单净化(落库前 clean,堵存储型 XSS 主入口)+ 前端框架默认输出转义(Vue / Element Plus 插值自动转义、不可信内容不走 v-html)+ C 端rich-text渲染不执行脚本——后端净化 + 前端渲染双重防护。上传:真实 MIME + 扩展名双重校验、重命名、落非 Web 可执行目录。 日志:操作 / 登录全审计 + 脱敏红线(密码 / token / 手机号 / 验证码黑名单 + 语义正则)。 支付:回调四件套(验签 + 幂等 + 金额二次校验 + 状态机合法迁移)。 防刷:登录 / 短信多维限流 + 验证码消费即删 + 错误锁定。 生产基线: APP_DEBUG=false、探针 / 测试种子全APP_DEBUG守门、无默认弱口令、统一异常不泄堆栈。
安全响应头(生产 Nginx / SafeLine 层配): Content-Security-Policy(XSS 纵深)+X-Frame-Options(防点击劫持)+X-Content-Type-Options: nosniff+ HSTS +Referrer-Policy。密码复杂度策略:后台 admin 密码强度校验可在应用层补(C 端走微信 + 手机号无密码,不涉及)。 依赖持续审计:开源后建议接 composer audit/ dependabot 定期盯依赖 CVE。token 存储权衡:token 存 storage(非 HttpOnly cookie)→ CSRF 天然免疫,但 XSS 可窃取,属「C 端无服务端会话」的取舍,据实说明、不回避。 IDOR 提示:底座 C 端当前仅只读公开内容,无水平越权风险;上层业务若加「我的订单 / 资料」类接口,须按 user_id过滤防越权读他人数据。