123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- package backend
- import (
- "context"
- "kpt-pasture/model"
- "kpt-pasture/util"
- "net/http"
- "strconv"
- "strings"
- "time"
- "gorm.io/gorm"
- "gitee.com/xuyiping_admin/pkg/logger/zaplog"
- "gitee.com/xuyiping_admin/pkg/xerr"
- "go.uber.org/zap"
- pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
- )
- func (s *StoreEntry) Bar(ctx context.Context) (*pasturePb.BarCowStructResponse, error) {
- barCowStructList := make([]*model.BarCowStruct, 0)
- var count int32 = 0
- if err := s.DB.Model(new(model.Cow)).
- Select("COUNT(*) AS number ,cow_type").
- Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
- Group("cow_type").
- Find(&barCowStructList).Error; err != nil {
- return nil, xerr.WithStack(err)
- }
- cowTypeMap := s.CowTypeMap()
- for _, v := range barCowStructList {
- count += v.Number
- }
- return &pasturePb.BarCowStructResponse{
- Code: http.StatusOK,
- Msg: "ok",
- Data: &pasturePb.BarCowStructData{
- List: model.BarCowStructSlice(barCowStructList).ToPB(cowTypeMap, count),
- Total: 38563,
- },
- }, nil
- }
- func (s *StoreEntry) NeckRingWarning(ctx context.Context) (*pasturePb.IndexNeckRingResponse, error) {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- estrusWarningCowList := make([]*model.NeckRingEstrus, 0)
- estrusWarningLevelItems := map[int32]int32{
- int32(pasturePb.EstrusLevel_Low): 0,
- int32(pasturePb.EstrusLevel_Middle): 0,
- int32(pasturePb.EstrusLevel_High): 0,
- }
- if err = s.DB.Model(new(model.EventEstrus)).
- Where("pasture_id = ?", userModel.AppPasture.Id).
- Where("is_show = ?", pasturePb.IsShow_Ok).
- Group("cow_id").Find(&estrusWarningCowList).Error; err != nil {
- zaplog.Error("NeckRingWarning", zap.Any("estrusWarningNumber", err))
- }
- for _, v := range estrusWarningCowList {
- estrusWarningLevelItems[int32(v.Level)] += estrusWarningLevelItems[int32(v.Level)]
- }
- healthWarningNumber := int64(0)
- if err = s.DB.Model(new(model.NeckRingHealthWarning)).
- Where("pasture_id = ?", userModel.AppPasture.Id).
- Where("is_show = ?", pasturePb.IsShow_Ok).
- Group("cow_id").
- Count(&healthWarningNumber).Error; err != nil {
- zaplog.Error("NeckRingWarning", zap.Any("estrusWarningNumber", err))
- }
- return &pasturePb.IndexNeckRingResponse{
- Code: http.StatusOK,
- Msg: "ok",
- Data: &pasturePb.NeckRingData{
- EstrusWarningNumber: int32(len(estrusWarningCowList)),
- HealthWarningNumber: int32(healthWarningNumber),
- AbortionWarningNumber: 0,
- StressWarningNumber: 0,
- EstrusWarningLevelItems: estrusWarningLevelItems,
- },
- }, nil
- }
- func (s *StoreEntry) FocusIndicatorsList(ctx context.Context, dimension string) (*pasturePb.IndexFocusIndicatorsResponse, error) {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- userFocusIndicators := userModel.SystemUser.IndicatorsKinds
- if len(userFocusIndicators) <= 0 {
- userFocusIndicators = model.DefaultFocusIndicators
- }
- userFocusIndicatorsList := strings.Split(userFocusIndicators, ",")
- indicatorsDataList := make([]*model.IndicatorsData, 0)
- pref := s.DB.Model(new(model.IndicatorsData)).
- Where("pasture_id = ?", userModel.AppPasture.Id).
- Where("kind in (?)", userFocusIndicatorsList)
- /*if dimension == "Year" {
- pref.Where("date = ?", time.Now().Format(model.LayoutMonth))
- }*/
- nowTime := time.Now()
- if dimension == "Month" {
- pref.Where("date = ?", nowTime.Format(model.LayoutMonth))
- }
- if err = pref.Find(&indicatorsDataList).Error; err != nil {
- zaplog.Error("FocusIndicators", zap.Any("err", err))
- }
- indicatorsDetailsMap, _, err := s.GetIndicatorsDetailsMap(ctx)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- focusIndicatorsList := make([]*pasturePb.FocusIndicators, 0)
- for _, v := range indicatorsDataList {
- indicatorsDetails, ok := indicatorsDetailsMap[v.Kind]
- if !ok {
- continue
- }
- onYear, onMonth := "", ""
- if dimension == "Year" {
- return nil, xerr.Custom("暂不支持该维度")
- }
- if dimension == "Month" {
- lastMonth := nowTime.AddDate(0, -1, 0).Format(model.LayoutMonth)
- oldIndicators, _ := s.GetIndicatorsDataByDate(userModel.AppPasture.Id, v.Kind, lastMonth)
- if oldIndicators != nil {
- if oldIndicators.Value != "" && oldIndicators.Value != "0" {
- oldValue, _ := strconv.ParseFloat(oldIndicators.Value, 64)
- currValue, _ := strconv.ParseFloat(v.Value, 64)
- onMonthValue := (oldValue - currValue) / oldValue * 100
- omv := util.RoundToTwoDecimals(onMonthValue)
- onMonth = strconv.FormatFloat(omv, 'f', 2, 64) + "%"
- }
- }
- }
- focusIndicatorsList = append(focusIndicatorsList, &pasturePb.FocusIndicators{
- Kind: indicatorsDetails.Kind,
- Name: indicatorsDetails.Name,
- Value: v.Value,
- Describe: indicatorsDetails.Zh,
- UnitName: indicatorsDetails.Unit,
- OnMonth: onMonth,
- OnYear: onYear,
- })
- }
- indicatorsDetailsList, _ := s.FindIndicatorsDetailsList(ctx)
- return &pasturePb.IndexFocusIndicatorsResponse{
- Code: http.StatusOK,
- Msg: "ok",
- Data: &pasturePb.FocusData{
- FocusIndicators: focusIndicatorsList,
- IndicatorsSet: model.IndicatorsDetailsSlice(indicatorsDetailsList).ToPB(userFocusIndicatorsList),
- },
- }, err
- }
- func (s *StoreEntry) FocusIndicatorsSet(ctx context.Context, req *pasturePb.IndexFocusIndicatorsSetRequest) error {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return xerr.WithStack(err)
- }
- if len(req.IndicatorsKind) <= 0 {
- return nil
- }
- userFocusIndicators := strings.Join(req.IndicatorsKind, ",")
- if err = s.DB.Model(new(model.SystemUser)).
- Where("id = ?", userModel.SystemUser.Id).
- Update("indicators_kinds", userFocusIndicators).Error; err != nil {
- return xerr.WithStack(err)
- }
- return nil
- }
- func (s *StoreEntry) DataWarningSet(ctx context.Context, req *pasturePb.IndexDataWarningSetRequest) error {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return xerr.WithStack(err)
- }
- if len(req.WarningDataSet) <= 0 {
- return nil
- }
- defaultDataWarning, _ := s.FindDataWarning(ctx, model.DefaultUserId)
- if len(defaultDataWarning) <= 0 {
- return xerr.Custom("默认预警数据不存在,请联系管理员!")
- }
- userDataWarningList, err := s.FindDataWarning(ctx, userModel.SystemUser.Id)
- if err != nil {
- return xerr.WithStack(err)
- }
- if len(userDataWarningList) <= 0 { // 新增
- return s.addUserDataWarning(ctx, userModel.SystemUser.Id, defaultDataWarning, req.WarningDataSet)
- }
- return s.updateUserDataWarning(ctx, userModel.SystemUser.Id, userDataWarningList, req.WarningDataSet)
- }
- func (s *StoreEntry) DataWarningList(ctx context.Context) (*pasturePb.IndexDataWarningResponse, error) {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- defaultDataWarning, _ := s.FindDataWarning(ctx, model.DefaultUserId)
- if len(defaultDataWarning) <= 0 {
- return nil, xerr.Custom("默认预警数据有误,请联系管理员!")
- }
- var isExist bool // 判断是否存在自己的设置的数据
- userDataWarning, _ := s.FindDataWarning(ctx, userModel.SystemUser.Id)
- if len(userDataWarning) == 0 {
- // 如果用户没有配置自己的预警数据,则使用默认数据
- isExist = true
- userDataWarning = defaultDataWarning
- }
- newTime := time.Now().Unix()
- needUpdateWarningIds := make([]int64, 0)
- for _, warningData := range userDataWarning {
- // 如果预警数据更新时间大于预警条件更新时间,并且更新时间距离当前时间小于2小时,则跳过
- if warningData.DataUpdateAt > warningData.ConditionUpdateAt && newTime-warningData.DataUpdateAt < int64(2*time.Hour) {
- continue
- }
- needUpdateWarningIds = append(needUpdateWarningIds, warningData.Id)
- }
- // 需要重新计算更新的warningId
- if len(needUpdateWarningIds) > 0 {
- s.UpdateWarningData(ctx, needUpdateWarningIds)
- }
- userDataWarningItems := make([]*model.DataWarningItems, 0)
- // 计算过后重新获取数据
- if isExist {
- userDataWarning, _ = s.FindDataWarning(ctx, model.DefaultUserId)
- userDataWarningItems, _ = s.FindDataWarningItems(ctx, model.DefaultUserId)
- } else {
- userDataWarning, _ = s.FindDataWarning(ctx, userModel.SystemUser.Id)
- userDataWarningItems, _ = s.FindDataWarningItems(ctx, userModel.SystemUser.Id)
- }
- return &pasturePb.IndexDataWarningResponse{
- Code: http.StatusOK,
- Msg: "ok",
- Data: &pasturePb.DataWarning{
- DataSet: model.DataWarningItemsSlice(userDataWarningItems).ToPB(userDataWarning),
- DataShow: model.DataWarningSlice(userDataWarning).ToPB(),
- },
- }, nil
- }
- // 新增用户预警数据
- func (s *StoreEntry) addUserDataWarning(ctx context.Context, userId int64, defaultDataWarning []*model.DataWarning, warningDataSet []*pasturePb.WarningDataSet) error {
- // 将默认预警数据按 Kind 映射
- defaultDataWarningMap := make(map[string]*model.DataWarning)
- for _, v := range defaultDataWarning {
- defaultDataWarningMap[v.Kind] = v
- }
- // 在事务中执行新增操作
- return s.DB.Transaction(func(tx *gorm.DB) error {
- addedKinds := make(map[string]bool) // 记录已添加的 Kind
- for _, set := range warningDataSet {
- dataWarning := model.NewDataWarning(userId, set.Kind, pasturePb.IsShow_Ok, defaultDataWarningMap[set.Kind])
- // 如果该 Kind 已添加,跳过
- if !addedKinds[set.Kind] {
- // 创建新的预警数据
- if err := tx.Create(dataWarning).Error; err != nil {
- return xerr.WithStack(err)
- }
- } else {
- oldDataWarning := &model.DataWarning{}
- if err := tx.Model(new(model.DataWarning)).
- Where("user_id = ?", userId).
- Where("kind = ?", set.Kind).
- First(oldDataWarning).Error; err != nil {
- return xerr.WithStack(err)
- }
- dataWarning.Id = oldDataWarning.Id
- }
- // 创建预警项数据
- if err := tx.Create(model.NewDataWarningItems(userId, dataWarning, set)).Error; err != nil {
- return xerr.WithStack(err)
- }
- addedKinds[set.Kind] = true
- }
- return nil
- })
- }
- // 更新用户预警数据
- func (s *StoreEntry) updateUserDataWarning(ctx context.Context, userId int64, userDataWarningList []*model.DataWarning, warningDataSet []*pasturePb.WarningDataSet) error {
- // 将请求数据按 WarningId 和 Id 映射
- warningIsShowMap := make(map[int32]pasturePb.IsShow_Kind)
- warningItemDataMap := make(map[int32]*pasturePb.WarningDataSet)
- for _, set := range warningDataSet {
- warningIsShowMap[set.WarningId] = set.IsShow
- warningItemDataMap[set.Id] = set
- }
- // 获取用户预警项数据
- userDataWarningItems, err := s.FindDataWarningItems(ctx, userId)
- if err != nil {
- return xerr.WithStack(err)
- }
- if len(userDataWarningItems) == 0 {
- return xerr.Custom("预警数据有误,请联系管理员!")
- }
- // 在事务中执行更新操作
- return s.DB.Transaction(func(tx *gorm.DB) error {
- // 更新预警数据的 IsShow 字段
- for _, warning := range userDataWarningList {
- if isShow, ok := warningIsShowMap[int32(warning.Id)]; ok {
- if err = tx.Model(&model.DataWarning{}).
- Where("id = ?", warning.Id).
- Update("is_show", isShow).Error; err != nil {
- return xerr.WithStack(err)
- }
- }
- }
- // 更新预警项数据的 IsShow 和 Value 字段
- for _, item := range userDataWarningItems {
- if set, ok := warningItemDataMap[int32(item.Id)]; ok {
- if err = tx.Model(&model.DataWarningItems{}).
- Where("id = ?", item.Id).
- Updates(map[string]interface{}{
- "is_show": set.IsShow,
- "value": set.Value,
- }).Error; err != nil {
- return xerr.WithStack(err)
- }
- }
- }
- return nil
- })
- }
- func (s *StoreEntry) FindDataWarning(ctx context.Context, userId int64) ([]*model.DataWarning, error) {
- dataWarningList := make([]*model.DataWarning, 0)
- if err := s.DB.Model(new(model.DataWarning)).
- Where("user_id = ?", userId).
- Find(&dataWarningList).Error; err != nil {
- return nil, xerr.WithStack(err)
- }
- return dataWarningList, nil
- }
- func (s *StoreEntry) FindDataWarningItems(ctx context.Context, userId int64) ([]*model.DataWarningItems, error) {
- dataWarningItemsList := make([]*model.DataWarningItems, 0)
- if err := s.DB.Model(new(model.DataWarningItems)).
- Where("user_id = ?", userId).
- Find(&dataWarningItemsList).Error; err != nil {
- return nil, xerr.WithStack(err)
- }
- return dataWarningItemsList, nil
- }
- func (s *StoreEntry) FindDataWarningMap(ctx context.Context, userId int64) (map[int64]*model.DataWarning, error) {
- dataWarning, err := s.FindDataWarning(ctx, userId)
- if err != nil {
- return nil, xerr.Custom("默认预警数据有误,请联系管理员!")
- }
- dataWarningMap := make(map[int64]*model.DataWarning)
- for _, v := range dataWarning {
- dataWarningMap[v.Id] = v
- }
- return dataWarningMap, nil
- }
- func (s *StoreEntry) FindDataWarningItemsMap(ctx context.Context, userId int64) (map[int64]*model.DataWarningItems, error) {
- dataWarningItemsList := make([]*model.DataWarningItems, 0)
- if err := s.DB.Model(new(model.DataWarningItems)).
- Where("user_id = ?", userId).
- Find(&dataWarningItemsList).Error; err != nil {
- return nil, xerr.WithStack(err)
- }
- dataWarningItemsMap := make(map[int64]*model.DataWarningItems)
- for _, v := range dataWarningItemsList {
- dataWarningItemsMap[v.Id] = v
- }
- return dataWarningItemsMap, nil
- }
- // UpdateWarningData 更新计算数据
- func (s *StoreEntry) UpdateWarningData(ctx context.Context, needUpdateWarningIds []int64) {
- if len(needUpdateWarningIds) <= 0 {
- return
- }
- for _, warningId := range needUpdateWarningIds {
- query, params, err := s.BuildQuery(warningId)
- if err != nil {
- zaplog.Error("UpdateWarningData", zap.Any("BuildQuery", err), zap.Any("warningId", warningId))
- }
- if len(query) == 0 || len(params) == 0 {
- continue
- }
- var count int64
- if err = s.DB.Model(new(model.Cow)).Where(query, params...).Count(&count).Error; err != nil {
- zaplog.Error("UpdateWarningData", zap.Any("err", err), zap.Any("query", query), zap.Any("params", params))
- }
- if err = s.DB.Model(new(model.DataWarning)).
- Where("id = ?", warningId).
- Updates(map[string]interface{}{
- "data_value": count,
- "data_update_at": time.Now().Unix(),
- }).Error; err != nil {
- zaplog.Error("UpdateWarningData", zap.Any("update", err))
- }
- }
- }
|