Browse Source

自动初始化整体调试完成

pixel 4 years ago
parent
commit
9b23ef9465

+ 7 - 8
server/api/v1/sys_initdb.go

@@ -5,7 +5,6 @@ import (
 	"gin-vue-admin/model/request"
 	"gin-vue-admin/model/response"
 	"gin-vue-admin/service"
-
 	"go.uber.org/zap"
 
 	"github.com/gin-gonic/gin"
@@ -31,7 +30,7 @@ func InitDB(c *gin.Context) {
 	}
 	if err := service.InitDB(dbInfo); err != nil {
 		global.GVA_LOG.Error("自动创建数据库失败", zap.Any("err", err))
-		response.FailWithMessage("自动创建数据库失败", c)
+		response.FailWithMessage("自动创建数据库失败,请查看后台日志", c)
 		return
 	}
 	response.OkWithData("自动创建数据库成功", c)
@@ -43,17 +42,17 @@ func InitDB(c *gin.Context) {
 // @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
 // @Router /init/checkdb [post]
 func CheckDB(c *gin.Context) {
-	if global.GVA_DB == nil {
+	if global.GVA_DB != nil {
 		global.GVA_LOG.Info("数据库无需初始化")
 		response.OkWithDetailed(gin.H{
-			"needInit":false,
-		},"数据库无需初始化", c)
+			"needInit": false,
+		}, "数据库无需初始化", c)
 		return
-	}else{
+	} else {
 		global.GVA_LOG.Info("前往初始化数据库")
 		response.OkWithDetailed(gin.H{
-			"needInit":true,
-		},"前往初始化数据库", c)
+			"needInit": true,
+		}, "前往初始化数据库", c)
 		return
 	}
 }

+ 5 - 5
server/config.yaml

@@ -54,11 +54,11 @@ captcha:
 
 # mysql connect configuration
 mysql:
-  path: '127.0.0.1:3306'
-  config: 'charset=utf8mb4&parseTime=True&loc=Local'
-  db-name: 'qmPlus'
-  username: 'root'
-  password: 'Aa@6447985'
+  path: ''
+  config: ''
+  db-name: ''
+  username: ''
+  password: ''
   max-idle-conns: 10
   max-open-conns: 100
   log-mode: false

+ 22 - 0
server/middleware/need_init.go

@@ -0,0 +1,22 @@
+package middleware
+
+import (
+	"gin-vue-admin/global"
+	"gin-vue-admin/model/response"
+	"github.com/gin-gonic/gin"
+)
+
+// 处理跨域请求,支持options访问
+func NeedInit() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		if global.GVA_DB == nil {
+			response.OkWithDetailed(gin.H{
+				"needInit": true,
+			}, "前往初始化数据库", c)
+			c.Abort()
+		} else {
+			c.Next()
+		}
+		// 处理请求
+	}
+}

+ 2 - 2
server/model/request/sys_init.go

@@ -3,7 +3,7 @@ package request
 type InitDB struct {
 	Host     string `json:"host"`
 	Port     string `json:"port"`
-	UserName string `json:"user_name" binding:"required"`
+	UserName string `json:"userName" binding:"required"`
 	Password string `json:"password"`
-	DBName   string `json:"db_name" binding:"required"`
+	DBName   string `json:"dbName" binding:"required"`
 }

+ 2 - 2
server/router/sys_initdb.go

@@ -8,7 +8,7 @@ import (
 func InitInitRouter(Router *gin.RouterGroup) {
 	ApiRouter := Router.Group("init")
 	{
-	ApiRouter.POST("initbd", v1.InitDB)   // 创建Api
-	ApiRouter.POST("checkdb", v1.CheckDB)   // 创建Api
+		ApiRouter.POST("initdb", v1.InitDB)   // 创建Api
+		ApiRouter.POST("checkdb", v1.CheckDB) // 创建Api
 	}
 }

+ 59 - 2
server/service/sys_initdb.go

@@ -8,6 +8,8 @@ import (
 	"gin-vue-admin/model/request"
 	"gin-vue-admin/source"
 	"github.com/spf13/viper"
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm"
 )
 
 //@author: [songzhibin97](https://github.com/songzhibin97)
@@ -62,6 +64,7 @@ func InitDB(conf request.InitDB) error {
 	if conf.Host == "" {
 		conf.Host = "127.0.0.1"
 	}
+
 	if conf.Port == "" {
 		conf.Port = "3306"
 	}
@@ -76,11 +79,65 @@ func InitDB(conf request.InitDB) error {
 		"mysql.db-name":  conf.DBName,
 		"mysql.username": conf.UserName,
 		"mysql.password": conf.Password,
+		"mysql.config":   "charset=utf8mb4&parseTime=True&loc=Local",
 	}
 	if err := writeConfig(global.GVA_VP, setting); err != nil {
 		return err
 	}
-	err := initDB(source.Admin,
+	m := global.GVA_CONFIG.Mysql
+	if m.Dbname == "" {
+		return nil
+	}
+
+	linkDns := m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config
+	mysqlConfig := mysql.Config{
+		DSN:                       linkDns, // DSN data source name
+		DefaultStringSize:         191,     // string 类型字段的默认长度
+		DisableDatetimePrecision:  true,    // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
+		DontSupportRenameIndex:    true,    // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
+		DontSupportRenameColumn:   true,    // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
+		SkipInitializeWithVersion: false,   // 根据版本自动配置
+	}
+	if db, err := gorm.Open(mysql.New(mysqlConfig), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}); err != nil {
+		//global.GVA_LOG.Error("MySQL启动异常", zap.Any("err", err))
+		//os.Exit(0)
+		//return nil
+		return nil
+	} else {
+		sqlDB, _ := db.DB()
+		sqlDB.SetMaxIdleConns(m.MaxIdleConns)
+		sqlDB.SetMaxOpenConns(m.MaxOpenConns)
+		global.GVA_DB = db
+	}
+
+	err := global.GVA_DB.AutoMigrate(
+		model.SysUser{},
+		model.SysAuthority{},
+		model.SysApi{},
+		model.SysBaseMenu{},
+		model.SysBaseMenuParameter{},
+		model.JwtBlacklist{},
+		model.SysDictionary{},
+		model.SysDictionaryDetail{},
+		model.ExaFileUploadAndDownload{},
+		model.ExaFile{},
+		model.ExaFileChunk{},
+		model.ExaSimpleUploader{},
+		model.ExaCustomer{},
+		model.SysOperationRecord{},
+		model.WorkflowProcess{},
+		model.WorkflowNode{},
+		model.WorkflowEdge{},
+		model.WorkflowStartPoint{},
+		model.WorkflowEndPoint{},
+		model.WorkflowMove{},
+		model.ExaWfLeave{},
+	)
+	if err != nil {
+		return err
+	}
+	err = initDB(
+		source.Admin,
 		source.Api,
 		source.AuthorityMenu,
 		source.Authority,
@@ -92,7 +149,7 @@ func InitDB(conf request.InitDB) error {
 		source.File,
 		source.BaseMenu,
 		source.Workflow)
-	if err!=nil {
+	if err != nil {
 		return err
 	}
 	return nil

+ 1 - 0
server/source/casbin.go

@@ -176,6 +176,7 @@ var carbines = []gormadapter.CasbinRule{
 //@author: [SliverHorn](https://github.com/SliverHorn)
 //@description: casbin_rule 表数据初始化
 func (c *casbin) Init() error {
+	global.GVA_DB.AutoMigrate(gormadapter.CasbinRule{})
 	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
 		if tx.Find(&[]gormadapter.CasbinRule{}).RowsAffected == 154 {
 			color.Danger.Println("\n[Mysql] --> casbin_rule 表的初始数据已存在!")

+ 12 - 1
web/src/App.vue

@@ -5,9 +5,20 @@
 </template>
 
 <script>
+import { checkDB } from "@/api/initdb"
 export default {
   name: 'app',
-  components: {}
+  async created(){
+    const res = await checkDB()
+    if(res.code == 0 && res.data.needInit){
+      this.$message({
+        type:"info",
+        message:"您是第一次使用,请初始化"
+      })
+        this.$store.commit("user/NeedInit")
+        this.$router.push({name:"init"})
+    }
+  }  
 }
 </script>
 

+ 29 - 0
web/src/api/initdb.js

@@ -0,0 +1,29 @@
+import service from '@/utils/request'
+
+// @Tags InitDB
+// @Summary 初始化用户数据库
+// @Produce  application/json
+// @Param data body request.InitDB true "初始化数据库参数"
+// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}"
+// @Router /init/initdb [post]
+export const initDB = (data) => {
+    return service({
+        url: "/init/initdb",
+        method: 'post',
+        data
+    })
+}
+
+
+// @Tags CheckDB
+// @Summary 初始化用户数据库
+// @Produce  application/json
+// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
+// @Router /init/checkdb [post]
+
+export const checkDB = () => {
+    return service({
+        url: "/init/checkdb",
+        method: 'post',
+    })
+}

+ 1 - 1
web/src/permission.js

@@ -4,7 +4,7 @@ import getPageTitle from '@/utils/page'
 
 let asyncRouterFlag = 0
 
-const whiteList = ['login']
+const whiteList = ['login','init']
 router.beforeEach(async(to, from, next) => {
     const token = store.getters['user/token']
         // 在白名单中的判断情况

+ 16 - 10
web/src/router/index.js

@@ -7,19 +7,25 @@ Vue.use(Router)
 const originalPush = Router.prototype.push
 //修改原型对象中的push方法
 Router.prototype.push = function push(location) {
-   return originalPush.call(this, location).catch(err => err)
+    return originalPush.call(this, location).catch(err => err)
 }
 
 const baseRouters = [{
-        path: '/',
-        redirect: '/login'
-    },
-    {
-        path: '/login',
-        name: 'login',
-        component: () =>
-            import ('@/view/login/login.vue')
-    }
+    path: '/',
+    redirect: '/login'
+},
+{
+    path: "/init",
+    name: 'init',
+    component: () =>
+        import('@/view/init/init.vue')
+},
+{
+    path: '/login',
+    name: 'login',
+    component: () =>
+        import('@/view/login/login.vue')
+}
 ]
 
 // 需要通过后台数据来生成的组件

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

@@ -42,7 +42,10 @@ export const router = {
                 children: []
             }]
             const asyncRouterRes = await asyncMenu()
-            const asyncRouter = asyncRouterRes.data.menus
+            if(asyncRouterRes.code !=0){
+                return
+            }
+            const asyncRouter = asyncRouterRes.data&&asyncRouterRes.data.menus
             asyncRouter.push({
                 path: "404",
                 name: "404",

+ 7 - 0
web/src/store/module/user.js

@@ -21,6 +21,13 @@ export const user = {
             // 这里的 `state` 对象是模块的局部状态
             state.token = token
         },
+        NeedInit(state){
+            state.userInfo = {}
+            state.token = ""
+            sessionStorage.clear()
+            router.push({ name: 'init', replace: true })
+
+        },
         LoginOut(state) {
             state.userInfo = {}
             state.token = ""

+ 106 - 0
web/src/view/init/init.vue

@@ -0,0 +1,106 @@
+<template>
+  <div class="init">
+    <p class="in-one a-fadeinT">欢迎使用GIN-VUE-ADMIN</p>
+    <p class="in-two a-fadeinT">您需要初始化您的数据库并且填充初始数据</p>
+    <div class="form-card in-three a-fadeinB">
+      <el-form ref="form" :model="form" label-width="100px">
+        <el-form-item label="数据库类型">
+          <el-select disabled v-model="form.sqlType" placeholder="请选择">
+            <el-option key="mysql" label="mysql(目前只支持mysql)" value="mysql">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="host">
+          <el-input v-model="form.host" placeholder="请输入数据库链接"></el-input>
+        </el-form-item>
+        <el-form-item label="port">
+          <el-input v-model="form.port" placeholder="请输入数据库端口"></el-input>
+        </el-form-item>
+        <el-form-item label="userName">
+          <el-input v-model="form.userName" placeholder="请输入数据库用户名"></el-input>
+        </el-form-item>
+        <el-form-item label="password">
+          <el-input
+            v-model="form.password"
+            placeholder="请输入数据库密码(没有则为空)"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="dbName">
+          <el-input v-model="form.dbName" placeholder="请输入数据库名称"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <div style="text-align: right">
+            <el-button type="primary" @click="onSubmit">立即初始化</el-button>
+          </div>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+import { initDB } from "@/api/initdb";
+export default {
+  name: "Init",
+  data() {
+    return {
+      form: {
+        sqlType: "mysql",
+        host: "127.0.0.1",
+        port: "3306",
+        userName: "root",
+        password: "",
+        dbName: "gva",
+      },
+    };
+  },
+  methods: {
+    async onSubmit() {
+      const loading = this.$loading({
+        lock: true,
+        text: "正在初始化数据库,请稍候",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+      try {
+        const res = await initDB(this.form);
+        if (res.code == 0) {
+          this.$message({
+            type: "success",
+            message: res.msg,
+          });
+          this.$router.push({name:"login"})
+        }
+          loading.close();
+      } catch (err) {
+          loading.close();
+      }
+    },
+  },
+};
+</script>
+<style lang="scss">
+.init {
+  height: 100vh;
+  flex-direction: column;
+  display: flex;
+  align-items: center;
+  background: #fff;
+}
+.in-one {
+  font-size: 26px;
+  line-height: 98px;
+}
+.in-two {
+  font-size: 22px;
+}
+.form-card {
+  margin-top: 60px;
+  box-shadow: 0px 0px 5px 0px rgba(5, 12, 66, 0.15);
+  width: 60vw;
+  height: auto;
+  background: #fff;
+  padding: 20px;
+  border-radius: 6px;
+}
+</style>