fix:拖拽排序
This commit is contained in:
1 parent
4496d865a5
commit
c8716084e9
8 files changed
+253
-25
No files matched your search
@@ -44,6 +44,17 @@ export function editGroupItem(data: any) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改分组排序
|
||||
*/
|
||||
export function editGroupSort(data: any) {
|
||||
return request({
|
||||
url: '/admin/device/deviceGroup/editGroupSort',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加设施分组子项
|
||||
*/
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
|
||||
<script setup lang="ts" name="DraggableDeviceGroupDraggable">
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import { getDeviceGroupTree, editGroupItem } from "/@/api/device/deviceGroup"
|
||||
import { getDeviceGroupTree, editGroupItem, editGroupSort } from "/@/api/device/deviceGroup"
|
||||
|
||||
const emit = defineEmits(["getSelectNode"])
|
||||
|
||||
@@ -305,6 +305,7 @@ const nodeDragStart = (node: Node, ev: DragEvent) => {
|
||||
}
|
||||
|
||||
// 拖拽成功完成时触发的事件
|
||||
// dropType为:before、after、inner
|
||||
const handleNodeDrop = async (draggingNode: any, dropNode: any, dropType: any, ev: DragEvent) => {
|
||||
const checkedIds = state.checkedTreeNodes.map((item: any) => item.id)
|
||||
if (checkedIds && checkedIds.length) {
|
||||
@@ -312,16 +313,57 @@ const handleNodeDrop = async (draggingNode: any, dropNode: any, dropType: any, e
|
||||
}
|
||||
const draggingNodeSort = draggingNode.data?.sort ?? 0
|
||||
const dropNodeSort = dropNode.data?.sort ?? 0
|
||||
|
||||
console.log("移动中的sort:", draggingNodeSort, "目标sort:", dropNodeSort, "移动类型:", dropType);
|
||||
console.log("checkedTreeNodes:", state.checkedTreeNodes);
|
||||
|
||||
const leafSelected = (state.checkedTreeNodes || []).filter((n: any) => n && (n.deep === 2 || !n.children || (Array.isArray(n.children) && n.children.length === 0)))
|
||||
if (leafSelected.length && Array.isArray(state.treeDataList)) {
|
||||
const selectedSet = new Set<string>(leafSelected.map((n: any) => String(n.id)))
|
||||
const result: any[] = []
|
||||
const dragParentId = draggingNode?.data?.parentId
|
||||
const dragId = String(draggingNode?.data?.id)
|
||||
const dropId = String(dropNode?.data?.id)
|
||||
const isAfter = dropType === "after" || dropType === "next"
|
||||
for (const p of state.treeDataList) {
|
||||
const chs = Array.isArray(p.children) ? p.children : []
|
||||
let idOrder: string[] = chs.map((c: any) => String(c.id))
|
||||
if (String(p.id) === String(dragParentId) && idOrder.length) {
|
||||
idOrder = idOrder.filter((id) => id !== dragId)
|
||||
let dropIndex = idOrder.indexOf(dropId)
|
||||
if (dropIndex < 0) dropIndex = 0
|
||||
const insertIndex = Math.min(Math.max(dropIndex + (isAfter ? 1 : 0), 0), idOrder.length)
|
||||
idOrder.splice(insertIndex, 0, dragId)
|
||||
}
|
||||
for (const cid of idOrder) {
|
||||
if (selectedSet.has(cid)) {
|
||||
const sel = leafSelected.find((s: any) => String(s.id) === cid)
|
||||
const ch = chs.find((c: any) => String(c.id) === cid)
|
||||
if (sel && ch && typeof ch.sort !== "undefined") sel.sort = ch.sort
|
||||
if (sel) result.push(sel)
|
||||
}
|
||||
}
|
||||
}
|
||||
state.checkedTreeNodes = result
|
||||
}
|
||||
console.log("drag后重排checkedTreeNodes:", state.checkedTreeNodes);
|
||||
|
||||
const length = state.checkedTreeNodes.length
|
||||
const list = state.checkedTreeNodes.map((item: any, index: number) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
sort: (length - index) * 10
|
||||
}
|
||||
})
|
||||
|
||||
console.log("list:", list);
|
||||
|
||||
try {
|
||||
await editGroupItem({
|
||||
id: draggingNode.data.id,
|
||||
sort: dropNodeSort + 10
|
||||
await editGroupSort({
|
||||
list: list
|
||||
})
|
||||
await getTreeData()
|
||||
if (state.checkedTreeNodes && state.checkedTreeNodes.length) {
|
||||
// 重写排序
|
||||
state.checkedTreeNodes = state.checkedTreeNodes.filter((item: any) => item.deep == 2).sort((a: any, b: any) => b.sort - a.sort)
|
||||
}
|
||||
emit("getSelectNode", state.curClickedNode, state.checkedTreeNodes, state.switch, buildParentChildCheckedArray())
|
||||
} catch (error) {
|
||||
console.log("|拖拽成功完成时触发的事件|,意外的错误", error);
|
||||
|
||||
@@ -83,7 +83,7 @@ async function initVideo() {
|
||||
let { records, total } = data
|
||||
if (!records || !records.length) records = []
|
||||
state.total = total
|
||||
let suitableNum = state.num
|
||||
let suitableNum = state.currentNum
|
||||
if (state.total < state.numList[state.numList.length - 1]) {
|
||||
suitableNum = findSuitableNum(records.length, state.numList);
|
||||
state.maxCurrentNum = suitableNum
|
||||
|
||||
@@ -194,8 +194,14 @@ const getDeviceChannelList = async (codeStr: any) => {
|
||||
]
|
||||
}
|
||||
console.log("replayVideoRef:", replayVideoRef);
|
||||
let list = []
|
||||
let deviceCode = state.code
|
||||
if (_data.playbackGroupChannelCode) {
|
||||
list = data.map((item: any) => item.channelCode)
|
||||
deviceCode = null
|
||||
}
|
||||
replayVideoRef.value.init(
|
||||
{ list: [], deviceCode: state.code },
|
||||
{ list: list, deviceCode: deviceCode },
|
||||
queryForm,
|
||||
)
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -108,7 +108,9 @@ const selectObjs = ref([]) as any
|
||||
const multiple = ref(true)
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
queryForm: {
|
||||
excludeBizTypeList: ["3"]
|
||||
},
|
||||
pageList: deviceGroupApi.fetchList
|
||||
})
|
||||
|
||||
|
||||
@@ -37,13 +37,6 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column width="120" prop="groupName" label="默认播放码流">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.deviceChannelStreamType == 1" type="primary">主码流</el-tag>
|
||||
<el-tag v-else-if="row.deviceChannelStreamType == 2" type="primary">辅码流</el-tag>
|
||||
<el-tag v-else type="danger">未定义</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="80" prop="groupName" label="排序">
|
||||
<template #default="{ row }">
|
||||
{{ row.sort ?? 0 }}
|
||||
@@ -51,10 +44,6 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button icon="edit-pen" text type="primary" @click="cameraTableFormDialogRef.openDialog
|
||||
(row.id)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button icon="delete" text type="primary" size="mini" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -81,7 +70,7 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<camera-table-form-dialog ref="cameraTableFormDialogRef" @refresh="getDataList" />
|
||||
<!-- <camera-table-form-dialog ref="cameraTableFormDialogRef" @refresh="getDataList" /> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="CameraTableDialog">
|
||||
@@ -90,7 +79,7 @@ import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
|
||||
import * as deviceGroupApi from "/@/api/device/deviceGroup";
|
||||
|
||||
import CameraTableFormDialog from "./camera-table-form-dialog.vue"
|
||||
// import CameraTableFormDialog from "./camera-table-form-dialog.vue"
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref();
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
|
||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="分组名称" prop="name">
|
||||
<el-input :disabled="form.bizType == '1'" v-model="form.name" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col v-if="false" :span="24" class="mb20">
|
||||
<el-form-item label="类型" prop="bizType">
|
||||
<el-input v-model="form.bizType" placeholder="请输入类型" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<template #label>
|
||||
<span>排序</span>
|
||||
<tip content="越大越在前" />
|
||||
</template>
|
||||
<el-input-number :min="0" :step="1" v-model="form.sort" placeholder="" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DeviceGroupDialog">
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import * as deviceGroupApi from "/@/api/device/deviceGroup";
|
||||
import { rule } from '/@/utils/validate';
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref();
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
// 定义字典
|
||||
const { panel_type } = useDict("panel_type")
|
||||
// 提交表单数据
|
||||
const defaultForm = {
|
||||
id: '',
|
||||
name: '',
|
||||
bizType: '3',
|
||||
panelViewCodes: [],
|
||||
sort: 10,
|
||||
}
|
||||
const form = reactive({ ...defaultForm });
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = ref({
|
||||
name: [{ required: true, message: '分组名称不能为空', trigger: 'blur' }],
|
||||
panelViewCodes: [{ required: true, message: '类型不能为空', trigger: 'change' }],
|
||||
sort: [{ required: true, message: '排序不能为空', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (id: string) => {
|
||||
visible.value = true
|
||||
form.id = ''
|
||||
|
||||
// 重置表单数据
|
||||
dataFormRef.value?.resetFields();
|
||||
Object.assign(form, defaultForm)
|
||||
// 获取deviceGroup信息
|
||||
if (id) {
|
||||
form.id = id
|
||||
getdeviceGroupData(id)
|
||||
}
|
||||
};
|
||||
|
||||
// 提交
|
||||
const onSubmit = async () => {
|
||||
const valid = await dataFormRef.value.validate().catch(() => { });
|
||||
if (!valid) return false;
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
const _form: any = { ...form }
|
||||
_form.bizType = '3'
|
||||
if (_form.panelViewCodes && _form.panelViewCodes.length) {
|
||||
_form.panelViewCodes = _form.panelViewCodes.join(',')
|
||||
} else {
|
||||
_form.panelViewCodes = ""
|
||||
}
|
||||
form.id ? await deviceGroupApi.putObj(_form) : await deviceGroupApi.addObj(_form);
|
||||
useMessage().success(form.id ? '修改成功' : '添加成功');
|
||||
visible.value = false;
|
||||
emit('refresh');
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 初始化表单数据
|
||||
const getdeviceGroupData = async (id: string) => {
|
||||
try {
|
||||
loading.value = true
|
||||
const { code, data } = await deviceGroupApi.getObj(id)
|
||||
if (data.panelViewCodes) {
|
||||
data.panelViewCodes = data.panelViewCodes.split(',')
|
||||
} else {
|
||||
data.panelViewCodes = []
|
||||
}
|
||||
Object.assign(form, data)
|
||||
} catch (error) {
|
||||
console.error("|初始化表单数据|意外的错误:", error);
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog
|
||||
});
|
||||
</script>
|
||||
@@ -29,6 +29,41 @@
|
||||
@queryTable="getDataList"></right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-table :data="state.dataList" v-loading="state.loading" border :cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle" @selection-change="selectionChangHandle"
|
||||
@sort-change="sortChangeHandle">
|
||||
<el-table-column type="selection" width="40" align="center" />
|
||||
<el-table-column type="index" label="#" width="40" />
|
||||
<el-table-column prop="name" label="分组名称" />
|
||||
<el-table-column prop="bizType" label="类型">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="device_group_type" :value="row.bizType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort" label="排序" />
|
||||
<el-table-column label="操作" width="210">
|
||||
<template #default="{ row }">
|
||||
<div class="flex">
|
||||
<el-button icon="VideoPlay" text type="primary"
|
||||
@click="cameraTableDialogRef.openDialog(row.id)">
|
||||
摄像头
|
||||
</el-button>
|
||||
<el-button icon="edit-pen" text type="primary" v-auth="'device_deviceGroup_edit'"
|
||||
@click="formDialogRef.openDialog(row.id)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button v-if="row.bizType != 1" icon="delete" text type="primary"
|
||||
v-auth="'device_deviceGroup_del'" @click="handleDelete([row.id])">
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
||||
<camera-table-dialog ref="cameraTableDialogRef" @refresh="getDataList(false)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -39,6 +74,9 @@ import * as deviceGroupApi from "/@/api/device/deviceGroup";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
const CameraTableDialog = defineAsyncComponent(() => import('./camera-table-dialog.vue'));
|
||||
|
||||
// 定义查询字典
|
||||
const { device_group_type, panel_type } = useDict("device_group_type", "panel_type")
|
||||
// 定义变量内容
|
||||
@@ -52,7 +90,9 @@ const selectObjs = ref([]) as any
|
||||
const multiple = ref(true)
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
queryForm: {
|
||||
bizType: 3
|
||||
},
|
||||
pageList: deviceGroupApi.fetchList
|
||||
})
|
||||
|
||||
@@ -66,6 +106,12 @@ const {
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 多选事件
|
||||
const selectionChangHandle = (objs: { id: string }[]) => {
|
||||
selectObjs.value = objs.map(({ id }) => id);
|
||||
multiple.value = !objs.length;
|
||||
};
|
||||
|
||||
// 清空搜索条件
|
||||
const resetQuery = () => {
|
||||
// 清空搜索条件
|
||||
|
||||
Reference in new issue
Block a user