4 changed files with 280 additions and 8 deletions
			
			
		| @ -0,0 +1,225 @@ | |||
| 'use strict'; | |||
| import React, { useState, useEffect } from 'react'; | |||
| import { connect } from 'react-redux'; | |||
| import moment from 'moment'; | |||
| import { Modal, Form, Button, Notification } from '@douyinfe/semi-ui'; | |||
| import { IconUpload } from '@douyinfe/semi-icons'; | |||
| import XLSX from 'xlsx'; | |||
| import { performanceSummaryKeys } from '../../constants/index'; | |||
| //下载模板和上传文件读取 | |||
| const ImportPerformanceSummaryModal = props => { | |||
|     const { dispatch, actions, onCancel } = props; | |||
|     const { businessManagement } = actions | |||
|     const [msg, setMsg] = useState(''); | |||
|     const [loading, setLoading] = useState(''); | |||
|     const [postData, setPostData] = useState([]); | |||
|     //初始化 | |||
|     useEffect(() => { | |||
|     }, []); | |||
| 
 | |||
|     const confirm = () => { | |||
|         if (postData.length) { | |||
|             setLoading(true) | |||
|             dispatch(businessManagement.importAchieveDetails(postData)).then(res => { | |||
|                 if (res.success) { | |||
|                     onCancel() | |||
|                 } | |||
|                 setLoading(false) | |||
|             }) | |||
|         } else { | |||
|             Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 }) | |||
|         } | |||
|     } | |||
| 
 | |||
|     const dldCsvMb = () => { | |||
|         //表头 | |||
|         let head = []; | |||
|         Object.keys(performanceSummaryKeys).map(key => { | |||
|             head.push(performanceSummaryKeys[key]); | |||
|         }) | |||
|         head = head.join(',') + "\n"; | |||
|         //数据 | |||
|         //let data = 1 + ',' + 2 + ',' + 3 + ',' + 4 + ',' + 5 | |||
|         let templateCsv = "data:text/csv;charset=utf-8,\ufeff" + head; | |||
|         //创建一个a标签 | |||
|         let link = document.createElement("a"); | |||
|         //为a标签设置属性 | |||
|         link.setAttribute("href", templateCsv); | |||
|         link.setAttribute("download", "业绩汇总表导入模板.csv"); | |||
|         //点击a标签 | |||
|         link.click(); | |||
|     } | |||
|     const download = () => { | |||
|         dldCsvMb(); | |||
|     } | |||
| 
 | |||
|     const fileLimit = '.csv'; | |||
| 
 | |||
|     const getFileBlob = (url) => { | |||
|         return new Promise((resolve, reject) => { | |||
|             let request = new XMLHttpRequest() | |||
|             request.open("GET", url, true) | |||
|             request.responseType = "blob" | |||
|             request.onreadystatechange = e => { | |||
|                 if (request.readyState == 4) { | |||
|                     if (request.status == 200) { | |||
|                         if (window.FileReader) { | |||
|                             let reader = new FileReader(); | |||
|                             reader.readAsBinaryString(request.response); | |||
|                             reader.onload = event => { | |||
|                                 try { | |||
|                                     const { result } = event.target; | |||
|                                     // 以二进制流方式读取得到整份excel表格对象 | |||
|                                     const workbook = XLSX.read(result, { | |||
|                                         type: "binary", | |||
|                                         cellDates: true,//设为true,将天数的时间戳转为时间格式 | |||
|                                         codepage: 936//解决了乱码问题 | |||
|                                     }); | |||
|                                     let data = []; // 存储获取到的数据 | |||
|                                     // 遍历每张工作表进行读取(这里默认只读取第一张表) | |||
|                                     for (const sheet in workbook.Sheets) { | |||
|                                         if (workbook.Sheets.hasOwnProperty(sheet)) { | |||
|                                             data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet])); | |||
|                                         } | |||
|                                     } | |||
|                                     resolve(data);//导出数据 | |||
|                                 } catch (e) { | |||
|                                     reject("失败"); | |||
|                                 } | |||
|                             } | |||
|                         } | |||
|                     } | |||
|                 } | |||
|             } | |||
|             request.send(); | |||
|         }) | |||
|     } | |||
| 
 | |||
| 
 | |||
|     // const judgeNull = (value) => { | |||
|     //     return value ? String(value).trim().replace(/\s*/g, "") : null; | |||
|     // } | |||
| 
 | |||
|     // 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 judgeTimeValid = (time) => { | |||
|         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 ( | |||
|         <Modal | |||
|             title="导入" visible={true} | |||
|             onOk={confirm} width={620} | |||
|             confirmLoading={loading} | |||
|             onCancel={() => { | |||
|                 setMsg('') | |||
|                 setLoading(false) | |||
|                 setPostData([]) | |||
|                 onCancel() | |||
|             }} | |||
|         > | |||
|             <div style={{ borderBottom: '1px solid #DCDEE0', margin: '0px -24px' }}></div> | |||
|             <Form> | |||
|                 <Form.Upload | |||
|                     label={'业绩明细表'} labelPosition='left' | |||
|                     action={'/'} accept={fileLimit} | |||
|                     maxSize={200} limit={1} | |||
|                     onRemove={(currentFile, fileList, fileItem) => { | |||
|                         setMsg(''); | |||
|                         setPostData([]); | |||
|                     }} | |||
|                     customRequest={(data) => { | |||
|                         const { file, onSuccess, onError } = data | |||
|                         getFileBlob(file.url).then(res => { | |||
| 
 | |||
|                             const error = (msg) => { | |||
|                                 setMsg(msg) | |||
|                                 onError({ message: msg }) | |||
|                             } | |||
|                             if (res.length > 1000) { | |||
|                                 error('一次性上传数据行数应小于1000行,请分批上传') | |||
|                                 return | |||
|                             } | |||
|                             if (!res.length) { | |||
|                                 error('请填写至少一行数据') | |||
|                                 return | |||
|                             } | |||
|                             let postData = []; | |||
|                             let zzsPattern = /^[+]{0,1}(\d+)$/;//正整数 | |||
|                             for (let i = 0; i < res.length; i++) { | |||
|                                 let d = res[i]; | |||
|                                 let obj = {}; | |||
|                                 Object.keys(performanceSummaryKeys).map(key => { | |||
|                                     obj[key] = d[performanceSummaryKeys[key]] || null; | |||
|                                     //} | |||
|                                 }) | |||
|                                 let tValid = judgeTimeValid(obj.recConDate); | |||
|                                 // if (!tValid) { | |||
|                                 //     error(`第${i + 2}行【收到合同日期】错误,请填写yyyy/mm/dd格式`) | |||
|                                 //     return | |||
|                                 // } | |||
| 
 | |||
|                                 // if (obj.isApproval && ['是', '否'].indexOf(obj.isApproval) == -1) { | |||
|                                 //     error(`第${i + 2}行【价格是否特批】错误,请填写是或否`) | |||
|                                 //     return | |||
|                                 // } | |||
|                                 // //复购次数 正整数 | |||
|                                 // if (obj.repurchaseCount && !zzsPattern.test(obj.repurchaseCount)) { | |||
|                                 //     error(`第${i + 2}行【复购次数】填写错误,需要为非负整数`) | |||
|                                 //     return | |||
|                                 // } | |||
| 
 | |||
|                                 // if (obj.reproducible && ['是', '否'].indexOf(obj.reproducible) == -1) { | |||
|                                 //     error(`第${i + 2}行【是否可复制的业务路径】错误,请填写是或否`) | |||
|                                 //     return | |||
|                                 // } | |||
|                                 postData.push(obj); | |||
|                             } | |||
|                             setPostData(postData) | |||
|                             console.log(postData,'======================='); | |||
|                             let msg = '文件解析完成,点击确定按钮上传保存!' | |||
|                             setMsg(msg) | |||
|                             onSuccess({ message: msg }) | |||
|                         }) | |||
|                     }}> | |||
|                     <Button icon={<IconUpload />} theme="light"> | |||
|                         请选择文件 | |||
|                     </Button> | |||
|                 </Form.Upload> | |||
|                 <span>{msg}</span> | |||
|                 <div style={{ color: '#ccc' }}>最大不超过200M,导入文件需与 | |||
|                     <span onClick={() => download()} style={{ cursor: 'pointer', color: '#0066FF' }}>导入模板</span> | |||
|                     一致</div> | |||
|             </Form> | |||
|         </Modal > | |||
|     ) | |||
| } | |||
| 
 | |||
| function mapStateToProps(state) { | |||
|     const { auth, global } = state; | |||
|     return { | |||
|         user: auth.user, | |||
|         actions: global.actions, | |||
|     } | |||
| } | |||
| 
 | |||
| export default connect(mapStateToProps)(ImportPerformanceSummaryModal); | |||
					Loading…
					
					
				
		Reference in new issue