From 5954dac87b14cb9f20acde96f1666619be28833e Mon Sep 17 00:00:00 2001 From: Ky_Gyt <1971574843@qq.com> Date: Wed, 30 Jun 2021 11:42:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E8=AE=BE=E7=BD=AE=E5=92=8C?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-react/src/common/storage/index.js | 3 +- web-react/src/pages/system/account/index.jsx | 41 ++ .../src/pages/system/account/setting/info.jsx | 127 +++++ .../system/account/setting/satety/index.jsx | 179 +++++++ .../system/account/setting/satety/mail.jsx | 454 +++++++++++++++++ .../account/setting/satety/password.jsx | 107 ++++ .../system/account/setting/satety/phone.jsx | 455 ++++++++++++++++++ .../src/views/main/_layout/header/user.jsx | 11 +- 8 files changed, 1374 insertions(+), 3 deletions(-) create mode 100644 web-react/src/pages/system/account/index.jsx create mode 100644 web-react/src/pages/system/account/setting/info.jsx create mode 100644 web-react/src/pages/system/account/setting/satety/index.jsx create mode 100644 web-react/src/pages/system/account/setting/satety/mail.jsx create mode 100644 web-react/src/pages/system/account/setting/satety/password.jsx create mode 100644 web-react/src/pages/system/account/setting/satety/phone.jsx diff --git a/web-react/src/common/storage/index.js b/web-react/src/common/storage/index.js index 73e8b15..444d5c1 100644 --- a/web-react/src/common/storage/index.js +++ b/web-react/src/common/storage/index.js @@ -1,9 +1,10 @@ const SESSION_KEY = '__SESSION' const SETTING_KEY = '__SETTINGS' const GLOBAL_INFO_KEY = '__GLOBAL_INFO' - +const COUNT_DWON_KEY = '__COUNT_DWON' export { SESSION_KEY, SETTING_KEY, GLOBAL_INFO_KEY, + COUNT_DWON_KEY } \ No newline at end of file diff --git a/web-react/src/pages/system/account/index.jsx b/web-react/src/pages/system/account/index.jsx new file mode 100644 index 0000000..4492f45 --- /dev/null +++ b/web-react/src/pages/system/account/index.jsx @@ -0,0 +1,41 @@ +import React, { Component } from 'react' +import { Anchor, Form, Input, InputNumber, Spin } from 'antd' +import { AntIcon, Container, IconSelector } from 'components' +import { cloneDeep } from 'lodash' +import Safety from './setting/satety/index' +import Info from './setting/info' +import nav from 'store/reducer/nav' + +export default class index extends Component { + state = {} + + render() { + // let navs = [ + // { + // title: '我的信息', + // component: require('./setting/info'), + // }, + // { + // title: '安全设置', + // component: require('./setting/satety'), + // }, + // ] + + // return ( + // + // + // {navs.map(item => { + // return + // })} + // + //
+ //
+ // ) + return ( +
+ + +
+ ) + } +} diff --git a/web-react/src/pages/system/account/setting/info.jsx b/web-react/src/pages/system/account/setting/info.jsx new file mode 100644 index 0000000..211d2e1 --- /dev/null +++ b/web-react/src/pages/system/account/setting/info.jsx @@ -0,0 +1,127 @@ +import React, { Component } from 'react' +import { Button, DatePicker, Form, Input, message, Radio, Spin } from 'antd' +import { api } from 'common/api' +import { cloneDeep } from 'lodash' +import { AntIcon, Container, IconSelector, Image } from 'components' +import store from 'store' +import moment from 'moment' + +const { getState } = store + +export default class index extends Component { + state = { + info: getState('user'), + saving: false, + loading: false, + } + form = React.createRef() + componentDidMount() { + this.setState({ + loading: true, + }) + api.getLoginUser() + .then(({ data }) => { + delete data.apps + delete data.menus + this.setState({ + info: data, + }) + let birthday = data.birthday + birthday = moment(birthday) + data = { + ...data, + birthday: birthday, + } + this.form.current.setFieldsValue(data) + }) + .finally(() => { + this.setState({ + loading: false, + }) + }) + } + onSvaeInfo(data) { + this.setState({ + saving: true, + }) + let { birthday } = data.current.getFieldsValue() + let { nickName } = data.current.getFieldsValue() + let { sex } = data.current.getFieldsValue() + let { tel } = data.current.getFieldsValue() + api.sysUserUpdateInfo({ + nickName: nickName, + birthday: birthday, + sex: sex, + tel: tel, + }).then(() => { + message.success('更新个人信息成功') + this.setState({ + saving: false, + }) + }) + } + onAvatarStart() {} + + render() { + const { info } = this.state + return ( + + }> +
+

我的信息

+
+ } + type="avatar" + /> +
+
+
+ + + + + {info.name} + + + + + + + + + 保密 + + + + + + + + + + + + + + +
+
+
+ +
+ ) + } +} diff --git a/web-react/src/pages/system/account/setting/satety/index.jsx b/web-react/src/pages/system/account/setting/satety/index.jsx new file mode 100644 index 0000000..df20c83 --- /dev/null +++ b/web-react/src/pages/system/account/setting/satety/index.jsx @@ -0,0 +1,179 @@ +import React, { Component } from 'react' +import { Button, DatePicker, Form, Input, List, message as Message, Spin } from 'antd' +import { api } from 'common/api' +import { cloneDeep } from 'lodash' +import { AntIcon, Container, IconSelector, Image, ModalForm } from 'components' +import store from 'store' +import moment from 'moment' +import Item from 'antd/lib/list/Item' +import PasswordForm from './password' +import Mail from './mail' +import Phone from './phone' +const { getState } = store +const apiAction = { + update: api.sysUserUpdatePwd, +} + +export default class form extends Component { + state = { + saving: false, + info: [], + loading: true, + } + form = React.createRef() + // 新增窗口实例 + updateForm = React.createRef() + MailForm = React.createRef() + PhoneForm = React.createRef() + /** + * 对表格上的操作进行统一处理 + * [异步] + * @param {*} action + * @param {*} successMessage + */ + async onAction(action, successMessage) { + const { onLoading, onLoaded, onReloadData } = this.table.current + onLoading() + try { + if (action) { + await action + } + if (successMessage) { + Message.success(successMessage) + } + onReloadData() + } catch { + onLoaded() + } + } + + /** + * 打开新增/编辑弹窗 + * @param {*} modal + * @param {*} record + */ + onOpen(modal, record) { + modal.current.open({ + record, + }) + } + + componentDidMount() { + api.getLoginUser().then(({ data }) => { + this.setState({ + loading: true, + }) + let index = [] + //密码 + index.push({ + title: '登录密码', + description: + '安全性高的密码可以使帐号更安全。建议您定期更换密码,设置一个包含字母,符号或数字中至少两项且长度超过6位的密码。', + extra: ( +
+ 当前密码强度为: + { + [ + , + , + , + ][data.securityLevel - 1] + } +
+ ), + done: true, + action: () => { + this.onOpen(this.updateForm) + }, + }) + //手机 + index.push({ + title: '手机绑定(发送验证码到手机,未实现)', + description: ( +
+ 手机号可以直接用于登录、找回密码等。 + {data.phone && ( + + 您已绑定了手机{data.phone} + + )} +
+ ), + done: !!data.phone, + action: () => { + this.onOpen(this.PhoneForm) + }, + }) + //邮箱 + index.push({ + title: '邮箱绑定(发送验证码到邮箱,未实现)', + description: ( +
+ 安全邮箱可以直接用于登录、找回密码等。 + {data.email && ( + + 您已绑定了邮箱{data.email} + + )} +
+ ), + done: !!data.email, + action: () => { + this.onOpen(this.MailForm) + }, + }) + this.setState({ + info: index, + loading: false, + }) + }) + } + render() { + return ( + + }> +
+

安全设置

+
+ ( + + {item.done == true ? ( + <> + + + 已设置 + + + 修改 + + + ) : ( + <> + + + 未设置 + + + 设置 + + + )} + + + )} + /> +
+ + + + + +
+
+ ) + } +} diff --git a/web-react/src/pages/system/account/setting/satety/mail.jsx b/web-react/src/pages/system/account/setting/satety/mail.jsx new file mode 100644 index 0000000..e391cc0 --- /dev/null +++ b/web-react/src/pages/system/account/setting/satety/mail.jsx @@ -0,0 +1,454 @@ +import React, { Component } from 'react' +import { + Form, + Input, + InputNumber, + Modal, + Spin, + Steps, + Button, + Row, + Col, + message, + Select, +} from 'antd' +import { AntIcon, Container, IconSelector } from 'components' +import { cloneDeep, indexOf } from 'lodash' +import { api } from 'common/api' +import { COUNT_DWON_KEY } from 'common/storage' +import { Option } from 'antd/lib/mentions' +import { set } from 'nprogress' +import { getKeyThenIncreaseKey } from 'antd/lib/message' + +const initialValues = { + orgcode: '', + target: '', + code: '', + type: null, +} +var tempcode = '' +const { Step } = Steps +export default class form extends Component { + state = { + buttondisabled: true, + visible: false, + loading: false, + codeLoading: false, + current: 0, + countdown: 0, + sendOrNo: true, + type: [], + } + form = React.createRef() + //发送验证码 + sendcode(data) { + this.setState({ + codeLoading: true, + }) + var reg = /^([a-zA-Z]|[0-9])(\w|)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/ + let { target } = data.current.getFieldsValue() + let { type } = data.current.getFieldsValue() + let { code } = data.current.getFieldsValue() + let { orgcode } = data.current.getFieldsValue() + if (!reg.test(target) && type != '1' && type != '2') { + message.warn('请输入正确的邮箱') + this.setState({ + codeLoading: true, + }) + return + } + api.SendCode({ + target: target, + type: type, + code: code, + orgcode: orgcode, + }) + .then(res => { + if (res.success) { + this.addTime() + this.showcountdown() + } + }) + .finally(() => { + this.setState({ + codeLoading: false, + }) + }) + } + //进入下一步 + next(data) { + this.setState({ + loading: true, + }) + let { target } = data.current.getFieldsValue() + let { type } = data.current.getFieldsValue() + let { code } = data.current.getFieldsValue() + let { orgcode } = data.current.getFieldsValue() + tempcode = data.current.getFieldsValue() + let form = { + target: target, + type: type, + code: code, + orgcode: orgcode, + } + api.CheckBindcode(form) + .then(res => { + if (res.data) { + window.localStorage.removeItem(COUNT_DWON_KEY) + let current = this.state.current + 1 + this.setState({ + form: { + ...form, + type: null, + }, + buttondisabled: true, + current: current, + }) + } + }) + .finally(() => { + this.setState({ + loading: false, + }) + }) + } + /** + * 将倒计时添加入到本地 + */ + addTime() { + const now = Date.now() + var date = now + 60 * 1000 + 500 + window.localStorage.setItem(COUNT_DWON_KEY, date) + } + /** + * 显示倒计时 + */ + showcountdown() { + let _this = this + var Furdate = window.localStorage.getItem(COUNT_DWON_KEY) + var nowdate = new Date().getTime() + if (Furdate >= nowdate) { + this.setState({ + sendOrNo: false, + countdown: parseInt((Furdate - nowdate) / 1000), + }) + setTimeout(() => { + _this.showcountdown() + }, 1000) + } else { + this.setState({ + sendOrNo: true, + }) + } + } + //打开窗口 + open = (data = {}) => { + this.setState({ visible: true, loading: true }) + api.getLoginUser().then(({ data }) => { + let index = [] + data.phone && + index.push({ + Title: '使用手机号' + data.phone + '进行验证 ', + Value: 1, + }) + data.email && + index.push({ + Title: '使用邮箱' + data.email + '进行验证', + Value: 2, + }) + this.setState({ + type: index, + }) + if (index.length > 0) { + this.form.current.setFieldsValue({ + type: index[0].Value, + }) + } + this.setState({ loading: false }) + }) + } + // 前一步 + prev() { + window.localStorage.removeItem(COUNT_DWON_KEY) + let current = this.state.current - 1 + this.setState({ + current: current, + }) + } + //完成 + complete(data) { + let { target } = data.current.getFieldsValue() + let { code } = data.current.getFieldsValue() + let { orgcode } = tempcode + api.CheckBindcode({ + target: target, + type: null, + code: code, + orgcode: orgcode, + }).then(res => { + if (res.data) { + window.localStorage.removeItem(COUNT_DWON_KEY) + message.success('改绑完成') + this.onResetFields() + } + }) + } + onResetFields() { + setTimeout(() => { + this.setState({ visible: false }) + this.setState({ current: 0 }) + //window.localStorage.removeItem(COUNT_DWON_KEY) + /** 在这里可以初始化当前组件中其他属性 */ + /* ... */ + }, 300) + } + render() { + let steps = [ + { + title: '验证', + }, + { + title: '绑定', + }, + ] + const close = () => { + this.setState({ + visible: false, + current: 0, + }) + } + return ( + + + }> +
+ {this.state.type.length !== 0 ? ( +
+
+ + + + + {steps.map(item => ( + + ))} + + + + +
+
{ + this.setState({ + buttondisabled: !( + allValues.orgcode || + (allValues.target && allValues.code) + ), + }) + }} + > +
+ {this.state.current == 0 && ( +
+ + + + + + + + + + {this.state.sendOrNo ? ( + + ) : ( + + )} + + + +
+ )} + {this.state.current == 1 && ( +
+ + + + + + + + + + {this.state.sendOrNo ? ( + + ) : ( + + )} + + + +
+ )} +
+
+
+
+ {this.state.current == 0 && ( + <> +
+ +
+
+ + )} + {this.state.current == 1 && ( + <> + {this.state.current > 0 && ( + + )} + + + )} +
+
+ ) : ( +
+
{ + this.setState({ + buttondisabled: !( + allValues.target && allValues.code + ), + }) + }} + > + + + + + + + + + + {this.state.sendOrNo ? ( + + ) : ( + + )} + + + +
+
+ + + + + + + +
+
+ )} +
+
+
+
+ ) + } +} diff --git a/web-react/src/pages/system/account/setting/satety/password.jsx b/web-react/src/pages/system/account/setting/satety/password.jsx new file mode 100644 index 0000000..0616fc1 --- /dev/null +++ b/web-react/src/pages/system/account/setting/satety/password.jsx @@ -0,0 +1,107 @@ +import React, { Component } from 'react' +import { Form, Input, InputNumber, Spin } from 'antd' +import { AntIcon, IconSelector } from 'components' +import { cloneDeep } from 'lodash' + +const initialValues = { + sort: 100, +} +export default class form extends Component { + state = { + // 加载状态 + loading: true, + exist: false, + } + // 表单实例 + form = React.createRef() + + // 初始化数据 + record = {} + + /** + * mount后回调 + */ + componentDidMount() { + this.props.created && this.props.created(this) + } + + /** + * 填充数据 + * 可以在设置this.record之后对其作出数据结构调整 + * [异步,必要] + * @param {*} params + */ + async fillData(params) { + this.record = cloneDeep(params.record) + //#region 从后端转换成前段所需格式 + const exist = !!params.record + this.setState({ + exist, + }) + + this.record = { + ...this.record, + } + //#endregion + + this.form.current.setFieldsValue(this.record) + + this.setState({ + loading: false, + }) + } + + /** + * 获取数据 + * 可以对postData进行数据结构调整 + * [异步,必要] + * @returns + */ + async getData() { + const form = this.form.current + + const valid = await form.validateFields() + if (valid) { + const postData = form.getFieldsValue() + if (this.record) { + postData.id = this.record.id + } + //#region 从前段转换后端所需格式 + //#endregion + return postData + } + } + + render() { + return ( +
+ + {/* */} +
+ + + + + + + + + +
+
+
+ ) + } +} diff --git a/web-react/src/pages/system/account/setting/satety/phone.jsx b/web-react/src/pages/system/account/setting/satety/phone.jsx new file mode 100644 index 0000000..d5ebb56 --- /dev/null +++ b/web-react/src/pages/system/account/setting/satety/phone.jsx @@ -0,0 +1,455 @@ +import React, { Component } from 'react' +import { + Form, + Input, + InputNumber, + Modal, + Spin, + Steps, + Button, + Row, + Col, + message, + Select, +} from 'antd' +import { AntIcon, Container, IconSelector } from 'components' +import { cloneDeep, indexOf } from 'lodash' +import { api } from 'common/api' +import { COUNT_DWON_KEY } from 'common/storage' +import { Option } from 'antd/lib/mentions' +import { set } from 'nprogress' +import { getKeyThenIncreaseKey } from 'antd/lib/message' + +const initialValues = { + orgcode: '', + target: '', + code: '', + type: null, +} +var tempcode = '' +const { Step } = Steps +export default class form extends Component { + state = { + buttondisabled: true, + visible: false, + loading: false, + codeLoading: false, + current: 0, + countdown: 0, + sendOrNo: true, + type: [], + } + form = React.createRef() + //发送验证码 + sendcode(data) { + this.setState({ + codeLoading: true, + }) + var reg = + /^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$/ + let { target } = data.current.getFieldsValue() + let { type } = data.current.getFieldsValue() + let { code } = data.current.getFieldsValue() + let { orgcode } = data.current.getFieldsValue() + if (!reg.test(target) && type != '1' && type != '2') { + message.warn('请输入正确的手机号码') + this.setState({ + codeLoading: true, + }) + return + } + api.SendCode({ + target: target, + type: type, + code: code, + orgcode: orgcode, + }) + .then(res => { + if (res.success) { + this.addTime() + this.showcountdown() + } + }) + .finally(() => { + this.setState({ + codeLoading: false, + }) + }) + } + //进入下一步 + next(data) { + this.setState({ + loading: true, + }) + let { target } = data.current.getFieldsValue() + let { type } = data.current.getFieldsValue() + let { code } = data.current.getFieldsValue() + let { orgcode } = data.current.getFieldsValue() + tempcode = data.current.getFieldsValue() + let form = { + target: target, + type: type, + code: code, + orgcode: orgcode, + } + api.CheckBindcode(form) + .then(res => { + if (res.data) { + window.localStorage.removeItem(COUNT_DWON_KEY) + let current = this.state.current + 1 + this.setState({ + form: { + ...form, + type: null, + }, + buttondisabled: true, + current: current, + }) + } + }) + .finally(() => { + this.setState({ + loading: false, + }) + }) + } + /** + * 将倒计时添加入到本地 + */ + addTime() { + const now = Date.now() + var date = now + 60 * 1000 + 500 + window.localStorage.setItem(COUNT_DWON_KEY, date) + } + /** + * 显示倒计时 + */ + showcountdown() { + let _this = this + var Furdate = window.localStorage.getItem(COUNT_DWON_KEY) + var nowdate = new Date().getTime() + if (Furdate >= nowdate) { + this.setState({ + sendOrNo: false, + countdown: parseInt((Furdate - nowdate) / 1000), + }) + setTimeout(() => { + _this.showcountdown() + }, 1000) + } else { + this.setState({ + sendOrNo: true, + }) + } + } + //打开窗口 + open = (data = {}) => { + this.setState({ visible: true, loading: true }) + api.getLoginUser().then(({ data }) => { + let index = [] + data.phone && + index.push({ + Title: '使用手机号' + data.phone + '进行验证 ', + Value: 1, + }) + data.email && + index.push({ + Title: '使用邮箱' + data.email + '进行验证', + Value: 2, + }) + this.setState({ + type: index, + }) + if (index.length > 0) { + this.form.current.setFieldsValue({ + type: index[0].Value, + }) + } + this.setState({ loading: false }) + }) + } + // 前一步 + prev() { + window.localStorage.removeItem(COUNT_DWON_KEY) + let current = this.state.current - 1 + this.setState({ + current: current, + }) + } + //完成 + complete(data) { + let { target } = data.current.getFieldsValue() + let { code } = data.current.getFieldsValue() + let { orgcode } = tempcode + api.CheckBindcode({ + target: target, + type: null, + code: code, + orgcode: orgcode, + }).then(res => { + if (res.data) { + window.localStorage.removeItem(COUNT_DWON_KEY) + message.success('改绑完成') + this.onResetFields() + } + }) + } + onResetFields() { + setTimeout(() => { + this.setState({ visible: false }) + this.setState({ current: 0 }) + //window.localStorage.removeItem(COUNT_DWON_KEY) + /** 在这里可以初始化当前组件中其他属性 */ + /* ... */ + }, 300) + } + render() { + let steps = [ + { + title: '验证', + }, + { + title: '绑定', + }, + ] + const close = () => { + this.setState({ + visible: false, + current: 0, + }) + } + return ( + + + }> +
+ {this.state.type.length !== 0 ? ( +
+
+ + + + + {steps.map(item => ( + + ))} + + + + +
+
{ + this.setState({ + buttondisabled: !( + allValues.orgcode || + (allValues.target && allValues.code) + ), + }) + }} + > +
+ {this.state.current == 0 && ( +
+ + + + + + + + + + {this.state.sendOrNo ? ( + + ) : ( + + )} + + + +
+ )} + {this.state.current == 1 && ( +
+ + + + + + + + + + {this.state.sendOrNo ? ( + + ) : ( + + )} + + + +
+ )} +
+
+
+
+ {this.state.current == 0 && ( + <> +
+ +
+
+ + )} + {this.state.current == 1 && ( + <> + {this.state.current > 0 && ( + + )} + + + )} +
+
+ ) : ( +
+
{ + this.setState({ + buttondisabled: !( + allValues.target && allValues.code + ), + }) + }} + > + + + + + + + + + + {this.state.sendOrNo ? ( + + ) : ( + + )} + + + +
+
+ + + + + + + +
+
+ )} +
+
+
+
+ ) + } +} diff --git a/web-react/src/views/main/_layout/header/user.jsx b/web-react/src/views/main/_layout/header/user.jsx index b126243..cca8939 100644 --- a/web-react/src/views/main/_layout/header/user.jsx +++ b/web-react/src/views/main/_layout/header/user.jsx @@ -34,7 +34,14 @@ class User extends Component { this.unsubscribe() } - onAccountSetting = () => {} + onAccountSetting = () => { + window.openContentWindow({ + id: 'account-home', + title: '个人设置', + icon: '', + path: '/system/account', + }) + } onLogout = () => { Modal.confirm({ @@ -83,7 +90,7 @@ class User extends Component { - + this.onAccountSetting()}> 个人中心