增加进件功能
This commit is contained in:
@@ -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 = 1024KB,1KB = 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>
|
||||
Reference in New Issue
Block a user