// Package platform 提供平台总后台的同步 HTTP 业务逻辑。 package platform import ( "errors" "git.apinb.com/bsm-sdk/core/errcode" "git.apinb.com/bsm-sdk/core/infra" "git.apinb.com/bsm-sdk/core/utils" "git.apinb.com/heqiapp/platforms/backend/api/internal/impl" "git.apinb.com/heqiapp/platforms/backend/api/internal/models" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // UpdateRecordStatus 更新主表状态,停用和归档均保留历史记录。 func UpdateRecordStatus(ctx *gin.Context, model any) { var request struct { Status string `json:"status" binding:"required,max=32"` } if err := ctx.ShouldBindJSON(&request); err != nil { infra.Response.Error(ctx, errcode.ErrInvalidArgument) return } updateAllowedByIdentity(ctx, model, gin.H{"status": request.Status}, []string{"status"}) } // ArchiveRecord 通过 archived 状态实现逻辑删除,不物理删除主数据。 func ArchiveRecord(ctx *gin.Context, model any) { updateAllowedByIdentity(ctx, model, archiveValues(), []string{"status"}) } func newEntity(status string) models.Entity { return models.Entity{Identity: models.NewIdentity(), Status: status, Version: 1} } func listPage[T any](ctx *gin.Context) { page, size := pageSize(ctx) var list []T var total int64 databaseQuery := impl.DBService.Model(new(T)) if err := databaseQuery.Count(&total).Error; err != nil { infra.Response.Error(ctx, err) return } if err := databaseQuery.Order("created_at desc").Offset((page - 1) * size).Limit(size).Find(&list).Error; err != nil { infra.Response.Error(ctx, err) return } response, err := publicResourceResponse(list) if err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, gin.H{"total": total, "list": response}) } func getByIdentity[T any](ctx *gin.Context) { var data T if err := impl.DBService.Where("identity = ?", ctx.Param("identity")).First(&data).Error; err != nil { respondRecordError(ctx, err) return } response, err := publicResourceResponse(data) if err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, response) } func updateAllowedByIdentity(ctx *gin.Context, model any, values map[string]any, allowedFields []string) { values = filterFields(values, allowedFields) if len(values) == 0 { infra.Response.Success(ctx, gin.H{"updated": false}) return } result := impl.DBService.Model(model).Where("identity = ?", ctx.Param("identity")).Updates(values) if result.Error != nil { infra.Response.Error(ctx, result.Error) return } if result.RowsAffected == 0 { infra.Response.Error(ctx, errcode.ErrRecordNotFound) return } infra.Response.Success(ctx, gin.H{"updated": true}) } func updateByIdentity(ctx *gin.Context, model any, values map[string]any) { result := impl.DBService.Model(model).Where("identity = ?", ctx.Param("identity")).Updates(values) if result.Error != nil { infra.Response.Error(ctx, result.Error) return } if result.RowsAffected == 0 { infra.Response.Error(ctx, errcode.ErrRecordNotFound) return } infra.Response.Success(ctx, gin.H{"updated": true}) } func respondRecordError(ctx *gin.Context, err error) { if errors.Is(err, gorm.ErrRecordNotFound) { infra.Response.Error(ctx, errcode.ErrRecordNotFound) return } infra.Response.Error(ctx, err) } func pageSize(ctx *gin.Context) (int, int) { page := utils.String2Int(ctx.DefaultQuery("page", "1")) size := utils.String2Int(ctx.DefaultQuery("size", "20")) if page < 1 { page = 1 } if size < 1 || size > 100 { size = 20 } return page, size } func maskPhone(phone string) string { if len(phone) < 7 { return "***" } return phone[:3] + "****" + phone[len(phone)-4:] }