swapStats.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <template>
  2. <view class="page-view">
  3. <top-return color="#FFF" text="日常记录" refresh="true"></top-return>
  4. <!-- 背景 -->
  5. <view class="bg-box1"></view>
  6. <!-- 页面标题内容 -->
  7. <view class="top-box">
  8. <view class="flex-baseline">
  9. <view class="info-title" style="margin-left: 0;">{{dayTime.split('月')[0]}}</view>
  10. <view class="info-subtitle">月</view>
  11. <view class="info-title">{{dayTime.split('月')[1]}}
  12. </view>
  13. <view class="info-subtitle">日</view>
  14. <view class="info-title" style="margin-left: 20rpx;">{{weekTime}}</view>
  15. </view>
  16. <view class="flex-baseline">
  17. <view class="data-subtitle" style="margin-left: 0;">记录今日孩子表现吧</view>
  18. </view>
  19. </view>
  20. <!-- 记录模块 -->
  21. <view class="module-box" style="margin-top: 20rpx;">
  22. <view class="module-item" v-for="(item,index) in moduleData" :key="index" :style="item.color"
  23. @click="setTime(index)">
  24. <view class="module-item-subtext" style="margin-left: 30rpx;">{{item.text}}</view>
  25. <view class="flex-baseline" style="margin-left: 30rpx;" v-if="item.numData === ''">
  26. <text class="module-item-text">记录</text>
  27. <text class="module-item-subtext" style="margin-left: 8rpx;opacity:0.8;">今日时长</text>
  28. </view>
  29. <view class="flex-baseline" style="margin-left: 30rpx;"
  30. v-if="item.numData.includes('小时') && item.numData != ''">
  31. <text class="module-item-text">{{item.numData.split('小时')[0]}}</text>
  32. <text class="module-item-subtext" style="margin-left: 8rpx;opacity:0.8;">小时</text>
  33. <text class="module-item-text"
  34. style="margin-left: 8rpx;">{{item.numData.split('小时')[1].replace('分','')}}</text>
  35. <text class="module-item-subtext" style="margin-left: 8rpx;opacity:0.8;">分钟</text>
  36. </view>
  37. <view class="flex-baseline" style="margin-left: 30rpx;"
  38. v-if="item.numData.includes('小时') === false && item.numData != ''">
  39. <text class="module-item-text" style="margin-left: 8rpx;">{{item.numData.replace('分','')}}</text>
  40. <text class="module-item-subtext" style="margin-left: 8rpx;opacity:0.8;">分钟</text>
  41. </view>
  42. <view :class="item.icon"></view>
  43. </view>
  44. </view>
  45. <!-- 时间选择器 -->
  46. <u-picker :show="setTimePicker" :columns="pickerList" @confirm="pickerConfirm" @cancel="cancel">
  47. </u-picker>
  48. <!-- 统计列表 -->
  49. <view class="card-view" style="margin-top: 0;">
  50. <!-- 统计列表 -->
  51. <view class="flex-column-box" style="margin-left: 20rpx;">
  52. <view class="title" style="font-size: 32rpx;">近期统计</view>
  53. <view class="bottom-tag"
  54. style="background-image: linear-gradient(to right, #4169E1, rgba(255, 255, 255, 0.01));"></view>
  55. </view>
  56. <!-- 总成绩对比 -->
  57. <view class="card-item" style="width: 100%;">
  58. <view class="card-title">
  59. <view class="front-tag"></view>
  60. <view class="title">学习娱乐时长对比</view>
  61. </view>
  62. <view class="chart-box">
  63. <qiun-data-charts type="column" ontouch="true" :chartData="swapChartData[0]"
  64. tooltipFormat='tooltipHourColum' :canvas2d="true" canvasId="swap_chart1" />
  65. </view>
  66. </view>
  67. <!-- 单科与平均对比 -->
  68. <view class="card-item">
  69. <view class="card-title">
  70. <view class="front-tag"></view>
  71. <view class="title">近期运动记录</view>
  72. </view>
  73. <view class="chart-box" style="height: 350rpx;">
  74. <qiun-data-charts type="pie" :chartData="swapChartData[1]" tooltipFormat='pieMinute'
  75. :canvas2d="true" canvasId="swap_chart2" />
  76. </view>
  77. </view>
  78. <view class="card-item">
  79. <view class="card-title">
  80. <view class="front-tag"></view>
  81. <view class="title">近期睡眠记录</view>
  82. </view>
  83. <view class="chart-box" style="height: 350rpx;">
  84. <qiun-data-charts type="ring" :chartData="swapChartData[2]" tooltipFormat='pieHour' :canvas2d="true"
  85. canvasId="swap_chart3" :opts="ringOpts" />
  86. </view>
  87. </view>
  88. </view>
  89. </view>
  90. </template>
  91. <script>
  92. import {
  93. mapState,
  94. mapMutations
  95. } from 'vuex'
  96. export default {
  97. computed: {
  98. ...mapState('m_chart', ['swapChartData'])
  99. },
  100. data() {
  101. return {
  102. //记录卡片
  103. moduleData: [{
  104. text: '学习时长',
  105. color: 'background-color: #4169E1;',
  106. icon: 't-icon t-icon-bianjibi',
  107. numData: '',
  108. },
  109. {
  110. text: '娱乐时长',
  111. color: 'background-color: #ff5959;',
  112. icon: 't-icon t-icon-leimucuyule',
  113. numData: '',
  114. },
  115. {
  116. text: '运动时长',
  117. color: 'background-color: #ff8caf;',
  118. icon: 't-icon t-icon-yundong',
  119. numData: '',
  120. },
  121. {
  122. text: '睡眠时长',
  123. color: 'background-color: #f9c752;',
  124. icon: 't-icon t-icon-a-icon_wananyueliangshuimian',
  125. numData: '',
  126. }
  127. ],
  128. //标题配置
  129. ringOpts: {},
  130. //当前记录卡片
  131. cardCurrent: 5,
  132. //选择器
  133. setTimePicker: false,
  134. //时间表
  135. pickerList: [
  136. ['0小时', '1小时', '2小时', '3小时', '4小时', '5小时', '6小时', '7小时', '8小时', '9小时', '10小时'],
  137. ['5分', '10分', '15分', '20分', '25分', '30分', '35分', '40分', '45分', '50分', '55分']
  138. ],
  139. //历史数据
  140. dayTime: '',
  141. weekTime: '',
  142. //是否重新记录
  143. setTimeRecord: false
  144. }
  145. },
  146. onLoad() {
  147. this.init()
  148. },
  149. methods: {
  150. ...mapMutations('m_chart', ['updateSwapChartData']),
  151. ...mapMutations('m_parent', ['updateChildDailyData']),
  152. init() {
  153. this.getToday()
  154. this.getData()
  155. this.getRingOpts()
  156. },
  157. getToday() {
  158. this.dayTime = (new Date()).format('M-d').replace('-', '月')
  159. this.weekTime = "星期" + "日一二三四五六".charAt(new Date().getDay());
  160. },
  161. //记录信息初始化
  162. getData() {
  163. if (uni.getStorageSync('moduleData'))
  164. this.moduleData = JSON.parse(uni.getStorageSync('moduleData'));
  165. if (uni.getStorageSync('childDailyData'))
  166. this.historyData = JSON.parse(uni.getStorageSync('childDailyData'));
  167. this.saveToStudyChart()
  168. },
  169. //睡眠记录统计
  170. getRingOpts() {
  171. let sleepData = ''
  172. if (uni.getStorageSync('childDailyData'))
  173. sleepData = JSON.parse(uni.getStorageSync('childDailyData')).sleep;
  174. let sum = 0
  175. for (let i = 0; i < sleepData.length; i++) {
  176. sum += sleepData[i]
  177. }
  178. let sleepAvg = (sum / sleepData.length).toFixed(1)
  179. let opt = {
  180. title: {
  181. name: '平均睡眠',
  182. color: '#909399'
  183. },
  184. subtitle: {
  185. name: sleepAvg + ' 小时',
  186. color: '#4169E1'
  187. },
  188. }
  189. this.ringOpts = opt
  190. },
  191. //点击卡片唤起picker
  192. setTime(index) {
  193. if (this.moduleData[index].numData === '') {
  194. this.cardCurrent = index
  195. this.setTimePicker = true
  196. }
  197. if (this.moduleData[index].numData != '') {
  198. let that = this;
  199. uni.showModal({
  200. title: `今日${that.moduleData[index].text}已记录`,
  201. content: '需要重新记录吗?',
  202. success: function(res) {
  203. if (res.confirm) {
  204. that.cardCurrent = index
  205. that.setTimePicker = true
  206. that.setTimeRecord = true
  207. } else if (res.cancel) {
  208. console.log('取消记录');
  209. }
  210. }
  211. })
  212. }
  213. },
  214. //记录数据
  215. pickerConfirm(e) {
  216. if (this.setTimeRecord) {
  217. if (e.value[0] === '0小时') {
  218. this.moduleData[this.cardCurrent].numData = e.value[1]
  219. } else {
  220. this.moduleData[this.cardCurrent].numData = e.value[0] + e.value[1]
  221. }
  222. //转换为数据记录到图表中
  223. if (this.moduleData[this.cardCurrent].numData.includes('小时') === false) {
  224. let timeData = parseFloat((parseInt(this.moduleData[this.cardCurrent].numData.replace('分', '')) /
  225. 60)
  226. .toFixed(1))
  227. switch (this.cardCurrent) {
  228. case 0:
  229. this.historyData.study[6] = timeData
  230. break
  231. case 1:
  232. this.historyData.rest[6] = timeData
  233. break
  234. case 2:
  235. let numExercise = parseInt(this.moduleData[this.cardCurrent].numData.replace('分', ''))
  236. this.historyData.exercise[6] = numExercise
  237. break
  238. case 3:
  239. this.historyData.sleep[6] = timeData
  240. break
  241. }
  242. uni.setStorageSync('moduleData', JSON.stringify(this.moduleData))
  243. this.updateChildDailyData(this.historyData)
  244. this.saveToStudyChart()
  245. } else {
  246. let timeTemp = this.moduleData[this.cardCurrent].numData.replace('小时', '.').replace('分', '').split(
  247. '.')
  248. let timeData = parseInt(timeTemp[0]) + parseFloat((timeTemp[1] / 60).toFixed(1))
  249. switch (this.cardCurrent) {
  250. case 0:
  251. this.historyData.study[6] = timeData
  252. break
  253. case 1:
  254. this.historyData.rest[6] = timeData
  255. break
  256. case 2:
  257. let numExerciseData = parseInt(timeTemp[0] * 60) + parseFloat((timeTemp[1]))
  258. this.historyData.exercise[6] = numExerciseData
  259. break
  260. case 3:
  261. this.historyData.sleep[6] = timeData
  262. break
  263. }
  264. uni.setStorageSync('moduleData', JSON.stringify(this.moduleData))
  265. this.updateChildDailyData(this.historyData)
  266. this.saveToStudyChart()
  267. }
  268. this.setTimePicker = false
  269. this.setTimeRecord = false
  270. } else {
  271. if (e.value[0] === '0小时') {
  272. this.moduleData[this.cardCurrent].numData = e.value[1]
  273. } else {
  274. this.moduleData[this.cardCurrent].numData = e.value[0] + e.value[1]
  275. }
  276. //转换为数据记录到图表中
  277. if (this.moduleData[this.cardCurrent].numData.includes('小时') === false) {
  278. let timeData = parseFloat((parseInt(this.moduleData[this.cardCurrent].numData.replace('分', '')) /
  279. 60)
  280. .toFixed(1))
  281. switch (this.cardCurrent) {
  282. case 0:
  283. this.historyData.study.push(timeData)
  284. this.historyData.study.shift()
  285. break
  286. case 1:
  287. this.historyData.rest.push(timeData)
  288. this.historyData.rest.shift()
  289. break
  290. case 2:
  291. let numExercise = parseInt(this.moduleData[this.cardCurrent].numData.replace('分', ''))
  292. this.historyData.exercise.push(numExercise)
  293. this.historyData.exercise.shift()
  294. break
  295. case 3:
  296. this.historyData.sleep.push(timeData)
  297. this.historyData.sleep.shift()
  298. break
  299. }
  300. uni.setStorageSync('moduleData', JSON.stringify(this.moduleData))
  301. this.updateChildDailyData(this.historyData)
  302. this.saveToStudyChart()
  303. } else {
  304. let timeTemp = this.moduleData[this.cardCurrent].numData.replace('小时', '.').replace('分', '').split(
  305. '.')
  306. let timeData = parseInt(timeTemp[0]) + parseFloat((timeTemp[1] / 60).toFixed(1))
  307. switch (this.cardCurrent) {
  308. case 0:
  309. this.historyData.study.push(timeData)
  310. this.historyData.study.shift()
  311. break
  312. case 1:
  313. this.historyData.rest.push(timeData)
  314. this.historyData.rest.shift()
  315. break
  316. case 2:
  317. let numExerciseData = parseInt(timeTemp[0] * 60) + parseFloat((timeTemp[1]))
  318. this.historyData.exercise.push(numExerciseData)
  319. this.historyData.exercise.shift()
  320. break
  321. case 3:
  322. this.historyData.sleep.push(timeData)
  323. this.historyData.sleep.shift()
  324. break
  325. }
  326. uni.setStorageSync('moduleData', JSON.stringify(this.moduleData))
  327. this.updateChildDailyData(this.historyData)
  328. this.saveToStudyChart()
  329. }
  330. this.setTimePicker = false
  331. }
  332. },
  333. //取消
  334. cancel() {
  335. this.setTimePicker = false
  336. },
  337. //存储到图表
  338. saveToStudyChart() {
  339. let swapChartData = []
  340. let studyColumn = {
  341. categories: [],
  342. series: [{
  343. name: '自主学习',
  344. data: this.historyData.study
  345. },
  346. {
  347. name: '娱乐放松',
  348. data: this.historyData.rest
  349. }
  350. ]
  351. }
  352. //时间
  353. studyColumn.categories = this.$getRecentDateArray(this.historyData.study.length)
  354. //学习记录表数据记录
  355. switch (this.cardCurrent) {
  356. case 0:
  357. studyColumn.series[0].data = this.historyData.study
  358. break
  359. case 1:
  360. studyColumn.series[1].data = this.historyData.rest
  361. break
  362. }
  363. //运动记录表
  364. let exercisePie = {
  365. series: [{
  366. data: [{}, {}, {}, {}, {}, {}, {}]
  367. }]
  368. }
  369. //睡眠记录表
  370. let sleepRing = {
  371. series: [{
  372. data: [{}, {}, {}, {}, {}, {}, {}]
  373. }]
  374. }
  375. studyColumn.categories.forEach((value, index) => {
  376. exercisePie.series[0].data[index].name = value
  377. exercisePie.series[0].data[index].value = parseFloat((this.historyData.exercise[index])
  378. .toFixed(1))
  379. sleepRing.series[0].data[index].name = value
  380. sleepRing.series[0].data[index].value = this.historyData.sleep[index]
  381. })
  382. swapChartData.push(studyColumn)
  383. swapChartData.push(exercisePie)
  384. swapChartData.push(sleepRing)
  385. this.updateSwapChartData(swapChartData)
  386. this.getRingOpts()
  387. },
  388. }
  389. }
  390. </script>
  391. <style lang="scss">
  392. @import '@/subpkg/datalist/top_info.scss';
  393. .chart-box {
  394. width: 100%;
  395. height: 500rpx;
  396. }
  397. .flex-column-box {
  398. margin: 20rpx 0;
  399. display: flex;
  400. flex-direction: column;
  401. z-index: 55;
  402. }
  403. .module-box {
  404. display: flex;
  405. flex-flow: row wrap;
  406. margin: 0 20rpx;
  407. justify-content: space-between;
  408. .module-item {
  409. margin: 2% 0;
  410. width: 48%;
  411. height: auto;
  412. display: flex;
  413. flex-direction: column;
  414. padding: 24rpx 0 20rpx 0;
  415. background-color: #FFF;
  416. border-radius: 20rpx;
  417. justify-content: space-between;
  418. overflow: hidden;
  419. z-index: 3;
  420. .module-item-text {
  421. line-height: 80rpx;
  422. color: #FFF;
  423. font-size: 50rpx;
  424. font-family: YSfont;
  425. z-index: 5;
  426. }
  427. .module-item-subtext {
  428. line-height: 80rpx;
  429. color: #FFF;
  430. font-size: 30rpx;
  431. font-weight: bold;
  432. z-index: 5;
  433. }
  434. }
  435. .t-icon {
  436. width: 250rpx;
  437. height: 250rpx;
  438. margin: -250rpx 0 0 160rpx;
  439. z-index: 1;
  440. }
  441. }
  442. </style>