This commit is contained in:
vastxie
2024-03-15 17:40:19 +08:00
parent 4de54d8fec
commit 19254a8176
305 changed files with 8751 additions and 9416 deletions

View File

@@ -70,7 +70,7 @@ let AppService = class AppService {
demoData: demo ? demo.split('\n') : [],
coverImg,
des,
name
name,
};
}
async appCatsList(query) {

View File

@@ -34,7 +34,7 @@ __decorate([
__metadata("design:type", String)
], CreateAppDto.prototype, "des", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: '你现在是一个翻译官。接下来我说的所有话帮我翻译成中文', description: '预设的prompt', required: true }),
(0, swagger_1.ApiProperty)({ example: '你现在是一个翻译官。接下来我说的所有话帮我翻译成中文', description: '预设的prompt', required: false }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], CreateAppDto.prototype, "preset", void 0);

View File

@@ -30,7 +30,7 @@ const redisCache_module_1 = require("../redisCache/redisCache.module");
const userBalance_entity_1 = require("../userBalance/userBalance.entity");
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
const user_entity_1 = require("../user/user.entity");
const whiteList_entity_1 = require("../chatgpt/whiteList.entity");
const whiteList_entity_1 = require("../chat/whiteList.entity");
const fingerprint_entity_1 = require("../userBalance/fingerprint.entity");
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");

View File

@@ -225,7 +225,7 @@ let AuthService = class AuthService {
const token = this.jwtService.sign({
username: `游客${fingerprint}`,
id: fingerprint,
email: `${fingerprint}@nine.com`,
email: `${fingerprint}@visitor.com`,
role: 'visitor',
openId: null,
client: null,

View File

@@ -51,7 +51,7 @@ __decorate([
], UserRegisterDto.prototype, "invitedBy", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
example: 'https://public-1300678944.cos.ap-shanghai.myqcloud.com/blog/1682571295452image.png',
example: '',
description: '用户头像',
required: false,
}),

View File

@@ -12,92 +12,90 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatgptController = void 0;
const jwtAuth_guard_1 = require("./../../common/auth/jwtAuth.guard");
exports.ChatController = void 0;
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
const swagger_1 = require("@nestjs/swagger");
const chatgpt_service_1 = require("./chatgpt.service");
const chat_service_1 = require("./chat.service");
const common_1 = require("@nestjs/common");
const chatProcess_dto_1 = require("./dto/chatProcess.dto");
const chatDraw_dto_1 = require("./dto/chatDraw.dto");
const adminAuth_guard_1 = require("../../common/auth/adminAuth.guard");
const superAuth_guard_1 = require("../../common/auth/superAuth.guard");
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
let ChatgptController = class ChatgptController {
constructor(chatgptService, globalConfigService) {
this.chatgptService = chatgptService;
let ChatController = class ChatController {
constructor(chatService, globalConfigService) {
this.chatService = chatService;
this.globalConfigService = globalConfigService;
}
chatProcess(body, req, res) {
return this.chatgptService.chatProcess(body, req, res);
return this.chatService.chatProcess(body, req, res);
}
chatProcessSync(body, req) {
return this.chatgptService.chatProcess(Object.assign({}, body), req);
return this.chatService.chatProcess(Object.assign({}, body), req);
}
async mjAssociate(body, req) {
const mjCustomLianxiangPrompt = await this.globalConfigService.getConfigs(['mjCustomLianxiangPrompt']);
body.systemMessage =
mjCustomLianxiangPrompt ||
`midjourney是一款AI绘画工具只要你输入你想到的文字就能通过人工智能产出相对应的图片、我希望你作为MidJourney程序的提示词(prompt)生成器。你的工作是根据我给你的一段提示内容扩展为更详细和更有创意的描述以激发人工智能的独特和有趣的图像。请记住人工智能能够理解广泛的语言并能解释抽象的概念所以请自由发挥想象力和描述力尽可能地发挥。例如你可以描述一个未来城市的场景或一个充满奇怪生物的超现实景观。你的描述越详细、越有想象力产生的图像就越有趣、Midjourney prompt的标准公式为:(image we're prompting).(5 descriptivekeywords). (camera type). (camera lens type). (time of day)(style of photograph).(type offilm)、请记住这个公式后续统一使用该公式进行prompt生成、最终把我给你的提示变成一整段连续不分开的完整内容并且只需要用英文回复您的联想、一定不要回复别内容、包括解释、我只需要纯粹的内容。`;
return this.chatgptService.chatProcess(Object.assign(Object.assign({}, body), { cusromPrompt: true }), req);
ttsProcess(body, req, res) {
return this.chatService.ttsProcess(body, req, res);
}
async mjFanyi(body, req) {
const mjCustomFanyiPrompt = await this.globalConfigService.getConfigs(['mjCustomFanyiPrompt']);
const mjTranslatePrompt = await this.globalConfigService.getConfigs(['mjTranslatePrompt']);
body.model = 'translation-';
body.systemMessage =
mjCustomFanyiPrompt ||
mjTranslatePrompt ||
`接下来我会给你一些内容、我希望你帮我翻译成英文、不管我给你任何语言、你都回复我英文、如果给你了英文、依然回复我更加优化的英文、并且期望你不需要做任何多余的解释、给我英文即可、不要加任何东西、我只需要英文!`;
return this.chatgptService.chatProcess(Object.assign(Object.assign({}, body), { cusromPrompt: true }), req);
return this.chatService.chatProcess(Object.assign(Object.assign({}, body), { specialModel: true }), req);
}
async chatmind(body, req, res) {
const mindCustomPrompt = await this.globalConfigService.getConfigs(['mindCustomPrompt']);
body.model = 'mindmap-';
body.systemMessage =
mindCustomPrompt ||
`我希望你使用markdown格式回答我得问题、我的需求是得到一份markdown格式的大纲、尽量做的精细、层级多一点、不管我问你什么、都需要您回复我一个大纲出来、我想使用大纲做思维导图、除了大纲之外、不要无关内容和总结。`;
return this.chatgptService.chatProcess(Object.assign(Object.assign({}, body), { cusromPrompt: true }), req, res);
return this.chatService.chatProcess(Object.assign(Object.assign({}, body), { specialModel: true }), req, res);
}
async draw(body, req) {
return await this.chatgptService.draw(body, req);
return await this.chatService.draw(body, req);
}
async setChatBoxType(req, body) {
return await this.chatgptService.setChatBoxType(req, body);
return await this.chatService.setChatBoxType(req, body);
}
async delChatBoxType(req, body) {
return await this.chatgptService.delChatBoxType(req, body);
return await this.chatService.delChatBoxType(req, body);
}
async queryChatBoxType() {
return await this.chatgptService.queryChatBoxType();
return await this.chatService.queryChatBoxType();
}
async setChatBox(req, body) {
return await this.chatgptService.setChatBox(req, body);
return await this.chatService.setChatBox(req, body);
}
async delChatBox(req, body) {
return await this.chatgptService.delChatBox(req, body);
return await this.chatService.delChatBox(req, body);
}
async queryChatBox() {
return await this.chatgptService.queryChatBox();
return await this.chatService.queryChatBox();
}
async queryChatBoxFrontend() {
return await this.chatgptService.queryChatBoxFrontend();
return await this.chatService.queryChatBoxFrontend();
}
async setChatPreType(req, body) {
return await this.chatgptService.setChatPreType(req, body);
return await this.chatService.setChatPreType(req, body);
}
async delChatPreType(req, body) {
return await this.chatgptService.delChatPreType(req, body);
return await this.chatService.delChatPreType(req, body);
}
async queryChatPreType() {
return await this.chatgptService.queryChatPreType();
return await this.chatService.queryChatPreType();
}
async setChatPre(req, body) {
return await this.chatgptService.setChatPre(req, body);
return await this.chatService.setChatPre(req, body);
}
async delChatPre(req, body) {
return await this.chatgptService.delChatPre(req, body);
return await this.chatService.delChatPre(req, body);
}
async queryChatPre() {
return await this.chatgptService.queryChatPre();
return await this.chatService.queryChatPre();
}
async queryChatPreList() {
return await this.chatgptService.queryChatPreList();
return await this.chatService.queryChatPreList();
}
};
__decorate([
@@ -111,7 +109,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [chatProcess_dto_1.ChatProcessDto, Object, Object]),
__metadata("design:returntype", void 0)
], ChatgptController.prototype, "chatProcess", null);
], ChatController.prototype, "chatProcess", null);
__decorate([
(0, common_1.Post)('chat-sync'),
(0, swagger_1.ApiOperation)({ summary: 'gpt聊天对话' }),
@@ -122,18 +120,19 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [chatProcess_dto_1.ChatProcessDto, Object]),
__metadata("design:returntype", void 0)
], ChatgptController.prototype, "chatProcessSync", null);
], ChatController.prototype, "chatProcessSync", null);
__decorate([
(0, common_1.Post)('mj-associate'),
(0, swagger_1.ApiOperation)({ summary: 'gpt描述词绘画联想' }),
(0, common_1.Post)('tts-process'),
(0, swagger_1.ApiOperation)({ summary: 'tts语音播报' }),
(0, common_1.UseGuards)(jwtAuth_guard_1.JwtAuthGuard),
(0, swagger_1.ApiBearerAuth)(),
__param(0, (0, common_1.Body)()),
__param(1, (0, common_1.Req)()),
__param(2, (0, common_1.Res)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [chatProcess_dto_1.ChatProcessDto, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "mjAssociate", null);
__metadata("design:paramtypes", [chatProcess_dto_1.ChatProcessDto, Object, Object]),
__metadata("design:returntype", void 0)
], ChatController.prototype, "ttsProcess", null);
__decorate([
(0, common_1.Post)('mj-fy'),
(0, swagger_1.ApiOperation)({ summary: 'gpt描述词绘画翻译' }),
@@ -144,7 +143,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [chatProcess_dto_1.ChatProcessDto, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "mjFanyi", null);
], ChatController.prototype, "mjFanyi", null);
__decorate([
(0, common_1.Post)('chat-mind'),
(0, swagger_1.ApiOperation)({ summary: 'mind思维导图提示' }),
@@ -156,7 +155,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [chatProcess_dto_1.ChatProcessDto, Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "chatmind", null);
], ChatController.prototype, "chatmind", null);
__decorate([
(0, common_1.Post)('chat-draw'),
(0, swagger_1.ApiOperation)({ summary: 'gpt绘画' }),
@@ -167,7 +166,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [chatDraw_dto_1.ChatDrawDto, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "draw", null);
], ChatController.prototype, "draw", null);
__decorate([
(0, common_1.Post)('setChatBoxType'),
(0, swagger_1.ApiOperation)({ summary: '添加修改分类类型' }),
@@ -178,7 +177,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "setChatBoxType", null);
], ChatController.prototype, "setChatBoxType", null);
__decorate([
(0, common_1.Post)('delChatBoxType'),
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatBoxType' }),
@@ -189,7 +188,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "delChatBoxType", null);
], ChatController.prototype, "delChatBoxType", null);
__decorate([
(0, common_1.Get)('queryChatBoxTypes'),
(0, swagger_1.ApiOperation)({ summary: '查询ChatBoxType' }),
@@ -197,7 +196,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "queryChatBoxType", null);
], ChatController.prototype, "queryChatBoxType", null);
__decorate([
(0, common_1.Post)('setChatBox'),
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatBox' }),
@@ -208,7 +207,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "setChatBox", null);
], ChatController.prototype, "setChatBox", null);
__decorate([
(0, common_1.Post)('delChatBox'),
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatBox提示词' }),
@@ -219,7 +218,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "delChatBox", null);
], ChatController.prototype, "delChatBox", null);
__decorate([
(0, common_1.Get)('queryChatBoxs'),
(0, swagger_1.ApiOperation)({ summary: '查询ChatBox列表' }),
@@ -227,14 +226,14 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "queryChatBox", null);
], ChatController.prototype, "queryChatBox", null);
__decorate([
(0, common_1.Get)('queryChatBoxFrontend'),
(0, swagger_1.ApiOperation)({ summary: '查询ChatBox分类加详细' }),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "queryChatBoxFrontend", null);
], ChatController.prototype, "queryChatBoxFrontend", null);
__decorate([
(0, common_1.Post)('setChatPreType'),
(0, swagger_1.ApiOperation)({ summary: '添加修改预设分类类型' }),
@@ -245,7 +244,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "setChatPreType", null);
], ChatController.prototype, "setChatPreType", null);
__decorate([
(0, common_1.Post)('delChatPretype'),
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatPretype' }),
@@ -256,7 +255,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "delChatPreType", null);
], ChatController.prototype, "delChatPreType", null);
__decorate([
(0, common_1.Get)('queryChatPretypes'),
(0, swagger_1.ApiOperation)({ summary: '查询ChatPretype' }),
@@ -264,7 +263,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "queryChatPreType", null);
], ChatController.prototype, "queryChatPreType", null);
__decorate([
(0, common_1.Post)('setChatPre'),
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatPre' }),
@@ -275,7 +274,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "setChatPre", null);
], ChatController.prototype, "setChatPre", null);
__decorate([
(0, common_1.Post)('delChatPre'),
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatPre提示词' }),
@@ -286,7 +285,7 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "delChatPre", null);
], ChatController.prototype, "delChatPre", null);
__decorate([
(0, common_1.Get)('queryChatPres'),
(0, swagger_1.ApiOperation)({ summary: '查询ChatPre列表' }),
@@ -294,17 +293,17 @@ __decorate([
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "queryChatPre", null);
], ChatController.prototype, "queryChatPre", null);
__decorate([
(0, common_1.Get)('queryChatPreList'),
(0, swagger_1.ApiOperation)({ summary: '查询ChatPre列表' }),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], ChatgptController.prototype, "queryChatPreList", null);
ChatgptController = __decorate([
], ChatController.prototype, "queryChatPreList", null);
ChatController = __decorate([
(0, swagger_1.ApiTags)('chatgpt'),
(0, common_1.Controller)('chatgpt'),
__metadata("design:paramtypes", [chatgpt_service_1.ChatgptService, globalConfig_service_1.GlobalConfigService])
], ChatgptController);
exports.ChatgptController = ChatgptController;
__metadata("design:paramtypes", [chat_service_1.ChatService, globalConfig_service_1.GlobalConfigService])
], ChatController);
exports.ChatController = ChatController;

View File

@@ -6,10 +6,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatgptModule = void 0;
exports.ChatModule = void 0;
const common_1 = require("@nestjs/common");
const chatgpt_controller_1 = require("./chatgpt.controller");
const chatgpt_service_1 = require("./chatgpt.service");
const chat_controller_1 = require("./chat.controller");
const chat_service_1 = require("./chat.service");
const userBalance_service_1 = require("../userBalance/userBalance.service");
const typeorm_1 = require("@nestjs/typeorm");
const balance_entity_1 = require("../userBalance/balance.entity");
@@ -21,7 +21,6 @@ const chatLog_service_1 = require("../chatLog/chatLog.service");
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
const accountLog_entity_1 = require("../userBalance/accountLog.entity");
const config_entity_1 = require("../globalConfig/config.entity");
const gptKeys_entity_1 = require("./gptKeys.entity");
const whiteList_entity_1 = require("./whiteList.entity");
const cramiPackage_entity_1 = require("../crami/cramiPackage.entity");
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
@@ -35,9 +34,9 @@ const chatBoxType_entity_1 = require("./chatBoxType.entity");
const chatBox_entity_1 = require("./chatBox.entity");
const chatPreType_entity_1 = require("./chatPreType.entity");
const chatPre_entity_1 = require("./chatPre.entity");
let ChatgptModule = class ChatgptModule {
let ChatModule = class ChatModule {
};
ChatgptModule = __decorate([
ChatModule = __decorate([
(0, common_1.Global)(),
(0, common_1.Module)({
imports: [
@@ -48,7 +47,6 @@ ChatgptModule = __decorate([
chatLog_entity_1.ChatLogEntity,
accountLog_entity_1.AccountLogEntity,
config_entity_1.ConfigEntity,
gptKeys_entity_1.GptKeysEntity,
whiteList_entity_1.WhiteListEntity,
user_entity_1.UserEntity,
cramiPackage_entity_1.CramiPackageEntity,
@@ -64,9 +62,9 @@ ChatgptModule = __decorate([
chatPre_entity_1.ChatPreEntity
]),
],
controllers: [chatgpt_controller_1.ChatgptController],
providers: [chatgpt_service_1.ChatgptService, userBalance_service_1.UserBalanceService, user_service_1.UserService, verification_service_1.VerificationService, chatLog_service_1.ChatLogService, redisCache_service_1.RedisCacheService],
exports: [chatgpt_service_1.ChatgptService]
controllers: [chat_controller_1.ChatController],
providers: [chat_service_1.ChatService, userBalance_service_1.UserBalanceService, user_service_1.UserService, verification_service_1.VerificationService, chatLog_service_1.ChatLogService, redisCache_service_1.RedisCacheService],
exports: [chat_service_1.ChatService]
})
], ChatgptModule);
exports.ChatgptModule = ChatgptModule;
], ChatModule);
exports.ChatModule = ChatModule;

1156
dist/modules/chat/chat.service.js vendored Normal file

File diff suppressed because it is too large Load Diff

78
dist/modules/chat/dto/chatDraw.dto.js vendored Normal file
View File

@@ -0,0 +1,78 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatDrawDto = void 0;
const class_validator_1 = require("class-validator");
const swagger_1 = require("@nestjs/swagger");
class ChatDrawDto {
}
__decorate([
(0, swagger_1.ApiProperty)({ example: 'Draw a cute little dog', description: '绘画描述信息' }),
__metadata("design:type", String)
], ChatDrawDto.prototype, "prompt", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '绘画张数', required: true }),
__metadata("design:type", Number)
], ChatDrawDto.prototype, "n", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: '1024x1024', description: '图片尺寸', required: true }),
__metadata("design:type", String)
], ChatDrawDto.prototype, "size", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'standard', description: '图片质量', required: true }),
__metadata("design:type", String)
], ChatDrawDto.prototype, "quality", void 0);
__decorate([
(0, swagger_1.ApiProperty)({
example: 'close-up polaroid photo, of a little joyful cute panda, in the forest, sun rays coming, photographic, sharp focus, depth of field, soft lighting, heigh quality, 24mm, Nikon Z FX',
description: '绘画提示词!',
required: true,
}),
(0, swagger_1.ApiProperty)({ example: '--ar 16:9 --c 0', description: '除了prompt的额外参数' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], ChatDrawDto.prototype, "extraParam", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'https://xsdasdasd.com', description: '垫图图片地址' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], ChatDrawDto.prototype, "imgUrl", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'IMAGINE', description: '任务类型,可用值:IMAGINE,UPSCALE,VARIATION,ZOOM,PAN,DESCRIBE,BLEND,SHORTEN,SWAP_FACE' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], ChatDrawDto.prototype, "action", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '变体或者放大的序号' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", Number)
], ChatDrawDto.prototype, "orderId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '绘画的DBID' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", Number)
], ChatDrawDto.prototype, "drawId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: 'customId' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], ChatDrawDto.prototype, "customId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: 'base64' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], ChatDrawDto.prototype, "base64", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '任务ID' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", Number)
], ChatDrawDto.prototype, "taskId", void 0);
exports.ChatDrawDto = ChatDrawDto;

View File

@@ -28,7 +28,7 @@ __decorate([
__metadata("design:type", String)
], ChatProcessDto.prototype, "prompt", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'https://123.png', description: '对话附带的链接', required: false }),
(0, swagger_1.ApiProperty)({ example: 'https://aiweb.com', description: '对话附带的链接', required: false }),
__metadata("design:type", String)
], ChatProcessDto.prototype, "url", void 0);
__decorate([
@@ -49,4 +49,9 @@ __decorate([
(0, class_validator_1.IsOptional)(),
__metadata("design:type", Number)
], ChatProcessDto.prototype, "appId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: "gpt-3.5-turbo", description: '使用模型', required: false }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], ChatProcessDto.prototype, "model", void 0);
exports.ChatProcessDto = ChatProcessDto;

115
dist/modules/chat/store.js vendored Normal file
View File

@@ -0,0 +1,115 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NineStore = void 0;
const uuid_1 = require("uuid");
const tiktoken_1 = require("@dqbd/tiktoken");
const tokenizer = (0, tiktoken_1.get_encoding)('cl100k_base');
class NineStore {
constructor(options) {
const { store, namespace, expires } = this.formatOptions(options);
this.store = store;
this.namespace = namespace;
this.expires = expires;
}
formatOptions(options) {
const { store, expires = 1000 * 60 * 60 * 24 * 3, namespace = 'chat' } = options;
return { store, namespace, expires };
}
generateKey(key) {
return this.namespace ? `${this.namespace}-${key}` : key;
}
async getData(id) {
const res = await this.store.get(id);
return res;
}
async setData(message, expires = this.expires) {
await this.store.set(message.id, message, expires);
}
async buildMessageFromParentMessageId(text, options, chatLogService) {
let { systemMessage = '', fileInfo, model, groupId, maxRounds = 5, maxModelTokens = 4000, isFileUpload = 0 } = options;
let messages = [];
if (systemMessage) {
messages.push({ role: 'system', content: systemMessage });
}
if (groupId) {
const history = await chatLogService.chatHistory(groupId, maxRounds);
history.forEach((record) => {
let content;
if (isFileUpload === 2 && record.fileInfo) {
content = [
{ type: "text", text: record.text },
{ type: "image_url", image_url: { url: record.fileInfo } }
];
}
else if (isFileUpload === 1 && record.fileInfo) {
content = record.fileInfo + "\n" + record.text;
}
else {
content = record.text;
}
messages.push({ role: record.role, content });
});
}
let currentMessageContent;
if (isFileUpload === 2 && fileInfo) {
currentMessageContent = [
{ type: "text", text },
{ type: "image_url", image_url: { url: fileInfo } }
];
}
else if (isFileUpload === 1 && fileInfo) {
currentMessageContent = fileInfo + "\n" + text;
}
else {
currentMessageContent = text;
}
messages.push({ role: 'user', content: currentMessageContent });
let totalTokens = await this._getTokenCount(messages);
while (totalTokens > maxModelTokens / 2) {
let foundNonSystemMessage = false;
for (let i = 0; i < messages.length; i++) {
if (messages[i].role !== 'system') {
messages.splice(i, 2);
foundNonSystemMessage = true;
break;
}
}
if (!foundNonSystemMessage) {
break;
}
totalTokens = await this._getTokenCount(messages);
}
return {
messagesHistory: messages,
round: messages.length
};
}
_getTokenCount(messages) {
let text = messages.reduce((pre, cur) => {
if (Array.isArray(cur.content)) {
const contentText = cur.content
.filter((item) => item.type === 'text')
.map((item) => item.text)
.join(' ');
return pre + contentText;
}
else {
return pre + (cur.content || '');
}
}, '');
text = text.replace(/<\|endoftext\|>/g, '');
return tokenizer.encode(text).length;
}
_recursivePruning(messages, maxNumTokens, systemMessage) {
const currentTokens = this._getTokenCount(messages);
if (currentTokens <= maxNumTokens) {
return messages;
}
messages.splice(systemMessage ? 1 : 0, 1);
return this._recursivePruning(messages, maxNumTokens, systemMessage);
}
getUuid() {
return (0, uuid_1.v4)();
}
}
exports.NineStore = NineStore;

View File

@@ -53,8 +53,6 @@ let ChatGroupService = class ChatGroupService {
params['title'] = name;
}
params['appId'] = appId;
}
if (appId) {
modelConfig.appId = appId;
}
const newGroup = await this.chatGroupEntity.save(Object.assign(Object.assign({}, params), { config: JSON.stringify(modelConfig) }));

View File

@@ -19,97 +19,101 @@ __decorate([
__metadata("design:type", Number)
], ChatLogEntity.prototype, "userId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '使用型', nullable: true }),
(0, typeorm_1.Column)({ comment: '使用的模型', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "model", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '使用类型1: 普通对话 2: 绘图 3: 拓展性对话', nullable: true, default: 1 }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "type", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '自定义的模型名称', nullable: true, default: 'AI' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "modelName", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'Ip地址', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "curIp", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '询问的问题', type: 'text', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "prompt", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '附加参数', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "extraParam", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '回答的答案', type: 'text', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "answer", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '本次问题的token', nullable: true }),
(0, typeorm_1.Column)({ comment: '提问的token', nullable: true }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "promptTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '本次回答的token', nullable: true }),
(0, typeorm_1.Column)({ comment: '回答的token', nullable: true }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "completionTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '本次总花费的token', nullable: true }),
(0, typeorm_1.Column)({ comment: '总花费的token', nullable: true }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "totalTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '本次使用的模型', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "model", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '本次访问的Ip地址', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "curIp", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否推荐0: 默认 1: 推荐', nullable: true, default: 0 }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "rec", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '扩展参数', nullable: true, type: 'text' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "extend", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'mj绘画列表携带的一级id用于图片变换或者放大', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "message_id", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '一组图片的第几张、放大或者变换的时候需要使用', nullable: true }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "orderId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'mj绘画的动作、放大或者变换、或者全部重新绘制', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "action", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否是组图,这种图才可以指定放大', default: 0 }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "group", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '放大图片的Id记录', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "upscaleId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '变换图片的Id记录', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "variationId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '图片信息的string', nullable: true, type: 'text' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "fileInfo", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'role system user assistant', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "role", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '对话分组ID', nullable: true }),
(0, typeorm_1.Column)({ comment: '当前绘制任务的进度', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "progress", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '当前绘制任务的耗时', nullable: true }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "durationSpent", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '当前绘制任务的状态', nullable: true, default: 3 }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "status", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'mj绘画的动作、绘图、放大、变换、图生图', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "action", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '对图片操作的按钮ID', type: 'text', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "customId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '绘画的ID每条不一样', nullable: true }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "drawId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '图片比例', nullable: true, type: 'text' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "drawRatio", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '对话或绘图附带的链接', nullable: true, type: 'text' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "fileInfo", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '对话转语音的链接', nullable: true, type: 'text' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "ttsUrl", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否推荐0: 默认 1: 推荐', nullable: true, default: 0 }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "rec", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '分组ID', nullable: true }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "groupId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '序列化的本次会话参数', nullable: true, type: 'text' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "conversationOptions", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '序列化的本次提交参数', nullable: true, type: 'text' }),
__metadata("design:type", String)
], ChatLogEntity.prototype, "requestOptions", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否删除', default: false }),
__metadata("design:type", Boolean)
], ChatLogEntity.prototype, "isDelete", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '使用的应用id', nullable: true }),
__metadata("design:type", Number)
], ChatLogEntity.prototype, "appId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否删除', default: false }),
__metadata("design:type", Boolean)
], ChatLogEntity.prototype, "isDelete", void 0);
ChatLogEntity = __decorate([
(0, typeorm_1.Entity)({ name: 'chatlog' })
], ChatLogEntity);

View File

@@ -29,12 +29,19 @@ let ChatLogService = class ChatLogService {
this.chatGroupEntity = chatGroupEntity;
}
async saveChatLog(logInfo) {
return await this.chatLogEntity.save(logInfo);
const savedLog = await this.chatLogEntity.save(logInfo);
return savedLog;
}
async updateChatLog(id, logInfo) {
return await this.chatLogEntity.update({ id }, logInfo);
}
async findOneChatLog(id) {
return await this.chatLogEntity.findOne({ where: { id } });
}
async querDrawLog(req, query) {
const { id } = req.user;
const { model } = query;
const where = { userId: id, type: balance_constant_1.DeductionKey.PAINT_TYPE };
const where = { userId: id, type: balance_constant_1.ChatType.PAINT };
if (model) {
where.model = model;
if (model === 'DALL-E2') {
@@ -44,7 +51,7 @@ let ChatLogService = class ChatLogService {
const data = await this.chatLogEntity.find({
where,
order: { id: 'DESC' },
select: ['id', 'answer', 'prompt', 'message_id', 'group', 'model', 'extend', 'type', 'fileInfo'],
select: ['id', 'answer', 'prompt', 'model', 'type', 'fileInfo'],
});
data.forEach((r) => {
if (r.type === 'paintCount') {
@@ -64,7 +71,7 @@ let ChatLogService = class ChatLogService {
}
async querAllDrawLog(params) {
const { page = 1, size = 20, rec, userId, model } = params;
const where = { type: balance_constant_1.DeductionKey.PAINT_TYPE, prompt: (0, typeorm_2.Not)(''), answer: (0, typeorm_2.Not)('') };
const where = { type: balance_constant_1.ChatType.PAINT, prompt: (0, typeorm_2.Not)(''), answer: (0, typeorm_2.Not)('') };
rec && Object.assign(where, { rec });
userId && Object.assign(where, { userId });
if (model) {
@@ -104,9 +111,14 @@ let ChatLogService = class ChatLogService {
});
return { rows, count };
}
async findOneDrawLog(params) {
const { id } = params;
const record = await this.chatLogEntity.findOne({ where: { id } });
return record;
}
async recDrawImg(body) {
const { id } = body;
const l = await this.chatLogEntity.findOne({ where: { id, type: balance_constant_1.DeductionKey.PAINT_TYPE } });
const l = await this.chatLogEntity.findOne({ where: { id, type: balance_constant_1.ChatType.PAINT } });
if (!l) {
throw new common_1.HttpException('你推荐的图片不存在、请检查!', common_1.HttpStatus.BAD_REQUEST);
}
@@ -118,7 +130,7 @@ let ChatLogService = class ChatLogService {
throw new common_1.HttpException('你操作的图片不存在、请检查!', common_1.HttpStatus.BAD_REQUEST);
}
async exportExcel(body, res) {
const where = { type: balance_constant_1.DeductionKey.CHAT_TYPE };
const where = { type: balance_constant_1.ChatType.NORMAL_CHAT };
const { page = 1, size = 30, prompt, email } = body;
prompt && Object.assign(where, { prompt: (0, typeorm_2.Like)(`%${prompt}%`) });
if (email) {
@@ -160,7 +172,7 @@ let ChatLogService = class ChatLogService {
}
async querAllChatLog(params, req) {
const { page = 1, size = 20, userId, prompt } = params;
const where = { type: balance_constant_1.DeductionKey.CHAT_TYPE, prompt: (0, typeorm_2.Not)('') };
const where = { type: balance_constant_1.ChatType.NORMAL_CHAT, prompt: (0, typeorm_2.Not)('') };
userId && Object.assign(where, { userId });
prompt && Object.assign(where, { prompt: (0, typeorm_2.Like)(`%${prompt}%`) });
const [rows, count] = await this.chatLogEntity.findAndCount({
@@ -195,25 +207,40 @@ let ChatLogService = class ChatLogService {
}
const list = await this.chatLogEntity.find({ where });
return list.map((item) => {
const { prompt, role, answer, createdAt, model, conversationOptions, requestOptions, id, fileInfo } = item;
let parseConversationOptions = null;
let parseRequestOptions = null;
try {
parseConversationOptions = JSON.parse(conversationOptions);
parseRequestOptions = JSON.parse(requestOptions);
}
catch (error) {
}
const { prompt, role, answer, createdAt, model, modelName, type, status, action, drawId, id, fileInfo, ttsUrl, customId } = item;
return {
chatId: id,
dateTime: (0, utils_1.formatDate)(createdAt),
text: role === 'user' ? prompt : answer,
modelType: type,
status: status,
action: action,
drawId: drawId,
customId: customId,
inversion: role === 'user',
error: false,
conversationOptions: parseConversationOptions,
requestOptions: parseRequestOptions,
fileInfo: fileInfo,
ttsUrl: ttsUrl,
model: model,
modelName: modelName,
};
});
}
async chatHistory(groupId, rounds) {
const where = { isDelete: false, groupId: groupId };
const list = await this.chatLogEntity.find({
where,
order: {
createdAt: 'ASC'
},
take: rounds * 2
});
return list.map((item) => {
const { role, prompt, answer, fileInfo } = item;
return {
role: role,
text: role === 'user' ? prompt : answer,
fileInfo: fileInfo,
};
});
}

View File

@@ -1,827 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatgptService = void 0;
const upload_service_1 = require("./../upload/upload.service");
const user_service_1 = require("./../user/user.service");
const nestjs_config_1 = require("nestjs-config");
const common_1 = require("@nestjs/common");
const errorMessage_constant_1 = require("../../common/constants/errorMessage.constant");
const utils_1 = require("../../common/utils");
const axios_1 = require("axios");
const userBalance_service_1 = require("../userBalance/userBalance.service");
const balance_constant_1 = require("../../common/constants/balance.constant");
const chatLog_service_1 = require("../chatLog/chatLog.service");
const uuid = require("uuid");
const config_entity_1 = require("../globalConfig/config.entity");
const typeorm_1 = require("typeorm");
const typeorm_2 = require("@nestjs/typeorm");
const badwords_service_1 = require("../badwords/badwords.service");
const autoreply_service_1 = require("../autoreply/autoreply.service");
const gptKeys_entity_1 = require("./gptKeys.entity");
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
const fanyi_service_1 = require("../fanyi/fanyi.service");
const app_entity_1 = require("../app/app.entity");
const chatGroup_service_1 = require("../chatGroup/chatGroup.service");
const models_service_1 = require("../models/models.service");
const helper_1 = require("./helper");
const store_1 = require("./store");
const openai_1 = require("./openai");
const chatBoxType_entity_1 = require("./chatBoxType.entity");
const chatBox_entity_1 = require("./chatBox.entity");
const chatPre_entity_1 = require("./chatPre.entity");
const chatPreType_entity_1 = require("./chatPreType.entity");
let ChatgptService = class ChatgptService {
constructor(gptKeysEntity, configEntity, chatBoxTypeEntity, chatBoxEntity, appEntity, chatPreTypeEntity, chatPreEntity, configService, userBalanceService, chatLogService, userService, uploadService, badwordsService, autoreplyService, globalConfigService, fanyiService, chatGroupService, modelsService) {
this.gptKeysEntity = gptKeysEntity;
this.configEntity = configEntity;
this.chatBoxTypeEntity = chatBoxTypeEntity;
this.chatBoxEntity = chatBoxEntity;
this.appEntity = appEntity;
this.chatPreTypeEntity = chatPreTypeEntity;
this.chatPreEntity = chatPreEntity;
this.configService = configService;
this.userBalanceService = userBalanceService;
this.chatLogService = chatLogService;
this.userService = userService;
this.uploadService = uploadService;
this.badwordsService = badwordsService;
this.autoreplyService = autoreplyService;
this.globalConfigService = globalConfigService;
this.fanyiService = fanyiService;
this.chatGroupService = chatGroupService;
this.modelsService = modelsService;
this.nineStore = null;
this.whiteListUser = [];
this.keyPool = {
list3: [],
list4: [],
};
}
async onModuleInit() {
let chatgpt = await (0, utils_1.importDynamic)('chatgpt-ai-web');
let KeyvRedis = await (0, utils_1.importDynamic)('@keyv/redis');
let Keyv = await (0, utils_1.importDynamic)('keyv');
chatgpt = (chatgpt === null || chatgpt === void 0 ? void 0 : chatgpt.default) ? chatgpt.default : chatgpt;
KeyvRedis = (KeyvRedis === null || KeyvRedis === void 0 ? void 0 : KeyvRedis.default) ? KeyvRedis.default : KeyvRedis;
Keyv = (Keyv === null || Keyv === void 0 ? void 0 : Keyv.default) ? Keyv.default : Keyv;
const { ChatGPTAPI, ChatGPTError, ChatGPTUnofficialProxyAPI } = chatgpt;
const port = +process.env.REDIS_PORT;
const host = process.env.REDIS_HOST;
const password = process.env.REDIS_PASSWORD;
const username = process.env.REDIS_USER;
const redisUrl = `redis://${username || ''}:${password || ''}@${host}:${port}`;
const store = new KeyvRedis(redisUrl);
const messageStore = new Keyv({ store, namespace: 'nineai-chatlog' });
this.nineStore = new store_1.NineStore({ store: messageStore, namespace: 'chat' });
}
async getRequestParams(inputOpt, systemMessage, currentRequestModelKey, modelInfo = null) {
var _a;
if (!modelInfo) {
modelInfo = (_a = (await this.modelsService.getBaseConfig())) === null || _a === void 0 ? void 0 : _a.modelInfo;
}
const { timeout = 60 } = currentRequestModelKey;
const { topN: temperature, model } = modelInfo;
const { parentMessageId = 0 } = inputOpt;
const globalTimeoutMs = await this.globalConfigService.getConfigs(['openaiTimeoutMs']);
const timeoutMs = timeout * 1000 || globalTimeoutMs || 100 * 1000;
const options = {
parentMessageId,
timeoutMs: +timeoutMs,
completionParams: {
model,
temperature: temperature,
},
};
systemMessage && (options.systemMessage = systemMessage);
return options;
}
async chatSyncFree(prompt) {
const currentRequestModelKey = await this.modelsService.getRandomDrawKey();
const systemMessage = await this.globalConfigService.getConfigs(['systemPreMessage']);
const { maxModelTokens = 8000, maxResponseTokens = 4096, key, model } = currentRequestModelKey;
const proxyUrl = await this.getModelProxyUrl(currentRequestModelKey);
const { context: messagesHistory } = await this.nineStore.buildMessageFromParentMessageId(prompt, { parentMessageId: '', systemMessage });
try {
const response = await (0, openai_1.sendMessageFromOpenAi)(messagesHistory, {
apiKey: (0, utils_1.removeSpecialCharacters)(key),
model,
proxyUrl: proxyUrl,
onProgress: null,
});
return response === null || response === void 0 ? void 0 : response.text;
}
catch (error) {
console.log('error: ', error);
}
}
async chatProcess(body, req, res) {
var _a, _b, _c, _d;
const abortController = req.abortController;
const { options = {}, appId, cusromPrompt, systemMessage = '' } = body;
let setSystemMessage = systemMessage;
const { parentMessageId } = options;
const { prompt, fileInfo } = body;
const { groupId, usingNetwork } = options;
const groupInfo = await this.chatGroupService.getGroupInfoFromId(groupId);
const groupConfig = (groupInfo === null || groupInfo === void 0 ? void 0 : groupInfo.config) ? JSON.parse(groupInfo.config) : await this.modelsService.getBaseConfig();
const { keyType, model, topN: temperature, systemMessage: customSystemMessage, rounds } = groupConfig.modelInfo;
let currentRequestModelKey = null;
if (!cusromPrompt) {
currentRequestModelKey = await this.modelsService.getCurrentModelKeyInfo(model);
}
else {
currentRequestModelKey = await this.modelsService.getRandomDrawKey();
}
if (!currentRequestModelKey) {
throw new common_1.HttpException('当前流程所需要的模型已被管理员下架、请联系管理员上架专属模型!', common_1.HttpStatus.BAD_REQUEST);
}
const { deduct, isTokenBased, tokenFeeRatio, deductType, key: modelKey, secret, modelName, id: keyId, accessToken } = currentRequestModelKey;
await this.userService.checkUserStatus(req.user);
await this.userBalanceService.validateBalance(req, deductType === 1 ? 'model3' : 'model4', deduct);
res && res.setHeader('Content-type', 'application/octet-stream; charset=utf-8');
await this.badwordsService.checkBadWords(prompt, req.user.id);
const autoReplyRes = await this.autoreplyService.checkAutoReply(prompt);
if (autoReplyRes && res) {
const msg = { message: autoReplyRes, code: 500 };
res.write(JSON.stringify(msg));
return res.end();
}
if (appId) {
const appInfo = await this.appEntity.findOne({ where: { id: appId, status: (0, typeorm_1.In)([1, 3, 4, 5]) } });
if (!appInfo) {
throw new common_1.HttpException('你当前使用的应用已被下架、请删除当前对话开启新的对话吧!', common_1.HttpStatus.BAD_REQUEST);
}
appInfo.preset && (setSystemMessage = appInfo.preset);
}
else if (cusromPrompt) {
setSystemMessage = systemMessage;
}
else if (customSystemMessage) {
setSystemMessage = customSystemMessage;
}
else {
const currentDate = new Date().toISOString().split('T')[0];
const systemPreMessage = await this.globalConfigService.getConfigs(['systemPreMessage']);
setSystemMessage = systemPreMessage + `\n Current date: ${currentDate}`;
}
let netWorkPrompt = '';
if (usingNetwork) {
netWorkPrompt = await (0, utils_1.compileNetwork)(prompt);
const currentDate = new Date().toISOString().split('T')[0];
const systemPreMessage = await this.globalConfigService.getConfigs(['systemPreMessage']);
setSystemMessage = systemPreMessage + `\n Current date: ${currentDate}`;
}
const mergedOptions = await this.getRequestParams(options, setSystemMessage, currentRequestModelKey, groupConfig.modelInfo);
res && res.status(200);
let response = null;
let othersInfo = null;
try {
if (res) {
let lastChat = null;
let isSuccess = false;
res.on('close', async () => {
if (isSuccess)
return;
abortController.abort();
const prompt_tokens = (await (0, openai_1.getTokenCount)(prompt)) || 0;
const completion_tokens = (await (0, openai_1.getTokenCount)(lastChat === null || lastChat === void 0 ? void 0 : lastChat.text)) || 0;
const total_tokens = prompt_tokens + completion_tokens;
const curIp = (0, utils_1.getClientIp)(req);
await this.chatLogService.saveChatLog({
appId,
curIp,
userId: req.user.id,
type: balance_constant_1.DeductionKey.CHAT_TYPE,
prompt,
fileInfo: fileInfo,
answer: '',
promptTokens: prompt_tokens,
completionTokens: 0,
totalTokens: prompt_tokens,
model: model,
role: 'user',
groupId,
requestOptions: JSON.stringify({
options: null,
prompt,
}),
});
await this.chatLogService.saveChatLog({
appId,
curIp,
userId: req.user.id,
type: balance_constant_1.DeductionKey.CHAT_TYPE,
prompt: prompt,
answer: lastChat === null || lastChat === void 0 ? void 0 : lastChat.text,
promptTokens: prompt_tokens,
completionTokens: completion_tokens,
totalTokens: total_tokens,
model: model,
role: 'assistant',
groupId,
requestOptions: JSON.stringify({
options: {
model: model,
temperature,
},
prompt,
}),
conversationOptions: JSON.stringify({
conversationId: lastChat === null || lastChat === void 0 ? void 0 : lastChat.conversationId,
model: model,
parentMessageId: lastChat === null || lastChat === void 0 ? void 0 : lastChat.id,
temperature,
}),
});
let charge = deduct;
if (isTokenBased === true) {
charge = Math.ceil((deduct * total_tokens) / tokenFeeRatio);
}
await this.userBalanceService.deductFromBalance(req.user.id, `model${deductType === 1 ? 3 : 4}`, charge, total_tokens);
});
const { key, maxToken, maxTokenRes, proxyResUrl } = await this.formatModelToken(currentRequestModelKey);
const { parentMessageId, completionParams, systemMessage } = mergedOptions;
const { model, temperature } = completionParams;
const { context: messagesHistory } = await this.nineStore.buildMessageFromParentMessageId(usingNetwork ? netWorkPrompt : prompt, {
parentMessageId,
systemMessage,
maxModelToken: maxToken,
maxResponseTokens: maxTokenRes,
maxRounds: (0, helper_1.addOneIfOdd)(rounds),
fileInfo: fileInfo,
model: model
});
let firstChunk = true;
response = await (0, openai_1.sendMessageFromOpenAi)(messagesHistory, {
maxToken,
maxTokenRes,
apiKey: modelKey,
model,
prompt,
fileInfo,
temperature,
proxyUrl: proxyResUrl,
onProgress: (chat) => {
res.write(firstChunk ? JSON.stringify(chat) : `\n${JSON.stringify(chat)}`);
lastChat = chat;
firstChunk = false;
}
}, this.uploadService);
isSuccess = true;
const userMessageData = {
id: this.nineStore.getUuid(),
text: prompt,
role: 'user',
name: undefined,
usage: null,
fileInfo: fileInfo,
parentMessageId: parentMessageId,
conversationId: response === null || response === void 0 ? void 0 : response.conversationId,
};
othersInfo = { model, parentMessageId };
await this.nineStore.setData(userMessageData);
const assistantMessageData = {
id: response.id,
text: response.text,
role: 'assistant',
name: undefined,
usage: response === null || response === void 0 ? void 0 : response.usage,
fileInfo: response === null || response === void 0 ? void 0 : response.fileInfo,
parentMessageId: userMessageData.id,
conversationId: response === null || response === void 0 ? void 0 : response.conversationId,
};
await this.nineStore.setData(assistantMessageData);
othersInfo = { model, parentMessageId: userMessageData.id };
}
else {
const { key, maxToken, maxTokenRes, proxyResUrl } = await this.formatModelToken(currentRequestModelKey);
const { parentMessageId, completionParams, systemMessage } = mergedOptions;
const { model, temperature } = completionParams;
const { context: messagesHistory } = await this.nineStore.buildMessageFromParentMessageId(usingNetwork ? netWorkPrompt : prompt, {
parentMessageId,
systemMessage,
maxRounds: (0, helper_1.addOneIfOdd)(rounds),
});
response = await (0, openai_1.sendMessageFromOpenAi)(messagesHistory, {
apiKey: modelKey,
model,
temperature,
proxyUrl: proxyResUrl,
onProgress: null,
prompt,
});
}
const usage = ((_a = response.detail) === null || _a === void 0 ? void 0 : _a.usage) || { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 };
const { prompt_tokens, completion_tokens, total_tokens } = usage;
let charge = deduct;
if (isTokenBased === true) {
charge = Math.ceil((deduct * total_tokens) / tokenFeeRatio);
}
await this.userBalanceService.deductFromBalance(req.user.id, `model${deductType === 1 ? 3 : 4}`, charge, total_tokens);
await this.modelsService.saveUseLog(keyId, total_tokens);
const curIp = (0, utils_1.getClientIp)(req);
await this.chatLogService.saveChatLog({
appId,
curIp,
userId: req.user.id,
type: balance_constant_1.DeductionKey.CHAT_TYPE,
prompt,
fileInfo: fileInfo,
answer: '',
promptTokens: prompt_tokens,
completionTokens: 0,
totalTokens: total_tokens,
model: model,
role: 'user',
groupId,
requestOptions: JSON.stringify({
options: null,
prompt,
}),
});
await this.chatLogService.saveChatLog({
appId,
curIp,
userId: req.user.id,
type: balance_constant_1.DeductionKey.CHAT_TYPE,
prompt: prompt,
fileInfo: response === null || response === void 0 ? void 0 : response.fileInfo,
answer: response.text,
promptTokens: prompt_tokens,
completionTokens: completion_tokens,
totalTokens: total_tokens,
model: model,
role: 'assistant',
groupId,
requestOptions: JSON.stringify({
options: {
model: model,
temperature,
},
prompt,
}),
conversationOptions: JSON.stringify({
conversationId: response.conversationId,
model: model,
parentMessageId: response.id,
temperature,
}),
});
common_1.Logger.debug(`用户ID: ${req.user.id} 模型名称: ${modelName}-${model}, 消耗token: ${total_tokens}, 消耗积分: ${charge}`, 'ChatgptService');
const userBalance = await this.userBalanceService.queryUserBalance(req.user.id);
response.userBanance = Object.assign({}, userBalance);
response.result && (response.result = '');
response.is_end = true;
if (res) {
return res.write(`\n${JSON.stringify(response)}`);
}
else {
return response.text;
}
}
catch (error) {
console.log('chat-error <----------------------------------------->', modelKey, error);
const code = (error === null || error === void 0 ? void 0 : error.statusCode) || 400;
const status = ((_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.status) || (error === null || error === void 0 ? void 0 : error.statusCode) || 400;
console.log('chat-error-detail <----------------------------------------->', 'code: ', code, 'message', error === null || error === void 0 ? void 0 : error.message, 'statusText:', (_c = error === null || error === void 0 ? void 0 : error.response) === null || _c === void 0 ? void 0 : _c.statusText, 'status', (_d = error === null || error === void 0 ? void 0 : error.response) === null || _d === void 0 ? void 0 : _d.status);
if (error.status && error.status === 402) {
const errMsg = { message: `Catch Error ${error.message}`, code: 402 };
if (res) {
return res.write(JSON.stringify(errMsg));
}
else {
throw new common_1.HttpException(error.message, common_1.HttpStatus.PAYMENT_REQUIRED);
}
}
if (!status) {
if (res) {
return res.write(JSON.stringify({ message: error.message, code: 500 }));
}
else {
throw new common_1.HttpException(error.message, common_1.HttpStatus.BAD_REQUEST);
}
}
let message = errorMessage_constant_1.OpenAiErrorCodeMessage[status] ? errorMessage_constant_1.OpenAiErrorCodeMessage[status] : '服务异常、请重新试试吧!!!';
if ((error === null || error === void 0 ? void 0 : error.message.includes('The OpenAI account associated with this API key has been deactivated.')) && Number(keyType) === 1) {
await this.modelsService.lockKey(keyId, '当前模型key已被封禁、已冻结当前调用Key、尝试重新对话试试吧', -1);
message = '当前模型key已被封禁';
}
if ((error === null || error === void 0 ? void 0 : error.statusCode) === 429 && error.message.includes('billing') && Number(keyType) === 1) {
await this.modelsService.lockKey(keyId, '当前模型key余额已耗尽、已冻结当前调用Key、尝试重新对话试试吧', -3);
message = '当前模型key余额已耗尽';
}
if ((error === null || error === void 0 ? void 0 : error.statusCode) === 429 && (error === null || error === void 0 ? void 0 : error.statusText) === 'Too Many Requests') {
message = '当前模型调用过于频繁、请重新试试吧!';
}
if ((error === null || error === void 0 ? void 0 : error.statusCode) === 401 && error.message.includes('Incorrect API key provided') && Number(keyType) === 1) {
await this.modelsService.lockKey(keyId, '提供了错误的模型秘钥', -2);
message = '提供了错误的模型秘钥、已冻结当前调用Key、请重新尝试对话';
}
if ((error === null || error === void 0 ? void 0 : error.statusCode) === 404 && error.message.includes('This is not a chat model and thus not supported') && Number(keyType) === 1) {
await this.modelsService.lockKey(keyId, '当前模型不是聊天模型', -4);
message = '当前模型不是聊天模型、已冻结当前调用Key、请重新尝试对话';
}
if (code === 400) {
console.log('400 error', error, error.message);
}
const errMsg = { message: message || 'Please check the back-end console', code: code === 401 ? 400 : code || 500 };
if (res) {
return res.write(JSON.stringify(errMsg));
}
else {
throw new common_1.HttpException(errMsg.message, common_1.HttpStatus.BAD_REQUEST);
}
}
finally {
res && res.end();
}
}
async draw(body, req) {
var _a, _b, _c, _d;
await this.badwordsService.checkBadWords(body.prompt, req.user.id);
await this.userService.checkUserStatus(req.user);
const money = (body === null || body === void 0 ? void 0 : body.quality) === 'hd' ? 4 : 2;
await this.userBalanceService.validateBalance(req, 'mjDraw', money);
let images = [];
const detailKeyInfo = await this.modelsService.getCurrentModelKeyInfo('dall-e-3');
const keyId = detailKeyInfo === null || detailKeyInfo === void 0 ? void 0 : detailKeyInfo.id;
const { key, proxyResUrl } = await this.formatModelToken(detailKeyInfo);
common_1.Logger.log(`draw paompt info <==**==> ${body.prompt}, key ===> ${key}`, 'DrawService');
try {
const api = `${proxyResUrl}/v1/images/generations`;
const params = Object.assign(Object.assign({}, body), { model: 'dall-e-3' });
console.log('dall-e draw params: ', params);
const res = await axios_1.default.post(api, Object.assign(Object.assign({}, params), { response_format: 'b64_json' }), { headers: { Authorization: `Bearer ${key}` } });
images = res.data.data;
const task = [];
for (const item of images) {
const filename = uuid.v4().slice(0, 10) + '.png';
const buffer = Buffer.from(item.b64_json, 'base64');
task.push(this.uploadService.uploadFile({ filename, buffer }));
}
const urls = await Promise.all(task);
await this.userBalanceService.deductFromBalance(req.user.id, 'mjDraw', (params === null || params === void 0 ? void 0 : params.quality) === 'standard' ? 2 : 4, money);
const curIp = (0, utils_1.getClientIp)(req);
const taskLog = [];
const cosType = await this.uploadService.getUploadType();
const [width, height] = body.size.split('x');
urls.forEach((url) => {
taskLog.push(this.chatLogService.saveChatLog({
curIp,
userId: req.user.id,
type: balance_constant_1.DeductionKey.PAINT_TYPE,
prompt: body.prompt,
answer: url,
fileInfo: JSON.stringify({
cosType,
width,
height,
cosUrl: url,
}),
promptTokens: 0,
completionTokens: 0,
totalTokens: 0,
model: 'dall-e-3',
}));
});
await Promise.all(taskLog);
return urls;
}
catch (error) {
const status = ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status) || 500;
console.log('openai-draw error: ', JSON.stringify(error), key, status);
const message = (_d = (_c = (_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d.message;
if (status === 429) {
throw new common_1.HttpException('当前请求已过载、请稍等会儿再试试吧!', common_1.HttpStatus.BAD_REQUEST);
}
if (status === 400 && message.includes('This request has been blocked by our content filters')) {
throw new common_1.HttpException('您的请求已被系统拒绝。您的提示可能存在一些非法的文本。', common_1.HttpStatus.BAD_REQUEST);
}
if (status === 400 && message.includes('Billing hard limit has been reached')) {
await this.modelsService.lockKey(keyId, '当前模型key已被封禁、已冻结当前调用Key、尝试重新对话试试吧', -1);
throw new common_1.HttpException('当前Key余额已不足、请重新再试一次吧', common_1.HttpStatus.BAD_REQUEST);
}
if (status === 500) {
throw new common_1.HttpException('绘制图片失败,请检查你的提示词是否有非法描述!', common_1.HttpStatus.BAD_REQUEST);
}
if (status === 401) {
throw new common_1.HttpException('绘制图片失败,此次绘画被拒绝了!', common_1.HttpStatus.BAD_REQUEST);
}
throw new common_1.HttpException('绘制图片失败,请稍后试试吧!', common_1.HttpStatus.BAD_REQUEST);
}
}
async getAllKeyList() {
const list = await this.gptKeysEntity.find({
where: { status: 1 },
select: ['id', 'key', 'weight', 'model', 'maxModelTokens', 'maxResponseTokens', 'openaiProxyUrl', 'openaiTimeoutMs'],
});
const list3 = list.filter((t) => t.model.includes('gpt-3'));
const list4 = list.filter((t) => t.model.includes('gpt-4'));
this.keyPool = {
list3,
list4,
};
}
async getModelProxyUrl(modelKey) {
const openaiBaseUrl = await this.globalConfigService.getConfigs(['openaiBaseUrl']);
return (modelKey === null || modelKey === void 0 ? void 0 : modelKey.proxyUrl) || openaiBaseUrl || 'https://api.openai.com';
}
async formatModelToken(detailKeyInfo) {
const { openaiModel3MaxTokens = 0, openaiModel3MaxTokensRes = 0, openaiModel3MaxTokens16k = 0, openaiModel3MaxTokens16kRes = 0, openaiModel4MaxTokens = 0, openaiModel4MaxTokensRes = 0, openaiModel4MaxTokens32k = 0, openaiModel4MaxTokens32kRes = 0, openaiBaseUrl = '', } = await this.globalConfigService.getConfigs([
'openaiModel3MaxTokens',
'openaiModel3MaxTokensRes',
'openaiModel3MaxTokens16k',
'openaiModel3MaxTokens16kRes',
'openaiModel4MaxTokens',
'openaiModel4MaxTokensRes',
'openaiModel4MaxTokens32k',
'openaiModel4MaxTokens32kRes',
'openaiBaseUrl',
]);
let maxToken = null;
let maxTokenRes = null;
let proxyResUrl = null;
let { model, maxModelTokens = 0, maxResponseTokens = 0, proxyUrl = '', key } = detailKeyInfo;
if (model.toLowerCase().includes('gpt-4')) {
maxModelTokens >= 8192 && (maxModelTokens = 8192);
maxTokenRes >= 4096 && (maxModelTokens = 4096);
maxToken = maxModelTokens || openaiModel4MaxTokens || 8192;
maxTokenRes = maxResponseTokens || openaiModel4MaxTokensRes || 4096;
if (model.toLowerCase().includes('32k')) {
maxModelTokens >= 32768 && (maxModelTokens = 32768);
maxTokenRes >= 16384 && (maxModelTokens = 16384);
maxToken = maxModelTokens || openaiModel4MaxTokens32k || 32768;
maxTokenRes = maxResponseTokens || openaiModel4MaxTokens32kRes || 16384;
}
if (model.toLowerCase().includes('1106')) {
maxModelTokens >= 16380 && (maxModelTokens = 16380);
maxTokenRes >= 4096 && (maxModelTokens = 4096);
maxToken = maxModelTokens || 16380;
maxTokenRes = maxResponseTokens || 4096;
}
}
if (model.toLowerCase().includes('gpt-3')) {
maxModelTokens >= 4096 && (maxModelTokens = 4096);
maxTokenRes >= 2000 && (maxModelTokens = 2000);
maxToken = maxModelTokens || openaiModel3MaxTokens || 4096;
maxTokenRes = maxResponseTokens || openaiModel3MaxTokensRes || 2000;
if (model.toLowerCase().includes('16k')) {
maxModelTokens >= 16384 && (maxModelTokens = 16384);
maxTokenRes >= 8192 && (maxModelTokens = 8192);
maxToken = maxModelTokens || openaiModel3MaxTokens16k || 16384;
maxTokenRes = maxResponseTokens || openaiModel3MaxTokens16kRes || 8192;
}
if (model.toLowerCase().includes('1106')) {
maxModelTokens >= 16384 && (maxModelTokens = 16384);
maxTokenRes >= 4096 && (maxModelTokens = 4096);
maxToken = maxModelTokens || 16384;
maxTokenRes = maxResponseTokens || 4096;
}
}
proxyResUrl = proxyUrl || openaiBaseUrl || 'https://api.openai.com';
if (maxTokenRes >= maxToken) {
maxTokenRes = Math.floor(maxToken / 2);
}
return {
key,
maxToken,
maxTokenRes,
proxyResUrl,
};
}
async setChatBoxType(req, body) {
try {
const { name, icon, order, id, status } = body;
if (id) {
return await this.chatBoxTypeEntity.update({ id }, { name, icon, order, status });
}
else {
return await this.chatBoxTypeEntity.save({ name, icon, order, status });
}
}
catch (error) {
console.log('error: ', error);
}
}
async delChatBoxType(req, body) {
const { id } = body;
if (!id) {
throw new common_1.HttpException('非法操作!', common_1.HttpStatus.BAD_REQUEST);
}
const count = await this.chatBoxEntity.count({ where: { typeId: id } });
if (count) {
throw new common_1.HttpException('当前分类下有未处理数据不可移除!', common_1.HttpStatus.BAD_REQUEST);
}
return await this.chatBoxTypeEntity.delete({ id });
}
async queryChatBoxType() {
return await this.chatBoxTypeEntity.find({
order: { order: 'DESC' },
});
}
async setChatBox(req, body) {
const { title, prompt, appId, order, status, typeId, id, url } = body;
if (!typeId) {
throw new common_1.HttpException('缺失必要参数!', common_1.HttpStatus.BAD_REQUEST);
}
try {
const params = { title, order, status, typeId, url };
params.appId = appId || 0;
params.prompt = prompt || '';
if (id) {
return await this.chatBoxEntity.update({ id }, params);
}
else {
return await this.chatBoxEntity.save(params);
}
}
catch (error) {
console.log('error: ', error);
}
}
async delChatBox(req, body) {
const { id } = body;
if (!id) {
throw new common_1.HttpException('非法操作!', common_1.HttpStatus.BAD_REQUEST);
}
return await this.chatBoxEntity.delete({ id });
}
async queryChatBox() {
const data = await this.chatBoxEntity.find({
order: { order: 'DESC' },
});
const typeIds = [...new Set(data.map((t) => t.typeId))];
const appIds = [...new Set(data.map((t) => t.appId))];
const typeRes = await this.chatBoxTypeEntity.find({ where: { id: (0, typeorm_1.In)(typeIds) } });
const appRes = await this.appEntity.find({ where: { id: (0, typeorm_1.In)(appIds) } });
return data.map((item) => {
const { typeId, appId } = item;
item.typeInfo = typeRes.find((t) => t.id === typeId);
item.appInfo = appRes.find((t) => t.id === appId);
return item;
});
}
async queryChatBoxFrontend() {
const typeRes = await this.chatBoxTypeEntity.find({ order: { order: 'DESC' }, where: { status: true } });
const boxinfos = await this.chatBoxEntity.find({ where: { status: true } });
const appIds = [...new Set(boxinfos.map((t) => t.appId))];
const appInfos = await this.appEntity.find({ where: { id: (0, typeorm_1.In)(appIds) } });
boxinfos.forEach((item) => {
const app = appInfos.find((k) => k.id === item.appId);
item.coverImg = app === null || app === void 0 ? void 0 : app.coverImg;
return item;
});
return typeRes.map((t) => {
t.childList = boxinfos.filter((box) => box.typeId === t.id && box.status);
return t;
});
}
async setChatPreType(req, body) {
try {
const { name, icon, order, id, status } = body;
if (id) {
return await this.chatPreTypeEntity.update({ id }, { name, icon, order, status });
}
else {
return await this.chatPreTypeEntity.save({ name, icon, order, status });
}
}
catch (error) {
console.log('error: ', error);
}
}
async delChatPreType(req, body) {
const { id } = body;
if (!id) {
throw new common_1.HttpException('非法操作!', common_1.HttpStatus.BAD_REQUEST);
}
const count = await this.chatBoxEntity.count({ where: { typeId: id } });
if (count) {
throw new common_1.HttpException('当前分类下有未处理数据不可移除!', common_1.HttpStatus.BAD_REQUEST);
}
return await this.chatPreTypeEntity.delete({ id });
}
async queryChatPreType() {
return await this.chatPreTypeEntity.find({
order: { order: 'DESC' },
});
}
async setChatPre(req, body) {
const { title, prompt, appId, order, status, typeId, id, url } = body;
if (!typeId) {
throw new common_1.HttpException('缺失必要参数!', common_1.HttpStatus.BAD_REQUEST);
}
try {
const params = { title, prompt, order, status, typeId, url };
if (id) {
return await this.chatPreEntity.update({ id }, params);
}
else {
return await this.chatPreEntity.save(params);
}
}
catch (error) {
console.log('error: ', error);
}
}
async delChatPre(req, body) {
const { id } = body;
if (!id) {
throw new common_1.HttpException('非法操作!', common_1.HttpStatus.BAD_REQUEST);
}
return await this.chatPreEntity.delete({ id });
}
async queryChatPre() {
const data = await this.chatPreEntity.find({
order: { order: 'DESC' },
});
const typeIds = [...new Set(data.map((t) => t.typeId))];
const typeRes = await this.chatPreTypeEntity.find({ where: { id: (0, typeorm_1.In)(typeIds) } });
return data.map((item) => {
const { typeId, appId } = item;
item.typeInfo = typeRes.find((t) => t.id === typeId);
return item;
});
}
async queryChatPreList() {
const typeRes = await this.chatPreTypeEntity.find({ order: { order: 'DESC' }, where: { status: true } });
const chatPreData = await this.chatPreEntity.find({ where: { status: true } });
return typeRes.map((t) => {
t.childList = chatPreData.filter((box) => box.typeId === t.id && box.status);
return t;
});
}
async getMaxTokenFromModelWithOpenAi(model, maxModelToken, maxResToken) {
let maxToken = 4096;
let maxRes = 2048;
if (model.toLowerCase().includes('gpt-4')) {
maxToken = maxModelToken >= 8196 ? 8196 : maxModelToken;
maxRes = maxResToken >= 4096 ? 4096 : maxResToken;
if (model.toLowerCase().includes('32k')) {
maxToken = maxModelToken >= 32768 ? 32768 : maxModelToken;
maxRes = maxResToken >= 16000 ? 16000 : maxResToken;
}
if (model.toLowerCase().includes('gpt-4-1106') || model.toLowerCase().includes('gpt-4-vision-preview')) {
maxToken = maxModelToken >= 128000 ? 128000 : maxModelToken;
maxRes = maxResToken >= 4096 ? 4096 : maxResToken;
}
}
if (model.toLowerCase().includes('gpt-3')) {
maxToken = maxModelToken >= 4096 ? 4096 : maxModelToken;
maxRes = maxResToken >= 2048 ? 2048 : maxResToken;
if (model.toLowerCase().includes('16k')) {
maxToken = maxModelToken >= 16384 ? 16384 : maxModelToken;
maxRes = maxResToken >= 8000 ? 8000 : maxResToken;
}
if (model.toLowerCase().includes('1106')) {
maxToken = maxModelToken >= 16384 ? 16384 : maxModelToken;
maxRes = maxResToken >= 8000 ? 8000 : maxResToken;
}
}
return {
maxToken,
maxRes,
};
}
};
ChatgptService = __decorate([
(0, common_1.Injectable)(),
__param(0, (0, typeorm_2.InjectRepository)(gptKeys_entity_1.GptKeysEntity)),
__param(1, (0, typeorm_2.InjectRepository)(config_entity_1.ConfigEntity)),
__param(2, (0, typeorm_2.InjectRepository)(chatBoxType_entity_1.ChatBoxTypeEntity)),
__param(3, (0, typeorm_2.InjectRepository)(chatBox_entity_1.ChatBoxEntity)),
__param(4, (0, typeorm_2.InjectRepository)(app_entity_1.AppEntity)),
__param(5, (0, typeorm_2.InjectRepository)(chatPreType_entity_1.ChatPreTypeEntity)),
__param(6, (0, typeorm_2.InjectRepository)(chatPre_entity_1.ChatPreEntity)),
__metadata("design:paramtypes", [typeorm_1.Repository,
typeorm_1.Repository,
typeorm_1.Repository,
typeorm_1.Repository,
typeorm_1.Repository,
typeorm_1.Repository,
typeorm_1.Repository,
nestjs_config_1.ConfigService,
userBalance_service_1.UserBalanceService,
chatLog_service_1.ChatLogService,
user_service_1.UserService,
upload_service_1.UploadService,
badwords_service_1.BadwordsService,
autoreply_service_1.AutoreplyService,
globalConfig_service_1.GlobalConfigService,
fanyi_service_1.FanyiService,
chatGroup_service_1.ChatGroupService,
models_service_1.ModelsService])
], ChatgptService);
exports.ChatgptService = ChatgptService;

View File

@@ -1,32 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatDrawDto = void 0;
const swagger_1 = require("@nestjs/swagger");
class ChatDrawDto {
}
__decorate([
(0, swagger_1.ApiProperty)({ example: 'Draw a cute little dog', description: '绘画描述信息' }),
__metadata("design:type", String)
], ChatDrawDto.prototype, "prompt", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '绘画张数', required: true }),
__metadata("design:type", Number)
], ChatDrawDto.prototype, "n", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: '1024x1024', description: '图片尺寸', required: true }),
__metadata("design:type", String)
], ChatDrawDto.prototype, "size", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'standard', description: '图片质量', required: true }),
__metadata("design:type", String)
], ChatDrawDto.prototype, "quality", void 0);
exports.ChatDrawDto = ChatDrawDto;

View File

@@ -1,72 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GptKeysEntity = void 0;
const typeorm_1 = require("typeorm");
const baseEntity_1 = require("../../common/entity/baseEntity");
let GptKeysEntity = class GptKeysEntity extends baseEntity_1.BaseEntity {
};
__decorate([
(0, typeorm_1.Column)({ unique: true, comment: 'gpt key', length: 255 }),
__metadata("design:type", String)
], GptKeysEntity.prototype, "key", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '使用的状态: 0:禁用 1启用', default: 0 }),
__metadata("design:type", Number)
], GptKeysEntity.prototype, "status", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '绑定的模型是?', default: 'gpt-3.5-turbo' }),
__metadata("design:type", String)
], GptKeysEntity.prototype, "model", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key的余额', type: 'decimal', precision: 10, scale: 2, default: 0 }),
__metadata("design:type", String)
], GptKeysEntity.prototype, "balance", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key的余额类型', default: '', nullable: true }),
__metadata("design:type", String)
], GptKeysEntity.prototype, "type", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key的状态: 1:有效 2:余额耗尽 -1:被封号', default: 1 }),
__metadata("design:type", Number)
], GptKeysEntity.prototype, "keyStatus", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key的到期时间', nullable: true }),
__metadata("design:type", Date)
], GptKeysEntity.prototype, "expireTime", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key权重', default: 1 }),
__metadata("design:type", Number)
], GptKeysEntity.prototype, "weight", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key的使用次数', default: 0 }),
__metadata("design:type", Number)
], GptKeysEntity.prototype, "useCount", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型支持的最大Token', nullable: true }),
__metadata("design:type", Number)
], GptKeysEntity.prototype, "maxModelTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型设置的最大回复Token', nullable: true }),
__metadata("design:type", Number)
], GptKeysEntity.prototype, "maxResponseTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '当前模型的代理地址', nullable: true }),
__metadata("design:type", String)
], GptKeysEntity.prototype, "openaiProxyUrl", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '当前模型的超时时间单位ms', nullable: true }),
__metadata("design:type", Number)
], GptKeysEntity.prototype, "openaiTimeoutMs", void 0);
GptKeysEntity = __decorate([
(0, typeorm_1.Entity)({ name: 'gpt_keys' })
], GptKeysEntity);
exports.GptKeysEntity = GptKeysEntity;

View File

@@ -1,178 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTokenCount = exports.sendMessageFromOpenAi = void 0;
const axios_1 = require("axios");
const tiktoken_1 = require("@dqbd/tiktoken");
const common_1 = require("@nestjs/common");
const uuid = require("uuid");
const tokenizer = (0, tiktoken_1.get_encoding)('cl100k_base');
function getFullUrl(proxyUrl) {
const processedUrl = proxyUrl.endsWith('/') ? proxyUrl.slice(0, -1) : proxyUrl;
const baseUrl = processedUrl || 'https://api.openai.com';
return `${baseUrl}/v1/chat/completions`;
}
async function sendMessageFromOpenAi(messagesHistory, inputs, uploadService) {
var _a, _b, _c, _d;
const { onProgress, maxToken, apiKey, model, temperature = 0.8, proxyUrl, prompt } = inputs;
if (model.includes('dall')) {
let result = { text: '', fileInfo: '' };
try {
const options = {
method: 'POST',
url: `${proxyUrl}/v1/images/generations`,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
},
data: {
prompt: prompt,
model: model,
response_format: 'b64_json'
},
};
const response = await (0, axios_1.default)(options);
const { b64_json, revised_prompt } = response.data.data[0];
const buffer = Buffer.from(b64_json, 'base64');
let imgUrl = '';
try {
const filename = uuid.v4().slice(0, 10) + '.png';
common_1.Logger.debug(`------> 开始上传图片!!!`, 'MidjourneyService');
const buffer = Buffer.from(b64_json, 'base64');
imgUrl = await uploadService.uploadFile({ filename, buffer });
common_1.Logger.debug(`图片上传成功URL: ${imgUrl}`, 'MidjourneyService');
}
catch (error) {
common_1.Logger.error(`上传图片过程中出现错误: ${error}`, 'MidjourneyService');
}
result.fileInfo = imgUrl;
result.text = revised_prompt;
onProgress && onProgress({ text: result.text });
return result;
}
catch (error) {
const status = ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status) || 500;
console.log('openai-draw error: ', JSON.stringify(error), status);
const message = (_d = (_c = (_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d.message;
if (status === 429) {
result.text = '当前请求已过载、请稍等会儿再试试吧!';
return result;
}
if (status === 400 && message.includes('This request has been blocked by our content filters')) {
result.text = '您的请求已被系统拒绝。您的提示可能存在一些非法的文本。';
return result;
}
if (status === 400 && message.includes('Billing hard limit has been reached')) {
result.text = '当前模型key已被封禁、已冻结当前调用Key、尝试重新对话试试吧';
return result;
}
if (status === 500) {
result.text = '绘制图片失败,请检查你的提示词是否有非法描述!';
return result;
}
if (status === 401) {
result.text = '绘制图片失败,此次绘画被拒绝了!';
return result;
}
result.text = '绘制图片失败,请稍后试试吧!';
return result;
}
}
else {
let result = { text: '' };
const options = {
method: 'POST',
url: getFullUrl(proxyUrl),
responseType: 'stream',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
},
data: {
stream: true,
temperature,
model,
messages: messagesHistory,
},
};
if (model === 'gpt-4-vision-preview') {
options.data.max_tokens = 2048;
}
return new Promise(async (resolve, reject) => {
try {
const response = await (0, axios_1.default)(options);
const stream = response.data;
stream.on('data', (chunk) => {
var _a;
const splitArr = chunk.toString().split('\n\n').filter((line) => line.trim() !== '');
for (const line of splitArr) {
const data = line.replace('data:', '');
let ISEND = false;
try {
ISEND = JSON.parse(data).choices[0].finish_reason === 'stop';
}
catch (error) {
ISEND = false;
}
if (ISEND) {
result.text = result.text.trim();
return result;
}
try {
if (data !== " [DONE]" && data !== "[DONE]" && data != "[DONE] ") {
const parsedData = JSON.parse(data);
if (parsedData.id) {
result.id = parsedData.id;
}
if ((_a = parsedData.choices) === null || _a === void 0 ? void 0 : _a.length) {
const delta = parsedData.choices[0].delta;
result.delta = delta.content;
if (delta === null || delta === void 0 ? void 0 : delta.content)
result.text += delta.content;
if (delta.role) {
result.role = delta.role;
}
result.detail = parsedData;
}
onProgress && onProgress({ text: result.text });
}
}
catch (error) {
console.log('parse Error', data);
}
}
});
let totalText = '';
messagesHistory.forEach(message => {
totalText += message.content + ' ';
});
stream.on('end', () => {
if (result.detail && result.text) {
const promptTokens = getTokenCount(totalText);
const completionTokens = getTokenCount(result.text);
result.detail.usage = {
prompt_tokens: promptTokens,
completion_tokens: completionTokens,
total_tokens: promptTokens + completionTokens,
estimated: true
};
}
return resolve(result);
});
}
catch (error) {
reject(error);
}
});
}
}
exports.sendMessageFromOpenAi = sendMessageFromOpenAi;
function getTokenCount(text) {
if (!text)
return 0;
if (typeof text !== 'string') {
text = String(text);
}
text = text.replace(/<\|endoftext\|>/g, '');
return tokenizer.encode(text).length;
}
exports.getTokenCount = getTokenCount;

View File

@@ -1,131 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NineStore = void 0;
const uuid_1 = require("uuid");
const tiktoken_1 = require("@dqbd/tiktoken");
const tokenizer = (0, tiktoken_1.get_encoding)('cl100k_base');
class NineStore {
constructor(options) {
const { store, namespace, expires } = this.formatOptions(options);
this.store = store;
this.namespace = namespace;
this.expires = expires;
}
formatOptions(options) {
const { store, expires = 1000 * 60 * 60 * 24 * 3, namespace = 'chat' } = options;
return { store, namespace, expires };
}
generateKey(key) {
return this.namespace ? `${this.namespace}-${key}` : key;
}
async getData(id) {
const res = await this.store.get(id);
return res;
}
async setData(message, expires = this.expires) {
await this.store.set(message.id, message, expires);
}
async buildMessageFromParentMessageId(text, options) {
let { maxRounds, maxModelToken, maxResponseTokens, systemMessage = '', name, fileInfo, model } = options;
let { parentMessageId } = options;
let messages = [];
let nextNumTokensEstimate = 0;
if (systemMessage) {
messages.push({ role: 'system', content: systemMessage, name });
}
const systemMessageOffset = messages.length;
let round = 0;
if (model === 'gpt-4-vision-preview' && fileInfo) {
const content = [
{
"type": "text",
"text": text
},
{
"type": "image_url",
"image_url": {
"url": fileInfo
}
}
];
messages.push({ role: 'user', content: content, name });
}
else {
if (model === 'gpt-4-all' && fileInfo) {
text = fileInfo + "\n" + text;
}
messages.push({ role: 'user', content: text, name });
}
let nextMessages = messages;
do {
if (!parentMessageId) {
break;
}
const parentMessage = await this.getData(parentMessageId);
if (!parentMessage) {
break;
}
const { text, name, role, fileInfo } = parentMessage;
let content = text;
if (fileInfo) {
if (model === 'gpt-4-vision-preview') {
content = [
{ "type": "text", "text": text },
{ "type": "image_url", "image_url": { "url": fileInfo } }
];
}
else if (model === 'gpt-4-all') {
content = fileInfo + "\n" + text;
}
}
nextMessages = nextMessages.slice(0, systemMessageOffset).concat([
{ role, content, name },
...nextMessages.slice(systemMessageOffset)
]);
round++;
if (maxRounds && round >= maxRounds) {
break;
}
if (maxModelToken && maxResponseTokens) {
const maxNumTokens = maxModelToken - maxResponseTokens;
nextNumTokensEstimate = await this._getTokenCount(nextMessages);
const isValidPrompt = nextNumTokensEstimate + 200 <= maxNumTokens;
if (!isValidPrompt) {
nextMessages = this._recursivePruning(nextMessages, maxNumTokens, systemMessage);
}
}
parentMessageId = parentMessage.parentMessageId;
} while (true);
const maxTokens = Math.max(1, Math.min(maxModelToken - nextNumTokensEstimate, maxResponseTokens));
console.log('本次携带上下文的长度', nextMessages.length, nextNumTokensEstimate);
return { context: nextMessages, round: nextMessages.length, historyToken: nextNumTokensEstimate };
}
_getTokenCount(messages) {
let text = messages.reduce((pre, cur) => {
if (Array.isArray(cur.content)) {
const contentText = cur.content
.filter((item) => item.type === 'text')
.map((item) => item.text)
.join(' ');
return pre + contentText;
}
else {
return pre + (cur.content || '');
}
}, '');
text = text.replace(/<\|endoftext\|>/g, '');
return tokenizer.encode(text).length;
}
_recursivePruning(messages, maxNumTokens, systemMessage) {
const currentTokens = this._getTokenCount(messages);
if (currentTokens <= maxNumTokens) {
return messages;
}
messages.splice(systemMessage ? 1 : 0, 1);
return this._recursivePruning(messages, maxNumTokens, systemMessage);
}
getUuid() {
return (0, uuid_1.v4)();
}
}
exports.NineStore = NineStore;

View File

@@ -20,7 +20,7 @@ const accountLog_entity_1 = require("../userBalance/accountLog.entity");
const config_entity_1 = require("../globalConfig/config.entity");
const userBalance_entity_1 = require("../userBalance/userBalance.entity");
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
const whiteList_entity_1 = require("../chatgpt/whiteList.entity");
const whiteList_entity_1 = require("../chat/whiteList.entity");
const fingerprint_entity_1 = require("../userBalance/fingerprint.entity");
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");

View File

@@ -87,6 +87,9 @@ let DatabaseService = class DatabaseService {
},
{ configKey: 'buyCramiAddress', configVal: '', public: 1, encry: 0 },
{ configKey: 'openaiBaseUrl', configVal: 'https://api.lightai.io', public: 0, encry: 0 },
{ configKey: 'openaiTimeout', configVal: '300', public: 0, encry: 0 },
{ configKey: 'openaiBaseKey', configVal: 'sk-', public: 0, encry: 0 },
{ configKey: 'mjTranslatePrompt', configVal: `Translate any given phrase from any language into English. For instance, when I input '{可爱的熊猫}', you should output '{cute panda}', with no period at the end.`, public: 0, encry: 0 },
{ configKey: 'noticeInfo', configVal: noticeInfo, public: 1, encry: 0 },
{ configKey: 'registerVerifyEmailTitle', configVal: 'AIWeb账号验证', public: 0, encry: 0 },
{

View File

@@ -1,37 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FanyiController = void 0;
const common_1 = require("@nestjs/common");
const fanyi_service_1 = require("./fanyi.service");
let FanyiController = class FanyiController {
constructor(fanyiService) {
this.fanyiService = fanyiService;
}
convertToEnglish(text) {
return this.fanyiService.convertToEnglish(text);
}
};
__decorate([
(0, common_1.Get)('translate'),
__param(0, (0, common_1.Query)('text')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], FanyiController.prototype, "convertToEnglish", null);
FanyiController = __decorate([
(0, common_1.Controller)('fanyi'),
__metadata("design:paramtypes", [fanyi_service_1.FanyiService])
], FanyiController);
exports.FanyiController = FanyiController;

View File

@@ -1,23 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FanyiModule = void 0;
const common_1 = require("@nestjs/common");
const fanyi_service_1 = require("./fanyi.service");
const fanyi_controller_1 = require("./fanyi.controller");
let FanyiModule = class FanyiModule {
};
FanyiModule = __decorate([
(0, common_1.Global)(),
(0, common_1.Module)({
providers: [fanyi_service_1.FanyiService],
controllers: [fanyi_controller_1.FanyiController],
exports: [fanyi_service_1.FanyiService],
})
], FanyiModule);
exports.FanyiModule = FanyiModule;

View File

@@ -1,63 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FanyiService = void 0;
const globalConfig_service_1 = require("./../globalConfig/globalConfig.service");
const common_1 = require("@nestjs/common");
const axios_1 = require("axios");
const crypto = require("crypto");
let FanyiService = class FanyiService {
constructor(globalConfigService) {
this.globalConfigService = globalConfigService;
}
async convertToEnglish(text) {
if (!text)
throw new common_1.HttpException(`请输入要翻译的内容!`, common_1.HttpStatus.BAD_REQUEST);
const { baiduFanyiAppId, baiduFanyiSecret } = await this.globalConfigService.getConfigs(['baiduFanyiAppId', 'baiduFanyiSecret']);
if (!baiduFanyiAppId || !baiduFanyiSecret) {
throw new common_1.HttpException(`当前管理员还未开放翻译服务、请联系管理员开通吧!`, common_1.HttpStatus.BAD_REQUEST);
}
const salt = Date.now().toString();
const sign = crypto
.createHash('md5')
.update(baiduFanyiAppId + text + salt + baiduFanyiSecret)
.digest('hex');
const url = 'https://fanyi-api.baidu.com/api/trans/vip/translate';
const params = {
q: text.toString(),
from: 'auto',
to: 'en',
appid: baiduFanyiAppId,
salt,
sign,
};
const res = await axios_1.default.post(url, params, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
});
const { from, to, trans_result, error_code, error_msg } = res.data;
if (error_code) {
console.log('res: ', res);
throw new common_1.HttpException(`翻译失败[${error_code}][${error_msg}]!`, common_1.HttpStatus.BAD_REQUEST);
}
if (!trans_result || !trans_result.length) {
console.log('res: ', res);
throw new common_1.HttpException(`翻译失败[${error_code}][${error_msg}]!`, common_1.HttpStatus.BAD_REQUEST);
}
else {
}
return trans_result[0].dst;
}
};
FanyiService = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [globalConfig_service_1.GlobalConfigService])
], FanyiService);
exports.FanyiService = FanyiService;

View File

@@ -66,7 +66,6 @@ let GlobalConfigService = class GlobalConfigService {
async initBaiduSensitive(isInit = true) {
const { baiduTextApiKey, baiduTextSecretKey } = await this.getConfigs(['baiduTextApiKey', 'baiduTextSecretKey']);
if (!baiduTextApiKey || !baiduTextSecretKey) {
common_1.Logger.error('百度敏感词初始化失败,如果需要敏感检测、请前往后台系统配置!', 'GlobalConfigService');
return;
}
const headers = { 'Content-Type': 'application/json', Accept: 'application/json' };
@@ -77,7 +76,6 @@ let GlobalConfigService = class GlobalConfigService {
}
catch (error) {
if (isInit) {
common_1.Logger.error('百度敏感词配置检测失败,您的参数可能配置的不正确!', 'GlobalConfigService');
}
else {
throw new common_1.HttpException(error.response.data.error_description, common_1.HttpStatus.BAD_REQUEST);
@@ -145,6 +143,7 @@ let GlobalConfigService = class GlobalConfigService {
'clientHomePath',
'clientLogoPath',
'clientFavoIconPath',
'drawingStyles',
'isUseWxLogin',
'siteName',
'robotAvatar',
@@ -159,6 +158,7 @@ let GlobalConfigService = class GlobalConfigService {
'payHupiStatus',
'payWechatStatus',
'payMpayStatus',
'payLtzfStatus',
'isAutoOpenNotice',
'isShowAppCatIcon',
'salesBaseRatio',
@@ -247,7 +247,7 @@ let GlobalConfigService = class GlobalConfigService {
if (longKeys.includes(item.configKey)) {
return (item.configVal = (0, utils_1.hideString)(item.configVal, '隐私内容、非超级管理员无权查看'));
}
const whiteListKey = ['payEpayStatus', 'payHupiStatus', 'mjProxy'];
const whiteListKey = ['payEpayStatus', 'payHupiStatus', 'mjProxy', 'payLtzfStatus'];
if (!whiteListKey.includes(item.configKey) && !item.configKey.includes('Status')) {
item.configVal = (0, utils_1.hideString)(item.configVal);
}
@@ -307,8 +307,8 @@ let GlobalConfigService = class GlobalConfigService {
return await this.getConfigs(['copyrightUrl', 'copyrightTitle']);
}
async queryPayType() {
const { payHupiStatus = 0, payEpayStatus = 0, payWechatStatus = 0, payMpayStatus = 0, } = await this.getConfigs(['payHupiStatus', 'payEpayStatus', 'payMpayStatus', 'payWechatStatus']);
if ([payHupiStatus, payEpayStatus, payWechatStatus, payMpayStatus].every((status) => status === 0)) {
const { payHupiStatus = 0, payEpayStatus = 0, payWechatStatus = 0, payMpayStatus = 0, payLtzfStatus = 0, } = await this.getConfigs(['payHupiStatus', 'payEpayStatus', 'payMpayStatus', 'payWechatStatus', 'payLtzfStatus']);
if ([payHupiStatus, payEpayStatus, payWechatStatus, payMpayStatus, payLtzfStatus].every((status) => status === 0)) {
throw new common_1.HttpException('支付功能暂未开放!', common_1.HttpStatus.BAD_REQUEST);
}
if (Number(payWechatStatus) === 1) {
@@ -323,6 +323,9 @@ let GlobalConfigService = class GlobalConfigService {
if (Number(payHupiStatus) === 1) {
return 'hupi';
}
if (Number(payLtzfStatus) === 1) {
return 'ltzf';
}
}
async getAuthInfo() {
const { siteName, qqNumber, vxNumber, registerBaseUrl, domain } = await this.getConfigs([
@@ -367,7 +370,7 @@ let GlobalConfigService = class GlobalConfigService {
};
}
async auth() {
const api = 'https://api.jiangly.com/api/permission/auth';
const api = '';
const response = await fetch(api, {});
const responseData = await response.json();
const { success = true, message } = responseData;
@@ -378,11 +381,9 @@ let GlobalConfigService = class GlobalConfigService {
common_1.Logger.debug('感谢您使用NineAi、祝您使用愉快~');
}
async getSensitiveConfig() {
const { baiduTextStatus = 0, baiduTextAccessToken, nineaiBuiltInSensitiveStatus = 0, nineaiBuiltInSensitiveApiBase, nineaiBuiltInSensitiveAuthKey, } = await this.getConfigs([
const { baiduTextStatus = 0, baiduTextAccessToken, nineaiBuiltInSensitiveAuthKey, } = await this.getConfigs([
'baiduTextStatus',
'baiduTextAccessToken',
'nineaiBuiltInSensitiveStatus',
'nineaiBuiltInSensitiveApiBase',
'nineaiBuiltInSensitiveAuthKey',
]);
if (Number(baiduTextStatus) === 1) {
@@ -391,13 +392,6 @@ let GlobalConfigService = class GlobalConfigService {
baiduTextAccessToken,
};
}
if (Number(nineaiBuiltInSensitiveStatus) === 1) {
return {
useType: 'nineai',
nineaiBuiltInSensitiveApiBase,
nineaiBuiltInSensitiveAuthKey,
};
}
return null;
}
};

View File

@@ -33,7 +33,6 @@ let MenuService = class MenuService {
{ menuTipText: '应用广场', menuIcon: 'ant-design:appstore-outlined', menuName: 'AppStore', menuPath: '/app-store', menuType: 0, menuPlatform: 1, order: 200 },
{ menuTipText: '专业绘画', menuIcon: 'ri:landscape-line', menuName: 'Midjourney', menuPath: '/midjourney', menuType: 0, menuPlatform: 1, order: 300 },
{ menuTipText: '绘画广场', menuIcon: 'solar:album-line-duotone', menuName: 'Market', menuPath: '/market', menuType: 0, menuPlatform: 1, order: 400 },
{ menuTipText: '基础绘画', menuIcon: 'fluent:draw-image-24-regular', menuName: 'Draw', menuPath: '/draw', menuType: 0, menuPlatform: 1, order: 500 },
{ menuTipText: '思维导图', menuIcon: 'icon-park-outline:mindmap-map', menuName: 'Mind', menuPath: '/mind', menuType: 0, menuPlatform: 1, order: 600 },
{ menuTipText: '会员中心', menuIcon: 'icon-park-outline:shopping', menuName: 'Pay', menuPath: '/pay', menuType: 0, menuPlatform: 1, order: 700 },
{ menuTipText: '推广计划', menuIcon: 'uiw:share', menuName: 'Share', menuPath: '/share', menuType: 0, menuPlatform: 1, order: 800 },

View File

@@ -20,6 +20,7 @@ const midjourney_entity_1 = require("./midjourney.entity");
const typeorm_2 = require("typeorm");
const axios_1 = require("axios");
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
const models_service_1 = require("../models/models.service");
const midjourney_constant_1 = require("../../common/constants/midjourney.constant");
const upload_service_1 = require("../upload/upload.service");
const userBalance_service_1 = require("../userBalance/userBalance.service");
@@ -27,8 +28,9 @@ const utils_1 = require("../../common/utils");
const redisCache_service_1 = require("../redisCache/redisCache.service");
const prompt_entity_1 = require("./prompt.entity");
const image_size_1 = require("image-size");
const uuid = require("uuid");
let MidjourneyService = class MidjourneyService {
constructor(midjourneyEntity, userEntity, mjPromptsEntity, globalConfigService, uploadService, userBalanceService, redisCacheService) {
constructor(midjourneyEntity, userEntity, mjPromptsEntity, globalConfigService, uploadService, userBalanceService, redisCacheService, modelsService) {
this.midjourneyEntity = midjourneyEntity;
this.userEntity = userEntity;
this.mjPromptsEntity = mjPromptsEntity;
@@ -36,6 +38,7 @@ let MidjourneyService = class MidjourneyService {
this.uploadService = uploadService;
this.userBalanceService = userBalanceService;
this.redisCacheService = redisCacheService;
this.modelsService = modelsService;
this.lockPrompt = [];
}
async sleep(time) {
@@ -54,27 +57,32 @@ let MidjourneyService = class MidjourneyService {
}
}
async draw(jobData, jobId) {
const { id, action, drawId } = jobData;
const { id, action, base64, userId } = jobData;
const drawInfo = await this.midjourneyEntity.findOne({ where: { id } });
const { customId } = drawInfo;
const modelInfo = await this.modelsService.getSpecialModelKeyInfo('midjourney');
const { deduct, isTokenBased, tokenFeeRatio, deductType, key, modelName, id: keyId, maxRounds, proxyUrl, maxModelTokens, timeout, model: useModel } = modelInfo;
try {
await this.bindJobId(id, jobId);
await this.updateDrawStatus(id, midjourney_constant_1.MidjourneyStatusEnum.DRAWING);
const result = await this.sendDrawCommand(drawInfo, action);
const result = await this.sendDrawCommand(drawInfo, action, modelInfo, base64);
drawInfo.drawId = result;
const drawRes = await this.pollComparisonResultDraw(id, drawInfo);
const drawRes = await this.pollComparisonResultDraw(id, modelInfo, drawInfo);
await this.updateDrawData(jobData, drawRes);
this.drawSuccess(jobData);
const amount = action === "UPSCALE" ? deduct : deduct * 4;
common_1.Logger.log(`绘画完成,执行扣费,扣除费用:${amount}积分。`);
await this.userBalanceService.deductFromBalance(userId, deductType, amount);
await this.midjourneyEntity.update({ id }, { status: 3 });
return true;
}
catch (error) {
await this.midjourneyEntity.update({ id }, { status: 4 });
console.log('error: ', error);
return true;
}
}
async addDrawQueue(params) {
try {
const { prompt, imgUrl = '', extraParam = '', action, userId, orderId, customId, drawId } = params;
const { prompt, imgUrl = '', extraParam = '', action, userId, customId, drawId } = params;
const fullPrompt = imgUrl ? `${imgUrl} ${prompt} ${extraParam}` : `${prompt} ${extraParam}`;
const drawInfo = {
userId,
@@ -85,7 +93,6 @@ let MidjourneyService = class MidjourneyService {
fullPrompt,
status: midjourney_constant_1.MidjourneyStatusEnum.WAITING,
action,
orderId,
customId,
};
const res = await this.midjourneyEntity.save(drawInfo);
@@ -103,25 +110,39 @@ let MidjourneyService = class MidjourneyService {
try {
const { id, imageUrl, action, submitTime, finishTime, progress } = drawRes;
const durationSpent = finishTime - submitTime;
let filename = `${Date.now()}-${id}.png`;
const mjNotSaveImg = await this.globalConfigService.getConfigs(['mjNotSaveImg']);
const { mjNotSaveImg, mjProxyImgUrl, mjNotUseProxy, } = await this.globalConfigService.getConfigs([
'mjNotSaveImg',
'mjProxyImgUrl',
'mjNotUseProxy',
]);
let cosUrl = '';
let isSaveImg = true;
try {
if (!Number(mjNotSaveImg) || Number(mjNotSaveImg) === 0) {
common_1.Logger.debug(`------> 开始上传图片!!!`, 'MidjourneyService');
cosUrl = await this.uploadService.uploadFileFromUrl({ filename, url: imageUrl });
}
else {
cosUrl = imageUrl;
isSaveImg = false;
common_1.Logger.debug('本次不存图片了', 'MidjourneyService');
}
common_1.Logger.log(`绘制成功, 获取到的URL: ${imageUrl}`, 'MidjourneyService');
if (mjNotSaveImg == 1 && mjNotUseProxy == 0) {
const newUrlBase = new URL(mjProxyImgUrl);
const parsedUrl = new URL(imageUrl);
parsedUrl.protocol = newUrlBase.protocol;
parsedUrl.hostname = newUrlBase.hostname;
cosUrl = parsedUrl.toString();
common_1.Logger.log(`替换后的 URL: ${cosUrl}`, 'MidjourneyService');
}
catch (uploadError) {
common_1.Logger.error('存储图片失败,使用原始图片链接', 'MidjourneyService');
else if (mjNotSaveImg == 1 && mjNotUseProxy == 1) {
cosUrl = imageUrl;
isSaveImg = false;
common_1.Logger.log('使用原始图片链接', 'MidjourneyService');
}
else {
try {
const filename = `${Date.now()}-${uuid.v4().slice(0, 4)}.png`;
common_1.Logger.debug(`------> 开始上传图片!!!`, 'MidjourneyService');
cosUrl = await this.uploadService.uploadFileFromUrl({ filename, url: imageUrl });
common_1.Logger.log(`上传成功 URL: ${cosUrl}`, 'MidjourneyService');
}
catch (uploadError) {
common_1.Logger.error('存储图片失败,使用原始图片链接', 'MidjourneyService');
isSaveImg = false;
cosUrl = imageUrl;
}
}
const { width, height } = await this.getImageSizeFromUrl(imageUrl);
const drawInfo = {
@@ -131,7 +152,7 @@ let MidjourneyService = class MidjourneyService {
drawUrl: cosUrl,
drawRatio: `${width}x${height}`,
progress: 100,
extend: this.removeEmoji(JSON.stringify(drawRes)),
extend: JSON.stringify(drawRes),
durationSpent,
isSaveImg,
};
@@ -141,30 +162,39 @@ let MidjourneyService = class MidjourneyService {
throw new common_1.HttpException('更新绘画数据失败', common_1.HttpStatus.BAD_REQUEST);
}
}
async sendDrawCommand(drawInfo, action) {
const mjProxyUrl = (await this.globalConfigService.getConfigs(['mjProxyUrl']));
const mjKey = (await this.globalConfigService.getConfigs(['mjKey']));
async sendDrawCommand(drawInfo, action, modelInfo, base64) {
const { openaiBaseUrl, openaiBaseKey, } = await this.globalConfigService.getConfigs([
'openaiBaseUrl',
'openaiBaseKey',
]);
const { key, proxyUrl } = modelInfo;
const mjProxyUrl = proxyUrl || openaiBaseUrl;
const mjKey = key || openaiBaseKey;
const { id, fullPrompt, imgUrl, drawId, customId } = drawInfo;
const prompt = imgUrl ? `${imgUrl} ${fullPrompt}` : `${fullPrompt}`;
let url = '';
let payloadJson = {};
const MAX_RETRIES = 3;
let retryCount = 0;
const headers = { 'mj-api-secret': mjKey };
while (retryCount < MAX_RETRIES) {
try {
if (action === 'IMAGINE') {
url = `${mjProxyUrl}/mj/submit/imagine`;
payloadJson = { prompt: prompt };
}
else if (action === 'MODAL') {
url = `${mjProxyUrl}/mj/submit/modal`;
payloadJson = { maskBase64: base64, taskId: drawId, prompt: prompt };
}
else {
url = `${mjProxyUrl}/mj/submit/action`;
payloadJson = { taskId: drawId, customId: customId };
}
const headers = { "mj-api-secret": mjKey };
const res = await axios_1.default.post(url, payloadJson, { headers });
const { result } = res.data;
if (result) {
common_1.Logger.log(`绘画ID: ${result}`, 'MidjourneyService');
common_1.Logger.log(`绘画任务提交成功 绘画ID: ${result}`, 'MidjourneyService');
return result;
}
else {
@@ -172,6 +202,7 @@ let MidjourneyService = class MidjourneyService {
}
}
catch (error) {
common_1.Logger.error(`请求失败:${error.message}`);
retryCount++;
if (retryCount >= MAX_RETRIES) {
await this.updateDrawStatus(id, midjourney_constant_1.MidjourneyStatusEnum.DRAWFAIL);
@@ -180,12 +211,17 @@ let MidjourneyService = class MidjourneyService {
}
}
}
async pollComparisonResultDraw(id, drawInfo) {
const mjProxyUrl = (await this.globalConfigService.getConfigs(['mjProxyUrl']));
const mjKey = (await this.globalConfigService.getConfigs(['mjKey']));
async pollComparisonResultDraw(id, modelInfo, drawInfo) {
const { key, proxyUrl, timeout } = modelInfo;
const { openaiTimeout, } = await this.globalConfigService.getConfigs([
'openaiTimeout',
]);
const effectiveTimeout = Math.max(timeout || openaiTimeout || 300, 300);
const TIMEOUT = effectiveTimeout * 1000;
const mjProxyUrl = proxyUrl;
const mjKey = key;
const startTime = Date.now();
const POLL_INTERVAL = 5000;
const TIMEOUT = 150000;
let pollingCount = 0;
let retryCount = 0;
const MAX_RETRIES = 5;
@@ -193,6 +229,7 @@ let MidjourneyService = class MidjourneyService {
try {
while (Date.now() - startTime < TIMEOUT && retryCount < MAX_RETRIES) {
await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL));
common_1.Logger.log(`【绘制图片】第 ${pollingCount + 1} 次开始查询, 使用 drawId: ${drawId}`, 'MidjourneyService');
try {
const headers = {
"Content-Type": "application/x-www-form-urlencoded",
@@ -201,6 +238,7 @@ let MidjourneyService = class MidjourneyService {
const url = `${mjProxyUrl}/mj/task/${drawId}/fetch`;
const res = await axios_1.default.get(url, { headers });
const responses = res.data;
common_1.Logger.debug(`【绘制图片】第 ${pollingCount + 1} 次查询结果: ${JSON.stringify(responses)}`, 'MidjourneyService');
const progress = responses.process;
await this.midjourneyEntity.update({ id }, { progress: progress });
if (responses.status === 'SUCCESS') {
@@ -228,10 +266,6 @@ let MidjourneyService = class MidjourneyService {
throw error;
}
}
removeEmoji(str) {
const regex = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
return str.replace(regex, '');
}
async bindJobId(id, jobId) {
await this.midjourneyEntity.update({ id }, { jobId });
}
@@ -243,7 +277,7 @@ let MidjourneyService = class MidjourneyService {
order: { id: 'DESC' },
take: size,
skip: (page - 1) * size,
select: ['id', 'userId', 'prompt', 'extraParam', 'fullPrompt', 'rec', 'orderId', 'drawId', 'drawUrl', 'drawRatio', 'isDelete', 'status', 'action']
select: ['id', 'userId', 'prompt', 'extraParam', 'fullPrompt', 'rec', 'orderId', 'drawId', 'drawUrl', 'drawRatio', 'isDelete', 'status', 'action', 'extend']
});
const countQueue = await this.midjourneyEntity.count({ where: { isDelete: 0, status: (0, typeorm_2.In)([1, 2]) } });
const data = { rows: (0, utils_1.formatCreateOrUpdateDate)(rows), count, countQueue };
@@ -253,40 +287,25 @@ let MidjourneyService = class MidjourneyService {
throw new common_1.HttpException('获取我得绘制列表失败', common_1.HttpStatus.BAD_REQUEST);
}
}
async getDrawActionDetail(action, drawId, orderId) {
const detailInfo = await this.midjourneyEntity.findOne({ where: { drawId: drawId } });
const { extend, prompt, imgUrl, extraParam } = detailInfo;
const extendObj = JSON.parse(extend);
const buttons = extendObj.buttons || [];
let currentButton;
if (action === 'UPSCALE') {
currentButton = buttons.find(button => {
const isStandardUpscale = button.label.startsWith(`U${orderId}`);
const isUpscaleUpscale = (orderId === 1 && /(Redo )?Upscale \(Subtle\)/.test(button.label)) ||
(orderId === 2 && /(Redo )?Upscale \(Creative\)/.test(button.label));
return isStandardUpscale || isUpscaleUpscale;
});
async getDrawActionDetail(action, drawId, customId) {
const modelInfo = await this.modelsService.getSpecialModelKeyInfo('midjourney');
const { openaiBaseUrl, openaiBaseKey, } = await this.globalConfigService.getConfigs([
'openaiBaseUrl',
'openaiBaseKey',
]);
const { deduct, isTokenBased, tokenFeeRatio, deductType, key, modelName, id: keyId, maxRounds, proxyUrl, maxModelTokens, timeout, model: useModel } = modelInfo;
const mjProxyUrl = proxyUrl;
const mjKey = key || openaiBaseKey;
const headers = { 'mj-api-secret': mjKey || openaiBaseUrl };
let resultId;
if (action === 'MODAL') {
const payloadJson = { taskId: drawId, customId: customId };
const url = `${mjProxyUrl}/mj/submit/action`;
const res = await axios_1.default.post(url, payloadJson, { headers });
resultId = res.data.result;
console.log('Received response from action submission:', resultId);
}
if (action === 'VARIATION') {
currentButton = buttons.find(button => {
const isStandardVariation = button.label.startsWith(`V${orderId}`);
const isVaryVariation = (orderId === 1 && /Vary \(Strong\)/.test(button.label)) ||
(orderId === 2 && /Vary \(Region\)/.test(button.label));
return isStandardVariation || isVaryVariation;
});
}
if (action === 'REGENERATE') {
currentButton = buttons.find(button => button.customId.startsWith("MJ::JOB::reroll::0::") && button.label === "");
}
if (action === 'ZOOM') {
currentButton = buttons.find(button => (orderId === 1 && button.label === "Zoom Out 2x") ||
(orderId === 2 && button.label === "Zoom Out 1.5x"));
}
if (!currentButton) {
throw new common_1.HttpException('所需绘画操作信息不存在!', common_1.HttpStatus.BAD_REQUEST);
}
const { customId } = currentButton;
return { customId, prompt, extraParam, drawId };
return { drawId: resultId };
}
async deleteDraw(id, req) {
const d = await this.midjourneyEntity.findOne({ where: { id, userId: req.user.id, isDelete: 0 } });
@@ -321,7 +340,7 @@ let MidjourneyService = class MidjourneyService {
const { id, userId, action } = jobData;
const amount = action === "UPSCALE" ? 1 : 4;
common_1.Logger.debug(`绘画完成,执行扣费,扣除费用:${amount}积分。`);
await this.userBalanceService.refundMjBalance(userId, -amount);
await this.userBalanceService.deductFromBalance(userId, 3, 3);
await this.midjourneyEntity.update({ id }, { status: 3 });
}
async getList(params) {
@@ -346,13 +365,13 @@ let MidjourneyService = class MidjourneyService {
order: { id: 'DESC' },
take: size,
skip: (page - 1) * size,
select: ['id', 'drawId', 'drawUrl', 'drawRatio', 'prompt', 'fullPrompt', 'rec', 'createdAt', 'action', 'status'],
select: ['id', 'drawId', 'drawUrl', 'drawRatio', 'prompt', 'fullPrompt', 'rec', 'createdAt', 'action', 'status', 'extend'],
});
if (Number(size) === 999) {
const data = {
rows: rows.map((item) => {
const { id, drawId, drawUrl, drawRatio, prompt, fullPrompt, createdAt, rec, action, status } = item;
return { id, drawId, drawUrl, drawRatio, prompt, fullPrompt, createdAt, rec, action, status };
const { id, drawId, drawUrl, drawRatio, prompt, fullPrompt, createdAt, rec, action, status, extend } = item;
return { id, drawId, drawUrl, drawRatio, prompt, fullPrompt, createdAt, rec, action, status, extend };
}),
count,
};
@@ -479,6 +498,7 @@ MidjourneyService = __decorate([
globalConfig_service_1.GlobalConfigService,
upload_service_1.UploadService,
userBalance_service_1.UserBalanceService,
redisCache_service_1.RedisCacheService])
redisCache_service_1.RedisCacheService,
models_service_1.ModelsService])
], MidjourneyService);
exports.MidjourneyService = MidjourneyService;

View File

@@ -1,26 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MjDrawDto = void 0;
const class_validator_1 = require("class-validator");
const swagger_1 = require("@nestjs/swagger");
class MjDrawDto {
}
__decorate([
(0, swagger_1.ApiProperty)({
example: 'close-up polaroid photo, of a little joyful cute panda, in the forest, sun rays coming, photographic, sharp focus, depth of field, soft lighting, heigh quality, 24mm, Nikon Z FX',
description: '绘画提示词!',
required: true,
}),
(0, class_validator_1.IsDefined)({ message: '绘画提示词是必传参数!' }),
__metadata("design:type", String)
], MjDrawDto.prototype, "prompt", void 0);
exports.MjDrawDto = MjDrawDto;

View File

@@ -1,27 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MjEnlargeImgDto = void 0;
const class_validator_1 = require("class-validator");
const swagger_1 = require("@nestjs/swagger");
class MjEnlargeImgDto {
}
__decorate([
(0, swagger_1.ApiProperty)({ example: '1105361939590287360', description: '当前大图的message_id、四张的这种才存在有效的', required: true }),
(0, class_validator_1.IsDefined)({ message: '图片的message_id是必传的' }),
__metadata("design:type", String)
], MjEnlargeImgDto.prototype, "message_id", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '图片的orderId是必传的 表示放大图片的第几张!', required: true }),
(0, class_validator_1.IsDefined)({ message: '图片固体顺序id是必传的' }),
__metadata("design:type", Number)
], MjEnlargeImgDto.prototype, "orderId", void 0);
exports.MjEnlargeImgDto = MjEnlargeImgDto;

View File

@@ -1,27 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MjTransformImgDto = void 0;
const class_validator_1 = require("class-validator");
const swagger_1 = require("@nestjs/swagger");
class MjTransformImgDto {
}
__decorate([
(0, swagger_1.ApiProperty)({ example: '1105361939590287360', description: '当前大图的message_id、四张的这种才存在有效的', required: true }),
(0, class_validator_1.IsDefined)({ message: '图片的message_id是必传的' }),
__metadata("design:type", String)
], MjTransformImgDto.prototype, "message_id", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '图片的orderId是必传的 表示放大图片的第几张!', required: true }),
(0, class_validator_1.IsDefined)({ message: '图片固体顺序id是必传的' }),
__metadata("design:type", Number)
], MjTransformImgDto.prototype, "orderId", void 0);
exports.MjTransformImgDto = MjTransformImgDto;

View File

@@ -1,75 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MjController = void 0;
const common_1 = require("@nestjs/common");
const mj_service_1 = require("./mj.service");
const swagger_1 = require("@nestjs/swagger");
const mjDraw_dto_1 = require("./dto/mjDraw.dto");
const mjEnlargeImg_dto_1 = require("./dto/mjEnlargeImg.dto");
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
const mjTransform_dto_1 = require("./dto/mjTransform.dto");
let MjController = class MjController {
constructor(mjService) {
this.mjService = mjService;
}
draw(body, req) {
return this.mjService.draw(body, req);
}
upscaleSingleImg(body, req) {
return this.mjService.upscaleSingleImg(body, req);
}
variationSingleImg(body, req) {
return this.mjService.variationSingleImg(body, req);
}
};
__decorate([
(0, common_1.Post)('draw'),
(0, swagger_1.ApiOperation)({ summary: '绘制mj图片' }),
(0, common_1.UseGuards)(jwtAuth_guard_1.JwtAuthGuard),
(0, swagger_1.ApiBearerAuth)(),
__param(0, (0, common_1.Body)()),
__param(1, (0, common_1.Req)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [mjDraw_dto_1.MjDrawDto, Object]),
__metadata("design:returntype", void 0)
], MjController.prototype, "draw", null);
__decorate([
(0, common_1.Post)('upscaleSingleImg'),
(0, swagger_1.ApiOperation)({ summary: '放大单张图片' }),
(0, common_1.UseGuards)(jwtAuth_guard_1.JwtAuthGuard),
(0, swagger_1.ApiBearerAuth)(),
__param(0, (0, common_1.Body)()),
__param(1, (0, common_1.Req)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [mjEnlargeImg_dto_1.MjEnlargeImgDto, Object]),
__metadata("design:returntype", void 0)
], MjController.prototype, "upscaleSingleImg", null);
__decorate([
(0, common_1.Post)('variationSingleImg'),
(0, swagger_1.ApiOperation)({ summary: '变体单张图片' }),
(0, common_1.UseGuards)(jwtAuth_guard_1.JwtAuthGuard),
(0, swagger_1.ApiBearerAuth)(),
__param(0, (0, common_1.Body)()),
__param(1, (0, common_1.Req)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [mjTransform_dto_1.MjTransformImgDto, Object]),
__metadata("design:returntype", void 0)
], MjController.prototype, "variationSingleImg", null);
MjController = __decorate([
(0, swagger_1.ApiTags)('mj'),
(0, common_1.Controller)('mj'),
__metadata("design:paramtypes", [mj_service_1.MjService])
], MjController);
exports.MjController = MjController;

View File

@@ -1,27 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MjModule = void 0;
const chatLog_entity_1 = require("./../chatLog/chatLog.entity");
const common_1 = require("@nestjs/common");
const mj_service_1 = require("./mj.service");
const mj_controller_1 = require("./mj.controller");
const typeorm_1 = require("@nestjs/typeorm");
const balance_entity_1 = require("../userBalance/balance.entity");
let MjModule = class MjModule {
};
MjModule = __decorate([
(0, common_1.Global)(),
(0, common_1.Module)({
imports: [typeorm_1.TypeOrmModule.forFeature([chatLog_entity_1.ChatLogEntity, balance_entity_1.BalanceEntity])],
providers: [mj_service_1.MjService],
controllers: [mj_controller_1.MjController],
exports: [mj_service_1.MjService],
})
], MjModule);
exports.MjModule = MjModule;

View File

@@ -1,575 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MjService = void 0;
const globalConfig_service_1 = require("./../globalConfig/globalConfig.service");
const upload_service_1 = require("./../upload/upload.service");
const common_1 = require("@nestjs/common");
const axios_1 = require("axios");
const chatLog_service_1 = require("../chatLog/chatLog.service");
const balance_constant_1 = require("../../common/constants/balance.constant");
const utils_1 = require("../../common/utils");
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
const typeorm_1 = require("typeorm");
const typeorm_2 = require("@nestjs/typeorm");
const balance_entity_1 = require("../userBalance/balance.entity");
const fanyi_service_1 = require("../fanyi/fanyi.service");
const badwords_service_1 = require("../badwords/badwords.service");
let MjService = class MjService {
constructor(chatLogEntity, balanceEntity, uploadService, chatLogService, globalConfigService, fanyiService, badwordsService) {
this.chatLogEntity = chatLogEntity;
this.balanceEntity = balanceEntity;
this.uploadService = uploadService;
this.chatLogService = chatLogService;
this.globalConfigService = globalConfigService;
this.fanyiService = fanyiService;
this.badwordsService = badwordsService;
this.rateLimits = {};
this.drawWorking = [];
this.enlargeWorking = [];
this.queueCount = 0;
this.freeQueueUsers = {};
}
async mjDraw(data) {
const { jobId, prompt, startTime, userId } = data;
console.log('绘画任务开始', 'mjservice');
await new Promise((resolve) => setTimeout(resolve, 5000));
return { a: 1, b: 2 };
}
async draw(body, req) {
await this.checkAuth(req);
await this.badwordsService.checkBadWords(body.prompt, req.user.id);
const basicPrompt = body.prompt;
let fyPrompt = body.prompt;
const { baiduFanyiAppId, baiduFanyiSecret } = await this.globalConfigService.getConfigs(['baiduFanyiAppId', 'baiduFanyiSecret']);
if (baiduFanyiAppId && baiduFanyiSecret) {
fyPrompt = await this.fanyiService.convertToEnglish(basicPrompt);
}
const randomId = `[${(0, utils_1.createRandomUid)()}]`;
const prompt = `${randomId} ${fyPrompt}`;
console.log('randomId: ', randomId);
console.log('prompt --------> ', prompt);
const isWorking = this.drawWorking.find((item) => item.includes(body.prompt));
if (isWorking) {
throw new common_1.HttpException('当前提示词已经在任务队列中了、请勿重复提交。。。', common_1.HttpStatus.BAD_REQUEST);
}
if (this.queueCount >= 3) {
throw new common_1.HttpException('当前绘图任务满载、请排队等候、队列任务完成后即可开始您的任务...', common_1.HttpStatus.BAD_REQUEST);
}
await this.checkRateLimit(req);
this.queueCount++;
console.log(`开始请求用户${req.user.id} 队列+1: `, this.queueCount);
try {
const historyDraw = await this.chatLogEntity.find({ where: { prompt: (0, typeorm_1.Like)(`%${prompt}%`) } });
const histroyMessageIds = historyDraw.map((item) => item.message_id);
this.drawWorking.push(prompt);
let drawDetail;
const sendRes = await this.sendDrawInteractions(prompt, histroyMessageIds, randomId);
if (sendRes) {
console.log(`历史中存在当前图片、直接获取!`);
drawDetail = sendRes;
}
else {
drawDetail = await this.pollForResult(prompt, histroyMessageIds, randomId);
}
this.queueCount--;
this.queueCount < 0 && (this.queueCount = 0);
console.log('绘制图片任务结束 队列-1: ', this.queueCount);
const { id, content, channel_id, attachments = [], timestamp } = drawDetail;
if (!attachments.length || !attachments[0].url) {
throw new common_1.HttpException('绘画失败', common_1.HttpStatus.BAD_REQUEST);
}
const { filename, url, width, height, size } = attachments[0];
console.log('拿到了远程地址: ', url);
const mjNotSaveImg = this.globalConfigService.getConfigs(['mjNotSaveImg']);
let cosUrl = '';
if (!Number(mjNotSaveImg) || Number(mjNotSaveImg) === 0) {
cosUrl = await this.uploadService.uploadFileFromUrl({ filename, url });
console.log('存入图片完成: ', cosUrl);
}
const logInfo = {
curIp: (0, utils_1.getClientIp)(req),
userId: req.user.id,
type: balance_constant_1.DeductionKey.PAINT_TYPE,
prompt,
answer: cosUrl,
model: 'mj',
extend: this.removeEmoji(JSON.stringify(drawDetail)),
message_id: id,
variationId: id,
upscaleId: id,
group: 1,
isSaveImg: !Number(mjNotSaveImg) || Number(mjNotSaveImg) === 0,
fileInfo: JSON.stringify({ width, height, size, filename, cosUrl }),
};
await this.chatLogService.saveChatLog(logInfo);
await this.deductBalance(req);
this.drawWorking = this.drawWorking.filter((item) => item !== body.prompt);
return cosUrl;
}
catch (error) {
this.queueCount--;
this.queueCount < 0 && (this.queueCount = 0);
console.log('绘制图片任务异常中断 队列-1: ', this.queueCount);
this.drawWorking = this.drawWorking.filter((item) => item !== body.prompt);
throw new common_1.HttpException(error.response, common_1.HttpStatus.BAD_REQUEST);
}
}
async upscaleSingleImg(body, req) {
if (this.queueCount >= 3) {
throw new common_1.HttpException('当前绘图任务满载、请排队等候、队列任务完成后即可开始您的任务...', common_1.HttpStatus.BAD_REQUEST);
}
this.queueCount++;
console.log(`用户${req.user.id}开始请求放大图片 队列+1: `, this.queueCount);
const { message_id, orderId } = body;
try {
const historyLog = await this.chatLogEntity.findOne({ where: { message_id } });
if (!historyLog) {
throw new common_1.HttpException('历史记录中不存在当前图片、请确认您放大的图片是否存在', common_1.HttpStatus.BAD_REQUEST);
}
const isAreadlyEnlarge = await this.chatLogEntity.findOne({ where: { upscaleId: message_id, action: 'enlarge', orderId } });
if (isAreadlyEnlarge) {
throw new common_1.HttpException('当前图片已经放大过了、请勿重复放大!', common_1.HttpStatus.BAD_REQUEST);
}
const { prompt, extend } = historyLog;
let historyDetailDrawInfo = null;
try {
historyDetailDrawInfo = JSON.parse(extend);
}
catch (error) {
historyDetailDrawInfo = [];
}
const { components = [] } = historyDetailDrawInfo;
if (!components.length) {
throw new common_1.HttpException('当前图片没有绘画信息、无法放大!', common_1.HttpStatus.BAD_REQUEST);
}
const currentImgComponent = components[0]['components'][orderId - 1];
const { custom_id } = currentImgComponent;
console.log('放大custom_id: ', custom_id);
const params = { message_id, custom_id, prompt, orderId };
await this.sendSmInteractions(params);
console.log('发送放大指令成功');
const historyDraw = await this.chatLogEntity.find({ where: { prompt: (0, typeorm_1.Like)(`%${prompt}%`) } });
const histroyMessageIds = historyDraw.map((item) => item.message_id);
console.log('历史这些id已经被获取过了 不能拿了: ', histroyMessageIds);
const enlargeImgInfo = await this.pollForUpscaleResult(params, histroyMessageIds);
this.queueCount--;
this.queueCount < 0 && (this.queueCount = 0);
console.log('放大图片任务结束 队列-1: ', this.queueCount);
const { id, content, channel_id, attachments = [], timestamp } = enlargeImgInfo;
if (!attachments.length || !attachments[0].url) {
throw new common_1.HttpException('放大当前图片失败', common_1.HttpStatus.BAD_REQUEST);
}
const { filename, url, width, height, size } = attachments[0];
const mjNotSaveImg = this.globalConfigService.getConfigs(['mjNotSaveImg']);
let cosUrl = '';
if (!Number(mjNotSaveImg) || Number(mjNotSaveImg) === 0) {
cosUrl = await this.uploadService.uploadFileFromUrl({ filename, url });
console.log('存入图片完成: ', cosUrl);
}
const logInfo = {
curIp: (0, utils_1.getClientIp)(req),
userId: req.user.id,
type: balance_constant_1.DeductionKey.PAINT_TYPE,
prompt,
answer: cosUrl,
model: 'mj',
extend: this.removeEmoji(JSON.stringify(enlargeImgInfo)),
message_id,
upscaleId: id,
variationId: id,
action: 'enlarge',
orderId: params.orderId,
isSaveImg: !Number(mjNotSaveImg) || Number(mjNotSaveImg) === 0,
fileInfo: JSON.stringify({ width, height, size, filename, cosUrl }),
};
await this.chatLogService.saveChatLog(logInfo);
return cosUrl;
}
catch (error) {
console.log('error: ', error);
this.queueCount--;
this.queueCount < 0 && (this.queueCount = 0);
console.log('放大图片任务异常中断 队列-1: ', this.queueCount);
throw new common_1.HttpException(error.response, common_1.HttpStatus.BAD_REQUEST);
}
}
async variationSingleImg(body, req) {
if (this.queueCount >= 3) {
throw new common_1.HttpException('当前绘图任务满载、请排队等候、队列任务完成后即可开始您的任务...', common_1.HttpStatus.BAD_REQUEST);
}
await this.checkAuth(req);
await this.checkRateLimit(req);
this.queueCount++;
console.log(`用户${req.user.id}开始请求变换图片 队列+1: `, this.queueCount);
const { message_id, orderId } = body;
try {
const historyLog = await this.chatLogEntity.findOne({ where: { message_id } });
if (!historyLog) {
throw new common_1.HttpException('历史记录中不存在当前图片、请确认您需要变换的图片是否存在', common_1.HttpStatus.BAD_REQUEST);
}
const { prompt, extend } = historyLog;
let historyDetailDrawInfo = null;
try {
historyDetailDrawInfo = JSON.parse(extend);
}
catch (error) {
historyDetailDrawInfo = [];
}
const { components = [] } = historyDetailDrawInfo;
if (!components.length) {
throw new common_1.HttpException('当前图片没有绘画信息、无法变体!', common_1.HttpStatus.BAD_REQUEST);
}
const currentImgComponent = components[1]['components'][orderId - 1];
const { custom_id } = currentImgComponent;
const historyVariationLog = await this.chatLogEntity.find({ where: { variationId: (0, typeorm_1.Not)((0, typeorm_1.IsNull)()), prompt: (0, typeorm_1.Like)(`%${prompt}%`) } });
const historyVariationIds = historyVariationLog.map((item) => item.variationId);
const params = { message_id, custom_id, prompt, orderId };
await this.sendSmInteractions(params);
const variationImgInfo = await this.pollForVariationResult(params, historyVariationIds);
this.queueCount--;
this.queueCount < 0 && (this.queueCount = 0);
console.log('变换图片任务结束 队列-1: ', this.queueCount);
const { id, content, channel_id, attachments = [], timestamp } = variationImgInfo;
if (!attachments.length || !attachments[0].url) {
throw new common_1.HttpException('变换当前图片失败', common_1.HttpStatus.BAD_REQUEST);
}
const { filename, url, width, height, size } = attachments[0];
const mjNotSaveImg = this.globalConfigService.getConfigs(['mjNotSaveImg']);
let cosUrl = '';
if (!Number(mjNotSaveImg) || Number(mjNotSaveImg) === 0) {
cosUrl = await this.uploadService.uploadFileFromUrl({ filename, url });
console.log('存入图片完成: ', cosUrl);
}
const logInfo = {
curIp: (0, utils_1.getClientIp)(req),
userId: req.user.id,
type: balance_constant_1.DeductionKey.PAINT_TYPE,
prompt,
answer: cosUrl,
model: 'mj',
group: 1,
extend: this.removeEmoji(JSON.stringify(variationImgInfo)),
message_id: id,
upscaleId: id,
variationId: id,
action: 'enlarge',
orderId: params.orderId,
isSaveImg: !Number(mjNotSaveImg) || Number(mjNotSaveImg) === 0,
fileInfo: JSON.stringify({ width, height, size, filename, cosUrl }),
};
await this.chatLogService.saveChatLog(logInfo);
return cosUrl;
}
catch (error) {
console.log('error: ', error);
this.queueCount--;
this.queueCount < 0 && (this.queueCount = 0);
console.log('变化图片任务异常中断 队列-1: ', this.queueCount);
throw new common_1.HttpException(error.response, common_1.HttpStatus.BAD_REQUEST);
}
}
async sendSmInteractions(params) {
const { message_id, custom_id } = params;
const { application_id, guild_id, channel_id, session_id, version, id, authorization, mjProxy } = await this.getMjDefaultParams();
const url = mjProxy == 1 ? `http://172.247.48.137:8000/mj/draw` : 'https://discord.com/api/v9/interactions';
const headers = { authorization };
const body = {
type: 3,
guild_id,
channel_id,
message_flags: 0,
message_id,
application_id,
session_id,
data: {
component_type: 2,
custom_id,
},
};
try {
await axios_1.default.post(url, body, { headers });
console.log('绘图指令完成');
}
catch (error) {
console.log('error: ', error);
throw new common_1.HttpException('放大单张图片请求失败...', common_1.HttpStatus.BAD_REQUEST);
}
}
async pollForUpscaleResult(params, histroyMessageIds) {
const { message_id, custom_id, prompt, orderId } = params;
let enlargeImgDetail = null;
let pollingCount = 0;
while (!enlargeImgDetail && pollingCount < 10) {
try {
const startTime = Date.now();
const messageList = await this.queryMessageList();
console.log(`${pollingCount + 1} 次开始查询 => 当前查询结果:${messageList.length}`);
if (messageList && messageList.length) {
enlargeImgDetail = await this.findCurrentEnlargeImgResult(messageList, params, histroyMessageIds);
}
const elapsedTime = Date.now() - startTime;
const nextPollingDelay = 3000;
await this.sleep(Math.max(nextPollingDelay - elapsedTime, 0));
pollingCount++;
}
catch (error) {
console.error(`查询期间出现错误:${error.message}`);
}
}
return enlargeImgDetail;
}
async pollForVariationResult(params, historyVariationIds) {
const { message_id, custom_id, prompt, orderId } = params;
console.log('开始轮询单张变换图片结果');
let variationImgDetail = null;
let pollingCount = 0;
while (!variationImgDetail && pollingCount < 10) {
try {
console.log(`${pollingCount + 1} 次开始查询[变换图片]`);
const startTime = Date.now();
const messageList = await this.queryMessageList();
if (messageList && messageList.length) {
variationImgDetail = await this.findCurrentVariationImgResult(messageList, params, historyVariationIds);
}
const elapsedTime = Date.now() - startTime;
const nextPollingDelay = 8000;
await this.sleep(Math.max(nextPollingDelay - elapsedTime, 0));
pollingCount++;
}
catch (error) {
console.error(`查询期间出现错误:${error.message}`);
}
}
if (!variationImgDetail) {
throw new common_1.HttpException('变换当前图片超时!', common_1.HttpStatus.BAD_REQUEST);
}
return variationImgDetail;
}
async findCurrentEnlargeImgResult(messageList, params, histroyMessageIds) {
const { message_id, custom_id, prompt, orderId } = params;
const randomId = prompt.substring(0, 12);
console.log('本次放大图片的id: ', randomId);
const enlargeImgDetail = messageList.find((item) => {
const { content } = item;
if (!this.extractContent(content))
return false;
const { prompt, order } = this.extractContent(content);
return prompt.includes(randomId) && params.orderId === order && !histroyMessageIds.includes(item.id);
});
return enlargeImgDetail;
}
async findCurrentVariationImgResult(messageList, params, historyVariationIds) {
const { message_id, custom_id, prompt, orderId } = params;
const randomId = prompt.substring(0, 12);
const variationImgDetail = messageList.find((item) => {
const { content } = item;
const promptMatch = content.match(/\*\*(.+?)\*\*/);
const prompt = promptMatch ? promptMatch[1] : '';
if (!prompt)
return false;
return prompt.includes(randomId) && !historyVariationIds.includes(item.id);
});
return variationImgDetail;
}
async sendDrawInteractions(prompt, histroyMessageIds, randomId) {
const messageList = await this.queryMessageList();
const drawDetail = await this.findCurrentPromptResult(messageList, randomId, histroyMessageIds);
if (drawDetail) {
console.log('有历史信息之间返回: ', drawDetail);
return drawDetail;
}
const { application_id, guild_id, channel_id, session_id, version, id, authorization, mjProxy } = await this.getMjDefaultParams();
const payloadJson = {
type: 2,
application_id,
guild_id,
channel_id,
session_id,
data: { version, id, name: 'imagine', type: 1, options: [{ type: 3, name: 'prompt', value: prompt }], attachments: [] },
};
try {
const url = mjProxy == 1 ? `http://172.247.48.137:8000/mj/draw` : 'https://discord.com/api/v9/interactions';
const headers = { authorization };
const res = await axios_1.default.post(url, payloadJson, { headers });
console.log('发送绘画指令结果: ', res.data);
return false;
}
catch (error) {
console.log('axios: ', error);
throw new common_1.HttpException('绘画请求失败、当前使用人数过多、请稍后试试吧、排队中...', common_1.HttpStatus.BAD_REQUEST);
}
}
async pollForResult(prompt, histroyMessageIds, randomId) {
console.log('开始查询绘画结果轮询');
const startTime = Date.now();
try {
const MAX_POLLING_COUNT = 13;
const SHORT_INTERVAL = 12000;
const LONG_INTERVAL = 5000;
const TIME_THRESHOLD = 60 * 1000;
let pollingCount = 0;
let isLongInterval = false;
let drawDetail = null;
while (!drawDetail && pollingCount < MAX_POLLING_COUNT) {
console.log(`${pollingCount + 1} 次开始查询`);
if (Date.now() - startTime >= TIME_THRESHOLD) {
isLongInterval = true;
}
await this.sleep(isLongInterval ? LONG_INTERVAL : SHORT_INTERVAL);
const messageList = await this.queryMessageList();
drawDetail = await this.findCurrentPromptResult(messageList, randomId, histroyMessageIds);
pollingCount++;
}
if (!drawDetail) {
throw new common_1.HttpException('绘画超时,请稍后再试!', common_1.HttpStatus.BAD_REQUEST);
}
const endTime = Date.now();
console.log(`本次绘图耗时: ${Math.floor((endTime - startTime) / 1000)} S`);
return drawDetail;
}
catch (err) {
console.error(err.message);
throw new common_1.HttpException('网络连接失败,请稍后再试!', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async findCurrentPromptResult(data, randomId, histroyMessageIds) {
if (!data || !data.length)
return;
console.log('本次比对的随机ID: ', randomId);
const matchingItem = data.find((item) => {
const { attachments = [], content, edited_timestamp } = item;
return content.includes(randomId) && attachments.length > 0 && !edited_timestamp && !histroyMessageIds.includes(item.id);
});
return matchingItem || null;
}
async queryMessageList() {
try {
const { application_id, guild_id, channel_id, session_id, version, id, authorization, mjProxy } = await this.getMjDefaultParams();
const url = mjProxy == 1
? `http://172.247.48.137:8000/mj/list?channel_id=${channel_id}`
: `https://discord.com/api/v9/channels/${channel_id}/messages?limit=50`;
const headers = { authorization };
const response = await axios_1.default.get(url, { headers });
return response.data;
}
catch (error) {
console.log('axios get: ', error);
throw new common_1.HttpException('查询绘制结果失败...', common_1.HttpStatus.BAD_REQUEST);
}
}
async sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
extractContent(str) {
const promptMatch = str.match(/\*\*(.+?)\*\*/);
const orderMatch = str.match(/- Image #(\d+)/);
if (!promptMatch || !orderMatch) {
return null;
}
const prompt = promptMatch[1];
const order = parseInt(orderMatch[1]);
return { prompt, order };
}
async getMjDefaultParams() {
const configs = await this.globalConfigService.getConfigs([
'mjId',
'mjApplicationId',
'mjGuildId',
'mjChannelId',
'mjSessionId',
'mjVersion',
'mjAuthorization',
'mjRateLimit',
'mjProxy',
]);
const params = {
application_id: configs.mjApplicationId,
guild_id: configs.mjGuildId,
channel_id: configs.mjChannelId,
session_id: configs.mjSessionId,
version: configs.mjVersion,
id: configs.mjId,
authorization: configs.mjAuthorization,
mjRateLimit: configs.mjRateLimit,
mjProxy: configs.mjProxy || 0,
};
return params;
}
removeEmoji(str) {
const regex = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
return str.replace(regex, '');
}
async checkAuth(req) {
const m = await this.balanceEntity.findOne({ where: { userId: req.user.id } });
const { id, balance } = m;
if (!balance || (m === null || m === void 0 ? void 0 : m.balance) < 1) {
throw new common_1.HttpException('您当前暂无MJ绘画余额', common_1.HttpStatus.BAD_REQUEST);
}
}
async checkFree(req) {
const { id, role } = req.user;
if (!this.freeQueueUsers[id]) {
this.freeQueueUsers[id] = 1;
}
else {
this.freeQueueUsers[id] = this.freeQueueUsers[id] + 1;
}
console.log(`当前用户${id}使用的次数:`, this.freeQueueUsers[id]);
}
async checkRateLimit(req) {
const { id, role } = req.user;
if (['admin', 'super'].includes(role))
return true;
const { mjRateLimit } = await this.getMjDefaultParams();
if (this.rateLimits[id]) {
const val = this.rateLimits[id];
if (val > Date.now()) {
console.log(`当前用户 ${id} 请求过于频繁!`);
throw new common_1.HttpException(`由于速率限制、当前普通用户限制为${mjRateLimit}秒请求一次、请合理使用!`, common_1.HttpStatus.BAD_REQUEST);
}
else {
this.rateLimits[id] = Date.now() + Number(mjRateLimit) * 1000;
}
}
else {
const timeSpace = Date.now();
this.rateLimits[id] = timeSpace + 1000 * Number(mjRateLimit);
}
}
async deductBalance(req) {
await this.balanceEntity
.createQueryBuilder()
.update(balance_entity_1.BalanceEntity)
.set({ balance: () => 'balance - 1' })
.where('userId = :userId', { userId: req.user.id })
.execute();
}
async test() {
return 1;
}
};
MjService = __decorate([
(0, common_1.Injectable)(),
__param(0, (0, typeorm_2.InjectRepository)(chatLog_entity_1.ChatLogEntity)),
__param(1, (0, typeorm_2.InjectRepository)(balance_entity_1.BalanceEntity)),
__metadata("design:paramtypes", [typeorm_1.Repository,
typeorm_1.Repository,
upload_service_1.UploadService,
chatLog_service_1.ChatLogService,
globalConfig_service_1.GlobalConfigService,
fanyi_service_1.FanyiService,
badwords_service_1.BadwordsService])
], MjService);
exports.MjService = MjService;

View File

@@ -22,17 +22,13 @@ __decorate([
__metadata("design:type", Number)
], SetModelDto.prototype, "keyType", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: '文心一言普通模型', description: '模型中文名称', required: true }),
(0, swagger_1.ApiProperty)({ example: '默认', description: '模型中文名称', required: true }),
__metadata("design:type", String)
], SetModelDto.prototype, "modelName", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'dsadgadaorjoqm', description: '模型key', required: true }),
(0, swagger_1.ApiProperty)({ example: 'sk-', description: '模型key', required: false }),
__metadata("design:type", Object)
], SetModelDto.prototype, "key", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'dasdasdk2n31323k', description: '模型秘钥', required: false }),
__metadata("design:type", String)
], SetModelDto.prototype, "secret", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '是否开启当前key对应的模型', required: true }),
__metadata("design:type", Boolean)
@@ -50,19 +46,19 @@ __decorate([
__metadata("design:type", Number)
], SetModelDto.prototype, "modelOrder", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 4096, description: '模型支持的最大TOken数量', required: true }),
(0, swagger_1.ApiProperty)({ example: 'https://***.png', required: false }),
__metadata("design:type", String)
], SetModelDto.prototype, "modelAvatar", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 4096, description: '模型支持的最大TOken数量', required: false }),
__metadata("design:type", Number)
], SetModelDto.prototype, "maxModelTokens", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1000, description: '模型支持的最大回复TOken数量', required: true }),
__metadata("design:type", Number)
], SetModelDto.prototype, "maxResponseTokens", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '模型的代理地址', required: false }),
__metadata("design:type", String)
], SetModelDto.prototype, "proxyUrl", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '模型超时时间', required: false }),
(0, swagger_1.ApiProperty)({ example: 300, description: '模型超时时间', required: false }),
__metadata("design:type", Number)
], SetModelDto.prototype, "timeout", void 0);
__decorate([
@@ -85,6 +81,10 @@ __decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '是否设置为绘画Key', required: false }),
__metadata("design:type", Boolean)
], SetModelDto.prototype, "isDraw", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '是否支持文件上传', required: false }),
__metadata("design:type", Number)
], SetModelDto.prototype, "isFileUpload", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '是否使用token计费', required: false }),
__metadata("design:type", Boolean)

View File

@@ -22,7 +22,7 @@ __decorate([
__metadata("design:type", Number)
], SetModelTypeDto.prototype, "keyType", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: '文心一言普通模型', description: '模型中文名称', required: true }),
(0, swagger_1.ApiProperty)({ example: '普通模型', description: '模型中文名称', required: true }),
__metadata("design:type", String)
], SetModelTypeDto.prototype, "modelName", void 0);
__decorate([
@@ -34,13 +34,17 @@ __decorate([
__metadata("design:type", String)
], SetModelTypeDto.prototype, "model", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '温度' }),
(0, swagger_1.ApiProperty)({ example: 300, description: '模型超时时间', required: false }),
__metadata("design:type", Number)
], SetModelTypeDto.prototype, "temperature", void 0);
], SetModelTypeDto.prototype, "timeout", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '扣费类型 1 普通 2 高级余额', required: false }),
__metadata("design:type", Number)
], SetModelTypeDto.prototype, "deductType", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '文件上传类型 0 : 不使用 1: ALL类型 2: 4V类型', required: false }),
__metadata("design:type", Number)
], SetModelTypeDto.prototype, "isFileUpload", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: true, description: '单次扣除金额', required: false }),
__metadata("design:type", Number)

View File

@@ -38,6 +38,9 @@ let ModelsController = class ModelsController {
modelsList() {
return this.modelsService.modelsList();
}
getMjInfo() {
return this.modelsService.getMjInfo();
}
baseConfig() {
return this.modelsService.getBaseConfig();
}
@@ -89,6 +92,13 @@ __decorate([
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], ModelsController.prototype, "modelsList", null);
__decorate([
(0, common_1.Get)('mjInfo'),
(0, swagger_1.ApiOperation)({ summary: '客户端查询当前所有可以使用的模型' }),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], ModelsController.prototype, "getMjInfo", null);
__decorate([
(0, common_1.Get)('baseConfig'),
(0, swagger_1.ApiOperation)({ summary: '客户端查询当前已经配置模型的基础配置' }),

View File

@@ -15,7 +15,7 @@ const baseEntity_1 = require("../../common/entity/baseEntity");
let ModelsEntity = class ModelsEntity extends baseEntity_1.BaseEntity {
};
__decorate([
(0, typeorm_1.Column)({ comment: 'key模型类型 1: openai 2: 文心一言 3:清华智谱' }),
(0, typeorm_1.Column)({ comment: '模型类型 1: 普通对话 2: 绘画 3:高级对话' }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "keyType", void 0);
__decorate([
@@ -23,37 +23,69 @@ __decorate([
__metadata("design:type", String)
], ModelsEntity.prototype, "modelName", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型的key' }),
(0, typeorm_1.Column)({ comment: '绑定的模型是?' }),
__metadata("design:type", String)
], ModelsEntity.prototype, "model", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型头像', nullable: true }),
__metadata("design:type", String)
], ModelsEntity.prototype, "modelAvatar", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型排序', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "modelOrder", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型上下文支持的最大Token', default: 2000, nullable: true }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "maxModelTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型上下文最大条数', nullable: true }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "maxRounds", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型上下文最大条数', nullable: true }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "timeout", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型单次调用扣除的次数', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "deduct", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型扣除余额类型 1: 普通模型 2: 高级模型', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "deductType", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否使用token计费: 0:不是 1: 是', default: 0 }),
__metadata("design:type", Boolean)
], ModelsEntity.prototype, "isTokenBased", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否支持文件上传: 0:不是 1: 附件链接格式 2: 4V格式', default: 0 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "isFileUpload", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'token计费比例', default: 0 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "tokenFeeRatio", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型附加信息', nullable: true }),
__metadata("design:type", String)
], ModelsEntity.prototype, "remark", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型的key', nullable: true }),
__metadata("design:type", String)
], ModelsEntity.prototype, "key", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型的secret', default: null }),
__metadata("design:type", String)
], ModelsEntity.prototype, "secret", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '部分模型的调用token', default: null }),
__metadata("design:type", String)
], ModelsEntity.prototype, "accessToken", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '使用的状态: 0:禁用 1启用', default: 1 }),
__metadata("design:type", Boolean)
], ModelsEntity.prototype, "status", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '绑定的模型是?' }),
__metadata("design:type", String)
], ModelsEntity.prototype, "model", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key的状态: 1:有效 -1:被封号 -2: 错误的秘钥 -3: 余额使用完了', default: 1 }),
(0, typeorm_1.Column)({ comment: 'key的状态: 1:有效 -1:被封号 -2: 错误的秘钥 -3: 余额使用完了', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "keyStatus", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key权重', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "keyWeight", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key权重', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "modelOrder", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'key的使用次数', default: 0 }),
__metadata("design:type", Number)
@@ -62,50 +94,10 @@ __decorate([
(0, typeorm_1.Column)({ comment: 'key的已经使用的token数量', default: 0 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "useToken", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型支持的最大Token', default: 1000 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "maxModelTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '模型设置的最大回复Token', default: 4096 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "maxResponseTokens", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '当前模型的代理地址', nullable: true }),
__metadata("design:type", String)
], ModelsEntity.prototype, "proxyUrl", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '当前模型的超时时间单位s', default: 200 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "timeout", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '单次调用扣除的次数', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "deduct", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '扣除余额类型 1 普通模型 2高级模型', default: 1 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "deductType", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '备注信息', nullable: true }),
__metadata("design:type", String)
], ModelsEntity.prototype, "remark", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '限制用户上下文最大次数', nullable: true }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "maxRounds", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否是绘画key: 0:不是 1是', default: 0 }),
__metadata("design:type", Boolean)
], ModelsEntity.prototype, "isDraw", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '是否使用token计费: 0:不是 1是', default: 0 }),
__metadata("design:type", Boolean)
], ModelsEntity.prototype, "isTokenBased", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: 'token计费比例', default: 0 }),
__metadata("design:type", Number)
], ModelsEntity.prototype, "tokenFeeRatio", void 0);
ModelsEntity = __decorate([
(0, typeorm_1.Entity)({ name: 'models' })
], ModelsEntity);

View File

@@ -76,30 +76,41 @@ let ModelsService = class ModelsService {
this.initCalcKey();
}
async getCurrentModelKeyInfo(model) {
if (!this.keyPoolMap[model]) {
throw new common_1.HttpException('当前调用模型已经被移除、请重新选择模型!', common_1.HttpStatus.BAD_REQUEST);
const modelKeyInfo = await this.modelsEntity.findOne({ where: { model: model } });
if (!modelKeyInfo) {
throw new common_1.HttpException('当前调用模型的key未找到请重新选择模型', common_1.HttpStatus.BAD_REQUEST);
}
this.keyPoolIndexMap[model]++;
const index = this.keyPoolIndexMap[model];
if (index >= this.keyPoolMap[model].length)
this.keyPoolIndexMap[model] = 0;
const key = this.keyPoolMap[model][this.keyPoolIndexMap[model]];
return key;
return modelKeyInfo;
}
async getSpecialModelKeyInfo(modelPrefix) {
const matchingModels = await this.modelsEntity.find({
where: { model: (0, typeorm_2.Like)(`${modelPrefix}%`) }
});
if (matchingModels.length === 0) {
throw new common_1.HttpException('未找到匹配的模型,请重新选择模型!', common_1.HttpStatus.BAD_REQUEST);
}
const firstMatchModel = matchingModels[0];
const modifiedModelName = firstMatchModel.model.replace(modelPrefix, '');
const modifiedModel = Object.assign(Object.assign({}, firstMatchModel), { model: modifiedModelName });
return modifiedModel;
}
async getBaseConfig(appId) {
if (!this.modelTypes.length || !Object.keys(this.modelMaps).length)
return;
const modelTypeInfo = appId ? this.modelTypes.find(item => Number(item.val) === 1) : this.modelTypes[0];
const modelTypeInfo = this.modelTypes[0];
if (!modelTypeInfo)
return;
const { keyType, modelName, model, maxModelTokens, maxResponseTokens, deductType, deduct, maxRounds } = this.modelMaps[modelTypeInfo.val][0];
const { keyType, modelName, model, deductType, deduct, isFileUpload } = this.modelMaps[modelTypeInfo.val][0];
return {
modelTypeInfo,
modelInfo: { keyType, modelName, model, maxModelTokens, maxResponseTokens, topN: 0.8, systemMessage: '', deductType, deduct, maxRounds, rounds: 8 }
modelInfo: { keyType, modelName, model, deductType, deduct, isFileUpload }
};
}
async setModel(params) {
try {
if (isNaN(params.timeout)) {
params.timeout = null;
}
const { id } = params;
params.status && (params.keyStatus = 1);
if (id) {
@@ -119,6 +130,9 @@ let ModelsService = class ModelsService {
try {
const data = JSON.parse(JSON.stringify(params));
data.key = k;
if (isNaN(data.timeout)) {
data.timeout = null;
}
return data;
}
catch (error) {
@@ -166,7 +180,6 @@ let ModelsService = class ModelsService {
if (role !== 'super') {
rows.forEach(item => {
item.key && (item.key = (0, utils_1.hideString)(item.key));
item.secret && (item.secret = (0, utils_1.hideString)(item.secret));
});
}
return { rows, count };
@@ -177,8 +190,8 @@ let ModelsService = class ModelsService {
cloneModelMaps[key] = cloneModelMaps[key].sort((a, b) => a.modelOrder - b.modelOrder);
cloneModelMaps[key] = Array.from(cloneModelMaps[key]
.map(t => {
const { modelName, model, deduct, deductType, maxRounds } = t;
return { modelName, model, deduct, deductType, maxRounds };
const { modelName, keyType, model, deduct, deductType, maxRounds, modelAvatar, isFileUpload } = t;
return { modelName, keyType, model, deduct, deductType, maxRounds, modelAvatar, isFileUpload };
})
.reduce((map, obj) => map.set(obj.modelName, obj), new Map()).values());
});
@@ -187,6 +200,20 @@ let ModelsService = class ModelsService {
modelMaps: cloneModelMaps
};
}
async getMjInfo() {
const modelInfo = await this.modelsEntity.findOne({ where: { model: "midjourney" } });
if (modelInfo) {
return {
modelName: modelInfo.modelName,
model: modelInfo.model,
deduct: modelInfo.deduct,
deductType: modelInfo.deductType,
};
}
else {
return null;
}
}
async saveUseLog(id, useToken) {
await this.modelsEntity
.createQueryBuilder()
@@ -195,13 +222,6 @@ let ModelsService = class ModelsService {
.where('id = :id', { id })
.execute();
}
async getRandomDrawKey() {
const drawkeys = await this.modelsEntity.find({ where: { isDraw: true, status: true } });
if (!drawkeys.length) {
throw new common_1.HttpException('当前未指定特殊模型KEY、前往后台模型池设置吧', common_1.HttpStatus.BAD_REQUEST);
}
return (0, utils_1.getRandomItemFromArray)(drawkeys);
}
async getAllKey() {
return await this.modelsEntity.find();
}

View File

@@ -10,7 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OfficialService = void 0;
const chatgpt_service_1 = require("./../chatgpt/chatgpt.service");
const chat_service_1 = require("../chat/chat.service");
const globalConfig_service_1 = require("./../globalConfig/globalConfig.service");
const auth_service_1 = require("./../auth/auth.service");
const user_service_1 = require("./../user/user.service");
@@ -123,7 +123,7 @@ let OfficialService = class OfficialService {
return res;
}
async verify(signature, nonce, timestamp) {
const token = (await this.globalConfigService.getConfigs(['wechatOfficialToken'])) || 'jiangly';
const token = (await this.globalConfigService.getConfigs(['wechatOfficialToken'])) || '';
return (await this.sha1([token, nonce, timestamp].sort().join(''))) == signature;
}
sha1(data) {
@@ -152,8 +152,7 @@ let OfficialService = class OfficialService {
let question = '';
try {
console.log('来自公众号的询问问题 =======> ', msg);
const response = await Promise.race([this.chatgptService.chatSyncFree(msg), timeoutPromise]);
question = response || await this.autoreplyService.checkAutoReply(msg);
question = await this.autoreplyService.checkAutoReply(msg);
}
catch (error) {
console.log('来自公众号的回复问题 =======> 超时导致问题无法回答完整');
@@ -168,6 +167,6 @@ OfficialService = __decorate([
user_service_1.UserService,
auth_service_1.AuthService,
globalConfig_service_1.GlobalConfigService,
chatgpt_service_1.ChatgptService])
chat_service_1.ChatService])
], OfficialService);
exports.OfficialService = OfficialService;

View File

@@ -23,7 +23,7 @@ __decorate([
__metadata("design:type", String)
], OrderEntity.prototype, "tradeId", void 0);
__decorate([
(0, typeorm_1.Column)({ comment: '支付平台【epay|hupi】', length: 32, nullable: true }),
(0, typeorm_1.Column)({ comment: '支付平台【epay|hupi|ltzf】)', length: 32, nullable: true }),
__metadata("design:type", String)
], OrderEntity.prototype, "payPlatform", void 0);
__decorate([

View File

@@ -24,6 +24,10 @@ let PayController = class PayController {
console.log('hupi ->body: ', body);
return this.payService.notify(body);
}
notifyLtzf(body) {
console.log('ltzf ->body: ', body);
return this.payService.notify(body);
}
notifyEpay(query) {
console.log('epay ->query: ', query);
return this.payService.notify(query);
@@ -37,6 +41,14 @@ __decorate([
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], PayController.prototype, "notifyHupi", null);
__decorate([
(0, common_1.Post)('notify'),
(0, swagger_1.ApiOperation)({ summary: 'ltzf支付结果通知' }),
__param(0, (0, common_1.Body)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], PayController.prototype, "notifyLtzf", null);
__decorate([
(0, common_1.Get)('notify'),
(0, swagger_1.ApiOperation)({ summary: 'Epay支付结果通知' }),

View File

@@ -43,6 +43,9 @@ let PayService = class PayService {
if (params['attach'] == 'hupi') {
return this.notifyHupi(params);
}
if (params['attach'] == 'ltzf') {
return this.notifyLtzf(params);
}
if (typeof params['resource'] == 'object') {
return this.notifyWeChat(params);
}
@@ -69,6 +72,9 @@ let PayService = class PayService {
if (order.payPlatform == 'hupi') {
return this.payHupi(userId, orderId, payType);
}
if (order.payPlatform == 'ltzf') {
return this.payLtzf(userId, orderId, payType);
}
}
catch (error) {
console.log('支付请求失败: ', error);
@@ -414,6 +420,92 @@ let PayService = class PayService {
.join('&') + secret;
return crypto.createHash('md5').update(str).digest('hex');
}
ltzfSign(params, secret) {
const paramsArr = Object.keys(params);
paramsArr.sort();
const stringArr = [];
paramsArr.map(key => {
stringArr.push(key + '=' + params[key]);
});
stringArr.push("key=" + secret);
const str = stringArr.join('&');
return crypto.createHash('md5').update(str).digest('hex').toUpperCase();
}
async payLtzf(userId, orderId, payType = 'wxpay') {
const order = await this.orderEntity.findOne({ where: { userId, orderId } });
if (!order)
throw new common_1.HttpException('订单不存在!', common_1.HttpStatus.BAD_REQUEST);
const goods = await this.cramiPackageEntity.findOne({ where: { id: order.goodsId } });
if (!goods)
throw new common_1.HttpException('套餐不存在!', common_1.HttpStatus.BAD_REQUEST);
const { payLtzfMchId, payLtzfSecret, payLtzfNotifyUrl, payLtzfReturnUrl, } = await this.globalConfigService.getConfigs([
'payLtzfMchId',
'payLtzfSecret',
'payLtzfNotifyUrl',
'payLtzfReturnUrl',
]);
const params = {};
params['mch_id'] = payLtzfMchId;
params['timestamp'] = (Date.now() / 1000).toFixed(0);
params['out_trade_no'] = orderId;
params['body'] = goods.name;
params['total_fee'] = order.total;
params['notify_url'] = payLtzfNotifyUrl;
params['sign'] = this.ltzfSign(params, payLtzfSecret);
params['attach'] = 'ltzf';
params['return_url'] = payLtzfReturnUrl;
const formBody = Object.keys(params).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key])).join('&');
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
const response = await axios_1.default.post('https://api.ltzf.cn/api/wxpay/jsapi_convenient', formBody, config);
const { code, data, msg } = response.data;
if (code != 0)
throw new common_1.HttpException(msg, common_1.HttpStatus.BAD_REQUEST);
const url_qrcode = data.QRcode_url;
const url = data.order_url;
return { url_qrcode, url };
}
async queryLtzf(orderId) {
const { payLtzfMchId, payLtzfSecret } = await this.globalConfigService.getConfigs(['payLtzfMchId', 'payLtzfSecret']);
const params = {};
params['mch_id'] = payLtzfMchId;
params['timestamp'] = (Date.now() / 1000).toFixed(0);
params['out_trade_no'] = orderId;
params['sign'] = this.ltzfSign(params, payLtzfSecret);
const formBody = Object.keys(params).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key])).join('&');
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
const { data: { code, msg, data: result }, } = await axios_1.default.post('https://api.ltzf.cn/api/wxpay/get_pay_order', formBody, config);
if (code != 0)
throw new common_1.HttpException(msg + JSON.stringify(params), common_1.HttpStatus.BAD_REQUEST);
return result;
}
async notifyLtzf(params) {
const payLtzfSecret = await this.globalConfigService.getConfigs(['payLtzfSecret']);
const hash = params['sign'];
delete params['sign'];
delete params['pay_channel'];
delete params['trade_type'];
delete params['success_time'];
delete params['attach'];
delete params['openid'];
if (this.ltzfSign(params, payLtzfSecret) != hash)
return 'FAIL';
const order = await this.orderEntity.findOne({ where: { orderId: params['out_trade_no'], status: 0 } });
if (!order)
return 'FAIL';
await this.userBalanceService.addBalanceToOrder(order);
const result = await this.orderEntity.update({ orderId: params['out_trade_no'] }, { status: 1, paydAt: new Date() });
if (result.affected != 1)
return 'FAIL';
return 'SUCCESS';
}
};
PayService = __decorate([
(0, common_1.Injectable)(),

View File

@@ -48,6 +48,16 @@ __decorate([
(0, class_validator_1.IsOptional)(),
__metadata("design:type", Number)
], MjDrawDto.prototype, "drawId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: 'customId' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], MjDrawDto.prototype, "customId", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: 'base64' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)
], MjDrawDto.prototype, "base64", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 1, description: '任务ID' }),
(0, class_validator_1.IsOptional)(),

View File

@@ -13,18 +13,19 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueueService = void 0;
const common_1 = require("@nestjs/common");
const bull_1 = require("@nestjs/bull");
const utils_1 = require("../../common/utils");
const midjourney_service_1 = require("../midjourney/midjourney.service");
const userBalance_service_1 = require("../userBalance/userBalance.service");
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
const models_service_1 = require("../models/models.service");
let QueueService = class QueueService {
constructor(mjDrawQueue, midjourneyService, userBalanceService, globalConfigService) {
constructor(mjDrawQueue, midjourneyService, userBalanceService, globalConfigService, modelsService) {
this.mjDrawQueue = mjDrawQueue;
this.midjourneyService = midjourneyService;
this.userBalanceService = userBalanceService;
this.globalConfigService = globalConfigService;
this.modelsService = modelsService;
this.jobIds = [];
}
async onApplicationBootstrap() {
@@ -32,9 +33,12 @@ let QueueService = class QueueService {
await this.midjourneyService.cleanQueue();
}
async addMjDrawQueue(body, req) {
const { imgUrl, orderId, action, drawId } = body;
const { orderId, action, drawId } = body;
await this.midjourneyService.checkLimit(req);
await this.userBalanceService.validateBalance(req, 'mjDraw', action === 'UPSCALE' ? 1 : 4);
const detailKeyInfo = await this.modelsService.getCurrentModelKeyInfo('midjourney');
const keyId = detailKeyInfo === null || detailKeyInfo === void 0 ? void 0 : detailKeyInfo.id;
const { key, proxyUrl, deduct, deductType, timeout } = detailKeyInfo;
await this.userBalanceService.validateBalance(req, deductType, action === 'UPSCALE' ? deduct : deduct * 4);
if (action === 'IMAGINE') {
const randomDrawId = `${(0, utils_1.createRandomUid)()}`;
const params = Object.assign(Object.assign({}, body), { userId: req.user.id, randomDrawId });
@@ -45,18 +49,19 @@ let QueueService = class QueueService {
return true;
}
else {
const { orderId, action, drawId } = body;
const actionDetail = await this.midjourneyService.getDrawActionDetail(action, drawId, orderId);
const params = Object.assign(Object.assign(Object.assign({}, body), { userId: req.user.id }), actionDetail);
const { action, customId, base64 } = body;
let { drawId } = body;
if (action === 'MODAL') {
const result = await this.midjourneyService.getDrawActionDetail(action, drawId, customId);
drawId = result.drawId;
}
const params = Object.assign(Object.assign({}, body), { userId: req.user.id, drawId });
const res = await this.midjourneyService.addDrawQueue(params);
const timeout = (await this.globalConfigService.getConfigs(['mjTimeoutMs'])) || 200000;
const job = await this.mjDrawQueue.add('mjDraw', { id: res.id, action, userId: req.user.id }, { delay: 1000, timeout: +timeout });
const timeout = (await this.globalConfigService.getConfigs(['mjTimeoutMs'])) || 300000;
const job = await this.mjDrawQueue.add('mjDraw', { id: res.id, action, userId: req.user.id, base64 }, { delay: 1000, timeout: +timeout });
this.jobIds.push(job.id);
return;
}
if (!drawId || !orderId) {
throw new common_1.HttpException('缺少必要参数!', common_1.HttpStatus.BAD_REQUEST);
}
}
async getQueue() {
return { jobIds: this.jobIds };
@@ -66,6 +71,7 @@ QueueService = __decorate([
__param(0, (0, bull_1.InjectQueue)('MJDRAW')),
__metadata("design:paramtypes", [Object, midjourney_service_1.MidjourneyService,
userBalance_service_1.UserBalanceService,
globalConfig_service_1.GlobalConfigService])
globalConfig_service_1.GlobalConfigService,
models_service_1.ModelsService])
], QueueService);
exports.QueueService = QueueService;

View File

@@ -83,7 +83,7 @@ let StatisticService = class StatisticService {
return userCount;
}
async countChats() {
const chatCount = await this.chatLogEntity.count({ where: { type: balance_constant_1.DeductionKey.CHAT_TYPE } });
const chatCount = await this.chatLogEntity.count({ where: { type: balance_constant_1.ChatType.NORMAL_CHAT } });
return chatCount;
}
async countNewChatsToday() {
@@ -92,14 +92,14 @@ let StatisticService = class StatisticService {
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000);
const queryBuilder = this.chatLogEntity.createQueryBuilder('chatLog');
const chatCount = await queryBuilder
.where('chatLog.type = :type', { type: balance_constant_1.DeductionKey.CHAT_TYPE })
.where('chatLog.type = :type', { type: balance_constant_1.ChatType.NORMAL_CHAT })
.andWhere('chatLog.createdAt >= :today', { today })
.andWhere('chatLog.createdAt < :tomorrow', { tomorrow })
.getCount();
return chatCount;
}
async countDraws() {
const drawCount = await this.chatLogEntity.count({ where: { type: balance_constant_1.DeductionKey.PAINT_TYPE } });
const drawCount = await this.chatLogEntity.count({ where: { type: balance_constant_1.ChatType.PAINT } });
return drawCount;
}
async countNewDrawsToday() {
@@ -108,7 +108,7 @@ let StatisticService = class StatisticService {
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000);
const queryBuilder = this.chatLogEntity.createQueryBuilder('chatLog');
const drawCount = await queryBuilder
.where('chatLog.type = :type', { type: balance_constant_1.DeductionKey.PAINT_TYPE })
.where('chatLog.type = :type', { type: balance_constant_1.ChatType.PAINT })
.andWhere('chatLog.createdAt >= :today', { today })
.andWhere('chatLog.createdAt < :tomorrow', { tomorrow })
.getCount();
@@ -133,7 +133,7 @@ let StatisticService = class StatisticService {
const queryBuilder = this.chatLogEntity.createQueryBuilder('chatlog');
const result = await queryBuilder
.select(`DATE(chatlog.createdAt) as date, COUNT(*) as count`)
.where(`chatlog.type = :type`, { type: balance_constant_1.DeductionKey.CHAT_TYPE })
.where(`chatlog.type = :type`, { type: balance_constant_1.ChatType.NORMAL_CHAT })
.andWhere('chatlog.createdAt >= :startDate', { startDate })
.groupBy('date')
.orderBy('date')
@@ -161,7 +161,7 @@ let StatisticService = class StatisticService {
const queryBuilder = this.chatLogEntity.createQueryBuilder('chatlog');
const result = await queryBuilder
.select(`DATE(chatlog.createdAt) as date, COUNT(*) as count`)
.where(`chatlog.type = :type`, { type: balance_constant_1.DeductionKey.PAINT_TYPE })
.where(`chatlog.type = :type`, { type: balance_constant_1.ChatType.PAINT })
.andWhere('chatlog.createdAt >= :startDate', { startDate })
.groupBy('date')
.orderBy('date')

View File

@@ -24,9 +24,6 @@ let UploadController = class UploadController {
async uploadFile(file) {
return this.uploadService.uploadFile(file);
}
async test() {
return this.uploadService.test();
}
};
__decorate([
(0, common_1.Post)('file'),
@@ -37,13 +34,6 @@ __decorate([
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], UploadController.prototype, "uploadFile", null);
__decorate([
(0, common_1.Get)('test'),
(0, swagger_1.ApiOperation)({ summary: '测试' }),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], UploadController.prototype, "test", null);
UploadController = __decorate([
(0, swagger_1.ApiTags)('upload'),
(0, common_1.Controller)('upload'),

View File

@@ -233,16 +233,6 @@ let UploadService = class UploadService {
return { key, uploadPath };
}
}
async test() {
const params = {
filename: 'mjtest.png',
dir: 'mj',
url: 'https://cdn.discordapp.com/attachments/1097409128491651135/1169910551275638855/snine_60b5c001b_A_young_girl_smiles_brightly_in_the_pure_blue_f_8a41fe5f-5101-4c1e-b948-a748a0583577.png?ex=65571f1b&is=6544aa1b&hm=b82f2d88224eb7942e24c63a8e519c7693de12a2b96daa0f327dfb8f691b1480&',
};
const res = await this.uploadFileFromUrl(params);
console.log('res: ', res);
return res;
}
async getBufferFromUrl(url) {
const proxyMj = (await this.globalConfigService.getConfigs(['mjProxy'])) || 0;
const response = await axios_1.default.get(url, { responseType: 'stream' });

View File

@@ -23,7 +23,7 @@ __decorate([
__metadata("design:type", String)
], UpdateUserDto.prototype, "username", void 0);
__decorate([
(0, swagger_1.ApiProperty)({ example: 'https://file.jiangly.com/images/93971628.jpeg', description: '用户头像', required: false }),
(0, swagger_1.ApiProperty)({ example: '', description: '用户头像', required: false }),
(0, class_validator_1.IsNotEmpty)({ message: '用户头像不能为空!' }),
(0, class_validator_1.IsOptional)(),
__metadata("design:type", String)

View File

@@ -42,7 +42,7 @@ __decorate([
(0, typeorm_1.Column)({
length: 300,
nullable: true,
default: 'https://public-1300678944.cos.ap-shanghai.myqcloud.com/ai/7f042f63f.png',
default: '',
comment: '用户头像',
}),
__metadata("design:type", String)

View File

@@ -19,7 +19,7 @@ const balance_entity_1 = require("../userBalance/balance.entity");
const accountLog_entity_1 = require("../userBalance/accountLog.entity");
const config_entity_1 = require("../globalConfig/config.entity");
const cramiPackage_entity_1 = require("../crami/cramiPackage.entity");
const whiteList_entity_1 = require("../chatgpt/whiteList.entity");
const whiteList_entity_1 = require("../chat/whiteList.entity");
const userBalance_entity_1 = require("../userBalance/userBalance.entity");
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
const redisCache_service_1 = require("../redisCache/redisCache.service");

View File

@@ -28,7 +28,7 @@ const userBalance_service_1 = require("../userBalance/userBalance.service");
const utils_1 = require("../../common/utils");
const balance_constant_1 = require("../../common/constants/balance.constant");
const config_entity_1 = require("../globalConfig/config.entity");
const whiteList_entity_1 = require("../chatgpt/whiteList.entity");
const whiteList_entity_1 = require("../chat/whiteList.entity");
let UserService = class UserService {
constructor(userEntity, whiteListEntity, connection, verificationService, mailerService, userBalanceService, globalConfigService, configEntity) {
this.userEntity = userEntity;
@@ -265,8 +265,9 @@ let UserService = class UserService {
const { inviteCode } = u;
if (!inviteCode)
return [];
const invitedBy = inviteCode;
const [rows, count] = await this.userEntity.findAndCount({
where: { inviteCode },
where: { invitedBy },
order: { id: 'DESC' },
select: ['username', 'email', 'createdAt', 'status', 'avatar'],
take: size,
@@ -350,15 +351,9 @@ let UserService = class UserService {
if (n.role === 'super') {
throw new common_1.HttpException('超级管理员不可被操作!', common_1.HttpStatus.BAD_REQUEST);
}
if (n.status === user_constant_1.UserStatusEnum.PENDING) {
throw new common_1.HttpException('未激活用户不可手动变更状态!', common_1.HttpStatus.BAD_REQUEST);
}
if (n.role === 'super') {
throw new common_1.HttpException('超级管理员不可被操作!', common_1.HttpStatus.BAD_REQUEST);
}
if (status === user_constant_1.UserStatusEnum.PENDING) {
throw new common_1.HttpException('不可将用户置为未激活状态!', common_1.HttpStatus.BAD_REQUEST);
}
const r = await this.userEntity.update({ id }, { status });
if (r.affected <= 0) {
throw new common_1.HttpException('修改用户状态失败!', common_1.HttpStatus.BAD_REQUEST);

View File

@@ -20,7 +20,7 @@ const cramiPackage_entity_1 = require("../crami/cramiPackage.entity");
const userBalance_entity_1 = require("./userBalance.entity");
const user_entity_1 = require("../user/user.entity");
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
const whiteList_entity_1 = require("../chatgpt/whiteList.entity");
const whiteList_entity_1 = require("../chat/whiteList.entity");
const redisCache_service_1 = require("../redisCache/redisCache.service");
const fingerprint_entity_1 = require("./fingerprint.entity");
const chatLog_entity_1 = require("../chatLog/chatLog.entity");

View File

@@ -28,7 +28,7 @@ const date_1 = require("../../common/utils/date");
const user_entity_1 = require("../user/user.entity");
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
const sales_service_1 = require("../sales/sales.service");
const whiteList_entity_1 = require("../chatgpt/whiteList.entity");
const whiteList_entity_1 = require("../chat/whiteList.entity");
const fingerprint_entity_1 = require("./fingerprint.entity");
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
@@ -138,21 +138,21 @@ let UserBalanceService = class UserBalanceService {
}
const res = await this.configEntity.findOne({ where: { configKey: 'vxNumber' } });
const vxNumber = res ? res.configVal : '---';
const memberKey = type === 'model3' ? 'memberModel3Count' : type === 'model4' ? 'memberModel4Count' : type === 'mjDraw' ? 'memberDrawMjCount' : null;
const baseKey = type === 'model3' ? 'model3Count' : type === 'model4' ? 'model4Count' : type === 'mjDraw' ? 'drawMjCount' : null;
const memberKey = type === 1 ? 'memberModel3Count' : type === 2 ? 'memberModel4Count' : type === 3 ? 'memberDrawMjCount' : null;
const baseKey = type === 1 ? 'model3Count' : type === 2 ? 'model4Count' : type === 3 ? 'drawMjCount' : null;
if (b.packageId && b[memberKey] < amount) {
if (b[baseKey] < amount) {
throw new common_1.HttpException(`您的账户余额不足,如果想继续体验服务,请联系管理员 <VX: ${vxNumber}> 或购买专属套餐 `, common_1.HttpStatus.PAYMENT_REQUIRED);
throw new common_1.HttpException(`您的账户余额不足,如果想继续体验服务,请联系管理员或购买专属套餐 `, common_1.HttpStatus.PAYMENT_REQUIRED);
}
}
if (!b.packageId && b[baseKey] < amount) {
throw new common_1.HttpException(`您的账户余额不足,如果想继续体验服务,请联系管理员 <VX: ${vxNumber}> 或购买专属套餐 `, common_1.HttpStatus.PAYMENT_REQUIRED);
throw new common_1.HttpException(`您的账户余额不足,如果想继续体验服务,请联系管理员或购买专属套餐 `, common_1.HttpStatus.PAYMENT_REQUIRED);
}
return b;
}
async validateVisitorBalance(req, type, amount) {
const { id } = req.user;
const baseKey = type === 'model3' ? 'model3Count' : type === 'model4' ? 'model4Count' : type === 'mjDraw' ? 'drawMjCount' : null;
const baseKey = type === 1 ? 'model3Count' : type === 2 ? 'model4Count' : type === 3 ? 'drawMjCount' : null;
const now = new Date();
const log = await this.fingerprintLogEntity.findOne({ where: { fingerprint: id } });
const { visitorModel3Num, visitorModel4Num, visitorMJNum } = await this.globalConfigService.getConfigs(['visitorModel3Num', 'visitorModel4Num', 'visitorMJNum']);
@@ -216,14 +216,14 @@ let UserBalanceService = class UserBalanceService {
if (!b) {
throw new common_1.HttpException('缺失当前用户账户记录!', common_1.HttpStatus.BAD_REQUEST);
}
const memberKey = deductionType === 'model3'
const memberKey = deductionType === 1
? 'memberModel3Count'
: deductionType === 'model4'
: deductionType === 2
? 'memberModel4Count'
: deductionType === 'mjDraw'
: deductionType === 3
? 'memberDrawMjCount'
: null;
const baseKey = deductionType === 'model3' ? 'model3Count' : deductionType === 'model4' ? 'model4Count' : deductionType === 'mjDraw' ? 'drawMjCount' : null;
const baseKey = deductionType === 1 ? 'model3Count' : deductionType === 2 ? 'model4Count' : deductionType === 3 ? 'drawMjCount' : null;
const updateKey = b.packageId && b[memberKey] < amount ? baseKey : b.packageId ? memberKey : baseKey;
let useKey = null;
if (updateKey.includes('odel3')) {
@@ -245,6 +245,9 @@ let UserBalanceService = class UserBalanceService {
if (useKey === 'useModel4Token') {
updateBalance['useModel4Count'] = b['useModel4Count'] + amount;
}
if (useKey === 'useDrawMjToken') {
updateBalance['useDrawMjToken'] = b['useDrawMjToken'] + amount;
}
const result = await this.userBalanceEntity.update({ userId }, updateBalance);
if (result.affected === 0) {
throw new common_1.HttpException('消费余额失败!', common_1.HttpStatus.BAD_REQUEST);