dreamfactory_cmd/cmd/v2/ui/tool_luban.go
2023-06-09 21:58:02 +08:00

436 lines
12 KiB
Go

package ui
import (
"errors"
"fmt"
"go_dreamfactory/cmd/v2/lib/common"
os_storage "go_dreamfactory/cmd/v2/lib/storage"
"go_dreamfactory/cmd/v2/service"
"go_dreamfactory/cmd/v2/service/observer"
"os/exec"
"path/filepath"
"runtime"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
fyne_storage "fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"github.com/sirupsen/logrus"
)
type appGen struct {
appAdapter
obs observer.Observer
goList *common.ItemList
jsonList *common.ItemList
}
func (this *appGen) LazyInit(ptService service.PttService, obs observer.Observer) error {
this.obs = obs
this.goList = common.NewItemList()
this.jsonList = common.NewItemList()
this.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_GEN, theme.ContentCopyIcon(), nil)
storage, _ := os_storage.NewOSStorage()
conf, err := storage.LoadConfig()
if err != nil {
return err
}
content := container.NewMax()
content.Objects = []fyne.CanvasObject{}
serverAddr := widget.NewEntry()
serverAddr.PlaceHolder = "服务器地址 例如: 10.0.1.11"
projectDir := widget.NewEntry()
projectDir.PlaceHolder = `项目目录 例如: E:\projects\workspace\go_dreamfactory\`
workDir := widget.NewEntry()
workDir.PlaceHolder = `LuBan目录 例如: E:\svn\dreamworks\client\dreamworks\ExcelFile\`
// client
client := widget.NewEntry()
client.Text = `Luban.Client\Luban.Client.exe`
client.PlaceHolder = `配置Luban Client.exe路径`
//define
define := widget.NewEntry()
define.PlaceHolder = "定义文件"
define.Text = `Defines\\__root__.xml`
// output
outputCodeDir := widget.NewEntry()
outputCodeDir.Text = `sys\configure\structs`
outputJsonDir := widget.NewEntry()
outputJsonDir.Text = `bin\json`
//input
inputDir := widget.NewEntry()
inputDir.Text = "Datas"
tmpDir := widget.NewEntry()
tmpDir.Text = filepath.Join(`c:\tmp\`)
tmpDir.PlaceHolder = "临时目录,不要和工作目录和项目目录重复"
//genType
var genTypeText string
genType := widget.NewSelect([]string{"go", "json", "all"}, func(s string) {
genTypeText = s
})
genType.PlaceHolder = "生成类型"
if conf.LubanConf != nil {
serverAddr.Text = conf.LubanConf.ServerAddr
projectDir.Text = conf.LubanConf.ProjectDir
workDir.Text = conf.LubanConf.WorkDir
client.Text = conf.LubanConf.Client
genType.Selected = conf.LubanConf.GenType
genTypeText = conf.LubanConf.GenType
tmpDir.Text = conf.LubanConf.TmpDir
}
form := widget.NewForm(
widget.NewFormItem("服务地址", serverAddr),
widget.NewFormItem("项目目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() {
openFolder(projectDir, toolWin.w)
}), projectDir)),
widget.NewFormItem("工作目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() {
openFolder(workDir, toolWin.w)
}), workDir)),
widget.NewFormItem("LuBan Cli", client),
widget.NewFormItem("输入目录", inputDir),
widget.NewFormItem("输出Code目录", outputCodeDir),
widget.NewFormItem("输出JSON目录", outputJsonDir),
widget.NewFormItem("临时目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() {
openFolder(tmpDir, toolWin.w)
}), tmpDir)),
widget.NewFormItem("生成类型", genType),
)
getType := func() string {
if genTypeText == "" {
return ""
} else {
if genTypeText == "go" {
return "code_go_json"
} else if genTypeText == "json" {
return "data_json"
} else if genTypeText == "all" {
return "code_go_json,data_json"
}
}
return ""
}
saveBtn := widget.NewButtonWithIcon("保存配置", theme.DocumentSaveIcon(), func() {
lubanconf := &os_storage.LubanConfig{
ServerAddr: serverAddr.Text,
ProjectDir: projectDir.Text,
Client: client.Text,
WorkDir: workDir.Text,
InputDir: inputDir.Text,
OutputCodeDir: outputCodeDir.Text,
OutputJsonDir: outputJsonDir.Text,
GenType: genTypeText,
TmpDir: tmpDir.Text,
}
conf.LubanConf = lubanconf
if err := storage.StoreConfig(conf); err != nil {
logrus.WithField("err", err).Debug("保存配置")
}
logrus.Debug("save luban conf")
})
//go
this.goList.TitleLabel = widget.NewLabel("Go文件")
this.goList.TitleLabel.Hide()
// 复选列表
this.goList.ItemList = this.goList.CreateDefaultCheckList()
// 覆盖 -go
go_allSelBtn := &widget.Button{Icon: theme.CheckButtonCheckedIcon()}
go_allCancelBtn := &widget.Button{Icon: theme.CheckButtonIcon()}
go_overrideBtn := &widget.Button{Text: "覆盖", Icon: theme.ConfirmIcon()}
go_overrideBtn.Hide()
go_allSelBtn.Hide()
// 覆盖
go_overrideBtn.OnTapped = func() {
go_overrideBtn.Disable()
defer func() {
go_overrideBtn.Enable()
this.goList.ItemList.Refresh()
}()
for _, v := range this.goList.SelItemIds {
// logrus.WithField("path1", filepath.Join(tmpDir.Text, "go", v)).Debug("copy go")
// logrus.WithField("path2", filepath.Join(projectDir.Text, outputCodeDir.Text, v)).Debug("copy go")
_, err := common.Copy(filepath.Join(tmpDir.Text, "go", v),
filepath.Join(projectDir.Text, outputCodeDir.Text, v))
if err != nil {
logrus.Error(err)
return
}
this.goList.DeleteItem(v)
}
this.goList.ChangeFileCount()
}
//取消checked
go_allCancelBtn.OnTapped = func() {
defer func() {
go_allCancelBtn.Hide()
go_allSelBtn.Show()
}()
this.goList.SelItemIds = []string{}
for i, v := range this.goList.CachedList.Items {
this.goList.CachedList.Items[i].Checked = false
this.goList.ItemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
}
this.goList.ChangeFileCount()
this.goList.ItemList.Refresh()
}
//选择所有
go_allSelBtn.OnTapped = func() {
defer func() {
go_allCancelBtn.Show()
go_allSelBtn.Hide()
}()
for i, v := range this.goList.CachedList.Items {
this.goList.CachedList.Items[i].Checked = true
this.goList.SelItemIds = append(this.goList.SelItemIds, v.Text)
this.goList.ItemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
}
this.goList.ChangeFileCount()
// this.goList.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(this.goList.selItemIds), this.goList.fileTotal))
this.goList.ItemList.Refresh()
}
// json
this.jsonList.TitleLabel = widget.NewLabel("Json文件")
this.jsonList.TitleLabel.Hide()
// 复选列表
this.jsonList.ItemList = this.jsonList.CreateDefaultCheckList()
// 覆盖 -json
json_allSelBtn := &widget.Button{Icon: theme.CheckButtonCheckedIcon()}
json_allCancelBtn := &widget.Button{Icon: theme.CheckButtonIcon()}
json_overrideBtn := &widget.Button{Text: "覆盖", Icon: theme.ConfirmIcon()}
json_overrideBtn.Hide()
json_allSelBtn.Hide()
// 点击覆盖按钮
json_overrideBtn.OnTapped = func() {
json_overrideBtn.Disable()
defer func() {
json_overrideBtn.Enable()
this.jsonList.ItemList.Refresh()
}()
for _, v := range this.jsonList.SelItemIds {
logrus.WithField("path", v).Debug("select json")
// // logrus.WithField("path2", filepath.Join(projectDir.Text, outputJsonDir.Text, v)).Debug("copy json")
_, err := common.Copy(filepath.Join(tmpDir.Text, "json", v),
filepath.Join(projectDir.Text, outputJsonDir.Text, v))
if err != nil {
logrus.Error(err)
return
}
this.jsonList.DeleteItem(v)
}
this.jsonList.ChangeFileCount()
}
//取消checked
json_allSelBtn.OnTapped = func() {
defer func() {
json_allCancelBtn.Show()
json_allSelBtn.Hide()
}()
list := this.jsonList
list.SelItemIds = []string{}
for i, v := range list.CachedList.Items {
list.CachedList.Items[i].Checked = false
list.ItemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
}
this.jsonList.ChangeFileCount()
list.ItemList.Refresh()
}
//选择所有
json_allCancelBtn.OnTapped = func() {
defer func() {
json_allCancelBtn.Hide()
json_allSelBtn.Show()
}()
list := this.jsonList
for i, v := range list.CachedList.Items {
list.CachedList.Items[i].Checked = true
list.SelItemIds = append(list.SelItemIds, v.Text)
list.ItemList.UpdateItem(i, widget.NewCheck(v.Text, nil))
}
list.ChangeFileCount()
list.ItemList.Refresh()
}
// 资源管理器
explorBtn := &widget.Button{Text: "资源管理器", Icon: theme.FolderIcon()}
explorBtn.OnTapped = func() {
OpenExplor(filepath.Join(workDir.Text, inputDir.Text))
}
genBtn := &widget.Button{Text: "生成", Icon: theme.ConfirmIcon()}
genBtn.OnTapped = func() {
genBtn.Disable()
defer func() {
genBtn.Enable()
go_allCancelBtn.Show()
go_allSelBtn.Hide()
json_allCancelBtn.Show()
json_allSelBtn.Hide()
}()
if runtime.GOOS != "windows" {
dialog.ShowError(errors.New("no support "+runtime.GOOS), toolWin.w)
return
}
if genTypeText == "" {
dialog.ShowError(errors.New("类型未选择"), toolWin.w)
return
}
changeGo := func() {
this.goList.ChangeItem(filepath.Join(tmpDir.Text, "go"), filepath.Join(projectDir.Text, outputCodeDir.Text))
this.goList.TitleLabel.SetText(fmt.Sprintf("(%d/%d个)", len(this.goList.SelItemIds), this.goList.ItemTotal))
go_overrideBtn.Show()
this.goList.TitleLabel.Show()
}
changeJson := func() {
this.jsonList.ChangeItem(filepath.Join(tmpDir.Text, "json"), filepath.Join(projectDir.Text, outputJsonDir.Text))
this.jsonList.TitleLabel.SetText(fmt.Sprintf("(%d/%d)", len(this.jsonList.SelItemIds), this.jsonList.ItemTotal))
json_overrideBtn.Show()
this.jsonList.TitleLabel.Show()
}
gen := func() {
commandStr := `%s -h %s -j cfg -- -d %s --input_data_dir %s --output_code_dir %s --output_data_dir %s --gen_types %s --go:bright_module_name bright -s server`
arg := fmt.Sprintf(commandStr,
filepath.Join(workDir.Text, client.Text),
serverAddr.Text,
filepath.Join(workDir.Text, define.Text),
filepath.Join(workDir.Text, inputDir.Text),
filepath.Join(tmpDir.Text, "go"),
filepath.Join(tmpDir.Text, "json"),
getType(),
)
logrus.Debug(arg)
c := exec.Command("cmd.exe", "/c", arg)
if err := c.Run(); err != nil {
dialog.ShowError(err, toolWin.w)
return
}
// 更新列表
if genTypeText == "go" {
changeGo()
} else if genTypeText == "json" {
changeJson()
} else if genTypeText == "all" {
changeGo()
changeJson()
}
}
dc := dialog.NewConfirm("提示", "Excel文件需要更新吗?", func(b bool) {
if !b {
gen()
return
}
OpenExplor(filepath.Join(workDir.Text, inputDir.Text))
}, toolWin.w)
dc.SetDismissText("不更新")
dc.SetConfirmText("更新")
dc.Show()
}
//使用说明
desBtn := widget.NewButtonWithIcon("", theme.QuestionIcon(), func() {
quesWin := fyne.CurrentApp().NewWindow("使用说明")
quesWin.SetContent(widget.NewRichTextFromMarkdown(
`
1. SVN更新excel文件
2. 配置Luban(已做可忽略)
3. 选择**生成类型**,单击生成
4. 选择要覆盖的文件
`))
quesWin.Resize(fyne.NewSize(350, 200))
quesWin.SetFixedSize(true)
quesWin.CenterOnScreen()
quesWin.Show()
})
// layout
left := container.NewVBox(form, container.NewHBox(&layout.Spacer{}, desBtn, saveBtn, &layout.Spacer{}, explorBtn, genBtn))
right := container.NewGridWithColumns(2,
container.NewBorder(
container.NewHBox(go_allSelBtn, go_allCancelBtn, go_overrideBtn, widget.NewLabel("Go文件"), this.goList.TitleLabel),
nil, nil, nil,
this.goList.ItemList),
container.NewBorder(
container.NewHBox(json_allSelBtn, json_allCancelBtn, json_overrideBtn, widget.NewLabel("Json文件"), this.jsonList.TitleLabel),
nil, nil, nil,
this.jsonList.ItemList))
content.Objects = append(content.Objects, container.NewGridWithColumns(2, left, right))
this.tabItem.Content = content
return nil
}
// 打开目录
func openFolder(entry *widget.Entry, w fyne.Window) {
dConf := dialog.NewFolderOpen(func(lu fyne.ListableURI, err error) {
if lu == nil {
return
}
entry.Text = lu.Path()
entry.Refresh()
}, w)
luri, _ := fyne_storage.ListerForURI(fyne_storage.NewFileURI("."))
dConf.SetLocation(luri)
dConf.SetConfirmText("打开")
dConf.SetDismissText("取消")
dConf.Resize(fyne.NewSize(750, 500))
dConf.Show()
}
func openFile(entry *widget.Entry, w fyne.Window) {
dConf := dialog.NewFileOpen(func(lu fyne.URIReadCloser, err error) {
if lu == nil {
return
}
entry.SetText(lu.URI().Path())
entry.Refresh()
}, w)
dConf.SetConfirmText("打开")
dConf.SetDismissText("取消")
dConf.SetFilter(fyne_storage.NewExtensionFileFilter([]string{".exe"}))
dConf.Resize(fyne.NewSize(750, 500))
dConf.Show()
}
func (a *appGen) GetAppName() string {
return common.TOOLBAR_GEN
}
func(a *appGen) Icon() fyne.Resource{
return theme.ContentCopyIcon()
}