package service import ( "database/sql" "errors" "log" "github.com/wmms/wmms/internal/model" "github.com/wmms/wmms/internal/repository" ) var ErrInvalidMaterialCategory = errors.New("请选择有效的小类类型") type MaterialService struct { repo *repository.MaterialRepo logSvc *MaterialLogService } func NewMaterialService() *MaterialService { return &MaterialService{ repo: repository.NewMaterialRepo(), logSvc: NewMaterialLogService(), } } func (s *MaterialService) validateCategory(categoryID *int64, organizationID int64) error { if categoryID == nil || *categoryID <= 0 { return ErrInvalidMaterialCategory } exists, err := s.repo.IsActiveSubcategory(*categoryID, organizationID) if err != nil { return err } if !exists { return ErrInvalidMaterialCategory } return nil } func (s *MaterialService) Create(req *model.CreateMaterialRequest, operator string) (*model.Material, error) { organizationID := req.OrganizationID if organizationID == 0 { organizationID = 1 } if err := s.validateCategory(req.CategoryID, organizationID); err != nil { return nil, err } unit := req.Unit if unit == "" { unit = "pcs" } var materialImage *string if req.MaterialImage != nil { materialImage = req.MaterialImage } m := &model.Material{ OrganizationID: organizationID, MaterialCode: req.MaterialCode, Name: req.Name, MaterialImage: materialImage, Spec: req.Spec, CategoryID: req.CategoryID, BaseUnitID: req.BaseUnitID, Unit: unit, Status: "active", Version: 1, } if req.ManufacturerModel != nil { m.ManufacturerModel = req.ManufacturerModel } err := s.repo.Create(m) if err != nil { return nil, err } // 记录日志 if err := s.logSvc.LogCreate(m, operator); err != nil { log.Printf("Warning: failed to create material log: %v", err) } return m, nil } func (s *MaterialService) Obsolete(id int64, operator string) error { material, _ := s.GetByID(id) if err := s.repo.Obsolete(id); err != nil { return err } if material != nil { updated := *material updated.Status = "obsolete" updated.Version++ if err := s.logSvc.LogUpdate(&updated, material, operator); err != nil { log.Printf("Warning: failed to create material log: %v", err) } } return nil } func (s *MaterialService) Restore(id int64, operator string) error { material, _ := s.GetByID(id) if err := s.repo.Restore(id); err != nil { return err } if material != nil { updated := *material updated.Status = "active" updated.Version++ if err := s.logSvc.LogUpdate(&updated, material, operator); err != nil { log.Printf("Warning: failed to create material log: %v", err) } } return nil } func (s *MaterialService) GetByID(id int64) (*model.Material, error) { m := &model.Material{} err := s.repo.GetByID(id, m) if err != nil { return nil, err } return m, nil } func (s *MaterialService) List(search, category string, limit, offset int) ([]model.Material, int64, error) { return s.repo.List(search, category, limit, offset) } func (s *MaterialService) Update(id int64, req *model.UpdateMaterialRequest, operator string) (*model.Material, error) { // 获取修改前的数据 oldMaterial, err := s.GetByID(id) if err != nil { return nil, err } if err := s.validateCategory(req.CategoryID, oldMaterial.OrganizationID); err != nil { return nil, err } err = s.repo.Update(id, req) if err != nil { return nil, err } // 获取修改后的数据 newMaterial, err := s.GetByID(id) if err != nil { log.Printf("Warning: failed to get new material for logging: %v", err) } // 记录日志 if err := s.logSvc.LogUpdate(newMaterial, oldMaterial, operator); err != nil { log.Printf("Warning: failed to create material log: %v", err) } return newMaterial, nil } func (s *MaterialService) Delete(id int64, operator string) error { // 获取删除前的数据 material, _ := s.GetByID(id) err := s.repo.Delete(id) if err != nil { return err } // 记录日志 if material != nil { if err := s.logSvc.LogDelete(material, operator); err != nil { log.Printf("Warning: failed to create material log: %v", err) } } return nil } func (s *MaterialService) Exists(id int64) (bool, error) { m := &model.Material{} err := s.repo.GetByID(id, m) if err == sql.ErrNoRows { return false, nil } if err != nil { return false, err } return true, nil }