Files
dou_fire/uni_modules/oct-calendar-picker/components/oct-calendar-picker/oct-calendar-picker.vue
2023-03-31 22:18:54 +08:00

457 lines
13 KiB
Vue

<template>
<view>
<uni-popup ref="calendarPikerPopup">
<view class="calendar--piker">
<!-- header -->
<view class="calendar--piker--header">
<view class="calendar--piker--tabs">
<view class="calendar--piker--tabs--item" :class="{ 'acitve': tabVal == item.val }" v-for="(item, index) in tabs" :key="index" @click="onCalendarTabs(item)">{{item.title}}</view>
</view>
<uni-icons type="closeempty" size="20" color="#999" @click="close"></uni-icons>
</view>
<!-- 按月筛选 -->
<view class="calendar--piker--content" v-if="tabVal == 0">
<picker-view :indicator-style="indicatorStyle" :value="monthValue" @change="bindChangeMonth" class="calendar--piker--content--view">
<picker-view-column>
<view class="item" v-for="(item,index) in monthYM.years" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in monthYM.months" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
<!-- 按日筛选 -->
<view class="calendar--piker--content" v-if="tabVal == 1">
<view class="calendar--piker--content--subtitle">交易时间</view>
<view class="calendar--piker--content--flex">
<view class="item" :class="{ 'active': recentlyNum == 3 }" @click="getRecentlyDate(3)">近三月</view>
<view class="item" :class="{ 'active': recentlyNum == 6 }" @click="getRecentlyDate(6)">近半年</view>
<view class="item" :class="{ 'active': recentlyNum == 12 }" @click="getRecentlyDate(12)">近一年</view>
</view>
<view class="calendar--piker--content--subtitle">自定义</view>
<view class="calendar--piker--content--date">
<view class="date-item" @click="onDateTypeKey('start')" :class="{'date--active': dateTypeKey == 'start'}">{{ startDate || '开始时间' }}</view>
<view class="date-text"></view>
<view class="date-item" @click="onDateTypeKey('end')" :class="{'date--active': dateTypeKey == 'end'}">{{ endDate || '结束时间' }}</view>
</view>
<view class="calendar--piker--content--hint">最长可查询一年的账户记录</view>
<block v-if="dateTypeKey == 'start'">
<picker-view :indicator-style="indicatorStyle" :value="startValue" @change="bindChange" class="calendar--piker--content--view">
<picker-view-column>
<view class="item" v-for="(item,index) in startYMD.years" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in startYMD.months" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in startYMD.days" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</block>
<block v-if="dateTypeKey == 'end'">
<picker-view :indicator-style="indicatorStyle" :value="endValue" @change="bindChange" class="calendar--piker--content--view">
<picker-view-column>
<view class="item" v-for="(item,index) in endYMD.years" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in endYMD.months" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in endYMD.days" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</block>
</view>
<!-- 确定 -->
<view class="calendar--piker--btn">
<button size="default" @click="onCalendarChange">确定</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
/*
*
*
* */
var moment = require('moment')
export default{
data(){
const monthYM = { years: [], months: [] }
const monthValue = [ 0, 0 ]
for(let i = 2022; i <= moment().get('year'); i++){
monthYM.years.push(i)
}
for(let i = 1; i <= (moment().get('month') + 1); i++){
monthYM.months.push(i)
}
monthValue[0] = monthYM.years.length - 1;
monthValue[1] = monthYM.months.length - 1;
return {
tabs : [
{ val: 0, title: '月份选择' },
{ val: 1, title: '自定义时间' }
],
tabVal : 0,
// 月份选择
monthYM,
monthValue,
// 自定义时间
startYMD : { years: [], months: [], days: [] },
startValue : [0,0,0],
startDate : '',
endYMD : { years: [], months: [], days: [] },
endValue : [0,0,0],
endDate : '',
dateTypeKey : 'start',
indicatorStyle : `height: 35px;`,
// 快捷筛选选项
recentlyNum : ''
}
},
created() {
let year = moment().get('year')
let month = moment().get('month') + 1
let date = moment().get('date')
},
methods: {
// 打开弹出层
open(type){
this.$refs.calendarPikerPopup.open(type || 'bottom')
},
// 关闭弹出层
close(){
this.$refs.calendarPikerPopup.close()
},
// 获取初始化时间
onCalendarTabs(e){
let { val } = e
if(val == this.tabVal) return
if(val == 1 && this.startYMD.days == ''){
let { Ymd, Val, Date } = this.getAtData()
this.startYMD = Ymd
this.startValue = Val
this.startDate = Date
}
this.tabVal = val
},
// 获取初始化时间
getAtData(){
let Ymd = { years: [], months: [], days: [] }
let Val = [ 0,0,0 ]
let Date = ''
for(let i = 2022; i <= moment().get('year'); i++){
Ymd.years.push(i)
}
for(let i = 1; i <= (moment().get('month') + 1); i++){
Ymd.months.push(i)
}
for(let i = 1; i <= moment().get('date'); i++){
Ymd.days.push(i)
}
Val[0] = Ymd.years.length - 1
Val[1] = Ymd.months.length - 1
Val[2] = Ymd.days.length - 1
let year = Ymd.years[Val[0]];
let month = Ymd.months[Val[1]];
let day = Ymd.days[Val[2]]
Date = year + '-' + (month <= 9 ? '0' + month : month ) + '-' + (day <= 9 ? '0' + day : day )
return { Ymd, Val, Date }
},
// 月份选择
bindChangeMonth(e){
let { value } = e.detail
let atMonthVal = this.monthValue
let yearVal = this.monthYM.years[value[0]]
let isAtYear = yearVal == moment().get('year')
let monthsArr = []
if(value[0] != atMonthVal[0]){
for(let i = 1; i <= Number(isAtYear ? moment().get('month') + 1 : 12); i++ ){
monthsArr.push(i)
}
this.$set(this.monthYM, 'months', monthsArr)
}
this.monthValue = value
},
// 选择时间类型
onDateTypeKey(type){
if(type == this.dateTypeKey) return
if(this[type + 'Date'] == ''){
let { Ymd, Val, Date } = this.getAtData()
this[type + 'YMD'] = Ymd
this[type + 'Value'] = Val
this[type + 'Date'] = Date
}
if(this.endDate != '' && type == 'end'){
let years = []
let values = [ 0, 0, 0 ]
let endDateArr = this.endDate.split('-')
let { months, days } = this.getNewYM(endDateArr[0], endDateArr[1])
for(let i = 2022; i <= endDateArr[0]; i++){
years.push(i)
}
values[0] = years.length - 1
values[1] = months.length - 1
values[2] = days.length - 1
this.endYMD = { years, months, days}
this.endValue = values
}
this.dateTypeKey = type
},
// 选择日期
bindChange(e){
let { value } = e.detail
let typeKEY = this.dateTypeKey
let year = this[typeKEY + 'YMD'].years[value[0]]
let month = this[typeKEY + 'YMD'].months[value[1]]
let day = this[typeKEY + 'YMD'].days[value[2]]
if(value[0] != this[typeKEY + 'Value'][0] || value[1] != this[typeKEY + 'Value'][1]){
let { months, days } = this.getNewYM(year, month)
this.$set(this[typeKEY + 'YMD'], 'months', months)
this.$set(this[typeKEY + 'YMD'], 'days', days)
}
this[typeKEY + 'Value'] = value
this[typeKEY + 'Date'] = year + '-' + (month <= 9 ? '0' + month : month ) + '-' + (day <= 9 ? '0' + day : day )
this.recentlyNum = ''
},
// 获取最新的月份和日数据
getNewYM(year, month){
let months = []
let days = []
let lastDay = new Date(year, month, 0).getDate()
if(year == moment().get('year') && month == moment().get('month') + 1){
lastDay = moment().get('date')
}
for(let i = 1; i <= (year == moment().get('year') ? moment().get('month') + 1 : 12); i++){
months.push(i)
}
for(let i = 1; i <= lastDay; i++){
days.push(i)
}
return { months, days }
},
// 计算就近时间
getRecentlyDate(num){
let year = moment().get('year')
let month = moment().get('month') + 1
let today = moment().get('date')
let start = moment().subtract(num, 'month').format('YYYY-MM-DD')
let ymdArr = start.split('-')
let { months, days } = this.getNewYM(ymdArr[0], ymdArr[1])
this.$set(this.startYMD, 'months', months)
this.$set(this.startYMD, 'days', days)
let yearIndex = this.startYMD.years.findIndex(val => val == ymdArr[0]) || 0
let monthIndex = this.startYMD.months.findIndex(val => val == ymdArr[1]) || 0
let dayIndex = this.startYMD.days.findIndex(val => val == ymdArr[2]) || 0
this.startValue = [yearIndex, monthIndex, dayIndex]
this.startDate = start
this.endDate = year + '-' + (month <= 9 ? '0' + month : month ) + '-' + (today <= 9 ? '0' + today : today )
if(this.dateTypeKey == 'end'){
let years = []
let values = [ 0, 0, 0 ]
let endDateArr = this.endDate.split('-')
let { months, days } = this.getNewYM(endDateArr[0], endDateArr[1])
for(let i = 2022; i <= endDateArr[0]; i++){
years.push(i)
}
values[0] = years.length - 1
values[1] = months.length - 1
values[2] = days.length - 1
this.endYMD = { years, months, days}
this.endValue = values
}
this.recentlyNum = num
},
// 确认日期
onCalendarChange(){
let monthYM = this.monthYM, monthValue = this.monthValue
let startDate = ''
let endDate = ''
switch(this.tabVal){
case 0:
let yearsVal = monthYM.years[monthValue[0]]
let monthVal = monthYM.months[monthValue[1]]
let lastDay = new Date(yearsVal, monthVal, 0).getDate()
let isAt = yearsVal == moment().get('year') && monthVal == (moment().get('month') + 1)
startDate = yearsVal + '-' + (monthVal <= 9 ? '0' + monthVal: monthVal) + '-01'
endDate = yearsVal + '-' + (monthVal <= 9 ? '0' + monthVal: monthVal) + '-' + (isAt ? moment().get('date'): lastDay)
break;
case 1:
if(this.startDate == ''){
uni.showToast({
title: '开始时间不能为空',
icon : 'none'
})
return
}
if(this.endDate == ''){
uni.showToast({
title: '结束时间不能为空',
icon : 'none'
})
return
}
if(new Date(this.startDate).getTime() > new Date(this.endDate).getTime()){
uni.showToast({
title: '结束时间不能大于开始时间',
icon : 'none'
})
return
}
startDate = this.startDate
endDate = this.endDate
break;
}
this.$refs.calendarPikerPopup.close()
this.$emit('change', {
startDate,
endDate
})
}
}
}
</script>
<style lang="scss" scoped>
.calendar--piker{
background: white;
border-radius: 20rpx 20rpx 0 0;
padding: 0 30rpx 80rpx;
// header
&--header{
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
border-bottom: solid 1rpx #eaeaea;
}
// tabs
&--tabs{
display: flex;
justify-content: flex-start;
&--item{
margin-right: 50rpx;
line-height: 70rpx;
font-size: 28rpx;
position: relative;
&:last-child{
margin-right: 0;
}
&.acitve{
color: #446EFE;
&::after{
content: " ";
position: absolute;
bottom: -22rpx;
left: 0;
right: 0;
height: 1rpx;
background: #446EFE;
}
}
}
}
// 日期筛选
&--content{
padding-top: 50rpx;
&--subtitle{
font-size: 28rpx;
color: gray;
}
&--flex{
display: flex;
flex-wrap: wrap;
padding: 30rpx 0 50rpx;
font-size: 26rpx;
& > .item{
margin-right: 20rpx;
border: solid 1rpx #999;
color: gray;
border-radius: 5rpx;
padding: 0 20rpx;
height: 45rpx;
line-height: 43rpx;
&.active{
border-color: #446EFE;
color: #446EFE;
background-color: rgba(68, 110, 254, .1);
}
}
}
&--date{
padding-top: 30rpx;
display: flex;
align-items: center;
.date-text{
color: 333;
font-size: 30rpx;
width: 100rpx;
text-align: center;
font-weight: bold;
}
.date-item{
border-bottom: solid 6rpx #ddd;
width: calc(50% - 50rpx);
text-align: center;
height: 90rpx;
line-height: 84rpx;
&.date--active{
border-color: #446EFE;
color: #446EFE;
}
}
}
&--hint{
text-align: center;
font-size: 28rpx;
color: #FFAB3F;
padding: 30rpx 0;
line-height: 50rpx;
}
&--view{
height: 300rpx;
& .item{
line-height: 35px;
text-align: center;
}
}
}
// 按钮
&--btn{
padding-top: 50rpx;
& > button[size='default']{
background: #446EFE;
color: white;
height: 100rpx;
line-height: 100rpx;
padding: 0;
border-radius: 4rpx;
font-size: 34rpx;
&::after{
display: none;
}
}
}
}
</style>