ソースを参照

dashboard: 首页业务逻辑更新

Yi 1 年間 前
コミット
64ec22c541
8 ファイル変更445 行追加265 行削除
  1. 8 0
      go.mod
  2. 18 47
      go.sum
  3. 2 2
      http/routers/group_api.go
  4. 17 21
      models/group_data.go
  5. 62 101
      module/group.go
  6. 204 0
      pkg/logger/logrus/log.go
  7. 80 0
      pkg/logger/zaplog/log.go
  8. 54 94
      service/group/group.go

+ 8 - 0
go.mod

@@ -22,15 +22,18 @@ require (
 	github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4
 	github.com/json-iterator/go v1.1.12
 	github.com/kardianos/service v1.2.2
+	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
 	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
 	github.com/patrickmn/go-cache v2.1.0+incompatible
 	github.com/pkg/errors v0.9.1
 	github.com/recoilme/slowpoke v2.0.1+incompatible
 	github.com/robfig/cron v1.2.0
+	github.com/sirupsen/logrus v1.4.2
 	github.com/swaggo/gin-swagger v1.2.0
 	github.com/swaggo/swag v1.16.1
 	github.com/tealeg/xlsx v1.0.5
 	github.com/xormplus/xorm v0.0.0-20210822100304-4e1d4fcc1e67
+	go.uber.org/zap v1.24.0
 )
 
 require (
@@ -63,9 +66,12 @@ require (
 	github.com/golang-sql/sqlexp v0.1.0 // indirect
 	github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
+	github.com/jonboulle/clockwork v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/klauspost/cpuid/v2 v2.2.4 // indirect
+	github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
 	github.com/leodido/go-urn v1.2.4 // indirect
+	github.com/lestrrat-go/strftime v1.0.6 // indirect
 	github.com/mailru/easyjson v0.7.6 // indirect
 	github.com/mattn/go-isatty v0.0.19 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -78,6 +84,8 @@ require (
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	github.com/ugorji/go/codec v1.2.11 // indirect
 	github.com/xormplus/builder v0.0.0-20200331055651-240ff40009be // indirect
+	go.uber.org/atomic v1.7.0 // indirect
+	go.uber.org/multierr v1.6.0 // indirect
 	golang.org/x/arch v0.3.0 // indirect
 	golang.org/x/crypto v0.9.0 // indirect
 	golang.org/x/net v0.10.0 // indirect

+ 18 - 47
go.sum

@@ -49,6 +49,7 @@ github.com/axetroy/go-fs v1.0.0 h1:un0mpbpYjOQirgdlKlZlzTjF30DZwYwK+ObWMxubAXA=
 github.com/axetroy/go-fs v1.0.0/go.mod h1:Z4DMBpJRluxG178MMNZvixPIL2+j6nh+tBX0nGQeFDY=
 github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
 github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
+github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -57,7 +58,6 @@ github.com/bndr/gotabulate v1.1.2/go.mod h1:0+8yUgaPTtLRTjf49E8oju7ojpU11YmXyvq1
 github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
 github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
 github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
-github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
 github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
 github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
 github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
@@ -76,7 +76,6 @@ github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:T
 github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
 github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
 github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -149,7 +148,6 @@ github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyr
 github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
 github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
 github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
-github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
 github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
 github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
 github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
@@ -157,7 +155,6 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
 github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
 github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
-github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
 github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
 github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
 github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
@@ -167,7 +164,6 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt
 github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
-github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -222,6 +218,8 @@ github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4/go.mod h1:2RvX5Z
 github.com/jinzhu/gorm v1.9.10/go.mod h1:Kh6hTsSGffh4ui079FHrR5Gg+5D0hgihqDcsDN2BBJY=
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
+github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -238,6 +236,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
 github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -252,6 +251,12 @@ github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDu
 github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
 github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
 github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
+github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
+github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -263,7 +268,6 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
 github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
@@ -301,10 +305,8 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
 github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
-github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
 github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
 github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
@@ -342,17 +344,16 @@ github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfm
 github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
 github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
 github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
 github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
 github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
 github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
@@ -390,26 +391,29 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2
 github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
 github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
-github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
 github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
 github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
-github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
 github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
 github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
 github.com/xormplus/builder v0.0.0-20200331055651-240ff40009be h1:HTSana2sMSKVze3XXYrF89w2tw835Fh+7xX5KPvAkuo=
 github.com/xormplus/builder v0.0.0-20200331055651-240ff40009be/go.mod h1:PgBA7NoHtnttVkWModa/qpvIWkX6MpOKgyRCWsSKSB0=
 github.com/xormplus/xorm v0.0.0-20210822100304-4e1d4fcc1e67 h1:POBVR/O5wPVI0u7ZZGqu+HFPVTYpZlSL3Uo/9g+he/w=
 github.com/xormplus/xorm v0.0.0-20210822100304-4e1d4fcc1e67/go.mod h1:+v6b10b4x5IcQmp1/Cbo9IqaknxVeuhQng+fhya6bdI=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
 go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
 go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
+go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
+go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
 golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
@@ -420,20 +424,14 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
 golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
 golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
-golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -455,11 +453,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
 golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -471,7 +464,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -500,31 +492,17 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
-golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -535,12 +513,8 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
 golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
@@ -559,7 +533,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
 google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@@ -583,7 +556,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -599,4 +571,3 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
-sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

+ 2 - 2
http/routers/group_api.go

@@ -16,8 +16,8 @@ func GroupAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		apiPasture.POST("feed_formula/distribute", group.DistributeFeedFormula)       // 饲料配方下发
 		apiPasture.POST("feed_formula/is_modify", group.FeedFormulaIsModify)          // 饲料配方是否可修改
 		apiPasture.POST("feed_formula/list", group.FeedFormulaList)                   // 获取配方列表
-		apiPasture.POST("dashboard/accuracy_data", group.AnalysisAccuracy)            // 混料准确率数据
-		apiPasture.POST("dashboard/process_analysis", group.ProcessAnalysis)          // 过程分析
+		apiPasture.POST("dashboard/accuracy_data", group.AnalysisAccuracy)            // 准确率分析
+		apiPasture.POST("dashboard/process_analysis", group.ProcessAnalysis)          // 执行时间
 		apiPasture.POST("dashboard/sprinkle_statistics", group.SprinkleStatistics)    // 撒料统计
 		apiPasture.POST("forage_category/distribute", group.ForageCategoryDistribute) // 饲料分类下发
 		apiPasture.POST("forage_category/delete", group.ForageCategoryDelete)         // 饲料分类删除

+ 17 - 21
models/group_data.go

@@ -46,21 +46,15 @@ type AnalysisAccuracyRequest struct {
 }
 
 type MixedFodderDataList struct {
-	ActualWeightMinus float64   `xorm:"actualweightminus" json:"actualweightminus"`
-	Lweight           float64   `xorm:"lweight" json:"lweight"`
-	Date              time.Time `xorm:"date" json:"date"`
+	PlanTime                 string  `xorm:"plan_time" json:"plan_time"`
+	MixedFodderAccurateRatio float64 `xorm:"mixed_fodder_accurate_ratio" json:"mixed_fodder_accurate_ratio"`
+	MixedFodderCorrectRatio  float64 `xorm:"mixed_fodder_correct_ratio" json:"mixed_fodder_correct_ratio"`
 }
 
-type MixedFodderCorrectDataList struct {
-	UseMixedFodderOptionNumber int32  `xorm:"use_mixed_fodder_option_number" json:"use_mixed_fodder_option_number"` // 已混料操作数
-	Date                       string `xorm:"date" json:"date"`                                                     // 日期
-	MixedCorrectNumber         int32  `xorm:"mixed_correct_number" json:"mixed_correct_number"`                     // 混料正确数
-}
-
-type SprinkleFodderCorrectDataList struct {
-	UseSprinkleOptionNumber int32  `xorm:"use_sprinkle_option_number" json:"use_sprinkle_option_number"` // 已撒料操作数
-	Date                    string `xorm:"date" json:"date"`                                             // 日期
-	SprinkleCorrectNumber   int32  `xorm:"sprinkle_correct_number" json:"sprinkle_correct_number"`       // 撒料正确数
+type SprinkleFodderDataList struct {
+	PlanTime                    string  `xorm:"plan_time" json:"plan_time"`
+	SprinkleFodderAccurateRatio float64 `xorm:"sprinkle_fodder_accurate_ratio" json:"sprinkle_fodder_accurate_ratio"`
+	SprinkleFodderCorrectRatio  float64 `xorm:"sprinkle_fodder_correct_ratio" json:"sprinkle_fodder_correct_ratio"`
 }
 
 type AnalysisAccuracyResponse struct {
@@ -90,14 +84,16 @@ type ProcessAnalysisDataValue struct {
 }
 
 type ProcessData struct {
-	Id              int64     `xorm:"id" json:"id"`
-	ExecBeginTime   time.Time `xorm:"exec_begin_time" json:"exec_begin_time"`
-	ExecEndTime     time.Time `xorm:"exec_end_time" json:"exec_end_time"`
-	ExecProcessTime string    `xorm:"exec_process_time" json:"exec_process_time"`
-	ExecStirDelay   int       `xorm:"exec_stir_delay" json:"exec_stir_delay"`
-	L2BeginTime     time.Time `xorm:"l2_begin_time"  json:"l2_begin_time"`
-	L2EndTime       time.Time `xorm:"l2_end_time"  json:"l2_end_time"`
-	L2ProcessTime   string    `xorm:"l2_process_time" json:"l2_process_time"`
+	Id        int64  `xorm:"id" json:"id"`
+	Pid       int64  `xorm:"pid" json:"pid"`
+	PlanType  int32  `xorm:"plan_type" json:"plan_type"`
+	TmrName   string `xorm:"tmr_name" json:"tmr_name"`
+	CCid      int32  `xorm:"c_cid" json:"c_cid"`
+	PastureId int32  `xorm:"pasture_id" json:"pasture_id"`
+}
+
+type ProcessTimeList struct {
+	ProcessTime string `xorm:"process_time" json:"process_time"`
 }
 
 type SprinkleStatisticsRequest struct {

+ 62 - 101
module/group.go

@@ -34,23 +34,20 @@ func FeedFormulaIsModify(req *models.PastureFeedFormulaIsModifyRequest) error {
 // MixedFodderData 混料准确率
 func MixedFodderData(req *models.AnalysisAccuracyRequest) ([]*models.MixedFodderDataList, error) {
 	res := make([]*models.MixedFodderDataList, 0)
-	newSql := restful.Engine.NewSession().Table("downloadplandtl1").Alias("dp1").
-		Select(" dp1.actualweightminus,dp1.lweight,dp1.date ").
-		Join("LEFT", []string{"feedtemplet", "ft"}, "dp1.fid = ft.id").
-		Where("dp1.pastureid = ?", req.PastureId)
-
-	if len(req.StartDate) > 0 && len(req.EndDate) > 0 {
-		newSql.And("dp1.date >= ? and  dp1.date <= ?", req.StartDate, req.EndDate)
-	}
-
-	if req.CattleParentCategoryId > 0 {
-		newSql.And("ft.ccid = ?", req.CattleParentCategoryId)
-	}
-
+	whereFeedFormulaIdStr := ""
 	if req.FeedFormulaId > 0 {
-		newSql.And("dp1.fid = ?", req.FeedFormulaId)
-	}
-	if err := newSql.GroupBy("dp1.date").OrderBy("dp1.date").Find(&res); err != nil {
+		whereFeedFormulaIdStr = fmt.Sprintf(" AND  f.ccid = %d", req.FeedFormulaId)
+	}
+	sql := fmt.Sprintf(`SELECT DATE(de.date) AS plan_time,
+    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,
+	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
+	FROM downloadplandtl1 de 
+ 	LEFT JOIN downloadedplan d ON d.id = de.pid
+ 	LEFT JOIN feedtemplet f ON f.id = d.tempid
+	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' %s GROUP BY de.date`, req.PastureId, req.StartDate, req.EndDate, whereFeedFormulaIdStr)
+	if err := restful.Engine.SQL(sql).Find(&res); err != nil {
 		return nil, err
 	}
 
@@ -58,109 +55,65 @@ func MixedFodderData(req *models.AnalysisAccuracyRequest) ([]*models.MixedFodder
 }
 
 // SprinkleFodderData 撒料准确率
-func SprinkleFodderData(req *models.AnalysisAccuracyRequest) ([]*models.MixedFodderDataList, error) {
-	res := make([]*models.MixedFodderDataList, 0)
-	newSql := restful.Engine.NewSession().Table("downloadplandtl2").Alias("dp2").
-		Select("dp2.actualweightminus , dp2.lweight,  dp2.date").
-		Join("LEFT", []string{"feedtemplet", "ft"}, "dp2.feedtempletid = ft.id").
-		Where("dp2.pastureid = ?", req.PastureId)
-
-	if len(req.StartDate) > 0 && len(req.EndDate) > 0 {
-		newSql.And("dp2.date >= ? and  dp2.date <= ?", req.StartDate, req.EndDate)
-	}
-
-	if req.CattleParentCategoryId > 0 {
-		newSql.And("ft.ccid = ?", req.CattleParentCategoryId)
-	}
-
+func SprinkleFodderData(req *models.AnalysisAccuracyRequest) ([]*models.SprinkleFodderDataList, error) {
+	res := make([]*models.SprinkleFodderDataList, 0)
+	whereFeedFormulaIdStr := ""
 	if req.FeedFormulaId > 0 {
-		newSql.And("dp2.feedtempletid = ?", req.FeedFormulaId)
-	}
-	if err := newSql.GroupBy("dp2.date").OrderBy("dp2.date").Find(&res); err != nil {
+		whereFeedFormulaIdStr = fmt.Sprintf(" AND  f.ccid = %d", req.FeedFormulaId)
+	}
+	sql := fmt.Sprintf(`SELECT DATE(d.mydate) AS plan_time,
+		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,
+		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
+		FROM downloadplandtl2 de 
+		JOIN downloadedplan d ON d.id=de.pid AND d.pastureid = de.pastureid 
+		LEFT JOIN feedtemplet f ON f.id = d.tempid
+		WHERE  de.pastureid = %d AND DATE(de.date)  BETWEEN '%s' AND '%s' %s GROUP BY de.date`, req.PastureId, req.StartDate, req.EndDate, whereFeedFormulaIdStr)
+	if err := restful.Engine.SQL(sql).Find(&res); err != nil {
 		return nil, err
 	}
-
 	return res, nil
 }
 
-// MixedFodderCorrectData 混料正确率
-// SELECT
-//SUM(de.havebuttom) AS "已混料操作数",de.date,
-//IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0)),0) AS "混料正确数"
-//FROM downloadplandtl1 de LEFT JOIN feedtemplet ft ON ft.id = de.fid
-//WHERE de.pastureid = 1653271339
-//AND ft.id =20 AND ft.ccid = ?
-//GROUP BY de.date ORDER BY de.date
-func MixedFodderCorrectData(req *models.AnalysisAccuracyRequest) ([]*models.MixedFodderCorrectDataList, error) {
-	res := make([]*models.MixedFodderCorrectDataList, 0)
-	newSql := restful.Engine.NewSession().Table("downloadplandtl1").Alias("de").
-		Select("SUM(de.havebuttom) AS use_mixed_fodder_option_number,de.date,IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.feedallowratio AND de.actualweightminus<>0,1,0)),0) AS mixed_correct_number").
-		Join("LEFT", []string{"feedtemplet", "ft"}, "ft.id = de.fid").
-		Where("de.pastureid = ?", req.PastureId)
-
-	if len(req.StartDate) > 0 && len(req.EndDate) > 0 {
-		newSql.And("de.date >= ? and  de.date <= ?", req.StartDate, req.EndDate)
-	}
-
+// TMRList tmr设备列表
+func TMRList(req *models.AnalysisAccuracyRequest) ([]*models.ProcessData, error) {
+	res := make([]*models.ProcessData, 0)
+	sql := fmt.Sprintf(`SELECT d.lpplantype  as plan_type,d.tmrtname as tmr_name,f.ccid as c_cid,TRIM(d.pastureid) as pasture_id,TRIM(d.pid) as pid,TRIM(d.id) as id
+ 			FROM downloadedplan d LEFT JOIN  feedtemplet f on  f.id = d.tempid WHERE d.pastureid= %d and d.intime IS NOT NULL
+			AND d.mydate >= '%s' AND d.mydate <= '%s'`, req.PastureId, req.StartDate, req.EndDate)
 	if req.CattleParentCategoryId > 0 {
-		newSql.And("ft.ccid = ?", req.CattleParentCategoryId)
+		sql = fmt.Sprintf("%s AND f.ccid = %d", sql, req.CattleParentCategoryId)
 	}
 
-	if req.FeedFormulaId > 0 {
-		newSql.And("de.tempid = ?", req.FeedFormulaId)
-	}
-	if err := newSql.GroupBy("de.date").OrderBy("de.date").Find(&res); err != nil {
+	if err := restful.Engine.SQL(sql).Find(res); err != nil {
 		return nil, err
 	}
+
 	return res, nil
 }
 
-func SprinkleFodderCorrectData(req *models.AnalysisAccuracyRequest) ([]*models.SprinkleFodderCorrectDataList, error) {
-	res := make([]*models.SprinkleFodderCorrectDataList, 0)
-	newSql := restful.Engine.NewSession().Table("downloadplandtl2").Alias("de").
-		Select("SUM(de.havebuttom) AS use_sprinkle_option_number,de.date,IFNULL(SUM(IF(ABS(de.actualweightminus-de.lweight)<=de.allowratio AND de.actualweightminus<>0,1,0)),0) AS sprinkle_correct_number").
-		Join("LEFT", []string{"feedtemplet", "ft"}, "ft.id = de.feedtempletid").
-		Where("de.pastureid = ?", req.PastureId)
-
-	if len(req.StartDate) > 0 && len(req.EndDate) > 0 {
-		newSql.And("de.date >= ? and  de.date <= ?", req.StartDate, req.EndDate)
-	}
-
-	if req.CattleParentCategoryId > 0 {
-		newSql.And("ft.ccid = ?", req.CattleParentCategoryId)
-	}
-
-	if req.FeedFormulaId > 0 {
-		newSql.And("de.tempid = ?", req.FeedFormulaId)
-	}
-	if err := newSql.GroupBy("de.date").OrderBy("de.date").Find(&res); err != nil {
+// MixedProcessTimeList 混料时间列表
+func MixedProcessTimeList(pastureId int32, id int64) ([]*models.ProcessTimeList, error) {
+	res := make([]*models.ProcessTimeList, 0)
+	sql := fmt.Sprintf(`SELECT IFNULL(TIMEDIFF (d1.intime,(SELECT MAX(intime) FROM downloadplandtl1_exec d2 
+			WHERE  d1.pid=d2.pid AND d1.pastureid = d2.pastureid AND d2.intime<d1.intime)),TIMEDIFF(intime,(SELECT MAX(intime) FROM downloadedplan d2 
+			WHERE  d1.date=d2.mydate AND d1.pastureid = d2.pastureid AND d2.id=d1.pid))) AS proess_time
+			FROM downloadplandtl1_exec d1 WHERE d1.pastureid = %d AND d1.pid = %d ORDER BY sort`, pastureId, id)
+	if err := restful.Engine.SQL(sql).Find(res); err != nil {
 		return nil, err
 	}
 	return res, nil
 }
 
-func ProcessAnalysisData(req *models.AnalysisAccuracyRequest) ([]*models.ProcessData, error) {
-	res := make([]*models.ProcessData, 0)
-	newSql := restful.Engine.Table("downloadplandtl1_exec").Alias("e").
-		Select("e.id,e.begintime as exec_begin_time,e.intime as exec_end_time,e.processtime as exec_process_time,e.stirdelay as exec_stir_delay ,l2.begintime as l2_begin_time,l2.intime as l2_end_time,l2.processtime as l2_process_time").
-		Join("LEFT", []string{"downloadplandtl2", "l2"}, "e.pastureid = l2.pastureid and e.pid = l2.pid").
-		Where("e.pastureid = ?", req.PastureId)
-
-	if len(req.StartDate) > 0 && len(req.EndDate) > 0 {
-		newSql.And("e.date >= ? and  e.date <= ?", req.StartDate, req.EndDate)
-	}
-
-	if req.CattleParentCategoryId > 0 {
-		newSql.And("l2.cowclassid = ?", req.CattleParentCategoryId)
-	}
-
-	if req.FeedFormulaId > 0 {
-		newSql.And("l2.feedtempletid = ?", req.FeedFormulaId)
-	}
-	if err := newSql.GroupBy("e.date").OrderBy("e.date").Find(&res); err != nil {
+// SprinkleProcessTimeList 混料时间列表
+func SprinkleProcessTimeList(pastureId int32, id int64) ([]*models.ProcessTimeList, error) {
+	res := make([]*models.ProcessTimeList, 0)
+	sql := fmt.Sprintf(`SELECT IFNULL(TIMEDIFF (d1.intime,(SELECT MAX(intime) FROM downloadplandtl2 d2 
+    WHERE  d1.pid=d2.pid AND d1.pastureid = d2.pastureid AND d2.intime<d1.intime)), IMEDIFF(intime,(SELECT MAX(intime) FROM downloadplandtl1_exec d2 
+	WHERE  d1.date=d2.date AND d1.pastureid = d2.pastureid AND d2.pid=d1.pid))) AS proess_time FROM downloadplandtl2 d1
+	WHERE d1.pastureid = %d AND pid =%d ORDER BY sort`, pastureId, id)
+	if err := restful.Engine.SQL(sql).Find(res); err != nil {
 		return nil, err
 	}
-
 	return res, nil
 }
 
@@ -404,7 +357,11 @@ func getMixedDetail(pastureId, feedFormulaId int32, startTime, endTime string) (
 		ROUND(IFNULL(SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),
 		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
 		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'
-		GROUP BY de.date ) tmp HAVING tmp.feed_formula_id = %d`, pastureId, startTime, endTime, feedFormulaId)
+		GROUP BY de.date ) tmp `, pastureId, startTime, endTime)
+
+	if feedFormulaId > 0 {
+		sql = fmt.Sprintf("%s HAVING tmp.feed_formula_id = %d", sql, feedFormulaId)
+	}
 	dataList := &models.MixedDetail{}
 	if _, err := restful.Engine.NewSession().SQL(sql).Get(dataList); err != nil {
 		return nil, err
@@ -437,8 +394,12 @@ func getSprinkleDetail(pastureId, feedFormulaId int32, startTime, endTime string
 		TRIM(de.pid) pid,
 		ROUND(IFNULL(SUM(IF(((ABS(de.actualweightminus-de.lweight)/de.lweight)<=3 OR (de.lweight <30 AND de.actualweightminus <30 )),
 		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 
-		FROM downloadplandtl2 de JOIN downloadedplan d ON d.id=de.pid AND d.pastureid = de.pastureid WHERE  d.pastureid = %d AND DATE(d.mydate)  BETWEEN '%s' AND '%s'   AND d.lpplantype IN (0,2)) tmr HAVING  feed_formula_id = %d`,
-		pastureId, startTime, endTime, feedFormulaId)
+		FROM downloadplandtl2 de JOIN downloadedplan d ON d.id=de.pid AND d.pastureid = de.pastureid 
+		WHERE  d.pastureid = %d AND DATE(d.mydate)  BETWEEN '%s' AND '%s'   AND d.lpplantype IN (0,2)) tmr `, pastureId, startTime, endTime)
+
+	if feedFormulaId > 0 {
+		sql = fmt.Sprintf("%s HAVING  feed_formula_id = %d", sql, feedFormulaId)
+	}
 	dataList := &models.SprinkleDetail{}
 	if _, err := restful.Engine.NewSession().SQL(sql).Get(dataList); err != nil {
 		return nil, err

+ 204 - 0
pkg/logger/logrus/log.go

@@ -0,0 +1,204 @@
+package logrus
+
+import (
+	"fmt"
+	"kpt-tmr-group/pkg/tool"
+	"path"
+	"runtime"
+	"time"
+
+	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
+	"github.com/sirupsen/logrus"
+)
+
+var (
+	logPath     = "./logger"
+	logFileName = fmt.Sprintf("/logrus-%s.log", time.Now().Format(tool.DateTime))
+)
+
+func init() {
+	// Log as JSON instead of the default ASCII formatter.
+	logrus.SetFormatter(&logrus.JSONFormatter{
+		CallerPrettyfier: func(f *runtime.Frame) (string, string) {
+			filename := path.Base(f.File)
+			return fmt.Sprintf("%s()", f.Function), fmt.Sprintf("%s:%d", filename, f.Line)
+		},
+	})
+
+	// Output to stdout instead of the default stderr
+	// Can be any io.Writer, see below for File example
+	writer, _ := rotatelogs.New(
+		fmt.Sprintf("%s%s", logPath, logFileName),
+		// rotatelogs.WithLinkName(logPath),
+		rotatelogs.WithMaxAge(time.Duration(7*24)*time.Hour),     // 备份7天的日志
+		rotatelogs.WithRotationTime(time.Duration(24)*time.Hour), // 24小时切割一次日志
+	)
+	logrus.SetOutput(writer) // logrus 设置日志的输出方式
+	// Only log the warning severity or above.
+	logrus.SetLevel(DebugLevel)
+}
+
+// These are the different logging levels. You can set the logging level to log
+// on your instance of logger, obtained with `logrus.New()`.
+const (
+	// PanicLevel level, highest level of severity. Logs and then calls panic with the
+	// message passed to Debug, Info, ...
+	PanicLevel Level = iota
+	// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
+	// logging level is set to Panic.
+	FatalLevel
+	// ErrorLevel level. Logs. Used for errors that should definitely be noted.
+	// Commonly used for hooks to send errors to an error tracking service.
+	ErrorLevel
+	// WarnLevel level. Non-critical entries that deserve eyes.
+	WarnLevel
+	// InfoLevel level. General operational entries about what's going on inside the
+	// application.
+	InfoLevel
+	// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
+	DebugLevel
+	// TraceLevel level. Designates finer-grained informational events than the Debug.
+	TraceLevel
+)
+
+// Entry is the final or intermediate Logrus logging entry. It contains all
+// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
+// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
+// passed around as much as you wish to avoid field duplication.
+type Entry = logrus.Entry
+
+// Fields type, used to pass to `WithFields`.
+type Fields = logrus.Fields
+
+// FieldMap allows customization of the key names for default fields.
+type FieldMap = logrus.FieldMap
+
+// Level type
+type Level = logrus.Level
+
+// Logger type
+type Logger = logrus.Logger
+
+// JSONFormatter formats logs into parsable json
+type JSONFormatter struct {
+	logrus.JSONFormatter
+}
+
+// TextFormatter formats logs into text
+type TextFormatter struct {
+	logrus.TextFormatter
+}
+
+// Formatter
+// The Formatter interface is used to implement a custom Formatter. It takes an
+// `Entry`. It exposes all the fields, including the default ones:
+//
+// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
+// * `entry.Data["time"]`. The timestamp.
+// * `entry.Data["level"]. The level the entry was logged at.
+//
+// Any additional fields added with `WithField` or `WithFields` are also in
+// `entry.Data`. Format is expected to return an array of bytes which are then
+// logged to `logger.Out`.
+
+// SetLevel ...
+func SetLevel(level Level) {
+	logrus.SetLevel(level)
+}
+
+// NewWithFields returns a logrus Entry with fields
+func NewWithFields(fields Fields) *Entry {
+	return logrus.WithFields(fields)
+}
+
+// NewEntry return an entry is the final or intermediate Logrus logging entry
+func NewEntry(logger *Logger) *Entry {
+	return logrus.NewEntry(logger)
+}
+
+// Exported from logrus
+var (
+	// Creates a new logger. Configuration should be set by changing `Formatter`,
+	// `Out` and `Hooks` directly on the default logger instance. You can also just
+	// instantiate your own:
+	//
+	//    var log = &Logger{
+	//      Out: os.Stderr,
+	//      Formatter: new(JSONFormatter),
+	//      Level: logrus.DebugLevel,
+	//    }
+	//
+	// It's recommended to make this a global instance called `log`.
+	New = logrus.New
+	// StandardLogger default logger
+	StandardLogger = logrus.StandardLogger
+	// SetOutput sets the standard logger output.
+	SetOutput = logrus.SetOutput
+	// SetFormatter sets the standard logger formatter.
+	SetFormatter = logrus.SetFormatter
+	// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
+	WithError = logrus.WithError
+	// WithField creates an entry from the standard logger and adds a field to
+	// it. If you want multiple fields, use `WithFields`.
+	//
+	// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
+	// or Panic on the Entry it returns.
+	WithField = logrus.WithField
+	// WithFields creates an entry from the standard logger and adds multiple
+	// fields to it. This is simply a helper for `WithField`, invoking it
+	// once for each field.
+	//
+	// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
+	// or Panic on the Entry it returns.
+	WithFields = logrus.WithFields
+
+	// Debug logs a message at level Debug on the standard logger.
+	Debug = logrus.Debug
+	// Print logs a message at level Info on the standard logger.
+	Print = logrus.Print
+	// Info logs a message at level Info on the standard logger.
+	Info = logrus.Info
+	// Warn logs a message at level Warn on the standard logger.
+	Warn = logrus.Warn
+	// Warning logs a message at level Warn on the standard logger.
+	Warning = logrus.Warning
+	// Error logs a message at level Error on the standard logger.
+	Error = logrus.Error
+	// Panic logs a message at level Panic on the standard logger.
+	Panic = logrus.Panic
+	// Fatal logs a message at level Fatal on the standard logger.
+	Fatal = logrus.Fatal
+
+	// Debugf logs a message at level Debug on the standard logger.
+	Debugf = logrus.Debugf
+	// Printf logs a message at level Info on the standard logger.
+	Printf = logrus.Printf
+	// Infof logs a message at level Info on the standard logger.
+	Infof = logrus.Infof
+	// Warnf logs a message at level Warn on the standard logger.
+	Warnf = logrus.Warnf
+	// Warningf logs a message at level Warn on the standard logger.
+	Warningf = logrus.Warningf
+	// Errorf logs a message at level Error on the standard logger.
+	Errorf = logrus.Errorf
+	// Panicf logs a message at level Panic on the standard logger.
+	Panicf = logrus.Panicf
+	// Fatalf logs a message at level Fatal on the standard logger.
+	Fatalf = logrus.Fatalf
+	// Debugln logs a message at level Debug on the standard logger.
+	Debugln = logrus.Debugln
+	// Println logs a message at level Info on the standard logger.
+	Println = logrus.Println
+	// Infoln logs a message at level Info on the standard logger.
+	Infoln = logrus.Infoln
+	// Warnln logs a message at level Warn on the standard logger.
+	Warnln = logrus.Warnln
+	// Warningln logs a message at level Warn on the standard logger.
+	Warningln = logrus.Warningln
+	// Errorln logs a message at level Error on the standard logger.
+	Errorln = logrus.Errorln
+	// Panicln logs a message at level Panic on the standard logger.
+	Panicln = logrus.Panicln
+	// Fatalln logs a message at level Fatal on the standard logger.
+	Fatalln = logrus.Fatalln
+)

+ 80 - 0
pkg/logger/zaplog/log.go

@@ -0,0 +1,80 @@
+package zaplog
+
+import (
+	"fmt"
+	"path"
+	"runtime"
+	"strings"
+
+	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+)
+
+var (
+	Logger          *zap.Logger
+	logInfoFileName = fmt.Sprintf("./logger/zap-info.log")
+	logErrFileName  = fmt.Sprintf("./logger/zap-err.log")
+)
+
+func init() {
+	encoderConfig := zap.NewDevelopmentEncoderConfig()
+	// 设置日志时间格式
+	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
+	// 日志encoder 还是json encode,把日志进行格式化json格式的
+	encoder := zapcore.NewJSONEncoder(encoderConfig)
+
+	// topicErrors := zapcore.AddSync(ioutil.Discard)  //kafka topic
+	fileInfoWriteSyncer := getFileLogWriter(logInfoFileName)
+	fileErrWriteSyncer := getFileLogWriter(logErrFileName)
+	core := zapcore.NewTee(
+		// zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),  // 打印到控制台
+		// zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), topicErrors, zapcore.ErrorLevel),   // 打印到kafka 待验证
+		zapcore.NewCore(encoder, fileInfoWriteSyncer, zapcore.InfoLevel), // 打印到指定的日志文件
+		zapcore.NewCore(encoder, fileErrWriteSyncer, zapcore.ErrorLevel), // 打印到指定的日志文件
+	)
+	Logger = zap.New(core)
+}
+
+func getFileLogWriter(logFileName string) zapcore.WriteSyncer {
+	lumberRotateLogs, err := rotatelogs.New(
+		strings.Replace(logFileName, ".log", "", -1)+"-%Y%m%d.log",
+		rotatelogs.WithLinkName(logFileName),
+		rotatelogs.WithRotationCount(2),        // 2天的日志
+		rotatelogs.WithRotationSize(210000000), // 一个文件200MB
+	)
+	if err != nil {
+		panic(err)
+	}
+	return zapcore.AddSync(lumberRotateLogs)
+}
+
+func getCallerInfoForLog() (callerFields []zap.Field) {
+	pc, file, line, ok := runtime.Caller(2)
+	if !ok {
+		return
+	}
+	funcName := runtime.FuncForPC(pc).Name()
+	funcName = path.Base(funcName)
+
+	callerFields = append(callerFields, zap.String("func", funcName), zap.String("file", file), zap.Int("line", line))
+	return
+}
+
+func Info(message string, fields ...zap.Field) {
+	callerFields := getCallerInfoForLog()
+	fields = append(fields, callerFields...)
+	Logger.Info(message, fields...)
+}
+
+func Debug(message string, fields ...zap.Field) {
+	callerFields := getCallerInfoForLog()
+	fields = append(fields, callerFields...)
+	Logger.Debug(message, fields...)
+}
+
+func Error(message string, fields ...zap.Field) {
+	callerFields := getCallerInfoForLog()
+	fields = append(fields, callerFields...)
+	Logger.Error(message, fields...)
+}

+ 54 - 94
service/group/group.go

@@ -6,7 +6,10 @@ import (
 	"time"
 	"tmr-watch/models"
 	"tmr-watch/module"
+	"tmr-watch/pkg/logger/zaplog"
 	"tmr-watch/pkg/util"
+
+	"go.uber.org/zap"
 )
 
 // DistributeFeedFormulaService 饲料配方下发牧场端
@@ -70,49 +73,39 @@ func AnalysisAccuracyService(req *models.AnalysisAccuracyRequest) (*models.Analy
 		SprinkleFodderCorrectRatio:  make([]*models.PastureAnalysisAccuracyDataValue, 0),
 	}
 
-	// 混料准确率
+	// 混料准确率和正确率
 	mixedFodderDataList, err := module.MixedFodderData(req)
 	if err != nil {
 		return nil, err
 	}
 
-	// 撒料准确率
+	// 撒料准确率和撒料正确率
 	sprinkleFodderDataList, err := module.SprinkleFodderData(req)
 	if err != nil {
 		return nil, err
 	}
-	// 混料正确率
-	mixedFodderCorrectDataList, err := module.MixedFodderCorrectData(req)
-	if err != nil {
-		return nil, err
-	}
-
-	// 撒料正确率
-	sprinkleFodderCorrectDataList, err := module.SprinkleFodderCorrectData(req)
 
 	timeList := util.TimeBetween(req.StartDate, req.EndDate)
 	for _, dayTime := range timeList {
-		var mixedInfo, sprinkleInfo, mixedCorrectInfo, sprinkleCorrectInfo bool
+		var mixedInfo, sprinkleInfo bool
 		for _, mixed := range mixedFodderDataList {
-			myDate := mixed.Date.Format(util.LayoutDateFormat)
-			if myDate != dayTime {
+			if mixed.PlanTime != dayTime {
 				continue
 			}
 			// 混料准确率
-			var mixedFodderAccurateRatio float64 = 0
-			if mixed.Lweight > 0 && mixed.ActualWeightMinus > 0 {
-				if mixed.Lweight > mixed.ActualWeightMinus {
-					mixedFodderAccurateRatio = mixed.ActualWeightMinus / mixed.Lweight * 100
-				} else {
-					mixedFodderAccurateRatio = mixed.Lweight / mixed.ActualWeightMinus * 100
-				}
+			mixedAccurateValue := &models.PastureAnalysisAccuracyDataValue{
+				DayTime: dayTime,
+				Ratio:   mixed.MixedFodderAccurateRatio,
 			}
-			mixedValue := &models.PastureAnalysisAccuracyDataValue{
+			// 混料正确率
+			mixedCorrectValue := &models.PastureAnalysisAccuracyDataValue{
 				DayTime: dayTime,
-				Ratio:   mixedFodderAccurateRatio,
+				Ratio:   mixed.MixedFodderCorrectRatio,
 			}
-			response.MixedFodderAccurateRatio = append(response.MixedFodderAccurateRatio, mixedValue)
+			response.MixedFodderAccurateRatio = append(response.MixedFodderAccurateRatio, mixedAccurateValue)
+			response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, mixedCorrectValue)
 			mixedInfo = true
+
 		}
 		if !mixedInfo {
 			noInfo := &models.PastureAnalysisAccuracyDataValue{
@@ -120,27 +113,25 @@ func AnalysisAccuracyService(req *models.AnalysisAccuracyRequest) (*models.Analy
 				Ratio:   0,
 			}
 			response.MixedFodderAccurateRatio = append(response.MixedFodderAccurateRatio, noInfo)
+			response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, noInfo)
 		}
 
 		for _, sprinkle := range sprinkleFodderDataList {
-			myDate := sprinkle.Date.Format(util.LayoutDateFormat)
-			if myDate != dayTime {
+			if sprinkle.PlanTime != dayTime {
 				continue
 			}
 			// 撒料准确率
-			var sprinkleFodderAccurateRatio float64 = 0
-			if sprinkle.Lweight > 0 && sprinkle.ActualWeightMinus > 0 {
-				if sprinkle.Lweight > sprinkle.ActualWeightMinus {
-					sprinkleFodderAccurateRatio = sprinkle.ActualWeightMinus / sprinkle.Lweight * 100
-				} else {
-					sprinkleFodderAccurateRatio = sprinkle.Lweight / sprinkle.ActualWeightMinus * 100
-				}
+			sprinkleAccurateValue := &models.PastureAnalysisAccuracyDataValue{
+				DayTime: dayTime,
+				Ratio:   sprinkle.SprinkleFodderAccurateRatio,
 			}
-			sprinkleValue := &models.PastureAnalysisAccuracyDataValue{
+			// 撒料正确率
+			sprinkleCorrectValue := &models.PastureAnalysisAccuracyDataValue{
 				DayTime: dayTime,
-				Ratio:   sprinkleFodderAccurateRatio,
+				Ratio:   sprinkle.SprinkleFodderCorrectRatio,
 			}
-			response.SprinkleFodderAccurateRatio = append(response.SprinkleFodderAccurateRatio, sprinkleValue)
+			response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, sprinkleCorrectValue)
+			response.SprinkleFodderAccurateRatio = append(response.SprinkleFodderAccurateRatio, sprinkleAccurateValue)
 			sprinkleInfo = true
 		}
 		if !sprinkleInfo {
@@ -149,66 +140,14 @@ func AnalysisAccuracyService(req *models.AnalysisAccuracyRequest) (*models.Analy
 				Ratio:   0,
 			}
 			response.SprinkleFodderAccurateRatio = append(response.SprinkleFodderAccurateRatio, noInfo)
-		}
-
-		for _, mixedFodder := range mixedFodderCorrectDataList {
-			mixDateStr, _ := time.ParseInLocation(time.RFC3339, mixedFodder.Date, time.Local)
-			mixDate := mixDateStr.Format("2006-01-02")
-			if mixDate != dayTime {
-				continue
-			}
-			if mixedFodder.MixedCorrectNumber == 0 || mixedFodder.UseMixedFodderOptionNumber == 0 {
-				response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
-					DayTime: dayTime,
-					Ratio:   0,
-				})
-			} else {
-				response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
-					DayTime: dayTime,
-					Ratio:   float64(mixedFodder.MixedCorrectNumber) / float64(mixedFodder.UseMixedFodderOptionNumber) * 100,
-				})
-			}
-			mixedCorrectInfo = true
-		}
-		if !mixedCorrectInfo {
-			response.MixedFodderCorrectRatio = append(response.MixedFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
-				DayTime: dayTime,
-				Ratio:   0,
-			})
-		}
-
-		for _, sprinkle := range sprinkleFodderCorrectDataList {
-			myDateStr, _ := time.ParseInLocation(time.RFC3339, sprinkle.Date, time.Local)
-			myDate := myDateStr.Format("2006-01-02")
-			if myDate != dayTime {
-				continue
-			}
-
-			if sprinkle.SprinkleCorrectNumber == 0 || sprinkle.UseSprinkleOptionNumber == 0 {
-				response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
-					DayTime: dayTime,
-					Ratio:   0,
-				})
-			} else {
-				response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
-					DayTime: dayTime,
-					Ratio:   float64(sprinkle.SprinkleCorrectNumber) / float64(sprinkle.UseSprinkleOptionNumber) * 100,
-				})
-			}
-			sprinkleCorrectInfo = true
-		}
-		if !sprinkleCorrectInfo {
-			response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, &models.PastureAnalysisAccuracyDataValue{
-				DayTime: dayTime,
-				Ratio:   0,
-			})
+			response.SprinkleFodderCorrectRatio = append(response.SprinkleFodderCorrectRatio, noInfo)
 		}
 	}
 
 	return response, nil
 }
 
-// ProcessAnalysisService 过程分析
+// ProcessAnalysisService 过程分析-执行时间
 func ProcessAnalysisService(req *models.AnalysisAccuracyRequest) (*models.ProcessAnalysisResponse, error) {
 	response := &models.ProcessAnalysisResponse{
 		AddFeedTime:  &models.ProcessAnalysisDataValue{},
@@ -216,7 +155,8 @@ func ProcessAnalysisService(req *models.AnalysisAccuracyRequest) (*models.Proces
 		StirTime:     &models.ProcessAnalysisDataValue{},
 	}
 
-	processDataList, err := module.ProcessAnalysisData(req)
+	// 获取指定时间段内tmr设备列表
+	tmrList, err := module.TMRList(req)
 	if err != nil {
 		return nil, err
 	}
@@ -224,10 +164,30 @@ func ProcessAnalysisService(req *models.AnalysisAccuracyRequest) (*models.Proces
 	addFeedList := make([]int, 0)
 	sprinkleFeedList := make([]int, 0)
 	stirDelayList := make([]int, 0)
-	for _, v := range processDataList {
-		addFeedList = append(addFeedList, util.TimeParseToMinutes(v.ExecProcessTime))
-		sprinkleFeedList = append(sprinkleFeedList, util.TimeParseToMinutes(v.L2ProcessTime))
-		stirDelayList = append(stirDelayList, v.ExecStirDelay)
+
+	for _, v := range tmrList {
+		mixedProcessTimelist, err := module.MixedProcessTimeList(req.PastureId, v.Id)
+		if err != nil {
+			zaplog.Error("ProcessAnalysisService", zap.Any("MixedProcessTimeList", err))
+		} else {
+			tmrMixAllTime := 0
+			for _, t := range mixedProcessTimelist {
+				tmrMixAllTime += util.TimeParseToMinutes(t.ProcessTime)
+			}
+			addFeedList = append(addFeedList, tmrMixAllTime)
+		}
+
+		sprinkleProcessTimeList, err := module.SprinkleProcessTimeList(req.PastureId, v.Id)
+		if err != nil {
+			zaplog.Error("ProcessAnalysisService", zap.Any("SprinkleProcessTimeList", err))
+		} else {
+			tmrSpinkleAllTime := 0
+			for _, s := range sprinkleProcessTimeList {
+				tmrSpinkleAllTime += util.TimeParseToMinutes(s.ProcessTime)
+			}
+			sprinkleFeedList = append(sprinkleFeedList, tmrSpinkleAllTime)
+		}
+
 	}
 
 	if len(addFeedList) > 0 {