增加进件功能

This commit is contained in:
2026-01-09 18:52:26 +08:00
parent 6c08b3b878
commit 684014e183
28 changed files with 4765 additions and 67 deletions

View File

@@ -1,8 +1,8 @@
<template>
<view class="upload-file" @click="chooseImage">
<view class="upload-file" @click="chooseImage" :style="returnStyle('box')">
<slot v-if="$slots.default"></slot>
<view class="icon" v-if="!modelValue">+</view>
<image class="img" v-else :src="modelValue"></image>
<image class="img" v-else :src="modelValue" :style="returnStyle('img')"></image>
<view class="close" @click.stop="() => {}" v-if="modelValue">
<up-icon name="close-circle" color="#333" size="14" @click="clearImg"></up-icon>
@@ -11,79 +11,152 @@
</template>
<script setup>
import { uploadFile } from '@/http/api/index.js';
import {
uploadFile
} from '@/http/api/index.js';
import {
ref
} from 'vue';
import { reactive, ref, watch } from 'vue';
const modelValue = defineModel({
type: String,
default: ''
});
function chooseImage() {
uni.chooseImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'],
success: async function (res) {
uni.showLoading({
title: '上传中'
});
console.log(res);
const fileRes = await uploadFile(res.tempFiles[0]);
uni.hideLoading();
if (fileRes) {
modelValue.value = fileRes;
} else {
uni.showToast({
title: '上传失败',
icon: 'none'
});
const props = defineProps({
size: {
default: ''
},
// 图片最大上传大小单位M默认undefined不限制大小
maxSize: {
type: [Number, String], // 支持数字如2或字符串如"2")传参
default: undefined,
validator: (value) => {
// 校验传参必须是大于0的数字转换后否则视为不限制
const numValue = Number(value);
return value === undefined || (!isNaN(numValue) && numValue > 0);
}
}
});
}
})
function clearImg() {
modelValue.value = '';
}
function returnStyle(type) {
let size = null
if (!props.size) {
return
}
if (Number(props.size) === NaN) {
size = props.size
} else {
size = props.size + 'rpx'
}
return {
width: size,
height: size
}
}
const modelValue = defineModel({
type: String,
default: ''
});
const emits = defineEmits('uploadSuccess')
// ------------- 新增2工具函数将M转换为字节1M = 1024 * 1024 字节) -------------
/**
* 转换文件大小单位M → 字节)
* @returns {number} 最大允许的文件字节数返回0表示不限制
*/
function getMaxFileSizeInBytes() {
if (props.maxSize === undefined) return 0; // 未传参返回0不限制
const maxSizeNum = Number(props.maxSize);
// 无效数值返回0不限制
if (isNaN(maxSizeNum) || maxSizeNum <= 0) return 0;
// 转换公式1M = 1024KB1KB = 1024字节
return maxSizeNum * 1024 * 1024;
}
// ------------- 修改1在上传前增加文件大小校验 -------------
function chooseImage() {
uni.chooseImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'],
success: async function(res) {
// 1. 获取文件信息(大小、临时路径等)
const tempFile = res.tempFiles[0];
const maxFileSize = getMaxFileSizeInBytes();
// 2. 校验文件大小仅当maxFileSize>0时才校验
if (maxFileSize > 0 && tempFile.size > maxFileSize) {
uni.showToast({
title: `图片大小不能超过${props.maxSize}M`,
icon: 'none'
});
return; // 校验失败,终止后续上传逻辑
}
// 3. 校验通过,执行上传
uni.showLoading({
title: '上传中'
});
console.log(res);
const fileRes = await uploadFile(tempFile);
uni.hideLoading();
if (fileRes) {
modelValue.value = fileRes;
emits('uploadSuccess', fileRes)
} else {
uni.showToast({
title: '上传失败',
icon: 'none'
});
}
}
});
}
function clearImg() {
modelValue.value = '';
}
</script>
<style lang="scss">
.upload-file {
$size: 128rpx;
width: $size;
height: $size;
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed #d9d9d9;
border-radius: 8rpx;
position: relative;
.close {
position: absolute;
right: -10rpx;
top: -10rpx;
}
.img {
.upload-file {
$size: 128rpx;
width: $size;
height: $size;
}
.icon {
width: 36rpx;
height: 36rpx;
border: 4rpx solid #999;
border-radius: 8rpx;
font-weight: 700;
color: #999;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
line-height: 1;
padding: 0;
margin: 0;
text-align: center;
border: 1px dashed #d9d9d9;
border-radius: 8rpx;
position: relative;
.close {
position: absolute;
right: -10rpx;
top: -10rpx;
}
.img {
width: $size;
height: $size;
}
.icon {
width: 36rpx;
height: 36rpx;
border: 4rpx solid #999;
border-radius: 8rpx;
font-weight: 700;
color: #999;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
line-height: 1;
padding: 0;
margin: 0;
text-align: center;
}
}
}
</style>
</style>