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

37
.env
View File

@ -1,37 +0,0 @@
# server base
PORT=9520
PREFIX=/docs
APIPREFIX=/api
# mysql
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASS=
DB_DATABASE=chatgpt
DB_SYNC=true
# jwt key token过期时间
JWT_SECRET=chat-cooper
JWT_EXPIRESIN=7d
# mailer 邮件服务
MAILER_HOST=smtp.qq.com
MAILER_PORT=587
MAILER_USER=
MAILER_PASS=
MAILER_FROM=
# Redis
REDIS_PORT=6379
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=
REDIS_USER=
# 是否测试环境
ISDEV=FALSE
# mj并发数
CONCURRENCY=5
NAMESPACE=NINEAI

View File

@ -1,6 +1,6 @@
# NineAI 更新整合版
99AI 整合版:基于 NineAI 二开的可商业化 AI Web 应用(免授权,无后门,支持快速部署)
99AI ———— 基于 NineAI 二开的可商业化 AI Web 应用(免授权,无后门,支持快速部署)
## 页面预览
@ -18,6 +18,45 @@
## 更新日志
### v3.0.0
**前端改进**
- 对话页UI重构参考ChatGPT风格增加美观度。
- 新增对话页 Midjourney 绘图功能,包括绘画进度反馈及点按操作。
- Dalle绘图支持模型绘画比例选择方形/宽屏/垂直)。
- 绘图页面新增区域重绘功能。
- 全局字体优先使用系统默认,优化阅读体验。
- 适配ALL模型及GPTs返回图片修正显示过大的问题。
- 对话页根据模型自动展示AI头像可手动替换文件。
**后台配置调整**
- 模型配置迁移到模型管理,分普通对话/绘画/特殊模型。
- 后台支持模型文件上传模块开关区分ALL/4V格式。
- 后台新增 Midjourney 提示词优化开关及优化词配置
**注意**
- 重要:旧版 Midjourney 配置不再生效,需在模型配置绘画模型中重新配置。
- 模型配置支持扣除积分类型选择。
- 后台管理菜单重新排版,精简非必要配置。
**开发版已支持**
- [x] 应用页支持GPTS及固定模型功能。
- [x] 对话使用TTS进行语音播报。
- [x] Dalle绘图支持添加风格参数支持交互式连续绘画。
- [ ] ...
<details>
<summary>历史日志</summary>
### v2.6.0
1. **新增 mj-proxy-plus 支持**:支持[第三方](https://api.lightai.io)中转,添加容错和重试机制。(可联系作者获得 mj-proxy-plus 支持)
@ -41,6 +80,8 @@
4. 增加模型关联 Token 计费(可选)。
5. MJ 版本默认调整为 v6.0。
</details>
## 环境准备
1. **安装 Node.js 环境**

8
dist/app.module.js vendored
View File

@ -16,12 +16,11 @@ const user_module_1 = require("./modules/user/user.module");
const auth_module_1 = require("./modules/auth/auth.module");
const mailer_module_1 = require("./modules/mailer/mailer.module");
const verification_module_1 = require("./modules/verification/verification.module");
const chatgpt_module_1 = require("./modules/chatgpt/chatgpt.module");
const chat_module_1 = require("./modules/chat/chat.module");
const crami_module_1 = require("./modules/crami/crami.module");
const userBalance_module_1 = require("./modules/userBalance/userBalance.module");
const chatLog_module_1 = require("./modules/chatLog/chatLog.module");
const upload_module_1 = require("./modules/upload/upload.module");
const draw_module_1 = require("./modules/draw/draw.module");
const redisCache_module_1 = require("./modules/redisCache/redisCache.module");
const globalConfig_module_1 = require("./modules/globalConfig/globalConfig.module");
const statistic_module_1 = require("./modules/statistic/statistic.module");
@ -30,7 +29,6 @@ const autoreply_module_1 = require("./modules/autoreply/autoreply.module");
const app_module_1 = require("./modules/app/app.module");
const pay_module_1 = require("./modules/pay/pay.module");
const order_module_1 = require("./modules/order/order.module");
const fanyi_module_1 = require("./modules/fanyi/fanyi.module");
const official_module_1 = require("./modules/official/official.module");
const task_module_1 = require("./modules/task/task.module");
const queue_module_1 = require("./modules/queue/queue.module");
@ -60,12 +58,11 @@ AppModule = __decorate([
auth_module_1.AuthModule,
mailer_module_1.MailerModule,
verification_module_1.VerificationModule,
chatgpt_module_1.ChatgptModule,
chat_module_1.ChatModule,
crami_module_1.CramiModule,
userBalance_module_1.UserBalanceModule,
chatLog_module_1.ChatLogModule,
upload_module_1.UploadModule,
draw_module_1.DrawModule,
redisCache_module_1.RedisCacheModule,
globalConfig_module_1.GlobalConfigModule,
statistic_module_1.StatisticModule,
@ -74,7 +71,6 @@ AppModule = __decorate([
app_module_1.AppModule,
pay_module_1.PayModule,
order_module_1.OrderModule,
fanyi_module_1.FanyiModule,
official_module_1.OfficialModule,
task_module_1.TaskModule,
queue_module_1.QueueModule,

View File

@ -1,15 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RechargeType = exports.DeductionKey = exports.DeductionType = void 0;
exports.DeductionType = {
BALANCE: 'BALANCE_TYPE',
CHAT: 'CHAT_TYPE',
PAINT: 'PAINT_TYPE',
};
exports.DeductionKey = {
BALANCE_TYPE: 'balance',
CHAT_TYPE: 'usesLeft',
PAINT_TYPE: 'paintCount',
exports.RechargeType = exports.ChatType = void 0;
exports.ChatType = {
NORMAL_CHAT: 1,
PAINT: 2,
EXTENDED_CHAT: 3,
};
exports.RechargeType = {
REG_GIFT: 1,

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);

View File

@ -1,6 +1,6 @@
{
"name": "99ai",
"version": "2.6.0",
"name": "99AI",
"version": "3.0.0",
"description": "",
"author": "",
"private": true,
@ -48,11 +48,11 @@
"body-parser": "^1.20.2",
"bull": "^4.10.4",
"cache-manager-redis-store": "^3.0.1",
"chatgpt-ai-web": "^1.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"compression": "^1.7.4",
"cos-nodejs-sdk-v5": "^2.11.19",
"css-inline": "^0.11.2",
"dayjs": "^1.11.7",
"decimal.js": "^10.4.3",
"dotenv": "^16.0.3",

View File

@ -1,6 +1,6 @@
{
"apps": {
"name": "99ai-v2.6.0",
"name": "99AI",
"script": "./dist/main.js",
"watch": true,
"ignore_watch": ["node_modules", "logs"],

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{d as u,r as i,s as p,x as f,o as v,c as m,e as a,a as o,f as h,m as b,_ as x,h as I,p as k,i as w,k as y,t as B,b as N,n as g,q as s}from"./index-4eef28ae.js";const c=t=>(k("data-v-599b59df"),t=t(),w(),t),C={class:"notfound"},S={class:"content"},V=c(()=>o("h1",null,"404",-1)),R=c(()=>o("div",{class:"desc"}," 抱歉,你访问的页面不存在 ",-1)),_=u({__name:"[...all]",setup(t){const l=b(),e=i({inter:NaN,countdown:5});p(()=>{e.value.inter&&clearInterval(e.value.inter)}),f(()=>{e.value.inter=setInterval(()=>{e.value.countdown--,e.value.countdown===0&&(e.value.inter&&clearInterval(e.value.inter),n())},1e3)});function n(){l.push("/")}return(q,D)=>{const r=x,d=I("el-button");return v(),m("div",C,[a(r,{name:"404",class:"icon"}),o("div",S,[V,R,a(d,{type:"primary",onClick:n},{default:h(()=>[y(B(N(e).countdown)+" 秒后,返回首页 ",1)]),_:1})])])}}});typeof s=="function"&&s(_);const L=g(_,[["__scopeId","data-v-599b59df"]]);export{L as default};
import{d as u,r as i,s as p,x as f,o as v,c as m,e as a,a as o,f as h,j as b,_ as x,h as I,p as w,i as y,l as k,t as B,b as N,n as g,q as s}from"./index-b779f4e0.js";const c=t=>(w("data-v-599b59df"),t=t(),y(),t),C={class:"notfound"},S={class:"content"},V=c(()=>o("h1",null,"404",-1)),R=c(()=>o("div",{class:"desc"}," 抱歉,你访问的页面不存在 ",-1)),_=u({__name:"[...all]",setup(t){const l=b(),e=i({inter:NaN,countdown:5});p(()=>{e.value.inter&&clearInterval(e.value.inter)}),f(()=>{e.value.inter=setInterval(()=>{e.value.countdown--,e.value.countdown===0&&(e.value.inter&&clearInterval(e.value.inter),n())},1e3)});function n(){l.push("/")}return(j,q)=>{const r=x,d=I("el-button");return v(),m("div",C,[a(r,{name:"404",class:"icon"}),o("div",S,[V,R,a(d,{type:"primary",onClick:n},{default:h(()=>[k(B(N(e).countdown)+" 秒后,返回首页 ",1)]),_:1})])])}}});typeof s=="function"&&s(_);const E=g(_,[["__scopeId","data-v-599b59df"]]);export{E as default};

View File

@ -0,0 +1,9 @@
/**
* Fantastic-admin 提供技术支持
* Powered by Fantastic-admin
* Gitee https://gitee.com/hooray/fantastic-admin
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as F}from"./index-38e73db4.js";import{Y as x,d as G,r as _,Q as R,x as H,h as r,R as O,o as u,c as h,e as a,f as t,S as M,U as P,b as m,l as d,w as $,I as C,t as w,P as Q,q}from"./index-b779f4e0.js";import{r as J,s as K,U as W,p as X}from"./index-7b2ba868.js";import{u as Z}from"./utcformatTime-e76e5157.js";const ee={upgradeBalance:g=>x.post("balance/upgradeBalance",g),queryUserAccountLog:g=>x.get("balance/accountLog",{params:g})},ae=G({__name:"accountLog",setup(g){const T=_(),A=_(0),f=_(!1),n=R({userId:"",rechargeType:"",packageId:"",page:1,size:15});R({model3Count:[{required:!0,message:"请填写赠送基础模型额度",trigger:"blur"}],model4Count:[{required:!0,message:"请填写赠送高级模型额度",trigger:"blur"}],drawMjCount:[{required:!0,message:"请填写赠送绘画积分额度",trigger:"blur"}]});const U=_([]),S=_([]);async function i(){try{f.value=!0;const s=await ee.queryUserAccountLog(n),{rows:l,count:b}=s.data;f.value=!1,A.value=b,S.value=l}catch{f.value=!1}}async function D(s){const l=await Q.queryAllUser({size:30,keyword:s});U.value=l.data.rows}function V(s){s==null||s.resetFields(),i()}return H(()=>i()),(s,l)=>{const b=r("el-option"),k=r("el-select"),y=r("el-form-item"),z=r("el-button"),Y=r("el-form"),I=F,L=r("el-avatar"),o=r("el-table-column"),v=r("el-tag"),B=r("el-table"),E=r("el-pagination"),j=r("el-row"),N=O("loading");return u(),h("div",null,[a(I,null,{default:t(()=>[a(Y,{ref_key:"formRef",ref:T,inline:!0,model:n},{default:t(()=>[a(y,{label:"用户名称",prop:"userId"},{default:t(()=>[a(k,{modelValue:n.userId,"onUpdate:modelValue":l[0]||(l[0]=e=>n.userId=e),filterable:"",clearable:"",remote:"","reserve-keyword":"",placeholder:"昵称|手机号|邮箱[模糊搜索]","remote-show-suffix":"","remote-method":D},{default:t(()=>[(u(!0),h(M,null,P(U.value,e=>(u(),C(b,{key:e.id,label:e.username,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),a(y,{label:"充值类型",prop:"rechargeType"},{default:t(()=>[a(k,{modelValue:n.rechargeType,"onUpdate:modelValue":l[1]||(l[1]=e=>n.rechargeType=e),placeholder:"请选择充值类型",clearable:""},{default:t(()=>[(u(!0),h(M,null,P(m(J),e=>(u(),C(b,{key:e.value,label:e.label,value:e.value},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),a(y,null,{default:t(()=>[a(z,{type:"primary",onClick:i},{default:t(()=>[d(" 查询 ")]),_:1}),a(z,{onClick:l[2]||(l[2]=e=>V(T.value))},{default:t(()=>[d(" 重置 ")]),_:1})]),_:1})]),_:1},8,["model"])]),_:1}),a(I,{style:{width:"100%"}},{default:t(()=>[$((u(),C(B,{border:"",data:S.value,style:{width:"100%"},size:"large"},{default:t(()=>[a(o,{prop:"avatar",label:"用户头像",width:"120",fixed:""},{default:t(e=>[a(L,{src:e.row.avatar},null,8,["src"])]),_:1}),a(o,{prop:"username",label:"用户名称",width:"150",fixed:""}),a(o,{prop:"id",label:"用户ID",width:"80"}),a(o,{prop:"uid",label:"订单ID",width:"130"}),a(o,{prop:"email",label:"用户邮箱",width:"250",align:"left"}),a(o,{prop:"balanceInfo.useModel4Count",label:"充值类型",width:"160",align:"center"},{default:t(e=>[a(v,{type:"success"},{default:t(()=>{var c,p;return[d(w((c=e.row)!=null&&c.rechargeType?m(K)[(p=e.row)==null?void 0:p.rechargeType]:"---"),1)]}),_:2},1024)]),_:1}),a(o,{prop:"model3Count",label:"基础模型额度",width:"120",align:"center"}),a(o,{prop:"model4Count",label:"高级模型额度",width:"120",align:"center"}),a(o,{prop:"drawMjCount",label:"绘画余额额度",width:"120",align:"center"}),a(o,{label:"额度有效期",width:"170",align:"center"},{default:t(e=>[a(v,{type:"success"},{default:t(()=>{var c,p;return[d(w(((c=e.row)==null?void 0:c.days)<=0?"永久时效":`${(p=e.row)==null?void 0:p.days}`),1)]}),_:2},1024)]),_:1}),a(o,{prop:"status",label:"用户状态",width:"120",align:"center"},{default:t(({row:e})=>[a(v,{type:m(W)[e.status]},{default:t(()=>[d(w(m(X)[e.status]),1)]),_:2},1032,["type"])]),_:1}),a(o,{prop:"createdAt",label:"充值时间",width:"200",align:"center"},{default:t(e=>[d(w(m(Z)(e.row.createdAt,"YYYY-MM-DD hh:mm:ss")),1)]),_:1})]),_:1},8,["data"])),[[N,f.value]]),a(j,{class:"flex justify-end mt-5"},{default:t(()=>[a(E,{"current-page":n.page,"onUpdate:currentPage":l[3]||(l[3]=e=>n.page=e),"page-size":n.size,"onUpdate:pageSize":l[4]||(l[4]=e=>n.size=e),class:"mr-5","page-sizes":[15,30,50,100],layout:"total, sizes, prev, pager, next, jumper",total:A.value,onSizeChange:i,onCurrentChange:i},null,8,["current-page","page-size","total"])]),_:1})]),_:1})])}}});typeof q=="function"&&q(ae);export{ae as default};

View File

@ -1,9 +0,0 @@
/**
* Fantastic-admin 提供技术支持
* Powered by Fantastic-admin
* Gitee https://gitee.com/hooray/fantastic-admin
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as B}from"./index-7911c6db.js";import{a as N}from"./userBalance-567019d9.js";import{r as F,s as G,U as H,p as O}from"./index-66a830a3.js";import{u as $}from"./utcformatTime-e76e5157.js";import{d as Q,r as _,Q as I,x as X,o as u,c as y,e as a,f as t,R as x,S as R,b as m,k as d,w as J,I as h,t as b,P as K,h as r,X as W,q as M}from"./index-4eef28ae.js";const Z=Q({__name:"accountLog",setup(ee){const C=_(),T=_(0),f=_(!1),n=I({userId:"",rechargeType:"",packageId:"",page:1,size:15});I({model3Count:[{required:!0,message:"请填写赠送基础模型额度",trigger:"blur"}],model4Count:[{required:!0,message:"请填写赠送高级模型额度",trigger:"blur"}],drawMjCount:[{required:!0,message:"请填写赠送绘画积分额度",trigger:"blur"}]});const A=_([]),U=_([]);async function i(){try{f.value=!0;const s=await N.queryUserAccountLog(n),{rows:l,count:g}=s.data;f.value=!1,T.value=g,U.value=l}catch{f.value=!1}}async function P(s){const l=await K.queryAllUser({size:30,keyword:s});A.value=l.data.rows}function D(s){s==null||s.resetFields(),i()}return X(()=>i()),(s,l)=>{const g=r("el-option"),k=r("el-select"),w=r("el-form-item"),S=r("el-button"),V=r("el-form"),z=B,q=r("el-avatar"),o=r("el-table-column"),v=r("el-tag"),Y=r("el-table"),E=r("el-pagination"),L=r("el-row"),j=W("loading");return u(),y("div",null,[a(z,null,{default:t(()=>[a(V,{ref_key:"formRef",ref:C,inline:!0,model:n},{default:t(()=>[a(w,{label:"用户名称",prop:"userId"},{default:t(()=>[a(k,{modelValue:n.userId,"onUpdate:modelValue":l[0]||(l[0]=e=>n.userId=e),filterable:"",clearable:"",remote:"","reserve-keyword":"",placeholder:"昵称|手机号|邮箱[模糊搜索]","remote-show-suffix":"","remote-method":P},{default:t(()=>[(u(!0),y(x,null,R(A.value,e=>(u(),h(g,{key:e.id,label:e.username,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),a(w,{label:"充值类型",prop:"rechargeType"},{default:t(()=>[a(k,{modelValue:n.rechargeType,"onUpdate:modelValue":l[1]||(l[1]=e=>n.rechargeType=e),placeholder:"请选择充值类型",clearable:""},{default:t(()=>[(u(!0),y(x,null,R(m(F),e=>(u(),h(g,{key:e.value,label:e.label,value:e.value},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),a(w,null,{default:t(()=>[a(S,{type:"primary",onClick:i},{default:t(()=>[d(" 查询 ")]),_:1}),a(S,{onClick:l[2]||(l[2]=e=>D(C.value))},{default:t(()=>[d(" 重置 ")]),_:1})]),_:1})]),_:1},8,["model"])]),_:1}),a(z,{style:{width:"100%"}},{default:t(()=>[J((u(),h(Y,{border:"",data:U.value,style:{width:"100%"},size:"large"},{default:t(()=>[a(o,{prop:"avatar",label:"用户头像",width:"120",fixed:""},{default:t(e=>[a(q,{src:e.row.avatar},null,8,["src"])]),_:1}),a(o,{prop:"username",label:"用户名称",width:"150",fixed:""}),a(o,{prop:"id",label:"用户ID",width:"80"}),a(o,{prop:"uid",label:"订单ID",width:"130"}),a(o,{prop:"email",label:"用户邮箱",width:"250",align:"left"}),a(o,{prop:"balanceInfo.useModel4Count",label:"充值类型",width:"160",align:"center"},{default:t(e=>[a(v,{type:"success"},{default:t(()=>{var p,c;return[d(b((p=e.row)!=null&&p.rechargeType?m(G)[(c=e.row)==null?void 0:c.rechargeType]:"---"),1)]}),_:2},1024)]),_:1}),a(o,{prop:"model3Count",label:"基础模型额度",width:"120",align:"center"}),a(o,{prop:"model4Count",label:"高级模型额度",width:"120",align:"center"}),a(o,{prop:"drawMjCount",label:"绘画余额额度",width:"120",align:"center"}),a(o,{label:"额度有效期",width:"170",align:"center"},{default:t(e=>[a(v,{type:"success"},{default:t(()=>{var p,c;return[d(b(((p=e.row)==null?void 0:p.days)<=0?"永久时效":`${(c=e.row)==null?void 0:c.days}`),1)]}),_:2},1024)]),_:1}),a(o,{prop:"status",label:"用户状态",width:"120",align:"center"},{default:t(({row:e})=>[a(v,{type:m(H)[e.status]},{default:t(()=>[d(b(m(O)[e.status]),1)]),_:2},1032,["type"])]),_:1}),a(o,{prop:"createdAt",label:"充值时间",width:"200",align:"center"},{default:t(e=>[d(b(m($)(e.row.createdAt,"YYYY-MM-DD hh:mm:ss")),1)]),_:1})]),_:1},8,["data"])),[[j,f.value]]),a(L,{class:"flex justify-end mt-5"},{default:t(()=>[a(E,{"current-page":n.page,"onUpdate:currentPage":l[3]||(l[3]=e=>n.page=e),"page-size":n.size,"onUpdate:pageSize":l[4]||(l[4]=e=>n.size=e),class:"mr-5","page-sizes":[15,30,50,100],layout:"total, sizes, prev, pager, next, jumper",total:T.value,onSizeChange:i,onCurrentChange:i},null,8,["current-page","page-size","total"])]),_:1})]),_:1})])}}});typeof M=="function"&&M(Z);export{Z as default};

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as v}from"./index-7911c6db.js";import{a as O}from"./config-b4a9e7c0.js";import{d as w,Q as B,r as C,B as I,x as R,o as U,c as q,e,f as l,a as b,k as N,b as m,E as g,h as o,q as y}from"./index-4eef28ae.js";const j={class:"flex justify-between"},E=b("b",null,"阿里云OSS参数设置",-1),M=w({__name:"ali",setup(Q){const t=B({aliOssStatus:"",aliOssAccessKeyId:"",aliOssAccessKeySecret:"",aliOssRegion:"",aliOssBucket:""}),_=C();async function f(){const n=await O.queryConfig({keys:["aliOssAccessKeySecret","aliOssRegion","aliOssBucket","aliOssAccessKeyId","aliOssStatus"]});Object.assign(t,n.data)}function x(){var n;(n=_.value)==null||n.validate(async s=>{if(s){try{await O.setConfig({settings:V(t)}),g.success("变更配置信息成功")}catch{}f()}else g.error("请填写完整信息")})}function V(n){return Object.keys(n).map(s=>({configKey:s,configVal:n[s]}))}const i=I(()=>[{required:Number(t.aliOssStatus)===1,message:"开启配置后请填写此项",trigger:"change"}]);return R(()=>{f()}),(n,s)=>{const p=o("el-alert"),S=v,k=o("el-button"),K=o("el-switch"),c=o("el-form-item"),u=o("el-col"),r=o("el-row"),d=o("el-input"),A=o("el-form"),h=o("el-card");return U(),q("div",null,[e(S,null,{default:l(()=>[e(p,{closable:!1,"show-icon":"",title:"阿里云COS参数说明",description:"阿里云的对象存储oss服务、前往阿里云申请oss服务 https://oss.console.aliyun.com/ 、如果同时开启多个存储服务、腾讯云高于阿里云优先级!",type:"success"})]),_:1}),e(h,{style:{margin:"20px"}},{header:l(()=>[b("div",j,[E,e(k,{class:"button",text:"",onClick:x},{default:l(()=>[N(" 保存设置 ")]),_:1})])]),default:l(()=>[e(A,{ref_key:"formRef",ref:_,model:t,"label-width":"120px"},{default:l(()=>[e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"服务启用状态",prop:"aliOssStatus"},{default:l(()=>[e(K,{modelValue:t.aliOssStatus,"onUpdate:modelValue":s[0]||(s[0]=a=>t.aliOssStatus=a),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"accessKeyId",prop:"aliOssAccessKeyId",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssAccessKeyId,"onUpdate:modelValue":s[1]||(s[1]=a=>t.aliOssAccessKeyId=a),placeholder:"请填写SecretId",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"keySecret",prop:"aliOssAccessKeySecret",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssAccessKeySecret,"onUpdate:modelValue":s[2]||(s[2]=a=>t.aliOssAccessKeySecret=a),placeholder:"请填写SecretKey",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"存储桶名称",prop:"aliOssBucket",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssBucket,"onUpdate:modelValue":s[3]||(s[3]=a=>t.aliOssBucket=a),placeholder:"请填写存储桶名称",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"所属地域",prop:"aliOssRegion",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssRegion,"onUpdate:modelValue":s[4]||(s[4]=a=>t.aliOssRegion=a),placeholder:"请填写所属地域(oss-cn-shanghai)",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})])}}});typeof y=="function"&&y(M);export{M as default};
import{_ as v}from"./index-38e73db4.js";import{a as O}from"./config-61dee393.js";import{d as w,Q as B,r as C,B as I,x as R,h as o,o as U,c as q,e,f as l,a as b,l as N,b as m,E as g,q as y}from"./index-b779f4e0.js";const j={class:"flex justify-between"},E=b("b",null,"阿里云OSS参数设置",-1),M=w({__name:"ali",setup(Q){const t=B({aliOssStatus:"",aliOssAccessKeyId:"",aliOssAccessKeySecret:"",aliOssRegion:"",aliOssBucket:""}),_=C();async function f(){const n=await O.queryConfig({keys:["aliOssAccessKeySecret","aliOssRegion","aliOssBucket","aliOssAccessKeyId","aliOssStatus"]});Object.assign(t,n.data)}function x(){var n;(n=_.value)==null||n.validate(async s=>{if(s){try{await O.setConfig({settings:V(t)}),g.success("变更配置信息成功")}catch{}f()}else g.error("请填写完整信息")})}function V(n){return Object.keys(n).map(s=>({configKey:s,configVal:n[s]}))}const i=I(()=>[{required:Number(t.aliOssStatus)===1,message:"开启配置后请填写此项",trigger:"change"}]);return R(()=>{f()}),(n,s)=>{const p=o("el-alert"),S=v,K=o("el-button"),k=o("el-switch"),c=o("el-form-item"),u=o("el-col"),r=o("el-row"),d=o("el-input"),A=o("el-form"),h=o("el-card");return U(),q("div",null,[e(S,null,{default:l(()=>[e(p,{closable:!1,"show-icon":"",title:"阿里云COS参数说明",description:"阿里云的对象存储oss服务、前往阿里云申请oss服务 https://oss.console.aliyun.com/ 、如果同时开启多个存储服务、腾讯云高于阿里云优先级!",type:"success"})]),_:1}),e(h,{style:{margin:"20px"}},{header:l(()=>[b("div",j,[E,e(K,{class:"button",text:"",onClick:x},{default:l(()=>[N(" 保存设置 ")]),_:1})])]),default:l(()=>[e(A,{ref_key:"formRef",ref:_,model:t,"label-width":"120px"},{default:l(()=>[e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"服务启用状态",prop:"aliOssStatus"},{default:l(()=>[e(k,{modelValue:t.aliOssStatus,"onUpdate:modelValue":s[0]||(s[0]=a=>t.aliOssStatus=a),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"accessKeyId",prop:"aliOssAccessKeyId",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssAccessKeyId,"onUpdate:modelValue":s[1]||(s[1]=a=>t.aliOssAccessKeyId=a),placeholder:"请填写SecretId",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"keySecret",prop:"aliOssAccessKeySecret",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssAccessKeySecret,"onUpdate:modelValue":s[2]||(s[2]=a=>t.aliOssAccessKeySecret=a),placeholder:"请填写SecretKey",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"存储桶名称",prop:"aliOssBucket",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssBucket,"onUpdate:modelValue":s[3]||(s[3]=a=>t.aliOssBucket=a),placeholder:"请填写存储桶名称",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(r,null,{default:l(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(c,{label:"所属地域",prop:"aliOssRegion",rules:m(i)},{default:l(()=>[e(d,{modelValue:t.aliOssRegion,"onUpdate:modelValue":s[4]||(s[4]=a=>t.aliOssRegion=a),placeholder:"请填写所属地域(oss-cn-shanghai)",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})])}}});typeof y=="function"&&y(M);export{M as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{Y as o}from"./index-4eef28ae.js";const r={queryBadWords:(d={})=>o.get("badwords/query",{params:d}),queryViolation:(d={})=>o.get("badwords/violation",{params:d}),delBadWords:d=>o.post("badwords/del",d),addBadWords:d=>o.post("badwords/add",d),updateBadWords:d=>o.post("badwords/update",d)};export{r as A};
import{Y as o}from"./index-b779f4e0.js";const r={queryBadWords:(d={})=>o.get("badwords/query",{params:d}),queryViolation:(d={})=>o.get("badwords/violation",{params:d}),delBadWords:d=>o.post("badwords/del",d),addBadWords:d=>o.post("badwords/add",d),updateBadWords:d=>o.post("badwords/update",d)};export{r as A};

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as C}from"./index-7911c6db.js";import{a as m}from"./config-b4a9e7c0.js";import{d as k,Q as q,r as f,x as U,o as j,c as B,e,f as t,a as y,k as E,E as b,h as o,q as x}from"./index-4eef28ae.js";const N={class:"flex justify-between"},I=y("b",null,"百度文本审核参数设置",-1),M=k({__name:"baiduSensitive",setup(O){const a=q({baiduTextStatus:"",baiduTextApiKey:"",baiduTextSecretKey:""}),g=f({baiduTextStatus:[{required:!0,trigger:"blur",message:"请选择是否启用百度文本审核"}],baiduTextSecretKey:[{required:!0,trigger:"blur",message:"请填写百度文本审核SecretKey"}],baiduTextApiKey:[{required:!0,trigger:"blur",message:"请填写百度文本审核APIKey"}]}),c=f();async function d(){const n=await m.queryConfig({keys:["baiduTextStatus","baiduTextSecretKey","baiduTextApiKey"]});Object.assign(a,n.data)}function K(){var n;(n=c.value)==null||n.validate(async l=>{if(l){try{await m.setConfig({settings:T(a)}),b.success("变更配置信息成功")}catch{}d()}else b.error("请填写完整信息")})}function T(n){return Object.keys(n).map(l=>({configKey:l,configVal:n[l]}))}return U(()=>{d()}),(n,l)=>{const _=o("el-alert"),S=C,v=o("el-button"),V=o("el-switch"),w=o("el-tooltip"),i=o("el-form-item"),r=o("el-col"),s=o("el-row"),p=o("el-input"),h=o("el-form"),A=o("el-card");return j(),B("div",null,[e(S,null,{default:t(()=>[e(_,{closable:!1,"show-icon":"",title:"百度文本审核参数说明",description:"接入原因、当前百度云免费5万条申请文档地址https://console.bce.baidu.com/ai/#/ai/antiporn/overview/index 、如果百度云敏感词与自定义敏感词都配置的情况、会先检测百度云后检测自定义的敏感词!",type:"success"})]),_:1}),e(A,{style:{margin:"20px"}},{header:t(()=>[y("div",N,[I,e(v,{class:"button",text:"",onClick:K},{default:t(()=>[E(" 保存设置 ")]),_:1})])]),default:t(()=>[e(h,{ref_key:"formRef",ref:c,rules:g.value,model:a,"label-width":"150px"},{default:t(()=>[e(s,null,{default:t(()=>[e(r,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(i,{label:"开启此敏感词设置",prop:"baiduTextStatus"},{default:t(()=>[e(w,{content:"开启将打开敏感词检测、如果同时开启其他敏感词将会通过菜单顺序仅同时开启一个!",placement:"top","show-after":500},{default:t(()=>[e(V,{modelValue:a.baiduTextStatus,"onUpdate:modelValue":l[0]||(l[0]=u=>a.baiduTextStatus=u),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1}),e(s,null,{default:t(()=>[e(r,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(i,{label:"文本审核ApiKey",prop:"baiduTextApiKey"},{default:t(()=>[e(p,{modelValue:a.baiduTextApiKey,"onUpdate:modelValue":l[1]||(l[1]=u=>a.baiduTextApiKey=u),placeholder:"请填写百度文本审核ApiKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(s,null,{default:t(()=>[e(r,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(i,{label:"文本审核SecretKey",prop:"baiduTextSecretKey"},{default:t(()=>[e(p,{modelValue:a.baiduTextSecretKey,"onUpdate:modelValue":l[2]||(l[2]=u=>a.baiduTextSecretKey=u),placeholder:"请填写百度文本审核SecretKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof x=="function"&&x(M);export{M as default};
import{_ as C}from"./index-38e73db4.js";import{a as m}from"./config-61dee393.js";import{d as k,Q as q,r as f,x as U,h as o,o as j,c as B,e,f as t,a as y,l as E,E as b,q as x}from"./index-b779f4e0.js";const N={class:"flex justify-between"},I=y("b",null,"百度文本审核参数设置",-1),M=k({__name:"baiduSensitive",setup(O){const a=q({baiduTextStatus:"",baiduTextApiKey:"",baiduTextSecretKey:""}),g=f({baiduTextStatus:[{required:!0,trigger:"blur",message:"请选择是否启用百度文本审核"}],baiduTextSecretKey:[{required:!0,trigger:"blur",message:"请填写百度文本审核SecretKey"}],baiduTextApiKey:[{required:!0,trigger:"blur",message:"请填写百度文本审核APIKey"}]}),c=f();async function d(){const n=await m.queryConfig({keys:["baiduTextStatus","baiduTextSecretKey","baiduTextApiKey"]});Object.assign(a,n.data)}function K(){var n;(n=c.value)==null||n.validate(async l=>{if(l){try{await m.setConfig({settings:T(a)}),b.success("变更配置信息成功")}catch{}d()}else b.error("请填写完整信息")})}function T(n){return Object.keys(n).map(l=>({configKey:l,configVal:n[l]}))}return U(()=>{d()}),(n,l)=>{const _=o("el-alert"),S=C,v=o("el-button"),V=o("el-switch"),w=o("el-tooltip"),i=o("el-form-item"),r=o("el-col"),s=o("el-row"),p=o("el-input"),h=o("el-form"),A=o("el-card");return j(),B("div",null,[e(S,null,{default:t(()=>[e(_,{closable:!1,"show-icon":"",title:"百度文本审核参数说明",description:"接入原因、当前百度云免费5万条申请文档地址https://console.bce.baidu.com/ai/#/ai/antiporn/overview/index 、如果百度云敏感词与自定义敏感词都配置的情况、会先检测百度云后检测自定义的敏感词!",type:"success"})]),_:1}),e(A,{style:{margin:"20px"}},{header:t(()=>[y("div",N,[I,e(v,{class:"button",text:"",onClick:K},{default:t(()=>[E(" 保存设置 ")]),_:1})])]),default:t(()=>[e(h,{ref_key:"formRef",ref:c,rules:g.value,model:a,"label-width":"150px"},{default:t(()=>[e(s,null,{default:t(()=>[e(r,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(i,{label:"开启此敏感词设置",prop:"baiduTextStatus"},{default:t(()=>[e(w,{content:"开启将打开敏感词检测、如果同时开启其他敏感词将会通过菜单顺序仅同时开启一个!",placement:"top","show-after":500},{default:t(()=>[e(V,{modelValue:a.baiduTextStatus,"onUpdate:modelValue":l[0]||(l[0]=u=>a.baiduTextStatus=u),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1}),e(s,null,{default:t(()=>[e(r,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(i,{label:"文本审核ApiKey",prop:"baiduTextApiKey"},{default:t(()=>[e(p,{modelValue:a.baiduTextApiKey,"onUpdate:modelValue":l[1]||(l[1]=u=>a.baiduTextApiKey=u),placeholder:"请填写百度文本审核ApiKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(s,null,{default:t(()=>[e(r,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(i,{label:"文本审核SecretKey",prop:"baiduTextSecretKey"},{default:t(()=>[e(p,{modelValue:a.baiduTextSecretKey,"onUpdate:modelValue":l[2]||(l[2]=u=>a.baiduTextSecretKey=u),placeholder:"请填写百度文本审核SecretKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof x=="function"&&x(M);export{M as default};

View File

@ -1,9 +0,0 @@
/**
* Fantastic-admin 提供技术支持
* Powered by Fantastic-admin
* Gitee https://gitee.com/hooray/fantastic-admin
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as C}from"./index-7911c6db.js";import{a as f}from"./config-b4a9e7c0.js";import{d as k,Q as v,r as m,x as S,o as q,c as j,e,f as t,a as g,k as D,E as b,h as n,q as y}from"./index-4eef28ae.js";const P={class:"flex justify-between"},B=g("b",null,"百度翻译参数设置",-1),E=k({__name:"baidufanyi",setup(N){const l=v({baiduFanyiAppId:"",baiduFanyiSecret:""}),x=m({baiduFanyiSecret:[{required:!0,trigger:"blur",message:"请填写应用ID"}],baiduFanyiAppId:[{required:!0,trigger:"blur",message:"请填写基础ID"}]}),i=m();async function s(){const o=await f.queryConfig({keys:["baiduFanyiSecret","baiduFanyiAppId"]});Object.assign(l,o.data)}function F(){var o;(o=i.value)==null||o.validate(async a=>{if(a){try{await f.setConfig({settings:I(l)}),b.success("变更配置信息成功")}catch{}s()}else b.error("请填写完整信息")})}function I(o){return Object.keys(o).map(a=>({configKey:a,configVal:o[a]}))}return S(()=>{s()}),(o,a)=>{const u=n("el-alert"),A=C,V=n("el-button"),c=n("el-input"),d=n("el-form-item"),p=n("el-col"),_=n("el-row"),h=n("el-form"),w=n("el-card");return q(),j("div",null,[e(A,null,{default:t(()=>[e(u,{closable:!1,"show-icon":"",title:"百度翻译参数说明",description:"百度翻译为可选项、仅在mj描述词绘画中使用、当开启设置为百度翻译时会使用翻译、反之则使用AI翻译、如您需要、具体申请配置文档地址 https://api.fanyi.baidu.com/ 请开通通用文本翻译、别忘记填写你的服务器白名单才能使用!",type:"success"})]),_:1}),e(w,{style:{margin:"20px"}},{header:t(()=>[g("div",P,[B,e(V,{class:"button",text:"",onClick:F},{default:t(()=>[D(" 保存设置 ")]),_:1})])]),default:t(()=>[e(h,{ref_key:"formRef",ref:i,rules:x.value,model:l,"label-width":"130px"},{default:t(()=>[e(_,null,{default:t(()=>[e(p,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(d,{label:"百度翻译APPID",prop:"baiduFanyiAppId"},{default:t(()=>[e(c,{modelValue:l.baiduFanyiAppId,"onUpdate:modelValue":a[0]||(a[0]=r=>l.baiduFanyiAppId=r),placeholder:"请填写百度翻译APPID",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(_,null,{default:t(()=>[e(p,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(d,{label:"百度翻译秘钥",prop:"baiduFanyiSecret"},{default:t(()=>[e(c,{modelValue:l.baiduFanyiSecret,"onUpdate:modelValue":a[1]||(a[1]=r=>l.baiduFanyiSecret=r),placeholder:"请填写百度翻译秘钥",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof y=="function"&&y(E);export{E as default};

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as v}from"./index-7911c6db.js";import{a as f}from"./config-b4a9e7c0.js";import{d as M,Q as T,r as g,x as q,o as A,c as D,e,f as l,a as x,k as U,E as b,h as o,q as y}from"./index-4eef28ae.js";const h={class:"flex justify-between"},j=x("b",null,"分销系统基础设置",-1),E=M({__name:"base",setup(N){const a=T({salesBaseRatio:10,salesSeniorRatio:30,salesAllowDrawMoney:10,salesBaseTitle:"新秀分销商"}),w=g({salesBaseRatio:[{required:!0,trigger:"blur",message:"请填写默认佣金比例"}],salesSeniorRatio:[{required:!0,trigger:"blur",message:"请填写高级代理默认比例"}],salesBaseTitle:[{required:!0,trigger:"blur",message:"请填写默认用户推介等级名称"}]}),m=g();async function d(){const s=await f.queryConfig({keys:["salesBaseRatio","salesSeniorRatio","salesAllowDrawMoney","salesBaseTitle"]});Object.assign(a,s.data)}function V(){var s;(s=m.value)==null||s.validate(async t=>{if(t){try{await f.setConfig({settings:B(a)}),b.success("变更配置信息成功")}catch{}d()}else b.error("请填写完整信息")})}function B(s){return Object.keys(s).map(t=>({configKey:t,configVal:s[t]}))}return q(()=>{d()}),(s,t)=>{const c=o("el-alert"),R=v,C=o("el-button"),_=o("el-input-number"),r=o("el-form-item"),i=o("el-col"),u=o("el-row"),p=o("el-input"),S=o("el-form"),k=o("el-card");return A(),D("div",null,[e(R,null,{default:l(()=>[e(c,{closable:!1,"show-icon":"",title:"分销系统基础配置",description:"填写默认佣金比例和高级分销佣金比例会对应显示到客户端的分销页面、同时新用户将使用默认分销比例、允许提现额度限制用户最低提现金额、分销名称同样对应分销页面、高级代理可自定义名称!",type:"success"})]),_:1}),e(k,{style:{margin:"20px"}},{header:l(()=>[x("div",h,[j,e(C,{class:"button",text:"",onClick:V},{default:l(()=>[U(" 保存设置 ")]),_:1})])]),default:l(()=>[e(S,{ref_key:"formRef",ref:m,model:a,"label-width":"140px",rules:w.value},{default:l(()=>[e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"默认分销佣金比例",prop:"salesBaseRatio"},{default:l(()=>[e(_,{modelValue:a.salesBaseRatio,"onUpdate:modelValue":t[0]||(t[0]=n=>a.salesBaseRatio=n),max:100,min:0,step:5,"step-strictly":""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"高级分销佣金比例",prop:"salesSeniorRatio"},{default:l(()=>[e(_,{modelValue:a.salesSeniorRatio,"onUpdate:modelValue":t[1]||(t[1]=n=>a.salesSeniorRatio=n),max:100,min:0,step:5,"step-strictly":""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"允许最低提现金额",prop:"salesAllowDrawMoney"},{default:l(()=>[e(p,{modelValue:a.salesAllowDrawMoney,"onUpdate:modelValue":t[2]||(t[2]=n=>a.salesAllowDrawMoney=n),type:"number","step-strictly":""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"默认等级分销名称",prop:"salesBaseTitle"},{default:l(()=>[e(p,{modelValue:a.salesBaseTitle,"onUpdate:modelValue":t[3]||(t[3]=n=>a.salesBaseTitle=n),placeholder:"请填写SecretKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["model","rules"])]),_:1})])}}});typeof y=="function"&&y(E);export{E as default};
import{_ as M}from"./index-38e73db4.js";import{a as f}from"./config-61dee393.js";import{d as T,Q as k,r as g,x as q,h as o,o as A,c as D,e,f as l,a as x,l as U,E as b,q as y}from"./index-b779f4e0.js";const h={class:"flex justify-between"},j=x("b",null,"分销系统基础设置",-1),E=T({__name:"base",setup(N){const a=k({salesBaseRatio:10,salesSeniorRatio:30,salesAllowDrawMoney:10,salesBaseTitle:"新秀分销商"}),w=g({salesBaseRatio:[{required:!0,trigger:"blur",message:"请填写默认佣金比例"}],salesSeniorRatio:[{required:!0,trigger:"blur",message:"请填写高级代理默认比例"}],salesBaseTitle:[{required:!0,trigger:"blur",message:"请填写默认用户推介等级名称"}]}),m=g();async function d(){const s=await f.queryConfig({keys:["salesBaseRatio","salesSeniorRatio","salesAllowDrawMoney","salesBaseTitle"]});Object.assign(a,s.data)}function V(){var s;(s=m.value)==null||s.validate(async t=>{if(t){try{await f.setConfig({settings:B(a)}),b.success("变更配置信息成功")}catch{}d()}else b.error("请填写完整信息")})}function B(s){return Object.keys(s).map(t=>({configKey:t,configVal:s[t]}))}return q(()=>{d()}),(s,t)=>{const c=o("el-alert"),R=M,C=o("el-button"),_=o("el-input-number"),r=o("el-form-item"),i=o("el-col"),u=o("el-row"),p=o("el-input"),S=o("el-form"),v=o("el-card");return A(),D("div",null,[e(R,null,{default:l(()=>[e(c,{closable:!1,"show-icon":"",title:"分销系统基础配置",description:"填写默认佣金比例和高级分销佣金比例会对应显示到客户端的分销页面、同时新用户将使用默认分销比例、允许提现额度限制用户最低提现金额、分销名称同样对应分销页面、高级代理可自定义名称!",type:"success"})]),_:1}),e(v,{style:{margin:"20px"}},{header:l(()=>[x("div",h,[j,e(C,{class:"button",text:"",onClick:V},{default:l(()=>[U(" 保存设置 ")]),_:1})])]),default:l(()=>[e(S,{ref_key:"formRef",ref:m,model:a,"label-width":"140px",rules:w.value},{default:l(()=>[e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"默认分销佣金比例",prop:"salesBaseRatio"},{default:l(()=>[e(_,{modelValue:a.salesBaseRatio,"onUpdate:modelValue":t[0]||(t[0]=n=>a.salesBaseRatio=n),max:100,min:0,step:5,"step-strictly":""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"高级分销佣金比例",prop:"salesSeniorRatio"},{default:l(()=>[e(_,{modelValue:a.salesSeniorRatio,"onUpdate:modelValue":t[1]||(t[1]=n=>a.salesSeniorRatio=n),max:100,min:0,step:5,"step-strictly":""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"允许最低提现金额",prop:"salesAllowDrawMoney"},{default:l(()=>[e(p,{modelValue:a.salesAllowDrawMoney,"onUpdate:modelValue":t[2]||(t[2]=n=>a.salesAllowDrawMoney=n),type:"number","step-strictly":""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:l(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:l(()=>[e(r,{label:"默认等级分销名称",prop:"salesBaseTitle"},{default:l(()=>[e(p,{modelValue:a.salesBaseTitle,"onUpdate:modelValue":t[3]||(t[3]=n=>a.salesBaseTitle=n),placeholder:"请填写SecretKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["model","rules"])]),_:1})])}}});typeof y=="function"&&y(E);export{E as default};

View File

@ -0,0 +1,9 @@
/**
* Fantastic-admin 提供技术支持
* Powered by Fantastic-admin
* Gitee https://gitee.com/hooray/fantastic-admin
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as I}from"./index-38e73db4.js";import{a as m}from"./config-61dee393.js";import{d as S,Q as T,r as p,x as U,h as n,o as j,c as q,e,f as o,a as x,l as B,E as b,q as g}from"./index-b779f4e0.js";const E={class:"flex justify-between"},N=x("b",null,"系统基础设置",-1),M=S({__name:"base",setup(O){const t=T({baiduCode:"",baiduSiteId:"",baiduToken:""}),k=p({}),c=p();async function _(){const a=await m.queryConfig({keys:["baiduCode","baiduSiteId","baiduToken"]});Object.assign(t,a.data)}function y(){var a;(a=c.value)==null||a.validate(async l=>{if(l){try{await m.setConfig({settings:C(t)}),b.success("变更配置信息成功")}catch{}_()}else b.error("请填写完整信息")})}function C(a){return Object.keys(a).map(l=>({configKey:l,configVal:a[l]}))}return U(()=>{_()}),(a,l)=>{const f=n("el-alert"),V=I,w=n("el-button"),s=n("el-input"),u=n("el-form-item"),i=n("el-col"),r=n("el-row"),h=n("el-form"),v=n("el-card");return j(),q("div",null,[e(V,null,{default:o(()=>[e(f,{closable:!1,"show-icon":"",title:"网页统计说明",description:"百度统计的配置默认使用演示demo数据主要用于展示目的。实际的统计数据将在网站首页显示。为获取更精确的数据分析建议查阅部署文档或访问百度统计官网申请专属于您网站的key和token。百度统计提供的是一项免费服务。如果您选择不使用这项服务只需将相关设置项留空即可。",type:"success"})]),_:1}),e(v,{style:{margin:"20px"}},{header:o(()=>[x("div",E,[N,e(w,{class:"button",text:"",onClick:y},{default:o(()=>[B(" 保存设置 ")]),_:1})])]),default:o(()=>[e(h,{ref_key:"formRef",ref:c,rules:k.value,model:t,"label-width":"120px"},{default:o(()=>[e(r,null,{default:o(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(u,{label:"百度统计siteId",prop:"baiduSiteId"},{default:o(()=>[e(s,{modelValue:t.baiduSiteId,"onUpdate:modelValue":l[0]||(l[0]=d=>t.baiduSiteId=d),placeholder:"请填写百度site_id、不会请查看部署文档",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:o(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(u,{label:"百度统计token",prop:"baiduToken"},{default:o(()=>[e(s,{modelValue:t.baiduToken,"onUpdate:modelValue":l[1]||(l[1]=d=>t.baiduToken=d),placeholder:"请填写百度access_token、不会请查看部署文档",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:o(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(u,{label:"百度统计代码",prop:"baiduCode"},{default:o(()=>[e(s,{modelValue:t.baiduCode,"onUpdate:modelValue":l[2]||(l[2]=d=>t.baiduCode=d),placeholder:"填写百度统计代码可统计每日访问量详情,如果没有使用用请查看详细文档!",type:"textarea",rows:12,clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof g=="function"&&g(M);export{M as default};

View File

@ -1,9 +0,0 @@
/**
* Fantastic-admin 提供技术支持
* Powered by Fantastic-admin
* Gitee https://gitee.com/hooray/fantastic-admin
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as I}from"./index-7911c6db.js";import{a as m}from"./config-b4a9e7c0.js";import{d as S,Q as T,r as p,x as U,o as j,c as q,e,f as o,a as k,k as B,E as b,h as n,q as g}from"./index-4eef28ae.js";const E={class:"flex justify-between"},N=k("b",null,"系统基础设置",-1),M=S({__name:"base",setup(O){const t=T({baiduCode:"",baiduSiteId:"",baiduToken:""}),x=p({}),c=p();async function _(){const a=await m.queryConfig({keys:["baiduCode","baiduSiteId","baiduToken"]});Object.assign(t,a.data)}function y(){var a;(a=c.value)==null||a.validate(async l=>{if(l){try{await m.setConfig({settings:C(t)}),b.success("变更配置信息成功")}catch{}_()}else b.error("请填写完整信息")})}function C(a){return Object.keys(a).map(l=>({configKey:l,configVal:a[l]}))}return U(()=>{_()}),(a,l)=>{const f=n("el-alert"),V=I,w=n("el-button"),s=n("el-input"),u=n("el-form-item"),i=n("el-col"),r=n("el-row"),h=n("el-form"),v=n("el-card");return j(),q("div",null,[e(V,null,{default:o(()=>[e(f,{closable:!1,"show-icon":"",title:"基础设置说明",description:"百度统计默认使用的是demo数据、用于demo展示、最终数据在首页程呈现、请查看部署文档或前往百度统计申请自己的专属key与token、这是免费的服务、如果您不想使用将下面设置留空就行。",type:"success"})]),_:1}),e(v,{style:{margin:"20px"}},{header:o(()=>[k("div",E,[N,e(w,{class:"button",text:"",onClick:y},{default:o(()=>[B(" 保存设置 ")]),_:1})])]),default:o(()=>[e(h,{ref_key:"formRef",ref:c,rules:x.value,model:t,"label-width":"120px"},{default:o(()=>[e(r,null,{default:o(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(u,{label:"百度统计siteId",prop:"baiduSiteId"},{default:o(()=>[e(s,{modelValue:t.baiduSiteId,"onUpdate:modelValue":l[0]||(l[0]=d=>t.baiduSiteId=d),placeholder:"请填写百度site_id、不会请查看部署文档",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:o(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(u,{label:"百度统计token",prop:"baiduToken"},{default:o(()=>[e(s,{modelValue:t.baiduToken,"onUpdate:modelValue":l[1]||(l[1]=d=>t.baiduToken=d),placeholder:"请填写百度access_token、不会请查看部署文档",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:o(()=>[e(i,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(u,{label:"百度统计代码",prop:"baiduCode"},{default:o(()=>[e(s,{modelValue:t.baiduCode,"onUpdate:modelValue":l[2]||(l[2]=d=>t.baiduCode=d),placeholder:"填写百度统计代码可统计每日访问量详情,如果没有使用用请查看详细文档!",type:"textarea",rows:12,clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof g=="function"&&g(M);export{M as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as K}from"./index-7911c6db.js";import{a as m}from"./config-b4a9e7c0.js";import{d as C,Q as k,r as f,x as q,o as N,c as U,e,f as t,a as S,k as j,E as v,h as i,q as B}from"./index-4eef28ae.js";const E={class:"flex justify-between"},M=S("b",null,"百度文本审核参数设置",-1),O=C({__name:"builtIn",setup(R){const l=k({nineaiBuiltInSensitiveStatus:"",nineaiBuiltInSensitiveApiBase:"",nineaiBuiltInSensitiveAuthKey:""}),g=f({nineaiBuiltInSensitiveStatus:[{required:!0,trigger:"blur",message:"请选择是否启用官方敏感词审核"}],nineaiBuiltInSensitiveApiBase:[{required:!0,trigger:"blur",message:"请填写官方敏感词审核Api地址"}],nineaiBuiltInSensitiveAuthKey:[{required:!0,trigger:"blur",message:"请填写官方敏感词审核授权Key"}]}),c=f();async function _(){const a=await m.queryConfig({keys:["nineaiBuiltInSensitiveStatus","nineaiBuiltInSensitiveAuthKey","nineaiBuiltInSensitiveApiBase"]});Object.assign(l,a.data)}function y(){var a;(a=c.value)==null||a.validate(async n=>{if(n){try{await m.setConfig({settings:I(l)}),v.success("变更配置信息成功")}catch{}_()}else v.error("请填写完整信息")})}function I(a){return Object.keys(a).map(n=>({configKey:n,configVal:a[n]}))}return q(()=>{_()}),(a,n)=>{const p=i("el-alert"),b=K,A=i("el-button"),h=i("el-switch"),x=i("el-tooltip"),s=i("el-form-item"),u=i("el-col"),r=i("el-row"),d=i("el-input"),V=i("el-form"),w=i("el-card");return N(),U("div",null,[e(b,null,{default:t(()=>[e(p,{closable:!1,"show-icon":"",title:"NineAi敏感词说明",description:"官方提供的敏感词检测Api、价格相对实惠、如需使用请联系管理员购买、后续开通专有的通道",type:"success"})]),_:1}),e(w,{style:{margin:"20px"}},{header:t(()=>[S("div",E,[M,e(A,{class:"button",text:"",onClick:y},{default:t(()=>[j(" 保存设置 ")]),_:1})])]),default:t(()=>[e(V,{ref_key:"formRef",ref:c,rules:g.value,model:l,"label-width":"150px"},{default:t(()=>[e(r,null,{default:t(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"开启此敏感词设置",prop:"nineaiBuiltInSensitiveStatus"},{default:t(()=>[e(x,{content:"开启将打开敏感词检测、如果同时开启其他敏感词将会通过菜单顺序仅同时开启一个!",placement:"top","show-after":500},{default:t(()=>[e(h,{modelValue:l.nineaiBuiltInSensitiveStatus,"onUpdate:modelValue":n[0]||(n[0]=o=>l.nineaiBuiltInSensitiveStatus=o),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1}),e(r,null,{default:t(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"文本审核ApiKey",prop:"nineaiBuiltInSensitiveApiBase"},{default:t(()=>[e(d,{modelValue:l.nineaiBuiltInSensitiveApiBase,"onUpdate:modelValue":n[1]||(n[1]=o=>l.nineaiBuiltInSensitiveApiBase=o),placeholder:"请填写官方敏感词审核Api地址",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:t(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"文本审核SecretKey",prop:"nineaiBuiltInSensitiveAuthKey"},{default:t(()=>[e(d,{modelValue:l.nineaiBuiltInSensitiveAuthKey,"onUpdate:modelValue":n[2]||(n[2]=o=>l.nineaiBuiltInSensitiveAuthKey=o),placeholder:"请填写官方敏感词审核授权Key",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof B=="function"&&B(O);export{O as default};
import{_ as K}from"./index-38e73db4.js";import{a as m}from"./config-61dee393.js";import{d as C,Q as k,r as f,x as q,h as i,o as N,c as U,e,f as t,a as S,l as j,E as v,q as B}from"./index-b779f4e0.js";const E={class:"flex justify-between"},M=S("b",null,"百度文本审核参数设置",-1),O=C({__name:"builtIn",setup(R){const l=k({nineaiBuiltInSensitiveStatus:"",nineaiBuiltInSensitiveApiBase:"",nineaiBuiltInSensitiveAuthKey:""}),g=f({nineaiBuiltInSensitiveStatus:[{required:!0,trigger:"blur",message:"请选择是否启用官方敏感词审核"}],nineaiBuiltInSensitiveApiBase:[{required:!0,trigger:"blur",message:"请填写官方敏感词审核Api地址"}],nineaiBuiltInSensitiveAuthKey:[{required:!0,trigger:"blur",message:"请填写官方敏感词审核授权Key"}]}),c=f();async function _(){const a=await m.queryConfig({keys:["nineaiBuiltInSensitiveStatus","nineaiBuiltInSensitiveAuthKey","nineaiBuiltInSensitiveApiBase"]});Object.assign(l,a.data)}function y(){var a;(a=c.value)==null||a.validate(async n=>{if(n){try{await m.setConfig({settings:I(l)}),v.success("变更配置信息成功")}catch{}_()}else v.error("请填写完整信息")})}function I(a){return Object.keys(a).map(n=>({configKey:n,configVal:a[n]}))}return q(()=>{_()}),(a,n)=>{const p=i("el-alert"),b=K,A=i("el-button"),h=i("el-switch"),x=i("el-tooltip"),s=i("el-form-item"),u=i("el-col"),r=i("el-row"),d=i("el-input"),V=i("el-form"),w=i("el-card");return N(),U("div",null,[e(b,null,{default:t(()=>[e(p,{closable:!1,"show-icon":"",title:"NineAi敏感词说明",description:"官方提供的敏感词检测Api、价格相对实惠、如需使用请联系管理员购买、后续开通专有的通道",type:"success"})]),_:1}),e(w,{style:{margin:"20px"}},{header:t(()=>[S("div",E,[M,e(A,{class:"button",text:"",onClick:y},{default:t(()=>[j(" 保存设置 ")]),_:1})])]),default:t(()=>[e(V,{ref_key:"formRef",ref:c,rules:g.value,model:l,"label-width":"150px"},{default:t(()=>[e(r,null,{default:t(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"开启此敏感词设置",prop:"nineaiBuiltInSensitiveStatus"},{default:t(()=>[e(x,{content:"开启将打开敏感词检测、如果同时开启其他敏感词将会通过菜单顺序仅同时开启一个!",placement:"top","show-after":500},{default:t(()=>[e(h,{modelValue:l.nineaiBuiltInSensitiveStatus,"onUpdate:modelValue":n[0]||(n[0]=o=>l.nineaiBuiltInSensitiveStatus=o),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1}),e(r,null,{default:t(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"文本审核ApiKey",prop:"nineaiBuiltInSensitiveApiBase"},{default:t(()=>[e(d,{modelValue:l.nineaiBuiltInSensitiveApiBase,"onUpdate:modelValue":n[1]||(n[1]=o=>l.nineaiBuiltInSensitiveApiBase=o),placeholder:"请填写官方敏感词审核Api地址",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(r,null,{default:t(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"文本审核SecretKey",prop:"nineaiBuiltInSensitiveAuthKey"},{default:t(()=>[e(d,{modelValue:l.nineaiBuiltInSensitiveAuthKey,"onUpdate:modelValue":n[2]||(n[2]=o=>l.nineaiBuiltInSensitiveAuthKey=o),placeholder:"请填写官方敏感词审核授权Key",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof B=="function"&&B(O);export{O as default};

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as j}from"./index-7911c6db.js";import{d as K,r as u,Q as N,x as F,o as m,c as C,e as t,f as o,R as H,S as P,b as i,j as O,k as d,w as Q,I as T,t as _,a as x,P as X,h as l,X as $,l as G,q as A}from"./index-4eef28ae.js";import{m as g}from"./marked.esm-76161808.js";import{A as J}from"./chat-8cf72149.js";import{u as W}from"./utcformatTime-e76e5157.js";const Z={class:"answer"},E=["innerHTML"],ee=K({__name:"chat",setup(te){const V=new g.Renderer;g.setOptions({renderer:V,gfm:!0,pedantic:!1,sanitize:!1});const c=u(!1),h=u([]),v=u(),b=u(0),a=N({userId:"",prompt:"",page:1,size:10}),y=u([]);async function p(){c.value=!0;try{const r=await J.queryChatAll(a);c.value=!1;const{rows:n,count:f}=r.data;b.value=f,y.value=n}catch{c.value=!1}}async function I(r){const n=await X.queryAllUser({size:30,username:r});h.value=n.data.rows}function U(r){r==null||r.resetFields(),p()}return F(()=>{p()}),(r,n)=>{const f=l("el-option"),D=l("el-select"),w=l("el-form-item"),M=l("el-input"),k=l("el-button"),S=l("el-form"),z=j,s=l("el-table-column"),L=l("el-popover"),R=l("el-table"),q=l("el-pagination"),B=l("el-row"),Y=$("loading");return m(),C("div",null,[t(z,null,{default:o(()=>[t(S,{ref_key:"formRef",ref:v,inline:!0,model:a},{default:o(()=>[t(w,{label:"用户名称",prop:"userId"},{default:o(()=>[t(D,{modelValue:a.userId,"onUpdate:modelValue":n[0]||(n[0]=e=>a.userId=e),filterable:"",clearable:"",remote:"","reserve-keyword":"",placeholder:"用户姓名[模糊搜索]","remote-show-suffix":"","remote-method":I},{default:o(()=>[(m(!0),C(H,null,P(i(h),e=>(m(),T(f,{key:e.id,label:e.username,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),t(w,{label:"用户询问的问题",prop:"prompt"},{default:o(()=>[t(M,{modelValue:a.prompt,"onUpdate:modelValue":n[1]||(n[1]=e=>a.prompt=e),placeholder:"提问问题[模糊搜索]",onKeydown:O(G(p,["prevent"]),["enter"])},null,8,["modelValue","onKeydown"])]),_:1}),t(w,null,{default:o(()=>[t(k,{type:"primary",onClick:p},{default:o(()=>[d(" 查询 ")]),_:1}),t(k,{onClick:n[2]||(n[2]=e=>U(i(v)))},{default:o(()=>[d(" 重置 ")]),_:1})]),_:1})]),_:1},8,["model"])]),_:1}),t(z,{style:{width:"100%"}},{default:o(()=>[Q((m(),T(R,{border:"",data:i(y),style:{width:"100%"},size:"large","tooltip-options":{}},{default:o(()=>[t(s,{fixed:"",prop:"username",label:"用户名称",width:"150"}),t(s,{prop:"createdAt",label:"角色",width:"80"},{default:o(e=>[d(_(e.row.role==="user"?"用户":"电脑"),1)]),_:1}),t(s,{prop:"email",label:"用户邮箱",width:"200"}),t(s,{prop:"answer",label:"用户询问/AI回复"},{default:o(e=>[t(L,{placement:"top",width:400,trigger:"click"},{reference:o(()=>[x("div",Z,_(e.row.role==="user"?e.row.prompt:e.row.answer),1)]),default:o(()=>[x("div",{class:"answer_container",innerHTML:i(g)(e.row.role==="user"?e.row.prompt:e.row.answer||"")},null,8,E)]),_:2},1024)]),_:1}),t(s,{prop:"completionTokens",label:"提问/回答Token",width:"140",align:"center"},{default:o(e=>[d(_(e.row.role==="user"?e.row.promptTokens:e.row.completionTokens),1)]),_:1}),t(s,{prop:"totalTokens",label:"总计Toekn",width:"110",align:"center"}),t(s,{prop:"model",label:"模型",width:"200"}),t(s,{prop:"createdAt",label:"提问时间",width:"200"},{default:o(e=>[d(_(i(W)(e.row.createdAt,"YYYY-MM-DD hh:mm:ss")),1)]),_:1})]),_:1},8,["data"])),[[Y,i(c)]]),t(B,{class:"flex justify-end mt-5"},{default:o(()=>[t(q,{"current-page":a.page,"onUpdate:currentPage":n[3]||(n[3]=e=>a.page=e),"page-size":a.size,"onUpdate:pageSize":n[4]||(n[4]=e=>a.size=e),class:"mr-5","page-sizes":[10,20,30,50],layout:"total, sizes, prev, pager, next, jumper",total:i(b),onSizeChange:p,onCurrentChange:p},null,8,["current-page","page-size","total"])]),_:1})]),_:1})])}}});typeof A=="function"&&A(ee);export{ee as default};
import{_ as K}from"./index-38e73db4.js";import{d as N,r as u,Q as j,x as F,h as l,R as H,o as m,c as C,e as t,f as o,S as P,U as O,b as i,k as Q,m as $,l as d,w as G,I as T,t as _,a as x,P as J,q as A}from"./index-b779f4e0.js";import{m as g}from"./marked.esm-76161808.js";import{A as W}from"./chat-d220f18e.js";import{u as X}from"./utcformatTime-e76e5157.js";const Z={class:"answer"},E=["innerHTML"],ee=N({__name:"chat",setup(te){const V=new g.Renderer;g.setOptions({renderer:V,gfm:!0,pedantic:!1,sanitize:!1});const c=u(!1),h=u([]),v=u(),b=u(0),a=j({userId:"",prompt:"",page:1,size:10}),y=u([]);async function p(){c.value=!0;try{const r=await W.queryChatAll(a);c.value=!1;const{rows:n,count:f}=r.data;b.value=f,y.value=n}catch{c.value=!1}}async function U(r){const n=await J.queryAllUser({size:30,username:r});h.value=n.data.rows}function I(r){r==null||r.resetFields(),p()}return F(()=>{p()}),(r,n)=>{const f=l("el-option"),D=l("el-select"),w=l("el-form-item"),M=l("el-input"),k=l("el-button"),S=l("el-form"),z=K,s=l("el-table-column"),L=l("el-popover"),R=l("el-table"),q=l("el-pagination"),B=l("el-row"),Y=H("loading");return m(),C("div",null,[t(z,null,{default:o(()=>[t(S,{ref_key:"formRef",ref:v,inline:!0,model:a},{default:o(()=>[t(w,{label:"用户名称",prop:"userId"},{default:o(()=>[t(D,{modelValue:a.userId,"onUpdate:modelValue":n[0]||(n[0]=e=>a.userId=e),filterable:"",clearable:"",remote:"","reserve-keyword":"",placeholder:"用户姓名[模糊搜索]","remote-show-suffix":"","remote-method":U},{default:o(()=>[(m(!0),C(P,null,O(i(h),e=>(m(),T(f,{key:e.id,label:e.username,value:e.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),t(w,{label:"用户询问的问题",prop:"prompt"},{default:o(()=>[t(M,{modelValue:a.prompt,"onUpdate:modelValue":n[1]||(n[1]=e=>a.prompt=e),placeholder:"提问问题[模糊搜索]",onKeydown:Q($(p,["prevent"]),["enter"])},null,8,["modelValue","onKeydown"])]),_:1}),t(w,null,{default:o(()=>[t(k,{type:"primary",onClick:p},{default:o(()=>[d(" 查询 ")]),_:1}),t(k,{onClick:n[2]||(n[2]=e=>I(i(v)))},{default:o(()=>[d(" 重置 ")]),_:1})]),_:1})]),_:1},8,["model"])]),_:1}),t(z,{style:{width:"100%"}},{default:o(()=>[G((m(),T(R,{border:"",data:i(y),style:{width:"100%"},size:"large","tooltip-options":{}},{default:o(()=>[t(s,{fixed:"",prop:"username",label:"用户名称",width:"150"}),t(s,{prop:"createdAt",label:"角色",width:"80"},{default:o(e=>[d(_(e.row.role==="user"?"用户":"电脑"),1)]),_:1}),t(s,{prop:"email",label:"用户邮箱",width:"200"}),t(s,{prop:"answer",label:"用户询问/AI回复"},{default:o(e=>[t(L,{placement:"top",width:400,trigger:"click"},{reference:o(()=>[x("div",Z,_(e.row.role==="user"?e.row.prompt:e.row.answer),1)]),default:o(()=>[x("div",{class:"answer_container",innerHTML:i(g)(e.row.role==="user"?e.row.prompt:e.row.answer||"")},null,8,E)]),_:2},1024)]),_:1}),t(s,{prop:"completionTokens",label:"提问/回答Token",width:"140",align:"center"},{default:o(e=>[d(_(e.row.role==="user"?e.row.promptTokens:e.row.completionTokens),1)]),_:1}),t(s,{prop:"totalTokens",label:"总计Toekn",width:"110",align:"center"}),t(s,{prop:"model",label:"模型",width:"200"}),t(s,{prop:"createdAt",label:"提问时间",width:"200"},{default:o(e=>[d(_(i(X)(e.row.createdAt,"YYYY-MM-DD hh:mm:ss")),1)]),_:1})]),_:1},8,["data"])),[[Y,i(c)]]),t(B,{class:"flex justify-end mt-5"},{default:o(()=>[t(q,{"current-page":a.page,"onUpdate:currentPage":n[3]||(n[3]=e=>a.page=e),"page-size":a.size,"onUpdate:pageSize":n[4]||(n[4]=e=>a.size=e),class:"mr-5","page-sizes":[10,20,30,50],layout:"total, sizes, prev, pager, next, jumper",total:i(b),onSizeChange:p,onCurrentChange:p},null,8,["current-page","page-size","total"])]),_:1})]),_:1})])}}});typeof A=="function"&&A(ee);export{ee as default};

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{Y as t}from"./index-4eef28ae.js";const a={queryChatAll:r=>t.get("chatLog/chatAll",{params:r}),queryDrawAll:r=>t.get("chatLog/drawAll",{params:r}),recDrawImg:r=>t.post("chatLog/recDrawImg",r),queryMjDrawAll:r=>t.get("midjourney/getList",{params:r}),recMjDrawImg:r=>t.post("midjourney/rec",r),delChatLog:r=>t.post("midjourney/del",r)};export{a as A};
import{Y as t}from"./index-b779f4e0.js";const a={queryChatAll:r=>t.get("chatLog/chatAll",{params:r}),queryDrawAll:r=>t.get("chatLog/drawAll",{params:r}),recDrawImg:r=>t.post("chatLog/recDrawImg",r),queryMjDrawAll:r=>t.get("midjourney/getList",{params:r}),recMjDrawImg:r=>t.post("midjourney/rec",r),delChatLog:r=>t.post("midjourney/del",r)};export{a as A};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{Y as e}from"./index-4eef28ae.js";const p={queryKeyList:t=>e.get("chatgpt/keyList",{params:t}),queryKeyModelList:t=>e.get("chatgpt/keyModelList",{params:t}),queryKeyDetail:t=>e.get("chatgpt/keyDetail",{params:t}),addGptKey:t=>e.post("chatgpt/addKey",t),updateGptKey:t=>e.post("chatgpt/updateKey",t),addWhiteUser:t=>e.post("chatgpt/addWhiteUser",t),updateWhiteUser:t=>e.post("chatgpt/updateWhiteUser",t),queryWhiteUserList:t=>e.get("chatgpt/userWhiteList",{params:t}),deleteGptKey:t=>e.post("chatgpt/deleteKey",t),queryChatBoxTypes:()=>e.get("chatgpt/queryChatBoxTypes"),setChatBoxType:t=>e.post("chatgpt/setChatBoxType",t),delChatBoxType:t=>e.post("chatgpt/delChatBoxType",t),queryChatBoxs:()=>e.get("chatgpt/queryChatBoxs"),setChatBox:t=>e.post("chatgpt/setChatBox",t),delChatBox:t=>e.post("chatgpt/delChatBox",t),queryChatPreTypes:()=>e.get("chatgpt/queryChatPreTypes"),setChatPreType:t=>e.post("chatgpt/setChatPreType",t),delChatPreType:t=>e.post("chatgpt/delChatPreType",t),queryChatPres:()=>e.get("chatgpt/queryChatPres"),setChatPre:t=>e.post("chatgpt/setChatPre",t),delChatPre:t=>e.post("chatgpt/delChatPre",t)};export{p as A};
import{Y as e}from"./index-b779f4e0.js";const p={queryKeyList:t=>e.get("chatgpt/keyList",{params:t}),queryKeyModelList:t=>e.get("chatgpt/keyModelList",{params:t}),queryKeyDetail:t=>e.get("chatgpt/keyDetail",{params:t}),addGptKey:t=>e.post("chatgpt/addKey",t),updateGptKey:t=>e.post("chatgpt/updateKey",t),addWhiteUser:t=>e.post("chatgpt/addWhiteUser",t),updateWhiteUser:t=>e.post("chatgpt/updateWhiteUser",t),queryWhiteUserList:t=>e.get("chatgpt/userWhiteList",{params:t}),deleteGptKey:t=>e.post("chatgpt/deleteKey",t),queryChatBoxTypes:()=>e.get("chatgpt/queryChatBoxTypes"),setChatBoxType:t=>e.post("chatgpt/setChatBoxType",t),delChatBoxType:t=>e.post("chatgpt/delChatBoxType",t),queryChatBoxs:()=>e.get("chatgpt/queryChatBoxs"),setChatBox:t=>e.post("chatgpt/setChatBox",t),delChatBox:t=>e.post("chatgpt/delChatBox",t),queryChatPreTypes:()=>e.get("chatgpt/queryChatPreTypes"),setChatPreType:t=>e.post("chatgpt/setChatPreType",t),delChatPreType:t=>e.post("chatgpt/delChatPreType",t),queryChatPres:()=>e.get("chatgpt/queryChatPres"),setChatPre:t=>e.post("chatgpt/setChatPre",t),delChatPre:t=>e.post("chatgpt/delChatPre",t)};export{p as A};

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as k}from"./index-7911c6db.js";import{a as f}from"./config-b4a9e7c0.js";import{d as S,Q as P,r as q,B,x as N,o as j,c as A,e,f as t,a as y,k as E,b as h,E as v,h as a,q as g}from"./index-4eef28ae.js";const R={class:"flex justify-between"},M=y("b",null,"chevereto图床参数设置",-1),O=S({__name:"chevereto",setup(I){const l=P({cheveretoStatus:"",cheveretoUploadPath:"",cheveretoKey:""}),d=q();async function i(){const n=await f.queryConfig({keys:["cheveretoKey","cheveretoUploadPath","cheveretoStatus"]});Object.assign(l,n.data)}function b(){var n;(n=d.value)==null||n.validate(async o=>{if(o){try{await f.setConfig({settings:x(l)}),v.success("变更配置信息成功")}catch{}i()}else v.error("请填写完整信息")})}function x(n){return Object.keys(n).map(o=>({configKey:o,configVal:n[o]}))}const p=B(()=>[{required:Number(l.cheveretoStatus)===1,message:"开启配置后请填写此项",trigger:"change"}]);return N(()=>{i()}),(n,o)=>{const _=a("el-alert"),V=k,w=a("el-button"),U=a("el-switch"),s=a("el-form-item"),c=a("el-col"),u=a("el-row"),m=a("el-input"),C=a("el-form"),K=a("el-card");return j(),A("div",null,[e(V,null,{default:t(()=>[e(_,{closable:!1,"show-icon":"",title:"chevereto图床配置说明",description:"chevereto图床官方文档 https://v4-docs.chevereto.com/developer/api/api-v1.html 同时开启多个存储会以菜单排序优先级开启使用",type:"success"})]),_:1}),e(K,{style:{margin:"20px"}},{header:t(()=>[y("div",R,[M,e(w,{class:"button",text:"",onClick:b},{default:t(()=>[E(" 保存设置 ")]),_:1})])]),default:t(()=>[e(C,{ref_key:"formRef",ref:d,model:l,"label-width":"100px"},{default:t(()=>[e(u,null,{default:t(()=>[e(c,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"服务启用状态",prop:"cheveretoStatus"},{default:t(()=>[e(U,{modelValue:l.cheveretoStatus,"onUpdate:modelValue":o[0]||(o[0]=r=>l.cheveretoStatus=r),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:t(()=>[e(c,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"上传地址",prop:"cheveretoUploadPath",rules:h(p)},{default:t(()=>[e(m,{modelValue:l.cheveretoUploadPath,"onUpdate:modelValue":o[1]||(o[1]=r=>l.cheveretoUploadPath=r),placeholder:"请填写您的图床上传地址",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(u,null,{default:t(()=>[e(c,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"ApiKey",prop:"cheveretoKey",rules:h(p)},{default:t(()=>[e(m,{modelValue:l.cheveretoKey,"onUpdate:modelValue":o[2]||(o[2]=r=>l.cheveretoKey=r),placeholder:"请填写ApiKey",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})])}}});typeof g=="function"&&g(O);export{O as default};
import{_ as S}from"./index-38e73db4.js";import{a as f}from"./config-61dee393.js";import{d as k,Q as P,r as q,B,x as N,h as a,o as j,c as A,e,f as t,a as y,l as E,b as h,E as v,q as g}from"./index-b779f4e0.js";const R={class:"flex justify-between"},M=y("b",null,"chevereto图床参数设置",-1),O=k({__name:"chevereto",setup(I){const l=P({cheveretoStatus:"",cheveretoUploadPath:"",cheveretoKey:""}),d=q();async function i(){const n=await f.queryConfig({keys:["cheveretoKey","cheveretoUploadPath","cheveretoStatus"]});Object.assign(l,n.data)}function b(){var n;(n=d.value)==null||n.validate(async o=>{if(o){try{await f.setConfig({settings:x(l)}),v.success("变更配置信息成功")}catch{}i()}else v.error("请填写完整信息")})}function x(n){return Object.keys(n).map(o=>({configKey:o,configVal:n[o]}))}const p=B(()=>[{required:Number(l.cheveretoStatus)===1,message:"开启配置后请填写此项",trigger:"change"}]);return N(()=>{i()}),(n,o)=>{const _=a("el-alert"),V=S,w=a("el-button"),U=a("el-switch"),s=a("el-form-item"),c=a("el-col"),u=a("el-row"),m=a("el-input"),C=a("el-form"),K=a("el-card");return j(),A("div",null,[e(V,null,{default:t(()=>[e(_,{closable:!1,"show-icon":"",title:"chevereto图床配置说明",description:"chevereto图床官方文档 https://v4-docs.chevereto.com/developer/api/api-v1.html 同时开启多个存储会以菜单排序优先级开启使用",type:"success"})]),_:1}),e(K,{style:{margin:"20px"}},{header:t(()=>[y("div",R,[M,e(w,{class:"button",text:"",onClick:b},{default:t(()=>[E(" 保存设置 ")]),_:1})])]),default:t(()=>[e(C,{ref_key:"formRef",ref:d,model:l,"label-width":"100px"},{default:t(()=>[e(u,null,{default:t(()=>[e(c,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"服务启用状态",prop:"cheveretoStatus"},{default:t(()=>[e(U,{modelValue:l.cheveretoStatus,"onUpdate:modelValue":o[0]||(o[0]=r=>l.cheveretoStatus=r),"active-value":"1","inactive-value":"0"},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(u,null,{default:t(()=>[e(c,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"上传地址",prop:"cheveretoUploadPath",rules:h(p)},{default:t(()=>[e(m,{modelValue:l.cheveretoUploadPath,"onUpdate:modelValue":o[1]||(o[1]=r=>l.cheveretoUploadPath=r),placeholder:"请填写您的图床上传地址",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1}),e(u,null,{default:t(()=>[e(c,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(s,{label:"ApiKey",prop:"cheveretoKey",rules:h(p)},{default:t(()=>[e(m,{modelValue:l.cheveretoKey,"onUpdate:modelValue":o[2]||(o[2]=r=>l.cheveretoKey=r),placeholder:"请填写ApiKey",clearable:""},null,8,["modelValue"])]),_:1},8,["rules"])]),_:1})]),_:1})]),_:1},8,["model"])]),_:1})])}}});typeof g=="function"&&g(O);export{O as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{Y as o}from"./index-4eef28ae.js";const g={queryAllConfig:()=>o.get("config/queryAll"),queryGptKeys:()=>o.get("config/queryGptKeys"),setGptKeys:t=>o.post("config/setGptKeys",t),queryConfig:t=>o.post("config/query",t),copyright:()=>o.get("config/copyright"),setConfig:t=>o.post("config/set",t)};export{g as a};
import{Y as o}from"./index-b779f4e0.js";const g={queryAllConfig:()=>o.get("config/queryAll"),queryGptKeys:()=>o.get("config/queryGptKeys"),setGptKeys:t=>o.post("config/setGptKeys",t),queryConfig:t=>o.post("config/query",t),copyright:()=>o.get("config/copyright"),setConfig:t=>o.post("config/set",t)};export{g as a};

View File

@ -1,9 +0,0 @@
/**
* Fantastic-admin 提供技术支持
* Powered by Fantastic-admin
* Gitee https://gitee.com/hooray/fantastic-admin
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as v}from"./index-7911c6db.js";import{a as d}from"./config-b4a9e7c0.js";import{d as T,Q as q,r as m,x as j,o as B,c as E,e,f as t,a as h,k as N,E as g,h as n,q as y}from"./index-4eef28ae.js";const M={class:"flex justify-between"},O=h("b",null,"底部版权设置",-1),R=T({__name:"copyright",setup(A){const r=q({copyrightTitle:"",copyrightUrl:""}),b=m({copyrightUrl:[{required:!0,trigger:"blur",message:"请填写底部版权文字内容"}],copyrightTitle:[{required:!0,trigger:"blur",message:"请填写点击底部版本跳转的地址"}]}),s=m();async function c(){const l=await d.queryConfig({keys:["copyrightUrl","copyrightTitle"]});Object.assign(r,l.data)}function x(){var l;(l=s.value)==null||l.validate(async o=>{if(o){try{await d.setConfig({settings:V(r)}),g.success("变更配置信息成功")}catch{}c()}else g.error("请填写完整信息")})}function V(l){return Object.keys(l).map(o=>({configKey:o,configVal:l[o]}))}return j(()=>{c()}),(l,o)=>{const i=n("el-alert"),U=v,w=n("el-button"),u=n("el-input"),p=n("el-form-item"),_=n("el-col"),f=n("el-row"),C=n("el-form"),k=n("el-card");return B(),E("div",null,[e(U,null,{default:t(()=>[e(i,{closable:!1,"show-icon":"",title:"底部版本参数说明",description:"当前版本的后台版权信息、文字用于展示、地址用于点击文字的跳转地址",type:"success"})]),_:1}),e(k,{style:{margin:"20px"}},{header:t(()=>[h("div",M,[O,e(w,{class:"button",text:"",onClick:x},{default:t(()=>[N(" 保存设置 ")]),_:1})])]),default:t(()=>[e(C,{ref_key:"formRef",ref:s,rules:b.value,model:r,"label-width":"130px"},{default:t(()=>[e(f,null,{default:t(()=>[e(_,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(p,{label:"底部版权文字",prop:"copyrightTitle"},{default:t(()=>[e(u,{modelValue:r.copyrightTitle,"onUpdate:modelValue":o[0]||(o[0]=a=>r.copyrightTitle=a),placeholder:"请填写底部版权文字内容",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(f,null,{default:t(()=>[e(_,{xs:24,md:20,lg:15,xl:12},{default:t(()=>[e(p,{label:"底部跳转地址",prop:"copyrightUrl"},{default:t(()=>[e(u,{modelValue:r.copyrightUrl,"onUpdate:modelValue":o[1]||(o[1]=a=>r.copyrightUrl=a),placeholder:"请填写点击底部版本跳转的地址",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof y=="function"&&y(R);export{R as default};

View File

@ -6,4 +6,4 @@
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as B}from"./index-7911c6db.js";import{a as f}from"./config-b4a9e7c0.js";import{d as w,Q as R,r as p,x as h,o as q,c as v,e,f as o,a as S,k as O,E as g,h as a,q as b}from"./index-4eef28ae.js";const U={class:"flex justify-between"},j=S("b",null,"COS参数设置",-1),E=w({__name:"cos",setup(N){const t=R({cosSecretId:"",cosSecretKey:"",cosBucket:"",cosRegion:""}),y=p({cosSecretKey:[{required:!0,trigger:"blur",message:"请填写SecretKey"}],cosBucket:[{required:!0,trigger:"blur",message:"请填写存储桶名称"}],cosRegion:[{required:!0,trigger:"blur",message:"请填写存储桶所属地域"}],cosSecretId:[{required:!0,trigger:"blur",message:"请填写SecretId"}]}),i=p();async function m(){const r=await f.queryConfig({keys:["cosSecretKey","cosBucket","cosRegion","cosSecretId"]});Object.assign(t,r.data)}function x(){var r;(r=i.value)==null||r.validate(async l=>{if(l){try{await f.setConfig({settings:V(t)}),g.success("变更配置信息成功")}catch{}m()}else g.error("请填写完整信息")})}function V(r){return Object.keys(r).map(l=>({configKey:l,configVal:r[l]}))}return h(()=>{m()}),(r,l)=>{const _=a("el-alert"),k=B,C=a("el-button"),c=a("el-input"),s=a("el-form-item"),u=a("el-col"),d=a("el-row"),I=a("el-form"),K=a("el-card");return q(),v("div",null,[e(k,null,{default:o(()=>[e(_,{closable:!1,"show-icon":"",title:"COS参数说明",description:"当前默认使用腾讯云COS对象存储、如果您有特殊的对接通道、将为您开放API对接",type:"success"})]),_:1}),e(K,{style:{margin:"20px"}},{header:o(()=>[S("div",U,[j,e(C,{class:"button",text:"",onClick:x},{default:o(()=>[O(" 保存设置 ")]),_:1})])]),default:o(()=>[e(I,{ref_key:"formRef",ref:i,rules:y.value,model:t,"label-width":"120px"},{default:o(()=>[e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"SecretId",prop:"cosSecretId"},{default:o(()=>[e(c,{modelValue:t.cosSecretId,"onUpdate:modelValue":l[0]||(l[0]=n=>t.cosSecretId=n),placeholder:"请填写SecretId",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"SecretKey",prop:"cosSecretKey"},{default:o(()=>[e(c,{modelValue:t.cosSecretKey,"onUpdate:modelValue":l[1]||(l[1]=n=>t.cosSecretKey=n),placeholder:"请填写SecretKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"存储桶名称",prop:"cosBucket"},{default:o(()=>[e(c,{modelValue:t.cosBucket,"onUpdate:modelValue":l[2]||(l[2]=n=>t.cosBucket=n),placeholder:"请填写存储桶名称",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"所属地域",prop:"cosRegion"},{default:o(()=>[e(c,{modelValue:t.cosRegion,"onUpdate:modelValue":l[3]||(l[3]=n=>t.cosRegion=n),placeholder:"请填写所属地域(ap-guangzhou)",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof b=="function"&&b(E);export{E as default};
import{_ as B}from"./index-38e73db4.js";import{a as f}from"./config-61dee393.js";import{d as w,Q as R,r as p,x as h,h as a,o as q,c as v,e,f as o,a as S,l as O,E as g,q as b}from"./index-b779f4e0.js";const U={class:"flex justify-between"},j=S("b",null,"COS参数设置",-1),E=w({__name:"cos",setup(N){const t=R({cosSecretId:"",cosSecretKey:"",cosBucket:"",cosRegion:""}),y=p({cosSecretKey:[{required:!0,trigger:"blur",message:"请填写SecretKey"}],cosBucket:[{required:!0,trigger:"blur",message:"请填写存储桶名称"}],cosRegion:[{required:!0,trigger:"blur",message:"请填写存储桶所属地域"}],cosSecretId:[{required:!0,trigger:"blur",message:"请填写SecretId"}]}),i=p();async function m(){const r=await f.queryConfig({keys:["cosSecretKey","cosBucket","cosRegion","cosSecretId"]});Object.assign(t,r.data)}function x(){var r;(r=i.value)==null||r.validate(async l=>{if(l){try{await f.setConfig({settings:V(t)}),g.success("变更配置信息成功")}catch{}m()}else g.error("请填写完整信息")})}function V(r){return Object.keys(r).map(l=>({configKey:l,configVal:r[l]}))}return h(()=>{m()}),(r,l)=>{const _=a("el-alert"),k=B,C=a("el-button"),c=a("el-input"),s=a("el-form-item"),u=a("el-col"),d=a("el-row"),I=a("el-form"),K=a("el-card");return q(),v("div",null,[e(k,null,{default:o(()=>[e(_,{closable:!1,"show-icon":"",title:"COS参数说明",description:"当前默认使用腾讯云COS对象存储、如果您有特殊的对接通道、将为您开放API对接",type:"success"})]),_:1}),e(K,{style:{margin:"20px"}},{header:o(()=>[S("div",U,[j,e(C,{class:"button",text:"",onClick:x},{default:o(()=>[O(" 保存设置 ")]),_:1})])]),default:o(()=>[e(I,{ref_key:"formRef",ref:i,rules:y.value,model:t,"label-width":"120px"},{default:o(()=>[e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"SecretId",prop:"cosSecretId"},{default:o(()=>[e(c,{modelValue:t.cosSecretId,"onUpdate:modelValue":l[0]||(l[0]=n=>t.cosSecretId=n),placeholder:"请填写SecretId",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"SecretKey",prop:"cosSecretKey"},{default:o(()=>[e(c,{modelValue:t.cosSecretKey,"onUpdate:modelValue":l[1]||(l[1]=n=>t.cosSecretKey=n),placeholder:"请填写SecretKey",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"存储桶名称",prop:"cosBucket"},{default:o(()=>[e(c,{modelValue:t.cosBucket,"onUpdate:modelValue":l[2]||(l[2]=n=>t.cosBucket=n),placeholder:"请填写存储桶名称",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1}),e(d,null,{default:o(()=>[e(u,{xs:24,md:20,lg:15,xl:12},{default:o(()=>[e(s,{label:"所属地域",prop:"cosRegion"},{default:o(()=>[e(c,{modelValue:t.cosRegion,"onUpdate:modelValue":l[3]||(l[3]=n=>t.cosRegion=n),placeholder:"请填写所属地域(ap-guangzhou)",clearable:""},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})]),_:1},8,["rules","model"])]),_:1})])}}});typeof b=="function"&&b(E);export{E as default};

File diff suppressed because one or more lines are too long

View File

@ -1,9 +0,0 @@
/**
* Fantastic-admin 提供技术支持
* Powered by Fantastic-admin
* Gitee https://gitee.com/hooray/fantastic-admin
* Github https://github.com/hooray/fantastic-admin
*/
import{_ as O}from"./index-7911c6db.js";import{d as $,y as j,r,Q as P,B as Q,x as X,o as s,c as g,e as l,f as t,b as n,ap as S,j as I,R as W,S as x,k as m,w as G,I as p,U as H,W as J,E as R,h as i,X as Y,l as Z,t as ee,q as K}from"./index-4eef28ae.js";import{A as k}from"./badWords-bb34c9e2.js";import{E as te}from"./index-66a830a3.js";const le=$({__name:"custom",setup(oe){const N=j(),V=r(),T=r(0),f=r(!1),u=P({word:"",status:"",page:1,size:500}),U=Q(()=>N.settings.app.colorScheme),h=r([]);async function d(){try{f.value=!0;const a=await k.queryBadWords(u),{rows:o,count:v}=a.data;f.value=!1,T.value=v,h.value=o}catch{f.value=!1}}function A(a){a==null||a.resetFields(),d()}X(()=>{d()});const c=r(""),_=r(!1),B=r();async function D(a){await k.delBadWords({id:a}),R.success("删除敏感词成功"),await d()}function L(){_.value=!0,J(()=>{B.value.input.focus()})}async function C(){c.value&&(await k.addBadWords({word:c.value}),R.success("添加敏感词成功"),u.status="",await d()),_.value=!1,c.value=""}return(a,o)=>{const v=i("el-alert"),y=O,w=i("el-form-item"),q=i("el-option"),z=i("el-select"),b=i("el-button"),E=i("el-form"),M=i("el-tag"),F=Y("loading");return s(),g("div",null,[l(y,null,{default:t(()=>[l(v,{closable:!1,"show-icon":"",title:"敏感词说明",description:"当前为自定义敏感词、触发敏感词将自动拦截、如配置过三方平台、自定义检测将在三方平台通过后最后进行检测!",type:"success"})]),_:1}),l(y,null,{default:t(()=>[l(E,{ref_key:"formRef",ref:V,inline:!0,model:u},{default:t(()=>[l(w,{label:"敏感词",prop:"word"},{default:t(()=>[l(n(S),{modelValue:u.word,"onUpdate:modelValue":o[0]||(o[0]=e=>u.word=e),placeholder:"敏感词[模糊搜索]",onKeydown:I(Z(d,["prevent"]),["enter"])},null,8,["modelValue","onKeydown"])]),_:1}),l(w,{label:"敏感词状态",prop:"status"},{default:t(()=>[l(z,{modelValue:u.status,"onUpdate:modelValue":o[1]||(o[1]=e=>u.status=e),placeholder:"请选择敏感词状态",clearable:""},{default:t(()=>[(s(!0),g(W,null,x(n(te),e=>(s(),p(q,{key:e.value,label:e.label,value:e.value},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),l(w,null,{default:t(()=>[l(b,{type:"primary",onClick:d},{default:t(()=>[m(" 查询 ")]),_:1}),l(b,{onClick:o[2]||(o[2]=e=>A(n(V)))},{default:t(()=>[m(" 重置 ")]),_:1})]),_:1})]),_:1},8,["model"])]),_:1}),G((s(),p(y,{style:{width:"100%"}},{default:t(()=>[(s(!0),g(W,null,x(n(h),e=>(s(),p(M,{key:e.id,type:"warning",class:"mr-3 mb-3",closable:"",hit:"",effect:n(U),"disable-transitions":!0,onClose:ae=>D(e.id)},{default:t(()=>[m(ee(e.word),1)]),_:2},1032,["effect","onClose"]))),128)),n(_)?(s(),p(n(S),{key:0,ref_key:"InputRef",ref:B,modelValue:n(c),"onUpdate:modelValue":o[3]||(o[3]=e=>H(c)?c.value=e:null),class:"ml-1",style:{width:"80px"},size:"small",onKeyup:I(C,["enter"]),onBlur:C},null,8,["modelValue","onKeyup"])):(s(),p(b,{key:1,class:"ml-1",size:"small",onClick:L},{default:t(()=>[m(" + New Word ")]),_:1}))]),_:1})),[[F,n(f)]])])}}});typeof K=="function"&&K(le);export{le as default};

Some files were not shown because too many files have changed in this diff Show More