swapStats.vue 14 KB

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