timePicker.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. import dayjs from "dayjs";
  2. import {getUserWordTimes,formatDate} from "../../../utils/tools";
  3. Component({
  4. /**
  5. * 组件的属性列表
  6. */
  7. properties: {
  8. isPartition:{
  9. type: Boolean,
  10. },
  11. pickerShow: {
  12. type: Boolean,
  13. observer:function(val){ //弹出动画
  14. if(val){
  15. let animation = wx.createAnimation({
  16. duration: 500,
  17. timingFunction: "ease"
  18. });
  19. let animationOpacity = wx.createAnimation({
  20. duration: 500,
  21. timingFunction: "ease"
  22. });
  23. setTimeout(() => {
  24. animation.bottom(0).step();
  25. animationOpacity.opacity(0.7).step();
  26. this.setData({
  27. animationOpacity: animationOpacity.export(),
  28. animationData: animation.export()
  29. })
  30. }, 0);
  31. }else{
  32. let animation = wx.createAnimation({
  33. duration: 100,
  34. timingFunction: "ease"
  35. });
  36. let animationOpacity = wx.createAnimation({
  37. duration: 500,
  38. timingFunction: "ease"
  39. });
  40. animation.bottom(-320).step();
  41. animationOpacity.opacity(0).step();
  42. this.setData({
  43. animationOpacity: animationOpacity.export(),
  44. animationData: animation.export()
  45. });
  46. }
  47. // 在picker滚动未停止前点确定,会使startValue数组各项归零,发生错误,这里判断并重新初始化
  48. // 微信新增了picker滚动的回调函数,已进行兼容
  49. if(this.data.startValue&&this.data.endValue){
  50. let s = 0, e = 0;
  51. let conf = this.data.config;
  52. this.data.startValue.map(val => {
  53. if (val == 0) {
  54. s++
  55. }
  56. })
  57. this.data.endValue.map(val => {
  58. if (val == 0) {
  59. e++;
  60. }
  61. });
  62. let tmp={
  63. hour:4,
  64. minute:5,
  65. second:6
  66. }
  67. let n = tmp[conf.column];
  68. if (s>=n || e>=n) {
  69. this.initPick(this.data.config);
  70. this.setData({
  71. startValue: this.data.startValue,
  72. endValue: this.data.endValue,
  73. });
  74. }
  75. }
  76. }
  77. },
  78. config: Object,
  79. },
  80. /**
  81. * 组件的初始数据
  82. */
  83. data: {
  84. // pickerShow:true
  85. // limitStartTime: new Date().getTime()-1000*60*60*24*30,
  86. // limitEndTime: new Date().getTime(),
  87. // yearStart:2000,
  88. // yearEnd:2100
  89. },
  90. detached: function() {
  91. //console.log("dele");
  92. },
  93. attached: function() {},
  94. ready: function() {
  95. this.readConfig();
  96. this.initPick(this.data.config || {});
  97. this.setData({
  98. startValue: this.data.startValue,
  99. endValue: this.data.endValue,
  100. });
  101. },
  102. /**
  103. * 组件的方法列表
  104. */
  105. methods: {
  106. //阻止滑动事件
  107. onCatchTouchMove(e) {
  108. },
  109. //读取配置项
  110. readConfig() {
  111. let limitEndTime = new Date().getTime();
  112. let limitStartTime = new Date().getTime() - 1000 * 60 * 60 * 24 * 30;
  113. if (this.data.config) {
  114. let conf = this.data.config;
  115. if (typeof conf.dateLimit == "number") {
  116. limitStartTime =
  117. new Date().getTime() - 1000 * 60 * 60 * 24 * conf.dateLimit;
  118. }
  119. if(conf.limitStartTime){
  120. limitStartTime = new Date(conf.limitStartTime.replace(/-/g,'/')).getTime();
  121. }
  122. if (conf.limitEndTime) {
  123. limitEndTime = new Date(conf.limitEndTime.replace(/-/g, '/')).getTime();
  124. }
  125. this.setData({
  126. yearStart: conf.yearStart || 2000,
  127. yearEnd: conf.yearEnd || 2100,
  128. endDate: conf.endDate || false,
  129. dateLimit: conf.dateLimit || false,
  130. hourColumn:
  131. conf.column == "hour" ||
  132. conf.column == "minute" ||
  133. conf.column == "second",
  134. minColumn: conf.column == "minute" || conf.column == "second",
  135. secColumn: conf.column == "second"
  136. });
  137. }
  138. let limitStartTimeArr = formatTime(limitStartTime);
  139. let limitEndTimeArr = formatTime(limitEndTime);
  140. this.setData({
  141. limitStartTime,
  142. limitStartTimeArr,
  143. limitEndTime,
  144. limitEndTimeArr
  145. });
  146. },
  147. //滚动开始
  148. handlePickStart:function(e){
  149. this.setData({
  150. isPicking:true
  151. })
  152. },
  153. //滚动结束
  154. handlePickEnd:function(e){
  155. this.setData({
  156. isPicking:false
  157. })
  158. },
  159. partitionTimeHandle(time){
  160. let year = dayjs(time).year();
  161. let month = dayjs(time).month()+1;
  162. let day = dayjs(time).date();
  163. let hour = dayjs(time).hour();
  164. let minute = dayjs(time).minute();
  165. let current = formatDate(year, month, day, hour, minute);
  166. const {start,restStart,restEnd,end} = getUserWordTimes();
  167. let startArr = start.split(':');
  168. let endArr = end.split(':');
  169. let restEndArr = restEnd.split(':');
  170. if(dayjs(dayjs(current).format('YYYY-MM-DD HH:mm')).isBefore(dayjs(dayjs(current).format('YYYY-MM-DD')+start))){
  171. current = formatDate(year, month, day,parseInt(startArr[0]), parseInt(startArr[1]));
  172. }else if(dayjs(dayjs(current).format('YYYY-MM-DD HH:mm')).isAfter(dayjs(dayjs(current).format('YYYY-MM-DD')+end))){
  173. current = formatDate(year, month, day,parseInt(endArr[0]), parseInt(endArr[1]));
  174. }else if(
  175. dayjs(dayjs(current).format('YYYY-MM-DD HH:mm')).isAfter(dayjs(dayjs(current).format('YYYY-MM-DD')+restStart))
  176. &&
  177. dayjs(dayjs(current).format('YYYY-MM-DD HH:mm')).isBefore(dayjs(dayjs(current).format('YYYY-MM-DD')+restEnd))
  178. ){
  179. current = formatDate(year, month, day,parseInt(restEndArr[0]), parseInt(restEndArr[1]));
  180. }
  181. return current;
  182. },
  183. onConfirm: function() {
  184. //滚动未结束时不能确认
  185. if(this.data.isPicking){return}
  186. let startTime = new Date(this.data.startPickTime.replace(/-/g, "/"));
  187. let endTime = new Date(this.data.endPickTime.replace(/-/g, "/"));
  188. let lv = true;
  189. this.triggerEvent("conditionaljudgment", {
  190. startTime,
  191. endTime,
  192. setLv:(v)=>{lv = v}
  193. });//条件判断
  194. wx.nextTick(() => {
  195. if(!lv){return}
  196. if (startTime <= endTime || !this.data.endDate) {
  197. this.setData({
  198. startTime,
  199. endTime
  200. });
  201. let startArr = formatTime(startTime).arr;
  202. let endArr = formatTime(endTime).arr;
  203. let format0 = function(num){
  204. return num<10?'0'+num:num
  205. }
  206. let startTimeBack =
  207. startArr[0] +
  208. "-" +
  209. format0(startArr[1]) +
  210. "-" +
  211. format0(startArr[2]) +
  212. " " +
  213. (this.data.hourColumn ? format0(startArr[3]) : "00") +
  214. ":" +
  215. (this.data.minColumn ? format0(startArr[4]) : "00") +
  216. ":" +
  217. (this.data.secColumn ? format0(startArr[5]) : "00");
  218. let endTimeBack =
  219. endArr[0] +
  220. "-" +
  221. format0(endArr[1]) +
  222. "-" +
  223. format0(endArr[2]) +
  224. " " +
  225. (this.data.hourColumn ? format0(endArr[3]) : "00") +
  226. ":" +
  227. (this.data.minColumn ? format0(endArr[4]) : "00") +
  228. ":" +
  229. (this.data.secColumn ? format0(endArr[5]) : "00");
  230. let time = {
  231. startTime: startTimeBack,
  232. endTime: endTimeBack
  233. };
  234. //触发自定义事件
  235. //isPartition是否按地区判断工作开始结束时间
  236. if(this.data.isPartition){
  237. let startTimeInfor = this.partitionTimeHandle(time.startTime);
  238. let endTimeInfor = this.partitionTimeHandle(time.endTime);
  239. time.selectStartTime = time.startTime;
  240. time.selectEndTime = time.endTime;
  241. time.startTime = dayjs(startTimeInfor).format('YYYY-MM-DD HH:mm:ss');
  242. time.endTime = dayjs(endTimeInfor).format('YYYY-MM-DD HH:mm:ss');
  243. this.triggerEvent("setpickertime", time);
  244. }else{
  245. this.triggerEvent("setpickertime", time);
  246. }
  247. this.triggerEvent("hidepicker", {},{});
  248. } else {
  249. wx.showToast({
  250. icon: "none",
  251. title: "结束时间不能小于开始时间"
  252. });
  253. }
  254. })
  255. },
  256. hideModal: function(e) {
  257. this.triggerEvent("hidepicker", e.detail,{});
  258. },
  259. changeStartDateTime: function(e) {
  260. let val = e.detail.value;
  261. this.compareTime(val, "start");
  262. },
  263. changeEndDateTime: function(e) {
  264. let val = e.detail.value;
  265. this.compareTime(val, "end");
  266. },
  267. //比较时间是否在范围内
  268. compareTime(val_, type) {
  269. const val = val_.map(it=>it.toString());
  270. let h = val[3] ? this.data.HourList[val[3]] : "00";
  271. let m = val[4] ? this.data.MinuteList[val[4]] : "00";
  272. let s = val[5] ? this.data.SecondList[val[5]] : "00";
  273. let time =
  274. this.data.YearList[val[0]] +
  275. "-" +
  276. this.data.MonthList[val[1]] +
  277. "-" +
  278. this.data.DayList[val[2]] +
  279. " " +
  280. h +
  281. ":" +
  282. m +
  283. ":" +
  284. s;
  285. let start = this.data.limitStartTime;
  286. let end = this.data.limitEndTime;
  287. let timeNum = new Date(time.replace(/-/g, '/')).getTime();
  288. let year, month, day, hour, min, sec, limitDate;
  289. let tempArr = []
  290. if (!this.data.dateLimit){
  291. limitDate = [
  292. this.data.YearList[val[0]],
  293. this.data.MonthList[val[1]],
  294. this.data.DayList[val[2]],
  295. this.data.HourList[val[3]],
  296. this.data.MinuteList[val[4]],
  297. this.data.SecondList[val[5]]]
  298. } else if (type == "start" && timeNum > new Date(this.data.endPickTime.replace(/-/g, '/')) && this.data.config.endDate) {
  299. limitDate = formatTime(this.data.endPickTime).arr;
  300. } else if (type == "end" && timeNum < new Date(this.data.startPickTime.replace(/-/g, '/'))) {
  301. limitDate = formatTime(this.data.startPickTime).arr;
  302. } else if (timeNum < start) {
  303. limitDate = this.data.limitStartTimeArr.arr;
  304. } else if (timeNum > end) {
  305. limitDate = this.data.limitEndTimeArr.arr;
  306. } else {
  307. limitDate = [
  308. this.data.YearList[val[0]],
  309. this.data.MonthList[val[1]],
  310. this.data.DayList[val[2]],
  311. this.data.HourList[val[3]],
  312. this.data.MinuteList[val[4]],
  313. this.data.SecondList[val[5]]
  314. ]
  315. }
  316. year = limitDate[0];
  317. month = limitDate[1];
  318. day = limitDate[2];
  319. hour = limitDate[3];
  320. min = limitDate[4];
  321. sec = limitDate[5];
  322. if (type == "start") {
  323. this.setStartDate(year, month, day, hour, min, sec);
  324. } else if (type == "end") {
  325. this.setEndDate(year, month, day, hour, min, sec);
  326. }
  327. },
  328. getDays: function(year, month) {
  329. let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  330. if (month === 2) {
  331. return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
  332. ? 29
  333. : 28;
  334. } else {
  335. return daysInMonth[month - 1];
  336. }
  337. },
  338. initPick: function(initData) {
  339. const date = initData.initStartTime ? new Date(initData.initStartTime.replace(/-/g, '/')): new Date();
  340. const endDate = initData.initEndTime ? new Date(initData.initEndTime.replace(/-/g, '/')) : new Date();
  341. // const startDate = new Date(date.getTime() - 1000 * 60 * 60 * 24);
  342. const startDate = date;
  343. const startYear = date.getFullYear();
  344. const startMonth = date.getMonth() + 1;
  345. const startDay = date.getDate();
  346. const startHour = date.getHours();
  347. const startMinute = date.getMinutes();
  348. const startSecond = date.getSeconds();
  349. const endYear = endDate.getFullYear();
  350. const endMonth = endDate.getMonth() + 1;
  351. const endDay = endDate.getDate();
  352. const endHour = endDate.getHours();
  353. const endMinute = endDate.getMinutes();
  354. const endSecond = endDate.getSeconds();
  355. let YearList = [];
  356. let MonthList = [];
  357. let DayList = [];
  358. let HourList = [];
  359. let MinuteList = [];
  360. let SecondList = [];
  361. //设置年份列表
  362. for (let i = this.data.yearStart; i <= this.data.yearEnd; i++) {
  363. YearList.push(i);
  364. }
  365. // 设置月份列表
  366. for (let i = 1; i <= 12; i++) {
  367. MonthList.push(i);
  368. }
  369. // 设置日期列表
  370. for (let i = 1; i <= 31; i++) {
  371. DayList.push(i);
  372. }
  373. // 设置时列表
  374. for (let i = 0; i <= 23; i++) {
  375. if (0 <= i && i < 10) {
  376. i = "0" + i;
  377. }
  378. HourList.push(i);
  379. }
  380. // 分|秒
  381. for (let i = 0; i <= 59; i++) {
  382. if (0 <= i && i < 10) {
  383. i = "0" + i;
  384. }
  385. MinuteList.push(i);
  386. SecondList.push(i);
  387. }
  388. this.setData({
  389. YearList,
  390. MonthList,
  391. DayList,
  392. HourList,
  393. MinuteList,
  394. SecondList
  395. });
  396. this.setStartDate(startYear, startMonth, startDay, startHour, startMinute, startSecond);
  397. this.setEndDate(endYear, endMonth, endDay, endHour, endMinute, endSecond);
  398. //!!!
  399. // setTimeout(() => {
  400. // this.setStartDate(nowYear, nowMonth, nowDay, nowHour, nowMinute)
  401. // this.setEndDate(nowYear, nowMonth, nowDay, nowHour, nowMinute)
  402. // }, 0);
  403. },
  404. setPickerDateArr(type, year, month, day, hour, minute, second) {
  405. let yearIdx = 0;
  406. let monthIdx = 0;
  407. let dayIdx = 0;
  408. let hourIdx = 0;
  409. let minuteIdx = 0;
  410. let secondIdx = 0;
  411. this.data.YearList.map((v, idx) => {
  412. if (parseInt(v) === year) {
  413. yearIdx = idx;
  414. }
  415. });
  416. this.data.MonthList.map((v, idx) => {
  417. if (parseInt(v) === month) {
  418. monthIdx = idx;
  419. }
  420. });
  421. // 重新设置日期列表
  422. let DayList = [];
  423. for (let i = 1; i <= this.getDays(year, month); i++) {
  424. DayList.push(i);
  425. }
  426. DayList.map((v, idx) => {
  427. if (parseInt(v) === day) {
  428. dayIdx = idx;
  429. }
  430. });
  431. if (type == "start") {
  432. this.setData({ startDayList: DayList });
  433. } else if (type == "end") {
  434. this.setData({ endDayList: DayList });
  435. }
  436. this.data.HourList.map((v, idx) => {
  437. if (parseInt(v) === parseInt(hour)) {
  438. hourIdx = idx;
  439. }
  440. });
  441. this.data.MinuteList.map((v, idx) => {
  442. if (parseInt(v) === parseInt(minute)) {
  443. minuteIdx = idx;
  444. }
  445. });
  446. this.data.SecondList.map((v, idx) => {
  447. if (parseInt(v) === parseInt(second)) {
  448. secondIdx = idx;
  449. }
  450. });
  451. return {
  452. yearIdx,
  453. monthIdx,
  454. dayIdx,
  455. hourIdx,
  456. minuteIdx,
  457. secondIdx
  458. };
  459. },
  460. setStartDate: function(year, month, day, hour, minute, second) {
  461. let pickerDateArr = this.setPickerDateArr(
  462. "start",
  463. year,
  464. month,
  465. day,
  466. hour,
  467. minute,
  468. second
  469. );
  470. this.setData({
  471. startYearList: this.data.YearList,
  472. startMonthList: this.data.MonthList,
  473. // startDayList: this.data.DayList,
  474. startHourList: this.data.HourList,
  475. startMinuteList: this.data.MinuteList,
  476. startSecondList: this.data.SecondList,
  477. startValue: [
  478. pickerDateArr.yearIdx,
  479. pickerDateArr.monthIdx,
  480. pickerDateArr.dayIdx,
  481. pickerDateArr.hourIdx,
  482. pickerDateArr.minuteIdx,
  483. pickerDateArr.secondIdx
  484. ],
  485. startPickTime:
  486. this.data.YearList[pickerDateArr.yearIdx] +
  487. "-" +
  488. this.data.MonthList[pickerDateArr.monthIdx] +
  489. "-" +
  490. this.data.DayList[pickerDateArr.dayIdx] +
  491. " " +
  492. this.data.HourList[pickerDateArr.hourIdx] +
  493. ":" +
  494. this.data.MinuteList[pickerDateArr.minuteIdx] +
  495. ":" +
  496. this.data.SecondList[pickerDateArr.secondIdx]
  497. });
  498. },
  499. setEndDate: function(year, month, day, hour, minute, second) {
  500. let pickerDateArr = this.setPickerDateArr(
  501. "end",
  502. year,
  503. month,
  504. day,
  505. hour,
  506. minute,
  507. second
  508. );
  509. this.setData({
  510. endYearList: this.data.YearList,
  511. endMonthList: this.data.MonthList,
  512. // endDayList: this.data.DayList,
  513. endHourList: this.data.HourList,
  514. endMinuteList: this.data.MinuteList,
  515. endSecondList: this.data.SecondList,
  516. endValue: [
  517. pickerDateArr.yearIdx,
  518. pickerDateArr.monthIdx,
  519. pickerDateArr.dayIdx,
  520. pickerDateArr.hourIdx,
  521. pickerDateArr.minuteIdx,
  522. pickerDateArr.secondIdx
  523. ],
  524. endPickTime:
  525. this.data.YearList[pickerDateArr.yearIdx] +
  526. "-" +
  527. this.data.MonthList[pickerDateArr.monthIdx] +
  528. "-" +
  529. this.data.DayList[pickerDateArr.dayIdx] +
  530. " " +
  531. this.data.HourList[pickerDateArr.hourIdx] +
  532. ":" +
  533. this.data.MinuteList[pickerDateArr.minuteIdx] +
  534. ":" +
  535. this.data.SecondList[pickerDateArr.secondIdx]
  536. });
  537. },
  538. }
  539. });
  540. function formatTime(date) {
  541. if (typeof date == 'string' || 'number') {
  542. try {
  543. date = date.replace(/-/g, '/')//兼容ios
  544. } catch (error) {
  545. }
  546. date = new Date(date)
  547. }
  548. const year = date.getFullYear()
  549. const month = date.getMonth() + 1
  550. const day = date.getDate()
  551. const hour = date.getHours()
  552. const minute = date.getMinutes()
  553. const second = date.getSeconds()
  554. return {
  555. str: [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':'),
  556. arr: [year, month, day, hour, minute, second]
  557. }
  558. }
  559. function formatNumber(n) {
  560. n = n.toString()
  561. return n[1] ? n : '0' + n
  562. }