mirror of
https://github.com/certd/certd.git
synced 2026-04-24 12:27:25 +08:00
feat: 站点个性化设置
This commit is contained in:
+1
@@ -1 +1,2 @@
|
||||
export * from './service/plus-service.js';
|
||||
export * from './service/file-service.js';
|
||||
@@ -0,0 +1,86 @@
|
||||
import { Provide } from '@midwayjs/core';
|
||||
import dayjs from 'dayjs';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { cache, logger, utils } from '@certd/pipeline';
|
||||
import { NotFoundException, ParamException, PermissionException } from '../../../basic/index.js';
|
||||
|
||||
export type UploadFileItem = {
|
||||
filename: string;
|
||||
tmpFilePath: string;
|
||||
};
|
||||
const uploadRootDir = './data/upload';
|
||||
export const uploadTmpFileCacheKey = 'tmpfile_key_';
|
||||
/**
|
||||
*/
|
||||
@Provide()
|
||||
export class FileService {
|
||||
async saveFile(userId: number, tmpCacheKey: any, permission: 'public' | 'private') {
|
||||
if (tmpCacheKey.startsWith(`/${permission}`)) {
|
||||
//已经保存过,不需要再次保存
|
||||
return tmpCacheKey;
|
||||
}
|
||||
let fileName = '';
|
||||
let tmpFilePath = tmpCacheKey;
|
||||
if (uploadTmpFileCacheKey && tmpCacheKey.startsWith(uploadTmpFileCacheKey)) {
|
||||
const tmpFile: UploadFileItem = cache.get(tmpCacheKey);
|
||||
if (!tmpFile) {
|
||||
throw new ParamException('文件已过期,请重新上传');
|
||||
}
|
||||
tmpFilePath = tmpFile.tmpFilePath;
|
||||
fileName = tmpFile.filename || path.basename(tmpFilePath);
|
||||
}
|
||||
if (!tmpFilePath || !fs.existsSync(tmpFilePath)) {
|
||||
throw new Error('文件不存在,请重新上传');
|
||||
}
|
||||
const date = dayjs().format('YYYY_MM_DD');
|
||||
const random = Math.random().toString(36).substring(7);
|
||||
const userIdMd5 = Buffer.from(Buffer.from(userId + '').toString('base64')).toString('hex');
|
||||
const key = `/${permission}/${userIdMd5}/${date}/${random}_${fileName}`;
|
||||
let savePath = path.join(uploadRootDir, key);
|
||||
savePath = path.resolve(savePath);
|
||||
const parentDir = path.dirname(savePath);
|
||||
if (!fs.existsSync(parentDir)) {
|
||||
fs.mkdirSync(parentDir, { recursive: true });
|
||||
}
|
||||
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||
const copyFile = utils.promises.promisify(fs.copyFile);
|
||||
await copyFile(tmpFilePath, savePath);
|
||||
try {
|
||||
fs.unlinkSync(tmpFilePath);
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
getFile(key: string, userId?: number) {
|
||||
if (!key) {
|
||||
throw new ParamException('参数错误');
|
||||
}
|
||||
if (key.indexOf('..') >= 0) {
|
||||
//安全性判断
|
||||
throw new ParamException('参数错误');
|
||||
}
|
||||
if (!key.startsWith('/')) {
|
||||
throw new ParamException('参数错误');
|
||||
}
|
||||
const keyArr = key.split('/');
|
||||
const permission = keyArr[1];
|
||||
const userIdMd5 = keyArr[2];
|
||||
if (permission !== 'public') {
|
||||
//非公开文件需要验证用户
|
||||
const userIdStr = Buffer.from(Buffer.from(userIdMd5, 'hex').toString('base64')).toString();
|
||||
const userIdInt: number = parseInt(userIdStr, 10);
|
||||
if (userId == null || userIdInt !== userId) {
|
||||
throw new PermissionException('无访问权限');
|
||||
}
|
||||
}
|
||||
const filePath = path.join(uploadRootDir, key);
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new NotFoundException('文件不存在');
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './settings/index.js';
|
||||
export * from './plus/index.js';
|
||||
export * from './basic/index.js';
|
||||
|
||||
@@ -52,4 +52,5 @@ export class SysSiteInfo extends BaseSettings {
|
||||
title?: string;
|
||||
slogan?: string;
|
||||
logo?: string;
|
||||
loginLogo?: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user