Files
sundynix-pets/pets-fe/pages/record/record.wxss
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

76 lines
4.0 KiB
Plaintext

.mini-chart{
height:256rpx;border-radius:var(--r-md);margin-top:var(--sp-4);position:relative;overflow:hidden;
background:
linear-gradient(180deg,rgba(115,190,157,.16),rgba(115,190,157,0)),
repeating-linear-gradient(0deg,#fff,#fff 60rpx,#EFE8DE 62rpx);
}
.chart-line{position:absolute;left:36rpx;right:36rpx;top:44rpx;bottom:44rpx;width:auto;height:auto}
.dot-layer{position:absolute;left:36rpx;right:36rpx;top:44rpx;bottom:44rpx}
.dot{position:absolute;width:40rpx;height:40rpx;margin:-20rpx 0 0 -20rpx;border-radius:50%;}
.dot::after{content:'';position:absolute;left:50%;top:50%;width:18rpx;height:18rpx;margin:-9rpx 0 0 -9rpx;border-radius:50%;background:#fff;border:4rpx solid var(--green);box-sizing:border-box}
.dot.on::after{width:26rpx;height:26rpx;margin:-13rpx 0 0 -13rpx;background:var(--green);box-shadow:0 0 0 6rpx rgba(115,190,157,.25)}
.trend-stats{margin-top:var(--sp-3);font-size:var(--fs-sm);color:var(--muted)}
.point-detail{
margin-top:var(--sp-3);padding:var(--sp-4);border-radius:var(--r-md);
background:var(--green-soft);border:1rpx solid #DCEFE4;
}
.pd-main{display:flex;align-items:baseline;gap:var(--sp-3)}
.pd-date{font-size:var(--fs-sm);color:var(--muted)}
.pd-weight{font-size:var(--fs-xl);font-weight:var(--fw-b);color:var(--green-ink)}
.pd-delta{font-size:var(--fs-sm);font-weight:var(--fw-b)}
.pd-delta.up{color:var(--red-ink)}
.pd-delta.down{color:var(--green-ink)}
.pd-note{margin-top:var(--sp-2);font-size:var(--fs-md);color:var(--text-2);line-height:1.5}
.pd-note.muted{color:var(--muted)}
.chart-hint{margin-top:var(--sp-2);font-size:var(--fs-cap);color:var(--muted);text-align:center}
.health-timeline{display:flex;flex-direction:column;gap:var(--sp-2)}
.health-event{display:flex;gap:var(--sp-3);background:var(--surface-2);border-radius:var(--r-md);padding:var(--sp-4)}
/* 底色和文字色由 .tone-N 提供(记录类型决定),这里只管形状 */
.event-dot{
width:64rpx;height:64rpx;border-radius:var(--r-sm);flex:none;
display:flex;align-items:center;justify-content:center;
}
.he-b{font-size:var(--fs-md);font-weight:var(--fw-b)}
.he-p{color:var(--muted);font-size:var(--fs-sm);line-height:1.45;margin-top:6rpx}
.he-body{flex:1;min-width:0}
.he-img{margin-top:var(--sp-2);width:220rpx;height:220rpx;border-radius:var(--r-sm)}
.tl-tip{margin-top:var(--sp-3);text-align:center;color:var(--muted);font-size:var(--fs-cap)}
.tl-more{
margin-top:var(--sp-3);padding:var(--sp-3);text-align:center;color:var(--primary-dark);
background:var(--surface-2);border-radius:var(--r-md);font-size:var(--fs-sm);font-weight:var(--fw-b);
}
/* 健康洞察 */
.ins{border-radius:var(--r-md);padding:var(--sp-4);margin-bottom:var(--sp-2)}
.ins:last-child{margin-bottom:0}
.ins-info{background:var(--surface-2)}
.ins-warn{background:var(--primary-soft)}
.ins-alert{background:var(--red-soft)}
.ins-head{display:flex;align-items:flex-start;gap:var(--sp-2)}
.ins-ic{flex:none;margin-top:2rpx}
.ins-info .ins-ic{color:var(--green-ink)}
.ins-warn .ins-ic{color:var(--primary-ink)}
.ins-alert .ins-ic{color:var(--red-ink)}
.ins-title{flex:1;font-size:var(--fs-md);font-weight:var(--fw-b);line-height:1.4}
.ins-detail{color:var(--text-2);font-size:var(--fs-sm);line-height:1.6;margin-top:var(--sp-2)}
.ins-ev{color:var(--muted);font-size:var(--fs-cap);margin-top:var(--sp-2)}
/* ===== 记一笔的分组 =====
四组各一个色系,色值全走 token 的 soft/ink 二件套,没有新色。
.quick 的配色由 .tone-N 决定(app.wxss 里已有),这里只管组标题和留白 */
.tg{margin-bottom:var(--sp-4)}
.tg:last-of-type{margin-bottom:0}
.tg-head{
display:flex;align-items:center;gap:var(--sp-2);
font-size:var(--fs-md);font-weight:var(--fw-b);margin-bottom:var(--sp-3);
}
.tg-bar{width:6rpx;height:26rpx;border-radius:3rpx;background:currentColor}
.tg-n{margin-left:auto;font-size:var(--fs-cap);font-weight:var(--fw);color:var(--muted2)}
.tg.tone-1 .tg-head{color:var(--primary-ink)}
.tg.tone-2 .tg-head{color:var(--green-ink)}
.tg.tone-3 .tg-head{color:var(--blue-ink)}
.tg.tone-4 .tg-head{color:var(--purple-ink)}