|
|
|
|
@ -56,7 +56,7 @@
|
|
|
|
|
{{item.department_resources_name}}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-loading="loading" style="border: 1px solid #efefef;width: 100%; overflow-x: auto;">
|
|
|
|
|
<div v-loading="loading" ref="scrollContainer" style="border: 1px solid #efefef;width: 100%; overflow-x: auto; position: relative;">
|
|
|
|
|
<div style="text-align: right; padding: 8px; font-size: 12px; color: #999;">数据格式:占位/已用/总数</div>
|
|
|
|
|
<table class="planTable" v-if="planTableData.length>0">
|
|
|
|
|
<tr style="background-color: #f1f1f1;position: relative;">
|
|
|
|
|
@ -72,12 +72,15 @@
|
|
|
|
|
<td style="min-width: 120px;font-size: 14px;" v-for="(item,index) in date_list">{{item.substring(5,10)}} {{getWeekday(item)}}</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr v-for="(item,index) in planTableData" :key="index">
|
|
|
|
|
<td v-for="(item2,index2) in item" :key="index2" @mouseover="showTools(item2.id)"
|
|
|
|
|
@mouseleave="hideTools(item2.id)">
|
|
|
|
|
<td v-for="(item2,index2) in item" :key="index2"
|
|
|
|
|
:data-row="index" :data-col="index2"
|
|
|
|
|
@mouseover="onCellHover($event, item2, index, index2)"
|
|
|
|
|
@mouseleave="onCellLeave(item2.id)"
|
|
|
|
|
@mousedown="onCellMouseDown($event, item2, index, index2)">
|
|
|
|
|
<div>
|
|
|
|
|
<span v-if="index2=='time_range'">{{item2}}</span>
|
|
|
|
|
<div v-if="item2.countsInfo && item2.countsInfo.length>0"
|
|
|
|
|
:class="{'planInfo_k':item2.status==1,'planInfo_k planInfo_k_disabled':item2.status==0}">
|
|
|
|
|
:class="{'planInfo_k':item2.status==1,'planInfo_k planInfo_k_disabled':item2.status==0,'planInfo_k_selected':isSelected(item2.id)}">
|
|
|
|
|
<div v-if="hoverIndex==item2.id" class="hoverTools" >
|
|
|
|
|
<div class="icon_k" @click="getDetail(item2.id)">
|
|
|
|
|
<el-icon color="#409eff" size="20">
|
|
|
|
|
@ -121,7 +124,8 @@
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</table>
|
|
|
|
|
<div v-if="planTableData.length==0" style="width: 100%;background-color: #fff;">
|
|
|
|
|
<div v-if="isDragging" class="drag-selection-overlay" :style="dragOverlayStyle"></div>
|
|
|
|
|
<div v-if="planTableData.length==0" style="width: 100%;background-color: #fff;">>
|
|
|
|
|
<el-empty description="暂无号源" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@ -298,7 +302,8 @@
|
|
|
|
|
<script setup>
|
|
|
|
|
import {
|
|
|
|
|
ref,
|
|
|
|
|
onMounted
|
|
|
|
|
onMounted,
|
|
|
|
|
onUnmounted
|
|
|
|
|
} from 'vue'
|
|
|
|
|
import {
|
|
|
|
|
PlanListGetList,
|
|
|
|
|
@ -441,12 +446,100 @@
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
let hoverIndex = ref(null)
|
|
|
|
|
// 拖拽框选状态
|
|
|
|
|
let isDragging = ref(false)
|
|
|
|
|
let dragStart = ref({ row: 0, col: 0, x: 0, y: 0 })
|
|
|
|
|
let dragOverlayStyle = ref({})
|
|
|
|
|
let scrollContainer = ref(null)
|
|
|
|
|
const showTools = (index) => {
|
|
|
|
|
hoverIndex.value = index
|
|
|
|
|
}
|
|
|
|
|
const hideTools = (index) => {
|
|
|
|
|
hoverIndex.value = null
|
|
|
|
|
}
|
|
|
|
|
const onCellHover = (event, cellData, rowIdx, colKey) => {
|
|
|
|
|
if (isDragging.value) return
|
|
|
|
|
showTools(cellData?.id)
|
|
|
|
|
}
|
|
|
|
|
const onCellLeave = (cellId) => {
|
|
|
|
|
if (isDragging.value) return
|
|
|
|
|
hideTools(cellId)
|
|
|
|
|
}
|
|
|
|
|
const onCellMouseDown = (event, cellData, rowIdx, colKey) => {
|
|
|
|
|
// 点击勾选框不触发拖拽
|
|
|
|
|
if (event.target.closest('.plan_checkbox')) return
|
|
|
|
|
// time_range 列或无数据不触发
|
|
|
|
|
if (colKey === 'time_range' || !cellData || !cellData.id) return
|
|
|
|
|
const td = event.currentTarget
|
|
|
|
|
const tr = td.closest('tr')
|
|
|
|
|
if (!tr) return
|
|
|
|
|
const container = scrollContainer.value
|
|
|
|
|
if (!container) return
|
|
|
|
|
const containerRect = container.getBoundingClientRect()
|
|
|
|
|
isDragging.value = true
|
|
|
|
|
dragStart.value = {
|
|
|
|
|
row: tr.rowIndex,
|
|
|
|
|
col: td.cellIndex,
|
|
|
|
|
x: event.clientX - containerRect.left,
|
|
|
|
|
y: event.clientY - containerRect.top
|
|
|
|
|
}
|
|
|
|
|
// 清空原有选中,选中当前格子
|
|
|
|
|
selectedPlanArr.value = [cellData.id]
|
|
|
|
|
PlanSelectedAll.value = 0
|
|
|
|
|
}
|
|
|
|
|
const onDocumentMouseMove = (event) => {
|
|
|
|
|
if (!isDragging.value) return
|
|
|
|
|
const container = scrollContainer.value
|
|
|
|
|
if (!container) return
|
|
|
|
|
const containerRect = container.getBoundingClientRect()
|
|
|
|
|
const currentX = event.clientX - containerRect.left
|
|
|
|
|
const currentY = event.clientY - containerRect.top
|
|
|
|
|
// 更新拖拽矩形样式
|
|
|
|
|
dragOverlayStyle.value = {
|
|
|
|
|
left: Math.min(dragStart.value.x, currentX) + 'px',
|
|
|
|
|
top: Math.min(dragStart.value.y, currentY) + 'px',
|
|
|
|
|
width: Math.abs(currentX - dragStart.value.x) + 'px',
|
|
|
|
|
height: Math.abs(currentY - dragStart.value.y) + 'px'
|
|
|
|
|
}
|
|
|
|
|
// 用 elementFromPoint 找到鼠标下的 td
|
|
|
|
|
const el = document.elementFromPoint(event.clientX, event.clientY)
|
|
|
|
|
if (!el) return
|
|
|
|
|
const td = el.closest('td')
|
|
|
|
|
if (!td) return
|
|
|
|
|
const tr = td.closest('tr')
|
|
|
|
|
if (!tr) return
|
|
|
|
|
// 跳过表头行
|
|
|
|
|
if (tr.parentElement?.tagName === 'THEAD') return
|
|
|
|
|
const endRow = tr.rowIndex
|
|
|
|
|
const endCol = td.cellIndex
|
|
|
|
|
if (endCol === 0) return // 跳过 time_range 列
|
|
|
|
|
const startRow = dragStart.value.row
|
|
|
|
|
const startCol = dragStart.value.col
|
|
|
|
|
const minRow = Math.min(startRow, endRow)
|
|
|
|
|
const maxRow = Math.max(startRow, endRow)
|
|
|
|
|
const minCol = Math.min(startCol, endCol)
|
|
|
|
|
const maxCol = Math.max(startCol, endCol)
|
|
|
|
|
// 重建选中列表
|
|
|
|
|
selectedPlanArr.value = []
|
|
|
|
|
for (let r = minRow; r <= maxRow; r++) {
|
|
|
|
|
const dataRow = planTableData.value[r - 1]
|
|
|
|
|
if (!dataRow) continue
|
|
|
|
|
for (let c = minCol; c <= maxCol; c++) {
|
|
|
|
|
if (c === 0) continue
|
|
|
|
|
const colKey = date_list.value[c - 1]
|
|
|
|
|
if (!colKey) continue
|
|
|
|
|
const cellData = dataRow[colKey]
|
|
|
|
|
if (cellData && cellData.id) {
|
|
|
|
|
selectedPlanArr.value.push(cellData.id)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const onDocumentMouseUp = () => {
|
|
|
|
|
if (!isDragging.value) return
|
|
|
|
|
isDragging.value = false
|
|
|
|
|
dragOverlayStyle.value = {}
|
|
|
|
|
}
|
|
|
|
|
const zhenshiClick = (zhenshi) => {
|
|
|
|
|
ResourceActive.value = zhenshi
|
|
|
|
|
PlanSelectedAll.value = 0
|
|
|
|
|
@ -812,6 +905,13 @@
|
|
|
|
|
GetDepartmentEnableList()
|
|
|
|
|
getEnableResource()
|
|
|
|
|
GetEnableDeviceListFunc()
|
|
|
|
|
// 拖拽全局监听
|
|
|
|
|
document.addEventListener('mousemove', onDocumentMouseMove)
|
|
|
|
|
document.addEventListener('mouseup', onDocumentMouseUp)
|
|
|
|
|
})
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
document.removeEventListener('mousemove', onDocumentMouseMove)
|
|
|
|
|
document.removeEventListener('mouseup', onDocumentMouseUp)
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
@ -971,6 +1071,8 @@
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
/* 合并边框 */
|
|
|
|
|
color: #333;
|
|
|
|
|
user-select: none;
|
|
|
|
|
-webkit-user-select: none;
|
|
|
|
|
|
|
|
|
|
td {
|
|
|
|
|
border: 1px solid #f1f1f1;
|
|
|
|
|
@ -1026,4 +1128,20 @@
|
|
|
|
|
.bold-text{
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
/* 拖拽框选 */
|
|
|
|
|
.drag-selection-overlay {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
background: rgba(64, 158, 255, 0.12);
|
|
|
|
|
border: 1px solid rgba(64, 158, 255, 0.5);
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
z-index: 10;
|
|
|
|
|
}
|
|
|
|
|
.planInfo_k_selected {
|
|
|
|
|
background-color: #e6f7ff;
|
|
|
|
|
outline: 2px solid #409eff;
|
|
|
|
|
outline-offset: -2px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|