新增登录页图形验证码功能,支持通过Redis全局配置控制验证码的启用状态,优化登录流程以提升用户体验。新增相关API接口和前端配置项,确保验证码逻辑与后端同步。

This commit is contained in:
geht
2026-04-20 14:21:36 +08:00
parent 7a648b20be
commit 73426a7af3
23 changed files with 450 additions and 103 deletions

View File

@@ -1,4 +1,5 @@
import { defineComponent, computed, unref } from 'vue';
import { usePermission } from '/@/hooks/web/usePermission';
import { BasicDrawer } from '/@/components/Drawer/index';
import { Divider } from 'ant-design-vue';
import { TypePicker, ThemeColorPicker, SettingFooter, SwitchItem, SelectItem, InputNumberItem } from './components';
@@ -47,8 +48,13 @@ export default defineComponent({
getShowDarkModeToggle,
getThemeColor,
getAiIconShow,
getLoginCaptchaEnabled,
} = useRootSetting();
const { hasPermission } = usePermission();
/** 项目配置中「验证码登录」开关仅对有权限的用户展示 */
const showLoginCaptchaSetting = computed(() => hasPermission('system:project:setting:loginCaptcha'));
const { getOpenPageLoading, getBasicTransition, getEnableTransition, getOpenNProgress } = useTransitionSetting();
const {
@@ -318,6 +324,13 @@ export default defineComponent({
<SwitchItem title={t('layout.setting.colorWeak')} event={HandlerEnum.COLOR_WEAK} def={unref(getColorWeak)} />
<SwitchItem title={t('layout.setting.aiIconSHow')} event={HandlerEnum.AI_ICON_SHOW} def={unref(getAiIconShow)} />
{unref(showLoginCaptchaSetting) && (
<SwitchItem
title={t('layout.setting.loginCaptcha')}
event={HandlerEnum.LOGIN_CAPTCHA_ENABLED}
def={unref(getLoginCaptchaEnabled)}
/>
)}
</>
);
}

View File

@@ -41,10 +41,14 @@
const { t } = useI18n();
const getBindValue = computed(() => {
return props.def ? { checked: props.def } : {};
// 必须为 false 时也绑定 checked否则 def===false 会被当成无绑定,开关与持久化异常
if (props.def === undefined || props.def === null) {
return {};
}
return { checked: props.def };
});
function handleChange(e: ChangeEvent) {
props.event && baseHandler(props.event, e);
function handleChange(checked: boolean) {
props.event && baseHandler(props.event, checked);
}
return {
prefixCls,

View File

@@ -53,6 +53,8 @@ export enum HandlerEnum {
OPEN_PAGE_LOADING,
OPEN_ROUTE_TRANSITION,
AI_ICON_SHOW,
/** 登录页图形验证码开关 */
LOGIN_CAPTCHA_ENABLED,
}
// 标签页样式

View File

@@ -3,6 +3,8 @@ import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updat
import { updateColorWeak } from '/@/logics/theme/updateColorWeak';
import { updateGrayMode } from '/@/logics/theme/updateGrayMode';
import { message } from 'ant-design-vue';
import { setLoginCaptchaServerConfig } from '/@/api/sys/user';
import { useAppStore } from '/@/store/modules/app';
import { ProjectConfig } from '/#/config';
import { changeTheme } from '/@/logics/theme';
@@ -80,6 +82,12 @@ export function baseHandler(event: HandlerEnum, value: any) {
const appStore = useAppStore();
const config = handler(event, value);
appStore.setProjectConfig(config);
// 验证码登录开关同步到后端 Redis登录页仅依赖 GET /sys/loginCaptchaConfig
if (event === HandlerEnum.LOGIN_CAPTCHA_ENABLED) {
setLoginCaptchaServerConfig(!!value).catch(() => {
message.error('验证码开关同步到后端失败,请检查网络或是否具备 system:project:setting:loginCaptcha 权限');
});
}
if (event === HandlerEnum.CHANGE_THEME) {
updateHeaderBgColor();
updateSidebarBgColor();
@@ -210,6 +218,8 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf
// 代码逻辑说明: 【QQYUN-10952】AI助手支持通过设置来配置是否显示
case HandlerEnum.AI_ICON_SHOW:
return { aiIconShow: value };
case HandlerEnum.LOGIN_CAPTCHA_ENABLED:
return { loginCaptchaEnabled: value };
case HandlerEnum.SHOW_LOGO:
return { showLogo: value };