huangyinfeng
6 天以前 a9a03d64cf190188d3db04d14970fc0908b03491
提交 | 用户 | age
63d608 1 <template>
H 2   <div class="p-2">
3     <vxe-toolbar>
4       <template #buttons>
5         <div style="display: flex; align-items: flex-end">
6           <span style="font-size: 1.25rem; font-weight: 600">文件夹</span
7           ><span style="margin-left: 5px; padding-bottom: 4px; font-size: 12px"
8             >管理您的个人文件夹</span
9           >
10         </div>
11       </template>
12       <template #tools>
13         <a-button type="primary" @click="insertEvent">新建文件夹</a-button>
14       </template>
15     </vxe-toolbar>
16
17     <vxe-table
18       ref="xTable"
19       style="margin: 10px 0"
20       :data="demo.tableData"
21       @mounted="onMounted"
22       :row-config="{ keyField: 'id' }"
23       :column-config="{ resizable: true }"
24       :export-config="{}"
a9a03d 25       :tree-config="{ transform: true, rowField: 'rowId', parentField: 'parentRowId' }"
63d608 26       :edit-config="{ trigger: 'manual', mode: 'row' }"
H 27       height="600"
28     >
29       <vxe-column width="40">
30         <template #default>
31           <span class="drag-btn">
32             <HolderOutlined />
33           </span>
34         </template>
35       </vxe-column>
36       <vxe-column field="folderName" title="文件夹名称" minWidth="250" tree-node :edit-render="{}">
37         <template #edit="{ row }">
38           <vxe-input
a9a03d 39             :ref="(el) => (inputRefs[row.id] = el)"
63d608 40             v-model="row.folderName"
H 41             type="text"
42             style="width: 300px"
43             @blur="fnInputHandle(row)"
44           ></vxe-input>
45         </template>
46       </vxe-column>
47       <vxe-column field="age" title="操作" width="250">
48         <template #default="{ row }">
49           <a style="margin-right: 10px" @click="insertRow(row)">添加子文件夹</a>
50           <a style="margin-right: 10px" @click="editRowEvent(row)">编辑</a>
51           <a style="margin-right: 10px" @click="fnDelete(row)">删除</a>
52         </template>
53       </vxe-column>
54     </vxe-table>
55   </div>
56 </template>
57
58 <script lang="ts" setup>
59   import { ref, computed, onMounted, nextTick, onUnmounted, reactive } from 'vue';
60   import {
61     addFolderApi,
62     deleteFolderApi,
63     updateFolderApi,
64     getFolderApi,
65   } from '@/api/email/userList';
66
67   // 排序
68   import { HolderOutlined } from '@ant-design/icons-vue';
69   import Sortable from 'sortablejs';
70   let sortable: any;
71   const demo = reactive({
72     showHelpTip: false,
73     tableData: [],
74   });
75   const xTable = ref();
76   const rowDrop = () => {
77     const $table = xTable.value;
78     sortable = Sortable.create($table.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
79       handle: '.drag-btn',
80       onEnd: (sortableEvent) => {
81         const newIndex = sortableEvent.newIndex as number;
82         const oldIndex = sortableEvent.oldIndex as number;
83         const currRow: Record<string, any> = demo.tableData.splice(oldIndex, 1)[0];
84         // demo.tableData.splice(newIndex, 0, currRow);
85         updateFolderApi({
a9a03d 86           folderId: currRow.folderId,
H 87           folderName: currRow.folderName,
88           treeControl: currRow.treeControl,
89           parentRowId: currRow.parentRowId,
63d608 90           sortId: newIndex,
H 91         })
92           .then(() => {
93             fnGetList();
94           })
95           .catch(() => {});
96       },
97     });
98   };
99
100   let initTime: any;
101   nextTick(() => {
102     // 加载完成之后在绑定拖动事件
103     initTime = setTimeout(() => {
104       rowDrop();
105     }, 500);
106   });
107
108   onUnmounted(() => {
109     clearTimeout(initTime);
110     if (sortable) {
111       sortable.destroy();
112     }
113   });
114
115   function fnGetList() {
116     getFolderApi({}).then((res) => {
117       console.log(res);
a9a03d 118       demo.tableData = convertToTableData(res.data);
H 119       console.log(demo.tableData, '3333333333333');
63d608 120     });
a9a03d 121   }
H 122   function convertToTableData(data, parentId = null) {
123     let tableData = [];
124
125     data.forEach((item) => {
126       let tableItem = {
127         folderId: item.folderId,
128         parentRowId: parentId,
129         rowId: item.rowId,
130         folderName: item.folderName,
131         treeControl: item.treeControl,
132       };
133
134       if (item.list && item.list.length > 0) {
135         let children = convertToTableData(item.list, item.rowId);
136         tableData = tableData.concat(children);
137       }
138
139       tableData.push(tableItem);
140     });
141     return tableData;
63d608 142   }
H 143
144   const inputRefs = ref<{ [key: number]: HTMLElement | null }>({});
145   function insertEvent() {
146     const $table = xTable.value;
147     const rid = Date.now();
148     const record = {
149       folderName: `新数据${rid}`,
150       id: rid,
151     };
152     $table.insert(record).then(({ row }) => $table.setEditRow(row));
153     setTimeout(() => {
154       inputRefs.value[rid].focus();
155     }, 300);
156   }
157   import { useMessage } from '@/hooks/web/useMessage';
158
159   const { createMessage } = useMessage();
160   function fnInputHandle(row) {
161     console.log(row, '----333');
a9a03d 162     if (row.folderName == '') {
H 163       editRowEvent(row)
164       return createMessage.error('请输入文件夹名称');
165     }
166     const data =
167       row.opType == 'edit'
168         ? {
169             folderId: row.folderId,
170             folderName: row.folderName,
171             treeControl: row.treeControl,
172             parentRowId: row.parentRowId,
173             sortId: row.sortId,
174           }
175         : {
176             folderName: row.folderName,
177             parentRowId: row.parentRowId,
178           };
179     const api = row.opType == 'edit' ? updateFolderApi : addFolderApi;
180     const title = row.opType == 'edit' ? '编辑' : '添加';
181     api(data).then((res) => {
63d608 182       if (res.code == 0) {
a9a03d 183         createMessage.success(`${title}成功`);
63d608 184         fnGetList();
H 185       } else {
186         createMessage.error(res.msg);
187       }
188     });
189   }
190   async function insertRow(row) {
191     const $table = xTable.value;
192     const rid = Date.now();
193     const record = {
194       folderName: `新数据${rid}`,
195       id: rid,
196       parentRowId: row.rowId, // 需要指定父节点,自动插入该节点中
197     };
a9a03d 198     console.log(record, '99999993');
63d608 199     const { row: newRow } = await $table.insert(record);
a9a03d 200
63d608 201     await $table.setTreeExpand(row, true); // 将父节点展开
H 202     await $table.setEditRow(newRow); // 插入子节点
203   }
204   function fnDelete(row) {
205     deleteFolderApi({ folderId: row.folderId })
206       .then((res) => {
207         if (res.code == 0) {
208           fnGetList();
209           createMessage.success(res.msg);
210         }
211       })
212       .catch((err) => {
213         // createMessage.error(err);
214       });
215   }
216
217   function editRowEvent(row) {
218     const $table = xTable.value;
a9a03d 219     console.log(row, '---30494');
H 220     row.opType = 'edit';
63d608 221     $table.setEditRow(row);
H 222   }
223   onMounted(() => {
224     fnGetList();
225   });
226 </script>
227
228 <style scoped>
229   .sortable-row-demo .drag-btn {
230     font-size: 12px;
231     cursor: move;
232   }
233
234   .sortable-row-demo .vxe-body--row.sortable-ghost,
235   .sortable-row-demo .vxe-body--row.sortable-chosen {
236     background-color: #dfecfb;
237   }
238 </style>