package backend import ( "bytes" "context" "errors" "fmt" "io" "kpt-tmr-group/model" "kpt-tmr-group/pkg/logger/zaplog" "kpt-tmr-group/pkg/xerr" operationPb "kpt-tmr-group/proto/go/backend/operation" "github.com/xuri/excelize/v2" "go.uber.org/zap" "gorm.io/gorm" ) // CreateFeedFormula 添加数据 func (s *StoreEntry) CreateFeedFormula(ctx context.Context, req *operationPb.AddFeedFormulaRequest) error { forage := model.NewFeedFormula(req) if err := s.DB.Create(forage).Error; err != nil { return xerr.WithStack(err) } return nil } // EditFeedFormula 编辑数据 func (s *StoreEntry) EditFeedFormula(ctx context.Context, req *operationPb.AddFeedFormulaRequest) error { forage := model.FeedFormula{Id: int64(req.Id)} if err := s.DB.Where("is_delete = ?", operationPb.IsShow_OK).First(forage).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } updateData := &model.FeedFormula{ Name: req.Name, Colour: req.Colour, CattleCategoryId: req.CattleCategoryId, CattleCategoryName: req.CattleCategoryName, FormulaTypeId: req.FormulaTypeId, FormulaTypeName: req.FormulaTypeName, DataSourceId: req.DataSourceId, DataSourceName: req.DataSourceName, Remarks: req.Remarks, IsShow: req.IsShow, } if err := s.DB.Model(new(model.Forage)). Omit("is_show", "is_delete", "encode_number", "formula_type_id", "formula_type_name", "data_source", "version", "is_modify"). Where("id = ?", req.Id). Updates(updateData).Error; err != nil { return xerr.WithStack(err) } return nil } // SearchFeedFormulaList 查询数据列表 func (s *StoreEntry) SearchFeedFormulaList(ctx context.Context, req *operationPb.SearchFeedFormulaRequest) (*operationPb.SearchFeedFormulaListResponse, error) { feedFormula := make([]*model.FeedFormula, 0) var count int64 = 0 pref := s.DB.Model(new(model.Forage)).Where("is_delete = ?", operationPb.IsShow_OK) if req.Name != "" { pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%")) } if req.CattleCategoryId > 0 { pref.Where("cattle_category_id = ?", req.CattleCategoryId) } if req.FormulaTypeId > 0 { pref.Where("formula_type_id = ?", req.FormulaTypeId) } if req.IsShow > 0 { pref.Where("is_show = ?", req.IsShow) } if req.DataSource > 0 { pref.Where("data_source = ?", req.DataSource) } if req.Remarks != "" { pref.Where("remarks = ?", req.Remarks) } if err := pref.Order("id desc").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)). Find(&feedFormula).Error; err != nil { return nil, xerr.WithStack(err) } return &operationPb.SearchFeedFormulaListResponse{ Page: req.Pagination.Page, PageSize: req.Pagination.PageSize, Total: int32(count), List: model.FeedFormulaSlice(feedFormula).ToPB(), }, nil } // IsShowFeedFormula 是否启用和是否可修改 func (s *StoreEntry) IsShowFeedFormula(ctx context.Context, req *operationPb.IsShowModifyFeedFormula) error { feedFormula := &model.FeedFormula{Id: int64(req.FeedFormulaId)} if err := s.DB.First(feedFormula).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if req.EditType == 1 { if err := s.DB.Model(new(model.FeedFormula)).Where("id = ?", req.FeedFormulaId).Update("is_show", req.IsShow).Error; err != nil { return xerr.WithStack(err) } } if req.EditType == 2 { if err := s.DB.Model(new(model.FeedFormula)).Where("id = ?", req.FeedFormulaId).Update("is_modify", req.IsShow).Error; err != nil { return xerr.WithStack(err) } } return nil } // DeleteFeedFormula 是否删除 func (s *StoreEntry) DeleteFeedFormula(ctx context.Context, feedFormulaId int64) error { feedFormula := &model.FeedFormula{Id: feedFormulaId} if err := s.DB.First(feedFormula).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(new(model.FeedFormula)).Where("id = ?", feedFormula).Update("is_delete", operationPb.IsShow_NO).Error; err != nil { return xerr.WithStack(err) } return nil } // ExcelImportFeedFormula 导入excel func (s *StoreEntry) ExcelImportFeedFormula(ctx context.Context, req io.Reader) error { xlsx, err := excelize.OpenReader(req) if err != nil { return xerr.WithStack(err) } defer xlsx.Close() rows, err := xlsx.GetRows(xlsx.GetSheetName(xlsx.GetActiveSheetIndex())) if err != nil { return xerr.WithStack(err) } if len(rows) > 10000 { rows = rows[:10000] } feedFormulaList := make([]*model.FeedFormula, 0) for i, row := range rows { if i == 0 { continue } var ( name, encodeNumber, cattleCategoryName, formulaTypeName, dataSourceName, remarks, isShowStr string isShow operationPb.IsShow_Kind ) for k, v := range row { if k == 0 { name = v } if k == 1 { encodeNumber = v } if k == 2 { cattleCategoryName = v } if k == 3 { formulaTypeName = v } if k == 4 { dataSourceName = v } if k == 5 { remarks = v } if k == 6 { isShowStr = v } } if isShowStr == "是" { isShow = operationPb.IsShow_OK } else { isShow = operationPb.IsShow_NO } feedFormulaItem := &model.FeedFormula{ Name: name, EncodeNumber: encodeNumber, CattleCategoryName: cattleCategoryName, FormulaTypeName: formulaTypeName, Remarks: remarks, IsShow: isShow, IsDelete: operationPb.IsShow_OK, DataSourceId: operationPb.DataSource_EXCEL_IMPORT, DataSourceName: dataSourceName, } feedFormulaList = append(feedFormulaList, feedFormulaItem) } if len(feedFormulaList) > 0 { if err = s.DB.Create(feedFormulaList).Error; err != nil { return xerr.WithStack(err) } } return nil } // ExcelExportFeedFormula 流式导出excel func (s *StoreEntry) ExcelExportFeedFormula(ctx context.Context, req *operationPb.SearchFeedFormulaRequest) (*bytes.Buffer, error) { res, err := s.SearchFeedFormulaList(ctx, req) if err != nil { return nil, xerr.WithStack(err) } if len(res.List) <= 0 { return nil, xerr.Custom("数据为空") } file := excelize.NewFile() defer file.Close() streamWriter, err := file.NewStreamWriter("Sheet1") if err != nil { return nil, xerr.WithStack(err) } titles := []interface{}{"配方名称", "配方编码", "畜牧类别", "配方类别", "来源", "备注", "是否启用", "饲料组", "饲料名称", "重量(kg)", "搅拌延迟(min)", "是否锁定牛头数比例", "顺序"} if err = streamWriter.SetRow("A1", titles); err != nil { return nil, xerr.WithStack(err) } for i, item := range res.List { cell, err := excelize.CoordinatesToCellName(1, i+2) if err != nil { zaplog.Error("excelize.CoordinatesToCellName", zap.Any("Err", err)) continue } row := make([]interface{}, 0) row = append(row, item.Name, item.EncodeNumber, item.CattleCategoryName, item.FormulaTypeName, item.DataSourceName, item.Remarks, item.IsShow) if err = streamWriter.SetRow(cell, row); err != nil { return nil, xerr.WithStack(err) } } if err = streamWriter.Flush(); err != nil { return nil, xerr.WithStack(err) } return file.WriteToBuffer() } // ExcelTemplateFeedFormula 导出模板 func (s *StoreEntry) ExcelTemplateFeedFormula(ctx context.Context) (*bytes.Buffer, error) { file := excelize.NewFile() defer file.Close() streamWriter, err := file.NewStreamWriter("Sheet1") if err != nil { return nil, xerr.WithStack(err) } titles := []interface{}{"配方名称", "配方编码", "畜牧类别", "配方类别", "来源", "备注", "是否启用", "饲料组", "饲料名称", "重量(kg)", "搅拌延迟(min)", "是否锁定牛头数比例", "顺序"} if err = streamWriter.SetRow("A1", titles); err != nil { return nil, xerr.WithStack(err) } if err = streamWriter.Flush(); err != nil { return nil, xerr.WithStack(err) } return file.WriteToBuffer() }