3434 :current-node-key =" currentNodeKey"
3535 highlight-current
3636 class =" overflow-inherit_node__children"
37+ draggable
38+ :allow-drop =" allowDrop"
39+ :allow-drag =" allowDrag"
40+ @node-drop =" handleDrop"
3741 node-key =" id"
3842 v-loading =" loading"
3943 v-bind =" $attrs"
6367 <el-dropdown-menu >
6468 <el-dropdown-item
6569 @click.stop =" openCreateFolder(data)"
66- v-if =" node.level !== 3 && permissionPrecise.folderCreate(data.id)"
70+ v-if =" permissionPrecise.folderCreate(data.id)"
6771 >
6872 <AppIcon iconName =" app-add-folder" class =" color-secondary" ></AppIcon >
6973 {{ $t('components.folder.addChildFolder') }}
7579 <AppIcon iconName =" app-edit" class =" color-secondary" ></AppIcon >
7680 {{ $t('common.edit') }}
7781 </el-dropdown-item >
82+ <el-dropdown-item
83+ @click.stop =" openMoveToDialog(data)"
84+ v-if =" node.level !== 1 && permissionPrecise.folderEdit(data.id)"
85+ >
86+ <AppIcon iconName =" app-migrate" class =" color-secondary" ></AppIcon >
87+ {{ $t('common.moveTo') }}
88+ </el-dropdown-item >
7889 <el-dropdown-item
7990 @click.stop =" openAuthorization(data)"
8091 v-if =" permissionPrecise.folderAuth(data.id)"
101112 </el-scrollbar >
102113 </div >
103114 <CreateFolderDialog ref =" CreateFolderDialogRef" @refresh =" refreshFolder" :title =" title" />
115+ <MoveToDialog
116+ ref =" MoveToDialogRef"
117+ :source =" props.source"
118+ @refresh =" emit('refreshTree')"
119+ />
104120 <ResourceAuthorizationDrawer
105121 :type =" props.source"
106122 :is-folder =" true"
@@ -117,13 +133,14 @@ import type { TreeInstance } from 'element-plus'
117133import CreateFolderDialog from ' @/components/folder-tree/CreateFolderDialog.vue'
118134import ResourceAuthorizationDrawer from ' @/components/resource-authorization-drawer/index.vue'
119135import { t } from ' @/locales'
136+ import MoveToDialog from ' @/components/folder-tree/MoveToDialog.vue'
120137import { i18n_name } from ' @/utils/common'
121138import folderApi from ' @/api/folder'
122139import { EditionConst } from ' @/utils/permission/data'
123140import { hasPermission } from ' @/utils/permission/index'
124141import useStore from ' @/stores'
125142import { TreeToFlatten } from ' @/utils/array'
126- import { MsgConfirm } from ' @/utils/message'
143+ import { MsgConfirm , MsgError , MsgSuccess } from ' @/utils/message'
127144import permissionMap from ' @/permission'
128145import bus from ' @/bus'
129146defineOptions ({ name: ' FolderTree' })
@@ -177,13 +194,59 @@ const permissionPrecise = computed(() => {
177194
178195const MoreFilledPermission = (node : any , data : any ) => {
179196 return (
180- ( node . level !== 3 && permissionPrecise .value .folderCreate (data .id ) ) ||
197+ permissionPrecise .value .folderCreate (data .id ) ||
181198 permissionPrecise .value .folderEdit (data .id ) ||
182199 permissionPrecise .value .folderDelete (data .id ) ||
183200 permissionPrecise .value .folderAuth (data .id )
184201 )
185202}
186203
204+ const MoveToDialogRef = ref ()
205+ function openMoveToDialog(data : any ) {
206+ const obj = {
207+ id: data .id ,
208+ folder_type: props .source ,
209+ }
210+ MoveToDialogRef .value .open (obj , true )
211+ }
212+
213+ const allowDrag = (node : any ) => {
214+ return permissionPrecise .value .folderEdit (node .data .id )
215+ }
216+
217+ const allowDrop = (draggingNode : any , dropNode : any , type : string ) => {
218+ const dropData = dropNode .data
219+ if (type === ' inner' ) {
220+ return permissionPrecise .value .folderEdit (dropData .id )
221+ }
222+ return false
223+ }
224+
225+ const handleDrop = (draggingNode : any , dropNode : any , dropType : string , ev : DragEvent ) => {
226+ const dragData = draggingNode .data
227+ const dropData = dropNode .data
228+
229+ let newParentId: string
230+ if (dropType === ' inner' ) {
231+ newParentId = dropData .id
232+ } else {
233+ newParentId = dropData .parent_id
234+ }
235+ const obj = {
236+ ... dragData ,
237+ parent_id: newParentId
238+ }
239+ folderApi .putFolder (dragData .id , props .source , obj , loading )
240+ .then (() => {
241+ MsgSuccess (t (' common.saveSuccess' ))
242+ emit (' refreshTree' )
243+ })
244+ .catch (() => {
245+ MsgError (t (' components.folder.requiredMessage' ))
246+ emit (' refreshTree' )
247+ })
248+ }
249+
187250const { folder } = useStore ()
188251onBeforeRouteLeave ((to , from ) => {
189252 folder .setCurrentFolder ({})
@@ -328,6 +391,19 @@ onUnmounted(() => {
328391 height : calc (100vh - 210px );
329392 }
330393}
394+ :deep(.el-tree ) {
395+ .el-tree-node.is-dragging {
396+ opacity : 0.5 ;
397+ }
398+ .el-tree-node.is-drop-inner > .el-tree-node__content {
399+ background-color : var (--el-color-primary-light-9 );
400+ border : 2px dashed var (--el-color-primary );
401+ border-radius : 4px ;
402+ }
403+ .el-tree-node__content {
404+ position : relative ;
405+ }
406+ }
331407:deep(.overflow-inherit_node__children ) {
332408 .el-tree-node__children {
333409 overflow : inherit !important ;
0 commit comments