fixed bug, filelist page support pagination, do not load captcha component for user login first time

This commit is contained in:
RockYang 2024-09-13 17:03:05 +08:00
parent 5c77e67b0f
commit 6c7fa17e50
11 changed files with 33 additions and 19 deletions

View File

@ -2,6 +2,7 @@
## v4.1.4 ## v4.1.4
* 功能优化:用户文件列表组件增加分页功能支持 * 功能优化:用户文件列表组件增加分页功能支持
* Bug修复修复用户注册失败Bug注册操作只弹出一次行为验证码 * Bug修复修复用户注册失败Bug注册操作只弹出一次行为验证码
* 功能优化:首次登录不需要验证码,直接登录,登录失败之后才弹出验证码
## v4.1.3 ## v4.1.3
* 功能优化:重构用户登录模块,给所有的登录组件增加行为验证码功能,支持用户绑定手机,邮箱和微信 * 功能优化:重构用户登录模块,给所有的登录组件增加行为验证码功能,支持用户绑定手机,邮箱和微信

View File

@ -25,7 +25,7 @@ func (h *ChatAppTypeHandler) Save(c *gin.Context) {
var data struct { var data struct {
Id uint `json:"id"` Id uint `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Enable bool `json:"enable"` Enabled bool `json:"enabled"`
Icon string `json:"icon"` Icon string `json:"icon"`
SortNum int `json:"sort_num"` SortNum int `json:"sort_num"`
} }
@ -43,7 +43,7 @@ func (h *ChatAppTypeHandler) Save(c *gin.Context) {
err = h.DB.Create(&model.AppType{ err = h.DB.Create(&model.AppType{
Name: data.Name, Name: data.Name,
Icon: data.Icon, Icon: data.Icon,
Enabled: data.Enable, Enabled: data.Enabled,
SortNum: data.SortNum, SortNum: data.SortNum,
}).Error }).Error
if err != nil { 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{}{ err := h.DB.Model(&model.AppType{}).Where("id", data.Id).Updates(map[string]interface{}{
"name": data.Name, "name": data.Name,
"icon": data.Icon, "icon": data.Icon,
"enabled": data.Enable, "enabled": data.Enabled,
}).Error }).Error
if err != nil { if err != nil {
resp.ERROR(c, err.Error()) resp.ERROR(c, err.Error())

View File

@ -244,8 +244,10 @@ func (h *UserHandler) Login(c *gin.Context) {
resp.ERROR(c, types.InvalidArgs) resp.ERROR(c, types.InvalidArgs)
return 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 var check bool
if data.X != 0 { if data.X != 0 {
check = h.captcha.SlideCheck(data) check = h.captcha.SlideCheck(data)
@ -261,12 +263,14 @@ func (h *UserHandler) Login(c *gin.Context) {
var user model.User var user model.User
res := h.DB.Where("username = ?", data.Username).First(&user) res := h.DB.Where("username = ?", data.Username).First(&user)
if res.Error != nil { if res.Error != nil {
h.redis.Set(c, verifyKey, true, 0)
resp.ERROR(c, "用户名不存在") resp.ERROR(c, "用户名不存在")
return return
} }
password := utils.GenPassword(data.Password, user.Salt) password := utils.GenPassword(data.Password, user.Salt)
if password != user.Password { if password != user.Password {
h.redis.Set(c, verifyKey, true, 0)
resp.ERROR(c, "用户名或密码错误") resp.ERROR(c, "用户名或密码错误")
return return
} }
@ -299,11 +303,13 @@ func (h *UserHandler) Login(c *gin.Context) {
return return
} }
// 保存到 redis // 保存到 redis
key := fmt.Sprintf("users/%d", user.Id) sessionKey := fmt.Sprintf("users/%d", user.Id)
if _, err := h.redis.Set(c, key, tokenString, 0).Result(); err != nil { if _, err = h.redis.Set(c, sessionKey, tokenString, 0).Result(); err != nil {
resp.ERROR(c, "error with save token: "+err.Error()) resp.ERROR(c, "error with save token: "+err.Error())
return return
} }
// 移除登录行为验证码
h.redis.Del(c, verifyKey)
resp.SUCCESS(c, gin.H{"token": tokenString, "user_id": user.Id, "username": user.Username}) resp.SUCCESS(c, gin.H{"token": tokenString, "user_id": user.Id, "username": user.Username})
} }

View File

@ -1,6 +1,6 @@
VUE_APP_API_HOST= VUE_APP_API_HOST=
VUE_APP_WS_HOST= VUE_APP_WS_HOST=
VUE_APP_KEY_PREFIX=GeekAI_ 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_DOCS_URL=https://docs.geekai.me
VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai

View File

@ -143,7 +143,7 @@ onMounted(() => {
const links = props.data.content.match(linkRegex); const links = props.data.content.match(linkRegex);
if (links) { if (links) {
httpPost("/api/upload/list", {urls: links}).then(res => { httpPost("/api/upload/list", {urls: links}).then(res => {
files.value = res.data files.value = res.data.items
for (let link of links) { for (let link of links) {
if (isExternalImg(link, files.value)) { if (isExternalImg(link, files.value)) {

View File

@ -60,6 +60,7 @@ const removeFile = (file) => {
display flex display flex
flex-flow row flex-flow row
margin-right 10px margin-right 10px
max-width 600px
position relative position relative
.el-image { .el-image {

View File

@ -68,7 +68,7 @@ const fileList = ref([])
const fetchFiles = () => { const fetchFiles = () => {
show.value = true show.value = true
httpPost("/api/upload/list").then(res => { httpPost("/api/upload/list").then(res => {
fileList.value = res.data fileList.value = res.data.items
}).catch(() => { }).catch(() => {
}) })
} }

View File

@ -263,8 +263,8 @@ watch(() => props.show, (newValue) => {
const login = ref(true) const login = ref(true)
const data = ref({ const data = ref({
username: "", username: process.env.VUE_APP_USER,
password: "", password: process.env.VUE_APP_PASS,
mobile: "", mobile: "",
email: "", email: "",
repass: "", repass: "",
@ -285,6 +285,8 @@ const action = ref("login")
const enableVerify = ref(false) const enableVerify = ref(false)
const showResetPass = ref(false) const showResetPass = ref(false)
const router = useRouter() const router = useRouter()
//
const needVerify = ref(false)
onMounted(() => { onMounted(() => {
const returnURL = `${location.protocol}//${location.host}/login/callback?action=login` const returnURL = `${location.protocol}//${location.host}/login/callback?action=login`
@ -338,7 +340,7 @@ const submitLogin = () => {
if (data.value.password === '') { if (data.value.password === '') {
return ElMessage.error('请输入密码'); return ElMessage.error('请输入密码');
} }
if (enableVerify.value) { if (enableVerify.value && needVerify.value) {
captchaRef.value.loadCaptcha() captchaRef.value.loadCaptcha()
action.value = "login" action.value = "login"
} else { } else {
@ -355,8 +357,10 @@ const doLogin = (verifyData) => {
ElMessage.success("登录成功!") ElMessage.success("登录成功!")
emits("hide") emits("hide")
emits('success') emits('success')
needVerify.value = false
}).catch((e) => { }).catch((e) => {
ElMessage.error('登录失败,' + e.message) ElMessage.error('登录失败,' + e.message)
needVerify.value = true
}) })
} }

View File

@ -349,7 +349,6 @@ onMounted(() => {
onUnmounted(() => { onUnmounted(() => {
if (socket.value !== null) { if (socket.value !== null) {
socket.value.close()
socket.value = null socket.value = null
} }
}) })
@ -518,9 +517,9 @@ const loadChat = function (chat) {
modelID.value = chat.model_id; modelID.value = chat.model_id;
chatId.value = chat.chat_id; chatId.value = chat.chat_id;
showStopGenerate.value = false; showStopGenerate.value = false;
router.push(`/chat/${chatId.value}`)
loadHistory.value = true loadHistory.value = true
socket.value.close() connect()
router.replace(`/chat/${chatId.value}`)
} }
// //
@ -757,7 +756,7 @@ const sendMessage = function () {
if (files.value.length === 1) { if (files.value.length === 1) {
content += files.value.map(file => file.url).join(" ") content += files.value.map(file => file.url).join(" ")
} else if (files.value.length > 1) { } else if (files.value.length > 1) {
showMessageError("当前只支持一个文件!") showMessageError("当前只支持上传一个文件!")
return false return false
} }
// //

View File

@ -76,7 +76,6 @@ import {setUserToken} from "@/store/session";
import ResetPass from "@/components/ResetPass.vue"; import ResetPass from "@/components/ResetPass.vue";
import {showMessageError} from "@/utils/dialog"; import {showMessageError} from "@/utils/dialog";
import Captcha from "@/components/Captcha.vue"; import Captcha from "@/components/Captcha.vue";
import QRCode from "qrcode";
import {setRoute} from "@/store/system"; import {setRoute} from "@/store/system";
const router = useRouter(); const router = useRouter();
@ -89,6 +88,8 @@ const licenseConfig = ref({})
const wechatLoginURL = ref('') const wechatLoginURL = ref('')
const enableVerify = ref(false) const enableVerify = ref(false)
const captchaRef = ref(null) const captchaRef = ref(null)
//
const needVerify = ref(false)
onMounted(() => { onMounted(() => {
// //
@ -137,7 +138,7 @@ const login = function () {
return showMessageError('请输入密码'); return showMessageError('请输入密码');
} }
if (enableVerify.value) { if (enableVerify.value && needVerify.value) {
captchaRef.value.loadCaptcha() captchaRef.value.loadCaptcha()
} else { } else {
doLogin({}) doLogin({})
@ -153,6 +154,7 @@ const doLogin = (verifyData) => {
x: verifyData.x x: verifyData.x
}).then((res) => { }).then((res) => {
setUserToken(res.data.token) setUserToken(res.data.token)
needVerify.value = false
if (isMobile()) { if (isMobile()) {
router.push('/mobile') router.push('/mobile')
} else { } else {
@ -161,6 +163,7 @@ const doLogin = (verifyData) => {
}).catch((e) => { }).catch((e) => {
showMessageError('登录失败,' + e.message) showMessageError('登录失败,' + e.message)
needVerify.value = true
}) })
} }
</script> </script>

View File

@ -610,7 +610,7 @@ const publishJob = (item) => {
} }
const getShareURL = (item) => { const getShareURL = (item) => {
return `${location.protocol}//${location.host}/song/${item.id}` return `${location.protocol}//${location.host}/song/${item.song_id}`
} }
const uploadCover = (file) => { const uploadCover = (file) => {