feat: 添加右键菜单功能,优化机器人列表交互,增强用户体验
This commit is contained in:
parent
fe1ef44e9d
commit
c32dd105ef
@ -1,15 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { type RobotGroup, type RobotInfo, seizeRobotByIds } from '@api/robot';
|
import { type RobotGroup, type RobotInfo } from '@api/robot';
|
||||||
import type { RobotAddModalRef } from '@common/modal/robot-add-modal.vue';
|
import type { RobotAddModalRef } from '@common/modal/robot-add-modal.vue';
|
||||||
import type { RobotGroupRenameModalRef } from '@common/modal/robot-group-rename-modal.vue';
|
import type { RobotGroupRenameModalRef } from '@common/modal/robot-group-rename-modal.vue';
|
||||||
import type { RobotRegisterModalRef } from '@common/modal/robot-register-modal.vue';
|
import type { RobotRegisterModalRef } from '@common/modal/robot-register-modal.vue';
|
||||||
import type { EditorService } from '@core/editor.service';
|
import type { EditorService } from '@core/editor.service';
|
||||||
import { Modal } from 'ant-design-vue';
|
import { Modal } from 'ant-design-vue';
|
||||||
import { watch } from 'vue';
|
import { computed, inject, type InjectionKey, reactive, ref, type ShallowRef, shallowRef, watch } from 'vue';
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { computed, inject, type InjectionKey, ref, type ShallowRef, shallowRef } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
import { createContextMenuManager, handleContextMenu } from '../services/context-menu';
|
||||||
|
import ContextMenu from './context-menu/context-menu.vue';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
token: InjectionKey<ShallowRef<EditorService>>;
|
token: InjectionKey<ShallowRef<EditorService>>;
|
||||||
@ -27,15 +27,25 @@ type Events = {
|
|||||||
const emit = defineEmits<Events>();
|
const emit = defineEmits<Events>();
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
// const router = useRouter(); // 暂时注释掉,保留以备将来使用
|
||||||
|
|
||||||
//#region 接口
|
//#region 右键菜单
|
||||||
const seizeRobots = async () => {
|
const contextMenuManager = createContextMenuManager();
|
||||||
const res = await seizeRobotByIds([...selected.keys()]);
|
const contextMenuState = ref(contextMenuManager.getState());
|
||||||
editor.value.updateRobots(res, { canControl: true });
|
|
||||||
|
// 订阅右键菜单状态变化
|
||||||
|
contextMenuManager.subscribe((state) => {
|
||||||
|
contextMenuState.value = state;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理右键菜单关闭
|
||||||
|
const handleContextMenuClose = () => {
|
||||||
|
contextMenuManager.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
const keyword = ref<string>('');
|
const keyword = ref<string>('');
|
||||||
|
|
||||||
//#region 机器人列表
|
//#region 机器人列表
|
||||||
@ -75,6 +85,22 @@ const selectRobot = (id: RobotInfo['id'], checked: boolean) => {
|
|||||||
selected.delete(id);
|
selected.delete(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 处理机器人右键点击
|
||||||
|
const handleRobotRightClick = (event: MouseEvent, robot: RobotInfo) => {
|
||||||
|
// 为事件目标添加机器人标识
|
||||||
|
if (event.target && event.target instanceof HTMLElement) {
|
||||||
|
event.target.setAttribute('data-robot-id', robot.id);
|
||||||
|
event.target.setAttribute('data-robot-type', 'robot');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理右键菜单 - handleContextMenu 内部会处理 preventDefault 和 stopPropagation
|
||||||
|
handleContextMenu(event, contextMenuManager, {
|
||||||
|
robotService: {
|
||||||
|
getRobotById: (id: string) => editor.value.getRobotById(id)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region 机器人组操作
|
//#region 机器人组操作
|
||||||
@ -92,16 +118,6 @@ const toDeleteGroup = (id: RobotGroup['id']) =>
|
|||||||
onOk: () => editor.value.deleteRobotGroup(id),
|
onOk: () => editor.value.deleteRobotGroup(id),
|
||||||
});
|
});
|
||||||
|
|
||||||
const toEditGroup = (id: RobotGroup['id']) =>
|
|
||||||
Modal.confirm({
|
|
||||||
class: 'confirm',
|
|
||||||
title: t('您确定要编辑该机器人组吗?'),
|
|
||||||
content: t('请确保当前场景已经保存,否则将导致当前场景数据丢失。'),
|
|
||||||
centered: true,
|
|
||||||
cancelText: t('取消'),
|
|
||||||
okText: t('编辑'),
|
|
||||||
onOk: () => router.push({ name: '组编辑', params: { sid: props.sid, id } }),
|
|
||||||
});
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region 机器人操作
|
//#region 机器人操作
|
||||||
@ -137,6 +153,16 @@ const toRemoveRobots = () =>
|
|||||||
<RobotAddModal ref="refAddRobot" :token="token" />
|
<RobotAddModal ref="refAddRobot" :token="token" />
|
||||||
<RobotRegisterModal ref="refRegisterRobot" :token="token" />
|
<RobotRegisterModal ref="refRegisterRobot" :token="token" />
|
||||||
<RobotGroupRenameModal ref="refRenameGroup" :token="token" />
|
<RobotGroupRenameModal ref="refRenameGroup" :token="token" />
|
||||||
|
|
||||||
|
<!-- 右键菜单 -->
|
||||||
|
<ContextMenu
|
||||||
|
:visible="contextMenuState.visible"
|
||||||
|
:x="contextMenuState.x"
|
||||||
|
:y="contextMenuState.y"
|
||||||
|
:menu-type="contextMenuState.menuType"
|
||||||
|
:robot-info="contextMenuState.robotInfo"
|
||||||
|
@close="handleContextMenuClose"
|
||||||
|
/>
|
||||||
|
|
||||||
<a-flex class="full" vertical>
|
<a-flex class="full" vertical>
|
||||||
<a-input class="search mb-16" :placeholder="$t('请输入搜索关键字')" v-model:value="keyword">
|
<a-input class="search mb-16" :placeholder="$t('请输入搜索关键字')" v-model:value="keyword">
|
||||||
@ -148,16 +174,6 @@ const toRemoveRobots = () =>
|
|||||||
<a-flex v-if="editable" class="mb-8" style="height: 32px" justify="space-between" align="center">
|
<a-flex v-if="editable" class="mb-8" style="height: 32px" justify="space-between" align="center">
|
||||||
<a-checkbox :checked="isAllSelected" @change="selectAll($event.target.checked)">{{ $t('全选') }}</a-checkbox>
|
<a-checkbox :checked="isAllSelected" @change="selectAll($event.target.checked)">{{ $t('全选') }}</a-checkbox>
|
||||||
<a-space align="center">
|
<a-space align="center">
|
||||||
<a-button
|
|
||||||
v-if="false"
|
|
||||||
class="icon-btn panel-btn"
|
|
||||||
size="small"
|
|
||||||
:title="$t('抢占控制权')"
|
|
||||||
@click="seizeRobots"
|
|
||||||
:disabled="!selected.size"
|
|
||||||
>
|
|
||||||
<i class="mask control" />
|
|
||||||
</a-button>
|
|
||||||
<a-button
|
<a-button
|
||||||
class="icon-btn panel-btn"
|
class="icon-btn panel-btn"
|
||||||
size="small"
|
size="small"
|
||||||
@ -241,6 +257,7 @@ const toRemoveRobots = () =>
|
|||||||
:class="{ 'ph-16': !editable, 'pl-12': editable, 'pr-8': editable, selected: item.id === current }"
|
:class="{ 'ph-16': !editable, 'pl-12': editable, 'pr-8': editable, selected: item.id === current }"
|
||||||
style="height: 36px"
|
style="height: 36px"
|
||||||
@click="emit('change', item.id)"
|
@click="emit('change', item.id)"
|
||||||
|
@contextmenu="handleRobotRightClick($event, item)"
|
||||||
>
|
>
|
||||||
<template v-if="editable" #actions>
|
<template v-if="editable" #actions>
|
||||||
<a-button
|
<a-button
|
||||||
@ -283,4 +300,14 @@ const toRemoveRobots = () =>
|
|||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 机器人列表项样式
|
||||||
|
.ant-list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -165,7 +165,10 @@ export function parseEventData(event: MouseEvent | PointerEvent): ParsedEventDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 回退到DOM元素检查
|
// 回退到DOM元素检查
|
||||||
if (target?.closest('.robot-item')) {
|
// 检查机器人类型 - 支持多种选择器
|
||||||
|
if (target?.closest('.robot-item') ||
|
||||||
|
target?.closest('.ant-list-item') && target.dataset.robotType === 'robot' ||
|
||||||
|
target?.classList.contains('ant-list-item') && target.dataset.robotType === 'robot') {
|
||||||
return {
|
return {
|
||||||
type: 'robot',
|
type: 'robot',
|
||||||
id: target.dataset.robotId || target.id,
|
id: target.dataset.robotId || target.id,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user