import React, { Fragment } from 'react'; import { Button, Modal, Steps, Upload, Icon, message, Tabs, Table } from 'antd'; import styles from './ImportUtil.less'; import ButtonDiy from '@/baseComponent/ButtonDiy'; import config from '@/config/config'; import { connect } from 'dva'; import { exportExcel } from 'xlsx-oc'; const Step = Steps.Step; const TabPane = Tabs.TabPane; @connect(({ DataObj, loading }) => ({ DataObj, loading: loading.models.DataObj, })) export default class ImportUtil extends React.PureComponent { constructor(props) { super(props); const exportTemplateUrl = encodeURI( `${config.sqlFormsServer}/DataObjApi/importTemplateDownload?objId=${this.props.objId}&name=${ props.fileName }`, ); this.state = { ch: false, currentKey: '1', visible: false, current: 0, isShow: true, filekey: '', sucData: [], errData: [], column: [], exportTemplateUrl, isNextDisabled: false, }; } showModal = () => { this.setState({ visible: true, }); }; handleOk = (e) => { this.setState({ visible: false, }); }; handleCancel = (e) => { this.setState({ visible: false, }); }; next() { const current = this.state.current + 1; if (current === 2) { this.setState({ current: current, isShow: false, }); if (this.state.errData.lenth > 0) { message.error('请检查数据'); return; } else { this.import(); } } if (current === 3) { this.setState({ current: current, isShow: true, }); if (this.props.callback) { this.props.callback(); } } } prev() { const current = this.state.current - 1; this.setState({ current }); } import() { const { dispatch, importParams } = this.props; dispatch({ type: 'DataObj/importExecute', payload: { ...(importParams || {}), cacheKey: this.state.filekey, objId: this.props.objId, }, callback: (res) => { this.next(); message.success('导入成功'); this.setState({ current: 3, isShow: true, visible: false, }); if (this.props.callback) { this.props.callback(); } }, }); } getCachKey = (filePath) => { const { dispatch, importParams } = this.props; dispatch({ type: 'DataObj/importAnalyse', payload: { ...(importParams || {}), isLocal: false, filePath, objId: this.props.objId, }, callback: (res) => { this.setState({ filekey: res.cacheKey, }); this.queryFile(res.cacheKey); }, }); }; queryFile = (cacheKey) => { const { dispatch, importParams } = this.props; dispatch({ type: 'DataObj/importDataQuery', payload: { ...(importParams || {}), cacheKey, objId: this.props.objId, }, callback: (res) => { this.setState({ current: 1, isShow: false, sucData: res.pass, errData: res.noPass, column: res.column, }); if (res.noPass && res.noPass.length == 0) { if (res.pass.length == 0) { message.error('当前没有验证成功的数据,无法导入。'); this.setState({ currentKey: '1', ch: !this.state.ch, isNextDisabled: true, }); } else { message.success('所有数据验证通过,请确认后点击下一步。'); this.setState({ currentKey: '2', ch: !this.state.ch, isNextDisabled: false, }); } } else { message.error('当前存在未验证通过的数据,请按错误提示检测更正导入文件'); this.setState({ currentKey: '1', ch: !this.state.ch, isNextDisabled: true, }); } }, }); }; changePane = (activeKey) => { this.setState({ currentKey: activeKey }); }; exportError = (column, dataSource) => { var _headers = []; for (var i = 0; i < column.length; i++) { _headers.push({ k: column[i].dataIndex, v: column[i].title }); } for (var j = 0; j < dataSource.length; j++) { dataSource[j].index = j + 1; } exportExcel(_headers, dataSource); }; render() { const props = { name: 'file', action: config.sqlFormsServer + '/upload', headers: { authorization: 'authorization-text', }, accept: '.xlsx', showUploadList: false, onChange: (info) => { if (info.file.status !== 'uploading') { } if (info.file.status === 'done') { message.success(`${info.file.name} 上传成功`); let x = info.file.response; this.getCachKey(x); } else if (info.file.status === 'error') { message.error(`${info.file.name} file upload failed.`); } }, }; const steps = [ { title: '上传Excel', }, { title: '验证数据', }, { title: '数据导入', }, { title: '导入完成', }, ]; const { current } = this.state; const { name, loading } = this.props; const column1 = this.state.column ? [ { title: '序号', dataIndex: 'index', fixed: 'left', width: 50, render: (v, r, i) => i + 1, }, ...this.state.column, ] : []; var column2 = this.state.column ? [...this.state.column] : []; if (column1.length > 1) column1[1].render = (val) => <span style={{ color: 'red' }}>{val}</span>; column2.splice(0, 1); column2 = [{ title: '序号', fixed: 'left', width: 50, render: (v, r, i) => i + 1 }, ...column2]; return ( <span> <ButtonDiy name={name || '批量导入'} type="default" className="defaultBlue" handleClick={this.showModal} /> <Modal visible={this.state.visible} onOk={this.handleOk} maskClosable={false} destroyOnClose onCancel={this.handleCancel} title={null} footer={null} width={'80%'}> <div className={styles.nomal}> <p className={styles.import}>EXCEL导入向导</p> <div style={{ margin: 'auto 23px' }}> <Steps current={current}> {steps.map((item) => ( <Step key={item.title} title={item.title} /> ))} </Steps> <div className="steps-content">{steps[this.state.current].content}</div> <div className={styles.button}> {this.state.current < steps.length - 1 && this.state.current !== 0 && ( <ButtonDiy name={this.state.current == 3 ? '确认导入' : '下一步'} type="primary" disabled={this.state.current != 3 && this.state.isNextDisabled} className="primaryBlue" handleClick={() => this.next()} /> )} {this.state.current > 0 && ( <ButtonDiy style={{ marginLeft: 8 }} name="上一步" className="defaultBlue" handleClick={() => this.prev()} /> )} </div> </div> <div className={styles.tip}> <p className={styles.tipContent}> <span>欢迎使用EXCEL导入向导,首先请您上传需要导入的EXCEL文件。</span> <span> 点击“选择文件”选择您要导入的EXCEL文件,点击“开始上传”将其上传到服务器上,点击“清空队列”清空当前上传文件队列。 </span> </p> </div> {this.state.isShow ? ( <div className={styles.buttonDown}> <Upload {...props}> <Button style={{ marginRight: '20px' }}> <Icon type="upload" /> 点击上传 </Button> </Upload> <Button href={this.state.exportTemplateUrl} target="_blank" type="danger"> 下载模板 </Button> </div> ) : ( <Upload {...props}> <Button> <Icon type="upload" /> 重新上传 </Button> </Upload> )} {this.state.isShow ? ( <div className={styles.attentionItem}> <p>导入事项</p> <p>1. 导入操作一次只能上传 1 个EXCEL文件。</p> <p>2. 导入文件最大文件大小上传 1 GB。</p> <p>3. 只能上传EXCEL文件(XLS, XLSX) 默认支持EXCEL 2003和EXCEL 2007。</p> <p>4. 请将EXCEL文件的所有单元格格式设置为“文本”格式</p> </div> ) : ( <div className={styles.error} style={{ marginTop: 20 }}> <Tabs activeKey={this.state.currentKey} key={this.state.ch} onChange={this.changePane} type="card"> {this.state.errData && this.state.errData.length == 0 ? ( '' ) : ( <TabPane tab={<span style={{ color: 'red' }}>验证错误列表</span>} key="1"> <Button style={{ marginTop: 5, marginBottom: 5 }} type="danger" onClick={this.exportError.bind(this, column1, this.state.errData)}> 导出错误信息 </Button> <Table columns={column1} size="small" style={{ overflow: 'auto' }} dataSource={this.state.errData} bordered={true} /> </TabPane> )} <TabPane tab={<span style={{ color: 'green' }}>验证成功列表</span>} key="2"> <Button style={{ marginTop: 5, marginBottom: 5 }} type="primary" onClick={this.exportError.bind(this, column2, this.state.sucData)}> 导出正确信息 </Button> <Table columns={column2} size="small" style={{ overflow: 'auto' }} dataSource={this.state.sucData} bordered={true} /> </TabPane> </Tabs> </div> )} </div> </Modal> </span> ); } }