mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	fixed bug, filelist page support pagination, do not load captcha component for user login first time
This commit is contained in:
		@@ -2,6 +2,7 @@
 | 
			
		||||
## v4.1.4
 | 
			
		||||
* 功能优化:用户文件列表组件增加分页功能支持
 | 
			
		||||
* Bug修复:修复用户注册失败Bug,注册操作只弹出一次行为验证码
 | 
			
		||||
* 功能优化:首次登录不需要验证码,直接登录,登录失败之后才弹出验证码
 | 
			
		||||
 | 
			
		||||
## v4.1.3
 | 
			
		||||
* 功能优化:重构用户登录模块,给所有的登录组件增加行为验证码功能,支持用户绑定手机,邮箱和微信
 | 
			
		||||
 
 | 
			
		||||
@@ -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())
 | 
			
		||||
 
 | 
			
		||||
@@ -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})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,7 @@ const removeFile = (file) => {
 | 
			
		||||
    display flex
 | 
			
		||||
    flex-flow row
 | 
			
		||||
    margin-right 10px
 | 
			
		||||
    max-width 600px
 | 
			
		||||
    position relative
 | 
			
		||||
 | 
			
		||||
    .el-image {
 | 
			
		||||
 
 | 
			
		||||
@@ -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(() => {
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  }
 | 
			
		||||
  // 追加消息
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -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) => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user