Commit Graph

10 Commits

Author SHA1 Message Date
Blizzard 4c9fbc4a88 fix(fe+be): 我的页去重宠物墙 + 养宠天数按到家日算
- 养宠天数原来按建档日算,重新建档会被重置成 1(和首页「第869天」矛盾);
  改成按最早那只的到家日算(无到家日退建档日),和首页口径一致
- 「我的」页 profile-head 传 hideWall,藏掉社交宠物墙(下面「我的毛孩子」
  卡更详细,重复了);宠物墙只在别人访问/预览时出现,受「展示我的毛孩子」
  开关控制,语义更对(那开关本来就是给别人看的)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 15:11:59 +08:00
Blizzard 603bd5773e feat: 用户可见自己帖子的审核状态
- 发帖后若未直接过审,弹窗明确「审核中,通过后才出现在社区」,
  不再让用户以为发失败/是 bug
- 后端 ListUserPosts:看自己主页时返回待审核/未通过的帖子(带状态),
  看别人仍只返回已发布
- 个人主页帖子加「审核中/未通过」状态标 + 说明
- 我的页加「我的帖子」入口,进自己主页看审核状态

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 08:49:20 +08:00
Blizzard e2ce56680a fix(fe): 修切换条头像撑大 chip;我的页菜单只留设置
- pet-switch 头像 flex:none 锁死 52rpx,真机上图片固有尺寸不再撑大 chip
- 我的毛孩子去掉「+添加」(首页切换条可加)
- 菜单区只留「设置」,档案/计划/多宠都从首页和宠物卡进

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:20:02 +08:00
Blizzard 11c4d490e6 feat(fe): 宠物照片替代默认头像,身份卡移到首页门面卡
- 首页/我的/切换条:上传过照片就用照片,没有才退回 emoji
- 报告页分享海报:先异步加载头像再开画,画成圆形头像
- 一起生活的天数改成从到家日期算,没填就显示「-」并可点去补
- 身份卡入口从「我的」页移到首页门面卡右上角

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:08:32 +08:00
Blizzard cbfcaada55 feat: 宠物身份卡(canvas 绘制 + 小程序码 + 存相册/分享)
竞品那张「居民身份卡」,完整做了。

## 后端
service/wxacode.go —— 小程序码。两步:先拿 access_token(2h 有效,进程内缓存、
提前 5 分钟过期),再调 getwxacodeunlimit 换一张 PNG 存到 MinIO 返回 URL。
同一只宠物的码 object 名按 pet id 定死,存在就直接返回不重新生成 ——
微信侧有日调用配额,不能每次点都烧一次。

⚠️ getwxacodeunlimit 要求 page 在**已发布**的小程序版本里。开发/未发布时返回
errcode 41030,实测确认。这时身份卡照常出、只是没码(qr_ready=false),
发布后自动就有,不用改代码。best-effort,取不到不算错。

service/idcard.go —— 组装卡片内容。身份 ID 用「宠物雪花 id 的数字 + 生日」
拼成 18 位、每 4 位空一下,纯装饰不入库不校验,同一只每次都一样。
介绍按物种给默认(汪星人/喵星人来地球啦~)。有效期用生日起算。

GET /api/pets/:id/id-card
storage 加了 Exists(StatObject),生成前先查。

## 前端 pages/idcard
离屏 canvas 2d 画卡,导出成图展示 + 存相册 + 分享(open-type=share,
imageUrl 用画好的卡当封面)。

两张远程图(头像 + 小程序码)都用 node.createImage() 异步加载,
**Promise.all 等两张都就绪再开画** —— 否则小程序码会画不上或画一半
(规划里专门点过名的坑)。任一张加载失败 resolve(null),缺图也照画:
头像缺→画物种 emoji,码缺→画「小程序码 待发布」占位框。

存相册的权限被拒过一次后 wx.authorize 不再弹,走 openSetting 引导(同海报那套)。

绘制复用了 bottom-sheet 里 poster 的 canvas 模式(dpr 放大、roundRect、
canvasToTempFilePath),但 poster 只画文字不画远程图,这里的双图加载是新写的。

入口:「我的」→ 身份卡,用当前选中的宠物。

## 验证(预生产库实跑)
  id-card 接口返回:姓名/性别/品种/生日/介绍/身份ID/有效期 全对
  身份 ID = 3410 4333 1420 2503 17(宠物id数字+生日,稳定)
  qr_ready = false,日志确认 41030 invalid page(小程序未发布,预期)
  canvas 版式用 HTML 复刻确认过:未发布=占位、发布后=真码

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 16:48:16 +08:00
Blizzard 048408b0e9 fix(fe): 报告页/我的 底部被 tabBar 遮住
no-fab 的底部留白是 60rpx,那是给二级页(无 tabBar)用的。报告页和「我的」
是 tab 页,底下有原生 tabBar(高 108rpx),60rpx 让不开,最后一张卡/入口
被 tabBar 压住 —— 报告页的「全部记录」就点不到。

加 --pad-b-tab(150rpx + 安全区)和 .tab-nofab 类,报告页和我的改用它。
no-fab(60rpx)留给真正的二级页(record/plan/expense/history/settings…)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 16:05:14 +08:00
Blizzard aefb1bc103 feat: 建档改成三步向导页,品种改成后台可配的选择器
## pages/petform 三步向导
  ① 名字 + 传头像
  ② 猫还是狗 → 选品种
  ③ 性别 / 生日 / 到家日期 / 体重 / 毛色 / 阶段

**编辑时不分步**,一屏全放开:用户是来改某一项的,不该被按顺序走一遍。
同一个页面两种形态,靠 ?id= 区分。

每一步只校验这一步的东西。三步全填完才校验的话,用户在第三步才被告知
第一步没填名字,还得翻回去。

进度条没用 seg-tabs:那是「可以随意切」的语义,这里有顺序,
点第三步跳过前两步会拿到一份没名字的档案。

## 生日和到家日期分开
原来是一个「生日 / 到家时间」字段。领养的成年猫狗生日常常是不知道的,
而「一起生活了多少天」要按到家日算——合成一个字段两件事都说不准。
验过:到家 4 个月前 → 第 121 天;按生日算会是 801 天。

模型里 Birthday 和 ArrivedAt 本来就是两个字段,只是表单没露出来。

## 品种:自由文本 → 后台可配的选择器
原来品种是个输入框,用户手打「柯基」「柯基犬」「威尔士柯基」算三个品种,
以后想按品种做体重基准、常见病提示这类事就没法做。

新增 breeds 表,预置 34 种猫 + 45 种狗,按首字母分组、右侧 A-Z 索引跳转、
首字母吸顶。留了「不确定」——领养的串串确实说不出品种,逼着选一个只会
得到假数据。换物种会清掉已选品种(原来那个一定不对了)。

**首字母存字段不运行时算**:Go 没有标准拼音库,而多音字自动转常出错——
「藏獒」按 cang 还是 zang 分组、「柴犬」的柴,人来定比库来猜靠谱。
后台新增品种时手填这一位,服务端校验必须是单个 A-Z。

已有档案在用的品种不许删(删了那些档案的品种就变成查不到的字符串),
想隐藏用 enabled=false。同物种下不许重名——品种是统计口径,重名会把
同一种猫劈成两半。

预置数据自己填错了两条,实跑时看出来的:「苏格兰柯利犬」我按「柯利」
填了 K,应该按「苏格兰」算 S;「双血统边牧」根本不是品种,是血统描述。
seed 源和库里都改了。

## 弹层继续瘦
addPet/editPet 两支删掉,连带 10 个方法、ageFromBirthday/GENDERS/STAGES
和 5 个 add* 字段。累计(从记录表单搬走那次算起):
  js   1110 → 734 行
  wxml  485 → 307 行

多宠管理里「点某只去编辑」原来是 setType('editPet'),那支没了会开一个
空白弹层——改成关弹层再跳页。8 个页面的入口全换完,grep 无残留。

## 验证(预生产库实跑)
  品种接口   猫 34 种 16 个首字母、狗 45 种 17 个首字母;非法 species 返回 []
  建档      生日 / 到家日期 分别落库,品种毛色阶段都对
  编辑      只改名字,到家日期没被冲掉
  修正      柯利犬 K→S、双血统边牧已删

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 11:26:51 +08:00
Blizzard 7636454650 feat: 下掉用户端 AI,首页悬浮键改成快速记录
## 只砍入口,后端一行不动
10 个 AI 路由、service/ai_*.go、后台配额配置页、ai_usages / ai_messages
两张表全部保留。api.js 里那 5 个方法注释掉而不是删——想开回来解注释、
把入口接上就行,不用重写。

## 5 处露出
  pages/ai 聊天页        删页面 + 从 app.json 移除
  首页「AI 今日建议」卡    整张删(含「问问 AI 养宠助手」按钮)
  计划页「AI 计划」tab    删 tab + wxml 分支 + ?tab 深链;只剩「路线图」一项后
                        整条 seg-tabs 也藏了——单选的 tab 条是个没用的控件
  异常观察的 AI 风险评估   见下
  引导页「AI 日历」文案    改成「养护日历」

## 异常观察这一处差点做错
原链路是:symptom 只收集表单 → AI 风险评估 → 用户在 risk 页再点保存 →
buildRecord 的 case 'risk' 才真正落库。**symptom 自己从来不落库。**
拆掉中间环节如果只删 risk,结果就是「记了异常但没存下来」,而且不报错。

补了 case 'symptom' 让它自己存。连带发现第二个问题:category 存的是 AI 给的
风险等级,而 report.go:46 按 category='高' 统计周报的高风险数——不写这个字段
周报会永远是 0。改成让用户自己选严重程度(轻微/需留意/严重 → 低/中/高):
谁看着它谁最清楚,比规则化猜一个准,还顺手保住了周报。

## FAB
  首页    → 打开 24 项分组选择器(弹层新增 quickRecord 分支,
            点某一项在同一个弹层内 setType 切过去,不关不跳)
  社区    → 改成发帖(它本来就不该是记录入口)
  记录/报告/我的/计划/学习  → 直接去掉,底部留白从 pad-b-fab 换成 pad-b-plain,
            不然白留 330rpx

fab 组件原来图标写死成 ai,加了 icon 属性——按钮干什么事图标就得是什么。
顺手删了 settings.js 里一个死的 onFab(Phase A 拆页时漏的,页面上根本没有 fab)。

.tg 分组样式从 record.wxss 提到 app.wxss:记录页和快速记录弹层都在用,
页面级 wxss 跨不了页(这个项目已经栽过三次)。

## 顺手修了周报两个先前就有的 bug
验证时撞上的,和 AI 无关,但 AI 建议卡拆掉后周报权重变高了:

1. 摘要把「无高风险异常记录」写死,和它自己刚算出来的 highRisk 自相矛盾——
   记了 2 条高风险,摘要还说没有
2. next_week_focus 是一整句静态文案「第 2 针疫苗提醒、继续观察体重趋势、
   避免频繁更换食物」,不管谁的宠物多大年纪都是这句,而「第 2 针疫苗」
   对成年猫狗根本不适用。改成按真实数据拼:未来 7 天到期的提醒 +
   有高风险就提就医 + 一周没称体重就提醒补记

## 验证(预生产库实跑)
  异常观察三档   低/中/高 各存一条,category 正确落库
  周报          summary「有 2 条高风险异常记录」,不再自相矛盾
  next_week_focus  有高风险的宠物 → 「继续观察上周记录的异常,必要时就医」
                   新建幼犬(提醒都在 7 天外、没称过体重)→ 「本周还没称体重,补记一次」
  症状聚类洞察    仍然工作(insight.go 按 symptom 过滤,没受影响)
  全站 grep     无 pages/ai / onFab / riskData / onGenRisk 残留
  FAB           只剩首页(plus)和社区(edit)两处

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 09:50:33 +08:00
Blizzard 1584aabcc5 feat(fe): Phase D —— 主页装扮,「我的」和「宠友主页」共用一套渲染
## profile-head 组件
头图 / 头像 / 昵称 / 签名 / 帖子关注粉丝 / 养宠数据 / 宠物名片墙,
pages/mine 和 pages/user 用的是同一个组件、同一个接口
(GET /users/:id/profile)。

这件事必须一开始就做对:自己看和别人看要是两套渲染,会慢慢长歪,
装扮功能也就失去意义了——你调半天颜色,结果只有自己那页变了。
两边唯一的差别是底部按钮:自己看是「装扮我的主页」,别人看是「关注 TA」。

顺带把 mine 的头部从 /user/summary 切到了 /users/:id/profile。原来两边
字段对不上,装扮效果在「我的」页根本预览不到。

主题只在组件 wxss 里定义 --pf-a/--pf-b/--pf-ink 三个变量,下面所有着色
都走变量。后端存 key 不存色值,就是为了这套配色随时能在前端改。

## pages/decorate 装扮页
头图上传 / 五套主题色 / 个性签名 60 字 / 宠物墙开关,顶部实时预览。

预览用的就是 profile-head 本身,不是仿一个——仿的迟早会和真的长得不一样。
喂给它一份改过的 card 就行,组件那边不需要知道自己在被预览。

头图有个坑单独处理了:bg_file_id 只在真动过的时候才传。新上传带新 id,
点「恢复默认渐变」带空串,都没动就不传字段。否则「只改个主题色」会把
已有头图冲掉。上传时先用本地临时路径顶上,不让用户对着转圈等。

联调验证(本地 9090,真上传了一张图走完存储链路):
  上传             → file id + MinIO url
  保存装扮          → bg_url 落库,主题 violet,签名落库
  主页读回          → bio/theme/show_pets/bg_url/宠物墙/养宠数据 全对
  只改主题          → theme 变 sky,头图还在(没被冲掉)
  恢复默认渐变       → bg_url 清空,theme 和 bio 都没被动
  别人视角          → is_self=false、followed=false,装扮和宠物墙都能看到

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 18:02:07 +08:00
Blizzard 60baff8a2b refactor(fe): Phase A —— tab 换成「我的」,计划降级,设置拆出来
## tab 结构
首页 / 记录 / 报告 / 社区 / 我的。计划从 tab 移出变二级页(导航栏补了
返回键),从「我的 → 养护计划」进。

## 消灭 5 处硬编码
tabBar 高亮原来靠每个 tab 页在 onShow 里写死 selected: 0/1/2/3/4,
调一次顺序就得同时改五个文件,漏一个就高亮错位——这次把计划换成我的
正好会踩到。改成 tabBar 组件在 pageLifetimes.show 里按当前 route 自己
匹配,五处硬编码全删。

## profile 拆成两页
原来的 profile 混了两类东西:「我是谁」和「怎么设置」。拆开:

pages/mine(tab)  个人名片(头像/昵称/签名/关注粉丝记录三个数)
                   + 我的毛孩子列表 + 常用入口 + 齿轮进设置
pages/settings     提醒设置、会员权益、数据导出、意见反馈、关于我们

「我的」上放了个「看看别人眼里的我」,点进去就是 pages/user 那个公开
主页——自己看和别人看必须是同一个页面同一套渲染,否则两边会慢慢长歪。
这也是 Phase D 装扮功能的落点。

首页齿轮从「进 profile」改成「进设置」(个人页已经在 tab 上了)。
旧的 pages/profile 整个删掉,没留兼容层。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 17:33:32 +08:00