Files
profitManage1.1/src/components/echartsList/dateTimeSelect.vue

263 lines
11 KiB
Vue
Raw Normal View History

2025-10-10 13:48:09 +08:00
<template>
<div class="ultabs" :style="{'margin-top': dateShowType && (dateShowType === 'day' || dateShowType === 'month') ? '35px' : '10px'}">
<div v-if="sideIcon" style="display: inline-block;padding-left: 1px;float: right;">
<el-dropdown trigger="click">
<span class="el-dropdown-link">
<i style="font-size: 1.5rem;margin-top: 5px;" class="el-icon-s-tools"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="item of sideIcon && sideIcon.iconName" class="clearfix">
<div @click="onChange(item)">{{item.name}}</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<ul style="display: inline-block;padding-left: 1px;vertical-align: middle;margin:0;float: right;">
<template v-if="dateShowType === 'day'">
<li :class="{ 'activesbgs' : isActive == 'DAY' }" @click="toggle('DAY',7)">前7天</li>
<li :class="{ 'activesbgs' : isActive == 'WEEK' }" @click="toggle('WEEK',15)">前15天</li>
<li :class="{ 'activesbgs' : isActive == 'MONTH' }" @click="toggle('MONTH')">前一个月</li>
</template>
<template v-if="dateShowType === 'month'">
<li :class="{ 'activesbgs' : isActive == 'THREEMONTH' }" @click="toggle('THREEMONTH', 3)">前三个月</li>
<li :class="{ 'activesbgs' : isActive == 'HALFYEAR' }" @click="toggle('HALFYEAR', 6)">前半年</li>
<li :class="{ 'activesbgs' : isActive == 'YEAR' }" @click="toggle('YEAR', 12)">前一年</li>
</template>
</ul>
<el-date-picker
v-model="dateRange"
2025-10-16 19:08:32 +08:00
:class="dateShowType === 'datetimerange' ? null : 'timeIconSty'"
:type="dateShowType === 'month' ? 'monthrange' : dateShowType === 'day' ? 'daterange' : dateShowType ? dateShowType : 'daterange'"
2025-10-10 13:48:09 +08:00
:start-placeholder="dateShowType === 'month' ? '开始日期' : '开始时间'"
:end-placeholder="dateShowType === 'month' ? '结束日期' : '结束时间'"
range-separator="至"
2025-10-16 19:08:32 +08:00
:format="dateShowType === 'month' ? 'yyyy-MM' : dateShowType === 'datetimerange' ? 'yyyy-MM-dd HH:mm:ss' : 'yyyy-MM-dd' "
:value-format="dateShowType === 'month' ? 'yyyy-MM' : dateShowType === 'datetimerange' ? 'yyyy-MM-dd HH:mm:ss' : 'yyyy-MM-dd'"
:style="{display: 'inline-block!important', verticalAlign: 'middle', marginRight: '10px', float: 'right', width: dateShowType === 'datetimerange' ? '75%!important' : '45%!important'}"
:default-time="dateShowType === 'datetimerange' ? ['12:00:00', '12:00:00'] : null"
2025-10-10 13:48:09 +08:00
@change="dateChange"/>
</div>
</template>
<script setup>
export default {
name: 'dateTimeSelect',
props: {
dateShowType: {
type: String,
default: null
},
sideIcon: {
type: Object,
default: () => {}
2025-10-16 19:08:32 +08:00
},
dateDataTrans: {
type: Object,
default: () => {}
}
},
watch: {
dateDataTrans: {
handler(val) {
if (val && val.dateRange) {
this.dateRange = val.dateRange;
}
},
deep: true,
immediate: true
2025-10-10 13:48:09 +08:00
}
},
data() {
return {
dateRange: [],
isActive: ''
}
},
// DOM 挂载完成后
mounted() {
this.isActive = this.dateShowType && this.dateShowType === 'day' ? 'MONTH' : 'YEAR';
// 可以访问 DOM 元素
// setTimeout(() => {
// // this.getLastDays(6);
// // this.getDaysOfPreviousMonth();
// this.$emit("dataChange", this.isActive, []);
// }, 500);
},
methods: {
toggle(val, num) {
this.isActive = val;
this.dateRange = [];
if (val && val === 'MONTH') {
this.getDaysOfPreviousMonth();
} else if (val && (val === 'THREEMONTH' || val === 'HALFYEAR' || val === 'YEAR')) {
this.getLastMonths(num);
} else {
this.getLastDays(num - 1);
}
},
// 时间选择器
dateChange() {
2025-10-16 19:08:32 +08:00
if (this.dateDataTrans && this.dateDataTrans.transList) {
this.getDaysOfPreviousMonth(this.dateRange[0], this.dateRange[1]);
} else {
this.$emit("dataChange", this.isActive, this.dateRange);
this.isActive = '';
}
2025-10-10 13:48:09 +08:00
},
// 获取当前日期前7天的所有日期格式YYYY-MM-DD
getLastDays(num) {
const dayList = [];
const today = new Date();
for (let i = num; i >= 0; i--) {
const d = new Date(today);
d.setDate(today.getDate() - i);
// 格式化日期为 YYYY-MM-DD
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
dayList.push(`${year}-${month}-${day}`);
}
let timeArr = [dayList[0], dayList[dayList.length - 1]];
this.$emit("dataChange", this.isActive, timeArr);
// this.$emit("dataChange", this.isActive, dayList);
},
// 获取前一个月的所有日期
getDaysOfPreviousMonth(star, end) {
// 1. 获取当前日期(终点日期)
2025-10-16 19:08:32 +08:00
let currentDate = new Date();
if (end) {
currentDate = new Date(end);
}
2025-10-10 13:48:09 +08:00
const endYear = currentDate.getFullYear();
const endMonth = currentDate.getMonth(); // 0=1月11=12月
const endDay = currentDate.getDate(); // 当前日如8
// 2. 计算起点日期当前日期的“上月同日”处理边界如3月31日→2月28/29日
2025-10-16 19:08:32 +08:00
let startDate = new Date(endYear, endMonth, endDay);
if (star) {
startDate = new Date(star);
} else {
// 核心将当前日期的月份减1得到上月同日自动处理天数不足问题
startDate.setMonth(startDate.getMonth() - 1);
}
// 日期后面的时间
let timeStar = '';
let timeEnd = '';
if (this.dateShowType === 'datetimerange') {
timeStar = String(new Date(startDate).getHours()).padStart(2, '0') + ':' + String(new Date(startDate).getMinutes()).padStart(2, '0') + ':' + String(new Date(startDate).getSeconds()).padStart(2, '0');
timeEnd = String(new Date(currentDate).getHours()).padStart(2, '0') + ':' + String(new Date(currentDate).getMinutes()).padStart(2, '0') + ':' + String(new Date(currentDate).getSeconds()).padStart(2, '0');
}
2025-10-10 13:48:09 +08:00
// 3. 提取起点日期的年、月、日(用于循环判断)
const startYear = startDate.getFullYear();
const startMonth = startDate.getMonth();
const startDay = startDate.getDate();
// 4. 循环生成“起点~终点”的所有日期
const dateCollection = [];
// 临时日期:从起点日期开始递增
const tempDate = new Date(startYear, startMonth, startDay);
// 循环条件:临时日期 <= 当前日期(终点)
while (tempDate <= currentDate) {
// 格式化日期为“YYYY-MM-DD”补零处理如8月→085日→05
const year = tempDate.getFullYear();
const month = String(tempDate.getMonth() + 1).padStart(2, '0');
const day = String(tempDate.getDate()).padStart(2, '0');
2025-10-16 19:08:32 +08:00
let formattedDate = `${year}-${month}-${day}`;
if (this.dateShowType === 'datetimerange') {
if (dateCollection && dateCollection.length <= 0) {
formattedDate = formattedDate + ' ' + timeStar;
} else {
formattedDate = formattedDate + ' ' + timeEnd;
}
}
2025-10-10 13:48:09 +08:00
dateCollection.push(formattedDate);
// 临时日期加1天进入下一天
tempDate.setDate(tempDate.getDate() + 1);
}
let timeArr = [dateCollection[0], dateCollection[dateCollection.length - 1]];
2025-10-16 19:08:32 +08:00
this.$emit("dataChange", this.isActive, {timeArr: timeArr, timeList: dateCollection});
2025-10-10 13:48:09 +08:00
// this.$emit("dataChange", this.isActive, oneMonthDays);
},
// 获取前三个月的月
getLastMonths(num) {
const threeMonths = [];
const today = new Date(); // 当前日期
const currentYear = today.getFullYear();
const currentMonth = today.getMonth() + 1; // 月份从0开始0=1月11=12月
// 循环获取前3个月i=0: 前1个月i=1: 前2个月i=2: 前3个月
for (let i = 1; i <= num; i++) {
// 计算目标月份(当前月 - i
let targetMonth = currentMonth - i;
let targetYear = currentYear;
// 处理月份溢出如1月-1=12月年份减1
if (targetMonth < 0) {
targetMonth += 12;
targetYear -= 1;
}
// 格式化月份为两位数如5月→'05'
const monthStr = String(targetMonth + 1).padStart(2, '0'); // 加1是因为月份从0开始
threeMonths.unshift(`${targetYear}-${monthStr}`);
}
let timeArr = [threeMonths[0], threeMonths[threeMonths.length - 1]];
this.$emit("dataChange", this.isActive, timeArr);
// this.$emit("dataChange", this.isActive, threeMonths);
},
onChange(val){
this.$emit("dataChange", null, null, val);
},
}
}
</script>
<style scoped>
::v-deep .el-range-editor .el-range-input {
vertical-align: super!important;
}
::v-deep .el-date-editor .el-range-separator {
vertical-align: super!important;
}
2025-10-16 19:08:32 +08:00
::v-deep .timeIconSty .el-range__close-icon {
2025-10-10 13:48:09 +08:00
margin-top: -38px;
margin-right: -14px;
}
.ultabs {
width: 500px;
float: right;
position: relative;
z-index: 9;
}
.ultabs ul li {
user-select: none;
cursor: pointer;
list-style: none;
display: inline-block;
width: 70px;
text-align: center;
height: 38px;
line-height: 38px;
}
/*.ultabs ul li:nth-child样式做了更改*/
.ultabs ul li {
border-radius: 4px;
border: 1px solid #CCCCCC;
margin: 0 5px;
}
.activesbgs {
color: #FFF;
background: #5D78FF;
cursor: pointer;
list-style: none;
display: inline-block;
width: 70px;
text-align: center;
height: 40px !important;
line-height: 40px !important;
border: 1px solid #5D78FF;
}
</style>