create-chuntianxiaozhu
Version:
春天小猪模板工具
249 lines (237 loc) • 7.19 kB
text/typescript
import * as qiniu from 'qiniu';
import * as fs from 'fs';
import { Logger } from '@nestjs/common';
import { v4 as uuidv4 } from 'uuid';
import * as COS from 'cos-nodejs-sdk-v5';
import * as STS from 'qcloud-cos-sts';
const getConfig = () => {
return {
secretId: process.env.OSS_SECRET_ID, // 固定密钥
secretKey: process.env.OSS_SECRET_KEY, // 固定密钥
durationSeconds: 1800,
// host: 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
endpoint: 'sts.tencentcloudapi.com', // 域名,非必须,与host二选一,默认为 sts.tencentcloudapi.com
// 放行判断相关参数
bucket: process.env.OSS_BUCKET,
region: process.env.OSS_REGION,
allowPrefix: 'image_resources/custom/*', // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
// 简单上传和分片,需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
allowActions: [
// 简单上传
'name/cos:PutObject',
'name/cos:PostObject',
],
};
};
/**
* getCos
* @returns
*/
let cos;
export function getCos() {
if (cos) {
return cos;
}
cos = new COS({
SecretId: process.env.OSS_SECRET_ID,
SecretKey: process.env.OSS_SECRET_KEY,
});
return cos;
}
let qiniuOssManager: qiniu.rs.BucketManager;
export function getQiniuOssManager() {
if (qiniuOssManager) {
return qiniuOssManager;
}
const mac = new qiniu.auth.digest.Mac(
process.env.QINIU_ACCESS_KEY,
process.env.QINIU_ACCESS_SECRET,
);
const config = new qiniu.conf.Config();
qiniuOssManager = new qiniu.rs.BucketManager(mac, config);
return qiniuOssManager;
}
/**
* 生成七牛云临时秘钥
*/
export function generateQiniuTempToken(key) {
qiniu.conf.ACCESS_KEY = process.env.QINIU_ACCESS_KEY;
qiniu.conf.SECRET_KEY = process.env.QINIU_ACCESS_SECRET;
const putPolicy = new qiniu.rs.PutPolicy({
scope: `${process.env.QINIU_BUCKET}:${key}`,
expires: 20,
});
return putPolicy.uploadToken();
}
export function removeQiniuFile(key) {
qiniu.conf.ACCESS_KEY = process.env.QINIU_ACCESS_KEY;
qiniu.conf.SECRET_KEY = process.env.QINIU_ACCESS_SECRET;
const ossManager = getQiniuOssManager();
return new Promise((resolve) => {
ossManager.delete(process.env.QINIU_BUCKET, key, (err) => {
resolve(!err);
});
});
}
export function uploadFile(token, key, filePath) {
const extra = new qiniu.form_up.PutExtra();
return new Promise((resolve, reject) => {
new qiniu.form_up.FormUploader().putFile(
token,
key,
filePath,
extra,
(err, ret) => {
if (!err) {
resolve(ret);
} else {
reject(err);
}
},
);
});
}
export function uploadTencentFile(key, filePath) {
const cos = getCos();
return cos.uploadFile({
Bucket: process.env.OSS_BUCKET /* 填入您自己的存储桶,必须字段 */,
Region:
process.env.OSS_REGION /* 存储桶所在地域,例如 ap-beijing,必须字段 */,
Key: key /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */,
FilePath: filePath,
});
}
export function uploadImageResource(
path: string,
initPath: string = '',
callback: Function,
) {
fs.readdir(path, (err, fileOrDirs) => {
if (!fileOrDirs) {
return;
}
fileOrDirs.forEach((fileOrDir) => {
const filePath = `${path}/${fileOrDir}`;
fs.stat(filePath, (err, file) => {
if (file.isDirectory()) {
uploadImageResource(filePath, initPath, callback);
} else {
const uniqueId = uuidv4();
const fileRelativePath = filePath.replace(initPath, '');
const fileName = fileRelativePath.slice(
fileRelativePath.lastIndexOf('/') + 1,
fileRelativePath.lastIndexOf('.'),
);
const replaceFileRelativePath = fileRelativePath.replace(
fileName,
uniqueId,
);
const key = `image_resources${replaceFileRelativePath}`;
uploadTencentFile(key, filePath)
.then(() => {
Logger.log(`${fileRelativePath}上传成功`);
fs.rmSync(filePath);
const filePaths = fileRelativePath.split('/');
const cName = filePaths[filePaths.length - 2];
callback(key, key, fileName, cName);
})
.catch(() => {
Logger.error(`${fileRelativePath}上传失败`);
});
}
});
});
});
}
export function uploadSceneImage(
path: string,
initPath: string = '',
callback: Function,
) {
fs.readdir(path, (err, fileOrDirs) => {
if (!fileOrDirs) {
return;
}
fileOrDirs.forEach((fileOrDir) => {
const filePath = `${path}/${fileOrDir}`;
fs.stat(filePath, (err, file) => {
if (file.isDirectory()) {
uploadSceneImage(filePath, initPath, callback);
} else {
const uniqueId = uuidv4();
const fileRelativePath = filePath.replace(initPath, '');
const fileName = fileRelativePath.slice();
const replaceFileRelativePath = fileRelativePath.replace(
fileName,
uniqueId,
);
const key = `image_resources/custom${replaceFileRelativePath}`;
uploadTencentFile(key, filePath)
.then(() => {
Logger.log(`${fileRelativePath}上传成功`);
fs.rmSync(filePath);
const filePaths = fileRelativePath.split('/');
const cName = filePaths[filePaths.length - 2];
callback(key, key, fileName, cName);
})
.catch(() => {
Logger.error(`${fileRelativePath}上传失败`);
});
}
});
});
});
}
/**
* 腾讯云对象存储生成临时秘钥
* @returns
*/
export async function generateTempToken() {
const config = getConfig();
// 获取临时密钥
const shortBucketName = config.bucket.substr(
0,
config.bucket.lastIndexOf('-'),
);
const appId = config.bucket.substr(1 + config.bucket.lastIndexOf('-'));
const policy = {
version: '2.0',
statement: [
{
action: config.allowActions,
effect: 'allow',
principal: { qcs: ['*'] },
resource: [
'qcs::cos:' +
config.region +
':uid/' +
appId +
':prefix//' +
appId +
'/' +
shortBucketName +
'/' +
config.allowPrefix,
],
},
],
};
return new Promise((resolve, reject) => {
STS.getCredential(
{
secretId: config.secretId,
secretKey: config.secretKey,
durationSeconds: config.durationSeconds,
endpoint: config.endpoint,
policy: policy,
},
function (err, tempKeys) {
if (err) {
reject(err);
} else {
resolve(tempKeys);
}
},
);
});
}