refactor: 优化订单时间字段处理及数据库模型结构调整
- 将订单的PaidAt和CancelledAt从指针类型改为值类型 - 统一时间字段的判空逻辑,使用IsZero()替代nil检查 - 调整多个数据库模型结构,添加新字段并优化字段顺序 - 为活动奖励设置、用户邀请等表添加新字段 - 更新对应的DAO层代码以匹配模型变更
This commit is contained in:
parent
a7a0f639e1
commit
425e64daa5
@ -253,7 +253,7 @@ func (h *handler) ListPayOrders() core.HandlerFunc {
|
|||||||
"actual_amount": o.ActualAmount,
|
"actual_amount": o.ActualAmount,
|
||||||
"status": o.Status,
|
"status": o.Status,
|
||||||
"paid_at": func() string {
|
"paid_at": func() string {
|
||||||
if o.PaidAt != nil && !o.PaidAt.IsZero() {
|
if !o.PaidAt.IsZero() {
|
||||||
return o.PaidAt.Format("2006-01-02 15:04:05")
|
return o.PaidAt.Format("2006-01-02 15:04:05")
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
@ -585,7 +585,7 @@ func (h *handler) GetPayOrderDetail() core.HandlerFunc {
|
|||||||
Status: order.Status,
|
Status: order.Status,
|
||||||
ActualAmount: order.ActualAmount,
|
ActualAmount: order.ActualAmount,
|
||||||
PaidAt: func() string {
|
PaidAt: func() string {
|
||||||
if order.PaidAt != nil && !order.PaidAt.IsZero() {
|
if !order.PaidAt.IsZero() {
|
||||||
return order.PaidAt.Format("2006-01-02 15:04:05")
|
return order.PaidAt.Format("2006-01-02 15:04:05")
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@ -100,7 +100,7 @@ func (h *handler) ExportPayOrders() core.HandlerFunc {
|
|||||||
r.AddCell().SetInt64(pu)
|
r.AddCell().SetInt64(pu)
|
||||||
r.AddCell().SetInt64(couponApplied)
|
r.AddCell().SetInt64(couponApplied)
|
||||||
r.AddCell().SetInt64(o.ActualAmount)
|
r.AddCell().SetInt64(o.ActualAmount)
|
||||||
if o.PaidAt != nil {
|
if !o.PaidAt.IsZero() {
|
||||||
r.AddCell().Value = o.PaidAt.Format("2006-01-02 15:04:05")
|
r.AddCell().Value = o.PaidAt.Format("2006-01-02 15:04:05")
|
||||||
} else {
|
} else {
|
||||||
r.AddCell().Value = ""
|
r.AddCell().Value = ""
|
||||||
|
|||||||
@ -11,12 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type createProductRequest struct {
|
type createProductRequest struct {
|
||||||
Name string `json:"name" binding:"required"`
|
Name string `json:"name" binding:"required"`
|
||||||
CategoryID int64 `json:"category_id" binding:"required"`
|
CategoryID int64 `json:"category_id" binding:"required"`
|
||||||
ImagesJSON string `json:"images_json"`
|
ImagesJSON string `json:"images_json"`
|
||||||
Price int64 `json:"price" binding:"required"`
|
Price int64 `json:"price" binding:"required"`
|
||||||
Stock int64 `json:"stock" binding:"required"`
|
Stock int64 `json:"stock" binding:"required"`
|
||||||
Status int32 `json:"status"`
|
Status int32 `json:"status"`
|
||||||
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type createProductResponse struct {
|
type createProductResponse struct {
|
||||||
@ -46,7 +47,7 @@ func (h *handler) CreateProduct() core.HandlerFunc {
|
|||||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.product.CreateProduct(ctx.RequestContext(), prodsvc.CreateProductInput{Name: req.Name, CategoryID: req.CategoryID, ImagesJSON: req.ImagesJSON, Price: req.Price, Stock: req.Stock, Status: req.Status})
|
item, err := h.product.CreateProduct(ctx.RequestContext(), prodsvc.CreateProductInput{Name: req.Name, CategoryID: req.CategoryID, ImagesJSON: req.ImagesJSON, Price: req.Price, Stock: req.Stock, Status: req.Status, Description: req.Description})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
||||||
return
|
return
|
||||||
@ -58,12 +59,13 @@ func (h *handler) CreateProduct() core.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type modifyProductRequest struct {
|
type modifyProductRequest struct {
|
||||||
Name *string `json:"name"`
|
Name *string `json:"name"`
|
||||||
CategoryID *int64 `json:"category_id"`
|
CategoryID *int64 `json:"category_id"`
|
||||||
ImagesJSON *string `json:"images_json"`
|
ImagesJSON *string `json:"images_json"`
|
||||||
Price *int64 `json:"price"`
|
Price *int64 `json:"price"`
|
||||||
Stock *int64 `json:"stock"`
|
Stock *int64 `json:"stock"`
|
||||||
Status *int32 `json:"status"`
|
Status *int32 `json:"status"`
|
||||||
|
Description *string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ModifyProduct 修改商品
|
// ModifyProduct 修改商品
|
||||||
@ -90,7 +92,7 @@ func (h *handler) ModifyProduct() core.HandlerFunc {
|
|||||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := h.product.ModifyProduct(ctx.RequestContext(), id, prodsvc.ModifyProductInput{Name: req.Name, CategoryID: req.CategoryID, ImagesJSON: req.ImagesJSON, Price: req.Price, Stock: req.Stock, Status: req.Status}); err != nil {
|
if err := h.product.ModifyProduct(ctx.RequestContext(), id, prodsvc.ModifyProductInput{Name: req.Name, CategoryID: req.CategoryID, ImagesJSON: req.ImagesJSON, Price: req.Price, Stock: req.Stock, Status: req.Status, Description: req.Description}); err != nil {
|
||||||
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -133,14 +135,15 @@ type listProductsRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type productItem struct {
|
type productItem struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
CategoryID int64 `json:"category_id"`
|
CategoryID int64 `json:"category_id"`
|
||||||
ImagesJSON string `json:"images_json"`
|
ImagesJSON string `json:"images_json"`
|
||||||
Price int64 `json:"price"`
|
Price int64 `json:"price"`
|
||||||
Stock int64 `json:"stock"`
|
Stock int64 `json:"stock"`
|
||||||
Sales int64 `json:"sales"`
|
Sales int64 `json:"sales"`
|
||||||
Status int32 `json:"status"`
|
Status int32 `json:"status"`
|
||||||
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
type listProductsResponse struct {
|
type listProductsResponse struct {
|
||||||
Page int `json:"page"`
|
Page int `json:"page"`
|
||||||
@ -181,7 +184,7 @@ func (h *handler) ListProducts() core.HandlerFunc {
|
|||||||
res.Total = total
|
res.Total = total
|
||||||
res.List = make([]productItem, len(items))
|
res.List = make([]productItem, len(items))
|
||||||
for i, it := range items {
|
for i, it := range items {
|
||||||
res.List[i] = productItem{ID: it.ID, Name: it.Name, CategoryID: it.CategoryID, ImagesJSON: it.ImagesJSON, Price: it.Price, Stock: it.Stock, Sales: it.Sales, Status: it.Status}
|
res.List[i] = productItem{ID: it.ID, Name: it.Name, CategoryID: it.CategoryID, ImagesJSON: it.ImagesJSON, Price: it.Price, Stock: it.Stock, Sales: it.Sales, Status: it.Status, Description: it.Description}
|
||||||
}
|
}
|
||||||
ctx.Payload(res)
|
ctx.Payload(res)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,7 +141,7 @@ func (h *handler) CancelOrder() core.HandlerFunc {
|
|||||||
OrderID: order.ID,
|
OrderID: order.ID,
|
||||||
OrderNo: order.OrderNo,
|
OrderNo: order.OrderNo,
|
||||||
Status: order.Status,
|
Status: order.Status,
|
||||||
CancelledAt: order.CancelledAt,
|
CancelledAt: &order.CancelledAt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,6 +55,10 @@ func newActivities(db *gorm.DB, opts ...gen.DOOption) activities {
|
|||||||
_activities.CommitmentStateVersion = field.NewInt32(tableName, "commitment_state_version")
|
_activities.CommitmentStateVersion = field.NewInt32(tableName, "commitment_state_version")
|
||||||
_activities.CommitmentItemsRoot = field.NewBytes(tableName, "commitment_items_root")
|
_activities.CommitmentItemsRoot = field.NewBytes(tableName, "commitment_items_root")
|
||||||
_activities.GameplayIntro = field.NewString(tableName, "gameplay_intro")
|
_activities.GameplayIntro = field.NewString(tableName, "gameplay_intro")
|
||||||
|
_activities.DailySeed = field.NewString(tableName, "daily_seed")
|
||||||
|
_activities.DailySeedDate = field.NewString(tableName, "daily_seed_date")
|
||||||
|
_activities.LastDailySeed = field.NewString(tableName, "last_daily_seed")
|
||||||
|
_activities.LastDailySeedDate = field.NewString(tableName, "last_daily_seed_date")
|
||||||
|
|
||||||
_activities.fillFieldMap()
|
_activities.fillFieldMap()
|
||||||
|
|
||||||
@ -94,6 +98,10 @@ type activities struct {
|
|||||||
CommitmentStateVersion field.Int32
|
CommitmentStateVersion field.Int32
|
||||||
CommitmentItemsRoot field.Bytes
|
CommitmentItemsRoot field.Bytes
|
||||||
GameplayIntro field.String // 玩法介绍
|
GameplayIntro field.String // 玩法介绍
|
||||||
|
DailySeed field.String
|
||||||
|
DailySeedDate field.String // 种子日期(YYYY-MM-DD)
|
||||||
|
LastDailySeed field.String // 昨日种子
|
||||||
|
LastDailySeedDate field.String // 昨日种子日期
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@ -138,6 +146,10 @@ func (a *activities) updateTableName(table string) *activities {
|
|||||||
a.CommitmentStateVersion = field.NewInt32(table, "commitment_state_version")
|
a.CommitmentStateVersion = field.NewInt32(table, "commitment_state_version")
|
||||||
a.CommitmentItemsRoot = field.NewBytes(table, "commitment_items_root")
|
a.CommitmentItemsRoot = field.NewBytes(table, "commitment_items_root")
|
||||||
a.GameplayIntro = field.NewString(table, "gameplay_intro")
|
a.GameplayIntro = field.NewString(table, "gameplay_intro")
|
||||||
|
a.DailySeed = field.NewString(table, "daily_seed")
|
||||||
|
a.DailySeedDate = field.NewString(table, "daily_seed_date")
|
||||||
|
a.LastDailySeed = field.NewString(table, "last_daily_seed")
|
||||||
|
a.LastDailySeedDate = field.NewString(table, "last_daily_seed_date")
|
||||||
|
|
||||||
a.fillFieldMap()
|
a.fillFieldMap()
|
||||||
|
|
||||||
@ -154,7 +166,7 @@ func (a *activities) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *activities) fillFieldMap() {
|
func (a *activities) fillFieldMap() {
|
||||||
a.fieldMap = make(map[string]field.Expr, 28)
|
a.fieldMap = make(map[string]field.Expr, 32)
|
||||||
a.fieldMap["id"] = a.ID
|
a.fieldMap["id"] = a.ID
|
||||||
a.fieldMap["created_at"] = a.CreatedAt
|
a.fieldMap["created_at"] = a.CreatedAt
|
||||||
a.fieldMap["updated_at"] = a.UpdatedAt
|
a.fieldMap["updated_at"] = a.UpdatedAt
|
||||||
@ -183,6 +195,10 @@ func (a *activities) fillFieldMap() {
|
|||||||
a.fieldMap["commitment_state_version"] = a.CommitmentStateVersion
|
a.fieldMap["commitment_state_version"] = a.CommitmentStateVersion
|
||||||
a.fieldMap["commitment_items_root"] = a.CommitmentItemsRoot
|
a.fieldMap["commitment_items_root"] = a.CommitmentItemsRoot
|
||||||
a.fieldMap["gameplay_intro"] = a.GameplayIntro
|
a.fieldMap["gameplay_intro"] = a.GameplayIntro
|
||||||
|
a.fieldMap["daily_seed"] = a.DailySeed
|
||||||
|
a.fieldMap["daily_seed_date"] = a.DailySeedDate
|
||||||
|
a.fieldMap["last_daily_seed"] = a.LastDailySeed
|
||||||
|
a.fieldMap["last_daily_seed_date"] = a.LastDailySeedDate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a activities) clone(db *gorm.DB) activities {
|
func (a activities) clone(db *gorm.DB) activities {
|
||||||
|
|||||||
@ -40,6 +40,7 @@ func newActivityRewardSettings(db *gorm.DB, opts ...gen.DOOption) activityReward
|
|||||||
_activityRewardSettings.Sort = field.NewInt32(tableName, "sort")
|
_activityRewardSettings.Sort = field.NewInt32(tableName, "sort")
|
||||||
_activityRewardSettings.IsBoss = field.NewInt32(tableName, "is_boss")
|
_activityRewardSettings.IsBoss = field.NewInt32(tableName, "is_boss")
|
||||||
_activityRewardSettings.DeletedAt = field.NewField(tableName, "deleted_at")
|
_activityRewardSettings.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
|
_activityRewardSettings.MinScore = field.NewInt64(tableName, "min_score")
|
||||||
|
|
||||||
_activityRewardSettings.fillFieldMap()
|
_activityRewardSettings.fillFieldMap()
|
||||||
|
|
||||||
@ -64,6 +65,7 @@ type activityRewardSettings struct {
|
|||||||
Sort field.Int32 // 排序
|
Sort field.Int32 // 排序
|
||||||
IsBoss field.Int32 // Boss 1 是 0 不是
|
IsBoss field.Int32 // Boss 1 是 0 不是
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
|
MinScore field.Int64 // 最低得分/碰数要求
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@ -93,6 +95,7 @@ func (a *activityRewardSettings) updateTableName(table string) *activityRewardSe
|
|||||||
a.Sort = field.NewInt32(table, "sort")
|
a.Sort = field.NewInt32(table, "sort")
|
||||||
a.IsBoss = field.NewInt32(table, "is_boss")
|
a.IsBoss = field.NewInt32(table, "is_boss")
|
||||||
a.DeletedAt = field.NewField(table, "deleted_at")
|
a.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
|
a.MinScore = field.NewInt64(table, "min_score")
|
||||||
|
|
||||||
a.fillFieldMap()
|
a.fillFieldMap()
|
||||||
|
|
||||||
@ -109,7 +112,7 @@ func (a *activityRewardSettings) GetFieldByName(fieldName string) (field.OrderEx
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *activityRewardSettings) fillFieldMap() {
|
func (a *activityRewardSettings) fillFieldMap() {
|
||||||
a.fieldMap = make(map[string]field.Expr, 13)
|
a.fieldMap = make(map[string]field.Expr, 14)
|
||||||
a.fieldMap["id"] = a.ID
|
a.fieldMap["id"] = a.ID
|
||||||
a.fieldMap["created_at"] = a.CreatedAt
|
a.fieldMap["created_at"] = a.CreatedAt
|
||||||
a.fieldMap["updated_at"] = a.UpdatedAt
|
a.fieldMap["updated_at"] = a.UpdatedAt
|
||||||
@ -123,6 +126,7 @@ func (a *activityRewardSettings) fillFieldMap() {
|
|||||||
a.fieldMap["sort"] = a.Sort
|
a.fieldMap["sort"] = a.Sort
|
||||||
a.fieldMap["is_boss"] = a.IsBoss
|
a.fieldMap["is_boss"] = a.IsBoss
|
||||||
a.fieldMap["deleted_at"] = a.DeletedAt
|
a.fieldMap["deleted_at"] = a.DeletedAt
|
||||||
|
a.fieldMap["min_score"] = a.MinScore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a activityRewardSettings) clone(db *gorm.DB) activityRewardSettings {
|
func (a activityRewardSettings) clone(db *gorm.DB) activityRewardSettings {
|
||||||
|
|||||||
@ -44,6 +44,8 @@ func newOrders(db *gorm.DB, opts ...gen.DOOption) orders {
|
|||||||
_orders.UserAddressID = field.NewInt64(tableName, "user_address_id")
|
_orders.UserAddressID = field.NewInt64(tableName, "user_address_id")
|
||||||
_orders.IsConsumed = field.NewInt32(tableName, "is_consumed")
|
_orders.IsConsumed = field.NewInt32(tableName, "is_consumed")
|
||||||
_orders.PointsLedgerID = field.NewInt64(tableName, "points_ledger_id")
|
_orders.PointsLedgerID = field.NewInt64(tableName, "points_ledger_id")
|
||||||
|
_orders.CouponID = field.NewInt64(tableName, "coupon_id")
|
||||||
|
_orders.ItemCardID = field.NewInt64(tableName, "item_card_id")
|
||||||
_orders.Remark = field.NewString(tableName, "remark")
|
_orders.Remark = field.NewString(tableName, "remark")
|
||||||
|
|
||||||
_orders.fillFieldMap()
|
_orders.fillFieldMap()
|
||||||
@ -73,6 +75,8 @@ type orders struct {
|
|||||||
UserAddressID field.Int64 // 收货地址ID(user_addresses.id)
|
UserAddressID field.Int64 // 收货地址ID(user_addresses.id)
|
||||||
IsConsumed field.Int32 // 是否已履约/消耗(对虚拟资产)
|
IsConsumed field.Int32 // 是否已履约/消耗(对虚拟资产)
|
||||||
PointsLedgerID field.Int64 // 积分扣减流水ID(user_points_ledger.id)
|
PointsLedgerID field.Int64 // 积分扣减流水ID(user_points_ledger.id)
|
||||||
|
CouponID field.Int64 // 使用的优惠券ID
|
||||||
|
ItemCardID field.Int64 // 使用的道具卡ID
|
||||||
Remark field.String // 备注
|
Remark field.String // 备注
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
@ -107,6 +111,8 @@ func (o *orders) updateTableName(table string) *orders {
|
|||||||
o.UserAddressID = field.NewInt64(table, "user_address_id")
|
o.UserAddressID = field.NewInt64(table, "user_address_id")
|
||||||
o.IsConsumed = field.NewInt32(table, "is_consumed")
|
o.IsConsumed = field.NewInt32(table, "is_consumed")
|
||||||
o.PointsLedgerID = field.NewInt64(table, "points_ledger_id")
|
o.PointsLedgerID = field.NewInt64(table, "points_ledger_id")
|
||||||
|
o.CouponID = field.NewInt64(table, "coupon_id")
|
||||||
|
o.ItemCardID = field.NewInt64(table, "item_card_id")
|
||||||
o.Remark = field.NewString(table, "remark")
|
o.Remark = field.NewString(table, "remark")
|
||||||
|
|
||||||
o.fillFieldMap()
|
o.fillFieldMap()
|
||||||
@ -124,7 +130,7 @@ func (o *orders) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *orders) fillFieldMap() {
|
func (o *orders) fillFieldMap() {
|
||||||
o.fieldMap = make(map[string]field.Expr, 18)
|
o.fieldMap = make(map[string]field.Expr, 20)
|
||||||
o.fieldMap["id"] = o.ID
|
o.fieldMap["id"] = o.ID
|
||||||
o.fieldMap["created_at"] = o.CreatedAt
|
o.fieldMap["created_at"] = o.CreatedAt
|
||||||
o.fieldMap["updated_at"] = o.UpdatedAt
|
o.fieldMap["updated_at"] = o.UpdatedAt
|
||||||
@ -142,6 +148,8 @@ func (o *orders) fillFieldMap() {
|
|||||||
o.fieldMap["user_address_id"] = o.UserAddressID
|
o.fieldMap["user_address_id"] = o.UserAddressID
|
||||||
o.fieldMap["is_consumed"] = o.IsConsumed
|
o.fieldMap["is_consumed"] = o.IsConsumed
|
||||||
o.fieldMap["points_ledger_id"] = o.PointsLedgerID
|
o.fieldMap["points_ledger_id"] = o.PointsLedgerID
|
||||||
|
o.fieldMap["coupon_id"] = o.CouponID
|
||||||
|
o.fieldMap["item_card_id"] = o.ItemCardID
|
||||||
o.fieldMap["remark"] = o.Remark
|
o.fieldMap["remark"] = o.Remark
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@ func newProducts(db *gorm.DB, opts ...gen.DOOption) products {
|
|||||||
_products.Sales = field.NewInt64(tableName, "sales")
|
_products.Sales = field.NewInt64(tableName, "sales")
|
||||||
_products.Status = field.NewInt32(tableName, "status")
|
_products.Status = field.NewInt32(tableName, "status")
|
||||||
_products.DeletedAt = field.NewField(tableName, "deleted_at")
|
_products.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
|
_products.Description = field.NewString(tableName, "description")
|
||||||
|
|
||||||
_products.fillFieldMap()
|
_products.fillFieldMap()
|
||||||
|
|
||||||
@ -48,18 +49,19 @@ func newProducts(db *gorm.DB, opts ...gen.DOOption) products {
|
|||||||
type products struct {
|
type products struct {
|
||||||
productsDo
|
productsDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.Int64 // 主键ID
|
ID field.Int64 // 主键ID
|
||||||
CreatedAt field.Time // 创建时间
|
CreatedAt field.Time // 创建时间
|
||||||
UpdatedAt field.Time // 更新时间
|
UpdatedAt field.Time // 更新时间
|
||||||
Name field.String // 商品名称
|
Name field.String // 商品名称
|
||||||
CategoryID field.Int64 // 单一主分类ID(product_categories.id)
|
CategoryID field.Int64 // 单一主分类ID(product_categories.id)
|
||||||
ImagesJSON field.String // 商品图片JSON(数组)
|
ImagesJSON field.String // 商品图片JSON(数组)
|
||||||
Price field.Int64 // 商品售价(分)
|
Price field.Int64 // 商品售价(分)
|
||||||
Stock field.Int64 // 可售库存
|
Stock field.Int64 // 可售库存
|
||||||
Sales field.Int64 // 已售数量
|
Sales field.Int64 // 已售数量
|
||||||
Status field.Int32 // 上下架状态:1上架 2下架
|
Status field.Int32 // 上下架状态:1上架 2下架
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
|
Description field.String // 商品详情
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@ -87,6 +89,7 @@ func (p *products) updateTableName(table string) *products {
|
|||||||
p.Sales = field.NewInt64(table, "sales")
|
p.Sales = field.NewInt64(table, "sales")
|
||||||
p.Status = field.NewInt32(table, "status")
|
p.Status = field.NewInt32(table, "status")
|
||||||
p.DeletedAt = field.NewField(table, "deleted_at")
|
p.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
|
p.Description = field.NewString(table, "description")
|
||||||
|
|
||||||
p.fillFieldMap()
|
p.fillFieldMap()
|
||||||
|
|
||||||
@ -103,7 +106,7 @@ func (p *products) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *products) fillFieldMap() {
|
func (p *products) fillFieldMap() {
|
||||||
p.fieldMap = make(map[string]field.Expr, 11)
|
p.fieldMap = make(map[string]field.Expr, 12)
|
||||||
p.fieldMap["id"] = p.ID
|
p.fieldMap["id"] = p.ID
|
||||||
p.fieldMap["created_at"] = p.CreatedAt
|
p.fieldMap["created_at"] = p.CreatedAt
|
||||||
p.fieldMap["updated_at"] = p.UpdatedAt
|
p.fieldMap["updated_at"] = p.UpdatedAt
|
||||||
@ -115,6 +118,7 @@ func (p *products) fillFieldMap() {
|
|||||||
p.fieldMap["sales"] = p.Sales
|
p.fieldMap["sales"] = p.Sales
|
||||||
p.fieldMap["status"] = p.Status
|
p.fieldMap["status"] = p.Status
|
||||||
p.fieldMap["deleted_at"] = p.DeletedAt
|
p.fieldMap["deleted_at"] = p.DeletedAt
|
||||||
|
p.fieldMap["description"] = p.Description
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p products) clone(db *gorm.DB) products {
|
func (p products) clone(db *gorm.DB) products {
|
||||||
|
|||||||
@ -37,6 +37,7 @@ func newTaskCenterTaskTiers(db *gorm.DB, opts ...gen.DOOption) taskCenterTaskTie
|
|||||||
_taskCenterTaskTiers.Priority = field.NewInt32(tableName, "priority")
|
_taskCenterTaskTiers.Priority = field.NewInt32(tableName, "priority")
|
||||||
_taskCenterTaskTiers.CreatedAt = field.NewTime(tableName, "created_at")
|
_taskCenterTaskTiers.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
_taskCenterTaskTiers.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_taskCenterTaskTiers.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
|
_taskCenterTaskTiers.ExtraParams = field.NewString(tableName, "extra_params")
|
||||||
|
|
||||||
_taskCenterTaskTiers.fillFieldMap()
|
_taskCenterTaskTiers.fillFieldMap()
|
||||||
|
|
||||||
@ -47,17 +48,18 @@ func newTaskCenterTaskTiers(db *gorm.DB, opts ...gen.DOOption) taskCenterTaskTie
|
|||||||
type taskCenterTaskTiers struct {
|
type taskCenterTaskTiers struct {
|
||||||
taskCenterTaskTiersDo
|
taskCenterTaskTiersDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.Int64 // 主键ID
|
ID field.Int64 // 主键ID
|
||||||
TaskID field.Int64 // 关联任务ID(task_center_tasks.id)
|
TaskID field.Int64 // 关联任务ID(task_center_tasks.id)
|
||||||
Metric field.String // 指标:first_order|order_count|invite_count
|
Metric field.String // 指标:first_order|order_count|invite_count
|
||||||
Operator field.String // 比较符:>= 或 ==
|
Operator field.String // 比较符:>= 或 ==
|
||||||
Threshold field.Int64 // 阈值(数量或布尔首单)
|
Threshold field.Int64 // 阈值(数量或布尔首单)
|
||||||
Window field.String // 时间窗口:activity_period|since_registration
|
Window field.String // 时间窗口:activity_period|since_registration
|
||||||
Repeatable field.Int32 // 是否每档一次:0否 1是
|
Repeatable field.Int32 // 是否每档一次:0否 1是
|
||||||
Priority field.Int32 // 匹配优先级(数值越小越先匹配)
|
Priority field.Int32 // 匹配优先级(数值越小越先匹配)
|
||||||
CreatedAt field.Time // 创建时间
|
CreatedAt field.Time // 创建时间
|
||||||
UpdatedAt field.Time // 更新时间
|
UpdatedAt field.Time // 更新时间
|
||||||
|
ExtraParams field.String // 额外参数配置(如消费门槛)
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@ -84,6 +86,7 @@ func (t *taskCenterTaskTiers) updateTableName(table string) *taskCenterTaskTiers
|
|||||||
t.Priority = field.NewInt32(table, "priority")
|
t.Priority = field.NewInt32(table, "priority")
|
||||||
t.CreatedAt = field.NewTime(table, "created_at")
|
t.CreatedAt = field.NewTime(table, "created_at")
|
||||||
t.UpdatedAt = field.NewTime(table, "updated_at")
|
t.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
|
t.ExtraParams = field.NewString(table, "extra_params")
|
||||||
|
|
||||||
t.fillFieldMap()
|
t.fillFieldMap()
|
||||||
|
|
||||||
@ -100,7 +103,7 @@ func (t *taskCenterTaskTiers) GetFieldByName(fieldName string) (field.OrderExpr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *taskCenterTaskTiers) fillFieldMap() {
|
func (t *taskCenterTaskTiers) fillFieldMap() {
|
||||||
t.fieldMap = make(map[string]field.Expr, 10)
|
t.fieldMap = make(map[string]field.Expr, 11)
|
||||||
t.fieldMap["id"] = t.ID
|
t.fieldMap["id"] = t.ID
|
||||||
t.fieldMap["task_id"] = t.TaskID
|
t.fieldMap["task_id"] = t.TaskID
|
||||||
t.fieldMap["metric"] = t.Metric
|
t.fieldMap["metric"] = t.Metric
|
||||||
@ -111,6 +114,7 @@ func (t *taskCenterTaskTiers) fillFieldMap() {
|
|||||||
t.fieldMap["priority"] = t.Priority
|
t.fieldMap["priority"] = t.Priority
|
||||||
t.fieldMap["created_at"] = t.CreatedAt
|
t.fieldMap["created_at"] = t.CreatedAt
|
||||||
t.fieldMap["updated_at"] = t.UpdatedAt
|
t.fieldMap["updated_at"] = t.UpdatedAt
|
||||||
|
t.fieldMap["extra_params"] = t.ExtraParams
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t taskCenterTaskTiers) clone(db *gorm.DB) taskCenterTaskTiers {
|
func (t taskCenterTaskTiers) clone(db *gorm.DB) taskCenterTaskTiers {
|
||||||
|
|||||||
@ -36,6 +36,8 @@ func newUserInvites(db *gorm.DB, opts ...gen.DOOption) userInvites {
|
|||||||
_userInvites.CreatedAt = field.NewTime(tableName, "created_at")
|
_userInvites.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
_userInvites.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_userInvites.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
_userInvites.DeletedAt = field.NewField(tableName, "deleted_at")
|
_userInvites.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
|
_userInvites.IsEffective = field.NewBool(tableName, "is_effective")
|
||||||
|
_userInvites.AccumulatedAmount = field.NewInt64(tableName, "accumulated_amount")
|
||||||
|
|
||||||
_userInvites.fillFieldMap()
|
_userInvites.fillFieldMap()
|
||||||
|
|
||||||
@ -46,16 +48,18 @@ func newUserInvites(db *gorm.DB, opts ...gen.DOOption) userInvites {
|
|||||||
type userInvites struct {
|
type userInvites struct {
|
||||||
userInvitesDo
|
userInvitesDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
ID field.Int64 // 主键ID
|
ID field.Int64 // 主键ID
|
||||||
InviterID field.Int64 // 邀请人用户ID
|
InviterID field.Int64 // 邀请人用户ID
|
||||||
InviteeID field.Int64 // 被邀请用户ID
|
InviteeID field.Int64 // 被邀请用户ID
|
||||||
InviteCode field.String // 邀请时使用的邀请码
|
InviteCode field.String // 邀请时使用的邀请码
|
||||||
RewardPoints field.Int64 // 发放的积分数量(用于审计)
|
RewardPoints field.Int64 // 发放的积分数量(用于审计)
|
||||||
RewardedAt field.Time // 奖励发放时间
|
RewardedAt field.Time // 奖励发放时间
|
||||||
CreatedAt field.Time // 创建时间
|
CreatedAt field.Time // 创建时间
|
||||||
UpdatedAt field.Time // 更新时间
|
UpdatedAt field.Time // 更新时间
|
||||||
DeletedAt field.Field // 删除时间(软删)
|
DeletedAt field.Field // 删除时间(软删)
|
||||||
|
IsEffective field.Bool // 是否为有效邀请
|
||||||
|
AccumulatedAmount field.Int64 // 被邀请人累计消费金额(分)
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@ -81,6 +85,8 @@ func (u *userInvites) updateTableName(table string) *userInvites {
|
|||||||
u.CreatedAt = field.NewTime(table, "created_at")
|
u.CreatedAt = field.NewTime(table, "created_at")
|
||||||
u.UpdatedAt = field.NewTime(table, "updated_at")
|
u.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
u.DeletedAt = field.NewField(table, "deleted_at")
|
u.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
|
u.IsEffective = field.NewBool(table, "is_effective")
|
||||||
|
u.AccumulatedAmount = field.NewInt64(table, "accumulated_amount")
|
||||||
|
|
||||||
u.fillFieldMap()
|
u.fillFieldMap()
|
||||||
|
|
||||||
@ -97,7 +103,7 @@ func (u *userInvites) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInvites) fillFieldMap() {
|
func (u *userInvites) fillFieldMap() {
|
||||||
u.fieldMap = make(map[string]field.Expr, 9)
|
u.fieldMap = make(map[string]field.Expr, 11)
|
||||||
u.fieldMap["id"] = u.ID
|
u.fieldMap["id"] = u.ID
|
||||||
u.fieldMap["inviter_id"] = u.InviterID
|
u.fieldMap["inviter_id"] = u.InviterID
|
||||||
u.fieldMap["invitee_id"] = u.InviteeID
|
u.fieldMap["invitee_id"] = u.InviteeID
|
||||||
@ -107,6 +113,8 @@ func (u *userInvites) fillFieldMap() {
|
|||||||
u.fieldMap["created_at"] = u.CreatedAt
|
u.fieldMap["created_at"] = u.CreatedAt
|
||||||
u.fieldMap["updated_at"] = u.UpdatedAt
|
u.fieldMap["updated_at"] = u.UpdatedAt
|
||||||
u.fieldMap["deleted_at"] = u.DeletedAt
|
u.fieldMap["deleted_at"] = u.DeletedAt
|
||||||
|
u.fieldMap["is_effective"] = u.IsEffective
|
||||||
|
u.fieldMap["accumulated_amount"] = u.AccumulatedAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u userInvites) clone(db *gorm.DB) userInvites {
|
func (u userInvites) clone(db *gorm.DB) userInvites {
|
||||||
|
|||||||
@ -39,13 +39,13 @@ type Activities struct {
|
|||||||
CommitmentAlgo string `gorm:"column:commitment_algo;default:commit-v1" json:"commitment_algo"`
|
CommitmentAlgo string `gorm:"column:commitment_algo;default:commit-v1" json:"commitment_algo"`
|
||||||
CommitmentSeedMaster []byte `gorm:"column:commitment_seed_master" json:"commitment_seed_master"`
|
CommitmentSeedMaster []byte `gorm:"column:commitment_seed_master" json:"commitment_seed_master"`
|
||||||
CommitmentSeedHash []byte `gorm:"column:commitment_seed_hash" json:"commitment_seed_hash"`
|
CommitmentSeedHash []byte `gorm:"column:commitment_seed_hash" json:"commitment_seed_hash"`
|
||||||
DailySeed string `gorm:"column:daily_seed" json:"daily_seed"`
|
|
||||||
DailySeedDate string `gorm:"column:daily_seed_date" json:"daily_seed_date"`
|
|
||||||
LastDailySeed string `gorm:"column:last_daily_seed" json:"last_daily_seed"`
|
|
||||||
LastDailySeedDate string `gorm:"column:last_daily_seed_date" json:"last_daily_seed_date"`
|
|
||||||
CommitmentStateVersion int32 `gorm:"column:commitment_state_version" json:"commitment_state_version"`
|
CommitmentStateVersion int32 `gorm:"column:commitment_state_version" json:"commitment_state_version"`
|
||||||
CommitmentItemsRoot []byte `gorm:"column:commitment_items_root" json:"commitment_items_root"`
|
CommitmentItemsRoot []byte `gorm:"column:commitment_items_root" json:"commitment_items_root"`
|
||||||
GameplayIntro string `gorm:"column:gameplay_intro;comment:玩法介绍" json:"gameplay_intro"` // 玩法介绍
|
GameplayIntro string `gorm:"column:gameplay_intro;comment:玩法介绍" json:"gameplay_intro"` // 玩法介绍
|
||||||
|
DailySeed string `gorm:"column:daily_seed" json:"daily_seed"`
|
||||||
|
DailySeedDate string `gorm:"column:daily_seed_date;comment:种子日期(YYYY-MM-DD)" json:"daily_seed_date"` // 种子日期(YYYY-MM-DD)
|
||||||
|
LastDailySeed string `gorm:"column:last_daily_seed;comment:昨日种子" json:"last_daily_seed"` // 昨日种子
|
||||||
|
LastDailySeedDate string `gorm:"column:last_daily_seed_date;comment:昨日种子日期" json:"last_daily_seed_date"` // 昨日种子日期
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName Activities's table name
|
// TableName Activities's table name
|
||||||
|
|||||||
@ -26,8 +26,8 @@ type ActivityRewardSettings struct {
|
|||||||
Level int32 `gorm:"column:level;not null;comment:奖级(如1=S 2=A 3=B)" json:"level"` // 奖级(如1=S 2=A 3=B)
|
Level int32 `gorm:"column:level;not null;comment:奖级(如1=S 2=A 3=B)" json:"level"` // 奖级(如1=S 2=A 3=B)
|
||||||
Sort int32 `gorm:"column:sort;comment:排序" json:"sort"` // 排序
|
Sort int32 `gorm:"column:sort;comment:排序" json:"sort"` // 排序
|
||||||
IsBoss int32 `gorm:"column:is_boss;comment:Boss 1 是 0 不是" json:"is_boss"` // Boss 1 是 0 不是
|
IsBoss int32 `gorm:"column:is_boss;comment:Boss 1 是 0 不是" json:"is_boss"` // Boss 1 是 0 不是
|
||||||
MinScore int64 `gorm:"column:min_score;not null;default:0;comment:最低得分/碰数要求" json:"min_score"` // 最低得分/碰数要求
|
|
||||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"`
|
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"`
|
||||||
|
MinScore int64 `gorm:"column:min_score;not null;comment:最低得分/碰数要求" json:"min_score"` // 最低得分/碰数要求
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName ActivityRewardSettings's table name
|
// TableName ActivityRewardSettings's table name
|
||||||
|
|||||||
@ -12,26 +12,26 @@ const TableNameOrders = "orders"
|
|||||||
|
|
||||||
// Orders 订单
|
// Orders 订单
|
||||||
type Orders struct {
|
type Orders struct {
|
||||||
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
||||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"created_at"` // 创建时间
|
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"created_at"` // 创建时间
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP(3);comment:更新时间" json:"updated_at"` // 更新时间
|
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP(3);comment:更新时间" json:"updated_at"` // 更新时间
|
||||||
UserID int64 `gorm:"column:user_id;not null;comment:下单用户ID(user_members.id)" json:"user_id"` // 下单用户ID(user_members.id)
|
UserID int64 `gorm:"column:user_id;not null;comment:下单用户ID(user_members.id)" json:"user_id"` // 下单用户ID(user_members.id)
|
||||||
OrderNo string `gorm:"column:order_no;not null;comment:业务订单号(唯一)" json:"order_no"` // 业务订单号(唯一)
|
OrderNo string `gorm:"column:order_no;not null;comment:业务订单号(唯一)" json:"order_no"` // 业务订单号(唯一)
|
||||||
SourceType int32 `gorm:"column:source_type;not null;default:1;comment:来源:1商城直购 2抽奖票据 3其他" json:"source_type"` // 来源:1商城直购 2抽奖票据 3其他
|
SourceType int32 `gorm:"column:source_type;not null;default:1;comment:来源:1商城直购 2抽奖票据 3其他" json:"source_type"` // 来源:1商城直购 2抽奖票据 3其他
|
||||||
TotalAmount int64 `gorm:"column:total_amount;not null;comment:订单总金额(分)" json:"total_amount"` // 订单总金额(分)
|
TotalAmount int64 `gorm:"column:total_amount;not null;comment:订单总金额(分)" json:"total_amount"` // 订单总金额(分)
|
||||||
DiscountAmount int64 `gorm:"column:discount_amount;not null;comment:优惠券抵扣金额(分)" json:"discount_amount"` // 优惠券抵扣金额(分)
|
DiscountAmount int64 `gorm:"column:discount_amount;not null;comment:优惠券抵扣金额(分)" json:"discount_amount"` // 优惠券抵扣金额(分)
|
||||||
PointsAmount int64 `gorm:"column:points_amount;not null;comment:积分抵扣金额(分)" json:"points_amount"` // 积分抵扣金额(分)
|
PointsAmount int64 `gorm:"column:points_amount;not null;comment:积分抵扣金额(分)" json:"points_amount"` // 积分抵扣金额(分)
|
||||||
ActualAmount int64 `gorm:"column:actual_amount;not null;comment:实际支付金额(分)" json:"actual_amount"` // 实际支付金额(分)
|
ActualAmount int64 `gorm:"column:actual_amount;not null;comment:实际支付金额(分)" json:"actual_amount"` // 实际支付金额(分)
|
||||||
Status int32 `gorm:"column:status;not null;default:1;comment:订单状态:1待支付 2已支付 3已取消 4已退款" json:"status"` // 订单状态:1待支付 2已支付 3已取消 4已退款
|
Status int32 `gorm:"column:status;not null;default:1;comment:订单状态:1待支付 2已支付 3已取消 4已退款" json:"status"` // 订单状态:1待支付 2已支付 3已取消 4已退款
|
||||||
PayPreorderID int64 `gorm:"column:pay_preorder_id;comment:关联预支付单ID(payment_preorder.id)" json:"pay_preorder_id"` // 关联预支付单ID(payment_preorder.id)
|
PayPreorderID int64 `gorm:"column:pay_preorder_id;comment:关联预支付单ID(payment_preorder.id)" json:"pay_preorder_id"` // 关联预支付单ID(payment_preorder.id)
|
||||||
PaidAt *time.Time `gorm:"column:paid_at;comment:支付完成时间" json:"paid_at"` // 支付完成时间
|
PaidAt time.Time `gorm:"column:paid_at;comment:支付完成时间" json:"paid_at"` // 支付完成时间
|
||||||
CancelledAt *time.Time `gorm:"column:cancelled_at;comment:取消时间" json:"cancelled_at"` // 取消时间
|
CancelledAt time.Time `gorm:"column:cancelled_at;comment:取消时间" json:"cancelled_at"` // 取消时间
|
||||||
UserAddressID int64 `gorm:"column:user_address_id;comment:收货地址ID(user_addresses.id)" json:"user_address_id"` // 收货地址ID(user_addresses.id)
|
UserAddressID int64 `gorm:"column:user_address_id;comment:收货地址ID(user_addresses.id)" json:"user_address_id"` // 收货地址ID(user_addresses.id)
|
||||||
IsConsumed int32 `gorm:"column:is_consumed;not null;comment:是否已履约/消耗(对虚拟资产)" json:"is_consumed"` // 是否已履约/消耗(对虚拟资产)
|
IsConsumed int32 `gorm:"column:is_consumed;not null;comment:是否已履约/消耗(对虚拟资产)" json:"is_consumed"` // 是否已履约/消耗(对虚拟资产)
|
||||||
PointsLedgerID int64 `gorm:"column:points_ledger_id;comment:积分扣减流水ID(user_points_ledger.id)" json:"points_ledger_id"` // 积分扣减流水ID(user_points_ledger.id)
|
PointsLedgerID int64 `gorm:"column:points_ledger_id;comment:积分扣减流水ID(user_points_ledger.id)" json:"points_ledger_id"` // 积分扣减流水ID(user_points_ledger.id)
|
||||||
CouponID int64 `gorm:"column:coupon_id;comment:使用的优惠券ID" json:"coupon_id"` // 使用的优惠券ID
|
CouponID int64 `gorm:"column:coupon_id;comment:使用的优惠券ID" json:"coupon_id"` // 使用的优惠券ID
|
||||||
ItemCardID int64 `gorm:"column:item_card_id;comment:使用的道具卡ID" json:"item_card_id"` // 使用的道具卡ID
|
ItemCardID int64 `gorm:"column:item_card_id;comment:使用的道具卡ID" json:"item_card_id"` // 使用的道具卡ID
|
||||||
Remark string `gorm:"column:remark;comment:备注" json:"remark"` // 备注
|
Remark string `gorm:"column:remark;comment:备注" json:"remark"` // 备注
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName Orders's table name
|
// TableName Orders's table name
|
||||||
|
|||||||
@ -14,17 +14,18 @@ const TableNameProducts = "products"
|
|||||||
|
|
||||||
// Products 商品
|
// Products 商品
|
||||||
type Products struct {
|
type Products struct {
|
||||||
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
||||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"created_at"` // 创建时间
|
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"created_at"` // 创建时间
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP(3);comment:更新时间" json:"updated_at"` // 更新时间
|
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP(3);comment:更新时间" json:"updated_at"` // 更新时间
|
||||||
Name string `gorm:"column:name;not null;comment:商品名称" json:"name"` // 商品名称
|
Name string `gorm:"column:name;not null;comment:商品名称" json:"name"` // 商品名称
|
||||||
CategoryID int64 `gorm:"column:category_id;comment:单一主分类ID(product_categories.id)" json:"category_id"` // 单一主分类ID(product_categories.id)
|
CategoryID int64 `gorm:"column:category_id;comment:单一主分类ID(product_categories.id)" json:"category_id"` // 单一主分类ID(product_categories.id)
|
||||||
ImagesJSON string `gorm:"column:images_json;comment:商品图片JSON(数组)" json:"images_json"` // 商品图片JSON(数组)
|
ImagesJSON string `gorm:"column:images_json;comment:商品图片JSON(数组)" json:"images_json"` // 商品图片JSON(数组)
|
||||||
Price int64 `gorm:"column:price;not null;comment:商品售价(分)" json:"price"` // 商品售价(分)
|
Price int64 `gorm:"column:price;not null;comment:商品售价(分)" json:"price"` // 商品售价(分)
|
||||||
Stock int64 `gorm:"column:stock;not null;comment:可售库存" json:"stock"` // 可售库存
|
Stock int64 `gorm:"column:stock;not null;comment:可售库存" json:"stock"` // 可售库存
|
||||||
Sales int64 `gorm:"column:sales;not null;comment:已售数量" json:"sales"` // 已售数量
|
Sales int64 `gorm:"column:sales;not null;comment:已售数量" json:"sales"` // 已售数量
|
||||||
Status int32 `gorm:"column:status;not null;default:1;comment:上下架状态:1上架 2下架" json:"status"` // 上下架状态:1上架 2下架
|
Status int32 `gorm:"column:status;not null;default:1;comment:上下架状态:1上架 2下架" json:"status"` // 上下架状态:1上架 2下架
|
||||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"`
|
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"`
|
||||||
|
Description string `gorm:"column:description;comment:商品详情" json:"description"` // 商品详情
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName Products's table name
|
// TableName Products's table name
|
||||||
|
|||||||
@ -12,16 +12,17 @@ const TableNameTaskCenterTaskTiers = "task_center_task_tiers"
|
|||||||
|
|
||||||
// TaskCenterTaskTiers 任务中心-档位配置
|
// TaskCenterTaskTiers 任务中心-档位配置
|
||||||
type TaskCenterTaskTiers struct {
|
type TaskCenterTaskTiers struct {
|
||||||
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
||||||
TaskID int64 `gorm:"column:task_id;not null;comment:关联任务ID(task_center_tasks.id)" json:"task_id"` // 关联任务ID(task_center_tasks.id)
|
TaskID int64 `gorm:"column:task_id;not null;comment:关联任务ID(task_center_tasks.id)" json:"task_id"` // 关联任务ID(task_center_tasks.id)
|
||||||
Metric string `gorm:"column:metric;not null;comment:指标:first_order|order_count|invite_count" json:"metric"` // 指标:first_order|order_count|invite_count
|
Metric string `gorm:"column:metric;not null;comment:指标:first_order|order_count|invite_count" json:"metric"` // 指标:first_order|order_count|invite_count
|
||||||
Operator string `gorm:"column:operator;not null;comment:比较符:>= 或 ==" json:"operator"` // 比较符:>= 或 ==
|
Operator string `gorm:"column:operator;not null;comment:比较符:>= 或 ==" json:"operator"` // 比较符:>= 或 ==
|
||||||
Threshold int64 `gorm:"column:threshold;not null;comment:阈值(数量或布尔首单)" json:"threshold"` // 阈值(数量或布尔首单)
|
Threshold int64 `gorm:"column:threshold;not null;comment:阈值(数量或布尔首单)" json:"threshold"` // 阈值(数量或布尔首单)
|
||||||
Window string `gorm:"column:window;not null;comment:时间窗口:activity_period|since_registration" json:"window"` // 时间窗口:activity_period|since_registration
|
Window string `gorm:"column:window;not null;comment:时间窗口:activity_period|since_registration" json:"window"` // 时间窗口:activity_period|since_registration
|
||||||
Repeatable int32 `gorm:"column:repeatable;not null;default:1;comment:是否每档一次:0否 1是" json:"repeatable"` // 是否每档一次:0否 1是
|
Repeatable int32 `gorm:"column:repeatable;not null;default:1;comment:是否每档一次:0否 1是" json:"repeatable"` // 是否每档一次:0否 1是
|
||||||
Priority int32 `gorm:"column:priority;not null;comment:匹配优先级(数值越小越先匹配)" json:"priority"` // 匹配优先级(数值越小越先匹配)
|
Priority int32 `gorm:"column:priority;not null;comment:匹配优先级(数值越小越先匹配)" json:"priority"` // 匹配优先级(数值越小越先匹配)
|
||||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
|
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
|
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
|
||||||
|
ExtraParams string `gorm:"column:extra_params;comment:额外参数配置(如消费门槛)" json:"extra_params"` // 额外参数配置(如消费门槛)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName TaskCenterTaskTiers's table name
|
// TableName TaskCenterTaskTiers's table name
|
||||||
|
|||||||
@ -14,17 +14,17 @@ const TableNameUserInvites = "user_invites"
|
|||||||
|
|
||||||
// UserInvites 用户邀请关系表
|
// UserInvites 用户邀请关系表
|
||||||
type UserInvites struct {
|
type UserInvites struct {
|
||||||
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
ID int64 `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键ID" json:"id"` // 主键ID
|
||||||
InviterID int64 `gorm:"column:inviter_id;not null;comment:邀请人用户ID" json:"inviter_id"` // 邀请人用户ID
|
InviterID int64 `gorm:"column:inviter_id;not null;comment:邀请人用户ID" json:"inviter_id"` // 邀请人用户ID
|
||||||
InviteeID int64 `gorm:"column:invitee_id;not null;comment:被邀请用户ID" json:"invitee_id"` // 被邀请用户ID
|
InviteeID int64 `gorm:"column:invitee_id;not null;comment:被邀请用户ID" json:"invitee_id"` // 被邀请用户ID
|
||||||
InviteCode string `gorm:"column:invite_code;not null;comment:邀请时使用的邀请码" json:"invite_code"` // 邀请时使用的邀请码
|
InviteCode string `gorm:"column:invite_code;not null;comment:邀请时使用的邀请码" json:"invite_code"` // 邀请时使用的邀请码
|
||||||
RewardPoints int64 `gorm:"column:reward_points;not null;comment:发放的积分数量(用于审计)" json:"reward_points"` // 发放的积分数量(用于审计)
|
RewardPoints int64 `gorm:"column:reward_points;not null;comment:发放的积分数量(用于审计)" json:"reward_points"` // 发放的积分数量(用于审计)
|
||||||
IsEffective int32 `gorm:"column:is_effective;not null;default:0;comment:是否为有效邀请" json:"is_effective"` // 是否为有效邀请
|
|
||||||
AccumulatedAmount int64 `gorm:"column:accumulated_amount;not null;default:0;comment:被邀请人累计消费金额(分)" json:"accumulated_amount"` // 被邀请人累计消费金额(分)
|
|
||||||
RewardedAt time.Time `gorm:"column:rewarded_at;comment:奖励发放时间" json:"rewarded_at"` // 奖励发放时间
|
RewardedAt time.Time `gorm:"column:rewarded_at;comment:奖励发放时间" json:"rewarded_at"` // 奖励发放时间
|
||||||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"created_at"` // 创建时间
|
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP(3);comment:创建时间" json:"created_at"` // 创建时间
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP(3);comment:更新时间" json:"updated_at"` // 更新时间
|
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP(3);comment:更新时间" json:"updated_at"` // 更新时间
|
||||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间(软删)" json:"deleted_at"` // 删除时间(软删)
|
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间(软删)" json:"deleted_at"` // 删除时间(软删)
|
||||||
|
IsEffective bool `gorm:"column:is_effective;not null;comment:是否为有效邀请" json:"is_effective"` // 是否为有效邀请
|
||||||
|
AccumulatedAmount int64 `gorm:"column:accumulated_amount;not null;comment:被邀请人累计消费金额(分)" json:"accumulated_amount"` // 被邀请人累计消费金额(分)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName UserInvites's table name
|
// TableName UserInvites's table name
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
package product
|
package product
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"errors"
|
||||||
"time"
|
"strings"
|
||||||
"errors"
|
"time"
|
||||||
|
|
||||||
"bindbox-game/internal/pkg/logger"
|
"bindbox-game/internal/pkg/logger"
|
||||||
"bindbox-game/internal/repository/mysql"
|
"bindbox-game/internal/repository/mysql"
|
||||||
"bindbox-game/internal/repository/mysql/dao"
|
"bindbox-game/internal/repository/mysql/dao"
|
||||||
"bindbox-game/internal/repository/mysql/model"
|
"bindbox-game/internal/repository/mysql/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
@ -22,22 +22,22 @@ type Service interface {
|
|||||||
CreateProduct(ctx context.Context, in CreateProductInput) (*model.Products, error)
|
CreateProduct(ctx context.Context, in CreateProductInput) (*model.Products, error)
|
||||||
ModifyProduct(ctx context.Context, id int64, in ModifyProductInput) error
|
ModifyProduct(ctx context.Context, id int64, in ModifyProductInput) error
|
||||||
DeleteProduct(ctx context.Context, id int64) error
|
DeleteProduct(ctx context.Context, id int64) error
|
||||||
ListProducts(ctx context.Context, in ListProductsInput) (items []*model.Products, total int64, err error)
|
ListProducts(ctx context.Context, in ListProductsInput) (items []*model.Products, total int64, err error)
|
||||||
BatchUpdate(ctx context.Context, ids []int64, stock *int64, status *int32) (int64, error)
|
BatchUpdate(ctx context.Context, ids []int64, stock *int64, status *int32) (int64, error)
|
||||||
ListForApp(ctx context.Context, in AppListInput) (items []AppListItem, total int64, err error)
|
ListForApp(ctx context.Context, in AppListInput) (items []AppListItem, total int64, err error)
|
||||||
GetDetailForApp(ctx context.Context, id int64) (*AppDetail, error)
|
GetDetailForApp(ctx context.Context, id int64) (*AppDetail, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type service struct {
|
type service struct {
|
||||||
logger logger.CustomLogger
|
logger logger.CustomLogger
|
||||||
readDB *dao.Query
|
readDB *dao.Query
|
||||||
writeDB *dao.Query
|
writeDB *dao.Query
|
||||||
listCache map[string]cachedList
|
listCache map[string]cachedList
|
||||||
detailCache map[int64]cachedDetail
|
detailCache map[int64]cachedDetail
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(l logger.CustomLogger, db mysql.Repo) Service {
|
func New(l logger.CustomLogger, db mysql.Repo) Service {
|
||||||
return &service{logger: l, readDB: dao.Use(db.GetDbR()), writeDB: dao.Use(db.GetDbW()), listCache: make(map[string]cachedList), detailCache: make(map[int64]cachedDetail)}
|
return &service{logger: l, readDB: dao.Use(db.GetDbR()), writeDB: dao.Use(db.GetDbW()), listCache: make(map[string]cachedList), detailCache: make(map[int64]cachedDetail)}
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateCategoryInput struct {
|
type CreateCategoryInput struct {
|
||||||
@ -87,8 +87,8 @@ func (s *service) ModifyCategory(ctx context.Context, id int64, in ModifyCategor
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) DeleteCategory(ctx context.Context, id int64) error {
|
func (s *service) DeleteCategory(ctx context.Context, id int64) error {
|
||||||
_, err := s.writeDB.ProductCategories.WithContext(ctx).Where(s.writeDB.ProductCategories.ID.Eq(id)).Updates(map[string]any{"deleted_at": time.Now()})
|
_, err := s.writeDB.ProductCategories.WithContext(ctx).Where(s.writeDB.ProductCategories.ID.Eq(id)).Updates(map[string]any{"deleted_at": time.Now()})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) ListCategories(ctx context.Context, in ListCategoriesInput) (items []*model.ProductCategories, total int64, err error) {
|
func (s *service) ListCategories(ctx context.Context, in ListCategoriesInput) (items []*model.ProductCategories, total int64, err error) {
|
||||||
@ -114,21 +114,23 @@ func (s *service) ListCategories(ctx context.Context, in ListCategoriesInput) (i
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateProductInput struct {
|
type CreateProductInput struct {
|
||||||
Name string
|
Name string
|
||||||
CategoryID int64
|
CategoryID int64
|
||||||
ImagesJSON string
|
ImagesJSON string
|
||||||
Price int64
|
Price int64
|
||||||
Stock int64
|
Stock int64
|
||||||
Status int32
|
Status int32
|
||||||
|
Description string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModifyProductInput struct {
|
type ModifyProductInput struct {
|
||||||
Name *string
|
Name *string
|
||||||
CategoryID *int64
|
CategoryID *int64
|
||||||
ImagesJSON *string
|
ImagesJSON *string
|
||||||
Price *int64
|
Price *int64
|
||||||
Stock *int64
|
Stock *int64
|
||||||
Status *int32
|
Status *int32
|
||||||
|
Description *string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListProductsInput struct {
|
type ListProductsInput struct {
|
||||||
@ -140,40 +142,40 @@ type ListProductsInput struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppListInput struct {
|
type AppListInput struct {
|
||||||
CategoryID *int64
|
CategoryID *int64
|
||||||
PriceMin *int64
|
PriceMin *int64
|
||||||
PriceMax *int64
|
PriceMax *int64
|
||||||
SalesMin *int64
|
SalesMin *int64
|
||||||
InStock *bool
|
InStock *bool
|
||||||
SortBy string
|
SortBy string
|
||||||
Order string
|
Order string
|
||||||
Page int
|
Page int
|
||||||
PageSize int
|
PageSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppListItem struct {
|
type AppListItem struct {
|
||||||
ID int64
|
ID int64
|
||||||
Name string
|
Name string
|
||||||
MainImage string
|
MainImage string
|
||||||
Price int64
|
Price int64
|
||||||
Sales int64
|
Sales int64
|
||||||
InStock bool
|
InStock bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppDetail struct {
|
type AppDetail struct {
|
||||||
ID int64
|
ID int64
|
||||||
Name string
|
Name string
|
||||||
Album []string
|
Album []string
|
||||||
Price int64
|
Price int64
|
||||||
Sales int64
|
Sales int64
|
||||||
Stock int64
|
Stock int64
|
||||||
Description string
|
Description string
|
||||||
Service []string
|
Service []string
|
||||||
Recommendations []AppListItem
|
Recommendations []AppListItem
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) CreateProduct(ctx context.Context, in CreateProductInput) (*model.Products, error) {
|
func (s *service) CreateProduct(ctx context.Context, in CreateProductInput) (*model.Products, error) {
|
||||||
m := &model.Products{Name: in.Name, CategoryID: in.CategoryID, ImagesJSON: normalizeJSON(in.ImagesJSON), Price: in.Price, Stock: in.Stock, Status: in.Status}
|
m := &model.Products{Name: in.Name, CategoryID: in.CategoryID, ImagesJSON: normalizeJSON(in.ImagesJSON), Price: in.Price, Stock: in.Stock, Status: in.Status, Description: in.Description}
|
||||||
if err := s.writeDB.Products.WithContext(ctx).Create(m); err != nil {
|
if err := s.writeDB.Products.WithContext(ctx).Create(m); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -201,6 +203,9 @@ func (s *service) ModifyProduct(ctx context.Context, id int64, in ModifyProductI
|
|||||||
if in.Status != nil {
|
if in.Status != nil {
|
||||||
set["status"] = *in.Status
|
set["status"] = *in.Status
|
||||||
}
|
}
|
||||||
|
if in.Description != nil {
|
||||||
|
set["description"] = *in.Description
|
||||||
|
}
|
||||||
if len(set) == 0 {
|
if len(set) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -209,8 +214,8 @@ func (s *service) ModifyProduct(ctx context.Context, id int64, in ModifyProductI
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) DeleteProduct(ctx context.Context, id int64) error {
|
func (s *service) DeleteProduct(ctx context.Context, id int64) error {
|
||||||
_, err := s.writeDB.Products.WithContext(ctx).Where(s.writeDB.Products.ID.Eq(id)).Updates(map[string]any{"deleted_at": time.Now()})
|
_, err := s.writeDB.Products.WithContext(ctx).Where(s.writeDB.Products.ID.Eq(id)).Updates(map[string]any{"deleted_at": time.Now()})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) ListProducts(ctx context.Context, in ListProductsInput) (items []*model.Products, total int64, err error) {
|
func (s *service) ListProducts(ctx context.Context, in ListProductsInput) (items []*model.Products, total int64, err error) {
|
||||||
@ -239,120 +244,120 @@ func (s *service) ListProducts(ctx context.Context, in ListProductsInput) (items
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) ListForApp(ctx context.Context, in AppListInput) (items []AppListItem, total int64, err error) {
|
func (s *service) ListForApp(ctx context.Context, in AppListInput) (items []AppListItem, total int64, err error) {
|
||||||
key := s.listKey(in)
|
key := s.listKey(in)
|
||||||
if v, ok := s.listCache[key]; ok && time.Now().Before(v.expireAt) {
|
if v, ok := s.listCache[key]; ok && time.Now().Before(v.expireAt) {
|
||||||
return v.items, v.total, nil
|
return v.items, v.total, nil
|
||||||
}
|
}
|
||||||
if in.Page <= 0 {
|
if in.Page <= 0 {
|
||||||
in.Page = 1
|
in.Page = 1
|
||||||
}
|
}
|
||||||
if in.PageSize <= 0 {
|
if in.PageSize <= 0 {
|
||||||
in.PageSize = 20
|
in.PageSize = 20
|
||||||
}
|
}
|
||||||
q := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.Status.Eq(1))
|
q := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.Status.Eq(1))
|
||||||
if in.CategoryID != nil {
|
if in.CategoryID != nil {
|
||||||
q = q.Where(s.readDB.Products.CategoryID.Eq(*in.CategoryID))
|
q = q.Where(s.readDB.Products.CategoryID.Eq(*in.CategoryID))
|
||||||
}
|
}
|
||||||
if in.PriceMin != nil {
|
if in.PriceMin != nil {
|
||||||
q = q.Where(s.readDB.Products.Price.Gte(*in.PriceMin))
|
q = q.Where(s.readDB.Products.Price.Gte(*in.PriceMin))
|
||||||
}
|
}
|
||||||
if in.PriceMax != nil {
|
if in.PriceMax != nil {
|
||||||
q = q.Where(s.readDB.Products.Price.Lte(*in.PriceMax))
|
q = q.Where(s.readDB.Products.Price.Lte(*in.PriceMax))
|
||||||
}
|
}
|
||||||
if in.SalesMin != nil {
|
if in.SalesMin != nil {
|
||||||
q = q.Where(s.readDB.Products.Sales.Gte(*in.SalesMin))
|
q = q.Where(s.readDB.Products.Sales.Gte(*in.SalesMin))
|
||||||
}
|
}
|
||||||
if in.InStock != nil && *in.InStock {
|
if in.InStock != nil && *in.InStock {
|
||||||
q = q.Where(s.readDB.Products.Stock.Gt(0))
|
q = q.Where(s.readDB.Products.Stock.Gt(0))
|
||||||
}
|
}
|
||||||
total, err = q.Count()
|
total, err = q.Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
orderDesc := true
|
orderDesc := true
|
||||||
if strings.ToLower(in.Order) == "asc" {
|
if strings.ToLower(in.Order) == "asc" {
|
||||||
orderDesc = false
|
orderDesc = false
|
||||||
}
|
}
|
||||||
switch strings.ToLower(in.SortBy) {
|
switch strings.ToLower(in.SortBy) {
|
||||||
case "price":
|
case "price":
|
||||||
if orderDesc {
|
if orderDesc {
|
||||||
q = q.Order(s.readDB.Products.Price.Desc())
|
q = q.Order(s.readDB.Products.Price.Desc())
|
||||||
} else {
|
} else {
|
||||||
q = q.Order(s.readDB.Products.Price.Asc())
|
q = q.Order(s.readDB.Products.Price.Asc())
|
||||||
}
|
}
|
||||||
case "createdat", "created_at":
|
case "createdat", "created_at":
|
||||||
if orderDesc {
|
if orderDesc {
|
||||||
q = q.Order(s.readDB.Products.CreatedAt.Desc())
|
q = q.Order(s.readDB.Products.CreatedAt.Desc())
|
||||||
} else {
|
} else {
|
||||||
q = q.Order(s.readDB.Products.CreatedAt.Asc())
|
q = q.Order(s.readDB.Products.CreatedAt.Asc())
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if orderDesc {
|
if orderDesc {
|
||||||
q = q.Order(s.readDB.Products.Sales.Desc())
|
q = q.Order(s.readDB.Products.Sales.Desc())
|
||||||
} else {
|
} else {
|
||||||
q = q.Order(s.readDB.Products.Sales.Asc())
|
q = q.Order(s.readDB.Products.Sales.Asc())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rows, err := q.Limit(in.PageSize).Offset((in.Page-1)*in.PageSize).Find()
|
rows, err := q.Limit(in.PageSize).Offset((in.Page - 1) * in.PageSize).Find()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
items = make([]AppListItem, len(rows))
|
items = make([]AppListItem, len(rows))
|
||||||
for i, it := range rows {
|
for i, it := range rows {
|
||||||
items[i] = AppListItem{ID: it.ID, Name: it.Name, MainImage: firstImage(it.ImagesJSON), Price: it.Price, Sales: it.Sales, InStock: it.Stock > 0}
|
items[i] = AppListItem{ID: it.ID, Name: it.Name, MainImage: firstImage(it.ImagesJSON), Price: it.Price, Sales: it.Sales, InStock: it.Stock > 0}
|
||||||
}
|
}
|
||||||
s.listCache[key] = cachedList{items: items, total: total, expireAt: time.Now().Add(30 * time.Second)}
|
s.listCache[key] = cachedList{items: items, total: total, expireAt: time.Now().Add(30 * time.Second)}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) GetDetailForApp(ctx context.Context, id int64) (*AppDetail, error) {
|
func (s *service) GetDetailForApp(ctx context.Context, id int64) (*AppDetail, error) {
|
||||||
if v, ok := s.detailCache[id]; ok && time.Now().Before(v.expireAt) {
|
if v, ok := s.detailCache[id]; ok && time.Now().Before(v.expireAt) {
|
||||||
return v.detail, nil
|
return v.detail, nil
|
||||||
}
|
}
|
||||||
p, err := s.readDB.Products.WithContext(ctx).Where(s.readDB.Products.ID.Eq(id)).Take()
|
p, err := s.readDB.Products.WithContext(ctx).Where(s.readDB.Products.ID.Eq(id)).Take()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if p.Status != 1 {
|
if p.Status != 1 {
|
||||||
return nil, errors.New("PRODUCT_OFFSHELF")
|
return nil, errors.New("PRODUCT_OFFSHELF")
|
||||||
}
|
}
|
||||||
if p.Stock <= 0 {
|
if p.Stock <= 0 {
|
||||||
return nil, errors.New("PRODUCT_OUT_OF_STOCK")
|
return nil, errors.New("PRODUCT_OUT_OF_STOCK")
|
||||||
}
|
}
|
||||||
album := splitImages(p.ImagesJSON)
|
album := splitImages(p.ImagesJSON)
|
||||||
d := &AppDetail{ID: p.ID, Name: p.Name, Album: album, Price: p.Price, Sales: p.Sales, Stock: p.Stock, Description: "", Service: []string{}, Recommendations: []AppListItem{}}
|
d := &AppDetail{ID: p.ID, Name: p.Name, Album: album, Price: p.Price, Sales: p.Sales, Stock: p.Stock, Description: p.Description, Service: []string{}, Recommendations: []AppListItem{}}
|
||||||
recQ := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.Status.Eq(1)).Where(s.readDB.Products.ID.Neq(p.ID))
|
recQ := s.readDB.Products.WithContext(ctx).ReadDB().Where(s.readDB.Products.Status.Eq(1)).Where(s.readDB.Products.ID.Neq(p.ID))
|
||||||
if p.CategoryID > 0 {
|
if p.CategoryID > 0 {
|
||||||
recQ = recQ.Where(s.readDB.Products.CategoryID.Eq(p.CategoryID))
|
recQ = recQ.Where(s.readDB.Products.CategoryID.Eq(p.CategoryID))
|
||||||
}
|
}
|
||||||
recs, _ := recQ.Order(s.readDB.Products.Sales.Desc()).Limit(6).Find()
|
recs, _ := recQ.Order(s.readDB.Products.Sales.Desc()).Limit(6).Find()
|
||||||
for _, it := range recs {
|
for _, it := range recs {
|
||||||
d.Recommendations = append(d.Recommendations, AppListItem{ID: it.ID, Name: it.Name, MainImage: firstImage(it.ImagesJSON), Price: it.Price, Sales: it.Sales, InStock: it.Stock > 0})
|
d.Recommendations = append(d.Recommendations, AppListItem{ID: it.ID, Name: it.Name, MainImage: firstImage(it.ImagesJSON), Price: it.Price, Sales: it.Sales, InStock: it.Stock > 0})
|
||||||
}
|
}
|
||||||
s.detailCache[id] = cachedDetail{detail: d, expireAt: time.Now().Add(60 * time.Second)}
|
s.detailCache[id] = cachedDetail{detail: d, expireAt: time.Now().Add(60 * time.Second)}
|
||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) BatchUpdate(ctx context.Context, ids []int64, stock *int64, status *int32) (int64, error) {
|
func (s *service) BatchUpdate(ctx context.Context, ids []int64, stock *int64, status *int32) (int64, error) {
|
||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
set := map[string]any{}
|
set := map[string]any{}
|
||||||
if stock != nil {
|
if stock != nil {
|
||||||
set["stock"] = *stock
|
set["stock"] = *stock
|
||||||
}
|
}
|
||||||
if status != nil {
|
if status != nil {
|
||||||
set["status"] = *status
|
set["status"] = *status
|
||||||
}
|
}
|
||||||
if len(set) == 0 {
|
if len(set) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
updater := s.writeDB.Products.WithContext(ctx).Where(s.writeDB.Products.ID.In(ids...))
|
updater := s.writeDB.Products.WithContext(ctx).Where(s.writeDB.Products.ID.In(ids...))
|
||||||
result, err := updater.Updates(set)
|
result, err := updater.Updates(set)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return result.RowsAffected, nil
|
return result.RowsAffected, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeJSON(s string) string {
|
func normalizeJSON(s string) string {
|
||||||
@ -367,36 +372,37 @@ func normalizeJSON(s string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) listKey(in AppListInput) string {
|
func (s *service) listKey(in AppListInput) string {
|
||||||
b, _ := json.Marshal(in)
|
b, _ := json.Marshal(in)
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitImages(s string) []string {
|
func splitImages(s string) []string {
|
||||||
var arr []string
|
var arr []string
|
||||||
if strings.TrimSpace(s) == "" {
|
if strings.TrimSpace(s) == "" {
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
var v []string
|
var v []string
|
||||||
if json.Unmarshal([]byte(s), &v) != nil {
|
if json.Unmarshal([]byte(s), &v) != nil {
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func firstImage(s string) string {
|
func firstImage(s string) string {
|
||||||
imgs := splitImages(s)
|
imgs := splitImages(s)
|
||||||
if len(imgs) > 0 {
|
if len(imgs) > 0 {
|
||||||
return imgs[0]
|
return imgs[0]
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
type cachedList struct {
|
type cachedList struct {
|
||||||
items []AppListItem
|
items []AppListItem
|
||||||
total int64
|
total int64
|
||||||
expireAt time.Time
|
expireAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type cachedDetail struct {
|
type cachedDetail struct {
|
||||||
detail *AppDetail
|
detail *AppDetail
|
||||||
expireAt time.Time
|
expireAt time.Time
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,8 +91,8 @@ func (s *service) GrantReward(ctx context.Context, userID int64, req GrantReward
|
|||||||
PointsAmount: 0,
|
PointsAmount: 0,
|
||||||
ActualAmount: 0,
|
ActualAmount: 0,
|
||||||
IsConsumed: 0,
|
IsConsumed: 0,
|
||||||
PaidAt: &now, // 设置支付时间为当前时间
|
PaidAt: now, // 设置支付时间为当前时间
|
||||||
CancelledAt: &minValidTime, // 设置取消时间为最小有效时间,避免MySQL错误
|
CancelledAt: minValidTime, // 设置取消时间为最小有效时间,避免MySQL错误
|
||||||
Remark: req.Remark,
|
Remark: req.Remark,
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
|
|||||||
@ -324,3 +324,10 @@
|
|||||||
{"level":"info","time":"2025-12-23 20:10:39","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":3}
|
{"level":"info","time":"2025-12-23 20:10:39","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":3}
|
||||||
{"level":"info","time":"2025-12-23 20:10:39","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":0}
|
{"level":"info","time":"2025-12-23 20:10:39","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":0}
|
||||||
{"level":"info","time":"2025-12-23 20:10:39","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":4}
|
{"level":"info","time":"2025-12-23 20:10:39","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":4}
|
||||||
|
{"level":"info","time":"2025-12-23 23:32:14","caller":"logger/logger.go:309","msg":"Connected to Redis","domain":"mini-chat[fat]","addr":"118.25.13.43:8379"}
|
||||||
|
{"level":"info","time":"2025-12-23 23:32:14","caller":"logger/logger.go:309","msg":"Task center worker started","domain":"mini-chat[fat]"}
|
||||||
|
{"level":"info","time":"2025-12-23 23:32:14","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":4}
|
||||||
|
{"level":"info","time":"2025-12-23 23:32:14","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":1}
|
||||||
|
{"level":"info","time":"2025-12-23 23:32:14","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":2}
|
||||||
|
{"level":"info","time":"2025-12-23 23:32:14","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":3}
|
||||||
|
{"level":"info","time":"2025-12-23 23:32:14","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":0}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user