watchIndex.vue 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797
  1. <template>
  2. <view :class="source=='course'? 'watch-con watch-course':'watch-con'">
  3. <view :class="source=='course'? 'userbox userboxTop':'userbox'">
  4. <image v-show="source=='course'" class="home_top_bg" src="@/static/image/hall/home_top_bg.png" mode="widthFix"></image>
  5. <image v-show="source!='course'" class="home_top_bg" src="@/static/images/pages_watch/images/home_top_bg.png" mode="widthFix"></image>
  6. <!-- <image class="home_top_bg" src="@/static/newYear/home_top_bg.png" mode="widthFix"></image> -->
  7. <view class="user">
  8. <view class="user-navbox">
  9. <scroll-view class="tab-bar" :scroll-x="true" :show-scrollbar="false"
  10. :scroll-into-view="scrollInto">
  11. <view :class="selectUser == index ? 'user-navitem user-navitem-active':'user-navitem'" :id="'tab'+index"
  12. v-for="(item,index) in userList" :key="index" @click="handleUser(index)">
  13. <view>{{item.name}}</view>
  14. <view class="user-navbox-line" :style="{display: selectUser == index ? 'flex':'none'}">
  15. <image src="@/static/images/pages_watch/icons/tag_icon.png" mode="aspectFill"></image>
  16. </view>
  17. </view>
  18. </scroll-view>
  19. </view>
  20. <view class="user-family y-bc" @click="navigateToUrl('/pages_watch/index/myfamily/index')">
  21. <image src="@/static/images/pages_watch/icons/my_family_icon.png" mode="aspectFill"></image>
  22. <!-- <u-icon name="account" color="#fff" size="24"></u-icon> -->
  23. <view>我的家人</view>
  24. </view>
  25. </view>
  26. </view>
  27. <mescroll-body ref="mescrollRef" @init="mescrollInit" top="0" bottom="0" :down="downOption" :up="upOption" @down="downCallback">
  28. <view class="watch-con-body">
  29. <!-- banner v-if="userList[selectUser] && userList[selectUser].deviceId && userList[selectUser].deviceId.length > 0"-->
  30. <swiper v-if="userDeviceList && userDeviceList.length > 0" style="height: 350rpx;padding: 0 12rpx;box-sizing: border-box;" :current="activeTab" :duration="300" :previous-margin="userDeviceList.length > 0 &&activeTab == userDeviceList.length ? '92rpx':'0'" :next-margin="activeTab == userDeviceList.length ? '0':'92rpx'" @change="onSwiperChange">
  31. <swiper-item class="swiper-item" v-for="(item,index) in userDeviceList" :key="index">
  32. <view class="bindbox-banner" :style="{height: activeTab == index ?'308rpx':'260rpx'}">
  33. <view class="bindbox-head">
  34. <image class="bindbox-img" src="@/static/images/pages_watch/images/watch_icon.png" mode="aspectFill"></image>
  35. <view class="bindbox-headr" @tap="navigateToUrl('/pages_watch/index/targetInfo?selectUser='+selectUser+'&selectUserInfo='+ JSON.stringify(userList[selectUser]))">
  36. <view>
  37. <view class="bindbox-title textOne" v-show="selectUser == 0">
  38. {{item.user && item.user.nickName ? item.user.nickName : defaultName || '--' }}
  39. </view>
  40. <view class="bindbox-title textOne" v-show="selectUser != 0">
  41. {{userList[selectUser].name}}
  42. </view>
  43. <view>点击查看佩戴者信息</view>
  44. </view>
  45. <image src="@/static/images/pages_watch/icons/edit_white_arrow_right_icon.png"></image>
  46. </view>
  47. </view>
  48. <view class="bindbox-info">
  49. <view class="bindbox-info-l">
  50. <view class="bindbox-info-name">
  51. <view>{{ currentDevice && currentDevice.type == 1 ? '小护士设备' : '手表' }}</view>
  52. <view class="bindbox-info-desc">{{item.ble || '--'}}</view>
  53. </view>
  54. <view class="bindbox-info-status" v-show="currentDevice&&currentDevice.type==0">
  55. <view>状态</view>
  56. <!-- 0-OFFLINE 1-ONLINE 2-UNACTIVE 3-DISABLE 4-NOT EXIST -->
  57. <view class="bindbox-info-desc">
  58. {{item.status == 1 ? '在线' : '离线'}}
  59. <navigator url="/pages_watch/index/equipment/offlineReason" hover-class="none" style="display: inherit;">
  60. <image class="question_mark_icon" src="@/static/images/pages_watch/icons/question_mark_icon.png" mode="aspectFill"></image>
  61. </navigator>
  62. </view>
  63. <view class="bindbox-info-desc" v-show="currentDevice&&(currentDevice.type==1||currentDevice.type==2)">
  64. {{item.status == 1 ? '在线' : '离线'}}
  65. <navigator url="/pages_watch/index/equipment/offlineReason" hover-class="none" style="display: inherit;">
  66. <image class="question_mark_icon" src="@/static/images/pages_watch/icons/question_mark_icon.png" mode="aspectFill"></image>
  67. </navigator>
  68. </view>
  69. </view>
  70. </view>
  71. <view style="flex-shrink: 0;margin-left: 30rpx;" v-show="currentDevice&&currentDevice.type==0">
  72. <view class="status_btn demonstrate_btn" style="margin-bottom: 20rpx;width: 192rpx;" @click="handleGuide">操作视频<image src="@/static/images/pages_watch/icons/edit_white_arrow_right_icon.png"></image>
  73. </view>
  74. <view class="bindbox-info-r" @tap="navigateToUrl('/pages_watch/index/equipment/index?selectUser='+selectUser)">
  75. 设备管理
  76. <image src="@/static/images/pages_watch/icons/arrow_right_orange_icon.png"></image>
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. </swiper-item>
  82. <swiper-item class="swiper-item">
  83. <view class="add-device" :style="{height: activeTab == userDeviceList.length ?'308rpx':'260rpx', width:activeTab == userDeviceList.length ?'308rpx':'260rpx'}" @click="openMeasurePopup">
  84. <view class="add-device-icon">
  85. <image src="@/static/images/pages_watch/icons/add_watch_icon.png" mode="aspectFill"></image>
  86. </view>
  87. <text>添加设备</text>
  88. </view>
  89. </swiper-item>
  90. </swiper>
  91. <view class="banner" v-else>
  92. <image class="banner_bg" src="@/static/images/pages_watch/images/gold_circle_bg.png" mode="heightFix"></image>
  93. <image class="banner_bg_watch" src="@/static/images/pages_watch/images/watch_img.png" mode="heightFix"></image>
  94. <view style="position: relative;z-index: 1;">
  95. <view class="status_text">未绑定</view>
  96. <view class="status_desc">还没绑定健康手表,扫描 手表二维码去绑定</view>
  97. <view class="status_btnbox">
  98. <button class="status_btn binding_btn" :loading="btnLoading" :disabled="btnLoading" @click="openMeasurePopup">
  99. {{btnLoading ? "绑定中...":"立即绑定"}}
  100. <image v-show="!btnLoading" src="@/static/images/pages_watch/icons/arrow_right_orange_icon.png"></image>
  101. </button>
  102. <view class="status_btn demonstrate_btn" @click="handleGuide">操作视频<image src="@/static/images/pages_watch/icons/edit_white_arrow_right_icon.png"></image>
  103. </view>
  104. </view>
  105. </view>
  106. </view>
  107. <view class="ceshi" v-show="currentDevice&&(currentDevice.type==1||currentDevice.type==2)" @click="goMeasureDevice">
  108. <image src="@/static/images/pages_watch/icons/start_measurement_icon.png" mode="aspectFill"></image>
  109. <view class="ceshi-text">立即开始测量</view>
  110. </view>
  111. <view v-if="showMeasurePopup" class="measure-popup-mask" @click="closeMeasurePopup">
  112. <view class="measure-popup" @click.stop>
  113. <view class="measure-popup-title">选择绑定设备</view>
  114. <view
  115. v-for="item in measureDeviceOptions"
  116. :key="item.value"
  117. :class="selectedMeasureDevice === item.value ? 'measure-device-item measure-device-item-active' : 'measure-device-item'"
  118. @click="selectMeasureDevice(item.value)"
  119. >
  120. <view class="measure-device-left">
  121. <view >
  122. <view :class="selectedMeasureDevice === item.value ? 'measure-device-name measure-device-name-active' : 'measure-device-name'">{{ item.name }}</view>
  123. <view class="measure-device-desc">
  124. <image class="icon" :src="selectedMeasureDevice === item.value?'/static/images/pages_watch/icons/hook_pre_icon.png':'/static/images/pages_watch/icons/hook_icon.png'" mode="aspectFill"></image>
  125. 可测血压/心率、血糖、尿酸</view>
  126. </view>
  127. </view>
  128. <image class="measure-device-icon" :src="item.icon" mode="aspectFill"></image>
  129. <image class="measure-device-check" :src="selectedMeasureDevice === item.value?'/static/images/pages_watch/icons/frame_sel.png':'/static/images/pages_watch/icons/frame.png'" mode="aspectFill"></image>
  130. </view>
  131. <view class="measure-popup-btns">
  132. <view class="measure-popup-btn measure-popup-btn-cancel" @click="closeMeasurePopup">取消</view>
  133. <view class="measure-popup-btn measure-popup-btn-confirm" @click="confirmMeasureDevice">确定</view>
  134. </view>
  135. </view>
  136. </view>
  137. <view style="padding: 0 24rpx;">
  138. <!-- 健康风险 -->
  139. <view class="health-risks" v-show="deviceId&&alarmInfoList&&alarmInfoList.length>0">
  140. <view class="health-risks-title">
  141. <view class="health-risks-titlel"><text>健康</text>风险</view>
  142. <view @tap="navigateToUrl('/pages_watch/message/detail?title=手表通知')" class="health-risks-titler" >
  143. <text>更多提醒</text>
  144. <text class="health-risks-msgnum" v-show="alarmTotal > 0">{{alarmTotal}}</text>
  145. <image src="@/static/images/pages_watch/icons/arrow_right_icon.png"></image>
  146. </view>
  147. </view>
  148. <view class="health-risks-msg">
  149. <view class="health-risks-msgitem" v-for="(item,index) in alarmInfoList" :key="index">
  150. <view class="textOne health-risks-msgtxt">{{item.description}}</view>
  151. <view class="health-risks-msgbtn" @tap="navigateToUrl('/pages_watch/message/detail?title=手表通知')">{{item.type == "event"? '去就医':"去查看"}}</view>
  152. </view>
  153. </view>
  154. </view>
  155. <view class="navbox">
  156. <view class="tongue-diagnosis" @tap="navigateToUrl('/pages/user/healthRecords/index','健康档案')">
  157. <view>
  158. <view class="tongue-diagnosis-title">健康档案</view>
  159. <view>为您精准诊断</view>
  160. </view>
  161. <image src="@/static/images/pages_watch/icons/jkda.png" mode="aspectFill"></image>
  162. </view>
  163. <!-- <view class="health-report" @tap="navigateToUrl('/pages_watch/health/healthReport?selectUser='+selectUser,'健康报告')">
  164. <view>
  165. <view class="health-report-title">健康报告</view>
  166. <view>分析健康状态</view>
  167. </view>
  168. <image src="@/static/images/pages_watch/icons/health_report_icon.png" mode="aspectFill"></image>
  169. </view> -->
  170. <view class="health-report" @tap="navigateToUrl('/pages_watch/health/healthWeekReport?selectUser='+selectUser,'健康周报')">
  171. <view>
  172. <view class="health-report-title">健康周报</view>
  173. <view>分析健康状态</view>
  174. </view>
  175. <image src="@/static/images/pages_watch/icons/health_report_icon.png" mode="aspectFill"></image>
  176. </view>
  177. </view>
  178. <!-- 健康检测 -->
  179. <view class="box-title">
  180. <text class="box-title-left">健康监测</text>
  181. <view class="box-title-right">
  182. <view class="box-title-rightedit" @tap="navigateToUrl('/pages_watch/healthMonitoring/index')">
  183. <image src="@/static/images/pages_watch/icons/edit_add_icon.png"></image>
  184. <text>编辑卡片</text>
  185. </view>
  186. </view>
  187. </view>
  188. <sports ref='sports' v-if="showSports"></sports>
  189. <view class="health-monitoring">
  190. <view class="health-monitoring-item" v-for="(item,index) in indexInfo" :key="index"
  191. @tap="handleMonitoring(item)">
  192. <view class="health-monitoring-title">
  193. <view>
  194. <view class="health-monitoring-maintitle">{{item.type.type}}</view>
  195. <view>{{item.type.title}}</view>
  196. </view>
  197. <image :src="item.type.icon" mode="aspectFill"></image>
  198. </view>
  199. <view class="health-monitoring-res resnum">{{item.data || '--'}}</view>
  200. <view class="health-monitoring-time">{{item.date && item.date.substring(5,16)}}</view>
  201. </view>
  202. </view>
  203. </view>
  204. </view>
  205. </mescroll-body>
  206. </view>
  207. </template>
  208. <script>
  209. import sports from "@/pages_watch/components/sports/sports.vue";
  210. import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
  211. import mescrollBody from "@/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.vue";
  212. import permision from "@/utils/permission.js";
  213. import { getWatchUserInfo,getStatus,editUser,editMyfamily,editDevice } from "@/api/pages_watch/user.js";
  214. import { alarmInfo, queryIndexWatchData,getBatchData,getInfoByDeviceIds } from "@/api/pages_watch/index.js";
  215. import { getAppVersion } from '@/api/pages_watch/common.js';
  216. import { remove } from "lodash";
  217. // import { appCheckUdate,openDownload } from '@/utils/APPUpdate.js'
  218. const avatar="/static/images/pages_watch/images/my_heads_icon.png";
  219. export default {
  220. mixins: [MescrollMixin], // 使用mixin
  221. components: {
  222. mescrollBody,
  223. sports
  224. },
  225. props:['source'],
  226. data() {
  227. return {
  228. avatar,
  229. mescroll: null,
  230. downOption: { //下拉刷新
  231. auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
  232. },
  233. upOption: { //上拉加载
  234. auto: false, // 不自动加载
  235. page: {
  236. num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
  237. size: 10 // 每页数据的数量
  238. },
  239. noMoreSize: 5, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
  240. empty: {
  241. tip: '~ 暂无疗法 ~' // 提示
  242. // btnText: '去看看'
  243. },
  244. use:false
  245. },
  246. userboxWidth: "",
  247. scrollInto: "tab0",
  248. activeTab: 0,
  249. userDeviceList: [],
  250. // 当前的设备编号
  251. deviceId: uni.getStorageSync("deviceId"),
  252. // 新增:当前用户所有设备(包含3种类型)
  253. allDevices: [],
  254. // 当前选中的设备对象 { id, type }
  255. currentDevice: null,
  256. // 当前登录用户的信息
  257. userInfo: {},
  258. // 所有家庭成员(包括自己)
  259. userList: [{
  260. name: "自己",
  261. deviceId: [],
  262. relationship: ""
  263. }],
  264. // 选中的家庭成员
  265. selectUser: 0,
  266. // 立即绑定按钮loading
  267. btnLoading: false,
  268. // 健康风险
  269. alarmInfoList: [],
  270. // 健康风险未读提醒
  271. alarmTotal: 0,
  272. // 健康监测信息
  273. indexInfo: [
  274. {
  275. data: "",
  276. date: "",
  277. type: {
  278. type: "血糖",
  279. title: "血糖健康监测",
  280. icon: "/static/images/pages_watch/icons/blood_sugar_icon.png"
  281. }
  282. }
  283. ,{
  284. data: "",
  285. date: "",
  286. type: {
  287. type: "血压",
  288. title: "血压健康监测",
  289. icon:"/static/images/pages_watch/icons/blood_pressure_icon.png"
  290. }
  291. },{
  292. data: "",
  293. date: "",
  294. type: {
  295. type: "心率",
  296. title: "心脏健康管理",
  297. icon:"/static/images/pages_watch/icons/heart_rate_icon.png"
  298. }
  299. },{
  300. data: "",
  301. date: "",
  302. type: {
  303. type: "血氧",
  304. title: "血氧风险管控",
  305. icon:"/static/images/pages_watch/icons/blood_oxygen_icon.png"
  306. }
  307. },{
  308. data: "",
  309. date: "",
  310. type: {
  311. type: "体温",
  312. title: "体温健康监测",
  313. icon:"/static/images/pages_watch/icons/temperature_icon.png"
  314. }
  315. },{
  316. data: "",
  317. date: "",
  318. type: {
  319. type: "血脂",
  320. title: "血脂健康监测",
  321. icon:"/static/images/pages_watch/icons/blood_fat_icon.png"
  322. }
  323. },{
  324. data: "",
  325. date: "",
  326. type: {
  327. type: "尿酸",
  328. title: "尿酸健康监测",
  329. icon:"/static/images/pages_watch/icons/uric_acid_icon.png"
  330. }
  331. },{
  332. data: "",
  333. date: "",
  334. type: {
  335. type: "血酮",
  336. title: "血酮健康监测",
  337. icon:"/static/images/pages_watch/icons/blood_ketone_icon.png"
  338. }
  339. },
  340. ],
  341. isForce:false,
  342. showSports: false,
  343. defaultName: '',
  344. showMeasurePopup: false,
  345. selectedMeasureDevice: "watch",
  346. measureDeviceOptions: [
  347. {
  348. name: "智能手表",
  349. value: "watchold",
  350. icon: "/static/images/pages_watch/images/watch_img.png"
  351. },
  352. {
  353. name: "小护士血压仪",
  354. value: "nurse",
  355. icon: "/static/images/pages_watch/icons/blood_pressure_monitor_img.png"
  356. },
  357. {
  358. name: "FitCloud智能手表",
  359. value: "watch",
  360. icon: "/static/images/pages_watch/icons/smartwatch_img.png"
  361. }
  362. ]
  363. }
  364. },
  365. watch: {
  366. deviceId: {
  367. handler(oldVal,newVal) {
  368. this.getAlarmInfo()
  369. if(this.$refs.sports) {
  370. const isFamily = this.selectUser != 0
  371. this.$refs.sports.getServerData(isFamily)
  372. }
  373. },
  374. immediate: true
  375. }
  376. },
  377. created() {
  378. //#ifndef H5 || APP-PLUS
  379. this.userboxWidth = `width:${uni.getStorageSync('menuInfo').menuLeft}`
  380. //#endif
  381. uni.$on('getScanCodeInfo',(data)=>{
  382. const deviceId = data.imei || ""
  383. this.verifyDeviceId(data,deviceId)
  384. })
  385. uni.$on('scanFitWatch',(data)=>{
  386. this.initShow()
  387. })
  388. },
  389. beforeDestroy() {
  390. uni.$off("getScanCodeInfo")
  391. uni.$off("scanFitWatch")
  392. },
  393. methods: {
  394. initReady() {
  395. },
  396. initShow() {
  397. this.showSports = true
  398. if (this.$isLogin()) {
  399. const acindex = this.userDeviceList.length > 0 && this.userDeviceList.length == this.activeTab ? this.userDeviceList.length - 1 : this.activeTab
  400. this.activeTab = acindex
  401. const user = uni.getStorageSync('userInfo') ? JSON.parse(uni.getStorageSync('userInfo')): {}
  402. this.defaultName = user.nickName
  403. this.getUser()
  404. this.getAlarmInfo()
  405. this.$nextTick(()=>{
  406. const isFamily = this.selectUser != 0
  407. this.$refs.sports&&this.$refs.sports.getServerData(isFamily)
  408. })
  409. } else {
  410. setTimeout(()=>{
  411. this.mescroll.endSuccess();
  412. }, 500)
  413. }
  414. // #ifdef APP-PLUS
  415. // this.checkUpdateApp();
  416. // #endif
  417. },
  418. mescrollInit(mescroll) {
  419. this.mescroll = mescroll;
  420. },
  421. /*下拉刷新的回调 */
  422. downCallback(mescroll) {
  423. this.initShow()
  424. },
  425. onChangeSubnav(e) {
  426. this.$emit("onChangeSubnav",e)
  427. },
  428. handleGuide() {
  429. uni.navigateTo({
  430. url: "/pages_watch/index/equipment/instructions"
  431. })
  432. },
  433. openMeasurePopup() {
  434. this.showMeasurePopup = true
  435. },
  436. closeMeasurePopup() {
  437. this.showMeasurePopup = false
  438. },
  439. selectMeasureDevice(value) {
  440. this.selectedMeasureDevice = value
  441. },
  442. // 检测 // 0腕表1小护士2新表
  443. goMeasureDevice() {
  444. console.log("this.currentDevice检测===",this.currentDevice)
  445. if (this.currentDevice&&this.currentDevice.type==1) {
  446. this.selectedMeasureDevice=='nurse'
  447. const boundDevice= { deviceId: this.currentDevice.id, name: 'Bluetooth BP' }
  448. uni.setStorageSync('bound_health_device', JSON.stringify(boundDevice));
  449. uni.navigateTo({
  450. url: "/pages_bluetooth/healthMeter?selectUser="+this.selectUser+'&selectUserInfo='+ JSON.stringify(this.userList[this.selectUser])
  451. })
  452. }else if (this.currentDevice&&this.currentDevice.type==2) {
  453. this.selectedMeasureDevice=='watch'
  454. uni.setStorageSync('fitCloudWatch_mac', this.currentDevice.id);
  455. uni.navigateTo({
  456. url: "/pages_bluetooth/fitWatch?selectUser="+this.selectUser+'&selectUserInfo='+ JSON.stringify(this.userList[this.selectUser])
  457. })
  458. }
  459. },
  460. // 绑定
  461. confirmMeasureDevice() {
  462. this.showMeasurePopup = false
  463. if (this.selectedMeasureDevice=='nurse') {
  464. uni.navigateTo({
  465. url: "/pages_bluetooth/healthMeter?selectUser="+this.selectUser+'&selectUserInfo='+ JSON.stringify(this.userList[this.selectUser])
  466. })
  467. }else if (this.selectedMeasureDevice=='watch') {
  468. uni.navigateTo({
  469. url:"/pages_bluetooth/scanFitWatch?selectUser="+this.selectUser+'&selectUserInfo='+ JSON.stringify(this.userList[this.selectUser])
  470. })
  471. } else {
  472. this.handleBind()
  473. }
  474. },
  475. // swiper划动
  476. onSwiperChange(e) {
  477. this.activeTab = e.detail.current
  478. const device = this.allDevices[this.activeTab]
  479. if (device) {
  480. this.currentDevice = device;
  481. uni.setStorageSync("deviceId", device.id);
  482. uni.setStorageSync("currentDeviceType", device.type);
  483. } else {
  484. this.currentDevice = null;
  485. uni.removeStorageSync("deviceId");
  486. uni.removeStorageSync("currentDeviceType");
  487. }
  488. // 所有成员的健康监测卡片展示类别一致
  489. this.getIndexInfo(this.userInfo.monitorDataTypeOrder)
  490. if(this.$refs.sports) {
  491. const isFamily = this.selectUser != 0
  492. this.$refs.sports&&this.$refs.sports.getServerData(isFamily)
  493. }
  494. },
  495. getUser() {
  496. getWatchUserInfo({isFamily: false}).then(res => {
  497. setTimeout(()=>{
  498. this.mescroll.endSuccess();
  499. }, 500)
  500. if (res.code == 200) {
  501. this.userInfo = res.user
  502. uni.setStorageSync("userWatchInfo", JSON.stringify(res.user))
  503. let otherDevice = this.userInfo.otherDevice ? JSON.parse(this.userInfo.otherDevice) : []
  504. otherDevice = otherDevice.map(item=>({
  505. ...item,
  506. deviceId: item.deviceId ? item.deviceId.split(',') : [],
  507. xhsDeviceId: item.xhsDeviceId ? item.xhsDeviceId.split(',') : [], // type=1
  508. newXhsDeviceId: item.newXhsDeviceId ? item.newXhsDeviceId.split(',') : [], // type=2
  509. }))
  510. // const arry = [{
  511. // name: "自己",
  512. // deviceId: this.userInfo.deviceId || [],
  513. // relationship: ""
  514. // }]
  515. const arry = [{
  516. name: "自己",
  517. deviceId: this.userInfo.deviceId ? this.userInfo.deviceId.split(',') : [], // 旧手表
  518. xhsDeviceId: this.userInfo.xhsDeviceId ? this.userInfo.xhsDeviceId.split(',') : [], // type=1
  519. newXhsDeviceId: this.userInfo.newXhsDeviceId ?this.userInfo.newXhsDeviceId.split(',') : [], // type=2
  520. relationship: ""
  521. }]
  522. this.userList = arry.concat(otherDevice)
  523. if(this.$isEmpty(this.userList[this.selectUser])) {
  524. // 用户删除家人后没有选中的信息就选中第一个
  525. this.selectUser = 0
  526. this.activeTab = 0
  527. }
  528. this.mergeAllDevices()
  529. this.getInfoByDeviceIds()
  530. this.getIndexInfo(this.userInfo.monitorDataTypeOrder)
  531. }
  532. }).catch(()=>{
  533. setTimeout(()=>{
  534. this.mescroll.endSuccess();
  535. }, 500)
  536. })
  537. },
  538. // 首页轮播绑定信息
  539. getInfoByDeviceIds() {
  540. const arry = this.userList[this.selectUser]
  541. const paramdata = {
  542. params: [
  543. ...arry.deviceId.filter(id => id).map(id => ({ deviceId: id, deviceType: 0 })),
  544. ...arry.xhsDeviceId.filter(id => id).map(id => ({ deviceId: id, deviceType: 1 })),
  545. ...arry.newXhsDeviceId.filter(id => id).map(id => ({ deviceId: id, deviceType: 2 })),
  546. ],
  547. isFamily: this.selectUser != 0
  548. };
  549. // 判断是否有设备
  550. if (paramdata.params && paramdata.params.length > 0) {
  551. // 有设备
  552. getInfoByDeviceIds(paramdata).then(res=>{
  553. if(res.code == 200) {
  554. this.userDeviceList = res.data && res.data.length > 0 ? res.data : []
  555. }
  556. })
  557. } else {
  558. // 无设备
  559. this.userDeviceList = []
  560. }
  561. },
  562. // 绑定
  563. async handleBind() {
  564. if (!this.$isLogin()) {
  565. this.$showLoginPage()
  566. } else {
  567. // #ifdef APP-PLUS
  568. if(!this.$isAgreePrivacy()) {
  569. uni.showToast({title: "请同意隐私政策",icon: "none"});
  570. return;
  571. }
  572. let status = await this.checkAppCamera()
  573. if(status == 1) {
  574. uni.navigateTo({
  575. url: '/pages_watch/healthMonitoring/scanCode?typeFun=getScanCodeInfo'
  576. })
  577. }
  578. // #endif
  579. // #ifdef MP-WEIXIN
  580. this.checkWXCamera()
  581. // #endif
  582. }
  583. },
  584. scanQRCode() {
  585. uni.scanCode({
  586. success(res) {
  587. if (res.result) {
  588. // 扫描成功,处理二维码内容
  589. console.log('扫描结果:', res.scanType,res.result);
  590. const scanInfo = JSON.parse(res.result)
  591. const deviceId = scanInfo.dev_info.imei || ""
  592. this.verifyDeviceId(scanInfo.dev_info,deviceId)
  593. } else {
  594. // 扫描失败
  595. uni.showToast({
  596. title: '扫描失败',
  597. icon: 'none'
  598. });
  599. }
  600. },
  601. fail() {}
  602. });
  603. },
  604. // 验证设备
  605. verifyDeviceId(scanInfo,deviceId) {
  606. // index,0表示自己,如果是自己绑定直接调用修改用户信息接口
  607. this.btnLoading = true
  608. if(this.selectUser == 0) {
  609. editDevice(scanInfo).then(res=>{
  610. this.btnLoading = false
  611. if(res.code == 200) {
  612. uni.showToast({
  613. title: res.msg,
  614. icon: "none",
  615. position: 'top',
  616. duration: 2000
  617. })
  618. this.getUser()
  619. } else {
  620. uni.showToast({
  621. title: res.msg,
  622. icon: "none",
  623. position: 'top',
  624. duration: 2000
  625. })
  626. }
  627. }).catch(err=>{
  628. this.btnLoading = false
  629. })
  630. } else {
  631. this.bindDeviceId(deviceId);
  632. // getStatus({deviceId: deviceId}).then(res=>{
  633. // if(res.code == 200) {
  634. // if(res.data === 0 || res.data === 1 || res.data === 2 || res.data === 3) {
  635. // this.bindDeviceId(deviceId)
  636. // } else {
  637. // this.btnLoading = false
  638. // uni.showToast({
  639. // title: '绑定失败',
  640. // icon: "none",
  641. // position: 'top',
  642. // duration: 2000
  643. // })
  644. // }
  645. // }else {
  646. // this.btnLoading = false
  647. // uni.showToast({
  648. // title: res.msg,
  649. // icon: "none",
  650. // position: 'top',
  651. // duration: 2000
  652. // })
  653. // }
  654. // }).catch(err=>{
  655. // this.btnLoading = false
  656. // })
  657. }
  658. },
  659. // 绑定设备
  660. bindDeviceId(deviceId) {
  661. let param = this.userList.map((item,idx)=>({
  662. ...item,
  663. deviceId: idx == this.selectUser && !item.deviceId.includes(deviceId) ? item.deviceId.concat([deviceId]).join(','): item.deviceId.join(',')
  664. }))
  665. // 去掉自己
  666. param.splice(0,1)
  667. editMyfamily({otherDevice: JSON.stringify(param)}).then(res=>{
  668. this.btnLoading = false
  669. if(res.code == 200) {
  670. uni.showToast({
  671. title: "绑定成功",
  672. icon: "none",
  673. position: 'top',
  674. duration: 2000
  675. })
  676. this.getUser()
  677. } else {
  678. uni.showToast({
  679. title: res.msg,
  680. icon: "none",
  681. position: 'top',
  682. duration: 2000
  683. })
  684. }
  685. }).catch(err => {
  686. this.btnLoading = false
  687. console.log('err', err);
  688. })
  689. },
  690. // 切换绑定的成员信息
  691. handleUser(index) {
  692. this.selectUser = index
  693. this.activeTab = 0
  694. this.scrollInto = 'tab' + index
  695. this.mergeAllDevices()
  696. this.getInfoByDeviceIds()
  697. // 所有成员的健康监测卡片展示类别一致
  698. this.getIndexInfo(this.userInfo.monitorDataTypeOrder)
  699. },
  700. navigateToUrl(url,title) {
  701. if (this.$isLogin()) {
  702. // if(title == "健康周报" && !this.currentDevice.id) {
  703. // uni.showToast({
  704. // title: "请先绑定设备",
  705. // icon: "none"
  706. // })
  707. // return
  708. // }
  709. uni.navigateTo({
  710. url: url
  711. })
  712. } else {
  713. this.$showLoginPage()
  714. }
  715. },
  716. // 健康风险预警信息
  717. getAlarmInfo() {
  718. this.alarmInfoList = []
  719. this.alarmTotal = 0
  720. if(!this.currentDevice||!this.currentDevice.id || this.currentDevice.type!=0) {
  721. return
  722. }
  723. const param = {
  724. deviceId: this.currentDevice.id,
  725. pageNum: 1,
  726. pageSize: 3,
  727. }
  728. alarmInfo(param).then((res) => {
  729. if (res.code == 200) {
  730. this.alarmInfoList = res.rows
  731. this.alarmTotal = res.unreadNum
  732. }
  733. }).catch((err) => {});
  734. },
  735. // 健康监测信息
  736. getIndexInfo(monitorDataTypeOrder) {
  737. this.indexInfo = [
  738. {
  739. data: "",
  740. date: "",
  741. type: {
  742. type: "血糖",
  743. title: "血糖健康监测",
  744. icon: "/static/images/pages_watch/icons/blood_sugar_icon.png"
  745. }
  746. }
  747. ,{
  748. data: "",
  749. date: "",
  750. type: {
  751. type: "血压",
  752. title: "血压健康监测",
  753. icon:"/static/images/pages_watch/icons/blood_pressure_icon.png"
  754. }
  755. },{
  756. data: "",
  757. date: "",
  758. type: {
  759. type: "心率",
  760. title: "心脏健康管理",
  761. icon:"/static/images/pages_watch/icons/heart_rate_icon.png"
  762. }
  763. },{
  764. data: "",
  765. date: "",
  766. type: {
  767. type: "血氧",
  768. title: "血氧风险管控",
  769. icon:"/static/images/pages_watch/icons/blood_oxygen_icon.png"
  770. }
  771. },{
  772. data: "",
  773. date: "",
  774. type: {
  775. type: "体温",
  776. title: "体温健康监测",
  777. icon:"/static/images/pages_watch/icons/temperature_icon.png"
  778. }
  779. },{
  780. data: "",
  781. date: "",
  782. type: {
  783. type: "血脂",
  784. title: "血脂健康监测",
  785. icon:"/static/images/pages_watch/icons/blood_fat_icon.png"
  786. }
  787. },{
  788. data: "",
  789. date: "",
  790. type: {
  791. type: "尿酸",
  792. title: "尿酸健康监测",
  793. icon:"/static/images/pages_watch/icons/uric_acid_icon.png"
  794. }
  795. },{
  796. data: "",
  797. date: "",
  798. type: {
  799. type: "血酮",
  800. title: "血酮健康监测",
  801. icon:"/static/images/pages_watch/icons/blood_ketone_icon.png"
  802. }
  803. },
  804. ]
  805. if(!this.currentDevice||!this.currentDevice.id) {
  806. getBatchData({ids: monitorDataTypeOrder}).then(res => {
  807. if (res.code == 200) {
  808. this.indexInfo = res.data.map(item=>({
  809. data: "",
  810. date: "",
  811. type: item
  812. }))
  813. }
  814. }).catch((err) => {});
  815. } else {
  816. const param = {
  817. deviceId: this.currentDevice.id,
  818. type: monitorDataTypeOrder,
  819. deviceType: this.currentDevice.type,
  820. }
  821. queryIndexWatchData(param).then(res => {
  822. if (res.code == 200) {
  823. this.indexInfo = res.data
  824. }
  825. }).catch((err) => {});
  826. }
  827. },
  828. handleMonitoring(item) {
  829. if (this.$isLogin()) {
  830. if(!this.currentDevice||!this.currentDevice.id) {
  831. uni.showToast({
  832. title: "请先绑定设备",
  833. icon: "none"
  834. })
  835. return
  836. }
  837. let url = ""
  838. switch (item.type.type) {
  839. case "血糖":
  840. url = "/pages_watch/healthMonitoring/bloodSugar"
  841. break;
  842. case "血压":
  843. url = "/pages_watch/healthMonitoring/bloodPressure"
  844. break;
  845. case "心率":
  846. url = "/pages_watch/healthMonitoring/heartRate"
  847. break;
  848. case "血氧":
  849. url = "/pages_watch/healthMonitoring/bloodOxygen"
  850. break;
  851. case "睡眠":
  852. url = "/pages_watch/healthMonitoring/sleep"
  853. break;
  854. case "舌诊":
  855. url = "/pages/user/tongue/tongueList"
  856. break;
  857. case "体温":
  858. url = "/pages_watch/healthMonitoring/bodyTemperature"
  859. break;
  860. case "尿酸":
  861. url = "/pages_watch/healthMonitoring/uricAcid"
  862. break;
  863. case "压力":
  864. url = "/pages_watch/healthMonitoring/pressure"
  865. break;
  866. default:
  867. url = ""
  868. break;
  869. }
  870. if (url) {
  871. uni.navigateTo({
  872. url: url
  873. })
  874. } else {
  875. uni.showToast({
  876. title: '功能开发中...',
  877. icon: 'none',
  878. position: 'top',
  879. duration: 2000
  880. })
  881. }
  882. } else {
  883. this.$showLoginPage()
  884. }
  885. },
  886. async checkAppCamera() {
  887. let status = permision.isIOS ? await permision.requestIOS("camera") : await permision.requestAndroid("android.permission.CAMERA")
  888. if(status === null || status == 1) {
  889. status == 1
  890. } else if(status == 2) {
  891. uni.showModal({
  892. content: "相机权限已关闭",
  893. showCancel: false,
  894. success: () => {}
  895. })
  896. } else if(status.code) {
  897. uni.showModal({
  898. content: status.message
  899. })
  900. } else {
  901. uni.showModal({
  902. content: "为了使用相机功能,请点击设置开启相机权限",
  903. confirmText: "设置",
  904. success: (res) => {
  905. if(res.confirm) {
  906. permision.gotoAppSetting()
  907. }
  908. }
  909. })
  910. }
  911. return status
  912. },
  913. checkWXCamera() {
  914. const that = this
  915. uni.getSetting({
  916. success(res) {
  917. // 判断是否拥有此权限进行拉起授权 和 重新授权功能
  918. if (!res.authSetting['scope.camera']) {
  919. // 未授权此项权限 拉起授界面
  920. uni.authorize({
  921. scope: 'scope.camera',
  922. success() {
  923. // 授权成功后 就可以执行 需要权限的 操作函数了
  924. // 使用已授权的功能
  925. that.scanQRCode();
  926. },
  927. fail(err) {
  928. /*
  929. 第一次拒绝授权后必须在 uni.authorize的fail中使用
  930. uni.openSetting 才能进入设置界面打开授权按钮
  931. */
  932. uni.showToast({
  933. title: '您拒绝了授权',
  934. icon: 'none'
  935. });
  936. // 这里必须经过一个confirm 不然也会出现问题(啥问题我也不知道)
  937. uni.showModal({
  938. title: '是否重新授权相机功能',
  939. success(res) {
  940. if (res.confirm) {
  941. uni.openSetting({
  942. success() {
  943. console.log('开启权限成功');
  944. },
  945. fail() {
  946. console.log('开启权限失败');
  947. }
  948. });
  949. } else if (res.cancel) {
  950. console.log('拒绝开启开启权限');
  951. }
  952. }
  953. });
  954. }
  955. });
  956. } else {
  957. that.scanQRCode()
  958. }
  959. }
  960. });
  961. },
  962. /* 检查更新 在线更新 */
  963. checkUpdateApp:function(){
  964. // 获取manifest.json里的配置信息
  965. if(this.isForce){
  966. return;
  967. }
  968. let that=this;
  969. this.isForce=true;
  970. plus.runtime.getProperty(plus.runtime.appid, function(widgetinfo) {
  971. // console.log("App widgetinfo:"+JSON.stringify(widgetinfo));
  972. // 可以根据manifest.json里的应用名称来进行针对性的APP升级
  973. // if (widgetinfo.name == that.$qconfig.appName) { //APP名称
  974. // 获取manifest.json里的版本号
  975. let platform = uni.getSystemInfoSync().platform;
  976. let isAndroid=platform=="android";
  977. let type=isAndroid?1:2;
  978. getAppVersion(type).then(srcData => {
  979. this.isForce=false;
  980. if(srcData.code==200){
  981. let data = srcData.data;
  982. let version = widgetinfo.versionCode,//用户当前版本
  983. appVersion = data.versionCode,//升级包版本
  984. appName = widgetinfo.name, //app名称
  985. updata = data.isForce,//是否强制热更新
  986. appurl = data.url,//升级包地址
  987. intro = data.note;//升级包提示
  988. //如果用户版本号小于升级包版本号,先升级
  989. let afterVer=that.$qconfig.isAppStore?data.appStoreUpdate:true;
  990. // let afterVer= true;
  991. if(data && (version < appVersion) && afterVer){
  992. uni.showModal({
  993. title:"更新提示",
  994. confirmText:"立即升级",
  995. content:intro,
  996. cancelText:'确定',
  997. confirmText:'取消',
  998. success: (res) => {
  999. if (res.cancel) {
  1000. openDownload(srcData.data);
  1001. } else if (res.confirm) {
  1002. if(updata==1){
  1003. console.log('用户点击取消');
  1004. uni.showToast({
  1005. title:"请先升级APP版本",
  1006. icon:"none",
  1007. duration:2000
  1008. })
  1009. //退出app
  1010. setTimeout(function(){
  1011. plus.runtime.quit();
  1012. },2000)
  1013. }
  1014. }
  1015. },
  1016. fail: () => {
  1017. uni.hideLoading();
  1018. }
  1019. })
  1020. }
  1021. }
  1022. },
  1023. rej => {}
  1024. ).catch(()=>{
  1025. //联网失败, 结束加载
  1026. // this.mescroll.endErr();
  1027. });
  1028. // }
  1029. });
  1030. },
  1031. // 合并3种设备到统一列表
  1032. mergeAllDevices() {
  1033. const user = this.userList[this.selectUser] || {}
  1034. let list = []
  1035. // 旧手表 type=0
  1036. if (user.deviceId && user.deviceId.length) {
  1037. list = list.concat(user.deviceId.map(id => ({ id, type: 0 })))
  1038. }
  1039. // xhsDeviceId type=1
  1040. if (user.xhsDeviceId && user.xhsDeviceId.length) {
  1041. list = list.concat(user.xhsDeviceId.map(id => ({ id, type: 1 })))
  1042. }
  1043. // newXhsDeviceId type=2
  1044. if (user.newXhsDeviceId && user.newXhsDeviceId.length) {
  1045. list = list.concat(user.newXhsDeviceId.map(id => ({ id, type: 2 })))
  1046. }
  1047. this.allDevices = list
  1048. this.currentDevice = list[this.activeTab] ?? '';
  1049. this.currentDevice
  1050. ? (uni.setStorageSync('deviceId', this.currentDevice.id), uni.setStorageSync('currentDeviceType', this.currentDevice.type))
  1051. : (uni.removeStorageSync('deviceId'), uni.removeStorageSync('currentDeviceType'));
  1052. },
  1053. }
  1054. }
  1055. </script>
  1056. <style lang="scss" scoped>
  1057. @mixin u-flex($flexD, $alignI, $justifyC) {
  1058. display: flex;
  1059. flex-direction: $flexD;
  1060. align-items: $alignI;
  1061. justify-content: $justifyC;
  1062. }
  1063. .ceshi{
  1064. width:100;
  1065. height: 96rpx;
  1066. background: linear-gradient( 90deg, #F8551F 0%, #FF9501 100%);
  1067. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1068. display: flex;
  1069. align-items: center;
  1070. justify-content:center;
  1071. margin: 20rpx 24rpx 0;
  1072. image{
  1073. width: 40rpx;
  1074. height: 40rpx;
  1075. }
  1076. .ceshi-text{
  1077. margin-left: 10rpx;
  1078. font-family: PingFang SC, PingFang SC;
  1079. font-weight: 600;
  1080. font-size: 32rpx;
  1081. color: #FFFFFF;
  1082. }
  1083. }
  1084. .measure-popup-mask {
  1085. position: fixed;
  1086. left: 0;
  1087. right: 0;
  1088. top: 0;
  1089. bottom: 0;
  1090. background: rgba(0, 0, 0, 0.45);
  1091. z-index: 10000;
  1092. display: flex;
  1093. align-items: center;
  1094. justify-content: center;
  1095. padding: 0 40rpx;
  1096. box-sizing: border-box;
  1097. }
  1098. .measure-popup {
  1099. width: 100%;
  1100. max-width: 670rpx;
  1101. background: linear-gradient( 180deg, #FFF0E4 0%, #FFFFFF 16.35%, #FFFFFF 100%);
  1102. border-radius: 24rpx 24rpx 24rpx 24rpx;
  1103. padding: 40rpx 38rpx;
  1104. box-sizing: border-box;
  1105. }
  1106. .measure-popup-title {
  1107. text-align: center;
  1108. font-weight: 600;
  1109. font-size: 48rpx;
  1110. color: #222222;
  1111. margin-bottom: 40rpx;
  1112. }
  1113. .measure-device-item {
  1114. height: 160rpx;
  1115. background: #F5F5F7;
  1116. border-radius: 24rpx;
  1117. border: 2rpx solid transparent;
  1118. padding: 28rpx 32rpx;
  1119. margin-bottom: 24rpx;
  1120. box-sizing: border-box;
  1121. display: flex;
  1122. align-items: center;
  1123. justify-content: space-between;
  1124. position: relative;
  1125. }
  1126. .measure-device-item-active {
  1127. background: #FFF6EF;
  1128. border-color: #FF8A00;
  1129. }
  1130. .measure-device-left {
  1131. display: flex;
  1132. align-items: center;
  1133. .icon{
  1134. width: 24rpx;
  1135. height: 24rpx;
  1136. margin-right: 6rpx;
  1137. }
  1138. }
  1139. .measure-device-icon {
  1140. width: 96rpx;
  1141. height: 96rpx;
  1142. // margin-right: 20rpx;
  1143. }
  1144. .measure-device-name {
  1145. font-family: PingFang SC, PingFang SC;
  1146. font-weight: 600;
  1147. font-size: 32rpx;
  1148. color: #222222;
  1149. margin-bottom: 20rpx;
  1150. }
  1151. .measure-device-name-active {
  1152. color: #FF7A00;
  1153. }
  1154. .measure-device-desc {
  1155. font-family: PingFang SC, PingFang SC;
  1156. font-weight: 400;
  1157. font-size: 22rpx;
  1158. color: #757575;
  1159. display: flex;
  1160. align-items: center;
  1161. }
  1162. .measure-device-check {
  1163. width: 44rpx;
  1164. height: 40rpx;
  1165. flex-shrink: 0;
  1166. position: absolute;
  1167. right: 0;
  1168. bottom: 0;
  1169. }
  1170. .measure-device-check-active {
  1171. background: linear-gradient(90deg, #FF9D25 0%, #FF7A00 100%);
  1172. }
  1173. .measure-popup-btns {
  1174. display: flex;
  1175. align-items: center;
  1176. justify-content: space-between;
  1177. margin-top: 24rpx;
  1178. }
  1179. .measure-popup-btn {
  1180. width: 263rpx;
  1181. height: 92rpx;
  1182. line-height: 93rpx;
  1183. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1184. font-family: PingFang SC, PingFang SC;
  1185. font-weight: 500;
  1186. font-size: 32rpx;
  1187. color: #FFFFFF;
  1188. text-align: center;
  1189. }
  1190. .measure-popup-btn-cancel {
  1191. background: #EAEAEA;
  1192. color: #9B9B9B;
  1193. }
  1194. .measure-popup-btn-confirm {
  1195. background: #FF7700;
  1196. color: #FFFFFF;
  1197. }
  1198. .indexSubsection {
  1199. height: 88rpx;
  1200. display: flex;
  1201. align-items: center;
  1202. justify-content: center;
  1203. }
  1204. .watch-course {
  1205. background: none !important;
  1206. padding-top: 44px !important;
  1207. }
  1208. .watch-con {
  1209. padding-top: calc(var(--status-bar-height) + 44px + 88rpx);
  1210. padding-bottom: var(--window-bottom);
  1211. min-height: 100vh;
  1212. box-sizing: border-box;
  1213. background: linear-gradient(180deg, #FDF0DA 0%, #FDF4EB 75%, #F5F7FA 100%) no-repeat;
  1214. background-size: 100% 504rpx;
  1215. color: #222222;
  1216. &-body {
  1217. padding: 0 0 32rpx 0;
  1218. }
  1219. .userboxTop {
  1220. top: 0 !important;
  1221. }
  1222. .userbox {
  1223. width: 100%;
  1224. overflow: hidden;
  1225. position: fixed;
  1226. z-index: 9999;
  1227. left: 0;
  1228. top: calc(var(--status-bar-height) + 44px);
  1229. // .home_top_bg {
  1230. // width: 100%;
  1231. // position: absolute !important;
  1232. // left: 0;
  1233. // top: -44px;
  1234. // z-index: 0;
  1235. // }
  1236. .home_top_bg {
  1237. width: 100%;
  1238. position: absolute !important;
  1239. left: 0;
  1240. top: 0;
  1241. z-index: 0;
  1242. }
  1243. }
  1244. .tab-bar {
  1245. width: 100%;
  1246. flex-direction: row;
  1247. white-space: nowrap;
  1248. }
  1249. .user {
  1250. width: 100%;
  1251. height: 88rpx;
  1252. padding: 0 24rpx;
  1253. box-sizing: border-box;
  1254. @include u-flex(row, center, space-between);
  1255. font-family: PingFang SC, PingFang SC;
  1256. font-weight: 500;
  1257. color: #222222;
  1258. overflow: hidden;
  1259. position: relative;
  1260. &-navbox {
  1261. flex: 1;
  1262. margin-right: 20rpx;
  1263. overflow: hidden;
  1264. @include u-flex(row, center, flex-start);
  1265. font-size: 32rpx;
  1266. &-line {
  1267. display: inherit;
  1268. margin-top: 16rpx;
  1269. image {
  1270. width: 40rpx;
  1271. height: 12rpx;
  1272. }
  1273. }
  1274. }
  1275. &-navitem {
  1276. min-width: 90rpx;
  1277. padding: 0 20rpx;
  1278. box-sizing: border-box;
  1279. text-align: center;
  1280. @include u-flex(column, center, center);
  1281. display: inline-flex;
  1282. flex-wrap: nowrap;
  1283. &-active {
  1284. font-size: 40rpx;
  1285. color: #FF7700;
  1286. }
  1287. }
  1288. &-family {
  1289. flex-shrink: 0;
  1290. font-weight: 400;
  1291. font-size: 20rpx;
  1292. text-align: center;
  1293. image {
  1294. width: 32rpx;
  1295. height: 32rpx;
  1296. }
  1297. }
  1298. }
  1299. .banner {
  1300. height: 312rpx;
  1301. padding: 32rpx;
  1302. margin: 24rpx 24rpx 0 24rpx;
  1303. overflow: hidden;
  1304. background: linear-gradient(180deg, #FBA457 0%, #FE7040 100%);
  1305. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1306. font-family: PingFang SC, PingFang SC;
  1307. color: #FFFFFF;
  1308. box-sizing: border-box;
  1309. position: relative;
  1310. .banner_bg {
  1311. width: 414rpx;
  1312. height: 312rpx;
  1313. position: absolute !important;
  1314. right: 0;
  1315. top: 0;
  1316. }
  1317. .banner_bg_watch {
  1318. width: 264rpx;
  1319. height: 307rpx;
  1320. position: absolute !important;
  1321. right: 0;
  1322. top: 0;
  1323. }
  1324. .status_text {
  1325. padding-left: 28rpx;
  1326. line-height: 60rpx;
  1327. font-weight: 600;
  1328. font-size: 48rpx;
  1329. position: relative;
  1330. &::after {
  1331. content: "";
  1332. width: 8rpx;
  1333. height: 40rpx;
  1334. background: #FFFFFF;
  1335. border-radius: 4rpx 4rpx 4rpx 4rpx;
  1336. position: absolute;
  1337. left: 0;
  1338. top: 50%;
  1339. transform: translateY(-50%);
  1340. }
  1341. }
  1342. .status_desc {
  1343. width: 264rpx;
  1344. padding-top: 20rpx;
  1345. padding-bottom: 24rpx;
  1346. font-weight: 400;
  1347. font-size: 24rpx;
  1348. line-height: 36rpx;
  1349. }
  1350. .status_btnbox{
  1351. @include u-flex(row, center, flex-start);
  1352. }
  1353. .binding_btn {
  1354. background: #FFFFFF;
  1355. color: #FF7700;
  1356. margin-right: 16rpx !important;
  1357. }
  1358. }
  1359. .status_btn {
  1360. width: 200rpx;
  1361. height: 64rpx;
  1362. line-height: 64rpx;
  1363. border-radius: 36rpx 36rpx 36rpx 36rpx;
  1364. @include u-flex(row, center, center);
  1365. display: inline-flex;
  1366. font-weight: 500;
  1367. font-size: 26rpx;
  1368. border: 2rpx solid #FFFFFF;
  1369. box-sizing: border-box;
  1370. margin: 0;
  1371. &::after {
  1372. border: none;
  1373. }
  1374. image {
  1375. width: 32rpx;
  1376. height: 32rpx;
  1377. }
  1378. }
  1379. .demonstrate_btn {
  1380. image {
  1381. width: 48rpx !important;
  1382. height: 48rpx !important;
  1383. }
  1384. }
  1385. .swiper-item {
  1386. padding: 0 12rpx;
  1387. box-sizing: border-box;
  1388. height: 350rpx;
  1389. @include u-flex(row, center, flex-start);
  1390. }
  1391. .bindbox{
  1392. &-banner{
  1393. width: 100%;
  1394. min-width: 624rpx;
  1395. padding: 0 24rpx;
  1396. box-sizing: border-box;
  1397. @include u-flex(column, inherit, center);
  1398. background: linear-gradient( 180deg, #FBA457 0%, #FE7040 100%);
  1399. box-shadow: 0rpx 0rpx 14rpx 6rpx rgba(236,115,69,0.2);
  1400. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1401. overflow: hidden;
  1402. font-family: PingFang SC, PingFang SC;
  1403. font-weight: 400;
  1404. font-size: 24rpx;
  1405. color: #FFFFFF;
  1406. }
  1407. &-head {
  1408. width: 100%;
  1409. @include u-flex(row, center, flex-start);
  1410. }
  1411. &-img {
  1412. flex-shrink: 0;
  1413. width: 88rpx;
  1414. height: 88rpx;
  1415. padding: 8rpx;
  1416. box-sizing: border-box;
  1417. margin-right: 20rpx;
  1418. background: #FEF2E0;
  1419. border-radius: 50%;
  1420. }
  1421. &-headr {
  1422. flex: 1;
  1423. @include u-flex(row, center, space-between);
  1424. overflow: hidden;
  1425. image {
  1426. width: 48rpx;
  1427. height: 48rpx;
  1428. }
  1429. }
  1430. &-title {
  1431. font-weight: 600;
  1432. font-size: 36rpx;
  1433. line-height: 60rpx;
  1434. }
  1435. &-info {
  1436. width: 100%;
  1437. margin-top: 46rpx;
  1438. @include u-flex(row, center, space-between);
  1439. .question_mark_icon {
  1440. width: 24rpx;
  1441. height: 24rpx;
  1442. margin-left: 10rpx;
  1443. }
  1444. }
  1445. &-info-l {
  1446. flex: 1;
  1447. @include u-flex(row, center, flex-start);
  1448. }
  1449. &-info-desc {
  1450. margin-top: 18rpx;
  1451. font-weight: 500;
  1452. font-size: 28rpx;
  1453. color: #FFFFFF;
  1454. @include u-flex(row, center, center);
  1455. }
  1456. &-info-name {
  1457. text-align: left;
  1458. padding-right: 30rpx;
  1459. }
  1460. &-info-status {
  1461. border-left: 2rpx solid rgba(255,255,255,0.2);
  1462. padding-left: 30rpx;
  1463. text-align: center;
  1464. }
  1465. &-info-r {
  1466. width: 192rpx;
  1467. height: 64rpx;
  1468. background: #FFFFFF;
  1469. border-radius: 32rpx 32rpx 32rpx 32rpx;
  1470. font-family: PingFang SC, PingFang SC;
  1471. font-weight: 500;
  1472. font-size: 26rpx;
  1473. color: #FF7700;
  1474. line-height: 64rpx;
  1475. text-align: center;
  1476. @include u-flex(row, center, center);
  1477. image {
  1478. height: 32rpx;
  1479. width: 32rpx;
  1480. }
  1481. }
  1482. }
  1483. .add-device {
  1484. width: 308rpx;
  1485. height: 308rpx;
  1486. background: #FFFFFF;
  1487. box-shadow: 0rpx 0rpx 14rpx 8rpx rgba(236,115,69,0.1);
  1488. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1489. @include u-flex(column, center, center);
  1490. font-family: PingFang SC, PingFang SC;
  1491. font-weight: 400;
  1492. font-size: 28rpx;
  1493. color: #757575;
  1494. .add-device-icon {
  1495. width: 144rpx;
  1496. height: 144rpx;
  1497. margin-bottom: 16rpx;
  1498. border-radius: 32rpx 32rpx 32rpx 32rpx;
  1499. border: 4rpx dashed #FF7700;
  1500. @include u-flex(column, center, center);
  1501. image {
  1502. width: 56rpx;
  1503. height: 56rpx;
  1504. }
  1505. }
  1506. }
  1507. .health-risks {
  1508. margin-top: 20rpx;
  1509. padding: 4rpx 16rpx 16rpx 16rpx;
  1510. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1511. box-sizing: border-box;
  1512. background: linear-gradient(180deg, #FFF1ED 0%, #FFFFFF 100%);
  1513. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1514. border: 2rpx solid;
  1515. border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 1)) 2 2;
  1516. &-title {
  1517. padding: 20rpx 12rpx;
  1518. @include u-flex(row, center, space-between);
  1519. font-weight: 400;
  1520. font-size: 24rpx;
  1521. color: #757575;
  1522. }
  1523. &-titlel {
  1524. font-weight: 600;
  1525. font-size: 32rpx;
  1526. color: #333333;
  1527. text {
  1528. color: #FF7700;
  1529. }
  1530. }
  1531. &-titler {
  1532. @include u-flex(row, center, flex-start);
  1533. image {
  1534. width: 32rpx;
  1535. height: 32rpx;
  1536. flex-shrink: 0;
  1537. }
  1538. }
  1539. &-msgnum {
  1540. min-width: 46rpx;
  1541. height: 28rpx;
  1542. padding: 0 12rpx;
  1543. line-height: 28rpx;
  1544. box-sizing: border-box;
  1545. background: linear-gradient(136deg, #EE7D4E 0%, #E86235 100%);
  1546. border-radius: 14rpx 14rpx 14rpx 14rpx;
  1547. font-weight: 400;
  1548. font-size: 20rpx;
  1549. color: #FFFFFF;
  1550. margin: 0 8rpx;
  1551. flex-shrink: 0;
  1552. text-align: center;
  1553. }
  1554. &-msg {
  1555. padding: 20rpx 16rpx 0 16rpx;
  1556. background: #FFFFFF;
  1557. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1558. color: #333333;
  1559. font-weight: 400;
  1560. font-size: 26rpx;
  1561. }
  1562. &-msgitem {
  1563. margin-bottom: 20rpx;
  1564. @include u-flex(row, center, space-between);
  1565. }
  1566. &-msgtxt {
  1567. line-height: 52rpx;
  1568. padding-left: 26rpx;
  1569. position: relative;
  1570. &::before {
  1571. content: "";
  1572. width: 8rpx;
  1573. height: 8rpx;
  1574. background: rgba(255, 119, 0, 0.5);
  1575. border-radius: 50%;
  1576. position: absolute;
  1577. left: 0;
  1578. top: 50%;
  1579. transform: translateY(-50%);
  1580. }
  1581. }
  1582. &-msgbtn {
  1583. min-width: 108rpx;
  1584. height: 48rpx;
  1585. padding: 0 24rpx;
  1586. margin-left: 50rpx;
  1587. box-sizing: border-box;
  1588. line-height: 48rpx;
  1589. background: #FCF0E7;
  1590. border-radius: 26rpx 26rpx 26rpx 26rpx;
  1591. flex-shrink: 0;
  1592. font-weight: 500;
  1593. font-size: 20rpx;
  1594. color: #FF7700;
  1595. }
  1596. }
  1597. .navbox {
  1598. @include u-flex(row, center, flex-start);
  1599. // gap: 16rpx;
  1600. margin-top: 20rpx;
  1601. .tongue-diagnosis {
  1602. flex: 1;
  1603. height: 160rpx;
  1604. margin-right: 16rpx;
  1605. background: linear-gradient(180deg, #FBE2B0 0%, #FFCA80 100%);
  1606. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1607. font-weight: 400;
  1608. font-size: 26rpx;
  1609. color: #D36208;
  1610. padding: 0 24rpx;
  1611. @include u-flex(row, center, space-between);
  1612. image {
  1613. width: 97rpx;
  1614. height: 96rpx;
  1615. }
  1616. &-title {
  1617. font-weight: 600;
  1618. font-size: 32rpx;
  1619. margin-bottom: 10rpx;
  1620. }
  1621. }
  1622. .health-report {
  1623. flex: 1;
  1624. height: 160rpx;
  1625. padding: 0 24rpx;
  1626. background: linear-gradient(180deg, #D6E3FF 0%, #95AFFF 100%);
  1627. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1628. font-weight: 400;
  1629. font-size: 26rpx;
  1630. color: #455FAD;
  1631. @include u-flex(row, center, space-between);
  1632. image {
  1633. width: 99rpx;
  1634. height: 105rpx;
  1635. }
  1636. &-title {
  1637. font-weight: 600;
  1638. font-size: 32rpx;
  1639. margin-bottom: 10rpx;
  1640. }
  1641. }
  1642. }
  1643. .box-title {
  1644. height: 80rpx;
  1645. margin-top: 20rpx;
  1646. line-height: 80rpx;
  1647. font-weight: 500;
  1648. font-size: 36rpx;
  1649. color: #222222;
  1650. @include u-flex(row, center, space-between);
  1651. &-right {
  1652. flex-shrink: 0;
  1653. }
  1654. .arrow_right_icon {
  1655. font-weight: 400;
  1656. font-size: 24rpx;
  1657. color: #757575;
  1658. @include u-flex(row, center, flex-start);
  1659. image {
  1660. height: 48rpx;
  1661. width: 48rpx;
  1662. }
  1663. }
  1664. &-rightedit {
  1665. min-width: 192rpx;
  1666. height: 64rpx;
  1667. padding: 0 32rpx;
  1668. box-sizing: border-box;
  1669. background: #FFFFFF;
  1670. border-radius: 32rpx 32rpx 32rpx 32rpx;
  1671. font-weight: 500;
  1672. font-size: 24rpx;
  1673. color: #757575;
  1674. @include u-flex(row, center, center);
  1675. image {
  1676. width: 24rpx;
  1677. height: 24rpx;
  1678. margin-right: 4rpx;
  1679. }
  1680. }
  1681. }
  1682. .health-monitoring {
  1683. @include u-flex(row, center, flex-start);
  1684. flex-wrap: wrap;
  1685. // gap: 16rpx;
  1686. margin-bottom: -16rpx;
  1687. margin-right: -16rpx;
  1688. &-item {
  1689. width: 343rpx;
  1690. min-height: 264rpx;
  1691. margin: 0 16rpx 16rpx 0;
  1692. overflow: hidden;
  1693. background: #FFFFFF;
  1694. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1695. padding: 24rpx 34rpx 24rpx 24rpx;
  1696. box-sizing: border-box;
  1697. }
  1698. &-maintitle {
  1699. margin-bottom: 4rpx;
  1700. font-weight: 500;
  1701. font-size: 30rpx;
  1702. color: #333333;
  1703. }
  1704. &-title {
  1705. @include u-flex(row, center, space-between);
  1706. font-weight: 400;
  1707. font-size: 24rpx;
  1708. color: #999999;
  1709. image {
  1710. width: 72rpx;
  1711. height: 72rpx;
  1712. flex-shrink: 0;
  1713. }
  1714. }
  1715. .resnum {
  1716. font-family: DIN, DIN;
  1717. font-weight: 500;
  1718. font-size: 64rpx;
  1719. }
  1720. &-res {
  1721. height: 78rpx;
  1722. margin: 20rpx 0 6rpx;
  1723. font-family: PingFang SC, PingFang SC;
  1724. font-weight: 600;
  1725. font-size: 48rpx;
  1726. color: #333333;
  1727. }
  1728. &-time {
  1729. font-weight: 400;
  1730. font-size: 22rpx;
  1731. color: #999999;
  1732. }
  1733. }
  1734. }
  1735. </style>