编辑页面

修改后将从当前时间重新计算过期时间
禁用后该账号在管的患者数据仍保留,但不可再下发参数。
`, ok:'确认禁用', danger:true, act:"toast('账号已禁用,操作已留痕')"}, 'm-publish':{t:'保存并发布默认参数', s:'发布后仅影响新建会话的默认值,不回溯修改已有会话与设备内参数', b:`
新版本号
v1.5
生效时间
立即生效
发布操作需超级管理员权限,并记入操作日志。
`, ok:'确认发布', act:"toast('默认参数 v1.5 已发布')"}, 'm-stop':{t:'暂停 OTA 任务', s:'暂停后已下发但未完成的升级将在设备下次连接时继续', b:`

确认暂停任务 OTA-20261015-02?当前进度 68%(39 成功 / 2 失败)。

`, ok:'确认暂停', act:"toast('OTA 任务已暂停')"}, 'm-i18n':{t:'新增语言', s:'新增后需导入或人工补全词条,完成度达 100% 方可发布', b:`
否
是
`, ok:'确认新增', act:"toast('语言已新增,请补全词条')"}, 'm-role':{t:'新建角色', s:'角色权限保存后,对该角色下全部账号生效', b:`
`, ok:'创建角色', act:"toast('角色已创建,请配置权限项')"}, 'm-diff':{t:'参数变更对比', s:'张明远 · 刘桂芳 · 10月19日 08:42', b:`
参数项
变更前
变更后
刺激幅度
50%
55%
脉冲频率
30 Hz
35 Hz
脉冲时间
200 μs
200 μs
刺激时间
2 s
2 s
刺激间隔
5 s
5 s
下发结果:成功(1.2 s)· 服务器已同步保存。
`, ok:'知道了', act:"closeModal()"}, 'm-privacy':{t:'发布隐私协议 v2.2', s:'协议将在 App 首次启动、「我的 → 隐私协议」与后台登录页页脚同步生效', b:`
需要
不需要
`, ok:'确认发布', act:"toast('隐私协议 v2.2 已发布')"}, 'm-hospital':{t:'新增医院', s:'医院是科室的上级维度,编码创建后不可修改', b:`
启用(App 端可选)
停用
编码按 H- 三位流水自动生成;机构名称与资质材料不一致时,审核中心会以「机构信息不符」驳回。
`, ok:'保存', act:"closeModal();toast('医院已保存,App 端下拉即时生效')"}, 'm-dept':{t:'新增科室', s:'科室挂靠在医院下,编码全局唯一', b:`
启用
停用
编码规则:D-医院序号(2 位)+科室序号(2 位);跨院同名科室可重复,编码不可重复。
`, ok:'保存', act:"closeModal();toast('科室已保存,App 端级联下拉已更新')"}, 'm-title':{t:'新增职称', s:'保存后 App 端职称下拉立即可选', b:`
启用
停用
排序值决定 App 下拉顺序;同一职称被引用后不可删除,只能停用。
`, ok:'保存', act:"closeModal();toast('职称已保存,App 端下拉即时生效')"}, 'm-hosp-off':{t:'停用医院', s:'停用不等同于删除,历史数据全部保留', b:`
停用后该医院及其下全部科室将从 App 端下拉中移除,已归属的医护人员不会被解除关系,但资料编辑时需重新选择机构。
`, ok:'确认停用', act:"closeModal();toast('医院已停用,App 端不再展示')", danger:true}, 'm-dept-off':{t:'停用科室', s:'停用后 App 端不可再选择该科室', b:`
该科室下仍有医护人员时,停用不会解除其归属,但会提示管理员先完成人员调整;历史会话与报告不受影响。
`, ok:'确认停用', act:"closeModal();toast('科室已停用')", danger:true}, 'm-title-off':{t:'停用职称', s:'已被引用的职称只能停用,不能删除', b:`
停用后该职称不再出现在 App 下拉中;已引用该职称的医护人员资料保留原值,重新编辑时需改选其他职称。
仅停用
停用并批量改选
`, ok:'确认停用', act:"closeModal();toast('职称已停用')", danger:true}, 'm-staff':{t:'新增人员', s:'手机号是 App 注册匹配名册的唯一标识,须与本人注册号码一致', b:`
男
女
在职
停用
离职
所属医院与科室为级联关系,仅可选择启用条目;保存后该手机号注册 App 将自动匹配本名册并进入资质审核。
`, ok:'保存', act:"closeModal();toast('人员已保存,可凭手机号注册 App')"}, 'm-staff-off':{t:'停用人员', s:'停用后该人员无法登录 App,历史数据保留', b:`
停用后该人员立即退出登录,不能再绑定设备或调整参数;名下在管患者的随访任务需转交同科室其他医师。
`, ok:'确认停用', act:"closeModal();toast('人员已停用,账号同步禁用')", danger:true}, 'm-unbind-reject':{t:'驳回解绑申请', s:'驳回原因将推送至患者端与主治医生', b:`
`, ok:'确认驳回', act:"closeModal();toast('已驳回,结果已推送患者端')", danger:true} }; function openModal(id){ const mask = document.getElementById('mask'); const box = document.getElementById('modalBox'); let t,s,b,ok,act,danger,wide; if(id==='m-func'){ wide=true; t='后台功能对照'; s='PRD 第七章 20 项后台功能 ↔ 本原型页面'; b=funcTable(); ok='知道了'; act='closeModal()'; } else if(id==='m-notice'){ t='待办事项'; s='按类型查看待处理事项'; b=noticeList(); ok='全部标记已读'; act="toast('已全部标记为已读')"; } else if(id==='m-export'){ wide=true; t='新建导出任务'; s='导出内容将添加水印并记录操作人'; b=exportForm(); ok='创建导出任务'; act="closeModal();toast('导出任务已创建,完成后可下载')"; } else if(id==='m-session'){ wide=true; t='会话详情'; s='SES-20261019-0142'; b=sessionDetail(); ok='关闭'; act='closeModal()'; } else if(id==='m-restore'){ t='确认恢复数据'; s='此操作将覆盖当前数据库'; b=`
恢复至 10/19 03:00 的备份将丢失此后产生的全部会话与操作数据,且服务不可用约 10–20 分钟。
`; ok='执行恢复'; act="closeModal();toast('恢复任务已提交,等待云厂商执行')"; danger=true; } else if(id==='m-threshold'){ t='异常提示阈值配置'; s='阈值须由甲方书面提供,本平台不自行判定'; b=thresholdForm(); ok='保存阈值'; act="toast('阈值已保存')"; } else if(id==='m-newver'){ wide=true; t='发布 APP 版本'; s='版本号与更新说明须与商店提交内容一致'; b=versionForm(); ok='提交发布'; act="closeModal();toast('版本已提交发布流程')"; } else if(id==='m-ota'){ t='新建 OTA 推送任务'; s='依赖 OTA 协议:分包大小、断点续传、校验方式'; b=otaForm(); ok='创建任务'; act="closeModal();toast('OTA 任务已创建')"; } else if(id==='m-reject'){ t='驳回审核'; s='驳回原因将推送至申请人 App'; b=`
`; ok='确认驳回'; act="closeModal();toast('已驳回,结果已推送申请人')"; danger=true; } else if(GENERIC[id]){ const g=GENERIC[id]; t=g.t; s=g.s; b=g.b; ok=g.ok; act=g.act; danger=g.danger; } else { t='提示'; s=''; b='

原型演示

'; ok='知道了'; act='closeModal()'; } document.getElementById('mTitle').textContent = t; document.getElementById('mSub').textContent = s || ''; document.getElementById('mBody').innerHTML = b; box.classList.toggle('wide', !!wide); document.getElementById('mFoot').innerHTML = ` `; mask.classList.add('show'); modalBuild = id; } function closeModal(){ document.getElementById('mask').classList.remove('show'); } document.getElementById('mask').addEventListener('click', e=>{ if(e.target.id==='mask') closeModal(); }); document.addEventListener('keydown', e=>{ if(e.key==='Escape'){ closeModal(); closeDrawer(); } }); function funcTable(){ const rows = [ ['F-后台-01','患者用户列表','p-patient','✅ 已实现'], ['F-后台-02','患者状态管理(启用/禁用、重置密码)','p-patient','✅ 已实现'], ['F-后台-03','医护人员用户列表','p-doctor','✅ 已实现'], ['F-后台-04','医护人员审核与状态管理','p-doctor','✅ 已实现'], ['F-后台-05','设备列表(含最后活跃时间)','p-device','✅ 已实现'], ['F-后台-06','设备状态监控(60 秒轮询)','p-device','✅ 已实现'], ['F-后台-07','设备绑定记录','p-bind','✅ 已实现'], ['F-后台-08','固件版本管理 / OTA','p-firmware','⚠ 依赖 OTA 协议'], ['F-后台-09','患者会话数据查看','p-session','✅ 已实现'], ['F-后台-10','会话数据导出(PDF / Excel)','p-export','✅ 已实现'], ['F-后台-11','设备数据异常提示','p-alert','⚠ 阈值待确认'], ['F-后台-12','默认参数配置','p-param','⚠ 依赖协议'], ['F-后台-13','参数修改审计','p-auditlog','✅ 已实现'], ['F-后台-14','参数下发日志','p-pushlog','✅ 已实现'], ['F-后台-15','APP 版本管理 / 强制更新','p-version','✅ 已实现'], ['F-后台-16','多语言管理','p-i18n','⚠ 语种待确认'], ['F-后台-17','隐私协议管理','p-privacy','✅ 已实现'], ['F-后台-18','操作日志','p-oplog','✅ 已实现'], ['F-后台-19','角色权限管理','p-role','✅ 已实现'], ['F-后台-20','数据备份与恢复','p-backup','✅ 已实现'], ['附-01','医院信息维护(医院字典)','p-hospital','✅ 本次新增'], ['附-02','科室信息维护(科室字典)','p-dept','✅ 本次新增'], ['附-03','职称信息维护(职称字典)','p-title','✅ 本次新增'], ['附-04','院内人员名册(姓名 / 手机号 / 医院 / 科室 / 职称 / 状态)','p-staff','✅ 本次新增'] ]; return `
${rows.map(r=>``).join('')}
编号功能原型页面状态
${r[0]}${r[1]}${r[2]}${r[3].includes('⚠')?`${r[3].replace('⚠ ','')}`:`${r[3].replace('✅ ','')}`}
另有 3 项为医生端衍生需求,已并入后台:解绑审核、随访任务、重点关注名单;「医院信息」模块(附-01–03)为本次新增的组织字典能力。
`; } function noticeList(){ const items = [ ['设备解绑申请 2 条','陈志强 / 周明辉','a','p-audit'], ['数据异常提示 6 条待处理','按触发次数排序','r','p-alert'], ['设备超 7 天未活跃 14 台','建议核对绑定关系','grey','p-device'], ['OTA 任务 OTA-20261018-03 待执行','目标 210 台设备','p','p-firmware'], ['隐私协议 v2.2 待甲方确认','影响三处呈现文案','v','p-privacy'] ]; return `
${items.map(i=>`
${i[0]}
${i[1]}
待处理
`).join('')}
`; } function exportForm(){ return `
按医疗机构
按患者
按设备
PDF 报告
Excel 明细
包含患者身份信息
关闭时姓名脱敏、手机号打码
添加水印(导出人 + 时间)
建议始终开启,便于溯源
下载链接 7 天有效期
过期后需重新导出
导出内容将标注「仅统计已同步数据」,设备离线期间缺失的事件不计入合计。
`; } function sessionDetail(){ return `
患者
王慧敏 · PT-100238
设备
PT2026A00317 · S1
会话时段
10/19 23:02 → 10/19 06:31
时长
7 小时 29 分
刺激模式
跟随呼吸刺激
幅度
起始 50% → 结束 50%

呼吸波形与暂停区间

设备上报原始记录
23:0001:1203:4006:30
呼吸波形呼吸暂停区间
暂停事件(3 次)
01:12持续 12 秒幅度 50%
02:35持续 8 秒幅度 50%
04:08持续 21 秒幅度 52%
会话参数快照
脉冲时间 / 频率
200 μs / 30 Hz
刺激时间 / 间隔
2 s / 5 s
结束原因
患者手动停止
数据完整性
完整 · 无断连
`; } function thresholdForm(){ return `
次 / 夜,连续夜触发
低于% 或高于%
小时无上报
降级为排序与筛选
不展示该模块
阈值一旦由本方自行设定,即构成医学判断,与「健康管理类软件」定位冲突。须由甲方书面提供并留存确认记录。
`; } function versionForm(){ return `
iOS + Android
仅 iOS
仅 Android
强制更新
低版本客户端启动时弹出不可跳过提示
`; } function otaForm(){ return `
低于目标版本的全部设备(210 台)
手动选择设备
升级期间设备不可用,建议在日间执行;患者端会收到「固件升级中」提示,升级过程中请勿关闭设备。
`; } /* ================= 抽屉 ================= */ const PATIENTS = { '王慧敏':{sex:'女 · 52岁', id:'PT-100238', phone:'138****2156', dev:'S1 · PT2026A00317', fw:'v2.4.1', day:12, avg:'2.1', adh:'6/7', doc:'张明远', status:'正常'}, '刘桂芳':{sex:'女 · 47岁', id:'PT-100256', phone:'137****4021', dev:'S2 · PT2026B00921', fw:'v2.6.0', day:5, avg:'9.0', adh:'5/7', doc:'张明远', status:'重点关注'}, '陈志强':{sex:'男 · 58岁', id:'PT-100233', phone:'135****6672', dev:'S1 · PT2026A00276', fw:'v2.4.1', day:19, avg:'3.4', adh:'6/7', doc:'张明远', status:'解绑审核中'}, '赵文博':{sex:'男 · 45岁', id:'PT-100264', phone:'186****1190', dev:'S1 · PT2026A00408', fw:'v2.4.1', day:7, avg:'—', adh:'0/7', doc:'张明远', status:'数据缺漏'}, '吴雅琴':{sex:'女 · 49岁', id:'PT-100280', phone:'189****5521', dev:'S2-Pro · PT2026B00736', fw:'v2.8.3', day:4, avg:'6.1', adh:'2/7', doc:'李静', status:'重点关注'}, '孙丽娟':{sex:'女 · 61岁', id:'PT-100219', phone:'158****3374', dev:'S1 · PT2026A00408', fw:'v2.4.1', day:14, avg:'3.2', adh:'6/7', doc:'李静', status:'已暂停'}, '周明辉':{sex:'男 · 55岁', id:'PT-100271', phone:'133****9087', dev:'S2 · PT2026B01044', fw:'v2.6.0', day:9, avg:'2.8', adh:'5/7', doc:'赵敏', status:'解绑审核中'}, '李建国':{sex:'男 · 63岁', id:'PT-100241', phone:'139****8830', dev:'S2 · PT2026B00921', fw:'v2.6.0', day:3, avg:'4.3', adh:'4/7', doc:'李静', status:'血氧偏低'}, '张凤仪':{sex:'女 · 67岁', id:'PT-100112', phone:'136****7742', dev:'S1 · PT2026A00158', fw:'v2.4.1', day:0, avg:'1.4', adh:'—', doc:'张明远', status:'已禁用'}, '何秀兰':{sex:'女 · 56岁', id:'PT-100305', phone:'150****2288', dev:'未绑定', fw:'—', day:0, avg:'—', adh:'—', doc:'—', status:'未开始'}, '郑海涛':{sex:'男 · 39岁', id:'PT-100318', phone:'177****6034', dev:'S4 · PT2027A00412', fw:'v3.1.0', day:1, avg:'1.0', adh:'1/7', doc:'张明远', status:'正常'} }; function openPatient(name){ const p = PATIENTS[name] || PATIENTS['王慧敏']; document.getElementById('drTitle').textContent = name; document.getElementById('drSub').textContent = p.id + ' · ' + p.sex; document.getElementById('drBody').innerHTML = `

基本信息

手机号
${p.phone}
账号状态
${p.status}
注册时间
2026-08-30 14:22
最近使用
3 分钟前

绑定设备

${p.dev}
固件 ${p.fw} · 电量 86%
已绑定
绑定于 09月22日最后活跃 3 分钟前

近 7 日概况

疗程
第 ${p.day} 天
暂停均值
${p.avg} 次/夜
依从性
${p.adh} 天
在管医护
${p.doc}

最近会话

10/1923:02 – 06:31 · 7h29m3 次暂停
10/1822:50 – 06:12 · 7h22m2 次暂停
10/1723:18 – 06:04 · 6h46m4 次暂停
`; document.getElementById('drFoot').innerHTML = ` `; document.getElementById('drawer').classList.add('show'); } const DOCTORS = { '张明远':{id:'DR-0021', title:'主治医师', org:'武汉市第一医院', dept:'呼吸内科', dev:3, pat:142, bind:'09月23日', phone:'139****0088'}, '李静':{id:'DR-0023', title:'副主任医师', org:'同济医院', dept:'睡眠医学中心', dev:2, pat:96, bind:'08月02日', phone:'138****4412'}, '赵敏':{id:'DR-0018', title:'主任医师', org:'同济医院', dept:'睡眠医学中心', dev:4, pat:188, bind:'09月10日', phone:'186****5503'}, '孙伟':{id:'DR-0027', title:'主治医师', org:'武汉市中心医院', dept:'耳鼻喉科', dev:1, pat:34, bind:'10月12日', phone:'159****6408'} }; function openDoctor(name){ const d = DOCTORS[name] || DOCTORS['张明远']; document.getElementById('drTitle').textContent = name; document.getElementById('drSub').textContent = d.id + ' · ' + d.title; document.getElementById('drBody').innerHTML = `

执业信息

医疗机构
${d.org}
科室
${d.dept}
职称
${d.title}
手机号
${d.phone}
审核状态
已通过
账号状态
启用

绑定与在管

绑定设备
${d.dev} 台
在管患者
${d.pat} 人
S1
PT2026A00317
当前设备 · 绑定于 ${d.bind}
当前

近期参数下发

10/19 08:42刘桂芳 · 幅度 50→55%成功
10/18 09:12赵文博 · 幅度 45→40%校验失败
10/17 10:22陈志强 · 间隔 5→6s成功
`; document.getElementById('drFoot').innerHTML = ` `; document.getElementById('drawer').classList.add('show'); } function openDevice(sn){ document.getElementById('drTitle').textContent = 'PETU 睡眠治疗仪'; document.getElementById('drSub').textContent = 'SN · ' + sn; document.getElementById('drBody').innerHTML = `

设备信息

设备名称
PETU 睡眠治疗仪 S1
SN
${sn}
固件版本
v2.4.1
电量
86%
最后活跃
3 分钟前
累计会话
128 次
设备为 BLE 连接、无网络能力,「最后活跃」为最近一次 App 上报时间,不代表设备实时在线。

当前绑定

王
王慧敏
患者 · 张明远医生在管
生效中

近 7 日活跃

${[52,48,55,50,57,54,59].map((h,i)=>``).join('')} ${['三','四','五','六','日','一','二'].map((d,i)=>`${d}`).join('')}
`; document.getElementById('drFoot').innerHTML = ` `; document.getElementById('drawer').classList.add('show'); } function closeDrawer(){ document.getElementById('drawer').classList.remove('show'); } /* ================= 审核动作 ================= */ const AUDIT_DOCS = [ {name:'王海涛', gender:'男', code:'DR-0031', phone:'137****9931', hospital:'湖北省人民医院', dept:'耳鼻喉科', title:'主治医师', time:'提交于 10月17日 14:20 · 等待 1 天 19 小时'}, {name:'陈晓芸', gender:'女', code:'DR-0032', phone:'151****2780', hospital:'武汉市中心医院', dept:'呼吸与危重症医学科', title:'住院医师', time:'提交于 10月17日 18:05 · 等待 1 天 15 小时'}, {name:'周立群', gender:'男', code:'DR-0033', phone:'133****7712', hospital:'武汉市第三医院', dept:'呼吸内科', title:'主治医师', time:'提交于 10月18日 09:12 · 等待 1 天'}, {name:'吴梅', gender:'女', code:'DR-0034', phone:'180****3155', hospital:'湖北省中医院', dept:'呼吸内科', title:'医师', time:'已驳回', rejected:true, reason:'在职证明与实际机构不一致'} ]; function openAudit(i){ const d = AUDIT_DOCS[i] || AUDIT_DOCS[0]; if(d.rejected){ toast('该申请已驳回:' + d.reason); return; } document.getElementById('mTitle').textContent = '医护资质审核'; document.getElementById('mSub').textContent = d.code + ' · ' + d.name; document.getElementById('mBody').innerHTML = `
姓名${d.name}(${d.gender})
人员编码${d.code}
手机号${d.phone}
职称${d.title}
医疗机构${d.hospital}
科室${d.dept}
执业医师证.jpg 在职证明.pdf
${d.time}。通过后该人员可登录医生端并绑定设备;驳回后仅可见「审核进度」页。
`; document.getElementById('mFoot').innerHTML = ` `; document.getElementById('mask').classList.add('show'); } function approveAudit(btn, name){ const card = btn.closest('.audit-card, tr'); card.style.transition='.25s'; card.style.opacity='0'; card.style.transform='translateY(-6px)'; setTimeout(()=>{ card.remove(); toast('已通过:' + name); }, 240); } function openReject(){ openModal('m-reject'); } function openSession(id){ document.getElementById('mTitle').textContent = '会话详情'; document.getElementById('mSub').textContent = id; document.getElementById('mBody').innerHTML = sessionDetail(); document.getElementById('modalBox').classList.add('wide'); document.getElementById('mFoot').innerHTML = ``; document.getElementById('mask').classList.add('show'); } function openPrivacyPreview(){ document.getElementById('mTitle').textContent = '隐私协议预览'; document.getElementById('mSub').textContent = 'v2.1 · 生效中 · 患者端 / 医生端'; document.getElementById('modalBox').classList.add('wide'); document.getElementById('mBody').innerHTML = `

睡眠监测系统隐私协议

版本 v2.1 · 2026年9月30日生效

一、我们收集的信息

手机号(账号注册与登录)、设备 SN 与固件版本、会话起止时间、刺激幅度记录、设备上报的呼吸事件记录。

二、产品性质与责任边界

本软件为健康管理辅助工具,不构成医疗器械,不提供医学诊断。数据为设备上报的原始记录,未经医学解读,不替代医务人员的专业判断。

三、数据同步范围

呼吸暂停事件次数仅统计已同步数据。设备离线期间未补传的事件不计入统计。

四、数据存储与导出

会话数据归属患者账号,不随设备绑定关系变动。后台导出默认脱敏并添加水印,操作全程留痕。

`; document.getElementById('mFoot').innerHTML = ``; document.getElementById('mask').classList.add('show'); } /* 初始化 */ renderNav(); /* 支持深链:#p-xxx 直接进入对应页面(便于评审时直接分享单页) */ (function(){ const h = location.hash.replace('#',''); if(h && document.getElementById(h)){ doLogin(); go(h); } })();
取消
访问码: jrwrxazu