oa_based/src/modules/netdisk/manager/manage.service.ts

795 lines
26 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { isEmpty } from 'lodash';
import { ConfigKeyPaths } from '~/config';
import { generateRandomValue } from '~/utils';
import { SFileInfo, SFileInfoDetail, SFileList } from './manage.class';
import { InjectMinio } from 'nestjs-minio';
import { Client } from 'minio';
@Injectable()
export class NetDiskManageService {
private get ossConfig() {
return this.configService.get('oss', { infer: true });
}
constructor(
private configService: ConfigService<ConfigKeyPaths>,
@InjectMinio() private readonly minioClient: Client
) {}
/**
* 获取文件列表
* @param prefix 当前文件夹路径,搜索模式下会被忽略
* @param marker 下一页标识
* @returns iFileListResult
*/
async getFileList(prefix = '', marker = '', skey = ''): Promise<SFileList> {
// 是否需要搜索
const searching = !isEmpty(skey);
return new Promise<SFileList>((resolve, reject) => {
try {
const fileStream = this.minioClient.listObjects(this.ossConfig.bucket, prefix, false);
this.readStreamData<any>(fileStream).then(respBody => {
console.log(respBody);
const dirs = respBody.filter(item => 'prefix' in item).map(item => item.prefix);
const files = respBody.filter(item => !('prefix' in item));
// 如果这个nextMarker不为空那么还有未列举完毕的文件列表下次调用listPrefix的时候
// 指定options里面的marker为这个值
const fileList: SFileInfo[] = [];
// 处理目录,但只有非搜索模式下可用
if (!searching && !isEmpty(dirs)) {
// dir
for (const dirPath of dirs) {
const name = (dirPath as string).substr(0, dirPath.length - 1).replace(prefix, '');
if (isEmpty(skey) || name.includes(skey)) {
fileList.push({
name: (dirPath as string).substr(0, dirPath.length - 1).replace(prefix, ''),
type: 'dir',
id: generateRandomValue(10)
});
}
}
}
// handle items
if (!isEmpty(files)) {
// file
for (const item of files) {
// 搜索模式下处理
// if (searching) {
// const pathList: string[] = item.key.split(NETDISK_DELIMITER);
// // dir is empty stirng, file is key string
// const name = pathList.pop();
// if (
// item.key.endsWith(NETDISK_DELIMITER) &&
// pathList[pathList.length - 1].includes(skey)
// ) {
// // 结果是目录
// const ditName = pathList.pop();
// fileList.push({
// id: generateRandomValue(10),
// name: ditName,
// type: 'dir',
// belongTo: pathList.join(NETDISK_DELIMITER)
// });
// } else if (name.includes(skey)) {
// // 文件
// fileList.push({
// id: generateRandomValue(10),
// name,
// type: 'file',
// fsize: item.fsize,
// mimeType: item.mimeType,
// putTime: new Date(Number.parseInt(item.putTime) / 10000),
// belongTo: pathList.join(NETDISK_DELIMITER)
// });
// }
// } else {
// 正常获取列表
const fileKey = item.name.replace(prefix, '') as string;
if (!isEmpty(fileKey)) {
fileList.push({
id: generateRandomValue(10),
name: fileKey,
type: 'file',
fsize: `${item.size || 0}`,
mimeType: item.name.split('.').pop(),
putTime: new Date(item.lastModified)
});
// }
}
}
}
resolve({
list: fileList
// marker: respBody.marker || null
});
});
} catch (e) {
reject(e);
}
});
}
/**
* 获取文件信息
*/
async getFileInfo(name: string, path: string): Promise<SFileInfoDetail> {
const respBody = await this.minioClient.statObject(this.ossConfig.bucket, `${path}${name}`);
const detailInfo: SFileInfoDetail = {
fsize: respBody.size,
hash: respBody.metaData.hash || '',
md5: respBody.metaData.md5 || '',
mimeType: respBody.metaData['content-type'],
putTime: new Date(respBody.lastModified)
};
return detailInfo;
}
// /**
// * 修改文件MimeType
// */
// async changeFileHeaders(
// name: string,
// path: string,
// headers: { [k: string]: string }
// ): Promise<void> {
// return new Promise((resolve, reject) => {
// this.bucketManager.changeHeaders(
// this.qiniuConfig.bucket,
// `${path}${name}`,
// headers,
// (err, _, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// resolve();
// } else {
// reject(
// new Error(`Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`)
// );
// }
// }
// );
// });
// }
// /**
// * 创建文件夹
// * @returns true创建成功
// */
// async createDir(dirName: string): Promise<void> {
// const safeDirName = dirName.endsWith('/') ? dirName : `${dirName}/`;
// return new Promise((resolve, reject) => {
// // 上传一个空文件以用于显示文件夹效果
// const formUploader = new qiniu.form_up.FormUploader(this.config);
// const putExtra = new qiniu.form_up.PutExtra();
// formUploader.put(
// this.createUploadToken(''),
// safeDirName,
// ' ',
// putExtra,
// (respErr, respBody, respInfo) => {
// if (respErr) {
// reject(respErr);
// return;
// }
// if (respInfo.statusCode === 200) {
// resolve();
// } else {
// reject(
// new Error(`Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`)
// );
// }
// }
// );
// });
// }
// /**
// * 检查文件是否存在,同可检查目录
// */
// async checkFileExist(filePath: string): Promise<boolean> {
// return new Promise((resolve, reject) => {
// // fix path end must a /
// // 检测文件夹是否存在
// this.bucketManager.stat(this.qiniuConfig.bucket, filePath, (respErr, respBody, respInfo) => {
// if (respErr) {
// reject(respErr);
// return;
// }
// if (respInfo.statusCode === 200) {
// // 文件夹存在
// resolve(true);
// } else if (respInfo.statusCode === 612) {
// // 文件夹不存在
// resolve(false);
// } else {
// reject(
// new Error(`Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`)
// );
// }
// });
// });
// }
// /**
// * 创建Upload Token, 默认过期时间一小时
// * @returns upload token
// */
// createUploadToken(endUser: string): string {
// const policy = new qiniu.rs.PutPolicy({
// scope: this.qiniuConfig.bucket,
// insertOnly: 1,
// fsizeLimit: 1024 ** 2 * 10,
// endUser
// });
// const uploadToken = policy.uploadToken(this.mac);
// return uploadToken;
// }
// /**
// * 重命名文件
// * @param dir 文件路径
// * @param name 文件名称
// */
// async renameFile(dir: string, name: string, toName: string): Promise<void> {
// const fileName = `${dir}${name}`;
// const toFileName = `${dir}${toName}`;
// const op = {
// force: true
// };
// return new Promise((resolve, reject) => {
// this.bucketManager.move(
// this.qiniuConfig.bucket,
// fileName,
// this.qiniuConfig.bucket,
// toFileName,
// op,
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// } else {
// if (respInfo.statusCode === 200) {
// resolve();
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`
// )
// );
// }
// }
// }
// );
// });
// }
// /**
// * 移动文件
// */
// async moveFile(dir: string, toDir: string, name: string): Promise<void> {
// const fileName = `${dir}${name}`;
// const toFileName = `${toDir}${name}`;
// const op = {
// force: true
// };
// return new Promise((resolve, reject) => {
// this.bucketManager.move(
// this.qiniuConfig.bucket,
// fileName,
// this.qiniuConfig.bucket,
// toFileName,
// op,
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// } else {
// if (respInfo.statusCode === 200) {
// resolve();
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`
// )
// );
// }
// }
// }
// );
// });
// }
// /**
// * 复制文件
// */
// async copyFile(dir: string, toDir: string, name: string): Promise<void> {
// const fileName = `${dir}${name}`;
// // 拼接文件名
// const ext = extname(name);
// const bn = basename(name, ext);
// const toFileName = `${toDir}${bn}${NETDISK_COPY_SUFFIX}${ext}`;
// const op = {
// force: true
// };
// return new Promise((resolve, reject) => {
// this.bucketManager.copy(
// this.qiniuConfig.bucket,
// fileName,
// this.qiniuConfig.bucket,
// toFileName,
// op,
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// } else {
// if (respInfo.statusCode === 200) {
// resolve();
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`
// )
// );
// }
// }
// }
// );
// });
// }
// /**
// * 重命名文件夹
// */
// async renameDir(path: string, name: string, toName: string): Promise<void> {
// const dirName = `${path}${name}`;
// const toDirName = `${path}${toName}`;
// let hasFile = true;
// let marker = '';
// const op = {
// force: true
// };
// const bucketName = this.qiniuConfig.bucket;
// while (hasFile) {
// await new Promise<void>((resolve, reject) => {
// // 列举当前目录下的所有文件
// this.bucketManager.listPrefix(
// this.qiniuConfig.bucket,
// {
// prefix: dirName,
// limit: NETDISK_HANDLE_MAX_ITEM,
// marker
// },
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// const moveOperations = respBody.items.map(item => {
// const { key } = item;
// const destKey = key.replace(dirName, toDirName);
// return qiniu.rs.moveOp(bucketName, key, bucketName, destKey, op);
// });
// this.bucketManager.batch(moveOperations, (err2, respBody2, respInfo2) => {
// if (err2) {
// reject(err2);
// return;
// }
// if (respInfo2.statusCode === 200) {
// if (isEmpty(respBody.marker)) hasFile = false;
// else marker = respBody.marker;
// resolve();
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo2.statusCode}, Info: ${respInfo2.statusMessage}`
// )
// );
// }
// });
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`
// )
// );
// }
// }
// );
// });
// }
// }
// /**
// * 获取七牛下载的文件url链接
// * @param key 文件路径
// * @returns 连接
// */
getDownloadLink(key: string): Promise<string> {
return new Promise((resolve, reject) => {
if (this.ossConfig.access === 'public') {
this.minioClient.presignedUrl(
'GET',
this.ossConfig.bucket,
key,
24 * 60 * 60,
(err, presignedUrl) => {
if (err) reject();
resolve(presignedUrl);
}
);
} else if (this.ossConfig.access === 'private') {
// return this.bucketManager.privateDownloadUrl(
// this.qiniuConfig.domain,
// key,
// Date.now() / 1000 + 36000
// );
}
});
}
// /**
// * 删除文件
// * @param dir 删除的文件夹目录
// * @param name 文件名
// */
// async deleteFile(dir: string, name: string): Promise<void> {
// return new Promise((resolve, reject) => {
// this.bucketManager.delete(
// this.qiniuConfig.bucket,
// `${dir}${name}`,
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// resolve();
// } else {
// reject(
// new Error(`Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`)
// );
// }
// }
// );
// });
// }
// /**
// * 删除文件夹
// * @param dir 文件夹所在的上级目录
// * @param name 文件目录名称
// */
// async deleteMultiFileOrDir(fileList: FileOpItem[], dir: string): Promise<void> {
// const files = fileList.filter(item => item.type === 'file');
// if (files.length > 0) {
// // 批处理文件
// const copyOperations = files.map(item => {
// const fileName = `${dir}${item.name}`;
// return qiniu.rs.deleteOp(this.qiniuConfig.bucket, fileName);
// });
// await new Promise<void>((resolve, reject) => {
// this.bucketManager.batch(copyOperations, (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// resolve();
// } else if (respInfo.statusCode === 298) {
// reject(new Error('操作异常,但部分文件夹删除成功'));
// } else {
// reject(
// new Error(`Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`)
// );
// }
// });
// });
// }
// // 处理文件夹
// const dirs = fileList.filter(item => item.type === 'dir');
// if (dirs.length > 0) {
// // 处理文件夹的复制
// for (let i = 0; i < dirs.length; i++) {
// const dirName = `${dir}${dirs[i].name}/`;
// let hasFile = true;
// let marker = '';
// while (hasFile) {
// await new Promise<void>((resolve, reject) => {
// // 列举当前目录下的所有文件
// this.bucketManager.listPrefix(
// this.qiniuConfig.bucket,
// {
// prefix: dirName,
// limit: NETDISK_HANDLE_MAX_ITEM,
// marker
// },
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// const moveOperations = respBody.items.map(item => {
// const { key } = item;
// return qiniu.rs.deleteOp(this.qiniuConfig.bucket, key);
// });
// this.bucketManager.batch(moveOperations, (err2, respBody2, respInfo2) => {
// if (err2) {
// reject(err2);
// return;
// }
// if (respInfo2.statusCode === 200) {
// if (isEmpty(respBody.marker)) hasFile = false;
// else marker = respBody.marker;
// resolve();
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo2.statusCode}, Info: ${respInfo2.statusMessage}`
// )
// );
// }
// });
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`
// )
// );
// }
// }
// );
// });
// }
// }
// }
// }
// /**
// * 复制文件,含文件夹
// */
// async copyMultiFileOrDir(fileList: FileOpItem[], dir: string, toDir: string): Promise<void> {
// const files = fileList.filter(item => item.type === 'file');
// const op = {
// force: true
// };
// if (files.length > 0) {
// // 批处理文件
// const copyOperations = files.map(item => {
// const fileName = `${dir}${item.name}`;
// // 拼接文件名
// const ext = extname(item.name);
// const bn = basename(item.name, ext);
// const toFileName = `${toDir}${bn}${NETDISK_COPY_SUFFIX}${ext}`;
// return qiniu.rs.copyOp(
// this.qiniuConfig.bucket,
// fileName,
// this.qiniuConfig.bucket,
// toFileName,
// op
// );
// });
// await new Promise<void>((resolve, reject) => {
// this.bucketManager.batch(copyOperations, (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// resolve();
// } else if (respInfo.statusCode === 298) {
// reject(new Error('操作异常,但部分文件夹删除成功'));
// } else {
// reject(
// new Error(`Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`)
// );
// }
// });
// });
// }
// // 处理文件夹
// const dirs = fileList.filter(item => item.type === 'dir');
// if (dirs.length > 0) {
// // 处理文件夹的复制
// for (let i = 0; i < dirs.length; i++) {
// const dirName = `${dir}${dirs[i].name}/`;
// const copyDirName = `${toDir}${dirs[i].name}${NETDISK_COPY_SUFFIX}/`;
// let hasFile = true;
// let marker = '';
// while (hasFile) {
// await new Promise<void>((resolve, reject) => {
// // 列举当前目录下的所有文件
// this.bucketManager.listPrefix(
// this.qiniuConfig.bucket,
// {
// prefix: dirName,
// limit: NETDISK_HANDLE_MAX_ITEM,
// marker
// },
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// const moveOperations = respBody.items.map(item => {
// const { key } = item;
// const destKey = key.replace(dirName, copyDirName);
// return qiniu.rs.copyOp(
// this.qiniuConfig.bucket,
// key,
// this.qiniuConfig.bucket,
// destKey,
// op
// );
// });
// this.bucketManager.batch(moveOperations, (err2, respBody2, respInfo2) => {
// if (err2) {
// reject(err2);
// return;
// }
// if (respInfo2.statusCode === 200) {
// if (isEmpty(respBody.marker)) hasFile = false;
// else marker = respBody.marker;
// resolve();
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo2.statusCode}, Info: ${respInfo2.statusMessage}`
// )
// );
// }
// });
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`
// )
// );
// }
// }
// );
// });
// }
// }
// }
// }
// /**
// * 移动文件,含文件夹
// */
// async moveMultiFileOrDir(fileList: FileOpItem[], dir: string, toDir: string): Promise<void> {
// const files = fileList.filter(item => item.type === 'file');
// const op = {
// force: true
// };
// if (files.length > 0) {
// // 批处理文件
// const copyOperations = files.map(item => {
// const fileName = `${dir}${item.name}`;
// const toFileName = `${toDir}${item.name}`;
// return qiniu.rs.moveOp(
// this.qiniuConfig.bucket,
// fileName,
// this.qiniuConfig.bucket,
// toFileName,
// op
// );
// });
// await new Promise<void>((resolve, reject) => {
// this.bucketManager.batch(copyOperations, (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// resolve();
// } else if (respInfo.statusCode === 298) {
// reject(new Error('操作异常,但部分文件夹删除成功'));
// } else {
// reject(
// new Error(`Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`)
// );
// }
// });
// });
// }
// // 处理文件夹
// const dirs = fileList.filter(item => item.type === 'dir');
// if (dirs.length > 0) {
// // 处理文件夹的复制
// for (let i = 0; i < dirs.length; i++) {
// const dirName = `${dir}${dirs[i].name}/`;
// const toDirName = `${toDir}${dirs[i].name}/`;
// // 移动的目录不是是自己
// if (toDirName.startsWith(dirName)) continue;
// let hasFile = true;
// let marker = '';
// while (hasFile) {
// await new Promise<void>((resolve, reject) => {
// // 列举当前目录下的所有文件
// this.bucketManager.listPrefix(
// this.qiniuConfig.bucket,
// {
// prefix: dirName,
// limit: NETDISK_HANDLE_MAX_ITEM,
// marker
// },
// (err, respBody, respInfo) => {
// if (err) {
// reject(err);
// return;
// }
// if (respInfo.statusCode === 200) {
// const moveOperations = respBody.items.map(item => {
// const { key } = item;
// const destKey = key.replace(dirName, toDirName);
// return qiniu.rs.moveOp(
// this.qiniuConfig.bucket,
// key,
// this.qiniuConfig.bucket,
// destKey,
// op
// );
// });
// this.bucketManager.batch(moveOperations, (err2, respBody2, respInfo2) => {
// if (err2) {
// reject(err2);
// return;
// }
// if (respInfo2.statusCode === 200) {
// if (isEmpty(respBody.marker)) hasFile = false;
// else marker = respBody.marker;
// resolve();
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo2.statusCode}, Info: ${respInfo2.statusMessage}`
// )
// );
// }
// });
// } else {
// reject(
// new Error(
// `Qiniu Error Code: ${respInfo.statusCode}, Info: ${respInfo.statusMessage}`
// )
// );
// }
// }
// );
// });
// }
// }
// }
// }
/**
*
* @param stream 文件流
* @returns []
*/
readStreamData<T>(stream): Promise<T[]> {
return new Promise((resolve, reject) => {
const result: T[] = [];
stream
.on('data', function (row) {
result.push(row);
})
.on('end', function () {
resolve(result);
})
.on('error', function (error) {
reject(error);
});
});
}
}