package orm import ( "fmt" "gitee.ltd/lxh/logger/log" "gorm.io/gorm" "slices" ) // @title checkHasDeletedAt // @description 检查指定表是否有id_del字段 // @param tx *gorm.DB "已开启的事务对象" // @param tableName string "表名" // @return bool "是否包含" func checkHasDeletedAt(tx *gorm.DB, tableName string) bool { var columns []string // SQL语句 sql := fmt.Sprintf("select COLUMN_NAME from information_schema.COLUMNS where table_name = '%s'", tableName) err := tx.Raw(sql).Scan(&columns).Error if err != nil { log.Errorf("查询表字段失败: %v", err.Error()) return false } return slices.Contains(columns, "id_del") } // @title checkHasUpdatedAt // @description 检查指定表是否有updated_at字段 // @param tx *gorm.DB "已开启的事务对象" // @param tableName string "表名" // @return bool "是否包含" func checkHasUpdatedAt(tx *gorm.DB, tableName string) bool { var columns []string // SQL语句 sql := fmt.Sprintf("select COLUMN_NAME from information_schema.COLUMNS where table_name = '%s'", tableName) err := tx.Raw(sql).Scan(&columns).Error if err != nil { log.Errorf("查询表字段失败: %v", err.Error()) return false } return slices.Contains(columns, "updated_at") } // UpdateSortBefore // @description 更新之前处理序号 // @param tx *gorm.DB "已开启的事务对象" // @param model any "模型对象" // @return error "错误信息" func UpdateSortBefore(tx *gorm.DB, tableName, id string, sort int, param string) (err error) { // 查出原来的排序号 var oldSort int err = tx.Table(tableName).Select("`sort`").Where("id = ?", id).Scan(&oldSort).Error if err != nil { log.Errorf("查询老数据失败: %v", err.Error()) return } // 如果相等,啥都不干 if oldSort == sort { return nil } // 查询是否包含 id_del 字段 hasDeletedAt := checkHasDeletedAt(tx, tableName) // 处理排序 // 如果老的排序号小于新的,(老, 新]之间的排序号都要-1 // 如果老的大于新的,[老, 新)排序号-1 if oldSort < sort { // 老的小于新的,[老, 新) + 1 sel := tx.Table(tableName). Where("sort <= ? AND sort > ?", sort, oldSort) if hasDeletedAt { sel.Where("id_del = 0") } if param != "" { sel.Where(param) // 自定义条件 } err = sel.Update("sort", gorm.Expr("sort - 1")).Error } else { // 老的大于新的,[新, 老) + 1 sel := tx.Table(tableName). Where("sort >= ? AND sort < ?", sort, oldSort) if hasDeletedAt { sel.Where("id_del = 0") } if param != "" { sel.Where(param) // 自定义条件 } err = sel.Update("sort", gorm.Expr("sort + 1")).Error } return } // CreateSortBefore // @description 新建之前处理序号 // @param tx *gorm.DB "已开启的事务对象" // @param model any "模型对象" // @return error "错误信息" func CreateSortBefore(tx *gorm.DB, tableName string, sort int, param string) (err error) { // 查询是否包含 id_del 字段 hasDeletedAt := checkHasDeletedAt(tx, tableName) // 处理排序,如果没有传,就会是在最前面 sel := tx.Table(tableName).Where("sort >= ?", sort) if hasDeletedAt { sel.Where("id_del = 0") } if param != "" { sel.Where(param) } err = sel.Update("sort", gorm.Expr("sort + 1")).Error if err != nil { log.Errorf("处理前置排序失败:%v", err) } return } // DealSortAfter // @description 处理序号之后 // @param tx *gorm.DB "已开启的事务对象" // @param modelName string "表名" // @return error "错误信息" func DealSortAfter(tx *gorm.DB, modelName, param string) (err error) { // 保存成功,刷新排序 if param != "" { param = " AND " + param } // 查询是否包含 id_del 字段 hasDeletedAt := checkHasDeletedAt(tx, modelName) if hasDeletedAt { param += " AND id_del = 0" } // 如果有更新时间字段,也更新一下值 updateParam := "" if checkHasUpdatedAt(tx, modelName) { updateParam = ",updated_at = NOW()" } sql := fmt.Sprintf("UPDATE %s a, (SELECT (@i := @i + 1) i, id FROM %s WHERE 1=1 %s order by sort ASC) i, "+ "(SELECT @i := 0) ir SET a.sort = i.i %s WHERE a.id = i.id", modelName, modelName, param, updateParam) err = tx.Exec(sql).Error if err != nil { log.Errorf("刷新排序失败: %v", err.Error()) } return }