Explorar el Código

粮油代码迁移

gmy hace 7 meses
padre
commit
6f1404b781

+ 4 - 3
go.mod

@@ -6,23 +6,25 @@ require (
 	github.com/PuerkitoBio/goquery v1.9.2
 	github.com/beego/bee/v2 v2.1.0
 	github.com/beego/beego/v2 v2.1.4
+	github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732
+	github.com/chromedp/chromedp v0.9.5
 	github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b
 	github.com/mozillazg/go-pinyin v0.20.0
 	github.com/patrickmn/go-cache v2.1.0+incompatible
+	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/robfig/cron/v3 v3.0.1
 	github.com/shakinm/xlsReader v0.9.12
 	github.com/shopspring/decimal v1.3.1
 	github.com/tealeg/xlsx v1.0.5
 	github.com/xuri/excelize/v2 v2.8.0
 	golang.org/x/net v0.24.0
+	golang.org/x/text v0.14.0
 )
 
 require (
 	github.com/andybalholm/cascadia v1.3.2 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
-	github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732 // indirect
-	github.com/chromedp/chromedp v0.9.5 // indirect
 	github.com/chromedp/sysutil v1.0.0 // indirect
 	github.com/gobwas/httphead v0.1.0 // indirect
 	github.com/gobwas/pool v0.2.1 // indirect
@@ -54,7 +56,6 @@ require (
 	github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a // indirect
 	golang.org/x/crypto v0.22.0 // indirect
 	golang.org/x/sys v0.19.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
 	google.golang.org/protobuf v1.30.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

+ 143 - 0
go.sum

@@ -1,13 +1,29 @@
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
 github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
 github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
+github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
 github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
 github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
+github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
 github.com/beego/bee/v2 v2.1.0 h1:4WngbAnkvVOyKy74WXcRH3clon76wkjhuzrV2mx2fQU=
 github.com/beego/bee/v2 v2.1.0/go.mod h1:wDhKy5TNxv46LHKsK2gyxo38ObCOm9PbCN89lWHK3EU=
 github.com/beego/beego/v2 v2.1.4 h1:99d8+sUmQyfaArQIjjzWGE+KYU9M1GkfWec74nXQxFY=
 github.com/beego/beego/v2 v2.1.4/go.mod h1:0J0RQVIpepnRUfu6ax+kLVVB1FcdYryHK9lpRl5wvbY=
+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/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 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
+github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
 github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732 h1:XYUCaZrW8ckGWlCRJKCSoh/iFwlpX316a8yY9IFEzv8=
@@ -16,22 +32,53 @@ github.com/chromedp/chromedp v0.9.5 h1:viASzruPJOiThk7c5bueOUY91jGLJVximoEMGoH93
 github.com/chromedp/chromedp v0.9.5/go.mod h1:D4I2qONslauw/C7INoCir1BJkSwBYMyZgx8X276z3+Y=
 github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
 github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
+github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
+github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
+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/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=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
+github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
 github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/garyburd/redigo v1.6.3/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw=
+github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
 github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
 github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
 github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
 github.com/gobwas/ws v1.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q=
 github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
 github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
 github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac h1:Q0Jsdxl5jbxouNs1TQYt0gxesYMU4VXRbsTlgDloZ50=
 github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
 github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 h1:EvokxLQsaaQjcWVWSV38221VAK7qc2zhaO17bKys/18=
@@ -46,46 +93,90 @@ github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 h1:V2IgdyerlBa/MxaEFR
 github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw=
 github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b h1:fbskpz/cPqWH8VqkQ7LJghFkl2KPAiIFUHrTJ2O3RGk=
 github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 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.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+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=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
+github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
 github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
 github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
 github.com/metakeule/fmtdate v1.1.2 h1:n9M7H9HfAqp+6OA98wXGMdcAr6omshSNVct65Bks1lQ=
 github.com/metakeule/fmtdate v1.1.2/go.mod h1:2JyMFlKxeoGy1qS6obQukT0AL0Y4iNANQL8scbSdT4E=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
 github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
 github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
 github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
 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/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
 github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
 github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
 github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
 github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
 github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
 github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
+github.com/rdlucklib/rdluck_tools v1.0.3 h1:iOtK2QPlPQ6CL6c1htCk5VnFCHzyG6DCfJtunrMswK0=
+github.com/rdlucklib/rdluck_tools v1.0.3/go.mod h1:9Onw9o4w19C8KE5lxb8GyxgRBbZweRVkQSc79v38EaA=
 github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
 github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
 github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
@@ -96,25 +187,44 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
 github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
 github.com/shakinm/xlsReader v0.9.12 h1:F6GWYtCzfzQqdIuqZJ0MU3YJ7uwH1ofJtmTKyWmANQk=
 github.com/shakinm/xlsReader v0.9.12/go.mod h1:ME9pqIGf+547L4aE4YTZzwmhsij+5K9dR+k84OO6WSs=
+github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
 github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
 github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
+github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
+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/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
+github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
 github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
 github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
+github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
+github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
 github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca h1:uvPMDVyP7PXMMioYdyPH+0O+Ta/UO1WFfNYMO3Wz0eg=
 github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
 github.com/xuri/excelize/v2 v2.8.0 h1:Vd4Qy809fupgp1v7X+nCS/MioeQmYVVzi495UCTqB7U=
 github.com/xuri/excelize/v2 v2.8.0/go.mod h1:6iA2edBTKxKbZAa7X5bDhcCg51xdOn1Ar5sfoXRGrQg=
 github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a h1:Mw2VNrNNNjDtw68VsEj2+st+oCSn4Uz7vZw6TbhcV1o=
 github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
+github.com/ylywyn/jpush-api-go-client v0.0.0-20190906031852-8c4466c6e369/go.mod h1:Nv7wKD2/bCdKUFNKcJRa99a+1+aSLlCRJFriFYdjz/I=
 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=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
 golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
@@ -123,6 +233,10 @@ golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
 golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
 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/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -132,11 +246,22 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
 golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
 golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -170,13 +295,31 @@ 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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+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.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 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=
+gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
+gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+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.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=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 13 - 0
models/edb_data_ly.go

@@ -0,0 +1,13 @@
+// @Author gmy 2024/9/14 16:13:00
+package models
+
+type EdbDataLy struct {
+	edbDataId     int     `orm:"column(edb_data_id);pk"` // 数据ID
+	CreateTime    string  `orm:"column(create_time)"`    // 创建时间
+	ModifyTime    string  `orm:"column(modify_time)"`    // 修改时间
+	EdbInfoId     int     `orm:"column(edb_info_id)"`    // 指标id
+	EdbCode       string  `orm:"column(edb_code)"`       // 指标编码
+	DataTime      string  `orm:"column(data_time)"`      // 数据日期
+	Value         float64 `orm:"column(value)"`          // 数据值
+	DataTimestamp uint64  `orm:"column(data_timestamp)"` // 数据日期时间戳
+}

+ 54 - 0
models/edb_info.go

@@ -0,0 +1,54 @@
+// @Author gmy 2024/9/18 17:29:00
+package models
+
+import "time"
+
+type EdbInfo struct {
+	EdbInfoId        int    `orm:"column(edb_info_id);pk"`
+	EdbInfoType      int    `description:"指标类型,0:普通指标,1:预测指标"`
+	SourceName       string `description:"来源名称"`
+	Source           int    `description:"来源id"`
+	EdbCode          string `description:"指标编码"`
+	EdbName          string `description:"指标名称"`
+	EdbNameEn        string `description:"英文指标名称"`
+	EdbNameSource    string `description:"指标名称来源"`
+	Frequency        string `description:"频率"`
+	Unit             string `description:"单位"`
+	UnitEn           string `description:"英文单位"`
+	StartDate        string `description:"起始日期"`
+	EndDate          string `description:"终止日期"`
+	ClassifyId       int    `description:"分类id"`
+	SysUserId        int
+	SysUserRealName  string
+	UniqueCode       string `description:"指标唯一编码"`
+	CreateTime       time.Time
+	ModifyTime       time.Time
+	MinValue         float64 `description:"指标最小值"`
+	MaxValue         float64 `description:"指标最大值"`
+	CalculateFormula string  `description:"计算公式"`
+	EdbType          int     `description:"指标类型:1:基础指标,2:计算指标"`
+	IsUpdate         int     `description:"当天是否已更新,1:未更新,2:已更新"`
+	Sort             int     `description:"排序字段"`
+	LatestDate       string  `description:"数据最新日期(实际日期)"`
+	LatestValue      float64 `description:"数据最新值(实际值)"`
+	EndValue         float64 `description:"数据的最新值(预测日期的最新值)"`
+	MoveType         int     `description:"移动方式:1:领先(默认),2:滞后"`
+	MoveFrequency    string  `description:"移动频度"`
+	NoUpdate         int8    `description:"是否停止更新,0:继续更新;1:停止更新"`
+	ServerUrl        string  `description:"服务器地址"`
+	ChartImage       string  `description:"图表图片"`
+	Calendar         string  `description:"公历/农历" orm:"default(公历);"`
+	EmptyType        int     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
+	MaxEmptyType     int     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
+	DataDateType     string  `orm:"column(data_date_type);size(255);null;default(交易日)"`
+	ManualSave       int     `description:"是否有手动保存过上下限: 0-否; 1-是"`
+	TerminalCode     string  `description:"终端编码,用于配置在机器上"`
+	DataUpdateTime   string  `description:"最近一次数据发生变化的时间"`
+	ErDataUpdateDate string  `description:"本次更新,数据发生变化的最早日期"`
+	SourceIndexName  string  `description:"数据源中的指标名称"`
+	SubSource        int     `description:"子数据来源:0:经济数据库,1:日期序列"`
+	SubSourceName    string  `description:"子数据来源名称"`
+	IndicatorCode    string  `description:"指标代码"`
+	StockCode        string  `description:"证券代码"`
+	Extra            string  `description:"指标的额外配置"`
+}

+ 29 - 0
services/alarm_msg/alarm_msg.go

@@ -0,0 +1,29 @@
+package alarm_msg
+
+import (
+	"encoding/json"
+	"eta/eta_data_analysis/utils"
+	"github.com/rdlucklib/rdluck_tools/http"
+)
+
+var (
+	AlarmMsgUrl = "http://127.0.0.1:8606/api/alarm/send"
+)
+
+// projectName-项目名称
+// runMode-运行模式
+// msgBody-消息内容
+// level:消息基本,1:提示消息,2:警告消息,3:严重错误信息,默认为1 提示消息
+func SendAlarmMsg(msgBody string, level int) {
+	params := make(map[string]interface{})
+	params["ProjectName"] = utils.APPNAME
+	params["RunMode"] = utils.RunMode
+	params["MsgBody"] = msgBody
+	params["Level"] = level
+	param, err := json.Marshal(params)
+	if err != nil {
+		utils.FileLog.Info("SendAlarmMsg json.Marshal Err:" + err.Error())
+		return
+	}
+	http.Post(AlarmMsgUrl, string(param))
+}

+ 126 - 23
services/liangyou/commodity_liangyou.go

@@ -1,9 +1,10 @@
-package main
+package liangyou
 
 import (
 	"context"
 	"encoding/json"
 	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/services/alarm_msg"
 	"eta/eta_data_analysis/utils"
 	"fmt"
 	"github.com/beego/beego/v2/core/logs"
@@ -22,16 +23,10 @@ var (
 	lyLoginPath = "https://www.fao.com.cn/"
 )
 
-// UserInfo 登录用户信息
-type UserInfo struct {
-	Username string
-	Password string
-}
-
-func main() {
+func LyDataDeal(cont context.Context) (err error) {
 
 	// 读取 JSON 文件
-	configFile, err := os.ReadFile("D:\\go\\workspace1\\eta_crawler\\static\\liangyou.json")
+	configFile, err := os.ReadFile(utils.LY_JSON_PATH)
 	if err != nil {
 		fmt.Printf("读取配置文件错误: %v\n", err)
 		return
@@ -85,20 +80,18 @@ func main() {
 			}
 		}
 	}
+	return nil
 }
 
 func login(ctx context.Context) error {
-	userInfo := UserInfo{
-		Username: "13633849418",
-		Password: "828384Abc@",
-	}
+
 	return chromedp.Run(ctx,
 		chromedp.Navigate(lyLoginPath),
 		chromedp.Sleep(5*time.Second),
 		chromedp.Click(`a[id="btnLogin"]`, chromedp.ByQuery),
 		chromedp.Sleep(2*time.Second),
-		chromedp.SetValue(`input[id="userName"]`, userInfo.Username, chromedp.ByQuery),
-		chromedp.SetValue(`input[id="pwd"]`, userInfo.Password, chromedp.ByQuery),
+		chromedp.SetValue(`input[id="userName"]`, utils.LY_USERNAME, chromedp.ByQuery),
+		chromedp.SetValue(`input[id="pwd"]`, utils.LY_PASSWORD, chromedp.ByQuery),
 		chromedp.Sleep(2*time.Second),
 		chromedp.Click(`input[id="btn_Login"]`, chromedp.ByQuery),
 		chromedp.Sleep(5*time.Second),
@@ -241,19 +234,31 @@ func fetchReportData(ctx context.Context, product, category, report string, keyw
 		}
 
 		// 处理报告成功,将维护指标数据读取进度到数据库,避免后面重复读取
-		recordId, err := models.AddLyIndexRecord(&models.BaseFromLyIndexRecord{
+		record := &models.BaseFromLyIndexRecord{
 			CreateTime: utils.GetCurrentTime(),
 			ModifyTime: utils.GetCurrentTime(),
 			Product:    product,
 			Category:   category,
 			Url:        key,
 			DataTime:   format,
-		})
+		}
+		// 转换成json
+		marshal, err := json.Marshal(record)
+		if err != nil {
+			logs.Error("维护指标数据读取进度错误: %s, %s, %v: %v", product, category, key, err)
+			continue
+		}
+		// json 转 interface
+		var result map[string]interface{}
+		err = json.Unmarshal(marshal, &result)
+
+		postEdbLib, err = utils.PostEdbLibRequest(result, utils.ADD_LY_INDEX_RECORD)
 		if err != nil {
-			logs.Error("维护指标数据读取进度错误: %s, %s, %v: %v", product, category, recordId, err)
+			// 有错误就不继续执行
+			logs.Error("维护指标数据读取进度错误: %s, %s, %v: %v", product, category, key, err)
 			continue
 		}
-		logs.Info("维护指标数据读取进度成功: %s, %s, %v", product, category, recordId)
+		logs.Info("维护指标数据读取进度成功: %s, %s, %v", product, category, key)
 	}
 
 	return nil
@@ -430,6 +435,7 @@ func processReport(ctx context.Context, product string, category string, reportU
 	}
 
 	var lyIndexDataList []models.BaseFromLyData
+	var edbDataLyList []models.EdbDataLy
 	// Process the data based on keywords
 	for _, keyword := range keywords {
 		partialKeyword := strings.Split(keyword, ":")
@@ -440,10 +446,20 @@ func processReport(ctx context.Context, product string, category string, reportU
 		}
 
 		// 查询报告所属分类
-		classify, err := models.GetLyClassifyByName(product)
+		paramsLib := make(map[string]interface{})
+		paramsLib["CategoryName"] = product
+		postEdbLib, err := utils.PostEdbLibRequest(paramsLib, utils.GET_LY_CLASSIFY_BY_NAME)
+		if err != nil {
+			// 有错误就不继续执行
+			log.Printf("postEdbLib err: %v", err)
+			continue
+		}
+		var requestResponse models.RequestResponse[models.BaseFromLyClassify]
+		err = json.Unmarshal(postEdbLib, &requestResponse)
 		if err != nil {
 			return err
 		}
+		classify := requestResponse.Data
 
 		// Process the report content using the selected processor
 		baseFromLyDataList, err := processor.Process(ctx, product, reportContent, partialKeyword, classify.BaseFromLyClassifyId)
@@ -455,16 +471,76 @@ func processReport(ctx context.Context, product string, category string, reportU
 				if baseFromLyData.DataTime != "" && baseFromLyData.IndexCode != "" && baseFromLyData.IndexCode != "lysww" {
 					baseFromLyData.CreateTime = utils.GetCurrentTime()
 					baseFromLyData.ModifyTime = utils.GetCurrentTime()
+
+					// 补充 判断是否存在于指标库
+					paramsLib = make(map[string]interface{})
+					paramsLib["IndexCode"] = baseFromLyData.IndexCode
+					paramsLib["Source"] = utils.DATA_SOURCE_LY
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_EDB_INFO_BY_INDEX_CODE)
+					if err != nil {
+						// 有错误就不继续执行
+						log.Printf("postEdbLib err: %v", err)
+						continue
+					}
+					var requestResponse models.RequestResponse[models.EdbInfo]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+					if err != nil {
+						log.Printf("postEdbLib err: %v", err)
+						continue
+					}
+
 					lyIndexDataList = append(lyIndexDataList, baseFromLyData)
+
+					edbIndexData := requestResponse.Data
+					if edbIndexData.EdbCode == "" {
+						// 不存在 不用维护指标库数据
+						continue
+					}
+
+					// 存在 则同步新增指标库中的指标数据
+					edbDataLy := models.EdbDataLy{
+						CreateTime:    utils.GetCurrentTime(),
+						ModifyTime:    utils.GetCurrentTime(),
+						EdbInfoId:     edbIndexData.EdbInfoId,
+						EdbCode:       edbIndexData.EdbCode,
+						DataTime:      baseFromLyData.DataTime,
+						Value:         baseFromLyData.Value,
+						DataTimestamp: uint64(time.Now().UnixNano() / int64(time.Millisecond)),
+					}
+					edbDataLyList = append(edbDataLyList, edbDataLy)
 				}
 			}
 		}
-
 	}
 	// 新增指标数据
 	if len(lyIndexDataList) > 0 {
-		err = models.AddLyDataList(lyIndexDataList)
+		// 转换成json
+		marshal, err := json.Marshal(lyIndexDataList)
 		if err != nil {
+			log.Printf("postEdbLib err: %v", err)
+			return err
+		}
+		_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_LY_DATA_LIST, string(marshal), "application/json")
+		if err != nil {
+			// 有错误就不继续执行
+			log.Printf("postEdbLib err: %v", err)
+			return err
+		}
+	}
+
+	// 新增指标库数据
+	if len(edbDataLyList) > 0 {
+		// 转换成json
+		marshal, err := json.Marshal(edbDataLyList)
+		if err != nil {
+			log.Printf("postEdbLib err: %v", err)
+			return err
+		}
+		_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_LY_EDB_DATA, string(marshal), "application/json")
+		//_, err := httpRequestFill(edbDataLyList, utils.ADD_BATCH_LY_EDB_DATA)
+		if err != nil {
+			// 有错误就不继续执行
+			log.Printf("postEdbLib err: %v", err)
 			return err
 		}
 	}
@@ -484,9 +560,36 @@ func addLyIndex(classifyId int, indexCode string, indexName string, unit string,
 		Unit:                 unit,
 		EdbExist:             0,
 	}
-	indexId, err := models.AddLyIndex(index)
+	postEdbLib, err := httpRequestFill(index, utils.ADD_LY_INDEX)
 	if err != nil {
+		// 有错误就不继续执行
+		log.Printf("postEdbLib err: %v", err)
 		return 0, err
 	}
+	var requestResponse models.RequestResponse[int64]
+	err = json.Unmarshal(postEdbLib, &requestResponse)
+	indexId := requestResponse.Data
 	return int(indexId), nil
 }
+
+func httpRequestFill(data interface{}, urlMethod string) (postEdbLib []byte, err error) {
+	// 转换成json
+	marshal, err := json.Marshal(data)
+	if err != nil {
+		return nil, err
+	}
+	// json 转 interface
+	var result map[string]interface{}
+	err = json.Unmarshal(marshal, &result)
+	if err != nil {
+		return nil, err
+	}
+
+	postEdbLib, err = utils.PostEdbLibRequest(result, urlMethod)
+	if err != nil {
+		// 有错误就不继续执行
+		log.Printf("postEdbLib err: %v", err)
+		return nil, err
+	}
+	return postEdbLib, nil
+}

+ 218 - 40
services/liangyou/processor_business_logic.go

@@ -1,8 +1,9 @@
 // @Author gmy 2024/8/6 10:50:00
-package main
+package liangyou
 
 import (
 	"context"
+	"encoding/json"
 	"eta/eta_data_analysis/models"
 	"eta/eta_data_analysis/utils"
 	"fmt"
@@ -122,12 +123,18 @@ func (p *ImportCostProcessor) Process(ctx context.Context, product string, repor
 							logs.Error("ProcessingImportCostProcessor Process() : Failed to get index id: %v", err)
 							continue
 						}
-
-						indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+						paramsLib := make(map[string]interface{})
+						paramsLib["IndexId"] = indexId
+						paramsLib["DataTime"] = format
+						postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 						if err != nil {
 							logs.Error("ProcessingImportCostProcessor Process() : Failed to get data by index id and date: %v", err)
 							continue
 						}
+						var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+						err = json.Unmarshal(postEdbLib, &requestResponse)
+
+						indexData := requestResponse.Data
 						if len(indexData) > 0 {
 							logs.Info("ProcessingImportCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
@@ -152,9 +159,7 @@ func (p *ImportCostProcessor) Process(ctx context.Context, product string, repor
 					break
 				}
 			}
-
 		}
-
 	}
 
 	return result, nil
@@ -244,11 +249,18 @@ func (p *ProcessingProfitProcessor) Process(ctx context.Context, product string,
 							continue
 						}
 
-						indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+						paramsLib := make(map[string]interface{})
+						paramsLib["IndexId"] = indexId
+						paramsLib["DataTime"] = format
+						postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 						if err != nil {
 							logs.Error("ProcessingProfitProcessor Process() : Failed to get data by index id and date: %v", err)
 							continue
 						}
+						var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+						err = json.Unmarshal(postEdbLib, &requestResponse)
+
+						indexData := requestResponse.Data
 						if len(indexData) > 0 {
 							logs.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
@@ -357,11 +369,18 @@ func (p *ShippingCostProcessor) Process(ctx context.Context, product string, rep
 						continue
 					}
 
-					indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["DataTime"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 					if err != nil {
 						logs.Error("ShippingCostProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("ShippingCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						continue
@@ -492,11 +511,19 @@ func (p *SupplyDemandBalanceProcessor) Process(ctx context.Context, product stri
 						logs.Error("SupplyDemandBalanceProcessor Process() : Failed to get year month: %v", err)
 						continue
 					}
-					indexData, err := models.GetLyDataByIndexIdAndDataTimeYM(indexId, yearMonth)
+
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["YearMonth"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME_YM)
 					if err != nil {
 						logs.Error("SupplyDemandBalanceProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 存在走更新逻辑 主要更新今年在去年的预估值
@@ -514,20 +541,36 @@ func (p *SupplyDemandBalanceProcessor) Process(ctx context.Context, product stri
 
 							if time.Before(timeZero) {
 								// 更新指标数据
-								err := models.UpdateLyDataById(indexData.BaseFromLyDataId, value)
+								paramsLib := make(map[string]interface{})
+								paramsLib["Id"] = indexData.BaseFromLyDataId
+								paramsLib["Value"] = value
+								_, err := httpRequestFill(paramsLib, utils.UPDATE_LY_DATA_BY_ID)
 								if err != nil {
-									logs.Error("SupplyDemandBalanceProcessor Process() : Failed to update data: %v", err)
-									continue
+									return nil, fmt.Errorf("SupplyDemandBalanceProcessor Process() : failed to parse value '%s': %v", valueStr, err)
 								}
 								// 更新指标库数据
-								edbIndexData, err := models.GetLyEdbDataByIndexCodeAndDataTime(indexData.IndexCode, yearMonth)
+								paramsLib = make(map[string]interface{})
+								paramsLib["IndexCode"] = indexData.IndexCode
+								paramsLib["DataTime"] = yearMonth
+								postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_EDB_DATA_BY_INDEX_CODE_AND_DATA_TIME)
+								if err != nil {
+									logs.Error("SupplyDemandBalanceProcessor Process() : Failed to get data by index id and date: %v", err)
+									continue
+								}
+								var requestResponse models.RequestResponse[[]models.EdbDataLy]
+								err = json.Unmarshal(postEdbLib, &requestResponse)
 								if err != nil {
 									return nil, err
 								}
+
+								edbIndexData := requestResponse.Data
 								if len(edbIndexData) > 0 {
-									err := models.UpdateLyEdbDataById(edbIndexData[0].EdbInfoId, value)
+									paramsLib := make(map[string]interface{})
+									paramsLib["Id"] = edbIndexData[0].EdbInfoId
+									paramsLib["Value"] = value
+									_, err := httpRequestFill(paramsLib, utils.UPDATE_LY_EDB_DATA_BY_ID)
 									if err != nil {
-										return nil, err
+										return nil, fmt.Errorf("SupplyDemandBalanceProcessor Process() : failed to parse value '%s': %v", valueStr, err)
 									}
 								}
 							}
@@ -647,11 +690,19 @@ func (p *PurchaseShippingProcessor) Process(ctx context.Context, product string,
 					if err != nil {
 						return nil, err
 					}
-					indexData, err := models.GetLyDataByIndexIdAndDataTimeYM(indexId, month)
+
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["YearMonth"] = month
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME_YM)
 					if err != nil {
 						logs.Error("SupplyDemandBalanceProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						if indexData[0].Value != value {
 							logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
@@ -669,20 +720,37 @@ func (p *PurchaseShippingProcessor) Process(ctx context.Context, product string,
 
 							if time.Before(timeZero) {
 								// 更新指标数据
-								err := models.UpdateLyDataById(lyData.BaseFromLyDataId, value)
+								paramsLib := make(map[string]interface{})
+								paramsLib["Id"] = lyData.BaseFromLyDataId
+								paramsLib["Value"] = value
+								_, err := httpRequestFill(paramsLib, utils.UPDATE_LY_DATA_BY_ID)
 								if err != nil {
-									return nil, err
+									return nil, fmt.Errorf("SupplyDemandBalanceProcessor Process() : failed to parse value '%s': %v", valueStr, err)
 								}
 
 								// 同步更新指标库数据 须根据指标编码和日期更新
-								edbIndexData, err := models.GetLyEdbDataByIndexCodeAndDataTime(lyData.IndexCode, month)
+								paramsLib = make(map[string]interface{})
+								paramsLib["IndexCode"] = lyData.IndexCode
+								paramsLib["DataTime"] = yearMonth
+								postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_EDB_DATA_BY_INDEX_CODE_AND_DATA_TIME)
+								if err != nil {
+									logs.Error("SupplyDemandBalanceProcessor Process() : Failed to get data by index id and date: %v", err)
+									continue
+								}
+								var requestResponse models.RequestResponse[[]models.EdbDataLy]
+								err = json.Unmarshal(postEdbLib, &requestResponse)
+
+								edbIndexData := requestResponse.Data
 								if err != nil {
 									return nil, err
 								}
 								if len(edbIndexData) > 0 {
-									err := models.UpdateLyEdbDataById(edbIndexData[0].EdbInfoId, value)
+									paramsLib := make(map[string]interface{})
+									paramsLib["Id"] = edbIndexData[0].EdbInfoId
+									paramsLib["Value"] = value
+									_, err := httpRequestFill(paramsLib, utils.UPDATE_LY_EDB_DATA_BY_ID)
 									if err != nil {
-										return nil, err
+										return nil, fmt.Errorf("SupplyDemandBalanceProcessor Process() : failed to parse value '%s': %v", valueStr, err)
 									}
 								}
 							}
@@ -748,10 +816,18 @@ func (p *ProcessingReportProcessor) Process(ctx context.Context, product string,
 	if err != nil {
 		return []models.BaseFromLyData{}, err
 	}
-	indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+
+	paramsLib := make(map[string]interface{})
+	paramsLib["IndexId"] = indexId
+	paramsLib["DataTime"] = format
+	postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 	if err != nil {
 		return []models.BaseFromLyData{}, fmt.Errorf("ProcessingReportProcessor Process() : Failed to get data by index id and date: %v", err)
 	}
+	var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+	err = json.Unmarshal(postEdbLib, &requestResponse)
+
+	indexData := requestResponse.Data
 	if len(indexData) > 0 {
 		logs.Info("ProcessingReportProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 		// 不必做更新处理,报告每周刷新,即使本周和上周数据一致,也需要每周记录
@@ -820,11 +896,18 @@ func (p *ProcessingReportProcessor) Process(ctx context.Context, product string,
 						continue
 					}
 
-					indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["DataTime"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 					if err != nil {
 						logs.Error("ProcessingReportProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("ProcessingReportProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每日更新,即使今天和昨天数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
@@ -948,11 +1031,18 @@ func (p *InventoryAnalysisProcessor) Process(ctx context.Context, product string
 						continue
 					}
 
-					indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["DataTime"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 					if err != nil {
 						logs.Error("SupplyDemandBalanceProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每周更新,即使本周和上周数据一致,也需要每周记录,如果到这里也只是说,今天这个报告被读取了两次
@@ -1054,11 +1144,18 @@ func (p *PriceSpreadArbitrageProcessor) Process(ctx context.Context, product str
 						continue
 					}
 
-					indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["DataTime"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 					if err != nil {
 						logs.Error("ProcessingProfitProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每天更新,即使今天和每天数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
@@ -1169,11 +1266,18 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 						continue
 					}
 
-					indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["DataTime"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 					if err != nil {
 						logs.Error("DailyTransactionProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("DailyTransactionProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每周更新,一周出来一周中每天得数据,即使本周和上周数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
@@ -1227,11 +1331,18 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 								continue
 							}
 
-							indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+							paramsLib := make(map[string]interface{})
+							paramsLib["IndexId"] = indexId
+							paramsLib["DataTime"] = format
+							postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 							if err != nil {
 								logs.Error("DailyTransactionProcessor Process() : Failed to get data by index id and date: %v", err)
 								continue
 							}
+							var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+							err = json.Unmarshal(postEdbLib, &requestResponse)
+
+							indexData := requestResponse.Data
 							if len(indexData) > 0 {
 								logs.Info("DailyTransactionProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 								// 无需走更新逻辑,报告每周更新,即使本周和上周数据一致,也需要每周记录,如果到这里也只是说,今天这个报告被读取了两次
@@ -1312,11 +1423,18 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 						continue
 					}
 
-					indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["DataTime"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 					if err != nil {
 						logs.Error("SupplyDemandBalanceProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						continue
@@ -1444,11 +1562,18 @@ func (p *PalmOilImportCostProcessor) Process(ctx context.Context, product string
 							continue
 						}
 
-						indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+						paramsLib := make(map[string]interface{})
+						paramsLib["IndexId"] = indexId
+						paramsLib["DataTime"] = format
+						postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 						if err != nil {
 							logs.Error("PalmOilImportCostProcessor Process() : Failed to get data by index id and date: %v", err)
 							continue
 						}
+						var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+						err = json.Unmarshal(postEdbLib, &requestResponse)
+
+						indexData := requestResponse.Data
 						if len(indexData) > 0 {
 							logs.Info("PalmOilImportCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
@@ -1567,11 +1692,18 @@ func (p *ImportEstimateProcessor) Process(ctx context.Context, product string, r
 								continue
 							}
 
-							indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, slice)
+							paramsLib := make(map[string]interface{})
+							paramsLib["IndexId"] = indexId
+							paramsLib["DataTime"] = format
+							postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 							if err != nil {
 								logs.Error("ImportEstimateProcessor Process() : Failed to get data by index id and date: %v", err)
 								continue
 							}
+							var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+							err = json.Unmarshal(postEdbLib, &requestResponse)
+
+							indexData := requestResponse.Data
 
 							valueStr := row[columnIdx]
 							value, err := strconv.ParseFloat(valueStr, 64)
@@ -1596,20 +1728,37 @@ func (p *ImportEstimateProcessor) Process(ctx context.Context, product string, r
 
 									if lyData.Value != value && time.Before(timeZero) {
 										// 更新指标数据
-										err := models.UpdateLyDataById(lyData.BaseFromLyDataId, value)
+										paramsLib := make(map[string]interface{})
+										paramsLib["Id"] = lyData.BaseFromLyDataId
+										paramsLib["Value"] = value
+										_, err := httpRequestFill(paramsLib, utils.UPDATE_LY_DATA_BY_ID)
 										if err != nil {
-											return nil, err
+											return nil, fmt.Errorf("ImportEstimateProcessor Process() : failed to parse value '%s': %v", valueStr, err)
 										}
 
 										// 同步更新指标库数据
-										lyEdbIndexData, err := models.GetLyEdbDataByIndexCodeAndExactDataTime(lyData.IndexCode, lyData.DataTime)
+										paramsLib = make(map[string]interface{})
+										paramsLib["IndexCode"] = lyData.IndexCode
+										paramsLib["DataTime"] = lyData.DataTime
+										postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_EDB_DATA_BY_INDEX_CODE_AND_EXACT_DATA_TIME)
+										if err != nil {
+											logs.Error("ImportEstimateProcessor Process() : Failed to get ly edb data by index code and exact data time: %v", err)
+											continue
+										}
+										var requestResponse models.RequestResponse[[]models.EdbDataLy]
+										err = json.Unmarshal(postEdbLib, &requestResponse)
 										if err != nil {
 											return nil, err
 										}
+
+										lyEdbIndexData := requestResponse.Data
 										if len(lyEdbIndexData) > 0 {
-											err := models.UpdateLyEdbDataById(lyEdbIndexData[0].EdbInfoId, value)
+											paramsLib := make(map[string]interface{})
+											paramsLib["Id"] = lyEdbIndexData[0].EdbInfoId
+											paramsLib["Value"] = value
+											_, err := httpRequestFill(paramsLib, utils.UPDATE_LY_EDB_DATA_BY_ID)
 											if err != nil {
-												return nil, err
+												return nil, fmt.Errorf("ImportEstimateProcessor Process() : failed to parse value '%s': %v", valueStr, err)
 											}
 										}
 									}
@@ -1723,11 +1872,18 @@ func (p *InternationalPriceProcessor) Process(ctx context.Context, product strin
 							continue
 						}
 
-						indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+						paramsLib := make(map[string]interface{})
+						paramsLib["IndexId"] = indexId
+						paramsLib["DataTime"] = format
+						postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 						if err != nil {
 							logs.Error("InternationalPriceProcessor Process() : Failed to get data by index id and date: %v", err)
 							continue
 						}
+						var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+						err = json.Unmarshal(postEdbLib, &requestResponse)
+
+						indexData := requestResponse.Data
 						if len(indexData) > 0 {
 							logs.Info("InternationalPriceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							// 无需更新 指标展示本月和后两月的数据,报告每天更新,每天的值可能会改变,即使今天和每天数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
@@ -1826,11 +1982,18 @@ func (p *CanadaStatisticsBureauProcessor) Process(ctx context.Context, product s
 						continue
 					}
 
-					indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, format)
+					paramsLib := make(map[string]interface{})
+					paramsLib["IndexId"] = indexId
+					paramsLib["DataTime"] = format
+					postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 					if err != nil {
 						logs.Error("CanadaStatisticsBureauProcessor Process() : Failed to get data by index id and date: %v", err)
 						continue
 					}
+					var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+					err = json.Unmarshal(postEdbLib, &requestResponse)
+
+					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						logs.Info("CanadaStatisticsBureauProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需更新 指标展示本周的数据,报告每周更新,即使本周和上周数据一致,也需要每周记录,如果到这里也只是说,今天这个报告被读取了两次
@@ -1941,11 +2104,18 @@ func (p *ImportExportAnalysisProcessor) Process(ctx context.Context, product str
 							return nil, err
 						}
 
-						indexData, err := models.GetLyDataByIndexIdAndDataTime(indexId, lastDayOfMonth)
+						paramsLib := make(map[string]interface{})
+						paramsLib["IndexId"] = indexId
+						paramsLib["DataTime"] = format
+						postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME)
 						if err != nil {
 							logs.Error("ProcessingProfitProcessor Process() : Failed to get data by index id and date: %v", err)
 							continue
 						}
+						var requestResponse models.RequestResponse[[]models.BaseFromLyData]
+						err = json.Unmarshal(postEdbLib, &requestResponse)
+
+						indexData := requestResponse.Data
 						if len(indexData) > 0 {
 							logs.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
@@ -1997,11 +2167,19 @@ func getIndexId(indexCode string, indexName string, classifyId int, sourceName s
 
 	// 判断指标是否存在
 	var indexId int
-	indexInfo, err := models.GetLyIndexByCode(indexCode)
+	paramsLib := make(map[string]interface{})
+	paramsLib["IndexCode"] = indexCode
+	postEdbLib, err := httpRequestFill(paramsLib, utils.GET_LY_INDEX_BY_CODE)
+	if err != nil {
+		return 0, fmt.Errorf("getIndexId() : Failed to get ly index by code: %v", err)
+	}
+	var requestResponse models.RequestResponse[models.BaseFromLyIndex]
+	err = json.Unmarshal(postEdbLib, &requestResponse)
 	if err != nil {
-		return indexId, err
+		return 0, fmt.Errorf("getIndexId() : Failed to unmarshal response: %v", err)
 	}
-	if indexInfo == nil {
+	indexInfo := requestResponse.Data
+	if indexInfo.IndexName == "" {
 		// 新增指标
 		index, err := addLyIndex(classifyId, indexCode, indexName, frequency, unit)
 		if err != nil {

+ 2 - 2
services/liangyou/processor_factory.go

@@ -1,9 +1,9 @@
 // @Author gmy 2024/8/6 10:48:00
-package main
+package liangyou
 
 import (
 	"context"
-	"eta/eta_crawler/models"
+	"eta/eta_data_analysis/models"
 	"fmt"
 )
 

+ 7 - 0
services/task.go

@@ -4,6 +4,7 @@ import (
 	ccfService "eta/eta_data_analysis/services/base_from_ccf"
 	oilchemService "eta/eta_data_analysis/services/base_from_oilchem"
 	"eta/eta_data_analysis/services/fenwei"
+	"eta/eta_data_analysis/services/liangyou"
 	"eta/eta_data_analysis/utils"
 	"fmt"
 	"github.com/beego/beego/v2/task"
@@ -56,6 +57,12 @@ func Task() {
 		task.AddTask("汾渭网络数据处理", fenWeiNetDataDeal)
 	}
 
+	if utils.LY_OPEN == "1" {
+		lyData := task.NewTask("refreshData", "0 0 12 * * *", liangyou.LyDataDeal) // 粮油商务网
+
+		task.AddTask("粮油商务网", lyData)
+	}
+
 	if utils.MtjhOpen == "1" {
 		c := cron.New(cron.WithSeconds())
 		//每2分钟检测一次指标文件是否更新

+ 497 - 0
static/liangyou.json

@@ -0,0 +1,497 @@
+{
+  "大豆": {
+    "进口成本": {
+      "国际大豆进口成本参考价": [
+        "美湾:国际大豆进口成本价:期货收盘:张家港:美分/蒲式耳:日度",
+        "美湾:国际大豆进口成本价:升贴水:张家港:美分/蒲式耳:日度",
+        "美湾:国际大豆进口成本价:FOB价:张家港:美元/吨:日度",
+        "美湾:国际大豆进口成本价:运费:张家港:美元/吨:日度",
+        "美湾:国际大豆进口成本价:CNF升贴水:张家港:美分/蒲式耳:日度",
+        "美湾:国际大豆进口成本价:CNF:张家港:美元/吨:日度",
+        "美湾:国际大豆进口成本价:进口成本:张家港:元/吨:日度",
+        "巴西:国际大豆进口成本价:期货收盘:张家港:美分/蒲式耳:日度",
+        "巴西:国际大豆进口成本价:升贴水:张家港:美分/蒲式耳:日度",
+        "巴西:国际大豆进口成本价:FOB价:张家港:美元/吨:日度",
+        "巴西:国际大豆进口成本价:运费:张家港:美元/吨:日度",
+        "巴西:国际大豆进口成本价:CNF升贴水:张家港:美分/蒲式耳:日度",
+        "巴西:国际大豆进口成本价:CNF:张家港:美元/吨:日度",
+        "巴西:国际大豆进口成本价:进口成本:张家港:元/吨:日度"
+      ]
+    },
+    "加工利润": {
+      "进口大豆盘面榨利及现货榨利表": [
+        "美湾:进口大豆盘面榨利:元/吨:日度",
+        "巴西:进口大豆盘面榨利:元/吨:日度",
+        "美湾:进口大豆现货榨利:元/吨:日度",
+        "巴西:进口大豆现货榨利:元/吨:日度"
+      ]
+    },
+    "船运费用": {
+      "国际谷物船运费报价及走势图": [
+        "巴西桑托斯:中国北方港口:超灵便型船:国际谷物船运费:当日价格:美元:日度",
+        "阿根廷:中国北方港口:巴拿马型船:国际谷物船运费:当日价格:美元:日度",
+        "美湾密西西比河:中国北方港口:巴拿马型船:国际谷物船运费:当日价格:美元:日度",
+        "美西塔科马:中国北方港口:巴拿马型船:国际谷物船运费:当日价格:美元:日度",
+        "美国北太平洋沿岸:中国:巴拿马型船:国际谷物船运费:当日价格:美元:日度",
+        "美国墨西哥湾:中国:巴拿马型船:国际谷物船运费:当日价格:美元:日度",
+        "巴西巴拉那瓜:中国:巴拿马型船:国际谷物船运费:当日价格:美元:日度",
+        "伊特科提亚拉港:中国:巴拿马型船:国际谷物船运费:当日价格:美元:日度",
+        "波罗的海巴拿马型指数(BPI):国际谷物船运费:当日价格:%:日度",
+        "波罗的海超灵便型指数(BSI):国际谷物船运费:当日价格:%:日度",
+        "波罗的海海岬型指数(BCI):国际谷物船运费:当日价格:%:日度",
+        "波罗的海干散货指数(BDI):国际谷物船运费:当日价格:%:日度",
+        "波罗的海灵便型指数(BHSI):国际谷物船运费:当日价格:%:日度"
+      ]
+    },
+    "供需平衡": {
+      "年度中国大豆市场供需报告": [
+        "中国大豆市场供需:期初库存:万吨:月度",
+        "中国大豆市场供需:种植面积:万吨:月度",
+        "中国大豆市场供需:国内产量:万吨:月度",
+        "中国大豆市场供需:进口量:万吨:月度",
+        "中国大豆市场供需:总供应量:万吨:月度",
+        "中国大豆市场供需:压榨用量:万吨:月度",
+        "中国大豆市场供需:其中:国产大豆:万吨:月度",
+        "中国大豆市场供需:进口大豆:万吨:月度",
+        "中国大豆市场供需:出口量:万吨:月度",
+        "中国大豆市场供需:食用量:万吨:月度",
+        "中国大豆市场供需:种用及其他:万吨:月度",
+        "中国大豆市场供需:总需求量:万吨:月度",
+        "中国大豆市场供需:期末库存:万吨:月度"
+      ]
+    },
+    "采购装船": {
+      "中国大豆采购进度周统计": [
+        "中国大豆计划采购量:万吨:周度",
+        "中国大豆已采购量:美国:万吨:周度",
+        "中国大豆已采购量:巴西:万吨:周度",
+        "中国大豆已采购量:阿根廷/乌拉圭:万吨:周度",
+        "中国大豆已采购量:小计:万吨:周度",
+        "中国大豆未采购量:万吨:周度",
+        "中国大豆采购进度:%:周度"
+      ]
+    },
+    "加工报告": {
+      "国内大豆周度加工量调查": [
+        "国内大豆加工量:河南省:万吨:周度",
+        "国内大豆加工量:湖北省:万吨:周度",
+        "国内大豆加工量:湖南省:万吨:周度",
+        "国内大豆加工量:黑龙江:万吨:周度",
+        "国内大豆加工量:吉林省:万吨:周度",
+        "国内大豆加工量:辽宁省:万吨:周度",
+        "国内大豆加工量:内蒙古:万吨:周度",
+        "国内大豆加工量:河北省:万吨:周度",
+        "国内大豆加工量:天津市:万吨:周度",
+        "国内大豆加工量:江西省:万吨:周度",
+        "国内大豆加工量:山东省:万吨:周度",
+        "国内大豆加工量:安徽省:万吨:周度",
+        "国内大豆加工量:江苏省:万吨:周度",
+        "国内大豆加工量:上海市:万吨:周度",
+        "国内大豆加工量:浙江省:万吨:周度",
+        "国内大豆加工量:福建省:万吨:周度",
+        "国内大豆加工量:广东省:万吨:周度",
+        "国内大豆加工量:广西省:万吨:周度",
+        "国内大豆加工量:海南省:万吨:周度",
+        "国内大豆加工量:陕西省:万吨:周度",
+        "国内大豆加工量:四川省:万吨:周度",
+        "国内大豆加工量:重庆市:万吨:周度",
+        "国内大豆加工量:云南省:万吨:周度",
+        "国内大豆加工量:合计:万吨:周度",
+        "国内大豆加工量:其中:国产:万吨:周度",
+        "国内大豆加工量:进口:万吨:周度",
+        "国内大豆开机率:河南省:%:周度",
+        "国内大豆开机率:湖北省:%:周度",
+        "国内大豆开机率:湖南省:%:周度",
+        "国内大豆开机率:黑龙江:%:周度",
+        "国内大豆开机率:吉林省:%:周度",
+        "国内大豆开机率:辽宁省:%:周度",
+        "国内大豆开机率:内蒙古:%:周度",
+        "国内大豆开机率:河北省:%:周度",
+        "国内大豆开机率:天津市:%:周度",
+        "国内大豆开机率:山西省:%:周度",
+        "国内大豆开机率:山东省:%:周度",
+        "国内大豆开机率:安徽省:%:周度",
+        "国内大豆开机率:江苏省:%:周度",
+        "国内大豆开机率:上海市:%:周度",
+        "国内大豆开机率:浙江省:%:周度",
+        "国内大豆开机率:福建省:%:周度",
+        "国内大豆开机率:广东省:%:周度",
+        "国内大豆开机率:广西省:%:周度",
+        "国内大豆开机率:海南省:%:周度",
+        "国内大豆开机率:陕西省:%:周度",
+        "国内大豆开机率:四川省:%:周度",
+        "国内大豆开机率:重庆市:%:周度",
+        "国内大豆开机率:云南省:%:周度",
+        "国内大豆开机率:合计:%:周度",
+        "国内大豆开机率:其中:国产:%:周度",
+        "国内大豆开机率:进口:%:周度"
+      ]
+    },
+    "库存分析": {
+      "全国油厂进口大豆库存量统计周报": [
+        "全国油厂进口大豆库存量(万吨):东北地区:万吨:周度",
+        "全国油厂进口大豆库存量(万吨):华北地区:万吨:周度",
+        "全国油厂进口大豆库存量(万吨):华东地区:万吨:周度",
+        "全国油厂进口大豆库存量(万吨):华南地区:万吨:周度",
+        "全国油厂进口大豆库存量(万吨):西南地区:万吨:周度",
+        "全国油厂进口大豆库存量(万吨):其他地区:万吨:周度",
+        "全国油厂进口大豆库存量(万吨):全国统计:万吨:周度",
+        "全国油厂进口大豆库存量(万吨):其中:沿海库存:万吨:周度"
+      ]
+    }
+  },
+  "豆粕": {
+    "库存分析": {
+      "全国油厂豆粕库存与合同统计周报": [
+        "全国油厂豆粕库存量(万吨):东北地区:万吨:周度",
+        "全国油厂豆粕库存量(万吨):华北地区:万吨:周度",
+        "全国油厂豆粕库存量(万吨):华东地区:万吨:周度",
+        "全国油厂豆粕库存量(万吨):华中地区:万吨:周度",
+        "全国油厂豆粕库存量(万吨):华南地区:万吨:周度",
+        "全国油厂豆粕库存量(万吨):西南地区:万吨:周度",
+        "全国油厂豆粕库存量(万吨):西北地区:万吨:周度",
+        "全国油厂豆粕库存量(万吨):全国合计:万吨:周度",
+        "全国油厂豆粕库存量(万吨):其中:沿海库存:万吨:周度",
+        "全国油厂豆粕合同量(万吨):东北地区:万吨:周度",
+        "全国油厂豆粕合同量(万吨):华北地区:万吨:周度",
+        "全国油厂豆粕合同量(万吨):华东地区:万吨:周度",
+        "全国油厂豆粕合同量(万吨):华中地区:万吨:周度",
+        "全国油厂豆粕合同量(万吨):华南地区:万吨:周度",
+        "全国油厂豆粕合同量(万吨):西南地区:万吨:周度",
+        "全国油厂豆粕合同量(万吨):西北地区:万吨:周度",
+        "全国油厂豆粕合同量(万吨):全国合计:万吨:周度",
+        "全国油厂豆粕合同量(万吨):其中:沿海库存:万吨:周度"
+      ]
+    }
+  },
+  "大豆油": {
+    "库存分析": {
+      "全国油厂豆油库存与合同统计周报": [
+        "全国油厂豆油库存量(万吨):东北地区:万吨:周度",
+        "全国油厂豆油库存量(万吨):华北地区:万吨:周度",
+        "全国油厂豆油库存量(万吨):华东地区:万吨:周度",
+        "全国油厂豆油库存量(万吨):华中地区:万吨:周度",
+        "全国油厂豆油库存量(万吨):华南地区:万吨:周度",
+        "全国油厂豆油库存量(万吨):西南地区:万吨:周度",
+        "全国油厂豆油库存量(万吨):西北地区:万吨:周度",
+        "全国油厂豆油库存量(万吨):全国合计:万吨:周度",
+        "全国油厂豆油库存量(万吨):其中:沿海库存:万吨:周度",
+        "全国油厂豆油合同量(万吨):东北地区:万吨:周度",
+        "全国油厂豆油合同量(万吨):华北地区:万吨:周度",
+        "全国油厂豆油合同量(万吨):华东地区:万吨:周度",
+        "全国油厂豆油合同量(万吨):华中地区:万吨:周度",
+        "全国油厂豆油合同量(万吨):华南地区:万吨:周度",
+        "全国油厂豆油合同量(万吨):西南地区:万吨:周度",
+        "全国油厂豆油合同量(万吨):西北地区:万吨:周度",
+        "全国油厂豆油合同量(万吨):全国合计:万吨:周度",
+        "全国油厂豆油合同量(万吨):其中:沿海库存:万吨:周度"
+      ]
+    },
+    "价差套利": {
+      "豆棕油期现货价差统计": [
+        "棕榈油主力:大商所:期现货价差:元/吨:日度",
+        "豆油主力:大商所:期现货价差:元/吨:日度",
+        "24度棕榈油:进口液:期现货价差:元/吨:日度",
+        "一级豆油:进口压榨:期现货价差:元/吨:日度"
+      ]
+    },
+    "每日成交": {
+      "豆油成交量及价格统计": [
+        "豆油成交量:东北:吨:日度",
+        "豆油成交量:华北:吨:日度",
+        "豆油成交量:江苏:吨:日度",
+        "豆油成交量:浙江:吨:日度",
+        "豆油成交量:山东:吨:日度",
+        "豆油成交量:广东:吨:日度",
+        "豆油成交量:广西:吨:日度",
+        "豆油成交量:福建:吨:日度",
+        "豆油成交量:其他:吨:日度",
+        "豆油成交量:合计:吨:日度",
+        "豆油周度成交量:东北:吨:周度",
+        "豆油周度成交量:华北:吨:周度",
+        "豆油周度成交量:江苏:吨:周度",
+        "豆油周度成交量:浙江:吨:周度",
+        "豆油周度成交量:山东:吨:周度",
+        "豆油周度成交量:广东:吨:周度",
+        "豆油周度成交量:广西:吨:周度",
+        "豆油周度成交量:福建:吨:周度",
+        "豆油周度成交量:其他:吨:周度",
+        "豆油周度成交量:合计:吨:周度",
+        "主要集团:九三:豆油现货成交量:吨:周度",
+        "主要集团:中粮:豆油现货成交量:吨:周度",
+        "主要集团:中储粮:豆油现货成交量:吨:周度",
+        "豆油成交量:东北:1:吨:日度",
+        "豆油成交量:华北:1:吨:日度",
+        "豆油成交量:江苏:1:吨:日度",
+        "豆油成交量:浙江:1:吨:日度",
+        "豆油成交量:山东:1:吨:日度",
+        "豆油成交量:广东:1:吨:日度",
+        "豆油成交量:广西:1:吨:日度",
+        "豆油成交量:福建:1:吨:日度",
+        "豆油成交量:其他:1:吨:日度",
+        "豆油成交量:合计:1:吨:日度",
+        "豆油周度成交量:东北:1:吨:周度",
+        "豆油周度成交量:华北:1:吨:周度",
+        "豆油周度成交量:江苏:1:吨:周度",
+        "豆油周度成交量:浙江:1:吨:周度",
+        "豆油周度成交量:山东:1:吨:周度",
+        "豆油周度成交量:广东:1:吨:周度",
+        "豆油周度成交量:广西:1:吨:周度",
+        "豆油周度成交量:福建:1:吨:周度",
+        "豆油周度成交量:其他:1:吨:周度",
+        "豆油周度成交量:合计:1:吨:周度",
+        "主要集团:九三:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:中粮:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:中储粮:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:达孚:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:嘉吉:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:金光:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:邦基:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:益海:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:汇福:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:渤海:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:香驰:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:中海:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:其他:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:总计:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:九三:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:中粮:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:中储粮:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:达孚:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:嘉吉:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:金光:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:邦基:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:益海:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:汇福:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:渤海:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:香驰:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:中海:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:其他:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:总计:豆油基差成交量:本周(吨)基差成交:吨:周度"
+      ]
+    }
+  },
+  "棕榈油": {
+    "国际价格": {
+      "国际棕榈油FOB报价及走势": [
+        "马来棕榈液油:FOB价格:美元/吨:日度",
+        "马来棕榈油:FOB价格:美元/吨:日度",
+        "马来棕榈硬脂:FOB价格:美元/吨:日度",
+        "印尼毛棕油:FOB价格:美元/吨:日度"
+      ]
+    },
+    "进口成本": {
+      "马来西亚棕榈油进口成本参考价": [
+        "棕榈液油(24度):运费:张家港:美元/吨:日度",
+        "棕榈液油(24度):CNF:张家港:美元/吨:日度",
+        "棕榈液油(24度):完税价:张家港:美元/吨:日度",
+        "棕榈液油(24度):进口成本:张家港:元/吨:日度"
+      ]
+    },
+    "库存分析": {
+      "全国棕榈油库存与合同统计周报": [
+        "棕榈油24度及以下库存:华北地区:万吨:周度",
+        "棕榈油24度及以下库存:华东地区:万吨:周度",
+        "棕榈油24度及以下库存:华南地区:万吨:周度",
+        "棕榈油24度及以下库存:其他地区:万吨:周度",
+        "棕榈油24度及以下库存:全国合计:万吨:周度",
+        "棕油总库存:华北地区:万吨:周度",
+        "棕油总库存:华东地区:万吨:周度",
+        "棕油总库存:华南地区:万吨:周度",
+        "棕油总库存:其他地区:万吨:周度",
+        "棕油总库存:全国合计:万吨:周度",
+        "棕榈油合同量:华北地区:万吨:周度",
+        "棕榈油合同量:华东地区:万吨:周度",
+        "棕榈油合同量:华南地区:万吨:周度",
+        "棕榈油合同量:其他地区:万吨:周度",
+        "棕榈油合同量:全国合计:万吨:周度"
+      ]
+    },
+    "每日成交": {
+      "棕榈油成交量及价格统计": [
+        "棕榈油成交量:华北:1:吨:日度",
+        "棕榈油成交量:山东:1:吨:日度",
+        "棕榈油成交量:江苏:1:吨:日度",
+        "棕榈油成交量:浙江:1:吨:日度",
+        "棕榈油成交量:福建:1:吨:日度",
+        "棕榈油成交量:广东:1:吨:日度",
+        "棕榈油成交量:广西:1:吨:日度",
+        "棕榈油成交量:其他:1:吨:日度",
+        "棕榈油成交量:合计:1:吨:日度",
+        "棕榈油周度成交量:华北:1:吨:日度",
+        "棕榈油周度成交量:山东:1:吨:日度",
+        "棕榈油周度成交量:江苏:1:吨:日度",
+        "棕榈油周度成交量:浙江:1:吨:日度",
+        "棕榈油周度成交量:福建:1:吨:日度",
+        "棕榈油周度成交量:广东:1:吨:日度",
+        "棕榈油周度成交量:广西:1:吨:日度",
+        "棕榈油周度成交量:其他:1:吨:日度",
+        "棕榈油周度成交量:合计:1:吨:日度",
+        "主要集团:中粮:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:金光:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:益海:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:来宝:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:合益荣:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:其他:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:总计:豆油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:中粮:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:金光:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:益海:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:来宝:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:合益荣:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:其他:豆油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:总计:豆油基差成交量:本周(吨)基差成交:吨:周度"
+      ]
+    }
+  },
+  "油菜籽": {
+    "进口成本": {
+      "加拿大油菜籽理论进口成本": [
+        "加拿大油菜籽:期货收盘:广州港:美分/蒲式耳:日度",
+        "加拿大油菜籽:升贴水:广州港:美元/吨:日度",
+        "加拿大油菜籽:FOB价:广州港:美元/吨:日度",
+        "加拿大油菜籽:运费:广州港:美元/吨:日度",
+        "加拿大油菜籽:CNF升贴水:广州港:美元/吨:日度",
+        "加拿大油菜籽:CNF:广州港:美元/吨:日度",
+        "加拿大油菜籽:进口成本:广州港:元/吨:日度"
+      ]
+    },
+    "库存分析": {
+      "全国油厂进口油菜籽库存量统计周报": [
+        "全国油厂进口油菜籽库存量:广西地区:万吨:周度",
+        "全国油厂进口油菜籽库存量:广东地区:万吨:周度",
+        "全国油厂进口油菜籽库存量:福建地区:万吨:周度",
+        "全国油厂进口油菜籽库存量:江苏地区:万吨:周度",
+        "全国油厂进口油菜籽库存量:辽宁地区:万吨:周度",
+        "全国油厂进口油菜籽库存量:其它地区:万吨:周度",
+        "全国油厂进口油菜籽库存量:全国统计:万吨:周度"
+      ]
+    },
+    "进口预估": {
+      "进口油菜籽月度进口量预估": [
+        "进口油菜籽月度进口量预估:本年进口量:万吨:周度",
+        "进口油菜籽月度进口量预估:本年海关进口量:万吨:周度"
+      ]
+    },
+    "加拿大统计局": {
+      "加拿大双低油菜籽周度商业库存": [
+        "加拿大双低油菜籽:期初库存:万吨:周度",
+        "加拿大双低油菜籽:上市量:万吨:周度",
+        "加拿大双低油菜籽:出口量:万吨:周度",
+        "加拿大双低油菜籽:消费量:万吨:周度",
+        "加拿大双低油菜籽:期末库存:万吨:周度"
+      ]
+    },
+    "进出口分析": {
+      "油菜籽进口数量分析": [
+        "油菜籽进口量:万吨:月度"
+      ],
+      "油菜籽出口数量分析": [
+        "油菜籽出口量:吨:月度"
+      ]
+    }
+  },
+  "菜粕": {
+    "库存分析": {
+      "全国油厂进口压榨菜粕库存与合同统计周报": [
+        "全国油厂进口压榨菜粕库存量:广西地区:万吨:周度",
+        "全国油厂进口压榨菜粕库存量:广东地区:万吨:周度",
+        "全国油厂进口压榨菜粕库存量:福建地区:万吨:周度",
+        "全国油厂进口压榨菜粕库存量:江苏地区:万吨:周度",
+        "全国油厂进口压榨菜粕库存量:辽宁地区:万吨:周度",
+        "全国油厂进口压榨菜粕库存量:其他地区:万吨:周度",
+        "全国油厂进口压榨菜粕库存量:全国合计:万吨:周度",
+        "全国油厂进口压榨菜粕合同量:广西地区:万吨:周度",
+        "全国油厂进口压榨菜粕合同量:广东地区:万吨:周度",
+        "全国油厂进口压榨菜粕合同量:福建地区:万吨:周度",
+        "全国油厂进口压榨菜粕合同量:江苏地区:万吨:周度",
+        "全国油厂进口压榨菜粕合同量:辽宁地区:万吨:周度",
+        "全国油厂进口压榨菜粕合同量:其他地区:万吨:周度",
+        "全国油厂进口压榨菜粕合同量:全国合计:万吨:周度"
+
+      ]
+    },
+    "进出口分析": {
+      "菜粕出口数量分析": [
+        "菜粕出口数量:吨:月度"
+      ],
+      "菜粕进口数量分析": [
+        "菜粕进口数量:万吨:月度"
+      ]
+    }
+  },
+  "菜籽油": {
+    "库存分析": {
+      "全国油厂进口压榨菜油库存与合同统计周报": [
+        "全国油厂进口压榨菜油库存量:广西地区:万吨:周度",
+        "全国油厂进口压榨菜油库存量:广东地区:万吨:周度",
+        "全国油厂进口压榨菜油库存量:福建地区:万吨:周度",
+        "全国油厂进口压榨菜油库存量:江苏地区:万吨:周度",
+        "全国油厂进口压榨菜油库存量:辽宁地区:万吨:周度",
+        "全国油厂进口压榨菜油库存量:其他地区:万吨:周度",
+        "全国油厂进口压榨菜油库存量:全国合计:万吨:周度",
+        "全国油厂进口压榨菜油库存量:其中:非油企库存:万吨:周度",
+        "全国油厂进口压榨菜油库存量:油企库存:万吨:周度",
+        "全国油厂进口压榨菜油合同量:广西地区:万吨:周度",
+        "全国油厂进口压榨菜油合同量:广东地区:万吨:周度",
+        "全国油厂进口压榨菜油合同量:福建地区:万吨:周度",
+        "全国油厂进口压榨菜油合同量:江苏地区:万吨:周度",
+        "全国油厂进口压榨菜油合同量:辽宁地区:万吨:周度",
+        "全国油厂进口压榨菜油合同量:其他地区:万吨:周度",
+        "全国油厂进口压榨菜油合同量:全国合计:万吨:周度",
+        "全国油厂进口压榨菜油合同量:其中:非油企库存:万吨:周度",
+        "全国油厂进口压榨菜油合同量:油企库存:万吨:周度"
+      ]
+    },
+    "进口预估": {
+      "菜籽油月度进口量预估": [
+        "菜籽油月度进口量预估:本年进口量:万吨:周度",
+        "菜籽油月度进口量预估:本年海关进口量:万吨:周度"
+      ]
+    },
+    "每日成交": {
+      "菜籽油成交量及价格统计": [
+        "菜籽油成交量:东北:1:吨:日度",
+        "菜籽油成交量:华东:1:吨:日度",
+        "菜籽油成交量:福建:1:吨:日度",
+        "菜籽油成交量:广东:1:吨:日度",
+        "菜籽油成交量:广西:1:吨:日度",
+        "菜籽油成交量:其它:1:吨:日度",
+        "菜籽油成交量:合计:1:吨:日度",
+        "菜籽油成交量:华南合计:1:吨:日度",
+        "菜籽油成交量:沿海合计:1:吨:日度",
+        "菜籽油周度成交量:东北:1:吨:周度",
+        "菜籽油周度成交量:华东:1:吨:周度",
+        "菜籽油周度成交量:福建:1:吨:周度",
+        "菜籽油周度成交量:广东:1:吨:周度",
+        "菜籽油周度成交量:广西:1:吨:周度",
+        "菜籽油周度成交量:其它:1:吨:周度",
+        "菜籽油周度成交量:合计:1:吨:周度",
+        "菜籽油周度成交量:华南合计:1:吨:周度",
+        "菜籽油周度成交量:沿海合计:1:吨:周度",
+        "主要集团:营口嘉里:菜籽油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:富之源:菜籽油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:防城大海:菜籽油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:防城澳加:菜籽油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:成都中粮:菜籽油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:其它:菜籽油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:总计:菜籽油现货成交量:本周(吨)现货成交:吨:周度",
+        "主要集团:营口嘉里:菜籽油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:富之源:菜籽油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:防城大海:菜籽油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:防城澳加:菜籽油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:成都中粮:菜籽油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:其它:菜籽油基差成交量:本周(吨)基差成交:吨:周度",
+        "主要集团:总计:菜籽油基差成交量:本周(吨)基差成交:吨:周度"
+      ]
+    }
+  },
+  "葵花粕": {
+    "进口预估": {
+      "进口葵花粕月度进口量预估": [
+        "进口葵花粕月度进口量预估:本年进口量:万吨:周度",
+        "进口葵花粕月度进口量预估:本年海关进口量:万吨:周度"
+      ]
+    }
+  }
+}

+ 17 - 2
utils/config.go

@@ -72,6 +72,14 @@ var (
 	MtjhOpen     string //是否配置煤炭江湖数据源,1已配置
 )
 
+// 粮油商务网
+var (
+	LY_USERNAME  string
+	LY_PASSWORD  string
+	LY_JSON_PATH string
+	LY_OPEN      string
+)
+
 // CCF化纤信息
 var (
 	CCFOpen           string // 是否配置CCF
@@ -88,8 +96,8 @@ var (
 	OilchemAccount    string
 	OilchemPassword   string
 	OilchemCookieFile string
-	OilchemOpen string
-	OilchemDataInit string
+	OilchemOpen       string
+	OilchemDataInit   string
 )
 
 var TerminalCode string
@@ -184,6 +192,13 @@ func init() {
 		CCFPassword = config["ccf_password"]
 	}
 
+	{
+		LY_USERNAME = config["ly_username"]
+		LY_PASSWORD = config["ly_password"]
+		LY_JSON_PATH = config["ly_json_path"]
+		LY_OPEN = config["ly_open"]
+	}
+
 	// 隆众数据
 	{
 		OilchemAccount = config["oilchem_account"]

+ 35 - 25
utils/constants.go

@@ -97,6 +97,7 @@ const (
 	DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION            //预测标准差->69
 	DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE                    //预测百分位->70
 	DATA_SOURCE_FUBAO                                           //富宝数据->71
+	DATA_SOURCE_LY                                   = 91       // 粮油商务网
 )
 
 // 指标来源的中文展示
@@ -233,29 +234,38 @@ var FrequencyDaysMap = map[string]int{
 
 // edb_index_lib 的接口名称
 const (
-	LIB_ROUTE_YONGYI_HANDLE                  = "yongyi/handle/excel_data"                     //涌益咨询处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_JSM_HISTORY          = "/coal_mine/jsm/history"                       //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_COASTAL_HISTORY      = "/coal_mine/coastal/history"                   //沿海煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_INLAND_HISTORY       = "/coal_mine/inland/history"                    //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_JSM                  = "/coal_mine/jsm"                               //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_COASTAL              = "/coal_mine/coastal"                           //沿海煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_INLAND               = "/coal_mine/inland"                            //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
-	LIB_ROUTE_COAL_MINE_FIRM                 = "/coal_mine/firm"                              //分公司旬度煤炭网数据处理excel数据并入库 数据地址
-	LIB_ROUTE_FENWEI_HANDLE                  = "fenwei/handle/excel_data"                     // 汾渭煤炭excel数据入库接口地址
-	LIB_ROUTE_FENWEI_CLASSIFY                = "fenwei/classify_tree"                         // 汾渭煤炭分类接口地址
-	LIB_ROUTE_FENWEI_INDEX_LIST              = "fenwei/base_index_list"                       // 汾渭煤炭指标列表接口地址
-	LIB_ROUTE_COAL_MINE_MTJH                 = "/mtjh/data"                                   //煤炭江湖数据处理excel数据并入库 数据地址
-	LIB_ROUTE_CCF_EDB_HANDLE                 = "ccf/handle/edb_data"                          // CCF化纤信息指标入库接口地址
-	LIB_ROUTE_CCF_TABLE_HANDLE               = "ccf/handle/table_data"                        // CCF化纤信息装置表格入库接口地址
-	LIB_ROUTE_OILCHEM_TABLE_HANDLE           = "oilchem/handle/edb_data"                      // 隆众资讯入库接口地址
-	LIB_ROUTE_FENWEI_NET_DATA_HANDLE         = "/fenwei/net/data/handle"                      // 汾渭网页数据处理
-	GET_LY_CLASSIFY_BY_NAME                  = "/ly/get/ly/classify/by/name"                  // 获取分类
-	GET_LY_INDEX_RECORD_BY_URL               = "/ly/get/ly/index/record/by/url"               // 根据url获取指标已读取记录
-	ADD_LY_INDEX_RECORD                      = "/ly/add/ly/index/record"                      // 维护指标数据读取进度到数据库
-	ADD_LY_DATA_LIST                         = "/ly/add/ly/data/list"                         // 新增指标数据列表
-	ADD_LY_INDEX                             = "/ly/add/ly/index"                             // 新增指标
-	GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME    = "/ly/get/ly/data/by/index/id/and/data/time"    // 根据指标id和时间获取指标数据
-	GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME_YM = "/ly/get/ly/data/by/index/id/and/data/time/ym" // 根据指标id和年月时间获取指标数据
-	UPDATE_LY_DATA_BY_ID                     = "/ly/update/ly/data/by/id"                     // 更新数据源指标数据
-	UPDATE_LY_EDB_DATA_BY_ID                 = "/ly/update/ly/edb/data/by/id"                 // 更新指标库指标数据
+	LIB_ROUTE_YONGYI_HANDLE                           = "yongyi/handle/excel_data"                              //涌益咨询处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_JSM_HISTORY                   = "/coal_mine/jsm/history"                                //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_COASTAL_HISTORY               = "/coal_mine/coastal/history"                            //沿海煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_INLAND_HISTORY                = "/coal_mine/inland/history"                             //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_JSM                           = "/coal_mine/jsm"                                        //jsm三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_COASTAL                       = "/coal_mine/coastal"                                    //沿海煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_INLAND                        = "/coal_mine/inland"                                     //内陆三省煤炭网历史数据处理excel数据并入库 数据地址
+	LIB_ROUTE_COAL_MINE_FIRM                          = "/coal_mine/firm"                                       //分公司旬度煤炭网数据处理excel数据并入库 数据地址
+	LIB_ROUTE_FENWEI_HANDLE                           = "fenwei/handle/excel_data"                              // 汾渭煤炭excel数据入库接口地址
+	LIB_ROUTE_FENWEI_CLASSIFY                         = "fenwei/classify_tree"                                  // 汾渭煤炭分类接口地址
+	LIB_ROUTE_FENWEI_INDEX_LIST                       = "fenwei/base_index_list"                                // 汾渭煤炭指标列表接口地址
+	LIB_ROUTE_COAL_MINE_MTJH                          = "/mtjh/data"                                            //煤炭江湖数据处理excel数据并入库 数据地址
+	LIB_ROUTE_CCF_EDB_HANDLE                          = "ccf/handle/edb_data"                                   // CCF化纤信息指标入库接口地址
+	LIB_ROUTE_CCF_TABLE_HANDLE                        = "ccf/handle/table_data"                                 // CCF化纤信息装置表格入库接口地址
+	LIB_ROUTE_OILCHEM_TABLE_HANDLE                    = "oilchem/handle/edb_data"                               // 隆众资讯入库接口地址
+	LIB_ROUTE_FENWEI_NET_DATA_HANDLE                  = "/fenwei/net/data/handle"                               // 汾渭网页数据处理
+	GET_LY_CLASSIFY_BY_NAME                           = "/ly/get/ly/classify/by/name"                           // 获取分类
+	GET_LY_INDEX_RECORD_BY_URL                        = "/ly/get/ly/index/record/by/url"                        // 根据url获取指标已读取记录
+	ADD_LY_INDEX_RECORD                               = "/ly/add/ly/index/record"                               // 维护指标数据读取进度到数据库
+	ADD_LY_DATA_LIST                                  = "/ly/add/ly/data/list"                                  // 新增指标数据列表
+	ADD_LY_INDEX                                      = "/ly/add/ly/index"                                      // 新增指标
+	GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME             = "/ly/get/ly/data/by/index/id/and/data/time"             // 根据指标id和时间获取指标数据
+	GET_LY_DATA_BY_INDEX_ID_AND_DATA_TIME_YM          = "/ly/get/ly/data/by/index/id/and/data/time/ym"          // 根据指标id和年月时间获取指标数据
+	UPDATE_LY_DATA_BY_ID                              = "/ly/update/ly/data/by/id"                              // 更新数据源指标数据
+	UPDATE_LY_EDB_DATA_BY_ID                          = "/ly/update/ly/edb/data/by/id"                          // 更新指标库指标数据
+	GET_LY_EDB_DATA_BY_INDEX_CODE_AND_DATA_TIME       = "/ly/get/ly/edb/data/by/index/code/and/data/time"       // 根据指标编码和模糊日期获取指标库数据
+	GET_LY_EDB_DATA_BY_INDEX_CODE_AND_EXACT_DATA_TIME = "/ly/get/ly/edb/data/by/index/code/and/exact/data/time" //根据指标编码和精确日期获取指标库数据
+	GET_LY_INDEX_BY_CODE                              = "/ly/get/ly/index/by/code"                              // 根据指标编码获取指标
+	GET_EDB_INFO_BY_INDEX_CODE                        = "/ly/get/edb/info/by/index/code"                        // 根据指标code获取指标信息
+	ADD_BATCH_LY_EDB_DATA                             = "/ly/add/batch/ly/edb/data"                             // 批量增加粮油指标库数据
+)
+
+const (
+	APPNAME = "弘则-数据爬虫"
 )