group.go 27 KB

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