feat: 上线前安全加固与发布工程化;appmall 由插件迁移为独立应用
安全(P0) - 发布包签名:新增 scripts/package_keygen.php、scripts/package_verify.php、 ywxapp\service\PackageVerifier;FrameworkService::apply() 解压前强制验签 (ywxapp.framework_package_verify,默认开启) - JWT 收紧:config/jwt.php 移除公开默认密钥,JwtService::assertStrongSecret() 校验非空 / 长度≥32 / 已知弱值;.env.production.example 键名由 JWT_SECRET_KEY 修正为 JWT_SECRET - /api/v1/Article:免登录白名单收窄为只读接口,写操作字段白名单 + assertOwner() 越权校验 - 开发者令牌:查找接口不再回显明文、统一失败文案 + 限流 - TemplateInstaller:文件名白名单 + realpath 归一化 + 目录内断言,修复 Zip Slip;补 use ZipArchive - 后台登录:接入验证码、失败锁定与登录限流(config/ratelimit.php) - 缓存 / Session 驱动可由 .env 覆盖(CACHE_DRIVER / SESSION_TYPE),集群部署改 redis - paycenter 支付日志开关改为 PAY_LOG,不再跟随 APP_DEBUG 工程化 / 交付 - 新增 CHANGELOG.md 与 .env.production.example;composer.lock 入库锁定依赖版本 - 插件离线安装 CLI 增加 --uid,后台上传安装透传 uid,付费插件授权校验可通过 - 授权拒绝文案区分「未携带 uid」与「未找到有效授权」,便于排障 - .gitignore 放行 .env.production.example / .env.addon.example / .gitattributes / public/.htaccess 结构 - appmall 由 addon/appmall 迁移为独立应用 app/appmall(市场 / 开发者中心 / 审核 / 分润)
This commit is contained in:
1 parent
1d49e6f5ee
commit
18101cf11a
636 files changed
+58517
-9519
No files matched your search
@@ -0,0 +1,342 @@
|
||||
# haonav 网址导航 — 使用文档
|
||||
|
||||
> 面向站长/管理员。开发者请看 [haonav_dev_guide.md](haonav_dev_guide.md)。
|
||||
|
||||
- 插件标识:`haonav`
|
||||
- 版本:1.0.9
|
||||
- 访问入口:`https://你的域名/haonav`(前台)/ `https://你的域名/haonav/dashboard`(后台)
|
||||
- 依赖:YwxApp 框架 ≥ PHP 8.0、MySQL 5.7+
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能总览
|
||||
|
||||
| 模块 | 说明 |
|
||||
|---|---|
|
||||
| 网址导航首页 | 顶级分类聚合 + 子分类 + 每分类精选链接 + 热门/推荐 |
|
||||
| 站内搜索 | 关键词/拼音搜索 + 搜索建议(suggest)+ 多引擎跳转 |
|
||||
| 热门排行 | 按点击量 Top 50 |
|
||||
| 网址详情页 | 快照预览、评分、JSON-LD 结构化数据(SEO) |
|
||||
| 分类浏览 | 一级/二级分类,URL 规则化(`/haonav/category/{id}.html`) |
|
||||
| 申请收录 | 前台投稿 → 后台审核 |
|
||||
| 广告位 | 首页/详情页广告位管理 + 点击统计 |
|
||||
| 我的收藏 | 本地收藏(localStorage)+ 云端同步(登录)+ 收藏夹分享页 |
|
||||
| 实时小组件 | 实时热搜 / 天气(服务端代理 + 缓存) |
|
||||
| 主题个性化 | 浅色/暗色/跟随系统 + 5 组主色 + 10 组背景渐变 + 自定义背景图 + 随机换色 |
|
||||
| 节日/节气换装 | **36 项自动检测**(24 节气 + 传统节日 + 公历节日),后台可关,访客可关 |
|
||||
| PWA 离线 | manifest + Service Worker 缓存(支持添加到主屏幕、离线访问) |
|
||||
| SEO | sitemap.xml/html、canonical、JSON-LD、拼音搜索 |
|
||||
| 死链巡检 | 计划任务全量检测 + 前台惰性巡检兜底,可自动下线/恢复 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 安装与启用
|
||||
|
||||
1. 将插件目录放入 `addon/haonav/`
|
||||
2. 后台 → 应用管理 → 找到「网址导航」→ 安装/启用
|
||||
3. 首次访问后台配置页时,数据库会自动补种默认配置行(含表主键自愈),无需手工执行 SQL
|
||||
4. 前台访问 `/haonav` 即可看到空站点,进入后台开始录入
|
||||
|
||||
---
|
||||
|
||||
## 3. 快速上手(5 分钟建站)
|
||||
|
||||
1. **建分类**:后台 → 网址导航 → 分类管理 → 新增一级分类(如「常用工具」),可再挂二级分类
|
||||
2. **录链接**:链接管理 → 新增 → 选分类、填名称/URL/描述、可选设「热门」「推荐」
|
||||
3. **看前台**:`/haonav` 首页即展示;点击量自动累计进排行榜
|
||||
4. **做 SEO**:后台 → 网址导航配置 → 填 SEO 标题/关键词/描述
|
||||
5. **(可选)开启外观**:同一配置页「外观」分组设置背景图/随机换色/节日换装
|
||||
|
||||
---
|
||||
|
||||
## 4. 后台管理
|
||||
|
||||
### 4.1 数据概览(仪表盘)
|
||||
|
||||
`/haonav/dashboard` — 链接/分类/收藏/点击量汇总统计 + 点击热力图。访问时自动为存量链接回填拼音搜索串(每次 300 条,幂等)。
|
||||
|
||||
### 4.2 分类管理
|
||||
|
||||
- 一级/二级分类、排序(sort 越大越靠前)、启用/禁用
|
||||
- 删除分类不影响已挂链接(链接保留待重新归类)
|
||||
|
||||
### 4.3 链接管理
|
||||
|
||||
- 字段:名称、URL、分类、描述、关键词、热门/推荐标记、排序、状态
|
||||
- 自动抓取 favicon(`/haonav/favicon/...` 代理输出)与网站快照
|
||||
- **回收站**:删除先进回收站,可恢复/彻底删除
|
||||
- **死链巡检**:见 §8 计划任务
|
||||
|
||||
### 4.4 申请审核(Apply)
|
||||
|
||||
前台 `/haonav/apply` 投稿后进入待审列表,可一键通过(转为正式链接)/驳回。
|
||||
|
||||
### 4.5 广告位(Ad)
|
||||
|
||||
- 按 position 分组投放(如 `home_top`、`detail_side`)
|
||||
- 支持图片/文字广告、投放时段、排序
|
||||
- 点击经 `/haonav/ad/click` 跳转并计数
|
||||
|
||||
### 4.6 配置(Configs)
|
||||
|
||||
分组管理所有配置项,保存即时生效。见下节明细。
|
||||
|
||||
---
|
||||
|
||||
## 5. 配置项详解
|
||||
|
||||
后台 → 网址导航配置。首次访问自动补齐缺失项。
|
||||
|
||||
| 分组 | 配置项 | 默认 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 基础 | `default_engine` | baidu | 搜索框默认引擎 |
|
||||
| 基础 | `enable_submit` | 1 | 前台投稿开关 |
|
||||
| 基础 | `enable_hot_api` | 0 | 实时热搜组件开关 |
|
||||
| SEO | `seo_title` / `seo_keywords` / `seo_description` | — | 全站 TDK |
|
||||
| 返利 | `enable_rebate` | 0 | 命中域名自动拼接返利 PID |
|
||||
| 返利 | `rebate_param` | pid | 返利参数名 |
|
||||
| 返利 | `rebate_domains` | taobao.com,... | 返利适用域名列表 |
|
||||
| task | `deadlink_auto` | 0 | 死链连续失败达阈值自动下线 |
|
||||
| task | `deadlink_threshold` | 2 | 连续失败次数阈值 |
|
||||
| task | `deadlink_recover` | 0 | 恢复可达后自动重新上线 |
|
||||
| **外观** | `bg_image` | 空 | 全站默认背景图 URL(空=渐变) |
|
||||
| **外观** | `bg_mask` | 35 | 背景图遮罩不透明度 0-90(保证文字可读) |
|
||||
| **外观** | `bg_random` | 0 | 游客随机渐变背景(每次刷新随机) |
|
||||
| **外观** | `festival_theme` | 1 | 节日/节气自动换装总开关 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 前台功能说明
|
||||
|
||||
| 页面 | URL | 说明 |
|
||||
|---|---|---|
|
||||
| 首页 | `/haonav`(`/haonav/index.html`) | 分类聚合 + 热门 18 + 推荐 10 |
|
||||
| 搜索 | `/haonav/search?q=关键词` | 站内 + 引擎外跳 |
|
||||
| 排行 | `/haonav/rank` | 点击量 Top 50 |
|
||||
| 详情 | `/haonav/site/{id}.html` | 快照、评分、JSON-LD |
|
||||
| 分类 | `/haonav/category/{id}.html` | 单分类列表 |
|
||||
| 申请 | `/haonav/apply` | 收录/广告合作投稿 |
|
||||
| 分享页 | `/haonav/favorite/shared/{token}.html` | 只读收藏夹(noindex) |
|
||||
| 站点地图 | `/haonav/sitemap.xml` | XML + HTML 双格式 |
|
||||
| Service Worker | `/haonav/sw` | PWA 离线支撑 |
|
||||
|
||||
**会员**:`/haonav/account/login|register|logout|profile`。登录后「我的导航」自动云端同步收藏;未登录自动回退本地 localStorage。
|
||||
|
||||
---
|
||||
|
||||
## 7. 主题与个性化
|
||||
|
||||
前台导航栏 🎨 按钮打开主题面板:
|
||||
|
||||
| 功能 | 说明 | 记忆 |
|
||||
|---|---|---|
|
||||
| 模式 | ☀️ 浅色 / 🌙 暗色 / 🌗 跟随系统 | localStorage |
|
||||
| 主色 | 5 组色板(紫/绿/蓝/粉/灰) | localStorage |
|
||||
| 背景 | 10 组渐变色点 + 🎲 随机换色 + 自定义图片 URL | localStorage |
|
||||
| 恢复默认 | 一键清除以上所有个人偏好 | — |
|
||||
|
||||
**自定义背景图**:面板中「粘贴图片地址设为背景」→ 应用(或回车)。图片以 cover 全屏铺满,自动叠加白色遮罩(暗色模式自动改压暗),遮罩强度由后台 `bg_mask` 控制。
|
||||
|
||||
**优先级链**(高 → 低):
|
||||
|
||||
```
|
||||
访客自选背景/主色 > 节日/节气主题 > 站点背景图(bg_image) > 随机换色 > 默认渐变
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 节日 / 节气自动换装
|
||||
|
||||
### 8.1 内置条目(共 36 项)
|
||||
|
||||
- **24 节气**:立春/雨水/惊蛰/春分/清明/谷雨/立夏/小满/芒种/夏至/小暑/大暑/立秋/处暑/白露/秋分/寒露/霜降/立冬/小雪/大雪/冬至/小寒/大寒 — 公历固定日期,当天自动换季相配色 + 应季粒子(🌱☀️🍂❄️)
|
||||
- **传统节日(农历)**:除夕 / 春节(初一至初三)/ 元宵 / 小年 / 端午 / 七夕 / 中秋 / 重阳 — 内置 2026-2036 公历换算表
|
||||
- **公历节日**:元旦 / 情人节 / 国庆(10/1-10/7)/ 万圣节 / 圣诞(12/24-12/26)
|
||||
|
||||
### 8.2 效果
|
||||
|
||||
命中当天自动:换节日背景渐变 → 换全站主色 → 飘落装饰粒子(emoji 随机大小/速度)→ 右上角徽章(如「🏮 春节快乐」「⚡ 惊蛰」)。
|
||||
|
||||
- **时间判定**:浏览器本地时间(`new Date()`)。跨时区访客可能偏移 1 天,国内用户无感
|
||||
- **访客关闭**:点徽章右上 × 永久关闭(localStorage)
|
||||
- **站长关闭**:后台 → 外观 → 节日主题自动换装 → 0
|
||||
|
||||
### 8.3 「节日不生效」排查
|
||||
|
||||
依次检查(Console 执行):
|
||||
|
||||
```js
|
||||
localStorage.getItem('haonav_festival_off') // '1' = 曾点过关闭 → removeItem 后刷新
|
||||
localStorage.getItem('haonav_bg') // 有值 = 自选背景覆盖了节日背景
|
||||
window.NavAppearance.festival // 0 = 后台总开关关闭
|
||||
```
|
||||
|
||||
Service Worker 旧缓存干扰时:F12 → Application → Clear site data。
|
||||
|
||||
---
|
||||
|
||||
## 9. SEO 能力
|
||||
|
||||
- `sitemap.xml` / `sitemap.html` 双格式自动生成
|
||||
- 详情页输出 JSON-LD(WebSite + SearchAction 搜索直达框)
|
||||
- 全站 canonical 链接
|
||||
- 链接支持自定义 keywords/description
|
||||
- 拼音搜索:中文名自动转拼音串,支持拼音首字母检索
|
||||
|
||||
---
|
||||
|
||||
## 10. 死链检测(计划任务)
|
||||
|
||||
两种模式可同时启用:
|
||||
|
||||
### 10.1 定时全量(推荐 cron)
|
||||
|
||||
```cron
|
||||
0 3 * * * curl -s "https://你的域名/haonav/task/checklinks?token=你的TOKEN" > /dev/null
|
||||
```
|
||||
|
||||
每日凌晨全量检测所有启用链接。
|
||||
|
||||
### 10.2 惰性巡检(无 cron 兜底)
|
||||
|
||||
前台页面访问时异步触发 `/haonav/task/autocheck`,带缓存锁限频,自动分批检测。
|
||||
|
||||
### 10.3 自动下线/恢复
|
||||
|
||||
开启「死链自动下线」后:连续失败 ≥ 阈值 → 自动禁用;开启「恢复自动上线」后:重新可达 → 自动启用(仅对检测器下线的链接生效,手动禁用不受影响)。
|
||||
|
||||
---
|
||||
|
||||
## 11. 常见问题 FAQ
|
||||
|
||||
**Q1:页面 500?**
|
||||
确认没有模板 include 传参(`{include file="..." var="x" /}` 在 think-template 跨模板作用域不可靠,page-*.css 由各页面手动 `<link>` 引入)。
|
||||
|
||||
**Q2:改了背景图后台配置前台不生效?**
|
||||
浏览器/SW 缓存。F12 → Application → Clear site data;或等 sw 版本升级自动刷新。
|
||||
|
||||
**Q3:游客反馈"背景一直没变过"?**
|
||||
该游客曾点过节日徽章 × 或自选过背景。让其点击面板「↺ 恢复默认」。
|
||||
|
||||
**Q4:拼音搜索搜不到?**
|
||||
旧数据拼音串未回填。访问一次后台仪表盘即自动补(每批 300 条),或多次刷新。
|
||||
|
||||
**Q5:收藏在不同设备不同步?**
|
||||
收藏分本地(未登录)/云端(登录)两套。登录后自动 merge 并以云端为准。
|
||||
|
||||
---
|
||||
|
||||
## 12. 绑定域名访问
|
||||
|
||||
希望独立域名(如 `hao.example.com`)直接访问网址导航,而不是 `example.com/haonav`?YwxApp 通过 `config/app.php` 的 `domain_bind` 支持。
|
||||
|
||||
### 12.1 三种使用场景
|
||||
|
||||
| 场景 | 配置方式 | URL 形态 |
|
||||
|---|---|---|
|
||||
| 默认(路径访问) | 不配 | `example.com/haonav` |
|
||||
| 二级域名绑定 | `'hao' => 'haonav'` | `hao.example.com`(自动剥 `hao.`) |
|
||||
| 完整域名绑定 | `'hao.example.com' => 'haonav'` | 直接访问 `hao.example.com` |
|
||||
|
||||
### 12.2 启用步骤(5 步)
|
||||
|
||||
#### ① 修改 `config/app.php`
|
||||
|
||||
```php
|
||||
'domain_bind' => [
|
||||
'hao' => 'haonav', // 二级域名 → 插件名(推荐)
|
||||
// 'hao.example.com' => 'haonav', // 完整域名 → 插件名
|
||||
],
|
||||
```
|
||||
|
||||
#### ② Web 服务器指向同一项目目录
|
||||
|
||||
绑定域名访问本质上是同一份代码,让 DNS 把 `hao.example.com` 解析到与 `example.com` 相同的服务器 / 同一 Web 根。
|
||||
|
||||
**Nginx**(在主 server 块外新增或合并):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.com hao.example.com; # 多 server_name 即可
|
||||
root /www/ywxapp_dev/public;
|
||||
index index.php;
|
||||
|
||||
# 其余 fastcgi / rewrite 规则同主站
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass unix:/run/php/php-fpm.sock;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Apache**:`ServerName example.com` → `ServerAlias hao.example.com`。
|
||||
|
||||
#### ③ DNS 解析
|
||||
|
||||
到域名服务商把 `hao.example.com` 用 A/CNAME 记录指向主站 IP,TTL 选短值便于调试。
|
||||
|
||||
#### ④ 清框架运行时缓存
|
||||
|
||||
```bash
|
||||
rm -rf runtime/cache/*
|
||||
```
|
||||
|
||||
#### ⑤ 测试
|
||||
|
||||
浏览器访问 `http://hao.example.com` → 应直接呈现 haonav 首页(不再带 `/haonav` 前缀)。
|
||||
|
||||
### 12.3 「绑定后无法访问」逐项排查
|
||||
|
||||
按下面顺序逐项确认(90% 的问题在第 1/2 步):
|
||||
|
||||
| 序号 | 排查点 | 自检命令 / 现象 |
|
||||
|---|---|---|
|
||||
| 1 | **DNS 是否解析到服务器** | `ping hao.example.com` 应返回主站 IP;不通就是 DNS 没配 |
|
||||
| 2 | **Web Server 是否监听该域名** | `curl -H "Host: hao.example.com" http://服务器IP/` 不应返回 404/连接拒绝;Nginx 看 `server_name` 包含子域名,Apache 看 `ServerAlias` |
|
||||
| 3 | **`config/app.php` 是否正确** | `php -r "print_r(config('app.domain_bind'));"` 确认配置生效(务必重启 php-fpm) |
|
||||
| 4 | **缓存清理** | 改完配置删 `runtime/cache/*`;TP 路由缓存若有也清 |
|
||||
| 5 | **插件名与 bind 值一致** | `domain_bind['hao']='haonav'` 中 `haonav` 必须与 `addon/haonav/info.php` 的 `name` 完全一致(区分大小写) |
|
||||
| 6 | **`addon/haonav/` 存在且有 route** | 验证 `addon/haonav/route/app.php` 可被框架 include |
|
||||
| 7 | **完整域名是否带协议** | `'hao.example.com'` 不要写成 `'http://hao.example.com'` |
|
||||
| 8 | **HTTPS** | 绑定后若浏览器强制 HTTPS,请确保子域名也有证书(Let's Encrypt 用 `certbot --expand`) |
|
||||
| 9 | **SSL 泛域名** | 多子域名绑同一站点,用通配证书 `*.example.com` 最省事 |
|
||||
| 10 | **框架缓存类** | 部分主机有 OPcache,改完 `config/app.php` 重启 `php-fpm` 才生效 |
|
||||
|
||||
**最常见两大坑**:
|
||||
|
||||
```
|
||||
坑 ①:DNS 已解析但 Web Server 没加 server_name → 访问显示「无法访问此网站」/ 默认页
|
||||
坑 ②:Web Server 已加但 domain_bind 没写 / 拼写错 → 显示「路由不存在 404」
|
||||
```
|
||||
|
||||
### 12.4 多域名绑定同一插件
|
||||
|
||||
```php
|
||||
'domain_bind' => [
|
||||
'hao' => 'haonav', // hao.example.com
|
||||
'nav' => 'haonav', // nav.example.com
|
||||
'hao.dev.example.com' => 'haonav', // 测试子域
|
||||
],
|
||||
```
|
||||
|
||||
不同域名可分别承担同一插件的「访问入口」与「SEO 镜像」,但**避免一站多域名导致 SEO 重复**——通过 `seo_title` 区分或加 `<link rel="canonical">` 指向主域。
|
||||
|
||||
### 12.5 绑定域名后的相对路径影响
|
||||
|
||||
| 场景 | 行为 |
|
||||
|---|---|
|
||||
| 模板用 `url('haonav/index')` | 生成的 URL 已自动带域名上下文 → `https://hao.example.com/haonav/index.html` |
|
||||
| 模板用绝对路径 `/static/...` | 不变(推荐) |
|
||||
| 模板用相对路径 `static/...` | ⚠️ 子域名访问时可能找不到资源 → **统一用绝对路径** |
|
||||
| 前端 JS 中 `location.href = '/xxx'` | 浏览器会替换为当前域名下的绝对路径,安全 |
|
||||
| Service Worker | 缓存清单使用绝对路径(已配置),绑定域名后仍正常工作 |
|
||||
|
||||
---
|
||||
|
||||
## 13. 相关链接
|
||||
|
||||
- 开发文档:[haonav_dev_guide.md](haonav_dev_guide.md)
|
||||
- 框架插件机制:[../插件开发指南.md](../插件开发指南.md)
|
||||
- 部署指南:`docs/deploy/`
|
||||
Reference in new issue
Block a user