index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <template>
  2. <div>
  3. <n-drawer
  4. v-model:show="active"
  5. :width="240"
  6. placement="right"
  7. :trap-focus="false"
  8. :block-scroll="false"
  9. :show-mask="false"
  10. :mask-closable="false"
  11. to="#drawer-target"
  12. style="--n-body-padding: 0px"
  13. >
  14. <n-drawer-content title="专题导航">
  15. <div class="drawerContent m-5"></div>
  16. <n-flex justify="center">
  17. <n-button v-if="!isPanoEditing" type="primary" @click="handleAdd"
  18. >+ 添加
  19. </n-button>
  20. </n-flex>
  21. <n-list
  22. hoverable
  23. clickable
  24. style="--n-color-modal: none; margin-top: 20px"
  25. :show-divider="false"
  26. v-if="!isPanoEditing"
  27. >
  28. <n-list-item v-for="(nav, index) in dataList" :key="index" style="">
  29. <n-flex justify="space-between" align="center" :size="0">
  30. <n-flex align="center">
  31. <n-icon size="20">
  32. <WalkSharp />
  33. </n-icon>
  34. <template v-if="isShowEditing(index)">
  35. <n-flex style="flex: 1" align="center">
  36. <n-input-group>
  37. <n-input
  38. v-model:value="nav.title"
  39. style="max-width: 130px"
  40. />
  41. <n-button type="primary" @click="currentEditing = NaN">
  42. 退出
  43. </n-button>
  44. </n-input-group>
  45. </n-flex>
  46. </template>
  47. <div v-else @click="handleItem(index)">
  48. {{ nav.title === '新增路线' ? nav.title + index : nav.title }}
  49. </div>
  50. </n-flex>
  51. <n-dropdown
  52. @select="(key) => handleSelect(key, index)"
  53. trigger="hover"
  54. :options="fullOptions"
  55. >
  56. <n-icon :size="20" v-show="!isShowEditing(index)">
  57. <svg
  58. xmlns="http://www.w3.org/2000/svg"
  59. xmlns:xlink="http://www.w3.org/1999/xlink"
  60. viewBox="0 0 32 32"
  61. >
  62. <circle cx="8" cy="16" r="2" fill="currentColor"></circle>
  63. <circle cx="16" cy="16" r="2" fill="currentColor"></circle>
  64. <circle cx="24" cy="16" r="2" fill="currentColor"></circle>
  65. </svg>
  66. </n-icon>
  67. </n-dropdown>
  68. </n-flex>
  69. </n-list-item>
  70. </n-list>
  71. <template v-else>
  72. <n-flex justify="center" align="center" vertical style="flex: 1">
  73. <n-flex
  74. justify="start"
  75. align="start"
  76. style="min-height: 400px; width: 100%"
  77. vertical
  78. >
  79. <template v-if="dataList[currentPanoEditing].panos.length > 0">
  80. <n-list
  81. hoverable
  82. clickable
  83. style="--n-color-modal: none; width: 100%"
  84. :show-divider="false"
  85. >
  86. <n-list-item
  87. v-for="(pano, index) in dataList[currentPanoEditing].panos"
  88. :key="index"
  89. >
  90. <n-flex justify="space-between">
  91. {{ pano }}
  92. <n-icon
  93. :size="20"
  94. @click="handlePanoDel(index)"
  95. :color="'red'"
  96. >
  97. <TrashOutline />
  98. </n-icon>
  99. </n-flex>
  100. </n-list-item>
  101. </n-list>
  102. </template>
  103. <n-flex v-else justify="center" style="width: 100%">
  104. <span> 暂没数据,请选择线路</span>
  105. </n-flex>
  106. </n-flex>
  107. <n-button
  108. type="primary"
  109. @click="handleItemSubmit"
  110. style="width: 130px"
  111. >确定并返回列表
  112. </n-button>
  113. </n-flex>
  114. </template>
  115. </n-drawer-content>
  116. </n-drawer>
  117. </div>
  118. </template>
  119. <script setup lang="ts">
  120. import { computed, ref, watch, watchEffect } from 'vue'
  121. import { sdk, clearScreen } from '@/sdk'
  122. import { onMounted, onUnmounted } from 'vue'
  123. import {
  124. // NRadio,
  125. // NPopover,
  126. useDialog,
  127. useMessage,
  128. NDropdown,
  129. NList,
  130. NListItem,
  131. NInputGroup
  132. } from 'naive-ui'
  133. import { WalkSharp, TrashOutline, EllipsisHorizontal } from '@vicons/ionicons5'
  134. import { useMainStore } from '@/store'
  135. const panos = ref([])
  136. const main = useMainStore()
  137. const currentEditing = ref(NaN)
  138. const currentPanoEditing = ref()
  139. const isPanoEditing = ref(false)
  140. const naviData = computed(() => main.getEditorData.navigation)
  141. const dataList = ref<
  142. {
  143. title: string
  144. panos: string[]
  145. }[]
  146. >([])
  147. sdk.then((sdk) => {
  148. sdk.PanoCheckManager.on('changed', (list: any) => {
  149. panos.value = list
  150. console.log('panos', panos.value)
  151. })
  152. })
  153. const handleAdd = () => {
  154. dataList.value.push({
  155. title: '新增路线',
  156. panos: []
  157. })
  158. if (panos.value.length === 0) {
  159. } else {
  160. // message.warning('请先保存数据!')
  161. }
  162. }
  163. watchEffect(() => {
  164. if (naviData.value) {
  165. dataList.value = naviData.value
  166. }
  167. })
  168. onMounted(() => {
  169. sdk.then((sdk) => {
  170. sdk.Scene.whenLoaded(() => {
  171. sdk.PanoCheckManager.enter()
  172. // debugger
  173. clearScreen(true)
  174. })
  175. })
  176. })
  177. onUnmounted(() => {
  178. sdk.then((sdk) => {
  179. sdk.PanoCheckManager.leave()
  180. clearScreen(false)
  181. })
  182. })
  183. defineProps<{ msg: string }>()
  184. const dialog = useDialog()
  185. const message = useMessage()
  186. const active = ref(true)
  187. const fullOptions = ref([
  188. {
  189. label: '编辑',
  190. key: '1'
  191. },
  192. {
  193. label: '删除',
  194. key: '2'
  195. }
  196. ])
  197. const handleSelect = (key: string, index: number) => {
  198. // console.log('handleSelect', key)
  199. switch (key) {
  200. case '1':
  201. handleListEdit(index)
  202. break
  203. case '2':
  204. handleListDel(index)
  205. break
  206. }
  207. }
  208. const handleListEdit = (index: number) => {
  209. console.log('handleListEdit', index)
  210. currentPanoEditing.value = index
  211. isPanoEditing.value = true
  212. }
  213. const handleListDel = (index: number) => {
  214. console.log('handleListDel', index)
  215. dataList.value.splice(index, 1)
  216. }
  217. const isShowEditing = computed(() => (i: number) => currentEditing.value === i)
  218. const handleItem = (index: number) => {
  219. console.log('handleItem', index)
  220. currentEditing.value = index
  221. }
  222. const handleItemSubmit = () => {
  223. isPanoEditing.value = false
  224. main.syncNavigation(dataList.value)
  225. }
  226. const handlePanoDel = (index: number) => {
  227. const origin = dataList.value[currentPanoEditing.value].panos
  228. origin && origin.splice(index, 1)
  229. }
  230. watch(
  231. [panos, isPanoEditing],
  232. () => {
  233. if (isPanoEditing.value && typeof currentPanoEditing.value === 'number') {
  234. const origin = dataList.value[currentPanoEditing.value]
  235. if (origin) {
  236. origin.panos = panos.value || []
  237. }
  238. }
  239. },
  240. {
  241. deep: true,
  242. immediate: true
  243. }
  244. )
  245. </script>
  246. <style lang="sass" scoped>
  247. a
  248. color: #42b983
  249. label
  250. margin: 0 0.5em
  251. font-weight: bold
  252. code
  253. background-color: #eee
  254. padding: 2px 4px
  255. border-radius: 4px
  256. color: #304455
  257. </style>