Files
go-gin-api/internal/render/install/execute.go
T
新亮 4c37a7e6b5 feature(1.2.8): swagger 接口文档新增 Security
- 将 middleware 命名为 interceptor
- 将 deploy 命名为 deployments
- 移除 pkg/errno
- 使用 proposal 目录
- 优化代码
2021-11-28 13:25:27 +08:00

229 lines
6.0 KiB
Go

package install
import (
"fmt"
"net/http"
"os"
"runtime"
"github.com/xinliangnote/go-gin-api/configs"
"github.com/xinliangnote/go-gin-api/internal/code"
"github.com/xinliangnote/go-gin-api/internal/pkg/core"
"github.com/xinliangnote/go-gin-api/internal/proposal/tablesqls"
"github.com/go-redis/redis/v7"
"github.com/spf13/cast"
"github.com/spf13/viper"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
type initExecuteRequest struct {
Language string `form:"language" ` // 语言包
RedisAddr string `form:"redis_addr"` // 连接地址,例如:127.0.0.1:6379
RedisPass string `form:"redis_pass"` // 连接密码
RedisDb string `form:"redis_db"` // 连接 db
MySQLAddr string `form:"mysql_addr"`
MySQLUser string `form:"mysql_user"`
MySQLPass string `form:"mysql_pass"`
MySQLName string `form:"mysql_name"`
}
func (h *handler) Execute() core.HandlerFunc {
installTableList := map[string]map[string]string{
"authorized": {
"table_sql": tablesqls.CreateAuthorizedTableSql(),
"table_data_sql": tablesqls.CreateAuthorizedTableDataSql(),
},
"authorized_api": {
"table_sql": tablesqls.CreateAuthorizedAPITableSql(),
"table_data_sql": tablesqls.CreateAuthorizedAPITableDataSql(),
},
"admin": {
"table_sql": tablesqls.CreateAdminTableSql(),
"table_data_sql": tablesqls.CreateAdminTableDataSql(),
},
"admin_menu": {
"table_sql": tablesqls.CreateAdminMenuTableSql(),
"table_data_sql": tablesqls.CreateAdminMenuTableDataSql(),
},
"menu": {
"table_sql": tablesqls.CreateMenuTableSql(),
"table_data_sql": tablesqls.CreateMenuTableDataSql(),
},
"menu_action": {
"table_sql": tablesqls.CreateMenuActionTableSql(),
"table_data_sql": tablesqls.CreateMenuActionTableDataSql(),
},
"cron_task": {
"table_sql": tablesqls.CreateCronTaskTableSql(),
"table_data_sql": "",
},
}
return func(ctx core.Context) {
req := new(initExecuteRequest)
if err := ctx.ShouldBindForm(req); err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ParamBindError,
code.Text(code.ParamBindError)).WithError(err),
)
return
}
// region 验证 version
versionStr := runtime.Version()
version := cast.ToFloat32(versionStr[2:6])
if version < configs.MinGoVersion {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.GoVersionError,
code.Text(code.GoVersionError)),
)
return
}
// endregion
// region 验证 Redis 配置
cfg := configs.Get()
redisClient := redis.NewClient(&redis.Options{
Addr: req.RedisAddr,
Password: req.RedisPass,
DB: cast.ToInt(req.RedisDb),
MaxRetries: cfg.Redis.MaxRetries,
PoolSize: cfg.Redis.PoolSize,
MinIdleConns: cfg.Redis.MinIdleConns,
})
if err := redisClient.Ping().Err(); err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.RedisConnectError,
code.Text(code.RedisConnectError)).WithError(err),
)
return
}
defer redisClient.Close()
outPutString := "已检测 Redis 配置可用。\n"
// endregion
// region 验证 MySQL 配置
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=%t&loc=%s",
req.MySQLUser,
req.MySQLPass,
req.MySQLAddr,
req.MySQLName,
true,
"Local")
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
},
//Logger: logger.Default.LogMode(logger.Info), // 日志配置
})
if err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.MySQLConnectError,
code.Text(code.MySQLConnectError)).WithError(err),
)
return
}
db.Set("gorm:table_options", "CHARSET=utf8mb4")
dbClient, _ := db.DB()
defer dbClient.Close()
outPutString += "已检测 MySQL 配置可用。\n"
// endregion
// region 写入配置文件
viper.Set("language.local", req.Language)
viper.Set("redis.addr", req.RedisAddr)
viper.Set("redis.pass", req.RedisPass)
viper.Set("redis.db", req.RedisDb)
viper.Set("mysql.read.addr", req.MySQLAddr)
viper.Set("mysql.read.user", req.MySQLUser)
viper.Set("mysql.read.pass", req.MySQLPass)
viper.Set("mysql.read.name", req.MySQLName)
viper.Set("mysql.write.addr", req.MySQLAddr)
viper.Set("mysql.write.user", req.MySQLUser)
viper.Set("mysql.write.pass", req.MySQLPass)
viper.Set("mysql.write.name", req.MySQLName)
if viper.WriteConfig() != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.WriteConfigError,
code.Text(code.WriteConfigError)).WithError(err),
)
return
}
outPutString += "语言包 " + req.Language + " 配置成功。\n"
outPutString += "配置项 Redis、MySQL 配置成功。\n"
// endregion
// region 初始化表结构 + 默认数据
for k, v := range installTableList {
if v["table_sql"] != "" {
// region 初始化表结构
if err = db.Exec(v["table_sql"]).Error; err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.MySQLExecError,
code.Text(code.MySQLExecError)+" "+err.Error()).WithError(err),
)
return
}
outPutString += "初始化 MySQL 数据表:" + k + " 成功。\n"
// endregion
// region 初始化默认数据
if v["table_data_sql"] != "" {
if err = db.Exec(v["table_data_sql"]).Error; err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.MySQLExecError,
code.Text(code.MySQLExecError)+" "+err.Error()).WithError(err),
)
return
}
outPutString += "初始化 MySQL 数据表:" + k + " 默认数据成功。\n"
}
// endregion
}
}
// endregion
// region 生成 install 完成标识
f, err := os.Create(configs.ProjectInstallMark)
if err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.MySQLExecError,
code.Text(code.MySQLExecError)+" "+err.Error()).WithError(err),
)
return
}
defer f.Close()
// endregion
ctx.Payload(outPutString)
}
}