neck_ring.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. package crontab
  2. import (
  3. "fmt"
  4. "kpt-pasture/model"
  5. "math"
  6. "time"
  7. "gorm.io/gorm"
  8. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  9. "gitee.com/xuyiping_admin/pkg/xerr"
  10. )
  11. const (
  12. DefaultLimit = 10000
  13. MinChangeFilter = -99
  14. MinRuminaFilter = -99
  15. MinChewFilter = -99
  16. MinChangeHigh = -99
  17. DefaultNb = 30
  18. )
  19. // NeckRingOriginalMergeData 把脖环数据合并成2个小时的
  20. func (e *Entry) NeckRingOriginalMergeData() error {
  21. // 先看看上次任务有没有执行结束,结束在执行下面的任务
  22. if ok := e.IsExistCrontabLog(NeckRingOriginal); ok {
  23. return nil
  24. }
  25. e.CreateCrontabLog(NeckRingOriginal)
  26. defer func() {
  27. e.DeleteCrontabLog(NeckRingOriginal)
  28. }()
  29. limit := e.Cfg.NeckRingLimit
  30. if limit <= 0 {
  31. limit = DefaultLimit
  32. }
  33. neckRingList := make([]*model.NeckRingOriginal, 0)
  34. if err := e.DB.Model(new(model.NeckRingOriginal)).
  35. Where("is_show = ?", pasturePb.IsShow_No).
  36. Limit(int(limit)).
  37. Find(&neckRingList).Error; err != nil {
  38. return xerr.WithStack(err)
  39. }
  40. if len(neckRingList) <= 0 {
  41. return nil
  42. }
  43. neckRingIds := make([]int64, 0)
  44. originalMapData := make(map[string]*model.NeckRingOriginalMerge)
  45. // 合并成2个小时的
  46. for _, v := range neckRingList {
  47. neckRingIds = append(neckRingIds, v.Id)
  48. xframeId := int(math.Floor(float64(v.FrameId)/10) * 2)
  49. mapKey := fmt.Sprintf("%s%s%s%s%d", v.Imei, model.JoinKey, v.ActiveDate, model.JoinKey, xframeId) // 0001/2023-12-04/0 0001/2023-12-03/4
  50. if _, ok := originalMapData[mapKey]; !ok {
  51. originalMapData[mapKey] = new(model.NeckRingOriginalMerge)
  52. }
  53. v.IsAvgHours()
  54. originalMapData[mapKey].IsMageData(v)
  55. }
  56. // 算平均值
  57. for _, v := range originalMapData {
  58. v.SumAvg()
  59. }
  60. weeklyActive := &model.SystemConfigure{}
  61. if err := e.DB.Model(new(model.SystemConfigure)).
  62. Where("name = ?", model.WeeklyActive).
  63. Where("is_show = ?", pasturePb.IsShow_Ok).
  64. First(weeklyActive).Error; err != nil {
  65. return xerr.WithStack(err)
  66. }
  67. // 更新脖环牛只相关信息
  68. newNeckActiveHabitList := model.NeckRingOriginalMap(originalMapData).ForMatData(weeklyActive.Value, e.GetCowInfoByImei)
  69. if err := e.DB.Transaction(func(tx *gorm.DB) error {
  70. // 更新已处理过的id
  71. if len(neckRingIds) > 0 {
  72. if err := tx.Model(new(model.NeckRingOriginal)).
  73. Where("id IN ?", neckRingIds).
  74. Update("is_show", pasturePb.IsShow_Ok).
  75. Error; err != nil {
  76. return xerr.WithStack(err)
  77. }
  78. }
  79. for _, neckActiveHabit := range newNeckActiveHabitList {
  80. // 新数据直接插入
  81. if e.IsExistNeckActiveHabit(neckActiveHabit.NeckRingNumber, neckActiveHabit.Frameid) <= 0 {
  82. if err := tx.Create(neckActiveHabit).Error; err != nil {
  83. return xerr.WithStack(err)
  84. }
  85. continue
  86. }
  87. // 更新数据
  88. historyNeckActiveHabit := e.GetNeckActiveHabit(neckActiveHabit.NeckRingNumber, neckActiveHabit.Frameid)
  89. historyNeckActiveHabit.MergeData(neckActiveHabit)
  90. if err := tx.Model(new(model.NeckActiveHabit)).
  91. Select("rumina", "rumina", "intake", "gasp", "other", "high", "active").
  92. Where("id = ?", historyNeckActiveHabit.Id).
  93. Updates(historyNeckActiveHabit).Error; err != nil {
  94. return xerr.WithStack(err)
  95. }
  96. }
  97. return nil
  98. }); err != nil {
  99. return xerr.WithStack(err)
  100. }
  101. return nil
  102. }
  103. func (e *Entry) ActiveHabit() error {
  104. lastMaxHabitId := e.GetSystemConfigure(model.MaxHabit).Value
  105. currentMaxHabit := &model.NeckActiveHabit{}
  106. if err := e.DB.Model(new(model.NeckActiveHabit)).
  107. Order("id desc").First(currentMaxHabit).Error; err != nil {
  108. return xerr.WithStack(err)
  109. }
  110. // 本次执行<=上次执行的id,则不执行
  111. if currentMaxHabit.Id < int64(lastMaxHabitId) {
  112. return nil
  113. }
  114. // 统一更新is_max_time为0
  115. if err := e.DB.Model(new(model.NeckActiveHabit)).
  116. Where("is_max_time = ?", pasturePb.IsShow_Ok).
  117. Update("is_max_time", pasturePb.IsShow_No).Error; err != nil {
  118. return xerr.WithStack(err)
  119. }
  120. // 获取这段执行数据内最大日期和最小日期
  121. xToday := &XToday{}
  122. if err := e.DB.Model(new(model.NeckActiveHabit)).
  123. Select(`MIN(h.heat_date) as x_beg_date, MAX(h.heat_date) as x_end_date`).
  124. Where("id BETWEEN ? AND ?", lastMaxHabitId, currentMaxHabit).
  125. First(xToday).Error; err != nil {
  126. return xerr.WithStack(err)
  127. }
  128. xToday.LastMaxHabitId = int64(lastMaxHabitId)
  129. xToday.CurrMaxHabitId = currentMaxHabit.Id
  130. minHeatDateParse, err := time.Parse(model.LayoutDate2, xToday.XBegDate)
  131. if err != nil {
  132. return xerr.WithStack(err)
  133. }
  134. xBefore2Day := minHeatDateParse.AddDate(0, 0, -1).Format(model.LayoutDate2)
  135. xBefore7Day := minHeatDateParse.AddDate(0, 0, -7).Format(model.LayoutDate2)
  136. xMin2Id, err := e.GetMinIdByHeatDate(xBefore2Day, xToday.LastMaxHabitId)
  137. if err != nil {
  138. return xerr.WithStack(err)
  139. }
  140. xMin7Id, err := e.GetMinIdByHeatDate(xBefore7Day, xToday.LastMaxHabitId)
  141. if err != nil {
  142. return xerr.WithStack(err)
  143. }
  144. xToday.XMin2Id = xMin2Id
  145. xToday.XMin7Id = xMin7Id
  146. // id到上一次执行结果并且heat_date > 7天之前的最大牛只id置为is_max_time=1
  147. sqlQuery := e.DB.Model(new(model.NeckActiveHabit)).
  148. Select("MAX(id) as id").
  149. Where("id BETWEEN ? AND ?", xToday.XMin2Id, xToday.LastMaxHabitId).
  150. Where("change_filter > ?", MinChangeFilter).
  151. Where("heat_date >", xBefore7Day).
  152. Group("cow_id")
  153. if err = e.DB.Model(new(model.NeckActiveHabit)).
  154. Joins("JOIN (?) bb ON neck_active_habit.id = bb.id", sqlQuery).
  155. Update("is_max_time", pasturePb.IsShow_Ok).Error; err != nil {
  156. return xerr.WithStack(err)
  157. }
  158. activeLowest := e.GetSystemConfigure(model.ActiveLowest)
  159. ruminaLowest := e.GetSystemConfigure(model.RuminaLowest)
  160. xToday.ActiveLowest = int64(activeLowest.Value)
  161. xToday.RuminaLowest = int64(ruminaLowest.Value)
  162. // 更新活动滤波
  163. if err = e.FilterUpdate(xToday); err != nil {
  164. return xerr.WithStack(err)
  165. }
  166. // 更新周平均值
  167. if err = e.WeeklyActiveAvgUpdate(xToday); err != nil {
  168. return xerr.WithStack(err)
  169. }
  170. // 更新最后一次执行的id值
  171. if err = e.DB.Model(new(model.SystemConfigure)).
  172. Where("name = ?", model.MaxHabit).
  173. Update("value = ?", xToday.CurrMaxHabitId+1).
  174. Error; err != nil {
  175. return xerr.WithStack(err)
  176. }
  177. return nil
  178. }
  179. // FilterUpdate 更新活动滤波
  180. func (e *Entry) FilterUpdate(xToDay *XToday) error {
  181. newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
  182. if err := e.DB.Model(new(model.NeckActiveHabit)).
  183. Where(e.DB.Where("change_filter = ?", model.DefaultChangeFilter).Or("is_max_time = ?", pasturePb.IsShow_Ok)).
  184. Where(e.DB.Where("high >= ?", xToDay.ActiveLowest).Or("rumina >= ?", xToDay.RuminaLowest)).
  185. Order("cow_id,id").
  186. Find(&newNeckActiveHabitList).Error; err != nil {
  187. return xerr.WithStack(err)
  188. }
  189. var filterValues = make(map[int64]*model.NeckActiveHabit)
  190. // 活动量滤波
  191. for _, v := range newNeckActiveHabitList {
  192. prev, ok := filterValues[v.CowId]
  193. if !ok {
  194. if v.FilterHigh <= 0 {
  195. v.FilterHigh = v.High
  196. }
  197. if v.FilterRumina <= 0 {
  198. v.FilterRumina = v.Rumina
  199. }
  200. if v.FilterChew <= 0 {
  201. v.FilterChew = v.Rumina + v.Intake
  202. }
  203. filterValues[v.CowId] = v
  204. continue
  205. }
  206. if v.FilterHigh <= 0 {
  207. v.FilterHigh = int32(computeIfPositiveElse(float64(v.High), float64(prev.FilterHigh), 0.23, 0.77))
  208. }
  209. if v.FilterRumina <= 0 {
  210. v.FilterRumina = int32(computeIfPositiveElse(float64(v.Rumina), float64(prev.FilterRumina), 0.33, 0.67))
  211. }
  212. if v.FilterChew <= 0 {
  213. v.FilterChew = int32(computeIfPositiveElse(float64(v.Rumina+v.Intake), float64(prev.FilterChew), 0.33, 0.67))
  214. }
  215. // 更新过滤值
  216. filterValues[v.CowId] = v
  217. if err := e.DB.Model(new(model.NeckActiveHabit)).
  218. Select("filter_high", "filter_rumina", "filter_chew").
  219. Where("id = ?", v.Id).
  220. Updates(v).Error; err != nil {
  221. return xerr.WithStack(err)
  222. }
  223. }
  224. return nil
  225. }
  226. func (e *Entry) WeeklyActiveAvgUpdate(xToday *XToday) error {
  227. beginDayDate, err := time.Parse(model.LayoutDate2, xToday.XBegDate)
  228. if err != nil {
  229. return xerr.WithStack(err)
  230. }
  231. before7DayDate := beginDayDate.AddDate(0, 0, -7).Format(model.LayoutDate2)
  232. before1DayDate := beginDayDate.AddDate(0, 0, -1).Format(model.LayoutDate2)
  233. weeklyActive := e.GetSystemConfigure(model.WeeklyActive)
  234. xframeId := int64(0)
  235. maxXframeId := int64(11)
  236. xStartDate, _ := time.Parse(model.LayoutDate2, xToday.XBegDate)
  237. xEndDate, _ := time.Parse(model.LayoutDate2, xToday.XEndDate)
  238. for xStartDate.Format(model.LayoutDate2) < xEndDate.Format(model.LayoutDate2) || (xStartDate == xEndDate && xframeId <= maxXframeId) {
  239. // 时间点周平均
  240. AvgHabitList := make([]*AvgHabit, 0)
  241. if err = e.DB.Model(new(model.NeckActiveHabit)).
  242. Select("cow_id").
  243. Select("IF(COUNT(1)>=3, ROUND((SUM(filter_high) -MIN(filter_high) -MAX(filter_high))/ABS(COUNT(1) -2),0), -1) as avg_high_habit").
  244. Select("IF(COUNT(1)>=3, ROUND((SUM(filter_rumina) -MIN(filter_rumina) -MAX(filter_rumina))/ABS(COUNT(1) -2),0), -1) as avg_rumina_habit").
  245. Select("IF(COUNT(1)>=3, ROUND((SUM(filter_chew) -MIN(filter_chew) -MAX(filter_chew))/ABS(COUNT(1) -2),0), -1) as avg_chew_habit").
  246. Select("ROUND(AVG(intake),0) as avg_intake_habit").
  247. Select("ROUND(AVG(inactive),0) as avg_inactive_habit").
  248. Where("id BETWEEN ? AND ?", xToday.XMin7Id, xToday.CurrMaxHabitId).
  249. Where("heat_date BETWEEN ? AND ?", before7DayDate, before1DayDate).
  250. Where("frameid = ?", xframeId).
  251. Where("change_filter = ?", model.DefaultChangeFilter).
  252. Where(e.DB.Where("high > ?", xToday.ActiveLowest).Or("rumina > ?", xToday.RuminaLowest)).
  253. Group("cow_id").
  254. Find(&AvgHabitList).Error; err != nil {
  255. return xerr.WithStack(err)
  256. }
  257. for _, v := range AvgHabitList {
  258. if err := e.DB.Model(new(model.NeckActiveHabit)).
  259. Select("week_avg_high_habit", "avg_rumina_habit", "avg_chew_habit", "avg_intake_habit", "avg_inactive_habit").
  260. Where("cow_id = ?", v.CowId).
  261. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  262. Where("frameid = ?", xframeId).
  263. Where("change_filter = ?", model.DefaultChangeFilter).
  264. Where("heat_date = ?", xStartDate).
  265. Updates(v).Error; err != nil {
  266. return xerr.WithStack(err)
  267. }
  268. }
  269. // 累计24小时数值
  270. sumHabitList := make([]*SumHabit, 0)
  271. if err = e.DB.Model(new(model.NeckActiveHabit)).
  272. Select("cow_id").
  273. Select("IF(COUNT(1)>6, ROUND(AVG( h2.filter_rumina)*12,0), 0) as sum_rumina").
  274. Select("IF(COUNT(1)>6, ROUND(AVG( h2.intake)*12,0), 0) as sum_intake").
  275. Select("IF(COUNT(1)>6, ROUND(AVG( h2.inactive)*12,0), 0) as sum_inactive").
  276. Select("IF(COUNT(1)>6, ROUND(AVG( h2.active)*12,0), 0) as sum_active").
  277. Select("MAX(h2.change_filter) as sum_max_high").
  278. Select("MIN(IF(change_filter > ?, change_filter, 0)) as sum_min_high", MinChangeFilter).
  279. Select("MIN( CASE WHEN filter_chew > ? THEN filter_chew WHEN filter_rumina >= ? THEN filter_rumina ELSE 0 END) as sum_min_chew", MinChangeFilter, MinRuminaFilter).
  280. Where("id BETWEEN ? AND ?", xToday.XMin2Id, xToday.CurrMaxHabitId).
  281. Where("heat_date BETWEEN ? AND ?", xStartDate.AddDate(0, 0, -1).Format(model.LayoutDate2), xStartDate.Format(model.LayoutDate2)).
  282. Where("created_at BETWEEN ? AND ?", xStartDate.Add(-23*time.Hour).Unix(), xStartDate.Unix()).
  283. Where(e.DB.Where("high > ?", xToday.ActiveLowest).Or("rumina >= ?", xToday.RuminaLowest)).
  284. Group("cow_id").
  285. Find(&sumHabitList).Error; err != nil {
  286. return xerr.WithStack(err)
  287. }
  288. for _, v := range sumHabitList {
  289. if err = e.DB.Model(new(model.NeckActiveHabit)).
  290. Select("sum_rumina", "sum_intake", "sum_inactive", "sum_active", "sum_max_high", "sum_min_high", "sum_min_chew").
  291. Where("cow_id = ?", v.CowId).
  292. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  293. Where("heat_date = ?", xStartDate.Format(model.LayoutDate2)).
  294. Where("frameid = ?", xframeId).
  295. Where("change_filter = ?", model.DefaultChangeFilter).
  296. Updates(v).Error; err != nil {
  297. return xerr.WithStack(err)
  298. }
  299. }
  300. // 变化百分比
  301. changeHabitList := make([]*model.NeckActiveHabit, 0)
  302. if err = e.DB.Model(new(model.NeckActiveHabit)).
  303. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  304. Where("heat_date = ?", xStartDate.Format(model.LayoutDate2)).
  305. Where("frameid = ?", xframeId).
  306. Where("change_filter = ?", model.DefaultChangeFilter).
  307. Where("week_avg_high_habit > ?", 0).
  308. Where(e.DB.Where("high > ?", xToday.ActiveLowest).Or("rumina >= ?", xToday.RuminaLowest)).
  309. Find(&changeHabitList).Error; err != nil {
  310. return xerr.WithStack(err)
  311. }
  312. for _, v := range changeHabitList {
  313. if v.FilterHigh-v.AvgHighHabit > 0 {
  314. v.ChangeHigh = (v.FilterHigh - v.AvgHighHabit) / int32(float64(v.WeekHigh)*0.6+float64(v.AvgHighHabit)*0.2+float64(weeklyActive.Value)*0.2)
  315. } else {
  316. v.ChangeHigh = v.FilterHigh - v.AvgHighHabit/v.AvgHighHabit*100
  317. }
  318. v.ChangeRumina = v.RuminaFilter - v.AvgRuminaHabit/v.AvgHighHabit*100
  319. v.ChangeChew = v.FilterChew - v.AvgChewHabit/v.AvgHighHabit*100
  320. if err = e.DB.Model(new(model.NeckActiveHabit)).
  321. Select("change_high", "change_rumina", "change_chew").
  322. Where("id = ?", v.Id).
  323. Updates(v).Error; err != nil {
  324. return xerr.WithStack(err)
  325. }
  326. }
  327. if xframeId == maxXframeId {
  328. xframeId = 0
  329. xStartDate = xStartDate.AddDate(0, 0, 1)
  330. } else {
  331. xframeId++
  332. }
  333. }
  334. return nil
  335. }
  336. // UpdateChangeFilter 变化趋势滤波
  337. func (e *Entry) UpdateChangeFilter(xToday *XToday) error {
  338. xRuminaDisc := e.GetSystemConfigure(model.XRuminaDisc)
  339. xChangeDiscount := e.GetSystemConfigure(model.XChangeDiscount)
  340. newChangeFilterList := make([]*ChangeFilterData, 0)
  341. if err := e.DB.Model(new(model.NeckActiveHabit)).
  342. Select("id,cow_id,change_high,change_filter,rumina_filter,change_rumina,chew_filter,change_chew").
  343. Select("IF(lact=0,0.8,1) as xlc_dis_count").
  344. Where("id BETWEEN ? AND ?", xToday.XMin2Id, xToday.CurrMaxHabitId).
  345. Where(e.DB.Where("change_filter = ?", model.DefaultChangeFilter).Or("is_max_time = ?", pasturePb.IsShow_Ok)).
  346. Where("change_high > ?", MinChangeHigh).
  347. Order("cow_id,heat_date,frameid").
  348. Find(&newChangeFilterList).Error; err != nil {
  349. return xerr.WithStack(err)
  350. }
  351. var filterValues = make(map[int64]*ChangeFilterData)
  352. for _, v := range newChangeFilterList {
  353. prev, ok := filterValues[v.CowId]
  354. if v.ChangeFilter <= MinChangeFilter {
  355. prefChangeFilter := int32(0)
  356. if ok {
  357. prefChangeFilter = prev.ChangeFilter
  358. }
  359. leastValue := v.HighChange
  360. if prefChangeFilter < v.HighChange {
  361. leastValue = prefChangeFilter
  362. }
  363. v.ChangeFilter = int32(float64(prefChangeFilter)*(1-(float64(xChangeDiscount.Value)/10)*v.XlcDisCount) +
  364. float64(leastValue)*(float64(xChangeDiscount.Value)/10)*v.XlcDisCount)
  365. }
  366. if v.RuminaFilter <= MinChangeFilter {
  367. prefRuminaFilter := int32(0)
  368. if ok {
  369. prefRuminaFilter = prev.RuminaFilter
  370. }
  371. factor := float64(1)
  372. if math.Abs(float64(v.ChangeRumina)) > 60 {
  373. factor = 0.5
  374. }
  375. v.RuminaFilter = int32(float64(prefRuminaFilter)*(1-float64(xRuminaDisc.Value/10)*v.XlcDisCount*factor) +
  376. float64(v.ChangeRumina)*float64(xRuminaDisc.Value)/10*v.XlcDisCount*factor)
  377. }
  378. if v.RuminaFilter > 50 {
  379. v.RuminaFilter = 50
  380. }
  381. if v.ChewFilter <= MinChangeFilter {
  382. prefChewFilter := int32(0)
  383. if ok {
  384. prefChewFilter = prev.ChewFilter
  385. }
  386. factor := float64(1)
  387. if math.Abs(float64(v.ChangeChew)) > 60 {
  388. factor = 0.5
  389. }
  390. v.ChewFilter = int32(float64(prefChewFilter)*(1-float64(xRuminaDisc.Value)/10*factor) +
  391. float64(v.ChangeChew)*float64(xRuminaDisc.Value)/10*factor)
  392. }
  393. if v.ChewFilter > 50 {
  394. v.ChangeChew = 50
  395. }
  396. if err := e.DB.Model(new(model.NeckActiveHabit)).
  397. Select("change_filter", "rumina_filter", "chew_filter").
  398. Where("id = ?", v.Id).
  399. Where("cow_id = ?", v.CowId).
  400. Where("change_filter = ?", model.DefaultChangeFilter).
  401. Updates(v).Error; err != nil {
  402. return xerr.WithStack(err)
  403. }
  404. filterValues[v.CowId] = v
  405. }
  406. return nil
  407. }
  408. // ActivityVolumeChanges 计算活动量变化趋势校正值(活跃度校正)
  409. func (e *Entry) ActivityVolumeChanges(xToday *XToday) error {
  410. currDate, _ := time.Parse(model.LayoutDate2, xToday.XBegDate)
  411. XEndDateTime, _ := time.Parse(model.LayoutDate2, xToday.XEndDate)
  412. xframeId := int64(0)
  413. maxXframeId := int64(11)
  414. dayTimes := int64(1)
  415. for currDate.Format(model.LayoutDate2) < XEndDateTime.Format(model.LayoutDate2) || (currDate == XEndDateTime && xframeId <= maxXframeId) {
  416. activityVolumeList := make([]*ActivityVolume, 0)
  417. activeTime := fmt.Sprintf("%s %02d:00:00", currDate.Format(model.LayoutDate2), xframeId*2)
  418. activeTimeParse, err := time.Parse(model.LayoutTime, activeTime)
  419. if err != nil {
  420. return xerr.WithStack(err)
  421. }
  422. if dayTimes == 1 {
  423. if err = e.DB.Model(new(model.NeckActiveHabit)).
  424. Select("cow_id").
  425. Select("AVG(IF(change_filter>=60, 60, change_filter)) as avg_filter").
  426. Select("ROUND(STD(IF(change_filter>=60, 60, change_filter))) as std_filter").
  427. Select("COUNT(1) as nb").
  428. Where("id BETWEEN ? AND ?", xToday.XMin7Id, xToday.CurrMaxHabitId).
  429. Where("heat_date BETWEEN ? AND ?", currDate.AddDate(0, 0, -7).Format(model.LayoutDate2), currDate.AddDate(0, 0, -1).Format(model.LayoutDate2)).
  430. Where("frameid = ?", xframeId).
  431. Where(e.DB.Where("high > ?", xToday.ActiveLowest).Or("rumina >= ?", xToday.RuminaLowest)).
  432. Where("active_time <= ?", activeTimeParse.Add(-12*time.Hour)).
  433. Where("change_filter > ?", MinChangeFilter).
  434. Having("nb > ?", DefaultNb).
  435. Group("cow_id").
  436. Find(&activityVolumeList).Error; err != nil {
  437. return xerr.WithStack(err)
  438. }
  439. }
  440. for _, v := range activityVolumeList {
  441. filterCorrect := model.DefaultFilterCorrect - int(math.Floor(float64(v.AvgFilter)/3+float64(v.StdFilter)/2))
  442. if err = e.DB.Model(new(model.NeckActiveHabit)).
  443. Where("cow_id = ?", v.CowId).
  444. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  445. Where("frameid = ?", xframeId).
  446. Where("head_date = ?", currDate.Format(model.LayoutDate2)).
  447. Update("filter_correct", filterCorrect).Error; err != nil {
  448. return xerr.WithStack(err)
  449. }
  450. }
  451. /*n := 0
  452. if n <= 10 {
  453. // todo
  454. n += 2
  455. }*/
  456. if err = e.DB.Model(new(model.NeckActiveHabit)).
  457. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  458. Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
  459. Where("frameid = ?", xframeId).
  460. Where("change_filter = ?", model.DefaultChangeFilter).
  461. Update("change_filter", MinChangeFilter).Error; err != nil {
  462. return xerr.WithStack(err)
  463. }
  464. if err = e.DB.Model(new(model.NeckActiveHabit)).
  465. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  466. Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
  467. Where("frameid = ?", xframeId).
  468. Where("rumina_filter = ?", model.DefaultRuminaFilter).
  469. Update("rumina_filter", MinRuminaFilter).Error; err != nil {
  470. return xerr.WithStack(err)
  471. }
  472. if err = e.DB.Model(new(model.NeckActiveHabit)).
  473. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  474. Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
  475. Where("frameid = ?", xframeId).
  476. Where("chew_filter = ?", model.DefaultChewFilter).
  477. Update("chew_filter", MinChewFilter).Error; err != nil {
  478. return xerr.WithStack(err)
  479. }
  480. if err = e.DB.Model(new(model.NeckActiveHabit)).
  481. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  482. Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
  483. Where("frameid = ?", xframeId).
  484. Where("filter_correct < ?", model.DefaultFilterCorrect).
  485. Where("change_filter < ?", 0).
  486. Update("filter_correct", model.DefaultFilterCorrect).Error; err != nil {
  487. return xerr.WithStack(err)
  488. }
  489. // 更新评分
  490. newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
  491. if err = e.DB.Model(new(model.NeckActiveHabit)).
  492. Where("id BETWEEN ? AND ?", xToday.LastMaxHabitId, xToday.CurrMaxHabitId).
  493. Where("heat_date = ?", currDate.Format(model.LayoutDate2)).
  494. Where("frameid = ?", xframeId).
  495. Where("score = ?", 0).
  496. Find(&newNeckActiveHabitList).Error; err != nil {
  497. return xerr.WithStack(err)
  498. }
  499. // todo 待开发
  500. }
  501. return nil
  502. }
  503. // 辅助函数来计算过滤值
  504. func computeIfPositiveElse(newValue, prevFilterValue float64, weightPrev, weightNew float64) float64 {
  505. return math.Ceil((prevFilterValue * weightPrev) + (weightNew * newValue))
  506. }