mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: 登录
This commit is contained in:
parent
8994ac4b20
commit
f1672cfb66
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.2.13 on 2024-07-11 19:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0002_user_create_time_user_update_time'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='source',
|
||||
field=models.CharField(default='LOCAL', max_length=10, verbose_name='来源'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import {Result} from '@/request/Result'
|
||||
import {get, post, del, put} from '@/request/index'
|
||||
import type {pageRequest} from '@/api/type/common'
|
||||
import {type Ref} from 'vue'
|
||||
|
||||
const prefix = '/auth'
|
||||
/**
|
||||
* 获取认证设置
|
||||
*/
|
||||
const getAuthSetting: (auth_type: string, loading?: Ref<boolean>) => Promise<Result<any>> = (auth_type, loading) => {
|
||||
return get(`${prefix}/${auth_type}/info`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮箱测试
|
||||
*/
|
||||
const postAuthSetting: (data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
data,
|
||||
loading
|
||||
) => {
|
||||
return post(`${prefix}/connection`, data, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改邮箱设置
|
||||
*/
|
||||
const putAuthSetting: (auth_type: string, data: any, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
auth_type,
|
||||
data,
|
||||
loading
|
||||
) => {
|
||||
return put(`${prefix}/${auth_type}/info`, data, undefined, loading)
|
||||
}
|
||||
|
||||
export default {
|
||||
getAuthSetting,
|
||||
postAuthSetting,
|
||||
putAuthSetting
|
||||
}
|
||||
|
|
@ -1,26 +1,31 @@
|
|||
import { Result } from '@/request/Result'
|
||||
import { get, post } from '@/request/index'
|
||||
import {Result} from '@/request/Result'
|
||||
import {get, post} from '@/request/index'
|
||||
import type {
|
||||
LoginRequest,
|
||||
RegisterRequest,
|
||||
CheckCodeRequest,
|
||||
ResetPasswordRequest,
|
||||
User,
|
||||
ResetCurrentUserPasswordRequest
|
||||
LoginRequest,
|
||||
RegisterRequest,
|
||||
CheckCodeRequest,
|
||||
ResetPasswordRequest,
|
||||
User,
|
||||
ResetCurrentUserPasswordRequest
|
||||
} from '@/api/type/user'
|
||||
import type { Ref } from 'vue'
|
||||
import type {Ref} from 'vue'
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param auth_type
|
||||
* @param request 登录接口请求表单
|
||||
* @param loading 接口加载器
|
||||
* @returns 认证数据
|
||||
*/
|
||||
const login: (request: LoginRequest, loading?: Ref<boolean>) => Promise<Result<string>> = (
|
||||
request,
|
||||
loading
|
||||
const login: (auth_type: string, request: LoginRequest, loading?: Ref<boolean>) => Promise<Result<string>> = (
|
||||
auth_type,
|
||||
request,
|
||||
loading
|
||||
) => {
|
||||
return post('/user/login', request, undefined, loading)
|
||||
if (auth_type !== '') {
|
||||
return post(`/${auth_type}/login`, request, undefined, loading)
|
||||
}
|
||||
return post('/user/login', request, undefined, loading)
|
||||
}
|
||||
/**
|
||||
* 登出
|
||||
|
|
@ -28,7 +33,7 @@ const login: (request: LoginRequest, loading?: Ref<boolean>) => Promise<Result<s
|
|||
* @returns
|
||||
*/
|
||||
const logout: (loading?: Ref<boolean>) => Promise<Result<boolean>> = (loading) => {
|
||||
return post('/user/logout', undefined, undefined, loading)
|
||||
return post('/user/logout', undefined, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -38,10 +43,10 @@ const logout: (loading?: Ref<boolean>) => Promise<Result<boolean>> = (loading) =
|
|||
* @returns
|
||||
*/
|
||||
const register: (request: RegisterRequest, loading?: Ref<boolean>) => Promise<Result<string>> = (
|
||||
request,
|
||||
loading
|
||||
request,
|
||||
loading
|
||||
) => {
|
||||
return post('/user/register', request, undefined, loading)
|
||||
return post('/user/register', request, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,10 +56,10 @@ const register: (request: RegisterRequest, loading?: Ref<boolean>) => Promise<Re
|
|||
* @returns
|
||||
*/
|
||||
const checkCode: (request: CheckCodeRequest, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
|
||||
request,
|
||||
loading
|
||||
request,
|
||||
loading
|
||||
) => {
|
||||
return post('/user/check_code', request, undefined, loading)
|
||||
return post('/user/check_code', request, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -64,11 +69,11 @@ const checkCode: (request: CheckCodeRequest, loading?: Ref<boolean>) => Promise<
|
|||
* @returns
|
||||
*/
|
||||
const sendEmit: (
|
||||
email: string,
|
||||
type: 'register' | 'reset_password',
|
||||
loading?: Ref<boolean>
|
||||
email: string,
|
||||
type: 'register' | 'reset_password',
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<boolean>> = (email, type, loading) => {
|
||||
return post('/user/send_email', { email, type }, undefined, loading)
|
||||
return post('/user/send_email', {email, type}, undefined, loading)
|
||||
}
|
||||
/**
|
||||
* 发送邮件到当前用户
|
||||
|
|
@ -76,7 +81,7 @@ const sendEmit: (
|
|||
* @returns
|
||||
*/
|
||||
const sendEmailToCurrent: (loading?: Ref<boolean>) => Promise<Result<boolean>> = (loading) => {
|
||||
return post('/user/current/send_email', undefined, undefined, loading)
|
||||
return post('/user/current/send_email', undefined, undefined, loading)
|
||||
}
|
||||
/**
|
||||
* 修改当前用户密码
|
||||
|
|
@ -85,10 +90,10 @@ const sendEmailToCurrent: (loading?: Ref<boolean>) => Promise<Result<boolean>> =
|
|||
* @returns
|
||||
*/
|
||||
const resetCurrentUserPassword: (
|
||||
request: ResetCurrentUserPasswordRequest,
|
||||
loading?: Ref<boolean>
|
||||
request: ResetCurrentUserPasswordRequest,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<boolean>> = (request, loading) => {
|
||||
return post('/user/current/reset_password', request, undefined, loading)
|
||||
return post('/user/current/reset_password', request, undefined, loading)
|
||||
}
|
||||
/**
|
||||
* 获取用户基本信息
|
||||
|
|
@ -96,7 +101,7 @@ const resetCurrentUserPassword: (
|
|||
* @returns 用户基本信息
|
||||
*/
|
||||
const profile: (loading?: Ref<boolean>) => Promise<Result<User>> = (loading) => {
|
||||
return get('/user', undefined, loading)
|
||||
return get('/user', undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,10 +111,10 @@ const profile: (loading?: Ref<boolean>) => Promise<Result<User>> = (loading) =>
|
|||
* @returns
|
||||
*/
|
||||
const resetPassword: (
|
||||
request: ResetPasswordRequest,
|
||||
loading?: Ref<boolean>
|
||||
request: ResetPasswordRequest,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<boolean>> = (request, loading) => {
|
||||
return post('/user/re_password', request, undefined, loading)
|
||||
return post('/user/re_password', request, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,17 +123,17 @@ const resetPassword: (
|
|||
* email_or_username
|
||||
*/
|
||||
const getUserList: (email_or_username: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
email_or_username,
|
||||
loading
|
||||
email_or_username,
|
||||
loading
|
||||
) => {
|
||||
return get('/user/list', { email_or_username }, loading)
|
||||
return get('/user/list', {email_or_username}, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取profile
|
||||
*/
|
||||
const getProfile: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) => {
|
||||
return get('/profile', undefined, loading)
|
||||
return get('/profile', undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -137,24 +142,31 @@ const getProfile: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) =
|
|||
* @param valid_count 校验数量: 5 | 50 | 2
|
||||
*/
|
||||
const getValid: (
|
||||
valid_type: string,
|
||||
valid_count: number,
|
||||
loading?: Ref<boolean>
|
||||
valid_type: string,
|
||||
valid_count: number,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (valid_type, valid_count, loading) => {
|
||||
return get(`/valid/${valid_type}/${valid_count}`, undefined, loading)
|
||||
return get(`/valid/${valid_type}/${valid_count}`, undefined, loading)
|
||||
}
|
||||
/**
|
||||
* 获取登录方式
|
||||
*/
|
||||
const getAuthType: (loading?: Ref<boolean>) => Promise<Result<any>> = (loading) => {
|
||||
return get('auth/types', undefined, loading)
|
||||
}
|
||||
|
||||
export default {
|
||||
login,
|
||||
register,
|
||||
sendEmit,
|
||||
checkCode,
|
||||
profile,
|
||||
resetPassword,
|
||||
sendEmailToCurrent,
|
||||
resetCurrentUserPassword,
|
||||
logout,
|
||||
getUserList,
|
||||
getProfile,
|
||||
getValid
|
||||
login,
|
||||
register,
|
||||
sendEmit,
|
||||
checkCode,
|
||||
profile,
|
||||
resetPassword,
|
||||
sendEmailToCurrent,
|
||||
resetCurrentUserPassword,
|
||||
logout,
|
||||
getUserList,
|
||||
getProfile,
|
||||
getValid,
|
||||
getAuthType
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
<el-dropdown trigger="click" type="primary">
|
||||
<div class="flex-center cursor">
|
||||
<AppAvatar>
|
||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
||||
<img src="@/assets/user-icon.svg" style="width: 54%" alt=""/>
|
||||
</AppAvatar>
|
||||
<span class="ml-8">{{ user.userInfo?.username }}</span>
|
||||
<el-icon class="el-icon--right">
|
||||
<CaretBottom />
|
||||
<CaretBottom/>
|
||||
</el-icon>
|
||||
</div>
|
||||
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
<el-dropdown-item class="border-t p-8" @click="openResetPassword">
|
||||
{{ $t('layout.topbar.avatar.resetPassword') }}
|
||||
</el-dropdown-item>
|
||||
<div v-hasPermission="new ComplexPermission(['ADMIN'], ['x-pack'], 'AND')">
|
||||
<div v-hasPermission="new ComplexPermission([], ['x-pack'], 'OR')">
|
||||
<el-dropdown-item class="border-t p-8" @click="openAPIKeyDialog">
|
||||
{{ $t('layout.topbar.avatar.apiKey') }}
|
||||
</el-dropdown-item>
|
||||
|
|
@ -39,19 +39,20 @@
|
|||
</el-dropdown>
|
||||
<ResetPassword ref="resetPasswordRef"></ResetPassword>
|
||||
<AboutDialog ref="AboutDialogRef"></AboutDialog>
|
||||
<APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef" />
|
||||
<UserPwdDialog ref="UserPwdDialogRef" />
|
||||
<APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef"/>
|
||||
<UserPwdDialog ref="UserPwdDialogRef"/>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import {ref, onMounted} from 'vue'
|
||||
import useStore from '@/stores'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {useRouter} from 'vue-router'
|
||||
import ResetPassword from './ResetPassword.vue'
|
||||
import AboutDialog from './AboutDialog.vue'
|
||||
import UserPwdDialog from '@/views/user-manage/component/UserPwdDialog.vue'
|
||||
import APIKeyDialog from './APIKeyDialog.vue'
|
||||
import { ComplexPermission } from '@/utils/permission/type'
|
||||
const { user } = useStore()
|
||||
import {ComplexPermission} from '@/utils/permission/type'
|
||||
|
||||
const {user} = useStore()
|
||||
const router = useRouter()
|
||||
|
||||
const UserPwdDialogRef = ref()
|
||||
|
|
@ -62,6 +63,7 @@ const resetPasswordRef = ref<InstanceType<typeof ResetPassword>>()
|
|||
const openAbout = () => {
|
||||
AboutDialogRef.value?.open()
|
||||
}
|
||||
|
||||
function openAPIKeyDialog() {
|
||||
APIKeyDialogRef.value.open()
|
||||
}
|
||||
|
|
@ -72,7 +74,7 @@ const openResetPassword = () => {
|
|||
|
||||
const logout = () => {
|
||||
user.logout().then(() => {
|
||||
router.push({ name: 'login' })
|
||||
router.push({name: 'login'})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -85,9 +87,11 @@ onMounted(() => {
|
|||
<style lang="scss" scoped>
|
||||
.avatar-dropdown {
|
||||
min-width: 210px;
|
||||
|
||||
.userInfo {
|
||||
padding: 12px 11px;
|
||||
}
|
||||
|
||||
:deep(.el-dropdown-menu__item) {
|
||||
padding: 12px 11px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,28 @@ export default {
|
|||
views,
|
||||
components,
|
||||
en,
|
||||
login: {
|
||||
authentication: 'Login Authentication',
|
||||
ldap: {
|
||||
title: 'LDAP Settings',
|
||||
address: 'LDAP Address',
|
||||
serverPlaceholder: 'Please enter LDAP address',
|
||||
bindDN: 'Bind DN',
|
||||
bindDNPlaceholder: 'Please enter Bind DN',
|
||||
password: 'Password',
|
||||
passwordPlaceholder: 'Please enter password',
|
||||
ou: 'User OU',
|
||||
ouPlaceholder: 'Please enter User OU',
|
||||
ldap_filter: 'User Filter',
|
||||
ldap_filterPlaceholder: 'Please enter User Filter',
|
||||
ldap_mapping: 'LDAP Attribute Mapping',
|
||||
ldap_mappingPlaceholder: 'Please enter LDAP Attribute Mapping',
|
||||
test: 'Test Connection',
|
||||
enableAuthentication: 'Enable LDAP Authentication',
|
||||
save: 'Save',
|
||||
testConnectionSuccess: 'Test Connection Success',
|
||||
testConnectionFailed: 'Test Connection Failed',
|
||||
saveSuccess: 'Save Success',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,4 +9,28 @@ export default {
|
|||
views,
|
||||
components,
|
||||
zhCn,
|
||||
login: {
|
||||
authentication: '登录认证',
|
||||
ldap: {
|
||||
title: 'LDAP设置',
|
||||
address: 'LDAP地址',
|
||||
serverPlaceholder: '请输入LDAP地址',
|
||||
bindDN: '绑定DN',
|
||||
bindDNPlaceholder: '请输入绑定DN',
|
||||
password: '密码',
|
||||
passwordPlaceholder: '请输入密码',
|
||||
ou: '用户OU',
|
||||
ouPlaceholder: '请输入用户OU',
|
||||
ldap_filter: '用户过滤器',
|
||||
ldap_filterPlaceholder: '请输入用户过滤器',
|
||||
ldap_mapping: 'LDAP属性映射',
|
||||
ldap_mappingPlaceholder: '请输入LDAP属性映射',
|
||||
test: '测试连接',
|
||||
enableAuthentication: '启用LDAP认证',
|
||||
save: '保存',
|
||||
testConnectionSuccess: '测试连接成功',
|
||||
testConnectionFailed: '测试连接失败',
|
||||
saveSuccess: '保存成功',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ const useUserStore = defineStore({
|
|||
})
|
||||
},
|
||||
|
||||
async login(username: string, password: string) {
|
||||
return UserApi.login({ username, password }).then((ok) => {
|
||||
async login(auth_type: string, username: string, password: string) {
|
||||
return UserApi.login(auth_type, { username, password }).then((ok) => {
|
||||
this.token = ok.data
|
||||
localStorage.setItem('token', ok.data)
|
||||
return this.profile()
|
||||
|
|
@ -98,6 +98,11 @@ const useUserStore = defineStore({
|
|||
localStorage.removeItem('token')
|
||||
return true
|
||||
})
|
||||
},
|
||||
async getAuthType() {
|
||||
return UserApi.getAuthType().then((ok) => {
|
||||
return ok.data
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,72 +1,75 @@
|
|||
<template>
|
||||
<div class="p-24" v-loading="loading">
|
||||
<!-- <el-form
|
||||
ref="emailFormRef"
|
||||
:rules="rules"
|
||||
:model="form"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
<el-form
|
||||
ref="authFormRef"
|
||||
:rules="rules"
|
||||
:model="form"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
>
|
||||
<el-form-item label="SMTP 主机" prop="email_host">
|
||||
<el-input v-model="form.email_host" placeholder="请输入 SMTP 主机" />
|
||||
<el-form-item :label="$t('login.ldap.address')" prop="config_data.ldap_server">
|
||||
<el-input v-model="form.config_data.ldap_server" :placeholder="$t('login.ldap.serverPlaceholder')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="SMTP 端口" prop="email_port">
|
||||
<el-input v-model="form.email_port" placeholder="请输入 SMTP 端口" />
|
||||
<el-form-item :label="$t('login.ldap.bindDN')" prop="config_data.base_dn">
|
||||
<el-input v-model="form.config_data.base_dn" :placeholder="$t('login.ldap.bindDNPlaceholder')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="SMTP 账户" prop="email_host_user">
|
||||
<el-input v-model="form.email_host_user" placeholder="请输入 SMTP 账户" />
|
||||
<el-form-item :label="$t('login.ldap.password')" prop="config_data.password">
|
||||
<el-input v-model="form.config_data.password" :placeholder="$t('login.ldap.passwordPlaceholder')"
|
||||
show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item label="发件人邮箱" prop="from_email">
|
||||
<el-input v-model="form.from_email" placeholder="请输入发件人邮箱" />
|
||||
<el-form-item :label="$t('login.ldap.ou')" prop="config_data.ou">
|
||||
<el-input v-model="form.config_data.ou" :placeholder="$t('login.ldap.ouPlaceholder')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="email_host_password">
|
||||
<el-input v-model="form.email_host_password" placeholder="请输入发件人密码" show-password />
|
||||
<el-form-item :label="$t('login.ldap.ldap_filter')" prop="config_data.ldap_filter">
|
||||
<el-input v-model="form.config_data.ldap_filter" :placeholder="$t('login.ldap.ldap_filterPlaceholder')"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('login.ldap.ldap_mapping')" prop="config_data.ldap_mapping">
|
||||
<el-input v-model="form.config_data.ldap_mapping" :placeholder="$t('login.ldap.ldap_mappingPlaceholder')"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="form.email_use_ssl"
|
||||
>开启SSL(如果SMTP端口是465,通常需要启用SSL)
|
||||
</el-checkbox>
|
||||
<el-checkbox v-model="form.is_active">{{ $t('login.ldap.enableAuthentication') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="form.email_use_tls"
|
||||
>开启TLS(如果SMTP端口是587,通常需要启用TLS)</el-checkbox
|
||||
>
|
||||
</el-form-item>
|
||||
<el-button @click="submit(emailFormRef, 'test')" :disabled="loading"> 测试连接 </el-button>
|
||||
<el-button @click="submit(authFormRef, 'test')" :disabled="loading"> {{ $t('login.ldap.test') }}</el-button>
|
||||
</el-form>
|
||||
|
||||
<div class="text-right">
|
||||
<el-button @click="submit(emailFormRef)" type="primary" :disabled="loading"> 保存 </el-button>
|
||||
</div> -->
|
||||
<el-button @click="submit(authFormRef)" type="primary" :disabled="loading"> {{ $t('login.ldap.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch, onMounted } from 'vue'
|
||||
import emailApi from '@/api/email-setting'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
import {reactive, ref, watch, onMounted} from 'vue'
|
||||
import authApi from '@/api/auth-setting'
|
||||
import type {FormInstance, FormRules} from 'element-plus'
|
||||
import {t} from '@/locales'
|
||||
import {MsgSuccess} from '@/utils/message'
|
||||
|
||||
const form = ref<any>({
|
||||
email_host: '',
|
||||
email_port: '',
|
||||
email_host_user: '',
|
||||
email_host_password: '',
|
||||
email_use_tls: false,
|
||||
email_use_ssl: false,
|
||||
from_email: ''
|
||||
id: '',
|
||||
auth_type: 'LDAP',
|
||||
config_data: {
|
||||
ldap_server: '',
|
||||
base_dn: '',
|
||||
password: '',
|
||||
ou: '',
|
||||
ldap_filter: '',
|
||||
ldap_mapping: '',
|
||||
},
|
||||
is_active: true
|
||||
})
|
||||
|
||||
const emailFormRef = ref()
|
||||
const authFormRef = ref()
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const rules = reactive<FormRules<any>>({
|
||||
email_host: [{ required: true, message: '请输入 SMTP 主机', trigger: 'blur' }],
|
||||
email_port: [{ required: true, message: '请输入 SMTP 端口', trigger: 'blur' }],
|
||||
email_host_user: [{ required: true, message: '请输入 SMTP 账户', trigger: 'blur' }],
|
||||
email_host_password: [{ required: true, message: '请输入发件人邮箱密码', trigger: 'blur' }],
|
||||
from_email: [{ required: true, message: '请输入发件人邮箱', trigger: 'blur' }]
|
||||
'config_data.ldap_server': [{required: true, message: t('login.ldap.serverPlaceholder'), trigger: 'blur'}],
|
||||
'config_data.base_dn': [{required: true, message: t('login.ldap.bindDNPlaceholder'), trigger: 'blur'}],
|
||||
'config_data.password': [{required: true, message: t('login.ldap.passwordPlaceholder'), trigger: 'blur'}],
|
||||
'config_data.ou': [{required: true, message: t('login.ldap.ouPlaceholder'), trigger: 'blur'}],
|
||||
'config_data.ldap_filter': [{required: true, message: t('login.ldap.ldap_filterPlaceholder'), trigger: 'blur'}],
|
||||
'config_data.ldap_mapping': [{required: true, message: t('login.ldap.ldap_mappingPlaceholder'), trigger: 'blur'}]
|
||||
})
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined, test?: string) => {
|
||||
|
|
@ -74,12 +77,12 @@ const submit = async (formEl: FormInstance | undefined, test?: string) => {
|
|||
await formEl.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
if (test) {
|
||||
emailApi.postTestEmail(form.value, loading).then((res) => {
|
||||
MsgSuccess('测试连接成功')
|
||||
authApi.postAuthSetting(form.value, loading).then((res) => {
|
||||
MsgSuccess(t('login.ldap.testConnectionSuccess'))
|
||||
})
|
||||
} else {
|
||||
emailApi.putEmailSetting(form.value, loading).then((res) => {
|
||||
MsgSuccess('设置成功')
|
||||
authApi.putAuthSetting(form.value.auth_type, form.value, loading).then((res) => {
|
||||
MsgSuccess(t('login.ldap.saveSuccess'))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -87,9 +90,12 @@ const submit = async (formEl: FormInstance | undefined, test?: string) => {
|
|||
}
|
||||
|
||||
function getDetail() {
|
||||
emailApi.getEmailSetting(loading).then((res: any) => {
|
||||
authApi.getAuthSetting(form.value.auth_type, loading).then((res: any) => {
|
||||
if (res.data && JSON.stringify(res.data) !== '{}') {
|
||||
form.value = res.data
|
||||
if (res.data.config_data.ldap_mapping) {
|
||||
form.value.config_data.ldap_mapping = JSON.stringify(JSON.parse(res.data.config_data.ldap_mapping))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="authentication-setting p-24">
|
||||
<h4>登录认证</h4>
|
||||
<h4>{{$t('login.authentication')}}</h4>
|
||||
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
||||
<template v-for="(item, index) in tabList" :key="index">
|
||||
<el-tab-pane :label="item.label" :name="item.name">
|
||||
|
|
@ -17,16 +17,13 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, computed, onMounted } from 'vue'
|
||||
import emailApi from '@/api/email-setting'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import LDAP from './component/LDAP.vue'
|
||||
|
||||
import { t } from '@/locales'
|
||||
const activeName = ref('LDAP')
|
||||
const tabList = [
|
||||
{
|
||||
label: 'LDAP设置',
|
||||
label: t('login.ldap.title'),
|
||||
name: 'LDAP',
|
||||
component: LDAP
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,19 +3,19 @@
|
|||
<LoginContainer subTitle="欢迎使用 MaxKB 智能知识库">
|
||||
<h2 class="mb-24">{{ loginMode || '普通登录' }}</h2>
|
||||
<el-form
|
||||
class="login-form"
|
||||
:rules="rules"
|
||||
:model="loginForm"
|
||||
ref="loginFormRef"
|
||||
@keyup.enter="login"
|
||||
class="login-form"
|
||||
:rules="rules"
|
||||
:model="loginForm"
|
||||
ref="loginFormRef"
|
||||
@keyup.enter="login"
|
||||
>
|
||||
<div class="mb-24">
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="loginForm.username"
|
||||
placeholder="请输入用户名"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="loginForm.username"
|
||||
placeholder="请输入用户名"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
|
@ -23,12 +23,12 @@
|
|||
<div class="mb-24">
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="loginForm.password"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="loginForm.password"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
|
@ -40,47 +40,51 @@
|
|||
注册
|
||||
</el-button> -->
|
||||
<el-button
|
||||
class="forgot-password"
|
||||
@click="router.push('/forgot_password')"
|
||||
link
|
||||
type="primary"
|
||||
class="forgot-password"
|
||||
@click="router.push('/forgot_password')"
|
||||
link
|
||||
type="primary"
|
||||
>
|
||||
忘记密码?
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- <div class="login-gradient-divider lighter mt-24">
|
||||
<div class="login-gradient-divider lighter mt-24" v-if="modeList.length > 1">
|
||||
<span>更多登录方式</span>
|
||||
</div>
|
||||
<div class="text-center mt-16">
|
||||
<el-button
|
||||
v-if="loginMode !== 'LDAP'"
|
||||
circle
|
||||
class="login-button-circle color-secondary"
|
||||
@click="changeMode('LDAP')"
|
||||
>LDAP</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="loginMode !== ''"
|
||||
circle
|
||||
class="login-button-circle color-secondary"
|
||||
style="font-size: 24px"
|
||||
icon="UserFilled"
|
||||
@click="changeMode('')"
|
||||
/>
|
||||
</div> -->
|
||||
<template v-for="item in modeList">
|
||||
<el-button
|
||||
v-if="item !== ''&&loginMode !== item"
|
||||
circle
|
||||
:key="item"
|
||||
class="login-button-circle color-secondary"
|
||||
@click="changeMode(item)"
|
||||
>{{ item }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="item === ''&&loginMode !== ''"
|
||||
circle
|
||||
:key="item"
|
||||
class="login-button-circle color-secondary"
|
||||
style="font-size: 24px"
|
||||
icon="UserFilled"
|
||||
@click="changeMode('')"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</LoginContainer>
|
||||
</login-layout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import type { LoginRequest } from '@/api/type/user'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import {onMounted, ref} from 'vue'
|
||||
import type {LoginRequest} from '@/api/type/user'
|
||||
import {useRouter} from 'vue-router'
|
||||
import type {FormInstance, FormRules} from 'element-plus'
|
||||
import useStore from '@/stores'
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
const { user } = useStore()
|
||||
const {user} = useStore()
|
||||
const router = useRouter()
|
||||
const loginForm = ref<LoginRequest>({
|
||||
username: '',
|
||||
|
|
@ -105,6 +109,8 @@ const rules = ref<FormRules<LoginRequest>>({
|
|||
})
|
||||
const loginFormRef = ref<FormInstance>()
|
||||
|
||||
|
||||
const modeList = ref<string[]>(['']);
|
||||
const loginMode = ref('')
|
||||
|
||||
function changeMode(val: string) {
|
||||
|
|
@ -120,13 +126,25 @@ const login = () => {
|
|||
loginFormRef.value?.validate().then(() => {
|
||||
loading.value = true
|
||||
user
|
||||
.login(loginForm.value.username, loginForm.value.password)
|
||||
.then(() => {
|
||||
router.push({ name: 'home' })
|
||||
})
|
||||
.finally(() => (loading.value = false))
|
||||
.login(loginMode.value, loginForm.value.username, loginForm.value.password)
|
||||
.then(() => {
|
||||
router.push({name: 'home'})
|
||||
})
|
||||
.finally(() => (loading.value = false))
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
user.asyncGetProfile().then((res) => {
|
||||
if (user.isXPack) {
|
||||
loading.value = true
|
||||
user.getAuthType().then((res) => {
|
||||
modeList.value = [...modeList.value, ...res];
|
||||
}).finally(() => (loading.value = false))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.login-gradient-divider {
|
||||
|
|
@ -154,6 +172,7 @@ const login = () => {
|
|||
top: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.login-button-circle {
|
||||
padding: 25px !important;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue