merge
This commit is contained in:
@@ -1456,5 +1456,20 @@
|
|||||||
上报备注
|
上报备注
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Ewide.Application.AddHouseZoneInput.Pid">
|
||||||
|
<summary>
|
||||||
|
所属街道
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:Ewide.Application.AddHouseZoneInput.Name">
|
||||||
|
<summary>
|
||||||
|
名称
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:Ewide.Application.UpdateHouseZoneInput.Id">
|
||||||
|
<summary>
|
||||||
|
机构Id
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
|||||||
@@ -56,4 +56,10 @@ namespace Ewide.Application
|
|||||||
public string ZoonId { get; set; }
|
public string ZoonId { get; set; }
|
||||||
public int Type { get; set; }
|
public int Type { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GetHouseCodeInput
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "房屋编码ID不可为空")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,18 @@ namespace Ewide.Application
|
|||||||
public string Lng { get; set; }
|
public string Lng { get; set; }
|
||||||
public string Lat { get; set; }
|
public string Lat { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GetHouseCodeOutput
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public int Type { get; set; }
|
||||||
|
public int Industry { get; set; }
|
||||||
|
public string AreaCode { get; set; }
|
||||||
|
public string ProjectId { get; set; }
|
||||||
|
public int No { get; set; }
|
||||||
|
public string ZoneId { get; set; }
|
||||||
|
public string Address { get; set; }
|
||||||
|
public string Lng { get; set; }
|
||||||
|
public string Lat { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,16 @@ LEFT JOIN sys_area_code AA ON AA.AdCode = SUBSTR(CA.AdCode,1,6) ";
|
|||||||
return await _dapperRepository.QueryPageDataDynamic(sql, input, filterFields: new string[] {"Type", "Address", "HouseCode" });
|
return await _dapperRepository.QueryPageDataDynamic(sql, input, filterFields: new string[] {"Type", "Address", "HouseCode" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("/houseCode/detail")]
|
||||||
|
public async Task<dynamic> GetHouserCode([FromQuery] GetHouseCodeInput input)
|
||||||
|
{
|
||||||
|
var houseCode = await _houseCodeRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == input.Id);
|
||||||
|
var areaCode = (await Db.GetRepository<BsHouseProjectInfo>().DetachedEntities.FirstOrDefaultAsync(p => p.Id == houseCode.ProjectId)).AreaCode;
|
||||||
|
var result = houseCode.Adapt<GetHouseCodeOutput>();
|
||||||
|
result.AreaCode = areaCode;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取同一区域下的下一个编号
|
/// 获取同一区域下的下一个编号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ INNER JOIN (SELECT * FROM bs_house_member_relation WHERE SysUserId = @UserId) HM
|
|||||||
HouseCodeId = p
|
HouseCodeId = p
|
||||||
}.Insert();
|
}.Insert();
|
||||||
|
|
||||||
var initTask = _bsHouseTaskRep.DetachedEntities.FirstOrDefault(t => t.TaskType == 0);
|
var initTask = _bsHouseTaskRep.DetachedEntities.FirstOrDefault(t =>t.HouseCodeId == p && t.TaskType == 0);
|
||||||
if (initTask == null)
|
if (initTask == null)
|
||||||
{
|
{
|
||||||
new BsHouseTask
|
new BsHouseTask
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Ewide.Core.Service;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -13,4 +14,28 @@ namespace Ewide.Application
|
|||||||
[MinLength(9, ErrorMessage = "区域编码长度必须为9位及以上")]
|
[MinLength(9, ErrorMessage = "区域编码长度必须为9位及以上")]
|
||||||
public string AreaCode { get; set; }
|
public string AreaCode { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AddHouseZoneInput : OrgInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 所属街道
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "所属街道不能为空")]
|
||||||
|
public override string Pid { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 名称
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "片区名称不能为空")]
|
||||||
|
public override string Name { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UpdateHouseZoneInput : AddHouseZoneInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 机构Id
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "片区Id不能为空")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
using Ewide.Core.Extension;
|
using Ewide.Core.Extension;
|
||||||
using Ewide.Core.Service;
|
using Ewide.Core.Service;
|
||||||
using Furion.DatabaseAccessor;
|
using Furion.DatabaseAccessor;
|
||||||
|
using Furion.DatabaseAccessor.Extensions;
|
||||||
using Furion.DependencyInjection;
|
using Furion.DependencyInjection;
|
||||||
using Furion.DynamicApiController;
|
using Furion.DynamicApiController;
|
||||||
using Furion.FriendlyException;
|
using Furion.FriendlyException;
|
||||||
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
@@ -104,9 +106,9 @@ namespace Ewide.Application.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("/houseZone/autoIncrement")]
|
[HttpGet("/houseZone/autoIncrement")]
|
||||||
public async Task<dynamic> AutoIncrement([FromQuery] string code)
|
public async Task<dynamic> AutoIncrement([FromQuery] string roadId)
|
||||||
{
|
{
|
||||||
var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.AreaCode == code);
|
var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == roadId && p.Type == 3);
|
||||||
if (road == null) throw Oops.Oh("组织机构错误");
|
if (road == null) throw Oops.Oh("组织机构错误");
|
||||||
return await AutoIncrement(road);
|
return await AutoIncrement(road);
|
||||||
}
|
}
|
||||||
@@ -119,7 +121,7 @@ namespace Ewide.Application.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("/houseZone/add")]
|
[HttpPost("/houseZone/add")]
|
||||||
public async Task AddZone(AddOrgInput input)
|
public async Task AddZone(AddHouseZoneInput input)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* 区县市限定所属区域/上级机构是否为当前区
|
* 区县市限定所属区域/上级机构是否为当前区
|
||||||
@@ -136,15 +138,14 @@ namespace Ewide.Application.Service
|
|||||||
var roles = await _userManager.GetUserRoleList();
|
var roles = await _userManager.GetUserRoleList();
|
||||||
if (roles.Any(p => p.Code == areaManager))
|
if (roles.Any(p => p.Code == areaManager))
|
||||||
{
|
{
|
||||||
var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.AreaCode == input.AreaCode);
|
var road = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(p => p.Id == input.Pid);
|
||||||
if (!road.Pids.Contains(org.Id)) throw Oops.Oh("组织机构错误");
|
if (!road.Pids.Contains(org.Id)) throw Oops.Oh("当前用户组织机构错误");
|
||||||
|
|
||||||
input.Pid = road.Id;
|
input.AreaCode = road.AreaCode;
|
||||||
input.Code = road.Code + (await AutoIncrement(road)).ToString().PadLeft(3, '0');
|
input.Code = road.Code + (await AutoIncrement(road)).ToString().PadLeft(3, '0');
|
||||||
}
|
}
|
||||||
else if (roles.Any(p => p.Code == roadManager))
|
else if (roles.Any(p => p.Code == roadManager))
|
||||||
{
|
{
|
||||||
input.Pid = org.Id;
|
|
||||||
input.AreaCode = org.AreaCode;
|
input.AreaCode = org.AreaCode;
|
||||||
|
|
||||||
input.Code = org.Code + (await AutoIncrement(org)).ToString().PadLeft(3, '0');
|
input.Code = org.Code + (await AutoIncrement(org)).ToString().PadLeft(3, '0');
|
||||||
@@ -152,7 +153,17 @@ namespace Ewide.Application.Service
|
|||||||
|
|
||||||
input.Type = (int)OrgType.片区;
|
input.Type = (int)OrgType.片区;
|
||||||
|
|
||||||
await _sysOrgService.AddOrg(input);
|
AddOrgInput addOrgInput = input.Adapt<AddOrgInput>();
|
||||||
|
await _sysOrgService.AddOrg(addOrgInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("/houseZone/edit")]
|
||||||
|
public async Task EditZone(UpdateHouseZoneInput input)
|
||||||
|
{
|
||||||
|
var zone = await _sysOrgRep.DetachedEntities.FirstOrDefaultAsync(z => z.Id == input.Id);
|
||||||
|
if(zone == null) throw Oops.Oh("修改失败:数据有误,刷新列表后再尝试修改");
|
||||||
|
zone.Remark = input.Remark;
|
||||||
|
await zone.UpdateIncludeAsync(new[] { nameof(SysOrg.Remark) }, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,6 @@
|
|||||||
/// 文件Id
|
/// 文件Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
public System.DateTime CreatedTime { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Furion;
|
using Ewide.Core.Extension;
|
||||||
|
using Furion;
|
||||||
using Furion.DatabaseAccessor;
|
using Furion.DatabaseAccessor;
|
||||||
using Furion.DatabaseAccessor.Extensions;
|
using Furion.DatabaseAccessor.Extensions;
|
||||||
using Furion.DependencyInjection;
|
using Furion.DependencyInjection;
|
||||||
@@ -50,8 +51,7 @@ namespace Ewide.Core.Service
|
|||||||
.Where(input.FileLocation > 0, u => u.FileLocation == input.FileLocation)
|
.Where(input.FileLocation > 0, u => u.FileLocation == input.FileLocation)
|
||||||
.Where(fileBucket, u => EF.Functions.Like(u.FileBucket, $"%{input.FileBucket.Trim()}%"))
|
.Where(fileBucket, u => EF.Functions.Like(u.FileBucket, $"%{input.FileBucket.Trim()}%"))
|
||||||
.Where(fileOriginName, u => EF.Functions.Like(u.FileOriginName, $"%{input.FileOriginName.Trim()}%"))
|
.Where(fileOriginName, u => EF.Functions.Like(u.FileOriginName, $"%{input.FileOriginName.Trim()}%"))
|
||||||
.Select(u => u.Adapt<FileOutput>())
|
.ToPageData<SysFile, FileOutput>(input);
|
||||||
.ToPagedListAsync(input.PageIndex, input.PageSize);
|
|
||||||
return PageDataResult<FileOutput>.PageResult(files);
|
return PageDataResult<FileOutput>.PageResult(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Ewide.Core.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 父Id
|
/// 父Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Pid { get; set; }
|
public virtual string Pid { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 父Ids
|
/// 父Ids
|
||||||
|
|||||||
@@ -93,6 +93,7 @@
|
|||||||
"sysDictType:dropDowns",
|
"sysDictType:dropDowns",
|
||||||
"sysFileInfo:upload",
|
"sysFileInfo:upload",
|
||||||
"sysFileInfo:download",
|
"sysFileInfo:download",
|
||||||
|
"sysFileInfo:detail",
|
||||||
"sysFileInfo:preview",
|
"sysFileInfo:preview",
|
||||||
"sysUser:updateInfo",
|
"sysUser:updateInfo",
|
||||||
"sysUser:updatePwd",
|
"sysUser:updatePwd",
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ export default {
|
|||||||
if (record) {
|
if (record) {
|
||||||
const fileList = !!record.houseInfo.facadePhoto ? record.houseInfo.facadePhoto.split(',') : [];
|
const fileList = !!record.houseInfo.facadePhoto ? record.houseInfo.facadePhoto.split(',') : [];
|
||||||
for (let i = 0; i < fileList.length; i++) {
|
for (let i = 0; i < fileList.length; i++) {
|
||||||
|
try {
|
||||||
const file = await PreviewFile(fileList[i]);
|
const file = await PreviewFile(fileList[i]);
|
||||||
const base64 = await BlobToBase64(file);
|
const base64 = await BlobToBase64(file);
|
||||||
facadePhoto.push({
|
facadePhoto.push({
|
||||||
@@ -113,6 +114,15 @@ export default {
|
|||||||
url: base64,
|
url: base64,
|
||||||
status: 'done',
|
status: 'done',
|
||||||
});
|
});
|
||||||
|
} catch {
|
||||||
|
const { data: file } = await this.$api.sysFileInfoDetail({ id: fileList[i] });
|
||||||
|
facadePhoto.push({
|
||||||
|
uid: fileList[i],
|
||||||
|
response: '文件已丢失',
|
||||||
|
name: file.fileOriginName,
|
||||||
|
status: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaultForm.houseInfo.facadePhoto = facadePhoto;
|
defaultForm.houseInfo.facadePhoto = facadePhoto;
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ export default {
|
|||||||
const fileList =
|
const fileList =
|
||||||
!form.houseInfo[key] || form.houseInfo[key].length == 0 ? [] : form.houseInfo[key].split(',');
|
!form.houseInfo[key] || form.houseInfo[key].length == 0 ? [] : form.houseInfo[key].split(',');
|
||||||
for (let i = 0; i < fileList.length; i++) {
|
for (let i = 0; i < fileList.length; i++) {
|
||||||
|
try {
|
||||||
const file = await PreviewFile(fileList[i]);
|
const file = await PreviewFile(fileList[i]);
|
||||||
const base64 = await BlobToBase64(file);
|
const base64 = await BlobToBase64(file);
|
||||||
fileValue.push({
|
fileValue.push({
|
||||||
@@ -182,6 +183,15 @@ export default {
|
|||||||
url: base64,
|
url: base64,
|
||||||
status: 'done',
|
status: 'done',
|
||||||
});
|
});
|
||||||
|
} catch {
|
||||||
|
const { data: file } = await this.$api.sysFileInfoDetail({ id: fileList[i] });
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileList[i],
|
||||||
|
response: '文件已丢失',
|
||||||
|
name: file.fileOriginName,
|
||||||
|
status: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
form.houseInfo[key] = fileValue;
|
form.houseInfo[key] = fileValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
webpack: {
|
webpack: {
|
||||||
plugins: [
|
plugins: [
|
||||||
// new MonacoWebpackPlugin()
|
new MonacoWebpackPlugin()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
153
web-react/public/seed/form-tabs/index.jsx
Normal file
153
web-react/public/seed/form-tabs/index.jsx
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Button, Tabs } from 'antd'
|
||||||
|
import { ComponentDynamic, Container } from 'components'
|
||||||
|
import { isEqual, merge } from 'lodash'
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
{
|
||||||
|
title: '标题',
|
||||||
|
component: () => import('./tab'),
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default class index extends Component {
|
||||||
|
state = {
|
||||||
|
actived: '0',
|
||||||
|
loading: true,
|
||||||
|
record: null,
|
||||||
|
saveDisabled: true,
|
||||||
|
saving: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 子表单实例集合
|
||||||
|
children = []
|
||||||
|
|
||||||
|
// 整合提交数据
|
||||||
|
formData = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,可在此获取详细数据赋值到record
|
||||||
|
*/
|
||||||
|
componentDidMount() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收到所有子组件已加载完成,并启用提交按钮
|
||||||
|
*/
|
||||||
|
call(child, index) {
|
||||||
|
this.children[index] = child
|
||||||
|
if (this.children.filter(p => p).length === tabs.filter(p => p.show).length) {
|
||||||
|
this.setState({ saveDisabled: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onSubmit() {
|
||||||
|
for (const child of this.children) {
|
||||||
|
try {
|
||||||
|
const data = await child.getData()
|
||||||
|
merge(this.formData, data)
|
||||||
|
} catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 提交数据
|
||||||
|
this.setState({ saving: true })
|
||||||
|
this.setState({ saving: false })
|
||||||
|
//#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { id } = this.props
|
||||||
|
|
||||||
|
const { actived, loading, record, saveDisabled, saving } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="yo-form-page">
|
||||||
|
<div className="yo-form-page-layout">
|
||||||
|
{/* 底部工具栏(需放在前面) */}
|
||||||
|
<div className="yo-form-page--bar yo-form-page--bar--with-tab">
|
||||||
|
<Container mode="fluid">
|
||||||
|
<div className="yo-form-page--bar-inner">
|
||||||
|
<span></span>
|
||||||
|
<span>
|
||||||
|
<Button onClick={() => window.closeContentWindow()}>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
disabled={saveDisabled}
|
||||||
|
loading={saving}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => this.onSubmit()}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
{/* 顶部信息栏,不需要时刻删除 */}
|
||||||
|
<div className="yo-form-page--header" style={{ paddingBottom: 0 }}></div>
|
||||||
|
<div className="yo-tab-external-mount">
|
||||||
|
<Tabs
|
||||||
|
activeKey={actived}
|
||||||
|
animated={false}
|
||||||
|
onChange={activeKey => {
|
||||||
|
this.setState({ actived: activeKey })
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tabs.map(
|
||||||
|
(tab, i) =>
|
||||||
|
tab.show && (
|
||||||
|
<Tabs.TabPane
|
||||||
|
key={i}
|
||||||
|
forceRender={false}
|
||||||
|
tab={tab.title}
|
||||||
|
></Tabs.TabPane>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Tabs>
|
||||||
|
<div className="yo-tab-external-mount-content">
|
||||||
|
{tabs.map((tab, i) => {
|
||||||
|
if (tab.show) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className={[
|
||||||
|
actived == i
|
||||||
|
? 'yo-tab-external-tabpane-active'
|
||||||
|
: 'yo-tab-external-tabpane-inactive',
|
||||||
|
'yo-tab-external-tabpane',
|
||||||
|
].join(' ')}
|
||||||
|
>
|
||||||
|
<ComponentDynamic
|
||||||
|
is={tab.component}
|
||||||
|
id={id}
|
||||||
|
record={record}
|
||||||
|
loading={loading}
|
||||||
|
onRef={child => this.call(child, i)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return <></>
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
126
web-react/public/seed/form-tabs/tab/index.jsx
Normal file
126
web-react/public/seed/form-tabs/tab/index.jsx
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import { Anchor, Card, Col, Divider, Row, Spin } from 'antd'
|
||||||
|
import { AntIcon, ComponentDynamic, Container } from 'components'
|
||||||
|
import { isEqual, merge } from 'lodash'
|
||||||
|
|
||||||
|
const parts = [
|
||||||
|
{
|
||||||
|
// title: '标题',
|
||||||
|
component: () => import('./part'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default class index extends Component {
|
||||||
|
// 子表单实例集合
|
||||||
|
children = []
|
||||||
|
|
||||||
|
// 整合提交数据
|
||||||
|
formData = {}
|
||||||
|
|
||||||
|
// 锚点挂载DOM
|
||||||
|
container = window
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state) || this.props.loading !== props.loading
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call(child, index) {
|
||||||
|
this.children[index] = child
|
||||||
|
if (this.children.filter(p => p).length === parts.length) {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从下级组件获取表单数据,并传递给更上级组件
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
for (const child of this.children) {
|
||||||
|
const data = await child.getData()
|
||||||
|
merge(this.formData, data)
|
||||||
|
}
|
||||||
|
return this.formData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置锚点容器
|
||||||
|
* [非必要]
|
||||||
|
* @param {*} container
|
||||||
|
*/
|
||||||
|
setContainer = container => {
|
||||||
|
this.container = (ReactDOM.findDOMNode(container) || {}).parentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染
|
||||||
|
* 当前渲染结构已完善,非必要可以不用修改
|
||||||
|
* [必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { id, loading } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container mode="fluid" ref={this.setContainer}>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col flex="1">
|
||||||
|
<br />
|
||||||
|
<div className="yo-adorn--house-top" />
|
||||||
|
<Card className="yo-form-page--body">
|
||||||
|
{parts.map((item, i) => (
|
||||||
|
<React.Fragment key={i}>
|
||||||
|
<section id={`form-${i}-${id}`}>
|
||||||
|
{item.title && <h5>{item.title}</h5>}
|
||||||
|
<Spin
|
||||||
|
spinning={loading}
|
||||||
|
indicator={<AntIcon type="loading" />}
|
||||||
|
wrapperClassName={loading && 'h-400-min'}
|
||||||
|
>
|
||||||
|
{!loading && (
|
||||||
|
<ComponentDynamic
|
||||||
|
is={item.component}
|
||||||
|
{...this.props}
|
||||||
|
onRef={child => this.call(child, i)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Spin>
|
||||||
|
</section>
|
||||||
|
{i < parts.length - 1 && <Divider />}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
{/* 锚点,如果不需要可以删除以下节点 */}
|
||||||
|
<Col flex="240px">
|
||||||
|
<Anchor
|
||||||
|
getContainer={() => this.container}
|
||||||
|
offsetTop={24}
|
||||||
|
targetOffset={100}
|
||||||
|
wrapperStyle={{ backgroundColor: 'transparent' }}
|
||||||
|
onClick={e => e.preventDefault()}
|
||||||
|
>
|
||||||
|
{parts.map((part, i) => (
|
||||||
|
<Anchor.Link key={i} href={`#form-${i}-${id}`} title={part.title} />
|
||||||
|
))}
|
||||||
|
</Anchor>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
115
web-react/public/seed/form-tabs/tab/part.jsx
Normal file
115
web-react/public/seed/form-tabs/tab/part.jsx
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Form, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class part extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
//#endregion
|
||||||
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
></Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
169
web-react/public/seed/form/index.jsx
Normal file
169
web-react/public/seed/form/index.jsx
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import { Anchor, Button, Card, Col, Divider, Row, Spin } from 'antd'
|
||||||
|
import { AntIcon, ComponentDynamic, Container } from 'components'
|
||||||
|
import { isEqual, merge } from 'lodash'
|
||||||
|
|
||||||
|
const parts = [
|
||||||
|
{
|
||||||
|
// title: '标题',
|
||||||
|
component: () => import('./part'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default class index extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
record: null,
|
||||||
|
saveDisabled: true,
|
||||||
|
saving: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 子表单实例集合
|
||||||
|
children = []
|
||||||
|
|
||||||
|
// 整合提交数据
|
||||||
|
formData = {}
|
||||||
|
|
||||||
|
// 锚点挂载DOM
|
||||||
|
container = window
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,可在此获取详细数据赋值到record
|
||||||
|
*/
|
||||||
|
componentDidMount() {}
|
||||||
|
|
||||||
|
call(child, index) {
|
||||||
|
this.children[index] = child
|
||||||
|
if (this.children.filter(p => p).length === tabs.filter(p => p.show).length) {
|
||||||
|
this.setState({ saveDisabled: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async onSubmit() {
|
||||||
|
for (const child of this.children) {
|
||||||
|
try {
|
||||||
|
const data = await child.getData()
|
||||||
|
merge(this.formData, data)
|
||||||
|
} catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 提交数据
|
||||||
|
this.setState({ saving: true })
|
||||||
|
this.setState({ saving: false })
|
||||||
|
//#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置锚点容器
|
||||||
|
* [非必要]
|
||||||
|
* @param {*} container
|
||||||
|
*/
|
||||||
|
setContainer = container => {
|
||||||
|
this.container = (ReactDOM.findDOMNode(container) || {}).parentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染
|
||||||
|
* 当前渲染结构已完善,非必要可以不用修改
|
||||||
|
* [必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { id } = this.props
|
||||||
|
|
||||||
|
const { loading, record, saveDisabled, saving } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="yo-form-page">
|
||||||
|
<Container mode="fluid" ref={this.setContainer}>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col flex="1">
|
||||||
|
<br />
|
||||||
|
<div className="yo-adorn--house-top" />
|
||||||
|
<Card className="yo-form-page--body">
|
||||||
|
{parts.map((item, i) => (
|
||||||
|
<React.Fragment key={i}>
|
||||||
|
<section id={`form-${i}-${id}`}>
|
||||||
|
{item.title && <h5>{item.title}</h5>}
|
||||||
|
<Spin
|
||||||
|
spinning={loading}
|
||||||
|
indicator={<AntIcon type="loading" />}
|
||||||
|
wrapperClassName={loading && 'h-400-min'}
|
||||||
|
>
|
||||||
|
{!loading && (
|
||||||
|
<ComponentDynamic
|
||||||
|
is={item.component}
|
||||||
|
id={id}
|
||||||
|
record={record}
|
||||||
|
onRef={child => this.call(child, i)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Spin>
|
||||||
|
</section>
|
||||||
|
{i < parts.length - 1 && <Divider />}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
{/* 锚点,如果不需要可以删除以下节点 */}
|
||||||
|
<Col flex="240px">
|
||||||
|
<Anchor
|
||||||
|
getContainer={() => this.container}
|
||||||
|
offsetTop={24}
|
||||||
|
targetOffset={100}
|
||||||
|
wrapperStyle={{ backgroundColor: 'transparent' }}
|
||||||
|
onClick={e => e.preventDefault()}
|
||||||
|
>
|
||||||
|
{parts.map((part, i) => (
|
||||||
|
<Anchor.Link
|
||||||
|
key={i}
|
||||||
|
href={`#form-${i}-${id}`}
|
||||||
|
title={part.title}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Anchor>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Container>
|
||||||
|
<div className="yo-form-page--bar">
|
||||||
|
<Container mode="fluid">
|
||||||
|
<div className="yo-form-page--bar-inner">
|
||||||
|
<span></span>
|
||||||
|
<span>
|
||||||
|
<Button onClick={() => window.closeContentWindow()}>取消</Button>
|
||||||
|
<Button
|
||||||
|
disabled={saveDisabled}
|
||||||
|
loading={saving}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => this.onSubmit()}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
115
web-react/public/seed/form/part.jsx
Normal file
115
web-react/public/seed/form/part.jsx
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Form, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class part extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
//#endregion
|
||||||
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
></Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,3 +9,6 @@
|
|||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: @primary-color;
|
background-color: @primary-color;
|
||||||
}
|
}
|
||||||
|
.ant-anchor-link-active {
|
||||||
|
background: linear-gradient(90deg, #fff, transparent);
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,29 @@
|
|||||||
box-shadow: @btn-primary-shadow;
|
box-shadow: @btn-primary-shadow;
|
||||||
text-shadow: @btn-text-shadow;
|
text-shadow: @btn-text-shadow;
|
||||||
}
|
}
|
||||||
|
.ant-btn-danger-disabled,
|
||||||
|
.ant-btn-danger.disabled,
|
||||||
|
.ant-btn-danger[disabled],
|
||||||
|
.ant-btn-danger-disabled:hover,
|
||||||
|
.ant-btn-danger.disabled:hover,
|
||||||
|
.ant-btn-danger[disabled]:hover,
|
||||||
|
.ant-btn-danger-disabled:focus,
|
||||||
|
.ant-btn-danger.disabled:focus,
|
||||||
|
.ant-btn-danger[disabled]:focus,
|
||||||
|
.ant-btn-danger-disabled:active,
|
||||||
|
.ant-btn-danger.disabled:active,
|
||||||
|
.ant-btn-danger[disabled]:active,
|
||||||
|
.ant-btn-danger-disabled.active,
|
||||||
|
.ant-btn-danger.disabled.active,
|
||||||
|
.ant-btn-danger[disabled].active {
|
||||||
|
opacity: .5;
|
||||||
|
color: @btn-danger-color;
|
||||||
|
border-color: @btn-danger-border;
|
||||||
|
background-color: @btn-danger-bg;
|
||||||
|
box-shadow: @btn-primary-shadow;
|
||||||
|
text-shadow: @btn-text-shadow;
|
||||||
|
}
|
||||||
|
.ant-radio-button-wrapper-disabled,
|
||||||
.ant-radio-button-wrapper-disabled:first-child,
|
.ant-radio-button-wrapper-disabled:first-child,
|
||||||
.ant-radio-button-wrapper-disabled:hover {
|
.ant-radio-button-wrapper-disabled:hover {
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
|
|||||||
@@ -12,8 +12,9 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
>.ant-tabs {
|
>.ant-tabs {
|
||||||
>.ant-tabs-bar {
|
>.ant-tabs-nav {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
padding: 0 @padding-md;
|
||||||
|
|
||||||
background-color: @white;
|
background-color: @white;
|
||||||
|
|
||||||
|
|||||||
@@ -333,6 +333,9 @@
|
|||||||
margin-bottom: @padding-xs;
|
margin-bottom: @padding-xs;
|
||||||
|
|
||||||
border-left: @border-width-base @border-style-base @normal-color;
|
border-left: @border-width-base @border-style-base @normal-color;
|
||||||
|
&.ant-radio-button-wrapper-checked {
|
||||||
|
border-left-color: @primary-color;
|
||||||
|
}
|
||||||
&:not(:first-child) {
|
&:not(:first-child) {
|
||||||
&::before {
|
&::before {
|
||||||
content: none;
|
content: none;
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
@import (reference) '../extend.less';
|
@import (reference) '../extend.less';
|
||||||
|
|
||||||
.yo-query-bar {
|
.yo-query-bar {
|
||||||
margin-bottom: @padding-md;
|
margin-bottom: @padding-xs;
|
||||||
|
.ant-form-inline {
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: @padding-xs;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.yo-action-bar {
|
.yo-action-bar {
|
||||||
@@ -69,6 +74,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-table-sticky-scroll {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.yo-table {
|
.yo-table {
|
||||||
.ant-table {
|
.ant-table {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
@@ -151,6 +160,10 @@
|
|||||||
border-top: @border-width-base @border-style-base @table-border-color;
|
border-top: @border-width-base @border-style-base @table-border-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--row-no {
|
||||||
|
background-color: @table-header-bg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.yo-table-actions {
|
.yo-table-actions {
|
||||||
|
|||||||
@@ -3,13 +3,30 @@
|
|||||||
.width-height (@i) when (@i <=20) {
|
.width-height (@i) when (@i <=20) {
|
||||||
|
|
||||||
@n : @i * 50;
|
@n : @i * 50;
|
||||||
|
@px : @n * 1px;
|
||||||
|
|
||||||
.w-@{n} {
|
.w-@{n} {
|
||||||
width: @n * 1px !important;
|
width: @px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-@{n}-min {
|
||||||
|
min-width: @px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-@{n}-max {
|
||||||
|
max-width: @px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-@{n} {
|
.h-@{n} {
|
||||||
height: @n * 1px !important;
|
height: @px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-@{n}-min {
|
||||||
|
min-height: @px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-@{n}-max {
|
||||||
|
max-height: @px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-@{n}-p {
|
.w-@{n}-p {
|
||||||
|
|||||||
@@ -17,14 +17,73 @@
|
|||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: @layout-header-background;
|
||||||
>.ant-spin-nested-loading {
|
>.ant-spin-nested-loading {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
>div>.ant-spin {
|
>div>.ant-spin {
|
||||||
max-height: none;
|
max-height: none;
|
||||||
|
@-webkit-keyframes borderScale {
|
||||||
|
0% {
|
||||||
|
border: 5px solid white;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border: 25px solid transparent;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
border: 5px solid white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes borderScale {
|
||||||
|
0% {
|
||||||
|
border: 5px solid white;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border: 25px solid transparent;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
border: 5px solid white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.loader-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
|
||||||
|
box-sizing: content-box;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-right: -50%;
|
||||||
|
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
-webkit-animation: borderScale 1s infinite ease-in-out;
|
||||||
|
animation: borderScale 1s infinite ease-in-out;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
border: 5px solid transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
>p {
|
||||||
|
font-family: 'Raleway', sans-serif;
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
|
||||||
|
margin-right: -50%;
|
||||||
|
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
>.ant-spin-container {
|
>.ant-spin-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
&.ant-spin-blur {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,49 +163,6 @@
|
|||||||
&--avatar {
|
&--avatar {
|
||||||
box-shadow: 0 0 0 2px @white;
|
box-shadow: 0 0 0 2px @white;
|
||||||
}
|
}
|
||||||
&--name {
|
|
||||||
font-weight: bolder;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
left: 32px + @padding-sm * 2;
|
|
||||||
|
|
||||||
transition: @animation-duration-slow;
|
|
||||||
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
&--dropdown {
|
|
||||||
width: 200px;
|
|
||||||
|
|
||||||
transition: @animation-duration-base;
|
|
||||||
transform: scaleY(0);
|
|
||||||
transform-origin: top;
|
|
||||||
|
|
||||||
opacity: 0;
|
|
||||||
.ant-dropdown-menu {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.open {
|
|
||||||
width: 200px;
|
|
||||||
.user-container-inner {
|
|
||||||
background-color: @white;
|
|
||||||
box-shadow: @box-shadow-base;
|
|
||||||
}
|
|
||||||
.user {
|
|
||||||
&--name {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.drop {
|
|
||||||
.user {
|
|
||||||
&--dropdown {
|
|
||||||
transform: scaleY(1);
|
|
||||||
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -485,7 +501,6 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: @container-width;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
@layout-header-height: 54px;
|
@layout-header-height: 54px;
|
||||||
@@ -593,3 +608,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.yo-user-popover {
|
||||||
|
width: 280px;
|
||||||
|
padding-top: 0;
|
||||||
|
.ant-popover-arrow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.ant-popover-inner-content {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const urls = {
|
|||||||
houseCodeEdit: ['/houseCode/edit', 'post'],
|
houseCodeEdit: ['/houseCode/edit', 'post'],
|
||||||
houseCodePage: ['/houseCode/page', 'post'],
|
houseCodePage: ['/houseCode/page', 'post'],
|
||||||
houseCodeNo: '/houseCode/getNextNoByCode',
|
houseCodeNo: '/houseCode/getNextNoByCode',
|
||||||
|
houseCodeDetail: '/houseCode/detail'
|
||||||
}
|
}
|
||||||
|
|
||||||
export default urls
|
export default urls
|
||||||
@@ -7,7 +7,8 @@ const urls = {
|
|||||||
|
|
||||||
houseZoneList: '/houseZone/list',
|
houseZoneList: '/houseZone/list',
|
||||||
houseZoneAutoIncrement: '/houseZone/autoIncrement',
|
houseZoneAutoIncrement: '/houseZone/autoIncrement',
|
||||||
houseZoneAdd: ['/houseZone/add', 'post']
|
houseZoneAdd: ['/houseZone/add', 'post'],
|
||||||
|
houseZoneEdit: ['/houseZone/edit', 'post']
|
||||||
}
|
}
|
||||||
|
|
||||||
export default urls
|
export default urls
|
||||||
@@ -2,20 +2,27 @@ import React, { Component } from 'react'
|
|||||||
import * as Icon from '@ant-design/icons'
|
import * as Icon from '@ant-design/icons'
|
||||||
|
|
||||||
export default class AntIcon extends Component {
|
export default class AntIcon extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const type = (this.props.type || '').toUpperCase()
|
const type = (this.props.type || '').toUpperCase()
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
if (type.indexOf('OUTLINED') >= 0 || type.indexOf('FILLED') >= 0 || type.indexOf('TWOTONE') >= 0) {
|
if (
|
||||||
|
type.indexOf('OUTLINED') >= 0 ||
|
||||||
|
type.indexOf('FILLED') >= 0 ||
|
||||||
|
type.indexOf('TWOTONE') >= 0
|
||||||
|
) {
|
||||||
const I = Icon[this.props.type]
|
const I = Icon[this.props.type]
|
||||||
return <I {...this.props} />
|
return I ? <I {...this.props} /> : false
|
||||||
} else {
|
} else {
|
||||||
const t = type.split('-').map(p => {
|
const t =
|
||||||
|
type
|
||||||
|
.split('-')
|
||||||
|
.map(p => {
|
||||||
return p[0] + p.slice(1).toLowerCase()
|
return p[0] + p.slice(1).toLowerCase()
|
||||||
}).join('') + 'Outlined'
|
})
|
||||||
|
.join('') + 'Outlined'
|
||||||
const I = Icon[t]
|
const I = Icon[t]
|
||||||
return <I {...this.props} />
|
return I ? <I {...this.props} /> : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <></>
|
return <></>
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ const { getState, subscribe } = store
|
|||||||
const stroePath = 'user'
|
const stroePath = 'user'
|
||||||
|
|
||||||
export default class Auth extends Component {
|
export default class Auth extends Component {
|
||||||
|
|
||||||
state = getState(stroePath)
|
state = getState(stroePath)
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -62,11 +61,10 @@ export default class Auth extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const flag = auth.call(this.state, this.props.auth)
|
const flag = auth.call(this.state, this.props.auth)
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
return this.props.children
|
return this.props.children || <></>
|
||||||
}
|
}
|
||||||
|
|
||||||
return <></>
|
return <></>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ 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 PhotoSwipe } from './photo-swipe'
|
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'
|
||||||
export { default as QueryTableActions } from './query-table-actions'
|
export { default as QueryTableActions } from './query-table-actions'
|
||||||
|
|||||||
74
web-react/src/components/photo-preview/index.jsx
Normal file
74
web-react/src/components/photo-preview/index.jsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import 'photoswipe/dist/photoswipe.css'
|
||||||
|
import 'photoswipe/dist/default-skin/default-skin.css'
|
||||||
|
import PhotoSwipe from 'photoswipe'
|
||||||
|
import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default'
|
||||||
|
|
||||||
|
const defaultOptions = {
|
||||||
|
index: 0,
|
||||||
|
bgOpacity: 0.75,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class PhotoPreview extends Component {
|
||||||
|
initPhotoSwipe = (items = [], options = {}) => {
|
||||||
|
const pswpElement = this.refs.pswp
|
||||||
|
const gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
|
||||||
|
...defaultOptions,
|
||||||
|
...options,
|
||||||
|
})
|
||||||
|
gallery.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="pswp" tabIndex="-1" ref="pswp">
|
||||||
|
<div className="pswp__bg"></div>
|
||||||
|
<div className="pswp__scroll-wrap">
|
||||||
|
<div className="pswp__container">
|
||||||
|
<div className="pswp__item"></div>
|
||||||
|
<div className="pswp__item"></div>
|
||||||
|
<div className="pswp__item"></div>
|
||||||
|
</div>
|
||||||
|
<div className="pswp__ui pswp__ui--hidden">
|
||||||
|
<div className="pswp__top-bar">
|
||||||
|
<div className="pswp__counter"></div>
|
||||||
|
<button
|
||||||
|
className="pswp__button pswp__button--close"
|
||||||
|
title="Close (Esc)"
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
className="pswp__button pswp__button--fs"
|
||||||
|
title="Toggle fullscreen"
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
className="pswp__button pswp__button--zoom"
|
||||||
|
title="Zoom in/out"
|
||||||
|
></button>
|
||||||
|
<div className="pswp__preloader">
|
||||||
|
<div className="pswp__preloader__icn">
|
||||||
|
<div className="pswp__preloader__cut">
|
||||||
|
<div className="pswp__preloader__donut"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
|
||||||
|
<div className="pswp__share-tooltip"></div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="pswp__button pswp__button--arrow--left"
|
||||||
|
title="Previous (arrow left)"
|
||||||
|
></button>
|
||||||
|
<button
|
||||||
|
className="pswp__button pswp__button--arrow--right"
|
||||||
|
title="Next (arrow right)"
|
||||||
|
></button>
|
||||||
|
<div className="pswp__caption">
|
||||||
|
<div className="pswp__caption__center"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import React, { Component } from 'react'
|
|
||||||
|
|
||||||
export default class PhotoSwipe extends Component {
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@ import React, { Component } from 'react'
|
|||||||
import { Form, Button, Table, Tooltip } from 'antd'
|
import { Form, Button, Table, Tooltip } from 'antd'
|
||||||
import { AntIcon } from 'components'
|
import { AntIcon } from 'components'
|
||||||
|
|
||||||
const propsMap = ['autoLoad', 'loadData', 'pageIndex', 'pageSize']
|
const propsMap = ['columns', 'autoLoad', 'loadData', 'pageIndex', 'pageSize']
|
||||||
|
|
||||||
const clearChildren = data => {
|
const clearChildren = data => {
|
||||||
data.forEach(p => {
|
data.forEach(p => {
|
||||||
@@ -17,6 +17,17 @@ const clearChildren = data => {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rowNoColumn = {
|
||||||
|
title: '#',
|
||||||
|
dataIndex: 'rowNo',
|
||||||
|
width: 30,
|
||||||
|
fixed: true,
|
||||||
|
align: 'center',
|
||||||
|
ellipsis: true,
|
||||||
|
className: 'yo-table--row-no',
|
||||||
|
render: (text, record, index) => index + 1,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染查询栏
|
* 渲染查询栏
|
||||||
* @returns
|
* @returns
|
||||||
@@ -64,7 +75,7 @@ export default class QueryTable extends Component {
|
|||||||
// 加载状态
|
// 加载状态
|
||||||
loading: false,
|
loading: false,
|
||||||
// 表格类型
|
// 表格类型
|
||||||
type: '',
|
type: 'tree',
|
||||||
// 数据
|
// 数据
|
||||||
dataSource: [],
|
dataSource: [],
|
||||||
}
|
}
|
||||||
@@ -105,6 +116,8 @@ export default class QueryTable extends Component {
|
|||||||
this.loadData =
|
this.loadData =
|
||||||
typeof this.props.loadData === 'function' ? this.props.loadData : async () => {}
|
typeof this.props.loadData === 'function' ? this.props.loadData : async () => {}
|
||||||
|
|
||||||
|
this.rowNumber = typeof this.props.rowNumber === 'boolean' ? this.props.rowNumber : true
|
||||||
|
|
||||||
if (this.props.pageIndex) {
|
if (this.props.pageIndex) {
|
||||||
this.pageIndex = this.props.pageIndex
|
this.pageIndex = this.props.pageIndex
|
||||||
this.pagination.current = this.pageIndex
|
this.pagination.current = this.pageIndex
|
||||||
@@ -113,6 +126,19 @@ export default class QueryTable extends Component {
|
|||||||
this.pageSize = this.props.pageSize
|
this.pageSize = this.props.pageSize
|
||||||
this.pagination.pageSize = this.pageSize
|
this.pagination.pageSize = this.pageSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 默认排序
|
||||||
|
if (this.props.columns) {
|
||||||
|
for (const column of this.props.columns) {
|
||||||
|
if (column.defaultSortOrder) {
|
||||||
|
this.sorter = {
|
||||||
|
sortField: column.dataIndex,
|
||||||
|
sortOrder: column.defaultSortOrder,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,7 +273,9 @@ export default class QueryTable extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { loading, dataSource } = this.state
|
const { rowNumber } = this
|
||||||
|
|
||||||
|
const { loading, dataSource, type } = this.state
|
||||||
|
|
||||||
const { query, operator, columns } = this.props
|
const { query, operator, columns } = this.props
|
||||||
|
|
||||||
@@ -262,11 +290,19 @@ export default class QueryTable extends Component {
|
|||||||
loading,
|
loading,
|
||||||
pagination: this.pagination,
|
pagination: this.pagination,
|
||||||
dataSource,
|
dataSource,
|
||||||
columns: (columns || []).filter(p => !p.hidden),
|
columns: (() => {
|
||||||
|
const c = []
|
||||||
|
if (type !== 'tree' && rowNumber) {
|
||||||
|
c.push(rowNoColumn)
|
||||||
|
}
|
||||||
|
c.push(...(columns || []))
|
||||||
|
return c.filter(p => !p.hidden)
|
||||||
|
})(),
|
||||||
bordered: true,
|
bordered: true,
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
rowKey: record => record.id || Math.random().toString(16).slice(2),
|
rowKey: record => record.id || Math.random().toString(16).slice(2),
|
||||||
sticky: true,
|
sticky: true,
|
||||||
|
scroll: { x: 'max-content' },
|
||||||
...attrs,
|
...attrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, Card, message as Message, Modal } from 'antd'
|
import { Button, Card, Col, message as Message, Modal, Row, Spin } from 'antd'
|
||||||
import { ComponentDynamic, Container } from 'components'
|
import { AntIcon, ComponentDynamic, Container } from 'components'
|
||||||
import { isEqual } from 'lodash'
|
import { isEqual } from 'lodash'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
|
|
||||||
const parts = [{
|
const parts = [
|
||||||
component: () => import('./part')
|
{
|
||||||
}]
|
component: () => import('./part'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
saving: false
|
loading: true,
|
||||||
|
record: null,
|
||||||
|
|
||||||
|
saving: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
children = []
|
children = []
|
||||||
@@ -22,21 +26,35 @@ export default class index extends Component {
|
|||||||
return !isEqual(this.state, state)
|
return !isEqual(this.state, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
// 获取详细数据
|
||||||
|
const { id } = this.props.param
|
||||||
|
if (id) {
|
||||||
|
api.houseCodeDetail({ id }).then(({ data }) => {
|
||||||
|
this.setState({
|
||||||
|
record: data,
|
||||||
|
loading: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async onSubmit() {
|
async onSubmit() {
|
||||||
for (const child of this.children) {
|
for (const child of this.children) {
|
||||||
try {
|
try {
|
||||||
const data = await child.getData()
|
const data = await child.getData()
|
||||||
this.formData = {
|
this.formData = {
|
||||||
...this.formData,
|
...this.formData,
|
||||||
...data
|
...data,
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (e) {
|
||||||
return
|
return e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#region 提交数据
|
||||||
this.setState({ saving: true })
|
this.setState({ saving: true })
|
||||||
if (!this.props.param.record) {
|
if (!this.state.record) {
|
||||||
// 新增
|
// 新增
|
||||||
try {
|
try {
|
||||||
const { success } = await api.houseCodeAdd(this.formData)
|
const { success } = await api.houseCodeAdd(this.formData)
|
||||||
@@ -44,12 +62,10 @@ export default class index extends Component {
|
|||||||
Message.success('保存成功')
|
Message.success('保存成功')
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
content: '已添加成功,是否继续添加?',
|
content: '已添加成功,是否继续添加?',
|
||||||
onOk: () => {
|
onOk: () => {},
|
||||||
|
|
||||||
},
|
|
||||||
onCancel: () => {
|
onCancel: () => {
|
||||||
window.closeContentWindow()
|
window.closeContentWindow()
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -58,7 +74,10 @@ export default class index extends Component {
|
|||||||
} else {
|
} else {
|
||||||
// 编辑
|
// 编辑
|
||||||
try {
|
try {
|
||||||
const { success } = await api.houseCodeEdit(this.formData)
|
const { success } = await api.houseCodeEdit({
|
||||||
|
id: this.state.record.id,
|
||||||
|
...this.formData,
|
||||||
|
})
|
||||||
if (success) {
|
if (success) {
|
||||||
Message.success('保存成功')
|
Message.success('保存成功')
|
||||||
}
|
}
|
||||||
@@ -66,35 +85,57 @@ export default class index extends Component {
|
|||||||
this.setState({ saving: false })
|
this.setState({ saving: false })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { id } = this.props
|
||||||
|
|
||||||
const { id, param } = this.props
|
const { loading, record, saving } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="yo-form-page">
|
<div className="yo-form-page">
|
||||||
<Container mode="fluid">
|
<Container mode="fluid" ref={this.setContainer}>
|
||||||
|
<Row gutter={16} type="flex">
|
||||||
|
<Col flex="1">
|
||||||
<br />
|
<br />
|
||||||
<div className="yo-adorn--house-top" />
|
<div className="yo-adorn--house-top" />
|
||||||
<Card className="yo-form-page--body">
|
<Card className="yo-form-page--body">
|
||||||
{
|
{parts.map((item, i) => (
|
||||||
parts.map((item, i) => (
|
|
||||||
<section key={i} id={`form-${i}-${id}`}>
|
<section key={i} id={`form-${i}-${id}`}>
|
||||||
{item.title && <h5>{parts.title}</h5>}
|
{item.title && <h5>{item.title}</h5>}
|
||||||
<ComponentDynamic is={item.component} param={param} onRef={(r) => this.children.push(r)} />
|
<Spin
|
||||||
|
spinning={loading}
|
||||||
|
indicator={<AntIcon type="loading" />}
|
||||||
|
wrapperClassName={loading && 'h-400-min'}
|
||||||
|
>
|
||||||
|
{!loading && (
|
||||||
|
<ComponentDynamic
|
||||||
|
is={item.component}
|
||||||
|
record={record}
|
||||||
|
onRef={r => this.children.push(r)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Spin>
|
||||||
</section>
|
</section>
|
||||||
))
|
))}
|
||||||
}
|
|
||||||
</Card>
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
</Container>
|
</Container>
|
||||||
<div className="yo-form-page--bar">
|
<div className="yo-form-page--bar">
|
||||||
<Container mode="fluid">
|
<Container mode="fluid">
|
||||||
<div className="yo-form-page--bar-inner">
|
<div className="yo-form-page--bar-inner">
|
||||||
<span></span>
|
<span></span>
|
||||||
<span>
|
<span>
|
||||||
<Button>取消</Button>
|
<Button onClick={() => window.closeContentWindow()}>取消</Button>
|
||||||
<Button type="primary" onClick={() => this.onSubmit()} loading={this.state.saving}>保存</Button>
|
<Button
|
||||||
|
loading={saving}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => this.onSubmit()}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -1,36 +1,49 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, Cascader, Form, Input, InputNumber, Radio, Spin, Select, Row, Col, Tag, Alert, Tooltip } from 'antd'
|
import {
|
||||||
|
Button,
|
||||||
|
Cascader,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
InputNumber,
|
||||||
|
Radio,
|
||||||
|
Spin,
|
||||||
|
Select,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
Tag,
|
||||||
|
Alert,
|
||||||
|
Tooltip,
|
||||||
|
} from 'antd'
|
||||||
import { AntIcon, Auth } from 'components'
|
import { AntIcon, Auth } from 'components'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
import getDictData from 'util/dic'
|
import getDictData from 'util/dic'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import { CITY } from 'util/global'
|
import { CITY } from 'util/global'
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
type: 1,
|
type: 1,
|
||||||
industry: 1
|
industry: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelCol = { flex: '150px' }
|
const labelCol = { flex: '150px' }
|
||||||
const wrapperCol = { flex: '1' }
|
const wrapperCol = { flex: '1' }
|
||||||
|
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
// 加载状态
|
// 加载状态
|
||||||
loading: true,
|
loading: true,
|
||||||
codes: {
|
codes: {
|
||||||
dicHouseType: [],
|
houseType: [],
|
||||||
dicHouseIndustry: []
|
houseIndustry: [],
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
areaTree: [],
|
areaTree: [],
|
||||||
projects: [],
|
projects: [],
|
||||||
zones: []
|
zones: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
houseCode: '',
|
houseCode: '',
|
||||||
showIndustry: false
|
showIndustry: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表单实例
|
// 表单实例
|
||||||
@@ -41,6 +54,10 @@ export default class form extends Component {
|
|||||||
// 初始化数据
|
// 初始化数据
|
||||||
record = {}
|
record = {}
|
||||||
|
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mount后回调
|
* mount后回调
|
||||||
*/
|
*/
|
||||||
@@ -48,7 +65,9 @@ export default class form extends Component {
|
|||||||
if (this.props.onRef) {
|
if (this.props.onRef) {
|
||||||
this.props.onRef(this)
|
this.props.onRef(this)
|
||||||
}
|
}
|
||||||
this.fillData(this.props.param)
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@@ -62,7 +81,6 @@ 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 从后端转换成前段所需格式
|
||||||
await this.initMap()
|
await this.initMap()
|
||||||
@@ -75,12 +93,12 @@ export default class form extends Component {
|
|||||||
areaCode.substr(0, 4),
|
areaCode.substr(0, 4),
|
||||||
areaCode.substr(0, 6),
|
areaCode.substr(0, 6),
|
||||||
areaCode.substr(0, 9),
|
areaCode.substr(0, 9),
|
||||||
areaCode
|
areaCode,
|
||||||
]
|
]
|
||||||
// 获取项目和片区列表
|
// 获取项目和片区列表
|
||||||
const data = await this.getProjectsAndZones({
|
const data = await this.getProjectsAndZones({
|
||||||
areaCode: this.record.areaCode,
|
areaCode: this.record.areaCode,
|
||||||
type
|
type,
|
||||||
})
|
})
|
||||||
Object.assign(options, data)
|
Object.assign(options, data)
|
||||||
// 定位
|
// 定位
|
||||||
@@ -88,19 +106,19 @@ export default class form extends Component {
|
|||||||
this.setMarker(position)
|
this.setMarker(position)
|
||||||
this.map.setCenter(position)
|
this.map.setCenter(position)
|
||||||
}
|
}
|
||||||
const codes = await getDictData('dic_house_type', 'dic_house_industry')
|
const codes = await getDictData('house_type', 'house_industry')
|
||||||
const { data: areaTree } = await api.getAreaTree()
|
const { data: areaTree } = await api.getAreaTree()
|
||||||
options.areaTree = areaTree
|
options.areaTree = areaTree
|
||||||
this.setState({
|
this.setState({
|
||||||
codes,
|
codes,
|
||||||
options
|
options,
|
||||||
})
|
})
|
||||||
this.showHouseCode()
|
this.showHouseCode()
|
||||||
//#endregion
|
//#endregion
|
||||||
this.form.current.setFieldsValue(this.record)
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,9 +134,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 从前段转换后端所需格式
|
||||||
if (postData.areaCode) {
|
if (postData.areaCode) {
|
||||||
postData.areaCode = postData.areaCode[3]
|
postData.areaCode = postData.areaCode[3]
|
||||||
@@ -130,7 +145,6 @@ export default class form extends Component {
|
|||||||
|
|
||||||
//#region 自定义方法
|
//#region 自定义方法
|
||||||
initMap() {
|
initMap() {
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const amap = AMap
|
const amap = AMap
|
||||||
|
|
||||||
@@ -140,7 +154,7 @@ export default class form extends Component {
|
|||||||
const district = new amap.DistrictSearch({
|
const district = new amap.DistrictSearch({
|
||||||
subdistrict: 0,
|
subdistrict: 0,
|
||||||
extensions: 'all',
|
extensions: 'all',
|
||||||
level: 'city'
|
level: 'city',
|
||||||
})
|
})
|
||||||
|
|
||||||
district.search(city, (status, result) => {
|
district.search(city, (status, result) => {
|
||||||
@@ -152,15 +166,15 @@ export default class form extends Component {
|
|||||||
|
|
||||||
const geocoder = new amap.Geocoder({ city })
|
const geocoder = new amap.Geocoder({ city })
|
||||||
geocoder.getLocation(city, (status, result) => {
|
geocoder.getLocation(city, (status, result) => {
|
||||||
|
if (status !== 'complete' || !(result.geocodes && result.geocodes.length))
|
||||||
if (status !== 'complete' || !(result.geocodes && result.geocodes.length)) return
|
return
|
||||||
|
|
||||||
this.citycode = result.geocodes[0].addressComponent.citycode
|
this.citycode = result.geocodes[0].addressComponent.citycode
|
||||||
|
|
||||||
this.map = new amap.Map(this.refs.map, {
|
this.map = new amap.Map(this.refs.map, {
|
||||||
mask,
|
mask,
|
||||||
zoom: 12,
|
zoom: 12,
|
||||||
center: result.geocodes[0].location
|
center: result.geocodes[0].location,
|
||||||
})
|
})
|
||||||
|
|
||||||
this.map.on('click', e => {
|
this.map.on('click', e => {
|
||||||
@@ -176,7 +190,7 @@ export default class form extends Component {
|
|||||||
path,
|
path,
|
||||||
strokeColor: '#ccc',
|
strokeColor: '#ccc',
|
||||||
strokeWeight: 4,
|
strokeWeight: 4,
|
||||||
map: this.map
|
map: this.map,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,13 +200,13 @@ export default class form extends Component {
|
|||||||
const auto = new amap.AutoComplete({
|
const auto = new amap.AutoComplete({
|
||||||
input: this.refs['map-search'].input,
|
input: this.refs['map-search'].input,
|
||||||
city,
|
city,
|
||||||
citylimit: true
|
citylimit: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const placeSearch = new amap.PlaceSearch({
|
const placeSearch = new amap.PlaceSearch({
|
||||||
city,
|
city,
|
||||||
citylimit: true,
|
citylimit: true,
|
||||||
pageSize: 1
|
pageSize: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
auto.on('select', ({ poi: { name: keywords, adcode } }) => {
|
auto.on('select', ({ poi: { name: keywords, adcode } }) => {
|
||||||
@@ -206,15 +220,13 @@ export default class form extends Component {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setMarker(position, geocoder) {
|
setMarker(position, geocoder) {
|
||||||
|
const set = position => {
|
||||||
const set = (position) => {
|
|
||||||
if (this.marker) {
|
if (this.marker) {
|
||||||
this.marker.setPosition(position)
|
this.marker.setPosition(position)
|
||||||
} else {
|
} else {
|
||||||
@@ -242,7 +254,6 @@ export default class form extends Component {
|
|||||||
|
|
||||||
set(position)
|
set(position)
|
||||||
resolve(position)
|
resolve(position)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.error('根据经纬度查询地址失败')
|
console.error('根据经纬度查询地址失败')
|
||||||
|
|
||||||
@@ -260,7 +271,7 @@ export default class form extends Component {
|
|||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
address,
|
address,
|
||||||
lng,
|
lng,
|
||||||
lat
|
lat,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,13 +290,13 @@ export default class form extends Component {
|
|||||||
if (mode.includes('projects')) {
|
if (mode.includes('projects')) {
|
||||||
const { data: projects } = await api.houseProjectList({
|
const { data: projects } = await api.houseProjectList({
|
||||||
areaCode: areaCode[3],
|
areaCode: areaCode[3],
|
||||||
type
|
type,
|
||||||
})
|
})
|
||||||
result.projects = projects
|
result.projects = projects
|
||||||
}
|
}
|
||||||
if (mode.includes('zones')) {
|
if (mode.includes('zones')) {
|
||||||
const { data: zones } = await api.houseZoneList({
|
const { data: zones } = await api.houseZoneList({
|
||||||
areaCode: areaCode[3]
|
areaCode: areaCode[3],
|
||||||
})
|
})
|
||||||
result.zones = zones
|
result.zones = zones
|
||||||
}
|
}
|
||||||
@@ -300,7 +311,7 @@ export default class form extends Component {
|
|||||||
this.setState({ loading: true })
|
this.setState({ loading: true })
|
||||||
const { data: no } = await api.houseCodeNo({ projectId })
|
const { data: no } = await api.houseCodeNo({ projectId })
|
||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
no
|
no,
|
||||||
})
|
})
|
||||||
this.setState({ loading: false })
|
this.setState({ loading: false })
|
||||||
}
|
}
|
||||||
@@ -308,7 +319,7 @@ export default class form extends Component {
|
|||||||
showHouseCode(values) {
|
showHouseCode(values) {
|
||||||
if (this.record) {
|
if (this.record) {
|
||||||
this.setState({
|
this.setState({
|
||||||
houseCode: this.record.houseCode
|
houseCode: this.record.houseCode,
|
||||||
})
|
})
|
||||||
} else if (values) {
|
} else if (values) {
|
||||||
const { type, industry, areaCode, projectId, no } = values
|
const { type, industry, areaCode, projectId, no } = values
|
||||||
@@ -323,7 +334,8 @@ export default class form extends Component {
|
|||||||
if (!industry) {
|
if (!industry) {
|
||||||
this.setState({ houseCode: '' })
|
this.setState({ houseCode: '' })
|
||||||
} else {
|
} else {
|
||||||
const tag = this.state.codes.dicHouseIndustry.find(p => p.code == industry).extCode.tag
|
const tag = this.state.codes.houseIndustry.find(p => p.code == industry)
|
||||||
|
.extCode.tag
|
||||||
houseCode += `-${tag}`
|
houseCode += `-${tag}`
|
||||||
this.setState({ houseCode })
|
this.setState({ houseCode })
|
||||||
}
|
}
|
||||||
@@ -340,16 +352,16 @@ export default class form extends Component {
|
|||||||
if (changedValues.hasOwnProperty('type')) {
|
if (changedValues.hasOwnProperty('type')) {
|
||||||
this.setState({
|
this.setState({
|
||||||
showIndustry: changedValues.type == 2,
|
showIndustry: changedValues.type == 2,
|
||||||
loading: true
|
loading: true,
|
||||||
})
|
})
|
||||||
const data = await this.getProjectsAndZones()
|
const data = await this.getProjectsAndZones()
|
||||||
form.setFieldsValue({ projectId: undefined })
|
form.setFieldsValue({ projectId: undefined })
|
||||||
this.setState({
|
this.setState({
|
||||||
options: {
|
options: {
|
||||||
...this.state.options,
|
...this.state.options,
|
||||||
...data
|
...data,
|
||||||
},
|
},
|
||||||
loading: false
|
loading: false,
|
||||||
})
|
})
|
||||||
this.showHouseCode(form.getFieldsValue())
|
this.showHouseCode(form.getFieldsValue())
|
||||||
}
|
}
|
||||||
@@ -362,9 +374,9 @@ export default class form extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
options: {
|
options: {
|
||||||
...this.state.options,
|
...this.state.options,
|
||||||
...data
|
...data,
|
||||||
},
|
},
|
||||||
loading: false
|
loading: false,
|
||||||
})
|
})
|
||||||
this.showHouseCode(form.getFieldsValue())
|
this.showHouseCode(form.getFieldsValue())
|
||||||
}
|
}
|
||||||
@@ -392,15 +404,14 @@ export default class form extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
options: {
|
options: {
|
||||||
...this.state.options,
|
...this.state.options,
|
||||||
...data
|
...data,
|
||||||
},
|
},
|
||||||
loading: false
|
loading: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const { loading, codes, options, showIndustry, houseCode } = this.state
|
const { loading, codes, options, showIndustry, houseCode } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -409,61 +420,70 @@ export default class form extends Component {
|
|||||||
ref={this.form}
|
ref={this.form}
|
||||||
// labelCol={labelCol}
|
// labelCol={labelCol}
|
||||||
// wrapperCol={wrapperCol}
|
// wrapperCol={wrapperCol}
|
||||||
onValuesChange={(changedValues, allValues) => this.onValuesChange(changedValues, allValues)}
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
|
|
||||||
>
|
>
|
||||||
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={10}>
|
<Col span={10}>
|
||||||
<div className="yo-map-container">
|
<div className="yo-map-container">
|
||||||
<div className="yo-map--search">
|
<div className="yo-map--search">
|
||||||
<Input.Search allowClear placeholder="请输入关键字" ref="map-search" />
|
<Input.Search
|
||||||
|
allowClear
|
||||||
|
placeholder="请输入关键字"
|
||||||
|
ref="map-search"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-700" ref="map"></div>
|
<div className="h-700" ref="map"></div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={14}>
|
<Col span={14}>
|
||||||
<Form.Item label="房屋性质" name="type" rules={[{ required: true, message: '请选择房屋性质' }]}>
|
<Form.Item
|
||||||
<Radio.Group
|
label="房屋性质"
|
||||||
disabled={!!this.record}
|
name="type"
|
||||||
buttonStyle="solid"
|
rules={[{ required: true, message: '请选择房屋性质' }]}
|
||||||
>
|
>
|
||||||
{codes.dicHouseType.map(item => (
|
<Radio.Group disabled={!!this.record} buttonStyle="solid">
|
||||||
<Radio.Button
|
{codes.houseType.map(item => (
|
||||||
key={item.code}
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
value={+item.code}
|
{item.value}
|
||||||
>{item.value}</Radio.Button>
|
</Radio.Button>
|
||||||
))}
|
))}
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{
|
{showIndustry && (
|
||||||
showIndustry &&
|
<Form.Item
|
||||||
<Form.Item label="所属行业、系统" name="industry" rules={[{ required: true, message: '请选择所属行业、系统' }]}>
|
label="所属行业、系统"
|
||||||
<Radio.Group
|
name="industry"
|
||||||
disabled={!!this.record}
|
rules={[{ required: true, message: '请选择所属行业、系统' }]}
|
||||||
buttonStyle="solid"
|
|
||||||
>
|
>
|
||||||
{codes.dicHouseIndustry.map(item => (
|
<Radio.Group disabled={!!this.record} buttonStyle="solid">
|
||||||
<Radio.Button
|
{codes.houseIndustry.map(item => (
|
||||||
key={item.code}
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
value={+item.code}
|
{item.value}
|
||||||
>{item.value}</Radio.Button>
|
</Radio.Button>
|
||||||
))}
|
))}
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
}
|
)}
|
||||||
<Form.Item label="房屋编码" required className="mb-none">
|
<Form.Item label="房屋编码" required className="mb-none">
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col flex="100%">
|
<Col flex="100%">
|
||||||
<Form.Item name="areaCode" rules={[{ required: true, message: '请选择房屋所在区域' }]}>
|
<Form.Item
|
||||||
|
name="areaCode"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请选择房屋所在区域' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
<Cascader
|
<Cascader
|
||||||
allowClear={false}
|
allowClear={false}
|
||||||
displayRender={(labels) => labels.join(' - ')}
|
displayRender={labels => labels.join(' - ')}
|
||||||
fieldNames={{
|
fieldNames={{
|
||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'code',
|
value: 'code',
|
||||||
children: 'children'
|
children: 'children',
|
||||||
}}
|
}}
|
||||||
options={options.areaTree}
|
options={options.areaTree}
|
||||||
expandTrigger="hover"
|
expandTrigger="hover"
|
||||||
@@ -473,13 +493,20 @@ export default class form extends Component {
|
|||||||
<Col flex="1">
|
<Col flex="1">
|
||||||
<Row gutter={8}>
|
<Row gutter={8}>
|
||||||
<Col flex="1">
|
<Col flex="1">
|
||||||
<Form.Item name="projectId" rules={[{ required: true, message: '请选择项目' }]}>
|
<Form.Item
|
||||||
|
name="projectId"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请选择项目' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
<Select placeholder="请选择项目">
|
<Select placeholder="请选择项目">
|
||||||
{options.projects.map(item => (
|
{options.projects.map(item => (
|
||||||
<Select.Option
|
<Select.Option
|
||||||
key={item.id}
|
key={item.id}
|
||||||
value={item.id}
|
value={item.id}
|
||||||
>{item.name}({item.note})</Select.Option>
|
>
|
||||||
|
{item.name}({item.note})
|
||||||
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -488,8 +515,18 @@ export default class form extends Component {
|
|||||||
<Col>
|
<Col>
|
||||||
<Button.Group>
|
<Button.Group>
|
||||||
<Button>项目管理</Button>
|
<Button>项目管理</Button>
|
||||||
<Tooltip placement="top" title="重新加载项目列表">
|
<Tooltip
|
||||||
<Button icon={<AntIcon type="reload" />} onClick={() => this.onReloadProjectsOrZones('projects')}></Button>
|
placement="top"
|
||||||
|
title="重新加载项目列表"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={<AntIcon type="reload" />}
|
||||||
|
onClick={() =>
|
||||||
|
this.onReloadProjectsOrZones(
|
||||||
|
'projects'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
></Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Button.Group>
|
</Button.Group>
|
||||||
</Col>
|
</Col>
|
||||||
@@ -497,9 +534,12 @@ export default class form extends Component {
|
|||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
<Col flex="1">
|
<Col flex="1">
|
||||||
<Form.Item name="no" rules={[{ required: true, message: '请输入房屋序号' }]}>
|
<Form.Item
|
||||||
|
name="no"
|
||||||
|
rules={[{ required: true, message: '请输入房屋序号' }]}
|
||||||
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
formatter={(value) => value.padStart(3, '0')}
|
formatter={value => value.padStart(3, '0')}
|
||||||
max={999}
|
max={999}
|
||||||
min={1}
|
min={1}
|
||||||
precision={0}
|
precision={0}
|
||||||
@@ -509,14 +549,10 @@ export default class form extends Component {
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
{
|
{showIndustry && <Col>-</Col>}
|
||||||
showIndustry &&
|
|
||||||
<Col>-</Col>
|
|
||||||
}
|
|
||||||
</Row>
|
</Row>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{
|
{houseCode && (
|
||||||
houseCode &&
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Tag
|
<Tag
|
||||||
color="purple"
|
color="purple"
|
||||||
@@ -524,27 +560,64 @@ export default class form extends Component {
|
|||||||
fontSize: '24px',
|
fontSize: '24px',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
letterSpacing: '10px',
|
letterSpacing: '10px',
|
||||||
padding: '12px'
|
padding: '12px',
|
||||||
}}
|
}}
|
||||||
>{houseCode}</Tag>
|
>
|
||||||
|
{houseCode}
|
||||||
|
</Tag>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
}
|
)}
|
||||||
<Alert
|
<Alert
|
||||||
message={<b>房屋编码说明</b>}
|
message={<b>房屋编码说明</b>}
|
||||||
description={<>
|
description={
|
||||||
房屋所在市<AntIcon type="border" /><AntIcon type="border" /><AntIcon type="border" /><AntIcon type="border" />—县(市、区)<AntIcon type="border" /><AntIcon type="border" />—街道(乡、镇)<AntIcon type="border" /><AntIcon type="border" /><AntIcon type="border" />—社区、居(村)委会)<AntIcon type="border" /><AntIcon type="border" /><AntIcon type="border" />—项目<AntIcon type="border" /><AntIcon type="border" /><AntIcon type="border" />—实物幢序号<AntIcon type="border" /><AntIcon type="border" /><AntIcon type="border" />。 根据省厅既有建筑物编号规则,房屋所在区域编号按照市、县(市、区)、街道(乡、镇)、社区、居(村)委会)、项目分类,其中市、县(市)区部分按照《中华人民共和国行政区划代码》(GB2260)标准编码,街道(乡、镇)按《县以下行政区划代码编码规则》(GB10114-88)标准编码,社区、居(村)委会部分按照统计局提供编码设定。各地上报各街道社区名称后,上述编号由系统自动生成。<br />各社区下辖项目由各地负责统一编码,住宅项目序号一般一个小区一号,采用3位数,001号起编,范围为001~999。实物幢序号由各地负责统一编码,以幢为单位,采用3位数,001号起编,范围为001~999。
|
<>
|
||||||
</>} />
|
房屋所在市
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
—县(市、区)
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
—街道(乡、镇)
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
—社区、居(村)委会)
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
—项目
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
—实物幢序号
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />
|
||||||
|
<AntIcon type="border" />。
|
||||||
|
根据省厅既有建筑物编号规则,房屋所在区域编号按照市、县(市、区)、街道(乡、镇)、社区、居(村)委会)、项目分类,其中市、县(市)区部分按照《中华人民共和国行政区划代码》(GB2260)标准编码,街道(乡、镇)按《县以下行政区划代码编码规则》(GB10114-88)标准编码,社区、居(村)委会部分按照统计局提供编码设定。各地上报各街道社区名称后,上述编号由系统自动生成。
|
||||||
|
<br />
|
||||||
|
各社区下辖项目由各地负责统一编码,住宅项目序号一般一个小区一号,采用3位数,001号起编,范围为001~999。实物幢序号由各地负责统一编码,以幢为单位,采用3位数,001号起编,范围为001~999。
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<br />
|
<br />
|
||||||
<Form.Item label="所属片区" required>
|
<Form.Item label="所属片区" required>
|
||||||
<Row gutter={8}>
|
<Row gutter={8}>
|
||||||
<Col flex="1">
|
<Col flex="1">
|
||||||
<Form.Item name="zoneId" rules={[{ required: true, message: '请选择所属片区' }]} noStyle>
|
<Form.Item
|
||||||
<Select placeholder="请选择所属片区" className="w-100-p">
|
name="zoneId"
|
||||||
|
rules={[{ required: true, message: '请选择所属片区' }]}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
placeholder="请选择所属片区"
|
||||||
|
className="w-100-p"
|
||||||
|
>
|
||||||
{options.zones.map(item => (
|
{options.zones.map(item => (
|
||||||
<Select.Option
|
<Select.Option key={item.id} value={item.id}>
|
||||||
key={item.id}
|
{item.name}
|
||||||
value={item.id}
|
</Select.Option>
|
||||||
>{item.name}</Select.Option>
|
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -554,26 +627,58 @@ export default class form extends Component {
|
|||||||
<Button.Group>
|
<Button.Group>
|
||||||
<Button>片区管理</Button>
|
<Button>片区管理</Button>
|
||||||
<Tooltip placement="top" title="重新加载片区列表">
|
<Tooltip placement="top" title="重新加载片区列表">
|
||||||
<Button icon={<AntIcon type="reload" />} onClick={() => this.onReloadProjectsOrZones('zones')}></Button>
|
<Button
|
||||||
|
icon={<AntIcon type="reload" />}
|
||||||
|
onClick={() =>
|
||||||
|
this.onReloadProjectsOrZones('zones')
|
||||||
|
}
|
||||||
|
></Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Button.Group>
|
</Button.Group>
|
||||||
</Col>
|
</Col>
|
||||||
</Auth>
|
</Auth>
|
||||||
</Row>
|
</Row>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="房屋地址" name="address" rules={[{ required: true, message: '请输入房屋地址' }]}>
|
<Form.Item
|
||||||
<Input autoComplete="off" placeholder="请输入房屋地址或在地图上选择地点" />
|
label="房屋地址"
|
||||||
|
name="address"
|
||||||
|
rules={[{ required: true, message: '请输入房屋地址' }]}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
autoComplete="off"
|
||||||
|
placeholder="请输入房屋地址或在地图上选择地点"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="地理坐标" required>
|
<Form.Item label="地理坐标" required>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item name="lng" className="mb-none" rules={[{ required: true, message: '请在地图中选择坐标' }]}>
|
<Form.Item
|
||||||
<Input disabled placeholder="请在地图中选择坐标" prefix="经度" />
|
name="lng"
|
||||||
|
className="mb-none"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请在地图中选择坐标' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
disabled
|
||||||
|
placeholder="请在地图中选择坐标"
|
||||||
|
prefix="经度"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item name="lat" className="mb-none" rules={[{ required: true, message: '请在地图中选择坐标' }]}>
|
<Form.Item
|
||||||
<Input disabled placeholder="请在地图中选择坐标" prefix="纬度" />
|
name="lat"
|
||||||
|
className="mb-none"
|
||||||
|
rules={[
|
||||||
|
{ required: true, message: '请在地图中选择坐标' },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
disabled
|
||||||
|
placeholder="请在地图中选择坐标"
|
||||||
|
prefix="纬度"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, Card, Cascader, Form, Input, InputNumber, Popconfirm, message as Message, Radio, Select } from 'antd'
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Cascader,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
InputNumber,
|
||||||
|
Popconfirm,
|
||||||
|
message as Message,
|
||||||
|
Radio,
|
||||||
|
Select,
|
||||||
|
} from 'antd'
|
||||||
import { isEqual } from 'lodash'
|
import { isEqual } from 'lodash'
|
||||||
import { AntIcon, Auth, Container, QueryTable, QueryTableActions } from 'components'
|
import { AntIcon, Auth, Container, QueryTable, QueryTableActions } from 'components'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
@@ -10,25 +21,24 @@ import { getSearchInfo } from 'util/query'
|
|||||||
|
|
||||||
// 配置页面所需接口函数
|
// 配置页面所需接口函数
|
||||||
const apiAction = {
|
const apiAction = {
|
||||||
page: api.houseCodePage
|
page: api.houseCodePage,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于弹窗标题
|
// 用于弹窗标题
|
||||||
const name = '房屋编码'
|
const name = '房屋编码'
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
dicHouseType: [],
|
houseType: [],
|
||||||
dicHouseIndustry: []
|
houseIndustry: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
areaTree: []
|
areaTree: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
type: ''
|
type: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表格实例
|
// 表格实例
|
||||||
@@ -41,14 +51,19 @@ export default class index extends Component {
|
|||||||
dataIndex: 'houseCode',
|
dataIndex: 'houseCode',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 300,
|
width: 300,
|
||||||
render: (text, record) => `${record.areaName}-${record.roadName}-${record.commName}-${record.note}-${record.no.toString().padStart(3, '0')}`
|
render: (text, record) =>
|
||||||
|
`${record.areaName}-${record.roadName}-${record.commName}-${record.note}-${record.no
|
||||||
|
.toString()
|
||||||
|
.padStart(3, '0')}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '房屋性质及行业',
|
title: '房屋性质及行业',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 150,
|
width: 150,
|
||||||
render: (text, record) => this.bindCodeValue(text, 'dic_house_type') + (text === 2 ? `(${this.bindCodeValue(record.industry, 'dic_house_industry')})` : '')
|
render: (text, record) =>
|
||||||
|
this.bindCodeValue(text, 'house_type') +
|
||||||
|
(text === 2 ? `(${this.bindCodeValue(record.industry, 'house_industry')})` : ''),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '地址',
|
title: '地址',
|
||||||
@@ -77,7 +92,8 @@ export default class index extends Component {
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: (text, record) => (<QueryTableActions>
|
render: (text, record) => (
|
||||||
|
<QueryTableActions>
|
||||||
<Auth auth="houseCode:edit">
|
<Auth auth="houseCode:edit">
|
||||||
<a onClick={() => this.onOpen(record)}>编辑</a>
|
<a onClick={() => this.onOpen(record)}>编辑</a>
|
||||||
</Auth>
|
</Auth>
|
||||||
@@ -90,7 +106,8 @@ export default class index extends Component {
|
|||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Auth>
|
</Auth>
|
||||||
</QueryTableActions>)
|
</QueryTableActions>
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,16 +131,19 @@ export default class index extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { onLoading, onLoadData } = this.table.current
|
const { onLoading, onLoadData } = this.table.current
|
||||||
onLoading()
|
onLoading()
|
||||||
getDictData('dic_house_type', 'dic_house_industry').then(async (res) => {
|
getDictData('house_type', 'house_industry').then(async res => {
|
||||||
const { data } = await api.getAreaTree()
|
const { data } = await api.getAreaTree()
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
codes: res,
|
codes: res,
|
||||||
options: {
|
options: {
|
||||||
areaTree: data
|
areaTree: data,
|
||||||
}
|
},
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
onLoadData()
|
onLoadData()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +155,6 @@ export default class index extends Component {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
loadData = async (params, query) => {
|
loadData = async (params, query) => {
|
||||||
|
|
||||||
if (query.areaCode) {
|
if (query.areaCode) {
|
||||||
query.areaCode = query.areaCode.pop()
|
query.areaCode = query.areaCode.pop()
|
||||||
}
|
}
|
||||||
@@ -146,8 +165,8 @@ export default class index extends Component {
|
|||||||
no: '=',
|
no: '=',
|
||||||
type: '=',
|
type: '=',
|
||||||
address: 'like',
|
address: 'like',
|
||||||
houseCode: 'like'
|
houseCode: 'like',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data } = await apiAction.page({
|
const { data } = await apiAction.page({
|
||||||
@@ -167,7 +186,7 @@ export default class index extends Component {
|
|||||||
name = toCamelCase(name)
|
name = toCamelCase(name)
|
||||||
const codes = this.state.codes[name]
|
const codes = this.state.codes[name]
|
||||||
if (codes) {
|
if (codes) {
|
||||||
const c = codes.find((p) => p.code == code)
|
const c = codes.find(p => p.code == code)
|
||||||
if (c) {
|
if (c) {
|
||||||
return c.value
|
return c.value
|
||||||
}
|
}
|
||||||
@@ -187,11 +206,13 @@ export default class index extends Component {
|
|||||||
title: record ? '修改房屋编码' : '新增房屋编码',
|
title: record ? '修改房屋编码' : '新增房屋编码',
|
||||||
subTitle:
|
subTitle:
|
||||||
record &&
|
record &&
|
||||||
`${record.areaName}-${record.roadName}-${record.commName}-${record.note}-${record.no.toString().padStart(3, '0')}`,
|
`${record.areaName}-${record.roadName}-${record.commName}-${record.note}-${record.no
|
||||||
|
.toString()
|
||||||
|
.padStart(3, '0')}`,
|
||||||
path,
|
path,
|
||||||
param: {
|
param: {
|
||||||
record
|
id: record.id,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
// modal.current.open({
|
// modal.current.open({
|
||||||
// record
|
// record
|
||||||
@@ -225,17 +246,13 @@ export default class index extends Component {
|
|||||||
* @param {*} record
|
* @param {*} record
|
||||||
*/
|
*/
|
||||||
onDelete(record) {
|
onDelete(record) {
|
||||||
this.onAction(
|
this.onAction(apiAction.delete(record), '删除成功')
|
||||||
apiAction.delete(record),
|
|
||||||
'删除成功'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region 自定义方法
|
//#region 自定义方法
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const { options, codes, type } = this.state
|
const { options, codes, type } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -248,9 +265,9 @@ export default class index extends Component {
|
|||||||
loadData={this.loadData}
|
loadData={this.loadData}
|
||||||
columns={this.columns}
|
columns={this.columns}
|
||||||
queryInitialValues={{
|
queryInitialValues={{
|
||||||
type: ''
|
type: '',
|
||||||
}}
|
}}
|
||||||
onQueryChange={(values) => {
|
onQueryChange={values => {
|
||||||
if (values.hasOwnProperty('type')) {
|
if (values.hasOwnProperty('type')) {
|
||||||
this.setState({ type: values.type })
|
this.setState({ type: values.type })
|
||||||
}
|
}
|
||||||
@@ -259,11 +276,11 @@ export default class index extends Component {
|
|||||||
<Auth auth="houseCode:page">
|
<Auth auth="houseCode:page">
|
||||||
<Form.Item name="areaCode">
|
<Form.Item name="areaCode">
|
||||||
<Cascader
|
<Cascader
|
||||||
displayRender={(labels) => labels.join(' - ')}
|
displayRender={labels => labels.join(' - ')}
|
||||||
fieldNames={{
|
fieldNames={{
|
||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'code',
|
value: 'code',
|
||||||
children: 'children'
|
children: 'children',
|
||||||
}}
|
}}
|
||||||
options={options.areaTree}
|
options={options.areaTree}
|
||||||
className="w-400"
|
className="w-400"
|
||||||
@@ -273,7 +290,7 @@ export default class index extends Component {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="编号" name="no">
|
<Form.Item label="编号" name="no">
|
||||||
<InputNumber
|
<InputNumber
|
||||||
formatter={(value) => value && value.padStart(3, '0')}
|
formatter={value => value && value.padStart(3, '0')}
|
||||||
max={999}
|
max={999}
|
||||||
min={1}
|
min={1}
|
||||||
precision={0}
|
precision={0}
|
||||||
@@ -284,31 +301,28 @@ export default class index extends Component {
|
|||||||
<Form.Item label="房屋性质" name="type">
|
<Form.Item label="房屋性质" name="type">
|
||||||
<Radio.Group buttonStyle="solid">
|
<Radio.Group buttonStyle="solid">
|
||||||
<Radio.Button value="">全部</Radio.Button>
|
<Radio.Button value="">全部</Radio.Button>
|
||||||
{
|
{codes.houseType.map(item => (
|
||||||
codes.dicHouseType.map(item => (
|
<Radio.Button key={item.code} value={item.code}>
|
||||||
<Radio.Button
|
{item.value}
|
||||||
key={item.code}
|
</Radio.Button>
|
||||||
value={item.code}
|
))}
|
||||||
>{item.value}</Radio.Button>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{
|
{type == 2 && (
|
||||||
type == 2 &&
|
|
||||||
<Form.Item label="行业" name="industry">
|
<Form.Item label="行业" name="industry">
|
||||||
<Select allowClear className="w-150" placeholder="请选择行业">
|
<Select
|
||||||
{
|
allowClear
|
||||||
codes.dicHouseIndustry.map(item => (
|
className="w-150"
|
||||||
<Select.Option
|
placeholder="请选择行业"
|
||||||
key={item.code}
|
>
|
||||||
value={item.code}
|
{codes.houseIndustry.map(item => (
|
||||||
>{item.value}</Select.Option>
|
<Select.Option key={item.code} value={item.code}>
|
||||||
))
|
{item.value}
|
||||||
}
|
</Select.Option>
|
||||||
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
}
|
)}
|
||||||
<Form.Item label="地址" name="address">
|
<Form.Item label="地址" name="address">
|
||||||
<Input autoComplete="off" placeholder="请输入地址" />
|
<Input autoComplete="off" placeholder="请输入地址" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -322,7 +336,9 @@ export default class index extends Component {
|
|||||||
<Button
|
<Button
|
||||||
icon={<AntIcon type="plus" />}
|
icon={<AntIcon type="plus" />}
|
||||||
onClick={() => this.onOpen()}
|
onClick={() => this.onOpen()}
|
||||||
>新增{name}</Button>
|
>
|
||||||
|
新增{name}
|
||||||
|
</Button>
|
||||||
</Auth>
|
</Auth>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
230
web-react/src/pages/business/house/info/form/base/aspect.jsx
Normal file
230
web-react/src/pages/business/house/info/form/base/aspect.jsx
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Form, Spin, Upload } from 'antd'
|
||||||
|
import { AntIcon, PhotoPreview } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
import { BlobToBase64, GetFileName, PreviewFile } from 'util/file'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class aspect extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
photoPreview = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,在此将自身传递给父级
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
if (this.props.onRef) {
|
||||||
|
this.props.onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
if (this.record) {
|
||||||
|
const { houseInfo } = this.record
|
||||||
|
const fileValue = []
|
||||||
|
const fileList =
|
||||||
|
!houseInfo.facadePhoto || !houseInfo.facadePhoto.length
|
||||||
|
? []
|
||||||
|
: houseInfo.facadePhoto.split(',')
|
||||||
|
for (const fileId of fileList) {
|
||||||
|
try {
|
||||||
|
const file = await PreviewFile(fileId)
|
||||||
|
const base64 = await BlobToBase64(file)
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: fileId,
|
||||||
|
name: file.name,
|
||||||
|
url: base64,
|
||||||
|
status: 'done',
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
const { data: file } = await api.sysFileInfoDetail({ id: fileId })
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: '文件已丢失',
|
||||||
|
name: file.fileOriginName,
|
||||||
|
status: 'error',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
houseInfo.facadePhoto = fileValue
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
postData.houseInfo.facadePhoto = postData.houseInfo.facadePhoto
|
||||||
|
.map(item => (item.uid.startsWith('rc-upload') ? item.response : item.uid))
|
||||||
|
.join(',')
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
|
||||||
|
async onFileUpload({ file, onProgress, onSuccess, onError }) {
|
||||||
|
onProgress({
|
||||||
|
percent: 0,
|
||||||
|
})
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('file', file)
|
||||||
|
try {
|
||||||
|
const { data: fileId } = await api.sysFileInfoUpload(fd)
|
||||||
|
onSuccess(fileId)
|
||||||
|
} catch {
|
||||||
|
onError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onFilePreview(file, key) {
|
||||||
|
const fileList = this.form.current
|
||||||
|
.getFieldValue(['houseInfo', key])
|
||||||
|
.filter(p => p.status === 'done')
|
||||||
|
const items = []
|
||||||
|
for (const _file of fileList) {
|
||||||
|
const img = new Image()
|
||||||
|
const src = _file.url || _file.thumbUrl
|
||||||
|
img.src = src
|
||||||
|
items.push({
|
||||||
|
src,
|
||||||
|
w: img.naturalWidth,
|
||||||
|
h: img.naturalHeight,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.photoPreview.current.initPhotoSwipe(items, {
|
||||||
|
index: fileList.indexOf(file),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async onFileDownload(file) {
|
||||||
|
const { data, headers } = await api.sysFileInfoDownload({ id: file.response })
|
||||||
|
const url = window.URL.createObjectURL(data)
|
||||||
|
const fileName = GetFileName(headers['content-disposition'])
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
a.remove()
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="外立面照片"
|
||||||
|
name={['houseInfo', 'facadePhoto']}
|
||||||
|
valuePropName="fileList"
|
||||||
|
getValueFromEvent={e => {
|
||||||
|
if (Array.isArray(e)) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return e && e.fileList
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Upload
|
||||||
|
listType="picture-card"
|
||||||
|
customRequest={e => this.onFileUpload(e)}
|
||||||
|
showUploadList={{
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: true,
|
||||||
|
}}
|
||||||
|
onPreview={file => this.onFilePreview(file, 'facadePhoto')}
|
||||||
|
onDownload={file => this.onFileDownload(file)}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<AntIcon type="plus" />
|
||||||
|
<div className="ant-upload-text">外立面照片</div>
|
||||||
|
</div>
|
||||||
|
</Upload>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
<PhotoPreview ref={this.photoPreview} />
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Button, Form, Spin, Upload } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
import { BlobToBase64, GetFileName, PreviewFile } from 'util/file'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploads = [
|
||||||
|
{
|
||||||
|
key: 'anEntryDocument',
|
||||||
|
label: '立项文件',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'planningPermission',
|
||||||
|
label: '规划许可',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'completionRecord',
|
||||||
|
label: '竣工验收备案',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'monitorDocument',
|
||||||
|
label: '监理文件',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'identificationReport',
|
||||||
|
label: '鉴定报告',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'otherDocument',
|
||||||
|
label: '其他附件',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default class attachments extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,在此将自身传递给父级
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
if (this.props.onRef) {
|
||||||
|
this.props.onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
if (this.record) {
|
||||||
|
const { houseInfo } = this.record
|
||||||
|
const keys = uploads.map(p => p.key)
|
||||||
|
for (const key of keys) {
|
||||||
|
const fileValue = []
|
||||||
|
const fileList =
|
||||||
|
!houseInfo[key] || !houseInfo[key].length ? [] : houseInfo[key].split(',')
|
||||||
|
for (const fileId of fileList) {
|
||||||
|
try {
|
||||||
|
const file = await PreviewFile(fileId)
|
||||||
|
const base64 = await BlobToBase64(file)
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: fileId,
|
||||||
|
name: file.name,
|
||||||
|
url: base64,
|
||||||
|
status: 'done',
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
const { data: file } = await api.sysFileInfoDetail({ id: fileId })
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: '文件已丢失',
|
||||||
|
name: file.fileOriginName,
|
||||||
|
status: 'error',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
houseInfo[key] = fileValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
const { houseInfo } = postData
|
||||||
|
for (const key in houseInfo) {
|
||||||
|
houseInfo[key] = houseInfo[key]
|
||||||
|
.map(item => (item.uid.startsWith('rc-upload') ? item.response : item.uid))
|
||||||
|
.join(',')
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
|
||||||
|
async onFileUpload({ file, onProgress, onSuccess, onError }) {
|
||||||
|
onProgress({
|
||||||
|
percent: 0,
|
||||||
|
})
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('file', file)
|
||||||
|
try {
|
||||||
|
const { data: fileId } = await api.sysFileInfoUpload(fd)
|
||||||
|
onSuccess(fileId)
|
||||||
|
} catch {
|
||||||
|
onError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onFileDownload(file) {
|
||||||
|
const { data, headers } = await api.sysFileInfoDownload({ id: file.response })
|
||||||
|
const url = window.URL.createObjectURL(data)
|
||||||
|
const fileName = GetFileName(headers['content-disposition'])
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
a.remove()
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{uploads.map((item, i) => (
|
||||||
|
<Form.Item
|
||||||
|
key={i}
|
||||||
|
label={item.label}
|
||||||
|
name={['houseInfo', item.key]}
|
||||||
|
valuePropName="fileList"
|
||||||
|
getValueFromEvent={e => {
|
||||||
|
if (Array.isArray(e)) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return e && e.fileList
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Upload
|
||||||
|
customRequest={e => this.onFileUpload(e)}
|
||||||
|
showUploadList={{
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: true,
|
||||||
|
}}
|
||||||
|
onPreview={() => false}
|
||||||
|
onDownload={file => this.onFileDownload(file)}
|
||||||
|
>
|
||||||
|
<Button type="dashed" icon={<AntIcon type="upload" />}>
|
||||||
|
上传{item.label}
|
||||||
|
</Button>
|
||||||
|
</Upload>
|
||||||
|
</Form.Item>
|
||||||
|
))}
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
167
web-react/src/pages/business/house/info/form/base/drawing.jsx
Normal file
167
web-react/src/pages/business/house/info/form/base/drawing.jsx
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Checkbox, Col, Form, Input, Row, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, isEqual, sortBy } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class drawing extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {
|
||||||
|
houseStorageOfDrawings: [],
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
|
||||||
|
showDrawingMaterialText: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
if (this.record) {
|
||||||
|
const { houseInfo } = this.record
|
||||||
|
// checkbox
|
||||||
|
if (houseInfo.drawingMaterial) {
|
||||||
|
houseInfo.drawingMaterial = houseInfo.drawingMaterial.split(',')
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
showDrawingMaterialText:
|
||||||
|
!!houseInfo.drawingMaterial && houseInfo.drawingMaterial.includes('100'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const codes = await getDictData('house_storage_of_drawings')
|
||||||
|
console.log(codes)
|
||||||
|
this.setState({ codes })
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
const { houseInfo } = postData
|
||||||
|
// checkbox
|
||||||
|
if (houseInfo.drawingMaterial) {
|
||||||
|
houseInfo.drawingMaterial = sortBy(houseInfo.drawingMaterial, p => +p).join(',')
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {
|
||||||
|
const { houseInfo } = changedValues
|
||||||
|
if (houseInfo.hasOwnProperty('drawingMaterial')) {
|
||||||
|
this.setState({ showDrawingMaterialText: houseInfo.drawingMaterial.includes('100') })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading, codes, showDrawingMaterialText } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="图纸资料存档处"
|
||||||
|
name={['houseInfo', 'drawingMaterial']}
|
||||||
|
rules={[{ required: true, message: '请选择图纸资料存档处' }]}
|
||||||
|
>
|
||||||
|
<Checkbox.Group>
|
||||||
|
{codes.houseStorageOfDrawings.map(item => (
|
||||||
|
<Checkbox key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
</Form.Item>
|
||||||
|
{showDrawingMaterialText && (
|
||||||
|
<Form.Item
|
||||||
|
colon={false}
|
||||||
|
label=" "
|
||||||
|
name={['houseInfo', 'drawingMaterialText']}
|
||||||
|
>
|
||||||
|
<Input.TextArea autoSize placeholder="请输入其他图纸资料存档处" />
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Form, Radio, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class identification extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {
|
||||||
|
houseIdentification: [],
|
||||||
|
houseGovernment: [],
|
||||||
|
houseUsedStatus: [],
|
||||||
|
houseGrade: [],
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
const codes = await getDictData(
|
||||||
|
'house_identification',
|
||||||
|
'house_government',
|
||||||
|
'house_used_status',
|
||||||
|
'house_grade'
|
||||||
|
)
|
||||||
|
this.setState({ codes })
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading, codes } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="房屋使用状态"
|
||||||
|
name={['houseInfo', 'houseUsedStatus']}
|
||||||
|
rules={[{ required: true, message: '请选择房屋使用状态' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.houseUsedStatus.map(item => (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="综合等级"
|
||||||
|
name={['houseInfo', 'houseGrade']}
|
||||||
|
rules={[{ required: true, message: '请选择综合等级' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.houseGrade.map(item => (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { Row, Col, Card, Anchor } from 'antd'
|
import { Row, Col, Card, Anchor, Spin, Divider } from 'antd'
|
||||||
import { defaultsDeep } from 'lodash'
|
import { merge } from 'lodash'
|
||||||
import { ComponentDynamic, Container } from 'components'
|
import { AntIcon, ComponentDynamic, Container } from 'components'
|
||||||
|
|
||||||
const parts = [
|
const parts = [
|
||||||
{
|
{
|
||||||
@@ -10,107 +10,113 @@ const parts = [
|
|||||||
component: () => import('./building'),
|
component: () => import('./building'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '建筑物基本信息',
|
title: '权属情况',
|
||||||
component: () => import('./building'),
|
component: () => import('./ownership'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '建筑物基本信息',
|
title: '调查情况',
|
||||||
component: () => import('./building'),
|
component: () => import('./investigation'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '建筑物基本信息',
|
title: '鉴定治理',
|
||||||
component: () => import('./building'),
|
component: () => import('./identification'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '建筑物基本信息',
|
title: '图纸资料存档处',
|
||||||
component: () => import('./building'),
|
component: () => import('./drawing'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '建筑物基本信息',
|
title: '相关附件资料',
|
||||||
component: () => import('./building'),
|
component: () => import('./attachments'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '建筑概貌',
|
||||||
|
component: () => import('./aspect'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '调查单位',
|
||||||
|
component: () => import('./unit'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
container = window
|
container = window
|
||||||
forms = []
|
|
||||||
|
|
||||||
constructor(props) {
|
children = []
|
||||||
super(props)
|
|
||||||
|
|
||||||
// 使父组件获取到当前组件实例
|
formData = {}
|
||||||
if (props.onRef) {
|
|
||||||
props.onRef(this)
|
shouldComponentUpdate(props) {
|
||||||
|
return this.props.loading !== props.loading
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通知上层组件已加载完毕
|
||||||
|
call(child, index) {
|
||||||
|
this.children[index] = child
|
||||||
|
if (this.children.filter(p => p).length === parts.length) {
|
||||||
|
if (this.props.onRef) {
|
||||||
|
this.props.onRef(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getContainer = () => {
|
setContainer = container => {
|
||||||
return this.container
|
|
||||||
}
|
|
||||||
|
|
||||||
setContainer = (container) => {
|
|
||||||
this.container = (ReactDOM.findDOMNode(container) || {}).parentNode
|
this.container = (ReactDOM.findDOMNode(container) || {}).parentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
onGetData = () => {
|
async getData() {
|
||||||
return new Promise(async (resolve, reject) => {
|
for (const child of this.children) {
|
||||||
let formData = {},
|
const data = await child.getData()
|
||||||
flag = true
|
merge(this.formData, data)
|
||||||
for (let i = 0; i < this.forms.length; i++) {
|
|
||||||
const form = this.forms[i]
|
|
||||||
try {
|
|
||||||
const data = await form.onGetData()
|
|
||||||
formData = defaultsDeep(formData, data)
|
|
||||||
} catch (err) {
|
|
||||||
flag = false
|
|
||||||
reject(err)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (flag) {
|
return this.formData
|
||||||
resolve(formData)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { id, loading } = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container mode="fluid" ref={this.setContainer}>
|
<Container mode="fluid" ref={this.setContainer}>
|
||||||
<Row gutter={16} type="flex">
|
<Row gutter={16} type="flex">
|
||||||
<Col flex="1">
|
<Col flex="1">
|
||||||
<br />
|
<br />
|
||||||
|
<div className="yo-adorn--house-top" />
|
||||||
<Card className="yo-form-page--body">
|
<Card className="yo-form-page--body">
|
||||||
{
|
{parts.map((part, i) => (
|
||||||
parts.map((part, i) => {
|
<React.Fragment key={i}>
|
||||||
return (
|
<section id={`form-${i}-${id}`}>
|
||||||
<section key={i} id={`form-${i}-${this.props.id}`}>
|
|
||||||
{part.title && <h5>{part.title}</h5>}
|
{part.title && <h5>{part.title}</h5>}
|
||||||
<ComponentDynamic is={part.component} {...this.props} onRef={c => this.forms.push(c)} />
|
<Spin
|
||||||
|
spinning={loading}
|
||||||
|
indicator={<AntIcon type="loading" />}
|
||||||
|
wrapperClassName={loading && 'h-400-min'}
|
||||||
|
>
|
||||||
|
{!loading && (
|
||||||
|
<ComponentDynamic
|
||||||
|
is={part.component}
|
||||||
|
{...this.props}
|
||||||
|
onRef={child => this.call(child, i)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Spin>
|
||||||
</section>
|
</section>
|
||||||
)
|
{i < parts.length - 1 && <Divider />}
|
||||||
})
|
</React.Fragment>
|
||||||
}
|
))}
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col flex="240px">
|
<Col flex="240px">
|
||||||
<Anchor
|
<Anchor
|
||||||
getContainer={this.getContainer}
|
getContainer={() => this.container}
|
||||||
offsetTop={24}
|
offsetTop={24}
|
||||||
targetOffset={48}
|
targetOffset={100}
|
||||||
wrapperStyle={{ backgroundColor: 'transparent' }}
|
wrapperStyle={{ backgroundColor: 'transparent' }}
|
||||||
onClick={(e) => e.preventDefault()}
|
onClick={e => e.preventDefault()}
|
||||||
>
|
>
|
||||||
{
|
{parts.map((part, i) => (
|
||||||
parts.map((part, i) => {
|
<Anchor.Link key={i} href={`#form-${i}-${id}`} title={part.title} />
|
||||||
return (
|
))}
|
||||||
<Anchor.Link
|
|
||||||
key={i}
|
|
||||||
href={`#form-${i}-${this.props.id}`}
|
|
||||||
title={part.title}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</Anchor>
|
</Anchor>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -0,0 +1,301 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Checkbox, Form, Input, Radio, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, first, isEqual, last, sortBy } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkboxKeys = [
|
||||||
|
'houseSite',
|
||||||
|
'adjacentConstruction',
|
||||||
|
'chemicalErosion',
|
||||||
|
'repairAndReinforce',
|
||||||
|
'historicalCalamity',
|
||||||
|
'functionalChange',
|
||||||
|
]
|
||||||
|
|
||||||
|
export default class investigation extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {
|
||||||
|
houseHouseSite: [],
|
||||||
|
houseAdjacentConstruction: [],
|
||||||
|
houseChemicalErosion: [],
|
||||||
|
houseStructuralDismantling: [],
|
||||||
|
houseAddingLayer: [],
|
||||||
|
houseRepairAndReinforce: [],
|
||||||
|
houseHistoricalCalamity: [],
|
||||||
|
houseFunctionalChange: [],
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
if (this.record) {
|
||||||
|
const { houseInfo } = this.record
|
||||||
|
// checkbox
|
||||||
|
checkboxKeys.forEach(key => {
|
||||||
|
if (houseInfo[key]) {
|
||||||
|
houseInfo[key] = houseInfo[key].split(',')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const codes = await getDictData(
|
||||||
|
'house_house_site',
|
||||||
|
'house_adjacent_construction',
|
||||||
|
'house_chemical_erosion',
|
||||||
|
'house_structural_dismantling',
|
||||||
|
'house_adding_layer',
|
||||||
|
'house_repair_and_reinforce',
|
||||||
|
'house_historical_calamity',
|
||||||
|
'house_functional_change'
|
||||||
|
)
|
||||||
|
this.setState({ codes })
|
||||||
|
//#endregion
|
||||||
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
const { houseInfo } = postData
|
||||||
|
// checkbox
|
||||||
|
checkboxKeys.forEach(key => {
|
||||||
|
if (houseInfo[key]) {
|
||||||
|
houseInfo[key] = sortBy(houseInfo[key], p => +p).join(',')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {
|
||||||
|
const { houseInfo } = changedValues
|
||||||
|
const key = Object.keys(houseInfo).shift()
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
'adjacentConstruction',
|
||||||
|
'chemicalErosion',
|
||||||
|
'repairAndReinforce',
|
||||||
|
'historicalCalamity',
|
||||||
|
'functionalChange',
|
||||||
|
].includes(key)
|
||||||
|
) {
|
||||||
|
this.checkedNone(houseInfo[key], key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedNone(value, key) {
|
||||||
|
const form = this.form.current
|
||||||
|
if (first(value) == 0 && value.length > 1) {
|
||||||
|
// 在'无'之后选中其他值
|
||||||
|
value.shift()
|
||||||
|
form.setFieldsValue({
|
||||||
|
houseInfo: { [key]: value },
|
||||||
|
})
|
||||||
|
} else if (last(value) == 0 && value.length > 1) {
|
||||||
|
// 在其他值之后选中'无'
|
||||||
|
value = ['0']
|
||||||
|
form.setFieldsValue({
|
||||||
|
houseInfo: { [key]: value },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading, codes } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
label="房屋场地"
|
||||||
|
name={['houseInfo', 'houseSite']}
|
||||||
|
rules={[{ required: true, message: '请选择房屋场地' }]}
|
||||||
|
>
|
||||||
|
<Checkbox.Group>
|
||||||
|
{codes.houseHouseSite.map(item => (
|
||||||
|
<Checkbox key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="相邻施工"
|
||||||
|
name={['houseInfo', 'adjacentConstruction']}
|
||||||
|
rules={[{ required: true, message: '请选择相邻施工' }]}
|
||||||
|
>
|
||||||
|
<Checkbox.Group>
|
||||||
|
{codes.houseAdjacentConstruction.map(item => (
|
||||||
|
<Checkbox key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="化学侵蚀"
|
||||||
|
name={['houseInfo', 'chemicalErosion']}
|
||||||
|
rules={[{ required: true, message: '请选择化学侵蚀' }]}
|
||||||
|
>
|
||||||
|
<Checkbox.Group>
|
||||||
|
{codes.houseChemicalErosion.map(item => (
|
||||||
|
<Checkbox key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="结构拆改"
|
||||||
|
name={['houseInfo', 'structuralDismantling']}
|
||||||
|
rules={[{ required: true, message: '请选择结构拆改' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.houseStructuralDismantling.map(item => (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="加层改造"
|
||||||
|
name={['houseInfo', 'addingLayer']}
|
||||||
|
rules={[{ required: true, message: '请选择加层改造' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.houseAddingLayer.map(item => (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="修缮加固"
|
||||||
|
name={['houseInfo', 'repairAndReinforce']}
|
||||||
|
rules={[{ required: true, message: '请选择修缮加固' }]}
|
||||||
|
>
|
||||||
|
<Checkbox.Group>
|
||||||
|
{codes.houseRepairAndReinforce.map(item => (
|
||||||
|
<Checkbox key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="历史灾害"
|
||||||
|
name={['houseInfo', 'historicalCalamity']}
|
||||||
|
rules={[{ required: true, message: '请选择历史灾害' }]}
|
||||||
|
>
|
||||||
|
<Checkbox.Group>
|
||||||
|
{codes.houseHistoricalCalamity.map(item => (
|
||||||
|
<Checkbox key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="使用功能变更"
|
||||||
|
name={['houseInfo', 'functionalChange']}
|
||||||
|
rules={[{ required: true, message: '请选择使用功能变更' }]}
|
||||||
|
>
|
||||||
|
<Checkbox.Group>
|
||||||
|
{codes.houseFunctionalChange.map(item => (
|
||||||
|
<Checkbox key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Checkbox>
|
||||||
|
))}
|
||||||
|
</Checkbox.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="其他调查内容" name={['houseInfo', 'otherContents']}>
|
||||||
|
<Input.TextArea autoSize placeholder="请输入其他调查内容" />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
253
web-react/src/pages/business/house/info/form/base/ownership.jsx
Normal file
253
web-react/src/pages/business/house/info/form/base/ownership.jsx
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Col, Form, Input, InputNumber, Radio, Row, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ownership extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {
|
||||||
|
housePropertyRights: [],
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
const codes = await getDictData('house_property_rights')
|
||||||
|
this.setState({ codes })
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading, codes } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Form.Item label="产权性质" name={['houseInfo', 'propertyRights']}>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.housePropertyRights.map(item => (
|
||||||
|
<Radio.Button key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="房屋包含的住宅总套数" className="mb-none">
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="直管公房" required>
|
||||||
|
<Form.Item
|
||||||
|
name={['houseInfo', 'straightHouseCount']}
|
||||||
|
rules={[{ required: true, message: '请输入直管公房' }]}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<InputNumber min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套;</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="单位自管公房" required>
|
||||||
|
<Form.Item
|
||||||
|
name={['houseInfo', 'selfHouseCount']}
|
||||||
|
rules={[{ required: true, message: '请输入单位自管公房' }]}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<InputNumber min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套;</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="其他">
|
||||||
|
<Form.Item name={['houseInfo', 'otherCount']} noStyle>
|
||||||
|
<InputNumber min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套;</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="商品房" required>
|
||||||
|
<Form.Item
|
||||||
|
name={['houseInfo', 'businessCount']}
|
||||||
|
rules={[{ required: true, message: '请输入商品房' }]}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<InputNumber min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套;</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="房改房" required>
|
||||||
|
<Form.Item
|
||||||
|
name={['houseInfo', 'changeHouseCount']}
|
||||||
|
rules={[{ required: true, message: '请输入房改房' }]}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<InputNumber min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套;</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="拆迁安置房" required>
|
||||||
|
<Form.Item
|
||||||
|
name={['houseInfo', 'resettlementHouseCount']}
|
||||||
|
rules={[{ required: true, message: '请输入拆迁安置房' }]}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<InputNumber min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套;</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="私房">
|
||||||
|
<Form.Item name={['houseInfo', 'privateHouseCount']} noStyle>
|
||||||
|
<InputNumber min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套;</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Form.Item colon={false} label="总共">
|
||||||
|
<Form.Item name={['houseInfo', 'houseCount']} noStyle>
|
||||||
|
<InputNumber disabled min={0} step={1} placeholder="几" />
|
||||||
|
</Form.Item>
|
||||||
|
<div className="ant-form-text">套</div>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="产权单位" name={['houseInfo', 'propertyUnit']}>
|
||||||
|
<Input autoComplete="off" placeholder="请输入产权单位" />
|
||||||
|
</Form.Item>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="负责人" name={['houseInfo', 'propertyUnitUser']}>
|
||||||
|
<Input autoComplete="off" placeholder="请输入负责人" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label="负责人电话"
|
||||||
|
name={['houseInfo', 'propertyUnitUserTel']}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入负责人电话" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="联系人" name={['houseInfo', 'propertyUnitConent']}>
|
||||||
|
<Input autoComplete="off" placeholder="请输入联系人" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label="联系人电话"
|
||||||
|
name={['houseInfo', 'propertyUnitConentTel']}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入联系人电话" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
154
web-react/src/pages/business/house/info/form/base/unit.jsx
Normal file
154
web-react/src/pages/business/house/info/form/base/unit.jsx
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Col, Form, Input, Row, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class unit extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label="调查登记机构"
|
||||||
|
name={['houseInfo', 'investigateAgency']}
|
||||||
|
rules={[{ required: true, message: '请输入调查登记机构' }]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入调查登记机构" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label="调查人员"
|
||||||
|
name={['houseInfo', 'investigateUser']}
|
||||||
|
rules={[{ required: true, message: '请输入调查人员' }]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入调查人员" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label="审核人员"
|
||||||
|
name={['houseInfo', 'offlineAuditor']}
|
||||||
|
rules={[{ required: true, message: '请输入审核人员' }]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入审核人员" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label="主管部门"
|
||||||
|
name={['houseInfo', 'competentDepartment']}
|
||||||
|
rules={[{ required: true, message: '请输入主管部门' }]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入主管部门" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Tabs, Button, message } from 'antd'
|
import { Button, Descriptions, message as Message, Spin, Tabs } from 'antd'
|
||||||
import { defaultsDeep } from 'lodash'
|
import { merge, isEqual } from 'lodash'
|
||||||
import { ComponentDynamic, Container } from 'components'
|
import { AntIcon, ComponentDynamic, Container } from 'components'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
@@ -38,76 +39,141 @@ const tabs = [
|
|||||||
// active: false,
|
// active: false,
|
||||||
// show: false,
|
// show: false,
|
||||||
// },
|
// },
|
||||||
// {
|
{
|
||||||
// title: '巡查登记',
|
title: '巡查登记',
|
||||||
// name: 'patrol',
|
component: () => import('./patrol'),
|
||||||
// path: 'patrol',
|
active: false,
|
||||||
// active: false,
|
show: true,
|
||||||
// show: true,
|
},
|
||||||
// },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
actived: '0'
|
actived: '0',
|
||||||
}
|
|
||||||
forms = []
|
|
||||||
|
|
||||||
onSubmit = async () => {
|
loading: true,
|
||||||
let formData = {},
|
record: null,
|
||||||
flag = true
|
|
||||||
for (let i = 0; i < this.forms.length; i++) {
|
saveDisabled: true,
|
||||||
const form = this.forms[i]
|
saving: false,
|
||||||
try {
|
}
|
||||||
const data = await form.onGetData()
|
|
||||||
formData = defaultsDeep(formData, data)
|
children = []
|
||||||
} catch (err) {
|
|
||||||
if (err) {
|
formData = {}
|
||||||
err.errorFields.forEach(p => {
|
|
||||||
message.error(p.errors[0])
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
// 获取详细数据
|
||||||
|
const { taskId } = this.props.param
|
||||||
|
if (taskId) {
|
||||||
|
api.houseInfoGetByTaskId({ taskId }).then(({ data }) => {
|
||||||
|
this.setState({
|
||||||
|
record: data,
|
||||||
|
loading: false,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
flag = false
|
}
|
||||||
|
|
||||||
|
call(child, index) {
|
||||||
|
this.children[index] = child
|
||||||
|
if (this.children.filter(p => p).length === tabs.filter(p => p.show).length) {
|
||||||
|
this.setState({ saveDisabled: false })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flag) {
|
async onSubmit() {
|
||||||
return
|
for (const child of this.children) {
|
||||||
|
try {
|
||||||
|
const data = await child.getData()
|
||||||
|
merge(this.formData, data)
|
||||||
|
} catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(formData)
|
//#region 提交数据
|
||||||
|
console.log(this.formData)
|
||||||
|
this.setState({ saving: true })
|
||||||
|
|
||||||
message.success('提交成功')
|
setTimeout(() => {
|
||||||
|
Message.success('提交成功')
|
||||||
|
this.setState({ saving: false })
|
||||||
|
}, 3000)
|
||||||
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { loading, record, saveDisabled, saving } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="yo-form-page">
|
<div className="yo-form-page">
|
||||||
<div className="yo-form-page-layout">
|
<div className="yo-form-page-layout">
|
||||||
{/* 底部工具栏(需放在前面) */}
|
{/* 底部工具栏(需放在前面) */}
|
||||||
<div className="yo-form-page--bar yo-form-page--bar--with-tab">
|
<div className="yo-form-page--bar yo-form-page--bar--with-tab">
|
||||||
<Container>
|
<Container mode="fluid">
|
||||||
<div className="yo-form-page--bar-inner">
|
<div className="yo-form-page--bar-inner">
|
||||||
|
<span></span>
|
||||||
<span>
|
<span>
|
||||||
{/* 可以在工具栏中增加其他控件(只能在一行内) */}
|
<Button onClick={() => window.closeContentWindow()}>
|
||||||
</span>
|
取消
|
||||||
<span>
|
</Button>
|
||||||
<Button onClick={() => window.closeContentWindow()}>取消</Button>
|
<Button
|
||||||
<Button onClick={this.onSubmit} type="primary">保存</Button>
|
disabled={saveDisabled}
|
||||||
|
loading={saving}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => this.onSubmit()}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
<div className="yo-form-page--header"></div>
|
<div className="yo-form-page--header" style={{ paddingBottom: 0 }}>
|
||||||
|
<Container mode="fluid">
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Descriptions column={4}>
|
||||||
|
<Descriptions.Item label="区县(市)">
|
||||||
|
{record && record.houseCode.areaName}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="街道(乡镇)">
|
||||||
|
{record && record.houseCode.roadName}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="社区">
|
||||||
|
{record && record.houseCode.commName}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="片区">
|
||||||
|
{record && record.houseCode.zoneName}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span="2" label="编号">
|
||||||
|
{record &&
|
||||||
|
`${record.houseCode.areaName}-${
|
||||||
|
record.houseCode.roadName
|
||||||
|
}-${record.houseCode.commName}-${
|
||||||
|
record.houseCode.projectFullName
|
||||||
|
}-${record.houseCode.no.toString().padStart(3, '0')}`}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item span="2" label="编码">
|
||||||
|
{record && record.houseCode.houseCode}
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</Spin>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
<div className="yo-tab-external-mount">
|
<div className="yo-tab-external-mount">
|
||||||
<Tabs
|
<Tabs
|
||||||
activeKey={this.state.actived}
|
activeKey={this.state.actived}
|
||||||
animated={false}
|
animated={false}
|
||||||
onChange={(activeKey) => { this.setState({ actived: activeKey }) }}
|
onChange={activeKey => {
|
||||||
|
this.setState({ actived: activeKey })
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{
|
{tabs.map((tab, i) => {
|
||||||
tabs.map((tab, i) => {
|
|
||||||
if (tab.show) {
|
if (tab.show) {
|
||||||
return (
|
return (
|
||||||
<Tabs.TabPane
|
<Tabs.TabPane
|
||||||
@@ -118,27 +184,33 @@ export default class index extends Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
return <></>
|
return <></>
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div className="yo-tab-external-mount-content">
|
<div className="yo-tab-external-mount-content">
|
||||||
{
|
{tabs.map((tab, i) => {
|
||||||
tabs.map((tab, i) => {
|
|
||||||
if (tab.show) {
|
if (tab.show) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
className={
|
className={[
|
||||||
(this.state.actived === i.toString() ? 'yo-tab-external-tabpane-active' : 'yo-tab-external-tabpane-inactive') + ' yo-tab-external-tabpane'
|
this.state.actived === i.toString()
|
||||||
}
|
? 'yo-tab-external-tabpane-active'
|
||||||
|
: 'yo-tab-external-tabpane-inactive',
|
||||||
|
'yo-tab-external-tabpane',
|
||||||
|
].join(' ')}
|
||||||
>
|
>
|
||||||
<ComponentDynamic is={tab.component} {...this.props} onRef={c => this.forms.push(c)} />
|
<ComponentDynamic
|
||||||
|
is={tab.component}
|
||||||
|
id={this.props.id}
|
||||||
|
record={record}
|
||||||
|
loading={loading}
|
||||||
|
onRef={child => this.call(child, i)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return <></>
|
return <></>
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
112
web-react/src/pages/business/house/info/form/patrol/base.jsx
Normal file
112
web-react/src/pages/business/house/info/form/patrol/base.jsx
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Row, Col, Form, Input, DatePicker, Spin } from 'antd'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import moment from 'moment'
|
||||||
|
import { CITY } from 'util/global'
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class base extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
call() {
|
||||||
|
if (this.props.onRef) {
|
||||||
|
this.props.onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
if (this.record) {
|
||||||
|
const { patrolDate } = this.record.patrolInfo
|
||||||
|
this.record.patrolInfo.patrolDate = patrolDate ? moment(patrolDate) : patrolDate
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
if (postData.patrolInfo.patrolDate) {
|
||||||
|
postData.patrolInfo.patrolDate = postData.patrolInfo.patrolDate.format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading } = this.state
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form {...layout} ref={this.form}>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
name={['patrolInfo', 'patrolDate']}
|
||||||
|
label="巡查日期"
|
||||||
|
rules={[{ required: true, message: '请选择巡查日期' }]}
|
||||||
|
>
|
||||||
|
<DatePicker
|
||||||
|
onChange={date => {
|
||||||
|
/*$root.transfer.completedYear = date.format('YYYY') */
|
||||||
|
}}
|
||||||
|
className="w-100-p"
|
||||||
|
placeholder="请选择巡查日期"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
label="巡查人/单位"
|
||||||
|
name={['patrolInfo', 'patrolUser']}
|
||||||
|
rules={[{ required: true, message: '请输入巡查人/单位' }]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入巡查人/单位" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
183
web-react/src/pages/business/house/info/form/patrol/grade.jsx
Normal file
183
web-react/src/pages/business/house/info/form/patrol/grade.jsx
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Form, Tooltip, Radio, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, first, isEqual, last, sortBy } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
import store from 'store'
|
||||||
|
|
||||||
|
const { getState, subscribe } = store
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class handling extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {
|
||||||
|
housePatrolInitGrade: [],
|
||||||
|
housePatrolDamageGrade: [],
|
||||||
|
houseGrade: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.unsubscribe = subscribe('business', business => {
|
||||||
|
const initGrade = this.getInitGrade(business.completedDate)
|
||||||
|
this.form.current.setFieldsValue({
|
||||||
|
patrolInfo: {
|
||||||
|
initGrade,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
|
call() {
|
||||||
|
if (this.props.onRef) {
|
||||||
|
this.props.onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
|
||||||
|
const _state = { loading: false }
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
if (this.record) {
|
||||||
|
const { patrolInfo } = this.record
|
||||||
|
patrolInfo.initGrade = this.getInitGrade(getState('business').completedDate)
|
||||||
|
}
|
||||||
|
_state.codes = await getDictData(
|
||||||
|
'house_patrol_init_grade',
|
||||||
|
'house_patrol_damage_grade',
|
||||||
|
'house_grade'
|
||||||
|
)
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState(_state)
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getInitGrade(completedDate) {
|
||||||
|
const date = completedDate.find(p => p.id === this.props.id)
|
||||||
|
if (date) {
|
||||||
|
const { value: year } = date
|
||||||
|
if (year > 1999) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (year > 1994 && year < 2000) {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
if (year > 1979 && year < 1995) {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
if (year < 1980) {
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading, codes, initGradeValue } = this.state
|
||||||
|
console.log(initGradeValue)
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form {...layout} ref={this.form}>
|
||||||
|
<Form.Item
|
||||||
|
label="初始等级"
|
||||||
|
name={['patrolInfo', 'initGrade']}
|
||||||
|
rules={[{ required: true, message: '请选择初始等级' }]}
|
||||||
|
>
|
||||||
|
<Tooltip title="初始等级无法手动更改,由房屋详情的竣工日期决定:2000年之后竣工的为一级,1995年~1999年竣工的为二级,1980年~1994年竣工的为三级,早于1980年竣工的为四级。选择房屋竣工日期后,初始等级会自动填充。">
|
||||||
|
<Radio.Group disabled buttonStyle="solid">
|
||||||
|
{codes.housePatrolInitGrade.map(item => {
|
||||||
|
return (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Radio.Group>
|
||||||
|
</Tooltip>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label="损坏等级"
|
||||||
|
name={['patrolInfo', 'damageGrade']}
|
||||||
|
rules={[{ required: true, message: '请选择损坏等级' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.housePatrolDamageGrade.map(item => {
|
||||||
|
return (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label="综合等级"
|
||||||
|
name={['patrolInfo', 'comprehensiveGrade']}
|
||||||
|
rules={[{ required: true, message: '请选择综合等级' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.houseGrade.map(item => {
|
||||||
|
return (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
131
web-react/src/pages/business/house/info/form/patrol/handling.jsx
Normal file
131
web-react/src/pages/business/house/info/form/patrol/handling.jsx
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Form, Input, Radio, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, first, isEqual, last, sortBy } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class handling extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {
|
||||||
|
housePatrolHandlingOpinion: [],
|
||||||
|
housePatrolRectifyReform: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
call() {
|
||||||
|
if (this.props.onRef) {
|
||||||
|
this.props.onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
const _state = { loading: false }
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
_state.codes = await getDictData(
|
||||||
|
'house_patrol_handling_opinion',
|
||||||
|
'house_patrol_rectify_Reform'
|
||||||
|
)
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState(_state)
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const { loading, codes } = this.state
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form {...layout} ref={this.form}>
|
||||||
|
<Form.Item
|
||||||
|
label="处理建议"
|
||||||
|
name={['patrolInfo', 'handlingOpinion']}
|
||||||
|
rules={[{ required: true, message: '请选择处理建议' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.housePatrolHandlingOpinion.map(item => {
|
||||||
|
return (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item label="处理建议备注" name={['patrolInfo', 'handlingOpinionRemark']}>
|
||||||
|
<Input.TextArea
|
||||||
|
autoSize={{ minRows: 3 }}
|
||||||
|
placeholder="请输入处理建议备注"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label="整改情况"
|
||||||
|
name={['patrolInfo', 'rectifyAndReform']}
|
||||||
|
rules={[{ required: true, message: '请选择整改情况' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.housePatrolRectifyReform.map(item => {
|
||||||
|
return (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item label="整改情况备注" name={['patrolInfo', 'rectifyAndReformRemark']}>
|
||||||
|
<Input.TextArea
|
||||||
|
autoSize={{ minRows: 3 }}
|
||||||
|
placeholder="请输入整改情况备注"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
146
web-react/src/pages/business/house/info/form/patrol/index.jsx
Normal file
146
web-react/src/pages/business/house/info/form/patrol/index.jsx
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
import { Anchor, Card, Col, Divider, Row, Spin } from 'antd'
|
||||||
|
import { AntIcon, ComponentDynamic, Container } from 'components'
|
||||||
|
import { isEqual, merge } from 'lodash'
|
||||||
|
|
||||||
|
const parts = [
|
||||||
|
{
|
||||||
|
title: '巡查基本情况',
|
||||||
|
component: () => import('./base'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '房屋检查',
|
||||||
|
component: () => import('./inspection'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '等级划分',
|
||||||
|
component: () => import('./grade'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '处理情况',
|
||||||
|
component: () => import('./handling'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '本期巡查结果',
|
||||||
|
component: () => import('./result'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default class index extends Component {
|
||||||
|
// 子表单实例集合
|
||||||
|
children = []
|
||||||
|
|
||||||
|
// 整合提交数据
|
||||||
|
formData = {}
|
||||||
|
|
||||||
|
// 锚点挂载DOM
|
||||||
|
container = window
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state) || this.props.loading !== props.loading
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call(child, index) {
|
||||||
|
this.children[index] = child
|
||||||
|
if (this.children.filter(p => p).length === parts.length) {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从下级组件获取表单数据,并传递给更上级组件
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
for (const child of this.children) {
|
||||||
|
const data = await child.getData()
|
||||||
|
merge(this.formData, data)
|
||||||
|
}
|
||||||
|
return this.formData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置锚点容器
|
||||||
|
* [非必要]
|
||||||
|
* @param {*} container
|
||||||
|
*/
|
||||||
|
setContainer = container => {
|
||||||
|
this.container = (ReactDOM.findDOMNode(container) || {}).parentNode
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染
|
||||||
|
* 当前渲染结构已完善,非必要可以不用修改
|
||||||
|
* [必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { id, loading } = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container mode="fluid" ref={this.setContainer}>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col flex="1">
|
||||||
|
<br />
|
||||||
|
<div className="yo-adorn--house-top" />
|
||||||
|
<Card className="yo-form-page--body">
|
||||||
|
{parts.map((item, i) => (
|
||||||
|
<React.Fragment key={i}>
|
||||||
|
<section id={`form-patrol-${i}-${id}`}>
|
||||||
|
{item.title && <h5>{item.title}</h5>}
|
||||||
|
<Spin
|
||||||
|
spinning={loading}
|
||||||
|
indicator={<AntIcon type="loading" />}
|
||||||
|
wrapperClassName={loading && 'h-400-min'}
|
||||||
|
>
|
||||||
|
{!loading && (
|
||||||
|
<ComponentDynamic
|
||||||
|
is={item.component}
|
||||||
|
{...this.props}
|
||||||
|
onRef={child => this.call(child, i)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Spin>
|
||||||
|
</section>
|
||||||
|
{i < parts.length - 1 && <Divider />}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
{/* 锚点,如果不需要可以删除以下节点 */}
|
||||||
|
<Col flex="240px">
|
||||||
|
<Anchor
|
||||||
|
getContainer={() => this.container}
|
||||||
|
offsetTop={24}
|
||||||
|
targetOffset={100}
|
||||||
|
wrapperStyle={{ backgroundColor: 'transparent' }}
|
||||||
|
onClick={e => e.preventDefault()}
|
||||||
|
>
|
||||||
|
{parts.map((part, i) => (
|
||||||
|
<Anchor.Link
|
||||||
|
key={i}
|
||||||
|
href={`#form-patrol-${i}-${id}`}
|
||||||
|
title={part.title}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Anchor>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Col, Form, Input, Row, Spin, Upload } from 'antd'
|
||||||
|
import { AntIcon, PhotoPreview } from 'components'
|
||||||
|
import { cloneDeep, isEqual } from 'lodash'
|
||||||
|
import { BlobToBase64, GetFileName, PreviewFile } from 'util/file'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
|
||||||
|
const initialValues = {}
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageUploads = [{ key: 'settlementTiltFiles' }, { key: 'otherInfoFiles' }]
|
||||||
|
|
||||||
|
export default class inspection extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {},
|
||||||
|
options: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单实例
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
photoPreview = React.createRef()
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
record = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM加载完成钩子,绑定数据
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载完成,通知父级组件并传递自身
|
||||||
|
*/
|
||||||
|
call() {
|
||||||
|
const { onRef } = this.props
|
||||||
|
if (onRef) onRef(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
if (this.record) {
|
||||||
|
const { patrolInfo } = this.record
|
||||||
|
const keys = imageUploads.map(p => p.key)
|
||||||
|
for (const key of keys) {
|
||||||
|
const fileValue = []
|
||||||
|
const fileList =
|
||||||
|
!patrolInfo[key] || !patrolInfo[key].length ? [] : patrolInfo[key].split(',')
|
||||||
|
for (const fileId of fileList) {
|
||||||
|
try {
|
||||||
|
const file = await PreviewFile(fileId)
|
||||||
|
const base64 = await BlobToBase64(file)
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: fileId,
|
||||||
|
name: file.name,
|
||||||
|
url: base64,
|
||||||
|
status: 'done',
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
const { data: file } = await api.sysFileInfoDetail({ id: fileId })
|
||||||
|
fileValue.push({
|
||||||
|
uid: fileId,
|
||||||
|
response: '文件已丢失',
|
||||||
|
name: file.fileOriginName,
|
||||||
|
status: 'error',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
patrolInfo[key] = fileValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
const { patrolInfo } = postData
|
||||||
|
const keys = imageUploads.map(p => p.key)
|
||||||
|
for (const key of keys) {
|
||||||
|
patrolInfo[key] = patrolInfo[key]
|
||||||
|
.map(item => (item.uid.startsWith('rc-upload') ? item.response : item.uid))
|
||||||
|
.join(',')
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
/**
|
||||||
|
* 表单change事件处理,包括了所有字段的change
|
||||||
|
* [异步,非必要]
|
||||||
|
* @param {*} changedValues
|
||||||
|
* @param {*} allValues
|
||||||
|
*/
|
||||||
|
async onValuesChange(changedValues, allValues) {}
|
||||||
|
|
||||||
|
async onFileUpload({ file, onProgress, onSuccess, onError }) {
|
||||||
|
onProgress({
|
||||||
|
percent: 0,
|
||||||
|
})
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('file', file)
|
||||||
|
try {
|
||||||
|
const { data: fileId } = await api.sysFileInfoUpload(fd)
|
||||||
|
onSuccess(fileId)
|
||||||
|
} catch {
|
||||||
|
onError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onFilePreview(file, key) {
|
||||||
|
const fileList = this.form.current
|
||||||
|
.getFieldValue(['patrolInfo', key])
|
||||||
|
.filter(p => p.status === 'done')
|
||||||
|
const items = []
|
||||||
|
for (const _file of fileList) {
|
||||||
|
const img = new Image()
|
||||||
|
const src = _file.url || _file.thumbUrl
|
||||||
|
img.src = src
|
||||||
|
items.push({
|
||||||
|
src,
|
||||||
|
w: img.naturalWidth,
|
||||||
|
h: img.naturalHeight,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.photoPreview.current.initPhotoSwipe(items, {
|
||||||
|
index: fileList.indexOf(file),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async onFileDownload(file) {
|
||||||
|
const { data, headers } = await api.sysFileInfoDownload({ id: file.response })
|
||||||
|
const url = window.URL.createObjectURL(data)
|
||||||
|
const fileName = GetFileName(headers['content-disposition'])
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
a.remove()
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { loading } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form
|
||||||
|
initialValues={initialValues}
|
||||||
|
ref={this.form}
|
||||||
|
{...layout}
|
||||||
|
onValuesChange={(changedValues, allValues) =>
|
||||||
|
this.onValuesChange(changedValues, allValues)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="沉降倾斜情况" name={['patrolInfo', 'settlementTilt']}>
|
||||||
|
<Input.TextArea
|
||||||
|
autoSize={{ minRows: 4.6 }}
|
||||||
|
placeholder="请输入沉降倾斜情况"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
name={['patrolInfo', 'settlementTiltFiles']}
|
||||||
|
valuePropName="fileList"
|
||||||
|
getValueFromEvent={e => {
|
||||||
|
if (Array.isArray(e)) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return e && e.fileList
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Upload
|
||||||
|
listType="picture-card"
|
||||||
|
customRequest={e => this.onFileUpload(e)}
|
||||||
|
showUploadList={{
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: true,
|
||||||
|
}}
|
||||||
|
onPreview={file =>
|
||||||
|
this.onFilePreview(file, 'settlementTiltFiles')
|
||||||
|
}
|
||||||
|
onDownload={file => this.onFileDownload(file)}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<AntIcon type="plus" />
|
||||||
|
<div className="ant-upload-text">沉降倾斜照片</div>
|
||||||
|
</div>
|
||||||
|
</Upload>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item label="其他情况" name={['patrolInfo', 'otherInfo']}>
|
||||||
|
<Input.TextArea
|
||||||
|
autoSize={{ minRows: 4.6 }}
|
||||||
|
placeholder="请输入其他情况"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
name={['patrolInfo', 'otherInfoFiles']}
|
||||||
|
valuePropName="fileList"
|
||||||
|
getValueFromEvent={e => {
|
||||||
|
if (Array.isArray(e)) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return e && e.fileList
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Upload
|
||||||
|
listType="picture-card"
|
||||||
|
customRequest={e => this.onFileUpload(e)}
|
||||||
|
showUploadList={{
|
||||||
|
showRemoveIcon: true,
|
||||||
|
showDownloadIcon: true,
|
||||||
|
}}
|
||||||
|
onPreview={file => this.onFilePreview(file, 'otherInfoFiles')}
|
||||||
|
onDownload={file => this.onFileDownload(file)}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<AntIcon type="plus" />
|
||||||
|
<div className="ant-upload-text">其他情况照片</div>
|
||||||
|
</div>
|
||||||
|
</Upload>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Form.Item label="主要安全隐患综述" name={['patrolInfo', 'mainSafety']}>
|
||||||
|
<Input.TextArea
|
||||||
|
autoSize={{ minRows: 4.6 }}
|
||||||
|
placeholder="请输入主要安全隐患综述"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
<PhotoPreview ref={this.photoPreview} />
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
102
web-react/src/pages/business/house/info/form/patrol/result.jsx
Normal file
102
web-react/src/pages/business/house/info/form/patrol/result.jsx
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Form, Input, Radio, Spin } from 'antd'
|
||||||
|
import { AntIcon } from 'components'
|
||||||
|
import { cloneDeep, first, isEqual, last, sortBy } from 'lodash'
|
||||||
|
|
||||||
|
const layout = {
|
||||||
|
labelCol: { flex: '150px' },
|
||||||
|
wrapperCol: { flex: '1' },
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class result extends Component {
|
||||||
|
state = {
|
||||||
|
loading: true,
|
||||||
|
codes: {
|
||||||
|
patrolResult: [
|
||||||
|
{ code: '0', value: '正常' },
|
||||||
|
{ code: '-1', value: '异常' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
form = React.createRef()
|
||||||
|
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fillData({
|
||||||
|
record: this.props.record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
call() {
|
||||||
|
if (this.props.onRef) {
|
||||||
|
this.props.onRef(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充数据
|
||||||
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
async fillData(params) {
|
||||||
|
this.record = cloneDeep(params.record)
|
||||||
|
//#region 从后端转换成前段所需格式
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
this.form.current && this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
|
this.setState({ loading: false })
|
||||||
|
this.call()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据
|
||||||
|
* 可以对postData进行数据结构调整
|
||||||
|
* [异步,必要]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async getData() {
|
||||||
|
const form = this.form.current
|
||||||
|
|
||||||
|
const valid = await form.validateFields()
|
||||||
|
if (valid) {
|
||||||
|
const postData = form.getFieldsValue()
|
||||||
|
//#region 从前段转换后端所需格式
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
return postData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const { loading, codes } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={loading} indicator={<AntIcon type="loading" />}>
|
||||||
|
<Form {...layout} ref={this.form}>
|
||||||
|
<Form.Item
|
||||||
|
label="正常与否"
|
||||||
|
name={['patrolInfo', 'patrolResult']}
|
||||||
|
rules={[{ required: true, message: '请选择本期巡查结果' }]}
|
||||||
|
>
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
{codes.patrolResult.map(item => {
|
||||||
|
return (
|
||||||
|
<Radio.Button key={item.code} value={+item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="异常情况描述" name={['patrolInfo', 'patrolResultRemark']}>
|
||||||
|
<Input.TextArea autoSize placeholder="请输入异常情况描述" />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,7 @@ export default class index extends Component {
|
|||||||
const { userId } = this.state
|
const { userId } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs>
|
<Tabs tabBarStyle={{ padding: '0 24px' }}>
|
||||||
<Tabs.TabPane key="1" tab="选房">
|
<Tabs.TabPane key="1" tab="选房">
|
||||||
<SelectorList
|
<SelectorList
|
||||||
userId={userId}
|
userId={userId}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ const authName = 'houseSelector'
|
|||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
dicHouseType: [],
|
houseType: [],
|
||||||
dicHouseIndustry: [],
|
houseIndustry: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
saving: false,
|
saving: false,
|
||||||
@@ -57,7 +57,7 @@ export default class index extends Component {
|
|||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 150,
|
width: 150,
|
||||||
render: text => this.bindCodeValue(text, 'dic_house_type'),
|
render: text => this.bindCodeValue(text, 'house_type'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '地址',
|
title: '地址',
|
||||||
@@ -91,7 +91,7 @@ export default class index extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { onLoading, onLoadData } = this.table.current
|
const { onLoading, onLoadData } = this.table.current
|
||||||
onLoading()
|
onLoading()
|
||||||
getDictData('dic_house_type', 'dic_house_industry').then(codes => {
|
getDictData('house_type', 'house_industry').then(codes => {
|
||||||
this.setState({ codes }, () => {
|
this.setState({ codes }, () => {
|
||||||
onLoadData()
|
onLoadData()
|
||||||
})
|
})
|
||||||
@@ -218,7 +218,7 @@ export default class index extends Component {
|
|||||||
<Form.Item label="房屋性质" name="type">
|
<Form.Item label="房屋性质" name="type">
|
||||||
<Radio.Group buttonStyle="solid">
|
<Radio.Group buttonStyle="solid">
|
||||||
<Radio.Button value="">全部</Radio.Button>
|
<Radio.Button value="">全部</Radio.Button>
|
||||||
{codes.dicHouseType.map(item => (
|
{codes.houseType.map(item => (
|
||||||
<Radio.Button key={item.code} value={item.code}>
|
<Radio.Button key={item.code} value={item.code}>
|
||||||
{item.value}
|
{item.value}
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
@@ -228,7 +228,7 @@ export default class index extends Component {
|
|||||||
{type == 2 && (
|
{type == 2 && (
|
||||||
<Form.Item label="行业" name="industry">
|
<Form.Item label="行业" name="industry">
|
||||||
<Select allowClear className="w-150" placeholder="请选择行业">
|
<Select allowClear className="w-150" placeholder="请选择行业">
|
||||||
{codes.dicHouseIndustry.map(item => (
|
{codes.houseIndustry.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>
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ const authName = 'houseSelector'
|
|||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
dicHouseType: [],
|
houseType: [],
|
||||||
dicHouseIndustry: [],
|
houseIndustry: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
saving: false,
|
saving: false,
|
||||||
@@ -57,7 +57,7 @@ export default class index extends Component {
|
|||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 150,
|
width: 150,
|
||||||
render: text => this.bindCodeValue(text, 'dic_house_type'),
|
render: text => this.bindCodeValue(text, 'house_type'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '地址',
|
title: '地址',
|
||||||
@@ -91,7 +91,7 @@ export default class index extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { onLoading, onLoadData } = this.table.current
|
const { onLoading, onLoadData } = this.table.current
|
||||||
onLoading()
|
onLoading()
|
||||||
getDictData('dic_house_type', 'dic_house_industry').then(codes => {
|
getDictData('house_type', 'house_industry').then(codes => {
|
||||||
this.setState({ codes }, () => {
|
this.setState({ codes }, () => {
|
||||||
onLoadData()
|
onLoadData()
|
||||||
})
|
})
|
||||||
@@ -218,7 +218,7 @@ export default class index extends Component {
|
|||||||
<Form.Item label="房屋性质" name="type">
|
<Form.Item label="房屋性质" name="type">
|
||||||
<Radio.Group buttonStyle="solid">
|
<Radio.Group buttonStyle="solid">
|
||||||
<Radio.Button value="">全部</Radio.Button>
|
<Radio.Button value="">全部</Radio.Button>
|
||||||
{codes.dicHouseType.map(item => (
|
{codes.houseType.map(item => (
|
||||||
<Radio.Button key={item.code} value={item.code}>
|
<Radio.Button key={item.code} value={item.code}>
|
||||||
{item.value}
|
{item.value}
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
@@ -228,7 +228,7 @@ export default class index extends Component {
|
|||||||
{type == 2 && (
|
{type == 2 && (
|
||||||
<Form.Item label="行业" name="industry">
|
<Form.Item label="行业" name="industry">
|
||||||
<Select allowClear className="w-150" placeholder="请选择行业">
|
<Select allowClear className="w-150" placeholder="请选择行业">
|
||||||
{codes.dicHouseIndustry.map(item => (
|
{codes.houseIndustry.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>
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import { Cascader, Form, Input, InputNumber, Radio, Spin, TreeSelect } from 'ant
|
|||||||
import { AntIcon } from 'components'
|
import { AntIcon } from 'components'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import { numberToChinese } from 'util/format';
|
import { numberToChinese } from 'util/format'
|
||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
sort: 100,
|
sort: 100,
|
||||||
type: 1
|
type: 1,
|
||||||
}
|
}
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
state = {
|
state = {
|
||||||
@@ -16,8 +16,8 @@ export default class form extends Component {
|
|||||||
exist: false,
|
exist: false,
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
areaData: []
|
areaData: [],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
areaCode = ''
|
areaCode = ''
|
||||||
houseType = 1
|
houseType = 1
|
||||||
@@ -41,8 +41,12 @@ export default class form extends Component {
|
|||||||
* @param {*} params
|
* @param {*} params
|
||||||
*/
|
*/
|
||||||
async fillData(params) {
|
async fillData(params) {
|
||||||
const areaCodeDefault = params.record ? params.record.areaCode : params.pid ? params.pid : '';
|
const areaCodeDefault = params.record
|
||||||
this.houseType = params.record ? params.record.type : 1;
|
? params.record.areaCode
|
||||||
|
: params.pid
|
||||||
|
? params.pid
|
||||||
|
: ''
|
||||||
|
this.houseType = params.record ? params.record.type : 1
|
||||||
this.record = cloneDeep(params.record)
|
this.record = cloneDeep(params.record)
|
||||||
this.initRecord = cloneDeep(params.record)
|
this.initRecord = cloneDeep(params.record)
|
||||||
//#region 从后端转换成前段所需格式
|
//#region 从后端转换成前段所需格式
|
||||||
@@ -50,47 +54,47 @@ export default class form extends Component {
|
|||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
exist: !!params.record,
|
exist: !!params.record,
|
||||||
options: { areaData }
|
options: { areaData },
|
||||||
})
|
})
|
||||||
|
|
||||||
const areaCode = [];
|
const areaCode = []
|
||||||
const findCode = (data, level) => {
|
const findCode = (data, level) => {
|
||||||
level = level || 0;
|
level = level || 0
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
const item = data[i];
|
const item = data[i]
|
||||||
areaCode[level] = item.code;
|
areaCode[level] = item.code
|
||||||
|
|
||||||
if (item.code === areaCodeDefault) {
|
if (item.code === areaCodeDefault) {
|
||||||
areaCode.length = level + 1;
|
areaCode.length = level + 1
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
const found = findCode(item.children, level + 1);
|
const found = findCode(item.children, level + 1)
|
||||||
if (found) {
|
if (found) {
|
||||||
return true;
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if (areaCodeDefault) {
|
if (areaCodeDefault) {
|
||||||
findCode(areaData);
|
findCode(areaData)
|
||||||
this.areaCode = areaCodeDefault
|
this.areaCode = areaCodeDefault
|
||||||
this.nextSort(this.areaCode, this.houseType);
|
this.nextSort(this.areaCode, this.houseType)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.record = {
|
this.record = {
|
||||||
pid: params.pid,
|
pid: params.pid,
|
||||||
...this.record,
|
...this.record,
|
||||||
areaCode: areaCode.length == 4 ? areaCode : []
|
areaCode: areaCode.length == 4 ? areaCode : [],
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
this.form.current.setFieldsValue(this.record)
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -117,78 +121,84 @@ export default class form extends Component {
|
|||||||
|
|
||||||
async loadAreaData() {
|
async loadAreaData() {
|
||||||
const { data } = await api.getAreaTree()
|
const { data } = await api.getAreaTree()
|
||||||
const clearChiildren = (data) => {
|
console.log(data)
|
||||||
data.forEach((item) => {
|
const clearChiildren = data => {
|
||||||
|
data.forEach(item => {
|
||||||
if (item.children && item.children.length) {
|
if (item.children && item.children.length) {
|
||||||
clearChiildren(item.children);
|
clearChiildren(item.children)
|
||||||
} else {
|
} else {
|
||||||
delete item.children;
|
delete item.children
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
clearChiildren(data);
|
clearChiildren(data)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
async nextSort(areaCode, houseType) {
|
async nextSort(areaCode, houseType) {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
if (!!this.initRecord && this.initRecord.areaCode == areaCode && this.initRecord.type == houseType) {
|
if (
|
||||||
|
!!this.initRecord &&
|
||||||
|
this.initRecord.areaCode == areaCode &&
|
||||||
|
this.initRecord.type == houseType
|
||||||
|
) {
|
||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
name: this.initRecord.name,
|
name: this.initRecord.name,
|
||||||
sort: this.initRecord.sort
|
sort: this.initRecord.sort,
|
||||||
})
|
})
|
||||||
} else if (areaCode.length < 12) {
|
} else if (areaCode.length < 12) {
|
||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
name: '',
|
name: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
areaCode: []
|
areaCode: [],
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await api.houseProjectNextSort({ areaCode, type: houseType })
|
await api
|
||||||
|
.houseProjectNextSort({ areaCode, type: houseType })
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
name: `项目${numberToChinese(data)}`,
|
name: `项目${numberToChinese(data)}`,
|
||||||
sort: data
|
sort: data,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
name: '',
|
name: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
areaCode: []
|
areaCode: [],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onHouseTypeChange(e) {
|
onHouseTypeChange(e) {
|
||||||
this.houseType = e.target.value;
|
this.houseType = e.target.value
|
||||||
if (this.areaCode != '') {
|
if (this.areaCode != '') {
|
||||||
this.nextSort(this.areaCode, this.houseType);
|
this.nextSort(this.areaCode, this.houseType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAreaCodeChange(value) {
|
onAreaCodeChange(value) {
|
||||||
this.areaCode = value[value.length - 1]
|
this.areaCode = value[value.length - 1]
|
||||||
if (this.houseType > 0) {
|
if (this.houseType > 0) {
|
||||||
this.nextSort(this.areaCode, this.houseType);
|
this.nextSort(this.areaCode, this.houseType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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="type">
|
<Form.Item label="类型" name="type">
|
||||||
<Radio.Group disabled={this.state.exist} buttonStyle="solid" onChange={(e) => this.onHouseTypeChange(e)}>
|
<Radio.Group
|
||||||
|
disabled={this.state.exist}
|
||||||
|
buttonStyle="solid"
|
||||||
|
onChange={e => this.onHouseTypeChange(e)}
|
||||||
|
>
|
||||||
<Radio.Button value={1}>
|
<Radio.Button value={1}>
|
||||||
<span>住宅</span>
|
<span>住宅</span>
|
||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
@@ -197,13 +207,17 @@ export default class form extends Component {
|
|||||||
</Radio.Button>
|
</Radio.Button>
|
||||||
</Radio.Group>
|
</Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="所属区域" name="areaCode" rules={[{ required: true, message: '请选择所属区域' }]}>
|
<Form.Item
|
||||||
|
label="所属区域"
|
||||||
|
name="areaCode"
|
||||||
|
rules={[{ required: true, message: '请选择所属区域' }]}
|
||||||
|
>
|
||||||
<Cascader
|
<Cascader
|
||||||
options={this.state.options.areaData}
|
options={this.state.options.areaData}
|
||||||
fieldNames={{
|
fieldNames={{
|
||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'code',
|
value: 'code',
|
||||||
children: 'children'
|
children: 'children',
|
||||||
}}
|
}}
|
||||||
expandTrigger="hover"
|
expandTrigger="hover"
|
||||||
// changeOnSelect
|
// changeOnSelect
|
||||||
@@ -211,8 +225,16 @@ export default class form extends Component {
|
|||||||
onChange={(val, selectedOptions) => this.onAreaCodeChange(val)}
|
onChange={(val, selectedOptions) => this.onAreaCodeChange(val)}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="项目名称" name="name" rules={[{ required: true, message: '片区名称', trigger: 'blur' }]}>
|
<Form.Item
|
||||||
<Input autoComplete="off" placeholder="选择所属区域和类型之后自动生成" disabled={true} />
|
label="项目名称"
|
||||||
|
name="name"
|
||||||
|
rules={[{ required: true, message: '片区名称', trigger: 'blur' }]}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
autoComplete="off"
|
||||||
|
placeholder="选择所属区域和类型之后自动生成"
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="序号" name="sort">
|
<Form.Item label="序号" name="sort">
|
||||||
<InputNumber
|
<InputNumber
|
||||||
@@ -226,7 +248,8 @@ export default class form extends Component {
|
|||||||
<Form.Item label="备注" name="note">
|
<Form.Item label="备注" name="note">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
rows="4"
|
rows="4"
|
||||||
placeholder="填写房屋所属单位的名称、道路的名称或大厦的名称,比如XX中学、XX大厦、XX小区等。登记项目时,应在项目备注中明确项目所指对象。" />
|
placeholder="填写房屋所属单位的名称、道路的名称或大厦的名称,比如XX中学、XX大厦、XX小区等。登记项目时,应在项目备注中明确项目所指对象。"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
</Spin>
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
|
import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
|
||||||
import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions, QueryTreeLayout } from 'components'
|
import {
|
||||||
|
AntIcon,
|
||||||
|
Auth,
|
||||||
|
Container,
|
||||||
|
ModalForm,
|
||||||
|
QueryTable,
|
||||||
|
QueryTableActions,
|
||||||
|
QueryTreeLayout,
|
||||||
|
} 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 { toCamelCase } from 'util/format'
|
import { toCamelCase } from 'util/format'
|
||||||
@@ -13,17 +21,16 @@ const apiAction = {
|
|||||||
page: api.getHouseProjectPage,
|
page: api.getHouseProjectPage,
|
||||||
add: api.houseProejctAdd,
|
add: api.houseProejctAdd,
|
||||||
edit: api.houseProejctEdit,
|
edit: api.houseProejctEdit,
|
||||||
delete: api.houseProejctDelete
|
delete: api.houseProejctDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = '项目'
|
const name = '项目'
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
dicHouseType: []
|
houseType: [],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表格实例
|
// 表格实例
|
||||||
@@ -37,28 +44,31 @@ export default class index extends Component {
|
|||||||
// 树选中节点
|
// 树选中节点
|
||||||
selectCode = undefined
|
selectCode = undefined
|
||||||
columns = [
|
columns = [
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '项目名称',
|
title: '项目名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
width: 150,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '社区',
|
title: '社区',
|
||||||
dataIndex: 'areaName',
|
dataIndex: 'areaName',
|
||||||
|
width: 100,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '备注',
|
title: '备注',
|
||||||
dataIndex: 'note',
|
dataIndex: 'note',
|
||||||
|
width: 150,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '类型',
|
title: '类型',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
render: text => (<>{this.bindCodeValue(text, 'dic_house_type')}</>)
|
width: 80,
|
||||||
}
|
render: text => <>{this.bindCodeValue(text, 'house_type')}</>,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
/**
|
/**
|
||||||
* 构造函数,在渲染前动态添加操作字段等
|
* 构造函数,在渲染前动态添加操作字段等
|
||||||
@@ -67,14 +77,15 @@ export default class index extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
const flag = auth({ sysArea: [['edit'], ['delete']] })
|
const flag = auth({ houseProjectInfo: [['edit'], ['delete']] })
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.columns.push({
|
this.columns.push({
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: (text, record) => (<QueryTableActions>
|
render: (text, record) => (
|
||||||
|
<QueryTableActions>
|
||||||
<Auth auth="houseProjectInfo:edit">
|
<Auth auth="houseProjectInfo:edit">
|
||||||
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
||||||
</Auth>
|
</Auth>
|
||||||
@@ -87,7 +98,8 @@ export default class index extends Component {
|
|||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Auth>
|
</Auth>
|
||||||
</QueryTableActions>)
|
</QueryTableActions>
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,12 +121,15 @@ export default class index extends Component {
|
|||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.table.current.onLoading()
|
this.table.current.onLoading()
|
||||||
getDictData('dic_house_type').then(res => {
|
getDictData('house_type').then(res => {
|
||||||
this.setState({
|
this.setState(
|
||||||
codes: res
|
{
|
||||||
}, () => {
|
codes: res,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
this.table.current.onLoadData()
|
this.table.current.onLoadData()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -125,10 +140,9 @@ export default class index extends Component {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
loadData = async (params, query) => {
|
loadData = async (params, query) => {
|
||||||
|
|
||||||
query = {
|
query = {
|
||||||
...query,
|
...query,
|
||||||
pid: this.selectCode
|
pid: this.selectCode,
|
||||||
}
|
}
|
||||||
//首次加载根据code列升序排序
|
//首次加载根据code列升序排序
|
||||||
// if (!params.sortField) {
|
// if (!params.sortField) {
|
||||||
@@ -172,7 +186,7 @@ export default class index extends Component {
|
|||||||
name = toCamelCase(name)
|
name = toCamelCase(name)
|
||||||
const codes = this.state.codes[name]
|
const codes = this.state.codes[name]
|
||||||
if (codes) {
|
if (codes) {
|
||||||
const c = codes.find((p) => +p.code === code)
|
const c = codes.find(p => +p.code === code)
|
||||||
if (c) {
|
if (c) {
|
||||||
return c.value
|
return c.value
|
||||||
}
|
}
|
||||||
@@ -188,7 +202,7 @@ export default class index extends Component {
|
|||||||
onOpen(modal, record) {
|
onOpen(modal, record) {
|
||||||
modal.current.open({
|
modal.current.open({
|
||||||
pid: this.selectCode,
|
pid: this.selectCode,
|
||||||
record
|
record,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,10 +228,7 @@ export default class index extends Component {
|
|||||||
* @param {*} record
|
* @param {*} record
|
||||||
*/
|
*/
|
||||||
onDelete(record) {
|
onDelete(record) {
|
||||||
this.onAction(
|
this.onAction(apiAction.delete(record), '删除成功')
|
||||||
apiAction.delete(record),
|
|
||||||
'删除成功'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -225,7 +236,7 @@ export default class index extends Component {
|
|||||||
<QueryTreeLayout
|
<QueryTreeLayout
|
||||||
loadData={this.loadTreeData}
|
loadData={this.loadTreeData}
|
||||||
defaultExpanded={true}
|
defaultExpanded={true}
|
||||||
onSelect={(key) => this.onSelectTree(key)}
|
onSelect={key => this.onSelectTree(key)}
|
||||||
replaceFields={{ value: 'code', title: 'name', children: 'children' }}
|
replaceFields={{ value: 'code', title: 'name', children: 'children' }}
|
||||||
>
|
>
|
||||||
<Container mode="fluid">
|
<Container mode="fluid">
|
||||||
@@ -250,12 +261,12 @@ export default class index extends Component {
|
|||||||
<Button
|
<Button
|
||||||
icon={<AntIcon type="plus" />}
|
icon={<AntIcon type="plus" />}
|
||||||
onClick={() => this.onOpen(this.addForm)}
|
onClick={() => this.onOpen(this.addForm)}
|
||||||
>新增{name}</Button>
|
>
|
||||||
|
新增{name}
|
||||||
|
</Button>
|
||||||
</Auth>
|
</Auth>
|
||||||
}
|
}
|
||||||
>
|
></QueryTable>
|
||||||
|
|
||||||
</QueryTable>
|
|
||||||
</Card>
|
</Card>
|
||||||
</Container>
|
</Container>
|
||||||
<ModalForm
|
<ModalForm
|
||||||
|
|||||||
265
web-react/src/pages/business/house/task/index.jsx
Normal file
265
web-react/src/pages/business/house/task/index.jsx
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import { Button, Card, Form, Input, message as Message, Popconfirm, Radio, Select, Tag } from 'antd'
|
||||||
|
import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } from 'components'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
import auth from 'components/authorized/handler'
|
||||||
|
import { isEqual } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
import { toCamelCase } from 'util/format'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注释段[\/**\/]为必须要改
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置页面所需接口函数
|
||||||
|
*/
|
||||||
|
const apiAction = {
|
||||||
|
page: api.houseTaskPage,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一配置权限标识
|
||||||
|
* [必要]
|
||||||
|
*/
|
||||||
|
const authName = 'houseTask'
|
||||||
|
|
||||||
|
export default class index extends Component {
|
||||||
|
state = {
|
||||||
|
codes: {
|
||||||
|
houseType: [],
|
||||||
|
houseIndustry: [],
|
||||||
|
},
|
||||||
|
|
||||||
|
type: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格实例
|
||||||
|
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({ houseInfo: 'getByTaskId' })
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
this.columns.push({
|
||||||
|
title: '操作',
|
||||||
|
width: 150,
|
||||||
|
dataIndex: 'actions',
|
||||||
|
render: (text, record) => (
|
||||||
|
<QueryTableActions>
|
||||||
|
<Auth auth={{ houseInfo: 'getByTaskId' }}>
|
||||||
|
<a onClick={() => this.onOpen(record.id)}>登记</a>
|
||||||
|
</Auth>
|
||||||
|
</QueryTableActions>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @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_type', 'house_industry').then(codes => {
|
||||||
|
this.setState({ codes }, () => {
|
||||||
|
onLoadData()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用加载数据接口,可在调用前对query进行处理
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
* @param {*} query
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
loadData = async (params, query) => {
|
||||||
|
const { data } = await apiAction.page({
|
||||||
|
...params,
|
||||||
|
...query,
|
||||||
|
})
|
||||||
|
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 {*} record
|
||||||
|
*/
|
||||||
|
onOpen(taskId) {
|
||||||
|
window.openContentWindow({
|
||||||
|
title: '房屋登记',
|
||||||
|
path: 'business/house/info/form',
|
||||||
|
param: {
|
||||||
|
taskId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对表格上的操作进行统一处理
|
||||||
|
* [异步]
|
||||||
|
* @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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
//#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={{
|
||||||
|
type: '',
|
||||||
|
}}
|
||||||
|
onQueryChange={values => {
|
||||||
|
if (values.hasOwnProperty('type')) {
|
||||||
|
this.setState({ type: values.type })
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
query={
|
||||||
|
<Auth auth={{ [authName]: 'page' }}>
|
||||||
|
<Form.Item label="房屋性质" name="type">
|
||||||
|
<Radio.Group buttonStyle="solid">
|
||||||
|
<Radio.Button value="">全部</Radio.Button>
|
||||||
|
{codes.houseType.map(item => (
|
||||||
|
<Radio.Button key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Radio.Button>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
{type == 2 && (
|
||||||
|
<Form.Item label="行业" name="industry">
|
||||||
|
<Select
|
||||||
|
allowClear
|
||||||
|
className="w-150"
|
||||||
|
placeholder="请选择行业"
|
||||||
|
>
|
||||||
|
{codes.houseIndustry.map(item => (
|
||||||
|
<Select.Option key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
|
<Form.Item label="地址" name="address">
|
||||||
|
<Input autoComplete="off" placeholder="请输入地址" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="房屋唯一编码" name="houseCode">
|
||||||
|
<Input autoComplete="off" placeholder="请输入房屋唯一编码" />
|
||||||
|
</Form.Item>
|
||||||
|
</Auth>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,36 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Cascader, Form, Input, InputNumber, Select, Spin, TreeSelect } from 'antd'
|
import { Form, Input, InputNumber, Spin, TreeSelect } from 'antd'
|
||||||
import { AntIcon } from 'components'
|
import { AntIcon } from 'components'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import getDictData from 'util/dic'
|
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
import { numberToChinese } from 'util/format';
|
import { numberToChinese } from 'util/format'
|
||||||
|
import store from 'store'
|
||||||
|
|
||||||
|
const { getState, subscribe } = store
|
||||||
|
const storePath = 'user'
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
sort: 100
|
sort: 100,
|
||||||
}
|
}
|
||||||
export default class form extends Component {
|
export default class form extends Component {
|
||||||
state = {
|
state = {
|
||||||
// 加载状态
|
// 加载状态
|
||||||
loading: true,
|
loading: true,
|
||||||
|
exist: false,
|
||||||
options: {
|
options: {
|
||||||
areaData: []
|
orgData: [],
|
||||||
}
|
},
|
||||||
|
user: getState(storePath),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.unsubscribe = subscribe(storePath, () => {
|
||||||
|
this.setState({
|
||||||
|
user: getState(storePath),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
// 表单实例
|
// 表单实例
|
||||||
form = React.createRef()
|
form = React.createRef()
|
||||||
|
|
||||||
@@ -31,7 +43,9 @@ export default class form extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.created && this.props.created(this)
|
this.props.created && this.props.created(this)
|
||||||
}
|
}
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unsubscribe()
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 填充数据
|
* 填充数据
|
||||||
* 可以在设置this.record之后对其作出数据结构调整
|
* 可以在设置this.record之后对其作出数据结构调整
|
||||||
@@ -39,52 +53,38 @@ export default class form extends Component {
|
|||||||
* @param {*} params
|
* @param {*} params
|
||||||
*/
|
*/
|
||||||
async fillData(params) {
|
async fillData(params) {
|
||||||
|
const { user } = this.state
|
||||||
this.record = cloneDeep(params.record)
|
this.record = cloneDeep(params.record)
|
||||||
//#region 从后端转换成前段所需格式
|
//#region 从后端转换成前段所需格式
|
||||||
const areaData = await this.loadAreaData()
|
const orgData = await this.loadOrgData()
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
options: { areaData }
|
exist: !!params.record,
|
||||||
|
options: { orgData },
|
||||||
})
|
})
|
||||||
|
|
||||||
const areaCode = [];
|
//街道角色新增,不管左侧树选中与否,默认值均为本街道
|
||||||
const findCode = (data, level) => {
|
if (user.adminType === 2) {
|
||||||
level = level || 0;
|
user.roles.map(role => {
|
||||||
for (let i = 0; i < data.length; i++) {
|
if (role.code == 'road_manager') {
|
||||||
const item = data[i];
|
params.orgId = user.loginEmpInfo.orgId
|
||||||
areaCode[level] = item.code;
|
|
||||||
|
|
||||||
if (item.code === params.record.areaCode) {
|
|
||||||
areaCode.length = level + 1;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
if (item.children && item.children.length) {
|
|
||||||
const found = findCode(item.children, level + 1);
|
|
||||||
if (found) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (params.record && params.record.areaCode) {
|
|
||||||
findCode(areaData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.record = {
|
this.record = {
|
||||||
pid: params.orgId,
|
pid: params.orgId,
|
||||||
...this.record,
|
...this.record,
|
||||||
areaCode
|
|
||||||
}
|
}
|
||||||
this.record.areaCode = areaCode
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
if (!params.record && !!params.orgId) {
|
||||||
|
this.onOrgIdChanged(params.orgId)
|
||||||
|
}
|
||||||
this.form.current.setFieldsValue(this.record)
|
this.form.current.setFieldsValue(this.record)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -102,74 +102,64 @@ export default class form extends Component {
|
|||||||
if (this.record) {
|
if (this.record) {
|
||||||
postData.id = this.record.id
|
postData.id = this.record.id
|
||||||
}
|
}
|
||||||
//#region 从前段转换后端所需格式
|
//#region 从前段转换后端所需格
|
||||||
postData.areaCode = postData.areaCode[postData.areaCode.length - 1]
|
|
||||||
//#endregion
|
//#endregion
|
||||||
return postData
|
return postData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadAreaData() {
|
async loadOrgData() {
|
||||||
const { data } = await api.getAreaTree({ level: 3 })
|
const { data } = await api.getOrgTree({ type: 4 })
|
||||||
const clearChiildren = (data) => {
|
|
||||||
data.forEach((item) => {
|
|
||||||
if (item.children && item.children.length) {
|
|
||||||
clearChiildren(item.children);
|
|
||||||
} else {
|
|
||||||
delete item.children;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
clearChiildren(data);
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
onAreaCodeChange(value) {
|
onOrgIdChanged(value) {
|
||||||
this.loading = true;
|
this.loading = true
|
||||||
// const { data } = api.houseZoneAutoIncrement({ code: selectedOptions[selectedOptions.length - 1] });
|
|
||||||
|
|
||||||
api.houseZoneAutoIncrement({ code: value[value.length - 1] })
|
api.houseZoneAutoIncrement({ roadId: value })
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
name: `片区${numberToChinese(data)}`
|
name: `片区${numberToChinese(data)}`,
|
||||||
|
sort: data,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.form.current.setFieldsValue({
|
this.form.current.setFieldsValue({
|
||||||
name: '',
|
name: '',
|
||||||
areaCode: []
|
sort: 0,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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="areaCode" rules={[{ required: true, message: '请选择所属区域' }]}>
|
<Form.Item
|
||||||
<Cascader
|
label="所属街道"
|
||||||
options={this.state.options.areaData}
|
name="pid"
|
||||||
fieldNames={{
|
rules={[{ required: true, message: '请选择所属街道' }]}
|
||||||
label: 'name',
|
>
|
||||||
value: 'code',
|
<TreeSelect
|
||||||
children: 'children'
|
treeData={this.state.options.orgData}
|
||||||
}}
|
dropdownStyle={{ maxHeight: '300px', overflow: 'auto' }}
|
||||||
expandTrigger="hover"
|
treeDefaultExpandAll
|
||||||
// changeOnSelect
|
placeholder="请选择所属街道"
|
||||||
placeholder="请选择所属区域"
|
onChange={(value, label, extra) => this.onOrgIdChanged(value)}
|
||||||
onChange={(val, selectedOptions) => this.onAreaCodeChange(val)}
|
disabled={this.state.exist}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="片区名称" name="name" rules={[{ required: true, message: '片区名称', trigger: 'blur' }]}>
|
|
||||||
<Input autoComplete="off" placeholder="请输入机构名称" />
|
<Form.Item
|
||||||
|
label="片区名称"
|
||||||
|
name="name"
|
||||||
|
rules={[{ required: true, message: '片区名称', trigger: 'blur' }]}
|
||||||
|
>
|
||||||
|
<Input autoComplete="off" placeholder="请输入机构名称" disabled />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="排序" name="sort">
|
<Form.Item label="排序" name="sort">
|
||||||
<InputNumber
|
<InputNumber
|
||||||
@@ -177,6 +167,7 @@ export default class form extends Component {
|
|||||||
min={0}
|
min={0}
|
||||||
placeholder="请输入排序"
|
placeholder="请输入排序"
|
||||||
className="w-100-p"
|
className="w-100-p"
|
||||||
|
disabled
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="备注" name="remark">
|
<Form.Item label="备注" name="remark">
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
|
import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
|
||||||
import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions, QueryTreeLayout } from 'components'
|
import {
|
||||||
|
AntIcon,
|
||||||
|
Auth,
|
||||||
|
Container,
|
||||||
|
ModalForm,
|
||||||
|
QueryTable,
|
||||||
|
QueryTableActions,
|
||||||
|
QueryTreeLayout,
|
||||||
|
} 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 { toCamelCase } from 'util/format'
|
import { toCamelCase } from 'util/format'
|
||||||
@@ -12,14 +20,13 @@ const apiAction = {
|
|||||||
tree: api.getOrgTree,
|
tree: api.getOrgTree,
|
||||||
page: api.houseZonePage,
|
page: api.houseZonePage,
|
||||||
add: api.houseZoneAdd,
|
add: api.houseZoneAdd,
|
||||||
edit: api.sysOrgEdit,
|
edit: api.houseZoneEdit,
|
||||||
delete: api.sysOrgDelete
|
delete: api.sysOrgDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = '片区'
|
const name = '片区'
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
// 树框架实例
|
// 树框架实例
|
||||||
treeLayout = React.createRef()
|
treeLayout = React.createRef()
|
||||||
|
|
||||||
@@ -63,18 +70,19 @@ export default class index extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|
||||||
const flag = auth({ sysOrg: [['edit'], ['delete']] })
|
const flag = auth({ houseZone: [['edit'], ['delete']] })
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.columns.push({
|
this.columns.push({
|
||||||
title: '操作',
|
title: '操作',
|
||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: (text, record) => (<QueryTableActions>
|
render: (text, record) => (
|
||||||
<Auth auth="sysOrg:edit">
|
<QueryTableActions>
|
||||||
|
<Auth auth="houseZone:edit">
|
||||||
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
||||||
</Auth>
|
</Auth>
|
||||||
<Auth auth="sysOrg:delete">
|
<Auth auth="houseZone:delete">
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
placement="topRight"
|
placement="topRight"
|
||||||
title="是否确认删除"
|
title="是否确认删除"
|
||||||
@@ -83,7 +91,8 @@ export default class index extends Component {
|
|||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Auth>
|
</Auth>
|
||||||
</QueryTableActions>)
|
</QueryTableActions>
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +127,7 @@ export default class index extends Component {
|
|||||||
loadData = async (params, query) => {
|
loadData = async (params, query) => {
|
||||||
query = {
|
query = {
|
||||||
...query,
|
...query,
|
||||||
pid: this.selectId
|
pid: this.selectId,
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await apiAction.page({
|
const { data } = await apiAction.page({
|
||||||
@@ -158,7 +167,7 @@ export default class index extends Component {
|
|||||||
name = toCamelCase(name)
|
name = toCamelCase(name)
|
||||||
const codes = this.state.codes[name]
|
const codes = this.state.codes[name]
|
||||||
if (codes) {
|
if (codes) {
|
||||||
const c = codes.find((p) => p.code === code)
|
const c = codes.find(p => p.code === code)
|
||||||
if (c) {
|
if (c) {
|
||||||
return c.value
|
return c.value
|
||||||
}
|
}
|
||||||
@@ -174,7 +183,7 @@ export default class index extends Component {
|
|||||||
onOpen(modal, record) {
|
onOpen(modal, record) {
|
||||||
modal.current.open({
|
modal.current.open({
|
||||||
orgId: this.selectId,
|
orgId: this.selectId,
|
||||||
record
|
record,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,10 +214,7 @@ export default class index extends Component {
|
|||||||
* @param {*} record
|
* @param {*} record
|
||||||
*/
|
*/
|
||||||
onDelete(record) {
|
onDelete(record) {
|
||||||
this.onAction(
|
this.onAction(apiAction.delete(record), '删除成功')
|
||||||
apiAction.delete(record),
|
|
||||||
'删除成功'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region 自定义方法
|
//#region 自定义方法
|
||||||
@@ -220,7 +226,7 @@ export default class index extends Component {
|
|||||||
ref={this.treeLayout}
|
ref={this.treeLayout}
|
||||||
loadData={this.loadTreeData}
|
loadData={this.loadTreeData}
|
||||||
defaultExpanded={true}
|
defaultExpanded={true}
|
||||||
onSelect={(key) => this.onSelectTree(key)}
|
onSelect={key => this.onSelectTree(key)}
|
||||||
>
|
>
|
||||||
<Container mode="fluid">
|
<Container mode="fluid">
|
||||||
<Card bordered={false}>
|
<Card bordered={false}>
|
||||||
@@ -239,7 +245,9 @@ export default class index extends Component {
|
|||||||
<Button
|
<Button
|
||||||
icon={<AntIcon type="plus" />}
|
icon={<AntIcon type="plus" />}
|
||||||
onClick={() => this.onOpen(this.addForm)}
|
onClick={() => this.onOpen(this.addForm)}
|
||||||
>新增{name}</Button>
|
>
|
||||||
|
新增{name}
|
||||||
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -15,18 +15,17 @@ const apiAction = {
|
|||||||
edit: api.sysAppEdit,
|
edit: api.sysAppEdit,
|
||||||
delete: api.sysAppDelete,
|
delete: api.sysAppDelete,
|
||||||
|
|
||||||
setDefault: api.sysAppSetAsDefault
|
setDefault: api.sysAppSetAsDefault,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于弹窗标题
|
// 用于弹窗标题
|
||||||
const name = '应用'
|
const name = '应用'
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
commonStatus: []
|
commonStatus: [],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表格实例
|
// 表格实例
|
||||||
@@ -42,21 +41,25 @@ export default class index extends Component {
|
|||||||
{
|
{
|
||||||
title: '应用名称',
|
title: '应用名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
width: 300,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '唯一编码',
|
title: '唯一编码',
|
||||||
dataIndex: 'code',
|
dataIndex: 'code',
|
||||||
|
width: 300,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '是否默认',
|
title: '是否默认',
|
||||||
dataIndex: 'active',
|
dataIndex: 'active',
|
||||||
|
width: 200,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
render: (text, record) => (<>
|
render: (text, record) => (
|
||||||
|
<>
|
||||||
{text ? '是' : '否'}
|
{text ? '是' : '否'}
|
||||||
{
|
{!record.active && (
|
||||||
!record.active && <Auth auth="sysApp:setAsDefault">
|
<Auth auth="sysApp:setAsDefault">
|
||||||
<QueryTableActions>
|
<QueryTableActions>
|
||||||
<span></span>
|
<span></span>
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
@@ -68,18 +71,21 @@ export default class index extends Component {
|
|||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</QueryTableActions>
|
</QueryTableActions>
|
||||||
</Auth>
|
</Auth>
|
||||||
}
|
)}
|
||||||
</>)
|
</>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
|
width: 100,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
render: text => (<>{this.bindCodeValue(text, 'common_status')}</>)
|
render: text => <>{this.bindCodeValue(text, 'common_status')}</>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '排序',
|
title: '排序',
|
||||||
dataIndex: 'sort',
|
dataIndex: 'sort',
|
||||||
|
width: 100,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -98,7 +104,8 @@ export default class index extends Component {
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: (text, record) => (<QueryTableActions>
|
render: (text, record) => (
|
||||||
|
<QueryTableActions>
|
||||||
<Auth auth="sysApp:edit">
|
<Auth auth="sysApp:edit">
|
||||||
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
||||||
</Auth>
|
</Auth>
|
||||||
@@ -111,7 +118,8 @@ export default class index extends Component {
|
|||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Auth>
|
</Auth>
|
||||||
</QueryTableActions>)
|
</QueryTableActions>
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,11 +144,14 @@ export default class index extends Component {
|
|||||||
const { onLoading, onLoadData } = this.table.current
|
const { onLoading, onLoadData } = this.table.current
|
||||||
onLoading()
|
onLoading()
|
||||||
getDictData('common_status').then(res => {
|
getDictData('common_status').then(res => {
|
||||||
this.setState({
|
this.setState(
|
||||||
codes: res
|
{
|
||||||
}, () => {
|
codes: res,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
onLoadData()
|
onLoadData()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +180,7 @@ export default class index extends Component {
|
|||||||
name = toCamelCase(name)
|
name = toCamelCase(name)
|
||||||
const codes = this.state.codes[name]
|
const codes = this.state.codes[name]
|
||||||
if (codes) {
|
if (codes) {
|
||||||
const c = codes.find((p) => p.code === code)
|
const c = codes.find(p => p.code == code)
|
||||||
if (c) {
|
if (c) {
|
||||||
return c.value
|
return c.value
|
||||||
}
|
}
|
||||||
@@ -184,7 +195,7 @@ export default class index extends Component {
|
|||||||
*/
|
*/
|
||||||
onOpen(modal, record) {
|
onOpen(modal, record) {
|
||||||
modal.current.open({
|
modal.current.open({
|
||||||
record
|
record,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,18 +226,12 @@ export default class index extends Component {
|
|||||||
* @param {*} record
|
* @param {*} record
|
||||||
*/
|
*/
|
||||||
onDelete(record) {
|
onDelete(record) {
|
||||||
this.onAction(
|
this.onAction(apiAction.delete(record), '删除成功')
|
||||||
apiAction.delete(record),
|
|
||||||
'删除成功'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region 自定义方法
|
//#region 自定义方法
|
||||||
async onSetDefault(record) {
|
async onSetDefault(record) {
|
||||||
this.onAction(
|
this.onAction(apiAction.setDefault(record), '设置成功')
|
||||||
apiAction.setDefault(record),
|
|
||||||
'设置成功'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
@@ -255,7 +260,9 @@ export default class index extends Component {
|
|||||||
<Button
|
<Button
|
||||||
icon={<AntIcon type="plus" />}
|
icon={<AntIcon type="plus" />}
|
||||||
onClick={() => this.onOpen(this.addForm)}
|
onClick={() => this.onOpen(this.addForm)}
|
||||||
>新增{name}</Button>
|
>
|
||||||
|
新增{name}
|
||||||
|
</Button>
|
||||||
</Auth>
|
</Auth>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
|
import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
|
||||||
import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions, QueryTreeLayout } from 'components'
|
import {
|
||||||
|
AntIcon,
|
||||||
|
Auth,
|
||||||
|
Container,
|
||||||
|
ModalForm,
|
||||||
|
QueryTable,
|
||||||
|
QueryTableActions,
|
||||||
|
QueryTreeLayout,
|
||||||
|
} 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 { toCamelCase } from 'util/format'
|
import { toCamelCase } from 'util/format'
|
||||||
@@ -13,17 +21,16 @@ const apiAction = {
|
|||||||
page: api.sysAreaPage,
|
page: api.sysAreaPage,
|
||||||
add: api.sysAreaAdd,
|
add: api.sysAreaAdd,
|
||||||
edit: api.sysAreaEdit,
|
edit: api.sysAreaEdit,
|
||||||
delete: api.sysAreaDelete
|
delete: api.sysAreaDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = '区域'
|
const name = '区域'
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
codes: {
|
codes: {
|
||||||
dicAreacodeType: []
|
areacodeType: [],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表格实例
|
// 表格实例
|
||||||
@@ -41,31 +48,37 @@ export default class index extends Component {
|
|||||||
title: '区域类型',
|
title: '区域类型',
|
||||||
dataIndex: 'levelType',
|
dataIndex: 'levelType',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
render: text => (<>{this.bindCodeValue(text, 'dic_areacode_type')}</>)
|
width: 50,
|
||||||
|
render: text => <>{this.bindCodeValue(text, 'areacode_type')}</>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '区域名称',
|
title: '区域名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
width: 100,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '区域编号',
|
title: '区域编号',
|
||||||
dataIndex: 'code',
|
dataIndex: 'code',
|
||||||
|
width: 80,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '行政编号',
|
title: '行政编号',
|
||||||
dataIndex: 'adCode',
|
dataIndex: 'adCode',
|
||||||
|
width: 80,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '描述',
|
title: '描述',
|
||||||
dataIndex: 'note',
|
dataIndex: 'note',
|
||||||
|
width: 200,
|
||||||
sorter: false,
|
sorter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '排序',
|
title: '排序',
|
||||||
dataIndex: 'sort',
|
dataIndex: 'sort',
|
||||||
|
width: 80,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -83,7 +96,8 @@ export default class index extends Component {
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: (text, record) => (<QueryTableActions>
|
render: (text, record) => (
|
||||||
|
<QueryTableActions>
|
||||||
<Auth auth="sysArea:edit">
|
<Auth auth="sysArea:edit">
|
||||||
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
<a onClick={() => this.onOpen(this.editForm, record)}>编辑</a>
|
||||||
</Auth>
|
</Auth>
|
||||||
@@ -96,7 +110,8 @@ export default class index extends Component {
|
|||||||
<a>删除</a>
|
<a>删除</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
</Auth>
|
</Auth>
|
||||||
</QueryTableActions>)
|
</QueryTableActions>
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,12 +133,15 @@ export default class index extends Component {
|
|||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.table.current.onLoading()
|
this.table.current.onLoading()
|
||||||
getDictData('dic_areacode_type').then(res => {
|
getDictData('areacode_type').then(res => {
|
||||||
this.setState({
|
this.setState(
|
||||||
codes: res
|
{
|
||||||
}, () => {
|
codes: res,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
this.table.current.onLoadData()
|
this.table.current.onLoadData()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -134,15 +152,14 @@ export default class index extends Component {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
loadData = async (params, query) => {
|
loadData = async (params, query) => {
|
||||||
|
|
||||||
query = {
|
query = {
|
||||||
...query,
|
...query,
|
||||||
pcode: this.selectCode
|
pcode: this.selectCode,
|
||||||
}
|
}
|
||||||
//首次加载根据code列升序排序
|
//首次加载根据code列升序排序
|
||||||
if (!params.sortField) {
|
if (!params.sortField) {
|
||||||
params.sortField = 'code';
|
params.sortField = 'code'
|
||||||
params.sortOrder = 'ascend';
|
params.sortOrder = 'ascend'
|
||||||
}
|
}
|
||||||
const { data } = await apiAction.page({
|
const { data } = await apiAction.page({
|
||||||
...params,
|
...params,
|
||||||
@@ -181,7 +198,7 @@ export default class index extends Component {
|
|||||||
name = toCamelCase(name)
|
name = toCamelCase(name)
|
||||||
const codes = this.state.codes[name]
|
const codes = this.state.codes[name]
|
||||||
if (codes) {
|
if (codes) {
|
||||||
const c = codes.find((p) => +p.code === code)
|
const c = codes.find(p => +p.code === code)
|
||||||
if (c) {
|
if (c) {
|
||||||
return c.value
|
return c.value
|
||||||
}
|
}
|
||||||
@@ -197,7 +214,7 @@ export default class index extends Component {
|
|||||||
onOpen(modal, record) {
|
onOpen(modal, record) {
|
||||||
modal.current.open({
|
modal.current.open({
|
||||||
pcode: this.pcode,
|
pcode: this.pcode,
|
||||||
record
|
record,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,10 +240,7 @@ export default class index extends Component {
|
|||||||
* @param {*} record
|
* @param {*} record
|
||||||
*/
|
*/
|
||||||
onDelete(record) {
|
onDelete(record) {
|
||||||
this.onAction(
|
this.onAction(apiAction.delete(record), '删除成功')
|
||||||
apiAction.delete(record),
|
|
||||||
'删除成功'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -234,7 +248,7 @@ export default class index extends Component {
|
|||||||
<QueryTreeLayout
|
<QueryTreeLayout
|
||||||
loadData={this.loadTreeData}
|
loadData={this.loadTreeData}
|
||||||
defaultExpanded={true}
|
defaultExpanded={true}
|
||||||
onSelect={(key) => this.onSelectTree(key)}
|
onSelect={key => this.onSelectTree(key)}
|
||||||
replaceFields={{ value: 'code', title: 'name', children: 'children' }}
|
replaceFields={{ value: 'code', title: 'name', children: 'children' }}
|
||||||
>
|
>
|
||||||
<Container mode="fluid">
|
<Container mode="fluid">
|
||||||
@@ -259,12 +273,12 @@ export default class index extends Component {
|
|||||||
<Button
|
<Button
|
||||||
icon={<AntIcon type="plus" />}
|
icon={<AntIcon type="plus" />}
|
||||||
onClick={() => this.onOpen(this.addForm)}
|
onClick={() => this.onOpen(this.addForm)}
|
||||||
>新增{name}</Button>
|
>
|
||||||
|
新增{name}
|
||||||
|
</Button>
|
||||||
</Auth>
|
</Auth>
|
||||||
}
|
}
|
||||||
>
|
></QueryTable>
|
||||||
|
|
||||||
</QueryTable>
|
|
||||||
</Card>
|
</Card>
|
||||||
</Container>
|
</Container>
|
||||||
<ModalForm
|
<ModalForm
|
||||||
|
|||||||
398
web-react/src/pages/system/file/index.jsx
Normal file
398
web-react/src/pages/system/file/index.jsx
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
message as Message,
|
||||||
|
Popconfirm,
|
||||||
|
Select,
|
||||||
|
Tag,
|
||||||
|
Tooltip,
|
||||||
|
Upload,
|
||||||
|
} from 'antd'
|
||||||
|
import { AntIcon, Auth, Container, PhotoPreview, QueryTable, QueryTableActions } from 'components'
|
||||||
|
import { api } from 'common/api'
|
||||||
|
import auth from 'components/authorized/handler'
|
||||||
|
import { isEqual } from 'lodash'
|
||||||
|
import getDictData from 'util/dic'
|
||||||
|
import { toCamelCase } from 'util/format'
|
||||||
|
import { ArrayBufferToBase64, GetFileName, PreviewFileArrayBuffer } from 'util/file'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注释段[\/**\/]为必须要改
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置页面所需接口函数
|
||||||
|
*/
|
||||||
|
const apiAction = {
|
||||||
|
page: api.sysFileInfoPage,
|
||||||
|
delete: api.sysFileInfoDelete,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于弹窗标题
|
||||||
|
* [必要]
|
||||||
|
*/
|
||||||
|
const name = '/**/'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一配置权限标识
|
||||||
|
* [必要]
|
||||||
|
*/
|
||||||
|
const authName = 'sysFileInfo'
|
||||||
|
|
||||||
|
export default class index extends Component {
|
||||||
|
state = {
|
||||||
|
codes: {
|
||||||
|
fileStorageLocation: [],
|
||||||
|
},
|
||||||
|
|
||||||
|
uploading: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格实例
|
||||||
|
table = React.createRef()
|
||||||
|
|
||||||
|
photoPreview = React.createRef()
|
||||||
|
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
title: '文件名称',
|
||||||
|
dataIndex: 'fileOriginName',
|
||||||
|
width: 300,
|
||||||
|
ellipsis: {
|
||||||
|
showTitle: false,
|
||||||
|
},
|
||||||
|
sorter: true,
|
||||||
|
render: text => <Tooltip title={text}>{text}</Tooltip>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '文件后缀',
|
||||||
|
dataIndex: 'fileSuffix',
|
||||||
|
width: 120,
|
||||||
|
sorter: true,
|
||||||
|
render: text => <Tag color="green">{text}</Tag>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '文件大小',
|
||||||
|
dataIndex: 'fileSizeKb',
|
||||||
|
width: 120,
|
||||||
|
sorter: true,
|
||||||
|
render: text => (
|
||||||
|
<>
|
||||||
|
{text}
|
||||||
|
<small>KB</small>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '存储位置',
|
||||||
|
dataIndex: 'fileLocation',
|
||||||
|
width: 120,
|
||||||
|
sorter: true,
|
||||||
|
render: text => this.bindCodeValue(text, 'file_storage_location'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '文件仓库',
|
||||||
|
dataIndex: 'fileBucket',
|
||||||
|
width: 200,
|
||||||
|
ellipsis: {
|
||||||
|
showTitle: false,
|
||||||
|
},
|
||||||
|
sorter: true,
|
||||||
|
render: text => <Tooltip title={text}>{text}</Tooltip>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '唯一标识id',
|
||||||
|
dataIndex: 'fileObjectName',
|
||||||
|
width: 250,
|
||||||
|
ellipsis: {
|
||||||
|
showTitle: false,
|
||||||
|
},
|
||||||
|
sorter: true,
|
||||||
|
render: text => <Tooltip title={text}>{text}</Tooltip>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '上传时间',
|
||||||
|
dataIndex: 'createdTime',
|
||||||
|
width: 200,
|
||||||
|
sorter: true,
|
||||||
|
defaultSortOrder: 'descend',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数,在渲染前动态添加操作字段等
|
||||||
|
* @param {*} props
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
const flag = auth({ [authName]: 'delete' })
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
this.columns.push({
|
||||||
|
title: '操作',
|
||||||
|
width: 150,
|
||||||
|
dataIndex: 'actions',
|
||||||
|
render: (text, record) => (
|
||||||
|
<QueryTableActions>
|
||||||
|
<a onClick={() => this.onFileDownload(record)}>下载</a>
|
||||||
|
<Auth auth={{ [authName]: 'delete' }}>
|
||||||
|
<Popconfirm
|
||||||
|
placement="topRight"
|
||||||
|
title="是否确认删除"
|
||||||
|
onConfirm={() => this.onDelete(record)}
|
||||||
|
>
|
||||||
|
<a>删除</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</Auth>
|
||||||
|
{['png', 'jpeg', 'jpg', 'gif', 'tif', 'bmp'].includes(
|
||||||
|
record.fileSuffix
|
||||||
|
) && <a onClick={() => this.onFilePreview(record)}>预览</a>}
|
||||||
|
</QueryTableActions>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止外部组件引发的渲染,提升性能
|
||||||
|
* 可自行添加渲染条件
|
||||||
|
* [必要]
|
||||||
|
* @param {*} props
|
||||||
|
* @param {*} state
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
shouldComponentUpdate(props, state) {
|
||||||
|
return !isEqual(this.state, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载字典数据,之后开始加载表格数据
|
||||||
|
* 如果必须要加载字典数据,可直接对表格设置autoLoad=true
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
const { onLoading, onLoadData } = this.table.current
|
||||||
|
onLoading()
|
||||||
|
getDictData('file_storage_location').then(codes => {
|
||||||
|
this.setState({ codes }, () => {
|
||||||
|
onLoadData()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用加载数据接口,可在调用前对query进行处理
|
||||||
|
* [异步,必要]
|
||||||
|
* @param {*} params
|
||||||
|
* @param {*} query
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
loadData = async (params, query) => {
|
||||||
|
const { data } = await apiAction.page({
|
||||||
|
...params,
|
||||||
|
...query,
|
||||||
|
})
|
||||||
|
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 {*} record
|
||||||
|
*/
|
||||||
|
onOpen(modal, record) {
|
||||||
|
modal.current.open({
|
||||||
|
record,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对表格上的操作进行统一处理
|
||||||
|
* [异步]
|
||||||
|
* @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 {*} record
|
||||||
|
*/
|
||||||
|
onDelete(record) {
|
||||||
|
this.onAction(apiAction.delete(record), '删除成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region 自定义方法
|
||||||
|
async onFileUpload({ file }) {
|
||||||
|
this.setState({ uploading: true })
|
||||||
|
const table = this.table.current
|
||||||
|
table.onLoading()
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('file', file)
|
||||||
|
try {
|
||||||
|
await api.sysFileInfoUpload(fd)
|
||||||
|
table.onReloadData()
|
||||||
|
} catch {
|
||||||
|
table.onLoaded()
|
||||||
|
} finally {
|
||||||
|
this.setState({ uploading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onFilePreview({ id }) {
|
||||||
|
const key = Math.random().toString(16).slice(2)
|
||||||
|
const hide = Message.loading({
|
||||||
|
key,
|
||||||
|
content: '正在获取文件...',
|
||||||
|
duration: 0,
|
||||||
|
})
|
||||||
|
const file = await PreviewFileArrayBuffer(id)
|
||||||
|
if (file) {
|
||||||
|
const base64 = await ArrayBufferToBase64(file)
|
||||||
|
var img = new Image()
|
||||||
|
img.onload = () => {
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
src: base64,
|
||||||
|
w: img.naturalWidth,
|
||||||
|
h: img.naturalHeight,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
this.photoPreview.current.initPhotoSwipe(items)
|
||||||
|
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
img.onerror = () => {
|
||||||
|
Message.error({
|
||||||
|
key,
|
||||||
|
content: '获取文件失败',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
img.src = base64
|
||||||
|
} else {
|
||||||
|
Message.error({
|
||||||
|
key,
|
||||||
|
content: '获取文件失败',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onFileDownload({ id }) {
|
||||||
|
const key = Math.random().toString(16).slice(2)
|
||||||
|
const hide = Message.loading({
|
||||||
|
key,
|
||||||
|
content: '正在获取文件...',
|
||||||
|
duration: 0,
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
const { data, headers } = await api.sysFileInfoDownload({ id })
|
||||||
|
const url = window.URL.createObjectURL(data)
|
||||||
|
const fileName = GetFileName(headers['content-disposition'])
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
a.download = fileName
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
a.remove()
|
||||||
|
hide()
|
||||||
|
} catch {
|
||||||
|
Message.error({
|
||||||
|
key,
|
||||||
|
content: '下载文件失败',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { codes, uploading } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container mode="fluid">
|
||||||
|
<br />
|
||||||
|
<Card bordered={false}>
|
||||||
|
<QueryTable
|
||||||
|
ref={this.table}
|
||||||
|
autoLoad={false}
|
||||||
|
loadData={this.loadData}
|
||||||
|
columns={this.columns}
|
||||||
|
query={
|
||||||
|
<Auth auth={{ [authName]: 'page' }}>
|
||||||
|
<Form.Item label="文件名" name="fileOriginName">
|
||||||
|
<Input
|
||||||
|
autoComplete="off"
|
||||||
|
placeholder="请输入文件名"
|
||||||
|
className="w-200"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="存储位置" name="fileLocation">
|
||||||
|
<Select placeholder="请选择存储位置" className="w-200">
|
||||||
|
{codes.fileStorageLocation.map(item => (
|
||||||
|
<Select.Option key={item.code} value={item.code}>
|
||||||
|
{item.value}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="文件仓库" name="fileBucket">
|
||||||
|
<Input
|
||||||
|
autoComplete="off"
|
||||||
|
placeholder="请输入文件仓库"
|
||||||
|
className="w-200"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Auth>
|
||||||
|
}
|
||||||
|
operator={
|
||||||
|
<Auth auth={{ [authName]: 'add' }}>
|
||||||
|
<Upload customRequest={e => this.onFileUpload(e)} fileList={[]}>
|
||||||
|
<Button loading={uploading} icon={<AntIcon type="upload" />}>
|
||||||
|
上传文件
|
||||||
|
</Button>
|
||||||
|
</Upload>
|
||||||
|
</Auth>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<PhotoPreview ref={this.photoPreview} />
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
33
web-react/src/store/reducer/business.js
Normal file
33
web-react/src/store/reducer/business.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
const business = (state = {}, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'PATROL_INIT_GRADE_BY_COMPLETED_DATE':
|
||||||
|
{
|
||||||
|
const completedDate = state.completedDate || []
|
||||||
|
const { date } = action
|
||||||
|
const record = completedDate.find(p => p.id === date.id)
|
||||||
|
if (record) {
|
||||||
|
record.value = date.value
|
||||||
|
} else {
|
||||||
|
completedDate.push(date)
|
||||||
|
}
|
||||||
|
const _state = { ...state, completedDate }
|
||||||
|
return _state
|
||||||
|
}
|
||||||
|
case 'PATROL_REMOVE_INIT_GRADE_BY_COMPLETED_DATE':
|
||||||
|
{
|
||||||
|
const completedDate = state.completedDate || []
|
||||||
|
const record = completedDate.find(p => p.id === action.id)
|
||||||
|
if (!record) {
|
||||||
|
return state
|
||||||
|
} else {
|
||||||
|
completedDate.splice(completedDate.indexOf(record), 1)
|
||||||
|
const _state = { ...state, completedDate }
|
||||||
|
return _state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default business
|
||||||
@@ -3,12 +3,14 @@ import user from './user'
|
|||||||
import layout from './layout'
|
import layout from './layout'
|
||||||
import nav from './nav'
|
import nav from './nav'
|
||||||
import dictData from './dict-data'
|
import dictData from './dict-data'
|
||||||
|
import business from './business'
|
||||||
|
|
||||||
const combine = combineReducers({
|
const combine = combineReducers({
|
||||||
user,
|
user,
|
||||||
layout,
|
layout,
|
||||||
nav,
|
nav,
|
||||||
dictData
|
dictData,
|
||||||
|
business
|
||||||
})
|
})
|
||||||
|
|
||||||
export default combine
|
export default combine
|
||||||
@@ -7,14 +7,14 @@ const { getState, dispatch } = store
|
|||||||
|
|
||||||
const getDictData = async (...args) => {
|
const getDictData = async (...args) => {
|
||||||
const dictData = getState('dictData')
|
const dictData = getState('dictData')
|
||||||
let result = {}
|
let dict = {}
|
||||||
const code = []
|
const code = []
|
||||||
for (let i = 0; i < args.length; i++) {
|
for (let i = 0; i < args.length; i++) {
|
||||||
const codeName = toCamelCase(args[i])
|
const codeName = toCamelCase(args[i])
|
||||||
if (!dictData.hasOwnProperty(codeName)) {
|
if (!dictData.hasOwnProperty(codeName)) {
|
||||||
code.push(args[i])
|
code.push(args[i])
|
||||||
} else {
|
} else {
|
||||||
result[codeName] = dictData[codeName]
|
dict[codeName] = dictData[codeName]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,14 +29,17 @@ const getDictData = async (...args) => {
|
|||||||
value
|
value
|
||||||
})
|
})
|
||||||
|
|
||||||
result = { ...result, ...value }
|
dict = { ...dict, ...value }
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
return dictData
|
const result = {}
|
||||||
|
args.forEach(p => {
|
||||||
|
const codeName = toCamelCase(p)
|
||||||
|
result[codeName] = dict[codeName]
|
||||||
|
})
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getDictData
|
export default getDictData
|
||||||
@@ -8,31 +8,29 @@ import { token } from 'common/token'
|
|||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
||||||
focusUser: false,
|
focusUser: false,
|
||||||
focusPassword: false
|
focusPassword: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
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`)
|
||||||
|
|
||||||
focus = {
|
focus = {
|
||||||
user: false,
|
user: false,
|
||||||
password: false
|
password: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
form = React.createRef()
|
form = React.createRef()
|
||||||
|
|
||||||
onLogin = (values) => {
|
onLogin = values => {
|
||||||
this.setState({
|
this.setState({ loading: true })
|
||||||
loading: true
|
|
||||||
})
|
|
||||||
|
|
||||||
let { account, password } = values
|
let { account, password } = values
|
||||||
password = encryptByRSA(password, RSA_PUBLIC_KEY)
|
password = encryptByRSA(password, RSA_PUBLIC_KEY)
|
||||||
api.login({ account, password }).then(({ success, data, message }) => {
|
api.login({ account, password })
|
||||||
|
.then(({ success, data, message }) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
token.value = data
|
token.value = data
|
||||||
Message.success('登录成功')
|
Message.success('登录成功')
|
||||||
@@ -40,15 +38,16 @@ export default class index extends Component {
|
|||||||
} else {
|
} else {
|
||||||
Message.error(message)
|
Message.error(message)
|
||||||
}
|
}
|
||||||
}).catch(({ message }) => {
|
})
|
||||||
|
.catch(({ message }) => {
|
||||||
if (typeof message === 'object' && message[0]) {
|
if (typeof message === 'object' && message[0]) {
|
||||||
Message.error(message[0].messages[0])
|
Message.error(message[0].messages[0])
|
||||||
}
|
}
|
||||||
|
this.setState({ loading: false })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="yo-login">
|
<div className="yo-login">
|
||||||
<img src={this.backgroundImage.default} alt="" />
|
<img src={this.backgroundImage.default} alt="" />
|
||||||
@@ -62,8 +61,14 @@ export default class index extends Component {
|
|||||||
label="用户名"
|
label="用户名"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
onBlur={() => { this.setState({ focusUser: !!this.form.current.getFieldValue('account') }); }}
|
onBlur={() => {
|
||||||
onFocus={() => { this.setState({ focusUser: true }) }}
|
this.setState({
|
||||||
|
focusUser: !!this.form.current.getFieldValue('account'),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onFocus={() => {
|
||||||
|
this.setState({ focusUser: true })
|
||||||
|
}}
|
||||||
size="large"
|
size="large"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
@@ -75,8 +80,15 @@ export default class index extends Component {
|
|||||||
label="密码"
|
label="密码"
|
||||||
>
|
>
|
||||||
<Input.Password
|
<Input.Password
|
||||||
onBlur={() => { this.setState({ focusPassword: !!this.form.current.getFieldValue('password') }) }}
|
onBlur={() => {
|
||||||
onFocus={() => { this.setState({ focusPassword: true }) }}
|
this.setState({
|
||||||
|
focusPassword:
|
||||||
|
!!this.form.current.getFieldValue('password'),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onFocus={() => {
|
||||||
|
this.setState({ focusPassword: true })
|
||||||
|
}}
|
||||||
size="large"
|
size="large"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
@@ -89,7 +101,9 @@ export default class index extends Component {
|
|||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
size="large"
|
size="large"
|
||||||
type="primary"
|
type="primary"
|
||||||
>登录</Button>
|
>
|
||||||
|
登录
|
||||||
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
@@ -5,14 +5,15 @@ import 'nprogress/nprogress.css'
|
|||||||
import AntIcon from 'components/ant-icon'
|
import AntIcon from 'components/ant-icon'
|
||||||
import { Container } from 'components'
|
import { Container } from 'components'
|
||||||
|
|
||||||
NProgress.configure({ parent: '.ant-layout-content > .yo-tab-external-mount > .yo-tab-external-mount-content' });
|
NProgress.configure({
|
||||||
|
parent: '.ant-layout-content > .yo-tab-external-mount > .yo-tab-external-mount-content',
|
||||||
|
})
|
||||||
|
|
||||||
class ComponentDynamic extends Component {
|
class ComponentDynamic extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
// 组件内部组件的key,用于刷新
|
// 组件内部组件的key,用于刷新
|
||||||
key: null,
|
key: null,
|
||||||
component: null
|
component: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate() {
|
shouldComponentUpdate() {
|
||||||
@@ -32,8 +33,7 @@ class ComponentDynamic extends Component {
|
|||||||
|
|
||||||
// 在这里使用setTimeout调用,是防止打开窗口时卡顿
|
// 在这里使用setTimeout调用,是防止打开窗口时卡顿
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
|
let component
|
||||||
let component;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
component = await import(`../../../../pages${this.props.path}`)
|
component = await import(`../../../../pages${this.props.path}`)
|
||||||
@@ -41,19 +41,22 @@ class ComponentDynamic extends Component {
|
|||||||
component = await import('views/error/404')
|
component = await import('views/error/404')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
key: Math.random().toString(16).slice(2),
|
key: Math.random().toString(16).slice(2),
|
||||||
component: component.default
|
component: component.default,
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
})
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.component) {
|
if (this.state.component) {
|
||||||
return <this.state.component
|
return (
|
||||||
|
<this.state.component
|
||||||
key={this.state.key}
|
key={this.state.key}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
supportInfo={
|
supportInfo={
|
||||||
@@ -64,15 +67,15 @@ class ComponentDynamic extends Component {
|
|||||||
</Container>
|
</Container>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class index extends Component {
|
export default class index extends Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
actived: ''
|
actived: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
panes = []
|
panes = []
|
||||||
@@ -83,13 +86,13 @@ export default class index extends Component {
|
|||||||
|
|
||||||
static getDerivedStateFromProps(props) {
|
static getDerivedStateFromProps(props) {
|
||||||
return {
|
return {
|
||||||
actived: props.actived
|
actived: props.actived,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(activeKey) {
|
onChange(activeKey) {
|
||||||
this.props.parent.setState({
|
this.props.parent.setState({
|
||||||
actived: activeKey
|
actived: activeKey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +102,7 @@ export default class index extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onReload = (key) => {
|
onReload = key => {
|
||||||
key = key || this.state.actived
|
key = key || this.state.actived
|
||||||
const pane = this.panes.find(p => p.props.id === key)
|
const pane = this.panes.find(p => p.props.id === key)
|
||||||
if (pane) {
|
if (pane) {
|
||||||
@@ -108,7 +111,6 @@ export default class index extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
this.panes = []
|
this.panes = []
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -118,11 +120,10 @@ export default class index extends Component {
|
|||||||
type="editable-card"
|
type="editable-card"
|
||||||
hideAdd
|
hideAdd
|
||||||
activeKey={this.state.actived}
|
activeKey={this.state.actived}
|
||||||
onChange={(activeKey) => this.onChange(activeKey)}
|
onChange={activeKey => this.onChange(activeKey)}
|
||||||
onEdit={(targetKey, action) => this.onClose(targetKey, action)}
|
onEdit={(targetKey, action) => this.onClose(targetKey, action)}
|
||||||
>
|
>
|
||||||
{
|
{this.props.panes.map(pane => {
|
||||||
this.props.panes.map(pane => {
|
|
||||||
return (
|
return (
|
||||||
<Tabs.TabPane
|
<Tabs.TabPane
|
||||||
closable={pane.closable}
|
closable={pane.closable}
|
||||||
@@ -132,11 +133,37 @@ export default class index extends Component {
|
|||||||
trigger={['contextMenu']}
|
trigger={['contextMenu']}
|
||||||
overlay={
|
overlay={
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item key="0" onClick={() => this.onReload(pane.key)}>重新加载</Menu.Item>
|
<Menu.Item
|
||||||
|
key="0"
|
||||||
|
onClick={() => this.onReload(pane.key)}
|
||||||
|
>
|
||||||
|
重新加载
|
||||||
|
</Menu.Item>
|
||||||
<Menu.Divider />
|
<Menu.Divider />
|
||||||
<Menu.Item key="1" onClick={() => window.closeContentWindow(pane.key)}>关闭</Menu.Item>
|
<Menu.Item
|
||||||
<Menu.Item key="2" onClick={() => window.closeOtherContentWindow(pane.key)}>关闭其他标签页</Menu.Item>
|
key="1"
|
||||||
<Menu.Item key="3" onClick={() => window.closeRightContentWindow(pane.key)}>关闭右侧标签页</Menu.Item>
|
onClick={() =>
|
||||||
|
window.closeContentWindow(pane.key)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
关闭
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item
|
||||||
|
key="2"
|
||||||
|
onClick={() =>
|
||||||
|
window.closeOtherContentWindow(pane.key)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
关闭其他标签页
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item
|
||||||
|
key="3"
|
||||||
|
onClick={() =>
|
||||||
|
window.closeRightContentWindow(pane.key)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
关闭右侧标签页
|
||||||
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -148,17 +175,18 @@ export default class index extends Component {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div className="yo-tab-external-mount-content">
|
<div className="yo-tab-external-mount-content">
|
||||||
{
|
{this.props.panes.map(pane => {
|
||||||
this.props.panes.map(pane => {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={pane.key}
|
key={pane.key}
|
||||||
className={
|
className={
|
||||||
(pane.key === this.state.actived ? 'yo-tab-external-tabpane-active' : 'yo-tab-external-tabpane-inactive') + ' yo-tab-external-tabpane'
|
(pane.key === this.state.actived
|
||||||
|
? 'yo-tab-external-tabpane-active'
|
||||||
|
: 'yo-tab-external-tabpane-inactive') +
|
||||||
|
' yo-tab-external-tabpane'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ComponentDynamic
|
<ComponentDynamic
|
||||||
@@ -170,8 +198,7 @@ export default class index extends Component {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layout.Content>
|
</Layout.Content>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { withRouter } from 'react-router-dom'
|
import { withRouter } from 'react-router-dom'
|
||||||
import { Modal, message as Message } from 'antd'
|
import { Modal, message as Message, Dropdown, Button, Menu, Popover, Tag, Row, Col } from 'antd'
|
||||||
import { isEqual } from 'lodash'
|
import { isEqual } from 'lodash'
|
||||||
import store from 'store'
|
import store from 'store'
|
||||||
import { api } from 'common/api'
|
import { api } from 'common/api'
|
||||||
@@ -11,12 +11,8 @@ const { getState, dispatch, subscribe } = store
|
|||||||
|
|
||||||
const storePath = 'user'
|
const storePath = 'user'
|
||||||
|
|
||||||
let userOpenTimer, userCloseTimer
|
|
||||||
let initDropdownHeight
|
|
||||||
|
|
||||||
class User extends Component {
|
class User extends Component {
|
||||||
state = {
|
state = {
|
||||||
dropdownHeight: 0,
|
|
||||||
user: getState(storePath),
|
user: getState(storePath),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,40 +26,14 @@ class User extends Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldComponentUpdate(props, state) {
|
shouldComponentUpdate(props, state) {
|
||||||
// return !isEqual(this.state, state)
|
return !isEqual(this.state, state)
|
||||||
// }
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
initDropdownHeight = this.refs.dropdown.scrollHeight
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.unsubscribe()
|
this.unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpen = e => {
|
|
||||||
clearTimeout(userCloseTimer)
|
|
||||||
this.refs.container.classList.add('open')
|
|
||||||
userOpenTimer = setTimeout(() => {
|
|
||||||
this.refs.container.classList.add('drop')
|
|
||||||
this.setState({
|
|
||||||
dropdownHeight: initDropdownHeight,
|
|
||||||
})
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
|
|
||||||
onClose = e => {
|
|
||||||
clearTimeout(userOpenTimer)
|
|
||||||
this.refs.container.classList.remove('drop')
|
|
||||||
this.setState({
|
|
||||||
dropdownHeight: 0,
|
|
||||||
})
|
|
||||||
userCloseTimer = setTimeout(() => {
|
|
||||||
this.refs.container.classList.remove('open')
|
|
||||||
}, 300)
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccountSetting = () => {}
|
onAccountSetting = () => {}
|
||||||
|
|
||||||
onLogout = () => {
|
onLogout = () => {
|
||||||
@@ -84,48 +54,74 @@ class User extends Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
renderMenu() {
|
||||||
|
const { user } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<>
|
||||||
className="user-container"
|
<div className="p-md pb-xs">
|
||||||
onMouseEnter={e => {
|
<Row align="bottom" justify="space-between">
|
||||||
this.onOpen(e)
|
<Col>
|
||||||
}}
|
<b className="h5">{user.nickName || user.name}</b>
|
||||||
onMouseLeave={e => {
|
</Col>
|
||||||
this.onClose(e)
|
<Col>
|
||||||
}}
|
<span className="text-gray">{user.account}</span>
|
||||||
ref="container"
|
</Col>
|
||||||
>
|
</Row>
|
||||||
|
<p className="text-gray">上次登录时间:{user.lastLoginTime}</p>
|
||||||
|
{user.adminType === 1 && (
|
||||||
|
<Tag color="pink" className="mb-xs">
|
||||||
|
超级管理员
|
||||||
|
</Tag>
|
||||||
|
)}
|
||||||
|
{user.roles &&
|
||||||
|
user.roles.map(role => (
|
||||||
|
<Tag color="purple" className="mb-xs">
|
||||||
|
{role.name}
|
||||||
|
</Tag>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<Menu selectable={false}>
|
||||||
|
<Menu.Divider />
|
||||||
|
<Menu.Item key="1">
|
||||||
|
<AntIcon type="user" className="mr-sm" />
|
||||||
|
个人中心
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item key="2">其他菜单</Menu.Item>
|
||||||
|
<Menu.Item key="3">其他菜单</Menu.Item>
|
||||||
|
<Menu.Item key="4">其他菜单</Menu.Item>
|
||||||
|
<Menu.Divider />
|
||||||
|
<Menu.Item key="-1" onClick={() => this.onLogout()}>
|
||||||
|
<AntIcon type="logout" className="mr-sm" />
|
||||||
|
退出登录
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { user } = this.state
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="user-container">
|
||||||
<div className="user-container-inner">
|
<div className="user-container-inner">
|
||||||
|
<Popover
|
||||||
|
arrowPointAtCenter={true}
|
||||||
|
overlayClassName="yo-user-popover"
|
||||||
|
placement="bottomRight"
|
||||||
|
content={this.renderMenu()}
|
||||||
|
>
|
||||||
<div className="user--base">
|
<div className="user--base">
|
||||||
<Image
|
<Image
|
||||||
width="32"
|
width="32"
|
||||||
type="avatar"
|
type="avatar"
|
||||||
className="user--avatar"
|
className="user--avatar"
|
||||||
icon={<AntIcon type="user" />}
|
icon={<AntIcon type="user" />}
|
||||||
id={this.state.user.avatar}
|
id={user.avatar}
|
||||||
/>
|
/>
|
||||||
<span className="user--name">
|
|
||||||
{this.state.user.nickName || this.state.user.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="user--dropdown"
|
|
||||||
ref="dropdown"
|
|
||||||
style={{ height: `${this.state.dropdownHeight}px` }}
|
|
||||||
>
|
|
||||||
<ul className="ant-dropdown-menu ant-dropdown-menu-vertical">
|
|
||||||
<li className="ant-dropdown-menu-item" onClick={this.onAccountSetting}>
|
|
||||||
<AntIcon type="user" />
|
|
||||||
个人中心
|
|
||||||
</li>
|
|
||||||
<li className="ant-dropdown-menu-item-divider"></li>
|
|
||||||
<li className="ant-dropdown-menu-item" onClick={this.onLogout}>
|
|
||||||
<AntIcon type="logout" />
|
|
||||||
退出登录
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -232,21 +232,24 @@ export default class index extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />
|
const { loading, panes, actived } = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="yo-layout--spin">
|
<section className="yo-layout--spin">
|
||||||
<Spin spinning={this.state.loading} indicator={antIcon}>
|
<Spin
|
||||||
|
spinning={loading}
|
||||||
|
indicator={
|
||||||
|
<div className="loader-container">
|
||||||
|
<p>Loading</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
<Layout className="yo-layout--top-nav--container-fluid yo-layout--top-nav">
|
<Layout className="yo-layout--top-nav--container-fluid yo-layout--top-nav">
|
||||||
<Layout>
|
<Layout>
|
||||||
<Header />
|
<Header />
|
||||||
<Layout className="yo-nav-theme--light">
|
<Layout className="yo-nav-theme--light">
|
||||||
<Sider />
|
<Sider />
|
||||||
<Content
|
<Content parent={this} panes={panes} actived={actived} />
|
||||||
parent={this}
|
|
||||||
panes={this.state.panes}
|
|
||||||
actived={this.state.actived}
|
|
||||||
/>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
Reference in New Issue
Block a user