|
|
@ -2,20 +2,13 @@ |
|
|
|
<q-tr |
|
|
|
ref="trRef" |
|
|
|
:class="row[table.selectedField] ? 'selected ' : ''" |
|
|
|
:draggable=" |
|
|
|
((typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable) || |
|
|
|
(typeof props.grid.props.draggable === 'string' && props.grid.props.draggable === 'local')) && |
|
|
|
table.bodyEditStatus === 'none' |
|
|
|
? true |
|
|
|
: false |
|
|
|
" |
|
|
|
:draggable="draggableComputed" |
|
|
|
@click.stop.prevent="click($event, row, row.rowIndex)" |
|
|
|
@dblclick.stop.prevent="dbClick($event, row, row.rowIndex)" |
|
|
|
@dragenter="onDragEnter($event, row)" |
|
|
|
@dragleave="onDragLeave($event, row)" |
|
|
|
@dragover="onDragOver($event, row)" |
|
|
|
@drop="onDrop($event, row)" |
|
|
|
@dragstart="onDragStart($event, row)" |
|
|
|
@dragleave="draggableComputed ? onDragLeave($event, row) : () => {}" |
|
|
|
@dragover="draggableComputed ? onDragOver($event, row) : () => {}" |
|
|
|
@drop="draggableComputed ? onDrop($event, row) : () => {}" |
|
|
|
@dragstart="draggableComputed ? onDragStart($event, row) : () => {}" |
|
|
|
> |
|
|
|
<q-td class="nowrap text-nowrap"> |
|
|
|
<div ref="tdDivRef" class="flex flex-nowrap items-center h-full w-full" style="flex-wrap: nowrap"> |
|
|
@ -137,6 +130,7 @@ |
|
|
|
import { ref, computed, inject, toRaw } from 'vue'; |
|
|
|
import { Tools, NotifyManager } from '@/platform'; |
|
|
|
import GridEditToolbar from './GridEditToolbar.vue'; |
|
|
|
import { draggableImage } from './ts/grid'; |
|
|
|
|
|
|
|
const trRef = ref(); |
|
|
|
const tdDivRef = ref(); |
|
|
@ -235,6 +229,15 @@ const style = { |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
|
const draggableComputed = computed(() => { |
|
|
|
if (typeof props.grid.props.draggable === 'boolean' && props.grid.props.draggable && table.bodyEditStatus === 'none') { |
|
|
|
return true; |
|
|
|
} else if (typeof props.grid.props.draggable === 'string' && props.grid.props.draggable === 'local' && table.bodyEditStatus === 'none') { |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
}); |
|
|
|
|
|
|
|
const isSelectedRowComputed = computed(() => { |
|
|
|
const selected = props.grid.getSelectedRow(); |
|
|
|
if (!Tools.isEmpty(selected)) { |
|
|
@ -384,7 +387,7 @@ document.addEventListener('drop', function (e) { |
|
|
|
// 拖拽开始 |
|
|
|
const onDragStart = (e, dataRow) => { |
|
|
|
const img = new Image(); |
|
|
|
img.src = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Cpath /%3E%3C/svg%3E`; |
|
|
|
img.src = draggableImage; |
|
|
|
e.dataTransfer.setDragImage(img, 0, 0); |
|
|
|
const selecteds = props.grid.getSelectedRows(); |
|
|
|
if ( |
|
|
@ -500,30 +503,6 @@ const dragRecordsContains = (dataRow) => { |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
// 根据传入节点判断该节点是否为所在层级的最后一个节点 |
|
|
|
const isLastNode = (dataRow) => { |
|
|
|
if (Tools.isEmpty(dataRow[props.grid.props.foreignKey])) { |
|
|
|
if (table.rows[table.rows.length - 1][props.grid.props.primaryKey] === dataRow[props.grid.props.primaryKey]) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} else { |
|
|
|
const parent = props.getRow(table.rows, dataRow[props.grid.props.foreignKey], true); |
|
|
|
if (parent.children[parent.children.length - 1][props.grid.props.primaryKey] === dataRow[props.grid.props.primaryKey]) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
}; |
|
|
|
|
|
|
|
// 拖拽至可放置区域触发 |
|
|
|
const onDragEnter = (e, dataRow) => { |
|
|
|
if (e.target.nodeName === 'TD' && e.offsetY <= gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) { |
|
|
|
addDragTopStyle(e); |
|
|
|
} else if (isLastNode(dataRow) && e.target.nodeName === 'TD' && e.offsetY > gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) { |
|
|
|
addDragBottomStyle(e); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 拖拽至不可放置区域触发 |
|
|
|
const onDragLeave = (e, dataRow) => { |
|
|
|
removeDragTopStyle(e); |
|
|
@ -549,7 +528,7 @@ const onDragOver = (e, dataRow) => { |
|
|
|
if (e.target.nodeName === 'TD' && e.offsetY <= gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) { |
|
|
|
removeDragBottomStyle(e); |
|
|
|
addDragTopStyle(e); |
|
|
|
} else if (isLastNode(dataRow) && e.target.nodeName === 'TD' && e.offsetY > gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) { |
|
|
|
} else if (e.target.nodeName === 'TD' && e.offsetY > gridTrMiddleHeightComputed.value && !dragRecordsContains(dataRow)) { |
|
|
|
removeDragTopStyle(e); |
|
|
|
addDragBottomStyle(e); |
|
|
|
} |
|
|
@ -583,42 +562,57 @@ const removeRecord = (arr, removeData) => { |
|
|
|
// 待更新的排序数据 |
|
|
|
const updateOrderData = <any>[]; |
|
|
|
|
|
|
|
// 处理树节点的增加 |
|
|
|
const nodeSplice = (e, dragIndex, targetIndex, drag, target, arr) => { |
|
|
|
if ( |
|
|
|
(Tools.isEmpty(drag[props.grid.props.foreignKey]) && Tools.isEmpty(target[props.grid.props.foreignKey])) || |
|
|
|
drag[props.grid.props.foreignKey] === target[props.grid.props.foreignKey] |
|
|
|
) { |
|
|
|
const lessThanResult = dragLessThanTarget(dragIndex, targetIndex); |
|
|
|
// 父节点相同的同级处理 |
|
|
|
if (e.offsetY <= gridTrMiddleHeightComputed.value && lessThanResult) { |
|
|
|
arr.splice(targetIndex - 1, 0, drag); |
|
|
|
} else if (e.offsetY > gridTrMiddleHeightComputed.value && !lessThanResult) { |
|
|
|
arr.splice(targetIndex + 1, 0, drag); |
|
|
|
} else { |
|
|
|
arr.splice(targetIndex, 0, drag); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 拖拽节点与目标节点不同级处理 |
|
|
|
if (e.offsetY <= gridTrMiddleHeightComputed.value) { |
|
|
|
arr.splice(targetIndex, 0, drag); |
|
|
|
} else if (e.offsetY > gridTrMiddleHeightComputed.value) { |
|
|
|
arr.splice(targetIndex + 1, 0, drag); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// 设置排序号 |
|
|
|
const setOrder = (arr) => { |
|
|
|
arr.forEach((item, index) => { |
|
|
|
item[props.grid.props.orderBy] = index + 1; |
|
|
|
item[props.grid.props.draggableOrderBy] = index + 1; |
|
|
|
// 添加至待更新集合中 |
|
|
|
updateOrderData.push({ ...toRaw(item), children: null }); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
// 增加并重新设置父属性 |
|
|
|
const addRecord = (e, arr, addData, targetData, dragIndex, targetIndex) => { |
|
|
|
const childrenResetOrder = (e, arr, addData, targetData, dragIndex, targetIndex) => { |
|
|
|
for (let i = 0; i < arr.length; i++) { |
|
|
|
if (arr[i][props.grid.props.primaryKey] === targetData[props.grid.props.foreignKey]) { |
|
|
|
if ( |
|
|
|
e.offsetY <= gridTrMiddleHeightComputed.value && |
|
|
|
isTrue(dragIndex, targetIndex) && |
|
|
|
addData[props.grid.props.foreignKey] === targetData[props.grid.props.foreignKey] |
|
|
|
) { |
|
|
|
arr[i].children.splice(targetIndex - 1, 0, addData); |
|
|
|
} else if (e.offsetY > gridTrMiddleHeightComputed.value && addData[props.grid.props.foreignKey] !== targetData[props.grid.props.foreignKey]) { |
|
|
|
arr[i].children.splice(arr[i].children.length, 0, addData); |
|
|
|
} else { |
|
|
|
arr[i].children.splice(targetIndex, 0, addData); |
|
|
|
} |
|
|
|
nodeSplice(e, dragIndex, targetIndex, addData, targetData, arr[i].children); |
|
|
|
// 修改父 |
|
|
|
addData[props.grid.props.foreignKey] = arr[i][props.grid.props.primaryKey]; |
|
|
|
// 重新设置排序号 |
|
|
|
setOrder(arr[i].children); |
|
|
|
break; |
|
|
|
} else if (arr[i].children && arr[i].children.length > 0) { |
|
|
|
addRecord(e, arr[i].children, addData, targetData, dragIndex, targetIndex); |
|
|
|
childrenResetOrder(e, arr[i].children, addData, targetData, dragIndex, targetIndex); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
const isTrue = (dragIndex, targetIndex) => { |
|
|
|
const dragLessThanTarget = (dragIndex, targetIndex) => { |
|
|
|
if (dragIndex < targetIndex) { |
|
|
|
return true; |
|
|
|
} |
|
|
@ -627,23 +621,15 @@ const isTrue = (dragIndex, targetIndex) => { |
|
|
|
|
|
|
|
// 数据处理 |
|
|
|
const resetOrderDataHandler = (e, dragRecords, targetData, targetIndex) => { |
|
|
|
// 1、从表格数据中将拖拽数据删除 |
|
|
|
dragRecords.forEach((item) => { |
|
|
|
// 从表格数据中将拖拽数据删除 |
|
|
|
const itemIndex = removeRecord(table.rows, item); |
|
|
|
// 2、表格数据中根据目标位置添加数据 |
|
|
|
if (Tools.isEmpty(targetData[props.grid.props.foreignKey])) { |
|
|
|
// 3、修正位置,当拖拽至行的上半部分,且拖拽对象跟目标对象处于同级,且下标小于目标时,使用splice添加到指定下标时需将下标-1(扣除自身所占的1个下标) |
|
|
|
if (e.offsetY <= gridTrMiddleHeightComputed.value && Tools.isEmpty(item[props.grid.props.foreignKey]) && isTrue(itemIndex, targetIndex)) { |
|
|
|
table.rows.splice(targetIndex - 1, 0, item); |
|
|
|
} else { |
|
|
|
table.rows.splice(targetIndex, 0, item); |
|
|
|
} |
|
|
|
nodeSplice(e, itemIndex, targetIndex, item, targetData, table.rows); |
|
|
|
item[props.grid.props.foreignKey] = null; |
|
|
|
setOrder(table.rows); |
|
|
|
// 根目录下顺序变化,直接将根目录下所有数据放到待更新集合中 |
|
|
|
// updateOrderData.push(...toRaw(table.rows)); |
|
|
|
} else { |
|
|
|
addRecord(e, table.rows, item, targetData, itemIndex, targetIndex); |
|
|
|
childrenResetOrder(e, table.rows, item, targetData, itemIndex, targetIndex); |
|
|
|
} |
|
|
|
}); |
|
|
|
}; |
|
|
|