feat(app): 添加自动启动和日志滚动功能并优化上传逻辑

- 增加了运行时自动启动上传配置选项
- 实现了日志输出的滚动控制功能
- 优化了上传进度显示和状态同步机制
- 提升了HTTP客户端连接池配置至500
- 改进了文件上传完成后的清理逻辑
- 添加了上下文取消检查避免资源泄露
- 完善了上传开始时的日志信息输出
This commit is contained in:
2026-04-27 23:40:10 +08:00
parent d4cc335fbf
commit f96f23360c
4 changed files with 72 additions and 27 deletions
+8
View File
@@ -35,6 +35,14 @@ func (a *App) startup(ctx context.Context) {
} }
}() }()
// 后台 goroutine 持续推送运行状态
go func() {
for {
time.Sleep(500 * time.Millisecond)
runtime.EventsEmit(a.ctx, "is-run", a.isRun)
}
}()
//在程序启动时运行上传程序 //在程序启动时运行上传程序
a.uploaderCTX, a.uploaderCancel = context.WithCancel(a.ctx) a.uploaderCTX, a.uploaderCancel = context.WithCancel(a.ctx)
if config.APPConfig.IsRunOnStart { if config.APPConfig.IsRunOnStart {
+21 -9
View File
@@ -12,11 +12,13 @@ const token = ref('')
const checkDir = ref('') const checkDir = ref('')
const concurrentFiles = ref(1) const concurrentFiles = ref(1)
const uploadThreads = ref(1) const uploadThreads = ref(1)
const autoStart = ref(false)
const progress = ref(0) const progress = ref(0)
const isRunning = ref(false) const isRunning = ref(false)
const logOutput = ref<string[]>([]) const logOutput = ref<string[]>([])
const logContentRef = ref<HTMLElement>() const logContentRef = ref<HTMLElement>()
const logRoll = ref(true)
interface FileProgress { interface FileProgress {
name: string name: string
@@ -32,7 +34,7 @@ const progressList = ref<FileProgress[]>([
const addLog = (msg: string) => { const addLog = (msg: string) => {
logOutput.value.push(`[${new Date().toLocaleString()}]` + msg) logOutput.value.push(`[${new Date().toLocaleString()}]` + msg)
nextTick(() => { nextTick(() => {
if (logContentRef.value) { if (logContentRef.value && logRoll.value){
logContentRef.value.scrollTop = logContentRef.value.scrollHeight logContentRef.value.scrollTop = logContentRef.value.scrollHeight
} }
}) })
@@ -60,13 +62,6 @@ const startRun = () => {
} }
isRunning.value = true isRunning.value = true
progress.value = 0 progress.value = 0
addLog("===============================================")
// addLog(`开始运行...`)
addLog(`服务器: ${serverUrl.value}`)
addLog(`检测目录: ${checkDir.value}`)
addLog(`同时处理文件数: ${concurrentFiles.value}`)
addLog(`单文件上传线程: ${uploadThreads.value}`)
addLog("===============================================")
StartUpload() StartUpload()
} }
@@ -100,6 +95,7 @@ try {
checkDir.value = config.check_dir checkDir.value = config.check_dir
concurrentFiles.value = config.handle_file_count concurrentFiles.value = config.handle_file_count
uploadThreads.value = config.thread_count uploadThreads.value = config.thread_count
autoStart.value = config.is_run_on_start
LogPrint(`[${new Date().toLocaleString()}] 配置已加载`) LogPrint(`[${new Date().toLocaleString()}] 配置已加载`)
}) })
@@ -122,6 +118,9 @@ watch(concurrentFiles, () => {
watch(uploadThreads, () => { watch(uploadThreads, () => {
WriteConfig("thread-count", uploadThreads.value) WriteConfig("thread-count", uploadThreads.value)
}) })
watch(autoStart, () => {
WriteConfig("is-run-on-start", autoStart.value)
})
EventsOn("log", (msg) => { EventsOn("log", (msg) => {
addLog(msg) addLog(msg)
@@ -129,6 +128,9 @@ EventsOn("log", (msg) => {
EventsOn("progress", (progress) => { EventsOn("progress", (progress) => {
progressList.value = progress progressList.value = progress
}) })
EventsOn("is-run", (run) => {
isRunning.value = run
})
</script> </script>
<template> <template>
@@ -162,6 +164,10 @@ EventsOn("progress", (progress) => {
<el-input-number v-model="uploadThreads" :min="1" :max="100" :disabled="isRunning"/> <el-input-number v-model="uploadThreads" :min="1" :max="100" :disabled="isRunning"/>
</div> </div>
<div class="form-item">
<el-checkbox v-model="autoStart" label="运行时自动启动上传" size="large" :disabled="isRunning"/>
</div>
<div class="form-item"> <div class="form-item">
<label>上传进度</label> <label>上传进度</label>
<div class="progress-list"> <div class="progress-list">
@@ -181,7 +187,10 @@ EventsOn("progress", (progress) => {
</div> </div>
<div class="right-panel"> <div class="right-panel">
<div class="log-header">日志输出</div> <div class="log-header">
日志输出
<el-checkbox v-model="logRoll" label="开启日志滚动"/>
</div>
<div class="log-content" ref="logContentRef"> <div class="log-content" ref="logContentRef">
<div v-for="(log, index) in logOutput" :key="index" class="log-line">{{ log }}</div> <div v-for="(log, index) in logOutput" :key="index" class="log-line">{{ log }}</div>
</div> </div>
@@ -286,6 +295,9 @@ EventsOn("progress", (progress) => {
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
color: #303133; color: #303133;
display: flex;
justify-content: space-between;
align-items: center;
} }
.log-content { .log-content {
+2 -2
View File
@@ -11,8 +11,8 @@ import (
var httpClient = &http.Client{ var httpClient = &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
MaxIdleConns: 200, MaxIdleConns: 500,
MaxIdleConnsPerHost: 200, MaxIdleConnsPerHost: 500,
IdleConnTimeout: 30 * time.Second, IdleConnTimeout: 30 * time.Second,
}, },
Timeout: 30 * time.Second, Timeout: 30 * time.Second,
+25
View File
@@ -9,6 +9,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
@@ -33,6 +34,13 @@ type Progress struct {
} }
func StartLooking(ctx context.Context, logChan *chan string, lookingPath string) { func StartLooking(ctx context.Context, logChan *chan string, lookingPath string) {
AddLog(logChan, "===============================================")
AddLog(logChan, `服务器: `+config.APPConfig.Url)
AddLog(logChan, `Token: `+config.APPConfig.Token)
AddLog(logChan, `检测目录: `+config.APPConfig.CheckDir)
AddLog(logChan, `同时处理文件数: `+strconv.Itoa(config.APPConfig.HandleFileCount))
AddLog(logChan, `单文件上传线程: `+strconv.Itoa(config.APPConfig.ThreadCount))
AddLog(logChan, "===============================================")
//推送上传进度 //推送上传进度
go func() { go func() {
for { for {
@@ -108,6 +116,7 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
fileLines[filepath.Base(filePath)] = lineCount fileLines[filepath.Base(filePath)] = lineCount
isAllEmpty = false isAllEmpty = false
AddLog(logChan, fmt.Sprintf("%s 文件行数:%v", filepath.Base(filePath), lineCount)) AddLog(logChan, fmt.Sprintf("%s 文件行数:%v", filepath.Base(filePath), lineCount))
progress.Store(filepath.Base(filePath), Progress{FileName: filepath.Base(filePath), Total: lineCount, Uploaded: 0, Percentage: 0})
} }
} }
if isAllEmpty { if isAllEmpty {
@@ -135,6 +144,10 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
processFile(egctx, logChan, task.FilePath, task.FileLines) processFile(egctx, logChan, task.FilePath, task.FileLines)
select {
case <-egctx.Done():
return egctx.Err()
default:
//上传完成,清空文件 //上传完成,清空文件
err := os.Truncate(task.FilePath, 0) err := os.Truncate(task.FilePath, 0)
if err != nil { if err != nil {
@@ -142,9 +155,14 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
} }
return nil return nil
} }
}
}) })
} }
select {
case <-ctx.Done():
return
default:
// 等待所有任务完成 // 等待所有任务完成
if err := g.Wait(); err != nil { if err := g.Wait(); err != nil {
AddLog(logChan, fmt.Sprintf("任务执行出错: %v", err)) AddLog(logChan, fmt.Sprintf("任务执行出错: %v", err))
@@ -154,6 +172,7 @@ func uploadData(ctx context.Context, logChan *chan string, lookingPath string) {
AddLog(logChan, fmt.Sprintf("上传完成,耗时:%s", time.Since(start).String())) AddLog(logChan, fmt.Sprintf("上传完成,耗时:%s", time.Since(start).String()))
progress.Clear() progress.Clear()
}
} }
// 获取目录中的所有txt文件 // 获取目录中的所有txt文件
@@ -194,10 +213,15 @@ func processFile(ctx context.Context, logChan *chan string, filePath string, fil
var countLine int32 = 0 var countLine int32 = 0
// 创建指定个worker同时处理文件上传 // 创建指定个worker同时处理文件上传
for i := 0; i < config.APPConfig.ThreadCount; i++ { for i := 0; i < config.APPConfig.ThreadCount; i++ {
select {
case <-ctx.Done():
return
default:
wg.Go(func() { wg.Go(func() {
processLines(ctx, logChan, &lines, i, filePath, &countLine) processLines(ctx, logChan, &lines, i, filePath, &countLine)
}) })
} }
}
// 读取文件并发送到通道 // 读取文件并发送到通道
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
@@ -257,6 +281,7 @@ func processLines(ctx context.Context, logChan *chan string, lines *chan string,
} }
} }
// AddLog 添加日志
func AddLog(logChan *chan string, message string) { func AddLog(logChan *chan string, message string) {
*logChan <- message *logChan <- message
} }