需求描述
由于本人主要负责干部和招聘板块,招聘板块接到了要做一个面试大盘表的需求,需要展示面试官的面试情况,还需要面试官维护自己的可面试时间,之后人资进行面试安排,然后面试者到手机端进行自主选择面试官和面试场次。
最终展示
功能描述
移出维护区域自动上下滚动,单机是单个格子维护,点击鼠标不放开拖动是多个格子维护,每一列是一天的时间。
面试有面试的状态展示,涉及单元格的合并,判断逻辑较为复杂暂不具体分享,有兴趣或有问题可一起讨论。
设计思路
提供日期和时间的表格范围,监听鼠标的按下、拖动和抬起事件,根据起始位置和结束位置来改变被选中单元格的状态。
上下自动滚动是监听移入移出事件,mouseleave和mouseenter事件,注意:这两个事件只会自身生效,而mouseover和mouseout在子元素中会一直触发。在移出的时候判断鼠标位置来添加上滚或者下滚的延时函数,滚动的逻辑是scrollTop的加减,需要在触底和触顶的时候移出定时器,代码中包含相关注释,在移入的时候需要清除定时器来停止上下滚动行为。
时间维护代码
<template>
<basic-container>
<div style="overflow: scroll; white-space: nowrap">
<div class="left_container">
<div class="date_picker">
<vue-datepicker-local v-model="interviewDate" type="inline" @change="dateChange"></vue-datepicker-local>
<!-- <t-date-picker-panel v-model="interviewDate" @change="dateChange" /> -->
</div>
<div>
<el-tabs v-model="typeName" type="border-card" @tab-click="handleClick">
<el-tab-pane label="初试" name="first">
<div class="type_table">
<div class="type_table_title">
<div class="table_title_post">岗位</div>
<div>领头人</div>
<div>钻尖</div>
<div>后备</div>
<div>其他</div>
</div>
<div v-for="item in postList" :key="item.type">
<el-tooltip class="item" effect="dark" :content="item.applyPostName" placement="top">
<div class="post_postName">{{ item.applyPostName }}</div>
</el-tooltip>
<div>{{ item.talentType01First }}</div>
<div>{{ item.talentType02First }}</div>
<div>{{ item.talentType03First }}</div>
<div>{{ item.talentType04First === -1 ? 0 : item.talentType04First }}</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="复试" name="second">
<div class="type_table">
<div class="type_table_title">
<div class="table_title_post">岗位</div>
<div>领头人</div>
<div>钻尖</div>
<div>后备</div>
<div>其他</div>
</div>
<div v-for="item in postList" :key="item.type">
<el-tooltip class="item" effect="dark" :content="item.applyPostName" placement="top">
<div class="post_postName">{{ item.applyPostName }}</div>
</el-tooltip>
<div>{{ item.talentType01Second }}</div>
<div>{{ item.talentType02Second }}</div>
<div>{{ item.talentType03Second }}</div>
<div>{{ item.talentType04Second === -1 ? 0 : item.talentType04Second }}</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="终试" name="third">
<div class="type_table">
<div class="type_table_title">
<div class="table_title_post">岗位</div>
<div>领头人</div>
<div>钻尖</div>
<div>后备</div>
<div>其他</div>
</div>
<div v-for="item in postList" :key="item.type">
<el-tooltip class="item" effect="dark" :content="item.applyPostName" placement="top">
<div class="post_postName">{{ item.applyPostName }}</div>
</el-tooltip>
<div>{{ item.talentType01Last }}</div>
<div>{{ item.talentType02Last }}</div>
<div>{{ item.talentType03Last }}</div>
<div>{{ item.talentType04Last === -1 ? 0 : item.talentType04Last }}</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
<div v-loading="loading" class="weektime" :style="{ width: containerWidth }">
<div class="weektime-main">
<div class="weektime-hd">
<div class="weektime-hd-title">日期</div>
<div class="weektime-hd-con">
<!-- <div class="weektime-hd-con-top">
<div class="weektime-date-range">00:00 - 12:00</div>
<div class="weektime-date-range">12:00 - 24:00</div>
</div> -->
<!-- <div> -->
<div v-for="week in weekDays" :key="week" :style="{ color: $moment(week).format('E') === '1' && '#dcdee2' }" class="weektime-date-cell">{{ week }}</div>
<!-- </div> -->
</div>
</div>
<div class="weektime-hd">
<div class="weektime-hd-title">星期</div>
<div class="weektime-hd-con">
<!-- <div class="weektime-hd-con-top">
<div class="weektime-date-range">00:00 - 12:00</div>
<div class="weektime-date-range">12:00 - 24:00</div>
</div> -->
<!-- <div> -->
<div v-for="week in weekDays" :key="week" :style="{ color: $moment(week).format('E') === '1' && '#dcdee2' }" class="weektime-date-cell">
{{ elist[Number($moment(week).format('E')) - 1] }}
</div>
<!-- </div> -->
</div>
</div>
<div class="weektime-bd" @mouseleave="mouseleave" @mouseenter="mouseenter">
<div class="week-body">
<div v-for="(hour, index) in hourList" :key="hour.id" class="week-item">
{{ index !== 0 ? hour.intervalName : '' }}
<!-- <div v-if="hour.intervalName === '12:30'" class="grey_space"></div> -->
</div>
</div>
<div class="time-body" @mousedown="handleMousedown" @mouseup="handleMouseup" @mousemove="handleMousemove">
<el-tooltip v-for="(i, key) in weekTimes" :key="key" :data-index="key" :content="tiptxt(key)" :open-delay="800" placement="top" effect="dark">
<div
class="time-cell"
:class="{
active: list[key] === '1',
active_blue: ['2', '3'].includes(list[key]),
active_pick: list[key] === '4',
active_grey: isGrey(key),
'pre-active': preViewIndex.includes(key),
disable: disableTimes.includes(key),
firstActive:
list[key] !== '0' &&
((key >= weekDays.length &&
(list[key - weekDays.length] !== list[key] ||
(infoList.findIndex((item) => item.index === key - weekDays.length) !== -1 &&
infoList.findIndex((item) => item.index === key) !== -1 &&
infoList[infoList.findIndex((item) => item.index === key - weekDays.length)].id !== infoList[infoList.findIndex((item) => item.index === key)].id))) ||
key < weekDays.length ||
(Math.floor(key / weekDays.length) < hourList.length && hourList[Math.floor(key / weekDays.length)].intervalName === '14:30')),
lastActive:
list[key] !== '0' &&
((key + weekDays.length <= weekDays.length * hourList.length &&
(list[key + weekDays.length] !== list[key] ||
(infoList.findIndex((item) => item.index === key + weekDays.length) !== -1 &&
infoList.findIndex((item) => item.index === key) !== -1 &&
infoList[infoList.findIndex((item) => item.index === key + weekDays.length)].id !== infoList[infoList.findIndex((item) => item.index === key)].id))) ||
key + weekDays.length > weekDays.length * hourList.length ||
(Math.floor(key / weekDays.length) < hourList.length && hourList[Math.floor(key / weekDays.length)].intervalName === '12:30'))
}"
>
{{ cardText(key) }}
</div>
</el-tooltip>
</div>
</div>
</div>
<div class="weektime-help">
<div class="weektime-help-tx">
<div class="weektime-help-bd">
<!-- 当前功能暂时不需要,如之后需要添加可以参考 -->
<!-- <span class="color-box"></span>
<span class="text-box">未选</span>
<span class="color-box color-active"></span>
<span class="text-box">已选</span> -->
</div>
<!-- <div class="weektime-help-ft" @click="initList()">清空选择</div> -->
</div>
<!-- <div class="weektime-help-select">
<p v-for="(week, key) in weekDays" v-show="showTimeText[key]" :key="key">
<span class="weektime-help-week-tx">{{ week + ':' }}</span>
<span>{{ showTimeText[key] }}</span>
</p>
</div> -->
</div>
<div class="submit_btn">
<!-- element的按钮不够大,所以自己又写了个按钮,但是也存在表格的点击事件的优先级比按钮高 -->
<!-- <div v-loading="submitLoading" class="my_button" @click="submit">提交</div> -->
<el-button v-loading="submitLoading" type="primary" size="medium" @click="submit">提交</el-button>
</div>
</div>
</div>
</basic-container>
</template>
<script>
import VueDatepickerLocal from '@/components/datePickLocal'
import * as API from '../interviewOverviewTableApi'
import { GetDateStr } from '@/util/date.js'
let DayTimes = 24 * 2
export default {
name: 'InterviewOverviewTable',
props: {
value: String,
startTime: Number,
endTime: Number,
customDisableTimes: Array
},
components: {
VueDatepickerLocal
},
watch: {
value(n) {
if (n.split('') === this.list.join('')) return
this.initList(n)
}
},
data() {
return {
timer: '',
jobNo: '',
deptTypeCode: '',
param: {},
loading: false,
submitLoading: false,
interviewDate: '',
typeName: 'first',
containerWidth: 'calc(100% - 330px)',
isMove: false,
hourList: [],
statusList: ['', '待安排', '已安排', '无学生预约', '无学生预约', '未安排面试'],
postList: [
{
type: '合计',
zy: '2',
zj: '3',
hb: '95'
},
{
type: '合计',
zy: '2',
zj: '3',
hb: '95'
},
{
type: '合计',
zy: '2',
zj: '3',
hb: '95'
},
{
type: '合计',
zy: '2',
zj: '3',
hb: '95'
}
],
elist: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
textList: [],
list: [],
infoList: [],
weekTimes: 24,
// 实际是以选择的日期向后七天,这里只是当时本来是周几的形式,之后只是为了方便遍历
weekDays: ['7-3', '7-4', '7-5', '7-6', '7-7', '7-8', '7-9', '7-10'],
sumitWeekDays: ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
timeTextList: [], //显示的时间数组 ["00:00","00:30","01:00",...]
startIndex: 0,
axis: {},
preViewIndex: [],
showTimeText: []
}
},
computed: {
disableTimes() {
if (Array.isArray(this.customDisableTimes) && this.customDisableTimes.every((num) => typeof num === 'number')) return this.customDisableTimes
if (this.startTime > -1 && this.endTime > -1) {
const disabled = []
for (let index = 0; index < this.weekTimes; index++) {
const firstIdx = index % DayTimes
if (this.startTime > firstIdx || this.endTime < firstIdx) disabled.push(index)
}
return disabled
}
return []
}
},
mounted() {
this.getInfo()
},
methods: {
// 1. 我的空闲时间 2. 已安排面试 3. 安排面试且有人预约 4. 安排面试过了时间没人预约 灰色为前端处理,当前时间超过维护的时间且未安排面试
getInfo() {
this.loading = true
if (window.dd.env.platform === 'notInDingTalk') {
this.param = this.getAllParams()
this.deptTypeCode = (JSON.stringify(this.$store.state.user.loginUserInfo) !== '{}' && this.$store.state.user.loginUserInfo.depttypeCode) || this.param.deptTypeCode
this.jobNo = (this.$store.state.user && this.$store.state.user.userInfo.user_name) || this.param.jobNo
this.getHourList()
this.timeTextList = this.initTimeText()
document.addEventListener('mouseup', this.resetMousemove)
this.initList(this.value)
this.interviewDate = this.$moment()
this.getPostList()
return
}
window.dd.ready(() => {
const corpId = 'ding6cb12bb491f5fbbc'
window.dd.runtime.permission.requestAuthCode({
corpId,
onSuccess: (res) => {
API.getDingUserInfoExternal({ code: res.code }).then((res) => {
if (res.data.code === 200) {
this.jobNo = res.data.data.jobNumber
API.getDeptTypeByJobNo({ jobNo: this.jobNo }).then((res) => {
if (res.data.code === 200) {
this.deptTypeCode = res.data.data[0].value
this.getHourList()
this.timeTextList = this.initTimeText()
document.addEventListener('mouseup', this.resetMousemove)
this.initList(this.value)
this.interviewDate = this.$moment()
this.getPostList()
}
})
}
})
}
})
})
},
getAllParams() {
const href = window.location.href
const query = href.substring(href.indexOf('?') + 1)
const vars = query.split('&')
const obj = {}
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split('=')
// 将参数名和参数值分别作为对象的属性名和属性值
obj[pair[0]] = pair[1]
}
return obj
},
isGrey(i) {
const date = this.sumitWeekDays[i % this.sumitWeekDays.length]
if (Math.floor(i / this.weekDays.length) + 1 >= this.hourList.length) return
const time = this.hourList[Math.floor(i / this.weekDays.length) + 1].intervalName
if (this.list[i] === '1' && new Date(date.slice(0, 10) + ' ' + time + ':00').getTime() < new Date().getTime()) {
return true
}
},
cardText(i) {
if (
this.list[i] !== '0' &&
((i >= this.weekDays.length &&
(this.list[i - this.weekDays.length] !== this.list[i] ||
(this.infoList.findIndex((item) => item.index === i - this.weekDays.length) !== -1 &&
this.infoList.findIndex((item) => item.index === i) !== -1 &&
this.infoList[this.infoList.findIndex((item) => item.index === i - this.weekDays.length)].id !==
this.infoList[this.infoList.findIndex((item) => item.index === i)].id))) ||
i < this.weekDays.length ||
(Math.floor(i / this.weekDays.length) < this.hourList.length && this.hourList[Math.floor(i / this.weekDays.length)].intervalName === '14:30'))
) {
return this.recursionSelect(i, i)
}
const text = this.cardText(i - this.weekDays.length, i - this.weekDays.length)
if (i - this.weekDays.length >= 0) {
if (text && text.split('-').length > 1) {
if (['2', '4'].includes(this.list[i])) {
return '预计人数:' + this.infoList.find((item) => item.index === i).expectedNum
} else if (this.list[i] === '3') {
return '已预约人数:' + this.infoList.find((item) => item.index === i).expectedNum
} else if (this.isGrey(i)) {
return '未安排面试'
} else if (!this.isGrey(i) && this.list[i] === '1') {
return '待安排面试'
} else if (this.list[i] === '4') {
return '无学生预约'
}
}
if (text && text.includes('人数') && this.list[i] === '4') {
return '无学生预约'
}
}
},
// 递归遍历,拿到时间段
recursionSelect(i, startIndex) {
// 这里和firstActive的逻辑一样,但是最开始的时候就没封一块,太长了懒得改了
// 需要处理边界问题,还要处理12.30-14.30这个中午特殊时间的问题,12.30下一个时间是14.30,所以这两个不是连续的
// 下午到晚上的分割线,7点之后是晚上,之前是下午
// 判断是不是首个的依据是list[i](当前格子状态),前一个不等于list[i]或者
// this.infoList[this.infoList.findIndex((item) => item.index === i + this.weekDays.length)].id !==
// this.infoList[this.infoList.findIndex((item) => item.index === i)].id
// 这个id的判断是因为安排多场面试之后不能连在一起,要判断是不是一场面试
if (
this.list[i] !== '0' &&
((i + this.weekDays.length <= this.weekDays.length * this.hourList.length && this.list[i + this.weekDays.length] !== this.list[i]) ||
(this.infoList.findIndex((item) => item.index === i + this.weekDays.length) !== -1 &&
this.infoList.findIndex((item) => item.index === i) !== -1 &&
this.infoList[this.infoList.findIndex((item) => item.index === i + this.weekDays.length)].id !==
this.infoList[this.infoList.findIndex((item) => item.index === i)].id) ||
i + this.weekDays.length > this.weekDays.length * this.hourList.length ||
(Math.floor(i / this.weekDays.length) < this.hourList.length && this.hourList[Math.floor(i / this.weekDays.length)].intervalName === '12:30'))
) {
if (this.hourList[Math.floor(startIndex / this.weekDays.length)] && this.hourList[Math.floor(i / this.weekDays.length) + 1]) {
return this.hourList[Math.floor(startIndex / this.weekDays.length)].intervalName + '-' + this.hourList[Math.floor(i / this.weekDays.length) + 1].intervalName
} else if (this.hourList[Math.floor(startIndex / this.weekDays.length)] && this.hourList[Math.floor(i / this.weekDays.length)]) {
return this.hourList[Math.floor(startIndex / this.weekDays.length)].intervalName + '-' + this.hourList[Math.floor(i / this.weekDays.length)].intervalName
}
} else {
return this.recursionSelect(i + this.weekDays.length, startIndex)
}
},
getPostList() {
API.getTodoData({ deptTypeCode: this.deptTypeCode }).then((res) => {
if (res.data.code === 200) {
this.postList = res.data.data
}
})
},
getDetail() {
this.loading = true
API.timeDetail({
interviewerJobNo: this.jobNo,
interviewDate: this.$moment(this.interviewDate).format('YYYY-MM-DD') + ' 00:00:00'
})
.then((res) => {
if (res.data.code === 200) {
this.list = new Array(this.weekTimes).fill('0')
for (let i = 0; i < this.list.length; i++) {
this.$set(this.list, i, '0')
}
res.data.data.forEach((item) => {
if (this.weekDays.findIndex((w) => item.interviewDate.includes(w)) !== -1) {
const resultIndex =
this.hourList.findIndex((h) => h.id === item.timeId) * this.sumitWeekDays.length + this.sumitWeekDays.findIndex((i) => item.interviewDate.includes(i))
if (Number(item.status) > Number(this.list[resultIndex])) {
this.$set(this.list, resultIndex, item.status + '')
if ([2, 3, 4].includes(item.status)) {
this.infoList.push({
index: resultIndex,
id: item.id,
expectedNum: item.expectedNum
})
}
}
}
})
this.loading = false
}
})
.catch(() => (this.loading = false))
},
submit() {
this.submitLoading = true
const params = []
this.list.forEach((item, index) => {
if (item === '1') {
const obj = {
interviewerJobNo: this.jobNo,
interviewDate: this.sumitWeekDays[index % this.sumitWeekDays.length],
timeId: this.hourList[Math.floor(index / this.sumitWeekDays.length)].id
}
params.push(obj)
}
})
API.updateInterviewerTime({
jobNo: this.jobNo,
delDate: this.$moment(this.interviewDate).format('YYYY-MM-DD HH:mm:ss'),
params
})
.then((res) => {
if (res.data.code === 200) {
this.submitLoading = false
this.$message.success('提交成功')
}
})
.catch(() => (this.submitLoading = false))
},
dateChange() {
this.weekDays.forEach((item, index) => {
this.$set(this.weekDays, index, GetDateStr(index, this.interviewDate, true))
this.sumitWeekDays[index] = this.$moment(GetDateStr(index, this.interviewDate)).format('YYYY-MM-DD HH:mm:ss')
})
this.getDetail()
},
getHourList() {
API.hourList({ current: 1, size: 1000, jobNo: this.jobNo }).then((res) => {
if (res.data.code === 200) {
this.hourList = res.data.data.records
DayTimes = this.weekDays.length
this.weekTimes = this.hourList.length * DayTimes
this.dateChange()
}
})
},
/**
* 鼠标停留时提示当前时间段
*/
tiptxt(index) {
const timeIndex = index % DayTimes
const weekIndex = ~~(index / DayTimes)
// 为了解决没有intervalName的问题
if (
this.hourList[weekIndex] &&
this.hourList[weekIndex].intervalName &&
this.hourList[weekIndex + 1] &&
this.hourList[weekIndex + 1].intervalName &&
this.weekDays[timeIndex]
) {
return `${this.weekDays[timeIndex]} ${this.hourList[weekIndex].intervalName} - ${this.hourList[weekIndex + 1].intervalName}`
} else {
return ''
}
},
/**
* 初始化显示的时间数组
* @return {Array} ["00:00","00:30","01:00",...]
*/
initTimeText() {
const timeTextList = []
const hours = []
const minutes = ['00', '30']
for (let i = 0; i <= 24; i++) {
i < 10 ? hours.push('0' + i) : hours.push(i.toString())
}
for (const hour of hours) {
for (const minute of minutes) {
timeTextList.push(`${hour}:${minute}`)
}
}
return timeTextList
},
handleMousedown(event) {
this.startIndex = event.target.getAttribute('data-index')
if (this.disableTimes.includes(~~this.startIndex)) return
this.isMove = true
this.axis.startx = this.startIndex % DayTimes
this.axis.starty = ~~(this.startIndex / DayTimes)
},
mouseleave(event) {
if (this.isMove) {
var body = document.getElementsByClassName('weektime-bd')
const scrollDistance = 60
this.timer = setInterval(() => {
if (event.offsetY > 400) {
body[0].scrollTop = body[0].scrollTop + scrollDistance
//判断是否滚动到底部, 每次加scrollDistance,判断相等需要计算如何才能正好加完时相等,所以判断大于等于
// 可视高度加距离顶部的滚动高度
if (body[0].clientHeight + body[0].scrollTop >= body[0].scrollHeight - 1) {
clearInterval(this.timer)
}
} else {
body[0].scrollTop = body[0].scrollTop - scrollDistance
//判断是否滚动到顶部, 每次加scrollDistance,判断相等需要计算如何才能减好加完时相等,所以判断小于等于
// 距离顶部的滚动高度为0即触顶,由于每次减一定数据所以可能无法达到0而是一个负数
// 例如从40开始减,一次减60是-20,但dom会取0,值是-20,所以小于等于
if (body[0].scrollTop <= 0) {
clearInterval(this.timer)
}
}
}, 300)
}
},
mouseenter(event) {
clearInterval(this.timer)
},
handleMouseup(event) {
clearInterval(this.timer)
this.handleMousemove(event)
this.resetMousemove()
},
handleMousemove(event) {
if (!this.isMove) return
const index = event.target.getAttribute('data-index')
this.axis.endx = index % DayTimes
this.axis.endy = ~~(index / DayTimes)
this.preViewIndex = this.getSelectIndex()
},
resetMousemove() {
if (!this.isMove) return
this.setSelectIndex(this.preViewIndex)
this.isMove = false
this.axis = {}
this.preViewIndex = []
},
/**
* 获取拖动鼠标选择的index数组
*/
getSelectIndex() {
const indexList = []
const newAxis = {
startx: Math.min(this.axis.startx, this.axis.endx),
starty: Math.min(this.axis.starty, this.axis.endy),
endx: Math.max(this.axis.startx, this.axis.endx),
endy: Math.max(this.axis.starty, this.axis.endy)
}
if (newAxis.endx - newAxis.startx === DayTimes || newAxis.startx - newAxis.endx === DayTimes) {
indexList.push(newAxis.startx + newAxis.starty * DayTimes)
indexList.push(newAxis.endy + newAxis.endx * DayTimes)
}
for (let y = newAxis.starty; y <= newAxis.endy; y++) {
for (let x = newAxis.startx; x <= newAxis.endx; x++) {
indexList.push(x + y * DayTimes)
}
}
return indexList.filter((v) => !this.disableTimes.includes(v))
},
/**
* 设置选择的时间段并赋给绑定的值,选完之前标色是这个方法
* @param {Array} indexList 选择的index数组
*/
setSelectIndex(indexList) {
if (!Array.isArray(indexList)) return
const listLength = indexList.length
for (let i = 0; i < listLength; i++) {
let newData = '1'
if (this.list[indexList[i]] === '1') {
newData = '0'
}
if (!['0', '1'].includes(this.list[indexList[i]])) {
newData = this.list[indexList[i]]
}
this.list.splice(indexList[i], 1, newData)
}
this.$emit('input', this.list.join(''))
this.showSelectTime(this.list)
},
/**
* 展示选择的时间段
* @param {Array} list 已选择的list数组
*/
showSelectTime(list) {
if (!Array.isArray(list)) return
const weeksSelect = []
const listlength = list.length
this.showTimeText = []
if (listlength === 0) return
// 把 336长度的 list 分成 8 组,每组 48 个
for (var i = 0; i < listlength; i += DayTimes) {
weeksSelect.push(list.slice(i, i + DayTimes))
}
weeksSelect.forEach((item) => {
this.showTimeText.push(this.getTimeText(item))
})
},
getTimeText(arrIndex) {
if (!Array.isArray(arrIndex)) return ''
/*方法一 matchAll 正则匹配 (速度较慢) */
// let strIndex = arrIndex.join('');
// let arrMatches = Array.from(strIndex.matchAll(/1+/g));
// let timeText = "";
// arrMatches.forEach(value => {
// timeText += this.timeTextList[value.index];
// timeText += '~' + this.timeTextList[value.index + value[0].length] + '、';
// })
/*方法一 end */
/**方法二 循环 (速度是方法一的十倍+)*/
const timeLength = arrIndex.length
let isSelect = false
let timeText = ''
arrIndex.forEach((value, index) => {
if (value === '1') {
if (!isSelect) {
timeText += this.timeTextList[index]
isSelect = true
}
if (index === timeLength - 1) timeText += '~' + this.timeTextList[index + 1] + '、'
} else {
if (isSelect) {
timeText += '~' + this.timeTextList[index] + '、'
isSelect = false
}
}
})
/*方法二 end */
return timeText.slice(0, -1)
},
initList(value) {
const reg = new RegExp('^[01]{' + this.weekTimes + '}$')
if (value && reg.test(value)) {
this.list = value.split('')
return this.showSelectTime(this.list)
}
this.list = new Array(this.weekTimes).fill('0')
this.$emit('input', this.list.join(''))
this.showSelectTime(this.list)
}
},
destroyed() {
document.removeEventListener('mouseup', this.resetMousemove)
}
}
</script>
<style lang="scss" scoped>
$width: 66px;
$borderColor: #dbdbdb;
.grey_space {
background: #dcdcdc;
height: 16px;
}
/deep/.t-date-picker__panel-date {
width: 320px;
}
.submit_btn {
position: fixed;
bottom: 10px;
// left: 50%;
background: white;
width: 70%;
height: 50px;
line-height: 50px;
text-align: center;
z-index: 1000;
.my_button {
margin: 0 auto;
width: 100px;
height: 50px;
background-color: #409eff;
color: #fff;
border-radius: 6px;
cursor: pointer;
}
}
/deep/.el-tabs__content {
max-height: calc(100vh - 420px);
overflow-y: auto;
padding-top: 0;
}
.left_container {
display: inline-block;
white-space: nowrap;
vertical-align: top;
width: 320px;
margin-right: 10px;
white-space: nowrap;
/deep/.datepicker-popup {
width: 300px;
}
/deep/.calendar {
width: 100%;
}
/deep/.calendar-body {
width: 100%;
}
/deep/ .el-tabs__nav-scroll {
display: flex;
padding: 0 10px;
justify-content: space-around;
}
/deep/ .el-tabs {
margin-top: 10px;
}
/deep/ .date_picker {
text-align: center;
}
.type_table .post_postName {
flex: 2;
text-align: left;
overflow: hidden; /*内容会被修剪,并且其余内容是不可见的*/
text-overflow: ellipsis; /*显示省略符号来代表被修剪的文本。*/
white-space: nowrap;
}
.type_table {
font-size: 12px;
text-align: center;
line-height: 40px;
.type_table_title {
font-size: 14px;
font-weight: 600;
position: sticky;
top: 0;
background: #fff;
}
& > div {
display: flex;
justify-content: space-around;
flex-wrap: nowrap;
border-bottom: 1px solid #dbdbdb;
height: 40px;
padding: 5px;
& > div {
flex: 1;
}
& > .table_title_post {
flex: 2;
}
}
}
}
div,
span,
p {
margin: 0;
padding: 0;
border: 0;
// font-weight: normal;
vertical-align: baseline;
-webkit-tap-highlight-color: transparent;
-ms-tap-highlight-color: transparent;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.weektime {
display: inline-block;
min-width: 580px;
font-size: 14px;
line-height: 32px;
color: #515a6e;
user-select: none;
}
.weektime .weektime-main {
border: 1px solid #dcdee2;
border-bottom: 0;
position: relative;
}
.weektime .weektime-hd {
display: flex;
border-bottom: 1px solid #dcdee2;
position: sticky;
top: 0;
// background: #f8f8f9;
}
.weektime .weektime-hd-title {
display: flex;
justify-content: center;
align-items: center;
/* padding: 0 6px; */
width: 80px;
/* height: 65px; */
}
.weektime .weektime-hd-con {
flex: 1;
display: flex;
justify-content: space-around;
-webkit-box-orient: vertical;
// flex-direction: column;
}
.weektime .weektime-hd-con-top {
display: flex;
border-bottom: 1px solid #dcdee2;
}
.weektime .weektime-date-range {
width: 288px;
height: 32px;
line-height: 32px;
text-align: center;
border-left: 1px solid #dcdee2;
}
.weektime .weektime-hd-con-bottom {
display: flex;
}
.weektime .weektime-date-cell {
// display: inline-block;
width: calc(100% / 8);
padding: 5px;
margin: 0 2.5px;
height: 37px;
/* line-height: 32px; */
text-align: center;
border-left: 1px solid #dcdee2;
}
.weektime .weektime-bd {
display: flex;
max-height: calc(100vh - 330px);
overflow: auto;
}
.weektime .week-body {
width: 80px;
flex-shrink: 0;
}
.weektime .week-item {
// border-top: 1px solid #dcdee2;
text-align: center;
height: 37px;
line-height: 30px;
&:first-child {
margin-top: -19px;
}
&:last-child {
height: 18px;
}
}
.weektime .time-body {
width: 100%;
height: 210px;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
justify-content: space-around;
position: relative;
}
.weektime .time-cell {
position: relative;
width: calc((100% - 35px) / 8);
height: 37px;
border-radius: 8px;
font-size: 12px;
margin: 0 2.5px;
border-left: 1px solid $borderColor;
border-top: 1px solid $borderColor;
overflow: hidden;
transition: all 0.3s ease;
outline-width: 0;
text-align: center;
// 处理滚动条带来的列偏移
&:nth-of-type(8n) {
width: calc((100% - 35px) / 8 - 9px);
}
.time-cell-card {
position: absolute;
width: $width;
height: 74px;
background: #35cb44;
}
}
$borderActiveColor: #35cb44;
.weektime .active {
background: #ddf8ed;
color: #69bf7e;
border-top: 0;
// border-left: 2px solid $borderActiveColor;
// border-right: 2px solid $borderActiveColor;
border-radius: 0;
}
.weektime {
.active_blue {
background: #d3eaff;
color: #6198fe;
border-radius: 0;
border-top: 0;
}
.active_pick {
background: #ffdddc;
color: #e07d28;
border-radius: 0;
border-top: 0;
}
.active_grey {
background: #d8d8d8;
color: #4d6778;
border-radius: 0;
border-top: 0;
}
}
.weektime .time-cell.firstActive {
// border-top: 2px solid $borderActiveColor;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.weektime .time-cell.lastActive {
// border-bottom: 2px solid $borderActiveColor;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
.weektime .time-cell.disable {
cursor: no-drop;
}
.weektime .time-cell::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: transparent;
opacity: 0.5;
transition: all 866ms ease;
z-index: 99999;
}
.weektime .pre-active::after {
background: #113860;
}
.weektime .disable::after {
background: #cccccc;
}
/* 没用到的样式 */
.time-area {
width: 545px;
height: 210px;
position: absolute;
top: 0;
left: 0;
z-index: 100;
background: transparent;
}
.weektime .weektime-help {
// width: 545px;
border: 1px solid #dcdee2;
border-top: 0;
border-top: none;
padding: 5px 15px;
// min-height: 40px;
}
.weektime .weektime-help-tx {
display: flex;
align-items: center;
justify-content: space-between;
}
.weektime .weektime-help-week-tx {
color: #999;
}
.weektime .weektime-help-bd {
display: flex;
align-items: center;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 4px 0;
}
.weektime .weektime-help .color-box {
width: 14px;
height: 20px;
background: #fff;
border: 1px solid #dddddd;
display: block;
margin-right: 6px;
}
.weektime .weektime-help-bd .color-box.color-active {
background: #2d8cf0;
}
.weektime .weektime-help .text-box {
margin-right: 15px;
}
.weektime .weektime-help .weektime-help-ft {
color: #2d8cf0;
cursor: pointer;
}
</style>