3 changed files with 222 additions and 72 deletions
			
			
		| @ -1,70 +0,0 @@ | |||||
| import React, { useEffect, useState } from 'react'; |  | ||||
| import { Modal, Form, Button, Upload } from '@douyinfe/semi-ui'; |  | ||||
| import { IconUpload } from '@douyinfe/semi-icons'; |  | ||||
| import ExportJsonExcel from 'js-export-excel'; |  | ||||
| const ExportMembersModal = (props) => { |  | ||||
|     const { onCancel, user } = props; |  | ||||
|     useEffect(() => { |  | ||||
| 
 |  | ||||
|     }, []); |  | ||||
| 
 |  | ||||
|     const handleOk = () => { |  | ||||
| 
 |  | ||||
|     } |  | ||||
| 
 |  | ||||
|     const download = () => { |  | ||||
|         dldTemplate(); |  | ||||
|         dldText("填写说明.txt", "12121212121212"); |  | ||||
|     } |  | ||||
| 
 |  | ||||
|     const dldTemplate = () => { |  | ||||
|         let dataTable = []; |  | ||||
|         let option = {}; |  | ||||
|         option.fileName = '人资系统人员信息导入模板'; |  | ||||
|         option.datas = [ |  | ||||
|             { |  | ||||
|                 sheetData: dataTable, |  | ||||
|                 sheetName: '人资系统人员信息导入模板', |  | ||||
|                 sheetFilter: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'],  //excel文件中需显示的列数据 |  | ||||
|                 sheetHeader: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'],  //excel文件中每列的表头名称 |  | ||||
|             } |  | ||||
|         ] |  | ||||
|         let toExcel = new ExportJsonExcel(option);  //生成excel文件 |  | ||||
|         toExcel.saveExcel();  //下载excel文件 |  | ||||
|     } |  | ||||
| 
 |  | ||||
|     const dldText = (filename, text) => { |  | ||||
|         var element = document.createElement('a'); |  | ||||
|         element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); |  | ||||
|         element.setAttribute('download', filename); |  | ||||
| 
 |  | ||||
|         element.style.display = 'none'; |  | ||||
|         document.body.appendChild(element); |  | ||||
| 
 |  | ||||
|         element.click(); |  | ||||
|         document.body.removeChild(element); |  | ||||
|     } |  | ||||
| 
 |  | ||||
|     const action = '/_file-server/upload?type=excel&token=' + user.token; |  | ||||
|     const fileLimit = '.xls,.xlsx,.csv'; |  | ||||
| 
 |  | ||||
|     return ( |  | ||||
|         <Modal title="导入信息" visible={true} okText='完成' |  | ||||
|             onOk={() => handleOk(null)} |  | ||||
|             onCancel={onCancel}> |  | ||||
|             <Form> |  | ||||
|                 <Form.Upload label={'员工信息'} labelPosition='left' action={action} accept={fileLimit} maxSize={200}> |  | ||||
|                     <Button icon={<IconUpload />} theme="light"> |  | ||||
|                         请选择文件 |  | ||||
|                     </Button> |  | ||||
|                 </Form.Upload> |  | ||||
|                 <div style={{ color: '#ccc' }}>最大不超过200M,导入文件需与 |  | ||||
|                     <span onClick={() => download()} style={{ cursor: 'pointer', color: '#0066FF' }}>导入模板</span> |  | ||||
|                     一致</div> |  | ||||
|             </Form> |  | ||||
|         </Modal> |  | ||||
|     ) |  | ||||
| } |  | ||||
| 
 |  | ||||
| 
 |  | ||||
| export default ExportMembersModal; |  | ||||
| @ -0,0 +1,220 @@ | |||||
|  | 'use strict'; | ||||
|  | import React, { useState } from 'react'; | ||||
|  | import { connect } from 'react-redux'; | ||||
|  | //import { Button, Input, Card, Modal, Upload, message } from 'antd';
 | ||||
|  | import { Modal, Form, Button, Upload, Notification } from '@douyinfe/semi-ui'; | ||||
|  | import { IconUpload } from '@douyinfe/semi-icons'; | ||||
|  | //import { Request } from '@peace/utils'
 | ||||
|  | //import request from 'superagent'
 | ||||
|  | import XLSX from 'xlsx' | ||||
|  | //import { userBulkAdd } from '../../actions'
 | ||||
|  | 
 | ||||
|  | //TODO 下载模板和上传文件读取
 | ||||
|  | const ImportUser = props => { | ||||
|  |     const { user, dispatch, onCancel } = props | ||||
|  |     const [msg, setMsg] = useState('') | ||||
|  |     const [loading, setLoading] = useState('') | ||||
|  |     const [postData, setPostData] = useState([]) | ||||
|  | 
 | ||||
|  |     const confirm = () => { | ||||
|  |         if (postData.length) { | ||||
|  |             setLoading(true) | ||||
|  |             // dispatch(userBulkAdd(postData, params.departmentId ? params.departmentId : null)).then(res => {
 | ||||
|  |             //     if (res.success) {
 | ||||
|  | 
 | ||||
|  |             //     }
 | ||||
|  |             //     setLoading(false)
 | ||||
|  |             // })
 | ||||
|  |         } else { | ||||
|  |             Notification.warn('没有数据可以提交,请上传数据文件') | ||||
|  |         } | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     const download = () => { | ||||
|  |         dldTemplate(); | ||||
|  |         dldText("填写说明.txt", "12121212121212"); | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     const dldTemplate = () => { | ||||
|  |         let dataTable = []; | ||||
|  |         let option = {}; | ||||
|  |         option.fileName = '人资系统人员信息导入模板'; | ||||
|  |         option.datas = [ | ||||
|  |             { | ||||
|  |                 sheetData: dataTable, | ||||
|  |                 sheetName: '人资系统人员信息导入模板', | ||||
|  |                 sheetFilter: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'],  //excel文件中需显示的列数据
 | ||||
|  |                 sheetHeader: ['人员编号', '姓名', '证件号', '性别(男/女)', '出生年月日(例2022/02/01)', '籍贯', '婚育状态(已婚/未婚/已婚已育)', '政治面貌', '联系方式', '工作地点', '毕业院校', '学历', '专业', '毕业时间', '入职时间', '转试用期时间', '转正时间', '离职日期', '工作经验(年)', '历史工作经历与职务'],  //excel文件中每列的表头名称
 | ||||
|  |             } | ||||
|  |         ] | ||||
|  |         let toExcel = new ExportJsonExcel(option);  //生成excel文件
 | ||||
|  |         toExcel.saveExcel();  //下载excel文件
 | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     const dldText = (filename, text) => { | ||||
|  |         var element = document.createElement('a'); | ||||
|  |         element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); | ||||
|  |         element.setAttribute('download', filename); | ||||
|  | 
 | ||||
|  |         element.style.display = 'none'; | ||||
|  |         document.body.appendChild(element); | ||||
|  | 
 | ||||
|  |         element.click(); | ||||
|  |         document.body.removeChild(element); | ||||
|  |     } | ||||
|  |     //const action = '/file/qiniu/upload?type=excel&token=' + user.token;
 | ||||
|  |     const fileLimit = '.xls,.xlsx,.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,将天数的时间戳转为时间格式
 | ||||
|  |                                     }); | ||||
|  |                                     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("失败"); | ||||
|  |                                 } | ||||
|  |                             } | ||||
|  |                         } | ||||
|  |                     } | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         }) | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     return ( | ||||
|  |         <Modal | ||||
|  |             title="导入信息" visible={true} | ||||
|  |             onOk={confirm} | ||||
|  |             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} | ||||
|  |                     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 = [] | ||||
|  |                             const pattern = /^1[3|4|5|6|7|8|9]\d{9}$/; | ||||
|  |                             const sfz = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;//身份证
 | ||||
|  |                             for (let i = 0; i < res.length; i++) { | ||||
|  |                                 let d = res[i] | ||||
|  |                                 let number = String(d['人员编号']).trim(); | ||||
|  |                                 let name = String(d['姓名']).trim(); | ||||
|  |                                 let idNumber = String(d['证件照']).trim(); | ||||
|  |                                 let gender = String(d['性别(男/女)']).trim(); | ||||
|  |                                 let birthday = String(d['出生年月日(例2022/02/01)']).trim(); | ||||
|  |                                 let nativePlace = String(d['籍贯']).trim(); | ||||
|  |                                 let marital = String(d['婚育状态(已婚/未婚/已婚已育)']).trim(); | ||||
|  |                                 let politicsStatus = String(d['政治面貌']).trim(); | ||||
|  |                                 let phoneNumber = String(d['联系方式']).trim(); | ||||
|  | 
 | ||||
|  |                                 let workPlace = String(d['工作地点']).trim(); | ||||
|  |                                 let graduatedFrom = String(d['毕业院校']).trim(); | ||||
|  |                                 let educationBackground = String(d['学历']).trim(); | ||||
|  |                                 let specialty = String(d['专业']).trim(); | ||||
|  |                                 let graduationDate = String(d['毕业时间']).trim(); | ||||
|  |                                 let hiredate = String(d['入职时间']).trim(); | ||||
|  | 
 | ||||
|  |                                 let turnProbationPeriod = String(d['转试用期时间']).trim(); | ||||
|  |                                 let regularDate = String(d['转正时间']).trim(); | ||||
|  |                                 let dimissionDate = String(d['离职日期']).trim(); | ||||
|  |                                 let experienceYear = String(d['工作经验(年)']).trim(); | ||||
|  |                                 let occupationalHistory = String(d['历史工作经历与职务']).trim(); | ||||
|  | 
 | ||||
|  |                                 //let account = String(d['账号']).trim()
 | ||||
|  |                                 if (!number || !name) { | ||||
|  |                                     error(`第${i + 1} 行有空值,请填写后重新上传`) | ||||
|  |                                     return | ||||
|  |                                 } | ||||
|  |                                 if (!sfz.test(idcard)) { | ||||
|  |                                     error(`第${i + 1} 行证件号错误`) | ||||
|  |                                     return | ||||
|  |                                 } | ||||
|  |                                 if (!pattern.test(phoneNumber)) { | ||||
|  |                                     error(`第${i + 1} 行手机号码错误`) | ||||
|  |                                     return | ||||
|  |                                 } | ||||
|  |                                 if (name.length > 128 || account.length > 128) { | ||||
|  |                                     error(`第${i + 1} 行数据字符长度大于 128,请更改后重新上传`) | ||||
|  |                                     return | ||||
|  |                                 } | ||||
|  |                                 if (postData.some(p => p.number == number)) { | ||||
|  |                                     error(`第${i + 1} 行人员编号重复,请更改后重新上传`) | ||||
|  |                                     return | ||||
|  |                                 } | ||||
|  |                                 postData.push({ | ||||
|  |                                     name, phoneNumber, account | ||||
|  |                                 }) | ||||
|  |                             } | ||||
|  |                             if (postData.length) { | ||||
|  |                                 setPostData(postData) | ||||
|  |                             } | ||||
|  |                             let msg = '文件解析完成,点击确定按钮上传保存!' | ||||
|  |                             setMsg(msg) | ||||
|  |                             onSuccess({ message: msg }) | ||||
|  |                         }) | ||||
|  |                     }} | ||||
|  |                 > | ||||
|  |                     <Button icon={<IconUpload />} theme="light"> | ||||
|  |                         请选择文件 | ||||
|  |                     </Button> | ||||
|  |                 </Form.Upload> | ||||
|  |                 <div style={{ color: '#ccc' }}>最大不超过200M,导入文件需与 | ||||
|  |                     <span onClick={() => download()} style={{ cursor: 'pointer', color: '#0066FF' }}>导入模板</span> | ||||
|  |                     一致</div> | ||||
|  |             </Form> | ||||
|  |         </Modal > | ||||
|  |     ) | ||||
|  | } | ||||
|  | 
 | ||||
|  | function mapStateToProps(state) { | ||||
|  |     const { auth, customizeList } = state; | ||||
|  |     return { | ||||
|  |         user: auth.user, | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | export default connect(mapStateToProps)(ImportUser); | ||||
					Loading…
					
					
				
		Reference in new issue