ChangePasswordModal.jsx 9.66 KB
Newer Older
1
/* eslint-disable import/no-unresolved */
2
import React, { useEffect, useState } from 'react';
3 4
import { Modal, Form, Input, notification, message, Divider } from 'antd';
import voca from 'voca';
5
import classNames from 'classnames';
皮倩雯's avatar
皮倩雯 committed
6 7 8 9 10 11 12
import {
  editUser,
  updateUserPassword,
  GetPasswordRegularization,
  SysConfiguration,
} from '@/services/userManage/api';
import { encipher } from '@wisdom-utils/utils/lib/helpers';
13
import styles from './AddUserModal.less';
14 15

const ChangePasswordModal = props => {
16 17 18 19 20 21 22 23
  const { visible, currentUser, currentSelectOrg, onCancel, onSelect, submitSearchUser } = props;
  const [editUserForm] = Form.useForm(); // 编辑用户
  /** ***正则验证**** */
  const noChinese = new RegExp(/^[^\u4e00-\u9fa5]+$/); // 不能包含中文
  const isPhone = new RegExp(/^1(3|4|5|6|7|8|9)\d{9}$/); // 手机号
  const isEmail = new RegExp(
    /^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*@[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*\.[a-z]{2,}$/,
  ); // 邮箱
24
  const [passwordForm] = Form.useForm(); // 修改密码
25 26
  const [newPasswordLevel, setNewPasswordLevel] = useState('');
  const [passwordConfirmLevel, setPasswordConfirmLevel] = useState('');
27
  const [rules, setRules] = useState();
皮倩雯's avatar
皮倩雯 committed
28
  const [pasType, setPasType] = useState('');
29

30
  useEffect(() => {
31
    if (visible) {
32
      getPasswordRule();
皮倩雯's avatar
皮倩雯 committed
33
      passwordType();
34 35 36 37 38 39
      editUserForm.setFieldsValue({
        loginName: voca.stripTags(currentUser.loginName),
        userName: voca.stripTags(currentUser.userName),
        phone: voca.stripTags(currentUser.phone) || '',
        email: currentUser.email || '',
      });
40
      passwordForm.setFieldsValue({
41
       // oldPassword: currentUser.password,
42 43 44
        newPassword: '',
        passwordConfirm: '',
      });
45 46 47
    } else {
      setNewPasswordLevel('');
      setPasswordConfirmLevel('');
48
    }
49
  }, [visible]);
50

皮倩雯's avatar
皮倩雯 committed
51 52 53 54 55 56 57 58
  const passwordType = () => {
    SysConfiguration().then(res => {
      if (res.code === 0) {
        setPasType(res.data);
      }
    });
  };

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
  const getPasswordRule = () => {
    GetPasswordRegularization().then(res => {
      if (res.code === 0) {
        setRules(res.data);
      }
    });
  };

  // 提交-编辑用户
  const submitEditUser = () => {
    const newPassword = passwordForm.getFieldValue('newPassword');
    const passwordConfirm = passwordForm.getFieldValue('passwordConfirm');
    passwordForm.validateFields().then(validate => {
      if (validate) {
        if ((newPassword && newPassword.length < 6) || (passwordConfirm && passwordConfirm < 6)) {
          notification.error({
            message: '提交失败',
            description: '密码至少为6位!',
          });
          return;
        }
        if (newPassword !== passwordConfirm) {
          notification.error({
            message: '提交失败',
            description: '确认密码不一致!',
          });
          return;
        }
        if (newPassword && newPassword) {
          if (newPasswordLevel === '弱') {
            notification.error({
              message: '提交失败',
              description: '密码强度太弱,加强密码强度',
            });
            return;
          }
          if (
            !/^(?=.*[a-zA-Z])(?=.*\d)[\w\S]{6,16}$/.test(newPassword) ||
            !/^(?!.*(?:SELECT|UPDATE|INSERT|AND|OR|'|"|;|--|\\)).*$/.test(newPassword)
          ) {
            notification.error({
              message: '提交失败',
              description: '密码验证未通过',
            });
            return;
          }
        }
        // 所有验证通过才可以提交,phone/email为空时不验证

        submitChangePassword();
      }
    });
  };
  const title = (
    <span>
      重置用户
      <span style={{ fontWeight: 'bold', color: 'rgb(24, 144, 255)' }}>
{currentUser.userName}
      </span>
      的密码
    </span>
  );

122 123
  // 提交-修改密码
  const submitChangePassword = () => {
124
   // const oldPassword = passwordForm.getFieldValue('oldPassword');
125 126 127 128 129 130 131 132 133 134
    const newPassword = passwordForm.getFieldValue('newPassword');
    const passwordConfirm = passwordForm.getFieldValue('passwordConfirm');
    if (
      newPassword &&
      newPassword.length >= 6 &&
      passwordConfirm &&
      newPassword.length >= 6 &&
      newPassword === passwordConfirm
    ) {
      updateUserPassword({
135
        UserId: +currentUser.userId,
136
      //  OldPassWord: oldPassword,
皮倩雯's avatar
皮倩雯 committed
137
        NewPassWord: encipher(newPassword, pasType ? pasType : '').toUpperCase(),
138 139 140 141
      })
        .then(res => {
          if (res.code === 0) {
            onCancel();
142
            // eslint-disable-next-line no-unused-expressions
143
            currentSelectOrg === '-1' ? submitSearchUser() : onSelect([currentSelectOrg]);
144 145 146 147
            notification.success({
              message: '修改成功',
              duration: 2,
            });
148 149 150
          } else {
            notification.error({
              message: '提交失败',
151
              description: res.msg,
152 153
            });
          }
tianfen's avatar
tianfen committed
154
          passwordForm.setFieldsValue({
155
         //   oldPassword: currentUser.password,
tianfen's avatar
tianfen committed
156 157 158
            newPassword: '',
            passwordConfirm: '',
          });
159 160 161 162 163 164
        })
        .catch(err => {
          message.error(err);
        });
    }
  };
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
  const changeValue = changedFields => {
    if (changedFields[0].name[0] === 'newPassword') {
      setNewPasswordLevel(checkStrong(changedFields[0].value));
    }
    if (changedFields[0].name[0] === 'passwordConfirm') {
      setPasswordConfirmLevel(checkStrong(changedFields[0].value));
    }
  };
  const checkStrong = sValue => {
    let modes = 0;
    // 正则表达式验证符合要求的
    if (sValue.length < 1) return modes;
    if (/\d/.test(sValue)) modes++; // 数字
    if (/[a-z]/.test(sValue)) modes++; // 小写
    if (/[A-Z]/.test(sValue)) modes++; // 大写
    if (/[_\W]/.test(sValue)) modes++; // 特殊字符
    console.log(modes, 'modes');
    // 逻辑处理
    // eslint-disable-next-line default-case
    switch (modes) {
      case 1:
        return '弱';
      case 2:
        if (sValue.length > 8) {
          return '中';
        }
        return '弱';
192 193 194
      case 3:
        if (sValue.length > 8) {
          return '强';
195
        }
196 197
        return '中';
      case 4:
198 199 200
        return '强';
    }
  };
201 202
  return (
    <Modal
203
      title={title}
204
      visible={visible}
205 206
      maskClosable={false}
      destroyOnClose
207
      onOk={submitEditUser}
tianfen's avatar
tianfen committed
208 209
      onCancel={() => {
        onCancel();
210
        passwordForm.resetFields();
tianfen's avatar
tianfen committed
211
      }}
212 213 214
      okText="确认"
      cancelText="取消"
    >
215 216
      <div className={styles.modalContent}>
        <Form form={passwordForm} labelCol={{ span: 4 }} onFieldsChange={changeValue}>
217
          {/* <Form.Item name="oldPassword" label="原始密码">
218
            <Input disabled />
219
          </Form.Item> */}
220 221 222 223 224
          <div className={styles.formBox}>
            <Form.Item
              name="newPassword"
              label="新密码"
              rules={[
225 226 227 228 229
                { required: true, message: '请输入密码' },
                {
                  pattern: rules ? rules.regex : `/^(?=.*[a-zA-Z])(?=.*d)[wS]{6,16}$/`,
                  message: rules ? rules.tip : '长度6-16位,必须包含数字与字母',
                },
230
                {
231 232
                  pattern: /^(?!.*(?:SELECT|UPDATE|INSERT|AND|OR|'|"|;|--|\\)).*$/,
                  message: '当前密码存在sql注入风险,请重新输入', // 防止sql注入
233
                },
234
                // { required: true },
235 236
              ]}
            >
237 238 239 240 241 242 243 244 245 246 247 248
              <Input.Password
                placeholder="请输入新密码"
                autoComplete="off"
                maxLength="16"
                onCopy={e => {
                  e.preventDefault();
                }}
                onPaste={e => {
                  // 禁止粘贴
                  e.preventDefault();
                }}
              />
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
            </Form.Item>
            <div
              className={classNames(styles.tipsText, {
                [styles.tipsRed]: newPasswordLevel === '弱',
                [styles.tipsOrange]: newPasswordLevel === '中',
                [styles.tipsGreen]: newPasswordLevel === '强',
              })}
            >
              {newPasswordLevel}
            </div>
          </div>
          <div className={styles.formBox}>
            <Form.Item
              name="passwordConfirm"
              label="确认密码"
              rules={[
265 266 267 268 269
                { required: true, message: '请输入密码' },
                {
                  pattern: rules ? rules.regex : `/^(?=.*[a-zA-Z])(?=.*d)[wS]{6,16}$/`,
                  message: rules ? rules.tip : '长度6-16位,必须包含数字与字母',
                },
270
                {
271 272
                  pattern: /^(?!.*(?:SELECT|UPDATE|INSERT|AND|OR|'|"|;|--|\\)).*$/,
                  message: '当前密码存在sql注入风险,请重新输入', // 防止sql注入
273 274 275
                },
              ]}
            >
276 277 278 279 280 281 282 283 284 285 286 287
              <Input.Password
                placeholder="再次确认新密码"
                autoComplete="off"
                maxLength="16"
                onCopy={e => {
                  e.preventDefault();
                }}
                onPaste={e => {
                  // 禁止粘贴
                  e.preventDefault();
                }}
              />
288 289 290 291 292 293 294 295 296 297 298 299 300
            </Form.Item>
            <div
              className={classNames(styles.tipsText, {
                [styles.tipsRed]: passwordConfirmLevel === '弱',
                [styles.tipsOrange]: passwordConfirmLevel === '中',
                [styles.tipsGreen]: passwordConfirmLevel === '强',
              })}
            >
              {passwordConfirmLevel}
            </div>
          </div>
        </Form>
      </div>
301 302 303 304 305
    </Modal>
  );
};

export default ChangePasswordModal;