|
|
@@ -0,0 +1,349 @@
|
|
|
+import React, { useCallback, useEffect, useRef, useState } from 'react'
|
|
|
+import styles from './index.module.scss'
|
|
|
+import { Button, Cascader, Checkbox, Input, Modal, Select, Table } from 'antd'
|
|
|
+import { A3topArr } from '@/pages/A3goods/data'
|
|
|
+import { ArrowLeftOutlined, ArrowRightOutlined } from '@ant-design/icons'
|
|
|
+import ImageLazy from '@/components/ImageLazy'
|
|
|
+import { MessageFu } from '@/utils/message'
|
|
|
+
|
|
|
+type Props = {
|
|
|
+ leftApi: any
|
|
|
+ rightApi: any
|
|
|
+ closeFu: (flag: boolean) => void
|
|
|
+ rightCan?: any
|
|
|
+}
|
|
|
+
|
|
|
+function MoveTable({ leftApi, rightApi, closeFu, rightCan }: Props) {
|
|
|
+ const [formData, setFormData] = useState<any>({ pageNum: 1, pageSize: 99999 })
|
|
|
+ const formDataRef = useRef({ pageNum: 1, pageSize: 99999 })
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ formDataRef.current = formData
|
|
|
+ }, [formData])
|
|
|
+
|
|
|
+ // 点击搜索的 时间戳
|
|
|
+ const [timeKey, setTimeKey] = useState(0)
|
|
|
+
|
|
|
+ // 点击搜索
|
|
|
+ const clickSearch = useCallback(() => {
|
|
|
+ setFormData({ ...formData, pageNum: 1 })
|
|
|
+ setTimeout(() => {
|
|
|
+ setTimeKey(Date.now())
|
|
|
+ }, 50)
|
|
|
+ }, [formData])
|
|
|
+
|
|
|
+ const timeRef = useRef(0)
|
|
|
+
|
|
|
+ const [leftAll, setLeftAll] = useState<any[]>([])
|
|
|
+ const [leftAc, setLeftAc] = useState<any[]>([])
|
|
|
+ const [rightAll, setRightAll] = useState<any[]>([])
|
|
|
+ const [rightAc, setRightAc] = useState<any[]>([])
|
|
|
+
|
|
|
+ const [checkLeft, setCheckLeft] = useState<number[]>([])
|
|
|
+ const [checkRight, setCheckRight] = useState<number[]>([])
|
|
|
+
|
|
|
+ const checkLeftFu = useCallback(
|
|
|
+ (id: number) => {
|
|
|
+ if (checkLeft.includes(id)) setCheckLeft(checkLeft.filter(v => v !== id))
|
|
|
+ else setCheckLeft([...checkLeft, id])
|
|
|
+ },
|
|
|
+ [checkLeft]
|
|
|
+ )
|
|
|
+
|
|
|
+ const checkRightFu = useCallback(
|
|
|
+ (id: number) => {
|
|
|
+ if (checkRight.includes(id)) setCheckRight(checkRight.filter(v => v !== id))
|
|
|
+ else setCheckRight([...checkRight, id])
|
|
|
+ },
|
|
|
+ [checkRight]
|
|
|
+ )
|
|
|
+
|
|
|
+ // 封装发送请求的函数
|
|
|
+ const getListFu = useCallback(async () => {
|
|
|
+ const obj1: any = { ...formDataRef.current }
|
|
|
+ const obj2: any = { ...formDataRef.current }
|
|
|
+
|
|
|
+ if (rightCan) {
|
|
|
+ for (const k in rightCan) {
|
|
|
+ obj1[k] = rightCan[k]
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const res1 = await rightApi(obj1, true)
|
|
|
+ if (res1.code === 0) {
|
|
|
+ const list1 = res1.data.records || []
|
|
|
+
|
|
|
+ if (timeRef.current === 0) setRightAll(list1)
|
|
|
+
|
|
|
+ setRightAc(list1)
|
|
|
+
|
|
|
+ const res2 = await leftApi(obj2, true)
|
|
|
+
|
|
|
+ if (res2.code === 0) {
|
|
|
+ const rightIds: number[] = list1.map((v: any) => v.id)
|
|
|
+
|
|
|
+ let list2: any[] = res2.data.records || []
|
|
|
+
|
|
|
+ list2 = list2.filter(v => !rightIds.includes(v.id))
|
|
|
+
|
|
|
+ if (timeRef.current === 0) setLeftAll(list2)
|
|
|
+ setLeftAc(list2)
|
|
|
+
|
|
|
+ timeRef.current++
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [leftApi, rightApi, rightCan])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ getListFu()
|
|
|
+ setCheckLeft([])
|
|
|
+ setCheckRight([])
|
|
|
+ }, [getListFu, timeKey])
|
|
|
+
|
|
|
+ // 输入框和下拉框的改变
|
|
|
+ const fromFu = useCallback(
|
|
|
+ (key: string, val: string) => {
|
|
|
+ setFormData({ ...formData, [key]: val })
|
|
|
+ },
|
|
|
+ [formData]
|
|
|
+ )
|
|
|
+
|
|
|
+ // 点击重置
|
|
|
+ const clickReset = useCallback(() => {
|
|
|
+ setFormData({ pageNum: 1, pageSize: 99999 })
|
|
|
+ setTimeout(() => {
|
|
|
+ setTimeKey(Date.now())
|
|
|
+ }, 50)
|
|
|
+ }, [])
|
|
|
+
|
|
|
+ // 级联变化
|
|
|
+ const dataChangeFu = useCallback(
|
|
|
+ (val: any, item: any) => {
|
|
|
+ // 省市区选择
|
|
|
+ if (item.type === 'Cascader2') {
|
|
|
+ const txt = val ? val[val.length - 1] : ''
|
|
|
+
|
|
|
+ setFormData({ ...formData, [item.key]: txt, [item.key2]: val })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [formData]
|
|
|
+ )
|
|
|
+
|
|
|
+ // 全选和反选
|
|
|
+ const checkAll = useCallback(
|
|
|
+ (type: 'left' | 'right') => {
|
|
|
+ if (type === 'left') {
|
|
|
+ if (checkLeft.length !== leftAc.length) setCheckLeft(leftAc.map(v => v.id))
|
|
|
+ else setCheckLeft([])
|
|
|
+ } else {
|
|
|
+ if (checkRight.length !== rightAc.length) setCheckRight(rightAc.map(v => v.id))
|
|
|
+ else setCheckRight([])
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [checkLeft.length, checkRight.length, leftAc, rightAc]
|
|
|
+ )
|
|
|
+
|
|
|
+ // 右边的向左边移
|
|
|
+ const rightToLeft = useCallback(() => {
|
|
|
+ const rightAllIds = rightAll.filter(v => !checkRight.includes(v.id)).map(v => v.id)
|
|
|
+ console.log('右→左', rightAllIds)
|
|
|
+ setCheckRight([])
|
|
|
+ changeFlag.current = true
|
|
|
+ MessageFu.success('操作成功')
|
|
|
+ }, [checkRight, rightAll])
|
|
|
+
|
|
|
+ // 左边的向右边移
|
|
|
+ const leftToRight = useCallback(() => {
|
|
|
+ console.log('左→右', checkLeft)
|
|
|
+ setCheckLeft([])
|
|
|
+ changeFlag.current = true
|
|
|
+ MessageFu.success('操作成功')
|
|
|
+ }, [checkLeft])
|
|
|
+
|
|
|
+ const columns = useCallback(
|
|
|
+ (type: 'left' | 'right') => {
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ width: 100,
|
|
|
+ title: (
|
|
|
+ <>
|
|
|
+ <Checkbox
|
|
|
+ onClick={() => checkAll(type)}
|
|
|
+ indeterminate={
|
|
|
+ type === 'left'
|
|
|
+ ? !!checkLeft.length && checkLeft.length !== leftAc.length
|
|
|
+ : !!checkRight.length && checkRight.length !== rightAc.length
|
|
|
+ }
|
|
|
+ checked={
|
|
|
+ type === 'left'
|
|
|
+ ? !!checkLeft.length && checkLeft.length === leftAc.length
|
|
|
+ : !!checkRight.length && checkRight.length === rightAc.length
|
|
|
+ }
|
|
|
+ >
|
|
|
+ 选择
|
|
|
+ </Checkbox>
|
|
|
+ </>
|
|
|
+ ),
|
|
|
+ render: (item: any) => (
|
|
|
+ <div
|
|
|
+ className='MTcheck'
|
|
|
+ onClick={() => {
|
|
|
+ type === 'left' ? checkLeftFu(item.id) : checkRightFu(item.id)
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Checkbox
|
|
|
+ checked={
|
|
|
+ type === 'left' ? checkLeft.includes(item.id) : checkRight.includes(item.id)
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ },
|
|
|
+ {
|
|
|
+ width: 100,
|
|
|
+ title: '封面',
|
|
|
+ render: (item: any) => (
|
|
|
+ <div className='tableImgAuto'>
|
|
|
+ <ImageLazy
|
|
|
+ width={60}
|
|
|
+ height={60}
|
|
|
+ srcBig={item.thumbPc || item.thumb}
|
|
|
+ src={item.thumb || item.thumbPc}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '名称',
|
|
|
+ render: (item: any) => item.name || '(空)'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '总登记号',
|
|
|
+ render: (item: any) => item.num || '(空)'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ [checkAll, checkLeft, checkLeftFu, checkRight, checkRightFu, leftAc.length, rightAc.length]
|
|
|
+ )
|
|
|
+
|
|
|
+ // 数据是否改变了,关闭的时候需要重置外层列表
|
|
|
+ const changeFlag = useRef(false)
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Modal
|
|
|
+ getContainer={() => document.getElementById('root') as HTMLElement}
|
|
|
+ wrapClassName={styles.MoveTable}
|
|
|
+ destroyOnClose
|
|
|
+ open={true}
|
|
|
+ title='设置展示藏品'
|
|
|
+ footer={
|
|
|
+ [] // 设置footer为空,去掉 取消 确定默认按钮
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div className='MTtop'>
|
|
|
+ <div className='MTtop1'>
|
|
|
+ {A3topArr.map(item => (
|
|
|
+ <div key={item.key} className='MTtopRow'>
|
|
|
+ {item.type === 'Select' ? (
|
|
|
+ <Select
|
|
|
+ placeholder={item.placeholder}
|
|
|
+ options={item.options}
|
|
|
+ allowClear
|
|
|
+ value={formData[item.key] || null}
|
|
|
+ onChange={e => fromFu(item.key, e)}
|
|
|
+ />
|
|
|
+ ) : item.type === 'Input' ? (
|
|
|
+ <Input
|
|
|
+ placeholder={item.placeholder}
|
|
|
+ allowClear
|
|
|
+ value={formData[item.key] || ''}
|
|
|
+ onChange={e => fromFu(item.key, e.target.value.trim())}
|
|
|
+ />
|
|
|
+ ) : item.type === 'Cascader2' ? (
|
|
|
+ // 省市区选择
|
|
|
+ <Cascader
|
|
|
+ changeOnSelect
|
|
|
+ options={item.options}
|
|
|
+ placeholder={item.placeholder}
|
|
|
+ allowClear
|
|
|
+ value={formData[item.key2!] || []}
|
|
|
+ onChange={e => dataChangeFu(e, item)}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ <div className='MTtop2'>
|
|
|
+ <Button type='primary' onClick={clickSearch}>
|
|
|
+ 查询
|
|
|
+ </Button>
|
|
|
+ <Button onClick={clickReset}>重置</Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='MTmain'>
|
|
|
+ <div className='MTMll'>
|
|
|
+ <div className='MTMtiti'>
|
|
|
+ <h3>藏品清单</h3>
|
|
|
+ <span>
|
|
|
+ 共{leftAll.length}条藏品信息;当前选中{checkLeft.length}条
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Table
|
|
|
+ scroll={{ y: 550 }}
|
|
|
+ columns={columns('left')}
|
|
|
+ dataSource={leftAc}
|
|
|
+ rowKey='id'
|
|
|
+ size='middle'
|
|
|
+ pagination={false}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='MTMmove'>
|
|
|
+ <Button
|
|
|
+ onClick={rightToLeft}
|
|
|
+ disabled={checkRight.length === 0}
|
|
|
+ type='primary'
|
|
|
+ icon={<ArrowLeftOutlined />}
|
|
|
+ size='large'
|
|
|
+ />
|
|
|
+ <Button
|
|
|
+ onClick={leftToRight}
|
|
|
+ disabled={checkLeft.length === 0}
|
|
|
+ type='primary'
|
|
|
+ icon={<ArrowRightOutlined />}
|
|
|
+ size='large'
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='MTMrr'>
|
|
|
+ <div className='MTMtiti'>
|
|
|
+ <h3>展示藏品</h3>
|
|
|
+ <span>
|
|
|
+ 共{rightAll.length}条藏品信息;当前选中{checkRight.length}条
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Table
|
|
|
+ scroll={{ y: 550 }}
|
|
|
+ columns={columns('right')}
|
|
|
+ dataSource={rightAc}
|
|
|
+ rowKey='id'
|
|
|
+ size='middle'
|
|
|
+ pagination={false}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='MTbtn'>
|
|
|
+ <Button onClick={() => closeFu(changeFlag.current)}>关闭</Button>
|
|
|
+ {/* <MyPopconfirm txtK='取消' onConfirm={closeFu} /> */}
|
|
|
+ </div>
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const MemoMoveTable = React.memo(MoveTable)
|
|
|
+
|
|
|
+export default MemoMoveTable
|