Yi преди 1 седмица
родител
ревизия
ac3eead400
променени са 5 файла, в които са добавени 75 реда и са изтрити 18 реда
  1. 2 2
      go.mod
  2. 4 0
      go.sum
  3. 38 16
      model/data_notice.go
  4. 2 0
      module/backend/neck_ring_warning.go
  5. 29 0
      module/crontab/cow_neck_ring_error.go

+ 2 - 2
go.mod

@@ -3,8 +3,8 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20250613015007-39c38d700b04
-	gitee.com/xuyiping_admin/pkg v0.0.0-20250514071642-f92d2ac9a85d
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20250613080456-430ffc4a0af3
+	gitee.com/xuyiping_admin/pkg v0.0.0-20250613101634-36c36a2d27d0
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/eclipse/paho.mqtt.golang v1.4.3
 	github.com/eko/gocache v1.1.0

+ 4 - 0
go.sum

@@ -158,10 +158,14 @@ gitee.com/xuyiping_admin/go_proto v0.0.0-20250612030131-3c8b446ca813 h1:ttDGhXoy
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250612030131-3c8b446ca813/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250613015007-39c38d700b04 h1:sl0O3loQUllFaQKpEWzLxYo6X3JSA1XkkZyG1+jAelA=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250613015007-39c38d700b04/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250613080456-430ffc4a0af3 h1:c5JtCkem6L1VsCw3QkkjLBrmVhWOOZfkcOhV23aVnKo=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250613080456-430ffc4a0af3/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b h1:w05MxH7yqveRlaRbxHhbif5YjPrJFodRPfOjYhXn7Zk=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
 gitee.com/xuyiping_admin/pkg v0.0.0-20250514071642-f92d2ac9a85d h1:vBXmMRggF7mZVPGRDgavZ87igJgkezwX0a3v1/XtIMQ=
 gitee.com/xuyiping_admin/pkg v0.0.0-20250514071642-f92d2ac9a85d/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
+gitee.com/xuyiping_admin/pkg v0.0.0-20250613101634-36c36a2d27d0 h1:ZCOqEAnGm6+DTAhACigzWKbwMKtleb8/7OzP2xfHG7g=
+gitee.com/xuyiping_admin/pkg v0.0.0-20250613101634-36c36a2d27d0/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=

+ 38 - 16
model/data_notice.go

@@ -4,19 +4,25 @@ import (
 	"kpt-pasture/util"
 	"strconv"
 	"strings"
+	"time"
+
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
 )
 
+const DefaultDataLatencyMinutes = 40
+
 type DataNotice struct {
-	Id         int64  `json:"id"`
-	PastureId  int64  `json:"pastureId"`
-	Title      string `json:"title"`
-	Content    string `json:"content"`
-	KnownUsers string `json:"knownUsers"`
-	StartDate  string `json:"startDate"`
-	EndDate    string `json:"endDate"`
-	IsShow     int32  `json:"isShow"`
-	CreatedAt  int64  `json:"createdAt"`
-	UpdatedAt  int64  `json:"updatedAt"`
+	Id         int64                     `json:"id"`
+	PastureId  int64                     `json:"pastureId"`
+	Title      string                    `json:"title"`
+	Content    string                    `json:"content"`
+	KnownUsers string                    `json:"knownUsers"`
+	NoticeKind pasturePb.NoticeType_Kind `json:"noticeKind"`
+	StartDate  string                    `json:"startDate"`
+	EndDate    string                    `json:"endDate"`
+	IsShow     pasturePb.IsShow_Kind     `json:"isShow"`
+	CreatedAt  int64                     `json:"createdAt"`
+	UpdatedAt  int64                     `json:"updatedAt"`
 }
 
 func (d *DataNotice) TableName() string {
@@ -35,6 +41,20 @@ func (d *DataNotice) GetUserIds() []int64 {
 	return userIds
 }
 
+func NewDataNotice(pastureId int64, title, content string, noticeKind pasturePb.NoticeType_Kind) *DataNotice {
+	nowTime := time.Now().Local()
+	return &DataNotice{
+		Title:      title,
+		Content:    content,
+		StartDate:  nowTime.Format(LayoutDate2),
+		EndDate:    nowTime.Format(LayoutDate2),
+		IsShow:     pasturePb.IsShow_Ok,
+		PastureId:  pastureId,
+		NoticeKind: noticeKind,
+		KnownUsers: "",
+	}
+}
+
 type DataNoticeSlice []*DataNotice
 
 func (d DataNoticeSlice) ToPB(currentUserId int64) []*NoticeContent {
@@ -45,9 +65,10 @@ func (d DataNoticeSlice) ToPB(currentUserId int64) []*NoticeContent {
 			continue
 		}
 		res = append(res, &NoticeContent{
-			Id:      v.Id,
-			Title:   v.Title,
-			Content: v.Content,
+			Id:         v.Id,
+			Title:      v.Title,
+			Content:    v.Content,
+			NoticeKind: v.NoticeKind,
 		})
 	}
 	return res
@@ -60,7 +81,8 @@ type DataNoticeResponse struct {
 }
 
 type NoticeContent struct {
-	Id      int64  `json:"id"`
-	Title   string `json:"title"`
-	Content string `json:"content"`
+	Id         int64                     `json:"id"`
+	Title      string                    `json:"title"`
+	Content    string                    `json:"content"`
+	NoticeKind pasturePb.NoticeType_Kind `json:"noticeKind"`
 }

+ 2 - 0
module/backend/neck_ring_warning.go

@@ -350,6 +350,8 @@ func (s *StoreEntry) DataNoticeDetail(ctx context.Context) *model.DataNoticeResp
 		Where("pasture_id = ?", pastureId).
 		Where("is_show = ?", pasturePb.IsShow_Ok).
 		Where("start_date >= ? AND end_date <= ?", nowTime, nowTime).
+		Order("id desc").
+		Group("notice_kind").
 		Find(&noticeList).Error; err != nil {
 		return res
 	}

+ 29 - 0
module/crontab/cow_neck_ring_error.go

@@ -1,6 +1,7 @@
 package crontab
 
 import (
+	"fmt"
 	"kpt-pasture/model"
 	"kpt-pasture/util"
 	"time"
@@ -18,6 +19,7 @@ func (e *Entry) CowNeckRingErrorEnter() (err error) {
 	}
 	for _, pasture := range pastureList {
 		e.CowNeckRingError(pasture.Id)
+		e.NeckRingLastDate(pasture.Id)
 		zaplog.Error("CowNeckRingErrorEnter-Success", zap.Any("pasture", pasture))
 	}
 	return nil
@@ -281,3 +283,30 @@ func (e *Entry) NeckRingErrorOfDataLatency(pastureId int64, neckRing *model.Neck
 	}
 	return pasturePb.NeckRingNumberError_Invalid
 }
+
+// NeckRingLastDate 获取牧场脖环最后数据时间
+func (e *Entry) NeckRingLastDate(pastureId int64) {
+	lastOriginalData := &model.NeckRingOriginal{}
+	if err := e.DB.Model(new(model.NeckRingOriginal)).
+		Where("pasture_id = ?", pastureId).
+		Order("id DESC").
+		First(&lastOriginalData).Error; err != nil {
+		zaplog.Error("NeckRingLastDate", zap.Any("err", err), zap.Any("pastureId", pastureId))
+	}
+	if lastOriginalData.CreatedAt <= 0 {
+		return
+	}
+	nowTime := time.Now().Local()
+	subMinutes := nowTime.Sub(time.Unix(lastOriginalData.CreatedAt, 0)).Minutes()
+	if subMinutes >= model.DefaultDataLatencyMinutes {
+
+		hours := int(subMinutes) / 60
+		minutes := int(subMinutes) % 60
+		title := "脖环数据延迟"
+		content := fmt.Sprintf("距离目前已经%d小时%d分钟未接收到脖环数据,核实是否有电,如有电请及时联系服务工程师", hours, minutes)
+		newDataNotice := model.NewDataNotice(pastureId, title, content, pasturePb.NoticeType_Neck_Ring_Data_Latency)
+		if err := e.DB.Model(new(model.DataNotice)).Create(newDataNotice).Error; err != nil {
+			zaplog.Error("NeckRingLastDate", zap.Any("err", err), zap.Any("pastureId", pastureId))
+		}
+	}
+}