mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
refactor: add logout
This commit is contained in:
parent
b8b14884bd
commit
8d40004c67
|
|
@ -10,9 +10,9 @@ from drf_spectacular.types import OpenApiTypes
|
|||
from drf_spectacular.utils import OpenApiParameter
|
||||
|
||||
from common.mixins.api_mixin import APIMixin
|
||||
from common.result import ResultSerializer
|
||||
from common.result import ResultSerializer, DefaultResultSerializer
|
||||
from users.serializers.user import UserProfileResponse, CreateUserSerializer, UserManageSerializer, \
|
||||
UserInstanceSerializer
|
||||
UserInstanceSerializer, RePasswordSerializer, CheckCodeSerializer, SendEmailSerializer
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
|
|
@ -192,3 +192,29 @@ class TestWorkspacePermissionUserApi(APIMixin):
|
|||
# 指定必须给
|
||||
required=True,
|
||||
)]
|
||||
|
||||
|
||||
class ResetPasswordAPI(APIMixin):
|
||||
@staticmethod
|
||||
def get_request():
|
||||
return RePasswordSerializer
|
||||
|
||||
|
||||
class CheckCodeAPI(APIMixin):
|
||||
@staticmethod
|
||||
def get_request():
|
||||
return CheckCodeSerializer
|
||||
|
||||
@staticmethod
|
||||
def get_response():
|
||||
return DefaultResultSerializer
|
||||
|
||||
|
||||
class SendEmailAPI(APIMixin):
|
||||
@staticmethod
|
||||
def get_request():
|
||||
return SendEmailSerializer
|
||||
|
||||
@staticmethod
|
||||
def get_response():
|
||||
return DefaultResultSerializer
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@
|
|||
@date:2025/4/14 19:18
|
||||
@desc:
|
||||
"""
|
||||
import datetime
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from itertools import product
|
||||
|
||||
from django.core.mail.backends.smtp import EmailBackend
|
||||
from django.db import transaction
|
||||
from django.db.models import Q, QuerySet
|
||||
from rest_framework import serializers
|
||||
|
|
@ -20,9 +23,13 @@ from common.database_model_manage.database_model_manage import DatabaseModelMana
|
|||
from common.db.search import page_search
|
||||
from common.exception.app_exception import AppApiException
|
||||
from common.utils.common import valid_license, password_encrypt
|
||||
from maxkb.conf import PROJECT_DIR
|
||||
from system_manage.models import SystemSetting, SettingType
|
||||
from users.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _, to_locale
|
||||
from django.core import validators
|
||||
from django.core.mail import send_mail
|
||||
from django.utils.translation import get_language
|
||||
|
||||
PASSWORD_REGEX = re.compile(
|
||||
r"^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z_!@#$%^&*`~.()-+=]+$)(?![a-z0-9]+$)(?![a-z_!@#$%^&*`~()-+=]+$)"
|
||||
|
|
@ -441,3 +448,169 @@ def update_user_role(instance, user):
|
|||
workspace_id=workspace_id,
|
||||
user_id=user.id
|
||||
)
|
||||
|
||||
|
||||
class RePasswordSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField(
|
||||
required=True,
|
||||
label=_("Email"),
|
||||
validators=[validators.EmailValidator(message=ExceptionCodeConstants.EMAIL_FORMAT_ERROR.value.message,
|
||||
code=ExceptionCodeConstants.EMAIL_FORMAT_ERROR.value.code)])
|
||||
|
||||
code = serializers.CharField(required=True, label=_("Verification code"))
|
||||
|
||||
password = serializers.CharField(required=True, label=_("Password"),
|
||||
validators=[validators.RegexValidator(regex=re.compile(
|
||||
"^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z_!@#$%^&*`~.()-+=]+$)(?![a-z0-9]+$)(?![a-z_!@#$%^&*`~()-+=]+$)"
|
||||
"(?![0-9_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9_!@#$%^&*`~.()-+=]{6,20}$")
|
||||
, message=_(
|
||||
"The confirmation password must be 6-20 characters long and must be a combination of letters, numbers, and special characters."))])
|
||||
|
||||
re_password = serializers.CharField(required=True, label=_("Confirm Password"),
|
||||
validators=[validators.RegexValidator(regex=re.compile(
|
||||
"^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z_!@#$%^&*`~.()-+=]+$)(?![a-z0-9]+$)(?![a-z_!@#$%^&*`~()-+=]+$)"
|
||||
"(?![0-9_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9_!@#$%^&*`~.()-+=]{6,20}$")
|
||||
, message=_(
|
||||
"The confirmation password must be 6-20 characters long and must be a combination of letters, numbers, and special characters."))]
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = '__all__'
|
||||
|
||||
def is_valid(self, *, raise_exception=False):
|
||||
super().is_valid(raise_exception=True)
|
||||
email = self.data.get("email")
|
||||
# TODO 删除缓存
|
||||
# cache_code = user_cache.get(email + ':reset_password')
|
||||
if self.data.get('password') != self.data.get('re_password'):
|
||||
raise AppApiException(ExceptionCodeConstants.PASSWORD_NOT_EQ_RE_PASSWORD.value.code,
|
||||
ExceptionCodeConstants.PASSWORD_NOT_EQ_RE_PASSWORD.value.message)
|
||||
# if cache_code != self.data.get('code'):
|
||||
# raise AppApiException(ExceptionCodeConstants.CODE_ERROR.value.code,
|
||||
# ExceptionCodeConstants.CODE_ERROR.value.message)
|
||||
return True
|
||||
|
||||
def reset_password(self):
|
||||
"""
|
||||
修改密码
|
||||
:return: 是否成功
|
||||
"""
|
||||
if self.is_valid():
|
||||
email = self.data.get("email")
|
||||
QuerySet(User).filter(email=email).update(
|
||||
password=password_encrypt(self.data.get('password')))
|
||||
code_cache_key = email + ":reset_password"
|
||||
# 删除验证码缓存
|
||||
# user_cache.delete(code_cache_key)
|
||||
return True
|
||||
|
||||
|
||||
class SendEmailSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField(
|
||||
required=True
|
||||
, label=_("Email"),
|
||||
validators=[validators.EmailValidator(message=ExceptionCodeConstants.EMAIL_FORMAT_ERROR.value.message,
|
||||
code=ExceptionCodeConstants.EMAIL_FORMAT_ERROR.value.code)])
|
||||
|
||||
type = serializers.CharField(required=True, label=_("Type"), validators=[
|
||||
validators.RegexValidator(regex=re.compile("^register|reset_password$"),
|
||||
message=_("The type only supports register|reset_password"), code=500)
|
||||
])
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = '__all__'
|
||||
|
||||
def is_valid(self, *, raise_exception=False):
|
||||
super().is_valid(raise_exception=raise_exception)
|
||||
user_exists = QuerySet(User).filter(email=self.data.get('email')).exists()
|
||||
if not user_exists and self.data.get('type') == 'reset_password':
|
||||
raise ExceptionCodeConstants.EMAIL_IS_NOT_EXIST.value.to_app_api_exception()
|
||||
elif user_exists and self.data.get('type') == 'register':
|
||||
raise ExceptionCodeConstants.EMAIL_IS_EXIST.value.to_app_api_exception()
|
||||
code_cache_key = self.data.get('email') + ":" + self.data.get("type")
|
||||
code_cache_key_lock = code_cache_key + "_lock"
|
||||
ttl = None # user_cache.ttl(code_cache_key_lock)
|
||||
if ttl is not None:
|
||||
raise AppApiException(500, _("Do not send emails again within {seconds} seconds").format(
|
||||
seconds=int(ttl.total_seconds())))
|
||||
return True
|
||||
|
||||
def send(self):
|
||||
"""
|
||||
发送邮件
|
||||
:return: 是否发送成功
|
||||
:exception 发送失败异常
|
||||
"""
|
||||
email = self.data.get("email")
|
||||
state = self.data.get("type")
|
||||
# 生成随机验证码
|
||||
code = "".join(list(map(lambda i: random.choice(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'
|
||||
]), range(6))))
|
||||
# 获取邮件模板
|
||||
language = get_language()
|
||||
file = open(
|
||||
os.path.join(PROJECT_DIR, "apps", "common", 'template', f'email_template_{to_locale(language)}.html'), "r",
|
||||
encoding='utf-8')
|
||||
content = file.read()
|
||||
file.close()
|
||||
code_cache_key = email + ":" + state
|
||||
code_cache_key_lock = code_cache_key + "_lock"
|
||||
# 设置缓存
|
||||
# user_cache.set(code_cache_key_lock, code, timeout=datetime.timedelta(minutes=1))
|
||||
system_setting = QuerySet(SystemSetting).filter(type=SettingType.EMAIL.value).first()
|
||||
if system_setting is None:
|
||||
# user_cache.delete(code_cache_key_lock)
|
||||
raise AppApiException(1004,
|
||||
_("The email service has not been set up. Please contact the administrator to set up the email service in [Email Settings]."))
|
||||
try:
|
||||
connection = EmailBackend(system_setting.meta.get("email_host"),
|
||||
system_setting.meta.get('email_port'),
|
||||
system_setting.meta.get('email_host_user'),
|
||||
system_setting.meta.get('email_host_password'),
|
||||
system_setting.meta.get('email_use_tls'),
|
||||
False,
|
||||
system_setting.meta.get('email_use_ssl')
|
||||
)
|
||||
# 发送邮件
|
||||
send_mail(_('【Intelligent knowledge base question and answer system-{action}】').format(
|
||||
action=_('User registration') if state == 'register' else _('Change password')),
|
||||
'',
|
||||
html_message=f'{content.replace("${code}", code)}',
|
||||
from_email=system_setting.meta.get('from_email'),
|
||||
recipient_list=[email], fail_silently=False, connection=connection)
|
||||
except Exception as e:
|
||||
# user_cache.delete(code_cache_key_lock)
|
||||
raise AppApiException(500, f"{str(e)}" + _("Email sending failed"))
|
||||
# user_cache.set(code_cache_key, code, timeout=datetime.timedelta(minutes=30))
|
||||
return True
|
||||
|
||||
|
||||
class CheckCodeSerializer(serializers.Serializer):
|
||||
"""
|
||||
校验验证码
|
||||
"""
|
||||
email = serializers.EmailField(
|
||||
required=True,
|
||||
label=_("Email"),
|
||||
validators=[validators.EmailValidator(message=ExceptionCodeConstants.EMAIL_FORMAT_ERROR.value.message,
|
||||
code=ExceptionCodeConstants.EMAIL_FORMAT_ERROR.value.code)])
|
||||
code = serializers.CharField(required=True, label=_("Verification code"))
|
||||
|
||||
type = serializers.CharField(required=True,
|
||||
label=_("Type"),
|
||||
validators=[
|
||||
validators.RegexValidator(regex=re.compile("^register|reset_password$"),
|
||||
message=_(
|
||||
"The type only supports register|reset_password"),
|
||||
code=500)
|
||||
])
|
||||
|
||||
def is_valid(self, *, raise_exception=False):
|
||||
super().is_valid()
|
||||
#TODO 这里的缓存 需要重新设计
|
||||
value = None#user_cache.get(self.data.get("email") + ":" + self.data.get("type"))
|
||||
if value is None or value != self.data.get("code"):
|
||||
raise ExceptionCodeConstants.CODE_ERROR.value.to_app_api_exception()
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ urlpatterns = [
|
|||
path('user/profile', views.UserProfileView.as_view(), name="user_profile"),
|
||||
path('user/captcha', views.CaptchaView.as_view(), name='captcha'),
|
||||
path('user/test', views.TestPermissionsUserView.as_view(), name="test"),
|
||||
path('user/logout', views.Logout.as_view(), name='logout'),
|
||||
path("user/send_email", views.SendEmail.as_view(), name='send_email'),
|
||||
path("user/check_code", views.CheckCode.as_view(), name='check_code'),
|
||||
path("user/re_password", views.RePasswordView.as_view(), name='re_password'),
|
||||
path("user/current/send_email", views.SendEmailToCurrentUserView.as_view(), name="send_email_current"),
|
||||
path('workspace/<str:workspace_id>/user_list', views.WorkspaceUserListView.as_view(),
|
||||
name="test_workspace_id_permission"),
|
||||
path('workspace/<str:workspace_id>/user/profile', views.TestWorkspacePermissionUserView.as_view(),
|
||||
|
|
|
|||
|
|
@ -6,14 +6,18 @@
|
|||
@date:2025/4/14 10:22
|
||||
@desc:
|
||||
"""
|
||||
from django.core.cache import cache
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from common import result
|
||||
from common.auth import TokenAuth
|
||||
from common.constants.cache_version import Cache_Version
|
||||
from common.log.log import log
|
||||
from common.utils.common import encryption
|
||||
from models_provider.api.model import DefaultModelResponse
|
||||
from users.api.login import LoginAPI, CaptchaAPI
|
||||
from users.serializers.login import LoginSerializer, CaptchaSerializer
|
||||
|
||||
|
|
@ -44,6 +48,23 @@ class LoginView(APIView):
|
|||
return result.success(LoginSerializer().login(request.data))
|
||||
|
||||
|
||||
class Logout(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
@extend_schema(methods=['POST'],
|
||||
summary=_("Sign out"),
|
||||
description=_("Sign out"),
|
||||
operation_id=_("Sign out"), # type: ignore
|
||||
tags=[_("User Management")], # type: ignore
|
||||
responses=DefaultModelResponse.get_response())
|
||||
@log(menu='User management', operate='Sign out',
|
||||
get_operation_object=lambda r, k: {'name': r.user.username})
|
||||
def post(self, request: Request):
|
||||
version, get_key = Cache_Version.TOKEN.value
|
||||
cache.delete(get_key(token=request.auth), version=version)
|
||||
return result.success(True)
|
||||
|
||||
|
||||
class CaptchaView(APIView):
|
||||
@extend_schema(methods=['GET'],
|
||||
summary=_("Get captcha"),
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ from common.result import result
|
|||
from maxkb.const import CONFIG
|
||||
from models_provider.api.model import DefaultModelResponse
|
||||
from tools.serializers.tool import encryption
|
||||
from users.api import SendEmailAPI, CheckCodeAPI, ResetPasswordAPI
|
||||
from users.api.user import UserProfileAPI, TestWorkspacePermissionUserApi, DeleteUserApi, EditUserApi, \
|
||||
ChangeUserPasswordApi, UserPageApi, UserListApi, UserPasswordResponse, WorkspaceUserAPI
|
||||
from users.models import User
|
||||
from users.serializers.user import UserProfileSerializer, UserManageSerializer
|
||||
from users.serializers.user import UserProfileSerializer, UserManageSerializer, CheckCodeSerializer, \
|
||||
SendEmailSerializer, RePasswordSerializer
|
||||
|
||||
default_password = CONFIG.get('default_password', 'MaxKB@123..')
|
||||
|
||||
|
|
@ -223,3 +225,73 @@ class UserManage(APIView):
|
|||
data={'email_or_username': request.query_params.get('email_or_username', None),
|
||||
'user_id': str(request.user.id)})
|
||||
return result.success(d.page(current_page, page_size))
|
||||
|
||||
|
||||
class RePasswordView(APIView):
|
||||
|
||||
@extend_schema(methods=['POST'],
|
||||
summary=_("Change password"),
|
||||
description=_("Change password"),
|
||||
operation_id=_("Change password"), # type: ignore
|
||||
tags=[_("User Management")], # type: ignore
|
||||
request=ResetPasswordAPI.get_request(),
|
||||
responses=DefaultModelResponse.get_response())
|
||||
@log(menu='User management', operate='Change password',
|
||||
get_operation_object=lambda r, k: {'name': r.data.get('email', None)},
|
||||
get_user=lambda r: {'user_name': None, 'email': r.data.get('email', None)},
|
||||
get_details=get_re_password_details)
|
||||
def post(self, request: Request):
|
||||
serializer_obj = RePasswordSerializer(data=request.data)
|
||||
return result.success(serializer_obj.reset_password())
|
||||
|
||||
|
||||
class SendEmail(APIView):
|
||||
|
||||
@extend_schema(methods=['POST'],
|
||||
summary=_("Send email"),
|
||||
description=_("Send email"),
|
||||
operation_id=_("Send email"), # type: ignore
|
||||
tags=[_("User Management")], # type: ignore
|
||||
request=SendEmailAPI().get_request(),
|
||||
responses=SendEmailAPI().get_response())
|
||||
@log(menu='User management', operate='Send email',
|
||||
get_operation_object=lambda r, k: {'name': r.data.get('email', None)},
|
||||
get_user=lambda r: {'user_name': None, 'email': r.data.get('email', None)})
|
||||
def post(self, request: Request):
|
||||
serializer_obj = SendEmailSerializer(data=request.data)
|
||||
if serializer_obj.is_valid(raise_exception=True):
|
||||
return result.success(serializer_obj.send())
|
||||
|
||||
|
||||
class CheckCode(APIView):
|
||||
|
||||
@extend_schema(methods=['POST'],
|
||||
summary=_("Check whether the verification code is correct"),
|
||||
description=_("Check whether the verification code is correct"),
|
||||
operation_id=_("Check whether the verification code is correct"), # type: ignore
|
||||
tags=[_("User Management")], # type: ignore
|
||||
request=CheckCodeAPI().get_request(),
|
||||
responses=CheckCodeAPI().get_response())
|
||||
@log(menu='User management', operate='Check whether the verification code is correct',
|
||||
get_operation_object=lambda r, k: {'name': r.data.get('email', None)},
|
||||
get_user=lambda r: {'user_name': None, 'email': r.data.get('email', None)})
|
||||
def post(self, request: Request):
|
||||
return result.success(CheckCodeSerializer(data=request.data).is_valid(raise_exception=True))
|
||||
|
||||
|
||||
class SendEmailToCurrentUserView(APIView):
|
||||
authentication_classes = [TokenAuth]
|
||||
|
||||
@extend_schema(methods=['POST'],
|
||||
summary=_("Send email to current user"),
|
||||
description=_("Send email to current user"),
|
||||
operation_id=_("Send email to current user"), # type: ignore
|
||||
tags=[_("User Management")], # type: ignore
|
||||
request=SendEmailAPI().get_request(),
|
||||
responses=SendEmailAPI().get_response())
|
||||
@log(menu='User management', operate='Send email to current user',
|
||||
get_operation_object=lambda r, k: {'name': r.user.username})
|
||||
def post(self, request: Request):
|
||||
serializer_obj = SendEmailSerializer(data={'email': request.user.email, 'type': "reset_password"})
|
||||
if serializer_obj.is_valid(raise_exception=True):
|
||||
return result.success(serializer_obj.send())
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import {Result} from '@/request/Result'
|
||||
import {get, post, del, put} from '@/request/index'
|
||||
|
||||
import {type Ref} from 'vue'
|
||||
|
||||
const prefix = '/system/api_key'
|
||||
|
||||
/**
|
||||
* API_KEY列表
|
||||
*/
|
||||
const getAPIKey: (loading?: Ref<boolean>) => Promise<Result<any>> = () => {
|
||||
return get(`${prefix}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增API_KEY
|
||||
*/
|
||||
const postAPIKey: (loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
loading
|
||||
) => {
|
||||
return post(`${prefix}`, {}, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除API_KEY
|
||||
* @param 参数 application_id api_key_id
|
||||
*/
|
||||
const delAPIKey: (
|
||||
api_key_id: string,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<boolean>> = (api_key_id, loading) => {
|
||||
return del(`${prefix}/${api_key_id}`, undefined, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改API_KEY
|
||||
* data {
|
||||
* is_active: boolean
|
||||
* }
|
||||
* @param api_key_id
|
||||
* @param data
|
||||
* @param loading
|
||||
*/
|
||||
const putAPIKey: (
|
||||
api_key_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (api_key_id, data, loading) => {
|
||||
return put(`${prefix}/${api_key_id}`, data, undefined, loading)
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
getAPIKey,
|
||||
postAPIKey,
|
||||
delAPIKey,
|
||||
putAPIKey
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ import { Result } from '@/request/Result'
|
|||
import { get, put, post, del } from '@/request/index'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
import type { Ref } from 'vue'
|
||||
import type {ResetPasswordRequest} from "@/api/type/user.ts";
|
||||
|
||||
const prefix = '/user_manage'
|
||||
/**
|
||||
|
|
@ -64,11 +65,24 @@ const putUserManagePassword: (
|
|||
return put(`${prefix}/${user_id}/re_password`, data, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
* @param request 重置密码请求参数
|
||||
* @param loading 接口加载器
|
||||
* @returns
|
||||
*/
|
||||
const resetPassword: (
|
||||
request: ResetPasswordRequest,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<boolean>> = (request, loading) => {
|
||||
return post('/user/re_password', request, undefined, loading)
|
||||
}
|
||||
|
||||
export default {
|
||||
getUserManage,
|
||||
putUserManage,
|
||||
delUserManage,
|
||||
postUserManage,
|
||||
putUserManagePassword
|
||||
putUserManagePassword,
|
||||
resetPassword
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,9 +87,10 @@
|
|||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef" />
|
||||
<!-- <ResetPassword ref="resetPasswordRef"></ResetPassword> -->
|
||||
<!-- <AboutDialog ref="AboutDialogRef"></AboutDialog>
|
||||
<APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef" /> -->
|
||||
-->
|
||||
<!-- <UserPwdDialog ref="UserPwdDialogRef" /> -->
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
|
@ -99,14 +100,14 @@ 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 APIKeyDialog from './APIKeyDialog.vue'
|
||||
import { ComplexPermission } from '@/utils/permission/type'
|
||||
import { langList } from '@/locales/index'
|
||||
import { useLocale } from '@/locales/useLocale'
|
||||
import type ResetPassword from "@/layout/layout-header/avatar/ResetPassword.vue";
|
||||
const { user } = useStore()
|
||||
const router = useRouter()
|
||||
|
||||
const UserPwdDialogRef = ref()
|
||||
const AboutDialogRef = ref()
|
||||
const APIKeyDialogRef = ref()
|
||||
const resetPasswordRef = ref<InstanceType<typeof ResetPassword>>()
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ import type { ResetPasswordRequest } from '@/api/type/user'
|
|||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { MsgSuccess } from '@/utils/message'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import UserApi from '@/api/user'
|
||||
import UserApi from '@/api/user/user-manage'
|
||||
import { t } from '@/locales'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
|
|
|||
Loading…
Reference in New Issue