group.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. package module
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "strconv"
  7. "time"
  8. "tmr-watch/http/handle/restful"
  9. "tmr-watch/models"
  10. operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation"
  11. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/pasture"
  12. "github.com/xormplus/xorm"
  13. )
  14. // DistributeFeedFormula 接受集团饲料配方下发
  15. func DistributeFeedFormula(feedTemplateList []*models.FeedTemplate) error {
  16. tx := restful.Engine.NewSession()
  17. defer tx.Close()
  18. for _, feedTemplate := range feedTemplateList {
  19. // 过滤掉没有饲料详情的配方
  20. if len(feedTemplate.FeedFormulaDetail) <= 0 {
  21. continue
  22. }
  23. if _, err := tx.Table(new(models.FeedTemplate)).Insert(feedTemplate); err != nil {
  24. return err
  25. }
  26. feedFormulaDetail := make([]*models.FeedTemplateDetail, 0)
  27. for _, f := range feedTemplate.FeedFormulaDetail {
  28. f.FtId = feedTemplate.Id
  29. feedFormulaDetail = append(feedFormulaDetail, f)
  30. }
  31. if _, err := tx.Table(new(models.FeedTemplateDetail)).Insert(feedFormulaDetail); err != nil {
  32. return err
  33. }
  34. }
  35. return tx.Commit()
  36. }
  37. // CancelDistributeFeedFormula 集团饲料配方取消下发
  38. func CancelDistributeFeedFormula(pastureId int64, ids []int64) error {
  39. if _, err := restful.Engine.Table(new(models.FeedTemplate)).
  40. Where("id IN ?", ids).Where("pasture_id = ?", pastureId).Update(map[string]interface{}{"enable": 2, "is_modify": 2}); err != nil {
  41. return err
  42. }
  43. return nil
  44. }
  45. func FeedFormulaIsModify(req *models.PastureFeedFormulaIsModifyRequest) error {
  46. if _, err := restful.Engine.Table(new(models.FeedTemplate)).Cols("is_modify").
  47. Where("id = ?", req.FeedFormulaId).And("pastureid = ?", req.PastureId).
  48. Update(map[string]interface{}{"is_modify": req.IsModify}); err != nil {
  49. return err
  50. }
  51. return nil
  52. }
  53. // MixedFodderData 混料准确率
  54. func MixedFodderData(req *models.AnalysisAccuracyRequest) ([]*models.MixedFodderDataList, error) {
  55. res := make([]*models.MixedFodderDataList, 0)
  56. whereFeedFormulaIdStr := ""
  57. if req.FeedFormulaId > 0 {
  58. whereFeedFormulaIdStr = fmt.Sprintf(" AND f.ccid = %d", req.FeedFormulaId)
  59. }
  60. sql := fmt.Sprintf(`SELECT DATE(de.date) AS plan_time,
  61. CONCAT( IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2) AS mixed_fodder_accurate_ratio,
  62. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) AS mixed_fodder_correct_ratio
  63. FROM downloadplandtl1 de
  64. LEFT JOIN downloadedplan d ON d.id = de.pid
  65. LEFT JOIN feedtemplet f ON f.id = d.tempid
  66. WHERE de.pastureid= %d AND de.intime IS NOT NULL
  67. AND (SELECT d.lpplantype FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid) IN (0,1,4)
  68. AND de.date >= '%s' AND de.date <= '%s' %s GROUP BY de.date`, req.PastureId, req.StartDate, req.EndDate, whereFeedFormulaIdStr)
  69. if err := restful.Engine.SQL(sql).Find(&res); err != nil {
  70. return nil, err
  71. }
  72. return res, nil
  73. }
  74. // SprinkleFodderData 撒料准确率
  75. func SprinkleFodderData(req *models.AnalysisAccuracyRequest) ([]*models.SprinkleFodderDataList, error) {
  76. res := make([]*models.SprinkleFodderDataList, 0)
  77. whereFeedFormulaIdStr := ""
  78. if req.FeedFormulaId > 0 {
  79. whereFeedFormulaIdStr = fmt.Sprintf(" AND f.ccid = %d", req.FeedFormulaId)
  80. }
  81. sql := fmt.Sprintf(`SELECT DATE(d.mydate) AS plan_time,
  82. CONCAT( IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2),SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2) AS sprinkle_fodder_accurate_ratio,
  83. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) AS sprinkle_fodder_correct_ratio
  84. FROM downloadplandtl2 de
  85. JOIN downloadedplan d ON d.id=de.pid AND d.pastureid = de.pastureid
  86. LEFT JOIN feedtemplet f ON f.id = d.tempid
  87. WHERE de.pastureid = %d AND DATE(de.date) BETWEEN '%s' AND '%s' %s GROUP BY de.date`, req.PastureId, req.StartDate, req.EndDate, whereFeedFormulaIdStr)
  88. if err := restful.Engine.SQL(sql).Find(&res); err != nil {
  89. return nil, err
  90. }
  91. return res, nil
  92. }
  93. // TMRList tmr设备列表
  94. func TMRList(req *models.AnalysisAccuracyRequest) ([]*models.ProcessData, error) {
  95. res := make([]*models.ProcessData, 0)
  96. sql := fmt.Sprintf(`SELECT d.lpplantype as plan_type,
  97. d.tmrtname as tmr_name,
  98. f.ccid as c_cid,
  99. TRIM(d.pastureid) as pasture_id,
  100. TRIM(d.pid) as pid,
  101. TRIM(d.id) as id
  102. FROM downloadedplan d
  103. LEFT JOIN feedtemplet f on f.id = d.tempid
  104. WHERE d.pastureid= %d and d.intime IS NOT NULL
  105. AND d.mydate >= '%s' AND d.mydate <= '%s'`, req.PastureId, req.StartDate, req.EndDate)
  106. if req.CattleParentCategoryId > 0 {
  107. sql = fmt.Sprintf("%s AND f.ccid = %d", sql, req.CattleParentCategoryId)
  108. }
  109. if err := restful.Engine.SQL(sql).Find(&res); err != nil {
  110. return nil, err
  111. }
  112. return res, nil
  113. }
  114. // MixedProcessTimeList 混料时间列表
  115. func MixedProcessTimeList(pastureId int32, id int64) ([]*models.ProcessTimeList, error) {
  116. res := make([]*models.ProcessTimeList, 0)
  117. sql := fmt.Sprintf(`SELECT IFNULL(TIMEDIFF (d1.intime,(SELECT MAX(intime) FROM downloadplandtl1_exec d2
  118. WHERE d1.pid=d2.pid AND d1.pastureid = d2.pastureid AND d2.intime<d1.intime)),TIMEDIFF(intime,(SELECT MAX(intime) FROM downloadedplan d2
  119. WHERE d1.date=d2.mydate AND d1.pastureid = d2.pastureid AND d2.id=d1.pid))) AS process_time
  120. FROM downloadplandtl1_exec d1 WHERE d1.pastureid = %d AND d1.pid = %d ORDER BY sort`, pastureId, id)
  121. if err := restful.Engine.SQL(sql).Find(&res); err != nil {
  122. return nil, err
  123. }
  124. return res, nil
  125. }
  126. // SprinkleProcessTimeList 混料时间列表
  127. func SprinkleProcessTimeList(pastureId int32, id int64) ([]*models.ProcessTimeList, error) {
  128. res := make([]*models.ProcessTimeList, 0)
  129. sql := fmt.Sprintf(`SELECT IFNULL(TIMEDIFF (d1.intime,(SELECT MAX(intime) FROM downloadplandtl2 d2
  130. WHERE d1.pid=d2.pid AND d1.pastureid = d2.pastureid AND d2.intime<d1.intime)), TIMEDIFF(intime,(SELECT MAX(intime) FROM downloadplandtl1_exec d2
  131. WHERE d1.date=d2.date AND d1.pastureid = d2.pastureid AND d2.pid=d1.pid))) AS process_time FROM downloadplandtl2 d1
  132. WHERE d1.pastureid = %d AND pid =%d ORDER BY sort`, pastureId, id)
  133. if err := restful.Engine.SQL(sql).Find(&res); err != nil {
  134. return nil, err
  135. }
  136. return res, nil
  137. }
  138. func SprinkleStatistics(req *models.SprinkleStatisticsRequest) ([]*models.SprinkleStatisticsDataList, error) {
  139. res := make([]*models.SprinkleStatisticsDataList, 0)
  140. newSql := restful.Engine.Table("downloadedplan").Alias("b").
  141. Select("a.fbarid,a.fname,a.intime,a.processtime,b.times").
  142. Join("LEFT", []string{"downloadplandtl2", "a"}, "a.pastureid = b.pastureid AND b.pid = a.flpid").
  143. Where("a.pastureid = ?", req.PastureId).And("b.times > 0 ").
  144. And("a.fbarid > 0").And("a.intime IS NOT NULL").And("a.processtime IS NOT NULL")
  145. if len(req.StartDate) > 0 && len(req.EndDate) > 0 {
  146. newSql.And("a.date >= ? and a.date <= ?", req.StartDate, req.EndDate)
  147. }
  148. if req.FeedFormulaId > 0 {
  149. newSql.And("a.feedtempletid = ?", req.FeedFormulaId)
  150. }
  151. if err := newSql.GroupBy("a.fbarid ,b.intime").Limit(100).Find(&res); err != nil {
  152. return nil, err
  153. }
  154. return res, nil
  155. }
  156. func AccountDistribution(req *models.AccountDistributionRequest) error {
  157. res := &models.User{}
  158. _, err := restful.Engine.Select("pastureid,username,empname,password,phone").
  159. Where("enable = ?", operationPb.IsShow_OK).And("isdelete = ?", operationPb.IsShow_NO).And("pastureid = ?", req.PastureId).
  160. And("username = ?", req.Account).Get(res)
  161. if err != nil {
  162. return err
  163. }
  164. if res.Username == req.Account {
  165. return errors.New("该账号已经存在")
  166. }
  167. session := restful.Engine.NewSession()
  168. defer session.Close()
  169. if err = session.Begin(); err != nil {
  170. return err
  171. }
  172. // 查看牧场是否存在
  173. pastureData := &models.Pasture{}
  174. if _, err = session.Table(new(models.Pasture).TableName()).Where("pastureid = ?", req.PastureId).Get(pastureData); err != nil {
  175. return err
  176. }
  177. if pastureData.PastureId <= 0 {
  178. newPasture := models.NewPasture(int64(req.PastureId), req.PastureName, req.Address, req.UserName, req.Phone)
  179. if _, err = session.Table(new(models.Pasture).TableName()).Insert(newPasture); err != nil {
  180. return err
  181. }
  182. }
  183. // 查询牧场对应菜单是否存在
  184. menuPasture := &models.MenuPasture{}
  185. if _, err = session.Table(new(models.MenuPasture).TableName()).Where("pastureid = ?", req.PastureId).Get(menuPasture); err != nil {
  186. return err
  187. }
  188. // 创建新的超级管理员角色
  189. newRole := models.NewDefaultRole(int64(req.PastureId))
  190. if _, err = session.Table(new(models.Role).TableName()).Insert(newRole); err != nil {
  191. return err
  192. }
  193. menuList := make([]*models.Menu, 0)
  194. if err = session.Table(new(models.Menu).TableName()).Find(&menuList); err != nil {
  195. return err
  196. }
  197. if menuPasture.PastureId <= 0 {
  198. newMenuPastureList := models.NewMenuPastureList(int64(req.PastureId), menuList)
  199. if _, err = session.Table(new(models.MenuPasture).TableName()).Insert(newMenuPastureList); err != nil {
  200. return err
  201. }
  202. }
  203. NewRoleMenu := models.NewRoleMenu(int64(req.PastureId), newRole.Id, menuList)
  204. if _, err = session.Table(new(models.RoleMenu).TableName()).Insert(NewRoleMenu); err != nil {
  205. return err
  206. }
  207. // 创建用户并绑定管理员权限
  208. newUser := models.NewUser(int64(req.PastureId), req.Account, req.UserName, req.Password, req.Phone, newRole.Id)
  209. if _, err = session.Table(new(models.User).TableName()).Insert(newUser); err != nil {
  210. return err
  211. }
  212. return session.Commit()
  213. }
  214. func CattleCategoryDistribute(req *models.CowClass) error {
  215. has, err := restful.Engine.Table(new(models.CowClass).TableName()).Exist(&models.CowClass{GroupId: req.GroupId})
  216. if err != nil {
  217. return err
  218. }
  219. if has {
  220. if _, err = restful.Engine.Table(new(models.CowClass).TableName()).
  221. Where("group_id = ?", req.GroupId).
  222. Update(map[string]interface{}{
  223. "pastureid": req.PastureId,
  224. "classcode": req.ClassCode,
  225. "classname": req.ClassName,
  226. "enable": req.Enable,
  227. "parentid": req.ParentId,
  228. "parentname": req.ParentName,
  229. }); err != nil {
  230. return err
  231. }
  232. } else {
  233. if _, err = restful.Engine.Table(new(models.CowClass).TableName()).Insert(req); err != nil {
  234. return err
  235. }
  236. }
  237. return nil
  238. }
  239. func ForageCategoryDistribute(req *models.FeedClass) error {
  240. has, err := restful.Engine.Table(new(models.FeedClass).TableName()).Exist(&models.FeedClass{GroupId: req.GroupId})
  241. if err != nil {
  242. return err
  243. }
  244. if has {
  245. if _, err = restful.Engine.Table(new(models.FeedClass).TableName()).
  246. Where("group_id = ?", req.GroupId).
  247. Update(map[string]interface{}{
  248. "pastureid": req.PastureId,
  249. "fccode": req.FCCode,
  250. "fcname": req.FCName,
  251. "enable": req.Enable,
  252. "bigfeedclassid": req.BigFeedClassId,
  253. "bigfeedclassname": req.BigFeedClassName,
  254. }); err != nil {
  255. return err
  256. }
  257. } else {
  258. lastData := &models.FeedClass{}
  259. if err = restful.Engine.Table(new(models.FeedClass).TableName()).OrderBy("id desc").GetFirst(lastData).Error; err != nil {
  260. req.Id = 1
  261. } else {
  262. req.Id = lastData.Id + 1
  263. }
  264. if _, err = restful.Engine.Table(new(models.FeedClass).TableName()).Insert(req); err != nil {
  265. return err
  266. }
  267. }
  268. return nil
  269. }
  270. func ForageCategoryDelete(pastureId, groupId int64) error {
  271. feedClassHas := &models.FeedClass{GroupId: groupId, PastureId: pastureId}
  272. has, err := restful.Engine.Table(new(models.FeedClass).TableName()).Exist(feedClassHas)
  273. if err != nil {
  274. return err
  275. }
  276. if has {
  277. if _, err = restful.Engine.Table(new(models.FeedClass).TableName()).ID(feedClassHas.Id).Delete(feedClassHas); err != nil {
  278. return err
  279. }
  280. }
  281. return nil
  282. }
  283. func CowCategoryDelete(pastureId, groupId int64) error {
  284. cowClassHas := &models.CowClass{GroupId: groupId, PastureId: pastureId}
  285. has, err := restful.Engine.Table(new(models.CowClass).TableName()).Exist(cowClassHas)
  286. if err != nil {
  287. return err
  288. }
  289. if has {
  290. if _, err = restful.Engine.Table(new(models.CowClass).TableName()).ID(cowClassHas.Id).Delete(cowClassHas); err != nil {
  291. return err
  292. }
  293. }
  294. return nil
  295. }
  296. func FeedTemplateList(req *models.FeedListRequest) ([]*models.FeedTemplate, int64, error) {
  297. var (
  298. res []*models.FeedTemplate
  299. total int64
  300. err error
  301. )
  302. newSession := restful.Engine.NewSession()
  303. total, err = newSession.Table(new(models.FeedTemplate).TableName()).
  304. Where("pastureid = ?", req.PastureId).Count(&res)
  305. if err != nil {
  306. return nil, 0, err
  307. }
  308. if err = newSession.Table(new(models.FeedTemplate).TableName()).Limit(int(req.PageSize), int(req.Page-1)*int(req.PageSize)).Find(&res); err != nil {
  309. return nil, 0, err
  310. }
  311. return res, total, nil
  312. }
  313. func FeedList(req *models.FeedListRequest) ([]*models.Feed, int64, error) {
  314. var (
  315. res []*models.Feed
  316. total int64
  317. err error
  318. )
  319. newSession := restful.Engine.NewSession()
  320. total, err = newSession.Table(new(models.Feed).TableName()).
  321. Where("pastureid = ?", req.PastureId).Count(&res)
  322. if err != nil {
  323. return nil, 0, err
  324. }
  325. if err = newSession.Table(new(models.Feed).TableName()).Limit(int(req.PageSize), int(req.Page-1)*int(req.PageSize)).Find(&res); err != nil {
  326. return nil, 0, err
  327. }
  328. return res, total, nil
  329. }
  330. func FeedTemplateDetailList(req *models.FeedListRequest) ([]*models.FeedTemplateDetail, int64, error) {
  331. var (
  332. res []*models.FeedTemplateDetail
  333. total int64
  334. err error
  335. )
  336. newSession := restful.Engine.NewSession()
  337. total, err = newSession.Table(new(models.FeedTemplateDetail).TableName()).
  338. Where("pastureid = ?", req.PastureId).Count(&res)
  339. if err != nil {
  340. return nil, 0, err
  341. }
  342. if err = newSession.Table(new(models.FeedTemplateDetail).TableName()).Limit(int(req.PageSize), int(req.Page-1)*int(req.PageSize)).Find(&res); err != nil {
  343. return nil, 0, err
  344. }
  345. return res, total, nil
  346. }
  347. func FeedTemplateUsageDetail(req *models.FeedFormulaUsageRequest) (*models.FeedFormulaUsageResponse, error) {
  348. mixedDetail, err := getMixedDetail(req.PastureId, req.FeedFormulaId, req.StartTime, req.EndTime)
  349. if err != nil {
  350. return nil, err
  351. }
  352. sprinkleDetail, err := getSprinkleDetail(req.PastureId, req.FeedFormulaId, req.StartTime, req.EndTime)
  353. if err != nil {
  354. return nil, err
  355. }
  356. response := &models.FeedFormulaUsageResponse{
  357. MixedFodderAccurateRatio: strconv.FormatFloat(mixedDetail.MixedFodderAccurateRatio, 'f', 2, 64) + "%",
  358. MixedFodderCorrectRatio: strconv.FormatFloat(mixedDetail.MixedFodderCorrectRatio, 'f', 3, 64) + "%",
  359. SprinkleFodderAccurateRatio: strconv.FormatFloat(sprinkleDetail.SprinkleFodderAccurateRatio, 'f', 3, 64) + "%",
  360. SprinkleFodderCorrectRatio: strconv.FormatFloat(sprinkleDetail.SprinkleFodderCorrectRatio, 'f', 3, 64) + "%",
  361. AddFeedTime: "",
  362. SprinkleTime: "",
  363. StirTime: "",
  364. LastEditTime: "",
  365. }
  366. return response, nil
  367. }
  368. func getMixedDetail(pastureId, feedFormulaId int32, startTime, endTime string) (*models.MixedDetail, error) {
  369. sql := fmt.Sprintf(`SELECT * FROM (
  370. SELECT DATE(de.date) AS plan_time,
  371. IFNULL((SELECT d.templetname FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),de.fname) AS feed_formula_name,
  372. IFNULL((SELECT d.tempid FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),0) AS feed_formula_id,
  373. ROUND(SUM(de.lweight),2) AS l_weight,ROUND(SUM(de.actualweightminus),2) AS reality_weight,
  374. SUM(1) AS plan_mixed_opts,SUM(de.havebuttom) AS reality_mixed_opts,
  375. ROUND(SUM(de.havebuttom)/SUM(1)*100,2) AS mixed_ops_ratio,
  376. SUM(IF(de.buttontype =1,1,0)) AS mixed_auto_jump_number , SUM(IF(de.buttontype>1,1,0)) AS mixed_manual_jump_number ,
  377. ROUND(ABS(SUM(de.lweight)-SUM(de.actualweightminus)),2) AS mix_error_number,
  378. CONCAT( IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  379. SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2) AS mixed_fodder_accurate_ratio,
  380. IF (SUM(de.actualweightminus)>SUM(de.lweight),
  381. ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  382. ROUND((SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2)) AS hlzq,
  383. SUM(CASE WHEN (ABS(de.actualweightminus-de.lweight)/de.lweight)>3 AND de.lweight >30 AND de.actualweightminus >30 THEN 1 ELSE 0 END) AS cancel_number,
  384. ROUND(STD(ABS(de.actualweightminus-de.lweight)) ,2) AS variance_ratio,
  385. IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0)),0) AS mixed_fodder_correct_number,
  386. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) AS mixed_fodder_correct_ratio,
  387. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) hlzql,
  388. TRIM(de.pid) pid,
  389. ROUND(IFNULL(SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),
  390. IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0),0))/SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),1,0 )),0)*100,2) AS remove_cancel_correct_ratio
  391. FROM downloadplandtl1 de WHERE de.pastureid= %d AND de.intime IS NOT NULL AND (SELECT d.lpplantype FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid) IN (0,1,4) AND de.date >= '%s' AND de.date <= '%s'
  392. GROUP BY de.date ) tmp `, pastureId, startTime, endTime)
  393. if feedFormulaId > 0 {
  394. sql = fmt.Sprintf("%s HAVING tmp.feed_formula_id = %d", sql, feedFormulaId)
  395. }
  396. dataList := &models.MixedDetail{}
  397. if _, err := restful.Engine.NewSession().SQL(sql).Get(dataList); err != nil {
  398. return nil, err
  399. }
  400. return dataList, nil
  401. }
  402. func getSprinkleDetail(pastureId, feedFormulaId int32, startTime, endTime string) (*models.SprinkleDetail, error) {
  403. sql := fmt.Sprintf(`SELECT * FROM (SELECT DATE(d.mydate) AS plan_time,
  404. IFNULL((SELECT d.templetname FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),de.fname) AS feed_formula_name,
  405. IFNULL((SELECT d.tempid FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),0) AS feed_formula_id,
  406. d.tmrtname AS tmr_name,
  407. IFNULL(TIMEDIFF ((SELECT MAX(intime) FROM downloadplandtl2 d2 WHERE d2.pid=de.pid AND d2.pastureid = de.pastureid ),(SELECT MAX(intime) FROM downloadplandtl1_exec d2 WHERE d2.pid=de.pid AND d2.pastureid = de.pastureid )),'00:00:00') AS mixed_time,
  408. IFNULL(TIMEDIFF ((SELECT MIN(intime) FROM downloadplandtl2 d2 WHERE d2.pid=de.pid AND d2.pastureid = de.pastureid ),(SELECT MAX(intime) FROM downloadplandtl1_exec d2 WHERE d2.pid=de.pid AND d2.pastureid = de.pastureid )),'00:00:00') AS wait_time,
  409. SUM(de.lweight) AS l_weight,ROUND(SUM(de.actualweightminus)) AS reality_weight,
  410. SUM(1) AS plan_sprinkle_opts,
  411. SUM(de.havebuttom) AS reality_sprinkle_opts,
  412. ROUND(SUM(de.havebuttom)/SUM(1)*100,2) AS sprinkle_ops_ratio,
  413. SUM(IF(de.buttontype =1,1,0)) AS sprinkle_auto_jump_number ,
  414. SUM(IF(de.buttontype>1,1,0)) AS sprinkle_manual_jump_number ,
  415. ABS(SUM(de.actualweightminus)-SUM(de.lweight)) AS sprinkle_error_number,
  416. CONCAT( IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  417. SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2) AS sprinkle_fodder_accurate_ratio,
  418. IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  419. ROUND((SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2)) slzq,
  420. SUM(CASE WHEN (ABS(de.actualweightminus-de.lweight)/de.lweight)>3 AND de.lweight >30 AND de.actualweightminus >30 THEN 1 ELSE 0 END) AS cancel_number,
  421. IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0)),0) AS sprinkle_fodder_correct_number,
  422. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) AS sprinkle_fodder_correct_ratio,
  423. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) as slzql,
  424. TRIM(de.pid) pid,
  425. ROUND(IFNULL(SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),
  426. IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0),0))/SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),1,0 )),0)*100,2) AS remove_cancel_correct_ratio
  427. FROM downloadplandtl2 de JOIN downloadedplan d ON d.id=de.pid AND d.pastureid = de.pastureid
  428. WHERE d.pastureid = %d AND DATE(d.mydate) BETWEEN '%s' AND '%s' AND d.lpplantype IN (0,2)) tmr `, pastureId, startTime, endTime)
  429. if feedFormulaId > 0 {
  430. sql = fmt.Sprintf("%s HAVING feed_formula_id = %d", sql, feedFormulaId)
  431. }
  432. dataList := &models.SprinkleDetail{}
  433. if _, err := restful.Engine.NewSession().SQL(sql).Get(dataList); err != nil {
  434. return nil, err
  435. }
  436. return dataList, nil
  437. }
  438. func FeedFormulaVersion(pastureId int64, req *models.FeedFormulaUpdateVersionRequest) error {
  439. if req.Belong == 0 {
  440. return nil
  441. }
  442. DbSession := restful.Engine.NewSession()
  443. defer DbSession.Close()
  444. // 开启事务
  445. if err := DbSession.Begin(); err != nil {
  446. return err
  447. }
  448. feedDetailVersion := &models.FeedDetailVersion{
  449. FeedTemplateId: req.FeedTemplateId,
  450. PastureId: pastureId,
  451. GroupVersion: req.Version,
  452. Belong: req.Belong,
  453. CreatedAt: time.Now().Unix(),
  454. UpdatedAt: time.Now().Unix(),
  455. }
  456. if _, err := DbSession.Insert(feedDetailVersion); err != nil {
  457. DbSession.Rollback()
  458. return err
  459. }
  460. // FeedDetailVersionLog 更新
  461. versionLogs := make([]*models.FeedDetailVersionLog, 0)
  462. for _, v := range req.Data {
  463. versionLogs = append(versionLogs, &models.FeedDetailVersionLog{
  464. VersionId: feedDetailVersion.Id,
  465. PastureId: pastureId,
  466. FeedTemplateId: req.FeedTemplateId,
  467. ForageId: int64(v.ForageId),
  468. ForageName: v.ForageName,
  469. ForageGroupName: v.ForageGroupName,
  470. Weight: int32(v.Weight * 100),
  471. StirDelay: v.StirDelay,
  472. AllowError: v.AllowError,
  473. IsModify: v.IsModify,
  474. IsLockCowCountRatio: operationPb.IsShow_Kind(v.IsLockCowCountRatio),
  475. Sort: v.Sort,
  476. })
  477. }
  478. if _, err := DbSession.Table(new(models.FeedDetailVersionLog).TableName()).Insert(versionLogs); err != nil {
  479. DbSession.Rollback()
  480. return err
  481. }
  482. return DbSession.Commit()
  483. }
  484. func NewSearchFeedTemplateList(ctx context.Context, req *pasturePb.SearchFeedTemplateRequest) ([]*models.FeedTemplate, int64, error) {
  485. DBSession := restful.Engine.NewSession()
  486. defer DBSession.Close()
  487. res := make([]*models.FeedTemplate, 0)
  488. if req.Name != "" {
  489. DBSession.Where("name like '%?%'", req.Name)
  490. }
  491. if req.CattleCategoryId > 0 {
  492. DBSession.Where("ccid = ?", req.CattleCategoryId)
  493. }
  494. if req.FormulaTypeId > 0 {
  495. DBSession.Where("fttypeid = ?", req.FormulaTypeId)
  496. }
  497. switch req.SourceId {
  498. case 0:
  499. DBSession.Where("source = '自定义'")
  500. case 1:
  501. DBSession.Where("source = '集团下发未调整'")
  502. case 2:
  503. DBSession.Where("source = '集团下发有调整'")
  504. case 3:
  505. DBSession.Where("source = '导入'")
  506. }
  507. if req.Enable > 0 {
  508. DBSession.Where("enable = ?", req.Enable)
  509. }
  510. if req.Remark != "" {
  511. DBSession.Where("remark = ?", req.Remark)
  512. }
  513. DBSession.Desc("id")
  514. if total, err := DBSession.Count(&res); err != nil {
  515. return nil, 0, err
  516. } else {
  517. return res, total, nil
  518. }
  519. }
  520. func FeedDetailVersionLogList(ctx context.Context) ([]*models.FeedDetailVersion, error) {
  521. res := make([]*models.FeedDetailVersion, 0)
  522. if err := restful.Engine.NewSession().Find(&res); err != nil {
  523. if !errors.Is(err, xorm.ErrNotExist) {
  524. return nil, err
  525. }
  526. }
  527. return res, nil
  528. }
  529. // SearchFeedTemplateDetailListByFeedTemplateId 获取配方当前饲料列表详情
  530. func SearchFeedTemplateDetailListByFeedTemplateId(ctx context.Context, pastureId, feedTemplateId int64) ([]*models.FeedTemplateDetail, error) {
  531. res := make([]*models.FeedTemplateDetail, 0)
  532. if err := restful.Engine.Table(new(models.FeedTemplateDetail).TableName()).Where("pastureid = ?", pastureId).And("ftid = ?", feedTemplateId).Find(&res); err != nil {
  533. return nil, err
  534. }
  535. return res, nil
  536. }
  537. // GetFeedDetailVersionByDesc 获取配方最新版本数据
  538. func GetFeedDetailVersionByDesc(ctx context.Context, pastureId, feedTemplateId int64) (*models.FeedDetailVersion, error) {
  539. res := &models.FeedDetailVersion{}
  540. if _, err := restful.Engine.Table(new(models.FeedDetailVersion).TableName()).
  541. Where("pasture_id = ?", pastureId).
  542. And("feed_template_id = ?", feedTemplateId).OrderBy("id desc").Get(res); err != nil {
  543. return nil, err
  544. }
  545. return res, nil
  546. }
  547. // SearchFeedDetailVersionLogById 获取配方关联最新饲料信息
  548. func SearchFeedDetailVersionLogById(ctx context.Context, pastureId, feedTemplateId, versionId int64) ([]*models.FeedDetailVersionLog, error) {
  549. res := make([]*models.FeedDetailVersionLog, 0)
  550. if err := restful.Engine.NewSession().Table(new(models.FeedDetailVersionLog).TableName()).Where("pasture_id = ?", pastureId).
  551. And("feed_formula_id = ?", feedTemplateId).And("version = ?", versionId).Find(&res); err != nil {
  552. return nil, err
  553. }
  554. return res, nil
  555. }
  556. // FeetTemplateUpgradeNewVersion 配方更新至最新版本
  557. func FeetTemplateUpgradeNewVersion(ctx context.Context, pastureId, feedTemplateId int64) error {
  558. newFeedDetailVersion, err := GetFeedDetailVersionByDesc(ctx, pastureId, feedTemplateId)
  559. if err != nil {
  560. return err
  561. }
  562. DBSession := restful.Engine.NewSession()
  563. defer DBSession.Close()
  564. if err = DBSession.Begin(); err != nil {
  565. return err
  566. }
  567. if _, err = DBSession.Table(new(models.FeedTemplateDetail).TableName()).
  568. Where("pasture_id = ?", pastureId).
  569. And("feed_template_id = ?", feedTemplateId).Update("is_show", operationPb.IsShow_NO); err != nil {
  570. DBSession.Rollback()
  571. return err
  572. }
  573. res, err := SearchFeedDetailVersionLogById(ctx, pastureId, feedTemplateId, newFeedDetailVersion.Id)
  574. if err != nil {
  575. DBSession.Rollback()
  576. return err
  577. }
  578. if len(res) <= 0 {
  579. return DBSession.Commit()
  580. }
  581. newFtDetailList := make([]*models.FeedTemplateDetail, 0)
  582. for _, v := range res {
  583. newFtDetailList = append(newFtDetailList, &models.FeedTemplateDetail{
  584. PastureId: pastureId,
  585. FtId: feedTemplateId,
  586. FId: v.ForageId,
  587. FName: v.ForageName,
  588. FWeight: float64(v.Weight / 100),
  589. IsLockCount: int32(v.IsLockCowCountRatio),
  590. IsFg: 0,
  591. Sort: v.Sort,
  592. FeedGroup: v.ForageGroupName,
  593. PreFtId: 0,
  594. AutoSecond: v.StirDelay,
  595. AutoSecondName: "",
  596. SplitFtPreId: 0,
  597. Deviation: v.AllowError,
  598. IsModify: int32(v.IsModify),
  599. IsShow: int32(operationPb.IsShow_OK),
  600. })
  601. }
  602. if _, err = DBSession.Table(new(models.FeedTemplateDetail).TableName()).Insert(newFtDetailList); err != nil {
  603. DBSession.Rollback()
  604. return err
  605. }
  606. return DBSession.Commit()
  607. }