作者 yangfu

Merge branch 'feature_bsn' into feature_sign_up

@@ -20,6 +20,8 @@ require ( @@ -20,6 +20,8 @@ require (
20 github.com/sergi/go-diff v1.2.0 // indirect 20 github.com/sergi/go-diff v1.2.0 // indirect
21 github.com/smartystreets/goconvey v1.6.4 // indirect 21 github.com/smartystreets/goconvey v1.6.4 // indirect
22 github.com/stretchr/testify v1.7.0 22 github.com/stretchr/testify v1.7.0
  23 + github.com/tal-tech/go-queue v1.0.5
  24 + github.com/tal-tech/go-zero v1.0.27
23 github.com/valyala/fasthttp v1.23.0 // indirect 25 github.com/valyala/fasthttp v1.23.0 // indirect
24 github.com/xeipuuv/gojsonschema v1.2.0 // indirect 26 github.com/xeipuuv/gojsonschema v1.2.0 // indirect
25 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect 27 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
@@ -21,6 +21,7 @@ github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+Dx @@ -21,6 +21,7 @@ github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+Dx
21 github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= 21 github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
22 github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= 22 github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
23 github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= 23 github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
  24 +github.com/beanstalkd/go-beanstalk v0.1.0/go.mod h1:/G8YTyChOtpOArwLTQPY1CHB+i212+av35bkPXXj56Y=
24 github.com/beego/beego/v2 v2.0.1 h1:07a7Z0Ok5vbqyqh+q53sDPl9LdhKh0ZDy3gbyGrhFnE= 25 github.com/beego/beego/v2 v2.0.1 h1:07a7Z0Ok5vbqyqh+q53sDPl9LdhKh0ZDy3gbyGrhFnE=
25 github.com/beego/beego/v2 v2.0.1/go.mod h1:8zyHi1FnWO1mZLwTn62aKRIZF/aIKvkCBB2JYs+eqQI= 26 github.com/beego/beego/v2 v2.0.1/go.mod h1:8zyHi1FnWO1mZLwTn62aKRIZF/aIKvkCBB2JYs+eqQI=
26 github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= 27 github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
@@ -179,6 +180,7 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b @@ -179,6 +180,7 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
179 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= 180 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
180 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 181 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
181 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 182 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
  183 +github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
182 github.com/iancoleman/strcase v0.1.2/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= 184 github.com/iancoleman/strcase v0.1.2/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
183 github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= 185 github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
184 github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= 186 github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
@@ -204,6 +206,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW @@ -204,6 +206,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
204 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= 206 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
205 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 207 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
206 github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 208 github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
  209 +github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
207 github.com/klauspost/compress v1.11.8 h1:difgzQsp5mdAz9v8lm3P/I+EpDKMU/6uTMw1y1FObuo= 210 github.com/klauspost/compress v1.11.8 h1:difgzQsp5mdAz9v8lm3P/I+EpDKMU/6uTMw1y1FObuo=
208 github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= 211 github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
209 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 212 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -312,6 +315,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L @@ -312,6 +315,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
312 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 315 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
313 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 316 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
314 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 317 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
  318 +github.com/segmentio/kafka-go v0.4.2 h1:QXZ6q9Bu1JkAJQ/CQBb2Av8pFRG8LQ0kWCrLXgQyL8c=
  319 +github.com/segmentio/kafka-go v0.4.2/go.mod h1:Inh7PqOsxmfgasV8InZYKVXWsdjcCq2d9tFV75GLbuM=
315 github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= 320 github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
316 github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 321 github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
317 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo= 322 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
@@ -347,6 +352,9 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc @@ -347,6 +352,9 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
347 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 352 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
348 github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= 353 github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
349 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= 354 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
  355 +github.com/tal-tech/go-queue v1.0.5 h1:cd2o0lPjAFJKIXuEbQvsGypUhzz6FLib4FVVAyxsMtY=
  356 +github.com/tal-tech/go-queue v1.0.5/go.mod h1:gQK4Eg8pqel8Z9r1hjlSXbJFavLeJQVyTSwBKeAnpm8=
  357 +github.com/tal-tech/go-zero v1.0.21/go.mod h1:llP5PQjnATfnzZo/lo5unjR41njzoL3lkGO/KXbnisw=
350 github.com/tal-tech/go-zero v1.0.27 h1:QMIbaTxibMc/OsO5RTAuKZ8ndbl2dGN6pITQEtp2x/A= 358 github.com/tal-tech/go-zero v1.0.27 h1:QMIbaTxibMc/OsO5RTAuKZ8ndbl2dGN6pITQEtp2x/A=
351 github.com/tal-tech/go-zero v1.0.27/go.mod h1:JtNXlsh/CgeIHyQnt5C5M2IcSevW7V0NAnqO93TQgm8= 359 github.com/tal-tech/go-zero v1.0.27/go.mod h1:JtNXlsh/CgeIHyQnt5C5M2IcSevW7V0NAnqO93TQgm8=
352 github.com/tiptok/egglib-go v0.0.0-20210608073225-c852ce95ae34 h1:9iDNyYbfpv5KLWDLpDywD/aIODg+PNnwn+v9on7KGlE= 360 github.com/tiptok/egglib-go v0.0.0-20210608073225-c852ce95ae34 h1:9iDNyYbfpv5KLWDLpDywD/aIODg+PNnwn+v9on7KGlE=
@@ -357,6 +365,7 @@ github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYm @@ -357,6 +365,7 @@ github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYm
357 github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= 365 github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
358 github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= 366 github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
359 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= 367 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
  368 +github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
360 github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= 369 github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
361 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 370 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
362 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 371 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@@ -373,7 +382,9 @@ github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq @@ -373,7 +382,9 @@ github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq
373 github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= 382 github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
374 github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= 383 github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
375 github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= 384 github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
  385 +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
376 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= 386 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
  387 +github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
377 github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= 388 github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
378 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= 389 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
379 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 390 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -423,6 +434,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf @@ -423,6 +434,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
423 golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 434 golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
424 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 435 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
425 golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= 436 golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
  437 +golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
426 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 438 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
427 golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 439 golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
428 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 440 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -11,6 +11,7 @@ import ( @@ -11,6 +11,7 @@ import (
11 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log" 11 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
12 _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log" 12 _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
13 _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego" 13 _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego"
  14 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/goqueue"
14 ) 15 )
15 16
16 func main() { 17 func main() {
@@ -28,6 +29,8 @@ func main() { @@ -28,6 +29,8 @@ func main() {
28 }) 29 })
29 log.Logger.AddHook(bw) 30 log.Logger.AddHook(bw)
30 31
  32 + goqueue.SetUp()
  33 +
31 log.Logger.Info("server start!") 34 log.Logger.Info("server start!")
32 web.Run() 35 web.Run()
33 } 36 }
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type UpChainCommand struct {
  12 + // 数据来源 例如:app.model
  13 + Source string `cname:"数据来源 例如:app.model" json:"source" valid:"Required"`
  14 + // 来源数据唯一ID
  15 + PrimaryId string `cname:"来源数据唯一ID" json:"primaryId" valid:"Required"`
  16 + // 溯源ID 标记同一个系列的数据;例如订单相关事件
  17 + IssueId string `cname:"溯源ID 标记同一个系列的数据;例如订单相关事件" json:"issueId"`
  18 + // 数据体
  19 + Data string `cname:"数据体" json:"data" valid:"Required"`
  20 +}
  21 +
  22 +func (upChainCommand *UpChainCommand) Valid(validation *validation.Validation) {
  23 + //validation.SetError("CustomValid", "未实现的自定义认证")
  24 +}
  25 +
  26 +func (upChainCommand *UpChainCommand) ValidateCommand() error {
  27 + valid := validation.Validation{}
  28 + b, err := valid.Valid(upChainCommand)
  29 + if err != nil {
  30 + return err
  31 + }
  32 + if !b {
  33 + elem := reflect.TypeOf(upChainCommand).Elem()
  34 + for _, validErr := range valid.Errors {
  35 + field, isExist := elem.FieldByName(validErr.Field)
  36 + if isExist {
  37 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  38 + } else {
  39 + return fmt.Errorf(validErr.Message)
  40 + }
  41 + }
  42 + }
  43 + return nil
  44 +}
  1 +package dto
  2 +
  3 +import "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  4 +
  5 +type BlockChain struct {
  6 + UpChainId int64 `json:"upChainId"`
  7 + PrimaryId string `json:"primaryId"`
  8 + // 数据块hash
  9 + BlockHash string `json:"blockHash"`
  10 +}
  11 +
  12 +type BlockChains []*BlockChain
  13 +
  14 +func (b *BlockChain) LoadDto(upChain *domain.UpChain) {
  15 + b.PrimaryId = upChain.PrimaryId
  16 + b.BlockHash = upChain.Hash
  17 + b.UpChainId = upChain.UpChainId
  18 +}
  19 +
  20 +func NewBlockChains(upChains []*domain.UpChain) BlockChains {
  21 + var rsp = make([]*BlockChain, 0)
  22 + for i := range upChains {
  23 + item := new(BlockChain)
  24 + item.LoadDto(upChains[i])
  25 + rsp = append(rsp, item)
  26 + }
  27 + return rsp
  28 +}
  1 +package query
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type GetBlockChainTokenQuery struct {
  12 + // 操作类型:
  13 + //1-交易哈希溯源
  14 + //2-溯源ID溯源
  15 + //3-验真
  16 + Type int `cname:"操作类型" json:"type" valid:"Required"`
  17 + // 参数
  18 + UpChainId int64 `cname:"上链Id" json:"upChainId,omitempty" valid:"Required"`
  19 +}
  20 +
  21 +func (listBlockChain *GetBlockChainTokenQuery) Valid(validation *validation.Validation) {
  22 + //validation.SetError("CustomValid", "未实现的自定义认证")
  23 +}
  24 +
  25 +func (listBlockChain *GetBlockChainTokenQuery) ValidateQuery() error {
  26 + valid := validation.Validation{}
  27 + b, err := valid.Valid(listBlockChain)
  28 + if err != nil {
  29 + return err
  30 + }
  31 + if !b {
  32 + elem := reflect.TypeOf(listBlockChain).Elem()
  33 + for _, validErr := range valid.Errors {
  34 + field, isExist := elem.FieldByName(validErr.Field)
  35 + if isExist {
  36 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  37 + } else {
  38 + return fmt.Errorf(validErr.Message)
  39 + }
  40 + }
  41 + }
  42 + return nil
  43 +}
  1 +package query
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  6 + "reflect"
  7 + "strings"
  8 +
  9 + "github.com/beego/beego/v2/core/validation"
  10 +)
  11 +
  12 +type ListBlockChainQuery struct {
  13 + OperateInfo *domain.OperateInfo `json:"-"`
  14 + // 查询偏离量
  15 + Offset int `cname:"查询偏离量" json:"offset,omitempty"`
  16 + // 查询限制
  17 + Limit int `cname:"查询限制" json:"limit,omitempty"`
  18 + // 数据来源 例如:app.model
  19 + Source string `cname:"数据来源 例如:app.model" json:"source" valid:"Required"`
  20 + // 来源数据唯一ID列表
  21 + PrimaryIdList []string `cname:"来源数据唯一ID列表" json:"primaryIdList"`
  22 + // 过滤重复的primaryId
  23 + EnableDistinctPrimaryId bool `cname:"过滤重复的primaryId" json:"enableDistinctPrimaryId"`
  24 + // 关闭查询限制
  25 + DisableLimit bool `cname:"关闭查询限制" json:"disableLimit,omitempty"`
  26 +}
  27 +
  28 +func (listBlockChain *ListBlockChainQuery) Valid(validation *validation.Validation) {
  29 + //validation.SetError("CustomValid", "未实现的自定义认证")
  30 +}
  31 +
  32 +func (listBlockChain *ListBlockChainQuery) ValidateQuery() error {
  33 + valid := validation.Validation{}
  34 + b, err := valid.Valid(listBlockChain)
  35 + if err != nil {
  36 + return err
  37 + }
  38 + if !b {
  39 + elem := reflect.TypeOf(listBlockChain).Elem()
  40 + for _, validErr := range valid.Errors {
  41 + field, isExist := elem.FieldByName(validErr.Field)
  42 + if isExist {
  43 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  44 + } else {
  45 + return fmt.Errorf(validErr.Message)
  46 + }
  47 + }
  48 + }
  49 + return nil
  50 +}
  1 +package service
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/linmadan/egglib-go/core/application"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/command"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/dto"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/query"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
  10 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  11 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/blockchain"
  12 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/utils"
  13 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
  14 + "strconv"
  15 + "time"
  16 +)
  17 +
  18 +// 区块链服务
  19 +type BlockChainService struct {
  20 +}
  21 +
  22 +// 数据上链
  23 +func (blockChainService *BlockChainService) UpChain(upChainCommand *command.UpChainCommand) (interface{}, error) {
  24 + if err := upChainCommand.ValidateCommand(); err != nil {
  25 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  26 + }
  27 + transactionContext, err := factory.CreateTransactionContext(nil)
  28 + if err != nil {
  29 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  30 + }
  31 + if err := transactionContext.StartTransaction(); err != nil {
  32 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  33 + }
  34 + defer func() {
  35 + transactionContext.RollbackTransaction()
  36 + }()
  37 +
  38 + upChain := &domain.UpChain{
  39 + Source: upChainCommand.Source,
  40 + PrimaryId: upChainCommand.PrimaryId,
  41 + IssueId: upChainCommand.IssueId,
  42 + Data: upChainCommand.Data,
  43 + UpChainStatus: 2,
  44 + CreatedAt: time.Now(),
  45 + }
  46 +
  47 + // 1. 查重
  48 + upChainRepository, _, _ := factory.FastPgUpChain(transactionContext, 0)
  49 + // 可溯源数据,可重复上传,可以追溯历史修改记录
  50 + if len(upChain.IssueId) == 0 {
  51 + if item, err := upChainRepository.FindOne(map[string]interface{}{"source": upChain.Source, "primaryId": upChain.PrimaryId}); err == nil && item != nil {
  52 + return nil, fmt.Errorf("duplicate message %v %v", upChain.Source, upChain.PrimaryId)
  53 + }
  54 + }
  55 +
  56 + // 2.上链
  57 + bc := &blockchain.BSNBlockChain{
  58 + PublicPem: []byte(blockchain.PubPem),
  59 + Host: blockchain.Host,
  60 + PublicKey: blockchain.PubKey,
  61 + PrivatePem: blockchain.PriK,
  62 + EnableDebugLog: true,
  63 + }
  64 + options := blockchain.NewUpToChainOptions(upChain.Source, upChain.PrimaryId, upChain.Data).WithInnerPrimaryIssueId(upChain.IssueId)
  65 + upToChainResponse, e := bc.UpToChain(options)
  66 + if e != nil || upToChainResponse == nil {
  67 + upChain.UpFail()
  68 + if e != nil {
  69 + log.Logger.Error("up chain err:" + e.Error())
  70 + }
  71 + } else {
  72 + upChain.UpSuccess(string(*upToChainResponse))
  73 + }
  74 +
  75 + // 3.保存记录
  76 + if upChain, err = upChainRepository.Save(upChain); err != nil {
  77 + return nil, err
  78 + }
  79 +
  80 + if err := transactionContext.CommitTransaction(); err != nil {
  81 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  82 + }
  83 + return upChain, nil
  84 +}
  85 +
  86 +// 区块链列表
  87 +func (blockChainService *BlockChainService) ListBlockChain(listBlockChain *query.ListBlockChainQuery) (interface{}, error) {
  88 + if err := listBlockChain.ValidateQuery(); err != nil {
  89 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  90 + }
  91 + transactionContext, err := factory.CreateTransactionContext(nil)
  92 + if err != nil {
  93 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  94 + }
  95 + if err := transactionContext.StartTransaction(); err != nil {
  96 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  97 + }
  98 + defer func() {
  99 + transactionContext.RollbackTransaction()
  100 + }()
  101 +
  102 + upChainRepository, _, _ := factory.FastPgUpChain(transactionContext, 0)
  103 + queryOptions := utils.ObjectToMap(listBlockChain)
  104 +
  105 + _, upChains, err := upChainRepository.Find(queryOptions)
  106 + if err != nil {
  107 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  108 + }
  109 + response := dto.NewBlockChains(upChains)
  110 + if err := transactionContext.CommitTransaction(); err != nil {
  111 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  112 + }
  113 + return response, nil
  114 +}
  115 +
  116 +func (blockChainService *BlockChainService) GetBlockChainToken(listBlockChain *query.GetBlockChainTokenQuery) (interface{}, error) {
  117 + if err := listBlockChain.ValidateQuery(); err != nil {
  118 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  119 + }
  120 + transactionContext, err := factory.CreateTransactionContext(nil)
  121 + if err != nil {
  122 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  123 + }
  124 + if err := transactionContext.StartTransaction(); err != nil {
  125 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  126 + }
  127 + defer func() {
  128 + transactionContext.RollbackTransaction()
  129 + }()
  130 +
  131 + upChainRepository, _, _ := factory.FastPgUpChain(transactionContext, 0)
  132 +
  133 + upChain, err := upChainRepository.FindOne(map[string]interface{}{"upChainId": listBlockChain.UpChainId})
  134 + if err != nil {
  135 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  136 + }
  137 + var request = blockchain.GetTokenRequest{
  138 + Type: listBlockChain.Type,
  139 + ShowValue: true,
  140 + }
  141 + bsn := newBSNBlockChain()
  142 + switch listBlockChain.Type {
  143 + case blockchain.QueryByHashId:
  144 + request.TsTxId = upChain.Hash
  145 + case blockchain.QueryByIssueId:
  146 + request.TsTxId = upChain.Hash
  147 + request.IssueId = upChain.IssueId
  148 + default:
  149 + return nil, application.ThrowError(application.ARG_ERROR, "unknown type "+strconv.Itoa(listBlockChain.Type))
  150 + }
  151 + getTokenResponse, err := bsn.GetToken(&request)
  152 + if err != nil {
  153 + log.Logger.Error(err.Error())
  154 + return nil, application.ThrowError(application.BUSINESS_ERROR, "不存在")
  155 + }
  156 + if err := transactionContext.CommitTransaction(); err != nil {
  157 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  158 + }
  159 + return map[string]interface{}{
  160 + "token": getTokenResponse.Token,
  161 + "browseUrl": fmt.Sprintf("%v?token=%v", blockchain.BlockBrowserAddress, getTokenResponse.Token),
  162 + }, nil
  163 +}
  164 +
  165 +func newBSNBlockChain() *blockchain.BSNBlockChain {
  166 + // 2.上链
  167 + bc := &blockchain.BSNBlockChain{
  168 + PublicPem: []byte(blockchain.PubPem),
  169 + Host: blockchain.Host,
  170 + PublicKey: blockchain.PubKey,
  171 + PrivatePem: blockchain.PriK,
  172 + EnableDebugLog: true,
  173 + }
  174 + return bc
  175 +}
  176 +
  177 +func NewBlockChainService(options map[string]interface{}) *BlockChainService {
  178 + newBlockChainService := &BlockChainService{}
  179 + return newBlockChainService
  180 +}
@@ -169,6 +169,32 @@ func FastPgMenu(transactionContext application.TransactionContext, menuId int64) @@ -169,6 +169,32 @@ func FastPgMenu(transactionContext application.TransactionContext, menuId int64)
169 return rep, mod, err 169 return rep, mod, err
170 } 170 }
171 171
  172 +// FastPgUpChain 快速返回区块链
  173 +//
  174 +// transactionContext 事务
  175 +// upChain upChainId
  176 +func FastPgUpChain(transactionContext application.TransactionContext, upChainId int64) (domain.UpChainRepository, *domain.UpChain, error) {
  177 + var rep domain.UpChainRepository
  178 + var mod *domain.UpChain
  179 + var err error
  180 + if value, err := CreateUpChainRepository(map[string]interface{}{
  181 + "transactionContext": transactionContext,
  182 + }); err != nil {
  183 + return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  184 + } else {
  185 + rep = value
  186 + }
  187 + if upChainId > 0 {
  188 + if mod, err = rep.FindOne(map[string]interface{}{"upChainId": upChainId}); err != nil {
  189 + if err == domain.ErrorNotFound {
  190 + return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该组织不存在")
  191 + }
  192 + return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  193 + }
  194 + }
  195 + return rep, mod, err
  196 +}
  197 +
172 // FastPgCustomizeMenu 快速返回领域自定义菜单 198 // FastPgCustomizeMenu 快速返回领域自定义菜单
173 // 199 //
174 // transactionContext 事务 200 // transactionContext 事务
@@ -69,3 +69,11 @@ func CreateAccountDestroyRecordRepository(options map[string]interface{}) (domai @@ -69,3 +69,11 @@ func CreateAccountDestroyRecordRepository(options map[string]interface{}) (domai
69 } 69 }
70 return repository.NewAccountDestroyRecordRepository(transactionContext) 70 return repository.NewAccountDestroyRecordRepository(transactionContext)
71 } 71 }
  72 +
  73 +func CreateUpChainRepository(options map[string]interface{}) (domain.UpChainRepository, error) {
  74 + var transactionContext *pg.TransactionContext
  75 + if value, ok := options["transactionContext"]; ok {
  76 + transactionContext = value.(*pg.TransactionContext)
  77 + }
  78 + return repository.NewUpChainRepository(transactionContext)
  79 +}
@@ -4,9 +4,11 @@ import "os" @@ -4,9 +4,11 @@ import "os"
4 4
5 var ( 5 var (
6 // kafka 地址 6 // kafka 地址
7 - KAFKA_HOST = "192.168.0.250:9092,192.168.0.251:9092,192.168.0.252:9092" 7 + KAFKA_HOST = "106.75.231.90:9092" //"192.168.0.250:9092,192.168.0.251:9092,192.168.0.252:9092"
8 // kafka topic log stash 8 // kafka topic log stash
9 - TOPIC_LOG_STASH = "go_stash_dev" 9 + TOPIC_LOG_STASH = "go_stash_dev" //"pushMessage"
  10 + // kafka topic up_block_chain
  11 + TOPIC_UP_BLOCK_CHAIN = "up_block_chain"
10 // 是否启用日志收集 (本地不启用) 12 // 是否启用日志收集 (本地不启用)
11 ENABLE_KAFKA_LOG = false 13 ENABLE_KAFKA_LOG = false
12 ) 14 )
  1 +package domain
  2 +
  3 +import "time"
  4 +
  5 +// 上链数据
  6 +type UpChain struct {
  7 + // 上链数据唯一标识
  8 + UpChainId int64 `json:"upChainId,string"`
  9 + // 数据来源 例如:app.model
  10 + Source string `json:"source"`
  11 + // 来源数据唯一ID
  12 + PrimaryId string `json:"primaryId"`
  13 + // 溯源ID 标记同一个系列的数据;例如订单相关事件
  14 + IssueId string `json:"issueId"`
  15 + // 数据体
  16 + Data string `json:"data"`
  17 + // 数据块hash
  18 + Hash string `json:"hash"`
  19 + // 上链状态 1:成功 2:失败
  20 + UpChainStatus int `json:"upChainStatus"`
  21 + // 创建时间
  22 + CreatedAt time.Time `json:"createdAt"`
  23 +}
  24 +
  25 +type UpChainRepository interface {
  26 + Save(upChain *UpChain) (*UpChain, error)
  27 + Remove(upChain *UpChain) (*UpChain, error)
  28 + FindOne(queryOptions map[string]interface{}) (*UpChain, error)
  29 + Find(queryOptions map[string]interface{}) (int64, []*UpChain, error)
  30 +}
  31 +
  32 +func (upChain *UpChain) Identify() interface{} {
  33 + if upChain.UpChainId == 0 {
  34 + return nil
  35 + }
  36 + return upChain.UpChainId
  37 +}
  38 +
  39 +func (upChain *UpChain) Update(data map[string]interface{}) error {
  40 + //if source, ok := data["source"]; ok {
  41 + // upChain.Source = source.(string)
  42 + //}
  43 + //if primaryId, ok := data["primaryId"]; ok {
  44 + // upChain.PrimaryId = primaryId.(string)
  45 + //}
  46 + //if issueId, ok := data["issueId"]; ok {
  47 + // upChain.IssueId = issueId.(string)
  48 + //}
  49 + //if data, ok := data["data"]; ok {
  50 + // upChain.Data = data.(string)
  51 + //}
  52 + if hash, ok := data["hash"]; ok {
  53 + upChain.Hash = hash.(string)
  54 + }
  55 + if upChainStatus, ok := data["upChainStatus"]; ok {
  56 + upChain.UpChainStatus = upChainStatus.(int)
  57 + }
  58 + if createdAt, ok := data["createdAt"]; ok {
  59 + upChain.CreatedAt = createdAt.(time.Time)
  60 + }
  61 + return nil
  62 +}
  63 +
  64 +func (upChain *UpChain) UpSuccess(hashData string) {
  65 + if len(upChain.Hash) > 0 {
  66 + return
  67 + }
  68 + upChain.Hash = hashData
  69 + upChain.UpChainStatus = 1
  70 +}
  71 +
  72 +func (upChain *UpChain) UpFail() {
  73 + if len(upChain.Hash) > 0 {
  74 + return
  75 + }
  76 + upChain.Hash = ""
  77 + upChain.UpChainStatus = 2
  78 +}
  1 +package blockchain
  2 +
  3 +import (
  4 + "bytes"
  5 + "encoding/base64"
  6 + rawjson "encoding/json"
  7 + "fmt"
  8 + "github.com/beego/beego/v2/client/httplib"
  9 + "github.com/linmadan/egglib-go/utils/json"
  10 + "net/http"
  11 + "net/http/httputil"
  12 + "sort"
  13 + "time"
  14 +)
  15 +
  16 +type (
  17 + BSNBlockChain struct {
  18 + PublicPem []byte
  19 + PrivatePem []byte
  20 + PublicKey string
  21 + Host string
  22 + EnableDebugLog bool
  23 + }
  24 + UpToChainRequest struct {
  25 + // 上链数据的数据库、数据表等的标识值 (非必填)
  26 + InnerDBTable string `json:"innerDBTable,omitempty"`
  27 + // 上链数据的唯一标识主键值 (非必填)
  28 + InnerPrimaryKey string `json:"innerPrimaryKey,omitempty"`
  29 + // 上链记录的一个标记值(IssueId), 数据溯源出所有相关事件内容,例如快递单号,过滤出该快递的所有相关事件内容并用于展示 (非必填)
  30 + InnerPrimaryIssueId string `json:"innerPrimaryIssueId,omitempty"`
  31 + // 作用与key1相同 (非必填)
  32 + InnerSecondIssueId string `json:"innerSecondIssueId,omitempty"`
  33 + // 数据原文 (必填)
  34 + Value string `json:"value,omitempty"`
  35 + // 数据描述: 对value的描述,无论needHash为何值,本字段均会原文存储到链上
  36 + Desc string `json:"desc,omitempty"`
  37 + // 是否哈希: true: 需要哈希,会将value进行hash上链,false:不需要哈希,明文上链,链上所有用户都可看到明文,默认false
  38 + NeedHash bool `json:"needHash"`
  39 + }
  40 + UpToChainResponse string
  41 +
  42 + GetTokenRequest struct {
  43 + // 操作类型:
  44 + //1-交易哈希溯源
  45 + //2-溯源ID溯源
  46 + //3-验真
  47 + Type int `json:"type"`
  48 + // type为1或者3时必填
  49 + TsTxId string `json:"tsTxId,omitempty"`
  50 + // type为2时必填
  51 + IssueId string `json:"issueId,omitempty"`
  52 + // type为3时必填
  53 + Value string `json:"value,omitempty"`
  54 + // 当type=1或者2必填,为false只显示密文,为true溯源才会显示原文
  55 + ShowValue bool `json:"showValue"`
  56 + }
  57 + GetTokenResponse struct {
  58 + Token string `json:"token"`
  59 + }
  60 +
  61 + Response struct {
  62 + Data rawjson.RawMessage `json:"data"`
  63 + Code int `json:"code"`
  64 + Message string `json:"message"`
  65 + }
  66 +)
  67 +
  68 +// 上链
  69 +func (c *BSNBlockChain) UpToChain(options *UpToChainOptions) (*UpToChainResponse, error) {
  70 + req, err := c.MakeRequest(options, "/chainApi/upToChain", "upToChain", http.MethodPost)
  71 + if err != nil {
  72 + return nil, err
  73 + }
  74 +
  75 + var upToChainResponse UpToChainResponse
  76 + _, err = c.HandlerResponse(req, &upToChainResponse)
  77 +
  78 + return &upToChainResponse, err
  79 +}
  80 +
  81 +// 浏览器溯源验真申请
  82 +func (c *BSNBlockChain) GetToken(options *GetTokenRequest) (*GetTokenResponse, error) {
  83 + req, err := c.MakeRequest(options, "/chainApi/getToken", "getToken", http.MethodPost)
  84 + if err != nil {
  85 + return nil, err
  86 + }
  87 + var getTokenResponse = GetTokenResponse{}
  88 + _, err = c.HandlerResponse(req, &getTokenResponse)
  89 + return &getTokenResponse, err
  90 +}
  91 +
  92 +// 签名
  93 +func (c *BSNBlockChain) Signature(body map[string]interface{}, method string) (string, error) {
  94 + var keys []string
  95 + for key, _ := range body {
  96 + keys = append(keys, key)
  97 + }
  98 + sort.Strings(keys)
  99 + encryptString := bytes.NewBuffer(nil)
  100 + for i := range keys {
  101 + key := keys[i]
  102 + if v, ok := body[key]; ok {
  103 + encryptString.WriteString(fmt.Sprintf("%s=%v&", key, v))
  104 + }
  105 + }
  106 + encryptString.WriteString(fmt.Sprintf("method=%v", method))
  107 +
  108 + // 此处用私钥签名
  109 + encryptData, err := RsaSign(c.PrivatePem, encryptString.Bytes())
  110 + if err != nil {
  111 + return "", err
  112 + }
  113 +
  114 + return base64.StdEncoding.EncodeToString(encryptData), nil
  115 +}
  116 +
  117 +func (c *BSNBlockChain) MakeRequest(obj interface{}, action string, signAction, httpMethod string) (*httplib.BeegoHTTPRequest, error) {
  118 + var mapBlockInfo = make(map[string]interface{})
  119 + json.UnmarshalFromString(json.MarshalToString(obj), &mapBlockInfo)
  120 + secret, err := c.Signature(mapBlockInfo, signAction)
  121 + if err != nil {
  122 + return nil, err
  123 + }
  124 + req := httplib.NewBeegoRequest(c.Host+action, httpMethod)
  125 + req.Header("pubKey", c.PublicKey) //url.QueryEscape(string(c.PublicKey))
  126 + req.Header("signature", secret) //url.QueryEscape(secret)
  127 + req.SetTimeout(time.Second*5, time.Second*5)
  128 + if httpMethod == http.MethodPost || httpMethod == http.MethodPut {
  129 + req.JSONBody(obj)
  130 + }
  131 + if c.EnableDebugLog {
  132 + data, _ := httputil.DumpRequest(req.GetRequest(), true)
  133 + fmt.Println(string(data))
  134 + }
  135 + return req, nil
  136 +}
  137 +
  138 +func (c *BSNBlockChain) HandlerResponse(req *httplib.BeegoHTTPRequest, value interface{}) (*Response, error) {
  139 + response := &Response{}
  140 + data, err := req.Bytes()
  141 + if err != nil {
  142 + return nil, err
  143 + }
  144 + rsp, err := req.Response()
  145 + if err != nil {
  146 + return nil, err
  147 + }
  148 + if rsp.StatusCode != http.StatusOK {
  149 + return nil, fmt.Errorf("response code:%v status:%v", rsp.StatusCode, rsp.Status)
  150 + }
  151 + err = json.Unmarshal(data, response)
  152 + if err != nil {
  153 + return nil, err
  154 + }
  155 + if c.EnableDebugLog {
  156 + fmt.Println("\nHttp Response-> \n", string(data))
  157 + }
  158 + if response.Code != 0 {
  159 + return nil, fmt.Errorf("upchain code:%v msg:%v", response.Code, response.Message)
  160 + }
  161 + json.Unmarshal(response.Data, value)
  162 + return response, nil
  163 +}
  164 +
  165 +func (b *UpToChainRequest) Complete(options *UpToChainOptions) {
  166 + b.InnerDBTable = options.InnerDBTable
  167 + b.InnerPrimaryKey = options.InnerPrimaryKey
  168 + b.InnerPrimaryIssueId = options.InnerPrimaryIssueId
  169 + b.InnerSecondIssueId = options.InnerSecondIssueId
  170 + b.Value = options.Value
  171 + b.Desc = options.Desc
  172 + b.NeedHash = options.NeedHash
  173 +}
  1 +package blockchain
  2 +
  3 +import (
  4 + "bytes"
  5 + "crypto/rand"
  6 + "crypto/rsa"
  7 + "crypto/x509"
  8 + "encoding/pem"
  9 + "fmt"
  10 + "github.com/linmadan/egglib-go/utils/json"
  11 + "github.com/stretchr/testify/assert"
  12 + "log"
  13 + "os"
  14 + "testing"
  15 +)
  16 +
  17 +//var priK = []byte(`-----BEGIN RSA PRIVATE KEY-----
  18 +//MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA2H6x0D1mg5QbXfU7
  19 +//MZKltypRj+eZktPKIApyEqRsyLqe3sRSd1Eh+VqKlQ9QFI8dae3t0USWlVmyfIDM
  20 +//0ly85QIDAQABAkAPnKNJ9wOLfYSzs9l+66pTmROkovjqI6exw88SFRVbLCgM8maa
  21 +//GOWEP/nhZDlQYBKHUqG0/KsLkeyLGkE8N7JBAiEA8lM3npA3q+Kmhy+lmQbfHFPQ
  22 +//31OSkA+RaW/LPn0lP50CIQDktlF3iDk5kxnzgT/3lvvKhHInUh+pH5F19C6MymMD
  23 +//6QIgLxDct655MahnAdDOUCeWhBD/e7DmwZZUfu8Ywb1a070CIArsUjO9Q85mIiUp
  24 +//FR8EDP59GN6b43s2UMIraVW8DMKRAiEAnnMPbDsD2HsQbgmNNEqETUxYGVyO+p7w
  25 +//OZZReuOyvCM=
  26 +//-----END RSA PRIVATE KEY-----`)
  27 +//var pubPem = `-----BEGIN PUBLIC KEY-----
  28 +//MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANh+sdA9ZoOUG131OzGSpbcqUY/nmZLT
  29 +//yiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ==
  30 +//-----END PUBLIC KEY-----`
  31 +//var pubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANh+sdA9ZoOUG131OzGSpbcqUY/nmZLT\nyiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ=="
  32 +//
  33 +//var host = "http://allied-creation-gateway-dev.fjmaimaimai.com"
  34 +
  35 +var priK = []byte(`-----BEGIN RSA PRIVATE KEY-----
  36 +MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA2H6x0D1mg5QbXfU7
  37 +MZKltypRj+eZktPKIApyEqRsyLqe3sRSd1Eh+VqKlQ9QFI8dae3t0USWlVmyfIDM
  38 +0ly85QIDAQABAkAPnKNJ9wOLfYSzs9l+66pTmROkovjqI6exw88SFRVbLCgM8maa
  39 +GOWEP/nhZDlQYBKHUqG0/KsLkeyLGkE8N7JBAiEA8lM3npA3q+Kmhy+lmQbfHFPQ
  40 +31OSkA+RaW/LPn0lP50CIQDktlF3iDk5kxnzgT/3lvvKhHInUh+pH5F19C6MymMD
  41 +6QIgLxDct655MahnAdDOUCeWhBD/e7DmwZZUfu8Ywb1a070CIArsUjO9Q85mIiUp
  42 +FR8EDP59GN6b43s2UMIraVW8DMKRAiEAnnMPbDsD2HsQbgmNNEqETUxYGVyO+p7w
  43 +OZZReuOyvCM=
  44 +-----END RSA PRIVATE KEY-----`)
  45 +var pubPem = `-----BEGIN PUBLIC KEY-----
  46 +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANh+sdA9ZoOUG131OzGSpbcqUY/nmZLT
  47 +yiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ==
  48 +-----END PUBLIC KEY-----`
  49 +var pubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANh+sdA9ZoOUG131OzGSpbcqUY/nmZLTyiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ=="
  50 +
  51 +var host = "http://101.34.29.149:9092/test"
  52 +
  53 +func TestSignature(t *testing.T) {
  54 + options := NewUpToChainOptions("table", "1", "149848948").WithDesc("desc")
  55 + bsn := &BSNBlockChain{
  56 + PrivatePem: priK,
  57 + PublicPem: []byte(pubPem),
  58 + }
  59 + bInfo := &UpToChainRequest{}
  60 + bInfo.Complete(options)
  61 + var mapBlockInfo = make(map[string]interface{})
  62 + json.UnmarshalFromString(json.MarshalToString(bInfo), &mapBlockInfo)
  63 + secret, err := bsn.Signature(mapBlockInfo, "upToChain")
  64 + assert.Nil(t, err)
  65 + t.Log(secret)
  66 + decryptSecret, err := RsaDecrypt(priK, []byte(secret))
  67 + if err != nil {
  68 + t.Log(err.Error())
  69 + }
  70 + t.Log(decryptSecret)
  71 +}
  72 +
  73 +func TestGenerateRSA(t *testing.T) {
  74 + // generate key
  75 + privatekey, err := rsa.GenerateKey(rand.Reader, 512)
  76 + if err != nil {
  77 + fmt.Printf("Cannot generate RSA key\n")
  78 + os.Exit(1)
  79 + }
  80 + publickey := &privatekey.PublicKey
  81 +
  82 + // dump private key to file
  83 + var privateKeyBytes []byte = x509.MarshalPKCS1PrivateKey(privatekey)
  84 + privateKeyBlock := &pem.Block{
  85 + Type: "RSA PRIVATE KEY",
  86 + Bytes: privateKeyBytes,
  87 + }
  88 + privatePem := bytes.NewBuffer(nil)
  89 + if err != nil {
  90 + fmt.Printf("error when create private.pem: %s \n", err)
  91 + os.Exit(1)
  92 + }
  93 + err = pem.Encode(privatePem, privateKeyBlock)
  94 + if err != nil {
  95 + fmt.Printf("error when encode private pem: %s \n", err)
  96 + os.Exit(1)
  97 + }
  98 +
  99 + // dump public key to file
  100 + publicKeyBytes, err := x509.MarshalPKIXPublicKey(publickey)
  101 + if err != nil {
  102 + fmt.Printf("error when dumping publickey: %s \n", err)
  103 + os.Exit(1)
  104 + }
  105 + publicKeyBlock := &pem.Block{
  106 + Type: "PUBLIC KEY",
  107 + Bytes: publicKeyBytes,
  108 + }
  109 + publicPem := bytes.NewBuffer(nil)
  110 + if err != nil {
  111 + fmt.Printf("error when create public.pem: %s \n", err)
  112 + os.Exit(1)
  113 + }
  114 + err = pem.Encode(publicPem, publicKeyBlock)
  115 + if err != nil {
  116 + fmt.Printf("error when encode public pem: %s \n", err)
  117 + os.Exit(1)
  118 + }
  119 + log.Println(privatePem.String())
  120 + log.Println(publicPem.String())
  121 +}
  122 +
  123 +func TestBSNBlockChain_UpToChain(t *testing.T) {
  124 + bc := &BSNBlockChain{
  125 + PublicPem: []byte(pubPem),
  126 + Host: host,
  127 + PublicKey: pubKey,
  128 + PrivatePem: priK,
  129 + }
  130 + options := NewUpToChainOptions("table", "2", "149848948").WithDesc("desc")
  131 + rsp, err := bc.UpToChain(options)
  132 + if err != nil {
  133 + t.Fatal(err)
  134 + }
  135 + t.Log(string(*rsp))
  136 +}
  137 +
  138 +func TestBSNBlockChain_GetToken(t *testing.T) {
  139 + bc := &BSNBlockChain{
  140 + PublicPem: []byte(pubPem),
  141 + Host: host,
  142 + PublicKey: pubKey,
  143 + PrivatePem: priK,
  144 + EnableDebugLog: true,
  145 + }
  146 + options := &GetTokenRequest{
  147 + Type: 1,
  148 + TsTxId: "54df75d3bead65d144a1123d1f18af8bb4db65420c5c449631e9a93b81fcdb93",
  149 + ShowValue: true,
  150 + }
  151 + token, err := bc.GetToken(options)
  152 + if err != nil {
  153 + t.Fatal(err)
  154 + }
  155 + fmt.Println(token.Token)
  156 +}
  157 +
  158 +func TestBSNBlockChain_UpToChain_All_Type(t *testing.T) {
  159 + bc := &BSNBlockChain{
  160 + PublicPem: []byte(pubPem),
  161 + Host: host,
  162 + PublicKey: pubKey,
  163 + PrivatePem: priK,
  164 + EnableDebugLog: true,
  165 + }
  166 + inputs := []struct {
  167 + name string
  168 + option *UpToChainOptions
  169 + t int
  170 + }{
  171 + {
  172 + "1.交易哈希溯源",
  173 + NewUpToChainOptions("app.order", "793745u988434", `{"orderId":"793745u988434"}`).WithDesc(""),
  174 + 1,
  175 + },
  176 + {
  177 + "2.交易哈希溯源",
  178 + NewUpToChainOptions("app.order", "793745u988435", `{"orderId":"793745u988435"}`).WithDesc("").WithInnerPrimaryIssueId("893745u988435"),
  179 + 2,
  180 + },
  181 + {
  182 + "3.验真",
  183 + NewUpToChainOptions("app.order", "793745u988436", `{"orderId":"793745u988436"}`).WithDesc("").WithInnerPrimaryIssueId("893745u988436"),
  184 + 3,
  185 + },
  186 + }
  187 + for i := range inputs {
  188 + input := inputs[i]
  189 + fmt.Println(input.name)
  190 + rsp, err := bc.UpToChain(input.option)
  191 + if err != nil {
  192 + t.Fatal(err)
  193 + }
  194 + fmt.Println()
  195 + options := &GetTokenRequest{
  196 + Type: input.t,
  197 + ShowValue: true,
  198 + }
  199 + switch input.t {
  200 + case 1:
  201 + options.TsTxId = string(*rsp)
  202 + case 2:
  203 + options.IssueId = input.option.InnerPrimaryIssueId
  204 + case 3:
  205 + options.TsTxId = string(*rsp)
  206 + options.Value = input.option.Value
  207 + }
  208 + token, err := bc.GetToken(options)
  209 + if err != nil {
  210 + t.Fatal(err)
  211 + }
  212 + fmt.Println(fmt.Sprintf("Token:%v \n", token.Token))
  213 + }
  214 +}
  1 +package blockchain
  2 +
  3 +var PriK = []byte(`-----BEGIN RSA PRIVATE KEY-----
  4 +MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEA2H6x0D1mg5QbXfU7
  5 +MZKltypRj+eZktPKIApyEqRsyLqe3sRSd1Eh+VqKlQ9QFI8dae3t0USWlVmyfIDM
  6 +0ly85QIDAQABAkAPnKNJ9wOLfYSzs9l+66pTmROkovjqI6exw88SFRVbLCgM8maa
  7 +GOWEP/nhZDlQYBKHUqG0/KsLkeyLGkE8N7JBAiEA8lM3npA3q+Kmhy+lmQbfHFPQ
  8 +31OSkA+RaW/LPn0lP50CIQDktlF3iDk5kxnzgT/3lvvKhHInUh+pH5F19C6MymMD
  9 +6QIgLxDct655MahnAdDOUCeWhBD/e7DmwZZUfu8Ywb1a070CIArsUjO9Q85mIiUp
  10 +FR8EDP59GN6b43s2UMIraVW8DMKRAiEAnnMPbDsD2HsQbgmNNEqETUxYGVyO+p7w
  11 +OZZReuOyvCM=
  12 +-----END RSA PRIVATE KEY-----`)
  13 +var PubPem = `-----BEGIN PUBLIC KEY-----
  14 +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANh+sdA9ZoOUG131OzGSpbcqUY/nmZLT
  15 +yiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ==
  16 +-----END PUBLIC KEY-----`
  17 +var PubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANh+sdA9ZoOUG131OzGSpbcqUY/nmZLTyiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ=="
  18 +
  19 +var Host = "http://101.34.29.149:9092/test"
  20 +
  21 +var BlockBrowserAddress = "http://101.34.29.149/browser"
  1 +package blockchain
  2 +
  3 +type UpToChainOptions struct {
  4 + // 上链数据的数据库、数据表等的标识值 (非必填)
  5 + InnerDBTable string `json:"innerDBTable,omitempty"`
  6 + // 上链数据的唯一标识主键值 (非必填)
  7 + InnerPrimaryKey string `json:"innerPrimaryKey,omitempty"`
  8 + // 上链记录的一个标记值(IssueId), 数据溯源出所有相关事件内容,例如快递单号,过滤出该快递的所有相关事件内容并用于展示 (非必填)
  9 + InnerPrimaryIssueId string `json:"innerPrimaryIssueId,omitempty"`
  10 + // 作用与key1相同 (非必填)
  11 + InnerSecondIssueId string `json:"innerSecondIssueId,omitempty"`
  12 + // 数据原文 (必填)
  13 + Value string `json:"value"`
  14 + // 数据描述: 对value的描述,无论needHash为何值,本字段均会原文存储到链上
  15 + Desc string `json:"desc,omitempty"`
  16 + // 是否哈希: true: 需要哈希,会将value进行hash上链,false:不需要哈希,明文上链,链上所有用户都可看到明文,默认false
  17 + NeedHash bool `json:"needHash"`
  18 +}
  19 +
  20 +func NewUpToChainOptions(table, primaryKey, value string) *UpToChainOptions {
  21 + return &UpToChainOptions{InnerDBTable: table, InnerPrimaryKey: primaryKey, Value: value, NeedHash: false}
  22 +}
  23 +
  24 +func (o *UpToChainOptions) WithInnerDBTable(innerDBTable string) *UpToChainOptions {
  25 + o.InnerDBTable = innerDBTable
  26 + return o
  27 +}
  28 +
  29 +func (o *UpToChainOptions) WithInnerPrimaryKey(innerPrimaryKey string) *UpToChainOptions {
  30 + o.InnerPrimaryKey = innerPrimaryKey
  31 + return o
  32 +}
  33 +
  34 +func (o *UpToChainOptions) WithInnerPrimaryIssueId(innerPrimaryIssueId string) *UpToChainOptions {
  35 + o.InnerPrimaryIssueId = innerPrimaryIssueId
  36 + return o
  37 +}
  38 +
  39 +func (o *UpToChainOptions) WithInnerSecondIssueId(innerSecondIssueId string) *UpToChainOptions {
  40 + o.InnerSecondIssueId = innerSecondIssueId
  41 + return o
  42 +}
  43 +
  44 +func (o *UpToChainOptions) WithValue(Value string) *UpToChainOptions {
  45 + o.Value = Value
  46 + return o
  47 +}
  48 +
  49 +func (o *UpToChainOptions) WithDesc(Desc string) *UpToChainOptions {
  50 + o.Desc = Desc
  51 + return o
  52 +}
  53 +
  54 +func (o *UpToChainOptions) WithNeedHash() *UpToChainOptions {
  55 + o.NeedHash = true
  56 + return o
  57 +}
  58 +
  59 +const (
  60 + QueryByHashId = iota + 1
  61 + QueryByIssueId
  62 +)
  1 +package blockchain
  2 +
  3 +import (
  4 + "crypto"
  5 + "crypto/md5"
  6 + "crypto/rand"
  7 + "crypto/rsa"
  8 + "crypto/x509"
  9 + "encoding/base64"
  10 + "encoding/pem"
  11 + "errors"
  12 + "fmt"
  13 +)
  14 +
  15 +// rsa签名
  16 +func RsaSign(publicKey []byte, origData []byte) ([]byte, error) {
  17 + block, _ := pem.Decode(publicKey)
  18 + if block == nil {
  19 + return nil, errors.New("public key error")
  20 + }
  21 + pubInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
  22 + if err != nil {
  23 + return nil, err
  24 + }
  25 +
  26 + // md5
  27 + hash := md5.New()
  28 + hash.Write([]byte(origData))
  29 + pub := pubInterface.(*rsa.PrivateKey)
  30 + return rsa.SignPKCS1v15(rand.Reader, pub, crypto.MD5, hash.Sum(nil))
  31 + //pub := pubInterface.(*rsa.PublicKey)
  32 + //return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
  33 +}
  34 +
  35 +func RsaEncrypt(publicKey []byte, origData []byte) ([]byte, error) {
  36 + block, _ := pem.Decode(publicKey)
  37 + if block == nil {
  38 + return nil, errors.New("public key error")
  39 + }
  40 + pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
  41 + if err != nil {
  42 + return nil, err
  43 + }
  44 +
  45 + fmt.Println(string(origData))
  46 + // md5
  47 + hash := md5.New()
  48 + hash.Write([]byte(origData))
  49 + pub := pubInterface.(*rsa.PublicKey)
  50 + fmt.Println(hash.Sum(nil))
  51 + return rsa.EncryptPKCS1v15(rand.Reader, pub, hash.Sum(nil))
  52 +}
  53 +
  54 +// 解密
  55 +func RsaDecrypt(privateKey []byte, ciphertext []byte) ([]byte, error) {
  56 + block, _ := pem.Decode(privateKey)
  57 + if block == nil {
  58 + return nil, errors.New("private key error!")
  59 + }
  60 + encryptData, _ := base64.StdEncoding.DecodeString(string(ciphertext))
  61 + priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
  62 + if err != nil {
  63 + // pkcs1 是标准但裸奔,pkcs8升级支持密码
  64 + pri2, err := x509.ParsePKCS8PrivateKey(block.Bytes)
  65 + if err != nil {
  66 + return nil, err
  67 + }
  68 + priv = pri2.(*rsa.PrivateKey)
  69 + }
  70 + return rsa.DecryptPKCS1v15(rand.Reader, priv, encryptData)
  71 +}
@@ -35,6 +35,7 @@ func init() { @@ -35,6 +35,7 @@ func init() {
35 (*models.User)(nil), 35 (*models.User)(nil),
36 (*models.UserBase)(nil), 36 (*models.UserBase)(nil),
37 (*models.AccountDestroyRecord)(nil), 37 (*models.AccountDestroyRecord)(nil),
  38 + (*models.UpChain)(nil),
38 } { 39 } {
39 err := DB.Model(model).CreateTable(&orm.CreateTableOptions{ 40 err := DB.Model(model).CreateTable(&orm.CreateTableOptions{
40 Temp: false, 41 Temp: false,
  1 +package models
  2 +
  3 +import "time"
  4 +
  5 +type UpChain struct {
  6 + tableName string `comment:"上链数据" pg:"business.up_chain"`
  7 + // 上链数据唯一标识
  8 + UpChainId int64 `comment:"上链数据唯一标识" pg:"pk:up_chain_id"`
  9 + // 数据来源 例如:app.model
  10 + Source string `comment:"数据来源 例如:app.model"`
  11 + // 来源数据唯一ID
  12 + PrimaryId string `comment:"来源数据唯一ID"`
  13 + // 溯源ID 标记同一个系列的数据;例如订单相关事件
  14 + IssueId string `comment:"溯源ID 标记同一个系列的数据;例如订单相关事件"`
  15 + // 数据体
  16 + Data string `comment:"数据体"`
  17 + // 数据块hash
  18 + Hash string `comment:"数据块hash"`
  19 + // 上链状态 1:成功 2:失败
  20 + UpChainStatus int `comment:"上链状态 1:成功 2:失败"`
  21 + // 创建时间
  22 + CreatedAt time.Time `comment:"创建时间"`
  23 +}
  1 +package transform
  2 +
  3 +import (
  4 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg/models"
  6 +)
  7 +
  8 +func TransformToUpChainDomainModelFromPgModels(upChainModel *models.UpChain) (*domain.UpChain, error) {
  9 + return &domain.UpChain{
  10 + UpChainId: upChainModel.UpChainId,
  11 + Source: upChainModel.Source,
  12 + PrimaryId: upChainModel.PrimaryId,
  13 + IssueId: upChainModel.IssueId,
  14 + Data: upChainModel.Data,
  15 + Hash: upChainModel.Hash,
  16 + UpChainStatus: upChainModel.UpChainStatus,
  17 + CreatedAt: upChainModel.CreatedAt,
  18 + }, nil
  19 +}
  1 +package repository
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/go-pg/pg/v10"
  6 +
  7 + "github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
  8 + pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
  9 + "github.com/linmadan/egglib-go/utils/snowflake"
  10 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
  11 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg/models"
  12 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg/transform"
  13 +)
  14 +
  15 +type UpChainRepository struct {
  16 + transactionContext *pgTransaction.TransactionContext
  17 +}
  18 +
  19 +func (repository *UpChainRepository) nextIdentify() (int64, error) {
  20 + IdWorker, err := snowflake.NewIdWorker(1)
  21 + if err != nil {
  22 + return 0, err
  23 + }
  24 + id, err := IdWorker.NextId()
  25 + return id, err
  26 +}
  27 +func (repository *UpChainRepository) Save(upChain *domain.UpChain) (*domain.UpChain, error) {
  28 + sqlBuildFields := []string{
  29 + "up_chain_id",
  30 + "source",
  31 + "primary_id",
  32 + "issue_id",
  33 + "data",
  34 + "hash",
  35 + "up_chain_status",
  36 + "created_at",
  37 + }
  38 + insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "up_chain_id"))
  39 + insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "up_chain_id"))
  40 + returningFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields)
  41 + updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "up_chain_id")
  42 + updateFieldsSnippet := sqlbuilder.SqlUpdateFieldsSnippet(updateFields)
  43 + tx := repository.transactionContext.PgTx
  44 + if upChain.Identify() == nil {
  45 + upChainId, err := repository.nextIdentify()
  46 + if err != nil {
  47 + return upChain, err
  48 + } else {
  49 + upChain.UpChainId = upChainId
  50 + }
  51 + if _, err := tx.QueryOne(
  52 + pg.Scan(
  53 + &upChain.UpChainId,
  54 + &upChain.Source,
  55 + &upChain.PrimaryId,
  56 + &upChain.IssueId,
  57 + &upChain.Data,
  58 + &upChain.Hash,
  59 + &upChain.UpChainStatus,
  60 + &upChain.CreatedAt,
  61 + ),
  62 + fmt.Sprintf("INSERT INTO business.up_chain (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
  63 + //upChain.UpChainId,
  64 + upChain.Source,
  65 + upChain.PrimaryId,
  66 + upChain.IssueId,
  67 + upChain.Data,
  68 + upChain.Hash,
  69 + upChain.UpChainStatus,
  70 + upChain.CreatedAt,
  71 + ); err != nil {
  72 + return upChain, err
  73 + }
  74 + } else {
  75 + if _, err := tx.QueryOne(
  76 + pg.Scan(
  77 + &upChain.UpChainId,
  78 + &upChain.Source,
  79 + &upChain.PrimaryId,
  80 + &upChain.IssueId,
  81 + &upChain.Data,
  82 + &upChain.Hash,
  83 + &upChain.UpChainStatus,
  84 + &upChain.CreatedAt,
  85 + ),
  86 + fmt.Sprintf("UPDATE business.up_chain SET %s WHERE up_chain_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
  87 + upChain.Source,
  88 + upChain.PrimaryId,
  89 + upChain.IssueId,
  90 + upChain.Data,
  91 + upChain.Hash,
  92 + upChain.UpChainStatus,
  93 + upChain.CreatedAt,
  94 + upChain.Identify(),
  95 + ); err != nil {
  96 + return upChain, err
  97 + }
  98 + }
  99 + return upChain, nil
  100 +}
  101 +func (repository *UpChainRepository) Remove(upChain *domain.UpChain) (*domain.UpChain, error) {
  102 + tx := repository.transactionContext.PgTx
  103 + upChainModel := new(models.UpChain)
  104 + upChainModel.UpChainId = upChain.Identify().(int64)
  105 + if _, err := tx.Model(upChainModel).WherePK().Delete(); err != nil {
  106 + return upChain, err
  107 + }
  108 + return upChain, nil
  109 +}
  110 +func (repository *UpChainRepository) FindOne(queryOptions map[string]interface{}) (*domain.UpChain, error) {
  111 + tx := repository.transactionContext.PgTx
  112 + upChainModel := new(models.UpChain)
  113 + query := sqlbuilder.BuildQuery(tx.Model(upChainModel), queryOptions)
  114 + query.SetWhereByQueryOption("up_chain.up_chain_id = ?", "upChainId")
  115 + query.SetWhereByQueryOption("up_chain.source = ?", "source")
  116 + query.SetWhereByQueryOption("up_chain.primary_id = ?", "primaryId")
  117 + if err := query.First(); err != nil {
  118 + if err.Error() == "pg: no rows in result set" {
  119 + return nil, fmt.Errorf("没有此资源")
  120 + } else {
  121 + return nil, err
  122 + }
  123 + }
  124 + if upChainModel.UpChainId == 0 {
  125 + return nil, nil
  126 + } else {
  127 + return transform.TransformToUpChainDomainModelFromPgModels(upChainModel)
  128 + }
  129 +}
  130 +func (repository *UpChainRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.UpChain, error) {
  131 + tx := repository.transactionContext.PgTx
  132 + var upChainModels []*models.UpChain
  133 + upChains := make([]*domain.UpChain, 0)
  134 + query := sqlbuilder.BuildQuery(tx.Model(&upChainModels), queryOptions)
  135 +
  136 + if v, ok := queryOptions["disableLimit"]; !(ok && v.(bool)) {
  137 + query.SetOffsetAndLimit(20)
  138 + }
  139 + if v, ok := queryOptions["source"]; ok && len(v.(string)) > 0 {
  140 + query.Where(`source = ?`, v)
  141 + }
  142 + if v, ok := queryOptions["primaryIdList"]; ok && len(v.([]string)) > 0 {
  143 + query.Where(`primary_id in (?)`, pg.In(v.([]string)))
  144 + }
  145 + if v, ok := queryOptions["enableDistinctPrimaryId"]; ok && v.(bool) {
  146 + query.DistinctOn(`primary_id`)
  147 + query.SetOrderDirect("primary_id", "DESC")
  148 + }
  149 +
  150 + query.SetOrderDirect("up_chain_id", "DESC")
  151 + if count, err := query.SelectAndCount(); err != nil {
  152 + return 0, upChains, err
  153 + } else {
  154 + for _, upChainModel := range upChainModels {
  155 + if upChain, err := transform.TransformToUpChainDomainModelFromPgModels(upChainModel); err != nil {
  156 + return 0, upChains, err
  157 + } else {
  158 + upChains = append(upChains, upChain)
  159 + }
  160 + }
  161 + return int64(count), upChains, nil
  162 + }
  163 +}
  164 +func NewUpChainRepository(transactionContext *pgTransaction.TransactionContext) (*UpChainRepository, error) {
  165 + if transactionContext == nil {
  166 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  167 + } else {
  168 + return &UpChainRepository{
  169 + transactionContext: transactionContext,
  170 + }, nil
  171 + }
  172 +}
  1 +package controllers
  2 +
  3 +import (
  4 + "github.com/linmadan/egglib-go/web/beego"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/query"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/service"
  7 +)
  8 +
  9 +type BlockChainController struct {
  10 + beego.BaseController
  11 +}
  12 +
  13 +//func (controller *BlockChainController) CreateBlockChain() {
  14 +// blockChainService := service.NewBlockChainService(nil)
  15 +// createBlockChainCommand := &command.CreateBlockChainCommand{}
  16 +// controller.Unmarshal(createBlockChainCommand)
  17 +// data, err := blockChainService.CreateBlockChain(createBlockChainCommand)
  18 +// controller.Response(data, err)
  19 +//}
  20 +//
  21 +//func (controller *BlockChainController) UpdateBlockChain() {
  22 +// blockChainService := service.NewBlockChainService(nil)
  23 +// updateBlockChainCommand := &command.UpdateBlockChainCommand{}
  24 +// controller.Unmarshal(updateBlockChainCommand)
  25 +// blockChainId, _ := controller.GetString(":blockChainId")
  26 +// updateBlockChainCommand.BlockChainId = blockChainId
  27 +// data, err := blockChainService.UpdateBlockChain(updateBlockChainCommand)
  28 +// controller.Response(data, err)
  29 +//}
  30 +//
  31 +//func (controller *BlockChainController) GetBlockChain() {
  32 +// blockChainService := service.NewBlockChainService(nil)
  33 +// getBlockChainQuery := &query.GetBlockChainQuery{}
  34 +// blockChainId, _ := controller.GetString(":blockChainId")
  35 +// getBlockChainQuery.BlockChainId = blockChainId
  36 +// data, err := blockChainService.GetBlockChain(getBlockChainQuery)
  37 +// controller.Response(data, err)
  38 +//}
  39 +//
  40 +//func (controller *BlockChainController) RemoveBlockChain() {
  41 +// blockChainService := service.NewBlockChainService(nil)
  42 +// removeBlockChainCommand := &command.RemoveBlockChainCommand{}
  43 +// controller.Unmarshal(removeBlockChainCommand)
  44 +// blockChainId, _ := controller.GetString(":blockChainId")
  45 +// removeBlockChainCommand.BlockChainId = blockChainId
  46 +// data, err := blockChainService.RemoveBlockChain(removeBlockChainCommand)
  47 +// controller.Response(data, err)
  48 +//}
  49 +
  50 +func (controller *BlockChainController) ListBlockChain() {
  51 + blockChainService := service.NewBlockChainService(nil)
  52 + listBlockChainQuery := &query.ListBlockChainQuery{}
  53 + Must(controller.Unmarshal(listBlockChainQuery))
  54 + listBlockChainQuery.OperateInfo = ParseOperateInfo(controller.BaseController)
  55 + data, err := blockChainService.ListBlockChain(listBlockChainQuery)
  56 + controller.Response(data, err)
  57 +}
  58 +
  59 +func (controller *BlockChainController) GetBlockChainToken() {
  60 + blockChainService := service.NewBlockChainService(nil)
  61 + listBlockChainQuery := &query.GetBlockChainTokenQuery{}
  62 + Must(controller.Unmarshal(listBlockChainQuery))
  63 + //listBlockChainQuery.OperateInfo = ParseOperateInfo(controller.BaseController)
  64 + data, err := blockChainService.GetBlockChainToken(listBlockChainQuery)
  65 + controller.Response(data, err)
  66 +}
  1 +package routers
  2 +
  3 +import (
  4 + "github.com/beego/beego/v2/server/web"
  5 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego/controllers"
  6 +)
  7 +
  8 +func init() {
  9 + //web.Router("/block-chains/", &controllers.BlockChainController{}, "Post:CreateBlockChain")
  10 + //web.Router("/block-chains/:blockChainId", &controllers.BlockChainController{}, "Put:UpdateBlockChain")
  11 + //web.Router("/block-chains/:blockChainId", &controllers.BlockChainController{}, "Get:GetBlockChain")
  12 + //web.Router("/block-chains/:blockChainId", &controllers.BlockChainController{}, "Delete:RemoveBlockChain")
  13 + web.Router("/block-chains/", &controllers.BlockChainController{}, "Post:ListBlockChain")
  14 + web.Router("/block-chains/token", &controllers.BlockChainController{}, "Post:GetBlockChainToken")
  15 +}
  1 +package goqueue
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/tal-tech/go-queue/kq"
  6 + "github.com/tal-tech/go-zero/core/logx"
  7 + "github.com/tal-tech/go-zero/core/service"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/constant"
  9 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
  10 + "strings"
  11 +)
  12 +
  13 +func SetUp() {
  14 + go func() {
  15 + q := kq.MustNewQueue(NewConfig(constant.TOPIC_UP_BLOCK_CHAIN, constant.TOPIC_UP_BLOCK_CHAIN, 2), kq.WithHandle(UpToChainHandler))
  16 + defer func() {
  17 + q.Stop()
  18 + log.Logger.Info(fmt.Sprintf("goqueue:%v stop!", constant.TOPIC_UP_BLOCK_CHAIN))
  19 + }()
  20 + q.Start()
  21 + }()
  22 + log.Logger.Info("goqueue start!")
  23 +}
  24 +
  25 +func NewConfig(topic, group string, consumers int) kq.KqConf {
  26 + brokers := strings.Split(constant.KAFKA_HOST, ",")
  27 + return kq.KqConf{
  28 + ServiceConf: service.ServiceConf{
  29 + Name: topic,
  30 + Log: logx.LogConf{
  31 + Mode: "console",
  32 + },
  33 + Mode: "pro",
  34 + },
  35 + Brokers: brokers,
  36 + Group: group,
  37 + Topic: topic,
  38 + Offset: "first",
  39 + Conns: 1,
  40 + Consumers: consumers,
  41 + Processors: 4,
  42 + MinBytes: 10200,
  43 + MaxBytes: 10485760,
  44 + }
  45 +}
  1 +package goqueue
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/linmadan/egglib-go/utils/json"
  6 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/command"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/service"
  8 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
  9 +)
  10 +
  11 +func UpToChainHandler(k, v string) error {
  12 + log.Logger.Debug(fmt.Sprintf("%s", v), map[string]interface{}{"handler": "UptoChain"})
  13 + blockChainService := service.NewBlockChainService(nil)
  14 + upChainCommand := &command.UpChainCommand{}
  15 + err := json.UnmarshalFromString(v, upChainCommand)
  16 + if err != nil {
  17 + return err
  18 + }
  19 + _, err = blockChainService.UpChain(upChainCommand)
  20 + return err
  21 +}
  1 +package block_chain
  2 +
  3 +import (
  4 + "net/http"
  5 + "net/http/httptest"
  6 + "testing"
  7 +
  8 + "github.com/beego/beego/v2/server/web"
  9 + . "github.com/onsi/ginkgo"
  10 + . "github.com/onsi/gomega"
  11 + _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  12 + _ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego"
  13 +)
  14 +
  15 +func TestBlockChain(t *testing.T) {
  16 + RegisterFailHandler(Fail)
  17 + RunSpecs(t, "Beego Port BlockChain Correlations Test Case Suite")
  18 +}
  19 +
  20 +var handler http.Handler
  21 +var server *httptest.Server
  22 +
  23 +var _ = BeforeSuite(func() {
  24 + handler = web.BeeApp.Handlers
  25 + server = httptest.NewServer(handler)
  26 +})
  27 +
  28 +var _ = AfterSuite(func() {
  29 + server.Close()
  30 +})
  1 +package block_chain
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/gavv/httpexpect"
  7 + . "github.com/onsi/ginkgo"
  8 + . "github.com/onsi/gomega"
  9 + pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  10 +)
  11 +
  12 +var _ = Describe("创建", func() {
  13 + Describe("提交数据创建", func() {
  14 + Context("提交正确的新上链数据数据", func() {
  15 + It("返回上链数据数据", func() {
  16 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  17 + body := map[string]interface{}{
  18 + "upChainId": "int64",
  19 + }
  20 + httpExpect.POST("/block-chains/").
  21 + WithJSON(body).
  22 + Expect().
  23 + Status(http.StatusOK).
  24 + JSON().
  25 + Object().
  26 + ContainsKey("code").ValueEqual("code", 0).
  27 + ContainsKey("msg").ValueEqual("msg", "ok").
  28 + ContainsKey("data").Value("data").Object().
  29 + ContainsKey("upChainId").ValueNotEqual("upChainId", BeZero())
  30 + })
  31 + })
  32 + })
  33 + AfterEach(func() {
  34 + _, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
  35 + Expect(err).NotTo(HaveOccurred())
  36 + })
  37 +})
  1 +package block_chain
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("返回", func() {
  14 + var upChainId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&upChainId),
  18 + "INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
  19 + "testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("根据upChainId参数返回上链数据", func() {
  23 + Context("传入有效的upChainId", func() {
  24 + It("返回上链数据数据", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + httpExpect.GET("/block-chains/{blockChainId}").
  27 + Expect().
  28 + Status(http.StatusOK).
  29 + JSON().
  30 + Object().
  31 + ContainsKey("code").ValueEqual("code", 0).
  32 + ContainsKey("msg").ValueEqual("msg", "ok").
  33 + ContainsKey("data").Value("data").Object()
  34 + })
  35 + })
  36 + })
  37 + AfterEach(func() {
  38 + _, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
  39 + Expect(err).NotTo(HaveOccurred())
  40 + })
  41 +})
  1 +package block_chain
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("返回列表", func() {
  14 + var upChainId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&upChainId),
  18 + "INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
  19 + "testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("根据参数返回上链数据列表", func() {
  23 + Context("传入有效的参数", func() {
  24 + It("返回上链数据数据列表", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + httpExpect.GET("/block-chains/").
  27 + WithQuery("offset", "int").
  28 + WithQuery("limit", "int").
  29 + Expect().
  30 + Status(http.StatusOK).
  31 + JSON().
  32 + Object().
  33 + ContainsKey("code").ValueEqual("code", 0).
  34 + ContainsKey("msg").ValueEqual("msg", "ok").
  35 + ContainsKey("data").Value("data").Object().
  36 + ContainsKey("count").ValueEqual("count", 1).
  37 + ContainsKey("upChains").Value("upChains").Array()
  38 + })
  39 + })
  40 + })
  41 + AfterEach(func() {
  42 + _, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
  43 + Expect(err).NotTo(HaveOccurred())
  44 + })
  45 +})
  1 +package block_chain
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("移除", func() {
  14 + var upChainId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&upChainId),
  18 + "INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
  19 + "testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("根据参数移除", func() {
  23 + Context("传入有效的upChainId", func() {
  24 + It("返回被移除上链数据的数据", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + httpExpect.DELETE("/block-chains/{blockChainId}").
  27 + Expect().
  28 + Status(http.StatusOK).
  29 + JSON().
  30 + Object().
  31 + ContainsKey("code").ValueEqual("code", 0).
  32 + ContainsKey("msg").ValueEqual("msg", "ok").
  33 + ContainsKey("data").Value("data").Object()
  34 + })
  35 + })
  36 + })
  37 + AfterEach(func() {
  38 + _, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
  39 + Expect(err).NotTo(HaveOccurred())
  40 + })
  41 +})
  1 +package block_chain
  2 +
  3 +import (
  4 + "github.com/go-pg/pg/v10"
  5 + "net/http"
  6 +
  7 + "github.com/gavv/httpexpect"
  8 + . "github.com/onsi/ginkgo"
  9 + . "github.com/onsi/gomega"
  10 + pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  11 +)
  12 +
  13 +var _ = Describe("更新", func() {
  14 + var upChainId int64
  15 + BeforeEach(func() {
  16 + _, err := pG.DB.QueryOne(
  17 + pg.Scan(&upChainId),
  18 + "INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
  19 + "testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
  20 + Expect(err).NotTo(HaveOccurred())
  21 + })
  22 + Describe("提交数据更新", func() {
  23 + Context("提交正确的上链数据数据", func() {
  24 + It("返回更新后的上链数据数据", func() {
  25 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  26 + body := map[string]interface{}{
  27 + "upChainId": "int64",
  28 + }
  29 + httpExpect.PUT("/block-chains/{blockChainId}").
  30 + WithJSON(body).
  31 + Expect().
  32 + Status(http.StatusOK).
  33 + JSON().
  34 + Object().
  35 + ContainsKey("code").ValueEqual("code", 0).
  36 + ContainsKey("msg").ValueEqual("msg", "ok").
  37 + ContainsKey("data").Value("data").Object().
  38 + ContainsKey("upChainId").ValueEqual("upChainId", upChainId)
  39 + })
  40 + })
  41 + })
  42 + AfterEach(func() {
  43 + _, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
  44 + Expect(err).NotTo(HaveOccurred())
  45 + })
  46 +})
  1 +package goqueue
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/linmadan/egglib-go/utils/json"
  6 + "github.com/tal-tech/go-queue/kq"
  7 + "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/constant"
  8 + "strings"
  9 + "testing"
  10 + "time"
  11 +)
  12 +
  13 +func Test_UpChain(t *testing.T) {
  14 + pusher := kq.NewPusher(strings.Split(constant.KAFKA_HOST, ","), constant.TOPIC_UP_BLOCK_CHAIN)
  15 + err := pusher.Push(json.MarshalToString(map[string]interface{}{
  16 + "source": "allied-creation.cooperation",
  17 + "primaryId": fmt.Sprintf("%v", time.Now().Unix()),
  18 + "issueId": "key12345",
  19 + "data": "{}",
  20 + }))
  21 + if err != nil {
  22 + t.Fatal(err)
  23 + }
  24 + time.Sleep(time.Second * 5)
  25 +}