import Link from "next/link"; import { redirect } from "next/navigation"; import { BindDeviceForm, SendMessageForm } from "@/components/dashboard-actions"; import { getCaregiverDashboard } from "@/lib/monitor-data"; import { buildCaregiverSessionBootstrapPath, getCaregiverSession, } from "@/lib/session"; export const dynamic = "force-dynamic"; function formatTime(date: Date | null | undefined) { if (!date) { return "暂时还没有记录"; } return new Intl.DateTimeFormat("zh-CN", { month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit", }).format(date); } function getImportanceLabel(level: string) { switch (level) { case "LOW": return "温和提醒"; case "HIGH": return "希望尽快看到"; case "URGENT": return "需要尽快联系"; default: return "日常问候"; } } function getUsageLabel(eventType: string) { switch (eventType) { case "APP_OPEN": return "打开了老人端应用"; case "SETTINGS_OPENED": return "打开了家人连接页"; case "AI_SESSION_STARTED": return "开始了一次陪伴对话"; case "AI_SESSION_ENDED": return "结束了一次陪伴对话"; case "CAMERA_ENABLED": return "打开了镜头模式"; case "CAMERA_DISABLED": return "关闭了镜头模式"; case "TOOL_CALLED": return "模型调用了一次桥接工具"; default: return eventType; } } export default async function Home() { const caregiver = await getCaregiverSession(); if (!caregiver) { redirect(buildCaregiverSessionBootstrapPath("/")); } const dashboard = await getCaregiverDashboard(caregiver.id); const totalUnreadForElder = dashboard.devices.reduce( (total, device) => total + device.familyUnreadCount, 0, ); const totalUnreadForCaregiver = dashboard.devices.reduce( (total, device) => total + device.elderUnreadCount, 0, ); const totalConversations = dashboard.devices.reduce( (total, device) => total + device.elderDevice._count.conversationTurns, 0, ); return (

Digital Human Bridge

把老人的陪伴对话、留言和家人问候,收进同一张暖色桌面。

这里是家属端控制台。扫码绑定以后,您能看到老人留给家里的话、老人最近的使用轨迹、重要对话片段,也能反过来给老人写下一句问候。

当前家属账号:{dashboard.caregiver.sessionToken.slice(0, 8).toUpperCase()} 已连接 {dashboard.devices.length} 位老人设备

家属已绑定设备

{dashboard.devices.length}

老人未读家属留言

{totalUnreadForElder}

最近存档对话条数

{totalConversations}

今日总览

老人给家里的新留言

{totalUnreadForCaregiver}

老人待接收的家属留言

{totalUnreadForElder}

扫码绑定更顺手

如果您正拿着另一台手机,可以直接打开扫码页,对准老人的家人连接二维码。

去扫码

面板说明

留言桥接

老人在数字人对话里说“给儿子带句话”时,模型会走 function calling,把内容存到这里。

陪伴记录

面板会收下老人端的重要使用事件、最近对话片段和工具调用记录,方便您回看状态。

反向留言

家属端写下的留言会进到老人设备的消息列表里,也能被 function calling 工具读取给老人听。

{dashboard.devices.length === 0 ? (

还没有绑定老人设备

先扫一下老人手机里的二维码

绑定完成后,这里会出现老人的留言、陪伴轨迹、最近对话和工具调用记录。当前页面已经替您准备好扫码与手动绑定入口。

) : (
{dashboard.devices.map((binding) => { const familyMessages = binding.elderDevice.messages.filter( (message) => message.direction === "FAMILY_TO_ELDER", ); const elderMessages = binding.elderDevice.messages.filter( (message) => message.direction === "ELDER_TO_FAMILY", ); return (

老人设备

{binding.elderDevice.displayName || "未命名陪伴设备"}

UUID:{binding.elderDevice.deviceUuid} 最近在线:{formatTime(binding.elderDevice.lastSeenAt)} 绑定链接:{binding.bindUrl}

老人新留言

{binding.elderUnreadCount}

待老人查看

{binding.familyUnreadCount}

对话条数

{binding.elderDevice._count.conversationTurns}

工具调用

{binding.elderDevice._count.toolCalls}

老人给家里留的话

最近想转达给家人的内容

未读 {binding.elderUnreadCount}
{elderMessages.length === 0 ? (

老人暂时还没有通过大模型给家里捎话。

) : ( elderMessages.map((message) => (
{getImportanceLabel(message.importance)} {message.recipientRelation ? ( 目标:{message.recipientRelation} ) : null} {formatTime(message.createdAt)}

{message.content}

)) )}

最近活动

老人端刚刚发生了什么

{binding.elderDevice.usageEvents.length === 0 ? (

暂时还没有同步到新的使用记录。

) : ( binding.elderDevice.usageEvents.map((event) => (
{getUsageLabel(event.eventType)} {formatTime(event.createdAt)}
)) )}

发给老人的留言

最近写给老人的问候

待查看 {binding.familyUnreadCount}
{familyMessages.length === 0 ? (

您还没有给这位老人留下新的问候。

) : ( familyMessages.map((message) => (
{getImportanceLabel(message.importance)} {formatTime(message.createdAt)} {message.readAt ? "老人已看过" : "等待老人查看"}

{message.content}

)) )}

最近对话片段

可快速回看的陪伴内容

{binding.elderDevice.conversationTurns.length === 0 ? (

这位老人最近的实时对话还没有同步到这里。

) : ( binding.elderDevice.conversationTurns.map((turn) => (
{turn.role === "USER" ? "老人说" : turn.role === "ASSISTANT" ? "数字人回复" : "工具结果"} {formatTime(turn.createdAt)}

{turn.content}

)) )}
); })}
)}
); }