健康同学微信公众号h5项目
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

1945 lignes
51KB

  1. <!-- -->
  2. <template>
  3. <div class="pageContent insight">
  4. <div class="periodNav">
  5. <div class="periodItem week" :class="{ active: active == 0 }" @click="active = 0">周</div>
  6. <div class="periodItem month" :class="{ active: active == 1 }" @click="active = 1">月</div>
  7. </div>
  8. <DateSwitch :dateType="active == 0 ? 'week' : 'month'" @updateDate="updateDate" v-if="false"></DateSwitch>
  9. <!-- <div class="periodSwitch">
  10. <div class="arrow arrowLeft">
  11. <van-icon name="arrow-left"></van-icon>
  12. </div>
  13. <div class="timearea">2023-11-15~2023-11-22</div>
  14. <div class="arrow arrowRight">
  15. <van-icon name="arrow"></van-icon>
  16. </div>
  17. </div> -->
  18. <div class="label">
  19. <div class="left">情绪感知</div>
  20. <div class="right">
  21. <span @click="onRouterTo('emo')">详情 ></span>
  22. </div>
  23. </div>
  24. <div class="periodNav">
  25. <div class="periodItem minPeriodItem" :class="{ active: emotionActive == index }" v-for="(item, index) in psyList"
  26. :key="index" @click="onEmotionClick(item, index)">
  27. <span>{{ item.name }}</span>
  28. </div>
  29. </div>
  30. <div class="echart-container">
  31. <div class="echart">
  32. <EchartBox echartId="emotionChart" :outTitle="emoLegend.outTitle" height="200" width="200" :legend="emoLegend"
  33. :options="defaultOptions"></EchartBox>
  34. </div>
  35. </div>
  36. <div class="grid">
  37. <div class="gridItem" :style="`background:${item.color};`" v-for="(item, index) in emotionList" :key="index">
  38. <div class="time">
  39. <span class="number">{{ item.days }}</span>
  40. <span>天</span>
  41. </div>
  42. <div class="title">{{ item.text }}</div>
  43. </div>
  44. </div>
  45. <div class="label">
  46. <div class="left">体征感知</div>
  47. <div class="right">
  48. <span @click="onRouterTo('signs')">详情 ></span>
  49. </div>
  50. </div>
  51. <div class="periodNav">
  52. <div class="periodItem minPeriodItem" :class="{ active: signActive == index }" v-for="(item, index) in signList"
  53. :key="index" @click="onSignClick(index, item)">
  54. <span>{{ item.name }}</span>
  55. </div>
  56. </div>
  57. <!-- bmi显示/输入 TODO待接口-->
  58. <div class="bmi" v-show="signActive == 2">
  59. <p>身高:<span>{{ bmi.height }}</span>cm</p>
  60. <p>体重:<span>{{ bmi.weight }}</span>kg</p>
  61. <p>BMI:<span>{{ bmi.value }}</span></p>
  62. <p>{{ bmi.result }}</p>
  63. <van-button size="mini" @click="onUpdateBmi">更新</van-button>
  64. </div>
  65. <van-dialog v-model="bmi.isBmiShow" :title="dialogTitle" confirm-button-color="#179b3b" cancel-button-text="关闭"
  66. show-cancel-button @confirm="onConfirmBmi" @cancel="onCancelBmi">
  67. <div class="bmiDialog">
  68. <van-cell-group>
  69. <van-field v-model="bmi.height" label="身高:" type="number" maxlength="3" placeholder="请输入身高" border
  70. input-align="left" />
  71. <van-field v-model="bmi.weight" label="体重:" type="number" maxlength="3" placeholder="请输入体重" border
  72. input-align="left" />
  73. </van-cell-group>
  74. </div>
  75. </van-dialog>
  76. <div class="title-out">
  77. <span>{{ signsChartTitle }}</span>
  78. </div>
  79. <div class="ChatBox" :class="{ hiddenChart: signActive == 2 }">
  80. <div class="legendBox minLegendBox">
  81. <div class="legend">
  82. <div class="legendItem" :class="item.type" v-for="(item, index) in signGrid" :key="index">
  83. <span>{{ item.name }}</span>
  84. </div>
  85. </div>
  86. </div>
  87. <div class="Chat signChart" id="signChart"></div>
  88. </div>
  89. <div class="grid">
  90. <div class="gridItem" v-show="signActive != 2" :style="`background:${item.color};`"
  91. v-for="(item, index) in signDaysList" :key="index">
  92. <div class="time">
  93. <span class="number">{{ item.day }}</span>
  94. <span>天</span>
  95. </div>
  96. <div class="title">{{ item.name }}</div>
  97. </div>
  98. </div>
  99. <div class="ChatBox minChartBox" :class="{ hiddenChart: signActive != 2 }">
  100. <h4>运动步数</h4>
  101. <div class="Chat stepChart" id="stepChart"></div>
  102. <div class="result">
  103. <div class="wrapBox">
  104. <div class="text">
  105. <div class="left">
  106. <p>总步数:{{ stepsData.total || '--' }}</p>
  107. </div>
  108. <div class="right">
  109. <img :src="stepsData.compare > 0 ? upImg : downImg" alt="" />
  110. <span>{{ Math.abs(stepsData.compare) || '--' }}</span>
  111. </div>
  112. </div>
  113. <div class="text">
  114. <div class="left">
  115. <p>平均步数:{{ stepsData.avg || '--' }}</p>
  116. </div>
  117. <div class="right">
  118. <img :src="stepsData.compare > 0 ? upImg : downImg" alt="" />
  119. <span>{{ Math.abs(stepsData.compare) || '--' }}</span>
  120. </div>
  121. </div>
  122. </div>
  123. </div>
  124. </div>
  125. <div class="ChatBox minChartBox" :class="{ hiddenChart: signActive != 2 }">
  126. <h4>热量消耗</h4>
  127. <div class="Chat calorieChart" id="calorieChart"></div>
  128. <div class="result">
  129. <div class="wrapBox">
  130. <div class="text">
  131. <div class="left">
  132. <p>总消耗:{{ calorieData.total || '--' }}</p>
  133. </div>
  134. <div class="right">
  135. <img :src="calorieData.compare > 0 ? upImg : downImg" alt="" />
  136. <span>{{ Math.abs(calorieData.compare) || '--' }}</span>
  137. </div>
  138. </div>
  139. <div class="text">
  140. <div class="left">
  141. <p>平均消耗:{{ calorieData.avg || '--' }}</p>
  142. </div>
  143. <div class="right">
  144. <img :src="calorieData.compare > 0 ? upImg : downImg" alt="" />
  145. <span>{{ Math.abs(calorieData.compare) || '--' }}</span>
  146. </div>
  147. </div>
  148. </div>
  149. </div>
  150. </div>
  151. </div>
  152. </template>
  153. <script>
  154. import DateSwitch from '@/components/DateSwitch.vue';
  155. import { format, startOfMonth, endOfMonth } from 'date-fns';
  156. import ToastService from '@/services/toast-service';
  157. import DialogService from '@/services/dialog-service';
  158. import { /* EmotionModel, */ PsyBaseUrl } from '@/config/models';
  159. import axios from 'axios';
  160. import EchartBox from '@/components/EchartBox';
  161. import APIHealthUser from '@/api/health-user';
  162. import APIAlarm from '@/api/core';
  163. import { isNull } from '@/services/utils-service';
  164. export default {
  165. components: {
  166. DateSwitch,
  167. EchartBox
  168. },
  169. data() {
  170. return {
  171. active: 0,
  172. emotionActive: 0,
  173. signActive: 0,
  174. emotionChart: null,
  175. signChart: null,
  176. stepChart: null,
  177. calorieChart: null,
  178. psyList: [
  179. {
  180. name: '疲劳',
  181. type: 3
  182. },
  183. {
  184. name: '压力',
  185. type: 1
  186. },
  187. {
  188. name: '抑郁',
  189. type: 2
  190. }
  191. ],
  192. degreeList: [
  193. {
  194. name: '无',
  195. type: 'not',
  196. color: '#179B3B'
  197. },
  198. {
  199. name: '轻度',
  200. type: 'mild',
  201. color: '#2EA7E0'
  202. },
  203. {
  204. name: '中度',
  205. type: 'moderate',
  206. color: '#8DC21F'
  207. },
  208. {
  209. name: '重度',
  210. type: 'severe',
  211. color: '#FF5F8B'
  212. }
  213. ],
  214. signList: [
  215. {
  216. grid: 'heartRateList',
  217. name: '心率',
  218. label: 'heartrate'
  219. },
  220. {
  221. grid: 'temperatureList',
  222. name: '体温',
  223. label: 'temperature'
  224. },
  225. {
  226. grid: null,
  227. name: '运动',
  228. label: 'step'
  229. }
  230. ],
  231. heartRateList: [
  232. {
  233. name: '正常',
  234. type: 'moderate',
  235. color: '#179B3B'
  236. },
  237. {
  238. name: '偏高',
  239. type: 'severe',
  240. color: '#FF5F8B'
  241. },
  242. {
  243. name: '偏低',
  244. type: 'mild',
  245. color: '#2EA7E0'
  246. }
  247. ],
  248. temperatureList: [
  249. {
  250. name: '正常',
  251. type: 'moderate',
  252. color: '#179B3B'
  253. },
  254. {
  255. name: '发烧',
  256. type: 'severe',
  257. color: '#FF5F8B'
  258. }
  259. ],
  260. bmi: {
  261. height: '',
  262. weight: '',
  263. value: '',
  264. result: '',
  265. isBmiShow: false,
  266. curHeight: '', //当前的身高
  267. curWeight: '',//当前的体重
  268. },
  269. upImg: require('@/assets/today/icons/up.png'),
  270. downImg: require('@/assets/today/icons/down.png'),
  271. date: '',
  272. monthDate: {},
  273. dateList: [],
  274. emotionData: [],
  275. xAxisData: [], //图表x轴展示的数据
  276. echarts: null,
  277. signCurrent: 0,
  278. emoName: '',
  279. result: '',
  280. // 需要高亮的日期数组
  281. highlightDates: [],
  282. // 日历 默认最小可选择日期,默认为当前时间
  283. maxDate: new Date(this.$dayjs().hour(0).minute(0).second(0).format()),
  284. // 默认日历日期时间
  285. defaultDate: new Date(this.$dayjs().hour(0).minute(0).second(0).format()),
  286. // 7天和30天最大数据列表
  287. weekAndMonData: [],
  288. weekList: [],
  289. startDate: '', //接口需要的开始时间
  290. endDate: '', //接口需要的结束时间
  291. currentEmoName: '', //当前情绪名称
  292. emotionList: [],
  293. weekAndMonthSeries: null,
  294. emoType: '1',
  295. signData: {},
  296. signDaysList: [],
  297. stepsData: {},
  298. calorieData: {},
  299. personData: null
  300. };
  301. },
  302. created() {
  303. this.emoName = this.psyList[this.emotionActive].name;
  304. this.initEchartText();
  305. /* this.getPsychologiclData('', '2023-11-21', '2023-12-21'); */
  306. },
  307. async mounted() {
  308. const isExistToken = await this.getAuth();
  309. if (isExistToken) {
  310. this.initData();
  311. this.getPsychologiclData();
  312. this.getPersonInfo();
  313. }
  314. },
  315. watch: {
  316. active(val) {
  317. console.log(val);
  318. console.log('最近7天开始时间和结束时间', this.$getRangeStartAndEnd(7));
  319. let days = val === 0 ? 7 : 30;
  320. let startAndEndDate = this.$getRangeStartAndEnd(days);
  321. let date = {
  322. start: this.$dayjs(startAndEndDate.start).format('YYYY-MM-DD'),
  323. end: this.$dayjs(startAndEndDate.end).format('YYYY-MM-DD')
  324. };
  325. this.$nextTick(() => {
  326. this.updateDate(date);
  327. });
  328. },
  329. emotionActive(val) {
  330. console.log(val);
  331. /* this.$nextTick(() => {
  332. this.initEmotionChart();
  333. }); */
  334. },
  335. signActive(val) {
  336. console.log(val);
  337. this.$nextTick(() => {
  338. /* this.initSignChart(); */
  339. this.initData();
  340. });
  341. }
  342. },
  343. computed: {
  344. uid() {
  345. return this.$store.getters.uid
  346. },
  347. signsChartTitle() {
  348. return `${this.signList[this.signActive].name}数据图`
  349. },
  350. degreeMap() {
  351. let map = new Map();
  352. this.degreeList.forEach(item => {
  353. map.set(item.name, item.color);
  354. });
  355. return map;
  356. },
  357. heartRateMap() {
  358. let map = new Map();
  359. this.heartRateList.forEach(item => {
  360. map.set(item.name, item.color);
  361. });
  362. return map;
  363. },
  364. temperatureMap() {
  365. let map = new Map();
  366. this.temperatureList.forEach(item => {
  367. map.set(item.name, item.color);
  368. });
  369. return map;
  370. },
  371. signGrid() {
  372. let list = [];
  373. if (this.signList[this.signActive].grid) {
  374. let temp = this[`${this.signList[this.signActive].grid}`];
  375. if (temp) {
  376. list = temp;
  377. }
  378. }
  379. return list;
  380. },
  381. defaultOptions() {
  382. return {
  383. time: {
  384. useUTC: false
  385. },
  386. grid: {
  387. show: true,
  388. borderWidth: 0,
  389. top: '3%',
  390. left: '1%',
  391. right: '3%',
  392. bottom: '15%',
  393. containLabel: true
  394. },
  395. xAxis: {
  396. type: 'category',
  397. axisLine: {
  398. show: false
  399. },
  400. textStyle: {
  401. fontSize: 10
  402. },
  403. axisTick: {
  404. show: false
  405. },
  406. splitLine: {
  407. show: false,
  408. lineStyle: {
  409. color: '#ddd',
  410. width: 2
  411. }
  412. },
  413. nameLocation: 'center',
  414. axisLabel: {
  415. show: true,
  416. fontSize: 12,
  417. showMinLabel: true, //显示最小值
  418. showMaxLabel: true //显示最大值
  419. },
  420. data: this.xAxisData
  421. },
  422. dataZoom: [
  423. /* {
  424. type: "inside",
  425. start: 0,
  426. end: 100,
  427. }, */
  428. {
  429. start: 0,
  430. end: 100,
  431. textStyle: {
  432. color: '#FFF',
  433. fontSize: 14
  434. },
  435. show: true,
  436. height: 20,
  437. bottom: 4,
  438. handleStyle: {
  439. borderWidth: 1,
  440. borderCap: 'square'
  441. }
  442. }
  443. ],
  444. tooltip: {
  445. trigger: 'axis',
  446. textStyle: {
  447. fontSize: 14,
  448. align: 'center'
  449. },
  450. formatter: function (params) {
  451. return params[0].marker + params[0].name + '</br>' + params[0].value;
  452. }
  453. },
  454. yAxis: {
  455. type: 'value',
  456. max: 100,
  457. min: 0,
  458. interval: 20,
  459. splitNumber: 1,
  460. boundaryGap: ['5%', '5%'],
  461. nameTextStyle: {
  462. fontSize: 13
  463. },
  464. alignTicks: false,
  465. axisTick: {
  466. show: false
  467. },
  468. axisLabel: {
  469. show: true,
  470. fontSize: 13
  471. },
  472. splitLine: {
  473. show: false,
  474. lineStyle: {
  475. color: '#ddd',
  476. width: 1
  477. }
  478. }
  479. },
  480. series: []
  481. };
  482. },
  483. emoLegend() {
  484. return {
  485. title: '',
  486. outTitle: `${this.emoName}数据图`,
  487. list: [
  488. { name: `无${this.emoName}倾向`, color: '#179b3b' },
  489. { name: `轻度${this.emoName}倾向`, color: '#8dc21f' },
  490. { name: `中度${this.emoName}倾向`, color: '#2ea7e0' },
  491. { name: `重度${this.emoName}倾向`, color: '#ff5f8b' }
  492. ]
  493. };
  494. }
  495. },
  496. methods: {
  497. // 获取b端token
  498. getAuth() {
  499. let manufactorId = '5bf13062-a41e-4d00-ba14-1101aad12650';
  500. return new Promise((resove, reject) => {
  501. APIAlarm.getAuth({ manufactorId: manufactorId })
  502. .then(res => {
  503. let data = res.data;
  504. if (data.code === 0) {
  505. this.$store.commit('ssjlToken', res.data.data);
  506. resove(true);
  507. }
  508. })
  509. .catch(() => {
  510. reject(false);
  511. });
  512. });
  513. },
  514. initEchartText() {
  515. this.result = `无${this.emoName}倾向`;
  516. this.defaultSeries = [
  517. {
  518. name: ``,
  519. type: 'line',
  520. padding: 5,
  521. data: this.emotionData,
  522. symbol: 'circle',
  523. symbolSize: 12, // 拐点圆的大小
  524. areaStyle: {}
  525. },
  526. {
  527. name: `轻度${this.emoName}倾向`,
  528. type: 'line',
  529. padding: 10,
  530. data: '',
  531. symbol: 'circle',
  532. symbolSize: 12 // 拐点圆的大小
  533. },
  534. {
  535. name: `中度${this.emoName}倾向`,
  536. type: 'line',
  537. data: ''
  538. },
  539. {
  540. name: `重度${this.emoName}倾向`,
  541. type: 'line',
  542. data: ''
  543. }
  544. ];
  545. let days = this.active === 0 ? 7 : 30;
  546. let startAndEndDate = this.$getRangeStartAndEnd(days);
  547. this.date = {
  548. start: this.$dayjs(startAndEndDate.start).format('YYYY-MM-DD'),
  549. end: this.$dayjs(startAndEndDate.end).format('YYYY-MM-DD')
  550. };
  551. },
  552. // 获取情绪数据
  553. getPsychologiclData(date, startDate, endDate) {
  554. ToastService.loading({
  555. message: '数据加载中'
  556. });
  557. let reqParams = {
  558. uid: this.uid,
  559. startDate: startDate || this.date.start,
  560. endDate: endDate || this.date.end,
  561. type: this.emoType
  562. };
  563. console.log('请求参数', reqParams);
  564. let reqUrl = `${PsyBaseUrl}/api/Data/GetHisData`;
  565. axios
  566. .get(reqUrl, {
  567. params: { ...reqParams },
  568. headers: { AccessToken: this.$store.getters.ssjlToken }
  569. })
  570. .then(res => {
  571. if (res.data) {
  572. let data = res.data.response;
  573. // 监测次数
  574. this.monitoringCount = data.Count;
  575. this.pieRightList = [];
  576. this.statisticsList = [];
  577. this.emotionList = [];
  578. let None = {
  579. count: data.None,
  580. percentage: this.calcPercentage(data.None, data.Count),
  581. text: `无${this.emoName}倾向`,
  582. color: '#179b3b'
  583. };
  584. let Mild = {
  585. count: data.Mild,
  586. percentage: this.calcPercentage(data.Mild, data.Count),
  587. text: `轻度${this.emoName}倾向`,
  588. color: '#8dc21f'
  589. };
  590. let Moderate = {
  591. count: data.Moderate,
  592. percentage: this.calcPercentage(data.Moderate, data.Count),
  593. text: `中度${this.emoName}倾向`,
  594. color: '#2ea7e0'
  595. };
  596. let Severe = {
  597. count: data.Severe,
  598. percentage: this.calcPercentage(data.Severe, data.Count),
  599. text: `重度${this.emoName}倾向`,
  600. color: '#ff5f8b'
  601. };
  602. // 饼状图右边数据
  603. this.pieRightList.push(None);
  604. this.pieRightList.push(Mild);
  605. this.pieRightList.push(Moderate);
  606. this.pieRightList.push(Severe);
  607. this.pieData = this.pieRightList.map(item => {
  608. item.value = item.count;
  609. item.itemStyle = {
  610. color: item.color
  611. };
  612. return item;
  613. });
  614. // 最大,最小和最近值
  615. let Max = {
  616. label: '最大值',
  617. value: data.Max,
  618. time: data.MaxDesc
  619. ? this.currentDays === 0
  620. ? this.$dayjs(data.MaxDesc).format('HH:mm')
  621. : this.$dayjs(data.MaxDesc).format('MM/DD HH:mm')
  622. : '',
  623. bgColor: '#ff5f8b'
  624. };
  625. let Min = {
  626. label: '最小值',
  627. value: data.Min,
  628. time: data.MinDesc
  629. ? this.currentDays === 0
  630. ? this.$dayjs(data.MinDesc).format('HH:mm')
  631. : this.$dayjs(data.MinDesc).format('MM/DD HH:mm')
  632. : '',
  633. bgColor: '#189b3b'
  634. };
  635. /* let Avg = {
  636. label: '平均值',
  637. value: data.Avg,
  638. time: data.AvgDesc
  639. ? this.currentDays === 0
  640. ? this.$dayjs(data.AvgDesc).format('HH:mm')
  641. : this.$dayjs(data.AvgDesc).format('MM/DD HH:mm')
  642. : ''
  643. }; */
  644. let Current = {
  645. label: '最近值',
  646. value: data.Current,
  647. time: data.CurrentDesc
  648. ? this.currentDays === 0
  649. ? this.$dayjs(data.CurrentDesc).format('HH:mm')
  650. : this.$dayjs(data.CurrentDesc).format('MM/DD HH:mm')
  651. : '',
  652. bgColor: '#2ea7e0'
  653. };
  654. this.statisticsList.push(Max);
  655. this.statisticsList.push(Min);
  656. /* this.statisticsList.push(Avg); */
  657. this.statisticsList.push(Current);
  658. // 周报月报底部显示数据
  659. let NoneDay = {
  660. days: data.NoneDay,
  661. text: `无${this.emoName}倾向`,
  662. color: '#179b3b'
  663. };
  664. let MildDay = {
  665. days: data.MildDay,
  666. text: `轻度${this.emoName}倾向`,
  667. color: '#8dc21f'
  668. };
  669. let ModerateDay = {
  670. days: data.ModerateDay,
  671. text: `中度${this.emoName}倾向`,
  672. color: '#2ea7e0'
  673. };
  674. let SevereDay = {
  675. days: data.SevereDay,
  676. text: `重度${this.emoName}倾向`,
  677. color: '#ff5f8b'
  678. };
  679. this.emotionList.push(NoneDay);
  680. this.emotionList.push(MildDay);
  681. this.emotionList.push(ModerateDay);
  682. this.emotionList.push(SevereDay);
  683. // 图表数据
  684. this.emotionData = data.ChartDatas.map(item => {
  685. return {
  686. value: item.Value,
  687. itemStyle: {
  688. borderColor: this.calcResultColor(item.Level)
  689. }
  690. };
  691. });
  692. // 7天 和 30天柱形图显示
  693. this.weekAndMonData = data.ChartDatas.map((item, index) => {
  694. return {
  695. value: [index, item.MinValue, item.MaxValue]
  696. };
  697. });
  698. console.log("this.weekAndMonData", this.weekAndMonData);
  699. // x轴显示数据
  700. if (this.currentDays === 0) {
  701. // 显示今天数据
  702. this.xAxisData = data.ChartDatas.map(item => {
  703. return this.$dayjs(item.Key.replace(/-/g, '/')).format('HH:mm');
  704. });
  705. } else {
  706. this.xAxisData = data.ChartDatas.map(item => {
  707. return this.$dayjs(item.Key.replace(/-/g, '/')).format('MM/DD');
  708. });
  709. let that = this;
  710. // 7天和30天变成柱状图
  711. this.weekAndMonthSeries = [
  712. {
  713. name: '平均值',
  714. type: 'scatter',
  715. symbolSize: 14,
  716. data: this.emotionData
  717. },
  718. {
  719. name: '',
  720. type: 'custom',
  721. data: this.weekAndMonData,
  722. renderItem: function (params, api) {
  723. let categoryIndex = api.value(0);
  724. let end = api.coord([categoryIndex, api.value(1)]);
  725. let start = api.coord([categoryIndex, api.value(2)]);
  726. let width = 16;
  727. let rectShape = that.$echarts.graphic.clipRectByRect(
  728. {
  729. x: start[0] - width / 2,
  730. y: start[1],
  731. width: 16,
  732. height: end[1] - start[1]
  733. },
  734. {
  735. x: params.coordSys.x,
  736. y: params.coordSys.y,
  737. width: params.coordSys.width,
  738. height: params.coordSys.height
  739. }
  740. );
  741. if (rectShape) {
  742. rectShape.r = [10];
  743. }
  744. return (
  745. rectShape && {
  746. type: 'rect',
  747. shape: rectShape,
  748. style: api.style()
  749. }
  750. );
  751. },
  752. itemStyle: {
  753. opacity: 0.8
  754. },
  755. encode: {
  756. y: [1, 2],
  757. x: 0
  758. }
  759. },
  760. {
  761. name: `轻度${this.emoName}倾向`,
  762. type: 'scatter',
  763. symbolSize: 12,
  764. data: ''
  765. },
  766. {
  767. name: `中度${this.emoName}倾向`,
  768. type: 'scatter',
  769. symbolSize: 12,
  770. data: ''
  771. },
  772. {
  773. name: `重度${this.emoName}倾向`,
  774. type: 'scatter',
  775. symbolSize: 12,
  776. data: ''
  777. },
  778. {
  779. name: `无${this.emoName}倾向`,
  780. type: 'scatter',
  781. symbolSize: 12,
  782. data: ''
  783. }
  784. ];
  785. // 点击提示此时为空
  786. this.defaultOptions.tooltip = {
  787. trigger: 'axis',
  788. formatter: function (params) {
  789. return (
  790. params[0].marker +
  791. '平均值:' +
  792. params[0].name +
  793. '--' +
  794. params[0].value +
  795. '</br>' +
  796. params[1].marker +
  797. '最大值:' +
  798. params[1].name +
  799. '--' +
  800. params[1].value[2] +
  801. '</br>' +
  802. params[1].marker +
  803. '最小值:' +
  804. params[1].name +
  805. '--' +
  806. params[1].value[1]
  807. );
  808. }
  809. };
  810. this.defaultOptions.series = this.weekAndMonthSeries;
  811. }
  812. // 结果解读
  813. this.result = data.Result;
  814. this.resultLevel = data.ResultLevel;
  815. this.advice = data.Advice;
  816. ToastService.success({
  817. message: '数据加载完成'
  818. });
  819. }
  820. })
  821. .catch(error => {
  822. console.log(error);
  823. })
  824. .finally(() => {
  825. ToastService.clear();
  826. });
  827. },
  828. getPostDate(dateNow, intervalDays, bolPastTime) {
  829. let oneDayTime = 24 * 60 * 60 * 1000;
  830. let list = [];
  831. let lastDay;
  832. if (bolPastTime == true) {
  833. lastDay = new Date(dateNow.getTime() - intervalDays * oneDayTime);
  834. list.push(this.formateDate(lastDay));
  835. list.push(this.formateDate(dateNow));
  836. } else {
  837. lastDay = new Date(dateNow.getTime() + intervalDays * oneDayTime);
  838. list.push(this.formateDate(dateNow));
  839. list.push(this.formateDate(lastDay));
  840. }
  841. return list;
  842. },
  843. updateDate(value) {
  844. this.date = value;
  845. console.log('this.date', this.date);
  846. this.getPsychologiclData('', value.start, value.end);
  847. this.initData();
  848. //this.getReportData('', value.start, value.end);
  849. },
  850. formateDate(time) {
  851. let year = time.getFullYear();
  852. let month = time.getMonth() + 1;
  853. let day = time.getDate();
  854. if (month < 10) {
  855. month = '0' + month;
  856. }
  857. if (day < 10) {
  858. day = '0' + day;
  859. }
  860. return year + '-' + month + '-' + day + '';
  861. },
  862. // 计算结果采用哪种颜色
  863. calcResultColor(value, isCallBackClass) {
  864. let color = '';
  865. let className = '';
  866. switch (Number(value)) {
  867. case 0:
  868. color = '#179b3b';
  869. className = 'none';
  870. break;
  871. case 1:
  872. color = '#8dc21f';
  873. className = 'mild';
  874. break;
  875. case 2:
  876. color = '#2ea7e0';
  877. className = 'moderate';
  878. break;
  879. case 3:
  880. color = '#ff5f8b';
  881. className = 'severe';
  882. break;
  883. }
  884. return isCallBackClass ? className : color;
  885. },
  886. // 计算百分比
  887. calcPercentage(value, total) {
  888. if (typeof value !== 'number' || typeof total !== 'number' || total === 0) {
  889. return 0;
  890. }
  891. let milValue = value * 1000;
  892. let milTotal = total * 1000;
  893. return Math.round((milValue / milTotal) * 100);
  894. },
  895. getMonthStaEnd(value) {
  896. const dateObj = {};
  897. console.log("时间值", value);
  898. const start = startOfMonth(value);
  899. const end = endOfMonth(value);
  900. console.log("时间值start", start);
  901. console.log("时间值end", end);
  902. dateObj.start = format(start, 'yyyy-MM-dd');
  903. dateObj.end = format(end, 'yyyy-MM-dd');
  904. this.monthDate = { ...dateObj };
  905. },
  906. initData() {
  907. //初始化图表
  908. if (!this.signChart) {
  909. this.signChart = this.$echarts.init(document.getElementById('signChart'));
  910. }
  911. if (!this.stepChart) {
  912. this.stepChart = this.$echarts.init(document.getElementById('stepChart'));
  913. }
  914. if (!this.calorieChart) {
  915. this.calorieChart = this.$echarts.init(document.getElementById('calorieChart'));
  916. }
  917. //渲染图表
  918. this.initSignChart();
  919. },
  920. initEmotionChart() {
  921. let option = this.getOption();
  922. //测试
  923. let data = [
  924. {
  925. time: '5.11',
  926. value: 10
  927. },
  928. {
  929. time: '5.12',
  930. value: 20
  931. },
  932. {
  933. time: '5.13',
  934. value: 40
  935. },
  936. {
  937. time: '5.14',
  938. value: 50
  939. },
  940. {
  941. time: '5.15',
  942. value: 60
  943. },
  944. {
  945. time: '5.16',
  946. value: 70
  947. },
  948. {
  949. time: '5.17',
  950. value: 90
  951. }
  952. ];
  953. this.formateEmotionData(option, data);
  954. this.emotionChart.setOption(option);
  955. },
  956. async initSignChart() {
  957. let option = this.getOption();
  958. let data = await this.getReportData('', this.date.start, this.date.end);
  959. if (this.signActive == 0) {
  960. //测试
  961. this.formateHeartRateData(option, data.days);
  962. this.signChart.setOption(option);
  963. } else if (this.signActive == 1) {
  964. //测试
  965. this.formateTemperatureData(option, data.days);
  966. this.signChart.setOption(option);
  967. } else if (this.signActive == 2) {
  968. option = this.getOption(false);
  969. let option2 = this.getOption(false);
  970. let data2 = await this.getReportData(3, this.date.start, this.date.end);
  971. this.stepsData = { ...data.stepTotal, ...data.stepAvg };
  972. this.calorieData = { ...data2.calorieTotal, ...data2.calorieAvg };
  973. this.formateStepData(option, data.days);
  974. this.formateCalorieData(option2, data2.days);
  975. this.stepChart.setOption(option);
  976. this.calorieChart.setOption(option2);
  977. console.log("this.calorieData", this.calorieData);
  978. }
  979. },
  980. formateEmotionData(option, data) {
  981. let xdata = [];
  982. let ydata = [];
  983. let fill = [];
  984. let max = 0;
  985. data.forEach(item => {
  986. if (item.value > max) {
  987. max = item.value || '--';
  988. }
  989. });
  990. data.forEach(item => {
  991. xdata.push(item.time);
  992. fill.push({
  993. value: max - item.value || '--',
  994. label: {
  995. show: false
  996. },
  997. itemStyle: {
  998. color: this.formateEmotionColor(item.value)
  999. }
  1000. });
  1001. ydata.push({
  1002. value: item.value || '--',
  1003. label: {
  1004. show: true
  1005. },
  1006. itemStyle: {
  1007. color: this.formateEmotionColor(item.value)
  1008. }
  1009. });
  1010. });
  1011. option.xAxis.data = xdata;
  1012. option.series[0].data = ydata;
  1013. /* option.series[1].data = fill; */
  1014. },
  1015. formateEmotionColor(value) {
  1016. if (value > 75) {
  1017. return this.degreeMap.get('重度');
  1018. } else if (value > 50) {
  1019. return this.degreeMap.get('中度');
  1020. } else if (value > 25) {
  1021. return this.degreeMap.get('轻度');
  1022. } else {
  1023. return this.degreeMap.get('无');
  1024. }
  1025. },
  1026. formateHeartRateData(option, data) {
  1027. let xdata = [];
  1028. let ydata = [];
  1029. let fill = [];
  1030. data.forEach((item) => {
  1031. xdata.push(item.key);
  1032. /* fill.push({
  1033. value: [index, Number(item.valueMax) || '--', Number(item.valueMin) || '--'],
  1034. }); */
  1035. ydata.push({
  1036. value: item.value || '--',
  1037. label: {
  1038. show: false
  1039. },
  1040. itemStyle: {
  1041. borderWidth: 3,
  1042. borderColor: this.calcColorByEvaluate(item.level)
  1043. }
  1044. },
  1045. );
  1046. });
  1047. fill = data.map((item, index) => {
  1048. return {
  1049. value: [index, item.valueMin || '--', item.valueMax || '--']
  1050. };
  1051. })
  1052. option.xAxis.data = xdata;
  1053. option.series[0].data = ydata;
  1054. option.series[1].data = fill;
  1055. option[0] =
  1056. option.tooltip = {
  1057. trigger: 'axis',
  1058. textStyle: {
  1059. fontSize: 16
  1060. },
  1061. formatter: function (params) {
  1062. return (
  1063. /* params[0].marker + */
  1064. '平均值:' +
  1065. params[0].name +
  1066. '--' +
  1067. params[0].value +
  1068. '</br>' +
  1069. /* params[1].marker + */
  1070. '最大值:' +
  1071. params[1].name +
  1072. '--' +
  1073. params[1].value[2] +
  1074. '</br>' +
  1075. /* params[1].marker + */
  1076. '最小值:' +
  1077. params[1].name +
  1078. '--' +
  1079. params[1].value[1]
  1080. );
  1081. }
  1082. };
  1083. // 规定最小值
  1084. option.yAxis.min = 40;
  1085. // 规定最大值
  1086. option.yAxis.max = 150;
  1087. //设置高压标线
  1088. option.series[0].markLine = {
  1089. data: [
  1090. {
  1091. symbol: 'pin',
  1092. silent: true,
  1093. yAxis: 120,
  1094. lineStyle: {
  1095. color: '#C1272D'
  1096. },
  1097. label: {
  1098. color: '#C1272D'
  1099. }
  1100. }
  1101. ]
  1102. };
  1103. },
  1104. formateTemperatureData(option, data) {
  1105. let xdata = [];
  1106. let ydata = [];
  1107. let fill = [];
  1108. let max = 0;
  1109. data.forEach(item => {
  1110. if (item.value > max) {
  1111. max = item.value || '--';
  1112. }
  1113. });
  1114. data.forEach(item => {
  1115. xdata.push(item.key);
  1116. ydata.push({
  1117. value: item.value || '--',
  1118. label: {
  1119. show: false
  1120. },
  1121. itemStyle: {
  1122. borderWidth: 3,
  1123. borderColor: this.calcColorByEvaluate(item.level)
  1124. }
  1125. });
  1126. });
  1127. fill = data.map((item, index) => {
  1128. return {
  1129. value: [index, item.valueMin || '--', item.valueMax || '--']
  1130. };
  1131. })
  1132. option.xAxis.data = xdata;
  1133. option.series[0].data = ydata;
  1134. option.series[0].markLine = {
  1135. data: [
  1136. {
  1137. type: "average",
  1138. name: "体温",
  1139. yAxis: 37.2,
  1140. label: {
  1141. fontSize: 14,
  1142. position: "end",
  1143. },
  1144. lineStyle: {
  1145. type: "dashed",
  1146. width: 2,
  1147. color: "red",
  1148. },
  1149. },
  1150. ],
  1151. }
  1152. option.series[1].data = fill;
  1153. option[0] =
  1154. option.tooltip = {
  1155. trigger: 'axis',
  1156. textStyle: {
  1157. fontSize: 16
  1158. },
  1159. formatter: function (params) {
  1160. return (
  1161. /* params[0].marker + */
  1162. '平均值:' +
  1163. params[0].name +
  1164. '--' +
  1165. params[0].value +
  1166. '</br>' +
  1167. /* params[1].marker + */
  1168. '最大值:' +
  1169. params[1].name +
  1170. '--' +
  1171. params[1].value[2] +
  1172. '</br>' +
  1173. /* params[1].marker + */
  1174. '最小值:' +
  1175. params[1].name +
  1176. '--' +
  1177. params[1].value[1]
  1178. );
  1179. }
  1180. };
  1181. /* option.series[1].data = fill; */
  1182. // 规定最小值
  1183. option.yAxis.min = 34.5;
  1184. // 规定最大值
  1185. option.yAxis.max = 42.5;
  1186. },
  1187. formateStepData(option, data) {
  1188. let xdata = [];
  1189. let ydata = [];
  1190. data.forEach(item => {
  1191. xdata.push(item.key);
  1192. ydata.push({
  1193. value: item.value,
  1194. label: {
  1195. show: true
  1196. },
  1197. itemStyle: {
  1198. borderWidth: 3,
  1199. borderColor: this.calcColorByEvaluate(item.level)
  1200. }
  1201. });
  1202. });
  1203. option.xAxis.data = xdata;
  1204. option.series[0].data = ydata;
  1205. // 隐藏y轴
  1206. option.yAxis.show = false;
  1207. },
  1208. formateCalorieData(option, data) {
  1209. let xdata = [];
  1210. let ydata = [];
  1211. data.forEach(item => {
  1212. xdata.push(item.key);
  1213. ydata.push({
  1214. value: item.value == null ? 0 : item.value,
  1215. label: {
  1216. show: true
  1217. },
  1218. itemStyle: {
  1219. borderWidth: 3,
  1220. borderColor: this.calcColorByEvaluate(item.level)
  1221. }
  1222. });
  1223. });
  1224. option.xAxis.data = xdata;
  1225. option.series[0].data = ydata;
  1226. // 隐藏y轴
  1227. option.yAxis.show = false;
  1228. },
  1229. getOption(/* point = true */) {
  1230. let that = this;
  1231. let chartSeries = [];
  1232. if (this.signActive === 0 || this.signActive === 1) {
  1233. chartSeries = [
  1234. {
  1235. name: '平均值',
  1236. type: 'scatter',
  1237. symbolSize: 14,
  1238. },
  1239. {
  1240. name: '',
  1241. type: 'custom',
  1242. renderItem: function (params, api) {
  1243. let categoryIndex = api.value(0);
  1244. let end = (api.coord([categoryIndex, api.value(1)]));
  1245. let start = (api.coord([categoryIndex, api.value(2)]));
  1246. let width = 16;
  1247. let rectShape = that.$echarts.graphic.clipRectByRect(
  1248. {
  1249. x: start[0] - width / 2,
  1250. y: start[1],
  1251. width: 16,
  1252. height: end[1] - start[1]
  1253. },
  1254. {
  1255. x: params.coordSys.x,
  1256. y: params.coordSys.y,
  1257. width: params.coordSys.width,
  1258. height: params.coordSys.height
  1259. }
  1260. );
  1261. if (rectShape) {
  1262. rectShape.r = [20];
  1263. }
  1264. return (
  1265. rectShape && {
  1266. type: 'rect',
  1267. shape: rectShape,
  1268. style: api.style()
  1269. }
  1270. );
  1271. },
  1272. itemStyle: {
  1273. opacity: 0.8
  1274. },
  1275. encode: {
  1276. y: [1, 2],
  1277. x: 0
  1278. }
  1279. },
  1280. ]
  1281. } else {
  1282. chartSeries = [
  1283. {
  1284. type: 'line',
  1285. padding: 10,
  1286. smooth: true,
  1287. symbol: 'circle',
  1288. symbolSize: 10,
  1289. itemStyle: {
  1290. color: '#fff',
  1291. borderWidth: 4
  1292. },
  1293. lineStyle: {
  1294. width: 6,
  1295. type: 'solid',
  1296. color: '#189b3b'
  1297. }
  1298. },
  1299. ]
  1300. }
  1301. let option = {
  1302. grid: {
  1303. show: true,
  1304. borderWidth: 0,
  1305. top: '10%',
  1306. left: '15%',
  1307. right: '10%',
  1308. bottom: '20%'
  1309. },
  1310. xAxis: {
  1311. type: 'category',
  1312. axisLine: {
  1313. show: false
  1314. },
  1315. axisTick: {
  1316. show: false
  1317. },
  1318. splitLine: {
  1319. show: false,
  1320. lineStyle: {
  1321. color: '#ddd',
  1322. width: 4
  1323. }
  1324. },
  1325. axisLabel: {
  1326. show: true,
  1327. fontSize: 12,
  1328. showMinLabel: true, //显示最小值
  1329. showMaxLabel: true, //显示最大值
  1330. marginBottom: 10 // 调整标签与轴线的距离
  1331. }
  1332. },
  1333. yAxis: {
  1334. type: 'value',
  1335. boundaryGap: ['5%', '5%'],
  1336. nameTextStyle: {
  1337. fontSize: 13
  1338. },
  1339. alignTicks: false,
  1340. axisTick: {
  1341. show: false
  1342. },
  1343. axisLabel: {
  1344. show: true,
  1345. fontSize: 13
  1346. },
  1347. splitLine: {
  1348. show: false,
  1349. lineStyle: {
  1350. color: '#ddd',
  1351. width: 1
  1352. }
  1353. }
  1354. },
  1355. dataZoom: [
  1356. {
  1357. start: 0,
  1358. end: 100,
  1359. textStyle: {
  1360. color: '#FFF',
  1361. fontSize: 14
  1362. },
  1363. show: true,
  1364. height: 20,
  1365. bottom: 8,
  1366. handleStyle: {
  1367. borderWidth: 4,
  1368. borderCap: 'square'
  1369. }
  1370. }
  1371. ],
  1372. tooltip: {
  1373. trigger: 'axis',
  1374. textStyle: {
  1375. fontSize: 16,
  1376. align: 'center'
  1377. },
  1378. formatter: function (params) {
  1379. return params[0].marker + params[0].name + '</br>' + params[0].value;
  1380. }
  1381. },
  1382. series: chartSeries
  1383. };
  1384. /* if (!point) {
  1385. option.series = [
  1386. {
  1387. type: 'bar',
  1388. barMaxWidth: 15,
  1389. label: {
  1390. show: true,
  1391. color: '#000',
  1392. position: 'outside'
  1393. },
  1394. itemStyle: {
  1395. borderRadius: 12
  1396. }
  1397. }
  1398. ];
  1399. } */
  1400. return option;
  1401. },
  1402. onEmotionClick(item, index) {
  1403. this.emotionActive = index;
  1404. this.emoName = item.name;
  1405. this.emoType = item.type;
  1406. if (this.active == 1) {
  1407. /* this.getMonthStaEnd(this.date); */
  1408. this.getPsychologiclData('', this.monthDate.start, this.monthDate.end);
  1409. } else {
  1410. this.getPsychologiclData('', this.date.start, this.date.end);
  1411. }
  1412. // 情绪选项变化重新渲染图表
  1413. },
  1414. onSignClick(index) {
  1415. this.signActive = index;
  1416. // 体征选项变化重新渲染图表
  1417. },
  1418. onRouterTo(name) {
  1419. this.$router.push({
  1420. name: name === 'emo' ? 'reportList' : 'signsReport',
  1421. query: {
  1422. type: name === 'emo' ? this.emoType : this.signActive,
  1423. dateType: this.active, //日期类型
  1424. name: this.signList[this.signActive].label
  1425. }
  1426. });
  1427. },
  1428. // 根据等级计算颜色
  1429. calcColorByEvaluate(value) {
  1430. let color = '';
  1431. const intValue = Number(value);
  1432. switch (intValue) {
  1433. case 2:
  1434. // 偏高
  1435. color = '#ff5f8b';
  1436. break;
  1437. case 1:
  1438. // 正常
  1439. color = '#189b3b';
  1440. break;
  1441. case 99:
  1442. // 正常
  1443. color = '#189b3b';
  1444. break;
  1445. case 0:
  1446. // 偏低
  1447. color = '#2ea7e0';
  1448. break;
  1449. default:
  1450. color = '#189b3b';
  1451. break;
  1452. }
  1453. return color;
  1454. },
  1455. // 获取体征历史数据
  1456. getReportData(value, startDate, endDate) {
  1457. let reqDate = this.date;
  1458. let reqBody = {
  1459. personId: this.$store.getters.personId,
  1460. dateType: 1,
  1461. healthyType: value || this.signActive,
  1462. startTime: startDate || reqDate.start,
  1463. endTime: endDate || reqDate.end
  1464. };
  1465. return new Promise(resolve => {
  1466. APIHealthUser.getReportData(reqBody).then(res => {
  1467. if (res.data.data.days) {
  1468. res.data.data.days = res.data.data.days.map(item => {
  1469. item.key = this.$dayjs(item.key).format('MM-DD');
  1470. return item;
  1471. });
  1472. }
  1473. this.signData = { ...res.data.data };
  1474. if (this.signActive === 1) {
  1475. this.signDaysList = [
  1476. {
  1477. day: res.data.data.normalDay.normalDay, name: '正常', color: '#189b3b'
  1478. },
  1479. { day: res.data.data.highDay.highDay, name: '偏高', color: '#ff5f8b' }
  1480. /* { day: res.data.data.low, name: '偏低', color: '#2ea7e0' } */
  1481. ];
  1482. } else if (this.signActive === 0) {
  1483. this.signDaysList = [
  1484. {
  1485. day: res.data.data.normalDay
  1486. .normalDay, name: '正常', color: '#189b3b'
  1487. },
  1488. { day: res.data.data.highDay.highDay, name: '偏高', color: '#ff5f8b' },
  1489. { day: res.data.data.lowDay.lowDay, name: '偏低', color: '#2ea7e0' }
  1490. ];
  1491. } else {
  1492. this.signDaysList = [
  1493. {
  1494. day: res.data.data.normalDay, name: '正常', color: '#189b3b'
  1495. },
  1496. { day: res.data.data.highDay, name: '偏高', color: '#ff5f8b' },
  1497. { day: res.data.data.lowDay, name: '偏低', color: '#2ea7e0' }
  1498. ];
  1499. }
  1500. resolve(res.data.data);
  1501. });
  1502. });
  1503. },
  1504. // 获取用户信息
  1505. getPersonInfo() {
  1506. let reqParams = {
  1507. personId: this.$store.getters.personId
  1508. };
  1509. APIHealthUser.personInfo(reqParams)
  1510. .then(res => {
  1511. const data = res.data.data;
  1512. if (data) {
  1513. this.bmi.height = data.height;
  1514. this.bmi.weight = data.weight;
  1515. this.bmi.curHeight = data.height;
  1516. this.bmi.curWeight = data.weight;
  1517. const bmiResult = this.$calcBMI(data.height, data.weight);
  1518. this.bmi.value = bmiResult.bmi;
  1519. this.bmi.result = bmiResult.result;
  1520. this.personData = { ...data }
  1521. console.log("bmi信息", bmiResult);
  1522. }
  1523. })
  1524. .catch(error => {
  1525. console.log('error', error);
  1526. this.showOverlay = false;
  1527. this.isPageShow = true;
  1528. })
  1529. .finally(() => {
  1530. })
  1531. },
  1532. // 更新用户信息
  1533. updatePerson() {
  1534. let reqBody = {
  1535. ...this.personData
  1536. };
  1537. reqBody.height = Number(this.bmi.height);
  1538. reqBody.weight = Number(this.bmi.weight);
  1539. console.log('reqBody', reqBody);
  1540. ToastService.loading({
  1541. message: '更新中'
  1542. });
  1543. APIHealthUser.updatePerson(reqBody)
  1544. .then(res => {
  1545. ToastService.clear();
  1546. console.log(res.data);
  1547. if (res.data.stateCode == 1) {
  1548. ToastService.success({
  1549. message: '更新成功'
  1550. });
  1551. setTimeout(() => {
  1552. this.getPersonInfo();
  1553. }, 1000);
  1554. } else {
  1555. DialogService.confirm({
  1556. title: res.data.message
  1557. });
  1558. }
  1559. })
  1560. .catch(e => {
  1561. ToastService.clear();
  1562. DialogService.confirm({
  1563. title: e.message || '服务器异常'
  1564. });
  1565. });
  1566. },
  1567. // 更新bmi
  1568. onUpdateBmi() {
  1569. // 打开输入弹窗
  1570. this.bmi.isBmiShow = true;
  1571. },
  1572. onConfirmBmi() {
  1573. if (isNull(this.bmi.height) || isNull(this.bmi.weight)) {
  1574. this.bmi.height = this.bmi.curHeight;
  1575. this.bmi.weight = this.bmi.curWeight;
  1576. return DialogService.confirm({
  1577. title: '身高和体重不能为空'
  1578. })
  1579. }
  1580. this.updatePerson();
  1581. },
  1582. onCancelBmi() {
  1583. this.bmi.height = this.bmi.curHeight;
  1584. this.bmi.weight = this.bmi.curWeight;
  1585. }
  1586. }
  1587. };
  1588. </script>
  1589. <style scoped lang="scss">
  1590. @import './include.scss';
  1591. .insight {
  1592. padding-top: 20px;
  1593. .periodNav {
  1594. display: flex;
  1595. justify-content: space-around;
  1596. align-items: center;
  1597. .periodItem {
  1598. width: 48%;
  1599. font-size: 28px;
  1600. color: black;
  1601. text-align: center;
  1602. padding: 12px;
  1603. border-radius: 30px;
  1604. background: #e6e6e6;
  1605. &.active {
  1606. color: white;
  1607. background: #179b3b;
  1608. }
  1609. }
  1610. .minPeriodItem {
  1611. width: 32%;
  1612. padding: 8px;
  1613. }
  1614. }
  1615. .periodSwitch {
  1616. display: flex;
  1617. width: 100%;
  1618. justify-content: space-between;
  1619. align-items: center;
  1620. padding: 40px 10px;
  1621. padding-bottom: 10px;
  1622. .timearea {
  1623. font-size: 28px;
  1624. justify-self: center;
  1625. color: gray;
  1626. }
  1627. .arrow {
  1628. font-size: 45px;
  1629. }
  1630. }
  1631. .bmi {
  1632. display: flex;
  1633. justify-content: flex-start;
  1634. align-items: center;
  1635. white-space: nowrap;
  1636. padding: 40px 8px 0 8px;
  1637. font-weight: bold;
  1638. p {
  1639. padding: 0 5px;
  1640. font-size: 28px;
  1641. }
  1642. .van-button {
  1643. padding: 5px 10px;
  1644. margin-left: 10px;
  1645. font-size: 12px;
  1646. color: #fff;
  1647. border-radius: 30px;
  1648. background-color: $green;
  1649. }
  1650. }
  1651. .bmiDialog {
  1652. padding: 40px 60px;
  1653. @include center();
  1654. .van-cell .van-field {
  1655. margin: 20px 0 !important;
  1656. }
  1657. }
  1658. .label {
  1659. font-size: 36px;
  1660. font-weight: bold;
  1661. padding: 30px 10px 30px 0;
  1662. display: flex;
  1663. justify-content: space-between;
  1664. align-items: center;
  1665. .right {
  1666. font-size: 30px;
  1667. }
  1668. }
  1669. .title-out {
  1670. font-size: 36px;
  1671. font-weight: bold;
  1672. padding: 60px 20px 20px 20px;
  1673. }
  1674. .echart-container {
  1675. flex: 1;
  1676. position: relative;
  1677. min-height: 600px;
  1678. background-color: #fff;
  1679. padding: 0 10px;
  1680. }
  1681. .ChatBox {
  1682. overflow: hidden;
  1683. width: calc(100vw - 60px);
  1684. height: 650px;
  1685. border: 2px solid #cdf348;
  1686. border-radius: 30px;
  1687. /* margin-top: 30px; */
  1688. h4 {
  1689. padding: 40px 0 10px 60px;
  1690. }
  1691. .legendBox {
  1692. width: 100%;
  1693. height: 100px;
  1694. display: flex;
  1695. justify-content: flex-end;
  1696. align-items: center;
  1697. padding: 0 30px;
  1698. .legend {
  1699. display: flex;
  1700. flex-wrap: wrap;
  1701. justify-content: flex-end;
  1702. align-items: center;
  1703. font-size: 20px;
  1704. .legendItem {
  1705. position: relative;
  1706. width: 205px;
  1707. margin-top: 10px;
  1708. margin-right: 20px;
  1709. &:nth-child(2n) {
  1710. margin-right: 0;
  1711. }
  1712. }
  1713. .not {
  1714. .number {
  1715. color: #179b3b;
  1716. }
  1717. &::before {
  1718. content: '';
  1719. position: absolute;
  1720. top: 0;
  1721. bottom: 0;
  1722. left: -20px;
  1723. width: 15px;
  1724. height: 15px;
  1725. background: #179b3b;
  1726. border-radius: 50%;
  1727. margin: auto;
  1728. }
  1729. }
  1730. .mild {
  1731. .number {
  1732. color: #2ea7e0;
  1733. }
  1734. &::before {
  1735. content: '';
  1736. position: absolute;
  1737. top: 0;
  1738. bottom: 0;
  1739. left: -20px;
  1740. width: 15px;
  1741. height: 15px;
  1742. background: #2ea7e0;
  1743. border-radius: 50%;
  1744. margin: auto;
  1745. }
  1746. }
  1747. .moderate {
  1748. .number {
  1749. color: #8dc21f;
  1750. }
  1751. &::before {
  1752. content: '';
  1753. position: absolute;
  1754. top: 0;
  1755. bottom: 0;
  1756. left: -20px;
  1757. width: 15px;
  1758. height: 15px;
  1759. background: #8dc21f;
  1760. border-radius: 50%;
  1761. margin: auto;
  1762. }
  1763. }
  1764. .severe {
  1765. .number {
  1766. color: #ff5f8b;
  1767. }
  1768. &::before {
  1769. content: '';
  1770. position: absolute;
  1771. top: 0;
  1772. bottom: 0;
  1773. left: -20px;
  1774. width: 15px;
  1775. height: 15px;
  1776. background: #ff5f8b;
  1777. border-radius: 50%;
  1778. margin: auto;
  1779. }
  1780. }
  1781. }
  1782. }
  1783. .minLegendBox {
  1784. .legend {
  1785. .legendItem {
  1786. width: auto;
  1787. margin-right: 50px;
  1788. &:nth-child(2n) {
  1789. margin-right: 50px;
  1790. }
  1791. &:last-child {
  1792. margin-right: 0;
  1793. }
  1794. }
  1795. }
  1796. }
  1797. .Chat {
  1798. width: calc(100vw - 60px);
  1799. height: 500px;
  1800. }
  1801. .result {
  1802. height: 140px;
  1803. padding: 0 30px;
  1804. border-radius: 70px;
  1805. display: flex;
  1806. justify-content: center;
  1807. align-items: flex-start;
  1808. flex-direction: column;
  1809. .wrapBox {
  1810. padding: 10px 120px 10px 60px;
  1811. width: 100%;
  1812. background-color: #e6e6e6;
  1813. border-radius: 30px;
  1814. }
  1815. .text {
  1816. display: flex;
  1817. justify-content: flex-start;
  1818. align-items: center;
  1819. .right {
  1820. @include center();
  1821. padding-left: px2rem(20);
  1822. img {
  1823. height: 30px;
  1824. width: 30px;
  1825. object-fit: contain;
  1826. margin: 0 5px;
  1827. }
  1828. }
  1829. }
  1830. }
  1831. }
  1832. .minChartBox {
  1833. height: 760px;
  1834. }
  1835. .hiddenChart {
  1836. width: 0;
  1837. height: 0;
  1838. }
  1839. .grid {
  1840. display: flex;
  1841. flex-wrap: wrap;
  1842. justify-content: space-between;
  1843. color: white;
  1844. font-size: 30px;
  1845. .gridItem {
  1846. width: calc((100vw - 60px) * 0.48);
  1847. height: calc((100vw - 60px) * 0.48);
  1848. border-radius: 60px;
  1849. display: flex;
  1850. flex-direction: column;
  1851. justify-content: center;
  1852. align-items: center;
  1853. margin-top: 30px;
  1854. .time {
  1855. .number {
  1856. font-size: 90px;
  1857. font-weight: bold;
  1858. }
  1859. }
  1860. }
  1861. .minItem {
  1862. width: calc((100vw - 60px) * 0.32);
  1863. height: calc((100vw - 60px) * 0.32);
  1864. font-size: 28px;
  1865. .time {
  1866. .number {
  1867. font-size: 70px;
  1868. font-weight: bold;
  1869. }
  1870. }
  1871. }
  1872. }
  1873. }
  1874. </style>