| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- <template>
- <!--
- <headerBar
- title="遥控模拟器"
- />-->
- <div class="remote-control_main-container">
- <div class="te-c" style="color: #8C92A7">遥控器模拟器</div>
- <el-row align="middle" class="mar-top-20">
- <el-col :span="3"></el-col>
- <el-col :span="6"><div class="button up" title="单击鼠标右键可切换配置" @click="runLeft" @contextmenu="handleLeftRightClick($event, 'left')">左脚</div></el-col>
- <el-col :span="6"><div class="button up" @click="run_take_picture">拍照</div></el-col>
- <el-col :span="6"><div class="button up" title="单击鼠标右键可切换配置" @click="runRight" @contextmenu="handleLeftRightClick($event, 'right')">右脚</div></el-col>
- <el-col :span="3"></el-col>
- </el-row>
- <el-row align="middle" >
- <el-col :span="3"></el-col>
- <el-col :span="6"><div class="button up" @click="handleLeftRightClick($event, 'left')"><span style="font-size: 12px;">左脚配置</span></div></el-col>
- <el-col :span="6"></el-col>
- <el-col :span="6"><div class="button up" @click="handleLeftRightClick($event, 'right')"><span style="font-size: 12px;">右脚配置</span></div></el-col>
- <el-col :span="3"></el-col>
- </el-row>
- <el-row align="middle">
- <el-col :span="3"></el-col>
- <el-col :span="6">
- <div class="button up" @click="switchLED(1)" v-log="{ describe: { action: 'LED开启' } }">LED开</div>
- </el-col>
- <el-col :span="6">
- <div class="button up" @click="switchLED(0)" v-log="{ describe: { action: 'LED关闭' } }">LED关</div>
- </el-col>
- <el-col :span="6">
- <div class="button up" :class="{ disabled: !canStop }" @click="oneClickStop" v-log="{ describe: { action: '一键停止拍摄' } }">停止</div>
- </el-col>
- <el-col :span="3"></el-col>
- </el-row>
- <!-- 左脚配置菜单 -->
- <div v-if="showLeftMenu" class="context-menu" :style="{ left: menuPosition.x + 'px', top: menuPosition.y + 'px' }" @click.stop>
- <div class="menu-title">左脚配置</div>
- <div class="menu-items">
- <div
- v-for="tab in leftTabs"
- :key="tab.id"
- class="menu-item"
- :class="{ active: leftConfigId === tab.id }"
- @click="selectConfig('left', tab.id)"
- >
- {{ leftConfigId === tab.id ? '✓ ' : '' }}{{ tab.mode_name }}
- </div>
- </div>
- </div>
- <!-- 右脚配置菜单 -->
- <div v-if="showRightMenu" class="context-menu" :style="{ left: menuPosition.x + 'px', top: menuPosition.y + 'px' }" @click.stop>
- <div class="menu-title">右脚配置</div>
- <div class="menu-items">
- <div
- v-for="tab in rightTabs"
- :key="tab.id"
- class="menu-item"
- :class="{ active: rightConfigId === tab.id }"
- @click="selectConfig('right', tab.id)"
- >
- {{ rightConfigId === tab.id ? '✓ ' : '' }}{{ tab.mode_name }}
- </div>
- </div>
- </div>
- <!-- 点击其他地方关闭菜单 -->
- <div v-if="showLeftMenu || showRightMenu" class="menu-overlay" @click="closeMenus"></div>
- </div>
- </template>
- <script setup lang="ts">
- import { defineEmits, defineProps, ref } from 'vue'
- import socket from "@/stores/modules/socket";
- import { getTopTabs, setLeftRightConfig } from '@/apis/setting';
- import { ElMessage } from 'element-plus';
- // 初始化 WebSocket 状态管理
- const socketStore = socket()
- const props = defineProps<{
- canStop: boolean
- }>()
- const emit = defineEmits(['onRemoteControl'])
- // 配置切换相关
- const leftConfigId = ref(0)
- const rightConfigId = ref(0)
- const leftTabs = ref([]) // 左脚配置选项
- const rightTabs = ref([]) // 右脚配置选项
- const showLeftMenu = ref(false) // 显示左脚菜单
- const showRightMenu = ref(false) // 显示右脚菜单
- const menuPosition = ref({ x: 0, y: 0 }) // 菜单位置
- const runLeft = async () => {
- emit('onRemoteControl','left')
- }
- const runRight = async () => {
- emit('onRemoteControl','right')
- }
- const run_take_picture = () => {
- emit('onRemoteControl','take_picture')
- }
- //LED
- const switchLED = async (value) => {
- socketStore.sendMessage({
- type: 'control_mcu',
- data: {
- device_name: "laser_position",
- value,
- }
- });
- }
- // 一键停止
- const oneClickStop = () => {
- if (!props.canStop) {
- return
- }
- socketStore.sendMessage({
- type: 'stop_action',
- })
- }
- // 右击左脚按钮
- const handleLeftRightClick = (event, type) => {
- event.preventDefault()
- menuPosition.value = { x: event.clientX, y: event.clientY }
- if (type === 'left') {
- showLeftMenu.value = true
- showRightMenu.value = false
- loadLeftConfig()
- } else {
- showRightMenu.value = true
- showLeftMenu.value = false
- loadRightConfig()
- }
- }
- // 加载左脚配置
- const loadLeftConfig = async () => {
- try {
- const result = await getTopTabs({ type: 0 })
- if (result.code === 0) {
- leftConfigId.value = result.data.select_configs.left
- leftTabs.value = result.data.tabs
- }
- } catch (error) {
- console.error('加载左脚配置失败:', error)
- }
- }
- // 加载右脚配置
- const loadRightConfig = async () => {
- try {
- const result = await getTopTabs({ type: 1 })
- if (result.code === 0) {
- rightConfigId.value = result.data.select_configs.right
- rightTabs.value = result.data.tabs
- }
- } catch (error) {
- console.error('加载右脚配置失败:', error)
- }
- }
- // 选择配置
- const selectConfig = async (type, configId) => {
- try {
- const result = await setLeftRightConfig({
- type: type,
- id: configId
- })
- if (result.code === 0) {
- if (type === 'left') {
- leftConfigId.value = configId
- showLeftMenu.value = false
- } else {
- rightConfigId.value = configId
- showRightMenu.value = false
- }
- ElMessage.success('配置切换成功')
- }
- } catch (error) {
- console.error('切换配置失败:', error)
- ElMessage.error('配置切换失败')
- }
- }
- // 关闭菜单
- const closeMenus = () => {
- showLeftMenu.value = false
- showRightMenu.value = false
- }
- </script>
- <style scoped lang="scss">
- .remote-control_main-container {
- background: #EAECED;
- height: 450px;
- width: 300px;
- margin: 0 auto;
- margin-top: 10px;
- padding-top: 30px;
- background: url(@/assets/images/Photography/yk.png) 0px 0px no-repeat;
- background-size: 300px 450px;
- }
- .button {
- width: 60px;
- height: 60px;
- background: #fff;
- border-radius: 60px;
- line-height: 60px;
- color: #474747;
- margin: 0 auto;
- box-shadow: 0 2px 8px 0 rgba(0,0,0,0.2);
- background: url(@/assets/images/Photography/hui.png) 0px 0px no-repeat;
- background-size: 60px 60px;
- }
- .el-row {
- min-height: 100px;
- }
- .button:hover {
- background: url(@/assets/images/Photography/lan.png) 0px 0px no-repeat;
- background-size: 60px 60px;
- cursor: pointer;
- }
- .button.stop {
- background: #ff4c00;
- color: white;
- border-radius: 10px;
- width: 120px;
- height: 40px;
- line-height: 40px;
- font-size: 14px;
- margin: 0 auto;
- }
- .button.stop:hover {
- background: #e64500;
- }
- .button.disabled {
- opacity: 0.5;
- cursor: not-allowed;
- pointer-events: none;
- }
- .context-menu {
- position: fixed;
- background: white;
- border: 1px solid #e4e7ed;
- border-radius: 4px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- z-index: 2000;
- min-width: 120px;
- max-width: 200px;
- }
- .menu-title {
- padding: 8px 12px;
- font-size: 12px;
- font-weight: 600;
- color: #606266;
- border-bottom: 1px solid #ebeef5;
- background-color: #f5f7fa;
- }
- .menu-items {
- max-height: 250px;
- overflow: auto;
- }
- .menu-item {
- padding: 8px 12px;
- font-size: 14px;
- color: #606266;
- cursor: pointer;
- transition: background-color 0.2s;
- &:hover {
- background-color: #f5f7fa;
- }
- &.active {
- color: #2957FF;
- font-weight: 600;
- }
- }
- .menu-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 1999;
- }
- </style>
|