index.vue 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  1. <template>
  2. <view class="flex-col justify-start home-container">
  3. <view class="container-bg"></view>
  4. <cu-custom bgColor="#fff"><view slot="content" style="color: #FFFFFF">UU睡眠</view></cu-custom>
  5. <view class="flex-col home-module space-y-20">
  6. <!-- no device added -->
  7. <view v-if="!deviceAdded">
  8. <view class="flex-col items-start home-header space-y-10">
  9. <text class="home-header-title">欢迎回来!</text>
  10. <text class="font_3 text_3 home-header-subtitle">我是小U,您的健康智慧管家。</text>
  11. </view>
  12. <view class="flex-row items-center home_add_devive space-x-10">
  13. <image
  14. class="image_4"
  15. src="../../static/home/homeIconAdd.png"
  16. />
  17. <text class="text_5">添加设备</text>
  18. </view>
  19. <view class="home-ad flex-col group_5 space-y-40">
  20. <view class="flex-col home-header space-y-6">
  21. <view class="flex-row items-center space-x-8">
  22. <text class="font_4 text_8">UU AI智能睡眠监测仪</text>
  23. <view class="flex-row items-center section_7">
  24. <text class="font_5 text_9">去看看</text>
  25. <image
  26. class="shrink-0 image_9"
  27. src="../../static/home/homeIconGO.png"
  28. />
  29. </view>
  30. </view>
  31. <view class="flex-row items-center space-x-10">
  32. <text class="font_5 text_3 text_10">AI时代,全家人的睡眠健康顾问</text>
  33. </view>
  34. </view>
  35. </view>
  36. <view class="flex-col">
  37. <view class="flex-col group_5">
  38. <view class="flex-col home_blank_heart">
  39. <view class="flex-row items-center group_7 space-x-4">
  40. <image
  41. class="image_6"
  42. src="../../static/home/homeIconHeart.png"
  43. />
  44. <text class="font_1 text_9">心率</text>
  45. </view>
  46. <view class="flex-row justify-end items-start">
  47. <view class="section_5 view"></view>
  48. <text class="font_3 text_10">--</text>
  49. </view>
  50. <view class="flex-col group_8">
  51. <text class="self-start font_4 text_11">次/分</text>
  52. <view class="shrink-0 self-end section_5"></view>
  53. </view>
  54. </view>
  55. <view class="flex-col home_blank_breath">
  56. <view class="flex-row items-center group_10 space-x-4">
  57. <image
  58. class="image_7"
  59. src="../../static/home/homeIconBreath.png"
  60. />
  61. <text class="font_1 text_12">呼吸</text>
  62. </view>
  63. <view class="flex-row justify-end items-start">
  64. <view class="section_5 view_2"></view>
  65. <text class="font_3 text_13">--</text>
  66. </view>
  67. <view class="flex-col group_8">
  68. <text class="self-start font_4 text_11">次/分</text>
  69. <view class="shrink-0 self-end section_5"></view>
  70. </view>
  71. </view>
  72. </view>
  73. <view class="flex-row items-center home_blank_alert space-x-16">
  74. <image
  75. class="image_8"
  76. src="../../static/home/homeIconGift.png"
  77. />
  78. <view class="flex-col items-start flex-auto space-y-4">
  79. <text class="font_5">昨晚您的睡眠质量很好</text>
  80. <text class="font_5">暂时没有预警信息</text>
  81. </view>
  82. </view>
  83. </view>
  84. </view>
  85. <!-- device added -->
  86. <view v-if="deviceAdded" class="flex-col">
  87. <view class="flex-col items-start home-header space-y-10">
  88. <text class="home-header-title">欢迎回来!</text>
  89. <text class="font_3 text_3 home-header-subtitle">我是小U,您的健康智慧管家。</text>
  90. </view>
  91. <!-- home device -->
  92. <view class="flex-col home-device space-y-15">
  93. <view class="flex-row home-device-header">
  94. <view class="flex-row justify-between flex-auto equal-division">
  95. <view class="flex-row equal-division-item space-x-4">
  96. <text class="font_3 text_5">当前设备</text>
  97. <text class="font_3">{{ homeFrom.nowDevice }}</text>
  98. </view>
  99. <view class="flex-row equal-division-item space-x-14">
  100. <view class="flex-row space-x-4 margin-left-xl">
  101. <image class="shrink-0 image_6" src="../../static/home/homeIconWifi.png" />
  102. <text class="font_3">{{ homeFrom.status }}</text>
  103. </view>
  104. <!-- <view class="flex-row items-center space-x-6">-->
  105. <!-- <text class="font_3 text_6">45%</text>-->
  106. <!-- <image class="shrink-0 image_7" src="../../static/home/homeIconPower.png" />-->
  107. <!-- </view>-->
  108. </view>
  109. </view>
  110. <view class="flex-row items-center section_5 space-x-4">
  111. <image class="shrink-0 image_8" src="../../static/home/homeIconChange.png"/>
  112. <text class="font_3">切换</text>
  113. </view>
  114. </view>
  115. <view class="flex-row justify-center self-center home-device-status space-x-8">
  116. <text class="font_4 text_7">当前状态</text>
  117. <text class="font_4">{{ sleepStatus }}</text>
  118. </view>
  119. <!-- <view>-->
  120. <!-- <uni-steps :options="list1" :active="active" />-->
  121. <!-- </view>-->
  122. <!-- <view class="flex-row self-center items-center home-device-setting">-->
  123. <!-- <image-->
  124. <!-- class="shrink-0 image_8"-->
  125. <!-- src="../../static/home/homeIconSet.png"-->
  126. <!-- />-->
  127. <!-- <text>设置目标</text>-->
  128. <!-- </view>-->
  129. </view>
  130. <view class="home-report flex-col group_5 space-y-40">
  131. <view class="flex-col home-header space-y-6">
  132. <view class="flex-row items-center space-x-8">
  133. <text class="font_4 text_8">睡眠报告</text>
  134. <view class="flex-row items-center section_7">
  135. <text class="font_5 text_9">去看看</text>
  136. <image
  137. class="shrink-0 image_9"
  138. src="../../static/home/homeIconGO.png"
  139. />
  140. </view>
  141. </view>
  142. <view class="flex-row items-center space-x-10">
  143. <text class="font_5 text_3 text_10">小U已为您生成最后一份睡眠报告</text>
  144. <text class="font_5 text_3 text_11">2021-08-24</text>
  145. </view>
  146. </view>
  147. </view>
  148. <view class="flex-col space-y-40 home-data">
  149. <view class="flex-row group_6 equal-division">
  150. <view class="flex-row group_7 space-x-6 home-data-item equal-division-item">
  151. <view class="flex-col shrink-0 self-stretch group_9 space-y-20">
  152. <view class="flex-row items-center space-x-4">
  153. <image
  154. class="shrink-0 image_10"
  155. src="../../static/home/homeIconHeart.png"
  156. />
  157. <text class="font_1">心率</text>
  158. </view>
  159. <text class="self-center font_6">73</text>
  160. </view>
  161. <text class="self-start font_7 text_14">次/分</text>
  162. </view>
  163. <view class="flex-row justify-center group_8 space-x-6 home-data-item equal-division-item">
  164. <view class="flex-col space-y-20">
  165. <view class="flex-row space-x-4">
  166. <image
  167. class="shrink-0 image_4"
  168. src="../../static/home/homeIconBreath.png"
  169. />
  170. <text class="font_1 text_12">呼吸</text>
  171. </view>
  172. <text class="self-center font_6 text_13">24</text>
  173. </view>
  174. <text class="self-start font_7 text_15">次/分</text>
  175. </view>
  176. </view>
  177. </view>
  178. <view class="cu-card article">
  179. <view class="cu-item shadow chartsBgColor">
  180. <view class="title"><view class="text-cut text-lg text-gray">心率 <text class="text-green margin-left">{{ pjxl }} 分钟/次</text></view></view>
  181. <view class="content">
  182. <view class="echarts-wrap">
  183. <mpvue-echarts class="ec-canvas" canvasId="canvasChart-1" ref="xinlvRefChart" @onInit="onInit1"></mpvue-echarts>
  184. </view>
  185. </view>
  186. </view>
  187. </view>
  188. <view class="cu-card article">
  189. <view class="cu-item shadow chartsBgColor">
  190. <view class="title"><view class="text-cut text-lg text-white">呼吸<text class="text-orange margin-left">{{ pjhx }} 分钟/次</text></view></view>
  191. <view class="content">
  192. <view class="echarts-wrap">
  193. <mpvue-echarts class="ec-canvas" canvasId="canvasChart-2" ref="huxiRefChart" @onInit="onInit2"></mpvue-echarts>
  194. </view>
  195. </view>
  196. </view>
  197. </view>
  198. <view class="flex-col home-alert space-y-4">
  199. <view class="flex-row items-center space-x-4 home-alert-header">
  200. <image
  201. class="image_10"
  202. src="../../static/home/homeIconHeart.png"
  203. />
  204. <text class="font_1">实时预警</text>
  205. </view>
  206. <view v-if="list_alerts.length === 0" @click="handleAlertSetting" class="flex-row items-center home_blank_alert space-x-16">
  207. <image
  208. class="image_8"
  209. src="../../static/home/homeIconGift.png"
  210. />
  211. <view class="flex-col items-start flex-auto space-y-4">
  212. <text class="font_5">昨晚您的睡眠质量很好</text>
  213. <text class="font_5">暂时没有预警信息</text>
  214. </view>
  215. </view>
  216. <view v-else @click="handleAlertSetting" class="flex-col home-alert-list">
  217. <view class="flex-row justify-between items-center list-item" :key="i" v-for="(item, i) in list_alerts">
  218. <view class="flex-row items-center space-x-6">
  219. <image
  220. class="shrink-0 image_11"
  221. src="../../static/home/homeIconAlert.png"
  222. />
  223. <text class="font_8">{{ formatSosType(item.warn_type) }}</text>
  224. <text class="font_9 text_16">{{ formatSosTime(item.warn_time) }}</text>
  225. </view>
  226. <view class="flex-row items-baseline space-x-4">
  227. <text class="font_10">{{ item.warn_desc }}</text>
  228. </view>
  229. </view>
  230. </view>
  231. </view>
  232. </view>
  233. </view>
  234. <!-- <tab-bar currentPage="home" /> -->
  235. </view>
  236. </template>
  237. <script>
  238. import echarts from '@/static/echarts.min.js'
  239. import mpvueEcharts from '@/components/mpvue-echarts/src/echarts.vue'
  240. import Storage from '@/utils/storage'
  241. import * as API_deviceMemberBind from '@/api/device_member_bind'
  242. export default {
  243. components: {
  244. mpvueEcharts
  245. },
  246. data() {
  247. return {
  248. deviceAdded: false,
  249. list_alerts: [],
  250. active: 4,
  251. list1: [{
  252. title: '昨日就寝 11:24PM'
  253. }, {
  254. title: '就寝目标 11:00PM'
  255. }, {
  256. title: '起床目标 7:00AM'
  257. }, {
  258. title: '今日起床 7:14AM'
  259. }],
  260. chartObj1: null, // 心率图表
  261. chartObj2: null, // 呼吸图表
  262. myData1: [], // 心率数据
  263. myData2: [], // 呼吸数据
  264. myCount1: 0, // 心率x轴数字
  265. myCount2: 0, // 呼吸x轴数字
  266. allXl: 0, // 总心率
  267. pjxl: 0, // 平均心率
  268. allHx: 0, // 总呼吸
  269. pjhx: 0, // 平均呼吸
  270. sleepStatus: '离床',
  271. connecting: false,
  272. connected: false,
  273. mySocketTask: null,
  274. homeFrom: {
  275. nowDevice: '', // 当前设备
  276. status: '离线'
  277. },
  278. deviceList: [], // 设备列表
  279. lastMsgTime: 0, // 最后一次设备消息时间
  280. memberId: 50289 // 先写死
  281. };
  282. },
  283. onLoad() {
  284. this.API_getDeviceList()
  285. },
  286. onUnload() {
  287. this.mySocketTask.onClose(res => {
  288. this.connected = false
  289. clearInterval(this.timer)
  290. })
  291. },
  292. methods: {
  293. API_getDeviceList() {
  294. const _this = this
  295. API_deviceMemberBind.getDeviceByDtypeAndMemberId({dtype: '睡眠床垫', memberId: this.memberId}).then(res => {
  296. if (res.length === 0) {
  297. _this.deviceAdded = false
  298. } else {
  299. _this.deviceAdded = true
  300. _this.deviceList = res
  301. _this.homeFrom.nowDevice = res[0].imei
  302. Storage.setItem("nowChangeDevice", _this.homeFrom.nowDevice)
  303. _this.init()
  304. }
  305. })
  306. },
  307. init() {
  308. const _this = this
  309. setTimeout(() => {
  310. _this.nowChart1()
  311. _this.nowChart2()
  312. _this.connect()
  313. }, 800)
  314. },
  315. connect() {
  316. let _this = this
  317. if (this.connected || this.connecting) {
  318. uni.showModal({
  319. content: '正在连接或者已经连接,请勿重复连接!',
  320. showCancel: false
  321. });
  322. return false
  323. }
  324. this.connecting = true
  325. // let wsUrl = api.base.replace('http', 'ws')
  326. this.mySocketTask = uni.connectSocket({
  327. url: 'ws://wdkl.natapp1.cc/sleep_report/monitor/' + this.memberId,
  328. success(res) {
  329. // 这里是接口调用成功的回调,不是连接成功的回调,请注意
  330. },
  331. fail(err) {
  332. // 这里是接口调用失败的回调,不是连接失败的回调,请注意
  333. }
  334. })
  335. this.mySocketTask.onOpen(res => {
  336. this.connecting = false
  337. this.connected = true
  338. uni.hideLoading()
  339. let _this = this
  340. this.timer = setInterval(function () { //每隔5秒钟发送一次心跳,避免websocket连接因超时而自动断开
  341. if (Date.parse(new Date()) - _this.lastMsgTime > 5000) { // 5秒没有收到新消息,则判断为离线
  342. _this.homeFrom.status = '离线'
  343. _this.sleepStatus = '离线'
  344. _this.pjxl = '--'
  345. _this.pjhx = '--'
  346. }
  347. _this.mySocketTask.send({data: 'ping'})
  348. }, 30000) // 30秒的心跳包
  349. })
  350. this.mySocketTask.onError(err => {
  351. this.connecting = false
  352. this.connected = false
  353. uni.hideLoading()
  354. uni.showModal({
  355. content: '连接失败,可能是websocket服务不可用,请稍后再试',
  356. showCancel: false
  357. })
  358. console.log('onError', err)
  359. })
  360. this.mySocketTask.onMessage(res => {
  361. let msg = res.data
  362. // console.log('收到消息:', msg)
  363. if (msg.length === 30) {
  364. if (this.homeFrom.nowDevice !== msg.substring(2, 14)) {
  365. return
  366. }
  367. this.homeFrom.status = '在线'
  368. this.lastMsgTime = Date.parse(new Date())
  369. this.getValue1(parseInt(msg.substring(22, 24), 16))
  370. this.getValue2(parseInt(msg.substring(24, 26), 16))
  371. switch (msg.substring(26, 28)) {
  372. case "03":
  373. this.sleepStatus = '在床'
  374. break;
  375. case "04":
  376. this.sleepStatus = '离床'
  377. break;
  378. case "05":
  379. this.sleepStatus = '打鼾'
  380. break;
  381. case "06":
  382. this.sleepStatus = '体动'
  383. break;
  384. default:
  385. break;
  386. }
  387. } else {
  388. const data = JSON.parse(res.data)
  389. console.log('收到消息为:', data)
  390. if (data.sn && this.homeFrom.nowDevice === data.sn) {
  391. this.list_alerts.push(data)
  392. }
  393. }
  394. })
  395. this.mySocketTask.onClose(res => {
  396. this.connected = false
  397. this.msg = false
  398. clearInterval(this.timer)
  399. })
  400. },
  401. nowChart1() {
  402. this.onInit1(this.chartObj1)
  403. let canvas = this.$refs.xinlvRefChart.canvas
  404. echarts.setCanvasCreator(() => canvas)
  405. this.myChart1 = echarts.init(canvas, 'halloween', {
  406. width: this.chartObj1.width,
  407. height: this.chartObj1.height
  408. })
  409. this.options1 = Object.assign(this.getOptions('#FFFFFF', 800), {})
  410. this.options1.series.forEach((item) => {
  411. item.data = this.myData1
  412. })
  413. this.myChart1.setOption(this.options1)
  414. },
  415. nowChart2() {
  416. this.onInit2(this.chartObj2);
  417. let canvas = this.$refs.huxiRefChart.canvas;
  418. echarts.setCanvasCreator(() => canvas);
  419. this.myChart2 = echarts.init(canvas, 'halloween', {
  420. width: this.chartObj2.width,
  421. height: this.chartObj2.height
  422. });
  423. this.options2 = Object.assign(this.getOptions('#06f5d2', 400), {})
  424. this.options2.series.forEach((item) => {
  425. item.data = this.myData2
  426. })
  427. this.myChart2.setOption(this.options2)
  428. },
  429. onInit1(e) {
  430. this.chartObj1 = e
  431. },
  432. onInit2(e) {
  433. this.chartObj2 = e
  434. },
  435. getOptions(color, xMax) {
  436. return {
  437. visualMap: [
  438. {
  439. show: false,
  440. type: 'continuous',
  441. seriesIndex: 0,
  442. min: 0,
  443. max: 300,
  444. },
  445. ],
  446. color: color,
  447. title: {
  448. left: 'left',
  449. // text: title,
  450. },
  451. tooltip: {
  452. trigger: 'axis',
  453. axisPointer: {
  454. animation: false,
  455. },
  456. },
  457. grid: {
  458. top: '15%',
  459. bottom: '10%',
  460. },
  461. xAxis: {
  462. type: 'category',
  463. boundaryGap: [0, '100%'],
  464. show: false, // 不显示x轴
  465. splitLine: {
  466. show: false,
  467. },
  468. triggerEvent: true
  469. },
  470. yAxis: {
  471. type: 'value',
  472. boundaryGap: [0, '100%'],
  473. min: 0,
  474. max: xMax,
  475. // max: 'dataMax', // 取数据在该轴上的最大值作为最大刻度
  476. splitLine: {
  477. show: false, // 是否显示分隔线
  478. },
  479. axisLine: {
  480. show: false, // 是否显示坐标轴轴线
  481. lineStyle:{
  482. color:'#FFFFFF',
  483. width:1, //x轴线的宽度
  484. }
  485. },
  486. },
  487. series: [
  488. {
  489. type: 'line',
  490. showSymbol: false,
  491. hoverAnimation: false,
  492. data: [],
  493. },
  494. ]
  495. }
  496. },
  497. getValue1(value) {
  498. // console.log("心率是", value)
  499. this.pjxl = value
  500. if (this.myData1.length > 60) {
  501. this.myData1.splice(0,5)
  502. }
  503. if (value !== 0) {
  504. for (let i = 0; i < 5; i++) {
  505. this.myCount1 ++;
  506. value = parseInt(Math.random(100) * 500 + 300)
  507. this.myData1.push([this.myCount1, value])
  508. }
  509. } else {
  510. for (let i = 0; i < 5; i++) {
  511. this.myCount1 ++;
  512. value = 410 + parseInt(Math.random() * 10 - 5)
  513. this.myData1.push([this.myCount1, value])
  514. }
  515. }
  516. this.myChart1.setOption(this.options1)
  517. },
  518. getValue2(value) {
  519. // console.log("呼吸值是", value)
  520. this.pjhx = value
  521. if (this.myData2.length > 60) {
  522. this.myData2.splice(0,5)
  523. }
  524. if (value === 0) {
  525. for (let i = 0; i < 5; i++) {
  526. this.myCount2 ++;
  527. value = 220 + parseInt(Math.random() * 10 - 5)
  528. this.myData2.push([this.myCount2, value])
  529. }
  530. } else {
  531. value = parseInt((Math.random(10) * 300 + 100))
  532. for (let i = 0; i < 5; i++) {
  533. this.myCount2 ++;
  534. value += parseInt(Math.random() * 10 - 5)
  535. this.myData2.push([this.myCount2, value])
  536. }
  537. }
  538. this.myChart2.setOption(this.options2)
  539. },
  540. handleAlertSetting() {
  541. uni.navigateTo({
  542. url: "/pages/alertSetting/alertSetting?imei=" + this.homeFrom.nowDevice
  543. });
  544. },
  545. formatSosType(value) {
  546. switch (value) {
  547. case 1:
  548. return '心率过速'
  549. case 2:
  550. return '心率过缓'
  551. case 3:
  552. return '呼吸过速'
  553. case 4:
  554. return '呼吸过缓'
  555. case 5:
  556. return '离床预警'
  557. case 6:
  558. return '一键预警'
  559. case 7:
  560. return '离线预警'
  561. default:
  562. break;
  563. }
  564. },
  565. formatSosTime(value) {
  566. return value.substring(10, value.length - 3)
  567. }
  568. }
  569. };
  570. </script>
  571. <style lang="scss" scoped>
  572. .echarts-wrap {
  573. width: 100%;
  574. height: 150px;
  575. /*padding: 10upx;*/
  576. margin-bottom: 0.3rem
  577. }
  578. .chartsBgColor{
  579. background: linear-gradient(90deg, rgba(86, 17, 247, 0.5) 0%, #4d9efa 100%);
  580. }
  581. .equal-division {
  582. .equal-division-item {
  583. padding: 0.25rem 0.38rem 0;
  584. flex: 1 1 10.81rem;
  585. }
  586. }
  587. .home_add_devive {
  588. margin-right: 1.25rem;
  589. margin: 1rem;
  590. padding: 3.75rem 0;
  591. background-color: #0233c699;
  592. border-radius: 1rem;
  593. backdrop-filter: blur(0.63rem);
  594. width: 20.94rem;
  595. .image_4 {
  596. margin-left: 6.38rem;
  597. width: 1.5rem;
  598. height: 1.5rem;
  599. }
  600. .text_5 {
  601. color: #ffffff;
  602. font-size: 1.5rem;
  603. font-family: PingFangSC;
  604. line-height: 1.38rem;
  605. }
  606. }
  607. .space-x-10 {
  608. & > view:not(:first-child),
  609. & > text:not(:first-child),
  610. & > image:not(:first-child) {
  611. margin-left: 0.63rem;
  612. }
  613. }
  614. .home_ad {
  615. margin-left: 2.25rem;
  616. background: url(../../static/home/homeBg2.png);
  617. background-repeat: no-repeat;
  618. background-size: contain;
  619. .text_6 {
  620. padding: 0.13rem 0;
  621. color: #ffffff;
  622. font-size: 1rem;
  623. font-family: PingFangSC;
  624. line-height: 0.94rem;
  625. }
  626. .section_4 {
  627. padding: 0.13rem 0.38rem;
  628. background-image: linear-gradient(90deg, #2c25f799 0%, #061599 100%);
  629. border-radius: 0.44rem;
  630. width: 2.88rem;
  631. height: 0.88rem;
  632. .font_2 {
  633. font-size: 0.69rem;
  634. font-family: PingFangSC;
  635. line-height: 0.63rem;
  636. color: #ffffff;
  637. }
  638. .text_7 {
  639. font-size: 0.63rem;
  640. line-height: 0.56rem;
  641. }
  642. .image_5 {
  643. width: 0.19rem;
  644. height: 0.31rem;
  645. }
  646. }
  647. }
  648. .space-x-6 {
  649. & > view:not(:first-child),
  650. & > text:not(:first-child),
  651. & > image:not(:first-child) {
  652. margin-left: 0.38rem;
  653. }
  654. }
  655. .group_5 {
  656. padding-left: 1rem;
  657. padding-right: 1rem;
  658. .font_2 {
  659. font-size: 0.69rem;
  660. font-family: PingFangSC;
  661. line-height: 0.63rem;
  662. color: #ffffff;
  663. }
  664. .text_8 {
  665. font-size: 0.63rem;
  666. line-height: 0.59rem;
  667. opacity: 0.6;
  668. }
  669. .home_blank_heart {
  670. margin-top: 1rem;
  671. opacity: 1;
  672. border-radius: 16px;
  673. background: linear-gradient(180deg, rgba(52, 26, 75, 1) 0%, rgba(22, 125, 242, 1) 100%);
  674. backdrop-filter: blur(20px);
  675. padding:1rem 0rem 2rem 1rem;
  676. .group_7 {
  677. padding-bottom: 1.13rem;
  678. .image_6 {
  679. width: 1.13rem;
  680. height: 0.88rem;
  681. }
  682. .text_9 {
  683. line-height: 1.03rem;
  684. }
  685. }
  686. .view {
  687. margin-right: -20.13rem;
  688. }
  689. .text_10 {
  690. margin-right: 18.75rem;
  691. margin-top: 1rem;
  692. }
  693. }
  694. .home_blank_breath {
  695. margin-top: 1rem;
  696. opacity: 1;
  697. border-radius: 16px;
  698. background: linear-gradient(180deg, rgba(52, 26, 75, 1) 0%, rgba(22, 125, 242, 1) 100%);
  699. backdrop-filter: blur(20px);
  700. padding:1rem 0rem 2rem 1rem;
  701. .group_10 {
  702. padding-bottom: 1.25rem;
  703. .image_7 {
  704. width: 1.13rem;
  705. height: 1.06rem;
  706. }
  707. .text_12 {
  708. line-height: 1rem;
  709. }
  710. }
  711. .view_2 {
  712. margin-right: -20rem;
  713. }
  714. .text_13 {
  715. margin-right: 18.63rem;
  716. margin-top: 1rem;
  717. }
  718. }
  719. .space-x-4 {
  720. & > view:not(:first-child),
  721. & > text:not(:first-child),
  722. & > image:not(:first-child) {
  723. margin-left: 0.25rem;
  724. }
  725. }
  726. .font_1 {
  727. font-size: 1.13rem;
  728. font-family: PingFangSC;
  729. line-height: 1.06rem;
  730. color: #ffffff;
  731. }
  732. .section_5 {
  733. background-color: #ffffff1a;
  734. width: 15.94rem;
  735. height: 0.063rem;
  736. }
  737. .font_3 {
  738. font-size: 2.5rem;
  739. font-family: PingFangSC;
  740. line-height: 0.19rem;
  741. color: #ffffff;
  742. }
  743. .group_8 {
  744. margin-top: 1.38rem;
  745. padding-left: 0.63rem;
  746. .font_4 {
  747. font-size: 0.69rem;
  748. font-family: PingFangSC;
  749. line-height: 0.63rem;
  750. color: #ffffff80;
  751. }
  752. .text_11 {
  753. font-size: 0.75rem;
  754. line-height: 0.69rem;
  755. }
  756. }
  757. }
  758. .home_blank_alert {
  759. margin: 1rem 1.25rem 0;
  760. padding: 0.94rem;
  761. background-color: #02299ecc;
  762. border-radius: 1rem;
  763. .image_8 {
  764. width: 7.06rem;
  765. height: 4.94rem;
  766. }
  767. .space-y-4 {
  768. & > view:not(:first-child),
  769. & > text:not(:first-child),
  770. & > image:not(:first-child) {
  771. margin-top: 0.25rem;
  772. }
  773. .font_5 {
  774. font-size: 0.88rem;
  775. font-family: PingFangSC;
  776. line-height: 1.06rem;
  777. color: #167df2;
  778. }
  779. }
  780. }
  781. .space-x-16 {
  782. & > view:not(:first-child),
  783. & > text:not(:first-child),
  784. & > image:not(:first-child) {
  785. margin-left: 1rem;
  786. }
  787. }
  788. .container-bg {
  789. position: fixed;
  790. left: -130px;
  791. top: -130px;
  792. width: 480px;
  793. height: 344px;
  794. opacity: 1;
  795. overflow: hidden;
  796. border-radius: 63px;
  797. -webkit-transform: rotate(-315deg);
  798. transform: rotate(-315deg);
  799. background: linear-gradient(90deg, rgba(86, 17, 247, 0.5) 0%, #4d9efa 100%);
  800. }
  801. .home-container {
  802. padding-bottom: 2rem;
  803. background-color: #000000;
  804. width: 100%;
  805. overflow-y: auto;
  806. overflow-x: hidden;
  807. height: 100%;
  808. .home-module {
  809. padding: 1.75rem 0 3.38rem;
  810. overflow-y: auto;
  811. z-index: 100;
  812. .home-header {
  813. padding: 0 1.25rem;
  814. .home-header-title {
  815. color: #ffffff;
  816. font-size: 1.25rem;
  817. font-family: PingFangSC;
  818. line-height: 1.16rem;
  819. }
  820. .text_8 {
  821. color: #ffffff;
  822. opacity: 1;
  823. }
  824. .text_3 {
  825. opacity: 0.6;
  826. }
  827. .home-header-subtitle {
  828. line-height: 0.72rem;
  829. }
  830. .space-x-10 {
  831. & > view:not(:first-child),
  832. & > text:not(:first-child),
  833. & > image:not(:first-child) {
  834. margin-left: 0.63rem;
  835. }
  836. .text_10 {
  837. line-height: 0.59rem;
  838. }
  839. .text_11 {
  840. line-height: 0.47rem;
  841. }
  842. }
  843. }
  844. .space-y-10 {
  845. & > view:not(:first-child),
  846. & > text:not(:first-child),
  847. & > image:not(:first-child) {
  848. margin-top: 0.63rem;
  849. }
  850. }
  851. .home-device {
  852. margin: 1rem 1.25rem;
  853. padding-bottom: 2rem;
  854. background-color: #0233c699;
  855. border-radius: 1rem;
  856. backdrop-filter: blur(0.63rem);
  857. .home-device-setting {
  858. width: 70px;
  859. height: 20px;
  860. opacity: 1;
  861. border-radius: 7px;
  862. background: linear-gradient(90deg, rgba(255, 35, 247, 1) 0%, rgba(91, 30, 154, 1) 100%);
  863. .image_8 {
  864. width: 10px;
  865. height: 10px;
  866. }
  867. font-size: 10px;
  868. font-weight: 400;
  869. line-height: 10px;
  870. color: rgba(255, 255, 255, 1);
  871. padding: 0.3rem;
  872. }
  873. .home-device-header {
  874. background-color: #ffffff33;
  875. border-radius: 1rem 1rem 0px 0px;
  876. .equal-division {
  877. padding: 0 1rem;
  878. .equal-division-item {
  879. padding: 0.38rem 0;
  880. .text_5 {
  881. opacity: 0.5;
  882. }
  883. }
  884. .space-x-14 {
  885. & > view:not(:first-child),
  886. & > text:not(:first-child),
  887. & > image:not(:first-child) {
  888. margin-left: 0.88rem;
  889. }
  890. }
  891. }
  892. .section_5 {
  893. padding: 0.38rem 0.5rem;
  894. background-image: linear-gradient(90deg, #2c25f799 0%, #061599 100%);
  895. border-radius: 0px 1rem 0px 0px;
  896. height: 1.5rem;
  897. .image_8 {
  898. width: 0.75rem;
  899. height: 0.75rem;
  900. }
  901. }
  902. }
  903. .home-device-status {
  904. padding: 0.25rem 0 0.25rem 0.25rem;
  905. background-color: #ffffff33;
  906. border-radius: 0.75rem;
  907. width: 7.88rem;
  908. .text_7 {
  909. opacity: 0.4;
  910. }
  911. }
  912. }
  913. .space-y-15 {
  914. & > view:not(:first-child),
  915. & > text:not(:first-child),
  916. & > image:not(:first-child) {
  917. margin-top: 0.94rem;
  918. }
  919. }
  920. .font_3 {
  921. font-size: 0.75rem;
  922. font-family: PingFangSC;
  923. line-height: 0.69rem;
  924. color: #ffffff;
  925. }
  926. .home-report {
  927. margin: 0 1.25rem;
  928. padding: 1rem 0;
  929. background-image: url(../../static/home/homeReportBg.png);
  930. background-size: contain;
  931. background-repeat: no-repeat;
  932. .space-y-6 {
  933. & > view:not(:first-child),
  934. & > text:not(:first-child),
  935. & > image:not(:first-child) {
  936. margin-top: 0.38rem;
  937. }
  938. }
  939. }
  940. .home-ad {
  941. margin: 0 1.25rem;
  942. padding: 1rem 0;
  943. background-image: url(../../static/home/homeBg2.png);
  944. background-size: contain;
  945. background-repeat: no-repeat;
  946. .space-y-6 {
  947. & > view:not(:first-child),
  948. & > text:not(:first-child),
  949. & > image:not(:first-child) {
  950. margin-top: 0.38rem;
  951. }
  952. }
  953. }
  954. .home-data {
  955. margin: 0rem 1.25rem;
  956. padding: 1rem 0rem;
  957. .home-data-item {
  958. padding: 1rem 0rem;
  959. margin: 0 0.3rem;
  960. opacity: 1;
  961. border-radius: 16px;
  962. background: linear-gradient(180deg, rgba(52, 26, 75, 0.65) 0%, rgba(22, 125, 242, 1) 100%);
  963. backdrop-filter: blur(20px);
  964. }
  965. }
  966. .group_6 {
  967. overflow-x: hidden;
  968. width: 100%;
  969. .group_7 {
  970. overflow-x: hidden;
  971. width: 10rem;
  972. .group_9 {
  973. margin-left: 2.25rem;
  974. }
  975. .text_14 {
  976. margin-top: 3.5rem;
  977. }
  978. }
  979. .group_8 {
  980. width: 10rem;
  981. .text_15 {
  982. margin-top: 3.63rem;
  983. }
  984. }
  985. .font_6 {
  986. font-size: 3rem;
  987. font-family: PingFangSC;
  988. line-height: 2.19rem;
  989. color: #ffffff;
  990. }
  991. .font_7 {
  992. font-size: 0.75rem;
  993. font-family: PingFangSC;
  994. line-height: 0.69rem;
  995. color: #ffffff80;
  996. }
  997. }
  998. .space-y-40 {
  999. & > view:not(:first-child),
  1000. & > text:not(:first-child),
  1001. & > image:not(:first-child) {
  1002. margin-top: 2.5rem;
  1003. }
  1004. }
  1005. .space-x-8 {
  1006. & > view:not(:first-child),
  1007. & > text:not(:first-child),
  1008. & > image:not(:first-child) {
  1009. margin-left: 0.5rem;
  1010. }
  1011. .text_8 {
  1012. padding: 0.13rem 0;
  1013. }
  1014. .section_7 {
  1015. padding: 0.13rem 0.38rem;
  1016. background-image: linear-gradient(90deg, #ff23f7 0%, #5b1e9a 100%);
  1017. border-radius: 0.44rem;
  1018. height: 0.88rem;
  1019. .text_9 {
  1020. line-height: 0.56rem;
  1021. }
  1022. .image_9 {
  1023. width: 0.19rem;
  1024. height: 0.31rem;
  1025. }
  1026. }
  1027. }
  1028. .font_4 {
  1029. font-size: 1rem;
  1030. font-family: PingFangSC;
  1031. line-height: 0.94rem;
  1032. color: #ffffff;
  1033. }
  1034. .font_5 {
  1035. font-size: 0.63rem;
  1036. font-family: PingFangSC;
  1037. color: #ffffff;
  1038. }
  1039. .space-x-6 {
  1040. & > view:not(:first-child),
  1041. & > text:not(:first-child),
  1042. & > image:not(:first-child) {
  1043. margin-left: 0.38rem;
  1044. }
  1045. .text_6 {
  1046. line-height: 0.56rem;
  1047. }
  1048. .image_7 {
  1049. width: 1.31rem;
  1050. height: 0.69rem;
  1051. }
  1052. .image_11 {
  1053. width: 1.13rem;
  1054. height: 0.94rem;
  1055. }
  1056. .font_9 {
  1057. font-size: 0.88rem;
  1058. font-family: PingFangSC;
  1059. line-height: 0.69rem;
  1060. color: #ced5dc;
  1061. }
  1062. .text_16 {
  1063. line-height: 0.63rem;
  1064. }
  1065. }
  1066. .space-x-4 {
  1067. & > view:not(:first-child),
  1068. & > text:not(:first-child),
  1069. & > image:not(:first-child) {
  1070. margin-left: 0.25rem;
  1071. }
  1072. .image_6 {
  1073. width: 0.94rem;
  1074. height: 0.75rem;
  1075. }
  1076. .image_10 {
  1077. width: 1.13rem;
  1078. height: 0.88rem;
  1079. }
  1080. .font_1 {
  1081. font-size: 1.13rem;
  1082. font-family: PingFangSC;
  1083. line-height: 1.03rem;
  1084. color: #ffffff;
  1085. }
  1086. .image_4 {
  1087. width: 1.13rem;
  1088. height: 1.06rem;
  1089. }
  1090. .text_12 {
  1091. line-height: 1rem;
  1092. }
  1093. .font_10 {
  1094. font-size: 1.13rem;
  1095. font-family: PingFangSC;
  1096. line-height: 0.81rem;
  1097. color: #ff465a;
  1098. }
  1099. }
  1100. .home-alert {
  1101. margin: 0 1.25rem;
  1102. padding: 1rem 0.88rem 0.13rem;
  1103. background-color: #0233c6cc;
  1104. border-radius: 1rem;
  1105. .home-alert-header {
  1106. }
  1107. .home-alert-list {
  1108. .list-item {
  1109. padding: 0.88rem 0;
  1110. border-bottom: solid 0.063rem #ffffff1a;
  1111. }
  1112. }
  1113. }
  1114. .space-y-4 {
  1115. & > view:not(:first-child),
  1116. & > text:not(:first-child),
  1117. & > image:not(:first-child) {
  1118. margin-top: 0.25rem;
  1119. }
  1120. }
  1121. .font_8 {
  1122. font-size: 0.88rem;
  1123. font-family: PingFangSC;
  1124. line-height: 0.81rem;
  1125. color: #ffffff;
  1126. }
  1127. }
  1128. .space-y-20 {
  1129. & > view:not(:first-child),
  1130. & > text:not(:first-child),
  1131. & > image:not(:first-child) {
  1132. margin-top: 1.25rem;
  1133. }
  1134. .text_13 {
  1135. line-height: 2.16rem;
  1136. }
  1137. }
  1138. }
  1139. </style>