analysis_breed.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. package backend
  2. import (
  3. "context"
  4. "fmt"
  5. "kpt-pasture/model"
  6. "kpt-pasture/util"
  7. "net/http"
  8. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  9. "gitee.com/xuyiping_admin/pkg/xerr"
  10. )
  11. // SingleFactorInfantSurvivalRateAnalysis 单因素受胎率分析
  12. func (s *StoreEntry) SingleFactorInfantSurvivalRateAnalysis(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) (*pasturePb.SingleFactorPregnancyRateResponse, error) {
  13. startTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  14. endTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  15. if startTimeUnix == 0 || endTimeUnix == 0 || endTimeUnix <= startTimeUnix {
  16. return nil, xerr.Custom("开始时间不能大于结束时间")
  17. }
  18. var err error
  19. list := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  20. chart := &pasturePb.SingleFactorPregnancyRateChart{
  21. Headers: make([]string, 0),
  22. PregnantRate: make([]float32, 0),
  23. MaxValue: make([]int32, 0),
  24. MinValue: make([]int32, 0),
  25. AveragePregnantRate: 0,
  26. }
  27. switch req.AnalysisMethod {
  28. case pasturePb.SingleFactorAnalysisMethod_Cycle:
  29. list, err = s.SingleFactorAnalysisMethodCycle(ctx, req)
  30. case pasturePb.SingleFactorAnalysisMethod_Months:
  31. list, err = s.SingleFactorAnalysisMethodMonths(ctx, req)
  32. case pasturePb.SingleFactorAnalysisMethod_Mating_Times:
  33. list, err = s.SingleFactorAnalysisMethodMatingTimes(ctx, req)
  34. case pasturePb.SingleFactorAnalysisMethod_Breeding_Method:
  35. list, err = s.SingleFactorAnalysisMethodBreeding(ctx, req)
  36. case pasturePb.SingleFactorAnalysisMethod_Breeding_Company:
  37. list, err = s.SingleFactorAnalysisMethodBreedingCompany(ctx, req)
  38. case pasturePb.SingleFactorAnalysisMethod_Operation:
  39. list, err = s.SingleFactorAnalysisMethodOperation(ctx, req)
  40. case pasturePb.SingleFactorAnalysisMethod_Mating_Interval:
  41. list, err = s.SingleFactorAnalysisMethodMatingInterval(ctx, req)
  42. case pasturePb.SingleFactorAnalysisMethod_Bull:
  43. list, err = s.SingleFactorAnalysisMethodBull(ctx, req)
  44. case pasturePb.SingleFactorAnalysisMethod_Breeding_Cycle:
  45. list, err = s.SingleFactorAnalysisMethodBreedingCycle(ctx, req)
  46. case pasturePb.SingleFactorAnalysisMethod_Week:
  47. list, err = s.SingleFactorAnalysisMethodWeek(ctx, req)
  48. case pasturePb.SingleFactorAnalysisMethod_Lact:
  49. list, err = s.SingleFactorAnalysisMethodLact(ctx, req)
  50. default:
  51. return nil, xerr.Custom("错误的统计方式")
  52. }
  53. if err != nil {
  54. return nil, xerr.WithStack(err)
  55. }
  56. totalCountMap := make(map[int]int32, len(list))
  57. allTotalCount := int32(0) // 总头数
  58. allPregnantRate := float64(0) // 总受胎率
  59. for i, v := range list {
  60. chart.Headers = append(chart.Headers, v.StatisticMethod)
  61. pregnantRate := float64(0)
  62. if v.EmptyPregnantCount+v.PregnantCount > 0 {
  63. pregnantRate = float64(v.PregnantCount) / float64(v.EmptyPregnantCount+v.PregnantCount)
  64. }
  65. chart.PregnantRate = append(chart.PregnantRate, float32(util.RoundToTwoDecimals(pregnantRate*100)))
  66. v.TotalCount = v.PregnantCount + v.EmptyPregnantCount + v.OtherCount
  67. v.PregnantRate = float32(util.RoundToTwoDecimals(pregnantRate * 100))
  68. spcRate := float32(0)
  69. if v.PregnantRate > 0 {
  70. spcRate = float32(util.RoundToTwoDecimals((float64(v.PregnantCount) / float64(v.TotalCount)) * 100))
  71. }
  72. v.SpceRate = spcRate
  73. totalCountMap[i] = v.TotalCount
  74. allTotalCount += v.TotalCount
  75. allPregnantRate += pregnantRate
  76. }
  77. for i, v := range totalCountMap {
  78. if allTotalCount <= 0 || list[i].TotalCount <= 0 {
  79. continue
  80. }
  81. list[i].TotalRate = float32(util.RoundToTwoDecimals(float64(v) / float64(allTotalCount) * 100))
  82. }
  83. if len(list) > 0 && allPregnantRate > 0 {
  84. chart.AveragePregnantRate = float32(util.RoundToTwoDecimals(allPregnantRate/float64(len(list))) * 100)
  85. }
  86. return &pasturePb.SingleFactorPregnancyRateResponse{
  87. Code: http.StatusOK,
  88. Message: "ok",
  89. Data: &pasturePb.SingleFactorPregnancyRateData{
  90. Total: int32(len(list)),
  91. List: list,
  92. Chart: chart,
  93. },
  94. }, nil
  95. }
  96. func (s *StoreEntry) SingleFactorAnalysisMethodCycle(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  97. dateTimeRange, err := util.GetRangeDayByDays(req.StartDayTime, req.EndDayTime, req.Value)
  98. if err != nil {
  99. return nil, xerr.WithStack(err)
  100. }
  101. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  102. selectSql := ""
  103. for _, v := range dateTimeRange {
  104. if len(v) != 2 {
  105. continue
  106. }
  107. startDayTimeUnix := util.TimeParseLocalUnix(v[0])
  108. endDayTimeUnix := util.TimeParseLocalEndUnix(v[1])
  109. selectSql += fmt.Sprintf(`
  110. SELECT
  111. '%s ~ %s' as statistic_method,
  112. COUNT(DISTINCT CASE WHEN mating_result = %d AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  113. COUNT(DISTINCT CASE WHEN mating_result = %d AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  114. COUNT(DISTINCT CASE WHEN mating_result = %d AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  115. COUNT(DISTINCT CASE WHEN mating_result IN (%d, %d) THEN cow_id END) AS other_count, -- 其他数
  116. (
  117. COUNT(DISTINCT CASE WHEN mating_result = %d AND mating_result_at > 0 THEN cow_id END) +
  118. COUNT(DISTINCT CASE WHEN mating_result = %d AND mating_result_at > 0 THEN cow_id END) +
  119. COUNT(DISTINCT CASE WHEN mating_result IN (%d, %d) THEN cow_id END)
  120. ) AS total_count -- 总数
  121. FROM event_mating WHERE status = %d AND reality_day BETWEEN %d AND %d
  122. UNION ALL `, v[0], v[1], pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  123. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  124. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch,
  125. pasturePb.IsShow_Ok, startDayTimeUnix, endDayTimeUnix)
  126. }
  127. if len(selectSql) > 0 {
  128. selectSql = selectSql[:len(selectSql)-len("UNION ALL")-3] + ";"
  129. }
  130. if err = s.DB.Raw(selectSql).Scan(&res).Error; err != nil {
  131. return nil, xerr.WithStack(err)
  132. }
  133. return res, nil
  134. }
  135. func (s *StoreEntry) SingleFactorAnalysisMethodMonths(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  136. startDayTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  137. endDayTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  138. if startDayTimeUnix == 0 || endDayTimeUnix == 0 || endDayTimeUnix <= startDayTimeUnix {
  139. return nil, xerr.Custom("开始时间不能大于结束时间")
  140. }
  141. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  142. pref := s.DB.Model(new(model.EventMating)).
  143. Select(`
  144. DATE_FORMAT(FROM_UNIXTIME(reality_day), '%Y-%m') AS months,
  145. DATE_FORMAT(FROM_UNIXTIME(reality_day), '%Y-%m') AS statistic_method,
  146. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  147. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  148. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  149. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END) AS other_count, -- 其他数
  150. (
  151. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  152. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  153. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END)
  154. ) AS total_count -- 总数
  155. `, pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  156. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  157. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch).
  158. Where("status = ?", pasturePb.IsShow_Ok).
  159. Where("reality_day BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix)
  160. if req.CowType > 0 {
  161. pref.Where("cow_type = ?", req.CowType)
  162. }
  163. if req.CowKind > 0 {
  164. pref.Where("cow_kind = ?", req.CowKind)
  165. }
  166. if req.LactInterval > 0 {
  167. switch req.LactInterval {
  168. case pasturePb.CompareSymbol_Less_Than:
  169. pref.Where("lact < ?", req.LactIntervalStartValue)
  170. case pasturePb.CompareSymbol_Less_Than_Or_Equal_To:
  171. pref.Where("lact <= ?", req.LactIntervalStartValue)
  172. case pasturePb.CompareSymbol_Greater_Than:
  173. pref.Where("lact > ?", req.LactIntervalStartValue)
  174. case pasturePb.CompareSymbol_Greater_Than_Or_Equal_To:
  175. pref.Where("lact >= ?", req.LactIntervalStartValue)
  176. case pasturePb.CompareSymbol_Equal_To:
  177. pref.Where("lact = ?", req.LactIntervalStartValue)
  178. case pasturePb.CompareSymbol_Not_Equal_To:
  179. pref.Where("lact != ?", req.LactIntervalStartValue)
  180. case pasturePb.CompareSymbol_Between:
  181. pref.Where("lact BETWEEN ? AND ? ", req.LactIntervalStartValue, req.LactIntervalEndValue)
  182. default:
  183. return nil, xerr.Custom("错误的胎次区间符号")
  184. }
  185. }
  186. if err := pref.Group("months").Order("months").Find(&res).Error; err != nil {
  187. return nil, xerr.WithStack(err)
  188. }
  189. return res, nil
  190. }
  191. func (s *StoreEntry) SingleFactorAnalysisMethodMatingTimes(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  192. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  193. return res, nil
  194. }
  195. func (s *StoreEntry) SingleFactorAnalysisMethodBreeding(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  196. startDayTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  197. endDayTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  198. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  199. if err := s.DB.Model(new(model.EventMating)).
  200. Select(`
  201. CASE
  202. WHEN expose_estrus_type = ? THEN '脖环揭发'
  203. WHEN expose_estrus_type = ? THEN '脚环/计步器'
  204. WHEN expose_estrus_type = ? THEN '自然发情'
  205. WHEN expose_estrus_type = ? THEN '同期'
  206. ELSE '未知'
  207. END AS statistic_method,
  208. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  209. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  210. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  211. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END) AS other_count, -- 其他数
  212. (
  213. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  214. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  215. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END)
  216. ) AS total_count -- 总数
  217. `, pasturePb.ExposeEstrusType_Neck_Ring, pasturePb.ExposeEstrusType_Foot_Ring,
  218. pasturePb.ExposeEstrusType_Natural_Estrus, pasturePb.ExposeEstrusType_Same_Time,
  219. pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  220. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  221. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch,
  222. ).Where("status = ?", pasturePb.IsShow_Ok).
  223. Where("reality_day BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix).
  224. Where("cow_type = ?", req.CowType).
  225. Group("expose_estrus_type").
  226. Order("expose_estrus_type").
  227. Find(&res).Error; err != nil {
  228. return nil, xerr.WithStack(err)
  229. }
  230. return res, nil
  231. }
  232. func (s *StoreEntry) SingleFactorAnalysisMethodBreedingCompany(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  233. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  234. startDayTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  235. endDayTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  236. pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventMating).TableName())).
  237. Select(`
  238. b.producer AS statistic_method,
  239. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  240. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  241. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  242. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END) AS other_count, -- 其他数
  243. (
  244. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  245. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  246. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END)
  247. ) AS total_count -- 总数
  248. `, pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  249. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  250. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch).
  251. Joins(fmt.Sprintf("left join %s as b on a.frozen_semen_number = b.bull_id ", new(model.FrozenSemen).TableName()))
  252. if req.CowType > 0 {
  253. pref.Where("a.cow_type = ?", req.CowType)
  254. }
  255. if req.CowKind > 0 {
  256. pref.Where("a.cow_kind = ?", req.CowKind)
  257. }
  258. if req.LactInterval > 0 {
  259. switch req.LactInterval {
  260. case pasturePb.CompareSymbol_Less_Than:
  261. pref.Where("a.lact < ?", req.LactIntervalStartValue)
  262. case pasturePb.CompareSymbol_Less_Than_Or_Equal_To:
  263. pref.Where("a.lact <= ?", req.LactIntervalStartValue)
  264. case pasturePb.CompareSymbol_Greater_Than:
  265. pref.Where("a.lact > ?", req.LactIntervalStartValue)
  266. case pasturePb.CompareSymbol_Greater_Than_Or_Equal_To:
  267. pref.Where("a.lact >= ?", req.LactIntervalStartValue)
  268. case pasturePb.CompareSymbol_Equal_To:
  269. pref.Where("a.lact = ?", req.LactIntervalStartValue)
  270. case pasturePb.CompareSymbol_Not_Equal_To:
  271. pref.Where("a.lact != ?", req.LactIntervalStartValue)
  272. case pasturePb.CompareSymbol_Between:
  273. pref.Where("a.lact BETWEEN ? AND ? ", req.LactIntervalStartValue, req.LactIntervalEndValue)
  274. default:
  275. return nil, xerr.Custom("错误的胎次区间符号")
  276. }
  277. }
  278. if err := pref.Where("a.status = ?", pasturePb.IsShow_Ok).
  279. Where("a.reality_day BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix).
  280. Group("b.producer").
  281. Find(&res).Error; err != nil {
  282. return nil, xerr.WithStack(err)
  283. }
  284. return res, nil
  285. }
  286. func (s *StoreEntry) SingleFactorAnalysisMethodOperation(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  287. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  288. startDayTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  289. endDayTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  290. pref := s.DB.Model(new(model.EventMating)).Select(`
  291. operation_name AS statistic_method,
  292. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  293. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  294. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  295. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END) AS other_count, -- 其他数
  296. (
  297. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  298. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  299. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END)
  300. ) AS total_count -- 总数
  301. `, pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  302. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  303. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch)
  304. if req.CowType > 0 {
  305. pref.Where("cow_type = ?", req.CowType)
  306. }
  307. if req.CowKind > 0 {
  308. pref.Where("cow_kind = ?", req.CowKind)
  309. }
  310. if req.LactInterval > 0 {
  311. switch req.LactInterval {
  312. case pasturePb.CompareSymbol_Less_Than:
  313. pref.Where("lact < ?", req.LactIntervalStartValue)
  314. case pasturePb.CompareSymbol_Less_Than_Or_Equal_To:
  315. pref.Where("lact <= ?", req.LactIntervalStartValue)
  316. case pasturePb.CompareSymbol_Greater_Than:
  317. pref.Where("lact > ?", req.LactIntervalStartValue)
  318. case pasturePb.CompareSymbol_Greater_Than_Or_Equal_To:
  319. pref.Where("lact >= ?", req.LactIntervalStartValue)
  320. case pasturePb.CompareSymbol_Equal_To:
  321. pref.Where("lact = ?", req.LactIntervalStartValue)
  322. case pasturePb.CompareSymbol_Not_Equal_To:
  323. pref.Where("lact != ?", req.LactIntervalStartValue)
  324. case pasturePb.CompareSymbol_Between:
  325. pref.Where("lact BETWEEN ? AND ? ", req.LactIntervalStartValue, req.LactIntervalEndValue)
  326. default:
  327. return nil, xerr.Custom("错误的胎次区间符号")
  328. }
  329. }
  330. if err := pref.Where("status = ?", pasturePb.IsShow_Ok).
  331. Where("reality_day BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix).
  332. Group("operation_id").
  333. Find(&res).Error; err != nil {
  334. return nil, xerr.WithStack(err)
  335. }
  336. return res, nil
  337. }
  338. func (s *StoreEntry) SingleFactorAnalysisMethodMatingInterval(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  339. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  340. return res, nil
  341. }
  342. func (s *StoreEntry) SingleFactorAnalysisMethodBull(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  343. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  344. startDayTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  345. endDayTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  346. pref := s.DB.Model(new(model.EventMating)).
  347. Select(`
  348. frozen_semen_number AS statistic_method,
  349. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  350. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  351. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  352. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END) AS other_count, -- 其他数
  353. (
  354. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  355. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  356. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END)
  357. ) AS total_count -- 总数
  358. `, pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  359. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  360. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch)
  361. if req.CowType > 0 {
  362. pref.Where("cow_type = ?", req.CowType)
  363. }
  364. if req.CowKind > 0 {
  365. pref.Where("cow_kind = ?", req.CowKind)
  366. }
  367. if req.LactInterval > 0 {
  368. switch req.LactInterval {
  369. case pasturePb.CompareSymbol_Less_Than:
  370. pref.Where("lact < ?", req.LactIntervalStartValue)
  371. case pasturePb.CompareSymbol_Less_Than_Or_Equal_To:
  372. pref.Where("lact <= ?", req.LactIntervalStartValue)
  373. case pasturePb.CompareSymbol_Greater_Than:
  374. pref.Where("lact > ?", req.LactIntervalStartValue)
  375. case pasturePb.CompareSymbol_Greater_Than_Or_Equal_To:
  376. pref.Where("lact >= ?", req.LactIntervalStartValue)
  377. case pasturePb.CompareSymbol_Equal_To:
  378. pref.Where("lact = ?", req.LactIntervalStartValue)
  379. case pasturePb.CompareSymbol_Not_Equal_To:
  380. pref.Where("lact != ?", req.LactIntervalStartValue)
  381. case pasturePb.CompareSymbol_Between:
  382. pref.Where("lact BETWEEN ? AND ? ", req.LactIntervalStartValue, req.LactIntervalEndValue)
  383. default:
  384. return nil, xerr.Custom("错误的胎次区间符号")
  385. }
  386. }
  387. if err := pref.Where("status = ?", pasturePb.IsShow_Ok).
  388. Where("reality_day BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix).
  389. Group("frozen_semen_number").
  390. Find(&res).Error; err != nil {
  391. return nil, xerr.WithStack(err)
  392. }
  393. return res, nil
  394. }
  395. func (s *StoreEntry) SingleFactorAnalysisMethodBreedingCycle(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  396. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  397. return res, nil
  398. }
  399. func (s *StoreEntry) SingleFactorAnalysisMethodWeek(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  400. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  401. startDayTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  402. endDayTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  403. pref := s.DB.Model(new(model.EventMating)).
  404. Select(`
  405. CASE
  406. DAYOFWEEK(DATE(FROM_UNIXTIME(reality_day)))
  407. WHEN 2 THEN '星期一'
  408. WHEN 3 THEN '星期二'
  409. WHEN 4 THEN '星期三'
  410. WHEN 5 THEN '星期四'
  411. WHEN 6 THEN '星期五'
  412. WHEN 7 THEN '星期六'
  413. WHEN 1 THEN '星期日'
  414. ELSE '未知'
  415. END AS statistic_method,
  416. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  417. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  418. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  419. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END) AS other_count, -- 其他数
  420. (
  421. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  422. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  423. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END)
  424. ) AS total_count -- 总数
  425. `, pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  426. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  427. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch)
  428. if req.CowType > 0 {
  429. pref.Where("cow_type = ?", req.CowType)
  430. }
  431. if req.CowKind > 0 {
  432. pref.Where("cow_kind = ?", req.CowKind)
  433. }
  434. if req.LactInterval > 0 {
  435. switch req.LactInterval {
  436. case pasturePb.CompareSymbol_Less_Than:
  437. pref.Where("lact < ?", req.LactIntervalStartValue)
  438. case pasturePb.CompareSymbol_Less_Than_Or_Equal_To:
  439. pref.Where("lact <= ?", req.LactIntervalStartValue)
  440. case pasturePb.CompareSymbol_Greater_Than:
  441. pref.Where("lact > ?", req.LactIntervalStartValue)
  442. case pasturePb.CompareSymbol_Greater_Than_Or_Equal_To:
  443. pref.Where("lact >= ?", req.LactIntervalStartValue)
  444. case pasturePb.CompareSymbol_Equal_To:
  445. pref.Where("lact = ?", req.LactIntervalStartValue)
  446. case pasturePb.CompareSymbol_Not_Equal_To:
  447. pref.Where("lact != ?", req.LactIntervalStartValue)
  448. case pasturePb.CompareSymbol_Between:
  449. pref.Where("lact BETWEEN ? AND ? ", req.LactIntervalStartValue, req.LactIntervalEndValue)
  450. default:
  451. return nil, xerr.Custom("错误的胎次区间符号")
  452. }
  453. }
  454. if err := pref.Where("status = ?", pasturePb.IsShow_Ok).
  455. Where("reality_day BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix).
  456. Group("statistic_method").
  457. Find(&res).Error; err != nil {
  458. return nil, xerr.WithStack(err)
  459. }
  460. return res, nil
  461. }
  462. func (s *StoreEntry) SingleFactorAnalysisMethodLact(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) ([]*pasturePb.SingleFactorPregnancyRateList, error) {
  463. res := make([]*pasturePb.SingleFactorPregnancyRateList, 0)
  464. startDayTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  465. endDayTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  466. pref := s.DB.Model(new(model.EventMating)).
  467. Select(`
  468. lact AS statistic_method,
  469. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  470. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  471. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  472. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END) AS other_count, -- 其他数
  473. (
  474. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  475. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) +
  476. COUNT(DISTINCT CASE WHEN mating_result IN (?, ?) THEN cow_id END)
  477. ) AS total_count -- 总数
  478. `, pasturePb.MatingResult_Pregnant, pasturePb.MatingResult_Empty, pasturePb.MatingResult_Abort,
  479. pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch, pasturePb.MatingResult_Pregnant,
  480. pasturePb.MatingResult_Empty, pasturePb.MatingResult_Unknown, pasturePb.MatingResult_ReMatch)
  481. if req.CowType > 0 {
  482. pref.Where("cow_type = ?", req.CowType)
  483. }
  484. if req.CowKind > 0 {
  485. pref.Where("cow_kind = ?", req.CowKind)
  486. }
  487. if err := pref.Where("status = ?", pasturePb.IsShow_Ok).
  488. Where("reality_day BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix).
  489. Group("lact").
  490. Find(&res).Error; err != nil {
  491. return nil, xerr.WithStack(err)
  492. }
  493. return res, nil
  494. }
  495. func (s *StoreEntry) MultipleFactorAnalysis(ctx context.Context, req *pasturePb.MultiFactorPregnancyRateRequest) (*pasturePb.MultiFactorPregnancyRateResponse, error) {
  496. startTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
  497. endTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
  498. if startTimeUnix == 0 || endTimeUnix == 0 || endTimeUnix <= startTimeUnix {
  499. return nil, xerr.Custom("开始时间不能大于结束时间")
  500. }
  501. if req.XAxle == req.YAxle {
  502. return nil, xerr.Custom("X轴和Y轴不能相同")
  503. }
  504. if req.XAxle == 0 || req.YAxle == 0 {
  505. return nil, xerr.Custom("错误的XY轴数据")
  506. }
  507. pref := s.DB.Model(new(model.EventMating)).
  508. Where("status = ?", pasturePb.IsShow_Ok).
  509. Where("cow_type = ?", req.CowType)
  510. if req.LactCompareSymbol > 0 {
  511. switch req.LactCompareSymbol {
  512. case pasturePb.CompareSymbol_Less_Than:
  513. pref.Where("lact < ?", req.LactStartValue)
  514. case pasturePb.CompareSymbol_Less_Than_Or_Equal_To:
  515. pref.Where("lact <= ?", req.LactStartValue)
  516. case pasturePb.CompareSymbol_Greater_Than:
  517. pref.Where("lact > ?", req.LactStartValue)
  518. case pasturePb.CompareSymbol_Greater_Than_Or_Equal_To:
  519. pref.Where("lact >= ?", req.LactStartValue)
  520. case pasturePb.CompareSymbol_Equal_To:
  521. pref.Where("lact = ?", req.LactStartValue)
  522. case pasturePb.CompareSymbol_Not_Equal_To:
  523. pref.Where("lact != ?", req.LactStartValue)
  524. case pasturePb.CompareSymbol_Between:
  525. pref.Where("lact BETWEEN ? AND ? ", req.LactStartValue, req.LactEndValue)
  526. }
  527. }
  528. if req.MatingTimesCompareSymbol > 0 {
  529. switch req.MatingTimesCompareSymbol {
  530. case pasturePb.CompareSymbol_Less_Than:
  531. pref.Where("mating_number < ?", req.LactStartValue)
  532. case pasturePb.CompareSymbol_Less_Than_Or_Equal_To:
  533. pref.Where("mating_number <= ?", req.LactStartValue)
  534. case pasturePb.CompareSymbol_Greater_Than:
  535. pref.Where("mating_number > ?", req.LactStartValue)
  536. case pasturePb.CompareSymbol_Greater_Than_Or_Equal_To:
  537. pref.Where("mating_number >= ?", req.LactStartValue)
  538. case pasturePb.CompareSymbol_Equal_To:
  539. pref.Where("mating_number = ?", req.LactStartValue)
  540. case pasturePb.CompareSymbol_Not_Equal_To:
  541. pref.Where("mating_number != ?", req.LactStartValue)
  542. case pasturePb.CompareSymbol_Between:
  543. pref.Where("mating_number BETWEEN ? AND ? ", req.LactStartValue, req.LactEndValue)
  544. }
  545. }
  546. if req.XAxle > 0 {
  547. switch req.XAxle {
  548. case pasturePb.MultiFactorAnalysisMethod_Months:
  549. pref.Select(`
  550. DATE_FORMAT(reality_day, '%Y-%m') AS statistic_method,
  551. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS pregnant_count, -- 怀孕头数
  552. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS empty_pregnant_count, -- 空怀头数
  553. COUNT(DISTINCT CASE WHEN mating_result = ? AND mating_result_at > 0 THEN cow_id END) AS abortion_count, -- 流产头数
  554. `)
  555. }
  556. }
  557. list := make([]*pasturePb.MultiFactorPregnancyRateList, 0)
  558. if err := pref.Group("statistic_method").Find(&list).Error; err != nil {
  559. return nil, xerr.WithStack(err)
  560. }
  561. chart := &pasturePb.MultiFactorPregnancyRateChart{
  562. Headers: make([]string, 0),
  563. PregnantRate: make(map[string]*pasturePb.PregnancyRate),
  564. }
  565. return &pasturePb.MultiFactorPregnancyRateResponse{
  566. Code: http.StatusOK,
  567. Message: "ok",
  568. Data: &pasturePb.MultiFactorPregnancyRateData{
  569. Total: int32(len(list)),
  570. List: list,
  571. Chart: chart,
  572. },
  573. }, nil
  574. }