gemercheung 2 tahun lalu
induk
melakukan
5fe13f121d

+ 2 - 1
package.json

@@ -46,6 +46,7 @@
     "@typescript-eslint/eslint-plugin": "^5.36.2",
     "@typescript-eslint/parser": "^5.36.2",
     "@vitejs/plugin-vue": "^3.1.0",
+    "@vue-macros/volar": "^0.12.2",
     "chalk": "^5.0.1",
     "eslint": "^8.23.1",
     "eslint-config-prettier": "^8.5.0",
@@ -58,7 +59,7 @@
     "typescript": "^4.6.4",
     "unplugin-auto-import": "^0.11.2",
     "unplugin-vue-components": "^0.22.7",
-    "unplugin-vue-define-options": "^0.11.2",
+    "unplugin-vue-define-options": "^1.3.11",
     "vite": "^3.1.0",
     "vite-plugin-chunk-split": "^0.4.7",
     "vue-eslint-parser": "^9.1.0",

+ 2 - 0
src/api/constant.ts

@@ -19,4 +19,6 @@ export const DEL_ROOM = '/takelook/roomDelete'
 export const ROOM_ACTION_CHECKER = '/takelook/checkCanDel'
 export const GET_ROOM_LEADER_MINI_CODE = '/takelook/roomGetHostCode'
 export const GET_ROOM_MINI_CODE = '/takelook/roomGetShareCode'
+
+export const BASE_UPLOAD = '/takelook/upload/file'
 // /takelook/roomGetHostCode

+ 15 - 3
src/api/room.ts

@@ -11,6 +11,7 @@ import axios from './instance'
 import type { PageResult, Scene } from './'
 import type { SScene } from './scene'
 import type { Dayjs } from 'dayjs'
+import { head } from 'lodash-es'
 
 export type SRoom = {
   roomId: number
@@ -30,6 +31,9 @@ export type SRoom = {
   takeLookLock?: number
   userObjList?: AuthUser[]
   location?: string
+  image?: string[]
+  head?: string
+  gps?: string
 }
 
 export interface RoomScene {
@@ -58,7 +62,11 @@ export interface Room {
   isRoamMode?: boolean,
   freeRoamLock?: number
   takeLookLock?: number
-  userObjList?: AuthUser[]
+  userObjList?: AuthUser[],
+  scenesAvatar?: string
+  scenesAlbum?: string[]
+  gps?: string
+
 }
 
 export type Rooms = Room[]
@@ -76,7 +84,9 @@ const serverToLocal = (sroom: SRoom): Room => ({
   roomStatus: sroom.roomStatus,
   hostStatus: sroom.hostStatus,
   visitPassword: sroom.visitPassword,
-  userObjList: sroom.userObjList
+  userObjList: sroom.userObjList,
+  scenesAlbum: sroom.image,
+  scenesAvatar: sroom.head,
 })
 const localToServer = (room: Room): SRoom => ({
   roomId: room.id,
@@ -93,7 +103,9 @@ const localToServer = (room: Room): SRoom => ({
   visitPassword: room.visitPassword,
   takeLookLock: room.takeLookLock || 0,
   freeRoamLock: room.freeRoamLock || 0,
-  userObjList: room.userObjList
+  userObjList: room.userObjList,
+  image: room.scenesAlbum,
+  head: room.scenesAvatar
 })
 
 export const fetchRomms = async (status: number = 1): Promise<Rooms> => {

+ 39 - 0
src/components.d.ts

@@ -7,12 +7,51 @@ export {}
 
 declare module '@vue/runtime-core' {
   export interface GlobalComponents {
+    AAvatar: typeof import('ant-design-vue/es')['Avatar']
+    AButton: typeof import('ant-design-vue/es')['Button']
+    ACard: typeof import('ant-design-vue/es')['Card']
+    ACol: typeof import('ant-design-vue/es')['Col']
+    AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
+    ADrawer: typeof import('ant-design-vue/es')['Drawer']
+    ADropdown: typeof import('ant-design-vue/es')['Dropdown']
+    AEmpty: typeof import('ant-design-vue/es')['Empty']
+    AForm: typeof import('ant-design-vue/es')['Form']
+    AFormItem: typeof import('ant-design-vue/es')['FormItem']
+    AInput: typeof import('ant-design-vue/es')['Input']
+    AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
     ALayout: typeof import('ant-design-vue/es')['Layout']
     ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
+    ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader']
+    AList: typeof import('ant-design-vue/es')['List']
+    AListItem: typeof import('ant-design-vue/es')['ListItem']
+    AMenu: typeof import('ant-design-vue/es')['Menu']
+    AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
+    AModal: typeof import('ant-design-vue/es')['Modal']
+    APopover: typeof import('ant-design-vue/es')['Popover']
+    AppstoreOutlined: typeof import('@ant-design/icons-vue')['AppstoreOutlined']
+    ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
+    ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
+    ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
+    ARow: typeof import('ant-design-vue/es')['Row']
+    ATable: typeof import('ant-design-vue/es')['Table']
+    ATabPane: typeof import('ant-design-vue/es')['TabPane']
+    ATabs: typeof import('ant-design-vue/es')['Tabs']
+    ATextarea: typeof import('ant-design-vue/es')['Textarea']
+    AUpload: typeof import('ant-design-vue/es')['Upload']
+    BarChartOutlined: typeof import('@ant-design/icons-vue')['BarChartOutlined']
+    CloseOutlined: typeof import('@ant-design/icons-vue')['CloseOutlined']
     DataList: typeof import('./components/data-list/index.vue')['default']
+    DownOutlined: typeof import('@ant-design/icons-vue')['DownOutlined']
+    EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
+    InfoCircleOutlined: typeof import('@ant-design/icons-vue')['InfoCircleOutlined']
     Loading: typeof import('./components/loading/index.vue')['default']
     LocalePicker: typeof import('./components/localePicker/index.vue')['default']
+    PieChartOutlined: typeof import('@ant-design/icons-vue')['PieChartOutlined']
+    PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
+    SearchOutlined: typeof import('@ant-design/icons-vue')['SearchOutlined']
+    UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined']
+    VerticalAlignTopOutlined: typeof import('@ant-design/icons-vue')['VerticalAlignTopOutlined']
   }
 }

+ 2 - 2
src/helper/index.ts

@@ -4,7 +4,7 @@ import { genMount } from '@/shared'
 const { app } = userApp()
 export const mount = genMount(app)
 
-export const renderCompoent = <P>(comp: ComponentConstructor<P>, props: P) => {
+export const renderComponent = <P>(comp: ComponentConstructor<P>, props: P) => {
   const element = document.createElement('div')
   const { destroy } = mount(comp, { props, element })
   return () => {
@@ -26,5 +26,5 @@ export const renderModal = <P>(
     }
   } as P
 
-  const destroy = renderCompoent(comp, props)
+  const destroy = renderComponent(comp, props)
 }

+ 223 - 0
src/views/room/edit-room/album-list.vue

@@ -0,0 +1,223 @@
+<template>
+  <a-list :grid="{ gutter: 20, column: 3 }" :data-source="current">
+    <template #renderItem="{ item }: { item: FileItem | typeof addMarked }">
+      <a-list-item class="scene-item">
+        <div v-if="item === addMarked" class="add-album">
+          <a-upload
+            v-model:file-list="albumFile"
+            name="file"
+            :show-upload-list="false"
+            action="https://v4-test.4dkankan.com/takelook/upload/file"
+            :multiple="true"
+            :before-upload="handleBeforeUpload"
+            @change="handleABlumChange"
+          >
+            <div class="add-item-icon">
+              <a-button shape="circle" class="button" type="primary">
+                <plus-outlined class="add-room-icon" />
+              </a-button>
+            </div>
+          </a-upload>
+        </div>
+
+        <div v-else class="scene-sign">
+          <img v-if="item.response" :src="item.response?.data" />
+          <span class="delete-scene" @click="deleteAblum(item)">
+            <close-outlined class="delete-scene-icon" />
+          </span>
+        </div>
+      </a-list-item>
+    </template>
+  </a-list>
+</template>
+
+<script lang="ts" setup>
+import { computed, ref, watch, unref } from 'vue'
+import { Modal, message } from 'ant-design-vue'
+import type { UploadChangeParam } from 'ant-design-vue'
+import { useI18n } from '@/hook/useI18n'
+import { watchEffect } from 'vue'
+import { uniqBy } from 'lodash-es'
+
+export interface FileItem {
+  uid: string
+  response:
+    | {
+        ok?: number
+        data: string
+      }
+    | undefined
+  name?: string
+  status?: string
+  url?: string
+  type?: string
+  size?: number
+  originFileObj?: any
+}
+
+const { t } = useI18n()
+
+defineOptions<{ name: 'RoomSceneList' }>()
+const props = defineProps<{ data: string[] }>()
+
+const addMarked = Symbol('add-album')
+const albumFile = ref<any[]>([])
+
+const current = computed(() => [addMarked, ...albumFile.value])
+const albumList = computed(() =>
+  Array.from(albumFile.value).reduce((prev, cur) => {
+    if (prev && cur.response?.data) {
+      return prev.concat(cur.response.data)
+    }
+  }, [])
+)
+
+const deleteAblum = (item: FileItem) => {
+  const index = albumFile.value.findIndex(i => i.uid === item.uid)
+
+  if (index > -1) {
+    albumFile.value.splice(index, 1)
+  }
+  const syncData = albumList.value ? albumList.value : []
+  console.log('sync', syncData)
+  emit('syncList', syncData)
+}
+const emit = defineEmits(['syncList'])
+watchEffect(() => {
+  if (props.data?.length) {
+    const mapper = Array.from(props.data).map((i, index) => {
+      const tempData = {} as FileItem
+      tempData.uid = `data-${index}`
+      tempData.response = {
+        data: i,
+        ok: 0
+      }
+      return tempData
+    })
+
+    albumFile.value = uniqBy(albumFile.value.concat(mapper), 'response.data')
+  }
+})
+
+const handleABlumChange = (info: UploadChangeParam) => {
+  if (info.file.status === 'done') {
+    const syncData = albumList.value ? albumList.value : []
+    console.log('sync', syncData)
+    emit('syncList', syncData)
+  } else if (info.file.status === 'error') {
+    message.error(`${info.file.name} file upload failed.`)
+  }
+}
+const handleBeforeUpload = (file: any) => {
+  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
+  if (!isJpgOrPng) {
+    message.error('You can only upload JPG file!')
+  }
+  const isLt5M = file.size / 1024 / 1024 < 5
+  if (!isLt5M) {
+    message.error('Image must smaller than 5MB!')
+  }
+  return isJpgOrPng && isLt5M
+}
+</script>
+
+<style lang="scss" scoped>
+.add-album {
+  border: 1px solid #ebedf0;
+  border-radius: 4px;
+  height: 100%;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  .button {
+    width: 40px;
+    height: 40px;
+    line-height: 34px;
+    background: linear-gradient(144deg, #00aefb 0%, #0076f6 100%);
+  }
+
+  .add-room-icon {
+    font-size: 18px;
+  }
+}
+
+.scene-sign {
+  height: 100%;
+  border-radius: 4px;
+  overflow: hidden;
+  position: relative;
+  img {
+    width: 100%;
+    height: 100%;
+    display: block;
+    object-fit: cover;
+  }
+  .title {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 24px;
+    background: rgba(0, 0, 0, 0.5);
+    padding: 5px;
+    font-size: 12px;
+    color: #fff;
+    margin: 0;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .delete-scene {
+    z-index: 2;
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 52px;
+    height: 52px;
+    background-color: rgba(0, 0, 0, 0.5);
+    color: #fa5555;
+    font-size: 14px;
+    border-radius: 50%;
+    display: flex;
+    align-items: flex-end;
+    transform: translate(100%, -100%);
+    transition: all 0.3s ease;
+    opacity: 0;
+    cursor: pointer;
+
+    .delete-scene-icon {
+      padding: 10px;
+    }
+  }
+
+  &:hover .delete-scene {
+    transform: translate(50%, -50%);
+    opacity: 1;
+  }
+  .status-cover {
+    z-index: 1;
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.5);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    p {
+      color: #fff;
+    }
+  }
+}
+</style>
+
+<style>
+.scene-item {
+  height: 120px;
+}
+</style>

+ 167 - 0
src/views/room/edit-room/avatar.vue

@@ -0,0 +1,167 @@
+<template>
+  <a-upload
+    v-model:file-list="avatarFile"
+    name="file"
+    :show-upload-list="false"
+    action="https://v4-test.4dkankan.com/takelook/upload/file"
+    :max-count="1"
+    class="uploader"
+    :headers="{
+      authorization: 'authorization-text'
+    }"
+    :disabled="avatarFile.length > 0"
+    @change="handleAvatarChange"
+  >
+    <div
+      class="add-item-icon scene-sign"
+      v-if="avatarFile.length > 0 && avatarFile[0].response"
+    >
+      <img class="avatar" :src="avatarFile[0].response.data" alt="avatar" />
+      <span class="delete-scene" @click="deleteAvatar(avatarFile[0])">
+        <close-outlined class="delete-scene-icon" />
+      </span>
+    </div>
+    <div class="add-item-icon" v-else>
+      <a-button shape="circle" class="button" type="primary">
+        <plus-outlined class="add-room-icon" />
+      </a-button>
+    </div>
+  </a-upload>
+</template>
+<script lang="ts" setup>
+import { ref } from 'vue'
+import { message, type UploadChangeParam } from 'ant-design-vue'
+import type { FileItem } from './album-list.vue'
+
+import { watchEffect } from 'vue'
+const emit = defineEmits(['sync'])
+const avatarFile = ref<any[]>([])
+const props = defineProps<{ data: string | undefined }>()
+
+watchEffect(() => {
+  if (props.data?.length) {
+    const tempData = {} as FileItem
+    tempData.uid = `data-0`
+    tempData.response = {
+      data: props.data,
+      ok: 0
+    }
+    if (!avatarFile.value?.length) {
+      console.log('mapper', tempData)
+      avatarFile.value = [tempData]
+    }
+  } else {
+    avatarFile.value = []
+  }
+})
+
+const handleAvatarChange = (info: UploadChangeParam) => {
+  if (info.file.status === 'done') {
+    const { code, data } = info.file.response
+    if (code === 0) {
+      emit('sync', data || '')
+    }
+  } else if (info.file.status === 'error') {
+    message.error(`${info.file.name} file upload failed.`)
+  }
+}
+const deleteAvatar = (item: any) => {
+  const index = avatarFile.value.findIndex(i => i.uid === item.uid)
+  if (index > -1) {
+    avatarFile.value.splice(index, 1)
+  }
+  emit('sync', '')
+}
+</script>
+
+<style lang="scss" scoped>
+.add-item-icon {
+  width: 120px;
+  height: 120px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border: 1px solid #ebedf0;
+  overflow: hidden;
+  .avatar {
+    max-width: 100%;
+    // border-radius: 50%;
+  }
+  .button {
+    background: linear-gradient(144deg, #00aefb 0%, #0076f6 100%);
+    width: 40px;
+    height: 40px;
+  }
+}
+.scene-sign {
+  border-radius: 4px;
+  overflow: hidden;
+  position: relative;
+  z-index: 10;
+  img {
+    width: 100%;
+    height: 100%;
+    display: block;
+    object-fit: cover;
+  }
+  .title {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 24px;
+    background: rgba(0, 0, 0, 0.5);
+    padding: 5px;
+    font-size: 12px;
+    color: #fff;
+    margin: 0;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .delete-scene {
+    z-index: 2;
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 52px;
+    height: 52px;
+    background-color: rgba(0, 0, 0, 0.5);
+    color: #fa5555;
+    font-size: 14px;
+    border-radius: 50%;
+    display: flex;
+    align-items: flex-end;
+    transform: translate(100%, -100%);
+    transition: all 0.3s ease;
+    opacity: 0;
+    cursor: pointer;
+
+    .delete-scene-icon {
+      padding: 10px;
+    }
+  }
+
+  &:hover .delete-scene {
+    transform: translate(50%, -50%);
+    opacity: 1;
+  }
+  .status-cover {
+    z-index: 1;
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.5);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    p {
+      color: #fff;
+    }
+  }
+}
+</style>

+ 126 - 71
src/views/room/edit-room/index.vue

@@ -86,6 +86,7 @@
             <div style="margin: 10px 0"></div>
             <div ref="mapRef" style="width: 100%; height: 194px"></div>
           </a-form-item>
+
           <a-form-item :label="t('room.form.desc')" name="desc">
             <a-textarea
               v-model:value="current.desc"
@@ -96,6 +97,7 @@
             />
           </a-form-item>
           <!-- <h4>{{ t('room.form.host') }}</h4> -->
+
           <a-form-item
             :label="t('room.form.nickname')"
             name="leaderName"
@@ -118,23 +120,16 @@
             name="title"
             :rules="[{ required: true, message: '' }]"
           >
-            <a-upload
-              v-model:file-list="avatarFile"
-              name="file"
-              action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
-              :headers="{
-                authorization: 'authorization-text'
-              }"
-              @change="handleAvatarChange"
-            >
-              <div class="add-item-icon">
-                <a-button shape="circle" class="button" type="primary">
-                  <plus-outlined class="add-room-icon" />
-                </a-button>
-              </div>
-            </a-upload>
+            <EditAvatar :data="current.scenesAvatar" @sync="handleAvatarSync" />
+          </a-form-item>
+          <!-- 相册 -->
+          <a-form-item label="相册" name="title">
+            <EditAlbum
+              :data="current.scenesAlbum || []"
+              @sync-list="handleAlbumSync"
+            />
           </a-form-item>
-          <!-- <h4>{{ t('room.form.selectScene') }}</h4> -->
+
           <a-form-item
             :label="t('room.form.addScene')"
             class="select-scene"
@@ -142,6 +137,7 @@
             style="margin-bottom: 2px"
           >
           </a-form-item>
+
           <EditScenes
             :class="{ disabled: isRoomEnd }"
             :scenes="current.scenes"
@@ -308,6 +304,8 @@ import { props } from './props'
 import { message, Modal } from 'ant-design-vue'
 import { mainURL } from '@/env'
 import EditScenes from './scene-list.vue'
+import EditAlbum from './album-list.vue'
+import EditAvatar from './avatar.vue'
 import unScenePng from '@/assets/images/un-scene.png'
 import VOtpInput from 'vue3-otp-input'
 import type { Scene } from '@/store/modules/scene'
@@ -321,6 +319,7 @@ import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
 import { useScript } from '@/hook/useScript'
 import { onMounted } from 'vue'
 import type { UploadChangeParam } from 'ant-design-vue'
+import { watchEffect } from 'vue'
 
 dayjs.extend(duration)
 // const titleValidator = ref({
@@ -337,7 +336,7 @@ interface AuthUserFormState {
 
 export default defineComponent({
   name: 'EditRoom',
-  components: { EditScenes, VOtpInput },
+  components: { EditScenes, VOtpInput, EditAlbum, EditAvatar },
   props,
   setup(props) {
     const visible = ref(true)
@@ -345,7 +344,6 @@ export default defineComponent({
     const mapRef = ref<HTMLDivElement | null>(null)
     const authformState: UnwrapRef<AuthUserFormState> = reactive({
       userName: ''
-      // useTimeList: []
     })
     const { getAntdLocale } = useLocale()
     const roomStore = useRoomStore()
@@ -353,7 +351,7 @@ export default defineComponent({
     const { getLocale } = useLocale()
     const { t } = useI18n()
 
-    const avatarFile = ref([])
+    const avatarFile = ref<any[]>([])
 
     const returnLocale = computed(() => {
       if (unref(getLocale).includes('zh')) {
@@ -365,6 +363,7 @@ export default defineComponent({
     const otpInput = ref('')
     const formRef = ref<FormInstance>()
     const current = reactive(createRoom(props.room || {}))
+    // current.scenesAlbum = []
     if (current.useTimeList?.length) {
       current.useTimeList = current.useTimeList?.map(i => dayjs(i))
     }
@@ -499,25 +498,49 @@ export default defineComponent({
     const onCancel = () => {
       visible.value = false
     }
+    ;(window as any)._AMapSecurityConfig = {
+      securityJsCode: 'cbac8ddaf1e7346784b24f10cae245a3'
+    }
     const A_MAP_URL =
-      'https://webapi.amap.com/maps?v=2.0&key=e661b00bdf2c44cccf71ef6070ef41b8'
+      'https://webapi.amap.com/maps?v=2.0&key=5a2d384532ae531bf99bd8487c4f03d2'
+    const UI = 'https://webapi.amap.com/ui/1.0/main.js?v=1.0.11'
+    // const { toPromise: toUIPromise } = useScript({ src: UI })
     const { toPromise } = useScript({ src: A_MAP_URL })
 
     const initMap = async () => {
       await toPromise()
+      // await toUIPromise();
+
       console.log('mapRef', unref(mapRef))
       const AMap = (window as any).AMap
-      console.log('AMap', AMap)
-      // const center = [120.262337, 30.178285]
+      // console.log('AMap', AMap)
+      // ** 有数据时默认位置
+      // const center = [113.549574, 22.215372]
+
+      // var icon = new AMap.Icon({
+      //   size: new AMap.Size(40, 50), // 图标尺寸
+      //   image: '//webapi.amap.com/theme/v1.3/images/newpc/way_btn2.png', // Icon的图像
+      //   imageOffset: new AMap.Pixel(0, -60), // 图像相对展示区域的偏移量,适于雪碧图等
+      //   imageSize: new AMap.Size(40, 50) // 根据所设置的大小拉伸或压缩图片
+      // })
+      var marker = new AMap.Marker({
+        position: new AMap.LngLat(113.549574, 22.215372),
+        title: current.location,
+        zoom: 13
+      })
+
       const map = new AMap.Map(unref(mapRef), {
         zoom: 15,
         resizeEnable: true
-        // center: center,
+        // center: center
+        // resizeEnable: true
         // viewMode: '3D',
-        // resizeEnable: true,
+        // resizeEnable: true
         // floorControl: true,
         // showIndoorMap: true
       })
+      map.add(marker)
+
       AMap.plugin(
         [
           'AMap.Scale',
@@ -529,44 +552,50 @@ export default defineComponent({
         ],
         function () {
           const autoOptions = {
-            city: '珠海',
+            // city: '珠海',
             input: 'location'
           }
           const autocomplete = new AMap.Autocomplete(autoOptions)
           const placeSearch = new AMap.PlaceSearch({
-            city: '珠海', // 默认城市,一定要有,不然没有放大效果
+            // city: '珠海', // 默认城市,一定要有,不然没有放大效果
             map: map // 地图,选中会有放大功能,绑定上面创建的地图即可
           })
           AMap.Event.addListener(autocomplete, 'select', function (e: any) {
             placeSearch.search(e.poi.name)
-            console.log('location', e.poi.location) // 获取选中的的地址的经纬度
-          })
-          var geolocation = new AMap.Geolocation({
-              // 是否使用高精度定位,默认:true
-              enableHighAccuracy: true,
-              // 设置定位超时时间,默认:无穷大
-              timeout: 10000,
-              // 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
-              buttonOffset: new AMap.Pixel(10, 20),
-              //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
-              zoomToAccuracy: true,
-              //  定位按钮的排放位置,  RB表示右下
-              buttonPosition: 'RB'
-            })
-
-            geolocation.getCurrentPosition()
-            AMap.Event.addListener(geolocation, 'complete', onComplete)
-            AMap.Event.addListener(geolocation, 'error', onError)
-
-            function onComplete(data: any) {
-              console.log('data', data)
-              // data是具体的定位信息
-            }
-
-            function onError(data: any) {
-              console.log('data', data)
-              // 定位出错
+            // console.log('location', e.poi.location) // 获取选中的的地址的经纬度
+            console.log('select', e.poi) // 获取选中的的地址的经纬度
+            if (e.poi.name) {
+              current.location = e.poi.name
             }
+          })
+          AMap.Event.addListener(autocomplete, 'click', function (e: any) {
+            console.log('click', e)
+          })
+          // var geolocation = new AMap.Geolocation({
+          //   // 是否使用高精度定位,默认:true
+          //   enableHighAccuracy: true,
+          //   // 设置定位超时时间,默认:无穷大
+          //   timeout: 10000,
+          //   // 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
+          //   buttonOffset: new AMap.Pixel(10, 20),
+          //   //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
+          //   zoomToAccuracy: true,
+          //   //  定位按钮的排放位置,  RB表示右下
+          //   buttonPosition: 'RB'
+          // })
+
+          // geolocation.getCurrentPosition()
+          // AMap.Event.addListener(geolocation, 'complete', onComplete)
+          // AMap.Event.addListener(geolocation, 'error', onError)
+
+          // function onComplete(data: any) {
+          //   console.log('onComplete-data', data)
+          // }
+
+          function onError(data: any) {
+            console.log('onError-data', data)
+            // 定位出错
+          }
         }
       )
     }
@@ -576,16 +605,32 @@ export default defineComponent({
     })
 
     const handleAvatarChange = (info: UploadChangeParam) => {
-      if (info.file.status !== 'uploading') {
-        console.log(info.file, info.fileList)
-      }
+      // if (info.file.status !== 'uploading') {
+      //   console.log(info.file, info.fileList)
+      // }
       if (info.file.status === 'done') {
-        message.success(`${info.file.name} file uploaded successfully`)
+        console.log('info.file', info.file)
+        if (info.file.response) {
+          const { code, data } = info.file.response
+          if (code === 0) {
+            current.scenesAvatar = data
+          }
+        }
+        // message.success(`${info.file.name} file uploaded successfully`)
       } else if (info.file.status === 'error') {
         message.error(`${info.file.name} file upload failed.`)
       }
     }
 
+    const handleAlbumSync = (list: any[]) => {
+      current.scenesAlbum = list
+      // console.log('handleAlbumSync', list)
+    }
+    const handleAvatarSync = (avatarURL: string) => {
+      console.log('avatarURL', avatarURL)
+      current.scenesAvatar = avatarURL
+    }
+
     return {
       handleNickRegex,
       returnLocale,
@@ -615,7 +660,9 @@ export default defineComponent({
       onCancel,
       mapRef,
       avatarFile,
-      handleAvatarChange
+      handleAvatarChange,
+      handleAlbumSync,
+      handleAvatarSync
     }
   }
 })
@@ -782,17 +829,25 @@ export default defineComponent({
     margin: 0;
   }
 }
-.add-item-icon {
-  width: 120px;
-  height: 120px;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  border: 1px solid #ebedf0;
-  .button {
-    background: linear-gradient(144deg, #00aefb 0%, #0076f6 100%);
-    width: 40px;
-    height: 40px;
-  }
-}
+
+// .album-list {
+//   .album-list-item {
+//     .list-item {
+//       width: 100%;
+//       height: 100%;
+//       overflow: hidden;
+//       display: flex;
+//       justify-content: center;
+//       align-items: center;
+//       height: 120px;
+//       overflow: hidden;
+//       img {
+//         max-width: 100%;
+//         // height: 100%;
+//         display: block;
+//         object-fit: cover;
+//       }
+//     }
+//   }
+// }
 </style>

+ 8 - 1
tsconfig.json

@@ -32,5 +32,12 @@
     "src/**/*.vue",
     "types/**/*.ts"
   ],
-  "references": [{ "path": "./tsconfig.node.json" }]
+  "references": [{ "path": "./tsconfig.node.json" }],
+  "vueCompilerOptions": {
+    "target": 3, // or 2.7 for Vue 2
+    "plugins": [
+      "@vue-macros/volar/define-options"
+      // ...more feature
+    ]
+  }
 }

File diff ditekan karena terlalu besar
+ 2712 - 0
yarn.lock