index.tsx 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
  2. import styles from './index.module.scss'
  3. import { Button, Input, Tree, TreeDataNode } from 'antd'
  4. import { treeResIdFu } from './data'
  5. import { useDispatch, useSelector } from 'react-redux'
  6. import { RootState } from '@/store'
  7. import { A2_APIdel1, A2_APIdel2, A2_APIgetList1, A2_APIgetList2 } from '@/store/action/A2classify'
  8. import MyPopconfirm from '@/components/MyPopconfirm'
  9. import { MessageFu } from '@/utils/message'
  10. import A2add, { A2AddInfoType } from './A2add'
  11. import { A2tableType, A2TreeType } from '@/types'
  12. import MyTable from '@/components/MyTable'
  13. import { A2tableC } from '@/utils/tableData'
  14. import A2add2 from './A2add2'
  15. export type TopLeftArrType = '中图法分类' | '展示分类'
  16. const topLeftArr: TopLeftArrType[] = ['中图法分类', '展示分类']
  17. function A2classify() {
  18. const treeDataTemp = useSelector((state: RootState) => state.A2classify.treeData)
  19. const dispatch = useDispatch()
  20. const [topType, setTopType] = useState<TopLeftArrType>('中图法分类')
  21. const getList1 = useCallback(() => {
  22. dispatch(A2_APIgetList1())
  23. }, [dispatch])
  24. const getList2 = useCallback(
  25. async (val: string) => {
  26. dispatch(A2_APIgetList2({ pageNum: 1, pageSize: 9999, searchKey: val }))
  27. },
  28. [dispatch]
  29. )
  30. useEffect(() => {
  31. getList1()
  32. }, [getList1])
  33. // 点击重置
  34. const resetSelectFu = useCallback(
  35. (flag?: boolean) => {
  36. setValue('')
  37. if (topType === '展示分类') getList2('')
  38. if (flag) getList1()
  39. },
  40. [getList1, getList2, topType]
  41. )
  42. // 顶部切换tab
  43. const cutTop = useCallback(
  44. (item: TopLeftArrType) => {
  45. setValue('')
  46. setTopType(item)
  47. item === '中图法分类' ? getList1() : getList2('')
  48. },
  49. [getList1, getList2]
  50. )
  51. const [value, setValue] = useState('')
  52. const time = useRef(-1)
  53. const valueChange = useCallback(
  54. (val: string) => {
  55. setValue(val)
  56. clearInterval(time.current)
  57. time.current = window.setTimeout(() => {
  58. if (topType === '展示分类') getList2(val)
  59. // topType === '中图法分类' ? getList1(val) : getList2(val)
  60. }, 500)
  61. },
  62. [getList2, topType]
  63. )
  64. // 有关树------------------------
  65. const tab1Flag = useRef(true)
  66. useEffect(() => {
  67. if (treeDataTemp && treeDataTemp.length && tab1Flag.current) {
  68. tab1Flag.current = false
  69. setAcShu(treeDataTemp[0].id as number)
  70. }
  71. }, [treeDataTemp])
  72. // 当前选中的树节点ID
  73. const [acShu, setAcShu] = useState(0)
  74. // 点击树节点
  75. const onSelect = (id: any) => {
  76. if (id[0]) setAcShu(id[0])
  77. }
  78. // 搜索高亮
  79. const treeData = useMemo(() => {
  80. const loop = (dataTemp: any[]): TreeDataNode[] => {
  81. const data = dataTemp || []
  82. return data.map(item => {
  83. const strTitle = ((item.num ? item.num + ' ' : '') + item.name) as string
  84. const index = strTitle.indexOf(value)
  85. const beforeStr = strTitle.substring(0, index)
  86. const afterStr = strTitle.slice(index + value.length)
  87. const title =
  88. index > -1 ? (
  89. <span key={item.id}>
  90. {beforeStr}
  91. <span className='site-tree-search-value'>{value}</span>
  92. {afterStr}
  93. </span>
  94. ) : (
  95. <span key={item.id}>{strTitle}</span>
  96. )
  97. if (item.children) {
  98. return { title, key: item.id, children: loop(item.children) }
  99. }
  100. return {
  101. title,
  102. key: item.id
  103. }
  104. })
  105. }
  106. return loop(treeDataTemp)
  107. }, [treeDataTemp, value])
  108. // 右侧信息
  109. const rightData = useMemo(() => {
  110. let obj = {} as A2TreeType
  111. obj = treeResIdFu(treeDataTemp, acShu)
  112. return obj || {}
  113. }, [acShu, treeDataTemp])
  114. // 点击删除
  115. const delTree = useCallback(
  116. async (id: number) => {
  117. const res = await A2_APIdel1(id)
  118. if (res.code === 0) {
  119. MessageFu.success('删除成功!')
  120. tab1Flag.current = true
  121. getList1()
  122. }
  123. },
  124. [getList1]
  125. )
  126. // 点击新增和编辑
  127. const [addInfo, setAddInfo] = useState({} as A2AddInfoType)
  128. const addSonFu = useCallback(
  129. (id: number) => {
  130. setAddInfo({
  131. id,
  132. txt: id > 0 ? '编辑' : '新增',
  133. acInfo: rightData
  134. })
  135. },
  136. [rightData]
  137. )
  138. // -----------------展示分类
  139. const tableInfo = useSelector((state: RootState) => state.A2classify.tableInfo)
  140. const delTableFu = useCallback(
  141. async (id: number) => {
  142. const res = await A2_APIdel2(id)
  143. if (res.code === 0) {
  144. MessageFu.success('删除成功!')
  145. getList2(value)
  146. }
  147. },
  148. [getList2, value]
  149. )
  150. const tableLastBtn = useMemo(() => {
  151. return [
  152. {
  153. title: '操作',
  154. render: (item: A2tableType) => (
  155. <>
  156. <Button size='small' type='text' onClick={() => setTab2Id(item.id)}>
  157. 编辑
  158. </Button>
  159. <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
  160. </>
  161. )
  162. }
  163. ]
  164. }, [delTableFu])
  165. // tab新增/编辑
  166. const [tab2Id, setTab2Id] = useState(0)
  167. return (
  168. <div className={styles.A2classify}>
  169. <div className='pageTitle'>图书分类</div>
  170. {/* 顶部 */}
  171. <div className='A2top'>
  172. <div className='A2top1'>
  173. {topLeftArr.map(item => (
  174. <Button
  175. onClick={() => cutTop(item)}
  176. key={item}
  177. type={topType === item ? 'primary' : 'default'}
  178. >
  179. {item}
  180. </Button>
  181. ))}
  182. </div>
  183. <div className='A2top1'>
  184. <Input
  185. style={{ width: 240 }}
  186. placeholder={topType === '中图法分类' ? '请输入分类名称/编号' : '请输入标题'}
  187. value={value}
  188. onChange={e => valueChange(e.target.value)}
  189. />
  190. &emsp;
  191. <Button onClick={() => resetSelectFu()}>重置</Button>&emsp;
  192. <Button
  193. type='primary'
  194. onClick={() =>
  195. topType === '展示分类'
  196. ? setTab2Id(-1)
  197. : setAddInfo({ id: -1, txt: '新增', acInfo: rightData })
  198. }
  199. >
  200. 新增
  201. </Button>
  202. </div>
  203. </div>
  204. {/* 主体 */}
  205. <div className='A2main'>
  206. <div className='A2m1' hidden={topType !== '中图法分类'}>
  207. <div className='A2m1ll'>
  208. {treeDataTemp && treeDataTemp.length ? (
  209. <Tree
  210. // 默认全部展开
  211. defaultExpandAll={true}
  212. // 数据
  213. treeData={treeData}
  214. // 自定义字段
  215. // fieldNames={{ title: 'title', key: 'key', children: 'children' }}
  216. // 选中
  217. selectedKeys={[acShu]}
  218. // 点击
  219. onSelect={onSelect}
  220. />
  221. ) : (
  222. <div className='A2Null'>暂无数据</div>
  223. )}
  224. </div>
  225. <div className='A2m1rr'>
  226. <div className='A2mr1'>分类详情</div>
  227. {rightData.id ? (
  228. <>
  229. <div className='A2mr2'>
  230. <Button type='text' onClick={() => addSonFu(rightData.id)}>
  231. 编辑
  232. </Button>
  233. &emsp;
  234. <MyPopconfirm txtK='删除' onConfirm={() => delTree(rightData.id)} />
  235. </div>
  236. <div className='A2mr3'>
  237. <div className='A2mr3ll'>分类编号:</div>
  238. <div className='A2mr3rr'>{rightData.num}</div>
  239. </div>
  240. <div className='A2mr3'>
  241. <div className='A2mr3ll'>分类名称:</div>
  242. <div className='A2mr3rr'>{rightData.name}</div>
  243. </div>
  244. <div className='A2mr3'>
  245. <div className='A2mr3ll'>层级:</div>
  246. <div className='A2mr3rr'>{rightData.level}</div>
  247. </div>
  248. <div className='A2mr3'>
  249. <div className='A2mr3ll'>排序值:</div>
  250. <div className='A2mr3rr'>{rightData.sort}</div>
  251. </div>
  252. <div className='A2mr3'>
  253. <div className='A2mr3ll'>编辑时间:</div>
  254. <div className='A2mr3rr'>{rightData.updateTime}</div>
  255. </div>
  256. <div className='A2mr3'>
  257. <div className='A2mr3ll'>编辑人:</div>
  258. <div className='A2mr3rr'>{rightData.creatorName}</div>
  259. </div>
  260. </>
  261. ) : (
  262. <div className='A2Null'>暂无数据</div>
  263. )}
  264. </div>
  265. </div>
  266. <div className='A2m2' hidden={topType !== '展示分类'}>
  267. <MyTable
  268. yHeight={678}
  269. list={tableInfo.list}
  270. columnsTemp={A2tableC}
  271. lastBtn={tableLastBtn}
  272. pagingInfo={false}
  273. />
  274. </div>
  275. </div>
  276. {/* 新增/编辑页面 中图法分类 */}
  277. {addInfo.id ? (
  278. <A2add
  279. addInfo={addInfo}
  280. addFu={() => resetSelectFu(true)}
  281. closeFu={() => setAddInfo({} as A2AddInfoType)}
  282. />
  283. ) : null}
  284. {/* 新增/编辑 展示分类 */}
  285. {tab2Id ? (
  286. <A2add2
  287. tab2Id={tab2Id}
  288. addFu={flag => (flag ? getList2(value) : resetSelectFu())}
  289. closeFu={() => setTab2Id(0)}
  290. />
  291. ) : null}
  292. </div>
  293. )
  294. }
  295. const MemoA2classify = React.memo(A2classify)
  296. export default MemoA2classify