yanzhen-design-vue
Version:
278 lines (277 loc) • 9.45 kB
JavaScript
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
};