Merge branch 'master' into features/UserManger

This commit is contained in:
2021-06-30 15:21:06 +08:00
50 changed files with 18550 additions and 100 deletions

View File

@@ -626,6 +626,11 @@
房屋详细信息 房屋详细信息
</summary> </summary>
</member> </member>
<member name="T:Ewide.Application.Service.HouseSafety.HouseQuery.HouseQueryService">
<summary>
住宅查询
</summary>
</member>
<member name="M:Ewide.Application.Service.HouseMemberService.QueryMemberPageList(Ewide.Core.Service.UserInput)"> <member name="M:Ewide.Application.Service.HouseMemberService.QueryMemberPageList(Ewide.Core.Service.UserInput)">
<summary> <summary>
分页查询用户 分页查询用户

View File

@@ -0,0 +1,14 @@
using Ewide.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Application
{
public class HouseQueryInput: PageInputBase
{
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Application
{
public class HouseQueryOutput
{
}
}

View File

@@ -0,0 +1,81 @@
using Dapper;
using Ewide.Core.Extension;
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Application.Service.HouseSafety.HouseQuery
{
/// <summary>
/// 住宅查询
/// </summary>
[ApiDescriptionSettings(Name = "HouseQuery", Order = 210)]
public class HouseQueryService : IHouseQueryService, IDynamicApiController, ITransient
{
private readonly IRepository<BsHouseCode> _houseCodeRep;
private readonly IRepository<BsHouseInfo> _houseInfoRep;
private readonly IRepository<BsHouseTask> _houseTaskRep;
private readonly IDapperRepository _dapperRepository;
public HouseQueryService(IRepository<BsHouseCode> HouseCodeRep, IRepository<BsHouseInfo> HouseInfoRep, IRepository<BsHouseTask> HouseTaskRep, IDapperRepository dapperRepository)
{
_houseCodeRep = HouseCodeRep;
_houseInfoRep = HouseInfoRep;
_houseTaskRep = HouseTaskRep;
_dapperRepository = dapperRepository;
}
[HttpPost("/houseQuery/page")]
public async Task<dynamic> QueryPage([FromBody] HouseQueryInput input)
{
var sql = @"SELECT
HC.ID,
HC.HouseCode,
AA.Name AreaName,
RA.Name RoadName,
CA.Name CommName,
Proj.AreaCode,
Proj.Note,
Proj.Name,
CONCAT(Proj.Name,'(',Proj.Note,')') FullProjName,
HC.Address,
IFNULL(HI.BuildingName,'') BuildingName,
IFNULL(HI.TotalFloor,0) TotalFloor,
IFNULL(HI.TotalArea,0) TotalArea,
HI.LandAttribute,
IFNULL(HI.HouseGrade,0) HouseGrade,
HC.Type,
HC.No,
HI.State,
HI.CompletedDate,
HI.CreatedTime
FROM bs_house_code HC
LEFT JOIN bs_house_info HI ON HI.HouseCodeId = HC.Id
LEFT JOIN bs_house_projectinfo Proj ON Proj.Id=HC.ProjectId
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 1=1";
return await _dapperRepository.QueryPageDataDynamic(sql, input, filterFields: new string[] {
"HouseCode",
"Address",
"BuildingName",
"State",
"AreaCode",
"LandAttribute",
"HouseGrade",
"CompletedDate",
"CreatedTime",
"TotalArea",
"TotalFloor"
});
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Application.Service.HouseSafety.HouseQuery
{
public interface IHouseQueryService
{
}
}

View File

@@ -40,7 +40,7 @@ namespace Ewide.Application.Service
[HttpPost("/houseTask/page")] [HttpPost("/houseTask/page")]
public async Task<dynamic> QueryPage([FromBody] QueryHouseTaskInput input) public async Task<dynamic> QueryPage([FromBody] QueryHouseTaskInput input)
{ {
var sql = @"SELECT T.Id,AA.Name AreaName,RA.Name RoadName,CA.Name CommName,Proj.AreaCode,Proj.Note,Proj.Name,CONCAT(Proj.Name,'(',Proj.Note,')') FullProjName,HC.HouseCode,HC.Address,T.EndTime,HC.Type,HC.Industry,HC.No FROM `bs_house_task` T var sql = @"SELECT T.Id,AA.Name AreaName,RA.Name RoadName,CA.Name CommName,Proj.AreaCode,Proj.Note,Proj.Name,CONCAT(Proj.Name,'(',Proj.Note,')') FullProjName,HC.HouseCode,HC.Address,T.EndTime,HC.Type,HC.Industry,HC.No,T.Status,IFNULL(HI.State,0) State FROM `bs_house_task` T
LEFT JOIN bs_house_code HC ON T.HouseCodeId = HC.Id LEFT JOIN bs_house_code HC ON T.HouseCodeId = HC.Id
LEFT JOIN bs_house_info HI ON HI.HouseCodeId = T.HouseCodeId LEFT JOIN bs_house_info HI ON HI.HouseCodeId = T.HouseCodeId
LEFT JOIN bs_house_projectinfo Proj ON Proj.Id=HC.ProjectId LEFT JOIN bs_house_projectinfo Proj ON Proj.Id=HC.ProjectId
@@ -56,7 +56,7 @@ WHERE {0}";
var param = new DynamicParameters(); var param = new DynamicParameters();
if (userRoles.Where(r => r.Code == Enum.GetName(HouseManagerRole.HouseSecurityManager).ToUnderScoreCase()).Count() > 0) if (userRoles.Where(r => r.Code == Enum.GetName(HouseManagerRole.HouseSecurityManager).ToUnderScoreCase()).Count() > 0)
{ {
sql = String.Format(sql, " (T.Status !=3) AND T.UserID=@UserID "); sql = String.Format(sql, " T.UserID=@UserID ");
param.Add("UserID", user.Id); param.Add("UserID", user.Id);
} }
@@ -66,7 +66,7 @@ WHERE {0}";
param.Add("ZoneId", userOrg.Id); param.Add("ZoneId", userOrg.Id);
} }
return await _dapperRepository.QueryPageDataDynamic(sql, input, param, filterFields: new string[] { "Type", "Address", "HouseCode" }); return await _dapperRepository.QueryPageDataDynamic(sql, input, param, filterFields: new string[] { "Type", "Address", "HouseCode", "Status","State" });
} }
[HttpPost("/houseTask/submit")] [HttpPost("/houseTask/submit")]

View File

@@ -5148,6 +5148,16 @@
关联显示父级 关联显示父级
</summary> </summary>
</member> </member>
<member name="P:Ewide.Core.Service.MenuTreeOutput.Permission">
<summary>
权限标识
</summary>
</member>
<member name="P:Ewide.Core.Service.MenuTreeOutput.Remark">
<summary>
备注
</summary>
</member>
<member name="P:Ewide.Core.Service.MenuTreeOutput.Sort"> <member name="P:Ewide.Core.Service.MenuTreeOutput.Sort">
<summary> <summary>
排序,越小优先级越高 排序,越小优先级越高

View File

@@ -38,6 +38,16 @@ namespace Ewide.Core.Service
/// </summary> /// </summary>
public bool VisibleParent { get; set; } public bool VisibleParent { get; set; }
/// <summary>
/// 权限标识
/// </summary>
public string Permission { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
/// <summary> /// <summary>
/// 排序,越小优先级越高 /// 排序,越小优先级越高
/// </summary> /// </summary>

View File

@@ -138,7 +138,7 @@ namespace Ewide.Core.Service
var roleIdList = await _sysUserRoleService.GetUserRoleIdList(userId); var roleIdList = await _sysUserRoleService.GetUserRoleIdList(userId);
var menuIdList = await _sysRoleMenuService.GetRoleMenuIdList(roleIdList); var menuIdList = await _sysRoleMenuService.GetRoleMenuIdList(roleIdList);
return await _sysMenuRep.DetachedEntities return await _sysMenuRep.DetachedEntities
.Where(u => u.VisibleParent) .Where(u => (u.Type == 2 && u.VisibleParent) || u.Type < 2)
.Where(u => menuIdList.Contains(u.Id)) .Where(u => menuIdList.Contains(u.Id))
.Where(u => u.Status == (int)CommonStatus.ENABLE) .Where(u => u.Status == (int)CommonStatus.ENABLE)
.Select(u => u.Application).ToListAsync(); .Select(u => u.Application).ToListAsync();
@@ -460,6 +460,8 @@ namespace Ewide.Core.Service
Title = u.Name, Title = u.Name,
Type = u.Type, Type = u.Type,
VisibleParent = u.VisibleParent, VisibleParent = u.VisibleParent,
Permission = u.Permission,
Remark = u.Remark,
Sort = u.Sort Sort = u.Sort
}).ToListAsync(); }).ToListAsync();
return new TreeBuildUtil<MenuTreeOutput>().DoTreeBuild(menus); return new TreeBuildUtil<MenuTreeOutput>().DoTreeBuild(menus);

View File

@@ -330,7 +330,7 @@ namespace Ewide.Core.Service
// 如果是范围类型是全部数据则获取当前所有的组织架构Id // 如果是范围类型是全部数据则获取当前所有的组织架构Id
if (dataScopeType == (int)DataScopeType.ALL) if (dataScopeType == (int)DataScopeType.ALL)
{ {
orgIdList = await _sysOrgRep.DetachedEntities.Where(u => u.Status != (int)CommonStatus.ENABLE).Select(u => u.Id).ToListAsync(); orgIdList = await _sysOrgRep.DetachedEntities.Where(u => u.Status == (int)CommonStatus.ENABLE).Select(u => u.Id).ToListAsync();
} }
// 如果范围类型是本部门及以下部门,则查询本节点和子节点集合,包含本节点 // 如果范围类型是本部门及以下部门,则查询本节点和子节点集合,包含本节点
else if (dataScopeType == (int)DataScopeType.DEPT_WITH_CHILD) else if (dataScopeType == (int)DataScopeType.DEPT_WITH_CHILD)

View File

@@ -238,7 +238,7 @@ namespace Ewide.Core.Util
var Message = "邮箱验证码为:" + code.ToString(); var Message = "邮箱验证码为:" + code.ToString();
mailMessage.Body = Message; mailMessage.Body = Message;
smtpClient.Send(mailMessage); smtpClient.Send(mailMessage);
return true; return true;
} }
catch catch

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=118.178.224.202;Port=3306;Database=ewide;User ID=root;Password=root;pooling=true;sslmode=none;CharSet=utf8;"
}
}

View File

@@ -36,9 +36,11 @@ export default {
onAccountSetting() { onAccountSetting() {
this.openContentWindow({ this.openContentWindow({
key: 'account-home', id: 'account-home',
title: '个人中心', meta: {
icon: 'user', title: '个人设置',
icon: '',
},
path: '/system/account' path: '/system/account'
}) })
}, },

View File

@@ -19,6 +19,7 @@
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"photoswipe": "^4.1.3", "photoswipe": "^4.1.3",
"react": "^17.0.2", "react": "^17.0.2",
"react-color": "^2.19.3",
"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",

View File

@@ -35,6 +35,7 @@
@import './lib/tree-layout.less'; @import './lib/tree-layout.less';
@import './lib/authority-view.less'; @import './lib/authority-view.less';
@import './lib/icon-selector.less'; @import './lib/icon-selector.less';
@import './lib/color-selector.less';
@import './lib/anchor.less'; @import './lib/anchor.less';
@import './lib/disabled.less'; @import './lib/disabled.less';
@import './theme/primary.less'; @import './theme/primary.less';

View File

@@ -9,7 +9,12 @@
width: 150px; width: 150px;
} }
.ant-descriptions { .ant-descriptions {
clear: both;
margin-bottom: @padding-sm; margin-bottom: @padding-sm;
.ant-descriptions-view {
overflow: visible;
}
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
@@ -26,4 +31,23 @@
} }
} }
} }
.ant-card-grid {
width: 25%;
margin-bottom: @padding-sm;
padding: @padding-xs;
cursor: pointer;
}
.ant-card {
margin-bottom: 0;
background-color: transparent;
&-body {
margin: -1px 0 0 -1px;
padding: 0;
}
.ant-card-grid {
margin-bottom: 0;
}
}
} }

View File

@@ -0,0 +1,18 @@
@import (reference) '../extend.less';
.ant-select-dropdown {
.chrome-picker {
width: auto !important;
margin: -@padding-xxs 0;
border-radius: 0 !important;
background: transparent !important;
box-shadow: none !important;
}
}
.color-selector--palette {
width: 32px;
height: 32px;
border-radius: @border-radius-base;
box-shadow: inset 0 0 0 @border-width-base @border-color-base, inset 0 0 0 3px @white;
}

View File

@@ -315,6 +315,13 @@
white-space: normal; white-space: normal;
} }
} }
.ant-form-vertical {
.ant-form-item-label {
>label {
font-weight: bold;
}
}
}
.ant-form-item-required { .ant-form-item-required {
&::before { &::before {
content: '' !important; content: '' !important;

View File

@@ -0,0 +1,5 @@
const urls = {
houseQueryPage: ['/houseQuery/page', 'post'],
}
export default urls

View File

@@ -5,6 +5,7 @@ import houseMember from './houseMember'
import houseSelector from './houseSelector' import houseSelector from './houseSelector'
import houseTask from './houseTask' import houseTask from './houseTask'
import houseInfo from './houseInfo' import houseInfo from './houseInfo'
import houseQuery from './houseQuery'
const urls = { const urls = {
...houseProjectInfo, ...houseProjectInfo,
@@ -13,7 +14,8 @@ const urls = {
...houseMember, ...houseMember,
...houseSelector, ...houseSelector,
...houseTask, ...houseTask,
...houseInfo ...houseInfo,
...houseQuery
} }
export default urls export default urls

View File

@@ -73,6 +73,18 @@ const urls = {
* 更新基本信息 * 更新基本信息
*/ */
sysUserUpdateInfo: ['/sysUser/updateInfo', 'post'], sysUserUpdateInfo: ['/sysUser/updateInfo', 'post'],
/**
* 发送验证码
*/
SendCode: ['/sysUser/SendCode', 'post'],
/**
* 绑定/验证
*/
CheckBindcode: ['/sysUser/CheckBindcode', 'post'],
} }
export default urls export default urls

View File

@@ -1,9 +1,10 @@
const SESSION_KEY = '__SESSION' const SESSION_KEY = '__SESSION'
const SETTING_KEY = '__SETTINGS' const SETTING_KEY = '__SETTINGS'
const GLOBAL_INFO_KEY = '__GLOBAL_INFO' const GLOBAL_INFO_KEY = '__GLOBAL_INFO'
const COUNT_DWON_KEY = '__COUNT_DWON'
export { export {
SESSION_KEY, SESSION_KEY,
SETTING_KEY, SETTING_KEY,
GLOBAL_INFO_KEY, GLOBAL_INFO_KEY,
COUNT_DWON_KEY
} }

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { Checkbox, Descriptions, Empty, Spin, Tooltip } from 'antd' import { Card, Checkbox, Descriptions, Empty, Popover, Spin, Tooltip } from 'antd'
import { AntIcon } from 'components' import { AntIcon } from 'components'
import { EMPTY_ID } from 'util/global' import { EMPTY_ID } from 'util/global'
@@ -58,7 +58,7 @@ function renderDescriptions(data) {
function renderItem(data) { function renderItem(data) {
return ( return (
<Descriptions bordered column={1}> <Descriptions bordered column={1} contentStyle={{ padding: 0 }}>
<Descriptions.Item <Descriptions.Item
label={ label={
<Checkbox <Checkbox
@@ -71,7 +71,7 @@ function renderItem(data) {
</Checkbox> </Checkbox>
} }
> >
{renderDescriptions.call(this, data.children)} <Card bordered={false}>{renderDescriptions.call(this, data.children)}</Card>
</Descriptions.Item> </Descriptions.Item>
</Descriptions> </Descriptions>
) )
@@ -79,16 +79,26 @@ function renderItem(data) {
function renderCheckbox(data) { function renderCheckbox(data) {
return ( return (
<div className="yo-authority-view--checkbox"> <label className="ant-card-grid ant-card-grid-hoverable">
<Checkbox value={data.id} checked={data.checked} onChange={e => this.onChange(e, data)}> <Popover
{data.title} placement="topLeft"
</Checkbox> content={data.remark || <span className="text-normal">没有说明</span>}
{data.visibleParent && data.type == 2 && ( >
<Tooltip placement="top" title="选中此项才会显示菜单"> <Checkbox
<AntIcon type="eye" style={{ color: '#1890ff' }} className="mr-xxs" /> value={data.id}
</Tooltip> checked={data.checked}
)} onChange={e => this.onChange(e, data)}
</div> >
{data.title}
</Checkbox>
{data.visibleParent && data.type == 2 && (
<Tooltip placement="bottom" title="选中此项才会显示菜单">
<AntIcon type="eye" style={{ color: '#1890ff' }} className="mr-xxs" />
</Tooltip>
)}
<div className="text-gray">{data.permission}</div>
</Popover>
</label>
) )
} }

View File

@@ -0,0 +1,55 @@
import React, { Component } from 'react'
import { Col, Row, Select } from 'antd'
import { ChromePicker } from 'react-color'
export default class index extends Component {
select = React.createRef()
state = {
color: null,
}
onChange(color) {
this.setState({ color: color.hex })
}
onChangeComplete(color) {
this.props.onChange && this.props.onChange(color.hex)
}
render() {
const { color } = this.state
const { value } = this.props
return (
<Row gutter={8}>
<Col flex="1">
<Select
ref={this.select}
dropdownRender={() => (
<ChromePicker
color={color || value || '#000'}
disableAlpha
onChange={color => this.onChange(color)}
onChangeComplete={color => this.onChangeComplete(color)}
/>
)}
showArrow={false}
{...this.props}
value={value}
/>
</Col>
<Col flex="32px">
<div
className="color-selector--palette"
style={{ backgroundColor: color || value || '#000' }}
onClick={() => {
this.select.current.focus()
}}
></div>
</Col>
</Row>
)
}
}

View File

@@ -0,0 +1,46 @@
import React, { Component } from 'react'
import { Col, Input, InputNumber, Row } from 'antd'
import { AntIcon } from 'components'
export default class index extends Component {
render() {
const { unit, placeholder, value, onChange } = this.props
console.log(value)
return (
<Input.Group>
<Row align="middle">
<Col flex="1">
<InputNumber
{...this.props}
className="w-100-p"
placeholder={placeholder && placeholder[0]}
value={value && value[0]}
onChange={e => {
const result = [e, value && value[1]]
onChange && onChange(result)
}}
/>
</Col>
<span className="yo-addon">
<AntIcon className="text-gray" type="swap-right" />
</span>
<Col flex="1">
<InputNumber
{...this.props}
className="w-100-p"
placeholder={placeholder && placeholder[1]}
value={value && value[1]}
onChange={e => {
const result = [value && value[0], e]
onChange && onChange(result)
}}
/>
</Col>
{unit && <span className="yo-addon">{unit}</span>}
</Row>
</Input.Group>
)
}
}

View File

@@ -1,11 +1,13 @@
export { default as AntIcon } from 'components/ant-icon' export { default as AntIcon } from 'components/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 ComponentDynamic } from './component-dynamic' export { default as ComponentDynamic } from './component-dynamic'
export { default as Container } from './container' export { default as Container } from './container'
export { default as IconSelector } from './icon-selector' export { default as IconSelector } from './icon-selector'
export { default as Image } from './image' export { default as Image } from './image'
export { default as ModalForm } from './modal-form' export { default as ModalForm } from './modal-form'
export { default as InputNumberRange } from './form/input-number-range'
export { default as PhotoPreview } from './photo-preview' export { default as PhotoPreview } from './photo-preview'
export { default as QueryList } from './query-list' export { default as QueryList } from './query-list'
export { default as QueryTable } from './query-table' export { default as QueryTable } from './query-table'

View File

@@ -1,6 +1,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { Button, Form, List, Pagination, Spin, Tooltip } from 'antd' import { Button, Form, List, Pagination, Spin, Tooltip } from 'antd'
import { AntIcon } from 'components' import { AntIcon } from 'components'
import { cloneDeep } from 'lodash'
const propsMap = ['autoLoad', 'loadData', 'pageIndex', 'pageSize'] const propsMap = ['autoLoad', 'loadData', 'pageIndex', 'pageSize']
@@ -113,7 +114,7 @@ export default class QueryList extends Component {
pageIndex: this.pagination.current, pageIndex: this.pagination.current,
pageSize: this.pagination.pageSize, pageSize: this.pagination.pageSize,
}, },
this.query cloneDeep(this.query)
) )
this.setState( this.setState(

View File

@@ -1,7 +1,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { Form, Button, Table, Tooltip } from 'antd' import { Form, Button, Table, Tooltip, Drawer } from 'antd'
import { AntIcon } from 'components' import { AntIcon } from 'components'
import { isEqual } from 'lodash' import { cloneDeep, isEqual } from 'lodash'
const propsMap = ['columns', 'autoLoad', 'loadData', 'pageIndex', 'pageSize'] const propsMap = ['columns', 'autoLoad', 'loadData', 'pageIndex', 'pageSize']
@@ -34,17 +34,18 @@ const rowNoColumn = {
* @returns * @returns
*/ */
function renderQueryBar() { function renderQueryBar() {
const { query, moreQuery, onQueryChange } = this.props const { query, moreQuery, onQueryChange, queryInitialValues } = this.props
return ( return (
<div className="yo-query-bar"> <div className="yo-query-bar">
<Form <Form
layout="inline" layout="inline"
ref={this.form} ref={this.queryForm}
onFinish={value => this.onQuery(value)} onFinish={value => this.onQuery(value)}
initialValues={this.props.queryInitialValues} initialValues={queryInitialValues}
onValuesChange={(changedValues, allValues) => onValuesChange={(changedValues, allValues) =>
onQueryChange && onQueryChange(changedValues, allValues) onQueryChange &&
this.queryForm.current.setFieldsValue(onQueryChange(changedValues, allValues))
} }
> >
{query} {query}
@@ -55,18 +56,73 @@ function renderQueryBar() {
</Button> </Button>
<Tooltip placement="bottom" title="重置查询"> <Tooltip placement="bottom" title="重置查询">
<Button <Button
onClick={() => this.onResetQuery()} onClick={() => this.onResetQuery(this.queryForm)}
icon={<AntIcon type="undo" />} icon={<AntIcon type="undo" />}
/> />
</Tooltip> </Tooltip>
</Button.Group> </Button.Group>
{moreQuery && <Button>更多查询条件</Button>} {moreQuery && (
<Button type="text" onClick={() => this.onOpenMoreQuery()}>
更多查询条件
</Button>
)}
</Form.Item> </Form.Item>
</Form> </Form>
</div> </div>
) )
} }
function renderMoreQueryBody() {
const { moreQueryVisible } = this.state
const { moreQuery, onQueryChange, queryInitialValues } = this.props
return (
<Drawer
width={700}
title="查询"
className="yo-drawer-form"
visible={moreQueryVisible}
forceRender
onClose={() => this.setState({ moreQueryVisible: false })}
>
<Form
layout="vertical"
ref={this.moreQueryForm}
initialValues={queryInitialValues}
onValuesChange={(changedValues, allValues) =>
onQueryChange &&
this.moreQueryForm.current.setFieldsValue(
onQueryChange(changedValues, allValues)
)
}
>
<div className="yo-drawer-form--body">{moreQuery}</div>
<div className="ant-drawer-footer">
<Button.Group>
<Button
htmlType="submit"
type="primary"
icon={<AntIcon type="search" />}
onClick={() =>
this.onQuery(this.moreQueryForm.current.getFieldsValue())
}
>
查询
</Button>
<Tooltip placement="top" title="重置查询">
<Button
onClick={() => this.onResetQuery(this.moreQueryForm)}
icon={<AntIcon type="undo" />}
/>
</Tooltip>
</Button.Group>
</div>
</Form>
</Drawer>
)
}
function renderTable(props, on) { function renderTable(props, on) {
return <Table className="yo-table" {...props} {...on} /> return <Table className="yo-table" {...props} {...on} />
} }
@@ -79,10 +135,14 @@ export default class QueryTable extends Component {
type: 'tree', type: 'tree',
// 数据 // 数据
dataSource: [], dataSource: [],
moreQueryVisible: false,
} }
// 查询表单实例 // 查询表单实例
form = React.createRef() queryForm = React.createRef()
// 更多查询表单实例
moreQueryForm = React.createRef()
// 查询值 // 查询值
query = {} query = {}
@@ -168,7 +228,7 @@ export default class QueryTable extends Component {
pageSize: this.pagination.pageSize, pageSize: this.pagination.pageSize,
...this.sorter, ...this.sorter,
}, },
this.query cloneDeep(this.query)
) )
if (res.rows || res.data || res.items) { if (res.rows || res.data || res.items) {
this.setState({ this.setState({
@@ -213,7 +273,13 @@ export default class QueryTable extends Component {
* @param {*} values * @param {*} values
*/ */
onQuery = values => { onQuery = values => {
this.query = values const { queryInitialValues } = this.props
this.query = {
...queryInitialValues,
...this.query,
...values,
}
this.onReloadData(true) this.onReloadData(true)
} }
@@ -221,15 +287,25 @@ export default class QueryTable extends Component {
* 重置查询 * 重置查询
* 初始化表单字段值,加载数据,并返回到第一页 * 初始化表单字段值,加载数据,并返回到第一页
*/ */
onResetQuery = () => { onResetQuery = from => {
const { queryInitialValues, onQueryChange } = this.props const { queryInitialValues, onQueryChange, query, moreQuery } = this.props
let queryValues = {}
if (from === this.queryForm) {
from.current.resetFields()
queryValues = moreQuery ? this.moreQueryForm.current.getFieldsValue() : {}
} else if (from === this.moreQueryForm) {
from.current.resetFields()
queryValues = query ? this.queryForm.current.getFieldsValue() : {}
}
this.form.current.resetFields()
this.query = { this.query = {
...queryInitialValues, ...queryInitialValues,
...queryValues,
} }
const values = this.form.current.getFieldsValue()
onQueryChange && onQueryChange(values, values) const changedValues = cloneDeep(this.query)
onQueryChange && onQueryChange(changedValues, changedValues)
this.onReloadData(true) this.onReloadData(true)
} }
@@ -277,12 +353,16 @@ export default class QueryTable extends Component {
return false return false
} }
onOpenMoreQuery = () => {
this.setState({ moreQueryVisible: true })
}
render() { render() {
const { rowNumber } = this const { rowNumber } = this
const { loading, dataSource, type } = this.state const { loading, dataSource, type } = this.state
const { query, operator, columns, expandable, expandedRowRender } = this.props const { query, moreQuery, operator, columns, expandable, expandedRowRender } = this.props
const attrs = {} const attrs = {}
Object.keys(this.props).forEach(key => { Object.keys(this.props).forEach(key => {
@@ -337,6 +417,7 @@ export default class QueryTable extends Component {
) : ( ) : (
renderTable.call(this, props, on) renderTable.call(this, props, on)
)} )}
{moreQuery && renderMoreQueryBody.call(this)}
</section> </section>
) )
} }

View File

@@ -157,35 +157,37 @@ export default class building extends Component {
onValuesChange(changedValues, allValues) { onValuesChange(changedValues, allValues) {
const form = this.form.current const form = this.form.current
const { houseInfo } = changedValues const { houseInfo } = changedValues
if ( if (houseInfo) {
houseInfo.hasOwnProperty('landFloorCount') || if (
houseInfo.hasOwnProperty('underFloorCount') houseInfo.hasOwnProperty('landFloorCount') ||
) { houseInfo.hasOwnProperty('underFloorCount')
const { ) {
houseInfo: { landFloorCount, underFloorCount }, const {
} = allValues houseInfo: { landFloorCount, underFloorCount },
form.setFieldsValue({ } = allValues
houseInfo: { form.setFieldsValue({
totalFloor: +landFloorCount + +underFloorCount, houseInfo: {
}, totalFloor: +landFloorCount + +underFloorCount,
}) },
} })
}
if (houseInfo.hasOwnProperty('insulationMaterial')) { if (houseInfo.hasOwnProperty('insulationMaterial')) {
const value = this.checkedNone(houseInfo.insulationMaterial, 'insulationMaterial') const value = this.checkedNone(houseInfo.insulationMaterial, 'insulationMaterial')
this.setState({ this.setState({
showKeepWarmMaterialText: value.includes('100'), showKeepWarmMaterialText: value.includes('100'),
}) })
} }
if (houseInfo.hasOwnProperty('completedDate')) { if (houseInfo.hasOwnProperty('completedDate')) {
dispatch({ dispatch({
type: 'PATROL_INIT_GRADE_BY_COMPLETED_DATE', type: 'PATROL_INIT_GRADE_BY_COMPLETED_DATE',
date: { date: {
id: this.props.id, id: this.props.id,
value: +houseInfo.completedDate.format('YYYY'), value: +houseInfo.completedDate.format('YYYY'),
}, },
}) })
}
} }
} }

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { Form, Button, Input, Descriptions, message as Message, Spin, Tabs } from 'antd' import { Form, Button, Input, Descriptions, message as Message, Modal, Spin, Tabs } from 'antd'
import { merge, isEqual } from 'lodash' import { merge, isEqual } from 'lodash'
import { AntIcon, ComponentDynamic, Container } from 'components' import { AntIcon, ComponentDynamic, Container } from 'components'
import { api } from 'common/api' import { api } from 'common/api'
@@ -46,6 +46,23 @@ const tabs = [
show: true, show: true,
}, },
] ]
const actions = {
save: {
action: 'houseInfoSave',
remark: '保存',
after: 'reload',
},
submit: {
action: 'houseInfoSubmitToCheck',
remark: '提交',
after: 'close',
},
check: {
action: 'houseInfoSave',
remark: '审核',
after: 'close',
},
}
export default class index extends Component { export default class index extends Component {
state = { state = {
@@ -62,7 +79,7 @@ export default class index extends Component {
children = [] children = []
formData = {} formData = {}
checkform = React.createRef() checkForm = React.createRef()
shouldComponentUpdate(props, state) { shouldComponentUpdate(props, state) {
return !isEqual(this.state, state) return !isEqual(this.state, state)
@@ -89,7 +106,43 @@ export default class index extends Component {
} }
} }
async onSubmit(action, append) { async onSave() {
await this.onPostData(actions.save)
}
async onSubmit() {
Modal.confirm({
content: '确认提交审核吗?',
onOk: () => {
this.onPostData(actions.submit)
},
onCancel: () => {},
})
}
async onCheck(pass_or_back) {
const form = this.checkForm.current
const valid = await form.validateFields()
Modal.confirm({
content: '审核结果即将提交,请确认',
onOk: () => {
if (valid) {
var checkRecord = {
taskCheckRecord: {
taskId: this.props.param.taskId,
passOrBack: +pass_or_back,
content: form.getFieldValue(['taskCheckRecord', 'content']),
},
}
this.onPostData(actions.check, checkRecord)
}
},
onCancel: () => {},
})
}
async onPostData(action, append) {
for (const child of this.children) { for (const child of this.children) {
try { try {
const data = await child.getData() const data = await child.getData()
@@ -118,12 +171,28 @@ export default class index extends Component {
console.log(this.formData) console.log(this.formData)
this.setState({ saving: true }) this.setState({ saving: true })
api[action](this.formData) if (action) {
.then(({ data }) => {}) try {
.catch(() => {}) const { success } = await api[action.action](this.formData)
.finally(() => { if (success) {
Message.success(action.remark + '成功')
this.setState({ saving: false })
if (this.props.param.table) {
this.props.param.table.current.onReloadData()
}
switch (action.after) {
case 'close':
window.closeContentWindow()
break
default:
this.componentDidMount()
break
}
}
} finally {
this.setState({ saving: false }) this.setState({ saving: false })
}) }
}
// setTimeout(() => { // setTimeout(() => {
// Message.success('提交成功') // Message.success('提交成功')
@@ -163,8 +232,18 @@ export default class index extends Component {
/> />
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
<Button type="primary">通过</Button> <Button
<Button type="primary">退回</Button> type="primary"
onClick={() => this.onCheck(6)}
>
通过
</Button>
<Button
type="primary"
onClick={() => this.onCheck(-1)}
>
退回
</Button>
</Form.Item> </Form.Item>
</Form> </Form>
)} )}
@@ -175,16 +254,13 @@ export default class index extends Component {
disabled={saveDisabled} disabled={saveDisabled}
loading={saving} loading={saving}
type="primary" type="primary"
onClick={() => this.onSubmit('houseInfoSave')} onClick={() => this.onSave()}
> >
保存 保存
</Button> </Button>
)} )}
{this.state.taskStatus == 2 && ( {this.state.taskStatus == 2 && (
<Button <Button type="primary" onClick={() => this.onSubmit()}>
type="primary"
onClick={() => this.onSubmit('houseInfoSubmitToCheck')}
>
提交审核 提交审核
</Button> </Button>
)} )}

View File

@@ -124,7 +124,6 @@ export default class handling extends Component {
render() { render() {
const { loading, codes, initGradeValue } = this.state const { loading, codes, initGradeValue } = this.state
console.log(initGradeValue)
return ( return (
<Spin spinning={loading} indicator={<AntIcon type="loading" />}> <Spin spinning={loading} indicator={<AntIcon type="loading" />}>
<Form {...layout} ref={this.form}> <Form {...layout} ref={this.form}>

View File

@@ -249,7 +249,7 @@ export default class index extends Component {
size="small" size="small"
type="primary" type="primary"
className="block w-100-p mt-xxs" className="block w-100-p mt-xxs"
onClick={() => this.onOpen(this.selectorModal, record)} onClick={() => this.onOpen(this.selectorModal, id)}
> >
选房 选房
</Button> </Button>

View File

@@ -0,0 +1,538 @@
import React, { Component } from 'react'
import {
Button,
Card,
Checkbox,
Col,
DatePicker,
Form,
Input,
InputNumber,
message as Message,
Row,
Tag,
} from 'antd'
import { AntIcon, Auth, Container, InputNumberRange, QueryTable } from 'components'
import { api } from 'common/api'
import auth from 'components/authorized/handler'
import { first, isEqual, last } from 'lodash'
import getDictData from 'util/dic'
import { toCamelCase } from 'util/format'
import { getSearchDateRange, getSearchInfo, QueryType } from 'util/query'
/**
* 注释段[\/**\/]为必须要改
*/
/**
* 配置页面所需接口函数
*/
const apiAction = {
page: api.houseQueryPage,
}
/**
* 用于弹窗标题
* [必要]
*/
const name = '/**/'
/**
* 统一配置权限标识
* [必要]
*/
const authName = 'houseQuery'
export default class index extends Component {
state = {
codes: {
houseUsedStatus: [],
housePropertyRights: [],
landAttribute: [],
houseBaseInfo: [],
houseStructureType: [],
houseStorageOfDrawings: [],
houseGrade: [],
},
showDrawingMaterialText: false,
}
// 表格实例
table = React.createRef()
// 新增窗口实例
addForm = React.createRef()
// 编辑窗口实例
editForm = React.createRef()
columns = [
{
title: '房屋编码',
dataIndex: 'houseCode',
sorter: true,
width: 300,
render: (text, record) => (
<>
{`${record.areaName}-${record.roadName}-${record.commName}-${
record.note
}-${record.no.toString().padStart(3, '0')}`}
<br />
<Tag color="purple">{text}</Tag>
</>
),
},
{
title: '房屋性质及行业',
dataIndex: 'type',
sorter: true,
width: 150,
render: text => this.bindCodeValue(text, 'house_type'),
},
{
title: '地址',
dataIndex: 'address',
sorter: true,
},
{
title: '任务截止时间',
dataIndex: 'endTime',
sorter: true,
width: 150,
},
]
/**
* 构造函数,在渲染前动态添加操作字段等
* @param {*} props
*/
constructor(props) {
super(props)
const flag = auth({ [authName]: [['edit'], ['delete']] })
}
/**
* 阻止外部组件引发的渲染,提升性能
* 可自行添加渲染条件
* [必要]
* @param {*} props
* @param {*} state
* @returns
*/
shouldComponentUpdate(props, state) {
return !isEqual(this.state, state)
}
/**
* 加载字典数据,之后开始加载表格数据
* 如果必须要加载字典数据,可直接对表格设置autoLoad=true
*/
componentDidMount() {
const { onLoading, onLoadData } = this.table.current
onLoading()
getDictData(
'house_used_status',
'house_property_rights',
'land_attribute',
'house_base_info',
'house_structure_type',
'house_storage_of_drawings',
'house_grade'
).then(codes => {
this.setState({ codes }, () => {
onLoadData()
})
})
}
/**
* 调用加载数据接口,可在调用前对query进行处理
* [异步,必要]
* @param {*} params
* @param {*} query
* @returns
*/
loadData = async (params, query) => {
query.completedDate = getSearchDateRange(query.completedDate)
query.createdTime = getSearchDateRange(query.createdTime)
const searchInfo = getSearchInfo({
query,
queryType: {
areaCode: QueryType.Like,
completedDate: [QueryType.GreaterThanOrEqual, QueryType.LessThan],
createdTime: [QueryType.GreaterThanOrEqual, QueryType.LessThan],
totalArea: [QueryType.GreaterThanOrEqual, QueryType.LessThanOrEqual],
totalFloor: [QueryType.GreaterThanOrEqual, QueryType.LessThanOrEqual],
},
})
const { data } = await apiAction.page({
...params,
searchInfo,
})
return data
}
/**
* 绑定字典数据
* @param {*} code
* @param {*} name
* @returns
*/
bindCodeValue(code, name) {
name = toCamelCase(name)
const codes = this.state.codes[name]
if (codes) {
const c = codes.find(p => p.code == code)
if (c) {
return c.value
}
}
return null
}
/**
* 打开新增/编辑弹窗
* @param {*} modal
* @param {*} id
*/
onOpen(modal, id) {
modal.current.open({ id })
}
/**
* 对表格上的操作进行统一处理
* [异步]
* @param {*} action
* @param {*} successMessage
*/
async onAction(action, successMessage) {
const { onLoading, onLoaded, onReloadData } = this.table.current
onLoading()
try {
if (action) {
await action
}
if (successMessage) {
Message.success(successMessage)
}
onReloadData()
} catch {
onLoaded()
}
}
/**
* 删除
* @param {*} id
*/
onDelete(id) {
this.onAction(apiAction.delete({ id }), '删除成功')
}
//#region 自定义方法
rednerMoreQuery() {
const { codes, showDrawingMaterialText } = this.state
return (
<Row gutter={16}>
<Col span={24}>
<Form.Item label="使用状态" name="houseUsedStatus">
<Checkbox.Group>
{codes.houseUsedStatus.map(item => (
<Checkbox key={item.code} value={+item.code}>
{item.value}
</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="有无幕墙" name="curtainWall">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
<Checkbox value={0}></Checkbox>
<Checkbox value={1}></Checkbox>
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="有无面砖" name="faceBrick">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
<Checkbox value={0}></Checkbox>
<Checkbox value={1}></Checkbox>
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="有无涂料" name="coating">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
<Checkbox value={0}></Checkbox>
<Checkbox value={1}></Checkbox>
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="有无粉刷" name="painting">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
<Checkbox value={0}></Checkbox>
<Checkbox value={1}></Checkbox>
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="安全管理员">
<Input autoComplete="off" placeholder="请输入安全管理员" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="片区监管员">
<Input autoComplete="off" placeholder="请输入片区监管员" />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="产权性质" name="propertyRights">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
{codes.housePropertyRights.map(item => (
<Checkbox key={item.code} value={+item.code}>
{item.value}
</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="土地性质" name="landAttribute">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
{codes.landAttribute.map(item => (
<Checkbox key={item.code} value={+item.code}>
{item.value}
</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="基础情况" name="baseInfo">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
{codes.houseBaseInfo.map(item => (
<Checkbox key={item.code} value={+item.code}>
{item.value}
</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="结构类型" name="structureType">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
{codes.houseStructureType.map(item => (
<Checkbox key={item.code} value={+item.code}>
{item.value}
</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="图纸资料存档处" name="drawingMaterial">
<Form.Item name="drawingMaterial" className="mb-none">
<Checkbox.Group>
{codes.houseStorageOfDrawings.map(item => (
<Checkbox key={item.code} value={item.code}>
{item.value}
</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
{showDrawingMaterialText && (
<Form.Item name="drawingMaterialText" className="mb-none mt-xs">
<Input.TextArea autoSize placeholder="请输入其他图纸资料存档处" />
</Form.Item>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="竣工日期" name="completedDate">
<DatePicker.RangePicker
className="w-100-p"
placeholder={['请选择竣工开始日期', '请选择竣工结束日期']}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="填表日期" name="createdTime">
<DatePicker.RangePicker
className="w-100-p"
placeholder={['请选择填表开始日期', '请选择填表结束日期']}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="总建筑面积" name="totalArea">
<InputNumberRange
min={0}
unit="m²"
placeholder={['请输入最小总建筑面积', '请输入最大总建筑面积']}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="总层数" name="totalFloor">
<InputNumberRange
min={0}
precision={0}
step={1}
unit="层"
placeholder={['请输入最小总层数', '请输入最大总层数']}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="建设单位" name="buildingUnit">
<Input autoComplete="off" placeholder="请输入建设单位" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="设计单位" name="desingerUnit">
<Input autoComplete="off" placeholder="请输入设计单位" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="施工单位" name="constructionUnit">
<Input autoComplete="off" placeholder="请输入施工单位" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="监理单位" name="monitorUnit">
<Input autoComplete="off" placeholder="请输入监理单位" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="产权单位" name="propertyUnit">
<Input autoComplete="off" placeholder="请输入产权单位" />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="综合等级" name="houseGrade">
<Checkbox.Group>
<Checkbox value="">全部</Checkbox>
{codes.houseGrade.map(item => (
<Checkbox key={item.code} value={+item.code}>
{item.value}
</Checkbox>
))}
</Checkbox.Group>
</Form.Item>
</Col>
</Row>
)
}
onQueryChange(changedValues, allValues) {
console.log(changedValues)
if (changedValues.hasOwnProperty('drawingMaterial') && changedValues.drawingMaterial) {
this.setState({
showDrawingMaterialText: changedValues.drawingMaterial.includes('100'),
})
return
}
// 全部
const { codes } = this.state
const key = first(Object.keys(changedValues))
const mapCount = {
curtainWall: 2,
faceBrick: 2,
coating: 2,
painting: 2,
propertyRights: codes.housePropertyRights.length,
landAttribute: codes.landAttribute.length,
baseInfo: codes.houseBaseInfo.length,
structureType: codes.houseStructureType.length,
houseGrade: codes.houseGrade.length,
}
if (Object.keys(mapCount).includes(key)) {
return {
[key]: this.checkedNone(changedValues[key], mapCount[key]),
}
}
}
checkedNone(value, count) {
if (first(value) == '' && value.length > 1) {
// 在'无'之后选中其他值
value.shift()
} else if ((last(value) == '' && value.length > 1) || value.length === count) {
// 在其他值之后选中'无'
value = ['']
}
return value
}
//#endregion
render() {
const { codes, type } = this.state
return (
<Container mode="fluid">
<br />
<Card bordered={false}>
<QueryTable
ref={this.table}
autoLoad={false}
loadData={this.loadData}
columns={this.columns}
queryInitialValues={{
houseUsedStatus: [1, 2],
curtainWall: [''],
faceBrick: [''],
coating: [''],
painting: [''],
propertyRights: [''],
landAttribute: [''],
baseInfo: [''],
structureType: [''],
houseGrade: [''],
}}
query={
<Auth auth={{ [authName]: 'page' }}>
<Form.Item label="地址" name="address">
<Input autoComplete="off" placeholder="请输入地址" />
</Form.Item>
<Form.Item label="房屋唯一编码" name="houseCode">
<Input autoComplete="off" placeholder="请输入房屋唯一编码" />
</Form.Item>
</Auth>
}
moreQuery={
<Auth auth={{ [authName]: 'page' }}>{this.rednerMoreQuery()}</Auth>
}
onQueryChange={(changedValues, allValues) =>
this.onQueryChange(changedValues, allValues)
}
operator={
<Auth auth={{ [authName]: 'add' }}>
<Button
icon={<AntIcon type="plus" />}
onClick={() => this.onOpen(this.addForm)}
>
新增{name}
</Button>
</Auth>
}
/>
</Card>
</Container>
)
}
}

View File

@@ -6,6 +6,7 @@ import auth from 'components/authorized/handler'
import { isEqual } from 'lodash' import { isEqual } from 'lodash'
import getDictData from 'util/dic' import getDictData from 'util/dic'
import { toCamelCase } from 'util/format' import { toCamelCase } from 'util/format'
import { getSearchInfo } from 'util/query'
/** /**
* 注释段[\/**\/]为必须要改 * 注释段[\/**\/]为必须要改
@@ -27,6 +28,10 @@ const authName = 'houseTask'
export default class index extends Component { export default class index extends Component {
state = { state = {
codes: { codes: {
status: [
{ code: 3, value: '审核中' },
{ code: 6, value: '审核通过' },
],
houseType: [], houseType: [],
houseIndustry: [], houseIndustry: [],
}, },
@@ -63,7 +68,9 @@ export default class index extends Component {
dataIndex: 'type', dataIndex: 'type',
sorter: true, sorter: true,
width: 150, width: 150,
render: text => this.bindCodeValue(text, 'house_type'), render: (text, record) =>
this.bindCodeValue(text, 'house_type') +
(text === 2 ? `(${this.bindCodeValue(record.industry, 'house_industry')})` : ''),
}, },
{ {
title: '地址', title: '地址',
@@ -76,6 +83,13 @@ export default class index extends Component {
sorter: true, sorter: true,
width: 150, width: 150,
}, },
{
title: '审核状态',
dataIndex: 'status',
sorter: true,
width: 100,
render: text => this.bindCodeValue(text, 'status'),
},
] ]
/** /**
@@ -95,7 +109,9 @@ export default class index extends Component {
render: (text, record) => ( render: (text, record) => (
<QueryTableActions> <QueryTableActions>
<Auth auth={{ houseInfo: 'getByTaskId' }}> <Auth auth={{ houseInfo: 'getByTaskId' }}>
<a onClick={() => this.onOpen(record.id)}>审核</a> <a onClick={() => this.onOpen(record.id)}>
{record.state === 3 ? `审核` : `查看`}
</a>
</Auth> </Auth>
</QueryTableActions> </QueryTableActions>
), ),
@@ -123,7 +139,7 @@ export default class index extends Component {
const { onLoading, onLoadData } = this.table.current const { onLoading, onLoadData } = this.table.current
onLoading() onLoading()
getDictData('house_type', 'house_industry').then(codes => { getDictData('house_type', 'house_industry').then(codes => {
this.setState({ codes }, () => { this.setState({ codes: { ...this.state.codes, ...codes } }, () => {
onLoadData() onLoadData()
}) })
}) })
@@ -137,9 +153,20 @@ export default class index extends Component {
* @returns * @returns
*/ */
loadData = async (params, query) => { loadData = async (params, query) => {
const searchInfo = getSearchInfo({
query,
queryType: {
type: '=',
industry: '=',
address: 'like',
houseCode: 'like',
status: '=',
},
})
const { data } = await apiAction.page({ const { data } = await apiAction.page({
...params, ...params,
...query, searchInfo,
}) })
return data return data
} }
@@ -173,6 +200,7 @@ export default class index extends Component {
path: 'business/house/info/form', path: 'business/house/info/form',
param: { param: {
taskId, taskId,
table: this.table,
}, },
}) })
} }
@@ -216,6 +244,7 @@ export default class index extends Component {
columns={this.columns} columns={this.columns}
queryInitialValues={{ queryInitialValues={{
type: '', type: '',
status: '',
}} }}
onQueryChange={values => { onQueryChange={values => {
if (values.hasOwnProperty('type')) { if (values.hasOwnProperty('type')) {
@@ -255,6 +284,16 @@ export default class index extends Component {
<Form.Item label="房屋唯一编码" name="houseCode"> <Form.Item label="房屋唯一编码" name="houseCode">
<Input autoComplete="off" placeholder="请输入房屋唯一编码" /> <Input autoComplete="off" placeholder="请输入房屋唯一编码" />
</Form.Item> </Form.Item>
<Form.Item label="审核状态" name="status">
<Radio.Group buttonStyle="solid">
<Radio.Button value="">全部</Radio.Button>
{codes.status.map(item => (
<Radio.Button key={item.code} value={item.code}>
{item.value}
</Radio.Button>
))}
</Radio.Group>
</Form.Item>
</Auth> </Auth>
} }
/> />

View File

@@ -6,6 +6,7 @@ import auth from 'components/authorized/handler'
import { isEqual } from 'lodash' import { isEqual } from 'lodash'
import getDictData from 'util/dic' import getDictData from 'util/dic'
import { toCamelCase } from 'util/format' import { toCamelCase } from 'util/format'
import { getSearchInfo } from 'util/query'
/** /**
* 注释段[\/**\/]为必须要改 * 注释段[\/**\/]为必须要改
@@ -27,6 +28,14 @@ const authName = 'houseTask'
export default class index extends Component { export default class index extends Component {
state = { state = {
codes: { codes: {
status: [
{ code: -1, value: '审核退回' },
{ code: 0, value: '待处理' },
{ code: 1, value: '暂存' },
{ code: 2, value: '待提交' },
{ code: 3, value: '审核中' },
{ code: 6, value: '审核通过' },
],
houseType: [], houseType: [],
houseIndustry: [], houseIndustry: [],
}, },
@@ -63,7 +72,9 @@ export default class index extends Component {
dataIndex: 'type', dataIndex: 'type',
sorter: true, sorter: true,
width: 150, width: 150,
render: text => this.bindCodeValue(text, 'house_type'), render: (text, record) =>
this.bindCodeValue(text, 'house_type') +
(text === 2 ? `(${this.bindCodeValue(record.industry, 'house_industry')})` : ''),
}, },
{ {
title: '地址', title: '地址',
@@ -76,6 +87,13 @@ export default class index extends Component {
sorter: true, sorter: true,
width: 150, width: 150,
}, },
{
title: '建档状态',
dataIndex: 'state',
sorter: true,
width: 100,
render: text => this.bindCodeValue(text, 'status'),
},
] ]
/** /**
@@ -95,7 +113,13 @@ export default class index extends Component {
render: (text, record) => ( render: (text, record) => (
<QueryTableActions> <QueryTableActions>
<Auth auth={{ houseInfo: 'getByTaskId' }}> <Auth auth={{ houseInfo: 'getByTaskId' }}>
<a onClick={() => this.onOpen(record.id)}>登记</a> <a onClick={() => this.onOpen(record.id)}>
{record.state === -1 || record.state === 1 || record.state === 2
? `修改`
: record.state === 3 || record.state === 6
? `查看`
: `登记`}
</a>
</Auth> </Auth>
</QueryTableActions> </QueryTableActions>
), ),
@@ -123,7 +147,7 @@ export default class index extends Component {
const { onLoading, onLoadData } = this.table.current const { onLoading, onLoadData } = this.table.current
onLoading() onLoading()
getDictData('house_type', 'house_industry').then(codes => { getDictData('house_type', 'house_industry').then(codes => {
this.setState({ codes }, () => { this.setState({ codes: { ...this.state.codes, ...codes } }, () => {
onLoadData() onLoadData()
}) })
}) })
@@ -137,9 +161,20 @@ export default class index extends Component {
* @returns * @returns
*/ */
loadData = async (params, query) => { loadData = async (params, query) => {
const searchInfo = getSearchInfo({
query,
queryType: {
type: '=',
industry: '=',
address: 'like',
houseCode: 'like',
state: '=',
},
})
const { data } = await apiAction.page({ const { data } = await apiAction.page({
...params, ...params,
...query, searchInfo,
}) })
return data return data
} }
@@ -173,6 +208,7 @@ export default class index extends Component {
path: 'business/house/info/form', path: 'business/house/info/form',
param: { param: {
taskId, taskId,
table: this.table,
}, },
}) })
} }
@@ -216,6 +252,7 @@ export default class index extends Component {
columns={this.columns} columns={this.columns}
queryInitialValues={{ queryInitialValues={{
type: '', type: '',
state: 0,
}} }}
onQueryChange={values => { onQueryChange={values => {
if (values.hasOwnProperty('type')) { if (values.hasOwnProperty('type')) {
@@ -255,6 +292,16 @@ export default class index extends Component {
<Form.Item label="房屋唯一编码" name="houseCode"> <Form.Item label="房屋唯一编码" name="houseCode">
<Input autoComplete="off" placeholder="请输入房屋唯一编码" /> <Input autoComplete="off" placeholder="请输入房屋唯一编码" />
</Form.Item> </Form.Item>
<Form.Item label="建档状态" name="state">
<Select allowClear className="w-150" placeholder="建档状态">
<Select.Option value="">全部</Select.Option>
{codes.status.map(item => (
<Select.Option key={item.code} value={item.code}>
{item.value}
</Select.Option>
))}
</Select>
</Form.Item>
</Auth> </Auth>
} }
/> />

View File

@@ -0,0 +1,41 @@
import React, { Component } from 'react'
import { Anchor, Form, Input, InputNumber, Spin } from 'antd'
import { AntIcon, Container, IconSelector } from 'components'
import { cloneDeep } from 'lodash'
import Safety from './setting/satety/index'
import Info from './setting/info'
import nav from 'store/reducer/nav'
export default class index extends Component {
state = {}
render() {
// let navs = [
// {
// title: '我的信息',
// component: require('./setting/info'),
// },
// {
// title: '安全设置',
// component: require('./setting/satety'),
// },
// ]
// return (
// <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 (
<div>
<Info></Info>
<Safety></Safety>
</div>
)
}
}

View File

@@ -0,0 +1,127 @@
import React, { Component } from 'react'
import { Button, DatePicker, Form, Input, message, Radio, Spin } from 'antd'
import { api } from 'common/api'
import { cloneDeep } from 'lodash'
import { AntIcon, Container, IconSelector, Image } from 'components'
import store from 'store'
import moment from 'moment'
const { getState } = store
export default class index extends Component {
state = {
info: getState('user'),
saving: false,
loading: false,
}
form = React.createRef()
componentDidMount() {
this.setState({
loading: true,
})
api.getLoginUser()
.then(({ data }) => {
delete data.apps
delete data.menus
this.setState({
info: data,
})
let birthday = data.birthday
birthday = moment(birthday)
data = {
...data,
birthday: birthday,
}
this.form.current.setFieldsValue(data)
})
.finally(() => {
this.setState({
loading: false,
})
})
}
onSvaeInfo(data) {
this.setState({
saving: true,
})
let { birthday } = data.current.getFieldsValue()
let { nickName } = data.current.getFieldsValue()
let { sex } = data.current.getFieldsValue()
let { tel } = data.current.getFieldsValue()
api.sysUserUpdateInfo({
nickName: nickName,
birthday: birthday,
sex: sex,
tel: tel,
}).then(() => {
message.success('更新个人信息成功')
this.setState({
saving: false,
})
})
}
onAvatarStart() {}
render() {
const { info } = this.state
return (
<Container mode="xxs">
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
<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">
<Form.Item label="昵称" name="nickName">
<Input placeholder="请输入昵称"></Input>
</Form.Item>
<Form.Item label="用户名">
<span>{info.name}</span>
</Form.Item>
<Form.Item label="生日" name="birthday">
<DatePicker
onChange={this.onChange}
className="w-100-p"
placeholder="请选择生日"
/>
</Form.Item>
<Form.Item label="性别" name="sex">
<Radio.Group>
<Radio.Button value={0}>
<AntIcon className="mr-xxs" type="stop" />
<span>保密</span>
</Radio.Button>
<Radio.Button value={1}>
<AntIcon color="#1890ff" className="mr-xxs" type="man" />
<span></span>
</Radio.Button>
<Radio.Button value={2}>
<AntIcon color="#eb2f96" className="mr-xxs" type="woman" />
<span></span>
</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item label="电话" name="tel">
<Input placeholder="请输入电话" />
</Form.Item>
</div>
</Form>
</Spin>
<Button
loading={this.state.saving}
onClick={() => this.onSvaeInfo(this.form)}
block
>
更新个人信息
</Button>
</Container>
)
}
}

View File

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

View File

@@ -0,0 +1,454 @@
import React, { Component } from 'react'
import {
Form,
Input,
InputNumber,
Modal,
Spin,
Steps,
Button,
Row,
Col,
message,
Select,
} from 'antd'
import { AntIcon, Container, IconSelector } from 'components'
import { cloneDeep, indexOf } from 'lodash'
import { api } from 'common/api'
import { COUNT_DWON_KEY } from 'common/storage'
import { Option } from 'antd/lib/mentions'
import { set } from 'nprogress'
import { getKeyThenIncreaseKey } from 'antd/lib/message'
const initialValues = {
orgcode: '',
target: '',
code: '',
type: null,
}
var tempcode = ''
const { Step } = Steps
export default class form extends Component {
state = {
buttondisabled: true,
visible: false,
loading: false,
codeLoading: false,
current: 0,
countdown: 0,
sendOrNo: true,
type: [],
}
form = React.createRef()
//发送验证码
sendcode(data) {
this.setState({
codeLoading: true,
})
var reg = /^([a-zA-Z]|[0-9])(\w|)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/
let { target } = data.current.getFieldsValue()
let { type } = data.current.getFieldsValue()
let { code } = data.current.getFieldsValue()
let { orgcode } = data.current.getFieldsValue()
if (!reg.test(target) && type != '1' && type != '2') {
message.warn('请输入正确的邮箱')
this.setState({
codeLoading: true,
})
return
}
api.SendCode({
target: target,
type: type,
code: code,
orgcode: orgcode,
})
.then(res => {
if (res.success) {
this.addTime()
this.showcountdown()
}
})
.finally(() => {
this.setState({
codeLoading: false,
})
})
}
//进入下一步
next(data) {
this.setState({
loading: true,
})
let { target } = data.current.getFieldsValue()
let { type } = data.current.getFieldsValue()
let { code } = data.current.getFieldsValue()
let { orgcode } = data.current.getFieldsValue()
tempcode = data.current.getFieldsValue()
let form = {
target: target,
type: type,
code: code,
orgcode: orgcode,
}
api.CheckBindcode(form)
.then(res => {
if (res.data) {
window.localStorage.removeItem(COUNT_DWON_KEY)
let current = this.state.current + 1
this.setState({
form: {
...form,
type: null,
},
buttondisabled: true,
current: current,
})
}
})
.finally(() => {
this.setState({
loading: false,
})
})
}
/**
* 将倒计时添加入到本地
*/
addTime() {
const now = Date.now()
var date = now + 60 * 1000 + 500
window.localStorage.setItem(COUNT_DWON_KEY, date)
}
/**
* 显示倒计时
*/
showcountdown() {
let _this = this
var Furdate = window.localStorage.getItem(COUNT_DWON_KEY)
var nowdate = new Date().getTime()
if (Furdate >= nowdate) {
this.setState({
sendOrNo: false,
countdown: parseInt((Furdate - nowdate) / 1000),
})
setTimeout(() => {
_this.showcountdown()
}, 1000)
} else {
this.setState({
sendOrNo: true,
})
}
}
//打开窗口
open = (data = {}) => {
this.setState({ visible: true, loading: true })
api.getLoginUser().then(({ data }) => {
let index = []
data.phone &&
index.push({
Title: '使用手机号' + data.phone + '进行验证 ',
Value: 1,
})
data.email &&
index.push({
Title: '使用邮箱' + data.email + '进行验证',
Value: 2,
})
this.setState({
type: index,
})
if (index.length > 0) {
this.form.current.setFieldsValue({
type: index[0].Value,
})
}
this.setState({ loading: false })
})
}
// 前一步
prev() {
window.localStorage.removeItem(COUNT_DWON_KEY)
let current = this.state.current - 1
this.setState({
current: current,
})
}
//完成
complete(data) {
let { target } = data.current.getFieldsValue()
let { code } = data.current.getFieldsValue()
let { orgcode } = tempcode
api.CheckBindcode({
target: target,
type: null,
code: code,
orgcode: orgcode,
}).then(res => {
if (res.data) {
window.localStorage.removeItem(COUNT_DWON_KEY)
message.success('改绑完成')
this.onResetFields()
}
})
}
onResetFields() {
setTimeout(() => {
this.setState({ visible: false })
this.setState({ current: 0 })
//window.localStorage.removeItem(COUNT_DWON_KEY)
/** 在这里可以初始化当前组件中其他属性 */
/* ... */
}, 300)
}
render() {
let steps = [
{
title: '验证',
},
{
title: '绑定',
},
]
const close = () => {
this.setState({
visible: false,
current: 0,
})
}
return (
<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">
<br />
<Row>
<Col flex="1" />
<Col flex="3">
<Steps current={this.state.current}>
{steps.map(item => (
<Steps.Step
key={item.title}
title={item.title}
/>
))}
</Steps>
</Col>
<Col flex="1" />
</Row>
<br />
<Form
ref={this.form}
initialValues={initialValues}
onValuesChange={(changedValues, allValues) => {
this.setState({
buttondisabled: !(
allValues.orgcode ||
(allValues.target && allValues.code)
),
})
}}
>
<div>
{this.state.current == 0 && (
<div>
<Form.Item label="选择验证方式" name="type">
<Select placeholder="请选择验证方式">
{this.state.type.map(item => (
<Select.Option
key={item.Title}
value={item.Value}
>
{item.Title}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label="验证码" name="orgcode">
<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>
)}
{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 && (
<>
{this.state.current > 0 && (
<Button onClick={() => this.prev()}>
前一步
</Button>
)}
<Button
disabled={this.state.buttondisabled}
onClick={() => this.complete(this.form)}
type="primary"
>
完成
</Button>
</>
)}
</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" />
}
/>
发送验证码
</Button>
) : (
<Button disabled>
{this.state.countdown}秒后重新发送
</Button>
)}
</Col>
</Row>
</Form.Item>
</Form>
<br />
<Row>
<Col flex="1" />
<Col flex="1" align="middle">
<Button
disabled={this.state.buttondisabled}
onClick={() => this.complete(this.form)}
type="primary"
>
绑定
</Button>
</Col>
<Col flex="1" />
</Row>
<br />
</div>
)}
</div>
</Spin>
</Modal>
</Container>
)
}
}

View File

@@ -0,0 +1,107 @@
import React, { Component } from 'react'
import { Form, Input, InputNumber, Spin } from 'antd'
import { AntIcon, IconSelector } from 'components'
import { cloneDeep } from 'lodash'
const initialValues = {
sort: 100,
}
export default class form extends Component {
state = {
// 加载状态
loading: true,
exist: false,
}
// 表单实例
form = React.createRef()
// 初始化数据
record = {}
/**
* mount后回调
*/
componentDidMount() {
this.props.created && this.props.created(this)
}
/**
* 填充数据
* 可以在设置this.record之后对其作出数据结构调整
* [异步,必要]
* @param {*} params
*/
async fillData(params) {
this.record = cloneDeep(params.record)
//#region 从后端转换成前段所需格式
const exist = !!params.record
this.setState({
exist,
})
this.record = {
...this.record,
}
//#endregion
this.form.current.setFieldsValue(this.record)
this.setState({
loading: false,
})
}
/**
* 获取数据
* 可以对postData进行数据结构调整
* [异步,必要]
* @returns
*/
async getData() {
const form = this.form.current
const valid = await form.validateFields()
if (valid) {
const postData = form.getFieldsValue()
if (this.record) {
postData.id = this.record.id
}
//#region 从前段转换后端所需格式
//#endregion
return postData
}
}
render() {
return (
<Form className="yo-form" ref={this.form}>
<Spin spinning={this.state.loading}>
{/* <AntIcon slot="indicator" spin type="loading" /> */}
<div className="yo-form-group">
<Form.Item
label="旧密码"
rules={[{ required: true, message: '请输入旧密码' }]}
name="password"
>
<Input placeholder="请输入旧密码" />
</Form.Item>
<Form.Item
label="新密码"
rules={[{ required: true, message: '请输入新密码' }]}
name="newPassword"
>
<Input placeholder="请输入新密码" />
</Form.Item>
<Form.Item
label="确认新密码"
rules={[{ required: true, message: '确认新密码' }]}
name="confirm"
>
<Input placeholder="请确认新密码" />
</Form.Item>
</div>
</Spin>
</Form>
)
}
}

View File

@@ -0,0 +1,455 @@
import React, { Component } from 'react'
import {
Form,
Input,
InputNumber,
Modal,
Spin,
Steps,
Button,
Row,
Col,
message,
Select,
} from 'antd'
import { AntIcon, Container, IconSelector } from 'components'
import { cloneDeep, indexOf } from 'lodash'
import { api } from 'common/api'
import { COUNT_DWON_KEY } from 'common/storage'
import { Option } from 'antd/lib/mentions'
import { set } from 'nprogress'
import { getKeyThenIncreaseKey } from 'antd/lib/message'
const initialValues = {
orgcode: '',
target: '',
code: '',
type: null,
}
var tempcode = ''
const { Step } = Steps
export default class form extends Component {
state = {
buttondisabled: true,
visible: false,
loading: false,
codeLoading: false,
current: 0,
countdown: 0,
sendOrNo: true,
type: [],
}
form = React.createRef()
//发送验证码
sendcode(data) {
this.setState({
codeLoading: true,
})
var reg =
/^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$/
let { target } = data.current.getFieldsValue()
let { type } = data.current.getFieldsValue()
let { code } = data.current.getFieldsValue()
let { orgcode } = data.current.getFieldsValue()
if (!reg.test(target) && type != '1' && type != '2') {
message.warn('请输入正确的手机号码')
this.setState({
codeLoading: true,
})
return
}
api.SendCode({
target: target,
type: type,
code: code,
orgcode: orgcode,
})
.then(res => {
if (res.success) {
this.addTime()
this.showcountdown()
}
})
.finally(() => {
this.setState({
codeLoading: false,
})
})
}
//进入下一步
next(data) {
this.setState({
loading: true,
})
let { target } = data.current.getFieldsValue()
let { type } = data.current.getFieldsValue()
let { code } = data.current.getFieldsValue()
let { orgcode } = data.current.getFieldsValue()
tempcode = data.current.getFieldsValue()
let form = {
target: target,
type: type,
code: code,
orgcode: orgcode,
}
api.CheckBindcode(form)
.then(res => {
if (res.data) {
window.localStorage.removeItem(COUNT_DWON_KEY)
let current = this.state.current + 1
this.setState({
form: {
...form,
type: null,
},
buttondisabled: true,
current: current,
})
}
})
.finally(() => {
this.setState({
loading: false,
})
})
}
/**
* 将倒计时添加入到本地
*/
addTime() {
const now = Date.now()
var date = now + 60 * 1000 + 500
window.localStorage.setItem(COUNT_DWON_KEY, date)
}
/**
* 显示倒计时
*/
showcountdown() {
let _this = this
var Furdate = window.localStorage.getItem(COUNT_DWON_KEY)
var nowdate = new Date().getTime()
if (Furdate >= nowdate) {
this.setState({
sendOrNo: false,
countdown: parseInt((Furdate - nowdate) / 1000),
})
setTimeout(() => {
_this.showcountdown()
}, 1000)
} else {
this.setState({
sendOrNo: true,
})
}
}
//打开窗口
open = (data = {}) => {
this.setState({ visible: true, loading: true })
api.getLoginUser().then(({ data }) => {
let index = []
data.phone &&
index.push({
Title: '使用手机号' + data.phone + '进行验证 ',
Value: 1,
})
data.email &&
index.push({
Title: '使用邮箱' + data.email + '进行验证',
Value: 2,
})
this.setState({
type: index,
})
if (index.length > 0) {
this.form.current.setFieldsValue({
type: index[0].Value,
})
}
this.setState({ loading: false })
})
}
// 前一步
prev() {
window.localStorage.removeItem(COUNT_DWON_KEY)
let current = this.state.current - 1
this.setState({
current: current,
})
}
//完成
complete(data) {
let { target } = data.current.getFieldsValue()
let { code } = data.current.getFieldsValue()
let { orgcode } = tempcode
api.CheckBindcode({
target: target,
type: null,
code: code,
orgcode: orgcode,
}).then(res => {
if (res.data) {
window.localStorage.removeItem(COUNT_DWON_KEY)
message.success('改绑完成')
this.onResetFields()
}
})
}
onResetFields() {
setTimeout(() => {
this.setState({ visible: false })
this.setState({ current: 0 })
//window.localStorage.removeItem(COUNT_DWON_KEY)
/** 在这里可以初始化当前组件中其他属性 */
/* ... */
}, 300)
}
render() {
let steps = [
{
title: '验证',
},
{
title: '绑定',
},
]
const close = () => {
this.setState({
visible: false,
current: 0,
})
}
return (
<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">
<br />
<Row>
<Col flex="1" />
<Col flex="3">
<Steps current={this.state.current}>
{steps.map(item => (
<Steps.Step
key={item.title}
title={item.title}
/>
))}
</Steps>
</Col>
<Col flex="1" />
</Row>
<br />
<Form
ref={this.form}
initialValues={initialValues}
onValuesChange={(changedValues, allValues) => {
this.setState({
buttondisabled: !(
allValues.orgcode ||
(allValues.target && allValues.code)
),
})
}}
>
<div>
{this.state.current == 0 && (
<div>
<Form.Item label="选择验证方式" name="type">
<Select placeholder="请选择验证方式">
{this.state.type.map(item => (
<Select.Option
key={item.Title}
value={item.Value}
>
{item.Title}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label="验证码" name="orgcode">
<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>
)}
{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 && (
<>
{this.state.current > 0 && (
<Button onClick={() => this.prev()}>
前一步
</Button>
)}
<Button
disabled={this.state.buttondisabled}
onClick={() => this.complete(this.form)}
type="primary"
>
完成
</Button>
</>
)}
</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" />
}
/>
发送验证码
</Button>
) : (
<Button disabled>
{this.state.countdown}秒后重新发送
</Button>
)}
</Col>
</Row>
</Form.Item>
</Form>
<br />
<Row>
<Col flex="1" />
<Col flex="1" align="middle">
<Button
disabled={this.state.buttondisabled}
onClick={() => this.complete(this.form)}
type="primary"
>
绑定
</Button>
</Col>
<Col flex="1" />
</Row>
<br />
</div>
)}
</div>
</Spin>
</Modal>
</Container>
)
}
}

View File

@@ -1,7 +1,6 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { Form, Input, InputNumber, Spin } from 'antd' import { Form, Input, InputNumber, Spin } from 'antd'
import { AntIcon, IconSelector } from 'components' import { AntIcon, ColorSelector, IconSelector } from 'components'
import { cloneDeep } from 'lodash'
import { api } from 'common/api' import { api } from 'common/api'
const initialValues = { const initialValues = {
@@ -107,6 +106,9 @@ export default class form extends Component {
} }
/> />
</Form.Item> </Form.Item>
<Form.Item label="颜色" name="color">
<ColorSelector placeholder="请选择颜色" />
</Form.Item>
<Form.Item label="排序" name="sort"> <Form.Item label="排序" name="sort">
<InputNumber <InputNumber
max={1000} max={1000}

View File

@@ -38,6 +38,33 @@ export default class index extends Component {
// 表格字段 // 表格字段
columns = [ columns = [
{
title: '图标',
dataIndex: 'icon',
width: 32,
render: (text, record) => (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '32px',
height: '32px',
borderRadius: '100%',
backgroundColor: record.color,
margin: '0 auto',
}}
>
<AntIcon
type={text}
style={{
fontSize: '20px',
color: '#fff',
}}
/>
</div>
),
},
{ {
title: '应用名称', title: '应用名称',
dataIndex: 'name', dataIndex: 'name',

View File

@@ -38,4 +38,7 @@ export const RSA_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQU
*/ */
export const CITY = '黄石市' export const CITY = '黄石市'
/**
* 响应式响应宽度
*/
export const SIDER_BREAK_POINT = 1366 export const SIDER_BREAK_POINT = 1366

View File

@@ -1,3 +1,41 @@
import moment from 'moment'
/**
* 从键值对的query类型转换成数组类型
* 键:自动作为field值
* 值:得到一个数组作为value的值
* queryType:一个json类型,已query的键为键,QueryType为值. 如果是一个QueryType的数组,则自动对应到value中的各个值
* 示例:
*
getSearchInfo({
query: {
value: '123',
text: '123',
code: 'abc',
check: ['1', '2', '3'],
range: [1, 10]
},
queryType: {
text: QueryType.Equal,
code: QueryType.Like,
check: QueryType.Equal,
range: [QueryType.GreaterThanOrEqual, QueryType.LessThan]
}
})
=>
[
{ field: 'value', value: ['123'] },
{ field: 'text', value: ['123'], type: '=' },
{ field: 'code', value: ['abc'], type: 'like' },
{ field: 'check', value: ['1', '2', '3'], type: '=' },
{ field: 'range', value: [1], type: '>=' },
{ field: 'range', value: [10], type: '<' }
]
* @param {*} param0
* @returns [{ field: '', value: [], type: '' } ...]
*/
export const getSearchInfo = ({ query, queryType }) => { export const getSearchInfo = ({ query, queryType }) => {
const searchInfo = [] const searchInfo = []
Object.keys(query).forEach((p) => { Object.keys(query).forEach((p) => {
@@ -38,4 +76,32 @@ export const getSearchInfo = ({ query, queryType }) => {
}) })
return searchInfo return searchInfo
}
/**
* 获取查询用时间范围数组
* 在这里会自动将第二个时间增加1天
* 如果选择的日期范围为2021-01-01~2021-01-10,最终需要取得 >=2021-01-01 and <2021-01-11 的结果
* @param {*} range 时间范围数组
* @param {*} format 格式化
* @returns
*/
export const getSearchDateRange = (range, format = 'YYYY-MM-DD', unit = 'days') => {
if (Array.isArray(range) && range.length === 2) {
range[1] = moment(range[1]).add(1, unit)
range = range.map(p => moment(p).format(format))
}
return range
}
/**
* 查询条件类型
*/
export const QueryType = {
GreaterThan: '>',
GreaterThanOrEqual: '>=',
LessThan: '<',
LessThanOrEqual: '<=',
Like: 'LIKE',
Equal: '='
} }

View File

@@ -34,7 +34,14 @@ class User extends Component {
this.unsubscribe() this.unsubscribe()
} }
onAccountSetting = () => {} onAccountSetting = () => {
window.openContentWindow({
id: 'account-home',
title: '个人设置',
icon: '',
path: '/system/account',
})
}
onLogout = () => { onLogout = () => {
Modal.confirm({ Modal.confirm({
@@ -83,7 +90,7 @@ class User extends Component {
</div> </div>
<Menu selectable={false}> <Menu selectable={false}>
<Menu.Divider /> <Menu.Divider />
<Menu.Item key="1"> <Menu.Item key="1" onClick={() => this.onAccountSetting()}>
<AntIcon type="user" className="mr-sm" /> <AntIcon type="user" className="mr-sm" />
个人中心 个人中心
</Menu.Item> </Menu.Item>

View File

@@ -1315,6 +1315,11 @@
dependencies: dependencies:
"@hapi/hoek" "^8.3.0" "@hapi/hoek" "^8.3.0"
"@icons/material@^0.2.4":
version "0.2.4"
resolved "https://registry.nlark.com/@icons/material/download/@icons/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
integrity sha1-6QyfcXaLNzbnbX3WeD/Gwq+oi8g=
"@istanbuljs/load-nyc-config@^1.0.0": "@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0" version "1.1.0"
resolved "https://registry.nlark.com/@istanbuljs/load-nyc-config/download/@istanbuljs/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" resolved "https://registry.nlark.com/@istanbuljs/load-nyc-config/download/@istanbuljs/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@@ -7172,6 +7177,11 @@ locate-path@^5.0.0:
dependencies: dependencies:
p-locate "^4.1.0" p-locate "^4.1.0"
lodash-es@^4.17.15:
version "4.17.21"
resolved "https://registry.npm.taobao.org/lodash-es/download/lodash-es-4.17.21.tgz?cache=0&sync_timestamp=1613836185353&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash-es%2Fdownload%2Flodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha1-Q+YmxG5lkbd1C+srUBFzkMYJ4+4=
lodash._reinterpolate@^3.0.0: lodash._reinterpolate@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.nlark.com/lodash._reinterpolate/download/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" resolved "https://registry.nlark.com/lodash._reinterpolate/download/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
@@ -7232,7 +7242,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" resolved "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0: "lodash@>=3.5 <5", lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0:
version "4.17.21" version "4.17.21"
resolved "https://registry.nlark.com/lodash/download/lodash-4.17.21.tgz?cache=0&sync_timestamp=1618847150612&other_urls=https%3A%2F%2Fregistry.nlark.com%2Flodash%2Fdownload%2Flodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.nlark.com/lodash/download/lodash-4.17.21.tgz?cache=0&sync_timestamp=1618847150612&other_urls=https%3A%2F%2Fregistry.nlark.com%2Flodash%2Fdownload%2Flodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw= integrity sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=
@@ -7316,6 +7326,11 @@ map-visit@^1.0.0:
dependencies: dependencies:
object-visit "^1.0.0" object-visit "^1.0.0"
material-colors@^1.2.1:
version "1.2.6"
resolved "https://registry.npm.taobao.org/material-colors/download/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46"
integrity sha1-bRlYhxEmmSzuzHL0vMTY8BCGX0Y=
md5.js@^1.3.4: md5.js@^1.3.4:
version "1.3.5" version "1.3.5"
resolved "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" resolved "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@@ -9130,7 +9145,7 @@ prompts@^2.0.1:
kleur "^3.0.3" kleur "^3.0.3"
sisteransi "^1.0.5" sisteransi "^1.0.5"
prop-types@^15.6.2, prop-types@^15.7.2: prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2" version "15.7.2"
resolved "https://registry.npm.taobao.org/prop-types/download/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" resolved "https://registry.npm.taobao.org/prop-types/download/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha1-UsQedbjIfnK52TYOAga5ncv/psU= integrity sha1-UsQedbjIfnK52TYOAga5ncv/psU=
@@ -9658,6 +9673,19 @@ react-base16-styling@^0.6.0:
lodash.flow "^3.3.0" lodash.flow "^3.3.0"
pure-color "^1.2.0" pure-color "^1.2.0"
react-color@^2.19.3:
version "2.19.3"
resolved "https://registry.npm.taobao.org/react-color/download/react-color-2.19.3.tgz#ec6c6b4568312a3c6a18420ab0472e146aa5683d"
integrity sha1-7GxrRWgxKjxqGEIKsEcuFGqlaD0=
dependencies:
"@icons/material" "^0.2.4"
lodash "^4.17.15"
lodash-es "^4.17.15"
material-colors "^1.2.1"
prop-types "^15.5.10"
reactcss "^1.2.0"
tinycolor2 "^1.4.1"
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"
@@ -9852,6 +9880,13 @@ react@^17.0.2:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
reactcss@^1.2.0:
version "1.2.3"
resolved "https://registry.npm.taobao.org/reactcss/download/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd"
integrity sha1-wAATh15Vexzw39mjaKHD2rO1SN0=
dependencies:
lodash "^4.0.1"
read-pkg-up@^3.0.0: read-pkg-up@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.nlark.com/read-pkg-up/download/read-pkg-up-3.0.0.tgz?cache=0&sync_timestamp=1618846971516&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" resolved "https://registry.nlark.com/read-pkg-up/download/read-pkg-up-3.0.0.tgz?cache=0&sync_timestamp=1618846971516&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07"
@@ -11248,6 +11283,11 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3:
resolved "https://registry.npm.taobao.org/tiny-warning/download/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" resolved "https://registry.npm.taobao.org/tiny-warning/download/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha1-lKMNtFPfTGQ9D9VmBg1gqHXYR1Q= integrity sha1-lKMNtFPfTGQ9D9VmBg1gqHXYR1Q=
tinycolor2@^1.4.1:
version "1.4.2"
resolved "https://registry.nlark.com/tinycolor2/download/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
integrity sha1-P2pNEHGtB2dtf6Ry4frECnGdiAM=
tmpl@1.0.x: tmpl@1.0.x:
version "1.0.4" version "1.0.4"
resolved "https://registry.npm.taobao.org/tmpl/download/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" resolved "https://registry.npm.taobao.org/tmpl/download/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"