mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-29 16:22:50 +00:00
* feat(marketplace): update plugin/ download count statistic (#5957) * feat: download count * feat: update ui * fix: ui * chore: update sdk verison * chore: update .env.template * chore: adjust * chore: remove console.log * chore: adjust * Update projects/marketplace/src/pages/index.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update projects/marketplace/src/pages/index.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update projects/app/src/pages/config/tool/marketplace.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: update refresh; feat: marketplace download count per hour --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * download * marketplace code * fix: ui (#5963) * feat: support dataset and files as global variables (#5961) * json & dataset * file * fix file var * fix * fix init * remove * perf: file vars * fix: file uploading errors (#5969) * fix: file uploading errors * fix build * perf: fileselector ux * feat: integrate S3 for dataset with compatibility (#5941) * fix: text split * remove test * feat: integrate S3 for dataset with compatibility * fix: delay s3 files delete timing * fix: remove imageKeys * fix: remove parsed images' TTL * fix: improve codes by pr comments --------- Co-authored-by: archer <545436317@qq.com> * remove log * perf: request limit * chore: s3 migration script (#5971) * test * perf: s3 code * fix: migration script (#5972) * perf: s3 move object * wip: fix s3 bugs (#5976) * fix: incorrect replace origin logic (#5978) * fix: add downloadURL (#5980) * perf: file variable ttl & quick create dataset with temp s3 bucket (#5973) * perf: file variable ttl & quick create dataset with temp s3 bucket * fix * plugin & form input variables (#5979) * plugin & form input variables * fix * docs: 4143.mdx (#5981) * doc: update 4143.mdx (#5982) * fix form input file ttl (#5983) * trans file type (#5986) * trans file type * fix * fix: S3 script early return (#5985) * fix: S3 script typeof * fix: truncate large filename to fit S3 name * perf(permission): add a schema verification for resource permission, tmbId, groupId, orgId should be set at least one of them (#5987) * fix: version & typo (#5988) * fix-v4.14.3 (#5991) * fix: empty alt make replace JWT failed & incorrect image dataset preview url (#5989) * fix: empty alt make replace JWT failed & incorrect image dataset preview url * fix: s3 files recovery script * fix: incorrect chat external url parsing (#5993) --------- Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: heheer <heheer@sealos.io> Co-authored-by: Roy <whoeverimf5@gmail.com>
54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
/* 基于 Team 的限流 */
|
|
import { getGlobalRedisConnection } from '../../common/redis';
|
|
import { jsonRes } from '../../common/response';
|
|
import type { NextApiResponse } from 'next';
|
|
|
|
export enum LimitTypeEnum {
|
|
chat = 'chat'
|
|
}
|
|
const limitMap = {
|
|
[LimitTypeEnum.chat]: {
|
|
seconds: 60,
|
|
limit: Number(process.env.CHAT_MAX_QPM || 5000)
|
|
}
|
|
};
|
|
|
|
type FrequencyLimitOption = {
|
|
teamId: string;
|
|
type: LimitTypeEnum;
|
|
res: NextApiResponse;
|
|
};
|
|
|
|
export const teamFrequencyLimit = async ({ teamId, type, res }: FrequencyLimitOption) => {
|
|
const { seconds, limit } = limitMap[type];
|
|
const redis = getGlobalRedisConnection();
|
|
const key = `frequency:${type}:${teamId}`;
|
|
|
|
const result = await redis
|
|
.multi()
|
|
.incr(key)
|
|
.expire(key, seconds, 'NX') // 只在key不存在时设置过期时间
|
|
.exec();
|
|
|
|
if (!result) {
|
|
return Promise.reject(new Error('Redis connection error'));
|
|
}
|
|
|
|
const currentCount = result[0][1] as number;
|
|
|
|
if (currentCount > limit) {
|
|
const remainingTime = await redis.ttl(key);
|
|
jsonRes(res, {
|
|
code: 429,
|
|
error: `Rate limit exceeded. Maximum ${limit} requests per ${seconds} seconds for this team. Please try again in ${remainingTime} seconds.`
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// 在响应头中添加限流信息
|
|
res.setHeader('X-RateLimit-Limit', limit);
|
|
res.setHeader('X-RateLimit-Remaining', Math.max(0, limit - currentCount));
|
|
res.setHeader('X-RateLimit-Reset', Date.now() + seconds * 1000);
|
|
return true;
|
|
};
|