Files
sundynix-pets/pets-fe/pages/ai/ai.wxss
T
Blizzard cecc7f4cbb feat(fe): Phase B —— 计划并进首页,日期条能展开成整月
## 日期条 → 可展开日历
首页那条七天日期带下面加了「展开整月」。展开后是整月网格(有安排的
日子带绿点),点任意一天,任务卡跟着切到那天。收起来还是七天,默认
不拉日历接口。

这块原来是计划页的「日历」tab,现在从计划页整个摘掉了——「哪天要做
什么」和「今天要做什么」本来就是一件事,分在两个 tab 里只是让人多点
两下。日历样式(.cal-* / .day-detail / .dd-*)跟着从 plan.wxss 搬到
home.wxss,plan.wxss 里没留死规则。

## 任务卡下面挂当天的计划节点和提醒
day-plan 接口本来就返回 plan_nodes / reminders / tasks 三份。这里只取
前两份,任务列表仍然走 /tasks——因为 /tasks 会补生成当天任务而
day-plan 不会,拿它的 tasks 覆盖列表会让今天的任务凭空少掉。

## 「接下来」卡
30 天计划里最近 3 个还没做的节点,日期显示成「今天/明天/3 天后」而不是
7月31日。带完成度进度条,右上角「完整计划」进计划页。

计划页降级成二级页之后,这张卡是它在首页的唯一露出;没有它,计划这个
功能对用户来说就等于消失了。

## AI 计划入口
AI 页快捷区加了「生成养护计划」,直达 /pages/plan/plan?tab=aiPlan。

没有把这个表单搬进 AI 聊天页:它要渲染 extracted 四宫格和可勾选的任务
节点,塞进聊天流意味着同一个页面维护两套完全不同的渲染,收益只是少跳
一次。原本要解决的是「计划页降级后 AI 计划找不到了」,一个入口就够了。

顺带:iconfont 补了 up / down 两个 chevron(展开收起用)。

联调验证(本地 9090,新建幼犬档案):
  day-plan 今天    → plan_nodes=['确认免疫与驱虫计划']
  plan            → completion_pct=0,4 个节点,date 字段齐全
  接下来筛出        → 07-29 确认免疫与驱虫计划 / 08-01 观察饮水与排便 / 08-05 体重趋势检查
  calendar        → 2026-7,today=29,tasked_days=[29]
  day-plan 未来日   → 08-01、08-05 各自返回对应节点

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 17:48:12 +08:00

48 lines
2.0 KiB
Plaintext

/* 整页聊天:上面滚动区自适应,下面输入区固定,中间不留空 */
.chat-scroll{flex:1;min-height:0}
.chat-body{padding:var(--sp-3) var(--pad-x) var(--sp-5)}
.chat-bottom{height:1rpx}
.row{display:flex;align-items:flex-start;gap:var(--sp-2);margin-bottom:var(--sp-4)}
.row-user{justify-content:flex-end}
.ai-avatar{
width:60rpx;height:60rpx;border-radius:var(--r-sm);flex:none;margin-top:4rpx;
display:flex;align-items:center;justify-content:center;
background:var(--cta);color:#fff;
}
.bubble{
max-width:76%;border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4);
font-size:var(--fs-md);line-height:1.62;word-break:break-word;
}
.bubble-ai{background:#fff;box-shadow:var(--sd-1);border-top-left-radius:var(--r-xs)}
.bubble-user{background:var(--primary-soft);color:var(--primary-ink);border-top-right-radius:var(--r-xs)}
/* 打字光标 */
.caret{color:var(--primary);animation:blink .9s steps(1) infinite}
@keyframes blink{50%{opacity:0}}
/* 底部输入区 */
.dock{
flex:none;background:rgba(255,255,255,.94);
backdrop-filter:blur(28rpx);-webkit-backdrop-filter:blur(28rpx);
border-top:1rpx solid var(--line);
padding:var(--sp-3) var(--pad-x) calc(var(--sp-3) + env(safe-area-inset-bottom));
}
.presets{white-space:nowrap;margin-bottom:var(--sp-3)}
.preset{
display:inline-block;height:var(--h-sm);line-height:var(--h-sm);padding:0 var(--sp-4);
margin-right:var(--sp-2);border-radius:var(--r-full);border:1rpx solid var(--line);
background:#fff;color:var(--text-2);font-size:var(--fs-sm);
}
.input-row{display:flex;align-items:center;gap:var(--sp-3)}
.input-row .input{flex:1;background:var(--surface-2)}
.send{
width:88rpx;height:88rpx;border-radius:var(--r-md);flex:none;
display:flex;align-items:center;justify-content:center;
background:var(--line);color:#fff;transition:.16s ease;
}
.send.on{background:var(--cta)}
.preset-go{
display:inline-flex;align-items:center;gap:6rpx;
background:var(--primary-soft);color:var(--primary-dark);border-color:var(--primary-line);
}