Blizzard
7a55ee0f2e
feat(community): 评论改为独立二级页面 + 评论内容安全审核 + 评论数按实发实时纠正
...
前端:
- 新增 pages/comments 独立评论页(列表 + 底部输入条 + 回复),社区卡片点评论改为 navigateTo
- 输入条用普通流式布局 + 原生 adjust-position 做键盘避让,聚焦期间不 setData 碰输入框
- 评论只能配 1 张图;底部常驻「审核后公开」提示;发送按钮在途「审核中…」防连点
- 发布结果按状态区分:过审即时展示,其余提示「已提交,审核通过后展示」
- 评论页把已发布评论数回传社区列表,卡片数字实时更新
后端:
- CreateComment 文本判为违规时直接拒收(ErrContentRejected),不入库
- 社区列表/用户帖子列表用「已发布评论实时条数」覆盖 comment_count,
修正异步过审/删待审/后台改状态导致的计数漂移
- IDCard 手机号返回完整号码(上一批遗留)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-08-03 16:04:21 +08:00
Blizzard
59412010dc
feat(fe+be): 身份卡加公章、修性别符号、电话显示全、照护卡标题两行
...
- 修正性别 ♂/♀:用名字字号量宽度再定位,不再怼到名字上(之前用小字号量偏了)
- 正反两张卡右上角各盖一枚「肉垫计划 · 官方认证」红色公章(双圈+五角星,微旋转半透明)
- 照护卡标题改成两行「X星地球移民 / 居民身份卡」(按猫狗取 喵/汪/宠)
- 正面「物ID」改为「ID」
- 后端 IDCard.Phone 返回完整手机号,不再脱敏
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 18:32:09 +08:00
Blizzard
586875f8c5
feat: 身份卡改上下两张卡(正面/背面) + 手机号硬门槛
...
- canvas 重画成上下两张:正面(暖黄,头像/名字性别/性别品种毛色年龄/性格
彩色标签/介绍/物ID+一起生活天数)、背面(蓝色照护信息条 + 主人/电话/疫苗/
备注/发证机构/有效期 + 走失联系框&小程序码)
- 生成前查手机号:没有则唤起 getPhoneNumber 组件,验证成功才生成;
拒绝则提示「无法生成」不出卡
- IDCard 增 age/days;ic-canvas 高度改 1480 否则导出被裁
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 17:48:39 +08:00
Blizzard
ef172f4e4a
feat: 宠物加性格/过敏/备注字段 + 身份卡照护信息 + 微信取手机号
...
- Pet 增 personality/allergy/notes;建档表单加「性格标签(多选)/过敏/备注」
- IDCard 增 color/personality/owner/phone(脱敏)/allergy/notes/疫苗驱虫状态/发证机构
- 微信取手机号:POST /api/user/phone 用 getPhoneNumber 的 code 换手机号存库
(BindPhoneByCode 走 getuserphonenumber,复用 access_token)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 17:12:56 +08:00
Blizzard
72c5308214
fix(be): 海报 pet_avatar_url 一直为空——ownedPet 不解析头像
...
GetPoster 用 ownedPet 只填了 Age,头像 URL 没解析,导致 pet_avatar_url
恒为空、海报总是退回 emoji。改成显式 s.fileURL(pet.AvatarFileID)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 16:08:23 +08:00
Blizzard
c890732410
feat: 成长报告海报改周报口径 + 显示统计周期
...
- 海报四项统计原来是全部累计,和「周报告」不符;改成近 7 天口径
(和报告页本周概览一致),高风险异常也按本周真实统计(原来写死 0)
- Poster 加 period 字段,海报上画出「近 7 天 · 07.25 - 07.31」
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 15:33:12 +08:00
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
4a1b5e66d3
fix: 成长报告海报用宠物真实头像(没传才用 emoji)
...
- 后端 Poster 增 pet_avatar_url(取 pet.AvatarURL,和身份卡同一可靠路径)
- 海报 canvas 优先用它、store 兜底;有照片画圆形头像、没有才 emoji
- 头像九参数居中裁剪,竖图/横图都不压扁
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 15:00:47 +08:00
Blizzard
2f2757267e
fix(be): 任务完成统计与留痕改用 PlanTask(DailyTask 已空)
...
- TogglePlanTask:完成无 sheet_type 的任务时补一条 note 记录,
首页/计划页两条路径都统一留痕(ToggleTask 委托它);去掉前端重复建记录
- 报告页「完成任务」原来统计空的 DailyTask 恒为 0,改成经 plan 关联
统计 PlanTask 本周完成数;用户汇总的 tasksDone 同改
- 首页今日完成度 todayCompletionPct 同样从 DailyTask 改成今日 PlanTask
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 14:29:04 +08:00
Blizzard
0f3efbc895
chore(be): 上传对象按月份分文件夹 uploads/YYYY-MM/
...
MD5 去重本来就有(相同内容直接返回已有记录不重传);对象名从
files/<md5> 改成 uploads/2026-07/<md5>,跨月的同内容仍走去重不重复占用。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 14:16:53 +08:00
Blizzard
a91f5e39ca
feat: 发帖去身份用昵称、标签对齐筛选、图片限2、无类型任务也留痕
...
- 发帖去掉「发布身份」选择,统一用发布者昵称(后端按 user 取昵称)
- 发帖标签改成 晒宠/新手求助/经验,和社区顶部筛选完全一致;
tabTag 新手求助→新手求助(原来映射成「求助」对不上)
- 内容输入框:点整块 field 都聚焦(原生 textarea 在 scroll-view 里
命中区域会偏,只有 placeholder 处能点)
- 发帖图片上限 3→2,文案标注「最多 2 张」
- 无记录类型的自定义任务完成后,补一条 note 记录,最近记录里留痕
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 14:12:52 +08:00
Blizzard
bb7db78763
feat(fe+be): 身份卡头像不再压扁 + 内容丰富
...
- 头像用九参数 drawImage 居中裁剪(cover),竖图/横图都不变形,加白边圈
- 后端 IDCard 增 zodiac(按生日算星座) + weight,卡面加「星座/体重」行
- 加淡淡的肉垫水印 + 旋转的「肉垫计划·官方认证」印章
- 画布加高容纳新增内容
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-31 11:50:04 +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
6bb327e62e
fix(be): 登记 wechat.msg_token 默认值,让 PETS_WECHAT_MSG_TOKEN 能覆盖
...
viper AutomaticEnv 只对已登记的 key 生效,纯 .env 部署下未登记的
key 绑不上,会静默取空值。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 19:04:38 +08:00
Blizzard
67b97e4b38
feat(be+admin): 后台看板扩展 + 社区内容安全审核
...
看板(Recharts):
- 概览页加 DAU/WAU/MAU、今日/本月新增 KPI,新增趋势/活跃趋势/月活/留存曲线
- GET /admin/analytics 内存计算,活跃口径=当天有记录/发帖/评论,排除 bot
内容安全(微信官方 UGC):
- 文本 msg_sec_check 同步判、图片 media_check_async 异步查
- 帖子/评论加 pending/rejected 审核态,feed 只放 published
- 图片结果回调 /api/wx/sec-callback,JSON/XML + 明文模式,签名校验
- 检测不了/未发布时一律转待审核,走后台手动审核
- 后台帖子/评论审核页:修好看不到图(补 attachPostImages)、
加状态筛选 + 通过/打回;新增评论审核状态接口
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 19:01:48 +08:00
Blizzard
de2b72221c
fix(be): 编辑档案补写到家日期/生日;关迁移期外键修复重复索引
...
- UpdatePet 的 fields map 之前漏了 birthday 和 arrived_at,
导致编辑档案改到家日期不落库(首页天数一直显示「-」)
- DisableForeignKeyConstraintWhenMigrating:外键列自动索引和字段
index tag 撞成同名索引,父子表同迁时报 1061,关掉库级外键约束创建
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 17:57:05 +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
cff6982613
chore(admin): 删掉停用的老方案,养护方案页按猫狗分 tab
...
## 停用的 8 套直接删了
上一个提交把老方案(按 3 段配的)改名停用没删,理由是「万一新内容有问题
还能翻回去看」。你要求删掉,删了。
走 service 的 DeleteTemplate 而不是直接删主表:明细要跟着一起清。
复查孤儿明细 0 条。剩 10 套(5 阶段 × 2 物种,各一套)。
已套用出去的计划节点不受影响 —— 套用时就展开成实体行、和模板断开了。
## 按猫狗分 tab
混在一起 10 套要上下找,而且阶段名两边一样(幼年期/青年期…),扫一眼分不清
哪套是猫的。tab 上带条数,「阶段」列不再重复物种。
顺带两处:
行按阶段顺序排 —— 数据库按 sort 排,但 sort 是全局的,分物种看时会跳号
新建时默认跟当前 tab 的物种,省一步点击
品种管理页本来就有猫狗 tab;记录事项页不分物种(记录类型猫狗共用)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 12:53:22 +08:00
Blizzard
c4c0c2b7cd
feat: 生命阶段按猫狗真实生理规律细分,划分标准和判定用同一份数据
...
## 你问的「养了半年会不会自动切换」
原来的答案是「都不会,而且比这更糟」:
age「2个月」 建档时算好存进库,养半年后首页还显示 2个月
stage「幼年期」同上,一年后还是幼年期
养护方案 按 stage 挑的,所以永远给幼猫那套
NormalizeStage 只在建档那一次调用(handler/pet.go:51),之后就是两个死字符串。
现在:
age 改成计算字段(gorm:"-"),读取时现算。它没有手改需求,存下来只会过期。
填在 ownedPet 这个收口里,不是逐个函数补——那样漏一个就返回空年龄。
stage 保留存储(有正当的手改需求:领养的猫生日是估的,主人按体型判断更准),
但加了漂移检测 GET /pets/:id/stage-drift。
**系统负责发现,用户负责决定。** 不自动改的三个理由:
1. 用户可能手改过
2. 已经排好的这个月计划不该被推翻(套用是「往里加」不是「替换」)
3. 偷偷换会让用户莫名发现计划变了,找不到原因
## 猫狗不能共用阈值 —— 这是这次最实质的发现
原来一刀切「<12月幼年,>=7岁老年」,对猫勉强,对狗两头都错:
吉娃娃 8 个月已性成熟、可换成犬粮;大丹犬 8 个月还在长骨头,
这时喂成犬粮(钙磷比和热量密度都不同)会加重关节负担。
吉娃娃 7 岁还在成年期(8 岁才进中年,能活 13-16 年);
大丹犬 7 岁已是老年(平均寿命 7-10 年)。
所以狗的阶段判定要看体型。体型不能靠当前体重(幼犬体重说明不了成年后多大),
只能靠品种 —— breeds 表加 size_class,45 个犬种逐个标了。
实测:同样 10 个月大 → 吉娃娃青年期、柴犬幼年期、金毛幼年期、大丹犬幼年期;
同样 7 岁 → 吉娃娃成年期、大丹犬老年期。
## 阶段 3 段 → 5 段
幼年期 / 青年期 / 成年期 / 中年期 / 老年期。
标签做成物种中立(不分幼猫期/幼犬期)——物种本来是另一个字段,
分开会让 (species,stage) 的组合和方案配置都翻倍。
「刚到家 0-30 天」不进这五段:它和年龄正交(刚接回家的成年猫两套都需要),
代码里本来就是叠加处理的。
猫按 AAFP/AAHA 猫生命阶段指南那套,在成年里细分出中年。
狗五段的阈值按体型走四组,越大的犬种生长期越长、老得越早。
## 划分标准和判定用同一张表
StageRules 那张表既驱动判定,也直接吐给前端当依据展示
(GET /api/life-stages?species=dog&size=giant)。
不是「代码里判定 + 文档里写标准」——后者一定会漂:改了阈值忘了改文档,
用户看到的说明和实际行为对不上,比没有说明更糟。
建档第三步的阶段选择器现在会显示「0-18 月 · 巨型犬生长期最长,18 个月还在长;
这阶段最忌过度补钙」,还会标出「巨型犬(成年 >40kg)——阶段阈值按体型算」。
前端和后台的 STAGES 硬编码列表都删了,改成读后端。
## 10 套方案,内容按各阶段真实重点配
不是把同一份换个名字:
幼年期 疫苗序列 + 驱虫 + 社会化,大型犬还要控制生长速度
青年期 绝育窗口 + 换成年粮
成年期 维持期,把基线数据记下来
中年期 年度血检开始有意义,体重和牙结石重点看
老年期 体检半年一次;猫记饮水量(多饮多尿是慢性肾病最典型的早期表现)、
狗记精神食欲,都设成「重要」
老的 8 套(按 3 段配的)改名停用不删:万一新内容有问题还能翻回去看;
而且已套用出去的计划早就和模板断开了,停用不影响任何用户。
## 验证(预生产库实跑)
体型判定 10 个月 / 7 岁两组对照,四个体型都落在预期阶段
age '13个月' 现算,不入库
漂移检测 手改成幼年期后 drifted=true,连带给出新阶段的依据和重点
划分标准 猫 5 段、狗 4 个体型各 5 段,老年起点 7/8/10/11 岁
全链路 3 个月大丹犬建档 → 幼年期 → 0 任务 + 4 条必要提醒 →
挑「幼犬标准照护」→ 套用下月 104 条节点,
周四那天正确出现每周项(检查爪垫和耳朵)
迁移 45 个犬种体型回填;现有 5 只宠物阶段重算后无变化(原本都对)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 12:51:10 +08:00
Blizzard
afdbf94450
feat(admin): 养护方案页重写 —— 多套、重复规则、"弹层"改成真实的记录事项
...
## 你问的那个「弹层」是什么
sheet_type = 用户在小程序点这条计划时,直接跳到哪个记录表单。
「体重记录」这条关联 weight,点了就是体重表单,不用自己去记录页找。
叫「弹层」是因为那时候记录表单是底部弹出的浮层。三件事让这个名字烂掉了:
1. 记录表单上一批已经搬成 pages/addrecord 独立页面了
2. 可选值写死 6 个,而记录事项现在有 24 种且后台可配 —— 新加的一个都选不到
3. 里头的 report / taskDetail 早就不存在,选了等于点了没反应
现在改成「关联记录事项」,下拉读 record_types 表。后台加一种事项,
这里立刻能选到。
## 这一页原来和后端已经对不上了
它的结构(今日任务 / 30 天计划 / 提醒 三段、第 N 天偏移)就是上一个提交在后端
推翻掉的那套。你在上面配的东西一部分已经不会生效——所以先改它,不等前端。
三段 → 两段(计划事项 / 到期提醒)
「第 N 天 + 标签」 → 重复规则:每天 / 每周(勾星期几)/ 每月(几号)/ 一次性
一个 (物种,阶段) 一套 → 多套,列表页展示,每套有名字和摘要
## 后端跟着改成按 id 存取
原来是「按 species+stage 覆盖」:GET/PUT /admin/care-templates?species=&stage=。
那个模型下「让用户选方案」无从选起。改成
GET /admin/care-templates 列全部
GET /admin/care-templates/:id
POST /admin/care-templates 新增或更新
DELETE /admin/care-templates/:id
## 唯一索引是真拦路石
从模型 tag 里去掉 uniqueIndex:idx_species_stage 之后,新增第二套仍然报
Duplicate entry —— **AutoMigrate 会加索引但不会删已有的**。写了个一次性程序
DropIndex 才通。这个坑值得记:改索引不能只改 tag。
## 校验放服务端
一条配错(「每周」没勾星期几)会让套用时静默少排几条,用户看不出是配错了。
所以保存时就拦,并且报出是哪一条:「梳毛」选了每周,但没勾星期几。
## 列表里报「展开后大概多少条」
只报明细条数会骗人:4 条「每天」套一整月就是 120 多条。
列表和小程序端的方案卡都按重复方式分开报数。
## 验证(预生产库实跑 service 层)
8 套现有方案迁移后都有名字
没名字 / 每周没勾星期几 / 每月几号填 0 → 三条校验都拦住并指名道姓
(猫,成年期) 成功配出第二套「成年猫省心版」,小程序端能看到 2 套可选
tsc --noEmit 通过;npm run build 后重启,/admin/ 资源哈希与新构建一致
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 11:59:52 +08:00
Blizzard
8b1b4cde02
refactor(be): 今日任务并进计划节点,养护方案改成可选、按重复规则配
...
## 三个问题,一起解决
你问「模版要不要做成可选」,摸下来发现底下有三个更硬的:
**① 根本没有多套模版可选。** 模板表唯一索引是 (species, stage) ——
同一个「猫 × 幼年期」只能有一套。「让用户选模版」在数据模型上做不到。
去掉唯一索引,加 Name / Summary / Sort / Enabled。
**② 今日任务和计划节点是两套,而且是我上一轮改出来的。**
DailyTask 模板 kind=task 生成,ensureDayTasks 每天把昨天那份复制到今天
PlanTask 模板 kind=plan 生成,Day 偏移
计划改成月度管理 + 加了「应用到每天」之后,两者做的是同一件事,
但首页读 DailyTask、计划页管 PlanTask —— 用户在计划页加一条「每天喂药」,
首页今日任务里看不到。
DailyTask 退役。task.go 重写成 PlanTask 的一层「按日期取」的门面,
/pets/:id/tasks 路径不变,小程序端不用为这次合并改调用。
PlanTask 加 Priority(首页那份要能标出哪条重要)。
顺手删掉重复的 CreateTask/UpdateTask/DeleteTask —— /plan-tasks 那套已经
覆盖了,留着两套会出现「首页管理弹层加的任务」和「计划页加的节点」进不同的表。
**③ 模板的 Day 偏移和月度计划对不上。** 月底建档的话 day=14/21/30 全落到
下个月,用户建完档打开计划页发现本月是空的。
改成重复规则:once(偏移 N 天,疫苗序列要用)/ daily / weekly(星期几)
/ monthly(几号)。套用 = 展开成目标月份的具体日期。
「每月 31 号」在 2 月按月末算,不然那个月直接没有。
列名用 repeat_rule 不用 repeat —— repeat 是 MySQL 保留字(和 group_key 同理)。
## 展开成实体行,不是「存规则读时展开」
勾选状态是按天的。存规则得再开一张表记「哪天打过勾」,而且用户把
「每周二梳毛」这周挪到周三就要引入例外记录。一次展开成行,增删改和打勾全免费。
代价是套用后模板和计划断开:后台改模板不影响已套用的宠物。这是有意的——
用户已经在自己的计划上勾了几十个勾,后台一改就被覆盖才是灾难。
## 建档不再自动铺
seedPetDefaults 只建必要提醒(疫苗、驱虫)。漏针是真会出事的,而且它们是
「到期提醒」不占计划页的格子。其余交给用户挑方案。
自动铺的问题是:用户还没看懂这个 App 是干什么的,首页已经躺着十几条他没
答应过的任务,第一反应是「这些是什么」而不是「我该做什么」。
**改完发现还有第二条自动铺的路径**:newStagePlan 在建计划壳子时顺手把模板
铺成节点。所以我改完 seedPetDefaults 之后,建档后首页仍然躺着 5 条任务。
惰性生成尤其难查——不是建档时发生的,是第一次读计划才发生的。
## 方案摘要按重复方式分开报数
一开始只报一个总数,「10 条」套用一整月展开成 130 条,用户会以为出 bug。
现在分成 每天 4 · 每周 0 · 每月 0 · 一次性 6 · 提醒 4。
## 数据迁移(预生产库,已执行)
模板明细 kind=task → plan + repeat=daily 28 条
模板明细 kind=plan 补 repeat=once 44 条
8 套方案补名字和摘要
DailyTask → PlanTask 34 条,跳过 0
DailyTask 表的行**没删**,先留着当备份。
迁移第一版又踩了「列还没 AutoMigrate 出来就跑」那个坑:Count 静默返回 0,
我以为「没有需要补的」。第二版加了 HasColumn 前置检查才发现 44 条没转。
和上次 record_types.fields 回填是同一个错。
## 验证(预生产库实跑)
今日任务/计划页今天 4 条 vs 4 条,一致
建档后 0 任务 / 0 计划节点 / 4 条必要提醒
套用本月 从今天到月末,4 条(7/30-7/31 两天)
重复套用 0 条新增(按「日期+标题」去重)
套用下月 130 条覆盖 31 天,每天 4.2 条
全部完成 5 → 0 未做
## 还没做(下一步)
前端:建档第 4 步选方案、计划页空月份的套用入口、首页「管理」改跳计划页、
弹层删 manageTasks;后台模板页要支持多套 + 重复规则编辑。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 11:50:54 +08:00
Blizzard
69bd56671c
feat(admin): 补品种管理和记录事项两个后台页
...
## 这两个页面是漏的,不是新需求
Step 2 我说了「记录类型后台可配」,接口加了(GET/POST/DELETE
/api/admin/record-types)但 React 页面根本没建;品种那次同样只加了接口。
也就是说「可配」这件事在后台上一直是点不到的。补上。
## 品种管理
猫/狗切换,按首字母分段列出(和小程序端的 A-Z 索引对得上)。
首字母是手填的输入框,配了一句说明:多音字自己定(藏獒 Z、柴犬 C)。
不做自动转拼音——Go 没有标准拼音库,而且多音字自动转常出错,
错了以后用户在小程序里按字母索引就找不到那个品种。
## 记录事项
按分组列出 24 种,「表单字段」那列把 DSL 渲染成人话
(体重·数值kg / 状态·单选★),★ 表示这个单选落 category。
字段配置的写法说明直接放在编辑弹窗里,不是写进文档:这东西一年用两次,
去翻文档的成本比它本身还高。
内置那 9 种打了「内置」标签、隐藏删除按钮、code 输入框禁用 —— 但真正的
拦截在 service 层,前端只是别让人白点。
## 报错原样透出
两个页面的保存失败都把后端消息显示出来,不写成「保存失败」。
后端那些消息是特意写具体的(第几行、错在哪、几个档案在用),
包成一句「失败」等于把它们扔了。
## 验证(预生产库实跑 service 层)
品种 首字母两位/中文 → 拒;物种 bird → 拒;同物种重名「布偶猫」→ 拒
有 1 个档案在用时删 → 拒并报出数量;没人用 → 删成功
事项 两个字段都落 category → 「第 2 行」;options 没选项 → 「第 1 行」;
类型写成 num → 「第 1 行类型 num 不认识」;缺名称 → 「第 1 行缺名称」;
第二个加 :- → 通过
tsc --noEmit 通过;npm run build 后重启,/admin/ 返回的资源哈希
和新构建一致(go:embed 是编译期打包的,不重启看不到新页面)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 11:32:50 +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
9b30bfaaff
feat: 计划按自然月管理,加「应用到每天」和下月未排提醒
...
## 为什么不是「从计划开始日起 30 天」
上一版是那样做的,截图一看就不对:计划是月中建的,日历显示
「7月26日 — 8月25日」,既不像本月也不像下月,用户想问「这个月还剩什么」
根本对不上。改成自然月,日历就是一眼能认的月历。
能翻到下月 —— 否则「做下月计划」这件事本身做不了。
## 校验从「Day 上限」改成「日期」
PlanTask.Day 是相对计划开始日的,月份边界是相对今天的,两者会错开。
原来卡 Day<=30,计划建了几天之后下月末就换算成 Day=40 多,
用户在日历上明明看得到那格、点进去却存不了。
现在的规则:不早于计划开始日(下界放到开始日而不是本月 1 号——模板生成的
历史节点可能在上个月,那些要允许原地改),不晚于下月月底。
## 应用到每天
一天建一条,不做「一条 + repeat 字段读时展开」:勾选状态是按天的,
展开方案还得再开一张表记「哪天打过勾」,而直接建 N 条天然就有这个能力。
范围止于**这一天所在那个月**的月底,不跨月——「应用到每天」说的是这个月每天,
跨过去就变成用户没要求的事了。只有新增能选,已有的那条改成每天等于凭空
复制 N 份(用户想要的是「以后每天」,不是「把这条撒开」)。
## 首页那个提醒
GET /pets/:id/plan/month-status 返回本月件数/剩余、下月件数、need_next。
need_next 只在**月末最后 7 天**且下月为空时为真:月初就催「排下个月」太早,
用户会当成噪音。角标做在图标上而不是弹 toast——每次进首页弹一下很烦,
而这件事不紧急、看见就行。
副标题有优先级:「8 月计划还没排」压过「本月都做完了」,因为前者有时效。
四种状态实跑验过,包括让位关系。
## 顺手
pet-switch 加 show-add 属性。计划页只需要在既有宠物之间切,建档入口在首页
和「我的」就够了,到处摆一个「添加」会让这条 chip 变得很长。
本月/下月的切换用新的 .link-tabs 而不是挂在 .head-links 上:首页的
「管理 / 全部完成」也用 head-links,那是两个并列动作,不该有一个是灰的。
## 验证(预生产库实跑)
月边界 本月末通过、下月末通过、下下月拒(报出具体日期)
应用到每天 今天→本月末 2 条,没跨月
month-status 下月清空 → need_next 翻 true;补一条 → 翻回 false
四种副标题 下月未排 / 本月还有 N 件 / 本月都做完了 / 还没有安排,含优先级
测试数据全部还原
上一条 cd 打错目录,导致「日期窗口」那次改动没写进文件、只有批量那半截进去了,
所以中间出现过一次 planWindow undefined。这次一并改对。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 11:09:06 +08:00
Blizzard
15b52eebd0
feat: 首页改成记录时间轴,计划可自己管,花销独立成页
...
## 首页
原来是任务卡 + 日期带/日历 + 接下来 + AI建议 + 快速记录 + 新手内容的堆叠,
六张聚合卡,唯独看不到「我记了什么」。改成:
宠物名片(品种·年龄·星座 + 性别徽章叠头像 + 一起生活的第 N 天)
两个入口(管理计划 / 记花销)
今日任务(有才显示)
记录时间轴 —— 竖线 + 圆点 + 卡片,往下翻,长按删
日历挪回计划页了:它本来就属于那儿。Phase B 当时把它并进首页是因为计划还是
个 tab;现在计划是二级页,日历跟着回去更合理。
情绪点那几样字段后端早就返回了,只是没人用。抽了 utils/petmeta.js:
星座七个边界(含 12/22 跨年那个)+ 天数(到家日优先于建档日,
「一起生活」说的是它到你家之后的日子)+ 性别徽章,都在 node 里跑过。
顺带 stat-ring 组件和 homeSummary 接口现在没人用了,先留着没删。
## 两个入口取代竞品那一排
竞品是买商品/上豪车/记花销/领猫砂盆——除了记花销全是电商和广告位。
副标题给了真信息:「还有 5 件没做」「本月 ¥128」,不然就是两个没信息量的图标。
## 计划页:用户自己能管了
后端原来只有 toggle,节点全靠内置模板生成,用户加不了自己的事。补了
POST /api/pets/:id/plan-tasks
PUT /api/plan-tasks/:id
DELETE /api/plan-tasks/:id
三件事值得说:
**30 天边界硬拦在服务端**(dayOffset)。只在前端拦的话,改个请求就能塞一条
第 200 天的节点,日历上没有那格、它就永远不显示也删不掉。
**归属校验单独抽了 ownedPlanTask**。PUT/DELETE /plan-tasks/:id 这种按资源 id
的路由最容易漏——不校验的话拿到别人的 task id 就能改删别人的计划。验过:
别人的 token 改和删都返回「无权操作」。
**边界差一天,是验证时撞出来的**:内置模板生成到 day=30(第 31 天),
我一开始按 0-29 卡,结果模板自己的最后一个节点(生成月度报告)落在窗口外——
日历上没有那一格,用户看得到却改不动也删不掉。前后端都改成 [0,30],
两边各留了一句注释指向对方,别再单方面改。
日历只画计划覆盖的 31 天,不画整月:整月会多出一堆空白格子、跨月还要翻页。
## 花销独立成页
写的是同一张表(type='cost',金额进 num_value、类别进 category),
报告页的账单聚合照样认——独立页的价值在专门的录入体验和当页就有月度汇总,
不是另存一份数据。
类别预置读 record_types 里 cost 的字段配置,后台改一处这页和 addrecord
同时生效,不会出现两套类别把账单切开。另外允许自定义类别,验过「寄养」
(不在预置里)能落库、账单也认。
## 检查器又抓到一次跨页借用
我在计划页复用了花销页的 ex-ph(placeholder 类),检查器直接报了位置。
顺手把三个页面的私有 placeholder 类统一到 app.wxss 已有的 .placeholder。
cal-* 现在首页没有了、计划页在用,也提到了 app.wxss。
## 验证(预生产库实跑)
计划 CRUD 加/改/删 全过;空标题拒;越权改删拒
30 天边界 day=30 通过、day=31 拒、day=-1 拒
模板 day=30 现在能原地改了(修边界前会被自己的规则拒掉)
首页时间轴 8 条记录按 occurred_at 倒序,type/tone/图标都取到
两个入口副标题 「还有 5 件没做」「本月 ¥128」
花销自定义类别 「寄养」落库,账单分类变成 [(医疗,128),(寄养,60)]
petmeta 星座 7 个边界 + 天数 3 种情况,node 单测全过
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 10:43:08 +08:00
Blizzard
3ea50efb7d
feat: 添加记录独立成页,表单字段由后端配置驱动
...
## 弹层里塞 24 个表单是走不通的
弹层高度受 .sheet-scroll 的 78vh 限制,字段一多就变成内滚;24 项的选择器
挤在弹层里更难看(用户原话「很丑」)。整体搬成页面。
## pages/addrecord —— 一个页面吃掉全部 24 种
形态:记录宠物 / 记录时间 / 类型专属字段 / 描述 + 照片 / 底部固定保存键。
关键在「类型专属字段」整段是后端驱动的:前端不认识「体重」「金额」这些业务词,
只认识 number / options / text 三种渲染方式,以及每个字段的值该落到哪儿。
record_types 加了 fields 列,后台用紧凑写法配(一行一个):
number:体重:kg 数值 → num_value
options:状态:正常|软便|拉稀 单选 → category
options:症状:呕吐|拉稀|精神差:- 末尾 - 表示不落 category,只进标题
text:吃了什么 文本 → 只进标题
(空) 只要 时间+描述+照片
解析放服务端不放前端:配错了要在后台保存时就报出来(第几行、错在哪),
不能等用户点开表单才发现渲染不出东西。读取时解析失败只让这一种事项没有额外
字段并打 warn,不让一条烂配置把整个记录页打空。
## 那个 - 开关不是过度设计
异常观察有两个单选(症状 + 严重程度),而 category 只有一个坑,
周报的高风险数按 category='高' 统计(report.go:46)——必须能指定谁占这个坑。
同理账单按 cost 的 category 分组聚合(report.go:134),
食便相关性排除 poop 的 category='正常'。这三处口径都得严丝合缝对上。
## 记录页瘦成纯列表
只留分组宫格。健康洞察 / 体重趋势 / 健康时间轴整页搬到 pages/history,
从报告页「记录与趋势」进——报告页才是看数据的地方,而一个「我要记一笔」的
页面上摆三块只读图表,用户每次都得先滚过去才能找到要点的东西。
**没有直接删掉那三块**:时间轴是唯一能看和删历史记录的地方,报告页只有
周报/账单这些聚合。删了用户就再也看不到自己记过什么。搬页面用的是 git 里
改动前的完整版复制,比往 report.js 里合并代码安全。
## 弹层瘦了一圈
9 个记录分支删掉,连带 17 个方法、SIMPLE_HINT、buildRecord 的 7 个 case
和一批只有它们在用的 data 字段。
js 1089 → 857 行
wxml 480 → 335 行
弹层现在只管「不是记一笔」的事:提醒、海报、档案、发帖、评论、导出、反馈。
buildRecord 只剩 vetSummary 一个分支(它写一条 note 留痕,不是用户填的表单)。
## 验证(预生产库实跑)
24 种的字段配置逐个核对解析结果,然后照 addrecord 的 buildBody 组装落库:
体重 title='体重:4.6kg' num=4.6 → 宠物档案回写成 4.6kg ✓
记账 title='记账:128元 医疗' num=128 cat=医疗 → 账单 total=128 分类[(医疗,128)] ✓
异常 title='异常:呕吐 高' cat=高 → 周报 high_risk_count=1 ✓
排便 cat=软便 食便相关性口径保住
饮食 title='饮食:幼猫粮 45g 偏少' cat=偏少
喝水 num=180(新类型带数值,老代码没有它的分支也不影响)
洗澡 title='洗澡'(无额外字段)
看病 num=320(两个字段:文本+数值)
体重趋势 1 个点、值 4.6,没被其他 7 条污染。
回填踩过一次坑:fields 列是服务启动时 AutoMigrate 才建的,我在启动前就跑了
回填,Update 报错被忽略、13 行静默没写进去。第二版加了 HasColumn 前置检查
和逐行错误统计才发现。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 10:25:42 +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
60ee9d4bbc
feat(be): 记录类型挪进数据库,后台可配 + 15 种新类型
...
## 为什么
9 种记录类型全是低频医疗和记账(疫苗一年一次、驱虫一季一次、体检更少),
用户今天打开 App 大概率没什么可记,时间轴是空的。竞品 35 种里有 26 种是
高频日常(洗澡/剪指甲/换猫砂/喝水/洗食盆),那才是每天打开的理由。
## 一个比预想好得多的发现
本来担心加类型会踩到分析逻辑。把那 9 个常量的引用全捞了一遍,结论是不会:
weight record.go:83 回写宠物体重;home/insight/report 的体重趋势与基准
food + poop insight.go:130 食便相关性
symptom insight.go:160 症状聚类;report 高风险计数
cost report.go:99 消费统计
vaccine report.go:137 疫苗完成度
deworm/medicine/photo 没有任何特殊分支
这些分支全都是「按某个具体常量过滤」,没有一处是 switch 全枚举、也没有
default 兜底。CreateRecord 更是完全没有 type 白名单校验。所以新增类型
不可能碰到任何现存逻辑——一行分析代码都不用改。
于是分工是:
record_types 表 负责「展示什么、能记什么」
那 9 个常量 负责「哪几种参与分析」
两者各管一段,常量一个都没删。
## 表设计
code / label / icon / group_key / sort / enabled / form / locked。
group_key 而不是 group:group 是 MySQL 保留字,GORM 会加反引号所以能跑,
但手写 SQL 排查时很容易踩。
form 区分 full(弹层里有专用 wx:elif 分支)和 simple(时间+备注+照片)。
15 种新类型全是 simple——下一步在弹层加一个通用分支吃掉它们,不然 28 个
分支再加 15 个会把 bottom-sheet 写到 1800 行。
locked 给那 9 种:有代码分支依赖、且被 care_template_items.sheet_type 引用。
## 两条硬拦在 service 层的规则
1. locked 的删不掉
2. 已经有记录的删不掉(删了历史记录会变孤儿)
想让它从记录页消失应该用 enabled=false,历史记录仍能正常显示。
都在 service 层拦,不是靠前端隐藏按钮。改 code 同样受 2 的约束——
code 是落库值,改了历史记录会对不上任何类型。
## bootstrap 的取舍
文章和养护模板当初按你的要求从代码里挪走了,这次 24 种类型仍然放在 seed 里,
因为它不是内容而是结构:表空着记录页一个可记事项都没有,App 直接不能用。
和管理员账号一样,只在表**完全为空**时铺一次,之后一切以数据库为准。
表非空就完全不碰,否则后台删掉的类型会每次重启自己长回来。
ListRecordTypes 在表为空时返回空数组 + 打 warn,不硬编码兜底一份——
那等于把「可配置」又变回代码常量,下次改配置的人会发现改了没用。
## 图标
新增 15 个(iconfont.wxss 40 → 55),全部取自本地那份 tabler-icons-3.46.0
真源,不是凭记忆画路径。已解码抽检确认路径非空。
## 验证(生产库实跑)
建表 + 24 条 bootstrap 一次到位,分组 daily6/health7/care6/clean5
locked 9 个、simple 表单 15 个
规则 1 删 weight → 「有统计和分析逻辑依赖它,不能删」
规则 2 新增 nose 成功 → 重复 code 报错 → 删除成功
规则 3 造 1 条 tmptest 记录 → 删类型被拦;删掉记录后再删 → 成功;残留 0
规则 4 停用「美容」→ 小程序端洗护组只剩 5 项;恢复后回到 6 项
规则 3 一开始没真验到:库里唯一的记录类型是 weight,locked 先拦住了,
「已有记录」那个分支根本没走到。补了个造真记录的测试才算验过。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-30 09:24:24 +08:00
Blizzard
8606c1dfc8
feat(be): Phase C —— 个人主页装扮 + 养宠数据
...
## User 加四个装扮字段
bio / bg_file_id / theme / hide_pets。
hide_pets 存的是「隐藏」而不是「展示」,为的是零值即默认:AutoMigrate
给存量行填 0,正好等于「展示宠物墙」,不用给老用户跑一次刷值。对外
API 仍然用 show_pets(UI 上是个「展示我的宠物」开关,正着说更自然),
只在 handler 边界取一次反。
theme 存 key 不存色值。色值属于前端表现层,存进库以后想调色就得改数据;
存 key 还能保证前端只渲染已知的那几种。非法 key 走 40000,老用户的空
theme 在读取时兜底成 warm,前端不会拿空 key 去查表。
## GET /users/:id/profile 扩展
原来只有昵称头像和三个计数,现在带上 bio / bg_url / theme / show_pets
+ 宠物名片墙 + 养宠数据。自己看和别人看走同一个接口,省得两套渲染慢慢长歪。
## 养宠数据
days 养宠天数,按最早那只的建档日算——这里要表达的是「你在这照顾它
多久了」,不是宠物活了多久
records 累计记录条数
act_days 有记录的天数
streak 连续打卡
streak 有个必须处理的边界:今天还没记录不能算断签,否则用户每天早上打开
都会看到连续天数归零。实现是先看今天有没有记,没有就从昨天起往回数。
## PUT /api/user/decoration
四个字段全用指针,区分「没传」和「传了空串」——清空个性签名和不改个性
签名是两件事。bio 服务端截到 60 字。
联调验证(本地 9090):
老用户读取 theme 兜底 warm、bio ''、hide_pets false
改装扮 theme=mint、bio 落库
theme=rainbow 40000 参数不合法
bio 100 字 截断到 60
show_pets false → pets 字段消失,stats.pet_count 仍为 1
别人视角 is_self=false、followed=false、装扮和宠物墙都能看到
streak 1/2/3/5 天前各记一条:act_days=4 streak=3(第 4 天空档正确断开)
今天再补一条:act_days=5 streak=4
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 17:54:16 +08:00
Blizzard
25f655a6fc
feat: 补齐关注的入口——用户主页 + 关注/粉丝列表
...
关注之前只做了一半:能从帖子上点「+关注」,也有「关注」信息流,但
关注完就石沉大海——没有用户主页、看不到自己关注了谁、也不知道谁关注
了自己。功能是通的,路是断的。
后端新增:
- GET /api/users/:id/profile 公开资料 + 帖子/关注/粉丝三个计数 + 我是否已关注
- GET /api/users/:id/posts TA 发布的帖子
- GET /api/users/:id/relations?kind=following|followers
- /api/user/summary 补 following / followers,否则「我的」页那两行永远是 0
关系列表里「我是否关注了这批人」用一次 IN 查询查完,不是每行一次。
小程序端新增两个页面:
- pages/user/user 用户主页:头像/昵称/三项计数/关注按钮 + TA 的帖子
- pages/relations 关注列表与粉丝列表(同一页,kind 区分)
入口:
- 社区点头像或昵称 → TA 的主页
- 主页点「关注/粉丝」数字 → 对应列表
- 「我的」页新增「我的关注」「我的粉丝」两行
关注按钮先本地翻转再发请求,失败回滚——等接口返回按钮才变会显得很迟钝。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 17:13:04 +08:00
Blizzard
9fc61e878e
feat: 评论支持回复(两级 + @某人)
...
不做无限层级——手机屏幕撑不住层层缩进,读到第四层就没法看了。
微信、小红书、B站清一色是两级:一级评论 + 其下的回复列表,回复里
用「回复 @某人」表达指向谁。
数据结构:comments 加 parent_id + reply_to_name。回复的回复会被
压平到同一条一级评论下(parent_id 取爷爷的),同时把被回复人的名字
记进 reply_to_name —— 这样既保住两级,又不丢「在跟谁说话」的信息。
几个容易做错的地方:
- 一次查完这一页所有一级评论的回复,不是每条一次查询(N+1)
- 一级评论默认只带 3 条回复,其余点「展开全部 N 条」再拉,避免热门
评论一次返回几百条
- 删一级评论要连它下面的回复一起删,否则回复变成挂在空处的孤儿;
帖子的 comment_count 也要按实际删除条数减,不是减 1
- total 统计含回复,和帖子上显示的数字对得上
- replies 为空时返回 [],不是 null
实测四条评论(含一条回复的回复):
▸ 甲:一级评论 (2 条回复)
└ 乙:多久了?
└ 甲 回复 乙:三天了
▸ 乙:另一条一级评论 (0 条回复)
删掉第一条一级评论后 total 4→1,comment_count 同步。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 16:33:50 +08:00
Blizzard
535ef08da7
fix: 评论配图整条链路补全 + 宠物切换条吸顶
...
## 评论图片传了等于没传
上次只做了一半:model 加了 Images 字段、前端做了上传 UI,但
handler 的 commentReq 没有 images、service 的 CreateComment 连
参数都没有,图片上传完就丢了;评论列表也从没渲染过图片。
补齐:请求体 → service 落库(JSON 数组) → 列表回显 → 点击大图预览。
实测带两张图的评论和纯文字评论各存各的,互不影响。
## 宠物切换条吸顶
首页/计划/记录/报告四页的 pet-switch 原本在 scroll-view 里,滚下去
就找不到了。而切宠物是随时要用的动作——多宠用户看着 A 的数据想切到
B,还得先滚回顶部。
移出滚动区,放在导航栏下方做成固定的一条,带毛玻璃和分隔线。首页的
问候语留在滚动区里,滚走就滚走,反正它只在刚进页面时有意义。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 16:19:32 +08:00
Blizzard
5b2f8e50bc
fix: 带 date 查任务时区错位导致重复生成 + 评论弹窗重做 + AI 每日次数上限
...
## 首页添加的任务不显示(根因比表象严重)
time.Parse("2006-01-02", q) 返回的是 UTC 时间,dayStart 又保留了
t.Location(),于是带 ?date= 查询时:
查询区间 = 07-29 00:00 UTC ~ 次日 = CST 的 08:00 ~ 次日 08:00
已有任务的 task_date 是 07-29 00:00 CST,落在区间外
后果不只是「新任务不显示」——ensureDayTasks 因此认为今天没有任务,
每刷一次首页就重新生成一批。用户手动加的那条(00:00 CST)永远不在
那个错位窗口里,所以管理页看得到、首页看不到。
全项目 7 处 time.Parse 日期解析统一换成 ParseInLocation + time.Local
(任务、日计划、生日、到家日期、提醒到期日都受影响)。
实测:加一条后带 date 查得到 4 条,连查 4 次仍是 4 条不再增长。
## 评论弹窗
- 改成居中弹出。评论以输入为主,贴底弹层会被键盘顶掉大半屏
- 单行 input 换成自动撑高的 textarea,最多 500 字,带字数
- 支持配图,最多 3 张(评论表加 images 字段)
- 空评论原来会直接把弹层关掉,看起来像发成功了,改成明确提示
- 发完就地刷新列表,不再关闭弹层——连着回复更顺
## AI 每日次数上限
AI 调用是真金白银,不设上限等于把钱包交给用户。新增按「用户 + 自然日
+ 功能」计的额度,后台「社区运营」页可配问问 AI / 异常评估 / AI 计划
三档,改完立即生效。
两个刻意的设计:
- 扣额度在请求大模型之前,失败也算用掉一次。否则刷接口空转照样烧钱
- 配置读不到时回落到保守默认值,绝不「读不到就不限制」——那正是配置
出问题时最不该发生的事
超限返回业务码 42900,小程序端明确说明「明天 0 点恢复」,不当成网络
错误让用户反复重试。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 15:50:38 +08:00
Blizzard
75765b3ee8
feat: 健康洞察——把散落的记录变成能看懂的结论
...
之前用户记几十条数据只换回一条折线,数据没有回到他身上,所以不记也不亏。
新增 GET /api/pets/:id/insights,只看最近 90 天(更早的对「现在怎么样」
没参考价值,还会让关联分析找出一堆巧合),产出最多 6 条按严重度排序的结论:
1. 体重趋势 —— 单次数字没意义,跨度 ≥14 天的连续同向变化才算。
跌 10% 报警建议血检,涨 15% 提醒控制,跌 5% 持续观察
2. 换粮 → 软便的时间关联 —— 找异常排便前 72 小时内的饮食记录。
这是用户最看不出来的一类:两条记录隔两三天、分属不同类型,翻时间轴翻不出来
3. 异常扎堆 —— 两周内 ≥2 次异常。偶发一次和反复出现完全不是一回事
4. 逾期提醒 —— 设了不看等于没设
5. 同龄体重对比 —— 同物种、月龄差 2 个月内其它宠物的中位数。
样本 <8 只直接不显示:拿 3 只算出来的「中位数」比不给还糟
6. 记录习惯 —— 数据不足时negative空手而归,给一句「再记几条就能看出规律」
每条都带 evidence(支撑它的具体数据)和 action(点击直接跳到对应记录入口),
结论不能只是断言。文案沿用 AI 助手同一套护栏:不做诊断,异常一律写清
什么时候必须就医。
前端落在记录页体重趋势卡上方,三档配色区分严重度。
实测(造 4 条体重下滑 + 换粮 + 软便 + 两次异常):
🔴 体重掉了 13%,建议就医检查(39 天内 4.50→3.90kg)
🔴 两周内记了 2 次异常
🟠 这次「软便」之前 2 天有过饮食变化(7月20日换粮 → 7月22日软便)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 15:03:36 +08:00
Blizzard
7acdf916d5
refactor(be): 养护模板也从代码里移出,只从数据库读
...
和文章同一个理由:模板是运营内容,不是代码。留一套内置默认还额外带来
一个坏处——库里配的和代码里写的会悄悄分叉,出问题时分不清用户拿到的
到底是哪一套。
删掉:
- builtinCat / builtinDog / builtinCareItems(8 套 × 96 条)
- SeedCareTemplates(启动时写内置默认)
- ResetCareTemplate + 后台「恢复默认」按钮 —— 已经没有默认可恢复
careTemplateItems 现在查不到就返回空。这意味着后台把某个组合配空了,
新用户会拿到一个什么都没有的首页而且不报错,所以 seedPetDefaults 里
加了一条 log:模板为空时打出 species/stage/petID,否则没人能发现。
「AI 生成草稿」原来在 AI 未开启或调用失败时静默返回内置默认,看起来
像是 AI 生成的。现在直接报错说清原因,让管理员知道要么开 AI 要么手填。
数据在库里,删代码不影响:预生产 8 套 96 条原样在,建档端到端复测通过
(3 月龄幼猫仍拿到「下一针疫苗·21 天后」,成年犬仍有疫苗驱虫提醒)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 13:59:11 +08:00
Blizzard
4f6f0f632e
refactor(be): 文章内容从代码里移出,改为直接同步数据库
...
几百字的正文塞进 Go 源文件,既看不清 diff 也没法在后台改完再同步
回来——内容和代码本来就是两条生命周期。
- 删掉 articles_more.go(16 篇)
- seed.go 只保留 seedAdmin,去掉 seedArticles / builtinArticles /
backfillArticleContent(后者是给早期无正文文章补内容的一次性逻辑,
已无意义)
数据已经在库里,删代码不影响:预生产 20 篇文章原样在,小程序端照常
读得到。上线时手动同步这张表即可。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 13:53:35 +08:00
Blizzard
7159930d9c
feat(admin): 随机昵称 + 建档数统计 + 帖子发布时间 + 16 篇新文章
...
## 新用户昵称
微信登录拿不到昵称(要用户主动授权),原来一律叫「微信用户」,
社区里一屏全是同名,后台也没法区分。改成随机生成「铲屎官12138」
这种形式:10 个前缀 × 5 位数字,落库前查重,撞了重试。
新增 users.nickname_auto 标记这个昵称是系统生成的。原来判断该不该
用微信授权昵称覆盖,靠的是「昵称是不是等于『微信用户』」这个字符串
比较,改成随机昵称后这招就失效了。有标记位才能安全覆盖,同时保证
用户自己改过的昵称不会被冲掉(改昵称时会把标记置 false)。
## 用户管理
加「宠物档案」列,显示每个用户建了几个档。用一次 GROUP BY 查完
当页所有人,不是每行一次 count——那会是 N+1。
## 帖子审核
加发布时间列。今天的显示「今天 14:48」,昨天的显示「昨天」,
更早的显示日期——审核时关心的是「多久以前发的」而不是完整时间戳。
## 文章
新增 16 篇,连同原有 4 篇共 20 篇,每篇 400-570 字:
猫 5 篇(新猫到家第一周 / 猫砂盆 / 公猫尿闭 / 掉毛毛球 / 老年猫信号)
狗 5 篇(社会化关键期 / 定点排便 / 遛狗时长 / 刷牙 / 中暑防护)
通用 6 篇(体重趋势 / 驱虫周期 / 绝育 / 急诊清单 / 就医准备 / 养宠预算)
沿用和 AI 助手一样的安全护栏:不做诊断、不给药物剂量,凡是可能
延误病情的都写清「什么时候必须去医院」。犬用驱虫药对猫的致死风险
这类真实事故也写进去了。
seedArticles 从「库空才插」改成「按标题补缺失」,以后往内置清单加
文章,老库启动也能拿到。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 12:55:22 +08:00
Blizzard
d9d7e128ff
feat: 引导页阶段按生日推断 + 8 套养护模板按临床共识重配
...
## 引导页三个逻辑漏洞
1. **阶段和生日脱节**:用户填了 3 个月的生日,却能手选「成年期」,
而阶段决定疫苗针次、驱虫周期和每天要做的事,选错整套计划都是偏的。
现在按生日自动推断(猫狗同:12 月龄成年、7 岁进老年),仍可手改,
但改成矛盾值时会弹框说明代价;服务端 NormalizeStage 兜底。
2. **`goals` 是假选择**:6 个勾选框收上来只存进 pets.goals,一处没用过。
现在真正生效:体重提醒、月度报告按勾选生成,勾了「想控制养宠开销」
会多一条记账任务。疫苗和驱虫不给关——狂犬是法定要求,漏驱虫真会出事。
3. **「刚到家 0-30 天」和年龄阶段互斥**:挤在一个四选一里,刚接回家的
成年猫只能二选一。现在拆开:stage 只存年龄阶段,新增 pets.arrived_at,
到家不满 30 天时把安置期那套任务和计划叠加上去(同标题去重)。
顺带:生日/到家日期不能选未来(前后端各拦一道)、体重范围校验。
## 疫苗提醒改为按月龄算
原来不管多大都排「14 天后首针」,一只 8 月龄才接回家的猫会被安排去打首免。
现在 dueDaysFor 按真实月龄推:<2 月龄等到 8 周龄、2-5 月龄间隔 21 天、
5-12 月龄两周内补齐、成年走年度加强。标题也跟着改写,否则用户照着
「年度疫苗加强」去打错针。
年度疫苗不再编一个假的到期日(原来写 30 天后),改用频率描述。
## 8 套模板按临床共识重配
依据 WSAVA 疫苗指南、ESCCAP/CAPC 驱虫建议、AAHA 生命阶段指南整理:
猫三联 3 针间隔 3-4 周末针不早于 16 周龄、犬联苗 2-3 针 + 3 月龄狂犬、
体内驱虫 6 月龄前每月一次之后每 3 个月、幼崽 3-6 月龄每天 3-4 餐、
成年犬每天 2 次共 30-60 分钟遛狗、老年建议半年一次体检。
每套从 11 条扩到 10-14 条,描述写成能直接照做的具体动作。
后台新增「恢复默认」:启动 seed 改为只补缺失、不覆盖已有(管理员可能
改过),内置模板更新后必须从后台显式推一次。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 11:58:00 +08:00
Blizzard
9adafb1354
feat(auth): access token 缩到 2 小时 + refresh token 机制
...
后台登录框原来预填了 sundynix/sundynix,等于把凭证写在页面上,去掉。
令牌改为 access(2h) + refresh 两段式:
- 新表 sundynix_refresh_tokens,只存 sha256,明文只在签发时返回一次
- 有效期:小程序 30 天、后台 7 天
- 新接口 /api/auth/refresh|logout、/api/admin/refresh|logout
安全约定:
- 每次续期都轮换刷新令牌,旧的立即作废
- 作废后 60 秒内再到达算并发重试放行,超过则判定泄露、吊销该账号全部会话
- 主动退出与被连坐吊销的令牌不吃宽限期,否则「吊销全部」形同虚设
- 禁用用户时一并吊销刷新令牌,最多 2 小时彻底失去访问
两端请求层都做了单飞续期:并发请求同时 401 只发一次 refresh,
否则刷新令牌会被并发轮换掉互相打架。小程序续期失败回退 wx.login,
登录/续期请求标 noAuthRetry,避免登录失败(同样返回 40100)触发自我套娃。
顺带修掉 vite 代理仍指向 8080 的遗留(端口早已改 9090)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-07-29 09:38:19 +08:00
Blizzard
2e3345cdfc
feat: 记录删除与筛选、用户侧内容删除、AI 聊天历史
...
修复雪花 ID 精度丢失(真 bug)
- bottom-sheet 的 postId 声明为 Number,而 ID 是 18 位雪花字符串,
超出 JS 安全整数范围:339346584095428608 会被转成 ...600,
评论弹层实际查的是不存在的帖子。改为 String
记录
- 后端 DELETE /records/:id 早已就绪但前端从未调用,记错了删不掉。
时间轴支持长按删除
- 时间轴加类型筛选(体重/便便/饮食/异常/用药/疫苗/消费/照片),
后端 ?type= 本就支持
用户侧内容删除(UGC 合规:用户应能删除自己发布的内容)
- 新增 DELETE /posts/:id 与 DELETE /comments/:id,仅限本人,
越权返回 40300;帖子软删除,评论删除同步递减 comment_count
- 评论列表返回 is_self;社区长按自己的帖子、长按自己的评论可删
AI 聊天历史
- ai_messages 一直在写但没有查询接口,每次打开弹层都是空白。
新增 GET /api/ai/messages,弹层打开时接在开场白后加载
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-28 17:42:14 +08:00
Blizzard
77beb9ca96
fix(pro): 会员改为「即将开放」,堵住点一下白拿会员的漏洞
...
原先 /api/pro/activate 直接写库开通一年会员,没有任何支付校验,
任何人调一次接口就是会员。支付暂不接入,这里必须在服务端拒绝,
只改 UI 挡不住直接调接口。
- ActivatePro 一律返回 ErrPayNotReady;真正写库的逻辑保留为
activateProAfterPaid,等接微信支付时在校验支付单据后调用
- handler 对该错误返回参数错而非 500,前端直接展示提示文案
- 小程序 Pro 弹层按钮置灰为「即将开放」,我的页入口改为
「Pro 会员(即将开放)」
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-25 18:15:38 +08:00
Blizzard
3fde90e97b
feat: 补齐五块缺失功能(记录丢数据/文章正文/提醒管理/我的页入口/分享/关注)
...
P0 修数据问题
- 记录弹层有 5 个输入框从未绑定,用户填的便便备注、饮食内容、药品名称、
剂量、消费备注全部丢弃;用药记录因此只存下「用药记录」四个字。已全部绑定并入库
- 异常观察保存时写死「风险中」,AI 实际判定的等级被丢掉。改为使用 riskData
的真实 risk_level,并把成因与建议存进备注
文章正文
- 早期 seed 的 4 篇文章 Content 全空,点开只是打开关联记录弹层,内容运营等于白做
- 补写 4 篇真实正文(疫苗驱虫/软便判断/换粮方案/养宠花销),遵循不诊断、
异常必提就医的护栏;对已存在的空正文做幂等回填
- 新增文章详情页,学习页与首页卡片改为打开正文
提醒管理
- 后端 CRUD 早已具备但小程序只读,用户改不了疫苗驱虫日期。提醒弹层支持增删改
- 修复后端 UpdateReminder 漏掉 type 字段导致改类型不生效
「我的」页 7 个死入口接活
- 提醒设置、健康记录、多宠物管理、会员权益分别落到对应功能
- 数据导出:汇总档案与记录为文本,可复制发给医生
- 意见反馈:新增 feedback 表与提交接口,后台加「意见反馈」管理页
- 关于我们:应用说明与免责声明
分享
- 各页面补 onShareAppMessage/onShareTimeline
- 帖子分享按钮改用微信原生 open-type="share",删除原来点了没反应的空壳弹层
社区关注
- 新增 follows 表与关注/取关接口,「关注」tab 此前等同「推荐」,
现只显示已关注用户的帖子;帖子头部可直接关注,标记 followed / is_self
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-25 18:11:08 +08:00
Blizzard
8507d5060b
fix(storage): 共用 MinIO 实例下不再覆盖已存在桶的访问策略
...
deploy / deploy (push) Has been cancelled
MinIO 是多服务共用实例(sundynix-agent / sundynix-plant 等)。原先
ensureBucket 每次启动都无条件 SetBucketPolicy 设为公开只读,一旦
MINIO_BUCKET 配错成别的服务的桶,启动一次就会把人家的桶悄悄改成
全网可读且无任何报错。
改为:桶已存在则只连接、绝不修改策略并打日志说明;仅对本服务新建的
桶设公开只读(小程序需要图片直链)。.env.example 补充共用实例注意事项,
并建议改用仅授权 sundynix-pet 的独立账号替代 root 凭据。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-25 16:57:37 +08:00
Blizzard
eaa21585de
ci: Docker 单镜像部署 + Gitea 自动发布
...
- pets-be/Dockerfile:多阶段单镜像,node 构建管理后台 → Go 编译内嵌
(go:embed)→ alpine 运行。一个容器同时提供 /api 与 /admin,50MB,
非 root、内置 tzdata 保证按东八区计算每日任务
- deploy/docker-compose.yml:只有一个 app 容器,MySQL/MinIO 用外部现成的,
容器内 9090 映射宿主机 4000
- deploy/.env.example:全部配置项(MySQL/MinIO/微信/AI/管理员)
- .gitea/workflows/deploy.yml:push 或合并到 main 触发,runner 构建镜像 →
save 打包 → scp 到服务器 → docker load + compose up -d → 健康检查
- 修复容器化阻塞问题:config.Load 原本强制要求 config.yaml(而它不进 git),
且 viper 未登记默认值的 key 环境变量绑不上。现补全默认值并把配置文件
改为可选,纯 .env 即可启动
- 服务端口统一改为 9090
验证:镜像构建通过;本地起完整栈 ping/admin/登录/建表 seed/图片上传全通;
对接真实 MySQL 9.4(sundynix_pet)建表 19 张并 seed 成功。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-25 16:47:49 +08:00
Blizzard
3816cd1b02
chore: 小程序更名为「肉垫计划」
...
- 原名「毛孩子计划」在微信已被占用,全项目 24 处替换(导航标题、
AI 提示词身份、社区官方号、后台登录页、logo 横版文案)
- logo 英文副标同步改为 PAW PAD · CARE PLAN
- 新增 小程序资料.md:后台要填的简介(多长度版本)、关键词、
服务类目建议与审核避雷要点
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-25 16:46:21 +08:00
Blizzard
28b95a6468
feat: 每日任务顺延与增删改 + 计划到期续期 + 靠谱养护模板 + 图片URL修复
...
后端
- 每日任务惰性生成:某天为空则从最近一天顺延复制(done 重置),首天用模板
- 任务增删改 API(POST /pets/:id/tasks、PUT/DELETE /tasks/:id),改动自动顺延
- 30 天计划到期自动归档并按当前阶段生成新一轮
- 内置养护模板重写为兽医常识向:狗每阶段含遛狗/牵引/狂犬,猫含猫砂/梳毛/饮水
- 文件 URL 改为按 object_name + 当前配置动态拼接,换 IP/域名不再有旧地址
小程序
- 首页今日任务加「管理」入口:增删改任务弹层
- 记录时间轴显示照片缩略图(可全屏预览)+ 拍照成功提示
- 社区发布条精简为单个「发布图文」按钮,去掉头像/输入框误触
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-06 10:06:13 +08:00
Blizzard
2f5dd6eefc
feat: 养护模板/社区运营/体重趋势/计划日历 + 雪花ID重构 + 文件表与图片上传
...
后端
- 主键改雪花字符串 ID(pkg/idgen + Base.BeforeCreate),全表外键/JWT/中间件随之调整
- 新增 files 表:/api/upload 按 MD5 去重,返回 {id,url,md5},服务端只收图片
- 头像/记录附图/帖子图改 file_id 关联,读取解析为 URL
- 养护模板(物种×阶段)后台可配 + AI 生成草稿;建档按模板生成任务/计划/提醒
- 社区 AI 运营:虚拟账号池 + 每日定时/手动生成,帖子带 AI 标
- 计划路线图节点带真实日期;首页周历与计划日历同源;新增 day-plan 当日安排
- 体重趋势接口带备注;记录列表分页
小程序
- 公共图片上传 utils/upload.js(仅图片);记录拍照/我的头像/社区发图三处接入
- 首页日历点选查当日任务;记录页体重趋势可点看备注 + 时间轴分页折叠
- 计划页日历点选查当日计划;自定义 tabBar 高度调整
后台(React)
- 新增「养护模板」「社区运营」页;用户管理加机器人筛选
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-06 08:48:15 +08:00
Blizzard
609f7d06cf
init: 毛孩子计划 小程序 + Go 后端 + 内嵌后台
...
- pets-fe: 微信原生小程序(首页/计划/记录/报告/社区/引导),
服务端驱动、无假数据;弹层改用 scroll-view,打开时隐藏自定义 tabBar
- pets-be: Gin + GORM(MySQL, sundynix_ 前缀) + MinIO,统一响应/分页,
微信 code2session 登录,provider-neutral AI(DeepSeek),go:embed React 后台
- 修复:分段选择类型不匹配(字符串 vs 数字)导致选不中
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-03 15:36:55 +08:00