dashboard_more.go 8.9 KB

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