# UI 问题修改计划 > 来源:设计验收问题记录(UI-001 ~ UI-0014),共 14 项,全部状态:待修改 > 设计稿基准:宽度 390px,换算到小程序 750rpx --- ## 一、尺寸换算规则(px → rpx) 换算公式:`1px = 750 / 390 rpx ≈ 1.923rpx` | 设计稿 px | 换算 rpx | 取值建议 | | --- | --- | --- | | 2px | 3.85rpx | 4rpx | | 4px | 7.69rpx | 8rpx | | 10px(10号字) | 19.23rpx | 19rpx | | 16px(16号字) | 30.77rpx | 31rpx | > 所有从设计稿(设计规格说明.md / Figma)量取的 px 值,一律按上表换算为 rpx 再写入代码。 --- ## 二、远程资源路径规范 ### 2.1 资源存放约定 - 本地 `切图/切图/` 文件夹整体改名为 `miniprogram` 后上传至服务器,线上路径前缀为:`/assets/miniprogram/` - 资源域名复用 API 域名:`https://official.inkreach.cc`(即 api/request.js 中小程序端 BASE_URL 的域名) - 代码中**不要写死完整 URL**,统一通过 `buildUrl()` 拼接: ```js import { buildUrl } from '@/api/request.js' const ASSET_BASE = '/assets/miniprogram/' // 示例 buildUrl(ASSET_BASE + 'logo.png') // → https://official.inkreach.cc/assets/miniprogram/logo.png(三端一致) ``` > 说明:buildUrl 对 `assets/` 开头的路径直接用域名根目录拼接(不拼 v2-api),接口仍走 `https://official.inkreach.cc/v2-api/`。 ### 2.2 资源映射表(原图 → 线上路径) | 原图(切图/切图/) | 线上路径(/assets/miniprogram/,保留切图原始中文文件名) | 对应问题 | | --- | --- | --- | | logo.png(单张完整logo,含中英文) | logo.png | UI-001 | | 首页主视觉全球图.png | 首页主视觉全球图.png | UI-003 | | 4步开始/01步骤-选择产品.png | 4步开始/01步骤-选择产品.png | UI-004 | | 4步开始/02步骤-上传设计.png | 4步开始/02步骤-上传设计.png | UI-004 | | 4步开始/03步骤-在线销售.png | 4步开始/03步骤-在线销售.png | UI-004 | | 4步开始/04步骤-生产配送.png | 4步开始/04步骤-生产配送.png | UI-004 | | 用强大功能/全球配送.png | 用强大功能/全球配送.png | UI-005 | | 用强大功能/店铺集成.png | 用强大功能/店铺集成.png | UI-005 | | 用强大功能/自动化履约.png | 用强大功能/自动化履约.png | UI-005 | | 用强大功能/设计工具.png | 用强大功能/设计工具.png | UI-005 | | 公司简介背景.png | 公司简介背景.png | UI-007 | | PingFang SC/ 文件夹(7 个字重 ttf,见 2.3) | fonts/PingFang-Regular.subset.ttf 等(已生成,见 2.3) | 全局字体 | > 中文文件名由 buildUrl/uni.request 自动 URL 编码,三端均可正常访问;只有字体目录用英文名 `fonts/`。 > > Figma 导出的小图标(UI-009/0010)为本地静态资源,不上传服务器:`static/icons/products/icon_search.png`(48×48@3x)、`static/icons/products/icon_filter.png`(54×54@3x)。 ### 2.3 字体方案 #### 现有字体文件 服务器路径:`miniprogram/PingFang SC/`,共 7 个字重,**每个约 13.4MB**: | 文件 | 字重 | 是否选用 | | --- | --- | --- | | PingFang (Thin).ttf | 100 | 不用 | | PingFang (Ultralight).ttf | 200 | 不用 | | PingFang (Light).ttf | 300 | 不用 | | **PingFang (Regular).ttf** | **400** | **选用(主字体,正文/数字)** | | **PingFang (Medium).ttf** | **500** | **选用(可选,标题/强调)** | | PingFang (Semibold).ttf | 600 | 备选(如 Medium 效果不够重再换) | | PingFang (Heavy/Bold 等).ttf | 700+ | 不用 | > 结论:**首选 Regular(400)**,它对应 font-weight: 400 的常规文本;如需标题更醒目可加 **Medium(500)**。其余字重不加载,避免浪费带宽。7 个文件全部上传也没关系,但代码里只引用选中的 1~2 个。 #### 关键问题:必须子集化,不能直接全量加载 - 每个 ttf 全量约 **13.4MB**,小程序加载一个字体包就要 13MB+,用户流量和加载时间都不可接受 - **处理方式**:用 [fontmin](https://github.com/ecomfe/fontmin) 或在线工具(如 font-spider、字节跳动的字体子集化工具)把 ttf 裁成子集: - 方案 A(推荐):只保留**数字 + 英文 + 常用符号**,子集后仅 **20~50KB**,用于价格、数据等数字/英文场景 - 方案 B:保留常用 3500 中文字 + 数字英文,约 1~2MB,可覆盖绝大部分中文(牺牲一些包体) #### ✅ 子集文件已生成(2026-08-31) 已在本项目根目录 `miniprogram-fonts/` 下生成 4 个文件(字符集 = 常用3500字 + ASCII + 中文标点 + 项目源码实际用字,共 3661 字符): | 文件 | 大小 | 用途 | | --- | --- | --- | | PingFang-Regular.subset.ttf | 724 KB | 主字体(正文/数字),**推荐直接用这个** | | PingFang-Regular.subset.woff2 | 382 KB | 同上,体积更小,loadFontFace 部分端支持不完善,备用 | | PingFang-Medium.subset.ttf | 722 KB | 标题/强调字体 | | PingFang-Medium.subset.woff2 | 387 KB | 同上备用 | **待办**:将 `miniprogram-fonts/` 下需要使用的文件复制到服务器 `miniprogram/fonts/`(即线上 `/assets/miniprogram/fonts/`),文件名保持不变。 - 子集化脚本已保留:`subset_fonts.py`(字符表 `chars_3500.txt`),后续文案变动可重新生成(需 `pip install --target ./pylibs fonttools brotli`,再 `PYTHONPATH=./pylibs python subset_fonts.py`) - 原始解压字体在 `切图/切图/PingFang SC/`,如不需要可直接删除 #### uni-app 加载方式 **方式一:`uni.loadFontFace`(推荐,全端通用)** 在**首页 [index.vue](pages/index/index.vue) 的 `onLoad`** 中全局加载(注意:不能放 App.vue 的 onLaunch,页面未创建会报 `loadFontFace:fail not font page`),小程序/H5/App 三端都支持: ```js // pages/index/index.vue onLoad(global: true 照样全局生效) uni.loadFontFace({ global: true, // 跨页面生效,必须加 family: 'PingFangSC', // 自定义字体名,避免和系统 PingFang SC 冲突 source: 'url("https://official.inkreach.cc/assets/miniprogram/fonts/PingFang-Regular.subset.ttf")', success: () => console.log('字体加载成功'), fail: err => console.warn('字体加载失败,回退系统字体', err) }); ``` 使用:CSS 里直接 `font-family: 'PingFangSC', -apple-system, 'PingFang SC', sans-serif;`(加载失败自动回退系统字体,无副作用) **方式二:app.css 里写 `@font-face`** - H5 端:完全支持,写在 [app.css](app.css) 即可 - 小程序端:基础库 2.10.0 起支持 wxss 中的网络字体 @font-face,但兼容性不如方式一稳定 ```css @font-face { font-family: 'PingFangSC'; src: url('https://official.inkreach.cc/assets/miniprogram/fonts/PingFang-Regular.subset.ttf') format('truetype'); font-weight: 400; } ``` > 注意:CSS 内无法调用 buildUrl(),必须写**完整远程 URL**。 **小程序端额外要求**: - 字体 URL 必须是 **https** - 字体所在域名 `official.inkreach.cc` 需加入小程序后台的 **downloadFile 合法域名**(与现有 API 域名相同,如已配置则无需重复添加) - 本地调试可在开发者工具勾选"不校验合法域名" #### 中文字体怎么办(结论:先不加载,按需再补) - **iOS 无需处理**:iOS 系统字体本身就是苹方(PingFang SC),中文不加载任何字体也和设计稿完全一致 - **Android 有轻微差异**:系统字体是 MiSans / HarmonyOS Sans,与苹方观感接近、细节略有不同,多数场景肉眼难辨 - 如需 Android 中文也统一,推荐做"**实际用字子集**": - 小程序静态中文文案基本固定,提取代码里全部中文去重(约 600~900 字)+ 数字英文,子集约 **300~500KB** - 动态数据(如后端商品名)出现子集外的字时,**缺字自动回退系统字体**,不会乱码,仅个别字字形不同,几乎看不出 - 若担心覆盖不足,改用"常用 3500 字"子集(1~2MB),覆盖 99% 动态文字 - 缺字回退由系统自动完成,CSS 字体栈里排好回退顺序即可,无需额外代码 #### 最终建议组合 1. 第一步:Regular + Medium 做**数字/英文子集**(方案 A)上线,零风险 2. 首页 index.vue `onLoad` 用 `uni.loadFontFace(global: true)` 加载(不能在 App.vue onLaunch 调,会报 not font page) 3. app.css 全局字体栈改为 `'PingFangSC', -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif`(数字英文走子集字体,中文自动回退系统 PingFang/苹方,iOS 与设计稿完全一致) 4. 第二步(可选):看安卓真机效果后,若要求中文统一,再做中文"实际用字子集"或常用 3500 字子集,**只需替换/新增字体文件并在 loadFontFace 里加一条,代码结构不变** --- ## 三、问题清单与修改方案 > **暂缓项(需参考 Figma 设计稿,链接如下,后续再改)**: > - UI-009(搜索图标+搜索按钮)、UI-0010(筛选遮挡) > https://www.figma.com/design/9JTxflMXhnfltaGbDmTgOm/inkreach?node-id=1962-143&m=dev > - UI-014(产品详情顶部导航,暂不改) > https://www.figma.com/design/9JTxflMXhnfltaGbDmTgOm/inkreach?node-id=1508-155&m=dev ### UI-001 首页第一屏 · logo 替换(P1) - 文件:[HeroBanner.vue](pages/index/components/HeroBanner.vue)(第 19-20 行) - 现状:两张图 `logo_en.svg` + `logo_cn.svg` - 方案:删除两张 svg,改用单张 logo 图:`buildUrl(ASSET_BASE + 'logo.png')`,按设计稿调整尺寸与分割线表现 ### UI-002 首页第一屏 · 数据列辅助文案字号(P2) - 文件:[HeroBanner.vue](pages/index/components/HeroBanner.vue)(数据列 label,文案见 [mock.js](pages/index/mock.js) 第 6 行"全球本土工厂") - 方案:辅助文案(label)字号调整为 10号 → **19rpx** ### UI-003 首页第一屏 · 全球地图主视觉模糊(P2) - 文件:[HeroBanner.vue](pages/index/components/HeroBanner.vue) - 方案:替换为切图高清原图 `首页主视觉全球图.png`(线上路径见 2.2) ### UI-004 首页 · 4步开始你的按需定制生意 · 配图模糊(P3) - 文件:[StepsFlow.vue](pages/index/components/StepsFlow.vue),当前用 `static/images/home/step_0x_*.jpg` - 方案:四张步骤图全部替换为切图原图(4步开始/01~04步骤-*.png),路径走 buildUrl ### UI-005 首页 · 用强大的功能开启盈利快车道 · 配图模糊(P3) - 文件:[PlatformFeatures.vue](pages/index/components/PlatformFeatures.vue),当前用 `static/images/home/feat_*.jpg` - 方案:四张功能图全部替换为切图原图(用强大功能/*.png),路径走 buildUrl ### UI-006 首页 · 为什么选择 Inkreach · 文案与间距(P1) - 文件:[WhyChoose.vue](pages/index/components/WhyChoose.vue) - 方案: 1. 标题英文统一为 `Inkreach`(大小写按此,不使用全大写) 2. 上下间距调整为与左右间距一致(按设计稿量取 px 后换算 rpx) ### UI-007 首页 · 公司简介 · 添加背景图(P1) - 文件:[CompanyIntro.vue](pages/index/components/CompanyIntro.vue) - 方案:为该区块添加背景图 `公司简介背景.png`(线上路径见 2.2),铺满区块,内容层叠加在背景之上 ### UI-008 首页 · 联系方式 · 电话号码字号(P2) - 文件:[CompanyIntro.vue](pages/index/components/CompanyIntro.vue)(电话栏,约第 72-74 行) - 方案:电话号码字号调整为 16号 → **31rpx** ### UI-009 产品页 · 搜索栏 · 图标与搜索按钮(P1) - 文件:[SearchBar.vue](pages/products/components/SearchBar.vue) - 方案(按 Figma node-id=1962-143): 1. emoji 🔍 替换为设计稿导出的 `icon_search.png`(31rpx,Figma 3 倍图 48×48) 2. 搜索框右侧增加"搜索"按钮:96×54rpx、`#FF6800`、圆角 27rpx、白字 25rpx,距框边缘 4rpx,点击触发搜索 3. 搜索框 209×32px → 402×62rpx,`#F5F5F5` 圆角 31rpx;占位文案"搜索产品" `#929292` 25rpx;上下留白 6px→12rpx ### UI-0010 产品页 · 搜索栏 · 筛选被遮挡(P1) - 文件:[SearchBar.vue](pages/products/components/SearchBar.vue) / [products.vue](pages/products/products.vue) / [products.css](pages/products/products.css) - 被遮挡原因:筛选按钮原在搜索行右侧,小程序胶囊按钮恰好覆盖该区域 - 方案(按设计稿+实际确认):筛选入口与已选标签合并为**同一行**([ActiveFilters.vue](pages/products/components/ActiveFilters.vue) 重构):`[筛选图标 35rpx] [已选标签 scroll-x 横向滚动不换行] [清除(有标签才显示)]`;搜索行右侧留空避开胶囊;FilterDrawer 弹窗逻辑不变(入口 emit `open` → 父组件 `toggleFilter`) ### UI-0011 产品页 · 国家分类 · 间距(P3) - 文件:[CountryBar.vue](pages/products/components/CountryBar.vue) - 方案: 1. 标签内国旗与名称间距 = 4px → **8rpx** 2. 标签上下间距在现有基础上增加 2px → **4rpx** ### UI-0012 产品页 · 产品列表 · 大背景灰色值(P1) - 文件:[products.vue](pages/products/products.vue)/[products.css](pages/products/products.css)(页面容器背景),涉及 [ProductGrid.vue](pages/products/components/ProductGrid.vue) 第 132 行 `#f2f2f2` - 方案:页面大背景灰色统一调整为 **#ECECEC** ### UI-0013 标签栏 · 产品图标大小不一致(P1) - 文件:[pages.json](pages.json)(tabBar 配置,第 28-44 行),图标在 `static/icons/tabbar/` - 方案:检查 tab_product 选中/未选中两张图的画布尺寸是否一致;统一为同一尺寸(推荐与 home 图标一致,或按设计稿重出图)。注意 tabBar 图标必须是 png(小程序限制) ### UI-0014 产品详情 · 顶部导航缺失(P1) - 文件:[product-detail.vue](pages/product-detail/product-detail.vue)(该页已设 `navigationStyle: custom`) - 方案:在页面顶部(状态栏高度 padding 之下)增加自定义导航栏:左侧返回按钮(`uni.navigateBack`)+ 居中标题"产品详情" --- ## 四、建议实施顺序 1. **P1 先行**:UI-001、UI-006、UI-007、UI-009、UI-0010、UI-0012、UI-0013、UI-0014 2. **P2 次之**:UI-002、UI-003、UI-008 3. **P3 收尾**:UI-004、UI-005、UI-0011 **前置依赖**:切图文件夹改名 `miniprogram` 并上传服务器后,远程图片/字体路径才可访问;UI-009 的搜索按钮图标需设计补充切图。 **验证方式**:每项修改后在微信开发者工具 + H5 双端检查显示效果;图片类修改需确认线上 URL 可直接访问(浏览器打开 buildUrl 拼出的完整地址)。 --- ## 五、修改记录(2026-08-31 第一批) | 编号 | 状态 | 修改内容 | | --- | --- | --- | | UI-001 | ✅ 已改 | [HeroBanner.vue](pages/index/components/HeroBanner.vue):删除 logo_en.svg + logo_cn.svg 双图,改用单张远程 logo.png(buildUrl 拼接,320×60rpx aspectFit) | | UI-002 | ✅ 已改 | HeroBanner.vue `.stat-label` 字号 16rpx → 19rpx(10号) | | UI-003 | ✅ 已改 | HeroBanner.vue 主视觉图改用远程高清原图 首页主视觉全球图.png | | UI-004 | ✅ 已改 | [mock.js](pages/index/mock.js) stepList 四张图 → 远程 4步开始/01~04步骤-*.png 原图 | | UI-005 | ✅ 已改 | mock.js featureList 四张图 → 远程 用强大功能/*.png 原图 | | UI-006 | ✅ 已改 | [WhyChoose.vue](pages/index/components/WhyChoose.vue):标题"为什么选择Inkrecah?"→"为什么选择Inkreach?";卡片去掉 margin-bottom,上下间距统一用 gap 20rpx 与左右一致;区块上下留白对称(96rpx) | | UI-007 | ✅ 已改 | [CompanyIntro.vue](pages/index/components/CompanyIntro.vue) 背景图改用远程切图原图 公司简介背景.png;透明度最终按用户确认:**不设 opacity,原图直接展示**(Figma 标注 0.2 + backdrop blur,但实际观感过淡,用户要求原图) | | UI-008 | ✅ 已改 | CompanyIntro.vue `.phone-text` 字号 23rpx → 31rpx(16号) | | UI-009 | ✅ 已改 | [SearchBar.vue](pages/products/components/SearchBar.vue):emoji 🔍 → Figma 导出 icon_search.png(31rpx);新增橙色"搜索"按钮(96×54rpx `#FF6800` 圆角 27rpx,点击/键盘确认均触发搜索);搜索框 402×62rpx `#F5F5F5` 圆角 31rpx,占位"搜索产品" 25rpx `#929292` | | UI-0010 | ✅ 已改 | 筛选入口从搜索行(被胶囊遮挡)移至商品区顶部;[ActiveFilters.vue](pages/products/components/ActiveFilters.vue) 重构为一行布局:筛选图标 + 已选标签横向滚动(scroll-x 不换行)+ 清除按钮,FilterDrawer 逻辑不变 | | UI-0011 | ✅ 已改 | [CountryBar.vue](pages/products/components/CountryBar.vue):国旗与名称间距 20rpx → 8rpx(4px);标签上下 row-gap 16rpx → 20rpx(+2px) | | UI-0012 | ✅ 已改 | [products.css](pages/products/products.css) 页面背景 + [ProductGrid.vue](pages/products/components/ProductGrid.vue) 右侧内容区背景 → #ECECEC | | UI-0013 | ✅ 已改 | tab_product_gray/orange.png 由 57×57 放大至 72×72(Pillow LANCZOS),与 home 图标一致 | | UI-0014 | ⏸ 暂缓 | 按要求暂不修改(Figma node-id=1508-155) | | 全局字体 | ✅ 已改 | 首页 [index.vue](pages/index/index.vue) `onLoad` 用 `uni.loadFontFace(global: true)` 加载 `fonts/PingFang-Regular.subset.ttf`(family 自定义名 `PingFangSC`;App.vue onLaunch 调用会报 not font page,已移至页面);[app.css](app.css) 字体栈首位插入 `'PingFangSC'`,加载失败自动回退系统字体 | **注意事项**: - 远程图片依赖服务器 `/assets/miniprogram/` 下对应文件(保留切图原始中文文件名:logo.png、首页主视觉全球图.png、公司简介背景.png、4步开始/×4、用强大功能/×4),访问前确认已部署,文件名与映射表(2.2 节)一致 - 包体清理(2026-08-31):已删除 12 个无引用静态图(logo_en/cn.svg、step_01~04_*.jpg、feat_*.jpg、Rectangle_178_1426_1248.png、公司简介背景_1461_1606.png),共约 362KB;保留的静态图均有引用(tabbar、能力/优势图标、横幅小图、联系方式图、Figma 导出搜索/筛选图标)