You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
12 KiB

  1. package gva
  2. import (
  3. "fmt"
  4. information "gin-vue-admin/cmd/information/extra"
  5. data "gin-vue-admin/cmd/information/system"
  6. "gin-vue-admin/global"
  7. "gin-vue-admin/model"
  8. gormadapter "github.com/casbin/gorm-adapter/v3"
  9. "github.com/gookit/color"
  10. "gorm.io/driver/mysql"
  11. "gorm.io/gorm"
  12. "gorm.io/gorm/logger"
  13. "os"
  14. "strings"
  15. )
  16. type DatabaseInfo struct {
  17. Value string `gorm:"column:Value"`
  18. VariableName string `gorm:"column:Variable_name"`
  19. }
  20. var Mysql = &_mysql{_config: &gorm.Config{}}
  21. type _mysql struct {
  22. db *gorm.DB
  23. err error
  24. _config *gorm.Config
  25. old string // 配置文件第一次读取数据库数据
  26. input string
  27. version string
  28. character string
  29. }
  30. //@author: [SliverHorn](https://github.com/SliverHorn)
  31. //@description: gorm连接mysql数据库
  32. func (m *_mysql) Init() {
  33. if global.GVA_CONFIG.Mysql.LogMode {
  34. m._config.Logger = logger.Default.LogMode(logger.Info)
  35. } else {
  36. m._config.Logger = logger.Default.LogMode(logger.Silent)
  37. }
  38. m._config.DisableForeignKeyConstraintWhenMigrating = true
  39. m.db, m.err = gorm.Open(mysql.New(mysql.Config{
  40. DSN: global.GVA_CONFIG.Mysql.Dsn(), // DSN data source name
  41. DefaultStringSize: 191, // string 类型字段的默认长度
  42. DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
  43. DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
  44. DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
  45. SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
  46. }), m._config)
  47. global.GVA_DB = m.db
  48. }
  49. //@author: [SliverHorn](https://github.com/SliverHorn)
  50. //@description: gorm 同步模型 生成mysql表
  51. func (m *_mysql) AutoMigrateTables() {
  52. if !global.GVA_DB.Migrator().HasTable("casbin_rule") {
  53. m.err = global.GVA_DB.Migrator().CreateTable(&gormadapter.CasbinRule{})
  54. }
  55. m.err = m.db.AutoMigrate(
  56. new(model.SysApi),
  57. new(model.SysUser),
  58. new(model.SysBaseMenu),
  59. new(model.SysAuthority),
  60. new(model.SysDictionary),
  61. new(model.JwtBlacklist),
  62. new(model.SysOperationRecord),
  63. new(model.SysDictionaryDetail),
  64. new(model.SysBaseMenuParameter),
  65. new(model.WorkflowNode),
  66. new(model.WorkflowEdge),
  67. new(model.WorkflowProcess),
  68. new(model.WorkflowEndPoint),
  69. new(model.WorkflowStartPoint),
  70. new(model.ExaFileUploadAndDownload),
  71. new(model.ExaFile),
  72. new(model.ExaFileChunk),
  73. )
  74. if m.err != nil {
  75. color.Warn.Printf("[Mysql] --> 初始化数据表失败, err: %v\n", m.err)
  76. os.Exit(0)
  77. }
  78. color.Info.Println("[Mysql] --> 初始化数据表成功! ")
  79. }
  80. //@author: [SliverHorn](https://github.com/SliverHorn)
  81. //@description: 初始化数据
  82. func (m *_mysql) InitData() {
  83. if m.err = data.Api.Init(); m.err != nil {
  84. color.Warn.Println("\n[Mysql] --> sys_apis 表初始数据失败, err: %v", m.err)
  85. os.Exit(0)
  86. }
  87. if m.err = data.Admin.Init(); m.err != nil {
  88. color.Warn.Println("\n[Mysql] --> sys_users 表初始数据失败, err: %v", m.err)
  89. os.Exit(0)
  90. }
  91. if m.err = data.Casbin.Init(); m.err != nil {
  92. color.Error.Println("\n[Mysql] --> casbin_rule 表初始数据失败, err: %v", m.err)
  93. os.Exit(0)
  94. }
  95. if m.err = data.BaseMenu.Init(); m.err != nil {
  96. color.Error.Println("\n[Mysql] --> sys_base_menus 表初始数据失败, err: %v", m.err)
  97. os.Exit(0)
  98. }
  99. if m.err = data.Authority.Init(); m.err != nil {
  100. color.Error.Println("\n[Mysql] --> sys_authorities 表初始数据失败, err: %v", m.err)
  101. os.Exit(0)
  102. }
  103. if m.err = data.AuthorityMenu.Init(); m.err != nil {
  104. color.Error.Println("\n[Mysql] --> authority_menu 视图创建失败!, err:%v", m.err)
  105. os.Exit(0)
  106. }
  107. if m.err = data.Dictionary.Init(); m.err != nil {
  108. color.Warn.Println("\n[Mysql] --> dictionaries 表初始数据失败, err: %v", m.err)
  109. os.Exit(0)
  110. }
  111. if m.err = data.AuthoritiesMenus.Init(); m.err != nil {
  112. color.Warn.Println("\n[Mysql] --> sys_authority_menus 表初始数据失败, err: %v", m.err)
  113. os.Exit(0)
  114. }
  115. if m.err = data.DataAuthorities.Init(); m.err != nil {
  116. color.Warn.Println("\n[Mysql] --> sys_data_authority_id 表初始数据失败, err: %v", m.err)
  117. os.Exit(0)
  118. }
  119. if m.err = data.DictionaryDetail.Init(); m.err != nil {
  120. color.Warn.Println("\n[Mysql] --> sys_dictionary_details 表初始数据失败, err: %v", m.err)
  121. os.Exit(0)
  122. }
  123. if m.err = data.Workflow.Init(); m.err != nil {
  124. color.Warn.Println("\n[Mysql] --> 工作流相关 表初始数据失败, err: %v", m.err)
  125. os.Exit(0)
  126. }
  127. if m.err = information.File.Init(); m.err != nil {
  128. color.Warn.Println("\n[Mysql] --> exa_file_upload_and_downloads 表初始数据失败, err: %v", m.err)
  129. os.Exit(0)
  130. }
  131. color.Info.Println("\n[Mysql] --> 初始化数据成功!\n")
  132. }
  133. //@author: [SliverHorn](https://github.com/SliverHorn)
  134. //@description: 检查数据库是否存在
  135. func (m *_mysql) CheckDatabase() {
  136. var unknownDatabase = fmt.Sprintf("Unknown database '%v'", global.GVA_CONFIG.Mysql.Dbname)
  137. m.Init()
  138. if m.err != nil {
  139. if strings.Split(m.err.Error(), ": ")[1] == unknownDatabase {
  140. color.Debug.Print("\n[Mysql] -->配置文件的数据库名为:")
  141. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  142. color.Debug.Println("不存在!\n")
  143. color.Debug.Println("您的配置文件所配置的数据库不存在,请选择:")
  144. color.Debug.Print("0:请自行创建配置文件所配置的数据库名为:")
  145. color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
  146. color.Debug.Print("1:尝试使用sql为您创建配置文件所配置的数据库名为:")
  147. color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
  148. color.Debug.Println("2:忽略错误! 注意: 如果不修复, 将会退出初始化数据的进程!")
  149. color.Warn.Println("\n注意!!!!!!!")
  150. color.Warn.Println("输入1之后,如果配置文件的mysql用户名为root才会有百分百的权限去创建数据库,不是root的话就会跳过创建数据库步骤!\n")
  151. color.Debug.Println("请输入指令:")
  152. if n, _ := fmt.Scanln(&m.input); n != 0 {
  153. if m.input == "1" {
  154. if global.GVA_CONFIG.Mysql.Username == "root" {
  155. m.database()
  156. } else {
  157. color.Debug.Print("\n很抱歉,您的配置文件的mysql用户名配置不是root,不确定你有无权限创建数据库,为您跳过创建数据库操作,请自行创建配置文件所配置的数据库名为:")
  158. color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
  159. }
  160. } else if m.input == "2" {
  161. os.Exit(0)
  162. } else {
  163. color.Warn.Println("[Mysql] --> 请自行创建数据库!")
  164. os.Exit(0)
  165. }
  166. }
  167. }
  168. }
  169. }
  170. //@author: [SliverHorn](https://github.com/SliverHorn)
  171. //@description: 检查数据库编码是不是utf8mb4
  172. func (m *_mysql) CheckUtf8mb4() {
  173. m.Character()
  174. if m.character != "utf8mb4" {
  175. color.Info.Println("您当前的数据库编码不是utf8mb4,请选择:")
  176. color.Info.Println("0:请自行修改数据的编码为utf8mb4!")
  177. color.Info.Println("1:尝试使用sql为您修改编码为utf8mb4!")
  178. color.Info.Println("2:忽略错误! 注意如果不修复,生成初始数据的时候也许或许可能有几率报错的喔!")
  179. color.Info.Println("请输入指令:")
  180. if n, _ := fmt.Scanln(&m.input); n != 0 {
  181. if m.input == "1" {
  182. m.utf8mb4()
  183. } else if m.input == "2" {
  184. return
  185. } else {
  186. color.Warn.Println("[Mysql] --> 请自行修改数据的编码为utf8mb4!")
  187. os.Exit(0)
  188. }
  189. }
  190. }
  191. }
  192. //@author: [SliverHorn](https://github.com/SliverHorn)
  193. //@description: 打印数据库基本信息
  194. func (m *_mysql) Info() {
  195. m.Version()
  196. color.Debug.Print("\n您当前的数据库版本: ")
  197. color.LightGreen.Printf(" {%v} ", m.version)
  198. color.Debug.Print(", 使用的数据库是: ")
  199. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  200. color.Debug.Print(", 数据库编码是: ")
  201. color.LightGreen.Printf(" {%v} \n\n", m.character)
  202. }
  203. //@author: [SliverHorn](https://github.com/SliverHorn)
  204. //@description: 获取数据库版本
  205. func (m *_mysql) Version() {
  206. color.Debug.Println("[Mysql] -->获取数据库版本中.......")
  207. if err := global.GVA_DB.Raw("SELECT VERSION() AS version;").Scan(&m.version).Error; err != nil {
  208. color.Info.Printf("[Mysql] -->获取数据库版本失败! err: %v", err)
  209. m.version = "未知版本~~~"
  210. }
  211. color.Debug.Printf("\n[Mysql] -->获取数据库版本成功!\n")
  212. }
  213. //@author: [SliverHorn](https://github.com/SliverHorn)
  214. //@description: 获取数据库编码
  215. func (m *_mysql) Character() {
  216. var info DatabaseInfo
  217. color.Debug.Println("\n[Mysql] -->获取数据库编码中.......")
  218. if err := global.GVA_DB.Raw("show variables like 'character_set_database' ").Scan(&info).Error; err != nil {
  219. color.Error.Printf("[Mysql] -->获取数据库编码失败! err:%v\n", err)
  220. m.character = "未知编码~~~"
  221. }
  222. color.Debug.Println("\n[Mysql] -->获取数据库编码成功!\n")
  223. m.character = info.Value
  224. }
  225. //@author: [SliverHorn](https://github.com/SliverHorn)
  226. //@description: 设置配置文件的数据库编码为utf8mb4
  227. func (m *_mysql) utf8mb4() {
  228. color.Debug.Print("\n[Mysql] --> 设置数据库名为:")
  229. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  230. color.Debug.Print("数据库的编码为utf8mb4中.......\n")
  231. if err := global.GVA_DB.Debug().Exec("ALTER DATABASE " + global.GVA_CONFIG.Mysql.Dbname + " CHARACTER SET `utf8mb4` COLLATE `utf8mb4_general_ci`").Error; err != nil {
  232. color.Debug.Print("\n[Mysql] --> 设置数据库名为:")
  233. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  234. color.Debug.Print("数据库的编码为utf8mb4失败!请手动修改数据库名为:")
  235. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  236. color.Debug.Println("的编码为utf8mb4\n")
  237. return
  238. }
  239. color.Info.Print("\n[Mysql] --> 设置数据库名为:")
  240. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  241. color.Debug.Print("的编码为utf8mb4成功!\n")
  242. }
  243. //@author: [SliverHorn](https://github.com/SliverHorn)
  244. //@description: 创建配置文件的数据库
  245. func (m *_mysql) database() {
  246. m.old = global.GVA_CONFIG.Mysql.Dbname
  247. global.GVA_CONFIG.Mysql.Dbname = "mysql"
  248. color.Debug.Printf("\n[Mysql] --> 正在连接 mysql 数据库中.......\n")
  249. m.Init()
  250. if m.err != nil {
  251. color.Error.Printf("\n[Mysql] --> 链接 mysql 数据库失败!, err: %v\n", m.err)
  252. color.Error.Printf("[Mysql] --> 请自行创建配置文件所需的数据库!\n")
  253. os.Exit(0)
  254. }
  255. color.Debug.Printf("\n[Mysql] --> 连接 mysql 数据库成功\n")
  256. global.GVA_CONFIG.Mysql.Dbname = m.old
  257. color.Debug.Print("\n[Mysql] --> 正在为您创建数据库名为:")
  258. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  259. color.Debug.Print("中.......\n")
  260. 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 {
  261. color.Debug.Print("\n[Mysql] --> 创建数据库名为:")
  262. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  263. color.Debug.Print("失败!请手动修改数据库名为")
  264. color.LightGreen.Printf(" {%v} \n", global.GVA_CONFIG.Mysql.Dbname)
  265. os.Exit(0)
  266. return
  267. }
  268. color.Debug.Print("\n[Mysql] --> 正在为您创建数据库名为:")
  269. color.LightGreen.Printf(" {%v} ", global.GVA_CONFIG.Mysql.Dbname)
  270. color.Debug.Print("成功!\n")
  271. }
  272. //@author: [SliverHorn](https://github.com/SliverHorn)
  273. //@description: 处理零值
  274. func (m *_mysql) zero() {
  275. var info DatabaseInfo
  276. color.Info.Println("\n[Mysql]--> 获取数据库数据中.......")
  277. if err := global.GVA_DB.Raw("show variables like 'sql_mode';").Scan(&info).Error; err != nil {
  278. color.Error.Printf("\n[Mysql]-->获取数据库数据失败! err:%v\n", err)
  279. }
  280. color.Info.Println("\n[Mysql]--> 处理数据库返回数据.......")
  281. var values = strings.Split(info.Value, ",")
  282. info.Value = ""
  283. for i, value := range values {
  284. if value == "NO_ZERO_IN_DATE" || value == "NO_ZERO_DATE" {
  285. } else {
  286. if i == len(values)-1 {
  287. info.Value += value
  288. } else {
  289. info.Value += value + ","
  290. }
  291. }
  292. }
  293. if err := global.GVA_DB.Exec("set global sql_mode='" + info.Value + "';").Error; err != nil {
  294. color.Error.Printf("\n[Mysql]--> 设置数据库的零值失效失败! err:%v\n", err)
  295. return
  296. }
  297. color.Info.Println("\n[Mysql]--> 设置数据库零值失效成功")
  298. }