.gitignore
This commit is contained in:
@@ -36,6 +36,17 @@ type MongoBaseDO struct {
|
|||||||
IsDeleted bool `bson:"isDeleted" json:"isDeleted" default:"false"`
|
IsDeleted bool `bson:"isDeleted" json:"isDeleted" default:"false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SQLBaseDO SQL数据库基础实体
|
||||||
|
type SQLBaseDO struct {
|
||||||
|
Id uint64 `json:"id"` // 主键ID
|
||||||
|
Creator string `json:"creator"` // 创建人
|
||||||
|
CreatedAt *time.Time `json:"createdAt"` // 创建时间
|
||||||
|
Updater string `json:"updater"` // 更新人
|
||||||
|
UpdatedAt *time.Time `json:"updatedAt"` // 更新时间
|
||||||
|
TenantId string `json:"tenantId"` // 租户ID
|
||||||
|
IsDeleted bool `json:"isDeleted"` // 是否删除
|
||||||
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
UserId interface{} `bson:"userId" json:"userId"` // 用户ID
|
UserId interface{} `bson:"userId" json:"userId"` // 用户ID
|
||||||
UserName interface{} `bson:"userName" json:"userName"` // 用户名
|
UserName interface{} `bson:"userName" json:"userName"` // 用户名
|
||||||
|
|||||||
459
sql/sql.go
Normal file
459
sql/sql.go
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// SQL 业务操作封装
|
||||||
|
// 提供向后兼容的CRUD操作方法,支持 PostgreSQL
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
package sql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gitee.com/red-future---jilin-g/common/beans"
|
||||||
|
"gitee.com/red-future---jilin-g/common/utils"
|
||||||
|
"github.com/gogf/gf/v2/database/gdb"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PageSize = 20
|
||||||
|
)
|
||||||
|
|
||||||
|
type sqlDB struct {
|
||||||
|
noTenantId bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func DB(cache ...bool) *sqlDB {
|
||||||
|
return &sqlDB{
|
||||||
|
noTenantId: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoTenantId 不使用租户过滤
|
||||||
|
func (s *sqlDB) NoTenantId() *sqlDB {
|
||||||
|
s.noTenantId = true
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count 查询总数
|
||||||
|
func (s *sqlDB) Count(ctx context.Context, model *gdb.Model) (int64, error) {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
count, _ := model.Count(ctx)
|
||||||
|
return int64(count), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 插入记录(集合版本)
|
||||||
|
func (s *sqlDB) Insert(ctx context.Context, data interface{}, collection string) ([]any, error) {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
model := g.DB().Model(collection)
|
||||||
|
|
||||||
|
// 处理切片类型数据
|
||||||
|
var resultSlice []any
|
||||||
|
if slice, ok := data.([]interface{}); ok {
|
||||||
|
for _, item := range slice {
|
||||||
|
// 转换为map
|
||||||
|
dataMap := gconv.Map(item)
|
||||||
|
delete(dataMap, "id")
|
||||||
|
|
||||||
|
// 设置租户ID
|
||||||
|
if !g.IsEmpty(user.TenantId) && g.IsEmpty(dataMap["tenant_id"]) {
|
||||||
|
dataMap["tenant_id"] = user.TenantId
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置创建人
|
||||||
|
if !g.IsEmpty(user.UserName) && g.IsEmpty(dataMap["creator"]) {
|
||||||
|
dataMap["creator"] = user.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置更新人
|
||||||
|
if !g.IsEmpty(user.UserName) && g.IsEmpty(dataMap["updater"]) {
|
||||||
|
dataMap["updater"] = user.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置时间
|
||||||
|
now := gtime.Now().Time
|
||||||
|
if g.IsEmpty(dataMap["created_at"]) {
|
||||||
|
dataMap["created_at"] = now
|
||||||
|
}
|
||||||
|
if g.IsEmpty(dataMap["updated_at"]) {
|
||||||
|
dataMap["updated_at"] = now
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置删除标记
|
||||||
|
if g.IsEmpty(dataMap["is_deleted"]) {
|
||||||
|
dataMap["is_deleted"] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resultSlice = append(resultSlice, dataMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量插入
|
||||||
|
result, err := model.Data(resultSlice).Insert(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return []any{id}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单条数据插入
|
||||||
|
dataMap := gconv.Map(data)
|
||||||
|
delete(dataMap, "id")
|
||||||
|
|
||||||
|
// 设置租户ID
|
||||||
|
if !g.IsEmpty(user.TenantId) && g.IsEmpty(dataMap["tenant_id"]) {
|
||||||
|
dataMap["tenant_id"] = user.TenantId
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置创建人
|
||||||
|
if !g.IsEmpty(user.UserName) && g.IsEmpty(dataMap["creator"]) {
|
||||||
|
dataMap["creator"] = user.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置更新人
|
||||||
|
if !g.IsEmpty(user.UserName) && g.IsEmpty(dataMap["updater"]) {
|
||||||
|
dataMap["updater"] = user.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置时间
|
||||||
|
now := gtime.Now().Time
|
||||||
|
if g.IsEmpty(dataMap["created_at"]) {
|
||||||
|
dataMap["created_at"] = now
|
||||||
|
}
|
||||||
|
if g.IsEmpty(dataMap["updated_at"]) {
|
||||||
|
dataMap["updated_at"] = now
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置删除标记
|
||||||
|
if g.IsEmpty(dataMap["is_deleted"]) {
|
||||||
|
dataMap["is_deleted"] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行插入
|
||||||
|
result, err := model.Data(dataMap).Insert(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := result.LastInsertId()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return []any{id}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOne 根据ID查询单条记录
|
||||||
|
func (s *sqlDB) FindOne(ctx context.Context, id string, collection string, result interface{}) error {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
model := g.DB().Model(collection).Where("id", id)
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
return model.Scan(ctx, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOneWithResult 根据ID查询单条记录并返回结果
|
||||||
|
func (s *sqlDB) FindOneWithResult(ctx context.Context, id string, collection string, result interface{}) (interface{}, error) {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
model := g.DB().Model(collection).Where("id", id)
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
err = model.Scan(ctx, result)
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindOneByModel 根据Model查询单条记录
|
||||||
|
func (s *sqlDB) FindOneByModel(ctx context.Context, model *gdb.Model, result interface{}) error {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
return model.Scan(ctx, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find 查询多条记录(集合版本)
|
||||||
|
func (s *sqlDB) Find(ctx context.Context, model *gdb.Model, collection string, result interface{}, page *beans.Page, orderBy []beans.OrderBy) (int64, error) {
|
||||||
|
if model == nil {
|
||||||
|
model = g.DB().Model(collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 分页处理
|
||||||
|
limit := int64(PageSize)
|
||||||
|
offset := int64(0)
|
||||||
|
if page != nil && !g.IsEmpty(page.PageNum) && !g.IsEmpty(page.PageSize) {
|
||||||
|
limit = page.PageSize
|
||||||
|
if limit != -1 {
|
||||||
|
offset = (page.PageNum - 1) * limit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排序处理
|
||||||
|
if orderBy != nil && len(orderBy) > 0 {
|
||||||
|
for _, o := range orderBy {
|
||||||
|
orderStr := string(o.Order)
|
||||||
|
if orderStr == "asc" || orderStr == "ASC" {
|
||||||
|
model = model.OrderAsc(o.Field)
|
||||||
|
} else {
|
||||||
|
model = model.OrderDesc(o.Field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model = model.OrderDesc("created_at")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
if limit != -1 {
|
||||||
|
total, err := s.Count(ctx, model)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if total == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
err = model.Offset(int(offset)).Limit(int(limit)).Scan(ctx, result)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不分页,查询全部
|
||||||
|
err = model.Scan(ctx, result)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取结果集长度
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update 更新记录(ID版本)
|
||||||
|
func (s *sqlDB) Update(ctx context.Context, id string, collection string, data interface{}) (int64, error) {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
model := g.DB().Model(collection).Where("id", id)
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 转换为map
|
||||||
|
dataMap := gconv.Map(data)
|
||||||
|
delete(dataMap, "id")
|
||||||
|
|
||||||
|
// 设置更新人
|
||||||
|
if !g.IsEmpty(user.UserName) && g.IsEmpty(dataMap["updater"]) {
|
||||||
|
dataMap["updater"] = user.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置更新时间
|
||||||
|
dataMap["updated_at"] = gtime.Now().Time
|
||||||
|
|
||||||
|
// 执行更新
|
||||||
|
result, err := model.Data(dataMap).Update(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 软删除(ID版本)
|
||||||
|
func (s *sqlDB) Delete(ctx context.Context, id string, collection string) (int64, error) {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
model := g.DB().Model(collection).Where("id", id)
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 软删除
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"is_deleted": true,
|
||||||
|
"updater": user.UserName,
|
||||||
|
"updated_at": gtime.Now().Time,
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := model.Data(data).Update(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteByModel 软删除(Model版本)
|
||||||
|
func (s *sqlDB) DeleteSoftByModel(ctx context.Context, model *gdb.Model) (int64, error) {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 软删除
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"is_deleted": true,
|
||||||
|
"updater": user.UserName,
|
||||||
|
"updated_at": gtime.Now().Time,
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := model.Data(data).Update(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment 字段自增
|
||||||
|
func (s *sqlDB) Increment(ctx context.Context, id string, collection string, field string, value int64) (int64, error) {
|
||||||
|
user, err := utils.GetUserInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
model := g.DB().Model(collection).Where("id", id)
|
||||||
|
|
||||||
|
// 如果没有调用 noTenantId,则添加 tenantId 过滤
|
||||||
|
if !s.noTenantId && !g.IsEmpty(user.TenantId) {
|
||||||
|
model = model.Where("tenant_id", user.TenantId)
|
||||||
|
}
|
||||||
|
|
||||||
|
model = model.Where("is_deleted", false)
|
||||||
|
|
||||||
|
// 设置更新人和时间
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"updater": user.UserName,
|
||||||
|
"updated_at": gtime.Now().Time,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用原生SQL实现自增
|
||||||
|
data[field] = gdb.Raw(field + " + " + gconv.String(value) + "::bigint")
|
||||||
|
|
||||||
|
// 执行更新
|
||||||
|
result, err := model.Data(data).Update(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return affected, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSoft 软删除(ID版本)
|
||||||
|
func (s *sqlDB) DeleteSoft(ctx context.Context, id string, collection string) (int64, error) {
|
||||||
|
return s.Delete(ctx, id, collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Model 获取Model
|
||||||
|
func (s *sqlDB) Model(collection string) *gdb.Model {
|
||||||
|
return g.DB().Model(collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildUpdateData 构建更新数据
|
||||||
|
func BuildUpdateData(ctx context.Context, req interface{}) (map[string]interface{}, error) {
|
||||||
|
return gconv.Map(req), nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user