|
66 | 66 | size="large" |
67 | 67 | class="input-item" |
68 | 68 | v-model="loginForm.username" |
| 69 | + @blur="handleUsernameBlur(loginForm.username)" |
69 | 70 | :placeholder="$t('views.login.loginForm.username.placeholder')" |
70 | 71 | > |
71 | 72 | </el-input> |
|
84 | 85 | </el-input> |
85 | 86 | </el-form-item> |
86 | 87 | </div> |
87 | | - <div class="mb-24" v-if="loginMode !== 'LDAP'"> |
| 88 | + <div class="mb-24" v-if="loginMode !== 'LDAP'&& showCaptcha"> |
88 | 89 | <el-form-item prop="captcha"> |
89 | 90 | <div class="flex-between w-full"> |
90 | 91 | <el-input |
|
100 | 101 | alt="" |
101 | 102 | height="38" |
102 | 103 | class="ml-8 cursor border border-r-6" |
103 | | - @click="makeCode" |
| 104 | + @click="makeCode(loginForm.username)" |
104 | 105 | /> |
105 | 106 | </div> |
106 | 107 | </el-form-item> |
@@ -212,6 +213,7 @@ const loginForm = ref<LoginRequest>({ |
212 | 213 | captcha: '', |
213 | 214 | }) |
214 | 215 |
|
| 216 | +const max_attempts = ref<number>(1) // 声明为 ref |
215 | 217 | const rules = ref<FormRules<LoginRequest>>({ |
216 | 218 | username: [ |
217 | 219 | { |
@@ -253,20 +255,30 @@ const loginHandle = () => { |
253 | 255 | params: {accessToken: chatUser.accessToken}, |
254 | 256 | query: route.query, |
255 | 257 | }) |
| 258 | + localStorage.removeItem('chat_' + loginForm.value.username) |
| 259 | + }).catch(() => { |
| 260 | + const username = loginForm.value.username |
| 261 | + localStorage.setItem('chat_' + username, String(Number(localStorage.getItem('chat_' + username) || '0') + 1)) |
| 262 | + loading.value = false |
| 263 | + loginForm.value.username = '' |
| 264 | + loginForm.value.password = '' |
| 265 | + const timestampKey = `${username}_chat_first_fail_timestamp` |
| 266 | + if (!localStorage.getItem(timestampKey)) { |
| 267 | + localStorage.setItem(timestampKey, Date.now().toString()) |
| 268 | + } |
256 | 269 | }) |
257 | 270 | } |
258 | 271 | }) |
259 | 272 | } |
260 | 273 |
|
261 | | -function makeCode(userrname?: string) { |
262 | | - loginApi.getCaptcha(userrname).then((res: any) => { |
| 274 | +function makeCode(username?: string) { |
| 275 | + loginApi.getCaptcha(username).then((res: any) => { |
263 | 276 | identifyCode.value = res.data.captcha |
264 | 277 | }) |
265 | 278 | } |
266 | 279 |
|
267 | 280 | onBeforeMount(() => { |
268 | 281 | locale.value = chatUser.getLanguage() |
269 | | - makeCode() |
270 | 282 | }) |
271 | 283 |
|
272 | 284 | const modeList = ref<string[]>([]) |
@@ -365,7 +377,59 @@ function changeMode(val: string) { |
365 | 377 | loginFormRef.value?.clearValidate() |
366 | 378 | } |
367 | 379 |
|
| 380 | +const showCaptcha = computed<boolean>(() => { |
| 381 | + // -1 表示一直不显示 |
| 382 | + if (max_attempts.value === -1) { |
| 383 | + return false |
| 384 | + } |
| 385 | +
|
| 386 | + // 0 表示一直显示 |
| 387 | + if (max_attempts.value === 0) { |
| 388 | + return true |
| 389 | + } |
| 390 | +
|
| 391 | + // 大于 0,根据登录失败次数决定 |
| 392 | + const username = loginForm.value.username?.trim() |
| 393 | + if (!username) { |
| 394 | + return false // 没有输入用户名时不显示 |
| 395 | + } |
| 396 | +
|
| 397 | + const timestampKey = `${username}_chat_first_fail_timestamp` |
| 398 | + const firstFailTimestamp = localStorage.getItem(timestampKey) |
| 399 | +
|
| 400 | + if (firstFailTimestamp) { |
| 401 | + const expirationTime = 60 * 60 * 1000 // 10分钟毫秒数 |
| 402 | + if (Date.now() - parseInt(firstFailTimestamp) > expirationTime) { |
| 403 | + // 过期则清除记录 |
| 404 | + localStorage.removeItem('chat_' + username) |
| 405 | + localStorage.removeItem(timestampKey) |
| 406 | + return false |
| 407 | + } |
| 408 | + } else { |
| 409 | + // 如果没有时间戳但有失败次数,可能是旧数据,清除失败次数 |
| 410 | + const failCount = Number(localStorage.getItem('chat_' + username) || '0') |
| 411 | + if (failCount > 0) { |
| 412 | + localStorage.removeItem('chat_' + username) |
| 413 | + return false |
| 414 | + } |
| 415 | + } |
| 416 | +
|
| 417 | + const failCount = Number(localStorage.getItem('chat_' + username) || '0') |
| 418 | + console.log('failCount', failCount) |
| 419 | +
|
| 420 | + return failCount >= max_attempts.value |
| 421 | +}) |
| 422 | +
|
| 423 | +function handleUsernameBlur(username: string) { |
| 424 | + if (showCaptcha.value) { |
| 425 | + makeCode(username) |
| 426 | + } |
| 427 | +} |
| 428 | +
|
368 | 429 | onBeforeMount(() => { |
| 430 | + if (chatUser.chat_profile?.max_attempts) { |
| 431 | + max_attempts.value = chatUser.chat_profile.max_attempts |
| 432 | + } |
369 | 433 | if (chatUser.chat_profile?.login_value) { |
370 | 434 | modeList.value = chatUser.chat_profile.login_value |
371 | 435 | if (modeList.value.includes('LOCAL')) { |
|
0 commit comments