data.js 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429
  1. import * as echarts from '../../ec-canvas/echarts';
  2. // 渐变圆环
  3. let chartCircularProgressBar;//圈圈
  4. let chartOutOfBed;//离床
  5. let chartBodyMovementsLine;//体动
  6. let chartCardiacSystemLine;//心脏系统
  7. let chartRespiratoryLine;//平均呼吸率
  8. let chartSnoringLine;//打鼾
  9. let chartApneaLine;//呼吸暂停
  10. let chartTimeWaterfall;//深浅睡眠
  11. // 圈圈>90分极好(绿色)
  12. // > 75分,(浅绿色)良好
  13. // 各项睡眠监测数据统计 > 60分,较差(黄色)
  14. // < 60分,很差(红色)
  15. function setChartCircularProgressBarOption(chart, data = {}) {
  16. var rscore_value = data?.rscore_value || 0;
  17. var checkList = [{
  18. title: "极好",
  19. titleColor: "#0BC3AA",
  20. startColor: "#0AB1C3",
  21. centerColor: "#0BC3AA",
  22. endColor: "#36E1CA",
  23. }, {
  24. title: "良好",
  25. titleColor: "#9C43FF",
  26. startColor: "#8D25FF",
  27. centerColor: "#A631FF",
  28. endColor: "#FF8FF0",
  29. }, {
  30. title: "较差",
  31. titleColor: "#FF8F4E",
  32. startColor: "#EE8B52",
  33. centerColor: "#FAA472",
  34. endColor: "#FAA472",
  35. }, {
  36. title: "很差",
  37. titleColor: "#FB717B",
  38. startColor: "#FB717B",
  39. centerColor: "#FB717B",
  40. endColor: "#FF98A0",
  41. }];
  42. var checkData = checkList[0];
  43. if (rscore_value >= 90 && rscore_value <= 100) {
  44. checkData = checkList[0];
  45. } else if (rscore_value >= 75 && rscore_value < 90) {
  46. checkData = checkList[1];
  47. } else if (rscore_value >= 60 && rscore_value < 75) {
  48. checkData = checkList[2];
  49. } else {
  50. checkData = checkList[3];
  51. }
  52. // 定义仪表盘配置项
  53. var option = {
  54. series: [
  55. {
  56. type: 'gauge', // 仪表盘类型
  57. startAngle: -270, // 仪表盘起始角度
  58. endAngle: 90, // 仪表盘结束角度
  59. legendHoverLink: true, // 是否启用图例悬浮联动
  60. min: 0, // 仪表盘最小值
  61. max: 100, // 仪表盘最大值
  62. itemStyle: {
  63. color: '#58D9F9', // 仪表盘背景色
  64. shadowColor: 'rgba(0,138,255,0.45)', // 阴影颜色
  65. shadowBlur: 5, // 阴影模糊大小
  66. shadowOffsetX: 1, // 阴影水平偏移
  67. shadowOffsetY: 1 // 阴影垂直偏移
  68. },
  69. progress: {
  70. show: true, // 是否显示进度条
  71. roundCap: true, // 是否显示圆角
  72. width: 10, // 进度条宽度
  73. itemStyle: {
  74. // 进度条样式
  75. color: {
  76. // 自定义渐变色
  77. type: 'linear',
  78. x: 0.75,
  79. y: 0.75,
  80. x2: 0,
  81. y2: 0.75,
  82. colorStops: [
  83. {
  84. offset: 0,
  85. color: checkData.startColor // 0% 处的颜色
  86. },
  87. {
  88. offset: 0.5,
  89. color: checkData.centerColor // 100% 处的颜色
  90. },
  91. {
  92. offset: 1,
  93. color: checkData.endColor // 100% 处的颜色
  94. }
  95. ],
  96. global: false // 缺省为 false
  97. }
  98. }
  99. },
  100. pointer: {
  101. show: false, // 是否显示指针
  102. },
  103. axisLine: {
  104. roundCap: true, // 是否显示圆角
  105. lineStyle: {
  106. width: 10, // 轴线宽度
  107. }
  108. },
  109. axisTick: {
  110. show: false // 是否显示分隔线
  111. },
  112. splitLine: {
  113. show: false // 是否显示分隔线
  114. },
  115. axisLabel: {
  116. show: false, // 是否显示标签
  117. },
  118. title: {
  119. color: checkData.titleColor, // 标题颜色
  120. offsetCenter: [0, '-36%'], // 标题位置
  121. lineHeight: 15, // 行高
  122. fontSize: 15, // 字体大小
  123. },
  124. detail: {
  125. backgroundColor: '#fff', // 背景颜色
  126. width: '60%', // 宽度
  127. lineHeight: 40, // 行高
  128. height: 40, // 高度
  129. color: '#333333', // 字体颜色
  130. offsetCenter: [0, "24%"], // 位置
  131. valueAnimation: true, // 是否启用值的动画效果
  132. formatter: function (value) {
  133. value=(isNaN(value)||null||undefined)?"--":value.toFixed(0);
  134. return '{value|' + value+ '}'; // 数据格式化
  135. },
  136. rich: {
  137. value: {
  138. fontSize: 30, // 字体大小
  139. fontWeight: 'bolder', // 加粗
  140. color: checkData.titleColor // 颜色
  141. },
  142. }
  143. },
  144. data: [
  145. {
  146. name: data?.rscore_desc || checkData.title || '无', // 数据名称
  147. value: data?.rscore_value || 0 // 数据值
  148. }
  149. ]
  150. }
  151. ]
  152. };
  153. chart.setOption(option, true);
  154. }
  155. function initChartHumidifier(canvas, width, height, dpr) {
  156. // this.selectComponent('#mychart-dom-bar00').init((canvas, width, height, dpr) => {
  157. // 获取组件的 canvas、width、height 后的回调函数
  158. // 在这里初始化图表
  159. const chart = echarts.init(canvas, null, {
  160. width: width,
  161. height: height,
  162. devicePixelRatio: dpr // new
  163. });
  164. canvas.setChart(chart);
  165. setChartCircularProgressBarOption(chart);
  166. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  167. chartCircularProgressBar = chart;
  168. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  169. return chart;
  170. // });
  171. };
  172. function updateChartCircularProgressBarOption(rscore_desc, rscore_value, that) {
  173. if (chartCircularProgressBar) {
  174. setChartCircularProgressBarOption(chartCircularProgressBar, { rscore_desc, rscore_value });
  175. } else {
  176. that.selectComponent('#mychart-dom-CircularProgressBar').init((canvas, width, height, dpr) => {
  177. const chart = echarts.init(canvas, null, {
  178. width: width,
  179. height: height,
  180. devicePixelRatio: dpr // new
  181. });
  182. canvas.setChart(chart);
  183. setChartCircularProgressBarOption(chart, { rscore_desc, rscore_value });
  184. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  185. chartCircularProgressBar = chart;
  186. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  187. return chart;
  188. });
  189. }
  190. }
  191. //离床
  192. function initChartOutOfBed(canvas, width, height, dpr) {
  193. // this.selectComponent('#mychart-dom-bar00').init((canvas, width, height, dpr) => {
  194. // 获取组件的 canvas、width、height 后的回调函数
  195. // 在这里初始化图表
  196. const chart = echarts.init(canvas, null, {
  197. width: width,
  198. height: height,
  199. devicePixelRatio: dpr // new
  200. });
  201. canvas.setChart(chart);
  202. setChartOutOfBedOption(chart);
  203. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  204. chartOutOfBed = chart;
  205. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  206. return chart;
  207. // });
  208. };
  209. function setChartOutOfBedOption(chart, data1 = [], data2 = [],) {
  210. var option = option = {
  211. tooltip: {
  212. show: true,
  213. trigger: 'axis',
  214. formatter: function (param) {
  215. return `${param[0] && param[0].value == 1 ? '在床' : '离床'}`
  216. }
  217. },
  218. dataZoom: [
  219. { // 第一个 dataZoom 组件
  220. type: 'inside',
  221. },
  222. ],
  223. grid: {
  224. top: '40rpx',
  225. left: 0,
  226. right: '20rpx',
  227. bottom: 0,
  228. containLabel: true
  229. },
  230. xAxis: {
  231. type: 'category',
  232. axisLabel: {
  233. color: '#6C6970',// 设置 x 轴标签颜色为白色
  234. fontSize: 10
  235. },
  236. boundaryGap: false,
  237. splitLine: {
  238. show: false, // 是否显示刻度线
  239. },
  240. axisTick: {
  241. // 不显示Y轴刻度线
  242. show: false
  243. },
  244. data: data1,
  245. axisLine: {
  246. // 不显示X轴轴线
  247. show: false
  248. }
  249. },
  250. yAxis: {
  251. // Y 轴配置
  252. type: 'value',
  253. show: false
  254. },
  255. series: [{
  256. type: 'line',
  257. name: '睡眠状态',
  258. smooth: true,
  259. lineStyle: {
  260. width: 1,
  261. color: '#54C68B'
  262. },
  263. emphasis: {
  264. disabled: true,
  265. scale: false,
  266. lineStyle: {
  267. width: 1,
  268. color: '#54C68B'
  269. },
  270. },
  271. showSymbol: false,
  272. areaStyle: {
  273. opacity: 0.8,
  274. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  275. {
  276. offset: 0,
  277. color: '#B8EBD0'
  278. },
  279. {
  280. offset: 1,
  281. color: 'rgba(255, 255, 255, 0)'
  282. }
  283. ])
  284. },
  285. data: data2,
  286. }]
  287. };
  288. chart.setOption(option, true);
  289. }
  290. function updateOutOfBed(data1, data2, startSleepTime, endSleepTime, that) {
  291. if (chartOutOfBed) {
  292. setChartOutOfBedOption(chartOutOfBed, data1, data2);
  293. } else {
  294. that.selectComponent('#chartOutOfBed-dom').init((canvas, width, height, dpr) => {
  295. const chart = echarts.init(canvas, null, {
  296. width: width,
  297. height: height,
  298. devicePixelRatio: dpr // new
  299. });
  300. canvas.setChart(chart);
  301. setChartOutOfBedOption(chart, data1, data2);
  302. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  303. chartOutOfBed = chart;
  304. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  305. return chart;
  306. });
  307. }
  308. }
  309. //体动
  310. function initChartBodyMovementsLine(canvas, width, height, dpr) {
  311. // 在这里初始化图表
  312. const chart = echarts.init(canvas, null, {
  313. width: width,
  314. height: height,
  315. devicePixelRatio: dpr // new
  316. });
  317. canvas.setChart(chart);
  318. setBodyMovementsOption(chart);
  319. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  320. chartBodyMovementsLine = chart;
  321. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  322. return chart;
  323. };
  324. function setBodyMovementsOption(chart, data1 = [], data2 = [],) {
  325. var option = option = {
  326. tooltip: {
  327. show: true,
  328. trigger: 'axis',
  329. formatter: function (param) {
  330. return `${param[0] && param[0].value == 1 ? '体动' : '否'}`
  331. }
  332. },
  333. dataZoom: [
  334. { // 第一个 dataZoom 组件
  335. type: 'inside',
  336. },
  337. ],
  338. grid: {
  339. top: '40rpx',
  340. left: 0,
  341. right: '20rpx',
  342. bottom: 0,
  343. containLabel: true
  344. },
  345. xAxis: {
  346. type: 'category',
  347. axisLabel: {
  348. color: '#6C6970',// 设置 x 轴标签颜色为白色
  349. fontSize: 10
  350. },
  351. boundaryGap: false,
  352. splitLine: {
  353. show: false, // 是否显示刻度线
  354. },
  355. axisTick: {
  356. // 不显示Y轴刻度线
  357. show: false
  358. },
  359. data: data1,
  360. axisLine: {
  361. // 不显示X轴轴线
  362. show: false
  363. }
  364. },
  365. yAxis: {
  366. // Y 轴配置
  367. type: 'value',
  368. show: false
  369. },
  370. series: [{
  371. name: '睡眠状态',
  372. type: 'line',
  373. smooth: true,
  374. lineStyle: {
  375. width: 1,
  376. color: '#5582FF'
  377. },
  378. emphasis: {
  379. disabled: true,
  380. scale: false,
  381. lineStyle: {
  382. width: 1,
  383. color: '#5582FF'
  384. },
  385. },
  386. showSymbol: false,
  387. areaStyle: {
  388. opacity: 0.8,
  389. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  390. {
  391. offset: 0,
  392. color: 'rgba(85, 130, 255, 0.5)'
  393. },
  394. {
  395. offset: 1,
  396. color: 'rgba(149, 177, 255, 0.3)'
  397. }
  398. ])
  399. },
  400. data: data2,
  401. }]
  402. };
  403. chart.setOption(option, true);
  404. }
  405. function updateBodyMovements(data1, data2, startSleepTime, endSleepTime, that) {
  406. if (chartBodyMovementsLine) {
  407. setBodyMovementsOption(chartBodyMovementsLine, data1, data2);
  408. } else {
  409. that.selectComponent('#chartBodyMovementsLine-dom').init((canvas, width, height, dpr) => {
  410. const chart = echarts.init(canvas, null, {
  411. width: width,
  412. height: height,
  413. devicePixelRatio: dpr // new
  414. });
  415. canvas.setChart(chart);
  416. setBodyMovementsOption(chart, data1, data2);
  417. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  418. chartBodyMovementsLine = chart;
  419. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  420. return chart;
  421. });
  422. }
  423. }
  424. //心脏系统
  425. function initChartCardiacSystemLine(canvas, width, height, dpr) {
  426. // 在这里初始化图表
  427. const chart = echarts.init(canvas, null, {
  428. width: width,
  429. height: height,
  430. devicePixelRatio: dpr // new
  431. });
  432. canvas.setChart(chart);
  433. setCardiacSystemOption(chart);
  434. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  435. chartCardiacSystemLine = chart;
  436. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  437. return chart;
  438. };
  439. function setCardiacSystemOption(chart, data1 = [], data2 = [],) {
  440. var option = option = {
  441. tooltip: {
  442. show: true,
  443. trigger: 'axis',
  444. formatter: function (param) {
  445. return `${(param[0].value || 0) + '次'}`
  446. }
  447. },
  448. dataZoom: [
  449. { // 第一个 dataZoom 组件
  450. type: 'inside',
  451. },
  452. ],
  453. grid: {
  454. top: '20rpx',
  455. left: '20rpx',
  456. right: '20rpx',
  457. bottom: '10rpx',
  458. containLabel: true
  459. },
  460. xAxis: {
  461. type: 'category',
  462. axisLabel: {
  463. color: '#6C6970',// 设置 x 轴标签颜色为白色
  464. fontSize: 10
  465. },
  466. boundaryGap: false,
  467. splitLine: {
  468. show: false, // 是否显示刻度线
  469. },
  470. axisTick: {
  471. // 不显示Y轴刻度线
  472. show: false
  473. },
  474. data: data1,
  475. axisLine: {
  476. // 不显示X轴轴线
  477. show: false
  478. }
  479. },
  480. yAxis: {
  481. type: 'value',
  482. max: 100,
  483. min: 0,
  484. show: true,
  485. offset: 10,
  486. splitLine: {
  487. show: false
  488. },
  489. axisLabel: {
  490. hideOverlap: true,
  491. fontSize: 10,
  492. }
  493. },
  494. series: [{
  495. type: 'line',
  496. smooth: true,
  497. lineStyle: {
  498. width: 1,
  499. color: '#F47893'
  500. },
  501. emphasis: {
  502. disabled: true,
  503. scale: false,
  504. lineStyle: {
  505. width: 1,
  506. color: '#F47893'
  507. },
  508. },
  509. showSymbol: false,
  510. areaStyle: {
  511. opacity: 0.8,
  512. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  513. {
  514. offset: 0,
  515. color: 'rgba(244, 120, 147, 0.5)'
  516. },
  517. {
  518. offset: 1,
  519. color: 'rgba(250, 140, 164, 0.3)'
  520. }
  521. ])
  522. },
  523. data: data2,
  524. }]
  525. };
  526. chart.setOption(option, true);
  527. }
  528. function updateCardiacSystem(data1, data2, that) {
  529. if (chartCardiacSystemLine) {
  530. setCardiacSystemOption(chartCardiacSystemLine, data1, data2);
  531. } else {
  532. that.selectComponent('#chartCardiacSystemLine-dom').init((canvas, width, height, dpr) => {
  533. const chart = echarts.init(canvas, null, {
  534. width: width,
  535. height: height,
  536. devicePixelRatio: dpr // new
  537. });
  538. canvas.setChart(chart);
  539. setCardiacSystemOption(chart, data1, data2);
  540. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  541. chartBodyMovementsLine = chart;
  542. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  543. return chart;
  544. });
  545. }
  546. }
  547. //平均呼吸率
  548. function initChartRespiratoryLine(canvas, width, height, dpr) {
  549. // 在这里初始化图表
  550. const chart = echarts.init(canvas, null, {
  551. width: width,
  552. height: height,
  553. devicePixelRatio: dpr // new
  554. });
  555. canvas.setChart(chart);
  556. setRespiratoryOption(chart);
  557. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  558. chartRespiratoryLine = chart;
  559. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  560. return chart;
  561. };
  562. function setRespiratoryOption(chart, data1 = [], data2 = [],) {
  563. var option = option = {
  564. tooltip: {
  565. show: true,
  566. trigger: 'axis',
  567. formatter: function (param) {
  568. return `${(param[0].value || 0) + '次'}`
  569. }
  570. },
  571. dataZoom: [
  572. { // 第一个 dataZoom 组件
  573. type: 'inside',
  574. },
  575. ],
  576. grid: {
  577. top: '20rpx',
  578. left: '20rpx',
  579. right: '20rpx',
  580. bottom: '10rpx',
  581. containLabel: true
  582. },
  583. xAxis: {
  584. type: 'category',
  585. axisLabel: {
  586. color: '#6C6970',// 设置 x 轴标签颜色为白色
  587. fontSize: 10
  588. },
  589. boundaryGap: false,
  590. splitLine: {
  591. show: false, // 是否显示刻度线
  592. },
  593. axisTick: {
  594. // 不显示Y轴刻度线
  595. show: false
  596. },
  597. data: data1,
  598. axisLine: {
  599. // 不显示X轴轴线
  600. show: false
  601. }
  602. },
  603. yAxis: {
  604. type: 'value',
  605. max: 24,
  606. min: 0,
  607. show: true,
  608. offset: 10,
  609. splitLine: {
  610. show: false
  611. },
  612. axisLabel: {
  613. hideOverlap: true,
  614. fontSize: 10,
  615. }
  616. },
  617. series: [{
  618. type: 'line',
  619. smooth: true,
  620. lineStyle: {
  621. width: 1,
  622. color: '#06A9AD'
  623. },
  624. emphasis: {
  625. disabled: true,
  626. scale: false,
  627. lineStyle: {
  628. width: 1,
  629. color: '#06A9AD'
  630. },
  631. },
  632. showSymbol: false,
  633. areaStyle: {
  634. opacity: 0.8,
  635. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  636. {
  637. offset: 0,
  638. color: 'rgba(186, 246, 231, 1)'
  639. },
  640. {
  641. offset: 1,
  642. color: 'rgba(255, 255, 255, 0)'
  643. }
  644. ])
  645. },
  646. data: data2,
  647. }]
  648. };
  649. chart.setOption(option, true);
  650. }
  651. function updateRespiratory(data1, data2, startSleepTime, endSleepTime, that) {
  652. if (chartRespiratoryLine) {
  653. setRespiratoryOption(chartRespiratoryLine, data1, data2);
  654. } else {
  655. that.selectComponent('#chartRespiratoryLine-dom').init((canvas, width, height, dpr) => {
  656. const chart = echarts.init(canvas, null, {
  657. width: width,
  658. height: height,
  659. devicePixelRatio: dpr // new
  660. });
  661. canvas.setChart(chart);
  662. setRespiratoryOption(chart, data1, data2);
  663. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  664. chartRespiratoryLine = chart;
  665. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  666. return chart;
  667. });
  668. }
  669. }
  670. //打鼾
  671. function initSnoringLine(canvas, width, height, dpr) {
  672. // 在这里初始化图表
  673. const chart = echarts.init(canvas, null, {
  674. width: width,
  675. height: height,
  676. devicePixelRatio: dpr // new
  677. });
  678. canvas.setChart(chart);
  679. setSnoringOption(chart);
  680. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  681. chartSnoringLine = chart;
  682. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  683. return chart;
  684. };
  685. function setSnoringOption(chart, data1 = [], data2 = [],) {
  686. var option = option = {
  687. tooltip: {
  688. show: true,
  689. trigger: 'axis',
  690. formatter: function (param) {
  691. return `${param[0] && param[0].value == 1 ? '打鼾' : '否'}`
  692. }
  693. },
  694. dataZoom: [
  695. { // 第一个 dataZoom 组件
  696. type: 'inside',
  697. },
  698. ],
  699. grid: {
  700. top: '40rpx',
  701. left: 0,
  702. right: '20rpx',
  703. bottom: 0,
  704. containLabel: true
  705. },
  706. xAxis: {
  707. type: 'category',
  708. axisLabel: {
  709. color: '#6C6970',// 设置 x 轴标签颜色为白色
  710. fontSize: 10
  711. },
  712. boundaryGap: false,
  713. splitLine: {
  714. show: false, // 是否显示刻度线
  715. },
  716. axisTick: {
  717. // 不显示Y轴刻度线
  718. show: false
  719. },
  720. data: data1,
  721. axisLine: {
  722. // 不显示X轴轴线
  723. show: false
  724. }
  725. },
  726. yAxis: {
  727. type: 'value',
  728. show: false,
  729. },
  730. series: [{
  731. type: 'line',
  732. smooth: true,
  733. lineStyle: {
  734. width: 1,
  735. color: '#EE8B52'
  736. },
  737. emphasis: {
  738. disabled: true,
  739. scale: false,
  740. lineStyle: {
  741. width: 1,
  742. color: '#EE8B52'
  743. },
  744. },
  745. showSymbol: false,
  746. areaStyle: {
  747. opacity: 0.8,
  748. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  749. {
  750. offset: 0,
  751. color: 'rgba(249, 211, 189, 1)'
  752. },
  753. {
  754. offset: 1,
  755. color: 'rgba(255, 255, 255, 0)'
  756. }
  757. ])
  758. },
  759. data: data2,
  760. }]
  761. };
  762. chart.setOption(option, true);
  763. }
  764. function updateSnoring(data1, data2, startSleepTime, endSleepTime, that) {
  765. if (chartSnoringLine) {
  766. setSnoringOption(chartSnoringLine, data1, data2);
  767. } else {
  768. that.selectComponent('#chartSnoringLine-dom').init((canvas, width, height, dpr) => {
  769. const chart = echarts.init(canvas, null, {
  770. width: width,
  771. height: height,
  772. devicePixelRatio: dpr // new
  773. });
  774. canvas.setChart(chart);
  775. setSnoringOption(chart, data1, data2);
  776. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  777. chartSnoringLine = chart;
  778. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  779. return chart;
  780. });
  781. }
  782. }
  783. //呼吸暂停
  784. function initApneaLine(canvas, width, height, dpr) {
  785. // 在这里初始化图表
  786. const chart = echarts.init(canvas, null, {
  787. width: width,
  788. height: height,
  789. devicePixelRatio: dpr // new
  790. });
  791. canvas.setChart(chart);
  792. setApneaOption(chart);
  793. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  794. chartApneaLine = chart;
  795. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  796. return chart;
  797. };
  798. function setApneaOption(chart, data1 = [], data2 = [],) {
  799. var option = option = {
  800. tooltip: {
  801. show: true,
  802. trigger: 'axis',
  803. formatter: function (param) {
  804. return `${param[0] && param[0].value == 1 ? '停止' : '否'}`
  805. }
  806. },
  807. dataZoom: [
  808. { // 第一个 dataZoom 组件
  809. type: 'inside',
  810. },
  811. ],
  812. grid: {
  813. top: '40rpx',
  814. left: 0,
  815. right: '20rpx',
  816. bottom: 0,
  817. containLabel: true
  818. },
  819. xAxis: {
  820. type: 'category',
  821. axisLabel: {
  822. color: '#6C6970',// 设置 x 轴标签颜色为白色
  823. fontSize: 10
  824. },
  825. boundaryGap: false,
  826. splitLine: {
  827. show: false, // 是否显示刻度线
  828. },
  829. axisTick: {
  830. // 不显示Y轴刻度线
  831. show: false
  832. },
  833. data: data1,
  834. axisLine: {
  835. // 不显示X轴轴线
  836. show: false
  837. }
  838. },
  839. yAxis: {
  840. type: 'value',
  841. show: false,
  842. },
  843. series: [{
  844. type: 'line',
  845. smooth: true,
  846. lineStyle: {
  847. width: 1,
  848. color: '#6086EF'
  849. },
  850. emphasis: {
  851. disabled: true,
  852. scale: false,
  853. lineStyle: {
  854. width: 1,
  855. color: '#6086EF'
  856. },
  857. },
  858. showSymbol: false,
  859. areaStyle: {
  860. opacity: 0.8,
  861. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  862. {
  863. offset: 0,
  864. color: 'rgba(96, 134, 239, 1)'
  865. },
  866. {
  867. offset: 1,
  868. color: 'rgba(255, 255, 255, 0)'
  869. }
  870. ])
  871. },
  872. data: data2,
  873. }]
  874. };
  875. chart.setOption(option, true);
  876. }
  877. function updateApnea(data1, data2, startSleepTime, endSleepTime, that) {
  878. if (chartApneaLine) {
  879. setApneaOption(chartApneaLine, data1, data2);
  880. } else {
  881. that.selectComponent('#chartApneaLine-dom').init((canvas, width, height, dpr) => {
  882. const chart = echarts.init(canvas, null, {
  883. width: width,
  884. height: height,
  885. devicePixelRatio: dpr // new
  886. });
  887. canvas.setChart(chart);
  888. setApneaOption(chart, data1, data2);
  889. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  890. chartApneaLine = chart;
  891. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  892. return chart;
  893. });
  894. }
  895. }
  896. //深浅睡眠
  897. function timestampToHHMM(timestamp) {
  898. let date = new Date(timestamp); // 注意:JavaScript中的Date是以毫秒为单位的
  899. let hours = date.getHours().toString().padStart(2, '0'); // 获取小时数,并补零
  900. let minutes = date.getMinutes().toString().padStart(2, '0'); // 获取分钟数,并补零
  901. return hours + ':' + minutes;
  902. }
  903. // 自定义图形
  904. function renderItem(params, api) {
  905. var categoryIndex = api.value(0);
  906. var startX = api.coord([api.value(1), categoryIndex])[0];
  907. var endX = api.coord([api.value(2), categoryIndex])[0];
  908. var centerY = api.coord([
  909. api.value(1) + (api.value(2) - api.value(1)) / 2,
  910. categoryIndex
  911. ])[1]; // 取中间点的y坐标
  912. var height = api.size([0, 1])[1] * 1;
  913. var width = endX - startX;
  914. // 创建一个矩形
  915. var rect = {
  916. x: startX,
  917. y: centerY - height / 2,
  918. r: 2,
  919. width: width,
  920. height: height
  921. };
  922. // 返回的图形对象
  923. return {
  924. type: 'rect',
  925. shape: rect,
  926. style: api.style()
  927. };
  928. }
  929. function initChartTimeWaterfall(canvas, width, height, dpr) {
  930. // 在这里初始化图表
  931. const chart = echarts.init(canvas, null, {
  932. width: width,
  933. height: height,
  934. devicePixelRatio: dpr // new
  935. });
  936. canvas.setChart(chart);
  937. setTimeWaterfallOption(chart, null, [{ "name": "清醒", "value": [2, 0, 0, 0], "itemStyle": { "normal": { "color": { "colorStops": [{ "offset": 0, "color": "#AAD09F" }, { "offset": 1, "color": "#AAD09F" }], "x": 0, "y": 0, "x2": 0, "y2": 1, "type": "linear", "global": false } } } }]);
  938. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  939. chartTimeWaterfall = chart;
  940. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  941. return chart;
  942. };
  943. function setTimeWaterfallOption(chart, startTime = new Date().getTime(), data = [], categories = ['深睡', '中睡', '浅睡', '清醒']) {
  944. var option =
  945. option = {
  946. tooltip: {
  947. show: true,
  948. formatter: function (params) {
  949. return params.marker + params.name + ': ' + params.value[3] + ' m';
  950. }
  951. },
  952. dataZoom: [
  953. {
  954. type: 'inside',
  955. filterMode: 'weakFilter'
  956. }
  957. ],
  958. grid: {
  959. top: 0,
  960. bottom: 0,
  961. height: 160,
  962. containLabel: false
  963. },
  964. xAxis: {
  965. type: 'value',
  966. scale: true,
  967. min: startTime,
  968. splitLine: {
  969. show: false // 是否显示刻度线
  970. },
  971. axisLabel: {
  972. color: '#6C6970',// 设置 x 轴标签颜色为白色
  973. fontSize: 10,
  974. formatter: function (val) {
  975. return timestampToHHMM(val || startTime);
  976. }
  977. }
  978. },
  979. yAxis: {
  980. show: false,
  981. data: categories
  982. },
  983. series: [
  984. {
  985. type: 'custom',
  986. renderItem: renderItem,
  987. itemStyle: {
  988. opacity: 1
  989. },
  990. encode: {
  991. x: [1, 2],
  992. y: 0
  993. },
  994. data: data
  995. }
  996. ]
  997. };
  998. chart.setOption(option, true);
  999. }
  1000. function updateTimeWaterfall(startTime = new Date().getTime(), data, that) {
  1001. console.log("updateTimeWaterfall========>", data);
  1002. if (chartTimeWaterfall) {
  1003. setTimeWaterfallOption(chartTimeWaterfall, startTime, data);
  1004. } else {
  1005. that.selectComponent('#chartTimeWaterfall-dom').init((canvas, width, height, dpr) => {
  1006. const chart = echarts.init(canvas, null, {
  1007. width: width,
  1008. height: height,
  1009. devicePixelRatio: dpr // new
  1010. });
  1011. canvas.setChart(chart);
  1012. setTimeWaterfallOption(chart, startTime, data);
  1013. // 将图表实例绑定到 this 上,可以在其他成员函数(如 dispose)中访问
  1014. chartTimeWaterfall = chart;
  1015. // 注意这里一定要返回 chart 实例,否则会影响事件处理等
  1016. return chart;
  1017. });
  1018. }
  1019. }
  1020. function addZero(str) {
  1021. if (String(str).length == 1) {
  1022. return "0" + String(str);
  1023. } else {
  1024. return String(str);
  1025. }
  1026. }
  1027. const aipushApi = "https://aipush.aidsleep.cn";
  1028. const token_push = "b74fd5754c5ef24cf600c39194abdaeb";
  1029. const token_today_push = "89835e65993fee4a6a6cbbe4c271da51e5521822934e13769e61cadabaed72c3";
  1030. Page({
  1031. /**
  1032. * 页面的初始数据
  1033. */
  1034. data: {
  1035. ecCircularProgressBar: {
  1036. // lazyLoad: true, // 懒加载
  1037. onInit: initChartHumidifier
  1038. },
  1039. ecOutOfBed: {
  1040. // lazyLoad: true, // 懒加载
  1041. onInit: initChartOutOfBed
  1042. },
  1043. ecBodyMovements: {
  1044. // lazyLoad: true, // 懒加载
  1045. onInit: initChartBodyMovementsLine
  1046. },
  1047. ecCardiacSystemLine: {
  1048. // lazyLoad: true, // 懒加载
  1049. onInit: initChartCardiacSystemLine
  1050. },
  1051. ecChartRespiratoryLine: {
  1052. // lazyLoad: true, // 懒加载
  1053. onInit: initChartRespiratoryLine
  1054. },
  1055. // ecSnoringLine: {
  1056. // // lazyLoad: true, // 懒加载
  1057. // onInit: initSnoringLine
  1058. // },
  1059. // ecApneaLine: {
  1060. // // lazyLoad: true, // 懒加载
  1061. // onInit: initApneaLine
  1062. // },
  1063. ecTimeWaterfall: {
  1064. // lazyLoad: true, // 懒加载
  1065. onInit: initChartTimeWaterfall
  1066. },
  1067. showAuthorizedDialog: false,
  1068. status: "",
  1069. isToDay: false,
  1070. year: addZero(new Date().getFullYear()),
  1071. month: addZero(new Date().getMonth()),
  1072. date: addZero(new Date().getDate()),
  1073. hours: addZero(new Date().getHours()),
  1074. rdt_arr: [],
  1075. rrh_arr: [],
  1076. rhx_arr: [],
  1077. rsnoring_arr: [],
  1078. routbed_arr: [],
  1079. rmove_arr: [],
  1080. rhxstop_arr: [],
  1081. rsleep_arr: [],
  1082. rdt_arrNew: [],//睡眠时间轴数据集合
  1083. rrh_arrNew: [],//睡眠心率数据集合
  1084. rhx_arrNew: [],//睡眠呼吸数据集合
  1085. rmove_arrNew: [],//体动状态数据集合,0-否,1-体动状态
  1086. rsleep_arrNew: [],//睡眠状态数据集合,0-清醒,10-浅睡,20-中睡,30-深睡
  1087. rsleep_arr_all_New: [],//睡眠状态数据集合,0-清醒,10-浅睡,20-中睡,30-深睡
  1088. durationData: [], //睡眠时长
  1089. sleep_duration: [], //睡眠和清醒对比
  1090. rdeep_durationFormatA: {},
  1091. rdeep_duration: 0,
  1092. rlight_duration: 0,
  1093. rin_duration: 0,
  1094. rawake_duration: 0,
  1095. rrs_duration: 0,//入睡时长
  1096. routbed_count_value: 0,//离床次数
  1097. rsleep_eff_value: '',//睡眠效率
  1098. rdeep_durationFormat: '',
  1099. rlight_durationFormat: '',
  1100. rin_durationFormat: '',
  1101. rawake_durationFormat: '',
  1102. ravg_hx_value: 0,
  1103. ravg_hx_desc: '',
  1104. ravg_rh_value: 0,
  1105. ravg_rh_desc: '',
  1106. rscore_value: 0,
  1107. rscore_desc: '',
  1108. sleep_efficiency: '',//睡眠效率
  1109. zdPoint: [],
  1110. rsn: '',
  1111. rdate: '',
  1112. total_duration: 0,
  1113. rtotal_duration: 0,
  1114. rinbed_duration: 0,
  1115. rgobed_time: 0,
  1116. routbed_time: 0,
  1117. rgobed_routbed: 0,
  1118. sleepHourSub: 0,
  1119. reportDate: '',
  1120. currentDate: '',
  1121. currentTime: '',
  1122. rmove_arrFrequency: 0,//体动次数
  1123. routbed_arrFrequency: 0,//离床次数
  1124. rsnoring_arrFrequency: 0,//打鼾次数
  1125. rhxstop_arrFrequency: 0,//呼吸暂停次数
  1126. sleep_durationCountA: 0,//睡眠时间
  1127. tvEntityIds: [],
  1128. ifOneMoreTV: false,//数据推送是否有多于一台电视
  1129. hotelcode: '',//酒店编码
  1130. roomcode: '',//房间编码
  1131. rdeep_duration_efficiency: '',//深睡比例
  1132. rlight_duration_efficiency: '',//浅睡比例
  1133. rin_duration_efficiency: '',//中睡比例
  1134. rawake_duration_efficiency: '',//清醒比例
  1135. isLoading: false,
  1136. reportId: '',
  1137. hotelname: '',
  1138. roomname: '',
  1139. bedname: '',
  1140. pushReportId: '',//推送用:reportId
  1141. sn: '',//今日报告切换用
  1142. sns: [],//床
  1143. dateData: [],//日期
  1144. dateTimeData: [],//时间段
  1145. selectTitleList: [],//床垫
  1146. showSelect: false,
  1147. showSelectSn: false,
  1148. showSelectDate: false,
  1149. showSelectDateTime: false,
  1150. isNoReportToday: false,
  1151. isShowTz: false,
  1152. tzTitle: '',
  1153. tzSubTitle: '',
  1154. },
  1155. toWarmReminder(e) {
  1156. const tabName = e.currentTarget.dataset.index || 1;
  1157. wx.navigateTo({
  1158. url: '/subpages/warmReminder/warmReminder?id=' + tabName
  1159. })
  1160. },
  1161. getRsleep_arr(list) {
  1162. if (list) {
  1163. // console.log("getRsleep_arr_list1==" + JSON.stringify(list));
  1164. for (let i = 0; i < list.length; i++) {
  1165. if (list[i] == '0') {
  1166. list[i] = '清醒';
  1167. } else if (list[i] == '10') {
  1168. list[i] = '浅睡';
  1169. } else if (list[i] == '20') {
  1170. list[i] = '中睡';
  1171. } else if (list[i] == '30') {
  1172. list[i] = '深睡';
  1173. } else {
  1174. list[i] = '其他';
  1175. }
  1176. }
  1177. }
  1178. // console.log("getRsleep_arr_list2==" + JSON.stringify(list));
  1179. },
  1180. getFrequency(list) {//获取
  1181. if (list) {
  1182. // console.log("getRsleep_arr_list1==" + JSON.stringify(list));
  1183. for (let i = 0; i < list.length; i++) {
  1184. if (list[i] == '0') {
  1185. list[i] = '清醒';
  1186. } else if (list[i] == '10') {
  1187. list[i] = '浅睡';
  1188. } else if (list[i] == '20') {
  1189. list[i] = '中睡';
  1190. } else if (list[i] == '30') {
  1191. list[i] = '深睡';
  1192. } else {
  1193. list[i] = '其他';
  1194. }
  1195. }
  1196. }
  1197. // console.log("getRsleep_arr_list2==" + JSON.stringify(list));
  1198. },
  1199. splitN(originalArray, n) {
  1200. if (!originalArray) return [];
  1201. // 计算每份的大小
  1202. // let chunkSize = Math.ceil(originalArray.length / n);
  1203. // 分割数组并获取每份的最后一个元素
  1204. // let lastElements = [];
  1205. // for (let i = 0; i < originalArray.length; i += chunkSize) {
  1206. // let chunk = originalArray.slice(i, i + chunkSize);
  1207. // lastElements.push(chunk[chunk.length - 1]);
  1208. // }
  1209. // 输出每份的最后一个元素
  1210. // console.log('lastElements=' + lastElements);
  1211. return originalArray;
  1212. },
  1213. //获取次数
  1214. getFrequency(list, o) {
  1215. if (!list) return 0;
  1216. let frequency = 0;
  1217. for (let i = 0; i < list.length; i++) {
  1218. if (list[i] == o) frequency++;
  1219. }
  1220. // console.log('frequency=' + frequency);
  1221. return frequency;
  1222. },
  1223. getTimeDiffInHours: function (startTimeStr, endTimeStr) {
  1224. // 假设两个时间都是同一天的,这里我们使用当前日期作为基准
  1225. if (!startTimeStr || !endTimeStr) return null;
  1226. const now = new Date();
  1227. const startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), ...startTimeStr.split(':').map(Number));
  1228. const endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), ...endTimeStr.split(':').map(Number));
  1229. // 处理跨天的情况
  1230. if (endDate < startDate) {
  1231. endDate.setDate(endDate.getDate() + 1); // 将结束时间设置为第二天的同一时间
  1232. }
  1233. // 计算时间差(毫秒)
  1234. const diffInMs = endDate - startDate;
  1235. // 转换为小时
  1236. const diffInHours = diffInMs / (1000 * 60 * 60);
  1237. return diffInHours;
  1238. },
  1239. // 时间格式化
  1240. convertTimeToHoursAndMinutes: function (timeWithText, flag = 0) {
  1241. if (!timeWithText) return;
  1242. // 移除'分钟'两个字
  1243. var minutesStr = timeWithText.replace('分钟', '');
  1244. var minutes = parseInt(minutesStr); // 将字符串转换为整数
  1245. if (isNaN(minutes)) {
  1246. // 如果转换失败,则可能是输入的不是有效的数字
  1247. console.error('Invalid minutes format');
  1248. return;
  1249. }
  1250. var hours = Math.floor(minutes / 60); // 整除60得到小时数
  1251. var remainingMinutes = minutes % 60; // 取余得到剩余的分钟数
  1252. // 如果小时数或分钟数小于10,前面补0
  1253. // var formattedHours = hours < 10 ? '0' + hours : hours;
  1254. var formattedHours = hours;
  1255. // var formattedMinutes = remainingMinutes < 10 ? '0' + remainingMinutes : remainingMinutes;
  1256. var formattedMinutes = remainingMinutes;
  1257. // 拼接小时和分钟,形成HH:mm格式
  1258. var formattedTime = '';
  1259. if (flag == 1) {
  1260. formattedTime = formattedHours + 'H ' + formattedMinutes + 'M';
  1261. } else if (flag == 2) {
  1262. formattedTime = formattedHours + '{units|小时}' + formattedMinutes + '{units|分钟}';
  1263. } else {
  1264. formattedTime = {
  1265. formattedHours,
  1266. formattedMinutes
  1267. };
  1268. }
  1269. // 更新数据
  1270. // this.setData({
  1271. // formattedTime: formattedTime
  1272. // });
  1273. return formattedTime;
  1274. },
  1275. // 组装深度睡眠数据
  1276. calculateTheDurationOfDeepSleep() {
  1277. var that = this;
  1278. // var totalDuration = this.data.total_duration;
  1279. // var timePeriod = this.data.rdt_arrNew;
  1280. var sleepData = this.data.rsleep_arr;//睡眠状态数据集合,0-清醒,10-浅睡,20-中睡,30-深睡
  1281. // console.log("睡眠总时长=>", totalDuration);
  1282. // console.log("睡眠时间片段=>", timePeriod);
  1283. // console.log("睡眠时间片段=>", timePeriod.length);
  1284. // console.log("睡眠数据=>", sleepData);
  1285. // console.log("睡眠数据=>", sleepData.length);
  1286. var awakeColor = [{ offset: 0, color: '#F7E3BA' }, { offset: 1, color: '#F7E3BA' }];;
  1287. var lightSleepColor = [{ offset: 0, color: '#AAD09F' }, { offset: 1, color: '#AAD09F' }];
  1288. var sleptInColor = [{ offset: 0, color: '#75BDE0' }, { offset: 1, color: '#75BDE0' }];
  1289. var deepSleepColor = [{ offset: 0, color: '#3D7299' }, { offset: 1, color: '#3D7299' }];
  1290. // var linearGradient = new echarts.graphic.LinearGradient(
  1291. // 0, 0, 0, 1, // 方向从左到右
  1292. // [
  1293. // { offset: 0, color: '#FDBE25' }, // 渐变开始的颜色
  1294. // { offset: 1, color: '#FD7778' } // 渐变结束的颜色
  1295. // ]
  1296. // );
  1297. // var item = {
  1298. // name: { name: '清醒', color: '#7b9ce1' },
  1299. // value: [index, baseTime, (baseTime += duration), duration],
  1300. // itemStyle: {
  1301. // normal: {
  1302. // color: linearGradient,
  1303. // }
  1304. // }
  1305. // };
  1306. // var sleepData = ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", "0", "0", "0", "0", "0", "0", "0", "0", "0", "10", "10", "10", "10", "10", "10", "10", "20", "20", "20", "20", "20", "20", "20", "20", "30", "30", "30", "30", "30", "30", "30", "30", "30"];//睡眠状态数据集合,0-清醒,10-浅睡,20-中睡,30-深睡
  1307. // 状态映射
  1308. const statusMap = {
  1309. "0": "清醒",
  1310. "10": "REM",
  1311. "20": "浅睡",
  1312. "30": "深睡"
  1313. };
  1314. // 状态映射
  1315. const statusColorMap = {
  1316. "20": awakeColor,
  1317. "0": lightSleepColor,
  1318. "10": sleptInColor,
  1319. "30": deepSleepColor
  1320. };
  1321. // 状态映射
  1322. const statusIndexMap = {
  1323. "20": 3,
  1324. "0": 2,
  1325. "10": 1,
  1326. "30": 0
  1327. };
  1328. // 初始化变量 reportDate
  1329. // let dateString = '2024/09/14 23:20:00';
  1330. let dateString = `${that.data.reportDate.replaceAll("-", "/")} ${that.data.rgobed_time + ":00"}`;
  1331. let date = new Date(dateString);
  1332. let startTime = date.getTime(); // 基准时间,这里设为午夜开始
  1333. // console.log("时间=》", timestampToHHMM(startTime));
  1334. let oldTime = startTime;
  1335. let currentTime = startTime;
  1336. let currentState = sleepData[0];
  1337. let timePeriods = [];
  1338. // 遍历睡眠数据数组
  1339. for (let i = 0; i < sleepData.length; i++) {
  1340. // 如果当前状态与前一个状态不同,则记录前一个时间段
  1341. if (i > 0 && sleepData[i] !== sleepData[i - 1]) {
  1342. // 计算前一个时间段的结束时间(注意这里不需要减去一分钟,因为 currentTime 还未递增)
  1343. let endTime = currentTime;
  1344. // 计算前一个时间段的持续时间(分钟)
  1345. let duration = Math.floor((endTime - startTime) / (1000 * 60));
  1346. // 记录时间段
  1347. if (duration > 0) {
  1348. var linearGradient = new echarts.graphic.LinearGradient(
  1349. 0, 0, 0, 1, // 方向从左到右
  1350. statusColorMap[sleepData[i - 1]]
  1351. );
  1352. timePeriods.push({
  1353. name: statusMap[sleepData[i - 1]],// 使用前一个状态
  1354. value: [statusIndexMap[sleepData[i - 1]], startTime, endTime, duration],
  1355. itemStyle: {
  1356. normal: {
  1357. color: linearGradient,
  1358. }
  1359. },
  1360. // startTime: new Date(startTime), // 转换为 Date 对象以便更易于阅读
  1361. // endTime: new Date(endTime),
  1362. // durationMinutes: duration
  1363. });
  1364. }
  1365. // 更新当前状态和开始时间
  1366. currentState = sleepData[i];
  1367. startTime = currentTime;
  1368. }
  1369. // 递增时间(每分钟)
  1370. currentTime += 1000 * 60;
  1371. // 处理最后一个时间段(如果数组不是以状态变化结束的话)
  1372. if (i === sleepData.length - 1) {
  1373. let endTime = currentTime;
  1374. let duration = Math.floor((endTime - startTime) / (1000 * 60));
  1375. if (duration > 0) {
  1376. var linearGradient = new echarts.graphic.LinearGradient(
  1377. 0, 0, 0, 1, // 方向从左到右
  1378. statusColorMap[currentState]
  1379. );
  1380. timePeriods.push({
  1381. name: statusMap[currentState],// 使用前一个状态
  1382. value: [statusIndexMap[currentState], startTime, endTime, duration],
  1383. itemStyle: {
  1384. normal: {
  1385. color: linearGradient,
  1386. }
  1387. },
  1388. // startTime: new Date(startTime), // 转换为 Date 对象以便更易于阅读
  1389. // endTime: new Date(endTime),
  1390. // durationMinutes: duration
  1391. });
  1392. }
  1393. }
  1394. }
  1395. wx.nextTick(() => {
  1396. setTimeout(() => {
  1397. updateTimeWaterfall(oldTime, timePeriods, that)
  1398. }, 1000);
  1399. });
  1400. // console.log("睡眠数据最终=>", dateString);
  1401. // console.log("睡眠数据最终=>", startTime);
  1402. // console.log("睡眠数据最终=>", JSON.stringify(timePeriods));
  1403. },
  1404. // 授权成功
  1405. authorizationSuccessful() {
  1406. // console.log("授权成功");
  1407. this.setData({ showAuthorizedDialog: false })
  1408. this.showData();
  1409. },
  1410. onReady() {
  1411. },
  1412. showData() {
  1413. let hotelcodeTemp = wx.getStorageSync("hotelEmpower");
  1414. let roomcodeTemp = wx.getStorageSync("roomEmpower");
  1415. // hotelcodeTemp = wx.getStorageSync('res').result.split('|')[0];
  1416. // roomcodeTemp = wx.getStorageSync('res').result.split('|')[1];
  1417. // 设置canvas的宽高
  1418. this.setData({
  1419. hotelcode: hotelcodeTemp,
  1420. roomcode: roomcodeTemp,
  1421. });
  1422. if (this.data.isToDay) {
  1423. this.getToDayReportData();
  1424. } else {
  1425. this.getReportData();
  1426. }
  1427. this.getTzData();
  1428. },
  1429. /**
  1430. * 生命周期函数--监听页面加载
  1431. */
  1432. onShow: function () {
  1433. if (!wx.getStorageSync('hasAuth')) {
  1434. this.setData({ showAuthorizedDialog: true })
  1435. } else {
  1436. this.showData();
  1437. }
  1438. },
  1439. onLoad(options) {
  1440. var that = this;
  1441. if (options.rpids) {
  1442. that.setData({
  1443. reportId: options.rpids,
  1444. isToDay: false
  1445. })
  1446. wx.setNavigationBarTitle({
  1447. title: "历史睡眠报告"
  1448. })
  1449. } else {
  1450. wx.setNavigationBarTitle({
  1451. title: "最新睡眠报告" || "今日睡眠报告"
  1452. })
  1453. that.setData({
  1454. isToDay: true
  1455. })
  1456. }
  1457. },
  1458. onTitleChange(event) {
  1459. const { picker, value, index } = event.detail;
  1460. this.setData({
  1461. reportId: value.rpid,
  1462. hotelname: value.hotelname,
  1463. roomname: value.roomname,
  1464. bedname: value.bedname,
  1465. });
  1466. this.closePicker();
  1467. this.getReportData();//更新报告
  1468. },
  1469. onSnChange(event) {
  1470. const { picker, value, index } = event.detail;
  1471. this.closePicker();
  1472. this.getDateData(value.sn);//自动获取日期
  1473. //
  1474. // this.getDateTimeData(this.data.reportDate);//如果不能修改日期 自动获取时间段
  1475. },
  1476. onDateChange(event) {
  1477. const { picker, value, index } = event.detail;
  1478. this.closePicker();
  1479. this.getDateTimeData(value.rdate);//自动获取时间段
  1480. },
  1481. onDateTimeChange(event) {
  1482. const { picker, value, index } = event.detail;
  1483. this.setData({
  1484. reportId: value.rpids
  1485. });
  1486. this.closePicker();
  1487. this.getReportData();//更新报告
  1488. },
  1489. showPicker(e) {
  1490. // return //暂时不开放
  1491. // 不是今天不让选择
  1492. if (!this.data.isToDay) {
  1493. return
  1494. }
  1495. var type = e.currentTarget.dataset.type;
  1496. if (type == 'sn' && this.data.selectTitleList.length) {
  1497. this.setData({
  1498. showSelect: true,
  1499. });
  1500. } else if (type == 'sn' && this.data.sns.length) {
  1501. // this.setData({
  1502. // showSelectSn: true,
  1503. // });
  1504. } else if (type == 'date' && this.data.dateData.length) {
  1505. return
  1506. // this.setData({
  1507. // showSelectDate: true,
  1508. // });
  1509. } else if (type == 'dateTime' && this.data.dateTimeData.length) {
  1510. return
  1511. // this.setData({
  1512. // showSelectDateTime: true,
  1513. // });
  1514. }
  1515. },
  1516. closePicker() {
  1517. this.setData({
  1518. showSelect: false,
  1519. showSelectSn: false,
  1520. showSelectDate: false,
  1521. showSelectDateTime: false
  1522. });
  1523. },
  1524. getAllUnionidList() {
  1525. var that = this;
  1526. wx.request({
  1527. url: `${aipushApi}` + '/allunionidlist',
  1528. data: {
  1529. "udi": wx.getStorageSync("unionid"),
  1530. "token": token_today_push
  1531. },
  1532. method: 'POST',
  1533. success(res) {
  1534. try {
  1535. const tempList = res.data.data || []
  1536. that.setData({
  1537. selectTitleList: tempList,
  1538. });
  1539. } catch (error) {
  1540. console.error(error);
  1541. }
  1542. },
  1543. })
  1544. },
  1545. getSnData() {
  1546. var that = this;
  1547. wx.request({
  1548. url: `${aipushApi}` + '/getsn',
  1549. data: {
  1550. // "hotelcode": "lab",
  1551. // "roomcode": "labs",
  1552. "hotelcode": that.data.hotelcode ? that.data.hotelcode : "club",
  1553. "roomcode": that.data.roomcode ? that.data.roomcode : "nuange",
  1554. "token": token_push
  1555. },
  1556. method: 'POST',
  1557. success(res) {
  1558. try {
  1559. if (res && res.data && res.data[0]) {
  1560. that.setData({
  1561. hotelname: res.data[0].hn,
  1562. roomname: res.data[0].rn,
  1563. sn: res.data[0].sn,
  1564. sns: res.data //床的数组
  1565. });
  1566. that.getDateData(res.data[0].sn, false);//根据 sn 获取可以用的时间段
  1567. // console.log("res.data=sn=" + JSON.stringify(res.data));
  1568. }
  1569. } catch (error) {
  1570. console.error(error);
  1571. }
  1572. },
  1573. })
  1574. },
  1575. toReport() {
  1576. wx.navigateTo({
  1577. url: '/subpages/constitutionDiagnosis/constitutionDiagnosis'
  1578. })
  1579. },
  1580. getTzData() {
  1581. var that = this;
  1582. var userId = wx.getStorageSync("unionid");
  1583. wx.request({
  1584. url: `https://fare.somnisix.top/system/constitutionDiagnosis/user/${userId}`,
  1585. data: {
  1586. "token": "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX2tleSI6Ijk5YzI3MjI2LTdkOWQtNDhiOC1hYjlhLWM4YjVjYWZiZGNkNyIsInVzZXJuYW1lIjoiYWRtaW4ifQ.zITQOINFkHs19_1RAgHS4I9YMaVxVq0Dsn3t6r_K7rv3rXvJy0sMtodejIMi_PNa_m4uQYxnU-6k3wC2LZht_Q"
  1587. },
  1588. header: {
  1589. 'Authorization': 'Bearer ' + "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX2tleSI6Ijk5YzI3MjI2LTdkOWQtNDhiOC1hYjlhLWM4YjVjYWZiZGNkNyIsInVzZXJuYW1lIjoiYWRtaW4ifQ.zITQOINFkHs19_1RAgHS4I9YMaVxVq0Dsn3t6r_K7rv3rXvJy0sMtodejIMi_PNa_m4uQYxnU-6k3wC2LZht_Q" // 在头部设置Bearer Token
  1590. },
  1591. method: 'GET',
  1592. success(res) {
  1593. try {
  1594. if (res && res.data && res.data.data) {
  1595. if (res.data.data.value2) {
  1596. var data = JSON.parse(res.data.data.value2);
  1597. var ratingResultsMap = {
  1598. A: {
  1599. index: 0,
  1600. title: "气虚型",
  1601. tips: "(体力和气力都低下,需要规律性的生活方式)",
  1602. subTitle: "累啊』『真倒霉』成了口头语",
  1603. desc: "一般来说气虚型的人,就是被称作生命力的“气”整体不足。因为体力和气力的整体下降,无论做什么都会感到“真倒霉”“真麻烦”,饮食和运动也是马马虎虎地应付。结果,陷入生活越不规律,“气”就越衰弱的恶性循环。特点就是免疫力降低,易患感冒,而且很难一次性治愈。\n\n为了改善气虚,最重要的就是要有规律性的生活方式。晚上早睡,早上早起。日常食物也要以应季的食材为主,促进胃肠的蠕动,尽量多食用可以提升体温的豆类、薯类等食材。\n\n适度的运动是必要的,但因体力下降,所以万不可强求大的运动量,可以从散步呀、瑜伽呀等轻负荷的运动练起。\n\n特征:驼背。显老像;稍一运动就出汗;手脚发冷;易疲劳,总有困意与疲倦感;下半身易发胖。"
  1604. }, B: {
  1605. index: 1,
  1606. title: "气滞型",
  1607. tips: "(常常紧张、焦虑~要有意识地放松自己)",
  1608. subTitle: "感情起伏剧烈",
  1609. desc: "“气”本来是在体内正常循环的,但是因紧张和压力等使气滞留,就造成了气滞型。“气’一旦滞留,就表现为腹胀、肿胀、疼痛等症状。而且,感情起伏剧烈也是其特征。一旦情绪低落,很快就会焦虑起来,给人以“易发怒”歇斯底里”的感觉。更年期出现气滞的人也不在少数。\n\n养生法无疑是减轻压力的最好办法,但暴饮暴食则会适得其反。值得注意的是体重的增加会影响气的循环。香草和香味蔬菜有促进气循环和防止暴饮暴食的作用。除此之外,每天的日常安排中应留出自我放松的时间,也可以进行深呼吸,这些都有助于改善气滞。\n\n气滞型:入睡困难;眼睛充血;肚子容易生赘肉;焦虑,易怒,皮肤油腻,发红;易打嗝,矢气。"
  1610. }, C: {
  1611. index: 2,
  1612. title: "血虚型",
  1613. tips: "(饮食生活无规律~可能也有气虚或气滞的原因)",
  1614. subTitle: "头发散乱,皮肤无光泽",
  1615. desc: "你是否为了减肥极端地限制饮食,或者光在外边吃快餐?如果一直这样,就会使营养失去平衡,引起“血”的不足,陷入血虚状态。\n\n为此,日常饮食重要的是要注意营养的平衡,特别要多食用有造血作用的羊栖菜、动物肝脏、梅干等。“血”增加了,头发散乱、皮肤无光泽这些血虚型的症状自然就消失了。夜间是人体的造血时间,因此不要熬夜。还要控制电脑和手机的使用,也要控制看电视的时间。中医学以为用眼是消耗“血”的。\n\n特征:头发脆弱,脱发;常常眩晕,站起时头晕;脸色不好,皮肤干燥;指甲偏薄,易裂;耳鸣;冷静,认真型。"
  1616. }, D: {
  1617. index: 3,
  1618. title: "淤血型",
  1619. tips: "(血流不畅~更要注意减压,慎食生冷食品)",
  1620. subTitle: "常常感到肩凝、头痛",
  1621. desc: "血流不顺畅,易在体内形成血块(瘀血)。其原因有喜食生冷食品、压力大、过劳、睡眠不足等等。也有因气虚和血虚造成的瘀血。\n\n对这个型的人,首先是必须使其血行畅通,提高代谢。要多食用牛蒡、蒟蒻(魔芋)、黑醋等有化解瘀血作用的食品,也要多食用生姜和韭菜、葱等有香味的蔬菜。饮料也要尽量选择热你,偏冷会影响血循环。\n\n要养成运动的习惯。运动可以促进血行,缓解瘀血引起的肩凝和腰痛。当然,按摩下半身也可以有效地改善脸部的气色。\n\n特征:容易被晒伤;容易长色斑,雀斑;容易出现黑眼圈;常常为肩凝和腰痛烦恼;经血中有动物肝脏样血块;基本上自制力较强,但偶尔也会感情爆发。"
  1622. }, E: {
  1623. index: 4,
  1624. title: "水虚型",
  1625. tips: "(身体如同干枯一般~避免食用香辛食物和剧烈运动)",
  1626. subTitle: "常为头晕眼花、身体发热而烦恼",
  1627. desc: "体内水分不足称为水虚。皮肤、毛发、大便干燥的入水虚的可能性较大。而且,这类人因为给身体起到降温作用的水分不足,所以,常常感到头晕眼花或者身体发热。\n\n作为养生法,就是要通过食物的摄取,有效地补充水分。其中,苹果和香蕉、白菜可以有效地滋润身体,要有意识地多多食用。而且,因为睡眠中容易出汗,水分会在不知不觉中流失,因此,要在枕边预备下温开水,醒来后先饮水。\n\n另一方面,要尽量避免食用香辛食材。因为香辛料有温暖身体的作用,可能会加重头晕眼花和身体发热的症状。水虚的人还要避免剧烈的运动。因为他们的关节水分不足,剧烈运动会引发疼痛。\n\n特征:睡眠浅,盗汗;关节运动不灵活;不明原因的消沉,情绪低落;毛发和皮肤脆弱,口腔和咽喉干燥;便秘,尿量少。"
  1628. }, F: {
  1629. index: 5,
  1630. title: "痰湿型",
  1631. tips: "(体内多余的水分~常常引发各种“不调”,要慎食味重食品)",
  1632. subTitle: "体型胖墩墩的",
  1633. desc: "现代职场女性多为痰湿型。所谓痰湿就是生活不规律、压力大等原因造成身体内形成多余的水分块(痰湿)的状态。因为我们的身体70%是由水构成的,所以痰湿的影响不容忽视,会造成我们的身心状态出现各种各样的“不调”。\n\n首先,有氧运动能够增加肌肉的弹力,促进血行和代谢。肌肉弹力的提高、血行和代谢的改善,就可以通过汗和取把多余的水分排出体外。\n\n第二要注意减少冷饮和味重食品的摄入量,因为它们会造成水分的滞留。\n\n第三要多食用黄瓜和西瓜、梨等有较好利尿作用的食物。也要多食红豆、薏米。\n\n特征:整个身体容易浮肿;容易发胖;早晨起床后脸上有枕头的痕迹;皮肤发白。胖墩墩的;爱生湿乎乎的疙瘩;性格自我,爱慕虚荣。"
  1634. }
  1635. };
  1636. var key = that.findKeyWithMaxValue(data);
  1637. // console.log("睡眠数据最终555=>", ratingResultsMap[key]);
  1638. // console.log("睡眠数据最终555=>", key);
  1639. that.setData({
  1640. tzTitle: ratingResultsMap[key]?.title ?? "健康型",
  1641. tzSubTitle: ratingResultsMap[key]?.subTitle ?? "太棒了,您的身体非常健康,请继续保持",
  1642. isShowTz: true
  1643. })
  1644. }
  1645. }
  1646. } catch (error) {
  1647. console.error(error);
  1648. }
  1649. },
  1650. })
  1651. },
  1652. /**
  1653. * A、B、C、D、E、F 最后积累的数量对比,按数量多少来判断,6个分别对应:气虚型、气滞型、血虚型、淤血型、水虚型、痰湿型
  1654. * 找出对象中值最大的键
  1655. * @param {Object} obj - 包含键值对的对象
  1656. * @returns {string|null} - 值最大的键,如果没有找到则返回null
  1657. */
  1658. findKeyWithMaxValue(obj) {
  1659. if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
  1660. throw new Error('Input must be a plain object');
  1661. }
  1662. let maxKey = null;
  1663. let maxValue = 0;
  1664. for (let key in obj) {
  1665. if (obj.hasOwnProperty(key)) {
  1666. if (obj[key] > maxValue) {
  1667. maxValue = obj[key];
  1668. maxKey = key;
  1669. }
  1670. }
  1671. }
  1672. return maxKey;
  1673. },
  1674. // 可选择的日期
  1675. getDateData: function (sn, isRefresh = true) {
  1676. var that = this;
  1677. var sourceFourthTemp = [];
  1678. wx.request({
  1679. url: `${aipushApi}/getdatefromsn`, //
  1680. method: 'POST',
  1681. // header: {
  1682. // 'content-type': 'application/json', // 默认值
  1683. // 'Authorization': 'Bearer ' + token // 在头部设置认证信息,例如使用Bearer Token
  1684. // },
  1685. data: {
  1686. "sn": sn, "token": token_push
  1687. },
  1688. success(res) {
  1689. if (!res || !res.data || !res.data.results || !res.data.results.length) {
  1690. that.setData({
  1691. isNoReportToday: true
  1692. })
  1693. return;
  1694. }
  1695. that.setData({
  1696. dateData: res.data.results //床的数组
  1697. });
  1698. // {"results": [{ "rdate": "2024-10-08" }]}
  1699. that.getDateTimeData(res.data.results[0].rdate, isRefresh);
  1700. // var resDataSn = res.data.results
  1701. },
  1702. fail: function (error) {
  1703. console.error('error', error);
  1704. that.setData({
  1705. isNoReportToday: true
  1706. })
  1707. },
  1708. complete: function (e) {
  1709. }
  1710. });
  1711. },
  1712. // 可选择的时间 可自动选择 更改 reportId
  1713. getDateTimeData: function (rdate, isRefresh = true) {
  1714. var that = this;
  1715. wx.request({
  1716. url: `${aipushApi}/getimefromsn`, //
  1717. method: 'POST',
  1718. // header: {
  1719. // 'content-type': 'application/json', // 默认值
  1720. // 'Authorization': 'Bearer ' + token // 在头部设置认证信息,例如使用Bearer Token
  1721. // },
  1722. data: {
  1723. "sn": that.data.sn, "date": rdate, "token": token_push
  1724. },
  1725. success(res) {
  1726. // { "results": [{ "rpids": "459857", "durations": "14:17-17:55" }] }
  1727. if (!res || !res.data || !res.data.results || !res.data.results.length) {
  1728. that.setData({
  1729. isNoReportToday: true
  1730. })
  1731. return;
  1732. }
  1733. that.setData({
  1734. dateTimeData: res.data.results, //床的数组
  1735. });
  1736. if (isRefresh) {
  1737. that.setData({
  1738. isNoReportToday: false,
  1739. reportId: res.data.results[0].rpids
  1740. });
  1741. that.getReportData();
  1742. }
  1743. },
  1744. fail: function (error) {
  1745. console.error('error', error);
  1746. that.setData({
  1747. isNoReportToday: true
  1748. })
  1749. }
  1750. });
  1751. },
  1752. // 新版
  1753. getReportData() {
  1754. const that = this;
  1755. wx.request({
  1756. url: `${aipushApi}` + '/getsingle',
  1757. data: {
  1758. "token": token_push,
  1759. "rpids": this.data.reportId,
  1760. "udi": wx.getStorageSync("unionid")
  1761. },
  1762. method: 'POST',
  1763. success(ress) {
  1764. try {
  1765. if (ress && ress.data) {
  1766. console.log('ress.data-getsingle=' + JSON.stringify(ress.data.results));
  1767. if (!ress.data.results || ress.data.results == '') {
  1768. // wx.showModal({
  1769. // title: '提示',
  1770. // content: '无数据',
  1771. // showCancel: false
  1772. // });
  1773. that.setData({
  1774. isNoReportToday: true
  1775. })
  1776. return;
  1777. }
  1778. wx.nextTick(() => {
  1779. setTimeout(() => {
  1780. //初始化数据
  1781. that.initReportData(ress.data.results);
  1782. that.initChartCircle(ress.data.results);
  1783. that.initOutOfBed(ress.data.results);
  1784. that.initBodyMovements(ress.data.results);
  1785. that.initCardiacSystem(ress.data.results);
  1786. that.initChartRespiratory(ress.data.results);
  1787. // that.initChartSnoring(ress.data.results);
  1788. // that.initChartApnea(ress.data.results);
  1789. that.initTimeWaterfall(ress.data.results);
  1790. }, 1000);
  1791. });
  1792. } else {
  1793. // wx.showModal({
  1794. // title: '提示',
  1795. // content: '无数据',
  1796. // showCancel: false
  1797. // });
  1798. that.setData({
  1799. isNoReportToday: true
  1800. })
  1801. }
  1802. } catch (error) {
  1803. console.error(error);
  1804. }
  1805. },
  1806. fail: function (error) {
  1807. // wx.showToast({
  1808. // title: "无数据",
  1809. // icon: "error",
  1810. // mask: true,
  1811. // });
  1812. that.setData({
  1813. isNoReportToday: true
  1814. })
  1815. }
  1816. });
  1817. },
  1818. // 新版
  1819. getToDayReportData() {
  1820. const that = this;
  1821. wx.request({
  1822. url: `${aipushApi}` + '/getunionsingle',
  1823. data: {
  1824. "token": token_today_push,
  1825. "udi": wx.getStorageSync("unionid")
  1826. },
  1827. method: 'POST',
  1828. success(ress) {
  1829. try {
  1830. if (ress && ress.data) {
  1831. // console.log('ress.data-getunionsingle=' + JSON.stringify(ress.data));
  1832. if (ress.data == {} || ress.data.data == {} || ress.data.data == [] || !ress.data.data) {
  1833. // wx.showModal({
  1834. // title: '提示',
  1835. // content: '无数据',
  1836. // showCancel: false
  1837. // });
  1838. that.setData({
  1839. isNoReportToday: true
  1840. })
  1841. return;
  1842. }
  1843. //初始化数据
  1844. wx.nextTick(() => {
  1845. setTimeout(() => {
  1846. that.initReportData(ress.data.data);
  1847. that.initChartCircle(ress.data.data);
  1848. that.initOutOfBed(ress.data.data);
  1849. that.initBodyMovements(ress.data.data);
  1850. that.initCardiacSystem(ress.data.data);
  1851. that.initChartRespiratory(ress.data.data);
  1852. // that.initChartSnoring(ress.data.data);
  1853. // that.initChartApnea(ress.data.data);
  1854. that.initTimeWaterfall(ress.data.data);
  1855. }, 1000);
  1856. });
  1857. that.getSnData();//需要筛选的 要获取sn
  1858. that.getAllUnionidList();
  1859. } else {
  1860. // wx.showModal({
  1861. // title: '提示',
  1862. // content: '无数据',
  1863. // showCancel: false
  1864. // });
  1865. that.setData({
  1866. isNoReportToday: true
  1867. })
  1868. }
  1869. } catch (error) {
  1870. console.error(error);
  1871. }
  1872. },
  1873. fail: function (error) {
  1874. // wx.showToast({
  1875. // title: "无数据",
  1876. // icon: "error",
  1877. // mask: true,
  1878. // });
  1879. that.setData({
  1880. isNoReportToday: true
  1881. })
  1882. }
  1883. });
  1884. },
  1885. // 初始化的数据
  1886. initReportData(ress) {
  1887. const that = this;
  1888. let durationDataTemp = [];
  1889. let obj = {};
  1890. obj.name = '深睡';
  1891. obj.value = ress.rdeep_duration;
  1892. durationDataTemp.push(obj);
  1893. obj = {};
  1894. obj.name = '浅睡';
  1895. obj.value = ress.rin_duration;
  1896. durationDataTemp.push(obj);
  1897. obj = {};
  1898. obj.name = '中睡';//REM
  1899. obj.value = ress.rlight_duration;
  1900. durationDataTemp.push(obj);
  1901. obj = {};
  1902. obj.name = '清醒';
  1903. obj.value = ress.rawake_duration;
  1904. durationDataTemp.push(obj);
  1905. let sleep_durationCount = 0;
  1906. if (ress.rdeep_duration) {
  1907. sleep_durationCount += parseFloat(ress.rdeep_duration)
  1908. }
  1909. if (ress.rlight_duration) {
  1910. sleep_durationCount += parseFloat(ress.rlight_duration)
  1911. }
  1912. if (ress.rin_duration) {
  1913. sleep_durationCount += parseFloat(ress.rin_duration)
  1914. }
  1915. let sleep_efficiency_temp = ress.rtotal_duration ? (Math.ceil((sleep_durationCount / ress.rtotal_duration) * 100) + '%') : '%'
  1916. let rdeep_duration_efficiency_temp = ress.rtotal_duration ? (Math.ceil(((ress.rdeep_duration ? parseFloat(ress.rdeep_duration) : 0) / ress.rtotal_duration) * 100) + '%') : '%'
  1917. let rlight_duration_efficiency_temp = ress.rtotal_duration ? (Math.ceil(((ress.rlight_duration ? parseFloat(ress.rlight_duration) : 0) / ress.rtotal_duration) * 100) + '%') : '%'
  1918. let rin_duration_efficiency_temp = ress.rtotal_duration ? (Math.ceil(((ress.rin_duration ? parseFloat(ress.rin_duration) : 0) / ress.rtotal_duration) * 100) + '%') : '%'
  1919. let rawake_duration_efficiency_temp = ress.rtotal_duration ? (Math.ceil(((ress.rawake_duration ? parseFloat(ress.rawake_duration) : 0) / ress.rtotal_duration) * 100) + '%') : '%'
  1920. // let rdeep_duration_efficiency_temp = ress.darktrate;
  1921. // let rlight_duration_efficiency_temp = ress.lightrate;
  1922. // let rin_duration_efficiency_temp = ress.midrate;
  1923. // let rawake_duration_efficiency_temp = ress.awakenrate;
  1924. let sleep_durationTemp = [];
  1925. let obj1 = {};
  1926. obj1.name = '睡眠时间';
  1927. obj1.value = Math.ceil(sleep_durationCount / 60);
  1928. sleep_durationTemp.push(obj1);
  1929. obj1 = {};
  1930. obj1.name = '清醒时间';
  1931. obj1.value = Math.ceil(parseFloat(ress.rawake_duration) / 60);
  1932. sleep_durationTemp.push(obj1);
  1933. let zdPointTemp = [];
  1934. let rdt_arrTemp = [];
  1935. let rrh_arrTemp = [];
  1936. let rhx_arrTemp = [];
  1937. let rmove_arrTemp = [];
  1938. let rsleep_arrTemp = [];
  1939. let rsleep_arr_all_Temp = [];
  1940. if (ress.rrh_arr) {
  1941. rdt_arrTemp = that.splitN(ress.rdt_arr.split(","), 100);
  1942. }
  1943. if (ress.rrh_arr) {
  1944. rrh_arrTemp = that.splitN(ress.rrh_arr.split(","), 100);
  1945. }
  1946. if (ress.rhx_arr) {
  1947. rhx_arrTemp = that.splitN(ress.rhx_arr.split(","), 100);
  1948. }
  1949. if (ress.rmove_arr) {
  1950. rmove_arrTemp = that.splitN(ress.rmove_arr.split(","), 100);
  1951. }
  1952. if (ress.rsleep_arr) {
  1953. rsleep_arrTemp = that.splitN(ress.rsleep_arr.split(","), 100);
  1954. }
  1955. if (ress.rsleep_arr) {
  1956. rsleep_arr_all_Temp = ress.rsleep_arr.split(",");
  1957. }
  1958. that.setData({
  1959. rdt_arr: ress.rdt_arr ? ress.rdt_arr.split(',') : [],
  1960. rrh_arr: ress.rrh_arr ? ress.rrh_arr.split(',') : [],
  1961. rhx_arr: ress.rhx_arr ? ress.rhx_arr.split(',') : [],
  1962. rsnoring_arr: ress.rsnoring_arr ? ress.rsnoring_arr.split(',') : [],
  1963. routbed_arr: ress.routbed_arr ? ress.routbed_arr.split(',') : [],
  1964. rmove_arr: ress.rmove_arr ? ress.rmove_arr.split(',') : [],
  1965. rhxstop_arr: ress.rhxstop_arr ? ress.rhxstop_arr.split(',') : [],
  1966. rsleep_arr: ress.rsleep_arr ? ress.rsleep_arr.split(',') : [],//睡眠状态数据集合,0-清醒,10-浅睡,20-中睡,30-深睡
  1967. rsnoring_arrFrequency: that.getFrequency(ress.rsnoring_arr ? ress.rsnoring_arr.split(',') : [], 1),
  1968. routbed_arrFrequency: that.getFrequency(ress.routbed_arr ? ress.routbed_arr.split(',') : [], 0),
  1969. rmove_arrFrequency: that.getFrequency(ress.rmove_arr ? ress.rmove_arr.split(',') : [], 1),
  1970. rhxstop_arrFrequency: that.getFrequency(ress.rhxstop_arr ? ress.rhxstop_arr.split(',') : [], 1),
  1971. rdeep_durationFormatA: that.convertTimeToHoursAndMinutes(ress.rdeep_duration),
  1972. rlight_duration: ress.rlight_duration,
  1973. rin_duration: ress.rin_duration,
  1974. rawake_duration: ress.rawake_duration,
  1975. ravg_hx_value: ress.ravg_hx_value===null?"--":ress.ravg_hx_value,
  1976. ravg_hx_desc: ress.ravg_hx_desc===null?"--":ress.ravg_hx_desc,
  1977. ravg_rh_value: ress.ravg_rh_value===null?"--":ress.ravg_rh_value,
  1978. ravg_rh_desc: ress.ravg_rh_desc===null?"--":ress.ravg_rh_desc,
  1979. rscore_value: ress.rscore_value===null?"--":ress.rscore_value,
  1980. rscore_desc: ress.rscore_desc===null?"--":ress.rscore_desc,
  1981. rsn: ress.rsn,
  1982. rdate: ress.rdate,
  1983. total_duration: ress.rtotal_duration,
  1984. rtotal_duration: that.convertTimeToHoursAndMinutes(ress.rtotal_duration),//睡眠总时长,单位小时分钟
  1985. rinbed_duration: that.convertTimeToHoursAndMinutes(ress.rinbed_duration),//在床时长,单位小时分钟
  1986. rgobed_time: ress.rgobed_time,//上床时间
  1987. routbed_time: ress.routbed_time,//离床时间
  1988. rgobed_routbed: ress.rgobed_time + '~' + ress.routbed_time,
  1989. sleepHourSub: that.getTimeDiffInHours(ress.rgobed_time, ress.routbed_time),
  1990. zdPointT: zdPointTemp,
  1991. rdt_arrNew: rdt_arrTemp,
  1992. rrh_arrNew: rrh_arrTemp,
  1993. rhx_arrNew: rhx_arrTemp,
  1994. rmove_arrNew: rmove_arrTemp,
  1995. rsleep_arrNew: rsleep_arrTemp,
  1996. rsleep_arr_all_New: rsleep_arr_all_Temp,
  1997. durationData: durationDataTemp,
  1998. sleep_duration: sleep_durationTemp,
  1999. sleep_efficiency: sleep_efficiency_temp,
  2000. sleep_durationCountA: that.convertTimeToHoursAndMinutes(sleep_durationCount ? sleep_durationCount.toString() : '0'),
  2001. tvEntityIds: wx.getStorageSync('tvEntityIds'),
  2002. ifOneMoreTV: (wx.getStorageSync('tvEntityIds') && wx.getStorageSync('tvEntityIds').length > 1),
  2003. rdeep_duration_efficiency: rdeep_duration_efficiency_temp,
  2004. rlight_duration_efficiency: rlight_duration_efficiency_temp,
  2005. rin_duration_efficiency: rin_duration_efficiency_temp,
  2006. rawake_duration_efficiency: rawake_duration_efficiency_temp,
  2007. pushReportId: ress.rdid,
  2008. isNoReportToday: false,
  2009. rrs_duration: that.convertTimeToHoursAndMinutes(ress.rrs_duration ? ress.rrs_duration.toString() : '0')===null?"--":that.convertTimeToHoursAndMinutes(ress.rrs_duration ? ress.rrs_duration.toString() : '0'),
  2010. routbed_count_value: ress.routbed_count_value===null?"--":ress.routbed_count_value ,
  2011. rsleep_eff_value: ress.rsleep_eff_value===null?"--":ress.rsleep_eff_value ,
  2012. hotelname: ress.hotelname,
  2013. roomname: ress.roomname,
  2014. bedname: ress.bedname,
  2015. });
  2016. },
  2017. // 香睡指数
  2018. initChartCircle(ress) {
  2019. var that = this;
  2020. try {
  2021. let rscore_descTemp = [];
  2022. if (ress.rscore_desc) {
  2023. rscore_descTemp = ress.rscore_desc;
  2024. }
  2025. let rscore_valueTemp = [];
  2026. if (ress.rscore_value) {
  2027. rscore_valueTemp = ress.rscore_value;
  2028. }
  2029. that.setData({
  2030. rscore_desc: rscore_descTemp,
  2031. rscore_value: rscore_valueTemp,
  2032. });
  2033. updateChartCircularProgressBarOption(rscore_descTemp, rscore_valueTemp, that);
  2034. } catch (error) {
  2035. console.error(error);
  2036. }
  2037. },
  2038. // 心脏 系统
  2039. initCardiacSystem(ress) {
  2040. var that = this;
  2041. try {
  2042. let rdt_arrTemp = [];
  2043. if (ress.rrh_arr) {
  2044. rdt_arrTemp = that.splitN(ress.rdt_arr.split(","), 100);
  2045. }
  2046. if (ress.rdate) {
  2047. that.setData({
  2048. reportDate: ress.rdate
  2049. });
  2050. }
  2051. let rrh_arrTemp = [];
  2052. if (ress.rrh_arr) {
  2053. rrh_arrTemp = that.splitN(ress.rrh_arr.split(","), 100);
  2054. }
  2055. that.setData({
  2056. rdt_arrNew: rdt_arrTemp,
  2057. rrh_arrNew: rrh_arrTemp,
  2058. });
  2059. // console.log("that.data.rdt_arrNew,that.data.rrh_arrNew=" + that.data.rdt_arrNew + "," + that.data.rrh_arrNew);
  2060. updateCardiacSystem(that.data.rdt_arrNew, that.data.rrh_arrNew, that);
  2061. } catch (error) {
  2062. console.error(error);
  2063. }
  2064. },
  2065. initTimeWaterfall(ress) {//深浅睡眠
  2066. var that = this;
  2067. try {
  2068. let rdt_arrTemp = [];
  2069. if (ress.rrh_arr) {
  2070. // rdt_arrTemp = that.splitN(ress.rdt_arr.split(","), 100);
  2071. rdt_arrTemp = ress.rdt_arr.split(",");
  2072. }
  2073. // console.log('深浅睡眠11111=======' + JSON.stringify(rdt_arrTemp));
  2074. let rsleep_arr_Temp = [];
  2075. if (ress.rsleep_arr) {
  2076. // rsleep_arr_Temp = that.splitN(ress.rsleep_arr.split(","), 100);
  2077. rsleep_arr_Temp = ress.rsleep_arr.split(",");
  2078. }
  2079. // console.log('深浅睡眠222222=======' + JSON.stringify(rsleep_arr_Temp));
  2080. that.setData({
  2081. rdt_arrNew: rdt_arrTemp,
  2082. rsleep_arr: rsleep_arr_Temp,
  2083. rdeep_duration: ress.rdeep_duration,
  2084. rlight_duration: ress.rlight_duration,
  2085. rin_duration: ress.rin_duration,
  2086. rawake_duration: ress.rawake_duration,
  2087. rdeep_durationFormat: that.convertTimeToHoursAndMinutes(ress.rdeep_duration),
  2088. rlight_durationFormat: that.convertTimeToHoursAndMinutes(ress.rlight_duration),
  2089. rin_durationFormat: that.convertTimeToHoursAndMinutes(ress.rin_duration),
  2090. rawake_durationFormat: that.convertTimeToHoursAndMinutes(ress.rawake_duration),
  2091. });
  2092. that.calculateTheDurationOfDeepSleep();
  2093. } catch (error) {
  2094. console.error(error);
  2095. }
  2096. // console.log("that.data.rsleep_arr=" + that.data.rsleep_arr);
  2097. },
  2098. initOutOfBed(ress) {//离床次数
  2099. var that = this;
  2100. try {
  2101. var routbed_arr_Temp = [];
  2102. if (ress.routbed_arr) {
  2103. routbed_arr_Temp = ress.routbed_arr.split(",");
  2104. }
  2105. that.setData({
  2106. rdt_arr: ress.rdt_arr ? ress.rdt_arr.split(',') : [],
  2107. routbed_arr: routbed_arr_Temp,
  2108. rgobed_time: ress.rgobed_time,
  2109. routbed_time: ress.routbed_time,
  2110. rgobed_routbed: ress.rgobed_time + '~' + ress.routbed_time,
  2111. });
  2112. updateOutOfBed(that.data.rdt_arr, that.data.routbed_arr, that.data.rgobed_time, that.data.routbed_time, that)
  2113. } catch (error) {
  2114. console.error(error);
  2115. }
  2116. // console.log("that.data.routbed_arr=" + that.data.routbed_arr);
  2117. },
  2118. initBodyMovements(ress) {//体动次数
  2119. var that = this;
  2120. try {
  2121. var rmove_arr_Temp = [];
  2122. if (ress.rmove_arr) {
  2123. rmove_arr_Temp = ress.rmove_arr.split(",");
  2124. }
  2125. that.setData({
  2126. // rdt_arr: that.splitN(ress.rdt_arr ? ress.rdt_arr.split(',') : [], 100),
  2127. // rmove_arr: that.splitN(rmove_arr_Temp, 100),
  2128. rdt_arr: ress.rdt_arr ? ress.rdt_arr.split(',') : [],
  2129. rmove_arr: rmove_arr_Temp,
  2130. rgobed_time: ress.rgobed_time,
  2131. routbed_time: ress.routbed_time,
  2132. rgobed_routbed: ress.rgobed_time + '~' + ress.routbed_time,
  2133. });
  2134. updateBodyMovements(that.data.rdt_arr, that.data.rmove_arr, that.data.rgobed_time, that.data.routbed_time, that)
  2135. } catch (error) {
  2136. console.error(error);
  2137. }
  2138. // console.log("c8_that.data.rmove_arr=" + that.data.rmove_arr);
  2139. },
  2140. initChartRespiratory(ress) {//平均呼吸率
  2141. var that = this;
  2142. try {
  2143. var rhx_arr_Temp = [];
  2144. if (ress.rhx_arr) {
  2145. rhx_arr_Temp = ress.rhx_arr.split(",");
  2146. }
  2147. that.setData({
  2148. rdt_arr: that.splitN(ress.rdt_arr ? ress.rdt_arr.split(',') : [], 100),
  2149. rhx_arr: that.splitN(rhx_arr_Temp, 100),
  2150. rgobed_time: ress.rgobed_time,
  2151. routbed_time: ress.routbed_time,
  2152. rgobed_routbed: ress.rgobed_time + '~' + ress.routbed_time,
  2153. });
  2154. updateRespiratory(that.data.rdt_arr, that.data.rhx_arr, that.data.rgobed_time, that.data.routbed_time, that)
  2155. } catch (error) {
  2156. console.error(error);
  2157. }
  2158. // console.log("c81_that.data.ravg_hx_value=" + that.data.ravg_hx_value);
  2159. },
  2160. initChartSnoring(ress) {//打鼾
  2161. var that = this;
  2162. try {
  2163. var rsnoring_arr_Temp = [];
  2164. if (ress.rsnoring_arr) {
  2165. rsnoring_arr_Temp = ress.rsnoring_arr.split(",");
  2166. }
  2167. that.setData({
  2168. rdt_arr: that.splitN(ress.rdt_arr ? ress.rdt_arr.split(',') : [], 100),
  2169. rsnoring_arr: that.splitN(rsnoring_arr_Temp, 100),
  2170. rgobed_time: ress.rgobed_time,
  2171. routbed_time: ress.routbed_time,
  2172. rgobed_routbed: ress.rgobed_time + '~' + ress.routbed_time,
  2173. });
  2174. updateSnoring(that.data.rdt_arr, that.data.rsnoring_arr, that.data.rgobed_time, that.data.routbed_time, that)
  2175. } catch (error) {
  2176. console.error(error);
  2177. }
  2178. // console.log("c8_that.data.rmove_arr=" + that.data.rmove_arr);
  2179. },
  2180. initChartApnea(ress) {//呼吸暂停
  2181. var that = this;
  2182. try {
  2183. var rhxstop_arr_Temp = [];
  2184. if (ress.rhxstop_arr) {
  2185. rhxstop_arr_Temp = ress.rhxstop_arr.split(",");
  2186. }
  2187. that.setData({
  2188. rdt_arr: that.splitN(ress.rdt_arr ? ress.rdt_arr.split(',') : [], 100),
  2189. rhxstop_arr: that.splitN(rhxstop_arr_Temp, 100),
  2190. rgobed_time: ress.rgobed_time,
  2191. routbed_time: ress.routbed_time,
  2192. rgobed_routbed: ress.rgobed_time + '~' + ress.routbed_time,
  2193. });
  2194. updateApnea(that.data.rdt_arr, that.data.rhxstop_arr, that.data.rgobed_time, that.data.routbed_time, that)
  2195. } catch (error) {
  2196. console.error(error);
  2197. }
  2198. // console.log("c8_that.data.rhxstop_arr=" + that.data.rhxstop_arr);
  2199. },
  2200. mounted() {
  2201. },
  2202. /**
  2203. * 生命周期函数--监听页面隐藏
  2204. */
  2205. onHide: function () {
  2206. },
  2207. /**
  2208. * 生命周期函数--监听页面卸载
  2209. */
  2210. onUnload: function () {
  2211. },
  2212. /**
  2213. * 页面相关事件处理函数--监听用户下拉动作
  2214. */
  2215. onPullDownRefresh: function () {
  2216. },
  2217. /**
  2218. * 页面上拉触底事件的处理函数
  2219. */
  2220. onReachBottom: function () {
  2221. },
  2222. /**
  2223. * 用户点击右上角分享
  2224. */
  2225. onShareAppMessage: function () {
  2226. }
  2227. })