execute.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package install
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "runtime"
  7. "github.com/xinliangnote/go-gin-api/configs"
  8. "github.com/xinliangnote/go-gin-api/internal/code"
  9. "github.com/xinliangnote/go-gin-api/internal/pkg/core"
  10. "github.com/xinliangnote/go-gin-api/internal/proposal/tablesqls"
  11. "github.com/go-redis/redis/v7"
  12. "github.com/spf13/cast"
  13. "github.com/spf13/viper"
  14. "gorm.io/driver/mysql"
  15. "gorm.io/gorm"
  16. "gorm.io/gorm/schema"
  17. )
  18. type initExecuteRequest struct {
  19. Language string `form:"language" ` // 语言包
  20. RedisAddr string `form:"redis_addr"` // 连接地址,例如:127.0.0.1:6379
  21. RedisPass string `form:"redis_pass"` // 连接密码
  22. RedisDb string `form:"redis_db"` // 连接 db
  23. MySQLAddr string `form:"mysql_addr"`
  24. MySQLUser string `form:"mysql_user"`
  25. MySQLPass string `form:"mysql_pass"`
  26. MySQLName string `form:"mysql_name"`
  27. }
  28. func (h *handler) Execute() core.HandlerFunc {
  29. installTableList := map[string]map[string]string{
  30. "authorized": {
  31. "table_sql": tablesqls.CreateAuthorizedTableSql(),
  32. "table_data_sql": tablesqls.CreateAuthorizedTableDataSql(),
  33. },
  34. "authorized_api": {
  35. "table_sql": tablesqls.CreateAuthorizedAPITableSql(),
  36. "table_data_sql": tablesqls.CreateAuthorizedAPITableDataSql(),
  37. },
  38. "admin": {
  39. "table_sql": tablesqls.CreateAdminTableSql(),
  40. "table_data_sql": tablesqls.CreateAdminTableDataSql(),
  41. },
  42. "admin_menu": {
  43. "table_sql": tablesqls.CreateAdminMenuTableSql(),
  44. "table_data_sql": tablesqls.CreateAdminMenuTableDataSql(),
  45. },
  46. "menu": {
  47. "table_sql": tablesqls.CreateMenuTableSql(),
  48. "table_data_sql": tablesqls.CreateMenuTableDataSql(),
  49. },
  50. "menu_action": {
  51. "table_sql": tablesqls.CreateMenuActionTableSql(),
  52. "table_data_sql": tablesqls.CreateMenuActionTableDataSql(),
  53. },
  54. "cron_task": {
  55. "table_sql": tablesqls.CreateCronTaskTableSql(),
  56. "table_data_sql": "",
  57. },
  58. }
  59. return func(ctx core.Context) {
  60. req := new(initExecuteRequest)
  61. if err := ctx.ShouldBindForm(req); err != nil {
  62. ctx.AbortWithError(core.Error(
  63. http.StatusBadRequest,
  64. code.ParamBindError,
  65. code.Text(code.ParamBindError)).WithError(err),
  66. )
  67. return
  68. }
  69. // region 验证 version
  70. versionStr := runtime.Version()
  71. version := cast.ToFloat32(versionStr[2:6])
  72. if version < configs.MinGoVersion {
  73. ctx.AbortWithError(core.Error(
  74. http.StatusBadRequest,
  75. code.GoVersionError,
  76. code.Text(code.GoVersionError)),
  77. )
  78. return
  79. }
  80. // endregion
  81. // region 验证 Redis 配置
  82. cfg := configs.Get()
  83. redisClient := redis.NewClient(&redis.Options{
  84. Addr: req.RedisAddr,
  85. Password: req.RedisPass,
  86. DB: cast.ToInt(req.RedisDb),
  87. MaxRetries: cfg.Redis.MaxRetries,
  88. PoolSize: cfg.Redis.PoolSize,
  89. MinIdleConns: cfg.Redis.MinIdleConns,
  90. })
  91. if err := redisClient.Ping().Err(); err != nil {
  92. ctx.AbortWithError(core.Error(
  93. http.StatusBadRequest,
  94. code.RedisConnectError,
  95. code.Text(code.RedisConnectError)).WithError(err),
  96. )
  97. return
  98. }
  99. defer redisClient.Close()
  100. outPutString := "已检测 Redis 配置可用。\n"
  101. // endregion
  102. // region 验证 MySQL 配置
  103. dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=%t&loc=%s",
  104. req.MySQLUser,
  105. req.MySQLPass,
  106. req.MySQLAddr,
  107. req.MySQLName,
  108. true,
  109. "Local")
  110. db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  111. NamingStrategy: schema.NamingStrategy{
  112. SingularTable: true,
  113. },
  114. //Logger: logger.Default.LogMode(logger.Info), // 日志配置
  115. })
  116. if err != nil {
  117. ctx.AbortWithError(core.Error(
  118. http.StatusBadRequest,
  119. code.MySQLConnectError,
  120. code.Text(code.MySQLConnectError)).WithError(err),
  121. )
  122. return
  123. }
  124. db.Set("gorm:table_options", "CHARSET=utf8mb4")
  125. dbClient, _ := db.DB()
  126. defer dbClient.Close()
  127. outPutString += "已检测 MySQL 配置可用。\n"
  128. // endregion
  129. // region 写入配置文件
  130. viper.Set("language.local", req.Language)
  131. viper.Set("redis.addr", req.RedisAddr)
  132. viper.Set("redis.pass", req.RedisPass)
  133. viper.Set("redis.db", req.RedisDb)
  134. viper.Set("mysql.read.addr", req.MySQLAddr)
  135. viper.Set("mysql.read.user", req.MySQLUser)
  136. viper.Set("mysql.read.pass", req.MySQLPass)
  137. viper.Set("mysql.read.name", req.MySQLName)
  138. viper.Set("mysql.write.addr", req.MySQLAddr)
  139. viper.Set("mysql.write.user", req.MySQLUser)
  140. viper.Set("mysql.write.pass", req.MySQLPass)
  141. viper.Set("mysql.write.name", req.MySQLName)
  142. if viper.WriteConfig() != nil {
  143. ctx.AbortWithError(core.Error(
  144. http.StatusBadRequest,
  145. code.WriteConfigError,
  146. code.Text(code.WriteConfigError)).WithError(err),
  147. )
  148. return
  149. }
  150. outPutString += "语言包 " + req.Language + " 配置成功。\n"
  151. outPutString += "配置项 Redis、MySQL 配置成功。\n"
  152. // endregion
  153. // region 初始化表结构 + 默认数据
  154. for k, v := range installTableList {
  155. if v["table_sql"] != "" {
  156. // region 初始化表结构
  157. if err = db.Exec(v["table_sql"]).Error; err != nil {
  158. ctx.AbortWithError(core.Error(
  159. http.StatusBadRequest,
  160. code.MySQLExecError,
  161. code.Text(code.MySQLExecError)+" "+err.Error()).WithError(err),
  162. )
  163. return
  164. }
  165. outPutString += "初始化 MySQL 数据表:" + k + " 成功。\n"
  166. // endregion
  167. // region 初始化默认数据
  168. if v["table_data_sql"] != "" {
  169. if err = db.Exec(v["table_data_sql"]).Error; err != nil {
  170. ctx.AbortWithError(core.Error(
  171. http.StatusBadRequest,
  172. code.MySQLExecError,
  173. code.Text(code.MySQLExecError)+" "+err.Error()).WithError(err),
  174. )
  175. return
  176. }
  177. outPutString += "初始化 MySQL 数据表:" + k + " 默认数据成功。\n"
  178. }
  179. // endregion
  180. }
  181. }
  182. // endregion
  183. // region 生成 install 完成标识
  184. f, err := os.Create(configs.ProjectInstallMark)
  185. if err != nil {
  186. ctx.AbortWithError(core.Error(
  187. http.StatusBadRequest,
  188. code.MySQLExecError,
  189. code.Text(code.MySQLExecError)+" "+err.Error()).WithError(err),
  190. )
  191. return
  192. }
  193. defer f.Close()
  194. // endregion
  195. ctx.Payload(outPutString)
  196. }
  197. }