From 6c7fa17e506297d4a95461089929ec730f317510 Mon Sep 17 00:00:00 2001 From: RockYang Date: Fri, 13 Sep 2024 17:03:05 +0800 Subject: [PATCH] fixed bug, filelist page support pagination, do not load captcha component for user login first time --- CHANGELOG.md | 1 + api/handler/admin/chat_app_type_handler.go | 6 +++--- api/handler/user_handler.go | 12 +++++++++--- web/.env.production | 2 +- web/src/components/ChatPrompt.vue | 2 +- web/src/components/FileList.vue | 1 + web/src/components/FileSelect.vue | 2 +- web/src/components/LoginDialog.vue | 10 +++++++--- web/src/views/ChatPlus.vue | 7 +++---- web/src/views/Login.vue | 7 +++++-- web/src/views/Suno.vue | 2 +- 11 files changed, 33 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08e9116e..857a200c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v4.1.4 * 功能优化:用户文件列表组件增加分页功能支持 * Bug修复:修复用户注册失败Bug,注册操作只弹出一次行为验证码 +* 功能优化:首次登录不需要验证码,直接登录,登录失败之后才弹出验证码 ## v4.1.3 * 功能优化:重构用户登录模块,给所有的登录组件增加行为验证码功能,支持用户绑定手机,邮箱和微信 diff --git a/api/handler/admin/chat_app_type_handler.go b/api/handler/admin/chat_app_type_handler.go index d462f42c..d842a279 100644 --- a/api/handler/admin/chat_app_type_handler.go +++ b/api/handler/admin/chat_app_type_handler.go @@ -25,7 +25,7 @@ func (h *ChatAppTypeHandler) Save(c *gin.Context) { var data struct { Id uint `json:"id"` Name string `json:"name"` - Enable bool `json:"enable"` + Enabled bool `json:"enabled"` Icon string `json:"icon"` SortNum int `json:"sort_num"` } @@ -43,7 +43,7 @@ func (h *ChatAppTypeHandler) Save(c *gin.Context) { err = h.DB.Create(&model.AppType{ Name: data.Name, Icon: data.Icon, - Enabled: data.Enable, + Enabled: data.Enabled, SortNum: data.SortNum, }).Error if err != nil { @@ -54,7 +54,7 @@ func (h *ChatAppTypeHandler) Save(c *gin.Context) { err := h.DB.Model(&model.AppType{}).Where("id", data.Id).Updates(map[string]interface{}{ "name": data.Name, "icon": data.Icon, - "enabled": data.Enable, + "enabled": data.Enabled, }).Error if err != nil { resp.ERROR(c, err.Error()) diff --git a/api/handler/user_handler.go b/api/handler/user_handler.go index de7a9657..3b93310b 100644 --- a/api/handler/user_handler.go +++ b/api/handler/user_handler.go @@ -244,8 +244,10 @@ func (h *UserHandler) Login(c *gin.Context) { resp.ERROR(c, types.InvalidArgs) return } + verifyKey := fmt.Sprintf("users/verify/%s", data.Username) + needVerify, err := h.redis.Get(c, verifyKey).Bool() - if h.App.SysConfig.EnabledVerify { + if h.App.SysConfig.EnabledVerify && needVerify { var check bool if data.X != 0 { check = h.captcha.SlideCheck(data) @@ -261,12 +263,14 @@ func (h *UserHandler) Login(c *gin.Context) { var user model.User res := h.DB.Where("username = ?", data.Username).First(&user) if res.Error != nil { + h.redis.Set(c, verifyKey, true, 0) resp.ERROR(c, "用户名不存在") return } password := utils.GenPassword(data.Password, user.Salt) if password != user.Password { + h.redis.Set(c, verifyKey, true, 0) resp.ERROR(c, "用户名或密码错误") return } @@ -299,11 +303,13 @@ func (h *UserHandler) Login(c *gin.Context) { return } // 保存到 redis - key := fmt.Sprintf("users/%d", user.Id) - if _, err := h.redis.Set(c, key, tokenString, 0).Result(); err != nil { + sessionKey := fmt.Sprintf("users/%d", user.Id) + if _, err = h.redis.Set(c, sessionKey, tokenString, 0).Result(); err != nil { resp.ERROR(c, "error with save token: "+err.Error()) return } + // 移除登录行为验证码 + h.redis.Del(c, verifyKey) resp.SUCCESS(c, gin.H{"token": tokenString, "user_id": user.Id, "username": user.Username}) } diff --git a/web/.env.production b/web/.env.production index fee207e7..056d8338 100644 --- a/web/.env.production +++ b/web/.env.production @@ -1,6 +1,6 @@ VUE_APP_API_HOST= VUE_APP_WS_HOST= VUE_APP_KEY_PREFIX=GeekAI_ -VUE_APP_VERSION=v4.1.4 +VUE_APP_VERSION=v4.1.3 VUE_APP_DOCS_URL=https://docs.geekai.me VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai diff --git a/web/src/components/ChatPrompt.vue b/web/src/components/ChatPrompt.vue index 92dd392c..518ce2f4 100644 --- a/web/src/components/ChatPrompt.vue +++ b/web/src/components/ChatPrompt.vue @@ -143,7 +143,7 @@ onMounted(() => { const links = props.data.content.match(linkRegex); if (links) { httpPost("/api/upload/list", {urls: links}).then(res => { - files.value = res.data + files.value = res.data.items for (let link of links) { if (isExternalImg(link, files.value)) { diff --git a/web/src/components/FileList.vue b/web/src/components/FileList.vue index b503b922..8bf96897 100644 --- a/web/src/components/FileList.vue +++ b/web/src/components/FileList.vue @@ -60,6 +60,7 @@ const removeFile = (file) => { display flex flex-flow row margin-right 10px + max-width 600px position relative .el-image { diff --git a/web/src/components/FileSelect.vue b/web/src/components/FileSelect.vue index d340c460..554fb209 100644 --- a/web/src/components/FileSelect.vue +++ b/web/src/components/FileSelect.vue @@ -68,7 +68,7 @@ const fileList = ref([]) const fetchFiles = () => { show.value = true httpPost("/api/upload/list").then(res => { - fileList.value = res.data + fileList.value = res.data.items }).catch(() => { }) } diff --git a/web/src/components/LoginDialog.vue b/web/src/components/LoginDialog.vue index 6af69740..58f81428 100644 --- a/web/src/components/LoginDialog.vue +++ b/web/src/components/LoginDialog.vue @@ -263,8 +263,8 @@ watch(() => props.show, (newValue) => { const login = ref(true) const data = ref({ - username: "", - password: "", + username: process.env.VUE_APP_USER, + password: process.env.VUE_APP_PASS, mobile: "", email: "", repass: "", @@ -285,6 +285,8 @@ const action = ref("login") const enableVerify = ref(false) const showResetPass = ref(false) const router = useRouter() +// 是否需要验证码,输入一次密码错之后就要验证码 +const needVerify = ref(false) onMounted(() => { const returnURL = `${location.protocol}//${location.host}/login/callback?action=login` @@ -338,7 +340,7 @@ const submitLogin = () => { if (data.value.password === '') { return ElMessage.error('请输入密码'); } - if (enableVerify.value) { + if (enableVerify.value && needVerify.value) { captchaRef.value.loadCaptcha() action.value = "login" } else { @@ -355,8 +357,10 @@ const doLogin = (verifyData) => { ElMessage.success("登录成功!") emits("hide") emits('success') + needVerify.value = false }).catch((e) => { ElMessage.error('登录失败,' + e.message) + needVerify.value = true }) } diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index 48161be4..389c2b1a 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -349,7 +349,6 @@ onMounted(() => { onUnmounted(() => { if (socket.value !== null) { - socket.value.close() socket.value = null } }) @@ -518,9 +517,9 @@ const loadChat = function (chat) { modelID.value = chat.model_id; chatId.value = chat.chat_id; showStopGenerate.value = false; - router.push(`/chat/${chatId.value}`) loadHistory.value = true - socket.value.close() + connect() + router.replace(`/chat/${chatId.value}`) } // 编辑会话标题 @@ -757,7 +756,7 @@ const sendMessage = function () { if (files.value.length === 1) { content += files.value.map(file => file.url).join(" ") } else if (files.value.length > 1) { - showMessageError("当前只支持一个文件!") + showMessageError("当前只支持上传一个文件!") return false } // 追加消息 diff --git a/web/src/views/Login.vue b/web/src/views/Login.vue index d0ad1b66..9a9f7a14 100644 --- a/web/src/views/Login.vue +++ b/web/src/views/Login.vue @@ -76,7 +76,6 @@ import {setUserToken} from "@/store/session"; import ResetPass from "@/components/ResetPass.vue"; import {showMessageError} from "@/utils/dialog"; import Captcha from "@/components/Captcha.vue"; -import QRCode from "qrcode"; import {setRoute} from "@/store/system"; const router = useRouter(); @@ -89,6 +88,8 @@ const licenseConfig = ref({}) const wechatLoginURL = ref('') const enableVerify = ref(false) const captchaRef = ref(null) +// 是否需要验证码,输入一次密码错之后就要验证码 +const needVerify = ref(false) onMounted(() => { // 获取系统配置 @@ -137,7 +138,7 @@ const login = function () { return showMessageError('请输入密码'); } - if (enableVerify.value) { + if (enableVerify.value && needVerify.value) { captchaRef.value.loadCaptcha() } else { doLogin({}) @@ -153,6 +154,7 @@ const doLogin = (verifyData) => { x: verifyData.x }).then((res) => { setUserToken(res.data.token) + needVerify.value = false if (isMobile()) { router.push('/mobile') } else { @@ -161,6 +163,7 @@ const doLogin = (verifyData) => { }).catch((e) => { showMessageError('登录失败,' + e.message) + needVerify.value = true }) } diff --git a/web/src/views/Suno.vue b/web/src/views/Suno.vue index b5a58832..92aa4fcc 100644 --- a/web/src/views/Suno.vue +++ b/web/src/views/Suno.vue @@ -610,7 +610,7 @@ const publishJob = (item) => { } const getShareURL = (item) => { - return `${location.protocol}//${location.host}/song/${item.id}` + return `${location.protocol}//${location.host}/song/${item.song_id}` } const uploadCover = (file) => {