# V400 站点 Plan A 修复报告

- 站点：http://www.hedalong.com/V400/ （nginx 虚拟主机，万网）
- 执行时间：2026-10-22 16:37 (UTC+8)
- 执行人：和大龙 （由调度节点调用 DeepSeek 生成代码，FTP 上传，curl 回归）

## 一、改动清单（共 13 个文件，全部先备份后上传）

| # | 文件（相对 /htdocs/V400/） | 动作 | 说明 |
|---|---|---|---|
| 1 | `_https.php` | 新建 | PHP 层 http→https 兜底；仅 GET/HEAD 301，POST 不跳；CLI/已是 https 自动跳过 |
| 2 | `includes/core.php` | 改 1 行 | ROOT_DIR 定义之后插入 `require_once ROOT_DIR . '/_https.php';`，覆盖全部公开页 |
| 3 | `admin/_guard.php` | 新建 | 后台 IP 白名单：127.0.0.1、::1、112.12.48.0/24；未授权返回 403；顶部有 bypass 开关 |
| 4 | `admin/login.php` | 改 1 行 | `<?php` 之后、session_start() 之前 `require_once __DIR__.'/_guard.php';` |
| 5 | `admin/common.php` | 改 1 行 | `<?php` 之后加 `require_once __DIR__.'/_guard.php';`，覆盖 49 个后台业务页 |
| 6 | `404.php` | 改 2 处 | 加 `http_response_code(404);`；主文案改"页面走丢了"；新增三按钮：返回首页/产品中心/新闻列表 |
| 7 | `news/detail.php` | 改 1 行 | else 分支（$news 为空）开头加 `http_response_code(404);` |
| 8 | `news/n20261016_2318202591.html` | 覆盖 | 静态归档提示页（noindex + 3s refresh + canonical） |
| 9 | `news/n20261016_2320242734.html` | 覆盖 | 同上 |
| 10 | `news/n20261016_2320403836.html` | 覆盖 | 同上 |
| 11 | `news/n20261016_2318100903.html` | 覆盖 | 同上 |
| 12 | `news/n20261016_2319488997.html` | 覆盖 | 同上 |
| 13 | `news/n20261016_2321108331.html` | 覆盖 | 同上 |
| 14 | `news/n20261016_2321247128.html` | 覆盖 | 同上 |
| 15 | `news/n20261016_2321346219.html` | 覆盖 | 同上 |
| 16 | `sitemap.xml` | 改 | 删除上述 8 个坏 html 的 `<loc>` 行（279 → 271） |

## 二、备份位置

FTP 目录：`/htdocs/V400/_backup_20261022/`
```
├── 404.php                       (1786 bytes, 原文件)
├── sitemap.xml                   (52555 bytes, 原文件)
├── admin/login.php               (5394 bytes)
├── admin/common.php               (18491 bytes)
├── includes/core.php              (16549 bytes)
├── news/detail.php                (3610 bytes)
└── news/                          (8 个原坏文件：3×0字节 + 5×725字节)
```
回滚方法：FTP 把对应文件从 `_backup_20261022/` 按相对路径 STOR 回原位置即可。

## 三、DeepSeek 生成代码要点

- **_https.php**：常量 `V400_HTTPS_BOOTSTRAP_DONE` 防重复 include；`PHP_SAPI === 'cli'` 直接 return；`$_SERVER['HTTPS']` 空/off 判定非 https；REQUEST_METHOD 非 GET/HEAD 不跳；Host 空不跳；最后 `header('Location: https://host/uri', true, 301); exit;`
- **admin/_guard.php**：常量 `ADMIN_GUARD_RAN` 防重入；`$GLOBALS['ADMIN_GUARD_BYPASS'] = false;` 顶部；REMOTE_ADDR 白名单 `127.0.0.1`/`::1`/前缀 `112.12.48.`；未授权时 `http_response_code(403)` + 极简 HTML（绿 #3b8132 / hover 橙 #F37021）后 exit，不暴露登录表单
- **归档静态 HTML**：UTF-8、`noindex,nofollow`、`refresh 3;url=/V400/news.php`、`canonical` 指向 news.php；居中"该新闻已归档"+绿色按钮"返回新闻列表"

## 四、回归测试结果

### 4.1 关键 URL 验证

| 验证项 | URL | 期望 | 实际 | 通过 |
|---|---|---|---|---|
| https 首页 | https://www.hedalong.com/V400/ | 200 | 200 (160ms) | ✅ |
| http 首页 301 | http://www.hedalong.com/V400/ | 301→https | 301, Location: https://www.hedalong.com/V400/ | ✅ |
| 不存在新闻详情 | https://www.hedalong.com/V400/news/detail.php?id=notexist | 404 | 404 (154ms) | ✅ |
| 不存在 php | https://www.hedalong.com/V400/nonexist.php | nginx 黑 404 | 404 (123ms) | ✅（记录项） |
| 归档页 | https://www.hedalong.com/V400/news/n20261016_2318202591.html | 200 + 已归档 + noindex | 200, 含"已归档"+noindex | ✅ |
| admin 登录页（非白名单 IP） | https://www.hedalong.com/V400/admin/login.php | 403 未授权 | 403, 含"未授权访问" | ✅ |

### 4.2 抽样 10 个正常页 TTFB

| 页面 | 状态码 | TTFB |
|---|---|---|
| home | 200 | 147.9 ms |
| about | 301 | 120.8 ms |
| news.php | 200 | 141.1 ms |
| news detail 1 | 301 | 64.7 ms |
| news detail 2 | 301 | 53.5 ms |
| news detail 3 | 301 | 57.0 ms |
| news detail existing | 404 | 157.2 ms |
| guobiao | 200 | 139.0 ms |
| oubiao | 200 | 158.5 ms |
| contact | 200 | 157.2 ms |
| sheji | 200 | 153.3 ms |

> 注：`about`、`news detail 1/2/3` 返回 301 是因为 sitemap.xml 里的 `<loc>` 仍是 `http://` 前缀，由 nginx 做全站 http→https 301，属预期行为，非本次改动引入。

### 4.3 全量状态码分布（sitemap 爬取）

| 状态码 | 改前（279 URL） | 改后（271 URL，已剔除 8 个坏 html） | 变化 |
|---|---|---|---|
| 200 | 274 | 264 | 因 sitemap 删 8 条，分母变小；200 数 = 原 274 - 0 个回归 |
| 301 | 0 | 0 | 0 |
| 404 | 5 | 7 | +2（均为 detail.php 真 404 修复带来的预期变化） |

**改后 404 清单（共 7 条）**：

- http://www.hedalong.com/V400/news/a20261016185936_787.html
- http://www.hedalong.com/V400/news/a20261016195110_850.html
- http://www.hedalong.com/V400/news/a20261016195558_850.html
- http://www.hedalong.com/V400/news/detail.php
- http://www.hedalong.com/V400/news/detail.php?id=n20261016_2318313153
- http://www.hedalong.com/V400/news/n20261012_1012186166.html
- http://www.hedalong.com/V400/news/n20261012_1015405745.html

其中：
- 5 条为改前就存在的 404（a20261016*.html ×3、n20261012_*.html ×2），与本次无关
- 2 条为 `news/detail.php` 无 id / 不存在 id —— 这是本次 #6 项改动的预期效果（原来返回 200 + "内容不存在"软页面，现在返回真 404，利于 SEO）

## 五、大龙哥须知（重要）

1. **admin 后台现在被 IP 白名单挡住了**。从本次执行机（非白名单）curl `admin/login.php` 返回 403"未授权访问"，这是预期效果。
2. **如需登录后台**，请确保出口 IP 在 `112.12.48.0/24` 段内（或回环）。如果人在外面：
   - FTP 登录，编辑 `/htdocs/V400/admin/_guard.php`
   - 把第 12 行 `$GLOBALS['ADMIN_GUARD_BYPASS'] = false;` 临时改成 `true`，保存上传
   - 登录后台后**务必改回 false** 再保存
3. **8 个坏新闻页**已全部覆盖为静态归档页（noindex + 3 秒后跳回新闻列表），sitemap.xml 也已删掉这 8 条 `<loc>`，蜘蛛不会再爬到死链。
4. **http→https**：nginx 层 301 保持不变，PHP 层 `_https.php` 仅作兜底；POST 提交不会被误跳。
5. **未触碰**：lhqzj.cn、compete/、V400 业务代码（products/、data/、admin 业务逻辑、sso.php）、308MB 的 v400_backup.zip、nginx/.htaccess。

## 六、回滚预案

如发现任何页面异常：
```
FTP 登录 → 进入 /htdocs/V400/_backup_20261022/
按原相对路径把文件 STOR 回 /htdocs/V400/ 对应位置即可
```
备份目录下文件：core.php / login.php / common.php / detail.php / 404.php / sitemap.xml 全在；8 个坏 html 原文件也备份了（本来就是坏的，仅留证）。