From 5ffa151f582077432bca6acac2bd57653aa9c420 Mon Sep 17 00:00:00 2001 From: luorijun Date: Tue, 24 Mar 2026 16:25:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=AE=9A=E4=BB=B7=E4=B8=8E?= =?UTF-8?q?=E5=A5=97=E9=A4=90=E5=85=B3=E8=81=94=E8=A1=A8=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/gen/main.go | 1 + scripts/sql/init.sql | 80 +++++-- web/core/product.go | 8 + web/core/scopes.go | 22 +- web/handlers/product.go | 19 ++ web/handlers/product_discount.go | 105 +++++++++ web/handlers/resource.go | 4 +- web/models/product_discount.go | 19 ++ web/models/product_sku.go | 13 +- web/models/product_sku_user.go | 20 +- web/models/resource.go | 21 +- web/models/resource_long.go | 3 + web/models/resource_short.go | 3 + web/queries/bill.gen.go | 58 +++++ web/queries/channel.gen.go | 58 +++++ web/queries/gen.go | 8 + web/queries/logs_user_usage.gen.go | 58 +++++ web/queries/product_discount.gen.go | 339 ++++++++++++++++++++++++++++ web/queries/product_sku.gen.go | 122 ++++++++-- web/queries/product_sku_user.gen.go | 112 ++++++++- web/queries/proxy.gen.go | 73 ++++++ web/queries/resource.gen.go | 138 ++++++++++- web/queries/resource_long.gen.go | 114 +++++++++- web/queries/resource_short.gen.go | 114 +++++++++- web/routes.go | 6 + web/services/product_discount.go | 59 +++++ web/services/product_sku.go | 47 ++-- web/services/resource.go | 38 ++-- 28 files changed, 1550 insertions(+), 112 deletions(-) create mode 100644 web/core/product.go create mode 100644 web/handlers/product_discount.go create mode 100644 web/models/product_discount.go create mode 100644 web/queries/product_discount.gen.go create mode 100644 web/services/product_discount.go diff --git a/cmd/gen/main.go b/cmd/gen/main.go index 0bf599e..fcd391c 100644 --- a/cmd/gen/main.go +++ b/cmd/gen/main.go @@ -64,6 +64,7 @@ func main() { m.UserRole{}, m.Whitelist{}, m.Inquiry{}, + m.ProductDiscount{}, ) g.Execute() } diff --git a/scripts/sql/init.sql b/scripts/sql/init.sql index 15b8bd5..6e497fa 100644 --- a/scripts/sql/init.sql +++ b/scripts/sql/init.sql @@ -228,7 +228,7 @@ create table admin_role ( name text not null, description text, active bool not null default true, - sort int not null default 0, + sort int not null default 0, created_at timestamptz default current_timestamp, updated_at timestamptz default current_timestamp, deleted_at timestamptz @@ -449,8 +449,8 @@ comment on column permission.deleted_at is '删除时间'; -- link_user_role drop table if exists link_user_role cascade; create table link_user_role ( - id int generated by default as identity primary key, - user_id int not null, + id int generated by default as identity primary key, + user_id int not null, user_role_id int not null ); create index idx_link_user_role_user_id on link_user_role (user_id); @@ -465,9 +465,9 @@ comment on column link_user_role.user_role_id is '角色ID'; -- link_admin_role drop table if exists link_admin_role cascade; create table link_admin_role ( - id int generated by default as identity primary key, - admin_id int not null, - admin_role_id int not null + id int generated by default as identity primary key, + admin_id int not null, + admin_role_id int not null ); create index idx_link_admin_role_admin_id on link_admin_role (admin_id); create index idx_link_admin_role_role_id on link_admin_role (admin_role_id); @@ -482,7 +482,7 @@ comment on column link_admin_role.admin_role_id is '角色ID'; drop table if exists link_user_role_permission cascade; create table link_user_role_permission ( id int generated by default as identity primary key, - user_role_id int not null, + user_role_id int not null, permission_id int not null ); create index idx_link_user_role_permission_role_id on link_user_role_permission (user_role_id); @@ -498,7 +498,7 @@ comment on column link_user_role_permission.permission_id is '权限ID'; drop table if exists link_admin_role_permission cascade; create table link_admin_role_permission ( id int generated by default as identity primary key, - admin_role_id int not null, + admin_role_id int not null, permission_id int not null ); create index idx_link_admin_role_permission_role_id on link_admin_role_permission (admin_role_id); @@ -720,30 +720,52 @@ comment on column product.created_at is '创建时间'; comment on column product.updated_at is '更新时间'; comment on column product.deleted_at is '删除时间'; --- product_sku -drop table if exists product_sku cascade; -create table product_sku ( + +-- product_discount +drop table if exists product_discount cascade; +create table product_discount ( id int generated by default as identity primary key, - product_id int not null, - code text not null, - name text not null, - price decimal not null, - discount float not null, + name text, + discount int, created_at timestamptz default current_timestamp, updated_at timestamptz default current_timestamp, deleted_at timestamptz ); + +-- product_discount表字段注释 +comment on table product_discount is '产品折扣表'; +comment on column product_discount.id is 'ID'; +comment on column product_discount.name is '折扣名称'; +comment on column product_discount.discount is '折扣,0 - 100 的整数,表示 xx 折'; +comment on column product_discount.created_at is '创建时间'; +comment on column product_discount.updated_at is '更新时间'; +comment on column product_discount.deleted_at is '删除时间'; + +-- product_sku +drop table if exists product_sku cascade; +create table product_sku ( + id int generated by default as identity primary key, + product_id int not null, + discount_id int, + code text not null, + name text not null, + price decimal not null, + created_at timestamptz default current_timestamp, + updated_at timestamptz default current_timestamp, + deleted_at timestamptz +); create index idx_product_sku_product_id on product_sku (product_id) where deleted_at is null; +create index idx_product_sku_discount_id on product_sku (discount_id) where deleted_at is null; create index idx_product_sku_code on product_sku (code) where deleted_at is null; -- product_sku表字段注释 comment on table product_sku is '产品SKU表'; comment on column product_sku.id is 'SKU ID'; comment on column product_sku.product_id is '产品ID'; +comment on column product_sku.discount_id is '折扣ID'; comment on column product_sku.code is 'SKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔'; comment on column product_sku.name is 'SKU 可读名称'; comment on column product_sku.price is '定价'; -comment on column product_sku.discount is '折扣,0 - 1 的小数,表示 xx 折'; comment on column product_sku.created_at is '创建时间'; comment on column product_sku.updated_at is '更新时间'; comment on column product_sku.deleted_at is '删除时间'; @@ -754,21 +776,20 @@ create table product_sku_user ( id int generated by default as identity primary key, user_id int not null, product_sku_id int not null, - price decimal, - discount float, + discount_id int, created_at timestamptz default current_timestamp, updated_at timestamptz default current_timestamp ); create index idx_product_sku_user_user_id on product_sku_user (user_id); create index idx_product_sku_user_product_sku_id on product_sku_user (product_sku_id); +create index idx_product_sku_user_discount_id on product_sku_user (discount_id); -- product_sku_user表字段注释 comment on table product_sku_user is '用户产品SKU表'; comment on column product_sku_user.id is 'ID'; comment on column product_sku_user.user_id is '用户ID'; comment on column product_sku_user.product_sku_id is '产品SKU ID'; -comment on column product_sku_user.price is '定价'; -comment on column product_sku_user.discount is '折扣,0 - 1 的小数,表示 xx 折'; +comment on column product_sku_user.discount_id is '折扣ID'; comment on column product_sku_user.created_at is '创建时间'; comment on column product_sku_user.updated_at is '更新时间'; @@ -777,9 +798,10 @@ drop table if exists resource cascade; create table resource ( id int generated by default as identity primary key, user_id int not null, - resource_no text, - active bool not null default true, + resource_no text not null, + code text, type int not null, + active bool not null default true, created_at timestamptz default current_timestamp, updated_at timestamptz default current_timestamp, deleted_at timestamptz @@ -787,6 +809,7 @@ create table resource ( create unique index udx_resource_resource_no on resource (resource_no); create index idx_resource_user_id on resource (user_id) where deleted_at is null; create index idx_resource_created_at on resource (created_at) where deleted_at is null; +create index idx_resource_code on resource (code) where deleted_at is null; -- resource表字段注释 comment on table resource is '套餐表'; @@ -795,6 +818,7 @@ comment on column resource.user_id is '用户ID'; comment on column resource.resource_no is '套餐编号'; comment on column resource.active is '套餐状态'; comment on column resource.type is '套餐类型:1-短效动态,2-长效动态'; +comment on column resource.code is '产品编码'; comment on column resource.created_at is '创建时间'; comment on column resource.updated_at is '更新时间'; comment on column resource.deleted_at is '删除时间'; @@ -804,6 +828,7 @@ drop table if exists resource_short cascade; create table resource_short ( id int generated by default as identity primary key, resource_id int not null, + code text, live int not null, type int not null, quota int not null, @@ -813,11 +838,13 @@ create table resource_short ( last_at timestamptz ); create index idx_resource_short_resource_id on resource_short (resource_id); +create index idx_resource_short_code on resource_short (code); -- resource_short表字段注释 comment on table resource_short is '短效动态套餐表'; comment on column resource_short.id is 'ID'; comment on column resource_short.resource_id is '套餐ID'; +comment on column resource_short.code is '产品套餐编码'; comment on column resource_short.live is '可用时长(秒)'; comment on column resource_short.type is '套餐类型:1-包时,2-包量'; comment on column resource_short.quota is '每日配额(包时)或总配额(包量)'; @@ -831,6 +858,7 @@ drop table if exists resource_long cascade; create table resource_long ( id int generated by default as identity primary key, resource_id int not null, + code text, live int not null, type int not null, quota int not null, @@ -840,11 +868,13 @@ create table resource_long ( last_at timestamptz ); create index idx_resource_long_resource_id on resource_long (resource_id); +create index idx_resource_long_code on resource_long (code); -- resource_long表字段注释 comment on table resource_long is '长效动态套餐表'; comment on column resource_long.id is 'ID'; comment on column resource_long.resource_id is '套餐ID'; +comment on column resource_long.code is '产品套餐编码'; comment on column resource_long.live is '可用时长(小时)'; comment on column resource_long.type is '套餐类型:1-包时,2-包量'; comment on column resource_long.quota is '每日配额(包时)或总配额(包量)'; @@ -1113,11 +1143,15 @@ alter table coupon -- product_sku表外键 alter table product_sku add constraint fk_product_sku_product_id foreign key (product_id) references product (id) on delete cascade; +alter table product_sku + add constraint fk_product_sku_discount_id foreign key (discount_id) references product_discount (id) on delete restrict; -- product_sku_user表外键 alter table product_sku_user add constraint fk_product_sku_user_user_id foreign key (user_id) references "user" (id) on delete cascade; alter table product_sku_user add constraint fk_product_sku_user_product_sku_id foreign key (product_sku_id) references product_sku (id) on delete cascade; +alter table product_sku_user + add constraint fk_product_sku_user_discount_id foreign key (discount_id) references product_discount (id) on delete restrict; -- endregion diff --git a/web/core/product.go b/web/core/product.go new file mode 100644 index 0000000..9c56c53 --- /dev/null +++ b/web/core/product.go @@ -0,0 +1,8 @@ +package core + +type ProductCode string + +var ( + ProductShort ProductCode = "short" + ProductLong ProductCode = "long" +) diff --git a/web/core/scopes.go b/web/core/scopes.go index 187fa2d..a4dd983 100644 --- a/web/core/scopes.go +++ b/web/core/scopes.go @@ -1,14 +1,16 @@ package core const ( - ScopePermissionRead = string("permission:read") - ScopePermissionWrite = string("permission:write") - ScopeAdminRoleRead = string("admin_role:read") - ScopeAdminRoleWrite = string("admin_role:write") - ScopeAdminRead = string("admin:read") - ScopeAdminWrite = string("admin:write") - ScopeProductRead = string("product:read") - ScopeProductWrite = string("product:write") - ScopeProductSkuRead = string("product_sku:read") - ScopeProductSkuWrite = string("product_sku:write") + ScopePermissionRead = string("permission:read") + ScopePermissionWrite = string("permission:write") + ScopeAdminRoleRead = string("admin_role:read") + ScopeAdminRoleWrite = string("admin_role:write") + ScopeAdminRead = string("admin:read") + ScopeAdminWrite = string("admin:write") + ScopeProductRead = string("product:read") + ScopeProductWrite = string("product:write") + ScopeProductSkuRead = string("product_sku:read") + ScopeProductSkuWrite = string("product_sku:write") + ScopeProductDiscountRead = string("product_discount:read") + ScopeProductDiscountWrite = string("product_discount:write") ) diff --git a/web/handlers/product.go b/web/handlers/product.go index b48f0a2..fad4e50 100644 --- a/web/handlers/product.go +++ b/web/handlers/product.go @@ -158,6 +158,25 @@ func UpdateProductSku(c *fiber.Ctx) error { return nil } +func BatchUpdateProductSkuDiscount(c *fiber.Ctx) error { + _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite) + if err != nil { + return err + } + + var req s.BatchUpdateSkuDiscountData + if err := g.Validator.ParseBody(c, &req); err != nil { + return err + } + + err = s.ProductSku.BatchUpdateDiscount(req) + if err != nil { + return err + } + + return nil +} + func DeleteProductSku(c *fiber.Ctx) error { _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite) if err != nil { diff --git a/web/handlers/product_discount.go b/web/handlers/product_discount.go new file mode 100644 index 0000000..779f3c6 --- /dev/null +++ b/web/handlers/product_discount.go @@ -0,0 +1,105 @@ +package handlers + +import ( + "platform/web/auth" + "platform/web/core" + g "platform/web/globals" + s "platform/web/services" + + "github.com/gofiber/fiber/v2" +) + +func PageProductDiscountByAdmin(c *fiber.Ctx) error { + _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductDiscountRead) + if err != nil { + return err + } + + var req core.PageReq + if err := g.Validator.ParseBody(c, &req); err != nil { + return err + } + + list, total, err := s.ProductDiscount.Page(&req) + if err != nil { + return err + } + + return c.JSON(core.PageResp{ + Total: int(total), + Page: req.GetPage(), + Size: req.GetSize(), + List: list, + }) +} + +func AllProductDiscountsByAdmin(c *fiber.Ctx) error { + _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductDiscountRead) + if err != nil { + return err + } + + list, err := s.ProductDiscount.All() + if err != nil { + return err + } + + return c.JSON(list) +} + +func CreateProductDiscount(c *fiber.Ctx) error { + _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductDiscountWrite) + if err != nil { + return err + } + + var req s.CreateProductDiscountData + if err := g.Validator.ParseBody(c, &req); err != nil { + return err + } + + err = s.ProductDiscount.Create(req) + if err != nil { + return err + } + + return nil +} + +func UpdateProductDiscount(c *fiber.Ctx) error { + _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductDiscountWrite) + if err != nil { + return err + } + + var req s.UpdateProductDiscountData + if err := g.Validator.ParseBody(c, &req); err != nil { + return err + } + + err = s.ProductDiscount.Update(req) + if err != nil { + return err + } + + return nil +} + +func DeleteProductDiscount(c *fiber.Ctx) error { + _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductDiscountWrite) + if err != nil { + return err + } + + var req core.IdReq + if err := g.Validator.ParseBody(c, &req); err != nil { + return err + } + + err = s.ProductDiscount.Delete(req.Id) + if err != nil { + return err + } + + return nil +} diff --git a/web/handlers/resource.go b/web/handlers/resource.go index 319d392..084d5bf 100644 --- a/web/handlers/resource.go +++ b/web/handlers/resource.go @@ -70,7 +70,7 @@ func PageResourceShort(c *fiber.Ctx) error { } resource, err := q.Resource.Where(do). - Joins(q.Resource.Short). + Joins(q.Resource.Short, q.ResourceShort.Sku). Order(q.Resource.CreatedAt.Desc()). Offset(req.GetOffset()). Limit(req.GetLimit()). @@ -615,7 +615,7 @@ func ResourcePrice(c *fiber.Ctx) error { // 计算折扣 return c.JSON(ResourcePriceResp{ Price: before.StringFixed(2), - Discounted: sku.Discount, + Discounted: float32(sku.Discount.Discount) / 100, DiscountedPrice: after.StringFixed(2), }) } diff --git a/web/models/product_discount.go b/web/models/product_discount.go new file mode 100644 index 0000000..72c677e --- /dev/null +++ b/web/models/product_discount.go @@ -0,0 +1,19 @@ +package models + +import ( + "platform/web/core" + + "github.com/shopspring/decimal" +) + +// ProductDiscount 产品折扣表 +type ProductDiscount struct { + core.Model + Name string `json:"name" gorm:"column:name"` // 产品名称 + Discount int32 `json:"discount" gorm:"column:discount"` // 产品折扣 +} + +func (pd ProductDiscount) Decimal() decimal.Decimal { + return decimal.NewFromInt32(pd.Discount). + Div(decimal.NewFromInt32(100)) +} diff --git a/web/models/product_sku.go b/web/models/product_sku.go index ef5e1e7..134a101 100644 --- a/web/models/product_sku.go +++ b/web/models/product_sku.go @@ -9,11 +9,12 @@ import ( // ProductSku 产品SKU表 type ProductSku struct { core.Model - ProductID int32 `json:"product_id" gorm:"column:product_id"` // 产品ID - Code string `json:"code" gorm:"column:code"` // SSKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔 - Name string `json:"name" gorm:"column:name"` // SKU 可读名称 - Price decimal.Decimal `json:"price" gorm:"column:price"` // 定价 - Discount float32 `json:"discount" gorm:"column:discount"` // 折扣,0 - 1 的小数,表示 xx 折 + ProductID int32 `json:"product_id" gorm:"column:product_id"` // 产品ID + DiscountId int32 `json:"discount_id" gorm:"column:discount_id"` // 折扣,0 - 1 的小数,表示 xx 折 + Code string `json:"code" gorm:"column:code"` // SSKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔 + Name string `json:"name" gorm:"column:name"` // SKU 可读名称 + Price decimal.Decimal `json:"price" gorm:"column:price"` // 定价 - Product *Product `json:"product,omitempty" gorm:"foreignKey:ProductID"` + Product *Product `json:"product,omitempty" gorm:"foreignKey:ProductID"` + Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountId"` } diff --git a/web/models/product_sku_user.go b/web/models/product_sku_user.go index a98080e..c787b82 100644 --- a/web/models/product_sku_user.go +++ b/web/models/product_sku_user.go @@ -2,20 +2,18 @@ package models import ( "time" - - "github.com/shopspring/decimal" ) // ProductSkuUser 用户产品SKU表 type ProductSkuUser struct { - ID int32 `json:"id" gorm:"column:id;primaryKey"` - UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID - ProductSkuID int32 `json:"product_sku_id" gorm:"column:product_sku_id"` // 产品SKU ID - Price *decimal.Decimal `json:"price,omitempty" gorm:"column:price"` // 定价(覆盖SKU定价) - Discount *float32 `json:"discount,omitempty" gorm:"column:discount"` // 折扣(覆盖SKU折扣) - CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` - UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"` + ID int32 `json:"id" gorm:"column:id;primaryKey"` + UserID int32 `json:"user_id" gorm:"column:user_id"` // 用户ID + ProductSkuID int32 `json:"product_sku_id" gorm:"column:product_sku_id"` // 产品SKU ID + DiscountId int32 `json:"discount_id" gorm:"column:discount_id"` // 折扣ID + CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` + UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"` - User *User `json:"user,omitempty" gorm:"foreignKey:UserID"` - ProductSku *ProductSku `json:"product_sku,omitempty" gorm:"foreignKey:ProductSkuID"` + User *User `json:"user,omitempty" gorm:"foreignKey:UserID"` + ProductSku *ProductSku `json:"product_sku,omitempty" gorm:"foreignKey:ProductSkuID"` + Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountId"` } diff --git a/web/models/resource.go b/web/models/resource.go index 73b27c3..5be92ee 100644 --- a/web/models/resource.go +++ b/web/models/resource.go @@ -11,10 +11,12 @@ type Resource struct { ResourceNo *string `json:"resource_no,omitempty" gorm:"column:resource_no"` // 套餐编号 Active bool `json:"active" gorm:"column:active"` // 套餐状态 Type ResourceType `json:"type" gorm:"column:type"` // 套餐类型:1-短效动态,2-长效动态 + Code string `json:"code" gorm:"column:code"` // 产品编码 - User *User `json:"user,omitempty" gorm:"foreignKey:UserID"` - Short *ResourceShort `json:"short,omitempty" gorm:"foreignKey:ResourceID"` - Long *ResourceLong `json:"long,omitempty" gorm:"foreignKey:ResourceID"` + User *User `json:"user,omitempty" gorm:"foreignKey:UserID"` + Short *ResourceShort `json:"short,omitempty" gorm:"foreignKey:ResourceID"` + Long *ResourceLong `json:"long,omitempty" gorm:"foreignKey:ResourceID"` + Product *Product `json:"product,omitempty" gorm:"foreignKey:Code;references:Code"` } // ResourceType 套餐类型枚举 @@ -25,7 +27,18 @@ const ( ResourceTypeLong ResourceType = 2 // 长效动态 ) -// ResourceLongType 套餐计费模式枚举 +func (t ResourceType) Code() string { + switch t { + case ResourceTypeShort: + return "short" + case ResourceTypeLong: + return "long" + default: + return "unknown" + } +} + +// ResourceMode 套餐计费模式枚举 type ResourceMode int const ( diff --git a/web/models/resource_long.go b/web/models/resource_long.go index 6cd712c..156e4f9 100644 --- a/web/models/resource_long.go +++ b/web/models/resource_long.go @@ -8,6 +8,7 @@ import ( type ResourceLong struct { ID int32 `json:"id" gorm:"column:id"` // ID ResourceID int32 `json:"resource_id" gorm:"column:resource_id"` // 套餐ID + Code string `json:"code" gorm:"column:code"` // 套餐编码 Live int32 `json:"live" gorm:"column:live"` // 可用时长(小时) Type ResourceMode `json:"type" gorm:"column:type"` // 套餐类型:1-包时,2-包量 Quota int32 `json:"quota" gorm:"column:quota"` // 每日配额(包时)或总配额(包量) @@ -15,4 +16,6 @@ type ResourceLong struct { Used int32 `json:"used" gorm:"column:used"` // 总用量 Daily int32 `json:"daily" gorm:"column:daily"` // 当日用量 LastAt *time.Time `json:"last_at,omitempty" gorm:"column:last_at"` // 最后使用时间 + + Sku *ProductSku `json:"sku,omitempty" gorm:"foreignKey:Code;references:Code"` } diff --git a/web/models/resource_short.go b/web/models/resource_short.go index e249de5..a452044 100644 --- a/web/models/resource_short.go +++ b/web/models/resource_short.go @@ -8,6 +8,7 @@ import ( type ResourceShort struct { ID int32 `json:"id" gorm:"column:id"` // ID ResourceID int32 `json:"resource_id" gorm:"column:resource_id"` // 套餐ID + Code string `json:"code" gorm:"column:code"` // 套餐编码 Live int32 `json:"live" gorm:"column:live"` // 可用时长(秒) Type ResourceMode `json:"type" gorm:"column:type"` // 套餐类型:1-包时,2-包量 Quota int32 `json:"quota" gorm:"column:quota"` // 每日配额(包时)或总配额(包量) @@ -15,4 +16,6 @@ type ResourceShort struct { Used int32 `json:"used" gorm:"column:used"` // 总用量 Daily int32 `json:"daily" gorm:"column:daily"` // 当日用量 LastAt *time.Time `json:"last_at,omitempty" gorm:"column:last_at"` // 最后使用时间 + + Sku *ProductSku `json:"sku,omitempty" gorm:"foreignKey:Code;references:Code"` } diff --git a/web/queries/bill.gen.go b/web/queries/bill.gen.go index 62e5f2e..ab4aa9e 100644 --- a/web/queries/bill.gen.go +++ b/web/queries/bill.gen.go @@ -132,13 +132,56 @@ func newBill(db *gorm.DB, opts ...gen.DOOption) bill { }, Short: struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } }{ RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"), + Sku: struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"), + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"), + }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Short.Sku.Discount", "models.ProductDiscount"), + }, + }, }, Long: struct { field.RelationField + Sku struct { + field.RelationField + } }{ RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"), + Sku: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Long.Sku", "models.ProductSku"), + }, + }, + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Product", "models.Product"), }, } @@ -456,9 +499,24 @@ type billBelongsToResource struct { } Short struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } } Long struct { field.RelationField + Sku struct { + field.RelationField + } + } + Product struct { + field.RelationField } } diff --git a/web/queries/channel.gen.go b/web/queries/channel.gen.go index 4c7b909..e3e6669 100644 --- a/web/queries/channel.gen.go +++ b/web/queries/channel.gen.go @@ -129,13 +129,56 @@ func newChannel(db *gorm.DB, opts ...gen.DOOption) channel { }, Short: struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } }{ RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"), + Sku: struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"), + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"), + }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Short.Sku.Discount", "models.ProductDiscount"), + }, + }, }, Long: struct { field.RelationField + Sku struct { + field.RelationField + } }{ RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"), + Sku: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Long.Sku", "models.ProductSku"), + }, + }, + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Product", "models.Product"), }, } @@ -435,9 +478,24 @@ type channelBelongsToResource struct { } Short struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } } Long struct { field.RelationField + Sku struct { + field.RelationField + } + } + Product struct { + field.RelationField } } diff --git a/web/queries/gen.go b/web/queries/gen.go index 0da604d..66cbdf6 100644 --- a/web/queries/gen.go +++ b/web/queries/gen.go @@ -37,6 +37,7 @@ var ( LogsUserUsage *logsUserUsage Permission *permission Product *product + ProductDiscount *productDiscount ProductSku *productSku ProductSkuUser *productSkuUser Proxy *proxy @@ -73,6 +74,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) { LogsUserUsage = &Q.LogsUserUsage Permission = &Q.Permission Product = &Q.Product + ProductDiscount = &Q.ProductDiscount ProductSku = &Q.ProductSku ProductSkuUser = &Q.ProductSkuUser Proxy = &Q.Proxy @@ -110,6 +112,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query { LogsUserUsage: newLogsUserUsage(db, opts...), Permission: newPermission(db, opts...), Product: newProduct(db, opts...), + ProductDiscount: newProductDiscount(db, opts...), ProductSku: newProductSku(db, opts...), ProductSkuUser: newProductSkuUser(db, opts...), Proxy: newProxy(db, opts...), @@ -148,6 +151,7 @@ type Query struct { LogsUserUsage logsUserUsage Permission permission Product product + ProductDiscount productDiscount ProductSku productSku ProductSkuUser productSkuUser Proxy proxy @@ -187,6 +191,7 @@ func (q *Query) clone(db *gorm.DB) *Query { LogsUserUsage: q.LogsUserUsage.clone(db), Permission: q.Permission.clone(db), Product: q.Product.clone(db), + ProductDiscount: q.ProductDiscount.clone(db), ProductSku: q.ProductSku.clone(db), ProductSkuUser: q.ProductSkuUser.clone(db), Proxy: q.Proxy.clone(db), @@ -233,6 +238,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query { LogsUserUsage: q.LogsUserUsage.replaceDB(db), Permission: q.Permission.replaceDB(db), Product: q.Product.replaceDB(db), + ProductDiscount: q.ProductDiscount.replaceDB(db), ProductSku: q.ProductSku.replaceDB(db), ProductSkuUser: q.ProductSkuUser.replaceDB(db), Proxy: q.Proxy.replaceDB(db), @@ -269,6 +275,7 @@ type queryCtx struct { LogsUserUsage *logsUserUsageDo Permission *permissionDo Product *productDo + ProductDiscount *productDiscountDo ProductSku *productSkuDo ProductSkuUser *productSkuUserDo Proxy *proxyDo @@ -305,6 +312,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx { LogsUserUsage: q.LogsUserUsage.WithContext(ctx), Permission: q.Permission.WithContext(ctx), Product: q.Product.WithContext(ctx), + ProductDiscount: q.ProductDiscount.WithContext(ctx), ProductSku: q.ProductSku.WithContext(ctx), ProductSkuUser: q.ProductSkuUser.WithContext(ctx), Proxy: q.Proxy.WithContext(ctx), diff --git a/web/queries/logs_user_usage.gen.go b/web/queries/logs_user_usage.gen.go index 8fe7256..3ba0da6 100644 --- a/web/queries/logs_user_usage.gen.go +++ b/web/queries/logs_user_usage.gen.go @@ -119,13 +119,56 @@ func newLogsUserUsage(db *gorm.DB, opts ...gen.DOOption) logsUserUsage { }, Short: struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } }{ RelationField: field.NewRelation("Resource.Short", "models.ResourceShort"), + Sku: struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("Resource.Short.Sku", "models.ProductSku"), + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Short.Sku.Product", "models.Product"), + }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Short.Sku.Discount", "models.ProductDiscount"), + }, + }, }, Long: struct { field.RelationField + Sku struct { + field.RelationField + } }{ RelationField: field.NewRelation("Resource.Long", "models.ResourceLong"), + Sku: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Long.Sku", "models.ProductSku"), + }, + }, + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Resource.Product", "models.Product"), }, } @@ -336,9 +379,24 @@ type logsUserUsageBelongsToResource struct { } Short struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } } Long struct { field.RelationField + Sku struct { + field.RelationField + } + } + Product struct { + field.RelationField } } diff --git a/web/queries/product_discount.gen.go b/web/queries/product_discount.gen.go new file mode 100644 index 0000000..fa1b552 --- /dev/null +++ b/web/queries/product_discount.gen.go @@ -0,0 +1,339 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package queries + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "platform/web/models" +) + +func newProductDiscount(db *gorm.DB, opts ...gen.DOOption) productDiscount { + _productDiscount := productDiscount{} + + _productDiscount.productDiscountDo.UseDB(db, opts...) + _productDiscount.productDiscountDo.UseModel(&models.ProductDiscount{}) + + tableName := _productDiscount.productDiscountDo.TableName() + _productDiscount.ALL = field.NewAsterisk(tableName) + _productDiscount.ID = field.NewInt32(tableName, "id") + _productDiscount.CreatedAt = field.NewTime(tableName, "created_at") + _productDiscount.UpdatedAt = field.NewTime(tableName, "updated_at") + _productDiscount.DeletedAt = field.NewField(tableName, "deleted_at") + _productDiscount.Name = field.NewString(tableName, "name") + _productDiscount.Discount = field.NewInt32(tableName, "discount") + + _productDiscount.fillFieldMap() + + return _productDiscount +} + +type productDiscount struct { + productDiscountDo + + ALL field.Asterisk + ID field.Int32 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + Name field.String + Discount field.Int32 + + fieldMap map[string]field.Expr +} + +func (p productDiscount) Table(newTableName string) *productDiscount { + p.productDiscountDo.UseTable(newTableName) + return p.updateTableName(newTableName) +} + +func (p productDiscount) As(alias string) *productDiscount { + p.productDiscountDo.DO = *(p.productDiscountDo.As(alias).(*gen.DO)) + return p.updateTableName(alias) +} + +func (p *productDiscount) updateTableName(table string) *productDiscount { + p.ALL = field.NewAsterisk(table) + p.ID = field.NewInt32(table, "id") + p.CreatedAt = field.NewTime(table, "created_at") + p.UpdatedAt = field.NewTime(table, "updated_at") + p.DeletedAt = field.NewField(table, "deleted_at") + p.Name = field.NewString(table, "name") + p.Discount = field.NewInt32(table, "discount") + + p.fillFieldMap() + + return p +} + +func (p *productDiscount) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := p.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (p *productDiscount) fillFieldMap() { + p.fieldMap = make(map[string]field.Expr, 6) + p.fieldMap["id"] = p.ID + p.fieldMap["created_at"] = p.CreatedAt + p.fieldMap["updated_at"] = p.UpdatedAt + p.fieldMap["deleted_at"] = p.DeletedAt + p.fieldMap["name"] = p.Name + p.fieldMap["discount"] = p.Discount +} + +func (p productDiscount) clone(db *gorm.DB) productDiscount { + p.productDiscountDo.ReplaceConnPool(db.Statement.ConnPool) + return p +} + +func (p productDiscount) replaceDB(db *gorm.DB) productDiscount { + p.productDiscountDo.ReplaceDB(db) + return p +} + +type productDiscountDo struct{ gen.DO } + +func (p productDiscountDo) Debug() *productDiscountDo { + return p.withDO(p.DO.Debug()) +} + +func (p productDiscountDo) WithContext(ctx context.Context) *productDiscountDo { + return p.withDO(p.DO.WithContext(ctx)) +} + +func (p productDiscountDo) ReadDB() *productDiscountDo { + return p.Clauses(dbresolver.Read) +} + +func (p productDiscountDo) WriteDB() *productDiscountDo { + return p.Clauses(dbresolver.Write) +} + +func (p productDiscountDo) Session(config *gorm.Session) *productDiscountDo { + return p.withDO(p.DO.Session(config)) +} + +func (p productDiscountDo) Clauses(conds ...clause.Expression) *productDiscountDo { + return p.withDO(p.DO.Clauses(conds...)) +} + +func (p productDiscountDo) Returning(value interface{}, columns ...string) *productDiscountDo { + return p.withDO(p.DO.Returning(value, columns...)) +} + +func (p productDiscountDo) Not(conds ...gen.Condition) *productDiscountDo { + return p.withDO(p.DO.Not(conds...)) +} + +func (p productDiscountDo) Or(conds ...gen.Condition) *productDiscountDo { + return p.withDO(p.DO.Or(conds...)) +} + +func (p productDiscountDo) Select(conds ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.Select(conds...)) +} + +func (p productDiscountDo) Where(conds ...gen.Condition) *productDiscountDo { + return p.withDO(p.DO.Where(conds...)) +} + +func (p productDiscountDo) Order(conds ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.Order(conds...)) +} + +func (p productDiscountDo) Distinct(cols ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.Distinct(cols...)) +} + +func (p productDiscountDo) Omit(cols ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.Omit(cols...)) +} + +func (p productDiscountDo) Join(table schema.Tabler, on ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.Join(table, on...)) +} + +func (p productDiscountDo) LeftJoin(table schema.Tabler, on ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.LeftJoin(table, on...)) +} + +func (p productDiscountDo) RightJoin(table schema.Tabler, on ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.RightJoin(table, on...)) +} + +func (p productDiscountDo) Group(cols ...field.Expr) *productDiscountDo { + return p.withDO(p.DO.Group(cols...)) +} + +func (p productDiscountDo) Having(conds ...gen.Condition) *productDiscountDo { + return p.withDO(p.DO.Having(conds...)) +} + +func (p productDiscountDo) Limit(limit int) *productDiscountDo { + return p.withDO(p.DO.Limit(limit)) +} + +func (p productDiscountDo) Offset(offset int) *productDiscountDo { + return p.withDO(p.DO.Offset(offset)) +} + +func (p productDiscountDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *productDiscountDo { + return p.withDO(p.DO.Scopes(funcs...)) +} + +func (p productDiscountDo) Unscoped() *productDiscountDo { + return p.withDO(p.DO.Unscoped()) +} + +func (p productDiscountDo) Create(values ...*models.ProductDiscount) error { + if len(values) == 0 { + return nil + } + return p.DO.Create(values) +} + +func (p productDiscountDo) CreateInBatches(values []*models.ProductDiscount, batchSize int) error { + return p.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 (p productDiscountDo) Save(values ...*models.ProductDiscount) error { + if len(values) == 0 { + return nil + } + return p.DO.Save(values) +} + +func (p productDiscountDo) First() (*models.ProductDiscount, error) { + if result, err := p.DO.First(); err != nil { + return nil, err + } else { + return result.(*models.ProductDiscount), nil + } +} + +func (p productDiscountDo) Take() (*models.ProductDiscount, error) { + if result, err := p.DO.Take(); err != nil { + return nil, err + } else { + return result.(*models.ProductDiscount), nil + } +} + +func (p productDiscountDo) Last() (*models.ProductDiscount, error) { + if result, err := p.DO.Last(); err != nil { + return nil, err + } else { + return result.(*models.ProductDiscount), nil + } +} + +func (p productDiscountDo) Find() ([]*models.ProductDiscount, error) { + result, err := p.DO.Find() + return result.([]*models.ProductDiscount), err +} + +func (p productDiscountDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.ProductDiscount, err error) { + buf := make([]*models.ProductDiscount, 0, batchSize) + err = p.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 (p productDiscountDo) FindInBatches(result *[]*models.ProductDiscount, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return p.DO.FindInBatches(result, batchSize, fc) +} + +func (p productDiscountDo) Attrs(attrs ...field.AssignExpr) *productDiscountDo { + return p.withDO(p.DO.Attrs(attrs...)) +} + +func (p productDiscountDo) Assign(attrs ...field.AssignExpr) *productDiscountDo { + return p.withDO(p.DO.Assign(attrs...)) +} + +func (p productDiscountDo) Joins(fields ...field.RelationField) *productDiscountDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Joins(_f)) + } + return &p +} + +func (p productDiscountDo) Preload(fields ...field.RelationField) *productDiscountDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Preload(_f)) + } + return &p +} + +func (p productDiscountDo) FirstOrInit() (*models.ProductDiscount, error) { + if result, err := p.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*models.ProductDiscount), nil + } +} + +func (p productDiscountDo) FirstOrCreate() (*models.ProductDiscount, error) { + if result, err := p.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*models.ProductDiscount), nil + } +} + +func (p productDiscountDo) FindByPage(offset int, limit int) (result []*models.ProductDiscount, count int64, err error) { + result, err = p.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 = p.Offset(-1).Limit(-1).Count() + return +} + +func (p productDiscountDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = p.Count() + if err != nil { + return + } + + err = p.Offset(offset).Limit(limit).Scan(result) + return +} + +func (p productDiscountDo) Scan(result interface{}) (err error) { + return p.DO.Scan(result) +} + +func (p productDiscountDo) Delete(models ...*models.ProductDiscount) (result gen.ResultInfo, err error) { + return p.DO.Delete(models) +} + +func (p *productDiscountDo) withDO(do gen.Dao) *productDiscountDo { + p.DO = *do.(*gen.DO) + return p +} diff --git a/web/queries/product_sku.gen.go b/web/queries/product_sku.gen.go index 6b3a9ee..558b75b 100644 --- a/web/queries/product_sku.gen.go +++ b/web/queries/product_sku.gen.go @@ -32,16 +32,22 @@ func newProductSku(db *gorm.DB, opts ...gen.DOOption) productSku { _productSku.UpdatedAt = field.NewTime(tableName, "updated_at") _productSku.DeletedAt = field.NewField(tableName, "deleted_at") _productSku.ProductID = field.NewInt32(tableName, "product_id") + _productSku.DiscountId = field.NewInt32(tableName, "discount_id") _productSku.Code = field.NewString(tableName, "code") _productSku.Name = field.NewString(tableName, "name") _productSku.Price = field.NewField(tableName, "price") - _productSku.Discount = field.NewFloat32(tableName, "discount") _productSku.Product = productSkuBelongsToProduct{ db: db.Session(&gorm.Session{}), RelationField: field.NewRelation("Product", "models.Product"), } + _productSku.Discount = productSkuBelongsToDiscount{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Discount", "models.ProductDiscount"), + } + _productSku.fillFieldMap() return _productSku @@ -50,17 +56,19 @@ func newProductSku(db *gorm.DB, opts ...gen.DOOption) productSku { type productSku struct { productSkuDo - ALL field.Asterisk - ID field.Int32 - CreatedAt field.Time - UpdatedAt field.Time - DeletedAt field.Field - ProductID field.Int32 - Code field.String - Name field.String - Price field.Field - Discount field.Float32 - Product productSkuBelongsToProduct + ALL field.Asterisk + ID field.Int32 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + ProductID field.Int32 + DiscountId field.Int32 + Code field.String + Name field.String + Price field.Field + Product productSkuBelongsToProduct + + Discount productSkuBelongsToDiscount fieldMap map[string]field.Expr } @@ -82,10 +90,10 @@ func (p *productSku) updateTableName(table string) *productSku { p.UpdatedAt = field.NewTime(table, "updated_at") p.DeletedAt = field.NewField(table, "deleted_at") p.ProductID = field.NewInt32(table, "product_id") + p.DiscountId = field.NewInt32(table, "discount_id") p.Code = field.NewString(table, "code") p.Name = field.NewString(table, "name") p.Price = field.NewField(table, "price") - p.Discount = field.NewFloat32(table, "discount") p.fillFieldMap() @@ -102,16 +110,16 @@ func (p *productSku) GetFieldByName(fieldName string) (field.OrderExpr, bool) { } func (p *productSku) fillFieldMap() { - p.fieldMap = make(map[string]field.Expr, 10) + p.fieldMap = make(map[string]field.Expr, 11) p.fieldMap["id"] = p.ID p.fieldMap["created_at"] = p.CreatedAt p.fieldMap["updated_at"] = p.UpdatedAt p.fieldMap["deleted_at"] = p.DeletedAt p.fieldMap["product_id"] = p.ProductID + p.fieldMap["discount_id"] = p.DiscountId p.fieldMap["code"] = p.Code p.fieldMap["name"] = p.Name p.fieldMap["price"] = p.Price - p.fieldMap["discount"] = p.Discount } @@ -119,12 +127,15 @@ func (p productSku) clone(db *gorm.DB) productSku { p.productSkuDo.ReplaceConnPool(db.Statement.ConnPool) p.Product.db = db.Session(&gorm.Session{Initialized: true}) p.Product.db.Statement.ConnPool = db.Statement.ConnPool + p.Discount.db = db.Session(&gorm.Session{Initialized: true}) + p.Discount.db.Statement.ConnPool = db.Statement.ConnPool return p } func (p productSku) replaceDB(db *gorm.DB) productSku { p.productSkuDo.ReplaceDB(db) p.Product.db = db.Session(&gorm.Session{}) + p.Discount.db = db.Session(&gorm.Session{}) return p } @@ -209,6 +220,87 @@ func (a productSkuBelongsToProductTx) Unscoped() *productSkuBelongsToProductTx { return &a } +type productSkuBelongsToDiscount struct { + db *gorm.DB + + field.RelationField +} + +func (a productSkuBelongsToDiscount) Where(conds ...field.Expr) *productSkuBelongsToDiscount { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a productSkuBelongsToDiscount) WithContext(ctx context.Context) *productSkuBelongsToDiscount { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a productSkuBelongsToDiscount) Session(session *gorm.Session) *productSkuBelongsToDiscount { + a.db = a.db.Session(session) + return &a +} + +func (a productSkuBelongsToDiscount) Model(m *models.ProductSku) *productSkuBelongsToDiscountTx { + return &productSkuBelongsToDiscountTx{a.db.Model(m).Association(a.Name())} +} + +func (a productSkuBelongsToDiscount) Unscoped() *productSkuBelongsToDiscount { + a.db = a.db.Unscoped() + return &a +} + +type productSkuBelongsToDiscountTx struct{ tx *gorm.Association } + +func (a productSkuBelongsToDiscountTx) Find() (result *models.ProductDiscount, err error) { + return result, a.tx.Find(&result) +} + +func (a productSkuBelongsToDiscountTx) Append(values ...*models.ProductDiscount) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a productSkuBelongsToDiscountTx) Replace(values ...*models.ProductDiscount) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a productSkuBelongsToDiscountTx) Delete(values ...*models.ProductDiscount) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a productSkuBelongsToDiscountTx) Clear() error { + return a.tx.Clear() +} + +func (a productSkuBelongsToDiscountTx) Count() int64 { + return a.tx.Count() +} + +func (a productSkuBelongsToDiscountTx) Unscoped() *productSkuBelongsToDiscountTx { + a.tx = a.tx.Unscoped() + return &a +} + type productSkuDo struct{ gen.DO } func (p productSkuDo) Debug() *productSkuDo { diff --git a/web/queries/product_sku_user.gen.go b/web/queries/product_sku_user.gen.go index 2734b88..08fde46 100644 --- a/web/queries/product_sku_user.gen.go +++ b/web/queries/product_sku_user.gen.go @@ -30,8 +30,7 @@ func newProductSkuUser(db *gorm.DB, opts ...gen.DOOption) productSkuUser { _productSkuUser.ID = field.NewInt32(tableName, "id") _productSkuUser.UserID = field.NewInt32(tableName, "user_id") _productSkuUser.ProductSkuID = field.NewInt32(tableName, "product_sku_id") - _productSkuUser.Price = field.NewField(tableName, "price") - _productSkuUser.Discount = field.NewFloat32(tableName, "discount") + _productSkuUser.DiscountId = field.NewInt32(tableName, "discount_id") _productSkuUser.CreatedAt = field.NewTime(tableName, "created_at") _productSkuUser.UpdatedAt = field.NewTime(tableName, "updated_at") _productSkuUser.User = productSkuUserBelongsToUser{ @@ -114,6 +113,17 @@ func newProductSkuUser(db *gorm.DB, opts ...gen.DOOption) productSkuUser { }{ RelationField: field.NewRelation("ProductSku.Product", "models.Product"), }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("ProductSku.Discount", "models.ProductDiscount"), + }, + } + + _productSkuUser.Discount = productSkuUserBelongsToDiscount{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Discount", "models.ProductDiscount"), } _productSkuUser.fillFieldMap() @@ -128,14 +138,15 @@ type productSkuUser struct { ID field.Int32 UserID field.Int32 ProductSkuID field.Int32 - Price field.Field - Discount field.Float32 + DiscountId field.Int32 CreatedAt field.Time UpdatedAt field.Time User productSkuUserBelongsToUser ProductSku productSkuUserBelongsToProductSku + Discount productSkuUserBelongsToDiscount + fieldMap map[string]field.Expr } @@ -154,8 +165,7 @@ func (p *productSkuUser) updateTableName(table string) *productSkuUser { p.ID = field.NewInt32(table, "id") p.UserID = field.NewInt32(table, "user_id") p.ProductSkuID = field.NewInt32(table, "product_sku_id") - p.Price = field.NewField(table, "price") - p.Discount = field.NewFloat32(table, "discount") + p.DiscountId = field.NewInt32(table, "discount_id") p.CreatedAt = field.NewTime(table, "created_at") p.UpdatedAt = field.NewTime(table, "updated_at") @@ -178,8 +188,7 @@ func (p *productSkuUser) fillFieldMap() { p.fieldMap["id"] = p.ID p.fieldMap["user_id"] = p.UserID p.fieldMap["product_sku_id"] = p.ProductSkuID - p.fieldMap["price"] = p.Price - p.fieldMap["discount"] = p.Discount + p.fieldMap["discount_id"] = p.DiscountId p.fieldMap["created_at"] = p.CreatedAt p.fieldMap["updated_at"] = p.UpdatedAt @@ -191,6 +200,8 @@ func (p productSkuUser) clone(db *gorm.DB) productSkuUser { p.User.db.Statement.ConnPool = db.Statement.ConnPool p.ProductSku.db = db.Session(&gorm.Session{Initialized: true}) p.ProductSku.db.Statement.ConnPool = db.Statement.ConnPool + p.Discount.db = db.Session(&gorm.Session{Initialized: true}) + p.Discount.db.Statement.ConnPool = db.Statement.ConnPool return p } @@ -198,6 +209,7 @@ func (p productSkuUser) replaceDB(db *gorm.DB) productSkuUser { p.productSkuUserDo.ReplaceDB(db) p.User.db = db.Session(&gorm.Session{}) p.ProductSku.db = db.Session(&gorm.Session{}) + p.Discount.db = db.Session(&gorm.Session{}) return p } @@ -312,6 +324,9 @@ type productSkuUserBelongsToProductSku struct { Product struct { field.RelationField } + Discount struct { + field.RelationField + } } func (a productSkuUserBelongsToProductSku) Where(conds ...field.Expr) *productSkuUserBelongsToProductSku { @@ -389,6 +404,87 @@ func (a productSkuUserBelongsToProductSkuTx) Unscoped() *productSkuUserBelongsTo return &a } +type productSkuUserBelongsToDiscount struct { + db *gorm.DB + + field.RelationField +} + +func (a productSkuUserBelongsToDiscount) Where(conds ...field.Expr) *productSkuUserBelongsToDiscount { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a productSkuUserBelongsToDiscount) WithContext(ctx context.Context) *productSkuUserBelongsToDiscount { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a productSkuUserBelongsToDiscount) Session(session *gorm.Session) *productSkuUserBelongsToDiscount { + a.db = a.db.Session(session) + return &a +} + +func (a productSkuUserBelongsToDiscount) Model(m *models.ProductSkuUser) *productSkuUserBelongsToDiscountTx { + return &productSkuUserBelongsToDiscountTx{a.db.Model(m).Association(a.Name())} +} + +func (a productSkuUserBelongsToDiscount) Unscoped() *productSkuUserBelongsToDiscount { + a.db = a.db.Unscoped() + return &a +} + +type productSkuUserBelongsToDiscountTx struct{ tx *gorm.Association } + +func (a productSkuUserBelongsToDiscountTx) Find() (result *models.ProductDiscount, err error) { + return result, a.tx.Find(&result) +} + +func (a productSkuUserBelongsToDiscountTx) Append(values ...*models.ProductDiscount) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a productSkuUserBelongsToDiscountTx) Replace(values ...*models.ProductDiscount) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a productSkuUserBelongsToDiscountTx) Delete(values ...*models.ProductDiscount) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a productSkuUserBelongsToDiscountTx) Clear() error { + return a.tx.Clear() +} + +func (a productSkuUserBelongsToDiscountTx) Count() int64 { + return a.tx.Count() +} + +func (a productSkuUserBelongsToDiscountTx) Unscoped() *productSkuUserBelongsToDiscountTx { + a.tx = a.tx.Unscoped() + return &a +} + type productSkuUserDo struct{ gen.DO } func (p productSkuUserDo) Debug() *productSkuUserDo { diff --git a/web/queries/proxy.gen.go b/web/queries/proxy.gen.go index d5de9ea..98d5b2e 100644 --- a/web/queries/proxy.gen.go +++ b/web/queries/proxy.gen.go @@ -141,9 +141,24 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy { } Short struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } } Long struct { field.RelationField + Sku struct { + field.RelationField + } + } + Product struct { + field.RelationField } }{ RelationField: field.NewRelation("Channels.Resource", "models.Resource"), @@ -154,13 +169,56 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy { }, Short: struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } }{ RelationField: field.NewRelation("Channels.Resource.Short", "models.ResourceShort"), + Sku: struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("Channels.Resource.Short.Sku", "models.ProductSku"), + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Channels.Resource.Short.Sku.Product", "models.Product"), + }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Channels.Resource.Short.Sku.Discount", "models.ProductDiscount"), + }, + }, }, Long: struct { field.RelationField + Sku struct { + field.RelationField + } }{ RelationField: field.NewRelation("Channels.Resource.Long", "models.ResourceLong"), + Sku: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Channels.Resource.Long.Sku", "models.ProductSku"), + }, + }, + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Channels.Resource.Product", "models.Product"), }, }, Proxy: struct { @@ -314,9 +372,24 @@ type proxyHasManyChannels struct { } Short struct { field.RelationField + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } } Long struct { field.RelationField + Sku struct { + field.RelationField + } + } + Product struct { + field.RelationField } } Proxy struct { diff --git a/web/queries/resource.gen.go b/web/queries/resource.gen.go index c4ae5c9..d372367 100644 --- a/web/queries/resource.gen.go +++ b/web/queries/resource.gen.go @@ -35,16 +35,49 @@ func newResource(db *gorm.DB, opts ...gen.DOOption) resource { _resource.ResourceNo = field.NewString(tableName, "resource_no") _resource.Active = field.NewBool(tableName, "active") _resource.Type = field.NewInt(tableName, "type") + _resource.Code = field.NewString(tableName, "code") _resource.Short = resourceHasOneShort{ db: db.Session(&gorm.Session{}), RelationField: field.NewRelation("Short", "models.ResourceShort"), + Sku: struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + }{ + RelationField: field.NewRelation("Short.Sku", "models.ProductSku"), + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Short.Sku.Product", "models.Product"), + }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Short.Sku.Discount", "models.ProductDiscount"), + }, + }, } _resource.Long = resourceHasOneLong{ db: db.Session(&gorm.Session{}), RelationField: field.NewRelation("Long", "models.ResourceLong"), + Sku: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Long.Sku", "models.ProductSku"), + }, + } + + _resource.Product = resourceHasOneProduct{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Product", "models.Product"), } _resource.User = resourceBelongsToUser{ @@ -135,10 +168,13 @@ type resource struct { ResourceNo field.String Active field.Bool Type field.Int + Code field.String Short resourceHasOneShort Long resourceHasOneLong + Product resourceHasOneProduct + User resourceBelongsToUser fieldMap map[string]field.Expr @@ -164,6 +200,7 @@ func (r *resource) updateTableName(table string) *resource { r.ResourceNo = field.NewString(table, "resource_no") r.Active = field.NewBool(table, "active") r.Type = field.NewInt(table, "type") + r.Code = field.NewString(table, "code") r.fillFieldMap() @@ -180,7 +217,7 @@ func (r *resource) GetFieldByName(fieldName string) (field.OrderExpr, bool) { } func (r *resource) fillFieldMap() { - r.fieldMap = make(map[string]field.Expr, 11) + r.fieldMap = make(map[string]field.Expr, 13) r.fieldMap["id"] = r.ID r.fieldMap["created_at"] = r.CreatedAt r.fieldMap["updated_at"] = r.UpdatedAt @@ -189,6 +226,7 @@ func (r *resource) fillFieldMap() { r.fieldMap["resource_no"] = r.ResourceNo r.fieldMap["active"] = r.Active r.fieldMap["type"] = r.Type + r.fieldMap["code"] = r.Code } @@ -198,6 +236,8 @@ func (r resource) clone(db *gorm.DB) resource { r.Short.db.Statement.ConnPool = db.Statement.ConnPool r.Long.db = db.Session(&gorm.Session{Initialized: true}) r.Long.db.Statement.ConnPool = db.Statement.ConnPool + r.Product.db = db.Session(&gorm.Session{Initialized: true}) + r.Product.db.Statement.ConnPool = db.Statement.ConnPool r.User.db = db.Session(&gorm.Session{Initialized: true}) r.User.db.Statement.ConnPool = db.Statement.ConnPool return r @@ -207,6 +247,7 @@ func (r resource) replaceDB(db *gorm.DB) resource { r.resourceDo.ReplaceDB(db) r.Short.db = db.Session(&gorm.Session{}) r.Long.db = db.Session(&gorm.Session{}) + r.Product.db = db.Session(&gorm.Session{}) r.User.db = db.Session(&gorm.Session{}) return r } @@ -215,6 +256,16 @@ type resourceHasOneShort struct { db *gorm.DB field.RelationField + + Sku struct { + field.RelationField + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } + } } func (a resourceHasOneShort) Where(conds ...field.Expr) *resourceHasOneShort { @@ -296,6 +347,10 @@ type resourceHasOneLong struct { db *gorm.DB field.RelationField + + Sku struct { + field.RelationField + } } func (a resourceHasOneLong) Where(conds ...field.Expr) *resourceHasOneLong { @@ -373,6 +428,87 @@ func (a resourceHasOneLongTx) Unscoped() *resourceHasOneLongTx { return &a } +type resourceHasOneProduct struct { + db *gorm.DB + + field.RelationField +} + +func (a resourceHasOneProduct) Where(conds ...field.Expr) *resourceHasOneProduct { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a resourceHasOneProduct) WithContext(ctx context.Context) *resourceHasOneProduct { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a resourceHasOneProduct) Session(session *gorm.Session) *resourceHasOneProduct { + a.db = a.db.Session(session) + return &a +} + +func (a resourceHasOneProduct) Model(m *models.Resource) *resourceHasOneProductTx { + return &resourceHasOneProductTx{a.db.Model(m).Association(a.Name())} +} + +func (a resourceHasOneProduct) Unscoped() *resourceHasOneProduct { + a.db = a.db.Unscoped() + return &a +} + +type resourceHasOneProductTx struct{ tx *gorm.Association } + +func (a resourceHasOneProductTx) Find() (result *models.Product, err error) { + return result, a.tx.Find(&result) +} + +func (a resourceHasOneProductTx) Append(values ...*models.Product) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a resourceHasOneProductTx) Replace(values ...*models.Product) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a resourceHasOneProductTx) Delete(values ...*models.Product) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a resourceHasOneProductTx) Clear() error { + return a.tx.Clear() +} + +func (a resourceHasOneProductTx) Count() int64 { + return a.tx.Count() +} + +func (a resourceHasOneProductTx) Unscoped() *resourceHasOneProductTx { + a.tx = a.tx.Unscoped() + return &a +} + type resourceBelongsToUser struct { db *gorm.DB diff --git a/web/queries/resource_long.gen.go b/web/queries/resource_long.gen.go index fed7226..52ecdd6 100644 --- a/web/queries/resource_long.gen.go +++ b/web/queries/resource_long.gen.go @@ -29,6 +29,7 @@ func newResourceLong(db *gorm.DB, opts ...gen.DOOption) resourceLong { _resourceLong.ALL = field.NewAsterisk(tableName) _resourceLong.ID = field.NewInt32(tableName, "id") _resourceLong.ResourceID = field.NewInt32(tableName, "resource_id") + _resourceLong.Code = field.NewString(tableName, "code") _resourceLong.Live = field.NewInt32(tableName, "live") _resourceLong.Type = field.NewInt(tableName, "type") _resourceLong.Quota = field.NewInt32(tableName, "quota") @@ -36,6 +37,21 @@ func newResourceLong(db *gorm.DB, opts ...gen.DOOption) resourceLong { _resourceLong.Used = field.NewInt32(tableName, "used") _resourceLong.Daily = field.NewInt32(tableName, "daily") _resourceLong.LastAt = field.NewTime(tableName, "last_at") + _resourceLong.Sku = resourceLongHasOneSku{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Sku", "models.ProductSku"), + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Sku.Product", "models.Product"), + }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Sku.Discount", "models.ProductDiscount"), + }, + } _resourceLong.fillFieldMap() @@ -48,6 +64,7 @@ type resourceLong struct { ALL field.Asterisk ID field.Int32 ResourceID field.Int32 + Code field.String Live field.Int32 Type field.Int Quota field.Int32 @@ -55,6 +72,7 @@ type resourceLong struct { Used field.Int32 Daily field.Int32 LastAt field.Time + Sku resourceLongHasOneSku fieldMap map[string]field.Expr } @@ -73,6 +91,7 @@ func (r *resourceLong) updateTableName(table string) *resourceLong { r.ALL = field.NewAsterisk(table) r.ID = field.NewInt32(table, "id") r.ResourceID = field.NewInt32(table, "resource_id") + r.Code = field.NewString(table, "code") r.Live = field.NewInt32(table, "live") r.Type = field.NewInt(table, "type") r.Quota = field.NewInt32(table, "quota") @@ -96,9 +115,10 @@ func (r *resourceLong) GetFieldByName(fieldName string) (field.OrderExpr, bool) } func (r *resourceLong) fillFieldMap() { - r.fieldMap = make(map[string]field.Expr, 9) + r.fieldMap = make(map[string]field.Expr, 11) r.fieldMap["id"] = r.ID r.fieldMap["resource_id"] = r.ResourceID + r.fieldMap["code"] = r.Code r.fieldMap["live"] = r.Live r.fieldMap["type"] = r.Type r.fieldMap["quota"] = r.Quota @@ -106,18 +126,110 @@ func (r *resourceLong) fillFieldMap() { r.fieldMap["used"] = r.Used r.fieldMap["daily"] = r.Daily r.fieldMap["last_at"] = r.LastAt + } func (r resourceLong) clone(db *gorm.DB) resourceLong { r.resourceLongDo.ReplaceConnPool(db.Statement.ConnPool) + r.Sku.db = db.Session(&gorm.Session{Initialized: true}) + r.Sku.db.Statement.ConnPool = db.Statement.ConnPool return r } func (r resourceLong) replaceDB(db *gorm.DB) resourceLong { r.resourceLongDo.ReplaceDB(db) + r.Sku.db = db.Session(&gorm.Session{}) return r } +type resourceLongHasOneSku struct { + db *gorm.DB + + field.RelationField + + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } +} + +func (a resourceLongHasOneSku) Where(conds ...field.Expr) *resourceLongHasOneSku { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a resourceLongHasOneSku) WithContext(ctx context.Context) *resourceLongHasOneSku { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a resourceLongHasOneSku) Session(session *gorm.Session) *resourceLongHasOneSku { + a.db = a.db.Session(session) + return &a +} + +func (a resourceLongHasOneSku) Model(m *models.ResourceLong) *resourceLongHasOneSkuTx { + return &resourceLongHasOneSkuTx{a.db.Model(m).Association(a.Name())} +} + +func (a resourceLongHasOneSku) Unscoped() *resourceLongHasOneSku { + a.db = a.db.Unscoped() + return &a +} + +type resourceLongHasOneSkuTx struct{ tx *gorm.Association } + +func (a resourceLongHasOneSkuTx) Find() (result *models.ProductSku, err error) { + return result, a.tx.Find(&result) +} + +func (a resourceLongHasOneSkuTx) Append(values ...*models.ProductSku) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a resourceLongHasOneSkuTx) Replace(values ...*models.ProductSku) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a resourceLongHasOneSkuTx) Delete(values ...*models.ProductSku) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a resourceLongHasOneSkuTx) Clear() error { + return a.tx.Clear() +} + +func (a resourceLongHasOneSkuTx) Count() int64 { + return a.tx.Count() +} + +func (a resourceLongHasOneSkuTx) Unscoped() *resourceLongHasOneSkuTx { + a.tx = a.tx.Unscoped() + return &a +} + type resourceLongDo struct{ gen.DO } func (r resourceLongDo) Debug() *resourceLongDo { diff --git a/web/queries/resource_short.gen.go b/web/queries/resource_short.gen.go index 8a72193..827e6bd 100644 --- a/web/queries/resource_short.gen.go +++ b/web/queries/resource_short.gen.go @@ -29,6 +29,7 @@ func newResourceShort(db *gorm.DB, opts ...gen.DOOption) resourceShort { _resourceShort.ALL = field.NewAsterisk(tableName) _resourceShort.ID = field.NewInt32(tableName, "id") _resourceShort.ResourceID = field.NewInt32(tableName, "resource_id") + _resourceShort.Code = field.NewString(tableName, "code") _resourceShort.Live = field.NewInt32(tableName, "live") _resourceShort.Type = field.NewInt(tableName, "type") _resourceShort.Quota = field.NewInt32(tableName, "quota") @@ -36,6 +37,21 @@ func newResourceShort(db *gorm.DB, opts ...gen.DOOption) resourceShort { _resourceShort.Used = field.NewInt32(tableName, "used") _resourceShort.Daily = field.NewInt32(tableName, "daily") _resourceShort.LastAt = field.NewTime(tableName, "last_at") + _resourceShort.Sku = resourceShortHasOneSku{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Sku", "models.ProductSku"), + Product: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Sku.Product", "models.Product"), + }, + Discount: struct { + field.RelationField + }{ + RelationField: field.NewRelation("Sku.Discount", "models.ProductDiscount"), + }, + } _resourceShort.fillFieldMap() @@ -48,6 +64,7 @@ type resourceShort struct { ALL field.Asterisk ID field.Int32 ResourceID field.Int32 + Code field.String Live field.Int32 Type field.Int Quota field.Int32 @@ -55,6 +72,7 @@ type resourceShort struct { Used field.Int32 Daily field.Int32 LastAt field.Time + Sku resourceShortHasOneSku fieldMap map[string]field.Expr } @@ -73,6 +91,7 @@ func (r *resourceShort) updateTableName(table string) *resourceShort { r.ALL = field.NewAsterisk(table) r.ID = field.NewInt32(table, "id") r.ResourceID = field.NewInt32(table, "resource_id") + r.Code = field.NewString(table, "code") r.Live = field.NewInt32(table, "live") r.Type = field.NewInt(table, "type") r.Quota = field.NewInt32(table, "quota") @@ -96,9 +115,10 @@ func (r *resourceShort) GetFieldByName(fieldName string) (field.OrderExpr, bool) } func (r *resourceShort) fillFieldMap() { - r.fieldMap = make(map[string]field.Expr, 9) + r.fieldMap = make(map[string]field.Expr, 11) r.fieldMap["id"] = r.ID r.fieldMap["resource_id"] = r.ResourceID + r.fieldMap["code"] = r.Code r.fieldMap["live"] = r.Live r.fieldMap["type"] = r.Type r.fieldMap["quota"] = r.Quota @@ -106,18 +126,110 @@ func (r *resourceShort) fillFieldMap() { r.fieldMap["used"] = r.Used r.fieldMap["daily"] = r.Daily r.fieldMap["last_at"] = r.LastAt + } func (r resourceShort) clone(db *gorm.DB) resourceShort { r.resourceShortDo.ReplaceConnPool(db.Statement.ConnPool) + r.Sku.db = db.Session(&gorm.Session{Initialized: true}) + r.Sku.db.Statement.ConnPool = db.Statement.ConnPool return r } func (r resourceShort) replaceDB(db *gorm.DB) resourceShort { r.resourceShortDo.ReplaceDB(db) + r.Sku.db = db.Session(&gorm.Session{}) return r } +type resourceShortHasOneSku struct { + db *gorm.DB + + field.RelationField + + Product struct { + field.RelationField + } + Discount struct { + field.RelationField + } +} + +func (a resourceShortHasOneSku) Where(conds ...field.Expr) *resourceShortHasOneSku { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a resourceShortHasOneSku) WithContext(ctx context.Context) *resourceShortHasOneSku { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a resourceShortHasOneSku) Session(session *gorm.Session) *resourceShortHasOneSku { + a.db = a.db.Session(session) + return &a +} + +func (a resourceShortHasOneSku) Model(m *models.ResourceShort) *resourceShortHasOneSkuTx { + return &resourceShortHasOneSkuTx{a.db.Model(m).Association(a.Name())} +} + +func (a resourceShortHasOneSku) Unscoped() *resourceShortHasOneSku { + a.db = a.db.Unscoped() + return &a +} + +type resourceShortHasOneSkuTx struct{ tx *gorm.Association } + +func (a resourceShortHasOneSkuTx) Find() (result *models.ProductSku, err error) { + return result, a.tx.Find(&result) +} + +func (a resourceShortHasOneSkuTx) Append(values ...*models.ProductSku) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a resourceShortHasOneSkuTx) Replace(values ...*models.ProductSku) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a resourceShortHasOneSkuTx) Delete(values ...*models.ProductSku) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a resourceShortHasOneSkuTx) Clear() error { + return a.tx.Clear() +} + +func (a resourceShortHasOneSkuTx) Count() int64 { + return a.tx.Count() +} + +func (a resourceShortHasOneSkuTx) Unscoped() *resourceShortHasOneSkuTx { + a.tx = a.tx.Unscoped() + return &a +} + type resourceShortDo struct{ gen.DO } func (r resourceShortDo) Debug() *resourceShortDo { diff --git a/web/routes.go b/web/routes.go index 1d76d32..7a5b052 100644 --- a/web/routes.go +++ b/web/routes.go @@ -162,5 +162,11 @@ func adminRouter(api fiber.Router) { product.Post("/sku/page", handlers.PageProductSkuByAdmin) product.Post("/sku/create", handlers.CreateProductSku) product.Post("/sku/update", handlers.UpdateProductSku) + product.Post("/sku/update/discount/batch", handlers.BatchUpdateProductSkuDiscount) product.Post("/sku/remove", handlers.DeleteProductSku) + product.Post("/discount/page", handlers.PageProductDiscountByAdmin) + product.Post("/discount/all", handlers.AllProductDiscountsByAdmin) + product.Post("/discount/create", handlers.CreateProductDiscount) + product.Post("/discount/update", handlers.UpdateProductDiscount) + product.Post("/discount/remove", handlers.DeleteProductDiscount) } diff --git a/web/services/product_discount.go b/web/services/product_discount.go new file mode 100644 index 0000000..a65aa04 --- /dev/null +++ b/web/services/product_discount.go @@ -0,0 +1,59 @@ +package services + +import ( + "platform/web/core" + m "platform/web/models" + q "platform/web/queries" + "time" + + "gorm.io/gen/field" +) + +var ProductDiscount = &productDiscountService{} + +type productDiscountService struct{} + +func (s *productDiscountService) All() (result []*m.ProductDiscount, err error) { + return q.ProductDiscount.Find() +} + +func (s *productDiscountService) Page(req *core.PageReq) (result []*m.ProductDiscount, count int64, err error) { + return q.ProductDiscount.FindByPage(req.GetOffset(), req.GetLimit()) +} + +func (s *productDiscountService) Create(data CreateProductDiscountData) (err error) { + return q.ProductDiscount.Create(&m.ProductDiscount{ + Name: data.Name, + Discount: data.Discount, + }) +} + +type CreateProductDiscountData struct { + Name string `json:"name"` + Discount int32 `json:"discount" validate:"min=0,max=100"` +} + +func (s *productDiscountService) Update(data UpdateProductDiscountData) (err error) { + do := make([]field.AssignExpr, 0) + + if data.Name != nil { + do = append(do, q.ProductDiscount.Name.Value(*data.Name)) + } + if data.Discount != nil { + do = append(do, q.ProductDiscount.Discount.Value(*data.Discount)) + } + + _, err = q.ProductDiscount.Where(q.ProductDiscount.ID.Eq(data.ID)).UpdateSimple(do...) + return err +} + +type UpdateProductDiscountData struct { + ID int32 `json:"id"` + Name *string `json:"name"` + Discount *int32 `json:"discount" validate:"omitempty,min=0,max=100"` +} + +func (s *productDiscountService) Delete(id int32) (err error) { + _, err = q.ProductDiscount.Where(q.ProductDiscount.ID.Eq(id)).UpdateColumn(q.ProductDiscount.DeletedAt, time.Now()) + return +} diff --git a/web/services/product_sku.go b/web/services/product_sku.go index 33e2c8f..7dbed0d 100644 --- a/web/services/product_sku.go +++ b/web/services/product_sku.go @@ -21,6 +21,7 @@ func (s *productSkuService) Page(req *core.PageReq, productId *int32) (result [] do = append(do, q.ProductSku.ProductID.Eq(*productId)) } return q.ProductSku. + Joins(q.ProductSku.Discount). Where(do...). FindByPage(req.GetOffset(), req.GetLimit()) } @@ -32,20 +33,20 @@ func (s *productSkuService) Create(create CreateProductSkuData) (err error) { } return q.ProductSku.Create(&m.ProductSku{ - ProductID: create.ProductID, - Code: create.Code, - Name: create.Name, - Price: price, - Discount: create.Discount, + ProductID: create.ProductID, + DiscountId: create.DiscountID, + Code: create.Code, + Name: create.Name, + Price: price, }) } type CreateProductSkuData struct { - ProductID int32 `json:"product_id"` - Code string `json:"code"` - Name string `json:"name"` - Price string `json:"price"` - Discount float32 `json:"discount"` + ProductID int32 `json:"product_id"` + DiscountID int32 `json:"discount_id"` + Code string `json:"code"` + Name string `json:"name"` + Price string `json:"price"` } func (s *productSkuService) Update(update UpdateProductSkuData) (err error) { @@ -58,8 +59,8 @@ func (s *productSkuService) Update(update UpdateProductSkuData) (err error) { } do = append(do, q.ProductSku.Price.Value(price)) } - if update.Discount != nil { - do = append(do, q.ProductSku.Discount.Value(*update.Discount)) + if update.DiscountID != nil { + do = append(do, q.ProductSku.DiscountId.Value(*update.DiscountID)) } if update.Code != nil { do = append(do, q.ProductSku.Code.Value(*update.Code)) @@ -73,14 +74,26 @@ func (s *productSkuService) Update(update UpdateProductSkuData) (err error) { } type UpdateProductSkuData struct { - ID int32 `json:"id"` - Code *string `json:"code"` - Name *string `json:"name"` - Price *string `json:"price"` - Discount *float32 `json:"discount"` + ID int32 `json:"id"` + DiscountID *int32 `json:"discount_id"` + Code *string `json:"code"` + Name *string `json:"name"` + Price *string `json:"price"` } func (s *productSkuService) Delete(id int32) (err error) { _, err = q.ProductSku.Where(q.ProductSku.ID.Eq(id)).UpdateColumn(q.ProductSku.DeletedAt, time.Now()) return } + +func (s *productSkuService) BatchUpdateDiscount(data BatchUpdateSkuDiscountData) (err error) { + _, err = q.ProductSku.Where(q.ProductSku.ProductID.Eq(data.ProductID)).UpdateSimple( + q.ProductSku.DiscountId.Value(data.DiscountID), + ) + return +} + +type BatchUpdateSkuDiscountData struct { + ProductID int32 `json:"product_id"` + DiscountID int32 `json:"discount_id"` +} diff --git a/web/services/resource.go b/web/services/resource.go index 977d808..e655ae0 100644 --- a/web/services/resource.go +++ b/web/services/resource.go @@ -107,6 +107,7 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa ResourceNo: u.P(ID.GenReadable("res")), Active: true, Type: data.Type, + Code: data.Type.Code(), } switch data.Type { @@ -120,6 +121,7 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa Live: short.Live, Type: short.Mode, Quota: short.Quota, + Code: data.Code(), } if short.Mode == m.ResourceModeTime { if short.Expire == nil { @@ -139,6 +141,7 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa Live: long.Live, Type: long.Mode, Quota: long.Quota, + Code: data.Code(), } if long.Mode == m.ResourceModeTime { if long.Expire == nil { @@ -160,11 +163,18 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa } func (s *resourceService) GetSku(data *CreateResourceData) (*m.ProductSku, error) { - sku, err := q.ProductSku.Where(q.ProductSku.Code.Eq(data.Code())).Take() + sku, err := q.ProductSku. + Joins(q.ProductSku.Discount). + Where(q.ProductSku.Code.Eq(data.Code())). + Take() if err != nil { return nil, core.NewServErr("产品不可用", err) } + if sku.Discount == nil { + return nil, core.NewServErr("价格查询失败", err) + } + return sku, nil } @@ -174,28 +184,30 @@ func (s *resourceService) GetPrice(sku *m.ProductSku, count int32, uid *int32) ( var uSku *m.ProductSkuUser if uid != nil { var err error - uSku, err = q.ProductSkuUser.Where( - q.ProductSkuUser.UserID.Eq(*uid), - q.ProductSkuUser.ProductSkuID.Eq(sku.ID), - ).Take() + uSku, err = q.ProductSkuUser. + Joins(q.ProductSkuUser.Discount). + Where( + q.ProductSkuUser.UserID.Eq(*uid), + q.ProductSkuUser.ProductSkuID.Eq(sku.ID)). + Take() if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return decimal.Zero, decimal.Zero, core.NewServErr("客户特殊价查询失败", err) } } - // 返回计算价格 - price := sku.Price - if uSku != nil && uSku.Price != nil { - price = *uSku.Price + if uSku.Discount == nil { + return decimal.Decimal{}, decimal.Decimal{}, core.NewServErr("价格获取失败") } - discount := sku.Discount - if uSku != nil && uSku.Discount != nil { - discount = *uSku.Discount + // 返回计算价格 + price := sku.Price + discount := sku.Discount.Decimal() + if uSku != nil { + discount = uSku.Discount.Decimal() } before := price.Mul(decimal.NewFromInt32(count)) - after := before.Mul(decimal.NewFromFloat32(discount)) + after := before.Mul(discount) return before, after, nil }