package backend import ( "bytes" "context" "errors" "fmt" "io" "kpt-tmr-group/model" "net/http" "strconv" "sync" operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation" "gitee.com/xuyiping_admin/pkg/logger/zaplog" "gitee.com/xuyiping_admin/pkg/tool" "gitee.com/xuyiping_admin/pkg/xerr" "go.uber.org/zap" "github.com/xuri/excelize/v2" "gorm.io/gorm" ) // CreateGroupPasture 创建集团牧场 func (s *StoreEntry) CreateGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error { // 账号同步牧场端 groupPasture := model.NewGroupPasture(req) if err := s.DB.Create(groupPasture).Error; err != nil { return xerr.WithStack(err) } if err := s.PastureAccountDistribution(ctx, groupPasture); err != nil { s.DB.Model(new(model.GroupPasture)).Where("id = ?", groupPasture.Id).Update("is_delete", operationPb.IsShow_NO) return xerr.WithStack(err) } return nil } // PastureAccountDistribution 账号同步牧场端 func (s *StoreEntry) PastureAccountDistribution(ctx context.Context, groupPasture *model.GroupPasture) error { if groupPasture.Domain == "" { return nil } pastureId := groupPasture.Id if groupPasture.PastureId > 0 { pastureId = groupPasture.PastureId } body := &model.AccountDistribution{ Account: groupPasture.Account, UserName: groupPasture.ManagerUser, Password: groupPasture.Password, Phone: groupPasture.ManagerPhone, PastureId: int32(pastureId), PastureName: groupPasture.Name, Address: groupPasture.Address, } res := &model.PastureCommonResponse{} if err := s.PastureHttpClient(ctx, model.PastureAccountDistributionURl, groupPasture.Id, body, res); err != nil { zaplog.Error("AccountDistribution", zap.Any("url", model.PastureAccountDistributionURl), zap.Any("err", err), zap.Any("body", body), zap.Any("res", res)) return xerr.WithStack(err) } if res.Code == http.StatusOK { if err := s.DB.Model(new(model.GroupPasture)).Where("id = ?", groupPasture.Id).Update("is_distribution", operationPb.IsShow_OK).Error; err != nil { zaplog.Error("AccountDistribution-Update", zap.Any("url", model.PastureAccountDistributionURl), zap.Any("err", err), zap.Any("body", body), zap.Any("res", res)) return xerr.Customf("%s", res.Msg) } } return nil } func (s *StoreEntry) FindGroupPastureListByIds(ctx context.Context, pastureIds []int32) ([]*model.GroupPasture, error) { groupPastureList := make([]*model.GroupPasture, 0) if err := s.DB.Model(new(model.GroupPasture)).Where("is_delete = ? ", operationPb.IsShow_OK). Where("id IN ?", pastureIds). Find(&groupPastureList).Error; err != nil { return nil, xerr.WithStack(err) } return groupPastureList, nil } func (s *StoreEntry) GetGroupPastureListById(ctx context.Context, pastureId int64) (*model.GroupPasture, error) { groupPasture := &model.GroupPasture{ Id: pastureId, } if err := s.DB.Model(new(model.GroupPasture)).Where("is_delete = ? ", operationPb.IsShow_OK). First(&groupPasture).Error; err != nil { return nil, xerr.WithStack(err) } return groupPasture, nil } // EditGroupPasture 创建集团牧场 func (s *StoreEntry) EditGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error { groupPasture := &model.GroupPasture{Id: int64(req.Id)} if err := s.DB.First(groupPasture).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在!") } return xerr.WithStack(err) } updateData := &model.GroupPasture{ Name: req.Name, Account: req.Account, ManagerUser: req.ManagerUser, ManagerPhone: req.ManagerPhone, Address: req.Address, Domain: req.Domain, } if err := s.DB.Model(new(model.GroupPasture)).Omit("is_show", "password"). Where("id = ?", req.Id). Updates(updateData).Error; err != nil { return xerr.WithStack(err) } return nil } // SearchGroupPastureList 查询牧场列表 func (s *StoreEntry) SearchGroupPastureList(ctx context.Context, req *operationPb.SearchPastureRequest) (*operationPb.SearchPastureResponse, error) { groupPasture := make([]*model.GroupPasture, 0) var count int64 = 0 pref := s.DB.Model(new(model.GroupPasture)).Where("is_delete = ? ", operationPb.IsShow_OK) if req.Name != "" { pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%")) } if req.ManagerPhone != "" { pref.Where("manager_phone like ?", fmt.Sprintf("%s%s%s", "%", req.ManagerPhone, "%")) } if req.ManagerUser != "" { pref.Where("manager_user like ?", fmt.Sprintf("%s%s%s", "%", req.ManagerUser, "%")) } if req.StartTime > 0 && req.EndTime > 0 && req.EndTime >= req.StartTime { pref.Where("created_at BETWEEN ? AND ? ", req.StartTime, req.EndTime) } if err := pref.Order("id desc").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)). Find(&groupPasture).Error; err != nil { return nil, xerr.WithStack(err) } return &operationPb.SearchPastureResponse{ Code: http.StatusOK, Msg: "ok", Data: &operationPb.SearchPastureData{ Page: req.Pagination.Page, Total: int32(count), PageSize: req.Pagination.PageSize, List: model.GroupPastureSlice(groupPasture).ToPB(), }, }, nil } // GetGroupPastureById 根据id获取牧场端数据 func (s *StoreEntry) GetGroupPastureById(ctx context.Context, id int64) (*model.GroupPasture, error) { groupPasture := &model.GroupPasture{Id: id} if err := s.DB.Model(new(model.GroupPasture)). Where("is_delete = ?", operationPb.IsShow_OK). Where("is_show = ?", operationPb.IsShow_OK). First(groupPasture).Error; err != nil { return nil, xerr.WithStack(err) } return groupPasture, nil } // DataSyncGroupPastureList 用户数据下发的牧场 func (s *StoreEntry) DataSyncGroupPastureList(ctx context.Context) ([]*model.GroupPasture, error) { groupPastureList := make([]*model.GroupPasture, 0) if err := s.DB.Model(new(model.GroupPasture)).Where("is_delete = ? ", operationPb.IsShow_OK). Where("is_show = ?", operationPb.IsShow_OK).Where("domain != ''"). Where("is_distribution = ?", operationPb.IsShow_OK). Find(&groupPastureList).Error; err != nil { return nil, xerr.WithStack(err) } zaplog.Info("GroupPastureList", zap.Any("data", groupPastureList)) return groupPastureList, nil } func (s *StoreEntry) DeleteGroupPasture(ctx context.Context, pastureId int64) error { groupPasture := &model.GroupPasture{ Id: pastureId, } if err := s.DB.First(groupPasture).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(groupPasture).Update("is_delete", operationPb.IsShow_NO).Error; err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) ResetPasswordGroupPasture(ctx context.Context, pastureId int64) error { groupPasture := &model.GroupPasture{ Id: pastureId, } if err := s.DB.Where("is_delete = ?", operationPb.IsShow_OK).First(groupPasture).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(groupPasture).Update("password", tool.Md5String(model.InitManagerPassword)).Error; err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) IsShowGroupPasture(ctx context.Context, req *operationPb.IsShowGroupPasture) error { groupPasture := &model.GroupPasture{ Id: int64(req.PastureId), } if err := s.DB.First(groupPasture).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(groupPasture).Where("is_delete = ?", operationPb.IsShow_OK).Update("is_show", req.IsShow).Error; err != nil { return xerr.WithStack(err) } return nil } // AddCattleCategory 添加畜牧分类 func (s *StoreEntry) AddCattleCategory(ctx context.Context, req *operationPb.AddCattleCategoryRequest) error { cattleCategory := model.NewCattleCategory(req) if err := s.DB.Create(cattleCategory).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryRequest{ ParentId: int32(req.ParentId), ParentName: req.ParentName, Name: req.Name, Number: req.Number, IsShow: int32(req.IsShow), GroupId: int32(cattleCategory.Id), } if err = s.CategoryDistribution(ctx, model.CattleCategoryDistributionURl, body); err != nil { zaplog.Error("AddCattleCategory", zap.Any("CategoryDistribution", err)) } } return nil } // EditCattleCategory 编辑畜牧分类 func (s *StoreEntry) EditCattleCategory(ctx context.Context, req *operationPb.AddCattleCategoryRequest) error { cattleCategory := &model.CattleCategory{Id: int64(req.Id)} if err := s.DB.First(cattleCategory).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } updateData := &model.CattleCategory{ ParentName: req.ParentName, Name: req.Name, Number: req.Number, ParentId: req.ParentId, } if err := s.DB.Model(new(model.CattleCategory)).Omit("is_show", "is_delete"). Where("id = ?", req.Id). Updates(updateData).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryRequest{ ParentId: int32(req.ParentId), ParentName: req.ParentName, Name: req.Name, Number: req.Number, IsShow: int32(req.IsShow), GroupId: int32(req.Id), } if err = s.CategoryDistribution(ctx, model.CattleCategoryDistributionURl, body); err != nil { zaplog.Error("EditCattleCategory", zap.Any("CategoryDistribution", err)) } } return nil } // IsShowCattleCategory 是否启用 func (s *StoreEntry) IsShowCattleCategory(ctx context.Context, req *operationPb.IsShowCattleCategory) error { cattleCategory := &model.CattleCategory{Id: int64(req.CattleCategoryId)} if err := s.DB.First(cattleCategory).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(new(model.CattleCategory)).Where("id = ?", req.CattleCategoryId).Update("is_show", req.IsShow).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryRequest{ ParentId: int32(cattleCategory.ParentId), ParentName: cattleCategory.ParentName, Name: cattleCategory.Name, Number: cattleCategory.Number, IsShow: int32(req.IsShow), GroupId: int32(cattleCategory.Id), } if err = s.CategoryDistribution(ctx, model.CattleCategoryDistributionURl, body); err != nil { zaplog.Error("IsShowCattleCategory", zap.Any("CategoryDistribution", err), zap.Any("body", body)) } } return nil } // DeleteCattleCategory 是否删除 func (s *StoreEntry) DeleteCattleCategory(ctx context.Context, cattleCategoryId int64) error { cattleCategory := &model.CattleCategory{Id: cattleCategoryId} if err := s.DB.First(cattleCategory).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(new(model.CattleCategory)).Where("id = ?", cattleCategoryId).Update("is_delete", operationPb.IsShow_NO).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryDeleteRequest{ GroupId: int32(cattleCategory.Id), IsDelete: int32(operationPb.IsShow_OK), } if err = s.CategoryDelete(ctx, model.CattleCategoryDeleteURl, body); err != nil { zaplog.Error("DeleteCattleCategory", zap.Any("CategoryDelete", err), zap.Any("body", body)) } } return nil } // SearchCattleCategoryList 牧畜分类类别列表 func (s *StoreEntry) SearchCattleCategoryList(ctx context.Context, req *operationPb.SearchCattleCategoryRequest) (*operationPb.SearchCattleCategoryResponse, error) { cattleCategory := make([]*model.CattleCategory, 0) var count int64 = 0 pref := s.DB.Model(new(model.CattleCategory)).Where("is_delete = ?", operationPb.IsShow_OK) if req.Name != "" { pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%")) } if req.ParentId > 0 { pref.Where("parent_id = ?", req.ParentId) } if req.IsShow > 0 { pref.Where("is_show = ?", req.IsShow) } if err := pref.Order("id desc").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)). Find(&cattleCategory).Debug().Error; err != nil { return nil, xerr.WithStack(err) } return &operationPb.SearchCattleCategoryResponse{ Code: http.StatusOK, Msg: "ok", Data: &operationPb.SearchCattleCategoryData{ Page: req.Pagination.Page, PageSize: req.Pagination.PageSize, Total: int32(count), List: model.CattleCategorySlice(cattleCategory).ToPB(), }, }, nil } // AddForageCategory 添加饲料分类 func (s *StoreEntry) AddForageCategory(ctx context.Context, req *operationPb.AddForageCategoryRequest) error { forageCategory := model.NewForageCategory(req) if err := s.DB.Create(forageCategory).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryRequest{ ParentId: int32(req.ParentId), ParentName: req.ParentName, Name: req.Name, Number: req.Number, IsShow: int32(req.IsShow), GroupId: int32(forageCategory.Id), } if err = s.CategoryDistribution(ctx, model.ForageCategoryDistributionURl, body); err != nil { zaplog.Error("AddForageCategory", zap.Any("CategoryDistribution", err), zap.Any("body", body)) } } return nil } // EditForageCategory 编辑饲料分类 func (s *StoreEntry) EditForageCategory(ctx context.Context, req *operationPb.AddForageCategoryRequest) error { forageCategory := &model.ForageCategory{Id: int64(req.Id)} if err := s.DB.First(forageCategory).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } updateData := &model.ForageCategory{ ParentName: req.ParentName, Name: req.Name, Number: req.Number, ParentId: req.ParentId, } if err := s.DB.Model(new(model.ForageCategory)).Omit("is_show", "is_delete"). Where("id = ?", req.Id). Updates(updateData).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryRequest{ ParentId: int32(req.ParentId), ParentName: req.ParentName, Name: req.Name, Number: req.Number, IsShow: int32(req.IsShow), GroupId: int32(req.Id), } if err = s.CategoryDistribution(ctx, model.ForageCategoryDistributionURl, body); err != nil { zaplog.Error("EditForageCategory", zap.Any("CategoryDistribution", err), zap.Any("body", body)) } } return nil } // IsShowForageCategory 是否启用 func (s *StoreEntry) IsShowForageCategory(ctx context.Context, req *operationPb.IsShowForageCategory) error { forageCategory := &model.ForageCategory{Id: int64(req.ForageCategoryId)} if err := s.DB.First(forageCategory).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(new(model.ForageCategory)).Where("id = ?", req.ForageCategoryId).Update("is_show", req.IsShow).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryRequest{ ParentId: int32(forageCategory.ParentId), ParentName: forageCategory.ParentName, Name: forageCategory.Name, Number: forageCategory.Number, IsShow: int32(req.IsShow), GroupId: int32(forageCategory.Id), } if err = s.CategoryDistribution(ctx, model.ForageCategoryDistributionURl, body); err != nil { zaplog.Error("IsShowForageCategory", zap.Any("CategoryDistribution", err), zap.Any("body", body)) } } return nil } // DeleteForageCategory 是否删除 func (s *StoreEntry) DeleteForageCategory(ctx context.Context, forageCategoryId int64) error { forageCategory := &model.ForageCategory{Id: forageCategoryId} if err := s.DB.First(forageCategory).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(new(model.ForageCategory)).Where("id = ?", forageCategoryId).Update("is_delete", operationPb.IsShow_NO).Error; err != nil { return xerr.WithStack(err) } else { body := &model.CategoryDeleteRequest{ GroupId: int32(forageCategory.Id), IsDelete: int32(operationPb.IsShow_OK), } if err = s.CategoryDelete(ctx, model.ForageCategoryDeleteURl, body); err != nil { zaplog.Error("DeleteForageCategory", zap.Any("CategoryDelete", err), zap.Any("body", body)) } } return nil } // SearchForageCategoryList 饲料分类类别列表 func (s *StoreEntry) SearchForageCategoryList(ctx context.Context, req *operationPb.SearchForageCategoryRequest) (*operationPb.SearchForageCategoryResponse, error) { forageCategory := make([]*model.ForageCategory, 0) var count int64 = 0 pref := s.DB.Model(new(model.ForageCategory)).Where("is_delete = ?", operationPb.IsShow_OK) if req.Name != "" { pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%")) } if req.ParentId > 0 { pref.Where("parent_id = ?", req.ParentId) } if req.Number != "" { pref.Where("number like ?", fmt.Sprintf("%s%s%s", "%", req.Number, "%")) } if req.IsShow > 0 { pref.Where("is_show = ?", req.IsShow) } if err := pref.Order("id desc").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)). Find(&forageCategory).Debug().Error; err != nil { return nil, xerr.WithStack(err) } return &operationPb.SearchForageCategoryResponse{ Code: http.StatusOK, Msg: "ok", Data: &operationPb.SearchForageCategoryData{ Page: req.Pagination.Page, PageSize: req.Pagination.PageSize, Total: int32(count), List: model.ForageCategorySlice(forageCategory).ToPB(), }, }, nil } // CategoryDistribution 饲料分类和畜牧分类下发 func (s *StoreEntry) CategoryDistribution(ctx context.Context, url string, req *model.CategoryRequest) error { groupList, err := s.DataSyncGroupPastureList(ctx) if err != nil { return xerr.WithStack(err) } wg := sync.WaitGroup{} wg.Add(len(groupList)) for _, v := range groupList { go func(data *model.GroupPasture) { defer wg.Done() res := &model.PastureCommonResponse{} req.PastureId = int32(data.PastureId) if err = s.PastureHttpClient(ctx, url, data.Id, req, res); err != nil { zaplog.Error("CategoryDistribution", zap.Any("url", url), zap.Any("err", err), zap.Any("body", req), zap.Any("res", res), ) } if res.Code != http.StatusOK { zaplog.Error("CategoryDistribution-http", zap.Any("url", url), zap.Any("body", req), zap.Any("res", res), ) } }(v) } wg.Wait() return nil } // CategoryDelete 饲料分类和畜牧分类删除 func (s *StoreEntry) CategoryDelete(ctx context.Context, url string, req *model.CategoryDeleteRequest) error { groupList, err := s.DataSyncGroupPastureList(ctx) if err != nil { return xerr.WithStack(err) } wg := sync.WaitGroup{} wg.Add(len(groupList)) for _, v := range groupList { go func(data *model.GroupPasture) { defer wg.Done() res := &model.PastureCommonResponse{} req.PastureId = int32(data.Id) if err = s.PastureHttpClient(ctx, url, int64(data.Id), req, res); err != nil { zaplog.Error("CategoryDelete", zap.Any("url", url), zap.Any("err", err), zap.Any("body", req), zap.Any("res", res), ) } if res.Code != http.StatusOK { zaplog.Error("CategoryDelete-http", zap.Any("url", url), zap.Any("body", req), zap.Any("res", res), ) } }(v) } wg.Wait() return nil } // CreateForage 创建饲料 func (s *StoreEntry) CreateForage(ctx context.Context, req *operationPb.AddForageRequest) error { forage := model.NewForage(req) if err := s.DB.Create(forage).Error; err != nil { return xerr.WithStack(err) } return nil } // EditForage 编辑饲料 func (s *StoreEntry) EditForage(ctx context.Context, req *operationPb.AddForageRequest) error { forage := model.Forage{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.Forage{ Name: req.Name, CategoryId: int64(req.CategoryId), CategoryName: req.CategoryName, MaterialTypeKey: req.MaterialTypeKey, MaterialTypeName: req.MaterialTypeName, UniqueEncode: req.UniqueEncode, ForageSourceId: req.ForageSourceId, PlanTypeId: req.PlanTypeId, SmallMaterialScale: req.SmallMaterialScale, AllowError: int64(req.AllowError), PackageWeight: int64(req.PackageWeight), Price: int64(req.Price), JumpWeight: int64(req.JumpWeight), JumpDelay: req.JumpDelay, ConfirmStart: req.ConfirmStart, RelayLocations: int64(req.RelayLocations), Jmp: req.Jmp, Backup1: req.Backup1, Backup2: req.Backup2, Backup3: req.Backup3, } if err := s.DB.Model(new(model.Forage)).Omit("is_show", "is_delete").Where("id = ?", req.Id). Updates(updateData).Error; err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) SearchForageList(ctx context.Context, req *operationPb.SearchForageListRequest) (*operationPb.SearchForageListResponse, error) { forage := make([]*model.Forage, 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.CategoryId > 0 { pref.Where("category_id = ?", req.CategoryId) } if req.ForageSourceId > 0 { pref.Where("forage_source_id = ?", req.ForageSourceId) } if req.IsShow > 0 { pref.Where("is_show = ?", req.IsShow) } if req.AllowError > 0 { pref.Where("allow_error = ?", req.AllowError) } if req.JumpWeight > 0 { pref.Where("jump_weight = ?", req.JumpWeight) } if req.JumpDelay > 0 { pref.Where("jump_delay = ?", req.JumpDelay) } if err := pref.Order("id DESC").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)). Find(&forage).Error; err != nil { return nil, xerr.WithStack(err) } return &operationPb.SearchForageListResponse{ Code: http.StatusOK, Msg: "ok", Data: &operationPb.SearchForageList{ Page: req.Pagination.Page, PageSize: req.Pagination.PageSize, Total: int32(count), List: model.ForageSlice(forage).ToPB(), }, }, nil } func (s *StoreEntry) ForageListSort(ctx context.Context, req *operationPb.ForageListSortRequest) error { for _, v := range req.List { if err := s.DB.Model(new(model.Forage)).Select("sort").Where("id = ?", v.Id).Updates(map[string]interface{}{ "sort": v.Sort, }).Error; err != nil { zaplog.Error("ForageListSort", zap.Any("err", err), zap.Any("id", v.Id), zap.Any("sort", v.Sort)) } } return nil } func (s *StoreEntry) ForageEnumList(ctx context.Context) *operationPb.ForageEnumListResponse { res := &operationPb.ForageEnumListResponse{ Code: http.StatusOK, Msg: "ok", Data: &operationPb.ForageEnumList{ JumpDelaType: make([]*operationPb.JumpDelaTypeEnum, 0), ForageSource: make([]*operationPb.ForageSourceEnum, 0), ForagePlanType: make([]*operationPb.ForagePlanTypeEnum, 0), CattleParentCategory: make([]*operationPb.CattleParentCategoryEnum, 0), ForageParentCategory: make([]*operationPb.ForageParentCategoryEnum, 0), IsShow: make([]*operationPb.IsShowEnum, 0), FormulaType: make([]*operationPb.FormulaTypeEnum, 0), FormulaList: make([]*operationPb.FormulaOptionEnum, 0), ConfirmStart: make([]*operationPb.IsShowEnum, 0), FormulationEvaluation: make([]*operationPb.FormulaOptionEnum, 0), UseMaterialsType: make([]*operationPb.FormulaOptionEnum, 0), UseMaterialsList: make([]*operationPb.FormulaOptionEnum, 0), PriceMaterialsType: make([]*operationPb.FormulaOptionEnum, 0), }, } // 跳转延迟 res.Data.JumpDelaType = append(res.Data.JumpDelaType, &operationPb.JumpDelaTypeEnum{ Value: operationPb.JumpDelaType_INVALID, Label: "禁用", }, &operationPb.JumpDelaTypeEnum{ Value: operationPb.JumpDelaType_THREE, Label: "3秒", }, &operationPb.JumpDelaTypeEnum{ Value: operationPb.JumpDelaType_SIX, Label: "6秒", }) // 饲料来源 res.Data.ForageSource = append(res.Data.ForageSource, &operationPb.ForageSourceEnum{ Value: operationPb.ForageSource_SYSTEM_BUILT_IN, Label: "系统内置", }, &operationPb.ForageSourceEnum{ Value: operationPb.ForageSource_USER_DEFINED, Label: "用户自定义", }) // 计划类型 res.Data.ForagePlanType = append(res.Data.ForagePlanType, &operationPb.ForagePlanTypeEnum{ Value: operationPb.ForagePlanType_INVALID, Label: "无", }, &operationPb.ForagePlanTypeEnum{ Value: operationPb.ForagePlanType_FORKLIFT, Label: "铲车", }, &operationPb.ForagePlanTypeEnum{ Value: operationPb.ForagePlanType_CONCENTRATE, Label: "精料", }) // 畜牧类别 res.Data.CattleParentCategory = append(res.Data.CattleParentCategory, &operationPb.CattleParentCategoryEnum{ Value: operationPb.CattleCategoryParent_INVALID, Label: "所有类别", }, &operationPb.CattleParentCategoryEnum{ Value: operationPb.CattleCategoryParent_LACTATION_CAW, Label: "泌乳牛", }, &operationPb.CattleParentCategoryEnum{ Value: operationPb.CattleCategoryParent_FATTEN_CAW, Label: "育肥牛", }, &operationPb.CattleParentCategoryEnum{ Value: operationPb.CattleCategoryParent_RESERVE_CAW, Label: "后备牛", }, &operationPb.CattleParentCategoryEnum{ Value: operationPb.CattleCategoryParent_DRY_CAW, Label: "干奶牛", }, &operationPb.CattleParentCategoryEnum{ Value: operationPb.CattleCategoryParent_PERINATAL_CAW, Label: "围产牛", }, &operationPb.CattleParentCategoryEnum{ Value: operationPb.CattleCategoryParent_OTHER_CAW, Label: "其他", }) // 饲料类别 res.Data.ForageParentCategory = append(res.Data.ForageParentCategory, &operationPb.ForageParentCategoryEnum{ Value: operationPb.ForageCategoryParent_ROUGHAGE, Label: "粗料", }, &operationPb.ForageParentCategoryEnum{ Value: operationPb.ForageCategoryParent_CONCENTRATE, Label: "精料", }, &operationPb.ForageParentCategoryEnum{ Value: operationPb.ForageCategoryParent_HALF_ROUGHAGE_HALF_CONCENTRATE, Label: "粗料精料参半", }, &operationPb.ForageParentCategoryEnum{ Value: operationPb.ForageCategoryParent_OTHER, Label: "其他", }) res.Data.IsShow = append(res.Data.IsShow, &operationPb.IsShowEnum{ Value: operationPb.IsShow_OK, Label: "是", }, &operationPb.IsShowEnum{ Value: operationPb.IsShow_NO, Label: "否", }) res.Data.FormulationEvaluation = append(res.Data.FormulationEvaluation, &operationPb.FormulaOptionEnum{ Value: 0, Label: "按配方查询", }, &operationPb.FormulaOptionEnum{ Value: 1, Label: "按栏舍查询", }) res.Data.FormulaType = append(res.Data.FormulaType, &operationPb.FormulaTypeEnum{ Value: operationPb.FormulaType_FEED_FORMULA, Label: "饲喂配方", }, &operationPb.FormulaTypeEnum{ Value: operationPb.FormulaType_PREMIXED_FORMULA, Label: "预混配方", }, &operationPb.FormulaTypeEnum{ Value: operationPb.FormulaType_SUPPLEMENTARY_FORMULA, Label: "补料配方", }) res.Data.ConfirmStart = append(res.Data.ConfirmStart, &operationPb.IsShowEnum{ Value: operationPb.IsShow_OK, Label: "启用", }, &operationPb.IsShowEnum{ Value: operationPb.IsShow_NO, Label: "禁用", }) res.Data.UseMaterialsList = append(res.Data.UseMaterialsList, &operationPb.FormulaOptionEnum{ Value: 1, Label: "理论", }, &operationPb.FormulaOptionEnum{ Value: 2, Label: "实际", }) res.Data.PriceMaterialsType = append(res.Data.PriceMaterialsType, &operationPb.FormulaOptionEnum{ Value: 1, Label: "畜牧类别", }, &operationPb.FormulaOptionEnum{ Value: 2, Label: "栏舍名称", }, &operationPb.FormulaOptionEnum{ Value: 3, Label: "日期", }, &operationPb.FormulaOptionEnum{ Value: 4, Label: "TMR设备号", }) res.Data.UseMaterialsType = append(res.Data.PriceMaterialsType, &operationPb.FormulaOptionEnum{ Value: 5, Label: "TMR班次", }, &operationPb.FormulaOptionEnum{ Value: 6, Label: "车次", }) res.Data.JumpType = append(res.Data.JumpType, &operationPb.FormulaOptionEnum{ Value: 0, Label: "手动跳转", }, &operationPb.FormulaOptionEnum{ Value: 1, Label: "自动跳转", }) res.Data.StatisticsType = append(res.Data.StatisticsType, &operationPb.FormulaOptionEnum{ Value: 7, Label: "无分类", }, &operationPb.FormulaOptionEnum{ Value: 0, Label: "驾驶员", }, &operationPb.FormulaOptionEnum{ Value: 1, Label: "配方名称", }, &operationPb.FormulaOptionEnum{ Value: 2, Label: "栏舍名称", }, &operationPb.FormulaOptionEnum{ Value: 3, Label: "牧畜类别", }, &operationPb.FormulaOptionEnum{ Value: 4, Label: "车次", }, &operationPb.FormulaOptionEnum{ Value: 5, Label: "TMR名称", }, &operationPb.FormulaOptionEnum{ Value: 6, Label: "饲料", }) res.Data.FormulaList = append(res.Data.FormulaList, &operationPb.FormulaOptionEnum{ Value: 0, Label: "所有配方", }) formulaList := make([]*model.FeedFormula, 0) if err := s.DB.Where("is_delete = ?", operationPb.IsShow_OK).Find(&formulaList).Error; err != nil { zaplog.Error("OptionFormula", zap.Any("Err", err)) return res } for _, v := range formulaList { res.Data.FormulaList = append(res.Data.FormulaList, &operationPb.FormulaOptionEnum{ Value: int32(v.Id), Label: v.Name, }) } return res } func (s *StoreEntry) DeleteForageList(ctx context.Context, ids []int64) error { if len(ids) == 0 { return xerr.Custom("参数错误") } if err := s.DB.Model(new(model.Forage)).Where("id IN ?", ids).Update("is_delete", operationPb.IsShow_NO).Error; err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) IsShowForage(ctx context.Context, req *operationPb.IsShowForage) error { forage := &model.Forage{Id: int64(req.ForageId)} if err := s.DB.First(forage).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return xerr.Custom("该数据不存在") } return xerr.WithStack(err) } if err := s.DB.Model(new(model.Forage)).Where("id = ?", req.ForageId).Update("is_show", req.IsShow).Error; err != nil { return xerr.WithStack(err) } return nil } // ExcelImportForage 导入excel func (s *StoreEntry) ExcelImportForage(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] } forageList := make([]*model.Forage, 0) for i, row := range rows { if i == 0 { continue } var ( forageSourceId int32 categoryId, price, jumpWeight, relayLocations int allowError, packageWeight int name, uniqueEncode, backup1, backup2, backup3 string ) for k, v := range row { if k == 0 { name = v } if k == 2 { uniqueEncode = v } if k == 3 { forageSourceId = operationPb.ForageSource_Kind_value[v] } if k == 5 { allowError, _ = strconv.Atoi(v) } if k == 6 { packageWeight, _ = strconv.Atoi(v) } if k == 7 { price, _ = strconv.Atoi(v) } if k == 8 { jumpWeight, _ = strconv.Atoi(v) } if k == 11 { relayLocations, _ = strconv.Atoi(v) } if k == 13 { backup1 = v } if k == 14 { backup2 = v } if k == 15 { backup3 = v } } forageItem := &model.Forage{ Name: name, CategoryId: int64(categoryId), MaterialTypeKey: 0, MaterialTypeName: "", UniqueEncode: uniqueEncode, ForageSourceId: operationPb.ForageSource_Kind(forageSourceId), PlanTypeId: 0, SmallMaterialScale: "", AllowError: int64(allowError), PackageWeight: int64(packageWeight), Price: int64(price), JumpWeight: int64(jumpWeight), JumpDelay: 0, ConfirmStart: 0, RelayLocations: int64(relayLocations), Jmp: 0, Backup1: backup1, Backup2: backup2, Backup3: backup3, IsShow: operationPb.IsShow_OK, IsDelete: operationPb.IsShow_OK, DataSource: operationPb.DataSource_EXCEL_IMPORT, } forageList = append(forageList, forageItem) } if len(forageList) > 0 { if err = s.DB.Create(forageList).Error; err != nil { return xerr.WithStack(err) } } return nil } // ExcelExportForage 流式导出excel func (s *StoreEntry) ExcelExportForage(ctx context.Context, req *operationPb.SearchForageListRequest) (*bytes.Buffer, error) { res, err := s.SearchForageList(ctx, req) if err != nil { return nil, xerr.WithStack(err) } if len(res.Data.List) <= 0 { return nil, xerr.Custom("数据为空") } file := excelize.NewFile() defer file.Close() streamWriter, err := file.NewStreamWriter(model.DefaultSheetName) if err != nil { return nil, xerr.WithStack(err) } titles := []interface{}{"饲料名称", "饲料分类", "唯一编码", "饲料来源", "计划类型", "允许误差(kg)", "包装单位重量(kg)", "单价", "跳转重量域(kg)", "跳转延迟", "确认开始", "继电器位置", "无上域", "备用字段01", "备用字段02", "备用字段03"} if err = streamWriter.SetRow("A1", titles); err != nil { return nil, xerr.WithStack(err) } for i, item := range res.Data.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.CategoryName, item.UniqueEncode, item.ForageSourceId, item.PlanTypeId, item.AllowError, item.PackageWeight, float64(item.Price/100.00), item.JumpWeight, item.JumpDelay, item.ConfirmStart, item.RelayLocations, item.Jmp, item.Backup1, item.Backup2, item.Backup3) 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() } // ExcelTemplateForage 导出模板 func (s *StoreEntry) ExcelTemplateForage(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)", "包装单位重量(kg)", "单价", "跳转重量域(kg)", "跳转延迟", "确认开始", "继电器位置", "无上域", "备用字段01", "备用字段02", "备用字段03"} 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() } func (s *StoreEntry) SmallMaterial(ctx context.Context, req *operationPb.SmallMaterialRequest) (*model.PastureCommonResponse, error) { body := &model.PastureCommonRequest{ Name: req.ApiName, ReturnType: "Map", ParamMaps: &model.FormulaEstimateParams{ PastureId: fmt.Sprintf("%d", req.PastureId), ImforName: req.InfoName, }, } response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}} if err := s.PastureHttpClient(ctx, model.UrlDataByName, int64(req.PastureId), body, response); err != nil { return nil, xerr.WithStack(err) } return response, nil }