milk_original_update.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. package crontab
  2. import (
  3. "fmt"
  4. "kpt-pasture/model"
  5. "kpt-pasture/util"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  10. "go.uber.org/zap"
  11. )
  12. func (e *Entry) UpdateMilkOriginal() error {
  13. pastureList := e.FindPastureList()
  14. if pastureList == nil || len(pastureList) == 0 {
  15. return nil
  16. }
  17. for _, pasture := range pastureList {
  18. e.ProcessMilkOriginal(pasture.Id)
  19. }
  20. return nil
  21. }
  22. func (e *Entry) ProcessMilkOriginal(pastureId int64) {
  23. milkConfigList, err := e.FindMilkConfigure(pastureId)
  24. if err != nil {
  25. zaplog.Error("MilkOriginal", zap.Any("pastureId", pastureId), zap.Any("err", err))
  26. return
  27. }
  28. shifts := make([]int32, 0)
  29. milkClassConfig := &MilkClassConfig{}
  30. for _, v := range milkConfigList {
  31. switch v.Name {
  32. case model.FirstClassMilkTime:
  33. milkClassConfig.FirstClassMilkTime = v.Value
  34. shifts = append(shifts, 1)
  35. case model.SecondClassMilkTime:
  36. milkClassConfig.SecondClassMilkTime = v.Value
  37. shifts = append(shifts, 2)
  38. case model.ThirdClassMilkTime:
  39. milkClassConfig.ThirdClassMilkTime = v.Value
  40. shifts = append(shifts, 3)
  41. case model.FourthClassMilkTime:
  42. milkClassConfig.FourthClassMilkTime = v.Value
  43. shifts = append(shifts, 4)
  44. case model.UpdateMilkOriginalMaxId:
  45. maxId, _ := strconv.ParseInt(v.Value, 10, 64)
  46. milkClassConfig.OldUpdateMaxId = maxId
  47. }
  48. }
  49. xDBeg, xBeg1, xBeg2, xBeg3, xBeg4 := parseXBeg(milkClassConfig)
  50. e.UpdateShifts(pastureId, xBeg1, xBeg2, xBeg3, xBeg4)
  51. e.UpdateMilkDate(pastureId, xDBeg)
  52. // 获取当前最大Id
  53. var currentMaxId int64
  54. if err = e.DB.Model(new(model.MilkOriginal)).
  55. Select("MAX(id)").
  56. Where("pasture_id = ?", pastureId).
  57. Where("id > ?", milkClassConfig.OldUpdateMaxId).
  58. Scan(&currentMaxId).Error; err != nil {
  59. zaplog.Error("DeleteRepeatMilkData GetOriWid", zap.Any("pastureId", pastureId), zap.Any("err", err))
  60. return
  61. }
  62. milkClassConfig.CurrentMaxId = currentMaxId
  63. // 获取时间范围和ID范围
  64. deleteModel := &DeleteMilkOriginal{}
  65. selectSql := fmt.Sprintf(`MIN(DATE(TIMESTAMPADD(HOUR, -%d, attach_time))) as x_mind,
  66. MAX(DATE(TIMESTAMPADD(HOUR, -%d, attach_time))) as x_max_d2, MIN(id) as x_min_wid, MAX(id) as x_max_wid`, xDBeg, xDBeg)
  67. if err = e.DB.Model(new(model.MilkOriginal)).
  68. Select(selectSql).
  69. Where("pasture_id = ?", pastureId).
  70. Where("id > ?", milkClassConfig.OldUpdateMaxId).
  71. First(deleteModel).Error; err != nil {
  72. zaplog.Error("DeleteRepeatMilkData", zap.Any("pastureId", pastureId), zap.Any("err", err))
  73. return
  74. }
  75. milkOriginalList := make([]*model.MilkOriginal, 0)
  76. if err = e.DB.Model(new(model.MilkOriginal)).
  77. Where("pasture_id = ?", pastureId).
  78. Where("id BETWEEN ? AND ?", milkClassConfig.OldUpdateMaxId+1, milkClassConfig.CurrentMaxId).
  79. Find(&milkOriginalList).Error; err != nil {
  80. zaplog.Error("DeleteRepeatMilkData", zap.Any("pastureId", pastureId), zap.Any("err", err))
  81. return
  82. }
  83. e.DeleteRepeatMilkData(pastureId, deleteModel, milkClassConfig, milkOriginalList)
  84. milkHallList := e.FindMilkHallList(pastureId)
  85. for _, hall := range milkHallList {
  86. e.UpdateRecognitionTime(pastureId, hall)
  87. e.UpdateRepeatCupSet1(milkOriginalList)
  88. e.UpdateMilkOriginCowInfo(milkOriginalList, hall)
  89. e.UpdateRepeatCupSet2(milkOriginalList)
  90. e.UpdateMilkOriginalInitialTimesAndAttachAdjustTime(shifts, milkOriginalList)
  91. e.UpdateMilkNattach(pastureId, milkClassConfig, hall)
  92. e.UpdateMilkNoCowId(pastureId, milkClassConfig, hall)
  93. e.UpdateMilkLoad(pastureId, milkClassConfig, hall)
  94. e.UpdateMilkLoad2(pastureId, milkClassConfig, hall)
  95. e.UpdateMilkLoad3(pastureId, milkClassConfig, hall)
  96. e.UpdateMilkCowIdResetZero(pastureId, milkClassConfig, hall)
  97. }
  98. }
  99. // UpdateShifts 更新班次
  100. func (e *Entry) UpdateShifts(pastureId int64, xBeg1, xBeg2, xBeg3, xBeg4 int) {
  101. milkOriginalList := make([]*model.MilkOriginal, 0)
  102. if err := e.DB.Model(new(model.MilkOriginal)).
  103. Where("pasture_id = ?", pastureId).
  104. Where("shifts = ?", 0).
  105. Find(&milkOriginalList).Error; err != nil {
  106. zaplog.Error("UpdateShifts", zap.Any("pastureId", pastureId), zap.Any("err", err))
  107. }
  108. for _, v := range milkOriginalList {
  109. subDetachTime1 := util.Substr(v.DetachedTime, 11, 2)
  110. subDetachTime2 := util.Substr(v.DetachedTime, 14, 2)
  111. subDetachTime1Int, _ := strconv.ParseInt(subDetachTime1, 10, 64)
  112. subDetachTime2Int, _ := strconv.ParseInt(subDetachTime2, 10, 64)
  113. allDetachTime := int(subDetachTime1Int*100 + subDetachTime2Int)
  114. // 更新第一班
  115. if xBeg2 > xBeg1 {
  116. if allDetachTime >= xBeg1 && allDetachTime <= xBeg2 {
  117. v.Shifts = 1
  118. }
  119. } else {
  120. if allDetachTime >= xBeg1 || allDetachTime <= xBeg2 {
  121. v.Shifts = 1
  122. }
  123. }
  124. // 更新第二班
  125. if xBeg3 > xBeg2 {
  126. if allDetachTime >= xBeg2 && allDetachTime <= xBeg3 {
  127. v.Shifts = 2
  128. }
  129. } else {
  130. if allDetachTime >= xBeg2 || allDetachTime <= xBeg3 {
  131. v.Shifts = 2
  132. }
  133. }
  134. // 更新第四班(如果有)
  135. if xBeg4 > 0 && xBeg4 != xBeg1 {
  136. if xBeg1 > xBeg4 {
  137. if allDetachTime >= xBeg4 && allDetachTime <= xBeg1 {
  138. v.Shifts = 4
  139. }
  140. } else {
  141. if allDetachTime >= xBeg4 || allDetachTime <= xBeg1 {
  142. v.Shifts = 4
  143. }
  144. }
  145. }
  146. // 如果还没有分配班次,则分配到第三班
  147. if v.Shifts == 0 {
  148. v.Shifts = 3
  149. }
  150. // 批量更新数据库
  151. if err := e.DB.Model(new(model.MilkOriginal)).
  152. Select("shifts").
  153. Where("id = ?", v.Id).
  154. Updates(v).Error; err != nil {
  155. zaplog.Error("UpdateShifts Save", zap.Any("pastureId", pastureId), zap.Any("err", err))
  156. }
  157. }
  158. }
  159. // UpdateMilkDate 更换挤奶时间
  160. func (e *Entry) UpdateMilkDate(pastureId int64, xDBeg int) {
  161. milkOriginalList := make([]*model.MilkOriginal, 0)
  162. if err := e.DB.Model(new(model.MilkOriginal)).
  163. Where("pasture_id = ?", pastureId).
  164. Where("milk_date = ?", "").
  165. Find(&milkOriginalList).Error; err != nil {
  166. zaplog.Error("UpdateMilkDate", zap.Any("pastureId", pastureId), zap.Any("err", err))
  167. return
  168. }
  169. for _, v := range milkOriginalList {
  170. // 获取结束时间,如果为空则使用默认时间
  171. var endTime time.Time
  172. if v.EndTime == "" {
  173. endTime = time.Date(1999, 12, 31, 23, 0, 0, 0, time.Local)
  174. }
  175. // 比较挤奶时间和结束时间,取较晚的时间
  176. detachedTime, _ := util.TimeParseLocal(model.LayoutTime, v.DetachedTime)
  177. latestTime := detachedTime
  178. if endTime.After(detachedTime) {
  179. latestTime = endTime
  180. }
  181. // 减去xDBeg小时并获取日期
  182. milkDate := latestTime.Add(time.Duration(-xDBeg) * time.Hour).Format(model.LayoutDate2)
  183. // 更新数据库
  184. if err := e.DB.Model(new(model.MilkOriginal)).
  185. Select("milk_date").
  186. Where("id = ?", v.Id).
  187. Update("milk_date", milkDate).Error; err != nil {
  188. zaplog.Error("UpdateMilkDate", zap.Any("err", err), zap.Any("milkDate", milkDate))
  189. }
  190. }
  191. }
  192. // DeleteRepeatMilkData 删除重复数据
  193. func (e *Entry) DeleteRepeatMilkData(pastureId int64, deleteModel *DeleteMilkOriginal, cfg *MilkClassConfig, milkOriginalList []*model.MilkOriginal) {
  194. // 获取最小日期对应的最小wid
  195. var oriWid int64
  196. if err := e.DB.Model(new(model.MilkOriginal)).
  197. Select("MIN(id)").
  198. Where("pasture_id = ?", pastureId).
  199. Where("milk_date = ?", deleteModel.XMind).
  200. Scan(&oriWid).Error; err != nil {
  201. zaplog.Error("DeleteRepeatMilkData GetOriWid", zap.Any("pastureId", pastureId), zap.Any("err", err))
  202. return
  203. }
  204. for _, v := range milkOriginalList {
  205. e.delete1(v, deleteModel.XMind, cfg)
  206. e.delete2(v, deleteModel.XMind, cfg)
  207. e.delete3(v, deleteModel.XMind, cfg)
  208. e.delete4(v)
  209. }
  210. }
  211. func (e *Entry) delete1(data *model.MilkOriginal, xMinD string, cfg *MilkClassConfig) {
  212. // 1. 删除attach_time为00:00:00的记录
  213. actchStr := util.Substr(data.AttachTime, -1, 8)
  214. if data.MilkDate < xMinD || actchStr != "00:00:00" {
  215. return
  216. }
  217. // 2. 检查是否存在符合条件的m2记录
  218. var count int64
  219. if err := e.DB.Model(new(model.MilkOriginal)).
  220. Where("id BETWEEN ? AND ?", cfg.OldUpdateMaxId+1, cfg.CurrentMaxId).
  221. Where("milk_date = ?", data.MilkDate).
  222. Where("detached_address = ?", data.DetachedAddress).
  223. Where("ABS(TIMESTAMPDIFF(SECOND, detach_time, ?)) < 10", data.DetachedTime).
  224. Where("milk_weight = ?", data.MilkWeight).
  225. Where("pasture_id = ?", data.PastureId).
  226. Where("RIGHT(attach_time, 8) != '00:00:00'").
  227. Count(&count).Error; err != nil {
  228. zaplog.Error("Delete1", zap.Any("err", err))
  229. return
  230. }
  231. if count > 0 {
  232. if err := e.DB.Model(new(model.MilkOriginal)).
  233. Where("id = ?", data.Id).
  234. Delete(data).Error; err != nil {
  235. zaplog.Error("Delete1", zap.Any("err", err), zap.Any("data", data))
  236. }
  237. }
  238. }
  239. func (e *Entry) delete2(data *model.MilkOriginal, xMinD string, cfg *MilkClassConfig) {
  240. // 1. 检查记录是否在时间范围内
  241. if data.MilkDate < xMinD {
  242. return
  243. }
  244. // 2. 检查是否存在重复记录(除第一条外)
  245. var count int64
  246. if err := e.DB.Model(new(model.MilkOriginal)).
  247. Where("id BETWEEN ? AND ?", cfg.OldUpdateMaxId+1, cfg.CurrentMaxId).
  248. Where("milk_date = ?", data.MilkDate).
  249. Where("shifts = ?", data.Shifts).
  250. Where("detached_address = ?", data.DetachedAddress).
  251. Where("attach_time = ?", data.AttachTime).
  252. Where("milk_weight = ?", data.MilkWeight).
  253. Where("pasture_id = ?", data.PastureId).
  254. Where("id < ?", data.Id). // 只查找比当前记录更早的记录
  255. Count(&count).Error; err != nil {
  256. zaplog.Error("Delete2", zap.Any("err", err))
  257. return
  258. }
  259. // 3. 如果存在重复记录,则删除当前记录
  260. if count > 0 {
  261. if err := e.DB.Model(new(model.MilkOriginal)).
  262. Where("id = ?", data.Id).
  263. Delete(data).Error; err != nil {
  264. zaplog.Error("Delete2", zap.Any("err", err), zap.Any("data", data))
  265. }
  266. }
  267. }
  268. func (e *Entry) delete3(data *model.MilkOriginal, xMinD string, cfg *MilkClassConfig) {
  269. // 1. 检查记录是否在时间范围内
  270. if data.MilkDate < xMinD {
  271. return
  272. }
  273. // 2. 检查是否为班次开始且无奶量记录
  274. var isFirstInShift bool
  275. if err := e.DB.Raw(`
  276. SELECT 1 FROM (
  277. SELECT m.id, m.milk_date, m.shifts, m.milk_weight,
  278. @tot := IF(@tot + m.milk_weight > 100, 100,
  279. IF(m.shifts = @shifts, @tot, 0) + m.milk_weight) m_tot,
  280. @shifts := m.shifts
  281. FROM milk_original m, (SELECT @tot := 0, @shifts := 0) vars
  282. WHERE m.id BETWEEN ? AND ?
  283. AND m.milk_date >= ?
  284. AND m.pasture_id = ?
  285. ORDER BY m.milk_date, m.shifts, m.attach_time
  286. ) t
  287. WHERE t.id = ? AND t.m_tot = 0`,
  288. cfg.OldUpdateMaxId+1, cfg.CurrentMaxId, xMinD, data.PastureId, data.Id).
  289. Scan(&isFirstInShift).Error; err != nil {
  290. zaplog.Error("Delete3", zap.Any("err", err))
  291. return
  292. }
  293. // 3. 如果是班次开始且无奶量记录,则删除
  294. if isFirstInShift {
  295. if err := e.DB.Model(new(model.MilkOriginal)).
  296. Where("id = ?", data.Id).
  297. Delete(data).Error; err != nil {
  298. zaplog.Error("Delete3", zap.Any("err", err), zap.Any("data", data))
  299. }
  300. }
  301. }
  302. func (e *Entry) delete4(data *model.MilkOriginal) {
  303. // 1. 检查记录是否在时间范围内
  304. if data.MilkDate < "2020-10-01" {
  305. return
  306. }
  307. // 2. 检查是否为时间异常记录
  308. var isAbnormal bool
  309. if err := e.DB.Model(new(model.MilkOriginal)).
  310. Where("id = ?", data.Id).
  311. Where("milk_date >= ?", "2020-10-01").
  312. Where("recognition_time > detached_time").
  313. Where("attach_time > detached_time").
  314. Where("SUBSTRING(attach_time, 12, 2) = ?", "23").
  315. Where("pasture_id = ?", data.PastureId).
  316. Select("1").
  317. Scan(&isAbnormal).Error; err != nil {
  318. zaplog.Error("Delete4", zap.Any("err", err))
  319. return
  320. }
  321. // 3. 如果是时间异常记录,则删除
  322. if isAbnormal {
  323. if err := e.DB.Model(new(model.MilkOriginal)).
  324. Where("id = ?", data.Id).
  325. Delete(data).Error; err != nil {
  326. zaplog.Error("Delete4", zap.Any("err", err), zap.Any("data", data))
  327. }
  328. }
  329. }
  330. func parseXBeg(cfg *MilkClassConfig) (xBeg, xBeg1, xBeg2, xBeg3, xBeg4 int) {
  331. xBeg1Parts := strings.Split(cfg.FirstClassMilkTime, ":")
  332. if len(xBeg1Parts) < 2 {
  333. return
  334. }
  335. // 提取最后一部分
  336. xBeg1LastPart, _ := strconv.Atoi(xBeg1Parts[len(xBeg1Parts)-1])
  337. xBeg, _ = strconv.Atoi(xBeg1Parts[0])
  338. xBeg1, _ = strconv.Atoi(xBeg1Parts[1])
  339. xBeg1 = xBeg1*100 + xBeg1LastPart
  340. xBeg2Parts := strings.Split(cfg.SecondClassMilkTime, ":")
  341. if len(xBeg2Parts) < 2 {
  342. return
  343. }
  344. xBeg2LastPart, _ := strconv.Atoi(xBeg2Parts[len(xBeg2Parts)-1])
  345. xBeg2, _ = strconv.Atoi(xBeg2Parts[0])
  346. xBeg2 = xBeg2*100 + xBeg2LastPart
  347. xBeg3Parts := strings.Split(cfg.ThirdClassMilkTime, ":")
  348. if len(xBeg3Parts) < 2 {
  349. return
  350. }
  351. xBeg3LastPart, _ := strconv.Atoi(xBeg3Parts[len(xBeg3Parts)-1])
  352. xBeg3, _ = strconv.Atoi(xBeg3Parts[0])
  353. xBeg3 = xBeg3*100 + xBeg3LastPart
  354. xBeg4Parts := strings.Split(cfg.FourthClassMilkTime, ":")
  355. if len(xBeg4Parts) < 2 {
  356. return
  357. }
  358. xBeg4LastPart, _ := strconv.Atoi(xBeg4Parts[len(xBeg4Parts)-1])
  359. xBeg4, _ = strconv.Atoi(xBeg4Parts[0])
  360. xBeg4 = xBeg4*100 + xBeg4LastPart
  361. return
  362. }