Browse Source

feat: 接入强制修改密码逻辑

BaiLuoYan 21 hours ago
parent
commit
d29a4d26d2
3 changed files with 72 additions and 2 deletions
  1. 9 1
      src/app.tsx
  2. 61 0
      src/components/ForceChangePasswordModal/index.tsx
  3. 2 1
      src/components/index.ts

+ 9 - 1
src/app.tsx

@@ -1,7 +1,14 @@
 import bg1Layout from '@/assets/images/lay-bg1.webp';
 import bg2Layout from '@/assets/images/lay-bg2.webp';
 import bg3Layout from '@/assets/images/lay-bg3.webp';
-import { AvatarDropdown, AvatarName, Footer, Icon, SelectLang } from '@/components';
+import {
+  AvatarDropdown,
+  AvatarName,
+  Footer,
+  ForceChangePasswordModal,
+  Icon,
+  SelectLang,
+} from '@/components';
 import { secureLocalStorage as ls } from '@/utils/localUtils';
 import { Settings as LayoutSettings } from '@ant-design/pro-components';
 import mcLogoSvg from '@svgs/multi-color/mc-logo.svg';
@@ -152,6 +159,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
         <>
           {children}
           <VersionCheckComponent />
+          <ForceChangePasswordModal />
         </>
       );
     },

+ 61 - 0
src/components/ForceChangePasswordModal/index.tsx

@@ -0,0 +1,61 @@
+import { PasswordFields } from '@/pages/Sys/ModifyPassword/components/PasswordFields';
+import * as api from '@/services/login';
+import { message } from '@/utils/antdAppInstance';
+import { setToken } from '@/utils/authUtils';
+import { useModel } from '@umijs/max';
+import { Form, Modal } from 'antd';
+import { flushSync } from 'react-dom';
+
+export const ForceChangePasswordModal = () => {
+  const { initialState, setInitialState } = useModel('@@initialState');
+  const [form] = Form.useForm();
+
+  const mustChange = initialState?.currentUser?.mustChangePassword === 1;
+
+  const handleOk = async () => {
+    try {
+      const values = await form.validateFields();
+      const res = await api.fetchUserUpdatePassword({
+        oldPassword: values.oldPassword,
+        newPassword: values.newPassword,
+      });
+      if (!res.success || !res.data) {
+        message.error(res.errorMessage || '修改失败');
+        return;
+      }
+      const { accessToken, refreshToken, expires, userInfo } = res.data;
+      setToken({ accessToken, refreshToken, expires, ...userInfo });
+      flushSync(() => {
+        setInitialState((s) => ({
+          ...s,
+          currentUser: { ...s?.currentUser, ...userInfo },
+        }));
+      });
+      message.success('密码修改成功');
+      form.resetFields();
+    } catch {
+      // validation failed
+    }
+  };
+
+  return (
+    <Modal
+      open={mustChange}
+      title="请修改初始密码"
+      okText="确认修改"
+      cancelButtonProps={{ style: { display: 'none' } }}
+      closable={false}
+      maskClosable={false}
+      keyboard={false}
+      onOk={handleOk}
+      width={480}
+    >
+      <p className="text-(--ant-color-text-secondary) text-sm mb-4">
+        您的账号正在使用初始密码,为了账号安全,请立即修改密码后再继续使用系统。
+      </p>
+      <Form form={form} layout="vertical">
+        <PasswordFields />
+      </Form>
+    </Modal>
+  );
+};

+ 2 - 1
src/components/index.ts

@@ -1,7 +1,8 @@
 import Footer from './Footer';
+import { ForceChangePasswordModal } from './ForceChangePasswordModal';
 import { Icon } from './Icon';
 import { Question, SelectLang } from './RightContent';
 import { AvatarDropdown, AvatarName } from './RightContent/AvatarDropdown';
 
 export type { IconProps } from './Icon';
-export { AvatarDropdown, AvatarName, Footer, Icon, Question, SelectLang };
+export { AvatarDropdown, AvatarName, Footer, ForceChangePasswordModal, Icon, Question, SelectLang };