<template>
<div>
<div v-if="dateObj.includes(dateType)">
<div class="checkDate" v-if="checkMore">
<div class="leftDateDiv">
<el-date-picker @change="validateDate1And2"
v-model="dateValue1"
:type="dateType"
placeholder="请选择计划开始日期"
:disabled="disabled"
>
</el-date-picker>
</div>
<div class="middleDateDiv">至</div>
<div class="rightDateDiv">
<el-date-picker @change="validateDate2And1"
v-model="dateValue2"
:type="dateType"
placeholder="请选择计划结束日期"
:disabled="disabled"
>
</el-date-picker>
</div>
</div>
<div v-else style="width: 100%;">
<el-row type="flex" align="middle">
<el-col>
<el-dropdown trigger="click" :hide-on-click="dropdownHide" @command="dropdownFn">
<span>请选择重复规则<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu #default="dropdown">
<el-dropdown-item icon="el-icon-plus" style="width: max-content;height: max-content;">
<div style="width: 100%;height: 100%;">
<div style="margin-bottom: 20px;width: 100%;height: 20%;"
>
<el-button-group>
<el-row type="flex">
<el-col>
<el-button class="leftBtnRadio" type="success" :class="{clickedBtn:!isPlain1}"
size="mini"
@click="toggleChecked(1)"
>每天
</el-button>
</el-col>
<el-col>
<el-button class="secondBtnRadio" type="success" :class="{clickedBtn:!isPlain2}"
size="mini"
@click="toggleChecked(2)"
>周
</el-button>
</el-col>
<el-col v-if="allChecked">
<el-button v-if="!checkAllIscheckedOrcancel" class="allBtnRadio" type="success"
:class="{clickedBtn:!isPlain5}"
size="mini"
@click="CheckedAll"
>全选
</el-button>
<el-button v-else class="allBtnRadio" type="success" :class="{clickedBtn:!isPlain5}"
size="mini"
@click="CheckedAll"
>取消
</el-button>
</el-col>
<el-col>
<el-button class="threeBtnRadio" type="success" :class="{clickedBtn:!isPlain3}"
size="mini"
@click="toggleChecked(3)"
>月
</el-button>
</el-col>
<el-col>
<el-button class="rightBtnRadio" type="success" :class="{clickedBtn:!isPlain4}"
size="mini"
@click="toggleChecked(4)"
>年
</el-button>
</el-col>
</el-row>
</el-button-group>
</div>
<div
class="weeksDiv"
>
<!-- 周列表 -->
<div v-if="dateType1==='week'">
<span class="weeksSpan" v-for="(item) in weeksList" :key="item.label"
@click="changeWeekFn(item)" :class="{activeBgc:item.control}"
>{{ item.label }}</span>
</div>
<!-- 月列表 -->
<div v-else-if="dateType1==='month'">
<el-checkbox-group v-model="checkedMonthsList" @change="changeMonthFn">
<el-checkbox :label="item.label"
v-for="(item,) in monthsList"
:key="item.value"
>{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</div>
<!-- 年列表 -->
<div v-else-if="dateType1==='year'" class="defaultNoneTodayClass">
<el-date-picker
value-format="yyyy"
type="years"
:picker-options="YearPickerOptions"
@change="handleDatePickerChange"
v-model="checkedYearsList"
placeholder="选择一个或多个年"
>
</el-date-picker>
</div>
</div>
<div class="submitAndCancelBTN" v-if="checkedDateType">
<div style="width: max-content;height: 100%;margin-top: 30px;">
<el-button plain type="primary" @click="handleSubmit">确定</el-button>
<el-button plain @click="handleCancel">取消</el-button>
</div>
</div>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'timePicker',
props: {
dateType: {
required: true,
type: String,
default: 'week'
},
checkMore: {
type: Boolean,
default: true
},
dateArr: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: true
},
toggleEdit: {
type: Boolean,
default: true
}
},
computed: {
YearPickerOptions() {
return {
disabledDate: this.disabledDate
}
},
comWeeksOrMonthsList() {
return this.dateType1 === 'week' ? this.checkedWeekList.length === 7 : this.checkedMonthsList.length === 12
}
},
watch: {
dateType1(newValue, oldValue) {
if (newValue !== oldValue) {
if (oldValue === '' && (newValue === 'month' || newValue === 'week')) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = false
})
} else if (newValue === 'week' && (oldValue === 'year' || oldValue === 'date')) {
if (this.comWeeksOrMonthsList) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = true
this.isPlain2 = false
this.isPlain5 = false
})
} else if (!this.comWeeksOrMonthsList) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = false
this.isPlain2 = false
this.isPlain5 = true
})
}
} else if (newValue === 'month' && (oldValue === 'year' || oldValue === 'date')) {
if (this.comWeeksOrMonthsList) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = true
this.isPlain3 = false
this.isPlain5 = false
})
} else if (!this.comWeeksOrMonthsList) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = false
this.isPlain3 = false
this.isPlain5 = true
})
}
} else if (newValue === 'week' && oldValue === 'month') {
if (this.comWeeksOrMonthsList === false) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = false
})
} else if (this.comWeeksOrMonthsList === true) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = true
this.isPlain2 = false
this.isPlain5 = false
})
}
} else if (newValue === 'month' && oldValue === 'week') {
if (!this.comWeeksOrMonthsList) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = false
})
} else {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = true
this.isPlain3 = false
this.isPlain5 = false
})
}
}
}
},
comWeeksOrMonthsList(newValue, oldValue) {
if (newValue !== oldValue) {
if (newValue && this.dateType1 === 'week') {
this.checkAllIscheckedOrcancel = true
this.isPlain2 = false
this.isPlain5 = false
} else if (!newValue && this.dateType1 === 'week') {
this.checkAllIscheckedOrcancel = false
this.isPlain2 = false
this.isPlain5 = true
} else if (newValue && this.dateType1 === 'month') {
this.checkAllIscheckedOrcancel = true
this.isPlain3 = false
this.isPlain5 = false
} else if (!newValue && this.dateType1 === 'month') {
this.checkAllIscheckedOrcancel = false
this.isPlain3 = false
this.isPlain5 = true
}
}
}
},
data() {
return {
checkAllIscheckedOrcancel: true,
allChecked: false,
isPlain1: true,
isPlain2: true,
isPlain3: true,
isPlain4: true,
isPlain5: true,
dropdownHide: false,
dateType1: '',
cities: [
{ label: '一', value: 1 },
{ label: '二', value: 2 }
],
cities1: [
{ label: '每天', value: 1 },
{ label: '周', value: 2 },
{ label: '月', value: 3 },
{ label: '年', value: 4 }
],
weeksList: [
{ label: '日', value: 7, control: false },
{ label: '一', value: 1, control: false },
{ label: '二', value: 2, control: false },
{ label: '三', value: 3, control: false },
{ label: '四', value: 4, control: false },
{ label: '五', value: 5, control: false },
{ label: '六', value: 6, control: false }
],
monthsList: [
{ label: '一月', value: 1 },
{ label: '二月', value: 2 },
{ label: '三月', value: 3 },
{ label: '四月', value: 4 },
{ label: '五月', value: 5 },
{ label: '六月', value: 6 },
{ label: '七月', value: 7 },
{ label: '八月', value: 8 },
{ label: '九月', value: 9 },
{ label: '十月', value: 10 },
{ label: '十一月', value: 11 },
{ label: '十二月', value: 12 }
],
checkedWeekList: [],
checkedMonthsList: [],
checkedYearsList: [],
value2: '',
checkedDateType: '',
dateObj: ['year', 'date'],
dateObj1: [
{ date: 'year', value: 4 },
{ date: 'month', value: 3 },
{ date: 'week', value: 2 },
{
date: 'date',
value: 1
}
],
dateValue1: '',
dateValue2: '',
result: false,
yearArr: []
}
},
methods: {
disabledDate(time) {
const startYear = this.formatDate(this.dateArr[0], 1)
const endYear = this.formatDate(this.dateArr[1], 1)
const year = time.getFullYear()
return year < startYear || year > endYear
},
handleCancel() {
this.$emit('reEdit1')
this.$emit('toggleCheckMore')
},
checkTime(startTime, endTime, checkedDateType) {
const startDate = new Date(startTime)
const endDate = new Date(endTime)
const delta = (endDate - startDate) / (1000 * 60 * 60 * 24)
if (checkedDateType === 2) {
return delta >= 7
} else if (checkedDateType === 3) {
return delta >= 365
} else {
return true
}
},
async handleSubmit() {
switch (this.checkedDateType) {
case 1:
this.$emit('transferRepeatType', this.checkedDateType)
break
case 2:
if (this.dateType === 'date' && this.checkedDateType === 2 && Array.isArray(this.dateArr)) {
if (!this.checkTime(this.dateArr[0], this.dateArr[1], this.checkedDateType)) {
try {
await this.$confirm('所选计划日期不能完整覆盖一个重复周期,确认重选计划日期吗?')
this.dateValue1 = ''
this.dateValue2 = ''
this.$emit('reEdit')
return this.$emit('toggleCheckMore')
} catch (e) {
this.$emit('reEdit')
this.$emit('toggleCheckMore')
return this.$emit('toggleCheckMore')
}
}
}
const checkedWeekList = this.checkedWeekList.join()
console.log(checkedWeekList)
this.$emit('transferDate', checkedWeekList)
this.$emit('transferRepeatType', this.checkedDateType)
this.$emit('toggleCheckMore')
break
case 3:
if (this.dateType === 'date' && this.checkedDateType === 3 && Array.isArray(this.dateArr)) {
if (!this.checkTime(this.dateArr[0], this.dateArr[1], this.checkedDateType)) {
try {
await this.$confirm('所选计划日期不能完整覆盖一个重复周期,确认重选计划日期吗?')
this.dateValue1 = ''
this.dateValue2 = ''
this.$emit('reEdit')
return this.$emit('toggleCheckMore')
} catch (e) {
this.$emit('reEdit')
this.$emit('toggleCheckMore')
return this.$emit('toggleCheckMore')
}
}
}
let checkedMonthsList = []
this.checkedMonthsList.forEach(item => {
this.monthsList.forEach(item1 => {
if (item === item1.label) {
checkedMonthsList.push(item1)
}
})
})
checkedMonthsList = checkedMonthsList.map(item => item.value).join()
console.log(checkedMonthsList)
this.$emit('transferDate', checkedMonthsList)
this.$emit('transferRepeatType', this.checkedDateType)
this.$emit('toggleCheckMore')
break
case 4:
if (this.dateType === 'date' && this.checkedDateType === 4 && Array.isArray(this.dateArr)) {
if (!this.checkTime(this.dateArr[0], this.dateArr[1], 3)) {
try {
await this.$confirm('所选计划日期不能完整覆盖一个重复周期,确认重选计划日期吗?')
this.dateValue1 = ''
this.dateValue2 = ''
this.$emit('reEdit')
return this.$emit('toggleCheckMore')
} catch (e) {
this.$emit('reEdit')
this.$emit('toggleCheckMore')
return this.$emit('toggleCheckMore')
}
}
}
const checkedYearsList = this.checkedYearsList.join()
console.log(checkedYearsList)
this.$emit('transferDate', checkedYearsList)
this.$emit('transferRepeatType', this.checkedDateType)
this.$emit('toggleCheckMore')
break
default:
break
}
this.dropdownHide = true
if (!this.toggleEdit) {
this.$emit('toggleEdit', this.checkedDateType)
}
},
dropdownFn() {
this.dropdownHide = false
},
async handleDatePickerChange() {
if (this.dateType === 'date' && this.checkedDateType === 4 && Array.isArray(this.dateArr)) {
if (!this.checkTime(this.dateArr[0], this.dateArr[1], 3)) {
try {
await this.$confirm('所选计划日期不能完整覆盖一个重复周期,确认重选计划日期吗?')
this.dateValue1 = ''
this.dateValue2 = ''
this.$emit('reEdit')
return this.$emit('toggleCheckMore')
} catch (e) {
this.$emit('reEdit')
this.$emit('toggleCheckMore')
return this.$emit('toggleCheckMore')
}
}
}
await this.handleSubmit()
this.$emit('toggleCheckMore')
},
validateYearRange(dateValue1, dateValue2) {
const now1 = new Date(dateValue1)
const currentYear1 = now1.getFullYear()
const now2 = new Date(dateValue2)
const currentYear2 = now2.getFullYear()
return currentYear1 !== currentYear2 && currentYear2 - currentYear1 >= 2
},
validateDateRange(dateValue1, dateValue2) {
const startDate = new Date(dateValue1)
const endDate = new Date(dateValue2)
const diffTime = endDate.getTime() - startDate.getTime()
const diffDays = diffTime / (1000 * 3600 * 24)
return startDate !== endDate && startDate < endDate && diffDays >= 2
},
validateDate1And2() {
if (!(this.dateValue1 && this.dateValue2)) return
const arr = []
if (this.dateType === 'year') {
if (!this.validateYearRange(this.dateValue1, this.dateValue2)) {
return this.$message({
type: 'warning',
message: '请重新选择年份'
})
} else {
arr.push(this.dateValue1)
arr.push(this.dateValue2)
this.$emit('onetransferDate', arr)
this.$emit('toggleCheckMore')
this.$emit('toggleCycleTime')
}
} else if (this.dateType === 'date') {
if (!this.validateDateRange(this.dateValue1, this.dateValue2)) {
return this.$message({
type: 'warning',
message: '请重新选择日期'
})
} else {
arr.push(this.dateValue1)
arr.push(this.dateValue2)
this.$emit('onetransferDate', arr)
this.$emit('toggleCheckMore')
this.$emit('toggleCycleTime')
}
}
},
validateDate2And1() {
this.validateDate1And2()
},
changeMonthFn(arr) {
this.$emit('transferDate', arr)
},
CheckedAll() {
this.isPlain1 = true
this.isPlain2 = true
this.isPlain3 = true
this.isPlain4 = true
this.isPlain5 = !this.isPlain5
if (!this.isPlain5 && this.dateType1 === 'week') {
this.isPlain2 = false
this.checkAllIscheckedOrcancel = false
if (this.checkedWeekList.length !== 0) {
this.checkedWeekList.splice(0, this.checkedWeekList.length - 1)
}
this.weeksList.forEach(item => {
item.control = true
this.checkedWeekList.push(item.value)
this.checkedWeekList = this.checkedWeekList.filter((value, index, self) => {
return self.indexOf(value) === index
})
})
} else if (!this.isPlain5 && this.dateType1 === 'month') {
this.isPlain3 = false
this.checkAllIscheckedOrcancel = false
this.checkedMonthsList = []
this.monthsList.forEach(item => {
this.checkedMonthsList.push(item.label)
})
} else if (this.isPlain5 && this.dateType1 === 'week') {
this.checkAllIscheckedOrcancel = true
this.toggleCheckedPannel()
this.isPlain2 = false
this.weeksList.forEach(item => {
item.control = false
})
this.checkedWeekList = []
} else if (this.isPlain5 && this.dateType1 === 'month') {
this.checkAllIscheckedOrcancel = true
this.toggleCheckedPannel()
this.isPlain3 = false
this.checkedMonthsList = []
}
if (this.dateType1 === 'week' && !this.comWeeksOrMonthsList && !this.checkAllIscheckedOrcancel) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = true
})
}
},
toggleCheckedPannel() {
this.isPlain1 = true
this.isPlain2 = true
this.isPlain3 = true
this.isPlain4 = true
this.isPlain5 = true
},
toggleChecked(dateValue) {
this.checkedDateType = dateValue
switch (dateValue) {
case 1:
this.toggleCheckedPannel()
this.isPlain1 = false
this.allChecked = false
break
case 2:
this.toggleCheckedPannel()
this.isPlain2 = false
this.allChecked = true
break
case 3:
this.toggleCheckedPannel()
this.isPlain3 = false
this.allChecked = true
break
case 4:
this.toggleCheckedPannel()
this.isPlain4 = false
this.allChecked = false
break
default:
break
}
if ((this.dateType1 === 'week' || this.dateType1 === 'month') && this.comWeeksOrMonthsList) {
this.isPlain5 = false
}
this.dropdownHide = false
this.dateType1 = this.dateObj1.find(item => item.value === dateValue).date
},
changeWeekFn({ value: value1 }) {
this.weeksList.find(item => item.value === value1).control = !(this.weeksList.find(item => item.value === value1).control)
this.checkedWeekList.push(value1)
this.checkedWeekList = this.checkedWeekList.filter((value, index, self) => {
return self.indexOf(value) === index
})
this.weeksList.forEach((item) => {
this.checkedWeekList.forEach((item1, index1) => {
if (!item.control && item1 === item.value) {
this.checkedWeekList.splice(index1, 1)
}
})
})
if (this.dateType1 === 'week' && this.comWeeksOrMonthsList && this.checkAllIscheckedOrcancel) {
this.$nextTick(() => {
this.checkAllIscheckedOrcancel = false
this.isPlain5 = true
})
}
},
formatDate(date, dateType) {
const currentDate = new Date(date)
const year = currentDate.getFullYear()
const month = String(currentDate.getMonth() + 1).padStart(2, '0')
const day = String(currentDate.getDate()).padStart(2, '0')
if (dateType === 2) {
return `${year}-${month}-${day}`
} else if (dateType === 1) {
return year
}
}
}
}
</script>
<style lang="scss" scoped>
.checkDate {
display: flex;
align-items: center;
.leftDateDiv {
flex: 3;
margin: 0 10px;
}
.middleDateDiv {
flex: 1;
text-align: center;
}
.rightDateDiv {
flex: 3;
margin: 0 10px;
}
}
.optionNone {
display: none;
}
.weeksDiv {
width: 100%;
height: 40px;
margin: 40px 0;
line-height: 40px;
display: flex;
justify-content: space-evenly;
align-items: center;
.weeksSpan {
display: inline-block;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #fff;
text-align: center;
line-height: 30px;
color: #333333;
margin: 0 1px;
border: 1px solid rgba(18, 31, 50, 0.3);
&.activeBgc {
background-color: #4772fa;
}
}
}
.submitAndCancelBTN {
display: flex;
justify-content: center;
align-items: center;
}
.sixNextWrap {
white-space: pre-wrap;
}
.el-dropdown-menu__item {
background-color: #FFFFFF;
}
.el-dropdown-menu__item:hover {
background-color: #FFFFFF;
}
.leftBtnRadio {
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
background-color: #f4f4f4;
border: 0 solid red;
margin-right: 2px;
color: #333333;
}
.rightBtnRadio {
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
background-color: #f4f4f4;
border: 0 solid red;
color: #333333;
}
.secondBtnRadio {
background-color: #f4f4f4;
border: 0 solid red;
color: #333333;
margin-right: 2px;
}
.threeBtnRadio {
background-color: #f4f4f4;
border: 0 solid red;
color: #333333;
margin-right: 2px;
}
.allBtnRadio {
background-color: #f4f4f4;
border: 0 solid red;
color: #333333;
margin-right: 2px;
}
.clickedBtn {
background-color: #11b95c;
color: #FFFFFF;
}
</style>
**<!-- 时间组件的使用 -->**
<el-col :span="6">
<!-- 新增 timepicker -->
<time-picker ref="addDialog" @toggleCycleTime="toggleCycleTime" @reEdit1="reEdit1"
@toggleEdit="toggleEditFn1"
:toggleEdit="false"
:disabled="!(!isPlain1||!isPlain2)"
@transferRepeatType="transferRepeatTypeFn1"
:dateArr="dateArr"
@toggleCheckMore="toggleCheckMoreFn" :checkMore="checkMore"
@transferDate="transferDateFn" @onetransferDate="onetransferDateFn"
:dateType="dateType"
></time-picker>
</el-col>
<el-col :span="6">
<!-- 编辑 timepicker -->
<time-picker ref="editDialog" @toggleCycleTime="toggleCycleTime1" @reEdit1="reEdit1"
@reEdit="reEdit"
@toggleEdit="toggleEditFn" :toggleEdit="false"
:disabled="!(!isPlain1||!isPlain2)"
@transferRepeatType="transferRepeatTypeFn"
:dateArr="dateArr"
@toggleCheckMore="toggleCheckMoreFn" :checkMore="checkMore"
@transferDate="transferDateFn" @onetransferDate="onetransferDateFn"
:dateType="dateType"
></time-picker>
</el-col>

![点击并拖拽以移动]()

![点击并拖拽以移动]()

![点击并拖拽以移动]()

![点击并拖拽以移动]()