move_schedule.tsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. import { View, Text, Image, Switch } from "@tarojs/components";
  2. import './move_schedule.scss'
  3. import { useRouter } from "@tarojs/taro";
  4. import { useEffect, useState } from "react";
  5. import { createSchedule, getActiveMovesCurrent, getMoveSchedules } from "@/services/health";
  6. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  7. import { getThemeColor } from "@/features/health/hooks/health_hooks";
  8. import { rpxToPx } from "@/utils/tools";
  9. import NewHeader, { NewHeaderType } from "../components/new_header";
  10. import StatusIndicator, { StatusType } from "../base/status_indicator";
  11. import { MainColorType } from "@/context/themes/color";
  12. import { IconNotification, IconNotificationOff } from "@/components/basic/Icons";
  13. import ConsoleCell from "../components/console_cell";
  14. import Layout from "@/components/layout/layout";
  15. import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
  16. import Card from "../components/card";
  17. import { useTranslation } from "react-i18next";
  18. import { useSelector } from "react-redux";
  19. import showAlert from "@/components/basic/Alert";
  20. import NewSwitch from "@/components/basic/NewSwitch";
  21. let useRoute;
  22. let useNavigation;
  23. let scenario = '';
  24. if (process.env.TARO_ENV == 'rn') {
  25. useRoute = require("@react-navigation/native").useRoute
  26. useNavigation = require("@react-navigation/native").useNavigation
  27. }
  28. /*
  29. https://fast-dev.oss-cn-beijing.aliyuncs.com/users/b13170f6916a27713c118a5ce75ea74a/food-journal/2024/88620d96-c898-472f-8783-d425bb91333a_20240910114628_698.png
  30. https://fast-dev.oss-cn-beijing.aliyuncs.com/users/b13170f6916a27713c118a5ce75ea74a/food-journal/2024/88620d96-c898-472f-8783-d425bb91333a_20240910114628_698.png?x-oss-process=image/resize,w_50,limit_0
  31. */
  32. let timer;
  33. export default function MoveSchedule() {
  34. let router
  35. let navigation;
  36. if (useNavigation) {
  37. navigation = useNavigation()
  38. }
  39. if (process.env.TARO_ENV == 'rn') {
  40. router = useRoute()
  41. }
  42. else {
  43. router = useRouter()
  44. }
  45. const [hours, setHours] = useState<any>([])
  46. const [loaded, setLoaded] = useState(false)
  47. const permission = useSelector((state: any) => state.permission);
  48. const [count, setCount] = useState(1)
  49. const { t } = useTranslation()
  50. useEffect(() => {
  51. getData()
  52. timer = setInterval(() => {
  53. setCount((count => count + 1))
  54. var now = new Date()
  55. if (now.getMinutes() == 10 && now.getSeconds() == 0) {
  56. getData()
  57. }
  58. }, 1000)
  59. // getMoveSchedules().then(res => {
  60. // console.log(hours)
  61. // setLoaded(true)
  62. // })
  63. return () => {
  64. clearInterval(timer)
  65. }
  66. }, [])
  67. global.upcomingSchedule = ()=>{
  68. getData()
  69. }
  70. function getData() {
  71. getActiveMovesCurrent().then(res => {
  72. setLoaded(true)
  73. setHours((res as any).hours)
  74. })
  75. }
  76. // console.log(JSON.parse(router.params.hours))
  77. if (!loaded) return <View />
  78. function formatTimeInterval(startTimestamp, endTimestamp) {
  79. // 计算时间间隔(以秒为单位)
  80. const intervalSeconds = Math.floor((endTimestamp - startTimestamp) / 1000);
  81. // 处理负值的情况
  82. if (intervalSeconds < 0) {
  83. throw new Error("End timestamp must be greater than start timestamp");
  84. }
  85. // 如果时间间隔大于1小时
  86. if (intervalSeconds >= 3600) {
  87. const hours = Math.floor(intervalSeconds / 3600);
  88. const minutes = Math.floor((intervalSeconds % 3600) / 60);
  89. const seconds = intervalSeconds % 60;
  90. return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
  91. } else {
  92. // 如果时间间隔小于1小时
  93. const minutes = Math.floor(intervalSeconds / 60);
  94. const seconds = intervalSeconds % 60;
  95. return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
  96. }
  97. }
  98. function firstTime(index) {
  99. return ''
  100. var firstIndex = -1;
  101. var selHour = -1;
  102. for (var i = 0; i < hours.length; i++) {
  103. if (hours[i].status == 'WFS') {
  104. firstIndex = i;
  105. selHour = hours[i].hour
  106. break;
  107. }
  108. }
  109. if (firstIndex == index) {
  110. var endDate = new Date()
  111. endDate.setHours(selHour)
  112. endDate.setMinutes(10);
  113. endDate.setSeconds(0);
  114. endDate.setMilliseconds(0);
  115. var endTimestamp = endDate.getTime() + 3600 * 1000;
  116. if (new Date().getTime() > endTimestamp) {
  117. endTimestamp += 24 * 3600 * 1000
  118. }
  119. if (endTimestamp - new Date().getTime() > 20 * 60 * 1000) {
  120. return <Text>countdown {formatTimeInterval(new Date().getTime(), endTimestamp)} </Text>
  121. }
  122. else if (endTimestamp - new Date().getTime() < 10 * 60 * 1000) {
  123. <Text style={{ color: getThemeColor('ACTIVE') }}>Closing soon in {formatTimeInterval(new Date().getTime(), endTimestamp)} </Text>
  124. }
  125. return <Text>available </Text>
  126. }
  127. return <Text></Text>
  128. }
  129. function detailContent() {
  130. return <View style={{ display: 'flex', flexDirection: 'column' }}>
  131. <NewHeader type={NewHeaderType.left} title={t('health.upcomings')} />
  132. {
  133. hours.length == 0 && <View style={{ display: 'flex', flex: 1, flexDirection: 'column', alignItems: 'center', marginTop: rpxToPx(110) }}>
  134. <Image src={require('@assets/_health/sleep2.png')} style={{ width: rpxToPx(64), height: rpxToPx(64) }} />
  135. <Text style={{ marginTop: rpxToPx(24), fontSize: rpxToPx(50), fontWeight: 'bold', color: '#B2B2B2' }}>{t('health.sleep_well')}</Text>
  136. </View>
  137. }
  138. <Card>
  139. <View style={{ display: 'flex', flexDirection: 'column', width: rpxToPx(700) }}>
  140. {
  141. hours.map((item, index) => {
  142. var start = item.hour
  143. var open: any = start
  144. var end = start + 1
  145. start = (start + '').padStart(2, '0')
  146. end = (end + '').padStart(2, '0')
  147. open = (open + '').padStart(2, '0')
  148. if (item.status != 'WFS') return <View key={index} />
  149. return <ConsoleCell key={index}
  150. moveCell
  151. status={<StatusIndicator type={StatusType.normal}
  152. color={MainColorType.active}
  153. text={t('health.waking_hour') + (index + 1)} />}
  154. title={t('health.check_begin_at2', { time: open + ':50' })}
  155. description={`${parseInt(start) < new Date().getHours() ? '' : ''}${start}:00-${end}:00`}
  156. subDesc={<Text className="schedule_item_time"> {firstTime(index)}</Text>}
  157. right={<View style={{
  158. display: 'flex',
  159. flexDirection: 'row',
  160. alignItems: 'center'
  161. }}>
  162. {
  163. item.reminder && permission.wxPubFollow ? <IconNotification color={MainColorType.g03} width={rpxToPx(28)} /> : <IconNotificationOff color={MainColorType.g03} width={rpxToPx(28)} />
  164. }
  165. <View style={{ width: rpxToPx(12) }} />
  166. <NewSwitch
  167. disable={!permission.wxPubFollow}
  168. onClick={() => {
  169. if (!permission.wxPubFollow) {
  170. showAlert({
  171. title: t('health.reminder_alert_title'),
  172. content: '',
  173. cancelText: t('health.reminder_cancel'),
  174. confirmText: t('health.reminder_confirm'),
  175. showCancel: true,
  176. cancel: () => {
  177. },
  178. confirm: () => {
  179. global.followWxPub()
  180. // checkNotification()
  181. }
  182. })
  183. return
  184. }
  185. }}
  186. checked={item.reminder && permission.wxPubFollow} color={getThemeColor('ACTIVE')} onChange={e => {
  187. console.log(item)
  188. if (!permission.wxPubFollow) {
  189. showAlert({
  190. title: t('health.reminder_alert_title'),
  191. content: '',
  192. cancelText: t('health.reminder_cancel'),
  193. confirmText: t('health.reminder_confirm'),
  194. showCancel: true,
  195. cancel: () => {
  196. },
  197. confirm: () => {
  198. global.followWxPub()
  199. // checkNotification()
  200. }
  201. })
  202. return
  203. }
  204. createSchedule({
  205. schedules: [{
  206. id: item.schedule_id,
  207. reminder: e.detail.value
  208. }],
  209. }).then(res => {
  210. getData()
  211. if (global.refreshWindow) {
  212. global.refreshWindow()
  213. }
  214. if (global.refreshSchedules) {
  215. global.refreshSchedules()
  216. }
  217. if (global.updateMove) {
  218. global.updateMove()
  219. }
  220. })
  221. }} />
  222. {/* <Switch checked={item.reminder && permission.wxPubFollow} color={getThemeColor('ACTIVE')} onChange={e => {
  223. console.log(item)
  224. if (!permission.wxPubFollow) {
  225. showAlert({
  226. title: t('health.reminder_alert_title'),
  227. content: '',
  228. cancelText: t('health.reminder_cancel'),
  229. confirmText: t('health.reminder_confirm'),
  230. showCancel: true,
  231. cancel: () => {
  232. },
  233. confirm: () => {
  234. global.followWxPub()
  235. // checkNotification()
  236. }
  237. })
  238. return
  239. }
  240. createSchedule({
  241. schedules: [{
  242. id: item.schedule_id,
  243. reminder: e.detail.value
  244. }],
  245. }).then(res => {
  246. getData()
  247. if (global.refreshWindow) {
  248. global.refreshWindow()
  249. }
  250. if (global.refreshSchedules) {
  251. global.refreshSchedules()
  252. }
  253. if (global.updateMove) {
  254. global.updateMove()
  255. }
  256. })
  257. }} /> */}
  258. <View style={{ marginRight: -rpxToPx(14) }} />
  259. </View>}
  260. disable={true}
  261. onClick={() => { }}
  262. showLine={true}
  263. fullLine={false}
  264. />
  265. })
  266. }
  267. </View>
  268. </Card>
  269. <Text className="no_more" style={{ color: '#5C7099' }} onClick={() => {
  270. jumpPage('./move_setting_reminder')
  271. }}>{t('health.see_full_check')}</Text>
  272. </View>
  273. }
  274. return <Layout children={detailContent()}
  275. // title={router.params.title}
  276. header={null}
  277. secondPage={true}
  278. titleColor={'#fff'}
  279. title={t('health.upcomings')}
  280. type={TemplateType.customHeader}
  281. titleShowStyle={NaviBarTitleShowType.scrollToShow} />
  282. }