sunkaifei/FlyCms
sunkaifei/FlyCms has 658 GitHub stars and 252 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 04:29 UTC. Last push 2026-10-24.
Crecimiento de estrellas medido
- in 24h
- 0
- in 7 days
- Recopilando historial
- in 15 days
- Recopilando historial
- in 1 month
- Recopilando historial
Cambios netos en períodos que se solapan, no totales diarios. Los datos no disponibles se dejan en blanco. Las estrellas indican interés, no calidad.
Acerca de
FlyCms 是一个类似知乎以问答为基础的完全开源的JAVA语言开发的社交网络建站程序,基于 Spring Boot+Bootstrap3+MyBatis+MySql+Solr +Ehcache应用架构,专注于社区内容的整理、归类和检索,它集合了问答,digg,wiki 等多个程序的优点,帮助用户轻松搭建专业的知识库和在线问答社区。业务模块包括:权限管理,会员管理,角色管理,定时任务管理(调度管理),问答管理,文章管理,分享管理,短信接口管理和邮件系统发送(注册、找回密码、邮件订阅),跨域登录,消息推送,全文检索、前端国际化等等众多模块,等您自己来体验!
DatosREADME.md
OriginalFlyCms
一套前后端分离的开源内容建站系统:后台是 Vue 3 单页控制台,前台是 Freemarker 模板站。 核心技术 = 自定义模型引擎:文章、图片、下载、问答、链接……系统的一切内容模块都由后台在线建模生成(建模 → 自动建表 → 字段配置 → 模板渲染),不做第二套硬编码实现。目标是万能系统——用户只靠后台设置,就能生成任何想要的程序模块。历史上硬编码的内容模块正在按规划逐个退役并迁入模型引擎(见
docs/01-规划/主流CMS对标与全项目优化开发方案.md§9.4 阶段 U)。
后端 346 个 Java 文件 / 25 个业务模块 / 21 个 REST 控制器
前端 Vue 3 + TypeScript + Ant Design Vue,73 个页面组件
内容生产:fly_model(模型注册)→ fly_model_field(字段元数据)→ fly_cmodel_{code}(动态数据表)→ 通用管理页 + cmodel 模板通道
一、它现在是什么
FlyCms 最早是一个仿知乎的问答社区程序。经过持续重构,现在的内核是一套五面分离的 CMS 底座:
| 面 | 解决什么 | 对应能力 |
|---|---|---|
| 内容面 | 内容从哪来、长什么样 | 自定义模型引擎(唯一内容生产方式):建模 + 字段(含关联引用 relate/relates、URL 型图片 image_url/file_url、附件、地区等 19 种类型)+ 动态建表 + 通用数据管理;存量硬编码模块(文章/问答/分享/话题)退役中,评论/收藏收敛为平台能力 |
| 结构面 | 内容挂在哪、URL 怎么走 | 统一栏目树(列表 / 单页 / 外链 / 聚合,聚合可跨模型混排) |
| 呈现面 | 页面怎么渲染 | 模板中心(在线编辑 / 版本快照 / 一键回滚 / 皮肤导入导出)、碎片位与推荐位、模板标签手册 |
| 交互面 | 访客怎么参与 | 表单系统(可视化配字段)、站内信、公告、收藏、关注与 Feed、WebSocket 推送 |
| 运营面 | 站点怎么管 | SEO(sitemap / robots)、投稿与评论审核、敏感词过滤、审计日志、定时任务、菜单 / 角色 / 权限 |
二、技术栈
后端
| 组件 | 版本 / 选型 | 说明 |
|---|---|---|
| 运行时 | JDK 24 | maven-compiler-plugin 开启 proc:full 以支持 Lombok |
| 框架 | Spring Boot 4.1.1 | Jakarta 命名空间 |
| ORM | MyBatis(mybatis-spring-boot-starter 4.1.0) |
XML 与 Mapper 同目录打包 |
| 模板 | Freemarker | 前台站点渲染,开启 ALLOWS_NOTHING_RESOLVER 沙箱 |
| 缓存 | Caffeine | 已替代原 EhCache 2 |
| 连接池 | Druid 1.2.28 | Boot 4 下由 DruidConfig 手动装配 |
| 调度 | Quartz 2.3.2 | 后台可启停任务、查看执行日志 |
| 数据库 | MySQL 8(utf8mb4) | SQL 仅适配 MySQL |
| 检索 | Lucene 7.4 | 当前为技术中立接缝:原 Solr 已移除,SearchService 保留空实现,规划接入 Elasticsearch |
| 其它 | Hutool 5.8、jsoup 1.17、BCrypt、Log4j2、阿里云短信 SDK | 验证码、XSS 清洗、密码散列 |
前端
| 组件 | 版本 |
|---|---|
| Vue | 3.5.41 |
| TypeScript | 6.0 |
| Vite | 8.3 |
| Ant Design Vue | 4.2 |
| 状态 / 路由 | Pinia 4、Vue Router 5 |
| 基座 | Vue Vben Admin 5(@vben/* 内部包) |
| 工程 | pnpm 11 workspace + turbo,Node ^22.18 || ^24.12 |
后台是 SPA(apps/web-antd),通过 /api/** 与后端通信;前台仍是服务端渲染的 Freemarker 模板站,两者互不干扰。
三、功能清单
前台
- 栏目:列表 / 单页 / 外链 / 聚合四种形态,目录名即 URL,支持无限层级与移动改挂
- 内容模型:后台建模后自动生成数据表,前台按模型
code路由,列表自带分页条 - 问答:发布问题、悬赏积分邀请回答、答案列表与统计
- 文章:分类无限级、话题聚合、评论、顶踩、收藏
- 分享:分享资源地址赚取积分,支持积分兑换
- 表单:
<@fly_form code="...">输出表单,提交走POST /api/form/submit/{code} - 用户:注册(手机 / 邮箱)、登录验证码与失败次数限制、密码找回、手机 / 邮箱绑定、邀请注册奖励、积分充值
- 互动:关注、粉丝、Feed 动态、收藏、站内信、WebSocket 实时推送
- SEO:
/sitemap.xml、/robots.txt由配置键fly_sitemap_status/fly_sitemap_limit/fly_robots控制
后台(Vue 控制台)
| 分组 | 功能 |
|---|---|
| 系统管理 | 管理员、角色组、菜单权限(后端动态菜单)、站内信、公告、审计日志、附件库、导航、友情链接 |
| 内容 | 内容模型(模型 / 字段 / 数据 CRUD)、栏目、文章、评论审核、投稿审核(先审后发开关 + 批量通过 / 驳回) |
| 呈现 | 模板中心(文件树编辑、版本快照与回滚、皮肤导入导出、标签手册)、碎片位 / 推荐位 |
| 交互 | 表单管理(表单 + 字段 + 数据 + CSV 导出) |
| 运营 | 网站配置、定时任务、积分规则、订单、敏感词过滤、用户管理 |
| 统计 | 仪表盘 |
平台能力
- 动态菜单与权限:菜单、角色、权限点全部数据驱动,
actionKey同时用于前端按钮显隐(accessCodes)和后端 403 兜底 - 模板版本化:每次保存自动快照,改坏模板可一键回滚
- 定时发布:
TimingPublishJob+publish_time字段,status=4为待定时发布 - 审计日志:
AdminLogInterceptor记录后台操作,含敏感字段脱敏 - 定时任务:后台启停、Cron 配置、执行日志
四、安全设计
| 风险 | 处理 |
|---|---|
| 模板 RCE | Freemarker TemplateClassResolver.ALLOWS_NOTHING_RESOLVER 沙箱 |
| 上传 getshell | UploadSafeUtil.safeImage:扩展名 + MIME + 文件头魔数三重白名单,强制重命名丢弃原始文件名 |
| SQL 注入 | ORDER BY 走 OrderbyUtils.check 白名单;动态建表 / 列名走 SqlSafeUtil.safeColumnName / safeNumber |
| XSS | 提交内容用 jsoup Safelist.none() 清洗(表单模块),页面输出 HTML 转义 |
| 越权 | Session 认证 + requireAdmin()(401)/ requirePermission()(403)双重校验 |
| 爆破 | 登录验证码 + 失败次数限制;密码 BCrypt 散列 |
| 权限放大 | 表单数据走统一表 + JSON,不做动态建表,避免 DDL 权限外溢 |
五、目录结构
FlyCms/
├── backend/ # Java 后端
│ ├── src/main/java/com/flycms/
│ │ ├── config/ # MVC、CORS、WebSocket、Freemarker 沙箱、Druid
│ │ ├── core/ # 实体、工具类、全局标签、上传安全
│ │ ├── interceptor/ # 登录拦截、审计日志
│ │ ├── module/ # 26 个业务模块(model / channel / template / form ...)
│ │ └── web/
│ │ ├── api/ # /api/** REST(后台 SPA 用)
│ │ ├── front/ # 前台页面控制器
│ │ └── tags/ # Freemarker 自定义标签
│ ├── src/main/resources/
│ │ ├── application.yml
│ │ └── i18n/ # 国际化
├── frontend/ # pnpm workspace
│ ├── apps/web-antd/ # 后台控制台(Vue 3)
│ ├── packages/@core/ # 基础能力包
│ └── internal/ # 构建配置
├── sql/ # 数据库全量备份快照(最新一份,含结构+数据)
└── docs/ # 开发规划、模型手册、改造方案、审查报告、运维配置
六、快速开始
环境要求
- JDK 24、Maven 3.6+
- MySQL 8(字符集
utf8mb4) - Node
^22.18 || ^24.12、pnpm ≥ 11
1. 数据库
sql/ 目录只保留一份全量备份快照(表结构 + 全部数据一体,含所有已上线功能与权限节点),无需再按阶段执行增量脚本:
mysql -u root -p -e "CREATE DATABASE flycms DEFAULT CHARACTER SET utf8mb4;"
mysql -u root -p --default-character-set=utf8mb4 flycms < sql/flycms_20260928_093335.sql
⚠️ 必须加
--default-character-set=utf8mb4:mysql 客户端在某些终端环境默认 latin1 连接,中文数据会真实乱码(写入即损坏,不是显示问题)。备份快照由 MySQL 5.7.44 导出,兼容 MySQL 8 导入。导入后默认管理员:
flycms / admin123(请登录后立即改密)。
备份与更新快照:系统内置纯 Java 全库备份(不依赖 mysqldump),后台「系统工具 → 数据库备份」或直接调用:
curl -X POST http://localhost/api/system/tools/db/backup # 需管理员会话
备份文件生成于 backend/backup/flycms_*.sql;需要刷新 sql/ 快照时,将最新一份复制过去替换即可。
2. 后端
修改 backend/src/main/resources/application.yml 的数据库连接,然后:
cd backend
mvn clean compile # 编译
mvn spring-boot:run # 运行
默认监听 http://localhost:80,前台 http://localhost/;管理控制台是前端 Vue SPA(见下一步)。
3. 前端控制台
cd frontend
pnpm install
pnpm dev:antd # 开发端口 5666
vite.config.ts 已配置代理:/api/** → 后端 80 端口,/captcha 直连(验证码接口无 /api 前缀)。
4. 常用命令
| 命令 | 作用 |
|---|---|
mvn -o compile |
后端编译校验 |
pnpm dev:antd |
启动后台开发服务 |
pnpm build:antd |
构建后台 |
pnpm check:type |
前端类型检查(vue-tsc) |
pnpm check |
循环依赖 + 依赖 + 类型 + 拼写全量检查 |
七、打包部署
cd backend
mvn clean package # 产出 target/FlyCms.jar
java -jar target/FlyCms.jar --spring.profiles.active=prod > FlyCms.log 2>&1 &
- 配置外置:复制
application.yml为application-prod.yml后修改(务必改掉默认数据库口令) - 静态资源与上传目录在
application.yml的spring.web.resources.static-locations:./views/static/、./uploadfiles/ - 模板目录:
./views/templates/ - 停止:
ps -ef | grep FlyCms.jar | grep -v grep | cut -c 9-15 | xargs kill -s 9;看日志:tail -200f FlyCms.log
短信 SDK 使用官方坐标
com.aliyun,Maven 可直接解析,无需手动安装 jar。 Solr 不再需要——检索模块已改为技术中立接缝,不接 ES 也能正常跑(搜索返回空结果)。
八、前台模板与标签
模板放在 views/templates/{主题}/,后台「模板中心」可在线编辑、保存即生成版本快照。
<!-- 模型分页列表,自带分页条 -->
<@fly_page_model model="loupan" rows="10">
<#list dataList as row>
<a href="/loupan/${row.shortUrl}.html">${row.title}</a>
</#list>
${pageHtml!''}
</@fly_page_model>
<!-- 碎片位 / 推荐位 -->
<@fly_block key="home_focus">
<#list block.items as it><img src="${it.image}"></#list>
</@fly_block>
<!-- 表单 -->
<@fly_form code="feedback">
<form action="/api/form/submit/${form.formCode}" method="post">
<#list form.fields as f>
<input name="${f.fieldCode}" placeholder="${f.placeholder!''}">
</#list>
<#if form.needCaptcha == 1><img src="/captcha"><input name="captcha"></#if>
</form>
</@fly_form>
<!-- 按角色显隐 -->
<@fly_userpower groupName="技术专家组">
<a href="/ucenter/article/add">发布文章</a>
</@fly_userpower>
完整标签清单见后台「模板中心 → 标签手册」,或 TagManualService.java。
九、开发文档
| 文档 | 内容 |
|---|---|
docs/01-规划/主流CMS对标与全项目优化开发方案.md |
平台级复评 + K–R/U 阶段施工图;§9.4 阶段 U = 旧模块退役与统一生产总纲 |
docs/01-规划/自定义模型能力缺口与内容模块生产方案.md |
引擎缺口清单(E1–E10)与「每个存量模块如何用自定义模型生产出来」的逐模块对照 |
docs/01-规划/内容体系收敛与模型命名改造开发方案.md |
表名 / 主键策略的 ADR 与迁移步骤(P/D 批次已落地) |
docs/全智能CMS对标分析与开发规划.md |
阶段 A~J 的整体演进规划与设计决策 |
docs/02-手册/自定义模型系统开发手册.md |
内容模型建模、字段类型、数据表生成规则 |
docs/03-报告/2026-09-24-后端代码审查报告.md |
后端审查报告与已修 Bug 清单 |
docs/03-报告/2026-09-24-规划漏开发补齐报告.md |
规划对标后的漏开发补齐记录 |
docs/02-手册/前端权限接入开发手册.md |
前端权限码与按钮显隐约定 |
docs/04-运维/nginx-upload-security.conf |
上传目录的 Nginx 加固示例 |
十、已知边界
- 检索:
SearchService目前是空实现(方法签名保留),站内搜索返回空结果;接入 Elasticsearch 时替换实现类即可,调用方无需改动 - 数据库:SQL 仅适配 MySQL,切库需自行改写 Mapper
- 配置文件:
application.yml内含明文数据库口令与devtools.enabled: true,生产环境务必外置并关闭 - 上传目录:
Const.UPLOAD_PATH是相对路径./uploadfiles,部署换工作目录会导致上传丢失,建议配合docs/nginx-upload-security.conf做目录约束
十一、贡献
欢迎提 issue 与 PR。提问题时请附上复现步骤、环境版本与日志片段。
License
MIT