package ui import ( "errors" "fmt" "go_dreamfactory/cmd/v2/lib/common" "go_dreamfactory/cmd/v2/model" "go_dreamfactory/cmd/v2/service" "go_dreamfactory/cmd/v2/service/observer" "go_dreamfactory/utils" "io/ioutil" "os/exec" "path/filepath" "runtime" "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/data/binding" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/layout" "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 *fileList jsonList *fileList goChkList *widget.List jsonChkList *widget.List } func (this *appGen) LazyInit(obs observer.Observer) error { this.obs = obs this.goList = NewFileList() this.jsonList = NewFileList() this.tabItem = container.NewTabItemWithIcon(common.TOOLBAR_GEN, theme.ContentCopyIcon(), nil) // load gt := service.GetDbService().GetLubanConf(common.BUCKET_LUBANCONF) logrus.Debugf("%v", gt) 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.PlaceHolder = `配置Luban Client.exe路径 例如: Luban.Client\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 gt != nil { serverAddr.Text = gt.ServerAddr projectDir.Text = gt.ProjectDir workDir.Text = gt.WorkDir client.Text = gt.Client genType.Selected = gt.GenType genTypeText = gt.GenType tmpDir.Text = gt.TmpDir } // 打开目录 openFolder := func(entry *widget.Entry) { dConf := dialog.NewFolderOpen(func(lu fyne.ListableURI, err error) { if lu == nil { return } entry.Text = lu.Path() entry.Refresh() }, toolWin.w) luri, _ := storage.ListerForURI(storage.NewFileURI(".")) dConf.SetLocation(luri) dConf.SetConfirmText("打开") dConf.SetDismissText("取消") dConf.Resize(fyne.NewSize(750, 500)) dConf.Show() } form := widget.NewForm( widget.NewFormItem("服务地址", serverAddr), widget.NewFormItem("项目目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() { openFolder(projectDir) }), projectDir)), widget.NewFormItem("工作目录", container.NewBorder(nil, nil, nil, widget.NewButtonWithIcon("", theme.FolderIcon(), func() { openFolder(workDir) }), 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) }), 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() { if err := service.GetDbService().SaveLubanConf(&model.GenTool{ 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, }); err != nil { logrus.WithField("err", err).Debug("保存配置") } logrus.Debug("save luban conf") }) //go this.goList.titleLabel = widget.NewLabel("Go文件") this.goList.titleLabel.Hide() // 复选列表 this.goChkList = this.goList.createList() // 覆盖 -go go_overrideBtn := &widget.Button{Text: "覆盖Go", Icon: theme.ConfirmIcon()} go_overrideBtn.Hide() go_overrideBtn.OnTapped = func() { go_overrideBtn.Disable() defer func() { go_overrideBtn.Enable() // _ = common.RemoveContents(filepath.Join(tmpDir.Text, "go")) }() 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) } } } // json this.jsonList.titleLabel = widget.NewLabel("Json文件") this.jsonList.titleLabel.Hide() // 复选列表 this.jsonChkList = this.jsonList.createList() // 覆盖 -go json_overrideBtn := &widget.Button{Text: "覆盖Json", Icon: theme.ConfirmIcon()} json_overrideBtn.Hide() json_overrideBtn.OnTapped = func() { json_overrideBtn.Disable() defer func() { json_overrideBtn.Enable() // _ = common.RemoveContents(filepath.Join(tmpDir.Text, "json")) }() for _, v := range this.jsonList.selItemIds { // logrus.WithField("path1", filepath.Join(tmpDir.Text, "json", v)).Debug("copy 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) } logrus.Debug(v) } } genBtn := &widget.Button{Text: "生成", Icon: theme.ConfirmIcon()} genBtn.OnTapped = func() { genBtn.Disable() defer func() { genBtn.Enable() }() if runtime.GOOS != "windows" { dialog.ShowError(errors.New("no support "+runtime.GOOS), toolWin.w) return } if genTypeText == "" { dialog.ShowError(errors.New("类型未选择"), toolWin.w) return } 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" { this.goList.changeItem(filepath.Join(tmpDir.Text, "go")) this.goList.titleLabel.SetText(fmt.Sprintf("(%d/%d个)", len(this.goList.selItemIds), this.goList.fileTotal)) go_overrideBtn.Show() this.goList.titleLabel.Show() } else if genTypeText == "json" { this.jsonList.changeItem(filepath.Join(tmpDir.Text, "json")) this.jsonList.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(this.jsonList.selItemIds), this.jsonList.fileTotal)) json_overrideBtn.Show() this.jsonList.titleLabel.Show() } } // layout left := container.NewVBox(form, container.NewHBox(&layout.Spacer{}, saveBtn, genBtn)) right := container.NewBorder( container.NewHBox(widget.NewLabel("Go文件"), this.goList.titleLabel, &layout.Spacer{}, widget.NewLabel("Json文件"), this.jsonList.titleLabel), container.NewHBox(go_overrideBtn, &layout.Spacer{}, json_overrideBtn), nil, nil, container.NewMax( container.NewGridWithColumns(2, container.NewVScroll(this.goChkList), container.NewVScroll(this.jsonChkList), ))) content.Objects = append(content.Objects, container.NewGridWithColumns(2, left, right)) this.tabItem.Content = content return nil } type fileList struct { dataBinding binding.UntypedList selItemIds []string //选择的ID itemListData *model.ItemModelList fileTotal int //文件总数 titleLabel *widget.Label } func NewFileList() *fileList { return &fileList{ dataBinding: binding.NewUntypedList(), titleLabel: &widget.Label{}, } } func (f *fileList) createList() *widget.List { return widget.NewListWithData(f.dataBinding, func() fyne.CanvasObject { return container.NewHBox( &widget.Check{Checked: true}, // widget.NewCheck("", func(b bool) { }), widget.NewLabelWithStyle("", fyne.TextAlignCenter, fyne.TextStyle{}), widget.NewLabel(""), ) }, func(data binding.DataItem, item fyne.CanvasObject) { o, _ := data.(binding.Untyped).Get() pd := o.(*model.ItemModel) item.(*fyne.Container).Objects[0].(*widget.Check).OnChanged = func(b bool) { if b { f.selItemIds = append(f.selItemIds, pd.Id) } else { f.selItemIds = utils.DeleteString(f.selItemIds, pd.Id) } f.titleLabel.SetText(fmt.Sprintf("(%d/%d)", len(f.selItemIds), f.fileTotal)) } item.(*fyne.Container).Objects[1].(*widget.Label).SetText(pd.Label) }, ) } func (f *fileList) changeItem(dir string) { f.itemListData = model.NewItemModelList() files, err := ioutil.ReadDir(dir) if err != nil { logrus.Error(err) return } now := time.Now().Unix() for _, file := range files { if !file.IsDir() { // 仅筛选出变更的文件 if now-file.ModTime().Unix() < 5 { fm := &model.ItemModel{ Id: file.Name(), Label: file.Name(), } f.itemListData.DataList = append(f.itemListData.DataList, fm) f.selItemIds = append(f.selItemIds, fm.Id) f.fileTotal++ logrus.Debugf("%v", fm.Id) } } } f.reloadListData() } func (f *fileList) reloadListData() { if f.itemListData != nil { d := f.itemListData.AsInterfaceArray() f.dataBinding.Set(d) } } func (a *appGen) GetAppName() string { return common.TOOLBAR_GEN }