index.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <template>
  2. <view>
  3. <view class="top-box">
  4. <view class="container-top" @click="showPicker = true">
  5. <view class="top-left">
  6. <view class="word">一周内</view>
  7. <text>{{formatDate(defaultDate[0])}} ~ {{formatDate(defaultDate[1])}}</text>
  8. </view>
  9. <!-- <view class="top-right" @click.stop="fullscreenFn">
  10. <image src="/static/image/full.png" mode=""></image>
  11. </view> -->
  12. </view>
  13. <view class="chartsMain" v-show="Area.categories.length&&!showPicker">
  14. <canvas canvas-id="canvasArea" id="canvasArea" class="charts"></canvas>
  15. </view>
  16. <view class="chartsMain" v-show="!Area.categories.length">
  17. <image src="/static/image/none.png" mode=""></image>
  18. </view>
  19. </view>
  20. <view class="content-box">
  21. <view class="word-box">
  22. <view class="word-title">
  23. 睡眠记录
  24. </view>
  25. </view>
  26. <view class="list-box">
  27. <block v-for="(item,index) in infoData.list">
  28. <view class="list-box-item">
  29. <view class="list-box-left">
  30. <image src="/static/image/hearticon.png" mode=""></image>
  31. <text>{{formatHms(item.createTime)}}</text>
  32. </view>
  33. <view class="list-box-right">
  34. <view class="num">{{item.rollTimes}}</view>
  35. <view>次</view>
  36. </view>
  37. </view>
  38. </block>
  39. </view>
  40. </view>
  41. <!-- 日历 -->
  42. <van-calendar :show="showPicker" type="range" @confirm="onConfirm" @close="showPicker = false"
  43. :default-date="defaultDate" allow-same-day="true" :min-date="minDate" />
  44. </view>
  45. </template>
  46. <script>
  47. // import contentPage from './components/content.vue'
  48. // 图表
  49. import uCharts from "@/components/ucharts/ucharts.js";
  50. import * as infoApi from '@/api/info/index.js';
  51. import dayjs from "@/plugin/dayjs/dayjs.min.js";
  52. import {
  53. mapGetters
  54. } from "vuex";
  55. // import uCharts from "@/components/u-charts/u-charts.js";
  56. var _self;
  57. var canvaRing = null;
  58. var canvaArea = null;
  59. var canvaGauge = null;
  60. var canvaPie = null;
  61. var canvaColumn = null;
  62. var canvaFunnel = null;
  63. var canvaWord = null;
  64. export default {
  65. // components: {
  66. // contentPage
  67. // },
  68. data() {
  69. return {
  70. cWidth: '',
  71. cHeight: '',
  72. pixelRatio: 1,
  73. // dayValue: new Date(),
  74. defaultDate: [], //默认一周内
  75. showPicker: false, //日
  76. infoData: {}, //日数据
  77. minDate: new Date(2023, 0, 1).getTime(),
  78. list: [{
  79. time: '09:00',
  80. num: 63
  81. }, {
  82. time: '09:10',
  83. num: 63
  84. }, {
  85. time: '09:10',
  86. num: 63
  87. }],
  88. // 折线图
  89. Area: {
  90. categories: [],
  91. // categories: ['08:22','08:22','08:22','08:22'],
  92. series: [{
  93. name: '翻转次数',
  94. data: [],
  95. // data: [68,89,66,79],
  96. color: '#F35546'
  97. }]
  98. }
  99. };
  100. },
  101. computed: mapGetters(['deviceId']),
  102. async onLoad() {
  103. _self = this;
  104. this.cWidth = uni.upx2px(680);
  105. this.cHeight = uni.upx2px(400);
  106. this.defaultDate = [new Date(new Date().getTime() - 6 * 24 * 60 * 60 * 1000).getTime(), new Date()
  107. .getTime()
  108. ]
  109. await this.getData()
  110. this.getServerData();
  111. },
  112. mounted() {
  113. },
  114. methods: {
  115. getData() {
  116. let params = {
  117. deviceId: this.deviceId,
  118. startTime: `${this.formatDate(this.defaultDate[0])} 00:00:00`,
  119. endTime: `${this.formatDate(this.defaultDate[1])} 23:59:59`,
  120. }
  121. console.log(params, 111);
  122. return infoApi.getSleep(params).then(res => {
  123. console.log(res, 44);
  124. if (res.data === null) {
  125. this.infoData = {}
  126. this.infoData.list = []
  127. this.Area.categories = []
  128. }
  129. if (res.code === 0 && res.data.list.length) {
  130. this.infoData = res.data
  131. // 组装接口数据。上方折线图若超过10条,截取10条
  132. let categoriesArr = res.data.list.map(item => this.formatHHmm(item.createTime))
  133. let seriesArr = res.data.list.map(item => item.rollTimes)
  134. this.Area.categories = categoriesArr.length > 10 ? categoriesArr.slice(-10) :
  135. categoriesArr
  136. this.Area.series[0].data = seriesArr.length > 10 ? seriesArr.slice(-10) : seriesArr
  137. }
  138. })
  139. .catch(err => {
  140. return this.$util.Tips({
  141. title: err,
  142. // icon: 'error'
  143. });
  144. });
  145. },
  146. formatHms: function(date) {
  147. return dayjs(date).format("YYYY-MM-DD HH:mm:ss");
  148. },
  149. formatDate: function(date) {
  150. return dayjs(date).format("YYYY-MM-DD");
  151. },
  152. formatHHmm: function(date) {
  153. return dayjs(date).format("MM-DD");
  154. },
  155. async onConfirm(date) {
  156. console.log(date, 777);
  157. this.defaultDate = date.detail;
  158. await this.getData()
  159. this.getServerData()
  160. this.showPicker = false;
  161. },
  162. getServerData() {
  163. _self.showArea("canvasArea", this.chartData);
  164. },
  165. // 折线图
  166. showArea(canvasId, chartData) {
  167. canvaArea = new uCharts({
  168. $this: _self,
  169. canvasId: canvasId,
  170. type: 'area',
  171. fontSize: 11,
  172. legend: false,
  173. dataLabel: true,
  174. dataPointShape: true,
  175. background: '#FFFFFF',
  176. pixelRatio: _self.pixelRatio,
  177. categories: _self.Area.categories,
  178. series: _self.Area.series,
  179. animation: true,
  180. padding: [20, 10, 10, 10],
  181. xAxis: {
  182. type: 'grid',
  183. gridColor: '#CCCCCC',
  184. gridType: 'solid',
  185. dashLength: 8,
  186. disableGrid: true,
  187. rotateLabel:true,
  188. rotateAngle:-50,
  189. },
  190. yAxis: {
  191. gridType: 'dash',
  192. gridColor: '#CCCCCC',
  193. dashLength: 8,
  194. splitNumber: 5,
  195. min: 0,
  196. // max: 180,
  197. },
  198. width: _self.cWidth * _self.pixelRatio,
  199. height: _self.cHeight * _self.pixelRatio,
  200. extra: {
  201. area: {
  202. type: 'straight',
  203. opacity: 0.2,
  204. addLine: true,
  205. width: 2
  206. }
  207. }
  208. });
  209. },
  210. touchArea(e) {
  211. canvaArea.showToolTip(e, {
  212. format: function(item, category) {
  213. return item.name + ' ' + category + ' ' + ':' + item.data
  214. }
  215. });
  216. },
  217. }
  218. };
  219. </script>
  220. <style lang="scss" scoped>
  221. .top-box {
  222. padding: 28rpx 32rpx 19rpx;
  223. background-color: #fff;
  224. .container-top {
  225. display: flex;
  226. align-items: center;
  227. justify-content: space-between;
  228. margin-bottom: 28rpx;
  229. .top-left {
  230. .word {
  231. font-size: 36rpx;
  232. font-weight: 500;
  233. color: #000000;
  234. }
  235. text {
  236. font-size: 24rpx;
  237. font-weight: 500;
  238. color: #777777;
  239. line-height: 33rpx;
  240. }
  241. }
  242. .top-right {
  243. width: 32rpx;
  244. height: 32rpx;
  245. image {
  246. width: 32rpx;
  247. height: 32rpx;
  248. }
  249. }
  250. }
  251. .chartsMain {
  252. width: 100%;
  253. // height: 450rpx;
  254. // box-sizing: border-box;
  255. background: #fff;
  256. border-top: 2rpx solid #f2f2f2;
  257. text-align: center;
  258. image {
  259. width: 70%;
  260. // height: 100%;
  261. }
  262. .charts {
  263. width: 680rpx;
  264. height: 400rpx;
  265. box-sizing: border-box;
  266. }
  267. }
  268. }
  269. .content-box {
  270. background-color: #F7F7F7;
  271. // height: 100vh;
  272. .chartsMain {
  273. width: 750rpx;
  274. height: 450rpx;
  275. padding-top: 15rpx;
  276. background: #fff;
  277. margin-bottom: 24rpx;
  278. border-top: 2rpx solid #f2f2f2;
  279. .charts {
  280. width: 750rpx;
  281. height: 450rpx;
  282. box-sizing: border-box;
  283. }
  284. }
  285. .number-box {
  286. height: 131rpx;
  287. background-color: #fff;
  288. display: flex;
  289. margin-top: 16rpx;
  290. padding: 16rpx 32rpx;
  291. justify-content: space-around;
  292. .box-item {
  293. width: 218rpx;
  294. padding: 10rpx 16rpx;
  295. box-sizing: border-box;
  296. border-radius: 12rpx;
  297. border: 2rpx solid rgba(119, 119, 119, 0.3);
  298. text {
  299. font-size: 24rpx;
  300. font-weight: 400;
  301. color: #777777;
  302. }
  303. .item-under {
  304. display: flex;
  305. justify-content: space-between;
  306. align-items: center;
  307. margin-top: 12rpx;
  308. .item-under-left {
  309. image {
  310. width: 32rpx;
  311. height: 32rpx;
  312. }
  313. text {
  314. margin-left: 15rpx;
  315. font-size: 32rpx;
  316. font-weight: 400;
  317. color: #000000;
  318. }
  319. }
  320. text {
  321. font-size: 24rpx;
  322. font-weight: 400;
  323. color: #777777;
  324. }
  325. }
  326. }
  327. }
  328. .word-box {
  329. margin-top: 16rpx;
  330. background-color: #fff;
  331. padding: 32rpx;
  332. font-size: 32rpx;
  333. font-weight: 600;
  334. color: #000000;
  335. }
  336. .list-box {
  337. margin-top: 16rpx;
  338. background-color: #fff;
  339. padding: 0 32rpx;
  340. .list-box-item {
  341. height: 88rpx;
  342. display: flex;
  343. align-items: center;
  344. justify-content: space-between;
  345. .list-box-left {
  346. display: flex;
  347. align-items: center;
  348. image {
  349. width: 48rpx;
  350. height: 48rpx;
  351. }
  352. text {
  353. margin-left: 32rpx;
  354. font-size: 32rpx;
  355. font-weight: 400;
  356. color: #000000;
  357. }
  358. }
  359. .list-box-right {
  360. display: flex;
  361. font-size: 32rpx;
  362. font-weight: 600;
  363. color: #000000;
  364. .num {
  365. margin-right: 30rpx;
  366. }
  367. }
  368. }
  369. }
  370. }
  371. </style>