Files
sundynix-pets/pets-fe/components/bottom-sheet/bottom-sheet.wxml
T
Blizzard 3fc3cbc7d2 feat(fe): 记录页 24 种 4 组,弹层加通用简易表单
## 通用简易表单
洗护/清洁那 15 种只需要「什么时候 + 备注 + 可选照片」。弹层现在是 28 个
wx:elif 手写分支(402 行),各写一个会推到 700 行,而且每加一种类型都要发版。

加一个 wx:elif="{{isSimple}}",isSimple 由 JS 按后端返回的 form 字段算,
和上面那 9 种永不重叠。插在 photo 之后、提醒中心之前,没动任何现有分支的顺序。

备注给了逐类型的具体占位提示(「用了什么沐浴露、有没有吹干」),
比「请输入备注」有用得多——用户看到提示才知道这栏该写什么。

## 一个不写就会静默出错的地方
dayToISO():后端用 time.Parse(time.RFC3339) 解 occurred_at,只给日期
("2026-07-30")它解不出来会**静默回退成 time.Now()**——用户选「昨天洗澡」
会存成今天,而且不报错。

时区必须带真实偏移:转成 UTC 的 Z 形式,落库再转回本地时会把边界日期挪一天
(首页任务重复生成那个 bug 就是这么来的)。取正午同样是为了远离日界。

## 四处写死的类型列表全删
  RECORD_ITEMS   record.js  记录页 9 宫格
  QUICK_ITEMS    home.js    首页 8 宫格
  TYPE_TONE      record.js  时间轴色调(9 种写死,新类型会全掉到橙色一片分不清)
  TASK_SHEETS    弹层       任务关联记录类型的下拉(只有 6 种,加了类型选不到)

全部改成读 utils/recordTypes.js 这份共用缓存。缓存 load() 只真正请求一次,
并发调用共用同一个 promise;isSimple/label/groups 是同步的,弹层打开时
不该再等一次网络。

首页 8 宫格改成取后端前 8 个(按分组顺序再按 sort),后台调 sort 就能换首屏
露出哪几个;全部 24 种在记录页。

分组色系(daily橙/health绿/care紫/clean蓝)留在前端,后端只存 group key——
改配色不用动数据。

## 联调(预生产库实跑)
  15 种新类型  全部落库,且选「昨天」没被存成今天(15/15)
  原有 9 种    逐一回归,写库 emoji 原样;weight 回写宠物档案 → 4.5kg ✓
  时间轴       24 条混排,色调分布 6/7/5/6,没有一条查不到类型
  体重趋势     仍只有 1 个点(没被 24 条记录污染)
  周报/首页汇总  正常

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 09:44:07 +08:00

486 lines
31 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<wxs module="u">
module.exports.sel = function (map, key, index, def) {
var v = map[key];
if (v === undefined || v === null) v = def;
return v === index;
};
</wxs>
<view class="overlay {{show ? 'show' : ''}}" bindtap="onMaskTap">
<view class="sheet {{innerType === 'comments' ? 'sheet-cmp' : ''}}" catchtap="noop">
<view class="sheetbar"></view>
<!-- 评论:头 + 滚动列表 + 常驻输入栏。输入栏不能放进滚动区,
否则列表一滚它就跟着走,点评论回复时还得再找回来 -->
<block wx:if="{{innerType === 'comments'}}">
<view class="cmp-head">共 {{total}} 条评论</view>
<scroll-view class="cmp-list" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view wx:for="{{comments}}" wx:key="id" class="cm"
bindtap="onReplyTo" data-id="{{item.id}}" data-name="{{item.author_name}}">
<view class="cm-av">{{item.initial}}</view>
<view class="cm-body">
<view class="cm-name">{{item.author_name}}<text wx:if="{{item.is_self}}" class="mine-tag">我</text></view>
<view class="cm-text">{{item.content}}</view>
<view wx:if="{{item.imgs.length}}" class="cm-imgs">
<image wx:for="{{item.imgs}}" wx:for-item="u" wx:key="*this" class="cm-img"
src="{{u}}" mode="aspectFill" catchtap="onPreviewCommentImage"
data-urls="{{item.imgs}}" data-cur="{{u}}"></image>
</view>
<view class="cm-meta">
<text>{{item.timeText}}</text>
<text class="cm-reply-btn">回复</text>
<text wx:if="{{item.is_self}}" class="cm-del" catchtap="onDeleteComment"
data-id="{{item.id}}" data-self="{{true}}">删除</text>
</view>
<!-- 回复只缩进一层,再深手机上没法读 -->
<view wx:if="{{item.replies.length}}" class="cm-replies">
<view wx:for="{{item.replies}}" wx:for-item="r" wx:key="id" class="cm-reply"
catchtap="onReplyTo" data-id="{{r.id}}" data-name="{{r.author_name}}">
<view class="cm-av cm-av-sm">{{r.initial}}</view>
<view class="cm-body">
<view class="cm-name">
{{r.author_name}}<text wx:if="{{r.is_self}}" class="mine-tag">我</text>
<text wx:if="{{r.reply_to_name}}" class="cm-at"> 回复 {{r.reply_to_name}}</text>
</view>
<view class="cm-text">{{r.content}}</view>
<view class="cm-meta">
<text>{{r.timeText}}</text>
<text class="cm-reply-btn">回复</text>
<text wx:if="{{r.is_self}}" class="cm-del" catchtap="onDeleteComment"
data-id="{{r.id}}" data-self="{{true}}">删除</text>
</view>
</view>
</view>
<view wx:if="{{item.reply_n > item.replies.length}}" class="cm-more"
catchtap="onExpandReplies" data-id="{{item.id}}" data-index="{{index}}">
— 展开全部 {{item.reply_n}} 条回复
</view>
</view>
</view>
</view>
<view wx:if="{{!comments.length}}" class="empty lg">还没有评论,来抢个沙发</view>
</scroll-view>
<view class="cmp-dock" style="padding-bottom:{{kbHeight ? kbHeight + 'px' : 'calc(20rpx + env(safe-area-inset-bottom))'}}">
<view wx:if="{{replyTo.name}}" class="cm-replying">
<text>回复 {{replyTo.name}}</text>
<view class="cm-cancel" catchtap="onCancelReply"><pt-icon name="close" size="{{24}}"></pt-icon></view>
</view>
<view wx:if="{{commentImages.length}}" class="img-picker" style="margin-bottom:12rpx">
<view wx:for="{{commentImages}}" wx:key="id" class="img-thumb">
<image src="{{item.url}}" mode="aspectFill"></image>
<view class="img-del" catchtap="onRemoveCommentImage" data-index="{{index}}"><pt-icon name="close" size="{{24}}"></pt-icon></view>
</view>
</view>
<textarea class="textarea cm-ta" placeholder="{{replyTo.name ? '回复 @' + replyTo.name : '有话要说,快来评论'}}"
placeholder-class="placeholder" value="{{commentText}}" bindinput="onCommentInput"
focus="{{cmFocus}}" bindfocus="onCommentFocus" bindblur="onCommentBlur"
maxlength="500" auto-height="{{true}}" show-confirm-bar="{{false}}"
adjust-position="{{false}}" cursor-spacing="12"></textarea>
<view class="cm-bar">
<view class="cm-pic" catchtap="onPickCommentImages">
<pt-icon name="photo" size="{{36}}"></pt-icon>
</view>
<text class="cm-count">{{commentText.length}}/500</text>
<view class="cm-send {{commentText ? 'on' : ''}}" catchtap="onSendComment">发送</view>
</view>
</view>
</block>
<scroll-view wx:if="{{innerType !== 'comments'}}" class="sheet-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<!-- 记录体重 -->
<block wx:if="{{innerType === 'weight'}}">
<view class="sheet-h3">记录体重</view>
<view class="sheet-p">趋势比单次数值更重要。幼年期建议每周记录 1-2 次。</view>
<view class="field"><label>{{pet.name}} 当前体重</label>
<input class="input" value="{{wInput}}" bindinput="onWInput" type="digit"/></view>
<view class="field"><label>备注</label>
<textarea class="textarea" placeholder="例如:最近食欲不错,活动量正常" placeholder-class="placeholder" value="{{wNote}}" bindinput="onWNote"></textarea></view>
<button class="btn btn-primary btn-block" bindtap="onSaveWeight">保存记录</button>
</block>
<!-- 记录便便 -->
<block wx:elif="{{innerType === 'poop'}}">
<view class="sheet-h3">记录便便</view>
<view class="sheet-p">选择状态并补充备注,几秒完成。</view>
<view class="field"><label>状态</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'poopState',0,0)?'selected':''}}" data-group="poopState" data-index="0" bindtap="onSeg">正常</view>
<view class="seg-btn {{u.sel(segSel,'poopState',1,0)?'selected':''}}" data-group="poopState" data-index="1" bindtap="onSeg">软便</view>
<view class="seg-btn {{u.sel(segSel,'poopState',2,0)?'selected':''}}" data-group="poopState" data-index="2" bindtap="onSeg">拉稀</view>
</view></view>
<view class="field"><label>颜色/备注</label>
<textarea class="textarea" placeholder="颜色、次数、是否带血、是否有异味等" placeholder-class="placeholder" value="{{poopNote}}" bindinput="onPoopNote"></textarea></view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存记录</button>
</block>
<!-- 记录饮食 -->
<block wx:elif="{{innerType === 'food'}}">
<view class="sheet-h3">记录饮食</view>
<view class="field"><label>今天吃了什么?</label>
<input class="input" placeholder="例如:幼猫粮 45g" placeholder-class="placeholder" value="{{foodText}}" bindinput="onFoodText"/></view>
<view class="field"><label>食欲</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'food',0,0)?'selected':''}}" data-group="food" data-index="0" bindtap="onSeg">正常</view>
<view class="seg-btn {{u.sel(segSel,'food',1,0)?'selected':''}}" data-group="food" data-index="1" bindtap="onSeg">偏少</view>
<view class="seg-btn {{u.sel(segSel,'food',2,0)?'selected':''}}" data-group="food" data-index="2" bindtap="onSeg">不吃</view>
</view></view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存记录</button>
</block>
<!-- 异常观察 -->
<block wx:elif="{{innerType === 'symptom'}}">
<view class="sheet-h3">异常观察</view>
<view class="sheet-p">如实描述异常,AI 会给出观察建议与就医提示(非诊断)。</view>
<view class="field"><label>发生了什么?</label><view class="mini-options">
<view class="option {{u.sel(optSel,'symp',0,0)?'selected':''}}" data-group="symp" data-index="0" bindtap="onOpt">呕吐</view>
<view class="option {{u.sel(optSel,'symp',1,0)?'selected':''}}" data-group="symp" data-index="1" bindtap="onOpt">拉稀</view>
<view class="option {{u.sel(optSel,'symp',2,0)?'selected':''}}" data-group="symp" data-index="2" bindtap="onOpt">精神差</view>
<view class="option {{u.sel(optSel,'symp',3,0)?'selected':''}}" data-group="symp" data-index="3" bindtap="onOpt">皮肤红</view>
</view></view>
<view class="field"><label>持续多久?</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'dur',0,0)?'selected':''}}" data-group="dur" data-index="0" bindtap="onSeg">刚刚</view>
<view class="seg-btn {{u.sel(segSel,'dur',1,0)?'selected':''}}" data-group="dur" data-index="1" bindtap="onSeg">半天</view>
<view class="seg-btn {{u.sel(segSel,'dur',2,0)?'selected':''}}" data-group="dur" data-index="2" bindtap="onSeg">1天以上</view>
</view></view>
<view class="field"><label>精神状态</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'spirit',0,0)?'selected':''}}" data-group="spirit" data-index="0" bindtap="onSeg">正常</view>
<view class="seg-btn {{u.sel(segSel,'spirit',1,0)?'selected':''}}" data-group="spirit" data-index="1" bindtap="onSeg">一般</view>
<view class="seg-btn {{u.sel(segSel,'spirit',2,0)?'selected':''}}" data-group="spirit" data-index="2" bindtap="onSeg">明显变差</view>
</view></view>
<button class="btn btn-primary btn-block" bindtap="onGenRisk">生成观察建议</button>
</block>
<!-- AI 观察建议 -->
<block wx:elif="{{innerType === 'risk'}}">
<view class="sheet-h3">AI 观察建议</view>
<view class="risk-box"><pt-icon name="warn" size="{{32}}"></pt-icon> 风险等级:{{riskData ? riskData.risk_level : '中'}}</view>
<view class="sheet-p"><text class="bold">可能原因:</text>{{riskData ? riskData.causes : '可能与换粮、应激或消化不适有关。不要把这里写成诊断结论。'}}</view>
<view class="sheet-p"><text class="bold">建议:</text>{{riskData ? riskData.suggestion : '继续观察精神、食欲和排便;暂停新食物;记录呕吐或腹泻次数。'}}</view>
<view class="sheet-p"><text class="bold">建议就医:</text>{{riskData ? riskData.seek_care : '如果持续超过 24 小时,或伴随便血、精神明显变差、频繁呕吐,建议尽快就医。'}}</view>
<view class="sheet-actions">
<button class="btn btn-ghost" bindtap="onSave">保存记录</button>
<button class="btn btn-primary" data-type="vetSummary" bindtap="goSheet">就医摘要</button>
</view>
</block>
<!-- 就医前摘要 -->
<block wx:elif="{{innerType === 'vetSummary'}}">
<view class="sheet-h3">就医前摘要</view>
<view class="sheet-p pre">宠物:{{pet.name}}
阶段:{{pet.stage}}
当前体重:{{pet.weight}}
近期重点:疫苗期、换粮观察、排便记录
建议携带:排便/呕吐照片、饮食变化、疫苗驱虫记录。</view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存摘要</button>
</block>
<!-- 记录用药 -->
<block wx:elif="{{innerType === 'medicine'}}">
<view class="sheet-h3">记录用药</view>
<view class="field"><label>药品名称</label><input class="input" placeholder="例如:体内驱虫药" placeholder-class="placeholder" value="{{medName}}" bindinput="onMedName"/></view>
<view class="field"><label>剂量/备注</label><input class="input" placeholder="例如:按 2.8kg 剂量" placeholder-class="placeholder" value="{{medDose}}" bindinput="onMedDose"/></view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存记录</button>
</block>
<!-- 记一笔消费 -->
<block wx:elif="{{innerType === 'cost'}}">
<view class="sheet-h3">记一笔消费</view>
<view class="field"><label>金额</label><input class="input" placeholder="例如:168" placeholder-class="placeholder" type="digit" value="{{costAmount}}" bindinput="onCostInput"/></view>
<view class="field"><label>类别</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'cost',0,0)?'selected':''}}" data-group="cost" data-index="0" bindtap="onSeg">食品</view>
<view class="seg-btn {{u.sel(segSel,'cost',1,0)?'selected':''}}" data-group="cost" data-index="1" bindtap="onSeg">医疗</view>
<view class="seg-btn {{u.sel(segSel,'cost',2,0)?'selected':''}}" data-group="cost" data-index="2" bindtap="onSeg">用品</view>
</view></view>
<view class="field"><label>备注</label><input class="input" placeholder="例如:幼猫粮" placeholder-class="placeholder" value="{{costNote}}" bindinput="onCostNote"/></view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存记录</button>
</block>
<!-- 疫苗提醒 -->
<block wx:elif="{{innerType === 'vaccine'}}">
<view class="sheet-h3">疫苗提醒</view>
<view class="sheet-p">为 {{pet.name}} 设置疫苗提醒。接种前后避免洗澡和长途出行。</view>
<view class="field"><label>提醒日期</label>
<picker mode="date" value="{{dateVals.vaccine}}" data-key="vaccine" bindchange="onDate">
<view class="picker-box">{{dateVals.vaccine}}</view>
</picker></view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存提醒</button>
</block>
<!-- 驱虫提醒 -->
<block wx:elif="{{innerType === 'deworm'}}">
<view class="sheet-h3">驱虫提醒</view>
<view class="sheet-p">设置下次驱虫日期,到点提醒你。</view>
<view class="field"><label>下次驱虫日期</label>
<picker mode="date" value="{{dateVals.deworm}}" data-key="deworm" bindchange="onDate">
<view class="picker-box">{{dateVals.deworm}}</view>
</picker></view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存提醒</button>
</block>
<!-- 成长照片 -->
<block wx:elif="{{innerType === 'photo'}}">
<view class="sheet-h3">成长照片</view>
<view class="sheet-p">上传成长照片,用于宠物档案与成长报告。</view>
<view class="poster" style="margin-bottom:28rpx">
<view class="poster-avatar">{{pet.emoji}}</view>
<view class="bold" style="font-size:30rpx">{{pet.name}} 的成长照片</view>
<view class="muted" style="font-size:24rpx;margin-top:12rpx">支持 jpg / png,单张不超过 10MB</view>
</view>
<button class="btn btn-primary btn-block" bindtap="onSavePhoto">选择图片上传</button>
</block>
<!-- 通用简易记录。洗护/清洁那 15 种共用这一支:
它们只需要「什么时候 + 备注 + 可选照片」,各写一个 wx:elif 会把这个
文件从 400 行推到 700 行,而且每加一种类型都要发版。
isSimple 由 JS 按后端返回的 form 字段算,和上面那 9 种永不重叠 -->
<block wx:elif="{{isSimple}}">
<view class="sheet-h3">记录{{simpleLabel}}</view>
<view class="sheet-p">选个时间、写句备注就行,需要的话可以附张照片。</view>
<view class="field"><label>什么时候</label>
<picker mode="date" value="{{simpleDate}}" bindchange="onSimpleDate">
<view class="picker-box">{{simpleDate}}</view>
</picker></view>
<view class="field"><label>备注</label>
<textarea class="textarea" placeholder="{{simplePlaceholder}}" placeholder-class="placeholder"
value="{{simpleNote}}" bindinput="onSimpleNote"></textarea></view>
<view class="field"><label>照片(可选)</label>
<view class="img-picker">
<view wx:for="{{simpleImages}}" wx:key="id" class="img-thumb">
<image src="{{item.url}}" mode="aspectFill"></image>
<view class="img-del" catchtap="onRemoveSimpleImage" data-index="{{index}}"><pt-icon name="close" size="{{24}}"></pt-icon></view>
</view>
<view wx:if="{{simpleImages.length < 1}}" class="img-add" bindtap="onPickSimpleImage"><pt-icon name="plus" size="{{48}}"></pt-icon></view>
</view>
</view>
<button class="btn btn-primary btn-block" bindtap="onSave">保存记录</button>
</block>
<!-- 提醒中心 -->
<block wx:elif="{{innerType === 'reminders'}}">
<view class="sheet-h3">提醒中心</view>
<view class="sheet-p">疫苗、驱虫这些别靠记,设好日期到时候提醒你。</view>
<view wx:for="{{reminders}}" wx:key="id" class="mtask-row">
<view class="mtask-body">
<text class="mtask-b">{{item.title}}</text>
<view class="mtask-p">{{item.when}}</view>
</view>
<view class="mtask-op" catchtap="onEditReminder" data-index="{{index}}">改</view>
<view class="mtask-op del" catchtap="onDeleteReminder" data-index="{{index}}">删</view>
</view>
<view wx:if="{{!reminders.length}}" class="sheet-p">还没有提醒,下面加一条吧。</view>
<view class="field" style="margin-top:12rpx"><label>{{remForm.id ? '修改提醒' : '新增提醒'}}</label>
<input class="input" placeholder="提醒名,例如:第 3 针疫苗" placeholder-class="placeholder" value="{{remForm.title}}" bindinput="onRemTitle"/></view>
<view class="field"><label>类型 / 到期日</label>
<view class="mtask-form-row">
<picker mode="selector" range="{{remTypeLabels}}" value="{{remForm.typeIdx}}" bindchange="onRemType">
<view class="picker-box">{{remTypeLabels[remForm.typeIdx]}}</view>
</picker>
<picker mode="date" value="{{remForm.date}}" bindchange="onRemDate">
<view class="picker-box">{{remForm.date || '选择到期日'}}</view>
</picker>
</view>
</view>
<view class="field"><label>重复频率(可选)</label>
<input class="input" placeholder="例如:每月一次;填了可不选到期日" placeholder-class="placeholder" value="{{remForm.freq}}" bindinput="onRemFreq"/></view>
<button class="btn btn-primary btn-block" bindtap="onSaveReminder">{{remForm.id ? '保存修改' : '添加提醒'}}</button>
</block>
<!-- 任务详情 -->
<!-- 成长海报 -->
<block wx:elif="{{innerType === 'poster'}}">
<view class="poster">
<view class="poster-h3">{{pet.name}} 的成长报告</view>
<view class="poster-avatar">{{pet.emoji}}</view>
<view class="muted">{{pet.age}}{{pet.weight}}{{pet.stage}}</view>
<view class="poster-list pre">✓ 完成任务 {{poster ? poster.tasks_completed : 0}} 项
✓ 体重记录 {{poster ? poster.weight_records : 0}} 次
✓ 疫苗记录 {{poster ? poster.vaccine_records : 0}} 次
✓ 高风险异常 {{poster ? poster.high_risk_count : 0}} 次</view>
<view class="bold">健康状态:{{poster ? poster.headline : '稳定成长'}}</view>
<view class="muted" style="font-size:24rpx;margin-top:20rpx">生成自:肉垫计划</view>
</view>
<view class="sheet-actions" style="margin-top:28rpx">
<button class="btn btn-ghost" open-type="share">分享给朋友</button>
<button class="btn btn-primary" bindtap="onSavePoster" disabled="{{posterSaving}}">
{{posterSaving ? '生成中…' : '保存到相册'}}
</button>
</view>
<!-- 离屏画布:海报要存成图片才能进相册。不能用 display:none,否则取不到节点 -->
<canvas type="2d" id="posterCanvas" class="poster-canvas"></canvas>
</block>
<!-- 报告详情 -->
<block wx:elif="{{innerType === 'reportDetail'}}">
<view class="sheet-h3">本周成长报告</view>
<view class="sheet-p">{{reportDetail ? reportDetail.summary : '正在汇总本周数据…'}}</view>
<view wx:if="{{reportDetail}}" class="sheet-p"><text class="bold">下周重点:</text>{{reportDetail.next_week_focus}}</view>
<button class="btn btn-primary btn-block" data-type="poster" bindtap="goSheet">生成分享卡片</button>
</block>
<!-- Pro 会员 -->
<block wx:elif="{{innerType === 'pro'}}">
<view class="sheet-h3">肉垫计划 Pro</view>
<view class="sheet-p">解锁 365 天计划、PDF 健康档案、月度报告、多宠物管理与年度账单。</view>
<view class="check-list">
<view wx:for="{{proInfo.features}}" wx:key="*this" class="check selected"><view class="box"><pt-icon name="check" size="{{26}}"></pt-icon></view>{{item}}</view>
</view>
<button wx:if="{{proInfo.status === 'active'}}" class="btn btn-soft btn-block" bindtap="close"><pt-icon name="check" size="{{30}}"></pt-icon>已开通 Pro</button>
<button wx:else class="btn btn-soft btn-block" disabled="true">即将开放</button>
<view wx:if="{{proInfo.status !== 'active'}}" class="sheet-p" style="text-align:center;margin-top:16rpx;font-size:24rpx">
会员功能还在准备中,暂未开放购买。
</view>
</block>
<!-- 添加宠物 -->
<block wx:elif="{{innerType === 'addPet' || innerType === 'editPet'}}">
<view class="sheet-h3">{{innerType === 'editPet' ? '编辑档案' : '添加毛孩子'}}</view>
<view class="field"><label>名字</label><input class="input" placeholder="例如:布丁" placeholder-class="placeholder" value="{{addName}}" bindinput="onAddName"/></view>
<view class="field"><label>类型</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'addType',0,0)?'selected':''}}" data-group="addType" data-index="0" bindtap="onSeg">猫猫</view>
<view class="seg-btn {{u.sel(segSel,'addType',1,0)?'selected':''}}" data-group="addType" data-index="1" bindtap="onSeg">狗狗</view>
</view></view>
<view class="field"><label>性别</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'addGender',0,0)?'selected':''}}" data-group="addGender" data-index="0" bindtap="onSeg">男孩</view>
<view class="seg-btn {{u.sel(segSel,'addGender',1,0)?'selected':''}}" data-group="addGender" data-index="1" bindtap="onSeg">女孩</view>
<view class="seg-btn {{u.sel(segSel,'addGender',2,0)?'selected':''}}" data-group="addGender" data-index="2" bindtap="onSeg">不确定</view>
</view></view>
<view class="field"><label>生日 / 到家时间</label>
<picker mode="date" value="{{addBirthday}}" bindchange="onAddBirthday">
<view class="picker-box">{{addBirthday || '选择日期'}}</view>
</picker></view>
<view class="field"><label>毛色</label><input class="input" placeholder="例如:橘白 / 奶牛 / 黑" placeholder-class="placeholder" value="{{addColor}}" bindinput="onAddColor"/></view>
<view class="field"><label>品种</label><input class="input" placeholder="例如:中华田园猫 / 柯基" placeholder-class="placeholder" value="{{addBreed}}" bindinput="onAddBreed"/></view>
<view class="field"><label>当前体重</label><input class="input" placeholder="例如:2.8" placeholder-class="placeholder" type="digit" value="{{addWeight}}" bindinput="onAddWeight"/></view>
<view class="field"><label>当前阶段</label><view class="mini-options">
<view class="option {{u.sel(optSel,'addStage',0,0)?'selected':''}}" data-group="addStage" data-index="0" bindtap="onOpt">刚到家</view>
<view class="option {{u.sel(optSel,'addStage',1,0)?'selected':''}}" data-group="addStage" data-index="1" bindtap="onOpt">幼年期</view>
<view class="option {{u.sel(optSel,'addStage',2,0)?'selected':''}}" data-group="addStage" data-index="2" bindtap="onOpt">成年期</view>
<view class="option {{u.sel(optSel,'addStage',3,0)?'selected':''}}" data-group="addStage" data-index="3" bindtap="onOpt">老年期</view>
</view></view>
<button class="btn btn-primary btn-block" bindtap="onPetSubmit">{{innerType === 'editPet' ? '保存修改' : '添加宠物'}}</button>
<button wx:if="{{innerType === 'editPet'}}" class="btn btn-block del-btn" style="margin-top:16rpx" bindtap="onDeletePet">删除该宠物</button>
</block>
<!-- 发布图文 -->
<block wx:elif="{{innerType === 'createPost'}}">
<view class="sheet-h3">发布图文</view>
<view class="sheet-p">选择发布身份,分享你的养宠日常。</view>
<view class="field"><label>发布身份</label><view class="seg">
<view class="seg-btn {{u.sel(segSel,'ident',0,0)?'selected':''}}" data-group="ident" data-index="0" bindtap="onSeg">{{pet.name}}</view>
<view class="seg-btn {{u.sel(segSel,'ident',1,0)?'selected':''}}" data-group="ident" data-index="1" bindtap="onSeg">匿名宠友</view>
<view class="seg-btn {{u.sel(segSel,'ident',2,0)?'selected':''}}" data-group="ident" data-index="2" bindtap="onSeg">官方笔记</view>
</view></view>
<view class="field"><label>内容</label>
<textarea class="textarea" placeholder="分享养宠日常、求助问题、经验笔记..." placeholder-class="placeholder" value="{{postContent}}" bindinput="onPostInput"></textarea></view>
<view class="mini-options">
<view class="option {{u.sel(optSel,'ptag',0,0)?'selected':''}}" data-group="ptag" data-index="0" bindtap="onOpt">晒宠</view>
<view class="option {{u.sel(optSel,'ptag',1,0)?'selected':''}}" data-group="ptag" data-index="1" bindtap="onOpt">求助</view>
<view class="option {{u.sel(optSel,'ptag',2,0)?'selected':''}}" data-group="ptag" data-index="2" bindtap="onOpt">经验</view>
<view class="option {{u.sel(optSel,'ptag',3,0)?'selected':''}}" data-group="ptag" data-index="3" bindtap="onOpt">避坑</view>
</view>
<view class="field"><label>图片(可选,仅图片)</label>
<view class="img-picker">
<view wx:for="{{postImages}}" wx:key="id" class="img-thumb">
<image src="{{item.url}}" mode="aspectFill"></image>
<view class="img-del" catchtap="onRemovePostImage" data-index="{{index}}"><pt-icon name="close" size="{{24}}"></pt-icon></view>
</view>
<view wx:if="{{postImages.length < 9}}" class="img-add" bindtap="onPickPostImages"><pt-icon name="plus" size="{{48}}"></pt-icon></view>
</view>
</view>
<button class="btn btn-primary btn-block" bindtap="onCreatePost">发布到宠友圈</button>
</block>
<!-- 管理任务 -->
<block wx:elif="{{innerType === 'manageTasks'}}">
<view class="sheet-h3">管理任务</view>
<view class="sheet-p">增删改今日任务,改动会自动顺延到以后每天。</view>
<view wx:for="{{manageTasks}}" wx:key="id" class="mtask-row">
<view class="mtask-body">
<text class="mtask-b">{{item.title}}<text wx:if="{{item.priority}}" class="mtask-pri">{{item.priority}}</text></text>
<view wx:if="{{item.description}}" class="mtask-p">{{item.description}}</view>
</view>
<view class="mtask-op" catchtap="onEditTaskItem" data-index="{{index}}">改</view>
<view class="mtask-op del" catchtap="onDeleteTaskItem" data-index="{{index}}">删</view>
</view>
<view wx:if="{{!manageTasks.length}}" class="sheet-p">今天还没有任务,下面加一条吧。</view>
<view class="field" style="margin-top:12rpx"><label>{{taskForm.id ? '修改任务' : '新增任务'}}</label>
<input class="input" placeholder="任务名,例如:喂驱虫药" placeholder-class="placeholder" value="{{taskForm.title}}" bindinput="onTaskTitle"/></view>
<view class="field"><input class="input" placeholder="说明(可选)" placeholder-class="placeholder" value="{{taskForm.description}}" bindinput="onTaskDesc"/></view>
<view class="field"><label>优先级 / 关联记录</label>
<view class="mtask-form-row">
<view class="seg-btn {{taskForm.priority === '重要' ? 'selected' : ''}}" catchtap="onTaskPriority">重要</view>
<picker mode="selector" range="{{taskSheetLabels}}" value="{{taskForm.sheetIdx}}" bindchange="onTaskSheet">
<view class="picker-box">关联:{{taskSheetLabels[taskForm.sheetIdx]}}</view>
</picker>
</view>
</view>
<button class="btn btn-primary btn-block" bindtap="onSaveTask">{{taskForm.id ? '保存修改' : '添加任务'}}</button>
</block>
<!-- 评论 -->
<!-- 多宠物管理 -->
<block wx:elif="{{innerType === 'managePets'}}">
<view class="sheet-h3">多宠物管理</view>
<view class="sheet-p">点一只切换为当前宠物,或编辑它的档案。</view>
<view wx:for="{{myPets}}" wx:key="id" class="mtask-row">
<view class="mtask-body" catchtap="onSwitchPet" data-id="{{item.id}}">
<text class="mtask-b">{{item.emoji}} {{item.name}}<text wx:if="{{item.current}}" class="mtask-pri">当前</text></text>
<view class="mtask-p">{{item.meta}}</view>
</view>
<view class="mtask-op" catchtap="onEditPetFromList" data-id="{{item.id}}">编辑</view>
</view>
<view wx:if="{{!myPets.length}}" class="sheet-p">还没有毛孩子。</view>
<button class="btn btn-primary btn-block" style="margin-top:16rpx" data-type="addPet" bindtap="goSheet"> 添加毛孩子</button>
</block>
<!-- 导出健康档案 -->
<block wx:elif="{{innerType === 'exportData'}}">
<view class="sheet-h3">导出健康档案</view>
<view class="sheet-p">整理成一段文字,可复制后发给医生或存到备忘录。</view>
<view class="export-box">{{exportText || '正在整理…'}}</view>
<button class="btn btn-primary btn-block" bindtap="onCopyExport">复制全部内容</button>
</block>
<!-- 意见反馈 -->
<block wx:elif="{{innerType === 'feedback'}}">
<view class="sheet-h3">意见反馈</view>
<block wx:if="{{!fbDone}}">
<view class="sheet-p">用着哪儿别扭、想要什么功能,都可以告诉我们。</view>
<view class="field"><label>你的反馈</label>
<textarea class="textarea" placeholder="例如:希望能记录洗澡时间" placeholder-class="placeholder" value="{{fbContent}}" bindinput="onFbContent"></textarea></view>
<view class="field"><label>联系方式(可选)</label>
<input class="input" placeholder="微信号或邮箱,方便回复你" placeholder-class="placeholder" value="{{fbContact}}" bindinput="onFbContact"/></view>
<button class="btn btn-primary btn-block" bindtap="onSubmitFeedback" disabled="{{saving}}">{{saving ? '提交中…' : '提交反馈'}}</button>
</block>
<block wx:else>
<view class="sheet-p">已收到,谢谢你的反馈 🐾</view>
<button class="btn btn-primary btn-block" bindtap="close">好的</button>
</block>
</block>
<!-- 关于我们 -->
<block wx:elif="{{innerType === 'about'}}">
<view class="sheet-h3">关于肉垫计划</view>
<view class="sheet-p pre">肉垫计划是给新手养宠人做的照护记录工具。
按猫狗的品类和成长阶段生成每日照护任务和养护计划,随手记录体重、饮食、排便、用药、疫苗和开支,疫苗驱虫到期前提醒你,并把这些整理成成长报告。
版本:v0.2
反馈:我的 → 意见反馈</view>
<view class="sheet-p" style="color:var(--muted);font-size:24rpx">本小程序提供的是记录与观察建议,不能替代医生诊断。宠物出现持续异常请及时就医。</view>
<button class="btn btn-primary btn-block" bindtap="close">知道了</button>
</block>
</scroll-view>
</view>
</view>