index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. import * as React from 'react';
  2. import { observer } from 'mobx-react';
  3. import { List, Button, Card, Space, Typography, Divider, Flex, Layout, Empty, Image, Modal } from 'antd';
  4. import { PlusOutlined, FileOutlined, SettingOutlined, DeleteOutlined } from '@ant-design/icons';
  5. import { apis } from '@/apis';
  6. import './style.less';
  7. import IconSvg from '@/assets/public/icon.svg';
  8. import { PaginationConfig } from 'antd/es/pagination';
  9. import router from '@/router';
  10. const { Header, Footer, Sider, Content } = Layout;
  11. const headerStyle : React.CSSProperties = {
  12. textAlign: 'center',
  13. height: 24,
  14. paddingInline: 48,
  15. lineHeight: '30px',
  16. backgroundColor: '#fff',
  17. };
  18. const contentStyle : React.CSSProperties = {
  19. textAlign: 'center',
  20. lineHeight: '40px',
  21. backgroundColor: '#fff',
  22. };
  23. const siderStyle : React.CSSProperties = {
  24. paddingLeft: 30,
  25. paddingTop: 30,
  26. height: 80,
  27. backgroundColor: '#fff',
  28. };
  29. const footerStyle : React.CSSProperties = {
  30. textAlign: 'center',
  31. color: '#fff',
  32. height: 24,
  33. backgroundColor: '#4096ff',
  34. };
  35. const layoutStyle = {
  36. borderRadius: 8,
  37. overflow: 'hidden',
  38. width: 'calc(10% - 8px)',
  39. maxWidth: 'calc(20% - 8px)',
  40. };
  41. const QuestionAnswerList : React.FC = () => {
  42. interface Item {
  43. name : string,
  44. desc : string,
  45. appId : number,
  46. createBy : string,
  47. };
  48. interface PageInfo {
  49. pageNumber : number,
  50. pageSize : number,
  51. total : number,
  52. };
  53. const [ listLoading, setListLoading ] = React.useState( false );
  54. const [ list, setList ] = React.useState<Item[]>( [] );
  55. const [ page, setPage ] = React.useState<PageInfo>( {
  56. pageNumber: 1,
  57. pageSize: 10,
  58. total: 0,
  59. } );
  60. const [ appCount, setAppCount ] = React.useState<string>();
  61. const [ knowCount, setKnowCount ] = React.useState<string>();
  62. const { Header, Footer, Sider, Content } = Layout;
  63. const appApi = {
  64. fetchList: async () => {
  65. setListLoading( true );
  66. try {
  67. const res = await apis.fetchAppList( {
  68. pageSize: page.pageSize,
  69. pageNumber: page.pageNumber
  70. } )
  71. setList( res.data.list );
  72. setPage( {
  73. pageNumber: page.pageNumber,
  74. pageSize: page.pageSize,
  75. total: res.data.total,
  76. } );
  77. console.log( page, 'res.data.total' );
  78. } catch ( error ) {
  79. console.error( error );
  80. } finally {
  81. setListLoading( false );
  82. }
  83. }
  84. };
  85. // 删除应用
  86. const delApplication = async ( appId : string ) => {
  87. try {
  88. await apis.deleteApplicationApi( appId );
  89. await appApi.fetchList();
  90. } catch ( error ) {
  91. console.error( error );
  92. }
  93. }
  94. const indexApi = {
  95. fetchIndex: async () => {
  96. try {
  97. const res = await apis.fetchIndexCount( {
  98. pageSize: page.pageSize,
  99. pageNumber: page.pageNumber
  100. } )
  101. setAppCount( res.data.applicationCount );
  102. setKnowCount( res.data.knowledgeCount );
  103. // setPage({
  104. // pageNumber: page.pageNumber,
  105. // pageSize: page.pageSize,
  106. // total: res.data.total,
  107. // });
  108. } catch ( error ) {
  109. console.error( error );
  110. } finally {
  111. setListLoading( false );
  112. }
  113. }
  114. }
  115. const init = async () => {
  116. await appApi.fetchList();
  117. await indexApi.fetchIndex();
  118. }
  119. React.useEffect( () => {
  120. init();
  121. }, [ page.pageSize, page.pageNumber ] )
  122. const paginationConfig : PaginationConfig = {
  123. // 显示数据总量
  124. showTotal: ( total : number ) => {
  125. return `共 ${ total } 条`;
  126. },
  127. // 展示分页条数切换
  128. showSizeChanger: true,
  129. // 指定每页显示条数
  130. // pageSizeOptions: ['2', '20', '50', '100'],
  131. // 快速跳转至某页
  132. showQuickJumper: true,
  133. current: page.pageNumber,
  134. pageSize: page.pageSize,
  135. total: page.total,
  136. onChange: ( pageNumber, pageSize ) => {
  137. setPage( {
  138. pageNumber: pageNumber,
  139. pageSize: pageSize,
  140. total: page.total,
  141. } );
  142. },
  143. };
  144. return (
  145. <div>
  146. {
  147. list.length
  148. ?
  149. <div className='questionAnswerList'>
  150. {/*<div style={ { overflow: 'auto' } }>*/}
  151. {/* <Flex gap="middle" wrap>*/}
  152. {/* <Layout style={ layoutStyle }>*/}
  153. {/* <Sider width="25%" style={ siderStyle }>*/}
  154. {/* <FileOutlined />*/}
  155. {/* </Sider>*/}
  156. {/* <Layout>*/}
  157. {/* <Header style={ headerStyle }>问答应用总数</Header>*/}
  158. {/* <Content style={ contentStyle }>{ appCount }个</Content>*/}
  159. {/* </Layout>*/}
  160. {/* </Layout>*/}
  161. {/* <Layout style={ layoutStyle }>*/}
  162. {/* <Sider width="25%" style={ siderStyle }>*/}
  163. {/* <FileOutlined />*/}
  164. {/* </Sider>*/}
  165. {/* <Layout>*/}
  166. {/* <Header style={ headerStyle }>知识库总数</Header>*/}
  167. {/* <Content style={ contentStyle }>{ knowCount } 个</Content>*/}
  168. {/* </Layout>*/}
  169. {/* </Layout>*/}
  170. {/* </Flex>*/}
  171. {/*</div>*/}
  172. <div style={ { display: 'flex', justifyContent: 'space-between', padding: '16px 20px' } }>
  173. <div>所有问答应用</div>
  174. <Button type='primary'
  175. icon={ <PlusOutlined /> }
  176. onClick={ () => {
  177. router.navigate( { pathname: '/zhipu/questionAnswer/create' } );
  178. } }>创建问答应用</Button>
  179. </div>
  180. <div className='applicationList'>
  181. <List grid={ {
  182. gutter: 16,
  183. xs: 1,
  184. sm: 1,
  185. md: 2,
  186. lg: 2,
  187. xl: 3,
  188. xxl: 4, // 展示的列数
  189. } }
  190. dataSource={ list }
  191. renderItem={ ( item ) => (
  192. <List.Item>
  193. <div className='card'>
  194. <div style={ {
  195. display: 'flex',
  196. justifyContent: 'space-between',
  197. alignItems: 'center',
  198. overflow: 'auto'
  199. } }>
  200. <div style={ { display: 'flex', alignItems: 'center', overflow: 'auto' } }>
  201. <div style={ { marginRight: 10, overflow: 'auto' } }>
  202. <Image
  203. width={ 32 }
  204. height={ 32 }
  205. src={ IconSvg }
  206. />
  207. </div>
  208. {/*<div style={ { overflow: 'auto' } }>*/ }
  209. {/* { item.name }*/ }
  210. {/*</div>*/ }
  211. <div style={ {
  212. display: 'flex',
  213. flexDirection: 'column',
  214. justifyContent: 'center',
  215. height: '100%'
  216. } }>
  217. <div style={ {
  218. lineHeight: '18px',
  219. fontSize: 14,
  220. fontWeight: 500,
  221. overflow: 'auto'
  222. } }>{ item.name }</div>
  223. <Space size={ 4 } style={ { lineHeight: '18px' } }>
  224. <span style={ {
  225. color: '#999',
  226. fontSize: 12,
  227. margin: 0
  228. } }>ID:{ item.appId }</span>
  229. <Divider type="vertical" style={ { color: '999', margin: 0, height: 12 } } />
  230. {/*<span style={ { color: '#999', fontSize: 12 } }>创建者 { item.createBy }</span>*/ }
  231. </Space>
  232. </div>
  233. </div>
  234. </div>
  235. <Divider plain style={ { margin: '16px 0' } }></Divider>
  236. <div className='desc'>
  237. {
  238. item.desc !== '' && item.desc.length > 40 ? item.desc.substring( 0, 40 ) + '...' : item.desc
  239. }
  240. </div>
  241. <div style={ {
  242. display: 'flex',
  243. justifyContent: 'space-between',
  244. // justifyContent: 'flex-end',
  245. alignItems: 'flex-end',
  246. height: '100%',
  247. overflow: 'auto',
  248. paddingTop: 16,} }>
  249. <span style={ { color: '#999', fontSize: 12 } }>创建时间: {item.createTime}</span>
  250. <Space size={ 16 } align="center">
  251. <a onClick={ () => {
  252. router.navigate( { pathname: '/zhipu/questionAnswer/modify' }, { state: { id: item.appId } } );
  253. } }>
  254. <SettingOutlined /> 编辑
  255. </a>
  256. <a className='text-error' onClick={ () => {
  257. Modal.confirm( {
  258. title: '删除',
  259. content: `确定删除应用名称: ` + item.name + ` 吗?`,
  260. okType: 'danger',
  261. onOk: async () => {
  262. await delApplication( item.appId.toString() );
  263. }
  264. } );
  265. } }>
  266. <DeleteOutlined /> 删除
  267. </a>
  268. </Space>
  269. </div>
  270. </div>
  271. </List.Item>
  272. ) }
  273. pagination={ paginationConfig } // 分页
  274. />
  275. </div>
  276. </div>
  277. :
  278. <Empty image={ Empty.PRESENTED_IMAGE_SIMPLE } />
  279. }
  280. </div>
  281. )
  282. };
  283. export default observer( QuestionAnswerList );