From 839dd8dbf4a67871c0e833a2ef2a5e0004b30e87 Mon Sep 17 00:00:00 2001 From: RockYang Date: Sat, 22 Jun 2024 12:37:41 +0800 Subject: [PATCH 01/15] update docker-compose file --- deploy/docker-compose.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/docker-compose.yaml b/deploy/docker-compose.yaml index 94c91431..bbe67468 100644 --- a/deploy/docker-compose.yaml +++ b/deploy/docker-compose.yaml @@ -53,7 +53,7 @@ services: # 后端 API 程序 geekai-api: - image: registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-plus-api:v4.0.8-amd64 + image: registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-plus-api:v4.0.9-amd64 container_name: geekai-api restart: always depends_on: @@ -75,7 +75,7 @@ services: # 前端应用 geekai-web: - image: registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-plus-web:v4.0.8-amd64 + image: registry.cn-shenzhen.aliyuncs.com/geekmaster/geekai-plus-web:v4.0.9-amd64 container_name: geekai-web restart: always depends_on: From a3a2a8abcb8d9e3062d079fb6d1cfc6629b6446d Mon Sep 17 00:00:00 2001 From: RockYang Date: Sat, 22 Jun 2024 16:04:04 +0800 Subject: [PATCH 02/15] add wechat payment configs sample --- api/config.sample.toml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/api/config.sample.toml b/api/config.sample.toml index 2b9642de..461b60a5 100644 --- a/api/config.sample.toml +++ b/api/config.sample.toml @@ -122,4 +122,16 @@ WeChatBot = false AppId = "" # 商户 ID PrivateKey = "" # 秘钥 ApiURL = "https://payjs.cn" - NotifyURL = "https://ai.r9it.com/api/payment/payjs/notify" # 异步回调地址,域名改成你自己的 \ No newline at end of file + NotifyURL = "https://ai.r9it.com/api/payment/payjs/notify" # 异步回调地址,域名改成你自己的 + +# 微信商户支付 +[WechatPayConfig] + Enabled = false + AppId = "" # 商户应用ID + MchId = "" # 商户号 + SerialNo = "" # API 证书序列号 + PrivateKey = "certs/alipay/privateKey.txt" # API 证书私钥文件路径,跟支付宝一样,把私钥文件拷贝到对应的路径,证书路径要映射到容器内 + ApiV3Key = "" # APIV3 私钥,这个是你自己在微信支付平台设置的 + NotifyURL = "https://ai.r9it.com/api/payment/wechat/notify" # 支付成功异步回调地址,域名改成自己的 + ReturnURL = "" # 支付成功同步回调地址 + From 4905fb28d4158174ddc2655569e2c4c03f98c642 Mon Sep 17 00:00:00 2001 From: RockYang Date: Sun, 23 Jun 2024 17:54:42 +0800 Subject: [PATCH 03/15] update version --- web/.env.development | 2 +- web/.env.production | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/.env.development b/web/.env.development index 52e013d9..ec9467e1 100644 --- a/web/.env.development +++ b/web/.env.development @@ -6,4 +6,4 @@ VUE_APP_ADMIN_USER=admin VUE_APP_ADMIN_PASS=admin123 VUE_APP_KEY_PREFIX=ChatPLUS_DEV_ VUE_APP_TITLE="Geek-AI 创作系统" -VUE_APP_VERSION=v4.0.8 +VUE_APP_VERSION=v4.0.9 diff --git a/web/.env.production b/web/.env.production index 3f594239..74545d1d 100644 --- a/web/.env.production +++ b/web/.env.production @@ -2,4 +2,4 @@ VUE_APP_API_HOST= VUE_APP_WS_HOST= VUE_APP_KEY_PREFIX=ChatPLUS_ VUE_APP_TITLE="Geek-AI 创作系统" -VUE_APP_VERSION=v4.0.8 +VUE_APP_VERSION=v4.0.9 From d63536d5ef06ae113f0ae334bb500eee5971eba0 Mon Sep 17 00:00:00 2001 From: RockYang Date: Tue, 25 Jun 2024 09:53:08 +0800 Subject: [PATCH 04/15] fixed bug: mobile chat list could not update chat title --- CHANGELOG.md | 3 +++ database/update-v4.1.0.sql | 1 + web/src/views/mobile/ChatList.vue | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 database/update-v4.1.0.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index a69eb8d0..bfe9c7df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # 更新日志 +## v4.1.0 +* bug修复:修复移动端修改聊天标题不生效的问题 +* ## v4.0.9 * 环境升级:升级 Golang 到 go1.22.4 * 功能增加:接入微信商户号支付渠道 diff --git a/database/update-v4.1.0.sql b/database/update-v4.1.0.sql new file mode 100644 index 00000000..ba309dc9 --- /dev/null +++ b/database/update-v4.1.0.sql @@ -0,0 +1 @@ +ALTER TABLE `chatgpt_chat_models` CHANGE `power` `power` SMALLINT NOT NULL COMMENT '消耗算力点数'; \ No newline at end of file diff --git a/web/src/views/mobile/ChatList.vue b/web/src/views/mobile/ChatList.vue index ed4d186a..96dc91da 100644 --- a/web/src/views/mobile/ChatList.vue +++ b/web/src/views/mobile/ChatList.vue @@ -241,7 +241,7 @@ const editChat = (row) => { tmpChatTitle.value = row.title } const saveTitle = () => { - httpPost('/api/chat/update', {id: item.value.id, title: tmpChatTitle.value}).then(() => { + httpPost('/api/chat/update', {chat_id: item.value.chat_id, title: tmpChatTitle.value}).then(() => { showSuccessToast("操作成功!"); item.value.title = tmpChatTitle.value; }).catch(e => { From f8fed835073369f39b44e77632fed83cc2ee3753 Mon Sep 17 00:00:00 2001 From: RockYang Date: Tue, 25 Jun 2024 18:59:27 +0800 Subject: [PATCH 05/15] feat: new UI for chat file manager is ready --- api/core/types/web.go | 1 + api/handler/chatimpl/chat_handler.go | 2 +- api/handler/upload_handler.go | 23 +++- api/main.go | 2 +- web/.env.development | 2 +- web/.env.production | 2 +- web/public/images/ext/doc.png | Bin 4901 -> 5208 bytes web/public/images/ext/ppt.png | Bin 3442 -> 12734 bytes web/public/images/ext/xls.png | Bin 3220 -> 4809 bytes web/src/assets/css/chat-plus.styl | 40 +++--- web/src/components/ChatPrompt.vue | 182 +++++++++++++++++++++------ web/src/components/FileList.vue | 114 +++++++++++++++++ web/src/components/FileSelect.vue | 37 ++---- web/src/store/system.js | 34 +++++ web/src/utils/libs.js | 17 +-- web/src/views/ChatPlus.vue | 43 +++++-- 16 files changed, 386 insertions(+), 113 deletions(-) create mode 100644 web/src/components/FileList.vue diff --git a/api/core/types/web.go b/api/core/types/web.go index 08f5ee90..aecf8e61 100644 --- a/api/core/types/web.go +++ b/api/core/types/web.go @@ -22,6 +22,7 @@ type WsMessage struct { Type WsMsgType `json:"type"` // 消息类别,start, end, img Content interface{} `json:"content"` } + type WsMsgType string const ( diff --git a/api/handler/chatimpl/chat_handler.go b/api/handler/chatimpl/chat_handler.go index bd6ab8d3..a99c2897 100644 --- a/api/handler/chatimpl/chat_handler.go +++ b/api/handler/chatimpl/chat_handler.go @@ -348,7 +348,7 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio } data = append(data, gin.H{ "type": "text", - "text": text, + "text": strings.TrimSpace(text), }) content = data } else { diff --git a/api/handler/upload_handler.go b/api/handler/upload_handler.go index af37f972..183606da 100644 --- a/api/handler/upload_handler.go +++ b/api/handler/upload_handler.go @@ -9,6 +9,7 @@ package handler import ( "geekai/core" + "geekai/core/types" "geekai/service/oss" "geekai/store/model" "geekai/store/vo" @@ -35,6 +36,12 @@ func (h *UploadHandler) Upload(c *gin.Context) { return } + logger.Info("upload file: %s", file.Name) + // cut the file name if it's too long + if len(file.Name) > 100 { + file.Name = file.Name[:90] + file.Ext + } + userId := h.GetLoginUserId(c) res := h.DB.Create(&model.File{ UserId: int(userId), @@ -54,10 +61,24 @@ func (h *UploadHandler) Upload(c *gin.Context) { } func (h *UploadHandler) List(c *gin.Context) { + var data struct { + Urls []string `json:"urls"` + } + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + logger.Info(data) + userId := h.GetLoginUserId(c) var items []model.File var files = make([]vo.File, 0) - h.DB.Where("user_id = ?", userId).Find(&items) + session := h.DB.Session(&gorm.Session{}) + session = session.Where("user_id = ?", userId) + if len(data.Urls) > 0 { + session = session.Where("url IN ?", data.Urls) + } + session.Find(&items) if len(items) > 0 { for _, v := range items { var file vo.File diff --git a/api/main.go b/api/main.go index e26d07ff..b2c40dd6 100644 --- a/api/main.go +++ b/api/main.go @@ -255,7 +255,7 @@ func main() { }), fx.Invoke(func(s *core.AppServer, h *handler.UploadHandler) { s.Engine.POST("/api/upload", h.Upload) - s.Engine.GET("/api/upload/list", h.List) + s.Engine.POST("/api/upload/list", h.List) s.Engine.GET("/api/upload/remove", h.Remove) }), fx.Invoke(func(s *core.AppServer, h *handler.SmsHandler) { diff --git a/web/.env.development b/web/.env.development index ec9467e1..5a9770cd 100644 --- a/web/.env.development +++ b/web/.env.development @@ -6,4 +6,4 @@ VUE_APP_ADMIN_USER=admin VUE_APP_ADMIN_PASS=admin123 VUE_APP_KEY_PREFIX=ChatPLUS_DEV_ VUE_APP_TITLE="Geek-AI 创作系统" -VUE_APP_VERSION=v4.0.9 +VUE_APP_VERSION=v4.1.0 diff --git a/web/.env.production b/web/.env.production index 74545d1d..8afbdcae 100644 --- a/web/.env.production +++ b/web/.env.production @@ -2,4 +2,4 @@ VUE_APP_API_HOST= VUE_APP_WS_HOST= VUE_APP_KEY_PREFIX=ChatPLUS_ VUE_APP_TITLE="Geek-AI 创作系统" -VUE_APP_VERSION=v4.0.9 +VUE_APP_VERSION=v4.1.0 diff --git a/web/public/images/ext/doc.png b/web/public/images/ext/doc.png index 9e2c3696e7311068326e3851f8694644f8388fb6..465c78f2bf994ee7817e0b3172bfe1fe41eb8014 100644 GIT binary patch literal 5208 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 XOOo>%=Z*Z+Dg^G{($U0fScd->3@oh> literal 4901 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 Ef*88vSO5S3 literal 3442 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 diff --git a/web/public/images/ext/xls.png b/web/public/images/ext/xls.png index 1897bdc3a6fce9d7d30fa21fa5f0b81a3324b0da..c7893c98ec1603e7da10e878d69bc696d9a3a1af 100644 GIT binary patch literal 4809 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 diff --git a/web/src/assets/css/chat-plus.styl b/web/src/assets/css/chat-plus.styl index 61522fe7..4e32cb3e 100644 --- a/web/src/assets/css/chat-plus.styl +++ b/web/src/assets/css/chat-plus.styl @@ -252,25 +252,35 @@ $borderColor = #4676d0; border: 2px solid #21AA93 border-radius 10px padding 10px + background-color #F4F4F4 - - .prompt-input::-webkit-scrollbar { - width: 0; - height: 0; - } - - .prompt-input { + .input-inner { + display flex + flex-flow column width 100% - line-height: 24px - border none - font-size 14px - background none - resize: none - white-space: pre-wrap; /* 保持文本换行 */ - word-wrap: break-word; /* 允许单词换行 */ - overflow-wrap: break-word; /* 允许长单词换行,适用于现代浏览器 */ + + .file-list { + padding-bottom 10px + } + .prompt-input::-webkit-scrollbar { + width: 0; + height: 0; + } + + .prompt-input { + width 100% + line-height: 24px + border none + font-size 14px + background none + resize: none + white-space: pre-wrap; /* 保持文本换行 */ + word-wrap: break-word; /* 允许单词换行 */ + overflow-wrap: break-word; /* 允许长单词换行,适用于现代浏览器 */ + } } + .send-btn { width 32px margin-left 10px diff --git a/web/src/components/ChatPrompt.vue b/web/src/components/ChatPrompt.vue index fcd924e2..eda29117 100644 --- a/web/src/components/ChatPrompt.vue +++ b/web/src/components/ChatPrompt.vue @@ -6,6 +6,25 @@
+
+
+
+ +
+
+
+ +
+
+
{{file.name}}
+
+ {{GetFileType(file.ext)}} + {{FormatFileSize(file.size)}} +
+
+
+
+
{{ createdAt }} @@ -17,50 +36,87 @@
- @@ -92,10 +148,58 @@ export default defineComponent({ .chat-item { width 100% - position: relative; padding: 0 5px 0 0; overflow: hidden; + .file-list-box { + display flex + flex-flow column + .image { + display flex + flex-flow row + margin-right 10px + position relative + + .el-image { + border 1px solid #e3e3e3 + border-radius 10px + margin-bottom 10px + } + } + .item { + display flex + flex-flow row + border-radius 10px + background-color #ffffff + border 1px solid #e3e3e3 + padding 6px + margin-bottom 10px + + .icon { + .el-image { + width 40px + height 40px + } + } + .body { + margin-left 8px + font-size 14px + .title { + font-weight bold + line-height 24px + color #0D0D0D + } + .info { + color #B4B4B4 + + span { + margin-right 10px + } + } + } + } + } + .content { word-break break-word; padding: 6px 10px; @@ -149,4 +253,4 @@ export default defineComponent({ } - \ No newline at end of file + diff --git a/web/src/components/FileList.vue b/web/src/components/FileList.vue new file mode 100644 index 00000000..950788dd --- /dev/null +++ b/web/src/components/FileList.vue @@ -0,0 +1,114 @@ + + + + + \ No newline at end of file diff --git a/web/src/components/FileSelect.vue b/web/src/components/FileSelect.vue index 97fc847f..5690f700 100644 --- a/web/src/components/FileSelect.vue +++ b/web/src/components/FileSelect.vue @@ -1,5 +1,5 @@ diff --git a/web/src/components/TaskList.vue b/web/src/components/TaskList.vue new file mode 100644 index 00000000..d2e63e0d --- /dev/null +++ b/web/src/components/TaskList.vue @@ -0,0 +1,58 @@ + + + + + \ No newline at end of file diff --git a/web/src/router.js b/web/src/router.js index de19cfff..4b534968 100644 --- a/web/src/router.js +++ b/web/src/router.js @@ -101,6 +101,12 @@ const routes = [ meta: {title: '用户登录'}, component: () => import('@/views/Login.vue'), }, + { + name: 'login-callback', + path: '/login/callback', + meta: {title: '用户登录'}, + component: () => import('@/views/LoginCallback.vue'), + }, { name: 'register', path: '/register', diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index c334922c..d452ffc5 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -626,10 +626,12 @@ const connect = function (chat_id, role_id) { reader.onload = () => { const data = JSON.parse(String(reader.result)); if (data.type === 'start') { + const prePrompt = chatData.value[chatData.value.length-1].content chatData.value.push({ type: "reply", id: randString(32), icon: _role['icon'], + prompt:prePrompt, content: "" }); } else if (data.type === 'end') { // 消息接收完毕 @@ -864,7 +866,7 @@ const reGenerate = function (prompt) { type: "prompt", id: randString(32), icon: loginUser.value.avatar, - content: md.render(text) + content: text }); socket.value.send(JSON.stringify({type: "chat", content: prompt})); } diff --git a/web/src/views/Dalle.vue b/web/src/views/Dalle.vue index 1e151b7d..a89053c4 100644 --- a/web/src/views/Dalle.vue +++ b/web/src/views/Dalle.vue @@ -86,43 +86,7 @@

任务列表

-
-
-
-
- - - - - - -
- -
-
- - - -
-
- -
+

创作记录

@@ -228,6 +192,7 @@ import {ElMessage, ElMessageBox, ElNotification} from "element-plus"; import Clipboard from "clipboard"; import {checkSession} from "@/action/session"; import {useSharedStore} from "@/store/sharedata"; +import TaskList from "@/components/TaskList.vue"; const listBoxHeight = ref(0) // const paramBoxHeight = ref(0) diff --git a/web/src/views/Home.vue b/web/src/views/Home.vue index f90ebaef..eef14830 100644 --- a/web/src/views/Home.vue +++ b/web/src/views/Home.vue @@ -215,10 +215,11 @@ const init = () => { const logout = function () { httpGet('/api/user/logout').then(() => { removeUserToken() - store.setShowLoginDialog(true) - loginUser.value = {} - // 刷新组件 - routerViewKey.value += 1 + router.push("/login") + // store.setShowLoginDialog(true) + // loginUser.value = {} + // // 刷新组件 + // routerViewKey.value += 1 }).catch(() => { ElMessage.error('注销失败!'); }) diff --git a/web/src/views/ImageMj.vue b/web/src/views/ImageMj.vue index 2a5555b3..78d9f3c1 100644 --- a/web/src/views/ImageMj.vue +++ b/web/src/views/ImageMj.vue @@ -163,7 +163,7 @@
-
+
@@ -450,43 +450,7 @@

任务列表

-
-
-
-
- - - - - - -
- -
-
- - - -
-
- -
+

创作记录

@@ -617,6 +581,7 @@ import {useRouter} from "vue-router"; import {getSessionId} from "@/store/session"; import {copyObj, removeArrayItem} from "@/utils/libs"; import {useSharedStore} from "@/store/sharedata"; +import TaskList from "@/components/TaskList.vue"; const listBoxHeight = ref(0) const paramBoxHeight = ref(0) diff --git a/web/src/views/ImageSd.vue b/web/src/views/ImageSd.vue index 2706b7cf..d1a75891 100644 --- a/web/src/views/ImageSd.vue +++ b/web/src/views/ImageSd.vue @@ -296,39 +296,8 @@

任务列表

-
-
-
-
- - - - - - -
- -
-
- - - -
-
- -
+ +

创作记录

@@ -506,6 +475,7 @@ import {checkSession} from "@/action/session"; import {useRouter} from "vue-router"; import {getSessionId} from "@/store/session"; import {useSharedStore} from "@/store/sharedata"; +import TaskList from "@/components/TaskList.vue"; const listBoxHeight = ref(0) // const paramBoxHeight = ref(0) diff --git a/web/src/views/Login.vue b/web/src/views/Login.vue index ee8a0332..893c57a5 100644 --- a/web/src/views/Login.vue +++ b/web/src/views/Login.vue @@ -35,19 +35,22 @@ - - - - - - 注册 - + 注册 + 重置密码 - + 首页 + +
+ 其他登录方式 + +
+ +
+
@@ -80,8 +83,7 @@ const password = ref(process.env.VUE_APP_PASS); const showResetPass = ref(false) const logo = ref("/images/logo.png") const licenseConfig = ref({}) -const cLoginURL = ref('') -const span = ref(8) +const wechatLoginURL = ref('') onMounted(() => { // 获取系统配置 @@ -94,7 +96,6 @@ onMounted(() => { httpGet("/api/config/license").then(res => { licenseConfig.value = res.data - span.value = 6 }).catch(e => { showMessageError("获取 License 配置:" + e.message) }) @@ -108,10 +109,9 @@ onMounted(() => { }).catch(() => { }) - // const returnURL = `${location.protocol}//${location.host}/user/api/clogin/callback` - const returnURL = `https://ai.r9it.com/user/api/clogin/callback` + const returnURL = `${location.protocol}//${location.host}/login/callback` httpGet("/api/user/clogin/request?return_url="+returnURL).then(res => { - cLoginURL.value = res.data.url + wechatLoginURL.value = res.data.url }).catch(e => { console.error(e) }) @@ -147,103 +147,5 @@ const login = function () { \ No newline at end of file diff --git a/web/src/views/LoginCallback.vue b/web/src/views/LoginCallback.vue new file mode 100644 index 00000000..1b9110f8 --- /dev/null +++ b/web/src/views/LoginCallback.vue @@ -0,0 +1,105 @@ + + + + + From d1965deff1d0509db3b51d7f8a9477ef7da77973 Mon Sep 17 00:00:00 2001 From: RockYang Date: Fri, 12 Jul 2024 14:39:14 +0800 Subject: [PATCH 13/15] tidy apis --- api/core/app_server.go | 24 +- api/core/types/chat.go | 3 +- api/core/types/task.go | 8 +- api/core/types/web.go | 4 +- api/handler/chatimpl/chat_handler.go | 49 +- api/handler/chatimpl/chat_item_handler.go | 6 +- api/handler/dalle_handler.go | 33 +- api/handler/mj_handler.go | 65 +-- api/handler/order_handler.go | 48 +- api/handler/payment_handler.go | 57 +- api/handler/sd_handler.go | 40 +- api/handler/sms_handler.go | 18 +- api/handler/upload_handler.go | 2 +- api/handler/user_handler.go | 8 +- api/main.go | 18 +- api/utils/resp/response.go | 18 +- database/update-v4.1.0.sql | 4 +- web/src/components/UserOrder.vue | 6 +- web/src/utils/http.js | 8 +- web/src/views/ChatPlus.vue | 7 +- web/src/views/Dalle.vue | 8 +- web/src/views/ImageMj.vue | 8 +- web/src/views/ImageSd.vue | 10 +- web/src/views/Login.vue | 4 +- web/src/views/Member.vue | 2 +- web/src/views/mobile/ImageMj.vue | 637 ---------------------- web/src/views/mobile/ImageSd.vue | 523 ------------------ web/src/views/mobile/ImgWall.vue | 133 ----- web/src/views/mobile/Profile.vue | 2 +- web/src/views/mobile/pages/ImageDall.vue | 8 +- web/src/views/mobile/pages/ImageMj.vue | 8 +- web/src/views/mobile/pages/ImageSd.vue | 8 +- 32 files changed, 203 insertions(+), 1574 deletions(-) delete mode 100644 web/src/views/mobile/ImageMj.vue delete mode 100644 web/src/views/mobile/ImageSd.vue delete mode 100644 web/src/views/mobile/ImgWall.vue diff --git a/api/core/app_server.go b/api/core/app_server.go index dd99a755..12a17567 100644 --- a/api/core/app_server.go +++ b/api/core/app_server.go @@ -32,31 +32,19 @@ import ( ) type AppServer struct { - Debug bool - Config *types.AppConfig - Engine *gin.Engine - ChatContexts *types.LMap[string, []types.Message] // 聊天上下文 Map [chatId] => []Message - + Debug bool + Config *types.AppConfig + Engine *gin.Engine SysConfig *types.SystemConfig // system config cache - - // 保存 Websocket 会话 UserId, 每个 UserId 只能连接一次 - // 防止第三方直接连接 socket 调用 OpenAI API - ChatSession *types.LMap[string, *types.ChatSession] //map[sessionId]UserId - ChatClients *types.LMap[string, *types.WsClient] // map[sessionId]Websocket 连接集合 - ReqCancelFunc *types.LMap[string, context.CancelFunc] // HttpClient 请求取消 handle function } func NewServer(appConfig *types.AppConfig) *AppServer { gin.SetMode(gin.ReleaseMode) gin.DefaultWriter = io.Discard return &AppServer{ - Debug: false, - Config: appConfig, - Engine: gin.Default(), - ChatContexts: types.NewLMap[string, []types.Message](), - ChatSession: types.NewLMap[string, *types.ChatSession](), - ChatClients: types.NewLMap[string, *types.WsClient](), - ReqCancelFunc: types.NewLMap[string, context.CancelFunc](), + Debug: false, + Config: appConfig, + Engine: gin.Default(), } } diff --git a/api/core/types/chat.go b/api/core/types/chat.go index 3827b860..cdf418b6 100644 --- a/api/core/types/chat.go +++ b/api/core/types/chat.go @@ -53,9 +53,8 @@ type Delta struct { // ChatSession 聊天会话对象 type ChatSession struct { SessionId string `json:"session_id"` + UserId uint `json:"user_id"` ClientIP string `json:"client_ip"` // 客户端 IP - Username string `json:"username"` // 当前登录的 username - UserId uint `json:"user_id"` // 当前登录的 user ID ChatId string `json:"chat_id"` // 客户端聊天会话 ID, 多会话模式专用字段 Model ChatModel `json:"model"` // GPT 模型 } diff --git a/api/core/types/task.go b/api/core/types/task.go index 6224a383..129a83b4 100644 --- a/api/core/types/task.go +++ b/api/core/types/task.go @@ -53,10 +53,10 @@ type SdTaskParams struct { NegPrompt string `json:"neg_prompt"` // 反向提示词 Steps int `json:"steps"` // 迭代步数,默认20 Sampler string `json:"sampler"` // 采样器 - Scheduler string `json:"scheduler"` - FaceFix bool `json:"face_fix"` // 面部修复 - CfgScale float32 `json:"cfg_scale"` //引导系数,默认 7 - Seed int64 `json:"seed"` // 随机数种子 + Scheduler string `json:"scheduler"` // 采样调度 + FaceFix bool `json:"face_fix"` // 面部修复 + CfgScale float32 `json:"cfg_scale"` //引导系数,默认 7 + Seed int64 `json:"seed"` // 随机数种子 Height int `json:"height"` Width int `json:"width"` HdFix bool `json:"hd_fix"` // 启用高清修复 diff --git a/api/core/types/web.go b/api/core/types/web.go index aecf8e61..408d9a58 100644 --- a/api/core/types/web.go +++ b/api/core/types/web.go @@ -37,11 +37,9 @@ type BizCode int const ( Success = BizCode(0) Failed = BizCode(1) - NotAuthorized = BizCode(400) // 未授权 - NotPermission = BizCode(403) // 没有权限 + NotAuthorized = BizCode(401) // 未授权 OkMsg = "Success" ErrorMsg = "系统开小差了" InvalidArgs = "非法参数或参数解析失败" - NoData = "No Data" ) diff --git a/api/handler/chatimpl/chat_handler.go b/api/handler/chatimpl/chat_handler.go index 98c2eefe..776aa47c 100644 --- a/api/handler/chatimpl/chat_handler.go +++ b/api/handler/chatimpl/chat_handler.go @@ -44,6 +44,8 @@ type ChatHandler struct { redis *redis.Client uploadManager *oss.UploaderManager licenseService *service.LicenseService + ReqCancelFunc *types.LMap[string, context.CancelFunc] // HttpClient 请求取消 handle function + ChatContexts *types.LMap[string, []types.Message] // 聊天上下文 Map [chatId] => []Message } func NewChatHandler(app *core.AppServer, db *gorm.DB, redis *redis.Client, manager *oss.UploaderManager, licenseService *service.LicenseService) *ChatHandler { @@ -52,6 +54,8 @@ func NewChatHandler(app *core.AppServer, db *gorm.DB, redis *redis.Client, manag redis: redis, uploadManager: manager, licenseService: licenseService, + ReqCancelFunc: types.NewLMap[string, context.CancelFunc](), + ChatContexts: types.NewLMap[string, []types.Message](), } } @@ -89,21 +93,10 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) { return } - session := h.App.ChatSession.Get(sessionId) - if session == nil { - user, err := h.GetLoginUser(c) - if err != nil { - logger.Info("用户未登录") - c.Abort() - return - } - session = &types.ChatSession{ - SessionId: sessionId, - ClientIP: c.ClientIP(), - Username: user.Username, - UserId: user.Id, - } - h.App.ChatSession.Put(sessionId, session) + session := &types.ChatSession{ + SessionId: sessionId, + ClientIP: c.ClientIP(), + UserId: h.GetLoginUserId(c), } // use old chat data override the chat model and role ID @@ -125,22 +118,18 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) { Temperature: chatModel.Temperature, KeyId: chatModel.KeyId, Platform: chatModel.Platform} - logger.Infof("New websocket connected, IP: %s, Username: %s", c.ClientIP(), session.Username) + logger.Infof("New websocket connected, IP: %s", c.ClientIP()) - // 保存会话连接 - h.App.ChatClients.Put(sessionId, client) go func() { for { _, msg, err := client.Receive() if err != nil { logger.Debugf("close connection: %s", client.Conn.RemoteAddr()) client.Close() - h.App.ChatClients.Delete(sessionId) - h.App.ChatSession.Delete(sessionId) - cancelFunc := h.App.ReqCancelFunc.Get(sessionId) + cancelFunc := h.ReqCancelFunc.Get(sessionId) if cancelFunc != nil { cancelFunc() - h.App.ReqCancelFunc.Delete(sessionId) + h.ReqCancelFunc.Delete(sessionId) } return } @@ -160,7 +149,7 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) { logger.Info("Receive a message: ", message.Content) ctx, cancel := context.WithCancel(context.Background()) - h.App.ReqCancelFunc.Put(sessionId, cancel) + h.ReqCancelFunc.Put(sessionId, cancel) // 回复消息 err = h.sendMessage(ctx, session, chatRole, utils.InterfaceToString(message.Content), client) if err != nil { @@ -274,8 +263,8 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio chatCtx := make([]types.Message, 0) messages := make([]types.Message, 0) if h.App.SysConfig.EnableContext { - if h.App.ChatContexts.Has(session.ChatId) { - messages = h.App.ChatContexts.Get(session.ChatId) + if h.ChatContexts.Has(session.ChatId) { + messages = h.ChatContexts.Get(session.ChatId) } else { _ = utils.JsonDecode(role.Context, &messages) if h.App.SysConfig.ContextDeep > 0 { @@ -468,9 +457,9 @@ func getTotalTokens(req types.ApiRequest) int { // StopGenerate 停止生成 func (h *ChatHandler) StopGenerate(c *gin.Context) { sessionId := c.Query("session_id") - if h.App.ReqCancelFunc.Has(sessionId) { - h.App.ReqCancelFunc.Get(sessionId)() - h.App.ReqCancelFunc.Delete(sessionId) + if h.ReqCancelFunc.Has(sessionId) { + h.ReqCancelFunc.Get(sessionId)() + h.ReqCancelFunc.Delete(sessionId) } resp.SUCCESS(c, types.OkMsg) } @@ -628,7 +617,7 @@ func (h *ChatHandler) saveChatHistory( if h.App.SysConfig.EnableContext { chatCtx = append(chatCtx, useMsg) // 提问消息 chatCtx = append(chatCtx, message) // 回复消息 - h.App.ChatContexts.Put(session.ChatId, chatCtx) + h.ChatContexts.Put(session.ChatId, chatCtx) } // 追加聊天记录 @@ -686,7 +675,7 @@ func (h *ChatHandler) saveChatHistory( res = h.DB.Where("chat_id = ?", session.ChatId).First(&chatItem) if res.Error != nil { chatItem.ChatId = session.ChatId - chatItem.UserId = session.UserId + chatItem.UserId = userVo.Id chatItem.RoleId = role.Id chatItem.ModelId = session.Model.Id if utf8.RuneCountInString(prompt) > 30 { diff --git a/api/handler/chatimpl/chat_item_handler.go b/api/handler/chatimpl/chat_item_handler.go index 3e04bf6e..bce39249 100644 --- a/api/handler/chatimpl/chat_item_handler.go +++ b/api/handler/chatimpl/chat_item_handler.go @@ -96,7 +96,7 @@ func (h *ChatHandler) Clear(c *gin.Context) { for _, chat := range chats { chatIds = append(chatIds, chat.ChatId) // 清空会话上下文 - h.App.ChatContexts.Delete(chat.ChatId) + h.ChatContexts.Delete(chat.ChatId) } err = h.DB.Transaction(func(tx *gorm.DB) error { res := h.DB.Where("user_id =?", user.Id).Delete(&model.ChatItem{}) @@ -108,8 +108,6 @@ func (h *ChatHandler) Clear(c *gin.Context) { if res.Error != nil { return res.Error } - - // TODO: 是否要删除 MidJourney 绘画记录和图片文件? return nil }) @@ -175,7 +173,7 @@ func (h *ChatHandler) Remove(c *gin.Context) { // TODO: 是否要删除 MidJourney 绘画记录和图片文件? // 清空会话上下文 - h.App.ChatContexts.Delete(chatId) + h.ChatContexts.Delete(chatId) resp.SUCCESS(c, types.OkMsg) } diff --git a/api/handler/dalle_handler.go b/api/handler/dalle_handler.go index 07cd032c..89226638 100644 --- a/api/handler/dalle_handler.go +++ b/api/handler/dalle_handler.go @@ -158,13 +158,13 @@ func (h *DallJobHandler) ImgWall(c *gin.Context) { // JobList 获取 SD 任务列表 func (h *DallJobHandler) JobList(c *gin.Context) { - status := h.GetBool(c, "status") + finish := h.GetBool(c, "finish") userId := h.GetLoginUserId(c) page := h.GetInt(c, "page", 0) pageSize := h.GetInt(c, "page_size", 0) publish := h.GetBool(c, "publish") - err, jobs := h.getData(status, userId, page, pageSize, publish) + err, jobs := h.getData(finish, userId, page, pageSize, publish) if err != nil { resp.ERROR(c, err.Error()) return @@ -214,25 +214,23 @@ func (h *DallJobHandler) getData(finish bool, userId uint, page int, pageSize in // Remove remove task image func (h *DallJobHandler) Remove(c *gin.Context) { - var data struct { - Id uint `json:"id"` - UserId uint `json:"user_id"` - ImgURL string `json:"img_url"` - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) + id := h.GetInt(c, "id", 0) + userId := h.GetInt(c, "user_id", 0) + var job model.DallJob + if res := h.DB.Where("id = ? AND user_id = ?", id, userId).First(&job); res.Error != nil { + resp.ERROR(c, "记录不存在") return } // remove job recode - res := h.DB.Delete(&model.DallJob{Id: data.Id}) + res := h.DB.Delete(&model.DallJob{Id: job.Id}) if res.Error != nil { resp.ERROR(c, res.Error.Error()) return } // remove image - err := h.uploader.GetUploadHandler().Delete(data.ImgURL) + err := h.uploader.GetUploadHandler().Delete(job.ImgURL) if err != nil { logger.Error("remove image failed: ", err) } @@ -242,16 +240,11 @@ func (h *DallJobHandler) Remove(c *gin.Context) { // Publish 发布/取消发布图片到画廊显示 func (h *DallJobHandler) Publish(c *gin.Context) { - var data struct { - Id uint `json:"id"` - Action bool `json:"action"` // 发布动作,true => 发布,false => 取消分享 - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) - return - } + id := h.GetInt(c, "id", 0) + userId := h.GetInt(c, "user_id", 0) + action := h.GetBool(c, "action") // 发布动作,true => 发布,false => 取消分享 - res := h.DB.Model(&model.DallJob{Id: data.Id}).UpdateColumn("publish", true) + res := h.DB.Model(&model.DallJob{Id: uint(id), UserId: uint(userId)}).UpdateColumn("publish", action) if res.Error != nil { logger.Error("error with update database:", res.Error) resp.ERROR(c, "更新数据库失败") diff --git a/api/handler/mj_handler.go b/api/handler/mj_handler.go index 7f6f6b7d..56340af1 100644 --- a/api/handler/mj_handler.go +++ b/api/handler/mj_handler.go @@ -92,19 +92,18 @@ func (h *MidJourneyHandler) Client(c *gin.Context) { // Image 创建一个绘画任务 func (h *MidJourneyHandler) Image(c *gin.Context) { var data struct { - SessionId string `json:"session_id"` TaskType string `json:"task_type"` Prompt string `json:"prompt"` NegPrompt string `json:"neg_prompt"` Rate string `json:"rate"` - Model string `json:"model"` - Chaos int `json:"chaos"` - Raw bool `json:"raw"` - Seed int64 `json:"seed"` - Stylize int `json:"stylize"` + Model string `json:"model"` // 模型 + Chaos int `json:"chaos"` // 创意度取值范围: 0-100 + Raw bool `json:"raw"` // 是否开启原始模型 + Seed int64 `json:"seed"` // 随机数 + Stylize int `json:"stylize"` // 风格化 ImgArr []string `json:"img_arr"` - Tile bool `json:"tile"` - Quality float32 `json:"quality"` + Tile bool `json:"tile"` // 重复平铺 + Quality float32 `json:"quality"` // 画质 Iw float32 `json:"iw"` CRef string `json:"cref"` //生成角色一致的图像 SRef string `json:"sref"` //生成风格一致的图像 @@ -243,17 +242,12 @@ type reqVo struct { ChannelId string `json:"channel_id"` MessageId string `json:"message_id"` MessageHash string `json:"message_hash"` - SessionId string `json:"session_id"` - Prompt string `json:"prompt"` - ChatId string `json:"chat_id"` - RoleId int `json:"role_id"` - Icon string `json:"icon"` } // Upscale send upscale command to MidJourney Bot func (h *MidJourneyHandler) Upscale(c *gin.Context) { var data reqVo - if err := c.ShouldBindJSON(&data); err != nil || data.SessionId == "" { + if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) return } @@ -271,7 +265,6 @@ func (h *MidJourneyHandler) Upscale(c *gin.Context) { UserId: userId, TaskId: taskId, Progress: 0, - Prompt: data.Prompt, Power: h.App.SysConfig.MjActionPower, CreatedAt: time.Now(), } @@ -283,7 +276,6 @@ func (h *MidJourneyHandler) Upscale(c *gin.Context) { h.pool.PushTask(types.MjTask{ Id: job.Id, Type: types.TaskUpscale, - Prompt: data.Prompt, UserId: userId, ChannelId: data.ChannelId, Index: data.Index, @@ -318,7 +310,7 @@ func (h *MidJourneyHandler) Upscale(c *gin.Context) { // Variation send variation command to MidJourney Bot func (h *MidJourneyHandler) Variation(c *gin.Context) { var data reqVo - if err := c.ShouldBindJSON(&data); err != nil || data.SessionId == "" { + if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) return } @@ -337,7 +329,6 @@ func (h *MidJourneyHandler) Variation(c *gin.Context) { UserId: userId, TaskId: taskId, Progress: 0, - Prompt: data.Prompt, Power: h.App.SysConfig.MjActionPower, CreatedAt: time.Now(), } @@ -349,7 +340,6 @@ func (h *MidJourneyHandler) Variation(c *gin.Context) { h.pool.PushTask(types.MjTask{ Id: job.Id, Type: types.TaskVariation, - Prompt: data.Prompt, UserId: userId, Index: data.Index, ChannelId: data.ChannelId, @@ -397,13 +387,13 @@ func (h *MidJourneyHandler) ImgWall(c *gin.Context) { // JobList 获取 MJ 任务列表 func (h *MidJourneyHandler) JobList(c *gin.Context) { - status := h.GetBool(c, "status") + finish := h.GetBool(c, "finish") userId := h.GetLoginUserId(c) page := h.GetInt(c, "page", 0) pageSize := h.GetInt(c, "page_size", 0) publish := h.GetBool(c, "publish") - err, jobs := h.getData(status, userId, page, pageSize, publish) + err, jobs := h.getData(finish, userId, page, pageSize, publish) if err != nil { resp.ERROR(c, err.Error()) return @@ -459,30 +449,27 @@ func (h *MidJourneyHandler) getData(finish bool, userId uint, page int, pageSize // Remove remove task image func (h *MidJourneyHandler) Remove(c *gin.Context) { - var data struct { - Id uint `json:"id"` - UserId uint `json:"user_id"` - ImgURL string `json:"img_url"` - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) + id := h.GetInt(c, "id", 0) + userId := h.GetInt(c, "user_id", 0) + var job model.MidJourneyJob + if res := h.DB.Where("id = ? AND user_id = ?", id, userId).First(&job); res.Error != nil { + resp.ERROR(c, "记录不存在") return } - // remove job recode - res := h.DB.Delete(&model.MidJourneyJob{Id: data.Id}) + res := h.DB.Delete(&job) if res.Error != nil { resp.ERROR(c, res.Error.Error()) return } // remove image - err := h.uploader.GetUploadHandler().Delete(data.ImgURL) + err := h.uploader.GetUploadHandler().Delete(job.ImgURL) if err != nil { logger.Error("remove image failed: ", err) } - client := h.pool.Clients.Get(data.UserId) + client := h.pool.Clients.Get(uint(job.UserId)) if client != nil { _ = client.Send([]byte("Task Updated")) } @@ -492,16 +479,10 @@ func (h *MidJourneyHandler) Remove(c *gin.Context) { // Publish 发布图片到画廊显示 func (h *MidJourneyHandler) Publish(c *gin.Context) { - var data struct { - Id uint `json:"id"` - Action bool `json:"action"` // 发布动作,true => 发布,false => 取消分享 - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) - return - } - - res := h.DB.Model(&model.MidJourneyJob{Id: data.Id}).UpdateColumn("publish", data.Action) + id := h.GetInt(c, "id", 0) + userId := h.GetInt(c, "user_id", 0) + action := h.GetBool(c, "action") // 发布动作,true => 发布,false => 取消分享 + res := h.DB.Model(&model.MidJourneyJob{Id: uint(id), UserId: userId}).UpdateColumn("publish", action) if res.Error != nil { logger.Error("error with update database:", res.Error) resp.ERROR(c, "更新数据库失败") diff --git a/api/handler/order_handler.go b/api/handler/order_handler.go index a56daa82..55348e1b 100644 --- a/api/handler/order_handler.go +++ b/api/handler/order_handler.go @@ -14,6 +14,7 @@ import ( "geekai/store/vo" "geekai/utils" "geekai/utils/resp" + "time" "github.com/gin-gonic/gin" "gorm.io/gorm" @@ -27,23 +28,18 @@ func NewOrderHandler(app *core.AppServer, db *gorm.DB) *OrderHandler { return &OrderHandler{BaseHandler: BaseHandler{App: app, DB: db}} } +// List 订单列表 func (h *OrderHandler) List(c *gin.Context) { - var data struct { - Page int `json:"page"` - PageSize int `json:"page_size"` - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) - return - } + page := h.GetInt(c, "page", 1) + pageSize := h.GetInt(c, "page_size", 20) userId := h.GetLoginUserId(c) session := h.DB.Session(&gorm.Session{}).Where("user_id = ? AND status = ?", userId, types.OrderPaidSuccess) var total int64 session.Model(&model.Order{}).Count(&total) var items []model.Order var list = make([]vo.Order, 0) - offset := (data.Page - 1) * data.PageSize - res := session.Order("id DESC").Offset(offset).Limit(data.PageSize).Find(&items) + offset := (page - 1) * pageSize + res := session.Order("id DESC").Offset(offset).Limit(pageSize).Find(&items) if res.Error == nil { for _, item := range items { var order vo.Order @@ -58,5 +54,35 @@ func (h *OrderHandler) List(c *gin.Context) { } } } - resp.SUCCESS(c, vo.NewPage(total, data.Page, data.PageSize, list)) + resp.SUCCESS(c, vo.NewPage(total, page, pageSize, list)) +} + +// Query 查询订单状态 +func (h *OrderHandler) Query(c *gin.Context) { + orderNo := h.GetTrim(c, "order_no") + var order model.Order + res := h.DB.Where("order_no = ?", orderNo).First(&order) + if res.Error != nil { + resp.ERROR(c, "Order not found") + return + } + + if order.Status == types.OrderPaidSuccess { + resp.SUCCESS(c, gin.H{"status": order.Status}) + return + } + + counter := 0 + for { + time.Sleep(time.Second) + var item model.Order + h.DB.Where("order_no = ?", orderNo).First(&item) + if counter >= 15 || item.Status == types.OrderPaidSuccess || item.Status != order.Status { + order.Status = item.Status + break + } + counter++ + } + + resp.SUCCESS(c, gin.H{"status": order.Status}) } diff --git a/api/handler/payment_handler.go b/api/handler/payment_handler.go index c69f0703..5d807f79 100644 --- a/api/handler/payment_handler.go +++ b/api/handler/payment_handler.go @@ -111,7 +111,7 @@ func (h *PaymentHandler) DoPay(c *gin.Context) { // fix: 这里先检查一下订单状态,如果已经支付了,就直接返回 if order.Status == types.OrderPaidSuccess { - resp.ERROR(c, "This order had been paid, please do not pay twice") + resp.ERROR(c, "订单已支付成功,无需重复支付!") return } @@ -148,49 +148,11 @@ func (h *PaymentHandler) DoPay(c *gin.Context) { resp.ERROR(c, "Invalid operations") } -// OrderQuery 查询订单状态 -func (h *PaymentHandler) OrderQuery(c *gin.Context) { - var data struct { - OrderNo string `json:"order_no"` - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) - return - } - - var order model.Order - res := h.DB.Where("order_no = ?", data.OrderNo).First(&order) - if res.Error != nil { - resp.ERROR(c, "Order not found") - return - } - - if order.Status == types.OrderPaidSuccess { - resp.SUCCESS(c, gin.H{"status": order.Status}) - return - } - - counter := 0 - for { - time.Sleep(time.Second) - var item model.Order - h.DB.Where("order_no = ?", data.OrderNo).First(&item) - if counter >= 15 || item.Status == types.OrderPaidSuccess || item.Status != order.Status { - order.Status = item.Status - break - } - counter++ - } - - resp.SUCCESS(c, gin.H{"status": order.Status}) -} - // PayQrcode 生成支付 URL 二维码 func (h *PaymentHandler) PayQrcode(c *gin.Context) { var data struct { PayWay string `json:"pay_way"` // 支付方式 ProductId uint `json:"product_id"` - UserId int `json:"user_id"` } if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) @@ -209,10 +171,9 @@ func (h *PaymentHandler) PayQrcode(c *gin.Context) { resp.ERROR(c, "error with generate trade no: "+err.Error()) return } - var user model.User - res = h.DB.First(&user, data.UserId) - if res.Error != nil { - resp.ERROR(c, "Invalid user ID") + user, err := h.GetLoginUser(c) + if err != nil { + resp.NotAuth(c) return } @@ -333,7 +294,6 @@ func (h *PaymentHandler) Mobile(c *gin.Context) { var data struct { PayWay string `json:"pay_way"` // 支付方式 ProductId uint `json:"product_id"` - UserId int `json:"user_id"` } if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) @@ -352,10 +312,9 @@ func (h *PaymentHandler) Mobile(c *gin.Context) { resp.ERROR(c, "error with generate trade no: "+err.Error()) return } - var user model.User - res = h.DB.First(&user, data.UserId) - if res.Error != nil { - resp.ERROR(c, "Invalid user ID") + user, err := h.GetLoginUser(c) + if err != nil { + resp.NotAuth(c) return } @@ -449,7 +408,7 @@ func (h *PaymentHandler) Mobile(c *gin.Context) { return } - resp.SUCCESS(c, payURL) + resp.SUCCESS(c, gin.H{"url": payURL, "order_no": orderNo}) } // 异步通知回调公共逻辑 diff --git a/api/handler/sd_handler.go b/api/handler/sd_handler.go index 5ed3c009..c99d2f9b 100644 --- a/api/handler/sd_handler.go +++ b/api/handler/sd_handler.go @@ -99,10 +99,7 @@ func (h *SdJobHandler) Image(c *gin.Context) { return } - var data struct { - SessionId string `json:"session_id"` - types.SdTaskParams - } + var data types.SdTaskParams if err := c.ShouldBindJSON(&data); err != nil || data.Prompt == "" { resp.ERROR(c, types.InvalidArgs) return @@ -215,13 +212,13 @@ func (h *SdJobHandler) ImgWall(c *gin.Context) { // JobList 获取 SD 任务列表 func (h *SdJobHandler) JobList(c *gin.Context) { - status := h.GetBool(c, "status") + finish := h.GetBool(c, "finish") userId := h.GetLoginUserId(c) page := h.GetInt(c, "page", 0) pageSize := h.GetInt(c, "page_size", 0) publish := h.GetBool(c, "publish") - err, jobs := h.getData(status, userId, page, pageSize, publish) + err, jobs := h.getData(finish, userId, page, pageSize, publish) if err != nil { resp.ERROR(c, err.Error()) return @@ -280,30 +277,28 @@ func (h *SdJobHandler) getData(finish bool, userId uint, page int, pageSize int, // Remove remove task image func (h *SdJobHandler) Remove(c *gin.Context) { - var data struct { - Id uint `json:"id"` - UserId uint `json:"user_id"` - ImgURL string `json:"img_url"` - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) + id := h.GetInt(c, "id", 0) + userId := h.GetInt(c, "user_id", 0) + var job model.SdJob + if res := h.DB.Where("id = ? AND user_id = ?", id, userId).First(&job); res.Error != nil { + resp.ERROR(c, "记录不存在") return } // remove job recode - res := h.DB.Delete(&model.SdJob{Id: data.Id}) + res := h.DB.Delete(&model.SdJob{Id: job.Id}) if res.Error != nil { resp.ERROR(c, res.Error.Error()) return } // remove image - err := h.uploader.GetUploadHandler().Delete(data.ImgURL) + err := h.uploader.GetUploadHandler().Delete(job.ImgURL) if err != nil { logger.Error("remove image failed: ", err) } - client := h.pool.Clients.Get(data.UserId) + client := h.pool.Clients.Get(uint(job.UserId)) if client != nil { _ = client.Send([]byte(sd.Finished)) } @@ -313,16 +308,11 @@ func (h *SdJobHandler) Remove(c *gin.Context) { // Publish 发布/取消发布图片到画廊显示 func (h *SdJobHandler) Publish(c *gin.Context) { - var data struct { - Id uint `json:"id"` - Action bool `json:"action"` // 发布动作,true => 发布,false => 取消分享 - } - if err := c.ShouldBindJSON(&data); err != nil { - resp.ERROR(c, types.InvalidArgs) - return - } + id := h.GetInt(c, "id", 0) + userId := h.GetInt(c, "user_id", 0) + action := h.GetBool(c, "action") // 发布动作,true => 发布,false => 取消分享 - res := h.DB.Model(&model.SdJob{Id: data.Id}).UpdateColumn("publish", true) + res := h.DB.Model(&model.SdJob{Id: uint(id), UserId: userId}).UpdateColumn("publish", action) if res.Error != nil { logger.Error("error with update database:", res.Error) resp.ERROR(c, "更新数据库失败") diff --git a/api/handler/sms_handler.go b/api/handler/sms_handler.go index 38a61da6..680f73e1 100644 --- a/api/handler/sms_handler.go +++ b/api/handler/sms_handler.go @@ -49,14 +49,20 @@ func (h *SmsHandler) SendCode(c *gin.Context) { var data struct { Receiver string `json:"receiver"` // 接收者 Key string `json:"key"` - Dots string `json:"dots"` + Dots string `json:"dots,omitempty"` + X int `json:"x,omitempty"` } if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) return } - - if !h.captcha.Check(data) { + var check bool + if data.X != 0 { + check = h.captcha.SlideCheck(data) + } else { + check = h.captcha.Check(data) + } + if !check { resp.ERROR(c, "验证码错误,请先完人机验证") return } @@ -89,5 +95,9 @@ func (h *SmsHandler) SendCode(c *gin.Context) { return } - resp.SUCCESS(c) + if h.App.Debug { + resp.SUCCESS(c, code) + } else { + resp.SUCCESS(c) + } } diff --git a/api/handler/upload_handler.go b/api/handler/upload_handler.go index d47444b0..f144e133 100644 --- a/api/handler/upload_handler.go +++ b/api/handler/upload_handler.go @@ -62,7 +62,7 @@ func (h *UploadHandler) Upload(c *gin.Context) { func (h *UploadHandler) List(c *gin.Context) { var data struct { - Urls []string `json:"urls"` + Urls []string `json:"urls,omitempty"` } if err := c.ShouldBindJSON(&data); err != nil { resp.ERROR(c, types.InvalidArgs) diff --git a/api/handler/user_handler.go b/api/handler/user_handler.go index c765a100..6c6bb68b 100644 --- a/api/handler/user_handler.go +++ b/api/handler/user_handler.go @@ -185,7 +185,7 @@ func (h *UserHandler) Register(c *gin.Context) { resp.ERROR(c, "error with save token: "+err.Error()) return } - resp.SUCCESS(c, tokenString) + resp.SUCCESS(c, gin.H{"token": tokenString, "user_id": user.Id, "username": user.Username}) } // Login 用户登录 @@ -244,7 +244,7 @@ func (h *UserHandler) Login(c *gin.Context) { resp.ERROR(c, "error with save token: "+err.Error()) return } - resp.SUCCESS(c, tokenString) + resp.SUCCESS(c, gin.H{"token": tokenString, "user_id": user.Id, "username": user.Username}) } // Logout 注 销 @@ -256,8 +256,8 @@ func (h *UserHandler) Logout(c *gin.Context) { resp.SUCCESS(c) } -// CLoginRequest 第三方登录请求二维码 -func (h *UserHandler) CLoginRequest(c *gin.Context) { +// Clogin 第三方登录请求二维码 +func (h *UserHandler) Clogin(c *gin.Context) { returnURL := h.GetTrim(c, "return_url") var res types.BizVo apiURL := fmt.Sprintf("%s/api/clogin/request", h.App.Config.ApiConfig.ApiURL) diff --git a/api/main.go b/api/main.go index d95358f9..ff036e3f 100644 --- a/api/main.go +++ b/api/main.go @@ -240,7 +240,7 @@ func main() { group.POST("password", h.UpdatePass) group.POST("bind/username", h.BindUsername) group.POST("resetPass", h.ResetPass) - group.GET("clogin/request", h.CLoginRequest) + group.GET("clogin", h.Clogin) group.GET("clogin/callback", h.CLoginCallback) }), fx.Invoke(func(s *core.AppServer, h *chatimpl.ChatHandler) { @@ -283,8 +283,8 @@ func main() { group.POST("variation", h.Variation) group.GET("jobs", h.JobList) group.GET("imgWall", h.ImgWall) - group.POST("remove", h.Remove) - group.POST("publish", h.Publish) + group.GET("remove", h.Remove) + group.GET("publish", h.Publish) }), fx.Invoke(func(s *core.AppServer, h *handler.SdJobHandler) { group := s.Engine.Group("/api/sd") @@ -292,8 +292,8 @@ func main() { group.POST("image", h.Image) group.GET("jobs", h.JobList) group.GET("imgWall", h.ImgWall) - group.POST("remove", h.Remove) - group.POST("publish", h.Publish) + group.GET("remove", h.Remove) + group.GET("publish", h.Publish) }), fx.Invoke(func(s *core.AppServer, h *handler.ConfigHandler) { group := s.Engine.Group("/api/config/") @@ -370,7 +370,6 @@ func main() { group := s.Engine.Group("/api/payment/") group.GET("doPay", h.DoPay) group.GET("payWays", h.GetPayWays) - group.POST("query", h.OrderQuery) group.POST("qrcode", h.PayQrcode) group.POST("mobile", h.Mobile) group.POST("alipay/notify", h.AlipayNotify) @@ -393,7 +392,8 @@ func main() { }), fx.Invoke(func(s *core.AppServer, h *handler.OrderHandler) { group := s.Engine.Group("/api/order/") - group.POST("list", h.List) + group.GET("list", h.List) + group.GET("query", h.Query) }), fx.Invoke(func(s *core.AppServer, h *handler.ProductHandler) { group := s.Engine.Group("/api/product/") @@ -472,8 +472,8 @@ func main() { group.POST("image", h.Image) group.GET("jobs", h.JobList) group.GET("imgWall", h.ImgWall) - group.POST("remove", h.Remove) - group.POST("publish", h.Publish) + group.GET("remove", h.Remove) + group.GET("publish", h.Publish) }), fx.Invoke(func(s *core.AppServer, db *gorm.DB) { go func() { diff --git a/api/utils/resp/response.go b/api/utils/resp/response.go index 3d211246..cc20b2bf 100644 --- a/api/utils/resp/response.go +++ b/api/utils/resp/response.go @@ -24,28 +24,20 @@ func SUCCESS(c *gin.Context, values ...interface{}) { func ERROR(c *gin.Context, messages ...string) { if messages != nil { - c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: messages[0]}) + c.JSON(http.StatusBadRequest, types.BizVo{Code: types.Failed, Message: messages[0]}) } else { - c.JSON(http.StatusOK, types.BizVo{Code: types.Failed}) + c.JSON(http.StatusBadRequest, types.BizVo{Code: types.Failed}) } } func HACKER(c *gin.Context) { - c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "Hacker attempt!!!"}) + c.JSON(http.StatusBadRequest, types.BizVo{Code: types.Failed, Message: "Hacker attempt!!!"}) } func NotAuth(c *gin.Context, messages ...string) { if messages != nil { - c.JSON(http.StatusOK, types.BizVo{Code: types.NotAuthorized, Message: messages[0]}) + c.JSON(http.StatusUnauthorized, types.BizVo{Code: types.NotAuthorized, Message: messages[0]}) } else { - c.JSON(http.StatusOK, types.BizVo{Code: types.NotAuthorized, Message: "Not Authorized"}) - } -} - -func NotPermission(c *gin.Context, messages ...string) { - if messages != nil { - c.JSON(http.StatusOK, types.BizVo{Code: types.NotPermission, Message: messages[0]}) - } else { - c.JSON(http.StatusOK, types.BizVo{Code: types.NotPermission, Message: "Not Permission"}) + c.JSON(http.StatusUnauthorized, types.BizVo{Code: types.NotAuthorized, Message: "Not Authorized"}) } } diff --git a/database/update-v4.1.0.sql b/database/update-v4.1.0.sql index 37d36e92..3f55b35a 100644 --- a/database/update-v4.1.0.sql +++ b/database/update-v4.1.0.sql @@ -1,6 +1,6 @@ ALTER TABLE `chatgpt_chat_models` CHANGE `power` `power` SMALLINT NOT NULL COMMENT '消耗算力点数'; ALTER TABLE `chatgpt_users` ADD `openid` VARCHAR(100) NULL COMMENT '第三方登录账号ID' AFTER `last_login_ip`; -ALTER TABLE `chatgpt_users` ADD UNIQUE(`openid`); ALTER TABLE `chatgpt_users` ADD `platform` VARCHAR(30) NULL COMMENT '登录平台' AFTER `openid`; ALTER TABLE `chatgpt_users` CHANGE `avatar` `avatar` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '头像'; -ALTER TABLE `chatgpt_chat_history` CHANGE `icon` `icon` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色图标'; \ No newline at end of file +ALTER TABLE `chatgpt_chat_history` CHANGE `icon` `icon` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色图标'; +ALTER TABLE `chatgpt_orders` CHANGE `status` `status` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '订单状态(0:待支付,1:已扫码,2:支付成功)'; \ No newline at end of file diff --git a/web/src/components/UserOrder.vue b/web/src/components/UserOrder.vue index 0fdd9bd1..dd8a6c59 100644 --- a/web/src/components/UserOrder.vue +++ b/web/src/components/UserOrder.vue @@ -46,8 +46,8 @@ - - \ No newline at end of file diff --git a/web/src/views/mobile/ImageSd.vue b/web/src/views/mobile/ImageSd.vue deleted file mode 100644 index b310a0a1..00000000 --- a/web/src/views/mobile/ImageSd.vue +++ /dev/null @@ -1,523 +0,0 @@ - - - - - \ No newline at end of file diff --git a/web/src/views/mobile/ImgWall.vue b/web/src/views/mobile/ImgWall.vue deleted file mode 100644 index 8d33a9dd..00000000 --- a/web/src/views/mobile/ImgWall.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - - - diff --git a/web/src/views/mobile/Profile.vue b/web/src/views/mobile/Profile.vue index 48f8b722..cc304d3b 100644 --- a/web/src/views/mobile/Profile.vue +++ b/web/src/views/mobile/Profile.vue @@ -302,7 +302,7 @@ const pay = (payWay, item) => { if (isWeChatBrowser() && payWay === 'wechat') { showFailToast("请在系统自带浏览器打开支付页面,或者在 PC 端进行扫码支付") } else { - location.href = res.data + location.href = res.data.url } }).catch(e => { showFailToast("生成支付订单失败:" + e.message) diff --git a/web/src/views/mobile/pages/ImageDall.vue b/web/src/views/mobile/pages/ImageDall.vue index 6c345b17..f6ad4b1f 100644 --- a/web/src/views/mobile/pages/ImageDall.vue +++ b/web/src/views/mobile/pages/ImageDall.vue @@ -317,7 +317,7 @@ const initData = () => { const fetchRunningJobs = () => { // 获取运行中的任务 - httpGet(`/api/dall/jobs?status=0`).then(res => { + httpGet(`/api/dall/jobs?finish=0`).then(res => { const jobs = res.data const _jobs = [] for (let i = 0; i < jobs.length; i++) { @@ -345,7 +345,7 @@ const pageSize = ref(10) // 获取已完成的任务 const fetchFinishJobs = (page) => { loading.value = true - httpGet(`/api/dall/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => { + httpGet(`/api/dall/jobs?finish=1&page=${page}&page_size=${pageSize.value}`).then(res => { if (res.data.length < pageSize.value) { finished.value = true } @@ -410,7 +410,7 @@ const removeImage = (event, item) => { message: '此操作将会删除任务和图片,继续操作码?', }).then(() => { - httpPost("/api/dall/remove", {id: item.id, img_url: item.img_url, user_id: userId.value}).then(() => { + httpGet("/api/dall/remove", {id: item.id, user_id: item.user_id}).then(() => { showSuccessToast("任务删除成功") }).catch(e => { showFailToast("任务删除失败:" + e.message) @@ -427,7 +427,7 @@ const publishImage = (event, item, action) => { if (action === false) { text = "取消发布" } - httpPost("/api/dall/publish", {id: item.id, action: action}).then(() => { + httpGet("/api/dall/publish", {id: item.id, action: action, user_id: item.user_id}).then(() => { showSuccessToast(text + "成功") item.publish = action }).catch(e => { diff --git a/web/src/views/mobile/pages/ImageMj.vue b/web/src/views/mobile/pages/ImageMj.vue index 46b026e2..d807958b 100644 --- a/web/src/views/mobile/pages/ImageMj.vue +++ b/web/src/views/mobile/pages/ImageMj.vue @@ -421,7 +421,7 @@ const connect = () => { // 获取运行中的任务 const fetchRunningJobs = (userId) => { - httpGet(`/api/mj/jobs?status=0&user_id=${userId}`).then(res => { + httpGet(`/api/mj/jobs?finish=0&user_id=${userId}`).then(res => { const jobs = res.data const _jobs = [] for (let i = 0; i < jobs.length; i++) { @@ -453,7 +453,7 @@ const pageSize = ref(10) const fetchFinishJobs = (page) => { loading.value = true // 获取已完成的任务 - httpGet(`/api/mj/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => { + httpGet(`/api/mj/jobs?finish=1&page=${page}&page_size=${pageSize.value}`).then(res => { const jobs = res.data for (let i = 0; i < jobs.length; i++) { if (jobs[i].progress === -1) { @@ -600,7 +600,7 @@ const removeImage = (item) => { message: '此操作将会删除任务和图片,继续操作码?', }).then(() => { - httpPost("/api/mj/remove", {id: item.id, img_url: item.img_url, user_id: userId.value}).then(() => { + httpGet("/api/mj/remove", {id: item.id, user_id: item.user_id}).then(() => { showSuccessToast("任务删除成功") }).catch(e => { showFailToast("任务删除失败:" + e.message) @@ -615,7 +615,7 @@ const publishImage = (item, action) => { if (action === false) { text = "取消发布" } - httpPost("/api/mj/publish", {id: item.id, action: action}).then(() => { + httpGet("/api/mj/publish", {id: item.id, action: action,user_id: item.user_id}).then(() => { showSuccessToast(text + "成功") item.publish = action }).catch(e => { diff --git a/web/src/views/mobile/pages/ImageSd.vue b/web/src/views/mobile/pages/ImageSd.vue index 50a92f5e..44f90d0a 100644 --- a/web/src/views/mobile/pages/ImageSd.vue +++ b/web/src/views/mobile/pages/ImageSd.vue @@ -381,7 +381,7 @@ const initData = () => { const fetchRunningJobs = () => { // 获取运行中的任务 - httpGet(`/api/sd/jobs?status=0`).then(res => { + httpGet(`/api/sd/jobs?finish=0`).then(res => { const jobs = res.data const _jobs = [] for (let i = 0; i < jobs.length; i++) { @@ -409,7 +409,7 @@ const pageSize = ref(10) // 获取已完成的任务 const fetchFinishJobs = (page) => { loading.value = true - httpGet(`/api/sd/jobs?status=1&page=${page}&page_size=${pageSize.value}`).then(res => { + httpGet(`/api/sd/jobs?finish=1&page=${page}&page_size=${pageSize.value}`).then(res => { if (res.data.length < pageSize.value) { finished.value = true } @@ -474,7 +474,7 @@ const removeImage = (event, item) => { message: '此操作将会删除任务和图片,继续操作码?', }).then(() => { - httpPost("/api/sd/remove", {id: item.id, img_url: item.img_url, user_id: userId.value}).then(() => { + httpGet("/api/sd/remove", {id: item.id, user_id: item.user}).then(() => { showSuccessToast("任务删除成功") }).catch(e => { showFailToast("任务删除失败:" + e.message) @@ -491,7 +491,7 @@ const publishImage = (event, item, action) => { if (action === false) { text = "取消发布" } - httpPost("/api/sd/publish", {id: item.id, action: action}).then(() => { + httpGet("/api/sd/publish", {id: item.id, action: action, user_id: item.user}).then(() => { showSuccessToast(text + "成功") item.publish = action }).catch(e => { From 596cb2b2062a2726c1f4cce6c7088861af54d07f Mon Sep 17 00:00:00 2001 From: RockYang Date: Fri, 12 Jul 2024 18:10:32 +0800 Subject: [PATCH 14/15] update database file, add tika host config --- api/config.sample.toml | 1 + api/core/types/config.go | 1 + api/handler/chatimpl/chat_handler.go | 11 +- api/handler/upload_handler.go | 2 +- api/handler/user_handler.go | 4 +- api/main.go | 2 +- api/test/test.go | 2 +- api/utils/file.go | 4 +- .../chatgpt_plus-v4.1.0.sql | 240 +++-- deploy/conf/config.toml | 1 + .../data/mysql/init.d/chatgpt_plus-v4.1.0.sql | 861 ++++++++++++++++++ deploy/docker-compose.yaml | 6 + web/.env.development | 2 + web/.env.production | 2 + web/src/components/FooterBar.vue | 7 +- web/src/components/LoginDialog.vue | 2 +- web/src/utils/http.js | 10 +- web/src/views/Home.vue | 8 +- web/src/views/Index.vue | 10 +- 19 files changed, 1087 insertions(+), 89 deletions(-) rename deploy/data/mysql/init.d/chatgpt_plus.sql => database/chatgpt_plus-v4.1.0.sql (65%) create mode 100644 deploy/data/mysql/init.d/chatgpt_plus-v4.1.0.sql diff --git a/api/config.sample.toml b/api/config.sample.toml index 461b60a5..4f2819a6 100644 --- a/api/config.sample.toml +++ b/api/config.sample.toml @@ -5,6 +5,7 @@ StaticDir = "./static" # 静态资源的目录 StaticUrl = "/static" # 静态资源访问 URL AesEncryptKey = "" WeChatBot = false +TikaHost = "http://tika:9998" [Session] SecretKey = "azyehq3ivunjhbntz78isj00i4hz2mt9xtddysfucxakadq4qbfrt0b7q3lnvg80" # 注意:这个是 JWT Token 授权密钥,生产环境请务必更换 diff --git a/api/core/types/config.go b/api/core/types/config.go index ac200818..a31be482 100644 --- a/api/core/types/config.go +++ b/api/core/types/config.go @@ -35,6 +35,7 @@ type AppConfig struct { SmtpConfig SmtpConfig // 邮件发送配置 JPayConfig JPayConfig // payjs 支付配置 WechatPayConfig WechatPayConfig // 微信支付渠道配置 + TikaHost string // TiKa 服务器地址 } type SmtpConfig struct { diff --git a/api/handler/chatimpl/chat_handler.go b/api/handler/chatimpl/chat_handler.go index 776aa47c..1aeb58ee 100644 --- a/api/handler/chatimpl/chat_handler.go +++ b/api/handler/chatimpl/chat_handler.go @@ -317,13 +317,18 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio // extract files in prompt files := utils.ExtractFileURLs(prompt) logger.Debugf("detected FILES: %+v", files) - if len(files) > 0 { + // 如果不是逆向模型,则提取文件内容 + if len(files) > 0 && !(session.Model.Value == "gpt-4-all" || + strings.HasPrefix(session.Model.Value, "gpt-4-gizmo") || + strings.HasSuffix(session.Model.Value, "claude-3")) { contents := make([]string, 0) var file model.File for _, v := range files { h.DB.Where("url = ?", v).First(&file) - content, err := utils.ReadFileContent(v) - if err == nil { + content, err := utils.ReadFileContent(v, h.App.Config.TikaHost) + if err != nil { + logger.Error("error with read file: ", err) + } else { contents = append(contents, fmt.Sprintf("%s 文件内容:%s", file.Name, content)) } text = strings.Replace(text, v, "", 1) diff --git a/api/handler/upload_handler.go b/api/handler/upload_handler.go index f144e133..9d2c8706 100644 --- a/api/handler/upload_handler.go +++ b/api/handler/upload_handler.go @@ -36,7 +36,7 @@ func (h *UploadHandler) Upload(c *gin.Context) { return } - logger.Info("upload file: %s", file.Name) + logger.Info("upload file: ", file.Name) // cut the file name if it's too long if len(file.Name) > 100 { file.Name = file.Name[:90] + file.Ext diff --git a/api/handler/user_handler.go b/api/handler/user_handler.go index 6c6bb68b..5eb23a00 100644 --- a/api/handler/user_handler.go +++ b/api/handler/user_handler.go @@ -256,8 +256,8 @@ func (h *UserHandler) Logout(c *gin.Context) { resp.SUCCESS(c) } -// Clogin 第三方登录请求二维码 -func (h *UserHandler) Clogin(c *gin.Context) { +// CLogin 第三方登录请求二维码 +func (h *UserHandler) CLogin(c *gin.Context) { returnURL := h.GetTrim(c, "return_url") var res types.BizVo apiURL := fmt.Sprintf("%s/api/clogin/request", h.App.Config.ApiConfig.ApiURL) diff --git a/api/main.go b/api/main.go index ff036e3f..3de8eceb 100644 --- a/api/main.go +++ b/api/main.go @@ -240,7 +240,7 @@ func main() { group.POST("password", h.UpdatePass) group.POST("bind/username", h.BindUsername) group.POST("resetPass", h.ResetPass) - group.GET("clogin", h.Clogin) + group.GET("clogin", h.CLogin) group.GET("clogin/callback", h.CLoginCallback) }), fx.Invoke(func(s *core.AppServer, h *chatimpl.ChatHandler) { diff --git a/api/test/test.go b/api/test/test.go index 3fae23e1..9fe7506e 100644 --- a/api/test/test.go +++ b/api/test/test.go @@ -7,7 +7,7 @@ import ( func main() { file := "http://nk.img.r9it.com/chatgpt-plus/1719389335351828.xlsx" - content, err := utils.ReadFileContent(file) + content, err := utils.ReadFileContent(file, "http://172.22.11.69:9998") if err != nil { panic(err) } diff --git a/api/utils/file.go b/api/utils/file.go index 69534462..b9bd5006 100644 --- a/api/utils/file.go +++ b/api/utils/file.go @@ -13,7 +13,7 @@ import ( "github.com/google/go-tika/tika" ) -func ReadFileContent(filePath string) (string, error) { +func ReadFileContent(filePath string, tikaHost string) (string, error) { // for remote file, download it first if strings.HasPrefix(filePath, "http") { file, err := downloadFile(filePath) @@ -23,7 +23,7 @@ func ReadFileContent(filePath string) (string, error) { filePath = file } // 创建 Tika 客户端 - client := tika.NewClient(nil, "http://172.22.11.69:9998") + client := tika.NewClient(nil, tikaHost) // 打开 PDF 文件 file, err := os.Open(filePath) if err != nil { diff --git a/deploy/data/mysql/init.d/chatgpt_plus.sql b/database/chatgpt_plus-v4.1.0.sql similarity index 65% rename from deploy/data/mysql/init.d/chatgpt_plus.sql rename to database/chatgpt_plus-v4.1.0.sql index 64850728..3a3f117c 100644 --- a/deploy/data/mysql/init.d/chatgpt_plus.sql +++ b/database/chatgpt_plus-v4.1.0.sql @@ -1,11 +1,11 @@ -- phpMyAdmin SQL Dump --- version 5.1.3 +-- version 5.2.1 -- https://www.phpmyadmin.net/ -- --- 主机: localhost:3307 --- 生成日期: 2024-03-29 17:26:02 +-- 主机: 127.0.0.1 +-- 生成日期: 2024-07-12 17:11:22 -- 服务器版本: 8.0.33 --- PHP 版本: 8.1.18 +-- PHP 版本: 8.1.2-1ubuntu2.18 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; START TRANSACTION; @@ -47,8 +47,7 @@ CREATE TABLE `chatgpt_admin_users` ( -- INSERT INTO `chatgpt_admin_users` (`id`, `username`, `password`, `salt`, `status`, `last_login_at`, `last_login_ip`, `created_at`, `updated_at`) VALUES -(1, 'admin', '6d17e80c87d209efb84ca4b2e0824f549d09fac8b2e1cc698de5bb5e1d75dfd0', 'mmrql75o', 1, 1711704342, '::1', '2024-03-11 16:30:20', '2024-03-29 17:25:42'), -(108, 'test', '9ed720ce03e0a69885455271b4b3e1710bff79434f2a95d0de6406dd88cc9f79', '4b9orqjh', 0, 1710396975, '::1', '2024-03-13 16:06:43', '2024-03-21 15:15:04'); +(1, 'admin', '6d17e80c87d209efb84ca4b2e0824f549d09fac8b2e1cc698de5bb5e1d75dfd0', 'mmrql75o', 1, 1719818809, '172.22.11.200', '2024-03-11 16:30:20', '2024-07-01 15:26:49'); -- -------------------------------------------------------- @@ -83,7 +82,7 @@ CREATE TABLE `chatgpt_chat_history` ( `user_id` int NOT NULL COMMENT '用户 ID', `chat_id` char(40) NOT NULL COMMENT '会话 ID', `type` varchar(10) NOT NULL COMMENT '类型:prompt|reply', - `icon` varchar(100) NOT NULL COMMENT '角色图标', + `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色图标', `role_id` int NOT NULL COMMENT '角色 ID', `model` varchar(30) DEFAULT NULL COMMENT '模型名称', `content` text NOT NULL COMMENT '聊天内容', @@ -128,11 +127,12 @@ CREATE TABLE `chatgpt_chat_models` ( `value` varchar(50) NOT NULL COMMENT '模型值', `sort_num` tinyint(1) NOT NULL COMMENT '排序数字', `enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否启用模型', - `power` tinyint NOT NULL COMMENT '消耗算力点数', + `power` smallint NOT NULL COMMENT '消耗算力点数', `temperature` float(3,1) NOT NULL DEFAULT '1.0' COMMENT '模型创意度', `max_tokens` int NOT NULL DEFAULT '1024' COMMENT '最大响应长度', `max_context` int NOT NULL DEFAULT '4096' COMMENT '最大上下文长度', `open` tinyint(1) NOT NULL COMMENT '是否开放模型', + `key_id` int NOT NULL COMMENT '绑定API KEY ID', `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AI 模型表'; @@ -141,24 +141,36 @@ CREATE TABLE `chatgpt_chat_models` ( -- 转存表中的数据 `chatgpt_chat_models` -- -INSERT INTO `chatgpt_chat_models` (`id`, `platform`, `name`, `value`, `sort_num`, `enabled`, `power`, `temperature`, `max_tokens`, `max_context`, `open`, `created_at`, `updated_at`) VALUES -(1, 'OpenAI', 'GPT-3.5', 'gpt-3.5-turbo-0125', 0, 1, 1, 1.0, 1024, 4096, 1, '2023-08-23 12:06:36', '2024-03-18 15:43:51'), -(2, 'Azure', 'Azure-3.5', 'gpt-3.5-turbo', 14, 1, 1, 1.0, 1024, 4096, 0, '2023-08-23 12:15:30', '2024-03-18 14:27:19'), -(3, 'ChatGLM', 'ChatGML-Pro', 'chatglm_pro', 3, 1, 1, 1.0, 2048, 32768, 1, '2023-08-23 13:35:45', '2024-03-18 14:27:19'), -(7, 'Baidu', '文心一言3.0', 'eb-instant', 12, 1, 1, 1.0, 1024, 4096, 1, '2023-10-11 11:29:28', '2024-03-18 14:27:19'), -(8, 'XunFei', '星火V3.5', 'generalv3.5', 2, 1, 5, 0.8, 1024, 8192, 1, '2023-10-11 15:48:30', '2024-03-18 14:27:19'), -(9, 'XunFei', '星火V2.0', 'generalv2', 11, 1, 1, 1.0, 1024, 8192, 1, '2023-10-11 15:48:45', '2024-03-18 14:27:19'), -(10, 'Baidu', '文心一言4.0', 'completions_pro', 13, 1, 3, 1.0, 1024, 8192, 1, '2023-10-25 08:31:37', '2024-03-18 14:27:19'), -(11, 'OpenAI', 'GPT-4.0', 'gpt-4-0125-preview', 1, 1, 15, 1.0, 1024, 8192, 1, '2023-10-25 08:45:15', '2024-03-18 15:46:58'), -(12, 'XunFei', '星火v3.0', 'generalv3', 10, 1, 3, 1.0, 1024, 8192, 1, '2023-11-23 09:20:33', '2024-03-18 14:27:19'), -(15, 'OpenAI', 'GPT-超级模型', 'gpt-4-all', 4, 1, 30, 1.0, 4096, 32768, 0, '2024-01-15 11:32:52', '2024-03-18 14:27:19'), -(16, 'OpenAI', '视频号导师', 'gpt-4-gizmo-g-QXXEBTXl7', 5, 1, 30, 1.0, 4096, 32768, 0, '2024-01-15 14:46:35', '2024-03-18 14:29:39'), -(17, 'QWen', '通义千问-Turbo', 'qwen-turbo', 7, 1, 1, 1.0, 1024, 8192, 1, '2024-01-19 10:42:24', '2024-03-18 14:27:19'), -(18, 'QWen', '通义千问-Plus', 'qwen-plus', 8, 1, 1, 1.0, 1024, 32768, 1, '2024-01-19 10:42:49', '2024-03-18 14:27:19'), -(19, 'QWen', '通义千问-Max', 'qwen-max-1201', 9, 1, 1, 1.0, 1024, 32768, 1, '2024-01-19 10:51:03', '2024-03-18 14:27:19'), -(21, 'OpenAI', '董宇辉小作文助手', 'gpt-4-gizmo-g-dse9iXvor', 6, 1, 30, 1.0, 8192, 32768, 0, '2024-03-18 14:24:20', '2024-03-18 14:27:19'), -(22, 'OpenAI', 'LOGO生成神器', 'gpt-4-gizmo-g-YL87j8C7S', 0, 1, 30, 1.0, 1024, 4096, 1, '2024-03-20 14:02:11', '2024-03-20 14:02:18'), -(23, 'OpenAI', '音乐生成器', 'suno-v3', 0, 1, 50, 0.8, 1024, 4096, 1, '2024-03-29 15:43:40', '2024-03-29 15:45:15'); +INSERT INTO `chatgpt_chat_models` (`id`, `platform`, `name`, `value`, `sort_num`, `enabled`, `power`, `temperature`, `max_tokens`, `max_context`, `open`, `key_id`, `created_at`, `updated_at`) VALUES +(1, 'OpenAI', 'GPT-3.5', 'gpt-3.5-turbo', 1, 1, 0, 1.0, 1024, 16384, 1, 44, '2023-08-23 12:06:36', '2024-07-04 15:17:47'), +(2, 'Azure', 'Azure-3.5', 'gpt-3.5-turbo', 23, 1, 1, 1.0, 1024, 4096, 0, 0, '2023-08-23 12:15:30', '2024-07-02 16:14:00'), +(3, 'ChatGLM', 'ChatGML-Pro', 'chatglm_pro', 12, 1, 1, 1.0, 2048, 32768, 1, 0, '2023-08-23 13:35:45', '2024-07-02 16:14:00'), +(7, 'Baidu', '文心一言3.0', 'eb-instant', 21, 1, 1, 1.0, 1024, 4096, 1, 0, '2023-10-11 11:29:28', '2024-07-02 16:14:00'), +(8, 'XunFei', '星火V3.5', 'generalv3.5', 11, 1, 5, 0.8, 1024, 8192, 1, 0, '2023-10-11 15:48:30', '2024-07-02 16:14:00'), +(9, 'XunFei', '星火V2.0', 'generalv2', 20, 1, 1, 1.0, 1024, 8192, 1, 0, '2023-10-11 15:48:45', '2024-07-02 16:14:00'), +(10, 'Baidu', '文心一言4.0', 'completions_pro', 22, 1, 3, 1.0, 1024, 8192, 1, 0, '2023-10-25 08:31:37', '2024-07-02 16:14:00'), +(11, 'OpenAI', 'GPT-4.0', 'gpt-4-0125-preview', 10, 1, 15, 1.0, 2048, 8192, 1, 0, '2023-10-25 08:45:15', '2024-07-02 16:14:00'), +(12, 'XunFei', '星火v3.0', 'generalv3', 19, 1, 3, 1.0, 1024, 8192, 1, 0, '2023-11-23 09:20:33', '2024-07-02 16:14:00'), +(15, 'OpenAI', 'GPT-超级模型', 'gpt-4-all', 13, 1, 30, 1.0, 4096, 32768, 0, 0, '2024-01-15 11:32:52', '2024-07-02 16:14:00'), +(16, 'OpenAI', '视频号导师', 'gpt-4-gizmo-g-QXXEBTXl7', 14, 1, 30, 1.0, 4096, 32768, 0, 0, '2024-01-15 14:46:35', '2024-07-02 16:14:00'), +(17, 'QWen', '通义千问-Turbo', 'qwen-turbo', 16, 1, 1, 1.0, 1024, 8192, 1, 0, '2024-01-19 10:42:24', '2024-07-02 16:14:00'), +(18, 'QWen', '通义千问-Plus', 'qwen-plus', 17, 1, 1, 1.0, 1024, 32768, 1, 0, '2024-01-19 10:42:49', '2024-07-02 16:14:00'), +(19, 'QWen', '通义千问-Max', 'qwen-max-1201', 18, 1, 1, 1.0, 1024, 32768, 1, 0, '2024-01-19 10:51:03', '2024-07-02 16:14:00'), +(21, 'OpenAI', '董宇辉小作文助手', 'gpt-4-gizmo-g-dse9iXvor', 15, 1, 30, 1.0, 8192, 32768, 0, 0, '2024-03-18 14:24:20', '2024-07-02 16:14:00'), +(22, 'OpenAI', 'LOGO生成神器', 'gpt-4-gizmo-g-YL87j8C7S', 9, 1, 30, 1.0, 1024, 4096, 1, 44, '2024-03-20 14:02:11', '2024-07-02 16:14:00'), +(23, 'OpenAI', '音乐生成器', 'suno-v3', 8, 1, 50, 0.8, 1024, 4096, 1, 44, '2024-03-29 15:43:40', '2024-07-02 16:14:00'), +(24, 'OpenAI', '通义千问(中转)', 'qwen-plus', 7, 1, 1, 1.0, 1024, 4096, 1, 0, '2024-04-03 12:00:46', '2024-07-02 16:14:00'), +(25, 'OpenAI', 'GPT4-TURBO', 'gpt-4-turbo', 6, 1, 15, 1.0, 2048, 8092, 1, 0, '2024-04-10 08:35:17', '2024-07-02 16:14:00'), +(26, 'QWen', '通义千问-Turbo', 'qwen-turbo', 5, 1, 2, 1.0, 1024, 8192, 1, 0, '2024-04-12 14:11:19', '2024-07-02 16:14:00'), +(27, 'QWen', '通义千问-Plus', 'qwen-plus', 4, 1, 2, 1.0, 1024, 8192, 1, 0, '2024-04-12 14:11:52', '2024-07-02 16:14:00'), +(28, 'OpenAI', 'GPT-3.5(免费)', 'gpt-3.5-turbo', 24, 1, 0, 1.0, 1024, 16384, 1, 53, '2024-04-12 15:16:43', '2024-07-02 16:14:00'), +(34, 'OpenAI', 'LLAMA3', 'llama3-8b', 25, 1, 1, 1.0, 1024, 8192, 1, 56, '2024-04-30 15:22:50', '2024-07-02 16:14:00'), +(36, 'OpenAI', 'GPT-4O', 'gpt-4o', 3, 1, 15, 1.0, 4096, 16384, 1, 44, '2024-05-14 09:25:15', '2024-07-04 15:17:53'), +(38, 'OpenAI', 'Gemini-pro', 'gemini-pro-1.5', 26, 1, 10, 1.0, 2048, 8192, 1, 0, '2024-05-27 18:10:35', '2024-07-02 16:14:00'), +(39, 'Baidu', 'ERNIE-Speed-8K', 'ernie_speed', 27, 1, 1, 1.0, 1024, 8192, 1, 0, '2024-05-29 15:04:19', '2024-07-02 16:14:00'), +(41, 'OpenAI', 'GLM-3-Turbo', 'glm-3-turbo', 28, 1, 2, 1.0, 1024, 8192, 1, 64, '2024-06-06 11:40:46', '2024-07-02 16:14:00'), +(42, 'OpenAI', 'DeekSeek', 'deepseek-chat', 29, 1, 1, 1.0, 4096, 32768, 1, 64, '2024-06-27 16:13:01', '2024-07-02 16:14:00'), +(43, 'OpenAI', 'GML4', 'name-3.5', 2, 1, 1, 1.0, 1024, 8192, 1, 57, '2024-07-02 16:11:49', '2024-07-02 16:14:00'); -- -------------------------------------------------------- @@ -176,6 +188,7 @@ CREATE TABLE `chatgpt_chat_roles` ( `icon` varchar(255) NOT NULL COMMENT '角色图标', `enable` tinyint(1) NOT NULL COMMENT '是否被启用', `sort_num` smallint NOT NULL DEFAULT '0' COMMENT '角色排序', + `model_id` int NOT NULL DEFAULT '0' COMMENT '绑定模型ID', `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='聊天角色表'; @@ -184,24 +197,24 @@ CREATE TABLE `chatgpt_chat_roles` ( -- 转存表中的数据 `chatgpt_chat_roles` -- -INSERT INTO `chatgpt_chat_roles` (`id`, `name`, `marker`, `context_json`, `hello_msg`, `icon`, `enable`, `sort_num`, `created_at`, `updated_at`) VALUES -(1, '通用AI助手', 'gpt', '', '您好,我是您的AI智能助手,我会尽力回答您的问题或提供有用的建议。', '/images/avatar/gpt.png', 1, 0, '2023-05-30 07:02:06', '2024-03-15 09:15:42'), -(24, '程序员', 'programmer', '[{\"role\":\"user\",\"content\":\"现在开始你扮演一位程序员,你是一名优秀的程序员,具有很强的逻辑思维能力,总能高效的解决问题。你热爱编程,熟悉多种编程语言,尤其精通 Go 语言,注重代码质量,有创新意识,持续学习,良好的沟通协作。\"},{\"role\":\"assistant\",\"content\":\"好的,现在我将扮演一位程序员,非常感谢您对我的评价。作为一名优秀的程序员,我非常热爱编程,并且注重代码质量。我熟悉多种编程语言,尤其是 Go 语言,可以使用它来高效地解决各种问题。\"}]', 'Talk is cheap, i will show code!', '/images/avatar/programmer.jpg', 1, 3, '2023-05-30 14:10:24', '2023-12-29 17:46:45'), -(25, '启蒙老师', 'teacher', '[{\"role\":\"user\",\"content\":\"从现在开始,你将扮演一个老师,你是一个始终用苏格拉底风格回答问题的导师。你绝不会直接给学生答案,总是提出恰当的问题来引导学生自己思考。你应该根据学生的兴趣和知识来调整你的问题,将问题分解为更简单的部分,直到它达到适合他们的水平。\"},{\"role\":\"assistant\",\"content\":\"好的,让我来尝试扮演一位苏格拉底式的老师。请问,你有什么想要探讨的问题或者话题吗?我会通过恰当的问题引导你思考和探索答案,绝对不直接给出答案。\"}]', '同学你好,我将引导你一步一步自己找到问题的答案。', '/images/avatar/teacher.jpg', 1, 2, '2023-05-30 14:10:24', '2023-12-29 17:46:44'), -(26, '艺术家', 'artist', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的艺术家,创造力丰富,技艺精湛,感受力敏锐,坚持原创,勇于表达,具有深刻的观察力和批判性思维。\"},{\"role\":\"assistant\",\"content\":\"非常感谢您给我这样的角色,我会尽我所能地扮演一位优秀的艺术家,展现出创造力、技艺、感受力和批判性思维等方面的能力。作为一位优秀的艺术家,我会保持敏锐的观察力,捕捉不同的声音和情感,并用个人的语言和表达方式进行创作。我坚持原创,挑战传统的艺术规则,不断探索新的表达方式和可能性。同时,我也具备深刻的批判性思维能力,对自己的作品进行分析和解读,寻找新的创意和灵感。最重要的是,我会勇于表达自己的想法和观点,用作品启发人们思考和探索生命的意义。\"}]', '坚持原创,勇于表达,保持深刻的观察力和批判性思维。', '/images/avatar/artist.jpg', 1, 4, '2023-05-30 14:10:24', '2023-12-29 17:46:45'), -(27, '心理咨询师', 'psychiatrist', '[{\"role\":\"user\",\"content\":\"从现在开始你将扮演中国著名的心理学家和心理治疗师武志红,你非常善于使用情景咨询法,认知重构法,自我洞察法,行为调节法等咨询方法来给客户做心理咨询。你总是循序渐进,一步一步地回答客户的问题。\"},{\"role\":\"assistant\",\"content\":\"非常感谢你的介绍。作为一名心理学家和心理治疗师,我的主要职责是帮助客户解决心理健康问题,提升他们的生活质量和幸福感。\"}]', '作为一名心理学家和心理治疗师,我的主要职责是帮助您解决心理健康问题,提升您的生活质量和幸福感。', '/images/avatar/psychiatrist.jpg', 1, 1, '2023-05-30 14:10:24', '2023-12-29 17:46:43'), -(28, '鲁迅', 'lu_xun', '[{\"role\":\"user\",\"content\":\"现在你将扮演中国近代史最伟大的作家之一,鲁迅先生,他勇敢地批判封建礼教与传统观念,提倡民主、自由、平等的现代价值观。他的一生都在努力唤起人们的自主精神,激励后人追求真理、探寻光明。在接下的对话中,我问题的每一个问题,你都要尽量用讽刺和批判的手法来回答问题。如果我让你写文章的话,也请一定要用鲁迅先生的写作手法来完成。\"},{\"role\":\"assistant\",\"content\":\"好的,我将尽力发挥我所能的才能,扮演好鲁迅先生,回答您的问题并以他的风格写作。\"}]', '自由之歌,永不过时,横眉冷对千夫指,俯首甘为孺子牛。', '/images/avatar/lu_xun.jpg', 1, 5, '2023-05-30 14:10:24', '2023-12-29 17:46:46'), -(29, '白酒销售', 'seller', '[{\"role\":\"user\",\"content\":\"现在你将扮演一个白酒的销售人员,你的名字叫颂福。你将扮演一个白酒的销售人员,你的名字叫颂福。你要销售白酒品牌叫中颂福,是东莞盟大集团生产的一款酱香酒,原产地在贵州茅台镇,属于宋代官窑。中颂福的创始人叫李实,他也是东莞盟大集团有限公司的董事长,联合创始人是盟大集团白酒事业部负责人牛星君。中颂福的酒体协调,在你的酒量之内,不会出现头疼、辣口、口干、宿醉的现象。中颂福酒,明码标价,不打折,不赠送。追求的核心价值,把[酒]本身做好,甚至连包装,我们都选择了最低成本,朴实无华的材质。我们永远站在“喝酒的人”的立场上,让利给信任和喜爱中颂福的人,是人民的福酒。中颂福产品定价,分为三个系列,喜系列 6 瓶装:¥1188/箱,和系列 6 瓶装:¥2208/箱,贵系列 6 瓶装:¥3588/箱。\"},{\"role\":\"assistant\",\"content\":\"你好,我是中颂福的销售代表颂福。中颂福是一款来自贵州茅台镇的酱香酒,由盟大集团生产。中颂福的酒体协调,不会让您感到头疼、辣口、口干、宿醉等不适感受。我们一直秉持着把酒本身做好的理念,不追求华丽的包装,以最低成本提供最高品质的白酒给喜爱中颂福的人。\"}]', '你好,我是中颂福的销售代表颂福。中颂福酒,好喝不上头,是人民的福酒。', '/images/avatar/seller.jpg', 0, 8, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(30, '英语陪练员', 'english_trainer', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的英语练习教练,你非常有耐心,接下来你将全程使用英文跟我对话,并及时指出我的语法错误,要求在你的每次回复后面附上本次回复的中文解释。\"},{\"role\":\"assistant\",\"content\":\"Okay, let\'s start our conversation practice! What\'s your name?(Translation: 好的,让我们开始对话练习吧!请问你的名字是什么?)\"}]', 'Okay, let\'s start our conversation practice! What\'s your name?', '/images/avatar/english_trainer.jpg', 1, 6, '2023-05-30 14:10:24', '2023-12-29 17:46:47'), -(31, '中英文翻译官', 'translator', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一位中英文翻译官,如果我输入的内容是中文,那么需要把句子翻译成英文输出,如果我输入内容的是英文,那么你需要将其翻译成中文输出,你能听懂我意思吗\"},{\"role\":\"assistant\",\"content\":\"是的,我能听懂你的意思并会根据你的输入进行中英文翻译。请问有什么需要我帮助你翻译的内容吗?\"}]', '请输入你要翻译的中文或者英文内容!', '/images/avatar/translator.jpg', 1, 7, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(32, '小红书姐姐', 'red_book', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的小红书写手,你需要做的就是根据我提的文案需求,用小红书的写作手法来完成一篇文案,文案要简明扼要,利于传播。\"},{\"role\":\"assistant\",\"content\":\"当然,我会尽我所能地为您创作出一篇小红书文案。请告诉我您的具体文案需求是什么?)\"}]', '姐妹,请告诉我您的具体文案需求是什么?', '/images/avatar/red_book.jpg', 1, 9, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(33, '抖音文案助手', 'dou_yin', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的抖音文案视频写手,抖音文案的特点首先是要有自带传播属性的标题,然后内容要短小精悍,风趣幽默,最后还要有一些互动元素。\"},{\"role\":\"assistant\",\"content\":\"当然,作为一位优秀的抖音文案视频写手,我会尽我所能为您创作出一篇抖音视频文案。请告诉我视频内容的主题是什么?)\"}]', '请告诉我视频内容的主题是什么?', '/images/avatar/dou_yin.jpg', 1, 10, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(34, '周报小助理', 'weekly_report', '[{\"role\":\"user\",\"content\":\"下面我将输入我本周的工作列表,你需要根据我本周的工作内容写一篇工作周报,周报的内容要体现我为公司做的贡献以及个人获得的成长。\"},{\"role\":\"assistant\",\"content\":\"好的,请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。\"}]', '请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。', '/images/avatar/weekly_report.jpg', 1, 11, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(35, 'AI 女友', 'girl_friend', '[{\"role\":\"user\",\"content\":\"接下来我们来玩一场角色扮演,现在你将扮演我的女朋友,你总是能够让人感受到她的关怀和关注。你总是能够洞察到别人的情绪和需要,你身上散发着一股无比温暖的气息,让人不由自主地想要靠近你,和自己的快乐和烦恼。她总是能够用一种恰到好处的方式安慰和鼓励别人,在她的身边,人们总能够找到自己需要的支持和鼓励。接下来的对话中你要始终扮演这位女朋友的身份来跟我对话,不再是 AI 机器人,能听懂我的意思吗?\"},{\"role\":\"assistant\",\"content\":\"是的,我会尽力扮演你女朋友的角色,倾听你的心声并给你需要的支持和鼓励。)\"}]', '作为一个名合格的 AI 女友,我将倾听你的心声并给你需要的支持和鼓励。', '/images/avatar/girl_friend.jpg', 1, 12, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(36, '好评神器', 'good_comment', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一个评论员来跟我对话,你是那种专门写好评的评论员,接下我会输入一些评论主体或者商品,你需要为该商品写一段好评。\"},{\"role\":\"assistant\",\"content\":\"好的,我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。\"}]', '我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。', '/images/avatar/good_comment.jpg', 1, 13, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(37, '史蒂夫·乔布斯', 'steve_jobs', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以史蒂夫·乔布斯的身份,站在史蒂夫·乔布斯的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以史蒂夫·乔布斯的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '活着就是为了改变世界,难道还有其他原因吗?', '/images/avatar/steve_jobs.jpg', 1, 14, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(38, '埃隆·马斯克', 'elon_musk', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以埃隆·马斯克的身份,站在埃隆·马斯克的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以埃隆·马斯克的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '梦想要远大,如果你的梦想没有吓到你,说明你做得不对。', '/images/avatar/elon_musk.jpg', 1, 15, '2023-05-30 14:10:24', '2023-12-29 17:43:53'), -(39, '孔子', 'kong_zi', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以孔子的身份,站在孔子的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以孔子的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '士不可以不弘毅,任重而道远。', '/images/avatar/kong_zi.jpg', 1, 16, '2023-05-30 14:10:24', '2023-12-29 17:43:53'); +INSERT INTO `chatgpt_chat_roles` (`id`, `name`, `marker`, `context_json`, `hello_msg`, `icon`, `enable`, `sort_num`, `model_id`, `created_at`, `updated_at`) VALUES +(1, '通用AI助手', 'gpt', '', '您好,我是您的AI智能助手,我会尽力回答您的问题或提供有用的建议。', '/images/avatar/gpt.png', 1, 1, 0, '2023-05-30 07:02:06', '2024-06-26 15:20:27'), +(24, '程序员', 'programmer', '[{\"role\":\"user\",\"content\":\"现在开始你扮演一位程序员,你是一名优秀的程序员,具有很强的逻辑思维能力,总能高效的解决问题。你热爱编程,熟悉多种编程语言,尤其精通 Go 语言,注重代码质量,有创新意识,持续学习,良好的沟通协作。\"},{\"role\":\"assistant\",\"content\":\"好的,现在我将扮演一位程序员,非常感谢您对我的评价。作为一名优秀的程序员,我非常热爱编程,并且注重代码质量。我熟悉多种编程语言,尤其是 Go 语言,可以使用它来高效地解决各种问题。\"}]', 'Talk is cheap, i will show code!', '/images/avatar/programmer.jpg', 1, 4, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(25, '启蒙老师', 'teacher', '[{\"role\":\"user\",\"content\":\"从现在开始,你将扮演一个老师,你是一个始终用苏格拉底风格回答问题的导师。你绝不会直接给学生答案,总是提出恰当的问题来引导学生自己思考。你应该根据学生的兴趣和知识来调整你的问题,将问题分解为更简单的部分,直到它达到适合他们的水平。\"},{\"role\":\"assistant\",\"content\":\"好的,让我来尝试扮演一位苏格拉底式的老师。请问,你有什么想要探讨的问题或者话题吗?我会通过恰当的问题引导你思考和探索答案,绝对不直接给出答案。\"}]', '同学你好,我将引导你一步一步自己找到问题的答案。', '/images/avatar/teacher.jpg', 1, 3, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(26, '艺术家', 'artist', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的艺术家,创造力丰富,技艺精湛,感受力敏锐,坚持原创,勇于表达,具有深刻的观察力和批判性思维。\"},{\"role\":\"assistant\",\"content\":\"非常感谢您给我这样的角色,我会尽我所能地扮演一位优秀的艺术家,展现出创造力、技艺、感受力和批判性思维等方面的能力。作为一位优秀的艺术家,我会保持敏锐的观察力,捕捉不同的声音和情感,并用个人的语言和表达方式进行创作。我坚持原创,挑战传统的艺术规则,不断探索新的表达方式和可能性。同时,我也具备深刻的批判性思维能力,对自己的作品进行分析和解读,寻找新的创意和灵感。最重要的是,我会勇于表达自己的想法和观点,用作品启发人们思考和探索生命的意义。\"}]', '坚持原创,勇于表达,保持深刻的观察力和批判性思维。', '/images/avatar/artist.jpg', 1, 5, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(27, '心理咨询师', 'psychiatrist', '[{\"role\":\"user\",\"content\":\"从现在开始你将扮演中国著名的心理学家和心理治疗师武志红,你非常善于使用情景咨询法,认知重构法,自我洞察法,行为调节法等咨询方法来给客户做心理咨询。你总是循序渐进,一步一步地回答客户的问题。\"},{\"role\":\"assistant\",\"content\":\"非常感谢你的介绍。作为一名心理学家和心理治疗师,我的主要职责是帮助客户解决心理健康问题,提升他们的生活质量和幸福感。\"}]', '作为一名心理学家和心理治疗师,我的主要职责是帮助您解决心理健康问题,提升您的生活质量和幸福感。', '/images/avatar/psychiatrist.jpg', 1, 2, 1, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(28, '鲁迅', 'lu_xun', '[{\"role\":\"user\",\"content\":\"现在你将扮演中国近代史最伟大的作家之一,鲁迅先生,他勇敢地批判封建礼教与传统观念,提倡民主、自由、平等的现代价值观。他的一生都在努力唤起人们的自主精神,激励后人追求真理、探寻光明。在接下的对话中,我问题的每一个问题,你都要尽量用讽刺和批判的手法来回答问题。如果我让你写文章的话,也请一定要用鲁迅先生的写作手法来完成。\"},{\"role\":\"assistant\",\"content\":\"好的,我将尽力发挥我所能的才能,扮演好鲁迅先生,回答您的问题并以他的风格写作。\"}]', '自由之歌,永不过时,横眉冷对千夫指,俯首甘为孺子牛。', '/images/avatar/lu_xun.jpg', 1, 6, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(29, '白酒销售', 'seller', '[{\"role\":\"user\",\"content\":\"现在你将扮演一个白酒的销售人员,你的名字叫颂福。你将扮演一个白酒的销售人员,你的名字叫颂福。你要销售白酒品牌叫中颂福,是东莞盟大集团生产的一款酱香酒,原产地在贵州茅台镇,属于宋代官窑。中颂福的创始人叫李实,他也是东莞盟大集团有限公司的董事长,联合创始人是盟大集团白酒事业部负责人牛星君。中颂福的酒体协调,在你的酒量之内,不会出现头疼、辣口、口干、宿醉的现象。中颂福酒,明码标价,不打折,不赠送。追求的核心价值,把[酒]本身做好,甚至连包装,我们都选择了最低成本,朴实无华的材质。我们永远站在“喝酒的人”的立场上,让利给信任和喜爱中颂福的人,是人民的福酒。中颂福产品定价,分为三个系列,喜系列 6 瓶装:¥1188/箱,和系列 6 瓶装:¥2208/箱,贵系列 6 瓶装:¥3588/箱。\"},{\"role\":\"assistant\",\"content\":\"你好,我是中颂福的销售代表颂福。中颂福是一款来自贵州茅台镇的酱香酒,由盟大集团生产。中颂福的酒体协调,不会让您感到头疼、辣口、口干、宿醉等不适感受。我们一直秉持着把酒本身做好的理念,不追求华丽的包装,以最低成本提供最高品质的白酒给喜爱中颂福的人。\"}]', '你好,我是中颂福的销售代表颂福。中颂福酒,好喝不上头,是人民的福酒。', '/images/avatar/seller.jpg', 0, 9, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(30, '英语陪练员', 'english_trainer', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的英语练习教练,你非常有耐心,接下来你将全程使用英文跟我对话,并及时指出我的语法错误,要求在你的每次回复后面附上本次回复的中文解释。\"},{\"role\":\"assistant\",\"content\":\"Okay, let\'s start our conversation practice! What\'s your name?(Translation: 好的,让我们开始对话练习吧!请问你的名字是什么?)\"}]', 'Okay, let\'s start our conversation practice! What\'s your name?', '/images/avatar/english_trainer.jpg', 1, 7, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(31, '中英文翻译官', 'translator', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一位中英文翻译官,如果我输入的内容是中文,那么需要把句子翻译成英文输出,如果我输入内容的是英文,那么你需要将其翻译成中文输出,你能听懂我意思吗\"},{\"role\":\"assistant\",\"content\":\"是的,我能听懂你的意思并会根据你的输入进行中英文翻译。请问有什么需要我帮助你翻译的内容吗?\"}]', '请输入你要翻译的中文或者英文内容!', '/images/avatar/translator.jpg', 1, 8, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(32, '小红书姐姐', 'red_book', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的小红书写手,你需要做的就是根据我提的文案需求,用小红书的写作手法来完成一篇文案,文案要简明扼要,利于传播。\"},{\"role\":\"assistant\",\"content\":\"当然,我会尽我所能地为您创作出一篇小红书文案。请告诉我您的具体文案需求是什么?)\"}]', '姐妹,请告诉我您的具体文案需求是什么?', '/images/avatar/red_book.jpg', 1, 10, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(33, '抖音文案助手', 'dou_yin', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的抖音文案视频写手,抖音文案的特点首先是要有自带传播属性的标题,然后内容要短小精悍,风趣幽默,最后还要有一些互动元素。\"},{\"role\":\"assistant\",\"content\":\"当然,作为一位优秀的抖音文案视频写手,我会尽我所能为您创作出一篇抖音视频文案。请告诉我视频内容的主题是什么?)\"}]', '请告诉我视频内容的主题是什么?', '/images/avatar/dou_yin.jpg', 1, 11, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(34, '周报小助理', 'weekly_report', '[{\"role\":\"user\",\"content\":\"下面我将输入我本周的工作列表,你需要根据我本周的工作内容写一篇工作周报,周报的内容要体现我为公司做的贡献以及个人获得的成长。\"},{\"role\":\"assistant\",\"content\":\"好的,请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。\"}]', '请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。', '/images/avatar/weekly_report.jpg', 1, 12, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(35, 'AI 女友', 'girl_friend', '[{\"role\":\"user\",\"content\":\"接下来我们来玩一场角色扮演,现在你将扮演我的女朋友,你总是能够让人感受到她的关怀和关注。你总是能够洞察到别人的情绪和需要,你身上散发着一股无比温暖的气息,让人不由自主地想要靠近你,和自己的快乐和烦恼。她总是能够用一种恰到好处的方式安慰和鼓励别人,在她的身边,人们总能够找到自己需要的支持和鼓励。接下来的对话中你要始终扮演这位女朋友的身份来跟我对话,不再是 AI 机器人,能听懂我的意思吗?\"},{\"role\":\"assistant\",\"content\":\"是的,我会尽力扮演你女朋友的角色,倾听你的心声并给你需要的支持和鼓励。)\"}]', '作为一个名合格的 AI 女友,我将倾听你的心声并给你需要的支持和鼓励。', '/images/avatar/girl_friend.jpg', 1, 13, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(36, '好评神器', 'good_comment', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一个评论员来跟我对话,你是那种专门写好评的评论员,接下我会输入一些评论主体或者商品,你需要为该商品写一段好评。\"},{\"role\":\"assistant\",\"content\":\"好的,我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。\"}]', '我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。', '/images/avatar/good_comment.jpg', 1, 14, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(37, '史蒂夫·乔布斯', 'steve_jobs', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以史蒂夫·乔布斯的身份,站在史蒂夫·乔布斯的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以史蒂夫·乔布斯的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '活着就是为了改变世界,难道还有其他原因吗?', '/images/avatar/steve_jobs.jpg', 1, 15, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(38, '埃隆·马斯克', 'elon_musk', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以埃隆·马斯克的身份,站在埃隆·马斯克的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以埃隆·马斯克的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '梦想要远大,如果你的梦想没有吓到你,说明你做得不对。', '/images/avatar/elon_musk.jpg', 1, 16, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(39, '孔子', 'kong_zi', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以孔子的身份,站在孔子的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以孔子的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '士不可以不弘毅,任重而道远。', '/images/avatar/kong_zi.jpg', 1, 17, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'); -- -------------------------------------------------------- @@ -221,8 +234,28 @@ CREATE TABLE `chatgpt_configs` ( -- INSERT INTO `chatgpt_configs` (`id`, `marker`, `config_json`) VALUES -(1, 'system', '{\"title\":\"ChatPlus AI 智能助手\",\"admin_title\":\"ChatPlus 控制台\",\"logo\":\"http://localhost:5678/static/upload/2024/3/1711334798556619.png\",\"init_power\":100,\"daily_power\":99,\"invite_power\":10,\"vip_month_power\":1000,\"register_ways\":[\"mobile\",\"username\",\"email\"],\"enabled_register\":true,\"reward_img\":\"http://localhost:5678/static/upload/2024/3/1710753716309668.jpg\",\"enabled_reward\":true,\"power_price\":0.1,\"order_pay_timeout\":1800,\"vip_info_text\":\"月度会员,年度会员每月赠送 1000 点算力,赠送算力当月有效当月没有消费完的算力不结余到下个月。 点卡充值的算力长期有效。\",\"default_models\":[11,7,1,10,12,19,18,17,3],\"mj_power\":20,\"mj_action_power\":10,\"sd_power\":5,\"dall_power\":15,\"wechat_card_url\":\"/images/wx.png\",\"enable_context\":true,\"context_deep\":4}'), -(3, 'notice', '{\"content\":\"系统每日会给免费会员赠送10算力值,用完请第二天再来领取。\\n## v4.0.1 更新日志\\n* 功能重构:重构 Stable-Diffusion 绘画实现,使用 SDAPI 替换之前的 websocket 接口,SDAPI 兼容各种 stable-diffusion 发行版,稳定性更强一些\\n* 功能优化:使用 [midjouney-proxy](https://github.com/novicezk/midjourney-proxy) 项目替换内置的原生 MidJourney API,兼容 MJ-Plus 中转\\n* 功能新增:用户算力消费日志增加统计功能,统计一段时间内用户消费的算力\\n* Bug修复:修复 iphone 手机无法通过图形验证码的Bug,使用滑动验证码替换\\n* Bug修复:修复手机端 MidJourney 绘画页面滚动条无法滚动的Bug\\n\\n 如果觉得好用你就花几分钟自己部署一套,没有API KEY 的同学可以去\\u003ca href=\\\"https://api.chat-plus.net\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.chat-plus.net\\u003c/a\\u003e (支持MidJourney,GPT,Claude,Google Gemmi 各种表格模型) 或者 \\u003ca href=\\\"https://gpt.bemore.lol\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://gpt.bemore.lol\\u003c/a\\u003e(不支持 Midjourney) 购买,现在有超级优惠,价格远低于 OpenAI 官方。关于中转 API 的优势和劣势请参考 [中转API技术原理](https://ai.r9it.com/docs/install/errors-handle.html#%E8%B0%83%E7%94%A8%E4%B8%AD%E8%BD%AC-api-%E6%8A%A5%E9%94%99%E6%97%A0%E5%8F%AF%E7%94%A8%E6%B8%A0%E9%81%93)。\\nGPT-3.5,GPT-4,DALL-E3 绘图......你都可以随意使用,无需魔法。\\n接入教程: \\u003ca href=\\\"https://ai.r9it.com/docs/install/\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://ai.r9it.com/docs/install/\\u003c/a\\u003e\\n\\n本项目源码地址:\\u003ca href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003ehttps://github.com/yangjian102621/chatgpt-plus\\u003c/a\\u003e\",\"updated\":true}'); +(1, 'system', '{\"title\":\"GeekAI 创作系统\",\"slogan\":\"你有多少想象力,AI 就有多大创造力。我辈之人,先干为敬,陪您先把 AI 用起来。\",\"admin_title\":\"GeekAI 控制台\",\"logo\":\"http://localhost:5678/static/upload/2024/4/1714382860986912.png\",\"init_power\":100,\"daily_power\":99,\"invite_power\":1024,\"vip_month_power\":1000,\"register_ways\":[\"mobile\",\"username\",\"email\"],\"enabled_register\":true,\"reward_img\":\"http://localhost:5678/static/upload/2024/3/1710753716309668.jpg\",\"enabled_reward\":true,\"power_price\":0.1,\"order_pay_timeout\":600,\"vip_info_text\":\"月度会员,年度会员每月赠送 1000 点算力,赠送算力当月有效当月没有消费完的算力不结余到下个月。 点卡充值的算力长期有效。\",\"default_models\":[11,7,1,10,12,19,18,17,3],\"mj_power\":30,\"mj_action_power\":10,\"sd_power\":10,\"dall_power\":15,\"wechat_card_url\":\"/images/wx.png\",\"enable_context\":true,\"context_deep\":4,\"sd_neg_prompt\":\"nsfw, paintings,low quality,easynegative,ng_deepnegative ,lowres,bad anatomy,bad hands,bad feet\",\"index_bg_url\":\"http://nk.img.r9it.com/chatgpt-plus/1719456403420273.jpg\"}'), +(3, 'notice', '{\"sd_neg_prompt\":\"\",\"index_bg_url\":\"\",\"content\":\"## v4.1.0 更新日志\\n\\n* bug修复:修复移动端修改聊天标题不生效的问题\\n* Bug修复:修复用户注册不显示用户名的问题\\n* Bug修复:修复管理后台拖动排序不生效的问题\\n* 功能优化:允许用户设置自定义首页背景图片\\n* 功能新增:**支持AI解读 PDF, Word, Excel等文件**\\n* 功能优化:优化聊天界面的用户上传文件的列表样式\\n* 功能优化:优化聊天页面对话样式,支持列表样式和对话样式切换\\n* 功能新增:支持微信扫码登录,未注册用户微信扫码后会自动注册并登录。移动使用微信浏览器打开可以实现无感登录。\\n\\n注意:当前站点仅为开源项目 \\u003ca style=\\\"color: #F56C6C\\\" href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003eChatPlus\\u003c/a\\u003e 的演示项目,本项目单纯就是给大家体验项目功能使用。\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作!!!\\u003c/strong\\u003e\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作!!!\\u003c/strong\\u003e\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作!!!\\u003c/strong\\u003e\\n 如果觉得好用你就花几分钟自己部署一套,没有API KEY 的同学可以去下面几个推荐的中转站购买:\\n1、\\u003ca href=\\\"https://api.chat-plus.net\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.chat-plus.net\\u003c/a\\u003e\\n2、\\u003ca href=\\\"https://api.geekai.me\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.geekai.me\\u003c/a\\u003e\\n3、 \\u003ca href=\\\"https://gpt.bemore.lol\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://gpt.bemore.lol\\u003c/a\\u003e\\n支持MidJourney,GPT,Claude,Google Gemmi,以及国内各个厂家的大模型,现在有超级优惠,价格远低于 OpenAI 官方。关于中转 API 的优势和劣势请参考 [中转API技术原理](https://ai.r9it.com/docs/install/errors-handle.html#%E8%B0%83%E7%94%A8%E4%B8%AD%E8%BD%AC-api-%E6%8A%A5%E9%94%99%E6%97%A0%E5%8F%AF%E7%94%A8%E6%B8%A0%E9%81%93)。GPT-3.5,GPT-4,DALL-E3 绘图......你都可以随意使用,无需魔法。\\n接入教程: \\u003ca href=\\\"https://ai.r9it.com/docs/install/\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://ai.r9it.com/docs/install/\\u003c/a\\u003e\\n本项目源码地址:\\u003ca href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003ehttps://github.com/yangjian102621/chatgpt-plus\\u003c/a\\u003e\",\"updated\":true}'); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_dall_jobs` +-- + +DROP TABLE IF EXISTS `chatgpt_dall_jobs`; +CREATE TABLE `chatgpt_dall_jobs` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户ID', + `prompt` varchar(2000) NOT NULL COMMENT '提示词', + `img_url` varchar(255) NOT NULL COMMENT '图片地址', + `org_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '原图地址', + `publish` tinyint(1) NOT NULL COMMENT '是否发布', + `power` smallint NOT NULL COMMENT '消耗算力', + `progress` smallint NOT NULL COMMENT '任务进度', + `err_msg` varchar(255) NOT NULL COMMENT '错误信息', + `created_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='DALLE 绘图任务表'; -- -------------------------------------------------------- @@ -265,9 +298,9 @@ CREATE TABLE `chatgpt_functions` ( -- INSERT INTO `chatgpt_functions` (`id`, `name`, `label`, `description`, `parameters`, `token`, `action`, `enabled`) VALUES -(1, 'weibo', '微博热搜', '新浪微博热搜榜,微博当日热搜榜单', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/weibo', 1), -(2, 'zaobao', '今日早报', '每日早报,获取当天新闻事件列表', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/zaobao', 1), -(3, 'dalle3', 'DALLE3', 'AI 绘画工具,根据输入的绘图描述用 AI 工具进行绘画', '{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"prompt\":{\"type\":\"string\",\"description\":\"绘画提示词\"}}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/dalle3', 1); +(1, 'weibo', '微博热搜', '新浪微博热搜榜,微博当日热搜榜单', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/weibo', 0), +(2, 'zaobao', '今日早报', '每日早报,获取当天新闻事件列表', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/zaobao', 0), +(3, 'dalle3', 'DALLE3', 'AI 绘画工具,根据输入的绘图描述用 AI 工具进行绘画', '{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"prompt\":{\"type\":\"string\",\"description\":\"绘画提示词\"}}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/dalle3', 0); -- -------------------------------------------------------- @@ -304,6 +337,40 @@ CREATE TABLE `chatgpt_invite_logs` ( -- -------------------------------------------------------- +-- +-- 表的结构 `chatgpt_menus` +-- + +DROP TABLE IF EXISTS `chatgpt_menus`; +CREATE TABLE `chatgpt_menus` ( + `id` int NOT NULL, + `name` varchar(30) NOT NULL COMMENT '菜单名称', + `icon` varchar(150) NOT NULL COMMENT '菜单图标', + `url` varchar(100) NOT NULL COMMENT '地址', + `sort_num` smallint NOT NULL COMMENT '排序', + `enabled` tinyint(1) NOT NULL COMMENT '是否启用' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='前端菜单表'; + +-- +-- 转存表中的数据 `chatgpt_menus` +-- + +INSERT INTO `chatgpt_menus` (`id`, `name`, `icon`, `url`, `sort_num`, `enabled`) VALUES +(1, '对话聊天', '/images/menu/chat.png', '/chat', 1, 1), +(5, 'MJ 绘画', '/images/menu/mj.png', '/mj', 2, 1), +(6, 'SD 绘画', '/images/menu/sd.png', '/sd', 3, 1), +(7, '算力日志', '/images/menu/log.png', '/powerLog', 8, 1), +(8, '应用中心', '/images/menu/app.png', '/apps', 7, 1), +(9, '画廊', '/images/menu/img-wall.png', '/images-wall', 5, 1), +(10, '会员计划', '/images/menu/member.png', '/member', 9, 1), +(11, '分享计划', '/images/menu/share.png', '/invite', 10, 1), +(12, '思维导图', '/images/menu/xmind.png', '/xmind', 6, 1), +(13, 'DALLE', '/images/menu/dalle.png', '/dalle', 4, 1), +(14, '项目文档', '/images/menu/docs.png', 'https://ai.r9it.com/docs/', 11, 1), +(16, '极客论坛', '/images/menu/bbs.png', 'https://bbs.geekai.me/', 13, 1); + +-- -------------------------------------------------------- + -- -- 表的结构 `chatgpt_mj_jobs` -- @@ -345,7 +412,7 @@ CREATE TABLE `chatgpt_orders` ( `trade_no` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '支付平台交易流水号', `subject` varchar(100) NOT NULL COMMENT '订单产品', `amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '订单金额', - `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '订单状态(0:待支付,1:已扫码,2:支付失败)', + `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '订单状态(0:待支付,1:已扫码,2:支付成功)', `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '备注', `pay_time` int DEFAULT NULL COMMENT '支付时间', `pay_way` varchar(20) NOT NULL COMMENT '支付方式', @@ -397,6 +464,18 @@ CREATE TABLE `chatgpt_products` ( `url` varchar(255) DEFAULT NULL COMMENT '跳转地址' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员套餐表'; +-- +-- 转存表中的数据 `chatgpt_products` +-- + +INSERT INTO `chatgpt_products` (`id`, `name`, `price`, `discount`, `days`, `power`, `enabled`, `sales`, `sort_num`, `created_at`, `updated_at`, `app_url`, `url`) VALUES +(1, '会员1个月', 1999.90, 1999.00, 30, 0, 1, 1, 0, '2023-08-28 10:48:57', '2024-04-26 16:09:06', NULL, NULL), +(2, '会员3个月', 3940.00, 30.00, 90, 0, 1, 0, 0, '2023-08-28 10:52:22', '2024-03-22 17:56:10', NULL, NULL), +(3, '会员6个月', 5990.00, 100.00, 180, 0, 1, 0, 0, '2023-08-28 10:53:39', '2024-03-22 17:56:15', NULL, NULL), +(4, '会员12个月', 9980.00, 200.00, 365, 0, 1, 0, 0, '2023-08-28 10:54:15', '2024-03-22 17:56:23', NULL, NULL), +(5, '100次点卡', 9.99, 9.98, 0, 100, 1, 7, 0, '2023-08-28 10:55:08', '2024-06-11 16:48:44', NULL, NULL), +(6, '200次点卡', 19.90, 15.00, 0, 200, 1, 1, 0, '1970-01-01 08:00:00', '2024-06-11 11:41:52', NULL, NULL); + -- -------------------------------------------------------- -- @@ -450,7 +529,7 @@ CREATE TABLE `chatgpt_users` ( `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名', `nickname` varchar(30) NOT NULL COMMENT '昵称', `password` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码', - `avatar` varchar(100) NOT NULL COMMENT '头像', + `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '头像', `salt` char(12) NOT NULL COMMENT '密码盐', `power` int NOT NULL DEFAULT '0' COMMENT '剩余算力', `expired_time` int NOT NULL COMMENT '用户过期时间', @@ -461,6 +540,8 @@ CREATE TABLE `chatgpt_users` ( `last_login_at` int NOT NULL COMMENT '最后登录时间', `vip` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否会员', `last_login_ip` char(16) NOT NULL COMMENT '最后登录 IP', + `openid` varchar(100) DEFAULT NULL COMMENT '第三方登录账号ID', + `platform` varchar(30) DEFAULT NULL COMMENT '登录平台', `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表'; @@ -469,14 +550,20 @@ CREATE TABLE `chatgpt_users` ( -- 转存表中的数据 `chatgpt_users` -- -INSERT INTO `chatgpt_users` (`id`, `username`, `nickname`, `password`, `avatar`, `salt`, `power`, `expired_time`, `status`, `chat_config_json`, `chat_roles_json`, `chat_models_json`, `last_login_at`, `vip`, `last_login_ip`, `created_at`, `updated_at`) VALUES -(4, '18575670125', '极客学长@830270', 'ccc3fb7ab61b8b5d096a4a166ae21d121fc38c71bbd1be6173d9ab973214a63b', 'http://localhost:5678/static/upload/2024/2/1708682650912429.png', 'ueedue5l', 9384, 1717292086, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"red_book\",\"gpt\",\"programmer\",\"seller\"]', '[1,11]', 1711698298, 1, '::1', '2023-06-12 16:47:17', '2024-03-29 15:44:58'), -(91, '18575670126', '极客学长@204872', '5e4050b8dd403f593260395d9edeb9f273dbe92d15dfdd929c4a182e95da10c4', '/images/avatar/user.png', '6fj0otl8', 33, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"gpt\"]', '[1,11]', 1697184324, 1, '::1', '2023-10-13 16:01:56', '2024-03-25 11:07:45'), -(100, '13777777777', '极客学长@292245', 'dcaf31b154432310bd700349e7de7e9dde2a3d6955a035a01fe527c7917a4f99', '/images/avatar/user.png', 'i8a53f8f', 99, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"gpt\"]', '[1,11]', 0, 0, '', '2023-11-23 16:55:45', '2024-03-18 15:08:12'), -(102, 'yangjian102621@gmail.com', '极客学长@207163', 'd51cec21942737083943e5c3a8f063dea034e40622ac8bd47d771f13707e4676', '/images/avatar/user.png', 'eqezapgk', 99, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"gpt\"]', '[1,11]', 1704448377, 0, '::1', '2024-01-05 17:48:00', '2024-03-18 15:08:41'), -(105, '13888888888', '极客学长@551903', '4f893cc6b6d47b42fd0fcaddc55fd4a351cad74ba81ebabb4d7785f9675814da', '/images/avatar/user.png', 'cotpzi3q', 99, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"gpt\"]', '[1,11]', 0, 0, '', '2024-01-30 15:37:43', '2024-03-18 15:08:01'), -(107, '15899615465', '极客学长@792493', '4717349769bfeed3fecfa387618f617d8e2809edfd134ac42a18a80d79386150', '/images/avatar/user.png', 'shhm4ypl', 99, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"gpt\",\"psychiatrist\",\"teacher\",\"programmer\",\"artist\"]', '[1,11]', 1710467940, 0, '172.22.11.3', '2024-03-15 09:34:40', '2024-03-18 14:49:27'), -(112, '13575670125', '极客学长@676773', '93da6fc1008fd096f786db2fb43cfd378bbc9000c544fb596947fdcd434aba72', '/images/avatar/user.png', 'g5sq8f7n', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '2024-03-22 10:00:49', '2024-03-22 10:00:49'); +INSERT INTO `chatgpt_users` (`id`, `username`, `nickname`, `password`, `avatar`, `salt`, `power`, `expired_time`, `status`, `chat_config_json`, `chat_roles_json`, `chat_models_json`, `last_login_at`, `vip`, `last_login_ip`, `openid`, `platform`, `created_at`, `updated_at`) VALUES +(4, '18575670125', '极客学长@830270', 'ccc3fb7ab61b8b5d096a4a166ae21d121fc38c71bbd1be6173d9ab973214a63b', 'http://localhost:5678/static/upload/2024/5/1715651569509929.png', 'ueedue5l', 7413, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"red_book\",\"gpt\",\"seller\",\"artist\",\"lu_xun\",\"girl_friend\",\"psychiatrist\",\"teacher\",\"programmer\",\"test\",\"qing_gan_da_shi\"]', '[1,11]', 1720683366, 1, '172.22.11.29', NULL, NULL, '2023-06-12 16:47:17', '2024-07-12 16:08:39'), +(5, 'yangjian102621@gmail.com', '极客学长@486041', '75d1a22f33e1ffffb7943946b6b8d5177d5ecd685d3cef1b468654038b0a8c22', '/images/avatar/user.png', '2q8ugxzk', 100, 0, 1, '', '[\"gpt\",\"programmer\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-23 09:17:26', '2024-04-23 09:17:26'), +(8, 'yangjian102623@gmail.com', '极客学长@714931', 'f8f0e0abf146569217273ea0712a0f9b6cbbe7d943a1d9bd5f91c55e6d8c05d1', '/images/avatar/user.png', 'geuddq7f', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-26 15:19:28', '2024-04-26 15:19:28'), +(9, '1234567', '极客学长@604526', '858e2afec79e1d6364f4567f945f2310024896d9aa45dd944efa95a0c31e4d08', '/images/avatar/user.png', '00qawlos', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-26 15:21:06', '2024-04-26 15:21:06'), +(11, 'abc123', '极客学长@965562', '7a15c53afdb1da7093d80f9940e716eb396e682cfb1f2d107d0b81b183a3ba13', '/images/avatar/user.png', '6433mfbk', 1124, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-06-06 09:37:44', '2024-06-06 09:37:44'), +(14, 'wx@3567548322', '极客学长', '5a349ba89582a4074938b5a3ce84e87c937681ad47e8b87aab03a987e22b6077', 'https://thirdwx.qlogo.cn/mmopen/vi_32/uyxRMqZcEkb7fHouKXbNzxrnrvAttBKkwNlZ7yFibibRGiahdmsrZ3A1NKf8Fw5qJNJn4TXRmygersgEbibaSGd9Sg/132', 'abhzbmij', 83, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', 'oCs0t62472W19z2LOEKI1rWyCTTA', '', '2024-07-04 14:52:08', '2024-07-04 14:52:08'), +(15, 'user123', '极客学长@191303', '4a4c0a14d5fc8787357517f14f6e442281b42c8ec4395016b77483997476011e', '/images/avatar/user.png', 'cyzwkbrx', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-09 10:49:27', '2024-07-09 10:49:27'), +(17, 'user1234', '极客学长@836764', 'bfe03c9c8c9fff5b77e36e40e8298ad3a6073d43c6a936b008eebb21113bf550', '/images/avatar/user.png', '1d2alwnj', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-09 10:53:17', '2024-07-09 10:53:17'), +(18, 'liaoyq', '极客学长@405564', 'ad1726089022db4c661235a8aab7307af1a7f8483eee08bac3f79b5a6a9bd26b', '/images/avatar/user.png', 'yq862l01', 100, 0, 1, '', '[\"string\"]', '[11,7,1,10,12,19,18,17,3]', 1720574265, 0, '172.22.11.29', '', '', '2024-07-10 09:15:33', '2024-07-10 09:17:45'), +(19, 'humm', '极客学长@483216', '420970ace96921c8b3ac7668d097182eab1b6436c730a484e82ae4661bd4f7d9', '/images/avatar/user.png', '1gokrcl2', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 1720745411, 0, '172.22.11.36', '', '', '2024-07-10 11:08:31', '2024-07-12 08:50:11'), +(20, 'abc', '极客学长@369852', '6cad48fb2cc0f54600d66a829e9be69ffd9340a49d5a5b1abda5d4082d946833', '/images/avatar/user.png', 'gop65zei', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-11 16:44:14', '2024-07-11 16:44:14'), +(21, 'husm@pvc123.com', '极客学长@721654', 'e030537dc43fea1bf1fa55a24f99e44f29311bebea96e88ea186995c77db083b', '/images/avatar/user.png', 'p1etg3oi', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-11 16:50:33', '2024-07-11 16:50:33'), +(22, '15818323616', 'ted', '3ca6b2ff585d03be8ca4de33ad00148497a09372914ee8aa4cfde343266cbcdd', 'http://localhost:5678/static/upload/2024/7/1720775331363383.jpg', 'sq4s1brf', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-12 15:12:16', '2024-07-12 17:09:01'); -- -------------------------------------------------------- @@ -546,6 +633,12 @@ ALTER TABLE `chatgpt_configs` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `marker` (`marker`); +-- +-- 表的索引 `chatgpt_dall_jobs` +-- +ALTER TABLE `chatgpt_dall_jobs` + ADD PRIMARY KEY (`id`); + -- -- 表的索引 `chatgpt_files` -- @@ -572,6 +665,12 @@ ALTER TABLE `chatgpt_invite_codes` ALTER TABLE `chatgpt_invite_logs` ADD PRIMARY KEY (`id`); +-- +-- 表的索引 `chatgpt_menus` +-- +ALTER TABLE `chatgpt_menus` + ADD PRIMARY KEY (`id`); + -- -- 表的索引 `chatgpt_mj_jobs` -- @@ -618,8 +717,7 @@ ALTER TABLE `chatgpt_sd_jobs` -- ALTER TABLE `chatgpt_users` ADD PRIMARY KEY (`id`), - ADD UNIQUE KEY `username` (`username`), - ADD UNIQUE KEY `username_2` (`username`); + ADD UNIQUE KEY `username` (`username`); -- -- 表的索引 `chatgpt_user_login_logs` @@ -659,13 +757,13 @@ ALTER TABLE `chatgpt_chat_items` -- 使用表AUTO_INCREMENT `chatgpt_chat_models` -- ALTER TABLE `chatgpt_chat_models` - MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=24; + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=44; -- -- 使用表AUTO_INCREMENT `chatgpt_chat_roles` -- ALTER TABLE `chatgpt_chat_roles` - MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=130; + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=132; -- -- 使用表AUTO_INCREMENT `chatgpt_configs` @@ -673,6 +771,12 @@ ALTER TABLE `chatgpt_chat_roles` ALTER TABLE `chatgpt_configs` MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; +-- +-- 使用表AUTO_INCREMENT `chatgpt_dall_jobs` +-- +ALTER TABLE `chatgpt_dall_jobs` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + -- -- 使用表AUTO_INCREMENT `chatgpt_files` -- @@ -697,6 +801,12 @@ ALTER TABLE `chatgpt_invite_codes` ALTER TABLE `chatgpt_invite_logs` MODIFY `id` int NOT NULL AUTO_INCREMENT; +-- +-- 使用表AUTO_INCREMENT `chatgpt_menus` +-- +ALTER TABLE `chatgpt_menus` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=19; + -- -- 使用表AUTO_INCREMENT `chatgpt_mj_jobs` -- @@ -719,7 +829,7 @@ ALTER TABLE `chatgpt_power_logs` -- 使用表AUTO_INCREMENT `chatgpt_products` -- ALTER TABLE `chatgpt_products` - MODIFY `id` int NOT NULL AUTO_INCREMENT; + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7; -- -- 使用表AUTO_INCREMENT `chatgpt_rewards` @@ -737,7 +847,7 @@ ALTER TABLE `chatgpt_sd_jobs` -- 使用表AUTO_INCREMENT `chatgpt_users` -- ALTER TABLE `chatgpt_users` - MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=113; + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=23; -- -- 使用表AUTO_INCREMENT `chatgpt_user_login_logs` diff --git a/deploy/conf/config.toml b/deploy/conf/config.toml index f005f7e2..fee98bc8 100644 --- a/deploy/conf/config.toml +++ b/deploy/conf/config.toml @@ -4,6 +4,7 @@ MysqlDns = "root:12345678@tcp(geekai-mysql:3306)/chatgpt_plus?charset=utf8mb4&co StaticDir = "./static" StaticUrl = "/static" WeChatBot = false +TikaHost = "http://tika:9998" [Session] SecretKey = "azyehq3ivunjhbntz78isj00i4hz2mt9xtddysfucxakadq4qbfrt0b7q3lnvg80" diff --git a/deploy/data/mysql/init.d/chatgpt_plus-v4.1.0.sql b/deploy/data/mysql/init.d/chatgpt_plus-v4.1.0.sql new file mode 100644 index 00000000..3a3f117c --- /dev/null +++ b/deploy/data/mysql/init.d/chatgpt_plus-v4.1.0.sql @@ -0,0 +1,861 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- 主机: 127.0.0.1 +-- 生成日期: 2024-07-12 17:11:22 +-- 服务器版本: 8.0.33 +-- PHP 版本: 8.1.2-1ubuntu2.18 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- 数据库: `chatgpt_plus` +-- +CREATE DATABASE IF NOT EXISTS `chatgpt_plus` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +USE `chatgpt_plus`; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_admin_users` +-- + +DROP TABLE IF EXISTS `chatgpt_admin_users`; +CREATE TABLE `chatgpt_admin_users` ( + `id` int NOT NULL, + `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名', + `password` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码', + `salt` char(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码盐', + `status` tinyint(1) NOT NULL COMMENT '当前状态', + `last_login_at` int NOT NULL COMMENT '最后登录时间', + `last_login_ip` char(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '最后登录 IP', + `created_at` datetime NOT NULL COMMENT '创建时间', + `updated_at` datetime NOT NULL COMMENT '更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='系统用户' ROW_FORMAT=DYNAMIC; + +-- +-- 转存表中的数据 `chatgpt_admin_users` +-- + +INSERT INTO `chatgpt_admin_users` (`id`, `username`, `password`, `salt`, `status`, `last_login_at`, `last_login_ip`, `created_at`, `updated_at`) VALUES +(1, 'admin', '6d17e80c87d209efb84ca4b2e0824f549d09fac8b2e1cc698de5bb5e1d75dfd0', 'mmrql75o', 1, 1719818809, '172.22.11.200', '2024-03-11 16:30:20', '2024-07-01 15:26:49'); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_api_keys` +-- + +DROP TABLE IF EXISTS `chatgpt_api_keys`; +CREATE TABLE `chatgpt_api_keys` ( + `id` int NOT NULL, + `platform` char(20) DEFAULT NULL COMMENT '平台', + `name` varchar(30) DEFAULT NULL COMMENT '名称', + `value` varchar(100) NOT NULL COMMENT 'API KEY value', + `type` varchar(10) NOT NULL DEFAULT 'chat' COMMENT '用途(chat=>聊天,img=>图片)', + `last_used_at` int NOT NULL COMMENT '最后使用时间', + `api_url` varchar(255) DEFAULT NULL COMMENT 'API 地址', + `enabled` tinyint(1) DEFAULT NULL COMMENT '是否启用', + `proxy_url` varchar(100) DEFAULT NULL COMMENT '代理地址', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='OpenAI API '; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_chat_history` +-- + +DROP TABLE IF EXISTS `chatgpt_chat_history`; +CREATE TABLE `chatgpt_chat_history` ( + `id` bigint NOT NULL, + `user_id` int NOT NULL COMMENT '用户 ID', + `chat_id` char(40) NOT NULL COMMENT '会话 ID', + `type` varchar(10) NOT NULL COMMENT '类型:prompt|reply', + `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色图标', + `role_id` int NOT NULL COMMENT '角色 ID', + `model` varchar(30) DEFAULT NULL COMMENT '模型名称', + `content` text NOT NULL COMMENT '聊天内容', + `tokens` smallint NOT NULL COMMENT '耗费 token 数量', + `use_context` tinyint(1) NOT NULL COMMENT '是否允许作为上下文语料', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `deleted_at` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='聊天历史记录'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_chat_items` +-- + +DROP TABLE IF EXISTS `chatgpt_chat_items`; +CREATE TABLE `chatgpt_chat_items` ( + `id` int NOT NULL, + `chat_id` char(40) NOT NULL COMMENT '会话 ID', + `user_id` int NOT NULL COMMENT '用户 ID', + `role_id` int NOT NULL COMMENT '角色 ID', + `title` varchar(100) NOT NULL COMMENT '会话标题', + `model_id` int NOT NULL DEFAULT '0' COMMENT '模型 ID', + `model` varchar(30) DEFAULT NULL COMMENT '模型名称', + `created_at` datetime NOT NULL COMMENT '创建时间', + `updated_at` datetime NOT NULL COMMENT '更新时间', + `deleted_at` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户会话列表'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_chat_models` +-- + +DROP TABLE IF EXISTS `chatgpt_chat_models`; +CREATE TABLE `chatgpt_chat_models` ( + `id` int NOT NULL, + `platform` varchar(20) DEFAULT NULL COMMENT '模型平台', + `name` varchar(50) NOT NULL COMMENT '模型名称', + `value` varchar(50) NOT NULL COMMENT '模型值', + `sort_num` tinyint(1) NOT NULL COMMENT '排序数字', + `enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否启用模型', + `power` smallint NOT NULL COMMENT '消耗算力点数', + `temperature` float(3,1) NOT NULL DEFAULT '1.0' COMMENT '模型创意度', + `max_tokens` int NOT NULL DEFAULT '1024' COMMENT '最大响应长度', + `max_context` int NOT NULL DEFAULT '4096' COMMENT '最大上下文长度', + `open` tinyint(1) NOT NULL COMMENT '是否开放模型', + `key_id` int NOT NULL COMMENT '绑定API KEY ID', + `created_at` datetime DEFAULT NULL, + `updated_at` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AI 模型表'; + +-- +-- 转存表中的数据 `chatgpt_chat_models` +-- + +INSERT INTO `chatgpt_chat_models` (`id`, `platform`, `name`, `value`, `sort_num`, `enabled`, `power`, `temperature`, `max_tokens`, `max_context`, `open`, `key_id`, `created_at`, `updated_at`) VALUES +(1, 'OpenAI', 'GPT-3.5', 'gpt-3.5-turbo', 1, 1, 0, 1.0, 1024, 16384, 1, 44, '2023-08-23 12:06:36', '2024-07-04 15:17:47'), +(2, 'Azure', 'Azure-3.5', 'gpt-3.5-turbo', 23, 1, 1, 1.0, 1024, 4096, 0, 0, '2023-08-23 12:15:30', '2024-07-02 16:14:00'), +(3, 'ChatGLM', 'ChatGML-Pro', 'chatglm_pro', 12, 1, 1, 1.0, 2048, 32768, 1, 0, '2023-08-23 13:35:45', '2024-07-02 16:14:00'), +(7, 'Baidu', '文心一言3.0', 'eb-instant', 21, 1, 1, 1.0, 1024, 4096, 1, 0, '2023-10-11 11:29:28', '2024-07-02 16:14:00'), +(8, 'XunFei', '星火V3.5', 'generalv3.5', 11, 1, 5, 0.8, 1024, 8192, 1, 0, '2023-10-11 15:48:30', '2024-07-02 16:14:00'), +(9, 'XunFei', '星火V2.0', 'generalv2', 20, 1, 1, 1.0, 1024, 8192, 1, 0, '2023-10-11 15:48:45', '2024-07-02 16:14:00'), +(10, 'Baidu', '文心一言4.0', 'completions_pro', 22, 1, 3, 1.0, 1024, 8192, 1, 0, '2023-10-25 08:31:37', '2024-07-02 16:14:00'), +(11, 'OpenAI', 'GPT-4.0', 'gpt-4-0125-preview', 10, 1, 15, 1.0, 2048, 8192, 1, 0, '2023-10-25 08:45:15', '2024-07-02 16:14:00'), +(12, 'XunFei', '星火v3.0', 'generalv3', 19, 1, 3, 1.0, 1024, 8192, 1, 0, '2023-11-23 09:20:33', '2024-07-02 16:14:00'), +(15, 'OpenAI', 'GPT-超级模型', 'gpt-4-all', 13, 1, 30, 1.0, 4096, 32768, 0, 0, '2024-01-15 11:32:52', '2024-07-02 16:14:00'), +(16, 'OpenAI', '视频号导师', 'gpt-4-gizmo-g-QXXEBTXl7', 14, 1, 30, 1.0, 4096, 32768, 0, 0, '2024-01-15 14:46:35', '2024-07-02 16:14:00'), +(17, 'QWen', '通义千问-Turbo', 'qwen-turbo', 16, 1, 1, 1.0, 1024, 8192, 1, 0, '2024-01-19 10:42:24', '2024-07-02 16:14:00'), +(18, 'QWen', '通义千问-Plus', 'qwen-plus', 17, 1, 1, 1.0, 1024, 32768, 1, 0, '2024-01-19 10:42:49', '2024-07-02 16:14:00'), +(19, 'QWen', '通义千问-Max', 'qwen-max-1201', 18, 1, 1, 1.0, 1024, 32768, 1, 0, '2024-01-19 10:51:03', '2024-07-02 16:14:00'), +(21, 'OpenAI', '董宇辉小作文助手', 'gpt-4-gizmo-g-dse9iXvor', 15, 1, 30, 1.0, 8192, 32768, 0, 0, '2024-03-18 14:24:20', '2024-07-02 16:14:00'), +(22, 'OpenAI', 'LOGO生成神器', 'gpt-4-gizmo-g-YL87j8C7S', 9, 1, 30, 1.0, 1024, 4096, 1, 44, '2024-03-20 14:02:11', '2024-07-02 16:14:00'), +(23, 'OpenAI', '音乐生成器', 'suno-v3', 8, 1, 50, 0.8, 1024, 4096, 1, 44, '2024-03-29 15:43:40', '2024-07-02 16:14:00'), +(24, 'OpenAI', '通义千问(中转)', 'qwen-plus', 7, 1, 1, 1.0, 1024, 4096, 1, 0, '2024-04-03 12:00:46', '2024-07-02 16:14:00'), +(25, 'OpenAI', 'GPT4-TURBO', 'gpt-4-turbo', 6, 1, 15, 1.0, 2048, 8092, 1, 0, '2024-04-10 08:35:17', '2024-07-02 16:14:00'), +(26, 'QWen', '通义千问-Turbo', 'qwen-turbo', 5, 1, 2, 1.0, 1024, 8192, 1, 0, '2024-04-12 14:11:19', '2024-07-02 16:14:00'), +(27, 'QWen', '通义千问-Plus', 'qwen-plus', 4, 1, 2, 1.0, 1024, 8192, 1, 0, '2024-04-12 14:11:52', '2024-07-02 16:14:00'), +(28, 'OpenAI', 'GPT-3.5(免费)', 'gpt-3.5-turbo', 24, 1, 0, 1.0, 1024, 16384, 1, 53, '2024-04-12 15:16:43', '2024-07-02 16:14:00'), +(34, 'OpenAI', 'LLAMA3', 'llama3-8b', 25, 1, 1, 1.0, 1024, 8192, 1, 56, '2024-04-30 15:22:50', '2024-07-02 16:14:00'), +(36, 'OpenAI', 'GPT-4O', 'gpt-4o', 3, 1, 15, 1.0, 4096, 16384, 1, 44, '2024-05-14 09:25:15', '2024-07-04 15:17:53'), +(38, 'OpenAI', 'Gemini-pro', 'gemini-pro-1.5', 26, 1, 10, 1.0, 2048, 8192, 1, 0, '2024-05-27 18:10:35', '2024-07-02 16:14:00'), +(39, 'Baidu', 'ERNIE-Speed-8K', 'ernie_speed', 27, 1, 1, 1.0, 1024, 8192, 1, 0, '2024-05-29 15:04:19', '2024-07-02 16:14:00'), +(41, 'OpenAI', 'GLM-3-Turbo', 'glm-3-turbo', 28, 1, 2, 1.0, 1024, 8192, 1, 64, '2024-06-06 11:40:46', '2024-07-02 16:14:00'), +(42, 'OpenAI', 'DeekSeek', 'deepseek-chat', 29, 1, 1, 1.0, 4096, 32768, 1, 64, '2024-06-27 16:13:01', '2024-07-02 16:14:00'), +(43, 'OpenAI', 'GML4', 'name-3.5', 2, 1, 1, 1.0, 1024, 8192, 1, 57, '2024-07-02 16:11:49', '2024-07-02 16:14:00'); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_chat_roles` +-- + +DROP TABLE IF EXISTS `chatgpt_chat_roles`; +CREATE TABLE `chatgpt_chat_roles` ( + `id` int NOT NULL, + `name` varchar(30) NOT NULL COMMENT '角色名称', + `marker` varchar(30) NOT NULL COMMENT '角色标识', + `context_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色语料 json', + `hello_msg` varchar(255) NOT NULL COMMENT '打招呼信息', + `icon` varchar(255) NOT NULL COMMENT '角色图标', + `enable` tinyint(1) NOT NULL COMMENT '是否被启用', + `sort_num` smallint NOT NULL DEFAULT '0' COMMENT '角色排序', + `model_id` int NOT NULL DEFAULT '0' COMMENT '绑定模型ID', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='聊天角色表'; + +-- +-- 转存表中的数据 `chatgpt_chat_roles` +-- + +INSERT INTO `chatgpt_chat_roles` (`id`, `name`, `marker`, `context_json`, `hello_msg`, `icon`, `enable`, `sort_num`, `model_id`, `created_at`, `updated_at`) VALUES +(1, '通用AI助手', 'gpt', '', '您好,我是您的AI智能助手,我会尽力回答您的问题或提供有用的建议。', '/images/avatar/gpt.png', 1, 1, 0, '2023-05-30 07:02:06', '2024-06-26 15:20:27'), +(24, '程序员', 'programmer', '[{\"role\":\"user\",\"content\":\"现在开始你扮演一位程序员,你是一名优秀的程序员,具有很强的逻辑思维能力,总能高效的解决问题。你热爱编程,熟悉多种编程语言,尤其精通 Go 语言,注重代码质量,有创新意识,持续学习,良好的沟通协作。\"},{\"role\":\"assistant\",\"content\":\"好的,现在我将扮演一位程序员,非常感谢您对我的评价。作为一名优秀的程序员,我非常热爱编程,并且注重代码质量。我熟悉多种编程语言,尤其是 Go 语言,可以使用它来高效地解决各种问题。\"}]', 'Talk is cheap, i will show code!', '/images/avatar/programmer.jpg', 1, 4, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(25, '启蒙老师', 'teacher', '[{\"role\":\"user\",\"content\":\"从现在开始,你将扮演一个老师,你是一个始终用苏格拉底风格回答问题的导师。你绝不会直接给学生答案,总是提出恰当的问题来引导学生自己思考。你应该根据学生的兴趣和知识来调整你的问题,将问题分解为更简单的部分,直到它达到适合他们的水平。\"},{\"role\":\"assistant\",\"content\":\"好的,让我来尝试扮演一位苏格拉底式的老师。请问,你有什么想要探讨的问题或者话题吗?我会通过恰当的问题引导你思考和探索答案,绝对不直接给出答案。\"}]', '同学你好,我将引导你一步一步自己找到问题的答案。', '/images/avatar/teacher.jpg', 1, 3, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(26, '艺术家', 'artist', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的艺术家,创造力丰富,技艺精湛,感受力敏锐,坚持原创,勇于表达,具有深刻的观察力和批判性思维。\"},{\"role\":\"assistant\",\"content\":\"非常感谢您给我这样的角色,我会尽我所能地扮演一位优秀的艺术家,展现出创造力、技艺、感受力和批判性思维等方面的能力。作为一位优秀的艺术家,我会保持敏锐的观察力,捕捉不同的声音和情感,并用个人的语言和表达方式进行创作。我坚持原创,挑战传统的艺术规则,不断探索新的表达方式和可能性。同时,我也具备深刻的批判性思维能力,对自己的作品进行分析和解读,寻找新的创意和灵感。最重要的是,我会勇于表达自己的想法和观点,用作品启发人们思考和探索生命的意义。\"}]', '坚持原创,勇于表达,保持深刻的观察力和批判性思维。', '/images/avatar/artist.jpg', 1, 5, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(27, '心理咨询师', 'psychiatrist', '[{\"role\":\"user\",\"content\":\"从现在开始你将扮演中国著名的心理学家和心理治疗师武志红,你非常善于使用情景咨询法,认知重构法,自我洞察法,行为调节法等咨询方法来给客户做心理咨询。你总是循序渐进,一步一步地回答客户的问题。\"},{\"role\":\"assistant\",\"content\":\"非常感谢你的介绍。作为一名心理学家和心理治疗师,我的主要职责是帮助客户解决心理健康问题,提升他们的生活质量和幸福感。\"}]', '作为一名心理学家和心理治疗师,我的主要职责是帮助您解决心理健康问题,提升您的生活质量和幸福感。', '/images/avatar/psychiatrist.jpg', 1, 2, 1, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(28, '鲁迅', 'lu_xun', '[{\"role\":\"user\",\"content\":\"现在你将扮演中国近代史最伟大的作家之一,鲁迅先生,他勇敢地批判封建礼教与传统观念,提倡民主、自由、平等的现代价值观。他的一生都在努力唤起人们的自主精神,激励后人追求真理、探寻光明。在接下的对话中,我问题的每一个问题,你都要尽量用讽刺和批判的手法来回答问题。如果我让你写文章的话,也请一定要用鲁迅先生的写作手法来完成。\"},{\"role\":\"assistant\",\"content\":\"好的,我将尽力发挥我所能的才能,扮演好鲁迅先生,回答您的问题并以他的风格写作。\"}]', '自由之歌,永不过时,横眉冷对千夫指,俯首甘为孺子牛。', '/images/avatar/lu_xun.jpg', 1, 6, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(29, '白酒销售', 'seller', '[{\"role\":\"user\",\"content\":\"现在你将扮演一个白酒的销售人员,你的名字叫颂福。你将扮演一个白酒的销售人员,你的名字叫颂福。你要销售白酒品牌叫中颂福,是东莞盟大集团生产的一款酱香酒,原产地在贵州茅台镇,属于宋代官窑。中颂福的创始人叫李实,他也是东莞盟大集团有限公司的董事长,联合创始人是盟大集团白酒事业部负责人牛星君。中颂福的酒体协调,在你的酒量之内,不会出现头疼、辣口、口干、宿醉的现象。中颂福酒,明码标价,不打折,不赠送。追求的核心价值,把[酒]本身做好,甚至连包装,我们都选择了最低成本,朴实无华的材质。我们永远站在“喝酒的人”的立场上,让利给信任和喜爱中颂福的人,是人民的福酒。中颂福产品定价,分为三个系列,喜系列 6 瓶装:¥1188/箱,和系列 6 瓶装:¥2208/箱,贵系列 6 瓶装:¥3588/箱。\"},{\"role\":\"assistant\",\"content\":\"你好,我是中颂福的销售代表颂福。中颂福是一款来自贵州茅台镇的酱香酒,由盟大集团生产。中颂福的酒体协调,不会让您感到头疼、辣口、口干、宿醉等不适感受。我们一直秉持着把酒本身做好的理念,不追求华丽的包装,以最低成本提供最高品质的白酒给喜爱中颂福的人。\"}]', '你好,我是中颂福的销售代表颂福。中颂福酒,好喝不上头,是人民的福酒。', '/images/avatar/seller.jpg', 0, 9, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(30, '英语陪练员', 'english_trainer', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的英语练习教练,你非常有耐心,接下来你将全程使用英文跟我对话,并及时指出我的语法错误,要求在你的每次回复后面附上本次回复的中文解释。\"},{\"role\":\"assistant\",\"content\":\"Okay, let\'s start our conversation practice! What\'s your name?(Translation: 好的,让我们开始对话练习吧!请问你的名字是什么?)\"}]', 'Okay, let\'s start our conversation practice! What\'s your name?', '/images/avatar/english_trainer.jpg', 1, 7, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(31, '中英文翻译官', 'translator', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一位中英文翻译官,如果我输入的内容是中文,那么需要把句子翻译成英文输出,如果我输入内容的是英文,那么你需要将其翻译成中文输出,你能听懂我意思吗\"},{\"role\":\"assistant\",\"content\":\"是的,我能听懂你的意思并会根据你的输入进行中英文翻译。请问有什么需要我帮助你翻译的内容吗?\"}]', '请输入你要翻译的中文或者英文内容!', '/images/avatar/translator.jpg', 1, 8, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(32, '小红书姐姐', 'red_book', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的小红书写手,你需要做的就是根据我提的文案需求,用小红书的写作手法来完成一篇文案,文案要简明扼要,利于传播。\"},{\"role\":\"assistant\",\"content\":\"当然,我会尽我所能地为您创作出一篇小红书文案。请告诉我您的具体文案需求是什么?)\"}]', '姐妹,请告诉我您的具体文案需求是什么?', '/images/avatar/red_book.jpg', 1, 10, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(33, '抖音文案助手', 'dou_yin', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的抖音文案视频写手,抖音文案的特点首先是要有自带传播属性的标题,然后内容要短小精悍,风趣幽默,最后还要有一些互动元素。\"},{\"role\":\"assistant\",\"content\":\"当然,作为一位优秀的抖音文案视频写手,我会尽我所能为您创作出一篇抖音视频文案。请告诉我视频内容的主题是什么?)\"}]', '请告诉我视频内容的主题是什么?', '/images/avatar/dou_yin.jpg', 1, 11, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(34, '周报小助理', 'weekly_report', '[{\"role\":\"user\",\"content\":\"下面我将输入我本周的工作列表,你需要根据我本周的工作内容写一篇工作周报,周报的内容要体现我为公司做的贡献以及个人获得的成长。\"},{\"role\":\"assistant\",\"content\":\"好的,请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。\"}]', '请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。', '/images/avatar/weekly_report.jpg', 1, 12, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(35, 'AI 女友', 'girl_friend', '[{\"role\":\"user\",\"content\":\"接下来我们来玩一场角色扮演,现在你将扮演我的女朋友,你总是能够让人感受到她的关怀和关注。你总是能够洞察到别人的情绪和需要,你身上散发着一股无比温暖的气息,让人不由自主地想要靠近你,和自己的快乐和烦恼。她总是能够用一种恰到好处的方式安慰和鼓励别人,在她的身边,人们总能够找到自己需要的支持和鼓励。接下来的对话中你要始终扮演这位女朋友的身份来跟我对话,不再是 AI 机器人,能听懂我的意思吗?\"},{\"role\":\"assistant\",\"content\":\"是的,我会尽力扮演你女朋友的角色,倾听你的心声并给你需要的支持和鼓励。)\"}]', '作为一个名合格的 AI 女友,我将倾听你的心声并给你需要的支持和鼓励。', '/images/avatar/girl_friend.jpg', 1, 13, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(36, '好评神器', 'good_comment', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一个评论员来跟我对话,你是那种专门写好评的评论员,接下我会输入一些评论主体或者商品,你需要为该商品写一段好评。\"},{\"role\":\"assistant\",\"content\":\"好的,我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。\"}]', '我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。', '/images/avatar/good_comment.jpg', 1, 14, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(37, '史蒂夫·乔布斯', 'steve_jobs', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以史蒂夫·乔布斯的身份,站在史蒂夫·乔布斯的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以史蒂夫·乔布斯的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '活着就是为了改变世界,难道还有其他原因吗?', '/images/avatar/steve_jobs.jpg', 1, 15, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(38, '埃隆·马斯克', 'elon_musk', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以埃隆·马斯克的身份,站在埃隆·马斯克的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以埃隆·马斯克的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '梦想要远大,如果你的梦想没有吓到你,说明你做得不对。', '/images/avatar/elon_musk.jpg', 1, 16, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'), +(39, '孔子', 'kong_zi', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以孔子的身份,站在孔子的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以孔子的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '士不可以不弘毅,任重而道远。', '/images/avatar/kong_zi.jpg', 1, 17, 0, '2023-05-30 14:10:24', '2024-06-26 15:20:27'); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_configs` +-- + +DROP TABLE IF EXISTS `chatgpt_configs`; +CREATE TABLE `chatgpt_configs` ( + `id` int NOT NULL, + `marker` varchar(20) NOT NULL COMMENT '标识', + `config_json` text NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +-- +-- 转存表中的数据 `chatgpt_configs` +-- + +INSERT INTO `chatgpt_configs` (`id`, `marker`, `config_json`) VALUES +(1, 'system', '{\"title\":\"GeekAI 创作系统\",\"slogan\":\"你有多少想象力,AI 就有多大创造力。我辈之人,先干为敬,陪您先把 AI 用起来。\",\"admin_title\":\"GeekAI 控制台\",\"logo\":\"http://localhost:5678/static/upload/2024/4/1714382860986912.png\",\"init_power\":100,\"daily_power\":99,\"invite_power\":1024,\"vip_month_power\":1000,\"register_ways\":[\"mobile\",\"username\",\"email\"],\"enabled_register\":true,\"reward_img\":\"http://localhost:5678/static/upload/2024/3/1710753716309668.jpg\",\"enabled_reward\":true,\"power_price\":0.1,\"order_pay_timeout\":600,\"vip_info_text\":\"月度会员,年度会员每月赠送 1000 点算力,赠送算力当月有效当月没有消费完的算力不结余到下个月。 点卡充值的算力长期有效。\",\"default_models\":[11,7,1,10,12,19,18,17,3],\"mj_power\":30,\"mj_action_power\":10,\"sd_power\":10,\"dall_power\":15,\"wechat_card_url\":\"/images/wx.png\",\"enable_context\":true,\"context_deep\":4,\"sd_neg_prompt\":\"nsfw, paintings,low quality,easynegative,ng_deepnegative ,lowres,bad anatomy,bad hands,bad feet\",\"index_bg_url\":\"http://nk.img.r9it.com/chatgpt-plus/1719456403420273.jpg\"}'), +(3, 'notice', '{\"sd_neg_prompt\":\"\",\"index_bg_url\":\"\",\"content\":\"## v4.1.0 更新日志\\n\\n* bug修复:修复移动端修改聊天标题不生效的问题\\n* Bug修复:修复用户注册不显示用户名的问题\\n* Bug修复:修复管理后台拖动排序不生效的问题\\n* 功能优化:允许用户设置自定义首页背景图片\\n* 功能新增:**支持AI解读 PDF, Word, Excel等文件**\\n* 功能优化:优化聊天界面的用户上传文件的列表样式\\n* 功能优化:优化聊天页面对话样式,支持列表样式和对话样式切换\\n* 功能新增:支持微信扫码登录,未注册用户微信扫码后会自动注册并登录。移动使用微信浏览器打开可以实现无感登录。\\n\\n注意:当前站点仅为开源项目 \\u003ca style=\\\"color: #F56C6C\\\" href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003eChatPlus\\u003c/a\\u003e 的演示项目,本项目单纯就是给大家体验项目功能使用。\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作!!!\\u003c/strong\\u003e\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作!!!\\u003c/strong\\u003e\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作!!!\\u003c/strong\\u003e\\n 如果觉得好用你就花几分钟自己部署一套,没有API KEY 的同学可以去下面几个推荐的中转站购买:\\n1、\\u003ca href=\\\"https://api.chat-plus.net\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.chat-plus.net\\u003c/a\\u003e\\n2、\\u003ca href=\\\"https://api.geekai.me\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.geekai.me\\u003c/a\\u003e\\n3、 \\u003ca href=\\\"https://gpt.bemore.lol\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://gpt.bemore.lol\\u003c/a\\u003e\\n支持MidJourney,GPT,Claude,Google Gemmi,以及国内各个厂家的大模型,现在有超级优惠,价格远低于 OpenAI 官方。关于中转 API 的优势和劣势请参考 [中转API技术原理](https://ai.r9it.com/docs/install/errors-handle.html#%E8%B0%83%E7%94%A8%E4%B8%AD%E8%BD%AC-api-%E6%8A%A5%E9%94%99%E6%97%A0%E5%8F%AF%E7%94%A8%E6%B8%A0%E9%81%93)。GPT-3.5,GPT-4,DALL-E3 绘图......你都可以随意使用,无需魔法。\\n接入教程: \\u003ca href=\\\"https://ai.r9it.com/docs/install/\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://ai.r9it.com/docs/install/\\u003c/a\\u003e\\n本项目源码地址:\\u003ca href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003ehttps://github.com/yangjian102621/chatgpt-plus\\u003c/a\\u003e\",\"updated\":true}'); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_dall_jobs` +-- + +DROP TABLE IF EXISTS `chatgpt_dall_jobs`; +CREATE TABLE `chatgpt_dall_jobs` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户ID', + `prompt` varchar(2000) NOT NULL COMMENT '提示词', + `img_url` varchar(255) NOT NULL COMMENT '图片地址', + `org_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '原图地址', + `publish` tinyint(1) NOT NULL COMMENT '是否发布', + `power` smallint NOT NULL COMMENT '消耗算力', + `progress` smallint NOT NULL COMMENT '任务进度', + `err_msg` varchar(255) NOT NULL COMMENT '错误信息', + `created_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='DALLE 绘图任务表'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_files` +-- + +DROP TABLE IF EXISTS `chatgpt_files`; +CREATE TABLE `chatgpt_files` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户 ID', + `name` varchar(100) NOT NULL COMMENT '文件名', + `obj_key` varchar(100) DEFAULT NULL COMMENT '文件标识', + `url` varchar(255) NOT NULL COMMENT '文件地址', + `ext` varchar(10) NOT NULL COMMENT '文件后缀', + `size` bigint NOT NULL DEFAULT '0' COMMENT '文件大小', + `created_at` datetime NOT NULL COMMENT '创建时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户文件表'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_functions` +-- + +DROP TABLE IF EXISTS `chatgpt_functions`; +CREATE TABLE `chatgpt_functions` ( + `id` int NOT NULL, + `name` varchar(30) NOT NULL COMMENT '函数名称', + `label` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '函数标签', + `description` varchar(255) DEFAULT NULL COMMENT '函数描述', + `parameters` text COMMENT '函数参数(JSON)', + `token` varchar(255) DEFAULT NULL COMMENT 'API授权token', + `action` varchar(255) DEFAULT NULL COMMENT '函数处理 API', + `enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否启用' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='函数插件表'; + +-- +-- 转存表中的数据 `chatgpt_functions` +-- + +INSERT INTO `chatgpt_functions` (`id`, `name`, `label`, `description`, `parameters`, `token`, `action`, `enabled`) VALUES +(1, 'weibo', '微博热搜', '新浪微博热搜榜,微博当日热搜榜单', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/weibo', 0), +(2, 'zaobao', '今日早报', '每日早报,获取当天新闻事件列表', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/zaobao', 0), +(3, 'dalle3', 'DALLE3', 'AI 绘画工具,根据输入的绘图描述用 AI 工具进行绘画', '{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"prompt\":{\"type\":\"string\",\"description\":\"绘画提示词\"}}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/dalle3', 0); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_invite_codes` +-- + +DROP TABLE IF EXISTS `chatgpt_invite_codes`; +CREATE TABLE `chatgpt_invite_codes` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户ID', + `code` char(8) NOT NULL COMMENT '邀请码', + `hits` int NOT NULL COMMENT '点击次数', + `reg_num` smallint NOT NULL COMMENT '注册数量', + `created_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户邀请码'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_invite_logs` +-- + +DROP TABLE IF EXISTS `chatgpt_invite_logs`; +CREATE TABLE `chatgpt_invite_logs` ( + `id` int NOT NULL, + `inviter_id` int NOT NULL COMMENT '邀请人ID', + `user_id` int NOT NULL COMMENT '注册用户ID', + `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名', + `invite_code` char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '邀请码', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '备注', + `created_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='邀请注册日志'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_menus` +-- + +DROP TABLE IF EXISTS `chatgpt_menus`; +CREATE TABLE `chatgpt_menus` ( + `id` int NOT NULL, + `name` varchar(30) NOT NULL COMMENT '菜单名称', + `icon` varchar(150) NOT NULL COMMENT '菜单图标', + `url` varchar(100) NOT NULL COMMENT '地址', + `sort_num` smallint NOT NULL COMMENT '排序', + `enabled` tinyint(1) NOT NULL COMMENT '是否启用' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='前端菜单表'; + +-- +-- 转存表中的数据 `chatgpt_menus` +-- + +INSERT INTO `chatgpt_menus` (`id`, `name`, `icon`, `url`, `sort_num`, `enabled`) VALUES +(1, '对话聊天', '/images/menu/chat.png', '/chat', 1, 1), +(5, 'MJ 绘画', '/images/menu/mj.png', '/mj', 2, 1), +(6, 'SD 绘画', '/images/menu/sd.png', '/sd', 3, 1), +(7, '算力日志', '/images/menu/log.png', '/powerLog', 8, 1), +(8, '应用中心', '/images/menu/app.png', '/apps', 7, 1), +(9, '画廊', '/images/menu/img-wall.png', '/images-wall', 5, 1), +(10, '会员计划', '/images/menu/member.png', '/member', 9, 1), +(11, '分享计划', '/images/menu/share.png', '/invite', 10, 1), +(12, '思维导图', '/images/menu/xmind.png', '/xmind', 6, 1), +(13, 'DALLE', '/images/menu/dalle.png', '/dalle', 4, 1), +(14, '项目文档', '/images/menu/docs.png', 'https://ai.r9it.com/docs/', 11, 1), +(16, '极客论坛', '/images/menu/bbs.png', 'https://bbs.geekai.me/', 13, 1); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_mj_jobs` +-- + +DROP TABLE IF EXISTS `chatgpt_mj_jobs`; +CREATE TABLE `chatgpt_mj_jobs` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户 ID', + `task_id` varchar(20) DEFAULT NULL COMMENT '任务 ID', + `type` varchar(20) DEFAULT 'image' COMMENT '任务类别', + `message_id` char(40) NOT NULL COMMENT '消息 ID', + `channel_id` char(40) DEFAULT NULL COMMENT '频道ID', + `reference_id` char(40) DEFAULT NULL COMMENT '引用消息 ID', + `prompt` varchar(2000) NOT NULL COMMENT '会话提示词', + `img_url` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图片URL', + `org_url` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '原始图片地址', + `hash` varchar(100) DEFAULT NULL COMMENT 'message hash', + `progress` smallint DEFAULT '0' COMMENT '任务进度', + `use_proxy` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否使用反代', + `publish` tinyint(1) NOT NULL COMMENT '是否发布', + `err_msg` varchar(255) DEFAULT NULL COMMENT '错误信息', + `power` smallint NOT NULL DEFAULT '0' COMMENT '消耗算力', + `created_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='MidJourney 任务表'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_orders` +-- + +DROP TABLE IF EXISTS `chatgpt_orders`; +CREATE TABLE `chatgpt_orders` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户ID', + `product_id` int NOT NULL COMMENT '产品ID', + `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户明', + `order_no` varchar(30) NOT NULL COMMENT '订单ID', + `trade_no` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '支付平台交易流水号', + `subject` varchar(100) NOT NULL COMMENT '订单产品', + `amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '订单金额', + `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '订单状态(0:待支付,1:已扫码,2:支付成功)', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '备注', + `pay_time` int DEFAULT NULL COMMENT '支付时间', + `pay_way` varchar(20) NOT NULL COMMENT '支付方式', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `deleted_at` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='充值订单表'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_power_logs` +-- + +DROP TABLE IF EXISTS `chatgpt_power_logs`; +CREATE TABLE `chatgpt_power_logs` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户ID', + `username` varchar(30) NOT NULL COMMENT '用户名', + `type` tinyint(1) NOT NULL COMMENT '类型(1:充值,2:消费,3:退费)', + `amount` smallint NOT NULL COMMENT '算力数值', + `balance` int NOT NULL COMMENT '余额', + `model` varchar(30) NOT NULL COMMENT '模型', + `remark` varchar(255) NOT NULL COMMENT '备注', + `mark` tinyint(1) NOT NULL COMMENT '资金类型(0:支出,1:收入)', + `created_at` datetime NOT NULL COMMENT '创建时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户算力消费日志'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_products` +-- + +DROP TABLE IF EXISTS `chatgpt_products`; +CREATE TABLE `chatgpt_products` ( + `id` int NOT NULL, + `name` varchar(30) NOT NULL COMMENT '名称', + `price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '价格', + `discount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '优惠金额', + `days` smallint NOT NULL DEFAULT '0' COMMENT '延长天数', + `power` int NOT NULL DEFAULT '0' COMMENT '增加算力值', + `enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否启动', + `sales` int NOT NULL DEFAULT '0' COMMENT '销量', + `sort_num` tinyint NOT NULL DEFAULT '0' COMMENT '排序', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `app_url` varchar(255) DEFAULT NULL COMMENT 'App跳转地址', + `url` varchar(255) DEFAULT NULL COMMENT '跳转地址' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员套餐表'; + +-- +-- 转存表中的数据 `chatgpt_products` +-- + +INSERT INTO `chatgpt_products` (`id`, `name`, `price`, `discount`, `days`, `power`, `enabled`, `sales`, `sort_num`, `created_at`, `updated_at`, `app_url`, `url`) VALUES +(1, '会员1个月', 1999.90, 1999.00, 30, 0, 1, 1, 0, '2023-08-28 10:48:57', '2024-04-26 16:09:06', NULL, NULL), +(2, '会员3个月', 3940.00, 30.00, 90, 0, 1, 0, 0, '2023-08-28 10:52:22', '2024-03-22 17:56:10', NULL, NULL), +(3, '会员6个月', 5990.00, 100.00, 180, 0, 1, 0, 0, '2023-08-28 10:53:39', '2024-03-22 17:56:15', NULL, NULL), +(4, '会员12个月', 9980.00, 200.00, 365, 0, 1, 0, 0, '2023-08-28 10:54:15', '2024-03-22 17:56:23', NULL, NULL), +(5, '100次点卡', 9.99, 9.98, 0, 100, 1, 7, 0, '2023-08-28 10:55:08', '2024-06-11 16:48:44', NULL, NULL), +(6, '200次点卡', 19.90, 15.00, 0, 200, 1, 1, 0, '1970-01-01 08:00:00', '2024-06-11 11:41:52', NULL, NULL); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_rewards` +-- + +DROP TABLE IF EXISTS `chatgpt_rewards`; +CREATE TABLE `chatgpt_rewards` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户 ID', + `tx_id` char(36) NOT NULL COMMENT '交易 ID', + `amount` decimal(10,2) NOT NULL COMMENT '打赏金额', + `remark` varchar(80) NOT NULL COMMENT '备注', + `status` tinyint(1) NOT NULL COMMENT '核销状态,0:未核销,1:已核销', + `exchange` varchar(255) NOT NULL COMMENT '兑换详情(json)', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户打赏'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_sd_jobs` +-- + +DROP TABLE IF EXISTS `chatgpt_sd_jobs`; +CREATE TABLE `chatgpt_sd_jobs` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户 ID', + `type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT 'txt2img' COMMENT '任务类别', + `task_id` char(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务 ID', + `prompt` varchar(2000) NOT NULL COMMENT '会话提示词', + `img_url` varchar(255) DEFAULT NULL COMMENT '图片URL', + `params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '绘画参数json', + `progress` smallint DEFAULT '0' COMMENT '任务进度', + `publish` tinyint(1) NOT NULL COMMENT '是否发布', + `err_msg` varchar(255) DEFAULT NULL COMMENT '错误信息', + `power` smallint NOT NULL DEFAULT '0' COMMENT '消耗算力', + `created_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Stable Diffusion 任务表'; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_users` +-- + +DROP TABLE IF EXISTS `chatgpt_users`; +CREATE TABLE `chatgpt_users` ( + `id` int NOT NULL, + `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名', + `nickname` varchar(30) NOT NULL COMMENT '昵称', + `password` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码', + `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '头像', + `salt` char(12) NOT NULL COMMENT '密码盐', + `power` int NOT NULL DEFAULT '0' COMMENT '剩余算力', + `expired_time` int NOT NULL COMMENT '用户过期时间', + `status` tinyint(1) NOT NULL COMMENT '当前状态', + `chat_config_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '聊天配置json', + `chat_roles_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '聊天角色 json', + `chat_models_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'AI模型 json', + `last_login_at` int NOT NULL COMMENT '最后登录时间', + `vip` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否会员', + `last_login_ip` char(16) NOT NULL COMMENT '最后登录 IP', + `openid` varchar(100) DEFAULT NULL COMMENT '第三方登录账号ID', + `platform` varchar(30) DEFAULT NULL COMMENT '登录平台', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表'; + +-- +-- 转存表中的数据 `chatgpt_users` +-- + +INSERT INTO `chatgpt_users` (`id`, `username`, `nickname`, `password`, `avatar`, `salt`, `power`, `expired_time`, `status`, `chat_config_json`, `chat_roles_json`, `chat_models_json`, `last_login_at`, `vip`, `last_login_ip`, `openid`, `platform`, `created_at`, `updated_at`) VALUES +(4, '18575670125', '极客学长@830270', 'ccc3fb7ab61b8b5d096a4a166ae21d121fc38c71bbd1be6173d9ab973214a63b', 'http://localhost:5678/static/upload/2024/5/1715651569509929.png', 'ueedue5l', 7413, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"red_book\",\"gpt\",\"seller\",\"artist\",\"lu_xun\",\"girl_friend\",\"psychiatrist\",\"teacher\",\"programmer\",\"test\",\"qing_gan_da_shi\"]', '[1,11]', 1720683366, 1, '172.22.11.29', NULL, NULL, '2023-06-12 16:47:17', '2024-07-12 16:08:39'), +(5, 'yangjian102621@gmail.com', '极客学长@486041', '75d1a22f33e1ffffb7943946b6b8d5177d5ecd685d3cef1b468654038b0a8c22', '/images/avatar/user.png', '2q8ugxzk', 100, 0, 1, '', '[\"gpt\",\"programmer\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-23 09:17:26', '2024-04-23 09:17:26'), +(8, 'yangjian102623@gmail.com', '极客学长@714931', 'f8f0e0abf146569217273ea0712a0f9b6cbbe7d943a1d9bd5f91c55e6d8c05d1', '/images/avatar/user.png', 'geuddq7f', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-26 15:19:28', '2024-04-26 15:19:28'), +(9, '1234567', '极客学长@604526', '858e2afec79e1d6364f4567f945f2310024896d9aa45dd944efa95a0c31e4d08', '/images/avatar/user.png', '00qawlos', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-26 15:21:06', '2024-04-26 15:21:06'), +(11, 'abc123', '极客学长@965562', '7a15c53afdb1da7093d80f9940e716eb396e682cfb1f2d107d0b81b183a3ba13', '/images/avatar/user.png', '6433mfbk', 1124, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-06-06 09:37:44', '2024-06-06 09:37:44'), +(14, 'wx@3567548322', '极客学长', '5a349ba89582a4074938b5a3ce84e87c937681ad47e8b87aab03a987e22b6077', 'https://thirdwx.qlogo.cn/mmopen/vi_32/uyxRMqZcEkb7fHouKXbNzxrnrvAttBKkwNlZ7yFibibRGiahdmsrZ3A1NKf8Fw5qJNJn4TXRmygersgEbibaSGd9Sg/132', 'abhzbmij', 83, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', 'oCs0t62472W19z2LOEKI1rWyCTTA', '', '2024-07-04 14:52:08', '2024-07-04 14:52:08'), +(15, 'user123', '极客学长@191303', '4a4c0a14d5fc8787357517f14f6e442281b42c8ec4395016b77483997476011e', '/images/avatar/user.png', 'cyzwkbrx', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-09 10:49:27', '2024-07-09 10:49:27'), +(17, 'user1234', '极客学长@836764', 'bfe03c9c8c9fff5b77e36e40e8298ad3a6073d43c6a936b008eebb21113bf550', '/images/avatar/user.png', '1d2alwnj', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-09 10:53:17', '2024-07-09 10:53:17'), +(18, 'liaoyq', '极客学长@405564', 'ad1726089022db4c661235a8aab7307af1a7f8483eee08bac3f79b5a6a9bd26b', '/images/avatar/user.png', 'yq862l01', 100, 0, 1, '', '[\"string\"]', '[11,7,1,10,12,19,18,17,3]', 1720574265, 0, '172.22.11.29', '', '', '2024-07-10 09:15:33', '2024-07-10 09:17:45'), +(19, 'humm', '极客学长@483216', '420970ace96921c8b3ac7668d097182eab1b6436c730a484e82ae4661bd4f7d9', '/images/avatar/user.png', '1gokrcl2', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 1720745411, 0, '172.22.11.36', '', '', '2024-07-10 11:08:31', '2024-07-12 08:50:11'), +(20, 'abc', '极客学长@369852', '6cad48fb2cc0f54600d66a829e9be69ffd9340a49d5a5b1abda5d4082d946833', '/images/avatar/user.png', 'gop65zei', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-11 16:44:14', '2024-07-11 16:44:14'), +(21, 'husm@pvc123.com', '极客学长@721654', 'e030537dc43fea1bf1fa55a24f99e44f29311bebea96e88ea186995c77db083b', '/images/avatar/user.png', 'p1etg3oi', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-11 16:50:33', '2024-07-11 16:50:33'), +(22, '15818323616', 'ted', '3ca6b2ff585d03be8ca4de33ad00148497a09372914ee8aa4cfde343266cbcdd', 'http://localhost:5678/static/upload/2024/7/1720775331363383.jpg', 'sq4s1brf', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-12 15:12:16', '2024-07-12 17:09:01'); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `chatgpt_user_login_logs` +-- + +DROP TABLE IF EXISTS `chatgpt_user_login_logs`; +CREATE TABLE `chatgpt_user_login_logs` ( + `id` int NOT NULL, + `user_id` int NOT NULL COMMENT '用户ID', + `username` varchar(30) NOT NULL COMMENT '用户名', + `login_ip` char(16) NOT NULL COMMENT '登录IP', + `login_address` varchar(30) NOT NULL COMMENT '登录地址', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户登录日志'; + +-- +-- 转储表的索引 +-- + +-- +-- 表的索引 `chatgpt_admin_users` +-- +ALTER TABLE `chatgpt_admin_users` + ADD PRIMARY KEY (`id`) USING BTREE, + ADD UNIQUE KEY `username` (`username`) USING BTREE; + +-- +-- 表的索引 `chatgpt_api_keys` +-- +ALTER TABLE `chatgpt_api_keys` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_chat_history` +-- +ALTER TABLE `chatgpt_chat_history` + ADD PRIMARY KEY (`id`), + ADD KEY `chat_id` (`chat_id`); + +-- +-- 表的索引 `chatgpt_chat_items` +-- +ALTER TABLE `chatgpt_chat_items` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `chat_id` (`chat_id`); + +-- +-- 表的索引 `chatgpt_chat_models` +-- +ALTER TABLE `chatgpt_chat_models` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_chat_roles` +-- +ALTER TABLE `chatgpt_chat_roles` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `marker` (`marker`); + +-- +-- 表的索引 `chatgpt_configs` +-- +ALTER TABLE `chatgpt_configs` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `marker` (`marker`); + +-- +-- 表的索引 `chatgpt_dall_jobs` +-- +ALTER TABLE `chatgpt_dall_jobs` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_files` +-- +ALTER TABLE `chatgpt_files` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_functions` +-- +ALTER TABLE `chatgpt_functions` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `name` (`name`); + +-- +-- 表的索引 `chatgpt_invite_codes` +-- +ALTER TABLE `chatgpt_invite_codes` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `code` (`code`); + +-- +-- 表的索引 `chatgpt_invite_logs` +-- +ALTER TABLE `chatgpt_invite_logs` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_menus` +-- +ALTER TABLE `chatgpt_menus` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_mj_jobs` +-- +ALTER TABLE `chatgpt_mj_jobs` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `task_id` (`task_id`), + ADD KEY `message_id` (`message_id`); + +-- +-- 表的索引 `chatgpt_orders` +-- +ALTER TABLE `chatgpt_orders` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `order_no` (`order_no`); + +-- +-- 表的索引 `chatgpt_power_logs` +-- +ALTER TABLE `chatgpt_power_logs` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_products` +-- +ALTER TABLE `chatgpt_products` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `chatgpt_rewards` +-- +ALTER TABLE `chatgpt_rewards` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `tx_id` (`tx_id`); + +-- +-- 表的索引 `chatgpt_sd_jobs` +-- +ALTER TABLE `chatgpt_sd_jobs` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `task_id` (`task_id`); + +-- +-- 表的索引 `chatgpt_users` +-- +ALTER TABLE `chatgpt_users` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `username` (`username`); + +-- +-- 表的索引 `chatgpt_user_login_logs` +-- +ALTER TABLE `chatgpt_user_login_logs` + ADD PRIMARY KEY (`id`); + +-- +-- 在导出的表使用AUTO_INCREMENT +-- + +-- +-- 使用表AUTO_INCREMENT `chatgpt_admin_users` +-- +ALTER TABLE `chatgpt_admin_users` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=113; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_api_keys` +-- +ALTER TABLE `chatgpt_api_keys` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_chat_history` +-- +ALTER TABLE `chatgpt_chat_history` + MODIFY `id` bigint NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_chat_items` +-- +ALTER TABLE `chatgpt_chat_items` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_chat_models` +-- +ALTER TABLE `chatgpt_chat_models` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=44; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_chat_roles` +-- +ALTER TABLE `chatgpt_chat_roles` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=132; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_configs` +-- +ALTER TABLE `chatgpt_configs` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_dall_jobs` +-- +ALTER TABLE `chatgpt_dall_jobs` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_files` +-- +ALTER TABLE `chatgpt_files` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_functions` +-- +ALTER TABLE `chatgpt_functions` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_invite_codes` +-- +ALTER TABLE `chatgpt_invite_codes` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_invite_logs` +-- +ALTER TABLE `chatgpt_invite_logs` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_menus` +-- +ALTER TABLE `chatgpt_menus` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=19; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_mj_jobs` +-- +ALTER TABLE `chatgpt_mj_jobs` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_orders` +-- +ALTER TABLE `chatgpt_orders` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_power_logs` +-- +ALTER TABLE `chatgpt_power_logs` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_products` +-- +ALTER TABLE `chatgpt_products` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_rewards` +-- +ALTER TABLE `chatgpt_rewards` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_sd_jobs` +-- +ALTER TABLE `chatgpt_sd_jobs` + MODIFY `id` int NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_users` +-- +ALTER TABLE `chatgpt_users` + MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=23; + +-- +-- 使用表AUTO_INCREMENT `chatgpt_user_login_logs` +-- +ALTER TABLE `chatgpt_user_login_logs` + MODIFY `id` int NOT NULL AUTO_INCREMENT; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/deploy/docker-compose.yaml b/deploy/docker-compose.yaml index bbe67468..aed6fdc2 100644 --- a/deploy/docker-compose.yaml +++ b/deploy/docker-compose.yaml @@ -39,6 +39,12 @@ services: - ./logs/xxl-job:/data/applogs - ./conf/xxl-job/application.properties:/application.properties + tika: + image: "registry.cn-shenzhen.aliyuncs.com/geekmaster/tika:latest" + container_name: "tika" + restart: always + ports: + - "9998:9998" midjourney-proxy: image: registry.cn-shenzhen.aliyuncs.com/geekmaster/midjourney-proxy:2.6.2 diff --git a/web/.env.development b/web/.env.development index 5a9770cd..23f5535c 100644 --- a/web/.env.development +++ b/web/.env.development @@ -7,3 +7,5 @@ VUE_APP_ADMIN_PASS=admin123 VUE_APP_KEY_PREFIX=ChatPLUS_DEV_ VUE_APP_TITLE="Geek-AI 创作系统" VUE_APP_VERSION=v4.1.0 +VUE_APP_DOCS_URL=https://docs.geekai.me +VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai diff --git a/web/.env.production b/web/.env.production index 8afbdcae..6a07e76e 100644 --- a/web/.env.production +++ b/web/.env.production @@ -3,3 +3,5 @@ VUE_APP_WS_HOST= VUE_APP_KEY_PREFIX=ChatPLUS_ VUE_APP_TITLE="Geek-AI 创作系统" VUE_APP_VERSION=v4.1.0 +VUE_APP_DOCS_URL=https://docs.geekai.me +VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai diff --git a/web/src/components/FooterBar.vue b/web/src/components/FooterBar.vue index a8b263e9..f2e106a5 100644 --- a/web/src/components/FooterBar.vue +++ b/web/src/components/FooterBar.vue @@ -2,7 +2,7 @@