title: 表单添加多组规则 date: 2021-07-30 tags: - antd
起因
框架react+ant3(老项目重构很难)
新版本一个需求原型如下:[
可以有多个规则,且规则之间时间需要连续。上一个结束时间的第二天要是下一个规则的开始时间。
如果第一个结束时间是7月30号,下个月的开始时间要是7.31号。依次类推。
还要可以批量设置。就是一次性设置多个。
首先肯定想到的是用数组map,用的form表单。就新建一个数组arr=[0] ,点击添加按钮的时候就再push 一个0,删除按钮就arr.splice(index,1) ,index是当前元素下标。但是form.item 的依赖字段会重复。
然后只能自己用datePicker、Input 还有框架封装好的获取企业Id的模糊查询的组件。
且有规则后再修改可以回显数据。
如下:
这是外层的Modal:
因为批量多个参数逗号分隔。
初始化indexOf 判断有没有逗号,是单个还是批量,单个的话就获取数据,且把获取到的数据通过props传到子组件当中。因为render是先render。所以这里用个flag。保证获取到的数据可以传到子组件。
再把需要的一些方法传到子组件当中。
子组件中,通过onChange 获取到值放到一个对象中添加到数组里。
添加的时候获取到当前的结束时间。通过moment().add(1,'day') 当然这里要判断是不是数组中的第一个
还有就是对时间的判断。
因为时间的连续的删除只能删除最后一个。
基本完成了功能,但是感觉很冗余,还要修改,一些细节还要完善。
import React,{Component} from 'react'
import { Form, Button, Input, message } from "antd"
import fetchHandler from '@/fetch/fetchHandler'
import TrusteeshipForm from './TrusteeshipForm';
import moment from 'moment';
import {settlementSetting,getSettlementSetting} from '@/fetch/fetchApi'
class Trusteeship extends Component {
constructor(props) {
super(props)
this.props = props
this.state = {
domArr : [],
stubId:this.props.stubId,
info:[],
flag:true
}
}
componentWillMount() {
this.getInfo()
}
async getInfo () {
if(this.props.stubId.indexOf(',')>0) {
return
}
this.setState({
flag:false
})
await fetchHandler(getSettlementSetting,{
stubId:this.props.stubId
}).then( (res)=>{
if(res&&res.code==='success') {
const domArr = []
res.data.map((item,index)=>{
let obj = {}
obj.unitPrice = item.unitPrice
obj.paymentCompanyId=item.paymentCompanyId
obj.startDate = moment(item.startDate).format("YYYY-MM-DD")
obj.endDate = moment(item.endDate).format("YYYY-MM-DD")
obj.companyName = item.companyName
domArr.push(obj)
})
this.setState({
domArr,
info:res.data,
flag:true
})
}
})
}
onAdd = (newArr)=>{
this.setState({
domArr:newArr
})
}
onDel = ()=>{
const domArr = this.state.domArr
domArr.splice(domArr.length-1,1)
this.setState({
domArr
})
}
getDetaios(arr) {
for (var i in arr) {
if (arr[i] == null) {
return true
}
}
return false
}
onChange = (obj)=>{
this.props.form.setFieldsValue({
stubPeriodSetting: obj
})
}
onFinish = (e) => {
const domArr = this.state.domArr
const isNull = this.getDetaios(domArr[domArr.length-1])
console.log(domArr);
if(isNull) {
message.warning("存在未填项或开始时间在结束时间之前,请检查")
return
}
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
values.stubIds = this.state.stubId
fetchHandler(settlementSetting,values ).then((res) => {
console.log(res);
if (res.code === "success") {
message.success("保存成功!")
this.props.fresh()
this.props.onCancel()
}
})
}
});
};
setFlag () {
this.setState({
flag:true
})
}
render () {
const {getFieldDecorator} = this.props.form
const {domArr,flag,info} = this.state
console.log(domArr);
console.log(info);
return (
<Form
name="basic"
onSubmit={this.onFinish}
>
<h5>收费规则</h5>
{flag? <div><Form.Item label="合同编号" style={{ display:"flex" }} >
{getFieldDecorator('concatNo', {
rules: [{ required: true, message: '该项是必填项' }],
initialValue: (info.length!==0)?info[0].concatNo:""
})(
<Input style={{ 'width': '300px' }} placeholder="请输入合同编号" />,
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('stubPeriodSetting', {
rules: [{ required: true, message: '该项是必填项',type: 'array' }],
initialValue: ""
})(
<TrusteeshipForm
setFlag={()=>{this.setFlag}}
domArr={domArr}
onAdd = {this.onAdd}
onDel={this.onDel}
onChange={this.onChange} />,
)}
</Form.Item></div>:""}
<Form.Item style={{display: "flex",justifyContent:"center"}}>
<Button type="dashed" htmlType="submit">
保存
</Button>
</Form.Item>
</Form>
)
}
}
Trusteeship = Form.create({})(Trusteeship)
export default Trusteeship
import React, {
PureComponent
} from 'react';
import { Form, Button, Input, message,DatePicker } from "antd"
import fetchHandler from '@/fetch/fetchHandler'
import {companyList } from '@/fetch/fetchApi'
import AutoSearch from '@/components/display/input/AutoSearch';
import moment from 'moment';
class TrusteeshipForm extends PureComponent {
constructor(props) {
super(props);
this.props = props
this.state = {
domArr :this.props.domArr
}
}
style = {
display: 'flex',
alignItems:"center",
marginBottom:"20px"
}
getDetaios(arr) {
for (var i in arr) {
if (arr[i] == null) {
return true
}
}
return false
}
componentDidMount () {
this.props.onChange(this.state.domArr)
}
onAdd = ()=>{
const {domArr} = this.state
this.props.setFlag()
if(domArr.length>=10) {
message.warning("最多添加10条!")
return
}
if(this.getDetaios(domArr[domArr.length-1])) {
message.warning("存在未填项或数据不正确,请检查!")
return
}
let nextStartDate = moment(new Date()).format("YYYY-MM-DD")
let nextEndDate = moment(new Date()).add(7,'day').format("YYYY-MM-DD")
if(domArr.length>0) {
nextStartDate = moment(domArr[domArr.length-1].endDate).add(1,'day').format("YYYY-MM-DD")
nextEndDate = moment(nextStartDate).add(7,'day').format("YYYY-MM-DD")
}
const obj ={
unitPrice:null,
paymentCompanyId:null,
startDate:nextStartDate,
endDate: nextEndDate,
}
domArr.push(obj)
this.setState({
domArr,
},()=>{
this.props.onAdd(domArr)
}
)
}
startChange (startDate,index) {
const domArr = this.state.domArr
const time = moment(startDate).diff(moment(domArr[index].endDate))
if(time>0) {
message.warning("开始时间必须在结束时间之前!")
return
}
domArr[index].startDate = startDate
this.setState({
domArr
},()=>{
const domArr = this.state.domArr
this.props.onChange(domArr)
this.props.onAdd(domArr)
})
}
endChange (endDate,index) {
const domArr = this.state.domArr
let time
if( domArr[index+1]) {
time = moment(endDate).diff(moment(domArr[index+1].endDate))
}
if(time>0||time===0) {
domArr.forEach((item,i)=>{
if(i>index) {
item.endDate = null
item.startDate = null
}
})
}
if(domArr[index+1]) {
domArr[index+1].startDate = moment(endDate).add(1,'day').format("YYYY-MM-DD")
}
domArr[index].endDate = endDate
this.setState({
domArr
},()=>{
const domArr = this.state.domArr
this.props.onChange(domArr)
this.props.onAdd(domArr)
})
}
feeChange (fee,index) {
const domArr = this.state.domArr
domArr[index].unitPrice = fee
this.setState({
domArr
},()=>{
const domArr = this.state.domArr
this.props.onChange(domArr)
this.props.onAdd(domArr)
})
}
companyChange (e,index) {
const domArr = this.state.domArr
domArr[index].paymentCompanyId = e
this.setState({
domArr
},()=>{
const domArr = this.state.domArr
this.props.onChange(domArr)
this.props.onAdd(domArr)
})
}
render() {
const {domArr} = this.state
return <div style={{width:"552px"}}>
{domArr&&domArr.map((item,index)=>{
return <div key={index}>
<div style={this.style}>
<label><span style={{color:"red"}}>*</span> 时间周期:</label>
<DatePicker
placeholder="开始时间"
disabled={index!==0}
value = {moment(item.startDate,"YYYY-MM-DD")}
onChange={(e,date)=>{
this.startChange(date,index)
}}/>
<span>—</span>
<DatePicker
placeholder="结束时间"
defaultValue={moment(item.endDate,"YYYY-MM-DD")}
disabledDate={(current)=> {
return current && current <moment(item.startDate)
}}
onChange={(e,date)=>{
this.endChange(date,index)
}} />
</div>
<div style={this.style}>
<label><span style={{color:"red"}}>*</span> 托管费用:</label>
<Input
defaultValue={item.unitPrice}
type="number"
style={{ 'width': '300px' }}
onChange={(e)=>{
this.feeChange(e.target.value,index)
}}
placeholder="请输入托管费用" addonAfter="元/年" />
</div>
<div style={this.style}>
<label><span style={{color:"red"}}>*</span> 承担企业:</label>
<AutoSearch
key={item.companyName||'add'}
placeholder='请输入商户名称模糊搜索'
config={{
allowClear: true,
showParam: 'companyName',
choseParam: 'companyId',
sourceApi: companyList,
initialValue: item.companyName,
fetchParams:{
status:1
}
}}
module='company'
setValue={(e) => {
this.companyChange(e,index)
}}
/>
</div>
<hr/>
</div>
}) }
<div style={{display: "flex",justifyContent:"center"}}>
<Button type="primary" onClick={()=>{
this.onAdd()
}}> 添加规则</Button>
{domArr&&domArr.length!==0? <Button style={{marginLeft:"20px"}} type="primary" onClick={()=>{
this.props.onDel()
}}>删除</Button>:""}
</div>
</div>
}
}
TrusteeshipForm = Form.create({})(TrusteeshipForm)
export default TrusteeshipForm;
|