效果
Q
<div class="time-for-item" :class="{ 'no-margin-bottom': timeIndex === ruleForm.times.length - 1 }" v-for="( timeItem, timeIndex ) in ruleForm.times " :key="`${timeIndex}-time`">
<el-form-item :prop="'times.' + timeIndex + '.timeStart'" :rules="{ required: true, message: '开始时间不能为空', trigger: ['change', 'blur'] }">
<el-time-picker style="width: 165px;" clearable value-format="HH:mm:ss" format="HH:mm:ss" v-model="timeItem.timeStart" :picker-options="{ selectableRange: selectableRangeStartTime(timeIndex) }" placeholder="00:00:00" :disabled="see"></el-time-picker>
</el-form-item>
<span style="margin: 0 16px;">至</span>
<el-form-item :prop="'times.' + timeIndex + '.timeEnd'" :rules="{ required: true, message: '结束时间不能为空', trigger: ['change', 'blur'] }">
<el-time-picker style="width: 165px;" clearable value-format="HH:mm:ss" format="HH:mm:ss" v-model="timeItem.timeEnd" :picker-options="{ selectableRange: selectableRangeeEndTime(timeIndex) }" placeholder="23:59:59" :disabled="timeIndex !== 0 ? !timeItem.timeStart : false || see"></el-time-picker>
</el-form-item>
<i class="el-icon-delete del-time" :style="deleteTimeStyle" @click="deleteTime(timeIndex)"></i>
</div>
selectableRangeStartTime(timeIndex) {
let res = '00:00:00 - 23:59:59'
if (timeIndex !== 0) {
if (this.ruleForm.times[timeIndex - 1].timeEnd) {
res = `${adjustSecondInTimeString(this.ruleForm.times[timeIndex - 1].timeEnd)} - 23:59:59`
}
} else {
if (this.ruleForm.times[timeIndex].timeEnd) {
res = `00:00:00 - ${adjustSecondInTimeString(this.ruleForm.times[timeIndex].timeEnd, -1)}`
}
}
return res
},
selectableRangeeEndTime(timeIndex) {
let res = '00:00:00 - 23:59:59'
if (this.ruleForm.times[timeIndex].timeStart && this.ruleForm.times.length - 1 > timeIndex && this.ruleForm.times[timeIndex + 1].timeStart) {
res = `${adjustSecondInTimeString(this.ruleForm.times[timeIndex].timeStart)} - ${adjustSecondInTimeString(this.ruleForm.times[timeIndex + 1].timeStart, -1)}`
} else if (this.ruleForm.times[timeIndex].timeStart) {
res = `${adjustSecondInTimeString(this.ruleForm.times[timeIndex].timeStart)} - 23:59:59`
}
return res
},
添加到23:59:59 不允许再添加
addTime() {
if (this.see) return
const timeIndex = this.ruleForm.times.length
if (timeIndex === 0) {
this.ruleForm.times.push({
activityId: undefined,
timeStart: '00:00:00',
timeEnd: '23:59:59',
})
} else {
if (!this.ruleForm.times[timeIndex - 1].timeEnd) {
return this.$message.error('请填写完时间段,再添加!')
} else {
const timeString = this.ruleForm.times[timeIndex - 1].timeEnd
if (timeString === '23:59:59') {
return this.$message.error('当天时间已设置完毕,如需添加请调整')
}
const oneSecondLater = adjustSecondInTimeString(this.ruleForm.times[timeIndex - 1].timeEnd)
this.ruleForm.times.push({
activityId: undefined,
timeStart: oneSecondLater,
timeEnd: '23:59:59',
})
}
}
},
工具函数:
/**
* @param {string} time 字符串时分秒加1s/减1s
* @param {string} timeString 00:00:01
* @return {string} 00:00:02
*/
export function adjustSecondInTimeString(timeString, adjustment = 1) {
// 确保adjustment是1或-1
if (adjustment !== 1 && adjustment !== -1) {
throw new Error(
"Adjustment must be 1 (to add a second) or -1 (to subtract a second)."
);
}
let parts = timeString.split(":");
let hours = parseInt(parts[0], 10);
let minutes = parseInt(parts[1], 10);
let seconds = parseInt(parts[2], 10);
seconds += adjustment; // 增加或减少秒数
if (seconds < 0) {
// 如果秒数变为负数,从分钟中借一个单位
minutes--;
seconds += 60;
} else if (seconds >= 60) {
// 如果秒数大于等于60,进位到分钟
minutes++;
seconds -= 60;
}
if (minutes < 0) {
// 如果分钟数变为负数,从小时中借一个单位
hours--;
minutes += 60;
} else if (minutes >= 60) {
// 如果分钟数大于等于60,进位到小时
hours++;
minutes -= 60;
}
if (hours < 0) {
// 如果小时数变为负数,这通常表示一个错误,因为时间不应该有负的小时数
throw new Error("Time cannot have negative hours.");
} else if (hours >= 24) {
// 如果需要处理超过24小时的情况,可以在这里添加逻辑
// 例如,你可以将时间模24来获取一天内的时间
hours = hours % 24;
}
// 格式化小时、分钟和秒数,确保它们始终是两位数
hours = hours.toString().padStart(2, "0");
minutes = minutes.toString().padStart(2, "0");
seconds = seconds.toString().padStart(2, "0");
return hours + ":" + minutes + ":" + seconds;
}
缺点:一开始如果没有填好第一个时间 修改起来会比较麻烦
so 不加禁用全部放开 在提交的时候做处理
/**
* 判断传入的时间段数组是否存在重叠的时间段
*
* @param {times} 时间段数组,每个时间段是一个包含开始时间和结束时间的对象或数组
* @param {timeStart} 开始时间的键名或索引,用于从时间段对象或数组中获取开始时间
* @param {timeEnd} 结束时间的键名或索引,用于从时间段对象或数组中获取结束时间
* @returns 如果存在重叠的时间段,则返回true;否则返回false
*/
export function hasOverlappingTimes(times,timeStart,timeEnd) {
const toMinutes = (time) => {
const [hours, minutes, seconds] = time.split(":").map(Number);
return hours * 60 + minutes + seconds / 60;
};
const normalizedTimes = times.map((timePeriod) => ({
start: toMinutes(timePeriod[timeStart]),
end: toMinutes(timePeriod[timeEnd]),
}));
normalizedTimes.sort((a, b) => a.start - b.start);
for (let i = 0; i < normalizedTimes.length - 1; i++) {
const current = normalizedTimes[i];
const next = normalizedTimes[i + 1];
if (current.end > next.start) {
return true;
}
}
return false;
}