Browse Source

feat: 新增修改密码功能

曾坤森 1 month ago
parent
commit
24d2cf0c77

+ 6 - 3
src/api/user.ts

@@ -1,4 +1,3 @@
-import axios from 'axios';
 import type { RouteRecordNormalized } from 'vue-router';
 import { UserState } from '@/store/modules/user/types';
 import instance from './interceptor';
@@ -90,9 +89,13 @@ export async function getUserInfo(params: object): Promise<UserResData> {
   const res = await instance.post('/api/Author/GetUser', params);
   return res.data;
 }
+export async function saveUpdatePassword(params: object): Promise<LoginRes> {
+  const res = await instance.post('/api/Author/UpdatePassword', params);
+  return res.data;
+}
 export function logout() {
-  return axios.post<LoginRes>('/api/user/logout');
+  return instance.post<LoginRes>('/api/user/logout');
 }
 export function getMenuList() {
-  return axios.post<RouteRecordNormalized[]>('/api/user/menu');
+  return instance.post<RouteRecordNormalized[]>('/api/user/menu');
 }

+ 15 - 2
src/components/navbar/index.vue

@@ -167,6 +167,14 @@
                 </span>
               </a-space>
             </a-doption>
+            <a-doption>
+              <a-space @click="handleToggle">
+                <icon-settings />
+                <span>
+                  {{ $t('login.form.changePassword') }}
+                </span>
+              </a-space>
+            </a-doption>
             <a-doption>
               <a-space @click="handleLogout">
                 <icon-export />
@@ -180,10 +188,11 @@
       </li>
     </ul>
   </div>
+  <ChangePassword v-model="showChangePassword" />
 </template>
 
 <script name="NavBar" lang="ts" setup>
-import { computed, ref } from 'vue';
+import { computed, ref, shallowRef } from 'vue';
 import { Message } from '@arco-design/web-vue';
 import { useDark, useToggle, useFullscreen } from '@vueuse/core';
 import { useAppStore, useUserStore } from '@/store';
@@ -193,13 +202,14 @@ import useUser from '@/hooks/user';
 import Menu from '@/components/menu/index.vue';
 import MessageBox from '../message-box/index.vue';
 import GlobalBreadcrumb from '../global-breadcrumb/index.vue';
-
+import ChangePassword from '@/views/login/components/change-password.vue';
 const appStore = useAppStore();
 const userStore = useUserStore();
 const { logout } = useUser();
 const { changeLocale, currentLocale } = useLocale();
 const { isFullscreen, toggle: toggleFullScreen } = useFullscreen();
 const locales = [...LOCALE_OPTIONS];
+const showChangePassword = shallowRef<boolean>(false);
 const avatar = computed(() => {
   return userStore.avatar;
 });
@@ -261,6 +271,9 @@ const switchRoles = async () => {
   const res = await userStore.switchRoles();
   Message.success(res as string);
 };
+const handleToggle = () => {
+  showChangePassword.value = true;
+};
 const setCollapse = (val: boolean) => {
   if (appStore.device === 'desktop')
     appStore.updateSettings({ menuCollapse: val });

+ 2 - 0
src/locale/en-US/component.ts

@@ -1,4 +1,6 @@
 export default {
   'form.rules.required': 'This field is required',
   'form.rules.email': 'Please enter a valid email address',
+  'form.rules.passwordNotMatch': 'The passwords entered twice are inconsistent',
+  'form.rules.passwordNotSameMatch': 'Cannot be the same as the old password',
 };

+ 2 - 0
src/locale/zh-CN/component.ts

@@ -1,4 +1,6 @@
 export default {
   'form.rules.required': '不能为空',
   'form.rules.email': '请输入正确的邮箱地址',
+  'form.rules.passwordNotMatch': '两次输入的密码不一致',
+  'form.rules.passwordNotSameMatch': '新密码跟旧密码不能相同',
 };

+ 3 - 8
src/views/dashboard/camera/index.vue

@@ -123,15 +123,10 @@ import {
 import type { CameraParams, DataList } from '@/api/camera';
 import { SizeProps, Pagination } from '@/types/global';
 import BTag from '@/components/business/b-tag/index.vue';
-import { Modal } from '@arco-design/web-vue';
-import type { TableColumnData } from '@arco-design/web-vue';
 import useLoading from '@/hooks/loading';
 import { useI18n } from 'vue-i18n';
-import dayjs from 'dayjs';
-import { downLoadFun } from '@/utils/const';
-import { useIntervalFn } from '@vueuse/core';
-import EditDialog from './edit.vue';
 import router from '@/router';
+import type { RequestOption } from '@arco-design/web-vue';
 
 const { t } = useI18n();
 
@@ -207,9 +202,9 @@ const search = () => {
 const reset = () => {
   formModel.value = generateFormModel();
 };
-const uploadFun = (file: File) => {
+const uploadFun = (file: RequestOption) => {
   const formData = new FormData();
-  formData.append('file', file);
+  formData.append('file', file.fileItem.file);
 
   postUploadFile(formData).then(res => {
     console.log('res', res);

+ 135 - 0
src/views/login/components/change-password.vue

@@ -0,0 +1,135 @@
+<template>
+  <div>
+    <a-modal
+      v-model:visible="visible"
+      width="40%"
+      :title="$t('login.form.changePassword')"
+      @cancel="() => handleCancel()"
+      @before-ok="handleBeforeOk"
+    >
+      <a-form :model="form" auto-label-width ref="formRef">
+        <a-row :gutter="8">
+          <a-col :span="24">
+            <a-form-item
+              field="oledPassword"
+              :label="t('login.form.currentPassword')"
+              :rules="getRules(t).required"
+            >
+              <a-input-password v-model="form.oledPassword" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-item
+              field="password"
+              :label="t('login.form.newPassword')"
+              :rules="[
+                ...getRules(t).required,
+                {
+                  validator: (value: string, cb: (error?: string) => void) => {
+                    if (value === form.oledPassword) {
+                      cb(t('form.rules.passwordNotSameMatch'));
+                    } else {
+                      cb();
+                    }
+                  },
+                },
+              ]"
+            >
+              <a-input-password v-model="form.password" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-item
+              field="confirmPassword"
+              :label="t('login.form.confirmNewPassword')"
+              :rules="[
+                ...getRules(t).required,
+                {
+                  validator: (value: string, cb: (error?: string) => void) => {
+                    if (value !== form.password) {
+                      cb(t('form.rules.passwordNotMatch'));
+                    } else {
+                      cb();
+                    }
+                  },
+                },
+              ]"
+            >
+              <a-input-password v-model="form.confirmPassword" />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </a-form>
+    </a-modal>
+  </div>
+</template>
+<script setup lang="ts" name="ChangePassword">
+import { reactive, ref, shallowRef, watch, getCurrentInstance } from 'vue';
+import { getPluginDetails } from '@/api/plugin';
+import type { DataList } from '@/api/plugin';
+import { privilegeList, getRules } from '@/utils/const';
+import { useI18n } from 'vue-i18n';
+import type { UserData, UserParams } from '@/api/user';
+import { getUserList, saveUpdatePassword } from '@/api/user';
+
+const formRef = ref();
+const { t } = useI18n();
+
+const this_ = getCurrentInstance()?.appContext.config.globalProperties;
+export interface ChangePasswordForm {
+  oledPassword: string;
+  password: string;
+  confirmPassword: string;
+}
+interface ChangePasswordProps {
+  modelValue: boolean;
+}
+interface ChangePasswordEmits {
+  (e: 'update:modelValue', value: boolean): void;
+}
+const props = withDefaults(defineProps<ChangePasswordProps>(), {
+  modelValue: false,
+  id: null,
+});
+const emit = defineEmits<ChangePasswordEmits>();
+const visible = shallowRef<boolean>(false);
+watch(
+  () => props.modelValue,
+  value => {
+    visible.value = value;
+    if (value) {
+    }
+  }
+);
+const formModel = () => {
+  return {} as ChangePasswordForm;
+};
+const form = ref<ChangePasswordForm>(formModel());
+const handleBeforeOk = (done: (closed: boolean) => void) => {
+  formRef.value.validate().then((data: ChangePasswordForm) => {
+    if (!data) {
+      saveUpdatePassword(form.value)
+        .then(res => {
+          if (res.success) {
+            this_?.$message.success(t('message.success'));
+            handleCancel();
+            done(true); // 关闭模态框
+          } else {
+            res.message && this_?.$message.error(res.message);
+            done(false); // 关闭loading
+          }
+        })
+        .catch(() => {
+          done(false); // 不关闭模态框(例如提交失败时)
+        });
+    } else {
+      done(false); // 不关闭模态框(例如提交失败时)
+    }
+  });
+};
+const handleCancel = () => {
+  form.value = formModel();
+  visible.value = false;
+  emit('update:modelValue', false);
+};
+</script>

+ 4 - 5
src/views/login/components/login-form.vue

@@ -43,16 +43,15 @@
         </a-input-password>
       </a-form-item>
       <a-space :size="16" direction="vertical">
-        <!-- <div class="login-form-password-actions">
-          <a-checkbox
+        <div class="login-form-password-actions">
+          <!-- <a-checkbox
             checked="rememberPassword"
             :model-value="loginInfo.rememberPassword"
             @change="setRememberPassword as any"
           >
             {{ t('login.form.rememberPassword') }}
-          </a-checkbox>
-          <a-link>{{ t('login.form.forgetPassword') }}</a-link>
-        </div> -->
+          </a-checkbox> -->
+        </div>
         <a-button type="primary" html-type="submit" long :loading="loading">
           {{ t('login.form.login') }}
         </a-button>

+ 4 - 0
src/views/login/locale/en-US.ts

@@ -8,6 +8,10 @@ export default {
   'login.form.password.placeholder': 'Please enter the password',
   'login.form.rememberPassword': 'Remember password',
   'login.form.forgetPassword': 'Forgot password',
+  'login.form.changePassword': 'Change Password',
+  'login.form.currentPassword': 'Current Password',
+  'login.form.newPassword': 'New Password',
+  'login.form.confirmNewPassword': 'Confirm New Password',
   'login.form.login': 'login',
   'login.form.register': 'register account',
   'login.banner.slogan1': 'Out-of-the-box high-quality template',

+ 4 - 0
src/views/login/locale/zh-CN.ts

@@ -8,6 +8,10 @@ export default {
   'login.form.password.placeholder': '请输入密码',
   'login.form.rememberPassword': '记住密码',
   'login.form.forgetPassword': '忘记密码',
+  'login.form.changePassword': '修改密码',
+  'login.form.currentPassword': '当前密码',
+  'login.form.newPassword': '新密码',
+  'login.form.confirmNewPassword': '确认新密码',
   'login.form.login': '登录',
   'login.form.register': '注册账号',
   'login.banner.slogan1': '开箱即用的高质量模板',