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>
|