king
2020-03-06 e2ac71fbc53b7119ae87c5a3b08cdcf830b497e2
src/views/printTemplate/index.jsx
@@ -1,43 +1,65 @@
import React, {Component} from 'react'
import { DndProvider } from 'react-dnd'
import { is, fromJS } from 'immutable'
import HTML5Backend from 'react-dnd-html5-backend'
import { Card } from 'antd'
import { Card, notification, Row, Button, Modal } from 'antd'
import DragElement from './dragelement'
import MutilForm from './mutilform'
import SourceElement from './dragelement/source'
import {
  printItems,
  originConfig,
  getpageform,
  getTextForm,
  getBarcodeForm,
  getQrcodeForm,
  getImageForm,
  getElement,
  barurl,
  qrurl,
  imgurl
} from './option.js'
import Utils from '@/utils/utils.js'
import printCtrl from './print.js'
import Api from '@/api'
import './index.scss'
const printItems = [
  {
    type: 'print',
    label: '文本',
    subType: 'text',
    icon: 'file-text'
  },
  {
    type: 'print',
    label: '条形码',
    subType: 'barcode',
    icon: 'barcode'
  },
  {
    type: 'print',
    label: '二维码',
    subType: 'qrcode',
    icon: 'qrcode'
  },
  {
    type: 'print',
    label: '图片',
    subType: 'picture',
    icon: 'file-image'
  }
]
const { confirm } = Modal
let dropPoint = null
let origin = null
let timer = null
let preorigin = null
let nextorigin = null
class PrintTemplate extends Component {
  state = {
    ID: null
    config: null,
    ID: null,
    editItemId: '',
    editItemType: '',
    fields: [],
    formlist: null,
    saveloading: false
  }
  componentDidMount () {
  getclickpoint = (e) => {
    const { config } = this.state
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
    let screenX = e.clientX
    let screenY = e.clientY + scrollTop
    let offsetT = screenY - document.getElementById('darea').offsetTop
    let offsetL = screenX - document.getElementById('darea').offsetLeft
    let cx = Math.floor(offsetL / parseInt(document.getElementById('darea').style.width) * config.width)
    let cy = Math.floor(offsetT / parseInt(document.getElementById('darea').style.height) * config.height)
    return {
      cx: cx,
      cy: cy
    }
  }
  UNSAFE_componentWillMount () {
    let _param = window.atob(this.props.match.params.param)
    let _params = {}
    _param.split('&').forEach(cell => {
@@ -47,6 +69,632 @@
    this.setState({
      ID: _params.ID
    })
  }
  componentDidMount () {
    // 点击切换编辑元素
    document.getElementById('darea').addEventListener('click', (e) => {
      e.stopPropagation()
      let position = this.getclickpoint(e)
      let cx = position.cx
      let cy = position.cy
      let _selectItem = null
      let _config = JSON.parse(JSON.stringify(this.state.config))
      _config.elements.forEach(element => {
        let x = +element.left
        let y = +element.top
        let width = +element.width
        let height = +element.height
        let rotate = +element.rotate
        if (rotate === 90 || rotate === 270) {
          let _c = width
          x = x + width / 2 - height / 2
          y = y + height / 2 - width / 2
          width = height
          height = _c
        }
        if (width === 0) {
          x -= 4
          width = 8
        }
        if (height === 0) {
          y -= 4
          height = 8
        }
        if (cx > x && cx < x + width && cy > y && cy < y + height) {
          _selectItem = element
        }
      })
      if (!_selectItem) {
        _selectItem = _config
      } else {
        _config.elements = _config.elements.filter(ele => ele.uuid !== _selectItem.uuid)
        _config.elements.push(_selectItem)
      }
      let _formlist = null
      if (_selectItem.type === 'Template') {
        _formlist = getpageform(_selectItem)
      } else if (_selectItem.type === 'text') {
        _formlist = getTextForm(_selectItem, this.state.fields)
      } else if (_selectItem.type === 'barcode') {
        _formlist = getBarcodeForm(_selectItem, this.state.fields)
      } else if (_selectItem.type === 'qrcode') {
        _formlist = getQrcodeForm(_selectItem, this.state.fields)
      } else if (_selectItem.type === 'image') {
        _formlist = getImageForm(_selectItem, this.state.fields)
      }
      this.setState({
        config: _config,
        editItemId: _selectItem.uuid,
        editItemType: _selectItem.type,
        formlist: _formlist
      }, () => {
        this.resetview()
      })
    })
    // 触发拖动事件
    document.getElementById('darea').addEventListener('mousedown', (e) => {
      const { config } = this.state
      if (!this.state.editItemType || this.state.editItemType === 'Template') {
        origin = null
        return
      }
      let _selectItem = JSON.parse(JSON.stringify(this.state.config.elements.filter(ele => ele.uuid === this.state.editItemId)[0]))
      let _preItem = JSON.parse(JSON.stringify(_selectItem))
      let position = this.getclickpoint(e)
      let cx = position.cx
      let cy = position.cy
      let x = +_selectItem.left
      let y = +_selectItem.top
      let width = +_selectItem.width
      let height = +_selectItem.height
      let rotate = +_selectItem.rotate
      if (rotate === 90 || rotate === 270) {
        let _c = width
        x = x + width / 2 - height / 2
        y = y + height / 2 - width / 2
        width = height
        height = _c
      }
      if (width === 0) {
        x -= 4
        width = 8
      }
      if (height === 0) {
        y -= 4
        height = 8
      }
      if (cx > x && cx < x + width && cy > y && cy < y + height) {
        if (width > 3 && height > 3 && cx > x + width - 3 && cx < x + width + 2 && cy > y + height - 3 && cy < y + height + 2) {
          origin = {
            cx: cx,
            cy: cy,
            width: +_selectItem.width,
            height: +_selectItem.height
          }
          timer = setInterval(() => {
            if (JSON.stringify(preorigin) !== JSON.stringify(nextorigin)) {
              preorigin = nextorigin
              let _width = origin.width + (nextorigin.cx - origin.cx)
              let _height = origin.height + (nextorigin.cy - origin.cy)
              if (_width < 0) {
                _width = 0
              } else if (_selectItem.left + _width > config.width) {
                _width = config.width - _selectItem.left
              }
              if (_height < 0) {
                _height = 0
              } else if (_height + _selectItem.top > config.height) {
                _height = config.height - _selectItem.top
              }
              _selectItem.width = _width
              _selectItem.height = _height
              let result = this.resetItem(_selectItem)
              if (!is(fromJS(result), fromJS(_preItem))) {
                _preItem = JSON.parse(JSON.stringify(result))
                this.FormRef.resetForm(result)
                config.elements = config.elements.map(item => {
                  if (item.uuid === result.uuid) return result
                  return item
                })
                this.setState({
                  config: config
                }, () => {
                  this.resetview()
                })
              }
            }
          }, 100)
        } else {
          origin = {
            cx: cx,
            cy: cy,
            left: +_selectItem.left,
            top: +_selectItem.top
          }
          timer = setInterval(() => {
            if (JSON.stringify(preorigin) !== JSON.stringify(nextorigin)) {
              preorigin = nextorigin
              let _left = origin.left + (nextorigin.cx - origin.cx)
              let _top = origin.top + (nextorigin.cy - origin.cy)
              if (_left < 0) {
                _left = 0
              } else if (_left + _selectItem.width > config.width) {
                _left = config.width - _selectItem.width
              }
              if (_top < 0) {
                _top = 0
              } else if (_top + _selectItem.height > config.height) {
                _top = config.height - _selectItem.height
              }
              _selectItem.left = _left
              _selectItem.top = _top
              let result = this.resetItem(_selectItem)
              if (!is(fromJS(result), fromJS(_preItem))) {
                _preItem = JSON.parse(JSON.stringify(result))
                this.FormRef.resetForm(result)
                config.elements = config.elements.map(item => {
                  if (item.uuid === result.uuid) return result
                  return item
                })
                this.setState({
                  config: config
                }, () => {
                  this.resetview()
                })
              }
            }
          }, 100)
        }
      } else {
        origin = null
      }
    })
    document.getElementById('darea').addEventListener('mousemove', (e) => {
      if (!this.state.editItemType || this.state.editItemType === 'Template' || !origin) {
        return
      }
      let position = this.getclickpoint(e)
      nextorigin = {
        cx: position.cx,
        cy: position.cy
      }
    })
    document.getElementById('darea').addEventListener('mouseup', (e) => {
      origin = null
      clearInterval(timer)
    })
    document.getElementById('darea').addEventListener('mouseleave', (e) => {
      origin = null
      clearInterval(timer)
    })
    // 元素添加
    document.getElementById('darea').addEventListener('drop', (e) => {
      dropPoint = this.getclickpoint(e)
    })
    if (document.body.offsetWidth < 1360) {
      document.getElementById('darea').style.width = '600px'
    } else if (document.body.offsetWidth < 1500) {
      document.getElementById('darea').style.width = '700px'
    } else if (document.body.offsetWidth < 1920) {
      document.getElementById('darea').style.width = '800px'
    }
    this.loadconfig()
  }
  resetbox = () => {
    const { config } = this.state
    let ratio = (config.height || 1) / (config.width || 1)
    document.getElementById('darea').style.height = parseInt(document.getElementById('darea').style.width) * ratio + 'px'
    printCtrl.sketch(config, null)
  }
  resetview () {
    const { config, editItemId } = this.state
    printCtrl.sketch(config, editItemId)
  }
  /**
   * @description 获取模板配置信息
   */
  async loadconfig () {
    let param = {
      func: 's_PrintTemplateMGetData',
      ID: this.state.ID
    }
    let result = await Api.getCloudConfig(param)
    if (result.status) {
      let _config = ''
      if (result.ConfigParam) {
        try {
          _config = JSON.parse(window.decodeURIComponent(window.atob(result.ConfigParam)))
        } catch (e) {
          notification.warning({
            top: 92,
            message: '配置信息解析错误!',
            duration: 10
          })
          _config = ''
        }
      }
      if (!_config) {
        _config = originConfig
      }
      _config.name = result.PrintTempName || ''
      _config.remark = result.Remark || ''
      _config.PrintTempNO = result.PrintTempNO || ''
      _config.type = 'Template'
      _config.uuid = Utils.getuuid()
      if (result.data && result.data[0] && result.data[0].TableName) {
        this.loadFields(result.data[0].TableName)
      }
      this.setState({
        config: _config,
        editItemId: _config.uuid,
        editItemType: _config.type,
        formlist: getpageform(_config)
      }, () => {
        this.resetbox()
      })
    } else {
      notification.warning({
        top: 92,
        message: result.ErrMesg,
        duration: 10
      })
    }
  }
  /**
   * @description 获取可用字段
   */
  async loadFields (TBName) {
    let param = {
      func: 'sPC_Get_FieldName',
      TBName: TBName
    }
    let result = await Api.getCloudConfig(param)
    if (result.status) {
      let _fields = [{
        value: '',
        text: '空',
        type: ''
      }]
      let _f = new Map()
      result.FDName.forEach(item => {
        if (item.FieldName && !_f.has(item.FieldName)) {
          _f.set(item.FieldName, true)
          _fields.push({
            value: item.FieldName,
            text: item.FieldDec,
            type: item.FieldType
          })
        }
      })
      this.setState({
        fields: _fields
      })
    } else {
      notification.warning({
        top: 92,
        message: result.ErrMesg,
        duration: 10
      })
    }
  }
  dropcard = (item) => {
    const { config } = this.state
    let position = null
    if (dropPoint) {
      position = dropPoint
      dropPoint = null
    } else {
      return
    }
    let _width = Math.floor(config.width / 4)
    let _height = Math.floor(_width / 2)
    let _cx = Math.floor(position.cx - _width / 2)
    let _cy = Math.floor(position.cy - _height / 2)
    if (_cx < 0) { // 元素添加时,避免超出边界
      _cx = 0
    } else if (_cx + _width > config.width) {
      _cx = Math.floor(config.width - _width)
    }
    if (_cy < 0) {
      _cy = 0
    } else if (_cy + _height > config.height) {
      _cy = Math.floor(config.height - _height)
    }
    let _selectItem = null
    let _formlist = null
    if (item.subType === 'text') {
      _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height)
      _formlist = getTextForm(_selectItem, this.state.fields)
    } else if (item.subType === 'barcode') {
      _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height, barurl, config.width)
      _formlist = getBarcodeForm(_selectItem, this.state.fields)
    } else if (item.subType === 'qrcode') {
      _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height, qrurl)
      _formlist = getQrcodeForm(_selectItem, this.state.fields)
    } else if (item.subType === 'image') {
      _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height, imgurl)
      _formlist = getImageForm(_selectItem, this.state.fields)
    }
    config.elements.push(_selectItem)
    this.setState({
      config: config,
      editItemId: _selectItem.uuid,
      editItemType: _selectItem.type,
      formlist: _formlist
    }, () => {
      this.resetview()
    })
  }
  resetItem = (item) => {
    let _item = JSON.parse(JSON.stringify(item))
    const { config } = this.state
    let _boxwidth = +config.width
    let _boxheight = +config.height
    let _left = +_item.left
    let _top = +_item.top
    let _width = +_item.width
    let _height = +_item.height
    if (_left < 0) {
      _item.left = 0
    }
    if (_top < 0) {
      _item.top = 0
    }
    if (_left + _width > _boxwidth) {
      _item.width = _boxwidth - _left
    }
    if (_top + _height > _boxheight) {
      _item.height = _boxheight - _top
    }
    if (_item.type === 'barcode') {
      if (+_item.barcodeWidth > +_item.width) {
        _item.barcodeWidth = +_item.width
      }
      if (+_item.barcodeHeight > +_item.height) {
        _item.barcodeHeight = +_item.height
      }
    } else if (_item.type === 'qrcode') {
      if (+_item.qrcodeWidth > +_item.width) {
        _item.qrcodeWidth = +_item.width
      }
      if (+_item.qrcodeWidth > +_item.height) {
        _item.qrcodeWidth = +_item.height
      }
    } else if (_item.type === 'image') {
      if (+_item.imgWidth > +_item.width) {
        _item.imgWidth = +_item.width
      }
      if (+_item.imgHeight > +_item.height) {
        _item.imgHeight = +_item.height
      }
    }
    return _item
  }
  handleSubmit = () => {
    const { config } = this.state
    this.FormRef.handleConfirm().then(res => {
      if (res.type === 'Template') {
        res.width = parseInt(res.width)
        res.height = parseInt(res.height)
        if (res.width < 1) {
          res.width = 1
          this.FormRef.resetForm({width: 1})
        } else if (res.height < 1) {
          res.height = 1
          this.FormRef.resetForm({height: 1})
        }
        this.setState({
          config: {...config, ...res}
        }, () => {
          if (res.width !== config.width || res.height !== config.height) {
            this.resetbox()
          }
        })
      } else {
        if (res.type === 'barcode') {
          res.url = barurl
        } else if (res.type === 'qrcode') {
          res.url = qrurl
        } else if (res.type === 'image') {
          res.url = imgurl
        }
        let result = this.resetItem(res)
        if (!is(fromJS(result), fromJS(res))) {
          this.FormRef.resetForm(result)
        }
        config.elements = config.elements.map(item => {
          if (item.uuid === result.uuid) return result
          return item
        })
        this.setState({
          config: config
        }, () => {
          this.resetview()
        })
      }
    })
  }
  deleteItem = () => {
    const _this = this
    const { editItemId, config } = this.state
    confirm({
      title: '确定删除该元素吗?',
      okText: '确定',
      cancelText: '取消',
      onOk() {
        config.elements = config.elements.filter(item => item.uuid !== editItemId)
        _this.setState({
          config: config,
          editItemId: config.uuid,
          editItemType: config.type,
          formlist: getpageform(config)
        }, () => {
          _this.resetview()
        })
      },
      onCancel() {}
    })
  }
  submitConfig = () => {
    const { config } = this.state
    if (config.height / config.width > 10 || config.width / config.height > 10) {
      notification.warning({
        top: 92,
        message: '纸张纵横比不可超过10!',
        duration: 10
      })
      return
    }
    this.setState({
      saveloading: true
    })
    let _config = ''
    try {
      _config = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
    } catch {
      notification.warning({
        top: 92,
        message: '编译错误!',
        duration: 10
      })
      return
    }
    let param = {
      func: 's_PrintTemplateMSub',
      ID: this.state.ID,
      ConfigParam: _config,
      Images: '',
      PrintTempName: config.name,
      Remark: config.remark,
      PrintTempNO: config.PrintTempNO
    }
    new Promise(resolve => {
      printCtrl.sketch(config, null).then(res => {
        Api.fileuploadbase64(res, 'cloud').then(result => { // 图片上传,并获取图片路径
          if (result.status) {
            resolve(Utils.getcloudurl(result.Images))
          } else {
            // notification.warning({
            //   top: 92,
            //   message: result.ErrMesg,
            //   duration: 10
            // })
            // this.setState({
            //   saveloading: false
            // })
            // resolve(false)
            resolve(true)
          }
        })
      })
    }).then(res => {
      if (!res) return
      param.Images = 'http://css.positecgroup.com/Content/Upload/2020-01-08/2020010810525808769824_U000000001.png'
      return Api.getCloudConfig(param)
    }).then(res => {
      if (!res) return
      if (res.status) {
        notification.success({
          top: 92,
          message: '保存成功',
          duration: 2
        })
      } else {
        notification.warning({
          top: 92,
          message: res.ErrMesg,
          duration: 10
        })
      }
      this.setState({
        saveloading: false
      })
    })
  }
@@ -62,10 +710,33 @@
              })}
            </Card>
          </aside>
          <DragElement dropcard={this.dropcard} />
          <aside className="setting">
            <Card title="状态栏">
            </Card>
            {this.state.editItemId ?
              <Card title="状态栏">
                {this.state.formlist ?
                  <MutilForm
                    config={this.state.config}
                    formlist={this.state.formlist}
                    inputSubmit={this.handleSubmit}
                    editItem={{uuid: this.state.editItemId, type: this.state.editItemType}}
                    wrappedComponentRef={(inst) => this.FormRef = inst}
                  /> : null
                }
                <div className="operation">
                  {this.state.editItemType === 'Template' ?
                    <Row gutter={24}>
                      <Button type="primary" onClick={this.submitConfig} loading={this.state.saveloading}>保存</Button>
                    </Row> : null
                  }
                  {this.state.editItemType !== 'Template' ?
                    <Row gutter={24}>
                      <Button type="danger" onClick={this.deleteItem}>删除</Button>
                    </Row> : null
                  }
                </div>
              </Card> : null
            }
          </aside>
        </DndProvider>
      </div>