LimitPickers.tsx 10 KB

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