dashboard.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. package backend
  2. import (
  3. "context"
  4. "errors"
  5. "kpt-pasture/model"
  6. "kpt-pasture/util"
  7. "net/http"
  8. "regexp"
  9. "strconv"
  10. "strings"
  11. "time"
  12. "gorm.io/gorm"
  13. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  14. "gitee.com/xuyiping_admin/pkg/xerr"
  15. "go.uber.org/zap"
  16. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  17. )
  18. func (s *StoreEntry) NeckRingWarning(ctx context.Context) (*pasturePb.IndexNeckRingResponse, error) {
  19. userModel, err := s.GetUserModel(ctx)
  20. if err != nil {
  21. return nil, xerr.WithStack(err)
  22. }
  23. var count int64
  24. neckRingEstrusList := make([]*model.NeckRingEstrusWarning, 0)
  25. estrusWarningLevelItems := map[int32]int32{
  26. int32(pasturePb.EstrusLevel_Low): 0,
  27. int32(pasturePb.EstrusLevel_Middle): 0,
  28. int32(pasturePb.EstrusLevel_High): 0,
  29. }
  30. pref, err := s.EstrusWarningQuery(ctx, userModel.AppPasture.Id)
  31. if err != nil {
  32. return nil, xerr.Customf("系统错误!")
  33. }
  34. if err = pref.Order("a.level DESC").
  35. Count(&count).
  36. Find(&neckRingEstrusList).Error; err != nil {
  37. return nil, xerr.WithStack(err)
  38. }
  39. countEstrusWarning := 0
  40. nowTime := time.Now().Local()
  41. optimumMating := map[string]int32{
  42. "front": 0,
  43. "middle": 0,
  44. "behind": 0,
  45. }
  46. for _, v := range neckRingEstrusList {
  47. estrusWarningLevelItems[int32(v.Level)] += 1
  48. countEstrusWarning += 1
  49. cowInfo, _ := s.GetCowInfoByEarNumber(ctx, userModel.AppPasture.Id, v.EarNumber)
  50. pzHour := v.CalculatePzHour(cowInfo.Lact)
  51. optimumMatingStartTime := pzHour.Add(-4 * time.Hour)
  52. optimumMatingEndTime := pzHour.Add(4 * time.Hour)
  53. // 判断当前时间是否在 pzHour-4h 到 pzHour+4h 之间
  54. if nowTime.After(optimumMatingStartTime) && nowTime.Before(optimumMatingEndTime) {
  55. optimumMating["middle"] += 1
  56. }
  57. if nowTime.After(optimumMatingEndTime) {
  58. optimumMating["behind"] += 1
  59. }
  60. if nowTime.Before(optimumMatingStartTime) {
  61. optimumMating["front"] += 1
  62. }
  63. }
  64. abortionCount := int64(0)
  65. pref, err = s.AbortionWarningQuery(ctx, userModel.AppPasture.Id)
  66. if err != nil {
  67. return nil, xerr.Customf("系统错误!")
  68. }
  69. if err = pref.Group("cow_id").Count(&abortionCount).Error; err != nil {
  70. return nil, xerr.WithStack(err)
  71. }
  72. healthWarningNumber := int64(0)
  73. if err = s.DB.Model(new(model.NeckRingHealth)).
  74. Where("pasture_id = ?", userModel.AppPasture.Id).
  75. Group("cow_id").
  76. Count(&healthWarningNumber).Error; err != nil {
  77. zaplog.Error("NeckRingWarning", zap.Any("estrusWarningNumber", err))
  78. }
  79. return &pasturePb.IndexNeckRingResponse{
  80. Code: http.StatusOK,
  81. Msg: "ok",
  82. Data: &pasturePb.NeckRingData{
  83. EstrusWarningNumber: int32(countEstrusWarning),
  84. HealthWarningNumber: int32(healthWarningNumber),
  85. AbortionWarningNumber: int32(abortionCount),
  86. StressWarningNumber: 0,
  87. EstrusWarningLevelItems: estrusWarningLevelItems,
  88. OptimumMating: optimumMating,
  89. },
  90. }, nil
  91. }
  92. func (s *StoreEntry) FocusIndicatorsList(ctx context.Context, dimension string) (*pasturePb.IndexFocusIndicatorsResponse, error) {
  93. userModel, err := s.GetUserModel(ctx)
  94. if err != nil {
  95. return nil, xerr.WithStack(err)
  96. }
  97. userFocusIndicators := userModel.SystemUser.IndicatorsKinds
  98. if len(userFocusIndicators) <= 0 {
  99. userFocusIndicators = model.DefaultFocusIndicators
  100. }
  101. userFocusIndicatorsList := strings.Split(userFocusIndicators, ",")
  102. indicatorsDataList := make([]*model.IndicatorsData, 0)
  103. pref := s.DB.Model(new(model.IndicatorsData)).
  104. Where("pasture_id = ?", userModel.AppPasture.Id).
  105. Where("kind in (?)", userFocusIndicatorsList)
  106. /*if dimension == "Year" {
  107. pref.Where("date = ?", time.Now().Local().Format(model.LayoutMonth))
  108. }*/
  109. nowTime := time.Now().Local()
  110. if dimension == "Month" {
  111. pref.Where("date = ?", nowTime.Format(model.LayoutMonth))
  112. }
  113. if err = pref.Find(&indicatorsDataList).Error; err != nil {
  114. zaplog.Error("FocusIndicators", zap.Any("err", err))
  115. }
  116. indicatorsDetailsMap, _, err := s.GetIndicatorsDetailsMap(ctx)
  117. if err != nil {
  118. return nil, xerr.WithStack(err)
  119. }
  120. focusIndicatorsList := make([]*pasturePb.FocusIndicators, 0)
  121. for _, v := range indicatorsDataList {
  122. indicatorsDetails, ok := indicatorsDetailsMap[v.Kind]
  123. if !ok {
  124. continue
  125. }
  126. onYear, onMonth := "", ""
  127. isUp := pasturePb.IsShow_Ok
  128. if dimension == "Year" {
  129. return nil, xerr.Custom("暂不支持该维度")
  130. }
  131. if dimension == "Month" {
  132. lastMonth := nowTime.AddDate(0, -1, 0).Format(model.LayoutMonth)
  133. oldIndicators, _ := s.GetIndicatorsDataByDate(userModel.AppPasture.Id, v.Kind, lastMonth)
  134. if oldIndicators != nil {
  135. if oldIndicators.Value != "" && oldIndicators.Value != "0" {
  136. oldValue, _ := strconv.ParseFloat(oldIndicators.Value, 64)
  137. currValue, _ := strconv.ParseFloat(v.Value, 64)
  138. onMonthValue := (oldValue - currValue) / oldValue * 100
  139. omv := util.RoundToTwoDecimals(onMonthValue)
  140. if omv < 0 {
  141. isUp = pasturePb.IsShow_No
  142. }
  143. onMonth = strconv.FormatFloat(omv, 'f', 2, 64) + "%"
  144. }
  145. }
  146. }
  147. focusIndicatorsList = append(focusIndicatorsList, &pasturePb.FocusIndicators{
  148. Kind: indicatorsDetails.Kind,
  149. Name: indicatorsDetails.Name,
  150. Value: v.Value,
  151. Describe: indicatorsDetails.Zh,
  152. UnitName: indicatorsDetails.Unit,
  153. OnMonth: onMonth,
  154. OnYear: onYear,
  155. IsUp: isUp,
  156. })
  157. }
  158. indicatorsDetailsList, _ := s.FindIndicatorsDetailsList(ctx)
  159. return &pasturePb.IndexFocusIndicatorsResponse{
  160. Code: http.StatusOK,
  161. Msg: "ok",
  162. Data: &pasturePb.FocusData{
  163. FocusIndicators: focusIndicatorsList,
  164. IndicatorsSet: model.IndicatorsDetailsSlice(indicatorsDetailsList).ToPB(userFocusIndicatorsList),
  165. },
  166. }, err
  167. }
  168. func (s *StoreEntry) FocusIndicatorsSet(ctx context.Context, req *pasturePb.IndexFocusIndicatorsSetRequest) error {
  169. userModel, err := s.GetUserModel(ctx)
  170. if err != nil {
  171. return xerr.WithStack(err)
  172. }
  173. if len(req.IndicatorsKind) <= 0 {
  174. return nil
  175. }
  176. userFocusIndicators := strings.Join(req.IndicatorsKind, ",")
  177. if err = s.DB.Model(new(model.SystemUser)).
  178. Where("id = ?", userModel.SystemUser.Id).
  179. Update("indicators_kinds", userFocusIndicators).Error; err != nil {
  180. return xerr.WithStack(err)
  181. }
  182. return nil
  183. }
  184. func (s *StoreEntry) DataWarningSet(ctx context.Context, req *pasturePb.IndexDataWarningSetRequest) error {
  185. userModel, err := s.GetUserModel(ctx)
  186. if err != nil {
  187. return xerr.WithStack(err)
  188. }
  189. pastureId := userModel.AppPasture.Id
  190. if len(req.WarningDataSet) <= 0 {
  191. return xerr.Custom("请选择预警数据")
  192. }
  193. defaultDataWarning, _ := s.FindDataWarning(ctx, pastureId, model.DefaultUserId)
  194. if len(defaultDataWarning) <= 0 {
  195. return xerr.Custom("默认预警数据不存在,请联系管理员!")
  196. }
  197. userDataWarningList, err := s.FindDataWarning(ctx, pastureId, userModel.SystemUser.Id)
  198. if err != nil {
  199. return xerr.WithStack(err)
  200. }
  201. if len(userDataWarningList) <= 0 { // 新增
  202. return s.addUserDataWarning(ctx, pastureId, userModel.SystemUser.Id, defaultDataWarning, req.WarningDataSet)
  203. }
  204. return s.updateUserDataWarning(ctx, pastureId, userModel.SystemUser.Id, userDataWarningList, req.WarningDataSet)
  205. }
  206. func (s *StoreEntry) DataWarningList(ctx context.Context) (*pasturePb.IndexDataWarningResponse, error) {
  207. userModel, err := s.GetUserModel(ctx)
  208. if err != nil {
  209. return nil, xerr.WithStack(err)
  210. }
  211. pastureId := userModel.AppPasture.Id
  212. defaultDataWarning, _ := s.FindDataWarning(ctx, pastureId, model.DefaultUserId)
  213. if len(defaultDataWarning) <= 0 {
  214. return nil, xerr.Custom("默认预警数据有误,请联系管理员!")
  215. }
  216. var isExist bool // 判断是否存在自己的设置的数据
  217. userDataWarning, _ := s.FindDataWarning(ctx, pastureId, userModel.SystemUser.Id)
  218. if len(userDataWarning) == 0 {
  219. // 如果用户没有配置自己的预警数据,则使用默认数据
  220. isExist = true
  221. userDataWarning = defaultDataWarning
  222. }
  223. newTime := time.Now().Local().Unix()
  224. needUpdateWarningIds := make([]int64, 0)
  225. for _, warningData := range userDataWarning {
  226. // 如果预警数据更新时间大于预警条件更新时间,并且更新时间距离当前时间小于2小时,则跳过
  227. if warningData.DataUpdateAt > warningData.ConditionUpdateAt && newTime-warningData.DataUpdateAt < int64(2*time.Hour) {
  228. continue
  229. }
  230. needUpdateWarningIds = append(needUpdateWarningIds, warningData.Id)
  231. }
  232. // 需要重新计算更新的warningId
  233. if len(needUpdateWarningIds) > 0 {
  234. s.UpdateWarningData(ctx, pastureId, needUpdateWarningIds)
  235. }
  236. userDataWarningItems := make([]*model.DataWarningItems, 0)
  237. // 计算过后重新获取数据
  238. if isExist {
  239. userDataWarning, _ = s.FindDataWarning(ctx, pastureId, model.DefaultUserId)
  240. userDataWarningItems, _ = s.FindDataWarningItems(ctx, pastureId, model.DefaultUserId)
  241. } else {
  242. userDataWarning, _ = s.FindDataWarning(ctx, pastureId, userModel.SystemUser.Id)
  243. userDataWarningItems, _ = s.FindDataWarningItems(ctx, pastureId, userModel.SystemUser.Id)
  244. }
  245. return &pasturePb.IndexDataWarningResponse{
  246. Code: http.StatusOK,
  247. Msg: "ok",
  248. Data: &pasturePb.DataWarning{
  249. DataSet: model.DataWarningItemsSlice(userDataWarningItems).ToPB(userDataWarning),
  250. DataShow: model.DataWarningSlice(userDataWarning).ToPB(),
  251. },
  252. }, nil
  253. }
  254. func (s *StoreEntry) DataWarningPop(ctx context.Context, req *pasturePb.WarningDataListRequest, pagination *pasturePb.PaginationModel) (*model.WarningDataPopResponse, error) {
  255. userModel, err := s.GetUserModel(ctx)
  256. if err != nil {
  257. return nil, xerr.WithStack(err)
  258. }
  259. if req.Kind <= pasturePb.DataWarningType_Invalid {
  260. return nil, xerr.Custom("请选择预警数据")
  261. }
  262. pastureId := userModel.AppPasture.Id
  263. dataWaringItem := &model.DataWarning{}
  264. if err = s.DB.Model(new(model.DataWarning)).
  265. Where("pasture_id = ?", pastureId).
  266. Where("user_id = ?", userModel.SystemUser.Id).
  267. Where("kind = ?", req.Kind).
  268. First(dataWaringItem).Error; err != nil {
  269. if errors.Is(err, gorm.ErrRecordNotFound) {
  270. if err = s.DB.Model(new(model.DataWarning)).
  271. Where("pasture_id = ?", pastureId).
  272. Where("user_id = ?", model.DefaultUserId).
  273. Where("kind = ?", req.Kind).
  274. First(dataWaringItem).Error; err != nil {
  275. return nil, xerr.WithStack(err)
  276. }
  277. } else {
  278. return nil, xerr.Custom("预警数据不存在,请联系管理员!")
  279. }
  280. }
  281. headers, headerSort, err := dataWaringItem.GetWarningColumn()
  282. if err != nil {
  283. return nil, xerr.WithStack(err)
  284. }
  285. resp := &model.WarningDataPopResponse{
  286. Code: http.StatusOK,
  287. Msg: "ok",
  288. Data: &model.WarningPop{
  289. DataList: make([]interface{}, 0),
  290. Title: dataWaringItem.Name,
  291. Kind: dataWaringItem.Kind,
  292. HeaderSort: headerSort,
  293. Headers: headers,
  294. Page: pagination.Page,
  295. PageSize: pagination.PageSize,
  296. Total: 0,
  297. },
  298. }
  299. query, params, err := s.BuildQuery(dataWaringItem.Id)
  300. if err != nil {
  301. zaplog.Error("UpdateWarningData", zap.Any("BuildQuery", err), zap.Any("warningId", dataWaringItem.Id))
  302. return resp, nil
  303. }
  304. if len(query) == 0 || len(params) == 0 {
  305. return resp, nil
  306. }
  307. var count int64
  308. cowList := make([]*model.Cow, 0)
  309. if err = s.DB.Model(new(model.Cow)).
  310. Where("pasture_id = ?", pastureId).
  311. Where(query, params...).
  312. Count(&count).
  313. Limit(int(pagination.PageSize)).
  314. Offset(int(pagination.PageOffset)).
  315. Find(&cowList).
  316. Error; err != nil {
  317. zaplog.Error("UpdateWarningData", zap.Any("err", err), zap.Any("query", query), zap.Any("params", params))
  318. }
  319. cowTypeMap := s.CowTypeMap()
  320. breedStatusMap := s.CowBreedStatusMap()
  321. cowKindMap := s.CowKindMap()
  322. cowSourceMap := s.CowSourceMap()
  323. admissionStatusMap := s.AdmissionStatusMap()
  324. healthStatusMap := s.HealthStatusMap()
  325. purposeMap := s.PurposeMap()
  326. resp.Data.Total = int32(count)
  327. systemBasic, err := s.GetSystemBasicByName(ctx, userModel.AppPasture.Id, model.PregnancyAge)
  328. if err != nil {
  329. return nil, xerr.Custom("请在基础参数配置妊娠天数")
  330. }
  331. resp.Data.DataList = model.CowSlice(cowList).ToPB(
  332. cowTypeMap, breedStatusMap, cowKindMap,
  333. cowSourceMap, admissionStatusMap, healthStatusMap,
  334. purposeMap, systemBasic.MinValue,
  335. )
  336. return resp, nil
  337. }
  338. // 新增用户预警数据
  339. func (s *StoreEntry) addUserDataWarning(ctx context.Context, pastureId, userId int64, defaultDataWarning []*model.DataWarning, warningDataSet []*pasturePb.WarningDataSet) error {
  340. // 将默认预警数据按 Kind 映射
  341. defaultDataWarningMap := make(map[pasturePb.DataWarningType_Kind]*model.DataWarning)
  342. for _, v := range defaultDataWarning {
  343. defaultDataWarningMap[v.Kind] = v
  344. }
  345. // 在事务中执行新增操作
  346. return s.DB.Transaction(func(tx *gorm.DB) error {
  347. addedKinds := make(map[pasturePb.DataWarningType_Kind]bool) // 记录已添加的 Kind
  348. for _, set := range warningDataSet {
  349. dataWarning := model.NewDataWarning(pastureId, userId, set.Kind, pasturePb.IsShow_Ok, defaultDataWarningMap[set.Kind])
  350. // 如果该 Kind 已添加,跳过
  351. if !addedKinds[set.Kind] {
  352. // 创建新的预警数据
  353. if err := tx.Create(dataWarning).Error; err != nil {
  354. return xerr.WithStack(err)
  355. }
  356. } else {
  357. oldDataWarning := &model.DataWarning{}
  358. if err := tx.Model(new(model.DataWarning)).
  359. Where("user_id = ?", userId).
  360. Where("kind = ?", set.Kind).
  361. First(oldDataWarning).Error; err != nil {
  362. return xerr.WithStack(err)
  363. }
  364. dataWarning.Id = oldDataWarning.Id
  365. }
  366. // 创建预警项数据
  367. if err := tx.Create(model.NewDataWarningItems(pastureId, userId, dataWarning, set)).Error; err != nil {
  368. return xerr.WithStack(err)
  369. }
  370. addedKinds[set.Kind] = true
  371. }
  372. return nil
  373. })
  374. }
  375. // 更新用户预警数据
  376. func (s *StoreEntry) updateUserDataWarning(ctx context.Context, pastureId, userId int64, userDataWarningList []*model.DataWarning, warningDataSet []*pasturePb.WarningDataSet) error {
  377. // 将请求数据按 WarningId 和 Id 映射
  378. warningIsShowMap := make(map[int32]*pasturePb.WarningDataSet)
  379. warningItemDataMap := make(map[int32]*pasturePb.WarningDataSet)
  380. for _, set := range warningDataSet {
  381. warningIsShowMap[set.WarningId] = set
  382. warningItemDataMap[set.Id] = set
  383. }
  384. // 获取用户预警项数据
  385. userDataWarningItems, err := s.FindDataWarningItems(ctx, pastureId, userId)
  386. if err != nil {
  387. return xerr.WithStack(err)
  388. }
  389. if len(userDataWarningItems) == 0 {
  390. return xerr.Custom("预警数据有误,请联系管理员!")
  391. }
  392. // 在事务中执行更新操作
  393. return s.DB.Transaction(func(tx *gorm.DB) error {
  394. // 更新预警数据的 IsShow 字段
  395. for _, warning := range userDataWarningList {
  396. if data, ok := warningIsShowMap[int32(warning.Id)]; ok {
  397. if strings.ContainsAny(warning.Name, "0123456789") {
  398. re := regexp.MustCompile(`\d+`)
  399. warning.Name = re.ReplaceAllString(warning.Name, data.Value)
  400. warning.Description = re.ReplaceAllString(warning.Description, data.Value)
  401. }
  402. if err = tx.Model(&model.DataWarning{}).
  403. Where("id = ?", warning.Id).
  404. Updates(map[string]interface{}{
  405. "is_show": data.IsShow,
  406. "name": warning.Name,
  407. "description": warning.Description,
  408. }).Error; err != nil {
  409. return xerr.WithStack(err)
  410. }
  411. }
  412. }
  413. // 更新预警项数据的 IsShow 和 Value 字段
  414. for _, item := range userDataWarningItems {
  415. if set, ok := warningItemDataMap[int32(item.Id)]; ok {
  416. if err = tx.Model(&model.DataWarningItems{}).
  417. Where("id = ?", item.Id).
  418. Updates(map[string]interface{}{
  419. "is_show": set.IsShow,
  420. "value": set.Value,
  421. }).Error; err != nil {
  422. return xerr.WithStack(err)
  423. }
  424. }
  425. }
  426. return nil
  427. })
  428. }
  429. func (s *StoreEntry) FindDataWarning(ctx context.Context, pastureId, userId int64) ([]*model.DataWarning, error) {
  430. dataWarningList := make([]*model.DataWarning, 0)
  431. if err := s.DB.Model(new(model.DataWarning)).
  432. Where("user_id = ?", userId).
  433. Where("pasture_id = ?", pastureId).
  434. Find(&dataWarningList).Error; err != nil {
  435. return nil, xerr.WithStack(err)
  436. }
  437. return dataWarningList, nil
  438. }
  439. func (s *StoreEntry) FindDataWarningItems(ctx context.Context, pastureId, userId int64) ([]*model.DataWarningItems, error) {
  440. dataWarningItemsList := make([]*model.DataWarningItems, 0)
  441. if err := s.DB.Model(new(model.DataWarningItems)).
  442. Where("pasture_id = ?", pastureId).
  443. Where("user_id = ?", userId).
  444. Find(&dataWarningItemsList).Error; err != nil {
  445. return nil, xerr.WithStack(err)
  446. }
  447. return dataWarningItemsList, nil
  448. }
  449. func (s *StoreEntry) FindDataWarningMap(ctx context.Context, pastureId, userId int64) (map[int64]*model.DataWarning, error) {
  450. dataWarning, err := s.FindDataWarning(ctx, pastureId, userId)
  451. if err != nil {
  452. return nil, xerr.Custom("默认预警数据有误,请联系管理员!")
  453. }
  454. dataWarningMap := make(map[int64]*model.DataWarning)
  455. for _, v := range dataWarning {
  456. dataWarningMap[v.Id] = v
  457. }
  458. return dataWarningMap, nil
  459. }
  460. func (s *StoreEntry) FindDataWarningItemsMap(ctx context.Context, userId int64) (map[int64]*model.DataWarningItems, error) {
  461. dataWarningItemsList := make([]*model.DataWarningItems, 0)
  462. if err := s.DB.Model(new(model.DataWarningItems)).
  463. Where("user_id = ?", userId).
  464. Find(&dataWarningItemsList).Error; err != nil {
  465. return nil, xerr.WithStack(err)
  466. }
  467. dataWarningItemsMap := make(map[int64]*model.DataWarningItems)
  468. for _, v := range dataWarningItemsList {
  469. dataWarningItemsMap[v.Id] = v
  470. }
  471. return dataWarningItemsMap, nil
  472. }
  473. // UpdateWarningData 更新计算数据
  474. func (s *StoreEntry) UpdateWarningData(ctx context.Context, pastureId int64, needUpdateWarningIds []int64) {
  475. if len(needUpdateWarningIds) <= 0 {
  476. return
  477. }
  478. for _, warningId := range needUpdateWarningIds {
  479. query, params, err := s.BuildQuery(warningId)
  480. if err != nil {
  481. zaplog.Error("UpdateWarningData", zap.Any("BuildQuery", err), zap.Any("warningId", warningId))
  482. }
  483. if len(query) == 0 || len(params) == 0 {
  484. continue
  485. }
  486. var count int64
  487. if err = s.DB.Model(new(model.Cow)).
  488. Where("pasture_id = ?", pastureId).
  489. Where(query, params...).
  490. Count(&count).Error; err != nil {
  491. zaplog.Error("UpdateWarningData", zap.Any("err", err), zap.Any("query", query), zap.Any("params", params))
  492. }
  493. if err = s.DB.Model(new(model.DataWarning)).
  494. Where("id = ?", warningId).
  495. Updates(map[string]interface{}{
  496. "data_value": count,
  497. "data_update_at": time.Now().Local().Unix(),
  498. }).Error; err != nil {
  499. zaplog.Error("UpdateWarningData", zap.Any("update", err))
  500. }
  501. }
  502. }