forked from lxh/go-wxhelper
149 lines
4.2 KiB
Go
149 lines
4.2 KiB
Go
|
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
|
||
|
}
|