index.html 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. <!DOCTYPE html>
  2. <html lang="">
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <link href="assets/css/common.css" rel="stylesheet" type="text/css" />
  7. <link href="assets/css/style.css" rel="stylesheet" type="text/css" />
  8. <link href="assets/css/element-ui.css" rel="stylesheet" type="text/css" />
  9. <script type="text/javascript" src="assets/js/base.js"></script>
  10. </head>
  11. <body>
  12. <div id="app">
  13. <!-- 左边 -->
  14. <div v-if="sleepReportFrom.report_content" class="l-con" id="l-con">
  15. <div class="l-con-scroll">
  16. <!-- 当前用户 -->
  17. <div class="max-title">
  18. <span>睡眠报告</span>
  19. <ul>
  20. <li class="cur">{{ myFullName }}</li>
  21. <li>{{ myNickName }}</li>
  22. </ul>
  23. </div>
  24. <!-- 睡眠评分 -->
  25. <div v-if="sleepReportFrom.report_content" class="item-1">
  26. <div class="item-1-setting">
  27. <div class="set-time">
  28. <div class="in1">
  29. <el-date-picker v-model="selectDay" type="date" placeholder="选择日期" :clearable="false"
  30. @change="changeDate" @focus="isShow($event)" :picker-options="pickerOptions"></el-date-picker>
  31. </div>
  32. <div class="in2">
  33. <el-select v-model="selectIndex" placeholder="请选择" @change="pickerChange">
  34. <el-option v-for="(item,index) in todayTimeList" :key="'t'+index" :label="item.name"
  35. :value="item.id"></el-option>
  36. </el-select>
  37. </div>
  38. </div>
  39. <div class="score">
  40. <span>{{ sleepReportFrom.score_desc }}</span>
  41. <b v-bind:class="sleepReportFrom.report_content.score.state >= 3 ?
  42. 'text-green' : sleepReportFrom.report_content.score.state === 2 ? 'text-yellow' : 'text-red'">{{
  43. sleepReportFrom.score_value }}</b>
  44. <p>香睡指数</p>
  45. </div>
  46. </div>
  47. <!-- <div class="tip">+25</div>-->
  48. <div class="sleep-time">
  49. <div class="duration">
  50. <img src="assets/image/time_ico1.png" alt="">
  51. <span>睡眠总时长</span>
  52. <p>
  53. {{ formateSeconds(sleepReportFrom.total_duration, 0) }}
  54. </p>
  55. </div>
  56. <div class="hour">
  57. <img src="assets/image/time_ico2.png" alt="">
  58. <span>睡眠时间</span>
  59. <p>{{ sleepReportFrom.gobed_time + '~' + sleepReportFrom.outbed_time }}</p>
  60. </div>
  61. </div>
  62. </div>
  63. <!-- 各项睡眠监测数据统计 -->
  64. <div v-if="sleepReportFrom.report_content" class="item-2">
  65. <div class="count">
  66. <div class="title">各项睡眠监测数据统计</div>
  67. <ul>
  68. <li class="green">
  69. <span>上床时间</span>
  70. <p><b>{{ sleepReportFrom.gobed_time }}</b></p>
  71. </li>
  72. <li class="green">
  73. <span>在床时间</span>
  74. <p>{{ formateSeconds(sleepReportFrom.inbed_duration, 0) }}</p>
  75. </li>
  76. <li class="green">
  77. <span>深睡时长</span>
  78. <p><b>{{ formateSeconds(sleepReportFrom.deep_duration, 0) }}</b></p>
  79. </li>
  80. <li v-bind:class="sleepReportFrom.report_content.sleep_eff.state === 3 ? 'green' :
  81. sleepReportFrom.report_content.sleep_eff.state === 2 ? 'yellow' : 'red'">
  82. <span>睡眠效率</span>
  83. <p>{{ sleepReportFrom.report_content.sleep_eff.value }}</p>
  84. </li>
  85. <li v-bind:class="sleepReportFrom.report_content.avg_rh.state === 3 ? 'green' :
  86. sleepReportFrom.report_content.avg_rh.state === 2 ? 'yellow' : 'red'">
  87. <span>平均心率</span>
  88. <p><b>{{ sleepReportFrom.report_content.avg_rh.value }}</b>次/分</p>
  89. </li>
  90. <li v-bind:class="sleepReportFrom.report_content.avg_hx.state === 3 ? 'green' :
  91. sleepReportFrom.report_content.avg_hx.state === 2 ? 'yellow' : 'red'">
  92. <span>平均呼吸率</span>
  93. <p><b>{{ sleepReportFrom.report_content.avg_hx.value }}</b>次/分</p>
  94. </li>
  95. <li class="tip red">
  96. <span>温馨提示</span>
  97. <p><b>本次睡眠,您有{{ errCount }}项指标不及格。</b></p>
  98. </li>
  99. <li class="small" v-bind:class="sleepReportFrom.report_content.move_count.state === 3 ? 'green' :
  100. sleepReportFrom.report_content.move_count.state === 2 ? 'yellow' : 'red'">
  101. <span>体动次数<b style="float: right;color: white;margin-right: 10px;font-size: 12px">{{
  102. sleepReportFrom.report_content.move_count.value }}次</b></span>
  103. </li>
  104. <li class="small" v-bind:class="sleepReportFrom.report_content.snoring_count.state === 3 ? 'green' :
  105. sleepReportFrom.report_content.snoring_count.state === 2 ? 'yellow' : 'red'">
  106. <span>打鼾次数<b style="float: right;color: white;margin-right: 10px;font-size: 12px">{{
  107. sleepReportFrom.report_content.snoring_count.value }}次</b></span>
  108. </li>
  109. <li class="small" v-bind:class="sleepReportFrom.report_content.outbed_count.state === 3 ? 'green' :
  110. sleepReportFrom.report_content.outbed_count.state === 2 ? 'yellow' : 'red'">
  111. <span>离床次数<b style="float: right;color: white;margin-right: 10px;font-size: 12px">{{
  112. sleepReportFrom.report_content.outbed_count.value }}次</b></span>
  113. </li>
  114. </ul>
  115. </div>
  116. <div class="efficiency">
  117. <span>睡眠效率</span>
  118. <p>{{ sleepReportFrom.report_content.sleep_eff.value }}</p>
  119. </div>
  120. <div class="stability">
  121. <span>安稳度</span>
  122. <div class="sta-r">
  123. <em>入睡时长</em>
  124. <p>{{ formateSeconds(sleepReportFrom.rs_duration, 0) }}</p>
  125. </div>
  126. </div>
  127. </div>
  128. <!-- 离床次数 -->
  129. <div class="item-3">
  130. <div class="leave">
  131. <span>离床次数</span>
  132. <p><b>{{ sleepReportFrom.report_content.outbed_count.value }}</b>次</p>
  133. </div>
  134. <div id="leave-report" style="height:200px;"></div>
  135. </div>
  136. <!-- 体动次数 -->
  137. <div class="item-4">
  138. <div class="movement">
  139. <span>体动次数</span>
  140. <p><b>{{ sleepReportFrom.report_content.move_count.value }}</b>次</p>
  141. </div>
  142. <div id="movement-report" style="height:200px;"></div>
  143. </div>
  144. <!-- 心脏系统 -->
  145. <div class="item-5">
  146. <div class="heart">
  147. <span>心脏系统</span>
  148. </div>
  149. <div class="heart-info">
  150. <span>心率</span>
  151. <em>平均心率</em>
  152. <p><b>{{ sleepReportFrom.report_content.avg_rh.value }}</b>次/分</p>
  153. </div>
  154. <div id="heart-report" style="height:200px;"></div>
  155. </div>
  156. <!-- 呼吸系统 -->
  157. <div class="item-6">
  158. <div class="breathe">
  159. <span>呼吸系统</span>
  160. </div>
  161. <div class="breathe-info">
  162. <span>呼吸率</span>
  163. <em>平均呼吸率</em>
  164. <p><b>{{ sleepReportFrom.report_content.avg_hx.value }}</b>次/分</p>
  165. </div>
  166. <div id="breathe-report" style="height:200px;"></div>
  167. <div class="breathe-info">
  168. <span class="cur">打鼾</span>
  169. <p><b>{{ sleepReportFrom.report_content.snoring_count.value }}</b>次</p>
  170. </div>
  171. <div id="snore-report" style="height:200px;"></div>
  172. <div class="breathe-info">
  173. <span class="cur">呼吸暂停</span>
  174. <!-- <p><b>0</b>次</p>-->
  175. </div>
  176. <div id="suspend-report" style="height:200px;"></div>
  177. <!-- <div class="warn">-->
  178. <!-- <span>风险</span>-->
  179. <!-- <p>本次睡眠,您有1项指标不及格。</p>-->
  180. <!-- </div>-->
  181. </div>
  182. <!-- 深浅睡眠 -->
  183. <div class="item-7">
  184. <div class="depth">
  185. <span>深浅睡眠</span>
  186. </div>
  187. <div class="depth-info">
  188. <ul>
  189. <li>
  190. <span>清醒</span>
  191. {{ formateSeconds(sleepReportFrom.awake_duration, 1) }}
  192. </li>
  193. <li>
  194. <span>浅睡</span>
  195. {{ formateSeconds(sleepReportFrom.light_duration, 1) }}
  196. </li>
  197. <li>
  198. <span>中睡</span>
  199. {{ formateSeconds(sleepReportFrom.in_duration, 1) }}
  200. </li>
  201. <li>
  202. <span>深睡</span>
  203. {{ formateSeconds(sleepReportFrom.deep_duration, 1) }}
  204. </li>
  205. </ul>
  206. </div>
  207. <div id="depth-report" style="height:200px;"></div>
  208. </div>
  209. </div>
  210. </div>
  211. <div v-else class="l-con">
  212. <div class="l-con-scroll image-wrapper_2">
  213. <!-- <p style="text-align: center;margin-top: 100px;color: white">暂无数据</p>-->
  214. </div>
  215. </div>
  216. <!-- 左边 -->
  217. <!-- 中间 -->
  218. <div class="c-con">
  219. <div class="title">{{centerTit}}
  220. <el-link v-if="boolCheck" style="margin-left: 10px" type="primary" @click="drawer = true">切换代理</el-link>
  221. </div>
  222. <div class="state">
  223. <ul>
  224. <li>
  225. <span>共计</span>
  226. {{ frameList.length }}床
  227. </li>
  228. <li>
  229. <span>使用</span>
  230. {{ countFrom.used }}床
  231. </li>
  232. <li>
  233. <span>空余</span>
  234. {{ frameList.length - countFrom.used }}床
  235. </li>
  236. <li>
  237. <span>在床</span>
  238. {{ countFrom.inBed }}人
  239. </li>
  240. <li>
  241. <span>离床</span>
  242. {{ frameList.length - countFrom.inBed }}人
  243. </li>
  244. </ul>
  245. </div>
  246. <div class="list">
  247. <dl v-for="(item, index) in frameList" :key="'i'+index" v-bind:class="[getStatusClass(item)]"
  248. @click="changeLookBed(item)">
  249. <dt>
  250. <span>{{ item.full_name }}</span>
  251. </dt>
  252. <dd>
  253. <div class="list-l">
  254. <span v-if="item.nickname">{{ formartName(item.nickname) }}</span>
  255. <span v-else style="color: #FF9650">空置</span>
  256. <em>{{ getTimeByImei(item.imei) }}</em>
  257. </div>
  258. <div class="list-r">
  259. <p class="list-r-p1">
  260. <span>{{ item.heart ? item.heart : '--' }}</span>
  261. <b>心率</b>
  262. </p>
  263. <p class="list-r-p2">
  264. <span>{{ item.breathe ? item.breathe : '--' }}</span>
  265. <!-- <b>呼吸率</b>-->
  266. <b>呼吸</b>
  267. </p>
  268. </div>
  269. </dd>
  270. </dl>
  271. <!-- <dl class="offline warn">-->
  272. <!-- <dt>-->
  273. <!-- <span>02房01床</span>-->
  274. <!-- </dt>-->
  275. <!-- <dd>-->
  276. <!-- <div class="list-l">-->
  277. <!-- <span>王娟</span>-->
  278. <!-- <em>20:37</em>-->
  279. <!-- </div>-->
  280. <!-- <div class="list-r">-->
  281. <!-- <p class="list-r-p1">-->
  282. <!-- <span class="red">128</span>-->
  283. <!-- <b>心率</b>-->
  284. <!-- </p>-->
  285. <!-- <p class="list-r-p2">-->
  286. <!-- <span>18</span>-->
  287. <!-- <b>呼吸率</b>-->
  288. <!-- </p>-->
  289. <!-- </div>-->
  290. <!-- </dd>-->
  291. <!-- </dl>-->
  292. </div>
  293. </div>
  294. <!-- 中间 -->
  295. <!-- 右边 -->
  296. <div class="r-con" id="r-con">
  297. <!-- 报警 -->
  298. <div class="warn">
  299. <div class="title">实时报警</div>
  300. <!-- <div class="dddd"></div> -->
  301. <div class="state">
  302. <a>心率异常</a>
  303. <a>呼吸异常</a>
  304. <a>疑似呼吸暂停</a>
  305. <a>疑似生命异常</a>
  306. <a>紧急求助</a>
  307. <a>离线</a>
  308. <a>离床</a>
  309. </div>
  310. <div class="panel">
  311. <ul>
  312. <li v-for="(item, index) in warnList" :key="'w'+index" v-bind:class="[item.warn_class]">
  313. <span>{{ item.named }}</span>
  314. {{ item.warn_time }}
  315. </li>
  316. <li v-for="(item, index) in todayWarnLogs" :key="'e'+index" v-bind:class="[item.warn_class]">
  317. <span>{{ item.named }}</span>
  318. {{ item.warn_time }}
  319. </li>
  320. </ul>
  321. </div>
  322. </div>
  323. <!-- 昨天睡眠 -->
  324. <div class="yesterday-sleep">
  325. <div class="title">昨天睡眠报告分析</div>
  326. <div id="yesterday-sleep-report" style="height:300px;margin:20px 0 0 0;"></div>
  327. </div>
  328. <!-- 昨天告警 -->
  329. <div class="yesterday-warn">
  330. <div class="title">昨天告警情况</div>
  331. <div id="yesterday-warn-report" style="height:300px;margin:20px 0 0 0;"></div>
  332. </div>
  333. </div>
  334. <!-- 右边 -->
  335. <!-- 切换代理-->
  336. <el-drawer title="切换代理" :visible.sync="drawer">
  337. <div style="margin: 10px">
  338. <el-button style="margin: 10px" icon="el-icon-search" size="mini"
  339. @click="onLook(shopInfo.shop_id)">查看自己</el-button>
  340. <el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input>
  341. <el-tree class="filter-tree" :data="agentList" default-expand-all :filter-node-method="filterNode" ref="tree">
  342. <span slot-scope="{ node, data }" class="custom-tree-node">
  343. <el-tooltip :content="data.shop_name" :open-delay="300" placement="top" effect="dark">
  344. <span class="over-ellipsis">{{ data.shop_name }}</span>
  345. </el-tooltip>
  346. <span class="top-right">
  347. <el-tooltip content="查看" :open-delay="300" placement="top" effect="dark">
  348. <el-button type="text" size="mini" icon="el-icon-search"
  349. @click.stop="() => onLook(data.shop_id)"></el-button>
  350. </el-tooltip>
  351. </span>
  352. </span>
  353. </el-tree>
  354. </div>
  355. </el-drawer>
  356. <!-- 切换代理-->
  357. </div>
  358. <script type="text/javascript">
  359. // import autofit from './node_modules/autofit.js'
  360. //vue挂载
  361. const app = new Vue({
  362. el: "#app",
  363. data: {
  364. centerTit: '守护之影睡眠监测系统',
  365. myWebsocket: null,
  366. connected: false,
  367. connecting: false,
  368. timer: null,
  369. alwaysTimer: null,
  370. breakTimer: null,
  371. frameList: [],
  372. mySns: '',
  373. closed: false,
  374. shopId: null,
  375. countFrom: {
  376. used: 0,
  377. inBed: 0
  378. },
  379. bedTimeData: [], // 在床、离床时间数据
  380. nowDate: '',
  381. warnList: [], // 告警列表
  382. todayWarnLogs: [], // 进入告警列表
  383. sleepReportFrom: {
  384. total_duration: 0,
  385. inbed_duration: 0,
  386. deep_duration: 0,
  387. rs_duration: 0
  388. },
  389. sleepReportList: [],
  390. todayTimeList: [],
  391. errCount: 0,
  392. selectDay: '',
  393. pickerOptions: {},
  394. selected: [],
  395. selectYearMonth: {
  396. year: '',
  397. month: ''
  398. },
  399. params: {
  400. sn: '',
  401. reportTime: -1
  402. },
  403. setClick: false,
  404. selectIndex: 0,
  405. myFullName: '',
  406. myNickName: '',
  407. code: null, // 看板设置唯一码
  408. shopInfo: null,
  409. drawer: false,
  410. agentList: [], // 代理列表
  411. filterText: '',
  412. defaultProps: {
  413. children: 'children',
  414. label: 'label'
  415. },
  416. serverUrl: null,
  417. boolCheck: false,
  418. boolAgent: false
  419. },
  420. watch: {
  421. filterText(val) {
  422. this.$refs.tree.filter(val);
  423. }
  424. },
  425. mounted() {
  426. autofit.init({
  427. dh: 1080,
  428. dw: 1920,
  429. el: "body",
  430. resize: true
  431. })
  432. this.pickerOptions = {
  433. disabledDate(time) {
  434. return time.getTime() > Date.now();
  435. },
  436. cellClassName: (time) => {
  437. if (this.selected.includes(this.unixToDate2(time / 1000, "yyyy-MM-dd"))) {
  438. return 'badge'
  439. }
  440. }
  441. }
  442. this.code = this.getUrlQuery("code")
  443. if (!this.shopId && !this.code) {
  444. this.$message.error('机构参数错误,请联系管理员')
  445. return
  446. }
  447. const now = new Date().setHours(0, 0, 0, 0)
  448. this.nowDate = new Date(now)
  449. this.API_GetSetting()
  450. // 左右自动上下轮播
  451. // const lcon = document.getElementById('l-con');
  452. // this.autoScroll(300, 5000, 5000, lcon);
  453. // 获取床位设备列表
  454. },
  455. methods: {
  456. API_GetSetting() {
  457. const _this = this
  458. get("/bulletin_board_mattress/get_setting_by_code/" + this.code).then(res => {
  459. // console.log('res======', res)
  460. if (res) {
  461. this.serverUrl = 'http://' + res.server_url
  462. this.shopId = res.shop_id
  463. this.API_GetShopInfo()
  464. if (baseUrl.indexOf(res.server_url) > -1) {
  465. console.log('------------------------')
  466. _this.boolAgent = true
  467. }
  468. } else {
  469. _this.$message.error('看板参数不正确,请确定')
  470. }
  471. }).catch(err => {
  472. console.log('err====', err)
  473. })
  474. },
  475. API_GetShopInfo() {
  476. const _this = this
  477. const url = this.serverUrl + '/bulletin_board_mattress/get_shop_by_id/' + this.shopId
  478. get(url).then(res => {
  479. // console.log('res======', res)
  480. if (res) {
  481. this.shopInfo = res
  482. this.centerTit = res.shop_name + '睡眠监测看板'
  483. this.API_GetFrameList()
  484. setInterval(() => {
  485. console.log('刷新一次')
  486. _this.API_GetFrameList()
  487. setTimeout(() => {
  488. console.log('刷新一次11111111')
  489. _this.mySns = ''
  490. _this.sendSns()
  491. }, 5000)
  492. }, 60000 * 60) // 一个小时刷新一次
  493. if (this.shopInfo.shop_type === '4' || this.shopInfo.shop_type === '6') {
  494. _this.boolCheck = true
  495. _this.API_GetAgentList()
  496. }
  497. } else {
  498. _this.$message.error('机构参数不正确,请确定')
  499. }
  500. }).catch(err => {
  501. console.log('err====', err)
  502. })
  503. },
  504. API_GetFrameList() {
  505. const url = this.serverUrl + '/bulletin_board_mattress/get_mattress_info/' + this.shopId
  506. get(url).then(res => {
  507. console.log('res======', res)
  508. this.frameList = res
  509. if (res.length === 0) {
  510. this.sendSns()
  511. this.countFrom = {
  512. used: 0,
  513. inBed: 0
  514. }
  515. } else {
  516. this.countFrom.used = res.filter(item => item.nickname).length
  517. this.sendSns()
  518. // websocket连接
  519. this.initWebSocket()
  520. this.changeLookBed(res[0])
  521. }
  522. }).catch(err => {
  523. console.log('err====', err)
  524. })
  525. },
  526. initWebSocket: function () {
  527. if (this.connected || this.connecting) {
  528. console.log('webSocket已连接或者正在连接')
  529. return
  530. }
  531. this.connecting = true
  532. let time = Math.round(new Date()) + "" + Math.round(Math.random() * 100);
  533. console.log(time)
  534. let wsUrl = baseUrl.replace('http', 'ws')
  535. this.myWebsocket = new WebSocket(wsUrl + '/sleep_report/monitor/' + time)
  536. this.myWebsocket.onopen = this.websocketOnopen
  537. this.myWebsocket.onerror = this.websocketOnerror
  538. this.myWebsocket.onmessage = this.websocketOnmessage
  539. this.myWebsocket.onclose = this.websocketClose
  540. },
  541. websocketOnopen: function () {
  542. console.log('webSocket连接成功...')
  543. this.connecting = false
  544. this.connected = true
  545. // 清理重连定时器
  546. clearInterval(this.breakTimer)
  547. this.breakTimer = null
  548. // 心跳
  549. let _this = this
  550. this.timer = setInterval(function () { //每隔60秒钟发送一次心跳,避免websocket连接因超时而自动断开
  551. _this.myWebsocket.send('ping')
  552. // 监测床垫掉线
  553. _this.frameList.forEach(item => {
  554. item.boolOnline = false
  555. })
  556. setTimeout(function () {
  557. _this.frameList.forEach(item => {
  558. if (!item.boolOnline) {
  559. item.status = ''
  560. const i = _this.bedTimeData.findIndex(t => t.imei === item.imei)
  561. if (i !== -1) {
  562. // 修改离床状态
  563. _this.bedTimeData.splice(i, 1)
  564. if (_this.countFrom.inBed > 0) {
  565. _this.countFrom.inBed--
  566. }
  567. }
  568. // 修改心率与呼吸率
  569. item.heart = 0
  570. item.breathe = 0
  571. }
  572. })
  573. }, 5000)
  574. }, 55000) // 60秒的心跳包
  575. // this.alwaysTimer = setInterval(function () { // 监测床垫掉线
  576. // }, 30000)
  577. // 发送设备列表
  578. this.sendSns()
  579. },
  580. websocketOnerror: function (e) {
  581. console.log('webSocket连接失败...')
  582. this.connecting = false
  583. this.connected = false
  584. },
  585. websocketOnmessage: function (e) {
  586. // console.log('收到消息:', e)
  587. let msg = e.data
  588. // console.log('收到消息:', msg)
  589. switch (msg.length) {
  590. case 1:
  591. // 判断是否连接
  592. this.isConnect = true
  593. break
  594. case 234:
  595. const imei = msg.substring(2, 14)
  596. // 实时睡眠数据
  597. let index = this.frameList.findIndex(item => item.imei === imei)
  598. if (index === -1) {
  599. return
  600. }
  601. this.frameList[index].boolOnline = true
  602. this.frameList[index].heart = parseInt(msg.substring(22, 24), 16)
  603. this.frameList[index].breathe = parseInt(msg.substring(24, 26), 16)
  604. switch (msg.substring(26, 28)) {
  605. case "04": // 离床
  606. this.frameList[index].status = '离床'
  607. this.setBedTimeData(imei, false)
  608. break;
  609. case "03":
  610. case "05":
  611. case "06":
  612. this.frameList[index].status = '在床'
  613. this.setBedTimeData(imei, true)
  614. break;
  615. default:
  616. break;
  617. }
  618. break
  619. default: // 报警信息
  620. const data = JSON.parse(e.data)
  621. let i = this.frameList.findIndex(item => item.imei === data.sn)
  622. if (i === -1) {
  623. return
  624. }
  625. // this.warnList.push(data)
  626. this.$set(this.frameList[i], 'boolWarn', true)
  627. setTimeout(() => {
  628. this.$set(this.frameList[i], 'boolWarn', false)
  629. }, 10000) // 10秒后恢复正常
  630. this.setWarnData(data, !this.boolAgent ? this.frameList[i].full_name : this.frameList[i].nickname)
  631. break
  632. }
  633. },
  634. websocketClose: function (e) {
  635. console.log('connection closed (' + e.code + ')', ' 连接断开...')
  636. const _this = this
  637. this.connected = false
  638. this.closed = true
  639. // 清理心跳定时器
  640. clearInterval(this.timer)
  641. clearInterval(this.alwaysTimer)
  642. this.timer = null
  643. this.alwaysTimer = null
  644. if (!this.breakTimer) {
  645. this.breakTimer = setInterval(function () {
  646. console.log('正在重连...')
  647. _this.initWebSocket();
  648. }, 15000); // 5秒重连一次
  649. }
  650. },
  651. // 获取睡眠报告
  652. API_GetSleepReport() {
  653. const _this = this
  654. this.todayTimeList = []
  655. post("/bulletin_board_mattress/get_new_report_by_sn", this.params).then(res => {
  656. let size = 0, i = 0
  657. if (res.data.length > 0) {
  658. res.data.forEach((item, index) => {
  659. if (item.total_duration > size) {
  660. size = item.total_duration
  661. i = index
  662. _this.selectIndex = i
  663. }
  664. _this.todayTimeList.push({name: item.gobed_time + '~' + item.outbed_time, id: index})
  665. })
  666. _this.sleepReportFrom = Object.assign({}, res.data[i])
  667. _this.sleepReportFrom.report_content = JSON.parse(_this.sleepReportFrom.report_content)
  668. _this.selectDay = _this.unixToDate2(_this.sleepReportFrom.report_time, "yyyy-MM-dd")
  669. _this.sleepReportList = res.data
  670. if (_this.params.reportTime === -1) {
  671. let str = _this.selectDay.split("-")
  672. _this.selectYearMonth.year = str[0]
  673. _this.selectYearMonth.month = str[1]
  674. _this.getDaysTag()
  675. }
  676. _this.qualifiedCount(_this.sleepReportFrom.report_content)
  677. _this.initAllChar(_this.sleepReportFrom)
  678. } else {
  679. this.myFullName = ''
  680. this.myNickName = ''
  681. this.$message({
  682. message: '暂无睡眠报告',
  683. type: 'warning'
  684. })
  685. }
  686. }).catch(err => {
  687. console.log('err====', err)
  688. })
  689. },
  690. // 获取日期点
  691. getDaysTag() {
  692. post("/bulletin_board_mattress/get_sleep_report_days_tag_by_sn", this.selectYearMonth).then(res => {
  693. this.selected = []
  694. res.data.forEach(p => {
  695. this.selected.push(this.selectYearMonth.year + '-' + this.selectYearMonth.month + '-' + p.flog_time)
  696. })
  697. }).catch(err => {
  698. console.log('err====', err)
  699. })
  700. },
  701. // 发送webSocket设备列表
  702. sendSns() {
  703. if (this.connected) {
  704. if (this.frameList.length > 0) {
  705. let sns = []
  706. this.frameList.forEach(item => {
  707. if (item.imei) {
  708. sns.push(item.imei)
  709. }
  710. })
  711. if (sns.length === 0) {
  712. return
  713. }
  714. const data = sns.join(',')
  715. if (!this.mySns) {
  716. this.mySns = data
  717. } else {
  718. if (data === this.mySns && !this.closed) {
  719. return
  720. } else {
  721. this.closed = false
  722. this.mySns = data
  723. }
  724. }
  725. console.log('发送imei给服务器...', data)
  726. this.myWebsocket.send(data)
  727. this.API_GetRightData()
  728. } else {
  729. this.mySns = ''
  730. this.myWebsocket.send('')
  731. }
  732. }
  733. },
  734. // 获取看板右边数据
  735. API_GetRightData() {
  736. const params = {
  737. sns: this.mySns,
  738. time: this.nowDate.getTime() / 1000
  739. }
  740. post("/bulletin_board_mattress/get_right_data", params).then(res => {
  741. // 实时报警数据(进入报警)
  742. if (res.data.todayWarnLogs) {
  743. res.data.todayWarnLogs.forEach(item => {
  744. let i = this.frameList.findIndex(t => t.imei === item.sn)
  745. if (i !== -1) {
  746. item.named = !this.boolAgent ? this.frameList[i].full_name : this.frameList[i].nickname
  747. }
  748. const now = new Date(item.warn_time * 1000)
  749. item.warn_time = `${now.getHours()}:${now.getMinutes()}`
  750. switch (item.warn_type) {
  751. case 0:
  752. item.warn_class = 'jj'
  753. break
  754. case 1:
  755. item.warn_class = 'xl'
  756. break
  757. case 3:
  758. item.warn_class = 'hx'
  759. break
  760. case 4:
  761. item.warn_class = 'lc'
  762. break
  763. default:
  764. break
  765. }
  766. })
  767. this.todayWarnLogs = res.data.todayWarnLogs
  768. }
  769. // 昨天睡眠报表
  770. if (res.data.yesterdayReportChar) {
  771. let count = 0
  772. res.data.yesterdayReportChar.forEach(item => {
  773. count += parseInt(item.value)
  774. })
  775. this.setPieData('yesterday-sleep-report', count, res.data.yesterdayReportChar, ['#4085F7', '#53B389', '#D09464', '#D1D075'], '份')
  776. }
  777. // 昨天告警报表
  778. if (res.data.yesterdayWarnChar) {
  779. let count = 0
  780. res.data.yesterdayWarnChar.forEach(item => {
  781. count += parseInt(item.value)
  782. switch (item.name) {
  783. case '0':
  784. item.name = '紧急呼叫'
  785. break;
  786. case '1':
  787. item.name = '心率异常'
  788. break
  789. case '2':
  790. item.name = '呼吸异常'
  791. break
  792. case '3':
  793. item.name = '长时离床'
  794. break
  795. default:
  796. break;
  797. }
  798. })
  799. this.setPieData('yesterday-warn-report', count, res.data.yesterdayWarnChar, ['#972AF0', '#A66B55', '#119EEE', '#A5317E'], '次')
  800. }
  801. }).catch(err => {
  802. console.log('err====', err)
  803. })
  804. },
  805. /*
  806. * stepLength:一次滚动步长
  807. * speed:滚动速度
  808. * delay:停留时间
  809. * element:Element对象
  810. * element.offsetHeight 元素的像素高度(包括边框和填充)
  811. * element.scrollTop 元素的内容垂直滚动的像素
  812. * element.scrollHeight 元素的高度(包括带滚动条的隐蔽的地方)
  813. */
  814. autoScroll: function (stepLength, speed, delay, element) {
  815. let interval
  816. //let step = 1
  817. element.scrollTop = 0
  818. function start() {
  819. interval = setInterval(scrolling, speed)
  820. element.scrollTop += stepLength
  821. }
  822. function scrolling() {
  823. var sTop = element.scrollTop;
  824. element.scrollTop += stepLength;
  825. if (sTop === element.scrollTop || sTop == 0 || element.scrollTop === (element.scrollHeight - element
  826. .offsetHeight)) {
  827. stepLength *= -1 // 转换方向
  828. clearInterval(interval)
  829. setTimeout(start, delay)
  830. }
  831. }
  832. if (element.offsetHeight !== element.scrollHeight) { // 元素内容没有溢出时,不触发
  833. setTimeout(start, delay)
  834. }
  835. },
  836. // 计算睡眠不及格项
  837. qualifiedCount(data) {
  838. let count = 0
  839. if (data.avg_hx.state === 1) {
  840. count++
  841. } else if (data.sleep_eff.state === 1) {
  842. count++
  843. } else if (data.avg_rh.state === 1) {
  844. count++
  845. } else if (data.move_count.state === 1) {
  846. count++
  847. } else if (data.outbed_count.state === 1) {
  848. count++
  849. } else if (data.snoring_count.state === 1) {
  850. count++
  851. }
  852. this.errCount = count
  853. },
  854. initAllChar(data) {
  855. const _this = this
  856. setTimeout(() => {
  857. _this.setLineChart("leave-report", 1, data.report_content.dt_arr, data.report_content.outbed_arr)
  858. _this.setLineChart("movement-report", 2, data.report_content.dt_arr, data.report_content.move_arr)
  859. _this.setLineChart("heart-report", 3, data.report_content.dt_arr, data.report_content.rh_arr)
  860. _this.setLineChart("breathe-report", 4, data.report_content.dt_arr, data.report_content.hx_arr)
  861. _this.setLineChart("snore-report", 0, data.report_content.dt_arr, data.report_content.snoring_arr)
  862. _this.setLineChart("suspend-report", 6, data.report_content.dt_arr, data.report_content.hxstop_arr)
  863. _this.setLineChart("depth-report", -1, data.report_content.dt_arr, data.report_content.sleep_arr)
  864. }, 800)
  865. },
  866. // 组装折线图表
  867. setLineChart(refChar, type, xData, yData) {
  868. let options = Object.assign(this.getLineOptions(xData, yData), {})
  869. let myPieChart = echarts.init(document.getElementById(refChar))
  870. if (type <= 2) {
  871. options.yAxis = this.getLineYAxis1(type)
  872. } else {
  873. options.yAxis = this.getLineYAxis2()
  874. }
  875. if (type === -1) {
  876. options.series[0].areaStyle = {}
  877. }
  878. myPieChart.setOption(options)
  879. },
  880. // 获取折线图配置
  881. getLineOptions(xData, yData) {
  882. return {
  883. grid: {
  884. top: 30,
  885. right: 10,
  886. left: 40
  887. },
  888. xAxis: {
  889. type: 'category',
  890. data: xData,
  891. axisLine: {
  892. lineStyle: {
  893. color: "#323C77", //最左侧x轴颜色
  894. }
  895. },
  896. splitLine: {
  897. show: true,
  898. lineStyle: {
  899. color: "#323C77"
  900. }
  901. },
  902. axisLabel: {
  903. fontSize: 9,
  904. color: "#A5B6CA"
  905. }
  906. },
  907. yAxis: {},
  908. series: [
  909. {
  910. data: yData,
  911. type: 'line',
  912. smooth: true,
  913. showSymbol: false,
  914. hoverAnimation: false
  915. }
  916. ]
  917. }
  918. },
  919. getLineYAxis1(type) {
  920. let min = 0, max = 1
  921. if (type === -1) {
  922. min = 0
  923. max = 'dataMax'
  924. }
  925. return {
  926. type: 'value',
  927. // boundaryGap: [0, '100%'],
  928. min: min,
  929. max: max, // dataMax取数据在该轴上的最大值作为最大刻度
  930. splitNumber: 4,
  931. minInterval: 1,
  932. splitLine: {
  933. show: false, // 是否显示分隔线
  934. },
  935. axisLine: {
  936. show: true, // 是否显示坐标轴轴线
  937. lineStyle: {
  938. color: '#FFFFFF',
  939. width: 0.5, //x轴线的宽度
  940. }
  941. },
  942. axisLabel: {
  943. formatter: function (value) {
  944. switch (type) {
  945. case -1:
  946. let str = ''
  947. switch (value) {
  948. case 0:
  949. str = '清醒'
  950. break
  951. case 10:
  952. str = '浅睡'
  953. break
  954. case 20:
  955. str = '中睡'
  956. break
  957. case 30:
  958. str = '深睡'
  959. break
  960. default:
  961. break
  962. }
  963. return str
  964. case 0:
  965. return value === 0 ? '睡眠' : '打鼾'
  966. case 1:
  967. return value === 0 ? '离床' : '在床'
  968. case 2:
  969. return value === 0 ? '睡眠' : '体动'
  970. default:
  971. return value
  972. }
  973. }
  974. }
  975. }
  976. },
  977. getLineYAxis2() {
  978. return {
  979. type: 'value',
  980. boundaryGap: [0, '100%'],
  981. min: 0,
  982. max: 'dataMax', // 取数据在该轴上的最大值作为最大刻度
  983. splitLine: {
  984. show: false, // 是否显示分隔线
  985. },
  986. axisLine: {
  987. show: false, // 是否显示坐标轴轴线
  988. lineStyle: {
  989. color: '#FFFFFF'
  990. }
  991. }
  992. }
  993. },
  994. // 组装饼状图
  995. setPieData(refChar, count, data, color, unit) {
  996. let options = Object.assign(this.getPieOptions(count, data, color, unit), {})
  997. let myPieChart = echarts.init(document.getElementById(refChar))
  998. myPieChart.setOption(options)
  999. },
  1000. // 获取饼状图配置
  1001. getPieOptions(count, data, color, unit) {
  1002. return {
  1003. title: {
  1004. text: '总计:' + count + unit,
  1005. left: 'center',
  1006. textStyle: {
  1007. color: '#fff',
  1008. fontWeight: 'normal',
  1009. fontSize: 14
  1010. }
  1011. },
  1012. tooltip: {
  1013. trigger: 'item'
  1014. },
  1015. legend: {
  1016. left: 'center',
  1017. top: 30,
  1018. textStyle: {
  1019. color: '#fff'
  1020. }
  1021. },
  1022. series: [
  1023. {
  1024. top: 65,
  1025. type: 'pie',
  1026. radius: ['40%', '70%'],
  1027. label: {
  1028. show: true,
  1029. color: '#fff',
  1030. fontWeight: 'normal',
  1031. formatter(param) {
  1032. return param.data.value + unit;
  1033. }
  1034. },
  1035. color: color,
  1036. data: data
  1037. },
  1038. ]
  1039. }
  1040. },
  1041. // 存储实时离床、在床数据
  1042. setBedTimeData(imei, boolInBed) {
  1043. const i = this.bedTimeData.findIndex(item => item.imei === imei)
  1044. if (i === -1) {
  1045. this.bedTimeData.push({
  1046. imei: imei,
  1047. inBedTime: new Date(),
  1048. status: boolInBed
  1049. })
  1050. if (boolInBed) {
  1051. this.countFrom.inBed++
  1052. }
  1053. } else {
  1054. if (!this.bedTimeData[i].status === boolInBed) {
  1055. this.bedTimeData[i] = {
  1056. imei: imei,
  1057. inBedTime: new Date(),
  1058. status: boolInBed
  1059. }
  1060. if (boolInBed) {
  1061. this.countFrom.inBed++
  1062. } else {
  1063. this.countFrom.inBed--
  1064. }
  1065. }
  1066. }
  1067. },
  1068. // 组装报警信息
  1069. setWarnData(data, named) {
  1070. const now = new Date(data.warn_time)
  1071. const time = `${now.getHours()}:${now.getMinutes()}`
  1072. let warn_class = ''
  1073. switch (data.warn_type) {
  1074. case 1:
  1075. case 2:
  1076. warn_class = 'xl'
  1077. break
  1078. case 3:
  1079. case 4:
  1080. warn_class = 'hx'
  1081. break
  1082. case 5:
  1083. warn_class = 'lc'
  1084. break
  1085. case 6:
  1086. warn_class = 'jj'
  1087. break
  1088. default:
  1089. break
  1090. }
  1091. this.warnList.unshift({
  1092. warn_time: time,
  1093. warn_class: warn_class,
  1094. named: named
  1095. })
  1096. },
  1097. // 根据状态获取离床、在床样式
  1098. getStatusClass(item) {
  1099. let str = ''
  1100. switch (item.status) {
  1101. case '离床':
  1102. str = 'offline'
  1103. break
  1104. case '在床':
  1105. str = 'online'
  1106. break
  1107. default:
  1108. break
  1109. }
  1110. str += item.boolWarn ? ' warn' : ''
  1111. return str
  1112. },
  1113. // 根据imei获取在床、离床时间
  1114. getTimeByImei(imei) {
  1115. const index = this.bedTimeData.findIndex(item => item.imei === imei)
  1116. if (index === -1) {
  1117. return '--:--'
  1118. } else {
  1119. if (this.bedTimeData[index].inBedTime > this.nowDate) {
  1120. return this.unixToDate(this.bedTimeData[index].inBedTime, 1)
  1121. } else {
  1122. return this.unixToDate(this.bedTimeData[index].inBedTime, 0)
  1123. }
  1124. }
  1125. },
  1126. unixToDate(date, type) {
  1127. let year = date.getFullYear()
  1128. let month = date.getMonth() + 1
  1129. let day = date.getDate()
  1130. let hours = date.getHours()
  1131. let minutes = date.getMinutes()
  1132. let seconds = date.getSeconds()
  1133. if (Number(month) < 10) {
  1134. // 10月之前都需要补0
  1135. month = '0' + month
  1136. }
  1137. if (Number(day) < 10) {
  1138. // 10天之前都需要补0
  1139. day = '0' + day
  1140. }
  1141. if (Number(hours) < 10) {
  1142. // 10小时之前都需要补0
  1143. hours = '0' + hours
  1144. }
  1145. if (Number(minutes) < 10) {
  1146. // 10分钟之前都需要补0
  1147. minutes = '0' + minutes
  1148. }
  1149. let formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  1150. if (type === 0) {
  1151. return `${month}月${day}`
  1152. } else {
  1153. return `${hours}:${minutes}`
  1154. }
  1155. },
  1156. /**
  1157. * 将unix时间戳转换为指定格式
  1158. * @param unix 时间戳【秒】
  1159. * @param format 转换格式
  1160. * @returns {*|string}
  1161. */
  1162. unixToDate2(unix, format) {
  1163. if (!unix) return unix
  1164. let _format = format || 'yyyy-MM-dd hh:mm:ss'
  1165. const d = new Date(unix * 1000)
  1166. const o = {
  1167. 'M+': d.getMonth() + 1,
  1168. 'd+': d.getDate(),
  1169. 'h+': d.getHours(),
  1170. 'm+': d.getMinutes(),
  1171. 's+': d.getSeconds(),
  1172. 'q+': Math.floor((d.getMonth() + 3) / 3),
  1173. S: d.getMilliseconds()
  1174. }
  1175. if (/(y+)/.test(_format)) _format = _format.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length))
  1176. for (const k in o) if (new RegExp('(' + k + ')').test(_format)) _format = _format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
  1177. return _format
  1178. },
  1179. // 将分转化为时分
  1180. formateSeconds(endTime, type) {
  1181. let secondTime = endTime//将传入的秒的值转化为Number
  1182. let hourStr, minuteStr
  1183. if (type === 0) {
  1184. hourStr = '小时'
  1185. minuteStr = '分钟'
  1186. } else {
  1187. hourStr = '时'
  1188. minuteStr = '分'
  1189. }
  1190. let h = 0// 初始化小时
  1191. if (secondTime > 60) {//如果秒数大于60,将秒数转换成整数
  1192. h = parseInt(secondTime / 60)//获取小时,获取分钟除以60,得到整数小时
  1193. secondTime = parseInt(secondTime % 60) //获取小时后取佘的分,获取分钟除以60取佘的分
  1194. return h + hourStr + secondTime + minuteStr
  1195. } else {
  1196. return secondTime + minuteStr
  1197. }
  1198. },
  1199. formartName(name) {
  1200. if (name.length > 4) {
  1201. return name.substring(0, 4) + '...'
  1202. } else {
  1203. return name
  1204. }
  1205. },
  1206. // 选择日期
  1207. changeDate(e) {
  1208. let month = e.getMonth() + 1, day = e.getDate()
  1209. if (Number(month) < 10) {
  1210. // 10月之前都需要补0
  1211. month = '0' + month
  1212. }
  1213. if (Number(day) < 10) {
  1214. // 10天之前都需要补0
  1215. day = '0' + day
  1216. }
  1217. const str = e.getFullYear() + '-' + month + '-' + day
  1218. if (this.selected.findIndex(item => item === str) === -1) {
  1219. this.$message({
  1220. message: str + '没有睡眠报告,请选择其他日期',
  1221. type: 'warning'
  1222. })
  1223. return
  1224. }
  1225. this.params.reportTime = Math.round(e / 1000)
  1226. this.API_GetSleepReport()
  1227. },
  1228. // 获取焦点 展示日期
  1229. async isShow(e) {
  1230. await this.$nextTick()
  1231. if (this.setClick) return
  1232. document.querySelector('.el-month-table').addEventListener('click', () => {
  1233. this.monthChange()
  1234. })
  1235. document.querySelectorAll("[aria-label='下个月'],[aria-label='上个月'],[aria-label='后一年'],[aria-label='前一年']")
  1236. .forEach(item => item.addEventListener('click', () => {
  1237. this.monthChange()
  1238. }))
  1239. this.setClick = true
  1240. },
  1241. // 切换年月后重新调接口
  1242. async monthChange() {
  1243. let year, month
  1244. // 获取年月
  1245. year = document.querySelectorAll('.el-date-picker__header-label')[0].innerHTML.slice(0, 4)
  1246. month = document.querySelectorAll('.el-date-picker__header-label')[1].innerHTML.slice(0, -1)
  1247. if (Number(month) < 10) {
  1248. // 10月之前都需要补0
  1249. month = '0' + month;
  1250. }
  1251. const _this = this
  1252. _this.selectYearMonth.year = year
  1253. _this.selectYearMonth.month = month.trim()
  1254. this.getDaysTag()
  1255. },
  1256. // 选择睡眠时间段
  1257. pickerChange(index) {
  1258. this.sleepReportFrom = Object.assign({}, this.sleepReportList[index])
  1259. this.sleepReportFrom.report_content = JSON.parse(this.sleepReportFrom.report_content)
  1260. this.qualifiedCount(this.sleepReportFrom.report_content)
  1261. this.initAllChar(this.sleepReportFrom)
  1262. },
  1263. changeLookBed(item) {
  1264. this.params.sn = item.imei
  1265. this.selectYearMonth.sn = item.imei
  1266. this.myFullName = item.full_name
  1267. this.myNickName = item.nickname
  1268. this.params.reportTime = -1
  1269. this.API_GetSleepReport()
  1270. },
  1271. // 获取url参数
  1272. getUrlQuery(name) {
  1273. let reg = new RegExp('(^|&)' + name + "=([^&]*)", "i");
  1274. let r = decodeURI(window.location.search.substr(1)).match(reg);
  1275. if (r != null) return r[2]; return null;
  1276. },
  1277. filterNode(value, data) {
  1278. if (!value) return true;
  1279. return data.shop_name.indexOf(value) !== -1;
  1280. },
  1281. // 获取代理列表
  1282. API_GetAgentList() {
  1283. // getAllSubordinateAgents
  1284. get('/bulletin_board_mattress/get_child_recursion/' + this.shopId).then(res => {
  1285. console.log('res======', res)
  1286. this.agentList = res
  1287. }).catch(err => {
  1288. console.log('err====', err)
  1289. })
  1290. },
  1291. onLook(shopId) {
  1292. console.log('查看data===', shopId)
  1293. this.shopId = shopId
  1294. this.drawer = false
  1295. this.API_GetFrameList()
  1296. }
  1297. }
  1298. });
  1299. </script>
  1300. </body>
  1301. </html>