@@ -181,6 +181,140 @@ app.whenReady().then(() => {
181181 }
182182 ) ;
183183
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 [ ] = [ ] ;
193+
194+ async function traverseDirectory (
195+ currentPath : string ,
196+ relativePath : string = ''
197+ ) : Promise < void > {
198+ try {
199+ const items = await fs . readdir ( currentPath , {
200+ withFileTypes : true ,
201+ } ) ;
202+
203+ for ( const item of items ) {
204+ const fullPath = path . join ( currentPath , item . name ) ;
205+ const newRelativePath = relativePath
206+ ? `${ relativePath } /${ item . name } `
207+ : item . name ;
208+
209+ if ( item . isDirectory ( ) ) {
210+ // 递归遍历子目录
211+ await traverseDirectory ( fullPath , newRelativePath ) ;
212+ } else if (
213+ item . isFile ( ) &&
214+ item . name . endsWith ( '.jsonl' ) &&
215+ item . name !== 'summary.json'
216+ ) {
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+ }
232+ }
233+ }
234+ } catch ( error ) {
235+ console . error ( `Error reading directory ${ currentPath } :` , error ) ;
236+ }
237+ }
238+
239+ 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+ ) ;
251+ return filePaths . sort ( ) ;
252+ }
253+
254+ ipcMain . handle (
255+ 'get-all-jsonl-file-paths' ,
256+ async ( event , dirPath : string ) => {
257+ try {
258+ return await getAllJsonlFilePathsRecursive ( dirPath ) ;
259+ } catch ( error ) {
260+ console . error ( 'Error getting all JSONL file paths:' , error ) ;
261+ throw error ;
262+ }
263+ }
264+ ) ;
265+
266+ // 修改 readAllJsonlFilesRecursive,为每个数据项添加文件路径信息
267+ async function readAllJsonlFilesRecursiveWithPath (
268+ dirPath : string
269+ ) : Promise < any [ ] > {
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 ;
301+ }
302+ }
303+ ) ;
304+
305+ // 展平所有数组
306+ return allDataArrays . flat ( ) ;
307+ }
308+
309+ ipcMain . handle ( 'read-all-jsonl-files' , async ( event , dirPath : string ) => {
310+ try {
311+ return await readAllJsonlFilesRecursiveWithPath ( dirPath ) ;
312+ } catch ( error ) {
313+ console . error ( 'Error reading all JSONL files:' , error ) ;
314+ throw error ;
315+ }
316+ } ) ;
317+
184318 ipcMain . handle ( 'get-input-path' , ( ) => {
185319 const argv = minimist ( process ?. argv ?. slice ( 2 ) ) ;
186320 const inputPath = argv . input ;
0 commit comments