PuranCMS 系统概述
什么是 PuranCMS?
PuranCMS 是一款基于 ThinkPHP 8.0 框架开发的轻量级内容管理系统(CMS),专为中小企业和个人开发者设计。系统采用前后端分离的架构思想,后端使用 ThinkPHP 8.0 提供 API 接口,前端使用 Layui 构建管理界面,模板引擎采用 ThinkPHP 原生模板引擎。
设计理念
简洁高效:去除冗余功能,专注于核心内容管理
灵活扩展:采用模型驱动架构,支持自定义内容模型
易于部署:标准 LAMP/LEMP 环境即可运行
安全可靠:内置权限管理、SQL 防注入、XSS 防护
核心特性
多模型内容管理(文章、产品、页面、图片、下载、招聘、分支等)
自定义导航菜单管理
广告位管理
留言管理
后台权限管理
操作日志记录
访客统计
插件扩展机制
UEditor 富文本编辑器集成
适用场景
PuranCMS 适用于以下场景:
企业官网建设
产品展示网站
新闻资讯网站
个人博客
小型电商网站
功能特性详解
内容管理
系统支持多种内容模型,每种模型对应不同的业务场景:
| 模型 | 说明 | 应用场景 |
|---|---|---|
| Article | 文章模型 | 新闻资讯、博客文章 |
| Product | 产品模型 | 产品展示、产品目录 |
| Page | 单页模型 | 关于我们、联系方式 |
| Image | 图片模型 | 图片画廊、相册 |
| Download | 下载模型 | 文件下载、资源分享 |
| Recruitment | 招聘模型 | 职位发布、招聘信息 |
| Branch | 分支模型 | 分支机构、门店信息 |
导航管理
支持自定义导航菜单,可绑定不同的内容模型和模板,实现灵活的页面跳转和内容展示。
广告管理
支持多种广告类型(图片广告、文字广告、HTML 代码),可设置广告位置、排序、状态等。
留言管理
前台用户可提交留言,后台管理员可查看、标记已读、删除留言,支持批量操作。
权限管理
基于角色的权限控制(RBAC),支持菜单权限、操作权限的细粒度控制。
数据统计
提供控制台仪表盘,展示访客统计、地区分布、流量统计、操作日志等数据。
技术栈说明
后端技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| PHP | >= 8.0 | 后端编程语言 |
| ThinkPHP | 8.0 | Web 框架 |
| MySQL | >= 5.7 | 关系型数据库 |
| Composer | latest | 依赖管理 |
核心依赖包
| 包名 | 用途 |
|---|---|
| topthink/framework | ThinkPHP 核心框架 |
| topthink/think-orm | ORM 数据库操作 |
| topthink/think-filesystem | 文件系统操作 |
| topthink/think-captcha | 验证码生成 |
| topthink/think-view | 模板引擎 |
| topthink/think-worker | Workerman 支持 |
| topthink/think-migration | 数据库迁移 |
| topthink/think-queue | 消息队列 |
| bacon/bacon-qr-code | 二维码生成 |
| phpmailer/phpmailer | 邮件发送 |
| zoujingli/ip2region | IP 地址解析 |
前端技术栈
| 技术 | 用途 |
|---|---|
| Layui | 后台 UI 框架 |
| UEditor | 富文本编辑器 |
| jQuery | JavaScript 库(Layui 内置) |
| ECharts | 数据可视化(控制台图表) |
服务器环境
Web 服务器:Nginx 1.18+ / Apache 2.4+
PHP 扩展:PDO、MBString、OpenSSL、JSON、Fileinfo
推荐配置:2 核 CPU / 4GB 内存 / 50GB SSD
环境要求与准备
服务器环境要求
PHP:版本 >= 8.0,推荐 8.1 或 8.2
MySQL:版本 >= 5.7,推荐 8.0
Web 服务器:Nginx 1.18+ 或 Apache 2.4+
Composer:版本 >= 2.0
PHP 扩展要求
确保以下 PHP 扩展已启用:
pdo_mysql- 数据库连接mbstring- 多字节字符串处理openssl- 加密支持json- JSON 处理fileinfo- 文件类型检测gd- 图像处理(验证码、二维码)
目录权限要求
以下目录需要写入权限:
runtime/- 运行时缓存目录public/uploads/- 文件上传目录logs/- 日志目录(如有)
检查环境
# 检查 PHP 版本 php -v # 检查 PHP 扩展 php -m | grep -E "pdo_mysql|mbstring|openssl|json|fileinfo|gd" # 检查 Composer 版本 composer -V
安装步骤指南
方式一:通过安装向导安装(推荐)
将项目文件部署到 Web 服务器目录
配置 Web 服务器,将网站根目录指向
public/目录访问
http://your-domain/install进入安装向导按照向导提示完成环境检测、数据库配置、管理员账号设置
安装完成后,访问
http://your-domain/admin登录后台
方式二:手动安装
克隆或下载项目
git clone https://github.com/your-repo/purancms.git cd purancms
安装依赖
composer install
配置环境变量
cp .example.env .env
编辑
.env文件,配置数据库连接信息导入数据库
mysql -u root -p your_database < database/install.sql
设置目录权限
chmod -R 755 runtime/ chmod -R 755 public/uploads/
配置 Web 服务器
参考下方 Nginx/Apache 配置示例
Nginx 配置示例
server {
listen 80;
server_name your-domain.com;
root /path/to/purancms/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}Apache 配置示例
项目已包含 public/.htaccess 文件,确保 Apache 启用了 mod_rewrite 模块。
配置参数说明
环境变量配置 (.env)
[APP] DEBUG = true [DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = purancms USERNAME = root PASSWORD = your_password HOSTPORT = 3306 CHARSET = utf8mb4 PREFIX = pr_
配置文件说明
| 文件 | 说明 |
|---|---|
| config/app.php | 应用配置(默认控制器、时区等) |
| config/database.php | 数据库配置 |
| config/route.php | 路由配置 |
| config/session.php | Session 配置 |
| config/cache.php | 缓存配置 |
| config/log.php | 日志配置 |
| config/view.php | 模板引擎配置 |
后台系统配置
登录后台后,可在"系统设置"中配置:
站点名称、Logo、后台 Logo
SEO 设置(标题、关键词、描述)
联系方式(电话、邮箱、地址)
版权信息、备案号
后端目录结构
核心目录说明
app/ ├── admin/ # 后台模块 │ ├── controller/ # 后台控制器 │ │ ├── Base.php # 后台基础控制器 │ │ ├── Dashboard.php # 控制台 │ │ ├── Content.php # 内容管理 │ │ ├── System.php # 系统设置 │ │ ├── Upload.php # 文件上传 │ │ └── ... │ └── view/ # 后台视图 │ ├── layout/main.html # 后台布局模板 │ └── ... ├── index/ # 前台模块 │ └── controller/ # 前台控制器 ├── common/ # 公共模块 │ └── controller/Install.php # 安装向导 ├── model/ # 数据模型 │ ├── BaseModel.php # 模型基类 │ ├── Article.php # 文章模型 │ ├── Product.php # 产品模型 │ └── ... ├── service/ # 服务层 │ ├── ContentService.php # 内容服务 │ ├── AdminService.php # 管理员服务 │ └── ... ├── middleware/ # 中间件 │ ├── AdminCheck.php # 后台权限验证 │ └── InstallCheck.php # 安装状态检查 └── taglib/ # 自定义标签库 └── PuranTag.php # PuranCMS 模板标签
目录职责
controller/:处理 HTTP 请求,调用服务层,返回响应
model/:数据库操作,数据验证,业务数据封装
service/:复杂业务逻辑,组合多个模型操作
middleware/:请求拦截,权限验证,日志记录
taglib/:自定义模板标签,简化前端数据调用
前端目录结构
静态资源目录
public/static/ ├── admin/ # 后台静态资源 │ ├── css/ # 后台样式文件 │ │ ├── admin.css # 后台全局样式 │ │ ├── dashboard.css # 控制台样式 │ │ ├── content.css # 内容管理样式 │ │ └── ... │ ├── js/ # 后台 JavaScript 文件 │ │ ├── admin.js # 后台全局脚本 │ │ ├── content.js # 内容管理脚本 │ │ ├── dashboard.js # 控制台脚本 │ │ └── ... │ └── ueditor/ # UEditor 编辑器 ├── index/ # 前台静态资源 │ ├── css/style.css # 前台样式 │ └── js/main.js # 前台脚本 └── layui/ # Layui 框架
视图模板目录
template/default/ # 默认模板主题 ├── layout/main.html # 前台布局模板 ├── index/index.html # 首页模板 ├── product-list.html # 产品列表模板 └── product-detail.html # 产品详情模板
前端架构说明
后台采用 Layui 作为 UI 框架
JavaScript 采用模块化 IIFE 模式,避免全局污染
AJAX 请求统一使用 Layui 内置的 jQuery
样式采用独立文件,按功能模块划分
模板目录说明
模板目录结构
template/ └── default/ # 默认模板主题 ├── layout/ # 布局模板 │ └── main.html # 主布局(header + content + footer) └── index/ # 前台控制器对应模板 ├── index.html # 首页 ├── product-list.html # 产品列表 └── product-detail.html # 产品详情
模板引擎语法
ThinkPHP 模板引擎支持以下语法:
变量输出:
{$variable}条件判断:
{if condition="$status eq 1"}...{/if}循环遍历:
{foreach $list as $item}...{/foreach}模板继承:
{extend name="layout/main" /}区块定义:
{block name="content"}...{/block}原始输出:
{$content|raw}(不转义 HTML)
自定义标签
PuranCMS 提供了自定义标签库 PuranTag,可在模板中直接使用:
{puran:list name="模型标识" limit="10" category_id="分类ID" order="id desc"}{$item.title}{$item.description}{/puran:list}
{puran:detail name="模型标识" id="$id"}{$item.title}{$item.content|raw}{/puran:detail}
{puran:model key="模型标识"}{$modelInfo.name}{/puran:model} 命名空间规范
PSR-4 自动加载规范
项目遵循 PSR-4 自动加载规范,命名空间与目录结构严格对应:
命名空间映射
| 命名空间 | 对应目录 | 说明 |
|---|---|---|
| app\ | app/ | 应用根命名空间 |
| app\admin\controller\ | app/admin/controller/ | 后台控制器 |
| app\admin\model\ | app/admin/model/ | 后台模型(如有) |
| app\index\controller\ | app/index/controller/ | 前台控制器 |
| app\model\ | app/model/ | 数据模型 |
| app\service\ | app/service/ | 服务层 |
| app\middleware\ | app/middleware/ | 中间件 |
| app\common\ | app/common/ | 公共模块 |
命名空间声明示例
注意事项
所有 PHP 文件必须声明
开头命名空间声明必须在文件顶部(
之后第一行)使用
use语句引入外部类,避免使用完整命名空间类名必须与文件名一致(大小写敏感)
文件命名规范
PHP 文件命名
控制器:大驼峰命名(PascalCase),如
Content.php、System.php模型:大驼峰命名,如
Article.php、Product.php服务:大驼峰命名 + Service 后缀,如
ContentService.php中间件:大驼峰命名,如
AdminCheck.php
视图文件命名
使用小写字母 + 下划线,如
index.html、form.html布局文件放在
layout/目录下,如main.html
静态资源命名
CSS 文件:小写字母 + 连字符,如
content.css、dashboard.cssJavaScript 文件:小写字母 + 连字符,如
content.js、admin.js
数据库命名
表名:小写字母 + 下划线,前缀
pr_,如pr_article字段名:小写字母 + 下划线,如
create_time、status
代码开发规范
PHP 编码规范
遵循 PSR-12 编码规范
使用 4 个空格缩进
类名使用大驼峰命名(PascalCase)
方法名使用小驼峰命名(camelCase)
属性名使用小驼峰命名
常量使用全大写字母 + 下划线
控制器规范
控制器只负责接收请求、调用服务、返回响应
业务逻辑必须放在 Service 层
使用
$this->success()和$this->error()返回统一格式
模型规范
所有模型继承
BaseModel开启自动时间戳:
protected $autoWriteTimestamp = true;定义表名:
protected $name = 'table_name';定义关联关系方法
JavaScript 规范
使用 IIFE 模式封装,避免全局污染
变量使用
var声明使用
layui.use()加载模块AJAX 请求统一使用 JSON 格式
数据库配置说明
数据库连接配置
数据库配置在 config/database.php 或 .env 文件中:
[DATABASE] TYPE = mysql HOSTNAME = 127.0.0.1 DATABASE = purancms USERNAME = root PASSWORD = your_password HOSTPORT = 3306 CHARSET = utf8mb4 PREFIX = pr_
数据库表前缀
所有数据表使用 pr_ 前缀,方便多系统部署:
pr_admin- 管理员表pr_admin_menu- 菜单表pr_article- 文章表pr_product- 产品表pr_nav- 导航表pr_message- 留言表pr_advertisement- 广告表pr_system_config- 系统配置表
字符集
使用 utf8mb4 字符集,支持 Emoji 和特殊字符。
二次开发指南
开发环境搭建
安装 PHP 8.0+ 和 Composer
克隆项目并安装依赖:
composer install配置
.env文件导入数据库:
mysql -u root -p db_name < database/install.sql启动开发服务器:
php think run
添加新模块
在
app/admin/controller/创建控制器在
app/model/创建模型在
app/admin/view/创建视图在
route/app.php添加路由在后台菜单管理中添加菜单项
添加新模型
创建数据库表
在
app/model/创建模型类,继承BaseModel在后台"模型管理"中注册模型
在导航管理中绑定模型
交互逻辑脑图
用户请求 │ ├─ 前台请求 │ ├─ Index 控制器 │ │ ├─ 获取导航 │ │ ├─ 获取内容列表 │ │ └─ 渲染模板 │ └─ Upload 控制器 │ └─ 处理文件上传 │ └─ 后台请求 ├─ AdminCheck 中间件 │ └─ 验证登录状态 ├─ 控制器 │ ├─ 接收参数 │ ├─ 调用 Service │ └─ 返回 JSON/视图 └─ Service ├─ 业务逻辑处理 ├─ 调用 Model └─ 返回结果
v1.0.0 安全中心模块与项目基础架构
发布信息
| 发布日期 | 2026-05-01 |
|---|---|
| 更新类型 | 重大更新 |
一、项目立项背景
1.1 项目定位
PuranCMS 是一款基于 ThinkPHP 8.0+ 框架开发的企业级内容管理系统(CMS),旨在为企业提供一个功能完善、易于扩展、安全可靠的内容管理解决方案。
核心目标:
| 目标维度 | 具体描述 |
|---|---|
| 企业官网 | 支持企业官网、产品展示、新闻发布、门店展示等常见场景 |
| 内容管理 | 完善的内容管理体系:产品/新闻/单页/门店/招聘/案例/下载/留言等 |
| 安全可靠 | 内置多层安全防护机制,有效防御 SQL 注入、XSS、CSRF 等常见攻击 |
| 易于扩展 | 插件化架构,支持功能模块的独立开发与热插拔 |
| SEO 友好 | 支持静态化生成、伪静态 URL、Sitemap 自动生成等 SEO 优化 |
| 会员体系 | 完整的会员注册/登录/等级/积分/权益体系 |
1.2 技术栈选型
| 层级 | 技术 | 版本 | 说明 |
|---|---|---|---|
| 后端框架 | ThinkPHP | 8.1.4 | PHP MVC 框架 |
| PHP 版本 | PHP | >= 8.0 | 服务端脚本语言 |
| 数据库 | MySQL | >= 5.7 | 关系型数据库 |
| 后台前端 | Layui | 2.13.5 | 后台 UI 框架 |
| 数据可视化 | ECharts | 5.x | 图表库(仪表盘/地图) |
| 模板引擎 | ThinkPHP 原生 | - | 标签定界符 {} |
| IP 解析 | zoujingli/ip2region | ^3.0 | IP 地理位置解析 |
| 邮件发送 | PHPMailer | ^7.0 | 邮件发送库 |
| 包管理 | Composer | 2.x | PHP 包管理器 |
1.3 系统架构设计
┌─────────────────────────────────────────────────────┐ │ 表现层 (Presentation) │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ 后台管理视图 │ │ 前台展示模板 │ │ │ │ (Layui + TP模板) │ │ (default/enterprise) │ │ └──────────────────┘ └──────────────────┘ │ ├─────────────────────────────────────────────────────┤ │ 控制层 (Controller) │ │ admin/ | index/ | api/ | common/ │ ├─────────────────────────────────────────────────────┤ │ 中间件层 (Middleware) │ │ AdminCheck │ AuthCheck │ SecurityGuard │ ├─────────────────────────────────────────────────────┤ │ 业务层 (Service) │ │ ContentService │ SecurityService │ MemberService ... │ ├─────────────────────────────────────────────────────┤ │ 模型层 (Model) │ │ Product │ News │ Page │ User │ Admin │ Model ... │ ├─────────────────────────────────────────────────────┤ │ 数据存储层 (Database) │ │ MySQL 5.7+ (utf8mb4) │ └─────────────────────────────────────────────────────┘
1.4 项目目录结构
web.puran.cc/ ├── app/ │ ├── admin/controller/ # 后台控制器 │ ├── index/controller/ # 前台控制器 │ ├── api/controller/ # API 控制器 │ ├── model/ # 数据模型 │ ├── service/ # 业务服务层 │ ├── middleware/ # 中间件 │ ├── taglib/ # 自定义标签库 │ └── common/ # 公共模块 ├── template/ │ └── default/ # 默认前台主题 │ ├── index/ # 首页/列表页 │ ├── user/ # 会员中心 │ └── common/ # 公共组件(header/footer) ├── public/static/ # 静态资源 ├── config/ # 配置文件 ├── database/ # 数据库脚本 ├── route/ # 路由配置 └── extend/ # 扩展类库
二、基础开发历程(v0.1.0 ~ v0.9.0)
2.1 v0.1.0 — 项目初始化(2026-04-01)
引入 ThinkPHP 8.1.4 框架,完成 Composer 依赖配置
配置单应用模式(
auto_multi_app = false)建立项目基础目录结构
初始化路由分组配置
创建入口文件
public/index.php
2.2 v0.5.0 — 项目骨架搭建(2026-04-10)
后台基类控制器
AdminBase.php—— 权限校验、通用方法封装前台基类控制器
Index.php—— 前台公共逻辑路由配置
app/route.php—— 前后台路由分组基础模型层骨架(Admin、SystemConfig、Nav 等)
基础服务层骨架(AdminService、ContentService、AddonService)
Layui 2.13.5 前端框架集成
后台布局模板
layout/main.html登录页面
login/index.html数据库安装脚本
database/install.sql初版
2.3 v0.7.0 — RBAC 权限认证系统(2026-04-15)
权限三表模型:
| 表名 | 说明 |
|---|---|
| pr_auth_rule | 权限规则表(路由规则 + 菜单规则) |
| pr_auth_group | 用户组/角色表 |
| pr_auth_group_access | 用户与角色关联表 |
安装向导(4 步骤):
| 步骤 | 页面 | 功能 |
|---|---|---|
| Step 1 | 许可协议 | 显示许可协议,用户同意后继续 |
| Step 2 | 环境检测 | PHP 版本、扩展、目录权限检查 |
| Step 3 | 数据库配置 | 数据库连接测试 + 管理员创建 |
| Step 4 | 安装完成 | 写入安装锁,跳转后台 |
2.4 v0.8.0 — 内容管理核心(2026-04-20)
8 大内容类型:
| 模型 | 控制器 | 说明 |
|---|---|---|
| 产品管理 | Content.php (product) | 产品分类 + 产品列表/详情 |
| 新闻管理 | Content.php (news) | 新闻分类 + 新闻列表/详情 |
| 单页管理 | Content.php (page) | 关于我们、联系我们等 |
| 门店管理 | BranchManage.php | 门店列表/详情 |
| 招聘管理 | Content.php (recruitment) | 职位列表/详情 |
| 案例展示 | Content.php (showcase) | 案例列表/详情 |
| 下载中心 | Content.php (download) | 文件下载管理 |
| 留言管理 | Message.php | 留言板功能 |
前台控制器:
Index.php—— 首页渲染Doc.php—— 文档详情Dynamic.php—— 动态内容页BranchPage.php—— 门店页面Member.php—— 会员中心
2.5 v0.9.0 — 站点配置与仪表盘增强(2026-04-25)
站点配置:后台 Logo / 前台 Logo(固定+滑动)/ 公安备案号 / 联系信息
仪表盘增强:ECharts 中国地图访客分布 / 访问流量统计图表 / 流量来源分析
新增服务:
DashboardService.php新增数据表:
pr_visitor_log/pr_operation_log
三、v1.0.0 核心新增:安全中心模块
3.1 安全评分仪表盘
ECharts 仪表盘组件展示 0-100 分的安全评分,基于 8 项检测加权计算。
3.2 8 项安全检测
| 检测项 | 说明 | 权重 |
|---|---|---|
| ThinkPHP 版本 | 框架是否为最新版本 | 10% |
| PHP 版本 | 是否 >= 8.0 | 15% |
| 调试模式 | 是否已关闭调试模式 | 15% |
| 默认密码 | 是否存在默认密码账号 | 20% |
| 数据库安全 | 数据库配置安全性 | 10% |
| 上传类型 | 允许上传的文件类型限制 | 10% |
| Session 安全 | Session 配置安全性 | 10% |
| 目录权限 | 关键目录权限检查 | 10% |
3.3 风险等级划分
| 评分范围 | 风险等级 | 颜色 |
|---|---|---|
| 90-100 | 安全 | 绿色 |
| 70-89 | 低风险 | 蓝色 |
| 50-69 | 中风险 | 橙色 |
| 0-49 | 高风险 | 红色 |
3.4 安全策略配置(5 大类)
| 类别 | 配置项示例 |
|---|---|
| 登录安全 | 失败锁定开关 / 最大失败次数(5) / 锁定时间(30分钟) |
| 验证码 | 图形 / 滑块 / 点选 |
| 接口安全 | CSRF防护 / XSS过滤 / SQL注入防护 / 请求限流(100次/分) |
| 后台安全 | 路径伪装 / HTTPS强制 |
| 数据安全 | 自动备份 / 备份周期(日/周/月) |
3.5 IP 黑名单管理
支持精确 IP / CIDR 格式封禁,含封禁原因 + 过期时间(永久可选)
3.6 安全防御中间件 SecurityGuard(7 层防护链)
请求 → IP黑名单拦截 → HTTPS强制 → 请求限流 → CSRF验证 → SQL注入检测 → XSS检测 → 安全响应头 → 控制器
3.7 新增数据表(3 张)
pr_security_config — 安全配置表
pr_ip_blacklist — IP 黑名单表
pr_login_log — 登录日志表(用户名/IP/归属地/状态/时间)
3.8 新增文件清单
后端文件:
app/admin/controller/Security.php— 安全中心控制器app/model/SecurityConfig.php— 安全配置模型app/model/IpBlacklist.php— IP 黑名单模型app/model/LoginLog.php— 登录日志模型app/service/SecurityService.php— 安全服务层app/middleware/SecurityGuard.php— 安全防御中间件
扩展类库:
extend/security/IpTool.php— IP 工具类extend/security/SqlInjectFilter.php— SQL 注入过滤器extend/security/XssClean.php— XSS 过滤器extend/security/PathValidator.php— 目录权限验证器extend/security/PasswordChecker.php— 密码强度检查器
前端文件:
app/admin/view/security/index.html— 安全中心主页面app/admin/view/security/policy.html— 安全策略配置弹窗app/admin/view/security/ip_blacklist.html— IP 黑名单弹窗app/admin/view/security/permission.html— 目录权限检查弹窗app/admin/view/security/login_log.html— 登录日志弹窗public/static/admin/css/security.css— 样式public/static/admin/js/security.js— 前端逻辑
v1.1.0 图片管理增强与 IP 地理位置集成
发布信息
| 发布日期 | 2026-05-02 |
|---|---|
| 更新类型 | 新增 / 优化 |
一、图片管理增强
上传弹窗:120×120 占位框 → 多图选择 → 80×80 缩略图网格预览 → 串行上传
图片列表:时间 Y-m-d H:i:s 格式化 / B/KB/MB/GB 大小格式化 / 复制链接按钮
分类操作:悬停显示编辑/删除图标按钮、"全部图片"节点
二、IP 地理位置(ip2region v3.0 集成)
// 全局函数
$location = ip2region('61.142.118.231');
// 输出:中国广东省中山市【电信】
// 类方式(返回数组:country/province/city/isp/ip/version)
$ip2region = new Ip2Region();
$info = $ip2region->getIpInfo('61.142.118.231');三、Bug 修复
finfo_file / SplFileInfo 报错:move() 前先获取文件信息
前端 renderImageItem 空引用 / deleteCategory $ 未定义 / 按钮布局修复
v1.2.0 页面命名空间重构与安装向导优化
发布信息
| 发布日期 | 2026-05-05 |
|---|---|
| 更新类型 | 优化 / 重构 |
一、8 个页面重构(命名空间隔离)
| 页面 | 命名空间 |
|---|---|
| 标签管理 | #pr-page-content-tag / PR.TagAdmin |
| AI 索引管理 | #pr-page-system-aiindex / PR.AIIndexAdmin |
| 角色管理 | #pr-page-auth-role / PR.RoleAdmin |
| 权限规则 | #pr-page-auth-rule / PR.RuleAdmin |
| 渠道管理 | #pr-page-content-channel / PR.ChannelAdmin |
| 自定义链接 | #pr-page-content-link / PR.LinkAdmin |
| 表单管理 | #pr-page-content-form / PR.FormAdmin |
| 用户管理 | #pr-page-system-user / PR.UserAdmin |
规范:IIFE 包裹 + 命名空间对象 + 事件委托 + XSS 防护(escapeHtml)
二、安装向导重构
| 步骤 | 修改前 | 修改后 |
|---|---|---|
| 步骤1 | 环境检测 | 许可协议 |
| 步骤2 | 数据库配置 | 环境检测 |
| 步骤3 | 管理员创建 | 数据库与管理员(合并) |
| 步骤4 | 安装完成 | 安装进度与完成 |
修复步骤间导航 404 Bug(路由 POST→GET 修正)
v1.3.0 标签库加载修复与登录验证码校验失败修复
发布信息
| 发布日期 | 2026-05-08 |
|---|---|
| 更新类型 | Bug 修复 |
一、标签库加载问题修复
问题:PuranTag 无法正常加载,{puran:xxx} 标签无法解析
根因:PuranTag 缺少 $tagLib = 'puran' 属性
修复:添加属性 → TagLibService 注册 → ViewInitMiddleware 触发
二、登录验证码校验失败修复
2.1 滑块验证
onEnd 中 setTimeout 1秒自动重置导致 token 失效 → 移除自动重置
2.2 点选验证
clickCount≥4 时 500ms 自动刷新 → 移除自动刷新
2.3 坐标不一致
前端显示坐标 vs 后端原始坐标(310×155) → 新增 scaleClickCoords() 换算函数
v1.4.0 导航样式修复与文档完善
发布信息
| 发布日期 | 2026-05-12 |
|---|---|
| 更新类型 | 修复 / 文档 |
更新概述
本版本主要修复顶部导航样式问题,并输出完整开发历程文档。
一、顶部导航样式修复
| 修复项 | 修改前 | 修改后 |
|---|---|---|
| 文字加粗 | font-weight: 500/600/700 | normal |
| 文字颜色 | #333 | #000 |
| 文字阴影 | text-shadow 存在 | 移除 |
涉及文件:style.css / simple_header.css / page_detail.css
二、完整开发历程文档
docs/PuranCMS_完整开发历程文档.md — 含项目立项/技术栈/架构设计/数据库设计/开发阶段记录/功能模块/前后台模板/更新迭代日志/未来规划
v1.5.0 ~ v1.5.1 会员等级功能增强与协议修复
一、v1.5.0 会员等级功能增强
发布信息
| 发布日期 | 2026-05-12 |
|---|---|
| 更新类型 | 功能新增 / 增强 |
1.1 新增功能概览
会员积分系统 — user 表新增 points、total_amount 字段
等级升级条件 — min_points / max_points / min_amount 双重条件判断
会员权益管理 — benefits 字段(JSON 数组),后台动态添加/删除权益项
等级图标与颜色 — icon(layui 图标类名)+ color(如 #FFD700)
自动升级机制 — UserLevelService:checkAndUpgrade / calculateLevel / addPoints / addAmount
1.2 数据库变更
pr_user_level 表新增字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| min_points | int(11) | 最低积分门槛 |
| max_points | int(11) | 最高积分限制(0=不限) |
| min_amount | decimal(10,2) | 最低消费金额门槛 |
| icon | varchar(255) | 等级图标(layui-icon-diamond 等) |
| color | varchar(20) | 等级颜色 |
| benefits | text | 会员权益(JSON数组) |
pr_user 表新增字段:points(积分)、total_amount(累计消费金额)
二、v1.5.1 前台用户协议验证修复
发布信息
| 发布日期 | 2026-05-13 |
|---|---|
| 更新类型 | Bug 修复 |
2.1 问题
前台登录/注册/找回密码页面,未勾选同意协议可绕过验证成功提交。根因:user.js 的 submit handler 与页面内联 handler 冲突,user.js 先执行且无协议检查。
2.2 修复方案
在 user.js 统一添加协议勾选验证(login/register/forgot 三个表单)
移除各 HTML 页面中的重复 submit handler
将"记住我"自动填充逻辑迁移至 user.js
2.3 修改文件
public/static/index/js/user.js— 统一协议验证 + 找回密码 handler + 记住我逻辑template/default/user/login.html— 移除重复 handlertemplate/default/user/register.html— 移除重复 handlertemplate/default/user/forgot_password.html— 移除重复 handler
v1.6.0 会员体系完善与管理增强
发布信息
| 发布日期 | 2026-05-14 ~ 2026-05-18 |
|---|---|
| 更新类型 | 功能新增 |
更新概述
在 v1.5.0/v1.5.1 会员等级基础上,进一步完善会员系统的配套功能:会员设置面板、积分规则配置、标签管理、UEditor 集成、前台会员中心全套页面(16 个页面)。
一、会员设置管理面板
1.1 配置项(group: member)
| 配置项 | 默认值 | 说明 |
|---|---|---|
| member_enable | 1 | 全局启用/关闭会员功能 |
| member_register_enable | 1 | 是否允许新用户注册 |
| member_login_enable | 1 | 是否允许登录 |
| member_close_reason | 会员功能暂未开放 | 关闭时提示文案 |
| auth_page_bg | (空) | 登录/注册背景图 URL |
配套服务:MemberService::getConfig() / isEnabled() / isRegisterEnabled()(带缓存 TTL=3600s)
二、积分规则配置
2.1 规则项(group: points_rule)
| 配置项 | 默认值 | 说明 |
|---|---|---|
| points_register_points | 100 | 注册奖励积分 |
| points_login_points | 5 | 每日首次登录奖励 |
| points_message_points | 10 | 发表留言奖励 |
| points_profile_points | 50 | 完善资料奖励 |
| points_sign_points | 10 | 每日签到奖励 |
| points_invite_points | 200 | 邀请好友奖励 |
| points_consume_rate | 1 | 积分消耗比率 |
配套服务:PointsService::addPoints($userId, $points, $type, $desc)(带日志+缓存)
三、其他新增模块
3.1 标签管理系统
控制器:
TagManage.php| 服务:TagService.php| 模型:Tag.php+TagRelation.php支持 CRUD + 多对多关联 + 删除保护(有内容不可删)+ SEO 字段
3.2 UEditor 富文本编辑器集成
控制器:
Ueditor.php| 支持 7 种 action(config/uploadimage/uploadvideo/uploadfile/listimage/catchimage 等)安全特性:文件类型白名单、大小限制、远程抓取域名白名单、XSS 过滤
3.3 自定义链接管理
控制器:
CustomLinkManage.php| 模型:CustomLink.php三种类型:导航链接 / 友情链接 / 底部链接
四、前台会员中心(16 个页面)
| 页面 | 路径 | 功能 |
|---|---|---|
| login | user/login.html | 会员登录 |
| register | user/register.html | 会员注册 |
| center | user/center.html | 会员中心首页 |
| profile | user/profile.html | 个人资料编辑 |
| password | user/password.html | 修改密码 |
| level | user/level.html | 会员等级展示 |
| points_rule | user/points_rule.html | 积分规则说明 |
| messages | user/messages.html | 站内消息 |
| notifications | user/notifications.html | 系统通知列表 |
| appointment_list | user/appointment_list.html | 预约记录 |
| appointment_detail | user/appointment_detail.html | 预约详情 |
| pay_order | user/pay_order.html | 支付订单 |
| appointment_booking | user/appointment_booking.html | 在线预约下单 |
| forgot_password | user/forgot_password.html | 找回密码 |
| member_closed | user/member_closed.html | 关闭提示 |
| error | user/error.html | 通用错误 |
五、新增数据表(3 张)
pr_custom_link — 自定义链接表(title/url/type/target/icon/status)
pr_tag — 标签表(name/slug/description/cover/SEO字段/article_count/product_count)
pr_tag_relation — 标签关联表(tag_id + target_type + target_id 唯一索引)
v1.7.0 文档管理与动态表单系统
发布信息
| 发布日期 | 2026-05-19 ~ 2026-05-22 |
|---|---|
| 更新类型 | 功能新增 |
更新概述
新增两大核心模块:文档管理系统(树形分类 + 富文本内容)和动态表单系统(12 种字段类型 + JSON 数据收集)。
一、文档管理系统
1.1 模块组成
| 组件 | 文件路径 |
|---|---|
| 分类控制器 | app/admin/controller/DocCategory.php |
| 内容控制器 | app/admin/controller/DocContent.php |
| 服务类 | app/service/DocManageService.php |
| 分类模型 | app/model/DocCategory.php |
| 内容模型 | app/model/DocContent.php |
| 前台模板 | template/default/index/page_detail_doc.html |
1.2 文档分类(DocCategory)字段
| 字段 | 类型 | 说明 |
|---|---|---|
| id / parent_id | int | 主键/父级(0=顶级) |
| name / slug | varchar | 名称/URL别名 |
| description | text | 分类描述 |
| icon / sort / status | - | 图标/排序/状态 |
1.3 文档内容(DocContent)字段
| 字段 | 类型 | 说明 |
|---|---|---|
| category_id | int | 所属分类 |
| title / slug | varchar | 标题/URL别名(唯一) |
| content | longtext | HTML富文本 |
| summary / cover | - | 摘要/封面图 |
| seo_title / seo_keywords / seo_description | varchar/text | SEO 信息 |
二、动态表单系统
2.1 模块组成
| 组件 | 文件路径 |
|---|---|
| 表单控制器 | app/admin/controller/FormManage.php |
| 字段控制器 | app/admin/controller/FormField.php |
| 数据控制器 | app/admin/controller/FormData.php |
| Form / FormField / FormData 模型 | app/model/ 下三个模型 |
2.2 支持的字段类型(12 种)
| type | 说明 |
|---|---|
| text / textarea | 单行/多行文本 |
| number / email / phone | 数字/邮箱/手机号 |
| select / radio / checkbox | 下拉/单选/多选 |
| file / date / datetime | 文件上传/日期/日期时间 |
| image / rich_text | 图片上传/富文本 |
2.3 表单数据存储
所有提交数据以 JSON 格式存储在 FormData.data 字段中,便于灵活扩展。
三、新增数据表(5 张)
pr_doc_category — 文档分类表(树形结构)
pr_doc_content — 文档内容表(富文本)
pr_form — 自定义表单表
pr_form_field — 表单字段定义表
pr_form_data — 表单提交数据表(JSON)
v1.8.0 自定义内容模型、插件系统与主题管理
发布信息
| 发布日期 | 2026-05-20 |
|---|---|
| 更新类型 | 重大功能 |
一、自定义内容模型系统
1.1 功能概述
允许管理员在后台动态创建新的内容类型(如"课程"、"案例"、"FAQ"等),无需修改代码即可扩展平台的内容承载能力。每个模型自动生成对应的数据表。
1.2 核心能力
14 种字段类型:文本/多行文本/富文本/数字/日期时间/单选/多选/下拉框/图片上传/文件上传/开关/评分/关联模型/JSON
保留关键字保护:内置 17 个保留 key 防止与系统表冲突
自动建表:创建模型时根据字段定义自动生成数据库表结构
前台渲染支持:通过
{custom:content}标签在前台展示
二、插件系统(Addon System)
2.1 设计理念
插件系统采用"热插拔"架构设计,开发者可通过标准化的目录结构和接口规范开发独立的功能模块,实现功能的模块化封装与灵活组合。
2.2 插件目录结构
addons/ ├── anticode/ # 示例:防伪码查询插件 │ ├── config.php # 插件配置文件(元数据+钩子+标签) │ ├── Plugin.php # 插件主类(继承 BasePlugin) │ ├── Install.php # 安装脚本 │ ├── Uninstall.php # 卸载脚本 │ ├── route.php # 插件路由规则 │ ├── controller/ # 控制器层 │ │ ├── Admin.php # 后台控制器 │ │ └── Index.php # 前台控制器 │ ├── model/ # 数据模型 │ │ └── Anticode.php │ ├── service/ # 业务服务 │ │ └── Service.php │ ├── view/ # 视图模板 │ │ ├── admin/ # 后台视图 │ │ │ ├── index.html # 列表页 │ │ │ ├── edit.html # 编辑页 │ │ │ ├── settings.html # 设置页 │ │ │ └── nav.html # 导航配置 │ │ ├── index/ # 前台视图 │ │ │ ├── index.html # 列表页 │ │ │ ├── detail.html # 详情页 │ │ │ └── widget.html # 组件模板(可嵌入任意页面) │ │ └── assets/ # 静态资源 │ │ ├── css/admin.css │ │ └── js/admin.js │ ├── logs/ # 运行日志目录 │ └── README.md # 说明文档 ├── appointment/ # 示例:在线预约插件 ├── multilang/ # 示例:多语言切换插件 ├── timeline/ # 示例:时间线展示插件 └── .gitignore
2.3 BasePlugin 抽象基类
所有插件必须继承 app\common\BasePlugin,提供以下核心能力:
| 属性/方法 | 类型 | 说明 |
|---|---|---|
| $name | string | 插件唯一标识(小写字母开头) |
| $title | string | 插件显示名称 |
| $version | string | 版本号(语义化) |
| $description | string | 插件描述 |
| $author | string | 作者 |
| $hooks | array | 注册的钩子列表 |
| $tags | array | 注册的标签列表 |
| install() | abstract | 安装逻辑(必须实现) |
| uninstall() | abstract | 卸载逻辑(必须实现) |
| renderWidget() | public | 组件渲染方法 |
| tagList() / tagDetail() | public | 标签解析方法 |
| createTable() / dropTable() | protected | 建表/删表工具方法 |
| log() | protected | 日志记录(写入 addons/{name}/logs/) |
| loadConfig() / saveConfig() | public | 配置读写(config.php 文件) |
| registerHooks() | public | 向 HookService 注册钩子 |
2.4 config.php 配置文件结构
'my_addon', 'title' => '我的插件', 'description' => '插件功能说明', 'version' => '1.0.0', 'author' => 'AuthorName', 'icon' => 'layui-icon-app', 'status' => 0, // 0=未安装, 1=已安装启用, -1=已停用 // ===== 钩子系统 ===== 'hooks' => [ 'my_addon_widget' => [ 'method' => 'renderWidget', // Plugin 类中的方法名 'description' => '组件(可嵌入任意页面)', ], ], // ===== 标签系统 ===== 'tags' => [ 'list' => ['description' => '列表标签', 'params' => ['limit'=>'显示数量']], 'detail' => ['description' => '详情标签', 'params' => ['id'=>'内容ID']], ], // ===== 业务配置项 ===== 'config' => [ 'pagesize' => 10, 'show_status' => 1, 'nav_menu_show' => ['type'=>'switch', 'title'=>'前台导航显示', 'value'=>1], ], // ===== 导航菜单集成 ===== 'nav_menu' => [ 'enable' => true, 'position' => 'top', 'menus' => [['title'=>'我的插件', 'url'=>'/addons/my_addon/index', ...]], ], ];
2.5 插件生命周期管理
5 大操作流程:
| 操作 | 触发条件 | 执行步骤 |
|---|---|---|
| 创建 | 后台"新建插件"表单提交 | 名称校验 → AddonTemplate::generate() 自动生成完整骨架(22 个文件) |
| 安装 | 点击"安装"按钮 | 读取 config.php → 写入 pr_addon 表 → 执行 Install::install() → 注册钩子/标签 → 清除缓存 |
| 卸载 | 点击"卸载"按钮 | 执行 Uninstall::uninstall() → 删除 pr_addon 记录 → 清理插件目录 → 清除缓存 |
| 启用/停用 | 点击开关按钮 | 切换 status 字段 → 更新 config.php → 启用时重注册钩子/标签 → 清除缓存 |
| 配置 | 点击"设置"按钮 | 读取 config.php 中的 config 段 → 渲染配置表单 → 保存到 pr_addon.config 字段 + config.php |
2.6 钩子机制(HookService)
钩子系统是插件与系统交互的核心桥梁,采用观察者模式实现事件驱动:
请求到达 → 触发钩子 → HookService::trigger('hook_name')
↓
遍历所有已注册的回调函数 → 按优先级排序 → 依次执行
↓
收集所有返回值 → 返回给调用方
// 系统触发示例(在需要的位置)
HookService::trigger('frontend_header_js'); // 输出前端头部JS
HookService::trigger('frontend_footer_js'); // 输出前端底部JS
// 插件注册示例(在 Plugin.php 中)
$this->hooks = [
'frontend_header_js' => ['method' => 'injectHeaderScript'],
];HookService API:
| 方法 | 说明 |
|---|---|
HookService::register($name, $callback, $priority) | 注册钩子回调(支持优先级排序) |
HookService::trigger($name, $params) | 触发钩子,返回所有回调结果数组 |
HookService::triggerFirst($name, $params) | 触发钩子,仅返回第一个结果 |
HookService::hasHook($name) | 检查是否有注册的钩子 |
HookService::getHooks($name) | 获取指定钩子的所有回调 |
HookService::clearCache() | 清除钩子缓存 |
2.7 内置插件一览
| 插件标识 | 名称 | 功能说明 | 主要特性 |
|---|---|---|---|
| anticode | 防伪码查询 | 产品防伪码生成与验证 | 批量生成/导入导出/二维码/查询统计/操作日志 |
| appointment | 在线预约 | 服务预约与订单管理 | 分类/时段/字段自定义/用户端预约/订单管理 |
| multilang | 多语言切换 | 前台多语言支持 | 中英双语/术语映射/前端语言包加载 |
| timeline | 时间线展示 | 发展历程/大事记展示 | 树形分类/富文本详情/前台组件嵌入 |
2.8 插件路由与静态资源
路由:每个插件可定义独立的
route.php,通过/addons/{name}/{action}访问静态资源:后台提供
Addons::asset()方法安全输出 CSS/JS/图片等静态文件,含 MIME 类型检测和目录穿越防护图标上传:后台支持为每个插件上传专属图标(jpg/png/gif)
2.9 新增数据表
pr_addon — 插件主表(name/title/version/status/config/hooks/tags/install_time)
2.10 插件相关新增文件清单
核心框架:
app/common/BasePlugin.php— 插件抽象基类app/common/AddonTemplate.php— 插件代码生成器(22 个文件模板)app/service/HookService.php— 钩子服务(事件驱动引擎)app/service/AddonService.php— 插件生命周期管理服务app/model/Addon.php— 插件数据模型
后台管理:
app/admin/controller/Addons.php— 插件管理控制器(11 个方法:index/list/install/uninstall/toggle/create/config/saveConfig/manage/checkName/uploadIcon/asset)app/admin/view/addons/index.html— 插件列表页app/admin/view/addons/create.html— 创建插件向导app/admin/view/addons/config.html— 插件配置弹窗
内置插件(4 个):
addons/anticode/— 防伪码查询插件(完整 MVC + 服务层 + 日志)addons/appointment/— 在线预约插件(分类/时段/订单/字段自定义)addons/multilang/— 多语言切换插件(中英双语 + 术语映射)addons/timeline/— 时间线展示插件(树形分类 + 组件嵌入)
三、主题管理系统
3.1 功能概述
主题管理系统允许管理员在后台自由切换、预览、配置不同的前台视觉主题,支持多套主题并存,一键切换生效。
3.2 已有主题
| 主题名称 | 目录 | 特点 | 截图 |
|---|---|---|---|
| Default(默认主题) | template/default/ | 企业官网风格,功能最全,包含全部页面模板 | 4 张(首页/列表/详情/总览) |
| Enterprise(企业版) | template/enterprise/ | 精简商务风格,适合正式企业形象展示 | 无(使用默认占位图) |
3.3 theme.json 元数据格式
每个主题根目录下的 theme.json 定义主题基本信息:
{
"name": "default",
"title": "默认主题",
"version": "1.0.0",
"author": "PuranCMS",
"description": "PuranCMS 默认前台主题,适用于企业官网场景",
"screenshots": ["screenshot.png", "screenshot-home.png", "screenshot-list.png", "screenshot-detail.png"],
"config": {
"primary_color": {"type": "color", "title": "主色调", "value": "#1890ff"},
"header_style": {"type": "select", "title": "头部样式", "value": "fixed", "options": ["fixed", "static"]}
},
"required_files": []
}3.4 主题管理功能(ThemeService)
| 功能 | 方法 | 说明 |
|---|---|---|
| 获取所有主题 | getAllThemes() | 扫描 template/ 目录下所有子目录,读取 theme.json 元数据 |
| 获取当前主题 | getCurrentTheme() | 从 system_config 表读取 current_theme 配置项(缓存 1 小时) |
| 切换主题 | switchTheme($name) | 校验完整性 → 写入 system_config → 清除缓存 |
| 主题验证 | validateTheme($name) | 检查必需目录(common/index)和文件(header/footer/layout/index)是否存在 |
| 主题配置 | getThemeConfig() / saveThemeConfig() | 按 theme_{name} 分组读写配置到 system_config 表 |
| 主题预览 | preview($name) | 渲染预览页面(不实际切换) |
| 主题统计 | getThemeStats() | 返回总数/当前主题/有效主题数 |
| 静态资源路径 | getThemeStaticUrl($name) | 返回 /static/theme/{name}/ 路径 |
3.5 后台管理界面(Theme 控制器)
提供 8 个管理方法:
| 方法 | 功能 |
|---|---|
| index() | 主题列表主页 |
| getList() | AJAX 获取主题列表(含 is_current 标识) |
| getDetail() | 获取单个主题详细信息 + 配置 |
| switch() | POST 切换主题 |
| config() / saveConfig() | GET 显示 / POST 保存主题配置 |
| preview() | 主题预览 |
| validate() | 验证主题文件完整性 |
| stats() | 主题统计概览 |
3.6 Default 主题模板清单
公共组件 (common/):
header.html— 公共头部(Logo/导航/搜索/会员入口)footer.html— 公共底部(版权/备案/友情链接)simple_footer.html— 简洁底部pagination.html— 分页组件layout.html— 布局母版
首页 (index/):
index.html— 首页product_list/detail.html— 产品列表/详情article_list/detail.html— 新闻文章列表/详情page_detail.html— 单页详情branch_list/detail.html— 门店列表/详情download_list/detail.html— 下载中心列表/详情recruitment_list/detail.html— 招聘列表/详情image_list/detail.html— 图集列表/详情message.html— 留言板page_detail_contact.html— 联系我们page_detail_doc.html— 开发文档page_detail_anticode.html— 防伪查询(插件页)page_detail_appointment.html— 在线预约(插件页)
会员中心 (user/):
center/login/register/forgot_password/profile/password/level/points_rule/messages/notifications/...— 完整会员体系页面
3.7 Enterprise 主题模板清单
common/layout.html— 企业版布局母版index/index/article_list/detail/product_list/detail/page_detail/contact— 精简版页面user/auth_layout/center/login/register/layout— 企业版会员页面
3.8 主题相关新增文件清单app/service/ThemeService.php — 主题管理服务(15 个方法)
app/admin/controller/Theme.php — 主题管理控制器(8 个方法)
app/admin/view/theme/index.html — 主题列表页
app/admin/view/theme/config.html — 主题配置页
app/admin/view/theme/preview.html — 主题预览页
template/default/theme.json — 默认主题元数据
template/enterprise/theme.json — 企业版主题元数据
template/default/screenshot*.png — 默认主题截图(4 张)
app/service/ThemeService.php — 主题管理服务(15 个方法)
app/admin/controller/Theme.php — 主题管理控制器(8 个方法)
app/admin/view/theme/index.html — 主题列表页
app/admin/view/theme/config.html — 主题配置页
app/admin/view/theme/preview.html — 主题预览页
template/default/theme.json — 默认主题元数据
template/enterprise/theme.json — 企业版主题元数据
template/default/screenshot*.png — 默认主题截图(4 张)
v1.9.0 SEO 管理、缓存管理与 HTML 静态化
发布信息
| 发布日期 | 2026-05-28 ~ 2026-06-02 |
|---|---|
| 更新类型 | 功能新增 |
更新概述
本版本聚焦于 SEO 优化能力、缓存管理 和 HTML 静态化生成 三大基础设施功能。
一、SEO 管理系统
1.1 SEO 配置项(system_config, group=seo)
| 配置项 | 默认值 | 说明 |
|---|---|---|
| seo_title_separator | | - PuranCMS | 标题分隔符及后缀 |
| seo_default_title | PuranCMS 企业内容管理系统 | 默认站点标题 |
| seo_default_keywords | PuranCMS,企业CMS,内容管理 | 默认关键词 |
| seo_default_description | PuranCMS 是一款基于 ThinkPHP... | 默认描述 |
| seo_url_suffix | .html | URL 后缀 |
| seo_lowercase_url | 1 | URL 小写化 |
| seo_structured_data | {} | 结构化数据 LD-JSON |
| seo_site_type | WebSite | 站点类型 |
1.2 Sitemap 自动生成
SitemapService::generateSitemap(); // 生成 Sitemap XML SitemapService::getSitemapUrl(); // 获取访问 URL SitemapService::addUrl($url, $lastmod, $changefreq, $priority); // 添加条目
自动收录:首页、栏目页、详情页、单页、文档页面
1.3 结构化数据(LD-JSON)
{"@context": "https://schema.org", "@type": "WebSite", "name": "PuranCMS", "url": "https://example.com"}二、缓存管理中心
2.1 可管理的缓存类型
| 类型 | 清理目标 | 存储路径 |
|---|---|---|
| template | 模板编译缓存 | runtime/temp/ |
| log | 日志文件 | runtime/log/ |
| html | 静态 HTML 缓存 | public/html/ 或 runtime/html/ |
| cache | 系统 Cache | (TP Cache 驱动) |
| all | 全部一键清理 | |
2.2 API 接口
POST /admin/cache_manage/clear?type=template|log|html|cache|all GET /admin/cache_manage/index → 各类型磁盘占用大小
三、HTML 静态化缓存
3.1 支持的生成类型
| type | 说明 |
|---|---|
| home | 生成首页 |
| nav | 生成栏目页(nav_id) |
| content | 生成内容详情页(content_type + content_id) |
| all | 全站生成 |
3.2 核心方法
HtmlCacheService::generateHome(); HtmlCacheService::generateNavPage($navId); HtmlCacheService::generateContentPage($type, $id); HtmlCacheService::generateAll(); HtmlCacheService::getStatistics(); // 统计:总文件数/总大小/各类型数量
3.3 静态文件存储规则
runtime/html/ ├── index.html # 首页 ├── article/ # 文章 ├── product/ # 产品 ├── page/ # 单页 └── doc/ # 文档
3.4 Nginx 配置建议
location ~ ^/(article|product|page)/ {
try_files /runtime/html/$uri/index.html /runtime/html/$uri.html /index.php?$query_string;
}四、新增文件清单
app/admin/controller/SeoManage.php— SEO 管理app/admin/controller/CacheManage.php— 缓存管理app/admin/controller/HtmlCache.php— 静态化管理app/service/SeoService.php— SEO 服务app/service/SitemapService.php— Sitemap 生成app/service/HtmlCacheService.php— 静态化核心服务对应视图、CSS、JS 文件
v2.0.0 平台级能力全面升级
发布信息
| 发布日期 | 2026-06-06 |
|---|---|
| 更新类型 | 重大版本升级(Major Release) |
更新概述
v2.0.0 是 PuranCMS 发展历程中最重要的里程碑版本。本版本标志着系统从"内容管理系统(CMS)"正式跨越为"综合性应用平台",引入了 RESTful API 接口体系、通知消息系统、图片管理完善化,并整合了此前 v1.6.0 ~ v1.9.0 的全部平台能力。
版本号语义 — 从 v1.x 跳升至 v2.0.0 的理由:
API 体系的引入 — 新增完整的 RESTful API 模块,支持外部系统集成
通知系统的建立 — 站内消息/系统通知的统一管理能力
架构层面的扩展 — 新增 api 独立模块、中间件体系扩展
功能数量翻倍 — 从约 15 个功能模块增长到 30+ 个功能模块
一、RESTful API 接口体系(核心新增)
1.1 目录结构
app/api/ ├── controller/ │ ├── BaseController.php # API 基础控制器 │ ├── v1/ # v1 版本接口 │ │ ├── Content.php # 内容接口 v1 │ │ └── User.php # 用户接口 v1 │ ├── v2/ # v2 版本接口 │ │ ├── Content.php # 内容接口 v2 │ │ └── User.php # 用户接口 v2 │ ├── BranchController.php # 门店 API │ ├── ContentController.php # 内容 API(通用) │ └── MemberController.php # 会员 API ├── middleware/ │ ├── ApiAuth.php # API 身份认证中间件 │ └── ApiRateLimit.php # API 频率限制中间件 └── route/ └── app.php # API 路由配置
1.2 基础控制器(BaseController)
| 能力 | 说明 |
|---|---|
| Token 认证 | 基于 Cache 的 Token 机制 |
| Token 有效期 | 默认 7 天(604800 秒) |
| Token 生成算法 | MD5(uniqid() . $userId . time()) |
| 统一响应格式 | { code: 0/1, msg: '', data: {} } |
1.3 API 中间件
ApiAuth — 身份认证中间件:从 Header "Authorization" 或参数 "token" 获取 Token → Cache 验证 → 注入 userId / 返回 401
ApiRateLimit — 频率限制中间件:以 IP 为 key 计数 → 默认 60次/60秒/IP → 超限返回 429
1.4 版本策略
| 版本 | 路径前缀 | 特点 |
|---|---|---|
| v1 | /api/v1/ | 基础版,核心字段 |
| v2 | /api/v2/ | 扩展版,含更多字段和关联数据 |
1.5 已实现接口清单
内容接口:GET list/detail/search(v1 + v2)
用户接口:POST register/login, GET info/points, PUT profile(v1 + v2)
门店接口:GET list/detail/nearby
会员接口:GET level/points/log/notification/list, PUT notification/read
1.6 认证流程
注册:POST /api/v2/user/register { nickname, email, password }
登录:POST /api/v2/user/login { email, password } → 返回 token + user
认证:GET /api/v2/user/info Header: Authorization: Bearer xxx二、通知消息系统
2.1 通知类型
| 类型常量 | 说明 |
|---|---|
| system | 系统通知 |
| order | 订单通知 |
| activity | 活动通知 |
| message | 留言回复 |
2.2 核心方法
NotificationService::send($userId, $type, $title, $content, $extra); // 单人发送 NotificationService::sendBatch($userIds, $type, $title, $content); // 批量发送 NotificationService::broadcast($type, $title, $content); // 全员广播 NotificationService::markAsRead($notificationId, $userId); // 标记已读 NotificationService::markAllRead($userId); // 全部已读 NotificationService::getUserNotifications($userId, $page, $limit, $type); // 列表 NotificationService::getUnreadCount($userId); // 未读数
2.3 数据表结构(pr_notification)
| 字段 | 类型 | 说明 |
|---|---|---|
| user_id | int | 接收用户ID(0=全员广播) |
| type | varchar(20) | 通知类型 |
| title | varchar(200) | 标题 |
| content | text | 内容 |
| is_read | tinyint | 已读状态 |
| related_id / related_type | int / varchar | 关联业务 |
| extra_data | text | 扩展数据JSON |
三、图片管理完善化
3.1 新增服务类
| 服务类 | 说明 |
|---|---|
| ThumbnailService | 缩略图自动生成(thumb_s/m/l 三尺寸) |
| WatermarkService | 文字/图片水印处理 |
| FileStorageService | 文件上传/删除/URL获取/云存储迁移 |
| ImageCategory | 图片按分类组织管理 |
四、新增文件清单
API 模块(12 文件)
app/api/controller/BaseController.php— API 基础控制器app/api/controller/v1/Content.php,User.php— v1 接口app/api/controller/v2/Content.php,User.php— v2 接口app/api/controller/BranchController.php— 门店 APIapp/api/controller/ContentController.php— 通用内容 APIapp/api/controller/MemberController.php— 会员 APIapp/api/middleware/ApiAuth.php— 认证中间件app/api/middleware/ApiRateLimit.php— 限流中间件app/api/route/app.php— API 路由
通知系统(3 文件)
app/admin/controller/Notification.php— 后台管理app/service/NotificationService.php— 发送服务app/model/Notification.php— 数据模型
图片增强(3+ 文件)
app/service/ThumbnailService.php,WatermarkService.php,FileStorageService.phpapp/admin/controller/ImageCategory.php
服务层补充(5 文件)
AddonLoader.php,HookService.php,ContentManageService.php,MessageService.php,Ip2RegionAdapter.php
五、完整功能矩阵(v2.0.0)
| 领域 | 模块数 | 核心功能 |
|---|---|---|
| 内容管理 | 8 | 产品/新闻/单页/门店/招聘/案例/下载/留言 |
| 文档管理 | 2 | 文档分类树 + 文档内容 |
| 表单系统 | 3 | 自定义表单/字段/数据 |
| 自定义模型 | 3 | 模型/字段/动态内容 |
| 用户权限 | 5 | 管理员/会员/等级/RBAC/菜单 |
| 安全防护 | 8 | 8维度检测/黑名单/登录日志/多层过滤 |
| SEO 优化 | 2 | SEO配置/Sitemap生成 |
| 性能优化 | 3 | HTML静态化/缓存管理/缩略图 |
| 主题系统 | 2 | 多主题切换/资源管理 |
| API 接口 | 6 | v1/v2双版本/认证/限流/内容/用户/门店/会员 |
| 通知消息 | 1 | 站内通知(4种类型) |
| 图片管理 | 4 | 上传/分类/缩略图/水印 |
总计:30+ 功能模块,60+ 控制器/服务/模型文件
v2.1.0 安全中心全面升级
更新概述
v2.1.0 聚焦安全中心的全面升级与体验优化。本次更新完善了安全告警体系、通知系统隔离、操作日志追踪,并对安全中心 UI 进行了全面优化,使安全中心成为真正实用、易用的安全管理平台。
新增功能
1. 安全告警独立模块
功能概述
将安全告警从通用通知系统中独立出来,专属安全中心管理。安全告警(XSS 拦截、SQL 注入、暴力破解等)不再混入普通通知列表,而是集中在安全中心的安全告警模块中统一管理。
模块组成
| 组件 | 文件路径 | 说明 |
|---|---|---|
| 控制器方法 | app/admin/controller/Security.php | 安全告警 CRUD 接口 |
| 视图页面 | app/admin/view/security/alerts.html | 告警列表弹窗页面 |
| JS 逻辑 | public/static/admin/js/security.js | 弹窗交互逻辑 |
| 样式 | public/static/admin/css/security.css | 弹窗样式 |
新增接口
| 方法 | 路由 | 说明 |
|---|---|---|
alerts() | GET /admin/security/alerts | 告警弹窗页面 |
getAlerts() | GET /admin/security/getAlerts | 获取告警列表(含未读数) |
markAlertRead() | POST /admin/security/markAlertRead | 标记单条已读 |
deleteAlert() | POST /admin/security/deleteAlert | 删除单条告警 |
clearAlerts() | POST /admin/security/clearAlerts | 清空所有告警 |
getUnreadAlertCount() | GET /admin/security/getUnreadAlertCount | 获取未读数量 |
顶部导航角标
在后台顶部导航新增盾牌图标,实时显示未读安全告警数量:
有未读告警时显示红色数字角标(超过 99 显示
99+)无未读告警时自动隐藏
点击跳转到安全中心页面
每次页面切换自动刷新角标数量
2. 通知系统用户类型隔离
问题背景
之前安全告警通过 notification 表发送,但 user_id 字段同时被管理员和前台用户共用,导致安全告警可能被前台用户看到。
解决方案
新增 user_type 字段区分通知接收者类型:
| 字段 | 类型 | 说明 |
|---|---|---|
| user_type | varchar(20) | user-前台用户 / admin-后台管理员 |
代码变更
| 文件 | 变更 |
|---|---|
app/model/Notification.php | 新增 TYPE_SECURITY 和 USER_TYPE_* 常量 |
app/service/SecurityService.php | sendSecurityAlert() 设置 user_type='admin' |
app/service/NotificationService.php | 前台查询添加 where('user_type', 'user') 过滤 |
app/admin/controller/Notification.php | 后台列表显示所有通知(管理员视角) |
3. 留言回复通知精准推送
留言回复通知逻辑正确,无需修改:每个用户只收到自己留言的回复通知,互不干扰。
4. 安全中心 UI 优化
安全告警弹窗
采用 iframe 弹窗模式(type:2),与 IP 白名单/黑名单页面风格一致
弹窗尺寸优化为
60% × 80%,适配不同屏幕工具栏布局:左侧按钮组 + 右侧搜索框
空状态显示表情图标 + "暂无数据"文字
模块卡片渐变色
为安全中心 7 个模块卡片补充渐变色:
| 卡片 | 渐变色 |
|---|---|
| 安全策略配置 | #667eea → #764ba2 (紫) |
| IP 黑名单 | #f093fb → #f5576c (粉) |
| IP 白名单 | #4facfe → #00f2fe (蓝) |
| 目录权限检查 | #43e97b → #38f9d7 (绿) |
| 登录日志 | #fa709a → #fee140 (粉橙) |
| 操作日志 | #a18cd1 → #fbc2eb (紫粉) |
| 安全告警 | #fccb90 → #d57eeb (橙紫) |
修复问题
安全告警通知推送给前台用户:新增
user_type字段隔离,安全告警只发送给管理员。后台通知列表为空:后台通知管理显示所有通知(管理员视角),只有前台用户中心才过滤
user_type='user'。删除通知后列表不刷新:统一为
res.code === 0判断成功。安全告警弹窗一直加载中:在
route/app.php补充 5 条安全告警路由。安全告警弹窗样式不一致:在
security.css新增#pr-page-security-alerts专属样式。安全告警弹窗 jQuery 未定义:为 5 个方法全部补充
$声明。
文件变更清单
新增文件
| 文件路径 | 说明 |
|---|---|
app/admin/view/security/alerts.html | 安全告警弹窗页面 |
database/migrations/notify_user_type.sql | 通知表 user_type 字段迁移脚本 |
修改文件
| 文件路径 | 变更说明 |
|---|---|
app/admin/controller/Security.php | 新增 6 个安全告警接口方法 |
app/admin/controller/Notification.php | 移除 user_type 过滤(管理员查看全部) |
app/service/SecurityService.php | sendSecurityAlert 设置 user_type='admin' |
app/service/NotificationService.php | 前台查询添加 user_type='user' 过滤 |
app/model/Notification.php | 新增 TYPE_SECURITY 和 USER_TYPE_* 常量 |
app/admin/view/layout/main.html | 顶部导航新增安全告警盾牌图标 |
app/admin/view/security/index.html | 新增安全告警模块卡片,移除内联弹窗 HTML |
public/static/admin/js/security.js | 新增安全告警弹窗逻辑 |
public/static/admin/js/admin.js | 新增安全告警角标刷新逻辑 |
public/static/admin/css/security.css | 新增 alerts 弹窗样式 + 卡片渐变色 |
route/app.php | 新增 6 条安全告警路由 |
database/install.sql | pr_notification 表新增 user_type 字段 |
数据库变更
ALTER TABLE `pr_notification` ADD COLUMN `user_type` varchar(20) NOT NULL DEFAULT 'user' COMMENT '用户类型:user-前台用户, admin-后台管理员' AFTER `user_id`; ALTER TABLE `pr_notification` ADD INDEX `idx_user_type` (`user_type`); -- 更新 type 字段注释 ALTER TABLE `pr_notification` MODIFY COLUMN `type` varchar(20) NOT NULL DEFAULT 'system' COMMENT '通知类型:system-系统通知, order-订单通知, activity-活动通知, message-留言回复, security-安全告警';
安全告警触发场景
| 场景 | 告警标题 | 触发条件 |
|---|---|---|
| XSS 攻击拦截 | [安全] XSS 攻击拦截 | 请求参数包含 XSS 攻击特征 |
| SQL 注入拦截 | [安全] SQL 注入拦截 | 请求参数包含 SQL 注入特征 |
| 暴力破解 | [安全] 登录暴力破解 | 同一 IP 短时间内多次登录失败 |
| 异常登录 | [安全] 异常登录尝试 | 黑名单 IP 尝试访问后台 |
| 目录遍历 | [安全] 目录遍历尝试 | 请求路径包含 ../ 等遍历特征 |
升级指南
数据库升级:执行
notify_user_type.sql迁移脚本清除缓存:后台访问 缓存管理 → 全部清理
验证安全告警:访问安全中心,点击安全告警卡片,确认弹窗正常显示
v2.2.0 商城功能全面上线
更新概述
v2.2.0 为 PuranCMS 引入完整的商城交易闭环。涵盖前台购物车、结算、支付、会员中心订单管理,以及后台订单管理、商品管理联动等核心功能。同时优化了会员中心菜单布局、多语言插件兼容性等问题。
新增功能
1. 前台商城交易流程
1.1 购物车功能
| 功能 | 说明 |
|---|---|
| 加入购物车 | 产品详情页点击加入购物车,弹窗提示 |
| 全选/单选 | 支持全选和单个商品选择,实时计算总价 |
| 数量调整 | 点击数量增减按钮,自动更新金额 |
| 删除商品 | 支持单个删除和批量删除 |
| 实时金额计算 | 选择商品或调整数量时,合计金额实时更新 |
1.2 结算与支付
| 功能 | 说明 |
|---|---|
| 收货地址选择 | 从用户地址列表中选择或新增 |
| 订单确认 | 展示商品清单、金额明细、收货信息 |
| 支付流程 | 支持在线支付,支付结果页面展示 |
1.3 产品详情页优化
加入购物车弹窗改为系统统一弹窗样式
移除页面调试信息
2. 后台订单管理
2.1 订单列表页面
| 功能 | 说明 |
|---|---|
| 状态 Tab 筛选 | 全部/待付款/待发货/已发货/已完成/已取消/已退款,点击切换筛选 |
| 关键词搜索 | 支持按订单号、收货人姓名、手机号搜索 |
| 日期范围筛选 | 按下单日期范围筛选 |
| 表格列表展示 | 订单号、商品信息、数量、金额、状态、操作列 |
| 顶部固定 | 工具栏上下滑动时固定在顶部 |
| 分页加载 | 支持分页浏览订单列表 |
2.2 订单详情页面
| 功能 | 说明 |
|---|---|
| 订单信息 | 订单号、状态、下单用户、下单时间 |
| 收货信息 | 收货人、联系电话、收货地址 |
| 商品清单 | 商品图片、名称、单价、数量、小计 |
| 金额汇总 | 商品总额、运费、应付金额 |
| 状态操作 | 发货、完成、取消、退款 |
2.3 订单操作
| 操作 | 条件 | 说明 |
|---|---|---|
| 发货 | 待发货状态 | 填写物流公司、运单号 |
| 完成 | 已发货状态 | 确认订单完成 |
| 取消 | 待付款/待发货 | 取消订单 |
| 退款 | 已完成状态 | 处理退款 |
3. 后台一级菜单
新增 订单管理 一级菜单,独立于商城管理
菜单通过 SQL 迁移脚本添加到
pr_admin_menu表
优化改进
1. 会员中心菜单重构
1.1 菜单分组
将会员中心左侧菜单分为三个独立卡片:
| 卡片 | 菜单项 |
|---|---|
| 个人信息 | 个人资料、修改密码、我的地址 |
| 商城功能 | 我的订单、购物车 |
| 预约管理 | 我的预约(原"其他"改为"预约管理") |
1.2 商城功能联动
后台关闭商城功能时,会员中心自动隐藏"商城功能"卡片(我的订单、购物车)
开启商城功能时,自动显示
2. 多语言插件导航修复
问题:打开多语言插件后,后台所有页面都会显示多语言导航菜单。
原因:多语言插件通过 admin_header_nav_left 钩子注入导航,判断逻辑基于 URL 字符串匹配,不够精确。
修复方案:改为通过控制器、动作和参数精确匹配,仅在多语言插件管理页面显示导航。
3. 订单列表样式优化
卡片改为表格:将订单列表从卡片样式改为紧凑的表格列表样式
操作列按钮化:操作列从文字链接改为彩色按钮样式(详情蓝、发货绿、完成橙、取消红、退款黄)
商品图片同步:订单列表和详情页同步显示商品缩略图,无图时显示"无图"占位
4. 金额计算修复
问题:后端返回的价格字段为字符串类型,前端直接调用 .toFixed() 报错。
修复:所有金额显示前使用 parseFloat() 进行类型转换。
5. 调试信息清理
移除购买流程相关页面的所有调试信息代码:购物车页面、结算页面、支付结果页面、产品详情页面。
修复问题
| 问题 | 修复方案 |
|---|---|
| 购物车合计金额始终为0元 | 修正 JS 读取后端返回数据结构 |
| 全选按钮提示"参数错误" | 前端数组转逗号分隔字符串,后端兼容处理 |
| 订单详情页 cancel_time 未定义 | 模板中添加 isset() 检查 |
| 多语言导航在所有后台页面显示 | 改为控制器+动作+参数精确匹配 |
| 订单列表不显示数据 | 修正 status 筛选默认值,搜索按钮读取所有筛选条件 |
| 价格 toFixed 报错 | 添加 parseFloat() 类型转换 |
| 商品图片 404 | 修正字段名 product_thumb → product_image,无图显示占位文字 |
| 加入购物车弹窗样式不统一 | 改为系统统一弹窗样式 |
命名空间隔离
后台订单管理页面采用命名空间隔离方案,避免样式和脚本全局污染:
| 页面 | CSS 命名空间 | JS 命名空间 |
|---|---|---|
| 订单列表 | #pr-page-shop-order | PR.ShopOrderAdmin |
| 订单详情 | #pr-page-shop-order-detail | PR.ShopOrderDetail |
升级指南
执行菜单迁移:
mysql -u root -p webpurancc < database/shop_order_menu_migration.sql清除缓存:后台访问 缓存管理 → 全部清理
验证功能:前台购物车→结算→支付流程;后台订单管理→列表→详情→操作
发布日期:2026-06-22
更新类型:功能增强(Minor Release)
v2.3.0 防伪码与消息通知修复
更新概述
v2.3.0 主要修复了防伪码插件首次查询时间不显示的问题,以及前台会员中心消息通知页面的多个功能缺陷。同时完善了后台通知管理,使其能够展示所有分类的通知数据。
修复问题
1. 防伪码插件 — 首次查询时间不显示
问题描述:
前台查询防伪码后,结果页面"首次查询"字段显示为
-后台防伪码列表页面"首次查询时间"列显示为原始时间戳(如
1782260520)后台防伪码查看/编辑页面"首次查询"和"最后查询"字段显示异常
根本原因:Index.php 的 doSearch() 方法中,设置 first_query_time 的条件判断有误。原代码检查 if ($info['status'] == 0) 来设置首次查询时间,但 status == 0 的记录在前面已被拦截返回错误,导致该条件永远不成立。
修复方案:
将条件改为
if (empty($info['first_query_time']))后台
Admin.php的list()、edit()、view()方法中增加时间格式化逻辑模板文件移除
|date过滤器,改为直接显示控制器已格式化的时间字符串
2. 前台消息通知 — 分类 Tab 切换不生效
问题描述:切换"系统通知"、"订单通知"、"留言回复"、"活动通知"等 Tab 时,列表内容不变,所有消息始终显示在"全部"下。
根本原因:getUserNotifications() 用 where('notify_type', $type) 直接匹配,但数据库 notify_type 存的是 order_created、order_paid 等具体值,前端传的是 order、system 等大类,无法匹配。
修复方案:改为 LIKE 模糊匹配,type=order 时匹配 order_%,type=system 时匹配 system%,以此类推。
3. 前台消息通知 — 留言回复和系统消息不显示
问题描述:前台消息通知页面看不到留言回复和系统消息,但后台这些数据是存在的。
根本原因:系统有两个通知表:
notification表 — 后台管理使用,type字段存system、message、activity等notification_log表 — 订单服务使用,notify_type字段存order_created、order_paid等
前台 getUserNotifications() 只查了 notification_log 表,完全漏掉了 notification 表的数据。
修复方案:重写 NotificationService 中的相关方法,同时查询两个表并合并结果。
4. 前台消息通知 — 删除消息报错
问题描述:点击删除按钮时报错 Call to undefined method app\service\NotificationService::deleteNotification()。
修复方案:在 NotificationService 中添加 deleteNotification() 方法。
5. 前台消息通知 — 已读红点不消失
问题描述:点击查看消息后,左侧列表的红点不会消失。
根本原因:NotificationService 缺少 markAsRead() 和 markAllAsRead() 方法。
修复方案:添加 markAsRead() 和 markAllAsRead() 方法。
6. 前台消息通知 — 未读数字不动态更新
问题描述:标记已读或删除消息后,顶部未读数字不更新。
根本原因:updateUnreadCount() 函数查找 #unreadBadge,但布局模板中实际使用的是 .menu-badge 类名,选择器错误。
修复方案:改为从服务器 /user/center/unreadCount 接口获取真实未读数,并正确更新 .menu-badge 元素。
7. 前台消息通知 — 切换 Tab 时详情面板不重置
问题描述:切换消息分类 Tab 时,右边详情面板仍然显示之前选中的消息内容。
修复方案:在 Tab 点击事件中增加重置详情面板和清除列表选中状态的代码。
8. 前台消息通知 — 删除后按钮失效
问题描述:删除第一条消息成功后,再点击删除按钮没有反应,必须刷新页面才能继续删除。
根本原因:删除成功后 $btn.prop('disabled', true) 没有在回调中恢复为 false,导致按钮永久禁用。
修复方案:将 $btn.prop('disabled', false) 移到请求回调的最前面;同时将事件绑定改为 $(document).on() 事件委托模式。
9. 后台通知管理 — 只显示部分通知
问题描述:后台通知管理列表只显示安全告警和系统通知,看不到订单通知、留言回复等其他分类。
根本原因:后台 Notification.php 控制器只查了 notification 表,没有包含 notification_log 表中的订单相关通知。
修复方案:
list()方法合并两个表的数据,按时间倒序排列后分页返回delete()方法先尝试notification表,再尝试notification_log表batchDelete()方法同时从两个表中删除匹配的记录类型筛选适配两个表的字段差异
10. 后台通知管理 — 安全告警标签样式
问题描述:安全告警类型的标签没有专属样式。
修复方案:添加 .type-badge-security 样式,浅红底 + 深红字,与其他标签风格保持一致。
文件变更清单
| 文件路径 | 变更说明 |
|---|---|
addons/anticode/controller/Index.php | 修复首次查询时间设置条件和格式化 |
addons/anticode/controller/Admin.php | list/edit/view 方法增加时间字段格式化 |
addons/anticode/view/admin/list.html | 移除 |date 过滤器 |
addons/anticode/view/admin/edit.html | 移除 |date 过滤器 |
addons/anticode/view/index/result.html | 移除 |date 过滤器 |
addons/anticode/view/index/query.html | 增加对 - 值的判断 |
app/service/NotificationService.php | 合并两个通知表;新增 deleteNotification/markAsRead/markAllAsRead/sendToUser/sendToUsers/sendBroadcast 方法 |
app/index/controller/Member.php | 修复未读数更新选择器;修复 deleteNotification 调用 |
app/admin/controller/Notification.php | 合并两个表数据;修复删除/批量删除支持两个表 |
template/default/user/notifications.html | 修复 Tab 切换、详情重置、删除按钮禁用、未读数更新 |
template/default/user/layout.html | 修复未读数徽章选择器 |
public/static/admin/css/notification.css | 添加安全告警标签样式 |
升级指南
清除缓存:后台访问 缓存管理 → 全部清理
验证防伪码:前台查询防伪码 → 查看首次查询时间是否正常显示
验证消息通知:前台切换各分类 Tab → 验证列表正确筛选;删除消息 → 验证可连续删除
验证后台通知管理:验证列表显示所有分类通知;类型筛选正常工作
注意事项
两个通知表:系统同时使用
notification和notification_log两个表存储通知数据,前者用于后台发送的系统/活动/留言通知,后者用于订单服务自动生成的订单状态通知时间格式:防伪码的首次查询时间和最后查询时间现在由控制器统一格式化为
Y-m-d H:i:s字符串,模板中不再使用|date过滤器未读数徽章:会员中心布局模板中未读数徽章使用
.menu-badge类名,JS 中已修正选择器
发布日期:2026-06-24
更新类型:Bug 修复(Patch Release)
v2.4.0 图片素材管理与控制台优化
更新概述
v2.4.0 主要新增了后台图片素材引用检测功能,可自动识别全站前后台所有位置引用的图片并显示「已引用」标签,同时支持一键清除未引用图片。此外优化了控制台流量分析、访问统计图表,修复了省市县三级联动、主题颜色统一等多个问题。
新增功能
1. 图片素材引用检测
功能描述:
后台图片素材列表自动检测每张图片是否被全站引用
被引用的图片右上角显示红色「已引用」标签
鼠标悬停标签可查看具体引用来源(如"产品缩略图、文章内容")
检测范围(全站覆盖):
| 检测类型 | 表/字段 | 说明 |
|---|---|---|
| 单字段 | product.thumb | 产品缩略图 |
| 单字段 | article.thumb | 文章缩略图 |
| 单字段 | advertisement.image | 广告图片 |
| 单字段 | branch.thumb / branch.image | 门店图片 |
| 单字段 | nav.thumb | 栏目封面 |
| 单字段 | page.banner | 单页Banner |
| 单字段 | tag.cover | 标签封面 |
| 单字段 | user.avatar | 用户头像 |
| 单字段 | user_level.icon_url | 等级图标 |
| 单字段 | user_level.card_bg_url | 等级卡片背景图 |
| 单字段 | shop_order_item.product_image | 订单商品图 |
| 单字段 | addon_anticode.product_image | 防伪码产品图 |
| 单字段 | image.thumb | 图片内容缩略图 |
| 单字段 | addon.icon | 插件图标 |
| 单字段 | admin_menu.icon | 菜单图标 |
| JSON字段 | product.images / extra_fields / spec_json | 产品图片集/扩展字段/规格 |
| JSON字段 | article.extra_fields / spec_json | 文章扩展字段/规格 |
| JSON字段 | advertisement.slides | 轮播幻灯片 |
| JSON字段 | image.images / extra_fields | 图片素材集/扩展字段 |
| JSON字段 | addon.config | 插件配置 |
| JSON字段 | page.extra_fields | 单页扩展字段 |
| JSON字段 | recruitment.extra_fields | 招聘扩展字段 |
| JSON字段 | download.extra_fields | 下载扩展字段 |
| HTML内容 | product.content | 产品详情富文本 |
| HTML内容 | article.content | 文章富文本内容 |
| HTML内容 | page.content | 单页富文本内容 |
| HTML内容 | image.content | 图片内容详情 |
| HTML内容 | recruitment.content | 招聘详情 |
| 系统配置 | system_config.value | 所有系统配置值 |
匹配策略:
支持带域名完整URL匹配(
https://web.puran.cc/storage/images/...)支持相对路径匹配(
/storage/images/...)支持无斜杠路径匹配(
storage/images/...)支持文件名basename匹配(最宽松,兼容不同路径格式)
修改文件:
| 文件路径 | 变更说明 |
|---|---|
app/service/ImageManageService.php | 新增 checkImageReferences() 方法,实现全站图片引用检测 |
app/service/ImageManageService.php | 新增 cleanUnreferencedImages() 方法,清除未引用图片 |
app/admin/controller/ImageManage.php | 新增 checkReferences() 和 cleanUnreferenced() 接口 |
app/admin/view/image_manage/index.html | 新增「已引用」标签显示和「清除未引用图片」按钮 |
public/static/admin/css/image-manage.css | 新增 .image-referenced-badge 样式(红色渐变) |
public/static/admin/js/image-manage.js | 新增 checkImageReferences() 前端调用逻辑 |
public/static/admin/js/image-manage.js | 新增 cleanUnreferencedImages() 清除未引用图片逻辑 |
route/app.php | 新增 checkReferences 和 cleanUnreferenced 路由 |
2. 清除未引用图片
功能描述:
图片素材页面新增橙色「清除未引用图片」按钮
点击后弹出确认框,确认后自动扫描所有图片
未引用的图片:删除物理文件 + 删除数据库记录
已引用的图片:自动跳过
操作完成后显示删除数量、跳过数量和失败列表
优化改进
3. 控制台流量分析 — 搜索引擎细分
优化内容:
流量来源饼图新增搜索引擎细分展示
自动识别具体搜索引擎(百度、Google、Bing、搜狗、360搜索、Yandex、Yahoo、搜搜、有道、神马等)
搜索引擎数据合并到流量分析饼图中,不再单独显示
小占比数据扇区设置最小角度(minAngle: 3),确保标签可见
修改文件:
| 文件路径 | 变更说明 |
|---|---|
app/service/DashboardService.php | 新增 detectSearchEngine() 方法;修改 getSourceAnalysis() 合并搜索引擎细分 |
app/admin/controller/Dashboard.php | 移除 getSearchEngineAnalysis 接口 |
public/static/admin/js/dashboard.js | 优化 renderSourcePie() 小占比数据显示 |
4. 访问统计图表优化
优化内容:
今日/昨日数据点过少时(≤2个),自动从折线图切换为柱状图
柱状图顶部显示具体数值标签,提高可读性
折线图保留面积填充效果,柱状图移除面积填充
修改文件:
| 文件路径 | 变更说明 |
|---|---|
public/static/admin/js/dashboard.js | renderTrafficChart() 根据数据点数量自动切换图表类型 |
5. 省市县三级联动重构
优化内容:
重构为原生select + 自定义样式,移除Layui依赖
省份下拉框显示10个选项后出现滚动条
修复省份选择后市、县联动不显示的问题
修复行政区划代码(12位)超过JavaScript安全整数范围的精度丢失问题
修复省直市区县无下级时无法保存的问题(如湖北省仙桃市)
加载中提示优化:加载完成后立即显示"请选择",不再残留"加载中"
修改文件:
| 文件路径 | 变更说明 |
|---|---|
template/default/user/shop_address.html | 重构省市县三级联动,使用原生select+自定义样式 |
6. 主题颜色统一
优化内容:
选中颜色由橙红色改为金色(#c8a97e),与主题模板一致
订单页面Tab菜单选中色改为黑色,下划线改为黑色
Tab菜单鼠标悬停色改为黑色
购物车/订单页面"去结算"按钮颜色改为金色主题
修改文件:
| 文件路径 | 变更说明 |
|---|---|
template/default/user/shop_address.html | 选中颜色改为金色 |
template/default/user/shop_cart.html | 去结算按钮改为金色 |
template/default/user/shop_orders.html | Tab菜单选中/悬停色改为黑色,按钮颜色优化 |
Bug 修复
7. 控制台数据获取失败
问题:控制台页面报错 Undefined array key "admin_name" 和 Undefined array key "type"
修复:使用 ?? 空合并运算符替代 ?:,确保数组键不存在时返回默认值
修改文件:app/service/DashboardService.php
8. 图片素材引用检测 — 路由缺失
问题:checkReferences 接口返回整个HTML页面而非JSON数据
修复:在 route/app.php 中添加 checkReferences 和 cleanUnreferenced 路由定义
修改文件:route/app.php
9. 图片素材引用检测 — Db类未导入
问题:报错 Class "app\service\Db" not found
修复:在 ImageManageService.php 顶部添加 use think\facade\Db;
修改文件:app/service/ImageManageService.php
10. 图片素材引用检测 — URL格式不匹配
问题:图片URL存储格式不一致(带域名/带斜杠/不带斜杠),导致匹配失败
修复:
同时保留原始URL(带斜杠)和去斜杠版本的映射
SQL查询合并两种URL变体
PHP匹配逻辑同时检查两种格式
增加basename文件名匹配作为兜底方案
修改文件:app/service/ImageManageService.php
技术要点
URL匹配策略
系统同时支持以下四种格式的匹配,确保无论数据库中存储哪种格式都能正确识别引用关系:
| 格式 | 示例 |
|---|---|
| 完整URL | https://web.puran.cc/storage/images/2026/05/13/xxx.jpg |
| 相对路径 | /storage/images/2026/05/13/xxx.jpg |
| 无斜杠 | storage/images/2026/05/13/xxx.jpg |
| 文件名 | xxx.jpg |
图表自适应
访问统计图表根据数据点数量自动切换图表类型:
var useBar = dates.length
升级注意事项
图片素材引用检测:首次加载图片列表时会自动调用引用检测接口,图片较多时可能有轻微延迟
清除未引用图片:操作不可恢复,建议先确认图片确实未被使用后再执行
路由配置:新增了两个路由,确保 route/app.php 已更新
数据库:无需执行SQL,所有变更通过代码实现
发布日期:2026-06-24
更新类型:功能增强(Minor Release)
v2.5.0 多语言插件优化与主题管理修复
更新概述
v2.5.0 重点优化了多语言插件的专业术语翻译机制,参考 translate.zvo.cn 官方文档修复了术语表无法送达前台、缓存失效等核心问题。同时修复了主题管理中截图不显示、大图不居中等多个界面问题,并优化了联系我们页面的视觉风格统一性。
多语言插件优化
1. 专业术语翻译机制重构
问题描述:
后台设置的自定义术语在前台翻译时有时生效、有时不生效
术语表从未被正确传递到前端,
translate.nomenclature.append()始终收到空数据切换翻译服务后仍请求旧的 zvo.cn API,导致 CORS 和 502 错误
根本原因分析:
Plugin.php::buildInlineConfig()中'nomenclature_map' => []直接置空,注释说"通过 AJAX 加载即可"frontend.js::loadConfigAndInit()在有内联配置时直接 early-return,根本不会发起 AJAX 请求获取术语表Plugin.php::getDisplayConfig()缺少translate_service、source_lang、target_lang、ignore_selectors_raw字段,全部回退到默认值translate.js中temp_nomenclature[local]始终为undefined(变量声明但未赋值的 bug)
修复方案:
1.1 术语表内联输出(核心修复)
参考 translate.zvo.cn 官方文档要求:
translate.nomenclature.append(from, to, properties); 注意,这行要放到 translate.execute(); 上面在 Plugin.php 中新增 buildNomenclatureMap() 方法,从 addons/multilang/data/nomenclature.json 读取术语数据并按目标语言分组构建 原文=译文 字符串,直接内联输出到页面。
修改文件:
addons/multilang/Plugin.php— 新增buildNomenclatureMap()方法;修改buildInlineConfig()调用该方法
执行链路(修复后):
PHP 渲染 HTML 时输出
window.PR_INLINE_CONFIG = {..., nomenclature_map: {en: "你好=Hello\n世界=ShiJie"}}frontend.js加载translate.js(异步)initTranslate()调用translate.nomenclature.append('chinese_simplified', 'english', '你好=Hello\n世界=ShiJie')— 在 execute 之前translate.execute()重置temp_nomenclature后开始扫描节点术语原文被替换为译文且不再被翻译接口处理
1.2 补齐配置字段
getDisplayConfig() 补齐 translate_service、source_lang、target_lang、ignore_selectors_raw 字段,确保用户在后台切换的翻译服务、源/目标语言、忽略选择器真正生效。
修改文件:
addons/multilang/Plugin.php—getDisplayConfig()方法
1.3 修复 temp_nomenclature 变量 bug
原代码中 nomenclatureKeyArray 只声明未赋值,导致 typeof 判断永远为 undefined,push 永远被跳过,最终 temp_nomenclature[local] 始终为 undefined。
修改文件:
public/static/addons/multilang/translate.js— 在循环外初始化var nomenclatureKeyArray = new Array();,移除无效的 typeof 判断;增加已存在时的合并逻辑
2. 翻译服务切换修复
问题:切换翻译服务后仍请求 api.translate.zvo.cn,导致 CORS 和 502 错误
修复:
后台设置页面增加"默认翻译服务 (zvo.cn)"选项
移除 Google 翻译服务(需翻墙,存在合规问题)
保留 Edge 浏览器翻译(免费,国内可用)
修改文件:
addons/multilang/view/admin/settings.html— 翻译服务下拉选项public/static/addons/multilang/translate.js— 条件性跳过版本检查
3. 语言切换按钮图标消失修复
问题:每次修改系统内容保存后,多语言插件的语言切换按钮图标消失,需要重新上传
修复:修改 Admin.php 保存逻辑,仅在提供新值时更新图标字段,保留已有图标路径
修改文件:
addons/multilang/controller/Admin.php— 保存设置时增加条件判断
主题管理修复
4. 主题截图不显示
问题:enterprise 主题在后台主题管理页面不显示截图,只显示默认占位图
原因:ThemeService.php 只查找 screenshot.png,而 enterprise 主题的截图是 screenshot.jpg
修复:
修改
ThemeService.php按优先级查找截图文件(支持png、jpg、jpeg、webp、gif)修正 enterprise 主题
theme.json中screenshots数组的扩展名从.png改为.jpg
修改文件:
app/service/ThemeService.php— 截图查找逻辑template/enterprise/theme.json— screenshots 数组扩展名
5. 主题预览大图不居中
问题:主题预览页面的大图偏左,没有占据左右箭头按钮之间的全部空间
修复:在 .preview-screenshot-container 添加 flex: 1,让它占据剩余空间
修改文件:
public/static/admin/css/theme.css—.preview-screenshot-container样式
界面优化
6. 联系我们页面文字颜色统一
问题:常见问题和保持联系的灰色文字与系统金色主题不一致
修复:将文字颜色改为金色(#c8a97e)
修改文件:
public/static/index/css/page_detail_contact.css— 文字颜色
7. 社交媒体图标悬停效果
问题:联系我们页面的社交媒体图标鼠标悬停时没有显示二维码,与底部不一致
修复:添加悬停事件处理,显示对应的二维码图片
修改文件:
template/default/index/page_detail_contact.html— 社交媒体图标悬停逻辑
Bug 修复
8. CSRF Token 不匹配
问题:多表单页面保存配置时 CSRF token 验证失败
修复:修改 config.js 优先使用全局 globalCsrfToken,而非每个表单的独立 token
修改文件:public/static/admin/js/config.js
9. 数据库路径恢复旧值
问题:清除缓存后,数据库中的图片路径恢复为旧值
原因:pr_system_config 表存在重复记录,缓存清除后读取到旧记录
修复:清理重复记录,确保每个配置项只有一条记录
修改文件:database/pr_system_config.sql
10. PHP autoload 错误
问题:debug_config.php 报错 Failed opening required '/vendor/autoload.php'
修复:确保 Composer 依赖正确安装,autoload.php 路径正确
修改文件:public/debug_config.php
技术要点
术语表数据格式
nomenclature.json 支持两种格式:
新格式(推荐):
[{"source": "你好", "translations": {"en": "Hello", "ja": "こんにちは"}}]旧格式(自动迁移):
[{"source": "你好", "target": "Hello"}]系统会自动将旧格式转换为新格式,按目标语言分组输出。
截图查找优先级
ThemeService.php 按以下优先级查找主题截图:
screenshots数组中声明的文件(精确匹配)screenshot.pngscreenshot.jpgscreenshot.jpegscreenshot.webpscreenshot.gif默认占位图
/static/admin/images/theme-default.png
升级注意事项
多语言术语表:如果之前设置了自定义术语,升级后会自动生效,无需重新配置
翻译服务:建议在后台多语言设置中将翻译服务改为「Edge 浏览器翻译」,避免 zvo.cn 服务不稳定导致的 502 错误
主题截图:enterprise 主题的
theme.json已修正,如果自定义了主题,请检查screenshots数组中的扩展名是否与实际文件匹配数据库:建议执行
database/pr_system_config.sql清理重复记录
发布日期:2026-06-26
更新类型:功能增强与 Bug 修复(Minor Release)
v2.6.0 API 配置管理模块
更新概述
v2.6.0 版本新增了 API 配置管理模块,为 PuranCMS 引入完整的邮件和短信通知能力。管理员可在后台配置 SMTP 服务器、短信服务商参数,并按事件维度开启/关闭各类通知(订单、会员、留言、安全),同时支持短信模板的可视化配置。
核心新增
1. 邮件配置管理(mail.html)
1.1 SMTP 服务器配置
服务器参数:支持配置 SMTP 服务器地址、端口、加密方式(SSL/TLS/不加密)
认证信息:用户名、密码(支持授权码)配置,密码字段支持显示/隐藏切换
发件人信息:可自定义发件人邮箱地址和显示名称
测试功能:支持输入测试邮箱地址,一键发送测试邮件验证配置
配置项说明:
| 字段 | 说明 | 示例 |
|---|---|---|
mail_host | SMTP 服务器地址 | smtp.qq.com |
mail_port | SMTP 端口 | 465(SSL)、587(TLS)、25(非加密) |
mail_secure | 加密方式 | ssl / tls / 空(不加密) |
mail_username | SMTP 登录用户名 | 通常是邮箱地址 |
mail_password | SMTP 登录密码或授权码 | QQ/163 邮箱需使用授权码 |
mail_from_email | 发件人邮箱地址 | |
mail_from_name | 发件人显示名称 |
1.2 邮件通知事件配置
支持按事件维度开启/关闭邮件通知,涵盖 4 大类 10 个事件:
订单通知:
订单创建(
mail_notify_order_created)订单支付成功(
mail_notify_order_paid)订单取消(
mail_notify_order_cancelled)订单发货(
mail_notify_order_shipped)
会员通知:
会员注册(
mail_notify_user_register)找回密码(
mail_notify_user_reset_password)
留言通知:
留言回复(
mail_notify_message_reply)新留言通知(
mail_notify_new_message)
安全通知:
安全告警(
mail_notify_security_alert)—— SQL 注入、XSS 等攻击拦截时通知管理员后台登录(
mail_notify_admin_login)
2. 短信配置管理(sms.html)
2.1 短信服务商配置
多服务商支持:阿里云短信、腾讯云短信、华为云短信
认证参数:AccessKey ID、AccessKey Secret(支持显示/隐藏切换)
短信签名:可自定义短信签名(需在服务商控制台审核通过)
配置项说明:
| 字段 | 说明 | 示例 |
|---|---|---|
sms_provider | 短信服务商 | aliyun / tencent / huawei |
sms_access_key_id | AccessKey ID | |
sms_access_key_secret | AccessKey Secret | |
sms_sign_name | 短信签名 | PuranCMS |
2.2 短信通知事件配置
与邮件通知事件完全一致,同样涵盖 4 大类 10 个事件,字段前缀为 sms_notify_*:
sms_notify_order_created/sms_notify_order_paid/sms_notify_order_cancelled/sms_notify_order_shippedsms_notify_user_register/sms_notify_user_reset_passwordsms_notify_message_reply/sms_notify_new_messagesms_notify_security_alert/sms_notify_admin_login
2.3 短信模板管理
模板 CODE:配置服务商审核通过的模板 CODE
模板内容:填写与服务商处一致的模板内容,支持多种变量语法
启用状态:每个模板可独立启用/停用
变量支持:系统自动识别模板中的占位符并在发送时替换为实际值
支持的变量语法:
| 语法 | 说明 | 适用场景 |
|---|---|---|
{$orderNo} | 命名变量 | 通用 |
${orderNo} | 命名变量(阿里云推荐) | 阿里云 |
{1} | 数字索引(对应第 1 个可用变量) | 腾讯云 |
${1} | 数字索引(华为云) | 华为云 |
界面设计
1. 页面布局
采用 Layui Tab 组件实现多标签切换
邮件配置:「邮箱配置」+「通知事件」两个标签
短信配置:「短信配置」+「通知事件」+「短信模板」三个标签
2. 样式规范
页面容器 ID:
#pr-page-api-mail/#pr-page-api-smsCSS 命名空间:
.pr-page-api-mail/.pr-page-api-sms共用样式文件:
/static/admin/css/api_config.css卡片式布局:
.config-card包裹配置项,标题 + 内容分层
3. 交互细节
密码字段支持显示/隐藏切换(眼睛图标)
开关组件使用 Layui Switch(开启/关闭)
保存操作统一使用 AJAX POST 请求,成功后显示提示消息
测试邮件发送时显示加载动画
路由配置
邮件配置和短信配置的路由定义在 app/admin/route/app.php 中:
// 邮件配置
Route::get('apiConfig/mail', 'apiConfig/mail');
Route::post('apiConfig/mail', 'apiConfig/mail');
Route::post('apiConfig/testMail', 'apiConfig/testMail');
// 短信配置
Route::get('apiConfig/sms', 'apiConfig/sms');
Route::post('apiConfig/sms', 'apiConfig/sms');
Route::post('apiConfig/saveSmsTemplates', 'apiConfig/saveSmsTemplates');数据库变更
新增配置项
邮件和短信配置项存储在 pr_system_config 表中,group 字段为 api_config:
| group | name | value | 说明 |
|---|---|---|---|
| api_config | mail_host | SMTP 服务器 | |
| api_config | mail_port | 465 | SMTP 端口 |
| api_config | mail_secure | ssl | 加密方式 |
| api_config | mail_username | 用户名 | |
| api_config | mail_password | 密码 | |
| api_config | mail_from_email | 发件人邮箱 | |
| api_config | mail_from_name | 发件人名称 | |
| api_config | mail_notify_order_created | 0 | 订单创建通知 |
| api_config | mail_notify_order_paid | 0 | 订单支付通知 |
| api_config | mail_notify_order_cancelled | 0 | 订单取消通知 |
| api_config | mail_notify_order_shipped | 0 | 订单发货通知 |
| api_config | mail_notify_user_register | 0 | 会员注册通知 |
| api_config | mail_notify_user_reset_password | 0 | 找回密码通知 |
| api_config | mail_notify_message_reply | 0 | 留言回复通知 |
| api_config | mail_notify_new_message | 0 | 新留言通知 |
| api_config | mail_notify_security_alert | 1 | 安全告警通知 |
| api_config | mail_notify_admin_login | 0 | 后台登录通知 |
| api_config | sms_provider | aliyun | 短信服务商 |
| api_config | sms_access_key_id | AccessKey ID | |
| api_config | sms_access_key_secret | AccessKey Secret | |
| api_config | sms_sign_name | 短信签名 | |
| api_config | sms_notify_order_created | 0 | 订单创建通知 |
| api_config | sms_notify_order_paid | 0 | 订单支付通知 |
| api_config | sms_notify_order_cancelled | 0 | 订单取消通知 |
| api_config | sms_notify_order_shipped | 0 | 订单发货通知 |
| api_config | sms_notify_user_register | 0 | 会员注册通知 |
| api_config | sms_notify_user_reset_password | 0 | 找回密码通知 |
| api_config | sms_notify_message_reply | 0 | 留言回复通知 |
| api_config | sms_notify_new_message | 0 | 新留言通知 |
| api_config | sms_notify_security_alert | 0 | 安全告警通知 |
| api_config | sms_notify_admin_login | 0 | 后台登录通知 |
短信模板配置
短信模板配置以 JSON 格式存储在 pr_system_config 表中:
| group | name | value | 说明 |
|---|---|---|---|
| api_config | sms_templates | {...} | 短信模板配置 JSON |
JSON 结构示例:
{
"order_created": {
"code": "SMS_123456",
"content": "您的订单 {$orderNo} 已创建成功",
"enabled": 1
},
"order_paid": {
"code": "SMS_123457",
"content": "您的订单 {$orderNo} 已支付成功,金额 {$amount} 元",
"enabled": 1
}
}文件变更
新增文件
| 文件路径 | 说明 |
|---|---|
app/admin/view/api_config/mail.html | 邮件配置页面 |
app/admin/view/api_config/sms.html | 短信配置页面 |
static/admin/css/api_config.css | API 配置页面样式 |
修改文件
| 文件路径 | 说明 |
|---|---|
app/admin/route/app.php | 新增邮件/短信配置路由 |
app/admin/controller/ApiConfig.php | 新增邮件/短信配置控制器方法 |
使用指南
1. 配置邮件通知
进入后台 系统设置 → API 配置 → 邮箱配置
填写 SMTP 服务器信息(以 QQ 邮箱为例):
SMTP 服务器:
smtp.qq.comSMTP 端口:
465加密方式:
SSL用户名:你的 QQ 邮箱地址
密码:QQ 邮箱授权码(非登录密码,需在 QQ 邮箱设置中开启并获取)
发件人邮箱:你的 QQ 邮箱地址
发件人名称:显示在收件人邮箱中的名称
点击「发送测试邮件」验证配置是否正确
切换到「通知事件」标签,开启需要的事件通知
点击「保存配置」和「保存通知设置」
2. 配置短信通知
进入后台 系统设置 → API 配置 → 短信配置
选择短信服务商(阿里云/腾讯云/华为云)
填写 AccessKey ID 和 AccessKey Secret(需在服务商控制台获取)
填写短信签名(需在服务商控制台审核通过)
切换到「通知事件」标签,开启需要的事件通知
切换到「短信模板」标签,为每个事件配置模板 CODE 和内容
点击「保存配置」「保存通知设置」「保存模板设置」
注意事项
邮箱授权码:QQ 邮箱、163 邮箱等需要使用授权码而非登录密码,需在邮箱设置中开启 SMTP 服务并获取授权码
短信签名:短信签名需在服务商控制台申请并审核通过后才能使用
短信模板:模板内容需与服务商控制台审核通过的模板保持一致,变量名需与可用变量一致
安全告警:安全告警通知默认开启,建议保持开启状态以及时发现安全风险
测试邮件:配置完成后务必发送测试邮件验证配置正确性
后续计划
支持邮件模板配置(HTML 模板、变量替换)
支持短信发送记录查看
支持邮件发送记录查看
支持短信/邮件发送失败重试机制
支持批量发送通知(如全员通知)