Files
sundynix-pets/pets-fe/pages/petform/petform.wxml
T
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

121 lines
5.8 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.
<nav-bar title="{{editing ? '编辑档案' : '建一份档案'}}" show-back="{{true}}"></nav-bar>
<!-- 三步进度。编辑时不分步(用户是来改某一项的,不该被按顺序走一遍) -->
<view wx:if="{{!editing}}" class="pf-steps">
<view wx:for="{{steps}}" wx:key="*this" class="pf-step {{index <= step ? 'on' : ''}}">
<view class="pf-dot">{{index < step ? '✓' : index + 1}}</view>
<text class="pf-slabel">{{item}}</text>
</view>
</view>
<scroll-view class="page-scroll" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}">
<view class="page-body pf-body">
<!-- ① 名字 + 头像 -->
<block wx:if="{{editing || step === 0}}">
<view class="card">
<view class="pf-h">先给它起个名字</view>
<view class="pf-av-wrap" bindtap="pickAvatar">
<view class="pf-av">
<image wx:if="{{form.avatar_url}}" class="pf-av-img" src="{{form.avatar_url}}" mode="aspectFill"></image>
<block wx:else><pt-icon name="photo" size="{{56}}"></pt-icon></block>
</view>
<view class="pf-av-tip">{{form.avatar_url ? '换一张' : '传张照片'}}</view>
</view>
<view class="field"><label>名字</label>
<input class="input" placeholder="例如:布丁" placeholder-class="placeholder"
value="{{form.name}}" maxlength="16" bindinput="onName"/></view>
</view>
</block>
<!-- ② 猫还是狗 + 品种 -->
<block wx:if="{{editing || step === 1}}">
<view class="card">
<view class="pf-h">它是猫还是狗?</view>
<view class="pf-species">
<view class="pf-sp {{form.species === 'cat' ? 'on' : ''}}" data-sp="cat" bindtap="pickSpecies">
<pt-icon name="cat" size="{{64}}"></pt-icon><text>猫猫</text>
</view>
<view class="pf-sp {{form.species === 'dog' ? 'on' : ''}}" data-sp="dog" bindtap="pickSpecies">
<pt-icon name="dog" size="{{64}}"></pt-icon><text>狗狗</text>
</view>
</view>
<view class="field"><label>品种</label>
<view class="picker-box {{form.breed ? '' : 'pf-empty'}}" bindtap="openBreed">
{{form.breed || '选一个品种'}}
</view>
</view>
</view>
</block>
<!-- ③ 其他基本信息 -->
<block wx:if="{{editing || step === 2}}">
<view class="card">
<view class="pf-h">再补几项,之后都能改</view>
<view class="field"><label>性别</label><view class="seg">
<view wx:for="{{genders}}" wx:key="*this" class="seg-btn {{form.gender === item ? 'selected' : ''}}"
data-v="{{item}}" bindtap="pickGender">{{item}}</view>
</view></view>
<!-- 生日和到家日分开:领养的成年猫狗生日常常是不知道的,
而「一起生活了多少天」要按到家日算。合成一个字段两件事都说不准 -->
<view class="field"><label>生日</label>
<picker mode="date" value="{{form.birthday}}" end="{{today}}" bindchange="onBirthday">
<view class="picker-box {{form.birthday ? '' : 'pf-empty'}}">{{form.birthday || '不知道可以先跳过'}}</view>
</picker></view>
<view class="field"><label>到家日期</label>
<picker mode="date" value="{{form.arrived_at}}" end="{{today}}" bindchange="onArrived">
<view class="picker-box {{form.arrived_at ? '' : 'pf-empty'}}">{{form.arrived_at || '哪天接回家的'}}</view>
</picker></view>
<view class="field"><label>当前体重(kg</label>
<input class="input" type="digit" placeholder="例如:2.8" placeholder-class="placeholder"
value="{{form.weight}}" bindinput="onWeight"/></view>
<view class="field"><label>毛色</label>
<input class="input" placeholder="例如:橘白 / 奶牛 / 黑" placeholder-class="placeholder"
value="{{form.color}}" maxlength="16" bindinput="onColor"/></view>
<view class="field"><label>当前阶段</label><view class="mini-options">
<view wx:for="{{stages}}" wx:key="*this" class="option {{form.stage === item ? 'selected' : ''}}"
data-v="{{item}}" bindtap="pickStage">{{item}}</view>
</view>
<view wx:if="{{stageAuto}}" class="tiny">按生日推算是「{{stageAuto}}」,可以手改</view>
</view>
</view>
</block>
</view>
</scroll-view>
<!-- 底部按钮固定 -->
<view class="pf-foot">
<view wx:if="{{!editing && step > 0}}" class="btn btn-ghost pf-back" bindtap="prev">上一步</view>
<view class="btn btn-primary pf-next {{saving ? 'pf-busy' : ''}}" bindtap="next">
{{saving ? '保存中…' : (editing ? '保存' : (step < 2 ? '下一步' : '完成建档'))}}
</view>
</view>
<!-- 品种选择器:左侧列表 + 右侧 A-Z 索引 -->
<view wx:if="{{breedShow}}" class="pf-mask" bindtap="closeBreed">
<view class="pf-sheet" catchtap="noop">
<view class="pf-sheet-h">
<text>选择品种</text>
<view class="link" catchtap="clearBreed">不确定</view>
</view>
<view class="pf-breed-wrap">
<scroll-view class="pf-breed-list" scroll-y="{{true}}" enhanced="{{true}}" show-scrollbar="{{false}}"
scroll-into-view="{{breedAnchor}}" scroll-with-animation="{{true}}">
<block wx:for="{{breedGroups}}" wx:key="initial">
<view class="pf-bi" id="bi-{{item.initial}}">{{item.initial}}</view>
<view wx:for="{{item.items}}" wx:for-item="b" wx:key="id"
class="pf-brow {{form.breed === b.name ? 'on' : ''}}"
data-name="{{b.name}}" bindtap="pickBreed">{{b.name}}</view>
</block>
<view wx:if="{{!breedGroups.length}}" class="empty">还没有配置品种</view>
</scroll-view>
<view class="pf-index">
<view wx:for="{{breedGroups}}" wx:key="initial" class="pf-ichar"
data-i="{{item.initial}}" bindtap="jumpInitial">{{item.initial}}</view>
</view>
</view>
</view>
</view>