Last active
February 29, 2024 21:32
-
-
Save dansp89/e6b0105a03edf24d97b4a1d2d864ed03 to your computer and use it in GitHub Desktop.
Revisions
-
dansp89 revised this gist
Feb 29, 2024 . 1 changed file with 44 additions and 38 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -39,7 +39,14 @@ /** * @source Basic Usage <https://element-plus.org/en-US/component/upload.html#photo-wall> */ import { defineComponent, ref, watchEffect, watch, type PropType, onMounted } from "vue"; import { ElMessage, ElMessageBox } from "element-plus"; import type { UploadProps, UploadUserFile } from "element-plus"; import { UploadFilled } from "@element-plus/icons-vue"; @@ -109,8 +116,8 @@ export default defineComponent({ const fileList = ref<UploadUserFile[]>([]); const dialogImageUrl = ref(""); const dialogVisible = ref(false); const imageUrls = ref([]); const valor = ref(props.modelValue) as any; const instructions = ref(""); const uploadFileId = ref(); @@ -123,6 +130,32 @@ export default defineComponent({ } }; const loadImageById = async (ids: Array<number | string>) => { // Reset imageUrls array imageUrls.value = []; const IDs = JSON.parse(JSON.stringify(ids)); console.log("[loadImageById]::", IDs); // Loop through each id and fetch its URL for (const id of IDs) { try { const { data } = await ApiService.get(`/upload/files/${id}`); const response = data; // Assuming the response has a data object with a url property // console.log("[loadImageById]::response", valor.value); if (response.data && response.data.url) { imageUrls.value.push( import.meta.env.VITE_APP_API_URL.replace("/api", "") + response.data.url ); } } catch (error) { console.error("Error loading image with id:", id, error); } } valor.value = IDs; }; watchEffect(() => { if (props.accept === "*") { instructions.value = `Permitido ${props.limit} arquivo de todos os formatos, até ${props.limitSize}mb`; @@ -143,12 +176,6 @@ export default defineComponent({ ); }; watch( () => props.modelValue, (newValue, oldValue) => { @@ -162,37 +189,11 @@ export default defineComponent({ emit("update:modelValue", newValue); emit("change", newValue); emit("input", newValue); loadImageById(newValue as any[]); }, { deep: true, immediate: true } ); // { deep: true } para observação profunda, { immediate: true } para rodar na inicialização const beforeRemove: UploadProps["beforeRemove"] = ( uploadFile, uploadFiles @@ -270,7 +271,7 @@ export default defineComponent({ }) .filter(Boolean); console.log("[handleDragSuccess]::\n", response, uploadFile, filesIds); const ext = uploadFile.raw.type.split("/")[1]; console.log("EXT FILE::", ext); if (uploadFile.raw.type.includes("image")) { @@ -327,6 +328,10 @@ export default defineComponent({ return true; }; onMounted(() => { return loadImageById(valor.value); }); const updateValue = () => { emit("update:modelValue", valor.value); }; @@ -348,7 +353,8 @@ export default defineComponent({ handleDragCardPreview, handleDragSuccess, beforeDragUpload, loadImageById, imageUrls }; } }); -
dansp89 revised this gist
Feb 29, 2024 . 1 changed file with 52 additions and 17 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -143,6 +143,56 @@ export default defineComponent({ ); }; watch(valor, (newValue) => { emit("update:modelValue", newValue); emit("change", newValue); emit("input", newValue); }); watch( () => props.modelValue, (newValue, oldValue) => { console.log("modelValue alterado:", newValue); valor.value = newValue; // Para imprimir as diferenças entre os valores antigo e novo console.log("Valores antigos:", oldValue); console.log("Novos valores:", newValue); emit("update:modelValue", newValue); emit("change", newValue); emit("input", newValue); }, { deep: true, immediate: true } ); // { deep: true } para observação profunda, { immediate: true } para rodar na inicialização watch( () => props.modelValue, (newValue) => { emit("update:modelValue", newValue); emit("change", newValue); emit("input", newValue); }, { deep: true } ); const loadImageById = async (id: number | string) => { ApiService.setHeader(); // Configura o cabeçalho, se necessário try { const response = await ApiService.get(`/upload/files/${id}`); if (response.data && response.data.url) { imageUrl.value = import.meta.env.VITE_APP_API_URL.replace("/api", "") + response.data.url; } else { throw new Error("Imagem não encontrada"); } } catch (error) { ElMessage.error("Erro ao carregar a imagem"); console.error(error); } }; const beforeRemove: UploadProps["beforeRemove"] = ( uploadFile, uploadFiles @@ -245,18 +295,6 @@ export default defineComponent({ }; const beforeDragUpload: UploadProps["beforeUpload"] = (rawFile) => { if (valor.value.length >= props.limit) { ElMessage.error(`Permitido no máximo até ${props.limit} arquivo(s).`); return false; @@ -289,10 +327,6 @@ export default defineComponent({ return true; }; const updateValue = () => { emit("update:modelValue", valor.value); }; @@ -313,7 +347,8 @@ export default defineComponent({ handleDragRemove, handleDragCardPreview, handleDragSuccess, beforeDragUpload, loadImageById }; } }); -
dansp89 created this gist
Feb 29, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,325 @@ <template> <el-upload v-model:file-list="fileList" class="photo-wall-uploader" :list-type="listType" :drag="true" :name="name" :action="uploadMetas.url" :method="uploadMetas.method" :headers="uploadMetas.headers" :accept="accept" :multiple="multiple" :show-file-list="true" :on-success="handleDragSuccess" :on-remove="handleDragRemove" :on-exceed="handleExceed" :before-remove="beforeRemove" :before-upload="beforeDragUpload" :auto-upload="true" :limit="limit" > <!-- :disabled="fileList.length >= limit" --> <el-icon class="el-icon--upload"><upload-filled /></el-icon> <div class="el-upload__text"> Solte o arquivo aqui ou <em>clique para fazer upload</em> </div> <template #tip> <div class="el-upload__tip" v-html="instructions"></div> </template> </el-upload> <el-dialog v-model="dialogVisible"> <img :src="dialogImageUrl" alt="Preview Image" /> </el-dialog> </template> <script lang="ts"> /** * @source Basic Usage <https://element-plus.org/en-US/component/upload.html#photo-wall> */ import { defineComponent, ref, watchEffect, watch, type PropType } from "vue"; import { ElMessage, ElMessageBox } from "element-plus"; import type { UploadProps, UploadUserFile } from "element-plus"; import { UploadFilled } from "@element-plus/icons-vue"; import { getToken } from "@/core/services/JwtService"; import ApiService from "@/core/services/ApiService"; import { getAssetPath } from "@/core/helpers/assets"; export default defineComponent({ name: "campo-upload-photowall", components: { UploadFilled }, props: { buttonText: { type: String, default: "Clique para upload" }, accept: { type: String, default: "*" }, multiple: { type: Boolean, default: false }, name: { type: String, default: "files" // ( Nome da chave para o arquivo carregado. )Padrão usado no STRAPI 4 }, withCredentials: { type: Boolean, default: false }, showFileList: { type: Boolean, default: true }, drag: { type: Boolean, default: false }, listType: { type: String as PropType<"text" | "picture" | "picture-card">, default: "text", validator: (value: string) => ["text", "picture", "picture-card"].includes(value) }, disabled: { type: Boolean, default: false }, limit: { type: Number, default: 1 }, limitSize: { type: Number, default: 2 }, modelValue: { type: Array, // ou o tipo apropriado default: () => [] } }, emits: ["update:modelValue", "change", "input"], setup(props, { emit }) { const imageUrl = ref(""); const fileList = ref<UploadUserFile[]>([]); const dialogImageUrl = ref(""); const dialogVisible = ref(false); const valor = ref(props.modelValue); const instructions = ref(""); const uploadFileId = ref(); const uploadData = {} as ImageData; // Resposta do servidor const uploadMetas = { url: import.meta.env.VITE_APP_API_URL + "/upload", method: "POST", headers: { Authorization: `Bearer ${getToken()}` } }; watchEffect(() => { if (props.accept === "*") { instructions.value = `Permitido ${props.limit} arquivo de todos os formatos, até ${props.limitSize}mb`; } else { const filesExts = props.accept.split(",").map((a) => { return `*.${a.split("/")[1]}`; }); const archive = props.limit < 2 ? "arquivo" : "arquivos"; instructions.value = `Permitido <strong>${props.limit}</strong> ${archive} <strong>${filesExts}</strong> até <strong>${props.limitSize}mb</strong>`; } console.log("[Drag]::watchEffect", valor.value); }); const handleExceed: UploadProps["onExceed"] = (files, uploadFiles) => { console.log("[handleExceed]", files, uploadFiles); ElMessage.warning( `O limite é de ${props.limit}, Você selecionou ${files.length} arquivos de uma vez.` ); }; const beforeRemove: UploadProps["beforeRemove"] = ( uploadFile, uploadFiles ) => { console.log("[beforeRemove]", uploadFile, uploadFiles); return ElMessageBox.confirm( `Cancelar a transferência de ${uploadFile.name} ?` ).then( () => true, () => false ); }; const handleDragRemove: UploadProps["onRemove"] = async ( uploadFile, uploadFiles ) => { console.log("[handleDragRemove]", uploadFile, uploadFiles); let id = JSON.parse(JSON.stringify(uploadFile)); console.log("[handleDragRemove]::FILES IDS:", id); try { id = id.response[0].id; console.log("[handleDragRemove]::FILES IDS::toRemove:", id); ApiService.setHeader(); const deletar = await ApiService.delete(`/upload/files/${id}`); console.log("[handleDragRemove]::deletar", deletar); if (deletar?.status === 200) { ElMessage.success("Eliminado com sucesso!"); valor.value = valor.value?.filter((item) => item !== id); updateValue(); } else { ElMessage.error("Falha ao eliminar!"); } } catch { console.log(""); } }; const handleDragCardPreview: UploadProps["onPreview"] = (uploadFile) => { console.log("[handleDragCardPreview]", uploadFile); const ext = uploadFile.raw.type.split("/")[1]; console.log("EXT FILE::", ext); if (uploadFile.raw.type.includes("image")) { dialogImageUrl.value = URL.createObjectURL(uploadFile.raw!); } else if (ext.includes("pdf")) { dialogImageUrl.value = window.location.origin + getAssetPath(`media/svg/files/${ext}.svg`); } else { dialogImageUrl.value = window.location.origin + getAssetPath(`media/svg/files/upload.svg`); } // dialogImageUrl.value = uploadFile.url!; dialogImageUrl.value = window.location.origin + getAssetPath(`media/svg/files/upload.svg`); dialogVisible.value = true; valor.value = []; updateValue(); }; const handleDragSuccess: UploadProps["onSuccess"] = ( response, uploadFile, uploadFiles ) => { const filesIds = uploadFiles .map((a) => { try { a.response[0]?.id; } catch { a; } }) .filter(Boolean); console.log("[handleDragSuccess]::", response, uploadFile, filesIds); const ext = uploadFile.raw.type.split("/")[1]; console.log("EXT FILE::", ext); if (uploadFile.raw.type.includes("image")) { imageUrl.value = URL.createObjectURL(uploadFile.raw!); } else if (ext.includes("pdf")) { imageUrl.value = window.location.origin + getAssetPath(`media/svg/files/${ext}.svg`); } else { imageUrl.value = window.location.origin + getAssetPath(`media/svg/files/upload.svg`); } valor.value = filesIds; console.log( "[handleDragSuccess]::valor:", JSON.parse(JSON.stringify(valor.value)), "URL IMAGE:", imageUrl.value ); emit("update:modelValue", valor.value); emit("change", valor.value); emit("input", valor.value); }; const beforeDragUpload: UploadProps["beforeUpload"] = (rawFile) => { // console.log( // "[beforeDragUpload]", // fileList, // rawFile, // valor.value.length // ); // console.log( // "[LIMITE de arquivos]", // valor.value.length, // props.limit, // valor.value.length >= props.limit // ); if (valor.value.length >= props.limit) { ElMessage.error(`Permitido no máximo até ${props.limit} arquivo(s).`); return false; } if ( !props.accept .split(",") .map((a) => a.trim()) .includes(rawFile.type) ) { ElMessage.error( `Permitido ${props.limit} arquivo de todos os formatos, até ${props.limitSize}mb` ); return false; } if (rawFile.size / 1024 / 1024 > props.limitSize) { const filesExts = props.accept.split(",").map((a) => { return `*.${a.split("/")[1]}`; }); const archive = props.limit < 2 ? "arquivo" : "arquivos"; instructions.value = `Permitido <strong>${props.limit}</strong> ${archive} <strong>${filesExts}</strong> até <strong>${props.limitSize}mb</strong>`; ElMessage.error({ message: `Permitido ${props.limit} ${archive} ${filesExts} até ${props.limitSize}mb`, duration: 5000 }); return false; } return true; }; watch(valor, (newValue) => { emit("update:modelValue", newValue); }); const updateValue = () => { emit("update:modelValue", valor.value); }; return { dialogImageUrl, dialogVisible, imageUrl, fileList, instructions, uploadFileId, uploadData, uploadMetas, valor, updateValue, handleExceed, beforeRemove, handleDragRemove, handleDragCardPreview, handleDragSuccess, beforeDragUpload }; } }); </script> <style scoped> .el-dialog__body img { width: 100%; } </style>