mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	refactor: 重构项目目录结构
This commit is contained in:
		
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -8,7 +8,7 @@ pnpm-debug.log*
 | 
			
		||||
lerna-debug.log*
 | 
			
		||||
 | 
			
		||||
node_modules
 | 
			
		||||
dist
 | 
			
		||||
src/dist
 | 
			
		||||
dist-ssr
 | 
			
		||||
*.local
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +22,7 @@ dist-ssr
 | 
			
		||||
*.njsproj
 | 
			
		||||
*.sln
 | 
			
		||||
*.sw?
 | 
			
		||||
tmp
 | 
			
		||||
src/tmp
 | 
			
		||||
bin
 | 
			
		||||
web/.env.development 
 | 
			
		||||
data
 | 
			
		||||
src/data
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								README.md
									
									
									
									
									
								
							@@ -9,21 +9,42 @@
 | 
			
		||||
 | 
			
		||||
**本项目基于 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
 | 
			
		||||
* [x] 使用 level DB 保存用户,角色和聊天记录数据
 | 
			
		||||
* [x] 引入用户角色,添加用户聊天鉴权,设置口令模式
 | 
			
		||||
* [x] 定期清理不在线的会话 sessionID 和聊天上下文记录
 | 
			
		||||
* [x] OpenAI API 负载均衡,限制每个 API Key 每分钟之内调用次数不超过 15次,防止被封
 | 
			
		||||
* [x] 角色设定,预设一些角色,比如程序员,客服,作家,老师,艺术家...
 | 
			
		||||
* [x] 实现 markdown 语法解析和代码高亮,支持复制回复内容功能
 | 
			
		||||
* [ ] 用户配置界面,配置用户的使用习惯,可以让用户配置自己的 API KEY,调用自己的 API Key,将不记 Token 的使用次数
 | 
			
		||||
* [ ] **新增管理后台功能,实现用户,角色的动态管理**
 | 
			
		||||
* [ ] 嵌入 AI 绘画功能,支持根据描述词生成图片
 | 
			
		||||
* [ ] 接入自己训练的开源大语言模型
 | 
			
		||||
* [ ] 接入 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
 | 
			
		||||
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	logger2 "chatplus/logger"
 | 
			
		||||
	"chatplus/server"
 | 
			
		||||
	"embed"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/mitchellh/go-homedir"
 | 
			
		||||
	logger2 "openai/logger"
 | 
			
		||||
	"openai/server"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"openai/utils"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"openai/utils"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// AddApiKeyHandle 添加一个 API key
 | 
			
		||||
@@ -20,7 +20,7 @@ func (s *Server) AddApiKeyHandle(c *gin.Context) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// 过滤已存在的 Key
 | 
			
		||||
	for _,key:=range s.Config.Chat.ApiKeys {
 | 
			
		||||
	for _, key := range s.Config.Chat.ApiKeys {
 | 
			
		||||
		if key.Value == data.ApiKey {
 | 
			
		||||
			c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "API KEY 已存在"})
 | 
			
		||||
			return
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"openai/utils"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
)
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"openai/utils"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -3,6 +3,8 @@ package server
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
@@ -12,8 +14,6 @@ import (
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"openai/utils"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/gin-contrib/sessions"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"openai/utils"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	logger2 "chatplus/logger"
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"chatplus/utils"
 | 
			
		||||
	"context"
 | 
			
		||||
	"embed"
 | 
			
		||||
	"github.com/gin-contrib/sessions"
 | 
			
		||||
@@ -9,9 +12,6 @@ import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	logger2 "openai/logger"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"openai/utils"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime/debug"
 | 
			
		||||
@@ -2,10 +2,10 @@ package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	logger2 "chatplus/logger"
 | 
			
		||||
	"chatplus/types"
 | 
			
		||||
	"github.com/BurntSushi/toml"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	logger2 "openai/logger"
 | 
			
		||||
	"openai/types"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
 | 
			
		||||
    <el-dialog
 | 
			
		||||
        v-model="showDialog"
 | 
			
		||||
        title="编辑用户"
 | 
			
		||||
        title="编辑角色"
 | 
			
		||||
        width="50%"
 | 
			
		||||
    >
 | 
			
		||||
      <el-form :model="form1" label-width="120px" ref="formRef" :rules="rules">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,5 @@
 | 
			
		||||
const {defineConfig} = require('@vue/cli-service')
 | 
			
		||||
let webpack = require('webpack')
 | 
			
		||||
// const fs = require('fs')
 | 
			
		||||
// const path = require('path')
 | 
			
		||||
// const os = require('os')
 | 
			
		||||
 | 
			
		||||
module.exports = defineConfig({
 | 
			
		||||
    transpileDependencies: true,
 | 
			
		||||
    configureWebpack: {
 | 
			
		||||
@@ -17,7 +13,7 @@ module.exports = defineConfig({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    publicPath: '/chat',
 | 
			
		||||
    outputDir: '../dist',
 | 
			
		||||
    outputDir: '../src/dist',
 | 
			
		||||
    crossorigin: "anonymous",
 | 
			
		||||
    devServer: {
 | 
			
		||||
        allowedHosts: ['127.0.0.1:5678'],
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user