WeekCalendarItem.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. if (!props.isFastSleep) {
  50. isFast = item.scenario == 'EAT'
  51. }
  52. var real_start = item.real_start_time
  53. var real_end = item.real_end_time
  54. //睡眠数据下,以fast_end为准
  55. if (item.fast_real_end_timezone && item.fast_real_end_timezone.id) {
  56. var strEnd = TimeFormatter.tzTimeFormateLocalTime(real_end, item.fast_real_end_timezone.id, 'YYYY-MM-DDTHH:mm:ss')
  57. var duration = real_end - real_start
  58. real_end = new Date(strEnd).getTime()
  59. real_start = real_end - duration
  60. }
  61. else if (item.real_end_timezone && item.real_end_timezone.id) {
  62. var strEnd = TimeFormatter.tzTimeFormateLocalTime(real_end, item.real_end_timezone.id, 'YYYY-MM-DDTHH:mm:ss')
  63. var duration = real_end - real_start
  64. real_end = new Date(strEnd).getTime()
  65. real_start = real_end - duration
  66. }
  67. var range = getIntersection(start, end, real_start, real_end)
  68. if (range) {
  69. var begin = (range[0] - start) / (24 * 3600 * 1000)
  70. var height = (range[1] - range[0]) / (24 * 3600 * 1000)
  71. if (isFast) {
  72. fasts.push({
  73. begin,
  74. height
  75. })
  76. }
  77. else {
  78. sleeps.push({
  79. begin, height
  80. })
  81. }
  82. }
  83. })
  84. }
  85. setCharts(array)
  86. // if (array.length>0 && props.isCurrentWeek){
  87. // showAlert({
  88. // title:'111',
  89. // content:JSON.stringify(props.data)
  90. // })
  91. // }
  92. return () => {
  93. timer && clearInterval(timer)
  94. }
  95. }, [props.data])
  96. useEffect(() => {
  97. if (timer)
  98. clearInterval(timer)
  99. if (props.isCurrentWeek) {
  100. timer = setInterval(() => {
  101. getPosition()
  102. }, 60000)
  103. getPosition()
  104. }
  105. setShowCurrentTime(props.isCurrentWeek)
  106. }, [props.isCurrentWeek])
  107. function getPosition() {
  108. var now = new Date().getTime()
  109. var start = props.data.start
  110. var index = Math.floor((now - start) / (3600 * 24 * 1000))
  111. var left = (now - start) % (3600 * 24 * 1000)
  112. var top = left / (3600 * 24 * 1000) * 400
  113. if (top >= 398) {
  114. top = 398
  115. }
  116. setPosition({
  117. left: rpxToPx(94 * index),
  118. top: rpxToPx(top)
  119. })
  120. }
  121. function getIntersection(start1, end1, start2, end2) {
  122. // 确保 start1 小于等于 end1,start2 小于等于 end2
  123. if (start1 > end1) {
  124. [start1, end1] = [end1, start1];
  125. }
  126. if (start2 > end2) {
  127. [start2, end2] = [end2, start2];
  128. }
  129. // 计算相交的时间戳
  130. var intersectionStart = Math.max(start1, start2);
  131. var intersectionEnd = Math.min(end1, end2);
  132. // 检查是否存在相交时间戳
  133. if (intersectionStart <= intersectionEnd) {
  134. // 返回相交的时间戳
  135. return [intersectionStart, intersectionEnd];
  136. } else {
  137. // 不存在相交时间戳
  138. return null;
  139. }
  140. }
  141. function isTop() {
  142. var now = new Date()
  143. if (now.getHours() >= 12) {
  144. if (!props.isFastSleep) return false;
  145. return true
  146. }
  147. if (!props.isFastSleep) return true;
  148. return false
  149. }
  150. function weekIndex() {
  151. var week = new Date().getDay()
  152. if (!props.isFastSleep) {
  153. if (week == 0) {
  154. return 6;
  155. }
  156. return week - 1;
  157. }
  158. if (!isTop()) {
  159. return week - 1
  160. }
  161. return week
  162. }
  163. return <View className="chart_content" style={{ width: parseInt(rpxToPx(658) + '') }}>
  164. <View style={{ height: parseInt(rpxToPx(60) + '') }}>
  165. {
  166. props.isFastSleep ? <View className="chart_top_week">
  167. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(0) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 0 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(0)}</Text>
  168. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 1) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 1 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(1)}</Text>
  169. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 2) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 2 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(2)}</Text>
  170. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 3) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 3 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(3)}</Text>
  171. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 4) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 4 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(4)}</Text>
  172. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 5) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 5 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(5)}</Text>
  173. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 6) + ''), opacity: props.isCurrentWeek && isTop() && weekIndex() == 6 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(6)}</Text>
  174. </View> :
  175. <View className="chart_top_week">
  176. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(0) + ''), opacity: props.isCurrentWeek && weekIndex() == 0 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(1)}</Text>
  177. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 1) + ''), opacity: props.isCurrentWeek && weekIndex() == 1 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(2)}</Text>
  178. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 2) + ''), opacity: props.isCurrentWeek && weekIndex() == 2 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(3)}</Text>
  179. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 3) + ''), opacity: props.isCurrentWeek && weekIndex() == 3 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(4)}</Text>
  180. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 4) + ''), opacity: props.isCurrentWeek && weekIndex() == 4 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(5)}</Text>
  181. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 5) + ''), opacity: props.isCurrentWeek && weekIndex() == 5 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(6)}</Text>
  182. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 6) + ''), opacity: props.isCurrentWeek && weekIndex() == 6 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(0)}</Text>
  183. </View>
  184. }
  185. </View>
  186. <View className="chart_detail">
  187. <View className="verticalLine" style={{ left: 0 }} />
  188. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 1) + '') }} />
  189. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 2) + '') }} />
  190. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 3) + '') }} />
  191. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 4) + '') }} />
  192. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 5) + '') }} />
  193. <View className="verticalLine" style={{ left: parseInt(rpxToPx(94 * 6) + '') }} />
  194. <View className="horizontalLine" style={{ top: rpxToPx(100), backgroundColor: '#262626' }} />
  195. <View className="horizontalLine" style={{ top: rpxToPx(200), backgroundColor: '#383838' }} />
  196. <View className="horizontalLine" style={{ top: rpxToPx(300), backgroundColor: '#262626' }} />
  197. {
  198. charts.map((item, index) => {
  199. return <View className="lineContent" key={index * 9527} style={{ left: rpxToPx(94 * index) }}>
  200. {
  201. (item as any).fasts.length > 0 &&
  202. <View className="lineBgView">
  203. {
  204. (item as any).fasts.map((obj, k) => {
  205. return <View key={k} className="detailLine" style={{
  206. backgroundColor: props.isFastSleep ? ColorType.fast : ColorType.food,
  207. top: rpxToPx(obj.begin * 400),
  208. height: rpxToPx(obj.height * 400)
  209. }} />
  210. })
  211. }
  212. </View>
  213. }
  214. {
  215. (item as any).sleeps.length > 0 &&
  216. <View className="lineBgView">
  217. {
  218. (item as any).sleeps.map((obj, j) => {
  219. return <View key={j} className="detailLine" style={{
  220. backgroundColor: props.isFastSleep ? ColorType.sleep : ColorType.activity,
  221. top: rpxToPx(obj.begin * 400),
  222. height: rpxToPx(obj.height * 400)
  223. }} />
  224. })
  225. }
  226. </View>
  227. }
  228. </View>
  229. })
  230. }
  231. {
  232. showCurrentTime && <View className="currentLine" style={{
  233. position: 'absolute',
  234. left: position.left,
  235. top: position.top,
  236. width: rpxToPx(94 - 1),
  237. backgroundColor: 'red'
  238. }}>
  239. {/* <View className={position.top < rpxToPx(400)-40 ? 'currentTime currentTimeBottom' : 'currentTime currentTimeTop'}>{TimeFormatter.timelineFormatTime(new Date().getTime())}</View> */}
  240. </View>
  241. }
  242. </View>
  243. {
  244. props.isFastSleep && <View style={{ height: parseInt(rpxToPx(60) + '') }}>
  245. <View className="chart_bottom_week">
  246. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(0) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 0 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(1)}</Text>
  247. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 1) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 1 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(2)}</Text>
  248. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 2) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 2 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(3)}</Text>
  249. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 3) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 3 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(4)}</Text>
  250. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 4) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 4 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(5)}</Text>
  251. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 5) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == 5 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(6)}</Text>
  252. <Text className="chart_week_text" style={{ left: parseInt(rpxToPx(94 * 6) + ''), opacity: props.isCurrentWeek && !isTop() && weekIndex() == -1 ? 1 : 0.4 }}>{TimeFormatter.getDayOfWeek(0)}</Text>
  253. </View>
  254. </View>
  255. }
  256. </View>
  257. }