文件上传下载类组件,使用的是OSS的SDK,用于处理文件图片上传及获取一些参数。
// 方法
/**
* 文件上传下载类,使用的是OSS的SDK
*/
declare class Upload {
constructor(bucket: string, projectName?: string, opts?: {
region: string;
accessKeyId: string;
accessKeySecret: string;
secure: boolean;
});
client: OSS;
Options: OSS.Options;
Host: string;
ProjectName: string;
getFileName(file: File): Promise<string>;
/**
* 简单的上传文件,小于100MB
* @param file 文件对象
* @param opts 参数
* @returns 文件结果对象
*/
upload(file: File, opts?: OSS.PutObjectOptions): Promise<{
uid: any;
key: any;
url: string;
downloadUrl: any;
}>;
/**
* 获取下载的url
* @param fileName 文件名称,兼容url
* @returns 下载url
*/
getDownloadUrl(fileName: string): any;
/**
* 缩放图片宽高,可以只指定宽度或者高度
* @param fileName 文件名
* @param w 宽度
* @param h 高度
* @returns
*/
resizeImage(fileName: string, w: string, h: string): any;
/**
* 返回图片的宽高
* @param file
* @returns
*/
getImageWidthHeight(file: File): Promise<unknown>;
}
export default Upload;
使用方法非常简单,基本上就是拿来即用
// 首先在package.json 中 加入 img_oss 的引入,然后 yarn / npm install
"@dm/img_oss": "^1.0.9",
// 然后在需要用到的地方 import
import IMGOSS from '@dm/img_oss';
// BUCKET 此处为oss地址
const IMGCLIENT = new IMGOSS(BUCKET);
// 我这里是在antd 的upload 基础上做的处理,用的是customRequest
我们项目中一般是基于Upload另外封一个上传和回显,此处只阐述覆盖默认行为后使用@dm/img_oss的部分。
// 覆盖默认的上传行为,自定义自己的上传
const handleUploadFile = async (uploadFile) => {
//例:图片上传:除基本的文件后缀和文件大小校验外,会遇到图片宽高限制校验和图片比例校验
// 图片宽高校验,如不放图片则不校验
const getwahLimit = await limitWaH(file);
if (getwahLimit && getwahLimit.code === '205') {
message.error(getwahLimit.message);
return;
}
// 上传
const data = await IMGCLIENT.upload(file);
if (data) {
// 上传成功的处理
}
};
<Upload customRequest={handleUploadFile} />
/**
* 图片限制宽高校验,⚠️*注意⚠️:数值部分必须是大于0的数字
*/
// 有效值 是不是数字(图片宽高限制方法的有效值检查)
function isNumValid(unitVal) {
const isNum = unitVal ? isNaN(unitVal) : 0;
const unit = Number(unitVal);
if (isNum || unit < 0) {
throw rError(`${unitVal} 不是合法参数`, 500);
}
return unit;
}
// 最小值 (图片宽高限制方法的最小值检查)
function compareMin(minVal, imgVal) {
if (minVal && minVal > imgVal) return true;
}
// 最大值 (图片宽高限制方法的最大值检查)
function compareMax(maxVal, imgVal) {
if (maxVal && maxVal < imgVal) return true;
}
// 抛出错误的提示(图片宽高限制方法的)
function rError(message, code) {
return {
code: code || 500,
message,
};
}
// 获取图片宽高(图片宽高限制方法的)
async function fileWh(file) {
try {
if (!file) throw rError('未找到文件', 500);
const data = await IMGCLIENT.getImageWidthHeight(file);
if (data) return data;
throw this.rError('宽高解析失败,请检查文件', 500);
} catch (error) {
console.log('fileWh error', error);
throw this.rError(error.message || '网络连接失败', error.code || 500);
}
}
// (图片宽高限制方法)
export const LimitImgWH = {
async fixed(file, width, height) {
/**
* 固定宽高限制,比如:图片宽高必须是10*10 px【LimitImgWH.fixed(文件file, 10, 10)】
* LimitImgWH.fixed(file, width, height); // 文件,宽,高
*/
const wNum = isNumValid(width);
const hNum = isNumValid(height);
const wah = await fileWh(file);
const tipArr = [];
if (wNum && wNum !== wah.width) {
tipArr.push(`宽度为${wNum}`);
}
if (hNum && hNum !== wah.height) {
tipArr.push(`高度为${hNum}`);
}
if (tipArr.length > 1) {
throw rError(`请上传宽高为${wNum} x ${hNum}px的图片`, 205);
} else if (tipArr.length === 1) {
throw rError(`请上传${tipArr}px的图片`, 205);
}
},
async range(file, widthMin, widthMax, heightMin, heightMax) {
/**
* 宽高px范围限制,比如:图片宽高不超过200px 【LimitImgWH.range(file, _,200, _,200)】
* LimitImgWH.range(file, widthMin, widthMax, heightMin, heightMax); // 文件 宽的数据 高的数据
* =使用1:图片宽最小为10px,高最小为20px 【LimitImgWH.range(file, 10, _, 20)】
* =使用2:图片宽不超过10px,高不超过20px 【LimitImgWH.range(file, _,10, _,20)】
*/
const wMinNum = isNumValid(widthMin);
const wMaxNum = isNumValid(widthMax);
const hMinNum = isNumValid(heightMin);
const hMaxNum = isNumValid(heightMax);
const tipArr = [];
const wah = await fileWh(file);
if (compareMin(wMinNum, wah.width)) {
tipArr.push(`宽大于${wMinNum}`);
}
if (compareMax(wMaxNum, wah.width)) {
tipArr.push(`宽不超过${wMaxNum}`);
}
if (compareMin(hMinNum, wah.height)) {
tipArr.push(`高大于${hMinNum}`);
}
if (compareMax(hMaxNum, wah.height)) {
tipArr.push(`高不超过${hMaxNum}`);
}
if (tipArr.length) {
throw rError(`请上传${tipArr}px的图片`, 205);
}
},
async ratio(file, min = 0.1, max = 10) {
/**
* 宽高比限制,比如图片宽高比在1~2之间 【LimitImgWH.ratio(file, 1, 2)】
* LimitImgWH.ratio(file, min, max); // 文件 最小比 最大比
* ====注解:使用比例默认为0.1~10,所以【LimitImgWH.ratio(file)】的执行结果是:图片宽高比在0.1-10之间的图
* ====注解2:如果不需要限制其中一项,比如只需要最小比为1,则【LimitImgWH.ratio(file,1)】,最大会默认为10
* ====注解3:同理,如只需要最大比为1,则【LimitImgWH.ratio(file,_,1)】,最小会默认为0.1
*/
const minNumber = isNumValid(min) || 0.1;
const maxNumber = isNumValid(max) || 10;
const wah = await fileWh(file);
if (wah.width / wah.height < minNumber || wah.width / wah.height > maxNumber) {
throw rError(`请上传宽高比在${minNumber} - ${maxNumber}之间的图片`, 205);
}
},
};