550 lines
19 KiB
Vue
550 lines
19 KiB
Vue
<template>
|
||
<div style="width: 540px">
|
||
<el-select v-model="interval" style="min-width: 90px; width: 90px; margin-right: 10px" @change="timeChange">
|
||
<el-option v-for="item in timeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||
</el-select>
|
||
|
||
<el-date-picker v-model="timeValue" type="daterange" :disabled="disabledPicker"
|
||
style="width: 220px; margin-right: 10px" unlink-panels :clearable="false" range-separator="至"
|
||
start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" :shortcuts="shortcuts" />
|
||
<el-button :disabled="backDisabled" type="primary" :icon="DArrowLeft" @click="preClick"></el-button>
|
||
<el-button type="primary" :icon="VideoPause" @click="nowTime">当前</el-button>
|
||
<el-button :disabled="preDisabled" type="primary" :icon="DArrowRight" @click="next"></el-button>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { DArrowLeft, VideoPause, DArrowRight } from '@element-plus/icons-vue'
|
||
import { ref, onMounted, nextTick, watch } from 'vue'
|
||
|
||
interface Props {
|
||
nextFlag?: boolean
|
||
theCurrentTime: boolean
|
||
}
|
||
|
||
const props = withDefaults(defineProps<Props>(), {
|
||
nextFlag: false,
|
||
theCurrentTime: false
|
||
})
|
||
|
||
const interval = ref(3)
|
||
const timeFlag = ref(1)
|
||
const count = ref(0)
|
||
const disabledPicker = ref(true)
|
||
const timeValue = ref()
|
||
const backDisabled = ref(false)
|
||
const preDisabled = ref(true)
|
||
const timeOptions: any = ref([
|
||
{ label: '年份', value: 1 },
|
||
{ label: '季度', value: 2 },
|
||
{ label: '月份', value: 3 },
|
||
{ label: '周', value: 4 },
|
||
{ label: '自定义', value: 5 }
|
||
])
|
||
const shortcuts = [
|
||
{
|
||
text: '最近一周',
|
||
value: () => {
|
||
const end = new Date()
|
||
const start = new Date()
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
|
||
return [start, end]
|
||
}
|
||
},
|
||
{
|
||
text: '最近一个月',
|
||
value: () => {
|
||
const end = new Date()
|
||
const start = new Date()
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
|
||
return [start, end]
|
||
}
|
||
},
|
||
{
|
||
text: '最近3个月',
|
||
value: () => {
|
||
const end = new Date()
|
||
const start = new Date()
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
|
||
return [start, end]
|
||
}
|
||
}
|
||
]
|
||
onMounted(() => {
|
||
timeChange(3)
|
||
})
|
||
// 选择时间范围
|
||
const timeChange = (e: number) => {
|
||
backDisabled.value = false
|
||
preDisabled.value = props.nextFlag ? false : true
|
||
count.value = 0
|
||
if (e == 1) {
|
||
disabledPicker.value = true
|
||
|
||
timeValue.value = [setTime(1), setTime()]
|
||
} else if (e == 2) {
|
||
disabledPicker.value = true
|
||
timeValue.value = [setTime(2), setTime()]
|
||
} else if (e == 3) {
|
||
disabledPicker.value = true
|
||
timeValue.value = [setTime(3), setTime()]
|
||
} else if (e == 4) {
|
||
let year = parseInt(setTime().substring(0, 4))
|
||
let month = parseInt(setTime().substring(5, 7))
|
||
let date = parseInt(setTime().substring(8, 10))
|
||
|
||
var start = new Date(year, month - 1, date)
|
||
var dayOfWeek = start.getDay() == 0 ? 7 : start.getDay() - 1 // 如果为周日,则置为7天
|
||
|
||
disabledPicker.value = true
|
||
timeValue.value = [setTime(0, dayOfWeek), setTime(0, -6 + dayOfWeek)]
|
||
} else if (e == 5) {
|
||
disabledPicker.value = false
|
||
backDisabled.value = true
|
||
preDisabled.value = props.nextFlag ? false : true
|
||
timeValue.value = [setTime(), setTime()]
|
||
}
|
||
if (e == 1 || e == 2) {
|
||
timeFlag.value = 0
|
||
} else {
|
||
timeFlag.value = 1
|
||
}
|
||
}
|
||
|
||
// 当前
|
||
const nowTime = () => {
|
||
console.log(interval.value, '000000000')
|
||
timeChange(interval.value)
|
||
}
|
||
// 上一个
|
||
const preClick = () => {
|
||
preDisabled.value = false
|
||
let startTime = timeValue.value[0]
|
||
let endTime = timeValue.value[1]
|
||
let year = parseInt(startTime.substring(0, 4))
|
||
let month = parseInt(startTime.substring(5, 7))
|
||
let date = parseInt(startTime.substring(8, 10))
|
||
//按月
|
||
if (interval.value == 3) {
|
||
// 换年份
|
||
if (month == 1) {
|
||
year = year - 1
|
||
startTime = year + '-12-01'
|
||
endTime = year + '-12-31'
|
||
} else if (month <= 10) {
|
||
month = month - 1
|
||
startTime = year + '-0' + month + '-01'
|
||
let day = getDays(year, month)
|
||
endTime = year + '-0' + month + '-' + day
|
||
} else {
|
||
month = month - 1
|
||
startTime = year + '-' + month + '-01'
|
||
let day = getDays(year, month)
|
||
endTime = year + '-' + month + '-' + day
|
||
}
|
||
//按周
|
||
} else if (interval.value == 4) {
|
||
//根据开始时间推
|
||
let start = new Date(year, month - 1, date)
|
||
start.setDate(start.getDate() - 7)
|
||
startTime = formatTime(start)
|
||
var end = new Date(start)
|
||
end.setDate(start.getDate() + 6)
|
||
endTime = formatTime(end)
|
||
//按季度
|
||
} else if (interval.value == 2) {
|
||
// 换年份
|
||
if (month == 1) {
|
||
year = year - 1
|
||
startTime = year + '-10-01'
|
||
endTime = year + '-12-31'
|
||
} else {
|
||
// 还是本年
|
||
month = month - 3
|
||
startTime = year + '-0' + month + '-01'
|
||
month = month + 2
|
||
var day = getDays(year, month)
|
||
endTime = year + '-0' + month + '-' + day
|
||
}
|
||
//自定义
|
||
} else if (interval.value == 1) {
|
||
year = year - 1
|
||
startTime = year + '-01-01'
|
||
endTime = year + '-12-31'
|
||
}
|
||
timeValue.value = [startTime, endTime]
|
||
|
||
// 判断向后键的状态
|
||
// var temp = NowgetEndTime()
|
||
// timeStatus(temp, endTime)
|
||
}
|
||
//下一个
|
||
const next = () => {
|
||
//向后
|
||
let startTime = timeValue.value[0]
|
||
let endTime = timeValue.value[1]
|
||
let year = parseInt(startTime.substring(0, 4))
|
||
let month = parseInt(startTime.substring(5, 7))
|
||
let date = parseInt(startTime.substring(8, 10))
|
||
var now = new Date()
|
||
// 获取当前年份
|
||
var presentY = now.getFullYear()
|
||
// 获取当前月份
|
||
var presentM = now.getMonth() + 1
|
||
// 获取当前日期
|
||
var presentD = now.getDate()
|
||
if (interval.value == 3) {
|
||
if (month == 12) {
|
||
year = year + 1
|
||
|
||
// 年份进位后,大于当前的年份,是不科学的
|
||
if (presentY < year && !props.nextFlag) {
|
||
startTime = presentY + '-12-01'
|
||
if (presentD < 10) {
|
||
endTime = presentY + '-12' + '-0' + presentD
|
||
} else {
|
||
endTime = presentY + '-12' + '-' + presentD
|
||
}
|
||
// 年份进位后,等于当前的年份
|
||
} else if (presentY == year) {
|
||
startTime = year + '-01-01'
|
||
if (presentM > 1) {
|
||
endTime = year + '-01-31'
|
||
} else {
|
||
if (presentD < 10) {
|
||
endTime = year + '-01' + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-01' + '-' + presentD
|
||
}
|
||
}
|
||
// 年份进位后,依旧小于当前的年份
|
||
} else {
|
||
startTime = year + '-01-01'
|
||
endTime = year + '-01-31'
|
||
}
|
||
} else {
|
||
month = month + 1
|
||
// 年份等于当前年份
|
||
if (presentY == year) {
|
||
// 月份超过当前月份,是不科学的
|
||
if (month >= presentM && !props.nextFlag) {
|
||
if (presentM < 10) {
|
||
startTime = year + '-0' + presentM + '-01'
|
||
if (presentD < 10) {
|
||
endTime = year + '-0' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-0' + presentM + '-' + presentD
|
||
}
|
||
} else {
|
||
startTime = year + '-' + presentM + '-01'
|
||
if (presentD < 10) {
|
||
endTime = year + '-' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-' + presentM + '-' + presentD
|
||
}
|
||
}
|
||
} else {
|
||
if (month < 10) {
|
||
startTime = year + '-0' + month + '-01'
|
||
var day = getDays(year, month)
|
||
endTime = year + '-0' + month + '-' + day
|
||
} else {
|
||
startTime = year + '-' + month + '-01'
|
||
var day = getDays(year, month)
|
||
endTime = year + '-' + month + '-' + day
|
||
}
|
||
}
|
||
// 年份小于当前的年份
|
||
} else {
|
||
if (month < 10) {
|
||
startTime = year + '-0' + month + '-01'
|
||
var day = getDays(year, month)
|
||
endTime = year + '-0' + month + '-' + day
|
||
} else {
|
||
startTime = year + '-' + month + '-01'
|
||
var day = getDays(year, month)
|
||
endTime = year + '-' + month + '-' + day
|
||
}
|
||
}
|
||
}
|
||
} else if (interval.value == 2) {
|
||
// 前进需要年份进位
|
||
if (month == 10) {
|
||
year = year + 1
|
||
// 年份进位后大于当前年份是不科学的
|
||
if (year > presentY && !props.nextFlag) {
|
||
startTime = presentY + '-10-01'
|
||
if (presentD < 10) {
|
||
endTime = year + '-' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-' + presentM + '-' + presentD
|
||
}
|
||
} else if (year == presentY) {
|
||
startTime = year + '-01-01'
|
||
// 当前月份大约3月份
|
||
if (presentM > 3) {
|
||
endTime = year + '-03-31'
|
||
} else {
|
||
// 当前月份也在第一季度里
|
||
if (presentD < 10) {
|
||
endTime = year + '-0' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-0' + presentM + '-' + presentD
|
||
}
|
||
}
|
||
} else {
|
||
startTime = year + '-01-01'
|
||
endTime = year + '-03-31'
|
||
}
|
||
} else {
|
||
month = month + 3
|
||
console.log('🚀 ~ next ~ presentM:', presentM, month)
|
||
|
||
// 季度进位后,超过当前月份是不科学的
|
||
if (year == presentY && !props.nextFlag) {
|
||
if (month >= presentM) {
|
||
// 当季度进位后大于当前月,以当前月的时间显示季度
|
||
if (presentM > 0 && presentM < 4) {
|
||
// 第一季度
|
||
startTime = year + '-01-01'
|
||
if (presentD < 10) {
|
||
endTime = year + '-0' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-0' + presentM + '-' + presentD
|
||
}
|
||
} else if (presentM > 3 && presentM < 7) {
|
||
console.log(123123)
|
||
// 第二季度
|
||
startTime = year + '-04-01'
|
||
if (presentD < 10) {
|
||
endTime = year + '-0' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-0' + presentM + '-' + presentD
|
||
}
|
||
} else if (presentM > 6 && presentM < 10) {
|
||
// 第三季度
|
||
startTime = year + '-07-01'
|
||
if (presentD < 10) {
|
||
endTime = year + '-0' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-0' + presentM + '-' + presentD
|
||
}
|
||
} else {
|
||
// 第四季度
|
||
startTime = year + '-10-01'
|
||
if (presentD < 10) {
|
||
endTime = year + '-' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = year + '-' + presentM + '-' + presentD
|
||
}
|
||
}
|
||
} else {
|
||
if (month == 10) {
|
||
startTime = year + '-' + month + '-01'
|
||
} else {
|
||
startTime = year + '-0' + month + '-01'
|
||
}
|
||
month = month + 2
|
||
if (month >= presentM) {
|
||
endTime = NowgetEndTime()
|
||
} else {
|
||
var day = getDays(year, month)
|
||
endTime = year + '-0' + month + '-' + day
|
||
}
|
||
}
|
||
} else {
|
||
if (month == 10) {
|
||
startTime = year + '-' + month + '-01'
|
||
month = month + 2
|
||
var day = getDays(year, month)
|
||
endTime = year + '-' + month + '-' + day
|
||
} else {
|
||
startTime = year + '-0' + month + '-01'
|
||
month = month + 2
|
||
var day = getDays(year, month)
|
||
endTime = year + '-0' + month + '-' + day
|
||
}
|
||
}
|
||
}
|
||
console.log(startTime, endTime)
|
||
} else if (interval.value == 5) {
|
||
} else if (interval.value == 4) {
|
||
//根据开始时间推
|
||
var start = new Date(year, month - 1, date)
|
||
start.setDate(start.getDate() + 7)
|
||
startTime = formatTime(start)
|
||
var end = new Date(start)
|
||
end.setDate(start.getDate() + 6)
|
||
endTime = formatTime(end)
|
||
} else {
|
||
year = year + 1
|
||
// 年份进位后大于当前年份,是不科学的
|
||
if (year >= presentY && !props.nextFlag) {
|
||
startTime = presentY + '-01-01'
|
||
if (presentM < 10) {
|
||
|
||
if (presentD < 10) {
|
||
endTime = presentY + '-0' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = presentY + '-0' + presentM + '-' + presentD
|
||
}
|
||
} else {
|
||
if (presentD < 10) {
|
||
endTime = presentY + '-' + presentM + '-0' + presentD
|
||
} else {
|
||
endTime = presentY + '-' + presentM + '-' + presentD
|
||
}
|
||
}
|
||
} else {
|
||
startTime = year + '-01-01'
|
||
endTime = year + '-12-31'
|
||
}
|
||
|
||
}
|
||
if (!props.nextFlag) {
|
||
if (new Date(endTime + ' 00:00:00').getTime() >= new Date(window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd ') + ' 00:00:00').getTime()) {
|
||
preDisabled.value = props.nextFlag ? false : true
|
||
}
|
||
}
|
||
|
||
|
||
timeValue.value = [startTime, endTime]
|
||
}
|
||
|
||
const setTime = (flag = 0, e = 0) => {
|
||
let dd = window.XEUtils.toDateString(new Date().getTime() - e * 3600 * 1000 * 24, 'dd')
|
||
|
||
let data = ''
|
||
|
||
if ((dd < 4 || dd == 0) && interval.value != 4 && !props.theCurrentTime) {
|
||
data = window.XEUtils.toDateString(new Date().getTime() - (e + dd) * 3600 * 1000 * 24, 'yyyy-MM-dd')
|
||
} else {
|
||
data = window.XEUtils.toDateString(new Date().getTime() - e * 3600 * 1000 * 24, 'yyyy-MM-dd')
|
||
}
|
||
|
||
if (flag == 1) {
|
||
data = data.slice(0, 5) + '01-01'
|
||
} else if (flag == 2) {
|
||
let quarter = parseInt(data.slice(5, 7))
|
||
if (0 < quarter && quarter <= 3) {
|
||
data = data.slice(0, 5) + '01-01'
|
||
} else if (3 < quarter && quarter <= 6) {
|
||
data = data.slice(0, 5) + '04-01'
|
||
} else if (6 < quarter && quarter <= 9) {
|
||
data = data.slice(0, 5) + '07-01'
|
||
} else {
|
||
data = data.slice(0, 5) + '10-01'
|
||
}
|
||
}
|
||
if (flag == 3) {
|
||
data = data.slice(0, 8) + '01'
|
||
}
|
||
|
||
return data
|
||
}
|
||
|
||
// 获取月份的天数
|
||
const getDays = (year: any, month: any) => {
|
||
let max = new Date(year, month, 0).getDate()
|
||
return max
|
||
}
|
||
// 时间格式化
|
||
const formatTime = (time: any) => {
|
||
return (
|
||
time.getFullYear() +
|
||
'-' +
|
||
(time.getMonth() + 1 < 10 ? '0' : '') +
|
||
(time.getMonth() + 1) +
|
||
'-' +
|
||
(time.getDate() < 10 ? '0' : '') +
|
||
time.getDate()
|
||
)
|
||
}
|
||
const NowgetEndTime = () => {
|
||
let now = new Date()
|
||
let sep = '-'
|
||
let year = now.getFullYear()
|
||
let month: any = now.getMonth() + 1
|
||
if (month < 10) {
|
||
month = '0' + month
|
||
}
|
||
let date: any = now.getDate()
|
||
if (date < 10) {
|
||
date = '0' + date
|
||
}
|
||
|
||
// 拼接当前的日期
|
||
let endTime = year + sep + month + sep + date
|
||
return endTime
|
||
}
|
||
const setTimeOptions = (list: any) => {
|
||
timeOptions.value = list
|
||
}
|
||
const setTheDate = (value: any) => {
|
||
interval.value = value
|
||
timeChange(value)
|
||
}
|
||
|
||
// 获取时间范围的同比
|
||
function getYearOnYear(startDate: string, endDate: string): [string, string] {
|
||
const startYearAgo = new Date(startDate)
|
||
startYearAgo.setFullYear(startYearAgo.getFullYear() - 1)
|
||
|
||
const endYearAgo = new Date(endDate)
|
||
endYearAgo.setFullYear(endYearAgo.getFullYear() - 1)
|
||
|
||
return [formatDate(startYearAgo), formatDate(endYearAgo)]
|
||
}
|
||
|
||
// 获取时间范围的环比
|
||
function getMonthOnMonth(startDate: string, endDate: string): [string, string] {
|
||
const start = new Date(startDate)
|
||
const end = new Date(endDate)
|
||
|
||
const diffTime = end.getTime() - start.getTime() + 60 * 60 * 24 * 1000 // 计算时间差
|
||
const startMonthAgo = new Date(start)
|
||
startMonthAgo.setTime(startMonthAgo.getTime() - diffTime) // 将开始时间向前推移相同的时间差
|
||
|
||
const endMonthAgo = new Date(start)
|
||
endMonthAgo.setDate(start.getDate() - 1) // 结束时间是开始时间的前一天
|
||
|
||
return [formatDate(startMonthAgo), formatDate(endMonthAgo)]
|
||
}
|
||
|
||
// 格式化日期为 YYYY-MM-DD
|
||
function formatDate(date: Date): string {
|
||
const year = date.getFullYear()
|
||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||
const day = String(date.getDate()).padStart(2, '0')
|
||
return `${year}-${month}-${day}`
|
||
}
|
||
defineExpose({ timeValue, interval, timeFlag, setTimeOptions, setTheDate, getYearOnYear, getMonthOnMonth, timeChange })
|
||
</script>
|
||
|
||
<style scoped>
|
||
.demo-date-picker {
|
||
display: flex;
|
||
width: 100%;
|
||
padding: 0;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.demo-date-picker .block {
|
||
padding: 30px 0;
|
||
text-align: center;
|
||
border-right: solid 1px var(--el-border-color);
|
||
flex: 1;
|
||
}
|
||
|
||
.demo-date-picker .block:last-child {
|
||
border-right: none;
|
||
}
|
||
|
||
.demo-date-picker .demonstration {
|
||
display: block;
|
||
color: var(--el-text-color-secondary);
|
||
font-size: 14px;
|
||
margin-bottom: 20px;
|
||
}
|
||
</style>
|