feat: 优化项目目录结构

This commit is contained in:
2025-12-12 17:25:26 +08:00
parent ae627d0496
commit b89f83291e
235 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { OssController } from './oss.controller';
describe('OssController', () => {
let controller: OssController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [OssController],
}).compile();
controller = module.get<OssController>(OssController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@@ -0,0 +1,18 @@
import { Controller, Get, Request, UseGuards } from '@nestjs/common';
import { OssService } from './oss.service';
import { AuthGuard } from '@nestjs/passport';
@Controller('oss')
export class OssController {
constructor(private readonly ossService: OssService) {}
@UseGuards(AuthGuard('jwt'))
@Get('sts')
async getStsToken(@Request() req) {
const { userId } = req.user;
return {
...(await this.ossService.getStsToken(`${userId}`)),
userId,
};
}
}

View File

@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { OssService } from './oss.service';
import { OssController } from './oss.controller';
@Module({
providers: [OssService],
controllers: [OssController],
})
export class OssModule {}

View File

@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { OssService } from './oss.service';
describe('OssService', () => {
let service: OssService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [OssService],
}).compile();
service = module.get<OssService>(OssService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@@ -0,0 +1,53 @@
import { Injectable } from '@nestjs/common';
import { STS } from 'ali-oss';
@Injectable()
export class OssService {
private sts = new STS({
accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID,
accessKeySecret: process.env.ALIYUN_ACCESS_KEY_SECRET,
});
private stsCache: {
[session: string]: {
credentials: {
AccessKeyId: string;
AccessKeySecret: string;
SecurityToken: string;
Expiration: string;
};
expireTime: number; // 时间戳,单位为毫秒
};
} = {};
/** @todo 该方法存在缓存穿透问题,待优化 */
async getStsToken(session: string) {
if (this.stsCache[session]) {
const cached = this.stsCache[session];
// 检查缓存是否过期
if (cached.expireTime > Date.now()) {
return cached.credentials;
} else {
// 如果过期,删除缓存
delete this.stsCache[session];
}
}
return this.sts
.assumeRole(process.env.ALIYUN_OSS_STS_ROLE_ARN, ``, 3600, `${session}`)
.then((res) => {
// 缓存
this.stsCache[session] = {
credentials: res.credentials,
expireTime:
new Date(res.credentials.Expiration).getTime() - 5 * 60 * 1000, // 提前5分钟过期,
};
return res.credentials;
})
.catch((err) => {
console.error('获取STS Token失败:', err);
throw new Error('获取STS Token失败');
});
}
}