@@ -36,6 +36,7 @@ import { ref, reactive, nextTick, computed } from 'vue'
3636import { canvasState, getConfigure, getController, getCurrent, copyNode, removeNodeById } from '../container'
3737import { useLayout, useModal, useCanvas, usePage, getMergeMeta } from '@opentiny/tiny-engine-meta-register'
3838import { iconRight } from '@opentiny/vue-icon'
39+ import { useMultiSelect } from '../composables/useMultiSelect'
3940
4041const menuState = reactive({
4142 position: null,
@@ -84,6 +85,8 @@ export default {
8485 IconRight: iconRight()
8586 },
8687 setup(props, { emit }) {
88+ const { multiSelectedStates, areSiblingNodes, batchAddParent, groupAddParent } = useMultiSelect()
89+
8790 const menus = ref([
8891 { name: '修改属性', code: 'config' },
8992 {
@@ -116,6 +119,51 @@ export default {
116119 { name: '绑定事件', code: 'bindEvent' }
117120 ])
118121
122+ // 多选菜单
123+ const multiSelectMenus = ref([
124+ { name: '删除', code: 'multiDel' },
125+ { name: '复制', code: 'multiCopy' },
126+ {
127+ name: '添加父级',
128+ items: [
129+ {
130+ name: '批量添加-文字提示',
131+ code: 'batchWrap',
132+ value: 'TinyTooltip'
133+ },
134+ {
135+ name: '批量添加-弹出框',
136+ code: 'batchWrap',
137+ value: 'TinyPopover'
138+ },
139+ {
140+ name: '批量添加-容器',
141+ code: 'batchWrap',
142+ value: 'div'
143+ },
144+ {
145+ name: '整体添加-文字提示',
146+ code: 'groupWrap',
147+ value: 'TinyTooltip',
148+ check: () => areSiblingNodes()
149+ },
150+ {
151+ name: '整体添加-弹出框',
152+ code: 'groupWrap',
153+ value: 'TinyPopover',
154+ check: () => areSiblingNodes()
155+ },
156+ {
157+ name: '整体添加-容器',
158+ code: 'groupWrap',
159+ value: 'div',
160+ check: () => areSiblingNodes()
161+ }
162+ ],
163+ code: 'multiAddParent'
164+ }
165+ ])
166+
119167 // 通过画布右键快捷新建区块
120168 const { SaveNewBlock } = getMergeMeta('engine.plugins.blockmanage')?.components || {}
121169 if (SaveNewBlock) {
@@ -132,14 +180,26 @@ export default {
132180 }
133181 })
134182
135- const filteredMenus = computed(() =>
136- menus.value.filter((item) => {
183+ const isMultiSelect = computed(() => multiSelectedStates.value.length > 1)
184+
185+ const filteredMenus = computed(() => {
186+ // 如果是多选,则展示多选菜单
187+ if (isMultiSelect.value) {
188+ return multiSelectMenus.value.filter((item) => {
189+ if (typeof item.show === 'function') {
190+ return item.show()
191+ }
192+ return true
193+ })
194+ }
195+
196+ return menus.value.filter((item) => {
137197 if (typeof item.show === 'function') {
138198 return item.show()
139199 }
140200 return true
141201 })
142- )
202+ } )
143203
144204 const boxVisibility = ref(false)
145205
@@ -152,6 +212,14 @@ export default {
152212 copy() {
153213 copyNode(getCurrent().schema?.id)
154214 },
215+ multiDel() {
216+ const ids = multiSelectedStates.value.map((state) => state.id)
217+ ids.forEach((id) => removeNodeById(id))
218+ },
219+ multiCopy() {
220+ const ids = multiSelectedStates.value.map((state) => state.id)
221+ ids.forEach((id) => copyNode(id))
222+ },
155223 config() {
156224 useLayout().activeSetting('props')
157225 },
@@ -216,6 +284,14 @@ export default {
216284 parent.children.splice(index, 1, wrapSchema)
217285 getController().addHistory()
218286 },
287+ // 处理批量添加父级的操作
288+ batchWrap({ value }) {
289+ batchAddParent(value)
290+ },
291+ // 处理整体添加父级的操作
292+ groupWrap({ value }) {
293+ groupAddParent(value)
294+ },
219295 createBlock() {
220296 if (useCanvas().isSaved()) {
221297 boxVisibility.value = true
@@ -238,8 +314,13 @@ export default {
238314 return true
239315 }
240316
241- const actions = ['del', 'copy', 'addParent']
242- return actions.includes(actionItem.code) && !getCurrent().schema?.id
317+ if (isMultiSelect.value) {
318+ const multiSelectActions = ['multiDel', 'multiCopy', 'multiAddParent']
319+ return multiSelectActions.includes(actionItem.code) && multiSelectedStates.value.length === 0
320+ } else {
321+ const actions = ['del', 'copy', 'addParent']
322+ return actions.includes(actionItem.code) && !getCurrent().schema?.id
323+ }
243324 }
244325
245326 const onShowChildrenMenu = (menuItem) => {
0 commit comments