mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 01:06:39 +08:00
refactor: 重构项目目录结构
This commit is contained in:
parent
a897a755b6
commit
4dcae75488
6
.gitignore
vendored
6
.gitignore
vendored
@ -8,7 +8,7 @@ pnpm-debug.log*
|
|||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
|
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
src/dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
tmp
|
src/tmp
|
||||||
bin
|
bin
|
||||||
web/.env.development
|
web/.env.development
|
||||||
data
|
src/data
|
||||||
|
37
README.md
37
README.md
@ -9,21 +9,42 @@
|
|||||||
|
|
||||||
**本项目基于 MIT 协议,免费开放全部源代码,可以作为个人学习使用或者商用。如需商用建议联系作者登记,仅做统计使用,优秀项目我们将在项目首页为您展示。**
|
**本项目基于 MIT 协议,免费开放全部源代码,可以作为个人学习使用或者商用。如需商用建议联系作者登记,仅做统计使用,优秀项目我们将在项目首页为您展示。**
|
||||||
|
|
||||||
## 项目功能介绍
|
## 项目介绍
|
||||||
|
这一套完整的系统,包括两套前端聊天应用和一个后台管理系统。系统有用户鉴权,你可以自己使用,也可以部署直接给 C 端用户提供 ChatGPT 的服务。
|
||||||
|
|
||||||
|
项目的技术架构是
|
||||||
|
|
||||||
|
> Go + Vue3 + element-plus
|
||||||
|
|
||||||
|
后端采用的是 Go 语言开发的 Gin Web 框架。前端用的是 Vue3 + element-plus UI 框架
|
||||||
|
|
||||||
|
目前已经实现了以下功能:
|
||||||
|
1. 通用版的 ChatGPT 聊天界面和功能,聊天记录保存在客户端。
|
||||||
|
2. 口令机制:输入口令才可以访问,支持设置口令的对话次数,有效期。
|
||||||
|
3. 角色版的聊天界面和功能,角色设定,预设一些角色,比如程序员,客服,作家,老师,艺术家...
|
||||||
|
4. 保存聊天记录,支持聊天上下文。
|
||||||
|
5. OpenAI API 负载均衡,限制每个 API Key 每分钟之内调用次数不超过 15次,防止被封。
|
||||||
|
6. 支持配置多个代理,保证高可用。
|
||||||
|
7. 实现 markdown 语法解析和代码高亮,支持复制回复内容功能。
|
||||||
|
8. 后台管理功能,实现系统的动态配置,用户和角色的动态管理。
|
||||||
|
|
||||||
|
## 功能截图
|
||||||
|
|
||||||
|
### 1.
|
||||||
|
|
||||||
|
|
||||||
## TODOLIST
|
## TODOLIST
|
||||||
* [x] 使用 level DB 保存用户,角色和聊天记录数据
|
|
||||||
* [x] 引入用户角色,添加用户聊天鉴权,设置口令模式
|
|
||||||
* [x] 定期清理不在线的会话 sessionID 和聊天上下文记录
|
|
||||||
* [x] OpenAI API 负载均衡,限制每个 API Key 每分钟之内调用次数不超过 15次,防止被封
|
|
||||||
* [x] 角色设定,预设一些角色,比如程序员,客服,作家,老师,艺术家...
|
|
||||||
* [x] 实现 markdown 语法解析和代码高亮,支持复制回复内容功能
|
|
||||||
* [ ] 用户配置界面,配置用户的使用习惯,可以让用户配置自己的 API KEY,调用自己的 API Key,将不记 Token 的使用次数
|
* [ ] 用户配置界面,配置用户的使用习惯,可以让用户配置自己的 API KEY,调用自己的 API Key,将不记 Token 的使用次数
|
||||||
* [ ] **新增管理后台功能,实现用户,角色的动态管理**
|
|
||||||
* [ ] 嵌入 AI 绘画功能,支持根据描述词生成图片
|
* [ ] 嵌入 AI 绘画功能,支持根据描述词生成图片
|
||||||
* [ ] 接入自己训练的开源大语言模型
|
* [ ] 接入自己训练的开源大语言模型
|
||||||
* [ ] 接入 Google 语音 API,支持语音聊天
|
* [ ] 接入 Google 语音 API,支持语音聊天
|
||||||
|
|
||||||
|
## 本地部署
|
||||||
|
|
||||||
|
## 线上发布
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
## 参与贡献
|
## 参与贡献
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
Listen = "0.0.0.0:5678"
|
|
||||||
ProxyURL = "http://127.0.0.1:7890"
|
|
||||||
EnableAuth = false
|
|
||||||
Tokens = [""]
|
|
||||||
|
|
||||||
[Session]
|
|
||||||
SecretKey = "azyehq3ivunjhbntz78isj00i4hz2mt9xtddysfucxakadq4qbfrt0b7q3lnvg80"
|
|
||||||
Name = "CHAT_SESSION_ID"
|
|
||||||
Path = "/"
|
|
||||||
Domain = ""
|
|
||||||
MaxAge = 86400
|
|
||||||
Secure = true
|
|
||||||
HttpOnly = false
|
|
||||||
SameSite = 4
|
|
||||||
|
|
||||||
[Chat]
|
|
||||||
ApiURL = "https://api.openai.com/v1/chat/completions"
|
|
||||||
ApiKeys = ["xxx"]
|
|
||||||
Model = "gpt-3.5-turbo"
|
|
||||||
Temperature = 1.0
|
|
||||||
MaxTokens = 1024
|
|
||||||
EnableContext = true
|
|
31
src/config.sample.toml
Normal file
31
src/config.sample.toml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
Title = "Chat-Plus AI 助手"
|
||||||
|
ConsoleTitle = "Chat-Plus 控制台"
|
||||||
|
Listen = "0.0.0.0:5678"
|
||||||
|
ProxyURL = ["YOUR_PORYX_URL"]
|
||||||
|
AccessKey = "YOUR_ACCESS_KEY"
|
||||||
|
|
||||||
|
[Session]
|
||||||
|
SecretKey = "azyehq3ivunjhbntz78isj00i4hz2mt9xtddysfucxakadq4qbfrt0b7q3lnvg80"
|
||||||
|
Name = "CHAT_SESSION_ID"
|
||||||
|
Path = "/"
|
||||||
|
Domain = ""
|
||||||
|
MaxAge = 86400
|
||||||
|
Secure = false
|
||||||
|
HttpOnly = false
|
||||||
|
SameSite = 2
|
||||||
|
|
||||||
|
[ImgURL]
|
||||||
|
WechatCard = "https://img.r9it.com/chatgpt/WX20230505-162403.png"
|
||||||
|
WechatGroup = " https://img.r9it.com/chatgpt/WX20230505-162538.png"
|
||||||
|
|
||||||
|
[Manager]
|
||||||
|
Username = "admin"
|
||||||
|
Password = "admin123"
|
||||||
|
|
||||||
|
[Chat]
|
||||||
|
ApiURL = "https://api.openai.com/v1/chat/completions"
|
||||||
|
Model = "gpt-3.5-turbo"
|
||||||
|
Temperature = 1.0
|
||||||
|
MaxTokens = 1024
|
||||||
|
EnableContext = true
|
||||||
|
ChatContextExpireTime = 3600
|
@ -1,4 +1,4 @@
|
|||||||
module openai
|
module chatplus
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
@ -1,12 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
logger2 "chatplus/logger"
|
||||||
|
"chatplus/server"
|
||||||
"embed"
|
"embed"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
logger2 "openai/logger"
|
|
||||||
"openai/server"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
@ -1,9 +1,9 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"chatplus/types"
|
||||||
|
"chatplus/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"openai/types"
|
|
||||||
"openai/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
@ -1,11 +1,11 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"chatplus/types"
|
||||||
|
"chatplus/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"openai/types"
|
|
||||||
"openai/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddApiKeyHandle 添加一个 API key
|
// AddApiKeyHandle 添加一个 API key
|
||||||
@ -20,7 +20,7 @@ func (s *Server) AddApiKeyHandle(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 过滤已存在的 Key
|
// 过滤已存在的 Key
|
||||||
for _,key:=range s.Config.Chat.ApiKeys {
|
for _, key := range s.Config.Chat.ApiKeys {
|
||||||
if key.Value == data.ApiKey {
|
if key.Value == data.ApiKey {
|
||||||
c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "API KEY 已存在"})
|
c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "API KEY 已存在"})
|
||||||
return
|
return
|
@ -1,11 +1,11 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"chatplus/types"
|
||||||
|
"chatplus/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"openai/types"
|
|
||||||
"openai/utils"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"chatplus/types"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"openai/types"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
@ -1,12 +1,12 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"chatplus/types"
|
||||||
|
"chatplus/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"openai/types"
|
|
||||||
"openai/utils"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -3,6 +3,8 @@ package server
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"chatplus/types"
|
||||||
|
"chatplus/utils"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@ -12,8 +14,6 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"openai/types"
|
|
||||||
"openai/utils"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
@ -1,12 +1,12 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"chatplus/types"
|
||||||
|
"chatplus/utils"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"openai/types"
|
|
||||||
"openai/utils"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
@ -1,6 +1,9 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
logger2 "chatplus/logger"
|
||||||
|
"chatplus/types"
|
||||||
|
"chatplus/utils"
|
||||||
"context"
|
"context"
|
||||||
"embed"
|
"embed"
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
@ -9,9 +12,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
logger2 "openai/logger"
|
|
||||||
"openai/types"
|
|
||||||
"openai/utils"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
@ -2,10 +2,10 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
logger2 "chatplus/logger"
|
||||||
|
"chatplus/types"
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"net/http"
|
"net/http"
|
||||||
logger2 "openai/logger"
|
|
||||||
"openai/types"
|
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="showDialog"
|
v-model="showDialog"
|
||||||
title="编辑用户"
|
title="编辑角色"
|
||||||
width="50%"
|
width="50%"
|
||||||
>
|
>
|
||||||
<el-form :model="form1" label-width="120px" ref="formRef" :rules="rules">
|
<el-form :model="form1" label-width="120px" ref="formRef" :rules="rules">
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
const {defineConfig} = require('@vue/cli-service')
|
const {defineConfig} = require('@vue/cli-service')
|
||||||
let webpack = require('webpack')
|
let webpack = require('webpack')
|
||||||
// const fs = require('fs')
|
|
||||||
// const path = require('path')
|
|
||||||
// const os = require('os')
|
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
transpileDependencies: true,
|
transpileDependencies: true,
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
@ -17,7 +13,7 @@ module.exports = defineConfig({
|
|||||||
},
|
},
|
||||||
|
|
||||||
publicPath: '/chat',
|
publicPath: '/chat',
|
||||||
outputDir: '../dist',
|
outputDir: '../src/dist',
|
||||||
crossorigin: "anonymous",
|
crossorigin: "anonymous",
|
||||||
devServer: {
|
devServer: {
|
||||||
allowedHosts: ['127.0.0.1:5678'],
|
allowedHosts: ['127.0.0.1:5678'],
|
||||||
|
Loading…
Reference in New Issue
Block a user