说明:在使用cool-admin这个低代码平台时,发现官方的cos上传插件有问题,总是报错 substring,故自己找解决方案,修改本地的upload方法改为云端上传。
解决方案:
- 安装腾讯云cos的nodeJS SDK
shell
pnpm i cos-nodejs-sdk-v5
- 在
admin-midway/src/modules/plugin/hooks/upload
目录下新建工具文件upload_cos.ts
内容如下:
typescript
const COS: any = require('cos-nodejs-sdk-v5');
import fs = require('fs');
// 定义配置接口
interface CosConfig {
Bucket?: string;
Region?: string;
Prefix?: string;
}
// 定义上传参数接口
interface PutObjectParam {
key: string;
buffer: fs.ReadStream | Buffer;
}
class CosUtil {
private cos;
private Bucket: string;
private Region: string;
private Prefix: string;
// 构造函数,初始化配置
constructor(config?: CosConfig) {
this.Bucket = config?.Bucket || 'mybucket-xxxxxx'; // 存储桶名称
this.Region = config?.Region || 'ap-guangzhou'; // 存储桶区域
this.Prefix = config?.Prefix || ''; // 路径前缀
// 初始化 COS 实例
this.cos = new COS({
SecretId: 'xxxxxx', // 密钥id
SecretKey: 'xxxxxx', // 密钥key
});
}
// 上传文件方法
public putObject(param: PutObjectParam): Promise<any> {
return new Promise((resolve, reject) => {
this.cos.putObject(
{
Bucket: this.Bucket, // 必须
Region: this.Region, // 必须
Key: param.key, // 必须
Body: param.buffer, // 必须
},
(err: Error, data: any) => {
if (err) {
reject(err);
return;
}
resolve(data);
}
);
});
}
// 提取图片链接中的图片名称
public getName(imageUrl: string): string {
// 解析 URL
const parsedUrl = new URL(imageUrl);
// 获取路径部分
const pathname = parsedUrl.pathname;
// 提取文件名
const imageName = pathname.split('/').pop() || '';
return imageName;
}
}
export default CosUtil;
- 修改上述目录下的
index.ts
文件:
typescript
// ... existing code ...
import CosUtil from './upload_cos';
// ... existing code ...
// 修改之前的上传文件代码
/**
* 上传文件
* @param ctx
* @param key 文件路径
*/
async upload(ctx: any) {
const { domain } = this.pluginInfo.config;
const uploadUtil = new CosUtil();
try {
const { key } = ctx.fields;
if (
key &&
(key.includes('..') ||
key.includes('./') ||
key.includes('\\') ||
key.includes('//'))
) {
throw new CoolCommException('非法的key值');
}
if (_.isEmpty(ctx.files)) {
throw new CoolCommException('上传文件为空');
}
const basePath = pUploadPath();
const file = ctx.files[0];
const extension = file.filename.split('.').pop();
const name =
moment().format('YYYYMMDD') + '/' + (key || `${uuid()}.${extension}`);
const target = path.join(basePath, name);
const dirPath = path.join(basePath, moment().format('YYYYMMDD'));
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
const data = fs.readFileSync(file.data);
fs.writeFileSync(target, data);
// 主要变动在这里,key:上传图片的名称(带后缀),buffer:图片的buffer
const cosResult = await uploadUtil.putObject({
key: name,
buffer: data,
});
return `https://${cosResult.Location}`;
} catch (err) {
console.error(err);
throw new CoolCommException('上传失败' + err.message);
}
}
通过以上修改,原来的upload方法及前端组建调用上传方法会得到返回的腾讯云cos存储桶中图片的访问地址,add接口也会把该地址存储到数据库中。
此时admin-node/src/modules/plugin/config.ts
中domain
参数将会失效
json
// 基础插件配置
hooks: {
// 文件上传
upload: {
// 地址前缀
domain: ``,
},
},