timePicker.js 16 KB

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