group.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. package group
  2. import (
  3. "fmt"
  4. "sort"
  5. "time"
  6. "tmr-watch/models"
  7. "tmr-watch/module"
  8. "tmr-watch/pkg/util"
  9. )
  10. // DistributeFeedFormulaService 饲料配方下发牧场端
  11. func DistributeFeedFormulaService(req *models.PastureBodyRequest) error {
  12. if len(req.Body) <= 0 {
  13. return nil
  14. }
  15. feedTemplateList := make([]*models.FeedTemplate, 0)
  16. for _, b := range req.Body {
  17. feedTemplateList = append(feedTemplateList, &models.FeedTemplate{
  18. PastureId: req.PastureId,
  19. TCode: b.EncodeNumber,
  20. TName: b.Name,
  21. TColor: b.Colour,
  22. CCid: int64(b.CattleCategoryId),
  23. CCName: b.CattleCategoryName,
  24. FTType: b.FormulaTypeName,
  25. FTTypeId: b.FormulaTypeId,
  26. Source: "集团下发",
  27. Remark: b.Remarks,
  28. Enable: 1,
  29. Version: b.Version,
  30. SaveTime: time.Now().Format("2006-01-02 15:04:05"),
  31. IsIssue: 0,
  32. IssueVersion: 0,
  33. IssueId: 0,
  34. IsModify: b.IsModify,
  35. })
  36. }
  37. return module.DistributeFeedFormula(feedTemplateList)
  38. }
  39. func FeedFormulaIsModifyService(req *models.PastureFeedFormulaIsModifyRequest) error {
  40. return module.FeedFormulaIsModify(req)
  41. }
  42. func FeedFormulaList(req *models.FeedFormulaListRequest) (*models.FeedFormulaData, error) {
  43. res := &models.FeedFormulaData{
  44. Total: 0,
  45. Page: req.Page,
  46. PageSize: req.PageSize,
  47. List: make([]*models.FeedTemplate, 0),
  48. }
  49. dataList, total, err := module.FeedTemplateList(req)
  50. if err != nil {
  51. return nil, err
  52. }
  53. res.Total = int32(total)
  54. res.List = dataList
  55. return res, nil
  56. }
  57. // AnalysisAccuracyService 首页准确率分析
  58. func AnalysisAccuracyService(req *models.AnalysisAccuracyRequest) (*models.AnalysisAccuracyResponse, error) {
  59. response := &models.AnalysisAccuracyResponse{
  60. MixedFodderAccurateRatio: make([]*models.PastureAnalysisAccuracyDataValue, 0),
  61. MixedFodderCorrectRatio: make([]*models.PastureAnalysisAccuracyDataValue, 0),
  62. SprinkleFodderAccurateRatio: make([]*models.PastureAnalysisAccuracyDataValue, 0),
  63. SprinkleFodderCorrectRatio: make([]*models.PastureAnalysisAccuracyDataValue, 0),
  64. }
  65. // 混料准确率
  66. mixedFodderDataList, err := module.MixedFodderData(req)
  67. if err != nil {
  68. return nil, err
  69. }
  70. // 撒料准确率
  71. sprinkleFodderDataList, err := module.SprinkleFodderData(req)
  72. if err != nil {
  73. return nil, err
  74. }
  75. // 混料正确率
  76. mixedFodderCorrectDataList, err := module.MixedFodderCorrectData(req)
  77. if err != nil {
  78. return nil, err
  79. }
  80. // 撒料正确率
  81. sprinkleFodderCorrectDataList, err := module.SprinkleFodderCorrectData(req)
  82. timeList := util.TimeBetween(req.StartDate, req.EndDate)
  83. for _, dayTime := range timeList {
  84. var mixedInfo, sprinkleInfo, mixedCorrectInfo, sprinkleCorrectInfo bool
  85. for _, mixed := range mixedFodderDataList {
  86. myDate := mixed.Date.Format(util.LayoutDateFormat)
  87. if myDate != dayTime {
  88. continue
  89. }
  90. // 混料准确率
  91. var mixedFodderAccurateRatio float64 = 0
  92. if mixed.Lweight > 0 && mixed.ActualWeightMinus > 0 {
  93. if mixed.Lweight > mixed.ActualWeightMinus {
  94. mixedFodderAccurateRatio = mixed.ActualWeightMinus / mixed.Lweight * 100
  95. } else {
  96. mixedFodderAccurateRatio = mixed.Lweight / mixed.ActualWeightMinus * 100
  97. }
  98. }
  99. mixedValue := &models.PastureAnalysisAccuracyDataValue{
  100. DayTime: dayTime,
  101. Ratio: mixedFodderAccurateRatio,
  102. }
  103. response.MixedFodderAccurateRatio = append(response.MixedFodderAccurateRatio, mixedValue)
  104. mixedInfo = true
  105. }
  106. if !mixedInfo {
  107. noInfo := &models.PastureAnalysisAccuracyDataValue{
  108. DayTime: dayTime,
  109. Ratio: 0,
  110. }
  111. response.MixedFodderAccurateRatio = append(response.MixedFodderAccurateRatio, noInfo)
  112. }
  113. for _, sprinkle := range sprinkleFodderDataList {
  114. myDate := sprinkle.Date.Format(util.LayoutDateFormat)
  115. if myDate != dayTime {
  116. continue
  117. }
  118. // 撒料准确率
  119. var sprinkleFodderAccurateRatio float64 = 0
  120. if sprinkle.Lweight > 0 && sprinkle.ActualWeightMinus > 0 {
  121. if sprinkle.Lweight > sprinkle.ActualWeightMinus {
  122. sprinkleFodderAccurateRatio = sprinkle.ActualWeightMinus / sprinkle.Lweight * 100
  123. } else {
  124. sprinkleFodderAccurateRatio = sprinkle.Lweight / sprinkle.ActualWeightMinus * 100
  125. }
  126. }
  127. sprinkleValue := &models.PastureAnalysisAccuracyDataValue{
  128. DayTime: dayTime,
  129. Ratio: sprinkleFodderAccurateRatio,
  130. }
  131. response.SprinkleFodderAccurateRatio = append(response.SprinkleFodderAccurateRatio, sprinkleValue)
  132. sprinkleInfo = true
  133. }
  134. if !sprinkleInfo {
  135. noInfo := &models.PastureAnalysisAccuracyDataValue{
  136. DayTime: dayTime,
  137. Ratio: 0,
  138. }
  139. response.SprinkleFodderAccurateRatio = append(response.SprinkleFodderAccurateRatio, noInfo)
  140. }
  141. for _, mixedFodder := range mixedFodderCorrectDataList {
  142. mixDateStr, _ := time.ParseInLocation(time.RFC3339, mixedFodder.Date, time.Local)
  143. mixDate := mixDateStr.Format("2006-01-02")
  144. if mixDate != dayTime {
  145. continue
  146. }
  147. if mixedFodder.MixedCorrectNumber == 0 || mixedFodder.UseMixedFodderOptionNumber == 0 {
  148. response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
  149. DayTime: dayTime,
  150. Ratio: 0,
  151. })
  152. } else {
  153. response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
  154. DayTime: dayTime,
  155. Ratio: float64(mixedFodder.MixedCorrectNumber) / float64(mixedFodder.UseMixedFodderOptionNumber) * 100,
  156. })
  157. }
  158. mixedCorrectInfo = true
  159. }
  160. if !mixedCorrectInfo {
  161. response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
  162. DayTime: dayTime,
  163. Ratio: 0,
  164. })
  165. }
  166. for _, sprinkle := range sprinkleFodderCorrectDataList {
  167. myDateStr, _ := time.ParseInLocation(time.RFC3339, sprinkle.Date, time.Local)
  168. myDate := myDateStr.Format("2006-01-02")
  169. if myDate != dayTime {
  170. continue
  171. }
  172. if sprinkle.SprinkleCorrectNumber == 0 || sprinkle.UseSprinkleOptionNumber == 0 {
  173. response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
  174. DayTime: dayTime,
  175. Ratio: 0,
  176. })
  177. } else {
  178. response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
  179. DayTime: dayTime,
  180. Ratio: float64(sprinkle.SprinkleCorrectNumber) / float64(sprinkle.UseSprinkleOptionNumber) * 100,
  181. })
  182. }
  183. sprinkleCorrectInfo = true
  184. }
  185. if !sprinkleCorrectInfo {
  186. response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
  187. DayTime: dayTime,
  188. Ratio: 0,
  189. })
  190. }
  191. }
  192. return response, nil
  193. }
  194. // ProcessAnalysisService 过程分析
  195. func ProcessAnalysisService(req *models.AnalysisAccuracyRequest) (*models.ProcessAnalysisResponse, error) {
  196. response := &models.ProcessAnalysisResponse{
  197. AddFeedTime: &models.ProcessAnalysisDataValue{},
  198. SprinkleTime: &models.ProcessAnalysisDataValue{},
  199. StirTime: &models.ProcessAnalysisDataValue{},
  200. }
  201. processDataList, err := module.ProcessAnalysisData(req)
  202. if err != nil {
  203. return nil, err
  204. }
  205. addFeedList := make([]int, 0)
  206. sprinkleFeedList := make([]int, 0)
  207. stirDelayList := make([]int, 0)
  208. for _, v := range processDataList {
  209. addFeedList = append(addFeedList, util.TimeParseToMinutes(v.ExecProcessTime))
  210. sprinkleFeedList = append(sprinkleFeedList, util.TimeParseToMinutes(v.L2ProcessTime))
  211. stirDelayList = append(stirDelayList, v.ExecStirDelay)
  212. }
  213. if len(addFeedList) > 0 {
  214. sort.Ints(addFeedList)
  215. response.AddFeedTime.MaxValue = fmt.Sprintf("%.2f", float64(addFeedList[len(addFeedList)-1])/60)
  216. response.AddFeedTime.UpMiddleValue = fmt.Sprintf("%.2f", util.Median(addFeedList[len(addFeedList)/2+1:])/60)
  217. response.AddFeedTime.MiddleValue = fmt.Sprintf("%.2f", util.Median(addFeedList)/60)
  218. response.AddFeedTime.DownMiddleValue = fmt.Sprintf("%.2f", util.Median(addFeedList[0:len(addFeedList)/2])/60)
  219. response.AddFeedTime.MinValue = fmt.Sprintf("%.2f", float64(addFeedList[0])/60)
  220. }
  221. if len(sprinkleFeedList) > 0 {
  222. sort.Ints(sprinkleFeedList)
  223. response.SprinkleTime.MaxValue = fmt.Sprintf("%.2f", float64(sprinkleFeedList[len(sprinkleFeedList)-1])/60)
  224. response.SprinkleTime.UpMiddleValue = fmt.Sprintf("%.2f", util.Median(sprinkleFeedList[len(sprinkleFeedList)/2+1:])/60)
  225. response.SprinkleTime.MiddleValue = fmt.Sprintf("%.2f", util.Median(sprinkleFeedList)/60)
  226. response.SprinkleTime.DownMiddleValue = fmt.Sprintf("%.2f", util.Median(sprinkleFeedList[0:len(sprinkleFeedList)/2])/60)
  227. response.SprinkleTime.MinValue = fmt.Sprintf("%.2f", float64(sprinkleFeedList[0])/60)
  228. }
  229. if len(stirDelayList) > 0 {
  230. sort.Ints(stirDelayList)
  231. response.StirTime.MaxValue = fmt.Sprintf("%d", stirDelayList[len(stirDelayList)-1])
  232. response.StirTime.UpMiddleValue = fmt.Sprintf("%.2f", util.Median(stirDelayList[len(stirDelayList)/2+1:]))
  233. response.StirTime.MiddleValue = fmt.Sprintf("%.2f", util.Median(stirDelayList))
  234. response.StirTime.DownMiddleValue = fmt.Sprintf("%.2f", util.Median(stirDelayList[0:len(stirDelayList)/2]))
  235. response.StirTime.MinValue = fmt.Sprintf("%d", stirDelayList[0])
  236. }
  237. return response, nil
  238. }
  239. // SprinkleStatisticsService 撒料统计
  240. func SprinkleStatisticsService(req *models.SprinkleStatisticsRequest) ([]*models.SprinkleStatisticsDataList, error) {
  241. sprinkleDataList, err := module.SprinkleStatistics(req)
  242. if err != nil {
  243. return nil, err
  244. }
  245. return sprinkleDataList, nil
  246. }
  247. func AccountDistributionService(req *models.AccountDistributionRequest) error {
  248. return module.AccountDistribution(req)
  249. }
  250. func ForageCategoryDistributeService(req *models.CategoryRequest) error {
  251. feedClass := &models.FeedClass{
  252. PastureId: int64(req.PastureId),
  253. FCCode: req.Number,
  254. FCName: req.Name,
  255. Enable: req.IsShow,
  256. BigFeedClassId: req.ParentId,
  257. BigFeedClassName: req.ParentName,
  258. GroupId: int64(req.GroupId),
  259. }
  260. return module.ForageCategoryDistribute(feedClass)
  261. }
  262. func CattleCategoryDistributeService(req *models.CategoryRequest) error {
  263. cowClass := &models.CowClass{
  264. PastureId: int64(req.PastureId),
  265. ClassCode: req.Number,
  266. ClassName: req.Name,
  267. Enable: req.IsShow,
  268. ParentId: req.ParentId,
  269. ParentName: req.ParentName,
  270. GroupId: int64(req.GroupId),
  271. }
  272. return module.CattleCategoryDistribute(cowClass)
  273. }
  274. func CategoryDeleteService(keyWord string, req *models.CategoryDeleteRequest) error {
  275. switch keyWord {
  276. case "feed_delete":
  277. return module.ForageCategoryDelete(int64(req.PastureId), int64(req.GroupId))
  278. case "cow_delete":
  279. return module.CowCategoryDelete(int64(req.PastureId), int64(req.GroupId))
  280. }
  281. return nil
  282. }
  283. func FeedUsageService(req *models.FeedFormulaUsageRequest) (*models.FeedFormulaUsageResponse, error) {
  284. return module.FeedTemplateUsageDetail(req)
  285. }