# zry-cms **Repository Path**: bzm121/zry-cms ## Basic Information - **Project Name**: zry-cms - **Description**: 志睿源官网内容管理系统(CMS):基于自研 Node.js Web 框架,站点内容全部后台可视化配置;含访客统计/反爬/归属地、留言微信推送 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-15 - **Last Updated**: 2026-10-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # zry-cms > 志睿源官网 · 企业官网内容管理系统(CMS) > > 一套**从零自研**的企业官网 CMS:基于自研 Node.js Web 框架,前后端分离, > 站点内容(文案、产品、服务、价格、案例、文章、进展、视频、导航、SEO)**全部后台可视化配置**, > 改一个字段即时生效,不需要改代码、不需要重新构建。 **关键词**:`CMS` `企业官网` `Node.js` `MySQL` `零框架依赖` `内容管理` `可视化配置` `JWT` `Markdown` --- ## ✨ 它能做什么 这不是一个写死内容的静态站点,而是一套**数据驱动的站点系统**: - **站点设置即配置**:17 张数据表按 `sgroup` 分组存放站点全部内容,后台按分组渲染成表单,保存即生效 - **内容类型可插拔**:产品、服务、价格档、能力实证、技术方向、文章、进展日志、视频号内容、优势条目、内容渠道 —— 每种都是独立的「列表 + 增删改 + 排序」三件套 - **前台只读、后台受控**:74 个接口中 20 个完全公开,54 个走 JWT 鉴权(含吊销表,登出即刻失效) - **Markdown 文档联动**:文章支持 Markdown 正文,后台可解析外部 md 分享链接并做 uuid 一键体检 - **无需打包构建**:前端是原生 HTML/CSS/JS,后台是原生 SPA,改完刷新即可 - **进展与文档双向关联**:站点上的「进展事件」(什么时候发生了什么)与「关联文档」(详情在哪份 Markdown) 分开建模,三个入口(在做什么 / 产品 / 服务)都能各自挂载 - **文档锚点双轨**:库里存**稳定短码**作为外链锚点,真正指向的 Markdown 由内容哈希决定 —— 文档更新后哈希变化,后台重导一次、短码不变,**外部链接永不失效**; 另有保存前校验 / 挂载前二次校验 / 后台一键体检三层兜底,避免死链 ### 内容关联模型(v1.1.0) ``` zry_track(栏目·在做什么)──┐ ├── 进展事件 zry_progress ── 可挂「详情文档」 zry_product(产品)─────────┤ └── 关联文档 zry_doc ── 三个归属维度均可为空、也可同时有值 zry_service(服务)─────────┘ ``` - 一个产品可以没有栏目(例如销售场景类产品),此时**直接用 `product_code` 挂文档**,不必强行造栏目 - 进展事件的聚合口径是**并集**:「所属栏目下的」∪「产品直挂的」,单取一侧会漏 - `category` 表达**性质**(dev / tech / biz / content / company),`*_code` 表达**归属**,两者正交,不可互相替代过滤 ### 后台管理能力一览 | 模块 | 能力 | |---|---| | 概览 | 站点数据统计面板 | | 站点设置 | 分组表单(公司信息 / SEO / 联系方式 / 社交 / 系统) | | 导航管理 | 导航项增删改与排序 | | 产品 | 增删改、批量排序、详情富文本 | | 服务 | 增删改,关联价格档与案例 | | 价格 | 多档位价格维护 | | 能力实证 | 案例增删改(含技术点 JSON、指标) | | 技术方向 | 方向标签维护 | | 文章 | Markdown 编辑、草稿、slug 自动生成 | | 进展日志 | 时间轴条目维护 | | 栏目(事项) | 栏目树 + 关联进展与文档 + 排序 | | 关联文档 | md 链接解析、uuid 校验与体检、三维归属(栏目 / 产品 / 服务) | | 视频号内容 | 视频条目增删改与排序 | | 七大优势 | 优势条目维护 | | 内容渠道 | 外部渠道链接维护 | | 留言 | 访客留言查看、状态标记、删除 | | 访客统计 | 访问明细、日聚合、来源/设备/地域分布、真实心跳甄别(anti-bot)、反爬拦截记录 | | 操作日志 | 后台操作留痕 | | 图片上传 | 后台图片上传(10MB 上限) | --- ## 🏗 目录结构 保持生产环境的原始目录约定(**不要改动层级**,否则入口的相对引用会失效): ``` zry-cms/ ├── zry.js # 站点入口:装配配置、启动服务 ├── .env.example # 环境变量样例(复制为 .env 后填写) ├── package.json │ ├── zry/ # 前端(静态站点 + 后台 SPA) │ ├── index.html about.html services.html products.html │ ├── product.html blog.html article.html now.html │ ├── track.html doc.html contact.html 404.html │ ├── admin/ # 后台(index.html + admin.js + admin.css) │ ├── assets/ # 图片资源 │ ├── css/ js/ # 样式与页面脚本 │ ├── node/ │ ├── zry/ # 业务模块 │ │ ├── index.js # 模块汇总 + 鉴权钩子(onbefore/onafter) │ │ ├── api.js # 前台公开接口实现 │ │ ├── admin.js # 后台接口实现(含登录、改密、上传) │ │ ├── http.js # 接口路由表 │ │ ├── md.js # Markdown 渲染与 md 链接解析 │ │ ├── util.js # 工具(scrypt 密码哈希、限流、slug) │ │ ├── visit.js # 访客统计:明细、日聚合、来源与设备分析 │ │ ├── geo.js # IP 地域解析(ip2region 四级兜底)+ ASN/运营商/IP 类型 │ │ ├── bot.js # 反爬与爬虫识别(含 robots.txt 规则) │ │ ├── collector.js # 日志采集长驻进程(pm2 独立进程) │ │ ├── notifypush.js # 留言事件 → 微信消息推送中心(签名 webhook,fire-and-forget) │ │ ├── database_cfg.js# 数据库配置(环境变量驱动) │ │ └── sql/ # 建表、初始化数据、升级脚本 │ │ ├── zry_db_bootstrap.sql │ │ ├── zry_schema.sql │ │ ├── zry_init_data.sql │ │ └── zry_upgrade_*.sql │ │ │ └── web/ # 自研 Node.js Web 框架(本项目唯一依赖) │ ├── shared/ # 站点前端硬依赖的共享静态资源(按部署路径原样保留) │ ├── js/wx-id.js # 微信内置浏览器访客身份采集(openid / 昵称头像) │ └── md/ # 共享 Markdown 渲染核心(与 md-reader 各端同源) │ ├── md-core.js # 解析核心 │ ├── md-enhance.js # 增强层(Mermaid 图形渲染) │ └── test/ # 跨端一致性用例与校验器 │ ├── index.js # 框架入口 │ ├── base.js # 基础能力 │ ├── router.js # 路由 │ ├── req.js # 请求封装 │ ├── db-manager.js # 数据库管理(MySQL / PostgreSQL) │ ├── jwt-manager.js # JWT 签发与校验 │ ├── session-manager.js # 会话(支持 Redis) │ ├── static-server.js # 静态服务(gzip / 缓存 / 拒绝规则) │ ├── ws-handler.js # WebSocket │ ├── libcfg.js # 平台配置解析 │ └── request-handler/ # 请求处理链路 │ └── upload/ # 上传目录(运行时生成) ``` --- ## 🚀 快速开始 ### 1. 准备数据库 ```bash # 建库建账号(先编辑文件替换 ) mysql -h127.0.0.1 -P3306 -u root -p < node/zry/sql/zry_db_bootstrap.sql # 建表 mysql --default-character-set=utf8mb4 -u root -p zry < node/zry/sql/zry_schema.sql # 初始化站点内容(可选,会清空并重灌示例数据) mysql --default-character-set=utf8mb4 -u root -p zry < node/zry/sql/zry_init_data.sql ``` ### 2. 配置环境变量 ```bash cp .env.example .env # 编辑 .env,填入你的数据库地址与 JWT 密钥 ``` JWT 密钥建议用随机值生成: ```bash node -e "console.log(require('crypto').randomBytes(48).toString('hex'))" ``` ### 3. 安装依赖并启动 ```bash npm install node zry.js 8090 # 或 pm2 start zry.js --name zry-cms -- 8090 ``` 浏览器访问: - 前台:`http://localhost:8090/` - 后台:`http://localhost:8090/zry/admin/` - 示例账号:`admin` / `admin123`(**部署后请立即修改**) --- ## 🔌 接口一览 | 分类 | 数量 | 鉴权 | 示例 | |---|---|---|---| | 前台内容接口 | 15 | 公开 | `GET /api/zry/site`、`GET /api/zry/home`、`GET /api/zry/product/:code` | | 栏目与关联文档 | 4 | 公开 | `GET /api/zry/tracks`、`GET /api/zry/doc/:code` | | 登录 | 1 | 公开 | `POST /api/zry/admin/login` | | 后台管理接口 | 54 | JWT | `GET /api/zry/admin/overview`、`POST /api/zry/admin/product` | ### 鉴权机制 - 后台接口统一走 `node/zry/index.js` 的 `onbefore` 钩子:除 `/login` 外全部要求有效 JWT - 登出采用**内存吊销表**(`jti` → 过期时间),Token 未过期也会立即失效 - 密码用 `scrypt`(N=16384)加盐哈希,校验使用 `timingSafeEqual` 定长比较 - 留言提交等公开写接口带内存限流,防刷 --- ## 🛡 安全设计 - **静态目录拒绝规则**:入口配置 `denyPatterns`,屏蔽 `node/`、`node_modules/`、`.` 开头的隐藏文件,以及 `.sql` / `.json` / `.env` / `.bak` 等后缀,**源码与配置不会通过 HTTP 暴露** - **关闭多语句**:`multipleStatements: false`,压缩注入面 - **参数化查询**:所有 SQL 走占位符 - **JWT 吊销**:登出即失效,不依赖 Token 自然过期 - **操作日志**:后台写操作留痕 --- ## 🧩 技术栈 | 层 | 选型 | |---|---| | 运行时 | Node.js ≥ 18 | | Web 框架 | **自研**(`node/web/`,HTTP/HTTPS/WS + 路由 + 会话 + JWT + DB + 静态服务) | | 数据库 | MySQL 5.7+ / MariaDB(框架也支持 PostgreSQL) | | 前端 | 原生 HTML + CSS + JavaScript,无打包工具 | | 后台 | 原生 SPA,无框架 | | Markdown | 内置解析器 + `turndown`(HTML → Markdown) | | 第三方依赖 | `mysql2` `mysql` `jsonwebtoken` `redis` `ws` `formidable` `form-data` `jsdom` `turndown` —— 仅此 10 个 | --- ## 📜 许可证 / License 本项目基于 **Apache License 2.0** 开源 — 详见 [LICENSE](LICENSE) 与 [NOTICE](NOTICE)。 Copyright 2026 白志明 (Bai Zhiming) > 仓库内的示例文案、图片与初始化数据为演示内容,已做脱敏处理,可自由替换为自己的站点内容。 > > 开源版的数据库地址 / 端口 / 账号 / 口令一律走环境变量;JWT 密钥无内置默认值; > 初始化 SQL 中的管理员账号为占位凭据(`admin` / `admin123`)。**仓库内不含任何可用的生产凭据。** --- ## 📌 版本 当前版本 **v1.1.0**,变更见 [CHANGELOG.md](CHANGELOG.md)。