Browse Source

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

SliverHorn 4 years ago
parent
commit
353f9d25a8
45 changed files with 937 additions and 530 deletions
  1. 0 14
      server/cmd/datas/AuthorityMenu.go
  2. 0 32
      server/cmd/datas/authorities.go
  3. 0 36
      server/cmd/datas/authority_Ids.go
  4. 0 79
      server/cmd/datas/authority_menus.go
  5. 0 31
      server/cmd/datas/customers.go
  6. 0 58
      server/cmd/datas/init.go
  7. 12 23
      server/cmd/gva/initdb.go
  8. 316 0
      server/cmd/gva/mysql.go
  9. 1 1
      server/cmd/gva/version.go
  10. 17 16
      server/cmd/information/extra/file.go
  11. 15 12
      server/cmd/information/system/admin.go
  12. 14 11
      server/cmd/information/system/api.go
  13. 83 0
      server/cmd/information/system/authorities_menus.go
  14. 36 0
      server/cmd/information/system/authority.go
  15. 25 0
      server/cmd/information/system/authority_menu.go
  16. 16 12
      server/cmd/information/system/casbin.go
  17. 40 0
      server/cmd/information/system/data_authorities.go
  18. 18 14
      server/cmd/information/system/dictionary.go
  19. 15 14
      server/cmd/information/system/dictionary_details.go
  20. 16 13
      server/cmd/information/system/menu.go
  21. 11 9
      server/cmd/information/system/workflow.go
  22. 1 1
      server/config.yaml
  23. 4 0
      server/config/gorm.go
  24. 2 1
      server/core/server.go
  25. 1 0
      server/model/sys_authority.go
  26. 1 0
      server/model/sys_base_menu.go
  27. 1 1
      server/resource/template/server/router.go.tpl
  28. 11 11
      server/resource/template/web/table.vue.tpl
  29. 2 2
      web/package.json
  30. 4 2
      web/src/components/chooseImg/index.vue
  31. 2 1
      web/src/main.js
  32. 2 3
      web/src/permission.js
  33. 4 2
      web/src/store/module/router.js
  34. 12 8
      web/src/store/module/user.js
  35. 1 2
      web/src/view/example/customer/customer.vue
  36. 197 102
      web/src/view/layout/aside/historyComponent/history.vue
  37. 11 4
      web/src/view/layout/index.vue
  38. 10 4
      web/src/view/layout/search/search.vue
  39. 25 2
      web/src/view/superAdmin/authority/components/menus.vue
  40. 1 2
      web/src/view/superAdmin/dictionary/sysDictionary.vue
  41. 1 2
      web/src/view/superAdmin/dictionary/sysDictionaryDetail.vue
  42. 7 0
      web/src/view/superAdmin/menu/menu.vue
  43. 1 2
      web/src/view/superAdmin/operation/sysOperationRecord.vue
  44. 0 1
      web/src/view/systemTools/autoCode/component/fieldDialog.vue
  45. 1 2
      web/src/view/workflow/workflowProcess/workflowProcess.vue

+ 0 - 14
server/cmd/datas/AuthorityMenu.go

@@ -1,14 +0,0 @@
-package datas
-
-import (
-	"github.com/gookit/color"
-	"gorm.io/gorm"
-)
-
-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
-	}
-	color.Info.Println("authority_menu视图创建成功!")
-}

+ 0 - 32
server/cmd/datas/authorities.go

@@ -1,32 +0,0 @@
-package datas
-
-import (
-	"github.com/gookit/color"
-	"os"
-	"time"
-
-	"gin-vue-admin/model"
-	"gorm.io/gorm"
-)
-
-var Authorities = []model.SysAuthority{
-	{CreatedAt: time.Now(), UpdatedAt: time.Now(), AuthorityId: "888", AuthorityName: "普通用户", ParentId: "0"},
-	{CreatedAt: time.Now(), UpdatedAt: time.Now(), AuthorityId: "8881", AuthorityName: "普通用户子角色", ParentId: "888"},
-	{CreatedAt: time.Now(), UpdatedAt: time.Now(), AuthorityId: "9528", AuthorityName: "测试角色", ParentId: "0"},
-}
-
-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
-		}
-		if err := tx.Create(&Authorities).Error; err != nil { // 遇到错误时回滚事务
-			return err
-		}
-		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_authorities 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
-}

+ 0 - 36
server/cmd/datas/authority_Ids.go

@@ -1,36 +0,0 @@
-package datas
-
-import (
-	"github.com/gookit/color"
-	"gorm.io/gorm"
-	"os"
-)
-
-type SysDataAuthorityId struct {
-	SysAuthorityAuthorityId    string
-	DataAuthorityIdAuthorityId string
-}
-
-var DataAuthorityId = []SysDataAuthorityId{
-	{"888", "888"},
-	{"888", "8881"},
-	{"888", "9528"},
-	{"9528", "8881"},
-	{"9528", "9528"},
-}
-
-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
-		}
-		if err := tx.Create(&DataAuthorityId).Error; err != nil { // 遇到错误时回滚事务
-			return err
-		}
-		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_data_authority_id 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
-}

+ 0 - 79
server/cmd/datas/authority_menus.go

@@ -1,79 +0,0 @@
-package datas
-
-import (
-	"github.com/gookit/color"
-	"gorm.io/gorm"
-	"os"
-)
-
-type SysAuthorityMenus struct {
-	SysAuthorityAuthorityId string
-	SysBaseMenuId           uint
-}
-
-var AuthorityMenus = []SysAuthorityMenus{
-	{"888", 1},
-	{"888", 2},
-	{"888", 3},
-	{"888", 4},
-	{"888", 5},
-	{"888", 6},
-	{"888", 7},
-	{"888", 8},
-	{"888", 9},
-	{"888", 10},
-	{"888", 11},
-	{"888", 12},
-	{"888", 13},
-	{"888", 14},
-	{"888", 15},
-	{"888", 16},
-	{"888", 17},
-	{"888", 18},
-	{"888", 19},
-	{"888", 20},
-	{"888", 21},
-	{"888", 22},
-	{"888", 23},
-	{"888", 24},
-	{"888", 25},
-	{"888", 26},
-	{"888", 27},
-	{"888", 28},
-	{"888", 29},
-	{"8881", 1},
-	{"8881", 2},
-	{"8881", 8},
-	{"9528", 1},
-	{"9528", 2},
-	{"9528", 3},
-	{"9528", 4},
-	{"9528", 5},
-	{"9528", 6},
-	{"9528", 7},
-	{"9528", 8},
-	{"9528", 9},
-	{"9528", 10},
-	{"9528", 11},
-	{"9528", 12},
-	{"9528", 14},
-	{"9528", 15},
-	{"9528", 16},
-	{"9528", 17},
-}
-
-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
-		}
-		if err := tx.Create(&AuthorityMenus).Error; err != nil { // 遇到错误时回滚事务
-			return err
-		}
-		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_authority_menus 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
-}

+ 0 - 31
server/cmd/datas/customers.go

@@ -1,31 +0,0 @@
-package datas
-
-import (
-	"gin-vue-admin/global"
-	"github.com/gookit/color"
-	"os"
-	"time"
-
-	"gin-vue-admin/model"
-	"gorm.io/gorm"
-)
-
-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) {
-	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
-		}
-		if err := tx.Create(&Customers).Error; err != nil { // 遇到错误时回滚事务
-			return err
-		}
-		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> exa_customers 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
-}

+ 0 - 58
server/cmd/datas/init.go

@@ -1,58 +0,0 @@
-package datas
-
-import (
-	"gin-vue-admin/model"
-	gormadapter "github.com/casbin/gorm-adapter/v3"
-	"github.com/gookit/color"
-	"gorm.io/gorm"
-	"os"
-)
-
-func InitMysqlData(db *gorm.DB) {
-	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) {
-	var err error
-	if !db.Migrator().HasTable("casbin_rule") {
-		err = db.Migrator().CreateTable(&gormadapter.CasbinRule{})
-	}
-	err = db.AutoMigrate(
-		model.SysApi{},
-		model.SysUser{},
-		model.ExaFile{},
-		model.ExaCustomer{},
-		model.SysBaseMenu{},
-		model.SysAuthority{},
-		model.JwtBlacklist{},
-		model.ExaFileChunk{},
-		model.SysDictionary{},
-		model.ExaSimpleUploader{},
-		model.SysOperationRecord{},
-		model.SysDictionaryDetail{},
-		model.SysBaseMenuParameter{},
-		model.ExaFileUploadAndDownload{},
-		model.WorkflowProcess{},
-		model.WorkflowNode{},
-		model.WorkflowEdge{},
-		model.WorkflowStartPoint{},
-		model.WorkflowEndPoint{},
-	)
-	if err != nil {
-		color.Warn.Printf("[Mysql]-->初始化数据表失败,err: %v\n", err)
-		os.Exit(0)
-	}
-	color.Info.Println("[Mysql]-->初始化数据表成功")
-}

+ 12 - 23
server/cmd/gva/initdb.go

@@ -16,10 +16,7 @@ limitations under the License.
 package gva
 
 import (
-	"gin-vue-admin/cmd/datas"
 	"gin-vue-admin/core"
-	"gin-vue-admin/initialize"
-
 	"github.com/gookit/color"
 
 	_ "gin-vue-admin/core"
@@ -38,30 +35,22 @@ var initdbCmd = &cobra.Command{
 3. sqlite未适配,
 4. sqlserver未适配`,
 	Run: func(cmd *cobra.Command, args []string) {
+		frame, _ := cmd.Flags().GetString("frame")
 		path, _ := cmd.Flags().GetString("path")
 		global.GVA_VP = core.Viper(path)
 		global.GVA_LOG = core.Zap()           // 初始化zap日志库
-		db := initialize.GormMysql()
-		switch global.GVA_CONFIG.System.DbType {
-		case "mysql":
-			datas.InitMysqlTables(db)
-			datas.InitMysqlData(db)
-		case "postgresql":
-			color.Info.Println("postgresql功能开发中")
-		case "sqlite":
-			color.Info.Println("sqlite功能开发中")
-		case "sqlserver":
-			color.Info.Println("sqlserver功能开发中")
-		default:
-			datas.InitMysqlTables(db)
-			datas.InitMysqlData(db)
-		}
-		frame, _ := cmd.Flags().GetString("frame")
-		if frame == "gf" {
+		Mysql.CheckDatabase()
+		Mysql.CheckUtf8mb4()
+		Mysql.Info()
+		Mysql.Init()
+		switch frame {
+		case "gin":
+			if global.GVA_CONFIG.System.DbType == "mysql" {
+				Mysql.AutoMigrateTables()
+				Mysql.InitData()
+			}
+		case "gf":
 			color.Info.Println("gf功能开发中")
-			return
-		} else {
-			return
 		}
 	},
 }

+ 316 - 0
server/cmd/gva/mysql.go

@@ -0,0 +1,316 @@
+package gva
+
+import (
+	"fmt"
+	information "gin-vue-admin/cmd/information/extra"
+	data "gin-vue-admin/cmd/information/system"
+	"gin-vue-admin/global"
+	"gin-vue-admin/model"
+	gormadapter "github.com/casbin/gorm-adapter/v3"
+	"github.com/gookit/color"
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+	"os"
+	"strings"
+)
+
+type DatabaseInfo struct {
+	Value        string `gorm:"column:Value"`
+	VariableName string `gorm:"column:Variable_name"`
+}
+
+var Mysql = &_mysql{_config: &gorm.Config{}}
+
+type _mysql struct {
+	db      *gorm.DB
+	err     error
+	_config *gorm.Config
+
+	old       string // 配置文件第一次读取数据库数据
+	input     string
+	version   string
+	character string
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: gorm连接mysql数据库
+func (m *_mysql) Init() {
+	if global.GVA_CONFIG.Mysql.LogMode {
+		m._config.Logger = logger.Default.LogMode(logger.Info)
+	} else {
+		m._config.Logger = logger.Default.LogMode(logger.Silent)
+	}
+	m._config.DisableForeignKeyConstraintWhenMigrating = true
+	m.db, m.err = gorm.Open(mysql.New(mysql.Config{
+		DSN:                       global.GVA_CONFIG.Mysql.Dsn(), // DSN data source name
+		DefaultStringSize:         256,                           // string 类型字段的默认长度
+		DisableDatetimePrecision:  true,                          // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
+		DontSupportRenameIndex:    true,                          // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
+		DontSupportRenameColumn:   true,                          // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
+		SkipInitializeWithVersion: false,                         // 根据当前 MySQL 版本自动配置
+	}), m._config)
+	global.GVA_DB = m.db
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: gorm 同步模型 生成mysql表
+func (m *_mysql) AutoMigrateTables() {
+	if !global.GVA_DB.Migrator().HasTable("casbin_rule") {
+		m.err = global.GVA_DB.Migrator().CreateTable(&gormadapter.CasbinRule{})
+	}
+	m.err = m.db.AutoMigrate(
+		new(model.SysApi),
+		new(model.SysUser),
+		new(model.SysBaseMenu),
+		new(model.SysAuthority),
+		new(model.SysDictionary),
+		new(model.JwtBlacklist),
+		new(model.SysOperationRecord),
+		new(model.SysDictionaryDetail),
+		new(model.SysBaseMenuParameter),
+
+		new(model.WorkflowNode),
+		new(model.WorkflowEdge),
+		new(model.WorkflowProcess),
+		new(model.WorkflowEndPoint),
+		new(model.WorkflowStartPoint),
+
+		new(model.ExaFileUploadAndDownload),
+		new(model.ExaFile),
+		new(model.ExaFileChunk),
+	)
+	if m.err != nil {
+		color.Warn.Printf("[Mysql] --> 初始化数据表失败, err: %v\n", m.err)
+		os.Exit(0)
+	}
+	color.Info.Println("[Mysql] --> 初始化数据表成功! ")
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 初始化数据
+func (m *_mysql) InitData() {
+	if m.err = data.Api.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> sys_apis 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.Admin.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> sys_users 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.Casbin.Init(); m.err != nil {
+		color.Error.Println("\n[Mysql] --> casbin_rule 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.BaseMenu.Init(); m.err != nil {
+		color.Error.Println("\n[Mysql] --> sys_base_menus 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.Authority.Init(); m.err != nil {
+		color.Error.Println("\n[Mysql] --> sys_authorities 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.AuthorityMenu.Init(); m.err != nil {
+		color.Error.Println("\n[Mysql] --> authority_menu 视图创建失败!, err:%v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.Dictionary.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> dictionaries 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.AuthoritiesMenus.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> sys_authority_menus 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.DataAuthorities.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> sys_data_authority_id 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.DictionaryDetail.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> sys_dictionary_details 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = data.Workflow.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> 工作流相关 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	if m.err = information.File.Init(); m.err != nil {
+		color.Warn.Println("\n[Mysql] --> exa_file_upload_and_downloads 表初始数据失败, err: %v", m.err)
+		os.Exit(0)
+	}
+	color.Info.Println("\n[Mysql] --> 初始化数据成功!\n")
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 检查数据库是否存在
+func (m *_mysql) CheckDatabase() {
+	var unknownDatabase = fmt.Sprintf("Unknown database '%v'", global.GVA_CONFIG.Mysql.Dbname)
+	m.Init()
+	if m.err != nil {
+		if strings.Split(m.err.Error(), ": ")[1] == unknownDatabase {
+			color.Debug.Print("\n[Mysql] -->配置文件的数据库名为:")
+			color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+			color.Debug.Println("不存在!\n")
+			color.Debug.Println("您的配置文件所配置的数据库不存在,请选择:")
+			color.Debug.Print("0:请自行创建配置文件所配置的数据库名为:")
+			color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
+			color.Debug.Print("1:尝试使用sql为您创建配置文件所配置的数据库名为:")
+			color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
+			color.Debug.Println("2:忽略错误! 注意: 如果不修复, 将会退出初始化数据的进程!")
+			color.Warn.Println("\n注意!!!!!!!")
+			color.Warn.Println("输入1之后,如果配置文件的mysql用户名为root才会有百分百的权限去创建数据库,不是root的话就会跳过创建数据库步骤!\n")
+			color.Debug.Println("请输入指令:")
+			if n, _ := fmt.Scanln(&m.input); n != 0 {
+				if m.input == "1" {
+					if global.GVA_CONFIG.Mysql.Username == "root" {
+						m.database()
+					} else {
+						color.Debug.Print("\n很抱歉,您的配置文件的mysql用户名配置不是root,不确定你有无权限创建数据库,为您跳过创建数据库操作,请自行创建配置文件所配置的数据库名为:")
+						color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
+					}
+				} else if m.input == "2" {
+					os.Exit(0)
+				} else {
+					color.Warn.Println("[Mysql] --> 请自行创建数据库!")
+					os.Exit(0)
+				}
+			}
+		}
+	}
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 检查数据库编码是不是utf8mb4
+func (m *_mysql) CheckUtf8mb4() {
+	m.Character()
+	if m.character != "utf8mb4" {
+		color.Info.Println("您当前的数据库编码不是utf8mb4,请选择:")
+		color.Info.Println("0:请自行修改数据的编码为utf8mb4!")
+		color.Info.Println("1:尝试使用sql为您修改编码为utf8mb4!")
+		color.Info.Println("2:忽略错误! 注意如果不修复,生成初始数据的时候也许或许可能有几率报错的喔!")
+		color.Info.Println("请输入指令:")
+		if n, _ := fmt.Scanln(&m.input); n != 0 {
+			if m.input == "1" {
+				m.utf8mb4()
+			} else if m.input == "2" {
+				return
+			} else {
+				color.Warn.Println("[Mysql] --> 请自行修改数据的编码为utf8mb4!")
+				os.Exit(0)
+			}
+		}
+	}
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 打印数据库基本信息
+func (m *_mysql) Info() {
+	m.Version()
+	color.Debug.Print("\n您当前的数据库版本: ")
+	color.LightGreen.Printf(" {%v} ", m.version)
+	color.Debug.Print(", 使用的数据库是: ")
+	color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+	color.Debug.Print(", 数据库编码是: ")
+	color.LightGreen.Printf(" {%v} \n\n", m.character)
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 获取数据库版本
+func (m *_mysql) Version() {
+	color.Debug.Println("[Mysql] -->获取数据库版本中.......")
+	if err := global.GVA_DB.Raw("SELECT VERSION() AS version;").Scan(&m.version).Error; err != nil {
+		color.Info.Printf("[Mysql] -->获取数据库版本失败! err: %v", err)
+		m.version = "未知版本~~~"
+	}
+	color.Debug.Printf("\n[Mysql] -->获取数据库版本成功!\n")
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 获取数据库编码
+func (m *_mysql) Character() {
+	var info DatabaseInfo
+	color.Debug.Println("\n[Mysql] -->获取数据库编码中.......")
+	if err := global.GVA_DB.Raw("show variables like 'character_set_database' ").Scan(&info).Error; err != nil {
+		color.Error.Printf("[Mysql] -->获取数据库编码失败! err:%v\n", err)
+		m.character = "未知编码~~~"
+	}
+	color.Debug.Println("\n[Mysql] -->获取数据库编码成功!\n")
+	m.character = info.Value
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 设置配置文件的数据库编码为utf8mb4
+func (m *_mysql) utf8mb4() {
+	color.Debug.Print("\n[Mysql] --> 设置数据库名为:")
+	color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+	color.Debug.Print("数据库的编码为utf8mb4中.......\n")
+	if err := global.GVA_DB.Debug().Exec("ALTER DATABASE " + global.GVA_CONFIG.Mysql.Dbname + " CHARACTER SET `utf8mb4` COLLATE `utf8mb4_general_ci`").Error; err != nil {
+		color.Debug.Print("\n[Mysql] --> 设置数据库名为:")
+		color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+		color.Debug.Print("数据库的编码为utf8mb4失败!请手动修改数据库名为:")
+		color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+		color.Debug.Println("的编码为utf8mb4\n")
+		return
+	}
+	color.Info.Print("\n[Mysql] --> 设置数据库名为:")
+	color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+	color.Debug.Print("的编码为utf8mb4成功!\n")
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 创建配置文件的数据库
+func (m *_mysql) database() {
+	m.old = global.GVA_CONFIG.Mysql.Dbname
+	global.GVA_CONFIG.Mysql.Dbname = "mysql"
+	color.Debug.Printf("\n[Mysql] --> 正在连接 mysql 数据库中.......\n")
+	m.Init()
+	if m.err != nil {
+		color.Error.Printf("\n[Mysql] --> 链接 mysql 数据库失败!, err: %v\n", m.err)
+		color.Error.Printf("[Mysql] --> 请自行创建配置文件所需的数据库!\n")
+		os.Exit(0)
+	}
+	color.Debug.Printf("\n[Mysql] --> 连接 mysql 数据库成功\n")
+	global.GVA_CONFIG.Mysql.Dbname = m.old
+	color.Debug.Print("\n[Mysql] --> 正在为您创建数据库名为:")
+	color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+	color.Debug.Print("中.......\n")
+	if m.err = global.GVA_DB.Exec("CREATE DATABASE IF NOT EXISTS " + global.GVA_CONFIG.Mysql.Dbname + " DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;").Error; m.err != nil {
+		color.Debug.Print("\n[Mysql] --> 创建数据库名为:")
+		color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+		color.Debug.Print("失败!请手动修改数据库名为")
+		color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
+		os.Exit(0)
+		return
+	}
+	color.Debug.Print("\n[Mysql] --> 正在为您创建数据库名为:")
+	color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
+	color.Debug.Print("成功!\n")
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 处理零值
+func (m *_mysql) zero() {
+	var info DatabaseInfo
+	color.Info.Println("\n[Mysql]--> 获取数据库数据中.......")
+	if err := global.GVA_DB.Raw("show variables like 'sql_mode';").Scan(&info).Error; err != nil {
+		color.Error.Printf("\n[Mysql]-->获取数据库数据失败! err:%v\n", err)
+	}
+	color.Info.Println("\n[Mysql]--> 处理数据库返回数据.......")
+	var values = strings.Split(info.Value, ",")
+	info.Value = ""
+	for i, value := range values {
+		if value == "NO_ZERO_IN_DATE" || value == "NO_ZERO_DATE" {
+		} else {
+			if i == len(values)-1 {
+				info.Value += value
+			} else {
+				info.Value += value + ","
+			}
+		}
+	}
+	if err := global.GVA_DB.Exec("set global sql_mode='" + info.Value + "';").Error; err != nil {
+		color.Error.Printf("\n[Mysql]--> 设置数据库的零值失效失败! err:%v\n", err)
+		return
+	}
+	color.Info.Println("\n[Mysql]--> 设置数据库零值失效成功")
+}

+ 1 - 1
server/cmd/gva/version.go

@@ -27,7 +27,7 @@ var versionCmd = &cobra.Command{
 	Short: "版本信息",
 	Long:  `版本的长信息`,
 	Run: func(cmd *cobra.Command, args []string) {
-		color.Green.Println("v0.0.3")
+		color.Green.Println("v0.0.4")
 	},
 }
 

+ 17 - 16
server/cmd/datas/files.go → server/cmd/information/extra/file.go

@@ -1,33 +1,34 @@
-package datas
+package information
 
 import (
 	"gin-vue-admin/global"
-	"github.com/gookit/color"
-	"os"
-	"time"
-
 	"gin-vue-admin/model"
+	"github.com/gookit/color"
 	"gorm.io/gorm"
+	"time"
 )
 
-var Files = []model.ExaFileUploadAndDownload{
+var File = new(file)
+
+type file struct{}
+
+var files = []model.ExaFileUploadAndDownload{
 	{global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "10.png", "http://qmplusimg.henrongyi.top/gvalogo.png", "png", "158787308910.png"},
 	{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) {
-	if err := db.Transaction(func(tx *gorm.DB) error {
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: exa_file_upload_and_downloads 表初始化数据
+func (f *file) Init() error {
+	return global.GVA_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表的初始数据已存在!")
+			color.Danger.Println("\n[Mysql] --> exa_file_upload_and_downloads 表初始数据已存在!")
 			return nil
 		}
-		if err := tx.Create(&Files).Error; err != nil { // 遇到错误时回滚事务
+		if err := tx.Create(&files).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
-		color.Info.Println("[Mysql]-->初始数据成功")
+		color.Info.Println("\n[Mysql] --> exa_file_upload_and_downloads 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> exa_file_upload_and_downloads 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
-}
+	})
+}

+ 15 - 12
server/cmd/datas/users.go → server/cmd/information/system/admin.go

@@ -1,33 +1,36 @@
-package datas
+package information
 
 import (
 	"gin-vue-admin/global"
+	"gin-vue-admin/model"
 	"github.com/gookit/color"
-	"os"
 	"time"
 
-	"gin-vue-admin/model"
 	uuid "github.com/satori/go.uuid"
 	"gorm.io/gorm"
 )
 
-var Users = []model.SysUser{
+var Admin = new(admin)
+
+type admin struct{}
+
+var admins = []model.SysUser{
 	{GVA_MODEL: global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, UUID: uuid.NewV4(), Username: "admin", Password: "e10adc3949ba59abbe56e057f20f883e", NickName: "超级管理员", HeaderImg: "http://qmplusimg.henrongyi.top/gva_header.jpg", AuthorityId: "888"},
 	{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) {
-	if err := db.Transaction(func(tx *gorm.DB) error {
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: sys_users 表数据初始化
+func (a *admin) Init() error {
+	return global.GVA_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表的初始数据已存在!")
+			color.Danger.Println("\n[Mysql] --> sys_users 表的初始数据已存在!")
 			return nil
 		}
-		if err := tx.Create(&Users).Error; err != nil { // 遇到错误时回滚事务
+		if err := tx.Create(&admins).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
+		color.Info.Println("\n[Mysql] --> sys_users 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_users 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
+	})
 }

+ 14 - 11
server/cmd/datas/apis.go → server/cmd/information/system/api.go

@@ -1,16 +1,19 @@
-package datas
+package information
 
 import (
 	"gin-vue-admin/global"
 	"gin-vue-admin/model"
 	"github.com/gookit/color"
-	"os"
 	"time"
 
 	"gorm.io/gorm"
 )
 
-var Apis = []model.SysApi{
+var Api = new(api)
+
+type api struct{}
+
+var apis = []model.SysApi{
 	{global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/base/login", "用户登录", "base", "POST"},
 	{global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/user/register", "用户注册", "user", "POST"},
 	{global.GVA_MODEL{ID: 3, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/api/createApi", "创建api", "api", "POST"},
@@ -91,18 +94,18 @@ var Apis = []model.SysApi{
 	{global.GVA_MODEL{ID: 79, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/workflowProcess/completeWorkflowMove", "提交工作流", "workflowProcess", "POST"},
 }
 
-func InitSysApi(db *gorm.DB) {
-	if err := db.Transaction(func(tx *gorm.DB) error {
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: sys_apis 表数据初始化
+func (a *api) Init() error {
+	return global.GVA_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表的初始数据已存在!")
+			color.Danger.Println("\n[Mysql] --> sys_apis 表的初始数据已存在!")
 			return nil
 		}
-		if err := tx.Create(&Apis).Error; err != nil { // 遇到错误时回滚事务
+		if err := tx.Create(&apis).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
+		color.Info.Println("\n[Mysql] --> sys_apis 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_apis 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
+	})
 }

+ 83 - 0
server/cmd/information/system/authorities_menus.go

@@ -0,0 +1,83 @@
+package information
+
+import (
+	"gin-vue-admin/global"
+	"github.com/gookit/color"
+	"gorm.io/gorm"
+)
+
+var AuthoritiesMenus = new(authoritiesMenus)
+
+type authoritiesMenus struct{}
+
+type AuthorityMenus struct {
+	AuthorityId string `gorm:"column:sys_authority_authority_id"`
+	BaseMenuId  uint   `gorm:"column:sys_base_menu_id"`
+}
+
+var authorityMenus = []AuthorityMenus{
+	{"888", 1},
+	{"888", 2},
+	{"888", 3},
+	{"888", 4},
+	{"888", 5},
+	{"888", 6},
+	{"888", 7},
+	{"888", 8},
+	{"888", 9},
+	{"888", 10},
+	{"888", 11},
+	{"888", 12},
+	{"888", 13},
+	{"888", 14},
+	{"888", 15},
+	{"888", 16},
+	{"888", 17},
+	{"888", 18},
+	{"888", 19},
+	{"888", 20},
+	{"888", 21},
+	{"888", 22},
+	{"888", 23},
+	{"888", 24},
+	{"888", 25},
+	{"888", 26},
+	{"888", 27},
+	{"888", 28},
+	{"888", 29},
+	{"8881", 1},
+	{"8881", 2},
+	{"8881", 8},
+	{"9528", 1},
+	{"9528", 2},
+	{"9528", 3},
+	{"9528", 4},
+	{"9528", 5},
+	{"9528", 6},
+	{"9528", 7},
+	{"9528", 8},
+	{"9528", 9},
+	{"9528", 10},
+	{"9528", 11},
+	{"9528", 12},
+	{"9528", 14},
+	{"9528", 15},
+	{"9528", 16},
+	{"9528", 17},
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: sys_authority_menus 表数据初始化
+func (a *authoritiesMenus) Init() error {
+	return global.GVA_DB.Table("sys_authority_menus").Transaction(func(tx *gorm.DB) error {
+		if tx.Where("sys_authority_authority_id IN ('888', '8881', '9528')").Find(&[]AuthorityMenus{}).RowsAffected == 48 {
+			color.Danger.Println("\n[Mysql] --> sys_authority_menus 表的初始数据已存在!")
+			return nil
+		}
+		if err := tx.Create(&authorityMenus).Error; err != nil { // 遇到错误时回滚事务
+			return err
+		}
+		color.Info.Println("\n[Mysql] --> sys_authority_menus 表初始数据成功!")
+		return nil
+	})
+}

+ 36 - 0
server/cmd/information/system/authority.go

@@ -0,0 +1,36 @@
+package information
+
+import (
+	"gin-vue-admin/global"
+	"gin-vue-admin/model"
+	"github.com/gookit/color"
+	"time"
+
+	"gorm.io/gorm"
+)
+
+var Authority = new(authority)
+
+type authority struct{}
+
+var authorities = []model.SysAuthority{
+	{CreatedAt: time.Now(), UpdatedAt: time.Now(), AuthorityId: "888", AuthorityName: "普通用户", ParentId: "0", DefaultRouter: "dashboard"},
+	{CreatedAt: time.Now(), UpdatedAt: time.Now(), AuthorityId: "8881", AuthorityName: "普通用户子角色", ParentId: "888", DefaultRouter: "dashboard"},
+	{CreatedAt: time.Now(), UpdatedAt: time.Now(), AuthorityId: "9528", AuthorityName: "测试角色", ParentId: "0", DefaultRouter: "dashboard"},
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: sys_authorities 表数据初始化
+func (a *authority) Init() error {
+	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
+		if tx.Where("authority_id IN ? ", []string{"888", "9528"}).Find(&[]model.SysAuthority{}).RowsAffected == 2 {
+			color.Danger.Println("\n[Mysql] --> sys_authorities 表的初始数据已存在!")
+			return nil
+		}
+		if err := tx.Create(&authorities).Error; err != nil { // 遇到错误时回滚事务
+			return err
+		}
+		color.Info.Println("\n[Mysql] --> sys_authorities 表初始数据成功!")
+		return nil
+	})
+}

+ 25 - 0
server/cmd/information/system/authority_menu.go

@@ -0,0 +1,25 @@
+package information
+
+import (
+	"gin-vue-admin/global"
+	"gin-vue-admin/model"
+	"github.com/gookit/color"
+)
+
+var AuthorityMenu = new(authorityMenu)
+
+type authorityMenu struct{}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: authority_menu 视图数据初始化
+func (a *authorityMenu) Init() error {
+	if global.GVA_DB.Find(&[]model.SysMenu{}).RowsAffected > 0 {
+		color.Danger.Println("\n[Mysql] --> authority_menu 视图已存在!")
+		return nil
+	}
+	if err := global.GVA_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 {
+		return err
+	}
+	color.Info.Println("\n[Mysql] --> authority_menu 视图创建成功!")
+	return nil
+}

+ 16 - 12
server/cmd/datas/casbins.go → server/cmd/information/system/casbin.go

@@ -1,13 +1,17 @@
-package datas
+package information
 
 import (
+	"gin-vue-admin/global"
 	gormadapter "github.com/casbin/gorm-adapter/v3"
 	"github.com/gookit/color"
 	"gorm.io/gorm"
-	"os"
 )
 
-var Carbines = []gormadapter.CasbinRule{
+var Casbin = new(casbin)
+
+type casbin struct{}
+
+var carbines = []gormadapter.CasbinRule{
 	{PType: "p", V0: "888", V1: "/base/login", V2: "POST"},
 	{PType: "p", V0: "888", V1: "/user/register", V2: "POST"},
 	{PType: "p", V0: "888", V1: "/api/createApi", V2: "POST"},
@@ -164,18 +168,18 @@ var Carbines = []gormadapter.CasbinRule{
 	{PType: "p", V0: "9528", V1: "/autoCode/createTemp", V2: "POST"},
 }
 
-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表的初始数据已存在!")
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: casbin_rule 表数据初始化
+func (c *casbin) Init() error {
+	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
+		if tx.Find(&[]gormadapter.CasbinRule{}).RowsAffected == 154 {
+			color.Danger.Println("\n[Mysql] --> casbin_rule 表的初始数据已存在!")
 			return nil
 		}
-		if err := tx.Create(&Carbines).Error; err != nil { // 遇到错误时回滚事务
+		if err := tx.Create(&carbines).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
+		color.Info.Println("\n[Mysql] --> casbin_rule 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> casbin_rule 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
+	})
 }

+ 40 - 0
server/cmd/information/system/data_authorities.go

@@ -0,0 +1,40 @@
+package information
+
+import (
+	"gin-vue-admin/global"
+	"github.com/gookit/color"
+	"gorm.io/gorm"
+)
+
+var DataAuthorities = new(dataAuthorities)
+
+type dataAuthorities struct{}
+
+type DataAuthority struct {
+	AuthorityId   string `gorm:"column:sys_authority_authority_id"`
+	DataAuthority string `gorm:"column:data_authority_id_authority_id"`
+}
+
+var infos = []DataAuthority{
+	{"888", "888"},
+	{"888", "8881"},
+	{"888", "9528"},
+	{"9528", "8881"},
+	{"9528", "9528"},
+}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: sys_data_authority_id 表数据初始化
+func (d *dataAuthorities) Init() error {
+	return global.GVA_DB.Table("sys_data_authority_id").Transaction(func(tx *gorm.DB) error {
+		if tx.Where("authority_id IN ('888', '9528') ").Find(&[]DataAuthority{}).RowsAffected == 5 {
+			color.Danger.Println("\n[Mysql] --> sys_data_authority_id 表初始数据已存在!")
+			return nil
+		}
+		if err := tx.Create(&infos).Error; err != nil { // 遇到错误时回滚事务
+			return err
+		}
+		color.Info.Println("\n[Mysql] --> sys_data_authority_id 表初始数据成功!")
+		return nil
+	})
+}

+ 18 - 14
server/cmd/datas/dictionaries.go → server/cmd/information/system/dictionary.go

@@ -1,19 +1,25 @@
-package datas
+package information
 
 import (
 	"gin-vue-admin/global"
+	"gin-vue-admin/model"
 	"github.com/gookit/color"
-	"os"
 	"time"
 
-	"gin-vue-admin/model"
 	"gorm.io/gorm"
 )
 
-func InitSysDictionary(db *gorm.DB) {
-	var status = new(bool)
+var Dictionary = new(dictionary)
+
+type dictionary struct{}
+
+var status = new(bool)
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: sys_dictionaries 表数据初始化
+func (d *dictionary) Init() error {
 	*status = true
-	Dictionaries := []model.SysDictionary{
+	var dictionaries = []model.SysDictionary{
 		{GVA_MODEL: global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, Name: "性别", Type: "sex", Status: status, Desc: "性别字典"},
 		{GVA_MODEL: global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, Name: "数据库int类型", Type: "int", Status: status, Desc: "int类型对应的数据库类型"},
 		{GVA_MODEL: global.GVA_MODEL{ID: 3, CreatedAt: time.Now(), UpdatedAt: time.Now()}, Name: "数据库时间日期类型", Type: "time.Time", Status: status, Desc: "数据库时间日期类型"},
@@ -21,17 +27,15 @@ func InitSysDictionary(db *gorm.DB) {
 		{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类型"},
 	}
-	if err := db.Transaction(func(tx *gorm.DB) error {
+	return global.GVA_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表初始数据已存在!")
+			color.Danger.Println("\n[Mysql] --> sys_dictionaries 表初始数据已存在!")
 			return nil
 		}
-		if err := tx.Create(&Dictionaries).Error; err != nil { // 遇到错误时回滚事务
+		if err := tx.Create(&dictionaries).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
+		color.Info.Println("\n[Mysql] --> sys_dictionaries 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_dictionaries 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
-}
+	})
+}

+ 15 - 14
server/cmd/datas/dictionary_details.go → server/cmd/information/system/dictionary_details.go

@@ -1,19 +1,22 @@
-package datas
+package information
 
 import (
 	"gin-vue-admin/global"
+	"gin-vue-admin/model"
 	"github.com/gookit/color"
-	"os"
 	"time"
 
-	"gin-vue-admin/model"
 	"gorm.io/gorm"
 )
 
-func InitSysDictionaryDetail(db *gorm.DB) {
-	status := new(bool)
-	*status = true
-	DictionaryDetail := []model.SysDictionaryDetail{
+var DictionaryDetail = new(dictionaryDetail)
+
+type dictionaryDetail struct{}
+
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: dictionary_details 表数据初始化
+func (d *dictionaryDetail) Init() error {
+	var details = []model.SysDictionaryDetail{
 		{global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "smallint", 1, status, 1, 2},
 		{global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "mediumint", 2, status, 2, 2},
 		{global.GVA_MODEL{ID: 3, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "int", 3, status, 3, 2},
@@ -38,17 +41,15 @@ func InitSysDictionaryDetail(db *gorm.DB) {
 		{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},
 	}
-	if err := db.Transaction(func(tx *gorm.DB) error {
+	return global.GVA_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表的初始数据已存在!")
+			color.Danger.Println("\n[Mysql] --> sys_dictionary_details 表的初始数据已存在!")
 			return nil
 		}
-		if err := tx.Create(&DictionaryDetail).Error; err != nil { // 遇到错误时回滚事务
+		if err := tx.Create(&details).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
+		color.Info.Println("\n[Mysql] --> sys_dictionary_details 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_dictionary_details 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
+	})
 }

+ 16 - 13
server/cmd/datas/menus.go → server/cmd/information/system/menu.go

@@ -1,16 +1,19 @@
-package datas
+package information
 
 import (
 	"gin-vue-admin/global"
+	"gin-vue-admin/model"
 	"github.com/gookit/color"
-	"os"
 	"time"
 
-	"gin-vue-admin/model"
 	"gorm.io/gorm"
 )
 
-var BaseMenus = []model.SysBaseMenu{
+var BaseMenu = new(menu)
+
+type menu struct{}
+
+var menus = []model.SysBaseMenu{
 	{GVA_MODEL: global.GVA_MODEL{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "0", Path: "dashboard", Name: "dashboard", Hidden: false, Component: "view/dashboard/index.vue", Sort: 1, Meta: model.Meta{Title: "仪表盘", Icon: "setting"}},
 	{GVA_MODEL: global.GVA_MODEL{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "0", Path: "about", Name: "about", Component: "view/about/index.vue", Sort: 7, Meta: model.Meta{Title: "关于我们", Icon: "info"}},
 	{GVA_MODEL: global.GVA_MODEL{ID: 3, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, Hidden: false, ParentId: "0", Path: "admin", Name: "superAdmin", Component: "view/superAdmin/index.vue", Sort: 3, Meta: model.Meta{Title: "超级管理员", Icon: "user-solid"}},
@@ -42,18 +45,18 @@ var BaseMenus = []model.SysBaseMenu{
 	{GVA_MODEL: global.GVA_MODEL{ID: 29, CreatedAt: time.Now(), UpdatedAt: time.Now()}, MenuLevel: 0, ParentId: "24", 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) {
-	if err := db.Transaction(func(tx *gorm.DB) error {
-		if tx.Where("id IN ?", []int{1, 23}).Find(&[]model.SysBaseMenu{}).RowsAffected == 2 {
-			color.Danger.Println("sys_base_menus表的初始数据已存在!")
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: sys_base_menus 表数据初始化
+func (m *menu) Init() error {
+	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
+		if tx.Where("id IN ?", []int{1, 29}).Find(&[]model.SysBaseMenu{}).RowsAffected == 2 {
+			color.Danger.Println("\n[Mysql] --> sys_base_menus 表的初始数据已存在!")
 			return nil
 		}
-		if err := tx.Create(&BaseMenus).Error; err != nil { // 遇到错误时回滚事务
+		if err := tx.Create(&menus).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
+		color.Info.Println("\n[Mysql] --> sys_base_menus 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]--> sys_base_menus 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
+	})
 }

+ 11 - 9
server/cmd/datas/sys_workflow.go → server/cmd/information/system/workflow.go

@@ -1,14 +1,17 @@
-package datas
+package information
 
 import (
 	"gin-vue-admin/global"
 	"gin-vue-admin/model"
 	"github.com/gookit/color"
 	"gorm.io/gorm"
-	"os"
 	"time"
 )
 
+var Workflow = new(workflow)
+
+type workflow struct{}
+
 var WorkflowProcess = []model.WorkflowProcess{
 	{ID: "leaveFlow", CreatedAt: time.Now(), UpdatedAt: time.Now(), Name: "leaveFlow", Clazz: "process", Label: "请假流程(演示)", HideIcon: false, Description: "请假流程演示", View: "view/iconList/index.vue"},
 }
@@ -36,8 +39,10 @@ var WorkflowEndPoint = []model.WorkflowEndPoint{
 	{WorkflowEdgeID: "flow1604985881207", GVA_MODEL: global.GVA_MODEL{ID: 33, CreatedAt: time.Now(), UpdatedAt: time.Now()}, X: 517.5, Y: 302, Index: 2},
 }
 
-func InitWkProcess(db *gorm.DB) {
-	if err := db.Transaction(func(tx *gorm.DB) error {
+//@author: [SliverHorn](https://github.com/SliverHorn)
+//@description: 工作流相关 表数据初始化
+func (w *workflow) Init() error {
+	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
 		if err := tx.Create(&WorkflowProcess).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
@@ -53,10 +58,7 @@ func InitWkProcess(db *gorm.DB) {
 		if err := tx.Create(&WorkflowEndPoint).Error; err != nil { // 遇到错误时回滚事务
 			return err
 		}
-
+		color.Info.Println("\n[Mysql] --> 工作流相关 表初始数据成功!")
 		return nil
-	}); err != nil {
-		color.Warn.Printf("[Mysql]-->工作流相关 表的初始数据失败,err: %v\n", err)
-		os.Exit(0)
-	}
+	})
 }

+ 1 - 1
server/config.yaml

@@ -43,7 +43,7 @@ system:
   env: 'public'  # Change to "develop" to skip authentication for development mode
   addr: 8888
   db-type: 'mysql'
-  oss-type: 'local'
+  oss-type: 'local'    # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
   use-multipoint: false
 
 # captcha configuration

+ 4 - 0
server/config/gorm.go

@@ -11,3 +11,7 @@ type Mysql struct {
 	LogMode      bool   `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"`
 	LogZap       string `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"`
 }
+
+func (m *Mysql) Dsn() string {
+	return m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config
+}

+ 2 - 1
server/core/server.go

@@ -30,7 +30,8 @@ func RunWindowsServer() {
 
 	fmt.Printf(`
 	欢迎使用 Gin-Vue-Admin
-	当前版本:V2.3.8
+	当前版本:V2.3.9
+    加群方式:微信号:shouzi_1994 QQ群:622360840
 	默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
 	默认前端文件运行地址:http://127.0.0.1:8080
 	如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee

+ 1 - 0
server/model/sys_authority.go

@@ -14,4 +14,5 @@ type SysAuthority struct {
 	DataAuthorityId []SysAuthority `json:"dataAuthorityId" gorm:"many2many:sys_data_authority_id"`
 	Children        []SysAuthority `json:"children" gorm:"-"`
 	SysBaseMenus    []SysBaseMenu  `json:"menus" gorm:"many2many:sys_authority_menus;"`
+	DefaultRouter   string  		`json:"defaultRouter" gorm:"comment:默认菜单;default:dashboard"`
 }

+ 1 - 0
server/model/sys_base_menu.go

@@ -24,6 +24,7 @@ type Meta struct {
 	DefaultMenu bool   `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"`
 	Title       string `json:"title" gorm:"comment:菜单名"`
 	Icon        string `json:"icon" gorm:"comment:菜单图标"`
+	CloseTab    bool   `json:"closeTab" gorm:"comment:自动关闭tab"`
 }
 
 type SysBaseMenuParameter struct {

+ 1 - 1
server/resource/template/server/router.go.tpl

@@ -7,7 +7,7 @@ import (
 )
 
 func Init{{.StructName}}Router(Router *gin.RouterGroup) {
-	{{.StructName}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()).Use(middleware.OperationRecord())
+	{{.StructName}}Router := Router.Group("{{.Abbreviation}}").Use(middleware.OperationRecord())
 	{
 		{{.StructName}}Router.POST("create{{.StructName}}", v1.Create{{.StructName}})   // 新建{{.StructName}}
 		{{.StructName}}Router.DELETE("delete{{.StructName}}", v1.Delete{{.StructName}}) // 删除{{.StructName}}

+ 11 - 11
server/resource/template/web/table.vue.tpl

@@ -68,14 +68,7 @@
       <el-table-column label="按钮组">
         <template slot-scope="scope">
           <el-button class="table-button" @click="update{{.StructName}}(scope.row)" size="small" type="primary" icon="el-icon-edit">变更</el-button>
-          <el-popover placement="top" width="160" v-model="scope.row.visible">
-            <p>确定要删除吗?</p>
-            <div style="text-align: right; margin: 0">
-              <el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
-              <el-button type="primary" size="mini" @click="delete{{.StructName}}(scope.row)">确定</el-button>
-            </div>
-            <el-button type="danger" icon="el-icon-delete" size="mini" slot="reference">删除</el-button>
-          </el-popover>
+          <el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteRow(scope.row)">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -145,7 +138,6 @@ export default {
     return {
       listApi: get{{ .StructName }}List,
       dialogFormVisible: false,
-      visible: false,
       type: "",
       deleteVisible: false,
       multipleSelection: [],
@@ -208,6 +200,15 @@ export default {
       handleSelectionChange(val) {
         this.multipleSelection = val
       },
+      deleteRow(row){
+        this.$confirm('确定要删除吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+           this.delete{{.StructName}}(row);
+        });
+      },
       async onDelete() {
         const ids = []
         if(this.multipleSelection.length == 0){
@@ -265,7 +266,6 @@ export default {
       };
     },
     async delete{{.StructName}}(row) {
-      this.visible = false;
       const res = await delete{{.StructName}}({ ID: row.ID });
       if (res.code == 0) {
         this.$message({
@@ -317,4 +317,4 @@ export default {
 </script>
 
 <style>
-</style>
+</style>

+ 2 - 2
web/package.json

@@ -1,5 +1,5 @@
 {
-    "name": "qm-plus-vue-page",
+    "name": "gin-vue-admin",
     "version": "0.1.0",
     "private": true,
     "scripts": {
@@ -72,4 +72,4 @@
         "> 1%",
         "last 2 versions"
     ]
-}
+}

+ 4 - 2
web/src/components/chooseImg/index.vue

@@ -3,7 +3,7 @@
     <div style="display:flex;justify-content:space-around;flex-wrap:wrap;padding-top:40px">
       <el-image
         class="header-img-box-list"
-        :src="item.url"
+        :src="(item.url && item.url.slice(0, 4) !== 'http')?path+item.url:item.url"
         v-for="(item,key) in picList"
         :key="key"
         @click.native="chooseImg(item.url,target,targetKey)"
@@ -17,6 +17,7 @@
 </template>
 
 <script>
+const path = process.env.VUE_APP_BASE_API
 import { getFileList } from "@/api/fileUploadAndDownload";
 export default {
   props: {
@@ -26,7 +27,8 @@ export default {
   data() {
     return {
       drawer: false,
-      picList: []
+      picList: [],
+      path:path
     };
   },
   methods: {

+ 2 - 1
web/src/main.js

@@ -47,7 +47,8 @@ Vue.prototype.$echarts = echarts;
 
 console.log(`
        欢迎使用 Gin-Vue-Admin
-       当前版本:V2.3.8
+       当前版本:V2.3.9
+       加群方式:微信:shouzi_1994 QQ群:622360840
        默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
        默认前端文件运行地址:http://127.0.0.1:8080
        如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/docs/coffee

+ 2 - 3
web/src/permission.js

@@ -5,7 +5,6 @@ import getPageTitle from '@/utils/page'
 let asyncRouterFlag = 0
 
 const whiteList = ['login']
-
 router.beforeEach(async(to, from, next) => {
     const token = store.getters['user/token']
         // 在白名单中的判断情况
@@ -13,7 +12,7 @@ router.beforeEach(async(to, from, next) => {
     document.title = getPageTitle(to.meta.title)
     if (whiteList.indexOf(to.name) > -1) {
         if (token) {
-            next({ path: '/layout/dashboard' })
+            next({ name: store.getters["user/userInfo"].authority.defaultRouter })
         } else {
             next()
         }
@@ -21,7 +20,7 @@ router.beforeEach(async(to, from, next) => {
         // 不在白名单中并且已经登陆的时候
         if (token) {
             // 添加flag防止多次获取动态路由和栈溢出
-            if (!asyncRouterFlag) {
+            if (!asyncRouterFlag && store.getters['router/asyncRouters'].length == 0) {
                 asyncRouterFlag++
                 await store.dispatch('router/SetAsyncRouter')
                 const asyncRouters = store.getters['router/asyncRouters']

+ 4 - 2
web/src/store/module/router.js

@@ -8,7 +8,6 @@ const formatRouter = (routes) => {
         if ((!item.children || item.children.every(ch => ch.hidden)) && item.name != '404') {
             routerList.push({ label: item.meta.title, value: item.name })
         }
-        item.meta.hidden = item.hidden
         if (item.children && item.children.length > 0) {
             formatRouter(item.children)
         }
@@ -28,7 +27,7 @@ export const router = {
         // 设置动态路由
         setAsyncRouter(state, asyncRouters) {
             state.asyncRouters = asyncRouters
-        }
+        },
     },
     actions: {
         // 从后台获取动态路由
@@ -73,6 +72,9 @@ export const router = {
         },
         routerList(state) {
             return state.routerList
+        },
+        defaultRouter(state) {
+            return state.defaultRouter
         }
     }
 }

+ 12 - 8
web/src/store/module/user.js

@@ -24,8 +24,8 @@ export const user = {
         LoginOut(state) {
             state.userInfo = {}
             state.token = ""
-            router.push({ name: 'login', replace: true })
             sessionStorage.clear()
+            router.push({ name: 'login', replace: true })
             window.location.reload()
         },
         ResetUserInfo(state, userInfo = {}) {
@@ -35,17 +35,21 @@ export const user = {
         }
     },
     actions: {
-        async LoginIn({ commit }, loginInfo) {
+        async LoginIn({ commit, dispatch, rootGetters, getters }, loginInfo) {
             const res = await login(loginInfo)
             if (res.code == 0) {
                 commit('setUserInfo', res.data.user)
                 commit('setToken', res.data.token)
-                const redirect = router.history.current.query.redirect
-                if (redirect) {
-                    router.push({ path: redirect })
-                } else {
-                    router.push({ path: '/layout/dashboard' })
-                }
+                await dispatch('router/SetAsyncRouter', {}, { root: true })
+                const asyncRouters = rootGetters['router/asyncRouters']
+                router.addRoutes(asyncRouters)
+                // const redirect = router.history.current.query.redirect
+                // console.log(redirect)
+                // if (redirect) {
+                //     router.push({ path: redirect })
+                // } else {
+                    router.push({ name: getters["userInfo"].authority.defaultRouter })
+                // }
                 return true
             }
         },

+ 1 - 2
web/src/view/example/customer/customer.vue

@@ -84,7 +84,6 @@ export default {
     return {
       listApi: getExaCustomerList,
       dialogFormVisible: false,
-      visible: false,
       type: "",
       form: {
         customerName: "",
@@ -119,7 +118,7 @@ export default {
       };
     },
     async deleteCustomer(row) {
-      this.visible = false;
+      row.visible = false;
       const res = await deleteExaCustomer({ ID: row.ID });
       if (res.code == 0) {
         this.$message({

+ 197 - 102
web/src/view/layout/aside/historyComponent/history.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="router-history">
     <el-tabs
-      :closable="!(historys.length==1&&this.$route.name=='dashboard')"
+      :closable="!(historys.length==1&&this.$route.name==defaultRouter)"
       @contextmenu.prevent.native="openContextMenu($event)"
       @tab-click="changeTab"
       @tab-remove="removeTab"
@@ -9,9 +9,9 @@
       v-model="activeValue"
     >
       <el-tab-pane
-        :key="item.name"
+        :key="item.name + JSON.stringify(item.query)+JSON.stringify(item.params)"
         :label="item.meta.title"
-        :name="item.name"
+        :name="item.name + JSON.stringify(item.query)+JSON.stringify(item.params)"
         :tab="item"
         v-for="item in historys"
       ></el-tab-pane>
@@ -27,179 +27,276 @@
   </div>
 </template>
 <script>
+import { mapGetters } from "vuex";
+
 export default {
-  name: 'HistoryComponent',
+  name: "HistoryComponent",
   data() {
     return {
       historys: [],
-      activeValue: 'dashboard',
+      activeValue: "",
       contextMenuVisible: false,
       left: 0,
       top: 0,
       isCollapse: false,
       isMobile: false,
-      rightActive: ''
+      rightActive: ""
+    };
+  },
+  computed: {
+    ...mapGetters("user", ["userInfo"]),
+    defaultRouter() {
+      return this.userInfo.authority.defaultRouter;
     }
   },
   created() {
-    this.$bus.on('mobile', isMobile => {
-      this.isMobile = isMobile
-    })
-    this.$bus.on('collapse', isCollapse => {
-      this.isCollapse = isCollapse
-    })
+    this.$bus.on("mobile", isMobile => {
+      this.isMobile = isMobile;
+    });
+    this.$bus.on("collapse", isCollapse => {
+      this.isCollapse = isCollapse;
+    });
     const initHistorys = [
       {
-        name: 'dashboard',
+        name: this.defaultRouter,
         meta: {
-          title: '仪表盘'
-        }
+          title: "首页"
+        },
+        query: {},
+        params: {}
       }
-    ]
+    ];
     this.historys =
-      JSON.parse(sessionStorage.getItem('historys')) || initHistorys
-    this.setTab(this.$route)
+      JSON.parse(sessionStorage.getItem("historys")) || initHistorys;
+      if(!window.sessionStorage.getItem("activeValue")){
+        this.activeValue = this.$route.name + JSON.stringify(this.$route.query)+JSON.stringify(this.$route.params)
+      }else{
+        this.activeValue = window.sessionStorage.getItem("activeValue");
+      }
+    this.setTab(this.$route);
   },
 
   beforeDestroy() {
-    this.$bus.off('collapse')
-    this.$bus.off('mobile')
+    this.$bus.off("collapse");
+    this.$bus.off("mobile");
   },
   methods: {
     openContextMenu(e) {
-      if (this.historys.length == 1 && this.$route.name == 'dashboard') {
-        return false
+      if (this.historys.length == 1 && this.$route.name == this.defaultRouter) {
+        return false;
       }
       if (e.srcElement.id) {
-        this.contextMenuVisible = true
-        let width
+        this.contextMenuVisible = true;
+        let width;
         if (this.isCollapse) {
-          width = 54
+          width = 54;
         } else {
-          width = 220
+          width = 220;
         }
         if (this.isMobile) {
-          width = 0
+          width = 0;
         }
-        this.left = e.clientX - width
-        this.top = e.clientY + 10
-        this.rightActive = e.srcElement.id.split('-')[1]
+        this.left = e.clientX - width;
+        this.top = e.clientY + 10;
+        this.rightActive = e.srcElement.id.split("-")[1];
       }
     },
     closeAll() {
       this.historys = [
         {
-          name: 'dashboard',
+          name: this.defaultRouter,
           meta: {
-            title: '仪表盘'
-          }
+            title: "首页"
+          },
+          query: {},
+          params: {}
         }
-      ]
-      this.$router.push({ name: 'dashboard' })
-      this.contextMenuVisible = false
-      sessionStorage.setItem('historys', JSON.stringify(this.historys))
+      ];
+      this.$router.push({ name: this.defaultRouter });
+      this.contextMenuVisible = false;
+      sessionStorage.setItem("historys", JSON.stringify(this.historys));
     },
     closeLeft() {
-      let right
-      const rightIndex = this.historys.findIndex(
-        item => {
-          if(item.name == this.rightActive){
-            right = item
-          }
-          return item.name == this.rightActive
+      let right;
+      const rightIndex = this.historys.findIndex(item => {
+        if (
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.rightActive
+        ) {
+          right = item;
         }
-      )
+        return (
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.rightActive
+        );
+      });
       const activeIndex = this.historys.findIndex(
-        item => item.name == this.activeValue
-      )
-      this.historys.splice(0, rightIndex)
+        item =>
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.activeValue
+      );
+      this.historys.splice(0, rightIndex);
       if (rightIndex > activeIndex) {
-        this.$router.push(right)
+        this.$router.push(right);
       }
-      sessionStorage.setItem('historys', JSON.stringify(this.historys))
+      sessionStorage.setItem("historys", JSON.stringify(this.historys));
     },
     closeRight() {
-      let right
-      const leftIndex = this.historys.findIndex(
-        item => {
-          if(item.name == this.rightActive){
-            right = item
-          }
-          return item.name == this.rightActive
+      let right;
+      const leftIndex = this.historys.findIndex(item => {
+        if (
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.rightActive
+        ) {
+          right = item;
         }
-      )
+        return (
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.rightActive
+        );
+      });
       const activeIndex = this.historys.findIndex(
-        item => item.name == this.activeValue
-      )
-      this.historys.splice(leftIndex + 1, this.historys.length)
+        item =>
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.activeValue
+      );
+      this.historys.splice(leftIndex + 1, this.historys.length);
       if (leftIndex < activeIndex) {
-        this.$router.push(right)
+        this.$router.push(right);
       }
-      sessionStorage.setItem('historys', JSON.stringify(this.historys))
+      sessionStorage.setItem("historys", JSON.stringify(this.historys));
     },
     closeOther() {
-      let right
-      this.historys = this.historys.filter(
-        item => {
-          if(item.name == this.rightActive){
-            right = item
-          }
-          return item.name == this.rightActive
+      let right;
+      this.historys = this.historys.filter(item => {
+        if (
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.rightActive
+        ) {
+          right = item;
+        }
+        return (
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          this.rightActive
+        );
+      });
+      this.$router.push(right);
+      sessionStorage.setItem("historys", JSON.stringify(this.historys));
+    },
+    isSame(route1, route2) {
+      if (route1.name != route2.name) {
+        return false;
+      }
+      for (let key in route1.query) {
+        if (route1.query[key] != route2.query[key]) {
+          return false;
         }
-      )
-      this.$router.push(right)
-      sessionStorage.setItem('historys', JSON.stringify(this.historys))
+      }
+      for (let key in route1.params) {
+        if (route1.params[key] != route2.params[key]) {
+          return false;
+        }
+      }
+      return true;
     },
     setTab(route) {
-      if (!this.historys.some(item => item.name == route.name)) {
-        const obj = {}
-        obj.name = route.name
-        obj.meta = route.meta
-        obj.query = route.query
-        obj.params = route.params
-        this.historys.push(obj)
+      if (!this.historys.some(item => this.isSame(item, route))) {
+        const obj = {};
+        obj.name = route.name;
+        obj.meta = route.meta;
+        obj.query = route.query;
+        obj.params = route.params;
+        this.historys.push(obj);
       }
-      this.activeValue = this.$route.name
+      window.sessionStorage.setItem(
+        "activeValue",
+        this.$route.name +
+          JSON.stringify(this.$route.query) +
+          JSON.stringify(this.$route.params)
+      );
     },
     changeTab(component) {
-      const tab = component.$attrs.tab
-      this.$router.push({ name: tab.name,query:tab.query,params:tab.params })
+      const tab = component.$attrs.tab;
+      this.$router.push({
+        name: tab.name,
+        query: tab.query,
+        params: tab.params
+      });
     },
     removeTab(tab) {
-      const index = this.historys.findIndex(item => item.name == tab)
-      if (this.$route.name == tab) {
+      const index = this.historys.findIndex(
+        item =>
+          item.name +
+            JSON.stringify(item.query) +
+            JSON.stringify(item.params) ==
+          tab
+      );
+      if (
+        this.$route.name +
+          JSON.stringify(this.$route.query) +
+          JSON.stringify(this.$route.params) ==
+        tab
+      ) {
         if (this.historys.length == 1) {
-          this.$router.push({ name: 'dashboard' })
+          this.$router.push({ name: this.defaultRouter });
         } else {
           if (index < this.historys.length - 1) {
-            this.$router.push({ name: this.historys[index + 1].name,query:this.historys[index + 1].query,params:this.historys[index + 1].params })
+            this.$router.push({
+              name: this.historys[index + 1].name,
+              query: this.historys[index + 1].query,
+              params: this.historys[index + 1].params
+            });
           } else {
-            this.$router.push({ name: this.historys[index - 1].name,query:this.historys[index - 1].query,params:this.historys[index - 1].params })
+            this.$router.push({
+              name: this.historys[index - 1].name,
+              query: this.historys[index - 1].query,
+              params: this.historys[index - 1].params
+            });
           }
         }
       }
-      this.historys.splice(index, 1)
+      this.historys.splice(index, 1);
     }
   },
   watch: {
     contextMenuVisible() {
       if (this.contextMenuVisible) {
-        document.body.addEventListener('click', () => {
-          this.contextMenuVisible = false
-        })
+        document.body.addEventListener("click", () => {
+          this.contextMenuVisible = false;
+        });
       } else {
-        document.body.removeEventListener('click', () => {
-          this.contextMenuVisible = false
-        })
+        document.body.removeEventListener("click", () => {
+          this.contextMenuVisible = false;
+        });
       }
     },
-    $route(to) {
-      this.historys = this.historys.filter(item => !item.meta.hidden)
-      this.setTab(to)
-      sessionStorage.setItem('historys', JSON.stringify(this.historys))
+    $route(to, now) {
+      this.historys = this.historys.filter(item => !item.meta.closeTab);
+      this.setTab(to);
+      sessionStorage.setItem("historys", JSON.stringify(this.historys));
+      this.activeValue = window.sessionStorage.getItem("activeValue");
+      if (now && to && now.name == to.name) {
+        this.$bus.$emit("reload");
+      }
     }
   }
-}
+};
 </script>
 <style lang="scss">
 .contextmenu {
@@ -224,6 +321,4 @@ export default {
   background: #f2f2f2;
   cursor: pointer;
 }
-
-
 </style>

+ 11 - 4
web/src/view/layout/index.vue

@@ -36,7 +36,7 @@
                <el-col :xs="12" :lg="9" :md="9" :sm="14" :xl="9">
                  <div class="fl-right right-box">
                 <Search />
-                <Screenfull class="screenfull"></Screenfull>
+                <Screenfull class="screenfull" :style="{cursor:'pointer'}"></Screenfull>
                 <el-dropdown>
                   <span class="header-avatar">
                    <CustomPic/>
@@ -67,11 +67,11 @@
         </transition>
         <transition mode="out-in" name="el-fade-in-linear">
           <keep-alive>
-            <router-view  v-loading="loadingFlag"  element-loading-text="正在加载中" class="admin-box" v-if="$route.meta.keepAlive"></router-view>
+            <router-view :key="$route.fullPath" v-loading="loadingFlag"  element-loading-text="正在加载中" class="admin-box" v-if="$route.meta.keepAlive && reloadFlag"></router-view>
           </keep-alive>
         </transition>
         <transition mode="out-in" name="el-fade-in-linear">
-          <router-view  v-loading="loadingFlag"  element-loading-text="正在加载中" class="admin-box" v-if="!$route.meta.keepAlive"></router-view>
+          <router-view :key="$route.fullPath" v-loading="loadingFlag"  element-loading-text="正在加载中" class="admin-box" v-if="!$route.meta.keepAlive && reloadFlag"></router-view>
         </transition>
        <BottomInfo />
       </el-main>
@@ -98,7 +98,7 @@ export default {
       isMobile: false,
       isShadowBg: false,
       loadingFlag:false,
-      
+      reloadFlag:true,
       value: ''
     }
   },
@@ -112,6 +112,12 @@ export default {
   },
   methods: {
     ...mapActions('user', ['LoginOut']),
+    reload(){
+      this.reloadFlag = false
+      this.$nextTick(()=>{
+        this.reloadFlag = true
+      })
+    },
     totalCollapse() {
       this.isCollapse = !this.isCollapse
       this.isSider = !this.isCollapse
@@ -153,6 +159,7 @@ export default {
     }
     this.$bus.emit('collapse', this.isCollapse)
     this.$bus.emit('mobile', this.isMobile)
+    this.$bus.on("reload",this.reload)
     this.$bus.on("showLoading",()=>{
       this.loadingFlag = true
     })

+ 10 - 4
web/src/view/layout/search/search.vue

@@ -19,8 +19,14 @@
         </el-select>
       </div>
     </transition>
+    <div
+      :style="{display:'inline-block',float:'right',width:'31px',textAlign:'left',fontSize:'16px',paddingTop:'2px'}"
+      class="user-box"
+    >
+      <i @click="$bus.$emit('reload')" :style="{cursor:'pointer'}" class="el-icon-refresh" />
+    </div>
     <div :style="{display:'inline-block',float:'right'}" class="user-box">
-      <i @click="showSearch()" class="el-icon-search search-icon"></i>
+      <i :style="{cursor:'pointer'}" @click="showSearch()" class="el-icon-search search-icon"></i>
     </div>
   </div>
 </template>
@@ -48,9 +54,9 @@ export default {
     },
     showSearch() {
       this.show = true;
-      this.$nextTick(()=>{
-        this.$refs['search-input'].focus()
-      })
+      this.$nextTick(() => {
+        this.$refs["search-input"].focus();
+      });
     }
   }
 };

+ 25 - 2
web/src/view/superAdmin/authority/components/menus.vue

@@ -13,12 +13,28 @@
       node-key="ID"
       ref="menuTree"
       show-checkbox
-    ></el-tree>
+    >
+     <span class="custom-tree-node" slot-scope="{ node , data }">
+        <span>{{ node.label }}</span>
+        <span>
+          <el-button
+            type="text"
+            size="mini"
+            :style="{color:row.defaultRouter == data.name?'#E6A23C':'#85ce61'}"
+            :disabled="!node.checked"
+            @click="() => setDefault(data)">
+            {{row.defaultRouter == data.name?"首页":"设为首页"}}
+          </el-button>
+        </span>
+      </span>
+    </el-tree>
   </div>
 </template>
 <script>
 import { getBaseMenuTree, getMenuAuthority, addMenuAuthority } from '@/api/menu'
-
+import {
+  updateAuthority,
+} from "@/api/authority";
 export default {
   name: 'Menus',
   props: {
@@ -43,6 +59,13 @@ export default {
     }
   },
   methods: {
+    async setDefault(data){
+      const res = await updateAuthority({authorityId: this.row.authorityId,AuthorityName: this.row.authorityName,parentId: this.row.parentId,defaultRouter:data.name})
+      if(res.code == 0){
+        this.$message({type:"success",message:"设置成功"})
+        this.row.defaultRouter = res.data.authority.defaultRouter
+      }
+    },
     nodeChange(){
       this.needConfirm = true
     },

+ 1 - 2
web/src/view/superAdmin/dictionary/sysDictionary.vue

@@ -128,7 +128,6 @@ export default {
     return {
       listApi: getSysDictionaryList,
       dialogFormVisible: false,
-      visible: false,
       type: "",
       formData: {
         name: null,
@@ -214,7 +213,7 @@ export default {
       };
     },
     async deleteSysDictionary(row) {
-      this.visible = false;
+      row.visible = false;
       const res = await deleteSysDictionary({ ID: row.ID });
       if (res.code == 0) {
         this.$message({

+ 1 - 2
web/src/view/superAdmin/dictionary/sysDictionaryDetail.vue

@@ -124,7 +124,6 @@ export default {
     return {
       listApi: getSysDictionaryDetailList,
       dialogFormVisible: false,
-      visible: false,
       type: "",
       formData: {
         label: null,
@@ -203,7 +202,7 @@ export default {
       };
     },
     async deleteSysDictionaryDetail(row) {
-      this.visible = false;
+      row.visible = false;
       const res = await deleteSysDictionaryDetail({ ID: row.ID });
       if (res.code == 0) {
         this.$message({

+ 7 - 0
web/src/view/superAdmin/menu/menu.vue

@@ -117,6 +117,12 @@
             <el-option :value="true" label="是"></el-option>
           </el-select>
         </el-form-item>
+        <el-form-item label="closeTab" prop="meta.closeTab" style="width:30%">
+          <el-select placeholder="是否自动关闭tab" v-model="form.meta.closeTab">
+            <el-option :value="false" label="否"></el-option>
+            <el-option :value="true" label="是"></el-option>
+          </el-select>
+        </el-form-item>
       </el-form>
       <div class="warning">新增菜单需要在角色管理内配置权限才可使用</div>
       <div>
@@ -209,6 +215,7 @@ export default {
           title: "",
           icon: "",
           defaultMenu: false,
+          closeTab: false,
           keepAlive: false
         },
         parameters: []

+ 1 - 2
web/src/view/superAdmin/operation/sysOperationRecord.vue

@@ -123,7 +123,6 @@ export default {
     return {
       listApi: getSysOperationRecordList,
       dialogFormVisible: false,
-      visible: false,
       type: "",
       deleteVisible: false,
       multipleSelection: [],
@@ -186,7 +185,7 @@ export default {
       }
     },
     async deleteSysOperationRecord(row) {
-      this.visible = false;
+      row.visible = false;
       const res = await deleteSysOperationRecord({ ID: row.ID });
       if (res.code == 0) {
         this.$message({

+ 0 - 1
web/src/view/systemTools/autoCode/component/fieldDialog.vue

@@ -121,7 +121,6 @@ export default {
   data() {
     return {
       dbfdOptions: [],
-      visible: false,
       dictOptions: [],
       typeSearchOptions: [
         {

+ 1 - 2
web/src/view/workflow/workflowProcess/workflowProcess.vue

@@ -110,7 +110,6 @@ export default {
     return {
       listApi: getWorkflowProcessList,
       dialogFormVisible: false,
-      visible: false,
       deleteVisible: false,
       multipleSelection: []
     };
@@ -191,7 +190,7 @@ export default {
       });
     },
     async deleteWorkflowProcess(row) {
-      this.visible = false;
+      row.visible = false;
       const res = await deleteWorkflowProcess({ id: row.id });
       if (res.code == 0) {
         this.$message({