前端代码格式化

This commit is contained in:
2026-02-19 11:46:27 +08:00
parent d310a29c03
commit f0f0763ceb
101 changed files with 8952 additions and 13203 deletions
+115 -150
View File
@@ -20,39 +20,26 @@
class="custom-upload"
:class="{ 'drag-over': isDragOver }"
>
<div
v-if="fileList.length < maxCount && !disabled"
class="upload-area"
>
<div v-if="fileList.length < maxCount && !disabled" class="upload-area">
<loading-outlined v-if="uploading" class="upload-icon" />
<plus-outlined v-else class="upload-icon" />
<div class="ant-upload-text">
{{ uploading ? "上传中..." : uploadText }}
{{ uploading ? '上传中...' : uploadText }}
</div>
<div v-if="tip" class="ant-upload-tip">{{ tip }}</div>
</div>
</a-upload>
<a-modal
:open="previewVisible"
:title="previewTitle"
:footer="null"
:width="800"
@cancel="handleCancel"
>
<img
alt="图片预览"
style="width: 100%; max-height: 600px; object-fit: contain"
:src="previewImage"
/>
<a-modal :open="previewVisible" :title="previewTitle" :footer="null" :width="800" @cancel="handleCancel">
<img alt="图片预览" style="width: 100%; max-height: 600px; object-fit: contain" :src="previewImage" />
</a-modal>
</div>
</template>
<script setup>
import { ref, watch, computed } from "vue";
import { message, Modal } from "ant-design-vue";
import { PlusOutlined, LoadingOutlined } from "@ant-design/icons-vue";
import uploadConfig from "@/config/upload";
import { ref, watch, computed } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'
import uploadConfig from '@/config/upload'
const props = defineProps({
// 图片列表
@@ -68,7 +55,7 @@ const props = defineProps({
// 接受的文件类型
accept: {
type: String,
default: "image/*",
default: 'image/*',
},
// 是否禁用
disabled: {
@@ -83,12 +70,12 @@ const props = defineProps({
// 上传按钮文字
uploadText: {
type: String,
default: "上传图片",
default: '上传图片',
},
// 提示文字
tip: {
type: String,
default: "",
default: '',
},
// 最小宽度(像素)
minWidth: {
@@ -120,258 +107,236 @@ const props = defineProps({
type: Function,
default: null,
},
});
})
const emit = defineEmits([
"update:modelValue",
"change",
"preview",
"remove",
"uploadSuccess",
"uploadError",
]);
const emit = defineEmits(['update:modelValue', 'change', 'preview', 'remove', 'uploadSuccess', 'uploadError'])
// 文件列表
const fileList = ref([]);
const fileList = ref([])
// 预览相关
const previewVisible = ref(false);
const previewImage = ref("");
const previewVisible = ref(false)
const previewImage = ref('')
const previewTitle = computed(() => {
return previewImage.value ? "图片预览" : "";
});
return previewImage.value ? '图片预览' : ''
})
// 上传状态
const uploading = ref(false);
const uploading = ref(false)
// 拖拽状态
const isDragOver = ref(false);
const isDragOver = ref(false)
// 初始化文件列表
const initFileList = () => {
if (props.modelValue) {
if (typeof props.modelValue === "string") {
if (typeof props.modelValue === 'string') {
// 单图上传,字符串格式
fileList.value = props.modelValue
? [
{
uid: "-1",
name: "image.png",
status: "done",
uid: '-1',
name: 'image.png',
status: 'done',
url: props.modelValue,
},
]
: [];
: []
} else if (Array.isArray(props.modelValue)) {
// 多图上传,数组格式
fileList.value = props.modelValue.map((url, index) => ({
uid: `-${index}`,
name: `image${index}.png`,
status: "done",
status: 'done',
url: url,
}));
}))
}
} else {
fileList.value = [];
fileList.value = []
}
};
}
// 监听外部值变化
watch(
() => props.modelValue,
() => {
initFileList();
initFileList()
},
{ immediate: true },
);
)
// 自定义上传
const customUpload = (options) => {
const { file, onProgress, onSuccess, onError } = options;
const formData = new FormData();
formData.append(uploadConfig.filename || "file", file);
const { file, onProgress, onSuccess, onError } = options
const formData = new FormData()
formData.append(uploadConfig.filename || 'file', file)
uploading.value = true;
uploading.value = true
uploadConfig
.apiObj(formData, {
onUploadProgress: (progressEvent) => {
const percent = Math.round(
(progressEvent.loaded / progressEvent.total) * 100,
);
onProgress({ percent }, file);
const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100)
onProgress({ percent }, file)
},
})
.then((res) => {
const data = uploadConfig.parseData(res);
const data = uploadConfig.parseData(res)
if (data.code === uploadConfig.successCode) {
onSuccess(data, file);
message.success("上传成功");
emit("uploadSuccess", data, file);
onSuccess(data, file)
message.success('上传成功')
emit('uploadSuccess', data, file)
} else {
onError(new Error(data.msg || "上传失败"));
message.error(data.msg || "上传失败");
emit("uploadError", data.msg || "上传失败", file);
onError(new Error(data.msg || '上传失败'))
message.error(data.msg || '上传失败')
emit('uploadError', data.msg || '上传失败', file)
}
})
.catch((error) => {
onError(error);
message.error("上传失败:" + error.message);
emit("uploadError", error.message, file);
onError(error)
message.error('上传失败:' + error.message)
emit('uploadError', error.message, file)
})
.finally(() => {
uploading.value = false;
});
};
uploading.value = false
})
}
// 上传前校验
const beforeUpload = async (file) => {
// 文件大小校验
const maxSizeMB = uploadConfig.maxSize || 10;
const maxSizeBytes = maxSizeMB * 1024 * 1024;
const maxSizeMB = uploadConfig.maxSize || 10
const maxSizeBytes = maxSizeMB * 1024 * 1024
if (file.size > maxSizeBytes) {
message.error(`图片大小不能超过 ${maxSizeMB}MB`);
return false;
message.error(`图片大小不能超过 ${maxSizeMB}MB`)
return false
}
// 图片尺寸校验
if (
props.minWidth ||
props.maxWidth ||
props.minHeight ||
props.maxHeight
) {
if (props.minWidth || props.maxWidth || props.minHeight || props.maxHeight) {
try {
const dimensions = await getImageDimensions(file);
const { width, height } = dimensions;
const dimensions = await getImageDimensions(file)
const { width, height } = dimensions
if (props.minWidth && width < props.minWidth) {
message.error(`图片宽度不能小于 ${props.minWidth}px`);
return false;
message.error(`图片宽度不能小于 ${props.minWidth}px`)
return false
}
if (props.maxWidth && width > props.maxWidth) {
message.error(`图片宽度不能大于 ${props.maxWidth}px`);
return false;
message.error(`图片宽度不能大于 ${props.maxWidth}px`)
return false
}
if (props.minHeight && height < props.minHeight) {
message.error(`图片高度不能小于 ${props.minHeight}px`);
return false;
message.error(`图片高度不能小于 ${props.minHeight}px`)
return false
}
if (props.maxHeight && height > props.maxHeight) {
message.error(`图片高度不能大于 ${props.maxHeight}px`);
return false;
message.error(`图片高度不能大于 ${props.maxHeight}px`)
return false
}
} catch (error) {
message.error("图片尺寸校验失败");
return false;
message.error('图片尺寸校验失败')
return false
}
}
return true;
};
return true
}
// 获取图片尺寸
const getImageDimensions = (file) => {
return new Promise((resolve, reject) => {
const img = new Image();
const reader = new FileReader();
const img = new Image()
const reader = new FileReader()
reader.onload = (e) => {
img.src = e.target.result;
img.src = e.target.result
img.onload = () => {
resolve({ width: img.width, height: img.height });
};
img.onerror = reject;
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
};
resolve({ width: img.width, height: img.height })
}
img.onerror = reject
}
reader.onerror = reject
reader.readAsDataURL(file)
})
}
// 处理预览
const handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj);
file.preview = await getBase64(file.originFileObj)
}
previewImage.value = file.url || file.preview;
previewVisible.value = true;
emit("preview", file);
};
previewImage.value = file.url || file.preview
previewVisible.value = true
emit('preview', file)
}
// 获取Base64
const getBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
};
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
})
}
// 处理文件列表变化
const handleChange = ({ fileList: newFileList }) => {
// 更新文件列表,确保上传成功的文件有正确的 url
const updatedFileList = newFileList.map((file) => {
// 如果文件上传成功且有响应数据但没有 url,则设置 url
if (file.status === "done" && file.response?.src && !file.url) {
if (file.status === 'done' && file.response?.src && !file.url) {
return {
...file,
url: file.response.src,
};
}
}
return file;
});
return file
})
fileList.value = updatedFileList;
fileList.value = updatedFileList
// 过滤掉失败的文件
const validFileList = updatedFileList.filter(
(file) => file.status !== "error",
);
const validFileList = updatedFileList.filter((file) => file.status !== 'error')
// 提取成功的文件URL
const successFiles = validFileList
.filter(
(file) =>
file.status === "done" && (file.url || file.response?.src),
)
.map((file) => file.url || file.response?.src);
const successFiles = validFileList.filter((file) => file.status === 'done' && (file.url || file.response?.src)).map((file) => file.url || file.response?.src)
// 触发更新事件
if (props.returnUrl) {
// 返回URL字符串或数组
const value =
props.maxCount === 1 ? successFiles[0] || "" : successFiles;
emit("update:modelValue", value);
emit("change", value, validFileList);
const value = props.maxCount === 1 ? successFiles[0] || '' : successFiles
emit('update:modelValue', value)
emit('change', value, validFileList)
} else {
// 返回完整文件列表
emit("update:modelValue", validFileList);
emit("change", validFileList);
emit('update:modelValue', validFileList)
emit('change', validFileList)
}
};
}
// 拖拽相关
const handleDragEnter = (e) => {
e.preventDefault();
isDragOver.value = true;
};
e.preventDefault()
isDragOver.value = true
}
const handleDragLeave = (e) => {
e.preventDefault();
isDragOver.value = false;
};
e.preventDefault()
isDragOver.value = false
}
const handleDrop = (e) => {
e.preventDefault();
isDragOver.value = false;
};
e.preventDefault()
isDragOver.value = false
}
// 取消预览
const handleCancel = () => {
previewVisible.value = false;
};
previewVisible.value = false
}
</script>
<style scoped>