90 lines
2.0 KiB
Vue
90 lines
2.0 KiB
Vue
<template>
|
|
<div class="package-photo-field">
|
|
<photo-scroller
|
|
v-model="photoUrlList"
|
|
v-model:photo-items="photoItems"
|
|
:title="title"
|
|
:required="required"
|
|
:loading="isUploading"
|
|
:edit-mode="true"
|
|
@add="openFilePicker"
|
|
/>
|
|
<input ref="fileInput" class="file-input" type="file" accept="image/*" multiple @change="handleFileChange" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { AttachmentAPI } from "timi-web-api";
|
|
import PhotoScroller from "@/components/PhotoScroller.vue";
|
|
import type { PhotoItem } from "@/types/Photo";
|
|
import { compressUploadImageList } from "@/utils/imageCompression";
|
|
import { Message } from "@/utils/message";
|
|
|
|
interface Props {
|
|
required?: boolean;
|
|
title?: string;
|
|
}
|
|
|
|
withDefaults(defineProps<Props>(), {
|
|
required: false,
|
|
title: "业务照片"
|
|
});
|
|
|
|
defineOptions({
|
|
name: "PackagePhotoField"
|
|
});
|
|
|
|
const photoItems = defineModel<PhotoItem[]>({ required: true });
|
|
const fileInput = ref<HTMLInputElement>();
|
|
const isUploading = ref(false);
|
|
const photoUrlList = computed<string[]>({
|
|
get: () => photoItems.value.map(item => item.url),
|
|
set: value => {
|
|
const urlSet = new Set(value);
|
|
photoItems.value = photoItems.value.filter(item => urlSet.has(item.url));
|
|
}
|
|
});
|
|
|
|
function openFilePicker(): void {
|
|
fileInput.value?.click();
|
|
}
|
|
|
|
async function handleFileChange(event: Event): Promise<void> {
|
|
const input = event.target as HTMLInputElement;
|
|
const fileList = Array.from(input.files || []);
|
|
if (!fileList.length) {
|
|
return;
|
|
}
|
|
|
|
isUploading.value = true;
|
|
try {
|
|
const tempFileList = await AttachmentAPI.upload(await compressUploadImageList(fileList));
|
|
for (const tempFile of tempFileList) {
|
|
if (!tempFile.id) {
|
|
continue;
|
|
}
|
|
photoItems.value.push({
|
|
tempFileId: tempFile.id,
|
|
attachType: "PHOTO",
|
|
url: AttachmentAPI.getTempReadURL(tempFile.id)
|
|
});
|
|
}
|
|
} catch {
|
|
Message.error("照片上传失败");
|
|
} finally {
|
|
isUploading.value = false;
|
|
input.value = "";
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.package-photo-field {
|
|
width: 100%;
|
|
|
|
.file-input {
|
|
display: none;
|
|
}
|
|
}
|
|
</style>
|