<template>
|
<div class="p-2">
|
<vxe-toolbar>
|
<template #buttons>
|
<div style="display: flex; align-items: flex-end">
|
<span style="font-size: 1.25rem; font-weight: 600">文件夹</span
|
><span style="margin-left: 5px; padding-bottom: 4px; font-size: 12px"
|
>管理您的个人文件夹</span
|
>
|
</div>
|
</template>
|
<template #tools>
|
<a-button type="primary" @click="insertEvent">新建文件夹</a-button>
|
</template>
|
</vxe-toolbar>
|
|
<vxe-table
|
ref="xTable"
|
style="margin: 10px 0"
|
:data="demo.tableData"
|
@mounted="onMounted"
|
:row-config="{ keyField: 'id' }"
|
:column-config="{ resizable: true }"
|
:export-config="{}"
|
:tree-config="{ transform: true, rowField: 'rowId', parentField: 'parentRowId' }"
|
:edit-config="{ trigger: 'manual', mode: 'row' }"
|
height="600"
|
>
|
<vxe-column width="40">
|
<template #default>
|
<span class="drag-btn">
|
<HolderOutlined />
|
</span>
|
</template>
|
</vxe-column>
|
<vxe-column field="folderName" title="文件夹名称" minWidth="250" tree-node :edit-render="{}">
|
<template #edit="{ row }">
|
<vxe-input
|
:ref="(el) => (inputRefs[row.id] = el)"
|
v-model="row.folderName"
|
type="text"
|
style="width: 300px"
|
@blur="fnInputHandle(row)"
|
></vxe-input>
|
</template>
|
</vxe-column>
|
<vxe-column field="age" title="操作" width="250">
|
<template #default="{ row }">
|
<a style="margin-right: 10px" @click="insertRow(row)">添加子文件夹</a>
|
<a style="margin-right: 10px" @click="editRowEvent(row)">编辑</a>
|
<a style="margin-right: 10px" @click="fnDelete(row)">删除</a>
|
</template>
|
</vxe-column>
|
</vxe-table>
|
</div>
|
</template>
|
|
<script lang="ts" setup>
|
import { ref, computed, onMounted, nextTick, onUnmounted, reactive } from 'vue';
|
import {
|
addFolderApi,
|
deleteFolderApi,
|
updateFolderApi,
|
getFolderApi,
|
} from '@/api/email/userList';
|
|
// 排序
|
import { HolderOutlined } from '@ant-design/icons-vue';
|
import Sortable from 'sortablejs';
|
let sortable: any;
|
const demo = reactive({
|
showHelpTip: false,
|
tableData: [],
|
});
|
const xTable = ref();
|
const rowDrop = () => {
|
const $table = xTable.value;
|
sortable = Sortable.create($table.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
|
handle: '.drag-btn',
|
onEnd: (sortableEvent) => {
|
const newIndex = sortableEvent.newIndex as number;
|
const oldIndex = sortableEvent.oldIndex as number;
|
const currRow: Record<string, any> = demo.tableData.splice(oldIndex, 1)[0];
|
// demo.tableData.splice(newIndex, 0, currRow);
|
updateFolderApi({
|
folderId: currRow.folderId,
|
folderName: currRow.folderName,
|
treeControl: currRow.treeControl,
|
parentRowId: currRow.parentRowId,
|
sortId: newIndex,
|
})
|
.then(() => {
|
fnGetList();
|
})
|
.catch(() => {});
|
},
|
});
|
};
|
|
let initTime: any;
|
nextTick(() => {
|
// 加载完成之后在绑定拖动事件
|
initTime = setTimeout(() => {
|
rowDrop();
|
}, 500);
|
});
|
|
onUnmounted(() => {
|
clearTimeout(initTime);
|
if (sortable) {
|
sortable.destroy();
|
}
|
});
|
|
function fnGetList() {
|
getFolderApi({}).then((res) => {
|
demo.tableData = convertToTableData(res.data);
|
});
|
}
|
function convertToTableData(data, parentId = null) {
|
try {
|
let tableData = [];
|
|
data.forEach((item) => {
|
let tableItem = {
|
folderId: item.folderId,
|
parentRowId: parentId,
|
rowId: item.rowId,
|
folderName: item.folderName,
|
treeControl: item.treeControl,
|
};
|
|
if (item.list && item.list.length > 0) {
|
let children = convertToTableData(item.list, item.rowId);
|
tableData = tableData.concat(children);
|
}
|
|
tableData.push(tableItem);
|
});
|
return tableData;
|
|
} catch (error) { return [];}
|
}
|
|
const inputRefs = ref<{ [key: number]: HTMLElement | null }>({});
|
function insertEvent() {
|
const $table = xTable.value;
|
const rid = Date.now();
|
const record = {
|
folderName: `新文件夹`,
|
id: rid,
|
};
|
$table.insert(record).then(({ row }) => $table.setEditRow(row));
|
setTimeout(() => {
|
inputRefs.value[rid].focus();
|
}, 300);
|
}
|
import { useMessage } from '@/hooks/web/useMessage';
|
|
const { createMessage } = useMessage();
|
function fnInputHandle(row) {
|
if (row.folderName == '') {
|
editRowEvent(row);
|
fnGetList();
|
return createMessage.error('请输入文件夹名称');
|
}
|
const data =
|
row.opType == 'edit'
|
? {
|
folderId: row.folderId,
|
folderName: row.folderName,
|
treeControl: row.treeControl,
|
parentRowId: row.parentRowId,
|
sortId: row.sortId,
|
}
|
: {
|
folderName: row.folderName,
|
parentRowId: row.parentRowId,
|
};
|
const api = row.opType == 'edit' ? updateFolderApi : addFolderApi;
|
const title = row.opType == 'edit' ? '编辑' : '添加';
|
api(data).then((res) => {
|
if (res.code == 0) {
|
createMessage.success(`${title}成功`);
|
fnGetList();
|
} else {
|
createMessage.error(res.msg);
|
fnGetList();
|
}
|
});
|
}
|
async function insertRow(row) {
|
const $table = xTable.value;
|
const rid = Date.now();
|
const record = {
|
folderName: `新子文件夹`,
|
id: rid,
|
parentRowId: row.rowId, // 需要指定父节点,自动插入该节点中
|
};
|
const { row: newRow } = await $table.insert(record);
|
await $table.setTreeExpand(row, true); // 将父节点展开
|
await $table.setEditRow(newRow); // 插入子节点
|
setTimeout(() => {
|
inputRefs.value[rid].focus();
|
}, 300);
|
}
|
function fnDelete(row) {
|
deleteFolderApi({ folderId: row.folderId })
|
.then((res) => {
|
if (res.code == 0) {
|
fnGetList();
|
createMessage.success(res.msg);
|
}
|
})
|
.catch((err) => {
|
// createMessage.error(err);
|
});
|
}
|
|
function editRowEvent(row) {
|
const $table = xTable.value;
|
row.opType = 'edit';
|
$table.setEditRow(row);
|
}
|
onMounted(() => {
|
fnGetList();
|
});
|
</script>
|
|
<style scoped>
|
.sortable-row-demo .drag-btn {
|
font-size: 12px;
|
cursor: move;
|
}
|
|
.sortable-row-demo .vxe-body--row.sortable-ghost,
|
.sortable-row-demo .vxe-body--row.sortable-chosen {
|
background-color: #dfecfb;
|
}
|
</style>
|