22
33import React , { useState , useMemo , useEffect } from 'react' ;
44import { Table , Button , Space , Popconfirm } from 'antd' ;
5- import { EditOutlined , DeleteOutlined } from '@ant-design/icons' ;
5+ import { EditOutlined , DeleteOutlined , RightOutlined , DownOutlined } from '@ant-design/icons' ;
66import type { ColumnsType } from 'antd/es/table' ;
77import { Link } from '@/types/link' ;
88import { Category } from '@/types/category' ;
@@ -59,18 +59,19 @@ export const DataTable: React.FC<DataTableProps> = ({
5959 const categories = useAppSelector ( ( state ) => state . categories . items ) ;
6060
6161 // 使用外部传入的 selectedRowKeys 或内部状态
62- const selectedRowKeys = externalSelectedRowKeys !== undefined ? externalSelectedRowKeys : internalSelectedRowKeys ;
62+ const selectedRowKeys =
63+ externalSelectedRowKeys !== undefined ? externalSelectedRowKeys : internalSelectedRowKeys ;
6364
6465 // 构建树形数据结构
6566 const treeData = useMemo ( ( ) => {
6667 const tree : TreeNode [ ] = [ ] ;
6768
6869 // 按分类组织链接
69- categories . forEach ( category => {
70+ categories . forEach ( ( category ) => {
7071 const categoryLinks = links
71- . filter ( link => link . category === category . name )
72+ . filter ( ( link ) => link . category === category . name )
7273 . sort ( ( a , b ) => a . order - b . order )
73- . map ( link => ( {
74+ . map ( ( link ) => ( {
7475 key : link . id ,
7576 id : link . id ,
7677 name : link . name ,
@@ -101,9 +102,9 @@ export const DataTable: React.FC<DataTableProps> = ({
101102
102103 // 添加未分类节点(如果有未分类的链接)
103104 const uncategorizedLinks = links
104- . filter ( link => ! link . category || link . category === '' )
105+ . filter ( ( link ) => ! link . category || link . category === '' )
105106 . sort ( ( a , b ) => a . order - b . order )
106- . map ( link => ( {
107+ . map ( ( link ) => ( {
107108 key : link . id ,
108109 id : link . id ,
109110 name : link . name ,
@@ -136,42 +137,62 @@ export const DataTable: React.FC<DataTableProps> = ({
136137 return tree . sort ( ( a , b ) => a . order - b . order ) ;
137138 } , [ links , categories ] ) ;
138139
139- // 默认展开所有分类(包括未分类)
140+ // 默认展开第一个分类
140141 useEffect ( ( ) => {
141- const allCategoryKeys = categories . map ( cat => `category-${ cat . id } ` ) ;
142- // 如果有未分类链接,也展开未分类节点
143- const hasUncategorized = links . some ( link => ! link . category || link . category === '' ) ;
144- if ( hasUncategorized ) {
145- allCategoryKeys . push ( 'category-uncategorized' ) ;
142+ if ( categories . length > 0 ) {
143+ const firstCategoryKey = `category-${ categories [ 0 ] . id } ` ;
144+ setExpandedRowKeys ( [ firstCategoryKey ] ) ;
146145 }
147- setExpandedRowKeys ( allCategoryKeys ) ;
148- } , [ categories , links ] ) ;
146+ } , [ categories ] ) ;
149147
150148 // 表格列定义
151149 const columns : ColumnsType < TreeNode > = [
152150 {
153151 title : '名称' ,
154152 dataIndex : 'name' ,
155153 key : 'name' ,
156- width : 160 ,
154+ width : 120 ,
157155 ellipsis : true ,
158- render : ( name : string , record : TreeNode ) => (
159- < span className = { record . isCategory ? 'font-semibold text-base' : '' } >
160- { name }
161- </ span >
162- ) ,
156+ render : ( name : string , record : TreeNode ) =>
157+ record . isCategory ? (
158+ < span className = "font-semibold" > { name } </ span >
159+ ) : record . icon ? (
160+ < div className = "flex items-center" >
161+ < div
162+ className = "w-6 h-6 rounded border border-gray-300 flex justify-center items-center mr-2"
163+ style = { { background : record . backgroundColor } }
164+ >
165+ < img
166+ src = { record . icon }
167+ alt = "图标"
168+ className = "w-4 h-4 object-contain"
169+ onError = { ( e ) => {
170+ e . currentTarget . style . display = 'none' ;
171+ } }
172+ />
173+ </ div >
174+ < span > { name } </ span >
175+ </ div >
176+ ) : (
177+ < span > { name } </ span >
178+ ) ,
163179 } ,
164180 {
165181 title : '地址' ,
166182 dataIndex : 'url' ,
167183 key : 'url' ,
168- width : 200 ,
184+ width : 180 ,
169185 ellipsis : true ,
170- render : ( url : string , record : TreeNode ) =>
186+ render : ( url : string , record : TreeNode ) =>
171187 record . isCategory ? (
172188 < span className = "text-gray-400" > -</ span >
173189 ) : url ? (
174- < a href = { url } target = "_blank" rel = "noopener noreferrer" className = "text-blue-500 hover:text-blue-700" >
190+ < a
191+ href = { url }
192+ target = "_blank"
193+ rel = "noopener noreferrer"
194+ className = "text-blue-500 hover:text-blue-700"
195+ >
175196 { url }
176197 </ a >
177198 ) : null ,
@@ -180,21 +201,21 @@ export const DataTable: React.FC<DataTableProps> = ({
180201 title : '描述' ,
181202 dataIndex : 'description' ,
182203 key : 'description' ,
183- width : 300 ,
204+ width : 240 ,
184205 ellipsis : true ,
185- render : ( description : string , record : TreeNode ) =>
206+ render : ( description : string , record : TreeNode ) =>
186207 record . isCategory ? (
187208 < span className = "text-gray-500" > 共 { record . children ?. length || 0 } 条链接</ span >
188209 ) : (
189210 description
190211 ) ,
191212 } ,
192213 {
193- title : '背景颜色 ' ,
214+ title : '背景 ' ,
194215 dataIndex : 'backgroundColor' ,
195216 key : 'backgroundColor' ,
196217 width : 100 ,
197- render : ( color : string , record : TreeNode ) =>
218+ render : ( color : string , record : TreeNode ) =>
198219 record . isCategory ? (
199220 < span className = "text-gray-400" > -</ span >
200221 ) : (
@@ -210,15 +231,15 @@ export const DataTable: React.FC<DataTableProps> = ({
210231 {
211232 title : '操作' ,
212233 key : 'action' ,
213- width : 150 ,
234+ width : 120 ,
214235 fixed : 'right' ,
215236 render : ( _ , record : TreeNode ) => {
216237 if ( record . isCategory ) {
217238 // 未分类节点不允许编辑和删除
218239 if ( record . id === 'uncategorized' ) {
219240 return < span className = "text-gray-400" > -</ span > ;
220241 }
221-
242+
222243 // 分类节点的操作
223244 const category : Category = {
224245 id : record . id ,
@@ -228,7 +249,7 @@ export const DataTable: React.FC<DataTableProps> = ({
228249 createdAt : record . createdAt ,
229250 updatedAt : record . updatedAt ,
230251 } ;
231-
252+
232253 return (
233254 < Space size = "small" >
234255 < Button
@@ -250,19 +271,14 @@ export const DataTable: React.FC<DataTableProps> = ({
250271 cancelText = "取消"
251272 okType = "danger"
252273 >
253- < Button
254- type = "link"
255- danger
256- icon = { < DeleteOutlined /> }
257- size = "small"
258- >
274+ < Button type = "link" danger icon = { < DeleteOutlined /> } size = "small" >
259275 删除
260276 </ Button >
261277 </ Popconfirm >
262278 </ Space >
263279 ) ;
264280 }
265-
281+
266282 // 链接节点的操作
267283 return (
268284 < Space size = "small" >
@@ -280,12 +296,7 @@ export const DataTable: React.FC<DataTableProps> = ({
280296 okText = "确定"
281297 cancelText = "取消"
282298 >
283- < Button
284- type = "link"
285- danger
286- icon = { < DeleteOutlined /> }
287- size = "small"
288- >
299+ < Button type = "link" danger icon = { < DeleteOutlined /> } size = "small" >
289300 删除
290301 </ Button >
291302 </ Popconfirm >
@@ -300,7 +311,7 @@ export const DataTable: React.FC<DataTableProps> = ({
300311 selectedRowKeys,
301312 onChange : ( newSelectedRowKeys : React . Key [ ] ) => {
302313 // 过滤掉分类节点
303- const linkKeys = newSelectedRowKeys . filter ( key => ! String ( key ) . startsWith ( 'category-' ) ) ;
314+ const linkKeys = newSelectedRowKeys . filter ( ( key ) => ! String ( key ) . startsWith ( 'category-' ) ) ;
304315 if ( onSelectionChange ) {
305316 onSelectionChange ( linkKeys ) ;
306317 } else {
@@ -321,15 +332,12 @@ export const DataTable: React.FC<DataTableProps> = ({
321332 rowKey = "key"
322333 size = "middle"
323334 rowSelection = { rowSelection }
324- rowClassName = { ( record ) =>
325- record . isCategory
326- ? 'category-row'
327- : ''
328- }
335+ rowClassName = { ( record ) => ( record . isCategory ? 'category-row' : '' ) }
329336 expandable = { {
330337 expandedRowKeys,
338+ indentSize : 0 ,
331339 onExpandedRowsChange : ( keys ) => setExpandedRowKeys ( [ ...keys ] ) ,
332- defaultExpandAllRows : true ,
340+ // defaultExpandAllRows: true,
333341 } }
334342 pagination = { {
335343 current : currentPage ,
@@ -347,7 +355,6 @@ export const DataTable: React.FC<DataTableProps> = ({
347355 pageSizeOptions : [ '10' , '20' , '50' , '100' ] ,
348356 } }
349357 scroll = { { x : 1200 } }
350- className = "[&_.ant-empty]:z-0 [&_.category-row>td]:bg-blue-50! [&_.category-row>td]:dark:bg-blue-900/30! [&_.category-row:hover>td]:bg-blue-100! [&_.category-row:hover>td]:dark:bg-blue-800/40!"
351358 />
352359 </ div >
353360 ) ;
0 commit comments