index.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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="(element, 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="element.title"
  39. maxlength="15"
  40. style="max-width: 130px"
  41. />
  42. <n-button type="primary" @click="currentEditing = NaN">
  43. 退出
  44. </n-button>
  45. </n-input-group>
  46. </n-flex>
  47. </template>
  48. <div v-else @click="handleItem(index)" class="truncate inline-block" style="width: 140px">
  49. {{ element.title === '新增路线' ? element.title + index : element.title }}
  50. </div>
  51. </n-flex>
  52. <n-dropdown
  53. @select="(key) => handleSelect(key, index)"
  54. trigger="hover"
  55. :options="fullOptions"
  56. >
  57. <n-icon :size="20" v-show="!isShowEditing(index)">
  58. <svg
  59. xmlns="http://www.w3.org/2000/svg"
  60. xmlns:xlink="http://www.w3.org/1999/xlink"
  61. viewBox="0 0 32 32"
  62. >
  63. <circle cx="8" cy="16" r="2" fill="currentColor"></circle>
  64. <circle cx="16" cy="16" r="2" fill="currentColor"></circle>
  65. <circle cx="24" cy="16" r="2" fill="currentColor"></circle>
  66. </svg>
  67. </n-icon>
  68. </n-dropdown>
  69. </n-flex>
  70. </n-list-item>
  71. </n-list>
  72. <template v-else>
  73. <n-flex justify="center" align="center" vertical style="flex: 1">
  74. <n-flex
  75. justify="start"
  76. align="start"
  77. style="min-height: 400px; width: 100%"
  78. vertical
  79. >
  80. <template v-if="dataList[currentPanoEditing].panos.length > 0">
  81. <n-list
  82. hoverable
  83. clickable
  84. style="--n-color-modal: none; width: 100%"
  85. :show-divider="false"
  86. >
  87. <Sortable
  88. :list="dataList[currentPanoEditing].panos"
  89. itemKey="id"
  90. options="options"
  91. @end="logEvent"
  92. >
  93. <template #item="{ element, index }">
  94. <!-- v-for="(pano, index) in dataList[currentPanoEditing].panos" -->
  95. <n-list-item
  96. :key="index"
  97. >
  98. <n-flex justify="space-between">
  99. {{ element.index }}
  100. <n-icon
  101. :size="20"
  102. @click="handlePanoDel(index)"
  103. :color="'red'"
  104. >
  105. <TrashOutline />
  106. </n-icon>
  107. </n-flex>
  108. </n-list-item>
  109. </template>
  110. </Sortable>
  111. </n-list>
  112. </template>
  113. <n-flex v-else justify="center" style="width: 100%">
  114. <span> 暂没数据,请选择线路</span>
  115. </n-flex>
  116. </n-flex>
  117. <n-button
  118. type="primary"
  119. @click="handleItemSubmit"
  120. style="width: 130px"
  121. >确定并返回列表
  122. </n-button>
  123. </n-flex>
  124. </template>
  125. </n-drawer-content>
  126. </n-drawer>
  127. </div>
  128. </template>
  129. <script setup lang="ts">
  130. import { computed, ref, watch, watchEffect } from 'vue'
  131. import { sdk, clearScreen, sdk_mounted } from '@/sdk'
  132. import { onMounted, onUnmounted } from 'vue'
  133. import { Sortable } from 'sortablejs-vue3'
  134. import {
  135. // NRadio,
  136. // NPopover,
  137. useDialog,
  138. useMessage,
  139. NDropdown,
  140. NList,
  141. NListItem,
  142. NInputGroup
  143. } from 'naive-ui'
  144. import { WalkSharp, TrashOutline, EllipsisHorizontal } from '@vicons/ionicons5'
  145. import { useMainStore } from '@/store'
  146. const panos = ref([])
  147. const newDataList = ref<object[]>([])
  148. const main = useMainStore()
  149. const currentEditing = ref(NaN)
  150. const currentPanoEditing = ref()
  151. const isPanoEditing = ref(false)
  152. const naviData = computed(() => main.getEditorData.navigation)
  153. const dataList = ref<
  154. {
  155. title: string
  156. panos: any[]
  157. }[]
  158. >([])
  159. const logEvent = (evt) => {
  160. const changeData = newDataList.value.splice(evt.oldIndex || 0, 1)
  161. newDataList.value.splice(evt.newIndex || 0, 0, changeData[0])
  162. const origin = dataList.value[currentPanoEditing.value]
  163. origin.panos = newDataList.value
  164. }
  165. const handleAdd = () => {
  166. dataList.value.unshift({
  167. title: '新增路线',
  168. panos: []
  169. })
  170. panos.value = []
  171. currentPanoEditing.value = 0
  172. handleSelect("1",0)
  173. main.syncNavigation(dataList.value)
  174. }
  175. watchEffect(() => {
  176. if (naviData.value) {
  177. dataList.value = naviData.value
  178. }
  179. })
  180. onMounted(() => {
  181. })
  182. onUnmounted(() => {
  183. sdk_mounted((sdk) => {
  184. sdk.PanoCheckManager.leave()
  185. clearScreen(false)
  186. })
  187. })
  188. defineProps<{ msg: string }>()
  189. const dialog = useDialog()
  190. const message = useMessage()
  191. const active = ref(true)
  192. const fullOptions = ref([
  193. {
  194. label: '编辑',
  195. key: '1'
  196. },
  197. {
  198. label: '删除',
  199. key: '2'
  200. }
  201. ])
  202. const handleSelect = (key: string, index: number) => {
  203. // console.log('handleSelect', key)
  204. switch (key) {
  205. case '1':
  206. handleListEdit(index)
  207. break
  208. case '2':
  209. handleListDel(index)
  210. break
  211. }
  212. }
  213. const handleListEdit = (index: number) => {
  214. currentPanoEditing.value = index
  215. isPanoEditing.value = true
  216. panos.value = dataList.value[index].panos || []
  217. sdk_mounted((sdk) => {
  218. sdk.Scene.whenLoaded(() => {
  219. sdk.PanoCheckManager.enter(dataList.value[index].panos)
  220. sdk.PanoCheckManager.echo((list: any) => {
  221. panos.value = list
  222. })
  223. clearScreen(true)
  224. })
  225. })
  226. }
  227. const handleListDel = (index: number) => {
  228. dataList.value.splice(index, 1)
  229. }
  230. const isShowEditing = computed(() => (i: number) => currentEditing.value === i)
  231. const handleItem = (index: number) => {
  232. currentEditing.value = index
  233. }
  234. const handleItemSubmit = () => {
  235. isPanoEditing.value = false
  236. main.syncNavigation(dataList.value)
  237. sdk_mounted((sdk) => {
  238. // 重置状态
  239. sdk.PanoCheckManager.leave()
  240. clearScreen(false)
  241. })
  242. }
  243. const handlePanoDel = (index: number) => {
  244. const origin = dataList.value[currentPanoEditing.value].panos
  245. const panoId = origin[index].id
  246. origin && origin.splice(index, 1)
  247. sdk_mounted((sdk) => {
  248. sdk.Scene.whenLoaded(() => {
  249. sdk.PanoCheckManager.setPanoChecked(panoId,false)
  250. })
  251. })
  252. }
  253. watch(
  254. [panos, isPanoEditing],
  255. () => {
  256. if (isPanoEditing.value && typeof currentPanoEditing.value === 'number') {
  257. const origin = dataList.value[currentPanoEditing.value]
  258. if (origin && panos.value.length > 0) {
  259. origin.panos = panos.value
  260. }
  261. newDataList.value = JSON.parse(JSON.stringify(origin.panos))
  262. }
  263. },
  264. {
  265. deep: true,
  266. immediate: true
  267. }
  268. )
  269. </script>
  270. <style lang="sass" scoped>
  271. a
  272. color: #42b983
  273. label
  274. margin: 0 0.5em
  275. font-weight: bold
  276. code
  277. background-color: #eee
  278. padding: 2px 4px
  279. border-radius: 4px
  280. color: #304455
  281. </style>