Commit 56786c74 authored by nick zheng's avatar nick zheng

chore: 更换上传头像

parent 141244e9
<script setup lang="ts">
import { computed, ref, useSlots } from 'vue'
import CustomIcon from '../custom-icon/custom-icon.vue'
import { fetchUpload } from '@/apis/upload'
interface Emit {
(e: 'formatError'): void
(e: 'oversize'): void
(e: 'update:imageUrl', value: string): void
}
const props = defineProps({
imageUrl: {
type: String,
default: '',
},
maxImageSize: {
type: Number,
default: 1024 * 1024 * 3,
},
listType: {
type: Array,
default: () => ['jpg', 'png', 'jpeg', 'svg', 'gif'],
},
width: {
type: Number,
default: 72,
},
height: {
type: Number,
default: 72,
},
})
const emit = defineEmits<Emit>()
const slots = useSlots()
const uploadLoading = ref(false)
const isShowImageMask = ref(false)
const uploadImageUrl = computed({
get() {
return props.imageUrl
},
set(value: string) {
emit('update:imageUrl', value)
},
})
const uploadImageType = computed(() => {
return props.listType.map((typeItem) => 'image/' + typeItem).join(',')
})
console.log(uploadImageType.value)
async function handleUploadImage(event: any) {
const e = window.event || event
const file = e.target.files[0]
if (!props.listType.includes(file.type.split('/')[1])) {
emit('formatError')
return
}
if (file.size > props.maxImageSize) {
emit('oversize')
return
}
const URL = window.URL || window.webkitURL
const img = new Image()
img.src = URL.createObjectURL(file)
img.onload = async function () {
const formData = new FormData()
formData.append('file', file)
uploadLoading.value = true
const res = await fetchUpload(formData).finally(() => {
uploadLoading.value = false
event.target.value = null
})
if (res.code === 0) {
uploadImageUrl.value = res.data as string
}
}
}
</script>
<template>
<div class="relative overflow-hidden rounded-lg" :style="{ height: height + 'px', width: width + 'px' }">
<NSpin :show="uploadLoading" class="h-full w-full">
<label
class="hover:border-blue flex cursor-pointer flex-col items-center justify-center rounded-lg"
:class="uploadImageUrl ? '' : 'border border-gray-200'"
:style="{ height: height + 'px', width: width + 'px' }"
for="upload"
>
<CustomIcon v-if="!uploadLoading" class="text-lg" icon="mingcute:add-line" />
</label>
</NSpin>
<div
v-show="uploadImageUrl"
class="absolute left-0 top-0 h-full w-full"
@mouseenter="isShowImageMask = true"
@mouseleave="isShowImageMask = false"
>
<img :src="uploadImageUrl" class="h-full w-full" />
<label
v-show="isShowImageMask"
class="absolute left-0 top-0 flex h-full w-full cursor-pointer items-center justify-center bg-[#151b2680]"
for="upload"
>
<slot v-if="slots.mask" name="mask" />
<CustomIcon v-else class="text-base text-white" icon="lucide:edit" />
</label>
<input id="upload" type="file" :accept="uploadImageType" class="hidden" @change="handleUploadImage" />
</div>
</div>
</template>
<script setup lang="ts">
import { nextTick, ref, watch } from 'vue'
import type { UploadFileInfo } from 'naive-ui'
import { fetchUpload } from '@/apis/upload'
interface Emit {
(e: 'afterUpload', data: UploadFileInfo[]): void
(e: 'remove', data: number): void
}
const props = defineProps({
fileArr: {
type: Array,
default: () => {
return []
},
},
fileType: {
type: String,
default: 'image-card',
},
maxNum: {
type: Number,
default: 1,
},
listType: {
type: String,
default: '.doc,.docx,.pdf,.xls,.xlsx,.zip,.rar,.jpg,.png,.jpeg,.svg,.gif',
},
})
const emit = defineEmits<Emit>()
const fileList = ref<UploadFileInfo[]>([])
const previewImageUrl = ref('')
const uploadPhotoRef = ref()
const imageRef = ref()
const showImage = false
watch(
() => props.fileArr,
(newValue) => {
fileList.value = []
if (newValue?.length) {
newValue?.forEach((item) => {
const params = {
id: new Date().getTime().toString(),
name: new Date().getTime().toString(),
status: 'finished' as any,
url: item as string,
}
fileList.value.push(params)
})
}
},
{ deep: true, immediate: true },
)
function handleUpload(file: any) {
if (file.event) {
const formdata = new FormData()
formdata.append('file', file.file.file)
fetchUpload(formdata).then((res) => {
if (res.code === 0) {
const fileData = {
id: file.file.id,
name: file.file.name,
status: 'finished' as any,
url: (res.data as string) || null,
}
fileList.value.push(fileData)
} else {
const fileData = {
id: file.file.id as string,
name: file.file.name,
status: 'error' as any,
}
fileList.value.push(fileData)
}
fileList.value = fileList.value.filter((item) => {
return item.status !== 'pending'
})
emit('afterUpload', fileList.value)
})
} else {
const fileId = file.file.id
fileList.value = fileList.value.filter((item) => {
return item.id !== fileId
})
emit('afterUpload', fileList.value)
}
}
function handlePreview(file: UploadFileInfo) {
const { url } = file
previewImageUrl.value = url as string
nextTick(() => {
imageRef.value.click()
})
}
function handleRemove(options: { file: UploadFileInfo; fileList: UploadFileInfo[]; index: number }) {
emit('remove', options.index)
}
</script>
<template>
<NUpload
ref="uploadPhotoRef"
v-model:file-list="fileList"
:max="props.maxNum"
:list-type="props.fileType"
@change="handleUpload"
@preview="handlePreview"
@remove="handleRemove"
>
</NUpload>
<NImage
v-show="showImage"
ref="imageRef"
width="100"
:src="previewImageUrl"
:show-toolbar="false"
:preview-src="previewImageUrl"
/>
</template>
<script setup lang="ts">
import { computed, h, nextTick, onMounted, onUnmounted, reactive, ref, VNodeChild, watch } from 'vue'
import { useRouter } from 'vue-router'
import { FormInst, InputInst, SelectOption, UploadFileInfo } from 'naive-ui'
import { FormInst, InputInst, SelectOption } from 'naive-ui'
import { useThrottleFn } from '@vueuse/core'
import CustomIcon from '@/components/custom-icon/custom-icon.vue'
import UploadPhoto from '@/components/upload-photo/upload-photo.vue'
import UploadImage from '@/components/upload-image/upload-image.vue'
import AutoConfigModal from './auto-config-modal.vue'
import OptimizeSystemModal from './optimize-system-modal.vue'
import { usePersonalAppConfigStore } from '@/store/modules/personal-app-config'
......@@ -241,12 +241,8 @@ function handleSettingDefaultPrompt() {
personalAppConfig.value.baseInfo.agentSystem = defaultPrompt
}
function handleUploadAppAvatar(file: UploadFileInfo[]) {
personalAppConfig.value.baseInfo.agentAvatar = file?.[0]?.url || ''
}
function handleRemoveAppAvatar() {
personalAppConfig.value.baseInfo.agentAvatar = ''
function handleUploadAvatarOversize() {
window.$message.error('图片不能超过3MB')
}
function handleUpdateCommConfigExpandedNames(expandedNames: string[]) {
......@@ -553,11 +549,15 @@ function handleStopGenerate() {
<NCollapseItem title="基本信息" name="1" class="my-[13px]!">
<div class="justify-left flex items-start pl-5">
<div class="relative mr-2 w-[72px]">
<UploadPhoto
:file-arr="[personalAppConfig.baseInfo.agentAvatar]"
@after-upload="handleUploadAppAvatar"
@remove="handleRemoveAppAvatar"
/>
<UploadImage
v-model:image-url="personalAppConfig.baseInfo.agentAvatar"
:max-image-size="1024 * 1024 * 3"
@oversize="handleUploadAvatarOversize"
>
<template #mask>
<span class="text-xs text-white">修改头像</span>
</template>
</UploadImage>
<div
v-show="generateAgentAvatarLoading"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment