mirror of
https://github.com/certd/certd.git
synced 2026-04-26 05:37:25 +08:00
feat: 站点个性化设置
This commit is contained in:
@@ -44,6 +44,14 @@ export const Constants = {
|
||||
code: 402,
|
||||
message: '您没有权限',
|
||||
},
|
||||
param: {
|
||||
code: 400,
|
||||
message: '参数错误',
|
||||
},
|
||||
notFound: {
|
||||
code: 404,
|
||||
message: '页面/文件/资源不存在',
|
||||
},
|
||||
preview: {
|
||||
code: 10001,
|
||||
message: '对不起,预览环境不允许修改此数据',
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
export * from './auth-exception.js'
|
||||
export * from './base-exception.js'
|
||||
export * from './permission-exception.js'
|
||||
export * from './preview-exception.js'
|
||||
export * from './validation-exception.js'
|
||||
export * from './vip-exception.js'
|
||||
export * from './common-exception.js'
|
||||
export * from './auth-exception.js';
|
||||
export * from './base-exception.js';
|
||||
export * from './permission-exception.js';
|
||||
export * from './preview-exception.js';
|
||||
export * from './validation-exception.js';
|
||||
export * from './vip-exception.js';
|
||||
export * from './common-exception.js';
|
||||
export * from './not-found-exception.js';
|
||||
export * from './param-exception.js';
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 资源不存在
|
||||
*/
|
||||
export class NotFoundException extends BaseException {
|
||||
constructor(message) {
|
||||
super('NotFoundException', Constants.res.notFound.code, message ? message : Constants.res.notFound.message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Constants } from '../constants.js';
|
||||
import { BaseException } from './base-exception.js';
|
||||
/**
|
||||
* 参数异常
|
||||
*/
|
||||
export class ParamException extends BaseException {
|
||||
constructor(message) {
|
||||
super('ParamException', Constants.res.param.code, message ? message : Constants.res.param.message);
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,6 @@ import { BaseException } from './base-exception.js';
|
||||
*/
|
||||
export class PermissionException extends BaseException {
|
||||
constructor(message?: string) {
|
||||
super(
|
||||
'PermissionException',
|
||||
Constants.res.permission.code,
|
||||
message ? message : Constants.res.permission.message
|
||||
);
|
||||
super('PermissionException', Constants.res.permission.code, message ? message : Constants.res.permission.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@ import { BaseException } from './base-exception.js';
|
||||
*/
|
||||
export class ValidateException extends BaseException {
|
||||
constructor(message) {
|
||||
super(
|
||||
'ValidateException',
|
||||
Constants.res.validation.code,
|
||||
message ? message : Constants.res.validation.message
|
||||
);
|
||||
super('ValidateException', Constants.res.validation.code, message ? message : Constants.res.validation.message);
|
||||
}
|
||||
}
|
||||
|
||||
+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