Browse Source

Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gva_workflow

 Conflicts:
	server/cmd/datas/init.go
pixel 4 years ago
parent
commit
65458b4967

+ 5 - 45
server/api/v1/sys_auto_code.go

@@ -30,51 +30,11 @@ func CreateTemp(c *gin.Context) {
 		return
 	}
 	if a.AutoCreateApiToSql {
-		apiList := [6]model.SysApi{
-			{
-				Path:        "/" + a.Abbreviation + "/" + "create" + a.StructName,
-				Description: "新增" + a.Description,
-				ApiGroup:    a.Abbreviation,
-				Method:      "POST",
-			},
-			{
-				Path:        "/" + a.Abbreviation + "/" + "delete" + a.StructName,
-				Description: "删除" + a.Description,
-				ApiGroup:    a.Abbreviation,
-				Method:      "DELETE",
-			},
-			{
-				Path:        "/" + a.Abbreviation + "/" + "delete" + a.StructName + "ByIds",
-				Description: "批量删除" + a.Description,
-				ApiGroup:    a.Abbreviation,
-				Method:      "DELETE",
-			},
-			{
-				Path:        "/" + a.Abbreviation + "/" + "update" + a.StructName,
-				Description: "更新" + a.Description,
-				ApiGroup:    a.Abbreviation,
-				Method:      "PUT",
-			},
-			{
-				Path:        "/" + a.Abbreviation + "/" + "find" + a.StructName,
-				Description: "根据ID获取" + a.Description,
-				ApiGroup:    a.Abbreviation,
-				Method:      "GET",
-			},
-			{
-				Path:        "/" + a.Abbreviation + "/" + "get" + a.StructName + "List",
-				Description: "获取" + a.Description + "列表",
-				ApiGroup:    a.Abbreviation,
-				Method:      "GET",
-			},
-		}
-		for _, v := range apiList {
-			if err := service.AutoCreateApi(v); err != nil {
-				global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Any("err", err))
-				c.Writer.Header().Add("success", "false")
-				c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
-				return
-			}
+		if err := service.AutoCreateApi(&a); err != nil {
+			global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Any("err", err))
+			c.Writer.Header().Add("success", "false")
+			c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
+			return
 		}
 	}
 	err := service.CreateTemp(a)

+ 3 - 2
server/cmd/datas/AuthorityMenu.go

@@ -5,9 +5,10 @@ import (
 	"gorm.io/gorm"
 )
 
-func InitAuthorityMenu(db *gorm.DB) (err error) {
+func InitAuthorityMenu(db *gorm.DB) {
 	if err := db.Exec("CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `authority_menu` AS select `sys_base_menus`.`id` AS `id`,`sys_base_menus`.`created_at` AS `created_at`, `sys_base_menus`.`updated_at` AS `updated_at`, `sys_base_menus`.`deleted_at` AS `deleted_at`, `sys_base_menus`.`menu_level` AS `menu_level`,`sys_base_menus`.`parent_id` AS `parent_id`,`sys_base_menus`.`path` AS `path`,`sys_base_menus`.`name` AS `name`,`sys_base_menus`.`hidden` AS `hidden`,`sys_base_menus`.`component` AS `component`, `sys_base_menus`.`title`  AS `title`,`sys_base_menus`.`icon` AS `icon`,`sys_base_menus`.`sort` AS `sort`,`sys_authority_menus`.`sys_authority_authority_id` AS `authority_id`,`sys_authority_menus`.`sys_base_menu_id` AS `menu_id`,`sys_base_menus`.`keep_alive` AS `keep_alive`,`sys_base_menus`.`default_menu` AS `default_menu` from (`sys_authority_menus` join `sys_base_menus` on ((`sys_authority_menus`.`sys_base_menu_id` = `sys_base_menus`.`id`)))").Error; err != nil {
 		color.Danger.Println("authority_menu视图已存在!")
+		return
 	}
-	return nil
+	color.Info.Println("authority_menu视图创建成功!")
 }

+ 7 - 3
server/cmd/datas/apis.go

@@ -4,6 +4,7 @@ import (
 	"gin-vue-admin/global"
 	"gin-vue-admin/model"
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gorm.io/gorm"
@@ -88,8 +89,8 @@ var Apis = []model.SysApi{
 	{global.GVA_MODEL{ID: 77, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/workflowProcess/GetMyNeed", "获取我的待办", "workflowProcess", "GET"},
 }
 
-func InitSysApi(db *gorm.DB) (err error) {
-	return db.Transaction(func(tx *gorm.DB) error {
+func InitSysApi(db *gorm.DB) {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("id IN ?", []int{1, 67}).Find(&[]model.SysApi{}).RowsAffected == 2 {
 			color.Danger.Println("sys_apis表的初始数据已存在!")
 			return nil
@@ -98,5 +99,8 @@ func InitSysApi(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_apis 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/authorities.go

@@ -2,6 +2,7 @@ package datas
 
 import (
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gin-vue-admin/model"
@@ -14,8 +15,8 @@ var Authorities = []model.SysAuthority{
 	{CreatedAt: time.Now(), UpdatedAt: time.Now(), AuthorityId: "9528", AuthorityName: "测试角色", ParentId: "0"},
 }
 
-func InitSysAuthority(db *gorm.DB) (err error) {
-	return db.Transaction(func(tx *gorm.DB) error {
+func InitSysAuthority(db *gorm.DB) {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("authority_id IN ? ", []string{"888", "9528"}).Find(&[]model.SysAuthority{}).RowsAffected == 2 {
 			color.Danger.Println("sys_authorities表的初始数据已存在!")
 			return nil
@@ -24,5 +25,8 @@ func InitSysAuthority(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_authorities 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/authority_Ids.go

@@ -3,6 +3,7 @@ package datas
 import (
 	"github.com/gookit/color"
 	"gorm.io/gorm"
+	"os"
 )
 
 type SysDataAuthorityId struct {
@@ -18,8 +19,8 @@ var DataAuthorityId = []SysDataAuthorityId{
 	{"9528", "9528"},
 }
 
-func InitSysDataAuthorityId(db *gorm.DB) (err error) {
-	return db.Table("sys_data_authority_id").Transaction(func(tx *gorm.DB) error {
+func InitSysDataAuthorityId(db *gorm.DB) {
+	if err := db.Table("sys_data_authority_id").Transaction(func(tx *gorm.DB) error {
 		if tx.Where("sys_authority_authority_id IN ?", []string{"888", "9528"}).Find(&[]SysDataAuthorityId{}).RowsAffected == 5 {
 			color.Danger.Println("sys_data_authority_id表的初始数据已存在!")
 			return nil
@@ -28,5 +29,8 @@ func InitSysDataAuthorityId(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_data_authority_id 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/authority_menus.go

@@ -3,6 +3,7 @@ package datas
 import (
 	"github.com/gookit/color"
 	"gorm.io/gorm"
+	"os"
 )
 
 type SysAuthorityMenus struct {
@@ -72,8 +73,8 @@ var AuthorityMenus = []SysAuthorityMenus{
 	{"9528", 20},
 }
 
-func InitSysAuthorityMenus(db *gorm.DB) (err error) {
-	return db.Table("sys_authority_menus").Transaction(func(tx *gorm.DB) error {
+func InitSysAuthorityMenus(db *gorm.DB) {
+	if err := db.Table("sys_authority_menus").Transaction(func(tx *gorm.DB) error {
 		if tx.Where("sys_authority_authority_id IN ?", []string{"888", "8881", "9528"}).Find(&[]SysAuthorityMenus{}).RowsAffected == 53 {
 			color.Danger.Println("sys_authority_menus表的初始数据已存在!")
 			return nil
@@ -82,5 +83,8 @@ func InitSysAuthorityMenus(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_authority_menus 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/casbins.go

@@ -4,6 +4,7 @@ import (
 	gormadapter "github.com/casbin/gorm-adapter/v3"
 	"github.com/gookit/color"
 	"gorm.io/gorm"
+	"os"
 )
 
 var Carbines = []gormadapter.CasbinRule{
@@ -161,8 +162,8 @@ var Carbines = []gormadapter.CasbinRule{
 	{PType: "p", V0: "9528", V1: "/autoCode/createTemp", V2: "POST"},
 }
 
-func InitCasbinModel(db *gorm.DB) (err error) {
-	return db.Transaction(func(tx *gorm.DB) error {
+func InitCasbinModel(db *gorm.DB) {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("p_type = ? AND v0 IN ?", "p", []string{"888", "8881", "9528"}).Find(&[]gormadapter.CasbinRule{}).RowsAffected == 142 {
 			color.Danger.Println("casbin_rule表的初始数据已存在!")
 			return nil
@@ -171,5 +172,8 @@ func InitCasbinModel(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> casbin_rule 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/customers.go

@@ -3,6 +3,7 @@ package datas
 import (
 	"gin-vue-admin/global"
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gin-vue-admin/model"
@@ -13,8 +14,8 @@ var Customers = []model.ExaCustomer{
 	{GVA_MODEL: global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, CustomerName: "测试客户", CustomerPhoneData: "1761111111", SysUserID: 1, SysUserAuthorityID: "888"},
 }
 
-func InitExaCustomer(db *gorm.DB) (err error) {
-	return db.Transaction(func(tx *gorm.DB) error {
+func InitExaCustomer(db *gorm.DB) {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("id IN ? ", []int{1}).Find(&[]model.ExaCustomer{}).RowsAffected == 1 {
 			color.Danger.Println("exa_customers表的初始数据已存在!")
 			return nil
@@ -23,5 +24,8 @@ func InitExaCustomer(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> exa_customers 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/dictionaries.go

@@ -3,13 +3,14 @@ package datas
 import (
 	"gin-vue-admin/global"
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gin-vue-admin/model"
 	"gorm.io/gorm"
 )
 
-func InitSysDictionary(db *gorm.DB) (err error) {
+func InitSysDictionary(db *gorm.DB) {
 	var status = new(bool)
 	*status = true
 	Dictionaries := []model.SysDictionary{
@@ -20,7 +21,7 @@ func InitSysDictionary(db *gorm.DB) (err error) {
 		{GVA_MODEL: global.GVA_MODEL{ID: 5, CreatedAt: time.Now(), UpdatedAt: time.Now()}, Name: "数据库字符串", Type: "string", Status: status, Desc: "数据库字符串"},
 		{GVA_MODEL: global.GVA_MODEL{ID: 6, CreatedAt: time.Now(), UpdatedAt: time.Now()}, Name: "数据库bool类型", Type: "bool", Status: status, Desc: "数据库bool类型"},
 	}
-	return db.Transaction(func(tx *gorm.DB) error {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("id IN ?", []int{1, 6}).Find(&[]model.SysDictionary{}).RowsAffected == 2 {
 			color.Danger.Println("sys_dictionaries表的初始数据已存在!")
 			return nil
@@ -29,5 +30,8 @@ func InitSysDictionary(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_dictionaries 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/dictionary_details.go

@@ -3,13 +3,14 @@ package datas
 import (
 	"gin-vue-admin/global"
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gin-vue-admin/model"
 	"gorm.io/gorm"
 )
 
-func InitSysDictionaryDetail(db *gorm.DB) (err error) {
+func InitSysDictionaryDetail(db *gorm.DB) {
 	status := new(bool)
 	*status = true
 	DictionaryDetail := []model.SysDictionaryDetail{
@@ -37,7 +38,7 @@ func InitSysDictionaryDetail(db *gorm.DB) (err error) {
 		{global.GVA_MODEL{ID: 22, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "longtext", 9, status, 9, 5},
 		{global.GVA_MODEL{ID: 23, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "tinyint", 0, status, 0, 6},
 	}
-	return db.Transaction(func(tx *gorm.DB) error {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("id IN ?", []int{1, 23}).Find(&[]model.SysDictionaryDetail{}).RowsAffected == 2 {
 			color.Danger.Println("sys_dictionary_details表的初始数据已存在!")
 			return nil
@@ -46,5 +47,8 @@ func InitSysDictionaryDetail(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_dictionary_details 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 8 - 3
server/cmd/datas/files.go

@@ -3,6 +3,7 @@ package datas
 import (
 	"gin-vue-admin/global"
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gin-vue-admin/model"
@@ -14,8 +15,8 @@ var Files = []model.ExaFileUploadAndDownload{
 	{global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "logo.png", "http://qmplusimg.henrongyi.top/1576554439myAvatar.png", "png", "1587973709logo.png"},
 }
 
-func InitExaFileUploadAndDownload(db *gorm.DB) (err error) {
-	return db.Transaction(func(tx *gorm.DB) error {
+func InitExaFileUploadAndDownload(db *gorm.DB) {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("id IN ?", []int{1, 2}).Find(&[]model.ExaFileUploadAndDownload{}).RowsAffected == 2 {
 			color.Danger.Println("exa_file_upload_and_downloads表的初始数据已存在!")
 			return nil
@@ -23,6 +24,10 @@ func InitExaFileUploadAndDownload(db *gorm.DB) (err error) {
 		if err := tx.Create(&Files).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
+		color.Info.Println("[Mysql]-->初始化数据成功")
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> exa_file_upload_and_downloads 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 13 - 19
server/cmd/datas/init.go

@@ -9,25 +9,19 @@ import (
 )
 
 func InitMysqlData(db *gorm.DB) {
-	var err error
-	err = InitSysApi(db)
-	err = InitSysUser(db)
-	err = InitExaCustomer(db)
-	err = InitCasbinModel(db)
-	err = InitSysAuthority(db)
-	err = InitSysBaseMenus(db)
-	err = InitAuthorityMenu(db)
-	err = InitSysDictionary(db)
-	err = InitSysAuthorityMenus(db)
-	err = InitSysDataAuthorityId(db)
-	err = InitSysDictionaryDetail(db)
-	err = InitExaFileUploadAndDownload(db)
-	err = InitWkProcess(db)
-	if err != nil {
-		color.Warn.Printf("[Mysql]-->初始化数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
-	color.Info.Println("[Mysql]-->初始化数据成功")
+	InitSysApi(db)
+	InitSysUser(db)
+	InitExaCustomer(db)
+	InitCasbinModel(db)
+	InitSysAuthority(db)
+	InitSysBaseMenus(db)
+	InitAuthorityMenu(db)
+	InitSysDictionary(db)
+	InitSysAuthorityMenus(db)
+	InitSysDataAuthorityId(db)
+	InitSysDictionaryDetail(db)
+	InitExaFileUploadAndDownload(db)
+	InitWkProcess(db)
 }
 
 func InitMysqlTables(db *gorm.DB) {

+ 7 - 3
server/cmd/datas/menus.go

@@ -3,6 +3,7 @@ package datas
 import (
 	"gin-vue-admin/global"
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gin-vue-admin/model"
@@ -45,8 +46,8 @@ var BaseMenus = []model.SysBaseMenu{
 	{GVA_MODEL: global.GVA_MODEL{ID: 33, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "28", Path: "need", Name: "need", Hidden: false, Component: "view/workflow/userList/need.vue", Sort: 0, Meta: model.Meta{Title: "我的待办", Icon: "s-platform"}},
 }
 
-func InitSysBaseMenus(db *gorm.DB) (err error) {
-	return db.Transaction(func(tx *gorm.DB) error {
+func InitSysBaseMenus(db *gorm.DB) {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("id IN ?", []int{1, 27}).Find(&[]model.SysBaseMenu{}).RowsAffected == 2 {
 			color.Danger.Println("sys_base_menus表的初始数据已存在!")
 			return nil
@@ -55,5 +56,8 @@ func InitSysBaseMenus(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_base_menus 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 7 - 3
server/cmd/datas/users.go

@@ -3,6 +3,7 @@ package datas
 import (
 	"gin-vue-admin/global"
 	"github.com/gookit/color"
+	"os"
 	"time"
 
 	"gin-vue-admin/model"
@@ -15,8 +16,8 @@ var Users = []model.SysUser{
 	{GVA_MODEL: global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, UUID: uuid.NewV4(), Username: "a303176530", Password: "3ec063004a6f31642261936a379fde3d", NickName: "QMPlusUser", HeaderImg: "http://qmplusimg.henrongyi.top/1572075907logo.png", AuthorityId: "9528"},
 }
 
-func InitSysUser(db *gorm.DB) (err error) {
-	return db.Transaction(func(tx *gorm.DB) error {
+func InitSysUser(db *gorm.DB) {
+	if err := db.Transaction(func(tx *gorm.DB) error {
 		if tx.Where("id IN ?", []int{1, 2}).Find(&[]model.SysUser{}).RowsAffected == 2 {
 			color.Danger.Println("sys_users表的初始数据已存在!")
 			return nil
@@ -25,5 +26,8 @@ func InitSysUser(db *gorm.DB) (err error) {
 			return err
 		}
 		return nil
-	})
+	}); err != nil {
+		color.Warn.Printf("[Mysql]--> sys_users 表的初始数据失败,err: %v\n", err)
+		os.Exit(0)
+	}
 }

+ 53 - 0
server/cmd/gva/run.go

@@ -0,0 +1,53 @@
+/*
+Copyright © 2020 NAME HERE <EMAIL ADDRESS>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package gva
+
+import (
+	"gin-vue-admin/utils"
+	"github.com/spf13/cobra"
+	"os"
+)
+
+// runCmd represents the run command
+var runCmd = &cobra.Command{
+	Use:   "run",
+	Short: "running go codes with hot-compiled-like feature",
+	Long: `
+	The "run" command is used for running go codes with hot-compiled-like feature,     
+	which compiles and runs the go codes asynchronously when codes change.
+`,
+	Run: func(cmd *cobra.Command, args []string) {
+		w := utils.NewWatch()
+		t := utils.NewT()
+		path, _ := os.Getwd()
+		go w.Watch(path, t)
+		t.RunTask()
+	},
+}
+
+func init() {
+	rootCmd.AddCommand(runCmd)
+
+	// Here you will define your flags and configuration settings.
+
+	// Cobra supports Persistent Flags which will work for this command
+	// and all subcommands, e.g.:
+	// runCmd.PersistentFlags().String("foo", "", "A help for foo")
+
+	// Cobra supports local flags which will only run when this command
+	// is called directly, e.g.:
+	// runCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
+}

+ 1 - 1
server/config.yaml

@@ -56,7 +56,7 @@ mysql:
   config: 'charset=utf8mb4&parseTime=True&loc=Local'
   db-name: 'qmPlus'
   username: 'root'
-  password: 'Aa@6447985'
+  password: 'root123'
   max-idle-conns: 10
   max-open-conns: 100
   log-mode: false

+ 2 - 0
server/go.mod

@@ -56,3 +56,5 @@ require (
 	gorm.io/driver/mysql v0.3.0
 	gorm.io/gorm v1.20.5
 )
+
+replace github.com/casbin/gorm-adapter/v3 => github.com/casbin/gorm-adapter/v3 v3.0.2

+ 0 - 22
server/service/sys_api.go

@@ -33,28 +33,6 @@ func DeleteApi(api model.SysApi) (err error) {
 	return err
 }
 
-//@author: [piexlmax](https://github.com/piexlmax)
-//@function: CreateApi
-//@description: 自动创建api数据,
-//@param: api model.SysApi
-//@return: err error
-
-func AutoCreateApi(api model.SysApi) (err error) {
-	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
-		var fApi model.SysApi
-		var txErr error
-		fxErr := tx.Where("path = ? AND method = ?", api.Path, api.Method).First(&fApi).Error
-		if errors.Is(fxErr, gorm.ErrRecordNotFound) {
-			txErr = tx.Create(&api).Error
-			if txErr != nil {
-				return txErr
-			}
-		}
-		return nil
-	})
-	return err
-}
-
 //@author: [piexlmax](https://github.com/piexlmax)
 //@function: GetAPIInfoList
 //@description: 分页获取数据,

+ 64 - 1
server/service/sys_auto_code.go

@@ -7,6 +7,7 @@ import (
 	"gin-vue-admin/model"
 	"gin-vue-admin/model/request"
 	"gin-vue-admin/utils"
+	"gorm.io/gorm"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -201,9 +202,71 @@ func addAutoMoveFile(data *tplData) {
 		if strings.Contains(data.autoCodePath, "js") {
 			data.autoMoveFilePath = filepath.Join("../", "web", "src", dir, base)
 		} else if strings.Contains(data.autoCodePath, "form") {
-			data.autoMoveFilePath = filepath.Join("../", "web", "src", "view", filepath.Base(filepath.Dir(filepath.Dir(data.autoCodePath))), strings.TrimSuffix(base, filepath.Ext(base))+"From.vue")
+			data.autoMoveFilePath = filepath.Join("../", "web", "src", "view", filepath.Base(filepath.Dir(filepath.Dir(data.autoCodePath))), strings.TrimSuffix(base, filepath.Ext(base))+"Form.vue")
 		} else if strings.Contains(data.autoCodePath, "table") {
 			data.autoMoveFilePath = filepath.Join("../", "web", "src", "view", filepath.Base(filepath.Dir(filepath.Dir(data.autoCodePath))), base)
 		}
 	}
 }
+
+
+//@author: [piexlmax](https://github.com/piexlmax)
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@function: CreateApi
+//@description: 自动创建api数据,
+//@param: a *model.AutoCodeStruct
+//@return: error
+
+func AutoCreateApi(a *model.AutoCodeStruct) (err error) {
+	var apiList = []model.SysApi{
+		{
+			Path:        "/" + a.Abbreviation + "/" + "create" + a.StructName,
+			Description: "新增" + a.Description,
+			ApiGroup:    a.Abbreviation,
+			Method:      "POST",
+		},
+		{
+			Path:        "/" + a.Abbreviation + "/" + "delete" + a.StructName,
+			Description: "删除" + a.Description,
+			ApiGroup:    a.Abbreviation,
+			Method:      "DELETE",
+		},
+		{
+			Path:        "/" + a.Abbreviation + "/" + "delete" + a.StructName + "ByIds",
+			Description: "批量删除" + a.Description,
+			ApiGroup:    a.Abbreviation,
+			Method:      "DELETE",
+		},
+		{
+			Path:        "/" + a.Abbreviation + "/" + "update" + a.StructName,
+			Description: "更新" + a.Description,
+			ApiGroup:    a.Abbreviation,
+			Method:      "PUT",
+		},
+		{
+			Path:        "/" + a.Abbreviation + "/" + "find" + a.StructName,
+			Description: "根据ID获取" + a.Description,
+			ApiGroup:    a.Abbreviation,
+			Method:      "GET",
+		},
+		{
+			Path:        "/" + a.Abbreviation + "/" + "get" + a.StructName + "List",
+			Description: "获取" + a.Description + "列表",
+			ApiGroup:    a.Abbreviation,
+			Method:      "GET",
+		},
+	}
+	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
+		for _, v := range apiList {
+			var api model.SysApi
+			if err := tx.Where("path = ? AND method = ?", v.Path, v.Method).First(&api).Error; err != nil {
+				return err
+			}
+			if err := tx.Create(&v).Error; err != nil { // 遇到错误时回滚事务
+				return err
+			}
+		}
+		return nil
+	})
+	return err
+}

+ 164 - 0
server/utils/cmd_Task.go

@@ -0,0 +1,164 @@
+package utils
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"sync"
+)
+
+type RunTask interface {
+	AddTask()
+	RunTask()
+}
+
+// T: Task任务
+type T struct {
+	sync.Mutex
+
+	// ch: 获取事件channel
+	ch chan struct{}
+
+	closeChan chan struct{}
+
+	// 记录process对象
+	p *os.Process
+
+	// f: 执行任务
+	f func(chan struct{}) error
+}
+
+// NewT: 实例化方法
+func NewT() *T {
+	return newT(nil)
+}
+func newT(f func(chan struct{}) error) *T {
+	t := &T{
+		Mutex:     sync.Mutex{},
+		ch:        make(chan struct{}, 1),
+		closeChan: make(chan struct{}),
+		f:         f,
+	}
+	if f == nil {
+		t.f = t.DefaultF
+	}
+	return t
+}
+
+func (t *T) AddTask() {
+	if len(t.ch) == 1 {
+		return
+	}
+	t.Lock()
+	defer t.Unlock()
+	if len(t.ch) == 1 {
+		// 代表已经有任务了
+		// 直接丢弃这次任务
+		return
+	}
+	fmt.Println("::::发送任务->>>>>>>>")
+	t.ch <- struct{}{}
+}
+
+func (t *T) RunTask() {
+	fmt.Println("进入")
+	// 这里做的make 是用于关闭上一个执行的任务
+	ch := make(chan struct{})
+	// 先run服务
+	go t.f(ch)
+	for {
+		_, ok := <-t.ch
+		ch <- struct{}{}
+		if !ok {
+			return
+		}
+		// 等待上一个关闭
+		<-t.closeChan
+		go t.f(ch)
+	}
+
+}
+
+// DefaultF: 默认的StartFunction
+func (t *T) DefaultF(ch chan struct{}) error {
+
+	var buildCmd *exec.Cmd
+	var cmd *exec.Cmd
+
+	// 判断是否有makefile
+	_, err := os.Stat(filepath.Join("Makefile"))
+	if runtime.GOOS != "windows" && err == nil {
+		_, err := exec.LookPath("make")
+		if err == nil {
+			cmd = exec.Command("make", "run")
+			goto makefile
+		}
+	}
+	// 检测系统是否有编译环境
+	_, err = exec.LookPath("go")
+	if err != nil {
+		return err
+	}
+	// build
+
+	switch runtime.GOOS {
+	case "windows":
+		buildCmd = exec.Command("go", "build", "-o", "gva.exe", "main.go")
+	default:
+		buildCmd = exec.Command("go", "build", "-o", "gva", "main.go")
+	}
+	err = buildCmd.Run()
+	if err != nil {
+		return err
+	}
+	fmt.Println("build 执行完成")
+
+	// 执行
+
+	switch runtime.GOOS {
+	case "windows":
+		cmd = exec.Command("gva.exe")
+	default:
+		cmd = exec.Command("./gva")
+	}
+makefile:
+	// 开始执行任务
+	t.echo(cmd)
+	<-ch
+	// 回收资源
+	err = cmd.Process.Kill()
+	fmt.Println("kill err", err)
+	// 发送关闭完成信号
+	t.closeChan <- struct{}{}
+	return err
+}
+
+// echo: 封装回显
+func (t *T) echo(cmd *exec.Cmd) error {
+	var stdoutBuf bytes.Buffer
+	stdoutIn, _ := cmd.StdoutPipe()
+	var errStdout, errStderr error
+	stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
+	err := cmd.Start()
+	if err != nil {
+		return err
+	}
+	go func() {
+		_, errStdout = io.Copy(stdout, stdoutIn)
+	}()
+	t.p = cmd.Process
+	fmt.Println("pid", t.p.Pid)
+	go func() {
+		_ = cmd.Wait()
+		if errStdout != nil || errStderr != nil {
+			fmt.Printf("failed to capture stdout or stderr\n")
+		}
+		outStr := string(stdoutBuf.Bytes())
+		fmt.Printf("\nout:\n%s\n", outStr)
+	}()
+	return nil
+}

+ 138 - 0
server/utils/cmd_monitor.go

@@ -0,0 +1,138 @@
+package utils
+
+import (
+	"errors"
+	"fmt"
+	"github.com/fsnotify/fsnotify"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+)
+
+// Watch: 监控对象
+type Watch struct {
+	*fsnotify.Watcher
+}
+
+func NewWatch() *Watch {
+	obj, _ := fsnotify.NewWatcher()
+	return &Watch{obj}
+}
+
+// Watch: 监控对象
+func (w *Watch) Watch(path string, t *T) error {
+	// 先转化为绝对路径
+	path, err := filepath.Abs(path)
+	if err != nil {
+		return err
+	}
+	// 判断是单个文件还是目录文件
+	fileInfo, err := os.Stat(path)
+	if err != nil {
+		return err
+	}
+	// 判断是否是目录 添加监控
+	if fileInfo.IsDir() {
+		// dir
+		err = w.watchDir(path)
+
+	} else {
+		err = w.watchFile(path)
+
+	}
+	if err != nil {
+		return err
+	}
+	c := make(chan error)
+	// 启动监控
+	go func() {
+		for {
+			select {
+			case even, ok := <-w.Events:
+				if !ok {
+					// close
+					fmt.Println("Errors close")
+					c <- errors.New("errors close")
+					return
+				}
+				// 判断事件
+				switch {
+				case even.Op&fsnotify.Create == fsnotify.Create:
+					//这里获取新创建文件的信息,如果是目录,则加入监控中
+					fmt.Println("创建文件 : ", even.Name)
+					//t.AddTask()
+					_ = w.Add(even.Name)
+				case even.Op&fsnotify.Write == fsnotify.Write:
+					fmt.Println("修改文件 : ", even.Name)
+					w.addTask(t, even.Name)
+				case even.Op&fsnotify.Remove == fsnotify.Remove || even.Op&fsnotify.Rename == fsnotify.Rename:
+					fmt.Println("删除或重命名文件 : ", even.Name)
+					_ = w.Remove(even.Name)
+					w.addTask(t, even.Name)
+				}
+			case err = <-w.Errors:
+				fmt.Println("even Error:", err)
+				c <- err
+				return
+			}
+		}
+	}()
+	return <-c
+
+}
+
+// watchDir: 处理监控目录
+func (w *Watch) watchDir(path string) error {
+	// 先将自己添加到监控
+	err := w.Add(path)
+
+	if err != nil {
+		return err
+	}
+	fileSlice, err := ioutil.ReadDir(path)
+	if err != nil {
+		return err
+	}
+	for _, f := range fileSlice {
+		fPath := filepath.Join(path, f.Name())
+		if !f.IsDir() {
+			// 判断是否可监控的文件
+			if chickPower(fPath) {
+				err = w.watchFile(fPath)
+				if err != nil {
+					return err
+				}
+			}
+		} else {
+			err := w.watchDir(fPath)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return err
+}
+
+// watchDir: 处理监控单文件
+func (w *Watch) watchFile(path string) error {
+	var err error
+	if chickPower(path) {
+		err = w.Add(path)
+	}
+	return err
+}
+
+// chickPower: 判断是否在可控范围内
+func chickPower(name string) bool {
+	name = filepath.Ext(name)
+	fmt.Println(name)
+	return name == ".go" || name == ".yaml"
+}
+
+// addTask: 偏函数 简化发送任务
+func (w *Watch) addTask(t *T, name string) {
+	if chickPower(name) {
+		fmt.Println("Add Task->>>>>>")
+		t.AddTask()
+	}
+}

+ 11 - 0
web/src/style/main.scss

@@ -605,6 +605,17 @@ li {
                 }
                 .is-active {    
                     background-color: #1890ff;
+                    // 关闭三级菜单二级菜单样式
+                    ul{
+                        border:none;
+                    }
+                }
+                // 关闭三级菜单二级菜单样式
+                .is-active.is-opened{
+                    background-color: #191a23;
+                    ul{
+                        border:none;
+                    }
                 }
             }
         }