You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Wails V2中实现Go后端下载日志推送至React前端展示

Wails V2 + React 前端展示日志解决方案

后端实现(Go)

核心思路是利用Wails的事件系统,将日志内容作为事件推送到前端。

1. 导入Wails运行时包

确保代码中引入Wails的runtime包:

import "github.com/wailsapp/wails/v2/pkg/runtime"

2. 在日志输出处添加事件推送

修改现有代码,在输出日志的同时,通过runtime.Events.Emit向前端发送事件:

for results.Next(ctx) {
    var singleTrack Track
    if err = results.Decode(&singleTrack); err != nil {
        log.Println(err)
        // 推送错误日志到前端
        runtime.Events.Emit(ctx, "log-message", map[string]interface{}{
            "level":   "error",
            "message": err.Error(),
        })
    }

    baseFileName := "PMC_" + path.Base(singleTrack.FilePathUncompressed)
    downloadTarget := downloadUrl + singleTrack.FilePathCompressed

    resp, err := grab.Get(downloadDir+"/"+baseFileName, downloadTarget)

    if err != nil {
        // 推送致命错误日志后再退出
        runtime.Events.Emit(ctx, "log-message", map[string]interface{}{
            "level":   "fatal",
            "message": err.Error(),
        })
        log.Fatal(err)
    }

    // 推送Info日志到前端
    log.Info(resp.Filename)
    runtime.Events.Emit(ctx, "log-message", map[string]interface{}{
        "level":   "info",
        "message": resp.Filename,
    })

    tracks = append(tracks, singleTrack)

    if singleTrack.Variations == nil {
        masterIds = append(masterIds, singleTrack.ID.Hex())
    } else {
        trackVariations := singleTrack.Variations.Variations
        for _, trackId := range trackVariations {
            masterIds = append(masterIds, trackId.TrackID)
        }
    }
}

3. 进阶:自定义日志封装(可选)

如果不想重复编写事件推送代码,可以封装一个日志工具类,自动同步日志到前端:

type AppLogger struct {
    ctx context.Context
}

func NewAppLogger(ctx context.Context) *AppLogger {
    return &AppLogger{ctx: ctx}
}

func (l *AppLogger) Info(msg string) {
    log.Info(msg)
    runtime.Events.Emit(l.ctx, "log-message", map[string]interface{}{
        "level":   "info",
        "message": msg,
    })
}

func (l *AppLogger) Error(err error) {
    log.Error(err)
    runtime.Events.Emit(l.ctx, "log-message", map[string]interface{}{
        "level":   "error",
        "message": err.Error(),
    })
}

func (l *AppLogger) Fatal(err error) {
    runtime.Events.Emit(l.ctx, "log-message", map[string]interface{}{
        "level":   "fatal",
        "message": err.Error(),
    })
    log.Fatal(err)
}

使用时直接调用封装后的方法:

logger := NewAppLogger(ctx)
logger.Info(resp.Filename)

前端实现(React)

通过监听Wails的事件,接收后端推送的日志并展示。

1. 创建日志展示组件

import { useState, useEffect } from 'react';

export default function LogDisplay() {
    const [logs, setLogs] = useState([]);

    useEffect(() => {
        // 监听后端发送的日志事件
        const logHandler = (logData) => {
            setLogs(prevLogs => [...prevLogs, logData]);
            // 自动滚动到最新日志
            setTimeout(() => {
                const container = document.getElementById('log-container');
                if (container) container.scrollTop = container.scrollHeight;
            }, 0);
        };

        window.wails.Events.On('log-message', logHandler);

        // 组件卸载时移除监听
        return () => {
            window.wails.Events.Off('log-message', logHandler);
        };
    }, []);

    return (
        <div id="log-container" style={{ 
            height: '350px', 
            overflowY: 'auto', 
            border: '1px solid #e0e0e0', 
            borderRadius: '4px', 
            padding: '10px',
            fontFamily: 'monospace'
        }}>
            {logs.map((log, index) => (
                <div 
                    key={index}
                    style={{ 
                        color: log.level === 'error' || log.level === 'fatal' ? '#dc2626' : '#2563eb',
                        marginBottom: '4px'
                    }}
                >
                    [{new Date().toLocaleString()}] [{log.level.toUpperCase()}]: {log.message}
                </div>
            ))}
        </div>
    );
}

2. 在主应用中引入组件

将日志组件添加到需要展示的页面:

import LogDisplay from './LogDisplay';

function App() {
    return (
        <div className="App">
            {/* 其他业务组件 */}
            <div style={{ margin: '20px' }}>
                <h3>实时日志</h3>
                <LogDisplay />
            </div>
        </div>
    );
}

export default App;

内容的提问来源于stack exchange,提问作者Jamie_D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:20:03