7.4 KiB
7.4 KiB
用户端 App 头像与视觉纠偏
操作时间:2026-09-07。 操作类型:扩展及缺陷修复。 影响模块:用户端个人中心、个人资料、登录品牌、商城图片、头像上传及资料更新。
核对结论
用户指出的问题成立。此前没有图 41 的个人资料页和头像上传入口,多个一级入口只是未开放提示;布局、品牌图标、宣传图片和商品图片也没有达到 1:1。此前“已实现”的口径过宽,现按实际业务能力记录,不能将构建成功或截图生成视为验收。
| 设计范围 | 实际能力 | 仍未完成的设计功能 |
|---|---|---|
| 01 登录 | 密码/验证码接口、密码显隐、发送冷却、忘记密码、会话、真实协议读取;品牌改为原稿像素 | 真实短信渠道及协议同版本同状态验收;表单尺寸仍有差异 |
| 03 首页 | 真实服务归属和已发布内容、导航及维修申请入口 | 设备遥测、扫码绑定、蓝牙、分组、阀门控制及各安全详情 |
| 11 商城 | 公开商品、后台分类、搜索、价格库存、单品确认下单;宣传图复用原稿 | 购物车、收藏、完整商品详情和多商品结算;远程多条商品未配置图像,不能冒用参考样例 |
| 20 订单 | 气瓶/商城/工单列表、退款记录、服务端允许的支付/退款操作 | 设计中的完整详情、配送轨迹、发票和售后闭环 |
| 25 个人中心 | 钱包、资料/头像编辑、订单、合同、地址新增、维修和退出 | 设置、消息、押金、优惠券、家庭共享、紧急联系人、用气统计、收藏、发票、客服/关于独立页;地址管理目前仍只是新增弹窗 |
| 41 个人资料 | 选图、预览、上传、昵称保存、错误重试、取消草稿、返回刷新、真实服务归属和默认地址 | 手机换绑、性别、生日、实名认证状态及证件脱敏字段;不能用图中演示认证冒充用户事实 |
代码与行为变化
apps/user_app/lib/ui/features/profile/profile_edit_page.dart:新增资料页、_chooseAvatar、_save、_leave。支持相机/相册;2MB、JPG/PNG 检查;保存失败保留草稿,重试复用已上传 URI;退出确认。apps/user_app/lib/app/router.dart:新增受登录守卫保护的/profile/edit。apps/user_app/lib/ui/features/profile/profile_page.dart:头像资料行可点击;保存返回后刷新服务端头像;分组标题、行顺序、分隔线和图标调整。apps/user_app/lib/ui/features/profile/profile_avatar.dart:头像增加可配置尺寸,保留加载错误回退。apps/user_app/lib/data/services/api_client.dart:增加鉴权 multipart 上传,统一处理会话失效和后端错误。apps/user_app/lib/data/repositories/client_repository.dart:新增上传/保存资料;同 API 域名的图片绝对路径可正确解析。昵称保存省略头像时不覆盖旧图。backend/api/internal/logic/upload/avatar.go:头像写入登录客户端和账户摘要对应的目录;OwnsAvatar拒绝跨账户、跨客户端、伪造及穿越路径。旧 URI 仍可读取。backend/api/internal/logic/client/user/auth.go:资料更新保留省略的头像;新头像只能引用本人受控上传文件;纯空白昵称被拒绝。旧头像原值和显式清空兼容。apps/user_app/lib/ui/core/reference_image.dart、assets/design/:保留用户提供的两张原 PNG,只在品牌和宣传位显示指定图像区域。未用整张截图替代页面;表单、价格、账户和交互均为真实 Flutter 组件。- 新增
image_picker及平台实现依赖;iOS 加入相机/相册用途说明。数据库模型和 API 路由未变,无迁移。
验证证据
关键代码定位:profile_edit_page.dart 新增 399 行,选图 _chooseAvatar 第 64 行、保存 _save 第 136 行;profile_page.dart 的 _editProfile 第 44 行;api_client.dart 的上传方法第 148 行(新增 13 行);avatar.go 的 OwnsAvatar 第 109 行(新增 28 行、替换 1 行);auth.go 的 UpdateProfile 第 148 行。行数是当前快照,后续格式化后以符号名定位。
资料更新请求仅提交实际编辑内容:
await widget.repository.updateProfile(_name.text, avatar: _uploadedUri);
- Flutter 全量 50 项测试通过。新增测试覆盖 multipart 鉴权、过期、超限、相对图片路径、头像选取取消、保存失败重试、昵称校验及草稿退出。
- Go 全量测试、vet、构建通过。资料 SQL Mock 验证省略头像不覆盖旧值、跨账户拒绝、旧 URI 保留和空昵称拒绝。
- 平台契约检查 48 个资源通过。
- 六页、四种宽度(320/360/390/430)、两种字体缩放(1.0/1.3)共 48 项截图及溢出检查通过;已打开实际截图与原稿查看,严格视觉验收仍不通过。
- 浏览器实测发现 Web 构建缓存中的插件注册文件未更新,首次选图失败。已定位到生成文件缺少
ImagePickerPlugin.registerWith,通过失效对应的web_entrypoint.stamp重新生成,不手改生成源码。 - 修复缓存后,浏览器系统文件选择器实际选入测试 PNG;预览变更,点击保存后返回个人中心并显示新图。再次调用真实 API 确认资料 URI 属于 owners 目录、受保护图片 GET 返回 HTTP 200、88 字节。随后恢复测试账户原昵称与头像,未留下演示头像替代用户资料。
- 共享组件 3 项、工作人员 App 21 项回归通过;用户端蓝色描边按钮、10dp 圆角和无胶囊选中背景的底栏样式仅对 consumer 品牌调整。列表触控高度保留 48dp,部分设计图等比缩放后的行距低于这个尺寸,因此不能以压缩点击区域换取截图一致。
- 远程数据库与 Redis 沿用既有 dev 配置。本次没有启动本地数据库,没有执行迁移、种子或清库。
- 最终 Web Release 构建通过、用户端 analyze 无问题。Android 构建未通过:在线解析 Kotlin
kotlin-build-tools-compat:2.3.20出现 Maven TLS 握手失败,正常 HTTPS 补下载也失败;离线构建确认androidx.profileinstaller:profileinstaller:1.3.1、androidx.core:core-ktx:1.13.1等依赖未缓存。没有降低 TLS 校验,不能宣称 APK 或原生相机验收通过。NDK 28.2、Build-Tools 36、CMake 3.22.1 已由标准 SDK 构建流程安装;未改数据库环境。
风险与维护
- 所有尚未开放项继续保留可见入口,按照用户此前决定展示明确未开放提示;不计为已完成。
- 原图的固定宣传内容作为随包静态素材;真实商品图片仍由后台提供,不根据名称猜测图片、不覆盖远程商品记录。
- 实测远程 10 条商品中,9 条没有图片 URI,另 1 条
/mock/products/lpg-15kg.png返回 HTTP 404;前端路径解析修复不能补造不存在的后台文件。 - 上传成功但资料保存失败会保留文件以便重试;文件清理需要后续按引用关系和保留期实现,不能直接删历史资源。
- 增加插件后需要确认 Web 生成注册文件包含插件,避免仅凭 Flutter 构建返回成功判定功能有效。
- 个人资料页下拉刷新时,若存在草稿、正在选图或正在保存,保留当前草稿,防止昵称或选图被旧服务端值覆盖;保存失败重试测试同时覆盖该行为。
- 原头像可读兼容;出于权限修复,新 URI 不再允许任意跨账户引用。