index.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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" 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: 145px">
  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. console.log('end', evt, newDataList.value)
  165. }
  166. const handleAdd = () => {
  167. dataList.value.push({
  168. title: '新增路线',
  169. panos: []
  170. })
  171. handleSelect("1",dataList.value.length-1)
  172. main.syncNavigation(dataList.value)
  173. }
  174. watchEffect(() => {
  175. if (naviData.value) {
  176. dataList.value = naviData.value
  177. }
  178. })
  179. onMounted(() => {
  180. })
  181. onUnmounted(() => {
  182. sdk_mounted((sdk) => {
  183. sdk.PanoCheckManager.leave()
  184. clearScreen(false)
  185. })
  186. })
  187. defineProps<{ msg: string }>()
  188. const dialog = useDialog()
  189. const message = useMessage()
  190. const active = ref(true)
  191. const fullOptions = ref([
  192. {
  193. label: '编辑',
  194. key: '1'
  195. },
  196. {
  197. label: '删除',
  198. key: '2'
  199. }
  200. ])
  201. const handleSelect = (key: string, index: number) => {
  202. // console.log('handleSelect', key)
  203. switch (key) {
  204. case '1':
  205. handleListEdit(index)
  206. break
  207. case '2':
  208. handleListDel(index)
  209. break
  210. }
  211. }
  212. const handleListEdit = (index: number) => {
  213. console.log('handleListEdit', index)
  214. currentPanoEditing.value = index
  215. isPanoEditing.value = true
  216. sdk_mounted((sdk) => {
  217. sdk.Scene.whenLoaded(() => {
  218. sdk.PanoCheckManager.enter(dataList.value[index].panos)
  219. sdk.PanoCheckManager.echo((list: any) => {
  220. panos.value = list
  221. })
  222. clearScreen(true)
  223. })
  224. })
  225. }
  226. const handleListDel = (index: number) => {
  227. console.log('handleListDel', index)
  228. dataList.value.splice(index, 1)
  229. }
  230. const isShowEditing = computed(() => (i: number) => currentEditing.value === i)
  231. const handleItem = (index: number) => {
  232. console.log('handleItem', index)
  233. currentEditing.value = index
  234. }
  235. const handleItemSubmit = () => {
  236. isPanoEditing.value = false
  237. main.syncNavigation(dataList.value)
  238. sdk_mounted((sdk) => {
  239. // 重置状态
  240. sdk.PanoCheckManager.leave()
  241. clearScreen(false)
  242. })
  243. }
  244. const handlePanoDel = (index: number) => {
  245. const origin = dataList.value[currentPanoEditing.value].panos
  246. const panoId = origin[index].id
  247. origin && origin.splice(index, 1)
  248. sdk_mounted((sdk) => {
  249. sdk.Scene.whenLoaded(() => {
  250. sdk.PanoCheckManager.setPanoChecked(panoId,false)
  251. })
  252. })
  253. }
  254. watch(
  255. [panos, isPanoEditing],
  256. () => {
  257. if (isPanoEditing.value && typeof currentPanoEditing.value === 'number') {
  258. const origin = dataList.value[currentPanoEditing.value]
  259. if (origin && panos.value.length > 0) {
  260. origin.panos = panos.value
  261. }
  262. console.log('panos', origin.panos)
  263. newDataList.value = JSON.parse(JSON.stringify(origin.panos))
  264. }
  265. },
  266. {
  267. deep: true,
  268. immediate: true
  269. }
  270. )
  271. </script>
  272. <style lang="sass" scoped>
  273. a
  274. color: #42b983
  275. label
  276. margin: 0 0.5em
  277. font-weight: bold
  278. code
  279. background-color: #eee
  280. padding: 2px 4px
  281. border-radius: 4px
  282. color: #304455
  283. </style>