vr-shopxo-plugin/docs/city-diy-implementation-pla...

136 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 城市DIY模板 — VR Plugin 端实施计划
> 创建日期2026-06-10
> 基于审查文档:[city-diy-plan-review.md](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/docs/city-diy-plan-review.md)
> 目标零核心文件改动通过插件钩子实现「用户坐标→城市→DIY模板」动态路由
---
## 架构概述
```
UniApp 发送 user_lng, user_lat → /api.php?s=index/index
app/api/controller/Index::Index() ← 无需修改
DiyService::AppClientHomeDiyData() ← 无需修改
钩子: plugins_service_diy_app_client_home_diy_data ← 🔑 新增
DiyHomeCityRouter::handle()
├─ input('user_lng'), input('user_lat') → 直接读请求参数
├─ GeoCityService::FindNearestCityId() → 城市ID
├─ Db::name('Diy')->where(['name'=>"home_{city_id}",'is_enable'=>1])->value('id')
└─ 通过引用 &$diy_id 设置模板ID未找到则回退默认
```
---
## 实施步骤
### 步骤1注册钩子 — 修改 [config.json](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/config.json)
**文件**`shopxo/app/plugins/vr_ticket/config.json`
**操作**:在 `hook` 对象中新增一条记录
**当前状态**hooks 末尾):
```json
"plugins_view_admin_goods_content_inside_bottom": [
"app\\plugins\\vr_ticket\\hook\\AdminGoodsIndex"
]
```
**修改后**(在末尾追加逗号+新钩子):
```json
"plugins_view_admin_goods_content_inside_bottom": [
"app\\plugins\\vr_ticket\\hook\\AdminGoodsIndex"
],
"plugins_service_diy_app_client_home_diy_data": [
"app\\plugins\\vr_ticket\\hook\\DiyHomeCityRouter"
]
```
> [!NOTE]
> 钩子名 `plugins_service_diy_app_client_home_diy_data` 来自 [DiyService.php:48](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/service/DiyService.php#L48)
---
### 步骤2新建钩子处理类 — 创建 [DiyHomeCityRouter.php](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/hook/DiyHomeCityRouter.php)
**文件**`shopxo/app/plugins/vr_ticket/hook/DiyHomeCityRouter.php`(新建)
**命名空间**`app\plugins\vr_ticket\hook`
**类名**`DiyHomeCityRouter`
**参考实现**[Hook.php OnGoodsListBegin](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/Hook.php#L400-L436) — 已有相同的「坐标→城市ID」逻辑
**关键设计点**
1. `is_backend` 检查:仅前端请求生效(`is_backend === true` 时才处理,与 DiyService 传来的参数一致)
2. `input('user_lat')` / `input('user_lng')`:直接从 ThinkPHP 请求参数读取,无需依赖 `$params['params']`
3. `GeoCityService::FindNearestCityId()`:复用已有的最近城市查找方法
4. `&$diy_id`:通过引用修改,无需返回值
5. 兜底策略:找不到城市场景模板时 `diy_id` 保持原值,`DiyService` 会走 `AppClientHomeDiyId()` 的默认逻辑
**模板命名约定**
- `home_110100` → 北京市
- `home_310100` → 上海市
- `home_440100` → 广州市
- `home_default` → 默认模板(兜底,由 DiyService 自动匹配)
---
### 步骤3验证测试
**3a. 后端验证**
直接用浏览器访问 API 端点,模拟带坐标的 UniApp 请求:
```
http://localhost:10000/api.php?s=index/index&user_lng=118.110652&user_lat=24.585
```
**预期行为**
- 无坐标:返回默认 DIY 模板(与现有行为一致,向下兼容)
- 有坐标且城市存在对应模板:返回该城市的 DIY 配置
- 有坐标但城市无对应模板:回退到默认模板
**验证方法**
1. 先在后台创建一个测试用 DIY 模板,`name` 设为 `home_{测试城市ID}`
2. 用该城市的坐标访问 API检查返回的 JSON 是否为该模板的配置
3. 用一个不存在模板的城市坐标访问,确认回退到默认模板
**3b. GitNexus 变更检测**
在提交前运行:
```bash
npx gitnexus detect-changes
```
验证改动只影响预期的符号和执行流。
---
## 文件变更清单
| 文件 | 操作 | 行数变化 |
|------|------|----------|
| [config.json](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/config.json) | 修改 | +4 行 |
| [DiyHomeCityRouter.php](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/hook/DiyHomeCityRouter.php) | 新建 | ~35 行 |
| **核心文件** | **无修改** | **0 行** |
---
## 风险评估
| 风险 | 等级 | 缓解措施 |
|------|------|----------|
| 无坐标时走默认逻辑 | 🟢 无风险 | 向下兼容,行为不变 |
| GeoCityService 性能 | 🟢 低 | 已有内存+文件双层缓存1小时过期 |
| 钩子未注册 | 🟢 低 | config.json 改动量极小,可快速验证 |
| 模板命名冲突 | 🟡 中 | 使用 `home_{city_id}` 前缀约定,后台创建时需遵守 |
| 核心升级冲突 | 🟢 无 | 零核心文件修改 |
---
> [!TIP]
> 实施顺序步骤1 → 步骤2 → 步骤3共约 40 行代码改动。任何中断都可以从此文档恢复。