LimitTimeoutPickers.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. import { PickerView, PickerViewColumn, View, Text } from "@tarojs/components";
  2. import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
  3. import './LimitPickers.scss'
  4. import Taro from "@tarojs/taro";
  5. import React from "react";
  6. import { useTranslation } from "react-i18next";
  7. import { TimeFormatter } from "@/utils/time_format";
  8. // export default function Component(props: { limit: number, onChange: Function, onCancel: Function,isRealTime?:boolean,limitDay?:number,time?:number,ref?:any }) {
  9. let todayIndex = -1
  10. const Component = forwardRef((props: {
  11. limit: number, onChange: Function, onCancel: Function,
  12. isRealTime?: boolean, limitDay?: number, time: number, themeColor?: string, title?: string,
  13. isFast?: boolean,
  14. endTimestamp?: number
  15. }, ref) => {
  16. const days: string[] = [];
  17. const today = new Date();
  18. const pickerDate = new Date(props.time + 3 * 24 * 3600 * 1000)
  19. var color = props.themeColor ? props.themeColor : '#ff0000'
  20. var alpha = alphaToHex(0.4)
  21. const [values, setValues] = useState([3, today.getHours(), today.getMinutes()])
  22. const [isDisableConfirm, setIsDisableConfirm] = useState(false)
  23. const [count, setCount] = useState(0)
  24. // const [todayIndex,setTodayIndex] = useState(-1)
  25. const { t } = useTranslation()
  26. function alphaToHex(alpha) {
  27. var alphaValue = Math.round(alpha * 255); // 将透明度乘以255并四舍五入
  28. var hexValue = alphaValue.toString(16); // 将整数转换为十六进制字符串
  29. if (hexValue.length === 1) {
  30. hexValue = "0" + hexValue; // 如果十六进制字符串只有一位,补零
  31. }
  32. return hexValue;
  33. }
  34. useEffect(() => {
  35. global.picker_time = global.set_time
  36. if (props.time) {
  37. var date = new Date(props.time)
  38. setValues([3, date.getHours(), date.getMinutes()])
  39. }
  40. }, [])
  41. // useEffect(() => {
  42. // setValues([6, today.getHours(), today.getMinutes()])
  43. // }, [props.limit])
  44. useEffect(() => {
  45. var now = new Date();
  46. if (!props.isRealTime) {
  47. now = new Date(global.set_time);
  48. }
  49. now.setDate(today.getDate() - ((props.limitDay ? props.limitDay - 1 : 6) - values[0]));
  50. now.setHours(values[1])
  51. now.setMinutes(values[2])
  52. global.picker_time = now.getTime()
  53. }, [values])
  54. for (let i = props.limitDay ? props.limitDay - 1 : 6; i >= 0; i--) {
  55. const date = new Date();
  56. date.setDate(pickerDate.getDate() - i);
  57. const month = date.getMonth() + 1;
  58. const day = date.getDate();
  59. // const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][date.getDay()];
  60. const weekday = TimeFormatter.getDayOfWeek(date.getDay(), true);
  61. const formattedDate = global.language == 'en' ? `${weekday} ${TimeFormatter.getMonth(month)} ${day}` : `${TimeFormatter.getMonth(month)}${day}日 ${weekday}`;
  62. var today1 = new Date();
  63. var yesterday = new Date(today1.getTime() - 24 * 3600 * 1000)
  64. if (date.getMonth() == today1.getMonth() && date.getDate() == today1.getDate()) {
  65. days.push(TimeFormatter.getTodayUnit());
  66. todayIndex = i
  67. }
  68. else if (date.getMonth() == yesterday.getMonth() && date.getDate() == yesterday.getDate()) {
  69. days.push(TimeFormatter.getYesterdayUnit());
  70. }
  71. else {
  72. days.push(formattedDate);
  73. }
  74. }
  75. const hours: number[] = [];
  76. for (let i = 0; i <= 23; i++) {
  77. hours.push(i);
  78. }
  79. const minutes: number[] = [];
  80. for (let i = 0; i <= 59; i++) {
  81. minutes.push(i);
  82. }
  83. function getTimestamp(dateTimeString: string): number {
  84. const timestamp = Date.parse(dateTimeString);
  85. return timestamp;
  86. }
  87. function getDaysDiff(date: Date): number {
  88. const today = new Date();
  89. today.setHours(0, 0, 0, 0);
  90. const targetDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  91. targetDate.setHours(0, 0, 0, 0);
  92. const timeDiff = today.getTime() - targetDate.getTime();
  93. const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
  94. return daysDiff;
  95. }
  96. function onPickerChange(e) {
  97. setValues(e.detail.value)
  98. }
  99. function onPickerEnd(e) {
  100. }
  101. function cancel(e) {
  102. if (process.env.TARO_ENV == 'weapp') {
  103. e.stopPropagation()
  104. }
  105. props.onCancel()
  106. }
  107. function confirm(e) {
  108. if (process.env.TARO_ENV == 'weapp') {
  109. e.stopPropagation()
  110. }
  111. var date = new Date();
  112. date.setDate(pickerDate.getDate() - (6 - values[0]));
  113. const year = date.getFullYear();
  114. const month = date.getMonth() + 1;
  115. const day = date.getDate();
  116. const time = `${year}-${expandZero(month)}-${expandZero(day)}T${expandZero(hours[values[1]])}:${expandZero(minutes[values[2]])}:${expandZero((new Date(global.set_time)).getSeconds())}`;
  117. if (getTimestamp(time) > global.set_time) {
  118. setValues([todayIndex, (new Date(global.set_time)).getHours(), (new Date(global.set_time)).getMinutes()])
  119. setTimeout(() => {
  120. setValues([todayIndex, (new Date(global.set_time)).getHours(), (new Date(global.set_time)).getMinutes()])
  121. }, 300);
  122. Taro.showToast({
  123. icon: 'none',
  124. title: t('feature.common.toast.min_time_value'),
  125. })
  126. return
  127. }
  128. else {
  129. var limitDate = new Date(props.limit)
  130. if (getTimestamp(time) < props.limit) {
  131. if (limitDate.getDate() == new Date(props.time).getDate()) {
  132. setValues([3, limitDate.getHours(), limitDate.getMinutes()])
  133. setTimeout(() => {
  134. setValues([3, limitDate.getHours(), limitDate.getMinutes()])
  135. }, 300)
  136. }
  137. else {
  138. setValues([2, limitDate.getHours(), limitDate.getMinutes()])
  139. setTimeout(() => {
  140. setValues([2, limitDate.getHours(), limitDate.getMinutes()])
  141. }, 300)
  142. }
  143. Taro.showToast({
  144. icon: 'none',
  145. title: t('feature.common.toast.max_time_value'),
  146. })
  147. return
  148. }
  149. }
  150. props.onChange(new Date(time).getTime())
  151. // if (!props.isRealTime) {
  152. // date = new Date(global.set_time);
  153. // date.setDate(today.getDate() - ((props.limitDay ? props.limitDay - 1 : 6) - values[0]));
  154. // }
  155. //
  156. // date.setHours(values[1])
  157. // date.setMinutes(values[2])
  158. // props.onChange(date.getTime())
  159. }
  160. function expandZero(num: number): string {
  161. return num < 10 ? `0${num}` : `${num}`;
  162. }
  163. function getEndTimestamp(timestamp) {
  164. if (global.language == 'en') {
  165. return TimeFormatter.dateDescription(timestamp, true) + ' ' + TimeFormatter.timeDescription(timestamp)
  166. }
  167. return TimeFormatter.dateDescription(timestamp, true) + '' + TimeFormatter.timeDescription(timestamp)
  168. }
  169. function pickerTimeText() {
  170. if (props.isFast) {
  171. return `原定于${getEndTimestamp(props.endTimestamp!)}结束`
  172. }
  173. else {
  174. return `原定于${getEndTimestamp(props.endTimestamp!)}起床`
  175. }
  176. }
  177. function pickerDetail() {
  178. return <View style={{ display: 'flex', flexDirection: 'column' }}>
  179. <Text className='modal_title' style={{ color: color }}>{props.title ? props.title : '测试标题 '}</Text>
  180. <View style={{ backgroundColor: 'transparent', position: 'relative' }}>
  181. <PickerView
  182. itemStyle={{ color: '#fff', margin: 0, padding: 0 }}
  183. value={values}
  184. className="picker"
  185. maskClass="picker-mask"
  186. style={{ color: '#fff' }}
  187. onChange={onPickerChange}
  188. onPickEnd={onPickerEnd}
  189. immediateChange={true}
  190. indicatorStyle='height: 50px;color:red;'>
  191. <PickerViewColumn style='flex:0 0 45%'>
  192. {days.map(item => {
  193. return (
  194. <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff' }}>{item}</View>
  195. );
  196. })}
  197. </PickerViewColumn>
  198. <PickerViewColumn>
  199. {hours.map(item => {
  200. return (
  201. <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff' }}>{item < 10 ? `0${item}` : item}</View>
  202. );
  203. })}
  204. </PickerViewColumn>
  205. <PickerViewColumn>
  206. {minutes.map(item => {
  207. return (
  208. <View style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff' }}>{item < 10 ? `0${item}` : item}</View>
  209. );
  210. })}
  211. </PickerViewColumn>
  212. </PickerView>
  213. {/* <View className="point_bg1 ">
  214. <Text style={{ color: '#fff', fontSize: 16, fontWeight: 'bold' }}>:</Text>
  215. </View> */}
  216. </View>
  217. <Text className="pickerEndTime" style={{color:'red'}}>{pickerTimeText()}</Text>
  218. <View className='modal_operate'>
  219. <View className='modal_btn' style={{ backgroundColor: color + alpha }} onClick={cancel}>
  220. <Text className='modal_cancel_text' style={{ color: color, fontWeight: 'bold' }}>{t('feature.common.picker_cancel_btn')}</Text>
  221. </View>
  222. <View className='btn_space' />
  223. <View className='modal_btn' style={{ backgroundColor: color }} onClick={confirm}>
  224. <Text className='modal_confirm_text' style={{ color: '#000', fontWeight: 'bold' }}>{t('feature.common.picker_confirm_btn')}</Text>
  225. </View>
  226. </View>
  227. </View>
  228. }
  229. return pickerDetail()
  230. })
  231. export default React.memo(Component);;