2026-10-03 16:12:25 +08:00
<!doctype html>
< html lang = "zh-CN" >
< head >
< meta charset = "utf-8" >< meta name = "viewport" content = "width=device-width,initial-scale=1" >
2026-10-03 17:41:52 +08:00
< title > 赵府智家 · 家庭空间</ title >< link rel = "stylesheet" href = "/style.css" >
< script defer src = "/vendor/hls.min.js" ></ script >< script defer src = "/live-player.js" ></ script >< script defer src = "/kinship.js" ></ script >< script defer src = "/app.js" ></ script >< script defer src = "/family.js" ></ script >
2026-10-03 16:12:25 +08:00
</ head >
< body >
< aside class = "sidebar" >
2026-10-03 17:41:52 +08:00
< a class = "brand" href = "/" >< span class = "brand-icon" > ◉</ span >< span > 赵府智家< small > HOME / 本地家庭空间</ small ></ span ></ a >
2026-10-03 16:12:25 +08:00
< div class = "nav-label" > 工作空间</ div >
< nav aria-label = "主导航" >
< button data-page = "live" class = "active" > ◫ < span > 实时画面</ span ></ button >
< button data-page = "playback" > ◷ < span > 录像回放</ span ></ button >
2026-10-03 17:41:52 +08:00
< button data-page = "family" > ♧ < span > 家谱</ span ></ button >
< button data-page = "users" data-admin > ♙ < span > 账号与关系</ span ></ button >
2026-10-03 16:12:25 +08:00
< button data-page = "objects" > ▣ < span > 摄像头对象</ span ></ button >< button data-page = "recorders" > ▤ < span > 录像机</ span ></ button >< button data-page = "cameras" > ◫ < span > 镜头通道</ span ></ button >
< button data-page = "sites" > ⌂ < span > 空间档案</ span ></ button >
< button data-page = "storage" > ▤ < span > 录像与存储</ span ></ button >
</ nav >
< div class = "side-note" >< span class = "dot" ></ span > 自有部署 · 本地存储< p > 按空间组织画面< br > 让每一段记录有处可寻</ p ></ div >
2026-10-03 17:41:52 +08:00
< p id = "current-user" class = "description" ></ p >< button id = "logout" class = "quiet" > 退出登录</ button >
2026-10-03 16:12:25 +08:00
</ aside >
< main >
2026-10-03 17:41:52 +08:00
< header >< div >< div class = "eyebrow" > ZHAOFU HOME / FAMILY</ div >< h1 id = "page-title" > 实时画面</ h1 >< p id = "page-note" > 从一个空间,看到每一个位置。</ p ></ div >< div class = "header-status" >< span id = "service-status" class = "badge" > 等待连接</ span >< span id = "clock" ></ span ></ div ></ header >
2026-10-03 16:12:25 +08:00
< div id = "banner" class = "banner" hidden ></ div >
< section class = "metrics" >< div >< span > 摄像头</ span >< strong id = "metric-all" > —</ strong ></ div >< div >< span > 已接通码流</ span >< strong id = "metric-ready" > —</ strong ></ div >< div >< span > 录像占用</ span >< strong id = "metric-used" > —</ strong ></ div >< div >< span > 空间档案</ span >< strong id = "metric-sites" > —</ strong ></ div ></ section >
< div class = "filter-row" >< label > 空间范围 < select id = "site-filter" >< option value = "" > 全部空间</ option ></ select ></ label >< span id = "filter-caption" > 家庭与公司,分别管理</ span >< button id = "refresh" class = "quiet" > ↻ 刷新状态</ button ></ div >
2026-10-03 17:21:25 +08:00
< section id = "page-live" class = "page" >< div class = "section-head" >< h2 > 现场画面 < small > LIVE VIEW</ small ></ h2 >< div >< label > 清晰度 < select id = "quality" >< option value = "hd" > 主码流</ option >< option value = "compat" > 子码流</ option ></ select ></ label >< button data-action = "new-camera" > + 添加镜头通道</ button ></ div ></ div >< p class = "description" id = "quality-note" > 主码流画面更清晰,最高 1920×1080;子码流更流畅,最高 768×432,适合网络较慢时使用。</ p >< div id = "live-grid" class = "live-grid" ></ div ></ section >
2026-10-03 16:12:25 +08:00
< section id = "page-playback" class = "page" hidden >
< div class = "section-head" >< h2 > 回到那一刻 < small > PLAYBACK</ small ></ h2 ></ div >
< div class = "panel playback-controls" >< label > 摄像头< select id = "play-camera" ></ select ></ label >< label > 录像来源< select id = "archive-source" >< option value = "recorder" > 录像机原有录像</ option >< option value = "local" > 小电脑本机录像</ option ></ select ></ label >< label > 日期< input id = "play-date" type = "date" ></ label >< button id = "query-recordings" > 查找录像</ button >< span id = "play-info" > 选择日期,查看实际录像时段</ span ></ div >
< div class = "video-panel" >< video id = "play-video" controls playsinline ></ video >< div id = "play-empty" class = "video-empty" > 选择一个有录像的时间段</ div ></ div >
2026-10-03 17:10:06 +08:00
< div class = "panel" >< div class = "timeline-head" >< strong > 当日时间轴</ strong >< span >< i class = "legend" ></ i > 有录像的时段 · 点击定位</ span ></ div >< canvas id = "timeline" height = "76" aria-label = "录像时间轴" ></ canvas >< div class = "time-labels" >< span > 00:00</ span >< span > 06:00</ span >< span > 12:00</ span >< span > 18:00</ span >< span > 24:00</ span ></ div >< div class = "seek-row" >< label > 定位时间 < input id = "seek-time" type = "time" step = "1" value = "12:00:00" ></ label >< button id = "seek-button" class = "secondary" > 定位播放</ button >< a id = "download" class = "button secondary" hidden > 下载原始片段</ a ></ div ></ div >
2026-10-03 16:12:25 +08:00
< div id = "recording-list" class = "recording-list" ></ div >
</ section >
< section id = "page-cameras" class = "page" hidden >< div class = "section-head" >< h2 > 镜头通道 < small > CHANNELS</ small ></ h2 >< button data-action = "new-camera" > + 添加镜头通道</ button ></ div >< div class = "panel discovery" >< div >< strong > 发现局域网设备</ strong >< p > 探测 RTSP 服务,添加后用设备账号连接。</ p ></ div >< input id = "scan-network" placeholder = "例如 192.168.1.0/24" aria-label = "局域网网段" >< button id = "scan-button" class = "secondary" > 开始探测</ button ></ div >< div id = "scan-result" ></ div >< div id = "camera-list" ></ div ></ section >
< section id = "page-objects" class = "page" hidden >< div class = "section-head" >< h2 > 摄像头对象 < small > CAMERA ASSETS</ small ></ h2 >< button data-action = "new-asset" > + 新建摄像头对象</ button ></ div >< p class = "description" > 一台实体摄像头对应一个对象,双镜头在对象下建立两个镜头通道;每个镜头分别有主码流和子码流。</ p >< div id = "asset-list" class = "site-grid" ></ div ></ section >
< section id = "page-recorders" class = "page" hidden >< div class = "section-head" >< h2 > 录像机 < small > RECORDERS</ small ></ h2 >< button data-action = "new-recorder" > + 添加录像机</ button ></ div >< p class = "description" > 统一保存录像机地址与账号,镜头通道关联录像机。实时取流使用 RTSP;读取录像机已有历史录像,需要该型号的回放接口适配。</ p >< div id = "recorder-list" class = "site-grid" ></ div ></ section >
< section id = "page-sites" class = "page" hidden >< div class = "section-head" >< h2 > 空间档案 < small > PLACES</ small ></ h2 >< button data-action = "new-site" > + 新建空间</ button ></ div >< p class = "description" > 为家庭、公司或其他场所建立地址档案,再关联摄像头。地区、小区、楼栋和门牌都是独立属性。</ p >< div id = "site-list" class = "site-grid" ></ div ></ section >
2026-10-03 17:21:25 +08:00
< section id = "page-storage" class = "page" hidden >< div class = "section-head" >< h2 > 录像与存储 < small > STORAGE</ small ></ h2 ></ div >< div class = "storage-grid" >< form id = "storage-form" class = "panel" >< h3 > 录像保留策略</ h3 >< label > 保留天数< input name = "retentionDays" type = "number" min = "1" max = "365" required ></ label >< label > 录像容量上限(GB) < input name = "maxGB" type = "number" min = "5" max = "100000" required ></ label >< label > 磁盘预留空间(GB) < input name = "reserveGB" type = "number" min = "2" max = "1000" required ></ label >< p class = "description" > 超过保留天数的录像会自动删除。达到容量上限或预留空间不足时暂停录像;调整策略后自动恢复。容量每 20 秒检查一次,可能有少量超出。</ p >< button type = "submit" > 保存策略</ button >< span class = "form-error" ></ span ></ form >< div class = "panel" >< h3 > 运行状态</ h3 >< dl id = "storage-status" ></ dl >< p class = "description" > 开启摄像头的“持续录像”后,服务会保存主码流。预览默认使用主码流高清画面(最高 1920×1080、15 帧/秒),也可切换子码流流畅画面(最高 768×432、10 帧/秒)。本机录像保留设备原始编码。</ p >< h3 > 最近操作</ h3 >< div id = "audit-list" ></ div ></ div ></ div ></ section >
2026-10-03 17:41:52 +08:00
< section id = "page-family" class = "page" hidden >
< div class = "section-head" >< h2 > 家族的来处与延续 < small > FAMILY REGISTER</ small ></ h2 >< div >< button id = "family-reload" class = "quiet" > 重新载入</ button >< button id = "family-export" class = "quiet" > 导出家谱</ button >< button id = "new-person" > + 录入人物</ button ></ div ></ div >
< p class = "description" > 一个账号可以录入全家人物。先录人物,再连接父母、子女与配偶;祖先不需要登录账号。日期使用公历,不确定的信息可以留空。</ p >
< div class = "panel family-toolbar" >< label > 关系参照人物< select id = "family-reference" ></ select ></ label >< label > 查找人物< input id = "family-search" type = "search" placeholder = "姓名、别名或籍贯" ></ label >< label class = "check" >< input id = "family-archived" type = "checkbox" > 显示归档人物</ label >< span id = "family-count" ></ span ></ div >
< div id = "family-error" class = "form-error" role = "status" ></ div >
< div class = "family-layout" >< div id = "family-people" class = "family-people" ></ div >< div id = "family-detail" class = "panel" ></ div ></ div >
< div class = "panel" >< div class = "section-head" >< h3 > 以选中人物为中心的家谱</ h3 >< label > 展开代数< select id = "family-depth" >< option value = "2" > 2 代</ option >< option value = "4" selected > 4 代</ option >< option value = "8" > 8 代</ option ></ select ></ label ></ div >< p class = "description" > 点击树中的姓名查看人物。配偶单独列出;同一个祖先可出现在不同分支。复杂旁系关系以关系路径表示,长幼按已填写的出生日期判断。</ p >< div id = "family-tree" class = "family-tree" ></ div ></ div >
</ section >
< section id = "page-users" class = "page" hidden >< div class = "section-head" >< h2 > 账号与人物关系 < small > ACCOUNTS</ small ></ h2 >< button id = "new-user" > + 新建账号</ button ></ div >< p class = "description" > 亲属称呼用于描述人物关系。摄像头空间权限、家谱权限和管理员身份分别设置。无需为每一位家谱人物创建账号。</ p >< div id = "user-list" ></ div ></ section >
< footer >< span > 赵府智家 · 家庭空间</ span >< span id = "version" > 独立部署 / 数据自有</ span ></ footer >
2026-10-03 16:12:25 +08:00
</ main >
2026-10-03 17:41:52 +08:00
< dialog id = "auth-dialog" >< form id = "auth-form" >< span class = "eyebrow" > WELCOME HOME</ span >< h2 id = "auth-title" > 欢迎回来</ h2 >< p id = "auth-note" > 使用自己的账号,进入家庭空间。</ p >< label id = "setup-code-label" hidden > 初始化码< input name = "code" autocomplete = "off" ></ label >< label > 用户名< input name = "username" value = "admin" maxlength = "32" required autocomplete = "username" ></ label >< label > 密码< input name = "password" type = "password" minlength = "8" maxlength = "128" required autocomplete = "current-password" ></ label >< p class = "form-error" ></ p >< button type = "submit" class = "wide" > 进入系统</ button ></ form ></ dialog >
2026-10-03 16:12:25 +08:00
< dialog id = "site-dialog" >< form id = "site-form" >< div class = "dialog-heading" >< h2 > 空间档案</ h2 >< button type = "button" class = "quiet" data-close = "site-dialog" > 关闭</ button ></ div >< input name = "id" type = "hidden" >< div class = "form-grid" >< label > 空间名称 *< input name = "name" required maxlength = "100" placeholder = "例如:莱阳老家" ></ label >< label > 用途< select name = "kind" >< option value = "home" > 家庭</ option >< option value = "company" > 公司</ option >< option value = "other" > 其他</ option ></ select ></ label >< label > 所属家庭 / 单位< input name = "owner" maxlength = "100" ></ label >< label > 省 / 直辖市< input name = "province" maxlength = "100" ></ label >< label > 城市< input name = "city" maxlength = "100" ></ label >< label > 区 / 县< input name = "district" maxlength = "100" ></ label >< label > 街道 / 乡镇< input name = "street" maxlength = "100" ></ label >< label > 小区 / 园区 / 村< input name = "community" maxlength = "100" ></ label >< label > 楼栋< input name = "building" maxlength = "100" placeholder = "例如:3 号楼" ></ label >< label > 单元< input name = "unit" maxlength = "100" ></ label >< label > 楼层< input name = "floor" maxlength = "100" ></ label >< label > 门牌号< input name = "door" maxlength = "100" placeholder = "例如:502" ></ label >< label class = "full" > 详细地址< input name = "address" maxlength = "240" ></ label >< label class = "full" > 备注< input name = "note" maxlength = "240" ></ label ></ div >< p class = "form-error" ></ p >< div class = "dialog-footer" >< button type = "submit" > 保存空间</ button ></ div ></ form ></ dialog >
2026-10-03 16:16:23 +08:00
< dialog id = "camera-dialog" >< form id = "camera-form" >< div class = "dialog-heading" >< h2 > 镜头通道配置</ h2 >< button type = "button" class = "quiet" data-close = "camera-dialog" > 关闭</ button ></ div >< input name = "id" type = "hidden" >< div class = "form-grid" >< label class = "full" > 所属摄像头对象 *< select name = "assetId" required ></ select ></ label >< label > 接入方式< select name = "sourceKind" >< option value = "recorder" > 通过录像机</ option >< option value = "direct" > 直接连接摄像头</ option ></ select ></ label >< label > 关联录像机< select name = "recorderId" >< option value = "" > 请选择</ option ></ select ></ label >< label > 录像机通道编号< input name = "channelNumber" maxlength = "30" placeholder = "按录像机实际通道填写" ></ label >< label > 录像存储设备< select name = "archiveRecorderId" >< option value = "" > 尚未绑定</ option ></ select ></ label >< label > 历史录像主要保存于< select name = "archiveSource" >< option value = "recorder" > 录像机</ option >< option value = "local" > 本机</ option ></ select ></ label >< label > 镜头 / 通道名称 *< input name = "name" required maxlength = "120" placeholder = "例如:大门口" ></ label >< label > 所属空间 *< select name = "siteId" required ></ select ></ label >< label > 安装位置< input name = "point" maxlength = "120" placeholder = "例如:院门外侧" ></ label >< label > 品牌 / 型号< input name = "model" maxlength = "120" ></ label >< label > 设备 IP *< input name = "host" required placeholder = "局域网 IPv4 地址" ></ label >< label > RTSP 端口< input name = "port" type = "number" value = "554" min = "1" max = "65535" required ></ label >< label > 设备用户名< input name = "username" maxlength = "120" autocomplete = "off" ></ label >< label > 设备密码< input name = "password" type = "password" maxlength = "256" autocomplete = "new-password" placeholder = "编辑时留空,保留原密码" ></ label >< div class = "full" >< button id = "onvif-read" type = "button" class = "secondary" > 读取 ONVIF 镜头配置</ button >< p class = "description" > 直接接入摄像头时,可读取设备实际提供的媒体配置。默认 ONVIF HTTP 端口为 80。</ p >< div id = "onvif-result" ></ div ></ div >< label class = "full" > 常见码流路径< select id = "path-preset" >< option value = "custom" > 手动填写</ option >< option value = "tplink" > TP-Link 单镜头</ option >< option value = "hikvision" > 海康威视 / 兼容路径 · 通道 1</ option >< option value = "dahua" > 大华 / 兼容路径 · 通道 1</ option ></ select ></ label >< label class = "full" > 主码流路径 *< input name = "mainPath" required maxlength = "500" value = "/stream1" ></ label >< label class = "full" > 子码流路径 *< input name = "subPath" required maxlength = "500" value = "/stream2" ></ label >< label class = "check" >< input name = "enabled" type = "checkbox" checked > 启用连接</ label >< label class = "check" >< input name = "record" type = "checkbox" > 在小电脑额外保存录像(可选)</ label ></ div >< p class = "description" > 账号和密码只保存在本机受限数据目录。RTSP 服务响应代表设备可达,实际码流接通后才显示在线。路径预设需要与设备型号、通道一致。</ p >< p class = "form-error" ></ p >< div class = "dialog-footer" >< button type = "submit" > 保存设备</ button ></ div ></ form ></ dialog >
2026-10-03 16:12:25 +08:00
< dialog id = "asset-dialog" >< form id = "asset-form" >< div class = "dialog-heading" >< h2 > 摄像头对象</ h2 >< button type = "button" class = "quiet" data-close = "asset-dialog" > 关闭</ button ></ div >< input name = "id" type = "hidden" >< div class = "form-grid" >< label > 对象名称 *< input name = "name" required maxlength = "120" placeholder = "例如:院门双镜头摄像头" ></ label >< label > 所属空间 *< select name = "siteId" required ></ select ></ label >< label > 品牌< input name = "brand" maxlength = "120" ></ label >< label > 型号< input name = "model" maxlength = "120" ></ label >< label > 序列号< input name = "serial" maxlength = "120" ></ label >< label > 物理镜头数< input name = "lensCount" type = "number" value = "2" min = "1" max = "16" required ></ label >< label > 安装位置< input name = "point" maxlength = "120" ></ label >< label > 备注< input name = "note" maxlength = "120" ></ label ></ div >< p class = "form-error" ></ p >< div class = "dialog-footer" >< button type = "submit" > 保存对象</ button ></ div ></ form ></ dialog >
< dialog id = "recorder-dialog" >< form id = "recorder-form" >< div class = "dialog-heading" >< h2 > 录像机配置</ h2 >< button type = "button" class = "quiet" data-close = "recorder-dialog" > 关闭</ button ></ div >< input name = "id" type = "hidden" >< div class = "form-grid" >< label > 录像机名称 *< input name = "name" required maxlength = "120" ></ label >< label > 所属空间 *< select name = "siteId" required ></ select ></ label >< label > 品牌< input name = "brand" maxlength = "120" ></ label >< label > 型号< input name = "model" maxlength = "120" ></ label >< label > 录像机 IP *< input name = "host" required ></ label >< label > RTSP 端口< input name = "port" type = "number" value = "554" min = "1" max = "65535" required ></ label >< label > 登录用户名< input name = "username" maxlength = "120" autocomplete = "off" ></ label >< label > 设备密码< input name = "password" type = "password" maxlength = "256" placeholder = "留空保留原密码" autocomplete = "new-password" ></ label >< label class = "full" > 接入驱动< select name = "driver" >< option value = "generic-rtsp" > 通用 RTSP / 手动通道路径</ option >< option value = "hikvision-rtsp" > 海康 / 兼容型号 RTSP 路径</ option >< option value = "tplink-rtsp" > TP-Link RTSP 路径</ option >< option value = "dahua-rtsp" > 大华 / 兼容型号 RTSP 路径</ option ></ select ></ label ></ div >< p class = "description" > 驱动在当前版本提供路径模板。录像机历史录像检索、回放及通道自动导入,需要型号确认后接入,当前尚未实现。</ p >< p class = "form-error" ></ p >< div class = "dialog-footer" >< button type = "submit" > 保存录像机</ button ></ div ></ form ></ dialog >
2026-10-03 17:41:52 +08:00
< dialog id = "user-dialog" >< form id = "user-form" >< div class = "dialog-heading" >< h2 > 账号档案</ h2 >< button type = "button" class = "quiet" data-close = "user-dialog" > 关闭</ button ></ div >< input name = "id" type = "hidden" >< div class = "form-grid" >< label > 用户名 *< input name = "username" required minlength = "3" maxlength = "32" autocomplete = "off" ></ label >< label > 显示名称 *< input name = "name" required maxlength = "80" ></ label >< label > 密码< input name = "password" type = "password" minlength = "8" maxlength = "128" autocomplete = "new-password" placeholder = "编辑时留空保留" ></ label >< label > 系统角色< select name = "role" >< option value = "member" > 个人账号</ option >< option value = "admin" > 管理员</ option ></ select ></ label >< label > 家谱权限< select name = "familyAccess" >< option value = "none" > 不可访问</ option >< option value = "read" > 查看家谱</ option >< option value = "edit" > 录入和维护家谱</ option ></ select ></ label >< label > 关联家谱人物< select name = "personId" ></ select ></ label >< label > 这个账号是< select name = "relatedToId" ></ select ></ label >< label > 的什么关系< input name = "relationship" list = "relationship-choices" maxlength = "40" placeholder = "可选择或自行填写" ></ label >< fieldset class = "full" >< legend > 允许查看摄像头的空间</ legend >< div id = "user-sites" ></ div >< p class = "description" > 个人账号仅能观看已选空间的实时画面和回放;管理员可以管理全部空间。</ p ></ fieldset >< label class = "check" >< input name = "disabled" type = "checkbox" > 停用账号</ label ></ div >< p class = "form-error" ></ p >< div class = "dialog-footer" >< button type = "submit" > 保存账号</ button ></ div ></ form ></ dialog >
< datalist id = "relationship-choices" ></ datalist >
< dialog id = "person-dialog" >< form id = "person-form" >< div class = "dialog-heading" >< h2 > 家谱人物</ h2 >< button type = "button" class = "quiet" data-close = "person-dialog" > 关闭</ button ></ div >< input name = "id" type = "hidden" >< input name = "revision" type = "hidden" >< div class = "form-grid" >< label > 姓名 / 称呼 *< input name = "name" required maxlength = "80" placeholder = "姓名暂不知时可先填称呼" ></ label >< label > 别名 / 字 / 号< input name = "alias" maxlength = "120" ></ label >< label > 性别< select name = "gender" >< option value = "unknown" > 待确认</ option >< option value = "male" > 男</ option >< option value = "female" > 女</ option ></ select ></ label >< label > 在世情况< select name = "lifeStatus" >< option value = "unknown" > 待确认</ option >< option value = "alive" > 在世</ option >< option value = "deceased" > 已故</ option ></ select ></ label >< label > 出生日期(公历)< input name = "birthDate" type = "date" ></ label >< label > 逝世日期(公历)< input name = "deathDate" type = "date" ></ label >< label class = "full" > 籍贯 / 出生地< input name = "birthplace" maxlength = "160" ></ label >< label class = "full" > 生平简介< textarea name = "biography" rows = "4" maxlength = "2000" ></ textarea ></ label >< label class = "full" > 备注 / 信息来源< textarea name = "note" rows = "3" maxlength = "500" placeholder = "例如:农历日期、长辈口述、族谱记载、待考证信息" ></ textarea ></ label >< label class = "check" >< input name = "archived" type = "checkbox" > 归档人物(保留关系,可恢复)</ label ></ div >< p class = "form-error" ></ p >< div class = "dialog-footer" >< button type = "submit" > 保存人物</ button ></ div ></ form ></ dialog >
< dialog id = "relation-dialog" >< form id = "relation-form" >< div class = "dialog-heading" >< h2 > 连接人物关系</ h2 >< button type = "button" class = "quiet" data-close = "relation-dialog" > 关闭</ button ></ div >< input name = "id" type = "hidden" >< input name = "revision" type = "hidden" >< div class = "form-grid" >< label > 关系类型< select name = "kind" >< option value = "parent" > 父母 → 子女</ option >< option value = "spouse" > 配偶 ↔ 配偶</ option ></ select ></ label >< label > 亲子属性< select name = "lineage" >< option value = "unspecified" > 未注明</ option >< option value = "biological" > 亲生</ option >< option value = "adoptive" > 收养</ option >< option value = "step" > 继亲</ option ></ select ></ label >< label > 父母一方 / 配偶一方< select name = "fromId" required ></ select ></ label >< label > 子女 / 另一位配偶< select name = "toId" required ></ select ></ label >< label class = "full" > 关系备注< input name = "note" maxlength = "300" ></ label >< label class = "check" >< input name = "active" type = "checkbox" checked > 关系有效(取消后保留记录,可恢复)</ label ></ div >< p class = "description" > 每条亲子关系连接一位父母与一位子女。录入另一位父母时,再建立一条关系。</ p >< p class = "form-error" ></ p >< div class = "dialog-footer" >< button type = "submit" > 保存关系</ button ></ div ></ form ></ dialog >
2026-10-03 16:12:25 +08:00
< div id = "toast" role = "status" hidden ></ div >
</ body >
</ html >