import React, { useCallback, useState, useMemo } from "react"; import { LogoutOutlined, LockOutlined } from "@ant-design/icons"; import { Menu, Spin, Form, Modal, message, Avatar } from "antd"; import { history, useModel, useRequest } from "umi"; import { stringify } from "querystring"; import HeaderDropdown from "../HeaderDropdown"; import styles from "./index.less"; import { fakeAccountLoginOut, changePwd } from "@/services/login"; import InitForm from "@/components/InitForm"; import { doFetch } from "@/utils/doFetch"; import AES from "crypto-js/aes"; import ECB from "crypto-js/mode-ecb"; import Pkcs7 from "crypto-js/pad-pkcs7"; import Utf8 from "crypto-js/enc-utf8"; import moment from "moment"; /** * 退出登录,并且将当前的 url 保存 */ const loginOut = async () => { await fakeAccountLoginOut(); const { query = {} } = history.location; const { redirect } = query; // Note: There may be security issues, please note if (window.location.pathname !== "/user/login" && !redirect) { localStorage.clear(); history.replace("/user/login"); } }; const AvatarDropdown = ({ menu }) => { const { initialState, setInitialState } = useModel("@@initialState"); const [visible, cv] = useState(false), [formRef] = Form.useForm(), { run, loading } = useRequest(doFetch, { manual: true, formatResult: (res) => res, onSuccess: (result, params) => { if (result.code == "0000") { cv(false); message.success("密码修改成功,请重新登录", 2, () => { setInitialState((s) => ({ ...s, currentUser: undefined, newMenu: undefined, })); loginOut(); }); } }, }); const fields = useMemo(() => { return { password: { value: null, type: "password", title: "密码", name: ["password"], required: true, }, newPassword: { value: null, type: "password", title: "新密码", name: ["newPassword"], required: true, }, confirmPassword: { value: null, type: "password", title: "确认密码", name: ["confirmPassword"], required: true, checkConfirm: (rule, value) => { if (value && value !== formRef.getFieldValue("newPassword")) { return Promise.reject("2次密码不一致!"); } else { return Promise.resolve(); } }, }, }; }, []); const onMenuClick = useCallback( (event) => { const { key } = event; if (key === "logout") { setInitialState((s) => ({ ...s, currentUser: undefined, newMenu: undefined, })); loginOut(); return; } else if (key == "changepwd") { cv(true); return; } history.push(`/account/${key}`); }, [setInitialState] ); const loadings = ( <span className={`${styles.action} ${styles.account}`}> <Spin size="small" style={{ marginLeft: 8, marginRight: 8, }} /> </span> ); if (!initialState) { return loadings; } const { currentUser } = initialState; if (!currentUser || !currentUser.userName) { return loadings; } let saveData = (values) => { let newfields = JSON.parse(JSON.stringify(values)); delete newfields.confirmPassword; let timestamp = moment().valueOf().toString() + "acb"; let newtimestamp = AES.encrypt(timestamp, Utf8.parse("NANGAODEAESKEY--"), { mode: ECB, padding: Pkcs7, }).toString(); let newPassword = AES.encrypt(values.newPassword, Utf8.parse(timestamp), { mode: ECB, padding: Pkcs7, }).toString(), password = AES.encrypt(values.password, Utf8.parse(timestamp), { mode: ECB, padding: Pkcs7, }).toString(); let postData = { password, newPassword, encryptKey: newtimestamp, }; run({ url: "/ngic-auth/sysUser/changePassword", params: { ...postData } }); }; const menuHeaderDropdown = ( <Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}> <Menu.Item key="changepwd"> <LockOutlined /> 修改密码 </Menu.Item> <Menu.Divider /> <Menu.Item key="logout"> <LogoutOutlined /> 退出登录 </Menu.Item> </Menu> ); return ( <div> <Modal title="修改密码" visible={visible} onCancel={() => { cv(false); }} destroyOnClose={true} maskClosable={false} footer={false} > <InitForm formRef={formRef} fields={fields} col={{ span: 24 }} onChange={(changedValues, allValues) => { }} submitData={(values, fn) => { saveData(values, fn); }} submitting={loading || !visible} > </InitForm> </Modal> <HeaderDropdown overlay={menuHeaderDropdown}> <span className={`${styles.action} ${styles.account}`}> <Avatar style={{marginRight:12,backgroundColor:"#1890ff"}}>{currentUser.userName.substr(0,1)}</Avatar> <span className={`${styles.name} anticon`}> {currentUser.userName} </span> </span> </HeaderDropdown> </div> ); }; export default AvatarDropdown;