# AstraCMS **Repository Path**: grapefruit-pie/AstraCMS ## Basic Information - **Project Name**: AstraCMS - **Description**: 内容基座,连接 AI 的星辰” - **Primary Language**: PHP - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-12 - **Last Updated**: 2026-09-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AstraCMS AstraCMS 是一个基于 ThinkPHP 8.1、Bootstrap 5 和原生 JavaScript 的内容管理系统。 主要功能包括:内容与栏目管理、单页与页面编排、媒体、表单、会员、SEO、RBAC 权限、审计日志和 API 管理。 当前版本:`1.0.0`。版本号以根目录 [`VERSION`](VERSION) 为准,发布流程见 [`docs/releases.md`](docs/releases.md)。 ## 当前状态 后台视觉参考根目录 `soybean-admin-antd-main`(SoybeanAdmin AntDesign,MIT License),采用 Bootstrap 5 与原生 JavaScript重新实现,不加载 Vue、Vite、Pinia 或 Ant Design Vue 运行时。ThinkPHP 模板、RBAC 权限与现有表单流程保持不变。 - ThinkPHP 8.1 项目骨架、纯 Bootstrap 5 后台布局和控制台已完成 - 用户登录、失败锁定、密码修改和 CSRF 防护已完成 - RBAC 用户、角色、权限节点、部门、菜单及审计日志已完成 - 后台导航由菜单表驱动,并根据当前用户权限显示 - 权限模块列表支持关键词、状态、部门、类型和日期等组合筛选,并提供空状态、Toast 反馈、加载状态及快捷键 - 主内容区采用统一的页面说明、主操作、筛选、数据列表和分区表单布局,角色权限矩阵使用独立业务组件 - 系统配置 / 站点设置已完成第一版 - 系统监控第一版已完成:独立权限控制数据库、目录、磁盘和 PHP 扩展健康检查,并提供不暴露原始日志内容的错误日志摘要 - 定时任务中心第一版已完成:统一登记内容发布、媒体清理和系统健康检查任务,支持启停、Cron 配置、并发锁、手动执行与结果日志 - 安全中心第一版已完成:汇总登录失败、来源 IP、账号锁定与限流窗口,展示 7 日趋势、可疑来源和当前防护策略,并支持审计化人工解锁 - 数据分析第一版已完成:公开内容浏览按日聚合,后台支持 7/30/90 天趋势、热门内容、栏目贡献、发布与表单指标,并遵守内容数据范围 - SEO 管理已按任务拆分为概览、页面审计、URL 管理、Sitemap 和静态发布五个工作区:支持动态链接、伪静态路径、静态页面三种全站 URL 模式及栏目/内容命名规则,可按完整站点或单页原子生成真实 HTML,并提供安全的 301/302 站内重定向管理 - SEO 管理保持为独立一级模块,按概览、页面审计、URL 管理、静态发布和 Sitemap 拆分工作区 - 会员体系第一版已完成:后台拆分“会员列表”和“会员组管理”,前台提供可配置开放的注册、登录、退出、个人资料与账户安全中心;会员与后台管理员使用独立身份和会话,后台启停、密码重置、会员组停用及删除会即时撤销前台旧会话 - 站内通知中心第一版已完成:按登录账号隔离通知,顶部展示未读角标,内容审核发布、定时任务和表单咨询会自动生成待办消息 - 内容中心第一版已完成:内容模型与字段、分类树、标签、内容编辑、审核发布、定时发布和版本快照 - 模型字段已形成配置闭环:选择类字段支持选项配置,内容表单按类型动态生成控件并执行服务端校验;已产生内容数据的字段禁止改类型、改标识或直接删除 - 内容列表会在选定模型后按字段排序展示“列表显示”字段,“支持搜索”字段会参与数据库侧内容检索 - 内容查看与审核页展示完整模型字段;版本记录可打开只读历史快照,并同时查看当时的正文和模型字段 - 草稿和已驳回内容可从历史快照恢复;恢复会创建递增的新版本,其他状态必须先按流程撤回 - 内容版本快照包含当时的正文、动态字段和标签关系;历史数量按 `config/content.php` 的保留策略自动清理 - 内容删除流程已闭环:符合条件的内容先进入回收站,可恢复为草稿重新审核,也可在二次确认后永久删除关联版本、审核记录与字段索引 - 分类删除同样采用回收站流程:恢复遵守上级分类顺序,永久删除后才释放模型内分类别名 - 内容和分类在回收站期间继续占用业务别名;动态字段唯一值由业务预检与数据库唯一索引共同保护 - 后台内容支持真实前台模板预览:草稿、待审核和待发布状态均可预览已保存版本,预览受登录权限与数据范围保护,不改变状态、不增加阅读量,并禁止搜索引擎索引 - 内容编辑器按 `config/content.php` 周期保存完整浏览器快照,覆盖栏目、分类、标签、SEO、模型字段和正文;异常返回或刷新后可选择恢复,正式保存成功后自动清理,且按管理员账号隔离 - 正式内容页与预览页共用内容页面组装服务,统一展示模型中标记为 API 可见的动态字段和标签;停用栏目后正式内容入口同步失效 - 前台栏目与页面编排由 HTML 模板驱动:每个模板声明自己的可编辑区域,后台据此生成拖拽画布,并可组合多个模型区块、单篇内容、广告位和表单;旧版通栏、主栏、侧栏数据会按语义自动映射 - 内容模型可选择前台列表与详情模板,当前提供标准卡片、资讯列表、视觉展陈,以及文章、档案、产品、产品文档四类详情结构 - 内容模型新增产品文档中心与详情模板,可聚合子栏目、限定文档搜索,并自动生成章节导航、正文目录、代码复制及上一篇/下一篇;`ProductDocumentationSeeder` 提供完整可编辑示例 - 模型和分类列表可打开只读模板样式预览,直接复用正式站点组件与主题;预览仅使用公开内容,无数据时自动展示演示数据 - 页面区块采用草稿与线上快照隔离:后台可预览草稿,确认后独立发布;历史布局恢复只回到草稿,并使用乐观锁避免多人编辑互相覆盖 - 广告管理已完成第一版:广告位与广告内容分离,支持投放周期、状态和排序 - 媒体中心第一版已完成:文件夹、图片/PDF 安全上传、真实 MIME 校验、哈希去重、素材元数据和全局选择器 - 媒体处理已闭环:支持非破坏式缩放、裁剪、旋转、格式转换和压缩,派生素材与处理记录可追踪 - 上线加固已闭环:生产启动守卫、环境检查、数据库与媒体一致性备份、校验、定时保留和安全恢复命令 - 外部通知已闭环:SMTP 与签名 Webhook 使用持久化投递箱、重试退避、投递日志和手动重试 - API 平台已闭环:API Key、作用域、限流、请求审计、管理接口与 OpenAPI 文档均已实现 - 内容、分类封面及广告使用素材 ID 建立稳定关联,同时兼容外部 URL;被业务引用的素材禁止删除 - 内容正文使用本地部署的 Toast UI Editor 富文本编辑器,不依赖 Vue 或公共 CDN;前端依赖由 `pnpm-lock.yaml` 锁定 - 后台自定义样式位于 `public/static/nova/`;早期 AdminLTE 参考产物已经移除,运行时只保留实际使用的本地资源 ## 本地运行 ```bash composer install pnpm install --frozen-lockfile php think migrate:run # 先在 .env 设置符合密码策略的 ADMIN_INITIAL_PASSWORD php think seed:run -s RbacSeeder php think run -H 127.0.0.1 -p 8123 ``` 打开 `http://127.0.0.1:8123/admin`。 > 本机 `8000` 端口由另一个 CMS 占用,AstraCMS 本地开发端口使用 `8123`。 初始后台账号为 `admin`,密码必须通过 `.env` 的 `ADMIN_INITIAL_PASSWORD` 显式设置;项目不再提供可预测的固定默认密码。首次登录后请立即修改密码。 官网已补齐可展开的子栏目导航、手机直接搜索、文档检索和友好 404 页面。专项验证可运行 `pnpm test:site`,详见 [官网流程检查](docs/website-flow-review-2026-09-09.md)。 ## 代码质量 ```bash composer quality ``` 该命令依次执行 PHPUnit、全项目 PHPStan、核心写入链路 PHPStan level 8、架构检查、前端资源检查和可维护性门禁。可维护性门禁会阻止核心文件重新出现超长单行、空异常处理、公共脚本回流模板以及 Web/API 内容规则分叉。浏览器端权限范围与 UI 回归位于 `tests/rbac-scope-check.cjs` 和 `tests/ui-layout-check.cjs`。 正式发布前,在本地服务已启动后执行完整发布门禁: ```bash pnpm quality:release ``` 浏览器回归会创建并清理隔离的测试管理员和业务夹具,不读取真实管理员密码。测试优先使用 `ASTRACMS_BROWSER_EXECUTABLE` 指定的浏览器;Windows 未指定时自动查找 Edge 或 Chrome,CI 环境可执行 `pnpm exec playwright install chromium` 安装隔离浏览器。 项目分层、依赖准入和新模块开发约束见 [`docs/architecture.md`](docs/architecture.md)。 生产上线前必须逐项完成 [`docs/deployment-security.md`](docs/deployment-security.md),尤其是 HTTPS、安全 Cookie、Redis 会话、最小权限数据库账号和发布前备份。 ## 权限配置流程 后台以“权限管理”和“系统配置”为一级菜单。权限管理按以下顺序操作: 1. **部门管理**:建立组织树,维护部门编码与负责人。 2. **角色管理**:配置功能权限和数据范围(全部、本部门及下级、本部门、仅本人)。 3. **用户管理**:创建账号,选择所属部门并分配角色。 4. **菜单管理**:配置后台入口层级,并为菜单绑定页面查看权限。 5. **审计日志**:复核登录和敏感操作,确认配置是否按预期生效。 菜单决定“在哪里看到入口”,权限节点决定“能否访问页面或执行操作”,二者不会互相替代。 ## 后台交互规则 - **独立页面**:用户、角色及后续复杂业务对象的新建/编辑,涉及多个区域、授权或较长流程时使用。 - **右侧抽屉**:部门、菜单等需要对照当前列表或树结构完成的中等复杂配置使用。 - **确认弹框**:删除、停启用、密码重置等会改变状态或难以撤销的操作使用,并明确说明影响对象与后果。 - **列表页面**:只负责搜索、筛选、查看和发起操作,不再平铺创建或编辑表单。 - **按钮语义**:入口使用“新建”,最终提交根据场景显示“创建…”或“保存修改”,避免动作含义混淆。 ## 内容操作流程 1. **选择模型**:新建内容时先确定内容模型;模型决定字段结构,进入编辑页后不可切换。 2. **选择栏目并编辑草稿**:栏目是前台导航和页面归属;作者再填写正文、分类、标签和 SEO 信息,保存会生成版本快照。 3. **提交审核**:提交后正文锁定,作者不能继续修改。 4. **审核处理**:审核人员在待审核列表执行通过或驳回,也可以点击“查看”阅读完整内容;驳回必须填写具体原因。 5. **发布处理**:审核通过后由发布人员选择立即发布或定时发布。 6. **上线变更**:已发布内容不能直接编辑;必须先撤回为草稿,再重新经过审核和发布。 7. **归档删除**:已发布内容可以归档;只有草稿、已驳回和已归档内容允许移入回收站。 8. **恢复或永久删除**:回收站内容恢复后统一回到草稿并重新走审核发布;永久删除只允许从回收站发起且不可撤销。 ## 模块开发顺序 1. 后台基础框架与系统配置(第一版已完成) 2. 用户认证与 RBAC 权限(第一版已完成) 3. 内容模型、分类标签与内容编辑(第一版已完成) 4. 媒体中心(第一版已完成) 5. 模板、页面构建器与导航(页面草稿、预览、发布和版本恢复已完成) 6. 基础 SEO(全站元数据、Canonical、robots.txt 与 sitemap.xml 已完成) 7. 表单引擎与 API 平台(公开内容 API 与表单 MVP 已完成) 8. 数据看板、会员、SEO、通知、插件、安全与运维模块(数据分析、会员管理、SEO 管理、站内通知、系统监控、定时任务中心、安全中心第一版已完成) ## 内容组织关系 - **内容模型**定义内容的数据结构,例如文章、产品、案例;一个模型可以包含多个分类和多条内容。 - **分类**属于一个内容模型,用于该模型内部的树状归档和筛选,不直接生成前台导航。 - **标签**用于跨分类、跨模型的横向聚合,与导航层级无关。 - **栏目**是前台导航节点、页面容器和内容的直接归属。每条内容必须选择一个栏目;栏目可限定主模型,也可以配置为单篇内容、组合页面或外部链接。 - **页面区块**属于栏目,按顺序组合横幅、富文本、模型内容列表、单篇内容和广告位;一个组合页面可以通过多个列表区块展示多个模型。 - **广告位**定义页面上的稳定投放位置,广告内容定义实际素材和投放周期;页面区块引用广告位,不直接绑定某一条广告。 - **产品文档**不是写死模块:使用自定义模型定义版本、阅读对象、阅读时长和验证日期,使用栏目树定义章节,选择“产品文档”详情模板获得连续阅读界面。 ## 产品文档示例 在基础 RBAC 初始化完成后,可以安装官方产品文档示例: ```bash php think seed:run -s ProductDocumentationSeeder ``` 示例会创建一个“产品文档”自定义模型、四个结构化字段、产品文档栏目树和六篇已发布文档。入口默认为 `/docs`;根栏目会聚合全部子章节,搜索范围限定在当前文档模型。全部内容、字段、栏目与 URL 都可以继续在后台修改。 ## 环境要求 - PHP 8.1+ - Composer 2 - Node.js 18+ 与 pnpm 10+(仅用于同步后台前端资源) - MySQL 8.0+ - Redis 7.0+(缓存、队列模块启用时需要) ## 内容定时发布 生产环境应每分钟执行一次: ```bash php think content:publish-scheduled ``` 该命令使用数据库状态条件和行锁保证同一条内容不会被重复发布。 后台“系统配置 / 定时任务”可统一查看任务状态、调整启停与 Cron 元数据、手动执行及追踪日志。完整运维说明见 [`docs/scheduled-tasks.md`](docs/scheduled-tasks.md)。 ## 浏览器回归测试 回归脚本不保存管理员密码。运行前通过进程环境提供独立测试账号: ```powershell $env:ASTRACMS_TEST_ACCOUNT='admin' $env:ASTRACMS_TEST_PASSWORD='<本地测试密码>' node tests/ui-layout-check.cjs ``` 建议使用专用测试账号,不要在代码、命令历史或持续集成日志中写入生产凭据。