You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

622 lines
17 KiB

  1. <template>
  2. <view :class="className" :style="style" class="lr-datetime-picker">
  3. <view
  4. @tap.stop="maskClick"
  5. @touchmove.stop.prevent
  6. :class="{ show: showPicker }"
  7. class="lr-datetime-mask"
  8. catchtouchmove="true"
  9. ></view>
  10. <view :class="{ show: showPicker }" class="lr-datetime-content">
  11. <view @touchmove.stop.prevent catchtouchmove="true" class="lr-datetime-hd">
  12. <view @tap.stop="pickerCancel" class="lr-datetime-btn">取消</view>
  13. <view @tap.stop="pickerConfirm" :style="{ color: color }" class="lr-datetime-btn">确定</view>
  14. </view>
  15. <view class="lr-datetime-view">
  16. <picker-view
  17. v-if="isAll"
  18. @change="bindChange"
  19. :indicator-style="itemHeight"
  20. :value="values"
  21. style="height: 100%;"
  22. >
  23. <picker-view-column>
  24. <view v-for="(item, index) in dateObj.years" :key="index" class="lr-datetime-item">{{ item }}年</view>
  25. </picker-view-column>
  26. <picker-view-column>
  27. <view v-for="(item, index) in dateObj.months" :key="index" class="lr-datetime-item">{{ item }}月</view>
  28. </picker-view-column>
  29. <picker-view-column>
  30. <view v-for="(item, index) in dateObj.days" :key="index" class="lr-datetime-item">{{ item }}日</view>
  31. </picker-view-column>
  32. <picker-view-column>
  33. <view v-for="(item, index) in dateObj.hours" :key="index" class="lr-datetime-item">{{ item }}时</view>
  34. </picker-view-column>
  35. <picker-view-column>
  36. <view v-for="(item, index) in dateObj.minutes" :key="index" class="lr-datetime-item">{{ item }}分</view>
  37. </picker-view-column>
  38. <picker-view-column>
  39. <view v-for="(item, index) in dateObj.seconds" :key="index" class="lr-datetime-item">{{ item }}秒</view>
  40. </picker-view-column>
  41. </picker-view>
  42. <picker-view
  43. v-else
  44. @change="bindDateChange"
  45. :indicator-style="itemHeight"
  46. :value="dateValues"
  47. style="height: 100%;"
  48. >
  49. <picker-view-column class="yu-picker-column">
  50. <view v-for="(item, index) in dateObj.dates" :key="index" class="lr-datetime-item">{{ item }}</view>
  51. </picker-view-column>
  52. <picker-view-column>
  53. <view v-for="(item, index) in dateObj.hours" :key="index" class="lr-datetime-item">{{ item }}时</view>
  54. </picker-view-column>
  55. <picker-view-column>
  56. <view v-for="(item, index) in dateObj.minutes" :key="index" class="lr-datetime-item">{{ item }}分</view>
  57. </picker-view-column>
  58. <picker-view-column>
  59. <view v-for="(item, index) in dateObj.seconds" :key="index" class="lr-datetime-item">{{ item }}秒</view>
  60. </picker-view-column>
  61. </picker-view>
  62. </view>
  63. </view>
  64. </view>
  65. </template>
  66. <script>
  67. export default {
  68. name: 'l-datetime-panel',
  69. props: {
  70. //全部日期有效可选
  71. isAll: { default: true },
  72. //颜色
  73. color: { default: '#1aad19' },
  74. //开始年份
  75. startYear: { default: '1900' },
  76. //结束年份
  77. endYear: { default: '2100' },
  78. //设置默认日期时间
  79. val: { default: '' }
  80. },
  81. data() {
  82. let date = new Date()
  83. let year = date.getFullYear()
  84. let month = date.getMonth() + 1
  85. let day = date.getDate()
  86. let hour = date.getHours()
  87. let minute = date.getMinutes()
  88. let second = date.getSeconds()
  89. let dates = []
  90. let months = []
  91. let years = []
  92. let days = []
  93. let hours = []
  94. let minutes = []
  95. let seconds = []
  96. for (let i = month; i <= month + 2; i++) {
  97. //获取包括当前月份在内的3个月内的日期
  98. let localMonth = i
  99. let localYear = year
  100. if (i == 13) {
  101. localYear += 1
  102. }
  103. if (i >= 13) {
  104. localMonth -= 12
  105. }
  106. let total = new Date(localYear, localMonth, 0).getDate()
  107. if (i == month) {
  108. for (let j = day; j <= total; j++) {
  109. let m = localMonth
  110. let d = j
  111. if (localMonth < 10) {
  112. m = '0' + m
  113. }
  114. if (j < 10) {
  115. d = '0' + d
  116. }
  117. let str = year + '-' + m + '-' + d
  118. dates.push(str)
  119. }
  120. } else {
  121. for (let j = 1; j <= total; j++) {
  122. let m = localMonth
  123. let d = j
  124. if (localMonth < 10) {
  125. m = '0' + m
  126. }
  127. if (j < 10) {
  128. d = '0' + d
  129. }
  130. let str = year + '-' + m + '-' + d
  131. dates.push(str)
  132. }
  133. }
  134. }
  135. for (let i = parseInt(this.startYear); i <= this.endYear; i++) {
  136. years.push(i)
  137. }
  138. for (let i = 1; i <= 12; i++) {
  139. let str = i
  140. if (i < 10) {
  141. str = '0' + str
  142. } else {
  143. str = '' + str
  144. }
  145. months.push(str)
  146. }
  147. if (this.val) {
  148. let valueArr = this.val.split(' ')
  149. let valueDateArr = valueArr[0].split('-')
  150. let totalCurrent = new Date(valueDateArr[0], valueDateArr[1], 0).getDate()
  151. for (let i = 1; i <= totalCurrent; i++) {
  152. let str = i
  153. if (i < 10) {
  154. str = '0' + str
  155. } else {
  156. str = '' + str
  157. }
  158. days.push(str)
  159. }
  160. } else {
  161. let totalCurrent = new Date(year, month, 0).getDate()
  162. for (let i = 1; i <= totalCurrent; i++) {
  163. let str = i
  164. if (i < 10) {
  165. str = '0' + str
  166. } else {
  167. str = '' + str
  168. }
  169. days.push(str)
  170. }
  171. }
  172. for (let i = 0; i < 24; i++) {
  173. let str = i
  174. if (i < 10) {
  175. str = '0' + str
  176. } else {
  177. str = '' + str
  178. }
  179. hours.push(str)
  180. }
  181. for (let i = 0; i < 60; i++) {
  182. let str = i
  183. if (i < 10) {
  184. str = '0' + str
  185. } else {
  186. str = '' + str
  187. }
  188. minutes.push(str)
  189. }
  190. for (let i = 0; i < 60; i++) {
  191. let str = i
  192. if (i < 10) {
  193. str = '0' + str
  194. } else {
  195. str = '' + str
  196. }
  197. seconds.push(str)
  198. }
  199. let dateObj = {
  200. dates,
  201. years,
  202. months,
  203. days,
  204. hours,
  205. minutes,
  206. seconds
  207. }
  208. return {
  209. value: this.val,
  210. year,
  211. month,
  212. day,
  213. hour,
  214. minute,
  215. second,
  216. dateObj,
  217. itemHeight: `height: ${uni.upx2px(88)}px;`,
  218. values: [0, 0, 0, 0, 0, 0],
  219. selectArr: [],
  220. selectRes: '',
  221. showPicker: false,
  222. dateValues: [0, 0, 0, 0]
  223. }
  224. },
  225. mounted() {
  226. this.setDate()
  227. },
  228. methods: {
  229. setDate(dt) {
  230. if (dt) {
  231. this.value = dt
  232. }
  233. this.initDate()
  234. if (!this.value) {
  235. this.showCurrent()
  236. }
  237. },
  238. initDate() {
  239. let _this = this
  240. //解析默认显示的日期时间
  241. if (_this.value) {
  242. let values = [0, 0, 0, 0, 0, 0]
  243. let dateValues = [0, 0, 0, 0]
  244. let valueStr = _this.value
  245. let valueArr = valueStr.split(' ')
  246. let valueDateArr = valueArr[0].split('-')
  247. let valueTimeArr = valueArr[1].split(':')
  248. if (_this.isAll) {
  249. values[0] = valueDateArr[0] - _this.startYear > 0 ? valueDateArr[0] - _this.startYear : 0
  250. values[1] = parseInt(valueDateArr[1]) - 1
  251. values[2] = parseInt(valueDateArr[2]) - 1
  252. values[3] = parseInt(valueTimeArr[0])
  253. values[4] = parseInt(valueTimeArr[1])
  254. values[5] = parseInt(valueTimeArr[2])
  255. _this.$nextTick(() => {
  256. _this.values = values
  257. })
  258. if (valueDateArr[0] - _this.startYear >= 0) {
  259. _this.selectArr = [
  260. valueDateArr[0],
  261. valueDateArr[1],
  262. valueDateArr[2],
  263. valueTimeArr[0],
  264. valueTimeArr[1],
  265. valueTimeArr[2]
  266. ]
  267. _this.selectRes = _this.value
  268. } else {
  269. _this.selectArr = [
  270. _this.formatNum(_this.startYear),
  271. valueDateArr[1],
  272. valueDateArr[2],
  273. valueTimeArr[0],
  274. valueTimeArr[1],
  275. valueTimeArr[2]
  276. ]
  277. _this.selectRes = `${this.formatNum(_this.startYear) +
  278. '-' +
  279. valueDateArr[1] +
  280. '-' +
  281. valueDateArr[2] +
  282. ' ' +
  283. valueTimeArr[0] +
  284. ':' +
  285. valueTimeArr[1] +
  286. ':' +
  287. valueTimeArr[2]}`
  288. }
  289. } else {
  290. let str = valueDateArr.join('')
  291. let localStr = _this.formatNum(_this.year) + _this.formatNum(_this.month) + _this.formatNum(_this.day) + ''
  292. if (str < localStr) {
  293. dateValues[0] = 0
  294. _this.selectArr = [
  295. _this.formatNum(_this.year),
  296. _this.formatNum(_this.month),
  297. _this.formatNum(_this.day),
  298. valueTimeArr[0],
  299. valueTimeArr[1],
  300. valueTimeArr[2]
  301. ]
  302. _this.selectRes = `${_this.formatNum(_this.year) +
  303. '-' +
  304. _this.formatNum(_this.month) +
  305. '-' +
  306. _this.formatNum(_this.day) +
  307. ' ' +
  308. valueTimeArr[0] +
  309. ':' +
  310. valueTimeArr[1] +
  311. ':' +
  312. valueTimeArr[2]}`
  313. } else {
  314. let num = 0 //计算默认日期和当前日期相隔天数,计算下标
  315. let start =
  316. _this.formatNum(_this.year) + '-' + _this.formatNum(_this.month) + '-' + _this.formatNum(_this.day)
  317. let res = _this.getBetweenDateStr(start, valueArr[0])
  318. dateValues[0] = res.length - 1
  319. _this.selectArr = [
  320. valueDateArr[0],
  321. valueDateArr[1],
  322. valueDateArr[2],
  323. valueTimeArr[0],
  324. valueTimeArr[1],
  325. valueTimeArr[2]
  326. ]
  327. _this.selectRes = _this.value
  328. }
  329. dateValues[1] = parseInt(valueTimeArr[0])
  330. dateValues[2] = parseInt(valueTimeArr[1])
  331. dateValues[3] = parseInt(valueTimeArr[2])
  332. _this.$nextTick(() => {
  333. _this.dateValues = dateValues
  334. })
  335. }
  336. return
  337. }
  338. if (_this.isAll) {
  339. _this.selectArr = [_this.formatNum(_this.startYear), '01', '01', '00', '00', '00']
  340. _this.selectRes = `${_this.formatNum(_this.startYear) + '-01-01 00:00:00'}`
  341. } else {
  342. _this.selectArr = [_this.formatNum(_this.year), _this.formatNum(_this.month), '01', '00', '00', '00']
  343. _this.selectRes = `${_this.formatNum(_this.year) + '-' + _this.formatNum(_this.month) + '-01 00:00:00'}`
  344. }
  345. },
  346. showCurrent() {
  347. //显示当前的日期时间
  348. let arr = [0, 0, 0, 0, 0, 0]
  349. let dateArr = [0, 0, 0, 0]
  350. this.selectArr = [
  351. this.formatNum(this.year),
  352. this.formatNum(this.month),
  353. this.formatNum(this.day),
  354. this.formatNum(this.hour),
  355. this.formatNum(this.minute),
  356. this.formatNum(this.second)
  357. ]
  358. this.selectRes = `${this.formatNum(this.year) +
  359. '-' +
  360. this.formatNum(this.month) +
  361. '-' +
  362. this.formatNum(this.day) +
  363. ' ' +
  364. this.formatNum(this.hour) +
  365. ':' +
  366. this.formatNum(this.minute) +
  367. ':' +
  368. this.formatNum(this.second)}`
  369. if (this.isAll) {
  370. arr[0] = this.year - this.startYear
  371. arr[1] = this.month - 1
  372. arr[2] = this.day - 1
  373. arr[3] = this.hour
  374. arr[4] = this.minute
  375. arr[5] = this.second
  376. this.$nextTick(() => {
  377. this.values = arr
  378. })
  379. } else {
  380. dateArr[1] = this.hour
  381. dateArr[2] = this.minute
  382. dateArr[3] = this.second
  383. this.$nextTick(() => {
  384. this.dateValues = dateArr
  385. })
  386. }
  387. },
  388. initDayArr: (year, month) => {
  389. //初始化月份天数
  390. let totalDay = new Date(year, month, 0).getDate()
  391. let dayArr = []
  392. for (let i = 1; i <= totalDay; i++) {
  393. if (i < 10) {
  394. i = '0' + i
  395. } else {
  396. i = i + ''
  397. }
  398. dayArr.push(i)
  399. }
  400. return dayArr
  401. },
  402. formatNum(num) {
  403. //日期时间的初始化
  404. return num < 10 ? '0' + num : num + ''
  405. },
  406. maskClick() {
  407. //日期时间的遮罩
  408. this.showPicker = false
  409. this.$emit('cancel')
  410. },
  411. show() {
  412. //日期时间的显示
  413. this.showPicker = true
  414. },
  415. hide() {
  416. //日期时间的隐藏
  417. this.showPicker = false
  418. this.$emit('cancel')
  419. },
  420. pickerCancel() {
  421. //日期时间取消
  422. this.showPicker = false
  423. this.$emit('cancel', {
  424. selectArr: this.selectArr
  425. })
  426. },
  427. pickerConfirm(e) {
  428. //日期时间确定
  429. this.showPicker = false
  430. this.$emit('confirm', {
  431. selectArr: this.selectArr,
  432. selectRes: this.selectRes
  433. })
  434. },
  435. bindChange(e) {
  436. //默认滚动日期时间方法
  437. let valueArr = e.detail.value
  438. let year = '',
  439. month = '',
  440. day = '',
  441. hour = '',
  442. minute = '',
  443. second = ''
  444. let selectArr = this.selectArr
  445. let dayArr = []
  446. year = this.dateObj.years[valueArr[0]]
  447. month = this.dateObj.months[valueArr[1]]
  448. day = this.dateObj.days[valueArr[2]]
  449. hour = this.dateObj.hours[valueArr[3]]
  450. minute = this.dateObj.minutes[valueArr[4]]
  451. second = this.dateObj.seconds[valueArr[5]]
  452. if (year != selectArr[0]) {
  453. dayArr = this.initDayArr(year, month)
  454. this.dateObj.days = dayArr
  455. }
  456. if (month != selectArr[1]) {
  457. dayArr = this.initDayArr(year, month)
  458. this.dateObj.days = dayArr
  459. }
  460. this.selectArr = [year, month, day, hour, minute, second]
  461. this.selectRes = `${year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second}`
  462. this.$nextTick(() => {
  463. this.values = valueArr
  464. })
  465. },
  466. bindDateChange(e) {
  467. //有效日期的滚动日期时间方法
  468. let valueArr = e.detail.value
  469. let dateStr = '',
  470. dateArr = [],
  471. hour = '',
  472. minute = '',
  473. second = ''
  474. let selectArr = this.selectArr
  475. let dayArr = []
  476. dateStr = this.dateObj.dates[valueArr[0]]
  477. dateArr = dateStr.split('-')
  478. hour = this.dateObj.hours[valueArr[1]]
  479. minute = this.dateObj.minutes[valueArr[2]]
  480. second = this.dateObj.seconds[valueArr[3]]
  481. this.selectArr = [dateArr[0], dateArr[1], dateArr[2], hour, minute, second]
  482. this.selectRes = `${dateArr[0] + '-' + dateArr[1] + '-' + dateArr[2] + ' ' + hour + ':' + minute + ':' + second}`
  483. this.$nextTick(() => {
  484. this.dateValues = valueArr
  485. })
  486. },
  487. //遍历两个日期间的所有日期
  488. getBetweenDateStr(start, end) {
  489. let result = []
  490. let beginDay = start.split('-')
  491. let endDay = end.split('-')
  492. let diffDay = new Date()
  493. let dateList = new Array()
  494. let i = 0
  495. diffDay.setDate(beginDay[2])
  496. diffDay.setMonth(beginDay[1] - 1)
  497. diffDay.setFullYear(beginDay[0])
  498. result.push(start)
  499. while (i == 0) {
  500. let countDay = diffDay.getTime() + 24 * 60 * 60 * 1000
  501. diffDay.setTime(countDay)
  502. dateList[2] = diffDay.getDate()
  503. dateList[1] = diffDay.getMonth() + 1
  504. dateList[0] = diffDay.getFullYear()
  505. if (String(dateList[1]).length == 1) {
  506. dateList[1] = '0' + dateList[1]
  507. }
  508. if (String(dateList[2]).length == 1) {
  509. dateList[2] = '0' + dateList[2]
  510. }
  511. result.push(dateList[0] + '-' + dateList[1] + '-' + dateList[2])
  512. if (dateList[0] == endDay[0] && dateList[1] == endDay[1] && dateList[2] == endDay[2]) {
  513. i = 1
  514. }
  515. }
  516. return result
  517. }
  518. }
  519. }
  520. </script>
  521. <style>
  522. .lr-datetime-picker {
  523. position: relative;
  524. z-index: 888;
  525. }
  526. .lr-datetime-mask {
  527. position: fixed;
  528. z-index: 1000;
  529. top: 0;
  530. right: 0;
  531. left: 0;
  532. bottom: 0;
  533. background: rgba(0, 0, 0, 0.4);
  534. visibility: hidden;
  535. opacity: 0;
  536. transition: all 0.3s ease;
  537. }
  538. .lr-datetime-mask.show {
  539. visibility: visible;
  540. opacity: 1;
  541. }
  542. .lr-datetime-content {
  543. position: fixed;
  544. bottom: 0;
  545. left: 0;
  546. width: 100%;
  547. transition: all 0.3s ease;
  548. transform: translateY(100%);
  549. z-index: 3000;
  550. }
  551. .lr-datetime-content.show {
  552. transform: translateY(0);
  553. }
  554. .lr-datetime-hd {
  555. display: flex;
  556. align-items: center;
  557. padding: 0 30upx;
  558. height: 44px;
  559. background-color: #fff;
  560. position: relative;
  561. text-align: center;
  562. font-size: 15px;
  563. justify-content: space-between;
  564. }
  565. .lr-datetime-btn {
  566. font-size: 14px;
  567. }
  568. .lr-datetime-hd:after {
  569. content: ' ';
  570. position: absolute;
  571. left: 0;
  572. bottom: 0;
  573. right: 0;
  574. height: 1px;
  575. border-bottom: 1px solid #e5e5e5;
  576. color: #e5e5e5;
  577. transform-origin: 0 100%;
  578. transform: scaleY(0.5);
  579. }
  580. .lr-datetime-view {
  581. width: 100%;
  582. height: 200px;
  583. overflow: hidden;
  584. background-color: rgba(255, 255, 255, 1);
  585. z-index: 666;
  586. }
  587. .yu-picker-column {
  588. -webkit-flex: 2;
  589. -webkit-box-flex: 2;
  590. flex: 2;
  591. }
  592. .lr-datetime-item {
  593. text-align: center;
  594. width: 100%;
  595. height: 88upx;
  596. line-height: 88upx;
  597. text-overflow: ellipsis;
  598. white-space: nowrap;
  599. font-size: 30upx;
  600. }
  601. </style>