cow.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. package backend
  2. import (
  3. "context"
  4. "fmt"
  5. "kpt-pasture/model"
  6. "kpt-pasture/util"
  7. "net/http"
  8. "strings"
  9. "time"
  10. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  11. "go.uber.org/zap"
  12. "gitee.com/xuyiping_admin/pkg/xerr"
  13. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  14. )
  15. func (s *StoreEntry) Detail(ctx context.Context, req *pasturePb.SearchEventRequest) (*pasturePb.CowInfoResponse, error) {
  16. userModel, err := s.GetUserModel(ctx)
  17. if err != nil {
  18. return nil, xerr.WithStack(err)
  19. }
  20. cowInfo := make([]*model.Cow, 0)
  21. pref := s.DB.Model(new(model.Cow)).Where("pasture_id = ?", userModel.AppPasture.Id).Where("id = ?", req.CowId)
  22. if req.NeckRingNumber != "" {
  23. pref.Where("neck_ring_number = ?", req.NeckRingNumber)
  24. }
  25. if req.EarNumber != "" {
  26. pref.Where("ear_number = ?", req.EarNumber)
  27. }
  28. if err = pref.Order("id desc").
  29. Find(&cowInfo).Error; err != nil {
  30. return nil, xerr.WithStack(err)
  31. }
  32. penMap := s.PenMap(ctx, userModel.AppPasture.Id)
  33. cowTypeMap := s.CowTypeMap()
  34. breedStatusMap := s.CowBreedStatusMap()
  35. cowKindMap := s.CowKindMap()
  36. cowSourceMap := s.CowSourceMap()
  37. admissionStatusMap := s.AdmissionStatusMap()
  38. healthStatusMap := s.HealthStatusMap()
  39. return &pasturePb.CowInfoResponse{
  40. Code: http.StatusOK,
  41. Msg: "ok",
  42. Data: model.CowSlice(cowInfo).ToPB(penMap, cowTypeMap, breedStatusMap, cowKindMap, cowSourceMap, admissionStatusMap, healthStatusMap)[0],
  43. }, nil
  44. }
  45. func (s *StoreEntry) List(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchCowListResponse, error) {
  46. userModel, err := s.GetUserModel(ctx)
  47. if err != nil {
  48. return nil, xerr.WithStack(err)
  49. }
  50. cowList := make([]*model.Cow, 0)
  51. var count int64 = 0
  52. pref := s.DB.Model(new(model.Cow)).
  53. Where("pasture_id = ?", userModel.AppPasture.Id)
  54. if len(req.CowId) > 0 {
  55. cowIds := strings.Split(req.CowId, ",")
  56. pref.Where("id IN ?", cowIds)
  57. }
  58. if req.Id > 0 {
  59. pref.Where("id = ?", req.Id)
  60. }
  61. if req.PenId > 0 {
  62. pref.Where("pen_id = ?", req.PenId)
  63. }
  64. if req.CowType > 0 {
  65. pref.Where("cow_type = ?", req.CowType)
  66. }
  67. if req.BreedStatus > 0 {
  68. pref.Where("breed_status = ?", req.BreedStatus)
  69. }
  70. if req.CowKind > 0 {
  71. pref.Where("cow_kind = ?", req.CowKind)
  72. }
  73. if req.Sex > 0 {
  74. pref.Where("sex = ?", req.Sex)
  75. }
  76. if req.Lact > 0 {
  77. pref.Where("lact = ?", req.Lact)
  78. }
  79. if req.CowSource > 0 {
  80. pref.Where("source_id = ?", req.CowSource)
  81. }
  82. if req.EarNumber != "" {
  83. pref.Where("ear_number = ?", req.EarNumber)
  84. }
  85. if err = pref.Order("id desc").
  86. Count(&count).
  87. Limit(int(pagination.PageSize)).
  88. Offset(int(pagination.PageOffset)).
  89. Find(&cowList).Error; err != nil {
  90. return nil, xerr.WithStack(err)
  91. }
  92. penMap := s.PenMap(ctx, userModel.AppPasture.Id)
  93. cowTypeMap := s.CowTypeMap()
  94. breedStatusMap := s.CowBreedStatusMap()
  95. cowKindMap := s.CowKindMap()
  96. cowSourceMap := s.CowSourceMap()
  97. admissionStatusMap := s.AdmissionStatusMap()
  98. healthStatusMap := s.HealthStatusMap()
  99. return &pasturePb.SearchCowListResponse{
  100. Code: http.StatusOK,
  101. Msg: "ok",
  102. Data: &pasturePb.SearchCowData{
  103. List: model.CowSlice(cowList).ToPB(
  104. penMap, cowTypeMap, breedStatusMap, cowKindMap,
  105. cowSourceMap, admissionStatusMap, healthStatusMap,
  106. ),
  107. Total: int32(count),
  108. PageSize: pagination.PageSize,
  109. Page: pagination.Page,
  110. },
  111. }, nil
  112. }
  113. func (s *StoreEntry) EventList(ctx context.Context, req *pasturePb.SearchCowEventListRequest, pagination *pasturePb.PaginationModel) (*pasturePb.CowEventListResponse, error) {
  114. userModel, err := s.GetUserModel(ctx)
  115. if err != nil {
  116. return nil, xerr.WithStack(err)
  117. }
  118. cow := &model.Cow{}
  119. if err = s.DB.Model(cow).
  120. Where("pasture_id = ?", userModel.AppPasture.Id).
  121. Where("id = ?", req.CowId).First(cow).Error; err != nil {
  122. zaplog.Error("EventList", zap.Any("req", req), zap.Any("err", err), zap.Any("userModel", userModel))
  123. return nil, xerr.Customf("该牛不存在: %d", req.CowId)
  124. }
  125. eventCowLogList := make([]*model.EventCowLog, 0)
  126. eventCowLog := &model.EventCowLog{CowId: cow.Id}
  127. pref := s.DB.Table(eventCowLog.TableName()).
  128. Where("cow_id = ?", req.CowId)
  129. if req.Lact >= 0 {
  130. pref.Where("lact = ?", req.Lact)
  131. }
  132. if req.EventCategoryKind > 0 {
  133. pref.Where("event_category_id = ?", req.EventCategoryKind)
  134. }
  135. if err = pref.Order("id desc").
  136. Limit(int(pagination.PageSize)).
  137. Offset(int(pagination.PageOffset)).
  138. Find(&eventCowLogList).Error; err != nil {
  139. zaplog.Error("EventList", zap.Any("req", req), zap.Any("err", err), zap.Any("userModel", userModel))
  140. return nil, xerr.WithStack(err)
  141. }
  142. eventCategoryMap := s.EventCategoryMap()
  143. return &pasturePb.CowEventListResponse{
  144. Code: http.StatusOK,
  145. Msg: "ok",
  146. Data: &pasturePb.CowEventData{
  147. List: model.EventCowLogSlice(eventCowLogList).ToPB(eventCategoryMap),
  148. Total: int32(len(eventCowLogList)),
  149. PageSize: pagination.PageSize,
  150. Page: pagination.Page,
  151. },
  152. }, nil
  153. }
  154. func (s *StoreEntry) BehaviorCurve(ctx context.Context, req *pasturePb.CowBehaviorCurveRequest) (*model.CowBehaviorCurveResponse, error) {
  155. userModel, err := s.GetUserModel(ctx)
  156. if err != nil {
  157. return nil, xerr.WithStack(err)
  158. }
  159. cowInfo, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId))
  160. if err != nil {
  161. return nil, xerr.Customf("错误的牛只信息: %d", req.CowId)
  162. }
  163. nowTime := time.Now()
  164. nowDayZero := util.TimeParseLocalUnix(nowTime.Format(model.LayoutDate2))
  165. endDataTime := nowTime.Format(model.LayoutDate2)
  166. startDataTime := nowTime.AddDate(0, 0, -30).Format(model.LayoutDate2)
  167. // 行为曲线数据
  168. neckActiveHabitList := make([]*model.NeckActiveHabit, 0)
  169. if err = s.DB.Table(new(model.NeckActiveHabit).TableName()).
  170. Where("neck_ring_number = ?", cowInfo.NeckRingNumber).
  171. Where("pasture_id = ?", userModel.AppPasture.Id).
  172. Where("heat_date BETWEEN ? AND ?", startDataTime, endDataTime).
  173. Order("heat_date, frameid").
  174. Find(&neckActiveHabitList).Error; err != nil {
  175. return nil, xerr.WithStack(err)
  176. }
  177. // 牛只事件列表
  178. eventLogList := make([]*model.EventCowLog, 0)
  179. eventLog := &model.EventCowLog{CowId: cowInfo.Id}
  180. if err = s.DB.Table(eventLog.TableName()).
  181. Where("cow_id = ?", cowInfo.Id).
  182. Where("pasture_id = ?", userModel.AppPasture.Id).
  183. Where("event_at BETWEEN ? AND ?", nowDayZero-(30*86400), nowDayZero+86400).
  184. Order("event_at").
  185. Find(&eventLogList).Error; err != nil {
  186. return nil, xerr.WithStack(err)
  187. }
  188. data := model.NeckActiveHabitSlice(neckActiveHabitList).ToPB(req.CurveName, startDataTime, endDataTime)
  189. data.EventMap = s.EventTypeMap()
  190. for _, v := range eventLogList {
  191. eventAt := time.Unix(v.EventAt, 0)
  192. if data.EventList[v.EventTypeName] == nil {
  193. data.EventList[v.EventTypeName] = make([]string, 0)
  194. }
  195. data.EventList[v.EventTypeName] = append(data.EventList[v.EventTypeName], fmt.Sprintf("%s 09", eventAt.Format(model.LayoutDate2)))
  196. }
  197. // 发情数据
  198. estrusList := make([]*model.NeckRingEstrus, 0)
  199. if err = s.DB.Table(new(model.NeckRingEstrus).TableName()).
  200. Where("cow_id = ?", cowInfo.Id).
  201. Where("pasture_id = ?", userModel.AppPasture.Id).
  202. Where("estrus_start_date >= ?", startDataTime).
  203. Where("estrus_start_date <= ?", endDataTime).
  204. Order("estrus_start_date").
  205. Find(&estrusList).Error; err != nil {
  206. return nil, xerr.WithStack(err)
  207. }
  208. for _, v := range estrusList {
  209. if data.EstrusList[v.Level] == nil {
  210. data.EstrusList[v.Level] = make([]string, 0)
  211. }
  212. if len(v.EstrusStartDate) > 0 {
  213. // 格式化为到小时的字符串
  214. parsedTime, _ := time.Parse(model.LayoutTime, v.EstrusStartDate)
  215. hourStr := parsedTime.Format(model.LayoutHour)
  216. data.EstrusList[v.Level] = append(data.EstrusList[v.Level], hourStr)
  217. }
  218. }
  219. return &model.CowBehaviorCurveResponse{
  220. Code: http.StatusOK,
  221. Msg: "ok",
  222. Data: data,
  223. }, nil
  224. }
  225. func (s *StoreEntry) CowGrowthCurve(ctx context.Context, req *pasturePb.CowGrowthCurveRequest) (*pasturePb.CowGrowthCurveResponse, error) {
  226. userModel, err := s.GetUserModel(ctx)
  227. if err != nil {
  228. return nil, xerr.WithStack(err)
  229. }
  230. cowInfo, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId))
  231. if err != nil {
  232. return nil, xerr.Customf("错误的牛只信息: %d", req.CowId)
  233. }
  234. weightList := make([]*model.EventWeight, 0)
  235. if err = s.DB.Table(new(model.EventWeight).TableName()).
  236. Where("cow_id = ?", cowInfo.Id).
  237. Where("pasture_id = ?", userModel.AppPasture.Id).
  238. Order("weight_at").
  239. Find(&weightList).Error; err != nil {
  240. return nil, xerr.WithStack(err)
  241. }
  242. return &pasturePb.CowGrowthCurveResponse{
  243. Code: http.StatusOK,
  244. Msg: "ok",
  245. Data: model.EventWeightSlice(weightList).ToPB(),
  246. }, nil
  247. }