This commit is contained in:
2025-12-18 09:54:29 +08:00
parent 1eef314e98
commit 650ada9cc6
25 changed files with 3929 additions and 43 deletions

View File

@@ -0,0 +1,157 @@
package tenant
import (
"quyun/v2/app/errorx"
"quyun/v2/app/http/tenant/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
"github.com/gofiber/fiber/v3"
log "github.com/sirupsen/logrus"
)
// content provides tenant-side read-only content endpoints.
//
// @provider
type content struct{}
// list
//
// @Summary 内容列表(已发布)
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param filter query dto.ContentListFilter true "Filter"
// @Success 200 {object} requests.Pager{items=dto.ContentItem}
//
// @Router /t/:tenant_code/v1/contents [get]
// @Bind tenant local key(tenant)
// @Bind user local key(user)
// @Bind filter query
func (*content) list(ctx fiber.Ctx, tenant *models.Tenant, user *models.User, filter *dto.ContentListFilter) (*requests.Pager, error) {
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": user.ID,
}).Info("tenant.contents.list")
filter.Pagination.Format()
return services.Content.ListPublished(ctx, tenant.ID, user.ID, filter)
}
// show
//
// @Summary 内容详情(可见性+权益校验)
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param contentID path int64 true "ContentID"
// @Success 200 {object} dto.ContentDetail
//
// @Router /t/:tenant_code/v1/contents/:contentID [get]
// @Bind tenant local key(tenant)
// @Bind user local key(user)
// @Bind contentID path
func (*content) show(ctx fiber.Ctx, tenant *models.Tenant, user *models.User, contentID int64) (*dto.ContentDetail, error) {
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": user.ID,
"content_id": contentID,
}).Info("tenant.contents.show")
item, err := services.Content.Detail(ctx, tenant.ID, user.ID, contentID)
if err != nil {
return nil, err
}
return &dto.ContentDetail{
Content: item.Content,
Price: item.Price,
HasAccess: item.HasAccess,
}, nil
}
// previewAssets
//
// @Summary 获取试看资源preview role
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param contentID path int64 true "ContentID"
// @Success 200 {object} dto.ContentAssetsResponse
//
// @Router /t/:tenant_code/v1/contents/:contentID/preview [get]
// @Bind tenant local key(tenant)
// @Bind user local key(user)
// @Bind contentID path
func (*content) previewAssets(ctx fiber.Ctx, tenant *models.Tenant, user *models.User, contentID int64) (*dto.ContentAssetsResponse, error) {
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": user.ID,
"content_id": contentID,
}).Info("tenant.contents.preview_assets")
detail, err := services.Content.Detail(ctx, tenant.ID, user.ID, contentID)
if err != nil {
return nil, err
}
assets, err := services.Content.AssetsByRole(ctx, tenant.ID, contentID, consts.ContentAssetRolePreview)
if err != nil {
return nil, err
}
previewSeconds := int32(detail.Content.PreviewSeconds)
if previewSeconds <= 0 {
previewSeconds = 60
}
return &dto.ContentAssetsResponse{
Content: detail.Content,
Assets: assets,
PreviewSeconds: previewSeconds,
}, nil
}
// mainAssets
//
// @Summary 获取正片资源main role需要已购或免费
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param contentID path int64 true "ContentID"
// @Success 200 {object} dto.ContentAssetsResponse
//
// @Router /t/:tenant_code/v1/contents/:contentID/assets [get]
// @Bind tenant local key(tenant)
// @Bind user local key(user)
// @Bind contentID path
func (*content) mainAssets(ctx fiber.Ctx, tenant *models.Tenant, user *models.User, contentID int64) (*dto.ContentAssetsResponse, error) {
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": user.ID,
"content_id": contentID,
}).Info("tenant.contents.main_assets")
detail, err := services.Content.Detail(ctx, tenant.ID, user.ID, contentID)
if err != nil {
return nil, err
}
if !detail.HasAccess {
return nil, errorx.ErrPermissionDenied.WithMsg("未购买或无权限访问")
}
assets, err := services.Content.AssetsByRole(ctx, tenant.ID, contentID, consts.ContentAssetRoleMain)
if err != nil {
return nil, err
}
return &dto.ContentAssetsResponse{
Content: detail.Content,
Assets: assets,
}, nil
}

View File

@@ -0,0 +1,158 @@
package tenant
import (
"time"
"quyun/v2/app/errorx"
"quyun/v2/app/http/tenant/dto"
"quyun/v2/app/services"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
"github.com/gofiber/fiber/v3"
log "github.com/sirupsen/logrus"
)
// contentAdmin provides tenant-admin content management endpoints.
//
// @provider
type contentAdmin struct{}
func requireTenantAdmin(tenantUser *models.TenantUser) error {
if tenantUser == nil {
return errorx.ErrPermissionDenied
}
if !tenantUser.Role.Contains(consts.TenantUserRoleTenantAdmin) {
return errorx.ErrPermissionDenied
}
return nil
}
// create
//
// @Summary 创建内容(草稿)
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param form body dto.ContentCreateForm true "Form"
// @Success 200 {object} models.Content
//
// @Router /t/:tenant_code/v1/admin/contents [post]
// @Bind tenant local key(tenant)
// @Bind tenantUser local key(tenant_user)
// @Bind form body
func (*contentAdmin) create(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, form *dto.ContentCreateForm) (*models.Content, error) {
if err := requireTenantAdmin(tenantUser); err != nil {
return nil, err
}
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": tenantUser.UserID,
}).Info("tenant.admin.contents.create")
return services.Content.Create(ctx, tenant.ID, tenantUser.UserID, form)
}
// update
//
// @Summary 更新内容(标题/描述/状态等)
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param contentID path int64 true "ContentID"
// @Param form body dto.ContentUpdateForm true "Form"
// @Success 200 {object} models.Content
//
// @Router /t/:tenant_code/v1/admin/contents/:contentID [patch]
// @Bind tenant local key(tenant)
// @Bind tenantUser local key(tenant_user)
// @Bind contentID path
// @Bind form body
func (*contentAdmin) update(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, contentID int64, form *dto.ContentUpdateForm) (*models.Content, error) {
if err := requireTenantAdmin(tenantUser); err != nil {
return nil, err
}
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": tenantUser.UserID,
"content_id": contentID,
}).Info("tenant.admin.contents.update")
return services.Content.Update(ctx, tenant.ID, tenantUser.UserID, contentID, form)
}
// upsertPrice
//
// @Summary 设置内容价格与折扣
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param contentID path int64 true "ContentID"
// @Param form body dto.ContentPriceUpsertForm true "Form"
// @Success 200 {object} models.ContentPrice
//
// @Router /t/:tenant_code/v1/admin/contents/:contentID/price [put]
// @Bind tenant local key(tenant)
// @Bind tenantUser local key(tenant_user)
// @Bind contentID path
// @Bind form body
func (*contentAdmin) upsertPrice(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, contentID int64, form *dto.ContentPriceUpsertForm) (*models.ContentPrice, error) {
if err := requireTenantAdmin(tenantUser); err != nil {
return nil, err
}
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": tenantUser.UserID,
"content_id": contentID,
}).Info("tenant.admin.contents.upsert_price")
return services.Content.UpsertPrice(ctx, tenant.ID, tenantUser.UserID, contentID, form)
}
// attachAsset
//
// @Summary 绑定媒体资源到内容main/cover/preview
// @Tags Tenant
// @Accept json
// @Produce json
// @Param tenant_code path string true "Tenant Code"
// @Param contentID path int64 true "ContentID"
// @Param form body dto.ContentAssetAttachForm true "Form"
// @Success 200 {object} models.ContentAsset
//
// @Router /t/:tenant_code/v1/admin/contents/:contentID/assets [post]
// @Bind tenant local key(tenant)
// @Bind tenantUser local key(tenant_user)
// @Bind contentID path
// @Bind form body
func (*contentAdmin) attachAsset(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, contentID int64, form *dto.ContentAssetAttachForm) (*models.ContentAsset, error) {
if err := requireTenantAdmin(tenantUser); err != nil {
return nil, err
}
log.WithFields(log.Fields{
"tenant_id": tenant.ID,
"user_id": tenantUser.UserID,
"content_id": contentID,
"asset_id": form.AssetID,
"role": form.Role,
}).Info("tenant.admin.contents.attach_asset")
role := form.Role
if role == "" {
role = consts.ContentAssetRoleMain
}
sort := int32(0)
if form.Sort > 0 {
sort = form.Sort
}
return services.Content.AttachAsset(ctx, tenant.ID, tenantUser.UserID, contentID, form.AssetID, role, sort, time.Now())
}

View File

@@ -0,0 +1,43 @@
package dto
import (
"quyun/v2/app/requests"
"quyun/v2/database/models"
)
type ContentListFilter struct {
// Pagination controls paging parameters (page/limit).
requests.Pagination `json:",inline" query:",inline"`
// Keyword filters by title keyword (LIKE).
Keyword *string `json:"keyword,omitempty" query:"keyword"`
}
// ContentItem is a list item with price snapshot and access indicator for current user.
type ContentItem struct {
// Content is the content entity.
Content *models.Content `json:"content,omitempty"`
// Price is the current price settings for the content (may be nil if not set).
Price *models.ContentPrice `json:"price,omitempty"`
// HasAccess indicates whether current user can access main assets (free/owner/purchased).
HasAccess bool `json:"has_access"`
}
// ContentDetail is the detail payload with price snapshot and access indicator for current user.
type ContentDetail struct {
// Content is the content entity.
Content *models.Content `json:"content,omitempty"`
// Price is the current price settings for the content (may be nil if not set).
Price *models.ContentPrice `json:"price,omitempty"`
// HasAccess indicates whether current user can access main assets (free/owner/purchased).
HasAccess bool `json:"has_access"`
}
// ContentAssetsResponse returns assets for either preview or main role.
type ContentAssetsResponse struct {
// Content is the content entity.
Content *models.Content `json:"content,omitempty"`
// Assets is the list of media assets for the requested role (preview/main).
Assets []*models.MediaAsset `json:"assets,omitempty"`
// PreviewSeconds indicates the max preview duration (only meaningful for preview response).
PreviewSeconds int32 `json:"preview_seconds,omitempty"`
}

View File

@@ -0,0 +1,58 @@
package dto
import (
"time"
"quyun/v2/pkg/consts"
)
type ContentCreateForm struct {
// Title is the content title.
Title string `json:"title,omitempty"`
// Description is the content description.
Description string `json:"description,omitempty"`
// Visibility controls who can view the content detail (main assets still require free/purchase).
Visibility consts.ContentVisibility `json:"visibility,omitempty"`
// PreviewSeconds controls preview duration (defaults to 60 when omitted).
PreviewSeconds *int32 `json:"preview_seconds,omitempty"`
}
// ContentUpdateForm updates mutable fields of a content.
type ContentUpdateForm struct {
// Title updates the title when provided.
Title *string `json:"title,omitempty"`
// Description updates the description when provided.
Description *string `json:"description,omitempty"`
// Visibility updates the visibility when provided.
Visibility *consts.ContentVisibility `json:"visibility,omitempty"`
// Status updates the content status when provided (e.g. publish/unpublish).
Status *consts.ContentStatus `json:"status,omitempty"`
// PreviewSeconds updates preview duration when provided (must be > 0).
PreviewSeconds *int32 `json:"preview_seconds,omitempty"`
}
// ContentPriceUpsertForm upserts pricing and discount settings for a content.
type ContentPriceUpsertForm struct {
// PriceAmount is the base price in cents (CNY 分).
PriceAmount int64 `json:"price_amount,omitempty"`
// Currency is fixed to CNY for now.
Currency consts.Currency `json:"currency,omitempty"`
// DiscountType defines the discount algorithm (none/percent/amount).
DiscountType consts.DiscountType `json:"discount_type,omitempty"`
// DiscountValue is interpreted based on DiscountType.
DiscountValue int64 `json:"discount_value,omitempty"`
// DiscountStartAt enables discount from this time (optional).
DiscountStartAt *time.Time `json:"discount_start_at,omitempty"`
// DiscountEndAt disables discount after this time (optional).
DiscountEndAt *time.Time `json:"discount_end_at,omitempty"`
}
// ContentAssetAttachForm attaches a media asset to a content with a role and sort order.
type ContentAssetAttachForm struct {
// AssetID is the media asset id to attach.
AssetID int64 `json:"asset_id,omitempty"`
// Role indicates how this asset is used (main/cover/preview).
Role consts.ContentAssetRole `json:"role,omitempty"`
// Sort controls ordering under the same role.
Sort int32 `json:"sort,omitempty"`
}

View File

@@ -2,8 +2,12 @@ package dto
import "quyun/v2/database/models"
// MeResponse returns the resolved tenant context for the current request.
type MeResponse struct {
Tenant *models.Tenant `json:"tenant,omitempty"`
User *models.User `json:"user,omitempty"`
// Tenant is the resolved tenant by `tenant_code`.
Tenant *models.Tenant `json:"tenant,omitempty"`
// User is the authenticated user derived from JWT `user_id`.
User *models.User `json:"user,omitempty"`
// TenantUser is the membership record of the authenticated user within the tenant.
TenantUser *models.TenantUser `json:"tenant_user,omitempty"`
}

View File

@@ -7,6 +7,8 @@ import (
"github.com/gofiber/fiber/v3"
)
// me provides tenant context introspection endpoints (current tenant/user/tenant_user).
//
// @provider
type me struct{}

View File

@@ -10,6 +10,20 @@ import (
)
func Provide(opts ...opt.Option) error {
if err := container.Container.Provide(func() (*content, error) {
obj := &content{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*contentAdmin, error) {
obj := &contentAdmin{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*me, error) {
obj := &me{}
@@ -18,12 +32,16 @@ func Provide(opts ...opt.Option) error {
return err
}
if err := container.Container.Provide(func(
content *content,
contentAdmin *contentAdmin,
me *me,
middlewares *middlewares.Middlewares,
) (contracts.HttpRoute, error) {
obj := &Routes{
me: me,
middlewares: middlewares,
content: content,
contentAdmin: contentAdmin,
me: me,
middlewares: middlewares,
}
if err := obj.Prepare(); err != nil {
return nil, err

View File

@@ -5,6 +5,7 @@
package tenant
import (
"quyun/v2/app/http/tenant/dto"
"quyun/v2/app/middlewares"
"quyun/v2/database/models"
@@ -23,7 +24,9 @@ type Routes struct {
log *log.Entry `inject:"false"`
middlewares *middlewares.Middlewares
// Controller instances
me *me
content *content
contentAdmin *contentAdmin
me *me
}
// Prepare initializes the routes provider with logging configuration.
@@ -41,6 +44,67 @@ func (r *Routes) Name() string {
// Register registers all HTTP routes with the provided fiber router.
// Each route is registered with its corresponding controller action and parameter bindings.
func (r *Routes) Register(router fiber.Router) {
// Register routes for controller: content
r.log.Debugf("Registering route: Get /t/:tenant_code/v1/contents -> content.list")
router.Get("/t/:tenant_code/v1/contents"[len(r.Path()):], DataFunc3(
r.content.list,
Local[*models.Tenant]("tenant"),
Local[*models.User]("user"),
Query[dto.ContentListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /t/:tenant_code/v1/contents/:contentID -> content.show")
router.Get("/t/:tenant_code/v1/contents/:contentID"[len(r.Path()):], DataFunc3(
r.content.show,
Local[*models.Tenant]("tenant"),
Local[*models.User]("user"),
PathParam[int64]("contentID"),
))
r.log.Debugf("Registering route: Get /t/:tenant_code/v1/contents/:contentID/assets -> content.mainAssets")
router.Get("/t/:tenant_code/v1/contents/:contentID/assets"[len(r.Path()):], DataFunc3(
r.content.mainAssets,
Local[*models.Tenant]("tenant"),
Local[*models.User]("user"),
PathParam[int64]("contentID"),
))
r.log.Debugf("Registering route: Get /t/:tenant_code/v1/contents/:contentID/preview -> content.previewAssets")
router.Get("/t/:tenant_code/v1/contents/:contentID/preview"[len(r.Path()):], DataFunc3(
r.content.previewAssets,
Local[*models.Tenant]("tenant"),
Local[*models.User]("user"),
PathParam[int64]("contentID"),
))
// Register routes for controller: contentAdmin
r.log.Debugf("Registering route: Patch /t/:tenant_code/v1/admin/contents/:contentID -> contentAdmin.update")
router.Patch("/t/:tenant_code/v1/admin/contents/:contentID"[len(r.Path()):], DataFunc4(
r.contentAdmin.update,
Local[*models.Tenant]("tenant"),
Local[*models.TenantUser]("tenant_user"),
PathParam[int64]("contentID"),
Body[dto.ContentUpdateForm]("form"),
))
r.log.Debugf("Registering route: Post /t/:tenant_code/v1/admin/contents -> contentAdmin.create")
router.Post("/t/:tenant_code/v1/admin/contents"[len(r.Path()):], DataFunc3(
r.contentAdmin.create,
Local[*models.Tenant]("tenant"),
Local[*models.TenantUser]("tenant_user"),
Body[dto.ContentCreateForm]("form"),
))
r.log.Debugf("Registering route: Post /t/:tenant_code/v1/admin/contents/:contentID/assets -> contentAdmin.attachAsset")
router.Post("/t/:tenant_code/v1/admin/contents/:contentID/assets"[len(r.Path()):], DataFunc4(
r.contentAdmin.attachAsset,
Local[*models.Tenant]("tenant"),
Local[*models.TenantUser]("tenant_user"),
PathParam[int64]("contentID"),
Body[dto.ContentAssetAttachForm]("form"),
))
r.log.Debugf("Registering route: Put /t/:tenant_code/v1/admin/contents/:contentID/price -> contentAdmin.upsertPrice")
router.Put("/t/:tenant_code/v1/admin/contents/:contentID/price"[len(r.Path()):], DataFunc4(
r.contentAdmin.upsertPrice,
Local[*models.Tenant]("tenant"),
Local[*models.TenantUser]("tenant_user"),
PathParam[int64]("contentID"),
Body[dto.ContentPriceUpsertForm]("form"),
))
// Register routes for controller: me
r.log.Debugf("Registering route: Get /t/:tenant_code/v1/me -> me.get")
router.Get("/t/:tenant_code/v1/me"[len(r.Path()):], DataFunc3(

View File

@@ -5,9 +5,13 @@ import (
"quyun/v2/providers/jwt"
)
// Middlewares provides reusable Fiber middlewares shared across modules.
//
// @provider
type Middlewares struct {
// log is the module logger injected by the framework.
log *log.Entry `inject:"false"`
// jwt is the JWT provider used by auth-related middlewares.
jwt *jwt.JWT
}

View File

@@ -1,6 +1,7 @@
package middlewares
import (
"go.ipao.vip/atom/container"
"quyun/v2/app/errorx"
"quyun/v2/app/services"
"quyun/v2/database/models"
@@ -8,7 +9,6 @@ import (
"quyun/v2/providers/jwt"
"github.com/gofiber/fiber/v3"
"github.com/sirupsen/logrus"
)
func (f *Middlewares) TenantResolve(c fiber.Ctx) error {
@@ -19,9 +19,15 @@ func (f *Middlewares) TenantResolve(c fiber.Ctx) error {
tenantModel, err := services.Tenant.FindByCode(c, tenantCode)
if err != nil {
f.log.WithField("tenant_code", tenantCode).WithError(err).Warn("middlewares.tenant.resolve.failed")
return err
}
f.log.WithFields(map[string]any{
"tenant_id": tenantModel.ID,
"tenant_code": tenantCode,
}).Info("middlewares.tenant.resolve.ok")
c.Locals(consts.CtxKeyTenant, tenantModel)
return c.Next()
}
@@ -29,12 +35,24 @@ func (f *Middlewares) TenantResolve(c fiber.Ctx) error {
func (f *Middlewares) TenantAuth(c fiber.Ctx) error {
authHeader := c.Get(jwt.HttpHeader)
if authHeader == "" {
f.log.Info("middlewares.tenant.auth.missing_token")
return errorx.ErrTokenMissing
}
logrus.Infof("Token: %s", authHeader)
claims, err := f.jwt.Parse(authHeader)
jwtProvider := f.jwt
if jwtProvider == nil {
if err := container.Container.Invoke(func(j *jwt.JWT) {
jwtProvider = j
f.jwt = j
}); err != nil {
f.log.WithError(err).Error("middlewares.tenant.auth.jwt_provider_missing")
return errorx.ErrInternalError.WithMsg("jwt provider missing")
}
}
claims, err := jwtProvider.Parse(authHeader)
if err != nil {
f.log.WithError(err).Warn("middlewares.tenant.auth.invalid_token")
switch err {
case jwt.TokenExpired:
return errorx.ErrTokenExpired
@@ -45,9 +63,14 @@ func (f *Middlewares) TenantAuth(c fiber.Ctx) error {
}
}
if claims.UserID == 0 {
f.log.Warn("middlewares.tenant.auth.missing_user_id")
return errorx.ErrTokenInvalid
}
f.log.WithFields(map[string]any{
"user_id": claims.UserID,
}).Info("middlewares.tenant.auth.ok")
c.Locals(consts.CtxKeyClaims, claims)
return c.Next()
}
@@ -55,24 +78,36 @@ func (f *Middlewares) TenantAuth(c fiber.Ctx) error {
func (f *Middlewares) TenantRequireMember(c fiber.Ctx) error {
tenantModel, ok := c.Locals(consts.CtxKeyTenant).(*models.Tenant)
if !ok || tenantModel == nil {
f.log.Error("middlewares.tenant.require_member.missing_tenant_context")
return errorx.ErrInternalError.WithMsg("tenant context missing")
}
claims, ok := c.Locals(consts.CtxKeyClaims).(*jwt.Claims)
if !ok || claims == nil {
f.log.Error("middlewares.tenant.require_member.missing_claims_context")
return errorx.ErrInternalError.WithMsg("claims context missing")
}
tenantUser, err := services.Tenant.FindTenantUser(c, tenantModel.ID, claims.UserID)
if err != nil {
f.log.WithFields(map[string]any{
"tenant_id": tenantModel.ID,
"user_id": claims.UserID,
}).WithError(err).Warn("middlewares.tenant.require_member.denied")
return errorx.ErrPermissionDenied.WithMsg("不属于该租户")
}
userModel, err := services.User.FindByID(c, claims.UserID)
if err != nil {
f.log.WithField("user_id", claims.UserID).WithError(err).Warn("middlewares.tenant.require_member.load_user_failed")
return err
}
f.log.WithFields(map[string]any{
"tenant_id": tenantModel.ID,
"user_id": claims.UserID,
}).Info("middlewares.tenant.require_member.ok")
c.Locals(consts.CtxKeyTenantUser, tenantUser)
c.Locals(consts.CtxKeyUser, userModel)
return c.Next()

View File

@@ -0,0 +1,416 @@
package services
import (
"context"
"errors"
"time"
"quyun/v2/app/http/tenant/dto"
"quyun/v2/app/requests"
"quyun/v2/database"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
pkgerrors "github.com/pkg/errors"
"github.com/samber/lo"
log "github.com/sirupsen/logrus"
"go.ipao.vip/gen"
"gorm.io/gorm"
)
// content implements content-related domain operations.
//
// @provider
type content struct{}
// ContentDetailResult is the internal detail result used by controllers.
type ContentDetailResult struct {
// Content is the content entity.
Content *models.Content
// Price is the price settings (may be nil).
Price *models.ContentPrice
// HasAccess indicates whether the user can access main assets.
HasAccess bool
}
func (s *content) Create(ctx context.Context, tenantID, userID int64, form *dto.ContentCreateForm) (*models.Content, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"user_id": userID,
}).Info("services.content.create")
visibility := form.Visibility
if visibility == "" {
visibility = consts.ContentVisibilityTenantOnly
}
previewSeconds := int32(60)
if form.PreviewSeconds != nil && *form.PreviewSeconds > 0 {
previewSeconds = *form.PreviewSeconds
}
m := &models.Content{
TenantID: tenantID,
UserID: userID,
Title: form.Title,
Description: form.Description,
Status: consts.ContentStatusDraft,
Visibility: visibility,
PreviewSeconds: previewSeconds,
PreviewDownloadable: false,
}
if err := m.Create(ctx); err != nil {
return nil, pkgerrors.Wrap(err, "create content failed")
}
return m, nil
}
func (s *content) Update(ctx context.Context, tenantID, userID, contentID int64, form *dto.ContentUpdateForm) (*models.Content, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"user_id": userID,
"content_id": contentID,
}).Info("services.content.update")
tbl, query := models.ContentQuery.QueryContext(ctx)
m, err := query.Where(
tbl.TenantID.Eq(tenantID),
tbl.ID.Eq(contentID),
).First()
if err != nil {
return nil, pkgerrors.Wrap(err, "content not found")
}
if form.Title != nil {
m.Title = *form.Title
}
if form.Description != nil {
m.Description = *form.Description
}
if form.Visibility != nil {
m.Visibility = *form.Visibility
}
if form.PreviewSeconds != nil && *form.PreviewSeconds > 0 {
m.PreviewSeconds = *form.PreviewSeconds
m.PreviewDownloadable = false
}
if form.Status != nil {
m.Status = *form.Status
if m.Status == consts.ContentStatusPublished && m.PublishedAt.IsZero() {
m.PublishedAt = time.Now()
}
}
if _, err := m.Update(ctx); err != nil {
return nil, pkgerrors.Wrap(err, "update content failed")
}
return m, nil
}
func (s *content) UpsertPrice(ctx context.Context, tenantID, userID, contentID int64, form *dto.ContentPriceUpsertForm) (*models.ContentPrice, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"user_id": userID,
"content_id": contentID,
"amount": form.PriceAmount,
}).Info("services.content.upsert_price")
currency := form.Currency
if currency == "" {
currency = consts.CurrencyCNY
}
discountType := form.DiscountType
if discountType == "" {
discountType = consts.DiscountTypeNone
}
startAt := time.Time{}
if form.DiscountStartAt != nil {
startAt = *form.DiscountStartAt
}
endAt := time.Time{}
if form.DiscountEndAt != nil {
endAt = *form.DiscountEndAt
}
tbl, query := models.ContentPriceQuery.QueryContext(ctx)
m, err := query.Where(
tbl.TenantID.Eq(tenantID),
tbl.ContentID.Eq(contentID),
).First()
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, pkgerrors.Wrap(err, "find content price failed")
}
if errors.Is(err, gorm.ErrRecordNotFound) {
m = &models.ContentPrice{
TenantID: tenantID,
UserID: userID,
ContentID: contentID,
Currency: currency,
PriceAmount: form.PriceAmount,
DiscountType: discountType,
DiscountValue: form.DiscountValue,
DiscountStartAt: startAt,
DiscountEndAt: endAt,
}
if err := m.Create(ctx); err != nil {
return nil, pkgerrors.Wrap(err, "create content price failed")
}
return m, nil
}
m.UserID = userID
m.Currency = currency
m.PriceAmount = form.PriceAmount
m.DiscountType = discountType
m.DiscountValue = form.DiscountValue
m.DiscountStartAt = startAt
m.DiscountEndAt = endAt
if _, err := m.Update(ctx); err != nil {
return nil, pkgerrors.Wrap(err, "update content price failed")
}
return m, nil
}
func (s *content) AttachAsset(ctx context.Context, tenantID, userID, contentID, assetID int64, role consts.ContentAssetRole, sort int32, now time.Time) (*models.ContentAsset, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"user_id": userID,
"content_id": contentID,
"asset_id": assetID,
"role": role,
"sort": sort,
}).Info("services.content.attach_asset")
m := &models.ContentAsset{
TenantID: tenantID,
UserID: userID,
ContentID: contentID,
AssetID: assetID,
Role: role,
Sort: sort,
CreatedAt: now,
UpdatedAt: now,
}
if err := m.Create(ctx); err != nil {
return nil, pkgerrors.Wrap(err, "attach content asset failed")
}
return m, nil
}
func (s *content) ListPublished(ctx context.Context, tenantID, userID int64, filter *dto.ContentListFilter) (*requests.Pager, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"user_id": userID,
"page": filter.Page,
"limit": filter.Limit,
}).Info("services.content.list_published")
tbl, query := models.ContentQuery.QueryContext(ctx)
conds := []gen.Condition{
tbl.TenantID.Eq(tenantID),
tbl.Status.Eq(consts.ContentStatusPublished),
tbl.Visibility.In(consts.ContentVisibilityPublic, consts.ContentVisibilityTenantOnly),
}
if filter.Keyword != nil && *filter.Keyword != "" {
conds = append(conds, tbl.Title.Like(database.WrapLike(*filter.Keyword)))
}
filter.Pagination.Format()
items, total, err := query.Where(conds...).Order(tbl.ID.Desc()).FindByPage(int(filter.Offset()), int(filter.Limit))
if err != nil {
return nil, err
}
contentIDs := lo.Map(items, func(item *models.Content, _ int) int64 { return item.ID })
priceByContent, err := s.contentPriceMapping(ctx, tenantID, contentIDs)
if err != nil {
return nil, err
}
accessSet, err := s.accessSet(ctx, tenantID, userID, contentIDs)
if err != nil {
return nil, err
}
respItems := lo.Map(items, func(model *models.Content, _ int) *dto.ContentItem {
price := priceByContent[model.ID]
free := price == nil || price.PriceAmount == 0
has := free || accessSet[model.ID] || model.UserID == userID
return &dto.ContentItem{
Content: model,
Price: price,
HasAccess: has,
}
})
return &requests.Pager{
Pagination: filter.Pagination,
Total: total,
Items: respItems,
}, nil
}
func (s *content) Detail(ctx context.Context, tenantID, userID, contentID int64) (*ContentDetailResult, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"user_id": userID,
"content_id": contentID,
}).Info("services.content.detail")
tbl, query := models.ContentQuery.QueryContext(ctx)
model, err := query.Where(
tbl.TenantID.Eq(tenantID),
tbl.ID.Eq(contentID),
).First()
if err != nil {
return nil, pkgerrors.Wrapf(err, "content not found, tenantID=%d, contentID=%d", tenantID, contentID)
}
if model.Status != consts.ContentStatusPublished && model.UserID != userID {
return nil, errors.New("content is not published")
}
price, err := s.contentPrice(ctx, tenantID, contentID)
if err != nil {
return nil, err
}
free := price == nil || price.PriceAmount == 0
canView := false
switch model.Visibility {
case consts.ContentVisibilityPublic, consts.ContentVisibilityTenantOnly:
canView = true
case consts.ContentVisibilityPrivate:
canView = model.UserID == userID
default:
canView = false
}
hasAccess := model.UserID == userID || free
if !hasAccess {
ok, err := s.HasAccess(ctx, tenantID, userID, contentID)
if err != nil {
return nil, err
}
hasAccess = ok
canView = canView || ok
}
if !canView {
return nil, errors.New("content is private")
}
return &ContentDetailResult{
Content: model,
Price: price,
HasAccess: hasAccess,
}, nil
}
func (s *content) HasAccess(ctx context.Context, tenantID, userID, contentID int64) (bool, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"user_id": userID,
"content_id": contentID,
}).Info("services.content.has_access")
tbl, query := models.ContentAccessQuery.QueryContext(ctx)
_, err := query.Where(
tbl.TenantID.Eq(tenantID),
tbl.UserID.Eq(userID),
tbl.ContentID.Eq(contentID),
tbl.Status.Eq(consts.ContentAccessStatusActive),
).First()
if err != nil {
return false, nil
}
return true, nil
}
func (s *content) AssetsByRole(ctx context.Context, tenantID, contentID int64, role consts.ContentAssetRole) ([]*models.MediaAsset, error) {
log.WithFields(log.Fields{
"tenant_id": tenantID,
"content_id": contentID,
"role": role,
}).Info("services.content.assets_by_role")
maTbl, maQuery := models.MediaAssetQuery.QueryContext(ctx)
caTbl, _ := models.ContentAssetQuery.QueryContext(ctx)
assets, err := maQuery.
LeftJoin(caTbl, caTbl.AssetID.EqCol(maTbl.ID)).
Select(maTbl.ALL).
Where(
maTbl.TenantID.Eq(tenantID),
caTbl.TenantID.Eq(tenantID),
caTbl.ContentID.Eq(contentID),
caTbl.Role.Eq(role),
).
Order(caTbl.Sort.Asc()).
Find()
if err != nil {
return nil, err
}
return assets, nil
}
func (s *content) contentPrice(ctx context.Context, tenantID, contentID int64) (*models.ContentPrice, error) {
tbl, query := models.ContentPriceQuery.QueryContext(ctx)
m, err := query.Where(
tbl.TenantID.Eq(tenantID),
tbl.ContentID.Eq(contentID),
).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return m, nil
}
func (s *content) contentPriceMapping(ctx context.Context, tenantID int64, contentIDs []int64) (map[int64]*models.ContentPrice, error) {
if len(contentIDs) == 0 {
return map[int64]*models.ContentPrice{}, nil
}
tbl, query := models.ContentPriceQuery.QueryContext(ctx)
items, err := query.Where(
tbl.TenantID.Eq(tenantID),
tbl.ContentID.In(contentIDs...),
).Find()
if err != nil {
return nil, err
}
return lo.SliceToMap(items, func(item *models.ContentPrice) (int64, *models.ContentPrice) {
return item.ContentID, item
}), nil
}
func (s *content) accessSet(ctx context.Context, tenantID, userID int64, contentIDs []int64) (map[int64]bool, error) {
if len(contentIDs) == 0 {
return map[int64]bool{}, nil
}
tbl, query := models.ContentAccessQuery.QueryContext(ctx)
items, err := query.Where(
tbl.TenantID.Eq(tenantID),
tbl.UserID.Eq(userID),
tbl.ContentID.In(contentIDs...),
tbl.Status.Eq(consts.ContentAccessStatusActive),
).Find()
if err != nil {
return nil, err
}
out := make(map[int64]bool, len(items))
for _, item := range items {
out[item.ContentID] = true
}
return out, nil
}

View File

@@ -9,17 +9,26 @@ import (
)
func Provide(opts ...opt.Option) error {
if err := container.Container.Provide(func() (*content, error) {
obj := &content{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func(
content *content,
db *gorm.DB,
tenant *tenant,
test *test,
user *user,
) (contracts.Initial, error) {
obj := &services{
db: db,
tenant: tenant,
test: test,
user: user,
content: content,
db: db,
tenant: tenant,
test: test,
user: user,
}
if err := obj.Prepare(); err != nil {
return nil, err

View File

@@ -8,24 +8,27 @@ var _db *gorm.DB
// exported CamelCase Services
var (
Tenant *tenant
Test *test
User *user
Content *content
Tenant *tenant
Test *test
User *user
)
// @provider(model)
type services struct {
db *gorm.DB
// define Services
tenant *tenant
test *test
user *user
content *content
tenant *tenant
test *test
user *user
}
func (svc *services) Prepare() error {
_db = svc.db
// set exported Services here
Content = svc.content
Tenant = svc.tenant
Test = svc.test
User = svc.user

View File

@@ -17,6 +17,8 @@ import (
"go.ipao.vip/gen"
)
// tenant implements tenant-related domain operations.
//
// @provider
type tenant struct{}

View File

@@ -0,0 +1,65 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"time"
"quyun/v2/pkg/consts"
"go.ipao.vip/gen"
)
const TableNameContentAccess = "content_access"
// ContentAccess mapped from table <content_access>
type ContentAccess struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
ContentID int64 `gorm:"column:content_id;type:bigint;not null" json:"content_id"`
OrderID int64 `gorm:"column:order_id;type:bigint" json:"order_id"`
Status consts.ContentAccessStatus `gorm:"column:status;type:character varying(16);not null;default:active" json:"status"`
RevokedAt time.Time `gorm:"column:revoked_at;type:timestamp with time zone" json:"revoked_at"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
}
// Quick operations without importing query package
// Update applies changed fields to the database using the default DB.
func (m *ContentAccess) Update(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentAccess.WithContext(ctx).Updates(m)
}
// Save upserts the model using the default DB.
func (m *ContentAccess) Save(ctx context.Context) error {
return Q.ContentAccess.WithContext(ctx).Save(m)
}
// Create inserts the model using the default DB.
func (m *ContentAccess) Create(ctx context.Context) error {
return Q.ContentAccess.WithContext(ctx).Create(m)
}
// Delete removes the row represented by the model using the default DB.
func (m *ContentAccess) Delete(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentAccess.WithContext(ctx).Delete(m)
}
// ForceDelete permanently deletes the row (ignores soft delete) using the default DB.
func (m *ContentAccess) ForceDelete(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentAccess.WithContext(ctx).Unscoped().Delete(m)
}
// Reload reloads the model from database by its primary key and overwrites current fields.
func (m *ContentAccess) Reload(ctx context.Context) error {
fresh, err := Q.ContentAccess.WithContext(ctx).GetByID(m.ID)
if err != nil {
return err
}
*m = *fresh
return nil
}

View File

@@ -0,0 +1,493 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"go.ipao.vip/gen"
"go.ipao.vip/gen/field"
"gorm.io/plugin/dbresolver"
)
func newContentAccess(db *gorm.DB, opts ...gen.DOOption) contentAccessQuery {
_contentAccessQuery := contentAccessQuery{}
_contentAccessQuery.contentAccessQueryDo.UseDB(db, opts...)
_contentAccessQuery.contentAccessQueryDo.UseModel(&ContentAccess{})
tableName := _contentAccessQuery.contentAccessQueryDo.TableName()
_contentAccessQuery.ALL = field.NewAsterisk(tableName)
_contentAccessQuery.ID = field.NewInt64(tableName, "id")
_contentAccessQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_contentAccessQuery.UserID = field.NewInt64(tableName, "user_id")
_contentAccessQuery.ContentID = field.NewInt64(tableName, "content_id")
_contentAccessQuery.OrderID = field.NewInt64(tableName, "order_id")
_contentAccessQuery.Status = field.NewField(tableName, "status")
_contentAccessQuery.RevokedAt = field.NewTime(tableName, "revoked_at")
_contentAccessQuery.CreatedAt = field.NewTime(tableName, "created_at")
_contentAccessQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_contentAccessQuery.fillFieldMap()
return _contentAccessQuery
}
type contentAccessQuery struct {
contentAccessQueryDo contentAccessQueryDo
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
UserID field.Int64
ContentID field.Int64
OrderID field.Int64
Status field.Field
RevokedAt field.Time
CreatedAt field.Time
UpdatedAt field.Time
fieldMap map[string]field.Expr
}
func (c contentAccessQuery) Table(newTableName string) *contentAccessQuery {
c.contentAccessQueryDo.UseTable(newTableName)
return c.updateTableName(newTableName)
}
func (c contentAccessQuery) As(alias string) *contentAccessQuery {
c.contentAccessQueryDo.DO = *(c.contentAccessQueryDo.As(alias).(*gen.DO))
return c.updateTableName(alias)
}
func (c *contentAccessQuery) updateTableName(table string) *contentAccessQuery {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt64(table, "id")
c.TenantID = field.NewInt64(table, "tenant_id")
c.UserID = field.NewInt64(table, "user_id")
c.ContentID = field.NewInt64(table, "content_id")
c.OrderID = field.NewInt64(table, "order_id")
c.Status = field.NewField(table, "status")
c.RevokedAt = field.NewTime(table, "revoked_at")
c.CreatedAt = field.NewTime(table, "created_at")
c.UpdatedAt = field.NewTime(table, "updated_at")
c.fillFieldMap()
return c
}
func (c *contentAccessQuery) QueryContext(ctx context.Context) (*contentAccessQuery, *contentAccessQueryDo) {
return c, c.contentAccessQueryDo.WithContext(ctx)
}
func (c *contentAccessQuery) WithContext(ctx context.Context) *contentAccessQueryDo {
return c.contentAccessQueryDo.WithContext(ctx)
}
func (c contentAccessQuery) TableName() string { return c.contentAccessQueryDo.TableName() }
func (c contentAccessQuery) Alias() string { return c.contentAccessQueryDo.Alias() }
func (c contentAccessQuery) Columns(cols ...field.Expr) gen.Columns {
return c.contentAccessQueryDo.Columns(cols...)
}
func (c *contentAccessQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := c.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (c *contentAccessQuery) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 9)
c.fieldMap["id"] = c.ID
c.fieldMap["tenant_id"] = c.TenantID
c.fieldMap["user_id"] = c.UserID
c.fieldMap["content_id"] = c.ContentID
c.fieldMap["order_id"] = c.OrderID
c.fieldMap["status"] = c.Status
c.fieldMap["revoked_at"] = c.RevokedAt
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt
}
func (c contentAccessQuery) clone(db *gorm.DB) contentAccessQuery {
c.contentAccessQueryDo.ReplaceConnPool(db.Statement.ConnPool)
return c
}
func (c contentAccessQuery) replaceDB(db *gorm.DB) contentAccessQuery {
c.contentAccessQueryDo.ReplaceDB(db)
return c
}
type contentAccessQueryDo struct{ gen.DO }
func (c contentAccessQueryDo) Debug() *contentAccessQueryDo {
return c.withDO(c.DO.Debug())
}
func (c contentAccessQueryDo) WithContext(ctx context.Context) *contentAccessQueryDo {
return c.withDO(c.DO.WithContext(ctx))
}
func (c contentAccessQueryDo) ReadDB() *contentAccessQueryDo {
return c.Clauses(dbresolver.Read)
}
func (c contentAccessQueryDo) WriteDB() *contentAccessQueryDo {
return c.Clauses(dbresolver.Write)
}
func (c contentAccessQueryDo) Session(config *gorm.Session) *contentAccessQueryDo {
return c.withDO(c.DO.Session(config))
}
func (c contentAccessQueryDo) Clauses(conds ...clause.Expression) *contentAccessQueryDo {
return c.withDO(c.DO.Clauses(conds...))
}
func (c contentAccessQueryDo) Returning(value interface{}, columns ...string) *contentAccessQueryDo {
return c.withDO(c.DO.Returning(value, columns...))
}
func (c contentAccessQueryDo) Not(conds ...gen.Condition) *contentAccessQueryDo {
return c.withDO(c.DO.Not(conds...))
}
func (c contentAccessQueryDo) Or(conds ...gen.Condition) *contentAccessQueryDo {
return c.withDO(c.DO.Or(conds...))
}
func (c contentAccessQueryDo) Select(conds ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.Select(conds...))
}
func (c contentAccessQueryDo) Where(conds ...gen.Condition) *contentAccessQueryDo {
return c.withDO(c.DO.Where(conds...))
}
func (c contentAccessQueryDo) Order(conds ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.Order(conds...))
}
func (c contentAccessQueryDo) Distinct(cols ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.Distinct(cols...))
}
func (c contentAccessQueryDo) Omit(cols ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.Omit(cols...))
}
func (c contentAccessQueryDo) Join(table schema.Tabler, on ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.Join(table, on...))
}
func (c contentAccessQueryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.LeftJoin(table, on...))
}
func (c contentAccessQueryDo) RightJoin(table schema.Tabler, on ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.RightJoin(table, on...))
}
func (c contentAccessQueryDo) Group(cols ...field.Expr) *contentAccessQueryDo {
return c.withDO(c.DO.Group(cols...))
}
func (c contentAccessQueryDo) Having(conds ...gen.Condition) *contentAccessQueryDo {
return c.withDO(c.DO.Having(conds...))
}
func (c contentAccessQueryDo) Limit(limit int) *contentAccessQueryDo {
return c.withDO(c.DO.Limit(limit))
}
func (c contentAccessQueryDo) Offset(offset int) *contentAccessQueryDo {
return c.withDO(c.DO.Offset(offset))
}
func (c contentAccessQueryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *contentAccessQueryDo {
return c.withDO(c.DO.Scopes(funcs...))
}
func (c contentAccessQueryDo) Unscoped() *contentAccessQueryDo {
return c.withDO(c.DO.Unscoped())
}
func (c contentAccessQueryDo) Create(values ...*ContentAccess) error {
if len(values) == 0 {
return nil
}
return c.DO.Create(values)
}
func (c contentAccessQueryDo) CreateInBatches(values []*ContentAccess, batchSize int) error {
return c.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (c contentAccessQueryDo) Save(values ...*ContentAccess) error {
if len(values) == 0 {
return nil
}
return c.DO.Save(values)
}
func (c contentAccessQueryDo) First() (*ContentAccess, error) {
if result, err := c.DO.First(); err != nil {
return nil, err
} else {
return result.(*ContentAccess), nil
}
}
func (c contentAccessQueryDo) Take() (*ContentAccess, error) {
if result, err := c.DO.Take(); err != nil {
return nil, err
} else {
return result.(*ContentAccess), nil
}
}
func (c contentAccessQueryDo) Last() (*ContentAccess, error) {
if result, err := c.DO.Last(); err != nil {
return nil, err
} else {
return result.(*ContentAccess), nil
}
}
func (c contentAccessQueryDo) Find() ([]*ContentAccess, error) {
result, err := c.DO.Find()
return result.([]*ContentAccess), err
}
func (c contentAccessQueryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*ContentAccess, err error) {
buf := make([]*ContentAccess, 0, batchSize)
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (c contentAccessQueryDo) FindInBatches(result *[]*ContentAccess, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return c.DO.FindInBatches(result, batchSize, fc)
}
func (c contentAccessQueryDo) Attrs(attrs ...field.AssignExpr) *contentAccessQueryDo {
return c.withDO(c.DO.Attrs(attrs...))
}
func (c contentAccessQueryDo) Assign(attrs ...field.AssignExpr) *contentAccessQueryDo {
return c.withDO(c.DO.Assign(attrs...))
}
func (c contentAccessQueryDo) Joins(fields ...field.RelationField) *contentAccessQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Joins(_f))
}
return &c
}
func (c contentAccessQueryDo) Preload(fields ...field.RelationField) *contentAccessQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Preload(_f))
}
return &c
}
func (c contentAccessQueryDo) FirstOrInit() (*ContentAccess, error) {
if result, err := c.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*ContentAccess), nil
}
}
func (c contentAccessQueryDo) FirstOrCreate() (*ContentAccess, error) {
if result, err := c.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*ContentAccess), nil
}
}
func (c contentAccessQueryDo) FindByPage(offset int, limit int) (result []*ContentAccess, count int64, err error) {
result, err = c.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = c.Offset(-1).Limit(-1).Count()
return
}
func (c contentAccessQueryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = c.Count()
if err != nil {
return
}
err = c.Offset(offset).Limit(limit).Scan(result)
return
}
func (c contentAccessQueryDo) Scan(result interface{}) (err error) {
return c.DO.Scan(result)
}
func (c contentAccessQueryDo) Delete(models ...*ContentAccess) (result gen.ResultInfo, err error) {
return c.DO.Delete(models)
}
// ForceDelete performs a permanent delete (ignores soft-delete) for current scope.
func (c contentAccessQueryDo) ForceDelete() (gen.ResultInfo, error) {
return c.Unscoped().Delete()
}
// Inc increases the given column by step for current scope.
func (c contentAccessQueryDo) Inc(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column + step
e := field.NewUnsafeFieldRaw("?+?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Dec decreases the given column by step for current scope.
func (c contentAccessQueryDo) Dec(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column - step
e := field.NewUnsafeFieldRaw("?-?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Sum returns SUM(column) for current scope.
func (c contentAccessQueryDo) Sum(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("SUM(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Avg returns AVG(column) for current scope.
func (c contentAccessQueryDo) Avg(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("AVG(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Min returns MIN(column) for current scope.
func (c contentAccessQueryDo) Min(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MIN(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Max returns MAX(column) for current scope.
func (c contentAccessQueryDo) Max(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MAX(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// PluckMap returns a map[key]value for selected key/value expressions within current scope.
func (c contentAccessQueryDo) PluckMap(key, val field.Expr) (map[interface{}]interface{}, error) {
do := c.Select(key, val)
rows, err := do.DO.Rows()
if err != nil {
return nil, err
}
defer rows.Close()
mm := make(map[interface{}]interface{})
for rows.Next() {
var k interface{}
var v interface{}
if err := rows.Scan(&k, &v); err != nil {
return nil, err
}
mm[k] = v
}
return mm, rows.Err()
}
// Exists returns true if any record matches the given conditions.
func (c contentAccessQueryDo) Exists(conds ...gen.Condition) (bool, error) {
cnt, err := c.Where(conds...).Count()
if err != nil {
return false, err
}
return cnt > 0, nil
}
// PluckIDs returns all primary key values under current scope.
func (c contentAccessQueryDo) PluckIDs() ([]int64, error) {
ids := make([]int64, 0, 16)
pk := field.NewInt64(c.TableName(), "id")
if err := c.DO.Pluck(pk, &ids); err != nil {
return nil, err
}
return ids, nil
}
// GetByID finds a single record by primary key.
func (c contentAccessQueryDo) GetByID(id int64) (*ContentAccess, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).First()
}
// GetByIDs finds records by primary key list.
func (c contentAccessQueryDo) GetByIDs(ids ...int64) ([]*ContentAccess, error) {
if len(ids) == 0 {
return []*ContentAccess{}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Find()
}
// DeleteByID deletes records by primary key.
func (c contentAccessQueryDo) DeleteByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).Delete()
}
// DeleteByIDs deletes records by a list of primary keys.
func (c contentAccessQueryDo) DeleteByIDs(ids ...int64) (gen.ResultInfo, error) {
if len(ids) == 0 {
return gen.ResultInfo{RowsAffected: 0, Error: nil}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Delete()
}
func (c *contentAccessQueryDo) withDO(do gen.Dao) *contentAccessQueryDo {
c.DO = *do.(*gen.DO)
return c
}

View File

@@ -0,0 +1,65 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"time"
"quyun/v2/pkg/consts"
"go.ipao.vip/gen"
)
const TableNameContentAsset = "content_assets"
// ContentAsset mapped from table <content_assets>
type ContentAsset struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
ContentID int64 `gorm:"column:content_id;type:bigint;not null" json:"content_id"`
AssetID int64 `gorm:"column:asset_id;type:bigint;not null" json:"asset_id"`
Role consts.ContentAssetRole `gorm:"column:role;type:character varying(32);not null;default:main" json:"role"`
Sort int32 `gorm:"column:sort;type:integer;not null" json:"sort"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
}
// Quick operations without importing query package
// Update applies changed fields to the database using the default DB.
func (m *ContentAsset) Update(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentAsset.WithContext(ctx).Updates(m)
}
// Save upserts the model using the default DB.
func (m *ContentAsset) Save(ctx context.Context) error {
return Q.ContentAsset.WithContext(ctx).Save(m)
}
// Create inserts the model using the default DB.
func (m *ContentAsset) Create(ctx context.Context) error {
return Q.ContentAsset.WithContext(ctx).Create(m)
}
// Delete removes the row represented by the model using the default DB.
func (m *ContentAsset) Delete(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentAsset.WithContext(ctx).Delete(m)
}
// ForceDelete permanently deletes the row (ignores soft delete) using the default DB.
func (m *ContentAsset) ForceDelete(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentAsset.WithContext(ctx).Unscoped().Delete(m)
}
// Reload reloads the model from database by its primary key and overwrites current fields.
func (m *ContentAsset) Reload(ctx context.Context) error {
fresh, err := Q.ContentAsset.WithContext(ctx).GetByID(m.ID)
if err != nil {
return err
}
*m = *fresh
return nil
}

View File

@@ -0,0 +1,493 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"go.ipao.vip/gen"
"go.ipao.vip/gen/field"
"gorm.io/plugin/dbresolver"
)
func newContentAsset(db *gorm.DB, opts ...gen.DOOption) contentAssetQuery {
_contentAssetQuery := contentAssetQuery{}
_contentAssetQuery.contentAssetQueryDo.UseDB(db, opts...)
_contentAssetQuery.contentAssetQueryDo.UseModel(&ContentAsset{})
tableName := _contentAssetQuery.contentAssetQueryDo.TableName()
_contentAssetQuery.ALL = field.NewAsterisk(tableName)
_contentAssetQuery.ID = field.NewInt64(tableName, "id")
_contentAssetQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_contentAssetQuery.UserID = field.NewInt64(tableName, "user_id")
_contentAssetQuery.ContentID = field.NewInt64(tableName, "content_id")
_contentAssetQuery.AssetID = field.NewInt64(tableName, "asset_id")
_contentAssetQuery.Role = field.NewField(tableName, "role")
_contentAssetQuery.Sort = field.NewInt32(tableName, "sort")
_contentAssetQuery.CreatedAt = field.NewTime(tableName, "created_at")
_contentAssetQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_contentAssetQuery.fillFieldMap()
return _contentAssetQuery
}
type contentAssetQuery struct {
contentAssetQueryDo contentAssetQueryDo
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
UserID field.Int64
ContentID field.Int64
AssetID field.Int64
Role field.Field
Sort field.Int32
CreatedAt field.Time
UpdatedAt field.Time
fieldMap map[string]field.Expr
}
func (c contentAssetQuery) Table(newTableName string) *contentAssetQuery {
c.contentAssetQueryDo.UseTable(newTableName)
return c.updateTableName(newTableName)
}
func (c contentAssetQuery) As(alias string) *contentAssetQuery {
c.contentAssetQueryDo.DO = *(c.contentAssetQueryDo.As(alias).(*gen.DO))
return c.updateTableName(alias)
}
func (c *contentAssetQuery) updateTableName(table string) *contentAssetQuery {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt64(table, "id")
c.TenantID = field.NewInt64(table, "tenant_id")
c.UserID = field.NewInt64(table, "user_id")
c.ContentID = field.NewInt64(table, "content_id")
c.AssetID = field.NewInt64(table, "asset_id")
c.Role = field.NewField(table, "role")
c.Sort = field.NewInt32(table, "sort")
c.CreatedAt = field.NewTime(table, "created_at")
c.UpdatedAt = field.NewTime(table, "updated_at")
c.fillFieldMap()
return c
}
func (c *contentAssetQuery) QueryContext(ctx context.Context) (*contentAssetQuery, *contentAssetQueryDo) {
return c, c.contentAssetQueryDo.WithContext(ctx)
}
func (c *contentAssetQuery) WithContext(ctx context.Context) *contentAssetQueryDo {
return c.contentAssetQueryDo.WithContext(ctx)
}
func (c contentAssetQuery) TableName() string { return c.contentAssetQueryDo.TableName() }
func (c contentAssetQuery) Alias() string { return c.contentAssetQueryDo.Alias() }
func (c contentAssetQuery) Columns(cols ...field.Expr) gen.Columns {
return c.contentAssetQueryDo.Columns(cols...)
}
func (c *contentAssetQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := c.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (c *contentAssetQuery) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 9)
c.fieldMap["id"] = c.ID
c.fieldMap["tenant_id"] = c.TenantID
c.fieldMap["user_id"] = c.UserID
c.fieldMap["content_id"] = c.ContentID
c.fieldMap["asset_id"] = c.AssetID
c.fieldMap["role"] = c.Role
c.fieldMap["sort"] = c.Sort
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt
}
func (c contentAssetQuery) clone(db *gorm.DB) contentAssetQuery {
c.contentAssetQueryDo.ReplaceConnPool(db.Statement.ConnPool)
return c
}
func (c contentAssetQuery) replaceDB(db *gorm.DB) contentAssetQuery {
c.contentAssetQueryDo.ReplaceDB(db)
return c
}
type contentAssetQueryDo struct{ gen.DO }
func (c contentAssetQueryDo) Debug() *contentAssetQueryDo {
return c.withDO(c.DO.Debug())
}
func (c contentAssetQueryDo) WithContext(ctx context.Context) *contentAssetQueryDo {
return c.withDO(c.DO.WithContext(ctx))
}
func (c contentAssetQueryDo) ReadDB() *contentAssetQueryDo {
return c.Clauses(dbresolver.Read)
}
func (c contentAssetQueryDo) WriteDB() *contentAssetQueryDo {
return c.Clauses(dbresolver.Write)
}
func (c contentAssetQueryDo) Session(config *gorm.Session) *contentAssetQueryDo {
return c.withDO(c.DO.Session(config))
}
func (c contentAssetQueryDo) Clauses(conds ...clause.Expression) *contentAssetQueryDo {
return c.withDO(c.DO.Clauses(conds...))
}
func (c contentAssetQueryDo) Returning(value interface{}, columns ...string) *contentAssetQueryDo {
return c.withDO(c.DO.Returning(value, columns...))
}
func (c contentAssetQueryDo) Not(conds ...gen.Condition) *contentAssetQueryDo {
return c.withDO(c.DO.Not(conds...))
}
func (c contentAssetQueryDo) Or(conds ...gen.Condition) *contentAssetQueryDo {
return c.withDO(c.DO.Or(conds...))
}
func (c contentAssetQueryDo) Select(conds ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.Select(conds...))
}
func (c contentAssetQueryDo) Where(conds ...gen.Condition) *contentAssetQueryDo {
return c.withDO(c.DO.Where(conds...))
}
func (c contentAssetQueryDo) Order(conds ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.Order(conds...))
}
func (c contentAssetQueryDo) Distinct(cols ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.Distinct(cols...))
}
func (c contentAssetQueryDo) Omit(cols ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.Omit(cols...))
}
func (c contentAssetQueryDo) Join(table schema.Tabler, on ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.Join(table, on...))
}
func (c contentAssetQueryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.LeftJoin(table, on...))
}
func (c contentAssetQueryDo) RightJoin(table schema.Tabler, on ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.RightJoin(table, on...))
}
func (c contentAssetQueryDo) Group(cols ...field.Expr) *contentAssetQueryDo {
return c.withDO(c.DO.Group(cols...))
}
func (c contentAssetQueryDo) Having(conds ...gen.Condition) *contentAssetQueryDo {
return c.withDO(c.DO.Having(conds...))
}
func (c contentAssetQueryDo) Limit(limit int) *contentAssetQueryDo {
return c.withDO(c.DO.Limit(limit))
}
func (c contentAssetQueryDo) Offset(offset int) *contentAssetQueryDo {
return c.withDO(c.DO.Offset(offset))
}
func (c contentAssetQueryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *contentAssetQueryDo {
return c.withDO(c.DO.Scopes(funcs...))
}
func (c contentAssetQueryDo) Unscoped() *contentAssetQueryDo {
return c.withDO(c.DO.Unscoped())
}
func (c contentAssetQueryDo) Create(values ...*ContentAsset) error {
if len(values) == 0 {
return nil
}
return c.DO.Create(values)
}
func (c contentAssetQueryDo) CreateInBatches(values []*ContentAsset, batchSize int) error {
return c.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (c contentAssetQueryDo) Save(values ...*ContentAsset) error {
if len(values) == 0 {
return nil
}
return c.DO.Save(values)
}
func (c contentAssetQueryDo) First() (*ContentAsset, error) {
if result, err := c.DO.First(); err != nil {
return nil, err
} else {
return result.(*ContentAsset), nil
}
}
func (c contentAssetQueryDo) Take() (*ContentAsset, error) {
if result, err := c.DO.Take(); err != nil {
return nil, err
} else {
return result.(*ContentAsset), nil
}
}
func (c contentAssetQueryDo) Last() (*ContentAsset, error) {
if result, err := c.DO.Last(); err != nil {
return nil, err
} else {
return result.(*ContentAsset), nil
}
}
func (c contentAssetQueryDo) Find() ([]*ContentAsset, error) {
result, err := c.DO.Find()
return result.([]*ContentAsset), err
}
func (c contentAssetQueryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*ContentAsset, err error) {
buf := make([]*ContentAsset, 0, batchSize)
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (c contentAssetQueryDo) FindInBatches(result *[]*ContentAsset, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return c.DO.FindInBatches(result, batchSize, fc)
}
func (c contentAssetQueryDo) Attrs(attrs ...field.AssignExpr) *contentAssetQueryDo {
return c.withDO(c.DO.Attrs(attrs...))
}
func (c contentAssetQueryDo) Assign(attrs ...field.AssignExpr) *contentAssetQueryDo {
return c.withDO(c.DO.Assign(attrs...))
}
func (c contentAssetQueryDo) Joins(fields ...field.RelationField) *contentAssetQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Joins(_f))
}
return &c
}
func (c contentAssetQueryDo) Preload(fields ...field.RelationField) *contentAssetQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Preload(_f))
}
return &c
}
func (c contentAssetQueryDo) FirstOrInit() (*ContentAsset, error) {
if result, err := c.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*ContentAsset), nil
}
}
func (c contentAssetQueryDo) FirstOrCreate() (*ContentAsset, error) {
if result, err := c.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*ContentAsset), nil
}
}
func (c contentAssetQueryDo) FindByPage(offset int, limit int) (result []*ContentAsset, count int64, err error) {
result, err = c.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = c.Offset(-1).Limit(-1).Count()
return
}
func (c contentAssetQueryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = c.Count()
if err != nil {
return
}
err = c.Offset(offset).Limit(limit).Scan(result)
return
}
func (c contentAssetQueryDo) Scan(result interface{}) (err error) {
return c.DO.Scan(result)
}
func (c contentAssetQueryDo) Delete(models ...*ContentAsset) (result gen.ResultInfo, err error) {
return c.DO.Delete(models)
}
// ForceDelete performs a permanent delete (ignores soft-delete) for current scope.
func (c contentAssetQueryDo) ForceDelete() (gen.ResultInfo, error) {
return c.Unscoped().Delete()
}
// Inc increases the given column by step for current scope.
func (c contentAssetQueryDo) Inc(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column + step
e := field.NewUnsafeFieldRaw("?+?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Dec decreases the given column by step for current scope.
func (c contentAssetQueryDo) Dec(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column - step
e := field.NewUnsafeFieldRaw("?-?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Sum returns SUM(column) for current scope.
func (c contentAssetQueryDo) Sum(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("SUM(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Avg returns AVG(column) for current scope.
func (c contentAssetQueryDo) Avg(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("AVG(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Min returns MIN(column) for current scope.
func (c contentAssetQueryDo) Min(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MIN(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Max returns MAX(column) for current scope.
func (c contentAssetQueryDo) Max(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MAX(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// PluckMap returns a map[key]value for selected key/value expressions within current scope.
func (c contentAssetQueryDo) PluckMap(key, val field.Expr) (map[interface{}]interface{}, error) {
do := c.Select(key, val)
rows, err := do.DO.Rows()
if err != nil {
return nil, err
}
defer rows.Close()
mm := make(map[interface{}]interface{})
for rows.Next() {
var k interface{}
var v interface{}
if err := rows.Scan(&k, &v); err != nil {
return nil, err
}
mm[k] = v
}
return mm, rows.Err()
}
// Exists returns true if any record matches the given conditions.
func (c contentAssetQueryDo) Exists(conds ...gen.Condition) (bool, error) {
cnt, err := c.Where(conds...).Count()
if err != nil {
return false, err
}
return cnt > 0, nil
}
// PluckIDs returns all primary key values under current scope.
func (c contentAssetQueryDo) PluckIDs() ([]int64, error) {
ids := make([]int64, 0, 16)
pk := field.NewInt64(c.TableName(), "id")
if err := c.DO.Pluck(pk, &ids); err != nil {
return nil, err
}
return ids, nil
}
// GetByID finds a single record by primary key.
func (c contentAssetQueryDo) GetByID(id int64) (*ContentAsset, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).First()
}
// GetByIDs finds records by primary key list.
func (c contentAssetQueryDo) GetByIDs(ids ...int64) ([]*ContentAsset, error) {
if len(ids) == 0 {
return []*ContentAsset{}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Find()
}
// DeleteByID deletes records by primary key.
func (c contentAssetQueryDo) DeleteByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).Delete()
}
// DeleteByIDs deletes records by a list of primary keys.
func (c contentAssetQueryDo) DeleteByIDs(ids ...int64) (gen.ResultInfo, error) {
if len(ids) == 0 {
return gen.ResultInfo{RowsAffected: 0, Error: nil}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Delete()
}
func (c *contentAssetQueryDo) withDO(do gen.Dao) *contentAssetQueryDo {
c.DO = *do.(*gen.DO)
return c
}

View File

@@ -0,0 +1,68 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"time"
"quyun/v2/pkg/consts"
"go.ipao.vip/gen"
)
const TableNameContentPrice = "content_prices"
// ContentPrice mapped from table <content_prices>
type ContentPrice struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
ContentID int64 `gorm:"column:content_id;type:bigint;not null" json:"content_id"`
Currency consts.Currency `gorm:"column:currency;type:character varying(16);not null;default:CNY" json:"currency"`
PriceAmount int64 `gorm:"column:price_amount;type:bigint;not null" json:"price_amount"`
DiscountType consts.DiscountType `gorm:"column:discount_type;type:character varying(16);not null;default:none" json:"discount_type"`
DiscountValue int64 `gorm:"column:discount_value;type:bigint;not null" json:"discount_value"`
DiscountStartAt time.Time `gorm:"column:discount_start_at;type:timestamp with time zone" json:"discount_start_at"`
DiscountEndAt time.Time `gorm:"column:discount_end_at;type:timestamp with time zone" json:"discount_end_at"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
}
// Quick operations without importing query package
// Update applies changed fields to the database using the default DB.
func (m *ContentPrice) Update(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentPrice.WithContext(ctx).Updates(m)
}
// Save upserts the model using the default DB.
func (m *ContentPrice) Save(ctx context.Context) error {
return Q.ContentPrice.WithContext(ctx).Save(m)
}
// Create inserts the model using the default DB.
func (m *ContentPrice) Create(ctx context.Context) error {
return Q.ContentPrice.WithContext(ctx).Create(m)
}
// Delete removes the row represented by the model using the default DB.
func (m *ContentPrice) Delete(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentPrice.WithContext(ctx).Delete(m)
}
// ForceDelete permanently deletes the row (ignores soft delete) using the default DB.
func (m *ContentPrice) ForceDelete(ctx context.Context) (gen.ResultInfo, error) {
return Q.ContentPrice.WithContext(ctx).Unscoped().Delete(m)
}
// Reload reloads the model from database by its primary key and overwrites current fields.
func (m *ContentPrice) Reload(ctx context.Context) error {
fresh, err := Q.ContentPrice.WithContext(ctx).GetByID(m.ID)
if err != nil {
return err
}
*m = *fresh
return nil
}

View File

@@ -0,0 +1,505 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"go.ipao.vip/gen"
"go.ipao.vip/gen/field"
"gorm.io/plugin/dbresolver"
)
func newContentPrice(db *gorm.DB, opts ...gen.DOOption) contentPriceQuery {
_contentPriceQuery := contentPriceQuery{}
_contentPriceQuery.contentPriceQueryDo.UseDB(db, opts...)
_contentPriceQuery.contentPriceQueryDo.UseModel(&ContentPrice{})
tableName := _contentPriceQuery.contentPriceQueryDo.TableName()
_contentPriceQuery.ALL = field.NewAsterisk(tableName)
_contentPriceQuery.ID = field.NewInt64(tableName, "id")
_contentPriceQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_contentPriceQuery.UserID = field.NewInt64(tableName, "user_id")
_contentPriceQuery.ContentID = field.NewInt64(tableName, "content_id")
_contentPriceQuery.Currency = field.NewField(tableName, "currency")
_contentPriceQuery.PriceAmount = field.NewInt64(tableName, "price_amount")
_contentPriceQuery.DiscountType = field.NewField(tableName, "discount_type")
_contentPriceQuery.DiscountValue = field.NewInt64(tableName, "discount_value")
_contentPriceQuery.DiscountStartAt = field.NewTime(tableName, "discount_start_at")
_contentPriceQuery.DiscountEndAt = field.NewTime(tableName, "discount_end_at")
_contentPriceQuery.CreatedAt = field.NewTime(tableName, "created_at")
_contentPriceQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_contentPriceQuery.fillFieldMap()
return _contentPriceQuery
}
type contentPriceQuery struct {
contentPriceQueryDo contentPriceQueryDo
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
UserID field.Int64
ContentID field.Int64
Currency field.Field
PriceAmount field.Int64
DiscountType field.Field
DiscountValue field.Int64
DiscountStartAt field.Time
DiscountEndAt field.Time
CreatedAt field.Time
UpdatedAt field.Time
fieldMap map[string]field.Expr
}
func (c contentPriceQuery) Table(newTableName string) *contentPriceQuery {
c.contentPriceQueryDo.UseTable(newTableName)
return c.updateTableName(newTableName)
}
func (c contentPriceQuery) As(alias string) *contentPriceQuery {
c.contentPriceQueryDo.DO = *(c.contentPriceQueryDo.As(alias).(*gen.DO))
return c.updateTableName(alias)
}
func (c *contentPriceQuery) updateTableName(table string) *contentPriceQuery {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt64(table, "id")
c.TenantID = field.NewInt64(table, "tenant_id")
c.UserID = field.NewInt64(table, "user_id")
c.ContentID = field.NewInt64(table, "content_id")
c.Currency = field.NewField(table, "currency")
c.PriceAmount = field.NewInt64(table, "price_amount")
c.DiscountType = field.NewField(table, "discount_type")
c.DiscountValue = field.NewInt64(table, "discount_value")
c.DiscountStartAt = field.NewTime(table, "discount_start_at")
c.DiscountEndAt = field.NewTime(table, "discount_end_at")
c.CreatedAt = field.NewTime(table, "created_at")
c.UpdatedAt = field.NewTime(table, "updated_at")
c.fillFieldMap()
return c
}
func (c *contentPriceQuery) QueryContext(ctx context.Context) (*contentPriceQuery, *contentPriceQueryDo) {
return c, c.contentPriceQueryDo.WithContext(ctx)
}
func (c *contentPriceQuery) WithContext(ctx context.Context) *contentPriceQueryDo {
return c.contentPriceQueryDo.WithContext(ctx)
}
func (c contentPriceQuery) TableName() string { return c.contentPriceQueryDo.TableName() }
func (c contentPriceQuery) Alias() string { return c.contentPriceQueryDo.Alias() }
func (c contentPriceQuery) Columns(cols ...field.Expr) gen.Columns {
return c.contentPriceQueryDo.Columns(cols...)
}
func (c *contentPriceQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := c.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (c *contentPriceQuery) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 12)
c.fieldMap["id"] = c.ID
c.fieldMap["tenant_id"] = c.TenantID
c.fieldMap["user_id"] = c.UserID
c.fieldMap["content_id"] = c.ContentID
c.fieldMap["currency"] = c.Currency
c.fieldMap["price_amount"] = c.PriceAmount
c.fieldMap["discount_type"] = c.DiscountType
c.fieldMap["discount_value"] = c.DiscountValue
c.fieldMap["discount_start_at"] = c.DiscountStartAt
c.fieldMap["discount_end_at"] = c.DiscountEndAt
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt
}
func (c contentPriceQuery) clone(db *gorm.DB) contentPriceQuery {
c.contentPriceQueryDo.ReplaceConnPool(db.Statement.ConnPool)
return c
}
func (c contentPriceQuery) replaceDB(db *gorm.DB) contentPriceQuery {
c.contentPriceQueryDo.ReplaceDB(db)
return c
}
type contentPriceQueryDo struct{ gen.DO }
func (c contentPriceQueryDo) Debug() *contentPriceQueryDo {
return c.withDO(c.DO.Debug())
}
func (c contentPriceQueryDo) WithContext(ctx context.Context) *contentPriceQueryDo {
return c.withDO(c.DO.WithContext(ctx))
}
func (c contentPriceQueryDo) ReadDB() *contentPriceQueryDo {
return c.Clauses(dbresolver.Read)
}
func (c contentPriceQueryDo) WriteDB() *contentPriceQueryDo {
return c.Clauses(dbresolver.Write)
}
func (c contentPriceQueryDo) Session(config *gorm.Session) *contentPriceQueryDo {
return c.withDO(c.DO.Session(config))
}
func (c contentPriceQueryDo) Clauses(conds ...clause.Expression) *contentPriceQueryDo {
return c.withDO(c.DO.Clauses(conds...))
}
func (c contentPriceQueryDo) Returning(value interface{}, columns ...string) *contentPriceQueryDo {
return c.withDO(c.DO.Returning(value, columns...))
}
func (c contentPriceQueryDo) Not(conds ...gen.Condition) *contentPriceQueryDo {
return c.withDO(c.DO.Not(conds...))
}
func (c contentPriceQueryDo) Or(conds ...gen.Condition) *contentPriceQueryDo {
return c.withDO(c.DO.Or(conds...))
}
func (c contentPriceQueryDo) Select(conds ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.Select(conds...))
}
func (c contentPriceQueryDo) Where(conds ...gen.Condition) *contentPriceQueryDo {
return c.withDO(c.DO.Where(conds...))
}
func (c contentPriceQueryDo) Order(conds ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.Order(conds...))
}
func (c contentPriceQueryDo) Distinct(cols ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.Distinct(cols...))
}
func (c contentPriceQueryDo) Omit(cols ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.Omit(cols...))
}
func (c contentPriceQueryDo) Join(table schema.Tabler, on ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.Join(table, on...))
}
func (c contentPriceQueryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.LeftJoin(table, on...))
}
func (c contentPriceQueryDo) RightJoin(table schema.Tabler, on ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.RightJoin(table, on...))
}
func (c contentPriceQueryDo) Group(cols ...field.Expr) *contentPriceQueryDo {
return c.withDO(c.DO.Group(cols...))
}
func (c contentPriceQueryDo) Having(conds ...gen.Condition) *contentPriceQueryDo {
return c.withDO(c.DO.Having(conds...))
}
func (c contentPriceQueryDo) Limit(limit int) *contentPriceQueryDo {
return c.withDO(c.DO.Limit(limit))
}
func (c contentPriceQueryDo) Offset(offset int) *contentPriceQueryDo {
return c.withDO(c.DO.Offset(offset))
}
func (c contentPriceQueryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *contentPriceQueryDo {
return c.withDO(c.DO.Scopes(funcs...))
}
func (c contentPriceQueryDo) Unscoped() *contentPriceQueryDo {
return c.withDO(c.DO.Unscoped())
}
func (c contentPriceQueryDo) Create(values ...*ContentPrice) error {
if len(values) == 0 {
return nil
}
return c.DO.Create(values)
}
func (c contentPriceQueryDo) CreateInBatches(values []*ContentPrice, batchSize int) error {
return c.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (c contentPriceQueryDo) Save(values ...*ContentPrice) error {
if len(values) == 0 {
return nil
}
return c.DO.Save(values)
}
func (c contentPriceQueryDo) First() (*ContentPrice, error) {
if result, err := c.DO.First(); err != nil {
return nil, err
} else {
return result.(*ContentPrice), nil
}
}
func (c contentPriceQueryDo) Take() (*ContentPrice, error) {
if result, err := c.DO.Take(); err != nil {
return nil, err
} else {
return result.(*ContentPrice), nil
}
}
func (c contentPriceQueryDo) Last() (*ContentPrice, error) {
if result, err := c.DO.Last(); err != nil {
return nil, err
} else {
return result.(*ContentPrice), nil
}
}
func (c contentPriceQueryDo) Find() ([]*ContentPrice, error) {
result, err := c.DO.Find()
return result.([]*ContentPrice), err
}
func (c contentPriceQueryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*ContentPrice, err error) {
buf := make([]*ContentPrice, 0, batchSize)
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (c contentPriceQueryDo) FindInBatches(result *[]*ContentPrice, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return c.DO.FindInBatches(result, batchSize, fc)
}
func (c contentPriceQueryDo) Attrs(attrs ...field.AssignExpr) *contentPriceQueryDo {
return c.withDO(c.DO.Attrs(attrs...))
}
func (c contentPriceQueryDo) Assign(attrs ...field.AssignExpr) *contentPriceQueryDo {
return c.withDO(c.DO.Assign(attrs...))
}
func (c contentPriceQueryDo) Joins(fields ...field.RelationField) *contentPriceQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Joins(_f))
}
return &c
}
func (c contentPriceQueryDo) Preload(fields ...field.RelationField) *contentPriceQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Preload(_f))
}
return &c
}
func (c contentPriceQueryDo) FirstOrInit() (*ContentPrice, error) {
if result, err := c.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*ContentPrice), nil
}
}
func (c contentPriceQueryDo) FirstOrCreate() (*ContentPrice, error) {
if result, err := c.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*ContentPrice), nil
}
}
func (c contentPriceQueryDo) FindByPage(offset int, limit int) (result []*ContentPrice, count int64, err error) {
result, err = c.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = c.Offset(-1).Limit(-1).Count()
return
}
func (c contentPriceQueryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = c.Count()
if err != nil {
return
}
err = c.Offset(offset).Limit(limit).Scan(result)
return
}
func (c contentPriceQueryDo) Scan(result interface{}) (err error) {
return c.DO.Scan(result)
}
func (c contentPriceQueryDo) Delete(models ...*ContentPrice) (result gen.ResultInfo, err error) {
return c.DO.Delete(models)
}
// ForceDelete performs a permanent delete (ignores soft-delete) for current scope.
func (c contentPriceQueryDo) ForceDelete() (gen.ResultInfo, error) {
return c.Unscoped().Delete()
}
// Inc increases the given column by step for current scope.
func (c contentPriceQueryDo) Inc(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column + step
e := field.NewUnsafeFieldRaw("?+?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Dec decreases the given column by step for current scope.
func (c contentPriceQueryDo) Dec(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column - step
e := field.NewUnsafeFieldRaw("?-?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Sum returns SUM(column) for current scope.
func (c contentPriceQueryDo) Sum(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("SUM(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Avg returns AVG(column) for current scope.
func (c contentPriceQueryDo) Avg(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("AVG(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Min returns MIN(column) for current scope.
func (c contentPriceQueryDo) Min(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MIN(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Max returns MAX(column) for current scope.
func (c contentPriceQueryDo) Max(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MAX(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// PluckMap returns a map[key]value for selected key/value expressions within current scope.
func (c contentPriceQueryDo) PluckMap(key, val field.Expr) (map[interface{}]interface{}, error) {
do := c.Select(key, val)
rows, err := do.DO.Rows()
if err != nil {
return nil, err
}
defer rows.Close()
mm := make(map[interface{}]interface{})
for rows.Next() {
var k interface{}
var v interface{}
if err := rows.Scan(&k, &v); err != nil {
return nil, err
}
mm[k] = v
}
return mm, rows.Err()
}
// Exists returns true if any record matches the given conditions.
func (c contentPriceQueryDo) Exists(conds ...gen.Condition) (bool, error) {
cnt, err := c.Where(conds...).Count()
if err != nil {
return false, err
}
return cnt > 0, nil
}
// PluckIDs returns all primary key values under current scope.
func (c contentPriceQueryDo) PluckIDs() ([]int64, error) {
ids := make([]int64, 0, 16)
pk := field.NewInt64(c.TableName(), "id")
if err := c.DO.Pluck(pk, &ids); err != nil {
return nil, err
}
return ids, nil
}
// GetByID finds a single record by primary key.
func (c contentPriceQueryDo) GetByID(id int64) (*ContentPrice, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).First()
}
// GetByIDs finds records by primary key list.
func (c contentPriceQueryDo) GetByIDs(ids ...int64) ([]*ContentPrice, error) {
if len(ids) == 0 {
return []*ContentPrice{}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Find()
}
// DeleteByID deletes records by primary key.
func (c contentPriceQueryDo) DeleteByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).Delete()
}
// DeleteByIDs deletes records by a list of primary keys.
func (c contentPriceQueryDo) DeleteByIDs(ids ...int64) (gen.ResultInfo, error) {
if len(ids) == 0 {
return gen.ResultInfo{RowsAffected: 0, Error: nil}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Delete()
}
func (c *contentPriceQueryDo) withDO(do gen.Dao) *contentPriceQueryDo {
c.DO = *do.(*gen.DO)
return c
}

View File

@@ -0,0 +1,71 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"time"
"quyun/v2/pkg/consts"
"go.ipao.vip/gen"
"gorm.io/gorm"
)
const TableNameContent = "contents"
// Content mapped from table <contents>
type Content struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
Title string `gorm:"column:title;type:character varying(255);not null" json:"title"`
Description string `gorm:"column:description;type:text;not null" json:"description"`
Status consts.ContentStatus `gorm:"column:status;type:character varying(32);not null;default:draft" json:"status"`
Visibility consts.ContentVisibility `gorm:"column:visibility;type:character varying(32);not null;default:tenant_only" json:"visibility"`
PreviewSeconds int32 `gorm:"column:preview_seconds;type:integer;not null;default:60" json:"preview_seconds"`
PreviewDownloadable bool `gorm:"column:preview_downloadable;type:boolean;not null" json:"preview_downloadable"`
PublishedAt time.Time `gorm:"column:published_at;type:timestamp with time zone" json:"published_at"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp with time zone" json:"deleted_at"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
}
// Quick operations without importing query package
// Update applies changed fields to the database using the default DB.
func (m *Content) Update(ctx context.Context) (gen.ResultInfo, error) {
return Q.Content.WithContext(ctx).Updates(m)
}
// Save upserts the model using the default DB.
func (m *Content) Save(ctx context.Context) error { return Q.Content.WithContext(ctx).Save(m) }
// Create inserts the model using the default DB.
func (m *Content) Create(ctx context.Context) error { return Q.Content.WithContext(ctx).Create(m) }
// Delete removes the row represented by the model using the default DB.
func (m *Content) Delete(ctx context.Context) (gen.ResultInfo, error) {
return Q.Content.WithContext(ctx).Delete(m)
}
// ForceDelete permanently deletes the row (ignores soft delete) using the default DB.
func (m *Content) ForceDelete(ctx context.Context) (gen.ResultInfo, error) {
return Q.Content.WithContext(ctx).Unscoped().Delete(m)
}
// Restore sets deleted_at to NULL for this model's primary key using the default DB.
func (m *Content) Restore(ctx context.Context) (gen.ResultInfo, error) {
return Q.Content.WithContext(ctx).RestoreByID(m.ID)
}
// Reload reloads the model from database by its primary key and overwrites current fields.
func (m *Content) Reload(ctx context.Context) error {
fresh, err := Q.Content.WithContext(ctx).GetByID(m.ID)
if err != nil {
return err
}
*m = *fresh
return nil
}

View File

@@ -0,0 +1,522 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"go.ipao.vip/gen"
"go.ipao.vip/gen/field"
"gorm.io/plugin/dbresolver"
)
func newContent(db *gorm.DB, opts ...gen.DOOption) contentQuery {
_contentQuery := contentQuery{}
_contentQuery.contentQueryDo.UseDB(db, opts...)
_contentQuery.contentQueryDo.UseModel(&Content{})
tableName := _contentQuery.contentQueryDo.TableName()
_contentQuery.ALL = field.NewAsterisk(tableName)
_contentQuery.ID = field.NewInt64(tableName, "id")
_contentQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_contentQuery.UserID = field.NewInt64(tableName, "user_id")
_contentQuery.Title = field.NewString(tableName, "title")
_contentQuery.Description = field.NewString(tableName, "description")
_contentQuery.Status = field.NewField(tableName, "status")
_contentQuery.Visibility = field.NewField(tableName, "visibility")
_contentQuery.PreviewSeconds = field.NewInt32(tableName, "preview_seconds")
_contentQuery.PreviewDownloadable = field.NewBool(tableName, "preview_downloadable")
_contentQuery.PublishedAt = field.NewTime(tableName, "published_at")
_contentQuery.DeletedAt = field.NewField(tableName, "deleted_at")
_contentQuery.CreatedAt = field.NewTime(tableName, "created_at")
_contentQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_contentQuery.fillFieldMap()
return _contentQuery
}
type contentQuery struct {
contentQueryDo contentQueryDo
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
UserID field.Int64
Title field.String
Description field.String
Status field.Field
Visibility field.Field
PreviewSeconds field.Int32
PreviewDownloadable field.Bool
PublishedAt field.Time
DeletedAt field.Field
CreatedAt field.Time
UpdatedAt field.Time
fieldMap map[string]field.Expr
}
func (c contentQuery) Table(newTableName string) *contentQuery {
c.contentQueryDo.UseTable(newTableName)
return c.updateTableName(newTableName)
}
func (c contentQuery) As(alias string) *contentQuery {
c.contentQueryDo.DO = *(c.contentQueryDo.As(alias).(*gen.DO))
return c.updateTableName(alias)
}
func (c *contentQuery) updateTableName(table string) *contentQuery {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt64(table, "id")
c.TenantID = field.NewInt64(table, "tenant_id")
c.UserID = field.NewInt64(table, "user_id")
c.Title = field.NewString(table, "title")
c.Description = field.NewString(table, "description")
c.Status = field.NewField(table, "status")
c.Visibility = field.NewField(table, "visibility")
c.PreviewSeconds = field.NewInt32(table, "preview_seconds")
c.PreviewDownloadable = field.NewBool(table, "preview_downloadable")
c.PublishedAt = field.NewTime(table, "published_at")
c.DeletedAt = field.NewField(table, "deleted_at")
c.CreatedAt = field.NewTime(table, "created_at")
c.UpdatedAt = field.NewTime(table, "updated_at")
c.fillFieldMap()
return c
}
func (c *contentQuery) QueryContext(ctx context.Context) (*contentQuery, *contentQueryDo) {
return c, c.contentQueryDo.WithContext(ctx)
}
func (c *contentQuery) WithContext(ctx context.Context) *contentQueryDo {
return c.contentQueryDo.WithContext(ctx)
}
func (c contentQuery) TableName() string { return c.contentQueryDo.TableName() }
func (c contentQuery) Alias() string { return c.contentQueryDo.Alias() }
func (c contentQuery) Columns(cols ...field.Expr) gen.Columns {
return c.contentQueryDo.Columns(cols...)
}
func (c *contentQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := c.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (c *contentQuery) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 13)
c.fieldMap["id"] = c.ID
c.fieldMap["tenant_id"] = c.TenantID
c.fieldMap["user_id"] = c.UserID
c.fieldMap["title"] = c.Title
c.fieldMap["description"] = c.Description
c.fieldMap["status"] = c.Status
c.fieldMap["visibility"] = c.Visibility
c.fieldMap["preview_seconds"] = c.PreviewSeconds
c.fieldMap["preview_downloadable"] = c.PreviewDownloadable
c.fieldMap["published_at"] = c.PublishedAt
c.fieldMap["deleted_at"] = c.DeletedAt
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt
}
func (c contentQuery) clone(db *gorm.DB) contentQuery {
c.contentQueryDo.ReplaceConnPool(db.Statement.ConnPool)
return c
}
func (c contentQuery) replaceDB(db *gorm.DB) contentQuery {
c.contentQueryDo.ReplaceDB(db)
return c
}
type contentQueryDo struct{ gen.DO }
func (c contentQueryDo) Debug() *contentQueryDo {
return c.withDO(c.DO.Debug())
}
func (c contentQueryDo) WithContext(ctx context.Context) *contentQueryDo {
return c.withDO(c.DO.WithContext(ctx))
}
func (c contentQueryDo) ReadDB() *contentQueryDo {
return c.Clauses(dbresolver.Read)
}
func (c contentQueryDo) WriteDB() *contentQueryDo {
return c.Clauses(dbresolver.Write)
}
func (c contentQueryDo) Session(config *gorm.Session) *contentQueryDo {
return c.withDO(c.DO.Session(config))
}
func (c contentQueryDo) Clauses(conds ...clause.Expression) *contentQueryDo {
return c.withDO(c.DO.Clauses(conds...))
}
func (c contentQueryDo) Returning(value interface{}, columns ...string) *contentQueryDo {
return c.withDO(c.DO.Returning(value, columns...))
}
func (c contentQueryDo) Not(conds ...gen.Condition) *contentQueryDo {
return c.withDO(c.DO.Not(conds...))
}
func (c contentQueryDo) Or(conds ...gen.Condition) *contentQueryDo {
return c.withDO(c.DO.Or(conds...))
}
func (c contentQueryDo) Select(conds ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.Select(conds...))
}
func (c contentQueryDo) Where(conds ...gen.Condition) *contentQueryDo {
return c.withDO(c.DO.Where(conds...))
}
func (c contentQueryDo) Order(conds ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.Order(conds...))
}
func (c contentQueryDo) Distinct(cols ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.Distinct(cols...))
}
func (c contentQueryDo) Omit(cols ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.Omit(cols...))
}
func (c contentQueryDo) Join(table schema.Tabler, on ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.Join(table, on...))
}
func (c contentQueryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.LeftJoin(table, on...))
}
func (c contentQueryDo) RightJoin(table schema.Tabler, on ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.RightJoin(table, on...))
}
func (c contentQueryDo) Group(cols ...field.Expr) *contentQueryDo {
return c.withDO(c.DO.Group(cols...))
}
func (c contentQueryDo) Having(conds ...gen.Condition) *contentQueryDo {
return c.withDO(c.DO.Having(conds...))
}
func (c contentQueryDo) Limit(limit int) *contentQueryDo {
return c.withDO(c.DO.Limit(limit))
}
func (c contentQueryDo) Offset(offset int) *contentQueryDo {
return c.withDO(c.DO.Offset(offset))
}
func (c contentQueryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *contentQueryDo {
return c.withDO(c.DO.Scopes(funcs...))
}
func (c contentQueryDo) Unscoped() *contentQueryDo {
return c.withDO(c.DO.Unscoped())
}
func (c contentQueryDo) Create(values ...*Content) error {
if len(values) == 0 {
return nil
}
return c.DO.Create(values)
}
func (c contentQueryDo) CreateInBatches(values []*Content, batchSize int) error {
return c.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (c contentQueryDo) Save(values ...*Content) error {
if len(values) == 0 {
return nil
}
return c.DO.Save(values)
}
func (c contentQueryDo) First() (*Content, error) {
if result, err := c.DO.First(); err != nil {
return nil, err
} else {
return result.(*Content), nil
}
}
func (c contentQueryDo) Take() (*Content, error) {
if result, err := c.DO.Take(); err != nil {
return nil, err
} else {
return result.(*Content), nil
}
}
func (c contentQueryDo) Last() (*Content, error) {
if result, err := c.DO.Last(); err != nil {
return nil, err
} else {
return result.(*Content), nil
}
}
func (c contentQueryDo) Find() ([]*Content, error) {
result, err := c.DO.Find()
return result.([]*Content), err
}
func (c contentQueryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*Content, err error) {
buf := make([]*Content, 0, batchSize)
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (c contentQueryDo) FindInBatches(result *[]*Content, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return c.DO.FindInBatches(result, batchSize, fc)
}
func (c contentQueryDo) Attrs(attrs ...field.AssignExpr) *contentQueryDo {
return c.withDO(c.DO.Attrs(attrs...))
}
func (c contentQueryDo) Assign(attrs ...field.AssignExpr) *contentQueryDo {
return c.withDO(c.DO.Assign(attrs...))
}
func (c contentQueryDo) Joins(fields ...field.RelationField) *contentQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Joins(_f))
}
return &c
}
func (c contentQueryDo) Preload(fields ...field.RelationField) *contentQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Preload(_f))
}
return &c
}
func (c contentQueryDo) FirstOrInit() (*Content, error) {
if result, err := c.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*Content), nil
}
}
func (c contentQueryDo) FirstOrCreate() (*Content, error) {
if result, err := c.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*Content), nil
}
}
func (c contentQueryDo) FindByPage(offset int, limit int) (result []*Content, count int64, err error) {
result, err = c.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = c.Offset(-1).Limit(-1).Count()
return
}
func (c contentQueryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = c.Count()
if err != nil {
return
}
err = c.Offset(offset).Limit(limit).Scan(result)
return
}
func (c contentQueryDo) Scan(result interface{}) (err error) {
return c.DO.Scan(result)
}
func (c contentQueryDo) Delete(models ...*Content) (result gen.ResultInfo, err error) {
return c.DO.Delete(models)
}
// ForceDelete performs a permanent delete (ignores soft-delete) for current scope.
func (c contentQueryDo) ForceDelete() (gen.ResultInfo, error) {
return c.Unscoped().Delete()
}
// Inc increases the given column by step for current scope.
func (c contentQueryDo) Inc(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column + step
e := field.NewUnsafeFieldRaw("?+?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Dec decreases the given column by step for current scope.
func (c contentQueryDo) Dec(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column - step
e := field.NewUnsafeFieldRaw("?-?", column.RawExpr(), step)
return c.DO.UpdateColumn(column, e)
}
// Sum returns SUM(column) for current scope.
func (c contentQueryDo) Sum(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("SUM(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Avg returns AVG(column) for current scope.
func (c contentQueryDo) Avg(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("AVG(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Min returns MIN(column) for current scope.
func (c contentQueryDo) Min(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MIN(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Max returns MAX(column) for current scope.
func (c contentQueryDo) Max(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MAX(?)", column.RawExpr())
if err := c.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// PluckMap returns a map[key]value for selected key/value expressions within current scope.
func (c contentQueryDo) PluckMap(key, val field.Expr) (map[interface{}]interface{}, error) {
do := c.Select(key, val)
rows, err := do.DO.Rows()
if err != nil {
return nil, err
}
defer rows.Close()
mm := make(map[interface{}]interface{})
for rows.Next() {
var k interface{}
var v interface{}
if err := rows.Scan(&k, &v); err != nil {
return nil, err
}
mm[k] = v
}
return mm, rows.Err()
}
// Exists returns true if any record matches the given conditions.
func (c contentQueryDo) Exists(conds ...gen.Condition) (bool, error) {
cnt, err := c.Where(conds...).Count()
if err != nil {
return false, err
}
return cnt > 0, nil
}
// PluckIDs returns all primary key values under current scope.
func (c contentQueryDo) PluckIDs() ([]int64, error) {
ids := make([]int64, 0, 16)
pk := field.NewInt64(c.TableName(), "id")
if err := c.DO.Pluck(pk, &ids); err != nil {
return nil, err
}
return ids, nil
}
// GetByID finds a single record by primary key.
func (c contentQueryDo) GetByID(id int64) (*Content, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).First()
}
// GetByIDs finds records by primary key list.
func (c contentQueryDo) GetByIDs(ids ...int64) ([]*Content, error) {
if len(ids) == 0 {
return []*Content{}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Find()
}
// DeleteByID deletes records by primary key.
func (c contentQueryDo) DeleteByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).Delete()
}
// DeleteByIDs deletes records by a list of primary keys.
func (c contentQueryDo) DeleteByIDs(ids ...int64) (gen.ResultInfo, error) {
if len(ids) == 0 {
return gen.ResultInfo{RowsAffected: 0, Error: nil}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Delete()
}
// RestoreWhere sets deleted_at to NULL for rows matching current scope + conds.
func (c contentQueryDo) RestoreWhere(conds ...gen.Condition) (gen.ResultInfo, error) {
col := field.NewField(c.TableName(), "deleted_at")
return c.Unscoped().Where(conds...).UpdateColumn(col, nil)
}
// RestoreByID sets deleted_at to NULL for the given primary key.
func (c contentQueryDo) RestoreByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(c.TableName(), "id")
col := field.NewField(c.TableName(), "deleted_at")
return c.Unscoped().Where(pk.Eq(id)).UpdateColumn(col, nil)
}
func (c *contentQueryDo) withDO(do gen.Dao) *contentQueryDo {
c.DO = *do.(*gen.DO)
return c
}

View File

@@ -0,0 +1,73 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"time"
"quyun/v2/pkg/consts"
"go.ipao.vip/gen"
"go.ipao.vip/gen/types"
"gorm.io/gorm"
)
const TableNameMediaAsset = "media_assets"
// MediaAsset mapped from table <media_assets>
type MediaAsset struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
Type consts.MediaAssetType `gorm:"column:type;type:character varying(32);not null;default:video" json:"type"`
Status consts.MediaAssetStatus `gorm:"column:status;type:character varying(32);not null;default:uploaded" json:"status"`
Provider string `gorm:"column:provider;type:character varying(64);not null" json:"provider"`
Bucket string `gorm:"column:bucket;type:character varying(128);not null" json:"bucket"`
ObjectKey string `gorm:"column:object_key;type:character varying(512);not null" json:"object_key"`
Meta types.JSON `gorm:"column:meta;type:jsonb;not null;default:{}" json:"meta"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp with time zone" json:"deleted_at"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;not null;default:now()" json:"updated_at"`
}
// Quick operations without importing query package
// Update applies changed fields to the database using the default DB.
func (m *MediaAsset) Update(ctx context.Context) (gen.ResultInfo, error) {
return Q.MediaAsset.WithContext(ctx).Updates(m)
}
// Save upserts the model using the default DB.
func (m *MediaAsset) Save(ctx context.Context) error { return Q.MediaAsset.WithContext(ctx).Save(m) }
// Create inserts the model using the default DB.
func (m *MediaAsset) Create(ctx context.Context) error {
return Q.MediaAsset.WithContext(ctx).Create(m)
}
// Delete removes the row represented by the model using the default DB.
func (m *MediaAsset) Delete(ctx context.Context) (gen.ResultInfo, error) {
return Q.MediaAsset.WithContext(ctx).Delete(m)
}
// ForceDelete permanently deletes the row (ignores soft delete) using the default DB.
func (m *MediaAsset) ForceDelete(ctx context.Context) (gen.ResultInfo, error) {
return Q.MediaAsset.WithContext(ctx).Unscoped().Delete(m)
}
// Restore sets deleted_at to NULL for this model's primary key using the default DB.
func (m *MediaAsset) Restore(ctx context.Context) (gen.ResultInfo, error) {
return Q.MediaAsset.WithContext(ctx).RestoreByID(m.ID)
}
// Reload reloads the model from database by its primary key and overwrites current fields.
func (m *MediaAsset) Reload(ctx context.Context) error {
fresh, err := Q.MediaAsset.WithContext(ctx).GetByID(m.ID)
if err != nil {
return err
}
*m = *fresh
return nil
}

View File

@@ -0,0 +1,518 @@
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
// Code generated by go.ipao.vip/gen. DO NOT EDIT.
package models
import (
"context"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
"go.ipao.vip/gen"
"go.ipao.vip/gen/field"
"gorm.io/plugin/dbresolver"
)
func newMediaAsset(db *gorm.DB, opts ...gen.DOOption) mediaAssetQuery {
_mediaAssetQuery := mediaAssetQuery{}
_mediaAssetQuery.mediaAssetQueryDo.UseDB(db, opts...)
_mediaAssetQuery.mediaAssetQueryDo.UseModel(&MediaAsset{})
tableName := _mediaAssetQuery.mediaAssetQueryDo.TableName()
_mediaAssetQuery.ALL = field.NewAsterisk(tableName)
_mediaAssetQuery.ID = field.NewInt64(tableName, "id")
_mediaAssetQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_mediaAssetQuery.UserID = field.NewInt64(tableName, "user_id")
_mediaAssetQuery.Type = field.NewField(tableName, "type")
_mediaAssetQuery.Status = field.NewField(tableName, "status")
_mediaAssetQuery.Provider = field.NewString(tableName, "provider")
_mediaAssetQuery.Bucket = field.NewString(tableName, "bucket")
_mediaAssetQuery.ObjectKey = field.NewString(tableName, "object_key")
_mediaAssetQuery.Meta = field.NewJSONB(tableName, "meta")
_mediaAssetQuery.DeletedAt = field.NewField(tableName, "deleted_at")
_mediaAssetQuery.CreatedAt = field.NewTime(tableName, "created_at")
_mediaAssetQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_mediaAssetQuery.fillFieldMap()
return _mediaAssetQuery
}
type mediaAssetQuery struct {
mediaAssetQueryDo mediaAssetQueryDo
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
UserID field.Int64
Type field.Field
Status field.Field
Provider field.String
Bucket field.String
ObjectKey field.String
Meta field.JSONB
DeletedAt field.Field
CreatedAt field.Time
UpdatedAt field.Time
fieldMap map[string]field.Expr
}
func (m mediaAssetQuery) Table(newTableName string) *mediaAssetQuery {
m.mediaAssetQueryDo.UseTable(newTableName)
return m.updateTableName(newTableName)
}
func (m mediaAssetQuery) As(alias string) *mediaAssetQuery {
m.mediaAssetQueryDo.DO = *(m.mediaAssetQueryDo.As(alias).(*gen.DO))
return m.updateTableName(alias)
}
func (m *mediaAssetQuery) updateTableName(table string) *mediaAssetQuery {
m.ALL = field.NewAsterisk(table)
m.ID = field.NewInt64(table, "id")
m.TenantID = field.NewInt64(table, "tenant_id")
m.UserID = field.NewInt64(table, "user_id")
m.Type = field.NewField(table, "type")
m.Status = field.NewField(table, "status")
m.Provider = field.NewString(table, "provider")
m.Bucket = field.NewString(table, "bucket")
m.ObjectKey = field.NewString(table, "object_key")
m.Meta = field.NewJSONB(table, "meta")
m.DeletedAt = field.NewField(table, "deleted_at")
m.CreatedAt = field.NewTime(table, "created_at")
m.UpdatedAt = field.NewTime(table, "updated_at")
m.fillFieldMap()
return m
}
func (m *mediaAssetQuery) QueryContext(ctx context.Context) (*mediaAssetQuery, *mediaAssetQueryDo) {
return m, m.mediaAssetQueryDo.WithContext(ctx)
}
func (m *mediaAssetQuery) WithContext(ctx context.Context) *mediaAssetQueryDo {
return m.mediaAssetQueryDo.WithContext(ctx)
}
func (m mediaAssetQuery) TableName() string { return m.mediaAssetQueryDo.TableName() }
func (m mediaAssetQuery) Alias() string { return m.mediaAssetQueryDo.Alias() }
func (m mediaAssetQuery) Columns(cols ...field.Expr) gen.Columns {
return m.mediaAssetQueryDo.Columns(cols...)
}
func (m *mediaAssetQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := m.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (m *mediaAssetQuery) fillFieldMap() {
m.fieldMap = make(map[string]field.Expr, 12)
m.fieldMap["id"] = m.ID
m.fieldMap["tenant_id"] = m.TenantID
m.fieldMap["user_id"] = m.UserID
m.fieldMap["type"] = m.Type
m.fieldMap["status"] = m.Status
m.fieldMap["provider"] = m.Provider
m.fieldMap["bucket"] = m.Bucket
m.fieldMap["object_key"] = m.ObjectKey
m.fieldMap["meta"] = m.Meta
m.fieldMap["deleted_at"] = m.DeletedAt
m.fieldMap["created_at"] = m.CreatedAt
m.fieldMap["updated_at"] = m.UpdatedAt
}
func (m mediaAssetQuery) clone(db *gorm.DB) mediaAssetQuery {
m.mediaAssetQueryDo.ReplaceConnPool(db.Statement.ConnPool)
return m
}
func (m mediaAssetQuery) replaceDB(db *gorm.DB) mediaAssetQuery {
m.mediaAssetQueryDo.ReplaceDB(db)
return m
}
type mediaAssetQueryDo struct{ gen.DO }
func (m mediaAssetQueryDo) Debug() *mediaAssetQueryDo {
return m.withDO(m.DO.Debug())
}
func (m mediaAssetQueryDo) WithContext(ctx context.Context) *mediaAssetQueryDo {
return m.withDO(m.DO.WithContext(ctx))
}
func (m mediaAssetQueryDo) ReadDB() *mediaAssetQueryDo {
return m.Clauses(dbresolver.Read)
}
func (m mediaAssetQueryDo) WriteDB() *mediaAssetQueryDo {
return m.Clauses(dbresolver.Write)
}
func (m mediaAssetQueryDo) Session(config *gorm.Session) *mediaAssetQueryDo {
return m.withDO(m.DO.Session(config))
}
func (m mediaAssetQueryDo) Clauses(conds ...clause.Expression) *mediaAssetQueryDo {
return m.withDO(m.DO.Clauses(conds...))
}
func (m mediaAssetQueryDo) Returning(value interface{}, columns ...string) *mediaAssetQueryDo {
return m.withDO(m.DO.Returning(value, columns...))
}
func (m mediaAssetQueryDo) Not(conds ...gen.Condition) *mediaAssetQueryDo {
return m.withDO(m.DO.Not(conds...))
}
func (m mediaAssetQueryDo) Or(conds ...gen.Condition) *mediaAssetQueryDo {
return m.withDO(m.DO.Or(conds...))
}
func (m mediaAssetQueryDo) Select(conds ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.Select(conds...))
}
func (m mediaAssetQueryDo) Where(conds ...gen.Condition) *mediaAssetQueryDo {
return m.withDO(m.DO.Where(conds...))
}
func (m mediaAssetQueryDo) Order(conds ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.Order(conds...))
}
func (m mediaAssetQueryDo) Distinct(cols ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.Distinct(cols...))
}
func (m mediaAssetQueryDo) Omit(cols ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.Omit(cols...))
}
func (m mediaAssetQueryDo) Join(table schema.Tabler, on ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.Join(table, on...))
}
func (m mediaAssetQueryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.LeftJoin(table, on...))
}
func (m mediaAssetQueryDo) RightJoin(table schema.Tabler, on ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.RightJoin(table, on...))
}
func (m mediaAssetQueryDo) Group(cols ...field.Expr) *mediaAssetQueryDo {
return m.withDO(m.DO.Group(cols...))
}
func (m mediaAssetQueryDo) Having(conds ...gen.Condition) *mediaAssetQueryDo {
return m.withDO(m.DO.Having(conds...))
}
func (m mediaAssetQueryDo) Limit(limit int) *mediaAssetQueryDo {
return m.withDO(m.DO.Limit(limit))
}
func (m mediaAssetQueryDo) Offset(offset int) *mediaAssetQueryDo {
return m.withDO(m.DO.Offset(offset))
}
func (m mediaAssetQueryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *mediaAssetQueryDo {
return m.withDO(m.DO.Scopes(funcs...))
}
func (m mediaAssetQueryDo) Unscoped() *mediaAssetQueryDo {
return m.withDO(m.DO.Unscoped())
}
func (m mediaAssetQueryDo) Create(values ...*MediaAsset) error {
if len(values) == 0 {
return nil
}
return m.DO.Create(values)
}
func (m mediaAssetQueryDo) CreateInBatches(values []*MediaAsset, batchSize int) error {
return m.DO.CreateInBatches(values, batchSize)
}
// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (m mediaAssetQueryDo) Save(values ...*MediaAsset) error {
if len(values) == 0 {
return nil
}
return m.DO.Save(values)
}
func (m mediaAssetQueryDo) First() (*MediaAsset, error) {
if result, err := m.DO.First(); err != nil {
return nil, err
} else {
return result.(*MediaAsset), nil
}
}
func (m mediaAssetQueryDo) Take() (*MediaAsset, error) {
if result, err := m.DO.Take(); err != nil {
return nil, err
} else {
return result.(*MediaAsset), nil
}
}
func (m mediaAssetQueryDo) Last() (*MediaAsset, error) {
if result, err := m.DO.Last(); err != nil {
return nil, err
} else {
return result.(*MediaAsset), nil
}
}
func (m mediaAssetQueryDo) Find() ([]*MediaAsset, error) {
result, err := m.DO.Find()
return result.([]*MediaAsset), err
}
func (m mediaAssetQueryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*MediaAsset, err error) {
buf := make([]*MediaAsset, 0, batchSize)
err = m.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
defer func() { results = append(results, buf...) }()
return fc(tx, batch)
})
return results, err
}
func (m mediaAssetQueryDo) FindInBatches(result *[]*MediaAsset, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return m.DO.FindInBatches(result, batchSize, fc)
}
func (m mediaAssetQueryDo) Attrs(attrs ...field.AssignExpr) *mediaAssetQueryDo {
return m.withDO(m.DO.Attrs(attrs...))
}
func (m mediaAssetQueryDo) Assign(attrs ...field.AssignExpr) *mediaAssetQueryDo {
return m.withDO(m.DO.Assign(attrs...))
}
func (m mediaAssetQueryDo) Joins(fields ...field.RelationField) *mediaAssetQueryDo {
for _, _f := range fields {
m = *m.withDO(m.DO.Joins(_f))
}
return &m
}
func (m mediaAssetQueryDo) Preload(fields ...field.RelationField) *mediaAssetQueryDo {
for _, _f := range fields {
m = *m.withDO(m.DO.Preload(_f))
}
return &m
}
func (m mediaAssetQueryDo) FirstOrInit() (*MediaAsset, error) {
if result, err := m.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*MediaAsset), nil
}
}
func (m mediaAssetQueryDo) FirstOrCreate() (*MediaAsset, error) {
if result, err := m.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*MediaAsset), nil
}
}
func (m mediaAssetQueryDo) FindByPage(offset int, limit int) (result []*MediaAsset, count int64, err error) {
result, err = m.Offset(offset).Limit(limit).Find()
if err != nil {
return
}
if size := len(result); 0 < limit && 0 < size && size < limit {
count = int64(size + offset)
return
}
count, err = m.Offset(-1).Limit(-1).Count()
return
}
func (m mediaAssetQueryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = m.Count()
if err != nil {
return
}
err = m.Offset(offset).Limit(limit).Scan(result)
return
}
func (m mediaAssetQueryDo) Scan(result interface{}) (err error) {
return m.DO.Scan(result)
}
func (m mediaAssetQueryDo) Delete(models ...*MediaAsset) (result gen.ResultInfo, err error) {
return m.DO.Delete(models)
}
// ForceDelete performs a permanent delete (ignores soft-delete) for current scope.
func (m mediaAssetQueryDo) ForceDelete() (gen.ResultInfo, error) {
return m.Unscoped().Delete()
}
// Inc increases the given column by step for current scope.
func (m mediaAssetQueryDo) Inc(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column + step
e := field.NewUnsafeFieldRaw("?+?", column.RawExpr(), step)
return m.DO.UpdateColumn(column, e)
}
// Dec decreases the given column by step for current scope.
func (m mediaAssetQueryDo) Dec(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column - step
e := field.NewUnsafeFieldRaw("?-?", column.RawExpr(), step)
return m.DO.UpdateColumn(column, e)
}
// Sum returns SUM(column) for current scope.
func (m mediaAssetQueryDo) Sum(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("SUM(?)", column.RawExpr())
if err := m.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Avg returns AVG(column) for current scope.
func (m mediaAssetQueryDo) Avg(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("AVG(?)", column.RawExpr())
if err := m.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Min returns MIN(column) for current scope.
func (m mediaAssetQueryDo) Min(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MIN(?)", column.RawExpr())
if err := m.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Max returns MAX(column) for current scope.
func (m mediaAssetQueryDo) Max(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MAX(?)", column.RawExpr())
if err := m.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// PluckMap returns a map[key]value for selected key/value expressions within current scope.
func (m mediaAssetQueryDo) PluckMap(key, val field.Expr) (map[interface{}]interface{}, error) {
do := m.Select(key, val)
rows, err := do.DO.Rows()
if err != nil {
return nil, err
}
defer rows.Close()
mm := make(map[interface{}]interface{})
for rows.Next() {
var k interface{}
var v interface{}
if err := rows.Scan(&k, &v); err != nil {
return nil, err
}
mm[k] = v
}
return mm, rows.Err()
}
// Exists returns true if any record matches the given conditions.
func (m mediaAssetQueryDo) Exists(conds ...gen.Condition) (bool, error) {
cnt, err := m.Where(conds...).Count()
if err != nil {
return false, err
}
return cnt > 0, nil
}
// PluckIDs returns all primary key values under current scope.
func (m mediaAssetQueryDo) PluckIDs() ([]int64, error) {
ids := make([]int64, 0, 16)
pk := field.NewInt64(m.TableName(), "id")
if err := m.DO.Pluck(pk, &ids); err != nil {
return nil, err
}
return ids, nil
}
// GetByID finds a single record by primary key.
func (m mediaAssetQueryDo) GetByID(id int64) (*MediaAsset, error) {
pk := field.NewInt64(m.TableName(), "id")
return m.Where(pk.Eq(id)).First()
}
// GetByIDs finds records by primary key list.
func (m mediaAssetQueryDo) GetByIDs(ids ...int64) ([]*MediaAsset, error) {
if len(ids) == 0 {
return []*MediaAsset{}, nil
}
pk := field.NewInt64(m.TableName(), "id")
return m.Where(pk.In(ids...)).Find()
}
// DeleteByID deletes records by primary key.
func (m mediaAssetQueryDo) DeleteByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(m.TableName(), "id")
return m.Where(pk.Eq(id)).Delete()
}
// DeleteByIDs deletes records by a list of primary keys.
func (m mediaAssetQueryDo) DeleteByIDs(ids ...int64) (gen.ResultInfo, error) {
if len(ids) == 0 {
return gen.ResultInfo{RowsAffected: 0, Error: nil}, nil
}
pk := field.NewInt64(m.TableName(), "id")
return m.Where(pk.In(ids...)).Delete()
}
// RestoreWhere sets deleted_at to NULL for rows matching current scope + conds.
func (m mediaAssetQueryDo) RestoreWhere(conds ...gen.Condition) (gen.ResultInfo, error) {
col := field.NewField(m.TableName(), "deleted_at")
return m.Unscoped().Where(conds...).UpdateColumn(col, nil)
}
// RestoreByID sets deleted_at to NULL for the given primary key.
func (m mediaAssetQueryDo) RestoreByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(m.TableName(), "id")
col := field.NewField(m.TableName(), "deleted_at")
return m.Unscoped().Where(pk.Eq(id)).UpdateColumn(col, nil)
}
func (m *mediaAssetQueryDo) withDO(do gen.Dao) *mediaAssetQueryDo {
m.DO = *do.(*gen.DO)
return m
}

View File

@@ -16,14 +16,24 @@ import (
)
var (
Q = new(Query)
TenantQuery *tenantQuery
TenantUserQuery *tenantUserQuery
UserQuery *userQuery
Q = new(Query)
ContentQuery *contentQuery
ContentAccessQuery *contentAccessQuery
ContentAssetQuery *contentAssetQuery
ContentPriceQuery *contentPriceQuery
MediaAssetQuery *mediaAssetQuery
TenantQuery *tenantQuery
TenantUserQuery *tenantUserQuery
UserQuery *userQuery
)
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
*Q = *Use(db, opts...)
ContentQuery = &Q.Content
ContentAccessQuery = &Q.ContentAccess
ContentAssetQuery = &Q.ContentAsset
ContentPriceQuery = &Q.ContentPrice
MediaAssetQuery = &Q.MediaAsset
TenantQuery = &Q.Tenant
TenantUserQuery = &Q.TenantUser
UserQuery = &Q.User
@@ -31,29 +41,44 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
return &Query{
db: db,
Tenant: newTenant(db, opts...),
TenantUser: newTenantUser(db, opts...),
User: newUser(db, opts...),
db: db,
Content: newContent(db, opts...),
ContentAccess: newContentAccess(db, opts...),
ContentAsset: newContentAsset(db, opts...),
ContentPrice: newContentPrice(db, opts...),
MediaAsset: newMediaAsset(db, opts...),
Tenant: newTenant(db, opts...),
TenantUser: newTenantUser(db, opts...),
User: newUser(db, opts...),
}
}
type Query struct {
db *gorm.DB
Tenant tenantQuery
TenantUser tenantUserQuery
User userQuery
Content contentQuery
ContentAccess contentAccessQuery
ContentAsset contentAssetQuery
ContentPrice contentPriceQuery
MediaAsset mediaAssetQuery
Tenant tenantQuery
TenantUser tenantUserQuery
User userQuery
}
func (q *Query) Available() bool { return q.db != nil }
func (q *Query) clone(db *gorm.DB) *Query {
return &Query{
db: db,
Tenant: q.Tenant.clone(db),
TenantUser: q.TenantUser.clone(db),
User: q.User.clone(db),
db: db,
Content: q.Content.clone(db),
ContentAccess: q.ContentAccess.clone(db),
ContentAsset: q.ContentAsset.clone(db),
ContentPrice: q.ContentPrice.clone(db),
MediaAsset: q.MediaAsset.clone(db),
Tenant: q.Tenant.clone(db),
TenantUser: q.TenantUser.clone(db),
User: q.User.clone(db),
}
}
@@ -67,24 +92,39 @@ func (q *Query) WriteDB() *Query {
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
return &Query{
db: db,
Tenant: q.Tenant.replaceDB(db),
TenantUser: q.TenantUser.replaceDB(db),
User: q.User.replaceDB(db),
db: db,
Content: q.Content.replaceDB(db),
ContentAccess: q.ContentAccess.replaceDB(db),
ContentAsset: q.ContentAsset.replaceDB(db),
ContentPrice: q.ContentPrice.replaceDB(db),
MediaAsset: q.MediaAsset.replaceDB(db),
Tenant: q.Tenant.replaceDB(db),
TenantUser: q.TenantUser.replaceDB(db),
User: q.User.replaceDB(db),
}
}
type queryCtx struct {
Tenant *tenantQueryDo
TenantUser *tenantUserQueryDo
User *userQueryDo
Content *contentQueryDo
ContentAccess *contentAccessQueryDo
ContentAsset *contentAssetQueryDo
ContentPrice *contentPriceQueryDo
MediaAsset *mediaAssetQueryDo
Tenant *tenantQueryDo
TenantUser *tenantUserQueryDo
User *userQueryDo
}
func (q *Query) WithContext(ctx context.Context) *queryCtx {
return &queryCtx{
Tenant: q.Tenant.WithContext(ctx),
TenantUser: q.TenantUser.WithContext(ctx),
User: q.User.WithContext(ctx),
Content: q.Content.WithContext(ctx),
ContentAccess: q.ContentAccess.WithContext(ctx),
ContentAsset: q.ContentAsset.WithContext(ctx),
ContentPrice: q.ContentPrice.WithContext(ctx),
MediaAsset: q.MediaAsset.WithContext(ctx),
Tenant: q.Tenant.WithContext(ctx),
TenantUser: q.TenantUser.WithContext(ctx),
User: q.User.WithContext(ctx),
}
}