gemercheung 1 vuosi sitten
vanhempi
commit
e64604d0ea

+ 1 - 0
package.json

@@ -39,6 +39,7 @@
     "sass": "^1.54.9",
     "vue": "3.3.13",
     "vue-i18n": "^9.2.2",
+    "vue-image-crop-upload": "^3.0.3",
     "vue-router": "4",
     "vue3-autocounter": "^1.0.6",
     "vue3-otp-input": "0.4.2"

+ 26 - 0
pnpm-lock.yaml

@@ -56,6 +56,9 @@ dependencies:
   vue-i18n:
     specifier: ^9.2.2
     version: 9.2.2(vue@3.3.13)
+  vue-image-crop-upload:
+    specifier: ^3.0.3
+    version: 3.0.3
   vue-router:
     specifier: '4'
     version: 4.1.6(vue@3.3.13)
@@ -1310,6 +1313,13 @@ packages:
       - debug
     dev: false
 
+  /babel-runtime@6.26.0:
+    resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==}
+    dependencies:
+      core-js: 2.6.12
+      regenerator-runtime: 0.11.1
+    dev: false
+
   /balanced-match@1.0.2:
     resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
     dev: true
@@ -1448,6 +1458,12 @@ packages:
     dependencies:
       is-what: 3.14.1
 
+  /core-js@2.6.12:
+    resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==}
+    deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
+    requiresBuild: true
+    dev: false
+
   /core-js@3.26.0:
     resolution: {integrity: sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==}
     requiresBuild: true
@@ -2978,6 +2994,10 @@ packages:
     dependencies:
       picomatch: 2.3.1
 
+  /regenerator-runtime@0.11.1:
+    resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==}
+    dev: false
+
   /regenerator-runtime@0.13.10:
     resolution: {integrity: sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==}
     dev: false
@@ -3529,6 +3549,12 @@ packages:
       vue: 3.3.13(typescript@4.8.4)
     dev: false
 
+  /vue-image-crop-upload@3.0.3:
+    resolution: {integrity: sha512-VeBsU0oI1hXeCvdpnu19DM/r3KTlI8SUXTxsHsU4MhDXR0ahRziiL9tf4FbILGx+gRVNZhGbl32yuM6TiaGNhA==}
+    dependencies:
+      babel-runtime: 6.26.0
+    dev: false
+
   /vue-router@4.1.6(vue@3.3.13):
     resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==}
     peerDependencies:

+ 66 - 65
src/views/room/edit-room/avatar.vue

@@ -1,95 +1,85 @@
 <template>
-  <a-upload
-    v-model:file-list="avatarFile"
-    name="file"
-    accept=".png,.jpg,.jpeg"
-    :show-upload-list="false"
-    :action="baseURL + '/takelook/upload/file'"
-    :max-count="1"
-    class="uploader"
-    :headers="{
-      authorization: 'authorization-text'
-    }"
-    :disabled="avatarFile.length > 0"
-    @change="handleAvatarChange"
-    :before-upload="handleAvatarBeforeUpload"
-  >
-    <div
-      class="add-item-icon scene-sign"
-      v-if="avatarFile.length > 0 && avatarFile[0].response"
-    >
-      <a-image class="avatar" :src="avatarFile[0].response.data" alt="avatar" />
-      <span class="delete-scene" @click="deleteAvatar(avatarFile[0])">
+  <div class="uploader">
+    <div class="add-item-icon scene-sign" v-if="avatarImage">
+      <a-image class="avatar" :src="avatarImage" alt="avatar" />
+      <span class="delete-scene" @click="deleteAvatar">
         <close-outlined class="delete-scene-icon" />
       </span>
     </div>
     <div class="add-item-icon" v-else>
-      <a-button shape="circle" class="button" type="primary">
+      <a-button
+        shape="circle"
+        class="button"
+        type="primary"
+        @click="showAvatarUploader"
+      >
         <plus-outlined class="add-room-icon" />
       </a-button>
     </div>
-  </a-upload>
+
+    <my-upload
+      field="file"
+      name="file"
+      img-format=".png,.jpg,.jpeg"
+      :url="baseURL + '/takelook/upload/file'"
+      :headers="{
+        authorization: 'authorization-text'
+      }"
+      :disabled="file.length > 0"
+      :lang-type="getLocale"
+      v-model="isShowAvatarModel"
+      @crop-upload-success="handleAvatarUpload"
+      @crop-success="cropSuccess"
+    >
+    </my-upload>
+  </div>
 </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 { baseURL } from '@/env'
 import { watchEffect } from 'vue'
+import myUpload from 'vue-image-crop-upload'
 import { useI18n } from '@/hook/useI18n'
+import { useLocale } from '@/locales/useLocale'
+
 const emit = defineEmits(['sync'])
-const avatarFile = ref<any[]>([])
+const file = ref<any[]>([])
+const avatarImage = ref('')
 const props = defineProps<{ value: string | undefined }>()
 const { t } = useI18n()
+const isShowAvatarModel = ref(false)
+const { getLocale } = useLocale()
 
 watchEffect(() => {
   if (props.value?.length) {
-    const tempData = {} as FileItem
-    tempData.uid = `data-0`
-    tempData.response = {
-      data: props.value,
-      ok: 0
-    }
-    if (!avatarFile.value?.length) {
-      console.log('mapper', tempData)
-      avatarFile.value = [tempData]
-    }
-  } else {
-    avatarFile.value = []
+    debugger
   }
 })
 
-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 handleAvatarUpload = (res: any) => {
+  const { data } = res
+  console.log('avatarImage', data)
+  avatarImage.value = data
+  // setTimeout(() => {
+  //   isShowAvatarModel.value = false
+  // }, 1500)
 }
-const deleteAvatar = (item: any) => {
-  const index = avatarFile.value.findIndex(i => i.uid === item.uid)
-  if (index > -1) {
-    avatarFile.value.splice(index, 1)
-  }
-  emit('sync', '')
+const cropSuccess = (res: any) => {
+
 }
-const handleAvatarBeforeUpload = (file: File) => {
-  const max = file.size / 1024 / 1024 <= 1
-  if (!max) {
-    message.error(t('room.oneMPicLimit'))
-    // debugger;
-    setTimeout(() => {
-      avatarFile.value = []
-    }, 50)
-    return false
-  } else {
-    return true
-  }
+const cropUploadFail = (res: any) => {
+  console.log('cropUploadFail', res)
+}
+
+const showAvatarUploader = () => {
+  isShowAvatarModel.value = true
+  console.log('show')
+}
+const deleteAvatar = () => {
+  avatarImage.value = ''
 }
 </script>
+<style lang="scss"></style>
 
 <style lang="scss" scoped>
 .add-item-icon {
@@ -181,4 +171,15 @@ const handleAvatarBeforeUpload = (file: File) => {
     }
   }
 }
+
+// .vue-image-crop-upload {
+//   .vicp-wrap .vicp-operate {
+//     color: #0076f6 !important;
+//   }
+// }
+</style>
+<style>
+.vue-image-crop-upload .vicp-wrap .vicp-operate a {
+  color: #0076f6;
+}
 </style>

+ 184 - 0
src/views/room/edit-room/avatar.vue.bk

@@ -0,0 +1,184 @@
+<template>
+  <a-upload
+    v-model:file-list="avatarFile"
+    name="file"
+    accept=".png,.jpg,.jpeg"
+    :show-upload-list="false"
+    :action="baseURL + '/takelook/upload/file'"
+    :max-count="1"
+    class="uploader"
+    :headers="{
+      authorization: 'authorization-text'
+    }"
+    :disabled="avatarFile.length > 0"
+    @change="handleAvatarChange"
+    :before-upload="handleAvatarBeforeUpload"
+  >
+    <div
+      class="add-item-icon scene-sign"
+      v-if="avatarFile.length > 0 && avatarFile[0].response"
+    >
+      <a-image 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 { baseURL } from '@/env'
+import { watchEffect } from 'vue'
+import { useI18n } from '@/hook/useI18n'
+const emit = defineEmits(['sync'])
+const avatarFile = ref<any[]>([])
+const props = defineProps<{ value: string | undefined }>()
+const { t } = useI18n()
+
+watchEffect(() => {
+  if (props.value?.length) {
+    const tempData = {} as FileItem
+    tempData.uid = `data-0`
+    tempData.response = {
+      data: props.value,
+      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', '')
+}
+const handleAvatarBeforeUpload = (file: File) => {
+  const max = file.size / 1024 / 1024 <= 1
+  if (!max) {
+    message.error(t('room.oneMPicLimit'))
+    // debugger;
+    setTimeout(() => {
+      avatarFile.value = []
+    }, 50)
+    return false
+  } else {
+    return true
+  }
+}
+</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>

+ 3 - 2
src/views/room/edit-room/index.vue

@@ -45,14 +45,14 @@
       </a-button> -->
       </template>
       <div class="edit-room-layout">
-        <div class="scene">
+        <!-- <div class="scene">
           <iframe
             v-if="current.scenes.length"
             :src="`${mainURL}/smg.html?m=${current.scenes[0].num}&mobile=true&lang=${returnLocale}`"
             frameborder="0"
           />
           <img v-else :src="unScenePng" />
-        </div>
+        </div> -->
         <a-form
           ref="formRef"
           class="info"
@@ -365,6 +365,7 @@ import { addAuthUser, checkRoomEditOrDel } from '@/api'
 import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
 import { useScript } from '@/hook/useScript'
 import type { UploadChangeParam } from 'ant-design-vue'
+
 import {
   watchEffect,
   getCurrentInstance,

+ 1 - 1
tsconfig.json

@@ -31,7 +31,7 @@
     "src/**/*.tsx",
     "src/**/*.vue",
     "types/**/*.ts"
-  ],
+, "src/views/room/edit-room/avatar.vue.bk"  ],
   "references": [{ "path": "./tsconfig.node.json" }],
   "vueCompilerOptions": {
     "target": 3, // or 2.7 for Vue 2