Skip to content

Commit 038cee6

Browse files
committed
feat:adopt table column width and make data reading function as public method
1 parent d317688 commit 038cee6

File tree

5 files changed

+181
-5582
lines changed

5 files changed

+181
-5582
lines changed

app/src/main/index.ts

Lines changed: 69 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,15 @@ app.whenReady().then(() => {
181181
}
182182
);
183183

184-
// 递归获取所有 jsonl 文件的路径列表(相对路径)
185-
async function getAllJsonlFilePathsRecursive(
186-
dirPath: string
187-
): Promise<string[]> {
188-
const filePaths: string[] = [];
184+
// 通用的递归遍历 jsonl 文件的辅助函数
185+
async function traverseJsonlFiles<T>(
186+
dirPath: string,
187+
processFile: (
188+
fullPath: string,
189+
relativePath: string
190+
) => Promise<T | null>
191+
): Promise<T[]> {
192+
const results: T[] = [];
189193

190194
async function traverseDirectory(
191195
currentPath: string,
@@ -210,8 +214,21 @@ app.whenReady().then(() => {
210214
item.name.endsWith('.jsonl') &&
211215
item.name !== 'summary.json'
212216
) {
213-
// 添加 jsonl 文件路径(相对路径)
214-
filePaths.push(newRelativePath);
217+
// 处理 jsonl 文件
218+
try {
219+
const result = await processFile(
220+
fullPath,
221+
newRelativePath
222+
);
223+
if (result !== null) {
224+
results.push(result);
225+
}
226+
} catch (error) {
227+
console.error(
228+
`Error processing file ${fullPath}:`,
229+
error
230+
);
231+
}
215232
}
216233
}
217234
} catch (error) {
@@ -220,6 +237,17 @@ app.whenReady().then(() => {
220237
}
221238

222239
await traverseDirectory(dirPath);
240+
return results;
241+
}
242+
243+
// 递归获取所有 jsonl 文件的路径列表(相对路径)
244+
async function getAllJsonlFilePathsRecursive(
245+
dirPath: string
246+
): Promise<string[]> {
247+
const filePaths = await traverseJsonlFiles<string>(
248+
dirPath,
249+
async (_, relativePath) => relativePath
250+
);
223251
return filePaths.sort();
224252
}
225253

@@ -239,75 +267,43 @@ app.whenReady().then(() => {
239267
async function readAllJsonlFilesRecursiveWithPath(
240268
dirPath: string
241269
): Promise<any[]> {
242-
const allData: any[] = [];
243-
244-
async function traverseDirectory(
245-
currentPath: string,
246-
relativePath: string = ''
247-
): Promise<void> {
248-
try {
249-
const items = await fs.readdir(currentPath, {
250-
withFileTypes: true,
251-
});
252-
253-
for (const item of items) {
254-
const fullPath = path.join(currentPath, item.name);
255-
const newRelativePath = relativePath
256-
? `${relativePath}/${item.name}`
257-
: item.name;
258-
259-
if (item.isDirectory()) {
260-
// 递归遍历子目录
261-
await traverseDirectory(fullPath, newRelativePath);
262-
} else if (
263-
item.isFile() &&
264-
item.name.endsWith('.jsonl') &&
265-
item.name !== 'summary.json'
266-
) {
267-
// 读取 jsonl 文件(排除 summary.json)
268-
try {
269-
const fileContent = await fs.readFile(
270-
fullPath,
271-
'utf-8'
272-
);
273-
const lines = fileContent
274-
.trim()
275-
.split('\n')
276-
.filter(line => line.trim());
277-
const parsedData = lines
278-
.map(line => {
279-
try {
280-
const data = JSON.parse(line);
281-
// 为每个数据项添加文件路径信息
282-
return {
283-
...data,
284-
_filePath: newRelativePath,
285-
};
286-
} catch (e) {
287-
console.error(
288-
`Error parsing line in ${fullPath}:`,
289-
e
290-
);
291-
return null;
292-
}
293-
})
294-
.filter(item => item !== null);
295-
allData.push(...parsedData);
296-
} catch (error) {
297-
console.error(
298-
`Error reading file ${fullPath}:`,
299-
error
300-
);
301-
}
302-
}
270+
const allDataArrays = await traverseJsonlFiles<any[]>(
271+
dirPath,
272+
async (fullPath, relativePath) => {
273+
try {
274+
const fileContent = await fs.readFile(fullPath, 'utf-8');
275+
const lines = fileContent
276+
.trim()
277+
.split('\n')
278+
.filter(line => line.trim());
279+
const parsedData = lines
280+
.map(line => {
281+
try {
282+
const data = JSON.parse(line);
283+
// 为每个数据项添加文件路径信息
284+
return {
285+
...data,
286+
_filePath: relativePath,
287+
};
288+
} catch (e) {
289+
console.error(
290+
`Error parsing line in ${fullPath}:`,
291+
e
292+
);
293+
return null;
294+
}
295+
})
296+
.filter(item => item !== null);
297+
return parsedData;
298+
} catch (error) {
299+
console.error(`Error reading file ${fullPath}:`, error);
300+
return null;
303301
}
304-
} catch (error) {
305-
console.error(`Error reading directory ${currentPath}:`, error);
306302
}
307-
}
303+
);
308304

309-
await traverseDirectory(dirPath);
310-
return allData;
305+
// 展平所有数组
306+
return allDataArrays.flat();
311307
}
312308

313309
ipcMain.handle('read-all-jsonl-files', async (event, dirPath: string) => {

app/src/renderer/src/components/detail-table.tsx

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { ColumnsType } from 'antd/es/table';
44
import { useDALStore } from '@/store/dal';
55
import { FormattedMessage } from 'react-intl';
66
import { SummaryData } from '@/pages/main-home/components/summary-data-table';
7-
import { uniqBy } from 'lodash';
87
import FilterCascader from './filter-cascader';
98
import HighlightText from './HightLightText';
109

@@ -58,8 +57,7 @@ const DetailTable: React.FC<DetailTableProps> = ({ currentPath }) => {
5857
currentPath,
5958
})) as DataItem[]) || [];
6059

61-
// 使用 id 作为唯一标识
62-
setData(uniqBy(allData, 'id'));
60+
setData(allData);
6361
setCurrent({
6462
...current,
6563
currentPage: 1,
@@ -120,7 +118,6 @@ const DetailTable: React.FC<DetailTableProps> = ({ currentPath }) => {
120118
title: key,
121119
dataIndex: key,
122120
key: key,
123-
minWidth: 100,
124121
render: (value: unknown, record) => {
125122
if (key === 'content') {
126123
return (
@@ -142,25 +139,51 @@ const DetailTable: React.FC<DetailTableProps> = ({ currentPath }) => {
142139
!Array.isArray(value)
143140
) {
144141
return (
145-
<span className="select-text">
146-
{JSON.stringify(value, null, 2)}
147-
</span>
142+
<HighlightText
143+
text={JSON.stringify(value).slice(0, 10000)}
144+
highlight={record.reason_list || ''}
145+
showHighlight={false}
146+
/>
148147
);
149148
}
150149
// 如果是数组,显示为 JSON
151150
if (Array.isArray(value)) {
152151
return (
153-
<span className="select-text">
152+
<span
153+
className="select-text"
154+
style={{
155+
wordBreak: 'break-word',
156+
whiteSpace: 'pre-wrap',
157+
}}
158+
>
154159
{JSON.stringify(value)}
155160
</span>
156161
);
157162
}
158163
// 如果是字符串,直接显示
159164
if (typeof value === 'string') {
160-
return <span>{value || '-'}</span>;
165+
return (
166+
<span
167+
style={{
168+
wordBreak: 'break-word',
169+
whiteSpace: 'pre-wrap',
170+
}}
171+
>
172+
{value || '-'}
173+
</span>
174+
);
161175
}
162176
// 其他类型直接显示
163-
return <span>{String(value ?? '-')}</span>;
177+
return (
178+
<span
179+
style={{
180+
wordBreak: 'break-word',
181+
whiteSpace: 'pre-wrap',
182+
}}
183+
>
184+
{String(value ?? '-')}
185+
</span>
186+
);
164187
},
165188
};
166189
}
@@ -186,7 +209,6 @@ const DetailTable: React.FC<DetailTableProps> = ({ currentPath }) => {
186209
rowKey={(record, index) => {
187210
return `${record?._filePath}_${index}`;
188211
}}
189-
sticky={{offsetHeader: -30}}
190212
pagination={{
191213
pageSize: current?.pageSize,
192214
showQuickJumper: true,
@@ -208,7 +230,25 @@ const DetailTable: React.FC<DetailTableProps> = ({ currentPath }) => {
208230
});
209231
}
210232
}}
211-
scroll={{ x: '100%' }}
233+
scroll={{ x: 'max-content' }}
234+
components={{
235+
body: {
236+
cell: (
237+
props: React.TdHTMLAttributes<HTMLTableCellElement>
238+
) => (
239+
<td
240+
{...props}
241+
style={{
242+
...props.style,
243+
whiteSpace: 'normal',
244+
wordBreak: 'break-word',
245+
maxWidth: '500px',
246+
minWidth: '100px',
247+
}}
248+
/>
249+
),
250+
},
251+
}}
212252
/>
213253
</>
214254
);

0 commit comments

Comments
 (0)