group.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  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(pastureId int64, 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. if _, err = restful.Engine.Table(new(models.FeedClass).TableName()).Insert(req); err != nil {
  259. return err
  260. }
  261. }
  262. return nil
  263. }
  264. func ForageCategoryDelete(pastureId, groupId int64) error {
  265. feedClassHas := &models.FeedClass{GroupId: groupId, PastureId: pastureId}
  266. has, err := restful.Engine.Table(new(models.FeedClass).TableName()).Exist(feedClassHas)
  267. if err != nil {
  268. return err
  269. }
  270. if has {
  271. if _, err = restful.Engine.Table(new(models.FeedClass).TableName()).ID(feedClassHas.Id).Delete(feedClassHas); err != nil {
  272. return err
  273. }
  274. }
  275. return nil
  276. }
  277. func CowCategoryDelete(pastureId, groupId int64) error {
  278. cowClassHas := &models.CowClass{GroupId: groupId, PastureId: pastureId}
  279. has, err := restful.Engine.Table(new(models.CowClass).TableName()).Exist(cowClassHas)
  280. if err != nil {
  281. return err
  282. }
  283. if has {
  284. if _, err = restful.Engine.Table(new(models.CowClass).TableName()).ID(cowClassHas.Id).Delete(cowClassHas); err != nil {
  285. return err
  286. }
  287. }
  288. return nil
  289. }
  290. func FeedTemplateList(req *models.FeedListRequest) ([]*models.FeedTemplate, int64, error) {
  291. var (
  292. res []*models.FeedTemplate
  293. total int64
  294. err error
  295. )
  296. newSession := restful.Engine.NewSession()
  297. total, err = newSession.Table(new(models.FeedTemplate).TableName()).
  298. Where("pastureid = ?", req.PastureId).Count(&res)
  299. if err != nil {
  300. return nil, 0, err
  301. }
  302. if err = newSession.Table(new(models.FeedTemplate).TableName()).Limit(int(req.PageSize), int(req.Page-1)*int(req.PageSize)).Find(&res); err != nil {
  303. return nil, 0, err
  304. }
  305. return res, total, nil
  306. }
  307. func FeedList(req *models.FeedListRequest) ([]*models.Feed, int64, error) {
  308. var (
  309. res []*models.Feed
  310. total int64
  311. err error
  312. )
  313. newSession := restful.Engine.NewSession()
  314. total, err = newSession.Table(new(models.Feed).TableName()).
  315. Where("pastureid = ?", req.PastureId).Count(&res)
  316. if err != nil {
  317. return nil, 0, err
  318. }
  319. if err = newSession.Table(new(models.Feed).TableName()).Limit(int(req.PageSize), int(req.Page-1)*int(req.PageSize)).Find(&res); err != nil {
  320. return nil, 0, err
  321. }
  322. return res, total, nil
  323. }
  324. func FeedTemplateDetailList(req *models.FeedListRequest) ([]*models.FeedTemplateDetail, int64, error) {
  325. var (
  326. res []*models.FeedTemplateDetail
  327. total int64
  328. err error
  329. )
  330. newSession := restful.Engine.NewSession()
  331. total, err = newSession.Table(new(models.FeedTemplateDetail).TableName()).
  332. Where("pastureid = ?", req.PastureId).Count(&res)
  333. if err != nil {
  334. return nil, 0, err
  335. }
  336. if err = newSession.Table(new(models.FeedTemplateDetail).TableName()).Limit(int(req.PageSize), int(req.Page-1)*int(req.PageSize)).Find(&res); err != nil {
  337. return nil, 0, err
  338. }
  339. return res, total, nil
  340. }
  341. func FeedTemplateUsageDetail(req *models.FeedFormulaUsageRequest) (*models.FeedFormulaUsageResponse, error) {
  342. mixedDetail, err := getMixedDetail(req.PastureId, req.FeedFormulaId, req.StartTime, req.EndTime)
  343. if err != nil {
  344. return nil, err
  345. }
  346. sprinkleDetail, err := getSprinkleDetail(req.PastureId, req.FeedFormulaId, req.StartTime, req.EndTime)
  347. if err != nil {
  348. return nil, err
  349. }
  350. response := &models.FeedFormulaUsageResponse{
  351. MixedFodderAccurateRatio: strconv.FormatFloat(mixedDetail.MixedFodderAccurateRatio, 'f', 2, 64) + "%",
  352. MixedFodderCorrectRatio: strconv.FormatFloat(mixedDetail.MixedFodderCorrectRatio, 'f', 3, 64) + "%",
  353. SprinkleFodderAccurateRatio: strconv.FormatFloat(sprinkleDetail.SprinkleFodderAccurateRatio, 'f', 3, 64) + "%",
  354. SprinkleFodderCorrectRatio: strconv.FormatFloat(sprinkleDetail.SprinkleFodderCorrectRatio, 'f', 3, 64) + "%",
  355. AddFeedTime: "",
  356. SprinkleTime: "",
  357. StirTime: "",
  358. LastEditTime: "",
  359. }
  360. return response, nil
  361. }
  362. func getMixedDetail(pastureId, feedFormulaId int32, startTime, endTime string) (*models.MixedDetail, error) {
  363. sql := fmt.Sprintf(`SELECT * FROM (
  364. SELECT DATE(de.date) AS plan_time,
  365. IFNULL((SELECT d.templetname FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),de.fname) AS feed_formula_name,
  366. IFNULL((SELECT d.tempid FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),0) AS feed_formula_id,
  367. ROUND(SUM(de.lweight),2) AS l_weight,ROUND(SUM(de.actualweightminus),2) AS reality_weight,
  368. SUM(1) AS plan_mixed_opts,SUM(de.havebuttom) AS reality_mixed_opts,
  369. ROUND(SUM(de.havebuttom)/SUM(1)*100,2) AS mixed_ops_ratio,
  370. SUM(IF(de.buttontype =1,1,0)) AS mixed_auto_jump_number , SUM(IF(de.buttontype>1,1,0)) AS mixed_manual_jump_number ,
  371. ROUND(ABS(SUM(de.lweight)-SUM(de.actualweightminus)),2) AS mix_error_number,
  372. CONCAT( IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  373. SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2) AS mixed_fodder_accurate_ratio,
  374. IF (SUM(de.actualweightminus)>SUM(de.lweight),
  375. ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  376. ROUND((SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2)) AS hlzq,
  377. 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,
  378. ROUND(STD(ABS(de.actualweightminus-de.lweight)) ,2) AS variance_ratio,
  379. IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0)),0) AS mixed_fodder_correct_number,
  380. 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,
  381. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) hlzql,
  382. TRIM(de.pid) pid,
  383. ROUND(IFNULL(SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),
  384. 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
  385. 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'
  386. GROUP BY de.date ) tmp `, pastureId, startTime, endTime)
  387. if feedFormulaId > 0 {
  388. sql = fmt.Sprintf("%s HAVING tmp.feed_formula_id = %d", sql, feedFormulaId)
  389. }
  390. dataList := &models.MixedDetail{}
  391. if _, err := restful.Engine.NewSession().SQL(sql).Get(dataList); err != nil {
  392. return nil, err
  393. }
  394. return dataList, nil
  395. }
  396. func getSprinkleDetail(pastureId, feedFormulaId int32, startTime, endTime string) (*models.SprinkleDetail, error) {
  397. sql := fmt.Sprintf(`SELECT * FROM (SELECT DATE(d.mydate) AS plan_time,
  398. IFNULL((SELECT d.templetname FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),de.fname) AS feed_formula_name,
  399. IFNULL((SELECT d.tempid FROM downloadedplan d WHERE d.pastureid = de.pastureid AND d.id = de.pid),0) AS feed_formula_id,
  400. d.tmrtname AS tmr_name,
  401. 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,
  402. 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,
  403. SUM(de.lweight) AS l_weight,ROUND(SUM(de.actualweightminus)) AS reality_weight,
  404. SUM(1) AS plan_sprinkle_opts,
  405. SUM(de.havebuttom) AS reality_sprinkle_opts,
  406. ROUND(SUM(de.havebuttom)/SUM(1)*100,2) AS sprinkle_ops_ratio,
  407. SUM(IF(de.buttontype =1,1,0)) AS sprinkle_auto_jump_number ,
  408. SUM(IF(de.buttontype>1,1,0)) AS sprinkle_manual_jump_number ,
  409. ABS(SUM(de.actualweightminus)-SUM(de.lweight)) AS sprinkle_error_number,
  410. CONCAT( IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  411. SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2) AS sprinkle_fodder_accurate_ratio,
  412. IF (SUM(de.actualweightminus)>SUM(de.lweight),ROUND((SUM(de.lweight)/SUM(de.actualweightminus)*100),2) ,
  413. ROUND((SUM(de.actualweightminus)/SUM(de.lweight)*100) ,2)) slzq,
  414. 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,
  415. IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0)),0) AS sprinkle_fodder_correct_number,
  416. 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,
  417. ROUND(IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0))/SUM(1),0)*100,2) as slzql,
  418. TRIM(de.pid) pid,
  419. ROUND(IFNULL(SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),
  420. 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
  421. FROM downloadplandtl2 de JOIN downloadedplan d ON d.id=de.pid AND d.pastureid = de.pastureid
  422. WHERE d.pastureid = %d AND DATE(d.mydate) BETWEEN '%s' AND '%s' AND d.lpplantype IN (0,2)) tmr `, pastureId, startTime, endTime)
  423. if feedFormulaId > 0 {
  424. sql = fmt.Sprintf("%s HAVING feed_formula_id = %d", sql, feedFormulaId)
  425. }
  426. dataList := &models.SprinkleDetail{}
  427. if _, err := restful.Engine.NewSession().SQL(sql).Get(dataList); err != nil {
  428. return nil, err
  429. }
  430. return dataList, nil
  431. }
  432. func FeedFormulaVersion(pastureId int64, req *models.FeedFormulaUpdateVersionRequest) error {
  433. if req.Belong == 0 {
  434. return nil
  435. }
  436. DbSession := restful.Engine.NewSession()
  437. defer DbSession.Close()
  438. // 开启事务
  439. if err := DbSession.Begin(); err != nil {
  440. return err
  441. }
  442. feedDetailVersion := &models.FeedDetailVersion{
  443. FeedTemplateId: req.FeedTemplateId,
  444. PastureId: pastureId,
  445. GroupVersion: req.Version,
  446. Belong: req.Belong,
  447. CreatedAt: time.Now().Unix(),
  448. UpdatedAt: time.Now().Unix(),
  449. }
  450. if _, err := DbSession.Insert(feedDetailVersion); err != nil {
  451. DbSession.Rollback()
  452. return err
  453. }
  454. // FeedDetailVersionLog 更新
  455. versionLogs := make([]*models.FeedDetailVersionLog, 0)
  456. for _, v := range req.Data {
  457. versionLogs = append(versionLogs, &models.FeedDetailVersionLog{
  458. VersionId: feedDetailVersion.Id,
  459. PastureId: pastureId,
  460. FeedTemplateId: req.FeedTemplateId,
  461. ForageId: int64(v.ForageId),
  462. ForageName: v.ForageName,
  463. ForageGroupName: v.ForageGroupName,
  464. Weight: int32(v.Weight * 100),
  465. StirDelay: v.StirDelay,
  466. AllowError: v.AllowError,
  467. IsModify: v.IsModify,
  468. IsLockCowCountRatio: operationPb.IsShow_Kind(v.IsLockCowCountRatio),
  469. Sort: v.Sort,
  470. })
  471. }
  472. if _, err := DbSession.Table(new(models.FeedDetailVersionLog).TableName()).Insert(versionLogs); err != nil {
  473. DbSession.Rollback()
  474. return err
  475. }
  476. return DbSession.Commit()
  477. }
  478. func NewSearchFeedTemplateList(ctx context.Context, req *pasturePb.SearchFeedTemplateRequest) ([]*models.FeedTemplate, int64, error) {
  479. DBSession := restful.Engine.NewSession()
  480. defer DBSession.Close()
  481. res := make([]*models.FeedTemplate, 0)
  482. if req.Name != "" {
  483. DBSession.Where("name like '%?%'", req.Name)
  484. }
  485. if req.CattleCategoryId > 0 {
  486. DBSession.Where("ccid = ?", req.CattleCategoryId)
  487. }
  488. if req.FormulaTypeId > 0 {
  489. DBSession.Where("fttypeid = ?", req.FormulaTypeId)
  490. }
  491. switch req.SourceId {
  492. case 0:
  493. DBSession.Where("source = '自定义'")
  494. case 1:
  495. DBSession.Where("source = '集团下发未调整'")
  496. case 2:
  497. DBSession.Where("source = '集团下发有调整'")
  498. case 3:
  499. DBSession.Where("source = '导入'")
  500. }
  501. if req.Enable > 0 {
  502. DBSession.Where("enable = ?", req.Enable)
  503. }
  504. if req.Remark != "" {
  505. DBSession.Where("remark = ?", req.Remark)
  506. }
  507. DBSession.Desc("id")
  508. if total, err := DBSession.Count(&res); err != nil {
  509. return nil, 0, err
  510. } else {
  511. return res, total, nil
  512. }
  513. }
  514. func FeedDetailVersionLogList(ctx context.Context) ([]*models.FeedDetailVersion, error) {
  515. res := make([]*models.FeedDetailVersion, 0)
  516. if err := restful.Engine.NewSession().Find(&res); err != nil {
  517. if !errors.Is(err, xorm.ErrNotExist) {
  518. return nil, err
  519. }
  520. }
  521. return res, nil
  522. }
  523. // SearchFeedTemplateDetailListByFeedTemplateId 获取配方当前饲料列表详情
  524. func SearchFeedTemplateDetailListByFeedTemplateId(ctx context.Context, pastureId, feedTemplateId int64) ([]*models.FeedTemplateDetail, error) {
  525. res := make([]*models.FeedTemplateDetail, 0)
  526. if err := restful.Engine.Table(new(models.FeedTemplateDetail).TableName()).Where("pastureid = ?", pastureId).And("ftid = ?", feedTemplateId).Find(&res); err != nil {
  527. return nil, err
  528. }
  529. return res, nil
  530. }
  531. // GetFeedDetailVersionByDesc 获取配方最新版本数据
  532. func GetFeedDetailVersionByDesc(ctx context.Context, pastureId, feedTemplateId int64) (*models.FeedDetailVersion, error) {
  533. res := &models.FeedDetailVersion{}
  534. if _, err := restful.Engine.Table(new(models.FeedDetailVersion).TableName()).
  535. Where("pasture_id = ?", pastureId).
  536. And("feed_template_id = ?", feedTemplateId).OrderBy("id desc").Get(res); err != nil {
  537. return nil, err
  538. }
  539. return res, nil
  540. }
  541. // SearchFeedDetailVersionLogById 获取配方关联最新饲料信息
  542. func SearchFeedDetailVersionLogById(ctx context.Context, pastureId, feedTemplateId, versionId int64) ([]*models.FeedDetailVersionLog, error) {
  543. res := make([]*models.FeedDetailVersionLog, 0)
  544. if err := restful.Engine.NewSession().Table(new(models.FeedDetailVersionLog).TableName()).Where("pasture_id = ?", pastureId).
  545. And("feed_formula_id = ?", feedTemplateId).And("version = ?", versionId).Find(&res); err != nil {
  546. return nil, err
  547. }
  548. return res, nil
  549. }
  550. // FeetTemplateUpgradeNewVersion 配方更新至最新版本
  551. func FeetTemplateUpgradeNewVersion(ctx context.Context, pastureId, feedTemplateId int64) error {
  552. newFeedDetailVersion, err := GetFeedDetailVersionByDesc(ctx, pastureId, feedTemplateId)
  553. if err != nil {
  554. return err
  555. }
  556. DBSession := restful.Engine.NewSession()
  557. defer DBSession.Close()
  558. if err = DBSession.Begin(); err != nil {
  559. return err
  560. }
  561. if _, err = DBSession.Table(new(models.FeedTemplateDetail).TableName()).
  562. Where("pasture_id = ?", pastureId).
  563. And("feed_template_id = ?", feedTemplateId).Update("is_show", operationPb.IsShow_NO); err != nil {
  564. DBSession.Rollback()
  565. return err
  566. }
  567. res, err := SearchFeedDetailVersionLogById(ctx, pastureId, feedTemplateId, newFeedDetailVersion.Id)
  568. if err != nil {
  569. DBSession.Rollback()
  570. return err
  571. }
  572. if len(res) <= 0 {
  573. return DBSession.Commit()
  574. }
  575. newFtDetailList := make([]*models.FeedTemplateDetail, 0)
  576. for _, v := range res {
  577. newFtDetailList = append(newFtDetailList, &models.FeedTemplateDetail{
  578. PastureId: pastureId,
  579. FtId: feedTemplateId,
  580. FId: v.ForageId,
  581. FName: v.ForageName,
  582. FWeight: float64(v.Weight / 100),
  583. IsLockCount: int32(v.IsLockCowCountRatio),
  584. IsFg: 0,
  585. Sort: v.Sort,
  586. FeedGroup: v.ForageGroupName,
  587. PreFtId: 0,
  588. AutoSecond: v.StirDelay,
  589. AutoSecondName: "",
  590. SplitFtPreId: 0,
  591. Deviation: v.AllowError,
  592. IsModify: int32(v.IsModify),
  593. IsShow: int32(operationPb.IsShow_OK),
  594. })
  595. }
  596. if _, err = DBSession.Table(new(models.FeedTemplateDetail).TableName()).Insert(newFtDetailList); err != nil {
  597. DBSession.Rollback()
  598. return err
  599. }
  600. return DBSession.Commit()
  601. }