2025-11-20 17:45:41 +08:00
|
|
|
<template>
|
|
|
|
|
<view class="date-con" v-if="isShow">
|
|
|
|
|
<view class="date-bg">
|
|
|
|
|
<view class="date-title">
|
|
|
|
|
<uni-icons type="closeempty" size="20" @click="handleClose"></uni-icons>
|
|
|
|
|
<view class="choose-title">选择时间</view>
|
|
|
|
|
<view class="date-confirm" @click="handleConfirm">确定</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 最近多少天 '3days' | '7days' | '1month' | '3months'-->
|
|
|
|
|
<view class="range-list">
|
|
|
|
|
<view class="range-item" :class="{active:lastType=='3days'}" @click="handleChoose('3days')">近3天</view>
|
|
|
|
|
<view class="range-item" :class="{active:lastType=='7days'}" @click="handleChoose('7days')">近7天</view>
|
|
|
|
|
<view class="range-item" :class="{active:lastType=='1month'}" @click="handleChoose('1month')">近1月</view>
|
|
|
|
|
<view class="range-item" :class="{active:lastType=='3months'}" @click="handleChoose('3months')">近3月</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 时间段 -->
|
|
|
|
|
<view class="range-to">
|
|
|
|
|
<view class="to-bg" :class="{blue:dateType==1}" @click="handleChooseDate(1,beginDate)">{{beginDate}}</view>
|
|
|
|
|
<view class="to">至</view>
|
|
|
|
|
<view class="to-bg" :class="{blue:dateType==2}" @click="handleChooseDate(2,endDate)">{{endDate}}</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 时间选择 -->
|
|
|
|
|
<picker-view class="picker-view" v-if="pickerVisible" :indicator-style="indicatorStyle"
|
|
|
|
|
:value="dateValueArr" @change="bindChange"
|
|
|
|
|
>
|
|
|
|
|
<picker-view-column>
|
|
|
|
|
<view class="item" v-for="(item,index) in years" :key="index">{{item}}</view>
|
|
|
|
|
</picker-view-column>
|
|
|
|
|
<picker-view-column>
|
|
|
|
|
<view class="item" v-for="(item,index) in months" :key="index">{{item}}</view>
|
|
|
|
|
</picker-view-column>
|
|
|
|
|
<picker-view-column>
|
|
|
|
|
<view class="item" v-for="(item,index) in days" :key="index">{{item}}</view>
|
|
|
|
|
</picker-view-column>
|
|
|
|
|
</picker-view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { ref,onMounted } from 'vue'
|
|
|
|
|
import { getDateRange } from '@/utils/datetime.js';
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
isShow:false,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
let years = ref([]);
|
|
|
|
|
let months= ref([]);
|
|
|
|
|
let days = ref([]);
|
|
|
|
|
let pickerVisible =ref(false)
|
|
|
|
|
let indicatorStyle=ref(`height: 88rpx`);
|
|
|
|
|
let dateValueArr = ref([])
|
|
|
|
|
|
|
|
|
|
// 默认最近3天
|
|
|
|
|
let lastType = ref('3days');
|
|
|
|
|
let dateType = ref('');
|
|
|
|
|
let beginDate = ref('');
|
|
|
|
|
let endDate = ref('');
|
|
|
|
|
|
|
|
|
|
// 初始化日期
|
|
|
|
|
const initDate=(date)=>{
|
|
|
|
|
for (let i = 1990; i <= date.getFullYear() + 61; i++) {
|
|
|
|
|
years.value.push(i)
|
|
|
|
|
}
|
|
|
|
|
for (let i = 1; i <= 12; i++) {
|
|
|
|
|
months.value.push(i.toString().padStart(2, '0'))
|
|
|
|
|
}
|
|
|
|
|
for (let i = 1; i <= 31; i++) {
|
|
|
|
|
days.value.push(i.toString().padStart(2, '0'))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用父类方法
|
|
|
|
|
const emit = defineEmits(['close','confirm'])
|
|
|
|
|
const handleClose = ()=>{
|
|
|
|
|
emit('close');
|
|
|
|
|
}
|
|
|
|
|
const handleConfirm = ()=>{
|
2025-11-20 17:54:50 +08:00
|
|
|
emit('confirm',{
|
|
|
|
|
startDate:beginDate.value,
|
|
|
|
|
endDate:endDate.value,
|
|
|
|
|
lastType:lastType.value
|
|
|
|
|
});
|
2025-11-20 17:45:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 选择最近
|
|
|
|
|
const handleChoose=(type)=>{
|
|
|
|
|
lastType.value = type;
|
|
|
|
|
|
|
|
|
|
let dateObj = getDateRange(type);
|
|
|
|
|
beginDate.value = dateObj.startDate;
|
|
|
|
|
endDate.value = dateObj.endDate;
|
|
|
|
|
|
|
|
|
|
pickerVisible.value = false;
|
|
|
|
|
dateType.value=""
|
|
|
|
|
}
|
|
|
|
|
// 选择开始或结束时间
|
|
|
|
|
const handleChooseDate=(type,dateStr)=>{
|
|
|
|
|
dateType.value = type;
|
|
|
|
|
pickerVisible.value = true;
|
|
|
|
|
lastType.value='';
|
|
|
|
|
// 回显picker
|
|
|
|
|
let strs = dateStr.split("-");
|
|
|
|
|
const yearIndex = years.value.findIndex(item => item == strs[0])
|
|
|
|
|
const monthIndex = months.value.findIndex(item => item == strs[1])
|
|
|
|
|
const dayIndex = days.value.findIndex(item => item == strs[2])
|
|
|
|
|
dateValueArr.value = [yearIndex, monthIndex, dayIndex];
|
|
|
|
|
// console.log(strs,dateValueArr.value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 切换日期
|
|
|
|
|
const bindChange= (e)=>{
|
|
|
|
|
const val = e.detail.value
|
|
|
|
|
let year = years.value[val[0]]
|
|
|
|
|
let month = months.value[val[1]]
|
|
|
|
|
let day = days.value[val[2]]
|
|
|
|
|
// console.log(year,month,day);
|
|
|
|
|
let dateStr = `${year}-${month}-${day}`;
|
|
|
|
|
if(dateType.value==1){//开始时间
|
|
|
|
|
beginDate.value = dateStr
|
|
|
|
|
}else{
|
|
|
|
|
endDate.value = dateStr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
let date = new Date();
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
const month = date.getMonth() + 1;
|
|
|
|
|
const day = date.getDate();
|
|
|
|
|
|
|
|
|
|
initDate(date);
|
|
|
|
|
|
|
|
|
|
const yearIndex = years.value.findIndex(item => item == year)
|
|
|
|
|
const monthIndex = months.value.findIndex(item => item == month)
|
|
|
|
|
const dayIndex = days.value.findIndex(item => item == day)
|
|
|
|
|
dateValueArr.value = [yearIndex, monthIndex, dayIndex];
|
|
|
|
|
|
|
|
|
|
// 默认近3天
|
|
|
|
|
let dateObj = getDateRange('3days');
|
|
|
|
|
beginDate.value = dateObj.startDate;
|
|
|
|
|
endDate.value = dateObj.endDate
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.date-con {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
background: rgba(0, 0, 0, 0.4);
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
|
|
|
|
|
.date-bg{
|
|
|
|
|
width:670rpx;
|
|
|
|
|
border-radius: 18rpx 18rpx 0 0;
|
|
|
|
|
padding:20rpx 40rpx;
|
|
|
|
|
position: fixed;
|
|
|
|
|
bottom:0;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
min-height: 650rpx;
|
|
|
|
|
.date-title{
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
.choose-title{
|
|
|
|
|
width:550rpx;
|
|
|
|
|
margin:0 auto;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color:#333;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
}
|
|
|
|
|
.date-confirm{
|
|
|
|
|
margin-left:auto;
|
|
|
|
|
color:#05A3F4;
|
|
|
|
|
font-size:28rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.range-list{
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
margin-top:30rpx;
|
|
|
|
|
.range-item{
|
|
|
|
|
width:150rpx;
|
|
|
|
|
border-radius: 10rpx;
|
|
|
|
|
border:1px solid #E8E8E8;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color:#333333;
|
|
|
|
|
font-size:28rpx;
|
|
|
|
|
padding:10rpx 0;
|
|
|
|
|
margin-right:15rpx;
|
|
|
|
|
}
|
|
|
|
|
.range-item.active{
|
|
|
|
|
border:1px solid #05A3F4;
|
|
|
|
|
color:#05A3F4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.range-to{
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
margin-top:30rpx;
|
|
|
|
|
.to-bg{
|
|
|
|
|
border:1px solid #F5F5F5;
|
|
|
|
|
background-color: #F5F5F5;
|
|
|
|
|
width:275rpx;
|
|
|
|
|
border-radius: 28rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color:#919191;
|
|
|
|
|
font-size:28rpx;
|
|
|
|
|
padding:8rpx 0;
|
|
|
|
|
}
|
|
|
|
|
.to-bg.blue{
|
|
|
|
|
border:1px solid #05A3F4;
|
|
|
|
|
color:#05A3F4;
|
|
|
|
|
background-color:#fff;
|
|
|
|
|
}
|
|
|
|
|
.to{
|
|
|
|
|
color:#333333;
|
|
|
|
|
font-size:28rpx;
|
|
|
|
|
margin:0 30rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.picker-view {
|
|
|
|
|
width: 670rpx;
|
|
|
|
|
height: 385rpx;
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
:deep(.item){
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 78rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|