UNPKG

yanzhen-design-vue

Version:

278 lines (277 loc) 9.45 kB
import { ref, useAttrs, useSlots, computed, unref, mergeProps, h, reactive } from "vue"; import { PictureTwoTone, FileTwoTone, LoadingOutlined, PaperClipOutlined } from "@ant-design/icons-vue"; import { createReusableTemplate } from "@vueuse/core"; import { isEmptyValue, mergeWith } from "@yanzhen-libs/utils"; import { useProxyProps } from "@yanzhen-libs/utils-vue"; import { Upload, message } from "ant-design-vue"; import { isImageUrl } from "ant-design-vue/es/upload/utils"; import { isString, isFunction, pick } from "lodash-es"; import "./hooks/index.mjs"; import { useFileListConfig } from "./hooks/use-file-list-config.mjs"; import { provideUploadApi } from "./hooks/use-upload-apis.mjs"; import { AntUpload } from "./upload.mjs"; import { useUploadPreview } from "./use-upload-preview.mjs"; import { useUploadRules } from "./hooks/use-upload-rules.mjs"; function useUpload(props, emit) { const _ref = ref(null); const attrs = useAttrs(); const slots = useSlots(); const [DefineUploadIconRender, ReusableUploadIconRender] = createReusableTemplate(); const [DefineUploadPreview, ReusableUploadPreview] = createReusableTemplate(); const isEditTable = computed( () => isString(props.nativeTag) && props.nativeTag.startsWith("edit-table") ); const { customUploadRequest } = provideUploadApi(props); const { fileListRef, isImageType } = useFileListConfig(props, emit); const { imagePreviewRef, filePreviewRef, handleOpenPreview, ctx: previewCtx } = useUploadPreview(props, emit); const description = computed(() => { if (isEmptyValue(props.uploadDesc)) return; return `${props.uploadDesc || ""}文件类型:${props.accept || ""}`; }); const progressProps = computed(() => { return mergeWith( { strokeColor: { "0%": "#108ee9", "100%": "#87d068" } }, props.progress ?? {} ); }); const { acceptRef, maxCountRef, maxCountRemainderRef, maxSizeRef, validate: handleValidate } = useUploadRules(fileListRef, props); const imageUploadErrCollect = ref([]); const imageUploadTotalCount = ref(0); const imageUploadHasError = ref(false); const curBeforeImageUploads = ref(0); const currentImageUploads = ref(0); console.log( "图片最大数量", props, maxSizeRef, unref(imageUploadErrCollect), unref(maxCountRef), unref(maxCountRemainderRef) ); const multipleRef = computed(() => { const maxCount = unref(maxCountRef); const maxCountRemainder = unref(maxCountRemainderRef); switch (true) { case (maxCount === 1 || maxCountRemainder <= 1): return false; default: return props.multiple; } }); const handleBeforeUpload = async (file, fileList) => { if (unref(isImageType)) curBeforeImageUploads.value++; if (isFunction(props.beforeUpload)) { const flag2 = await props.beforeUpload(file, fileList); return flag2 || Upload.LIST_IGNORE; } let flag = true; if (unref(isImageType)) imageUploadTotalCount.value = fileList.length; const valid = handleValidate({ file, selectFileList: fileList, fileList: unref(fileListRef).concat(fileList), isImageType: unref(isImageType) }); if (valid) { if (unref(isImageType)) { imageUploadErrCollect.value.push(valid[0]); imageUploadHasError.value = true; } else message.error(valid[0].message); flag = false; } if (unref(isImageType)) { curBeforeImageUploads.value--; console.log("上传的图片-都不满足", curBeforeImageUploads.value); if (curBeforeImageUploads.value === 0) { handleImageUploadComplete(true); } } console.log( "1、BeforeUpload-图片校验", file, fileList, valid, fileList.length, imageUploadErrCollect ); return flag || Upload.LIST_IGNORE; }; const handleCustomRequest = async (options) => { if (unref(isImageType)) currentImageUploads.value++; const { file, onError, onProgress, onSuccess } = options; if (isFunction(props.customRequest)) { return props.customRequest(options); } if (typeof file === "string") { onSuccess == null ? void 0 : onSuccess(file); return; } const valid = handleValidate({ file }); console.log("2、CustomRequest-上传图片", currentImageUploads.value, options, file, valid); if (valid) { message.error(valid == null ? void 0 : valid[0].message); onError == null ? void 0 : onError(new Error(valid == null ? void 0 : valid[0].message)); return; } const progress = { percent: 0 }; onProgress == null ? void 0 : onProgress(progress); const timer = setInterval(() => { if (progress.percent < 80) { progress.percent = progress.percent + 5; onProgress == null ? void 0 : onProgress(progress); } else { clearInterval(timer); } }, 500); try { const result = await customUploadRequest({ ...options, data: { uploadType: props.uploadType, ...options.data ?? {} } }); if ((result == null ? void 0 : result.code) !== 0) { onProgress == null ? void 0 : onProgress({ percent: 80 }); onError == null ? void 0 : onError(new Error(result == null ? void 0 : result.message)); imageUploadHasError.value = true; } else { onProgress == null ? void 0 : onProgress({ percent: 100 }); onSuccess == null ? void 0 : onSuccess(result.data); } } catch (e) { onProgress == null ? void 0 : onProgress({ percent: 80 }); onError == null ? void 0 : onError(e); imageUploadHasError.value = true; } finally { if (unref(isImageType)) { currentImageUploads.value--; console.log("最后一次", currentImageUploads.value); if (currentImageUploads.value === 0) { handleImageUploadComplete(); } } clearInterval(timer); } }; const handleImageUploadComplete = (beforeUploadFlag = false) => { console.log("汇总提示!!!-end", imageUploadHasError.value, imageUploadErrCollect.value); if (imageUploadHasError.value) { const imageUploadErrCollectValue = unref(imageUploadErrCollect); const imageUploadErrCollectLen = imageUploadErrCollectValue.length; if (beforeUploadFlag && imageUploadErrCollectLen !== unref(imageUploadTotalCount)) return; const maxSizeErrData = imageUploadErrCollectValue.filter( (el) => typeof el.type === "object" && el.type !== null && "useDocMsg" in el.type ); const otherErrData = imageUploadErrCollectValue.filter((el) => typeof el.type === "string"); const uniqueErrorTypes = Array.from(new Set(otherErrData.map((el) => el.type))); const uniqueErrData = uniqueErrorTypes.map( (type) => { var _a; return (_a = otherErrData.find((el) => el.type === type)) == null ? void 0 : _a.message; } ); const maxSizeErrDataLen = maxSizeErrData.length; if (maxSizeErrDataLen) { const firstError = maxSizeErrData[0]; let maxSizeErrMsg = firstError.message; if (typeof firstError.type === "object" && firstError.type !== null) { const { useDocMsg, maxSize } = firstError.type; if (useDocMsg) maxSizeErrMsg = `有${maxSizeErrDataLen}张图片大小超过${maxSize}兆,无法上传成功,请重新选择图片上传`; } uniqueErrData.push(maxSizeErrMsg); } uniqueErrData.length && uniqueErrData.forEach((msg) => { message.error(msg); }); imageUploadErrCollect.value = []; imageUploadHasError.value = false; } }; const config = computed(() => pick(props, ...Object.keys(AntUpload.props))); const proxyProps = useProxyProps(config, AntUpload.emits, { emit, exclude: [ "value", "fileList", "onUpdate:fileList", "multiple", "accept", "progress", "onPreview" ], filter: true }); const propsRef = computed(() => { return mergeProps(unref(attrs), unref(proxyProps)); }); function UploadIconRender({ file, listType }) { var _a; const isLoading = file.status === "uploading"; const isImageUrl$1 = props.isImageUrl ?? isImageUrl; const uploading = (_a = props.locale) == null ? void 0 : _a.uploading; const fileIcon = isImageUrl$1 && isImageUrl$1(file) ? h(PictureTwoTone) : h(FileTwoTone); switch (true) { case listType === "picture": return isLoading ? h(LoadingOutlined) : fileIcon; case listType === "picture-card": return isLoading && !!uploading ? uploading : fileIcon; default: return isLoading ? h(LoadingOutlined) : h(PaperClipOutlined); } } const ctx = { ...previewCtx, _ref }; const exposeCtx = reactive(ctx); return { ...ctx, slots, isEditTable, isImageType, multipleRef, fileListRef, acceptRef, progressProps, propsRef, description, maxCountRef, handleCustomRequest, handleBeforeUpload, UploadIconRender, DefineUploadIconRender, ReusableUploadIconRender, DefineUploadPreview, ReusableUploadPreview, // Preview imagePreviewRef, filePreviewRef, handleOpenPreview, // expose ctx, exposeCtx }; } export { useUpload };