import React , { useEffect , useState } from 'react' ; import { Table , Input , Button , Popconfirm , Tag , Select } from 'antd' ; import { AutoSizer } from 'react-virtualized/dist/es/AutoSizer' ; import { PaginationConfig , SorterResult } from 'antd/lib/table' ; import { withRouter , RouteComponentProps } from 'react-router-dom' ; import styles from './index.scss' ; import { ArticleItem } from '@views/ArticleList/ArticleItem' ; import { deleteArticleById , getArticleList } from '@services/api' ; import UpdateArticle from './UpdateArticle' ; import { getTagColor } from '@utils/index' ; import { useTagStore } from '@store/index' ; import { useGetListData } from '@utils/hooks' ; const { Column } = Table ; const { Option } = Select ; const pageSize = 10 ; type sortTypeType = 'ASC' | 'DESC' | null ; const ArticleManager = ( { history } ) => { const [ keyword , setKeyword ] = useState < string > ( '' ) ; const [ currentKeyword , setCurrentKeyword ] = useState < string > ( '' ) ; const [ tagValue , setTagValue ] = useState < string > ( undefined ) ; const [ currentTagValue , setCurrentTagValue ] = useState < string > ( undefined ) ; const [ sortName , setSortName ] = useState < string > ( null ) ; const [ sortType , setSortType ] = useState < sortTypeType > ( null ) ; const [ isShowEdit , setIsShowEdit ] = useState < boolean > ( false ) ; const [ editTarget , setEditTarget ] = useState < ArticleItem > ( null ) ; const [ params , setParams ] = useState < FetchParams . GetArticleList > ( null ) ; const [ cancelRequire , setCancelRequire ] = useState < boolean > ( true ) ; const { list , loading , total , page } = useGetListData < ArticleItem , FetchParams . GetArticleList > ( getArticleList , params , cancelRequire ) ; const { state : { tagList } } = useTagStore ( ) ; const getList = async ( ) => { const params = { pageSize , keyword : currentKeyword , sortName , sortType , tag : currentTagValue } ; setCancelRequire ( false ) ; setParams ( params ) ; } ; const changePageAndSorter = ( pageStatus , sorterStatus ) => { const { current } = pageStatus ; if ( current !== page ) { setParams ( { ... params , page : current } ) ; } const { columnKey , order } = sorterStatus ; if ( ! ! Object . keys ( sorterStatus ) . length ) { setSortName ( columnKey ) ; setSortType ( order === 'ascend' ? 'ASC' : 'DESC' ) ; } else { setSortName ( null ) ; setSortType ( null ) ; } } ; const triggerShowEditArticle = ( isShow , targetArticle ? ) => { setIsShowEdit ( isShow ) ; setEditTarget ( isShow ? targetArticle : null ) ; } ; const checkArticle = ( id ) => { history . push ( `/article-detail/${ id }` ) ; } ; const deleteArticle = async ( id ) => { try { await deleteArticleById ( { id } ) ; getList ( ) ; } catch ( error ) { } } ; const onSearch = ( ) => { setParams ( { ... params , page : 1 } ) ; setCurrentKeyword ( keyword ) ; setCurrentTagValue ( tagValue ) ; } ; const selectTag = ( tagId ) => { const targetValue = ! ! tagId ? tagList . find ( item => item . id === Number ( tagId ) ) . value : undefined ; setTagValue ( targetValue ) ; } ; const gotoTagWithArticle = ( value ) => { history . push ( `/tag/${ value }` ) ; } ; const renderTags = ( article ) => { const tempTagList = getTagColor ( tagList , article . tags ) ; return ( < > { tempTagList . map ( item => { return ( < Tag className = { styles . tag } onClick = { ( ) => gotoTagWithArticle ( item . value ) } color = { item . color } key = { item . id } > { item . value } < /Tag>); } ) } < />); } ; const renderOperation = ( record ) => { return ( < div className = { styles . operation } > < span onClick = { ( ) => checkArticle ( record . id ) } className = { styles . operationItem } > 查看 < /span> < span onClick = { ( ) => triggerShowEditArticle ( true , record ) } className = { styles . operationItem } > 编辑 < /span> < Popconfirm title = "确定删除该文章吗?" okText = "确定" cancelText = "取消" onConfirm = { ( ) => deleteArticle ( record . id ) } > < span className = { styles . operationItem } > 删除 < /span> < /Popconfirm> < /div>); } ; useEffect ( ( ) => { getList ( ) ; } , [ currentKeyword , sortName , sortType , currentTagValue ] ) ; const pagination = { total , current : page , pageSize } ; return ( < div className = { styles . articleManager } > { isShowEdit ? ( < UpdateArticle getArticleList = { getList } triggerShowEditArticle = { triggerShowEditArticle } editTarget = { editTarget } / > ) : ( < > < div className = { styles . filter } > < div className = { styles . searchItem } > < div className = { styles . label } > 标题 : < /div> < Input onPressEnter = { onSearch } value = { keyword } onChange = { e => setKeyword ( e . target . value ) } placeholder = "请输入标题" / > < /div> < div className = { styles . searchItem } > < div className = { styles . label } > 标签 : < /div> < Select placeholder = "请选择标签" allowClear value = { tagValue } onChange = { selectTag } className = { styles . selectTag } > { tagList . map ( item => ( < Option key = { item . id } > { item . value } < /Option>))} < /Select> < /div> < Button onClick = { onSearch } type = "primary" > 搜索 < /Button> < /div> < AutoSizer disableWidth className = { styles . dataList } > { ( { height } ) => { return ( < Table onChange = { ( p , f , s ) => changePageAndSorter ( p , s ) } rowKey = "id" pagination = { pagination } dataSource = { list } loading = { loading } scroll = { { y : height - 220 , x : 1340 } } bordered > < Column < ArticleItem > width = { 200 } key = "title" dataIndex = "title" title = "标题" / > < Column < ArticleItem > width = { 500 } key = "tags" title = "标签" render = { ( article ) => renderTags ( article ) } /> < Column < ArticleItem > width = { 120 } key = "viewCount" sorter title = "浏览数" dataIndex = "viewCount" / > < Column < ArticleItem > sorter width = { 200 } key = "createdAt" dataIndex = "createdAt" title = "创建时间" / > < Column < ArticleItem > sorter width = { 200 } key = "updatedAt" dataIndex = "updatedAt" title = "修改时间" / > < Column < ArticleItem > key = "operation" title = "操作" width = { 120 } render = { ( record ) => renderOperation ( record ) } /> < /Table>); } } < /AutoSizer> < />)} < /div>); } ; export default withRouter ( ArticleManager ) ;