Merge branch 'master' into features/UserManger
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using Ewide.Core;
|
using Ewide.Core;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -11,4 +12,10 @@ namespace Ewide.Application
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class HouseQueryDetailInput
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "Id不能为空")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ using Ewide.Core.Extension;
|
|||||||
using Furion.DatabaseAccessor;
|
using Furion.DatabaseAccessor;
|
||||||
using Furion.DependencyInjection;
|
using Furion.DependencyInjection;
|
||||||
using Furion.DynamicApiController;
|
using Furion.DynamicApiController;
|
||||||
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -77,5 +79,32 @@ WHERE 1=1";
|
|||||||
"TotalFloor"
|
"TotalFloor"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("/houseQuery/detail")]
|
||||||
|
public async Task<dynamic> Detail([FromQuery] HouseQueryDetailInput input)
|
||||||
|
{
|
||||||
|
var houseCodeOutputAsync = await _dapperRepository.QueryAsync<HouseCodeOutput>(
|
||||||
|
@"SELECT HC.Id,HC.Address,HC.ProjectId,HC.ZoneId,HC.Type,AA.Name AreaName,RA.Name RoadName,CA.Name CommName,O.Name ZoneName,Proj.Note ProjectNote,CONCAT(Proj.Name,'(',Proj.Note,')') ProjectFullName,HC.HouseCode,HC.Lng,HC.Lat,HC.No FROM bs_house_code HC
|
||||||
|
LEFT JOIN bs_house_projectinfo Proj ON Proj.Id=HC.ProjectId
|
||||||
|
LEFT JOIN sys_org O ON HC.ZoneId = O.Id
|
||||||
|
LEFT JOIN sys_area_code CA ON CA.Code = Proj.AreaCode
|
||||||
|
LEFT JOIN sys_area_code RA ON RA.AdCode = SUBSTR(CA.AdCode,1,9)
|
||||||
|
LEFT JOIN sys_area_code AA ON AA.AdCode = SUBSTR(CA.AdCode,1,6)
|
||||||
|
WHERE HC.Id=@Id", new { input.Id }
|
||||||
|
);
|
||||||
|
|
||||||
|
var houseCodeOutput = houseCodeOutputAsync.SingleOrDefault();
|
||||||
|
|
||||||
|
|
||||||
|
var houseInfoOutputForDetailPage = new HouseInfoOutputForDetailPage
|
||||||
|
{
|
||||||
|
HouseCode = houseCodeOutput
|
||||||
|
};
|
||||||
|
|
||||||
|
var houseInfoOutput = (await _houseInfoRep.DetachedEntities.FirstOrDefaultAsync(p => p.HouseCodeId == houseCodeOutput.Id)).Adapt<HouseInfoOutput>();
|
||||||
|
houseInfoOutputForDetailPage.HouseInfo = houseInfoOutput;
|
||||||
|
|
||||||
|
return houseInfoOutputForDetailPage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,20 @@ namespace Ewide.Core
|
|||||||
// 解析异常信息
|
// 解析异常信息
|
||||||
var (StatusCode, ErrorCode, Errors) = UnifyContext.GetExceptionMetadata(context);
|
var (StatusCode, ErrorCode, Errors) = UnifyContext.GetExceptionMetadata(context);
|
||||||
|
|
||||||
|
// 如果是代码自行抛出的异常,视为接口调用成功,返回结果失败
|
||||||
|
if (context.Exception.GetType() == typeof(Furion.FriendlyException.AppFriendlyException))
|
||||||
|
{
|
||||||
|
return DisplayJson(new RestfulResult<object>
|
||||||
|
{
|
||||||
|
Code = StatusCodes.Status200OK,
|
||||||
|
Success = false,
|
||||||
|
Data = null,
|
||||||
|
Message = Errors,
|
||||||
|
Extras = UnifyContext.Take(),
|
||||||
|
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return DisplayJson(new RestfulResult<object>
|
return DisplayJson(new RestfulResult<object>
|
||||||
{
|
{
|
||||||
Code = StatusCode,
|
Code = StatusCode,
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ namespace Ewide.Core.Service
|
|||||||
///<summary>
|
///<summary>
|
||||||
///发送验证码
|
///发送验证码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpPost("/sysUser/SendCode")]
|
[HttpPost("/sysUser/sendCode")]
|
||||||
public async Task<dynamic> SendCode(Usermailphone input)
|
public async Task<dynamic> SendCode(Usermailphone input)
|
||||||
{
|
{
|
||||||
var Orgcode_Key = "ewide_Orgcode";
|
var Orgcode_Key = "ewide_Orgcode";
|
||||||
@@ -505,7 +505,7 @@ namespace Ewide.Core.Service
|
|||||||
///<summary>
|
///<summary>
|
||||||
///检验验证码并且绑定
|
///检验验证码并且绑定
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[HttpPost("/sysUser/CheckBindcode")]
|
[HttpPost("/sysUser/checkBindcode")]
|
||||||
public async Task<dynamic> CheckBindcode(Usermailphone input)
|
public async Task<dynamic> CheckBindcode(Usermailphone input)
|
||||||
{
|
{
|
||||||
var Orgcode_Key = "ewide_Orgcode";
|
var Orgcode_Key = "ewide_Orgcode";
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ namespace Ewide.EntityFramework.Core
|
|||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
if (App.HostEnvironment.EnvironmentName == "Testing") return;
|
if (App.HostEnvironment.EnvironmentName == "Testing") return;
|
||||||
//集成测试下面代码会报错
|
//集成测试下面代码会报错
|
||||||
|
#if DEBUG
|
||||||
XmlSerializerUtil xmlHandler = new XmlSerializerUtil();
|
XmlSerializerUtil xmlHandler = new XmlSerializerUtil();
|
||||||
Dictionary<Type, object> dic = xmlHandler.ReaderALL();
|
Dictionary<Type, object> dic = xmlHandler.ReaderALL();
|
||||||
foreach (KeyValuePair<Type, object> item in dic)
|
foreach (KeyValuePair<Type, object> item in dic)
|
||||||
@@ -183,6 +184,7 @@ namespace Ewide.EntityFramework.Core
|
|||||||
}
|
}
|
||||||
modelBuilder.Entity(item.Key).HasData(data);
|
modelBuilder.Entity(item.Key).HasData(data);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||||
|
-->
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<DeleteExistingFiles>False</DeleteExistingFiles>
|
||||||
|
<ExcludeApp_Data>False</ExcludeApp_Data>
|
||||||
|
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
||||||
|
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||||
|
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||||
|
<PublishProvider>FileSystem</PublishProvider>
|
||||||
|
<PublishUrl>bin\Release\net5.0\publish\</PublishUrl>
|
||||||
|
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
1
web-react/.env.development
Normal file
1
web-react/.env.development
Normal file
@@ -0,0 +1 @@
|
|||||||
|
REACT_APP_BASE_URL=http://localhost:5566/
|
||||||
1
web-react/.env.production
Normal file
1
web-react/.env.production
Normal file
@@ -0,0 +1 @@
|
|||||||
|
REACT_APP_BASE_URL=http://118.178.224.202:90/
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
"photoswipe": "^4.1.3",
|
"photoswipe": "^4.1.3",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
|
"react-cropper": "^2.1.8",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-json-view": "^1.21.3",
|
"react-json-view": "^1.21.3",
|
||||||
"react-monaco-editor": "^0.43.0",
|
"react-monaco-editor": "^0.43.0",
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
"rules": {
|
"rules": {
|
||||||
"eqeqeq": "off",
|
"eqeqeq": "off",
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
|
"no-sparse-arrays": "off",
|
||||||
"array-callback-return": "off",
|
"array-callback-return": "off",
|
||||||
"jsx-a11y/anchor-is-valid": "off"
|
"jsx-a11y/anchor-is-valid": "off"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -24,7 +24,7 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>React App</title>
|
<title>宽易科技</title>
|
||||||
<script src="https://webapi.amap.com/maps?v=2.0&key=c6a4832b8afbde0361b36630a3fc5bdc&plugin=Map3D,AMap.DistrictSearch,AMap.Geocoder,AMap.AutoComplete,AMap.PlaceSearch"></script>
|
<script src="https://webapi.amap.com/maps?v=2.0&key=c6a4832b8afbde0361b36630a3fc5bdc&plugin=Map3D,AMap.DistrictSearch,AMap.Geocoder,AMap.AutoComplete,AMap.PlaceSearch"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -9,6 +9,3 @@
|
|||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: @primary-color;
|
background-color: @primary-color;
|
||||||
}
|
}
|
||||||
.ant-anchor-link-active {
|
|
||||||
background: linear-gradient(90deg, #fff, transparent);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -220,6 +220,23 @@
|
|||||||
color: fade(@black, 50%);
|
color: fade(@black, 50%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.yo-form--no-border {
|
||||||
|
.ant-form-item {
|
||||||
|
padding: @padding-md 0;
|
||||||
|
|
||||||
|
border-right: 0;
|
||||||
|
border-left: 0;
|
||||||
|
&:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.yo-form-group {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.yo-modal-form {
|
.yo-modal-form {
|
||||||
.ant-modal-body {
|
.ant-modal-body {
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import status from './status'
|
|||||||
* api.getItemGroupType(parmas).then(...)
|
* api.getItemGroupType(parmas).then(...)
|
||||||
*/
|
*/
|
||||||
import urls from './requests'
|
import urls from './requests'
|
||||||
import { notification } from 'antd'
|
import { message as Message, notification } from 'antd'
|
||||||
|
|
||||||
const STATUS = status
|
const STATUS = status
|
||||||
|
|
||||||
axios.defaults.baseURL = '/api'
|
axios.defaults.baseURL = process.env.NODE_ENV === 'development' ? '/api' : process.env.REACT_APP_BASE_URL
|
||||||
|
|
||||||
const initInstance = (options) => {
|
const initInstance = (options) => {
|
||||||
const instance = axios
|
const instance = axios
|
||||||
@@ -64,6 +64,10 @@ const errorNotification = ({ code, message }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const errorMessage = (message) => {
|
||||||
|
Message.error(message)
|
||||||
|
}
|
||||||
|
|
||||||
const handlerUnauthorized = () => {
|
const handlerUnauthorized = () => {
|
||||||
token.value = ''
|
token.value = ''
|
||||||
window.location.replace('/login')
|
window.location.replace('/login')
|
||||||
@@ -125,13 +129,28 @@ for (let key in urls) {
|
|||||||
api[`${key}Await`](params)
|
api[`${key}Await`](params)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const { data } = res
|
const { data } = res
|
||||||
|
const isFile = [ArrayBuffer, Blob].includes(data.constructor)
|
||||||
|
const result = isFile ? res : data
|
||||||
|
|
||||||
|
// 错误的返回码,以通知的形式弹出
|
||||||
if (errerCodes.indexOf(data.code) >= 0) {
|
if (errerCodes.indexOf(data.code) >= 0) {
|
||||||
errorNotification(data)
|
errorNotification(data)
|
||||||
reject([ArrayBuffer, Blob].indexOf(data.constructor) > -1 ? res : data)
|
reject(result)
|
||||||
} else if (data.code === STATUS.Unauthorized) {
|
}
|
||||||
|
|
||||||
|
// 非文件,返回码正确,但是结果失败,以消息的形式弹出
|
||||||
|
else if (!isFile && !data.success) {
|
||||||
|
errorMessage(data.message)
|
||||||
|
reject(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 未登录
|
||||||
|
else if (data.code === STATUS.Unauthorized) {
|
||||||
handlerUnauthorized()
|
handlerUnauthorized()
|
||||||
} else {
|
}
|
||||||
reslove([ArrayBuffer, Blob].indexOf(data.constructor) > -1 ? res : data)
|
|
||||||
|
else {
|
||||||
|
reslove(result)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(({ response }) => {
|
.catch(({ response }) => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const urls = {
|
const urls = {
|
||||||
houseQueryPage: ['/houseQuery/page', 'post'],
|
houseQueryPage: ['/houseQuery/page', 'post'],
|
||||||
|
houseQueryDetail: ['/houseQuery/detail', 'get'],
|
||||||
}
|
}
|
||||||
|
|
||||||
export default urls
|
export default urls
|
||||||
@@ -78,12 +78,12 @@ const urls = {
|
|||||||
/**
|
/**
|
||||||
* 发送验证码
|
* 发送验证码
|
||||||
*/
|
*/
|
||||||
SendCode: ['/sysUser/SendCode', 'post'],
|
sysUserSendCode: ['/sysUser/sendCode', 'post'],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定/验证
|
* 绑定/验证
|
||||||
*/
|
*/
|
||||||
CheckBindcode: ['/sysUser/CheckBindcode', 'post'],
|
sysUserCheckBindcode: ['/sysUser/checkBindcode', 'post'],
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,17 +78,9 @@ function renderItem(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderCheckbox(data) {
|
function renderCheckbox(data) {
|
||||||
return (
|
const grid = (
|
||||||
<label className="ant-card-grid ant-card-grid-hoverable">
|
<label className="ant-card-grid ant-card-grid-hoverable">
|
||||||
<Popover
|
<Checkbox value={data.id} checked={data.checked} onChange={e => this.onChange(e, data)}>
|
||||||
placement="topLeft"
|
|
||||||
content={data.remark || <span className="text-normal">没有说明</span>}
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
value={data.id}
|
|
||||||
checked={data.checked}
|
|
||||||
onChange={e => this.onChange(e, data)}
|
|
||||||
>
|
|
||||||
{data.title}
|
{data.title}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
{data.visibleParent && data.type == 2 && (
|
{data.visibleParent && data.type == 2 && (
|
||||||
@@ -97,9 +89,15 @@ function renderCheckbox(data) {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
<div className="text-gray">{data.permission}</div>
|
<div className="text-gray">{data.permission}</div>
|
||||||
</Popover>
|
|
||||||
</label>
|
</label>
|
||||||
)
|
)
|
||||||
|
return data.remark ? (
|
||||||
|
<Popover placement="topLeft" content={data.remark}>
|
||||||
|
{grid}
|
||||||
|
</Popover>
|
||||||
|
) : (
|
||||||
|
grid
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class AuthorityView extends Component {
|
export default class AuthorityView extends Component {
|
||||||
|
|||||||
@@ -1,29 +1,23 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
|
|
||||||
export default class Container extends Component {
|
export default class Container extends Component {
|
||||||
|
|
||||||
getMode(mode) {
|
getMode(mode) {
|
||||||
const c = 'container'
|
const c = 'container'
|
||||||
switch (mode) {
|
const modes = ['xxs', 'xs', 'sm', 'md', 'fluid']
|
||||||
case 'sm':
|
if (modes.includes(mode)) {
|
||||||
return c + '-sm'
|
return `${c}-${mode}`
|
||||||
case 'md':
|
|
||||||
return c + '-md'
|
|
||||||
case 'fluid':
|
|
||||||
return c + '-fluid'
|
|
||||||
default:
|
|
||||||
return c
|
|
||||||
}
|
}
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let className = this.getMode(this.props.mode)
|
const { mode, className, children } = this.props
|
||||||
if (this.props.className) {
|
|
||||||
className += ` ${this.props.className}`
|
let containerName = this.getMode(mode)
|
||||||
|
if (className) {
|
||||||
|
containerName = [containerName, className].join(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return <section className={containerName}>{children}</section>
|
||||||
<section className={className}>{this.props.children}</section>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Avatar } from 'antd'
|
|||||||
import { isEqual } from 'lodash'
|
import { isEqual } from 'lodash'
|
||||||
import { PreviewFileBase64 } from 'util/file'
|
import { PreviewFileBase64 } from 'util/file'
|
||||||
|
|
||||||
const getSrc = async (id) => {
|
const getSrc = async id => {
|
||||||
if (id) {
|
if (id) {
|
||||||
const base64 = await PreviewFileBase64(id)
|
const base64 = await PreviewFileBase64(id)
|
||||||
return base64
|
return base64
|
||||||
@@ -12,9 +12,8 @@ const getSrc = async (id) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class Image extends Component {
|
export default class Image extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
src: ''
|
src: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
id = ''
|
id = ''
|
||||||
@@ -25,9 +24,9 @@ export default class Image extends Component {
|
|||||||
this.setSrc()
|
this.setSrc()
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(props) {
|
shouldComponentUpdate(props, state) {
|
||||||
// props变更或state.src变更时进行渲染
|
// props变更或state.src变更时进行渲染
|
||||||
return !isEqual(this.props, props) || !this.state.src
|
return !isEqual(this.props, props) || this.state.src !== state.src
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
@@ -46,13 +45,9 @@ export default class Image extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.type === 'avatar') {
|
if (this.props.type === 'avatar') {
|
||||||
return (
|
return <Avatar src={this.state.src} {...this.props} />
|
||||||
<Avatar src={this.state.src} {...this.props} />
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
return (
|
return <img src={this.state.src} {...this.props} alt="" />
|
||||||
<img src={this.state.src} {...this.props} alt="" />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export { default as AntIcon } from 'components/ant-icon'
|
export { default as AntIcon } from './ant-icon'
|
||||||
export { default as AuthorityView } from './authority-view'
|
export { default as AuthorityView } from './authority-view'
|
||||||
export { default as Auth } from './authorized'
|
export { default as Auth } from './authorized'
|
||||||
export { default as ColorSelector } from './form/color-selector'
|
export { default as ColorSelector } from './form/color-selector'
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ export default class QueryTable extends Component {
|
|||||||
this.query = this.props.queryInitialValues
|
this.query = this.props.queryInitialValues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const res = await this.loadData(
|
const res = await this.loadData(
|
||||||
{
|
{
|
||||||
pageIndex: this.pagination.current,
|
pageIndex: this.pagination.current,
|
||||||
@@ -245,9 +246,10 @@ export default class QueryTable extends Component {
|
|||||||
|
|
||||||
this.pagination = false
|
this.pagination = false
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
this.onLoaded()
|
this.onLoaded()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据开始加载
|
* 数据开始加载
|
||||||
|
|||||||
35
web-react/src/pages/business/house/query/detail.jsx
Normal file
35
web-react/src/pages/business/house/query/detail.jsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Card } from 'antd'
|
||||||
|
import Container from 'components/container'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
import ReactJson from 'react-json-view'
|
||||||
|
|
||||||
|
export default class detail extends Component {
|
||||||
|
state = {
|
||||||
|
loading: false,
|
||||||
|
record: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
// 获取详细数据
|
||||||
|
const { id } = this.props.param
|
||||||
|
if (id) {
|
||||||
|
api.houseQueryDetail({ id }).then(({ data }) => {
|
||||||
|
this.setState({
|
||||||
|
record: data,
|
||||||
|
loading: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<Card>
|
||||||
|
<ReactJson src={this.state.record} />
|
||||||
|
</Card>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,14 @@ import {
|
|||||||
Row,
|
Row,
|
||||||
Tag,
|
Tag,
|
||||||
} from 'antd'
|
} from 'antd'
|
||||||
import { AntIcon, Auth, Container, InputNumberRange, QueryTable } from 'components'
|
import {
|
||||||
|
AntIcon,
|
||||||
|
Auth,
|
||||||
|
Container,
|
||||||
|
InputNumberRange,
|
||||||
|
QueryTable,
|
||||||
|
QueryTableActions,
|
||||||
|
} from 'components'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import auth from 'components/authorized/handler'
|
import auth from 'components/authorized/handler'
|
||||||
import { first, isEqual, last } from 'lodash'
|
import { first, isEqual, last } from 'lodash'
|
||||||
@@ -46,6 +53,9 @@ const authName = 'houseQuery'
|
|||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
|
houseStatus: [],
|
||||||
|
houseType: [],
|
||||||
|
houseIndustry: [],
|
||||||
houseUsedStatus: [],
|
houseUsedStatus: [],
|
||||||
housePropertyRights: [],
|
housePropertyRights: [],
|
||||||
landAttribute: [],
|
landAttribute: [],
|
||||||
@@ -95,10 +105,11 @@ export default class index extends Component {
|
|||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '任务截止时间',
|
title: '建档状态',
|
||||||
dataIndex: 'endTime',
|
dataIndex: 'state',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 150,
|
width: 100,
|
||||||
|
render: text => this.bindCodeValue(text, 'house_status'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -109,7 +120,22 @@ export default class index extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
const flag = auth({ [authName]: [['edit'], ['delete']] })
|
const flag = auth({ [authName]: 'detail' })
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
this.columns.push({
|
||||||
|
title: '操作',
|
||||||
|
width: 150,
|
||||||
|
dataIndex: 'actions',
|
||||||
|
render: (text, record) => (
|
||||||
|
<QueryTableActions>
|
||||||
|
<Auth auth={{ [authName]: 'detail' }}>
|
||||||
|
<a onClick={() => this.onOpen(record.id)}>查看</a>
|
||||||
|
</Auth>
|
||||||
|
</QueryTableActions>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,6 +158,9 @@ export default class index extends Component {
|
|||||||
const { onLoading, onLoadData } = this.table.current
|
const { onLoading, onLoadData } = this.table.current
|
||||||
onLoading()
|
onLoading()
|
||||||
getDictData(
|
getDictData(
|
||||||
|
'house_status',
|
||||||
|
'house_type',
|
||||||
|
'house_industry',
|
||||||
'house_used_status',
|
'house_used_status',
|
||||||
'house_property_rights',
|
'house_property_rights',
|
||||||
'land_attribute',
|
'land_attribute',
|
||||||
@@ -198,8 +227,12 @@ export default class index extends Component {
|
|||||||
* @param {*} modal
|
* @param {*} modal
|
||||||
* @param {*} id
|
* @param {*} id
|
||||||
*/
|
*/
|
||||||
onOpen(modal, id) {
|
onOpen(id) {
|
||||||
modal.current.open({ id })
|
window.openContentWindow({
|
||||||
|
title: '房屋详情',
|
||||||
|
path: 'business/house/query/detail',
|
||||||
|
param: { id },
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,14 +28,7 @@ const authName = 'houseTask'
|
|||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
status: [
|
houseStatus: [],
|
||||||
{ code: -1, value: '审核退回' },
|
|
||||||
{ code: 0, value: '待处理' },
|
|
||||||
{ code: 1, value: '暂存' },
|
|
||||||
{ code: 2, value: '待提交' },
|
|
||||||
{ code: 3, value: '审核中' },
|
|
||||||
{ code: 6, value: '审核通过' },
|
|
||||||
],
|
|
||||||
houseType: [],
|
houseType: [],
|
||||||
houseIndustry: [],
|
houseIndustry: [],
|
||||||
},
|
},
|
||||||
@@ -92,7 +85,7 @@ export default class index extends Component {
|
|||||||
dataIndex: 'state',
|
dataIndex: 'state',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 100,
|
width: 100,
|
||||||
render: text => this.bindCodeValue(text, 'status'),
|
render: text => this.bindCodeValue(text, 'house_status'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -146,7 +139,7 @@ export default class index extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { onLoading, onLoadData } = this.table.current
|
const { onLoading, onLoadData } = this.table.current
|
||||||
onLoading()
|
onLoading()
|
||||||
getDictData('house_type', 'house_industry').then(codes => {
|
getDictData('house_status', 'house_type', 'house_industry').then(codes => {
|
||||||
this.setState({ codes: { ...this.state.codes, ...codes } }, () => {
|
this.setState({ codes: { ...this.state.codes, ...codes } }, () => {
|
||||||
onLoadData()
|
onLoadData()
|
||||||
})
|
})
|
||||||
@@ -295,8 +288,8 @@ export default class index extends Component {
|
|||||||
<Form.Item label="建档状态" name="state">
|
<Form.Item label="建档状态" name="state">
|
||||||
<Select allowClear className="w-150" placeholder="建档状态">
|
<Select allowClear className="w-150" placeholder="建档状态">
|
||||||
<Select.Option value="">全部</Select.Option>
|
<Select.Option value="">全部</Select.Option>
|
||||||
{codes.status.map(item => (
|
{codes.houseStatus.map(item => (
|
||||||
<Select.Option key={item.code} value={item.code}>
|
<Select.Option key={item.code} value={+item.code}>
|
||||||
{item.value}
|
{item.value}
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
|
|||||||
186
web-react/src/pages/system/account/base.jsx
Normal file
186
web-react/src/pages/system/account/base.jsx
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Button, Card, Col, Descriptions, Modal, Row, Spin, Tooltip, Upload } from 'antd'
|
||||||
|
import { AntIcon, Image } from 'components'
|
||||||
|
import { Cropper } from 'react-cropper'
|
||||||
|
import 'cropperjs/dist/cropper.css'
|
||||||
|
import { BlobToFile } from 'util/file'
|
||||||
|
|
||||||
|
import './base.less'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
|
||||||
|
export default class base extends Component {
|
||||||
|
state = {
|
||||||
|
img: true,
|
||||||
|
|
||||||
|
cropperVisible: false,
|
||||||
|
loadingAvatar: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
cropper = React.createRef()
|
||||||
|
|
||||||
|
avatarFile = null
|
||||||
|
|
||||||
|
async onOpenAvatarCropper() {
|
||||||
|
this.setState({ cropperVisible: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
onCloseAvatarCropper() {
|
||||||
|
this.setState({ cropperVisible: false }, () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const cropper = this.cropper.current && this.cropper.current.cropper
|
||||||
|
if (cropper) {
|
||||||
|
cropper.destroy()
|
||||||
|
}
|
||||||
|
this.avatarFile = null
|
||||||
|
this.setState({ img: true })
|
||||||
|
}, 300)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onUploadAvatar() {
|
||||||
|
this.setState({ loadingAvatar: true })
|
||||||
|
const canvas = this.cropper.current.cropper.getCroppedCanvas()
|
||||||
|
canvas.toBlob(async data => {
|
||||||
|
try {
|
||||||
|
const file = BlobToFile(data, this.avatarFile.name, this.avatarFile.type)
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('file', file)
|
||||||
|
const { data: avatar } = await api.sysFileInfoUpload(fd)
|
||||||
|
await api.sysUserUpdateInfo({ avatar })
|
||||||
|
this.onCloseAvatarCropper()
|
||||||
|
this.props.loadData()
|
||||||
|
} finally {
|
||||||
|
this.setState({ loadingAvatar: false })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { user } = this.props
|
||||||
|
|
||||||
|
const { img, cropperVisible, loadingAvatar } = this.state
|
||||||
|
|
||||||
|
const cropper = this.cropper.current && this.cropper.current.cropper
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Card title="我的信息">
|
||||||
|
<div className="yo-avatar-info">
|
||||||
|
<Image id={user.avatar} type="avatar" size={128} />
|
||||||
|
<div
|
||||||
|
onClick={() => this.onOpenAvatarCropper()}
|
||||||
|
className="yo-avatar-info--cover"
|
||||||
|
>
|
||||||
|
<AntIcon type="sync" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<Descriptions column={1} labelStyle={{ width: '100px' }}>
|
||||||
|
<Descriptions.Item label="用户名">{user.name}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="昵称">{user.nickName}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="帐号">{user.account}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="性别">{user.sex}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="生日">
|
||||||
|
{user.birthday &&
|
||||||
|
(typeof user.birthday === 'string'
|
||||||
|
? user.birthday
|
||||||
|
: user.birthday.format('YYYY-MM-DD'))}
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</Card>
|
||||||
|
<Modal
|
||||||
|
visible={cropperVisible}
|
||||||
|
width={800}
|
||||||
|
footer={false}
|
||||||
|
destroyOnClose
|
||||||
|
onCancel={() => this.onCloseAvatarCropper()}
|
||||||
|
>
|
||||||
|
<Spin spinning={loadingAvatar} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Row gutter={16} align="middle">
|
||||||
|
<Col span={12}>
|
||||||
|
<div className="yo-avatar-cropper">
|
||||||
|
<Cropper
|
||||||
|
ref={this.cropper}
|
||||||
|
src={img}
|
||||||
|
style={{ width: '100%', height: 240 }}
|
||||||
|
cropBoxResizable={false}
|
||||||
|
aspectRatio={1}
|
||||||
|
preview=".yo-avatar-preview"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<div className="yo-avatar-preview" />
|
||||||
|
</Col>
|
||||||
|
<Col span={12} className="mt-md text-center">
|
||||||
|
<Upload
|
||||||
|
beforeUpload={file => {
|
||||||
|
this.avatarFile = file
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
reader.onload = () => {
|
||||||
|
this.setState({ img: reader.result })
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}}
|
||||||
|
showUploadList={false}
|
||||||
|
className="mr-xs"
|
||||||
|
>
|
||||||
|
<Button type="primary" icon={<AntIcon type="picture" />}>
|
||||||
|
选择图片
|
||||||
|
</Button>
|
||||||
|
</Upload>
|
||||||
|
|
||||||
|
<Button.Group>
|
||||||
|
<Tooltip placement="bottom" title="放大">
|
||||||
|
<Button
|
||||||
|
disabled={!cropper}
|
||||||
|
type="text"
|
||||||
|
onClick={() => cropper.zoom(0.1)}
|
||||||
|
icon={<AntIcon type="zoom-in" />}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip placement="bottom" title="缩小">
|
||||||
|
<Button
|
||||||
|
disabled={!cropper}
|
||||||
|
type="text"
|
||||||
|
onClick={() => cropper.zoom(-0.1)}
|
||||||
|
icon={<AntIcon type="zoom-out" />}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip placement="bottom" title="左旋">
|
||||||
|
<Button
|
||||||
|
disabled={!cropper}
|
||||||
|
type="text"
|
||||||
|
onClick={() => cropper.rotate(-90)}
|
||||||
|
icon={<AntIcon type="undo" />}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip placement="bottom" title="右旋">
|
||||||
|
<Button
|
||||||
|
disabled={!cropper}
|
||||||
|
type="text"
|
||||||
|
onClick={() => cropper.rotate(90)}
|
||||||
|
icon={<AntIcon type="redo" />}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</Button.Group>
|
||||||
|
</Col>
|
||||||
|
<Col span={12} className="mt-md text-center">
|
||||||
|
<Button
|
||||||
|
disabled={!cropper}
|
||||||
|
type="primary"
|
||||||
|
className="mr-xs"
|
||||||
|
onClick={() => this.onUploadAvatar()}
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => this.onCloseAvatarCropper()}>取消</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Spin>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
51
web-react/src/pages/system/account/base.less
Normal file
51
web-react/src/pages/system/account/base.less
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
@import (reference) '~assets/style/app.less';
|
||||||
|
.yo-avatar-info {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
width: 128px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
&--cover {
|
||||||
|
font-size: @font-size-lg * 2;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
transition: @animation-duration-slow;
|
||||||
|
|
||||||
|
opacity: 0;
|
||||||
|
color: @white;
|
||||||
|
background-color: fade(@black, 50%);
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.yo-avatar-cropper {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
border-radius: @border-radius-base;
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
.yo-avatar-preview {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
@@ -1,41 +1,113 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Anchor, Form, Input, InputNumber, Spin } from 'antd'
|
import ReactDOM from 'react-dom'
|
||||||
import { AntIcon, Container, IconSelector } from 'components'
|
import { Anchor, Card, Col, Row, Spin } from 'antd'
|
||||||
import { cloneDeep } from 'lodash'
|
import { AntIcon, Container } from 'components'
|
||||||
import Safety from './setting/satety/index'
|
import moment from 'moment'
|
||||||
|
import store from 'store'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
|
||||||
|
import Base from './base'
|
||||||
import Info from './setting/info'
|
import Info from './setting/info'
|
||||||
import nav from 'store/reducer/nav'
|
import Safety from './setting/satety'
|
||||||
|
|
||||||
|
const { getState, dispatch, subscribe } = store
|
||||||
|
|
||||||
|
const navs = [
|
||||||
|
{ title: '基本信息', component: Info },
|
||||||
|
{ title: '安全设置', component: Safety },
|
||||||
|
]
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
state = {}
|
state = {
|
||||||
|
loading: false,
|
||||||
|
user: getState('user'),
|
||||||
|
}
|
||||||
|
|
||||||
|
container = window
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.unsubscribe = subscribe('user', user => {
|
||||||
|
this.setState({ user })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.loadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
|
loadData = async () => {
|
||||||
|
this.setState({ loading: true })
|
||||||
|
try {
|
||||||
|
const { data } = await api.getLoginUser()
|
||||||
|
if (data.birthday) {
|
||||||
|
data.birthday = moment(data.birthday)
|
||||||
|
}
|
||||||
|
dispatch({
|
||||||
|
type: 'SET_USER_ACCOUNT',
|
||||||
|
user: data,
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.setState({ loading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setContainer = container => {
|
||||||
|
this.container = (ReactDOM.findDOMNode(container) || {}).parentNode
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// let navs = [
|
const { loadData } = this
|
||||||
// {
|
|
||||||
// title: '我的信息',
|
const { loading, user } = this.state
|
||||||
// component: require('./setting/info'),
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: '安全设置',
|
|
||||||
// component: require('./setting/satety'),
|
|
||||||
// },
|
|
||||||
// ]
|
|
||||||
|
|
||||||
// return (
|
|
||||||
// <Container>
|
|
||||||
// <Anchor offsetTop={16} className="yo-account--anchor">
|
|
||||||
// {navs.map(item => {
|
|
||||||
// return <Anchor.Link key={item.title} title={nav.title}></Anchor.Link>
|
|
||||||
// })}
|
|
||||||
// </Anchor>
|
|
||||||
// <br />
|
|
||||||
// </Container>
|
|
||||||
// )
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />} ref={this.setContainer}>
|
||||||
<Info></Info>
|
<Container mode="fluid">
|
||||||
<Safety></Safety>
|
<Row gutter={16}>
|
||||||
</div>
|
<Col flex="200px">
|
||||||
|
<Anchor
|
||||||
|
getContainer={() => this.container}
|
||||||
|
offsetTop={24}
|
||||||
|
targetOffset={100}
|
||||||
|
wrapperStyle={{ backgroundColor: 'transparent' }}
|
||||||
|
onClick={e => e.preventDefault()}
|
||||||
|
>
|
||||||
|
{navs.map((item, i) => (
|
||||||
|
<Anchor.Link
|
||||||
|
key={i}
|
||||||
|
href={`#account-setting-${i}`}
|
||||||
|
title={item.title}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Anchor>
|
||||||
|
</Col>
|
||||||
|
<Col flex="1">
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col xl={{ span: 10, order: 2 }}>
|
||||||
|
<br />
|
||||||
|
<Base user={user} loadData={loadData} />
|
||||||
|
</Col>
|
||||||
|
<Col xl={{ span: 14, order: 1 }}>
|
||||||
|
{navs.map((item, i) => (
|
||||||
|
<section key={i} id={`account-setting-${i}`}>
|
||||||
|
<br />
|
||||||
|
<Card title={item.title}>
|
||||||
|
<item.component user={user} loadData={loadData} />
|
||||||
|
</Card>
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Container>
|
||||||
|
</Spin>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,96 +1,53 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, DatePicker, Form, Input, message, Radio, Spin } from 'antd'
|
import { Button, DatePicker, Form, Input, message as Message, Radio } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import { cloneDeep } from 'lodash'
|
|
||||||
import { AntIcon, Container, IconSelector, Image } from 'components'
|
|
||||||
import store from 'store'
|
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
const { getState } = store
|
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
state = {
|
state = {
|
||||||
info: getState('user'),
|
|
||||||
saving: false,
|
saving: false,
|
||||||
loading: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
form = React.createRef()
|
form = React.createRef()
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setState({
|
const { user } = this.props
|
||||||
loading: true,
|
if (user.birthday) {
|
||||||
})
|
user.birthday = moment(user.birthday)
|
||||||
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)
|
this.form.current.setFieldsValue(user)
|
||||||
})
|
}
|
||||||
.finally(() => {
|
|
||||||
this.setState({
|
async onSvaeInfo() {
|
||||||
loading: false,
|
this.setState({ saving: true })
|
||||||
})
|
try {
|
||||||
})
|
await api.sysUserUpdateInfo(this.form.current.getFieldsValue())
|
||||||
|
await this.props.loadData()
|
||||||
|
Message.success('更新个人信息成功')
|
||||||
|
} finally {
|
||||||
|
this.setState({ saving: 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() {}
|
onAvatarStart() {}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { info } = this.state
|
const { user } = this.props
|
||||||
|
|
||||||
|
const { saving } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container mode="xxs">
|
<>
|
||||||
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
|
<Form className="yo-form yo-form--no-border" ref={this.form}>
|
||||||
<Form className="yo-form" ref={this.form}>
|
|
||||||
<h4 className="h4">我的信息</h4>
|
|
||||||
<div className="yo-avatar-info">
|
|
||||||
<Image
|
|
||||||
id={info.avatar}
|
|
||||||
size={128}
|
|
||||||
icon={<AntIcon type="user" />}
|
|
||||||
type="avatar"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<div className="yo-form-group yo-form--short">
|
<div className="yo-form-group yo-form--short">
|
||||||
<Form.Item label="昵称" name="nickName">
|
<Form.Item label="昵称" name="nickName">
|
||||||
<Input placeholder="请输入昵称"></Input>
|
<Input autoComplete="off" placeholder="请输入昵称" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="用户名">
|
<Form.Item label="用户名">
|
||||||
<span>{info.name}</span>
|
<span>{user.name}</span>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="生日" name="birthday">
|
<Form.Item label="生日" name="birthday">
|
||||||
<DatePicker
|
<DatePicker className="w-100-p" placeholder="请选择生日" />
|
||||||
onChange={this.onChange}
|
|
||||||
className="w-100-p"
|
|
||||||
placeholder="请选择生日"
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="性别" name="sex">
|
<Form.Item label="性别" name="sex">
|
||||||
<Radio.Group>
|
<Radio.Group>
|
||||||
@@ -99,29 +56,32 @@ export default class index extends Component {
|
|||||||
<span>保密</span>
|
<span>保密</span>
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
<Radio.Button value={1}>
|
<Radio.Button value={1}>
|
||||||
<AntIcon color="#1890ff" className="mr-xxs" type="man" />
|
<AntIcon
|
||||||
|
style={{ color: '#1890ff' }}
|
||||||
|
className="mr-xxs"
|
||||||
|
type="man"
|
||||||
|
/>
|
||||||
<span>男</span>
|
<span>男</span>
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
<Radio.Button value={2}>
|
<Radio.Button value={2}>
|
||||||
<AntIcon color="#eb2f96" className="mr-xxs" type="woman" />
|
<AntIcon
|
||||||
|
style={{ color: '#eb2f96' }}
|
||||||
|
className="mr-xxs"
|
||||||
|
type="woman"
|
||||||
|
/>
|
||||||
<span>女</span>
|
<span>女</span>
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="电话" name="tel">
|
<Form.Item label="电话" name="tel">
|
||||||
<Input placeholder="请输入电话" />
|
<Input autoComplete="off" placeholder="请输入电话" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
</Spin>
|
<Button loading={saving} onClick={() => this.onSvaeInfo()} block type="text">
|
||||||
<Button
|
|
||||||
loading={this.state.saving}
|
|
||||||
onClick={() => this.onSvaeInfo(this.form)}
|
|
||||||
block
|
|
||||||
>
|
|
||||||
更新个人信息
|
更新个人信息
|
||||||
</Button>
|
</Button>
|
||||||
</Container>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,179 +1,126 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, DatePicker, Form, Input, List, message as Message, Spin } from 'antd'
|
import { List } from 'antd'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import { cloneDeep } from 'lodash'
|
import { AntIcon, ModalForm, QueryTableActions } from 'components'
|
||||||
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 PasswordForm from './password'
|
||||||
|
|
||||||
import Mail from './mail'
|
import Mail from './mail'
|
||||||
import Phone from './phone'
|
import Phone from './phone'
|
||||||
const { getState } = store
|
|
||||||
const apiAction = {
|
const apiAction = {
|
||||||
update: api.sysUserUpdatePwd,
|
updatePwd: api.sysUserUpdatePwd,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
state = {
|
updatePwdForm = React.createRef()
|
||||||
saving: false,
|
mailForm = React.createRef()
|
||||||
info: [],
|
mhoneForm = React.createRef()
|
||||||
loading: true,
|
|
||||||
}
|
onOpen(modal) {
|
||||||
form = React.createRef()
|
modal.current.open()
|
||||||
// 新增窗口实例
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
render() {
|
||||||
* 打开新增/编辑弹窗
|
const { user, loadData } = this.props
|
||||||
* @param {*} modal
|
|
||||||
* @param {*} record
|
|
||||||
*/
|
|
||||||
onOpen(modal, record) {
|
|
||||||
modal.current.open({
|
|
||||||
record,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
const index = []
|
||||||
api.getLoginUser().then(({ data }) => {
|
|
||||||
this.setState({
|
|
||||||
loading: true,
|
|
||||||
})
|
|
||||||
let index = []
|
|
||||||
//密码
|
//密码
|
||||||
index.push({
|
index.push({
|
||||||
title: '登录密码',
|
title: '登录密码',
|
||||||
description:
|
description:
|
||||||
'安全性高的密码可以使帐号更安全。建议您定期更换密码,设置一个包含字母,符号或数字中至少两项且长度超过6位的密码。',
|
'安全性高的密码可以使帐号更安全。建议您定期更换密码,设置一个包含字母,符号或数字中至少两项且长度超过6位的密码。',
|
||||||
extra: (
|
// extra: (
|
||||||
<div>
|
// <div>
|
||||||
当前密码强度为:
|
// 当前密码强度为:
|
||||||
{
|
// {
|
||||||
[
|
// [
|
||||||
<span class="text-error">弱</span>,
|
// <span class="text-error">弱</span>,
|
||||||
<span class="text-warning">中</span>,
|
// <span class="text-warning">中</span>,
|
||||||
<span class="text-success">强</span>,
|
// <span class="text-success">强</span>,
|
||||||
][data.securityLevel - 1]
|
// ][user.securityLevel - 1]
|
||||||
}
|
// }
|
||||||
</div>
|
// </div>
|
||||||
),
|
// ),
|
||||||
done: true,
|
done: true,
|
||||||
action: () => {
|
action: () => {
|
||||||
this.onOpen(this.updateForm)
|
this.onOpen(this.updatePwdForm)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
//手机
|
//手机
|
||||||
index.push({
|
index.push({
|
||||||
title: '手机绑定(发送验证码到手机,未实现)',
|
title: '手机绑定',
|
||||||
description: (
|
description: (
|
||||||
<div>
|
<div>
|
||||||
手机号可以直接用于登录、找回密码等。
|
手机号可以直接用于登录、找回密码等。
|
||||||
{data.phone && (
|
{user.phone && (
|
||||||
<span>
|
<>
|
||||||
您已绑定了手机<b>{data.phone}</b>
|
您已绑定了手机<b>{user.phone}</b>
|
||||||
</span>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
done: !!data.phone,
|
done: !!user.phone,
|
||||||
action: () => {
|
action: () => {
|
||||||
this.onOpen(this.PhoneForm)
|
this.onOpen(this.mhoneForm)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
//邮箱
|
//邮箱
|
||||||
index.push({
|
index.push({
|
||||||
title: '邮箱绑定(发送验证码到邮箱,未实现)',
|
title: '邮箱绑定',
|
||||||
description: (
|
description: (
|
||||||
<div>
|
<div>
|
||||||
安全邮箱可以直接用于登录、找回密码等。
|
安全邮箱可以直接用于登录、找回密码等。
|
||||||
{data.email && (
|
{user.email && (
|
||||||
<span>
|
<>
|
||||||
您已绑定了邮箱<b>{data.email}</b>
|
您已绑定了邮箱<b>{user.email}</b>
|
||||||
</span>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
done: !!data.email,
|
done: !!user.email,
|
||||||
action: () => {
|
action: () => {
|
||||||
this.onOpen(this.MailForm)
|
this.onOpen(this.mailForm)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
this.setState({
|
|
||||||
info: index,
|
|
||||||
loading: false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return (
|
return (
|
||||||
<Container mode="xxs">
|
|
||||||
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
|
|
||||||
<div className="yo-form">
|
|
||||||
<h4 className="h4">安全设置</h4>
|
|
||||||
</div>
|
|
||||||
<List
|
|
||||||
dataSource={this.state.info}
|
|
||||||
bordered
|
|
||||||
item-layout="vertical"
|
|
||||||
renderItem={item => (
|
|
||||||
<List.Item extra={item.extra} slot="renderItem" slot-scope="item">
|
|
||||||
{item.done == true ? (
|
|
||||||
<>
|
<>
|
||||||
<span className="text-success" slot="actions">
|
<List
|
||||||
|
dataSource={index}
|
||||||
|
itemLayout="vertical"
|
||||||
|
renderItem={item => (
|
||||||
|
<List.Item
|
||||||
|
extra={item.extra}
|
||||||
|
actions={[
|
||||||
|
item.done == true ? (
|
||||||
|
<QueryTableActions>
|
||||||
|
<span className="text-success">
|
||||||
<AntIcon className="mr-xxs" type="check-circle" />
|
<AntIcon className="mr-xxs" type="check-circle" />
|
||||||
已设置
|
已设置
|
||||||
</span>
|
</span>
|
||||||
<a onClick={item.action} slot="actions">
|
<a onClick={item.action}>修改</a>
|
||||||
修改
|
</QueryTableActions>
|
||||||
</a>
|
|
||||||
</>
|
|
||||||
) : (
|
) : (
|
||||||
<>
|
<QueryTableActions>
|
||||||
<span className="text-warning" slot="actions">
|
<span className="text-warning">
|
||||||
<AntIcon className="mr-xxs" type="exclamation-circle" />
|
<AntIcon className="mr-xxs" type="exclamation-circle" />
|
||||||
未设置
|
未设置
|
||||||
</span>
|
</span>
|
||||||
<a onClick={item.action} slot="actions">
|
<a onClick={item.action}>设置</a>
|
||||||
设置
|
</QueryTableActions>
|
||||||
</a>
|
),
|
||||||
</>
|
]}
|
||||||
)}
|
>
|
||||||
<List.Item.Meta description={item.description} title={item.title} />
|
<List.Item.Meta description={item.description} title={item.title} />
|
||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<br />
|
<ModalForm title={`更新密码`} action={apiAction.updatePwd} ref={this.updatePwdForm}>
|
||||||
<ModalForm title={`更新密码`} action={apiAction.update} ref={this.updateForm}>
|
<PasswordForm loadData={loadData} />
|
||||||
<PasswordForm />
|
|
||||||
</ModalForm>
|
</ModalForm>
|
||||||
<Mail ref={this.MailForm} />
|
<Phone ref={this.mhoneForm} loadData={loadData} />
|
||||||
<Phone ref={this.PhoneForm} />
|
<Mail ref={this.mailForm} loadData={loadData} />
|
||||||
</Spin>
|
</>
|
||||||
</Container>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,209 +1,14 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import {
|
import { Form, Input, Modal, Spin, Steps, Button, Row, Col, message as Message, Select } from 'antd'
|
||||||
Form,
|
import { AntIcon } from 'components'
|
||||||
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 { api } from 'common/api'
|
||||||
import { COUNT_DWON_KEY } from 'common/storage'
|
import { COUNT_DWON_KEY } from 'common/storage'
|
||||||
import { Option } from 'antd/lib/mentions'
|
import store from 'store'
|
||||||
import { set } from 'nprogress'
|
import { cloneDeep } from 'lodash'
|
||||||
import { getKeyThenIncreaseKey } from 'antd/lib/message'
|
|
||||||
|
|
||||||
const initialValues = {
|
const { getState } = store
|
||||||
orgcode: '',
|
|
||||||
target: '',
|
const steps = [
|
||||||
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: '验证',
|
||||||
},
|
},
|
||||||
@@ -211,170 +16,332 @@ export default class form extends Component {
|
|||||||
title: '绑定',
|
title: '绑定',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
const close = () => {
|
|
||||||
this.setState({
|
const reg = /^([a-zA-Z]|[0-9])(\w|)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/
|
||||||
|
|
||||||
|
const initState = {
|
||||||
visible: false,
|
visible: false,
|
||||||
current: 0,
|
loading: false,
|
||||||
|
|
||||||
|
// 可用于验证的类型
|
||||||
|
types: [],
|
||||||
|
// 当前步骤
|
||||||
|
currentStep: 0,
|
||||||
|
|
||||||
|
nextDisabled: true,
|
||||||
|
// 正在发送验证码
|
||||||
|
sendingCode: false,
|
||||||
|
// 冷却时间
|
||||||
|
countDown: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class form extends Component {
|
||||||
|
state = cloneDeep(initState)
|
||||||
|
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
orgCode = ''
|
||||||
|
|
||||||
|
//打开窗口
|
||||||
|
open = () => {
|
||||||
|
this.setState({ visible: true })
|
||||||
|
|
||||||
|
this.showCountDown()
|
||||||
|
|
||||||
|
const data = getState('user')
|
||||||
|
const types = []
|
||||||
|
data.phone &&
|
||||||
|
types.push({
|
||||||
|
title: `使用手机号${data.phone}进行验证`,
|
||||||
|
value: 1,
|
||||||
|
})
|
||||||
|
data.email &&
|
||||||
|
types.push({
|
||||||
|
title: `使用邮箱${data.email}进行验证`,
|
||||||
|
value: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.setState({ types })
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.setState(cloneDeep(initState))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将倒计时添加入到本地
|
||||||
|
*/
|
||||||
|
addTime() {
|
||||||
|
const now = Date.now() + 60 * 1000
|
||||||
|
window.localStorage.setItem(COUNT_DWON_KEY, now)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 显示倒计时
|
||||||
|
*/
|
||||||
|
showCountDown() {
|
||||||
|
const surplusTime = window.localStorage.getItem(COUNT_DWON_KEY)
|
||||||
|
const nowTime = Date.now()
|
||||||
|
if (surplusTime >= nowTime) {
|
||||||
|
this.setState({
|
||||||
|
countDown: parseInt((surplusTime - nowTime) / 1000),
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showCountDown()
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
this.setState({ countDown: 0 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//发送验证码
|
||||||
|
async onSendCode() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (!valid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ sendingCode: true })
|
||||||
|
|
||||||
|
const data = form.getFieldsValue()
|
||||||
|
try {
|
||||||
|
await api.sysUserSendCode(data)
|
||||||
|
const typeName = data.type ? [, '手机', '邮箱'][data.type] : '手机'
|
||||||
|
Message.success(`已发送验证码到${typeName},请注意查收`)
|
||||||
|
this.addTime()
|
||||||
|
this.showCountDown()
|
||||||
|
} finally {
|
||||||
|
this.setState({ sendingCode: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下一步
|
||||||
|
async onNext() {
|
||||||
|
this.setState({ loading: true })
|
||||||
|
const data = this.form.current.getFieldsValue()
|
||||||
|
this.orgCode = data.orgCode
|
||||||
|
|
||||||
|
try {
|
||||||
|
await api.sysUserCheckBindcode(data)
|
||||||
|
window.localStorage.removeItem(COUNT_DWON_KEY)
|
||||||
|
this.setState({
|
||||||
|
nextDisabled: true,
|
||||||
|
currentStep: this.state.currentStep + 1,
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.setState({ loading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上一步
|
||||||
|
onPrev() {
|
||||||
|
window.localStorage.removeItem(COUNT_DWON_KEY)
|
||||||
|
this.setState({
|
||||||
|
currentStep: this.state.currentStep - 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//完成
|
||||||
|
async onComplete() {
|
||||||
|
this.setState({ loading: true })
|
||||||
|
try {
|
||||||
|
await api.sysUserCheckBindcode({
|
||||||
|
...this.form.current.getFieldsValue(),
|
||||||
|
orgCode: this.orgCode,
|
||||||
|
})
|
||||||
|
await this.props.loadData()
|
||||||
|
window.localStorage.removeItem(COUNT_DWON_KEY)
|
||||||
|
Message.success('绑定邮箱成功')
|
||||||
|
this.close()
|
||||||
|
} finally {
|
||||||
|
this.setState({ loading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderForm() {
|
||||||
|
const { nextDisabled, sendingCode, countDown } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="yo-form-group">
|
||||||
|
<Form
|
||||||
|
ref={this.form}
|
||||||
|
onValuesChange={(changedValues, allValues) => {
|
||||||
|
this.setState({
|
||||||
|
nextDisabled: !(allValues.target && allValues.code),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="邮箱"
|
||||||
|
name="target"
|
||||||
|
required={false}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请输入邮箱' },
|
||||||
|
{ pattern: reg, message: '邮箱格式错误' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入邮箱" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="验证码">
|
||||||
|
<Row gutter={16} align="middle">
|
||||||
|
<Col flex="1">
|
||||||
|
<Form.Item name="code" noStyle>
|
||||||
|
<Input autoComplete="off" placeholder="请输入验证码" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
{countDown ? (
|
||||||
|
<Button disabled>{countDown}秒后重新发送</Button>
|
||||||
|
) : (
|
||||||
|
<Button onClick={() => this.onSendCode()} loading={sendingCode}>
|
||||||
|
发送验证码
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
<div className="text-center pt-md pb-md">
|
||||||
|
<Button
|
||||||
|
disabled={nextDisabled}
|
||||||
|
onClick={() => this.onComplete()}
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
绑定
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepForm() {
|
||||||
|
const { types, currentStep, sendingCode, countDown } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container mode="xxs">
|
|
||||||
<Modal
|
|
||||||
footer={false}
|
|
||||||
onCancel={close}
|
|
||||||
destroyOnClose
|
|
||||||
visible={this.state.visible}
|
|
||||||
className="yo-modal-form"
|
|
||||||
title="绑定邮箱"
|
|
||||||
>
|
|
||||||
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
|
|
||||||
<div className="yo-form">
|
|
||||||
{this.state.type.length !== 0 ? (
|
|
||||||
<div className="yo-form-group">
|
<div className="yo-form-group">
|
||||||
<br />
|
|
||||||
<Row>
|
<Row>
|
||||||
<Col flex="1" />
|
<Col span={12} offset={6} className="pt-md pb-md">
|
||||||
<Col flex="3">
|
<Steps current={currentStep}>
|
||||||
<Steps current={this.state.current}>
|
|
||||||
{steps.map(item => (
|
{steps.map(item => (
|
||||||
<Steps.Step
|
<Steps.Step key={item.title} title={item.title} />
|
||||||
key={item.title}
|
|
||||||
title={item.title}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</Steps>
|
</Steps>
|
||||||
</Col>
|
</Col>
|
||||||
<Col flex="1" />
|
|
||||||
</Row>
|
</Row>
|
||||||
<br />
|
|
||||||
<Form
|
<Form
|
||||||
ref={this.form}
|
ref={this.form}
|
||||||
initialValues={initialValues}
|
|
||||||
onValuesChange={(changedValues, allValues) => {
|
onValuesChange={(changedValues, allValues) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
buttondisabled: !(
|
nextDisabled: !(
|
||||||
allValues.orgcode ||
|
allValues.orgCode ||
|
||||||
(allValues.target && allValues.code)
|
(allValues.target && allValues.code)
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>
|
{currentStep === 0 && (
|
||||||
{this.state.current == 0 && (
|
<>
|
||||||
<div>
|
<Form.Item
|
||||||
<Form.Item label="选择验证方式" name="type">
|
label="选择验证方式"
|
||||||
<Select placeholder="请选择验证方式">
|
name="type"
|
||||||
{this.state.type.map(item => (
|
required={false}
|
||||||
<Select.Option
|
rules={[{ required: true, message: '请选择一种验证方式' }]}
|
||||||
key={item.Title}
|
|
||||||
value={item.Value}
|
|
||||||
>
|
>
|
||||||
{item.Title}
|
<Select placeholder="请选择验证方式">
|
||||||
|
{types.map(item => (
|
||||||
|
<Select.Option key={item.value} value={item.value}>
|
||||||
|
{item.title}
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="验证码" name="orgcode">
|
<Form.Item label="验证码">
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col flex="1">
|
<Col flex="1">
|
||||||
<Input placeholder="请输入验证码" />
|
<Form.Item name="orgCode" noStyle>
|
||||||
|
<Input autoComplete="off" placeholder="请输入验证码" />
|
||||||
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
{this.state.sendOrNo ? (
|
{countDown ? (
|
||||||
<Button
|
<Button disabled>
|
||||||
onClick={() => {
|
{countDown}
|
||||||
this.sendcode(this.form)
|
秒后重新发送
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={
|
|
||||||
this.state
|
|
||||||
.codeLoading
|
|
||||||
}
|
|
||||||
indicator={
|
|
||||||
<AntIcon type="loading" />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
发送验证码
|
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button disabled>
|
<Button
|
||||||
{this.state.countdown}
|
onClick={() => this.onSendCode()}
|
||||||
秒后重新发送
|
loading={sendingCode}
|
||||||
|
>
|
||||||
|
发送验证码
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{this.state.current == 1 && (
|
|
||||||
<div>
|
|
||||||
<Form.Item label="新邮箱号码" name="target">
|
|
||||||
<Input placeholder="请输入邮箱账号" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="验证码" name="code">
|
|
||||||
<Row gutter={16}>
|
|
||||||
<Col flex="1">
|
|
||||||
<Input placeholder="请输入六位验证码" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
{this.state.sendOrNo ? (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
this.sendcode(this.form)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={
|
|
||||||
this.state
|
|
||||||
.codeLoading
|
|
||||||
}
|
|
||||||
indicator={
|
|
||||||
<AntIcon type="loading" />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
发送验证码
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Button disabled>
|
|
||||||
{this.state.countdown}
|
|
||||||
秒后重新发送
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Form>
|
|
||||||
<br />
|
|
||||||
<div className="text-center">
|
|
||||||
{this.state.current == 0 && (
|
|
||||||
<>
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
onClick={() => this.next(this.form)}
|
|
||||||
type="primary"
|
|
||||||
disabled={this.state.buttondisabled}
|
|
||||||
>
|
|
||||||
下一步
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{this.state.current == 1 && (
|
{currentStep === 1 && (
|
||||||
<>
|
<>
|
||||||
{this.state.current > 0 && (
|
<Form.Item
|
||||||
<Button onClick={() => this.prev()}>
|
label="新邮箱"
|
||||||
前一步
|
name="target"
|
||||||
|
required={false}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请输入邮箱' },
|
||||||
|
{ pattern: reg, message: '邮箱格式错误' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入邮箱" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="验证码">
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col flex="1">
|
||||||
|
<Form.Item name="code" noStyle>
|
||||||
|
<Input autoComplete="off" placeholder="请输入验证码" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
{countDown ? (
|
||||||
|
<Button disabled>
|
||||||
|
{countDown}
|
||||||
|
秒后重新发送
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
onClick={() => this.onSendCode()}
|
||||||
|
loading={sendingCode}
|
||||||
|
>
|
||||||
|
发送验证码
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
<div className="text-center pt-md pb-md">
|
||||||
|
{currentStep === 0 && (
|
||||||
|
<>
|
||||||
<Button
|
<Button
|
||||||
disabled={this.state.buttondisabled}
|
onClick={() => this.onNext(this.form)}
|
||||||
onClick={() => this.complete(this.form)}
|
type="primary"
|
||||||
|
disabled={this.state.nextDisabled}
|
||||||
|
>
|
||||||
|
下一步,绑定
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{currentStep === 1 && (
|
||||||
|
<>
|
||||||
|
<Button onClick={() => this.onPrev()} className="mr-sm">
|
||||||
|
上一步,验证
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
disabled={this.state.nextDisabled}
|
||||||
|
onClick={() => this.onComplete()}
|
||||||
type="primary"
|
type="primary"
|
||||||
>
|
>
|
||||||
完成
|
完成
|
||||||
@@ -383,72 +350,27 @@ export default class form extends Component {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
)
|
||||||
<div className="yo-form-group">
|
|
||||||
<Form
|
|
||||||
initialValues={initialValues}
|
|
||||||
ref={this.form}
|
|
||||||
onValuesChange={(changedValues, allValues) => {
|
|
||||||
this.setState({
|
|
||||||
buttondisabled: !(
|
|
||||||
allValues.target && allValues.code
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Form.Item label="请输入邮箱" name="target">
|
|
||||||
<Input placeholder="请输入邮箱号码" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="验证码" name="code">
|
|
||||||
<Row gutter={16} align="middle">
|
|
||||||
<Col flex="1">
|
|
||||||
<Input placeholder="请输入验证码" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
{this.state.sendOrNo ? (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
this.sendcode(this.form)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={this.state.codeLoading}
|
|
||||||
indicator={
|
|
||||||
<AntIcon type="loading" />
|
|
||||||
}
|
}
|
||||||
/>
|
|
||||||
发送验证码
|
render() {
|
||||||
</Button>
|
const { visible, loading, types } = this.state
|
||||||
) : (
|
|
||||||
<Button disabled>
|
return (
|
||||||
{this.state.countdown}秒后重新发送
|
<Modal
|
||||||
</Button>
|
destroyOnClose
|
||||||
)}
|
footer={false}
|
||||||
</Col>
|
onCancel={() => this.close()}
|
||||||
</Row>
|
visible={visible}
|
||||||
</Form.Item>
|
className="yo-modal-form"
|
||||||
</Form>
|
title="绑定邮箱"
|
||||||
<br />
|
|
||||||
<Row>
|
|
||||||
<Col flex="1" />
|
|
||||||
<Col flex="1" align="middle">
|
|
||||||
<Button
|
|
||||||
disabled={this.state.buttondisabled}
|
|
||||||
onClick={() => this.complete(this.form)}
|
|
||||||
type="primary"
|
|
||||||
>
|
>
|
||||||
绑定
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
</Button>
|
<div className="yo-form">
|
||||||
</Col>
|
{types.length ? this.renderStepForm() : this.renderForm()}
|
||||||
<Col flex="1" />
|
|
||||||
</Row>
|
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
</Spin>
|
||||||
</Modal>
|
</Modal>
|
||||||
</Container>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Form, Input, InputNumber, Spin } from 'antd'
|
import { Form, Input } from 'antd'
|
||||||
import { AntIcon, IconSelector } from 'components'
|
|
||||||
import { cloneDeep } from 'lodash'
|
|
||||||
|
|
||||||
const initialValues = {
|
|
||||||
sort: 100,
|
|
||||||
}
|
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
state = {
|
state = {
|
||||||
// 加载状态
|
// 加载状态
|
||||||
loading: true,
|
|
||||||
exist: false,
|
exist: false,
|
||||||
}
|
}
|
||||||
// 表单实例
|
// 表单实例
|
||||||
@@ -31,25 +25,7 @@ export default class form extends Component {
|
|||||||
* [异步,必要]
|
* [异步,必要]
|
||||||
* @param {*} params
|
* @param {*} params
|
||||||
*/
|
*/
|
||||||
async fillData(params) {
|
async fillData() {}
|
||||||
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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取数据
|
* 获取数据
|
||||||
@@ -63,9 +39,6 @@ export default class form extends Component {
|
|||||||
const valid = await form.validateFields()
|
const valid = await form.validateFields()
|
||||||
if (valid) {
|
if (valid) {
|
||||||
const postData = form.getFieldsValue()
|
const postData = form.getFieldsValue()
|
||||||
if (this.record) {
|
|
||||||
postData.id = this.record.id
|
|
||||||
}
|
|
||||||
//#region 从前段转换后端所需格式
|
//#region 从前段转换后端所需格式
|
||||||
//#endregion
|
//#endregion
|
||||||
return postData
|
return postData
|
||||||
@@ -75,32 +48,39 @@ export default class form extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Form className="yo-form" ref={this.form}>
|
<Form className="yo-form" ref={this.form}>
|
||||||
<Spin spinning={this.state.loading}>
|
|
||||||
{/* <AntIcon slot="indicator" spin type="loading" /> */}
|
|
||||||
<div className="yo-form-group">
|
<div className="yo-form-group">
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="旧密码"
|
label="旧密码"
|
||||||
rules={[{ required: true, message: '请输入旧密码' }]}
|
rules={[{ required: true, message: '请输入旧密码' }]}
|
||||||
name="password"
|
name="password"
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入旧密码" />
|
<Input.Password autoComplete="off" placeholder="请输入旧密码" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="新密码"
|
label="新密码"
|
||||||
rules={[{ required: true, message: '请输入新密码' }]}
|
rules={[{ required: true, message: '请输入新密码' }]}
|
||||||
name="newPassword"
|
name="newPassword"
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入新密码" />
|
<Input.Password autoComplete="off" placeholder="请输入新密码" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="确认新密码"
|
label="确认新密码"
|
||||||
rules={[{ required: true, message: '确认新密码' }]}
|
rules={[
|
||||||
|
{ required: true, message: '请确认新密码' },
|
||||||
|
({ getFieldValue }) => ({
|
||||||
|
validator(_, value) {
|
||||||
|
if (!value || getFieldValue('newPassword') === value) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error('确认新密码不匹配'))
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]}
|
||||||
name="confirm"
|
name="confirm"
|
||||||
>
|
>
|
||||||
<Input placeholder="请确认新密码" />
|
<Input.Password autoComplete="off" placeholder="请确认新密码" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
|
||||||
</Form>
|
</Form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,210 +1,14 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import {
|
import { Form, Input, Modal, Spin, Steps, Button, Row, Col, message as Message, Select } from 'antd'
|
||||||
Form,
|
import { AntIcon } from 'components'
|
||||||
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 { api } from 'common/api'
|
||||||
import { COUNT_DWON_KEY } from 'common/storage'
|
import { COUNT_DWON_KEY } from 'common/storage'
|
||||||
import { Option } from 'antd/lib/mentions'
|
import store from 'store'
|
||||||
import { set } from 'nprogress'
|
import { cloneDeep } from 'lodash'
|
||||||
import { getKeyThenIncreaseKey } from 'antd/lib/message'
|
|
||||||
|
|
||||||
const initialValues = {
|
const { getState } = store
|
||||||
orgcode: '',
|
|
||||||
target: '',
|
const steps = [
|
||||||
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: '验证',
|
||||||
},
|
},
|
||||||
@@ -212,170 +16,332 @@ export default class form extends Component {
|
|||||||
title: '绑定',
|
title: '绑定',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
const close = () => {
|
|
||||||
this.setState({
|
const 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}$/
|
||||||
|
|
||||||
|
const initState = {
|
||||||
visible: false,
|
visible: false,
|
||||||
current: 0,
|
loading: false,
|
||||||
|
|
||||||
|
// 可用于验证的类型
|
||||||
|
types: [],
|
||||||
|
// 当前步骤
|
||||||
|
currentStep: 0,
|
||||||
|
|
||||||
|
nextDisabled: true,
|
||||||
|
// 正在发送验证码
|
||||||
|
sendingCode: false,
|
||||||
|
// 冷却时间
|
||||||
|
countDown: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class form extends Component {
|
||||||
|
state = cloneDeep(initState)
|
||||||
|
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
orgCode = ''
|
||||||
|
|
||||||
|
//打开窗口
|
||||||
|
open = () => {
|
||||||
|
this.setState({ visible: true })
|
||||||
|
|
||||||
|
this.showCountDown()
|
||||||
|
|
||||||
|
const data = getState('user')
|
||||||
|
const types = []
|
||||||
|
data.phone &&
|
||||||
|
types.push({
|
||||||
|
title: `使用手机号${data.phone}进行验证`,
|
||||||
|
value: 1,
|
||||||
|
})
|
||||||
|
data.email &&
|
||||||
|
types.push({
|
||||||
|
title: `使用邮箱${data.email}进行验证`,
|
||||||
|
value: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.setState({ types })
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.setState(cloneDeep(initState))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将倒计时添加入到本地
|
||||||
|
*/
|
||||||
|
addTime() {
|
||||||
|
const now = Date.now() + 60 * 1000
|
||||||
|
window.localStorage.setItem(COUNT_DWON_KEY, now)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 显示倒计时
|
||||||
|
*/
|
||||||
|
showCountDown() {
|
||||||
|
const surplusTime = window.localStorage.getItem(COUNT_DWON_KEY)
|
||||||
|
const nowTime = Date.now()
|
||||||
|
if (surplusTime >= nowTime) {
|
||||||
|
this.setState({
|
||||||
|
countDown: parseInt((surplusTime - nowTime) / 1000),
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showCountDown()
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
this.setState({ countDown: 0 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//发送验证码
|
||||||
|
async onSendCode() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (!valid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ sendingCode: true })
|
||||||
|
|
||||||
|
const data = form.getFieldsValue()
|
||||||
|
try {
|
||||||
|
await api.sysUserSendCode(data)
|
||||||
|
const typeName = data.type ? [, '手机', '邮箱'][data.type] : '手机'
|
||||||
|
Message.success(`已发送验证码到${typeName},请注意查收`)
|
||||||
|
this.addTime()
|
||||||
|
this.showCountDown()
|
||||||
|
} finally {
|
||||||
|
this.setState({ sendingCode: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下一步
|
||||||
|
async onNext() {
|
||||||
|
this.setState({ loading: true })
|
||||||
|
const data = this.form.current.getFieldsValue()
|
||||||
|
this.orgCode = data.orgCode
|
||||||
|
|
||||||
|
try {
|
||||||
|
await api.sysUserCheckBindcode(data)
|
||||||
|
window.localStorage.removeItem(COUNT_DWON_KEY)
|
||||||
|
this.setState({
|
||||||
|
nextDisabled: true,
|
||||||
|
currentStep: this.state.currentStep + 1,
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.setState({ loading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上一步
|
||||||
|
onPrev() {
|
||||||
|
window.localStorage.removeItem(COUNT_DWON_KEY)
|
||||||
|
this.setState({
|
||||||
|
currentStep: this.state.currentStep - 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//完成
|
||||||
|
async onComplete() {
|
||||||
|
this.setState({ loading: true })
|
||||||
|
try {
|
||||||
|
await api.sysUserCheckBindcode({
|
||||||
|
...this.form.current.getFieldsValue(),
|
||||||
|
orgCode: this.orgCode,
|
||||||
|
})
|
||||||
|
await this.props.loadData()
|
||||||
|
window.localStorage.removeItem(COUNT_DWON_KEY)
|
||||||
|
Message.success('绑定手机号成功')
|
||||||
|
this.close()
|
||||||
|
} finally {
|
||||||
|
this.setState({ loading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderForm() {
|
||||||
|
const { nextDisabled, sendingCode, countDown } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="yo-form-group">
|
||||||
|
<Form
|
||||||
|
ref={this.form}
|
||||||
|
onValuesChange={(changedValues, allValues) => {
|
||||||
|
this.setState({
|
||||||
|
nextDisabled: !(allValues.target && allValues.code),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="手机号码"
|
||||||
|
name="target"
|
||||||
|
required={false}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请输入手机号码' },
|
||||||
|
{ pattern: reg, message: '手机号码格式错误' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入手机号码" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="验证码">
|
||||||
|
<Row gutter={16} align="middle">
|
||||||
|
<Col flex="1">
|
||||||
|
<Form.Item name="code" noStyle>
|
||||||
|
<Input autoComplete="off" placeholder="请输入验证码" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
{countDown ? (
|
||||||
|
<Button disabled>{countDown}秒后重新发送</Button>
|
||||||
|
) : (
|
||||||
|
<Button onClick={() => this.onSendCode()} loading={sendingCode}>
|
||||||
|
发送验证码
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
<div className="text-center pt-md pb-md">
|
||||||
|
<Button
|
||||||
|
disabled={nextDisabled}
|
||||||
|
onClick={() => this.onComplete()}
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
绑定
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStepForm() {
|
||||||
|
const { types, currentStep, sendingCode, countDown } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container mode="xxs">
|
|
||||||
<Modal
|
|
||||||
footer={false}
|
|
||||||
onCancel={close}
|
|
||||||
destroyOnClose
|
|
||||||
visible={this.state.visible}
|
|
||||||
className="yo-modal-form"
|
|
||||||
title="绑定手机"
|
|
||||||
>
|
|
||||||
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
|
|
||||||
<div className="yo-form">
|
|
||||||
{this.state.type.length !== 0 ? (
|
|
||||||
<div className="yo-form-group">
|
<div className="yo-form-group">
|
||||||
<br />
|
|
||||||
<Row>
|
<Row>
|
||||||
<Col flex="1" />
|
<Col span={12} offset={6} className="pt-md pb-md">
|
||||||
<Col flex="3">
|
<Steps current={currentStep}>
|
||||||
<Steps current={this.state.current}>
|
|
||||||
{steps.map(item => (
|
{steps.map(item => (
|
||||||
<Steps.Step
|
<Steps.Step key={item.title} title={item.title} />
|
||||||
key={item.title}
|
|
||||||
title={item.title}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</Steps>
|
</Steps>
|
||||||
</Col>
|
</Col>
|
||||||
<Col flex="1" />
|
|
||||||
</Row>
|
</Row>
|
||||||
<br />
|
|
||||||
<Form
|
<Form
|
||||||
ref={this.form}
|
ref={this.form}
|
||||||
initialValues={initialValues}
|
|
||||||
onValuesChange={(changedValues, allValues) => {
|
onValuesChange={(changedValues, allValues) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
buttondisabled: !(
|
nextDisabled: !(
|
||||||
allValues.orgcode ||
|
allValues.orgCode ||
|
||||||
(allValues.target && allValues.code)
|
(allValues.target && allValues.code)
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>
|
{currentStep === 0 && (
|
||||||
{this.state.current == 0 && (
|
<>
|
||||||
<div>
|
<Form.Item
|
||||||
<Form.Item label="选择验证方式" name="type">
|
label="选择验证方式"
|
||||||
<Select placeholder="请选择验证方式">
|
name="type"
|
||||||
{this.state.type.map(item => (
|
required={false}
|
||||||
<Select.Option
|
rules={[{ required: true, message: '请选择一种验证方式' }]}
|
||||||
key={item.Title}
|
|
||||||
value={item.Value}
|
|
||||||
>
|
>
|
||||||
{item.Title}
|
<Select placeholder="请选择验证方式">
|
||||||
|
{types.map(item => (
|
||||||
|
<Select.Option key={item.value} value={item.value}>
|
||||||
|
{item.title}
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="验证码" name="orgcode">
|
<Form.Item label="验证码">
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col flex="1">
|
<Col flex="1">
|
||||||
<Input placeholder="请输入验证码" />
|
<Form.Item name="orgCode" noStyle>
|
||||||
|
<Input autoComplete="off" placeholder="请输入验证码" />
|
||||||
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
{this.state.sendOrNo ? (
|
{countDown ? (
|
||||||
<Button
|
<Button disabled>
|
||||||
onClick={() => {
|
{countDown}
|
||||||
this.sendcode(this.form)
|
秒后重新发送
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={
|
|
||||||
this.state
|
|
||||||
.codeLoading
|
|
||||||
}
|
|
||||||
indicator={
|
|
||||||
<AntIcon type="loading" />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
发送验证码
|
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button disabled>
|
<Button
|
||||||
{this.state.countdown}
|
onClick={() => this.onSendCode()}
|
||||||
秒后重新发送
|
loading={sendingCode}
|
||||||
|
>
|
||||||
|
发送验证码
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{this.state.current == 1 && (
|
|
||||||
<div>
|
|
||||||
<Form.Item label="新手机号码" name="target">
|
|
||||||
<Input placeholder="请输入手机账号" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="验证码" name="code">
|
|
||||||
<Row gutter={16}>
|
|
||||||
<Col flex="1">
|
|
||||||
<Input placeholder="请输入六位验证码" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
{this.state.sendOrNo ? (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
this.sendcode(this.form)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={
|
|
||||||
this.state
|
|
||||||
.codeLoading
|
|
||||||
}
|
|
||||||
indicator={
|
|
||||||
<AntIcon type="loading" />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
发送验证码
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Button disabled>
|
|
||||||
{this.state.countdown}
|
|
||||||
秒后重新发送
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Form>
|
|
||||||
<br />
|
|
||||||
<div className="text-center">
|
|
||||||
{this.state.current == 0 && (
|
|
||||||
<>
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
onClick={() => this.next(this.form)}
|
|
||||||
type="primary"
|
|
||||||
disabled={this.state.buttondisabled}
|
|
||||||
>
|
|
||||||
下一步
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{this.state.current == 1 && (
|
{currentStep === 1 && (
|
||||||
<>
|
<>
|
||||||
{this.state.current > 0 && (
|
<Form.Item
|
||||||
<Button onClick={() => this.prev()}>
|
label="新手机号码"
|
||||||
前一步
|
name="target"
|
||||||
|
required={false}
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请输入手机号码' },
|
||||||
|
{ pattern: reg, message: '手机号码格式错误' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入手机号码" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="验证码">
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col flex="1">
|
||||||
|
<Form.Item name="code" noStyle>
|
||||||
|
<Input autoComplete="off" placeholder="请输入验证码" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
{countDown ? (
|
||||||
|
<Button disabled>
|
||||||
|
{countDown}
|
||||||
|
秒后重新发送
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
onClick={() => this.onSendCode()}
|
||||||
|
loading={sendingCode}
|
||||||
|
>
|
||||||
|
发送验证码
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
<div className="text-center pt-md pb-md">
|
||||||
|
{currentStep === 0 && (
|
||||||
|
<>
|
||||||
<Button
|
<Button
|
||||||
disabled={this.state.buttondisabled}
|
onClick={() => this.onNext(this.form)}
|
||||||
onClick={() => this.complete(this.form)}
|
type="primary"
|
||||||
|
disabled={this.state.nextDisabled}
|
||||||
|
>
|
||||||
|
下一步,绑定
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{currentStep === 1 && (
|
||||||
|
<>
|
||||||
|
<Button onClick={() => this.onPrev()} className="mr-sm">
|
||||||
|
上一步,验证
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
disabled={this.state.nextDisabled}
|
||||||
|
onClick={() => this.onComplete()}
|
||||||
type="primary"
|
type="primary"
|
||||||
>
|
>
|
||||||
完成
|
完成
|
||||||
@@ -384,72 +350,27 @@ export default class form extends Component {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
)
|
||||||
<div className="yo-form-group">
|
|
||||||
<Form
|
|
||||||
initialValues={initialValues}
|
|
||||||
ref={this.form}
|
|
||||||
onValuesChange={(changedValues, allValues) => {
|
|
||||||
this.setState({
|
|
||||||
buttondisabled: !(
|
|
||||||
allValues.target && allValues.code
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Form.Item label="请输入手机" name="target">
|
|
||||||
<Input placeholder="请输入手机号码" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="验证码" name="code">
|
|
||||||
<Row gutter={16} align="middle">
|
|
||||||
<Col flex="1">
|
|
||||||
<Input placeholder="请输入验证码" />
|
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
{this.state.sendOrNo ? (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
this.sendcode(this.form)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin
|
|
||||||
spinning={this.state.codeLoading}
|
|
||||||
indicator={
|
|
||||||
<AntIcon type="loading" />
|
|
||||||
}
|
}
|
||||||
/>
|
|
||||||
发送验证码
|
render() {
|
||||||
</Button>
|
const { visible, loading, types } = this.state
|
||||||
) : (
|
|
||||||
<Button disabled>
|
return (
|
||||||
{this.state.countdown}秒后重新发送
|
<Modal
|
||||||
</Button>
|
destroyOnClose
|
||||||
)}
|
footer={false}
|
||||||
</Col>
|
onCancel={() => this.close()}
|
||||||
</Row>
|
visible={visible}
|
||||||
</Form.Item>
|
className="yo-modal-form"
|
||||||
</Form>
|
title="绑定手机"
|
||||||
<br />
|
|
||||||
<Row>
|
|
||||||
<Col flex="1" />
|
|
||||||
<Col flex="1" align="middle">
|
|
||||||
<Button
|
|
||||||
disabled={this.state.buttondisabled}
|
|
||||||
onClick={() => this.complete(this.form)}
|
|
||||||
type="primary"
|
|
||||||
>
|
>
|
||||||
绑定
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
</Button>
|
<div className="yo-form">
|
||||||
</Col>
|
{types.length ? this.renderStepForm() : this.renderForm()}
|
||||||
<Col flex="1" />
|
|
||||||
</Row>
|
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
</Spin>
|
||||||
</Modal>
|
</Modal>
|
||||||
</Container>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { cloneDeep } from 'lodash'
|
|||||||
import getDictData from 'util/dic'
|
import getDictData from 'util/dic'
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
sort: 100
|
sort: 100,
|
||||||
}
|
}
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
state = {
|
state = {
|
||||||
@@ -13,8 +13,8 @@ export default class form extends Component {
|
|||||||
loading: true,
|
loading: true,
|
||||||
exist: false,
|
exist: false,
|
||||||
codes: {
|
codes: {
|
||||||
dicAreacodeType: []
|
areacodeType: [],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
// 表单实例
|
// 表单实例
|
||||||
form = React.createRef()
|
form = React.createRef()
|
||||||
@@ -36,26 +36,25 @@ export default class form extends Component {
|
|||||||
* @param {*} params
|
* @param {*} params
|
||||||
*/
|
*/
|
||||||
async fillData(params) {
|
async fillData(params) {
|
||||||
|
|
||||||
this.record = cloneDeep(params.record)
|
this.record = cloneDeep(params.record)
|
||||||
//#region 从后端转换成前段所需格式
|
//#region 从后端转换成前段所需格式
|
||||||
|
|
||||||
const codes = await getDictData('dic_areacode_type')
|
const codes = await getDictData('areacode_type')
|
||||||
const exist = !!params.record;
|
const exist = !!params.record
|
||||||
this.setState({
|
this.setState({
|
||||||
codes,
|
codes,
|
||||||
exist
|
exist,
|
||||||
})
|
})
|
||||||
|
|
||||||
this.record = {
|
this.record = {
|
||||||
...this.record
|
...this.record,
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
this.form.current.setFieldsValue(this.record)
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,43 +81,55 @@ export default class form extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form initialValues={initialValues} ref={this.form} className="yo-form">
|
||||||
initialValues={initialValues}
|
|
||||||
ref={this.form}
|
|
||||||
className="yo-form"
|
|
||||||
>
|
|
||||||
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
|
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
|
||||||
<div className="yo-form-group">
|
<div className="yo-form-group">
|
||||||
{/* 表单控件 */}
|
{/* 表单控件 */}
|
||||||
<Form.Item label="区域类型" name="levelType" rules={[{ required: true, message: '请选择区域类型' }]}>
|
<Form.Item
|
||||||
<Select placeholder="请选择区域类型" suffixIcon={<AntIcon type="lock" v-if={this.state.exist} />}>
|
label="区域类型"
|
||||||
{
|
name="levelType"
|
||||||
this.state.codes.dicAreacodeType.map(item => {
|
rules={[{ required: true, message: '请选择区域类型' }]}
|
||||||
return <Select.Option
|
>
|
||||||
key={item.code}
|
<Select
|
||||||
value={+item.code}
|
placeholder="请选择区域类型"
|
||||||
>{item.value}</Select.Option>
|
suffixIcon={<AntIcon type="lock" v-if={this.state.exist} />}
|
||||||
})
|
>
|
||||||
}
|
{this.state.codes.areacodeType.map(item => {
|
||||||
|
return (
|
||||||
|
<Select.Option key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Select.Option>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="区域名称" name="name" rules={[{ required: true, message: '请输入区域名称' }]}>
|
<Form.Item
|
||||||
|
label="区域名称"
|
||||||
|
name="name"
|
||||||
|
rules={[{ required: true, message: '请输入区域名称' }]}
|
||||||
|
>
|
||||||
<Input autoComplete="off" placeholder="请输入区域名称" />
|
<Input autoComplete="off" placeholder="请输入区域名称" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="区域编码" name="code" tooltip="用于系统内部使用,添加后不可更改">
|
<Form.Item
|
||||||
<Input disabled={this.state.exist} placeholder="请输入区域编码" suffix={this.state.exist && <AntIcon type="lock" />}>
|
label="区域编码"
|
||||||
</Input>
|
name="code"
|
||||||
|
tooltip="用于系统内部使用,添加后不可更改"
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
disabled={this.state.exist}
|
||||||
|
placeholder="请输入区域编码"
|
||||||
|
suffix={this.state.exist && <AntIcon type="lock" />}
|
||||||
|
></Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="行政编码" name="adCode" tooltip="国家规定的区划代码,可随实际情况更改而更改">
|
<Form.Item
|
||||||
<Input placeholder="请输入区域编码" >
|
label="行政编码"
|
||||||
</Input>
|
name="adCode"
|
||||||
|
tooltip="国家规定的区划代码,可随实际情况更改而更改"
|
||||||
|
>
|
||||||
|
<Input placeholder="请输入区域编码"></Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="排序" name="sort">
|
<Form.Item label="排序" name="sort">
|
||||||
<InputNumber
|
<InputNumber min={0} placeholder="请输入排序" className="w-100-p" />
|
||||||
min={0}
|
|
||||||
placeholder="请输入排序"
|
|
||||||
className="w-100-p"
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="备注" name="note">
|
<Form.Item label="备注" name="note">
|
||||||
<Input.TextArea placeholder="请输入备注" />
|
<Input.TextArea placeholder="请输入备注" />
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export default class index extends Component {
|
|||||||
{
|
{
|
||||||
title: '机构类型',
|
title: '机构类型',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
|
width: 120,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
render: text => <>{this.bindCodeValue(text, 'org_type')}</>,
|
render: text => <>{this.bindCodeValue(text, 'org_type')}</>,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export default class index extends Component {
|
|||||||
|
|
||||||
focusUser: false,
|
focusUser: false,
|
||||||
focusPassword: false,
|
focusPassword: false,
|
||||||
|
|
||||||
|
btnDisabled: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundImage = require(`assets/image/login-bg-0${Math.floor(Math.random() * 4)}.jpg`)
|
backgroundImage = require(`assets/image/login-bg-0${Math.floor(Math.random() * 4)}.jpg`)
|
||||||
@@ -36,6 +38,7 @@ export default class index extends Component {
|
|||||||
Message.success('登录成功')
|
Message.success('登录成功')
|
||||||
this.props.history.replace('/')
|
this.props.history.replace('/')
|
||||||
} else {
|
} else {
|
||||||
|
this.setState({ loading: false })
|
||||||
Message.error(message)
|
Message.error(message)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -48,15 +51,26 @@ export default class index extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { loading, focusUser, focusPassword, btnDisabled } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="yo-login">
|
<div className="yo-login">
|
||||||
<img src={this.backgroundImage.default} alt="" />
|
<img src={this.backgroundImage.default} alt="" />
|
||||||
<div className="yo-login--placeholder">
|
<div className="yo-login--placeholder">
|
||||||
<Container mode="sm">
|
<Container mode="sm">
|
||||||
<Form ref={this.form} layout="vertical" onFinish={this.onLogin}>
|
<Form
|
||||||
|
ref={this.form}
|
||||||
|
layout="vertical"
|
||||||
|
onFinish={this.onLogin}
|
||||||
|
onValuesChange={(changedValues, values) => {
|
||||||
|
this.setState({
|
||||||
|
btnDisabled: !values.account || !values.password,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="account"
|
name="account"
|
||||||
className={!this.state.focusUser && 'yo-login--label'}
|
className={!focusUser && 'yo-login--label'}
|
||||||
colon={false}
|
colon={false}
|
||||||
label="用户名"
|
label="用户名"
|
||||||
>
|
>
|
||||||
@@ -75,7 +89,7 @@ export default class index extends Component {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="password"
|
name="password"
|
||||||
className={!this.state.focusPassword && 'yo-login--label'}
|
className={!focusPassword && 'yo-login--label'}
|
||||||
colon={false}
|
colon={false}
|
||||||
label="密码"
|
label="密码"
|
||||||
>
|
>
|
||||||
@@ -95,8 +109,8 @@ export default class index extends Component {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item className="mt-lg">
|
<Form.Item className="mt-lg">
|
||||||
<Button
|
<Button
|
||||||
disabled={this.form.user === '' || this.form.password === ''}
|
disabled={btnDisabled}
|
||||||
loading={this.state.loading}
|
loading={loading}
|
||||||
block
|
block
|
||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
size="large"
|
size="large"
|
||||||
|
|||||||
@@ -94,9 +94,10 @@ class User extends Component {
|
|||||||
<AntIcon type="user" className="mr-sm" />
|
<AntIcon type="user" className="mr-sm" />
|
||||||
个人中心
|
个人中心
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="2">其他菜单</Menu.Item>
|
<Menu.Item key="2">
|
||||||
<Menu.Item key="3">其他菜单</Menu.Item>
|
<AntIcon type="file-text" className="mr-sm" />
|
||||||
<Menu.Item key="4">其他菜单</Menu.Item>
|
操作手册
|
||||||
|
</Menu.Item>
|
||||||
<Menu.Divider />
|
<Menu.Divider />
|
||||||
<Menu.Item key="-1" onClick={() => this.onLogout()}>
|
<Menu.Item key="-1" onClick={() => this.onLogout()}>
|
||||||
<AntIcon type="logout" className="mr-sm" />
|
<AntIcon type="logout" className="mr-sm" />
|
||||||
|
|||||||
@@ -3762,6 +3762,11 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
|
|||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
sha.js "^2.4.8"
|
sha.js "^2.4.8"
|
||||||
|
|
||||||
|
cropperjs@^1.5.12:
|
||||||
|
version "1.5.12"
|
||||||
|
resolved "https://registry.nlark.com/cropperjs/download/cropperjs-1.5.12.tgz?cache=0&sync_timestamp=1623485718941&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcropperjs%2Fdownload%2Fcropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50"
|
||||||
|
integrity sha1-2cDbK/uMDXadUXOej5FrvEThD1A=
|
||||||
|
|
||||||
cross-fetch@^3.0.4:
|
cross-fetch@^3.0.4:
|
||||||
version "3.1.4"
|
version "3.1.4"
|
||||||
resolved "https://registry.npm.taobao.org/cross-fetch/download/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
|
resolved "https://registry.npm.taobao.org/cross-fetch/download/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
|
||||||
@@ -9686,6 +9691,13 @@ react-color@^2.19.3:
|
|||||||
reactcss "^1.2.0"
|
reactcss "^1.2.0"
|
||||||
tinycolor2 "^1.4.1"
|
tinycolor2 "^1.4.1"
|
||||||
|
|
||||||
|
react-cropper@^2.1.8:
|
||||||
|
version "2.1.8"
|
||||||
|
resolved "https://registry.nlark.com/react-cropper/download/react-cropper-2.1.8.tgz?cache=0&sync_timestamp=1624865139834&other_urls=https%3A%2F%2Fregistry.nlark.com%2Freact-cropper%2Fdownload%2Freact-cropper-2.1.8.tgz#bf35a7de65769f8ad357e8ae884e791fe3fe9212"
|
||||||
|
integrity sha1-vzWn3mV2n4rTV+iuiE55H+P+khI=
|
||||||
|
dependencies:
|
||||||
|
cropperjs "^1.5.12"
|
||||||
|
|
||||||
react-dev-utils@^11.0.3:
|
react-dev-utils@^11.0.3:
|
||||||
version "11.0.4"
|
version "11.0.4"
|
||||||
resolved "https://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-11.0.4.tgz?cache=0&sync_timestamp=1615231838520&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dev-utils%2Fdownload%2Freact-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
|
resolved "https://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-11.0.4.tgz?cache=0&sync_timestamp=1615231838520&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Freact-dev-utils%2Fdownload%2Freact-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
|
||||||
|
|||||||
Reference in New Issue
Block a user