Your Name 4 vuotta sitten
vanhempi
commit
9e79691bf1

+ 1
- 0
package.json Näytä tiedosto

@@ -66,6 +66,7 @@
66 66
     "react-dom": "^17.0.0",
67 67
     "react-helmet-async": "^1.0.4",
68 68
     "react-player": "^2.9.0",
69
+    "react-sortable-hoc": "^2.0.0",
69 70
     "umi": "^3.4.1",
70 71
     "umi-request": "^1.0.8",
71 72
     "wangeditor": "^4.6.15"

src/components/DndTr/Provider.jsx → src/components/DndRow/Provider.jsx Näytä tiedosto


src/components/DndTr/index.jsx → src/components/DndRow/index.jsx Näytä tiedosto

@@ -3,15 +3,15 @@ import useDnd from '@/utils/hooks/useDnd'
3 3
 
4 4
 export default (props) => {
5 5
   const ref = useRef();
6
-  const { index, bizId, moveRow, ...restProps } = props;
6
+  const { id, moveRow, ...restProps } = props;
7 7
   const { dragPreview, dragSource, dropTarget, onDrop } = useDnd({
8
-    item: { index, id: bizId },
8
+    item: { id },
9 9
   });
10 10
 
11 11
   onDrop((item) => {
12 12
     moveRow({
13
-      source: item,
14
-      target: { index, id: bizId }
13
+      from: item.id,
14
+      to: id,
15 15
     });
16 16
   });
17 17
 

+ 5
- 0
src/components/DragTable/DragHandle.jsx Näytä tiedosto

@@ -0,0 +1,5 @@
1
+import React from 'react';
2
+import { sortableHandle } from 'react-sortable-hoc';
3
+import { MenuOutlined } from '@ant-design/icons';
4
+
5
+export default sortableHandle(() => <MenuOutlined style={{ cursor: 'grab', color: '#999' }} />);

+ 15
- 0
src/components/DragTable/DraggableContainer.jsx Näytä tiedosto

@@ -0,0 +1,15 @@
1
+import React from 'react';
2
+import { sortableContainer } from 'react-sortable-hoc';
3
+import Styles from './style.less'
4
+
5
+export const SortableContainer = sortableContainer(props => <tbody {...props} />);
6
+
7
+export default (props) => (
8
+  <SortableContainer
9
+    useDragHandle
10
+    disableAutoscroll
11
+    helperClass={Styles['row-dragging']}
12
+    onSortEnd={props.onSortEnd}
13
+    {...props}
14
+  />
15
+);

+ 11
- 0
src/components/DragTable/DraggableRow.jsx Näytä tiedosto

@@ -0,0 +1,11 @@
1
+import React from 'react';
2
+import { sortableElement } from 'react-sortable-hoc';
3
+
4
+export const SortableItem = sortableElement(props => <tr {...props} />);
5
+
6
+export default function withDraggableRow(dataSource) {
7
+  return (props) => {
8
+    const index = dataSource.current.findIndex(x => x.serialNo === props['data-row-key']);
9
+    return  <SortableItem index={index} {...props} />
10
+  }
11
+}

+ 11
- 0
src/components/DragTable/index.jsx Näytä tiedosto

@@ -0,0 +1,11 @@
1
+import DraggableContainer, { SortableContainer } from './DraggableContainer';
2
+import withDraggableRow, { SortableItem } from './DraggableRow';
3
+import DragHandle from './DragHandle'
4
+
5
+export {
6
+  DraggableContainer,
7
+  withDraggableRow,
8
+  SortableContainer,
9
+  SortableItem,
10
+  DragHandle,
11
+}

+ 13
- 0
src/components/DragTable/style.less Näytä tiedosto

@@ -0,0 +1,13 @@
1
+
2
+.row-dragging {
3
+  background: #fafafa;
4
+  border: 1px solid rgba(0, 0, 0, .02);
5
+
6
+  td {
7
+    // padding: 1em;
8
+  }
9
+
10
+  .drag-visible {
11
+    visibility: visible;
12
+  }
13
+}

+ 5
- 5
src/pages/Cms/Banner/List/index.jsx Näytä tiedosto

@@ -6,7 +6,7 @@ import { PlusOutlined, MenuOutlined } from '@ant-design/icons';
6 6
 import { Button, Popconfirm, Image, Space, notification } from 'antd';
7 7
 import { sortableContainer, sortableElement, sortableHandle } from 'react-sortable-hoc';
8 8
 import request, { queryTable } from '@/utils/request';
9
-import arrayMove from 'array-move';
9
+// import arrayMove from 'array-move';
10 10
 
11 11
 const DragHandle = sortableHandle(() => <MenuOutlined style={{ cursor: 'grab', color: '#999' }} />);
12 12
 
@@ -135,10 +135,10 @@ const BannerList = () => {
135 135
     // const { dataSource } = this.state;
136 136
     console.log('Sorted items: ', dataSource, oldIndex, newIndex);
137 137
     if (oldIndex !== newIndex) {
138
-      const newData = arrayMove([].concat(dataSource), oldIndex, newIndex).filter((el) => !!el);
139
-      console.log('Sorted items: ', newData);
140
-      //   this.setState({ dataSource: newData });
141
-      setDataSource(newData);
138
+      // const newData = arrayMove([].concat(dataSource), oldIndex, newIndex).filter((el) => !!el);
139
+      // console.log('Sorted items: ', newData);
140
+      // //   this.setState({ dataSource: newData });
141
+      // setDataSource(newData);
142 142
     }
143 143
   };
144 144
 

+ 36
- 42
src/pages/Cms/Hot/List/index.jsx Näytä tiedosto

@@ -1,43 +1,44 @@
1
-import React, { useRef, useCallback, useState, useMemo } from 'react';
1
+import React, { useRef, useCallback, useMemo, useState } from 'react';
2 2
 import { connect, history } from 'umi';
3 3
 import { PageContainer } from '@ant-design/pro-layout';
4 4
 import ProTable from '@ant-design/pro-table';
5 5
 import { PlusOutlined, MenuOutlined } from '@ant-design/icons';
6 6
 import { Button, Popconfirm, Image, Space, notification } from 'antd';
7 7
 import request, { queryTable } from '@/utils/request';
8
-import DnDProvider from '@/components/DndTr/Provider';
9
-import DndTr from '@/components/DndTr';
8
+import { DraggableContainer, withDraggableRow, DragHandle } from '@/components/DragTable'
10 9
 
11 10
 const typeList = { post: '科普' };
12 11
 
13 12
 const HotList = () => {
14
-  const [forceUpdate, setForceUpdate] = useState(1)
13
+  const list = useRef([])
15 14
   const actRef = useRef()
16 15
 
17
-  // eslint-disable-next-line react-hooks/exhaustive-deps
18
-  const RowWrapper = useMemo(() => DndTr, [forceUpdate])
16
+  const handleDragEnd = useCallback(
17
+    ({oldIndex, newIndex}) => {
18
+      if (oldIndex === newIndex) {
19
+        return
20
+      }
21
+
22
+      const from = list.current[oldIndex]?.serialNo
23
+      const to = list.current[newIndex]?.serialNo
24
+
25
+      console.log('----------->', from, to)
26
+  
27
+      request('/sort/topic', { method: 'PUT', data: { from, to } }).then(() => {
28
+        actRef.current.reload()
29
+      }).catch((e) => {
30
+        notification.error({ message: e.message })
31
+      })
32
+    },
33
+    [],
34
+  )
19 35
 
20 36
   const tableWrapper = useMemo(() => ({
21 37
     body: {
22
-      wrapper: DnDProvider,
23
-      row: RowWrapper,
38
+      wrapper: (props) => <DraggableContainer {...props} onSortEnd={handleDragEnd} />,
39
+      row: withDraggableRow(list),
24 40
     },
25
-  // eslint-disable-next-line react-hooks/exhaustive-deps
26
-  }), [forceUpdate])
27
-
28
-  const moveRow = ({ source, target }) => {
29
-    console.log('--------->', source.index, target.index)
30
-    if (source.index === target.index) {
31
-      return
32
-    }
33
-
34
-    request('/sort/topic', { method: 'PUT', data: { from: source.index, to: target.index, id: source.id } }).then(() => {
35
-      actRef.current.reload()
36
-      setForceUpdate(forceUpdate + 1)
37
-    }).catch((e) => {
38
-      notification.error({ message: e.message })
39
-    })
40
-  }
41
+  }), [handleDragEnd])
41 42
 
42 43
   const handleHotClick = useCallback((id) => {
43 44
     history.push(id ? `/cms/hot/edit?id=${id}` : '/cms/hot/edit');
@@ -50,34 +51,27 @@ const HotList = () => {
50 51
   ];
51 52
 
52 53
   const deleteHotClick = (id) => {
53
-    setLoading(true);
54
-
55 54
     request(`/topic/${id}`, { method: 'delete' })
56 55
       .then(() => {
57 56
         notification.success({ message: '删除成功' });
58 57
         // ref.current.submit();
59 58
       })
60 59
       .catch((e) => {
61
-        setLoading(false);
62 60
         notification.error({ message: e.message });
63 61
       });
64 62
   };
65 63
 
66 64
   const changeStatus = (row) => {
67
-    setLoading(true);
68
-
69 65
     request(`/topic/${row.serialNo}`, {
70 66
       method: 'put',
71 67
       data: { ...row, status: row.status === 1 ? 0 : 1 },
72 68
     })
73 69
       .then(() => {
74 70
         notification.info({ message: '修改成功' });
75
-        setLoading(false);
76 71
         // ref.current.submit();
77 72
       })
78 73
       .catch((e) => {
79 74
         notification.error({ message: e.message });
80
-        setLoading(false);
81 75
         return Promise.reject(e.message);
82 76
       });
83 77
   };
@@ -89,13 +83,13 @@ const HotList = () => {
89 83
       width: 60,
90 84
       hideInSearch: true,
91 85
       align: 'center',
92
-      render: () => (<MenuOutlined style={{ cursor: 'grab', color: '#999' }} />),
86
+      className: 'drag-visible',
87
+      render: () => <DragHandle />,
93 88
     },
94 89
     {
95 90
       title: '主图',
96 91
       dataIndex: 'poster',
97 92
       hideInSearch: true,
98
-
99 93
       align: 'center',
100 94
       render: (text) => <Image width={64} height={64} src={text} />,
101 95
     },
@@ -148,13 +142,14 @@ const HotList = () => {
148 142
     },
149 143
   ];
150 144
 
151
-  const handleRow = useCallback((record) => ({
152
-    index: record.sortNo,
153
-    bizId: record.serialNo,
154
-    moveRow,
155
-
156
-  // eslint-disable-next-line react-hooks/exhaustive-deps
157
-  }), [forceUpdate])
145
+  const requestWrapper = (...args) => {
146
+    return new Promise((resolve, reject) => {
147
+      queryTable('/topic')(...args).then((res) => {
148
+        resolve(res)
149
+        list.current = res.data
150
+      }).catch(reject)
151
+    })
152
+  }
158 153
 
159 154
   return (
160 155
     <PageContainer>
@@ -162,12 +157,11 @@ const HotList = () => {
162 157
         pagination={false}
163 158
         columns={columns}
164 159
         actionRef={actRef}
165
-        request={queryTable('/topic')}
160
+        request={requestWrapper}
166 161
         rowKey="serialNo"
167 162
         headerTitle="科普列表"
168 163
         search={{ labelWidth: '4em' }}
169 164
         components={tableWrapper}
170
-        onRow={handleRow}
171 165
         toolBarRender={() => actions}
172 166
       />
173 167
     </PageContainer>