1.You can drag files to a specific area, to upload. Alternatively, you can also upload by selecting.
2.We can upload serveral files at once in modern browsers by giving the input the multiple attribute.
点击或者将文件拖动到下图指定区域后,点击upload order 按钮进行文件上传,而download按钮是实现单击后下载模板文档功能的

下面该类中为单击或拖动的组件
- import {DownloadOutlined, InboxOutlined, PlusOutlined, UploadOutlined} from '@ant-design/icons';
- import {Button, Col, message, Row, Upload,Typography} from 'antd';
- import React, {Component} from 'react';
- import classes from "../ManualOrder/ManualOrder.module.css";
- import {uploadRecord} from "../../api/order";
- import Constants from '../../utils/constants';
- import PagenHeader from '../../components/PagenHeader'
- const { Dragger } = Upload;
-
- export default class UploadRePOS extends Component {
- constructor(props) {
- super(props)
- this.state = {
- fileList: [],
- uploading: false,
- errorMsg: ''
- }
- }
- handleUpload = () => {
- const { fileList } = this.state;
- this.setState({ uploading: true });
- const formData = new FormData()
- formData.append('file', fileList[0])
- uploadRecord(formData).then(res => {
- if (res.code === 4) {
-
- const resultMessage = 'Successfully updated your production record'
- const pageResult = { statusCode: 0, message: resultMessage }
-
- this.setState({ uploading: false, errorMsg: ''})
- this.props.onPageResultChange(pageResult)
- this.props.parsePOData(res.data)
- this.props.onUploadSuccessfully(true)
-
- } else {
- const resultMessage = `Error submitting the record: ${res.message || res.msg}`
- const pageResult = { statusCode: 1, message: resultMessage }
- this.props.onPageResultChange(pageResult)
- this.props.parsePOData(res.data)
- this.props.onUploadSuccessfully(false)
- this.setState({ uploading: false, errorMsg:resultMessage,uploadSuccessfully:false});
- //this.setState({ uploading: false, errorMsg:res.message || res.msg ,uploadSuccessfully:false});
- }
- }, err => {
- const resultMessage = 'Error submitting the record:' + err + ". Please contact Avery Dennison Software Support Team software.support@ap.averydennison.com"
- const pageResult = { statusCode: 1, message: resultMessage }
- this.setState({ uploading: false,errorMsg:err,uploadSuccessfully:false , pageResult: pageResult });
- })
- }
- handleDownloadClick = () => {
- window.open(`${Constants.API_ROOT_URL}/record/v1.0/downloadRecordForm`)
- }
- handleRemove = (file) => {
- this.setState(state => {
- const index = state.fileList.indexOf(file);
- const newFileList = state.fileList.slice();
- newFileList.splice(index, 1);
- return {
- fileList: newFileList,
- errorMsg:''
- }
- })
- }
-
- handleBeforeUpload = (file) => {
- this.setState({ fileList: [file] })
- return false
- }
-
-
- render() {
- const {
- uploading,
- fileList,
- errorMsg
- } = this.state
- return (
- <div>
-
- <PagenHeader titleClass={classes.sitePageHeader}> Select data filePagenHeader>
-
-
-
- <Dragger
- name="file"
- onRemove={ this.handleRemove }
- beforeUpload={ this.handleBeforeUpload }
- fileList={ fileList }
- className={ classes.item_width }>
- <p className="ant-upload-drag-icon">
- <InboxOutlined/>
- p>
- <p className="ant-upload-text">Click or drag file to this area to uploadp>
- Dragger>
- <PagenHeader titleClass={classes.sitePageHeader}>Order Form SamplePagenHeader>
- <Row xs={2} md={4} lg={6}>
- <Col className={classes.item}>
- <Button icon={<DownloadOutlined/>} onClick={this.handleDownloadClick}
- className={classes.item_widths}>DownloadButton>
- Col>
- <Col >
- <Button type="primary"
- className={ classes.item_width }
- onClick={ this.handleUpload }
- icon={ <UploadOutlined /> }
- disabled={ fileList.length === 0 }
- >
- { uploading ? 'Uploading' : 'Upload' }
- Button>
- Col>
- Row>
-
- {(errorMsg !== '') &&
- <Row justify='center' className={ classes.error_msg }>
- <Col span={ 24 } ><Typography.Text type="danger">Error: {errorMsg}Typography.Text>Col>
- Row>
- }
- div>
- )
- }
- }
为父组件,在其中引用UploadRePOS.jsx 子组件.
该类中的handleUpload方法中的uploadRecord为在/api/order.js中设置的组件。用来管理后台跳转路径
- import React, { Component } from 'react'
- import { Table, Button, Row, Col, Divider, Select } from 'antd'
- import PagenHeader from '../../components/PagenHeader'
- import UploadPO from './UploadRePOS'
- import classes from '../../pages/ManualOrder/ManualOrder.module.css'
- import { getLocalStorage } from '../../utils/storage'
- import { submitOrder } from '../../api/order'
- import PageResult from '../../components/PageResult'
-
- export default class RecordUpload extends Component {
-
- state = {
- manualOrder: {
- },
- poDataList: [],
- isBillFormVisible: false,
- selectedRowKeys: [],
- submiting: false,
- submitSuccessfully: false,
- uploadSuccessfully: false,
- disableSelected: false,
- pageResult: {
- statusCode: 0,
- message: null
- },
- successMsg: '',
- errorMsg: ''
- }
-
- parsePOData = (data) => {
- const poDataList = [];
- data.items.forEach(item => poDataList.push(item));
- this.setState({ manualOrder: data, poDataList: poDataList });
- };
-
- onPageResultChange = (resultChange)=>{
- this.setState({pageResult: resultChange});
- }
-
- onUploadSuccessfully = (flag) => {
- this.setState({ uploadSuccessfully: flag })
- }
-
- handleDirectorCreateOrder = () => {
- window.location.href = '/kaloud/order/manualOrder'
- }
- onSelectChange = (selectedRowKeys, selectedRows) => {
- this.setState({selectedRowKeys:selectedRowKeys,selectedRows:selectedRows})
- };
-
-
- handleCloseForm = () => {
- this.setState({ isBillFormVisible: false })
- }
-
- onBillShipChange = (billShipFormData) => {
- this.setState({ billShipInfo: billShipFormData })
- }
-
- onUploadPORef = (ref) => {
- this.child = ref
- };
-
- constructorManualOrder = (manualOrder) => {
- let orderData = Object.assign({}, this.state.manualOrder, {
- items: this.state.selectedRows
- })
-
- const result = orderData;
- result.user = manualOrder.user === null ? getLocalStorage('user') : manualOrder.user
- this.setState({ manualOrder: result })
- return result;
- }
- goBack = () =>{
- this.setState({manualOrder: {},
- poDataList: [],
- selectedRowKeys: [],
- submiting: false,
- validateSuccessfully: false,
- submitSuccessfully: false,
- uploadSuccessfully: false,
- disableSelected: false,
- pageResult: {
- statusCode: 0,
- message: null
- },
- successMsg: '',
- errorMsg: ''})
- }
- incorrectItemsColumns = () =>{
- return [
- {
- title: 'Line#',
- dataIndex: 'rowNo',
- with:100
- }, {
- title: 'Serial#',
- dataIndex: 'serialNumber',
- with:100
- }, {
- title: 'Production Date',
- dataIndex: 'productionDate',
- with:50
- }, {
- title: 'SKU',
- dataIndex: 'sku',
- with:100
- }, {
- title: 'COO',
- dataIndex: 'coo',
- with:100
- }, {
- title: 'Message',
- dataIndex: 'errorMsg',
- with:300
- },
- ]
- }
- renderColumns = () => {
- return [
- {
- title: 'Message',
- dataIndex: 'validateMsg',
- render: text => {
- if (text === 'Ready' || text === 'Success') {
- return <span>{text}span>
- } else {
- return <span className="ant-typography ant-typography-danger" direction="ltr">{text}span>
- }
- }
- },
- {
- title: 'Line No',
- dataIndex: 'rowNo'
- },
- {
- title: 'Serial Number ',
- dataIndex: 'serialNumber'
- },
- {
- title: 'Production Date',
- dataIndex: 'productionDate'
- },
- {
- title: 'SKU',
- dataIndex: 'sku'
- },
- {
- title: 'COO',
- dataIndex: 'coo'
- }
- ];
- }
-
- render() {
- //const user = getLocalStorage('user');
- const result =new URLSearchParams(this.props.location.search)
- const user = result.get('user');
- //const { manualOrder, poDataList, billShipInfo, isBillFormVisible, printTypeList ,disableSelected,selectedRowKeys,uploadSuccessfully,showBillButton,submitSuccessfully,submiting, pageResult} = this.state;
-
- const { manualOrder, poDataList,disableSelected,selectedRowKeys,uploadSuccessfully,submitSuccessfully,submiting, pageResult} = this.state;
-
-
- const rowSelection = {
- selectedRowKeys,
- onChange: this.onSelectChange,
- getCheckboxProps: (record) => ({
- disabled: record.validateMsg !== 'Ready' || disableSelected
- })
- };
- return (
- <div>
- <PagenHeader titleClass={classes.title}> KaloudPagenHeader>
- <PagenHeader titleClass={classes.title}> Update production recordsPagenHeader>
- {
- (uploadSuccessfully === false) &&
- <UploadPO parsePOData={this.parsePOData} onPageResultChange={this.onPageResultChange} onUploadPORef={this.onUploadPORef} onUploadSuccessfully={this.onUploadSuccessfully} />
-
- }
- {
- (manualOrder.valid === false) &&
- <div>
- <PageResult result={{ statusCode: 1, message: manualOrder.errorMsg }} titleClass={classes.error_msg}>{manualOrder.errorMsg}PageResult>
- {
- (manualOrder.items.length > 0) &&
- <Table dataSource={manualOrder.items} pagination={{defaultCurrent:1,defaultPageSize:20}} columns={this.incorrectItemsColumns()} rowKey={record => record.rowNo}>Table>
- }
- div>
- }
- {
- (manualOrder.valid === true) &&
- <div>
-
- <Divider orientation="left">Divider>
- <Table
- rowSelection={rowSelection}
- pagination={false}
- columns={this.renderColumns()}
- dataSource={poDataList}
- disabled={this.state.submitSuccessfully}
- rowKey={record => record.rowNo}
- />
-
- {
- (manualOrder.valid === true ) &&
- <PageResult result={pageResult} titleClass={pageResult.statusCode === 0 ? classes.success_msg : classes.error_msg}>{pageResult.message}PageResult>
- }
- <Row justify="center" className={classes.submit}>
- { <Col span={2} >
- <Button onClick={this.goBack} size="large" style={{ display: (submitSuccessfully ? 'none' : 'block') }}>BackButton>
- Col>}
- Row>
- div>
- }
- div>
- )
- }
- }
- import request from '../utils/request'
-
- export function uploadManualOrder(data){
- return request({
- url: `/order/v1.0/uploadManualOrder`,
- method: 'post',
- data: data,
- contentType: 'multipart/form-data'
- })
- }
- export function uploadRecord(data){
- return request({
- url: `/record/v1.0/uploadRecord`,
- method: 'post',
- data: data,
- contentType: 'multipart/form-data'
- })
- }
- export function submitOrder(data){
- return request({
- url: `/order/v1.0/submitOrder`,
- method: 'post',
- data: data,
- contentType: 'application/json'
- })
- }
-
- export function downloadOrderForm(){
- return request({
- url: `/order/v1.0/downloadOrderForm`,
- method: 'get',
- contentType: 'multipart/form-data'
- })
- }
- export function downloadRecordForm(){
- return request({
- url: `/record/v1.0/downloadRecordForm`,
- method: 'get',
- contentType: 'multipart/form-data'
- })
- }
- import React from 'react';
- import ReactDOM from 'react-dom';
- import { Spin } from 'antd';
- import axios from 'axios'
- import Constants from './constants'
- import { getLocalStorage, setLocalStorage } from './storage'
-
- let isLock = false;
- let refreshSubscribers = [];
- let requestCount = 0
- function showLoading() {
- if (requestCount === 0) {
- var dom = document.createElement('div')
- dom.setAttribute('id', 'loading')
- document.body.appendChild(dom)
- ReactDOM.render(<Spin tip="Loading..." size="large" />, dom)
- }
- requestCount++
- }
-
- function hideLoading() {
- requestCount--
- if (requestCount === 0) {
- document.body.removeChild(document.getElementById('loading'))
- }
- }
-
- //push所有请求到数组中
- function subscribeTokenRefresh(cb) {
- refreshSubscribers.push(cb)
- }
-
- //刷新请求(refreshSubscribers数组中的请求得到新的token之后会自执行,用新的token去请求数据)
- function onRrefreshed(token) {
- refreshSubscribers.map(cb => cb(token))
- }
-
- //刷新token
- function refreshToken(config, token, resolve, reject) {
- axios({
- method: "get",
- url: `${Constants.API_ROOT_URL}/oauth/v1.0/getUserInfo?token=${token}`,
- }).then(response => {
- isLock = false;//释放锁
- const res = response.data
- // if the custom code is not 20000, it is judged as an error.
- if (res.code === 401) {
- window.location.href = '/kaloud/loginexpired';
- return reject(res);
- } else if (res.code === 412) {
- window.location.href = '/kaloud/userdeactivated';
- return reject(res);
- } if (res.code !== 4) {
- // message.error(`Error: ${res.msg || res.message}`)
- return res;
- }
- setLocalStorage('user', res.data.user)
- setLocalStorage('needRefreshToken', false)
-
- config.headers['token'] = token
- config.headers['user'] = res.data.user
- resolve(config);
- //执行数组里的函数,重新发起被挂起的请求
- onRrefreshed(res.data.user)
- //清空数组中保存的请求
- refreshSubscribers = []
- }).catch(err => {
- return err;
- });
- }
-
-
- // create an axios instance
- const service = axios.create({
- baseURL: Constants.API_ROOT_URL, // url = base url + request url
- withCredentials: true, // send cookies when cross-domain requests
- timeout: 120000 // request timeout
- })
-
- // request interceptor
- service.interceptors.request.use(
- config => {
-
- if(config.method === 'get'){
- config.params = {
- _t: Date.now(),
- ...config.params,
- };
- }
- // do something before request is sent
- if (config.isLoading !== false) {
- showLoading()
- }
- config.headers['retailer'] = Constants.RETAILER
- config.headers['Content-Type'] = config.contentType || 'application/json'
-
- const user = getLocalStorage('user')
- const token = getLocalStorage('token')
- const needRefreshToken = getLocalStorage('needRefreshToken')
- if ((!user && token) || needRefreshToken) {
- //判断当前是否正在请求刷新token
- if (!isLock) {
- isLock = true;//isLock设置true,锁住防止死循环。
- //使用Promise等待刷新完成返回配置信息
- let refresh = new Promise((resolve, reject) => {
- refreshToken(config, token, resolve, reject);
- })
- return refresh
-
- } else {
- //判断当前url是否是刷新token的请求地址,如果是直接下一步。
- if (config.url.indexOf("/kaloud/loginexpired") === -1 || config.url.indexOf("/kaloud/userdeactivated") === -1) {
- //把请求(token)=>{....}都push到一个数组中
- let retry = new Promise((resolve, reject) => {
- //(token) => {...}这个函数就是回调函数
- subscribeTokenRefresh((user) => {
- config.headers['token'] = token
- config.headers['user'] = user
- //将请求挂起
- resolve(config)
- })
- })
- return retry
- } else {
- config.headers['token'] = getLocalStorage('token')
- config.headers['user'] = user
- return config;
- }
- }
- } else {
- config.headers['token'] = token
- config.headers['user'] = user
- return config
- }
- },
- error => {
- // do something with request error
- hideLoading()
- console.log(error) // for debug
- return Promise.reject(error)
- }
- )
-
- // response interceptor
- service.interceptors.response.use(
- /**
- * If you want to get http information such as headers or status
- * Please return response => response
- */
-
- /**
- * Determine the request status by custom code
- * Here is just an example
- * You can also judge the status by HTTP Status Code
- */
- response => {
- hideLoading()
- const res = response.data
- // if the custom code is not 20000, it is judged as an error.
- if (res.code === 401) {
- window.location.href = '/kaloud/loginexpired';
- return Promise.reject(res);
- } else if (res.code === 412) {
- window.location.href = '/kaloud/userdeactivated';
- return Promise.reject(res);
- } if (res.code !== 4) {
- // message.error(`Error: ${res.msg || res.message}`)
- return res;
- } else {
- return res
- }
- },
- error => {
- console.log('err' + error) // for debug
- hideLoading()
- // Message({
- // message: error.message,
- // type: 'error',
- // duration: 5 * 1000
- // })
- return Promise.reject(error)
- }
- )
-
- export default service
- import React, { Component } from 'react'
- import { Row, Col, Typography } from 'antd'
-
- export default class PageResult extends Component {
-
- render() {
- const { children, result, titleClass } = this.props;
- return (
- <Row className={titleClass} justify='center'>
- {
- (result.statusCode === 0) &&
- <Col span={24}>
- <Typography.Text variant="h4" component="h4" type="success">
- {children}
- Typography.Text>
- Col>
- }
- {
- (result.statusCode === 1) &&
- <Col span={24}>
- <Typography.Text variant="h4" component="h4" type="danger">
- {children}
- Typography.Text>
- Col>
- }
- Row>
- );
- }
- }
- import React, { Component } from 'react'
- import { Row, Col, Typography } from 'antd';
-
- export default class PagenHeader extends Component {
- render() {
- const { children, titleClass } = this.props;
- return (
- <Row className={ titleClass }>
- <Col span={ 24 }>
- <Typography variant="h5" component="h2">
- { children }
- Typography>
- Col>
- Row>
- );
- }
- }
- export const setLocalStorage = (key, value) => {
- if (!key) return
- let content = value
- if (typeof value !== 'string') {
- content = JSON.stringify(value)
- }
- window.localStorage.setItem(key, content)
- }
-
- /**
- * 获取localStorage
- */
- export const getLocalStorage = key => {
- if (!key) return
- return window.localStorage.getItem(key)
- }
- let apiRootUrl = "/api/kaloud-api"
-
- if(process.env.NODE_ENV === "production") {
- apiRootUrl = "/kloud-api"
- }
-
- const Constants = {
- API_ROOT_URL: apiRootUrl,
- RETAILER: "Kloud"
- }
-
- export default Constants;
- .title {
- text-align: center;
- }
- .content {
- text-align: center;
- }
-
- .submit {
- margin-top: 20px;
- }
-
- .error_msg {
- margin-top: 20px;
- font-size: large;
- text-align: center;
- }
-
- /* Upload PO */
- .item {
- text-align: left;
- margin-bottom: 15px;
- }
-
- .item_width {
- width: 150px;
- }
-
- .label {
- text-align: center;
- padding: 5px 0;
- }
-
- /* bill ship form */
- .bill_ship_form {
- margin-left: 50px;
- }
- .c_form_item {
- margin-bottom: 4px;
- }
- .bill_ship_text {
- margin-bottom: 10px;
- text-align: center;
- font-weight: bold;
- }
-
- .table_item_error {
- font-style: normal;
- }
-
- .table_item_success {
- font-style: normal;
- }
-
- .message_error{
- color: crimson;
- }
-
- .success_msg{
- margin-top: 20px;
- font-size: large;
- text-align: center;
- }
- .black{
- background-color: gray;
- text-align: center;
- text-decoration-color: aliceblue;
- }
- .sitePageHeader {
- text-align: center;
- border: 1px solid rgb(235, 237, 240);
- background-color: gray;
-
- }
- .item_widths {
- width: 150px;
- margin-left: 600px;
-
- }