WeekCalendarItem.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import { View, Text } from "@tarojs/components";
  2. import './WeekCalendarItem.scss'
  3. import { rpxToPx } from "@/utils/tools";
  4. import { useEffect, useState } from "react";
  5. import { ColorType } from "@/context/themes/color";
  6. import { TimeFormatter } from "@/utils/time_format";
  7. import dayjs from 'dayjs'
  8. import showAlert from "@/components/basic/Alert";
  9. import { title } from "process";
  10. const utc = require('dayjs/plugin/utc')
  11. const timezone = require('dayjs/plugin/timezone')
  12. dayjs.extend(utc)
  13. dayjs.extend(timezone)
  14. let timer
  15. export default function WeekCalendarItem(props: { data: any, isCurrentWeek: boolean,isFastSleep:boolean }) {
  16. const [charts, setCharts] = useState([])
  17. const [showCurrentTime, setShowCurrentTime] = useState(false)
  18. const [position, setPosition] = useState({ left: 0, top: 0 })
  19. useEffect(() => {
  20. if (props.isCurrentWeek) {
  21. if (timer)
  22. clearInterval(timer)
  23. if (props.isCurrentWeek) {
  24. timer = setInterval(() => {
  25. getPosition()
  26. }, 6000)
  27. getPosition()
  28. }
  29. setShowCurrentTime(props.isCurrentWeek)
  30. }
  31. else {
  32. if (timer)
  33. clearInterval(timer)
  34. }
  35. var array: any = []
  36. for (var i = 0; i < 7; i++) {
  37. var start = props.data.start + 24 * 3600 * 1000 * i
  38. var end = props.data.start + (24 * 3600 * 1000) * (i + 1)
  39. var fasts: any = []
  40. var sleeps: any = []
  41. array.push({
  42. start,
  43. end,
  44. fasts,
  45. sleeps
  46. })
  47. props.data.list.map((item, index) => {
  48. var isFast = item.scenario == 'FAST'
  49. var real_start = item.real_start_time
  50. var real_end = item.real_end_time
  51. //睡眠数据下,以fast_end为准
  52. if (item.fast_real_end_timezone && item.fast_real_end_timezone.id){
  53. var strEnd = TimeFormatter.tzTimeFormateLocalTime(real_end, item.fast_real_end_timezone.id,'YYYY-MM-DDTHH:mm:ss')
  54. var duration = real_end - real_start
  55. real_end = new Date(strEnd).getTime()
  56. real_start = real_end - duration
  57. }
  58. else if (item.real_end_timezone && item.real_end_timezone.id) {
  59. var strEnd = TimeFormatter.tzTimeFormateLocalTime(real_end, item.real_end_timezone.id,'YYYY-MM-DDTHH:mm:ss')
  60. var duration = real_end - real_start
  61. real_end = new Date(strEnd).getTime()
  62. real_start = real_end - duration
  63. }
  64. var range = getIntersection(start, end, real_start, real_end)
  65. if (range) {
  66. var begin = (range[0] - start) / (24 * 3600 * 1000)
  67. var height = (range[1] - range[0]) / (24 * 3600 * 1000)
  68. if (isFast) {
  69. fasts.push({
  70. begin,
  71. height
  72. })
  73. }
  74. else {
  75. sleeps.push({
  76. begin, height
  77. })
  78. }
  79. }
  80. })
  81. }
  82. setCharts(array)
  83. // if (array.length>0 && props.isCurrentWeek){
  84. // showAlert({
  85. // title:'111',
  86. // content:JSON.stringify(props.data)
  87. // })
  88. // }
  89. return () => {
  90. timer && clearInterval(timer)
  91. }
  92. }, [props.data])
  93. useEffect(() => {
  94. if (timer)
  95. clearInterval(timer)
  96. if (props.isCurrentWeek) {
  97. timer = setInterval(() => {
  98. getPosition()
  99. }, 60000)
  100. getPosition()
  101. }
  102. setShowCurrentTime(props.isCurrentWeek)
  103. }, [props.isCurrentWeek])
  104. function getPosition() {
  105. var now = new Date().getTime()
  106. var start = props.data.start
  107. var index = Math.floor((now - start) / (3600 * 24 * 1000))
  108. var left = (now - start) % (3600 * 24 * 1000)
  109. var top = left / (3600 * 24 * 1000) * 400
  110. if (top >= 398) {
  111. top = 398
  112. }
  113. setPosition({
  114. left: rpxToPx(94 * index),
  115. top: rpxToPx(top)
  116. })
  117. }
  118. function getIntersection(start1, end1, start2, end2) {
  119. // 确保 start1 小于等于 end1,start2 小于等于 end2
  120. if (start1 > end1) {
  121. [start1, end1] = [end1, start1];
  122. }
  123. if (start2 > end2) {
  124. [start2, end2] = [end2, start2];
  125. }
  126. // 计算相交的时间戳
  127. var intersectionStart = Math.max(start1, start2);
  128. var intersectionEnd = Math.min(end1, end2);
  129. // 检查是否存在相交时间戳
  130. if (intersectionStart <= intersectionEnd) {
  131. // 返回相交的时间戳
  132. return [intersectionStart, intersectionEnd];
  133. } else {
  134. // 不存在相交时间戳
  135. return null;
  136. }
  137. }
  138. function isTop() {
  139. var now = new Date()
  140. if (now.getHours() >= 12) {
  141. return true
  142. }
  143. return false
  144. }
  145. function weekIndex() {
  146. var week = new Date().getDay()
  147. if (!isTop()) {
  148. return week - 1
  149. }
  150. return week
  151. }
  152. return <View className="chart_content" style={{ width: parseInt(rpxToPx(658) + '') }}>
  153. <View style={{ height: parseInt(rpxToPx(60) + '') }}>
  154. <View className="chart_top_week">
  155. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(0) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 0 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(0)}</Text>
  156. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 1) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 1 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(1)}</Text>
  157. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 2) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 2 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(2)}</Text>
  158. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 3) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 3 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(3)}</Text>
  159. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 4) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 4 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(4)}</Text>
  160. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 5) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 5 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(5)}</Text>
  161. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 6) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 6 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(6)}</Text>
  162. </View>
  163. </View>
  164. <View className="chart_detail">
  165. <View className="verticalLine" style={{ left: 0 }} />
  166. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 1) + '') }} />
  167. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 2) + '') }} />
  168. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 3) + '') }} />
  169. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 4) + '') }} />
  170. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 5) + '') }} />
  171. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 6) + '') }} />
  172. <View className="horizontalLine" style={{ top: rpxToPx(100), backgroundColor: '#262626' }} />
  173. <View className="horizontalLine" style={{ top: rpxToPx(200), backgroundColor: '#383838' }} />
  174. <View className="horizontalLine" style={{ top: rpxToPx(300), backgroundColor: '#262626' }} />
  175. {
  176. charts.map((item, index) => {
  177. return <View className="lineContent" key={index * 9527} style={{ left: rpxToPx(94 * index) }}>
  178. {
  179. (item as any).fasts.length > 0 &&
  180. <View className="lineBgView">
  181. {
  182. (item as any).fasts.map((obj, k) => {
  183. return <View key={k} className="detailLine" style={{
  184. backgroundColor: props.isFastSleep?ColorType.fast:ColorType.food,
  185. top: rpxToPx(obj.begin * 400),
  186. height: rpxToPx(obj.height * 400)
  187. }} />
  188. })
  189. }
  190. </View>
  191. }
  192. {
  193. (item as any).sleeps.length > 0 &&
  194. <View className="lineBgView">
  195. {
  196. (item as any).sleeps.map((obj, j) => {
  197. return <View key={j} className="detailLine" style={{
  198. backgroundColor: props.isFastSleep?ColorType.sleep:ColorType.activity,
  199. top: rpxToPx(obj.begin * 400),
  200. height: rpxToPx(obj.height * 400)
  201. }} />
  202. })
  203. }
  204. </View>
  205. }
  206. </View>
  207. })
  208. }
  209. {
  210. showCurrentTime && <View className="currentLine" style={{
  211. position: 'absolute',
  212. left: position.left,
  213. top: position.top,
  214. width: rpxToPx(94 - 1),
  215. backgroundColor: 'red'
  216. }}>
  217. {/* <View className={position.top < rpxToPx(400)-40 ? 'currentTime currentTimeBottom' : 'currentTime currentTimeTop'}>{TimeFormatter.timelineFormatTime(new Date().getTime())}</View> */}
  218. </View>
  219. }
  220. </View>
  221. <View style={{ height: parseInt(rpxToPx(60) + '') }}>
  222. <View className="chart_bottom_week">
  223. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(0) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 0 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(1)}</Text>
  224. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 1) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 1 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(2)}</Text>
  225. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 2) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 2 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(3)}</Text>
  226. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 3) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 3 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(4)}</Text>
  227. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 4) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 4 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(5)}</Text>
  228. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 5) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 5 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(6)}</Text>
  229. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 6) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == -1 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(0)}</Text>
  230. </View>
  231. </View>
  232. </View>
  233. }