package user import ( "strings" "time" "git.apinb.com/bsm-sdk/core/errcode" "git.apinb.com/bsm-sdk/core/infra" "git.apinb.com/heqiapp/platforms/backend/api/internal/impl" common "git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common" "git.apinb.com/heqiapp/platforms/backend/api/internal/models" "github.com/gin-gonic/gin" ) // PublicGasStations 提供注册页所需的最小启用气站数据。 func PublicGasStations(ctx *gin.Context) { var list []models.GasBasic if err := impl.DBService.Select("identity", "name", "address").Where("status = ?", common.StatusEnable).Order("name").Find(&list).Error; err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, common.ResourceResponse(list)) } // PublicDeliveryPoints 提供指定气站下的启用配送点。 func PublicDeliveryPoints(ctx *gin.Context) { var gas models.GasBasic if impl.DBService.Where("identity = ? AND status = ?", ctx.Query("gas_identity"), common.StatusEnable).First(&gas).Error != nil { infra.Response.Error(ctx, errcode.ErrRecordNotFound) return } var list []models.DeliveryBasic if err := impl.DBService.Select("identity", "name", "address").Where("gas_basic_id = ? AND status = ?", gas.ID, common.StatusEnable).Order("name").Find(&list).Error; err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, common.ResourceResponse(list)) } // PublicContents 返回已发布内容,支持内容类型筛选。 func PublicContents(ctx *gin.Context) { query := impl.DBService.Where("status = ? AND publish_status = ?", common.StatusEnable, "published") if contentType := strings.TrimSpace(ctx.Query("content_type")); contentType != "" { query = query.Where("content_type = ?", contentType) } var list []models.CmsContent if err := query.Order("created_at desc").Find(&list).Error; err != nil { infra.Response.Error(ctx, err) return } infra.Response.Success(ctx, common.ResourceResponse(list)) } // ConfirmContentRead 记录用户对特定内容版本的确认,幂等号全局唯一。 func ConfirmContentRead(ctx *gin.Context) { account, ok := common.UserAccount(ctx) if !ok { return } var request struct { ContentIdentity string `json:"content_identity" binding:"required"` ClientVersion string `json:"client_version"` DeviceIdentity string `json:"device_identity"` RequestNo string `json:"request_no" binding:"required"` } if ctx.ShouldBindJSON(&request) != nil { infra.Response.Error(ctx, errcode.ErrInvalidArgument) return } var content models.CmsContent if impl.DBService.Where("identity = ? AND publish_status = ?", request.ContentIdentity, "published").First(&content).Error != nil { infra.Response.Error(ctx, errcode.ErrRecordNotFound) return } record := models.CmsContentRead{ Entity: common.NewEntity(common.StatusEnable), UserAccountID: account.ID, CmsContentID: content.ID, VersionNo: content.VersionNo, ShownAt: time.Now(), ConfirmedAt: timePointer(time.Now()), ClientVersion: request.ClientVersion, DeviceIdentity: request.DeviceIdentity, RequestNo: request.RequestNo, } if err := impl.DBService.Create(&record).Error; err != nil { var existing models.CmsContentRead if impl.DBService.Where("request_no = ? AND user_account_id = ?", request.RequestNo, account.ID).First(&existing).Error != nil { infra.Response.Error(ctx, err) return } record = existing } infra.Response.Success(ctx, gin.H{"identity": record.Identity, "content_version": record.VersionNo}) } func timePointer(value time.Time) *time.Time { return &value }