GUI热更配置

This commit is contained in:
wh_zcy 2022-09-28 22:48:48 +08:00
parent 149932a66c
commit f3c3c517bf
9 changed files with 488 additions and 68 deletions

View File

@ -4,5 +4,5 @@ Website = "http://legu.cc"
Icon = "app.png" Icon = "app.png"
Name = "RobotGUI" Name = "RobotGUI"
ID = "cc.legu.app" ID = "cc.legu.app"
Version = "1.0.9" Version = "1.0.11"
Build = 10 Build = 14

View File

@ -92,7 +92,7 @@ const (
TOOLBAR_GEN = "Luban" TOOLBAR_GEN = "Luban"
TOOLBAR_SEC = "密码器" TOOLBAR_SEC = "密码器"
TOOLBAR_WEL = "欢迎" TOOLBAR_WEL = "欢迎"
TOOLBAR_TERM = "终端" TOOLBAR_TERM = "同步配置"
TOOLBAR_PB = "protobuf" TOOLBAR_PB = "protobuf"
//monitor //monitor

View File

@ -5,5 +5,12 @@ type SSHModel struct {
Port string Port string
UserName string UserName string
Password string Password string
CmdLast string LocalDir string
RemoteDir string
/////
ServerIp string
WorkDir string
LubanCli string
DataDir string
JsonDir string
} }

View File

@ -1,9 +1,9 @@
upgradeUrl: http://10.0.0.9:8080/ upgradeUrl: http://10.0.0.9:8080/
services: services:
- service: - service:
sid: 1 sid: "df01"
name: 外网 name: 外网
url: ws://119.3.89.14:7891/gateway url: ws://119.3.89.14:9891/gateway
- service: - service:
sid: "dfz" sid: "dfz"
name: 赵长远 name: 赵长远

View File

@ -7,16 +7,28 @@ import (
"net" "net"
"os" "os"
"path" "path"
"path/filepath"
"runtime"
"sync"
"time" "time"
"github.com/pkg/errors"
"github.com/pkg/sftp" "github.com/pkg/sftp"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
var sftpCli *sftp.Client
var sftpOne sync.Once
type SSHService struct { type SSHService struct {
Client *ssh.Client Client *ssh.Client
LastResult string LastResult string //执行结果
}
func NewSSHService() *SSHService {
ss := &SSHService{}
return ss
} }
func (ss *SSHService) Connect(user, password, host, key string, port int, cipherList []string) error { func (ss *SSHService) Connect(user, password, host, key string, port int, cipherList []string) error {
@ -79,9 +91,36 @@ func (ss *SSHService) Connect(user, password, host, key string, port int, cipher
if ss.Client, err = ssh.Dial("tcp", addr, clientConfig); err != nil { if ss.Client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
return err return err
} }
sftpCli, err = sftp.NewClient(ss.Client)
return nil return nil
} }
func (ss *SSHService) getSftp() (*sftp.Client, error) {
if ss.Client == nil {
return nil, errors.New("ssh client is nil")
}
sftpOne.Do(func() {
if sftpCli, err = sftp.NewClient(ss.Client); err != nil {
return
}
})
return sftpCli, nil
}
func (ss *SSHService) Close() {
if ss.Client != nil {
if err := ss.Client.Close(); err != nil {
logrus.WithField("err", err).Error("close ssh err")
}
}
// if sftpCli != nil {
// if err := sftpCli.Close(); err != nil {
// logrus.WithField("err", err).Error("close sftp err")
// }
// }
}
func (ss *SSHService) RunShell(shell string) { func (ss *SSHService) RunShell(shell string) {
var ( var (
session *ssh.Session session *ssh.Session
@ -109,7 +148,6 @@ func (ss *SSHService) RunShell(shell string) {
} else { } else {
ss.LastResult = string(output) ss.LastResult = string(output)
} }
} }
//单个copy //单个copy
@ -117,11 +155,21 @@ func (ss *SSHService) ScpCopy(localFilePath, remoteDir string) error {
var ( var (
err error err error
) )
sftpClient, err := sftp.NewClient(ss.Client)
fi, err := os.Stat(localFilePath)
if err != nil {
return err
}
if fi.IsDir() {
return errors.New(localFilePath + " is not file")
}
sftpCli, err = ss.getSftp()
if err != nil { if err != nil {
return fmt.Errorf("new sftp client error: %w", err) return fmt.Errorf("new sftp client error: %w", err)
} }
defer sftpClient.Close()
// defer sftpCli.Close()
srcFile, err := os.Open(localFilePath) srcFile, err := os.Open(localFilePath)
if err != nil { if err != nil {
@ -130,8 +178,15 @@ func (ss *SSHService) ScpCopy(localFilePath, remoteDir string) error {
} }
defer srcFile.Close() defer srcFile.Close()
var remoteFileName = path.Base(localFilePath) var remoteFileName string
dstFile, err := sftpClient.Create(path.Join(remoteDir, remoteFileName)) sysTyep := runtime.GOOS
if sysTyep == "windows" {
remoteFileName = path.Base(filepath.ToSlash(localFilePath))
} else {
remoteFileName = path.Base(localFilePath)
}
dstFile, err := sftpCli.Create(path.Join(remoteDir, remoteFileName))
if err != nil { if err != nil {
log.Println("scpCopy:", err) log.Println("scpCopy:", err)
return err return err
@ -143,10 +198,48 @@ func (ss *SSHService) ScpCopy(localFilePath, remoteDir string) error {
return fmt.Errorf("read local file failed: %w", err) return fmt.Errorf("read local file failed: %w", err)
} }
dstFile.Write(fileByte) if _, err := dstFile.Write(fileByte); err != nil {
return err
}
return nil return nil
} }
//批量copy
func (ss *SSHService) BatchScpCoy(cfs []CopyFiles, remoteDir string) error {
sftpCli, err = ss.getSftp()
if err != nil {
return fmt.Errorf("new sftp client error: %w", err)
}
for _, f := range cfs {
srcFile, err := os.Open(path.Join(f.Dir, f.FileName))
if err != nil {
return err
}
defer srcFile.Close()
dstFile, err := sftpCli.Create(path.Join(remoteDir, f.FileName))
if err != nil {
logrus.Error("scpCopy:", err)
return err
}
defer dstFile.Close()
fileByte, err := ioutil.ReadAll(srcFile)
if nil != err {
return fmt.Errorf("read local file failed: %w", err)
}
if _, err := dstFile.Write(fileByte); err != nil {
return err
}
}
return nil
}
//Deprecated Scp
func (ss *SSHService) Scp(targetDir, srcFileName string) (int, error) { func (ss *SSHService) Scp(targetDir, srcFileName string) (int, error) {
sftpClient, err := sftp.NewClient(ss.Client) sftpClient, err := sftp.NewClient(ss.Client)
if err != nil { if err != nil {
@ -187,3 +280,8 @@ func (ss *SSHService) Scp(targetDir, srcFileName string) (int, error) {
} }
return n, nil return n, nil
} }
type CopyFiles struct {
Dir string
FileName string
}

View File

@ -2,6 +2,8 @@ package service
import ( import (
"fmt" "fmt"
"path"
"path/filepath"
"testing" "testing"
) )
@ -36,9 +38,21 @@ func TestScp(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
path := filepath.Join(`E:/svn/dreamworks/client/dreamworks/ExcelFile/JSON/`, "game_vikingchallenge.json")
if err := ssh.ScpCopy(`E:/svn/dreamworks/client/dreamworks/ExcelFile/testscp.txt`, "/opt"); err != nil { fmt.Println(path)
if err := ssh.ScpCopy(path, "/opt/json/"); err != nil {
fmt.Println(err) fmt.Println(err)
} }
}
func TestPath(t *testing.T) {
Dir := `E:/svn/dreamworks/client/dreamworks/ExcelFile/JSON/`
mypath := filepath.Join(Dir, "a.json")
s := filepath.ToSlash(mypath)
fmt.Println(path.Base(s))
}
func TestMath(t *testing.T) {
a := float64(10) / float64(3)
fmt.Println(a)
} }

View File

@ -193,7 +193,6 @@ func (this *appGen) LazyInit(obs observer.Observer) error {
this.goList.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil)) this.goList.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
} }
this.goList.changeFileCount() this.goList.changeFileCount()
// this.goList.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(this.goList.selItemIds), this.goList.fileTotal))
this.goList.itemList.Refresh() this.goList.itemList.Refresh()
} }
@ -208,7 +207,8 @@ func (this *appGen) LazyInit(obs observer.Observer) error {
this.goList.selItemIds = append(this.goList.selItemIds, v.Text) this.goList.selItemIds = append(this.goList.selItemIds, v.Text)
this.goList.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil)) this.goList.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
} }
this.goList.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(this.goList.selItemIds), this.goList.fileTotal)) this.goList.changeFileCount()
// this.goList.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(this.goList.selItemIds), this.goList.fileTotal))
this.goList.itemList.Refresh() this.goList.itemList.Refresh()
} }
@ -257,7 +257,6 @@ func (this *appGen) LazyInit(obs observer.Observer) error {
list.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil)) list.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
} }
this.jsonList.changeFileCount() this.jsonList.changeFileCount()
// list.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(list.selItemIds), list.fileTotal))
list.itemList.Refresh() list.itemList.Refresh()
} }
@ -407,6 +406,12 @@ func NewFileList() *fileList {
} }
} }
func (f *fileList) reset() {
f.fileTotal = 0
f.selItemIds = []string{}
f.cachedList = NewList("")
}
func (f *fileList) createList() *widget.List { func (f *fileList) createList() *widget.List {
f.itemList = widget.NewList( f.itemList = widget.NewList(
func() int { func() int {
@ -464,6 +469,24 @@ func (f *fileList) deleteItem(name string) {
} }
} }
func (f *fileList) loadItem(dirPath string) {
f.reset()
files, err := ioutil.ReadDir(dirPath)
if err != nil {
logrus.Error(err)
return
}
for _, file := range files {
if !file.IsDir() {
f.addItem(file.Name())
f.selItemIds = append(f.selItemIds, file.Name())
f.fileTotal++
logrus.Debugf("%v", file.Name())
}
}
}
// 改变列表项目 // 改变列表项目
func (f *fileList) changeItem(tmpDir, projectDir string) { func (f *fileList) changeItem(tmpDir, projectDir string) {
f.fileTotal = 0 f.fileTotal = 0
@ -514,6 +537,11 @@ func (f *fileList) changeFileCount() {
f.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(f.selItemIds), f.fileTotal)) f.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(f.selItemIds), f.fileTotal))
} }
type CopyFiles struct {
Dir string
FileName string
}
func (a *appGen) GetAppName() string { func (a *appGen) GetAppName() string {
return common.TOOLBAR_GEN return common.TOOLBAR_GEN
} }

View File

@ -2,12 +2,21 @@ package ui
import ( import (
"errors" "errors"
"fmt"
"go_dreamfactory/cmd/v2/lib/common" "go_dreamfactory/cmd/v2/lib/common"
"go_dreamfactory/cmd/v2/model" "go_dreamfactory/cmd/v2/model"
"go_dreamfactory/cmd/v2/service" "go_dreamfactory/cmd/v2/service"
"go_dreamfactory/cmd/v2/service/observer" "go_dreamfactory/cmd/v2/service/observer"
"image/color"
"math/rand"
"os/exec"
"path/filepath"
"runtime"
"sync"
"time"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/layout"
@ -22,13 +31,26 @@ type appTerm struct {
obs observer.Observer obs observer.Observer
sshService *service.SSHService sshService *service.SSHService
jsonList *fileList //json列表
cProgress *widget.ProgressBarInfinite //连接进度条进度条
upProgress *widget.ProgressBar //上传进度条
endProgress sync.WaitGroup
} }
func (this *appTerm) LazyInit(obs observer.Observer) error { func (this *appTerm) LazyInit(obs observer.Observer) error {
this.obs = obs this.obs = obs
this.sshService = &service.SSHService{} this.sshService = &service.SSHService{}
this.jsonList = NewFileList()
this.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_TERM, theme.ContentCopyIcon(), nil) //progress
this.cProgress = widget.NewProgressBarInfinite()
this.cProgress.Hide()
this.upProgress = widget.NewProgressBar()
this.upProgress.Hide()
this.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_TERM, theme.MailSendIcon(), nil)
content := container.NewMax() content := container.NewMax()
content.Objects = []fyne.CanvasObject{} content.Objects = []fyne.CanvasObject{}
@ -38,26 +60,15 @@ func (this *appTerm) LazyInit(obs observer.Observer) error {
//left-top //left-top
localDir := widget.NewEntry() localDir := widget.NewEntry()
localDir.PlaceHolder = `本地目录` localDir.PlaceHolder = `本地Json目录`
remoteDir := widget.NewEntry() remoteDir := widget.NewEntry()
remoteDir.PlaceHolder = `远程目录` remoteDir.PlaceHolder = `远程目录`
remoteDir.Text = "/home/liwei/go_dreamfactory/bin/json"
dirForm := widget.NewForm(
widget.NewFormItem("本地目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() {
openFolder(localDir)
}), localDir)),
widget.NewFormItem("远程目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() {
openFolder(remoteDir)
}), remoteDir)),
)
// output panel
output := widget.NewMultiLineEntry()
logrus.Debug(output.CursorRow)
//config //config
ip := widget.NewEntry() ip := widget.NewEntry()
ip.PlaceHolder = "10.0.0.9"
port := widget.NewEntry() port := widget.NewEntry()
port.Text = "22" //default port port.Text = "22" //default port
port.PlaceHolder = "端口" port.PlaceHolder = "端口"
@ -67,40 +78,115 @@ func (this *appTerm) LazyInit(obs observer.Observer) error {
password.PlaceHolder = "密码" password.PlaceHolder = "密码"
passwordItem := &widget.FormItem{Text: "密码:", Widget: password} passwordItem := &widget.FormItem{Text: "密码:", Widget: password}
configForm := widget.NewForm(
&widget.FormItem{Text: "IP:", Widget: container.NewBorder(nil, nil, nil, port, ip)},
&widget.FormItem{Text: "用户名:", Widget: userName},
passwordItem,
widget.NewFormItem("Json目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() {
openFolder(localDir)
}), localDir)),
widget.NewFormItem("远程目录", remoteDir),
)
configForm.Items[4].HintText = "谨慎修改远程目录"
//svn form
lubanAddr := widget.NewEntry()
lubanAddr.PlaceHolder = "Luban服务IP"
workDir := widget.NewEntry()
workDir.PlaceHolder = "工作目录"
lubanCli := widget.NewEntry()
lubanCli.PlaceHolder = "luban客户端可执行文件"
//define
define := widget.NewEntry()
define.PlaceHolder = "定义文件"
define.Text = `Defines\\__root__.xml`
dataDir := widget.NewEntry()
dataDir.PlaceHolder = "Data目录"
jsonDir := widget.NewEntry()
jsonDir.PlaceHolder = "Json目录"
//set input entry //set input entry
if sshConf != nil { if sshConf != nil {
ip.Text = sshConf.Ip ip.Text = sshConf.Ip
port.Text = sshConf.Port port.Text = sshConf.Port
userName.Text = sshConf.UserName userName.Text = sshConf.UserName
password.Text = sshConf.Password password.Text = sshConf.Password
localDir.Text = sshConf.LocalDir
remoteDir.Text = sshConf.RemoteDir
// //
lubanAddr.Text = sshConf.ServerIp
workDir.Text = sshConf.WorkDir
lubanCli.Text = sshConf.LubanCli
dataDir.Text = sshConf.DataDir
jsonDir.Text = sshConf.JsonDir
} }
configForm := widget.NewForm( svnForm := widget.NewForm(
&widget.FormItem{Text: "IP:", Widget: container.NewBorder(nil, nil, nil, port, ip)}, &widget.FormItem{Text: "服务地址", Widget: lubanAddr},
&widget.FormItem{Text: "用户名:", Widget: userName}, &widget.FormItem{Text: "工作目录", Widget: container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() {
passwordItem, openFolder(workDir)
}), workDir)},
&widget.FormItem{Text: "LubanCli", Widget: lubanCli},
&widget.FormItem{Text: "Data目录", Widget: dataDir},
&widget.FormItem{Text: "JSON目录", Widget: jsonDir},
) )
// 非明文显示 // 非明文显示
passwordItem.Widget.Refresh() passwordItem.Widget.Refresh()
// save func // save func
saveBtn := widget.NewButtonWithIcon("保存配置", theme.DocumentSaveIcon(), func() { saveFunc := func() {
if err := service.GetDbService().SaveSSHConf(&model.SSHModel{ if err := service.GetDbService().SaveSSHConf(&model.SSHModel{
Ip: ip.Text, Ip: ip.Text,
UserName: userName.Text, UserName: userName.Text,
Password: password.Text, Password: password.Text,
Port: port.Text, Port: port.Text,
LocalDir: localDir.Text,
RemoteDir: remoteDir.Text,
////
ServerIp: lubanAddr.Text,
WorkDir: workDir.Text,
LubanCli: lubanCli.Text,
DataDir: dataDir.Text,
JsonDir: jsonDir.Text,
}); err != nil { }); err != nil {
logrus.WithField("err", err).Debug("保存配置") logrus.WithField("err", err).Debug("保存配置")
} }
logrus.Debug("save term conf") }
}) saveBtn1 := widget.NewButtonWithIcon("保存配置", theme.DocumentSaveIcon(), saveFunc)
saveBtn2 := widget.NewButtonWithIcon("保存配置", theme.DocumentSaveIcon(), saveFunc)
// conn func // conn func
connBtn := &widget.Button{Text: "连接", Icon: theme.ConfirmIcon()} connBtn := &widget.Button{Text: "连接", Icon: theme.MailForwardIcon()}
disConnBtn := &widget.Button{Text: "断开", Icon: theme.CancelIcon()}
syncBtn := &widget.Button{Text: "同步JSON", Icon: theme.ConfirmIcon()}
refreshBtn := &widget.Button{Text: "刷新", Icon: theme.ViewRefreshIcon()}
svnBtn := &widget.Button{Text: "SVN更新", Icon: theme.ConfirmIcon()}
explorBtn := &widget.Button{Text: "资源管理器", Icon: theme.FolderIcon()}
// 全选/全取消
allSelBtn := &widget.Button{Icon: theme.CheckButtonCheckedIcon()}
allCancelBtn := &widget.Button{Icon: theme.CheckButtonIcon()}
allSelBtn.Hide()
// 连接
connBtn.OnTapped = func() { connBtn.OnTapped = func() {
this.cProgress.Show()
this.cProgress.Start()
ciphers := []string{} ciphers := []string{}
if ip.Text == "" {
dialog.ShowError(errors.New("IP未填写"), toolWin.w)
return
}
if userName.Text == "" { if userName.Text == "" {
dialog.ShowError(errors.New("账号未填写"), toolWin.w) dialog.ShowError(errors.New("账号未填写"), toolWin.w)
return return
@ -113,42 +199,230 @@ func (this *appTerm) LazyInit(obs observer.Observer) error {
dialog.ShowError(errors.New("端口未填写"), toolWin.w) dialog.ShowError(errors.New("端口未填写"), toolWin.w)
return return
} }
if localDir.Text == "" {
dialog.ShowError(errors.New("JSON目录未填写"), toolWin.w)
return
}
if remoteDir.Text == "" {
dialog.ShowError(errors.New("远程目录未填写"), toolWin.w)
return
}
connBtn.Disable() connBtn.Disable()
err := this.sshService.Connect(userName.Text, password.Text, ip.Text, "", cast.ToInt(port.Text), ciphers) err := this.sshService.Connect(userName.Text, password.Text, ip.Text, "", cast.ToInt(port.Text), ciphers)
if err != nil { if err != nil {
dialog.ShowError(err, toolWin.w) dialog.ShowError(err, toolWin.w)
this.cProgress.Stop()
this.cProgress.Hide()
connBtn.Enable() connBtn.Enable()
return return
} else {
this.jsonList.loadItem(localDir.Text)
this.cProgress.Stop()
this.cProgress.Hide()
disConnBtn.Enable()
syncBtn.Enable()
this.upProgress.Hide()
allCancelBtn.Hide()
allSelBtn.Show()
refreshBtn.Enable()
}
}
// 刷新JSON列表
refreshBtn.Disable()
refreshBtn.OnTapped = func() {
defer func() {
syncBtn.Enable()
allSelBtn.Show()
allCancelBtn.Hide()
}()
this.jsonList.loadItem(localDir.Text)
}
disConnBtn.Disable()
// 断开
disConnBtn.OnTapped = func() {
defer func() {
this.jsonList.reset()
connBtn.Enable()
disConnBtn.Disable()
syncBtn.Disable()
allSelBtn.Hide()
allCancelBtn.Show()
refreshBtn.Disable()
}()
this.sshService.Close()
}
//资源管理器
explorBtn.OnTapped = func() {
logrus.Debug(localDir.Text)
if runtime.GOOS == "windows" {
if err := exec.Command("explorer", filepath.Join(localDir.Text)).Start(); err != nil {
dialog.ShowError(err, toolWin.w)
return
} }
} }
//excute }
excuteBtn := &widget.Button{Text: "执行", Icon: theme.ConfirmIcon()}
excuteBtn.TypedKey(&fyne.KeyEvent{Name: fyne.KeyEnter}) //使用说明
excuteBtn.OnTapped = func() { helpBtn1 := widget.NewButtonWithIcon("", theme.QuestionIcon(), func() {
output.Text = "" quesWin := fyne.CurrentApp().NewWindow("同步JSON使用说明")
excuteBtn.Disable() quesWin.SetContent(widget.NewRichTextFromMarkdown(
`
* 同步Json的操作仅限于数值热更,非结构热更
* 将json文件热更到内网测试环境
* 提示:
* IP:10.0.0.9 22 (保持一致)
* 用户名:root(保持一致)
* 密码:(服务端同学提供)
* Json目录:(json文件目录全路径)
* 远程目录:/home/liwei/go_dreamfactory/bin/json/(保持一致)
* 全部填写完点击保存配置
* 点击连接,右侧面板选择要同步的文件
`))
quesWin.Resize(fyne.NewSize(350, 200))
quesWin.SetFixedSize(true)
quesWin.CenterOnScreen()
quesWin.Show()
})
helpBtn2 := widget.NewButtonWithIcon("", theme.QuestionIcon(), func() {
quesWin := fyne.CurrentApp().NewWindow("SVN更新使用说明")
c := widget.NewRichTextFromMarkdown(
`
* 基于Luban工具生成json
* 建议每次同步JSON之前先点击SVN更新
* 提示:
* 服务地址:10.0.1.11 (保持一致)
* 工作目录:svn下ExcelFile目录全路径
* LubanCli:Luban.Client\Luban.Client.exe (保持一致)
* Datas:Datas(保持一致)
* JSON目录:output\json(保持一致)
* 全部填写完点击保存配置
* 点击SVN更新生成json文件
`,
)
quesWin.SetContent(c)
quesWin.Resize(fyne.NewSize(350, 200))
quesWin.SetFixedSize(true)
quesWin.CenterOnScreen()
quesWin.Show()
})
//同步JSON
syncBtn.Disable()
syncBtn.OnTapped = func() {
syncBtn.Disable()
defer func() { defer func() {
excuteBtn.Enable() syncBtn.Enable()
this.upProgress.Hide()
}() }()
if this.sshService.Client == nil { if this.sshService.Client == nil {
dialog.ShowError(errors.New("请先连接终端"), toolWin.w) dialog.ShowError(errors.New("请先连接终端"), toolWin.w)
return return
} }
output.SetText(this.sshService.LastResult)
this.upProgress.Show()
this.upProgress.SetValue(0)
len := len(this.jsonList.selItemIds)
num := 0.0
increment := func(wg *sync.WaitGroup) {
num += float64(1) / float64(len)
this.upProgress.SetValue(num)
wg.Done()
} }
btns := container.NewHBox(excuteBtn, &layout.Spacer{}, saveBtn, connBtn) for _, fileName := range this.jsonList.selItemIds {
this.endProgress.Add(1)
go func(fn string) {
time.Sleep(time.Second * time.Duration(rand.Intn(3)))
if err := this.sshService.ScpCopy(filepath.Join(localDir.Text, fn), remoteDir.Text); err != nil {
logrus.WithField("err", err).Error("同步json")
showTip(err.Error())
}
increment(&this.endProgress)
// 移除已上传的
this.jsonList.deleteItem(fn)
}(fileName)
}
this.endProgress.Wait()
this.upProgress.SetValue(1)
}
// layout // SVN更新
split := container.NewVSplit(container.NewGridWithColumns(2, svnBtn.OnTapped = func() {
dirForm, this.cProgress.Show()
container.NewBorder(configForm, btns, widget.NewSeparator(), nil)), output) this.cProgress.Start()
split.Offset = 0.25 svnBtn.Disable()
content.Objects = append(content.Objects, split) defer func() {
this.cProgress.Hide()
this.cProgress.Stop()
svnBtn.Enable()
}()
commandStr := `%s -h %s -j cfg -- -d %s --input_data_dir %s --output_data_dir %s --gen_types data_json -s server`
arg := fmt.Sprintf(commandStr,
filepath.Join(workDir.Text, lubanCli.Text),
lubanAddr.Text,
filepath.Join(workDir.Text, define.Text),
filepath.Join(workDir.Text, dataDir.Text),
filepath.Join(workDir.Text, jsonDir.Text),
)
logrus.Debug(arg)
c := exec.Command("cmd.exe", "/c", arg)
if err := c.Run(); err != nil {
dialog.ShowError(err, toolWin.w)
return
}
}
// 全部取消
allCancelBtn.OnTapped = func() {
defer func() {
allCancelBtn.Hide()
allSelBtn.Show()
}()
for i, v := range this.jsonList.cachedList.Items {
this.jsonList.cachedList.Items[i].Checked = true
this.jsonList.selItemIds = append(this.jsonList.selItemIds, v.Text)
this.jsonList.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
}
this.jsonList.itemList.Refresh()
}
// 全选
allSelBtn.OnTapped = func() {
defer func() {
allCancelBtn.Show()
allSelBtn.Hide()
}()
this.jsonList.selItemIds = []string{}
for i, v := range this.jsonList.cachedList.Items {
this.jsonList.cachedList.Items[i].Checked = false
this.jsonList.itemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
}
// this.jsonList.changeFileCount()
this.jsonList.itemList.Refresh()
}
// 创建json列表
this.jsonList.itemList = this.jsonList.createList()
btns1 := container.NewHBox(helpBtn1, &layout.Spacer{}, saveBtn1, connBtn, disConnBtn)
btns2 := container.NewHBox(helpBtn2, &layout.Spacer{}, saveBtn2, svnBtn)
split := container.NewHSplit(container.NewVBox(canvas.NewText("---只能在非上产环境!!!同步Json的操作仅限于数值热更,非结构热更---", color.RGBA{255, 0, 0, 255}), configForm,
btns1, svnForm, btns2, this.cProgress), container.NewBorder(container.NewHBox(allCancelBtn, allSelBtn, syncBtn, refreshBtn, explorBtn), nil, nil, nil, this.jsonList.itemList))
split.Offset = 0.45
content.Objects = append(content.Objects, container.NewBorder(nil, this.upProgress, nil, nil, split))
this.tabItem.Content = content this.tabItem.Content = content
@ -167,7 +441,6 @@ func (a *appTerm) OnClose() bool {
if a.sshService.Client != nil { if a.sshService.Client != nil {
a.sshService.Client.Close() a.sshService.Client.Close()
} }
}, toolWin.w) }, toolWin.w)
return true return true
} }

View File

@ -46,7 +46,7 @@ func NewToolWindow(ui *UIImpl, parent fyne.Window) ToolWindow {
openApp1(common.TOOLBAR_SEC) openApp1(common.TOOLBAR_SEC)
}), }),
widget.NewToolbarAction(theme.ContentUndoIcon(), func() { widget.NewToolbarAction(theme.MailSendIcon(), func() {
openApp1(common.TOOLBAR_TERM) openApp1(common.TOOLBAR_TERM)
}), }),