'use strict'; import moment from 'moment'; import React, { useState } from 'react'; import { connect } from 'react-redux'; import { Modal, Form, Button, Notification } from '@douyinfe/semi-ui'; import { IconUpload } from '@douyinfe/semi-icons'; import cityData from '../components/city.json'; import XLSX from 'xlsx' import { membersBulkAdd } from '../actions/personnelFiles' import ExportJsonExcel from 'js-export-excel'; import { rule } from './table-input-rule' //下载模板和上传文件读取 const ImportMembersModal = props => { const { dispatch, onCancel, xqMembers } = props const [msg, setMsg] = useState('') const [loading, setLoading] = useState('') const [postData, setPostData] = useState([]) const confirm = () => { if (postData.length) { setLoading(true) dispatch(membersBulkAdd(postData)).then(res => { if (res.success) { //Notification.success({ content: '导入员工信息成功', duration: 2 }) onCancel() } setLoading(false) }) } else { Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 }) } } const dldCsvMb = () => { //表头 let head = "人员编号,姓名,证件号,性别(男/女),出生年月日(例2022/02/01),籍贯,婚育状态(已婚/未婚/已婚已育),政治面貌,联系方式,工作地点,毕业院校,学历,专业,毕业时间,入职时间,转试用期时间,转正时间,离职日期,工作经验(年),历史工作经历与职务\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 = () => { //dldTemplate(); dldCsvMb(); let str = ""; rule.forEach((v, i) => { str += `${v}\r\n` }) dldText("填写说明.txt", str); } // 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 = '.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 judgePlace = (place) => { let valid = true; if (!place) {//可以不填 return valid; } if (place.split('-').length == 1) {//判断籍贯 if (['北京市', '上海市', '天津市', '重庆市'].indexOf(place) == -1) { valid = false; } } else if (place.split('-').length == 2) { let province = place.split('-')[0]; let city = place.split('-')[1]; let existProvince = cityData.find(cd => cd.name == province); if (!existProvince) { valid = false; } else { let existCity = existProvince.children.find(cd => cd.name == city); if (!existCity) { valid = false; } } } else { valid = false; } return valid; } 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; } 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; } return ( { setMsg('') setLoading(false) setPostData([]) onCancel() }} >
{ 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 = []; const zmsz = /^[A-Za-z0-9]+$/;//字母数字组合 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]$/;//身份证 //const ymd = /^((19|20)[0-9]{2})[\/\-]((0[1-9])|(1[0-2]))[\/\-]((0[1-9])|((1|2)[0-9])|(3[0-1]))$/;//年月日 const num0 = /^\d+(\.\d+)?$/;//非负浮点数 for (let i = 0; i < res.length; i++) { let d = res[i]; let number = judgeNull(d['人员编号']); let name = judgeNull(d['姓名']); let idNumber = judgeNull(d['证件号']); let gender = judgeNull(d['性别(男/女)']); let birthday = judgeNullTime(d['出生年月日(例2022/02/01)']);//-------判断时间 let nativePlace = judgeNull(d['籍贯']); let marital = judgeNull(d['婚育状态(已婚/未婚/已婚已育)']); let politicsStatus = judgeNull(d['政治面貌']); let phoneNumber = judgeNull(d['联系方式']); let workPlace = judgeNull(d['工作地点']); let graduatedFrom = judgeNull(d['毕业院校']); let educationBackground = judgeNull(d['学历']); let specialty = judgeNull(d['专业']); let graduationDate = judgeNullTime(d['毕业时间']);//-------------------判断时间 let hiredate = judgeNullTime(d['入职时间']);//-------------------------判断时间 let turnProbationPeriod = judgeNullTime(d['转试用期时间']);//-----------判断时间 let regularDate = judgeNullTime(d['转正时间']);//----------------------判断时间 let dimissionDate = judgeNullTime(d['离职日期']);//---------------------判断时间 let experienceYear = judgeNull(d['工作经验(年)']); let occupationalHistory = judgeNull(d['历史工作经历与职务']); if (!number) {//人员编号不为空,唯一,字母和数字 error(`第${i + 2}行人员编号为空,请填写`) return } let xqExist = xqMembers.find(m => m.userCode == number); if (!xqExist) { error(`第${i + 2}行的人员编号无对应的员工信息`) return } if (postData.some(p => p.number == number)) {//人员编号 唯一 error(`第${i + 2}行人员编号重复,请更改后重新上传`) return } if (!zmsz.test(number)) { error(`第${i + 2}行人员编号错误,请填写字母和数字的组合`) return } if (!name) {//姓名必填 error(`第${i + 2}行姓名为空,请填写`) return } if (idNumber && !sfz.test(idNumber)) { error(`第${i + 2}行证件号错误`) return } if (gender && ['男', '女'].indexOf(gender) == -1) { error(`第${i + 2}行性别错误`) return } let bsdValid = judgeTimeValid(birthday); if (!bsdValid) { error(`第${i + 2}行出生年月日错误,请填写yyyy/mm/dd格式`) return } let jgValid = judgePlace(nativePlace); if (!jgValid) { error(`第${i + 2}行籍贯错误`) return } if (marital && ['已婚', '未婚', '已婚已育'].indexOf(marital) == -1) { error(`第${i + 2}行婚育状态错误`) return } if (politicsStatus && ['群众', '党员'].indexOf(politicsStatus) == -1) { error(`第${i + 2}行政治面貌错误`) return } if (phoneNumber && !pattern.test(phoneNumber)) { error(`第${i + 2}行联系方式错误`) return } let wpValid = judgePlace(workPlace); if (!wpValid) { error(`第${i + 2}行工作地点错误`) return } if (educationBackground && ['小学', '初中', '高中', '大专', '本科', '研究生', '博士'].indexOf(educationBackground) == -1) { error(`第${i + 2}行学历错误`) return } let byValid = judgeTimeValid(graduationDate); if (!byValid) { error(`第${i + 2}行毕业时间错误,请填写yyyy/mm/dd格式`) return } let rzhValid = judgeTimeValid(hiredate); if (!rzhValid) { error(`第${i + 2}行入职时间错误,请填写yyyy/mm/dd格式`) return } let shyValid = judgeTimeValid(turnProbationPeriod); if (!shyValid) { error(`第${i + 2}行转试用期时间错误,请填写yyyy/mm/dd格式`) return } let zhzhValid = judgeTimeValid(regularDate); if (!zhzhValid) { error(`第${i + 2}行转正时间错误,请填写yyyy/mm/dd格式`) return } let lzhValid = judgeTimeValid(dimissionDate); if (!lzhValid) { error(`第${i + 2}行离职日期错误,请填写yyyy/mm/dd格式`) return } if (experienceYear && !num0.test(experienceYear)) { error(`第${i + 2}行工作经验(年)错误,请填写非负数`) return } postData.push({ pepUserId: xqExist.pepUserId, name, idNumber, gender, birthday, nativePlace, marital, politicsStatus, phoneNumber, workPlace, graduatedFrom, educationBackground, specialty, graduationDate, hiredate, turnProbationPeriod, regularDate, dimissionDate, experienceYear, occupationalHistory, del: false, number }) } //if (postData.length) { setPostData(postData) //} let msg = '文件解析完成,点击确定按钮上传保存!' setMsg(msg) onSuccess({ message: msg }) }) }}> {msg}
最大不超过200M,导入文件需与 download()} style={{ cursor: 'pointer', color: '#0066FF' }}>导入模板 一致
) } function mapStateToProps(state) { const { auth } = state; return { user: auth.user, } } export default connect(mapStateToProps)(ImportMembersModal);