dashboard_more.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. package backend
  2. import (
  3. "context"
  4. "kpt-pasture/model"
  5. "kpt-pasture/util"
  6. "net/http"
  7. "strconv"
  8. "strings"
  9. "time"
  10. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  11. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  12. "gitee.com/xuyiping_admin/pkg/xerr"
  13. "go.uber.org/zap"
  14. )
  15. func (s *StoreEntry) NeckRingWarning(ctx context.Context) (*pasturePb.IndexNeckRingResponse, error) {
  16. userModel, err := s.GetUserModel(ctx)
  17. if err != nil {
  18. return nil, xerr.WithStack(err)
  19. }
  20. var count int64
  21. neckRingEstrusList := make([]*model.NeckRingEstrusWarning, 0)
  22. estrusWarningLevelItems := map[int32]int32{
  23. int32(pasturePb.EstrusLevel_Low): 0,
  24. int32(pasturePb.EstrusLevel_Middle): 0,
  25. int32(pasturePb.EstrusLevel_High): 0,
  26. }
  27. pref, err := s.EstrusWarningQuery(ctx, userModel.AppPasture.Id)
  28. if err != nil {
  29. return nil, xerr.Customf("系统错误!")
  30. }
  31. if err = pref.Order("a.level DESC").
  32. Count(&count).
  33. Find(&neckRingEstrusList).Error; err != nil {
  34. return nil, xerr.WithStack(err)
  35. }
  36. countEstrusWarning := 0
  37. nowTime := time.Now().Local()
  38. optimumMating := map[string]int32{
  39. "front": 0,
  40. "middle": 0,
  41. "behind": 0,
  42. }
  43. for _, v := range neckRingEstrusList {
  44. estrusWarningLevelItems[int32(v.Level)] += 1
  45. countEstrusWarning += 1
  46. cowInfo, _ := s.GetCowInfoByEarNumber(ctx, userModel.AppPasture.Id, v.EarNumber)
  47. pzHour := v.CalculatePzHour(cowInfo.Lact)
  48. optimumMatingStartTime := pzHour.Add(-4 * time.Hour)
  49. optimumMatingEndTime := pzHour.Add(4 * time.Hour)
  50. // 判断当前时间是否在 pzHour-4h 到 pzHour+4h 之间
  51. if nowTime.After(optimumMatingStartTime) && nowTime.Before(optimumMatingEndTime) {
  52. optimumMating["middle"] += 1
  53. }
  54. if nowTime.After(optimumMatingEndTime) {
  55. optimumMating["behind"] += 1
  56. }
  57. if nowTime.Before(optimumMatingStartTime) {
  58. optimumMating["front"] += 1
  59. }
  60. }
  61. abortionCount := int64(0)
  62. pref, err = s.AbortionWarningQuery(ctx, userModel.AppPasture.Id)
  63. if err != nil {
  64. return nil, xerr.Customf("系统错误!")
  65. }
  66. if err = pref.Group("cow_id").Count(&abortionCount).Error; err != nil {
  67. return nil, xerr.WithStack(err)
  68. }
  69. healthWarningNumber := int64(0)
  70. if err = s.DB.Model(new(model.NeckRingHealthWarning)).
  71. Where("pasture_id = ?", userModel.AppPasture.Id).
  72. Where("is_show = ?", pasturePb.IsShow_Ok).
  73. Group("cow_id").
  74. Count(&healthWarningNumber).Error; err != nil {
  75. zaplog.Error("NeckRingWarning", zap.Any("estrusWarningNumber", err))
  76. }
  77. return &pasturePb.IndexNeckRingResponse{
  78. Code: http.StatusOK,
  79. Msg: "ok",
  80. Data: &pasturePb.NeckRingData{
  81. EstrusWarningNumber: int32(countEstrusWarning),
  82. HealthWarningNumber: int32(healthWarningNumber),
  83. AbortionWarningNumber: int32(abortionCount),
  84. StressWarningNumber: 0,
  85. EstrusWarningLevelItems: estrusWarningLevelItems,
  86. OptimumMating: optimumMating,
  87. },
  88. }, nil
  89. }
  90. func (s *StoreEntry) FocusIndicatorsList(ctx context.Context, dimension string) (*pasturePb.IndexFocusIndicatorsResponse, error) {
  91. userModel, err := s.GetUserModel(ctx)
  92. if err != nil {
  93. return nil, xerr.WithStack(err)
  94. }
  95. userFocusIndicators := userModel.SystemUser.IndicatorsKinds
  96. if len(userFocusIndicators) <= 0 {
  97. userFocusIndicators = model.DefaultFocusIndicators
  98. }
  99. userFocusIndicatorsList := strings.Split(userFocusIndicators, ",")
  100. indicatorsDataList := make([]*model.IndicatorsData, 0)
  101. pref := s.DB.Model(new(model.IndicatorsData)).
  102. Where("pasture_id = ?", userModel.AppPasture.Id).
  103. Where("kind in (?)", userFocusIndicatorsList)
  104. /*if dimension == "Year" {
  105. pref.Where("date = ?", time.Now().Local().Format(model.LayoutMonth))
  106. }*/
  107. nowTime := time.Now().Local()
  108. if dimension == "Month" {
  109. pref.Where("date = ?", nowTime.Format(model.LayoutMonth))
  110. }
  111. if err = pref.Find(&indicatorsDataList).Error; err != nil {
  112. zaplog.Error("FocusIndicators", zap.Any("err", err))
  113. }
  114. indicatorsDetailsMap, _, err := s.GetIndicatorsDetailsMap(ctx)
  115. if err != nil {
  116. return nil, xerr.WithStack(err)
  117. }
  118. focusIndicatorsList := make([]*pasturePb.FocusIndicators, 0)
  119. for _, v := range indicatorsDataList {
  120. indicatorsDetails, ok := indicatorsDetailsMap[v.Kind]
  121. if !ok {
  122. continue
  123. }
  124. onYear, onMonth := "", ""
  125. isUp := pasturePb.IsShow_Ok
  126. if dimension == "Year" {
  127. return nil, xerr.Custom("暂不支持该维度")
  128. }
  129. if dimension == "Month" {
  130. lastMonth := nowTime.AddDate(0, -1, 0).Format(model.LayoutMonth)
  131. oldIndicators, _ := s.GetIndicatorsDataByDate(userModel.AppPasture.Id, v.Kind, lastMonth)
  132. if oldIndicators != nil {
  133. if oldIndicators.Value != "" && oldIndicators.Value != "0" {
  134. oldValue, _ := strconv.ParseFloat(oldIndicators.Value, 64)
  135. currValue, _ := strconv.ParseFloat(v.Value, 64)
  136. onMonthValue := float64(0)
  137. if oldValue > 0 {
  138. onMonthValue = (oldValue - currValue) / oldValue * 100
  139. }
  140. omv := util.RoundToTwoDecimals(onMonthValue)
  141. if omv < 0 {
  142. isUp = pasturePb.IsShow_No
  143. }
  144. onMonth = strconv.FormatFloat(omv, 'f', 2, 64) + "%"
  145. }
  146. }
  147. }
  148. focusIndicatorsList = append(focusIndicatorsList, &pasturePb.FocusIndicators{
  149. Kind: indicatorsDetails.Kind,
  150. Name: indicatorsDetails.Name,
  151. Value: v.Value,
  152. Describe: indicatorsDetails.Zh,
  153. UnitName: indicatorsDetails.Unit,
  154. OnMonth: onMonth,
  155. OnYear: onYear,
  156. IsUp: isUp,
  157. })
  158. }
  159. indicatorsDetailsList, _ := s.FindIndicatorsDetailsList(ctx)
  160. return &pasturePb.IndexFocusIndicatorsResponse{
  161. Code: http.StatusOK,
  162. Msg: "ok",
  163. Data: &pasturePb.FocusData{
  164. FocusIndicators: focusIndicatorsList,
  165. IndicatorsSet: model.IndicatorsDetailsSlice(indicatorsDetailsList).ToPB(userFocusIndicatorsList),
  166. },
  167. }, err
  168. }
  169. func (s *StoreEntry) FocusIndicatorsSet(ctx context.Context, req *pasturePb.IndexFocusIndicatorsSetRequest) error {
  170. userModel, err := s.GetUserModel(ctx)
  171. if err != nil {
  172. return xerr.WithStack(err)
  173. }
  174. if len(req.IndicatorsKind) <= 0 {
  175. return nil
  176. }
  177. userFocusIndicators := strings.Join(req.IndicatorsKind, ",")
  178. if err = s.DB.Model(new(model.SystemUser)).
  179. Where("id = ?", userModel.SystemUser.Id).
  180. Update("indicators_kinds", userFocusIndicators).Error; err != nil {
  181. return xerr.WithStack(err)
  182. }
  183. return nil
  184. }
  185. func (s *StoreEntry) Equipment(ctx context.Context) (*pasturePb.EquipmentResponse, error) {
  186. userModel, err := s.GetUserModel(ctx)
  187. if err != nil {
  188. return nil, xerr.WithStack(err)
  189. }
  190. equipmentList := make([]*pasturePb.Equipment, 0)
  191. dashboardNeckRingList := make([]*model.DashboardNeckRing, 0)
  192. if err = s.DB.Model(new(model.NeckRing)).
  193. Select("status, count(*) as number").
  194. Where("pasture_id = ?", userModel.AppPasture.Id).
  195. Group("status").
  196. Find(&dashboardNeckRingList).Error; err != nil {
  197. }
  198. normalNumber, abnormalNumber := int32(0), int32(0)
  199. for _, v := range dashboardNeckRingList {
  200. if v.Status == pasturePb.NeckRingStatus_Normal {
  201. normalNumber = v.Number
  202. }
  203. if v.Status == pasturePb.NeckRingStatus_Abnormal {
  204. abnormalNumber = v.Number
  205. }
  206. }
  207. var receiverCount int64
  208. if err = s.DB.Model(new(model.AppPastureReceiver)).
  209. Where("pasture_id = ?", userModel.AppPasture.Id).
  210. Count(&receiverCount).Error; err != nil {
  211. }
  212. equipmentList = append(equipmentList, &pasturePb.Equipment{
  213. Name: "异常脖环数",
  214. Describe: "脖环",
  215. NormalNumber: normalNumber,
  216. AbnormalNumber: abnormalNumber,
  217. Icon: "/assets/welcome/ring@2x.png",
  218. Kind: pasturePb.EquipmentType_Neck_Ring,
  219. }, &pasturePb.Equipment{
  220. Name: "离线接收器",
  221. Describe: "接收器",
  222. NormalNumber: int32(receiverCount),
  223. AbnormalNumber: int32(0),
  224. Icon: "/assets/welcome/device@2x.png",
  225. Kind: pasturePb.EquipmentType_Receiver,
  226. })
  227. return &pasturePb.EquipmentResponse{
  228. Code: http.StatusOK,
  229. Msg: "ok",
  230. Data: &pasturePb.EquipmentData{EquipmentList: equipmentList},
  231. }, nil
  232. }