服务器下发业务、监控策略、脚本策略每次打开弹窗请求数据 ;交换机监控策略引用旧策略列表分页功能修改
自定义日期时间区间组件
This commit is contained in:
@@ -0,0 +1,892 @@
|
||||
<template>
|
||||
<div class="custom-datetime-range-picker">
|
||||
<!-- 输入框 -->
|
||||
<div
|
||||
class="el-input_parent el-input el-input--suffix"
|
||||
:class="{'is-focus': showPanel, 'is-disabled': disabled}"
|
||||
@click="togglePanel"
|
||||
ref="triggerRef"
|
||||
>
|
||||
<i class="el-input_dateIcon el-input__icon el-range__icon el-icon-time"></i>
|
||||
<input
|
||||
class="el-range-input el-input_first"
|
||||
type="text"
|
||||
readonly
|
||||
:placeholder="startPlaceholder"
|
||||
:value="displayValue[0]"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<span class="disInlineBlock textAlignCenter" style="width: 30px;">{{rangeSeparator}}</span>
|
||||
<input
|
||||
class="el-range-input el-input_second"
|
||||
type="text"
|
||||
readonly
|
||||
:placeholder="endPlaceholder"
|
||||
:value="displayValue[1]"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<span class="el-input__suffix" style="right: 5px!important;">
|
||||
<span class="el-input__suffix-inner">
|
||||
<i
|
||||
class="el-input__icon"
|
||||
:class="{'el-icon-circle-close': clearable && displayValue.length > 0}"
|
||||
@click.stop="clearSelection"
|
||||
></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 日期时间选择面板 -->
|
||||
<transition name="el-zoom-in-top">
|
||||
<div v-if="showPanel" class="el-picker-panel time-range-panel" :style="panelStyle" ref="panelRef">
|
||||
<div class="panel-body">
|
||||
<!-- 快捷选项 -->
|
||||
<template v-if="pickerOptions.shortcuts && pickerOptions.shortcuts.length > 0">
|
||||
<div class="quick-panel">
|
||||
<button
|
||||
type="button"
|
||||
class="el-picker-panel__shortcut"
|
||||
v-for="(shortcut, key) in pickerOptions.shortcuts"
|
||||
:key="key"
|
||||
@click="handleShortcutClick(shortcut)">{{shortcut.text}}</button>
|
||||
</div>
|
||||
<!-- 中间分隔线 -->
|
||||
<div class="panel-divider"></div>
|
||||
</template>
|
||||
<!-- 左侧:日期选择区域 -->
|
||||
<div class="date-panel">
|
||||
<!-- 开始结束时间选择 -->
|
||||
<div v-if="dateType === 'datetimerange'" style="padding: 8px 0 5px;">
|
||||
<el-time-picker v-model="startTime" :disabled="!(startDate && endDate)" size="small" style="width: 49%; margin-right: 1%;" placeholder="开始时间" />
|
||||
<el-time-picker v-model="endTime" :disabled="!(startDate && endDate)" size="small" style="width: 49%; margin-left: 1%;" placeholder="结束时间" />
|
||||
</div>
|
||||
<div style="width: 100%;height: 1px; background-color: #e4e7ed;"></div>
|
||||
<!-- 头部:年月切换 -->
|
||||
<div class="panel-header">
|
||||
<button
|
||||
type="button"
|
||||
class="icon-btn prev-year-btn"
|
||||
@click="prevYear"
|
||||
>
|
||||
<i class="el-icon-d-arrow-left"></i>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="icon-btn prev-month-btn"
|
||||
@click="prevMonth"
|
||||
>
|
||||
<i class="el-icon-arrow-left"></i>
|
||||
</button>
|
||||
<span class="header-label">
|
||||
{{ currentMonth }}年{{ currentDate }}月
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
class="icon-btn next-month-btn"
|
||||
@click="nextMonth"
|
||||
>
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="icon-btn next-year-btn"
|
||||
@click="nextYear"
|
||||
>
|
||||
<i class="el-icon-d-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 周几标题 -->
|
||||
<div class="weekdays">
|
||||
<div v-for="day in weekdays" :key="day" class="weekday">{{ day }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 日历表格 -->
|
||||
<div class="calendar">
|
||||
<div
|
||||
v-for="(day, index) in days"
|
||||
:key="index"
|
||||
class="day-cell"
|
||||
:class="getDayClass(day)"
|
||||
@click="selectDate(day)"
|
||||
>
|
||||
<div class="day-content">
|
||||
{{ day.date }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 面板底部 -->
|
||||
<div class="panel-footer">
|
||||
<div class="footer-actions w100" style="display: block;">
|
||||
<button
|
||||
type="button"
|
||||
class="footer-btn clear-btn"
|
||||
@click="clearSelection"
|
||||
>
|
||||
清空
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="el-button is-plain el-button--mini"
|
||||
:disabled="!(startDate && endDate)"
|
||||
@click="applySelection"
|
||||
>
|
||||
确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CustomDateTimeRangePicker',
|
||||
props: {
|
||||
dateType: {
|
||||
type: String,
|
||||
default: 'datetimerange'
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
startPlaceholder: {
|
||||
type: String,
|
||||
default: '开始日期'
|
||||
},
|
||||
endPlaceholder: {
|
||||
type: String,
|
||||
default: '结束日期'
|
||||
},
|
||||
rangeSeparator: {
|
||||
type: String,
|
||||
default: '至'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
default: 'YYYY-MM-DD HH:mm:ss'
|
||||
},
|
||||
defaultTime: {
|
||||
type: Array,
|
||||
default: () => ['00:00:00', '00:00:00']
|
||||
},
|
||||
pickerOptions: {
|
||||
type: Object,
|
||||
default: () => {shortcuts: []}
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottom-start',
|
||||
validator: (value) => ['bottom-start', 'bottom-end', 'top-start', 'top-end'].includes(value)
|
||||
},
|
||||
offset: {
|
||||
type: Number,
|
||||
default: 4 // 面板与触发器的距离
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const now = new Date();
|
||||
return {
|
||||
showPanel: false,
|
||||
currentDate: now.getMonth() + 1,
|
||||
currentMonth: now.getFullYear(),
|
||||
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
days: [],
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
panelStyle: {opacity: 0},
|
||||
actualPlacement: this.placement
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
displayValue() {
|
||||
if (this.value && this.value.length === 2 && this.value[0] && this.value[1]) {
|
||||
const start = this.formatDateTime(this.value[0]);
|
||||
const end = this.formatDateTime(this.value[1]);
|
||||
// return `${start} 至 ${end}`;
|
||||
return [start, end]
|
||||
}
|
||||
return [];
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
if (val && val.length === 2 && val[0] && val[1]) {
|
||||
const start = new Date(val[0]);
|
||||
const end = new Date(val[1]);
|
||||
this.startDate = start;
|
||||
this.endDate = end;
|
||||
if (this.dateType === 'datetimerange') {
|
||||
this.startTime = start;
|
||||
this.endTime = end;
|
||||
}
|
||||
// 同步月份显示
|
||||
this.currentMonth = start.getFullYear();
|
||||
this.currentDate = start.getMonth() + 1;
|
||||
} else {
|
||||
this.startDate = null;
|
||||
this.endDate = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
showPanel(val) {
|
||||
if (val) {
|
||||
this.generateCalendar();
|
||||
document.addEventListener('click', this.handleClickOutside);
|
||||
document.addEventListener('scroll', this.updatePanelPosition, true);
|
||||
window.addEventListener('resize', this.updatePanelPosition);
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.updatePanelPosition();
|
||||
},500);
|
||||
});
|
||||
} else {
|
||||
document.removeEventListener('click', this.handleClickOutside);
|
||||
document.removeEventListener('scroll', this.updatePanelPosition, true);
|
||||
window.removeEventListener('resize', this.updatePanelPosition);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.generateCalendar();
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener('click', this.handleClickOutside);
|
||||
document.removeEventListener('scroll', this.updatePanelPosition, true);
|
||||
window.removeEventListener('resize', this.updatePanelPosition);
|
||||
},
|
||||
methods: {
|
||||
// 更新面板位置
|
||||
updatePanelPosition() {
|
||||
if (!this.showPanel || !this.$refs.triggerRef || !this.$refs.panelRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
const trigger = this.$refs.triggerRef;
|
||||
const panel = this.$refs.panelRef;
|
||||
const viewport = {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
};
|
||||
|
||||
// 获取触发器位置
|
||||
const triggerRect = trigger.getBoundingClientRect();
|
||||
|
||||
// 计算面板基本尺寸
|
||||
const panelRect = panel.getBoundingClientRect();
|
||||
|
||||
// 应用最终位置
|
||||
if ((viewport.height - panelRect.height - triggerRect.top - 8) > 0) {
|
||||
this.panelStyle = {top: `100%`, opacity: 1};
|
||||
} else {
|
||||
this.panelStyle = {top: `${Math.round(viewport.height - panelRect.height - triggerRect.top - 8)}px`, opacity: 1};
|
||||
}
|
||||
},
|
||||
// 快捷选项点击事件
|
||||
handleShortcutClick(shortcut) {
|
||||
if (shortcut.onClick) {
|
||||
shortcut.onClick(this);
|
||||
}
|
||||
},
|
||||
generateCalendar() {
|
||||
const year = this.currentMonth;
|
||||
const month = this.currentDate - 1;
|
||||
const firstDayOfMonth = new Date(year, month, 1);
|
||||
const firstDayWeek = firstDayOfMonth.getDay();
|
||||
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||
const prevMonthDays = new Date(year, month, 0).getDate();
|
||||
|
||||
this.days = [];
|
||||
|
||||
// 添加上个月的天数
|
||||
for (let i = 0; i < firstDayWeek; i++) {
|
||||
const day = prevMonthDays - firstDayWeek + i + 1;
|
||||
this.days.push({
|
||||
date: day,
|
||||
month: 'prev',
|
||||
fullDate: new Date(year, month - 1, day)
|
||||
});
|
||||
}
|
||||
|
||||
// 添加当月天数
|
||||
for (let i = 1; i <= daysInMonth; i++) {
|
||||
this.days.push({
|
||||
date: i,
|
||||
month: 'current',
|
||||
fullDate: new Date(year, month, i)
|
||||
});
|
||||
}
|
||||
|
||||
// 添加下个月的天数
|
||||
const totalCells = 42; // 6行 * 7天
|
||||
const nextMonthDay = 1;
|
||||
while (this.days.length < totalCells) {
|
||||
this.days.push({
|
||||
date: nextMonthDay + (this.days.length - daysInMonth - firstDayWeek),
|
||||
month: 'next',
|
||||
fullDate: new Date(year, month + 1, nextMonthDay + (this.days.length - daysInMonth - firstDayWeek))
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
selectDate(day) {
|
||||
if (day.month !== 'current') {
|
||||
if (day.month === 'prev') {
|
||||
this.prevMonth();
|
||||
} else {
|
||||
this.nextMonth();
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.generateCalendar();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.startDate) {
|
||||
this.startDate = day.fullDate;
|
||||
} else if (!this.endDate) {
|
||||
this.endDate = day.fullDate;
|
||||
// 确保结束时间不早于开始时间
|
||||
if (this.endDate < this.startDate) {
|
||||
[this.startDate, this.endDate] = [this.endDate, this.startDate];
|
||||
}
|
||||
} else {
|
||||
this.startDate = day.fullDate;
|
||||
this.endDate = null;
|
||||
}
|
||||
if (this.startDate && this.endDate && this.dateType === 'datetimerange') {
|
||||
this.startTime = this.startTime ? this.startTime : new Date(0,0,0,this.defaultTime[0].split(':').map(Number)[0],this.defaultTime[0].split(':').map(Number)[1],this.defaultTime[0].split(':').map(Number)[2]);
|
||||
this.endTime = this.endTime ? this.endTime : new Date(0,0,0,this.defaultTime[1].split(':').map(Number)[0],this.defaultTime[1].split(':').map(Number)[1],this.defaultTime[1].split(':').map(Number)[2]);
|
||||
}
|
||||
},
|
||||
|
||||
getDayClass(day) {
|
||||
const classes = [];
|
||||
|
||||
if (day.month !== 'current') {
|
||||
classes.push('other-month');
|
||||
}
|
||||
|
||||
if (this.isToday(day.fullDate)) {
|
||||
classes.push('today');
|
||||
}
|
||||
|
||||
if (this.startDate && this.isSameDay(day.fullDate, this.startDate)) {
|
||||
classes.push('start-date');
|
||||
}
|
||||
|
||||
if (this.endDate && this.isSameDay(day.fullDate, this.endDate)) {
|
||||
classes.push('end-date');
|
||||
}
|
||||
|
||||
if (this.isInRange(day.fullDate)) {
|
||||
classes.push('in-range');
|
||||
}
|
||||
|
||||
return classes;
|
||||
},
|
||||
|
||||
isSameDay(date1, date2) {
|
||||
if (!date1 || !date2) return false;
|
||||
return date1.getDate() === date2.getDate() &&
|
||||
date1.getMonth() === date2.getMonth() &&
|
||||
date1.getFullYear() === date2.getFullYear();
|
||||
},
|
||||
|
||||
isInRange(date) {
|
||||
if (!this.startDate || !this.endDate) return false;
|
||||
const start = new Date(this.startDate);
|
||||
const end = new Date(this.endDate);
|
||||
start.setHours(0, 0, 0, 0);
|
||||
end.setHours(23, 59, 59, 999);
|
||||
return date >= start && date <= end;
|
||||
},
|
||||
|
||||
isToday(date) {
|
||||
const today = new Date();
|
||||
return date.getDate() === today.getDate() &&
|
||||
date.getMonth() === today.getMonth() &&
|
||||
date.getFullYear() === today.getFullYear();
|
||||
},
|
||||
applySelection() {
|
||||
if (this.startDate && this.endDate) {
|
||||
const start = new Date(this.startDate);
|
||||
const end = new Date(this.endDate);
|
||||
if (this.dateType === 'datetimerange') {
|
||||
start.setHours(
|
||||
this.startTime.getHours(),
|
||||
this.startTime.getMinutes(),
|
||||
this.startTime.getSeconds()
|
||||
);
|
||||
end.setHours(
|
||||
this.endTime.getHours(),
|
||||
this.endTime.getMinutes(),
|
||||
this.endTime.getSeconds()
|
||||
);
|
||||
}
|
||||
if (start > end) {
|
||||
this.$message.error('开始时间不能晚于结束时间');
|
||||
return;
|
||||
}
|
||||
let startFormat = this.formatDateTime(start);
|
||||
let endFormat = this.formatDateTime(end);
|
||||
this.$emit('change', [startFormat, endFormat]);
|
||||
this.$emit('input', [startFormat, endFormat]);
|
||||
this.showPanel = false;
|
||||
}
|
||||
},
|
||||
|
||||
clearSelection() {
|
||||
this.startDate = null;
|
||||
this.endDate = null;
|
||||
this.startTime = '';
|
||||
this.endTime = '';
|
||||
this.$emit('change', []);
|
||||
this.$emit('input', []);
|
||||
if (this.showPanel) {
|
||||
this.closePanel();
|
||||
}
|
||||
},
|
||||
|
||||
closePanel() {
|
||||
this.showPanel = false;
|
||||
},
|
||||
|
||||
togglePanel() {
|
||||
if (this.disabled) return;
|
||||
this.showPanel = !this.showPanel;
|
||||
},
|
||||
|
||||
prevMonth() {
|
||||
this.currentDate--;
|
||||
if (this.currentDate < 1) {
|
||||
this.currentDate = 12;
|
||||
this.currentMonth--;
|
||||
}
|
||||
this.generateCalendar();
|
||||
},
|
||||
|
||||
nextMonth() {
|
||||
this.currentDate++;
|
||||
if (this.currentDate > 12) {
|
||||
this.currentDate = 1;
|
||||
this.currentMonth++;
|
||||
}
|
||||
this.generateCalendar();
|
||||
},
|
||||
|
||||
prevYear() {
|
||||
this.currentMonth--;
|
||||
this.generateCalendar();
|
||||
},
|
||||
|
||||
nextYear() {
|
||||
this.currentMonth++;
|
||||
this.generateCalendar();
|
||||
},
|
||||
|
||||
handleClickOutside(event) {
|
||||
if (!this.$el.contains(event.target)) {
|
||||
this.showPanel = false;
|
||||
}
|
||||
},
|
||||
|
||||
formatDateTime(date) {
|
||||
if (!date) return '';
|
||||
const d = new Date(date);
|
||||
const year = d.getFullYear();
|
||||
const month = (d.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = d.getDate().toString().padStart(2, '0');
|
||||
const hour = d.getHours().toString().padStart(2, '0');
|
||||
const minute = d.getMinutes().toString().padStart(2, '0');
|
||||
|
||||
if (this.format === 'YYYY-MM-DD HH:mm:ss' || this.format === 'yyyy-MM-dd HH:mm:ss') {
|
||||
const second = d.getSeconds().toString().padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
||||
} else if (this.format === 'YYYY-MM-DD' || this.format === 'yyyy-MM-dd') {
|
||||
return `${year}-${month}-${day}`;
|
||||
} else {
|
||||
if (this.dateType === 'datetimerange') {
|
||||
const second = d.getSeconds().toString().padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
||||
} else if (this.dateType === 'daterange') {
|
||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-datetime-range-picker {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
/* 输入框前面的按钮*/
|
||||
.el-input_dateIcon {
|
||||
position: absolute;
|
||||
}
|
||||
.el-range__icon {
|
||||
font-size: 14px;
|
||||
color: #c0c4cc;
|
||||
float: left;
|
||||
line-height: 32px;
|
||||
}
|
||||
/* 输入框样式 */
|
||||
.el-input_parent {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dcdfe6;
|
||||
padding: 1px 0;
|
||||
}
|
||||
.el-input_parent:hover {
|
||||
border-color: #c0c4cc;
|
||||
}
|
||||
|
||||
.el-input_parent.is-focus {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.el-input_parent.is-disabled {
|
||||
background-color: #f5f7fa;
|
||||
border-color: #e4e7ed;
|
||||
color: #c0c4cc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.el-input_first {
|
||||
padding: 0 0 0 25px;
|
||||
}
|
||||
.el-input_second {
|
||||
padding: 0 30px 0 0;
|
||||
}
|
||||
.el-range-input {
|
||||
-webkit-appearance: none;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
color: #606266;
|
||||
display: inline-block;
|
||||
font-size: inherit;
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
width: calc((100% - 30px) / 2);
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
display: none;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
right: 5px!important;
|
||||
top: 0;
|
||||
text-align: center;
|
||||
color: #c0c4cc;
|
||||
transition: all 0.3s;
|
||||
pointer-events: none;
|
||||
}
|
||||
/*.el-input:hover .el-input__suffix {*/
|
||||
/* display: block;*/
|
||||
/*}*/
|
||||
|
||||
.el-input_parent:hover .el-input__suffix {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.el-input__suffix-inner {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.el-input__icon {
|
||||
height: 100%;
|
||||
width: 25px;
|
||||
text-align: center;
|
||||
transition: all 0.3s;
|
||||
line-height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-input__icon:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.el-icon-close:hover {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
/* 面板容器 */
|
||||
.time-range-panel {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
z-index: 2001;
|
||||
margin-top: 5px;
|
||||
background: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
display: flex;
|
||||
min-height: 350px;
|
||||
}
|
||||
/* 快捷选项面板 */
|
||||
.quick-panel {
|
||||
width: 110px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
/* 左侧日期面板 */
|
||||
.date-panel {
|
||||
/*flex: 1;*/
|
||||
width: 320px;
|
||||
padding: 0 20px 20px;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.icon-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: #303133;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.icon-btn:hover {
|
||||
background-color: #f5f7fa;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.header-label {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.header-label:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
/* 周几标题 */
|
||||
.weekdays {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 4px;
|
||||
margin-bottom: 12px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.weekday {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #606266;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
/* 日历表格 */
|
||||
.calendar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
grid-template-rows: repeat(6, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.day-cell {
|
||||
height: 36px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.day-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.day-cell:hover .day-content {
|
||||
background-color: #f2f6fc;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.day-cell.today .day-content {
|
||||
color: #409eff;
|
||||
font-weight: 500;
|
||||
border: 1px solid #409eff;
|
||||
}
|
||||
|
||||
.day-cell.other-month .day-content {
|
||||
color: #c0c4cc;
|
||||
}
|
||||
|
||||
.day-cell.start-date .day-content,
|
||||
.day-cell.end-date .day-content {
|
||||
background: #409eff;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.day-cell.in-range:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #f0f9ff;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.day-cell.start-date.in-range:before {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.day-cell.end-date.in-range:before {
|
||||
right: 50%;
|
||||
}
|
||||
|
||||
/* 中间分隔线 */
|
||||
.panel-divider {
|
||||
width: 1px;
|
||||
background-color: #e4e7ed;
|
||||
/*margin: 20px 0;*/
|
||||
}
|
||||
|
||||
/* 面板底部 */
|
||||
.panel-footer {
|
||||
padding: 4px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.footer-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.clear-btn {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.clear-btn:hover {
|
||||
color: #66b1ff;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.footer-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* Element UI 按钮样式 */
|
||||
.el-button {
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
border: 1px solid #dcdfe6;
|
||||
color: #606266;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
margin: 0;
|
||||
transition: 0.1s;
|
||||
font-weight: 500;
|
||||
padding: 7px 15px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.el-button--mini {
|
||||
padding: 7px 15px;
|
||||
font-size: 12px;
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.is-plain:hover {
|
||||
color: #409eff;
|
||||
background: #fff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.is-plain:disabled, .is-plain:disabled:hover {
|
||||
cursor: not-allowed;
|
||||
background: #fff;
|
||||
border-color: #ebeef5;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
::v-deep .el-input.is-disabled .el-range-input {
|
||||
background: #F5F7FA!important;
|
||||
border-color: #e4e7ed!important;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user