index.tsx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import * as React from 'react';
  2. import { Pagination } from 'antd';
  3. import { AppCard, FilterDrawer, HeroBanner, StatsGrid } from '@/components/common';
  4. import { useAppStore, type FilterState } from './store';
  5. import './style.scss';
  6. // 导入全局 Mock 数据
  7. import { getAppsByPageType, getPageConfig, processAppData, mockCurrentUser } from '@/mock';
  8. import { message } from 'antd';
  9. import { useNavigate } from 'react-router-dom';
  10. const AppPlazaList: React.FC = () => {
  11. const {
  12. filterOpen,
  13. setFilterOpen,
  14. selectedSort,
  15. setSelectedSort,
  16. category1,
  17. category2,
  18. sort,
  19. setFilters,
  20. currentPage,
  21. pageSize,
  22. setCurrentPage,
  23. setPageSize,
  24. } = useAppStore();
  25. // 组合 filters 对象
  26. const filters: FilterState = { category1, category2, sort };
  27. // 获取页面配置
  28. const pageConfig = getPageConfig('appPlaza');
  29. // 获取应用数据(使用全局 Mock)
  30. const allApps = getAppsByPageType('appPlaza');
  31. const handleApplyFilter = (newFilters: FilterState) => {
  32. setFilters(newFilters);
  33. setSelectedSort(newFilters.sort);
  34. setCurrentPage(1);
  35. console.log('应用筛选:', newFilters);
  36. };
  37. const handleSortChange = (sortType: string) => {
  38. setSelectedSort(sortType);
  39. setFilters({ sort: sortType });
  40. };
  41. // 根据筛选和分页处理数据
  42. const getFilteredAndPaginatedApps = () => {
  43. let filtered = [...allApps];
  44. // 根据排序筛选
  45. if (filters.sort === '最新上线') {
  46. filtered.sort((a, b) => b.id.localeCompare(a.id));
  47. } else if (filters.sort === '高频率调用') {
  48. // 模拟按热度排序(使用 viewCount)
  49. filtered.sort((a, b) => (b.viewCount || 0) - (a.viewCount || 0));
  50. }
  51. // 分页
  52. const startIndex = (currentPage - 1) * pageSize;
  53. const endIndex = startIndex + pageSize;
  54. return filtered.slice(startIndex, endIndex);
  55. };
  56. const paginatedApps = getFilteredAndPaginatedApps();
  57. const navigate = useNavigate();
  58. const handlePlay = (appId: string) => {
  59. console.log('立即使用:', appId);
  60. };
  61. const handleApi = (appId: string) => {
  62. console.log('API 服务:', appId);
  63. message.info('API 文档功能开发中');
  64. };
  65. const handleEdit = (appId: string) => {
  66. console.log('编辑应用:', appId);
  67. navigate(`/appCenter/questionAnswer/modify?id=${appId}`);
  68. };
  69. const handleDelete = (appId: string) => {
  70. console.log('删除应用:', appId);
  71. message.info('删除功能开发中');
  72. };
  73. const handleShare = (appId: string) => {
  74. console.log('分享应用:', appId);
  75. message.info('分享功能开发中');
  76. };
  77. const handleFavorite = (appId: string) => {
  78. console.log('收藏应用:', appId);
  79. message.success('已收藏');
  80. };
  81. const handlePageChange = (page: number, size: number) => {
  82. setCurrentPage(page);
  83. setPageSize(size);
  84. };
  85. return (
  86. <div className='app-plaza-list'>
  87. {/* Hero Banner - 建科 GPT-5.0 专业版广告 */}
  88. <HeroBanner />
  89. {/* 数据统计概览 */}
  90. <StatsGrid />
  91. {/* 筛选工具栏 */}
  92. <div className='list-header'>
  93. <div className='list-header-title'>
  94. <h3>{pageConfig.title}</h3>
  95. <p>{pageConfig.description}</p>
  96. </div>
  97. <div className='list-header-actions'>
  98. <div className='sort-buttons'>
  99. <button
  100. className={`sort-btn ${selectedSort === '综合排序' ? 'active' : ''}`}
  101. onClick={() => handleSortChange('综合排序')}
  102. >
  103. 综合排序
  104. </button>
  105. <button
  106. className={`sort-btn ${selectedSort === '最新上线' ? 'active' : ''}`}
  107. onClick={() => handleSortChange('最新上线')}
  108. >
  109. 最新上线
  110. </button>
  111. <button
  112. className={`sort-btn ${selectedSort === '高频率调用' ? 'active' : ''}`}
  113. onClick={() => handleSortChange('高频率调用')}
  114. >
  115. 高频率调用
  116. </button>
  117. </div>
  118. <button className='filter-btn' onClick={() => setFilterOpen(true)}>
  119. <span className='iconify' data-icon='solar:filter-linear'></span>
  120. </button>
  121. </div>
  122. </div>
  123. <div className='app-card-grid'>
  124. {paginatedApps.map((app) => {
  125. return (
  126. <AppCard
  127. key={app.id}
  128. {...app} // 直接使用原始数据,不使用 processAppData
  129. showCreator={pageConfig.showCreator}
  130. showActions={true} // 显示悬停操作按钮(分享/收藏)
  131. showCertification={pageConfig.showCertification}
  132. showTags={pageConfig.showTags}
  133. showHot={pageConfig.showHot}
  134. showViewCount={true} // 所有页面常态显示查看数
  135. showFavoriteCount={true} // 所有页面常态显示收藏数
  136. showCreateTime={true} // 所有页面常态显示创建时间
  137. createTime={app.createTime ? app.createTime.split(' ')[0] : ''}
  138. showOperations={true} // 显示悬停操作按钮
  139. isCreator={app.creatorId === mockCurrentUser.id}
  140. onView={() => handlePlay(app.id)}
  141. onApi={() => handleApi(app.id)}
  142. onApiDirect={() => handleApi(app.id)} // API 调用(非创建者)
  143. onEdit={app.creatorId === mockCurrentUser.id ? () => handleEdit(app.id) : undefined}
  144. onDelete={app.creatorId === mockCurrentUser.id ? () => handleDelete(app.id) : undefined}
  145. onShare={() => handleShare(app.id)}
  146. onFavorite={() => handleFavorite(app.id)}
  147. />
  148. );
  149. })}
  150. </div>
  151. {/* 分页器 */}
  152. <div className='pagination-container'>
  153. <Pagination
  154. current={currentPage}
  155. pageSize={pageSize}
  156. total={allApps.length}
  157. onChange={handlePageChange}
  158. showSizeChanger={true}
  159. showQuickJumper={true}
  160. showTotal={(total) => `共 ${total} 条`}
  161. pageSizeOptions={['12', '24', '36', '48']}
  162. />
  163. </div>
  164. {/* 筛选抽屉 */}
  165. <FilterDrawer
  166. open={filterOpen}
  167. onClose={() => setFilterOpen(false)}
  168. onApplyFilter={handleApplyFilter}
  169. />
  170. </div>
  171. );
  172. };
  173. export default AppPlazaList;