|
|
|
@ -1442,6 +1442,146 @@ modalCard: { backgroundColor: colors.white, borderRadius: 16, padding: 20 }, |
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
### 4.18 边距间隔统一 8px:页面留白 / 卡片内边距 / 卡片间隔(2026-09-20 批次,接 4.17) |
|
|
|
|
|
|
|
#### 1. 目标值在本批次中途被改过一次(16 → 8),这是本节的起点 |
|
|
|
|
|
|
|
`AGENTS.md` 第 15 行原为「…无阴影,**边距间隔一致**」,未给数值。三个维度上 16 都是众数 |
|
|
|
(卡片内边距 66/169、卡片间隔 30/92、页面留白 27/71),**「取众数 16」是一个站得住但错的猜测**。 |
|
|
|
我按 16 落了 176 处之后,用户把该行改成「…边距间隔一致,**为8px**。」——目标值变成 8。 |
|
|
|
|
|
|
|
**不能靠回滚实现**:回滚只能把「被我改过的值」还原成原值,而原来就是 16 的那 66 张卡 |
|
|
|
同样必须降到 8,还原不回 8。故改为**按目标值重算**,并把全部原始值落盘(脚本的中间产物 |
|
|
|
`spacing8-edits.json`,**不入库**,需要逆向核对时由本机临时文件提供)。事后看,这次踩坑的根因不是判断失误,而是 |
|
|
|
**在规则未定量时就开工**——规则定量前本应先问,这一点记在这里。 |
|
|
|
|
|
|
|
#### 2. 判定口径(本节定义,后续沿用) |
|
|
|
|
|
|
|
用户确认「边距间隔一致,为8px」**包含页面左右留白**(即「卡片离屏幕边缘的距离」), |
|
|
|
故三个维度统一为 8: |
|
|
|
|
|
|
|
| 维度 | 载体 | 现状 | |
|
|
|
|---|---|---| |
|
|
|
| 页面留白 | 主 ScrollView 的 `contentContainerStyle` 上的 `padding` / `paddingHorizontal`,或靠卡片自身 `marginHorizontal` 撑出的留白 | **全部 8** | |
|
|
|
| 卡片内边距 | 卡片样式块上的 `padding` / `paddingHorizontal` / `paddingVertical` | **全部 8** | |
|
|
|
| 卡片间隔 | 卡片的 `marginTop` / `marginBottom`,以及**分隔卡片的容器 `gap`** | **全部 8** | |
|
|
|
|
|
|
|
判定「是不是卡片」改为**结构判定**而非命名判定:`有 borderRadius` 且(`有 backgroundColor` |
|
|
|
或 `有 borderWidth`)。4.17 用的是命名判定(`card` / `*Card`),**有漏网**(见第 3 条)。 |
|
|
|
|
|
|
|
#### 3. 命名判定漏掉了什么(本批补齐) |
|
|
|
|
|
|
|
`app/(enterprise)/enterprise-chat.tsx` 的 `pendingItem`(radius 10)、`app/holland.tsx` 的 |
|
|
|
`dimItem`(radius 12)、`app/resume/{education,experience,project}.tsx` 的 `row`(radius 14)、 |
|
|
|
`app/interview-score.tsx` 与 `app/candidate-detail.tsx` 的 `suggestionRow`(radius 12)、 |
|
|
|
`app/appeal.tsx` 的 `reasonRow`(radius 10)、`app/game/level.tsx` 的 `explanation`(radius 6)、 |
|
|
|
`app/holland/question.tsx` 与 `app/game/level.tsx` 的 `option`(radius 12/6)、 |
|
|
|
`app/tools/salary-calculator.tsx` 的 `taxItem`(radius 10)——**这些名字里都没有 "Card", |
|
|
|
但结构上就是卡片**,4.17 整批漏过。本批一并归 8。 |
|
|
|
|
|
|
|
另有一批 **radius 本就是 8、但内边距/外边距不是 8** 的卡同样漏过: |
|
|
|
`matchBanner`/`offerBanner`(`(tabs)/chat.tsx`,padding 16)、`salaryBox`(`candidate-detail.tsx` 14、 |
|
|
|
`interview-score.tsx` 16)、`cardBase`/`cardOffer`/`banner`(`chat/[id].tsx` 12/12/10)、 |
|
|
|
`replyBlock`(`job-evaluations.tsx` 10)、`rank.section`(16)、`memberBanner`(`legal.tsx` 与 |
|
|
|
`legal/upgrade.tsx` 各一处)、`draftBanner`(`interview-score.tsx`)、`pathSummary`(`skill-cloud.tsx` 14)、 |
|
|
|
`aiTip`(`resume.tsx`)、`qualifications` 的 `imagePlaceholder` / `licenseImage` / |
|
|
|
`checkout.channelRow` / `levelDesc` / `matchBox`。 |
|
|
|
|
|
|
|
#### 4. 改动规模(`git diff --numstat` 实测,非估计) |
|
|
|
|
|
|
|
`73 个 .tsx 文件 + AGENTS.md`,`+390 / -398`。按属性计新增行中的 `= 8`: |
|
|
|
`padding` 209、`marginBottom` 74、`paddingHorizontal` 37、`marginTop` 18、`paddingVertical` 17、 |
|
|
|
`borderRadius` 15、`gap` 8、`marginHorizontal` 5、`margin` 1;另有 1 处属性行被删除 |
|
|
|
(`offer-compare` 的 `offerList.paddingHorizontal: 4` —— 外层 `content` 已是 8,内层再加 4 |
|
|
|
会让首张 Offer 卡离屏 12,归零后与全站一致)。 |
|
|
|
|
|
|
|
#### 5. 明确排除的类别(附理由,不是遗漏) |
|
|
|
|
|
|
|
| 排除项 | 理由 | |
|
|
|
|---|---| |
|
|
|
| 表单控件 `input` / `textarea` / `inputBox` / `inputWrap` / `uploadBox` / `checkbox` / `knob` / `sliderFill` | 圆角与内边距随控件形态走,不是卡片 | |
|
|
|
| 标签 / 胶囊 / 选项卡 `chip` / `tag` / `tab` / `categoryTab` / `filterItem` / `emptyTabItem` | 半径由胶囊高度决定(半高即全圆),压到 8 会变成方角 | |
|
|
|
| 按钮 `btn` / `modalSubmit` / `saveCancel` / `saveConfirm` / `sheetCancel` / `modalConfirm` | 同上 | |
|
|
|
| 图标底 / 装饰 `iconWrap` / `logoBox` / `progress` / `counter` / `sectionBar` / `barTrack` / `barFill` | 纯装饰 | |
|
|
|
| 错误重试态的 `center` 容器(`flex:1` + `paddingHorizontal:40` + `retryBtn`) | 它长得像卡片列表容器,实为居中错误态。全仓同名同形,**误改会把重试页的居中打散** | |
|
|
|
| `components/onboarding/**` | 引导页自成一套圆角体系(12/14/18),见第 6 条 | |
|
|
|
|
|
|
|
#### 6. 刻意不动的三处(范围边界) |
|
|
|
|
|
|
|
- **`app/resume/preview.tsx` 的 `paper.padding: 20`**:它是导出文档的**屏幕代理版心**, |
|
|
|
对应 `src/utils/resumeHtml.ts:208` 的 `@page` 页边距 `34px 38px`。压到 8 会让「预览」 |
|
|
|
和它存在的唯一目的(预览导出效果)脱钩。**保留**。 |
|
|
|
- **`components/onboarding/ui/SliderCaptcha.tsx` 的 `knob` 阴影**:滑块手柄是控件不是卡片, |
|
|
|
4.17 起就作为对照项保留,状态不变。 |
|
|
|
- **`components/onboarding/ui/ScreenShell.tsx` 的 `scrollContent.padding: 20`(+ `P1Login` 的 24)**: |
|
|
|
这是 **26 个引导页**共用的页壳,20 → 8 等于重排整个首启流程。**未改**,列为待定夺(见第 10 条)。 |
|
|
|
|
|
|
|
#### 7. 两个脚本自身的缺陷(各浪费了一轮,如实记录) |
|
|
|
|
|
|
|
- **heredoc 吞掉一层反斜杠**:`<<EOF`(未加引号)把 `'^\\s*'` 写成 `'^\s*'`, |
|
|
|
生成的 `new RegExp` 永不匹配,所有读数静默为空。**判定方法**:`sed -n '/^const get/,/^};/p' … | cat -A`。 |
|
|
|
改用 Write 工具落盘后解决。 |
|
|
|
- **简写正则时丢了捕获组**:把 `^(\s{2})(name)\s*:\s*\{` 简写成 `^ (name)\s*:\s*\{` 后 |
|
|
|
`h[2]` 取到 `undefined`,脚本报「找不到样式键」。**教训**:捕获组下标改动必须同步改取值。 |
|
|
|
|
|
|
|
两次都是**脚本报错或读数全空**暴露的,没有静默写坏文件——断言(每条改动核对旧值,不符即抛)起到了作用。 |
|
|
|
|
|
|
|
#### 8. 顺带修掉的一个既有缺陷(不在本批规则内,验证时发现) |
|
|
|
|
|
|
|
`app/tools/skill-cloud.tsx` 的行业 Tab 在**搜索框出现后被纵向裁切**:文字被切掉一半, |
|
|
|
只剩 6 个可点却看不见的胶囊(截图 43 为修复后)。根因是 |
|
|
|
`tabsWrap: { maxHeight: 52 }` 未设 `flexShrink: 0`,父容器变矮时这条横向 ScrollView |
|
|
|
被压到内容高度以下。已加 `flexGrow: 0, flexShrink: 0`。 |
|
|
|
`git diff` 确认 `tabsWrap` 不在本批改动内 —— **确系既有缺陷**,且属「有入口但看不见」, |
|
|
|
与既有的不留假交互原则冲突,故一并修。 |
|
|
|
|
|
|
|
#### 9. 真机实测(Android 模拟器 `emulator-5554`,截图核对,非代码走查) |
|
|
|
|
|
|
|
| 页面 | 看什么 | 结果 | |
|
|
|
|---|---|---| |
|
|
|
| `(tabs)/growth` | 页面留白、`toolsRow` gap、工具卡 | 8 ✓ 不挤 | |
|
|
|
| `jobs/rank` | 页面留白(16→8)、卡片堆叠间隔 | 8 ✓ | |
|
|
|
| `holland/question` | `option` radius 12→8、内边距 18/16→8 | 8 ✓ 文案未被压 | |
|
|
|
| `jobs/compare` | 三列并排卡 `jobRow` gap 10→8 | 8 ✓ 三列完整 | |
|
|
|
| `resume/education` | `row` radius 14→8、`paddingLeft` 16→8 | 8 ✓ | |
|
|
|
| `tools/salary-calculator` | 页面留白、`taxItem` 10/12→8 | 8 ✓ | |
|
|
|
| `appeal` | 页面留白、`reasonRow` 10→8 | 8 ✓ | |
|
|
|
| `tools/skill-cloud` | 页面留白 16→8、空态盒 `paddingVertical 32→8` | 8 ✓ 空态紧凑但不挤;行业 Tab 裁切已修 | |
|
|
|
| `legal` | 页面留白、`serviceGrid` gap | 8 ✓ | |
|
|
|
| `holland` | `dimGrid` gap、`dimItem` 12→8 | 8 ✓ 3×2 网格正常 | |
|
|
|
| 企业端 `我的` / 岗位管理 / 沟通 | 侧栏切企业端后:留白、`statsGrid` gap、`pendingItem` 10→8 | 8 ✓ | |
|
|
|
|
|
|
|
**未实测**:`resume/export` 的格式卡与模板卡三列、`personal-data-export` 的 `formatRow`、 |
|
|
|
`legal/templates` 的 `templateGrid`、`assessment` 的 `entries`、`interview-score` 的 |
|
|
|
`draftBanner`/`salaryBox`/`suggestionRow`、以及**空数据下**的 `ability`/`progress`/`legal` 空态盒 |
|
|
|
(本机数据非空,触发不到)。 |
|
|
|
|
|
|
|
`resume/education` 里出现的「Ñ」经查是**引导页 P20 手输的学校名**(`src/api/api.ts:3087` |
|
|
|
取 `profile.school`),这台模拟器上早前测试敲进去的**设备本地数据**,非代码缺陷。 |
|
|
|
|
|
|
|
#### 10. 本批次门槛复跑(2026-09-20 实测) |
|
|
|
|
|
|
|
`npx tsc --noEmit` 0 错误 · `npx eslint .` 0 命中 · `npm test` 26 套件 / 365 用例全过 · |
|
|
|
`check:icons` 无无效字形 · `check:affordances` 无假交互 · `check-backend-stubs` 140 个接口均预留 · |
|
|
|
`check-routes` 正常。 |
|
|
|
|
|
|
|
#### 11. 本批次仍未做 / 待定夺 |
|
|
|
|
|
|
|
- **【待定夺】`ScreenShell.padding: 20 → 8` 是否执行**:影响 26 个引导页的首启视觉。 |
|
|
|
规则说「整个项目」,且用户已确认「页面留白也统一 8px」;但引导页是独立设计流程, |
|
|
|
半径体系已按同一逻辑排除。**改动只有一行,等一句话。** |
|
|
|
- **【待定夺】卡片半径口径是否继续收紧**:结构判定下全仓仍有约 260 个 |
|
|
|
「有 borderRadius + 有背景/描边」的块不是 8,逐个核过后确认**绝大多数是控件/标签/按钮/图标底** |
|
|
|
(`retryBtn` / `avatar` / `tabIndicator` / `progressTrack` / `badge` / `sectionBar` …), |
|
|
|
已按第 5 条排除。**剩余无争议项已清零,未发现新的漏网卡片。** |
|
|
|
- 4.16 第七节 A–E 五条重复声明发现、4.16 第 5/6 条两项产品定夺、4.15 起的其余开放项 |
|
|
|
**状态全部不变**(详见 4.17 第 10 条)。 |
|
|
|
- **仍未建立设计令牌层**:8px 与各间距值目前仍是**裸字面量**,没有单一来源、没有 lint 强制。 |
|
|
|
这是「改一次值要动 73 个文件」的根因,也是本批次规模这么大的原因。**建议下一批做** |
|
|
|
(`src/theme` 目前只有 `colors.ts`)。 |
|
|
|
|
|
|
|
--- |
|
|
|
|
|
|
|
## 五、后续增量开发建议(优先级) |
|
|
|
|
|
|
|
- **P0(上架前必做)**:~~图标替换~~ **应用图标【已完成,`878710c`,1024×1024「有职」logo】** · ~~隐私 / 协议内容填充~~ **隐私/协议草案【已存在,含 18 岁门槛,待填【待确认】占位】** · ~~EAS 初始化~~ **EAS 配置骨架【已完成,`owner` / `projectId` 两处占位符阻塞 `eas build`,需 `eas init` 注入,详见 4.5】** · ~~18 岁门槛核对~~ **18 岁门槛【已在隐私政策第六章 + 用户协议前言落地】** · ~~微信登录接入评估~~ **微信登录接入评估【已完成 → 见 `微信登录接入方案.md`,SDK 接入阻塞于微信开放平台 AppID】** · ~~启动屏接线~~ **启动屏【已完成,`expo-splash-screen` + `splash-icon.png`,需出包验证】**。 |
|
|
|
|