Files
platforms/docs/操作日志_用户端APP_头像与视觉纠偏_20260907.md
czl231 3ef33b531d 已完成用户APP首期功能开发
交付用户端首期页面、配套接口、后台资源及测试文档。用户APP构建、静态分析和三个管理后台构建通过;完整测试仍有2项失败,后端模型注释检查未通过,详见交付记录。
2026-09-13 00:57:32 +08:00

7.4 KiB
Raw Permalink Blame History

用户端 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.dartassets/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.goOwnsAvatar 第 109 行(新增 28 行、替换 1 行);auth.goUpdateProfile 第 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.1androidx.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 不再允许任意跨账户引用。