| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528 | 
							- <template>
 
- 	<view class="calendar" v-if="visible">
 
- 		<view class="calendar-mask" @click.stop='maskEvent'></view>
 
- 		<view class="calendar-container" @click.stop='handleClickOutSide'>
 
- 			<view class="calendar-header" :style="{backgroundColor: headerBgColor}">
 
- 				<view class="txt solar" :style="{color: (isLunar ?  defaultColor : activeColor)}" @click="changeCalendar(0)">
 
- 					{{solarText}}
 
- 				</view>
 
- 				<view class="txt lunar" :style="{color: (!isLunar ?  defaultColor : activeColor)}" @click="changeCalendar(1)">
 
- 					{{lunarText}}
 
- 				</view>
 
- 				<view class="txt confirm" :style="{color: confirmColor}" @click="changeCalendar(2)">
 
- 					{{confirmText}}
 
- 				</view>
 
- 			</view>
 
- 			<view class="calendar-body">
 
- 				<picker-view @change="timeChange" data-index='0' data-id='year' :value='[multiIndex[0]]' indicator-style="height: 40px;"
 
- 				 class='calendar-body-wrap' v-if="level > 0 ">
 
- 					<picker-view-column>
 
- 						<view v-for="item in yearData" :key='item' style="line-height: 40px;text-align:center;">{{item}}</view>
 
- 					</picker-view-column>
 
- 				</picker-view>
 
- 				<picker-view @change="timeChange" data-index='1' data-id='month' :value='[multiIndex[1]]' indicator-style="height: 40px;"
 
- 				 class='calendar-body-wrap' v-if="level> 1">
 
- 					<picker-view-column>
 
- 						<view v-for="item in monthData" :key='item' style="line-height: 40px;text-align:center;">{{item}}</view>
 
- 					</picker-view-column>
 
- 				</picker-view>
 
- 				<picker-view @change="timeChange" data-index='2' data-id='day' :value='[multiIndex[2]]' indicator-style="height: 40px;"
 
- 				 class='calendar-body-wrap' v-if="level > 2 ">
 
- 					<picker-view-column>
 
- 						<view v-for="item in dayData" :key='item' style="line-height: 40px;text-align:center;">{{item}}</view>
 
- 					</picker-view-column>
 
- 				</picker-view>
 
- 				<picker-view @change="timeChange" data-index='3' data-id='hour' :value='[multiIndex[3]]' indicator-style="height: 40px;"
 
- 				 class='calendar-body-wrap' v-if="level > 3 && (!isLunar || isLunar && !isShowChinaTime)">
 
- 					<picker-view-column>
 
- 						<view v-for="item in hours" :key='item' style="line-height: 40px;text-align:center;">{{item}}时</view>
 
- 					</picker-view-column>
 
- 				</picker-view>
 
- 				<picker-view @change="timeChange" data-index='4' data-id='minus' :value='[multiIndex[4]]' indicator-style="height: 40px;"
 
- 				 class='calendar-body-wrap' v-if="level > 4 && (!isLunar || isLunar && !isShowChinaTime)">
 
- 					<picker-view-column>
 
- 						<view v-for="item in minutes" :key='item' style="line-height: 40px;text-align:center;">{{item}}分</view>
 
- 					</picker-view-column>
 
- 				</picker-view>
 
- 				<picker-view @change="timeChange" data-index='5' data-id='second' :value='[multiIndex[5]]' indicator-style="height: 40px;"
 
- 				 class='calendar-body-wrap' v-if="level > 5 && (!isLunar || isLunar && !isShowChinaTime)">
 
- 					<picker-view-column>
 
- 						<view v-for="item in seconds" :key='item' style="line-height: 40px;text-align:center;">{{item}}秒</view>
 
- 					</picker-view-column>
 
- 				</picker-view>
 
- 				<picker-view @change="timeChange" data-index='6' data-id='china' :value='[multiIndex[6]]' indicator-style="height: 40px;"
 
- 				 class='calendar-body-wrap' v-if="isLunar && isShowChinaTime">
 
- 					<picker-view-column>
 
- 						<view v-for="item in chinaHours" :key='item.startTime' style="line-height: 40px;text-align:center;">{{item.name}}</view>
 
- 					</picker-view-column>
 
- 				</picker-view>
 
- 			</view>
 
- 		</view>
 
- 	</view>
 
- </template>
 
- <script>
 
- 	import clickoutside from '../directives/clickoutside.js';
 
- 	import {
 
- 		calendar
 
- 	} from '../libs/calendar.js'
 
- 	import {
 
- 		getYears,
 
- 		getMonths,
 
- 		getDays,
 
- 		getHours,
 
- 		getMinutes,
 
- 		getSeconds,
 
- 		getDateTime,
 
- 		formateTime,
 
- 		addZero,
 
- 		createArray,
 
- 		getDateStringTime,
 
- 		chinaHours,
 
- 		getChinaTime
 
- 	} from '../utils/util.js';
 
- 	export default {
 
- 		name: 'CalendarPicker',
 
- 		props: {
 
- 			level: {
 
- 				type: String,
 
- 				default: '5'
 
- 			},
 
- 			isShowChinaTime: {
 
- 				type: Boolean,
 
- 				default: false
 
- 			},
 
- 			currentTime: {
 
- 				type: String,
 
- 				default: ''
 
- 			},
 
- 			startYear: {
 
- 				type: Number,
 
- 				default: 1900
 
- 			},
 
- 			endYear: {
 
- 				type: Number,
 
- 				default: 2100
 
- 			},
 
- 			isLunar: {
 
- 				type: Boolean,
 
- 				default: false
 
- 			},
 
- 			headerBgColor: {
 
- 				type: String,
 
- 				default: '#e9e9e9'
 
- 			},
 
- 			solarText: {
 
- 				type: String,
 
- 				default: '阳历'
 
- 			},
 
- 			lunarText: {
 
- 				type: String,
 
- 				default: '阴历'
 
- 			},
 
- 			activeColor: {
 
- 				type: String,
 
- 				default: '#912222'
 
- 			},
 
- 			defaultColor: {
 
- 				type: String,
 
- 				default: '#000000'
 
- 			},
 
- 			confirmText: {
 
- 				type: String,
 
- 				default: '确定'
 
- 			},
 
- 			confirmColor: {
 
- 				type: String,
 
- 				default: '#912222'
 
- 			}
 
- 		},
 
- 		computed:{
 
- 			yearData(){
 
- 				return this.isLunar ? this.ganZhiYears : this.years;
 
- 			},
 
- 			monthData(){
 
- 				return this.isLunar ? this.ganZhiMonths : this.months;
 
- 			},
 
- 			dayData(){
 
- 				return this.isLunar ? this.ganZhiDays : this.days;
 
- 			}
 
- 		},
 
- 		watch: {
 
- 			currentTime: {
 
- 				handler(value) {
 
- 					if (value != '') {
 
- 						this.years = getYears(this.startYear, this.endYear);
 
- 						this.months = getMonths();
 
- 						this.hours = getHours();
 
- 						this.minutes = getMinutes();
 
- 						this.seconds = getSeconds();
 
- 						const selectTime = value.split(' ')[1];
 
- 						const timeArray = selectTime.split(':');
 
- 						const dateArray = value.split(' ')[0].split('-');
 
- 						this.days = getDays(dateArray[0], dateArray[1]);
 
- 						const dateTimeArray = dateArray.concat(timeArray);
 
- 						this.$nextTick(() => {
 
- 							this.selectYear = dateArray[0];
 
- 							this.selectMonth = dateArray[1];
 
- 							this.selectDay = dateArray[2];
 
- 							const names = ['year', 'month', 'day', 'hour', 'minute', 'second', 'china'];
 
- 							let multiIndex = [];
 
- 							names.forEach((name, i) => {
 
- 								if (name == 'china') {
 
- 									multiIndex.push(0);
 
- 								} else {
 
- 									const index = this[name + 's'].findIndex(item => item == dateTimeArray[i]);
 
- 									multiIndex.push(index);
 
- 								}
 
- 								this.multiIndex = multiIndex;
 
- 							})
 
- 							if (this.isLunar) {
 
- 								if (this.isShowChinaTime) {
 
- 									const time =
 
- 										`${this.hours[this.multiIndex[3]]}:${this.minutes[this.multiIndex[4]]}:${this.seconds[this.multiIndex[5]]}`;
 
- 									const {
 
- 										name
 
- 									} = getChinaTime(time);
 
- 									const index = this.chinaHours.findIndex(item => item.name == name);
 
- 									this.multiIndex.splice(this.multiIndex.length - 1, 1, index)
 
- 								}
 
- 								this.getLunarDate()
 
- 							}
 
- 						})
 
- 					}
 
- 				},
 
- 				immediate: true
 
- 			}
 
- 		},
 
- 		data() {
 
- 			return {
 
- 				chinaHours,
 
- 				multiIndex: [],
 
- 				selectYear: '',
 
- 				selectMonth: '',
 
- 				selectDay: '',
 
- 				selectTime: '',
 
- 				isLeap: false,
 
- 				visible: false,
 
- 				years: [],
 
- 				months: [],
 
- 				days: [],
 
- 				hours: [],
 
- 				minutes: [],
 
- 				seconds: [],
 
- 				ganZhiYears: [],
 
- 				ganZhiMonths: [],
 
- 				ganZhiDays: []
 
- 			}
 
- 		},
 
- 		methods: {
 
- 			handleClickOutSide() {
 
- 				return;
 
- 			},
 
- 			maskEvent() {
 
- 				this.hide()
 
- 			},
 
- 			show() {
 
- 				this.visible = true;
 
- 			},
 
- 			hide() {
 
- 				this.visible = false;
 
- 			},
 
- 			getLunarDate() {
 
- 				const lunarData = calendar.solar2lunar(this.selectYear, this.selectMonth, this.selectDay);
 
- 				console.log('lunarData:', lunarData);
 
- 				const {
 
- 					lYear,
 
- 					lMonth,
 
- 					lDay,
 
- 					isLeap,
 
- 					IMonthCn,
 
- 					IDayCn
 
- 				} = lunarData;
 
- 				this.selectYear = lYear;
 
- 				this.selectMonth = lMonth;
 
- 				this.selectDay = lDay;
 
- 				this.isLeap = isLeap;
 
- 				this.ganZhiYears = this.years.map(year => `${year}${calendar.getGanZhiYear(year)}`);
 
- 				const yearIndex = this.ganZhiYears.findIndex(item => item.indexOf(lYear) > -1);
 
- 				this.multiIndex.splice(0, 1, yearIndex);
 
- 				const leapMonth = calendar.leapMonth(lYear);
 
- 				console.log('leapMonth:', leapMonth)
 
- 				this.ganZhiMonths = this.months.map(month => calendar.toChinaMonth(month));
 
- 				let monthCount;
 
- 				if (leapMonth > 0) { //所选的年有闰年
 
- 					this.ganZhiMonths.splice(leapMonth, 0, `闰${calendar.toChinaMonth(leapMonth)}`);
 
- 					monthCount = calendar.leapDays(lYear);
 
- 				} else {
 
- 					monthCount = calendar.monthDays(lYear, lMonth)
 
- 				}
 
- 				const monthIndex = this.ganZhiMonths.findIndex(item => item == IMonthCn);
 
- 				this.multiIndex.splice(1, 1, monthIndex);
 
- 				const ganZhiDays = [];
 
- 				for (let i = 1; i <= monthCount; i++) {
 
- 					ganZhiDays.push(calendar.toChinaDay(i));
 
- 				}
 
- 				this.ganZhiDays = ganZhiDays;
 
- 				const dayIndex = this.ganZhiDays.findIndex(item => item == IDayCn);
 
- 				this.multiIndex.splice(2, 1, dayIndex);
 
- 				if (this.isShowChinaTime) {
 
- 					const time =
 
- 						`${this.hours[this.multiIndex[3]]}:${this.minutes[this.multiIndex[4]]}:${this.seconds[this.multiIndex[5]]}`;
 
- 					const {
 
- 						name
 
- 					} = getChinaTime(time);
 
- 				
 
- 					const index = this.chinaHours.findIndex(item => item.name == name);
 
- 					this.multiIndex.splice(this.multiIndex.length - 1, 1, index)
 
- 				}
 
- 				
 
- 			},
 
- 			getSolarDate() {
 
- 				const solarData = calendar.lunar2solar(this.selectYear, this.selectMonth, this.selectDay, this.isLeap);
 
- 				console.log('solarData:', solarData);
 
- 				const {
 
- 					cYear,
 
- 					cMonth,
 
- 					cDay,
 
- 					lYear,
 
- 					lMonth,
 
- 					lDay,
 
- 					isLeap,
 
- 					IMonthCn,
 
- 					IDayCn
 
- 				} = solarData;
 
- 				this.selectYear = cYear;
 
- 				this.selectMonth = cMonth;
 
- 				this.selectDay = cDay;
 
- 				this.isLeap = isLeap;
 
- 				const yearIndex = this.years.findIndex(item => item == cYear);
 
- 				const monthIndex = this.months.findIndex(item => item == cMonth);
 
- 				const dayIndex = this.days.findIndex(item => item == cDay);
 
- 				this.multiIndex.splice(0, 1, yearIndex);
 
- 				this.multiIndex.splice(1, 1, monthIndex);
 
- 				this.multiIndex.splice(2, 1, dayIndex);
 
- 			},
 
- 			timeChange(e) {
 
- 				const {
 
- 					id,
 
- 					index
 
- 				} = e.target.dataset;
 
- 				console.log('++++++',id,index)
 
- 				const scrollIndex = e.detail.value[0];
 
- 				this.multiIndex.splice(index, 1, scrollIndex);
 
- 				const names = ['Year', 'Month', 'Day'];
 
- 				if (!this.isLunar) {
 
- 					if (index == 1) {
 
- 						this.selectMonth = addZero(scrollIndex + 1) + '';
 
- 						this.days = getDays(this.selectYear, this.selectMonth);
 
- 						if (this.multiIndex[index + 1] + 1 > this.days.length) {
 
- 							this.multiIndex.splice(index + 1, 1, this.days.length - 1);
 
- 							this.selectDay = addZero(this.days.length);
 
- 						}
 
- 					} else if (index == 0) {
 
- 						this.selectYear = this.years[scrollIndex];
 
- 					} else {
 
- 						this['select' + names[index]] = addZero(scrollIndex + 1) + '';
 
- 					}
 
- 					this.selectTime = `${addZero(this.multiIndex[3]+1)}:${addZero(this.multiIndex[4]+1)}:${addZero(this.multiIndex[5]+1)}`;
 
- 					this.$nextTick(() => {
 
- 						this.selectDate = `${this.selectYear}-${this.selectMonth}-${this.selectDay} ${this.selectTime}`;
 
- 						console.log('selectDate', this.selectDate)
 
- 					})
 
- 				} else {
 
- 					if (index == 0) {
 
- 						this.selectYear = Number(this.ganZhiYears[this.multiIndex[0]].slice(0, 4));
 
- 						const leapMonth = calendar.leapMonth(this.selectYear);
 
- 						console.log('leapMonth:', leapMonth)
 
- 						this.ganZhiMonths = this.months.map(month => calendar.toChinaMonth(month));
 
- 						let monthCount, monthIndex;
 
- 						if (leapMonth > 0) { //所选的年有闰年
 
- 							this.ganZhiMonths.splice(leapMonth, 0, `闰${calendar.toChinaMonth(leapMonth)}`);
 
- 						}
 
- 						if (this.multiIndex[1] + 1 > this.ganZhiMonths.length) {
 
- 							this.multiIndex.splice(1, 1, this.ganZhiMonths.length - 1);
 
- 						}
 
- 						const month = this.ganZhiMonths[this.multiIndex[1]];
 
- 						monthIndex = this.ganZhiMonths.findIndex(item => item == month);
 
- 						if (leapMonth > 0) {
 
- 							console.log('======', )
 
- 							if (monthIndex == leapMonth) {
 
- 								this.selectMonth = monthIndex;
 
- 								this.isLeap = true;
 
- 								monthCount = calendar.leapDays(this.selectYear);
 
- 							} else {
 
- 								if (monthIndex > leapMonth) {
 
- 									this.selectMonth = monthIndex
 
- 								} else {
 
- 									this.selectMonth = monthIndex + 1;
 
- 								}
 
- 								this.isLeap = false;
 
- 								monthCount = calendar.monthDays(this.selectYear, this.selectMonth)
 
- 							}
 
- 						} else {
 
- 							this.selectMonth = monthIndex + 1;
 
- 							this.isLeap = false;
 
- 							monthCount = calendar.monthDays(this.selectYear, this.selectMonth)
 
- 						}
 
- 						const ganZhiDays = [];
 
- 						for (let i = 1; i <= monthCount; i++) {
 
- 							ganZhiDays.push(calendar.toChinaDay(i));
 
- 						}
 
- 						this.ganZhiDays = ganZhiDays;
 
- 						if (this.multiIndex[2] + 1 > this.ganZhiDays.length) {
 
- 							this.multiIndex.splice(2, 1, this.ganZhiDays.length - 1);
 
- 						}
 
- 					} else if (index == 1) {
 
- 						const leapMonth = calendar.leapMonth(this.selectYear);
 
- 						console.log('leapMonth:', leapMonth)
 
- 						let monthCount, monthIndex;
 
- 						const month = this.ganZhiMonths[this.multiIndex[1]];
 
- 						monthIndex = this.ganZhiMonths.findIndex(item => item == month);
 
- 						if (leapMonth > 0) {
 
- 							if (monthIndex == leapMonth) {
 
- 								this.selectMonth = monthIndex;
 
- 								this.isLeap = true;
 
- 								monthCount = calendar.leapDays(this.selectYear);
 
- 							} else {
 
- 								if (monthIndex > leapMonth) {
 
- 									this.selectMonth = monthIndex
 
- 								} else {
 
- 									this.selectMonth = monthIndex + 1;
 
- 								}
 
- 								this.isLeap = false;
 
- 								monthCount = calendar.monthDays(this.selectYear, this.selectMonth)
 
- 							}
 
- 						} else {
 
- 							this.selectMonth = monthIndex + 1;
 
- 							this.isLeap = false;
 
- 							monthCount = calendar.monthDays(this.selectYear, this.selectMonth)
 
- 						}
 
- 						const ganZhiDays = [];
 
- 						for (let i = 1; i <= monthCount; i++) {
 
- 							ganZhiDays.push(calendar.toChinaDay(i));
 
- 						}
 
- 						this.ganZhiDays = ganZhiDays;
 
- 						if (this.multiIndex[2] + 1 > this.ganZhiDays.length) {
 
- 							this.multiIndex.splice(2, 1, this.ganZhiDays.length - 1);
 
- 						}
 
- 					} else if (index == 2) {
 
- 						this.selectDay = this.multiIndex[2] + 1;
 
- 					}else if(index == 6){
 
- 						const { startTime } = this.chinaHours[scrollIndex];
 
- 						this.selectTime = startTime;
 
- 					}
 
- 				}
 
- 			},
 
- 			changeCalendar(index) {
 
- 				if (index == 0) { //阳历
 
- 					this.$emit('changecalendar', false);
 
- 					this.getSolarDate();
 
- 				} else if (index == 1) { //阴历
 
- 					this.$emit('changecalendar', true);
 
- 					this.getLunarDate()
 
- 				} else if (index == 2) { //确定
 
- 					let selectDate;
 
- 					if (this.isLunar) {
 
- 						selectDate = calendar.lunar2solar(this.selectYear, this.selectMonth, this.selectDay, this.isLeap);
 
- 					} else {
 
- 						selectDate = calendar.solar2lunar(this.selectYear, this.selectMonth, this.selectDay);
 
- 					}
 
- 					this.hide();
 
- 					selectDate['date'] = getDateStringTime(selectDate['date']);
 
- 					selectDate['lunarDate'] = getDateStringTime(selectDate['lunarDate']);
 
- 					let time;
 
- 					if(this.isShowChinaTime){
 
- 						const { startTime,name } = this.chinaHours[this.multiIndex[6]];
 
- 						selectDate['chinaTime'] = name;
 
- 						time = startTime;
 
- 					}else{
 
- 						time =
 
- 							`${this.hours[this.multiIndex[3]]}:${this.minutes[this.multiIndex[4]]}:${this.seconds[this.multiIndex[5]]}`;
 
- 						selectDate['chinaTime'] = getChinaTime(time) && getChinaTime(time)['name'];
 
- 					}
 
- 					this.$emit('confirm', { ...selectDate,
 
- 						time
 
- 					})
 
- 				}
 
- 			}
 
- 		},
 
- 		mounted() {
 
- 		}
 
- 	}
 
- </script>
 
- <style lang="scss" scoped>
 
- 	$zIndex: 1000;
 
- 	.calendar {
 
- 		.calendar-mask {
 
- 			position: fixed;
 
- 			top: 0;
 
- 			left: 0;
 
- 			right: 0;
 
- 			bottom: 0;
 
- 			background-color: rgba(0, 0, 0, .5);
 
- 			z-index: $zIndex;
 
- 		}
 
- 		.calendar-container {
 
- 			position: absolute;
 
- 			bottom: 0;
 
- 			left: 0;
 
- 			right: 0;
 
- 			height: 500rpx;
 
- 			background-color: #fff;
 
- 			z-index: $zIndex+1;
 
- 			display: flex;
 
- 			flex-direction: column;
 
- 			.calendar-header {
 
- 				display: flex;
 
- 				justify-content: space-between;
 
- 				align-items: center;
 
- 				height: 80rpx;
 
- 				box-sizing: border-box;
 
- 				padding: 0 32rpx;
 
- 				.txt {
 
- 					flex: 1;
 
- 					font-size: 32rpx;
 
- 					&.solar {
 
- 						text-align: left;
 
- 					}
 
- 					&.lunar {
 
- 						text-align: center;
 
- 					}
 
- 					&.confirm {
 
- 						text-align: right;
 
- 						cursor: pointer;
 
- 					}
 
- 				}
 
- 			}
 
- 			.calendar-body {
 
- 				flex: 1;
 
- 				display: flex;
 
- 				.calendar-body-wrap {
 
- 					flex: 1;
 
- 					font-size: 26rpx;
 
- 				}
 
- 			}
 
- 		}
 
- 	}
 
- </style>
 
 
  |