选择时间段控件
实现的具体代码
<!--
* @Descripttion: 选择时间段
* @version:
* @Company: 广州工程建设监理系统
* @Author: WYH
* @Date: 2022-09-08 17:29:26
* @LastModifiedTime:
-->
<template>
<el-dialog custom-class="customWidth" v-model="timeQuantumProps.show" title="选择时间段" width="29%">
<div class="gantt-chart">
<div class="scale-line">
<div class="scale-box">
<span v-for="item in [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]" :key="item">{{ item }}</span>
</div>
<div class="line-box">
<span v-for="item in 12" :key="item"></span>
</div>
</div>
<div class="table-chart">
<div class="set-date-table" v-for="(item, index) in weektableDate" :key="item.week">
<div class="week">{{ item.weekName }}</div>
<div class="scale-line-week"></div>
<div class="table-box">
<div class="progress-bar" v-for="(t,k) in 6" :key="t"
:style="{ 'left': item['left' + k], 'right': item['right' + k] }"
v-show="(item['left' + k]&&item['right' + k])" @click="cancelingSchedule(item,k)"></div>
<div class="box" :style="[1, 3, 5].includes(index) ? 'background:#E3E5E8' : ''" v-for="val in 48 * 3"
:key="val" @mousedown="(event)=>{onmousedown(event,item,index)}" @mouseup="(event)=>{onmouseup(event,item,index)}"></div>
</div>
<el-button class="bth" type="primary" size="small" @click="setUpTheClick(item)">设置</el-button>
</div>
</div>
</div>
<div class="select-time-area">
<div class="week-select">
<el-checkbox v-model="allweek" label="全部" size="large" :disabled="timeQuantumProps.disabled"
@change="selectAllWeek" />
<el-checkbox v-for="item in TimeData" :key="item.week" v-model="item.weekBooleanVal" :label="item.weekName"
size="large" :disabled="item.currentBool || timeQuantumProps.disabled" />
</div>
<div class="time-select" v-for="item in TimeData" :key="item.week" v-show="item.currentBool">
<div class="time-box" v-for="(val, key) in item.periods" :key="key">
<el-checkbox v-model="val.booleanVal" :label="val.time" size="large"
:disabled="timeQuantumProps.disabled" @change="operationTimeRange(item, val, key)" />
<el-time-picker style="margin-left:10px" size="default" v-model="val.value" is-range range-separator="-"
value-format="HH:mm:ss" :disabled="timeQuantumProps.disabled"
@change="operationTimeRange(item, val, key)" />
</div>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="timeQuantumProps.show = false">取 消</el-button>
<el-button v-show="!timeQuantumProps.disabled" type="primary" @click="submit">确 定</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup name="WarningNoticeAddedEdit">
import { onMounted, reactive, ref } from 'vue'
const props = defineProps({
timeQuantumProps: {
type: Object,
default: () => { },
require: true
}
})
const weektableDate = reactive([
{ week: 7, weekName: '星期日', left0: '0px', right0: '0px' },
{ week: 1, weekName: '星期一', left0: '0px', right0: '0px' },
{ week: 2, weekName: '星期二', left0: '0px', right0: '0px' },
{ week: 3, weekName: '星期三', left0: '0px', right0: '0px' },
{ week: 4, weekName: '星期四', left0: '0px', right0: '0px' },
{ week: 5, weekName: '星期五', left0: '0px', right0: '0px' },
{ week: 6, weekName: '星期六', left0: '0px', right0: '0px' }
])
const allweek = ref(false)
const TimeData = reactive([])
const initializeDefaultData = () => {
const weekData = {
0: '星期日',
1: '星期一',
2: '星期二',
3: '星期三',
4: '星期四',
5: '星期五',
6: '星期六'
}
for (let i = 0; i < 7; i++) {
const periods = []
for (let j = 1; j < 7; j++) {
periods.push({
time: '时间段' + j,
value: ['00:00:00', '23:59:59'],
booleanVal: j === 1
})
}
TimeData.push({
periods,
week: i === 0 ? 7 : i,
weekName: weekData[i],
weekBooleanVal: i === 0,
currentBool: i === 0
})
}
console.log(TimeData, 'TimeData')
}
initializeDefaultData()
const setUpTheClick = (value) => {
TimeData.map(item => {
Object.assign(item, {
weekBooleanVal: value.week === item.week,
currentBool: value.week === item.week
})
})
}
watch(() => TimeData, val => {
const boollist = val.map(item => item.weekBooleanVal).filter(Boolean)
allweek.value = boollist.length >= 7
}, { deep: true, immediate: true })
function selectAllWeek (rows) {
TimeData.map(item => {
Object.assign(item, {
weekBooleanVal: rows
})
})
}
function cancelingSchedule (item, k) {
delete item['left' + k]
delete item['right' + k]
const data = TimeData.find(va => va.week === item.week)
data.periods.map((e, i) => {
if (i === k) {
Object.assign(e, {
booleanVal: false,
value: ['00:00:00', '23:59:59']
})
}
})
}
function operationTimeRange (item, rows, key) {
if (rows.booleanVal) {
periodContrastProcessing(item, rows)
} else {
const _rows = item.periods.find(e => e.booleanVal)
if (_rows) {
periodContrastProcessing(item, _rows)
}
}
}
function periodContrastProcessing (item, rows) {
const { leftOffset, rightOffset } = calculateOffset(item, rows)
const trueList = item.periods.filter(i => i.booleanVal)
trueList.map((val, key) => {
const data = calculateOffset(item, val)
Object.assign(weektableDate.find(t => t.week === item.week), {
['left' + key]: data.leftOffset + 'px',
['right' + key]: data.rightOffset + 'px'
})
})
}
function calculateOffset (item, rows) {
const stra = countTotalNumberSeconds(rows.value[0])
const end = countTotalNumberSeconds(rows.value[1])
const secondsOffset = 18.07 / (60 * 60)
const leftOffset = secondsOffset * stra
const rightOffset = secondsOffset * (countTotalNumberSeconds('23:59:59') - end)
return { leftOffset, rightOffset }
}
const countTotalNumberSeconds = (timeStr) => {
const timeList = timeStr.split(':')
const seconds = (Number(timeList[0]) * 60 * 60) + (Number(timeList[1]) * 60) + Number(timeList[2])
return seconds
}
if (props.timeQuantumProps.ruleForm[props.timeQuantumProps.tag]) {
const data = JSON.parse(props.timeQuantumProps.ruleForm[props.timeQuantumProps.tag])
const TimeDataMap = new Map()
data.map(item => {
TimeDataMap.set(item.week, item)
})
TimeData.map(rows => {
if (TimeDataMap.get(rows.week)) {
const { periods } = TimeDataMap.get(rows.week)
rows.periods.map((v, k) => {
if (periods[k]) {
Object.assign(v, {
booleanVal: true,
value: [periods[k]?.start, periods[k]?.end]
})
operationTimeRange(rows, v, k)
}
})
}
})
}
const pageXValue = ref(undefined)
const onmousedown = (e, item, index) => {
pageXValue.value = e.pageX
console.log('鼠标按下=>', e.pageX, index)
}
const onmouseup = (e, item, index) => {
const a = document.getElementsByClassName('table-box')
const tableBox = a[index].getBoundingClientRect()
console.log('鼠标抬起=>', e.pageX, index, tableBox.left, tableBox.right, tableBox)
if (e.pageX === pageXValue.value) return
const secondsOffset = 18.07 / (60 * 60)
const start = pageXValue.value < e.pageX ? secTotime((pageXValue.value - tableBox.left) / secondsOffset) : secTotime((e.pageX - tableBox.left) / secondsOffset)
const end = pageXValue.value < e.pageX ? secTotime(((e.pageX - tableBox.left)) / secondsOffset) : secTotime((pageXValue.value - tableBox.left) / secondsOffset)
const data = TimeData.find(val => val.week === item.week)
const _rows = data.periods.filter(item => !item.booleanVal)
if (_rows.length) {
Object.assign(data.periods[data.periods.indexOf(_rows[0])], {
booleanVal: true,
value: [start, end]
})
operationTimeRange(data, data.periods, data.periods.indexOf(_rows[0]))
}
console.log('计算偏移量=>', secTotime((pageXValue.value - tableBox.left) / secondsOffset), secTotime(((e.pageX - pageXValue.value) + (pageXValue.value - tableBox.left)) / secondsOffset), _rows, data.periods.indexOf(_rows[0]))
}
const secTotime = (s) => {
let t = ''
if (s > -1) {
const hour = Math.floor(s / 3600)
const min = Math.floor(s / 60) % 60
const sec = s % 60
if (hour < 10) {
t = '0' + hour + ':'
} else {
t = hour + ':'
}
if (min < 10) {
t += '0'
}
t += min + ':'
if (sec < 10) {
t += '0'
}
t += sec.toFixed(0)
}
return t
}
const currentCpn = getCurrentInstance()
const parent = currentCpn.parent
function submit () {
const resultsData = []
const selectData = TimeData.filter(item => item.weekBooleanVal)
selectData.map(val => {
const obj = {
week: val.week,
periods: []
}
val.periods.map(e => {
if (e.booleanVal) {
obj.periods.push({ start: e.value[0], end: e.value[1] })
}
})
resultsData.push(obj)
})
props.timeQuantumProps.ruleForm[`${props.timeQuantumProps.tag}s`] = resultsData
props.timeQuantumProps.ruleForm[`${props.timeQuantumProps.tag}`] = JSON.stringify(resultsData)
props.timeQuantumProps.show = false
console.log('resultsData', resultsData, props.timeQuantumProps.ruleForm)
}
</script>
<style lang="scss">
.customWidth {
min-width: 620px !important;
}
</style>
<style lang="scss" scoped>
.dialog-footer button:first-child {
margin-right: 10px;
}
.gantt-chart {
.scale-line {
margin-left: 50px;
.scale-box {
margin-bottom: 10px;
margin-left: -4px;
display: flex;
span {
width: 18px;
height: 16px;
display: block;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 13px;
color: #313442;
margin-right: 18px;
}
}
.line-box {
width: 435px;
display: flex;
position: relative;
&::after {
content: '';
position: absolute;
width: 1.5px;
height: 8px;
bottom: 0;
right: 0;
background: #C6C7CA;
}
span {
display: block;
width: 40px;
height: 1.5px;
background: #C6C7CA;
position: relative;
&::before {
content: '';
position: absolute;
width: 1.5px;
height: 8px;
bottom: 0;
left: 0;
background: #C6C7CA;
}
&::after {
content: '';
position: absolute;
width: 1.5px;
height: 5px;
bottom: 0;
left: 50%;
background: #C6C7CA;
}
}
}
}
.table-chart {
margin-top: 2px;
.set-date-table {
display: flex;
align-content: center;
height: 28px;
line-height: 28px;
.week {
width: 39px;
height: 16px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 13px;
color: #313442;
margin-right: 8px;
}
.scale-line-week {
width: 1.5px;
height: 28px;
background: #C6C7CA;
margin-right: 2px;
position: relative;
&::before {
content: '';
position: absolute;
width: 1.5px;
height: 6px;
top: -2px;
left: -2px;
background: #C6C7CA;
transform: rotate(90deg);
}
}
&:last-child {
.scale-line-week {
&::after {
content: '';
position: absolute;
width: 1.5px;
height: 5px;
bottom: -3px;
left: -2px;
background: #C6C7CA;
transform: rotate(90deg);
}
}
.table-box {
border-bottom: 1px solid #C6C7CA;
}
}
.table-box {
width: 435px;
display: flex;
flex-wrap: wrap;
position: relative;
border-right: 1px solid #C6C7CA;
cursor: crosshair;
.progress-bar {
position: absolute;
height: 9px;
left: 0px;
right: 0px;
background: #21E88D;
}
.box {
width: 2.083%;
height: 9px;
background: #F2F4F7;
// background: #21E88D;
border: 1px solid #C6C7CA;
border-right: none;
border-bottom: none;
}
}
.bth {
margin-left: 9px;
}
}
}
}
.select-time-area {
width: 580px;
background: #F7F8FA;
border: 1px solid #EFF0F2;
border-radius: 4px;
margin-top: 22px;
padding: 14px;
.week-select {
display: flex;
.el-checkbox {
margin-right: 8px;
}
}
}
</style>
引入使用
<!--
* @Descripttion: 新增编辑详情
* @version:
* @Company:
* @Author: WYH
* @Date: 2022-09-08 15:16:26
* @LastModifiedTime:
-->
<template>
<el-form-item label="监控时间段" prop="monitorTimePeriods">
<el-button type="primary" size="small" @click="selectTimeQuantum('monitorTimePeriod')">设置</el-button>
</el-form-item>
<SelectTimeQuantum v-if="timeQuantumProps.show" v-model:timeQuantumProps="timeQuantumProps"></SelectTimeQuantum>
</template>
<script setup name="WarningNoticeAddedEdit">
import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import SelectTimeQuantum from './SelectTimeQuantum.vue'
const timeQuantumProps = reactive({
show: false,
tag: ''
})
function selectTimeQuantum (text) {
Object.assign(timeQuantumProps, {
show: true,
tag: text,
ruleForm,
disabled: title === '详情'
})
}
</script>
<style scoped>
</style>
处理完的数据格式
[
{
"week": 7,
"periods": [
{
"start": "02:00:00",
"end": "04:59:59"
},
{
"start": "05:00:00",
"end": "08:59:59"
},
{
"start": "10:00:00",
"end": "14:59:59"
},
{
"start": "16:00:00",
"end": "18:59:59"
},
{
"start": "20:00:00",
"end": "21:59:59"
}
]
},
{
"week": 1,
"periods": [
{
"start": "01:00:00",
"end": "04:59:59"
},
{
"start": "09:00:00",
"end": "15:59:59"
},
{
"start": "17:00:00",
"end": "20:59:59"
}
]
}
]
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。
在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。
本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。
除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。
在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!