0.0.3
This commit is contained in:
parent
19ea9c5a16
commit
811536bea4
33
go.mod
33
go.mod
@ -3,26 +3,27 @@ module github.com/lyydhl-zhang/common-module
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29
|
||||||
|
github.com/denisenkom/go-mssqldb v0.12.0
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
|
github.com/lib/pq v1.10.4
|
||||||
|
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||||
|
github.com/o1egl/paseto v1.0.0
|
||||||
|
go.uber.org/zap v1.19.1
|
||||||
|
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272
|
||||||
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8
|
||||||
|
golang.org/x/text v0.3.7
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.1.0 // indirect
|
||||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||||
github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29 // indirect
|
|
||||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect
|
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 // indirect
|
||||||
github.com/gomodule/redigo v1.8.5 // indirect
|
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
|
||||||
github.com/matoous/go-nanoid v1.5.0 // indirect
|
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
|
|
||||||
github.com/o1egl/paseto v1.0.0 // indirect
|
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
github.com/stretchr/testify v1.7.0 // indirect
|
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.7.0 // indirect
|
go.uber.org/multierr v1.7.0 // indirect
|
||||||
go.uber.org/zap v1.19.1 // indirect
|
|
||||||
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 // indirect
|
|
||||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 // indirect
|
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
38
go.sum
38
go.sum
@ -1,3 +1,8 @@
|
|||||||
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
|
||||||
|
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||||
|
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
|
||||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||||
github.com/aead/chacha20poly1305 v0.0.0-20170617001512-233f39982aeb/go.mod h1:UzH9IX1MMqOcwhoNOIjmTQeAxrFgzs50j4golQtXXxU=
|
github.com/aead/chacha20poly1305 v0.0.0-20170617001512-233f39982aeb/go.mod h1:UzH9IX1MMqOcwhoNOIjmTQeAxrFgzs50j4golQtXXxU=
|
||||||
@ -5,27 +10,31 @@ github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29 h1:1DcvRPZOd
|
|||||||
github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29/go.mod h1:UzH9IX1MMqOcwhoNOIjmTQeAxrFgzs50j4golQtXXxU=
|
github.com/aead/chacha20poly1305 v0.0.0-20201124145622-1a5aba2a8b29/go.mod h1:UzH9IX1MMqOcwhoNOIjmTQeAxrFgzs50j4golQtXXxU=
|
||||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
|
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
|
||||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
|
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635/go.mod h1:lmLxL+FV291OopO93Bwf9fQLQeLyt33VJRUg5VJ30us=
|
||||||
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
|
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||||
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4=
|
||||||
|
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
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.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/matoous/go-nanoid v1.5.0 h1:VRorl6uCngneC4oUQqOYtO3S0H5QKFtKuKycFG3euek=
|
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||||
github.com/matoous/go-nanoid v1.5.0/go.mod h1:zyD2a71IubI24efhpvkJz+ZwfwagzgSO6UNiFsZKN7U=
|
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||||
github.com/o1egl/paseto v1.0.0 h1:bwpvPu2au176w4IBlhbyUv/S5VPptERIA99Oap5qUd0=
|
github.com/o1egl/paseto v1.0.0 h1:bwpvPu2au176w4IBlhbyUv/S5VPptERIA99Oap5qUd0=
|
||||||
github.com/o1egl/paseto v1.0.0/go.mod h1:5HxsZPmw/3RI2pAwGo1HhOOwSdvBpcuVzO7uDkm+CLU=
|
github.com/o1egl/paseto v1.0.0/go.mod h1:5HxsZPmw/3RI2pAwGo1HhOOwSdvBpcuVzO7uDkm+CLU=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
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.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
@ -35,13 +44,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
|
||||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
|
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
|
||||||
@ -51,6 +60,7 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
|||||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/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-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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 h1:3erb+vDS8lU1sxfDHF4/hhWyaXnhIaO+7RgL4fDZORA=
|
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 h1:3erb+vDS8lU1sxfDHF4/hhWyaXnhIaO+7RgL4fDZORA=
|
||||||
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
@ -58,7 +68,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
|
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
|
||||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -68,12 +80,15 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 h1:7ZDGnxgHAMw7thfC5bEos0RDAccZKxioiWBhfIe+tvw=
|
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 h1:7ZDGnxgHAMw7thfC5bEos0RDAccZKxioiWBhfIe+tvw=
|
||||||
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@ -85,8 +100,11 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
6
pkg/util/cache.go → pkg/cache/cache.go
vendored
6
pkg/util/cache.go → pkg/cache/cache.go
vendored
@ -1,4 +1,4 @@
|
|||||||
package util
|
package cache
|
||||||
|
|
||||||
// 简单缓存 适合小数据量
|
// 简单缓存 适合小数据量
|
||||||
|
|
||||||
@ -27,7 +27,3 @@ func GetCache(key string) (interface{}, bool) {
|
|||||||
func DeleteCache(key string) {
|
func DeleteCache(key string) {
|
||||||
globalMap.Delete(key)
|
globalMap.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
//func LenCache() int {
|
|
||||||
// return int(cacheLen)
|
|
||||||
//}
|
|
||||||
17
pkg/cache/manager.go
vendored
17
pkg/cache/manager.go
vendored
@ -1,17 +0,0 @@
|
|||||||
package cache
|
|
||||||
|
|
||||||
// Manager 管理缓存的接口定义
|
|
||||||
type Manager interface {
|
|
||||||
// Set 设置缓存
|
|
||||||
Set(key string, value interface{}) error
|
|
||||||
// SetDefault 设置缓存
|
|
||||||
SetDefault(key string, value interface{}, expire int64) error
|
|
||||||
// Get 获取缓存
|
|
||||||
Get(key string) (interface{}, error)
|
|
||||||
// GetString 获取缓存
|
|
||||||
GetString(key string) (string, error)
|
|
||||||
// Exists key是否存在
|
|
||||||
Exists(key string) bool
|
|
||||||
// Delete 删除key
|
|
||||||
Delete(key string) error
|
|
||||||
}
|
|
||||||
70
pkg/cache/memory_manager.go
vendored
70
pkg/cache/memory_manager.go
vendored
@ -1,70 +0,0 @@
|
|||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MemoryManager memory缓存管理
|
|
||||||
type MemoryManager struct {
|
|
||||||
cache *cache.Cache
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMemoryManager 获取一个新的内存管理对象
|
|
||||||
// defaultExpiration 缓存过期时间
|
|
||||||
// cleanupInterval 缓存清理时间
|
|
||||||
func NewMemoryManager(defaultExpiration, cleanupInterval time.Duration) Manager {
|
|
||||||
return &MemoryManager{cache: cache.New(defaultExpiration, cleanupInterval)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 设置缓存
|
|
||||||
// key 键
|
|
||||||
// value 值
|
|
||||||
func (manager *MemoryManager) Set(key string, value interface{}) error {
|
|
||||||
manager.cache.Set(key, value, time.Hour*24*365*100) // 10年
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefault 设置缓存
|
|
||||||
// key 键
|
|
||||||
// value 值
|
|
||||||
// expire 过期时间 (秒)
|
|
||||||
func (manager *MemoryManager) SetDefault(key string, value interface{}, expire int64) error {
|
|
||||||
manager.cache.Set(key, value, time.Second*time.Duration(expire))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get 获取缓存
|
|
||||||
func (manager *MemoryManager) Get(key string) (interface{}, error) {
|
|
||||||
value, found := manager.cache.Get(key)
|
|
||||||
if found {
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
return nil, errors.New("no found data with key")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString 获取缓存
|
|
||||||
func (manager *MemoryManager) GetString(key string) (string, error) {
|
|
||||||
value, found := manager.cache.Get(key)
|
|
||||||
if found {
|
|
||||||
return fmt.Sprintf("%v", value), nil
|
|
||||||
}
|
|
||||||
return "", errors.New("no found data with key")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exists key是否存在
|
|
||||||
func (manager *MemoryManager) Exists(key string) bool {
|
|
||||||
if _, found := manager.cache.Get(key); found {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete 删除key
|
|
||||||
func (manager *MemoryManager) Delete(key string) error {
|
|
||||||
manager.cache.Delete(key)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
135
pkg/cache/redis_manager.go
vendored
135
pkg/cache/redis_manager.go
vendored
@ -1,135 +0,0 @@
|
|||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gomodule/redigo/redis"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RedisManager redis缓存管理
|
|
||||||
type RedisManager struct {
|
|
||||||
pool *redis.Pool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRedisManager 获取一个新的redis管理对象
|
|
||||||
func NewRedisManager(address string) Manager {
|
|
||||||
pool := &redis.Pool{
|
|
||||||
// 连接方法
|
|
||||||
Dial: func() (redis.Conn, error) {
|
|
||||||
c, err := redis.Dial("tcp", address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.Do("SELECT", 0)
|
|
||||||
return c, nil
|
|
||||||
},
|
|
||||||
//DialContext: nil,
|
|
||||||
//TestOnBorrow: nil,
|
|
||||||
MaxIdle: 10, // 最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态。
|
|
||||||
MaxActive: 10, // 最大的激活连接数,表示同时最多有N个连接
|
|
||||||
IdleTimeout: 360 * time.Second, // 最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭
|
|
||||||
//Wait: false,
|
|
||||||
//MaxConnLifetime: 0,
|
|
||||||
}
|
|
||||||
return &RedisManager{pool}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 设置缓存
|
|
||||||
// key 键
|
|
||||||
// value 值
|
|
||||||
func (manager *RedisManager) Set(key string, value interface{}) error {
|
|
||||||
conn := manager.pool.Get()
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
_, err := conn.Do("Set", key, value)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("set cache error: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefault 设置缓存
|
|
||||||
// key 键
|
|
||||||
// value 值
|
|
||||||
// expire 过期时间 (秒)
|
|
||||||
func (manager *RedisManager) SetDefault(key string, value interface{}, expire int64) error {
|
|
||||||
conn := manager.pool.Get()
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
//_, err := conn.Do("set", key, value)
|
|
||||||
//if err != nil {
|
|
||||||
// return fmt.Errorf("set default cache error: %v", err)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//// 设置过期时间
|
|
||||||
//conn.Do("expire", key, expire)
|
|
||||||
//return nil
|
|
||||||
|
|
||||||
_, err := conn.Do("set", key, value, "ex", expire)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("set default cache error: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get 获取缓存
|
|
||||||
func (manager *RedisManager) Get(key string) (interface{}, error) {
|
|
||||||
conn := manager.pool.Get()
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
// 检查key是否存在
|
|
||||||
exit, err := redis.Bool(conn.Do("exists", key))
|
|
||||||
if err != nil || !exit {
|
|
||||||
return nil, fmt.Errorf("key is not exists")
|
|
||||||
}
|
|
||||||
|
|
||||||
value, err := conn.Do("get", key)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("get cache error: %v", err)
|
|
||||||
}
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString 获取缓存
|
|
||||||
func (manager *RedisManager) GetString(key string) (string, error) {
|
|
||||||
conn := manager.pool.Get()
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
// 检查key是否存在
|
|
||||||
exit, err := redis.Bool(conn.Do("exists", key))
|
|
||||||
if err != nil || !exit {
|
|
||||||
return "", fmt.Errorf("key is not exists")
|
|
||||||
}
|
|
||||||
|
|
||||||
value, err := redis.String(conn.Do("get", key))
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("get cache error: %v", err)
|
|
||||||
}
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exists key是否存在
|
|
||||||
func (manager *RedisManager) Exists(key string) bool {
|
|
||||||
conn := manager.pool.Get()
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
// 检查key是否存在
|
|
||||||
exit, err := redis.Bool(conn.Do("expire", key))
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return exit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete 删除key
|
|
||||||
func (manager *RedisManager) Delete(key string) error {
|
|
||||||
conn := manager.pool.Get()
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
_, err := conn.Do("del", key)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("删除key:[%s]异常:%v", key, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
7
pkg/conver/conver.go
Normal file
7
pkg/conver/conver.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package conver
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
func FloatToString(val float64) string {
|
||||||
|
return strconv.FormatFloat(val, 'f', 1, 64)
|
||||||
|
}
|
||||||
16
pkg/database/mssql.go
Normal file
16
pkg/database/mssql.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
mssql "github.com/denisenkom/go-mssqldb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MSIsUniqueViolation 唯一值是否冲突 ture: 是, false: 否
|
||||||
|
func MSIsUniqueViolation(err error) bool {
|
||||||
|
msErr, ok := err.(mssql.Error)
|
||||||
|
return ok && msErr.Number == 2627
|
||||||
|
}
|
||||||
|
|
||||||
|
//func MsIsForeignKeyViolation(err error) bool {
|
||||||
|
// msErr, ok := err.(mssql.Error)
|
||||||
|
// return ok && msErr.Number == 0
|
||||||
|
//}
|
||||||
15
pkg/database/postgres.go
Normal file
15
pkg/database/postgres.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/lib/pq"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PGIsUniqueViolation(err error) bool {
|
||||||
|
pqErr, ok := err.(*pq.Error)
|
||||||
|
return ok && pqErr.Code == "23505"
|
||||||
|
}
|
||||||
|
|
||||||
|
func PGIsForeignKeyViolation(err error) bool {
|
||||||
|
pqErr, ok := err.(*pq.Error)
|
||||||
|
return ok && pqErr.Code == "23503"
|
||||||
|
}
|
||||||
44
pkg/database/query.go
Normal file
44
pkg/database/query.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
var queriesCache sync.Map
|
||||||
|
|
||||||
|
func BuildQuery(text string, data map[string]interface{}) (string, []interface{}, error) {
|
||||||
|
var t *template.Template
|
||||||
|
v, ok := queriesCache.Load(text)
|
||||||
|
if !ok {
|
||||||
|
var err error
|
||||||
|
t, err = template.New("query").Parse(text)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, fmt.Errorf("could not parse sql query template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
queriesCache.Store(text, t)
|
||||||
|
} else {
|
||||||
|
t = v.(*template.Template)
|
||||||
|
}
|
||||||
|
|
||||||
|
var wr bytes.Buffer
|
||||||
|
if err := t.Execute(&wr, data); err != nil {
|
||||||
|
return "", nil, fmt.Errorf("could not apply sql query data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
query := wr.String()
|
||||||
|
var args []interface{}
|
||||||
|
for key, val := range data {
|
||||||
|
if !strings.Contains(query, "@"+key) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, val)
|
||||||
|
query = strings.Replace(query, "@"+key, fmt.Sprintf("$%d", len(args)), -1)
|
||||||
|
}
|
||||||
|
return query, args, nil
|
||||||
|
}
|
||||||
12
pkg/dt/time.go
Normal file
12
pkg/dt/time.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package dt
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
func GetTime(t string) (time.Time, error) {
|
||||||
|
now := time.Now()
|
||||||
|
d, err := time.ParseDuration(t)
|
||||||
|
if err != nil {
|
||||||
|
return now, err
|
||||||
|
}
|
||||||
|
return now.Add(d), nil
|
||||||
|
}
|
||||||
@ -70,6 +70,6 @@ func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
|
|||||||
// PKCS7UnPadding 去码
|
// PKCS7UnPadding 去码
|
||||||
func PKCS7UnPadding(origData []byte) []byte {
|
func PKCS7UnPadding(origData []byte) []byte {
|
||||||
length := len(origData)
|
length := len(origData)
|
||||||
unpadding := int(origData[length-1])
|
unPadding := int(origData[length-1])
|
||||||
return origData[:(length - unpadding)]
|
return origData[:(length - unPadding)]
|
||||||
}
|
}
|
||||||
12
pkg/encrypt/md5.go
Normal file
12
pkg/encrypt/md5.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package encrypt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MD5(value string) string {
|
||||||
|
m := md5.New()
|
||||||
|
m.Write([]byte(value))
|
||||||
|
return hex.EncodeToString(m.Sum(nil))
|
||||||
|
}
|
||||||
72
pkg/encrypt/password.go
Normal file
72
pkg/encrypt/password.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package encrypt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"golang.org/x/crypto/scrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ******************** scrypt ********************
|
||||||
|
|
||||||
|
// ScryptHashPassword scrypt 加密
|
||||||
|
// password 原始密码
|
||||||
|
func ScryptHashPassword(password string) (string, error) {
|
||||||
|
// example for making salt - https://play.golang.org/p/_Aw6WeWC42I
|
||||||
|
salt := make([]byte, 32)
|
||||||
|
_, err := rand.Read(salt)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// using recommended cost parameters from - https://godoc.org/golang.org/x/crypto/scrypt
|
||||||
|
shash, err := scrypt.Key([]byte(password), salt, 32768, 8, 1, 32)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// return hex-encoded string with salt appended to password
|
||||||
|
hashedPW := fmt.Sprintf("%s.%s", hex.EncodeToString(shash), hex.EncodeToString(salt))
|
||||||
|
|
||||||
|
return hashedPW, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScryptComparePassword 判断密码是否正确
|
||||||
|
// storedPassword 加密密码
|
||||||
|
// suppliedPassword 原始密码
|
||||||
|
func ScryptComparePassword(storedPassword string, suppliedPassword string) (bool, error) {
|
||||||
|
pwsalt := strings.Split(storedPassword, ".")
|
||||||
|
|
||||||
|
// check supplied password salted with hash
|
||||||
|
salt, err := hex.DecodeString(pwsalt[1])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("unable to verify user password")
|
||||||
|
}
|
||||||
|
|
||||||
|
shash, err := scrypt.Key([]byte(suppliedPassword), salt, 32768, 8, 1, 32)
|
||||||
|
|
||||||
|
return hex.EncodeToString(shash) == pwsalt[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ******************** bcrypt ********************
|
||||||
|
|
||||||
|
// BcryptHashPassword bcrypt 加密
|
||||||
|
// password 原始密码
|
||||||
|
func BcryptHashPassword(password string) (string, error) {
|
||||||
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to hash password: %w", err)
|
||||||
|
}
|
||||||
|
return string(hashedPassword), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BcryptComparePassword 判断密码是否正确
|
||||||
|
// hashedPassword 加密密码
|
||||||
|
// password 原始密码
|
||||||
|
func BcryptComparePassword(hashedPassword string, password string) error {
|
||||||
|
return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
||||||
|
}
|
||||||
12
pkg/env/env.go
vendored
Normal file
12
pkg/env/env.go
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package env
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
func GetEnvWithDefault(name, def string) string {
|
||||||
|
env := os.Getenv(name)
|
||||||
|
if len(env) != 0 {
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
|
return def
|
||||||
|
}
|
||||||
80
pkg/fetcher/fetcher.go
Normal file
80
pkg/fetcher/fetcher.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package fetcher
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/html/charset"
|
||||||
|
"golang.org/x/text/encoding"
|
||||||
|
"golang.org/x/text/encoding/unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get get 请求
|
||||||
|
func Get(url string) ([]byte, error) {
|
||||||
|
client := &http.Client{}
|
||||||
|
req, _ := http.NewRequest("GET", url, nil)
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
res, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostJson application/json post 请求
|
||||||
|
func PostJson(url, parameter string, timeout int) ([]byte, error) {
|
||||||
|
client := &http.Client{Timeout: time.Second * time.Duration(timeout)}
|
||||||
|
byteParameter := bytes.NewBuffer([]byte(parameter))
|
||||||
|
request, _ := http.NewRequest("POST", url, byteParameter)
|
||||||
|
request.Header.Set("Content-type", "application/json")
|
||||||
|
response, _ := client.Do(request)
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
return nil, errors.New("网络请求失败")
|
||||||
|
}
|
||||||
|
all, err := io.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("读取网络内容失败")
|
||||||
|
}
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostString application/x-www-form-urlencoded 请求
|
||||||
|
func PostString(url, parameter string, timeout int) ([]byte, error) {
|
||||||
|
client := &http.Client{Timeout: time.Second * time.Duration(timeout)}
|
||||||
|
byteParameter := bytes.NewBuffer([]byte(parameter))
|
||||||
|
request, _ := http.NewRequest("POST", url, byteParameter)
|
||||||
|
request.Header.Set("Content-type", "application/x-www-form-urlencoded")
|
||||||
|
response, _ := client.Do(request)
|
||||||
|
if response.StatusCode != 200 {
|
||||||
|
return nil, errors.New("网络请求失败")
|
||||||
|
}
|
||||||
|
all, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("读取网络内容失败")
|
||||||
|
}
|
||||||
|
return all, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func determinEncoding(r *bufio.Reader) encoding.Encoding {
|
||||||
|
bytes, err := r.Peek(1024)
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
log.Printf("Fetcher error: %v", err)
|
||||||
|
return unicode.UTF8
|
||||||
|
}
|
||||||
|
|
||||||
|
e, _, _ := charset.DetermineEncoding(bytes, "")
|
||||||
|
return e
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package util
|
package ft
|
||||||
|
|
||||||
import "os"
|
import "os"
|
||||||
|
|
||||||
@ -31,4 +31,4 @@ func MkDir(src string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -13,19 +13,17 @@ const (
|
|||||||
TOTAL_HEADER_LENGTH = 8192
|
TOTAL_HEADER_LENGTH = 8192
|
||||||
)
|
)
|
||||||
|
|
||||||
var err error
|
var IpRegion *Ip2Region
|
||||||
var ipInfo IpInfo
|
|
||||||
|
|
||||||
type Ip2Region struct {
|
type Ip2Region struct {
|
||||||
// db file handler
|
// db file handler
|
||||||
dbFileHandler *os.File
|
dbFileHandler *os.File
|
||||||
|
|
||||||
|
|
||||||
//header block info
|
//header block info
|
||||||
|
|
||||||
headerSip []int64
|
headerSip []int64
|
||||||
headerPtr []int64
|
headerPtr []int64
|
||||||
headerLen int64
|
headerLen int64
|
||||||
|
|
||||||
// super block index info
|
// super block index info
|
||||||
firstIndexPtr int64
|
firstIndexPtr int64
|
||||||
@ -35,20 +33,20 @@ type Ip2Region struct {
|
|||||||
// for memory mode only
|
// for memory mode only
|
||||||
// the original db binary string
|
// the original db binary string
|
||||||
|
|
||||||
dbBinStr []byte
|
dbBinStr []byte
|
||||||
dbFile string
|
dbFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
type IpInfo struct {
|
type IpInfo struct {
|
||||||
CityId int64
|
CityId int64 `json:"city_id"`
|
||||||
Country string
|
Country string `json:"country"`
|
||||||
Region string
|
Region string `json:"region"`
|
||||||
Province string
|
Province string `json:"province"`
|
||||||
City string
|
City string `json:"city"`
|
||||||
ISP string
|
ISP string `json:"isp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ip IpInfo)String() string {
|
func (ip IpInfo) String() string {
|
||||||
return strconv.FormatInt(ip.CityId, 10) + "|" + ip.Country + "|" + ip.Region + "|" + ip.Province + "|" + ip.City + "|" + ip.ISP
|
return strconv.FormatInt(ip.CityId, 10) + "|" + ip.Country + "|" + ip.Region + "|" + ip.Province + "|" + ip.City + "|" + ip.ISP
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +57,7 @@ func getIpInfo(cityId int64, line []byte) IpInfo {
|
|||||||
length := len(lineSlice)
|
length := len(lineSlice)
|
||||||
ipInfo.CityId = cityId
|
ipInfo.CityId = cityId
|
||||||
if length < 5 {
|
if length < 5 {
|
||||||
for i := 0; i <= 5 - length; i++ {
|
for i := 0; i <= 5-length; i++ {
|
||||||
lineSlice = append(lineSlice, "")
|
lineSlice = append(lineSlice, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,37 +70,39 @@ func getIpInfo(cityId int64, line []byte) IpInfo {
|
|||||||
return ipInfo
|
return ipInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(path string) (*Ip2Region, error) {
|
func New(path string) error {
|
||||||
|
|
||||||
file, err := os.Open(path)
|
file, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Ip2Region{
|
IpRegion = &Ip2Region{
|
||||||
dbFile:path,
|
dbFile: path,
|
||||||
dbFileHandler:file,
|
dbFileHandler: file,
|
||||||
}, nil
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Ip2Region) Close() {
|
func (region *Ip2Region) Close() error {
|
||||||
this.dbFileHandler.Close()
|
return region.dbFileHandler.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Ip2Region) MemorySearch(ipStr string) (ipInfo IpInfo, err error) {
|
func (region *Ip2Region) MemorySearch(ipStr string) (ipInfo IpInfo, err error) {
|
||||||
ipInfo = IpInfo{}
|
ipInfo = IpInfo{}
|
||||||
|
|
||||||
if this.totalBlocks == 0 {
|
if region.totalBlocks == 0 {
|
||||||
this.dbBinStr, err = ioutil.ReadFile(this.dbFile)
|
region.dbBinStr, err = ioutil.ReadFile(region.dbFile)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return ipInfo, err
|
return ipInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
this.firstIndexPtr = getLong(this.dbBinStr, 0)
|
region.firstIndexPtr = getLong(region.dbBinStr, 0)
|
||||||
this.lastIndexPtr = getLong(this.dbBinStr, 4)
|
region.lastIndexPtr = getLong(region.dbBinStr, 4)
|
||||||
this.totalBlocks = (this.lastIndexPtr - this.firstIndexPtr) /INDEX_BLOCK_LENGTH + 1
|
region.totalBlocks = (region.lastIndexPtr-region.firstIndexPtr)/INDEX_BLOCK_LENGTH + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := ip2long(ipStr)
|
ip, err := ip2long(ipStr)
|
||||||
@ -110,22 +110,22 @@ func (this *Ip2Region) MemorySearch(ipStr string) (ipInfo IpInfo, err error) {
|
|||||||
return ipInfo, err
|
return ipInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
h := this.totalBlocks
|
h := region.totalBlocks
|
||||||
var dataPtr, l int64;
|
var dataPtr, l int64
|
||||||
for (l <= h) {
|
for l <= h {
|
||||||
|
|
||||||
m := (l + h) >> 1
|
m := (l + h) >> 1
|
||||||
p := this.firstIndexPtr + m *INDEX_BLOCK_LENGTH
|
p := region.firstIndexPtr + m*INDEX_BLOCK_LENGTH
|
||||||
sip := getLong(this.dbBinStr, p)
|
sip := getLong(region.dbBinStr, p)
|
||||||
if ip < sip {
|
if ip < sip {
|
||||||
h = m - 1
|
h = m - 1
|
||||||
} else {
|
} else {
|
||||||
eip := getLong(this.dbBinStr, p + 4)
|
eip := getLong(region.dbBinStr, p+4)
|
||||||
if ip > eip {
|
if ip > eip {
|
||||||
l = m + 1
|
l = m + 1
|
||||||
} else {
|
} else {
|
||||||
dataPtr = getLong(this.dbBinStr, p + 8)
|
dataPtr = getLong(region.dbBinStr, p+8)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,26 +134,26 @@ func (this *Ip2Region) MemorySearch(ipStr string) (ipInfo IpInfo, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dataLen := ((dataPtr >> 24) & 0xFF)
|
dataLen := ((dataPtr >> 24) & 0xFF)
|
||||||
dataPtr = (dataPtr & 0x00FFFFFF);
|
dataPtr = (dataPtr & 0x00FFFFFF)
|
||||||
ipInfo = getIpInfo(getLong(this.dbBinStr, dataPtr), this.dbBinStr[(dataPtr) + 4:dataPtr + dataLen])
|
ipInfo = getIpInfo(getLong(region.dbBinStr, dataPtr), region.dbBinStr[(dataPtr)+4:dataPtr+dataLen])
|
||||||
return ipInfo, nil
|
return ipInfo, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Ip2Region)BinarySearch(ipStr string) (ipInfo IpInfo, err error) {
|
func (region *Ip2Region) BinarySearch(ipStr string) (ipInfo IpInfo, err error) {
|
||||||
ipInfo = IpInfo{}
|
ipInfo = IpInfo{}
|
||||||
if this.totalBlocks == 0 {
|
if region.totalBlocks == 0 {
|
||||||
this.dbFileHandler.Seek(0, 0)
|
region.dbFileHandler.Seek(0, 0)
|
||||||
superBlock := make([]byte, 8)
|
superBlock := make([]byte, 8)
|
||||||
this.dbFileHandler.Read(superBlock)
|
region.dbFileHandler.Read(superBlock)
|
||||||
this.firstIndexPtr = getLong(superBlock, 0)
|
region.firstIndexPtr = getLong(superBlock, 0)
|
||||||
this.lastIndexPtr = getLong(superBlock, 4)
|
region.lastIndexPtr = getLong(superBlock, 4)
|
||||||
this.totalBlocks = (this.lastIndexPtr - this.firstIndexPtr) /INDEX_BLOCK_LENGTH + 1
|
region.totalBlocks = (region.lastIndexPtr-region.firstIndexPtr)/INDEX_BLOCK_LENGTH + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var l, dataPtr, p int64
|
var l, dataPtr, p int64
|
||||||
|
|
||||||
h := this.totalBlocks
|
h := region.totalBlocks
|
||||||
|
|
||||||
ip, err := ip2long(ipStr)
|
ip, err := ip2long(ipStr)
|
||||||
|
|
||||||
@ -161,21 +161,21 @@ func (this *Ip2Region)BinarySearch(ipStr string) (ipInfo IpInfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l <= h) {
|
for l <= h {
|
||||||
m := (l + h) >> 1
|
m := (l + h) >> 1
|
||||||
|
|
||||||
p = m * INDEX_BLOCK_LENGTH
|
p = m * INDEX_BLOCK_LENGTH
|
||||||
|
|
||||||
_, err = this.dbFileHandler.Seek(this.firstIndexPtr + p, 0)
|
_, err = region.dbFileHandler.Seek(region.firstIndexPtr+p, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer := make([]byte, INDEX_BLOCK_LENGTH)
|
buffer := make([]byte, INDEX_BLOCK_LENGTH)
|
||||||
_, err = this.dbFileHandler.Read(buffer)
|
_, err = region.dbFileHandler.Read(buffer)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return ipInfo, err
|
||||||
}
|
}
|
||||||
sip := getLong(buffer, 0)
|
sip := getLong(buffer, 0)
|
||||||
if ip < sip {
|
if ip < sip {
|
||||||
@ -186,7 +186,7 @@ func (this *Ip2Region)BinarySearch(ipStr string) (ipInfo IpInfo, err error) {
|
|||||||
l = m + 1
|
l = m + 1
|
||||||
} else {
|
} else {
|
||||||
dataPtr = getLong(buffer, 8)
|
dataPtr = getLong(buffer, 8)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,76 +198,76 @@ func (this *Ip2Region)BinarySearch(ipStr string) (ipInfo IpInfo, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dataLen := ((dataPtr >> 24) & 0xFF)
|
dataLen := ((dataPtr >> 24) & 0xFF)
|
||||||
dataPtr = (dataPtr & 0x00FFFFFF);
|
dataPtr = (dataPtr & 0x00FFFFFF)
|
||||||
|
|
||||||
this.dbFileHandler.Seek(dataPtr, 0)
|
region.dbFileHandler.Seek(dataPtr, 0)
|
||||||
data := make([]byte, dataLen)
|
data := make([]byte, dataLen)
|
||||||
this.dbFileHandler.Read(data)
|
region.dbFileHandler.Read(data)
|
||||||
ipInfo = getIpInfo(getLong(data, 0), data[4:dataLen])
|
ipInfo = getIpInfo(getLong(data, 0), data[4:dataLen])
|
||||||
err = nil
|
err = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Ip2Region) BtreeSearch(ipStr string) (ipInfo IpInfo, err error) {
|
func (region *Ip2Region) BtreeSearch(ipStr string) (ipInfo IpInfo, err error) {
|
||||||
ipInfo = IpInfo{}
|
ipInfo = IpInfo{}
|
||||||
ip, err := ip2long(ipStr)
|
ip, err := ip2long(ipStr)
|
||||||
|
|
||||||
if this.headerLen == 0 {
|
if region.headerLen == 0 {
|
||||||
this.dbFileHandler.Seek(8, 0)
|
region.dbFileHandler.Seek(8, 0)
|
||||||
|
|
||||||
buffer := make([]byte, TOTAL_HEADER_LENGTH)
|
buffer := make([]byte, TOTAL_HEADER_LENGTH)
|
||||||
this.dbFileHandler.Read(buffer)
|
region.dbFileHandler.Read(buffer)
|
||||||
var idx int64;
|
var idx int64
|
||||||
for i := 0; i < TOTAL_HEADER_LENGTH; i += 8 {
|
for i := 0; i < TOTAL_HEADER_LENGTH; i += 8 {
|
||||||
startIp := getLong(buffer, int64(i))
|
startIp := getLong(buffer, int64(i))
|
||||||
dataPar := getLong(buffer, int64(i + 4))
|
dataPar := getLong(buffer, int64(i+4))
|
||||||
if dataPar == 0 {
|
if dataPar == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
this.headerSip = append(this.headerSip, startIp)
|
region.headerSip = append(region.headerSip, startIp)
|
||||||
this.headerPtr = append(this.headerPtr, dataPar)
|
region.headerPtr = append(region.headerPtr, dataPar)
|
||||||
idx ++;
|
idx++
|
||||||
}
|
}
|
||||||
|
|
||||||
this.headerLen = idx
|
region.headerLen = idx
|
||||||
}
|
}
|
||||||
|
|
||||||
var l, sptr, eptr int64
|
var l, sptr, eptr int64
|
||||||
h := this.headerLen
|
h := region.headerLen
|
||||||
|
|
||||||
for l <= h {
|
for l <= h {
|
||||||
m := int64(l + h) >> 1
|
m := int64(l+h) >> 1
|
||||||
if m < this.headerLen {
|
if m < region.headerLen {
|
||||||
if ip == this.headerSip[m] {
|
if ip == region.headerSip[m] {
|
||||||
if m > 0 {
|
if m > 0 {
|
||||||
sptr = this.headerPtr[m - 1]
|
sptr = region.headerPtr[m-1]
|
||||||
eptr = this.headerPtr[m]
|
eptr = region.headerPtr[m]
|
||||||
} else {
|
} else {
|
||||||
sptr = this.headerPtr[m]
|
sptr = region.headerPtr[m]
|
||||||
eptr = this.headerPtr[m + 1]
|
eptr = region.headerPtr[m+1]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if ip < this.headerSip[m] {
|
if ip < region.headerSip[m] {
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
sptr = this.headerPtr[m]
|
sptr = region.headerPtr[m]
|
||||||
eptr = this.headerPtr[m + 1]
|
eptr = region.headerPtr[m+1]
|
||||||
break
|
break
|
||||||
} else if ip > this.headerSip[m - 1] {
|
} else if ip > region.headerSip[m-1] {
|
||||||
sptr = this.headerPtr[m - 1]
|
sptr = region.headerPtr[m-1]
|
||||||
eptr = this.headerPtr[m]
|
eptr = region.headerPtr[m]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
h = m - 1
|
h = m - 1
|
||||||
} else {
|
} else {
|
||||||
if m == this.headerLen - 1 {
|
if m == region.headerLen-1 {
|
||||||
sptr = this.headerPtr[m - 1]
|
sptr = region.headerPtr[m-1]
|
||||||
eptr = this.headerPtr[m]
|
eptr = region.headerPtr[m]
|
||||||
break
|
break
|
||||||
} else if ip <= this.headerSip[m + 1] {
|
} else if ip <= region.headerSip[m+1] {
|
||||||
sptr = this.headerPtr[m ]
|
sptr = region.headerPtr[m]
|
||||||
eptr = this.headerPtr[m + 1]
|
eptr = region.headerPtr[m+1]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
l = m + 1
|
l = m + 1
|
||||||
@ -282,25 +282,25 @@ func (this *Ip2Region) BtreeSearch(ipStr string) (ipInfo IpInfo, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
blockLen := eptr - sptr
|
blockLen := eptr - sptr
|
||||||
this.dbFileHandler.Seek(sptr, 0)
|
region.dbFileHandler.Seek(sptr, 0)
|
||||||
index := make([]byte, blockLen +INDEX_BLOCK_LENGTH)
|
index := make([]byte, blockLen+INDEX_BLOCK_LENGTH)
|
||||||
this.dbFileHandler.Read(index)
|
region.dbFileHandler.Read(index)
|
||||||
var dataptr int64
|
var dataptr int64
|
||||||
h = blockLen / INDEX_BLOCK_LENGTH
|
h = blockLen / INDEX_BLOCK_LENGTH
|
||||||
l = 0
|
l = 0
|
||||||
|
|
||||||
for l <= h {
|
for l <= h {
|
||||||
m := int64(l + h) >> 1
|
m := int64(l+h) >> 1
|
||||||
p := m * INDEX_BLOCK_LENGTH
|
p := m * INDEX_BLOCK_LENGTH
|
||||||
sip := getLong(index, p)
|
sip := getLong(index, p)
|
||||||
if ip < sip {
|
if ip < sip {
|
||||||
h = m - 1;
|
h = m - 1
|
||||||
} else {
|
} else {
|
||||||
eip := getLong(index, p + 4)
|
eip := getLong(index, p+4)
|
||||||
if ip > eip {
|
if ip > eip {
|
||||||
l = m + 1
|
l = m + 1
|
||||||
} else {
|
} else {
|
||||||
dataptr = getLong(index, p + 8)
|
dataptr = getLong(index, p+8)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,19 +314,19 @@ func (this *Ip2Region) BtreeSearch(ipStr string) (ipInfo IpInfo, err error) {
|
|||||||
dataLen := (dataptr >> 24) & 0xFF
|
dataLen := (dataptr >> 24) & 0xFF
|
||||||
dataPtr := dataptr & 0x00FFFFFF
|
dataPtr := dataptr & 0x00FFFFFF
|
||||||
|
|
||||||
this.dbFileHandler.Seek(dataPtr, 0)
|
region.dbFileHandler.Seek(dataPtr, 0)
|
||||||
data := make([]byte, dataLen)
|
data := make([]byte, dataLen)
|
||||||
this.dbFileHandler.Read(data)
|
region.dbFileHandler.Read(data)
|
||||||
ipInfo = getIpInfo(getLong(data, 0), data[4:])
|
ipInfo = getIpInfo(getLong(data, 0), data[4:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLong(b []byte, offset int64) int64 {
|
func getLong(b []byte, offset int64) int64 {
|
||||||
|
|
||||||
val := (int64(b[offset ]) |
|
val := (int64(b[offset]) |
|
||||||
int64(b[offset + 1]) << 8 |
|
int64(b[offset+1])<<8 |
|
||||||
int64(b[offset + 2]) << 16 |
|
int64(b[offset+2])<<16 |
|
||||||
int64(b[offset + 3]) << 24)
|
int64(b[offset+3])<<24)
|
||||||
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
@ -341,9 +341,8 @@ func ip2long(IpStr string) (int64, error) {
|
|||||||
var sum int64
|
var sum int64
|
||||||
for i, n := range bits {
|
for i, n := range bits {
|
||||||
bit, _ := strconv.ParseInt(n, 10, 64)
|
bit, _ := strconv.ParseInt(n, 10, 64)
|
||||||
sum += bit << uint(24 - 8 * i)
|
sum += bit << uint(24-8*i)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum, nil
|
return sum, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,49 +0,0 @@
|
|||||||
package ip2region
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func BenchmarkBtreeSearch(B *testing.B) {
|
|
||||||
region, err := New("../../data/ip2region.db ")
|
|
||||||
if err != nil {
|
|
||||||
B.Error(err)
|
|
||||||
}
|
|
||||||
for i:=0;i<B.N;i++{
|
|
||||||
region.BtreeSearch("127.0.0.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkMemorySearch(B *testing.B) {
|
|
||||||
region, err := New("../../data/ip2region.db ")
|
|
||||||
if err != nil {
|
|
||||||
B.Error(err)
|
|
||||||
}
|
|
||||||
for i:=0;i<B.N;i++{
|
|
||||||
region.MemorySearch("127.0.0.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkBinarySearch(B *testing.B) {
|
|
||||||
region, err := New("../../data/ip2region.db ")
|
|
||||||
if err != nil {
|
|
||||||
B.Error(err)
|
|
||||||
}
|
|
||||||
for i:=0;i<B.N;i++{
|
|
||||||
region.BinarySearch("127.0.0.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIp2long(t *testing.T) {
|
|
||||||
ip, err := ip2long("127.0.0.1")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if ip != 2130706433 {
|
|
||||||
t.Error("result error")
|
|
||||||
}
|
|
||||||
t.Log(ip)
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package util
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/natefinch/lumberjack"
|
"github.com/natefinch/lumberjack"
|
||||||
@ -6,12 +6,12 @@ import (
|
|||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewLogger() *zap.SugaredLogger {
|
var Logger *zap.SugaredLogger
|
||||||
writeSyncer := getLogWriter()
|
|
||||||
encoder := getEncoder()
|
func NewLogger() {
|
||||||
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
|
core := zapcore.NewCore(getEncoder(), getLogWriter(), zapcore.DebugLevel)
|
||||||
logger := zap.New(core, zap.AddCaller())
|
logger := zap.New(core, zap.AddCaller())
|
||||||
return logger.Sugar()
|
Logger = logger.Sugar()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEncoder() zapcore.Encoder {
|
func getEncoder() zapcore.Encoder {
|
||||||
@ -1,12 +1,9 @@
|
|||||||
package util
|
package random
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
gonanoid "github.com/matoous/go-nanoid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
@ -29,23 +26,10 @@ func RandomString(n int) string {
|
|||||||
|
|
||||||
func RandomInt(n int) string {
|
func RandomInt(n int) string {
|
||||||
var letters = []byte("0123456789")
|
var letters = []byte("0123456789")
|
||||||
|
l := len(letters)
|
||||||
result := make([]byte, n)
|
result := make([]byte, n)
|
||||||
for i := range result {
|
for i := range result {
|
||||||
result[i] = letters[rand.Intn(len(letters))]
|
result[i] = letters[rand.Intn(l)]
|
||||||
}
|
}
|
||||||
return string(result)
|
return string(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RandomLevel() string {
|
|
||||||
levels := []string{"DEBUG", "INFO", "ERROR", "WARNING", "FAIL"}
|
|
||||||
n := len(levels)
|
|
||||||
return levels[rand.Intn(n)]
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateFilename() (string, error) {
|
|
||||||
filename, err := gonanoid.Nanoid()
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("could not generate avatar filename: %v", err)
|
|
||||||
}
|
|
||||||
return filename, nil
|
|
||||||
}
|
|
||||||
@ -1,8 +1,7 @@
|
|||||||
package util
|
package st
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -48,12 +47,8 @@ func RemoveHTML(str string) string {
|
|||||||
str = strings.ReplaceAll(str, "\n", "")
|
str = strings.ReplaceAll(str, "\n", "")
|
||||||
str = strings.ReplaceAll(str, " ", "")
|
str = strings.ReplaceAll(str, " ", "")
|
||||||
str = strings.ReplaceAll(str, " ", "")
|
str = strings.ReplaceAll(str, " ", "")
|
||||||
|
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func FloatToString(val float64) string {
|
|
||||||
return strconv.FormatFloat(val, 'f', 1, 64)
|
|
||||||
}
|
|
||||||
@ -24,14 +24,15 @@ func NewJWTMaker(secretKey string) (Maker, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateToken 根据用户名和时间创建一个新的token
|
// CreateToken 根据用户名和时间创建一个新的token
|
||||||
func (maker *JWTMaker) CreateToken(username string, duration time.Duration) (string, error) {
|
func (maker *JWTMaker) CreateToken(id string, username string, duration time.Duration) (string, *Payload, error) {
|
||||||
payload, err := NewPayload(username, duration)
|
payload, err := NewPayload(id, username, duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", payload, err
|
||||||
}
|
}
|
||||||
|
|
||||||
jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, payload)
|
jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, payload)
|
||||||
return jwtToken.SignedString([]byte(maker.secretKey))
|
token, err := jwtToken.SignedString([]byte(maker.secretKey))
|
||||||
|
return token, payload, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyToken checks if the token is valid or not
|
// VerifyToken checks if the token is valid or not
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import (
|
|||||||
// Maker 管理token的接口定义
|
// Maker 管理token的接口定义
|
||||||
type Maker interface {
|
type Maker interface {
|
||||||
// CreateToken 根据用户名和时间创建一个新的token
|
// CreateToken 根据用户名和时间创建一个新的token
|
||||||
CreateToken(username string, duration time.Duration) (string, error)
|
CreateToken(id string, username string, duration time.Duration) (string, *Payload, error)
|
||||||
|
|
||||||
// VerifyToken 校验token是否正确
|
// VerifyToken 校验token是否正确
|
||||||
VerifyToken(token string) (*Payload, error)
|
VerifyToken(token string) (*Payload, error)
|
||||||
|
|||||||
@ -29,13 +29,14 @@ func NewPasetoMaker(symmetricKey string) (Maker, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateToken creates a new token for a specific username and duration
|
// CreateToken creates a new token for a specific username and duration
|
||||||
func (maker *PasetoMaker) CreateToken(username string, duration time.Duration) (string, error) {
|
func (maker *PasetoMaker) CreateToken(id string, username string, duration time.Duration) (string, *Payload, error) {
|
||||||
payload, err := NewPayload(username, duration)
|
payload, err := NewPayload(id, username, duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", payload, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return maker.paseto.Encrypt(maker.symmetricKey, payload, nil)
|
token, err := maker.paseto.Encrypt(maker.symmetricKey, payload, nil)
|
||||||
|
return token, payload, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyToken checks if the token is valid or not
|
// VerifyToken checks if the token is valid or not
|
||||||
|
|||||||
@ -3,8 +3,6 @@ package token
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Different types of error returned by the VerifyToken function
|
// Different types of error returned by the VerifyToken function
|
||||||
@ -15,21 +13,16 @@ var (
|
|||||||
|
|
||||||
// Payload contains the payload data of the token
|
// Payload contains the payload data of the token
|
||||||
type Payload struct {
|
type Payload struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID string `json:"id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
IssuedAt time.Time `json:"issued_at"`
|
IssuedAt time.Time `json:"issued_at"`
|
||||||
ExpiredAt time.Time `json:"expired_at"`
|
ExpiredAt time.Time `json:"expired_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPayload creates a new token payload with a specific username and duration
|
// NewPayload creates a new token payload with a specific username and duration
|
||||||
func NewPayload(username string, duration time.Duration) (*Payload, error) {
|
func NewPayload(id string, username string, duration time.Duration) (*Payload, error) {
|
||||||
tokenID, err := uuid.NewRandom()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
payload := &Payload{
|
payload := &Payload{
|
||||||
ID: tokenID,
|
ID: id,
|
||||||
Username: username,
|
Username: username,
|
||||||
IssuedAt: time.Now(),
|
IssuedAt: time.Now(),
|
||||||
ExpiredAt: time.Now().Add(duration),
|
ExpiredAt: time.Now().Add(duration),
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
package encrypt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Md5Fun01(str string) string {
|
|
||||||
return fmt.Sprintf("%x", md5.Sum([]byte(str)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Md5Fun02(str string) string {
|
|
||||||
m := md5.New()
|
|
||||||
m.Write([]byte(str))
|
|
||||||
return hex.EncodeToString(m.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Md5Fun03(str string) string {
|
|
||||||
m := md5.New()
|
|
||||||
_, err := io.WriteString(m, str)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%x", md5.Sum(nil))
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Md5(str string) string {
|
|
||||||
return fmt.Sprintf("%x", md5.Sum([]byte(str)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func EncodeMD5(value string) string {
|
|
||||||
m := md5.New()
|
|
||||||
m.Write([]byte(value))
|
|
||||||
return hex.EncodeToString(m.Sum(nil))
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package util
|
|
||||||
|
|
||||||
// InitPageNo 初始化pageNo
|
|
||||||
func InitPageNo(pageNo int) int {
|
|
||||||
if pageNo < 1 {
|
|
||||||
pageNo = 1
|
|
||||||
}
|
|
||||||
return pageNo
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitPageSize 初始化pageSize
|
|
||||||
func InitPageSize(pageSize int) int {
|
|
||||||
if pageSize < 1 {
|
|
||||||
pageSize = 10
|
|
||||||
}
|
|
||||||
if pageSize > 20 {
|
|
||||||
pageSize = 20
|
|
||||||
}
|
|
||||||
return pageSize
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HashPassword returns the bcrypt hash of the password
|
|
||||||
func HashPassword(password string) (string, error) {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to hash password: %w", err)
|
|
||||||
}
|
|
||||||
return string(hashedPassword), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckPassword checks if the provided password is correct or not
|
|
||||||
func CheckPassword(password string, hashedPassword string) error {
|
|
||||||
return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
|
||||||
}
|
|
||||||
21
pkg/validator/phone.go
Normal file
21
pkg/validator/phone.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
rxPhone = regexp.MustCompile(`^(13|14|15|16|17|18|19)\d{9}$`)
|
||||||
|
ErrPhoneFormat = errors.New("phone format error")
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidateRxPhone(phone string) error {
|
||||||
|
phone = strings.TrimSpace(phone)
|
||||||
|
if !rxPhone.MatchString(phone) {
|
||||||
|
return ErrPhoneFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user