# PROJECT KNOWLEDGE BASE **Generated:** 2026-04-26 **Commit:** df6b22d **Branch:** master ## OVERVIEW 基于 ThinkPHP 6 的企业官网内容管理系统(CMS),项目名 `ulthon_admin`,最低支持 PHP 7.1。多应用架构(admin/index/api),layui 前端,支持 MySQL + SQLite 双数据库。 ## STRUCTURE ``` ulthon_information/ ├── app/ # 应用核心(多应用模式) │ ├── admin/controller/ # 后台管理(15个控制器) │ ├── index/controller/ # 前台展示(5个控制器) │ ├── api/controller/ # API接口(文章/附件/分类/文件/验证码/密钥) │ ├── model/ # 全局模型(17个,非各应用内) │ ├── common/ # 跨应用共享层(tools/traits/model) │ └── middleware/ # 中间件(ConfigInit/AdminLog/PermissionRecord) ├── config/ # 框架配置(16个,含2个自定义) ├── database/migrations/ # Phinx迁移(16个表) ├── database/seeds/ # 种子数据(3个) ├── extend/think/ # PSR-0自定义扩展(Htmx响应/DebugMysql日志) ├── public/ # Web根目录 │ └── static/lib/ # 前端库(layui/wangeditor/quill等,直接提交) ├── route/app.php # 全局路由(sitemap/rss/atom) ├── view/ # 模板文件(admin/index/common) ├── source/font/ # 思源黑体(水印用) └── think # CLI入口 ``` ## WHERE TO LOOK | 任务 | 位置 | 备注 | |------|------|------| | 添加后台功能 | `app/admin/controller/` | 继承 `admin\controller\Common` | | 添加前台页面 | `app/index/controller/` | 继承 `index\controller\Common` | | 添加API接口 | `app/api/controller/` | 直接继承 `app\BaseController` | | 添加数据模型 | `app/model/` | 继承 `common\model\Base`,使用 `AutoClearCache` | | 添加数据库表 | `database/migrations/` | 用 `ColumnFormat` 辅助类定义列 | | 修改全局函数 | `app/common.php` | json_message/geturl/check_permission等 | | 修改配置 | `config/` | 自定义: `upload_type.php`/`view_type.php` | | 添加前端库 | `public/static/lib/` | 直接提交源码(无npm) | | SEO相关 | `app/common/tools/Sitemap.php`/`Rss.php` | 通过 `route/app.php` 注册 | | 上传文件逻辑 | `app/UploadFiles.php` | 静态服务类,支持多编辑器适配 | | 权限控制 | `app/common.php` -> `check_permission()` | admin_id=1 为超级管理员 | | 模板渲染 | `view/` | ThinkPHP `{}` 标签,默认过滤 `ua_htmlentities` | ## CODE MAP ### 控制器继承链 ``` app\BaseController (abstract: validate/success/error/redirect) +-- admin\controller\Common (Session鉴权) -> 15个子控制器 +-- index\controller\BaseController (域名跳转/HTTPS) -> Common -> 3个子控制器 +-- api\controller\* (直接继承 BaseController, ApiKeyAuth中间件) -> 7个控制器(含分类查询) ``` ### 响应格式 ``` JSON: { code: 0(成功)/500(失败), msg: '', data: {} } AJAX请求 -> JSON; 普通请求 -> 模板页面(common@tpl/success|error) 辅助: json_message() / htmx() / $this->success() / $this->error() ``` ### 数据库表关系 ``` Post --(M:N)--> Category (通过 post_category) Post --(M:N)--> Tag (通过 post_tag) Post --(1:N)--> PostComment, PostVisit Post 字段含 cover_text: 封面文案,用于手机图片排版封面展示 Admin --(N:1)--> AdminGroup --(权限列表)--> AdminPermission 表前缀: ul_,时间戳: int(10),软删除: delete_time字段 ``` ## CONVENTIONS - **代码风格**: PSR-12 (见 `.php-cs-fixer.php`),单引号,后置自增,import按字母排序 - **自动加载**: PSR-4 `app\` -> `app/`,PSR-0 `extend/` - **时间戳**: 统一 int(10) 整数,非 datetime - **软删除**: `delete_time` 字段(int),值=0表示未删除 - **缓存**: 模型变更后自动清缓存(AutoClearCache trait) - **数据库迁移**: 仅 `change()` 方法(不可逆),用 `ColumnFormat` 辅助类 - **密码哈希**: `md5(password + salt)` (已知安全问题,但项目内一致使用) - **视图过滤**: 默认 `ua_htmlentities` (null安全) - **多应用URL**: 默认路径前缀 `/index/`/`/admin/`/`/api/`,README描述了域名绑定但配置中未启用 - **Session**: 7天过期 - **CLI模式**: 缓存强制用 file 驱动(防Redis连接失败) ## ANTI-PATTERNS (THIS PROJECT) - **md5密码哈希**: 全项目使用 `md5(password+salt)`,未使用 `password_hash()`。涉及 Login/Admin/User/ResetPassword - **批量赋值无保护**: `Model::create($post_data)` 未使用 `$fillable` 白名单 - **SSL验证禁用**: `geturl()`/`posturl()` 中 `CURLOPT_SSL_VERIFYPEER=false` - **调试残留**: `WxOpen::test()` 含 `dump()` 和硬编码微信AppID - **.env 含生产凭据**: 数据库密码明文,已提交Git - **.vscode/sftp.json**: 含服务器root密码 - **.user.ini 硬编码路径**: `open_basedir` 指向 `/www/wwwroot/phpreturn.com/` - **目录权限0777**: `File.php` 中 `mkdir` 使用 0777 - **中间件已禁用**: AdminLog/PermissionRecord 被注释掉 ## UNIQUE STYLES - **HTMX支持**: `extend/think/response/Htmx.php` 自定义响应类型,`htmx()` 全局函数 - **DebugMysql日志**: `extend/think/log/driver/DebugMysql.php` 将日志写入数据库 - **图片水印**: `common/tools/Image.php` 用 Intervention/Image + 思源黑体 - **防采集**: `common/tools/PostShow.php` 用 phpQuery 注入版权文字到HTML - **UA解析**: PostVisit 用 DeviceDetector 解析访问者设备信息 - **UserHub SSO**: 通过 `ulthon/user_hub_client` 包实现OAuth单点登录 - **HTML转Markdown**: admin/Post 控制器支持 HTML -> Markdown 转换 - **多编辑器适配**: UploadFiles 支持 wangEditor/editorMD/base64/URL 多种上传方式 - **view_type.php**: 分类/文章的视图模板映射(产品/案例/关于变体/动态) - **upload_type.php**: 上传文件业务类型枚举 ## COMMANDS ```bash # 安装 composer install # 数据库 php think migrate:run # 执行迁移 php think seed:run # 填充种子数据 # 开发服务器 php think run -p 8010 # 内置服务器(必须带index.php) # 代码风格 vendor/bin/php-cs-fixer fix # 运行 PHP-CS-Fixer # 维护 php think reset_password # 重置admin密码为123456 ``` ## NOTES - 默认数据库驱动为 SQLite(`ul.db`),生产通过 `.env` 切换为 MySQL - `app/command/spider/` 和 `app/common/response/` 为空目录(废弃/未实现) - `.travis.yml` 是 ThinkPHP 框架的CI配置,非本项目CI - 前端库(`public/static/lib/`)未使用包管理器,直接提交源码 - 日志默认通道为 `debug_mysql`,需确保对应表存在 - `cacheAlways()` 方法非TP6内置,可能来自 composer 依赖扩展 - `app_default_doamin` 在 config/app.php 中拼写错误(应为 domain) - 域名绑定规则: www->前台, admin->后台, api->接口 (需Web服务器配合)