gorm.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package initialize
  2. import (
  3. "os"
  4. "wails-app/internal/dao"
  5. "go.uber.org/zap"
  6. "gorm.io/gorm"
  7. "wails-app/internal/global"
  8. "wails-app/internal/model/example"
  9. )
  10. func Gorm() *gorm.DB {
  11. switch global.GVA_CONFIG.System.DbType {
  12. case "mysql":
  13. return GormMysql()
  14. case "pgsql":
  15. return GormPgSql()
  16. case "oracle":
  17. return GormOracle()
  18. case "mssql":
  19. return GormMssql()
  20. case "sqlite":
  21. return GormSqlite()
  22. default:
  23. return GormMysql()
  24. }
  25. }
  26. func RegisterTables() {
  27. db := global.GVA_DB
  28. err := db.AutoMigrate(
  29. dao.SysApi{},
  30. dao.SysUser{},
  31. dao.SysBaseMenu{},
  32. dao.JwtBlacklist{},
  33. dao.SysAuthority{},
  34. dao.SysDictionary{},
  35. dao.SysOperationRecord{},
  36. dao.SysDictionaryDetail{},
  37. dao.SysBaseMenuParameter{},
  38. dao.SysBaseMenuBtn{},
  39. dao.SysAuthorityBtn{},
  40. example.ExaFile{},
  41. example.ExaFileChunk{},
  42. dao.ExaFileUploadAndDownload{},
  43. dao.Vehicle{},
  44. dao.VehicleType{},
  45. dao.Owner{},
  46. dao.FeeConfig{},
  47. dao.Booth{},
  48. dao.Channel{},
  49. dao.ParkingLot{},
  50. dao.VehicleRecord{},
  51. dao.PaymentRecord{},
  52. dao.PaymentMethodConfig{},
  53. dao.PaymentEntryConfig{},
  54. dao.PaymentEntryMethod{},
  55. dao.UHFReader{},
  56. dao.DeviceDiscovery{},
  57. dao.DeviceImage{},
  58. dao.Camera{},
  59. dao.Shortlist{},
  60. dao.MonthlyCard{},
  61. dao.DigitalTicket{},
  62. dao.ShiftRecord{},
  63. dao.Printer{},
  64. dao.IncidentRecord{},
  65. dao.DeviceCommandLog{},
  66. )
  67. if err != nil {
  68. global.GVA_LOG.Error("register table failed", zap.Error(err))
  69. os.Exit(0)
  70. }
  71. if err := migrateDeviceDiscoveryIndexes(db); err != nil {
  72. global.GVA_LOG.Error("migrate device discovery indexes failed", zap.Error(err))
  73. os.Exit(0)
  74. }
  75. if err := reconcileParkingLotOccupancy(db); err != nil {
  76. global.GVA_LOG.Error("reconcile parking lot occupancy failed", zap.Error(err))
  77. }
  78. // 操作日志复合索引:created_at 位于 GVA_MODEL 内嵌字段(多表共用,不能加 tag),故显式创建
  79. // 覆盖高频查询:按用户 + 时间筛选操作日志
  80. if err := db.Exec("CREATE INDEX IF NOT EXISTS idx_op_user_time ON sys_operation_records (user_id, created_at)").Error; err != nil {
  81. global.GVA_LOG.Error("create idx_op_user_time failed", zap.Error(err))
  82. }
  83. global.GVA_LOG.Info("register table success")
  84. }
  85. // migrateDeviceDiscoveryIndexes converts the early unique request_id index into a normal index.
  86. // A discovery request legitimately receives multiple device responses.
  87. func migrateDeviceDiscoveryIndexes(db *gorm.DB) error {
  88. const requestIDIndex = "idx_device_discovery_request_id"
  89. if db.Migrator().HasIndex(&dao.DeviceDiscovery{}, requestIDIndex) {
  90. if err := db.Migrator().DropIndex(&dao.DeviceDiscovery{}, requestIDIndex); err != nil {
  91. return err
  92. }
  93. }
  94. return db.Migrator().CreateIndex(&dao.DeviceDiscovery{}, requestIDIndex)
  95. }
  96. // reconcileParkingLotOccupancy 在服务启动时以未出场停车会话为准校准占用数和余位。
  97. func reconcileParkingLotOccupancy(db *gorm.DB) error {
  98. return db.Transaction(func(tx *gorm.DB) error {
  99. var lots []dao.ParkingLot
  100. if err := tx.Find(&lots).Error; err != nil {
  101. return err
  102. }
  103. for _, lot := range lots {
  104. var occupied int64
  105. if err := tx.Model(&dao.VehicleRecord{}).
  106. Where("parking_lot_id = ? AND exit_time IS NULL", lot.ID).
  107. Count(&occupied).Error; err != nil {
  108. return err
  109. }
  110. available := int64(lot.Capacity) - occupied
  111. if available < 0 {
  112. available = 0
  113. }
  114. if err := tx.Model(&lot).UpdateColumns(map[string]interface{}{
  115. "occupied": occupied,
  116. "available": available,
  117. }).Error; err != nil {
  118. return err
  119. }
  120. }
  121. return nil
  122. })
  123. }