Files
FastGPT/packages/service/common/s3/sources/avatar.ts
T
Archer d571c768ea V4.14.1 feature (#5880)
* feat: app split (#5858)

* feat: app split script

* fix: app split

* chore: app split script try-catch

* adjust dashborad page (#5872)

* create page

* create page

* create button

* router name

* bot

* template

* create page

* mobile

* toolfolder

* fix

* fix

* fix build

* split tool select

* img

* doc

* rename enum

* fix page adjust (#5883)

* fix page adjust

* fix ad store

* fix: initv4141 (#5886)

* fix: create app

* doc

* hide api

* doc

* feat: payment pause interactive (#5892)

* fix: copy clbs (#5889)

* fix: copy clbs

* fix: copy clbs

* fix: http protocol handling in baseURL (#5890)

* fix: http protocol handling in baseURL

* ui fix

* auto saved version

* fix

* auto save

* fix: model permission modal (#5895)

* folder

* fix: del app

* navbar

* fix: plugin file selector (#5893)

* fix: plugin file selector

* fix: plugin file selector

* workflow tool inputform

* pick

---------

Co-authored-by: archer <545436317@qq.com>

* fix: workflow tool time

* doc

* fix workorder button (#5896)

* add inform track (#5897)

* remove invalid track

* comment

* feat: marketplace refresh api (#5884)

* marketplace refresh

* fix: helper bot menu button (#5898)

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
Co-authored-by: 伍闲犬 <whoeverimf5@gmail.com>
2025-11-11 14:05:02 +08:00

91 lines
2.2 KiB
TypeScript

import { S3Sources } from '../type';
import { MongoS3TTL } from '../schema';
import { S3PublicBucket } from '../buckets/public';
import { imageBaseUrl } from '@fastgpt/global/common/file/image/constants';
import type { ClientSession } from 'mongoose';
class S3AvatarSource {
private bucket: S3PublicBucket;
private static instance: S3AvatarSource;
constructor() {
this.bucket = new S3PublicBucket();
}
static getInstance() {
return (this.instance ??= new S3AvatarSource());
}
get prefix(): string {
return imageBaseUrl;
}
async createUploadAvatarURL({
filename,
teamId,
autoExpired = true
}: {
filename: string;
teamId: string;
autoExpired?: boolean;
}) {
return this.bucket.createPostPresignedUrl(
{ filename, teamId, source: S3Sources.avatar },
{
expiredHours: autoExpired ? 1 : undefined, // 1 Hours
maxFileSize: 5 // 5MB
}
);
}
createPublicUrl(objectKey: string): string {
return this.bucket.createPublicUrl(objectKey);
}
async removeAvatarTTL(avatar: string, session?: ClientSession): Promise<void> {
const key = avatar.slice(this.prefix.length);
await MongoS3TTL.deleteOne({ minioKey: key, bucketName: this.bucket.name }, session);
}
async deleteAvatar(avatar: string, session?: ClientSession): Promise<void> {
const key = avatar.slice(this.prefix.length);
await MongoS3TTL.deleteOne({ minioKey: key, bucketName: this.bucket.name }, session);
await this.bucket.delete(key);
}
async refreshAvatar(newAvatar?: string, oldAvatar?: string, session?: ClientSession) {
if (!newAvatar || newAvatar === oldAvatar) return;
// remove the TTL for the new avatar
await this.removeAvatarTTL(newAvatar, session);
if (oldAvatar) {
// delete the old avatar
// 1. delete the TTL record if it exists
// 2. delete the avatar in S3
await this.deleteAvatar(oldAvatar, session);
}
}
async copyAvatar({
sourceKey,
targetKey,
ttl
}: {
sourceKey: string;
targetKey: string;
ttl: boolean;
}) {
await this.bucket.copy({
src: sourceKey,
dst: targetKey,
ttl
});
return targetKey;
}
}
export function getS3AvatarSource() {
return S3AvatarSource.getInstance();
}