|  | @ -4,27 +4,40 @@ import { connect } from 'react-redux'; | 
			
		
	
		
		
			
				
					|  |  | import { Modal, Form, Button, Notification } from '@douyinfe/semi-ui'; |  |  | import { Modal, Form, Button, Notification } from '@douyinfe/semi-ui'; | 
			
		
	
		
		
			
				
					|  |  | import { IconUpload } from '@douyinfe/semi-icons'; |  |  | import { IconUpload } from '@douyinfe/semi-icons'; | 
			
		
	
		
		
			
				
					|  |  | import XLSX from 'xlsx'; |  |  | import XLSX from 'xlsx'; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | import moment from 'moment'; | 
			
		
	
		
		
			
				
					|  |  | import { contractDetailsColumnKeys } from '../../constants/index'; |  |  | import { contractDetailsColumnKeys } from '../../constants/index'; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | const ColumnDateKey = ['applyDate', 'recConDate', 'acceptanceDate', 'backConfirmDate']; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | const ColumnDateName = ['申请日期', '收到合同日期', '验收日期', '收入确认时间']; | 
			
		
	
		
		
			
				
					|  |  | //下载模板和上传文件读取
 |  |  | //下载模板和上传文件读取
 | 
			
		
	
		
		
			
				
					|  |  | const ImportContractDetailsModal = props => { |  |  | const ImportContractDetailsModal = props => { | 
			
		
	
		
		
			
				
					|  |  |     const { dispatch, actions, onCancel } = props; |  |  |     const { dispatch, actions, onCancel } = props; | 
			
		
	
		
		
			
				
					
					|  |  |     const { humanAffairs } = actions; |  |  |     const { businessManagement } = actions; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |     const [msg, setMsg] = useState(''); |  |  |     const [msg, setMsg] = useState(''); | 
			
		
	
		
		
			
				
					|  |  |     const [loading, setLoading] = useState(''); |  |  |     const [loading, setLoading] = useState(''); | 
			
		
	
		
		
			
				
					|  |  |     const [postData, setPostData] = useState([]); |  |  |     const [postData, setPostData] = useState([]); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const [uploadAble, setUploadAble] = useState(false); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const [allNumbers, setAllNumbers] = useState([]); | 
			
		
	
		
		
			
				
					|  |  |     //初始化
 |  |  |     //初始化
 | 
			
		
	
		
		
			
				
					|  |  |     useEffect(() => { |  |  |     useEffect(() => { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         //查询明细表已存在编号数据接口通用
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         dispatch(businessManagement.getReceivedNumbers({ tableModel: 'ContractDetail' })).then(r => { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if (r.success) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 setUploadAble(true); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 setAllNumbers(r.payload.data); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         }) | 
			
		
	
		
		
			
				
					|  |  |     }, []); |  |  |     }, []); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     const confirm = () => { |  |  |     const confirm = () => { | 
			
		
	
		
		
			
				
					|  |  |         if (postData.length) { |  |  |         if (postData.length) { | 
			
		
	
		
		
			
				
					|  |  |             setLoading(true) |  |  |             setLoading(true) | 
			
		
	
		
		
			
				
					
					|  |  |             // dispatch(humanAffairs.addSalesMemberBulk(postData)).then(res => {
 |  |  |             //导入明细接口通用
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             //     if (res.success) {
 |  |  |             dispatch(businessManagement.importBackDetails(postData, { tableModel: 'ContractDetail' })).then(res => { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             //         onCancel()
 |  |  |                 if (res.success) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             //     }
 |  |  |                     onCancel() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             //     setLoading(false)
 |  |  |                 } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             // })
 |  |  |                 setLoading(false) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             }) | 
			
		
	
		
		
			
				
					|  |  |         } else { |  |  |         } else { | 
			
		
	
		
		
			
				
					|  |  |             Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 }) |  |  |             Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 }) | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
	
		
		
			
				
					|  | @ -94,9 +107,29 @@ const ImportContractDetailsModal = props => { | 
			
		
	
		
		
			
				
					|  |  |         }) |  |  |         }) | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     const judgeNullTime = (v) => { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         //注意的点:xlsx将excel中的时间内容解析后,会小一天
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         //如2020/8/1,xlsx会解析成  Fri Jul 31 2020 23:59:17 GMT+0800    小了43秒  
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         let a = new Date(v); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         a.setTime(a.getTime() + 43 * 1000); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         return v ? a : null; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |     const judgeNull = (value) => { |  |  |     const judgeTimeValid = (time) => { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |         return value ? String(value).trim().replace(/\s*/g, "") : null; |  |  |         let valid = true; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |         if (!time) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             return valid;//可以不填
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         const ymd = /^((19|20)[0-9]{2})[\/\-]((0[1-9])|(1[0-2]))[\/\-]((0[1-9])|((1|2)[0-9])|(3[0-1]))$/;//年月日
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         if (time instanceof Date) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             let timeStr = moment(time).format('YYYY/MM/DD'); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if (!ymd.test(timeStr)) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 valid = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             valid = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         return valid; | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     return ( |  |  |     return ( | 
			
		
	
	
		
		
			
				
					|  | @ -137,12 +170,51 @@ const ImportContractDetailsModal = props => { | 
			
		
	
		
		
			
				
					|  |  |                                 return |  |  |                                 return | 
			
		
	
		
		
			
				
					|  |  |                             } |  |  |                             } | 
			
		
	
		
		
			
				
					|  |  |                             let postData = []; |  |  |                             let postData = []; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             let yearPattern = /^(19|20)\d{2}$/;//1900-2099年
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             let zzsPattern = /^[+]{0,1}(\d+)$/;//正整数
 | 
			
		
	
		
		
			
				
					|  |  |                             for (let i = 0; i < res.length; i++) { |  |  |                             for (let i = 0; i < res.length; i++) { | 
			
		
	
		
		
			
				
					|  |  |                                 let d = res[i]; |  |  |                                 let d = res[i]; | 
			
		
	
		
		
			
				
					|  |  |                                 let obj = {}; |  |  |                                 let obj = {}; | 
			
		
	
		
		
			
				
					|  |  |                                 Object.keys(contractDetailsColumnKeys).map(key => { |  |  |                                 Object.keys(contractDetailsColumnKeys).map(key => { | 
			
		
	
		
		
			
				
					
					|  |  |                                     obj[key] = d[contractDetailsColumnKeys[key]] || ''; |  |  |                                     //四个日期验证“申请日期”、“收到合同日期”、“验收日期”、“收入确认时间”
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                                     if (ColumnDateKey.indexOf(key) != -1) {//两个时间
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         obj[key] = judgeNullTime(d[contractDetailsColumnKeys[key]]); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         obj[key] = d[contractDetailsColumnKeys[key]] || null; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     } | 
			
		
	
		
		
			
				
					|  |  |                                 }) |  |  |                                 }) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 //年度 序号 编号必填
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 if (!obj.year || !obj.serialNo || !obj.number) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     error(`第${i + 2}行【年度】、【序号】、【编号】存在空值,请填写`) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     return | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 //年度
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 if (obj.year && !yearPattern.test(obj.year)) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     error(`第${i + 2}行【年度】填写错误`) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     return | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 //序号 正整数
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 if (obj.serialNo && !zzsPattern.test(obj.serialNo)) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     error(`第${i + 2}行【序号】填写错误,需要为非负整数`) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     return | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 let exist = allNumbers.find(m => m.number == obj.number);//数据库中 已有该编号
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 if (exist) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     error(`第${i + 2}行的【编号】在系统中已存在`) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     return | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 if (postData.some(p => p.number == obj.number)) {//编号 唯一
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     error(`第${i + 2}行【编号】重复,请更改后重新上传`) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     return | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 for (let k = 0; k < ColumnDateKey.length; k++) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     let cValid = judgeTimeValid(obj[ColumnDateKey[k]]); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     if (!cValid) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         error(`第${i + 2}行【${ColumnDateName[k]}】错误,请填写yyyy/mm/dd格式`) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         return | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |                                 postData.push(obj); |  |  |                                 postData.push(obj); | 
			
		
	
		
		
			
				
					|  |  |                             } |  |  |                             } | 
			
		
	
		
		
			
				
					|  |  |                             setPostData(postData) |  |  |                             setPostData(postData) | 
			
		
	
	
		
		
			
				
					|  | @ -151,7 +223,7 @@ const ImportContractDetailsModal = props => { | 
			
		
	
		
		
			
				
					|  |  |                             onSuccess({ message: msg }) |  |  |                             onSuccess({ message: msg }) | 
			
		
	
		
		
			
				
					|  |  |                         }) |  |  |                         }) | 
			
		
	
		
		
			
				
					|  |  |                     }}> |  |  |                     }}> | 
			
		
	
		
		
			
				
					
					|  |  |                     <Button icon={<IconUpload />} theme="light"> |  |  |                     <Button icon={<IconUpload />} theme="light" disabled={!uploadAble}> | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                         请选择文件 |  |  |                         请选择文件 | 
			
		
	
		
		
			
				
					|  |  |                     </Button> |  |  |                     </Button> | 
			
		
	
		
		
			
				
					|  |  |                 </Form.Upload> |  |  |                 </Form.Upload> | 
			
		
	
	
		
		
			
				
					|  | 
 |