From f895e8af9e6a393f71fec0dc26fdf1b9b6616cb4 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 11 十二月 2020 18:53:04 +0800
Subject: [PATCH] 2020-12-11

---
 src/templates/zshare/modalform/datatable/index.jsx |  140 ++++++++++++++++++++++++++++++++--------------
 1 files changed, 97 insertions(+), 43 deletions(-)

diff --git a/src/templates/zshare/modalform/datatable/index.jsx b/src/templates/zshare/modalform/datatable/index.jsx
index d05be5e..50e0cc6 100644
--- a/src/templates/zshare/modalform/datatable/index.jsx
+++ b/src/templates/zshare/modalform/datatable/index.jsx
@@ -1,6 +1,7 @@
 import React, { Component } from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
+import { DndProvider, DragSource, DropTarget } from 'react-dnd'
 import { Table, Input, Popconfirm, Form, Icon, notification } from 'antd'
 
 import Utils from '@/utils/utils.js'
@@ -8,6 +9,64 @@
 import './index.scss'
 
 const EditableContext = React.createContext()
+let dragingIndex = -1
+
+class BodyRow extends React.Component {
+  render() {
+    const { isOver, moveAble, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props
+    let { className } = restProps
+
+    if (isOver && moveAble) {
+      if (restProps.index > dragingIndex) {
+        className += ' drop-over-downward'
+      }
+      if (restProps.index < dragingIndex) {
+        className += ' drop-over-upward'
+      }
+    }
+
+    if (moveAble) {
+      return connectDragSource(
+        connectDropTarget(<tr {...restProps} className={className} style={{...restProps.style, cursor: 'move'}} />),
+      )
+    } else {
+      return (<tr {...restProps} className={className} style={restProps.style} />)
+    }
+  }
+}
+
+const rowSource = {
+  beginDrag(props) {
+    dragingIndex = props.index
+    return {
+      index: props.index,
+    }
+  }
+}
+
+const rowTarget = {
+  drop(props, monitor) {
+    const dragIndex = monitor.getItem().index
+    const hoverIndex = props.index
+
+    if (dragIndex === hoverIndex) {
+      return
+    }
+
+    props.moveRow(dragIndex, hoverIndex)
+
+    monitor.getItem().index = hoverIndex
+  },
+}
+
+const DragableBodyRow = DropTarget('row', rowTarget, (connect, monitor) => ({
+  connectDropTarget: connect.dropTarget(),
+  isOver: monitor.isOver(),
+}))(
+  DragSource('row', rowSource, connect => ({
+    connectDragSource: connect.dragSource(),
+  }))(BodyRow),
+)
 
 class EditableCell extends Component {
   getInput = (form) => {
@@ -161,8 +220,9 @@
     })
 
     columns.push({
-      title: 'operation',
+      title: '鎿嶄綔',
       dataIndex: 'operation',
+      align: 'center',
       width: '18%',
       render: (text, record) => {
         const { editingKey } = this.state
@@ -181,8 +241,6 @@
         ) : (
           <div className={'operation-btn' + (editingKey !== '' ? ' disabled' : '')}>
             <span className="primary" onClick={() => {editingKey === '' && this.edit(record.key)}}><Icon type="edit" /></span>
-            <span className="primary" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'up')}}><Icon type="arrow-up" /></span>
-            <span className="danger" onClick={() => {editingKey === '' && this.handleUpDown(record.key, 'down')}}><Icon type="arrow-down" /></span>
             {editingKey === '' ? <Popconfirm
               overlayClassName="popover-confirm"
               title={this.props.dict['model.query.delete']}
@@ -219,27 +277,6 @@
   handleDelete = (key) => {
     const { data } = this.state
     let _data = data.filter(item => key !== item.key)
-
-    this.setState({
-      data: _data
-    }, () => {
-      this.props.onChange(_data)
-    })
-  }
-
-  handleUpDown = (key, direction) => {
-    let _data = fromJS(this.state.data).toJS()
-    const index = _data.findIndex(item => key === item.key)
-
-    if ((index === 0 && direction === 'up') || (index === _data.length - 1 && direction === 'down')) {
-      return
-    }
-
-    if (direction === 'up') {
-      _data.splice(index - 1, 0, ..._data.splice(index, 1))
-    } else {
-      _data.splice(index + 1, 0, ..._data.splice(index, 1))
-    }
 
     this.setState({
       data: _data
@@ -286,14 +323,7 @@
 
   handleAdd = () => {
     const { fields, type } = this.props
-    if (this.state.editingKey) {
-      notification.warning({
-        top: 92,
-        message: '璇蜂繚瀛樼紪杈戜腑鐨勫厓绱狅紒',
-        duration: 5
-      })
-      return
-    } else if (this.state.data.length >= 20) {
+    if (this.state.data.length >= 20) {
       notification.warning({
         top: 92,
         message: '鏈�澶氬彲娣诲姞20椤癸紒',
@@ -314,7 +344,7 @@
 
     let data = [...this.state.data, item]
 
-    this.setState({ data }, () => {
+    this.setState({ data, editingKey: '' }, () => {
       this.props.onChange(data)
     })
   }
@@ -323,11 +353,27 @@
     this.setState({ editingKey: key })
   }
 
+  moveRow = (dragIndex, hoverIndex) => {
+    const { editingKey } = this.state
+    let _data = fromJS(this.state.data).toJS()
+
+    if (editingKey) return
+
+    _data.splice(hoverIndex, 0, ..._data.splice(dragIndex, 1))
+
+    this.setState({
+      data: _data
+    }, () => {
+      this.props.onChange(_data)
+    })
+  }
+
   render() {
     const components = {
       body: {
-        cell: EditableCell,
-      },
+        row: DragableBodyRow,
+        cell: EditableCell
+      }
     }
 
     const columns = this.state.columns.map(col => {
@@ -358,14 +404,22 @@
       <EditableContext.Provider value={this.props.form}>
         <div className="modal-card-data-table">
           {addable ? <Icon className="add-row" type="plus" onClick={this.handleAdd} /> : null}
-          <Table
-            components={components}
-            bordered
-            dataSource={this.state.data}
-            columns={columns}
-            rowClassName="editable-row"
-            pagination={false}
-          />
+          <DndProvider>
+            <Table
+              components={components}
+              bordered
+              rowKey="key"
+              dataSource={this.state.data}
+              columns={columns}
+              rowClassName="editable-row"
+              onRow={(record, index) => ({
+                index,
+                moveAble: !this.state.editingKey,
+                moveRow: this.moveRow,
+              })}
+              pagination={false}
+            />
+          </DndProvider>
         </div>
       </EditableContext.Provider>
     )

--
Gitblit v1.8.0