ComputerViewerView.vue 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. <script setup lang="ts">
  2. import { onBeforeUnmount, onMounted, ref } from 'vue'
  3. import { useRoute } from 'vue-router'
  4. import { apiRequest } from '@/api/client'
  5. import ComputerPanel from '@/components/workspace/ComputerPanel.vue'
  6. import type { WorkspaceAgent } from '@shared/workspace'
  7. const route = useRoute(), agent = ref<WorkspaceAgent>(), error = ref(''), panel = ref<InstanceType<typeof ComputerPanel>>()
  8. const backend = ref<'desktop' | 'cloud' | 'vm'>(), host = ref<string>()
  9. let detach: (() => void) | undefined
  10. async function finish(){await window.yaoyaoDesktop?.computerClosed()}
  11. async function targetChanged(backend: 'desktop' | 'cloud' | 'vm', host?: string) {
  12. await window.yaoyaoDesktop?.computerTargetChanged?.({backend,host})
  13. }
  14. async function close() {
  15. if (panel.value) await panel.value.close()
  16. else await window.yaoyaoDesktop?.computerClosed()
  17. }
  18. onMounted(async () => {
  19. detach = window.yaoyaoDesktop?.onComputerClose(() => { void close() })
  20. try {
  21. const requestedBackend = route.query.backend, requestedHost = route.query.host
  22. if (requestedBackend !== undefined && requestedBackend !== 'desktop' && requestedBackend !== 'cloud' && requestedBackend !== 'vm')
  23. throw new Error('所选电脑无效,请关闭窗口后重新选择')
  24. if (requestedHost !== undefined && (requestedBackend !== 'desktop' || typeof requestedHost !== 'string' || !/^[\w-]{1,128}$/.test(requestedHost)))
  25. throw new Error('所选电脑无效,请关闭窗口后重新选择')
  26. backend.value = requestedBackend
  27. host.value = typeof requestedHost === 'string' ? requestedHost : undefined
  28. const result = await apiRequest<{agents: WorkspaceAgent[]}>('/api/app/agents')
  29. agent.value = result.agents.find(item => item.id === route.params.agentId)
  30. if (!agent.value) throw new Error('这台电脑不可用,或你已没有访问权限')
  31. } catch (cause) { error.value = cause instanceof Error ? cause.message : '无法打开电脑' }
  32. })
  33. onBeforeUnmount(() => detach?.())
  34. </script>
  35. <template>
  36. <ComputerPanel v-if="agent" ref="panel" :agents="[agent]" :backend="backend" :host="host" standalone auto-take @close="finish" @target-changed="targetChanged" />
  37. <main v-else class="viewer-loading" role="status"><p>{{ error || '正在连接电脑…' }}</p><button v-if="error" @click="close">关闭窗口</button></main>
  38. </template>
  39. <style scoped>
  40. .viewer-loading{height:100dvh;display:grid;place-content:center;background:#111315;color:#f4f4f4;text-align:center}.viewer-loading button{padding:12px;border-radius:8px;border:1px solid #666;background:#292c30;color:inherit}
  41. </style>