React图片拖拽排序

import React, { Component,  } from 'react';
import { _Get, _Post, _Put, _Delete } from '@/common/request'
import API from '@/common/api';
import configBase from '../../../config';
import Author from '@/common/author'
import { Upload, Icon, message, Modal, Row, Col, Divider, Button } from 'antd';
import { sortable } from 'react-sortable';
import { baseImgUrl } from '@/config'
import { handlePicUrl } from '@/common/utils';
var items = []
class Item extends React.Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  // 鼠标移入
  handleMouseOver = (e) => {
    e.stopPropagation();
    this.setState({ mouseState: true })
  }
  // 鼠标移出
  handleMouseOut = (e) => {
    e.stopPropagation();
    this.setState({ mouseState: false })
  }
  // 放大图片
  onShowImage = (index) => {
    this.setState({ showImageState: true, imageUrl: items[index] })
  }
  // 确定modal
  handleOk = () => {
    this.setState({ showImageState: true })
  }
  // 关闭modal
  handleCancel = () => {
    this.setState({ showImageState: false })
  }
  // 删除图片
  delImageList = (index) => {
    items.splice(index, 1);
    this.props.onClicked({ items })
  }

  render() {
    return (
      <li {...this.props}
        style={{
          height: '140px',
          width: '120px',
          float: 'left',
          border: '1px solid #dddddd',
          borderRadius: '4px',
          position: 'relative',
          overflow: 'hidden',
          padding: '10px',
          marginRight: '10px',
          marginBottom: '10px',
        }} onMouseEnter={(e) => this.handleMouseOver(e)} onMouseLeave={(e) => this.handleMouseOut(e)}>
        <img alt="example" src={this.props.children && handlePicUrl(this.props.children)} style={{ width: '100%', objectFit: "cover" }} height='120' />
        {this.state.mouseState &&
          <div style={{
            position: 'absolute',
            width: '100%',
            background: '#666666',
            opacity: '0.5',
            height: '100%',
            bottom: 0,
            left: 0,
            right: 0,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-around',
            fontSize: '25px',
            color: 'white'
          }}>

            <Icon type="search" onClick={() => this.onShowImage(this.props.itemsIndex)} />
            <Icon type="delete" onClick={() => this.delImageList(this.props.itemsIndex)} />
          </div>}
        <Modal
          zIndex='100000'
          closable={false}
          footer={null}
          visible={this.state.showImageState}
          onCancel={this.handleCancel}
          onOk={this.handleOk}
        >
          <a style={{ color: 'white' }} href={this.state.imageUrl && handlePicUrl(this.state.imageUrl)} download={this.state.imageUrl && handlePicUrl(this.state.imageUrl)} target='_blank'>
            <Button type='primary' style={{ float: 'right', margin: '5px 0' }} >
              <Icon type="download" />下载图片
          </Button>
          </a>
          <img alt="example" src={this.state.imageUrl && handlePicUrl(this.state.imageUrl)} style={{ width: '100%' }} />
        </Modal>
      </li>
    )
  }
}


var SortableItem = sortable(Item);


class SortableList extends Component {
  construtor(props) {
    this.state = {
      items: this.props.items
    }
  }
  state = {
    items: this.props.items
  };

  onSortItems = (items) => {
    this.setState({
      items: items
    });
  }
  // 删除更新
  onChangeState = (changeList) => {
    this.setState(changeList);
  }
  componentWillUnmount(){
    items=[]
  }
  // 上传图片
  handleChange = info => {
    let fileSize = info.size / 1025
    if (fileSize > 500) { message.error('上传图片大小不能超过500K') } else {
      if (info.file.status === 'uploading') {
        this.setState({ loading: true });
        return;
      }
      if (info.file.status === 'done') {
        if (info.file.response.code == 200) {
          let obj = info.file.response.data.picUrl;
          let { items } = this.state
          items.push(obj)
          let that = this;
          setTimeout(function () {
            that.setState({ loading: false, items });
            that.props.onClicked({ items })
          }, 400);
        }
      }
    }
  };
  componentDidMount() {
    let token = Author.getToken();
    this.setState({ token });
    if (this.props.items) {
      this.setState({
        items: this.props.items
      })
    }
  }
  beforeUploadImage = (file) => {
    const isJpgOrPng = file.type === 'image/jpeg';
    if (!isJpgOrPng) {
      message.error('该上传仅支持image/jpeg格式图片!');
    }
    const isLt2M = file.size / 1024 / 1024 < 10;
    if (!isLt2M) {
      message.error('图片大小不能大于10m!');
    }
    return isJpgOrPng && isLt2M;
  }
  render() {
    const { items } = this.state || this.props;
    const props = {
      action: configBase.server + API.GOODS_MANAGE.saveProdPicture,
      name: 'file',
      headers: {
        Authorization: `Bearer ${this.state.token}`
      },
      onChange: this.handleChange,
      showUploadList: false,
    };
    var listItems = items.map((item, i) => {
      return (
        <SortableItem
          onClicked={this.onChangeState.bind(this)}
          itemsIndex={i}
          onSortItems={this.onSortItems}
          items={items}
          sortId={i}>{item}</SortableItem>
      );
    });

    return (
      <ul className='sortable-list' onClicked={this.onChangeState.bind(this)} style={{ overflow: 'hidden' }}>
        {listItems}
        {this.state.items.length < 8 &&
          <li {...this.props}
            style={{
              width: '126px',
              height: '140px',
              float: 'left',
              border: '1px solid #dddddd',
              borderRadius: '4px',
              position: 'relative',
              overflow: 'hidden',
              padding: '10px',
              marginRight: '10px',
              marginBottom: '10px',
            }} >
            <Upload
              name="avatar"
              listType="picture-card"
              className="avatar-uploader"
              style={{ width: '98px', height: '116px' }}
              {...props}
              multiple={true}
              beforeUpload={this.beforeUploadImage}
            >
              <div>
                <Icon type={this.state.loading ? 'loading' : 'plus'} />
                <div className="ant-upload-text">图片上传</div>
              </div>
            </Upload>
          </li>}
      </ul>
    )
  }
};


export default class stockGoods extends Component {
  constructor(props) {
    super(props)
    this.state = {
      isSetting: false
    }
    this.props.onRef(this);       //  点击下一步--父子传值
  }

  componentDidMount() {
    let token = Author.getToken();
    this.setState({ token });
    if (this.props.goodsImageItem) {
      items = this.props.goodsImageItem && this.props.goodsImageItem.split(',') || [];
      this.setState({ isSetting: true }, () => {
        items = this.props.goodsImageItem && this.props.goodsImageItem.split(',') || [];
      })
      let videoUrl = this.props.videoUrl || '';
      this.setState({ videoUrl })
    } else {
      this.setState({ isSetting: true })
    }

  }
  // 父组件调用子组件方法获取数据
  childMethod = () => {
    let productPic = items.join(',');
    let { videoUrl } = this.state
    return { productPic, videoUrl }
  }
  onChangeState = (data) => {
    let newItems = data.items;
    items = newItems
  }
  // 鼠标移入
  handleMouseOver = (e) => {
    e.stopPropagation();
    this.setState({ mouseState: true })
  }
  // 鼠标移出
  handleMouseOut = (e) => {
    e.stopPropagation();
    this.setState({ mouseState: false })
  }
  // 视频上传回调
  beforeVideoUpload = info => {
    let fileSize = info.size / 1025
    if (fileSize > 500) { message.error('上传视频大小不能超过500K') } else {
      if (info.file.status === 'uploading') {
        this.setState({ loading: true });
        return;
      }
      if (info.file.status === 'done') {
        if (info.file.response.code == 200) {
          let videoUrl = info.file.response.data.picUrl;
          let that = this;
          setTimeout(function () {
            that.setState({ loading: false, videoUrl });
          }, 400);
          ;

        }

      }
    }
  }
  beforeUpload = (file) => {
    const isJpgOrPng = file.type === 'video/mp4';
    if (!isJpgOrPng) {
      message.error('该上传仅支持视频上传!');
    }
    const isLt2M = file.size / 1024 / 1024 < 10;
    if (!isLt2M) {
      message.error('视频大小不能大于10m!');
    }
    return isJpgOrPng && isLt2M;
  }
  render() {
    const props = {
      action: configBase.server + API.GOODS_MANAGE.saveProdPicture,
      name: 'file',
      headers: {
        Authorization: `Bearer ${this.state.token}`
      },
      onChange: this.beforeVideoUpload,
      showUploadList: false,
    };
    return (
      <>
        <Row>
          <Col span={20} offset={2} style={{ marginBottom: '40px' }}>
            <Row >
              <Col>
                <div style={{ fontSize: '16px', }}>上传图片提示:</div>
                <div style={{ marginLeft: '30px', fontSize: '16px', padding: '5px 0' }}>1. 本地上传图片大小不能超过<span style={{ color: '#f60' }}> 500K </span></div>
                <div style={{ marginLeft: '30px', fontSize: '16px', padding: '5px 0', marginBottom: '15px' }}>2. 本类目下您最多可以上传  <span style={{ color: '#f60' }}>8 </span>张图片。</div>
                {this.state.isSetting && <SortableList items={items} onClicked={this.onChangeState.bind(this)} />}
                <div><span style={{ color: '#f60' }}> 450*450 </span>以上的图片可以在商品详情页主图提供图片放大功能 (图片可以拖动排序)</div>
              </Col>
            </Row>
          </Col>
          <Divider />
          <Col span={20} offset={2} style={{ marginTop: '15px' }}>
            <div style={{ fontSize: '16px', }}>上传视频提示:</div>
            <div style={{ marginLeft: '30px', fontSize: '16px', padding: '5px 0' }}>1. 本地上传视频大小不能超过<span style={{ color: '#f60' }}> 10M </span></div>
            <div style={{ marginLeft: '30px', fontSize: '16px', padding: '5px 0', marginBottom: '15px' }}>2. 本类目下您最多可以上传  <span style={{ color: '#f60' }}>1 </span>段视频。</div>
            <ul>
              {
                !this.state.videoUrl &&
                <li {...this.props}
                  style={{
                    width: '126px',
                    height: '140px',
                    float: 'left',
                    border: '1px solid #dddddd',
                    borderRadius: '4px',
                    position: 'relative',
                    overflow: 'hidden',
                    padding: '10px',
                    marginRight: '10px',
                    marginBottom: '10px',
                  }}>
                  <Upload
                    name="avatar"
                    listType="picture-card"
                    className="avatar-uploader"
                    style={{ width: '98px', height: '116px' }}
                    {...props}
                    multiple={true}
                    beforeUpload={this.beforeUpload}
                    accept='video'
                  >
                    <div>
                      <Icon type={this.state.loading ? 'loading' : 'plus'} />
                      <div className="ant-upload-text">视频上传</div>
                    </div>
                  </Upload>
                </li>}

              {
                this.state.videoUrl &&
                <li
                  style={{
                    width: '126px',
                    height: '140px',
                    float: 'left',
                    border: '1px solid #dddddd',
                    borderRadius: '4px',
                    position: 'relative',
                    overflow: 'hidden',
                    padding: '10px',
                    marginRight: '10px',
                    marginBottom: '10px',
                  }}
                  onMouseEnter={(e) => this.handleMouseOver(e)}
                  onMouseLeave={(e) => this.handleMouseOut(e)}
                >
                  <video src={baseImgUrl + this.state.videoUrl} width='105' height='120' style={{ objectFit: 'fill' }} ></video>
                  {
                    this.state.mouseState &&
                    <div style={{
                      position: 'absolute',
                      width: '100%',
                      background: '#666666',
                      opacity: '0.5',
                      height: '100%',
                      bottom: 0,
                      left: 0,
                      right: 0,
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'space-around',
                      fontSize: '25px',
                      color: 'white'
                    }}
                    >
                      <Icon type="search" onClick={() => this.setState({ videoVisiable: true ,videoModalUrl:this.state.videoUrl})} />
                      <Icon type="delete" onClick={() => this.setState({ videoUrl: '' })} />
                    </div>
                  }
                </li>}
            </ul>
          </Col>
        </Row>
        <Modal
          visible={this.state.videoVisiable}
          onCancel={() => this.setState({ videoVisiable: false ,videoModalUrl:''})}
          width={800}
          footer={null}
        >
          <video src={baseImgUrl + this.state.videoModalUrl} width='400' height='600' style={{ objectFit: 'fill' }} controls="controls" autoplay="autoplay"></video>
        </Modal>
      </>
    )
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值