glance.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <!-- 一点即视 -->
  2. <template>
  3. <div class="glance relative">
  4. <div class="glance-right">
  5. <UseFullscreen class="flex items-center" v-slot="{ toggle, isFullscreen }">
  6. <div class="glance-right-wrapper screen-full-target">
  7. <pub-video-new :newClass="'glance-ps-video' + currentActive" />
  8. <joystick :id="data.id" />
  9. <div
  10. v-if="isVideo"
  11. absolute
  12. top-0
  13. right-0
  14. left-0
  15. bottom-0
  16. flex
  17. flex-justify-center
  18. flex-items-center
  19. >
  20. <Icon icon="loading" color="#007bff" width="40" height="40" />
  21. </div>
  22. <div
  23. v-if="!isVideo && !useSystem.videoList.ball_camera"
  24. absolute
  25. top-0
  26. right-0
  27. left-0
  28. bottom-0
  29. flex
  30. flex-justify-center
  31. flex-items-center
  32. >
  33. <n-empty size="large" description="球机网络故障,请检查网络后重连设备!">
  34. <template #extra>
  35. <n-button size="small" @click="reconnect"> 重连 </n-button>
  36. </template>
  37. </n-empty>
  38. </div>
  39. <!-- 操作按钮 -->
  40. <div
  41. class="panoramic-situation-main-btn-box absolute top-10px right-10px flex flex-row-reverse"
  42. >
  43. <!-- 全屏按钮 -->
  44. <div
  45. class="panoramic-situation-main-all-screen screen-full-trigger cursor-pointer ml-1"
  46. alt="全屏按钮"
  47. >
  48. <Icon
  49. icon="icon-park-outline:off-screen"
  50. color="#8ac5ff"
  51. width="25"
  52. height="25"
  53. v-if="isFullscreen"
  54. @click="toggle"
  55. />
  56. <Icon
  57. icon="iconamoon:screen-full"
  58. color="#8ac5ff"
  59. width="25"
  60. height="25"
  61. @click="toggle"
  62. v-else
  63. />
  64. </div>
  65. <!-- 关闭按钮 -->
  66. <Icon
  67. icon="grommet-icons:power-shutdown"
  68. v-if="!isFullscreen"
  69. mr-1
  70. color="#8ac5ff"
  71. width="25"
  72. height="25"
  73. cursor-pointer
  74. alt="关闭画面"
  75. @click="closeWorker"
  76. />
  77. </div>
  78. </div>
  79. </UseFullscreen>
  80. </div>
  81. </div>
  82. </template>
  83. <script setup>
  84. import Joystick from './joystick.vue'
  85. import { NEmpty, NButton } from 'naive-ui'
  86. import { uuid } from '@/utils'
  87. import { omatVideoPlayer } from '@/assets/js/video-lib/flv/omatVideoPlayer'
  88. import { useOutsideSystemStore } from '@/stores/modules/system.js'
  89. import { UseFullscreen } from '@vueuse/components'
  90. defineOptions({ name: 'GlanceBox' })
  91. const clearCom = inject('clearCom')
  92. const useSystem = useOutsideSystemStore()
  93. const { API_CLICKTOSEE_POST, API_LY_B_RELOGIN_POST } = useRequest()
  94. const isVideo = ref(true)
  95. const props = defineProps({
  96. currentActive: Number,
  97. data: {
  98. type: Object,
  99. default: () => {}
  100. }
  101. })
  102. watch(
  103. () => useSystem.partObj,
  104. async (newV) => {
  105. // if (useSystem.winActive === props.currentActive) {
  106. // }
  107. await API_CLICKTOSEE_POST(
  108. { CameraId: props.data.id },
  109. {
  110. X: Number(newV.PartCenterX),
  111. Y: Number(newV.PartCenterY)
  112. }
  113. )
  114. },
  115. { deep: true }
  116. )
  117. // 球机重连
  118. const reconnect = async () => {
  119. isVideo.value = true
  120. try {
  121. await API_LY_B_RELOGIN_POST({ BallCameraId: props.data.id })
  122. getWss()
  123. } catch (e) {
  124. if ([7].includes(e.code)) {
  125. isVideo.value = false
  126. }
  127. }
  128. }
  129. const playerObj = shallowRef(null)
  130. provide('playerObj', playerObj)
  131. const getWss = () => {
  132. nextTick(() => {
  133. isVideo.value = true
  134. const url = useSystem.videoList.ball_camera
  135. .replace('{4}', uuid())
  136. .replace('{12}', props.data.id)
  137. playerObj.value = omatVideoPlayer(
  138. '.glance-ps-video' + props.currentActive,
  139. url,
  140. () => {
  141. isVideo.value = false
  142. },
  143. { enableZoom: false, enableDrag: false }
  144. )
  145. })
  146. }
  147. // 关闭线程
  148. const closeWorker = () => {
  149. playerObj.value?.destroyed()
  150. clearCom()
  151. }
  152. onMounted(() => {
  153. getWss()
  154. })
  155. onUnmounted(() => {
  156. playerObj.value?.destroyed()
  157. })
  158. </script>
  159. <style scoped lang="scss">
  160. .glance {
  161. display: flex;
  162. height: 100%;
  163. &-left {
  164. width: 400px;
  165. height: 100%;
  166. border-right: 1px solid rgba(0, 128, 255, 0.4);
  167. }
  168. &-right {
  169. flex: 1;
  170. display: flex;
  171. justify-content: center;
  172. align-items: center;
  173. &-wrapper {
  174. width: 100%;
  175. position: relative;
  176. overflow: hidden;
  177. transition: all 0.5s;
  178. aspect-ratio: 16/9;
  179. }
  180. }
  181. }
  182. </style>