feat: add coupon support to orders and create user_coupons model

- Added CouponID field to Order model to track used coupons.
- Updated order query generation to include CouponID.
- Introduced UserCoupon model to manage user coupon associations.
- Implemented query methods for UserCoupon to facilitate CRUD operations.
- Updated query context and default query setup to include UserCoupon.
This commit is contained in:
2025-12-30 17:28:21 +08:00
parent 69d750800c
commit dbfb08ed37
14 changed files with 1454 additions and 35 deletions

View File

@@ -4,6 +4,7 @@ type OrderCreateForm struct {
ContentID string `json:"content_id"`
Sku string `json:"sku"`
Quantity int `json:"quantity"`
UserCouponID string `json:"user_coupon_id"`
}
type OrderCreateResponse struct {

View File

@@ -0,0 +1,84 @@
package services
import (
"context"
"time"
"quyun/v2/app/errorx"
"quyun/v2/database/models"
)
// @provider
type coupon struct{}
// Validate checks if a coupon can be used for an order and returns the discount amount
func (s *coupon) Validate(ctx context.Context, userID, userCouponID, amount int64) (int64, error) {
uc, err := models.UserCouponQuery.WithContext(ctx).Where(models.UserCouponQuery.ID.Eq(userCouponID)).First()
if err != nil {
return 0, errorx.ErrRecordNotFound.WithMsg("优惠券不存在")
}
if uc.UserID != userID {
return 0, errorx.ErrUnauthorized.WithMsg("无权使用该优惠券")
}
if uc.Status != "unused" {
return 0, errorx.ErrBusinessLogic.WithMsg("优惠券已使用或失效")
}
c, err := models.CouponQuery.WithContext(ctx).Where(models.CouponQuery.ID.Eq(uc.CouponID)).First()
if err != nil {
return 0, errorx.ErrRecordNotFound.WithMsg("优惠券信息缺失")
}
now := time.Now()
if !c.StartAt.IsZero() && now.Before(c.StartAt) {
return 0, errorx.ErrBusinessLogic.WithMsg("优惠券尚未生效")
}
if !c.EndAt.IsZero() && now.After(c.EndAt) {
return 0, errorx.ErrBusinessLogic.WithMsg("优惠券已过期")
}
if amount < c.MinOrderAmount {
return 0, errorx.ErrBusinessLogic.WithMsg("未达到优惠券使用门槛")
}
var discount int64
if c.Type == "fix_amount" {
discount = c.Value
} else if c.Type == "discount" {
discount = (amount * c.Value) / 100
if c.MaxDiscount > 0 && discount > c.MaxDiscount {
discount = c.MaxDiscount
}
}
// Discount cannot exceed order amount
if discount > amount {
discount = amount
}
return discount, nil
}
// MarkUsed marks a user coupon as used (intended to be called inside a transaction)
func (s *coupon) MarkUsed(ctx context.Context, tx *models.Query, userCouponID, orderID int64) error {
now := time.Now()
// Update User Coupon
info, err := tx.UserCoupon.WithContext(ctx).Where(tx.UserCoupon.ID.Eq(userCouponID), tx.UserCoupon.Status.Eq("unused")).Updates(&models.UserCoupon{
Status: "used",
OrderID: orderID,
UsedAt: now,
})
if err != nil {
return err
}
if info.RowsAffected == 0 {
return errorx.ErrBusinessLogic.WithMsg("优惠券核销失败")
}
// Update Coupon used quantity (Optional, but good for stats)
// We need CouponID from uc
uc, _ := tx.UserCoupon.WithContext(ctx).Where(tx.UserCoupon.ID.Eq(userCouponID)).First()
_, _ = tx.Coupon.WithContext(ctx).Where(tx.Coupon.ID.Eq(uc.CouponID)).UpdateSimple(tx.Coupon.UsedQuantity.Add(1))
return nil
}

View File

@@ -0,0 +1,111 @@
package services
import (
"context"
"database/sql"
"testing"
"quyun/v2/app/commands/testx"
order_dto "quyun/v2/app/http/v1/dto"
"quyun/v2/database"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
"quyun/v2/providers/storage"
. "github.com/smartystreets/goconvey/convey"
"github.com/spf13/cast"
"github.com/stretchr/testify/suite"
"go.ipao.vip/atom/contracts"
"go.uber.org/dig"
)
type CouponTestSuiteInjectParams struct {
dig.In
DB *sql.DB
Initials []contracts.Initial `group:"initials"`
}
type CouponTestSuite struct {
suite.Suite
CouponTestSuiteInjectParams
}
func Test_Coupon(t *testing.T) {
providers := testx.Default().With(Provide).With(storage.Provide)
testx.Serve(providers, t, func(p CouponTestSuiteInjectParams) {
suite.Run(t, &CouponTestSuite{CouponTestSuiteInjectParams: p})
})
}
func (s *CouponTestSuite) Test_CouponFlow() {
Convey("Coupon Flow", s.T(), func() {
ctx := s.T().Context()
database.Truncate(ctx, s.DB, models.TableNameCoupon, models.TableNameUserCoupon, models.TableNameOrder, models.TableNameUser, models.TableNameContent, models.TableNameContentPrice)
user := &models.User{Username: "coupon_user", Phone: "13800000001"}
models.UserQuery.WithContext(ctx).Create(user)
// 1. Create Coupon (Fixed 5.00 CNY, Min 10.00 CNY)
cp := &models.Coupon{
Title: "Save 5",
Type: "fix_amount",
Value: 500,
MinOrderAmount: 1000,
}
models.CouponQuery.WithContext(ctx).Create(cp)
// 2. Give to User
uc := &models.UserCoupon{
UserID: user.ID,
CouponID: cp.ID,
Status: "unused",
}
models.UserCouponQuery.WithContext(ctx).Create(uc)
Convey("should validate coupon successfully", func() {
discount, err := Coupon.Validate(ctx, user.ID, uc.ID, 1500)
So(err, ShouldBeNil)
So(discount, ShouldEqual, 500)
})
Convey("should fail if below min amount", func() {
_, err := Coupon.Validate(ctx, user.ID, uc.ID, 800)
So(err, ShouldNotBeNil)
})
Convey("should apply in Order.Create", func() {
// Setup Content
c := &models.Content{UserID: 99, Title: "Test", Status: consts.ContentStatusPublished}
models.ContentQuery.WithContext(ctx).Create(c)
models.ContentPriceQuery.WithContext(ctx).Create(&models.ContentPrice{
ContentID: c.ID,
PriceAmount: 2000, // 20.00 CNY
Currency: "CNY",
})
form := &order_dto.OrderCreateForm{
ContentID: cast.ToString(c.ID),
UserCouponID: cast.ToString(uc.ID),
}
// Simulate Auth context for Order service
authCtx := context.WithValue(ctx, consts.CtxKeyUser, user.ID)
res, err := Order.Create(authCtx, form)
So(err, ShouldBeNil)
// Verify Order
oid := cast.ToInt64(res.OrderID)
o, _ := models.OrderQuery.WithContext(ctx).Where(models.OrderQuery.ID.Eq(oid)).First()
So(o.AmountOriginal, ShouldEqual, 2000)
So(o.AmountDiscount, ShouldEqual, 500)
So(o.AmountPaid, ShouldEqual, 1500)
So(o.CouponID, ShouldEqual, cp.ID)
// Verify Coupon Status
ucReload, _ := models.UserCouponQuery.WithContext(ctx).Where(models.UserCouponQuery.ID.Eq(uc.ID)).First()
So(ucReload.Status, ShouldEqual, "used")
So(ucReload.OrderID, ShouldEqual, oid)
})
})
}

View File

@@ -91,11 +91,30 @@ func (s *order) Create(ctx context.Context, form *transaction_dto.OrderCreateFor
price, err := models.ContentPriceQuery.WithContext(ctx).Where(models.ContentPriceQuery.ContentID.Eq(cid)).First()
if err != nil {
// If price missing, treat as error? Or maybe 0?
// Better to require price record.
return nil, errorx.ErrDataCorrupted.WithCause(err).WithMsg("价格信息缺失")
}
amountOriginal := price.PriceAmount
var amountDiscount int64 = 0
var couponID int64 = 0
// Validate Coupon
if form.UserCouponID != "" {
ucid := cast.ToInt64(form.UserCouponID)
discount, err := Coupon.Validate(ctx, uid, ucid, amountOriginal)
if err != nil {
return nil, err
}
amountDiscount = discount
uc, err := models.UserCouponQuery.WithContext(ctx).Where(models.UserCouponQuery.ID.Eq(ucid)).First()
if err == nil {
couponID = uc.CouponID
}
}
amountPaid := amountOriginal - amountDiscount
// 2. Create Order (Status: Created)
order := &models.Order{
TenantID: content.TenantID,
@@ -103,15 +122,17 @@ func (s *order) Create(ctx context.Context, form *transaction_dto.OrderCreateFor
Type: consts.OrderTypeContentPurchase,
Status: consts.OrderStatusCreated,
Currency: consts.Currency(price.Currency),
AmountOriginal: price.PriceAmount,
AmountDiscount: 0,
AmountPaid: price.PriceAmount,
AmountOriginal: amountOriginal,
AmountDiscount: amountDiscount,
AmountPaid: amountPaid,
CouponID: couponID,
IdempotencyKey: uuid.NewString(),
Snapshot: types.NewJSONType(fields.OrdersSnapshot{}),
}
if err := models.OrderQuery.WithContext(ctx).Create(order); err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err)
err = models.Q.Transaction(func(tx *models.Query) error {
if err := tx.Order.WithContext(ctx).Create(order); err != nil {
return err
}
// 3. Create Order Item
@@ -121,9 +142,26 @@ func (s *order) Create(ctx context.Context, form *transaction_dto.OrderCreateFor
OrderID: order.ID,
ContentID: cid,
ContentUserID: content.UserID,
AmountPaid: order.AmountPaid,
AmountPaid: amountPaid,
}
if err := tx.OrderItem.WithContext(ctx).Create(item); err != nil {
return err
}
// Mark Coupon Used
if form.UserCouponID != "" {
if err := Coupon.MarkUsed(ctx, tx, cast.ToInt64(form.UserCouponID), order.ID); err != nil {
return err
}
}
return nil
})
if err != nil {
if _, ok := err.(*errorx.AppError); ok {
return nil, err
}
if err := models.OrderItemQuery.WithContext(ctx).Create(item); err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err)
}

View File

@@ -38,6 +38,13 @@ func Provide(opts ...opt.Option) error {
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*coupon, error) {
obj := &coupon{}
return obj, nil
}); err != nil {
return err
}
if err := container.Container.Provide(func() (*creator, error) {
obj := &creator{}
@@ -67,12 +74,11 @@ func Provide(opts ...opt.Option) error {
audit *audit,
common *common,
content *content,
coupon *coupon,
creator *creator,
db *gorm.DB,
job *job.Job,
notification *notification,
order *order,
storage *storage.Storage,
super *super,
tenant *tenant,
user *user,
@@ -82,12 +88,11 @@ func Provide(opts ...opt.Option) error {
audit: audit,
common: common,
content: content,
coupon: coupon,
creator: creator,
db: db,
job: job,
notification: notification,
order: order,
storage: storage,
super: super,
tenant: tenant,
user: user,

View File

@@ -1,9 +1,6 @@
package services
import (
"quyun/v2/providers/job"
"quyun/v2/providers/storage"
"gorm.io/gorm"
)
@@ -14,11 +11,10 @@ var (
Audit *audit
Common *common
Content *content
Coupon *coupon
Creator *creator
Job *job.Job
Notification *notification
Order *order
Storage *storage.Storage
Super *super
Tenant *tenant
User *user
@@ -32,11 +28,10 @@ type services struct {
audit *audit
common *common
content *content
coupon *coupon
creator *creator
job *job.Job
notification *notification
order *order
storage *storage.Storage
super *super
tenant *tenant
user *user
@@ -50,11 +45,10 @@ func (svc *services) Prepare() error {
Audit = svc.audit
Common = svc.common
Content = svc.content
Coupon = svc.coupon
Creator = svc.creator
Job = svc.job
Notification = svc.notification
Order = svc.order
Storage = svc.storage
Super = svc.super
Tenant = svc.tenant
User = svc.user

View File

@@ -0,0 +1,46 @@
-- +goose Up
-- +goose StatementBegin
CREATE TABLE "coupons" (
"id" BIGSERIAL PRIMARY KEY,
"tenant_id" BIGINT NOT NULL DEFAULT 0, -- 租户ID
"title" VARCHAR(255) NOT NULL, -- 优惠券标题
"description" TEXT, -- 优惠券描述
"type" VARCHAR(32) NOT NULL, -- 优惠券类型: fix_amount(固定金额), discount(折扣比率)
"value" BIGINT NOT NULL, -- 优惠券面值 (固定金额为分折扣比率为0-100)
"min_order_amount" BIGINT NOT NULL DEFAULT 0, -- 最低订单金额门槛 (分)
"max_discount" BIGINT, -- 最高抵扣金额 (分,针对折扣券)
"total_quantity" INTEGER NOT NULL DEFAULT 0, -- 发行总量
"used_quantity" INTEGER NOT NULL DEFAULT 0, -- 已使用数量
"start_at" TIMESTAMPTZ, -- 开始生效时间
"end_at" TIMESTAMPTZ, -- 过期失效时间
"created_at" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX "idx_coupons_tenant_id" ON "coupons" ("tenant_id");
CREATE TABLE "user_coupons" (
"id" BIGSERIAL PRIMARY KEY,
"user_id" BIGINT NOT NULL, -- 用户ID
"coupon_id" BIGINT NOT NULL, -- 优惠券ID
"order_id" BIGINT, -- 使用该优惠券的订单ID
"status" VARCHAR(32) NOT NULL DEFAULT 'unused', -- 状态: unused(未使用), used(已使用), expired(已过期)
"used_at" TIMESTAMPTZ, -- 使用时间
"created_at" TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX "idx_user_coupons_user_id" ON "user_coupons" ("user_id");
CREATE INDEX "idx_user_coupons_coupon_id" ON "user_coupons" ("coupon_id");
-- Add CouponID to Orders table
ALTER TABLE "orders" ADD COLUMN "coupon_id" BIGINT DEFAULT 0; -- 关联优惠券ID (0表示未使用)
COMMENT ON COLUMN "orders"."coupon_id" IS '使用的优惠券ID (0表示未使用)';
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
ALTER TABLE "orders" DROP COLUMN IF EXISTS "coupon_id";
DROP TABLE IF EXISTS "user_coupons";
DROP TABLE IF EXISTS "coupons";
-- +goose StatementEnd

View File

@@ -0,0 +1,64 @@
// 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"
"go.ipao.vip/gen"
)
const TableNameCoupon = "coupons"
// Coupon mapped from table <coupons>
type Coupon 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"`
Title string `gorm:"column:title;type:character varying(255);not null" json:"title"`
Description string `gorm:"column:description;type:text" json:"description"`
Type string `gorm:"column:type;type:character varying(32);not null" json:"type"`
Value int64 `gorm:"column:value;type:bigint;not null" json:"value"`
MinOrderAmount int64 `gorm:"column:min_order_amount;type:bigint;not null" json:"min_order_amount"`
MaxDiscount int64 `gorm:"column:max_discount;type:bigint" json:"max_discount"`
TotalQuantity int32 `gorm:"column:total_quantity;type:integer;not null" json:"total_quantity"`
UsedQuantity int32 `gorm:"column:used_quantity;type:integer;not null" json:"used_quantity"`
StartAt time.Time `gorm:"column:start_at;type:timestamp with time zone" json:"start_at"`
EndAt time.Time `gorm:"column:end_at;type:timestamp with time zone" json:"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 *Coupon) Update(ctx context.Context) (gen.ResultInfo, error) {
return Q.Coupon.WithContext(ctx).Updates(m)
}
// Save upserts the model using the default DB.
func (m *Coupon) Save(ctx context.Context) error { return Q.Coupon.WithContext(ctx).Save(m) }
// Create inserts the model using the default DB.
func (m *Coupon) Create(ctx context.Context) error { return Q.Coupon.WithContext(ctx).Create(m) }
// Delete removes the row represented by the model using the default DB.
func (m *Coupon) Delete(ctx context.Context) (gen.ResultInfo, error) {
return Q.Coupon.WithContext(ctx).Delete(m)
}
// ForceDelete permanently deletes the row (ignores soft delete) using the default DB.
func (m *Coupon) ForceDelete(ctx context.Context) (gen.ResultInfo, error) {
return Q.Coupon.WithContext(ctx).Unscoped().Delete(m)
}
// Reload reloads the model from database by its primary key and overwrites current fields.
func (m *Coupon) Reload(ctx context.Context) error {
fresh, err := Q.Coupon.WithContext(ctx).GetByID(m.ID)
if err != nil {
return err
}
*m = *fresh
return nil
}

View File

@@ -0,0 +1,511 @@
// 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 newCoupon(db *gorm.DB, opts ...gen.DOOption) couponQuery {
_couponQuery := couponQuery{}
_couponQuery.couponQueryDo.UseDB(db, opts...)
_couponQuery.couponQueryDo.UseModel(&Coupon{})
tableName := _couponQuery.couponQueryDo.TableName()
_couponQuery.ALL = field.NewAsterisk(tableName)
_couponQuery.ID = field.NewInt64(tableName, "id")
_couponQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_couponQuery.Title = field.NewString(tableName, "title")
_couponQuery.Description = field.NewString(tableName, "description")
_couponQuery.Type = field.NewString(tableName, "type")
_couponQuery.Value = field.NewInt64(tableName, "value")
_couponQuery.MinOrderAmount = field.NewInt64(tableName, "min_order_amount")
_couponQuery.MaxDiscount = field.NewInt64(tableName, "max_discount")
_couponQuery.TotalQuantity = field.NewInt32(tableName, "total_quantity")
_couponQuery.UsedQuantity = field.NewInt32(tableName, "used_quantity")
_couponQuery.StartAt = field.NewTime(tableName, "start_at")
_couponQuery.EndAt = field.NewTime(tableName, "end_at")
_couponQuery.CreatedAt = field.NewTime(tableName, "created_at")
_couponQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_couponQuery.fillFieldMap()
return _couponQuery
}
type couponQuery struct {
couponQueryDo couponQueryDo
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
Title field.String
Description field.String
Type field.String
Value field.Int64
MinOrderAmount field.Int64
MaxDiscount field.Int64
TotalQuantity field.Int32
UsedQuantity field.Int32
StartAt field.Time
EndAt field.Time
CreatedAt field.Time
UpdatedAt field.Time
fieldMap map[string]field.Expr
}
func (c couponQuery) Table(newTableName string) *couponQuery {
c.couponQueryDo.UseTable(newTableName)
return c.updateTableName(newTableName)
}
func (c couponQuery) As(alias string) *couponQuery {
c.couponQueryDo.DO = *(c.couponQueryDo.As(alias).(*gen.DO))
return c.updateTableName(alias)
}
func (c *couponQuery) updateTableName(table string) *couponQuery {
c.ALL = field.NewAsterisk(table)
c.ID = field.NewInt64(table, "id")
c.TenantID = field.NewInt64(table, "tenant_id")
c.Title = field.NewString(table, "title")
c.Description = field.NewString(table, "description")
c.Type = field.NewString(table, "type")
c.Value = field.NewInt64(table, "value")
c.MinOrderAmount = field.NewInt64(table, "min_order_amount")
c.MaxDiscount = field.NewInt64(table, "max_discount")
c.TotalQuantity = field.NewInt32(table, "total_quantity")
c.UsedQuantity = field.NewInt32(table, "used_quantity")
c.StartAt = field.NewTime(table, "start_at")
c.EndAt = field.NewTime(table, "end_at")
c.CreatedAt = field.NewTime(table, "created_at")
c.UpdatedAt = field.NewTime(table, "updated_at")
c.fillFieldMap()
return c
}
func (c *couponQuery) QueryContext(ctx context.Context) (*couponQuery, *couponQueryDo) {
return c, c.couponQueryDo.WithContext(ctx)
}
func (c *couponQuery) WithContext(ctx context.Context) *couponQueryDo {
return c.couponQueryDo.WithContext(ctx)
}
func (c couponQuery) TableName() string { return c.couponQueryDo.TableName() }
func (c couponQuery) Alias() string { return c.couponQueryDo.Alias() }
func (c couponQuery) Columns(cols ...field.Expr) gen.Columns { return c.couponQueryDo.Columns(cols...) }
func (c *couponQuery) 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 *couponQuery) fillFieldMap() {
c.fieldMap = make(map[string]field.Expr, 14)
c.fieldMap["id"] = c.ID
c.fieldMap["tenant_id"] = c.TenantID
c.fieldMap["title"] = c.Title
c.fieldMap["description"] = c.Description
c.fieldMap["type"] = c.Type
c.fieldMap["value"] = c.Value
c.fieldMap["min_order_amount"] = c.MinOrderAmount
c.fieldMap["max_discount"] = c.MaxDiscount
c.fieldMap["total_quantity"] = c.TotalQuantity
c.fieldMap["used_quantity"] = c.UsedQuantity
c.fieldMap["start_at"] = c.StartAt
c.fieldMap["end_at"] = c.EndAt
c.fieldMap["created_at"] = c.CreatedAt
c.fieldMap["updated_at"] = c.UpdatedAt
}
func (c couponQuery) clone(db *gorm.DB) couponQuery {
c.couponQueryDo.ReplaceConnPool(db.Statement.ConnPool)
return c
}
func (c couponQuery) replaceDB(db *gorm.DB) couponQuery {
c.couponQueryDo.ReplaceDB(db)
return c
}
type couponQueryDo struct{ gen.DO }
func (c couponQueryDo) Debug() *couponQueryDo {
return c.withDO(c.DO.Debug())
}
func (c couponQueryDo) WithContext(ctx context.Context) *couponQueryDo {
return c.withDO(c.DO.WithContext(ctx))
}
func (c couponQueryDo) ReadDB() *couponQueryDo {
return c.Clauses(dbresolver.Read)
}
func (c couponQueryDo) WriteDB() *couponQueryDo {
return c.Clauses(dbresolver.Write)
}
func (c couponQueryDo) Session(config *gorm.Session) *couponQueryDo {
return c.withDO(c.DO.Session(config))
}
func (c couponQueryDo) Clauses(conds ...clause.Expression) *couponQueryDo {
return c.withDO(c.DO.Clauses(conds...))
}
func (c couponQueryDo) Returning(value interface{}, columns ...string) *couponQueryDo {
return c.withDO(c.DO.Returning(value, columns...))
}
func (c couponQueryDo) Not(conds ...gen.Condition) *couponQueryDo {
return c.withDO(c.DO.Not(conds...))
}
func (c couponQueryDo) Or(conds ...gen.Condition) *couponQueryDo {
return c.withDO(c.DO.Or(conds...))
}
func (c couponQueryDo) Select(conds ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.Select(conds...))
}
func (c couponQueryDo) Where(conds ...gen.Condition) *couponQueryDo {
return c.withDO(c.DO.Where(conds...))
}
func (c couponQueryDo) Order(conds ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.Order(conds...))
}
func (c couponQueryDo) Distinct(cols ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.Distinct(cols...))
}
func (c couponQueryDo) Omit(cols ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.Omit(cols...))
}
func (c couponQueryDo) Join(table schema.Tabler, on ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.Join(table, on...))
}
func (c couponQueryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.LeftJoin(table, on...))
}
func (c couponQueryDo) RightJoin(table schema.Tabler, on ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.RightJoin(table, on...))
}
func (c couponQueryDo) Group(cols ...field.Expr) *couponQueryDo {
return c.withDO(c.DO.Group(cols...))
}
func (c couponQueryDo) Having(conds ...gen.Condition) *couponQueryDo {
return c.withDO(c.DO.Having(conds...))
}
func (c couponQueryDo) Limit(limit int) *couponQueryDo {
return c.withDO(c.DO.Limit(limit))
}
func (c couponQueryDo) Offset(offset int) *couponQueryDo {
return c.withDO(c.DO.Offset(offset))
}
func (c couponQueryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *couponQueryDo {
return c.withDO(c.DO.Scopes(funcs...))
}
func (c couponQueryDo) Unscoped() *couponQueryDo {
return c.withDO(c.DO.Unscoped())
}
func (c couponQueryDo) Create(values ...*Coupon) error {
if len(values) == 0 {
return nil
}
return c.DO.Create(values)
}
func (c couponQueryDo) CreateInBatches(values []*Coupon, 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 couponQueryDo) Save(values ...*Coupon) error {
if len(values) == 0 {
return nil
}
return c.DO.Save(values)
}
func (c couponQueryDo) First() (*Coupon, error) {
if result, err := c.DO.First(); err != nil {
return nil, err
} else {
return result.(*Coupon), nil
}
}
func (c couponQueryDo) Take() (*Coupon, error) {
if result, err := c.DO.Take(); err != nil {
return nil, err
} else {
return result.(*Coupon), nil
}
}
func (c couponQueryDo) Last() (*Coupon, error) {
if result, err := c.DO.Last(); err != nil {
return nil, err
} else {
return result.(*Coupon), nil
}
}
func (c couponQueryDo) Find() ([]*Coupon, error) {
result, err := c.DO.Find()
return result.([]*Coupon), err
}
func (c couponQueryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*Coupon, err error) {
buf := make([]*Coupon, 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 couponQueryDo) FindInBatches(result *[]*Coupon, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return c.DO.FindInBatches(result, batchSize, fc)
}
func (c couponQueryDo) Attrs(attrs ...field.AssignExpr) *couponQueryDo {
return c.withDO(c.DO.Attrs(attrs...))
}
func (c couponQueryDo) Assign(attrs ...field.AssignExpr) *couponQueryDo {
return c.withDO(c.DO.Assign(attrs...))
}
func (c couponQueryDo) Joins(fields ...field.RelationField) *couponQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Joins(_f))
}
return &c
}
func (c couponQueryDo) Preload(fields ...field.RelationField) *couponQueryDo {
for _, _f := range fields {
c = *c.withDO(c.DO.Preload(_f))
}
return &c
}
func (c couponQueryDo) FirstOrInit() (*Coupon, error) {
if result, err := c.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*Coupon), nil
}
}
func (c couponQueryDo) FirstOrCreate() (*Coupon, error) {
if result, err := c.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*Coupon), nil
}
}
func (c couponQueryDo) FindByPage(offset int, limit int) (result []*Coupon, 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 couponQueryDo) 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 couponQueryDo) Scan(result interface{}) (err error) {
return c.DO.Scan(result)
}
func (c couponQueryDo) Delete(models ...*Coupon) (result gen.ResultInfo, err error) {
return c.DO.Delete(models)
}
// ForceDelete performs a permanent delete (ignores soft-delete) for current scope.
func (c couponQueryDo) ForceDelete() (gen.ResultInfo, error) {
return c.Unscoped().Delete()
}
// Inc increases the given column by step for current scope.
func (c couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) 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 couponQueryDo) GetByID(id int64) (*Coupon, error) {
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.Eq(id)).First()
}
// GetByIDs finds records by primary key list.
func (c couponQueryDo) GetByIDs(ids ...int64) ([]*Coupon, error) {
if len(ids) == 0 {
return []*Coupon{}, nil
}
pk := field.NewInt64(c.TableName(), "id")
return c.Where(pk.In(ids...)).Find()
}
// DeleteByID deletes records by primary key.
func (c couponQueryDo) 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 couponQueryDo) 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 *couponQueryDo) withDO(do gen.Dao) *couponQueryDo {
c.DO = *do.(*gen.DO)
return c
}

View File

@@ -37,6 +37,7 @@ type Order struct {
RefundReason string `gorm:"column:refund_reason;type:character varying(255)" json:"refund_reason"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"`
CouponID int64 `gorm:"column:coupon_id;type:bigint;comment:使用的优惠券ID (0表示未使用)" json:"coupon_id"` // 使用的优惠券ID (0表示未使用)
}
// Quick operations without importing query package

View File

@@ -43,6 +43,7 @@ func newOrder(db *gorm.DB, opts ...gen.DOOption) orderQuery {
_orderQuery.RefundReason = field.NewString(tableName, "refund_reason")
_orderQuery.CreatedAt = field.NewTime(tableName, "created_at")
_orderQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_orderQuery.CouponID = field.NewInt64(tableName, "coupon_id")
_orderQuery.fillFieldMap()
@@ -71,6 +72,7 @@ type orderQuery struct {
RefundReason field.String
CreatedAt field.Time
UpdatedAt field.Time
CouponID field.Int64 // 使用的优惠券ID (0表示未使用)
fieldMap map[string]field.Expr
}
@@ -105,6 +107,7 @@ func (o *orderQuery) updateTableName(table string) *orderQuery {
o.RefundReason = field.NewString(table, "refund_reason")
o.CreatedAt = field.NewTime(table, "created_at")
o.UpdatedAt = field.NewTime(table, "updated_at")
o.CouponID = field.NewInt64(table, "coupon_id")
o.fillFieldMap()
@@ -135,7 +138,7 @@ func (o *orderQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (o *orderQuery) fillFieldMap() {
o.fieldMap = make(map[string]field.Expr, 18)
o.fieldMap = make(map[string]field.Expr, 19)
o.fieldMap["id"] = o.ID
o.fieldMap["tenant_id"] = o.TenantID
o.fieldMap["user_id"] = o.UserID
@@ -154,6 +157,7 @@ func (o *orderQuery) fillFieldMap() {
o.fieldMap["refund_reason"] = o.RefundReason
o.fieldMap["created_at"] = o.CreatedAt
o.fieldMap["updated_at"] = o.UpdatedAt
o.fieldMap["coupon_id"] = o.CouponID
}
func (o orderQuery) clone(db *gorm.DB) orderQuery {

View File

@@ -22,6 +22,7 @@ var (
ContentAccessQuery *contentAccessQuery
ContentAssetQuery *contentAssetQuery
ContentPriceQuery *contentPriceQuery
CouponQuery *couponQuery
MediaAssetQuery *mediaAssetQuery
NotificationQuery *notificationQuery
OrderQuery *orderQuery
@@ -35,6 +36,7 @@ var (
UserQuery *userQuery
UserCommentActionQuery *userCommentActionQuery
UserContentActionQuery *userContentActionQuery
UserCouponQuery *userCouponQuery
)
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
@@ -44,6 +46,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
ContentAccessQuery = &Q.ContentAccess
ContentAssetQuery = &Q.ContentAsset
ContentPriceQuery = &Q.ContentPrice
CouponQuery = &Q.Coupon
MediaAssetQuery = &Q.MediaAsset
NotificationQuery = &Q.Notification
OrderQuery = &Q.Order
@@ -57,6 +60,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
UserQuery = &Q.User
UserCommentActionQuery = &Q.UserCommentAction
UserContentActionQuery = &Q.UserContentAction
UserCouponQuery = &Q.UserCoupon
}
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
@@ -67,6 +71,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
ContentAccess: newContentAccess(db, opts...),
ContentAsset: newContentAsset(db, opts...),
ContentPrice: newContentPrice(db, opts...),
Coupon: newCoupon(db, opts...),
MediaAsset: newMediaAsset(db, opts...),
Notification: newNotification(db, opts...),
Order: newOrder(db, opts...),
@@ -80,6 +85,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
User: newUser(db, opts...),
UserCommentAction: newUserCommentAction(db, opts...),
UserContentAction: newUserContentAction(db, opts...),
UserCoupon: newUserCoupon(db, opts...),
}
}
@@ -91,6 +97,7 @@ type Query struct {
ContentAccess contentAccessQuery
ContentAsset contentAssetQuery
ContentPrice contentPriceQuery
Coupon couponQuery
MediaAsset mediaAssetQuery
Notification notificationQuery
Order orderQuery
@@ -104,6 +111,7 @@ type Query struct {
User userQuery
UserCommentAction userCommentActionQuery
UserContentAction userContentActionQuery
UserCoupon userCouponQuery
}
func (q *Query) Available() bool { return q.db != nil }
@@ -116,6 +124,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
ContentAccess: q.ContentAccess.clone(db),
ContentAsset: q.ContentAsset.clone(db),
ContentPrice: q.ContentPrice.clone(db),
Coupon: q.Coupon.clone(db),
MediaAsset: q.MediaAsset.clone(db),
Notification: q.Notification.clone(db),
Order: q.Order.clone(db),
@@ -129,6 +138,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
User: q.User.clone(db),
UserCommentAction: q.UserCommentAction.clone(db),
UserContentAction: q.UserContentAction.clone(db),
UserCoupon: q.UserCoupon.clone(db),
}
}
@@ -148,6 +158,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
ContentAccess: q.ContentAccess.replaceDB(db),
ContentAsset: q.ContentAsset.replaceDB(db),
ContentPrice: q.ContentPrice.replaceDB(db),
Coupon: q.Coupon.replaceDB(db),
MediaAsset: q.MediaAsset.replaceDB(db),
Notification: q.Notification.replaceDB(db),
Order: q.Order.replaceDB(db),
@@ -161,6 +172,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
User: q.User.replaceDB(db),
UserCommentAction: q.UserCommentAction.replaceDB(db),
UserContentAction: q.UserContentAction.replaceDB(db),
UserCoupon: q.UserCoupon.replaceDB(db),
}
}
@@ -170,6 +182,7 @@ type queryCtx struct {
ContentAccess *contentAccessQueryDo
ContentAsset *contentAssetQueryDo
ContentPrice *contentPriceQueryDo
Coupon *couponQueryDo
MediaAsset *mediaAssetQueryDo
Notification *notificationQueryDo
Order *orderQueryDo
@@ -183,6 +196,7 @@ type queryCtx struct {
User *userQueryDo
UserCommentAction *userCommentActionQueryDo
UserContentAction *userContentActionQueryDo
UserCoupon *userCouponQueryDo
}
func (q *Query) WithContext(ctx context.Context) *queryCtx {
@@ -192,6 +206,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
ContentAccess: q.ContentAccess.WithContext(ctx),
ContentAsset: q.ContentAsset.WithContext(ctx),
ContentPrice: q.ContentPrice.WithContext(ctx),
Coupon: q.Coupon.WithContext(ctx),
MediaAsset: q.MediaAsset.WithContext(ctx),
Notification: q.Notification.WithContext(ctx),
Order: q.Order.WithContext(ctx),
@@ -205,6 +220,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
User: q.User.WithContext(ctx),
UserCommentAction: q.UserCommentAction.WithContext(ctx),
UserContentAction: q.UserContentAction.WithContext(ctx),
UserCoupon: q.UserCoupon.WithContext(ctx),
}
}

View File

@@ -0,0 +1,59 @@
// 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"
"go.ipao.vip/gen"
)
const TableNameUserCoupon = "user_coupons"
// UserCoupon mapped from table <user_coupons>
type UserCoupon struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
CouponID int64 `gorm:"column:coupon_id;type:bigint;not null" json:"coupon_id"`
OrderID int64 `gorm:"column:order_id;type:bigint" json:"order_id"`
Status string `gorm:"column:status;type:character varying(32);not null;default:unused" json:"status"`
UsedAt time.Time `gorm:"column:used_at;type:timestamp with time zone" json:"used_at"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;not null;default:now()" json:"created_at"`
}
// Quick operations without importing query package
// Update applies changed fields to the database using the default DB.
func (m *UserCoupon) Update(ctx context.Context) (gen.ResultInfo, error) {
return Q.UserCoupon.WithContext(ctx).Updates(m)
}
// Save upserts the model using the default DB.
func (m *UserCoupon) Save(ctx context.Context) error { return Q.UserCoupon.WithContext(ctx).Save(m) }
// Create inserts the model using the default DB.
func (m *UserCoupon) Create(ctx context.Context) error {
return Q.UserCoupon.WithContext(ctx).Create(m)
}
// Delete removes the row represented by the model using the default DB.
func (m *UserCoupon) Delete(ctx context.Context) (gen.ResultInfo, error) {
return Q.UserCoupon.WithContext(ctx).Delete(m)
}
// ForceDelete permanently deletes the row (ignores soft delete) using the default DB.
func (m *UserCoupon) ForceDelete(ctx context.Context) (gen.ResultInfo, error) {
return Q.UserCoupon.WithContext(ctx).Unscoped().Delete(m)
}
// Reload reloads the model from database by its primary key and overwrites current fields.
func (m *UserCoupon) Reload(ctx context.Context) error {
fresh, err := Q.UserCoupon.WithContext(ctx).GetByID(m.ID)
if err != nil {
return err
}
*m = *fresh
return nil
}

View File

@@ -0,0 +1,485 @@
// 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 newUserCoupon(db *gorm.DB, opts ...gen.DOOption) userCouponQuery {
_userCouponQuery := userCouponQuery{}
_userCouponQuery.userCouponQueryDo.UseDB(db, opts...)
_userCouponQuery.userCouponQueryDo.UseModel(&UserCoupon{})
tableName := _userCouponQuery.userCouponQueryDo.TableName()
_userCouponQuery.ALL = field.NewAsterisk(tableName)
_userCouponQuery.ID = field.NewInt64(tableName, "id")
_userCouponQuery.UserID = field.NewInt64(tableName, "user_id")
_userCouponQuery.CouponID = field.NewInt64(tableName, "coupon_id")
_userCouponQuery.OrderID = field.NewInt64(tableName, "order_id")
_userCouponQuery.Status = field.NewString(tableName, "status")
_userCouponQuery.UsedAt = field.NewTime(tableName, "used_at")
_userCouponQuery.CreatedAt = field.NewTime(tableName, "created_at")
_userCouponQuery.fillFieldMap()
return _userCouponQuery
}
type userCouponQuery struct {
userCouponQueryDo userCouponQueryDo
ALL field.Asterisk
ID field.Int64
UserID field.Int64
CouponID field.Int64
OrderID field.Int64
Status field.String
UsedAt field.Time
CreatedAt field.Time
fieldMap map[string]field.Expr
}
func (u userCouponQuery) Table(newTableName string) *userCouponQuery {
u.userCouponQueryDo.UseTable(newTableName)
return u.updateTableName(newTableName)
}
func (u userCouponQuery) As(alias string) *userCouponQuery {
u.userCouponQueryDo.DO = *(u.userCouponQueryDo.As(alias).(*gen.DO))
return u.updateTableName(alias)
}
func (u *userCouponQuery) updateTableName(table string) *userCouponQuery {
u.ALL = field.NewAsterisk(table)
u.ID = field.NewInt64(table, "id")
u.UserID = field.NewInt64(table, "user_id")
u.CouponID = field.NewInt64(table, "coupon_id")
u.OrderID = field.NewInt64(table, "order_id")
u.Status = field.NewString(table, "status")
u.UsedAt = field.NewTime(table, "used_at")
u.CreatedAt = field.NewTime(table, "created_at")
u.fillFieldMap()
return u
}
func (u *userCouponQuery) QueryContext(ctx context.Context) (*userCouponQuery, *userCouponQueryDo) {
return u, u.userCouponQueryDo.WithContext(ctx)
}
func (u *userCouponQuery) WithContext(ctx context.Context) *userCouponQueryDo {
return u.userCouponQueryDo.WithContext(ctx)
}
func (u userCouponQuery) TableName() string { return u.userCouponQueryDo.TableName() }
func (u userCouponQuery) Alias() string { return u.userCouponQueryDo.Alias() }
func (u userCouponQuery) Columns(cols ...field.Expr) gen.Columns {
return u.userCouponQueryDo.Columns(cols...)
}
func (u *userCouponQuery) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
_f, ok := u.fieldMap[fieldName]
if !ok || _f == nil {
return nil, false
}
_oe, ok := _f.(field.OrderExpr)
return _oe, ok
}
func (u *userCouponQuery) fillFieldMap() {
u.fieldMap = make(map[string]field.Expr, 7)
u.fieldMap["id"] = u.ID
u.fieldMap["user_id"] = u.UserID
u.fieldMap["coupon_id"] = u.CouponID
u.fieldMap["order_id"] = u.OrderID
u.fieldMap["status"] = u.Status
u.fieldMap["used_at"] = u.UsedAt
u.fieldMap["created_at"] = u.CreatedAt
}
func (u userCouponQuery) clone(db *gorm.DB) userCouponQuery {
u.userCouponQueryDo.ReplaceConnPool(db.Statement.ConnPool)
return u
}
func (u userCouponQuery) replaceDB(db *gorm.DB) userCouponQuery {
u.userCouponQueryDo.ReplaceDB(db)
return u
}
type userCouponQueryDo struct{ gen.DO }
func (u userCouponQueryDo) Debug() *userCouponQueryDo {
return u.withDO(u.DO.Debug())
}
func (u userCouponQueryDo) WithContext(ctx context.Context) *userCouponQueryDo {
return u.withDO(u.DO.WithContext(ctx))
}
func (u userCouponQueryDo) ReadDB() *userCouponQueryDo {
return u.Clauses(dbresolver.Read)
}
func (u userCouponQueryDo) WriteDB() *userCouponQueryDo {
return u.Clauses(dbresolver.Write)
}
func (u userCouponQueryDo) Session(config *gorm.Session) *userCouponQueryDo {
return u.withDO(u.DO.Session(config))
}
func (u userCouponQueryDo) Clauses(conds ...clause.Expression) *userCouponQueryDo {
return u.withDO(u.DO.Clauses(conds...))
}
func (u userCouponQueryDo) Returning(value interface{}, columns ...string) *userCouponQueryDo {
return u.withDO(u.DO.Returning(value, columns...))
}
func (u userCouponQueryDo) Not(conds ...gen.Condition) *userCouponQueryDo {
return u.withDO(u.DO.Not(conds...))
}
func (u userCouponQueryDo) Or(conds ...gen.Condition) *userCouponQueryDo {
return u.withDO(u.DO.Or(conds...))
}
func (u userCouponQueryDo) Select(conds ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.Select(conds...))
}
func (u userCouponQueryDo) Where(conds ...gen.Condition) *userCouponQueryDo {
return u.withDO(u.DO.Where(conds...))
}
func (u userCouponQueryDo) Order(conds ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.Order(conds...))
}
func (u userCouponQueryDo) Distinct(cols ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.Distinct(cols...))
}
func (u userCouponQueryDo) Omit(cols ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.Omit(cols...))
}
func (u userCouponQueryDo) Join(table schema.Tabler, on ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.Join(table, on...))
}
func (u userCouponQueryDo) LeftJoin(table schema.Tabler, on ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.LeftJoin(table, on...))
}
func (u userCouponQueryDo) RightJoin(table schema.Tabler, on ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.RightJoin(table, on...))
}
func (u userCouponQueryDo) Group(cols ...field.Expr) *userCouponQueryDo {
return u.withDO(u.DO.Group(cols...))
}
func (u userCouponQueryDo) Having(conds ...gen.Condition) *userCouponQueryDo {
return u.withDO(u.DO.Having(conds...))
}
func (u userCouponQueryDo) Limit(limit int) *userCouponQueryDo {
return u.withDO(u.DO.Limit(limit))
}
func (u userCouponQueryDo) Offset(offset int) *userCouponQueryDo {
return u.withDO(u.DO.Offset(offset))
}
func (u userCouponQueryDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *userCouponQueryDo {
return u.withDO(u.DO.Scopes(funcs...))
}
func (u userCouponQueryDo) Unscoped() *userCouponQueryDo {
return u.withDO(u.DO.Unscoped())
}
func (u userCouponQueryDo) Create(values ...*UserCoupon) error {
if len(values) == 0 {
return nil
}
return u.DO.Create(values)
}
func (u userCouponQueryDo) CreateInBatches(values []*UserCoupon, batchSize int) error {
return u.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 (u userCouponQueryDo) Save(values ...*UserCoupon) error {
if len(values) == 0 {
return nil
}
return u.DO.Save(values)
}
func (u userCouponQueryDo) First() (*UserCoupon, error) {
if result, err := u.DO.First(); err != nil {
return nil, err
} else {
return result.(*UserCoupon), nil
}
}
func (u userCouponQueryDo) Take() (*UserCoupon, error) {
if result, err := u.DO.Take(); err != nil {
return nil, err
} else {
return result.(*UserCoupon), nil
}
}
func (u userCouponQueryDo) Last() (*UserCoupon, error) {
if result, err := u.DO.Last(); err != nil {
return nil, err
} else {
return result.(*UserCoupon), nil
}
}
func (u userCouponQueryDo) Find() ([]*UserCoupon, error) {
result, err := u.DO.Find()
return result.([]*UserCoupon), err
}
func (u userCouponQueryDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*UserCoupon, err error) {
buf := make([]*UserCoupon, 0, batchSize)
err = u.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 (u userCouponQueryDo) FindInBatches(result *[]*UserCoupon, batchSize int, fc func(tx gen.Dao, batch int) error) error {
return u.DO.FindInBatches(result, batchSize, fc)
}
func (u userCouponQueryDo) Attrs(attrs ...field.AssignExpr) *userCouponQueryDo {
return u.withDO(u.DO.Attrs(attrs...))
}
func (u userCouponQueryDo) Assign(attrs ...field.AssignExpr) *userCouponQueryDo {
return u.withDO(u.DO.Assign(attrs...))
}
func (u userCouponQueryDo) Joins(fields ...field.RelationField) *userCouponQueryDo {
for _, _f := range fields {
u = *u.withDO(u.DO.Joins(_f))
}
return &u
}
func (u userCouponQueryDo) Preload(fields ...field.RelationField) *userCouponQueryDo {
for _, _f := range fields {
u = *u.withDO(u.DO.Preload(_f))
}
return &u
}
func (u userCouponQueryDo) FirstOrInit() (*UserCoupon, error) {
if result, err := u.DO.FirstOrInit(); err != nil {
return nil, err
} else {
return result.(*UserCoupon), nil
}
}
func (u userCouponQueryDo) FirstOrCreate() (*UserCoupon, error) {
if result, err := u.DO.FirstOrCreate(); err != nil {
return nil, err
} else {
return result.(*UserCoupon), nil
}
}
func (u userCouponQueryDo) FindByPage(offset int, limit int) (result []*UserCoupon, count int64, err error) {
result, err = u.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 = u.Offset(-1).Limit(-1).Count()
return
}
func (u userCouponQueryDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
count, err = u.Count()
if err != nil {
return
}
err = u.Offset(offset).Limit(limit).Scan(result)
return
}
func (u userCouponQueryDo) Scan(result interface{}) (err error) {
return u.DO.Scan(result)
}
func (u userCouponQueryDo) Delete(models ...*UserCoupon) (result gen.ResultInfo, err error) {
return u.DO.Delete(models)
}
// ForceDelete performs a permanent delete (ignores soft-delete) for current scope.
func (u userCouponQueryDo) ForceDelete() (gen.ResultInfo, error) {
return u.Unscoped().Delete()
}
// Inc increases the given column by step for current scope.
func (u userCouponQueryDo) Inc(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column + step
e := field.NewUnsafeFieldRaw("?+?", column.RawExpr(), step)
return u.DO.UpdateColumn(column, e)
}
// Dec decreases the given column by step for current scope.
func (u userCouponQueryDo) Dec(column field.Expr, step int64) (gen.ResultInfo, error) {
// column = column - step
e := field.NewUnsafeFieldRaw("?-?", column.RawExpr(), step)
return u.DO.UpdateColumn(column, e)
}
// Sum returns SUM(column) for current scope.
func (u userCouponQueryDo) Sum(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("SUM(?)", column.RawExpr())
if err := u.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Avg returns AVG(column) for current scope.
func (u userCouponQueryDo) Avg(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("AVG(?)", column.RawExpr())
if err := u.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Min returns MIN(column) for current scope.
func (u userCouponQueryDo) Min(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MIN(?)", column.RawExpr())
if err := u.Select(agg).Scan(&_v); err != nil {
return 0, err
}
return _v, nil
}
// Max returns MAX(column) for current scope.
func (u userCouponQueryDo) Max(column field.Expr) (float64, error) {
var _v float64
agg := field.NewUnsafeFieldRaw("MAX(?)", column.RawExpr())
if err := u.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 (u userCouponQueryDo) PluckMap(key, val field.Expr) (map[interface{}]interface{}, error) {
do := u.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 (u userCouponQueryDo) Exists(conds ...gen.Condition) (bool, error) {
cnt, err := u.Where(conds...).Count()
if err != nil {
return false, err
}
return cnt > 0, nil
}
// PluckIDs returns all primary key values under current scope.
func (u userCouponQueryDo) PluckIDs() ([]int64, error) {
ids := make([]int64, 0, 16)
pk := field.NewInt64(u.TableName(), "id")
if err := u.DO.Pluck(pk, &ids); err != nil {
return nil, err
}
return ids, nil
}
// GetByID finds a single record by primary key.
func (u userCouponQueryDo) GetByID(id int64) (*UserCoupon, error) {
pk := field.NewInt64(u.TableName(), "id")
return u.Where(pk.Eq(id)).First()
}
// GetByIDs finds records by primary key list.
func (u userCouponQueryDo) GetByIDs(ids ...int64) ([]*UserCoupon, error) {
if len(ids) == 0 {
return []*UserCoupon{}, nil
}
pk := field.NewInt64(u.TableName(), "id")
return u.Where(pk.In(ids...)).Find()
}
// DeleteByID deletes records by primary key.
func (u userCouponQueryDo) DeleteByID(id int64) (gen.ResultInfo, error) {
pk := field.NewInt64(u.TableName(), "id")
return u.Where(pk.Eq(id)).Delete()
}
// DeleteByIDs deletes records by a list of primary keys.
func (u userCouponQueryDo) DeleteByIDs(ids ...int64) (gen.ResultInfo, error) {
if len(ids) == 0 {
return gen.ResultInfo{RowsAffected: 0, Error: nil}, nil
}
pk := field.NewInt64(u.TableName(), "id")
return u.Where(pk.In(ids...)).Delete()
}
func (u *userCouponQueryDo) withDO(do gen.Dao) *userCouponQueryDo {
u.DO = *do.(*gen.DO)
return u
}