3fc3cbc7d2
## 通用简易表单
洗护/清洁那 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>
76 lines
4.0 KiB
Plaintext
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)}
|