邹方成 2a89a1ab9d
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(admin): 更新前端资源文件及修复相关功能
refactor(service): 修改banner和guild删除逻辑为软删除
fix(service): 修复删除操作使用软删除而非物理删除

build: 添加SQLite测试仓库实现
docs: 新增奖励管理字段拆分和批量抽奖UI改造文档

ci: 更新CI忽略文件
style: 清理无用资源文件
2025-11-19 01:35:55 +08:00

235 lines
6.2 KiB
Go

package product
import (
"context"
"encoding/json"
"strings"
"time"
"bindbox-game/internal/pkg/logger"
"bindbox-game/internal/repository/mysql"
"bindbox-game/internal/repository/mysql/dao"
"bindbox-game/internal/repository/mysql/model"
)
type Service interface {
CreateCategory(ctx context.Context, in CreateCategoryInput) (*model.ProductCategories, error)
ModifyCategory(ctx context.Context, id int64, in ModifyCategoryInput) error
DeleteCategory(ctx context.Context, id int64) error
ListCategories(ctx context.Context, in ListCategoriesInput) (items []*model.ProductCategories, total int64, err error)
CreateProduct(ctx context.Context, in CreateProductInput) (*model.Products, error)
ModifyProduct(ctx context.Context, id int64, in ModifyProductInput) error
DeleteProduct(ctx context.Context, id int64) 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)
}
type service struct {
logger logger.CustomLogger
readDB *dao.Query
writeDB *dao.Query
}
func New(l logger.CustomLogger, db mysql.Repo) Service {
return &service{logger: l, readDB: dao.Use(db.GetDbR()), writeDB: dao.Use(db.GetDbW())}
}
type CreateCategoryInput struct {
Name string
ParentID int64
Status int32
}
type ModifyCategoryInput struct {
Name *string
ParentID *int64
Status *int32
}
type ListCategoriesInput struct {
Name string
Status *int32
Page int
PageSize int
}
func (s *service) CreateCategory(ctx context.Context, in CreateCategoryInput) (*model.ProductCategories, error) {
m := &model.ProductCategories{Name: in.Name, ParentID: in.ParentID, Status: in.Status}
if err := s.writeDB.ProductCategories.WithContext(ctx).Create(m); err != nil {
return nil, err
}
return m, nil
}
func (s *service) ModifyCategory(ctx context.Context, id int64, in ModifyCategoryInput) error {
updater := s.writeDB.ProductCategories.WithContext(ctx).Where(s.writeDB.ProductCategories.ID.Eq(id))
set := map[string]any{}
if in.Name != nil {
set["name"] = *in.Name
}
if in.ParentID != nil {
set["parent_id"] = *in.ParentID
}
if in.Status != nil {
set["status"] = *in.Status
}
if len(set) == 0 {
return nil
}
_, err := updater.Updates(set)
return err
}
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()})
return err
}
func (s *service) ListCategories(ctx context.Context, in ListCategoriesInput) (items []*model.ProductCategories, total int64, err error) {
if in.Page <= 0 {
in.Page = 1
}
if in.PageSize <= 0 {
in.PageSize = 20
}
q := s.readDB.ProductCategories.WithContext(ctx).ReadDB()
if in.Name != "" {
q = q.Where(s.readDB.ProductCategories.Name.Like("%" + in.Name + "%"))
}
if in.Status != nil {
q = q.Where(s.readDB.ProductCategories.Status.Eq(*in.Status))
}
total, err = q.Count()
if err != nil {
return
}
items, err = q.Order(s.readDB.ProductCategories.ID.Desc()).Limit(in.PageSize).Offset((in.Page - 1) * in.PageSize).Find()
return
}
type CreateProductInput struct {
Name string
CategoryID int64
ImagesJSON string
Price int64
Stock int64
Status int32
}
type ModifyProductInput struct {
Name *string
CategoryID *int64
ImagesJSON *string
Price *int64
Stock *int64
Status *int32
}
type ListProductsInput struct {
Name string
CategoryID *int64
Status *int32
Page int
PageSize int
}
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}
if err := s.writeDB.Products.WithContext(ctx).Create(m); err != nil {
return nil, err
}
return m, nil
}
func (s *service) ModifyProduct(ctx context.Context, id int64, in ModifyProductInput) error {
updater := s.writeDB.Products.WithContext(ctx).Where(s.writeDB.Products.ID.Eq(id))
set := map[string]any{}
if in.Name != nil {
set["name"] = *in.Name
}
if in.CategoryID != nil {
set["category_id"] = *in.CategoryID
}
if in.ImagesJSON != nil {
set["images_json"] = normalizeJSON(*in.ImagesJSON)
}
if in.Price != nil {
set["price"] = *in.Price
}
if in.Stock != nil {
set["stock"] = *in.Stock
}
if in.Status != nil {
set["status"] = *in.Status
}
if len(set) == 0 {
return nil
}
_, err := updater.Updates(set)
return err
}
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()})
return err
}
func (s *service) ListProducts(ctx context.Context, in ListProductsInput) (items []*model.Products, total int64, err error) {
if in.Page <= 0 {
in.Page = 1
}
if in.PageSize <= 0 {
in.PageSize = 20
}
q := s.readDB.Products.WithContext(ctx).ReadDB()
if in.Name != "" {
q = q.Where(s.readDB.Products.Name.Like("%" + in.Name + "%"))
}
if in.CategoryID != nil {
q = q.Where(s.readDB.Products.CategoryID.Eq(*in.CategoryID))
}
if in.Status != nil {
q = q.Where(s.readDB.Products.Status.Eq(*in.Status))
}
total, err = q.Count()
if err != nil {
return
}
items, err = q.Order(s.readDB.Products.ID.Desc()).Limit(in.PageSize).Offset((in.Page - 1) * in.PageSize).Find()
return
}
func (s *service) BatchUpdate(ctx context.Context, ids []int64, stock *int64, status *int32) (int64, error) {
if len(ids) == 0 {
return 0, nil
}
set := map[string]any{}
if stock != nil {
set["stock"] = *stock
}
if status != nil {
set["status"] = *status
}
if len(set) == 0 {
return 0, nil
}
updater := s.writeDB.Products.WithContext(ctx).Where(s.writeDB.Products.ID.In(ids...))
result, err := updater.Updates(set)
if err != nil {
return 0, err
}
return result.RowsAffected, nil
}
func normalizeJSON(s string) string {
if strings.TrimSpace(s) == "" {
return "[]"
}
var v any
if json.Unmarshal([]byte(s), &v) != nil {
return "[]"
}
return s
}