mirror of
https://github.com/vastxie/99AI.git
synced 2024-11-15 19:22:29 +08:00
v3.5.0
This commit is contained in:
parent
086e5aed3c
commit
4fef3663e4
12
.env.docker
12
.env.docker
|
@ -1,7 +1,5 @@
|
|||
# server base
|
||||
PORT=9520
|
||||
PREFIX=/docs
|
||||
APIPREFIX=/api
|
||||
|
||||
DB_HOST=mysql
|
||||
DB_PORT=3306
|
||||
|
@ -10,17 +8,17 @@ DB_PASS=123456
|
|||
DB_DATABASE=chatgpt
|
||||
DB_SYNC=true
|
||||
|
||||
# jwt key token过期时间
|
||||
JWT_SECRET=chat-cooper
|
||||
JWT_EXPIRESIN=7d
|
||||
|
||||
# Redis
|
||||
REDIS_PORT=6379
|
||||
REDIS_HOST=redis
|
||||
REDIS_PASSWORD=
|
||||
REDIS_USER=
|
||||
REDIS_DB=0
|
||||
|
||||
# 是否测试环境
|
||||
ISDEV=FALSE
|
||||
|
||||
NAMESPACE=AIWEB
|
||||
# 自定义微信URL
|
||||
weChatOpenUrl=https://open.weixin.qq.com
|
||||
weChatApiUrl=https://api.weixin.qq.com
|
||||
weChatMpUrl=https://mp.weixin.qq.com
|
||||
|
|
22
.env.example
22
.env.example
|
@ -1,33 +1,25 @@
|
|||
# server base
|
||||
# 端口
|
||||
PORT=9520
|
||||
PREFIX=/docs
|
||||
APIPREFIX=/api
|
||||
|
||||
# MySQL
|
||||
# MySQL数据库主机地址
|
||||
DB_HOST=localhost
|
||||
# MySQL数据库端口号
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
# MySQL数据库用户名
|
||||
DB_USER=root
|
||||
# MySQL数据库密码
|
||||
DB_PASS=
|
||||
# 要使用的MySQL数据库名称
|
||||
DB_DATABASE=chatgpt
|
||||
DB_SYNC=true
|
||||
|
||||
|
||||
# jwt key token过期时间
|
||||
JWT_SECRET=chat-cooper
|
||||
JWT_EXPIRESIN=7d
|
||||
|
||||
# Redis
|
||||
REDIS_PORT=6379
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=
|
||||
REDIS_USER=
|
||||
REDIS_DB=0
|
||||
|
||||
# 是否测试环境
|
||||
ISDEV=FALSE
|
||||
|
||||
NAMESPACE=AIWEB
|
||||
# 自定义微信URL
|
||||
weChatOpenUrl=https://open.weixin.qq.com
|
||||
weChatApiUrl=https://api.weixin.qq.com
|
||||
weChatMpUrl=https://mp.weixin.qq.com
|
||||
|
|
34
Dockerfile
34
Dockerfile
|
@ -1,23 +1,29 @@
|
|||
# 编译阶段
|
||||
FROM node:18-alpine AS base
|
||||
FROM base AS build
|
||||
FROM node:20.14.0-alpine AS build
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json ./
|
||||
|
||||
# 使用腾讯源(国内服务器可取消下方注释以提升安装速度)
|
||||
# RUN npm config set registry https://mirrors.cloud.tencent.com/npm/
|
||||
COPY package*.json ./
|
||||
|
||||
# 如遇到提示网站证书无效,取消下方注释,禁止严格SS策略
|
||||
# RUN npm config set strict-ssl false
|
||||
|
||||
# 使用淘宝源安装项目依赖(国内用户居多)
|
||||
RUN npm config set registry https://registry.npmmirror.com && \
|
||||
npm install --omit=dev
|
||||
# 设置环境变量来忽略一些警告
|
||||
ENV NPM_CONFIG_LOGLEVEL=error
|
||||
ENV NODE_OPTIONS=--max-old-space-size=4096
|
||||
|
||||
# 合并RUN命令,更新依赖,设置镜像源,安装依赖,然后清理
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
|
||||
npm config set registry https://registry.npmmirror.com && \
|
||||
apk add --no-cache --virtual .build-deps git && \
|
||||
npm install -g npm@latest && \
|
||||
npm install --production --no-optional --legacy-peer-deps && \
|
||||
npm cache clean --force && \
|
||||
apk del .build-deps && \
|
||||
rm -rf /var/cache/apk/* /tmp/*
|
||||
|
||||
# 运行阶段
|
||||
FROM base AS runner
|
||||
ENV TZ="Asia/Shanghai"
|
||||
FROM node:20.14.0-alpine AS runner
|
||||
|
||||
ENV TZ="Asia/Shanghai" \
|
||||
NODE_ENV=production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
@ -26,4 +32,4 @@ COPY . .
|
|||
|
||||
EXPOSE 9520
|
||||
|
||||
CMD ["node", "./dist/main.js"]
|
||||
CMD ["node", "--max-old-space-size=4096", "./dist/main.js"]
|
||||
|
|
106
README.md
106
README.md
|
@ -1,13 +1,11 @@
|
|||
# 99 AI 稳定版
|
||||
|
||||
基于 NineAI 2.4.2 二开的可商业化 AI Web 应用,已编译为前后端整合包,支持快速部署。
|
||||
|
||||
旨在提供一个易部署的集成化人工智能服务站点。
|
||||
可商业化的 AI Web 应用,旨在提供一个易部署的集成化人工智能服务站点。已编译为前后端整合包,支持快速部署。
|
||||
|
||||
## 版本说明
|
||||
|
||||
| 特性 | 稳定版 | 开发版 |
|
||||
| :--- | :--- | :--- |
|
||||
| :--------- | :--------------------------- | :--------------------------- |
|
||||
| 项目功能 | 详见项目介绍 | 有一定的保留功能 |
|
||||
| 更新频率 | 月更 | 周更 |
|
||||
| 商用许可 | 可直接商用 | 可直接商用 |
|
||||
|
@ -19,36 +17,94 @@
|
|||
|
||||
## 项目介绍
|
||||
|
||||
**应用广场**
|
||||
### 基础对话
|
||||
|
||||
![应用广场](https://github.com/vastxie/99AI/assets/24899308/2cbeab33-0b6b-4f56-81a6-1e15e097023f)
|
||||
**AI 对话**
|
||||
|
||||
支持 OpenAI Chat 格式,后台可自定义模型名称、头像、介绍、代理、key、积分扣除方式、文件上传模式等参数。
|
||||
|
||||
**支持多模态**
|
||||
|
||||
使用`gpt-4o`、`claude-3`等视觉模型,或`gpt-4-all`等逆向模型,完成图像、文件的识别分析。
|
||||
|
||||
### 插件系统
|
||||
|
||||
对接[插件系统](https://github.com/vastxie/99AIPlugin),拓展 AI 功能边界。
|
||||
|
||||
**联网搜索**
|
||||
|
||||
**思维导图**
|
||||
|
||||
**AI 绘画**
|
||||
|
||||
![AI 绘画](https://github.com/vastxie/99AI/assets/24899308/1155d39a-aeed-481e-9f80-127500bf59e7)
|
||||
对接 `midjourney` 、`dall-e`、`stable-diffusion` 等绘画模型。
|
||||
|
||||
**AI 音乐**
|
||||
|
||||
![screenshot-1713627618821](https://github.com/vastxie/99AI/assets/24899308/f6966ae8-8be6-4ba5-8d06-c89b4c864f88)
|
||||
对接 `suno-music` 完成音乐创作。
|
||||
|
||||
**文件分析**(开发版支持)
|
||||
**AI 视频**
|
||||
|
||||
![文件分析](https://github.com/vastxie/99AI/assets/24899308/68e80920-6b54-4a50-8b76-2c8c946e8717)
|
||||
对接 `luma-video` 文生视频。
|
||||
|
||||
**绘画广场**
|
||||
### 开发版已 / 将支持
|
||||
|
||||
![绘画广场](https://github.com/vastxie/99AI/assets/24899308/4eb3954e-489d-48f6-9d9d-4de6d2fcce83)
|
||||
**AI 音乐弹窗**
|
||||
|
||||
支持调整歌词,选择音乐类型及风格。
|
||||
|
||||
**更丰富 AI 视频选项**
|
||||
|
||||
支持图生视频,视频尺寸的选择。
|
||||
|
||||
**代码预览**
|
||||
|
||||
支持 `HTML` 代码的预览与编辑。
|
||||
|
||||
**全模型文件分析**
|
||||
|
||||
更多功能持续开发中 ··· ···
|
||||
|
||||
### 不再维护的页面
|
||||
|
||||
**专业绘图**
|
||||
|
||||
![绘画页](https://github.com/vastxie/99AI/assets/24899308/148fb1fa-820c-4fe1-9dbe-e967ee41fd8b)
|
||||
|
||||
**绘画广场**
|
||||
|
||||
![绘画广场](https://github.com/vastxie/99AI/assets/24899308/4eb3954e-489d-48f6-9d9d-4de6d2fcce83)
|
||||
|
||||
**分销邀请**
|
||||
|
||||
![分销推荐](https://github.com/vastxie/99AI/assets/24899308/cc280beb-d0cb-43d1-984e-4a7b3a61b807)
|
||||
![分销邀请](https://github.com/vastxie/99AI/assets/24899308/cc280beb-d0cb-43d1-984e-4a7b3a61b807)
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 稳定版 v3.5.0
|
||||
|
||||
主要更新内容:
|
||||
|
||||
- 对话 UI 参考 ChatGPT 官网调整为左右布局。
|
||||
- 全新的[插件系统](https://github.com/vastxie/99AIPlugin)
|
||||
- 普通插件:联网搜索、思维导图。
|
||||
- 内置插件:Midjourney 绘图、Dalle 绘图、Stable-Diffusion 绘图、Suno 音乐、Luma 视频。
|
||||
- 优化调整多处 UI 界面显示。
|
||||
- 新增模型自定义图标及介绍。
|
||||
- 提问输入框支持通过剪切板粘贴图片,文件。
|
||||
- 对话显示公式渲染适配 `/[ /]`、`/( /)` 格式。
|
||||
- 新增对话中使用 `@` 调用应用功能。
|
||||
- 优化首页“九宫格”显示(使用内置对话预设、不再依赖后端配置)
|
||||
- Midjourney 绘图支持 `图生图`、`人脸一致性`、`风格一致性`、`MJ版本`自定义参数等自定义选择。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>历史日志</summary>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>历史日志</summary>
|
||||
|
||||
### 稳定版 v3.3.0
|
||||
|
||||
- 重构流式回复逻辑,加入错误反馈并优化用户端等待动画。
|
||||
|
@ -68,20 +124,6 @@
|
|||
- 重构应用逻辑,翻译及导图特殊模型不再需配置,已整合至【模型管理-系统应用】。
|
||||
- 新增模型配置选项,允许设置模型调用频率限制,确保用户体验。
|
||||
|
||||
### 开发版已/将支持
|
||||
|
||||
- 对话页 Midjourney 绘图支持 `图生图` `人脸一致性` `风格一致性` 以及更多自定义参数选择。
|
||||
- 全模型文件分析功能(只支持带文字的 pdf,word,ppt,txt,md 等文件)。
|
||||
- 全新的插件系统——联网搜索、思维导图等 ··· ···
|
||||
- `SD3` / `SD3 Turbo` 绘图模型,`Stable Video` 图生视频模型(`stability.ai` API 格式)。
|
||||
- Azure TTS 模型支持,语音播报更生动自然。
|
||||
- 临时文件支持本地存储并自动清空。
|
||||
- 更多功能持续开发中 ··· ···
|
||||
|
||||
<details>
|
||||
|
||||
<summary>历史日志</summary>
|
||||
|
||||
### v3.0.0
|
||||
|
||||
**前端改进**
|
||||
|
@ -182,7 +224,6 @@
|
|||
**3. 其他配置**
|
||||
|
||||
- 需配置 Redis 数据库以及新建一个 MySQL 数据库。
|
||||
|
||||
- 配置环境变量:
|
||||
- 复制 `.env.example` 文件为 `.env`。
|
||||
- 根据需要修改 `.env` 文件中的配置项。
|
||||
|
@ -231,6 +272,14 @@
|
|||
|
||||
**2. Shell 执行脚本**
|
||||
|
||||
请在项目的根目录下执行以下命令:
|
||||
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
或使用:
|
||||
|
||||
```bash
|
||||
bash <(curl -sL https://js.kengro.cn/99ai/onekey-cn-99ai.sh)
|
||||
```
|
||||
|
@ -285,7 +334,6 @@ bash <(curl -sL https://js.kengro.cn/99ai/onekey-cn-99ai.sh)
|
|||
|
||||
- **密码**:`123456`
|
||||
|
||||
|
||||
## 学习交流
|
||||
|
||||
扫码添加微信备注 `99`,拉交流群。(不接受私聊技术咨询,有问题优先群内交流)
|
||||
|
|
405
deploy.sh
Executable file
405
deploy.sh
Executable file
|
@ -0,0 +1,405 @@
|
|||
#!/usr/bin/env bash
|
||||
export LANG=zh_CN.UTF-8
|
||||
|
||||
# Set up color variables for output
|
||||
red='\033[0;31m'
|
||||
green='\033[0;32m'
|
||||
plain='\033[0m'
|
||||
|
||||
# Default values
|
||||
NVM_URL="https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh"
|
||||
default_node_version="18.16.0"
|
||||
CHATGPT_PORT=9520
|
||||
CONFIG_FILE=docker-compose.yml
|
||||
|
||||
# Welcome message
|
||||
echo -e "${green}欢迎使用99AI一键部署和升级脚本${plain}"
|
||||
echo -e "${green}----------------------------------------${plain}"
|
||||
echo -e "${green}注意:${plain}"
|
||||
echo -e "${green}1. Node.js 部署方式需要提前安装好 MySQL 和 Redis。${plain}"
|
||||
echo -e "${green}2. Docker 部署方式可以选择新建 MySQL 和 Redis 容器。${plain}"
|
||||
echo -e "${green}3. 从旧版本升级 Docker 时,请确保 data 和 SQL 文件已备份到根目录。${plain}"
|
||||
echo -e "${green}----------------------------------------${plain}"
|
||||
|
||||
check_cpu_arch() {
|
||||
case "$(uname -m)" in
|
||||
aarch64) arch=linux_arm64 ;;
|
||||
i686) arch=linux_386 ;;
|
||||
arm) arch=linux_arm ;;
|
||||
x86_64) arch=linux_amd64 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_os() {
|
||||
if [[ "$(uname)" == "Darwin" ]]; then
|
||||
os_name="macOS"
|
||||
InstallMethod="brew"
|
||||
else
|
||||
if command -v lsb_release >/dev/null; then
|
||||
DISTRO=$(lsb_release -i -s)
|
||||
else
|
||||
DISTRO=$(grep -oP '^ID=\K.*' /etc/*-release)
|
||||
fi
|
||||
case "$DISTRO" in
|
||||
Debian|Ubuntu) os_name="${DISTRO}-based Linux"; InstallMethod="sudo apt-get" ;;
|
||||
centos)
|
||||
if [[ "$(grep -oP '^VERSION_ID="\K[0-9]+' /etc/*-release)" == "7" ]]; then
|
||||
os_name="CentOS 7"; InstallMethod="yum"
|
||||
else
|
||||
os_name="CentOS 8"; InstallMethod="dnf"
|
||||
fi ;;
|
||||
fedora) os_name="Fedora"; InstallMethod="dnf" ;;
|
||||
opensuse-leap) os_name="openSUSE Leap"; InstallMethod="sudo zypper" ;;
|
||||
*) echo "未知操作系统,脚本不支持"; exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
install_if_missing() {
|
||||
if ! command -v "$1" >/dev/null; then
|
||||
echo -e "${red}$1 未安装,正在安装 $1...${plain}"
|
||||
${InstallMethod} install -y "$1"
|
||||
echo -e "${green}$1 已安装${plain}"
|
||||
else
|
||||
echo -e "${green}$1 已安装${plain}"
|
||||
fi
|
||||
}
|
||||
|
||||
install_nvm_and_node() {
|
||||
if ! command -v node >/dev/null; then
|
||||
echo -e "${red}node 未安装${plain}"
|
||||
echo -e "${red}开始安装NVM${plain}"
|
||||
curl -o- $NVM_URL | bash || wget -qO- $NVM_URL | bash
|
||||
source ~/.bashrc
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
|
||||
|
||||
echo -e "${green}列出node可用版本${plain}"
|
||||
nvm ls-remote
|
||||
read -p "请输入要安装的 Node.js 版本号 ,不知道安装啥的请回车[默认版本:$default_node_version]:" node_version
|
||||
node_version="${node_version:-$default_node_version}"
|
||||
echo -e "${red}正在安装 node-v$node_version${plain}"
|
||||
nvm install $node_version
|
||||
nvm use $node_version
|
||||
source ~/.bashrc
|
||||
|
||||
if ! command -v node >/dev/null; then
|
||||
echo -e "${red}Node.js 安装失败,请检查错误信息!${plain}"
|
||||
exit 1
|
||||
fi
|
||||
installed_version=$(node -v)
|
||||
if [[ "$installed_version" != "v$node_version" ]]; then
|
||||
echo -e "${red}Node.js 安装失败,当前安装版本为 $installed_version, 期望安装版本为 v$node_version ${plain}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${green}Node.js 安装完成!${plain}"
|
||||
else
|
||||
echo -e "${green}node 已安装${plain}"
|
||||
fi
|
||||
}
|
||||
|
||||
install_add_docker() {
|
||||
if [ -f "/etc/alpine-release" ]; then
|
||||
echo -e "${red}docker 未安装,正在安装 docker...${plain}"
|
||||
apk update
|
||||
apk add docker docker-compose
|
||||
echo -e "${green}docker 和 docker-compose 已安装${plain}"
|
||||
rc-update add docker default
|
||||
service docker start
|
||||
else
|
||||
echo -e "${red}docker 未安装,正在安装 docker...${plain}"
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
echo -e "${green}docker 已安装${plain}"
|
||||
ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin
|
||||
echo -e "${green}docker-compose 已安装${plain}"
|
||||
systemctl start docker
|
||||
systemctl enable docker
|
||||
fi
|
||||
echo -e "${green}docker 和 docker-compose 已安装${plain}"
|
||||
sleep 2
|
||||
}
|
||||
|
||||
docker_install() {
|
||||
if ! command -v docker &>/dev/null; then
|
||||
install_add_docker
|
||||
else
|
||||
echo "Docker 已经安装"
|
||||
fi
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
check_cpu_arch
|
||||
check_os
|
||||
|
||||
${InstallMethod} update -y >/dev/null 2>&1
|
||||
|
||||
install_if_missing git
|
||||
install_if_missing cat
|
||||
install_if_missing curl
|
||||
|
||||
if [[ "$operation_choice" == "1" || "$operation_choice" == "2" ]]; then
|
||||
install_nvm_and_node
|
||||
install_if_missing npm
|
||||
|
||||
if ! command -v pm2 >/dev/null; then
|
||||
echo -e "${red}pm2 未安装,正在安装 pm2...${plain}"
|
||||
npm install -g pm2
|
||||
echo -e "${green}pm2 已安装${plain}"
|
||||
else
|
||||
echo -e "${green}pm2 已安装${plain}"
|
||||
fi
|
||||
elif [[ "$operation_choice" == "3" || "$operation_choice" == "4" ]]; then
|
||||
docker_install
|
||||
fi
|
||||
}
|
||||
|
||||
# Node.js 部署任务
|
||||
node_deploy() {
|
||||
# 选择依赖管理工具
|
||||
read -p "请选择依赖管理工具(1. pnpm 2. yarn,输入q退出)[默认: 1]: " package_manager_choice
|
||||
package_manager_choice=${package_manager_choice:-1}
|
||||
|
||||
if [[ "$package_manager_choice" == "q" ]]; then
|
||||
echo "退出脚本"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ "$package_manager_choice" == "2" ]]; then
|
||||
if ! command -v yarn >/dev/null; then
|
||||
echo -e "${red}yarn 未安装,正在安装 yarn...${plain}"
|
||||
npm install -g yarn
|
||||
echo -e "${green}yarn 已安装${plain}"
|
||||
else
|
||||
echo -e "${green}yarn 已安装${plain}"
|
||||
fi
|
||||
package_manager="yarn"
|
||||
else
|
||||
if ! command -v pnpm >/dev/null; then
|
||||
echo -e "${red}pnpm 未安装,正在安装 pnpm...${plain}"
|
||||
npm install -g pnpm
|
||||
echo -e "${green}pnpm 已安装${plain}"
|
||||
else
|
||||
echo -e "${green}pnpm 已安装${plain}"
|
||||
fi
|
||||
package_manager="pnpm"
|
||||
fi
|
||||
|
||||
# 选择安装方式
|
||||
read -p "请选择安装方式(1. 全新安装 2. 更新,输入q退出)[默认: 1]: " install_choice
|
||||
install_choice=${install_choice:-1}
|
||||
|
||||
if [[ "$install_choice" == "q" ]]; then
|
||||
echo "退出脚本"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ "$install_choice" == "2" ]]; then
|
||||
echo "开始安装依赖包"
|
||||
$package_manager install
|
||||
echo "安装完成,开始运行99AI"
|
||||
$package_manager start
|
||||
pm2 save
|
||||
exit
|
||||
fi
|
||||
|
||||
echo -e "${green}请确保已安装MySQL和Redis${plain}"
|
||||
|
||||
echo -e "${green}正在进行运行配置${plain}"
|
||||
read -p "设置PORT(程序访问端口)为[回车默认: 9520]: " input_port
|
||||
PORT=${input_port:-9520}
|
||||
|
||||
read -p "设置DB_HOST为(数据库地址)[回车默认: 127.0.0.1]: " input_db_host
|
||||
DB_HOST=${input_db_host:-127.0.0.1}
|
||||
|
||||
read -p "设置DB_PORT为(数据库端口)[回车默认: 3306]: " input_db_port
|
||||
DB_PORT=${input_db_port:-3306}
|
||||
|
||||
read -p "设置DB_USER为(数据库用户名)[回车默认: root]: " input_db_user
|
||||
DB_USER=${input_db_user:-root}
|
||||
|
||||
read -p "设置DB_PASS(数据库密码)为[回车默认: 空]: " input_db_pass
|
||||
DB_PASS=${input_db_pass:-""}
|
||||
|
||||
read -p "设置DB_DATABASE(数据库名)为: " input_db_database
|
||||
DB_DATABASE=${input_db_database:-""}
|
||||
|
||||
read -p "设置REDIS_PORT(redis端口)为[回车默认: 6379]: " input_redis_port
|
||||
REDIS_PORT=${input_redis_port:-6379}
|
||||
|
||||
read -p "设置REDIS_HOST(redis地址)为[回车默认: 127.0.0.1]: " input_redis_host
|
||||
REDIS_HOST=${input_redis_host:-127.0.0.1}
|
||||
|
||||
read -p "设置REDIS_PASSWORD(redis密码)为[回车默认: 空]: " input_redis_password
|
||||
REDIS_PASSWORD=${input_redis_password:-""}
|
||||
|
||||
read -p "设置REDIS_DB(redis数据库)为[回车默认: 0]: " input_redis_db
|
||||
REDIS_DB=${input_redis_db:-"0"}
|
||||
|
||||
cat >.env <<EOF
|
||||
# server base
|
||||
PORT=$PORT
|
||||
PREFIX=/docs
|
||||
APIPREFIX=/api
|
||||
|
||||
# MySQL
|
||||
DB_HOST=$DB_HOST
|
||||
DB_PORT=$DB_PORT
|
||||
DB_USER=$DB_USER
|
||||
DB_PASS=$DB_PASS
|
||||
DB_DATABASE=$DB_DATABASE
|
||||
DB_SYNC=true
|
||||
|
||||
# Redis
|
||||
REDIS_PORT=$REDIS_PORT
|
||||
REDIS_HOST=$REDIS_HOST
|
||||
REDIS_PASSWORD=$REDIS_PASSWORD
|
||||
REDIS_DB=$REDIS_DB
|
||||
|
||||
# 是否测试环境
|
||||
ISDEV=FALSE
|
||||
|
||||
NAMESPACE=AIWEB
|
||||
EOF
|
||||
|
||||
declare -a NPM_MIRRORS=(
|
||||
"淘宝镜像" "https://registry.npmmirror.com"
|
||||
"阿里云镜像" "https://npm.aliyun.com"
|
||||
"腾讯云镜像" "https://mirrors.cloud.tencent.com/npm/"
|
||||
"华为云镜像" "https://mirrors.huaweicloud.com/repository/npm/"
|
||||
"网易镜像" "https://mirrors.163.com/npm/"
|
||||
"中科院大学开源镜像站" "http://mirrors.ustc.edu.cn/"
|
||||
"清华大学开源镜像站" "https://mirrors.tuna.tsinghua.edu.cn/"
|
||||
)
|
||||
|
||||
echo -e "${green}请选择要使用的npm源:${plain}"
|
||||
|
||||
for ((i=0; i<${#NPM_MIRRORS[@]}; i+=2)); do
|
||||
echo "$((i / 2 + 1))) ${NPM_MIRRORS[i]}"
|
||||
done
|
||||
|
||||
echo "8) 不使用国内源"
|
||||
echo "9) 退出"
|
||||
|
||||
read -p "请输入数字(1-9): " selection
|
||||
|
||||
case $selection in
|
||||
1 | 2 | 3 | 4 | 5 | 6 | 7)
|
||||
echo "设置npm源为:${NPM_MIRRORS[$(($selection * 2 - 1))]} ..."
|
||||
$package_manager config set registry ${NPM_MIRRORS[$(($selection * 2 - 1))]}
|
||||
echo "设置完成."
|
||||
;;
|
||||
8)
|
||||
echo "您选择了不使用国内源."
|
||||
;;
|
||||
9)
|
||||
echo "退出设置."
|
||||
exit
|
||||
;;
|
||||
*)
|
||||
echo "无效选择"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "开始安装依赖包"
|
||||
$package_manager install
|
||||
echo "安装完成,开始运行99AI"
|
||||
$package_manager start
|
||||
pm2 save
|
||||
|
||||
echo -e "=================================================================="
|
||||
echo -e "\033[32m安装成功!\033[0m"
|
||||
echo -e "=================================================================="
|
||||
|
||||
quit
|
||||
}
|
||||
|
||||
# Docker-compose 启动任务
|
||||
start_compose() {
|
||||
echo "配置阶段完成,启动docker-compose up -d。"
|
||||
docker-compose up -d
|
||||
echo "已启动docker-compose并使用默认配置启动了以下服务:"
|
||||
docker-compose ps
|
||||
}
|
||||
|
||||
# Docker-compose 配置任务
|
||||
config_compose() {
|
||||
echo "开始配置……"
|
||||
source .env.docker
|
||||
|
||||
read -p "是否修改端口[默认 9520](y/n,输入q退出): " change_port
|
||||
if [[ $change_port == "y" ]]; then
|
||||
read -p "输入您想修改的端口: " CHATGPT_PORT
|
||||
elif [[ $change_port == "q" ]]; then
|
||||
echo "退出脚本"
|
||||
exit
|
||||
fi
|
||||
|
||||
check_port() {
|
||||
netstat -tlpn | grep "\b$1\b" &> /dev/null
|
||||
}
|
||||
|
||||
if [[ $change_port == "y" ]]; then
|
||||
while check_port $CHATGPT_PORT; do
|
||||
read -p "端口 $CHATGPT_PORT 被占用,请重新输入端口: " CHATGPT_PORT
|
||||
done
|
||||
echo -e "\e[34m恭喜,端口 $CHATGPT_PORT 可用\e[0m"
|
||||
sed -E -i "s/[0-9]+:9520/$CHATGPT_PORT:9520/" docker-compose.yml
|
||||
fi
|
||||
|
||||
start_compose
|
||||
}
|
||||
|
||||
# Docker-compose 升级任务
|
||||
upgrade_compose() {
|
||||
echo "停止当前服务..."
|
||||
docker-compose down
|
||||
echo "重新构建并启动服务..."
|
||||
docker-compose up -d --build
|
||||
echo "服务已启动。"
|
||||
docker-compose ps
|
||||
}
|
||||
|
||||
# 选择操作
|
||||
echo "请选择操作:"
|
||||
echo "1. Node.js 全新部署"
|
||||
echo "2. Node.js 升级"
|
||||
echo "3. Docker-compose 部署"
|
||||
echo "4. Docker-compose 升级"
|
||||
|
||||
read -p "请输入数字(1-4,输入q退出)[默认: 1]: " operation_choice
|
||||
operation_choice=${operation_choice:-1}
|
||||
|
||||
if [[ "$operation_choice" == "q" ]]; then
|
||||
echo "退出脚本"
|
||||
exit
|
||||
fi
|
||||
|
||||
check_dependencies
|
||||
|
||||
case $operation_choice in
|
||||
1)
|
||||
echo "Node.js 全新部署选择"
|
||||
node_deploy
|
||||
;;
|
||||
2)
|
||||
echo "Node.js 升级选择"
|
||||
node_deploy
|
||||
;;
|
||||
3)
|
||||
echo "Docker-compose 部署选择"
|
||||
config_compose
|
||||
;;
|
||||
4)
|
||||
echo "Docker-compose 升级选择"
|
||||
upgrade_compose
|
||||
;;
|
||||
*)
|
||||
echo "无效选择,退出。"
|
||||
quit
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -e "=================================================================="
|
||||
echo -e "\033[32m安装成功!\033[0m"
|
||||
echo -e "=================================================================="
|
52
dist/app.module.js
vendored
52
dist/app.module.js
vendored
|
@ -8,39 +8,38 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AppModule = void 0;
|
||||
const abort_interceptor_1 = require("./common/interceptors/abort.interceptor");
|
||||
const custom_logger_service_1 = require("./common/logger/custom-logger.service");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const nestjs_config_1 = require("nestjs-config");
|
||||
const path_1 = require("path");
|
||||
const auth_module_1 = require("./modules/auth/auth.module");
|
||||
const chat_module_1 = require("./modules/chat/chat.module");
|
||||
const chatLog_module_1 = require("./modules/chatLog/chatLog.module");
|
||||
const crami_module_1 = require("./modules/crami/crami.module");
|
||||
const database_module_1 = require("./modules/database/database.module");
|
||||
const upload_module_1 = require("./modules/upload/upload.module");
|
||||
const user_module_1 = require("./modules/user/user.module");
|
||||
const userBalance_module_1 = require("./modules/userBalance/userBalance.module");
|
||||
const verification_module_1 = require("./modules/verification/verification.module");
|
||||
const app_module_1 = require("./modules/app/app.module");
|
||||
const autoreply_module_1 = require("./modules/autoreply/autoreply.module");
|
||||
const badwords_module_1 = require("./modules/badwords/badwords.module");
|
||||
const globalConfig_module_1 = require("./modules/globalConfig/globalConfig.module");
|
||||
const redisCache_module_1 = require("./modules/redisCache/redisCache.module");
|
||||
const statistic_module_1 = require("./modules/statistic/statistic.module");
|
||||
const order_module_1 = require("./modules/order/order.module");
|
||||
const pay_module_1 = require("./modules/pay/pay.module");
|
||||
const core_1 = require("@nestjs/core");
|
||||
const serve_static_1 = require("@nestjs/serve-static");
|
||||
const fetch = require("isomorphic-fetch");
|
||||
const path_2 = require("path");
|
||||
const path_1 = require("path");
|
||||
const app_module_1 = require("./modules/app/app.module");
|
||||
const auth_module_1 = require("./modules/auth/auth.module");
|
||||
const autoreply_module_1 = require("./modules/autoreply/autoreply.module");
|
||||
const badwords_module_1 = require("./modules/badwords/badwords.module");
|
||||
const chat_module_1 = require("./modules/chat/chat.module");
|
||||
const chatGroup_module_1 = require("./modules/chatGroup/chatGroup.module");
|
||||
const chatLog_module_1 = require("./modules/chatLog/chatLog.module");
|
||||
const crami_module_1 = require("./modules/crami/crami.module");
|
||||
const database_module_1 = require("./modules/database/database.module");
|
||||
const globalConfig_module_1 = require("./modules/globalConfig/globalConfig.module");
|
||||
const menu_module_1 = require("./modules/menu/menu.module");
|
||||
const midjourney_module_1 = require("./modules/midjourney/midjourney.module");
|
||||
const models_module_1 = require("./modules/models/models.module");
|
||||
const official_module_1 = require("./modules/official/official.module");
|
||||
const queue_module_1 = require("./modules/queue/queue.module");
|
||||
const order_module_1 = require("./modules/order/order.module");
|
||||
const pay_module_1 = require("./modules/pay/pay.module");
|
||||
const plugin_module_1 = require("./modules/plugin/plugin.module");
|
||||
const redisCache_module_1 = require("./modules/redisCache/redisCache.module");
|
||||
const sales_module_1 = require("./modules/sales/sales.module");
|
||||
const signin_module_1 = require("./modules/signin/signin.module");
|
||||
const statistic_module_1 = require("./modules/statistic/statistic.module");
|
||||
const task_module_1 = require("./modules/task/task.module");
|
||||
const upload_module_1 = require("./modules/upload/upload.module");
|
||||
const user_module_1 = require("./modules/user/user.module");
|
||||
const userBalance_module_1 = require("./modules/userBalance/userBalance.module");
|
||||
const verification_module_1 = require("./modules/verification/verification.module");
|
||||
global.fetch = fetch;
|
||||
let AppModule = class AppModule {
|
||||
};
|
||||
|
@ -48,12 +47,12 @@ AppModule = __decorate([
|
|||
(0, common_1.Global)(),
|
||||
(0, common_1.Module)({
|
||||
imports: [
|
||||
serve_static_1.ServeStaticModule.forRoot({
|
||||
rootPath: (0, path_2.join)(__dirname, '..', 'public'),
|
||||
}),
|
||||
nestjs_config_1.ConfigModule.load((0, path_1.resolve)(__dirname, 'config', '**/!(*.d).{ts,js}')),
|
||||
database_module_1.DatabaseModule,
|
||||
serve_static_1.ServeStaticModule.forRoot({
|
||||
rootPath: (0, path_1.join)(__dirname, '..', 'public'),
|
||||
}),
|
||||
user_module_1.UserModule,
|
||||
plugin_module_1.PluginModule,
|
||||
auth_module_1.AuthModule,
|
||||
verification_module_1.VerificationModule,
|
||||
chat_module_1.ChatModule,
|
||||
|
@ -71,7 +70,6 @@ AppModule = __decorate([
|
|||
order_module_1.OrderModule,
|
||||
official_module_1.OfficialModule,
|
||||
task_module_1.TaskModule,
|
||||
queue_module_1.QueueModule,
|
||||
midjourney_module_1.MidjourneyModule,
|
||||
chatGroup_module_1.ChatGroupModule,
|
||||
sales_module_1.SalesModule,
|
||||
|
@ -84,7 +82,9 @@ AppModule = __decorate([
|
|||
provide: core_1.APP_INTERCEPTOR,
|
||||
useClass: abort_interceptor_1.AbortInterceptor,
|
||||
},
|
||||
custom_logger_service_1.CustomLoggerService,
|
||||
],
|
||||
exports: [custom_logger_service_1.CustomLoggerService],
|
||||
})
|
||||
], AppModule);
|
||||
exports.AppModule = AppModule;
|
||||
|
|
14
dist/common/auth/jwt.strategy.js
vendored
14
dist/common/auth/jwt.strategy.js
vendored
|
@ -10,17 +10,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.JwtStrategy = void 0;
|
||||
const nestjs_config_1 = require("nestjs-config");
|
||||
const passport_jwt_1 = require("passport-jwt");
|
||||
const passport_1 = require("@nestjs/passport");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const passport_1 = require("@nestjs/passport");
|
||||
const passport_jwt_1 = require("passport-jwt");
|
||||
const redisCache_service_1 = require("../../modules/redisCache/redisCache.service");
|
||||
let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(passport_jwt_1.Strategy) {
|
||||
constructor(configService) {
|
||||
constructor(redisService) {
|
||||
super({
|
||||
jwtFromRequest: passport_jwt_1.ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
secretOrKey: configService.get('jwt').secret,
|
||||
secretOrKey: redisService.getJwtSecret(),
|
||||
});
|
||||
this.configService = configService;
|
||||
this.redisService = redisService;
|
||||
}
|
||||
async validate(payload) {
|
||||
return payload;
|
||||
|
@ -28,6 +28,6 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|||
};
|
||||
JwtStrategy = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [nestjs_config_1.ConfigService])
|
||||
__metadata("design:paramtypes", [redisCache_service_1.RedisCacheService])
|
||||
], JwtStrategy);
|
||||
exports.JwtStrategy = JwtStrategy;
|
||||
|
|
17
dist/common/auth/jwtAuth.guard.js
vendored
17
dist/common/auth/jwtAuth.guard.js
vendored
|
@ -10,12 +10,12 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.JwtAuthGuard = void 0;
|
||||
const globalConfig_service_1 = require("../../modules/globalConfig/globalConfig.service");
|
||||
const redisCache_service_1 = require("../../modules/redisCache/redisCache.service");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const core_1 = require("@nestjs/core");
|
||||
const passport_1 = require("@nestjs/passport");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const core_1 = require("@nestjs/core");
|
||||
const globalConfig_service_1 = require("../../modules/globalConfig/globalConfig.service");
|
||||
const auth_service_1 = require("../../modules/auth/auth.service");
|
||||
let JwtAuthGuard = class JwtAuthGuard extends (0, passport_1.AuthGuard)('jwt') {
|
||||
constructor(redisCacheService, moduleRef, globalConfigService, authService) {
|
||||
|
@ -27,13 +27,14 @@ let JwtAuthGuard = class JwtAuthGuard extends (0, passport_1.AuthGuard)('jwt') {
|
|||
}
|
||||
async canActivate(context) {
|
||||
if (!this.redisCacheService) {
|
||||
this.redisCacheService = this.moduleRef.get(redisCache_service_1.RedisCacheService, { strict: false });
|
||||
this.redisCacheService = this.moduleRef.get(redisCache_service_1.RedisCacheService, {
|
||||
strict: false,
|
||||
});
|
||||
}
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const domain = request.headers['x-website-domain'];
|
||||
const token = this.extractToken(request);
|
||||
request.user = this.validateToken(token);
|
||||
const auth = this.globalConfigService.getNineAiToken();
|
||||
request.user = await this.validateToken(token);
|
||||
await this.redisCacheService.checkTokenAuth(token, request);
|
||||
return true;
|
||||
}
|
||||
|
@ -56,9 +57,11 @@ let JwtAuthGuard = class JwtAuthGuard extends (0, passport_1.AuthGuard)('jwt') {
|
|||
}
|
||||
return parts[1];
|
||||
}
|
||||
validateToken(token) {
|
||||
async validateToken(token) {
|
||||
try {
|
||||
return jwt.verify(token, process.env.JWT_SECRET);
|
||||
const secret = await this.redisCacheService.getJwtSecret();
|
||||
const decoded = await jwt.verify(token, secret);
|
||||
return decoded;
|
||||
}
|
||||
catch (error) {
|
||||
throw new common_1.HttpException('亲爱的用户,请登录后继续操作,我们正在等您的到来!', common_1.HttpStatus.UNAUTHORIZED);
|
||||
|
|
45
dist/common/logger/custom-logger.service.js
vendored
Normal file
45
dist/common/logger/custom-logger.service.js
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
"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.CustomLoggerService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
let CustomLoggerService = class CustomLoggerService extends common_1.ConsoleLogger {
|
||||
constructor() {
|
||||
super();
|
||||
this.isDev = process.env.ISDEV === 'TRUE';
|
||||
}
|
||||
log(message, context) {
|
||||
super.log(message, context);
|
||||
}
|
||||
error(message, trace, context) {
|
||||
super.error(message, trace, context);
|
||||
}
|
||||
warn(message, context) {
|
||||
if (this.isDev) {
|
||||
super.warn(message, context);
|
||||
}
|
||||
}
|
||||
debug(message, context) {
|
||||
if (this.isDev) {
|
||||
super.debug(message, context);
|
||||
}
|
||||
}
|
||||
verbose(message, context) {
|
||||
if (this.isDev) {
|
||||
super.verbose(message, context);
|
||||
}
|
||||
}
|
||||
};
|
||||
CustomLoggerService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [])
|
||||
], CustomLoggerService);
|
||||
exports.CustomLoggerService = CustomLoggerService;
|
6
dist/common/swagger/index.js
vendored
6
dist/common/swagger/index.js
vendored
|
@ -3,13 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.createSwagger = void 0;
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const swaggerOptions = new swagger_1.DocumentBuilder()
|
||||
.setTitle('Nine Team api document')
|
||||
.setDescription('Nine Team api document')
|
||||
.setTitle('AIWeb Team api document')
|
||||
.setDescription('AIWeb Team api document')
|
||||
.setVersion('1.0.0')
|
||||
.addBearerAuth()
|
||||
.build();
|
||||
function createSwagger(app) {
|
||||
const document = swagger_1.SwaggerModule.createDocument(app, swaggerOptions);
|
||||
swagger_1.SwaggerModule.setup('/nineai/swagger/docs', app, document);
|
||||
swagger_1.SwaggerModule.setup('/swagger/docs', app, document);
|
||||
}
|
||||
exports.createSwagger = createSwagger;
|
||||
|
|
41
dist/common/utils/compileNetwork.js
vendored
41
dist/common/utils/compileNetwork.js
vendored
|
@ -1,41 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.compileNetwork = void 0;
|
||||
const axios_1 = require("axios");
|
||||
function formatSearchData(searchData, question) {
|
||||
const formatStr = searchData.results.map(({ title, body, href }) => `'${title}' : ${body} ; (${href})`).join('\n\n');
|
||||
const currentDate = new Date().toISOString().split('T')[0];
|
||||
const instructions = '你的任务是优先利用网络搜索结果来回答问题,并使用提问时的语言风格进行回复。你应该提供一个全面而有条理的回答,在每条答案后面明确指出来源于哪个链接,使用 [[数字](链接)] 格式进行标注。以下是搜索结果:';
|
||||
return `${instructions}\n今天是${currentDate}\n${formatStr}`;
|
||||
}
|
||||
async function compileNetwork(question) {
|
||||
const currentDate = new Date().toISOString().split('T')[0];
|
||||
console.log(`Current date: ${currentDate}`);
|
||||
console.log(`开始对问题“${question}”进行网络编译`);
|
||||
const datedQuestion = `${currentDate} ${question}`;
|
||||
let searchData = { results: [] };
|
||||
try {
|
||||
const url = ``;
|
||||
console.log(`正在向搜索API发送请求,URL为:${url}`);
|
||||
const responseData = await axios_1.default.get(url);
|
||||
searchData = responseData.data;
|
||||
console.log(`已成功接收问题“${question}”的搜索结果,结果数量:${searchData.results.length}`);
|
||||
searchData.results.forEach((result, index) => {
|
||||
console.log(`结果 ${index + 1}: 标题: ${result.title}, 链接: ${result.href}, 摘要: ${result.body.substring(0, 100)}...`);
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.log(`在对问题“${question}”进行网络编译时出错:`, error);
|
||||
}
|
||||
let formattedData = "";
|
||||
if (searchData.results.length === 0) {
|
||||
console.log(`未找到问题“${question}”的搜索结果,将返回原问题`);
|
||||
return question;
|
||||
}
|
||||
else {
|
||||
formattedData = formatSearchData(searchData, question);
|
||||
console.log(`格式化后的搜索结果为:\n${formattedData}`);
|
||||
return formattedData;
|
||||
}
|
||||
}
|
||||
exports.compileNetwork = compileNetwork;
|
11
dist/common/utils/fromatUrl.js
vendored
Normal file
11
dist/common/utils/fromatUrl.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.formatUrl = void 0;
|
||||
function formatUrl(url) {
|
||||
let formattedUrl = url.replace(/\s+/g, '');
|
||||
if (formattedUrl.endsWith('/')) {
|
||||
formattedUrl = formattedUrl.slice(0, -1);
|
||||
}
|
||||
return formattedUrl;
|
||||
}
|
||||
exports.formatUrl = formatUrl;
|
47
dist/common/utils/getClientIp.js
vendored
47
dist/common/utils/getClientIp.js
vendored
|
@ -1,43 +1,22 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getClientIp = void 0;
|
||||
function getClientIp(request) {
|
||||
let ipAddress = '';
|
||||
const headerList = [
|
||||
'X-Client-IP',
|
||||
'X-Real-IP',
|
||||
'X-Forwarded-For',
|
||||
'CF-Connecting-IP',
|
||||
'True-Client-IP',
|
||||
'X-Cluster-Client-IP',
|
||||
'Proxy-Client-IP',
|
||||
'WL-Proxy-Client-IP',
|
||||
'HTTP_CLIENT_IP',
|
||||
'HTTP_X_FORWARDED_FOR',
|
||||
];
|
||||
for (const header of headerList) {
|
||||
const value = request.headers[header];
|
||||
if (value && typeof value === 'string') {
|
||||
const ips = value.split(',');
|
||||
ipAddress = ips[0].trim();
|
||||
break;
|
||||
function getFirstValidIp(ipString) {
|
||||
const ips = ipString.split(',').map(ip => ip.trim());
|
||||
return ips.find(ip => isValidIp(ip)) || '';
|
||||
}
|
||||
function isValidIp(ip) {
|
||||
return /^\d{1,3}(\.\d{1,3}){3}$/.test(ip) || /^::ffff:\d{1,3}(\.\d{1,3}){3}$/.test(ip);
|
||||
}
|
||||
if (!ipAddress) {
|
||||
ipAddress = request.connection.remoteAddress || '';
|
||||
function getClientIp(req) {
|
||||
const forwardedFor = req.header('x-forwarded-for');
|
||||
let clientIp = forwardedFor ? getFirstValidIp(forwardedFor) : '';
|
||||
if (!clientIp) {
|
||||
clientIp = req.connection.remoteAddress || req.socket.remoteAddress || '';
|
||||
}
|
||||
if (ipAddress && ipAddress.includes('::')) {
|
||||
const isLocal = /^(::1|fe80(:1)?::1(%.*)?)$/i.test(ipAddress);
|
||||
if (isLocal) {
|
||||
ipAddress = '';
|
||||
if (clientIp.startsWith('::ffff:')) {
|
||||
clientIp = clientIp.substring(7);
|
||||
}
|
||||
else if (ipAddress.includes('::ffff:')) {
|
||||
ipAddress = ipAddress.split(':').pop() || '';
|
||||
}
|
||||
}
|
||||
if (!ipAddress || !/\d+\.\d+\.\d+\.\d+/.test(ipAddress)) {
|
||||
ipAddress = '';
|
||||
}
|
||||
return ipAddress;
|
||||
return clientIp;
|
||||
}
|
||||
exports.getClientIp = getClientIp;
|
||||
|
|
31
dist/common/utils/getTokenCount.js
vendored
Normal file
31
dist/common/utils/getTokenCount.js
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getTokenCount = void 0;
|
||||
const tiktoken_1 = require("@dqbd/tiktoken");
|
||||
const getTokenCount = async (input) => {
|
||||
let text = '';
|
||||
if (Array.isArray(input)) {
|
||||
text = input.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 || '');
|
||||
}
|
||||
}, '');
|
||||
}
|
||||
else if (typeof input === 'string') {
|
||||
text = input;
|
||||
}
|
||||
else if (input) {
|
||||
text = String(input);
|
||||
}
|
||||
text = text.replace(/<\|endoftext\|>/g, '');
|
||||
const tokenizer = (0, tiktoken_1.get_encoding)('cl100k_base');
|
||||
return tokenizer.encode(text).length;
|
||||
};
|
||||
exports.getTokenCount = getTokenCount;
|
43
dist/common/utils/handleError.js
vendored
Normal file
43
dist/common/utils/handleError.js
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.handleError = void 0;
|
||||
const axios_1 = require("axios");
|
||||
function handleError(error) {
|
||||
let message = '发生未知错误,请稍后再试';
|
||||
if (axios_1.default.isAxiosError(error) && error.response) {
|
||||
switch (error.response.status) {
|
||||
case 400:
|
||||
message =
|
||||
'发生错误:400 Bad Request - 请求因格式错误无法被服务器处理。';
|
||||
break;
|
||||
case 401:
|
||||
message = '发生错误:401 Unauthorized - 请求要求进行身份验证。';
|
||||
break;
|
||||
case 403:
|
||||
message = '发生错误:403 Forbidden - 服务器拒绝执行请求。';
|
||||
break;
|
||||
case 404:
|
||||
message = '发生错误:404 Not Found - 请求的资源无法在服务器上找到。';
|
||||
break;
|
||||
case 500:
|
||||
message =
|
||||
'发生错误:500 Internal Server Error - 服务器内部错误,无法完成请求。';
|
||||
break;
|
||||
case 502:
|
||||
message =
|
||||
'发生错误:502 Bad Gateway - 作为网关或代理工作的服务器从上游服务器收到无效响应。';
|
||||
break;
|
||||
case 503:
|
||||
message =
|
||||
'发生错误:503 Service Unavailable - 服务器暂时处于超负载或维护状态,无法处理请求。';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
message = error.message || message;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
exports.handleError = handleError;
|
37
dist/common/utils/index.js
vendored
37
dist/common/utils/index.js
vendored
|
@ -14,25 +14,26 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./date"), exports);
|
||||
__exportStar(require("./createRandomCode"), exports);
|
||||
__exportStar(require("./tools"), exports);
|
||||
__exportStar(require("./createRandomInviteCode"), exports);
|
||||
__exportStar(require("./maskEmail"), exports);
|
||||
__exportStar(require("./createRandomUid"), exports);
|
||||
__exportStar(require("./generateCrami"), exports);
|
||||
__exportStar(require("./base"), exports);
|
||||
__exportStar(require("./hideString"), exports);
|
||||
__exportStar(require("./createOrderId"), exports);
|
||||
__exportStar(require("./createRandomCode"), exports);
|
||||
__exportStar(require("./createRandomInviteCode"), exports);
|
||||
__exportStar(require("./createRandomNonceStr"), exports);
|
||||
__exportStar(require("./createRandomUid"), exports);
|
||||
__exportStar(require("./date"), exports);
|
||||
__exportStar(require("./encrypt"), exports);
|
||||
__exportStar(require("./fromatUrl"), exports);
|
||||
__exportStar(require("./generateCrami"), exports);
|
||||
__exportStar(require("./getClientIp"), exports);
|
||||
__exportStar(require("./getDiffArray"), exports);
|
||||
__exportStar(require("./getRandomItem"), exports);
|
||||
__exportStar(require("./getClientIp"), exports);
|
||||
__exportStar(require("./maskIpAddress"), exports);
|
||||
__exportStar(require("./maskCrami"), exports);
|
||||
__exportStar(require("./selectKeyWithWeight"), exports);
|
||||
__exportStar(require("./createOrderId"), exports);
|
||||
__exportStar(require("./createRandomNonceStr"), exports);
|
||||
__exportStar(require("./utcformatTime"), exports);
|
||||
__exportStar(require("./removeSpecialCharacters"), exports);
|
||||
__exportStar(require("./encrypt"), exports);
|
||||
__exportStar(require("./compileNetwork"), exports);
|
||||
__exportStar(require("./getRandomItemFromArray"), exports);
|
||||
__exportStar(require("./getTokenCount"), exports);
|
||||
__exportStar(require("./handleError"), exports);
|
||||
__exportStar(require("./hideString"), exports);
|
||||
__exportStar(require("./maskCrami"), exports);
|
||||
__exportStar(require("./maskEmail"), exports);
|
||||
__exportStar(require("./maskIpAddress"), exports);
|
||||
__exportStar(require("./removeSpecialCharacters"), exports);
|
||||
__exportStar(require("./tools"), exports);
|
||||
__exportStar(require("./utcformatTime"), exports);
|
||||
|
|
17
dist/common/utils/selectKeyWithWeight.js
vendored
17
dist/common/utils/selectKeyWithWeight.js
vendored
|
@ -1,17 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.selectKeyWithWeight = void 0;
|
||||
function selectKeyWithWeight(data) {
|
||||
if (data.length === 0)
|
||||
return undefined;
|
||||
const totalWeight = data.reduce((sum, item) => sum + item.weight, 0);
|
||||
let randomWeight = Math.random() * totalWeight;
|
||||
for (const item of data) {
|
||||
randomWeight -= item.weight;
|
||||
if (randomWeight < 0) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return data[data.length - 1];
|
||||
}
|
||||
exports.selectKeyWithWeight = selectKeyWithWeight;
|
11
dist/config/cos.js
vendored
11
dist/config/cos.js
vendored
|
@ -1,11 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Dotenv = require("dotenv");
|
||||
Dotenv.config({ path: '.env' });
|
||||
const config = {
|
||||
SecretId: process.env.TENTCENT_SECRET_ID,
|
||||
SecretKey: process.env.TENTCENT_SECRET_KEY,
|
||||
Bucket: process.env.COS_BUCKET_PUBLIC,
|
||||
Region: process.env.COS_REGION,
|
||||
};
|
||||
exports.default = config;
|
16
dist/config/database.js
vendored
16
dist/config/database.js
vendored
|
@ -1,16 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const config = {
|
||||
type: 'mysql',
|
||||
port: parseInt(process.env.DB_PORT),
|
||||
host: process.env.DB_HOST,
|
||||
username: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_DATABASE,
|
||||
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
|
||||
logging: false,
|
||||
synchronize: true,
|
||||
charset: 'utf8mb4',
|
||||
timezone: '+08:00',
|
||||
};
|
||||
exports.default = config;
|
9
dist/config/jwt.js
vendored
9
dist/config/jwt.js
vendored
|
@ -1,9 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const config = {
|
||||
secret: process.env.JWT_SECRET,
|
||||
signOptions: {
|
||||
expiresIn: process.env.JWT_EXPIRESIN || '7d',
|
||||
},
|
||||
};
|
||||
exports.default = config;
|
9
dist/config/main.js
vendored
9
dist/config/main.js
vendored
|
@ -1,9 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.APIPREFIX = exports.SWAGGERPREFIX = exports.PORT = void 0;
|
||||
const PORT = process.env.PORT || 3000;
|
||||
exports.PORT = PORT;
|
||||
const SWAGGERPREFIX = process.env.SWAGGERPREFIX || '/docs';
|
||||
exports.SWAGGERPREFIX = SWAGGERPREFIX;
|
||||
const APIPREFIX = process.env.APIPREFIX || '/api';
|
||||
exports.APIPREFIX = APIPREFIX;
|
9
dist/config/redis.js
vendored
9
dist/config/redis.js
vendored
|
@ -1,9 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const config = {
|
||||
port: parseInt(process.env.REDIS_PORT),
|
||||
host: process.env.REDIS_HOST,
|
||||
password: process.env.REDIS_PASSWORD,
|
||||
username: process.env.REDIS_USER,
|
||||
};
|
||||
exports.default = config;
|
2
dist/interfaces/mail.interface.js
vendored
2
dist/interfaces/mail.interface.js
vendored
|
@ -1,2 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
38
dist/main.js
vendored
38
dist/main.js
vendored
|
@ -1,36 +1,50 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Dotenv = require("dotenv");
|
||||
Dotenv.config({ path: '.env' });
|
||||
const core_1 = require("@nestjs/core");
|
||||
const app_module_1 = require("./app.module");
|
||||
const swagger_1 = require("./common/swagger");
|
||||
const allExceptions_filter_1 = require("./common/filters/allExceptions.filter");
|
||||
const typeOrmQueryFailed_filter_1 = require("./common/filters/typeOrmQueryFailed.filter");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const transform_interceptor_1 = require("./common/interceptors/transform.interceptor");
|
||||
const main_1 = require("./config/main");
|
||||
const custom_logger_service_1 = require("./common/logger/custom-logger.service");
|
||||
const initDatabase_1 = require("./modules/database/initDatabase");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const core_1 = require("@nestjs/core");
|
||||
const compression = require("compression");
|
||||
const crypto_1 = require("crypto");
|
||||
const Dotenv = require("dotenv");
|
||||
const xmlBodyParser = require("express-xml-bodyparser");
|
||||
const ioredis_1 = require("ioredis");
|
||||
const path_1 = require("path");
|
||||
const app_module_1 = require("./app.module");
|
||||
Dotenv.config({ path: '.env' });
|
||||
async function bootstrap() {
|
||||
await (0, initDatabase_1.initDatabase)();
|
||||
const redis = new ioredis_1.default({
|
||||
host: process.env.REDIS_HOST,
|
||||
port: Number(process.env.REDIS_PORT),
|
||||
password: process.env.REDIS_PASSWORD,
|
||||
db: Number(process.env.REDIS_DB || 0),
|
||||
});
|
||||
const existingSecret = await redis.get('JWT_SECRET');
|
||||
if (!existingSecret) {
|
||||
const jwtSecret = (0, crypto_1.randomBytes)(256).toString('base64');
|
||||
common_1.Logger.log('Generating and setting new JWT_SECRET');
|
||||
await redis.set('JWT_SECRET', jwtSecret);
|
||||
}
|
||||
const app = await core_1.NestFactory.create(app_module_1.AppModule);
|
||||
await (0, initDatabase_1.initDatabase)();
|
||||
app.useLogger(app.get(custom_logger_service_1.CustomLoggerService));
|
||||
app.use(compression());
|
||||
const www = (0, path_1.resolve)(__dirname, './public');
|
||||
app.use(xmlBodyParser());
|
||||
app.enableCors();
|
||||
app.setGlobalPrefix(main_1.APIPREFIX);
|
||||
app.setGlobalPrefix('/api');
|
||||
app.useGlobalInterceptors(new transform_interceptor_1.TransformInterceptor());
|
||||
app.useGlobalFilters(new typeOrmQueryFailed_filter_1.TypeOrmQueryFailedFilter());
|
||||
app.useGlobalFilters(new allExceptions_filter_1.AllExceptionsFilter());
|
||||
app.useGlobalPipes(new common_1.ValidationPipe());
|
||||
app.getHttpAdapter().getInstance().set('views', 'templates/pages');
|
||||
app.getHttpAdapter().getInstance().set('view engine', 'hbs');
|
||||
(0, swagger_1.createSwagger)(app);
|
||||
const server = await app.listen(main_1.PORT, () => {
|
||||
common_1.Logger.log(`服务启动成功: http://localhost:${main_1.PORT}/nineai/swagger/docs`, 'Main');
|
||||
const PORT = process.env.PORT || 3000;
|
||||
const server = await app.listen(PORT, () => {
|
||||
common_1.Logger.log(`服务启动成功: http://localhost:${PORT}`, 'Main');
|
||||
});
|
||||
server.timeout = 5 * 60 * 1000;
|
||||
}
|
||||
|
|
32
dist/modules/ai/azureTts.service.js
vendored
Normal file
32
dist/modules/ai/azureTts.service.js
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
"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 AzureTtsService_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AzureTtsService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const chatLog_service_1 = require("../chatLog/chatLog.service");
|
||||
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
|
||||
const upload_service_1 = require("../upload/upload.service");
|
||||
let AzureTtsService = AzureTtsService_1 = class AzureTtsService {
|
||||
constructor(uploadService, globalConfigService, chatLogService) {
|
||||
this.uploadService = uploadService;
|
||||
this.globalConfigService = globalConfigService;
|
||||
this.chatLogService = chatLogService;
|
||||
this.logger = new common_1.Logger(AzureTtsService_1.name);
|
||||
}
|
||||
};
|
||||
AzureTtsService = AzureTtsService_1 = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [upload_service_1.UploadService,
|
||||
globalConfig_service_1.GlobalConfigService,
|
||||
chatLog_service_1.ChatLogService])
|
||||
], AzureTtsService);
|
||||
exports.AzureTtsService = AzureTtsService;
|
185
dist/modules/ai/lumaVideo.service.js
vendored
Normal file
185
dist/modules/ai/lumaVideo.service.js
vendored
Normal file
|
@ -0,0 +1,185 @@
|
|||
"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.LumaVideoService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const axios_1 = require("axios");
|
||||
const chatLog_service_1 = require("../chatLog/chatLog.service");
|
||||
let LumaVideoService = class LumaVideoService {
|
||||
constructor(chatLogService) {
|
||||
this.chatLogService = chatLogService;
|
||||
}
|
||||
async lumaVideo(inputs) {
|
||||
var _a, _b, _c;
|
||||
const { apiKey, proxyUrl, fileInfo, prompt, timeout, assistantLogId, extraParam, } = inputs;
|
||||
let result = {
|
||||
text: '',
|
||||
fileInfo: '',
|
||||
taskId: '',
|
||||
taskData: '',
|
||||
status: 2,
|
||||
};
|
||||
let response = null;
|
||||
let url = '';
|
||||
let payloadJson = {};
|
||||
const headers = { Authorization: `Bearer ${apiKey}` };
|
||||
url = `${proxyUrl}/luma/generations/`;
|
||||
const aspectRatio = '16:9';
|
||||
payloadJson = {
|
||||
user_prompt: prompt,
|
||||
aspect_ratio: aspectRatio,
|
||||
expand_prompt: true,
|
||||
};
|
||||
common_1.Logger.log(`正在准备发送请求到 ${url},payload: ${JSON.stringify(payloadJson)}, headers: ${JSON.stringify(headers)}`, 'LumaService');
|
||||
try {
|
||||
response = await axios_1.default.post(url, payloadJson, { headers });
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`任务提交失败: ${error.message}`, 'LumaService');
|
||||
throw new Error('任务提交失败');
|
||||
}
|
||||
if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.id) {
|
||||
result.taskId = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.id;
|
||||
common_1.Logger.log(`任务提交成功, 任务ID: ${(_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.id}`, 'LumaService');
|
||||
}
|
||||
else {
|
||||
throw new Error('未能获取结果数据, 即将重试');
|
||||
}
|
||||
try {
|
||||
await this.pollLumaVideoResult({
|
||||
proxyUrl,
|
||||
apiKey,
|
||||
taskId: response.data.id,
|
||||
timeout,
|
||||
prompt,
|
||||
onSuccess: async (data) => {
|
||||
try {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||||
answer: (data === null || data === void 0 ? void 0 : data.answer) || prompt,
|
||||
progress: '100%',
|
||||
status: 3,
|
||||
taskId: data === null || data === void 0 ? void 0 : data.taskId,
|
||||
taskData: data === null || data === void 0 ? void 0 : data.taskData,
|
||||
});
|
||||
common_1.Logger.log('视频任务已完成', 'LumaService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'LumaService');
|
||||
}
|
||||
},
|
||||
onGenerating: async (data) => {
|
||||
try {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||||
answer: (data === null || data === void 0 ? void 0 : data.answer) || '视频生成中...',
|
||||
progress: data === null || data === void 0 ? void 0 : data.progress,
|
||||
status: data.status,
|
||||
});
|
||||
common_1.Logger.log('视频生成中...', 'LumaService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'LumaService');
|
||||
}
|
||||
},
|
||||
onFailure: async (data) => {
|
||||
try {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
answer: '视频生成失败',
|
||||
status: data.status,
|
||||
});
|
||||
common_1.Logger.log('生成失败', 'Lum aService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'LumaService');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error('查询生成结果时发生错误:', error.message, 'LumaService');
|
||||
throw new Error('查询生成结果时发生错误');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async pollLumaVideoResult(inputs) {
|
||||
const { proxyUrl, apiKey, taskId, timeout, onSuccess, onFailure, onGenerating, action, } = inputs;
|
||||
let result = {
|
||||
videoUrl: '',
|
||||
audioUrl: '',
|
||||
fileInfo: '',
|
||||
drawId: '',
|
||||
taskData: '',
|
||||
status: 2,
|
||||
progress: 0,
|
||||
answer: '',
|
||||
};
|
||||
const headers = { Authorization: `Bearer ${apiKey}` };
|
||||
const url = `${proxyUrl}/luma/generations/${taskId}`;
|
||||
const startTime = Date.now();
|
||||
const totalDuration = 300000;
|
||||
const POLL_INTERVAL = 5000;
|
||||
let retryCount = 0;
|
||||
try {
|
||||
while (Date.now() - startTime < timeout) {
|
||||
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
||||
try {
|
||||
const res = await axios_1.default.get(url, { headers });
|
||||
const interval = setInterval(() => {
|
||||
const elapsed = Date.now() - startTime;
|
||||
let percentage = Math.floor((elapsed / totalDuration) * 100);
|
||||
if (percentage >= 99)
|
||||
percentage = 99;
|
||||
result.answer = `视频生成中 (${percentage}%)`;
|
||||
}, 1000);
|
||||
const responses = res.data;
|
||||
common_1.Logger.debug(`轮询结果: ${JSON.stringify(responses)}`, 'LumaService');
|
||||
if (responses.state === 'completed') {
|
||||
result.taskId = responses.id;
|
||||
result.taskData = JSON.stringify(responses);
|
||||
result.fileInfo = responses.video.url;
|
||||
result.answer = `提示词: "${responses.prompt}"`;
|
||||
onSuccess(result);
|
||||
clearInterval(interval);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
onGenerating(result);
|
||||
}
|
||||
if (result.progress) {
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
retryCount++;
|
||||
common_1.Logger.error(`轮询失败,重试次数: ${retryCount}`, 'LumaService');
|
||||
}
|
||||
}
|
||||
common_1.Logger.error('轮询超时,请稍后再试!', 'LumaService');
|
||||
result.status = 4;
|
||||
onFailure(result);
|
||||
throw new Error('查询超时,请稍后再试!');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`轮询过程中发生错误: ${error}`, 'LumaService');
|
||||
result.status = 5;
|
||||
onFailure(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
LumaVideoService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [chatLog_service_1.ChatLogService])
|
||||
], LumaVideoService);
|
||||
exports.LumaVideoService = LumaVideoService;
|
211
dist/modules/ai/midjourneyDraw.service.js
vendored
Normal file
211
dist/modules/ai/midjourneyDraw.service.js
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
"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.MidjourneyService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const axios_1 = require("axios");
|
||||
const chatLog_service_1 = require("../chatLog/chatLog.service");
|
||||
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
|
||||
const upload_service_1 = require("../upload/upload.service");
|
||||
let MidjourneyService = class MidjourneyService {
|
||||
constructor(uploadService, globalConfigService, chatLogService) {
|
||||
this.uploadService = uploadService;
|
||||
this.globalConfigService = globalConfigService;
|
||||
this.chatLogService = chatLogService;
|
||||
}
|
||||
async midjourneyDraw(inputs) {
|
||||
var _a, _b;
|
||||
const { id, apiKey, proxyUrl, action, drawId, prompt, usePrompt, customId, timeout, assistantLogId, } = inputs;
|
||||
let result = {
|
||||
text: '',
|
||||
fileInfo: '',
|
||||
drawId: '',
|
||||
customId: '',
|
||||
status: 2,
|
||||
};
|
||||
let response;
|
||||
let retryCount = 0;
|
||||
let url = '';
|
||||
while (retryCount < 3) {
|
||||
let payloadJson = {};
|
||||
try {
|
||||
if (action === 'IMAGINE') {
|
||||
url = `${proxyUrl}/mj/submit/imagine`;
|
||||
payloadJson = { prompt: usePrompt };
|
||||
}
|
||||
else {
|
||||
url = `${proxyUrl}/mj/submit/action`;
|
||||
payloadJson = { taskId: drawId, customId: customId };
|
||||
}
|
||||
const headers = { 'mj-api-secret': apiKey };
|
||||
common_1.Logger.log(`正在准备发送请求到 ${url},payload: ${JSON.stringify(payloadJson)}, headers: ${JSON.stringify(headers)}`, 'MidjourneyService');
|
||||
response = await axios_1.default.post(url, payloadJson, { headers });
|
||||
if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.result) {
|
||||
result.drawId = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.result;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
throw new Error('未能获取结果数据, 即将重试');
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
retryCount++;
|
||||
if (retryCount >= 3) {
|
||||
common_1.Logger.log(`绘画任务提交失败, 请检查后台配置或者稍后重试! ${error}`, 'MidjourneyService');
|
||||
}
|
||||
}
|
||||
}
|
||||
this.pollMjDrawingResult({
|
||||
proxyUrl,
|
||||
apiKey,
|
||||
drawId: response.data.result,
|
||||
timeout,
|
||||
prompt,
|
||||
onSuccess: async (data) => {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||||
answer: (data === null || data === void 0 ? void 0 : data.answer) || prompt,
|
||||
progress: '100%',
|
||||
status: 3,
|
||||
drawId: data === null || data === void 0 ? void 0 : data.drawId,
|
||||
customId: data === null || data === void 0 ? void 0 : data.customId,
|
||||
});
|
||||
common_1.Logger.log('绘图成功!');
|
||||
},
|
||||
onDrawing: async (data) => {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
answer: (data === null || data === void 0 ? void 0 : data.answer) || '绘制中',
|
||||
progress: data === null || data === void 0 ? void 0 : data.progress,
|
||||
status: 2,
|
||||
});
|
||||
common_1.Logger.log(`绘制中!绘制进度${data === null || data === void 0 ? void 0 : data.progress}`);
|
||||
},
|
||||
onFailure: async (data) => {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
answer: '绘图失败',
|
||||
status: data.status,
|
||||
});
|
||||
common_1.Logger.log('绘图失败');
|
||||
},
|
||||
}).catch((error) => {
|
||||
common_1.Logger.error('查询绘图结果时发生错误:', error, 'MidjourneyService');
|
||||
});
|
||||
common_1.Logger.log(`绘画任务提交成功, 绘画ID: ${response.data.result}`, 'MidjourneyService');
|
||||
return result;
|
||||
}
|
||||
async pollMjDrawingResult(inputs) {
|
||||
const { proxyUrl, apiKey, drawId, timeout, onSuccess, prompt, onFailure, onDrawing, } = inputs;
|
||||
const { mjNotSaveImg, mjProxyImgUrl, mjNotUseProxy } = await this.globalConfigService.getConfigs([
|
||||
'mjNotSaveImg',
|
||||
'mjProxyImgUrl',
|
||||
'mjNotUseProxy',
|
||||
]);
|
||||
let response;
|
||||
let result = {
|
||||
fileInfo: '',
|
||||
drawId: '',
|
||||
customId: '',
|
||||
status: 2,
|
||||
progress: 0,
|
||||
answer: '',
|
||||
};
|
||||
let payloadJson = {};
|
||||
const startTime = Date.now();
|
||||
const POLL_INTERVAL = 5000;
|
||||
let retryCount = 0;
|
||||
let pollingCount = 0;
|
||||
try {
|
||||
while (Date.now() - startTime < timeout) {
|
||||
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
||||
try {
|
||||
const headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'mj-api-secret': apiKey,
|
||||
};
|
||||
const url = `${proxyUrl}/mj/task/${drawId}/fetch`;
|
||||
const res = await axios_1.default.get(url, { headers });
|
||||
const responses = res.data;
|
||||
if (responses.status === 'SUCCESS') {
|
||||
common_1.Logger.log(`绘制成功, 获取到的URL: ${responses.imageUrl}`, 'MidjourneyService');
|
||||
let processedUrl = responses.imageUrl;
|
||||
const shouldReplaceUrl = mjNotUseProxy === '0' && mjProxyImgUrl;
|
||||
let logMessage = '';
|
||||
if (shouldReplaceUrl) {
|
||||
const newUrlBase = new URL(mjProxyImgUrl);
|
||||
const parsedUrl = new URL(responses.imageUrl);
|
||||
parsedUrl.protocol = newUrlBase.protocol;
|
||||
parsedUrl.hostname = newUrlBase.hostname;
|
||||
parsedUrl.port = newUrlBase.port ? newUrlBase.port : '';
|
||||
processedUrl = parsedUrl.toString();
|
||||
logMessage = `使用代理替换后的 URL: ${processedUrl}`;
|
||||
common_1.Logger.log(logMessage, 'MidjourneyService');
|
||||
}
|
||||
if (mjNotSaveImg !== '1') {
|
||||
try {
|
||||
common_1.Logger.log(`------> 开始上传图片!!!`);
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const currentDate = `${year}${month}/${day}`;
|
||||
processedUrl = await this.uploadService.uploadFileFromUrl({
|
||||
url: processedUrl,
|
||||
dir: `images/midjourney/${currentDate}`,
|
||||
});
|
||||
logMessage = `上传成功 URL: ${processedUrl}`;
|
||||
}
|
||||
catch (uploadError) {
|
||||
common_1.Logger.error('存储图片失败,使用原始/代理图片链接');
|
||||
logMessage = `存储图片失败,使用原始/代理图片链接 ${processedUrl}`;
|
||||
}
|
||||
common_1.Logger.log(logMessage, 'MidjourneyService');
|
||||
}
|
||||
else {
|
||||
logMessage = `不保存图片,使用 URL: ${processedUrl}`;
|
||||
common_1.Logger.log(logMessage, 'MidjourneyService');
|
||||
}
|
||||
result.fileInfo = processedUrl;
|
||||
result.drawId = responses.id;
|
||||
result.customId = JSON.stringify(responses.buttons);
|
||||
result.answer = `${prompt}\n${responses.finalPrompt || responses.properties.finalPrompt || ''}`;
|
||||
onSuccess(result);
|
||||
return;
|
||||
}
|
||||
result.progress = responses === null || responses === void 0 ? void 0 : responses.progress;
|
||||
result.answer = `当前绘制进度 ${responses === null || responses === void 0 ? void 0 : responses.progress}`;
|
||||
if (result.progress) {
|
||||
onDrawing(result);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
retryCount++;
|
||||
common_1.Logger.error(`轮询过程中发生错误: ${error}`, 'MidjourneyService');
|
||||
}
|
||||
}
|
||||
common_1.Logger.error(`超过 ${startTime / 1000} s 未完成绘画, 请稍后再试! MidjourneyService`);
|
||||
result.status = 4;
|
||||
onFailure(result);
|
||||
throw new common_1.HttpException('绘画超时,请稍后再试!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`绘画失败: ${error} MidjourneyService`);
|
||||
result.status = 5;
|
||||
onFailure(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
MidjourneyService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [upload_service_1.UploadService,
|
||||
globalConfig_service_1.GlobalConfigService,
|
||||
chatLog_service_1.ChatLogService])
|
||||
], MidjourneyService);
|
||||
exports.MidjourneyService = MidjourneyService;
|
145
dist/modules/ai/openaiChat.service.js
vendored
Normal file
145
dist/modules/ai/openaiChat.service.js
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
"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.OpenAIChatService = void 0;
|
||||
const utils_1 = require("../../common/utils");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const axios_1 = require("axios");
|
||||
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
|
||||
let OpenAIChatService = class OpenAIChatService {
|
||||
constructor(globalConfigService) {
|
||||
this.globalConfigService = globalConfigService;
|
||||
}
|
||||
async openAIChat(messagesHistory, inputs) {
|
||||
const { onFailure, onProgress, apiKey, model, proxyUrl, modelName, timeout, chatId, isFileUpload, modelAvatar, temperature, abortController, } = inputs;
|
||||
let result = {
|
||||
text: '',
|
||||
model: '',
|
||||
modelName: modelName,
|
||||
chatId: chatId,
|
||||
answer: '',
|
||||
errMsg: '',
|
||||
modelAvatar: modelAvatar,
|
||||
};
|
||||
const options = {
|
||||
method: 'POST',
|
||||
url: `${proxyUrl}/v1/chat/completions`,
|
||||
responseType: 'stream',
|
||||
timeout: timeout,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
data: Object.assign({ stream: true, model, temperature: temperature, messages: messagesHistory }, (isFileUpload === 2 && { max_tokens: 2048 })),
|
||||
};
|
||||
console.log('请求配置:', JSON.stringify(options, null, 2), 'ChatService');
|
||||
try {
|
||||
const response = await (0, axios_1.default)(options);
|
||||
const stream = response.data;
|
||||
let buffer = '';
|
||||
await new Promise((resolve, reject) => {
|
||||
stream.on('data', (chunk) => {
|
||||
buffer += chunk.toString();
|
||||
let lines = buffer.split('\n');
|
||||
buffer = lines.pop();
|
||||
lines.forEach((line) => {
|
||||
var _a, _b;
|
||||
if (line.trim() === 'data: [DONE]') {
|
||||
console.log('处理结束信号 [DONE]');
|
||||
resolve(result);
|
||||
return;
|
||||
}
|
||||
if (line.startsWith('data: ')) {
|
||||
try {
|
||||
const cleanedLine = line.slice(6).trim();
|
||||
if (cleanedLine) {
|
||||
const jsonLine = JSON.parse(cleanedLine);
|
||||
const content = ((_b = (_a = jsonLine.choices[0]) === null || _a === void 0 ? void 0 : _a.delta) === null || _b === void 0 ? void 0 : _b.content) || '';
|
||||
result.answer += content;
|
||||
onProgress === null || onProgress === void 0 ? void 0 : onProgress({ text: content, answer: result.answer });
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Error parsing line:', line, error);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
stream.on('end', () => {
|
||||
resolve(result);
|
||||
});
|
||||
stream.on('error', (error) => {
|
||||
reject(error);
|
||||
});
|
||||
abortController.signal.addEventListener('abort', () => {
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
catch (error) {
|
||||
result.errMsg = (0, utils_1.handleError)(error);
|
||||
common_1.Logger.error(result.errMsg);
|
||||
onFailure(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
async chatFree(prompt, systemMessage, messagesHistory) {
|
||||
const { openaiBaseUrl = '', openaiBaseKey = '', openaiBaseModel, } = await this.globalConfigService.getConfigs([
|
||||
'openaiBaseKey',
|
||||
'openaiBaseUrl',
|
||||
'openaiBaseModel',
|
||||
]);
|
||||
const key = openaiBaseKey;
|
||||
const proxyUrl = openaiBaseUrl;
|
||||
let requestData = [];
|
||||
if (systemMessage) {
|
||||
requestData.push({
|
||||
role: 'system',
|
||||
content: systemMessage,
|
||||
});
|
||||
}
|
||||
if (messagesHistory && messagesHistory.length > 0) {
|
||||
requestData = requestData.concat(messagesHistory);
|
||||
}
|
||||
else {
|
||||
requestData.push({
|
||||
role: 'user',
|
||||
content: prompt,
|
||||
});
|
||||
}
|
||||
const options = {
|
||||
method: 'POST',
|
||||
url: `${proxyUrl}/v1/chat/completions`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${key}`,
|
||||
},
|
||||
data: {
|
||||
model: openaiBaseModel || 'gpt-3.5-turbo-0125',
|
||||
messages: requestData,
|
||||
},
|
||||
};
|
||||
try {
|
||||
const response = await (0, axios_1.default)(options);
|
||||
common_1.Logger.log(`全局模型调用成功, 返回结果: ${response === null || response === void 0 ? void 0 : response.data.choices[0].message.content}`, 'ChatService');
|
||||
return response === null || response === void 0 ? void 0 : response.data.choices[0].message.content;
|
||||
}
|
||||
catch (error) {
|
||||
console.log('error: ', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
OpenAIChatService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [globalConfig_service_1.GlobalConfigService])
|
||||
], OpenAIChatService);
|
||||
exports.OpenAIChatService = OpenAIChatService;
|
|
@ -8,69 +8,27 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var ApiDataService_1;
|
||||
var OpenAIDrawService_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ApiDataService = void 0;
|
||||
exports.OpenAIDrawService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const axios_1 = require("axios");
|
||||
const uuid = require("uuid");
|
||||
const chatLog_service_1 = require("../chatLog/chatLog.service");
|
||||
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
|
||||
const upload_service_1 = require("../upload/upload.service");
|
||||
let ApiDataService = ApiDataService_1 = class ApiDataService {
|
||||
constructor(uploadService, globalConfigService) {
|
||||
const openaiChat_service_1 = require("./openaiChat.service");
|
||||
let OpenAIDrawService = OpenAIDrawService_1 = class OpenAIDrawService {
|
||||
constructor(uploadService, globalConfigService, chatLogService, openAIChatService) {
|
||||
this.uploadService = uploadService;
|
||||
this.globalConfigService = globalConfigService;
|
||||
this.logger = new common_1.Logger(ApiDataService_1.name);
|
||||
}
|
||||
async chatFree(prompt, systemMessage, messagesHistory) {
|
||||
const { openaiBaseUrl = '', openaiBaseKey = '', openaiBaseModel, } = await this.globalConfigService.getConfigs([
|
||||
'openaiBaseKey',
|
||||
'openaiBaseUrl',
|
||||
'openaiBaseModel',
|
||||
]);
|
||||
const key = openaiBaseKey;
|
||||
const proxyUrl = openaiBaseUrl;
|
||||
let requestData = [];
|
||||
if (systemMessage) {
|
||||
requestData.push({
|
||||
"role": "system",
|
||||
"content": systemMessage
|
||||
});
|
||||
}
|
||||
if (messagesHistory && messagesHistory.length > 0) {
|
||||
requestData = requestData.concat(messagesHistory);
|
||||
}
|
||||
else {
|
||||
requestData.push({
|
||||
"role": "user",
|
||||
"content": prompt
|
||||
});
|
||||
}
|
||||
const options = {
|
||||
method: 'POST',
|
||||
url: `${proxyUrl}/v1/chat/completions`,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${key}`,
|
||||
},
|
||||
data: {
|
||||
model: openaiBaseModel || 'gpt-3.5-turbo-0125',
|
||||
messages: requestData,
|
||||
},
|
||||
};
|
||||
try {
|
||||
const response = await (0, axios_1.default)(options);
|
||||
common_1.Logger.log(`全局模型调用成功, 返回结果: ${response === null || response === void 0 ? void 0 : response.data.choices[0].message.content}`);
|
||||
return response === null || response === void 0 ? void 0 : response.data.choices[0].message.content;
|
||||
}
|
||||
catch (error) {
|
||||
console.log('error: ', error);
|
||||
}
|
||||
this.chatLogService = chatLogService;
|
||||
this.openAIChatService = openAIChatService;
|
||||
this.logger = new common_1.Logger(OpenAIDrawService_1.name);
|
||||
}
|
||||
async dalleDraw(inputs, messagesHistory) {
|
||||
var _a, _b, _c, _d;
|
||||
common_1.Logger.log('开始提交 Dalle 绘图任务 ', 'DrawService');
|
||||
const { apiKey, model, proxyUrl, prompt, extraParam, timeout, onSuccess, onFailure } = inputs;
|
||||
const { apiKey, model, proxyUrl, prompt, extraParam, timeout, onSuccess, onFailure, } = inputs;
|
||||
const size = (extraParam === null || extraParam === void 0 ? void 0 : extraParam.size) || '1024x1024';
|
||||
let result = { answer: '', fileInfo: '', status: 2 };
|
||||
try {
|
||||
|
@ -89,25 +47,30 @@ let ApiDataService = ApiDataService_1 = class ApiDataService {
|
|||
},
|
||||
};
|
||||
const response = await (0, axios_1.default)(options);
|
||||
common_1.Logger.debug(`请求成功${JSON.stringify(response.data.data[0])}`);
|
||||
common_1.Logger.debug(`请求状态${JSON.stringify(response.status)}`);
|
||||
const url = response.data.data[0].url;
|
||||
try {
|
||||
const filename = `${Date.now()}-${uuid.v4().slice(0, 4)}.png`;
|
||||
common_1.Logger.debug(`------> 开始上传图片!!!`, 'DrawService');
|
||||
result.fileInfo = await this.uploadService.uploadFileFromUrl({ filename, url: url });
|
||||
common_1.Logger.debug(`图片上传成功,URL: ${result.fileInfo}`, 'DrawService');
|
||||
common_1.Logger.log(`------> 开始上传图片!!!`, 'DrawService');
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const currentDate = `${year}${month}/${day}`;
|
||||
result.fileInfo = await this.uploadService.uploadFileFromUrl({
|
||||
url: url,
|
||||
dir: `images/dalle/${currentDate}`,
|
||||
});
|
||||
common_1.Logger.log(`图片上传成功,URL: ${result.fileInfo}`, 'DrawService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`上传图片过程中出现错误: ${error}`, 'DrawService');
|
||||
}
|
||||
let revised_prompt_cn;
|
||||
try {
|
||||
revised_prompt_cn = await this.chatFree(`根据提示词{${response.data.data[0].revised_prompt}}, 模拟AI绘画机器人的语气,用中文回复,告诉用户已经画好了`);
|
||||
revised_prompt_cn = await this.openAIChatService.chatFree(`根据提示词{${response.data.data[0].revised_prompt}}, 模拟AI绘画机器人的语气,用中文回复,告诉用户已经画好了`);
|
||||
}
|
||||
catch (error) {
|
||||
revised_prompt_cn = `${prompt} 绘制成功`;
|
||||
common_1.Logger.error("翻译失败: ", error);
|
||||
common_1.Logger.error('翻译失败: ', error);
|
||||
}
|
||||
result.answer = revised_prompt_cn;
|
||||
result.status = 3;
|
||||
|
@ -124,12 +87,15 @@ let ApiDataService = ApiDataService_1 = class ApiDataService {
|
|||
result.text = '当前请求已过载、请稍等会儿再试试吧!';
|
||||
return result;
|
||||
}
|
||||
if (status === 400 && message.includes('This request has been blocked by our content filters')) {
|
||||
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、尝试重新对话试试吧!';
|
||||
if (status === 400 &&
|
||||
message.includes('Billing hard limit has been reached')) {
|
||||
result.text =
|
||||
'当前模型key已被封禁、已冻结当前调用Key、尝试重新对话试试吧!';
|
||||
return result;
|
||||
}
|
||||
if (status === 500) {
|
||||
|
@ -145,9 +111,11 @@ let ApiDataService = ApiDataService_1 = class ApiDataService {
|
|||
}
|
||||
}
|
||||
};
|
||||
ApiDataService = ApiDataService_1 = __decorate([
|
||||
OpenAIDrawService = OpenAIDrawService_1 = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [upload_service_1.UploadService,
|
||||
globalConfig_service_1.GlobalConfigService])
|
||||
], ApiDataService);
|
||||
exports.ApiDataService = ApiDataService;
|
||||
globalConfig_service_1.GlobalConfigService,
|
||||
chatLog_service_1.ChatLogService,
|
||||
openaiChat_service_1.OpenAIChatService])
|
||||
], OpenAIDrawService);
|
||||
exports.OpenAIDrawService = OpenAIDrawService;
|
91
dist/modules/ai/stableDiffusion.service.js
vendored
Normal file
91
dist/modules/ai/stableDiffusion.service.js
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
"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 StableDiffusionService_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.StableDiffusionService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const axios_1 = require("axios");
|
||||
const chatLog_service_1 = require("../chatLog/chatLog.service");
|
||||
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
|
||||
const upload_service_1 = require("../upload/upload.service");
|
||||
let StableDiffusionService = StableDiffusionService_1 = class StableDiffusionService {
|
||||
constructor(uploadService, globalConfigService, chatLogService) {
|
||||
this.uploadService = uploadService;
|
||||
this.globalConfigService = globalConfigService;
|
||||
this.chatLogService = chatLogService;
|
||||
this.logger = new common_1.Logger(StableDiffusionService_1.name);
|
||||
}
|
||||
async sdxl(messagesHistory, inputs) {
|
||||
const { onGenerate, onSuccess, onFailure, apiKey, model, proxyUrl, modelName, timeout, chatId, isFileUpload, prompt, } = inputs;
|
||||
let result = {
|
||||
answer: '',
|
||||
model: model,
|
||||
modelName: modelName,
|
||||
chatId: chatId,
|
||||
fileInfo: '',
|
||||
status: 2,
|
||||
};
|
||||
console.log('开始处理', { model, modelName, prompt });
|
||||
const options = {
|
||||
method: 'POST',
|
||||
url: `${proxyUrl}/v1/chat/completions`,
|
||||
timeout: timeout,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
data: {
|
||||
model,
|
||||
messages: [{ role: 'user', content: prompt }],
|
||||
},
|
||||
};
|
||||
try {
|
||||
const response = await (0, axios_1.default)(options);
|
||||
console.log('API响应接收', response.data);
|
||||
if (response.data.choices && response.data.choices.length > 0) {
|
||||
const choice = response.data.choices[0];
|
||||
const content = choice.message.content;
|
||||
console.log('处理内容', content);
|
||||
const regex = /\]\((https?:\/\/[^\)]+)\)/;
|
||||
const match = content.match(regex);
|
||||
if (match && match[1]) {
|
||||
result.fileInfo = match[1];
|
||||
console.log('找到链接', match[1]);
|
||||
}
|
||||
else {
|
||||
console.log('没有找到链接');
|
||||
}
|
||||
let revised_prompt_cn;
|
||||
result.answer = `${prompt} 绘制成功`;
|
||||
if (result.fileInfo) {
|
||||
onSuccess(result);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
onFailure('No link found.');
|
||||
}
|
||||
}
|
||||
else {
|
||||
onFailure('No choices returned.');
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error('服务器错误,请求失败:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
StableDiffusionService = StableDiffusionService_1 = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [upload_service_1.UploadService,
|
||||
globalConfig_service_1.GlobalConfigService,
|
||||
chatLog_service_1.ChatLogService])
|
||||
], StableDiffusionService);
|
||||
exports.StableDiffusionService = StableDiffusionService;
|
247
dist/modules/ai/suno.service.js
vendored
Normal file
247
dist/modules/ai/suno.service.js
vendored
Normal file
|
@ -0,0 +1,247 @@
|
|||
"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.SunoService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const axios_1 = require("axios");
|
||||
const chatLog_service_1 = require("../chatLog/chatLog.service");
|
||||
let SunoService = class SunoService {
|
||||
constructor(chatLogService) {
|
||||
this.chatLogService = chatLogService;
|
||||
}
|
||||
async suno(inputs) {
|
||||
var _a, _b, _c;
|
||||
const { apiKey, proxyUrl, action, prompt, timeout, assistantLogId, taskData, extraParam, } = inputs;
|
||||
let result = {
|
||||
text: '',
|
||||
fileInfo: '',
|
||||
taskId: '',
|
||||
taskData: '',
|
||||
status: 2,
|
||||
};
|
||||
common_1.Logger.log('开始生成音乐', 'SunoService');
|
||||
let response = null;
|
||||
let url = '';
|
||||
let payloadJson = {};
|
||||
const headers = { Authorization: `Bearer ${apiKey}` };
|
||||
if (action === 'LYRICS') {
|
||||
url = `${proxyUrl}/task/suno/v1/submit/lyrics`;
|
||||
payloadJson = { prompt: prompt };
|
||||
}
|
||||
if (action === 'MUSIC') {
|
||||
url = `${proxyUrl}/task/suno/v1/submit/music`;
|
||||
try {
|
||||
payloadJson = JSON.parse(taskData);
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`解析taskData失败: ${error.message}`, 'SunoService');
|
||||
throw new Error('taskData格式错误');
|
||||
}
|
||||
}
|
||||
common_1.Logger.log(`正在准备发送请求到 ${url},payload: ${JSON.stringify(payloadJson)}, headers: ${JSON.stringify(headers)}`);
|
||||
try {
|
||||
response = await axios_1.default.post(url, payloadJson, { headers });
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`任务提交失败: ${error.message}`, 'SunoService');
|
||||
throw new Error('任务提交失败');
|
||||
}
|
||||
if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.data) {
|
||||
result.taskId = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.data;
|
||||
common_1.Logger.log(`任务提交成功, 任务ID: ${(_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.data}`, 'SunoService');
|
||||
}
|
||||
else {
|
||||
throw new Error('未能获取结果数据, 即将重试');
|
||||
}
|
||||
try {
|
||||
await this.pollSunoMusicResult({
|
||||
proxyUrl,
|
||||
apiKey,
|
||||
taskId: response.data.data,
|
||||
timeout,
|
||||
prompt,
|
||||
action,
|
||||
onSuccess: async (data) => {
|
||||
try {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||||
answer: (data === null || data === void 0 ? void 0 : data.answer) || prompt,
|
||||
progress: '100%',
|
||||
status: 3,
|
||||
taskId: data === null || data === void 0 ? void 0 : data.taskId,
|
||||
taskData: data === null || data === void 0 ? void 0 : data.taskData,
|
||||
});
|
||||
common_1.Logger.log('音乐任务已完成', 'SunoService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||||
}
|
||||
},
|
||||
onAudioSuccess: async (data) => {
|
||||
try {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||||
answer: (data === null || data === void 0 ? void 0 : data.answer) || prompt,
|
||||
progress: data === null || data === void 0 ? void 0 : data.progress,
|
||||
status: data.status,
|
||||
taskId: data === null || data === void 0 ? void 0 : data.taskId,
|
||||
taskData: data === null || data === void 0 ? void 0 : data.taskData,
|
||||
});
|
||||
common_1.Logger.log('音频生成成功,等待视频生成...', 'SunoService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||||
}
|
||||
},
|
||||
onGenerating: async (data) => {
|
||||
try {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
videoUrl: data === null || data === void 0 ? void 0 : data.videoUrl,
|
||||
audioUrl: data === null || data === void 0 ? void 0 : data.audioUrl,
|
||||
fileInfo: data === null || data === void 0 ? void 0 : data.fileInfo,
|
||||
answer: (data === null || data === void 0 ? void 0 : data.answer) || '音乐生成中...',
|
||||
progress: data === null || data === void 0 ? void 0 : data.progress,
|
||||
status: data.status,
|
||||
});
|
||||
common_1.Logger.log('音乐生成中...', 'SunoService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||||
}
|
||||
},
|
||||
onFailure: async (data) => {
|
||||
try {
|
||||
await this.chatLogService.updateChatLog(assistantLogId, {
|
||||
answer: '音乐生成失败',
|
||||
status: data.status,
|
||||
});
|
||||
common_1.Logger.log('生成失败', 'SunoService');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`更新日志失败: ${error.message}`, 'SunoService');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error('查询生成结果时发生错误:', error.message, 'SunoService');
|
||||
throw new Error('查询生成结果时发生错误');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async pollSunoMusicResult(inputs) {
|
||||
const { proxyUrl, apiKey, taskId, timeout, onSuccess, onAudioSuccess, onFailure, onGenerating, action, } = inputs;
|
||||
let result = {
|
||||
videoUrl: '',
|
||||
audioUrl: '',
|
||||
fileInfo: '',
|
||||
drawId: '',
|
||||
taskData: '',
|
||||
status: 2,
|
||||
progress: 0,
|
||||
answer: '',
|
||||
};
|
||||
const headers = { Authorization: `Bearer ${apiKey}` };
|
||||
const url = `${proxyUrl}/task/suno/v1/fetch/${taskId}`;
|
||||
const startTime = Date.now();
|
||||
const POLL_INTERVAL = 5000;
|
||||
let retryCount = 0;
|
||||
try {
|
||||
while (Date.now() - startTime < timeout) {
|
||||
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
||||
try {
|
||||
const res = await axios_1.default.get(url, { headers });
|
||||
const responses = res.data.data;
|
||||
if (action === 'LYRICS') {
|
||||
if (responses.status === 'SUCCESS') {
|
||||
result.taskId = responses.data.id;
|
||||
result.taskData = JSON.stringify(responses.data);
|
||||
result.answer = responses.data.text;
|
||||
onSuccess(result);
|
||||
return;
|
||||
}
|
||||
result.progress = responses === null || responses === void 0 ? void 0 : responses.progress;
|
||||
result.answer = `歌词生成中`;
|
||||
if (result.progress) {
|
||||
onGenerating(result);
|
||||
}
|
||||
}
|
||||
if (action === 'MUSIC') {
|
||||
const data = responses.data;
|
||||
if (responses.data) {
|
||||
const data = responses.data;
|
||||
result.taskData = JSON.stringify(data);
|
||||
if (Array.isArray(data)) {
|
||||
const validAudioUrls = data
|
||||
.map((item) => item.audio_url)
|
||||
.filter((url) => url);
|
||||
const validVideoUrls = data
|
||||
.map((item) => item.video_url)
|
||||
.filter((url) => url);
|
||||
const validImageUrls = data
|
||||
.map((item) => item.image_url)
|
||||
.filter((url) => url);
|
||||
const titles = data.map((item) => item.title);
|
||||
const firstTitle = titles.length > 0 ? titles[0] : '音乐已生成';
|
||||
const audioUrls = validAudioUrls.join(',');
|
||||
const videoUrls = validVideoUrls.join(',');
|
||||
const imageUrls = validImageUrls.join(',');
|
||||
result.audioUrl = audioUrls;
|
||||
result.videoUrl = videoUrls;
|
||||
result.fileInfo = imageUrls;
|
||||
if (validAudioUrls.length === 2) {
|
||||
result.status = 3;
|
||||
result.answer = firstTitle;
|
||||
}
|
||||
else {
|
||||
result.status = 2;
|
||||
result.progress = responses === null || responses === void 0 ? void 0 : responses.progress;
|
||||
result.answer = `当前生成进度 ${responses === null || responses === void 0 ? void 0 : responses.progress}`;
|
||||
}
|
||||
onAudioSuccess(result);
|
||||
}
|
||||
}
|
||||
if (responses.status === 'SUCCESS') {
|
||||
common_1.Logger.debug(`音乐生成成功: ${JSON.stringify(data)}`, 'SunoService');
|
||||
onSuccess(result);
|
||||
return;
|
||||
}
|
||||
if (result.progress && result.status === 2) {
|
||||
onGenerating(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
retryCount++;
|
||||
common_1.Logger.error(`轮询失败,重试次数: ${retryCount}`, 'SunoService');
|
||||
}
|
||||
}
|
||||
common_1.Logger.error('轮询超时,请稍后再试!', 'SunoService');
|
||||
result.status = 4;
|
||||
onFailure(result);
|
||||
throw new Error('查询超时,请稍后再试!');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`轮询过程中发生错误: ${error}`, 'SunoService');
|
||||
result.status = 5;
|
||||
onFailure(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
SunoService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [chatLog_service_1.ChatLogService])
|
||||
], SunoService);
|
||||
exports.SunoService = SunoService;
|
35
dist/modules/app/app.controller.js
vendored
35
dist/modules/app/app.controller.js
vendored
|
@ -13,22 +13,22 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AppController = void 0;
|
||||
const app_service_1 = require("./app.service");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const createCats_dto_1 = require("./dto/createCats.dto");
|
||||
const updateCats_dto_1 = require("./dto/updateCats.dto");
|
||||
const deleteCats_dto_1 = require("./dto/deleteCats.dto");
|
||||
const queryCats_dto_1 = require("./dto/queryCats.dto");
|
||||
const createApp_dto_1 = require("./dto/createApp.dto");
|
||||
const updateApp_dto_1 = require("./dto/updateApp.dto");
|
||||
const deleteApp_dto_1 = require("./dto/deleteApp.dto");
|
||||
const queryApp_dto_1 = require("./dto/queryApp.dto");
|
||||
const superAuth_guard_1 = require("../../common/auth/superAuth.guard");
|
||||
const adminAuth_guard_1 = require("../../common/auth/adminAuth.guard");
|
||||
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
|
||||
const superAuth_guard_1 = require("../../common/auth/superAuth.guard");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const app_service_1 = require("./app.service");
|
||||
const collectApp_dto_1 = require("./dto/collectApp.dto");
|
||||
const createApp_dto_1 = require("./dto/createApp.dto");
|
||||
const createCats_dto_1 = require("./dto/createCats.dto");
|
||||
const custonApp_dto_1 = require("./dto/custonApp.dto");
|
||||
const deleteApp_dto_1 = require("./dto/deleteApp.dto");
|
||||
const deleteCats_dto_1 = require("./dto/deleteCats.dto");
|
||||
const queryApp_dto_1 = require("./dto/queryApp.dto");
|
||||
const queryCats_dto_1 = require("./dto/queryCats.dto");
|
||||
const updateApp_dto_1 = require("./dto/updateApp.dto");
|
||||
const updateCats_dto_1 = require("./dto/updateCats.dto");
|
||||
let AppController = class AppController {
|
||||
constructor(appService) {
|
||||
this.appService = appService;
|
||||
|
@ -61,6 +61,9 @@ let AppController = class AppController {
|
|||
list(req, query) {
|
||||
return this.appService.frontAppList(req, query);
|
||||
}
|
||||
async searchList(body) {
|
||||
return this.appService.searchAppList(body);
|
||||
}
|
||||
createApp(body) {
|
||||
return this.appService.createApp(body);
|
||||
}
|
||||
|
@ -176,6 +179,14 @@ __decorate([
|
|||
__metadata("design:paramtypes", [Object, queryApp_dto_1.QuerAppDto]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], AppController.prototype, "list", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('searchList'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '客户端获取App' }),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AppController.prototype, "searchList", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('createApp'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加App' }),
|
||||
|
|
112
dist/modules/app/app.service.js
vendored
112
dist/modules/app/app.service.js
vendored
|
@ -50,7 +50,9 @@ let AppService = class AppService {
|
|||
}
|
||||
async updateAppCats(body) {
|
||||
const { id, name } = body;
|
||||
const c = await this.appCatsEntity.findOne({ where: { name, id: (0, typeorm_2.Not)(id) } });
|
||||
const c = await this.appCatsEntity.findOne({
|
||||
where: { name, id: (0, typeorm_2.Not)(id) },
|
||||
});
|
||||
if (c) {
|
||||
throw new common_1.HttpException('该分类名称已存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -65,7 +67,7 @@ let AppService = class AppService {
|
|||
throw new common_1.HttpException('缺失必要参数!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const app = await this.appEntity.findOne({ where: { id } });
|
||||
const { demoData: demo, coverImg, des, name, isFixedModel, isGPTs, appModel } = app;
|
||||
const { demoData: demo, coverImg, des, name, isFixedModel, isGPTs, appModel, } = app;
|
||||
return {
|
||||
demoData: demo ? demo.split('\n') : [],
|
||||
coverImg,
|
||||
|
@ -140,7 +142,12 @@ let AppService = class AppService {
|
|||
var _a;
|
||||
const { page = 1, size = 1000, name, catId, role } = query;
|
||||
const where = [
|
||||
{ status: (0, typeorm_2.In)([1, 4]), userId: (0, typeorm_2.IsNull)(), public: false, isSystemReserved: 0 },
|
||||
{
|
||||
status: (0, typeorm_2.In)([1, 4]),
|
||||
userId: (0, typeorm_2.IsNull)(),
|
||||
public: false,
|
||||
isSystemReserved: 0,
|
||||
},
|
||||
{ userId: (0, typeorm_2.MoreThan)(0), public: true },
|
||||
];
|
||||
const [rows, count] = await this.appEntity.findAndCount({
|
||||
|
@ -162,6 +169,42 @@ let AppService = class AppService {
|
|||
}
|
||||
return { rows, count };
|
||||
}
|
||||
async searchAppList(body) {
|
||||
console.log('搜索App列表', body);
|
||||
const { page = 1, size = 1000, keyword } = body;
|
||||
console.log(`搜索关键词:${keyword}`);
|
||||
let baseWhere = [
|
||||
{
|
||||
status: (0, typeorm_2.In)([1, 4]),
|
||||
userId: (0, typeorm_2.IsNull)(),
|
||||
public: false,
|
||||
isSystemReserved: 0,
|
||||
},
|
||||
{ userId: (0, typeorm_2.MoreThan)(0), public: true },
|
||||
];
|
||||
console.log('初始查询条件:', JSON.stringify(baseWhere));
|
||||
if (keyword) {
|
||||
baseWhere = baseWhere.map((condition) => (Object.assign(Object.assign({}, condition), { name: (0, typeorm_2.Like)(`%${keyword}%`) })));
|
||||
console.log('更新后的查询条件:', JSON.stringify(baseWhere));
|
||||
}
|
||||
try {
|
||||
const [rows, count] = await this.appEntity.findAndCount({
|
||||
where: baseWhere,
|
||||
skip: (page - 1) * size,
|
||||
take: size,
|
||||
});
|
||||
console.log(`查询返回 ${count} 条结果,显示第 ${page} 页的结果。`);
|
||||
rows.forEach((item) => {
|
||||
delete item.preset;
|
||||
});
|
||||
console.log('完成查询,准备返回结果');
|
||||
return { rows, count };
|
||||
}
|
||||
catch (error) {
|
||||
console.error('查询数据库时出错:', error);
|
||||
throw new Error('Database query failed');
|
||||
}
|
||||
}
|
||||
async createApp(body) {
|
||||
const { name, catId } = body;
|
||||
body.role = 'system';
|
||||
|
@ -177,13 +220,24 @@ let AppService = class AppService {
|
|||
}
|
||||
async customApp(body, req) {
|
||||
const { id } = req.user;
|
||||
const { name, catId, des, preset, coverImg, demoData, public: isPublic, appId } = body;
|
||||
const { name, catId, des, preset, coverImg, demoData, public: isPublic, appId, } = body;
|
||||
if (appId) {
|
||||
const a = await this.appEntity.findOne({ where: { id: appId, userId: id } });
|
||||
const a = await this.appEntity.findOne({
|
||||
where: { id: appId, userId: id },
|
||||
});
|
||||
if (!a) {
|
||||
throw new common_1.HttpException('您正在编辑一个不存在的应用!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const data = { name, catId, des, preset, coverImg, demoData, public: isPublic, status: isPublic ? 3 : 1 };
|
||||
const data = {
|
||||
name,
|
||||
catId,
|
||||
des,
|
||||
preset,
|
||||
coverImg,
|
||||
demoData,
|
||||
public: isPublic,
|
||||
status: isPublic ? 3 : 1,
|
||||
};
|
||||
const res = await this.appEntity.update({ id: appId, userId: id }, data);
|
||||
if (res.affected) {
|
||||
return '修改成功';
|
||||
|
@ -201,9 +255,27 @@ let AppService = class AppService {
|
|||
if (a) {
|
||||
throw new common_1.HttpException('该应用名称已存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const data = { name, catId, des, preset, coverImg, status: isPublic ? 3 : 1, demoData, public: isPublic, role: 'user', userId: id };
|
||||
const data = {
|
||||
name,
|
||||
catId,
|
||||
des,
|
||||
preset,
|
||||
coverImg,
|
||||
status: isPublic ? 3 : 1,
|
||||
demoData,
|
||||
public: isPublic,
|
||||
role: 'user',
|
||||
userId: id,
|
||||
};
|
||||
const res = await this.appEntity.save(data);
|
||||
const params = { appId: res.id, userId: id, appType: 'user', public: isPublic, status: isPublic ? 3 : 1, catId };
|
||||
const params = {
|
||||
appId: res.id,
|
||||
userId: id,
|
||||
appType: 'user',
|
||||
public: isPublic,
|
||||
status: isPublic ? 3 : 1,
|
||||
catId,
|
||||
};
|
||||
return this.userAppsEntity.save(params);
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +301,9 @@ let AppService = class AppService {
|
|||
async updateSystemApp(body) {
|
||||
const { id, name } = body;
|
||||
common_1.Logger.log(`尝试更新应用: ${name} (ID: ${id})`);
|
||||
const existingApp = await this.appEntity.findOne({ where: { name, id: (0, typeorm_2.Not)(id) } });
|
||||
const existingApp = await this.appEntity.findOne({
|
||||
where: { name, id: (0, typeorm_2.Not)(id) },
|
||||
});
|
||||
if (existingApp) {
|
||||
common_1.Logger.warn(`应用名称已存在:${name}`);
|
||||
throw new common_1.HttpException('该应用名称已存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -249,9 +323,6 @@ let AppService = class AppService {
|
|||
throw new common_1.HttpException('该应用不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const useApp = await this.userAppsEntity.count({ where: { appId: id } });
|
||||
if (useApp > 0) {
|
||||
throw new common_1.HttpException('该应用已被用户关联使用中,不可删除!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const res = await this.appEntity.delete(id);
|
||||
if (res.affected > 0)
|
||||
return '删除App成功';
|
||||
|
@ -279,7 +350,9 @@ let AppService = class AppService {
|
|||
}
|
||||
async delMineApp(body, req) {
|
||||
const { id } = body;
|
||||
const a = await this.appEntity.findOne({ where: { id, userId: req.user.id } });
|
||||
const a = await this.appEntity.findOne({
|
||||
where: { id, userId: req.user.id },
|
||||
});
|
||||
if (!a) {
|
||||
throw new common_1.HttpException('您正在操作一个不存在的资源!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -290,7 +363,9 @@ let AppService = class AppService {
|
|||
async collect(body, req) {
|
||||
const { appId } = body;
|
||||
const { id: userId } = req.user;
|
||||
const historyApp = await this.userAppsEntity.findOne({ where: { appId, userId } });
|
||||
const historyApp = await this.userAppsEntity.findOne({
|
||||
where: { appId, userId },
|
||||
});
|
||||
if (historyApp) {
|
||||
const r = await this.userAppsEntity.delete({ appId, userId });
|
||||
if (r.affected > 0) {
|
||||
|
@ -302,7 +377,14 @@ let AppService = class AppService {
|
|||
}
|
||||
const app = await this.appEntity.findOne({ where: { id: appId } });
|
||||
const { id, role: appRole, catId } = app;
|
||||
const collectInfo = { userId, appId: id, catId, appRole, public: true, status: 1 };
|
||||
const collectInfo = {
|
||||
userId,
|
||||
appId: id,
|
||||
catId,
|
||||
appRole,
|
||||
public: true,
|
||||
status: 1,
|
||||
};
|
||||
await this.userAppsEntity.save(collectInfo);
|
||||
return '已将应用加入到我的收藏!';
|
||||
}
|
||||
|
|
10
dist/modules/app/appCats.entity.js
vendored
10
dist/modules/app/appCats.entity.js
vendored
|
@ -10,22 +10,14 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AppCatsEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
const typeorm_1 = require("typeorm");
|
||||
let AppCatsEntity = class AppCatsEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ unique: true, comment: 'App分类名称' }),
|
||||
__metadata("design:type", String)
|
||||
], AppCatsEntity.prototype, "name", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: 'App分类描述信息' }),
|
||||
__metadata("design:type", String)
|
||||
], AppCatsEntity.prototype, "des", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: 'App分类封面图片', nullable: true }),
|
||||
__metadata("design:type", String)
|
||||
], AppCatsEntity.prototype, "coverImg", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: 'App分类排序、数字越大越靠前', default: 100 }),
|
||||
__metadata("design:type", Number)
|
||||
|
|
30
dist/modules/app/dto/createCats.dto.js
vendored
30
dist/modules/app/dto/createCats.dto.js
vendored
|
@ -10,37 +10,35 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CreateCatsDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class CreateCatsDto {
|
||||
}
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: '编程助手', description: 'app分类名称', required: true }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: '编程助手',
|
||||
description: 'app分类名称',
|
||||
required: true,
|
||||
}),
|
||||
(0, class_validator_1.IsDefined)({ message: 'app分类名称是必传参数' }),
|
||||
__metadata("design:type", String)
|
||||
], CreateCatsDto.prototype, "name", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: '适用于编程编码、期望成为您的编程助手',
|
||||
description: 'app分类名称详情描述',
|
||||
example: 100,
|
||||
description: '分类排序、数字越大越靠前',
|
||||
required: false,
|
||||
}),
|
||||
(0, class_validator_1.IsDefined)({ message: 'app分类名称描述是必传参数' }),
|
||||
__metadata("design:type", String)
|
||||
], CreateCatsDto.prototype, "des", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'https://xxxx.png', description: '套餐封面图片' }),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], CreateCatsDto.prototype, "coverImg", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 100, description: '套餐排序、数字越大越靠前', required: false }),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", Number)
|
||||
], CreateCatsDto.prototype, "order", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 1, description: '套餐状态 0:禁用 1:启用', required: true }),
|
||||
(0, class_validator_1.IsNumber)({}, { message: '套餐状态必须是Number' }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: 1,
|
||||
description: '分类状态 0:禁用 1:启用',
|
||||
required: true,
|
||||
}),
|
||||
(0, class_validator_1.IsNumber)({}, { message: '状态必须是Number' }),
|
||||
(0, class_validator_1.IsIn)([0, 1, 3, 4, 5], { message: '套餐状态错误' }),
|
||||
__metadata("design:type", Number)
|
||||
], CreateCatsDto.prototype, "status", void 0);
|
||||
|
|
7
dist/modules/app/dto/queryApp.dto.js
vendored
7
dist/modules/app/dto/queryApp.dto.js
vendored
|
@ -10,8 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QuerAppDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class QuerAppDto {
|
||||
}
|
||||
__decorate([
|
||||
|
@ -44,4 +44,9 @@ __decorate([
|
|||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], QuerAppDto.prototype, "role", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: '关键词', description: '搜索关键词', required: false }),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], QuerAppDto.prototype, "keyword", void 0);
|
||||
exports.QuerAppDto = QuerAppDto;
|
||||
|
|
15
dist/modules/auth/auth.controller.js
vendored
15
dist/modules/auth/auth.controller.js
vendored
|
@ -18,6 +18,7 @@ const common_1 = require("@nestjs/common");
|
|||
const swagger_1 = require("@nestjs/swagger");
|
||||
const auth_service_1 = require("./auth.service");
|
||||
const authLogin_dto_1 = require("./dto/authLogin.dto");
|
||||
const authRegister_dto_1 = require("./dto/authRegister.dto");
|
||||
const updatePassByOther_dto_1 = require("./dto/updatePassByOther.dto");
|
||||
const updatePassword_dto_1 = require("./dto/updatePassword.dto");
|
||||
let AuthController = class AuthController {
|
||||
|
@ -30,6 +31,9 @@ let AuthController = class AuthController {
|
|||
async login(body, req) {
|
||||
return this.authService.login(body, req);
|
||||
}
|
||||
async loginWithCaptcha(body, req) {
|
||||
return this.authService.loginWithCaptcha(body, req);
|
||||
}
|
||||
async updatePassword(req, body) {
|
||||
return this.authService.updatePassword(req, body);
|
||||
}
|
||||
|
@ -52,7 +56,7 @@ __decorate([
|
|||
__param(0, (0, common_1.Body)()),
|
||||
__param(1, (0, common_1.Req)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:paramtypes", [authRegister_dto_1.UserRegisterDto, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AuthController.prototype, "register", null);
|
||||
__decorate([
|
||||
|
@ -64,6 +68,15 @@ __decorate([
|
|||
__metadata("design:paramtypes", [authLogin_dto_1.UserLoginDto, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AuthController.prototype, "login", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('loginWithCaptcha'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '用户使用验证码登录' }),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__param(1, (0, common_1.Req)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AuthController.prototype, "loginWithCaptcha", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('updatePassword'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '用户更改密码' }),
|
||||
|
|
24
dist/modules/auth/auth.module.js
vendored
24
dist/modules/auth/auth.module.js
vendored
|
@ -13,8 +13,6 @@ const common_1 = require("@nestjs/common");
|
|||
const jwt_1 = require("@nestjs/jwt");
|
||||
const passport_1 = require("@nestjs/passport");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const nestjs_config_1 = require("nestjs-config");
|
||||
const whiteList_entity_1 = require("../chat/whiteList.entity");
|
||||
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
const cramiPackage_entity_1 = require("../crami/cramiPackage.entity");
|
||||
|
@ -42,10 +40,14 @@ AuthModule = __decorate([
|
|||
(0, common_1.Module)({
|
||||
imports: [
|
||||
user_module_1.UserModule,
|
||||
redisCache_module_1.RedisCacheModule,
|
||||
passport_1.PassportModule.register({ defaultStrategy: 'jwt' }),
|
||||
jwt_1.JwtModule.registerAsync({
|
||||
useFactory: async (configService) => configService.get('jwt'),
|
||||
inject: [nestjs_config_1.ConfigService],
|
||||
inject: [redisCache_service_1.RedisCacheService],
|
||||
useFactory: async (redisService) => ({
|
||||
secret: await redisService.getJwtSecret(),
|
||||
signOptions: { expiresIn: '7d' },
|
||||
}),
|
||||
}),
|
||||
typeorm_1.TypeOrmModule.forFeature([
|
||||
verifycation_entity_1.VerifycationEntity,
|
||||
|
@ -53,19 +55,25 @@ AuthModule = __decorate([
|
|||
accountLog_entity_1.AccountLogEntity,
|
||||
config_entity_1.ConfigEntity,
|
||||
cramiPackage_entity_1.CramiPackageEntity,
|
||||
redisCache_module_1.RedisCacheModule,
|
||||
userBalance_entity_1.UserBalanceEntity,
|
||||
salesUsers_entity_1.SalesUsersEntity,
|
||||
user_entity_1.UserEntity,
|
||||
whiteList_entity_1.WhiteListEntity,
|
||||
fingerprint_entity_1.FingerprintLogEntity,
|
||||
chatLog_entity_1.ChatLogEntity,
|
||||
chatGroup_entity_1.ChatGroupEntity,
|
||||
midjourney_entity_1.MidjourneyEntity
|
||||
midjourney_entity_1.MidjourneyEntity,
|
||||
]),
|
||||
],
|
||||
controllers: [auth_controller_1.AuthController],
|
||||
providers: [auth_service_1.AuthService, jwt_strategy_1.JwtStrategy, jwtAuth_guard_1.JwtAuthGuard, mailer_service_1.MailerService, verification_service_1.VerificationService, userBalance_service_1.UserBalanceService, redisCache_service_1.RedisCacheService],
|
||||
providers: [
|
||||
auth_service_1.AuthService,
|
||||
jwt_strategy_1.JwtStrategy,
|
||||
jwtAuth_guard_1.JwtAuthGuard,
|
||||
mailer_service_1.MailerService,
|
||||
verification_service_1.VerificationService,
|
||||
userBalance_service_1.UserBalanceService,
|
||||
redisCache_service_1.RedisCacheService,
|
||||
],
|
||||
exports: [auth_service_1.AuthService],
|
||||
})
|
||||
], AuthModule);
|
||||
|
|
201
dist/modules/auth/auth.service.js
vendored
201
dist/modules/auth/auth.service.js
vendored
|
@ -44,24 +44,60 @@ let AuthService = class AuthService {
|
|||
this.getIp();
|
||||
}
|
||||
async register(body, req) {
|
||||
const { username, password, contact, code, invitedBy } = body;
|
||||
await this.verificationService.verifyCaptcha(body);
|
||||
const { password, contact, code, invitedBy } = body;
|
||||
let email = '', phone = '';
|
||||
const isEmail = /\S+@\S+\.\S+/.test(contact);
|
||||
const isPhone = /^\d{10,}$/.test(contact);
|
||||
common_1.Logger.debug(`Contact: ${contact}, isEmail: ${isEmail}, isPhone: ${isPhone}`);
|
||||
let username = (0, utils_1.createRandomUid)();
|
||||
while (true) {
|
||||
const usernameTaken = await this.userService.verifyUserRegister({
|
||||
username,
|
||||
});
|
||||
common_1.Logger.debug(`Checking if username ${username} is taken: ${usernameTaken}`);
|
||||
if (usernameTaken) {
|
||||
break;
|
||||
}
|
||||
username = (0, utils_1.createRandomUid)();
|
||||
}
|
||||
if (isEmail) {
|
||||
email = contact;
|
||||
await this.userService.verifyUserRegister({ username, email });
|
||||
const isAvailable = await this.userService.verifyUserRegister({
|
||||
username,
|
||||
email,
|
||||
});
|
||||
common_1.Logger.debug(`Email ${email} is available: ${isAvailable}`);
|
||||
if (!isAvailable) {
|
||||
throw new common_1.HttpException('当前邮箱已注册,请勿重复注册!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
else if (isPhone) {
|
||||
phone = contact;
|
||||
await this.userService.verifyUserRegister({ username, phone });
|
||||
const isAvailable = await this.userService.verifyUserRegister({
|
||||
username,
|
||||
phone,
|
||||
});
|
||||
common_1.Logger.debug(`Phone ${phone} is available: ${isAvailable}`);
|
||||
if (!isAvailable) {
|
||||
throw new common_1.HttpException('当前手机号已注册,请勿重复注册!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new common_1.HttpException('请提供有效的邮箱地址或手机号码。', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const noVerifyRegister = await this.globalConfigService.getConfigs([
|
||||
'noVerifyRegister',
|
||||
]);
|
||||
common_1.Logger.debug(`noVerifyRegister: ${noVerifyRegister}`);
|
||||
if (noVerifyRegister !== '1') {
|
||||
const nameSpace = await this.globalConfigService.getNamespace();
|
||||
const key = `${nameSpace}:CODE:${contact}`;
|
||||
const redisCode = await this.redisCacheService.get({ key });
|
||||
common_1.Logger.debug(`Retrieved redisCode for ${contact}: ${redisCode}`);
|
||||
if (code === '') {
|
||||
throw new common_1.HttpException('请输入验证码', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (!redisCode) {
|
||||
common_1.Logger.log(`验证码过期: ${contact}`);
|
||||
throw new common_1.HttpException('验证码已过期,请重新发送!', common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -70,31 +106,47 @@ let AuthService = class AuthService {
|
|||
common_1.Logger.log(`验证码错误: ${contact} 输入的验证码: ${code}, 期望的验证码: ${redisCode}`);
|
||||
throw new common_1.HttpException('验证码填写错误,请重新输入!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
console.log('开始创建用户...');
|
||||
}
|
||||
let newUser;
|
||||
if (isEmail) {
|
||||
newUser = { username, password, email: contact, invitedBy, status: user_constant_1.UserStatusEnum.ACTIVE };
|
||||
newUser = {
|
||||
username,
|
||||
password,
|
||||
email: contact,
|
||||
invitedBy,
|
||||
status: user_constant_1.UserStatusEnum.ACTIVE,
|
||||
};
|
||||
}
|
||||
else {
|
||||
const email = `${(0, utils_1.createRandomUid)()}@aiweb.com`;
|
||||
newUser = { username, password, email, phone: contact, invitedBy, status: user_constant_1.UserStatusEnum.ACTIVE };
|
||||
newUser = {
|
||||
username,
|
||||
password,
|
||||
email,
|
||||
phone: contact,
|
||||
invitedBy,
|
||||
status: user_constant_1.UserStatusEnum.ACTIVE,
|
||||
};
|
||||
}
|
||||
;
|
||||
console.log('获取默认用户头像...');
|
||||
const userDefautlAvatar = await this.globalConfigService.getConfigs(['userDefautlAvatar']);
|
||||
console.log(`使用默认用户头像: ${userDefautlAvatar}`);
|
||||
common_1.Logger.debug('获取默认用户头像...');
|
||||
const userDefautlAvatar = await this.globalConfigService.getConfigs([
|
||||
'userDefautlAvatar',
|
||||
]);
|
||||
common_1.Logger.debug(`使用默认用户头像: ${userDefautlAvatar}`);
|
||||
newUser.avatar = userDefautlAvatar;
|
||||
console.log('加密用户密码...');
|
||||
common_1.Logger.debug('加密用户密码...');
|
||||
const hashedPassword = bcrypt.hashSync(password, 10);
|
||||
newUser.password = hashedPassword;
|
||||
console.log('保存新用户到数据库...');
|
||||
common_1.Logger.debug('保存新用户到数据库...');
|
||||
const u = await this.userService.createUser(newUser);
|
||||
console.log(`用户创建成功,用户ID: ${u.id}`);
|
||||
common_1.Logger.debug(`用户创建成功,用户ID: ${u.id}`);
|
||||
let inviteUser;
|
||||
if (invitedBy) {
|
||||
inviteUser = await this.userService.qureyUserInfoByInviteCode(invitedBy);
|
||||
common_1.Logger.debug(`邀请人信息: ${inviteUser}`);
|
||||
}
|
||||
await this.userBalanceService.addBalanceToNewUser(u.id, inviteUser === null || inviteUser === void 0 ? void 0 : inviteUser.id);
|
||||
common_1.Logger.debug('完成新用户余额处理');
|
||||
return { success: true, message: '注册成功' };
|
||||
}
|
||||
async login(user, req) {
|
||||
|
@ -109,7 +161,73 @@ let AuthService = class AuthService {
|
|||
const ip = (0, utils_1.getClientIp)(req);
|
||||
await this.userService.savaLoginIp(id, ip);
|
||||
console.log(`保存登录IP: ${ip} - 用户ID: ${id}`);
|
||||
const token = await this.jwtService.sign({ username, id, email, role, openId, client, phone });
|
||||
const token = await this.jwtService.sign({
|
||||
username,
|
||||
id,
|
||||
email,
|
||||
role,
|
||||
openId,
|
||||
client,
|
||||
phone,
|
||||
});
|
||||
console.log(`JWT令牌生成成功 - 用户ID: ${id}`);
|
||||
await this.redisCacheService.saveToken(id, token);
|
||||
console.log(`令牌已保存到Redis - 用户ID: ${id}`);
|
||||
return token;
|
||||
}
|
||||
async loginWithCaptcha(body, req) {
|
||||
const { contact, code } = body;
|
||||
let email = '', phone = '';
|
||||
const isEmail = /\S+@\S+\.\S+/.test(contact);
|
||||
const isPhone = /^\d{10,}$/.test(contact);
|
||||
if (isEmail) {
|
||||
email = contact;
|
||||
}
|
||||
else if (isPhone) {
|
||||
phone = contact;
|
||||
}
|
||||
else {
|
||||
throw new common_1.HttpException('请提供有效的邮箱地址或手机号码。', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const isAvailable = await this.userService.verifyUserRegister({
|
||||
email,
|
||||
phone,
|
||||
});
|
||||
const nameSpace = await this.globalConfigService.getNamespace();
|
||||
const key = `${nameSpace}:CODE:${contact}`;
|
||||
const redisCode = await this.redisCacheService.get({ key });
|
||||
if (!redisCode) {
|
||||
common_1.Logger.log(`验证码过期: ${contact}`);
|
||||
throw new common_1.HttpException('验证码已过期,请重新发送!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (code !== redisCode) {
|
||||
common_1.Logger.log(`验证码错误: ${contact} 输入的验证码: ${code}, 期望的验证码: ${redisCode}`);
|
||||
throw new common_1.HttpException('验证码填写错误,请重新输入!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
let u;
|
||||
if (isAvailable) {
|
||||
u = await this.userService.createUserFromContact({ email, phone });
|
||||
}
|
||||
else {
|
||||
u = await this.userService.getUserByContact({ email, phone });
|
||||
}
|
||||
if (!u) {
|
||||
throw new common_1.HttpException('登录失败,用户凭证无效。', common_1.HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
const { username, id, role, openId, client } = u;
|
||||
console.log(`用户凭证验证成功,用户ID: ${id}, 用户名: ${username}`);
|
||||
const ip = (0, utils_1.getClientIp)(req);
|
||||
await this.userService.savaLoginIp(id, ip);
|
||||
console.log(`保存登录IP: ${ip} - 用户ID: ${id}`);
|
||||
const token = await this.jwtService.sign({
|
||||
username,
|
||||
id,
|
||||
email,
|
||||
role,
|
||||
openId,
|
||||
client,
|
||||
phone,
|
||||
});
|
||||
console.log(`JWT令牌生成成功 - 用户ID: ${id}`);
|
||||
await this.redisCacheService.saveToken(id, token);
|
||||
console.log(`令牌已保存到Redis - 用户ID: ${id}`);
|
||||
|
@ -123,7 +241,14 @@ let AuthService = class AuthService {
|
|||
const { username, id, email, role, openId, client } = user;
|
||||
const ip = (0, utils_1.getClientIp)(req);
|
||||
await this.userService.savaLoginIp(id, ip);
|
||||
const token = await this.jwtService.sign({ username, id, email, role, openId, client });
|
||||
const token = await this.jwtService.sign({
|
||||
username,
|
||||
id,
|
||||
email,
|
||||
role,
|
||||
openId,
|
||||
client,
|
||||
});
|
||||
await this.redisCacheService.saveToken(id, token);
|
||||
return token;
|
||||
}
|
||||
|
@ -139,10 +264,6 @@ let AuthService = class AuthService {
|
|||
if (role === 'admin') {
|
||||
throw new common_1.HttpException('非法操作、请联系管理员!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const bool = await this.userService.verifyUserPassword(id, body.oldPassword);
|
||||
if (!bool) {
|
||||
throw new common_1.HttpException('旧密码错误、请检查提交', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
this.userService.updateUserPassword(id, body.password);
|
||||
return '密码修改成功';
|
||||
}
|
||||
|
@ -161,7 +282,9 @@ let AuthService = class AuthService {
|
|||
const interfaceInfo = interfaces[interfaceName];
|
||||
for (let i = 0; i < interfaceInfo.length; i++) {
|
||||
const alias = interfaceInfo[i];
|
||||
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
|
||||
if (alias.family === 'IPv4' &&
|
||||
alias.address !== '127.0.0.1' &&
|
||||
!alias.internal) {
|
||||
ipAddress = alias.address;
|
||||
break;
|
||||
}
|
||||
|
@ -172,33 +295,53 @@ let AuthService = class AuthService {
|
|||
async captcha(parmas) {
|
||||
const nameSpace = await this.globalConfigService.getNamespace();
|
||||
const { color = '#fff' } = parmas;
|
||||
const captcha = svgCaptcha.createMathExpr({ background: color, height: 30, width: 120, noise: 5 });
|
||||
const captcha = svgCaptcha.create({
|
||||
size: 5,
|
||||
ignoreChars: '0o1i',
|
||||
noise: 4,
|
||||
color: true,
|
||||
background: color,
|
||||
height: 33,
|
||||
width: 150,
|
||||
});
|
||||
const text = captcha.text;
|
||||
const randomId = (0, utils_1.createRandomUid)();
|
||||
const randomId = Math.random().toString(36).substr(2, 9);
|
||||
const key = `${nameSpace}:CAPTCHA:${randomId}`;
|
||||
await this.redisCacheService.set({ key, val: captcha.text }, 5 * 60);
|
||||
await this.redisCacheService.set({ key, val: text }, 5 * 60);
|
||||
return {
|
||||
svgCode: captcha.data,
|
||||
code: randomId,
|
||||
};
|
||||
}
|
||||
async sendCode(body) {
|
||||
await this.verificationService.verifyCaptcha(body);
|
||||
const { contact, username } = body;
|
||||
const { contact, isLogin } = body;
|
||||
let email = '', phone = '';
|
||||
const code = (0, utils_1.createRandomCode)();
|
||||
const isEmail = /\S+@\S+\.\S+/.test(contact);
|
||||
const isPhone = /^\d{10,}$/.test(contact);
|
||||
if (!isEmail && !isPhone) {
|
||||
throw new common_1.HttpException('请提供有效的邮箱地址或手机号码。', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (!isLogin) {
|
||||
await this.verificationService.verifyCaptcha(body);
|
||||
if (isEmail) {
|
||||
email = contact;
|
||||
await this.userService.verifyUserRegister({ username, email });
|
||||
const isAvailable = await this.userService.verifyUserRegister({
|
||||
email,
|
||||
});
|
||||
if (!isAvailable) {
|
||||
throw new common_1.HttpException('当前邮箱已注册,请勿重复注册!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
else if (isPhone) {
|
||||
phone = contact;
|
||||
await this.userService.verifyUserRegister({ username, phone });
|
||||
const isAvailable = await this.userService.verifyUserRegister({
|
||||
phone,
|
||||
});
|
||||
if (!isAvailable) {
|
||||
throw new common_1.HttpException('当前手机号已注册,请勿重复注册!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new common_1.HttpException('请提供有效的邮箱地址或手机号码。', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const nameSpace = await this.globalConfigService.getNamespace();
|
||||
const key = `${nameSpace}:CODE:${contact}`;
|
||||
|
|
2
dist/modules/auth/dto/authLogin.dto.js
vendored
2
dist/modules/auth/dto/authLogin.dto.js
vendored
|
@ -10,8 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UserLoginDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class UserLoginDto {
|
||||
}
|
||||
__decorate([
|
||||
|
|
21
dist/modules/auth/dto/authRegister.dto.js
vendored
21
dist/modules/auth/dto/authRegister.dto.js
vendored
|
@ -10,15 +10,12 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UserRegisterDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class UserRegisterDto {
|
||||
}
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'cooper', description: '用户名称' }),
|
||||
(0, class_validator_1.IsNotEmpty)({ message: '用户名不能为空!' }),
|
||||
(0, class_validator_1.MinLength)(2, { message: '用户名最低需要大于2位数!' }),
|
||||
(0, class_validator_1.MaxLength)(12, { message: '用户名不得超过12位!' }),
|
||||
__metadata("design:type", String)
|
||||
], UserRegisterDto.prototype, "username", void 0);
|
||||
__decorate([
|
||||
|
@ -29,9 +26,7 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], UserRegisterDto.prototype, "password", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'J_longyan@163.com', description: '用户邮箱' }),
|
||||
(0, class_validator_1.IsEmail)({}, { message: '请填写正确格式的邮箱!' }),
|
||||
(0, class_validator_1.IsNotEmpty)({ message: '邮箱不能为空!' }),
|
||||
(0, swagger_1.ApiProperty)({ example: 'ai@aiweb.com', description: '用户邮箱' }),
|
||||
__metadata("design:type", String)
|
||||
], UserRegisterDto.prototype, "email", void 0);
|
||||
__decorate([
|
||||
|
@ -45,7 +40,11 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], UserRegisterDto.prototype, "captchaId", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'FRJDLJHFNV', description: '用户填写的别人邀请码', required: false }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: 'FRJDLJHFNV',
|
||||
description: '用户填写的别人邀请码',
|
||||
required: false,
|
||||
}),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], UserRegisterDto.prototype, "invitedBy", void 0);
|
||||
|
@ -59,7 +58,11 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], UserRegisterDto.prototype, "avatar", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'default', description: '用户注册来源', required: false }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: 'default',
|
||||
description: '用户注册来源',
|
||||
required: false,
|
||||
}),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], UserRegisterDto.prototype, "client", void 0);
|
||||
|
|
9
dist/modules/auth/dto/updatePassword.dto.js
vendored
9
dist/modules/auth/dto/updatePassword.dto.js
vendored
|
@ -10,17 +10,10 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UpdatePasswordDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class UpdatePasswordDto {
|
||||
}
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: '123456', description: '用户旧密码' }),
|
||||
(0, class_validator_1.IsNotEmpty)({ message: '用户密码不能为空!' }),
|
||||
(0, class_validator_1.MinLength)(6, { message: '用户密码最低需要大于6位数!' }),
|
||||
(0, class_validator_1.MaxLength)(30, { message: '用户密码最长不能超过30位数!' }),
|
||||
__metadata("design:type", String)
|
||||
], UpdatePasswordDto.prototype, "oldPassword", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: '666666', description: '用户更新新密码' }),
|
||||
(0, class_validator_1.IsNotEmpty)({ message: '用户密码不能为空!' }),
|
||||
|
|
10
dist/modules/autoreply/autoreply.service.js
vendored
10
dist/modules/autoreply/autoreply.service.js
vendored
|
@ -14,9 +14,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AutoreplyService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const typeorm_2 = require("typeorm");
|
||||
const autoreplay_entity_1 = require("./autoreplay.entity");
|
||||
const typeorm_1 = require("typeorm");
|
||||
const typeorm_2 = require("@nestjs/typeorm");
|
||||
let AutoreplyService = class AutoreplyService {
|
||||
constructor(autoReplyEntity) {
|
||||
this.autoReplyEntity = autoReplyEntity;
|
||||
|
@ -44,7 +44,7 @@ let AutoreplyService = class AutoreplyService {
|
|||
const { page = 1, size = 10, prompt, status } = query;
|
||||
const where = {};
|
||||
[0, 1, '0', '1'].includes(status) && (where.status = status);
|
||||
prompt && (where.prompt = (0, typeorm_1.Like)(`%${prompt}%`));
|
||||
prompt && (where.prompt = (0, typeorm_2.Like)(`%${prompt}%`));
|
||||
const [rows, count] = await this.autoReplyEntity.findAndCount({
|
||||
where,
|
||||
skip: (page - 1) * size,
|
||||
|
@ -88,7 +88,7 @@ let AutoreplyService = class AutoreplyService {
|
|||
};
|
||||
AutoreplyService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__param(0, (0, typeorm_2.InjectRepository)(autoreplay_entity_1.AutoReplyEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_1.Repository])
|
||||
__param(0, (0, typeorm_1.InjectRepository)(autoreplay_entity_1.AutoReplyEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_2.Repository])
|
||||
], AutoreplyService);
|
||||
exports.AutoreplyService = AutoreplyService;
|
||||
|
|
|
@ -18,7 +18,11 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], AddAutoReplyDto.prototype, "prompt", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: '我是NineAi提供的Ai服务机器人', description: '回答的答案', required: true }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: '我是AIWeb提供的Ai服务机器人',
|
||||
description: '回答的答案',
|
||||
required: true,
|
||||
}),
|
||||
__metadata("design:type", String)
|
||||
], AddAutoReplyDto.prototype, "answer", void 0);
|
||||
exports.AddAutoReplyDto = AddAutoReplyDto;
|
||||
|
|
65
dist/modules/badwords/badwords.service.js
vendored
65
dist/modules/badwords/badwords.service.js
vendored
|
@ -13,15 +13,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.BadwordsService = void 0;
|
||||
const globalConfig_service_1 = require("./../globalConfig/globalConfig.service");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const badwords_entity_1 = require("./badwords.entity");
|
||||
const typeorm_1 = require("typeorm");
|
||||
const typeorm_2 = require("@nestjs/typeorm");
|
||||
const axios_1 = require("axios");
|
||||
const violationLog_entity_1 = require("./violationLog.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const utils_1 = require("../../common/utils");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const axios_1 = require("axios");
|
||||
const typeorm_2 = require("typeorm");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const globalConfig_service_1 = require("./../globalConfig/globalConfig.service");
|
||||
const badwords_entity_1 = require("./badwords.entity");
|
||||
const violationLog_entity_1 = require("./violationLog.entity");
|
||||
let BadwordsService = class BadwordsService {
|
||||
constructor(badWordsEntity, violationLogEntity, userEntity, globalConfigService) {
|
||||
this.badWordsEntity = badWordsEntity;
|
||||
|
@ -56,8 +56,8 @@ let BadwordsService = class BadwordsService {
|
|||
}
|
||||
async checkBadWordsByConfig(content, config, userId) {
|
||||
const { useType } = config;
|
||||
useType === 'baidu' && (await this.baiduCheckBadWords(content, config.baiduTextAccessToken, userId));
|
||||
useType === 'nineai' && (await this.nineaiCheckBadWords(content, config, userId));
|
||||
useType === 'baidu' &&
|
||||
(await this.baiduCheckBadWords(content, config.baiduTextAccessToken, userId));
|
||||
}
|
||||
extractContent(str) {
|
||||
const pattern = /存在(.*?)不合规/;
|
||||
|
@ -78,46 +78,31 @@ let BadwordsService = class BadwordsService {
|
|||
console.log('百度文本检测出现错误、请查看配置信息: ', error_msg);
|
||||
}
|
||||
if (conclusionType !== 1) {
|
||||
const types = [...new Set(data.map((item) => this.extractContent(item.msg)))];
|
||||
const types = [
|
||||
...new Set(data.map((item) => this.extractContent(item.msg))),
|
||||
];
|
||||
await this.recordUserBadWords(userId, content, ['***'], types, '百度云检测');
|
||||
const tips = `您提交的信息中包含${types.join(',')}的内容、我们已对您的账户进行标记、请合规使用!`;
|
||||
throw new common_1.HttpException(tips, common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
async nineaiCheckBadWords(content, config, userId) {
|
||||
var _a;
|
||||
const { nineaiBuiltInSensitiveApiBase, nineaiBuiltInSensitiveAuthKey } = config;
|
||||
if (!nineaiBuiltInSensitiveApiBase || !nineaiBuiltInSensitiveAuthKey)
|
||||
return;
|
||||
const res = await axios_1.default.post(nineaiBuiltInSensitiveApiBase, { content }, { headers: { 'Content-Type': 'application/json', Authorization: nineaiBuiltInSensitiveAuthKey } });
|
||||
if (!res.data)
|
||||
return;
|
||||
if (res.data.code !== '0') {
|
||||
const { msg = '检测失败' } = res.data;
|
||||
throw new common_1.HttpException(`敏感词检测 | ${msg}`, common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (res.data.word_list && ((_a = res.data.word_list) === null || _a === void 0 ? void 0 : _a.length)) {
|
||||
const words = [...new Set(res.data.word_list.map((t) => t.keyword))];
|
||||
const types = [...new Set(res.data.word_list.map((t) => t.category))];
|
||||
await this.recordUserBadWords(userId, content, words, types, 'NineAi检测');
|
||||
const tips = this.formarTips(res.data.word_list);
|
||||
throw new common_1.HttpException(tips, common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
formarTips(wordList) {
|
||||
const categorys = wordList.map((t) => t.category);
|
||||
const unSet = [...new Set(categorys)];
|
||||
return `您提交的内容中包含${unSet.join(',')}的信息、我们已对您账号进行标记、请合规使用!`;
|
||||
}
|
||||
async loadBadWords() {
|
||||
const data = await this.badWordsEntity.find({ where: { status: 1 }, select: ['word'] });
|
||||
const data = await this.badWordsEntity.find({
|
||||
where: { status: 1 },
|
||||
select: ['word'],
|
||||
});
|
||||
this.badWords = data.map((t) => t.word);
|
||||
}
|
||||
async queryBadWords(query) {
|
||||
const { page = 1, size = 500, word, status } = query;
|
||||
const where = {};
|
||||
[0, 1, '0', '1'].includes(status) && (where.status = status);
|
||||
word && (where.word = (0, typeorm_1.Like)(`%${word}%`));
|
||||
word && (where.word = (0, typeorm_2.Like)(`%${word}%`));
|
||||
const [rows, count] = await this.badWordsEntity.findAndCount({
|
||||
where,
|
||||
skip: (page - 1) * size,
|
||||
|
@ -200,7 +185,7 @@ let BadwordsService = class BadwordsService {
|
|||
});
|
||||
const userIds = [...new Set(rows.map((t) => t.userId))];
|
||||
const usersInfo = await this.userEntity.find({
|
||||
where: { id: (0, typeorm_1.In)(userIds) },
|
||||
where: { id: (0, typeorm_2.In)(userIds) },
|
||||
select: ['id', 'avatar', 'username', 'email', 'violationCount', 'status'],
|
||||
});
|
||||
rows.forEach((t) => {
|
||||
|
@ -213,12 +198,12 @@ let BadwordsService = class BadwordsService {
|
|||
};
|
||||
BadwordsService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__param(0, (0, typeorm_2.InjectRepository)(badwords_entity_1.BadWordsEntity)),
|
||||
__param(1, (0, typeorm_2.InjectRepository)(violationLog_entity_1.ViolationLogEntity)),
|
||||
__param(2, (0, typeorm_2.InjectRepository)(user_entity_1.UserEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_1.Repository,
|
||||
typeorm_1.Repository,
|
||||
typeorm_1.Repository,
|
||||
__param(0, (0, typeorm_1.InjectRepository)(badwords_entity_1.BadWordsEntity)),
|
||||
__param(1, (0, typeorm_1.InjectRepository)(violationLog_entity_1.ViolationLogEntity)),
|
||||
__param(2, (0, typeorm_1.InjectRepository)(user_entity_1.UserEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
globalConfig_service_1.GlobalConfigService])
|
||||
], BadwordsService);
|
||||
exports.BadwordsService = BadwordsService;
|
||||
|
|
203
dist/modules/chat/chat.controller.js
vendored
203
dist/modules/chat/chat.controller.js
vendored
|
@ -18,8 +18,6 @@ const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
|
|||
const chat_service_1 = require("./chat.service");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const chatProcess_dto_1 = require("./dto/chatProcess.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 ChatController = class ChatController {
|
||||
constructor(chatService, globalConfigService) {
|
||||
|
@ -32,56 +30,14 @@ let ChatController = class ChatController {
|
|||
chatProcessSync(body, req) {
|
||||
return this.chatService.chatProcess(Object.assign({}, body), req);
|
||||
}
|
||||
ttsProcess(body, req, res) {
|
||||
return this.chatService.ttsProcess(body, req, res);
|
||||
}
|
||||
async mjFanyi(body, req) {
|
||||
return this.chatService.chatProcess(Object.assign(Object.assign({}, body), { specialModel: 'PromptOptimization' }), req);
|
||||
}
|
||||
async chatmind(body, req, res) {
|
||||
return this.chatService.chatProcess(Object.assign(Object.assign({}, body), { specialModel: 'MindMap' }), req, res);
|
||||
}
|
||||
async setChatBoxType(req, body) {
|
||||
return await this.chatService.setChatBoxType(req, body);
|
||||
}
|
||||
async delChatBoxType(req, body) {
|
||||
return await this.chatService.delChatBoxType(req, body);
|
||||
}
|
||||
async queryChatBoxType() {
|
||||
return await this.chatService.queryChatBoxType();
|
||||
}
|
||||
async setChatBox(req, body) {
|
||||
return await this.chatService.setChatBox(req, body);
|
||||
}
|
||||
async delChatBox(req, body) {
|
||||
return await this.chatService.delChatBox(req, body);
|
||||
}
|
||||
async queryChatBox() {
|
||||
return await this.chatService.queryChatBox();
|
||||
}
|
||||
async queryChatBoxFrontend() {
|
||||
return await this.chatService.queryChatBoxFrontend();
|
||||
}
|
||||
async setChatPreType(req, body) {
|
||||
return await this.chatService.setChatPreType(req, body);
|
||||
}
|
||||
async delChatPreType(req, body) {
|
||||
return await this.chatService.delChatPreType(req, body);
|
||||
}
|
||||
async queryChatPreType() {
|
||||
return await this.chatService.queryChatPreType();
|
||||
}
|
||||
async setChatPre(req, body) {
|
||||
return await this.chatService.setChatPre(req, body);
|
||||
}
|
||||
async delChatPre(req, body) {
|
||||
return await this.chatService.delChatPre(req, body);
|
||||
}
|
||||
async queryChatPre() {
|
||||
return await this.chatService.queryChatPre();
|
||||
}
|
||||
async queryChatPreList() {
|
||||
return await this.chatService.queryChatPreList();
|
||||
ttsProcess(body, req, res) {
|
||||
return this.chatService.ttsProcess(body, req, res);
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
|
@ -107,18 +63,6 @@ __decorate([
|
|||
__metadata("design:paramtypes", [chatProcess_dto_1.ChatProcessDto, Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], ChatController.prototype, "chatProcessSync", null);
|
||||
__decorate([
|
||||
(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, Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], ChatController.prototype, "ttsProcess", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('mj-fy'),
|
||||
(0, swagger_1.ApiOperation)({ summary: 'gpt描述词绘画翻译' }),
|
||||
|
@ -143,142 +87,21 @@ __decorate([
|
|||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "chatmind", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('setChatBoxType'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改分类类型' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(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.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__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", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "setChatBoxType", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('delChatBoxType'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatBoxType' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "delChatBoxType", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('queryChatBoxTypes'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '查询ChatBoxType' }),
|
||||
(0, common_1.UseGuards)(adminAuth_guard_1.AdminAuthGuard),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "queryChatBoxType", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('setChatBox'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatBox' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "setChatBox", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('delChatBox'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatBox提示词' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "delChatBox", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('queryChatBoxs'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '查询ChatBox列表' }),
|
||||
(0, common_1.UseGuards)(adminAuth_guard_1.AdminAuthGuard),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", Promise)
|
||||
], 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)
|
||||
], ChatController.prototype, "queryChatBoxFrontend", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('setChatPreType'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改预设分类类型' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "setChatPreType", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('delChatPretype'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatPretype' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "delChatPreType", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('queryChatPretypes'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '查询ChatPretype' }),
|
||||
(0, common_1.UseGuards)(adminAuth_guard_1.AdminAuthGuard),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "queryChatPreType", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('setChatPre'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatPre' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "setChatPre", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('delChatPre'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '添加修改ChatPre提示词' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__param(1, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], ChatController.prototype, "delChatPre", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('queryChatPres'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '查询ChatPre列表' }),
|
||||
(0, common_1.UseGuards)(adminAuth_guard_1.AdminAuthGuard),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", Promise)
|
||||
], 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)
|
||||
], ChatController.prototype, "queryChatPreList", null);
|
||||
__metadata("design:paramtypes", [Object, Object, Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], ChatController.prototype, "ttsProcess", null);
|
||||
ChatController = __decorate([
|
||||
(0, swagger_1.ApiTags)('chatgpt'),
|
||||
(0, common_1.Controller)('chatgpt'),
|
||||
__metadata("design:paramtypes", [chat_service_1.ChatService, globalConfig_service_1.GlobalConfigService])
|
||||
__metadata("design:paramtypes", [chat_service_1.ChatService,
|
||||
globalConfig_service_1.GlobalConfigService])
|
||||
], ChatController);
|
||||
exports.ChatController = ChatController;
|
||||
|
|
37
dist/modules/chat/chat.module.js
vendored
37
dist/modules/chat/chat.module.js
vendored
|
@ -9,6 +9,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.ChatModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const lumaVideo_service_1 = require("../ai/lumaVideo.service");
|
||||
const midjourneyDraw_service_1 = require("../ai/midjourneyDraw.service");
|
||||
const openaiChat_service_1 = require("../ai/openaiChat.service");
|
||||
const openaiDraw_service_1 = require("../ai/openaiDraw.service");
|
||||
const stableDiffusion_service_1 = require("../ai/stableDiffusion.service");
|
||||
const suno_service_1 = require("../ai/suno.service");
|
||||
const app_entity_1 = require("../app/app.entity");
|
||||
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
|
@ -17,6 +23,7 @@ const cramiPackage_entity_1 = require("../crami/cramiPackage.entity");
|
|||
const config_entity_1 = require("../globalConfig/config.entity");
|
||||
const mailer_service_1 = require("../mailer/mailer.service");
|
||||
const midjourney_entity_1 = require("../midjourney/midjourney.entity");
|
||||
const plugin_entity_1 = require("../plugin/plugin.entity");
|
||||
const redisCache_service_1 = require("../redisCache/redisCache.service");
|
||||
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
|
@ -28,14 +35,8 @@ const userBalance_entity_1 = require("../userBalance/userBalance.entity");
|
|||
const userBalance_service_1 = require("../userBalance/userBalance.service");
|
||||
const verification_service_1 = require("../verification/verification.service");
|
||||
const verifycation_entity_1 = require("../verification/verifycation.entity");
|
||||
const apiDataService_service_1 = require("./apiDataService.service");
|
||||
const chat_controller_1 = require("./chat.controller");
|
||||
const chat_service_1 = require("./chat.service");
|
||||
const chatBox_entity_1 = require("./chatBox.entity");
|
||||
const chatBoxType_entity_1 = require("./chatBoxType.entity");
|
||||
const chatPre_entity_1 = require("./chatPre.entity");
|
||||
const chatPreType_entity_1 = require("./chatPreType.entity");
|
||||
const whiteList_entity_1 = require("./whiteList.entity");
|
||||
let ChatModule = class ChatModule {
|
||||
};
|
||||
ChatModule = __decorate([
|
||||
|
@ -45,11 +46,11 @@ ChatModule = __decorate([
|
|||
typeorm_1.TypeOrmModule.forFeature([
|
||||
balance_entity_1.BalanceEntity,
|
||||
user_entity_1.UserEntity,
|
||||
plugin_entity_1.PluginEntity,
|
||||
verifycation_entity_1.VerifycationEntity,
|
||||
chatLog_entity_1.ChatLogEntity,
|
||||
accountLog_entity_1.AccountLogEntity,
|
||||
config_entity_1.ConfigEntity,
|
||||
whiteList_entity_1.WhiteListEntity,
|
||||
user_entity_1.UserEntity,
|
||||
cramiPackage_entity_1.CramiPackageEntity,
|
||||
chatGroup_entity_1.ChatGroupEntity,
|
||||
|
@ -58,15 +59,25 @@ ChatModule = __decorate([
|
|||
salesUsers_entity_1.SalesUsersEntity,
|
||||
fingerprint_entity_1.FingerprintLogEntity,
|
||||
midjourney_entity_1.MidjourneyEntity,
|
||||
chatBoxType_entity_1.ChatBoxTypeEntity,
|
||||
chatBox_entity_1.ChatBoxEntity,
|
||||
chatPreType_entity_1.ChatPreTypeEntity,
|
||||
chatPre_entity_1.ChatPreEntity,
|
||||
]),
|
||||
],
|
||||
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, apiDataService_service_1.ApiDataService, mailer_service_1.MailerService],
|
||||
exports: [chat_service_1.ChatService]
|
||||
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,
|
||||
mailer_service_1.MailerService,
|
||||
suno_service_1.SunoService,
|
||||
openaiChat_service_1.OpenAIChatService,
|
||||
stableDiffusion_service_1.StableDiffusionService,
|
||||
midjourneyDraw_service_1.MidjourneyService,
|
||||
openaiDraw_service_1.OpenAIDrawService,
|
||||
lumaVideo_service_1.LumaVideoService,
|
||||
],
|
||||
exports: [chat_service_1.ChatService],
|
||||
})
|
||||
], ChatModule);
|
||||
exports.ChatModule = ChatModule;
|
||||
|
|
1207
dist/modules/chat/chat.service.js
vendored
1207
dist/modules/chat/chat.service.js
vendored
File diff suppressed because it is too large
Load Diff
36
dist/modules/chat/chatBoxType.entity.js
vendored
36
dist/modules/chat/chatBoxType.entity.js
vendored
|
@ -1,36 +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.ChatBoxTypeEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
let ChatBoxTypeEntity = class ChatBoxTypeEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '分类名称' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatBoxTypeEntity.prototype, "name", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: 'icon图标' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatBoxTypeEntity.prototype, "icon", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '排序ID', default: 10 }),
|
||||
__metadata("design:type", Number)
|
||||
], ChatBoxTypeEntity.prototype, "order", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '是否打开', default: true }),
|
||||
__metadata("design:type", Boolean)
|
||||
], ChatBoxTypeEntity.prototype, "status", void 0);
|
||||
ChatBoxTypeEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'chat_box_type' })
|
||||
], ChatBoxTypeEntity);
|
||||
exports.ChatBoxTypeEntity = ChatBoxTypeEntity;
|
40
dist/modules/chat/chatPre.entity.js
vendored
40
dist/modules/chat/chatPre.entity.js
vendored
|
@ -1,40 +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.ChatPreEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
let ChatPreEntity = class ChatPreEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '分类ID' }),
|
||||
__metadata("design:type", Number)
|
||||
], ChatPreEntity.prototype, "typeId", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '预设问题描述词', nullable: true, type: 'text' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatPreEntity.prototype, "prompt", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '标题名称' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatPreEntity.prototype, "title", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '排序ID', default: 100 }),
|
||||
__metadata("design:type", Number)
|
||||
], ChatPreEntity.prototype, "order", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '开启状态', default: true }),
|
||||
__metadata("design:type", Boolean)
|
||||
], ChatPreEntity.prototype, "status", void 0);
|
||||
ChatPreEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'chat_pre' })
|
||||
], ChatPreEntity);
|
||||
exports.ChatPreEntity = ChatPreEntity;
|
36
dist/modules/chat/chatPreType.entity.js
vendored
36
dist/modules/chat/chatPreType.entity.js
vendored
|
@ -1,36 +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.ChatPreTypeEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
let ChatPreTypeEntity = class ChatPreTypeEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '分类名称' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatPreTypeEntity.prototype, "name", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: 'icon图标', nullable: true }),
|
||||
__metadata("design:type", String)
|
||||
], ChatPreTypeEntity.prototype, "icon", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '排序ID', default: 10 }),
|
||||
__metadata("design:type", Number)
|
||||
], ChatPreTypeEntity.prototype, "order", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '是否打开', default: true }),
|
||||
__metadata("design:type", Boolean)
|
||||
], ChatPreTypeEntity.prototype, "status", void 0);
|
||||
ChatPreTypeEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'chat_pre_type' })
|
||||
], ChatPreTypeEntity);
|
||||
exports.ChatPreTypeEntity = ChatPreTypeEntity;
|
137
dist/modules/chat/store.js
vendored
137
dist/modules/chat/store.js
vendored
|
@ -1,137 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.NineStore = void 0;
|
||||
const tiktoken_1 = require("@dqbd/tiktoken");
|
||||
const uuid_1 = require("uuid");
|
||||
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) {
|
||||
console.log('Adding system message:', systemMessage);
|
||||
messages.push({ role: 'system', content: systemMessage });
|
||||
}
|
||||
if (groupId) {
|
||||
console.log('Querying chat history for groupId:', groupId, 'with maxRounds:', maxRounds);
|
||||
const history = await chatLogService.chatHistory(groupId, maxRounds);
|
||||
console.log('Received history records:', history.length);
|
||||
let tempUserMessage = null;
|
||||
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;
|
||||
}
|
||||
if (record.role === 'user') {
|
||||
tempUserMessage = { role: record.role, content };
|
||||
}
|
||||
else if (record.role === 'assistant' && tempUserMessage && content.trim() !== '') {
|
||||
messages.push(tempUserMessage);
|
||||
messages.push({ role: record.role, content });
|
||||
tempUserMessage = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
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) {
|
||||
if (messages.length === 2 && messages[0].role === 'system' && messages[1].role === 'user') {
|
||||
break;
|
||||
}
|
||||
let foundPairToDelete = false;
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
if (messages[i].role !== 'system' && messages[i + 1] && messages[i + 1].role === 'assistant') {
|
||||
messages.splice(i, 2);
|
||||
foundPairToDelete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundPairToDelete) {
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
if (messages[i].role === 'user') {
|
||||
messages.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
totalTokens = await this._getTokenCount(messages);
|
||||
if (messages.length <= 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
36
dist/modules/chat/whiteList.entity.js
vendored
36
dist/modules/chat/whiteList.entity.js
vendored
|
@ -1,36 +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.WhiteListEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
let WhiteListEntity = class WhiteListEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ unique: true, comment: '用户ID' }),
|
||||
__metadata("design:type", Number)
|
||||
], WhiteListEntity.prototype, "userId", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '使用次数限制', default: 0 }),
|
||||
__metadata("design:type", Number)
|
||||
], WhiteListEntity.prototype, "count", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '当前用户状态', default: 1 }),
|
||||
__metadata("design:type", Number)
|
||||
], WhiteListEntity.prototype, "status", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '已经使用的次数', default: 0 }),
|
||||
__metadata("design:type", Number)
|
||||
], WhiteListEntity.prototype, "useCount", void 0);
|
||||
WhiteListEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'white_list' })
|
||||
], WhiteListEntity);
|
||||
exports.WhiteListEntity = WhiteListEntity;
|
42
dist/modules/chatLog/chatLog.entity.js
vendored
42
dist/modules/chatLog/chatLog.entity.js
vendored
|
@ -23,13 +23,21 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "model", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '使用类型1: 普通对话 2: 绘图 3: 拓展性对话', nullable: true, default: 1 }),
|
||||
(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: '自定义的模型名称', nullable: false, default: '' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "modelAvatar", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: 'Ip地址', nullable: true }),
|
||||
__metadata("design:type", String)
|
||||
|
@ -67,19 +75,15 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "role", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '当前绘制任务的进度', 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 }),
|
||||
(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 }),
|
||||
(0, typeorm_1.Column)({ comment: '任务类型', nullable: true }),
|
||||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "action", void 0);
|
||||
__decorate([
|
||||
|
@ -91,11 +95,7 @@ __decorate([
|
|||
__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' }),
|
||||
(0, typeorm_1.Column)({ comment: '文件信息', nullable: true, type: 'text' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "fileInfo", void 0);
|
||||
__decorate([
|
||||
|
@ -118,6 +118,22 @@ __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", String)
|
||||
], ChatLogEntity.prototype, "taskId", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '任务数据', nullable: true, type: 'text' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "taskData", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '视频Url', nullable: true, type: 'text' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "videoUrl", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '音频Url', nullable: true, type: 'text' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatLogEntity.prototype, "audioUrl", void 0);
|
||||
ChatLogEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'chatlog' })
|
||||
], ChatLogEntity);
|
||||
|
|
17
dist/modules/chatLog/chatLog.module.js
vendored
17
dist/modules/chatLog/chatLog.module.js
vendored
|
@ -8,19 +8,26 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ChatLogModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const chatLog_service_1 = require("./chatLog.service");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const chatLog_entity_1 = require("./chatLog.entity");
|
||||
const chatLog_controller_1 = require("./chatLog.controller");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const badwords_entity_1 = require("../badwords/badwords.entity");
|
||||
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const chatLog_controller_1 = require("./chatLog.controller");
|
||||
const chatLog_entity_1 = require("./chatLog.entity");
|
||||
const chatLog_service_1 = require("./chatLog.service");
|
||||
let ChatLogModule = class ChatLogModule {
|
||||
};
|
||||
ChatLogModule = __decorate([
|
||||
(0, common_1.Global)(),
|
||||
(0, common_1.Module)({
|
||||
imports: [typeorm_1.TypeOrmModule.forFeature([chatLog_entity_1.ChatLogEntity, user_entity_1.UserEntity, badwords_entity_1.BadWordsEntity, chatGroup_entity_1.ChatGroupEntity])],
|
||||
imports: [
|
||||
typeorm_1.TypeOrmModule.forFeature([
|
||||
chatLog_entity_1.ChatLogEntity,
|
||||
user_entity_1.UserEntity,
|
||||
badwords_entity_1.BadWordsEntity,
|
||||
chatGroup_entity_1.ChatGroupEntity,
|
||||
]),
|
||||
],
|
||||
controllers: [chatLog_controller_1.ChatLogController],
|
||||
providers: [chatLog_service_1.ChatLogService],
|
||||
exports: [chatLog_service_1.ChatLogService],
|
||||
|
|
77
dist/modules/chatLog/chatLog.service.js
vendored
77
dist/modules/chatLog/chatLog.service.js
vendored
|
@ -59,7 +59,9 @@ let ChatLogService = class ChatLogService {
|
|||
if (r.type === 'paintCount') {
|
||||
const w = r.model === 'mj' ? 310 : 160;
|
||||
const imgType = r.answer.includes('cos') ? 'tencent' : 'ali';
|
||||
const compress = imgType === 'tencent' ? `?imageView2/1/w/${w}/q/55` : `?x-oss-process=image/resize,w_${w}`;
|
||||
const compress = imgType === 'tencent'
|
||||
? `?imageView2/1/w/${w}/q/55`
|
||||
: `?x-oss-process=image/resize,w_${w}`;
|
||||
r.thumbImg = r.answer + compress;
|
||||
try {
|
||||
r.fileInfo = r.fileInfo ? JSON.parse(r.fileInfo) : null;
|
||||
|
@ -73,23 +75,43 @@ let ChatLogService = class ChatLogService {
|
|||
}
|
||||
async querAllDrawLog(params) {
|
||||
const { page = 1, size = 20, rec, userId, model } = params;
|
||||
const where = { type: 2, prompt: (0, typeorm_2.Not)(''), answer: (0, typeorm_2.Not)(''), fileInfo: (0, typeorm_2.Not)(''), };
|
||||
const where = {
|
||||
type: 2,
|
||||
prompt: (0, typeorm_2.Not)(''),
|
||||
answer: (0, typeorm_2.Not)(''),
|
||||
fileInfo: (0, typeorm_2.Not)(''),
|
||||
};
|
||||
rec && Object.assign(where, { rec });
|
||||
userId && Object.assign(where, { userId });
|
||||
if (model) {
|
||||
where.model = model;
|
||||
}
|
||||
else {
|
||||
where.model = (0, typeorm_2.In)(['midjourney', 'dall-e-3', 'stable-diffusion']);
|
||||
}
|
||||
const [rows, count] = await this.chatLogEntity.findAndCount({
|
||||
order: { id: 'DESC' },
|
||||
skip: (page - 1) * size,
|
||||
take: size,
|
||||
where,
|
||||
});
|
||||
const userIds = rows
|
||||
.map((item) => item.userId)
|
||||
.filter((id) => id < 100000);
|
||||
const userInfos = await this.userEntity.find({
|
||||
where: { id: (0, typeorm_2.In)(userIds) },
|
||||
select: ['id', 'username', 'avatar', 'email'],
|
||||
});
|
||||
rows.forEach((item) => {
|
||||
item.userInfo = userInfos.find((user) => user.id === item.userId);
|
||||
});
|
||||
rows.forEach((r) => {
|
||||
var _a;
|
||||
const w = r.model === 'midjourney' ? 310 : 160;
|
||||
const imgType = r.answer.includes('cos') ? 'tencent' : 'ali';
|
||||
const compress = imgType === 'tencent' ? `?imageView2/1/w/${w}/q/55` : `?x-oss-process=image/resize,w_${w}`;
|
||||
const compress = imgType === 'tencent'
|
||||
? `?imageView2/1/w/${w}/q/55`
|
||||
: `?x-oss-process=image/resize,w_${w}`;
|
||||
r.thumbImg = r.answer + compress;
|
||||
try {
|
||||
const detailInfo = r.extend ? JSON.parse(r.extend) : null;
|
||||
|
@ -115,7 +137,9 @@ let ChatLogService = class ChatLogService {
|
|||
}
|
||||
async recDrawImg(body) {
|
||||
const { id } = body;
|
||||
const l = await this.chatLogEntity.findOne({ where: { id, type: balance_constant_1.ChatType.PAINT } });
|
||||
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);
|
||||
}
|
||||
|
@ -141,7 +165,9 @@ let ChatLogService = class ChatLogService {
|
|||
where,
|
||||
});
|
||||
const userIds = rows.map((r) => r.userId);
|
||||
const userInfos = await this.userEntity.find({ where: { id: (0, typeorm_2.In)(userIds) } });
|
||||
const userInfos = await this.userEntity.find({
|
||||
where: { id: (0, typeorm_2.In)(userIds) },
|
||||
});
|
||||
const data = rows.map((r) => {
|
||||
const userInfo = userInfos.find((u) => u.id === r.userId);
|
||||
return {
|
||||
|
@ -179,15 +205,19 @@ let ChatLogService = class ChatLogService {
|
|||
where,
|
||||
});
|
||||
const userIds = rows.map((item) => item.userId);
|
||||
const userInfo = await this.userEntity.find({ where: { id: (0, typeorm_2.In)(userIds) }, select: ['id', 'username', 'email'] });
|
||||
const userInfo = await this.userEntity.find({
|
||||
where: { id: (0, typeorm_2.In)(userIds) },
|
||||
select: ['id', 'username', 'email'],
|
||||
});
|
||||
rows.forEach((item) => {
|
||||
const { username, email } = userInfo.find((u) => u.id === item.userId) || {};
|
||||
item.username = username;
|
||||
item.email = email;
|
||||
});
|
||||
req.user.role !== 'super' && rows.forEach((t) => (t.email = (0, utils_1.maskEmail)(t.email)));
|
||||
req.user.role !== 'super' &&
|
||||
rows.forEach((t) => (t.email = (0, utils_1.maskEmail)(t.email)));
|
||||
rows.forEach((item) => {
|
||||
!item.email && (item.email = `${item === null || item === void 0 ? void 0 : item.userId}@nine.com`);
|
||||
!item.email && (item.email = `${item === null || item === void 0 ? void 0 : item.userId}@aiweb.com`);
|
||||
!item.username && (item.username = `游客${item === null || item === void 0 ? void 0 : item.userId}`);
|
||||
});
|
||||
return { rows, count };
|
||||
|
@ -198,13 +228,15 @@ let ChatLogService = class ChatLogService {
|
|||
const where = { userId: id, isDelete: false };
|
||||
groupId && Object.assign(where, { groupId });
|
||||
if (groupId) {
|
||||
const count = await this.chatGroupEntity.count({ where: { isDelete: false } });
|
||||
const count = await this.chatGroupEntity.count({
|
||||
where: { isDelete: false },
|
||||
});
|
||||
if (count === 0)
|
||||
return [];
|
||||
}
|
||||
const list = await this.chatLogEntity.find({ where });
|
||||
return list.map((item) => {
|
||||
const { prompt, role, answer, createdAt, model, modelName, type, status, action, drawId, id, fileInfo, ttsUrl, customId, pluginParam } = item;
|
||||
const { prompt, role, answer, createdAt, model, modelName, type, status, action, drawId, id, fileInfo, ttsUrl, videoUrl, audioUrl, customId, pluginParam, modelAvatar, taskData, } = item;
|
||||
return {
|
||||
chatId: id,
|
||||
dateTime: (0, utils_1.formatDate)(createdAt),
|
||||
|
@ -218,9 +250,13 @@ let ChatLogService = class ChatLogService {
|
|||
error: false,
|
||||
fileInfo: fileInfo,
|
||||
ttsUrl: ttsUrl,
|
||||
videoUrl: videoUrl,
|
||||
audioUrl: audioUrl,
|
||||
model: model,
|
||||
modelName: modelName,
|
||||
pluginParam: pluginParam,
|
||||
modelAvatar: modelAvatar,
|
||||
taskData: taskData,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -232,18 +268,23 @@ let ChatLogService = class ChatLogService {
|
|||
const list = await this.chatLogEntity.find({
|
||||
where,
|
||||
order: {
|
||||
createdAt: 'DESC'
|
||||
createdAt: 'DESC',
|
||||
},
|
||||
take: rounds * 2
|
||||
take: rounds * 2,
|
||||
});
|
||||
return list.map((item) => {
|
||||
const result = list
|
||||
.map((item) => {
|
||||
const { role, prompt, answer, fileInfo } = item;
|
||||
return {
|
||||
const record = {
|
||||
role: role,
|
||||
text: role === 'user' ? prompt : answer,
|
||||
fileInfo: fileInfo,
|
||||
};
|
||||
}).reverse();
|
||||
return record;
|
||||
})
|
||||
.reverse();
|
||||
common_1.Logger.debug('处理后的结果:', JSON.stringify(result, null, 2));
|
||||
return result;
|
||||
}
|
||||
async deleteChatLog(req, body) {
|
||||
const { id: userId } = req.user;
|
||||
|
@ -263,7 +304,9 @@ let ChatLogService = class ChatLogService {
|
|||
async delByGroupId(req, body) {
|
||||
const { groupId } = body;
|
||||
const { id } = req.user;
|
||||
const g = await this.chatGroupEntity.findOne({ where: { id: groupId, userId: id } });
|
||||
const g = await this.chatGroupEntity.findOne({
|
||||
where: { id: groupId, userId: id },
|
||||
});
|
||||
if (!g) {
|
||||
throw new common_1.HttpException('你删除的对话记录不存在、请检查!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -295,7 +338,7 @@ let ChatLogService = class ChatLogService {
|
|||
userId: userId.id,
|
||||
model,
|
||||
createdAt: (0, typeorm_2.MoreThan)(oneHourAgo),
|
||||
}
|
||||
},
|
||||
});
|
||||
adjustedUsageCount = Math.ceil(usageCount / 2);
|
||||
common_1.Logger.debug(`用户ID: ${userId.id} 模型: ${model} 一小时内已调用: ${adjustedUsageCount} 次`);
|
||||
|
|
30
dist/modules/crami/crami.module.js
vendored
30
dist/modules/crami/crami.module.js
vendored
|
@ -8,23 +8,22 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CramiModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const crami_service_1 = require("./crami.service");
|
||||
const crami_controller_1 = require("./crami.controller");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const crami_entity_1 = require("./crami.entity");
|
||||
const cramiPackage_entity_1 = require("./cramiPackage.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const userBalance_service_1 = require("../userBalance/userBalance.service");
|
||||
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 userBalance_entity_1 = require("../userBalance/userBalance.entity");
|
||||
const salesUsers_entity_1 = require("../sales/salesUsers.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");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
const config_entity_1 = require("../globalConfig/config.entity");
|
||||
const midjourney_entity_1 = require("../midjourney/midjourney.entity");
|
||||
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const accountLog_entity_1 = require("../userBalance/accountLog.entity");
|
||||
const balance_entity_1 = require("../userBalance/balance.entity");
|
||||
const fingerprint_entity_1 = require("../userBalance/fingerprint.entity");
|
||||
const userBalance_entity_1 = require("../userBalance/userBalance.entity");
|
||||
const userBalance_service_1 = require("../userBalance/userBalance.service");
|
||||
const crami_controller_1 = require("./crami.controller");
|
||||
const crami_entity_1 = require("./crami.entity");
|
||||
const crami_service_1 = require("./crami.service");
|
||||
const cramiPackage_entity_1 = require("./cramiPackage.entity");
|
||||
let CramiModule = class CramiModule {
|
||||
};
|
||||
CramiModule = __decorate([
|
||||
|
@ -40,11 +39,10 @@ CramiModule = __decorate([
|
|||
accountLog_entity_1.AccountLogEntity,
|
||||
config_entity_1.ConfigEntity,
|
||||
userBalance_entity_1.UserBalanceEntity,
|
||||
whiteList_entity_1.WhiteListEntity,
|
||||
fingerprint_entity_1.FingerprintLogEntity,
|
||||
chatLog_entity_1.ChatLogEntity,
|
||||
chatGroup_entity_1.ChatGroupEntity,
|
||||
midjourney_entity_1.MidjourneyEntity
|
||||
midjourney_entity_1.MidjourneyEntity,
|
||||
]),
|
||||
],
|
||||
providers: [crami_service_1.CramiService, userBalance_service_1.UserBalanceService],
|
||||
|
|
20
dist/modules/database/database.module.js
vendored
20
dist/modules/database/database.module.js
vendored
|
@ -13,13 +13,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.DatabaseModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const nestjs_config_1 = require("nestjs-config");
|
||||
const typeorm_2 = require("typeorm");
|
||||
const database_service_1 = require("./database.service");
|
||||
let DatabaseModule = DatabaseModule_1 = class DatabaseModule {
|
||||
constructor(connection, config) {
|
||||
constructor(connection) {
|
||||
this.connection = connection;
|
||||
this.config = config;
|
||||
this.logger = new common_1.Logger(DatabaseModule_1.name);
|
||||
}
|
||||
onModuleInit() {
|
||||
|
@ -31,12 +29,22 @@ DatabaseModule = DatabaseModule_1 = __decorate([
|
|||
(0, common_1.Module)({
|
||||
imports: [
|
||||
typeorm_1.TypeOrmModule.forRootAsync({
|
||||
useFactory: (config) => config.get('database'),
|
||||
inject: [nestjs_config_1.ConfigService],
|
||||
useFactory: () => ({
|
||||
type: 'mysql',
|
||||
host: process.env.DB_HOST,
|
||||
port: parseInt(process.env.DB_PORT, 10),
|
||||
username: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_DATABASE,
|
||||
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
|
||||
logging: false,
|
||||
charset: 'utf8mb4',
|
||||
timezone: '+08:00',
|
||||
}),
|
||||
}),
|
||||
],
|
||||
providers: [database_service_1.DatabaseService],
|
||||
}),
|
||||
__metadata("design:paramtypes", [typeorm_2.Connection, nestjs_config_1.ConfigService])
|
||||
__metadata("design:paramtypes", [typeorm_2.DataSource])
|
||||
], DatabaseModule);
|
||||
exports.DatabaseModule = DatabaseModule;
|
||||
|
|
181
dist/modules/database/database.service.js
vendored
181
dist/modules/database/database.service.js
vendored
|
@ -29,8 +29,22 @@ let DatabaseService = class DatabaseService {
|
|||
const adminPassword = bcrypt.hashSync('123456', 10);
|
||||
const superEmail = 'super';
|
||||
const adminEmail = 'admin';
|
||||
const superUserinfo = { username: 'super', password: superPassword, status: 1, email: superEmail, sex: 1, role: 'super' };
|
||||
const adminUserinfo = { username: 'admin', password: adminPassword, status: 0, email: adminEmail, sex: 1, role: 'admin' };
|
||||
const superUserinfo = {
|
||||
username: 'super',
|
||||
password: superPassword,
|
||||
status: 1,
|
||||
email: superEmail,
|
||||
sex: 1,
|
||||
role: 'super',
|
||||
};
|
||||
const adminUserinfo = {
|
||||
username: 'admin',
|
||||
password: adminPassword,
|
||||
status: 0,
|
||||
email: adminEmail,
|
||||
sex: 1,
|
||||
role: 'admin',
|
||||
};
|
||||
await this.createDefaultUser(superUserinfo);
|
||||
await this.createDefaultUser(adminUserinfo);
|
||||
}
|
||||
|
@ -41,7 +55,7 @@ let DatabaseService = class DatabaseService {
|
|||
const user = await this.connection.query(`INSERT INTO users (username, password, status, email, role) VALUES ('${username}', '${password}', '${status}', '${email}', '${role}')`);
|
||||
const userId = user.insertId;
|
||||
const balance = await this.connection.query(`INSERT INTO balance (userId, balance, usesLeft, paintCount) VALUES ('${userId}', 0, 1000, 100)`);
|
||||
common_1.Logger.log(`初始化创建${role}用户成功、用户名为[${username}]、初始密码为[${username === 'super' ? 'nine-super' : '123456'}] ==============> 请注意查阅`, 'DatabaseService');
|
||||
common_1.Logger.log(`初始化创建${role}用户成功、用户名为[${username}]、初始密码为[${username === 'super' ? 'super' : '123456'}] ==============> 请注意查阅`, 'DatabaseService');
|
||||
}
|
||||
catch (error) {
|
||||
console.log('error: ', error);
|
||||
|
@ -49,9 +63,17 @@ let DatabaseService = class DatabaseService {
|
|||
}
|
||||
}
|
||||
async checkSiteBaseConfig() {
|
||||
const keys = ['siteName', 'qqNumber', 'vxNumber', 'robotAvatar', 'userDefautlAvatar'];
|
||||
const keys = [
|
||||
'siteName',
|
||||
'qqNumber',
|
||||
'vxNumber',
|
||||
'robotAvatar',
|
||||
'userDefautlAvatar',
|
||||
];
|
||||
const result = await this.connection.query(`
|
||||
SELECT COUNT(*) AS count FROM config WHERE \`configKey\` IN (${keys.map((k) => `'${k}'`).join(',')})
|
||||
SELECT COUNT(*) AS count FROM config WHERE \`configKey\` IN (${keys
|
||||
.map((k) => `'${k}'`)
|
||||
.join(',')})
|
||||
`);
|
||||
const count = parseInt(result[0].count);
|
||||
if (count === 0) {
|
||||
|
@ -87,27 +109,112 @@ let DatabaseService = class DatabaseService {
|
|||
encry: 0,
|
||||
},
|
||||
{ configKey: 'buyCramiAddress', configVal: '', public: 1, encry: 0 },
|
||||
{ configKey: 'openaiBaseUrl', configVal: 'https://api.lightai.io', public: 0, 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: '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: 'registerSendStatus', configVal: '1', public: 1, encry: 0 },
|
||||
{ configKey: 'registerSendModel3Count', configVal: '30', public: 1, encry: 0 },
|
||||
{ configKey: 'registerSendModel4Count', configVal: '3', public: 1, encry: 0 },
|
||||
{ configKey: 'registerSendDrawMjCount', configVal: '3', public: 1, encry: 0 },
|
||||
{ configKey: 'firstRegisterSendStatus', configVal: '1', public: 1, encry: 0 },
|
||||
{ configKey: 'firstRegisterSendRank', configVal: '500', public: 1, encry: 0 },
|
||||
{ configKey: 'firstRregisterSendModel3Count', configVal: '10', public: 1, encry: 0 },
|
||||
{ configKey: 'firstRregisterSendModel4Count', configVal: '10', public: 1, encry: 0 },
|
||||
{ configKey: 'firstRregisterSendDrawMjCount', configVal: '10', public: 1, encry: 0 },
|
||||
{
|
||||
configKey: 'registerSendStatus',
|
||||
configVal: '1',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'registerSendModel3Count',
|
||||
configVal: '30',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'registerSendModel4Count',
|
||||
configVal: '3',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'registerSendDrawMjCount',
|
||||
configVal: '3',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'firstRegisterSendStatus',
|
||||
configVal: '1',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'firstRegisterSendRank',
|
||||
configVal: '500',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'firstRregisterSendModel3Count',
|
||||
configVal: '10',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'firstRregisterSendModel4Count',
|
||||
configVal: '10',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'firstRregisterSendDrawMjCount',
|
||||
configVal: '10',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{ configKey: 'inviteSendStatus', configVal: '1', public: 1, encry: 0 },
|
||||
{ configKey: 'inviteGiveSendModel3Count', configVal: '0', public: 1, encry: 0 },
|
||||
{ configKey: 'inviteGiveSendModel4Count', configVal: '0', public: 1, encry: 0 },
|
||||
{ configKey: 'inviteGiveSendDrawMjCount', configVal: '0', public: 1, encry: 0 },
|
||||
{ configKey: 'invitedGuestSendModel3Count', configVal: '10', public: 1, encry: 0 },
|
||||
{ configKey: 'invitedGuestSendModel4Count', configVal: '10', public: 1, encry: 0 },
|
||||
{ configKey: 'invitedGuestSendDrawMjCount', configVal: '10', public: 1, encry: 0 },
|
||||
{
|
||||
configKey: 'inviteGiveSendModel3Count',
|
||||
configVal: '0',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'inviteGiveSendModel4Count',
|
||||
configVal: '0',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'inviteGiveSendDrawMjCount',
|
||||
configVal: '0',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'invitedGuestSendModel3Count',
|
||||
configVal: '10',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'invitedGuestSendModel4Count',
|
||||
configVal: '10',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{
|
||||
configKey: 'invitedGuestSendDrawMjCount',
|
||||
configVal: '10',
|
||||
public: 1,
|
||||
encry: 0,
|
||||
},
|
||||
{ configKey: 'isVerifyEmail', configVal: '1', public: 1, encry: 0 },
|
||||
];
|
||||
const res = await this.connection.query(`INSERT INTO config (configKey, configVal, public, encry) VALUES ${defaultConfig
|
||||
|
@ -122,15 +229,39 @@ let DatabaseService = class DatabaseService {
|
|||
}
|
||||
async createSystemReservedApps() {
|
||||
const systemApps = [
|
||||
{ name: "提示词优化PromptOptimization", catId: 9900, des: "PromptOptimization", preset: "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.", appModel: "gpt-3.5-turbo", isFixedModel: 1, isSystemReserved: 1 },
|
||||
{ name: "思维导图MindMap", catId: 9900, des: "MindMap", preset: "我希望你使用markdown格式回答我得问题、我的需求是得到一份markdown格式的大纲、尽量做的精细、层级多一点、不管我问你什么、都需要您回复我一个大纲出来、我想使用大纲做思维导图、除了大纲之外、不要无关内容和总结。", appModel: "gpt-3.5-turbo", isFixedModel: 1, isSystemReserved: 1 },
|
||||
{
|
||||
name: '提示词优化PromptOptimization',
|
||||
catId: 9900,
|
||||
des: 'PromptOptimization',
|
||||
preset: "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.",
|
||||
appModel: 'gpt-3.5-turbo',
|
||||
isFixedModel: 1,
|
||||
isSystemReserved: 1,
|
||||
},
|
||||
{
|
||||
name: '思维导图MindMap',
|
||||
catId: 9900,
|
||||
des: 'MindMap',
|
||||
preset: '我希望你使用markdown格式回答我得问题、我的需求是得到一份markdown格式的大纲、尽量做的精细、层级多一点、不管我问你什么、都需要您回复我一个大纲出来、我想使用大纲做思维导图、除了大纲之外、不要无关内容和总结。',
|
||||
appModel: 'gpt-3.5-turbo',
|
||||
isFixedModel: 1,
|
||||
isSystemReserved: 1,
|
||||
},
|
||||
];
|
||||
try {
|
||||
for (const app of systemApps) {
|
||||
const result = await this.connection.query(`SELECT COUNT(*) AS count FROM app WHERE name = ? AND des = ? AND isSystemReserved = ?`, [app.name, app.des, app.isSystemReserved]);
|
||||
const count = parseInt(result[0].count, 10);
|
||||
if (count === 0) {
|
||||
await this.connection.query(`INSERT INTO app (name, catId, des, preset, appModel, isFixedModel, isSystemReserved) VALUES (?, ?, ?, ?, ?, ?, ?)`, [app.name, app.catId, app.des, app.preset, app.appModel, app.isFixedModel, app.isSystemReserved]);
|
||||
await this.connection.query(`INSERT INTO app (name, catId, des, preset, appModel, isFixedModel, isSystemReserved) VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
||||
app.name,
|
||||
app.catId,
|
||||
app.des,
|
||||
app.preset,
|
||||
app.appModel,
|
||||
app.isFixedModel,
|
||||
app.isSystemReserved,
|
||||
]);
|
||||
common_1.Logger.log(`系统预留应用${app.name}创建成功`, 'DatabaseService');
|
||||
}
|
||||
}
|
||||
|
|
90
dist/modules/database/initDatabase.js
vendored
90
dist/modules/database/initDatabase.js
vendored
|
@ -1,23 +1,95 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.initDatabase = void 0;
|
||||
const mysql = require("mysql2/promise");
|
||||
const common_1 = require("@nestjs/common");
|
||||
function initDatabase() {
|
||||
mysql
|
||||
.createConnection({
|
||||
const dotenv_1 = require("dotenv");
|
||||
const mysql = require("mysql2/promise");
|
||||
const typeorm_1 = require("typeorm");
|
||||
(0, dotenv_1.config)();
|
||||
const dataSourceOptions = {
|
||||
type: 'mysql',
|
||||
port: parseInt(process.env.DB_PORT, 10),
|
||||
host: process.env.DB_HOST,
|
||||
username: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_DATABASE,
|
||||
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
|
||||
logging: false,
|
||||
synchronize: true,
|
||||
charset: 'utf8mb4',
|
||||
timezone: '+08:00',
|
||||
};
|
||||
async function validateDatabase() {
|
||||
const conn = await mysql.createConnection({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
port: parseInt(process.env.DB_PORT),
|
||||
})
|
||||
.then(async (conn) => {
|
||||
const [rows] = await conn.execute(`SHOW DATABASES LIKE '${process.env.DB_DATABASE}'`);
|
||||
port: parseInt(process.env.DB_PORT, 10),
|
||||
});
|
||||
try {
|
||||
const [rows] = (await conn.execute(`SHOW DATABASES LIKE '${process.env.DB_DATABASE}'`));
|
||||
if (Array.isArray(rows) && rows.length === 0) {
|
||||
await conn.execute(`CREATE DATABASE ${process.env.DB_DATABASE}`);
|
||||
common_1.Logger.log(`数据库创建成功[${process.env.DB_DATABASE}]`);
|
||||
common_1.Logger.log(`数据库创建成功[${process.env.DB_DATABASE}]`, 'Database');
|
||||
}
|
||||
else {
|
||||
common_1.Logger.log(`数据库已存在[${process.env.DB_DATABASE}]`, 'Database');
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error('Error during database validation:', error, 'Database');
|
||||
}
|
||||
finally {
|
||||
await conn.end();
|
||||
}
|
||||
}
|
||||
async function updateColumnType() {
|
||||
const conn = await mysql.createConnection({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
port: parseInt(process.env.DB_PORT, 10),
|
||||
database: process.env.DB_DATABASE,
|
||||
});
|
||||
async function checkAndUpdateColumnType(tableName, columnName) {
|
||||
try {
|
||||
const [rows] = (await conn.execute(`SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND COLUMN_NAME = ?`, [tableName, columnName]));
|
||||
if (rows.length > 0 && rows[0].DATA_TYPE !== 'text') {
|
||||
await conn.execute(`ALTER TABLE ?? MODIFY COLUMN ?? TEXT`, [
|
||||
tableName,
|
||||
columnName,
|
||||
]);
|
||||
common_1.Logger.log(`Column ${columnName} type updated to TEXT in table ${tableName}`, 'Database');
|
||||
}
|
||||
else {
|
||||
common_1.Logger.log(`Column ${columnName} is already of type TEXT in table ${tableName}`, 'Database');
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error(`Error updating column type in table ${tableName}:`, error);
|
||||
}
|
||||
}
|
||||
try {
|
||||
await checkAndUpdateColumnType('config', 'configVal');
|
||||
await checkAndUpdateColumnType('app', 'coverImg');
|
||||
}
|
||||
finally {
|
||||
await conn.end();
|
||||
}
|
||||
}
|
||||
async function initDatabase() {
|
||||
await validateDatabase();
|
||||
await updateColumnType();
|
||||
const dataSource = new typeorm_1.DataSource(dataSourceOptions);
|
||||
try {
|
||||
await dataSource.initialize();
|
||||
common_1.Logger.log('Database connected and synchronized successfully', 'Database');
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error('Error during TypeORM initialization:', error);
|
||||
}
|
||||
finally {
|
||||
await dataSource.destroy();
|
||||
}
|
||||
}
|
||||
exports.initDatabase = initDatabase;
|
||||
|
|
14
dist/modules/globalConfig/config.entity.js
vendored
14
dist/modules/globalConfig/config.entity.js
vendored
|
@ -10,8 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ConfigEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
const typeorm_1 = require("typeorm");
|
||||
let ConfigEntity = class ConfigEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
|
@ -19,15 +19,21 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], ConfigEntity.prototype, "configKey", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ length: 3000, comment: '配置内容', nullable: true }),
|
||||
(0, typeorm_1.Column)({ type: 'text', comment: '配置内容', nullable: true }),
|
||||
__metadata("design:type", String)
|
||||
], ConfigEntity.prototype, "configVal", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ default: 0, comment: '配置是否公开,公开内容对前端项目展示 0:不公开 1:公开' }),
|
||||
(0, typeorm_1.Column)({
|
||||
default: 0,
|
||||
comment: '配置是否公开,公开内容对前端项目展示 0:不公开 1:公开',
|
||||
}),
|
||||
__metadata("design:type", Number)
|
||||
], ConfigEntity.prototype, "public", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ default: 0, comment: '配置是否加密,加密内容仅仅super权限可看 0:不加 1:加' }),
|
||||
(0, typeorm_1.Column)({
|
||||
default: 0,
|
||||
comment: '配置是否加密,加密内容仅仅super权限可看 0:不加 1:加',
|
||||
}),
|
||||
__metadata("design:type", Number)
|
||||
], ConfigEntity.prototype, "encry", void 0);
|
||||
__decorate([
|
||||
|
|
|
@ -10,13 +10,16 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SetConfigDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
const class_transformer_1 = require("class-transformer");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const class_transformer_1 = require("class-transformer");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class SetConfigDto {
|
||||
}
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: [{ configKey: 'siteName', configVal: 'NineAI' }], description: '设置配置信息' }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: [{ configKey: 'siteName', configVal: 'AIWeb' }],
|
||||
description: '设置配置信息',
|
||||
}),
|
||||
(0, class_validator_1.IsArray)(),
|
||||
(0, class_validator_1.ArrayNotEmpty)(),
|
||||
(0, class_validator_1.ValidateNested)({ each: true }),
|
||||
|
|
|
@ -10,13 +10,16 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SetConfigCustomDto = void 0;
|
||||
const class_validator_1 = require("class-validator");
|
||||
const class_transformer_1 = require("class-transformer");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const class_transformer_1 = require("class-transformer");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class SetConfigCustomDto {
|
||||
}
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: { configKey: 'siteName', configVal: 'NineAI', infoKey: 'NineAI' }, description: '设置更新配置信息' }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: { configKey: 'siteName', configVal: 'AIWeb', infoKey: 'AIWeb' },
|
||||
description: '设置更新配置信息',
|
||||
}),
|
||||
(0, class_validator_1.ValidateNested)({ each: true }),
|
||||
(0, class_transformer_1.Type)(() => Object),
|
||||
__metadata("design:type", Object)
|
||||
|
|
123
dist/modules/globalConfig/globalConfig.service.js
vendored
123
dist/modules/globalConfig/globalConfig.service.js
vendored
|
@ -32,7 +32,6 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
this.chatLogEntity = chatLogEntity;
|
||||
this.modelsService = modelsService;
|
||||
this.globalConfigs = {};
|
||||
this.nineAiToken = true;
|
||||
}
|
||||
async onModuleInit() {
|
||||
await this.initGetAllConfig();
|
||||
|
@ -64,11 +63,17 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
this.initBaiduSensitive();
|
||||
}
|
||||
async initBaiduSensitive(isInit = true) {
|
||||
const { baiduTextApiKey, baiduTextSecretKey } = await this.getConfigs(['baiduTextApiKey', 'baiduTextSecretKey']);
|
||||
const { baiduTextApiKey, baiduTextSecretKey } = await this.getConfigs([
|
||||
'baiduTextApiKey',
|
||||
'baiduTextSecretKey',
|
||||
]);
|
||||
if (!baiduTextApiKey || !baiduTextSecretKey) {
|
||||
return;
|
||||
}
|
||||
const headers = { 'Content-Type': 'application/json', Accept: 'application/json' };
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
};
|
||||
const url = `https://aip.baidubce.com/oauth/2.0/token?client_id=${baiduTextApiKey}&client_secret=${baiduTextSecretKey}&grant_type=client_credentials`;
|
||||
try {
|
||||
const response = await axios_1.default.post(url, { headers });
|
||||
|
@ -96,7 +101,8 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
this.wechatAccessToken = '';
|
||||
return;
|
||||
}
|
||||
const { data: { errmsg, access_token }, } = await axios_1.default.get(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${secret}`);
|
||||
const Url = (0, utils_1.formatUrl)(process.env.weChatApiUrl || 'https://api.weixin.qq.com');
|
||||
const { data: { errmsg, access_token }, } = await axios_1.default.get(`${Url}/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${secret}`);
|
||||
if (errmsg) {
|
||||
if (isInit) {
|
||||
common_1.Logger.error(`获取微信access_token失败、错误信息:${errmsg}`, 'OfficialService');
|
||||
|
@ -114,7 +120,8 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
this.wechatJsapiTicket = '';
|
||||
return;
|
||||
}
|
||||
const res = await axios_1.default.get(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`);
|
||||
const Url = (0, utils_1.formatUrl)(process.env.weChatApiUrl || 'https://api.weixin.qq.com');
|
||||
const res = await axios_1.default.get(`${Url}/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`);
|
||||
return (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.ticket;
|
||||
}
|
||||
async queryAllConfig(req) {
|
||||
|
@ -166,8 +173,6 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
'salesAllowDrawMoney',
|
||||
'companyName',
|
||||
'filingNumber',
|
||||
'phoneRegisterStatus',
|
||||
'emailRegisterStatus',
|
||||
'emailLoginStatus',
|
||||
'phoneLoginStatus',
|
||||
'wechatRegisterStatus',
|
||||
|
@ -177,17 +182,33 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
'signInModel4Count',
|
||||
'signInMjDrawToken',
|
||||
'appMenuHeaderTips',
|
||||
'appMenuHeaderBgUrl',
|
||||
'pluginFirst',
|
||||
'mjUseBaiduFy',
|
||||
'mjHideNotBlock',
|
||||
'mjHideWorkIn',
|
||||
'isVerifyEmail',
|
||||
'isHideSidebar',
|
||||
'isHideTts',
|
||||
'isHideModel3Point',
|
||||
'isHideModel4Point',
|
||||
'isHideDrawMjPoint',
|
||||
'model3Name',
|
||||
'model4Name',
|
||||
'drawMjName',
|
||||
'isModelInherited',
|
||||
'noVerifyRegister',
|
||||
];
|
||||
const data = await this.configEntity.find({ where: { configKey: (0, typeorm_2.In)(allowKeys) } });
|
||||
const data = await this.configEntity.find({
|
||||
where: { configKey: (0, typeorm_2.In)(allowKeys) },
|
||||
});
|
||||
const { domain } = query;
|
||||
const domainDb = this.globalConfigs['domain'];
|
||||
if (domainDb !== domain) {
|
||||
this.createOrUpdate({ configKey: `domain`, configVal: domain, status: 1 });
|
||||
this.createOrUpdate({
|
||||
configKey: `domain`,
|
||||
configVal: domain,
|
||||
status: 1,
|
||||
});
|
||||
await this.initGetAllConfig();
|
||||
}
|
||||
const publicConfig = data.reduce((prev, cur) => {
|
||||
|
@ -200,7 +221,9 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
}
|
||||
async queryGptKeys(req) {
|
||||
const { role } = req.user;
|
||||
const data = await this.configEntity.find({ where: { configKey: (0, typeorm_2.Like)(`%${'chatGptKey'}%`) } });
|
||||
const data = await this.configEntity.find({
|
||||
where: { configKey: (0, typeorm_2.Like)(`%${'chatGptKey'}%`) },
|
||||
});
|
||||
if (role === 'super')
|
||||
return data;
|
||||
return data.map((t) => {
|
||||
|
@ -213,9 +236,15 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
const keys = effectiveConfig.map((t) => t.configKey);
|
||||
for (const [index, value] of effectiveConfig.entries()) {
|
||||
const { configKey, configVal, status } = value;
|
||||
await this.createOrUpdate({ configKey: `chatGptKey:${index + 1}`, configVal, status });
|
||||
await this.createOrUpdate({
|
||||
configKey: `chatGptKey:${index + 1}`,
|
||||
configVal,
|
||||
status,
|
||||
});
|
||||
}
|
||||
const likeChatGptKeys = await this.configEntity.find({ where: { configKey: (0, typeorm_2.Like)(`%${'chatGptKey'}%`) } });
|
||||
const likeChatGptKeys = await this.configEntity.find({
|
||||
where: { configKey: (0, typeorm_2.Like)(`%${'chatGptKey'}%`) },
|
||||
});
|
||||
const allKey = likeChatGptKeys.map((t) => t.configKey);
|
||||
if (allKey.length > keys.length) {
|
||||
const diffKey = (0, utils_1.getDiffArray)(allKey.length, keys.length, 'chatGptKey:');
|
||||
|
@ -229,7 +258,9 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
async queryConfig(body, req) {
|
||||
const { role } = req.user;
|
||||
const { keys } = body;
|
||||
const data = await this.configEntity.find({ where: { configKey: (0, typeorm_2.In)(keys) } });
|
||||
const data = await this.configEntity.find({
|
||||
where: { configKey: (0, typeorm_2.In)(keys) },
|
||||
});
|
||||
if (role !== 'super') {
|
||||
data.forEach((item) => {
|
||||
if (item.configKey.includes('mj') ||
|
||||
|
@ -247,8 +278,14 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
if (longKeys.includes(item.configKey)) {
|
||||
return (item.configVal = (0, utils_1.hideString)(item.configVal, '隐私内容、非超级管理员无权查看'));
|
||||
}
|
||||
const whiteListKey = ['payEpayStatus', 'payHupiStatus', 'mjProxy', 'payLtzfStatus'];
|
||||
if (!whiteListKey.includes(item.configKey) && !item.configKey.includes('Status')) {
|
||||
const whiteListKey = [
|
||||
'payEpayStatus',
|
||||
'payHupiStatus',
|
||||
'mjProxy',
|
||||
'payLtzfStatus',
|
||||
];
|
||||
if (!whiteListKey.includes(item.configKey) &&
|
||||
!item.configKey.includes('Status')) {
|
||||
item.configVal = (0, utils_1.hideString)(item.configVal);
|
||||
}
|
||||
}
|
||||
|
@ -259,11 +296,6 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
return prev;
|
||||
}, {});
|
||||
}
|
||||
getNineAiToken() {
|
||||
const MjdrawCount = this.globalConfigs['MjdrawCount'];
|
||||
const auth = this.nineAiToken;
|
||||
return !auth || Number(MjdrawCount) === 1;
|
||||
}
|
||||
async setConfig(body) {
|
||||
try {
|
||||
const { settings } = body;
|
||||
|
@ -272,10 +304,12 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
}
|
||||
await this.initGetAllConfig();
|
||||
const keys = settings.map((t) => t.configKey);
|
||||
if (keys.includes('baiduTextApiKey') || keys.includes('baiduTextSecretKey')) {
|
||||
if (keys.includes('baiduTextApiKey') ||
|
||||
keys.includes('baiduTextSecretKey')) {
|
||||
await this.initBaiduSensitive(false);
|
||||
}
|
||||
if (keys.includes('wechatOfficialAppId') || keys.includes('wechatOfficialAppSecret')) {
|
||||
if (keys.includes('wechatOfficialAppId') ||
|
||||
keys.includes('wechatOfficialAppSecret')) {
|
||||
await this.getWechatAccessToken();
|
||||
}
|
||||
return '设置完成!';
|
||||
|
@ -292,7 +326,11 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
const res = await this.configEntity.update({ configKey }, { configVal, status });
|
||||
}
|
||||
else {
|
||||
const save = await this.configEntity.save({ configKey, configVal, status });
|
||||
const save = await this.configEntity.save({
|
||||
configKey,
|
||||
configVal,
|
||||
status,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
|
@ -307,8 +345,20 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
return await this.getConfigs(['copyrightUrl', 'copyrightTitle']);
|
||||
}
|
||||
async queryPayType() {
|
||||
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)) {
|
||||
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) {
|
||||
|
@ -338,7 +388,7 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
return { siteName, qqNumber, vxNumber, registerBaseUrl, domain };
|
||||
}
|
||||
async getPhoneVerifyConfig() {
|
||||
const { phoneRegisterStatus, aliPhoneAccessKeyId, aliPhoneAccessKeySecret, aliPhoneSignName, aliPhoneTemplateCode } = await this.getConfigs([
|
||||
const { phoneRegisterStatus, aliPhoneAccessKeyId, aliPhoneAccessKeySecret, aliPhoneSignName, aliPhoneTemplateCode, } = await this.getConfigs([
|
||||
'phoneRegisterStatus',
|
||||
'aliPhoneAccessKeyId',
|
||||
'aliPhoneAccessKeySecret',
|
||||
|
@ -359,7 +409,12 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
return process.env.NAMESPACE || 'AIWeb';
|
||||
}
|
||||
async getSignatureGiftConfig() {
|
||||
const { signInStatus = 0, signInModel3Count = 0, signInModel4Count = 0, signInMjDrawToken = 0, } = await this.getConfigs(['signInStatus', 'signInModel3Count', 'signInModel4Count', 'signInMjDrawToken']);
|
||||
const { signInStatus = 0, signInModel3Count = 0, signInModel4Count = 0, signInMjDrawToken = 0, } = await this.getConfigs([
|
||||
'signInStatus',
|
||||
'signInModel3Count',
|
||||
'signInModel4Count',
|
||||
'signInMjDrawToken',
|
||||
]);
|
||||
if (Number(signInStatus) !== 1) {
|
||||
throw new common_1.HttpException('签到功能暂未开放!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -374,18 +429,10 @@ let GlobalConfigService = class GlobalConfigService {
|
|||
const response = await fetch(api, {});
|
||||
const responseData = await response.json();
|
||||
const { success = true, message } = responseData;
|
||||
common_1.Logger.error('请按要求填写正确的授权信息');
|
||||
common_1.Logger.error('请填写您的授权码');
|
||||
common_1.Logger.error('缺失ip信息');
|
||||
common_1.Logger.error('缺失ip信息');
|
||||
common_1.Logger.debug('感谢您使用NineAi、祝您使用愉快~');
|
||||
common_1.Logger.debug('感谢您使用AIWeb,祝您使用愉快~');
|
||||
}
|
||||
async getSensitiveConfig() {
|
||||
const { baiduTextStatus = 0, baiduTextAccessToken, nineaiBuiltInSensitiveAuthKey, } = await this.getConfigs([
|
||||
'baiduTextStatus',
|
||||
'baiduTextAccessToken',
|
||||
'nineaiBuiltInSensitiveAuthKey',
|
||||
]);
|
||||
const { baiduTextStatus = 0, baiduTextAccessToken } = await this.getConfigs(['baiduTextStatus', 'baiduTextAccessToken']);
|
||||
if (Number(baiduTextStatus) === 1) {
|
||||
return {
|
||||
useType: 'baidu',
|
||||
|
|
|
@ -1,16 +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.KnowledgeBaseController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
let KnowledgeBaseController = class KnowledgeBaseController {
|
||||
};
|
||||
KnowledgeBaseController = __decorate([
|
||||
(0, common_1.Controller)('knowledgeBase')
|
||||
], KnowledgeBaseController);
|
||||
exports.KnowledgeBaseController = KnowledgeBaseController;
|
|
@ -1,17 +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.KnowledgeBaseEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
let KnowledgeBaseEntity = class KnowledgeBaseEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
KnowledgeBaseEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'knowledge_base' })
|
||||
], KnowledgeBaseEntity);
|
||||
exports.KnowledgeBaseEntity = KnowledgeBaseEntity;
|
|
@ -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;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.KnowledgeBaseModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const knowledgeBase_controller_1 = require("./knowledgeBase.controller");
|
||||
const knowledgeBase_service_1 = require("./knowledgeBase.service");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const knowledgeBase_entity_1 = require("./knowledgeBase.entity");
|
||||
let KnowledgeBaseModule = class KnowledgeBaseModule {
|
||||
};
|
||||
KnowledgeBaseModule = __decorate([
|
||||
(0, common_1.Global)(),
|
||||
(0, common_1.Module)({
|
||||
imports: [typeorm_1.TypeOrmModule.forFeature([knowledgeBase_entity_1.KnowledgeBaseEntity])],
|
||||
providers: [knowledgeBase_service_1.KnowledgeBaseService],
|
||||
controllers: [knowledgeBase_controller_1.KnowledgeBaseController],
|
||||
exports: [knowledgeBase_service_1.KnowledgeBaseService],
|
||||
})
|
||||
], KnowledgeBaseModule);
|
||||
exports.KnowledgeBaseModule = KnowledgeBaseModule;
|
|
@ -10,8 +10,8 @@ var __metadata = (this && this.__metadata) || function (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");
|
||||
const class_validator_1 = require("class-validator");
|
||||
class MjDrawDto {
|
||||
}
|
||||
__decorate([
|
||||
|
@ -24,17 +24,26 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], MjDrawDto.prototype, "prompt", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: '--ar 16:9 --c 0', description: '除了prompt的额外参数' }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: '--ar 16:9 --c 0',
|
||||
description: '除了prompt的额外参数',
|
||||
}),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], MjDrawDto.prototype, "extraParam", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'https://xsdasdasd.com', description: '垫图图片地址' }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: 'https://xsdasdasd.com',
|
||||
description: '垫图图片地址',
|
||||
}),
|
||||
(0, class_validator_1.IsOptional)(),
|
||||
__metadata("design:type", String)
|
||||
], MjDrawDto.prototype, "imgUrl", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'IMAGINE', description: '任务类型,可用值:IMAGINE,UPSCALE,VARIATION,ZOOM,PAN,DESCRIBE,BLEND,SHORTEN,SWAP_FACE' }),
|
||||
(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)
|
||||
], MjDrawDto.prototype, "action", void 0);
|
21
dist/modules/midjourney/midjourney.controller.js
vendored
21
dist/modules/midjourney/midjourney.controller.js
vendored
|
@ -13,14 +13,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MidjourneyController = void 0;
|
||||
const superAuth_guard_1 = require("../../common/auth/superAuth.guard");
|
||||
const midjourney_service_1 = require("./midjourney.service");
|
||||
const adminAuth_guard_1 = require("../../common/auth/adminAuth.guard");
|
||||
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
|
||||
const superAuth_guard_1 = require("../../common/auth/superAuth.guard");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const axios_1 = require("axios");
|
||||
const getList_dto_1 = require("./dto/getList.dto");
|
||||
const adminAuth_guard_1 = require("../../common/auth/adminAuth.guard");
|
||||
const mjDraw_dto_1 = require("./dto/mjDraw.dto");
|
||||
const midjourney_service_1 = require("./midjourney.service");
|
||||
let MidjourneyController = class MidjourneyController {
|
||||
constructor(midjourneyService) {
|
||||
this.midjourneyService = midjourneyService;
|
||||
|
@ -64,6 +65,9 @@ let MidjourneyController = class MidjourneyController {
|
|||
async proxyImg(params) {
|
||||
return await this.midjourneyService.proxyImg(params);
|
||||
}
|
||||
async mjDraw(body, req) {
|
||||
return await this.midjourneyService.addMjDrawQueue(body, req);
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
(0, common_1.Get)('drawList'),
|
||||
|
@ -182,6 +186,17 @@ __decorate([
|
|||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], MidjourneyController.prototype, "proxyImg", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('addMjDrawQueue'),
|
||||
(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", [mjDraw_dto_1.MjDrawDto, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], MidjourneyController.prototype, "mjDraw", null);
|
||||
MidjourneyController = __decorate([
|
||||
(0, common_1.Controller)('midjourney'),
|
||||
__metadata("design:paramtypes", [midjourney_service_1.MidjourneyService])
|
||||
|
|
28
dist/modules/midjourney/midjourney.module.js
vendored
28
dist/modules/midjourney/midjourney.module.js
vendored
|
@ -7,20 +7,38 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MidjourneyModule = void 0;
|
||||
const bull_1 = require("@nestjs/bull");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const midjourney_controller_1 = require("./midjourney.controller");
|
||||
const midjourney_service_1 = require("./midjourney.service");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const midjourney_entity_1 = require("./midjourney.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const redisCache_service_1 = require("../redisCache/redisCache.service");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const midjourney_controller_1 = require("./midjourney.controller");
|
||||
const midjourney_entity_1 = require("./midjourney.entity");
|
||||
const midjourney_service_1 = require("./midjourney.service");
|
||||
const prompt_entity_1 = require("./prompt.entity");
|
||||
let MidjourneyModule = class MidjourneyModule {
|
||||
};
|
||||
MidjourneyModule = __decorate([
|
||||
(0, common_1.Global)(),
|
||||
(0, common_1.Module)({
|
||||
imports: [typeorm_1.TypeOrmModule.forFeature([midjourney_entity_1.MidjourneyEntity, user_entity_1.UserEntity, prompt_entity_1.mjPromptEntity])],
|
||||
imports: [
|
||||
bull_1.BullModule.registerQueueAsync({
|
||||
name: 'MJDRAW',
|
||||
useFactory: () => {
|
||||
const config = {
|
||||
port: +process.env.REDIS_PORT,
|
||||
host: process.env.REDIS_HOST,
|
||||
db: Number(process.env.REDIS_DB || 0),
|
||||
};
|
||||
process.env.REDIS_PASSWORD &&
|
||||
(config.password = process.env.REDIS_PASSWORD);
|
||||
return {
|
||||
redis: config,
|
||||
};
|
||||
},
|
||||
}),
|
||||
typeorm_1.TypeOrmModule.forFeature([midjourney_entity_1.MidjourneyEntity, user_entity_1.UserEntity, prompt_entity_1.mjPromptEntity]),
|
||||
],
|
||||
controllers: [midjourney_controller_1.MidjourneyController],
|
||||
providers: [midjourney_service_1.MidjourneyService, redisCache_service_1.RedisCacheService],
|
||||
exports: [midjourney_service_1.MidjourneyService],
|
||||
|
|
239
dist/modules/midjourney/midjourney.service.js
vendored
239
dist/modules/midjourney/midjourney.service.js
vendored
|
@ -25,12 +25,13 @@ const user_entity_1 = require("./../user/user.entity");
|
|||
const midjourney_entity_1 = require("./midjourney.entity");
|
||||
const utils_1 = require("../../common/utils");
|
||||
const userBalance_service_1 = require("../userBalance/userBalance.service");
|
||||
const bull_1 = require("@nestjs/bull");
|
||||
const image_size_1 = require("image-size");
|
||||
const uuid = require("uuid");
|
||||
const redisCache_service_1 = require("../redisCache/redisCache.service");
|
||||
const prompt_entity_1 = require("./prompt.entity");
|
||||
let MidjourneyService = class MidjourneyService {
|
||||
constructor(midjourneyEntity, userEntity, mjPromptsEntity, globalConfigService, uploadService, userBalanceService, redisCacheService, modelsService) {
|
||||
constructor(mjDrawQueue, midjourneyEntity, userEntity, mjPromptsEntity, globalConfigService, uploadService, userBalanceService, redisCacheService, modelsService) {
|
||||
this.mjDrawQueue = mjDrawQueue;
|
||||
this.midjourneyEntity = midjourneyEntity;
|
||||
this.userEntity = userEntity;
|
||||
this.mjPromptsEntity = mjPromptsEntity;
|
||||
|
@ -41,12 +42,59 @@ let MidjourneyService = class MidjourneyService {
|
|||
this.modelsService = modelsService;
|
||||
this.lockPrompt = [];
|
||||
}
|
||||
async onApplicationBootstrap() {
|
||||
await this.mjDrawQueue.clean(0, 'active');
|
||||
await this.cleanQueue();
|
||||
}
|
||||
async addMjDrawQueue(body, req) {
|
||||
const { prompt = '', imgUrl = '', base64 = '', extraParam = '', drawId = null, action = '', orderId = null, customId = '', } = body;
|
||||
await this.checkLimit(req);
|
||||
const modelInfo = await this.modelsService.getCurrentModelKeyInfo('midjourney');
|
||||
const { deduct, deductType, proxyUrl, timeout } = modelInfo;
|
||||
await this.userBalanceService.validateBalance(req, deductType, action === 'UPSCALE' ? deduct : deduct * 4);
|
||||
const params = Object.assign(Object.assign({}, body), { userId: req.user.id });
|
||||
const drawInfo = await this.addDrawQueue(params);
|
||||
if (action === 'IMAGINE') {
|
||||
this.sendDrawCommand(drawInfo, modelInfo)
|
||||
.then((result) => this.pollComparisonResultDraw(result, modelInfo))
|
||||
.then((drawRes) => {
|
||||
console.log('drawRes', drawRes);
|
||||
return this.updateDrawData(drawInfo, drawRes);
|
||||
})
|
||||
.catch((error) => {
|
||||
common_1.Logger.error('Error in IMAGINE draw operation:', error);
|
||||
});
|
||||
}
|
||||
else {
|
||||
let resultPromise;
|
||||
if (action === 'MODAL') {
|
||||
resultPromise = this.getDrawActionDetail(action, drawId, customId).then((res) => res.drawId);
|
||||
}
|
||||
else {
|
||||
resultPromise = this.sendDrawCommand(drawInfo, modelInfo);
|
||||
}
|
||||
resultPromise
|
||||
.then((result) => this.pollComparisonResultDraw(result, modelInfo))
|
||||
.then((drawRes) => {
|
||||
console.log('drawRes', drawRes);
|
||||
return this.updateDrawData(drawInfo, drawRes);
|
||||
})
|
||||
.catch((error) => {
|
||||
common_1.Logger.error('Error in other draw operation:', error);
|
||||
});
|
||||
}
|
||||
common_1.Logger.log(`执行预扣费,扣除费用:${action === 'UPSCALE' ? deduct : deduct * 4}积分。`);
|
||||
await this.userBalanceService.deductFromBalance(req.user.id, deductType, action === 'UPSCALE' ? deduct : deduct * 4);
|
||||
return true;
|
||||
}
|
||||
async sleep(time) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
async getImageSizeFromUrl(imageUrl) {
|
||||
try {
|
||||
const response = await axios_1.default.get(imageUrl, { responseType: 'arraybuffer' });
|
||||
const response = await axios_1.default.get(imageUrl, {
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
const buffer = Buffer.from(response.data, 'binary');
|
||||
const dimensions = (0, image_size_1.default)(buffer);
|
||||
return { width: dimensions.width, height: dimensions.height };
|
||||
|
@ -56,34 +104,12 @@ let MidjourneyService = class MidjourneyService {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
async draw(jobData, jobId) {
|
||||
const { id, action, base64, userId } = jobData;
|
||||
const drawInfo = await this.midjourneyEntity.findOne({ where: { id } });
|
||||
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, modelInfo, base64);
|
||||
drawInfo.drawId = result;
|
||||
const drawRes = await this.pollComparisonResultDraw(id, modelInfo, drawInfo);
|
||||
await this.updateDrawData(jobData, drawRes);
|
||||
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, customId, drawId } = params;
|
||||
const fullPrompt = imgUrl ? `${imgUrl} ${prompt} ${extraParam}` : `${prompt} ${extraParam}`;
|
||||
const { prompt, imgUrl = '', extraParam = '', action, userId, customId, drawId, } = params;
|
||||
const fullPrompt = imgUrl
|
||||
? `${imgUrl} ${prompt} ${extraParam}`
|
||||
: `${prompt} ${extraParam}`;
|
||||
const drawInfo = {
|
||||
userId,
|
||||
drawId,
|
||||
|
@ -110,7 +136,7 @@ let MidjourneyService = class MidjourneyService {
|
|||
try {
|
||||
const { id, imageUrl, action, submitTime, finishTime, progress } = drawRes;
|
||||
const durationSpent = finishTime - submitTime;
|
||||
const { mjNotSaveImg, mjProxyImgUrl, mjNotUseProxy, } = await this.globalConfigService.getConfigs([
|
||||
const { mjNotSaveImg, mjProxyImgUrl, mjNotUseProxy } = await this.globalConfigService.getConfigs([
|
||||
'mjNotSaveImg',
|
||||
'mjProxyImgUrl',
|
||||
'mjNotUseProxy',
|
||||
|
@ -134,13 +160,28 @@ let MidjourneyService = class MidjourneyService {
|
|||
if (mjNotSaveImg !== '1') {
|
||||
try {
|
||||
common_1.Logger.debug(`------> 开始上传图片!!!`);
|
||||
const filename = `${Date.now()}-${uuid.v4().slice(0, 4)}.png`;
|
||||
processedUrl = await this.uploadService.uploadFileFromUrl({ filename, url: processedUrl });
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const currentDate = `${year}${month}/${day}`;
|
||||
common_1.Logger.debug(`------> 上传图片的URL: ${processedUrl}`);
|
||||
if (!processedUrl) {
|
||||
throw new Error('processedUrl is undefined or empty');
|
||||
}
|
||||
processedUrl = await this.uploadService.uploadFileFromUrl({
|
||||
url: processedUrl,
|
||||
dir: `midjourney/${currentDate}`,
|
||||
});
|
||||
logMessage = `上传成功 URL: ${processedUrl}`;
|
||||
common_1.Logger.debug(logMessage);
|
||||
}
|
||||
catch (uploadError) {
|
||||
common_1.Logger.error('存储图片失败,使用原始/代理图片链接');
|
||||
common_1.Logger.error(uploadError.message);
|
||||
common_1.Logger.error(uploadError.stack);
|
||||
logMessage = `存储图片失败,使用原始/代理图片链接 ${processedUrl}`;
|
||||
common_1.Logger.debug(logMessage);
|
||||
}
|
||||
common_1.Logger.log(logMessage, 'MidjourneyService');
|
||||
}
|
||||
|
@ -166,15 +207,15 @@ let MidjourneyService = class MidjourneyService {
|
|||
throw new common_1.HttpException('更新绘画数据失败', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
async sendDrawCommand(drawInfo, action, modelInfo, base64) {
|
||||
const { openaiBaseUrl, openaiBaseKey, } = await this.globalConfigService.getConfigs([
|
||||
async sendDrawCommand(drawInfo, modelInfo) {
|
||||
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 { id, fullPrompt, imgUrl, drawId, customId, action, base64 } = drawInfo;
|
||||
const prompt = imgUrl ? `${imgUrl} ${fullPrompt}` : `${fullPrompt}`;
|
||||
let url = '';
|
||||
let payloadJson = {};
|
||||
|
@ -215,9 +256,9 @@ let MidjourneyService = class MidjourneyService {
|
|||
}
|
||||
}
|
||||
}
|
||||
async pollComparisonResultDraw(id, modelInfo, drawInfo) {
|
||||
const { key, proxyUrl, timeout } = modelInfo;
|
||||
const { openaiTimeout, openaiBaseUrl, openaiBaseKey, } = await this.globalConfigService.getConfigs([
|
||||
async pollComparisonResultDraw(drawId, modelInfo) {
|
||||
const { key, proxyUrl, timeout, id } = modelInfo;
|
||||
const { openaiTimeout, openaiBaseUrl, openaiBaseKey } = await this.globalConfigService.getConfigs([
|
||||
'openaiTimeout',
|
||||
'openaiBaseUrl',
|
||||
'openaiBaseKey',
|
||||
|
@ -231,15 +272,14 @@ let MidjourneyService = class MidjourneyService {
|
|||
let pollingCount = 0;
|
||||
let retryCount = 0;
|
||||
const MAX_RETRIES = 5;
|
||||
const { drawId } = drawInfo;
|
||||
try {
|
||||
while (Date.now() - startTime < TIMEOUT && retryCount < MAX_RETRIES) {
|
||||
await new Promise(resolve => setTimeout(resolve, POLL_INTERVAL));
|
||||
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",
|
||||
"mj-api-secret": mjKey
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'mj-api-secret': mjKey,
|
||||
};
|
||||
const url = `${mjProxyUrl}/mj/task/${drawId}/fetch`;
|
||||
const res = await axios_1.default.get(url, { headers });
|
||||
|
@ -283,10 +323,31 @@ 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', 'extend']
|
||||
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 };
|
||||
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,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
catch (error) {
|
||||
|
@ -295,11 +356,11 @@ let MidjourneyService = class MidjourneyService {
|
|||
}
|
||||
async getDrawActionDetail(action, drawId, customId) {
|
||||
const modelInfo = await this.modelsService.getSpecialModelKeyInfo('midjourney');
|
||||
const { openaiBaseUrl, openaiBaseKey, } = await this.globalConfigService.getConfigs([
|
||||
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 { 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 };
|
||||
|
@ -314,7 +375,9 @@ let MidjourneyService = class MidjourneyService {
|
|||
return { drawId: resultId };
|
||||
}
|
||||
async deleteDraw(id, req) {
|
||||
const d = await this.midjourneyEntity.findOne({ where: { id, userId: req.user.id, isDelete: 0 } });
|
||||
const d = await this.midjourneyEntity.findOne({
|
||||
where: { id, userId: req.user.id, isDelete: 0 },
|
||||
});
|
||||
if (!d) {
|
||||
throw new common_1.HttpException('当前图片不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -331,8 +394,12 @@ let MidjourneyService = class MidjourneyService {
|
|||
}
|
||||
async checkLimit(req) {
|
||||
const { role, id } = req.user;
|
||||
const count = await this.midjourneyEntity.count({ where: { userId: id, isDelete: 0, status: (0, typeorm_2.In)([1, 2]) } });
|
||||
const mjLimitCount = await this.globalConfigService.getConfigs(['mjLimitCount']);
|
||||
const count = await this.midjourneyEntity.count({
|
||||
where: { userId: id, isDelete: 0, status: (0, typeorm_2.In)([1, 2]) },
|
||||
});
|
||||
const mjLimitCount = await this.globalConfigService.getConfigs([
|
||||
'mjLimitCount',
|
||||
]);
|
||||
const max = mjLimitCount ? Number(mjLimitCount) : 2;
|
||||
if (count >= max) {
|
||||
throw new common_1.HttpException(`当前管理员限制单用户同时最多能执行${max}个任务`, common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -342,17 +409,12 @@ let MidjourneyService = class MidjourneyService {
|
|||
const { id, userId, action } = jobData;
|
||||
await this.midjourneyEntity.update({ id }, { status: 4 });
|
||||
}
|
||||
async drawSuccess(jobData) {
|
||||
const { id, userId, action } = jobData;
|
||||
const amount = action === "UPSCALE" ? 1 : 4;
|
||||
common_1.Logger.debug(`绘画完成,执行扣费,扣除费用:${amount}积分。`);
|
||||
await this.userBalanceService.deductFromBalance(userId, 3, 3);
|
||||
await this.midjourneyEntity.update({ id }, { status: 3 });
|
||||
}
|
||||
async getList(params) {
|
||||
const { page = 1, size = 20, rec, userId, status } = params;
|
||||
if (Number(size) === 999) {
|
||||
const cache = await this.redisCacheService.get({ key: 'midjourney:getList' });
|
||||
const cache = await this.redisCacheService.get({
|
||||
key: 'midjourney:getList',
|
||||
});
|
||||
if (cache) {
|
||||
try {
|
||||
return JSON.parse(cache);
|
||||
|
@ -371,13 +433,37 @@ let MidjourneyService = class MidjourneyService {
|
|||
order: { id: 'DESC' },
|
||||
take: size,
|
||||
skip: (page - 1) * size,
|
||||
select: ['id', 'drawId', 'drawUrl', 'drawRatio', 'prompt', 'fullPrompt', 'rec', 'createdAt', 'action', 'status', 'extend'],
|
||||
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, extend } = item;
|
||||
return { id, drawId, drawUrl, drawRatio, prompt, fullPrompt, createdAt, rec, action, status, extend };
|
||||
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,
|
||||
};
|
||||
|
@ -407,8 +493,13 @@ let MidjourneyService = class MidjourneyService {
|
|||
take: size,
|
||||
skip: (page - 1) * size,
|
||||
});
|
||||
const userIds = rows.map((item) => item.userId).filter(id => id < 100000);
|
||||
const userInfos = await this.userEntity.find({ where: { id: (0, typeorm_2.In)(userIds) }, select: ['id', 'username', 'avatar', 'email'] });
|
||||
const userIds = rows
|
||||
.map((item) => item.userId)
|
||||
.filter((id) => id < 100000);
|
||||
const userInfos = await this.userEntity.find({
|
||||
where: { id: (0, typeorm_2.In)(userIds) },
|
||||
select: ['id', 'username', 'avatar', 'email'],
|
||||
});
|
||||
rows.forEach((item) => {
|
||||
item.userInfo = userInfos.find((user) => user.id === item.userId);
|
||||
});
|
||||
|
@ -427,7 +518,9 @@ let MidjourneyService = class MidjourneyService {
|
|||
}
|
||||
async recDraw(params) {
|
||||
const { id } = params;
|
||||
const draw = await this.midjourneyEntity.findOne({ where: { id, status: 3, isDelete: 0 } });
|
||||
const draw = await this.midjourneyEntity.findOne({
|
||||
where: { id, status: 3, isDelete: 0 },
|
||||
});
|
||||
if (!draw) {
|
||||
throw new common_1.HttpException('当前图片不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -465,7 +558,14 @@ let MidjourneyService = class MidjourneyService {
|
|||
return await this.mjPromptsEntity.update({ id }, { prompt, status, isCarryParams, order, aspect });
|
||||
}
|
||||
else {
|
||||
return await this.mjPromptsEntity.save({ prompt, status, isCarryParams, title, order, aspect });
|
||||
return await this.mjPromptsEntity.save({
|
||||
prompt,
|
||||
status,
|
||||
isCarryParams,
|
||||
title,
|
||||
order,
|
||||
aspect,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
|
@ -495,10 +595,11 @@ let MidjourneyService = class MidjourneyService {
|
|||
};
|
||||
MidjourneyService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__param(0, (0, typeorm_1.InjectRepository)(midjourney_entity_1.MidjourneyEntity)),
|
||||
__param(1, (0, typeorm_1.InjectRepository)(user_entity_1.UserEntity)),
|
||||
__param(2, (0, typeorm_1.InjectRepository)(prompt_entity_1.mjPromptEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_2.Repository,
|
||||
__param(0, (0, bull_1.InjectQueue)('MJDRAW')),
|
||||
__param(1, (0, typeorm_1.InjectRepository)(midjourney_entity_1.MidjourneyEntity)),
|
||||
__param(2, (0, typeorm_1.InjectRepository)(user_entity_1.UserEntity)),
|
||||
__param(3, (0, typeorm_1.InjectRepository)(prompt_entity_1.mjPromptEntity)),
|
||||
__metadata("design:paramtypes", [Object, typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
globalConfig_service_1.GlobalConfigService,
|
||||
|
|
58
dist/modules/models/dto/setModel.dto.js
vendored
58
dist/modules/models/dto/setModel.dto.js
vendored
|
@ -30,17 +30,21 @@ __decorate([
|
|||
__metadata("design:type", Object)
|
||||
], SetModelDto.prototype, "key", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: true, description: '是否开启当前key对应的模型', required: true }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: true,
|
||||
description: '是否开启当前key对应的模型',
|
||||
required: true,
|
||||
}),
|
||||
__metadata("design:type", Boolean)
|
||||
], SetModelDto.prototype, "status", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 'gpt-3.5', description: '当前key绑定的模型是多少 需要调用的模型', required: true }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: 'gpt-3.5',
|
||||
description: '当前key绑定的模型是多少 需要调用的模型',
|
||||
required: true,
|
||||
}),
|
||||
__metadata("design:type", String)
|
||||
], SetModelDto.prototype, "model", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 1, description: 'key的权重' }),
|
||||
__metadata("design:type", Number)
|
||||
], SetModelDto.prototype, "keyWeight", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 1, description: '模型排序' }),
|
||||
__metadata("design:type", Number)
|
||||
|
@ -50,11 +54,19 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], SetModelDto.prototype, "modelAvatar", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: 4096, description: '模型支持的最大TOken数量', required: false }),
|
||||
(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: true, description: '模型的代理地址', required: false }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: true,
|
||||
description: '模型的代理地址',
|
||||
required: false,
|
||||
}),
|
||||
__metadata("design:type", String)
|
||||
], SetModelDto.prototype, "proxyUrl", void 0);
|
||||
__decorate([
|
||||
|
@ -66,7 +78,11 @@ __decorate([
|
|||
__metadata("design:type", Number)
|
||||
], SetModelDto.prototype, "keyStatus", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: true, description: '扣费类型 1: 普通 2: 高级余额', required: false }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: true,
|
||||
description: '扣费类型 1: 普通 2: 高级余额',
|
||||
required: false,
|
||||
}),
|
||||
__metadata("design:type", Number)
|
||||
], SetModelDto.prototype, "deductType", void 0);
|
||||
__decorate([
|
||||
|
@ -74,19 +90,35 @@ __decorate([
|
|||
__metadata("design:type", Number)
|
||||
], SetModelDto.prototype, "deduct", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: true, description: '最大上下文轮次', required: false }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: true,
|
||||
description: '最大上下文轮次',
|
||||
required: false,
|
||||
}),
|
||||
__metadata("design:type", Number)
|
||||
], SetModelDto.prototype, "maxRounds", void 0);
|
||||
__decorate([
|
||||
(0, swagger_1.ApiProperty)({ example: true, description: '是否设置为绘画Key', required: false }),
|
||||
(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 }),
|
||||
(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 }),
|
||||
(0, swagger_1.ApiProperty)({
|
||||
example: true,
|
||||
description: '是否使用token计费',
|
||||
required: false,
|
||||
}),
|
||||
__metadata("design:type", Boolean)
|
||||
], SetModelDto.prototype, "isTokenBased", void 0);
|
||||
__decorate([
|
||||
|
|
28
dist/modules/models/models.entity.js
vendored
28
dist/modules/models/models.entity.js
vendored
|
@ -10,8 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ModelsEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
const typeorm_1 = require("typeorm");
|
||||
let ModelsEntity = class ModelsEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
|
@ -27,7 +27,7 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], ModelsEntity.prototype, "model", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '模型头像', nullable: true }),
|
||||
(0, typeorm_1.Column)({ length: 1024, comment: '模型头像', nullable: true }),
|
||||
__metadata("design:type", String)
|
||||
], ModelsEntity.prototype, "modelAvatar", void 0);
|
||||
__decorate([
|
||||
|
@ -35,7 +35,11 @@ __decorate([
|
|||
__metadata("design:type", Number)
|
||||
], ModelsEntity.prototype, "modelOrder", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '模型上下文支持的最大Token', default: 2000, nullable: true }),
|
||||
(0, typeorm_1.Column)({
|
||||
comment: '模型上下文支持的最大Token',
|
||||
default: 2000,
|
||||
nullable: true,
|
||||
}),
|
||||
__metadata("design:type", Number)
|
||||
], ModelsEntity.prototype, "maxModelTokens", void 0);
|
||||
__decorate([
|
||||
|
@ -59,7 +63,10 @@ __decorate([
|
|||
__metadata("design:type", Boolean)
|
||||
], ModelsEntity.prototype, "isTokenBased", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '是否支持文件上传: 0:不是 1: 附件链接格式 2: 4V格式', default: 0 }),
|
||||
(0, typeorm_1.Column)({
|
||||
comment: '是否支持文件上传: 0:不是 1: 附件链接格式 2: 4V格式',
|
||||
default: 0,
|
||||
}),
|
||||
__metadata("design:type", Number)
|
||||
], ModelsEntity.prototype, "isFileUpload", void 0);
|
||||
__decorate([
|
||||
|
@ -79,13 +86,12 @@ __decorate([
|
|||
__metadata("design:type", Boolean)
|
||||
], ModelsEntity.prototype, "status", 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: 0 }),
|
||||
__metadata("design:type", Number)
|
||||
|
@ -102,6 +108,10 @@ __decorate([
|
|||
(0, typeorm_1.Column)({ comment: '模型频率限制 次/小时', default: 999 }),
|
||||
__metadata("design:type", Number)
|
||||
], ModelsEntity.prototype, "modelLimits", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '模型介绍', nullable: true }),
|
||||
__metadata("design:type", String)
|
||||
], ModelsEntity.prototype, "modelDescription", void 0);
|
||||
ModelsEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'models' })
|
||||
], ModelsEntity);
|
||||
|
|
69
dist/modules/models/models.service.js
vendored
69
dist/modules/models/models.service.js
vendored
|
@ -47,18 +47,16 @@ let ModelsService = class ModelsService {
|
|||
}
|
||||
return pre;
|
||||
}, {});
|
||||
this.modelTypes = Object.keys(keyTypes).map(keyType => {
|
||||
this.modelTypes = Object.keys(keyTypes).map((keyType) => {
|
||||
return { label: status_constant_1.ModelsMapCn[keyType], val: keyType };
|
||||
});
|
||||
this.modelMaps = keyTypes;
|
||||
this.keyList = {};
|
||||
allKeys.forEach(keyDetail => {
|
||||
const { keyType, model, keyWeight } = keyDetail;
|
||||
allKeys.forEach((keyDetail) => {
|
||||
const { keyType, model } = keyDetail;
|
||||
if (!this.keyPoolMap[model])
|
||||
this.keyPoolMap[model] = [];
|
||||
for (let index = 0; index < keyWeight; index++) {
|
||||
this.keyPoolMap[model].push(keyDetail);
|
||||
}
|
||||
if (!this.keyPoolIndexMap[model])
|
||||
this.keyPoolIndexMap[model] = 0;
|
||||
if (!this.keyList[keyType])
|
||||
|
@ -74,7 +72,9 @@ let ModelsService = class ModelsService {
|
|||
this.initCalcKey();
|
||||
}
|
||||
async getCurrentModelKeyInfo(model) {
|
||||
const modelKeyInfo = await this.modelsEntity.findOne({ where: { model: model } });
|
||||
const modelKeyInfo = await this.modelsEntity.findOne({
|
||||
where: { model: model },
|
||||
});
|
||||
if (!modelKeyInfo) {
|
||||
throw new common_1.HttpException('当前调用模型的key未找到,请重新选择模型!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ let ModelsService = class ModelsService {
|
|||
}
|
||||
async getSpecialModelKeyInfo(modelPrefix) {
|
||||
const matchingModels = await this.modelsEntity.find({
|
||||
where: { model: (0, typeorm_2.Like)(`${modelPrefix}%`) }
|
||||
where: { model: (0, typeorm_2.Like)(`${modelPrefix}%`) },
|
||||
});
|
||||
if (matchingModels.length === 0) {
|
||||
throw new common_1.HttpException('未找到匹配的模型,请重新选择模型!', common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -95,9 +95,18 @@ let ModelsService = class ModelsService {
|
|||
async getBaseConfig(appId) {
|
||||
if (!this.modelTypes.length || !Object.keys(this.modelMaps).length)
|
||||
return;
|
||||
const { keyType, modelName, model, deductType, deduct, isFileUpload } = this.modelMaps[1][0];
|
||||
const { keyType, modelName, model, deductType, deduct, isFileUpload, modelAvatar, modelDescription, } = this.modelMaps[1][0];
|
||||
return {
|
||||
modelInfo: { keyType, modelName, model, deductType, deduct, isFileUpload }
|
||||
modelInfo: {
|
||||
keyType,
|
||||
modelName,
|
||||
model,
|
||||
deductType,
|
||||
deduct,
|
||||
isFileUpload,
|
||||
modelAvatar,
|
||||
modelDescription,
|
||||
},
|
||||
};
|
||||
}
|
||||
async setModel(params) {
|
||||
|
@ -120,7 +129,7 @@ let ModelsService = class ModelsService {
|
|||
return res;
|
||||
}
|
||||
else {
|
||||
const data = key.map(k => {
|
||||
const data = key.map((k) => {
|
||||
try {
|
||||
const data = JSON.parse(JSON.stringify(params));
|
||||
data.key = k;
|
||||
|
@ -166,13 +175,13 @@ let ModelsService = class ModelsService {
|
|||
const [rows, count] = await this.modelsEntity.findAndCount({
|
||||
where: where,
|
||||
order: {
|
||||
modelOrder: 'ASC'
|
||||
modelOrder: 'ASC',
|
||||
},
|
||||
skip: (page - 1) * size,
|
||||
take: size,
|
||||
});
|
||||
if (role !== 'super') {
|
||||
rows.forEach(item => {
|
||||
rows.forEach((item) => {
|
||||
item.key && (item.key = (0, utils_1.hideString)(item.key));
|
||||
});
|
||||
}
|
||||
|
@ -180,22 +189,37 @@ let ModelsService = class ModelsService {
|
|||
}
|
||||
async modelsList() {
|
||||
const cloneModelMaps = JSON.parse(JSON.stringify(this.modelMaps));
|
||||
Object.keys(cloneModelMaps).forEach(key => {
|
||||
cloneModelMaps[key] = cloneModelMaps[key].sort((a, b) => a.modelOrder - b.modelOrder);
|
||||
Object.keys(cloneModelMaps).forEach((key) => {
|
||||
cloneModelMaps[key] = cloneModelMaps[key]
|
||||
.filter((t) => t.keyStatus === 1)
|
||||
.sort((a, b) => a.modelOrder - b.modelOrder);
|
||||
cloneModelMaps[key] = Array.from(cloneModelMaps[key]
|
||||
.map(t => {
|
||||
const { modelName, keyType, model, deduct, deductType, maxRounds, modelAvatar, isFileUpload } = t;
|
||||
return { modelName, keyType, model, deduct, deductType, maxRounds, modelAvatar, isFileUpload };
|
||||
.map((t) => {
|
||||
const { modelName, keyType, model, deduct, deductType, maxRounds, modelAvatar, isFileUpload, modelDescription, } = t;
|
||||
return {
|
||||
modelName,
|
||||
keyType,
|
||||
model,
|
||||
deduct,
|
||||
deductType,
|
||||
maxRounds,
|
||||
modelAvatar,
|
||||
isFileUpload,
|
||||
modelDescription,
|
||||
};
|
||||
})
|
||||
.reduce((map, obj) => map.set(obj.modelName, obj), new Map()).values());
|
||||
.reduce((map, obj) => map.set(obj.modelName, obj), new Map())
|
||||
.values());
|
||||
});
|
||||
return {
|
||||
modelTypeList: this.modelTypes,
|
||||
modelMaps: cloneModelMaps
|
||||
modelMaps: cloneModelMaps,
|
||||
};
|
||||
}
|
||||
async getMjInfo() {
|
||||
const modelInfo = await this.modelsEntity.findOne({ where: { model: "midjourney" } });
|
||||
const modelInfo = await this.modelsEntity.findOne({
|
||||
where: { model: 'midjourney' },
|
||||
});
|
||||
if (modelInfo) {
|
||||
return {
|
||||
modelName: modelInfo.modelName,
|
||||
|
@ -212,7 +236,10 @@ let ModelsService = class ModelsService {
|
|||
await this.modelsEntity
|
||||
.createQueryBuilder()
|
||||
.update(models_entity_1.ModelsEntity)
|
||||
.set({ useCount: () => 'useCount + 1', useToken: () => `useToken + ${useToken}` })
|
||||
.set({
|
||||
useCount: () => 'useCount + 1',
|
||||
useToken: () => `useToken + ${useToken}`,
|
||||
})
|
||||
.where('id = :id', { id })
|
||||
.execute();
|
||||
}
|
||||
|
|
8
dist/modules/official/official.controller.js
vendored
8
dist/modules/official/official.controller.js
vendored
|
@ -13,12 +13,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.OfficialController = void 0;
|
||||
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
|
||||
const utils_1 = require("../../common/utils");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
|
||||
const official_service_1 = require("./official.service");
|
||||
const getQrCode_dto_1 = require("./dto/getQrCode.dto");
|
||||
const getQrSceneStr_dto_1 = require("./dto/getQrSceneStr.dto");
|
||||
const official_service_1 = require("./official.service");
|
||||
let OfficialController = class OfficialController {
|
||||
constructor(officialService) {
|
||||
this.officialService = officialService;
|
||||
|
@ -85,7 +86,8 @@ let OfficialController = class OfficialController {
|
|||
if (process.env.ISDEV === 'TRUE')
|
||||
return '';
|
||||
const ticket = await this.officialService.getQRCodeTicket(query.sceneStr);
|
||||
return `https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=${encodeURIComponent(ticket)}`;
|
||||
const Url = (0, utils_1.formatUrl)(process.env.weChatMpUrl || 'https://mp.weixin.qq.com');
|
||||
return `${Url}/cgi-bin/showqrcode?ticket=${encodeURIComponent(ticket)}`;
|
||||
}
|
||||
async loginBySceneStr(req, body) {
|
||||
return this.officialService.loginBySceneStr(req, body.sceneStr);
|
||||
|
|
59
dist/modules/official/official.service.js
vendored
59
dist/modules/official/official.service.js
vendored
|
@ -49,17 +49,24 @@ let OfficialService = class OfficialService {
|
|||
return this.fetchQRCodeTicket(sceneStr);
|
||||
}
|
||||
async getRedirectUrl(url) {
|
||||
const appId = await this.globalConfigService.getConfigs(['wechatOfficialAppId']);
|
||||
const res = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURIComponent(url)}&response_type=code&scope=snsapi_base&state=weChatLogin#wechat_redirect`;
|
||||
const appId = await this.globalConfigService.getConfigs([
|
||||
'wechatOfficialAppId',
|
||||
]);
|
||||
const Url = (0, utils_1.formatUrl)(process.env.weChatOpenUrl || 'https://open.weixin.qq.com');
|
||||
const res = `${Url}/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURIComponent(url)}&response_type=code&scope=snsapi_base&state=weChatLogin#wechat_redirect`;
|
||||
console.log('回跳跳转地址: ', res);
|
||||
return res;
|
||||
}
|
||||
async getJsapiTicket(url) {
|
||||
const nonceStr = (0, utils_1.createRandomNonceStr)(32);
|
||||
const timestamp = (Date.now() / 1000).toFixed(0);
|
||||
const jsapiTicket = await this.globalConfigService.getConfigs(['wechatJsapiTicket']);
|
||||
const jsapiTicket = await this.globalConfigService.getConfigs([
|
||||
'wechatJsapiTicket',
|
||||
]);
|
||||
console.log('jsapiTicket: ', jsapiTicket);
|
||||
const appId = await this.globalConfigService.getConfigs(['wechatOfficialAppId']);
|
||||
const appId = await this.globalConfigService.getConfigs([
|
||||
'wechatOfficialAppId',
|
||||
]);
|
||||
console.log('appId: ', appId);
|
||||
const str = `jsapi_ticket=${jsapiTicket}&noncestr=${nonceStr}×tamp=${timestamp}&url=${url}`;
|
||||
console.log('str: ', str);
|
||||
|
@ -67,18 +74,29 @@ let OfficialService = class OfficialService {
|
|||
return { appId, nonceStr, timestamp, signature };
|
||||
}
|
||||
async fetchQRCodeTicket(sceneStr) {
|
||||
const accessToken = await this.globalConfigService.getConfigs(['wechatAccessToken']);
|
||||
const params = { action_name: 'QR_STR_SCENE', action_info: { scene: { scene_str: sceneStr } } };
|
||||
const res = await axios_1.default.post(`https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=${accessToken}`, params);
|
||||
const accessToken = await this.globalConfigService.getConfigs([
|
||||
'wechatAccessToken',
|
||||
]);
|
||||
const Url = (0, utils_1.formatUrl)(process.env.weChatApiUrl || 'https://api.weixin.qq.com');
|
||||
const params = {
|
||||
action_name: 'QR_STR_SCENE',
|
||||
action_info: { scene: { scene_str: sceneStr } },
|
||||
};
|
||||
const res = await axios_1.default.post(`${Url}/cgi-bin/qrcode/create?access_token=${accessToken}`, params);
|
||||
const { data: { errmsg, ticket }, } = res;
|
||||
if (errmsg)
|
||||
throw new common_1.HttpException(errmsg, common_1.HttpStatus.BAD_REQUEST);
|
||||
return ticket;
|
||||
}
|
||||
async loginByCode(req, code) {
|
||||
const appId = await this.globalConfigService.getConfigs(['wechatOfficialAppId']);
|
||||
const secret = await this.globalConfigService.getConfigs(['wechatOfficialAppSecret']);
|
||||
const res = await axios_1.default.get(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appId}&secret=${secret}&code=${code}&grant_type=authorization_code`);
|
||||
const appId = await this.globalConfigService.getConfigs([
|
||||
'wechatOfficialAppId',
|
||||
]);
|
||||
const secret = await this.globalConfigService.getConfigs([
|
||||
'wechatOfficialAppSecret',
|
||||
]);
|
||||
const Url = (0, utils_1.formatUrl)(process.env.weChatApiUrl || 'https://api.weixin.qq.com');
|
||||
const res = await axios_1.default.get(`${Url}/sns/oauth2/access_token?appid=${appId}&secret=${secret}&code=${code}&grant_type=authorization_code`);
|
||||
const { data: { errmsg, openid }, } = res;
|
||||
if (errmsg)
|
||||
throw new common_1.HttpException(errmsg, common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -90,11 +108,22 @@ let OfficialService = class OfficialService {
|
|||
return this.authService.loginByOpenId(user, req);
|
||||
}
|
||||
async scan(openID, sceneStr) {
|
||||
if (!this.sceneStrMap[sceneStr])
|
||||
try {
|
||||
common_1.Logger.log(`Scanning with openID: ${openID}, sceneStr: ${sceneStr}`);
|
||||
if (!this.sceneStrMap[sceneStr]) {
|
||||
common_1.Logger.error(`非法参数: 未找到的 sceneStr ${sceneStr}`);
|
||||
throw new common_1.HttpException('非法参数', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const user = await this.userService.getUserFromOpenId(openID, sceneStr);
|
||||
common_1.Logger.log(`User found: ${user ? user.id : 'No user found'}`);
|
||||
this.scanedSceneStrMap[sceneStr] = user.id;
|
||||
}
|
||||
catch (error) {
|
||||
common_1.Logger.error('Error in scan method:', error.message);
|
||||
common_1.Logger.error('Stack trace:', error.stack);
|
||||
throw new common_1.HttpException('处理扫码事件时发生错误', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
async loginBySceneStr(req, sceneStr) {
|
||||
if (!this.sceneStrMap[sceneStr])
|
||||
return;
|
||||
|
@ -123,8 +152,9 @@ let OfficialService = class OfficialService {
|
|||
return res;
|
||||
}
|
||||
async verify(signature, nonce, timestamp) {
|
||||
const token = (await this.globalConfigService.getConfigs(['wechatOfficialToken'])) || '';
|
||||
return (await this.sha1([token, nonce, timestamp].sort().join(''))) == signature;
|
||||
const token = (await this.globalConfigService.getConfigs(['wechatOfficialToken'])) ||
|
||||
'';
|
||||
return ((await this.sha1([token, nonce, timestamp].sort().join(''))) == signature);
|
||||
}
|
||||
sha1(data) {
|
||||
return crypto.createHash('sha1').update(data).digest('hex');
|
||||
|
@ -149,7 +179,8 @@ let OfficialService = class OfficialService {
|
|||
reject(new Error('请求超时'));
|
||||
}, 4800);
|
||||
});
|
||||
let question = (await this.globalConfigService.getConfigs(['officialAutoReplyText'])) || '由于公众号的回复限制、过长的问题我们可能无法回复、您可以前往我们的官方站点享受更加完善的服务、如果您有更多问题、欢迎像我提问!';
|
||||
let question = (await this.globalConfigService.getConfigs(['officialAutoReplyText'])) ||
|
||||
'由于公众号的回复限制、过长的问题我们可能无法回复、您可以前往我们的官方站点享受更加完善的服务、如果您有更多问题、欢迎像我提问!';
|
||||
return question;
|
||||
}
|
||||
};
|
||||
|
|
80
dist/modules/plugin/plugin.controller.js
vendored
Normal file
80
dist/modules/plugin/plugin.controller.js
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
"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.PluginController = void 0;
|
||||
const superAuth_guard_1 = require("../../common/auth/superAuth.guard");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const plugin_service_1 = require("./plugin.service");
|
||||
let PluginController = class PluginController {
|
||||
constructor(pluginService) {
|
||||
this.pluginService = pluginService;
|
||||
}
|
||||
pluginList(req) {
|
||||
return this.pluginService.pluginList(req);
|
||||
}
|
||||
createPlugin(body) {
|
||||
return this.pluginService.createPlugin(body);
|
||||
}
|
||||
updatePlugin(body) {
|
||||
return this.pluginService.updatePlugin(body);
|
||||
}
|
||||
delPlugin(body) {
|
||||
return this.pluginService.delPlugin(body);
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
(0, common_1.Get)('pluginList'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '获取Plugin' }),
|
||||
__param(0, (0, common_1.Req)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], PluginController.prototype, "pluginList", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('createPlugin'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '创建Plugin' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], PluginController.prototype, "createPlugin", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('updatePlugin'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '修改插件' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], PluginController.prototype, "updatePlugin", null);
|
||||
__decorate([
|
||||
(0, common_1.Post)('delPlugin'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '删除插件' }),
|
||||
(0, common_1.UseGuards)(superAuth_guard_1.SuperAuthGuard),
|
||||
(0, swagger_1.ApiBearerAuth)(),
|
||||
__param(0, (0, common_1.Body)()),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], PluginController.prototype, "delPlugin", null);
|
||||
PluginController = __decorate([
|
||||
(0, swagger_1.ApiTags)('Plugin'),
|
||||
(0, common_1.Controller)('plugin'),
|
||||
__metadata("design:paramtypes", [plugin_service_1.PluginService])
|
||||
], PluginController);
|
||||
exports.PluginController = PluginController;
|
|
@ -9,40 +9,40 @@ 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.ChatBoxEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
exports.PluginEntity = void 0;
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
let ChatBoxEntity = class ChatBoxEntity extends baseEntity_1.BaseEntity {
|
||||
const typeorm_1 = require("typeorm");
|
||||
let PluginEntity = class PluginEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '分类ID' }),
|
||||
__metadata("design:type", Number)
|
||||
], ChatBoxEntity.prototype, "typeId", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '应用ID', nullable: true }),
|
||||
__metadata("design:type", Number)
|
||||
], ChatBoxEntity.prototype, "appId", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '快速描述词', nullable: true, type: 'text' }),
|
||||
(0, typeorm_1.Column)({ unique: true, comment: '插件名称' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatBoxEntity.prototype, "prompt", void 0);
|
||||
], PluginEntity.prototype, "name", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '标题名称' }),
|
||||
(0, typeorm_1.Column)({ comment: '插件封面', nullable: true, type: 'text' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatBoxEntity.prototype, "title", void 0);
|
||||
], PluginEntity.prototype, "pluginImg", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '排序ID', default: 100 }),
|
||||
(0, typeorm_1.Column)({ comment: '插件描述' }),
|
||||
__metadata("design:type", String)
|
||||
], PluginEntity.prototype, "description", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '插件是否启用 0:禁用 1:启用', default: 1 }),
|
||||
__metadata("design:type", Number)
|
||||
], ChatBoxEntity.prototype, "order", void 0);
|
||||
], PluginEntity.prototype, "isEnabled", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '开启状态', default: true }),
|
||||
__metadata("design:type", Boolean)
|
||||
], ChatBoxEntity.prototype, "status", void 0);
|
||||
(0, typeorm_1.Column)({ comment: '插件是否为系统插件 0:否 1:是', default: 0 }),
|
||||
__metadata("design:type", Number)
|
||||
], PluginEntity.prototype, "isSystemPlugin", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '跳转地址' }),
|
||||
(0, typeorm_1.Column)({ comment: '调用参数', type: 'text' }),
|
||||
__metadata("design:type", String)
|
||||
], ChatBoxEntity.prototype, "url", void 0);
|
||||
ChatBoxEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'chat_box' })
|
||||
], ChatBoxEntity);
|
||||
exports.ChatBoxEntity = ChatBoxEntity;
|
||||
], PluginEntity.prototype, "parameters", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ comment: '排序值', default: 0 }),
|
||||
__metadata("design:type", Number)
|
||||
], PluginEntity.prototype, "sortOrder", void 0);
|
||||
PluginEntity = __decorate([
|
||||
(0, typeorm_1.Entity)({ name: 'plugin' })
|
||||
], PluginEntity);
|
||||
exports.PluginEntity = PluginEntity;
|
|
@ -6,11 +6,19 @@ 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.KnowledgeBaseService = void 0;
|
||||
exports.PluginModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
let KnowledgeBaseService = class KnowledgeBaseService {
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const plugin_controller_1 = require("./plugin.controller");
|
||||
const plugin_entity_1 = require("./plugin.entity");
|
||||
const plugin_service_1 = require("./plugin.service");
|
||||
let PluginModule = class PluginModule {
|
||||
};
|
||||
KnowledgeBaseService = __decorate([
|
||||
(0, common_1.Injectable)()
|
||||
], KnowledgeBaseService);
|
||||
exports.KnowledgeBaseService = KnowledgeBaseService;
|
||||
PluginModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
imports: [typeorm_1.TypeOrmModule.forFeature([plugin_entity_1.PluginEntity])],
|
||||
controllers: [plugin_controller_1.PluginController],
|
||||
providers: [plugin_service_1.PluginService],
|
||||
})
|
||||
], PluginModule);
|
||||
exports.PluginModule = PluginModule;
|
103
dist/modules/plugin/plugin.service.js
vendored
Normal file
103
dist/modules/plugin/plugin.service.js
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
"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.PluginService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const typeorm_2 = require("typeorm");
|
||||
const plugin_entity_1 = require("./plugin.entity");
|
||||
let PluginService = class PluginService {
|
||||
constructor(PluginEntity) {
|
||||
this.PluginEntity = PluginEntity;
|
||||
}
|
||||
async pluginList(query) {
|
||||
const { page = 1, size = 1000 } = query;
|
||||
const rows = await this.PluginEntity.find({
|
||||
order: { sortOrder: 'ASC', id: 'DESC' },
|
||||
skip: (page - 1) * size,
|
||||
take: size,
|
||||
});
|
||||
return { rows, count: rows.length };
|
||||
}
|
||||
async createPlugin(body) {
|
||||
const { name, pluginImg, description, isEnabled, isSystemPlugin, parameters, sortOrder, } = body;
|
||||
const existingPlugin = await this.PluginEntity.findOne({
|
||||
where: { name },
|
||||
});
|
||||
if (existingPlugin) {
|
||||
throw new common_1.HttpException('该插件名称已存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const newPlugin = this.PluginEntity.create({
|
||||
name,
|
||||
pluginImg,
|
||||
description,
|
||||
isEnabled: isEnabled !== undefined ? isEnabled : 1,
|
||||
isSystemPlugin: isSystemPlugin !== undefined ? isSystemPlugin : 0,
|
||||
parameters,
|
||||
sortOrder: sortOrder !== undefined ? sortOrder : 0,
|
||||
});
|
||||
return await this.PluginEntity.save(newPlugin);
|
||||
}
|
||||
async updatePlugin(body) {
|
||||
const { id, name, pluginImg, description, isEnabled, isSystemPlugin, parameters, sortOrder, } = body;
|
||||
const existingPlugin = await this.PluginEntity.findOne({
|
||||
where: { id },
|
||||
});
|
||||
if (!existingPlugin) {
|
||||
throw new common_1.HttpException('插件不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const duplicatePlugin = await this.PluginEntity.findOne({
|
||||
where: { name, id: (0, typeorm_2.Not)(id) },
|
||||
});
|
||||
if (duplicatePlugin) {
|
||||
throw new common_1.HttpException('该插件名称已存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
existingPlugin.name = name;
|
||||
existingPlugin.pluginImg = pluginImg;
|
||||
existingPlugin.description = description;
|
||||
existingPlugin.isEnabled =
|
||||
isEnabled !== undefined ? isEnabled : existingPlugin.isEnabled;
|
||||
existingPlugin.isSystemPlugin =
|
||||
isSystemPlugin !== undefined
|
||||
? isSystemPlugin
|
||||
: existingPlugin.isSystemPlugin;
|
||||
existingPlugin.parameters = parameters;
|
||||
existingPlugin.sortOrder =
|
||||
sortOrder !== undefined ? sortOrder : existingPlugin.sortOrder;
|
||||
await this.PluginEntity.save(existingPlugin);
|
||||
return '修改插件信息成功';
|
||||
}
|
||||
async delPlugin(body) {
|
||||
const { id } = body;
|
||||
const existingPlugin = await this.PluginEntity.findOne({
|
||||
where: { id },
|
||||
});
|
||||
if (!existingPlugin) {
|
||||
throw new common_1.HttpException('该插件不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const deleteResult = await this.PluginEntity.delete(id);
|
||||
if (deleteResult.affected > 0) {
|
||||
return '删除插件成功';
|
||||
}
|
||||
else {
|
||||
throw new common_1.HttpException('删除插件失败!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
};
|
||||
PluginService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__param(0, (0, typeorm_1.InjectRepository)(plugin_entity_1.PluginEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_2.Repository])
|
||||
], PluginService);
|
||||
exports.PluginService = PluginService;
|
55
dist/modules/queue/queue.controller.js
vendored
55
dist/modules/queue/queue.controller.js
vendored
|
@ -1,55 +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.QueueController = void 0;
|
||||
const queue_service_1 = require("./queue.service");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const mjDraw_dto_1 = require("./dto/mjDraw.dto");
|
||||
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
|
||||
let QueueController = class QueueController {
|
||||
constructor(queueService) {
|
||||
this.queueService = queueService;
|
||||
}
|
||||
async mjDraw(body, req) {
|
||||
return await this.queueService.addMjDrawQueue(body, req);
|
||||
}
|
||||
async getQueue() {
|
||||
return await this.queueService.getQueue();
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
(0, common_1.Post)('addMjDrawQueue'),
|
||||
(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", [mjDraw_dto_1.MjDrawDto, Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], QueueController.prototype, "mjDraw", null);
|
||||
__decorate([
|
||||
(0, common_1.Get)('getQueue'),
|
||||
(0, swagger_1.ApiOperation)({ summary: '查询任务队列' }),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", Promise)
|
||||
], QueueController.prototype, "getQueue", null);
|
||||
QueueController = __decorate([
|
||||
(0, swagger_1.ApiTags)('Queue'),
|
||||
(0, common_1.Controller)('queue'),
|
||||
__metadata("design:paramtypes", [queue_service_1.QueueService])
|
||||
], QueueController);
|
||||
exports.QueueController = QueueController;
|
38
dist/modules/queue/queue.module.js
vendored
38
dist/modules/queue/queue.module.js
vendored
|
@ -1,38 +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.QueueModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const queue_controller_1 = require("./queue.controller");
|
||||
const queue_service_1 = require("./queue.service");
|
||||
const bull_1 = require("@nestjs/bull");
|
||||
const queue_process_1 = require("./queue.process");
|
||||
let QueueModule = class QueueModule {
|
||||
};
|
||||
QueueModule = __decorate([
|
||||
(0, common_1.Module)({
|
||||
imports: [
|
||||
bull_1.BullModule.registerQueueAsync({
|
||||
name: 'MJDRAW',
|
||||
useFactory: () => {
|
||||
const config = {
|
||||
port: +process.env.REDIS_PORT,
|
||||
host: process.env.REDIS_HOST,
|
||||
};
|
||||
process.env.REDIS_PASSWORD && (config.password = process.env.REDIS_PASSWORD);
|
||||
return {
|
||||
redis: config,
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
controllers: [queue_controller_1.QueueController],
|
||||
providers: [queue_service_1.QueueService, queue_process_1.QueueProcessor],
|
||||
})
|
||||
], QueueModule);
|
||||
exports.QueueModule = QueueModule;
|
119
dist/modules/queue/queue.process.js
vendored
119
dist/modules/queue/queue.process.js
vendored
|
@ -1,119 +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 QueueProcessor_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.QueueProcessor = void 0;
|
||||
const bull_1 = require("@nestjs/bull");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const midjourney_service_1 = require("../midjourney/midjourney.service");
|
||||
let QueueProcessor = QueueProcessor_1 = class QueueProcessor {
|
||||
constructor(midjourneyService) {
|
||||
this.midjourneyService = midjourneyService;
|
||||
this.logger = new common_1.Logger(QueueProcessor_1.name);
|
||||
}
|
||||
async handleJob(job) {
|
||||
const res = await this.midjourneyService.draw(job.data, job.id);
|
||||
return res;
|
||||
}
|
||||
onQueueActive(job) {
|
||||
}
|
||||
onQueueError(error) {
|
||||
console.log('队列发生错误', error);
|
||||
}
|
||||
onQueueProgress(job, progress) {
|
||||
console.log('队列任务的一个回调用于通知当前进度', job.id, progress);
|
||||
}
|
||||
onQueueCompleted(job, result) {
|
||||
}
|
||||
onQueueFailed(job, err) {
|
||||
common_1.Logger.error(`Queue failed: ${err.message}: 绘画失败 ${job.id}`, 'QueueProcessor');
|
||||
this.midjourneyService.drawFailed(job.data);
|
||||
}
|
||||
onQueuePaused() {
|
||||
console.log('队列暂停的时候调用');
|
||||
}
|
||||
onQueueResumed() {
|
||||
console.log('队列恢复的时候调用');
|
||||
}
|
||||
onQueueCleaned(jobs, type) {
|
||||
common_1.Logger.log(`Queue cleaned: ${jobs.length} jobs of type ${type} were cleaned.`, 'QueueProcessor');
|
||||
}
|
||||
onQueueDrained() {
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
(0, bull_1.Process)({
|
||||
name: 'mjDraw',
|
||||
concurrency: process.env.CONCURRENCY ? +process.env.CONCURRENCY : 3,
|
||||
}),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], QueueProcessor.prototype, "handleJob", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueActive)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueActive", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueError)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Error]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueError", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueProgress)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Number]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueProgress", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueCompleted)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Object]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueCompleted", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueFailed)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, Error]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueFailed", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueuePaused)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueuePaused", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueResumed)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueResumed", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueCleaned)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Array, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueCleaned", null);
|
||||
__decorate([
|
||||
(0, bull_1.OnQueueDrained)(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], QueueProcessor.prototype, "onQueueDrained", null);
|
||||
QueueProcessor = QueueProcessor_1 = __decorate([
|
||||
(0, bull_1.Processor)('MJDRAW'),
|
||||
__metadata("design:paramtypes", [midjourney_service_1.MidjourneyService])
|
||||
], QueueProcessor);
|
||||
exports.QueueProcessor = QueueProcessor;
|
77
dist/modules/queue/queue.service.js
vendored
77
dist/modules/queue/queue.service.js
vendored
|
@ -1,77 +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.QueueService = void 0;
|
||||
const utils_1 = require("../../common/utils");
|
||||
const bull_1 = require("@nestjs/bull");
|
||||
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
|
||||
const midjourney_service_1 = require("../midjourney/midjourney.service");
|
||||
const models_service_1 = require("../models/models.service");
|
||||
const userBalance_service_1 = require("../userBalance/userBalance.service");
|
||||
let QueueService = class QueueService {
|
||||
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() {
|
||||
await this.mjDrawQueue.clean(0, 'active');
|
||||
await this.midjourneyService.cleanQueue();
|
||||
}
|
||||
async addMjDrawQueue(body, req) {
|
||||
const { orderId, action, drawId } = body;
|
||||
await this.midjourneyService.checkLimit(req);
|
||||
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 });
|
||||
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: action, userId: req.user.id }, { delay: 1000, timeout: +timeout });
|
||||
this.jobIds.push(job.id);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
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'])) || 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;
|
||||
}
|
||||
}
|
||||
async getQueue() {
|
||||
return { jobIds: this.jobIds };
|
||||
}
|
||||
};
|
||||
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,
|
||||
models_service_1.ModelsService])
|
||||
], QueueService);
|
||||
exports.QueueService = QueueService;
|
31
dist/modules/redisCache/redisCache.module.js
vendored
31
dist/modules/redisCache/redisCache.module.js
vendored
|
@ -8,48 +8,51 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RedisCacheModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const redisCache_service_1 = require("./redisCache.service");
|
||||
const redisCache_controller_1 = require("./redisCache.controller");
|
||||
const nestjs_config_1 = require("nestjs-config");
|
||||
const redis_1 = require("redis");
|
||||
const redisCache_controller_1 = require("./redisCache.controller");
|
||||
const redisCache_service_1 = require("./redisCache.service");
|
||||
let RedisCacheModule = class RedisCacheModule {
|
||||
};
|
||||
RedisCacheModule = __decorate([
|
||||
(0, common_1.Global)(),
|
||||
(0, common_1.Module)({
|
||||
imports: [nestjs_config_1.ConfigModule],
|
||||
imports: [],
|
||||
controllers: [redisCache_controller_1.RedisCacheController],
|
||||
providers: [
|
||||
{
|
||||
provide: 'REDIS_CLIENT',
|
||||
useFactory: async (redisConfig) => {
|
||||
const port = +process.env.REDIS_PORT;
|
||||
useFactory: async () => {
|
||||
const host = process.env.REDIS_HOST;
|
||||
const port = parseInt(process.env.REDIS_PORT, 10);
|
||||
const password = process.env.REDIS_PASSWORD;
|
||||
const username = process.env.REDIS_USER;
|
||||
const database = parseInt(process.env.REDIS_DB, 10) || 0;
|
||||
if (!host || !port) {
|
||||
common_1.Logger.error(`Please config Redis config | 未配置 Redis 配置信息 请确认配置redis服务以获得更好的体验`, 'RedistCacheModule');
|
||||
common_1.Logger.error(`Please configure Redis config | 未配置 Redis 配置信息,请确认配置 Redis 服务以获得更好的体验`, 'RedisCacheModule');
|
||||
return;
|
||||
}
|
||||
const client = (0, redis_1.createClient)({
|
||||
socket: { host, port },
|
||||
socket: {
|
||||
host,
|
||||
port,
|
||||
},
|
||||
username,
|
||||
password,
|
||||
database,
|
||||
});
|
||||
const res = await client.connect();
|
||||
client.on('ready', () => {
|
||||
common_1.Logger.debug(`Your Redis connection successful`, 'RedistCacheModule');
|
||||
common_1.Logger.log(`Redis connection successful`, 'RedisCacheModule');
|
||||
});
|
||||
client.on('error', () => {
|
||||
common_1.Logger.error(`Your Redis connection failed | 您的 Redist 连接失败`, 'RedistCacheModule');
|
||||
client.on('error', (err) => {
|
||||
common_1.Logger.error(`Redis connection failed: ${err}`, 'RedisCacheModule');
|
||||
});
|
||||
await client.connect();
|
||||
return client;
|
||||
},
|
||||
inject: [nestjs_config_1.ConfigService],
|
||||
},
|
||||
redisCache_service_1.RedisCacheService,
|
||||
],
|
||||
exports: ['REDIS_CLIENT'],
|
||||
exports: ['REDIS_CLIENT', redisCache_service_1.RedisCacheService],
|
||||
})
|
||||
], RedisCacheModule);
|
||||
exports.RedisCacheModule = RedisCacheModule;
|
||||
|
|
13
dist/modules/redisCache/redisCache.service.js
vendored
13
dist/modules/redisCache/redisCache.service.js
vendored
|
@ -18,12 +18,6 @@ let RedisCacheService = class RedisCacheService {
|
|||
constructor(redisClient) {
|
||||
this.redisClient = redisClient;
|
||||
}
|
||||
async onModuleInit() {
|
||||
}
|
||||
test() {
|
||||
this.redisClient.set('aaa', 111);
|
||||
return 1;
|
||||
}
|
||||
async get(body) {
|
||||
const { key } = body;
|
||||
const res = await this.redisClient.get(key);
|
||||
|
@ -40,6 +34,13 @@ let RedisCacheService = class RedisCacheService {
|
|||
throw new common_1.HttpException(error, common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
async getJwtSecret() {
|
||||
const secret = await this.redisClient.get('JWT_SECRET');
|
||||
if (!secret) {
|
||||
throw new Error('JWT secret not found in Redis');
|
||||
}
|
||||
return secret;
|
||||
}
|
||||
async ttl(key) {
|
||||
return await this.redisClient.ttl(key);
|
||||
}
|
||||
|
|
102
dist/modules/statistic/statistic.service.js
vendored
102
dist/modules/statistic/statistic.service.js
vendored
|
@ -13,25 +13,27 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.StatisticService = void 0;
|
||||
const balance_constant_1 = require("../../common/constants/balance.constant");
|
||||
const midjourney_constant_1 = require("../../common/constants/midjourney.constant");
|
||||
const date_1 = require("../../common/utils/date");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const axios_1 = require("axios");
|
||||
const typeorm_2 = require("typeorm");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
const balance_constant_1 = require("../../common/constants/balance.constant");
|
||||
const date_1 = require("../../common/utils/date");
|
||||
const axios_1 = require("axios");
|
||||
const config_entity_1 = require("../globalConfig/config.entity");
|
||||
const order_entity_1 = require("../order/order.entity");
|
||||
const globalConfig_service_1 = require("../globalConfig/globalConfig.service");
|
||||
const midjourney_entity_1 = require("../midjourney/midjourney.entity");
|
||||
const midjourney_constant_1 = require("../../common/constants/midjourney.constant");
|
||||
const order_entity_1 = require("../order/order.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
let StatisticService = class StatisticService {
|
||||
constructor(userEntity, chatLogEntity, configEntity, orderEntity, midjourneyEntity) {
|
||||
constructor(userEntity, chatLogEntity, configEntity, orderEntity, midjourneyEntity, globalConfigService) {
|
||||
this.userEntity = userEntity;
|
||||
this.chatLogEntity = chatLogEntity;
|
||||
this.configEntity = configEntity;
|
||||
this.orderEntity = orderEntity;
|
||||
this.midjourneyEntity = midjourneyEntity;
|
||||
this.globalConfigService = globalConfigService;
|
||||
}
|
||||
async getBaseStatistic() {
|
||||
const userCount = await this.countUsers();
|
||||
|
@ -79,11 +81,16 @@ let StatisticService = class StatisticService {
|
|||
today.setHours(0, 0, 0, 0);
|
||||
const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000);
|
||||
const queryBuilder = this.userEntity.createQueryBuilder('user');
|
||||
const userCount = await queryBuilder.where('user.createdAt >= :today', { today }).andWhere('user.createdAt < :tomorrow', { tomorrow }).getCount();
|
||||
const userCount = await queryBuilder
|
||||
.where('user.createdAt >= :today', { today })
|
||||
.andWhere('user.createdAt < :tomorrow', { tomorrow })
|
||||
.getCount();
|
||||
return userCount;
|
||||
}
|
||||
async countChats() {
|
||||
const chatCount = await this.chatLogEntity.count({ where: { type: balance_constant_1.ChatType.NORMAL_CHAT } });
|
||||
const chatCount = await this.chatLogEntity.count({
|
||||
where: { type: balance_constant_1.ChatType.NORMAL_CHAT },
|
||||
});
|
||||
return chatCount;
|
||||
}
|
||||
async countNewChatsToday() {
|
||||
|
@ -99,7 +106,9 @@ let StatisticService = class StatisticService {
|
|||
return chatCount;
|
||||
}
|
||||
async countDraws() {
|
||||
const drawCount = await this.chatLogEntity.count({ where: { type: balance_constant_1.ChatType.PAINT } });
|
||||
const drawCount = await this.chatLogEntity.count({
|
||||
where: { type: balance_constant_1.ChatType.PAINT },
|
||||
});
|
||||
return drawCount;
|
||||
}
|
||||
async countNewDrawsToday() {
|
||||
|
@ -189,7 +198,9 @@ let StatisticService = class StatisticService {
|
|||
const queryBuilder = this.midjourneyEntity.createQueryBuilder('midjourney');
|
||||
const result = await queryBuilder
|
||||
.select(`DATE(midjourney.createdAt) as date, COUNT(*) as count`)
|
||||
.where(`midjourney.status = :status`, { status: midjourney_constant_1.MidjourneyStatusEnum.DRAWED })
|
||||
.where(`midjourney.status = :status`, {
|
||||
status: midjourney_constant_1.MidjourneyStatusEnum.DRAWED,
|
||||
})
|
||||
.andWhere('midjourney.createdAt >= :startDate', { startDate })
|
||||
.groupBy('date')
|
||||
.orderBy('date')
|
||||
|
@ -210,28 +221,68 @@ let StatisticService = class StatisticService {
|
|||
return dailyData;
|
||||
}
|
||||
async getBaiduStatistics(days) {
|
||||
var _a, _b;
|
||||
const end_date = (0, date_1.formatDate)(new Date(), 'YYYYMMDD');
|
||||
const start_date = (0, date_1.formatDate)(new Date(Date.now() - Number(days - 1) * 24 * 60 * 60 * 1000), 'YYYYMMDD');
|
||||
const metrics = 'pv_count,visitor_count,ip_count,bounce_ratio,avg_visit_time';
|
||||
const method = 'overview/getTimeTrendRpt';
|
||||
const configInfo = await this.configEntity.find({ where: { configKey: (0, typeorm_2.In)(['baiduToken', 'baiduSiteId']) } });
|
||||
const siteId = (_a = configInfo.find((c) => c.configKey === 'baiduSiteId')) === null || _a === void 0 ? void 0 : _a.configVal;
|
||||
const accessToken = (_b = configInfo.find((c) => c.configKey === 'baiduToken')) === null || _b === void 0 ? void 0 : _b.configVal;
|
||||
if (!siteId || !accessToken) {
|
||||
const { baiduToken, baiduSiteId, baiduApiKey, baiduSecretKey, baiduRefreshToken, } = await this.globalConfigService.getConfigs([
|
||||
'baiduToken',
|
||||
'baiduSiteId',
|
||||
'baiduApiKey',
|
||||
'baiduSecretKey',
|
||||
'baiduRefreshToken',
|
||||
]);
|
||||
if (!baiduApiKey ||
|
||||
!baiduToken ||
|
||||
!baiduSiteId ||
|
||||
!baiduRefreshToken ||
|
||||
!baiduSecretKey) {
|
||||
return [];
|
||||
}
|
||||
if (!siteId) {
|
||||
throw new common_1.HttpException('请先配置百度统计siteId', common_1.HttpStatus.BAD_REQUEST);
|
||||
let accessToken = baiduToken;
|
||||
let url = `https://openapi.baidu.com/rest/2.0/tongji/report/getData?access_token=${accessToken}&site_id=${baiduSiteId}&method=${method}&start_date=${start_date}&end_date=${end_date}&metrics=${metrics}`;
|
||||
let res;
|
||||
try {
|
||||
res = await axios_1.default.get(url);
|
||||
}
|
||||
if (!accessToken) {
|
||||
throw new common_1.HttpException('请先配置百度统计accessToken', common_1.HttpStatus.BAD_REQUEST);
|
||||
catch (error) {
|
||||
res = {
|
||||
data: {
|
||||
error_code: 111,
|
||||
message: 'Access token invalid or no longer valid',
|
||||
},
|
||||
};
|
||||
}
|
||||
const url = `https://openapi.baidu.com/rest/2.0/tongji/report/getData?access_token=${accessToken}&site_id=${siteId}&method=${method}&start_date=${start_date}&end_date=${end_date}&metrics=${metrics}`;
|
||||
const res = await axios_1.default.get(url);
|
||||
const { error_code, message } = res.data;
|
||||
let { error_code, message } = res.data;
|
||||
if (error_code === 111) {
|
||||
throw new common_1.HttpException(message || '百度授权码过期', common_1.HttpStatus.BAD_REQUEST);
|
||||
const tokenUrl = `http://openapi.baidu.com/oauth/2.0/token?grant_type=refresh_token&refresh_token=${baiduRefreshToken}&client_id=${baiduApiKey}&client_secret=${baiduSecretKey}`;
|
||||
common_1.Logger.log('获取新 accessToken', tokenUrl);
|
||||
let tokenRes;
|
||||
try {
|
||||
tokenRes = await axios_1.default.get(tokenUrl);
|
||||
}
|
||||
catch (tokenError) {
|
||||
common_1.Logger.error('获取新 accessToken 失败', {
|
||||
message: tokenError.message,
|
||||
stack: tokenError.stack,
|
||||
response: tokenError.response
|
||||
? tokenError.response.data
|
||||
: 'No response data',
|
||||
});
|
||||
throw new common_1.HttpException('获取新 accessToken 失败', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (tokenRes.status === 200 && tokenRes.data.access_token) {
|
||||
accessToken = tokenRes.data.access_token;
|
||||
await this.configEntity.update({ configKey: 'baiduToken' }, {
|
||||
configVal: accessToken,
|
||||
});
|
||||
url = `https://openapi.baidu.com/rest/2.0/tongji/report/getData?access_token=${accessToken}&site_id=${baiduSiteId}&method=${method}&start_date=${start_date}&end_date=${end_date}&metrics=${metrics}`;
|
||||
res = await axios_1.default.get(url);
|
||||
({ error_code, message } = res.data);
|
||||
}
|
||||
else {
|
||||
throw new common_1.HttpException('获取新 accessToken 失败', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
if (error_code && error_code !== 200) {
|
||||
throw new common_1.HttpException(message || '获取百度统计数据失败', common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -265,6 +316,7 @@ StatisticService = __decorate([
|
|||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Repository])
|
||||
typeorm_2.Repository,
|
||||
globalConfig_service_1.GlobalConfigService])
|
||||
], StatisticService);
|
||||
exports.StatisticService = StatisticService;
|
||||
|
|
11
dist/modules/upload/upload.controller.js
vendored
11
dist/modules/upload/upload.controller.js
vendored
|
@ -21,11 +21,11 @@ let UploadController = class UploadController {
|
|||
constructor(uploadService) {
|
||||
this.uploadService = uploadService;
|
||||
}
|
||||
async uploadFile(file) {
|
||||
return this.uploadService.uploadFile(file);
|
||||
async uploadFile(file, dir) {
|
||||
return this.uploadService.uploadFile(file, dir);
|
||||
}
|
||||
async uploadFileFromUrl({ filename, url, dir = 'ai' }) {
|
||||
return this.uploadService.uploadFileFromUrl({ filename, url, dir });
|
||||
async uploadFileFromUrl({ url, dir = 'ai' }) {
|
||||
return this.uploadService.uploadFileFromUrl({ url, dir });
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
|
@ -33,8 +33,9 @@ __decorate([
|
|||
(0, swagger_1.ApiOperation)({ summary: '上传文件' }),
|
||||
(0, common_1.UseInterceptors)((0, platform_express_1.FileInterceptor)('file')),
|
||||
__param(0, (0, common_1.UploadedFile)()),
|
||||
__param(1, (0, common_1.Query)('dir')),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object]),
|
||||
__metadata("design:paramtypes", [Object, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], UploadController.prototype, "uploadFile", null);
|
||||
__decorate([
|
||||
|
|
195
dist/modules/upload/upload.service.js
vendored
195
dist/modules/upload/upload.service.js
vendored
|
@ -25,29 +25,57 @@ let UploadService = class UploadService {
|
|||
this.globalConfigService = globalConfigService;
|
||||
}
|
||||
onModuleInit() { }
|
||||
async uploadFile(file) {
|
||||
const { filename: name, originalname, buffer, dir = 'ai', mimetype } = file;
|
||||
const fileTyle = mimetype ? mimetype.split('/')[1] : '';
|
||||
const filename = originalname || name;
|
||||
common_1.Logger.debug(`准备上传文件: ${filename}, 类型: ${fileTyle}`, 'UploadService');
|
||||
const { tencentCosStatus = 0, aliOssStatus = 0, cheveretoStatus = 0, } = await this.globalConfigService.getConfigs(['tencentCosStatus', 'aliOssStatus', 'cheveretoStatus']);
|
||||
async uploadFile(file, dir = 'others') {
|
||||
const { filename: name, originalname, buffer, mimetype, } = file;
|
||||
if (process.env.ISDEV) {
|
||||
dir = `dev/${dir}`;
|
||||
}
|
||||
common_1.Logger.debug(`准备上传文件: ${dir}`, 'UploadService');
|
||||
const now = new Date();
|
||||
const timestamp = now.getTime();
|
||||
const randomString = Math.random().toString(36).substring(2, 6);
|
||||
const fileType = mimetype ? mimetype.split('/')[1] : '';
|
||||
const filename = `${timestamp}_${randomString}.${fileType}`;
|
||||
common_1.Logger.debug(`准备上传文件: ${filename}, 类型: ${fileType}`, 'UploadService');
|
||||
const { tencentCosStatus = 0, aliOssStatus = 0, cheveretoStatus = 0, } = await this.globalConfigService.getConfigs([
|
||||
'tencentCosStatus',
|
||||
'aliOssStatus',
|
||||
'cheveretoStatus',
|
||||
]);
|
||||
common_1.Logger.debug(`上传配置状态 - 腾讯云: ${tencentCosStatus}, 阿里云: ${aliOssStatus}, Chevereto: ${cheveretoStatus}`, 'UploadService');
|
||||
if (!Number(tencentCosStatus) && !Number(aliOssStatus) && !Number(cheveretoStatus)) {
|
||||
if (!Number(tencentCosStatus) &&
|
||||
!Number(aliOssStatus) &&
|
||||
!Number(cheveretoStatus)) {
|
||||
throw new common_1.HttpException('请先前往后台配置上传图片的方式', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
try {
|
||||
if (Number(tencentCosStatus)) {
|
||||
common_1.Logger.debug(`使用腾讯云COS上传`, 'UploadService');
|
||||
return await this.uploadFileByTencentCos({ filename, buffer, dir, fileTyle });
|
||||
return await this.uploadFileByTencentCos({
|
||||
filename,
|
||||
buffer,
|
||||
dir,
|
||||
fileType,
|
||||
});
|
||||
}
|
||||
if (Number(aliOssStatus)) {
|
||||
common_1.Logger.debug(`使用阿里云OSS上传`, 'UploadService');
|
||||
return await this.uploadFileByAliOss({ filename, buffer, dir, fileTyle });
|
||||
return await this.uploadFileByAliOss({
|
||||
filename,
|
||||
buffer,
|
||||
dir,
|
||||
fileType,
|
||||
});
|
||||
}
|
||||
if (Number(cheveretoStatus)) {
|
||||
common_1.Logger.debug(`使用Chevereto上传`, 'UploadService');
|
||||
const { filename, buffer: fromBuffer, dir } = file;
|
||||
return await this.uploadFileByChevereto({ filename, buffer: fromBuffer.toString('base64'), dir, fileTyle });
|
||||
return await this.uploadFileByChevereto({
|
||||
filename,
|
||||
buffer: fromBuffer.toString('base64'),
|
||||
dir,
|
||||
fileType,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
|
@ -56,7 +84,11 @@ let UploadService = class UploadService {
|
|||
}
|
||||
}
|
||||
async getUploadType() {
|
||||
const { tencentCosStatus = 0, aliOssStatus = 0, cheveretoStatus = 0, } = await this.globalConfigService.getConfigs(['tencentCosStatus', 'aliOssStatus', 'cheveretoStatus']);
|
||||
const { tencentCosStatus = 0, aliOssStatus = 0, cheveretoStatus = 0, } = await this.globalConfigService.getConfigs([
|
||||
'tencentCosStatus',
|
||||
'aliOssStatus',
|
||||
'cheveretoStatus',
|
||||
]);
|
||||
if (Number(tencentCosStatus)) {
|
||||
return 'tencent';
|
||||
}
|
||||
|
@ -67,10 +99,72 @@ let UploadService = class UploadService {
|
|||
return 'chevereto';
|
||||
}
|
||||
}
|
||||
async uploadFileFromUrl({ filename, url, dir = 'ai' }) {
|
||||
dir = process.env.ISDEV ? 'mjdev' : dir;
|
||||
const { tencentCosStatus = 0, aliOssStatus = 0, cheveretoStatus = 0, } = await this.globalConfigService.getConfigs(['tencentCosStatus', 'aliOssStatus', 'cheveretoStatus']);
|
||||
if (!Number(tencentCosStatus) && !Number(aliOssStatus) && !Number(cheveretoStatus)) {
|
||||
async uploadFileFromUrl({ url, dir = 'others' }) {
|
||||
if (process.env.ISDEV) {
|
||||
dir = `dev/${dir}`;
|
||||
}
|
||||
const now = new Date();
|
||||
const timestamp = now.getTime();
|
||||
const randomString = Math.random().toString(36).substring(2, 6);
|
||||
const response = await axios_1.default.head(url);
|
||||
const mimeType = response.headers['content-type'];
|
||||
let fileExtension = '';
|
||||
if (mimeType) {
|
||||
const mimeTypeMap = {
|
||||
'image/jpeg': 'jpg',
|
||||
'image/png': 'png',
|
||||
'image/gif': 'gif',
|
||||
'image/webp': 'webp',
|
||||
'image/bmp': 'bmp',
|
||||
'image/svg+xml': 'svg',
|
||||
'image/tiff': 'tiff',
|
||||
'image/x-icon': 'ico',
|
||||
'video/mp4': 'mp4',
|
||||
'video/mpeg': 'mpeg',
|
||||
'video/ogg': 'ogv',
|
||||
'video/webm': 'webm',
|
||||
'video/quicktime': 'mov',
|
||||
'video/x-msvideo': 'avi',
|
||||
'video/x-flv': 'flv',
|
||||
'audio/mpeg': 'mp3',
|
||||
'audio/ogg': 'ogg',
|
||||
'audio/wav': 'wav',
|
||||
'audio/x-wav': 'wav',
|
||||
'audio/webm': 'weba',
|
||||
'application/pdf': 'pdf',
|
||||
'application/msword': 'doc',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
|
||||
'application/vnd.ms-excel': 'xls',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',
|
||||
'application/vnd.ms-powerpoint': 'ppt',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'pptx',
|
||||
'application/zip': 'zip',
|
||||
'application/x-rar-compressed': 'rar',
|
||||
'application/x-7z-compressed': '7z',
|
||||
'text/plain': 'txt',
|
||||
'text/html': 'html',
|
||||
'text/css': 'css',
|
||||
'text/javascript': 'js',
|
||||
'application/json': 'json',
|
||||
'application/xml': 'xml',
|
||||
'application/octet-stream': 'bin',
|
||||
'application/vnd.android.package-archive': 'apk',
|
||||
'application/x-sh': 'sh',
|
||||
};
|
||||
fileExtension = mimeTypeMap[mimeType] || '';
|
||||
}
|
||||
const filename = fileExtension
|
||||
? `${timestamp}_${randomString}.${fileExtension}`
|
||||
: `${timestamp}_${randomString}`;
|
||||
common_1.Logger.debug(`准备上传文件: ${filename}, URL: ${url}, 目录: ${dir}`, 'UploadService');
|
||||
const { tencentCosStatus = 0, aliOssStatus = 0, cheveretoStatus = 0, } = await this.globalConfigService.getConfigs([
|
||||
'tencentCosStatus',
|
||||
'aliOssStatus',
|
||||
'cheveretoStatus',
|
||||
]);
|
||||
if (!Number(tencentCosStatus) &&
|
||||
!Number(aliOssStatus) &&
|
||||
!Number(cheveretoStatus)) {
|
||||
throw new common_1.HttpException('请先前往后台配置上传图片的方式', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (Number(tencentCosStatus)) {
|
||||
|
@ -84,16 +178,20 @@ let UploadService = class UploadService {
|
|||
return await this.uploadFileByCheveretoFromUrl({ filename, url, dir });
|
||||
}
|
||||
}
|
||||
async uploadFileByTencentCos({ filename, buffer, dir, fileTyle }) {
|
||||
async uploadFileByTencentCos({ filename, buffer, dir, fileType }) {
|
||||
const { Bucket, Region, SecretId, SecretKey } = await this.getUploadConfig('tencent');
|
||||
this.tencentCos = new TENCENTCOS({ SecretId, SecretKey, FileParallelLimit: 10 });
|
||||
this.tencentCos = new TENCENTCOS({
|
||||
SecretId,
|
||||
SecretKey,
|
||||
FileParallelLimit: 10,
|
||||
});
|
||||
try {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const type = fileTyle || 'png';
|
||||
const type = fileType || 'png';
|
||||
this.tencentCos.putObject({
|
||||
Bucket: (0, utils_1.removeSpecialCharacters)(Bucket),
|
||||
Region: (0, utils_1.removeSpecialCharacters)(Region),
|
||||
Key: `${dir}/${filename || `${(0, utils_1.createRandomUid)()}.${fileTyle}`}`,
|
||||
Key: `${dir}/${filename || `${(0, utils_1.createRandomUid)()}.${fileType}`}`,
|
||||
StorageClass: 'STANDARD',
|
||||
Body: buffer,
|
||||
}, async (err, data) => {
|
||||
|
@ -118,25 +216,44 @@ let UploadService = class UploadService {
|
|||
}
|
||||
async uploadFileByTencentCosFromUrl({ filename, url, dir }) {
|
||||
const { Bucket, Region, SecretId, SecretKey } = await this.getUploadConfig('tencent');
|
||||
this.tencentCos = new TENCENTCOS({ SecretId, SecretKey, FileParallelLimit: 10 });
|
||||
this.tencentCos = new TENCENTCOS({
|
||||
SecretId,
|
||||
SecretKey,
|
||||
FileParallelLimit: 10,
|
||||
});
|
||||
try {
|
||||
const buffer = await this.getBufferFromUrl(url);
|
||||
return await this.uploadFileByTencentCos({ filename, buffer, dir, fileTyle: '' });
|
||||
return await this.uploadFileByTencentCos({
|
||||
filename,
|
||||
buffer,
|
||||
dir,
|
||||
fileType: '',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.log('TODO->error: ', error);
|
||||
throw new common_1.HttpException('上传图片失败[ten][url]', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
async uploadFileByAliOss({ filename, buffer, dir, fileTyle = 'png' }) {
|
||||
async uploadFileByAliOss({ filename, buffer, dir, fileType = 'png' }) {
|
||||
const { region, bucket, accessKeyId, accessKeySecret } = await this.getUploadConfig('ali');
|
||||
const client = new ALIOSS({ region: (0, utils_1.removeSpecialCharacters)(region), accessKeyId, accessKeySecret, bucket: (0, utils_1.removeSpecialCharacters)(bucket) });
|
||||
const client = new ALIOSS({
|
||||
region: (0, utils_1.removeSpecialCharacters)(region),
|
||||
accessKeyId,
|
||||
accessKeySecret,
|
||||
bucket: (0, utils_1.removeSpecialCharacters)(bucket),
|
||||
});
|
||||
try {
|
||||
console.log('ali 开始上传');
|
||||
return new Promise((resolve, reject) => {
|
||||
client
|
||||
.put(`${dir}/${filename || `${(0, utils_1.createRandomUid)()}.${fileTyle}`}`, buffer)
|
||||
.then((result) => {
|
||||
.put(`${dir}/${filename || `${(0, utils_1.createRandomUid)()}.${fileType}`}`, buffer)
|
||||
.then(async (result) => {
|
||||
const { acceleratedDomain } = await this.getUploadConfig('ali');
|
||||
if (acceleratedDomain) {
|
||||
result.url = result.url.replace(/^(https:\/\/[^/]+)(\/.*)$/, `https://${acceleratedDomain}$2`);
|
||||
console.log('当前已开启全球加速----------------->', result.url);
|
||||
}
|
||||
resolve(result.url);
|
||||
})
|
||||
.catch((err) => {
|
||||
|
@ -160,7 +277,7 @@ let UploadService = class UploadService {
|
|||
}
|
||||
async uploadFileToLocal({ filename, buffer, dir = 'ai' }) {
|
||||
if (!filename || !buffer) {
|
||||
throw new Error("必须提供文件名和文件内容");
|
||||
throw new Error('必须提供文件名和文件内容');
|
||||
}
|
||||
const appRoot = require('app-root-path');
|
||||
const uploadDir = path_1.default.join(appRoot.path, 'service', 'public', 'file');
|
||||
|
@ -187,7 +304,7 @@ let UploadService = class UploadService {
|
|||
throw new common_1.HttpException('上传图片失败[ALI][url]', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
async uploadFileByChevereto({ filename = '', buffer, dir = 'ai', fileTyle = 'png' }) {
|
||||
async uploadFileByChevereto({ filename = '', buffer, dir = 'ai', fileType = 'png', }) {
|
||||
var _a;
|
||||
const { key, uploadPath } = await this.getUploadConfig('chevereto');
|
||||
let url = uploadPath.endsWith('/') ? uploadPath.slice(0, -1) : uploadPath;
|
||||
|
@ -225,11 +342,29 @@ let UploadService = class UploadService {
|
|||
}
|
||||
async getUploadConfig(type) {
|
||||
if (type === 'ali') {
|
||||
const { aliOssRegion: region, aliOssBucket: bucket, aliOssAccessKeyId: accessKeyId, aliOssAccessKeySecret: accessKeySecret, } = await this.globalConfigService.getConfigs(['aliOssRegion', 'aliOssBucket', 'aliOssAccessKeyId', 'aliOssAccessKeySecret']);
|
||||
return { region, bucket, accessKeyId, accessKeySecret };
|
||||
const { aliOssRegion: region, aliOssBucket: bucket, aliOssAccessKeyId: accessKeyId, aliOssAccessKeySecret: accessKeySecret, aliOssAcceleratedDomain: acceleratedDomain, } = await this.globalConfigService.getConfigs([
|
||||
'aliOssRegion',
|
||||
'aliOssBucket',
|
||||
'aliOssAccessKeyId',
|
||||
'aliOssAccessKeySecret',
|
||||
'acceleratedDomain',
|
||||
]);
|
||||
return {
|
||||
region,
|
||||
bucket,
|
||||
accessKeyId,
|
||||
accessKeySecret,
|
||||
acceleratedDomain,
|
||||
};
|
||||
}
|
||||
if (type === 'tencent') {
|
||||
const { cosBucket: Bucket, cosRegion: Region, cosSecretId: SecretId, cosSecretKey: SecretKey, tencentCosAcceleratedDomain: acceleratedDomain, } = await this.globalConfigService.getConfigs(['cosBucket', 'cosRegion', 'cosSecretId', 'cosSecretKey', 'tencentCosAcceleratedDomain']);
|
||||
const { cosBucket: Bucket, cosRegion: Region, cosSecretId: SecretId, cosSecretKey: SecretKey, tencentCosAcceleratedDomain: acceleratedDomain, } = await this.globalConfigService.getConfigs([
|
||||
'cosBucket',
|
||||
'cosRegion',
|
||||
'cosSecretId',
|
||||
'cosSecretKey',
|
||||
'tencentCosAcceleratedDomain',
|
||||
]);
|
||||
return { Bucket, Region, SecretId, SecretKey, acceleratedDomain };
|
||||
}
|
||||
if (type === 'chevereto') {
|
||||
|
|
9
dist/modules/user/user.entity.js
vendored
9
dist/modules/user/user.entity.js
vendored
|
@ -10,8 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UserEntity = void 0;
|
||||
const typeorm_1 = require("typeorm");
|
||||
const baseEntity_1 = require("../../common/entity/baseEntity");
|
||||
const typeorm_1 = require("typeorm");
|
||||
let UserEntity = class UserEntity extends baseEntity_1.BaseEntity {
|
||||
};
|
||||
__decorate([
|
||||
|
@ -61,7 +61,12 @@ __decorate([
|
|||
__metadata("design:type", String)
|
||||
], UserEntity.prototype, "registerIp", void 0);
|
||||
__decorate([
|
||||
(0, typeorm_1.Column)({ length: 64, default: '', comment: '最后一次登录IP', nullable: true }),
|
||||
(0, typeorm_1.Column)({
|
||||
length: 64,
|
||||
default: '',
|
||||
comment: '最后一次登录IP',
|
||||
nullable: true,
|
||||
}),
|
||||
__metadata("design:type", String)
|
||||
], UserEntity.prototype, "lastLoginIp", void 0);
|
||||
__decorate([
|
||||
|
|
12
dist/modules/user/user.module.js
vendored
12
dist/modules/user/user.module.js
vendored
|
@ -9,7 +9,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.UserModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const whiteList_entity_1 = require("../chat/whiteList.entity");
|
||||
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
const cramiPackage_entity_1 = require("../crami/cramiPackage.entity");
|
||||
|
@ -41,17 +40,22 @@ UserModule = __decorate([
|
|||
accountLog_entity_1.AccountLogEntity,
|
||||
config_entity_1.ConfigEntity,
|
||||
cramiPackage_entity_1.CramiPackageEntity,
|
||||
whiteList_entity_1.WhiteListEntity,
|
||||
userBalance_entity_1.UserBalanceEntity,
|
||||
salesUsers_entity_1.SalesUsersEntity,
|
||||
fingerprint_entity_1.FingerprintLogEntity,
|
||||
chatLog_entity_1.ChatLogEntity,
|
||||
chatGroup_entity_1.ChatGroupEntity,
|
||||
midjourney_entity_1.MidjourneyEntity
|
||||
midjourney_entity_1.MidjourneyEntity,
|
||||
]),
|
||||
],
|
||||
controllers: [user_controller_1.UserController],
|
||||
providers: [user_service_1.UserService, verification_service_1.VerificationService, userBalance_service_1.UserBalanceService, redisCache_service_1.RedisCacheService, mailer_service_1.MailerService,],
|
||||
providers: [
|
||||
user_service_1.UserService,
|
||||
verification_service_1.VerificationService,
|
||||
userBalance_service_1.UserBalanceService,
|
||||
redisCache_service_1.RedisCacheService,
|
||||
mailer_service_1.MailerService,
|
||||
],
|
||||
exports: [user_service_1.UserService],
|
||||
})
|
||||
], UserModule);
|
||||
|
|
172
dist/modules/user/user.service.js
vendored
172
dist/modules/user/user.service.js
vendored
|
@ -22,7 +22,6 @@ const typeorm_1 = require("@nestjs/typeorm");
|
|||
const bcrypt = require("bcryptjs");
|
||||
const _ = require("lodash");
|
||||
const typeorm_2 = require("typeorm");
|
||||
const whiteList_entity_1 = require("../chat/whiteList.entity");
|
||||
const config_entity_1 = require("../globalConfig/config.entity");
|
||||
const userBalance_service_1 = require("../userBalance/userBalance.service");
|
||||
const user_constant_1 = require("./../../common/constants/user.constant");
|
||||
|
@ -30,9 +29,8 @@ const globalConfig_service_1 = require("./../globalConfig/globalConfig.service")
|
|||
const verification_service_1 = require("./../verification/verification.service");
|
||||
const user_entity_1 = require("./user.entity");
|
||||
let UserService = class UserService {
|
||||
constructor(userEntity, whiteListEntity, connection, verificationService, mailerService, userBalanceService, globalConfigService, configEntity) {
|
||||
constructor(userEntity, connection, verificationService, mailerService, userBalanceService, globalConfigService, configEntity) {
|
||||
this.userEntity = userEntity;
|
||||
this.whiteListEntity = whiteListEntity;
|
||||
this.connection = connection;
|
||||
this.verificationService = verificationService;
|
||||
this.mailerService = mailerService;
|
||||
|
@ -43,7 +41,9 @@ let UserService = class UserService {
|
|||
async createUserAndVerifycation(user, req) {
|
||||
const { username, email, password, invitedBy, client = 0 } = user;
|
||||
if (invitedBy) {
|
||||
const b = await this.userEntity.findOne({ where: { inviteCode: invitedBy } });
|
||||
const b = await this.userEntity.findOne({
|
||||
where: { inviteCode: invitedBy },
|
||||
});
|
||||
if (!b) {
|
||||
throw new common_1.HttpException('无效的邀请码!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -62,7 +62,9 @@ let UserService = class UserService {
|
|||
userInput.client = client;
|
||||
let n;
|
||||
if (!u) {
|
||||
const userDefautlAvatar = await this.globalConfigService.getConfigs(['userDefautlAvatar']);
|
||||
const userDefautlAvatar = await this.globalConfigService.getConfigs([
|
||||
'userDefautlAvatar',
|
||||
]);
|
||||
userInput.avatar = userDefautlAvatar;
|
||||
n = await this.userEntity.save(userInput);
|
||||
}
|
||||
|
@ -85,9 +87,13 @@ let UserService = class UserService {
|
|||
pre[cur.configKey] = cur.configVal;
|
||||
return pre;
|
||||
}, {});
|
||||
const isVerifyEmail = configMap['isVerifyEmail'] ? Number(configMap['isVerifyEmail']) : 1;
|
||||
const isVerifyEmail = configMap['isVerifyEmail']
|
||||
? Number(configMap['isVerifyEmail'])
|
||||
: 1;
|
||||
if (isVerifyEmail) {
|
||||
const expir = configMap['registerVerifyExpir'] ? Number(configMap['registerVerifyExpir']) : 30 * 60;
|
||||
const expir = configMap['registerVerifyExpir']
|
||||
? Number(configMap['registerVerifyExpir'])
|
||||
: 30 * 60;
|
||||
const v = await this.verificationService.createVerification(n, verification_constant_1.VerificationEnum.Registration, expir);
|
||||
const { code, email, id } = v;
|
||||
const { registerVerifyEmailFrom } = configMap;
|
||||
|
@ -127,7 +133,11 @@ let UserService = class UserService {
|
|||
}
|
||||
}
|
||||
if (username && password) {
|
||||
const where = [{ username }, { email: username }, { phone: username }];
|
||||
const where = [
|
||||
{ username },
|
||||
{ email: username },
|
||||
{ phone: username },
|
||||
];
|
||||
u = await this.userEntity.findOne({ where: where });
|
||||
if (!u) {
|
||||
throw new common_1.HttpException('当前账户不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -180,7 +190,16 @@ let UserService = class UserService {
|
|||
async getUserInfo(userId) {
|
||||
const userInfo = await this.userEntity.findOne({
|
||||
where: { id: userId },
|
||||
select: ['username', 'avatar', 'role', 'email', 'sign', 'inviteCode', 'openId', 'consecutiveDays'],
|
||||
select: [
|
||||
'username',
|
||||
'avatar',
|
||||
'role',
|
||||
'email',
|
||||
'sign',
|
||||
'inviteCode',
|
||||
'openId',
|
||||
'consecutiveDays',
|
||||
],
|
||||
});
|
||||
if (!userInfo) {
|
||||
throw new common_1.HttpException('当前用户信息失效、请重新登录!', common_1.HttpStatus.UNAUTHORIZED);
|
||||
|
@ -206,8 +225,8 @@ let UserService = class UserService {
|
|||
throw new common_1.HttpException('没有变更,无需更改!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (body.username) {
|
||||
const u = await this.userEntity.findOne({ where: { username: body.username, id: (0, typeorm_2.Not)(id) } });
|
||||
if (u) {
|
||||
const usernameTaken = await this.isUsernameTaken(body.username, id);
|
||||
if (usernameTaken) {
|
||||
throw new common_1.HttpException('用户名已存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +236,14 @@ let UserService = class UserService {
|
|||
}
|
||||
return '修改用户信息成功!';
|
||||
}
|
||||
async isUsernameTaken(username, excludeUserId) {
|
||||
const where = { username };
|
||||
if (excludeUserId) {
|
||||
where.id = (0, typeorm_2.Not)(excludeUserId);
|
||||
}
|
||||
const user = await this.userEntity.findOne({ where });
|
||||
return !!user;
|
||||
}
|
||||
async updateUserPassword(userId, password) {
|
||||
const hashedPassword = bcrypt.hashSync(password, 10);
|
||||
const r = await this.userEntity.update({ id: userId }, { password: hashedPassword });
|
||||
|
@ -253,7 +280,14 @@ let UserService = class UserService {
|
|||
const [rows, count] = await this.userEntity.findAndCount({
|
||||
where: { invitedBy },
|
||||
order: { id: 'DESC' },
|
||||
select: ['username', 'email', 'createdAt', 'status', 'avatar', 'updatedAt'],
|
||||
select: [
|
||||
'username',
|
||||
'email',
|
||||
'createdAt',
|
||||
'status',
|
||||
'avatar',
|
||||
'updatedAt',
|
||||
],
|
||||
take: size,
|
||||
skip: (page - 1) * size,
|
||||
});
|
||||
|
@ -286,7 +320,11 @@ let UserService = class UserService {
|
|||
}
|
||||
async userRecharge(body) {
|
||||
const { userId, model3Count = 0, model4Count = 0, drawMjCount = 0 } = body;
|
||||
await this.userBalanceService.addBalanceToUser(userId, { model3Count, model4Count, drawMjCount });
|
||||
await this.userBalanceService.addBalanceToUser(userId, {
|
||||
model3Count,
|
||||
model4Count,
|
||||
drawMjCount,
|
||||
});
|
||||
const res = await this.userBalanceService.saveRecordRechargeLog({
|
||||
userId,
|
||||
rechargeType: balance_constant_1.RechargeType.ADMIN_GIFT,
|
||||
|
@ -298,14 +336,18 @@ let UserService = class UserService {
|
|||
return res;
|
||||
}
|
||||
async queryAll(query, req) {
|
||||
const { page = 1, size = 10, username, email, status, keyword, phone } = query;
|
||||
const { page = 1, size = 10, username, email, status, keyword, phone, } = query;
|
||||
let where = {};
|
||||
username && Object.assign(where, { username: (0, typeorm_2.Like)(`%${username}%`) });
|
||||
email && Object.assign(where, { email: (0, typeorm_2.Like)(`%${email}%`) });
|
||||
phone && Object.assign(where, { phone: (0, typeorm_2.Like)(`%${phone}%`) });
|
||||
status && Object.assign(where, { status });
|
||||
if (keyword) {
|
||||
where = [{ username: (0, typeorm_2.Like)(`%${keyword}%`) }, { email: (0, typeorm_2.Like)(`%${keyword}%`) }, { phone: (0, typeorm_2.Like)(`%${keyword}%`) }];
|
||||
where = [
|
||||
{ username: (0, typeorm_2.Like)(`%${keyword}%`) },
|
||||
{ email: (0, typeorm_2.Like)(`%${keyword}%`) },
|
||||
{ phone: (0, typeorm_2.Like)(`%${keyword}%`) },
|
||||
];
|
||||
}
|
||||
const [rows, count] = await this.userEntity.findAndCount({
|
||||
skip: (page - 1) * size,
|
||||
|
@ -313,18 +355,36 @@ let UserService = class UserService {
|
|||
take: size,
|
||||
order: { createdAt: 'DESC' },
|
||||
cache: true,
|
||||
select: ['username', 'avatar', 'inviteCode', 'role', 'sign', 'status', 'id', 'email', 'createdAt', 'lastLoginIp', 'phone'],
|
||||
select: [
|
||||
'username',
|
||||
'avatar',
|
||||
'inviteCode',
|
||||
'role',
|
||||
'sign',
|
||||
'status',
|
||||
'id',
|
||||
'email',
|
||||
'createdAt',
|
||||
'lastLoginIp',
|
||||
'phone',
|
||||
],
|
||||
});
|
||||
const ids = rows.map((t) => t.id);
|
||||
const data = await this.userBalanceService.queryUserBalanceByIds(ids);
|
||||
rows.forEach((user) => (user.balanceInfo = data.find((t) => t.userId === user.id)));
|
||||
req.user.role !== 'super' && rows.forEach((t) => (t.email = (0, utils_1.maskEmail)(t.email)));
|
||||
req.user.role !== 'super' && rows.forEach((t) => (t.lastLoginIp = (0, utils_1.maskIpAddress)(t.lastLoginIp)));
|
||||
req.user.role !== 'super' && rows.forEach((t) => (t.phone = (0, utils_1.maskIpAddress)(t.phone)));
|
||||
req.user.role !== 'super' &&
|
||||
rows.forEach((t) => (t.email = (0, utils_1.maskEmail)(t.email)));
|
||||
req.user.role !== 'super' &&
|
||||
rows.forEach((t) => (t.lastLoginIp = (0, utils_1.maskIpAddress)(t.lastLoginIp)));
|
||||
req.user.role !== 'super' &&
|
||||
rows.forEach((t) => (t.phone = (0, utils_1.maskIpAddress)(t.phone)));
|
||||
return { rows, count };
|
||||
}
|
||||
async queryOne({ id }) {
|
||||
return await this.userEntity.findOne({ where: { id }, select: ['username', 'avatar', 'inviteCode', 'role', 'sign', 'status'] });
|
||||
return await this.userEntity.findOne({
|
||||
where: { id },
|
||||
select: ['username', 'avatar', 'inviteCode', 'role', 'sign', 'status'],
|
||||
});
|
||||
}
|
||||
async updateStatus(body) {
|
||||
const { id, status } = body;
|
||||
|
@ -373,7 +433,9 @@ let UserService = class UserService {
|
|||
return user;
|
||||
}
|
||||
async createUserFromOpenId(openId, invitedBy) {
|
||||
const userDefautlAvatar = await this.globalConfigService.getConfigs(['userDefautlAvatar']);
|
||||
const userDefautlAvatar = await this.globalConfigService.getConfigs([
|
||||
'userDefautlAvatar',
|
||||
]);
|
||||
const userInfo = {
|
||||
avatar: userDefautlAvatar,
|
||||
username: `用户${(0, utils_1.createRandomUid)()}`,
|
||||
|
@ -386,6 +448,46 @@ let UserService = class UserService {
|
|||
const user = await this.userEntity.save(userInfo);
|
||||
return user;
|
||||
}
|
||||
async createUserFromContact(params) {
|
||||
const { username, email, phone, invitedBy } = params;
|
||||
const userDefautlAvatar = await this.globalConfigService.getConfigs([
|
||||
'userDefautlAvatar',
|
||||
]);
|
||||
const userInfo = {
|
||||
avatar: userDefautlAvatar,
|
||||
username: `用户${(0, utils_1.createRandomUid)()}`,
|
||||
status: user_constant_1.UserStatusEnum.ACTIVE,
|
||||
sex: 0,
|
||||
};
|
||||
if (username) {
|
||||
userInfo.username = username;
|
||||
}
|
||||
if (email) {
|
||||
userInfo.email = email;
|
||||
}
|
||||
if (phone) {
|
||||
userInfo.phone = phone;
|
||||
}
|
||||
if (invitedBy) {
|
||||
userInfo.invitedBy = invitedBy;
|
||||
}
|
||||
const user = await this.userEntity.save(userInfo);
|
||||
return user;
|
||||
}
|
||||
async getUserByContact(params) {
|
||||
const { username, email, phone } = params;
|
||||
const where = [];
|
||||
if (username) {
|
||||
where.push({ username });
|
||||
}
|
||||
if (email) {
|
||||
where.push({ email });
|
||||
}
|
||||
if (phone) {
|
||||
where.push({ phone });
|
||||
}
|
||||
return await this.userEntity.findOne({ where });
|
||||
}
|
||||
async bindWx(openId, userId) {
|
||||
try {
|
||||
const user = await this.userEntity.findOne({ where: { id: userId } });
|
||||
|
@ -412,23 +514,33 @@ let UserService = class UserService {
|
|||
if (phone) {
|
||||
const userByPhone = await this.userEntity.findOne({ where: { phone } });
|
||||
if (userByPhone) {
|
||||
throw new common_1.HttpException('当前手机号已注册、请勿重复注册!', common_1.HttpStatus.BAD_REQUEST);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (email) {
|
||||
const userByEmail = await this.userEntity.findOne({ where: { email } });
|
||||
if (userByEmail) {
|
||||
throw new common_1.HttpException('当前邮箱已注册、请勿重复注册!', common_1.HttpStatus.BAD_REQUEST);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const userByUsername = await this.userEntity.findOne({ where: { username } });
|
||||
if (username) {
|
||||
const userByUsername = await this.userEntity.findOne({
|
||||
where: { username },
|
||||
});
|
||||
if (userByUsername) {
|
||||
throw new common_1.HttpException('用户名已存在、请更换用户名!', common_1.HttpStatus.BAD_REQUEST);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!phone && !email && !username) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
async verifyUserRegisterByPhone(params) {
|
||||
const { username, password, phone, phoneCode } = params;
|
||||
const user = await this.userEntity.findOne({ where: [{ username }, { phone }] });
|
||||
const user = await this.userEntity.findOne({
|
||||
where: [{ username }, { phone }],
|
||||
});
|
||||
if (user && user.username === username) {
|
||||
throw new common_1.HttpException('用户名已存在、请更换用户名!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -439,7 +551,9 @@ let UserService = class UserService {
|
|||
async verifyUserRegisterByEmail(params) {
|
||||
const { username, email } = params;
|
||||
console.log(`校验邮箱注册: 开始 - 用户名: ${username}, 邮箱: ${email}`);
|
||||
const user = await this.userEntity.findOne({ where: [{ username }, { email }] });
|
||||
const user = await this.userEntity.findOne({
|
||||
where: [{ username }, { email }],
|
||||
});
|
||||
if (user && user.username === username) {
|
||||
console.error(`校验失败: 用户名 "${username}" 已存在`);
|
||||
throw new common_1.HttpException('用户名已存在、请更换用户名!', common_1.HttpStatus.BAD_REQUEST);
|
||||
|
@ -457,10 +571,8 @@ let UserService = class UserService {
|
|||
UserService = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__param(0, (0, typeorm_1.InjectRepository)(user_entity_1.UserEntity)),
|
||||
__param(1, (0, typeorm_1.InjectRepository)(whiteList_entity_1.WhiteListEntity)),
|
||||
__param(7, (0, typeorm_1.InjectRepository)(config_entity_1.ConfigEntity)),
|
||||
__param(6, (0, typeorm_1.InjectRepository)(config_entity_1.ConfigEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Connection,
|
||||
verification_service_1.VerificationService,
|
||||
mailer_service_1.MailerService,
|
||||
|
|
|
@ -13,11 +13,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UserBalanceController = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const adminAuth_guard_1 = require("../../common/auth/adminAuth.guard");
|
||||
const jwtAuth_guard_1 = require("../../common/auth/jwtAuth.guard");
|
||||
const common_1 = require("@nestjs/common");
|
||||
const swagger_1 = require("@nestjs/swagger");
|
||||
const userBalance_service_1 = require("./userBalance.service");
|
||||
const adminAuth_guard_1 = require("../../common/auth/adminAuth.guard");
|
||||
let UserBalanceController = class UserBalanceController {
|
||||
constructor(userBalanceService) {
|
||||
this.userBalanceService = userBalanceService;
|
||||
|
|
28
dist/modules/userBalance/userBalance.module.js
vendored
28
dist/modules/userBalance/userBalance.module.js
vendored
|
@ -8,24 +8,23 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UserBalanceModule = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const userBalance_service_1 = require("./userBalance.service");
|
||||
const typeorm_1 = require("@nestjs/typeorm");
|
||||
const balance_entity_1 = require("./balance.entity");
|
||||
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
const cramiPackage_entity_1 = require("../crami/cramiPackage.entity");
|
||||
const config_entity_1 = require("../globalConfig/config.entity");
|
||||
const midjourney_entity_1 = require("../midjourney/midjourney.entity");
|
||||
const redisCache_service_1 = require("../redisCache/redisCache.service");
|
||||
const salesUsers_entity_1 = require("../sales/salesUsers.entity");
|
||||
const user_entity_1 = require("../user/user.entity");
|
||||
const verification_service_1 = require("../verification/verification.service");
|
||||
const verifycation_entity_1 = require("../verification/verifycation.entity");
|
||||
const accountLog_entity_1 = require("./accountLog.entity");
|
||||
const userBalance_controller_1 = require("./userBalance.controller");
|
||||
const config_entity_1 = require("../globalConfig/config.entity");
|
||||
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("../chat/whiteList.entity");
|
||||
const redisCache_service_1 = require("../redisCache/redisCache.service");
|
||||
const balance_entity_1 = require("./balance.entity");
|
||||
const fingerprint_entity_1 = require("./fingerprint.entity");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
|
||||
const midjourney_entity_1 = require("../midjourney/midjourney.entity");
|
||||
const userBalance_controller_1 = require("./userBalance.controller");
|
||||
const userBalance_entity_1 = require("./userBalance.entity");
|
||||
const userBalance_service_1 = require("./userBalance.service");
|
||||
let UserBalanceModule = class UserBalanceModule {
|
||||
};
|
||||
UserBalanceModule = __decorate([
|
||||
|
@ -41,11 +40,10 @@ UserBalanceModule = __decorate([
|
|||
cramiPackage_entity_1.CramiPackageEntity,
|
||||
user_entity_1.UserEntity,
|
||||
salesUsers_entity_1.SalesUsersEntity,
|
||||
whiteList_entity_1.WhiteListEntity,
|
||||
fingerprint_entity_1.FingerprintLogEntity,
|
||||
chatLog_entity_1.ChatLogEntity,
|
||||
chatGroup_entity_1.ChatGroupEntity,
|
||||
midjourney_entity_1.MidjourneyEntity
|
||||
midjourney_entity_1.MidjourneyEntity,
|
||||
]),
|
||||
],
|
||||
controllers: [userBalance_controller_1.UserBalanceController],
|
||||
|
|
293
dist/modules/userBalance/userBalance.service.js
vendored
293
dist/modules/userBalance/userBalance.service.js
vendored
|
@ -25,7 +25,6 @@ const accountLog_entity_1 = require("./accountLog.entity");
|
|||
const balance_entity_1 = require("./balance.entity");
|
||||
const userBalance_entity_1 = require("./userBalance.entity");
|
||||
const date_1 = require("../../common/utils/date");
|
||||
const whiteList_entity_1 = require("../chat/whiteList.entity");
|
||||
const chatGroup_entity_1 = require("../chatGroup/chatGroup.entity");
|
||||
const chatLog_entity_1 = require("../chatLog/chatLog.entity");
|
||||
const midjourney_entity_1 = require("../midjourney/midjourney.entity");
|
||||
|
@ -34,7 +33,7 @@ const salesUsers_entity_1 = require("../sales/salesUsers.entity");
|
|||
const user_entity_1 = require("../user/user.entity");
|
||||
const fingerprint_entity_1 = require("./fingerprint.entity");
|
||||
let UserBalanceService = class UserBalanceService {
|
||||
constructor(balanceEntity, userBalanceEntity, accountLogEntity, cramiPackageEntity, configEntity, userEntity, salesUsersEntity, whiteListEntity, fingerprintLogEntity, chatGroupEntity, chatLogEntity, midjourneyEntity, salesService, globalConfigService) {
|
||||
constructor(balanceEntity, userBalanceEntity, accountLogEntity, cramiPackageEntity, configEntity, userEntity, salesUsersEntity, fingerprintLogEntity, chatGroupEntity, chatLogEntity, midjourneyEntity, salesService, globalConfigService) {
|
||||
this.balanceEntity = balanceEntity;
|
||||
this.userBalanceEntity = userBalanceEntity;
|
||||
this.accountLogEntity = accountLogEntity;
|
||||
|
@ -42,7 +41,6 @@ let UserBalanceService = class UserBalanceService {
|
|||
this.configEntity = configEntity;
|
||||
this.userEntity = userEntity;
|
||||
this.salesUsersEntity = salesUsersEntity;
|
||||
this.whiteListEntity = whiteListEntity;
|
||||
this.fingerprintLogEntity = fingerprintLogEntity;
|
||||
this.chatGroupEntity = chatGroupEntity;
|
||||
this.chatLogEntity = chatLogEntity;
|
||||
|
@ -88,17 +86,28 @@ let UserBalanceService = class UserBalanceService {
|
|||
model4Count = model4Count + configMap.registerSendModel4Count;
|
||||
drawMjCount = drawMjCount + configMap.registerSendDrawMjCount;
|
||||
}
|
||||
if (configMap.registerSendStatus === 1 && configMap.firstRegisterSendStatus === 1 && userId <= configMap.firstRegisterSendRank) {
|
||||
if (configMap.registerSendStatus === 1 &&
|
||||
configMap.firstRegisterSendStatus === 1 &&
|
||||
userId <= configMap.firstRegisterSendRank) {
|
||||
model3Count = model3Count + configMap.firstRregisterSendModel3Count;
|
||||
model4Count = model4Count + configMap.firstRregisterSendModel4Count;
|
||||
drawMjCount = drawMjCount + configMap.firstRregisterSendDrawMjCount;
|
||||
}
|
||||
await this.saveRecordRechargeLog({ userId, rechargeType: balance_constant_1.RechargeType.REG_GIFT, model3Count, drawMjCount, model4Count });
|
||||
await this.saveRecordRechargeLog({
|
||||
userId,
|
||||
rechargeType: balance_constant_1.RechargeType.REG_GIFT,
|
||||
model3Count,
|
||||
drawMjCount,
|
||||
model4Count,
|
||||
});
|
||||
if (invitedId) {
|
||||
if (Number(configMap.inviteSendStatus) === 1) {
|
||||
model3Count = model3Count + Number(configMap.invitedGuestSendModel3Count);
|
||||
model4Count = model4Count + Number(configMap.invitedGuestSendModel4Count);
|
||||
drawMjCount = drawMjCount + Number(configMap.invitedGuestSendDrawMjCount);
|
||||
model3Count =
|
||||
model3Count + Number(configMap.invitedGuestSendModel3Count);
|
||||
model4Count =
|
||||
model4Count + Number(configMap.invitedGuestSendModel4Count);
|
||||
drawMjCount =
|
||||
drawMjCount + Number(configMap.invitedGuestSendDrawMjCount);
|
||||
await this.saveRecordRechargeLog({
|
||||
userId,
|
||||
rechargeType: balance_constant_1.RechargeType.INVITE_GIFT,
|
||||
|
@ -120,7 +129,13 @@ let UserBalanceService = class UserBalanceService {
|
|||
});
|
||||
}
|
||||
}
|
||||
await this.userBalanceEntity.save({ userId, model3Count, model4Count, drawMjCount, useTokens: 0 });
|
||||
await this.userBalanceEntity.save({
|
||||
userId,
|
||||
model3Count,
|
||||
model4Count,
|
||||
drawMjCount,
|
||||
useTokens: 0,
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.log('error: ', error);
|
||||
|
@ -136,11 +151,25 @@ let UserBalanceService = class UserBalanceService {
|
|||
if (role === 'visitor') {
|
||||
return this.validateVisitorBalance(req, type, amount);
|
||||
}
|
||||
const res = await this.configEntity.findOne({ where: { configKey: 'vxNumber' } });
|
||||
const res = await this.configEntity.findOne({
|
||||
where: { configKey: 'vxNumber' },
|
||||
});
|
||||
const vxNumber = res ? res.configVal : '---';
|
||||
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) {
|
||||
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] + b[baseKey] < amount) {
|
||||
if (b[baseKey] < amount) {
|
||||
throw new common_1.HttpException(`您的账户余额不足,如果想继续体验服务,请联系管理员或购买专属套餐 !`, common_1.HttpStatus.PAYMENT_REQUIRED);
|
||||
}
|
||||
|
@ -152,21 +181,33 @@ let UserBalanceService = class UserBalanceService {
|
|||
}
|
||||
async validateVisitorBalance(req, type, amount) {
|
||||
const { id } = req.user;
|
||||
const baseKey = type === 1 ? 'model3Count' : type === 2 ? 'model4Count' : type === 3 ? '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']);
|
||||
const log = await this.fingerprintLogEntity.findOne({
|
||||
where: { fingerprint: id },
|
||||
});
|
||||
const { visitorModel3Num, visitorModel4Num, visitorMJNum } = await this.globalConfigService.getConfigs([
|
||||
'visitorModel3Num',
|
||||
'visitorModel4Num',
|
||||
'visitorMJNum',
|
||||
]);
|
||||
const settings = {
|
||||
model3Count: visitorModel3Num ? Number(visitorModel3Num) : 0,
|
||||
model4Count: visitorModel4Num ? Number(visitorModel4Num) : 0,
|
||||
drawMjCount: visitorMJNum ? Number(visitorMJNum) : 0
|
||||
drawMjCount: visitorMJNum ? Number(visitorMJNum) : 0,
|
||||
};
|
||||
if (!log) {
|
||||
let data = {
|
||||
fingerprint: id,
|
||||
model3Count: 0,
|
||||
model4Count: 0,
|
||||
drawMjCount: 0
|
||||
drawMjCount: 0,
|
||||
};
|
||||
data[baseKey] = data[baseKey] + amount;
|
||||
if (data[baseKey] > settings[baseKey]) {
|
||||
|
@ -182,7 +223,7 @@ let UserBalanceService = class UserBalanceService {
|
|||
let data = {
|
||||
model3Count,
|
||||
model4Count,
|
||||
drawMjCount
|
||||
drawMjCount,
|
||||
};
|
||||
const date = Number(new Date(log.updatedAt));
|
||||
const isUpdateLastDay = this.isUpdatedToday(date);
|
||||
|
@ -193,7 +234,7 @@ let UserBalanceService = class UserBalanceService {
|
|||
data = {
|
||||
model3Count: 0,
|
||||
model4Count: 0,
|
||||
drawMjCount: 0
|
||||
drawMjCount: 0,
|
||||
};
|
||||
data[baseKey] = data[baseKey] + amount;
|
||||
}
|
||||
|
@ -216,37 +257,40 @@ let UserBalanceService = class UserBalanceService {
|
|||
if (!b) {
|
||||
throw new common_1.HttpException('缺失当前用户账户记录!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const memberKey = deductionType === 1
|
||||
? 'memberModel3Count'
|
||||
: deductionType === 2
|
||||
? 'memberModel4Count'
|
||||
: deductionType === 3
|
||||
? 'memberDrawMjCount'
|
||||
: 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')) {
|
||||
useKey = 'useModel3Token';
|
||||
}
|
||||
if (updateKey.includes('odel4')) {
|
||||
useKey = 'useModel4Token';
|
||||
}
|
||||
if (updateKey.includes('MjCount')) {
|
||||
useKey = 'useDrawMjToken';
|
||||
const keys = {
|
||||
1: {
|
||||
member: 'memberModel3Count',
|
||||
nonMember: 'model3Count',
|
||||
token: 'useModel3Token',
|
||||
},
|
||||
2: {
|
||||
member: 'memberModel4Count',
|
||||
nonMember: 'model4Count',
|
||||
token: 'useModel4Token',
|
||||
},
|
||||
3: {
|
||||
member: 'memberDrawMjCount',
|
||||
nonMember: 'drawMjCount',
|
||||
token: 'useDrawMjToken',
|
||||
},
|
||||
};
|
||||
const { member, nonMember, token } = keys[deductionType];
|
||||
let remainingAmount = amount;
|
||||
let newMemberBalance = Math.max(b[member] - remainingAmount, 0);
|
||||
remainingAmount -= b[member] - newMemberBalance;
|
||||
let newNonMemberBalance = b[nonMember];
|
||||
if (remainingAmount > 0) {
|
||||
newNonMemberBalance = Math.max(b[nonMember] - remainingAmount, 0);
|
||||
remainingAmount -= b[nonMember] - newNonMemberBalance;
|
||||
}
|
||||
const updateBalance = {
|
||||
[updateKey]: b[updateKey] - amount < 0 ? 0 : b[updateKey] - amount,
|
||||
[useKey]: b[useKey] + UseAmount,
|
||||
[member]: newMemberBalance,
|
||||
[nonMember]: newNonMemberBalance,
|
||||
[token]: (b[token] || 0) + UseAmount,
|
||||
};
|
||||
if (useKey === 'useModel3Token') {
|
||||
updateBalance['useModel3Count'] = b['useModel3Count'] + amount;
|
||||
}
|
||||
if (useKey === 'useModel4Token') {
|
||||
updateBalance['useModel4Count'] = b['useModel4Count'] + amount;
|
||||
}
|
||||
if (useKey === 'useDrawMjToken') {
|
||||
updateBalance['useDrawMjToken'] = b['useDrawMjToken'] + amount;
|
||||
if (token === 'useModel3Token' || token === 'useModel4Token') {
|
||||
updateBalance[token.replace('Token', 'Count')] =
|
||||
(b[token.replace('Token', 'Count')] || 0) + amount;
|
||||
}
|
||||
const result = await this.userBalanceEntity.update({ userId }, updateBalance);
|
||||
if (result.affected === 0) {
|
||||
|
@ -282,10 +326,18 @@ let UserBalanceService = class UserBalanceService {
|
|||
throw new common_1.HttpException('查询当前用户余额失败!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
res.sumModel3Count = res.packageId ? res.model3Count + res.memberModel3Count : res.model3Count;
|
||||
res.sumModel4Count = res.packageId ? res.model4Count + res.memberModel4Count : res.model4Count;
|
||||
res.sumDrawMjCount = res.packageId ? res.drawMjCount + res.memberDrawMjCount : res.drawMjCount;
|
||||
res.expirationTime = res.expirationTime ? (0, date_1.formatDate)(res.expirationTime, 'YYYY-MM-DD') : null;
|
||||
res.sumModel3Count = res.packageId
|
||||
? res.model3Count + res.memberModel3Count
|
||||
: res.model3Count;
|
||||
res.sumModel4Count = res.packageId
|
||||
? res.model4Count + res.memberModel4Count
|
||||
: res.model4Count;
|
||||
res.sumDrawMjCount = res.packageId
|
||||
? res.drawMjCount + res.memberDrawMjCount
|
||||
: res.drawMjCount;
|
||||
res.expirationTime = res.expirationTime
|
||||
? (0, date_1.formatDate)(res.expirationTime, 'YYYY-MM-DD')
|
||||
: null;
|
||||
return res;
|
||||
}
|
||||
catch (error) {
|
||||
|
@ -293,35 +345,53 @@ let UserBalanceService = class UserBalanceService {
|
|||
}
|
||||
}
|
||||
async saveRecordRechargeLog(logInfo) {
|
||||
const { userId, rechargeType, model3Count, model4Count, drawMjCount, days = -1, pkgName = '', extent = '' } = logInfo;
|
||||
const { userId, rechargeType, model3Count, model4Count, drawMjCount, days = -1, pkgName = '', extent = '', } = logInfo;
|
||||
if (!userId) {
|
||||
throw new common_1.HttpException('当前用户不存在,记录充值日志异常', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const uid = (0, utils_1.createRandomUid)();
|
||||
return await this.accountLogEntity.save({ userId, rechargeType, model3Count, model4Count, drawMjCount, days, extent, uid, pkgName });
|
||||
return await this.accountLogEntity.save({
|
||||
userId,
|
||||
rechargeType,
|
||||
model3Count,
|
||||
model4Count,
|
||||
drawMjCount,
|
||||
days,
|
||||
extent,
|
||||
uid,
|
||||
pkgName,
|
||||
});
|
||||
}
|
||||
async createBaseUserBalance(userId, userBalanceInfo = {}) {
|
||||
const { model3Count = 0, model4Count = 0, drawMjCount = 0 } = userBalanceInfo;
|
||||
const { model3Count = 0, model4Count = 0, drawMjCount = 0, } = userBalanceInfo;
|
||||
const balance = await this.userBalanceEntity.findOne({ where: { userId } });
|
||||
if (balance) {
|
||||
throw new common_1.HttpException('当前用户无需创建账户信息!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
return await this.userBalanceEntity.save({ userId, model3Count, model4Count, drawMjCount });
|
||||
return await this.userBalanceEntity.save({
|
||||
userId,
|
||||
model3Count,
|
||||
model4Count,
|
||||
drawMjCount,
|
||||
});
|
||||
}
|
||||
async addBalanceToUser(userId, balance, days = -1) {
|
||||
try {
|
||||
const userBalanceInfo = (await this.userBalanceEntity.findOne({ where: { userId } })) || (await this.createBaseUserBalance(userId));
|
||||
const userBalanceInfo = (await this.userBalanceEntity.findOne({ where: { userId } })) ||
|
||||
(await this.createBaseUserBalance(userId));
|
||||
if (!userBalanceInfo) {
|
||||
throw new common_1.HttpException('查询用户账户信息失败!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const { model3Count, model4Count, drawMjCount, memberModel3Count, memberModel4Count, memberDrawMjCount } = userBalanceInfo;
|
||||
const { model3Count, model4Count, drawMjCount, memberModel3Count, memberModel4Count, memberDrawMjCount, } = userBalanceInfo;
|
||||
let params = {};
|
||||
if (days > 0) {
|
||||
const { packageId } = balance;
|
||||
if (!packageId) {
|
||||
throw new common_1.HttpException('缺失当前套餐ID、充值失败!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const pkgInfo = await this.cramiPackageEntity.findOne({ where: { id: packageId } });
|
||||
const pkgInfo = await this.cramiPackageEntity.findOne({
|
||||
where: { id: packageId },
|
||||
});
|
||||
if (!pkgInfo) {
|
||||
throw new common_1.HttpException('当前套餐不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
@ -338,7 +408,9 @@ let UserBalanceService = class UserBalanceService {
|
|||
};
|
||||
}
|
||||
else {
|
||||
const curPackageInfo = await this.cramiPackageEntity.findOne({ where: { id: userBalanceInfo.packageId } });
|
||||
const curPackageInfo = await this.cramiPackageEntity.findOne({
|
||||
where: { id: userBalanceInfo.packageId },
|
||||
});
|
||||
if (weight >= curPackageInfo.weight) {
|
||||
params = {
|
||||
memberModel3Count: memberModel3Count + balance.model3Count,
|
||||
|
@ -380,11 +452,13 @@ let UserBalanceService = class UserBalanceService {
|
|||
console.log('充值的工单信息:', order);
|
||||
try {
|
||||
const { userId, goodsId } = order;
|
||||
const pkg = await this.cramiPackageEntity.findOne({ where: { id: order.goodsId, status: 1 } });
|
||||
const pkg = await this.cramiPackageEntity.findOne({
|
||||
where: { id: order.goodsId, status: 1 },
|
||||
});
|
||||
if (!pkg) {
|
||||
throw new common_1.HttpException('非法操作、当前充值套餐暂不存在!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
const { model3Count, model4Count, drawMjCount, days, name: pkgName } = pkg;
|
||||
const { model3Count, model4Count, drawMjCount, days, name: pkgName, } = pkg;
|
||||
const money = {
|
||||
model3Count,
|
||||
model4Count,
|
||||
|
@ -393,12 +467,24 @@ let UserBalanceService = class UserBalanceService {
|
|||
packageId: order.goodsId,
|
||||
};
|
||||
await this.addBalanceToUser(userId, money, days);
|
||||
await this.saveRecordRechargeLog({ userId, rechargeType: balance_constant_1.RechargeType.SCAN_PAY, model3Count, model4Count, drawMjCount, pkgName, days });
|
||||
await this.saveRecordRechargeLog({
|
||||
userId,
|
||||
rechargeType: balance_constant_1.RechargeType.SCAN_PAY,
|
||||
model3Count,
|
||||
model4Count,
|
||||
drawMjCount,
|
||||
pkgName,
|
||||
days,
|
||||
});
|
||||
const userInfo = await this.userEntity.findOne({ where: { id: userId } });
|
||||
const { invitedBy } = userInfo;
|
||||
if (invitedBy) {
|
||||
const inviteUserInfo = await this.userEntity.findOne({ where: { inviteCode: invitedBy } });
|
||||
const inviteUserSalesInfo = await this.salesUsersEntity.findOne({ where: { userId: inviteUserInfo.id } });
|
||||
const inviteUserInfo = await this.userEntity.findOne({
|
||||
where: { inviteCode: invitedBy },
|
||||
});
|
||||
const inviteUserSalesInfo = await this.salesUsersEntity.findOne({
|
||||
where: { userId: inviteUserInfo.id },
|
||||
});
|
||||
if (!inviteUserInfo)
|
||||
return;
|
||||
const { id: inviterUserId } = inviteUserInfo;
|
||||
|
@ -449,7 +535,9 @@ let UserBalanceService = class UserBalanceService {
|
|||
take: size,
|
||||
});
|
||||
const userIds = rows.map((item) => item.userId);
|
||||
const userInfo = await this.userEntity.find({ where: { id: (0, typeorm_2.In)(userIds) } });
|
||||
const userInfo = await this.userEntity.find({
|
||||
where: { id: (0, typeorm_2.In)(userIds) },
|
||||
});
|
||||
rows.forEach((item) => {
|
||||
const user = userInfo.find((user) => user.id === item.userId);
|
||||
item.username = user === null || user === void 0 ? void 0 : user.username;
|
||||
|
@ -477,57 +565,6 @@ let UserBalanceService = class UserBalanceService {
|
|||
async refundMjBalance(userId, amount) {
|
||||
return await this.deductFromBalance(userId, 'mjDraw', -amount);
|
||||
}
|
||||
async upgradeBalance() {
|
||||
const users = await this.userEntity.find();
|
||||
if (!users.length)
|
||||
return;
|
||||
const upgradeStatus = await this.globalConfigService.getConfigs(['upgradeStatus']);
|
||||
if (!upgradeStatus) {
|
||||
await this.globalConfigService.setConfig({ settings: [{ configKey: 'upgradeStatus', configVal: '1' }] });
|
||||
}
|
||||
else {
|
||||
throw new common_1.HttpException('您已经升级过了、请勿重复操作!', common_1.HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
users.forEach((user) => {
|
||||
const { id } = user;
|
||||
this.balanceEntity.findOne({ where: { userId: id } }).then((res) => {
|
||||
if (!res)
|
||||
return;
|
||||
this.writeOldBalanceToNewTable(id, res);
|
||||
});
|
||||
});
|
||||
}
|
||||
async writeOldBalanceToNewTable(userId, balanceInfo) {
|
||||
const { balance = 0, usesLeft = 0, paintCount = 0, useTokens = 0, useChats = 0, usePaints = 0 } = balanceInfo;
|
||||
const model4Info = await this.whiteListEntity.findOne({ where: { userId } });
|
||||
const newBalanceInfo = {
|
||||
userId,
|
||||
model3Count: Number(usesLeft),
|
||||
model4Count: (model4Info === null || model4Info === void 0 ? void 0 : model4Info.count) || 0,
|
||||
drawMjCount: Number(balance),
|
||||
useModel3Count: Number(useChats),
|
||||
useModel4Count: (model4Info === null || model4Info === void 0 ? void 0 : model4Info.useCount) || 0,
|
||||
useDrawMjCount: Number(usePaints),
|
||||
useModel3Token: Number(useTokens),
|
||||
useModel4Token: 0,
|
||||
useDrawMjToken: 0,
|
||||
};
|
||||
const userBalanceInfo = await this.userBalanceEntity.findOne({ where: { userId } });
|
||||
if (userBalanceInfo) {
|
||||
common_1.Logger.debug(`用户${userId}账户信息已经存在、迁移无效`, 'BalanceService');
|
||||
}
|
||||
else {
|
||||
this.userBalanceEntity
|
||||
.save(newBalanceInfo)
|
||||
.then((res) => {
|
||||
common_1.Logger.debug(`用户${userId}旧账户信息迁移成功`, 'BalanceService');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('error: ', error);
|
||||
common_1.Logger.debug(`用户${userId}旧账户信息迁移失败`, 'BalanceService');
|
||||
});
|
||||
}
|
||||
}
|
||||
async inheritVisitorData(req) {
|
||||
const { fingerprint } = req.headers;
|
||||
const { id: userId } = req.user;
|
||||
|
@ -538,9 +575,15 @@ let UserBalanceService = class UserBalanceService {
|
|||
}
|
||||
async getVisitorCount(req) {
|
||||
const { fingerprint } = req.headers;
|
||||
const countChat = await this.chatLogEntity.count({ where: { userId: fingerprint } });
|
||||
const countChatGroup = await this.chatGroupEntity.count({ where: { userId: fingerprint } });
|
||||
const countMj = await this.midjourneyEntity.count({ where: { userId: fingerprint } });
|
||||
const countChat = await this.chatLogEntity.count({
|
||||
where: { userId: fingerprint },
|
||||
});
|
||||
const countChatGroup = await this.chatGroupEntity.count({
|
||||
where: { userId: fingerprint },
|
||||
});
|
||||
const countMj = await this.midjourneyEntity.count({
|
||||
where: { userId: fingerprint },
|
||||
});
|
||||
return countChat || countChatGroup || countMj || 0;
|
||||
}
|
||||
};
|
||||
|
@ -553,11 +596,10 @@ UserBalanceService = __decorate([
|
|||
__param(4, (0, typeorm_1.InjectRepository)(config_entity_1.ConfigEntity)),
|
||||
__param(5, (0, typeorm_1.InjectRepository)(user_entity_1.UserEntity)),
|
||||
__param(6, (0, typeorm_1.InjectRepository)(salesUsers_entity_1.SalesUsersEntity)),
|
||||
__param(7, (0, typeorm_1.InjectRepository)(whiteList_entity_1.WhiteListEntity)),
|
||||
__param(8, (0, typeorm_1.InjectRepository)(fingerprint_entity_1.FingerprintLogEntity)),
|
||||
__param(9, (0, typeorm_1.InjectRepository)(chatGroup_entity_1.ChatGroupEntity)),
|
||||
__param(10, (0, typeorm_1.InjectRepository)(chatLog_entity_1.ChatLogEntity)),
|
||||
__param(11, (0, typeorm_1.InjectRepository)(midjourney_entity_1.MidjourneyEntity)),
|
||||
__param(7, (0, typeorm_1.InjectRepository)(fingerprint_entity_1.FingerprintLogEntity)),
|
||||
__param(8, (0, typeorm_1.InjectRepository)(chatGroup_entity_1.ChatGroupEntity)),
|
||||
__param(9, (0, typeorm_1.InjectRepository)(chatLog_entity_1.ChatLogEntity)),
|
||||
__param(10, (0, typeorm_1.InjectRepository)(midjourney_entity_1.MidjourneyEntity)),
|
||||
__metadata("design:paramtypes", [typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
|
@ -569,7 +611,6 @@ UserBalanceService = __decorate([
|
|||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
typeorm_2.Repository,
|
||||
sales_service_1.SalesService,
|
||||
globalConfig_service_1.GlobalConfigService])
|
||||
], UserBalanceService);
|
||||
|
|
106
package.json
106
package.json
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"name": "99AI",
|
||||
"version": "3.3.0",
|
||||
"name": "99ai",
|
||||
"version": "3.5.0",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"author": "vastxie",
|
||||
"private": true,
|
||||
"license": "UNLICENSED",
|
||||
"license": "Apache-2.0",
|
||||
"bin": "./dist/main.js",
|
||||
"scripts": {
|
||||
"start": "pm2 start pm2.conf.json",
|
||||
|
@ -27,87 +27,89 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@alicloud/pop-core": "^1.7.13",
|
||||
"@dqbd/tiktoken": "^1.0.7",
|
||||
"@keyv/redis": "^2.6.1",
|
||||
"@dqbd/tiktoken": "^1.0.15",
|
||||
"@keyv/redis": "^2.8.5",
|
||||
"@nestjs/bull": "^0.6.3",
|
||||
"@nestjs/common": "^9.0.0",
|
||||
"@nestjs/core": "^9.0.0",
|
||||
"@nestjs/jwt": "^10.0.3",
|
||||
"@nestjs/common": "^9.4.3",
|
||||
"@nestjs/config": "^3.2.2",
|
||||
"@nestjs/core": "^9.4.3",
|
||||
"@nestjs/jwt": "^10.2.0",
|
||||
"@nestjs/passport": "^9.0.3",
|
||||
"@nestjs/platform-express": "^9.4.0",
|
||||
"@nestjs/schedule": "^2.2.2",
|
||||
"@nestjs/serve-static": "^4.0.0",
|
||||
"@nestjs/swagger": "^6.2.1",
|
||||
"@nestjs/platform-express": "^9.4.3",
|
||||
"@nestjs/platform-socket.io": "^10.3.9",
|
||||
"@nestjs/schedule": "^2.2.3",
|
||||
"@nestjs/serve-static": "^4.0.2",
|
||||
"@nestjs/swagger": "^6.3.0",
|
||||
"@nestjs/typeorm": "^9.0.1",
|
||||
"@types/cache-manager-redis-store": "^2.0.1",
|
||||
"@nestjs/websockets": "^10.3.9",
|
||||
"@types/cache-manager-redis-store": "^2.0.4",
|
||||
"abort-controller": "^3.0.0",
|
||||
"ali-oss": "^6.17.1",
|
||||
"ali-oss": "^6.20.0",
|
||||
"app-root-path": "^3.1.0",
|
||||
"axios": "^1.4.0",
|
||||
"axios": "^1.7.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"body-parser": "^1.20.2",
|
||||
"bull": "^4.10.4",
|
||||
"bull": "^4.14.0",
|
||||
"cache-manager-redis-store": "^3.0.1",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"class-validator": "^0.14.1",
|
||||
"compression": "^1.7.4",
|
||||
"cos-nodejs-sdk-v5": "^2.11.19",
|
||||
"css-inline": "^0.11.2",
|
||||
"dayjs": "^1.11.7",
|
||||
"cos-nodejs-sdk-v5": "^2.14.2",
|
||||
"dayjs": "^1.11.11",
|
||||
"decimal.js": "^10.4.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"dotenv": "^16.4.5",
|
||||
"eventsource": "^2.0.2",
|
||||
"exceljs": "^4.3.0",
|
||||
"express": "^4.18.2",
|
||||
"exceljs": "^4.4.0",
|
||||
"express": "^4.19.2",
|
||||
"express-xml-bodyparser": "^0.3.0",
|
||||
"form-data": "^4.0.0",
|
||||
"guid-typescript": "^1.0.9",
|
||||
"handlebars": "^4.7.8",
|
||||
"hbs": "^4.2.0",
|
||||
"image-size": "^1.1.1",
|
||||
"ioredis": "^5.3.2",
|
||||
"ioredis": "^5.4.1",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"javascript-obfuscator": "^4.0.2",
|
||||
"jimp": "^0.22.7",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"keyv": "^4.5.2",
|
||||
"javascript-obfuscator": "^4.1.1",
|
||||
"jimp": "^0.22.12",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"keyv": "^4.5.4",
|
||||
"lodash": "^4.17.21",
|
||||
"microsoft-cognitiveservices-speech-sdk": "^1.36.0",
|
||||
"mysql2": "^3.2.0",
|
||||
"nestjs-config": "^1.4.10",
|
||||
"microsoft-cognitiveservices-speech-sdk": "^1.38.0",
|
||||
"mysql2": "^3.10.1",
|
||||
"nestjs-config": "^1.4.11",
|
||||
"nestjs-rate-limiter": "^3.1.0",
|
||||
"nestjs-redis": "^1.3.3",
|
||||
"node-fetch": "^3.3.1",
|
||||
"nodemailer": "^6.9.12",
|
||||
"node-fetch": "^3.3.2",
|
||||
"nodemailer": "^6.9.14",
|
||||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"redis": "^4.6.5",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.2.0",
|
||||
"redis": "^4.6.14",
|
||||
"reflect-metadata": "^0.1.14",
|
||||
"rxjs": "^7.8.1",
|
||||
"stream-to-buffer": "^0.1.0",
|
||||
"svg-captcha": "^1.4.0",
|
||||
"swagger-ui-express": "^4.6.2",
|
||||
"typeorm": "^0.3.12",
|
||||
"uuid": "^9.0.0",
|
||||
"wechatpay-node-v3": "^2.1.5"
|
||||
"swagger-ui-express": "^4.6.3",
|
||||
"typeorm": "^0.3.20",
|
||||
"uuid": "^9.0.1",
|
||||
"wechatpay-node-v3": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^9.0.0",
|
||||
"@nestjs/schematics": "^9.0.0",
|
||||
"@nestjs/testing": "^9.0.0",
|
||||
"@types/express": "^4.17.13",
|
||||
"@nestjs/cli": "^9.5.0",
|
||||
"@nestjs/schematics": "^9.2.0",
|
||||
"@nestjs/testing": "^9.4.3",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jest": "29.2.4",
|
||||
"@types/node": "18.11.18",
|
||||
"@types/supertest": "^2.0.11",
|
||||
"@types/supertest": "^2.0.16",
|
||||
"jest": "29.3.1",
|
||||
"prettier": "^2.3.2",
|
||||
"source-map-support": "^0.5.20",
|
||||
"supertest": "^6.1.3",
|
||||
"prettier": "^2.8.8",
|
||||
"source-map-support": "^0.5.21",
|
||||
"supertest": "^6.3.4",
|
||||
"ts-jest": "29.0.3",
|
||||
"ts-loader": "^9.2.3",
|
||||
"ts-node": "^10.0.0",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsconfig-paths": "4.1.1",
|
||||
"typescript": "^4.7.4"
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
|
8
public/admin/assets/HButton-aVY9RE9r.js
Normal file
8
public/admin/assets/HButton-aVY9RE9r.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
/**
|
||||
* 由 Fantastic-admin 提供技术支持
|
||||
* Powered by Fantastic-admin
|
||||
* https://fantastic-admin.github.io
|
||||
*/
|
||||
|
||||
import{_ as f}from"./index-B-LUCRde.js";export{f as default};
|
BIN
public/admin/assets/HButton-aVY9RE9r.js.br
Normal file
BIN
public/admin/assets/HButton-aVY9RE9r.js.br
Normal file
Binary file not shown.
8
public/admin/assets/HCheckList-BDt5IzdQ.js
Normal file
8
public/admin/assets/HCheckList-BDt5IzdQ.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
/**
|
||||
* 由 Fantastic-admin 提供技术支持
|
||||
* Powered by Fantastic-admin
|
||||
* https://fantastic-admin.github.io
|
||||
*/
|
||||
|
||||
import{_ as m}from"./HCheckList.vue_vue_type_script_setup_true_lang-DNeoHT7d.js";import"./index-B-LUCRde.js";export{m as default};
|
BIN
public/admin/assets/HCheckList-BDt5IzdQ.js.br
Normal file
BIN
public/admin/assets/HCheckList-BDt5IzdQ.js.br
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user