Files
admin-ui/src/views/system/pwconfig/index.vue
张斌 694577f2a6
Some checks failed
全局K3s部署 / deploy (push) Failing after 2s
增加密码策略配置
2026-05-25 12:27:34 +08:00

218 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="system-pwconfig-container">
<el-card shadow="hover">
<template #header>
<div class="card-header">
<span>密码策略配置</span>
</div>
</template>
<el-form :model="ruleForm" ref="formRef" :rules="rules" label-width="180px" style="max-width: 800px;">
<el-form-item label="启用密码策略" prop="enabled">
<el-switch v-model="ruleForm.enabled" />
</el-form-item>
<el-form-item label="最小密码长度" prop="minLength">
<el-input-number v-model="ruleForm.minLength" :min="4" :max="32" placeholder="请输入最小密码长度" />
<span class="ml10 text-muted"></span>
</el-form-item>
<el-form-item label="最大密码长度" prop="maxLength">
<el-input-number v-model="ruleForm.maxLength" :min="4" :max="128" placeholder="请输入最大密码长度" />
<span class="ml10 text-muted"></span>
</el-form-item>
<el-form-item label="必须包含大写字母" prop="requireUppercase">
<el-switch v-model="ruleForm.requireUppercase" />
</el-form-item>
<el-form-item label="必须包含小写字母" prop="requireLowercase">
<el-switch v-model="ruleForm.requireLowercase" />
</el-form-item>
<el-form-item label="必须包含数字" prop="requireDigit">
<el-switch v-model="ruleForm.requireDigit" />
</el-form-item>
<el-form-item label="必须包含特殊字符" prop="requireSpecialChar">
<el-switch v-model="ruleForm.requireSpecialChar" />
<div class="text-muted mt5" style="font-size: 12px;">特殊字符包括!@#$%^&*()_+-=[]{}|;:,.<>?</div>
</el-form-item>
<el-form-item label="密码过期天数" prop="expireDays">
<el-input-number v-model="ruleForm.expireDays" :min="0" :max="365" placeholder="请输入密码过期天数" />
<span class="ml10 text-muted">0表示永不过期</span>
</el-form-item>
<el-form-item label="禁止重复使用次数" prop="historyLimit">
<el-input-number v-model="ruleForm.historyLimit" :min="0" :max="24" placeholder="请输入禁止重复使用次数" />
<span class="ml10 text-muted">0表示不限制</span>
</el-form-item>
<el-form-item label="登录失败锁定次数" prop="maxRetryCount">
<el-input-number v-model="ruleForm.maxRetryCount" :min="0" :max="10" placeholder="请输入登录失败锁定次数" />
<span class="ml10 text-muted">0表示不锁定</span>
</el-form-item>
<el-form-item label="锁定时长" prop="lockTimeMinutes">
<el-input-number v-model="ruleForm.lockTimeMinutes" :min="1" :max="1440" placeholder="请输入锁定时长" />
<span class="ml10 text-muted">分钟</span>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="ruleForm.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit" :loading="loading">保存配置</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script lang="ts">
import { reactive, toRefs, defineComponent, ref, onMounted, unref } from 'vue';
import { ElMessage, FormInstance, FormRules } from 'element-plus';
import { getPwConfig, savePwConfig } from "/@/api/system/pwconfig";
interface RuleFormState {
enabled: boolean;
minLength: number;
maxLength: number;
requireUppercase: boolean;
requireLowercase: boolean;
requireDigit: boolean;
requireSpecialChar: boolean;
expireDays: number;
historyLimit: number;
maxRetryCount: number;
lockTimeMinutes: number;
remark: string;
}
interface PwConfigState {
ruleForm: RuleFormState;
rules: FormRules;
loading: boolean;
}
export default defineComponent({
name: 'systemPwConfig',
setup() {
const formRef = ref<FormInstance>();
const state = reactive<PwConfigState>({
loading: false,
ruleForm: {
enabled: false,
minLength: 8,
maxLength: 32,
requireUppercase: false,
requireLowercase: true,
requireDigit: true,
requireSpecialChar: false,
expireDays: 90,
historyLimit: 5,
maxRetryCount: 5,
lockTimeMinutes: 30,
remark: '',
},
rules: {
minLength: [
{ required: true, message: '请输入最小密码长度', trigger: 'blur' }
],
maxLength: [
{ required: true, message: '请输入最大密码长度', trigger: 'blur' }
],
expireDays: [
{ required: true, message: '请输入密码过期天数', trigger: 'blur' }
],
historyLimit: [
{ required: true, message: '请输入禁止重复使用次数', trigger: 'blur' }
],
maxRetryCount: [
{ required: true, message: '请输入登录失败锁定次数', trigger: 'blur' }
],
lockTimeMinutes: [
{ required: true, message: '请输入锁定时长', trigger: 'blur' }
],
}
});
// 获取配置
const loadConfig = async () => {
try {
const res: any = await getPwConfig();
if (res.code === 0 && res.data) {
state.ruleForm = {
...state.ruleForm,
...res.data,
};
}
} catch {
// 错误由全局拦截器处理
}
};
// 重置表单
const resetForm = () => {
loadConfig();
};
// 保存配置
const onSubmit = async () => {
const formWrap = unref(formRef);
if (!formWrap) return;
await formWrap.validate(async (valid: boolean) => {
if (valid) {
// 验证最小长度不大于最大长度
if (state.ruleForm.minLength > state.ruleForm.maxLength) {
ElMessage.error('最小密码长度不能大于最大密码长度');
return;
}
state.loading = true;
try {
await savePwConfig(state.ruleForm);
ElMessage.success('保存成功');
} finally {
state.loading = false;
}
}
});
};
// 页面加载时
onMounted(() => {
loadConfig();
});
return {
formRef,
onSubmit,
resetForm,
...toRefs(state),
};
},
});
</script>
<style scoped lang="scss">
.text-muted {
color: var(--el-text-color-placeholder);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.system-pwconfig-container {
:deep(.el-card__body) {
padding-top: 30px;
}
}
</style>