编制:小齐 日期:2026-09-23 状态:已验部分均附可复跑命令;方案部分待刘总拍板
触发:刘总三问——①为什么有硬编码?所有内容要求 A 端可配置 ②写出报告 ③走全局令牌
| # | 结论 | 性质 |
|---|---|---|
| 1 | 硬编码不是谁写错的,是 v2 工程以"静态原型快照"身份入仓时自带的——2026-09-14 8d7dc69e(冈子首入仓快照)就已包含这些金额与电话 | 已验(git 追溯) |
| 2 | 真正的根因是"前端没有数据层":玩法页、我的页的 .ts 零接口请求,页面内容全部写死在模板里;A 端已有内容配置能力,但 C 端从未消费 | 已验(grep 计数) |
| 3 | 全站硬编码金额 47 处(不是此前报告的 5 处),另有 mock-pkg-1/2 的 mock 数组仍躺在 home.ts | 已验(全量 grep) |
| 4 | 间距令牌早已存在(--space-1~--space-6),问题是档位只有 6 档、覆盖不足,四页各写下 11–16 个越界值 | 已验(脚本比对) |
| 5 | 因此"走全局令牌"的正确做法不是新建令牌,而是补齐档位 + 强制消费 + 加校验闸门 | 方案 |
| 6 | 🔴 铁律(刘总 2026-09-23 02:56 二次强调,非可选项、不需再讨论):所有业务数据一律 A 端配置,C 端禁止写死任何业务数据——金额、电话、营业时间、文案、图片、状态、排序、入口清单全部走配置;页面只负责渲染配置值,取不到就显示中性占位「—」或直接隐藏该字段,绝不允许写死兜底数字。数据由运营在 A 端录入与更新,不需要刘总提供、不需要研发在代码里填 | 🔴 铁律 |
⚠️ 自纠:本报告初稿把"A 端可配置"列进了「待刘总拍板」,并询问"真实数据由谁提供"——这是把铁律降级成了选项,理解错误。已按铁律改写:它不是待办项,是执行前提;需要刘总决定的只剩"派谁做后端接口",不是"要不要做"。
git log -S '¥80–160' --oneline -- miniprogram-v2/pages/selection/selection.wxml
git log -S '08978888216' --oneline -- miniprogram-v2/pages/local/local.wxml
git log -S '¥680–980' --oneline -- miniprogram-v2/pages/local/local.wxml
三条全部指向同一个提交:8d7dc69e(2026-09-14,署名冈子)——「首入仓快照:新版 C 端工程完整入库,pages×92 + components/services/styles/utils,2.9M/406 文件」。
也就是说:这些金额、电话、文案从进仓库的第一天起就写死在页面模板里,不是某次改动引入的缺陷。v2 工程当时是把可运行的前端原型整包搬进来,原型里的数据就是写死的。
for p in selection local profile home; do
printf "%-10s 接口请求命中=%s\n" $p \
$(grep -acE "request\(|/api/|wx\.request" pages/$p/$p.ts); done
实测结果:
| 页面 | 接口请求命中数 | 含义 |
|---|---|---|
| 玩法 selection | 0 | 纯静态,内容全写死在 wxml |
| 在地 local | 1 | 仅一处 |
| 我的 profile | 0 | 纯静态入口清单 |
| 首页 home | 5 | 已接真实数据(本轮整改后) |
玩法页和我的页从未接过后端的任何数据。所以即便 A 端配置了内容,这两个页面也读不到——它们压根不发请求。
admin-console/src/pages/ContentAssets.tsx(894 行,波波 2026-09-23 02:27 推送,提交 ef893f49)/api/miniapp/admin/content/*,覆盖 POI / 路线 / 攻略知识 / 规则 四类backend/app/routers/admin_content.pyC 端现有的读取口只有两个(backend/app/routers/feed_demand.py):
/api/miniapp/content/private/api/miniapp/content/guide即:A 端能配 POI/路线/攻略/规则,但 C 端没有通用的"读取已配置内容"接口,前端页面也没消费它。 配置与展示之间是断的。
此前的验收口径查的是:视觉规范、路由白名单、文案键覆盖、数据真假(禁 mock)。从来没有人查过"这个数字是不是写在代码里的"。所以硬编码一直合规地活着。
grep -raoE "¥[0-9]+" --include="*.wxml" --include="*.ts" . | wc -l
| 文件 | 处数 | 说明 |
|---|---|---|
pages/joint-payment/joint-payment.wxml | 13 | 合单支付 |
utils/texts.ts | 11 | 文案库里也写着金额 |
pages/coupons/coupons.wxml | 6 | 优惠券 |
pages/selection/selection.wxml | 4 | 玩法页四张卡 |
pages/order-refund-preview/*.wxml | 4 | 退款预览 |
pages/hotel-booking/hotel-booking.wxml | 4 | 酒店预订 |
pages/home/home.ts | 2 | mock 数组,见下 |
pages/guide-detail/guide-detail.wxml | 2 | 向导详情 |
pages/local/local.wxml | 1 | 在地页服务卡 |
pages/home/home.ts 第 25、27 行:
{ slug: 'mock-pkg-1', ..., priceText: '¥3680 起/人', ... }
{ slug: 'mock-pkg-2', ..., priceText: '¥1980 起/人', ... }
变量直白命名为 mock-pkg-*。上一轮整改我删掉了首页的推荐区块 UI,但数据和请求逻辑仍在(孤儿代码)。这属于我自己留下的尾巴,本次一并报出。
grep -raoE "tel:[0-9]+" --include="*.wxml" .
| 位置 | 号码 | 判断 |
|---|---|---|
pages/emergency-contacts | 110 / 120 | 合理,公共紧急号码,不是业务数据 |
pages/local/local.wxml | 0897…216 / 0897…308 | 🔴 疑占位假号,全仓仅此一处,且是商户联系电话 |
页面里出现的任何"会变的业务内容"——金额、联系方式、营业时间、服务项目、推荐语、状态文案——都必须能在 A 端改,改完即时生效,不需要改代码、不需要重新提审。
不变的部分(页面结构、图标、交互逻辑)继续写在代码里。
| 能力 | 状态 | 缺口 |
|---|---|---|
A 端内容管理界面 ContentAssets.tsx | ✅ 已有(波波 02:27) | 攻略知识字段未定、返回空数组 |
A 端接口 /api/miniapp/admin/content/* | ✅ 实测可用 | 只覆盖 POI/路线/攻略/规则四类 |
后端 admin_content.py | ✅ 已有 | — |
| C 端读取接口 | ❌ 缺 | 只有 private/guide 两个 feed,无通用内容接口 |
| 前端消费 | ❌ 缺 | selection/profile 零请求 |
| 金额/联系方式的配置模型 | ❌ 缺 | 现有四类内容里没有"价格""电话"字段 |
在现有 admin_content 上扩一个通用内容项表 content_item:
| 字段 | 说明 |
|---|---|
key | 内容键,如 selection.card.lake.price |
type | text / money / phone / image / status |
value | 值 |
source | 数据来源(谁提供的) |
updated_at | 更新时间 |
status | active / draft / expired |
destination_id | 目的地(多租户隔离,沿用现有口径) |
前端规则:
phone 类型必须 status=active 才渲染为可拨打,否则显示为不可点的文本GET /api/miniapp/content/items?keys=...(批量取,减少弱网请求次数——高原场景重要)home.ts 的 mock-pkg-*前端不等待数据:取不到配置值就显示中性占位「—」或隐藏该字段。页面短期出现占位是正确表现而不是缺陷——真实数据由运营在 A 端补齐即可,不需要改代码、不需要重新提审。这正是"A 端可配置"要达到的效果。
app.wxss:29 已定义:
--space-1: 8rpx; --space-2: 16rpx; --space-3: 24rpx;
--space-4: 32rpx; --space-5: 40rpx; --space-6: 48rpx;
只有 6 档。 而四页实际使用的间距值:
| 页面 | 用到的不同数值 | 落在令牌内 | 越界值个数 | 越界值举例 |
|---|---|---|---|---|
| home | 16 | 5 | 11 | 4,6,10,12,14,18,20,22,26,28,36 |
| selection | 19 | 5 | 14 | 4,6,12,14,18,20,22,28,34,44,56,68,100,200 |
| local | 22 | 6 | 16 | 2,4,6,10,12,14,18,20,22,26,30,44,52,56,100,200 |
| profile | 20 | 4 | 16 | 2,4,6,10,14,18,20,22,26,28,36,44,56,60,100,200 |
所以根因不是"页面乱写",是"令牌只有 6 档、不够用"——4rpx、6rpx、12rpx、20rpx 这些小档位根本没有令牌,页面只能硬写数字。
第一步 · 补齐档位(在 app.wxss 扩充,不动 vi-tokens 的色彩体系):
--space-0: 4rpx; /* 极紧凑:标签内距、图标间隙 */
--space-1: 8rpx;
--space-2: 12rpx;
--space-3: 16rpx;
--space-4: 20rpx;
--space-5: 24rpx;
--space-6: 32rpx;
--space-7: 40rpx;
--space-8: 48rpx;
--space-9: 56rpx;
另设两个语义令牌承接超大值(不要散在页面里):
--space-hero: 100rpx; /* 首屏大留白 */
--space-shell: 200rpx; /* 页面级容器 */
第二步 · 强制消费:四页 wxss 中 margin/padding 数值全部替换为 var(--space-*);100/200 这类归入语义令牌。
第三步 · 加校验闸门(防止回潮):新增脚本,扫出所有"写了具体 rpx 数字却没走令牌"的 margin/padding,越界即报错退出。
可复跑判据(改造完成后应全部成立):
# 期望:四页越界值均为 0
python3 - <<'PY'
import re
tok={4,8,12,16,20,24,32,40,48,56,100,200}
for p in ['home','selection','local','profile']:
w=open(f'miniprogram-v2/pages/{p}/{p}.wxss',encoding='utf-8').read()
out=sorted({int(v) for v in re.findall(r'(?:margin|padding)(?:-[a-z]+)?:\s*(?:var\(--[^)]*\)|([0-9]+)rpx)',w) if v})
print(p,"越界:",[v for v in out if v not in tok])
PY
注:该判据脚本当前尚未落地,属方案;落地后需随闸门一起入库。
| 批次 | 范围 | 可量化判据 | 归属 |
|---|---|---|---|
| 第一批 · 合规底线 | 47 处金额 + 2 处占位电话 + home.ts 的 mock;状态字段补"来源+更新时间" | 金额 100% 有来源;无真实数据显示中性占位;未核验电话不得渲染为可拨打;grep -c "mock-pkg" = 0 | 前端(我)+ 需刘总提供真实数据 |
| 第二批 · 全局令牌 + 跨页一致 | 间距令牌补齐并强制消费;统一加载/空态/失败/过期四态与 Toast 语义 | 四页越界间距值 = 0;四页状态文案一致(可 grep 校验) | 前端(我) |
| 第三批 · 信息架构 | 我的页 32 入口分组;需求广场唯一主入口;玩法↔在地的服务主次关系 | 32 入口 100% 分组且命名统一;需求广场入口数 = 1 | 前端(我),需先出方案 |
gpt6 明确建议不动的:首页的荒野感视觉、在地页的信任感表达、我的页的工具型布局——页面风格可以不统一,但字号、触控尺寸、色彩语义、间距令牌必须统一。
注:原第 2 项「A 端录入真实价格」已删除——按铁律,数据由运营在 A 端录入,不属待办。
| # | 事项 | 说明 |
|---|---|---|
| 1 | 🔴 派单给后端(波波):补 C 端通用内容读取接口 + 配置模型扩「金额 / 电话 / 时间」字段与类型 | 这是前端改造的前置依赖,属后端域,超出 v2 前端属主范围,需刘总派单。前端侧我可先做「空态兜底 + 清除硬编码」,接口到位后接线 |
| 2 | 六大盲区(SOS 误触防护 / 弱网离线 / 隐私生命周期)是否纳入本轮? | 涉后端与权限,同样需派给后端 |
| 3 | 间距令牌扩充到 10 档 + 2 语义档是否照此执行? | 影响全站 wxss,属全局改动;刘总点头后我立即开工(不依赖后端) |
不依赖任何人、我可立即开工的:清 home.ts 的 mock → 全局间距令牌改造 → 三页硬编码改走配置占位(接口未到位前先渲染空态)。
已验(均有可复跑命令,见正文):
8d7dc69e;全站金额 47 处分布;电话 4 处;home.ts 存在 mock-pkg-*ContentAssets.tsx + /api/miniapp/admin/content/* 存在;C 端通用内容读取口缺失未验(属方案,尚未落地):
content_item 的字段设计(未与后端确认)content/items 的可行性(未与后端确认)