daShangDao_kfzgw-info/newWalkingWithBooks.go
97694732@qq.com ac2a39742d 各种修改
2026-06-11 13:21:55 +08:00

2232 lines
68 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
//import (
// "bufio"
// "context"
// "encoding/json"
// "fmt"
// "gopkg.in/yaml.v3"
// "image"
// "image/color"
// "io"
// "io/ioutil"
// "net"
// "net/http"
// "os"
// "os/exec"
// "path/filepath"
// "strings"
// "syscall"
// "time"
// "unsafe"
//
// "gioui.org/app"
// "gioui.org/io/key"
// "gioui.org/layout"
// "gioui.org/op"
// "gioui.org/op/clip"
// "gioui.org/op/paint"
// "gioui.org/unit"
// "gioui.org/widget"
// "gioui.org/widget/material"
//)
//
//// ============================ 常量定义 ============================
//const (
// ColorReset = "\033[0m"
// ColorRed = "\033[31m"
// ColorGreen = "\033[32m"
// ColorYellow = "\033[33m"
// ColorBlue = "\033[34m"
// ColorMagenta = "\033[35m"
// ColorCyan = "\033[36m"
// ColorWhite = "\033[37m"
// ColorGray = "\033[90m"
//
// ColorBoldRed = "\033[1;31m"
// ColorBoldGreen = "\033[1;32m"
// ColorBoldYellow = "\033[1;33m"
// ColorBoldBlue = "\033[1;34m"
//
// ColorBgRed = "\033[41m"
// ColorBgGreen = "\033[42m"
//)
//
//// ============================ 结构体定义 ============================
//type VersionConfig struct {
// CsvVersion string `json:"csv"`
// KongfzVersion string `json:"kongfz"`
// LoggerVersion string `json:"logger"`
// ModuleErpVersion string `json:"module-erp"`
// ModuleKongfzVersion string `json:"module-kongfz"`
// ModuleTaskPoolVersion string `json:"module-taskPool"`
// ModuleVerifyPriceVersion string `json:"module-verifyPrice"`
// ModuleCenterBookVersion string `json:"module-centerBook"`
// ModuleLoginVersion string `json:"module-login"`
// PicToolVersion string `json:"picTool"`
// ProxyVersion string `json:"proxy"`
//}
//
//type VerifyPriceYAML struct {
// VerifyPriceLatestVersion string `yaml:"verifyPriceLatestVersion"`
//}
//
//type VersionInfo struct {
// LatestVersion string `json:"latestVersion"`
// HistoricalVersions []string `json:"historicalVersions"`
// VerifyPriceLatestVersion string `json:"verifyPriceLatestVersion"`
//}
//
//// ============================ Gio GUI 结构体 ============================
//type UpdaterApp struct {
// window *app.Window
// theme *material.Theme
//
// // 小部件
// progress float32
// statusText string
// actionBtn widget.Clickable
// showConsole bool
// consoleText string
// logEntries []string
//
// isPaused bool
// isUpdating bool
// isComplete bool
// isChecking bool
// isDownloading bool
//
// totalSize int64
// downloaded int64
// currentSpeed float64
// startTime time.Time
//
// // 更新状态
// currentFile string
// totalFiles int
// completedFiles int
//
// // 数据
// versionsJSON *VersionConfig
// verifyPriceVersion *VersionInfo
// localConfig VerifyPriceYAML
// currentDir string
// yamlPath string
//
// // 布局
// ops op.Ops
// scroll widget.List
//}
//
//// ============================ 控制台输出函数 ============================
//func printInfo(format string, v ...interface{}) {
// message := fmt.Sprintf(format, v...)
// fmt.Printf(ColorCyan + "[信息] " + message + ColorReset + "\n")
// if globalApp != nil {
// globalApp.addLog("[信息] " + message)
// }
//}
//
//func printSuccess(format string, v ...interface{}) {
// message := fmt.Sprintf(format, v...)
// fmt.Printf(ColorGreen + "[成功] " + message + ColorReset + "\n")
// if globalApp != nil {
// globalApp.addLog("[成功] " + message)
// }
//}
//
//func printWarning(format string, v ...interface{}) {
// message := fmt.Sprintf(format, v...)
// fmt.Printf(ColorYellow + "[警告] " + message + ColorReset + "\n")
// if globalApp != nil {
// globalApp.addLog("[警告] " + message)
// }
//}
//
//func printError(format string, v ...interface{}) {
// message := fmt.Sprintf(format, v...)
// fmt.Printf(ColorRed + "[错误] " + message + ColorReset + "\n")
// if globalApp != nil {
// globalApp.addLog("[错误] " + message)
// }
//}
//
//func printDebug(format string, v ...interface{}) {
// message := fmt.Sprintf(format, v...)
// fmt.Printf(ColorGray + "[调试] " + message + ColorReset + "\n")
// if globalApp != nil {
// globalApp.addLog("[调试] " + message)
// }
//}
//
//func printBanner(format string, v ...interface{}) {
// message := fmt.Sprintf(format, v...)
// fmt.Printf(ColorBoldBlue + "== " + message + " ==\n" + ColorReset)
// if globalApp != nil {
// globalApp.addLog("== " + message + " ==")
// }
//}
//
//func printDownload(format string, v ...interface{}) {
// message := fmt.Sprintf(format, v...)
// fmt.Printf(ColorBoldGreen + "[下载] " + message + ColorReset + "\n")
// if globalApp != nil {
// globalApp.addLog("[下载] " + message)
// }
//}
//
//func printVersionInfo(label, version string) {
// message := fmt.Sprintf("%-30s: %s", label, version)
// fmt.Printf(ColorBoldYellow+"%-30s: "+ColorCyan+"%s"+ColorReset+"\n", label, version)
// if globalApp != nil {
// globalApp.addLog(message)
// }
//}
//
//// ============================ 全局变量 ============================
//var globalApp *UpdaterApp
//
//// ============================ Gio GUI 方法 ============================
//// NewUpdaterApp 创建新的更新器应用
//func NewUpdaterApp() *UpdaterApp {
// // 使用新的 Window 创建方式
// window := new(app.Window)
//
// // 设置窗口选项
// window.Option(
// app.Title("核价软件更新器"),
// app.Size(unit.Dp(800), unit.Dp(600)),
// app.MinSize(unit.Dp(600), unit.Dp(400)),
// )
//
// // 创建主题
// theme := material.NewTheme()
//
// appNew := &UpdaterApp{
// window: window,
// theme: theme,
// progress: 0.0,
// statusText: "初始化更新器...",
// isPaused: false,
// isUpdating: true,
// startTime: time.Now(),
// showConsole: true,
// totalFiles: 12, // DLL文件数量 + 主程序
// scroll: widget.List{
// List: layout.List{
// Axis: layout.Vertical,
// },
// },
// }
//
// globalApp = appNew
// return appNew
//}
//
//// addLog 添加日志条目
//func (u *UpdaterApp) addLog(message string) {
// u.logEntries = append(u.logEntries, message)
// // 保持最后100条日志
// if len(u.logEntries) > 100 {
// u.logEntries = u.logEntries[len(u.logEntries)-100:]
// }
// u.window.Invalidate()
//}
//
//// updateStatus 更新状态文本
//func (u *UpdaterApp) updateStatus(status string) {
// u.statusText = status
// u.addLog(status)
// u.window.Invalidate()
//}
//
//// updateProgress 更新进度
//func (u *UpdaterApp) updateProgress(progress float32) {
// u.progress = progress
// u.window.Invalidate()
//}
//
//// updateFileProgress 更新文件进度
//func (u *UpdaterApp) updateFileProgress(currentFile string, downloaded, totalSize int64) {
// u.currentFile = currentFile
// u.downloaded = downloaded
// u.totalSize = totalSize
//
// if totalSize > 0 {
// u.progress = float32(downloaded) / float32(totalSize)
// }
//
// // 计算速度
// elapsed := time.Since(u.startTime).Seconds()
// if elapsed > 0 && downloaded > 0 {
// u.currentSpeed = float64(downloaded) / elapsed / 1024 / 1024
// }
//
// u.window.Invalidate()
//}
//
//// updateFileCount 更新文件计数
//func (u *UpdaterApp) updateFileCount(completed int) {
// u.completedFiles = completed
//
// // 计算总体进度文件计数占30%文件内进度占70%
// fileProgress := float32(completed) / float32(u.totalFiles)
// overallProgress := 0.3*fileProgress + 0.7*u.progress
// u.updateProgress(overallProgress)
//
// u.window.Invalidate()
//}
//
//// Run 运行GUI主循环
//func (u *UpdaterApp) Run() error {
// // 启动更新过程
// go u.startUpdateProcess()
//
// var ops op.Ops
// for {
// ev := u.window.Event()
// switch e := ev.(type) {
// case app.DestroyEvent:
// return e.Err
//
// case app.FrameEvent:
// gtx := app.NewContext(&ops, e)
// u.handleEvents(gtx)
// u.drawUI(gtx)
// e.Frame(gtx.Ops)
//
// case key.Event:
// if e.Name == "C" && e.Modifiers.Contain(key.ModCtrl) {
// u.showConsole = !u.showConsole
// u.window.Invalidate()
// }
// }
// }
//}
//
//// handleEvents 处理用户事件
//func (u *UpdaterApp) handleEvents(gtx layout.Context) {
// // 处理按钮点击
// if u.actionBtn.Clicked(gtx) {
// if u.isComplete {
// // 启动核价软件
// u.startVerifyPriceApp()
// } else if u.isPaused {
// // 继续更新
// u.isPaused = false
// u.updateStatus("继续更新...")
// } else {
// // 暂停更新
// u.isPaused = true
// u.updateStatus("更新已暂停")
// }
// }
//}
//
//// drawUI 绘制用户界面
//func (u *UpdaterApp) drawUI(gtx layout.Context) layout.Dimensions {
// // 背景色
// paint.Fill(gtx.Ops, color.NRGBA{R: 245, G: 245, B: 245, A: 255})
//
// return layout.Flex{
// Axis: layout.Vertical,
// Spacing: layout.SpaceBetween,
// }.Layout(gtx,
// // 标题栏
// layout.Rigid(u.drawHeader),
//
// // 主内容区域
// layout.Flexed(1, u.drawMainContent),
//
// // 底部控制栏
// layout.Rigid(u.drawFooter),
// )
//}
//
//// drawHeader 绘制标题栏
//func (u *UpdaterApp) drawHeader(gtx layout.Context) layout.Dimensions {
// return layout.Inset{
// Top: unit.Dp(10),
// Bottom: unit.Dp(10),
// Left: unit.Dp(20),
// Right: unit.Dp(20),
// }.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// return layout.Flex{
// Axis: layout.Horizontal,
// Spacing: layout.SpaceBetween,
// Alignment: layout.Middle,
// }.Layout(gtx,
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// title := material.H4(u.theme, "核价软件更新器")
// title.Color = color.NRGBA{R: 0, G: 100, B: 200, A: 255}
// return title.Layout(gtx)
// }),
//
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// // 状态文本和颜色的逻辑保持不变
// statusText := "就绪"
// if u.isChecking {
// statusText = "检查中"
// } else if u.isDownloading {
// statusText = "下载中"
// } else if u.isPaused {
// statusText = "已暂停"
// } else if u.isComplete {
// statusText = "已完成"
// }
//
// // 根据状态设置文本颜色
// statusLabel := material.Body2(u.theme, statusText)
// if u.isPaused {
// statusLabel.Color = color.NRGBA{R: 241, G: 196, B: 15, A: 255} // 黄色
// } else if u.isDownloading {
// statusLabel.Color = color.NRGBA{R: 52, G: 152, B: 219, A: 255} // 蓝色
// } else if u.isChecking {
// statusLabel.Color = color.NRGBA{R: 155, G: 89, B: 182, A: 255} // 紫色
// } else if u.isComplete {
// statusLabel.Color = color.NRGBA{R: 46, G: 204, B: 113, A: 255} // 绿色
// } else {
// statusLabel.Color = color.NRGBA{R: 120, G: 120, B: 120, A: 255} // 灰色
// }
//
// return material.Body2(u.theme, statusText).Layout(gtx)
// }),
// )
// })
//}
//
//// drawMainContent 绘制主内容区域
//func (u *UpdaterApp) drawMainContent(gtx layout.Context) layout.Dimensions {
// return layout.Flex{
// Axis: layout.Vertical,
// Spacing: layout.SpaceSides,
// }.Layout(gtx,
// // 状态信息区域
// layout.Rigid(u.drawStatusInfo),
//
// // 进度条区域
// layout.Rigid(u.drawProgressBar),
//
// // 文件信息区域
// layout.Rigid(u.drawFileInfo),
//
// // 日志区域(可折叠)
// layout.Flexed(1, u.drawLogArea),
// )
//}
//
//// drawStatusInfo 绘制状态信息
//func (u *UpdaterApp) drawStatusInfo(gtx layout.Context) layout.Dimensions {
// return layout.Inset{
// Left: unit.Dp(20),
// Right: unit.Dp(20),
// Top: unit.Dp(10),
// }.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// return layout.Flex{
// Axis: layout.Vertical,
// Spacing: layout.SpaceEnd,
// }.Layout(gtx,
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// status := material.H6(u.theme, u.statusText)
// status.Color = color.NRGBA{R: 60, G: 60, B: 60, A: 255}
// return status.Layout(gtx)
// }),
//
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// if u.currentFile != "" {
// fileInfo := material.Caption(u.theme, "当前文件: "+u.currentFile)
// return fileInfo.Layout(gtx)
// }
// return layout.Dimensions{}
// }),
// )
// })
//}
//
//// drawProgressBar 绘制进度条
//func (u *UpdaterApp) drawProgressBar(gtx layout.Context) layout.Dimensions {
// return layout.Inset{
// Left: unit.Dp(20),
// Right: unit.Dp(20),
// Top: unit.Dp(15),
// Bottom: unit.Dp(15),
// }.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// // 进度条背景
// barHeight := gtx.Dp(unit.Dp(30))
// barWidth := gtx.Constraints.Max.X
//
// // 圆角矩形背景
// rrect := clip.UniformRRect(
// image.Rect(0, 0, barWidth, barHeight),
// gtx.Dp(unit.Dp(6)),
// )
// paint.FillShape(gtx.Ops, color.NRGBA{R: 230, G: 230, B: 230, A: 255}, rrect.Op(gtx.Ops))
//
// // 进度条前景
// progressWidth := int(float32(barWidth) * u.progress)
// if progressWidth > 0 {
// progressRrect := clip.UniformRRect(
// image.Rect(0, 0, progressWidth, barHeight),
// gtx.Dp(unit.Dp(6)),
// )
//
// // 根据进度选择颜色
// var barColor color.NRGBA
// if u.isComplete {
// barColor = color.NRGBA{R: 46, G: 204, B: 113, A: 255} // 绿色
// } else if u.progress < 0.3 {
// barColor = color.NRGBA{R: 231, G: 76, B: 60, A: 255} // 红色
// } else if u.progress < 0.7 {
// barColor = color.NRGBA{R: 241, G: 196, B: 15, A: 255} // 黄色
// } else {
// barColor = color.NRGBA{R: 52, G: 152, B: 219, A: 255} // 蓝色
// }
//
// paint.FillShape(gtx.Ops, barColor, progressRrect.Op(gtx.Ops))
// }
//
// // 使用 Flex 布局来居中文本
// return layout.Flex{
// Axis: layout.Vertical,
// Spacing: layout.SpaceSides,
// Alignment: layout.Middle, // 水平居中
// }.Layout(gtx,
// // 占位空间,让文本垂直居中
// layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
// return layout.Dimensions{}
// }),
// // 文本行
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// return layout.Flex{
// Axis: layout.Horizontal,
// Spacing: layout.SpaceSides,
// Alignment: layout.Middle, // 水平居中
// }.Layout(gtx,
// // 占位空间,让文本水平居中
// layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
// return layout.Dimensions{}
// }),
// // 实际文本
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// text := material.Body1(u.theme, fmt.Sprintf("%.1f%%", u.progress*100))
// if u.progress < 0.5 {
// text.Color = color.NRGBA{R: 60, G: 60, B: 60, A: 255}
// } else {
// text.Color = color.NRGBA{R: 255, G: 255, B: 255, A: 255}
// }
// return text.Layout(gtx)
// }),
// // 占位空间,让文本水平居中
// layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
// return layout.Dimensions{}
// }),
// )
// }),
// // 占位空间,让文本垂直居中
// layout.Flexed(50, func(gtx layout.Context) layout.Dimensions {
// return layout.Dimensions{}
// }),
// )
// })
//}
//
//// drawFileInfo 绘制文件信息
//func (u *UpdaterApp) drawFileInfo(gtx layout.Context) layout.Dimensions {
// return layout.Inset{
// Left: unit.Dp(20),
// Right: unit.Dp(20),
// Bottom: unit.Dp(10),
// }.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// return layout.Flex{
// Axis: layout.Horizontal,
// Spacing: layout.SpaceAround,
// Alignment: layout.Middle,
// }.Layout(gtx,
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// fileCount := fmt.Sprintf("文件: %d/%d", u.completedFiles, u.totalFiles)
// return material.Caption(u.theme, fileCount).Layout(gtx)
// }),
//
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// var sizeInfo string
// if u.totalSize > 0 {
// sizeInfo = fmt.Sprintf("大小: %.2f/%.2f MB",
// float64(u.downloaded)/(1024*1024),
// float64(u.totalSize)/(1024*1024))
// } else {
// sizeInfo = "大小: 计算中..."
// }
// return material.Caption(u.theme, sizeInfo).Layout(gtx)
// }),
//
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// speedInfo := fmt.Sprintf("速度: %.2f MB/s", u.currentSpeed)
// return material.Caption(u.theme, speedInfo).Layout(gtx)
// }),
// )
// })
//}
//
//// drawLogArea 绘制日志区域
//func (u *UpdaterApp) drawLogArea(gtx layout.Context) layout.Dimensions {
// if !u.showConsole {
// return layout.Dimensions{}
// }
//
// return layout.Inset{
// Left: unit.Dp(20),
// Right: unit.Dp(20),
// Top: unit.Dp(10),
// Bottom: unit.Dp(10),
// }.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// return material.List(u.theme, &u.scroll).Layout(gtx, len(u.logEntries), func(gtx layout.Context, index int) layout.Dimensions {
// return layout.Inset{
// Bottom: unit.Dp(4),
// }.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// logText := material.Body2(u.theme, u.logEntries[index])
// logText.Color = color.NRGBA{R: 100, G: 100, B: 100, A: 255}
//
// // 根据日志类型设置颜色
// logTextStr := u.logEntries[index]
// if strings.Contains(logTextStr, "[错误]") {
// logText.Color = color.NRGBA{R: 231, G: 76, B: 60, A: 255}
// } else if strings.Contains(logTextStr, "[警告]") {
// logText.Color = color.NRGBA{R: 241, G: 196, B: 15, A: 255}
// } else if strings.Contains(logTextStr, "[成功]") {
// logText.Color = color.NRGBA{R: 46, G: 204, B: 113, A: 255}
// } else if strings.Contains(logTextStr, "[信息]") {
// logText.Color = color.NRGBA{R: 52, G: 152, B: 219, A: 255}
// } else if strings.Contains(logTextStr, "[下载]") {
// logText.Color = color.NRGBA{R: 155, G: 89, B: 182, A: 255}
// }
//
// return logText.Layout(gtx)
// })
// })
// })
//}
//
//// drawFooter 绘制底部控制栏
//func (u *UpdaterApp) drawFooter(gtx layout.Context) layout.Dimensions {
// return layout.Inset{
// Top: unit.Dp(10),
// Bottom: unit.Dp(15),
// Left: unit.Dp(20),
// Right: unit.Dp(20),
// }.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// return layout.Flex{
// Axis: layout.Horizontal,
// Spacing: layout.SpaceBetween,
// Alignment: layout.Middle,
// }.Layout(gtx,
// //layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// // hint := material.Caption(u.theme, "提示: 按 Ctrl+C 切换日志显示")
// // hint.Color = color.NRGBA{R: 150, G: 150, B: 150, A: 255}
// // return hint.Layout(gtx)
// //}),
//
// layout.Rigid(func(gtx layout.Context) layout.Dimensions {
// var btnText string
// var btnColor color.NRGBA
//
// if u.isComplete {
// btnText = "启动核价软件"
// btnColor = color.NRGBA{R: 46, G: 204, B: 113, A: 255}
// } else if u.isPaused {
// btnText = "继续更新"
// btnColor = color.NRGBA{R: 46, G: 204, B: 113, A: 255}
// } else {
// btnText = "暂停更新"
// btnColor = color.NRGBA{R: 241, G: 196, B: 15, A: 255}
// }
//
// btn := material.Button(u.theme, &u.actionBtn, btnText)
// btn.CornerRadius = unit.Dp(8)
// btn.TextSize = unit.Sp(14)
// btn.Background = btnColor
// btn.Color = color.NRGBA{R: 255, G: 255, B: 255, A: 255}
// btn.Inset = layout.UniformInset(unit.Dp(12))
//
// return btn.Layout(gtx)
// }),
// )
// })
//}
//
//// ============================ 更新过程 ============================
//func (u *UpdaterApp) startUpdateProcess() {
// // 初始化
// u.updateStatus("正在初始化...")
// u.updateProgress(0.05)
//
// // 获取当前目录
// currentDir, err := os.Getwd()
// if err != nil {
// u.updateStatus(fmt.Sprintf("获取当前目录失败: %v", err))
// return
// }
// u.currentDir = currentDir
// u.yamlPath = filepath.Join(currentDir, "version.yaml")
//
// // 步骤1: 检查核价软件版本
// u.isChecking = true
// u.updateStatus("正在检查核价软件版本...")
// u.updateProgress(0.1)
// u.verifyPriceVersion, err = getVerifyPriceVersionJSON()
// if err != nil {
// u.updateStatus(fmt.Sprintf("读取核价软件版本失败: %v", err))
// u.isChecking = false
// return
// }
// u.isChecking = false
//
// // 步骤2: 读取本地配置
// u.updateStatus("正在读取本地配置...")
// u.updateProgress(0.15)
// data, err := ioutil.ReadFile(u.yamlPath)
// if err == nil {
// yaml.Unmarshal(data, &u.localConfig)
// } else {
// u.localConfig = VerifyPriceYAML{}
// }
//
// // 步骤3: 检查并下载主程序
// u.updateStatus("检查核价软件主程序...")
// u.updateProgress(0.2)
// err = u.checkAndDownloadMainApp()
// if err != nil {
// u.updateStatus(fmt.Sprintf("主程序处理失败: %v", err))
// }
//
// // 步骤4: 检查DLL组件版本
// u.isChecking = true
// u.updateStatus("正在检查DLL组件版本...")
// u.updateProgress(0.3)
// u.versionsJSON, err = getVersionsJSON()
// if err != nil {
// u.updateStatus(fmt.Sprintf("读取DLL版本失败: %v", err))
// u.isChecking = false
// return
// }
// u.isChecking = false
//
// // 步骤5: 下载所有DLL文件
// u.isDownloading = true
// u.updateStatus("开始更新DLL组件...")
// u.updateProgress(0.4)
// err = u.updateAllDLLs()
// if err != nil {
// u.updateStatus(fmt.Sprintf("DLL更新失败: %v", err))
// }
// u.isDownloading = false
//
// // 步骤6: 完成
// u.updateStatus("所有更新已完成!")
// u.updateProgress(1.0)
// u.isComplete = true
// u.isUpdating = false
//
// // 自动启动核价软件3秒后
// go func() {
// time.Sleep(3 * time.Second)
// if u.isComplete {
// u.startVerifyPriceApp()
// }
// }()
//}
//
//func (u *UpdaterApp) checkAndDownloadMainApp() error {
// exePath := filepath.Join(u.currentDir, "VerifyPriceApp.exe")
//
// if _, err := os.Stat(exePath); os.IsNotExist(err) {
// // 文件缺失,下载
// u.updateStatus("发现核价软件缺失,开始下载...")
// url := fmt.Sprintf("http://103.236.81.185:8099/exe/VerifyPriceApp_%s.exe",
// u.verifyPriceVersion.VerifyPriceLatestVersion)
// err = u.downloadWithProgress(url, exePath, "VerifyPriceApp.exe")
// if err != nil {
// return fmt.Errorf("下载失败: %v", err)
// }
// u.updateStatus("核价软件下载完成")
// u.localConfig.VerifyPriceLatestVersion = u.verifyPriceVersion.VerifyPriceLatestVersion
// writeYAML(u.yamlPath, u.localConfig)
// } else {
// // 检查版本
// if u.verifyPriceVersion.VerifyPriceLatestVersion != u.localConfig.VerifyPriceLatestVersion {
// u.updateStatus("发现新版本,开始更新...")
// url := fmt.Sprintf("http://103.236.81.185:8099/exe/VerifyPriceApp_%s.exe",
// u.verifyPriceVersion.VerifyPriceLatestVersion)
// err = u.downloadWithProgress(url, exePath, "VerifyPriceApp.exe")
// if err != nil {
// return fmt.Errorf("更新失败: %v", err)
// }
// u.updateStatus("核价软件更新完成")
// u.localConfig.VerifyPriceLatestVersion = u.verifyPriceVersion.VerifyPriceLatestVersion
// writeYAML(u.yamlPath, u.localConfig)
// } else {
// u.updateStatus("核价软件已是最新版本")
// }
// }
//
// u.completedFiles++
// u.updateFileCount(u.completedFiles)
//
// return nil
//}
//
//func (u *UpdaterApp) updateAllDLLs() error {
// dlls := []struct {
// name string
// version string
// checker func(string, string) (string, error)
// }{
// {"csv.dll", u.versionsJSON.CsvVersion, csvDllVersion},
// //{"kongfz.dll", u.versionsJSON.KongfzVersion, kongfzDllVersion},
// //{"logger.dll", u.versionsJSON.LoggerVersion, loggerDllVersion},
// //{"module-centerBook.dll", u.versionsJSON.ModuleCenterBookVersion, moduleCenterBookDllVersion},
// //{"module-login.dll", u.versionsJSON.ModuleLoginVersion, moduleLoginDllVersion},
// //{"module-erp.dll", u.versionsJSON.ModuleErpVersion, moduleErpDllVersion},
// //{"module-kongfz.dll", u.versionsJSON.ModuleKongfzVersion, moduleKongfzDllVersion},
// //{"module-taskPool.dll", u.versionsJSON.ModuleTaskPoolVersion, moduleTaskPoolDllVersion},
// //{"module-verifyPrice.dll", u.versionsJSON.ModuleVerifyPriceVersion, moduleVerifyPriceDllVersion},
// //{"picTool.dll", u.versionsJSON.PicToolVersion, picToolDllVersion},
// //{"proxy.dll", u.versionsJSON.ProxyVersion, proxyDllVersion},
// }
//
// for i, dll := range dlls {
// // 检查是否暂停
// for u.isPaused {
// time.Sleep(100 * time.Millisecond)
// }
//
// u.updateStatus(fmt.Sprintf("检查 %s...", dll.name))
// u.currentFile = dll.name
//
// // 检查当前版本
// currentVersion, err := dll.checker(u.currentDir, dll.version)
// if err != nil {
// u.updateStatus(fmt.Sprintf("检查 %s 失败: %v", dll.name, err))
// continue
// }
//
// // 如果需要更新
// if dll.version != currentVersion && currentVersion != "" {
// u.updateStatus(fmt.Sprintf("更新 %s...,版本:%s", dll.name, dll.version))
//
// // 创建带new-前缀的临时文件名
// newFileName := "new-" + dll.name
// dllDir := filepath.Join(u.currentDir, "dll")
// newDllPath := filepath.Join(dllDir, newFileName)
// finalDllPath := filepath.Join(dllDir, dll.name)
//
// //dllPath := filepath.Join(u.currentDir, "dll", dll.name)
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", newDllPath, dll.name, dll.version)
// //if err != nil {
// // u.updateStatus(fmt.Sprintf("更新 %s 失败: %v", dll.name, err))
// //} else {
// // u.updateStatus(fmt.Sprintf("%s 更新完成", dll.name))
// //}
//
// if err != nil {
// u.updateStatus(fmt.Sprintf("更新 %s 失败: %v", dll.name, err))
// } else {
// // 下载成功后删除原文件如果存在并将new-文件重命名为原文件名
// if _, err := os.Stat(finalDllPath); err == nil {
// os.Remove(finalDllPath)
// }
// if err := os.Rename(newDllPath, finalDllPath); err != nil {
// u.updateStatus(fmt.Sprintf("重命名 %s 失败: %v", dll.name, err))
// } else {
// u.updateStatus(fmt.Sprintf("%s 更新完成", dll.name))
// }
// }
// } else {
// u.updateStatus(fmt.Sprintf("%s 已是最新版本", dll.name))
// }
//
// // 更新进度
// u.completedFiles++
// progress := 0.4 + 0.5*(float32(i+1)/float32(len(dlls)))
// u.updateProgress(progress)
// u.updateFileCount(u.completedFiles)
//
// // 短暂暂停以避免UI卡顿
// time.Sleep(100 * time.Millisecond)
// }
//
// return nil
//}
//
//func (u *UpdaterApp) downloadWithProgress(url, filePath, fileName string) error {
// u.currentFile = fileName
// u.startTime = time.Now()
// u.downloaded = 0
//
// // 创建目录
// os.MkdirAll(filepath.Dir(filePath), 0755)
//
// // 发送请求
// client := &http.Client{Timeout: 30 * time.Minute}
// resp, err := client.Get(url)
// if err != nil {
// return err
// }
// defer resp.Body.Close()
//
// if resp.StatusCode != http.StatusOK {
// return fmt.Errorf("HTTP错误: %d", resp.StatusCode)
// }
//
// // 获取文件大小
// u.totalSize = resp.ContentLength
//
// // 创建临时文件
// tempPath := filePath + ".tmp"
// file, err := os.Create(tempPath)
// if err != nil {
// return err
// }
// defer file.Close()
//
// // 下载文件
// buf := make([]byte, 32*1024) // 32KB缓冲区
// for {
// // 检查是否暂停
// for u.isPaused {
// time.Sleep(100 * time.Millisecond)
// }
//
// n, err := resp.Body.Read(buf)
// if n > 0 {
// _, writeErr := file.Write(buf[:n])
// if writeErr != nil {
// return writeErr
// }
// u.downloaded += int64(n)
// u.updateFileProgress(fileName, u.downloaded, u.totalSize)
// }
//
// if err != nil {
// if err == io.EOF {
// break
// }
// return err
// }
// }
//
// // 关闭文件
// file.Close()
//
// // 重命名为最终文件
// if err := os.Rename(tempPath, filePath); err != nil {
// // 如果重命名失败,尝试复制
// if err := copyFile(tempPath, filePath); err != nil {
// return err
// }
// }
//
// // 清理临时文件
// os.Remove(tempPath)
//
// return nil
//}
//
//func (u *UpdaterApp) startVerifyPriceApp() {
// exePath := filepath.Join(u.currentDir, "VerifyPriceApp.exe")
//
// u.updateStatus("正在启动核价软件...")
//
// cmd := exec.Command(exePath)
// cmd.Dir = u.currentDir
//
// err := cmd.Start()
// if err != nil {
// u.updateStatus(fmt.Sprintf("启动失败: %v", err))
// u.updateStatus("请手动运行 VerifyPriceApp.exe")
// } else {
// u.updateStatus("核价软件已启动,即将退出...")
// time.Sleep(2 * time.Second)
// os.Exit(0)
// }
//}
//
//// ============================ 主函数 ============================
//func main() {
// //// 隐藏控制台窗口仅Windows
// //hideConsoleWindow()
//
// // 检查是否以控制台模式运行
// if len(os.Args) > 1 && os.Args[1] == "--console" {
// runConsoleMode()
// return
// }
//
// // GUI模式
// go func() {
// app := NewUpdaterApp()
// if err := app.Run(); err != nil {
// fmt.Fprintf(os.Stderr, "错误: %v\n", err)
// os.Exit(1)
// }
// }()
// app.Main()
//}
//
////// hideConsoleWindow 隐藏控制台窗口仅Windows有效
////func hideConsoleWindow() {
//// // 仅在Windows平台下生效
//// kernel32 := syscall.NewLazyDLL("kernel32.dll")
//// getConsoleWindow := kernel32.NewProc("GetConsoleWindow")
//// showWindow := syscall.NewLazyDLL("user32.dll").NewProc("ShowWindow")
////
//// if hwnd, _, _ := getConsoleWindow.Call(); hwnd != 0 {
//// showWindow.Call(hwnd, 0) // 0 = SW_HIDE
//// }
////}
//
//func runConsoleMode() {
// // 控制台模式原main.go的逻辑
// printBanner("核价软件更新器")
// printWarning("更新时请勿操作!!!")
//
// // 获取当前工作目录
// currentDir, err := os.Getwd()
// if err != nil {
// printError("获取当前目录失败: %v", err)
// return
// }
// printInfo("当前目录: %v", currentDir)
//
// // 获取选品中心中verify_price_version.json
// printInfo("正在检查核价软件版本...")
// verifyPriceVersionJSON, err := getVerifyPriceVersionJSON()
// if err != nil {
// printError("读取核价软件版本信息失败: %v", err)
// return
// }
//
// // 直接读取yaml文件
// yamlPath := filepath.Join(currentDir, "version.yaml")
// data, err := ioutil.ReadFile(yamlPath)
// if err != nil {
// printError("读取YAML配置文件失败: %v", err)
// }
//
// // 解析 YAML
// var config VerifyPriceYAML
// err = yaml.Unmarshal(data, &config)
// if err != nil {
// printError("解析 YAML 配置失败: %v", err)
// }
// printVersionInfo("当前核价软件版本号", config.VerifyPriceLatestVersion)
//
// // 检查并下载核价软件主程序
// printInfo("检查核价软件主程序...")
// if _, err := os.Stat(filepath.Join(currentDir, "VerifyPriceApp.exe")); os.IsNotExist(err) {
// printDownload("发现核价软件缺失,开始下载...")
// url := fmt.Sprintf("http://103.236.81.185:8099/exe/VerifyPriceApp_%s.exe", verifyPriceVersionJSON.VerifyPriceLatestVersion)
// err = downloadEXE(url, currentDir, "VerifyPriceApp.exe")
// if err != nil {
// if err.Error() == "The process cannot access the file because it is being used by another process." {
// printWarning("文件被占用,请重新启动与书同行.exe软件")
// } else {
// printError("下载核价软件失败: %v", err)
// }
// } else {
// printSuccess("核价软件下载完成")
// }
// //修改yaml文件
// config.VerifyPriceLatestVersion = verifyPriceVersionJSON.VerifyPriceLatestVersion
// err = writeYAML(yamlPath, config)
// if err != nil {
// printError("更新YAML配置文件失败: %v", err)
// }
// } else {
// if verifyPriceVersionJSON.VerifyPriceLatestVersion != config.VerifyPriceLatestVersion || config.VerifyPriceLatestVersion == "" {
// printDownload("发现新版本核价软件,开始更新...")
// url := fmt.Sprintf("http://103.236.81.185:8099/exe/VerifyPriceApp_%s.exe", verifyPriceVersionJSON.VerifyPriceLatestVersion)
// err = downloadEXE(url, currentDir, "VerifyPriceApp.exe")
// if err != nil {
// if err.Error() == "The process cannot access the file because it is being used by another process." {
// printWarning("文件被占用,请重新启动与书同行.exe软件")
// } else {
// printError("下载核价软件失败: %v", err)
// }
// } else {
// printSuccess("核价软件更新完成")
// }
// //修改yaml文件
// config.VerifyPriceLatestVersion = verifyPriceVersionJSON.VerifyPriceLatestVersion
// err = writeYAML(yamlPath, config)
// if err != nil {
// printError("更新YAML配置文件失败: %v", err)
// }
// } else {
// printSuccess("核价软件已是最新版本")
// }
// }
//
// // 获取ES2中version.json
// printInfo("正在检查DLL组件版本...")
// versionsJSON, err := getVersionsJSON()
// if err != nil {
// printError("读取DLL版本信息失败: %v", err)
// return
// }
//
// // 打印版本信息标题
// printBanner("版本信息")
//
// // 打印所有版本信息
// printVersionInfo("最新核价软件版本", verifyPriceVersionJSON.VerifyPriceLatestVersion)
// printVersionInfo("csv.dll版本号:", versionsJSON.CsvVersion)
// printVersionInfo("kongfz.dll版本号:", versionsJSON.KongfzVersion)
// printVersionInfo("logger.dll版本号:", versionsJSON.LoggerVersion)
// printVersionInfo("module-centerBook.dll版本号:", versionsJSON.ModuleCenterBookVersion)
// printVersionInfo("module-login.dll版本号:", versionsJSON.ModuleLoginVersion)
// printVersionInfo("module-erp.dll版本号:", versionsJSON.ModuleErpVersion)
// printVersionInfo("module-kongfz.dll版本号:", versionsJSON.ModuleKongfzVersion)
// printVersionInfo("module-taskPool.dll版本号:", versionsJSON.ModuleTaskPoolVersion)
// printVersionInfo("module-verifyPrice.dll版本号:", versionsJSON.ModuleVerifyPriceVersion)
// printVersionInfo("picTool.dll版本号:", versionsJSON.PicToolVersion)
// printVersionInfo("proxy.dll版本号:", versionsJSON.ProxyVersion)
//
// // 验证并更新DLL文件
// printBanner("组件检查与更新")
//
// // 验证csv.dll文件版本
// printInfo("检查csv.dll...")
// csvVersion, err := csvDllVersion(currentDir, versionsJSON.CsvVersion)
// if err != nil {
// printWarning("获取csv.dll版本失败: %v", err)
// }
// if versionsJSON.CsvVersion != csvVersion && csvVersion != "" {
// printDownload("csv.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "csv.dll"), "csv.dll", "")
// if err != nil {
// printError("下载csv.dll失败: %v", err)
// } else {
// printSuccess("csv.dll更新完成")
// }
// } else {
// printSuccess("csv.dll已是最新版本")
// }
//
// // 验证kongfz.dll文件版本
// printInfo("检查kongfz.dll...")
// kongfzVersion, err := kongfzDllVersion(currentDir, versionsJSON.KongfzVersion)
// if err != nil {
// printWarning("获取kongfz.dll版本失败: %v", err)
// }
// if versionsJSON.KongfzVersion != kongfzVersion && kongfzVersion != "" {
// printDownload("kongfz.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "kongfz.dll"), "kongfz.dll", "")
// if err != nil {
// printError("下载kongfz.dll失败: %v", err)
// } else {
// printSuccess("kongfz.dll更新完成")
// }
// } else {
// printSuccess("kongfz.dll已是最新版本")
// }
//
// // 验证logger.dll文件版本
// printInfo("检查logger.dll...")
// loggerVersion, err := loggerDllVersion(currentDir, versionsJSON.LoggerVersion)
// if err != nil {
// printWarning("获取logger.dll版本失败: %v", err)
// }
// if versionsJSON.LoggerVersion != loggerVersion && loggerVersion != "" {
// printDownload("logger.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "logger.dll"), "logger.dll", "")
// if err != nil {
// printError("下载logger.dll失败: %v", err)
// } else {
// printSuccess("logger.dll更新完成")
// }
// } else {
// printSuccess("logger.dll已是最新版本")
// }
//
// // 验证module-centerBook.dll文件版本
// printInfo("检查module-centerBook.dll...")
// moduleCenterBookVersion, err := moduleCenterBookDllVersion(currentDir, versionsJSON.ModuleCenterBookVersion)
// if err != nil {
// printWarning("获取module-centerBook.dll版本失败: %v", err)
// }
// if versionsJSON.ModuleCenterBookVersion != moduleCenterBookVersion && moduleCenterBookVersion != "" {
// printDownload("module-centerBook.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-centerBook.dll"), "module-centerBook.dll", "")
// if err != nil {
// printError("下载module-centerBook.dll失败: %v", err)
// } else {
// printSuccess("module-centerBook.dll更新完成")
// }
// } else {
// printSuccess("module-centerBook.dll已是最新版本")
// }
//
// // 验证module-login.dll文件版本
// printInfo("检查module-login.dll...")
// moduleLoginVersion, err := moduleLoginDllVersion(currentDir, versionsJSON.ModuleLoginVersion)
// if err != nil {
// printWarning("获取module-login.dll版本失败: %v", err)
// }
// if versionsJSON.ModuleLoginVersion != moduleLoginVersion && moduleLoginVersion != "" {
// printDownload("module-login.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-login.dll"), "module-login.dll", "")
// if err != nil {
// printError("下载module-login.dll失败: %v", err)
// } else {
// printSuccess("module-login.dll更新完成")
// }
// } else {
// printSuccess("module-login.dll已是最新版本")
// }
//
// // 验证module-erp.dll文件版本
// printInfo("检查module-erp.dll...")
// moduleErpVersion, err := moduleErpDllVersion(currentDir, versionsJSON.ModuleErpVersion)
// if err != nil {
// printWarning("获取module-erp.dll版本失败: %v", err)
// }
// if versionsJSON.ModuleErpVersion != moduleErpVersion && moduleErpVersion != "" {
// printDownload("module-erp.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-erp.dll"), "module-erp.dll", "")
// if err != nil {
// printError("下载module-erp.dll失败: %v", err)
// } else {
// printSuccess("module-erp.dll更新完成")
// }
// } else {
// printSuccess("module-erp.dll已是最新版本")
// }
//
// // 验证module-kongfz.dll文件版本
// printInfo("检查module-kongfz.dll...")
// moduleKongfzVersion, err := moduleKongfzDllVersion(currentDir, versionsJSON.ModuleKongfzVersion)
// if err != nil {
// printWarning("获取module-kongfz.dll版本失败: %v", err)
// }
// if versionsJSON.ModuleKongfzVersion != moduleKongfzVersion && moduleKongfzVersion != "" {
// printDownload("module-kongfz.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-kongfz.dll"), "module-kongfz.dll", "")
// if err != nil {
// printError("下载module-kongfz.dll失败: %v", err)
// } else {
// printSuccess("module-kongfz.dll更新完成")
// }
// } else {
// printSuccess("module-kongfz.dll已是最新版本")
// }
//
// // 验证module-taskPool.dll文件版本
// printInfo("检查module-taskPool.dll...")
// moduleTaskPoolVersion, err := moduleTaskPoolDllVersion(currentDir, versionsJSON.ModuleTaskPoolVersion)
// if err != nil {
// printWarning("获取module-taskPool.dll版本失败: %v", err)
// }
// if versionsJSON.ModuleTaskPoolVersion != moduleTaskPoolVersion && moduleTaskPoolVersion != "" {
// printDownload("module-taskPool.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-taskPool.dll"), "module-taskPool.dll", "")
// if err != nil {
// printError("下载module-taskPool.dll失败: %v", err)
// } else {
// printSuccess("module-taskPool.dll更新完成")
// }
// } else {
// printSuccess("module-taskPool.dll已是最新版本")
// }
//
// // 验证module-verifyPrice.dll文件版本
// printInfo("检查module-verifyPrice.dll...")
// moduleVerifyPriceVersion, err := moduleVerifyPriceDllVersion(currentDir, versionsJSON.ModuleVerifyPriceVersion)
// if err != nil {
// printWarning("获取module-verifyPrice.dll版本失败: %v", err)
// }
// if versionsJSON.ModuleVerifyPriceVersion != moduleVerifyPriceVersion && moduleVerifyPriceVersion != "" {
// printDownload("module-verifyPrice.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-verifyPrice.dll"), "module-verifyPrice.dll", "")
// if err != nil {
// printError("下载module-verifyPrice.dll失败: %v", err)
// } else {
// printSuccess("module-verifyPrice.dll更新完成")
// }
// } else {
// printSuccess("module-verifyPrice.dll已是最新版本")
// }
//
// // 验证picTool.dll文件版本
// printInfo("检查picTool.dll...")
// picToolVersion, err := picToolDllVersion(currentDir, versionsJSON.PicToolVersion)
// if err != nil {
// printWarning("获取picTool.dll版本失败: %v", err)
// }
// if versionsJSON.PicToolVersion != picToolVersion && picToolVersion != "" {
// printDownload("picTool.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "picTool.dll"), "picTool.dll", "")
// if err != nil {
// printError("下载picTool.dll失败: %v", err)
// } else {
// printSuccess("picTool.dll更新完成")
// }
// } else {
// printSuccess("picTool.dll已是最新版本")
// }
//
// // 验证proxy.dll文件版本
// printInfo("检查proxy.dll...")
// proxyVersion, err := proxyDllVersion(currentDir, versionsJSON.ProxyVersion)
// if err != nil {
// printWarning("获取proxy.dll版本失败: %v", err)
// }
// if versionsJSON.ProxyVersion != proxyVersion && proxyVersion != "" {
// printDownload("proxy.dll需要更新")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "proxy.dll"), "proxy.dll", "")
// if err != nil {
// printError("下载proxy.dll失败: %v", err)
// } else {
// printSuccess("proxy.dll更新完成")
// }
// } else {
// printSuccess("proxy.dll已是最新版本")
// }
//
// printWarning("更新完成!按回车键打开核价软件...")
//
// // 等待用户输入
// bufio.NewReader(os.Stdin).ReadBytes('\n')
//
// // 启动核价软件
// verifyPriceAppPath := filepath.Join(currentDir, "VerifyPriceApp.exe")
// if _, err := os.Stat(verifyPriceAppPath); os.IsNotExist(err) {
// printError("核价软件主程序不存在: %s", verifyPriceAppPath)
// } else {
// cmd := exec.Command(verifyPriceAppPath)
// cmd.Dir = currentDir
// err := cmd.Start()
// if err != nil {
// printError("启动核价软件失败: %v", err)
// } else {
// printSuccess("核价软件已启动 (PID: %d)", cmd.Process.Pid)
// }
// }
//
// printBanner("程序执行完毕")
//}
//
//// ============================ 原main.go的函数 ============================
//func writeYAML(filePath string, config VerifyPriceYAML) error {
// yamlData, err := yaml.Marshal(config)
// if err != nil {
// return fmt.Errorf("序列化YAML失败: %v", err)
// }
//
// backupFilePath := filePath + ".bak"
// err = backupFile(filePath, backupFilePath)
// if err != nil {
// printDebug("创建备份文件失败: %v", err)
// }
//
// err = ioutil.WriteFile(filePath, yamlData, 0755)
// if err != nil {
// return fmt.Errorf("写入文件失败: %v", err)
// }
//
// return nil
//}
//
//func backupFile(originalPath, backupPath string) error {
// data, err := ioutil.ReadFile(originalPath)
// if err != nil {
// return err
// }
// return ioutil.WriteFile(backupPath, data, 0755)
//}
//
//// 下载exe文件
//func downloadEXE(url, folderPath, filename string) error {
// if err := os.MkdirAll(folderPath, 0755); err != nil {
// return fmt.Errorf("创建文件夹失败: %v", err)
// }
//
// filePath := filepath.Join(folderPath, filename)
// printDebug("下载到: %s", filePath)
//
// resp, err := http.Get(url)
// if err != nil {
// return fmt.Errorf("请求失败: %v", err)
// }
// defer resp.Body.Close()
//
// if resp.StatusCode != http.StatusOK {
// return fmt.Errorf("下载失败,状态码: %d", resp.StatusCode)
// }
//
// file, err := os.Create(filePath)
// if err != nil {
// return fmt.Errorf("创建文件失败: %v", err)
// }
// defer file.Close()
//
// _, err = io.Copy(file, resp.Body)
// if err != nil {
// return fmt.Errorf("写入文件失败: %v", err)
// }
//
// return nil
//}
//
//func getVerifyPriceVersionJSON() (*VersionInfo, error) {
// url := "http://103.236.81.185:8099/verify_price_version.json"
// client := &http.Client{Timeout: 30 * time.Second}
//
// resp, err := client.Get(url)
// if err != nil {
// return nil, fmt.Errorf("请求失败: %v", err)
// }
// defer resp.Body.Close()
//
// if resp.StatusCode != http.StatusOK {
// return nil, fmt.Errorf("HTTP请求失败状态码: %d", resp.StatusCode)
// }
//
// body, err := io.ReadAll(resp.Body)
// if err != nil {
// return nil, fmt.Errorf("读取响应失败: %v", err)
// }
//
// var versionInfo VersionInfo
// err = json.Unmarshal(body, &versionInfo)
// if err != nil {
// return nil, fmt.Errorf("解析JSON失败: %v", err)
// }
// return &versionInfo, nil
//}
//
//func getVersionsJSON() (*VersionConfig, error) {
// url := "http://36.212.20.113:53300/versionNew.json"
// client := &http.Client{Timeout: 30 * time.Second}
//
// resp, err := client.Get(url)
// if err != nil {
// return nil, fmt.Errorf("请求失败: %v", err)
// }
// defer resp.Body.Close()
//
// if resp.StatusCode != http.StatusOK {
// return nil, fmt.Errorf("HTTP请求失败状态码: %d", resp.StatusCode)
// }
//
// body, err := io.ReadAll(resp.Body)
// if err != nil {
// return nil, fmt.Errorf("读取响应失败: %v", err)
// }
//
// var versionConfig VersionConfig
// err = json.Unmarshal(body, &versionConfig)
// if err != nil {
// return nil, fmt.Errorf("解析JSON失败: %v", err)
// }
// return &versionConfig, nil
//}
//
//func cStr(ptr uintptr) string {
// if ptr == 0 {
// return ""
// }
// var b []byte
// for {
// c := *(*byte)(unsafe.Pointer(ptr))
// if c == 0 {
// break
// }
// b = append(b, c)
// ptr++
// }
// return string(b)
//}
//
//func csvDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "csv.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("csv.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "csv.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 csv.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载csv.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找csv.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用csv.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func kongfzDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "kongfz.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("kongfz.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "kongfz.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 kongfz.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载kongfz.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找kongfz.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用kongfz.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func loggerDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "logger.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("logger.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "logger.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 logger.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载logger.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找logger.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用logger.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func moduleCenterBookDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "module-centerBook.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("module-centerBook.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-centerBook.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 module-centerBook.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载module-centerBook.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找module-centerBook.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用module-centerBook.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func moduleLoginDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "module-login.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("module-login.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-login.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 module-login.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载module-login.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找module-login.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用module-login.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func moduleErpDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "module-erp.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("module-erp.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-erp.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 module-erp.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载module-erp.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找module-erp.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用module-erp.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func moduleKongfzDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "module-kongfz.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("module-kongfz.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-kongfz.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 module-kongfz.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载module-kongfz.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找module-kongfz.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用module-kongfz.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func moduleTaskPoolDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "module-taskPool.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("module-taskPool.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-taskPool.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 module-taskPool.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载module-taskPool.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找module-taskPool.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用module-taskPool.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func moduleVerifyPriceDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "module-verifyPrice.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("module-verifyPrice.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-verifyPrice.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 module-verifyPrice.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载module-verifyPrice.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找module-verifyPrice.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用module-verifyPrice.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func picToolDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "picTool.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("picTool.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "picTool.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 picTool.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载picTool.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找picTool.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用picTool.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func proxyDllVersion(currentDir string, version string) (string, error) {
// dllPath := filepath.Join(currentDir, "dll", "proxy.dll")
//
// _, err := os.Stat(dllPath)
// if err != nil {
// if os.IsNotExist(err) {
// printDownload("proxy.dll文件缺失开始下载...")
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "proxy.dll", version)
// if err != nil {
// return "", fmt.Errorf("下载 proxy.dll 文件失败: %v", err)
// }
// return "", nil
// }
// }
//
// dll, err := syscall.LoadDLL(dllPath)
// if err != nil {
// return "", fmt.Errorf("加载proxy.dll文件失败: %v", err)
// }
//
// proc, err := dll.FindProc("GetVersion")
// if err != nil {
// return "", fmt.Errorf("查找proxy.dll GetVersion 函数失败: %v", err)
// }
//
// ret, _, err := proc.Call()
// if err != nil && err.Error() != "The operation completed successfully." {
// return "", fmt.Errorf("调用proxy.dll GetVersion 函数失败: %v", err)
// }
// str := cStr(ret)
//
// if proc, err = dll.FindProc("FreeCString"); err == nil {
// defer proc.Call(ret)
// }
// return str, nil
//}
//
//func downloadDLL(url, outputPath, filename, version string) error {
// // 1. 确保目录存在
// dir := filepath.Dir(outputPath)
// if err := os.MkdirAll(dir, 0755); err != nil {
// return fmt.Errorf("创建目录失败: %v", err)
// }
//
// // 2. 创建临时文件路径
// tempPath := outputPath + ".tmp"
//
// // 3. 清理可能存在的旧临时文件
// if _, err := os.Stat(tempPath); err == nil {
// os.Remove(tempPath)
// }
//
// // 4. 检查目标文件是否存在
// if _, err := os.Stat(outputPath); err == nil {
// backupPath := outputPath + ".bak"
// if err := os.Rename(outputPath, backupPath); err != nil {
// // 重命名失败,尝试直接删除
// for i := 0; i < 3; i++ {
// if err := os.Remove(outputPath); err == nil {
// break
// }
// if i == 2 {
// if strings.Contains(err.Error(), "Access is denied") {
// return fmt.Errorf("文件被其他程序占用,请关闭可能使用此文件的程序后再试: %s", outputPath)
// }
// return fmt.Errorf("无法删除已存在的文件: %v", err)
// }
// time.Sleep(1 * time.Second)
// }
// } else {
// // 异步清理备份文件
// go func() {
// time.Sleep(30 * time.Second)
// if _, err := os.Stat(backupPath); err == nil {
// os.Remove(backupPath)
// }
// }()
// }
// }
//
// // 5. 打印下载信息
// if version == "" {
// printDownload("正在下载: %s (版本: 最新版本)", filename)
// } else {
// printDownload("正在下载: %s (版本: %s)", filename, version)
// }
//
// // 6. 首先尝试获取文件大小信息HEAD请求
// headClient := &http.Client{
// Timeout: 30 * time.Second,
// }
//
// headReq, err := http.NewRequest("HEAD", url, nil)
// if err != nil {
// printError("创建HEAD请求失败使用默认超时设置: %v", err)
// } else {
// // 添加查询参数
// q := headReq.URL.Query()
// q.Add("filename", filename)
// if version != "" {
// q.Add("version", version)
// }
// headReq.URL.RawQuery = q.Encode()
// headReq.Header.Set("User-Agent", "DLL-Downloader/1.0")
//
// resp, err := headClient.Do(headReq)
// if err == nil && resp.StatusCode == http.StatusOK {
// if contentLength := resp.ContentLength; contentLength > 0 {
// fmt.Printf(ColorGray+"获取到文件大小: %.2f MB\n"+ColorReset,
// float64(contentLength)/1024/1024)
// }
// resp.Body.Close()
// }
// }
//
// // 7. 创建长时间下载的HTTP客户端
// transport := &http.Transport{
// Proxy: http.ProxyFromEnvironment,
// DialContext: (&net.Dialer{
// Timeout: 30 * time.Second,
// KeepAlive: 30 * time.Second,
// DualStack: true,
// }).DialContext,
// ForceAttemptHTTP2: true,
// MaxIdleConns: 100,
// MaxIdleConnsPerHost: 10,
// IdleConnTimeout: 90 * time.Second,
// TLSHandshakeTimeout: 15 * time.Second,
// ExpectContinueTimeout: 5 * time.Second,
// ResponseHeaderTimeout: 30 * time.Second,
// ReadBufferSize: 128 * 1024, // 128KB
// WriteBufferSize: 128 * 1024,
// }
//
// client := &http.Client{
// Transport: transport,
// }
//
// // 8. 创建下载请求
// ctx, cancel := context.WithTimeout(context.Background(), 3*time.Hour)
// defer cancel()
//
// req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
// if err != nil {
// return fmt.Errorf("创建请求失败: %v", err)
// }
//
// // 添加查询参数
// q := req.URL.Query()
// q.Add("filename", filename)
// if version != "" {
// q.Add("version", version)
// }
// req.URL.RawQuery = q.Encode()
//
// // 添加请求头
// req.Header.Set("User-Agent", "DLL-Downloader/1.0")
// req.Header.Set("Accept", "*/*")
// req.Header.Set("Accept-Encoding", "gzip, deflate")
// req.Header.Set("Connection", "keep-alive")
//
// // 9. 发送请求
// resp, err := client.Do(req)
// if err != nil {
// if strings.Contains(err.Error(), "context deadline exceeded") {
// return fmt.Errorf("连接超时,请检查网络连接: %v", err)
// }
// return fmt.Errorf("请求失败: %v", err)
// }
// defer resp.Body.Close()
//
// if resp.StatusCode != http.StatusOK {
// body, _ := io.ReadAll(io.LimitReader(resp.Body, 1024))
// return fmt.Errorf("服务器返回错误: %d - %s", resp.StatusCode, string(body))
// }
//
// // 10. 获取文件大小
// totalSize := resp.ContentLength
// if totalSize > 0 {
// fmt.Printf(ColorGray+"文件大小: %.2f MB\n"+ColorReset, float64(totalSize)/1024/1024)
//
// // 根据文件大小提供预估时间
// minSpeed := 50.0 * 1024
// estimatedTime := time.Duration(float64(totalSize)/minSpeed) * time.Second
// if estimatedTime > 30*time.Second {
// fmt.Printf(ColorGray+"预估下载时间: %v (基于50KB/s最低速度)\n"+ColorReset,
// estimatedTime.Round(time.Second))
// }
// } else {
// fmt.Println(ColorGray + "文件大小: 未知" + ColorReset)
// }
//
// // 11. 创建临时文件
// out, err := os.OpenFile(tempPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
// if err != nil {
// return fmt.Errorf("创建临时文件失败: %v", err)
// }
// defer out.Close()
//
// // 12. 确保下载失败时清理临时文件
// downloadSuccess := false
// defer func() {
// if !downloadSuccess {
// os.Remove(tempPath)
// }
// }()
//
// // 13. 活动检测机制
// activityCh := make(chan time.Time, 100)
// var lastActivity time.Time
// lastActivity = time.Now()
//
// // 创建活动检测的reader
// activityReader := &activityReader{
// reader: resp.Body,
// activityCh: activityCh,
// activityPtr: &lastActivity,
// }
//
// // 启动活动检测goroutine
// activityCtx, activityCancel := context.WithCancel(context.Background())
// defer activityCancel()
//
// go func() {
// ticker := time.NewTicker(30 * time.Second)
// defer ticker.Stop()
//
// for {
// select {
// case <-activityCtx.Done():
// return
// case activityTime := <-activityCh:
// lastActivity = activityTime
// case <-ticker.C:
// if time.Since(lastActivity) > 60*time.Second {
// printError("下载活动超时60秒内没有收到数据")
// cancel()
// return
// }
// }
// }
// }()
//
// // 14. 下载进度显示
// startTime := time.Now()
// var downloaded int64 = 0
// var lastUpdate time.Time
// lastUpdate = time.Now()
//
// // 15. 创建缓冲区
// buf := make([]byte, 128*1024)
//
// // 显示初始进度
// fmt.Print(ColorCyan + "下载进度: 0.00% (0.00/0.00 MB)" + ColorReset)
//
// for {
// select {
// case <-ctx.Done():
// return fmt.Errorf("下载被取消: %v", ctx.Err())
// default:
// }
//
// n, err := activityReader.Read(buf)
// if n > 0 {
// if _, writeErr := out.Write(buf[:n]); writeErr != nil {
// return fmt.Errorf("写入文件失败: %v", writeErr)
// }
//
// downloaded += int64(n)
//
// if time.Since(lastUpdate) > 1*time.Second || err != nil {
// if totalSize > 0 {
// percent := float64(downloaded) / float64(totalSize) * 100
// elapsed := time.Since(startTime).Seconds()
// speed := 0.0
// if elapsed > 0 {
// speed = float64(downloaded) / elapsed / 1024 / 1024
// }
//
// remaining := time.Duration(0)
// if speed > 0 && downloaded > 0 {
// remainingSecs := float64(totalSize-downloaded) / (float64(downloaded) / elapsed)
// remaining = time.Duration(remainingSecs) * time.Second
// }
//
// fmt.Printf("\r\033[K"+ColorCyan+"下载进度: %.2f%% (%.2f/%.2f MB) 速度: %.2f MB/s 剩余: %v"+ColorReset,
// percent,
// float64(downloaded)/1024/1024,
// float64(totalSize)/1024/1024,
// speed,
// remaining.Round(time.Second))
// } else {
// elapsed := time.Since(startTime).Seconds()
// speed := 0.0
// if elapsed > 0 {
// speed = float64(downloaded) / elapsed / 1024 / 1024
// }
// fmt.Printf("\r\033[K"+ColorCyan+"已下载: %.2f MB 速度: %.2f MB/s"+ColorReset,
// float64(downloaded)/1024/1024,
// speed)
// }
// lastUpdate = time.Now()
// }
// }
//
// if err != nil {
// if err == io.EOF {
// break
// }
// if ctx.Err() != nil {
// return fmt.Errorf("下载中断: %v", ctx.Err())
// }
// return fmt.Errorf("读取数据失败: %v", err)
// }
// }
//
// // 16. 下载完成,显示最终进度
// if totalSize > 0 && downloaded < totalSize {
// downloaded = totalSize
// }
//
// if totalSize > 0 {
// fmt.Printf("\r\033[K"+ColorGreen+"下载完成: 100.00%% (%.2f/%.2f MB)\n"+ColorReset,
// float64(downloaded)/1024/1024,
// float64(totalSize)/1024/1024)
// } else {
// fmt.Printf("\r\033[K"+ColorGreen+"下载完成: %.2f MB\n"+ColorReset,
// float64(downloaded)/1024/1024)
// }
//
// activityCancel()
//
// // 17. 验证下载的文件大小
// if totalSize > 0 {
// fi, err := os.Stat(tempPath)
// if err != nil {
// return fmt.Errorf("无法验证下载文件: %v", err)
// }
// if fi.Size() != totalSize {
// return fmt.Errorf("文件大小不匹配: 期望 %d 字节, 实际 %d 字节", totalSize, fi.Size())
// }
// }
//
// // 18. 将临时文件重命名为目标文件
// maxRetries := 5
// for i := 0; i < maxRetries; i++ {
// if err := os.Rename(tempPath, outputPath); err == nil {
// downloadSuccess = true
// break
// }
//
// if i == maxRetries-1 {
// if err := copyFile(tempPath, outputPath); err != nil {
// return fmt.Errorf("保存文件失败: %v", err)
// }
// downloadSuccess = true
// } else {
// time.Sleep(500 * time.Millisecond * time.Duration(i+1))
// }
// }
//
// // 19. 验证最终文件
// fi, err := os.Stat(outputPath)
// if err != nil {
// return fmt.Errorf("最终文件验证失败: %v", err)
// }
//
// elapsed := time.Since(startTime)
// speed := float64(fi.Size()) / elapsed.Seconds() / 1024 / 1024
// printSuccess("下载完成: %s (大小: %.2f MB, 耗时: %v, 平均速度: %.2f MB/s)",
// filepath.Base(outputPath),
// float64(fi.Size())/1024/1024,
// elapsed.Round(time.Second),
// speed)
//
// return nil
//}
//
//type activityReader struct {
// reader io.Reader
// activityCh chan<- time.Time
// activityPtr *time.Time
//}
//
//func (r *activityReader) Read(p []byte) (n int, err error) {
// n, err = r.reader.Read(p)
// if n > 0 {
// now := time.Now()
// r.activityCh <- now
// if r.activityPtr != nil {
// *r.activityPtr = now
// }
// }
// return
//}
//
//func copyFile(src, dst string) error {
// source, err := os.Open(src)
// if err != nil {
// return err
// }
// defer source.Close()
//
// destination, err := os.Create(dst)
// if err != nil {
// return err
// }
// defer destination.Close()
//
// _, err = io.Copy(destination, source)
// return err
//}