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>
This commit is contained in:
Blizzard
2026-07-06 10:06:13 +08:00
parent 2f5dd6eefc
commit 28b95a6468
21 changed files with 478 additions and 81 deletions
+98 -39
View File
@@ -205,72 +205,131 @@ func careReminder(rtype, title string, offset int, freq string) model.CareTempla
return model.CareTemplateItem{Kind: model.CareKindReminder, ReminderType: rtype, Title: title, OffsetDays: offset, Frequency: freq}
}
// builtinCareItems 内置默认模板(8 套),既作开箱数据也作兜底
// builtinCareItems 内置默认模板(猫/狗 × 4 阶段,共 8 套)。
// 兽医常识向:狗每个阶段都含遛狗/牵引,猫含猫砂盆/梳毛/饮水;疫苗驱虫节奏按物种阶段区分。
func builtinCareItems(species, stage string) []model.CareTemplateItem {
isDog := species == model.SpeciesDog
dewormAdult := 90
if isDog {
dewormAdult = 60 // 狗驱虫间隔通常比猫短
if species == model.SpeciesDog {
return builtinDog(stage)
}
return builtinCat(stage)
}
func builtinCat(stage string) []model.CareTemplateItem {
switch stage {
case "刚到家 0-30 天":
return []model.CareTemplateItem{
careTask("记录一次体重", "到家后每周记录,建立基线", "重要", "weight"),
careTask("观察饮水与排便", "换环境应激常见软便,连续观察几天", "", "poop"),
careTask("布置安静休息角", "固定饮食、厕所与休息区,减少应激", "", ""),
carePlan(0, "今天", "安顿与环境适应", "固定饮食、厕所、休息区位置", "taskDetail"),
carePlan(3, "第3天", "观察排便与食欲", "记录应激缓解情况", "poop"),
careTask("记录一次体重", "到家先称个底,之后每周一次看增长", "重要", "weight"),
careTask("清理猫砂盆并观察", "换环境应激常见软便,留意颜色和次数", "", "poop"),
careTask("陪玩 15 分钟", "逗猫棒建立信任,缓解应激,别强抱", "", ""),
carePlan(0, "今天", "安顿与环境适应", "猫砂盆、食盆、水碗、猫窝固定位置,给它安静空间", "taskDetail"),
carePlan(3, "第3天", "观察进食与排便", "食欲和便便恢复正常说明适应良好", "poop"),
carePlan(7, "第7天", "第一次体重记录", "作为后续趋势基线", "weight"),
carePlan(14, "第14天", "预约首次体检/疫苗", "确认医院与时间", "vaccine"),
carePlan(14, "第14天", "预约首次疫苗/体检", "确认医院、驱虫和免疫计划", "vaccine"),
careReminder("vaccine", "首次疫苗接种", 14, ""),
careReminder("deworm", "首次体内外驱虫", 7, ""),
careReminder("weight", "体重记录", 0, "每周一次"),
careReminder("monthlyReport", "月度报告", 0, "每月 1 日"),
}
case "幼年期":
vaccineTitle := "第 2 针疫苗"
if isDog {
vaccineTitle = "下一针联苗"
}
return []model.CareTemplateItem{
careTask("记录一次体重", "幼年期每周至少记录 2 次", "重要", "weight"),
careTask("观察饮水与排便", "换粮、应激都可能影响排便状态", "", "poop"),
careTask("检查疫苗预约", "按免疫程序别漏针", "重要", "vaccine"),
carePlan(0, "今天", "观察排便状态", "记录颜色、形态、次数", "taskDetail"),
carePlan(1, "天", "检查疫苗预约", "确认下一针医院与时间", "vaccine"),
carePlan(7, "第7天", "体重趋势检查", "每周称重,观察稳定增长", "weight"),
carePlan(14, "第14天", "复盘饮食与便便", "换粮记录与异常一起看", "taskDetail"),
careReminder("vaccine", vaccineTitle, 18, ""),
careReminder("deworm", "体内外驱虫", 12, ""),
careTask("记录一次体重", "幼猫长得快,每周记 2 次", "重要", "weight"),
careTask("梳毛并陪玩", "每天梳毛+两次互动,帮助社会化、减少毛球", "", ""),
careTask("检查疫苗计划", "幼猫三针联苗按时打,别漏针", "重要", "vaccine"),
carePlan(0, "今天", "确认免疫与驱虫计划", "对照月龄核对疫苗针次和驱虫时间", "vaccine"),
carePlan(3, "第3天", "观察饮水与排便", "换粮期留意软便,7 天过渡换粮", "poop"),
carePlan(7, "第7天", "体重趋势检查", "每周称重,稳定增长是关键指标", "weight"),
carePlan(14, "第14天", "驱虫与饮食复盘", "确认驱虫到期、复盘换粮情况", "medicine"),
careReminder("vaccine", "第 2 针疫苗", 18, ""),
careReminder("deworm", "体内外驱虫", 30, ""),
careReminder("weight", "体重记录", 0, "每周二、周五"),
careReminder("monthlyReport", "月度报告", 0, "每月 1 日"),
}
case "老年期":
return []model.CareTemplateItem{
careTask("记录一次体重", "老年期体重波动要重视", "重要", "weight"),
careTask("观察精神与食欲", "明显变差要尽快就医", "重要", "symptom"),
careTask("关注饮水量", "多饮多尿可能是慢病信号", "", ""),
carePlan(0, "今天", "老年健康自查", "精神、食欲、饮水一起看", "taskDetail"),
carePlan(7, "第7天", "体重与饮水记录", "留意慢病早期信号", "weight"),
carePlan(14, "第14天", "用药与体检回顾", "慢病管理与用药记录", "medicine"),
carePlan(30, "第30天", "生成月度报告", "整理给医生看的记录", "report"),
careTask("记录一次体重", "老年猫消瘦要警惕,别忽视", "重要", "weight"),
careTask("关注饮水量与排尿", "多饮多尿常是肾病/糖尿信号,异常尽快就医", "重要", "symptom"),
careTask("清理猫砂盆并观察", "关注尿量、尿色和排尿是否困难", "", "poop"),
carePlan(0, "今天", "老年健康自查", "精神、食欲、饮水、体重整体过一遍", "taskDetail"),
carePlan(7, "第7天", "体重与饮水记录", "两项一起看,慢病早发现", "weight"),
carePlan(14, "第14天", "用药与慢病回顾", "整理长期用药和体检结果", "medicine"),
carePlan(30, "第30天", "月度报告 / 建议体检", "老年猫建议每半年一次体检", "report"),
careReminder("vaccine", "年度疫苗加强", 30, ""),
careReminder("deworm", "体内外驱虫", dewormAdult, ""),
careReminder("deworm", "体内外驱虫", 90, ""),
careReminder("weight", "体重记录", 0, "每两周一次"),
careReminder("monthlyReport", "月度报告 / 建议体检", 0, "每月 1 日"),
careReminder("monthlyReport", "月度报告 / 半年体检", 0, "每月 1 日"),
}
default: // 成年期
return []model.CareTemplateItem{
careTask("记录一次体重", "成年每月称重一次即可", "", "weight"),
careTask("观察饮水与排便", "发现软便可连续观察几天", "", "poop"),
careTask("梳毛与口腔检查", "关注牙结石皮肤状态", "", ""),
carePlan(0, "今天", "全面健康自查", "体重、精神、食欲、被毛过一遍", "taskDetail"),
carePlan(7, "第7天", "体重趋势检查", "对比上月,观察是否稳定", "weight"),
careTask("记录一次体重", "成年每月一次,防止肥胖", "", "weight"),
careTask("清理猫砂盆并观察", "泌尿问题早发现,公猫尤其注意尿闭", "", "poop"),
careTask("梳毛与口腔检查", "关注毛球、牙结石皮肤状态", "", ""),
carePlan(0, "今天", "全面健康自查", "体重、精神、食欲、饮水、被毛过一遍", "taskDetail"),
carePlan(7, "第7天", "体重趋势检查", "对比上月,稳定为宜", "weight"),
carePlan(14, "第14天", "驱虫记录复盘", "确认体内外驱虫是否到期", "medicine"),
carePlan(30, "第30天", "生成月度报告", "回顾本月记录,导出成长卡片", "report"),
careReminder("vaccine", "年度疫苗加强", 30, ""),
careReminder("deworm", "体内外驱虫", dewormAdult, ""),
careReminder("deworm", "体内外驱虫", 90, ""),
careReminder("weight", "体重记录", 0, "每月一次"),
careReminder("monthlyReport", "月度报告", 0, "每月 1 日"),
}
}
}
func builtinDog(stage string) []model.CareTemplateItem {
switch stage {
case "刚到家 0-30 天":
return []model.CareTemplateItem{
careTask("记录一次体重", "到家先称个底,之后每周一次", "重要", "weight"),
careTask("定点排便训练", "固定厕所位置,成功就表扬,别惩罚", "", "poop"),
careTask("室内活动 / 自家院子", "疫苗未打全前少去人多狗多的地方,先在家熟悉环境", "", ""),
carePlan(0, "今天", "安顿与环境适应", "食盆、水碗、狗窝、厕所固定位置", "taskDetail"),
carePlan(3, "第3天", "观察进食与排便", "应激期常见软便,留意精神状态", "poop"),
carePlan(7, "第7天", "第一次体重记录", "作为后续趋势基线", "weight"),
carePlan(14, "第14天", "预约疫苗 / 体检", "确认联苗、狂犬和驱虫计划", "vaccine"),
careReminder("vaccine", "首针疫苗接种", 14, ""),
careReminder("deworm", "首次体内外驱虫", 7, ""),
careReminder("weight", "体重记录", 0, "每周一次"),
careReminder("monthlyReport", "月度报告", 0, "每月 1 日"),
}
case "幼年期":
return []model.CareTemplateItem{
careTask("遛狗与基础训练", "每天 2 次,牵引、坐下、召回,社会化关键期", "重要", ""),
careTask("记录一次体重", "幼犬长得快,每周记 2 次", "重要", "weight"),
careTask("观察饮水与排便", "换粮、驱虫期留意软便", "", "poop"),
carePlan(0, "今天", "确认免疫与驱虫计划", "联苗+狂犬按月龄打,别漏针", "vaccine"),
carePlan(1, "明天", "定点排便 + 牵引训练", "打好如厕和牵引基础", "taskDetail"),
carePlan(7, "第7天", "体重趋势检查", "每周称重,稳定增长", "weight"),
carePlan(14, "第14天", "驱虫与社会化复盘", "确认驱虫到期、多接触人和环境", "medicine"),
careReminder("vaccine", "下一针联苗", 18, ""),
careReminder("deworm", "体内外驱虫", 30, ""),
careReminder("weight", "体重记录", 0, "每周二、周五"),
careReminder("monthlyReport", "月度报告", 0, "每月 1 日"),
}
case "老年期":
return []model.CareTemplateItem{
careTask("温和遛狗", "缩短时长、避免剧烈跳跃,保护关节", "重要", ""),
careTask("记录一次体重", "骤增骤减都要重视", "重要", "weight"),
careTask("观察关节 / 精神 / 饮水", "后腿无力、多饮多尿要及时就医", "", "symptom"),
carePlan(0, "今天", "老年健康自查", "精神、食欲、饮水、关节活动一起看", "taskDetail"),
carePlan(7, "第7天", "体重与饮水记录", "慢病早发现", "weight"),
carePlan(14, "第14天", "用药与慢病回顾", "整理长期用药和体检结果", "medicine"),
carePlan(30, "第30天", "月度报告 / 建议体检", "老年犬建议每半年一次体检", "report"),
careReminder("vaccine", "年度疫苗 + 狂犬加强", 30, ""),
careReminder("deworm", "体内外驱虫", 60, ""),
careReminder("weight", "体重记录", 0, "每两周一次"),
careReminder("monthlyReport", "月度报告 / 半年体检", 0, "每月 1 日"),
}
default: // 成年期
return []model.CareTemplateItem{
careTask("遛狗", "每天 2 次共 30-60 分钟,消耗精力、防拆家", "重要", ""),
careTask("记录一次体重", "每月一次,控制体重防肥胖", "", "weight"),
careTask("刷牙 / 口腔检查", "每周 2-3 次,狗牙结石高发", "", ""),
carePlan(0, "今天", "全面健康自查", "体重、精神、食欲、被毛、指甲过一遍", "taskDetail"),
carePlan(7, "第7天", "体重趋势检查", "对比上月,稳定为宜", "weight"),
carePlan(14, "第14天", "驱虫记录复盘", "遛狗接触多,确认驱虫是否到期", "medicine"),
carePlan(30, "第30天", "生成月度报告", "回顾本月记录,导出成长卡片", "report"),
careReminder("vaccine", "年度疫苗 + 狂犬加强", 30, ""),
careReminder("deworm", "体内外驱虫", 60, ""),
careReminder("weight", "体重记录", 0, "每月一次"),
careReminder("monthlyReport", "月度报告", 0, "每月 1 日"),
}