diff --git a/components.d.ts b/components.d.ts
index e472236..df6e3ab 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -26,6 +26,9 @@ declare module 'vue' {
     ASwitch: typeof import('ant-design-vue/es')['Switch']
     ATextarea: typeof import('ant-design-vue/es')['Textarea']
     ATooltip: typeof import('ant-design-vue/es')['Tooltip']
+    ElButton: typeof import('element-plus/es')['ElButton']
+    ElDialog: typeof import('element-plus/es')['ElDialog']
+    ElInput: typeof import('element-plus/es')['ElInput']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     Empty: typeof import('./src/components/empty/Empty.vue')['default']
     ImageCropper: typeof import('./src/components/image-cropper/index.vue')['default']
diff --git a/src/services/index.js b/src/services/index.js
index a15deb8..29d69b8 100644
--- a/src/services/index.js
+++ b/src/services/index.js
@@ -21,12 +21,12 @@ export function logout() {
 }
 export function getConfig(params) {
   return request.get('/sms/v1/logo', {
-    params: wrapperParams(params),
+    params: wrapperParams(params)
   })
 }
 export function getDict(data) {
   return request.get('/dict/children', {
-    params: wrapperParams(data),
+    params: wrapperParams(data)
   })
 }
 export function getSysconf() {
@@ -48,7 +48,7 @@ export function getPortal(params) {
 }
 export function getServiceQuota(tenantId, data) {
   return request.get(`/cos/v1/tenants/${tenantId}/quotas`, {
-    params: wrapperParams(data),
+    params: wrapperParams(data)
   })
 }
 export function replaceToken(params) {
@@ -69,7 +69,7 @@ export function getSystemTreeConfigs(params) {
 // 更新系统配置信息
 export function updateSystemConfigs(params) {
   return request.put('/sms/v1/system-configs', params, {
-    headers: { 'Content-Type': 'multipart/form-data', BsmAjaxHeader: true, options: { noSeri: true } },
+    headers: { 'Content-Type': 'multipart/form-data', BsmAjaxHeader: true, options: { noSeri: true } }
   })
 }
 // 测试连接
@@ -79,3 +79,8 @@ export function testLinkApi(category) {
 export function getVertifyCode(params) {
   return request.post('/sms/v1/users/code', wrapperParams(params))
 }
+
+// 忘记密码
+export function forgetPassword(params) {
+  return request.post('/sms/v1/users/forget', params)
+}
diff --git a/src/views/login/login.vue b/src/views/login/login.vue
index 8b04ee4..c1d4563 100644
--- a/src/views/login/login.vue
+++ b/src/views/login/login.vue
@@ -42,13 +42,42 @@
               
               记住密码
             
-            {{ configs.helpInformationContent }}
+            {{ configs.helpInformationContent }}
+            忘记密码
           
         
         登录
       
     
     
{{ configs.copyrightInformation }}
+    
+    
+      
+        
+          
+        
+        
+          
+        
+        
+          
+        
+        
+          
+        
+      
+      
+        
+      
+    
   
 
 
@@ -61,8 +90,8 @@ import { useStore } from 'vuex'
 import { useRouter, useRoute } from 'vue-router'
 import setLoginData from './tools'
 import { required } from '@/validate'
-import { getVertifyCode } from '@/services'
-import { message } from 'ant-design-vue'
+import { getVertifyCode, forgetPassword } from '@/services'
+import { message, Modal } from 'ant-design-vue'
 
 export default {
   components: { UserOutlined, LockOutlined },
@@ -78,11 +107,23 @@ export default {
       verifyLoading: false,
       countdown: 0,
       isCountingDown: false,
-      needSmsVerify: true
+      needSmsVerify: true,
+      showForgotPasswordDialog: false,
+      forgotPasswordForm: {
+        account: '',
+        password: '',
+        confirmPassword: '',
+        verificationCode: ''
+      },
+      forgotPasswordLoading: false,
+      codeCountdown: 0,
+      codeLoading: false
     })
     const store = useStore()
+    const pwdRule = computed(() => store.state.app.systemConfig.pwdStrength + ',pswNoSpace' + ',required')
     const configs = computed(() => store.getters.pageConfig)
     const loginFormRef = ref(null)
+    const forgotPasswordFormRef = ref(null)
     let countdownTimer = null
 
     // 开始倒计时
@@ -122,12 +163,15 @@ export default {
     const route = useRoute()
 
     // 监听account变化,如果清空则重置needSmsVerify
-    watch(() => state.loginForm.account, (newAccount) => {
-      if (!newAccount.trim()) {
-        state.needSmsVerify = true
-        resetCountdown() // 同时重置倒计时
+    watch(
+      () => state.loginForm.account,
+      (newAccount) => {
+        if (!newAccount.trim()) {
+          state.needSmsVerify = true
+          resetCountdown() // 同时重置倒计时
+        }
       }
-    })
+    )
 
     const getVertify = () => {
       if (state.isCountingDown) return // 如果正在倒计时,不允许重复点击
@@ -209,6 +253,58 @@ export default {
         state.capsTooltip = false
       }
     }
+
+    function getVerificationCode() {
+      if (!state.forgotPasswordForm.account) {
+        message.error('请先输入用户名')
+        return
+      }
+      state.codeLoading = true
+      getVertifyCode({ account: state.forgotPasswordForm.account })
+        .then((res) => {
+          if (res.success) {
+            message.success('验证码已发送')
+            state.codeCountdown = 60
+            const timer = setInterval(() => {
+              state.codeCountdown--
+              if (state.codeCountdown <= 0) {
+                clearInterval(timer)
+              }
+            }, 1000)
+          }
+        })
+        .finally(() => {
+          state.codeLoading = false
+        })
+    }
+
+    function openForgotPasswordDialog() {
+      // 将当前登录表单的用户名带入忘记密码表单
+      state.forgotPasswordForm.account = state.loginForm.account
+      state.showForgotPasswordDialog = true
+    }
+
+    function handleForgotPassword() {
+      forgotPasswordFormRef.value.validate().then(() => {
+        const { account, password, confirmPassword, verificationCode } = state.forgotPasswordForm
+        if (confirmPassword !== password) return message.error('两次输入的密码不相同')
+        state.forgotPasswordLoading = true
+        forgetPassword({
+          account,
+          password: encrypt(password),
+          code: verificationCode
+        })
+          .then((res) => {
+            if (res.success) {
+              message.success(res.message)
+              state.showForgotPasswordDialog = false
+            }
+          })
+          .finally(() => {
+            state.forgotPasswordLoading = false
+          })
+      })
+    }
     return {
       ...toRefs(state),
       required,
@@ -218,7 +314,12 @@ export default {
       checkCapslock,
       getVertify,
       startCountdown,
-      resetCountdown
+      resetCountdown,
+      forgotPasswordFormRef,
+      getVerificationCode,
+      openForgotPasswordDialog,
+      handleForgotPassword,
+      pwdRule
     }
   }
 }