Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84483dce61 | ||
|
|
a4eb7a47f3 | ||
|
|
20c84d7fe5 | ||
|
|
9d5acd2b36 | ||
|
|
7508f6b92b | ||
|
|
379030fe71 | ||
|
|
10027eea20 | ||
|
|
69f25a176b | ||
|
|
ac19f06b6c | ||
|
|
87a81f59c7 | ||
|
|
7389e5e54b | ||
|
|
e6792b8188 | ||
|
|
a037546cfa | ||
|
|
8efaacf1ef | ||
|
|
a38dd1cef8 | ||
|
|
77521112d0 | ||
|
|
4f9a5d238c | ||
|
|
d5fb39ed50 | ||
|
|
58a84083ae | ||
|
|
9f564a4739 | ||
|
|
c20accbf58 | ||
|
|
3f21b3148e | ||
|
|
74e909a501 | ||
|
|
4150ee1b47 | ||
|
|
df04de2151 | ||
|
|
4dc5d9aa7e | ||
|
|
0ef7e6ccd8 | ||
|
|
ed2b831e5a | ||
|
|
5d392ecd43 | ||
|
|
ea147d7506 | ||
|
|
b45136c2c8 | ||
|
|
530e1513ec | ||
|
|
6c60677b72 | ||
|
|
a1bec5e578 | ||
|
|
9dece058d9 | ||
|
|
89df6ae6bf | ||
|
|
85b6e6428c | ||
|
|
0df204a1df |
@@ -52,7 +52,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
unzip := helpers.NewUnzip(zipPath, targetPath)
|
var unzip = helpers.NewUnzip(zipPath, targetPath)
|
||||||
err := unzip.Run()
|
err := unzip.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stderr("ERROR: " + err.Error())
|
stderr("ERROR: " + err.Error())
|
||||||
|
|||||||
6
go.mod
6
go.mod
@@ -10,10 +10,11 @@ require (
|
|||||||
github.com/andybalholm/brotli v1.0.4
|
github.com/andybalholm/brotli v1.0.4
|
||||||
github.com/cespare/xxhash v1.1.0
|
github.com/cespare/xxhash v1.1.0
|
||||||
github.com/cespare/xxhash/v2 v2.1.1
|
github.com/cespare/xxhash/v2 v2.1.1
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
github.com/go-acme/lego/v4 v4.10.2
|
github.com/go-acme/lego/v4 v4.10.2
|
||||||
github.com/go-sql-driver/mysql v1.7.0
|
github.com/go-sql-driver/mysql v1.7.0
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||||
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470
|
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b
|
||||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
|
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
|
||||||
github.com/miekg/dns v1.1.50
|
github.com/miekg/dns v1.1.50
|
||||||
github.com/mozillazg/go-pinyin v0.18.0
|
github.com/mozillazg/go-pinyin v0.18.0
|
||||||
@@ -29,7 +30,6 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
@@ -41,6 +41,8 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||||
github.com/smartwalle/crypto4go v1.0.2 // indirect
|
github.com/smartwalle/crypto4go v1.0.2 // indirect
|
||||||
|
github.com/tdewolff/minify/v2 v2.12.7 // indirect
|
||||||
|
github.com/tdewolff/parse/v2 v2.6.6 // indirect
|
||||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
||||||
github.com/tklauser/numcpus v0.3.0 // indirect
|
github.com/tklauser/numcpus v0.3.0 // indirect
|
||||||
|
|||||||
19
go.sum
19
go.sum
@@ -19,6 +19,7 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
|||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
@@ -30,6 +31,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
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/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
@@ -81,8 +84,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
||||||
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470 h1:TuRxvKRv9PxKVijWOkUnZm5TeanQqWGUJyPx9u6cra4=
|
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b h1:yYUaxnc04uzfr7C9HBN52ZZvcQomND+C5aZTpjOUYFI=
|
||||||
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
|
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
|
||||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo=
|
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo=
|
||||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
|
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
@@ -98,10 +101,11 @@ github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
|||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
|
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@@ -142,12 +146,20 @@ github.com/smartwalle/crypto4go v1.0.2 h1:9DUEOOsPhmp00438L4oBdcL8EZG1zumecft5bW
|
|||||||
github.com/smartwalle/crypto4go v1.0.2/go.mod h1:LQ7vCZIb7BE5+MuMtJBuO8ORkkQ01m4DXDBWPzLbkMY=
|
github.com/smartwalle/crypto4go v1.0.2/go.mod h1:LQ7vCZIb7BE5+MuMtJBuO8ORkkQ01m4DXDBWPzLbkMY=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
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.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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
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/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
|
github.com/tdewolff/minify/v2 v2.12.7 h1:pBzz2tAfz5VghOXiQIsSta6srhmTeinQPjRDHWoumCA=
|
||||||
|
github.com/tdewolff/minify/v2 v2.12.7/go.mod h1:ZRKTheiOGyLSK8hOZWWv+YoJAECzDivNgAlVYDHp/Ws=
|
||||||
|
github.com/tdewolff/parse/v2 v2.6.6 h1:Yld+0CrKUJaCV78DL1G2nk3C9lKrxyRTux5aaK/AkDo=
|
||||||
|
github.com/tdewolff/parse/v2 v2.6.6/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
|
||||||
|
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
|
github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0=
|
||||||
|
github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||||
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
|
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
|
||||||
@@ -225,7 +237,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.2.0"
|
Version = "1.2.2"
|
||||||
|
|
||||||
ProductName = "Edge API"
|
ProductName = "Edge API"
|
||||||
ProcessName = "edge-api"
|
ProcessName = "edge-api"
|
||||||
@@ -18,7 +18,7 @@ const (
|
|||||||
|
|
||||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||||
|
|
||||||
NodeVersion = "1.2.0"
|
NodeVersion = "1.2.2"
|
||||||
|
|
||||||
// SQLVersion SQL版本号
|
// SQLVersion SQL版本号
|
||||||
SQLVersion = "11"
|
SQLVersion = "11"
|
||||||
|
|||||||
@@ -2,6 +2,22 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
AdminField_Id dbs.FieldName = "id" // ID
|
||||||
|
AdminField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
AdminField_Username dbs.FieldName = "username" // 用户名
|
||||||
|
AdminField_Password dbs.FieldName = "password" // 密码
|
||||||
|
AdminField_Fullname dbs.FieldName = "fullname" // 全名
|
||||||
|
AdminField_IsSuper dbs.FieldName = "isSuper" // 是否为超级管理员
|
||||||
|
AdminField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
AdminField_UpdatedAt dbs.FieldName = "updatedAt" // 修改时间
|
||||||
|
AdminField_State dbs.FieldName = "state" // 状态
|
||||||
|
AdminField_Modules dbs.FieldName = "modules" // 允许的模块
|
||||||
|
AdminField_CanLogin dbs.FieldName = "canLogin" // 是否可以登录
|
||||||
|
AdminField_Theme dbs.FieldName = "theme" // 模板设置
|
||||||
|
AdminField_Lang dbs.FieldName = "lang" // 语言代号
|
||||||
|
)
|
||||||
|
|
||||||
// Admin 管理员
|
// Admin 管理员
|
||||||
type Admin struct {
|
type Admin struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -16,6 +32,7 @@ type Admin struct {
|
|||||||
Modules dbs.JSON `field:"modules"` // 允许的模块
|
Modules dbs.JSON `field:"modules"` // 允许的模块
|
||||||
CanLogin bool `field:"canLogin"` // 是否可以登录
|
CanLogin bool `field:"canLogin"` // 是否可以登录
|
||||||
Theme string `field:"theme"` // 模板设置
|
Theme string `field:"theme"` // 模板设置
|
||||||
|
Lang string `field:"lang"` // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
type AdminOperator struct {
|
type AdminOperator struct {
|
||||||
@@ -31,6 +48,7 @@ type AdminOperator struct {
|
|||||||
Modules any // 允许的模块
|
Modules any // 允许的模块
|
||||||
CanLogin any // 是否可以登录
|
CanLogin any // 是否可以登录
|
||||||
Theme any // 模板设置
|
Theme any // 模板设置
|
||||||
|
Lang any // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAdminOperator() *AdminOperator {
|
func NewAdminOperator() *AdminOperator {
|
||||||
|
|||||||
@@ -155,6 +155,12 @@ func (this *DNSTaskDAO) DeleteDNSTask(tx *dbs.Tx, taskId int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllDNSTasks 删除所有任务
|
||||||
|
func (this *DNSTaskDAO) DeleteAllDNSTasks(tx *dbs.Tx) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
DeleteQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateDNSTaskError 设置任务错误
|
// UpdateDNSTaskError 设置任务错误
|
||||||
func (this *DNSTaskDAO) UpdateDNSTaskError(tx *dbs.Tx, taskId int64, err string) error {
|
func (this *DNSTaskDAO) UpdateDNSTaskError(tx *dbs.Tx, taskId int64, err string) error {
|
||||||
if taskId <= 0 {
|
if taskId <= 0 {
|
||||||
@@ -195,6 +201,27 @@ func (this *DNSTaskDAO) UpdateDNSTaskDone(tx *dbs.Tx, taskId int64, taskVersion
|
|||||||
return this.Save(tx, op)
|
return this.Save(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateVersion 生成最新的版本号
|
||||||
|
func (this *DNSTaskDAO) GenerateVersion() int64 {
|
||||||
|
return time.Now().UnixNano()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateClusterDNSTasksDone 设置所有集群任务完成
|
||||||
|
func (this *DNSTaskDAO) UpdateClusterDNSTasksDone(tx *dbs.Tx, clusterId int64, maxVersion int64) error {
|
||||||
|
if clusterId <= 0 || maxVersion <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("clusterId", clusterId).
|
||||||
|
Attr("isOk", false).
|
||||||
|
Lte("version", maxVersion).
|
||||||
|
Set("isDone", true).
|
||||||
|
Set("isOk", true).
|
||||||
|
Set("error", "").
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteDNSTasksWithClusterId 删除集群相关任务
|
// DeleteDNSTasksWithClusterId 删除集群相关任务
|
||||||
func (this *DNSTaskDAO) DeleteDNSTasksWithClusterId(tx *dbs.Tx, clusterId int64) error {
|
func (this *DNSTaskDAO) DeleteDNSTasksWithClusterId(tx *dbs.Tx, clusterId int64) error {
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
package dns
|
package dns_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDNSTaskDAO_CreateDNSTask(t *testing.T) {
|
func TestDNSTaskDAO_CreateDNSTask(t *testing.T) {
|
||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
err := SharedDNSTaskDAO.CreateDNSTask(nil, 1, 2, 3, 0, "cdn", "taskType")
|
err := dns.SharedDNSTaskDAO.CreateDNSTask(nil, 1, 2, 3, 0, "cdn", "taskType")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDNSTaskDAO_UpdateClusterDNSTasksDone(t *testing.T) {
|
||||||
|
var dao = dns.NewDNSTaskDAO()
|
||||||
|
var tx *dbs.Tx
|
||||||
|
err := dao.UpdateClusterDNSTasksDone(tx, 46, time.Now().UnixNano())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ func (this *HTTPCachePolicyDAO) FindAllEnabledCachePolicies(tx *dbs.Tx) (result
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateCachePolicy 创建缓存策略
|
// CreateCachePolicy 创建缓存策略
|
||||||
func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name string, description string, capacityJSON []byte, maxKeys int64, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) (int64, error) {
|
func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name string, description string, capacityJSON []byte, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) (int64, error) {
|
||||||
var op = NewHTTPCachePolicyOperator()
|
var op = NewHTTPCachePolicyOperator()
|
||||||
op.State = HTTPCachePolicyStateEnabled
|
op.State = HTTPCachePolicyStateEnabled
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
@@ -105,7 +105,6 @@ func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name st
|
|||||||
if len(capacityJSON) > 0 {
|
if len(capacityJSON) > 0 {
|
||||||
op.Capacity = capacityJSON
|
op.Capacity = capacityJSON
|
||||||
}
|
}
|
||||||
op.MaxKeys = maxKeys
|
|
||||||
if len(maxSizeJSON) > 0 {
|
if len(maxSizeJSON) > 0 {
|
||||||
op.MaxSize = maxSizeJSON
|
op.MaxSize = maxSizeJSON
|
||||||
}
|
}
|
||||||
@@ -184,7 +183,7 @@ func (this *HTTPCachePolicyDAO) CreateDefaultCachePolicy(tx *dbs.Tx, name string
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
policyId, err := this.CreateCachePolicy(tx, true, "\""+name+"\"缓存策略", "默认创建的缓存策略", capacityJSON, 0, maxSizeJSON, serverconfigs.CachePolicyStorageFile, storageOptionsJSON, false)
|
policyId, err := this.CreateCachePolicy(tx, true, "\""+name+"\"缓存策略", "默认创建的缓存策略", capacityJSON, maxSizeJSON, serverconfigs.CachePolicyStorageFile, storageOptionsJSON, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -192,7 +191,7 @@ func (this *HTTPCachePolicyDAO) CreateDefaultCachePolicy(tx *dbs.Tx, name string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCachePolicy 修改缓存策略
|
// UpdateCachePolicy 修改缓存策略
|
||||||
func (this *HTTPCachePolicyDAO) UpdateCachePolicy(tx *dbs.Tx, policyId int64, isOn bool, name string, description string, capacityJSON []byte, maxKeys int64, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) error {
|
func (this *HTTPCachePolicyDAO) UpdateCachePolicy(tx *dbs.Tx, policyId int64, isOn bool, name string, description string, capacityJSON []byte, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) error {
|
||||||
if policyId <= 0 {
|
if policyId <= 0 {
|
||||||
return errors.New("invalid policyId")
|
return errors.New("invalid policyId")
|
||||||
}
|
}
|
||||||
@@ -205,7 +204,6 @@ func (this *HTTPCachePolicyDAO) UpdateCachePolicy(tx *dbs.Tx, policyId int64, is
|
|||||||
if len(capacityJSON) > 0 {
|
if len(capacityJSON) > 0 {
|
||||||
op.Capacity = capacityJSON
|
op.Capacity = capacityJSON
|
||||||
}
|
}
|
||||||
op.MaxKeys = maxKeys
|
|
||||||
if len(maxSizeJSON) > 0 {
|
if len(maxSizeJSON) > 0 {
|
||||||
op.MaxSize = maxSizeJSON
|
op.MaxSize = maxSizeJSON
|
||||||
}
|
}
|
||||||
@@ -256,8 +254,6 @@ func (this *HTTPCachePolicyDAO) ComposeCachePolicy(tx *dbs.Tx, policyId int64, c
|
|||||||
config.Capacity = capacityConfig
|
config.Capacity = capacityConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
config.MaxKeys = types.Int64(policy.MaxKeys)
|
|
||||||
|
|
||||||
// max size
|
// max size
|
||||||
if IsNotNull(policy.MaxSize) {
|
if IsNotNull(policy.MaxSize) {
|
||||||
maxSizeConfig := &shared.SizeCapacity{}
|
maxSizeConfig := &shared.SizeCapacity{}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedHTTPCacheTaskDAO.Clean(nil, 30) // 只保留N天
|
err := SharedHTTPCacheTaskDAO.CleanDefaultDays(nil, 30) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("HTTPCacheTaskDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("HTTPCacheTaskDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -228,8 +228,8 @@ func (this *HTTPCacheTaskDAO) CheckUserTask(tx *dbs.Tx, userId int64, taskId int
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理以往的任务
|
// CleanDays 清理N天以前的任务
|
||||||
func (this *HTTPCacheTaskDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *HTTPCacheTaskDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
if days <= 0 {
|
if days <= 0 {
|
||||||
days = 30
|
days = 30
|
||||||
}
|
}
|
||||||
@@ -248,6 +248,23 @@ func (this *HTTPCacheTaskDAO) Clean(tx *dbs.Tx, days int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CleanDefaultDays 清除任务
|
||||||
|
func (this *HTTPCacheTaskDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.HTTPCacheTask.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.HTTPCacheTask.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyChange 发送通知
|
// NotifyChange 发送通知
|
||||||
func (this *HTTPCacheTaskDAO) NotifyChange(tx *dbs.Tx, taskId int64) error {
|
func (this *HTTPCacheTaskDAO) NotifyChange(tx *dbs.Tx, taskId int64) error {
|
||||||
// TODO
|
// TODO
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
func TestHTTPCacheTaskDAO_Clean(t *testing.T) {
|
func TestHTTPCacheTaskDAO_Clean(t *testing.T) {
|
||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
|
|
||||||
err := models.SharedHTTPCacheTaskDAO.Clean(nil, 30)
|
err := models.SharedHTTPCacheTaskDAO.CleanDays(nil, 30)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,8 +124,9 @@ func (this *HTTPRewriteRuleDAO) ComposeRewriteRule(tx *dbs.Tx, rewriteRuleId int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateRewriteRule 创建规则
|
// CreateRewriteRule 创建规则
|
||||||
func (this *HTTPRewriteRuleDAO) CreateRewriteRule(tx *dbs.Tx, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool, condsJSON []byte) (int64, error) {
|
func (this *HTTPRewriteRuleDAO) CreateRewriteRule(tx *dbs.Tx, userId int64, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool, condsJSON []byte) (int64, error) {
|
||||||
var op = NewHTTPRewriteRuleOperator()
|
var op = NewHTTPRewriteRuleOperator()
|
||||||
|
op.UserId = userId
|
||||||
op.State = HTTPRewriteRuleStateEnabled
|
op.State = HTTPRewriteRuleStateEnabled
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
|
|
||||||
@@ -172,6 +173,34 @@ func (this *HTTPRewriteRuleDAO) UpdateRewriteRule(tx *dbs.Tx, rewriteRuleId int6
|
|||||||
return this.NotifyUpdate(tx, rewriteRuleId)
|
return this.NotifyUpdate(tx, rewriteRuleId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *HTTPRewriteRuleDAO) CheckUserRewriteRule(tx *dbs.Tx, userId int64, rewriteRuleId int64) error {
|
||||||
|
if rewriteRuleId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := this.Query(tx).
|
||||||
|
Pk(rewriteRuleId).
|
||||||
|
Attr("userId", userId).
|
||||||
|
Exist()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithRewriteRuleId(tx, rewriteRuleId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if webId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return SharedHTTPWebDAO.CheckUserWeb(tx, userId, webId)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *HTTPRewriteRuleDAO) NotifyUpdate(tx *dbs.Tx, rewriteRuleId int64) error {
|
func (this *HTTPRewriteRuleDAO) NotifyUpdate(tx *dbs.Tx, rewriteRuleId int64) error {
|
||||||
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithRewriteRuleId(tx, rewriteRuleId)
|
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithRewriteRuleId(tx, rewriteRuleId)
|
||||||
|
|||||||
@@ -151,6 +151,18 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, isLocationOrGr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optimization
|
||||||
|
if IsNotNull(web.Optimization) {
|
||||||
|
var optimizationConfig = serverconfigs.NewHTTPPageOptimizationConfig()
|
||||||
|
err = json.Unmarshal(web.Optimization, optimizationConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if this.shouldCompose(isLocationOrGroup, forNode, optimizationConfig.IsPrior, true) {
|
||||||
|
config.Optimization = optimizationConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// charset
|
// charset
|
||||||
if IsNotNull(web.Charset) {
|
if IsNotNull(web.Charset) {
|
||||||
var charsetConfig = &serverconfigs.HTTPCharsetConfig{}
|
var charsetConfig = &serverconfigs.HTTPCharsetConfig{}
|
||||||
@@ -550,7 +562,20 @@ func (this *HTTPWebDAO) CreateWeb(tx *dbs.Tx, adminId int64, userId int64, rootJ
|
|||||||
if len(rootJSON) > 0 {
|
if len(rootJSON) > 0 {
|
||||||
op.Root = JSONBytes(rootJSON)
|
op.Root = JSONBytes(rootJSON)
|
||||||
}
|
}
|
||||||
err := this.Save(tx, op)
|
|
||||||
|
// 设置默认的remote-addr
|
||||||
|
// set default remote-addr config
|
||||||
|
var remoteAddrConfig = &serverconfigs.HTTPRemoteAddrConfig{
|
||||||
|
IsOn: true,
|
||||||
|
Value: "${rawRemoteAddr}",
|
||||||
|
}
|
||||||
|
remoteAddrConfigJSON, err := json.Marshal(remoteAddrConfig)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.RemoteAddr = remoteAddrConfigJSON
|
||||||
|
|
||||||
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -574,14 +599,42 @@ func (this *HTTPWebDAO) UpdateWeb(tx *dbs.Tx, webId int64, rootJSON []byte) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateWebCompression 修改压缩配置
|
// UpdateWebCompression 修改压缩配置
|
||||||
func (this *HTTPWebDAO) UpdateWebCompression(tx *dbs.Tx, webId int64, compressionConfig []byte) error {
|
func (this *HTTPWebDAO) UpdateWebCompression(tx *dbs.Tx, webId int64, compressionConfig *serverconfigs.HTTPCompressionConfig) error {
|
||||||
if webId <= 0 {
|
if webId <= 0 {
|
||||||
return errors.New("invalid webId")
|
return errors.New("invalid webId")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compressionJSON, err := json.Marshal(compressionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var op = NewHTTPWebOperator()
|
var op = NewHTTPWebOperator()
|
||||||
op.Id = webId
|
op.Id = webId
|
||||||
op.Compression = JSONBytes(compressionConfig)
|
op.Compression = compressionJSON
|
||||||
err := this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyUpdate(tx, webId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateWebOptimization 修改页面优化配置
|
||||||
|
func (this *HTTPWebDAO) UpdateWebOptimization(tx *dbs.Tx, webId int64, optimizationConfig *serverconfigs.HTTPPageOptimizationConfig) error {
|
||||||
|
if webId <= 0 {
|
||||||
|
return errors.New("invalid webId")
|
||||||
|
}
|
||||||
|
|
||||||
|
optimizationJSON, err := json.Marshal(optimizationConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var op = NewHTTPWebOperator()
|
||||||
|
op.Id = webId
|
||||||
|
op.Optimization = optimizationJSON
|
||||||
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,47 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTPWebField_Id dbs.FieldName = "id" // ID
|
||||||
|
HTTPWebField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
HTTPWebField_TemplateId dbs.FieldName = "templateId" // 模版ID
|
||||||
|
HTTPWebField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
HTTPWebField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
HTTPWebField_State dbs.FieldName = "state" // 状态
|
||||||
|
HTTPWebField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
HTTPWebField_Root dbs.FieldName = "root" // 根目录
|
||||||
|
HTTPWebField_Charset dbs.FieldName = "charset" // 字符集
|
||||||
|
HTTPWebField_Shutdown dbs.FieldName = "shutdown" // 临时关闭页面配置
|
||||||
|
HTTPWebField_Pages dbs.FieldName = "pages" // 特殊页面
|
||||||
|
HTTPWebField_RedirectToHttps dbs.FieldName = "redirectToHttps" // 跳转到HTTPS设置
|
||||||
|
HTTPWebField_Indexes dbs.FieldName = "indexes" // 首页文件列表
|
||||||
|
HTTPWebField_MaxRequestBodySize dbs.FieldName = "maxRequestBodySize" // 最大允许的请求内容尺寸
|
||||||
|
HTTPWebField_RequestHeader dbs.FieldName = "requestHeader" // 请求Header配置
|
||||||
|
HTTPWebField_ResponseHeader dbs.FieldName = "responseHeader" // 响应Header配置
|
||||||
|
HTTPWebField_AccessLog dbs.FieldName = "accessLog" // 访问日志配置
|
||||||
|
HTTPWebField_Stat dbs.FieldName = "stat" // 统计配置
|
||||||
|
HTTPWebField_Gzip dbs.FieldName = "gzip" // Gzip配置(v0.3.2弃用)
|
||||||
|
HTTPWebField_Compression dbs.FieldName = "compression" // 压缩配置
|
||||||
|
HTTPWebField_Cache dbs.FieldName = "cache" // 缓存配置
|
||||||
|
HTTPWebField_Firewall dbs.FieldName = "firewall" // 防火墙设置
|
||||||
|
HTTPWebField_Locations dbs.FieldName = "locations" // 路由规则配置
|
||||||
|
HTTPWebField_Websocket dbs.FieldName = "websocket" // Websocket设置
|
||||||
|
HTTPWebField_RewriteRules dbs.FieldName = "rewriteRules" // 重写规则配置
|
||||||
|
HTTPWebField_HostRedirects dbs.FieldName = "hostRedirects" // 域名跳转
|
||||||
|
HTTPWebField_Fastcgi dbs.FieldName = "fastcgi" // Fastcgi配置
|
||||||
|
HTTPWebField_Auth dbs.FieldName = "auth" // 认证策略配置
|
||||||
|
HTTPWebField_Webp dbs.FieldName = "webp" // WebP配置
|
||||||
|
HTTPWebField_RemoteAddr dbs.FieldName = "remoteAddr" // 客户端IP配置
|
||||||
|
HTTPWebField_MergeSlashes dbs.FieldName = "mergeSlashes" // 是否合并路径中的斜杠
|
||||||
|
HTTPWebField_RequestLimit dbs.FieldName = "requestLimit" // 请求限制
|
||||||
|
HTTPWebField_RequestScripts dbs.FieldName = "requestScripts" // 请求脚本
|
||||||
|
HTTPWebField_Uam dbs.FieldName = "uam" // UAM设置
|
||||||
|
HTTPWebField_Cc dbs.FieldName = "cc" // CC设置
|
||||||
|
HTTPWebField_Referers dbs.FieldName = "referers" // 防盗链设置
|
||||||
|
HTTPWebField_UserAgent dbs.FieldName = "userAgent" // UserAgent设置
|
||||||
|
HTTPWebField_Optimization dbs.FieldName = "optimization" // 页面优化配置
|
||||||
|
)
|
||||||
|
|
||||||
// HTTPWeb HTTP Web
|
// HTTPWeb HTTP Web
|
||||||
type HTTPWeb struct {
|
type HTTPWeb struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -41,6 +82,7 @@ type HTTPWeb struct {
|
|||||||
Cc dbs.JSON `field:"cc"` // CC设置
|
Cc dbs.JSON `field:"cc"` // CC设置
|
||||||
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
||||||
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
||||||
|
Optimization dbs.JSON `field:"optimization"` // 页面优化配置
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPWebOperator struct {
|
type HTTPWebOperator struct {
|
||||||
@@ -81,6 +123,7 @@ type HTTPWebOperator struct {
|
|||||||
Cc any // CC设置
|
Cc any // CC设置
|
||||||
Referers any // 防盗链设置
|
Referers any // 防盗链设置
|
||||||
UserAgent any // UserAgent设置
|
UserAgent any // UserAgent设置
|
||||||
|
Optimization any // 页面优化配置
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPWebOperator() *HTTPWebOperator {
|
func NewHTTPWebOperator() *HTTPWebOperator {
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var countries = []*iplibrary.Country{}
|
var countries = []*iplibrary.Country{}
|
||||||
for _, country := range dbCountries {
|
for _, country := range dbCountries {
|
||||||
countries = append(countries, &iplibrary.Country{
|
countries = append(countries, &iplibrary.Country{
|
||||||
Id: types.Uint16(country.Id),
|
Id: types.Uint16(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
Codes: country.AllCodes(),
|
Codes: country.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -354,7 +354,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var provinces = []*iplibrary.Province{}
|
var provinces = []*iplibrary.Province{}
|
||||||
for _, province := range dbProvinces {
|
for _, province := range dbProvinces {
|
||||||
provinces = append(provinces, &iplibrary.Province{
|
provinces = append(provinces, &iplibrary.Province{
|
||||||
Id: types.Uint16(province.Id),
|
Id: types.Uint16(province.ValueId),
|
||||||
Name: province.DisplayName(),
|
Name: province.DisplayName(),
|
||||||
Codes: province.AllCodes(),
|
Codes: province.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -369,7 +369,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var cities = []*iplibrary.City{}
|
var cities = []*iplibrary.City{}
|
||||||
for _, city := range dbCities {
|
for _, city := range dbCities {
|
||||||
cities = append(cities, &iplibrary.City{
|
cities = append(cities, &iplibrary.City{
|
||||||
Id: city.Id,
|
Id: city.ValueId,
|
||||||
Name: city.DisplayName(),
|
Name: city.DisplayName(),
|
||||||
Codes: city.AllCodes(),
|
Codes: city.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -384,7 +384,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var towns = []*iplibrary.Town{}
|
var towns = []*iplibrary.Town{}
|
||||||
for _, town := range dbTowns {
|
for _, town := range dbTowns {
|
||||||
towns = append(towns, &iplibrary.Town{
|
towns = append(towns, &iplibrary.Town{
|
||||||
Id: town.Id,
|
Id: town.ValueId,
|
||||||
Name: town.DisplayName(),
|
Name: town.DisplayName(),
|
||||||
Codes: town.AllCodes(),
|
Codes: town.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -399,7 +399,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var providers = []*iplibrary.Provider{}
|
var providers = []*iplibrary.Provider{}
|
||||||
for _, provider := range dbProviders {
|
for _, provider := range dbProviders {
|
||||||
providers = append(providers, &iplibrary.Provider{
|
providers = append(providers, &iplibrary.Provider{
|
||||||
Id: types.Uint16(provider.Id),
|
Id: types.Uint16(provider.ValueId),
|
||||||
Name: provider.DisplayName(),
|
Name: provider.DisplayName(),
|
||||||
Codes: provider.AllCodes(),
|
Codes: provider.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -440,35 +440,35 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var countryMap = map[string]int64{} // countryName => countryId
|
var countryMap = map[string]int64{} // countryName => countryId
|
||||||
for _, country := range dbCountries {
|
for _, country := range dbCountries {
|
||||||
for _, code := range country.AllCodes() {
|
for _, code := range country.AllCodes() {
|
||||||
countryMap[code] = int64(country.Id)
|
countryMap[code] = int64(country.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var provinceMap = map[string]int64{} // countryId_provinceName => provinceId
|
var provinceMap = map[string]int64{} // countryId_provinceName => provinceId
|
||||||
for _, province := range dbProvinces {
|
for _, province := range dbProvinces {
|
||||||
for _, code := range province.AllCodes() {
|
for _, code := range province.AllCodes() {
|
||||||
provinceMap[types.String(province.CountryId)+"_"+code] = int64(province.Id)
|
provinceMap[types.String(province.CountryId)+"_"+code] = int64(province.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cityMap = map[string]int64{} // provinceId_cityName => cityId
|
var cityMap = map[string]int64{} // provinceId_cityName => cityId
|
||||||
for _, city := range dbCities {
|
for _, city := range dbCities {
|
||||||
for _, code := range city.AllCodes() {
|
for _, code := range city.AllCodes() {
|
||||||
cityMap[types.String(city.ProvinceId)+"_"+code] = int64(city.Id)
|
cityMap[types.String(city.ProvinceId)+"_"+code] = int64(city.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var townMap = map[string]int64{} // cityId_townName => townId
|
var townMap = map[string]int64{} // cityId_townName => townId
|
||||||
for _, town := range dbTowns {
|
for _, town := range dbTowns {
|
||||||
for _, code := range town.AllCodes() {
|
for _, code := range town.AllCodes() {
|
||||||
townMap[types.String(town.CityId)+"_"+code] = int64(town.Id)
|
townMap[types.String(town.CityId)+"_"+code] = int64(town.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var providerMap = map[string]int64{} // providerName => providerId
|
var providerMap = map[string]int64{} // providerName => providerId
|
||||||
for _, provider := range dbProviders {
|
for _, provider := range dbProviders {
|
||||||
for _, code := range provider.AllCodes() {
|
for _, code := range provider.AllCodes() {
|
||||||
providerMap[code] = int64(provider.Id)
|
providerMap[code] = int64(provider.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -36,7 +38,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateLog 创建管理员日志
|
// CreateLog 创建管理员日志
|
||||||
func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level string, description string, action string, ip string) error {
|
func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level string, description string, action string, ip string, langMessageCode langs.MessageCode, langMessageArgs []any) error {
|
||||||
var op = NewLogOperator()
|
var op = NewLogOperator()
|
||||||
op.Level = level
|
op.Level = level
|
||||||
op.Description = utils.LimitString(description, 1000)
|
op.Description = utils.LimitString(description, 1000)
|
||||||
@@ -53,6 +55,16 @@ func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level
|
|||||||
op.ProviderId = adminId
|
op.ProviderId = adminId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// i18n
|
||||||
|
op.LangMessageCode = langMessageCode
|
||||||
|
if len(langMessageArgs) > 0 {
|
||||||
|
langMessageArgsJSON, err := json.Marshal(langMessageArgs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.LangMessageArgs = langMessageArgsJSON
|
||||||
|
}
|
||||||
|
|
||||||
op.Day = timeutil.Format("Ymd")
|
op.Day = timeutil.Format("Ymd")
|
||||||
op.Type = LogTypeAdmin
|
op.Type = LogTypeAdmin
|
||||||
err := this.Save(tx, op)
|
err := this.Save(tx, op)
|
||||||
|
|||||||
@@ -1,34 +1,60 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
// 操作日志
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
LogField_Id dbs.FieldName = "id" // ID
|
||||||
|
LogField_Level dbs.FieldName = "level" // 级别
|
||||||
|
LogField_Description dbs.FieldName = "description" // 描述
|
||||||
|
LogField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
LogField_Action dbs.FieldName = "action" // 动作
|
||||||
|
LogField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
LogField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
LogField_ProviderId dbs.FieldName = "providerId" // 供应商ID
|
||||||
|
LogField_Ip dbs.FieldName = "ip" // IP地址
|
||||||
|
LogField_Type dbs.FieldName = "type" // 类型:admin, user
|
||||||
|
LogField_Day dbs.FieldName = "day" // 日期
|
||||||
|
LogField_BillId dbs.FieldName = "billId" // 账单ID
|
||||||
|
LogField_LangMessageCode dbs.FieldName = "langMessageCode" // 多语言消息代号
|
||||||
|
LogField_LangMessageArgs dbs.FieldName = "langMessageArgs" // 多语言参数
|
||||||
|
LogField_Params dbs.FieldName = "params" // 关联对象参数
|
||||||
|
)
|
||||||
|
|
||||||
|
// Log 操作日志
|
||||||
type Log struct {
|
type Log struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
Level string `field:"level"` // 级别
|
Level string `field:"level"` // 级别
|
||||||
Description string `field:"description"` // 描述
|
Description string `field:"description"` // 描述
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
Action string `field:"action"` // 动作
|
Action string `field:"action"` // 动作
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
ProviderId uint32 `field:"providerId"` // 供应商ID
|
ProviderId uint32 `field:"providerId"` // 供应商ID
|
||||||
Ip string `field:"ip"` // IP地址
|
Ip string `field:"ip"` // IP地址
|
||||||
Type string `field:"type"` // 类型:admin, user
|
Type string `field:"type"` // 类型:admin, user
|
||||||
Day string `field:"day"` // 日期
|
Day string `field:"day"` // 日期
|
||||||
BillId uint32 `field:"billId"` // 账单ID
|
BillId uint32 `field:"billId"` // 账单ID
|
||||||
|
LangMessageCode string `field:"langMessageCode"` // 多语言消息代号
|
||||||
|
LangMessageArgs dbs.JSON `field:"langMessageArgs"` // 多语言参数
|
||||||
|
Params dbs.JSON `field:"params"` // 关联对象参数
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogOperator struct {
|
type LogOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Level interface{} // 级别
|
Level any // 级别
|
||||||
Description interface{} // 描述
|
Description any // 描述
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt any // 创建时间
|
||||||
Action interface{} // 动作
|
Action any // 动作
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
ProviderId interface{} // 供应商ID
|
ProviderId any // 供应商ID
|
||||||
Ip interface{} // IP地址
|
Ip any // IP地址
|
||||||
Type interface{} // 类型:admin, user
|
Type any // 类型:admin, user
|
||||||
Day interface{} // 日期
|
Day any // 日期
|
||||||
BillId interface{} // 账单ID
|
BillId any // 账单ID
|
||||||
|
LangMessageCode any // 多语言消息代号
|
||||||
|
LangMessageArgs any // 多语言参数
|
||||||
|
Params any // 关联对象参数
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLogOperator() *LogOperator {
|
func NewLogOperator() *LogOperator {
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ func (this *NodeClusterDAO) FindNodeClusterName(tx *dbs.Tx, clusterId int64) (st
|
|||||||
// FindAllEnableClusters 查找所有可用的集群
|
// FindAllEnableClusters 查找所有可用的集群
|
||||||
func (this *NodeClusterDAO) FindAllEnableClusters(tx *dbs.Tx) (result []*NodeCluster, err error) {
|
func (this *NodeClusterDAO) FindAllEnableClusters(tx *dbs.Tx) (result []*NodeCluster, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
|
Result(NodeClusterField_Id, NodeClusterField_Name, NodeClusterField_IsOn, NodeClusterField_HealthCheck, NodeClusterField_AutoRemoteStart, NodeClusterField_AutoRegister, NodeClusterField_CreatedAt, NodeClusterField_UniqueId, NodeClusterField_Secret).
|
||||||
State(NodeClusterStateEnabled).
|
State(NodeClusterStateEnabled).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
Desc("isPinned").
|
Desc("isPinned").
|
||||||
@@ -175,7 +176,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
|||||||
|
|
||||||
// 全局服务配置
|
// 全局服务配置
|
||||||
if globalServerConfig == nil {
|
if globalServerConfig == nil {
|
||||||
globalServerConfig = serverconfigs.DefaultGlobalServerConfig()
|
globalServerConfig = serverconfigs.NewGlobalServerConfig()
|
||||||
}
|
}
|
||||||
globalServerConfigJSON, err := json.Marshal(globalServerConfig)
|
globalServerConfigJSON, err := json.Marshal(globalServerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -262,19 +263,40 @@ func (this *NodeClusterDAO) CountAllEnabledClusters(tx *dbs.Tx, keyword string)
|
|||||||
|
|
||||||
// ListEnabledClusters 列出单页集群
|
// ListEnabledClusters 列出单页集群
|
||||||
func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, offset, size int64) (result []*NodeCluster, err error) {
|
func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, offset, size int64) (result []*NodeCluster, err error) {
|
||||||
query := this.Query(tx).
|
var query = this.Query(tx).
|
||||||
State(NodeClusterStateEnabled)
|
State(NodeClusterStateEnabled)
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
query.Where("(name LIKE :keyword OR dnsName like :keyword OR (dnsDomainId > 0 AND dnsDomainId IN (SELECT id FROM "+dns.SharedDNSDomainDAO.Table+" WHERE name LIKE :keyword AND state=1)))").
|
query.Where("(name LIKE :keyword OR dnsName like :keyword OR (dnsDomainId > 0 AND dnsDomainId IN (SELECT id FROM "+dns.SharedDNSDomainDAO.Table+" WHERE name LIKE :keyword AND state=1)))").
|
||||||
Param("keyword", dbutils.QuoteLike(keyword))
|
Param("keyword", dbutils.QuoteLike(keyword))
|
||||||
}
|
}
|
||||||
_, err = query.
|
_, err = query.
|
||||||
|
Result(
|
||||||
|
NodeClusterField_Id,
|
||||||
|
NodeClusterField_Name,
|
||||||
|
NodeClusterField_IsOn,
|
||||||
|
NodeClusterField_IsPinned,
|
||||||
|
NodeClusterField_InstallDir,
|
||||||
|
NodeClusterField_HttpFirewallPolicyId,
|
||||||
|
NodeClusterField_AdminId,
|
||||||
|
NodeClusterField_IsOn,
|
||||||
|
NodeClusterField_IsAD,
|
||||||
|
NodeClusterField_UserId,
|
||||||
|
NodeClusterField_DnsName,
|
||||||
|
NodeClusterField_DnsDomainId,
|
||||||
|
NodeClusterField_Dns,
|
||||||
|
NodeClusterField_CreatedAt,
|
||||||
|
NodeClusterField_UniqueId,
|
||||||
|
NodeClusterField_Secret,
|
||||||
|
NodeClusterField_GrantId,
|
||||||
|
NodeClusterField_TimeZone,
|
||||||
|
).
|
||||||
Offset(offset).
|
Offset(offset).
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
Desc("isPinned").
|
Desc("isPinned").
|
||||||
DescPk().
|
DescPk().
|
||||||
FindAll()
|
FindAll()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1113,11 +1135,12 @@ func (this *NodeClusterDAO) FindClusterUAMPolicy(tx *dbs.Tx, clusterId int64, ca
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var policy = nodeconfigs.NewUAMPolicy()
|
||||||
|
|
||||||
if IsNull(uamJSON) {
|
if IsNull(uamJSON) {
|
||||||
return nodeconfigs.DefaultUAMPolicy, nil
|
return policy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var policy = &nodeconfigs.UAMPolicy{}
|
|
||||||
err = json.Unmarshal(uamJSON, policy)
|
err = json.Unmarshal(uamJSON, policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1373,7 +1396,7 @@ func (this *NodeClusterDAO) FindClusterGlobalServerConfig(tx *dbs.Tx, clusterId
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = serverconfigs.DefaultGlobalServerConfig()
|
var config = serverconfigs.NewGlobalServerConfig()
|
||||||
if IsNull(configJSON) {
|
if IsNull(configJSON) {
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
@@ -1389,7 +1412,7 @@ func (this *NodeClusterDAO) FindClusterGlobalServerConfig(tx *dbs.Tx, clusterId
|
|||||||
// UpdateClusterGlobalServerConfig 修改全局服务配置
|
// UpdateClusterGlobalServerConfig 修改全局服务配置
|
||||||
func (this *NodeClusterDAO) UpdateClusterGlobalServerConfig(tx *dbs.Tx, clusterId int64, config *serverconfigs.GlobalServerConfig) error {
|
func (this *NodeClusterDAO) UpdateClusterGlobalServerConfig(tx *dbs.Tx, clusterId int64, config *serverconfigs.GlobalServerConfig) error {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = serverconfigs.DefaultGlobalServerConfig()
|
config = serverconfigs.NewGlobalServerConfig()
|
||||||
}
|
}
|
||||||
configJSON, err := json.Marshal(config)
|
configJSON, err := json.Marshal(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,6 +2,49 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
NodeClusterField_Id dbs.FieldName = "id" // ID
|
||||||
|
NodeClusterField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
NodeClusterField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
NodeClusterField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
NodeClusterField_Name dbs.FieldName = "name" // 名称
|
||||||
|
NodeClusterField_UseAllAPINodes dbs.FieldName = "useAllAPINodes" // 是否使用所有API节点
|
||||||
|
NodeClusterField_ApiNodes dbs.FieldName = "apiNodes" // 使用的API节点
|
||||||
|
NodeClusterField_InstallDir dbs.FieldName = "installDir" // 安装目录
|
||||||
|
NodeClusterField_Order dbs.FieldName = "order" // 排序
|
||||||
|
NodeClusterField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
NodeClusterField_GrantId dbs.FieldName = "grantId" // 默认认证方式
|
||||||
|
NodeClusterField_SshParams dbs.FieldName = "sshParams" // SSH默认参数
|
||||||
|
NodeClusterField_State dbs.FieldName = "state" // 状态
|
||||||
|
NodeClusterField_AutoRegister dbs.FieldName = "autoRegister" // 是否开启自动注册
|
||||||
|
NodeClusterField_UniqueId dbs.FieldName = "uniqueId" // 唯一ID
|
||||||
|
NodeClusterField_Secret dbs.FieldName = "secret" // 密钥
|
||||||
|
NodeClusterField_HealthCheck dbs.FieldName = "healthCheck" // 健康检查
|
||||||
|
NodeClusterField_DnsName dbs.FieldName = "dnsName" // DNS名称
|
||||||
|
NodeClusterField_DnsDomainId dbs.FieldName = "dnsDomainId" // 域名ID
|
||||||
|
NodeClusterField_Dns dbs.FieldName = "dns" // DNS配置
|
||||||
|
NodeClusterField_Toa dbs.FieldName = "toa" // TOA配置
|
||||||
|
NodeClusterField_CachePolicyId dbs.FieldName = "cachePolicyId" // 缓存策略ID
|
||||||
|
NodeClusterField_HttpFirewallPolicyId dbs.FieldName = "httpFirewallPolicyId" // WAF策略ID
|
||||||
|
NodeClusterField_AccessLog dbs.FieldName = "accessLog" // 访问日志设置
|
||||||
|
NodeClusterField_SystemServices dbs.FieldName = "systemServices" // 系统服务设置
|
||||||
|
NodeClusterField_TimeZone dbs.FieldName = "timeZone" // 时区
|
||||||
|
NodeClusterField_NodeMaxThreads dbs.FieldName = "nodeMaxThreads" // 节点最大线程数
|
||||||
|
NodeClusterField_DdosProtection dbs.FieldName = "ddosProtection" // DDoS防护设置
|
||||||
|
NodeClusterField_AutoOpenPorts dbs.FieldName = "autoOpenPorts" // 是否自动尝试开放端口
|
||||||
|
NodeClusterField_IsPinned dbs.FieldName = "isPinned" // 是否置顶
|
||||||
|
NodeClusterField_Webp dbs.FieldName = "webp" // WebP设置
|
||||||
|
NodeClusterField_Uam dbs.FieldName = "uam" // UAM设置
|
||||||
|
NodeClusterField_Clock dbs.FieldName = "clock" // 时钟配置
|
||||||
|
NodeClusterField_GlobalServerConfig dbs.FieldName = "globalServerConfig" // 全局服务配置
|
||||||
|
NodeClusterField_AutoRemoteStart dbs.FieldName = "autoRemoteStart" // 自动远程启动
|
||||||
|
NodeClusterField_AutoInstallNftables dbs.FieldName = "autoInstallNftables" // 自动安装nftables
|
||||||
|
NodeClusterField_IsAD dbs.FieldName = "isAD" // 是否为高防集群
|
||||||
|
NodeClusterField_HttpPages dbs.FieldName = "httpPages" // 自定义页面设置
|
||||||
|
NodeClusterField_Cc dbs.FieldName = "cc" // CC设置
|
||||||
|
NodeClusterField_Http3 dbs.FieldName = "http3" // HTTP3设置
|
||||||
|
)
|
||||||
|
|
||||||
// NodeCluster 节点集群
|
// NodeCluster 节点集群
|
||||||
type NodeCluster struct {
|
type NodeCluster struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ func (this *NodeCluster) DecodeClock() *nodeconfigs.ClockConfig {
|
|||||||
|
|
||||||
// DecodeGlobalServerConfig 解析全局服务配置
|
// DecodeGlobalServerConfig 解析全局服务配置
|
||||||
func (this *NodeCluster) DecodeGlobalServerConfig() *serverconfigs.GlobalServerConfig {
|
func (this *NodeCluster) DecodeGlobalServerConfig() *serverconfigs.GlobalServerConfig {
|
||||||
var config = serverconfigs.DefaultGlobalServerConfig()
|
var config = serverconfigs.NewGlobalServerConfig()
|
||||||
if IsNotNull(this.GlobalServerConfig) {
|
if IsNotNull(this.GlobalServerConfig) {
|
||||||
err := json.Unmarshal(this.GlobalServerConfig, config)
|
err := json.Unmarshal(this.GlobalServerConfig, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1174,7 +1174,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
|
|
||||||
// UAM
|
// UAM
|
||||||
if IsNotNull(nodeCluster.Uam) {
|
if IsNotNull(nodeCluster.Uam) {
|
||||||
var uamPolicy = &nodeconfigs.UAMPolicy{}
|
var uamPolicy = nodeconfigs.NewUAMPolicy()
|
||||||
err = json.Unmarshal(nodeCluster.Uam, uamPolicy)
|
err = json.Unmarshal(nodeCluster.Uam, uamPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -233,6 +233,12 @@ func (this *NodeTaskDAO) DeleteNodeTasks(tx *dbs.Tx, role string, nodeId int64)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllNodeTasks 删除所有节点相关任务
|
||||||
|
func (this *NodeTaskDAO)DeleteAllNodeTasks(tx *dbs.Tx) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
DeleteQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// FindDoingNodeTasks 查询一个节点的所有任务
|
// FindDoingNodeTasks 查询一个节点的所有任务
|
||||||
func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int64, version int64) (result []*NodeTask, err error) {
|
func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int64, version int64) (result []*NodeTask, err error) {
|
||||||
if nodeId <= 0 {
|
if nodeId <= 0 {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedNodeTrafficDailyStatDAO.Clean(nil, 30) // 只保留N天
|
err := SharedNodeTrafficDailyStatDAO.CleanDefaultDays(nil, 32) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("NodeTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("NodeTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -134,11 +134,27 @@ func (this *NodeTrafficDailyStatDAO) SumDailyStat(tx *dbs.Tx, role string, nodeI
|
|||||||
return one.(*NodeTrafficDailyStat), nil
|
return one.(*NodeTrafficDailyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *NodeTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *NodeTrafficDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *NodeTrafficDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.NodeTrafficDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.NodeTrafficDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -104,7 +104,8 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
|
|||||||
certRef *sslconfigs.SSLCertRef,
|
certRef *sslconfigs.SSLCertRef,
|
||||||
domains []string,
|
domains []string,
|
||||||
host string,
|
host string,
|
||||||
followPort bool) (originId int64, err error) {
|
followPort bool,
|
||||||
|
http2Enabled bool) (originId int64, err error) {
|
||||||
var op = NewOriginOperator()
|
var op = NewOriginOperator()
|
||||||
op.AdminId = adminId
|
op.AdminId = adminId
|
||||||
op.UserId = userId
|
op.UserId = userId
|
||||||
@@ -182,6 +183,7 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
|
|||||||
|
|
||||||
op.Host = host
|
op.Host = host
|
||||||
op.FollowPort = followPort
|
op.FollowPort = followPort
|
||||||
|
op.Http2Enabled = http2Enabled
|
||||||
|
|
||||||
op.State = OriginStateEnabled
|
op.State = OriginStateEnabled
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
@@ -208,7 +210,8 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
|||||||
certRef *sslconfigs.SSLCertRef,
|
certRef *sslconfigs.SSLCertRef,
|
||||||
domains []string,
|
domains []string,
|
||||||
host string,
|
host string,
|
||||||
followPort bool) error {
|
followPort bool,
|
||||||
|
http2Enabled bool) error {
|
||||||
if originId <= 0 {
|
if originId <= 0 {
|
||||||
return errors.New("invalid originId")
|
return errors.New("invalid originId")
|
||||||
}
|
}
|
||||||
@@ -290,6 +293,7 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
|||||||
|
|
||||||
op.Host = host
|
op.Host = host
|
||||||
op.FollowPort = followPort
|
op.FollowPort = followPort
|
||||||
|
op.Http2Enabled = http2Enabled
|
||||||
|
|
||||||
err := this.Save(tx, op)
|
err := this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -353,6 +357,7 @@ func (this *OriginDAO) CloneOrigin(tx *dbs.Tx, fromOriginId int64) (newOriginId
|
|||||||
op.Domains = origin.Domains
|
op.Domains = origin.Domains
|
||||||
}
|
}
|
||||||
op.FollowPort = origin.FollowPort
|
op.FollowPort = origin.FollowPort
|
||||||
|
op.Http2Enabled = origin.Http2Enabled
|
||||||
op.State = origin.State
|
op.State = origin.State
|
||||||
return this.SaveInt64(tx, op)
|
return this.SaveInt64(tx, op)
|
||||||
}
|
}
|
||||||
@@ -391,6 +396,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *
|
|||||||
RequestHost: origin.Host,
|
RequestHost: origin.Host,
|
||||||
Domains: origin.DecodeDomains(),
|
Domains: origin.DecodeDomains(),
|
||||||
FollowPort: origin.FollowPort,
|
FollowPort: origin.FollowPort,
|
||||||
|
HTTP2Enabled: origin.Http2Enabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
// addr
|
// addr
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type Origin struct {
|
|||||||
Domains dbs.JSON `field:"domains"` // 所属域名
|
Domains dbs.JSON `field:"domains"` // 所属域名
|
||||||
FollowPort bool `field:"followPort"` // 端口跟随
|
FollowPort bool `field:"followPort"` // 端口跟随
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
|
Http2Enabled bool `field:"http2Enabled"` // 是否支持HTTP/2
|
||||||
}
|
}
|
||||||
|
|
||||||
type OriginOperator struct {
|
type OriginOperator struct {
|
||||||
@@ -63,6 +64,7 @@ type OriginOperator struct {
|
|||||||
Domains any // 所属域名
|
Domains any // 所属域名
|
||||||
FollowPort any // 端口跟随
|
FollowPort any // 端口跟随
|
||||||
State any // 状态
|
State any // 状态
|
||||||
|
Http2Enabled any // 是否支持HTTP/2
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOriginOperator() *OriginOperator {
|
func NewOriginOperator() *OriginOperator {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func init() {
|
|||||||
// EnableRegionCity 启用条目
|
// EnableRegionCity 启用条目
|
||||||
func (this *RegionCityDAO) EnableRegionCity(tx *dbs.Tx, id uint32) error {
|
func (this *RegionCityDAO) EnableRegionCity(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCityStateEnabled).
|
Set("state", RegionCityStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -51,7 +51,7 @@ func (this *RegionCityDAO) EnableRegionCity(tx *dbs.Tx, id uint32) error {
|
|||||||
// DisableRegionCity 禁用条目
|
// DisableRegionCity 禁用条目
|
||||||
func (this *RegionCityDAO) DisableRegionCity(tx *dbs.Tx, id uint32) error {
|
func (this *RegionCityDAO) DisableRegionCity(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCityStateDisabled).
|
Set("state", RegionCityStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -60,7 +60,7 @@ func (this *RegionCityDAO) DisableRegionCity(tx *dbs.Tx, id uint32) error {
|
|||||||
// FindEnabledRegionCity 查找启用中的条目
|
// FindEnabledRegionCity 查找启用中的条目
|
||||||
func (this *RegionCityDAO) FindEnabledRegionCity(tx *dbs.Tx, id int64) (*RegionCity, error) {
|
func (this *RegionCityDAO) FindEnabledRegionCity(tx *dbs.Tx, id int64) (*RegionCity, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionCityStateEnabled).
|
Attr("state", RegionCityStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -72,7 +72,7 @@ func (this *RegionCityDAO) FindEnabledRegionCity(tx *dbs.Tx, id int64) (*RegionC
|
|||||||
// FindRegionCityName 根据主键查找名称
|
// FindRegionCityName 根据主键查找名称
|
||||||
func (this *RegionCityDAO) FindRegionCityName(tx *dbs.Tx, id uint32) (string, error) {
|
func (this *RegionCityDAO) FindRegionCityName(tx *dbs.Tx, id uint32) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ func (this *RegionCityDAO) FindRegionCityName(tx *dbs.Tx, id uint32) (string, er
|
|||||||
func (this *RegionCityDAO) FindCityWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionCityDAO) FindCityWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Attr("dataId", dataId).
|
Attr("dataId", dataId).
|
||||||
ResultPk().
|
Result(RegionCityField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ func (this *RegionCityDAO) CreateCity(tx *dbs.Tx, provinceId int64, name string,
|
|||||||
op.DataId = dataId
|
op.DataId = dataId
|
||||||
op.State = RegionCityStateEnabled
|
op.State = RegionCityStateEnabled
|
||||||
|
|
||||||
codes := []string{name}
|
var codes = []string{name}
|
||||||
codesJSON, err := json.Marshal(codes)
|
codesJSON, err := json.Marshal(codes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -103,7 +103,18 @@ func (this *RegionCityDAO) CreateCity(tx *dbs.Tx, provinceId int64, name string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return types.Int64(op.Id), nil
|
var cityId = types.Int64(op.Id)
|
||||||
|
|
||||||
|
// value id
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(cityId).
|
||||||
|
Set(RegionCityField_ValueId, cityId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cityId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindCityIdWithName 根据城市名查找城市ID
|
// FindCityIdWithName 根据城市名查找城市ID
|
||||||
@@ -113,7 +124,7 @@ func (this *RegionCityDAO) FindCityIdWithName(tx *dbs.Tx, provinceId int64, city
|
|||||||
Where("(name=:cityName OR customName=:cityName OR JSON_CONTAINS(codes, :cityNameJSON) OR JSON_CONTAINS(customCodes, :cityNameJSON))").
|
Where("(name=:cityName OR customName=:cityName OR JSON_CONTAINS(codes, :cityNameJSON) OR JSON_CONTAINS(customCodes, :cityNameJSON))").
|
||||||
Param("cityName", cityName).
|
Param("cityName", cityName).
|
||||||
Param("cityNameJSON", strconv.Quote(cityName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("cityNameJSON", strconv.Quote(cityName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionCityField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +158,7 @@ func (this *RegionCityDAO) UpdateCityCustom(tx *dbs.Tx, cityId int64, customName
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(cityId).
|
Attr(RegionCityField_ValueId, cityId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,22 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionCityField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionCityField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionCityField_ProvinceId dbs.FieldName = "provinceId" // 省份ID
|
||||||
|
RegionCityField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionCityField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionCityField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionCityField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionCityField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionCityField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
)
|
||||||
|
|
||||||
// RegionCity 区域-城市
|
// RegionCity 区域-城市
|
||||||
type RegionCity struct {
|
type RegionCity struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
ProvinceId uint32 `field:"provinceId"` // 省份ID
|
ProvinceId uint32 `field:"provinceId"` // 省份ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
@@ -15,14 +28,15 @@ type RegionCity struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionCityOperator struct {
|
type RegionCityOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
ProvinceId interface{} // 省份ID
|
ValueId any // 实际ID
|
||||||
Name interface{} // 名称
|
ProvinceId any // 省份ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
DataId interface{} // 原始数据ID
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionCityOperator() *RegionCityOperator {
|
func NewRegionCityOperator() *RegionCityOperator {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -20,10 +21,6 @@ const (
|
|||||||
RegionCountryStateDisabled = 0 // 已禁用
|
RegionCountryStateDisabled = 0 // 已禁用
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
CountryChinaId = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
var regionCountryIdAndNameCacheMap = map[int64]string{} // country id => name
|
var regionCountryIdAndNameCacheMap = map[int64]string{} // country id => name
|
||||||
|
|
||||||
type RegionCountryDAO dbs.DAO
|
type RegionCountryDAO dbs.DAO
|
||||||
@@ -50,7 +47,7 @@ func init() {
|
|||||||
// EnableRegionCountry 启用条目
|
// EnableRegionCountry 启用条目
|
||||||
func (this *RegionCountryDAO) EnableRegionCountry(tx *dbs.Tx, id uint32) error {
|
func (this *RegionCountryDAO) EnableRegionCountry(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCountryStateEnabled).
|
Set("state", RegionCountryStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -59,7 +56,7 @@ func (this *RegionCountryDAO) EnableRegionCountry(tx *dbs.Tx, id uint32) error {
|
|||||||
// DisableRegionCountry 禁用条目
|
// DisableRegionCountry 禁用条目
|
||||||
func (this *RegionCountryDAO) DisableRegionCountry(tx *dbs.Tx, id int64) error {
|
func (this *RegionCountryDAO) DisableRegionCountry(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCountryStateDisabled).
|
Set("state", RegionCountryStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -68,7 +65,7 @@ func (this *RegionCountryDAO) DisableRegionCountry(tx *dbs.Tx, id int64) error {
|
|||||||
// FindEnabledRegionCountry 查找启用中的条目
|
// FindEnabledRegionCountry 查找启用中的条目
|
||||||
func (this *RegionCountryDAO) FindEnabledRegionCountry(tx *dbs.Tx, id int64) (*RegionCountry, error) {
|
func (this *RegionCountryDAO) FindEnabledRegionCountry(tx *dbs.Tx, id int64) (*RegionCountry, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionCountryStateEnabled).
|
Attr("state", RegionCountryStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -88,7 +85,7 @@ func (this *RegionCountryDAO) FindRegionCountryName(tx *dbs.Tx, id int64) (strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
name, err := this.Query(tx).
|
name, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,7 +102,7 @@ func (this *RegionCountryDAO) FindRegionCountryName(tx *dbs.Tx, id int64) (strin
|
|||||||
func (this *RegionCountryDAO) FindCountryIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionCountryDAO) FindCountryIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Attr("dataId", dataId).
|
Attr("dataId", dataId).
|
||||||
ResultPk().
|
Result(RegionCountryField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +112,7 @@ func (this *RegionCountryDAO) FindCountryIdWithName(tx *dbs.Tx, countryName stri
|
|||||||
Where("(name=:countryName OR JSON_CONTAINS(codes, :countryNameJSON) OR customName=:countryName OR JSON_CONTAINS(customCodes, :countryNameJSON))").
|
Where("(name=:countryName OR JSON_CONTAINS(codes, :countryNameJSON) OR customName=:countryName OR JSON_CONTAINS(customCodes, :countryNameJSON))").
|
||||||
Param("countryName", countryName).
|
Param("countryName", countryName).
|
||||||
Param("countryNameJSON", strconv.Quote(countryName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("countryNameJSON", strconv.Quote(countryName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionCountryField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,16 +142,61 @@ func (this *RegionCountryDAO) CreateCountry(tx *dbs.Tx, name string, dataId stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return types.Int64(op.Id), nil
|
var countryId = types.Int64(op.Id)
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(countryId).
|
||||||
|
Set(RegionCountryField_ValueId, countryId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return countryId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledCountriesOrderByPinyin 查找所有可用的国家并按拼音排序
|
// FindAllEnabledCountriesOrderByPinyin 查找所有可用的国家并按拼音排序
|
||||||
func (this *RegionCountryDAO) FindAllEnabledCountriesOrderByPinyin(tx *dbs.Tx) (result []*RegionCountry, err error) {
|
func (this *RegionCountryDAO) FindAllEnabledCountriesOrderByPinyin(tx *dbs.Tx) (result []*RegionCountry, err error) {
|
||||||
_, err = this.Query(tx).
|
ones, err := this.Query(tx).
|
||||||
State(RegionCountryStateEnabled).
|
State(RegionCountryStateEnabled).
|
||||||
Slice(&result).
|
Asc("JSON_EXTRACT(pinyin, '$[0]')").
|
||||||
Asc("pinyin").
|
|
||||||
FindAll()
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// resort China special regions
|
||||||
|
var chinaRegionMap = map[int64]*RegionCountry{} // countryId => *RegionCountry
|
||||||
|
for _, one := range ones {
|
||||||
|
var country = one.(*RegionCountry)
|
||||||
|
var valueId = int64(country.ValueId)
|
||||||
|
if regionconfigs.CheckRegionIsInGreaterChina(valueId) {
|
||||||
|
chinaRegionMap[valueId] = country
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, one := range ones {
|
||||||
|
var country = one.(*RegionCountry)
|
||||||
|
var valueId = int64(country.ValueId)
|
||||||
|
if valueId == regionconfigs.RegionChinaId {
|
||||||
|
result = append(result, country)
|
||||||
|
|
||||||
|
// add hk, tw, mo, mainland ...
|
||||||
|
for _, subRegionId := range regionconfigs.FindAllGreaterChinaSubRegionIds() {
|
||||||
|
subRegion, ok := chinaRegionMap[subRegionId]
|
||||||
|
if ok {
|
||||||
|
result = append(result, subRegion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if regionconfigs.CheckRegionIsInGreaterChina(valueId) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, country)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +205,7 @@ func (this *RegionCountryDAO) FindAllCountries(tx *dbs.Tx) (result []*RegionCoun
|
|||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionCountryStateEnabled).
|
State(RegionCountryStateEnabled).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
AscPk().
|
Asc(RegionCountryField_ValueId).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -185,7 +227,7 @@ func (this *RegionCountryDAO) UpdateCountryCustom(tx *dbs.Tx, countryId int64, c
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(countryId).
|
Attr("valueId", countryId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,25 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionCountryField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionCountryField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionCountryField_ValueCode dbs.FieldName = "valueCode" // 值代号
|
||||||
|
RegionCountryField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionCountryField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionCountryField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionCountryField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionCountryField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionCountryField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
RegionCountryField_Pinyin dbs.FieldName = "pinyin" // 拼音
|
||||||
|
RegionCountryField_IsCommon dbs.FieldName = "isCommon" // 是否常用
|
||||||
|
)
|
||||||
|
|
||||||
// RegionCountry 区域-国家/地区
|
// RegionCountry 区域-国家/地区
|
||||||
type RegionCountry struct {
|
type RegionCountry struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
|
ValueCode string `field:"valueCode"` // 值代号
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
CustomName string `field:"customName"` // 自定义名称
|
CustomName string `field:"customName"` // 自定义名称
|
||||||
@@ -12,17 +28,21 @@ type RegionCountry struct {
|
|||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
DataId string `field:"dataId"` // 原始数据ID
|
DataId string `field:"dataId"` // 原始数据ID
|
||||||
Pinyin dbs.JSON `field:"pinyin"` // 拼音
|
Pinyin dbs.JSON `field:"pinyin"` // 拼音
|
||||||
|
IsCommon bool `field:"isCommon"` // 是否常用
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegionCountryOperator struct {
|
type RegionCountryOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Name interface{} // 名称
|
ValueId any // 实际ID
|
||||||
Codes interface{} // 代号
|
ValueCode any // 值代号
|
||||||
CustomName interface{} // 自定义名称
|
Name any // 名称
|
||||||
CustomCodes interface{} // 自定义代号
|
Codes any // 代号
|
||||||
State interface{} // 状态
|
CustomName any // 自定义名称
|
||||||
DataId interface{} // 原始数据ID
|
CustomCodes any // 自定义代号
|
||||||
Pinyin interface{} // 拼音
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
|
Pinyin any // 拼音
|
||||||
|
IsCommon any // 是否常用
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionCountryOperator() *RegionCountryOperator {
|
func NewRegionCountryOperator() *RegionCountryOperator {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func init() {
|
|||||||
// EnableRegionProvider 启用条目
|
// EnableRegionProvider 启用条目
|
||||||
func (this *RegionProviderDAO) EnableRegionProvider(tx *dbs.Tx, id uint32) error {
|
func (this *RegionProviderDAO) EnableRegionProvider(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProviderStateEnabled).
|
Set("state", RegionProviderStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -50,7 +50,7 @@ func (this *RegionProviderDAO) EnableRegionProvider(tx *dbs.Tx, id uint32) error
|
|||||||
// DisableRegionProvider 禁用条目
|
// DisableRegionProvider 禁用条目
|
||||||
func (this *RegionProviderDAO) DisableRegionProvider(tx *dbs.Tx, id uint32) error {
|
func (this *RegionProviderDAO) DisableRegionProvider(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProviderStateDisabled).
|
Set("state", RegionProviderStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -59,7 +59,7 @@ func (this *RegionProviderDAO) DisableRegionProvider(tx *dbs.Tx, id uint32) erro
|
|||||||
// FindEnabledRegionProvider 查找启用中的条目
|
// FindEnabledRegionProvider 查找启用中的条目
|
||||||
func (this *RegionProviderDAO) FindEnabledRegionProvider(tx *dbs.Tx, id int64) (*RegionProvider, error) {
|
func (this *RegionProviderDAO) FindEnabledRegionProvider(tx *dbs.Tx, id int64) (*RegionProvider, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionProviderStateEnabled).
|
Attr("state", RegionProviderStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -71,7 +71,7 @@ func (this *RegionProviderDAO) FindEnabledRegionProvider(tx *dbs.Tx, id int64) (
|
|||||||
// FindRegionProviderName 根据主键查找名称
|
// FindRegionProviderName 根据主键查找名称
|
||||||
func (this *RegionProviderDAO) FindRegionProviderName(tx *dbs.Tx, id uint32) (string, error) {
|
func (this *RegionProviderDAO) FindRegionProviderName(tx *dbs.Tx, id uint32) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ func (this *RegionProviderDAO) FindProviderIdWithName(tx *dbs.Tx, providerName s
|
|||||||
Where("(name=:providerName OR customName=:providerName OR JSON_CONTAINS(codes, :providerNameJSON) OR JSON_CONTAINS(customCodes, :providerNameJSON))").
|
Where("(name=:providerName OR customName=:providerName OR JSON_CONTAINS(codes, :providerNameJSON) OR JSON_CONTAINS(customCodes, :providerNameJSON))").
|
||||||
Param("providerName", providerName).
|
Param("providerName", providerName).
|
||||||
Param("providerNameJSON", strconv.Quote(providerName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("providerNameJSON", strconv.Quote(providerName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionProviderField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,20 @@ func (this *RegionProviderDAO) CreateProvider(tx *dbs.Tx, name string) (int64, e
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
op.Codes = codesJSON
|
op.Codes = codesJSON
|
||||||
return this.SaveInt64(tx, op)
|
providerId, err := this.SaveInt64(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(providerId).
|
||||||
|
Set(RegionProviderField_ValueId, providerId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return providerId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledProviders 查找所有服务商
|
// FindAllEnabledProviders 查找所有服务商
|
||||||
@@ -119,7 +132,7 @@ func (this *RegionProviderDAO) UpdateProviderCustom(tx *dbs.Tx, providerId int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(providerId).
|
Attr("valueId", providerId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,20 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionProviderField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionProviderField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionProviderField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionProviderField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionProviderField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionProviderField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionProviderField_State dbs.FieldName = "state" // 状态
|
||||||
|
)
|
||||||
|
|
||||||
// RegionProvider 区域-运营商
|
// RegionProvider 区域-运营商
|
||||||
type RegionProvider struct {
|
type RegionProvider struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
CustomName string `field:"customName"` // 自定义名称
|
CustomName string `field:"customName"` // 自定义名称
|
||||||
@@ -13,12 +24,13 @@ type RegionProvider struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionProviderOperator struct {
|
type RegionProviderOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Name interface{} // 名称
|
ValueId any // 实际ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
|
State any // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionProviderOperator() *RegionProviderOperator {
|
func NewRegionProviderOperator() *RegionProviderOperator {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func init() {
|
|||||||
// EnableRegionProvince 启用条目
|
// EnableRegionProvince 启用条目
|
||||||
func (this *RegionProvinceDAO) EnableRegionProvince(tx *dbs.Tx, id int64) error {
|
func (this *RegionProvinceDAO) EnableRegionProvince(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProvinceStateEnabled).
|
Set("state", RegionProvinceStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -51,7 +51,7 @@ func (this *RegionProvinceDAO) EnableRegionProvince(tx *dbs.Tx, id int64) error
|
|||||||
// DisableRegionProvince 禁用条目
|
// DisableRegionProvince 禁用条目
|
||||||
func (this *RegionProvinceDAO) DisableRegionProvince(tx *dbs.Tx, id int64) error {
|
func (this *RegionProvinceDAO) DisableRegionProvince(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProvinceStateDisabled).
|
Set("state", RegionProvinceStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -60,7 +60,7 @@ func (this *RegionProvinceDAO) DisableRegionProvince(tx *dbs.Tx, id int64) error
|
|||||||
// FindEnabledRegionProvince 查找启用中的条目
|
// FindEnabledRegionProvince 查找启用中的条目
|
||||||
func (this *RegionProvinceDAO) FindEnabledRegionProvince(tx *dbs.Tx, id int64) (*RegionProvince, error) {
|
func (this *RegionProvinceDAO) FindEnabledRegionProvince(tx *dbs.Tx, id int64) (*RegionProvince, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionProvinceStateEnabled).
|
Attr("state", RegionProvinceStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -72,7 +72,7 @@ func (this *RegionProvinceDAO) FindEnabledRegionProvince(tx *dbs.Tx, id int64) (
|
|||||||
// FindRegionProvinceName 根据主键查找名称
|
// FindRegionProvinceName 根据主键查找名称
|
||||||
func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (string, error) {
|
func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (str
|
|||||||
func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Attr("dataId", dataId).
|
Attr("dataId", dataId).
|
||||||
ResultPk().
|
Result(RegionProvinceField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ func (this *RegionProvinceDAO) FindProvinceIdWithName(tx *dbs.Tx, countryId int6
|
|||||||
Where("(name=:provinceName OR customName=:provinceName OR JSON_CONTAINS(codes, :provinceNameJSON) OR JSON_CONTAINS(customCodes, :provinceNameJSON))").
|
Where("(name=:provinceName OR customName=:provinceName OR JSON_CONTAINS(codes, :provinceNameJSON) OR JSON_CONTAINS(customCodes, :provinceNameJSON))").
|
||||||
Param("provinceName", provinceName).
|
Param("provinceName", provinceName).
|
||||||
Param("provinceNameJSON", strconv.Quote(provinceName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("provinceNameJSON", strconv.Quote(provinceName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionProvinceField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ func (this *RegionProvinceDAO) CreateProvince(tx *dbs.Tx, countryId int64, name
|
|||||||
op.DataId = dataId
|
op.DataId = dataId
|
||||||
op.State = RegionProvinceStateEnabled
|
op.State = RegionProvinceStateEnabled
|
||||||
|
|
||||||
codes := []string{name}
|
var codes = []string{name}
|
||||||
codesJSON, err := json.Marshal(codes)
|
codesJSON, err := json.Marshal(codes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -114,7 +114,17 @@ func (this *RegionProvinceDAO) CreateProvince(tx *dbs.Tx, countryId int64, name
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return types.Int64(op.Id), nil
|
var provinceId = types.Int64(op.Id)
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(provinceId).
|
||||||
|
Set(RegionProvinceField_ValueId, provinceId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return provinceId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledProvincesWithCountryId 查找某个国家/地区的所有省份
|
// FindAllEnabledProvincesWithCountryId 查找某个国家/地区的所有省份
|
||||||
@@ -122,7 +132,7 @@ func (this *RegionProvinceDAO) FindAllEnabledProvincesWithCountryId(tx *dbs.Tx,
|
|||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionProvinceStateEnabled).
|
State(RegionProvinceStateEnabled).
|
||||||
Attr("countryId", countryId).
|
Attr("countryId", countryId).
|
||||||
AscPk().
|
Asc(RegionProvinceField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -132,7 +142,7 @@ func (this *RegionProvinceDAO) FindAllEnabledProvincesWithCountryId(tx *dbs.Tx,
|
|||||||
func (this *RegionProvinceDAO) FindAllEnabledProvinces(tx *dbs.Tx) (result []*RegionProvince, err error) {
|
func (this *RegionProvinceDAO) FindAllEnabledProvinces(tx *dbs.Tx) (result []*RegionProvince, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionProvinceStateEnabled).
|
State(RegionProvinceStateEnabled).
|
||||||
AscPk().
|
Asc(RegionProvinceField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -149,7 +159,7 @@ func (this *RegionProvinceDAO) UpdateProvinceCustom(tx *dbs.Tx, provinceId int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(provinceId).
|
Attr("valueId", provinceId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,22 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionProvinceField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionProvinceField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionProvinceField_CountryId dbs.FieldName = "countryId" // 国家ID
|
||||||
|
RegionProvinceField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionProvinceField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionProvinceField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionProvinceField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionProvinceField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionProvinceField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
)
|
||||||
|
|
||||||
// RegionProvince 区域-省份
|
// RegionProvince 区域-省份
|
||||||
type RegionProvince struct {
|
type RegionProvince struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
CountryId uint32 `field:"countryId"` // 国家ID
|
CountryId uint32 `field:"countryId"` // 国家ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
@@ -15,14 +28,15 @@ type RegionProvince struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionProvinceOperator struct {
|
type RegionProvinceOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
CountryId interface{} // 国家ID
|
ValueId any // 实际ID
|
||||||
Name interface{} // 名称
|
CountryId any // 国家ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
DataId interface{} // 原始数据ID
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionProvinceOperator() *RegionProvinceOperator {
|
func NewRegionProvinceOperator() *RegionProvinceOperator {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func init() {
|
|||||||
// EnableRegionTown 启用条目
|
// EnableRegionTown 启用条目
|
||||||
func (this *RegionTownDAO) EnableRegionTown(tx *dbs.Tx, id uint32) error {
|
func (this *RegionTownDAO) EnableRegionTown(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionTownStateEnabled).
|
Set("state", RegionTownStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -50,7 +50,7 @@ func (this *RegionTownDAO) EnableRegionTown(tx *dbs.Tx, id uint32) error {
|
|||||||
// DisableRegionTown 禁用条目
|
// DisableRegionTown 禁用条目
|
||||||
func (this *RegionTownDAO) DisableRegionTown(tx *dbs.Tx, id uint32) error {
|
func (this *RegionTownDAO) DisableRegionTown(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionTownStateDisabled).
|
Set("state", RegionTownStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -59,7 +59,7 @@ func (this *RegionTownDAO) DisableRegionTown(tx *dbs.Tx, id uint32) error {
|
|||||||
// FindEnabledRegionTown 查找启用中的区县
|
// FindEnabledRegionTown 查找启用中的区县
|
||||||
func (this *RegionTownDAO) FindEnabledRegionTown(tx *dbs.Tx, id int64) (*RegionTown, error) {
|
func (this *RegionTownDAO) FindEnabledRegionTown(tx *dbs.Tx, id int64) (*RegionTown, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionTownStateEnabled).
|
Attr("state", RegionTownStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -72,7 +72,7 @@ func (this *RegionTownDAO) FindEnabledRegionTown(tx *dbs.Tx, id int64) (*RegionT
|
|||||||
func (this *RegionTownDAO) FindAllRegionTowns(tx *dbs.Tx) (result []*RegionTown, err error) {
|
func (this *RegionTownDAO) FindAllRegionTowns(tx *dbs.Tx) (result []*RegionTown, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionTownStateEnabled).
|
State(RegionTownStateEnabled).
|
||||||
AscPk().
|
Asc(RegionTownField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -83,7 +83,7 @@ func (this *RegionTownDAO) FindAllRegionTownsWithCityId(tx *dbs.Tx, cityId int64
|
|||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionTownStateEnabled).
|
State(RegionTownStateEnabled).
|
||||||
Attr("cityId", cityId).
|
Attr("cityId", cityId).
|
||||||
AscPk().
|
Asc(RegionTownField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -96,14 +96,14 @@ func (this *RegionTownDAO) FindTownIdWithName(tx *dbs.Tx, cityId int64, townName
|
|||||||
Where("(name=:townName OR customName=:townName OR JSON_CONTAINS(codes, :townNameJSON) OR JSON_CONTAINS(customCodes, :townNameJSON))").
|
Where("(name=:townName OR customName=:townName OR JSON_CONTAINS(codes, :townNameJSON) OR JSON_CONTAINS(customCodes, :townNameJSON))").
|
||||||
Param("townName", townName).
|
Param("townName", townName).
|
||||||
Param("townNameJSON", strconv.Quote(townName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("townNameJSON", strconv.Quote(townName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionTownField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindRegionTownName 根据主键查找名称
|
// FindRegionTownName 根据主键查找名称
|
||||||
func (this *RegionTownDAO) FindRegionTownName(tx *dbs.Tx, id uint32) (string, error) {
|
func (this *RegionTownDAO) FindRegionTownName(tx *dbs.Tx, id uint32) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ func (this *RegionTownDAO) UpdateTownCustom(tx *dbs.Tx, townId int64, customName
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(townId).
|
Attr("valueId", townId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
@@ -176,5 +176,18 @@ func (this *RegionTownDAO) CreateTown(tx *dbs.Tx, cityId int64, townName string)
|
|||||||
op.Codes = codes
|
op.Codes = codes
|
||||||
|
|
||||||
op.State = RegionTownStateEnabled
|
op.State = RegionTownStateEnabled
|
||||||
return this.SaveInt64(tx, op)
|
townId, err := this.SaveInt64(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(townId).
|
||||||
|
Set(RegionTownField_ValueId, townId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return townId, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,22 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionTownField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionTownField_ValueId dbs.FieldName = "valueId" // 真实ID
|
||||||
|
RegionTownField_CityId dbs.FieldName = "cityId" // 城市ID
|
||||||
|
RegionTownField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionTownField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionTownField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionTownField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionTownField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionTownField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
)
|
||||||
|
|
||||||
// RegionTown 区域-省份
|
// RegionTown 区域-省份
|
||||||
type RegionTown struct {
|
type RegionTown struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 真实ID
|
||||||
CityId uint32 `field:"cityId"` // 城市ID
|
CityId uint32 `field:"cityId"` // 城市ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
@@ -15,14 +28,15 @@ type RegionTown struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionTownOperator struct {
|
type RegionTownOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
CityId interface{} // 城市ID
|
ValueId any // 真实ID
|
||||||
Name interface{} // 名称
|
CityId any // 城市ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
DataId interface{} // 原始数据ID
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionTownOperator() *RegionTownOperator {
|
func NewRegionTownOperator() *RegionTownOperator {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedServerBandwidthStatDAO.Clean(nil)
|
err := SharedServerBandwidthStatDAO.CleanDefaultDays(nil, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("SharedServerBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("SharedServerBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -745,9 +745,9 @@ func (this *ServerBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, serverId int64, reg
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理过期数据
|
// CleanDays 清理过期数据
|
||||||
func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
func (this *ServerBandwidthStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days)) // 保留大约3个月的数据
|
||||||
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Table(table).
|
Table(table).
|
||||||
@@ -757,6 +757,22 @@ func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *ServerBandwidthStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.ServerBandwidthStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.ServerBandwidthStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|
||||||
// 批量执行
|
// 批量执行
|
||||||
func (this *ServerBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
func (this *ServerBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
||||||
var locker = &sync.Mutex{}
|
var locker = &sync.Mutex{}
|
||||||
|
|||||||
@@ -72,11 +72,11 @@ func TestServerBandwidthStatDAO_FindAllServerStatsWithDay(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerBandwidthStatDAO_Clean(t *testing.T) {
|
func TestServerBandwidthStatDAO_CleanDays(t *testing.T) {
|
||||||
var dao = models.NewServerBandwidthStatDAO()
|
var dao = models.NewServerBandwidthStatDAO()
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
var before = time.Now()
|
var before = time.Now()
|
||||||
err := dao.Clean(tx)
|
err := dao.CleanDays(tx, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -28,7 +29,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedServerDailyStatDAO.Clean(nil, 60) // 只保留 N 天,时间需要长一些,因为需要用来生成账单
|
err := SharedServerDailyStatDAO.CleanDefaultDays(nil, 60) // 只保留 N 天,时间需要长一些,因为需要用来生成账单
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Println("ServerDailyStatDAO", "clean expired data failed: "+err.Error())
|
logs.Println("ServerDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -513,7 +514,8 @@ func (this *ServerDailyStatDAO) FindStatsWithDay(tx *dbs.Tx, serverId int64, day
|
|||||||
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "day", "timeFrom", "MIN(timeTo) AS timeTo").
|
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "day", "timeFrom", "MIN(timeTo) AS timeTo").
|
||||||
Attr("serverId", serverId).
|
Attr("serverId", serverId).
|
||||||
Attr("day", day).
|
Attr("day", day).
|
||||||
Group("day").Group("timeFrom", dbs.QueryOrderDesc)
|
Group("day").
|
||||||
|
Group("timeFrom")
|
||||||
|
|
||||||
if len(timeFrom) > 0 {
|
if len(timeFrom) > 0 {
|
||||||
query.Gte("timeFrom", timeFrom)
|
query.Gte("timeFrom", timeFrom)
|
||||||
@@ -530,6 +532,11 @@ func (this *ServerDailyStatDAO) FindStatsWithDay(tx *dbs.Tx, serverId int64, day
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort results
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].TimeFrom < result[j].TimeFrom
|
||||||
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,8 +680,8 @@ func (this *ServerDailyStatDAO) compatFindHourlyStats(tx *dbs.Tx, serverId int64
|
|||||||
result = append(result, stat)
|
result = append(result, stat)
|
||||||
} else {
|
} else {
|
||||||
result = append(result, &ServerDailyStat{
|
result = append(result, &ServerDailyStat{
|
||||||
Hour: hour,
|
Hour: hour,
|
||||||
Day: hour[:8],
|
Day: hour[:8],
|
||||||
TimeFrom: hour[8:] + "00",
|
TimeFrom: hour[8:] + "00",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -742,11 +749,27 @@ func (this *ServerDailyStatDAO) UpdateStatFee(tx *dbs.Tx, statId int64, fee floa
|
|||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *ServerDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *ServerDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *ServerDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.ServerDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.ServerDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 60
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -140,6 +140,6 @@ func TestServerDailyStatDAO_FindStatsWithDay(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, stat := range stats {
|
for _, stat := range stats {
|
||||||
t.Log(stat.TimeFrom, stat.TimeTo, stat.Bytes)
|
t.Log(stat.Day, stat.TimeFrom, stat.TimeTo, stat.Bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -903,6 +903,22 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
|
|||||||
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), bandwidthBytes, 0)")
|
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), bandwidthBytes, 0)")
|
||||||
query.Param("times", strings.Join(times, ","))
|
query.Param("times", strings.Join(times, ","))
|
||||||
query.DescPk()
|
query.DescPk()
|
||||||
|
case "requestsAsc":
|
||||||
|
query.Asc("IF(FIND_IN_SET(bandwidthTime, :times), countRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
|
case "requestsDesc":
|
||||||
|
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), countRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
|
case "attackRequestsAsc":
|
||||||
|
query.Asc("IF(FIND_IN_SET(bandwidthTime, :times), countAttackRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
|
case "attackRequestsDesc":
|
||||||
|
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), countAttackRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
default:
|
default:
|
||||||
query.DescPk()
|
query.DescPk()
|
||||||
}
|
}
|
||||||
@@ -913,6 +929,8 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
|
|||||||
for _, server := range result {
|
for _, server := range result {
|
||||||
if len(server.BandwidthTime) > 0 && !lists.ContainsString(times, server.BandwidthTime) {
|
if len(server.BandwidthTime) > 0 && !lists.ContainsString(times, server.BandwidthTime) {
|
||||||
server.BandwidthBytes = 0
|
server.BandwidthBytes = 0
|
||||||
|
server.CountRequests = 0
|
||||||
|
server.CountAttackRequests = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2737,7 +2755,7 @@ func (this *ServerDAO) FindUserServerClusterIds(tx *dbs.Tx, userId int64) ([]int
|
|||||||
|
|
||||||
// UpdateServerBandwidth 更新服务带宽
|
// UpdateServerBandwidth 更新服务带宽
|
||||||
// fullTime YYYYMMDDHHII
|
// fullTime YYYYMMDDHHII
|
||||||
func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTime string, bandwidthBytes int64) error {
|
func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTime string, bandwidthBytes int64, countRequests int64, countAttackRequests int64) error {
|
||||||
if serverId <= 0 {
|
if serverId <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -2758,13 +2776,19 @@ func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTim
|
|||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Set("bandwidthTime", fullTime).
|
Set("bandwidthTime", fullTime).
|
||||||
Set("bandwidthBytes", bandwidthBytes).
|
Set("bandwidthBytes", bandwidthBytes).
|
||||||
|
Set("countRequests", countRequests).
|
||||||
|
Set("countAttackRequests", countAttackRequests).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
} else {
|
} else {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Set("bandwidthTime", fullTime).
|
Set("bandwidthTime", fullTime).
|
||||||
Set("bandwidthBytes", dbs.SQL("bandwidthBytes+:bytes")).
|
Set("bandwidthBytes", dbs.SQL("bandwidthBytes+:bytes")).
|
||||||
|
Set("countRequests", dbs.SQL("countRequests+:countRequests")).
|
||||||
|
Set("countAttackRequests", dbs.SQL("countAttackRequests+:countAttackRequests")).
|
||||||
Param("bytes", bandwidthBytes).
|
Param("bytes", bandwidthBytes).
|
||||||
|
Param("countRequests", countRequests).
|
||||||
|
Param("countAttackRequests", countAttackRequests).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ func TestServerDAO_FindBool(t *testing.T) {
|
|||||||
func TestServerDAO_UpdateServerBandwidth(t *testing.T) {
|
func TestServerDAO_UpdateServerBandwidth(t *testing.T) {
|
||||||
var dao = models.NewServerDAO()
|
var dao = models.NewServerDAO()
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
err := dao.UpdateServerBandwidth(tx, 1, timeutil.FormatTime("YmdHi", time.Now().Unix()/300*300), 1024)
|
err := dao.UpdateServerBandwidth(tx, 1, timeutil.FormatTime("YmdHi", time.Now().Unix()/300*300), 1024, 1, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,57 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
ServerField_Id dbs.FieldName = "id" // ID
|
||||||
|
ServerField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
ServerField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
ServerField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
ServerField_Type dbs.FieldName = "type" // 服务类型
|
||||||
|
ServerField_Name dbs.FieldName = "name" // 名称
|
||||||
|
ServerField_Description dbs.FieldName = "description" // 描述
|
||||||
|
ServerField_PlainServerNames dbs.FieldName = "plainServerNames" // 扁平化域名列表
|
||||||
|
ServerField_ServerNames dbs.FieldName = "serverNames" // 域名列表
|
||||||
|
ServerField_AuditingAt dbs.FieldName = "auditingAt" // 审核提交时间
|
||||||
|
ServerField_AuditingServerNames dbs.FieldName = "auditingServerNames" // 审核中的域名
|
||||||
|
ServerField_IsAuditing dbs.FieldName = "isAuditing" // 是否正在审核
|
||||||
|
ServerField_AuditingResult dbs.FieldName = "auditingResult" // 审核结果
|
||||||
|
ServerField_Http dbs.FieldName = "http" // HTTP配置
|
||||||
|
ServerField_Https dbs.FieldName = "https" // HTTPS配置
|
||||||
|
ServerField_Tcp dbs.FieldName = "tcp" // TCP配置
|
||||||
|
ServerField_Tls dbs.FieldName = "tls" // TLS配置
|
||||||
|
ServerField_Unix dbs.FieldName = "unix" // Unix配置
|
||||||
|
ServerField_Udp dbs.FieldName = "udp" // UDP配置
|
||||||
|
ServerField_WebId dbs.FieldName = "webId" // WEB配置
|
||||||
|
ServerField_ReverseProxy dbs.FieldName = "reverseProxy" // 反向代理配置
|
||||||
|
ServerField_GroupIds dbs.FieldName = "groupIds" // 分组ID列表
|
||||||
|
ServerField_Config dbs.FieldName = "config" // 服务配置,自动生成
|
||||||
|
ServerField_ConfigMd5 dbs.FieldName = "configMd5" // Md5
|
||||||
|
ServerField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||||
|
ServerField_IncludeNodes dbs.FieldName = "includeNodes" // 部署条件
|
||||||
|
ServerField_ExcludeNodes dbs.FieldName = "excludeNodes" // 节点排除条件
|
||||||
|
ServerField_Version dbs.FieldName = "version" // 版本号
|
||||||
|
ServerField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
ServerField_State dbs.FieldName = "state" // 状态
|
||||||
|
ServerField_DnsName dbs.FieldName = "dnsName" // DNS名称
|
||||||
|
ServerField_TcpPorts dbs.FieldName = "tcpPorts" // 所包含TCP端口
|
||||||
|
ServerField_UdpPorts dbs.FieldName = "udpPorts" // 所包含UDP端口
|
||||||
|
ServerField_SupportCNAME dbs.FieldName = "supportCNAME" // 允许CNAME不在域名名单
|
||||||
|
ServerField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
||||||
|
ServerField_TrafficDay dbs.FieldName = "trafficDay" // YYYYMMDD
|
||||||
|
ServerField_TrafficMonth dbs.FieldName = "trafficMonth" // YYYYMM
|
||||||
|
ServerField_TotalDailyTraffic dbs.FieldName = "totalDailyTraffic" // 日流量
|
||||||
|
ServerField_TotalMonthlyTraffic dbs.FieldName = "totalMonthlyTraffic" // 月流量
|
||||||
|
ServerField_TrafficLimitStatus dbs.FieldName = "trafficLimitStatus" // 流量限制状态
|
||||||
|
ServerField_TotalTraffic dbs.FieldName = "totalTraffic" // 总流量
|
||||||
|
ServerField_UserPlanId dbs.FieldName = "userPlanId" // 所属套餐ID
|
||||||
|
ServerField_LastUserPlanId dbs.FieldName = "lastUserPlanId" // 上一次使用的套餐
|
||||||
|
ServerField_Uam dbs.FieldName = "uam" // UAM设置
|
||||||
|
ServerField_BandwidthTime dbs.FieldName = "bandwidthTime" // 带宽更新时间,YYYYMMDDHHII
|
||||||
|
ServerField_BandwidthBytes dbs.FieldName = "bandwidthBytes" // 最近带宽峰值
|
||||||
|
ServerField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 最近攻击请求数
|
||||||
|
ServerField_CountRequests dbs.FieldName = "countRequests" // 最近总请求数
|
||||||
|
)
|
||||||
|
|
||||||
// Server 服务
|
// Server 服务
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -50,6 +101,8 @@ type Server struct {
|
|||||||
Uam dbs.JSON `field:"uam"` // UAM设置
|
Uam dbs.JSON `field:"uam"` // UAM设置
|
||||||
BandwidthTime string `field:"bandwidthTime"` // 带宽更新时间,YYYYMMDDHHII
|
BandwidthTime string `field:"bandwidthTime"` // 带宽更新时间,YYYYMMDDHHII
|
||||||
BandwidthBytes uint64 `field:"bandwidthBytes"` // 最近带宽峰值
|
BandwidthBytes uint64 `field:"bandwidthBytes"` // 最近带宽峰值
|
||||||
|
CountAttackRequests uint64 `field:"countAttackRequests"` // 最近攻击请求数
|
||||||
|
CountRequests uint64 `field:"countRequests"` // 最近总请求数
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerOperator struct {
|
type ServerOperator struct {
|
||||||
@@ -99,6 +152,8 @@ type ServerOperator struct {
|
|||||||
Uam any // UAM设置
|
Uam any // UAM设置
|
||||||
BandwidthTime any // 带宽更新时间,YYYYMMDDHHII
|
BandwidthTime any // 带宽更新时间,YYYYMMDDHHII
|
||||||
BandwidthBytes any // 最近带宽峰值
|
BandwidthBytes any // 最近带宽峰值
|
||||||
|
CountAttackRequests any // 最近攻击请求数
|
||||||
|
CountRequests any // 最近总请求数
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServerOperator() *ServerOperator {
|
func NewServerOperator() *ServerOperator {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedNodeClusterTrafficDailyStatDAO.Clean(nil, 30) // 只保留N天
|
err := SharedNodeClusterTrafficDailyStatDAO.CleanDefaultDays(nil, 30) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("NodeClusterTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("NodeClusterTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -128,11 +129,27 @@ func (this *NodeClusterTrafficDailyStatDAO) SumDailyStat(tx *dbs.Tx, clusterId i
|
|||||||
return one.(*NodeClusterTrafficDailyStat), nil
|
return one.(*NodeClusterTrafficDailyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *NodeClusterTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *NodeClusterTrafficDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *NodeClusterTrafficDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.NodeClusterTrafficDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.NodeClusterTrafficDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedNodeTrafficHourlyStatDAO.Clean(nil, 15) // 只保留N天
|
err := SharedNodeTrafficHourlyStatDAO.CleanDefaultDays(nil, 15) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("NodeTrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("NodeTrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -197,11 +198,27 @@ func (this *NodeTrafficHourlyStatDAO) FindHourlyStatsWithNodeId(tx *dbs.Tx, role
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *NodeTrafficHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *NodeTrafficHourlyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("hour", hour).
|
Lt("hour", hour).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *NodeTrafficHourlyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.NodeTrafficHourlyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.NodeTrafficHourlyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
@@ -25,7 +26,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedServerDomainHourlyStatDAO.Clean(nil, 7) // 只保留 N 天
|
err := SharedServerDomainHourlyStatDAO.CleanDefaultDays(nil, 7) // 只保留 N 天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("ServerDomainHourlyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("ServerDomainHourlyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -366,8 +367,8 @@ func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithServerId(tx *dbs.Tx
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *ServerDomainHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *ServerDomainHourlyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
||||||
for _, table := range this.FindAllPartitionTables() {
|
for _, table := range this.FindAllPartitionTables() {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
@@ -380,3 +381,19 @@ func (this *ServerDomainHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *ServerDomainHourlyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.ServerDomainHourlyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.ServerDomainHourlyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 7
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedTrafficDailyStatDAO.Clean(nil, 30) // 只保留N天
|
err := SharedTrafficDailyStatDAO.CleanDefaultDays(nil, 30) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("TrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("TrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -124,11 +125,27 @@ func (this *TrafficDailyStatDAO) FindDailyStat(tx *dbs.Tx, day string) (*Traffic
|
|||||||
return one.(*TrafficDailyStat), nil
|
return one.(*TrafficDailyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *TrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *TrafficDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *TrafficDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.TrafficDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.TrafficDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedTrafficHourlyStatDAO.Clean(nil, 15) // 只保留N天
|
err := SharedTrafficHourlyStatDAO.CleanDefaultDays(nil, 15) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("TrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("TrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -137,11 +138,27 @@ func (this *TrafficHourlyStatDAO) SumHourlyStats(tx *dbs.Tx, hourFrom string, ho
|
|||||||
return one.(*TrafficHourlyStat), nil
|
return one.(*TrafficHourlyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *TrafficHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *TrafficHourlyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("hour", hour).
|
Lt("hour", hour).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *TrafficHourlyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.TrafficHourlyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.TrafficHourlyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/zero"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SysLockerDAO dbs.DAO
|
type SysLockerDAO dbs.DAO
|
||||||
|
|
||||||
|
// concurrent transactions control
|
||||||
|
// 考虑到存在多个API节点的可能性,容量不能太大,也不能使用mutex
|
||||||
|
var sysLockerConcurrentLimiter = make(chan zero.Zero, 8)
|
||||||
|
|
||||||
func NewSysLockerDAO() *SysLockerDAO {
|
func NewSysLockerDAO() *SysLockerDAO {
|
||||||
return dbs.NewDAO(&SysLockerDAO{
|
return dbs.NewDAO(&SysLockerDAO{
|
||||||
DAOObject: dbs.DAOObject{
|
DAOObject: dbs.DAOObject{
|
||||||
@@ -114,9 +121,20 @@ func (this *SysLockerDAO) Unlock(tx *dbs.Tx, key string) error {
|
|||||||
|
|
||||||
// Increase 增加版本号
|
// Increase 增加版本号
|
||||||
func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (int64, error) {
|
func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (int64, error) {
|
||||||
|
// validate key
|
||||||
|
if strings.Contains(key, "'") {
|
||||||
|
return 0, errors.New("invalid key '" + key + "'")
|
||||||
|
}
|
||||||
|
|
||||||
if tx == nil {
|
if tx == nil {
|
||||||
var result int64
|
var result int64
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
sysLockerConcurrentLimiter <- zero.Zero{} // push
|
||||||
|
defer func() {
|
||||||
|
<-sysLockerConcurrentLimiter // pop
|
||||||
|
}()
|
||||||
|
|
||||||
err = this.Instance.RunTx(func(tx *dbs.Tx) error {
|
err = this.Instance.RunTx(func(tx *dbs.Tx) error {
|
||||||
result, err = this.Increase(tx, key, defaultValue)
|
result, err = this.Increase(tx, key, defaultValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -126,7 +144,22 @@ func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (
|
|||||||
})
|
})
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
err := this.Query(tx).
|
|
||||||
|
// combine statements to make increasing faster
|
||||||
|
colValue, err := tx.FindCol(0, "INSERT INTO `"+this.Table+"` (`key`, `version`) VALUES ('"+key+"', "+types.String(defaultValue)+") ON DUPLICATE KEY UPDATE `version`=`version`+1; SELECT `version` FROM `"+this.Table+"` WHERE `key`='"+key+"'")
|
||||||
|
if err != nil {
|
||||||
|
if CheckSQLErrCode(err, 1064 /** syntax error **/) {
|
||||||
|
// continue to use seperated query
|
||||||
|
err = nil
|
||||||
|
} else {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return types.Int64(colValue), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Reuse(false). // no need to prepare statement in every transaction
|
||||||
InsertOrUpdateQuickly(maps.Map{
|
InsertOrUpdateQuickly(maps.Map{
|
||||||
"key": key,
|
"key": key,
|
||||||
"version": defaultValue,
|
"version": defaultValue,
|
||||||
@@ -137,12 +170,12 @@ func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
|
Reuse(false). // no need to prepare statement in every transaction
|
||||||
Attr("key", key).
|
Attr("key", key).
|
||||||
Result("version").
|
Result("version").
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 读取当前版本号
|
// 读取当前版本号
|
||||||
func (this *SysLockerDAO) Read(tx *dbs.Tx, key string) (int64, error) {
|
func (this *SysLockerDAO) Read(tx *dbs.Tx, key string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
|
|||||||
@@ -3,44 +3,146 @@ package models
|
|||||||
import (
|
import (
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSysLockerDAO_Lock(t *testing.T) {
|
func TestSysLockerDAO_Lock(t *testing.T) {
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
|
|
||||||
isOk, err := SharedSysLockerDAO.Lock(tx, "test", 600)
|
var dao = NewSysLockerDAO()
|
||||||
|
|
||||||
|
isOk, err := dao.Lock(tx, "test", 600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Log(isOk)
|
t.Log(isOk)
|
||||||
|
|
||||||
if isOk {
|
if isOk {
|
||||||
err = SharedSysLockerDAO.Unlock(tx, "test")
|
err = dao.Unlock(tx, "test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSysLocker_Increase_SQL(t *testing.T) {
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
value, err := dao.Read(nil, "hello")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("before:", value)
|
||||||
|
v, err := dao.Increase(nil, "hello", 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Log("err:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Log("after:", v)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSysLocker_Increase(t *testing.T) {
|
func TestSysLocker_Increase(t *testing.T) {
|
||||||
count := 100
|
dbs.NotifyReady()
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
|
var count = 1000
|
||||||
|
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
value, err := dao.Read(nil, "hello")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("before", value)
|
||||||
|
|
||||||
|
var locker = sync.Mutex{}
|
||||||
|
var allValueMap = map[int64]bool{}
|
||||||
|
|
||||||
|
var before = time.Now()
|
||||||
|
|
||||||
|
var wg = sync.WaitGroup{}
|
||||||
wg.Add(count)
|
wg.Add(count)
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
go func() {
|
go func(i int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
v, err := NewSysLockerDAO().Increase(nil, "hello", 0)
|
|
||||||
|
var key = "hello"
|
||||||
|
v, err := dao.Increase(nil, key, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log("err:", err)
|
t.Log("err:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.Log("v:", v)
|
|
||||||
}()
|
locker.Lock()
|
||||||
|
if allValueMap[v] {
|
||||||
|
t.Log("duplicated:", v)
|
||||||
|
} else {
|
||||||
|
allValueMap[v] = true
|
||||||
|
}
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
//t.Log("v:", v)
|
||||||
|
_ = v
|
||||||
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
t.Log("ok")
|
|
||||||
|
t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
|
||||||
|
|
||||||
|
value, err = dao.Read(nil, "hello")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("after", value, "values:", len(allValueMap))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSysLocker_Increase_Performance(t *testing.T) {
|
||||||
|
dbs.NotifyReady()
|
||||||
|
|
||||||
|
var count = 1000
|
||||||
|
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
|
||||||
|
var before = time.Now()
|
||||||
|
|
||||||
|
var wg = sync.WaitGroup{}
|
||||||
|
wg.Add(count)
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
go func(i int) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
var key = "hello" + types.String(i%10)
|
||||||
|
v, err := dao.Increase(nil, key, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Log("err:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//t.Log("v:", v)
|
||||||
|
_ = v
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSysLockerDAO_Increase(b *testing.B) {
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
_, _ = dao.Increase(nil, "hello", 0)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
_, err := dao.Increase(nil, "hello", 0)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,3 +262,20 @@ func (this *SysSettingDAO) ReadUserRegisterConfig(tx *dbs.Tx) (*userconfigs.User
|
|||||||
}
|
}
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *SysSettingDAO) ReadDatabaseConfig(tx *dbs.Tx) (config *systemconfigs.DatabaseConfig, err error) {
|
||||||
|
valueJSON, err := this.ReadSetting(tx, systemconfigs.SettingCodeDatabaseConfigSetting)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(valueJSON) == 0 {
|
||||||
|
return systemconfigs.NewDatabaseConfig(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
config = systemconfigs.NewDatabaseConfig()
|
||||||
|
err = json.Unmarshal(valueJSON, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedUserBandwidthStatDAO.Clean(nil)
|
err := SharedUserBandwidthStatDAO.CleanDefaultDays(nil, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("SharedUserBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("SharedUserBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -460,9 +460,9 @@ func (this *UserBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, userId int64, regionI
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理过期数据
|
// CleanDays 清理过期数据
|
||||||
func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
func (this *UserBandwidthStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days)) // 保留大约3个月的数据
|
||||||
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Table(table).
|
Table(table).
|
||||||
@@ -472,6 +472,22 @@ func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *UserBandwidthStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.UserBandwidthStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.UserBandwidthStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|
||||||
// 批量执行
|
// 批量执行
|
||||||
func (this *UserBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
func (this *UserBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
||||||
var locker = &sync.Mutex{}
|
var locker = &sync.Mutex{}
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ func TestUserBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
|
|||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUserBandwidthStatDAO_Clean(t *testing.T) {
|
func TestUserBandwidthStatDAO_CleanDays(t *testing.T) {
|
||||||
var dao = models.NewUserBandwidthStatDAO()
|
var dao = models.NewUserBandwidthStatDAO()
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
err := dao.Clean(tx)
|
err := dao.CleanDays(tx, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,42 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserField_Id dbs.FieldName = "id" // ID
|
||||||
|
UserField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
UserField_Username dbs.FieldName = "username" // 用户名
|
||||||
|
UserField_Password dbs.FieldName = "password" // 密码
|
||||||
|
UserField_Fullname dbs.FieldName = "fullname" // 真实姓名
|
||||||
|
UserField_Mobile dbs.FieldName = "mobile" // 手机号
|
||||||
|
UserField_VerifiedMobile dbs.FieldName = "verifiedMobile" // 已验证手机号
|
||||||
|
UserField_Tel dbs.FieldName = "tel" // 联系电话
|
||||||
|
UserField_Remark dbs.FieldName = "remark" // 备注
|
||||||
|
UserField_Email dbs.FieldName = "email" // 邮箱地址
|
||||||
|
UserField_VerifiedEmail dbs.FieldName = "verifiedEmail" // 激活后的邮箱
|
||||||
|
UserField_EmailIsVerified dbs.FieldName = "emailIsVerified" // 邮箱是否已验证
|
||||||
|
UserField_AvatarFileId dbs.FieldName = "avatarFileId" // 头像文件ID
|
||||||
|
UserField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
UserField_Day dbs.FieldName = "day" // YYYYMMDD
|
||||||
|
UserField_UpdatedAt dbs.FieldName = "updatedAt" // 修改时间
|
||||||
|
UserField_State dbs.FieldName = "state" // 状态
|
||||||
|
UserField_Source dbs.FieldName = "source" // 来源
|
||||||
|
UserField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||||
|
UserField_Features dbs.FieldName = "features" // 允许操作的特征
|
||||||
|
UserField_RegisteredIP dbs.FieldName = "registeredIP" // 注册使用的IP
|
||||||
|
UserField_IsRejected dbs.FieldName = "isRejected" // 是否已拒绝
|
||||||
|
UserField_RejectReason dbs.FieldName = "rejectReason" // 拒绝理由
|
||||||
|
UserField_IsVerified dbs.FieldName = "isVerified" // 是否验证通过
|
||||||
|
UserField_RequirePlans dbs.FieldName = "requirePlans" // 是否需要购买套餐
|
||||||
|
UserField_Modules dbs.FieldName = "modules" // 用户模块
|
||||||
|
UserField_PriceType dbs.FieldName = "priceType" // 计费类型:traffic|bandwidth
|
||||||
|
UserField_PricePeriod dbs.FieldName = "pricePeriod" // 结算周期
|
||||||
|
UserField_ServersEnabled dbs.FieldName = "serversEnabled" // 是否禁用所有服务
|
||||||
|
UserField_Notification dbs.FieldName = "notification" // 通知设置
|
||||||
|
UserField_BandwidthAlgo dbs.FieldName = "bandwidthAlgo" // 带宽算法
|
||||||
|
UserField_BandwidthModifier dbs.FieldName = "bandwidthModifier" // 带宽修正值
|
||||||
|
UserField_Lang dbs.FieldName = "lang" // 语言代号
|
||||||
|
)
|
||||||
|
|
||||||
// User 用户
|
// User 用户
|
||||||
type User struct {
|
type User struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -36,6 +72,7 @@ type User struct {
|
|||||||
Notification dbs.JSON `field:"notification"` // 通知设置
|
Notification dbs.JSON `field:"notification"` // 通知设置
|
||||||
BandwidthAlgo string `field:"bandwidthAlgo"` // 带宽算法
|
BandwidthAlgo string `field:"bandwidthAlgo"` // 带宽算法
|
||||||
BandwidthModifier float64 `field:"bandwidthModifier"` // 带宽修正值
|
BandwidthModifier float64 `field:"bandwidthModifier"` // 带宽修正值
|
||||||
|
Lang string `field:"lang"` // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserOperator struct {
|
type UserOperator struct {
|
||||||
@@ -71,6 +108,7 @@ type UserOperator struct {
|
|||||||
Notification any // 通知设置
|
Notification any // 通知设置
|
||||||
BandwidthAlgo any // 带宽算法
|
BandwidthAlgo any // 带宽算法
|
||||||
BandwidthModifier any // 带宽修正值
|
BandwidthModifier any // 带宽修正值
|
||||||
|
Lang any // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserOperator() *UserOperator {
|
func NewUserOperator() *UserOperator {
|
||||||
|
|||||||
@@ -80,3 +80,12 @@ func CheckSQLDuplicateErr(err error) bool {
|
|||||||
}
|
}
|
||||||
return CheckSQLErrCode(err, 1062)
|
return CheckSQLErrCode(err, 1062)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsMySQLError Check error is MySQLError
|
||||||
|
func IsMySQLError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, ok := err.(*mysql.MySQLError)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
package dbutils
|
package dbutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
executils "github.com/TeaOSLab/EdgeAPI/internal/utils/exec"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/lists"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewQuery 构造Query
|
// NewQuery 构造Query
|
||||||
@@ -127,3 +135,79 @@ func MySQLVersionFrom8() (bool, error) {
|
|||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindMySQLPath find out mysqld_safe path from system processes
|
||||||
|
func FindMySQLPath() string {
|
||||||
|
psExe, err := executils.LookPath("ps")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var cmd = executils.NewTimeoutCmd(3*time.Second, psExe, "-ef").
|
||||||
|
WithStdout().
|
||||||
|
WithStderr()
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var reg = regexp.MustCompile(`\s(/\S+/mysqld_safe)\s`)
|
||||||
|
var matches = reg.FindStringSubmatch(cmd.Stdout())
|
||||||
|
if len(matches) > 1 {
|
||||||
|
var path = matches[1]
|
||||||
|
_, err = os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindMySQLPathAndRemember find out mysqld_safe path then remember it for future usage
|
||||||
|
func FindMySQLPathAndRemember() {
|
||||||
|
var path = FindMySQLPath()
|
||||||
|
if len(path) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var cacheFile = Tea.Root + "/data/mysql-path.cache"
|
||||||
|
_ = os.WriteFile(cacheFile, []byte(path), 0666) // ignore error
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartLocalMySQL try to start local mysql server
|
||||||
|
func StartLocalMySQL() {
|
||||||
|
// possible installed paths
|
||||||
|
var mysqldSafeFiles = []string{}
|
||||||
|
|
||||||
|
// read last path from cache file
|
||||||
|
var cacheFile = Tea.Root + "/data/mysql-path.cache"
|
||||||
|
cacheData, err := os.ReadFile(cacheFile)
|
||||||
|
if err == nil && len(cacheData) > 0 {
|
||||||
|
mysqldSafeFiles = append(mysqldSafeFiles, string(cacheData))
|
||||||
|
}
|
||||||
|
|
||||||
|
// from $PATH variable
|
||||||
|
exePath, lookErr := executils.LookPath("mysqld_safe")
|
||||||
|
if lookErr == nil && len(exePath) > 0 && !lists.ContainsString(mysqldSafeFiles, exePath) {
|
||||||
|
mysqldSafeFiles = append(mysqldSafeFiles, exePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// these installed by edge-boot or foolish-mysql
|
||||||
|
for _, path := range []string{
|
||||||
|
"/usr/local/mysql/bin/mysqld_safe",
|
||||||
|
"/usr/local/mysql8/bin/mysqld_safe",
|
||||||
|
} {
|
||||||
|
if !lists.ContainsString(mysqldSafeFiles, path) {
|
||||||
|
mysqldSafeFiles = append(mysqldSafeFiles, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mysqldSafeFile := range mysqldSafeFiles {
|
||||||
|
_, err := os.Stat(mysqldSafeFile)
|
||||||
|
if err == nil {
|
||||||
|
logs.Println("[API_NODE]try to start local mysql server from '" + mysqldSafeFile + "' ...")
|
||||||
|
var mysqlCmd = exec.Command(mysqldSafeFile)
|
||||||
|
_ = mysqlCmd.Start()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,3 +35,11 @@ func TestMySQLVersion(t *testing.T) {
|
|||||||
func TestMySQLVersionFrom8(t *testing.T) {
|
func TestMySQLVersionFrom8(t *testing.T) {
|
||||||
t.Log(dbutils.MySQLVersionFrom8())
|
t.Log(dbutils.MySQLVersionFrom8())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindMySQLPath(t *testing.T) {
|
||||||
|
t.Log(dbutils.FindMySQLPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStartLocalMySQL(t *testing.T) {
|
||||||
|
dbutils.StartLocalMySQL()
|
||||||
|
}
|
||||||
@@ -37,8 +37,8 @@ func (this *Unzip) Run() error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
for _, file := range reader.File {
|
for _, file := range reader.File {
|
||||||
info := file.FileInfo()
|
var info = file.FileInfo()
|
||||||
target := this.targetDir + "/" + file.Name
|
var target = this.targetDir + "/" + file.Name
|
||||||
|
|
||||||
// 目录
|
// 目录
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
@@ -62,7 +62,7 @@ func (this *Unzip) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 文件
|
// 文件
|
||||||
err := func(file *zip.File, target string) error {
|
err = func(file *zip.File, target string) error {
|
||||||
fileReader, err := file.Open()
|
fileReader, err := file.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -71,6 +71,10 @@ func (this *Unzip) Run() error {
|
|||||||
_ = fileReader.Close()
|
_ = fileReader.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// remove old
|
||||||
|
_ = os.Remove(target)
|
||||||
|
|
||||||
|
// create new
|
||||||
fileWriter, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, file.FileInfo().Mode())
|
fileWriter, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, file.FileInfo().Mode())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -295,6 +295,9 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err
|
|||||||
func (this *APINode) checkDB() error {
|
func (this *APINode) checkDB() error {
|
||||||
logs.Println("[API_NODE]checking database connection ...")
|
logs.Println("[API_NODE]checking database connection ...")
|
||||||
|
|
||||||
|
// lookup mysqld_safe process
|
||||||
|
go dbutils.FindMySQLPathAndRemember()
|
||||||
|
|
||||||
db, err := dbs.Default()
|
db, err := dbs.Default()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -311,13 +314,7 @@ func (this *APINode) checkDB() error {
|
|||||||
if strings.Contains(err.Error(), "connection refused") {
|
if strings.Contains(err.Error(), "connection refused") {
|
||||||
config, _ := db.Config()
|
config, _ := db.Config()
|
||||||
if config != nil && (strings.Contains(config.Dsn, "tcp(127.0.0.1:") || strings.Contains(config.Dsn, "tcp(localhost:")) && os.Getgid() == 0 /** ROOT 用户 **/ {
|
if config != nil && (strings.Contains(config.Dsn, "tcp(127.0.0.1:") || strings.Contains(config.Dsn, "tcp(localhost:")) && os.Getgid() == 0 /** ROOT 用户 **/ {
|
||||||
var mysqldSafeFile = "/usr/local/mysql/bin/mysqld_safe"
|
dbutils.StartLocalMySQL()
|
||||||
_, err = os.Stat(mysqldSafeFile)
|
|
||||||
if err == nil {
|
|
||||||
logs.Println("[API_NODE]try to start local mysql server from '" + mysqldSafeFile + "' ...")
|
|
||||||
var mysqlCmd = exec.Command(mysqldSafeFile)
|
|
||||||
_ = mysqlCmd.Start()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,7 +832,7 @@ func (this *APINode) unaryInterceptor(ctx context.Context, req any, info *grpc.U
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
statusErr, ok := status.FromError(err)
|
statusErr, ok := status.FromError(err)
|
||||||
if ok {
|
if ok {
|
||||||
err = status.Error(statusErr.Code(), "'" + info.FullMethod + "()' says: " + err.Error())
|
err = status.Error(statusErr.Code(), "'"+info.FullMethod+"()' says: "+err.Error())
|
||||||
} else {
|
} else {
|
||||||
err = errors.New("'" + info.FullMethod + "()' says: " + err.Error())
|
err = errors.New("'" + info.FullMethod + "()' says: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ func (this *AdminService) FindAllAdminModules(ctx context.Context, req *pb.FindA
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := []*pb.AdminModuleList{}
|
var result = []*pb.AdminModuleList{}
|
||||||
for _, admin := range admins {
|
for _, admin := range admins {
|
||||||
modules := []*systemconfigs.AdminModule{}
|
modules := []*systemconfigs.AdminModule{}
|
||||||
if len(admin.Modules) > 0 {
|
if len(admin.Modules) > 0 {
|
||||||
@@ -292,7 +292,7 @@ func (this *AdminService) FindAllAdminModules(ctx context.Context, req *pb.FindA
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pbModules := []*pb.AdminModule{}
|
var pbModules = []*pb.AdminModule{}
|
||||||
for _, module := range modules {
|
for _, module := range modules {
|
||||||
pbModules = append(pbModules, &pb.AdminModule{
|
pbModules = append(pbModules, &pb.AdminModule{
|
||||||
AllowAll: module.AllowAll,
|
AllowAll: module.AllowAll,
|
||||||
@@ -301,11 +301,12 @@ func (this *AdminService) FindAllAdminModules(ctx context.Context, req *pb.FindA
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
list := &pb.AdminModuleList{
|
var list = &pb.AdminModuleList{
|
||||||
AdminId: int64(admin.Id),
|
AdminId: int64(admin.Id),
|
||||||
IsSuper: admin.IsSuper,
|
IsSuper: admin.IsSuper,
|
||||||
Fullname: admin.Fullname,
|
Fullname: admin.Fullname,
|
||||||
Theme: admin.Theme,
|
Theme: admin.Theme,
|
||||||
|
Lang: admin.Lang,
|
||||||
Modules: pbModules,
|
Modules: pbModules,
|
||||||
}
|
}
|
||||||
result = append(result, list)
|
result = append(result, list)
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ func (this *APINodeService) FindEnabledAPINode(ctx context.Context, req *pb.Find
|
|||||||
|
|
||||||
// FindCurrentAPINodeVersion 获取当前API节点的版本
|
// FindCurrentAPINodeVersion 获取当前API节点的版本
|
||||||
func (this *APINodeService) FindCurrentAPINodeVersion(ctx context.Context, req *pb.FindCurrentAPINodeVersionRequest) (*pb.FindCurrentAPINodeVersionResponse, error) {
|
func (this *APINodeService) FindCurrentAPINodeVersion(ctx context.Context, req *pb.FindCurrentAPINodeVersionRequest) (*pb.FindCurrentAPINodeVersionResponse, error) {
|
||||||
_, _, _, err := rpcutils.ValidateRequest(ctx)
|
role, _, _, err := rpcutils.ValidateRequest(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -249,6 +249,7 @@ func (this *APINodeService) FindCurrentAPINodeVersion(ctx context.Context, req *
|
|||||||
Version: teaconst.Version,
|
Version: teaconst.Version,
|
||||||
Os: runtime.GOOS,
|
Os: runtime.GOOS,
|
||||||
Arch: runtime.GOARCH,
|
Arch: runtime.GOARCH,
|
||||||
|
Role: role,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -303,7 +303,24 @@ func (this *DNSDomainService) SyncDNSDomainData(ctx context.Context, req *pb.Syn
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return this.syncClusterDNS(req)
|
|
||||||
|
var latestVersion = dns.SharedDNSTaskDAO.GenerateVersion()
|
||||||
|
|
||||||
|
resp, err := this.syncClusterDNS(req)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记集群所有任务已完成
|
||||||
|
if req.NodeClusterId > 0 && resp != nil && resp.IsOk {
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = dns.SharedDNSTaskDAO.UpdateClusterDNSTasksDone(tx, req.NodeClusterId, latestVersion)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllDNSDomainRoutes 查看支持的线路
|
// FindAllDNSDomainRoutes 查看支持的线路
|
||||||
|
|||||||
@@ -117,3 +117,19 @@ func (this *DNSTaskService) DeleteDNSTask(ctx context.Context, req *pb.DeleteDNS
|
|||||||
}
|
}
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllDNSTasks 删除所有同步任务
|
||||||
|
func (this *DNSTaskService) DeleteAllDNSTasks(ctx context.Context, req *pb.DeleteAllDNSTasksRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = dns.SharedDNSTaskDAO.DeleteAllDNSTasks(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ func (this *HTTPCachePolicyService) CreateHTTPCachePolicy(ctx context.Context, r
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
policyId, err := models.SharedHTTPCachePolicyDAO.CreateCachePolicy(tx, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxKeys, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
policyId, err := models.SharedHTTPCachePolicyDAO.CreateCachePolicy(tx, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ func (this *HTTPCachePolicyService) UpdateHTTPCachePolicy(ctx context.Context, r
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedHTTPCachePolicyDAO.UpdateCachePolicy(tx, req.HttpCachePolicyId, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxKeys, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
err = models.SharedHTTPCachePolicyDAO.UpdateCachePolicy(tx, req.HttpCachePolicyId, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ package services
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,6 +25,34 @@ func (this *HTTPPageService) CreateHTTPPage(ctx context.Context, req *pb.CreateH
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// validate
|
||||||
|
const maxURLLength = 512
|
||||||
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
|
switch req.BodyType {
|
||||||
|
case shared.BodyTypeURL:
|
||||||
|
if len(req.Url) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(req.Url) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
req.Body = ""
|
||||||
|
}
|
||||||
|
case shared.BodyTypeHTML:
|
||||||
|
if len(req.Body) > maxBodyLength {
|
||||||
|
return nil, errors.New("'body' too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Url) > maxURLLength { // we keep short url for user experience
|
||||||
|
req.Url = ""
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
||||||
|
}
|
||||||
|
|
||||||
pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -46,6 +77,34 @@ func (this *HTTPPageService) UpdateHTTPPage(ctx context.Context, req *pb.UpdateH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validate
|
||||||
|
const maxURLLength = 512
|
||||||
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
|
switch req.BodyType {
|
||||||
|
case shared.BodyTypeURL:
|
||||||
|
if len(req.Url) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(req.Url) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
req.Body = ""
|
||||||
|
}
|
||||||
|
case shared.BodyTypeHTML:
|
||||||
|
if len(req.Body) > maxBodyLength {
|
||||||
|
return nil, errors.New("'body' too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Url) > maxURLLength { // we keep short url for user experience
|
||||||
|
req.Url = ""
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
||||||
|
}
|
||||||
|
|
||||||
err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ type HTTPRewriteRuleService struct {
|
|||||||
// CreateHTTPRewriteRule 创建重写规则
|
// CreateHTTPRewriteRule 创建重写规则
|
||||||
func (this *HTTPRewriteRuleService) CreateHTTPRewriteRule(ctx context.Context, req *pb.CreateHTTPRewriteRuleRequest) (*pb.CreateHTTPRewriteRuleResponse, error) {
|
func (this *HTTPRewriteRuleService) CreateHTTPRewriteRule(ctx context.Context, req *pb.CreateHTTPRewriteRuleRequest) (*pb.CreateHTTPRewriteRuleResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
rewriteRuleId, err := models.SharedHTTPRewriteRuleDAO.CreateRewriteRule(tx, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
rewriteRuleId, err := models.SharedHTTPRewriteRuleDAO.CreateRewriteRule(tx, userId, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -33,12 +33,18 @@ func (this *HTTPRewriteRuleService) CreateHTTPRewriteRule(ctx context.Context, r
|
|||||||
// UpdateHTTPRewriteRule 修改重写规则
|
// UpdateHTTPRewriteRule 修改重写规则
|
||||||
func (this *HTTPRewriteRuleService) UpdateHTTPRewriteRule(ctx context.Context, req *pb.UpdateHTTPRewriteRuleRequest) (*pb.RPCSuccess, error) {
|
func (this *HTTPRewriteRuleService) UpdateHTTPRewriteRule(ctx context.Context, req *pb.UpdateHTTPRewriteRuleRequest) (*pb.RPCSuccess, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
if userId > 0 {
|
||||||
|
err = models.SharedHTTPRewriteRuleDAO.CheckUserRewriteRule(tx, userId, req.RewriteRuleId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = models.SharedHTTPRewriteRuleDAO.UpdateRewriteRule(tx, req.RewriteRuleId, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
err = models.SharedHTTPRewriteRuleDAO.UpdateRewriteRule(tx, req.RewriteRuleId, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,6 +111,8 @@ func (this *HTTPWebService) UpdateHTTPWeb(ctx context.Context, req *pb.UpdateHTT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.RootJSON = []byte("{}") // 为了安全
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
@@ -139,7 +143,60 @@ func (this *HTTPWebService) UpdateHTTPWebCompression(ctx context.Context, req *p
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedHTTPWebDAO.UpdateWebCompression(tx, req.HttpWebId, req.CompressionJSON)
|
if len(req.CompressionJSON) == 0 {
|
||||||
|
return nil, errors.New("'compressionJSON' should not be empty")
|
||||||
|
}
|
||||||
|
var compressionConfig = &serverconfigs.HTTPCompressionConfig{}
|
||||||
|
err = json.Unmarshal(req.CompressionJSON, compressionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = compressionConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedHTTPWebDAO.UpdateWebCompression(tx, req.HttpWebId, compressionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateHTTPWebOptimization 修改页面优化配置
|
||||||
|
func (this *HTTPWebService) UpdateHTTPWebOptimization(ctx context.Context, req *pb.UpdateHTTPWebOptimizationRequest) (*pb.RPCSuccess, error) {
|
||||||
|
// 校验请求
|
||||||
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if userId > 0 {
|
||||||
|
// 检查用户权限
|
||||||
|
err = models.SharedHTTPWebDAO.CheckUserWeb(nil, userId, req.HttpWebId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
if len(req.OptimizationJSON) == 0 {
|
||||||
|
return nil, errors.New("invalid 'optimizationJSON'")
|
||||||
|
}
|
||||||
|
var optimizationConfig = serverconfigs.NewHTTPPageOptimizationConfig()
|
||||||
|
err = json.Unmarshal(req.OptimizationJSON, optimizationConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = optimizationConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedHTTPWebDAO.UpdateWebOptimization(tx, req.HttpWebId, optimizationConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -292,8 +349,53 @@ func (this *HTTPWebService) UpdateHTTPWebShutdown(ctx context.Context, req *pb.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
var newShutdownJSON = req.ShutdownJSON
|
||||||
|
if len(req.ShutdownJSON) > 0 {
|
||||||
|
const maxURLLength = 512
|
||||||
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
err = models.SharedHTTPWebDAO.UpdateWebShutdown(tx, req.HttpWebId, req.ShutdownJSON)
|
var shutdownConfig = &serverconfigs.HTTPShutdownConfig{}
|
||||||
|
err = json.Unmarshal(req.ShutdownJSON, shutdownConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = shutdownConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("validate config failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
switch shutdownConfig.BodyType {
|
||||||
|
case shared.BodyTypeURL:
|
||||||
|
if len(shutdownConfig.URL) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(shutdownConfig.URL) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(shutdownConfig.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
shutdownConfig.Body = ""
|
||||||
|
}
|
||||||
|
case shared.BodyTypeHTML:
|
||||||
|
if len(shutdownConfig.Body) > maxBodyLength {
|
||||||
|
return nil, errors.New("'body' too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(shutdownConfig.URL) > maxURLLength { // we keep short url for user experience
|
||||||
|
shutdownConfig.URL = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, errors.New("invalid 'bodyType': " + shutdownConfig.BodyType)
|
||||||
|
}
|
||||||
|
|
||||||
|
newShutdownJSON, err = json.Marshal(shutdownConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedHTTPWebDAO.UpdateWebShutdown(tx, req.HttpWebId, newShutdownJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -319,14 +421,23 @@ func (this *HTTPWebService) UpdateHTTPWebPages(ctx context.Context, req *pb.Upda
|
|||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
// 检查配置
|
// 检查配置
|
||||||
var pages = []*serverconfigs.HTTPPageConfig{}
|
|
||||||
err = json.Unmarshal(req.PagesJSON, &pages)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("decode 'pages' failed: " + err.Error())
|
|
||||||
}
|
|
||||||
var newPages = []*serverconfigs.HTTPPageConfig{}
|
var newPages = []*serverconfigs.HTTPPageConfig{}
|
||||||
for _, page := range pages {
|
if len(req.PagesJSON) > 0 {
|
||||||
newPages = append(newPages, &serverconfigs.HTTPPageConfig{Id: page.Id})
|
var pages = []*serverconfigs.HTTPPageConfig{}
|
||||||
|
err = json.Unmarshal(req.PagesJSON, &pages)
|
||||||
|
|
||||||
|
for _, page := range pages {
|
||||||
|
err = page.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("validate page failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset not needed fields, keep "id" reference only
|
||||||
|
page.URL = ""
|
||||||
|
page.Body = ""
|
||||||
|
|
||||||
|
newPages = append(newPages, &serverconfigs.HTTPPageConfig{Id: page.Id})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
newPagesJSON, err := json.Marshal(newPages)
|
newPagesJSON, err := json.Marshal(newPages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ func (this *IPLibraryFileService) CheckCountriesWithIPLibraryFileId(ctx context.
|
|||||||
}
|
}
|
||||||
for _, similarCountry := range similarCountries {
|
for _, similarCountry := range similarCountries {
|
||||||
pbMissingCountry.SimilarCountries = append(pbMissingCountry.SimilarCountries, &pb.RegionCountry{
|
pbMissingCountry.SimilarCountries = append(pbMissingCountry.SimilarCountries, &pb.RegionCountry{
|
||||||
Id: int64(similarCountry.Id),
|
Id: int64(similarCountry.ValueId),
|
||||||
Name: similarCountry.Name,
|
Name: similarCountry.Name,
|
||||||
DisplayName: similarCountry.DisplayName(),
|
DisplayName: similarCountry.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -391,7 +391,7 @@ func (this *IPLibraryFileService) CheckProvincesWithIPLibraryFileId(ctx context.
|
|||||||
|
|
||||||
for _, similarProvince := range similarProvinces {
|
for _, similarProvince := range similarProvinces {
|
||||||
pbMissingProvince.SimilarProvinces = append(pbMissingProvince.SimilarProvinces, &pb.RegionProvince{
|
pbMissingProvince.SimilarProvinces = append(pbMissingProvince.SimilarProvinces, &pb.RegionProvince{
|
||||||
Id: int64(similarProvince.Id),
|
Id: int64(similarProvince.ValueId),
|
||||||
Name: similarProvince.Name,
|
Name: similarProvince.Name,
|
||||||
DisplayName: similarProvince.DisplayName(),
|
DisplayName: similarProvince.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -482,7 +482,7 @@ func (this *IPLibraryFileService) CheckCitiesWithIPLibraryFileId(ctx context.Con
|
|||||||
|
|
||||||
for _, similarCity := range similarCities {
|
for _, similarCity := range similarCities {
|
||||||
pbMissingCity.SimilarCities = append(pbMissingCity.SimilarCities, &pb.RegionCity{
|
pbMissingCity.SimilarCities = append(pbMissingCity.SimilarCities, &pb.RegionCity{
|
||||||
Id: int64(similarCity.Id),
|
Id: int64(similarCity.ValueId),
|
||||||
Name: similarCity.Name,
|
Name: similarCity.Name,
|
||||||
DisplayName: similarCity.DisplayName(),
|
DisplayName: similarCity.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -597,7 +597,7 @@ func (this *IPLibraryFileService) CheckTownsWithIPLibraryFileId(ctx context.Cont
|
|||||||
|
|
||||||
for _, similarTown := range similarTowns {
|
for _, similarTown := range similarTowns {
|
||||||
pbMissingTown.SimilarTowns = append(pbMissingTown.SimilarTowns, &pb.RegionTown{
|
pbMissingTown.SimilarTowns = append(pbMissingTown.SimilarTowns, &pb.RegionTown{
|
||||||
Id: int64(similarTown.Id),
|
Id: int64(similarTown.ValueId),
|
||||||
Name: similarTown.Name,
|
Name: similarTown.Name,
|
||||||
DisplayName: similarTown.DisplayName(),
|
DisplayName: similarTown.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -654,7 +654,7 @@ func (this *IPLibraryFileService) CheckProvidersWithIPLibraryFileId(ctx context.
|
|||||||
}
|
}
|
||||||
for _, similarProvider := range similarProviders {
|
for _, similarProvider := range similarProviders {
|
||||||
pbMissingProvider.SimilarProviders = append(pbMissingProvider.SimilarProviders, &pb.RegionProvider{
|
pbMissingProvider.SimilarProviders = append(pbMissingProvider.SimilarProviders, &pb.RegionProvider{
|
||||||
Id: int64(similarProvider.Id),
|
Id: int64(similarProvider.ValueId),
|
||||||
Name: similarProvider.Name,
|
Name: similarProvider.Name,
|
||||||
DisplayName: similarProvider.DisplayName(),
|
DisplayName: similarProvider.DisplayName(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,7 +24,16 @@ func (this *LogService) CreateLog(ctx context.Context, req *pb.CreateLogRequest)
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedLogDAO.CreateLog(tx, userType, userId, req.Level, req.Description, req.Action, req.Ip)
|
// i18n
|
||||||
|
var langMessageArgs = []any{}
|
||||||
|
if len(req.LangMessageArgsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.LangMessageArgsJSON, &langMessageArgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedLogDAO.CreateLog(tx, userType, userId, req.Level, req.Description, req.Action, req.Ip, langs.MessageCode(req.LangMessageCode), langMessageArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2016,7 +2016,7 @@ func (this *NodeService) FindNodeGlobalServerConfig(ctx context.Context, req *pb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = serverconfigs.DefaultGlobalServerConfig()
|
config = serverconfigs.NewGlobalServerConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
configJSON, err := json.Marshal(config)
|
configJSON, err := json.Marshal(config)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (this *NodeClusterService) CreateNodeCluster(ctx context.Context, req *pb.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 全局服务配置
|
// 全局服务配置
|
||||||
var serverGlobalConfig = serverconfigs.DefaultGlobalServerConfig()
|
var serverGlobalConfig = serverconfigs.NewGlobalServerConfig()
|
||||||
if len(req.GlobalServerConfigJSON) > 0 {
|
if len(req.GlobalServerConfigJSON) > 0 {
|
||||||
err = json.Unmarshal(req.GlobalServerConfigJSON, serverGlobalConfig)
|
err = json.Unmarshal(req.GlobalServerConfigJSON, serverGlobalConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1130,15 +1130,15 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UAM
|
// UAM
|
||||||
|
var uamPolicy = nodeconfigs.NewUAMPolicy()
|
||||||
if models.IsNotNull(cluster.Uam) {
|
if models.IsNotNull(cluster.Uam) {
|
||||||
var uamPolicy = &nodeconfigs.UAMPolicy{}
|
|
||||||
err = json.Unmarshal(cluster.Uam, uamPolicy)
|
err = json.Unmarshal(cluster.Uam, uamPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result.UamIsOn = uamPolicy.IsOn
|
result.UamIsOn = uamPolicy.IsOn
|
||||||
} else {
|
} else {
|
||||||
result.UamIsOn = nodeconfigs.DefaultUAMPolicy.IsOn
|
result.UamIsOn = uamPolicy.IsOn
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP CC
|
// HTTP CC
|
||||||
@@ -1292,7 +1292,7 @@ func (this *NodeClusterService) UpdateNodeClusterUAMPolicy(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var uamPolicy = &nodeconfigs.UAMPolicy{}
|
var uamPolicy = nodeconfigs.NewUAMPolicy()
|
||||||
err = json.Unmarshal(req.UamPolicyJSON, uamPolicy)
|
err = json.Unmarshal(req.UamPolicyJSON, uamPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1444,7 +1444,7 @@ func (this *NodeClusterService) UpdateNodeClusterGlobalServerConfig(ctx context.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = serverconfigs.DefaultGlobalServerConfig()
|
var config = serverconfigs.NewGlobalServerConfig()
|
||||||
err = json.Unmarshal(req.GlobalServerConfigJSON, config)
|
err = json.Unmarshal(req.GlobalServerConfigJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -216,6 +216,22 @@ func (this *NodeTaskService) DeleteNodeTasks(ctx context.Context, req *pb.Delete
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllNodeTasks 删除所有任务
|
||||||
|
func (this *NodeTaskService) DeleteAllNodeTasks(ctx context.Context, req *pb.DeleteAllNodeTasksRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedNodeTaskDAO.DeleteAllNodeTasks(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
// CountDoingNodeTasks 计算正在执行的任务数量
|
// CountDoingNodeTasks 计算正在执行的任务数量
|
||||||
func (this *NodeTaskService) CountDoingNodeTasks(ctx context.Context, req *pb.CountDoingNodeTasksRequest) (*pb.RPCCountResponse, error) {
|
func (this *NodeTaskService) CountDoingNodeTasks(ctx context.Context, req *pb.CountDoingNodeTasksRequest) (*pb.RPCCountResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOrigi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, addrMap.AsJSON(), ossConfig, req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort)
|
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, addrMap.AsJSON(), ossConfig, req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort, req.Http2Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, addrMap.AsJSON(), ossConfig, req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort)
|
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, addrMap.AsJSON(), ossConfig, req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort, req.Http2Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEn
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &pb.Origin{
|
return &pb.FindEnabledOriginResponse{Origin: &pb.Origin{
|
||||||
Id: int64(origin.Id),
|
Id: int64(origin.Id),
|
||||||
IsOn: origin.IsOn,
|
IsOn: origin.IsOn,
|
||||||
Name: origin.Name,
|
Name: origin.Name,
|
||||||
@@ -213,10 +213,11 @@ func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEn
|
|||||||
Host: addr.Host,
|
Host: addr.Host,
|
||||||
PortRange: addr.PortRange,
|
PortRange: addr.PortRange,
|
||||||
},
|
},
|
||||||
Description: origin.Description,
|
Description: origin.Description,
|
||||||
Domains: origin.DecodeDomains(),
|
Domains: origin.DecodeDomains(),
|
||||||
}
|
FollowPort: origin.FollowPort,
|
||||||
return &pb.FindEnabledOriginResponse{Origin: result}, nil
|
Http2Enabled: origin.Http2Enabled,
|
||||||
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindEnabledOriginConfig 查找源站配置
|
// FindEnabledOriginConfig 查找源站配置
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (this *RegionCityService) FindAllEnabledRegionCities(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbProvince = &pb.RegionProvince{
|
pbProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
DisplayName: province.DisplayName(),
|
DisplayName: province.DisplayName(),
|
||||||
@@ -57,7 +57,7 @@ func (this *RegionCityService) FindAllEnabledRegionCities(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbCities = append(pbCities, &pb.RegionCity{
|
pbCities = append(pbCities, &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -108,7 +108,7 @@ func (this *RegionCityService) FindAllRegionCities(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbProvince = &pb.RegionProvince{
|
pbProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -118,7 +118,7 @@ func (this *RegionCityService) FindAllRegionCities(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbCities = append(pbCities, &pb.RegionCity{
|
pbCities = append(pbCities, &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -155,7 +155,7 @@ func (this *RegionCityService) FindAllRegionCitiesWithRegionProvinceId(ctx conte
|
|||||||
var pbProvince = &pb.RegionProvince{Id: provinceId}
|
var pbProvince = &pb.RegionProvince{Id: provinceId}
|
||||||
|
|
||||||
pbCities = append(pbCities, &pb.RegionCity{
|
pbCities = append(pbCities, &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -192,7 +192,7 @@ func (this *RegionCityService) FindEnabledRegionCity(ctx context.Context, req *p
|
|||||||
|
|
||||||
return &pb.FindEnabledRegionCityResponse{
|
return &pb.FindEnabledRegionCityResponse{
|
||||||
RegionCity: &pb.RegionCity{
|
RegionCity: &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -223,7 +223,7 @@ func (this *RegionCityService) FindRegionCity(ctx context.Context, req *pb.FindR
|
|||||||
|
|
||||||
return &pb.FindRegionCityResponse{
|
return &pb.FindRegionCityResponse{
|
||||||
RegionCity: &pb.RegionCity{
|
RegionCity: &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
|
|||||||
@@ -40,13 +40,14 @@ func (this *RegionCountryService) FindAllEnabledRegionCountries(ctx context.Cont
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, &pb.RegionCountry{
|
result = append(result, &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
Pinyin: pinyinStrings,
|
Pinyin: pinyinStrings,
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
CustomCodes: country.DecodeCustomCodes(),
|
CustomCodes: country.DecodeCustomCodes(),
|
||||||
DisplayName: country.DisplayName(),
|
DisplayName: country.DisplayName(),
|
||||||
|
IsCommon: country.IsCommon,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &pb.FindAllEnabledRegionCountriesResponse{
|
return &pb.FindAllEnabledRegionCountriesResponse{
|
||||||
@@ -74,7 +75,7 @@ func (this *RegionCountryService) FindEnabledRegionCountry(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindEnabledRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
return &pb.FindEnabledRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
@@ -110,13 +111,14 @@ func (this *RegionCountryService) FindAllRegionCountries(ctx context.Context, re
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, &pb.RegionCountry{
|
result = append(result, &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
Pinyin: pinyinStrings,
|
Pinyin: pinyinStrings,
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
CustomCodes: country.DecodeCustomCodes(),
|
CustomCodes: country.DecodeCustomCodes(),
|
||||||
DisplayName: country.DisplayName(),
|
DisplayName: country.DisplayName(),
|
||||||
|
IsCommon: country.IsCommon,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &pb.FindAllRegionCountriesResponse{
|
return &pb.FindAllRegionCountriesResponse{
|
||||||
@@ -143,12 +145,13 @@ func (this *RegionCountryService) FindRegionCountry(ctx context.Context, req *pb
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
return &pb.FindRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
CustomCodes: country.DecodeCustomCodes(),
|
CustomCodes: country.DecodeCustomCodes(),
|
||||||
DisplayName: country.DisplayName(),
|
DisplayName: country.DisplayName(),
|
||||||
|
IsCommon: country.IsCommon,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (this *RegionProviderService) FindAllEnabledRegionProviders(ctx context.Con
|
|||||||
var pbProviders = []*pb.RegionProvider{}
|
var pbProviders = []*pb.RegionProvider{}
|
||||||
for _, provider := range providers {
|
for _, provider := range providers {
|
||||||
pbProviders = append(pbProviders, &pb.RegionProvider{
|
pbProviders = append(pbProviders, &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
@@ -65,7 +65,7 @@ func (this *RegionProviderService) FindEnabledRegionProvider(ctx context.Context
|
|||||||
|
|
||||||
return &pb.FindEnabledRegionProviderResponse{
|
return &pb.FindEnabledRegionProviderResponse{
|
||||||
RegionProvider: &pb.RegionProvider{
|
RegionProvider: &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
@@ -91,7 +91,7 @@ func (this *RegionProviderService) FindAllRegionProviders(ctx context.Context, r
|
|||||||
var pbProviders = []*pb.RegionProvider{}
|
var pbProviders = []*pb.RegionProvider{}
|
||||||
for _, provider := range providers {
|
for _, provider := range providers {
|
||||||
pbProviders = append(pbProviders, &pb.RegionProvider{
|
pbProviders = append(pbProviders, &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
@@ -125,7 +125,7 @@ func (this *RegionProviderService) FindRegionProvider(ctx context.Context, req *
|
|||||||
|
|
||||||
return &pb.FindRegionProviderResponse{
|
return &pb.FindRegionProviderResponse{
|
||||||
RegionProvider: &pb.RegionProvider{
|
RegionProvider: &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func (this *RegionProvinceService) FindAllEnabledRegionProvincesWithCountryId(ct
|
|||||||
result := []*pb.RegionProvince{}
|
result := []*pb.RegionProvince{}
|
||||||
for _, province := range provinces {
|
for _, province := range provinces {
|
||||||
result = append(result, &pb.RegionProvince{
|
result = append(result, &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -64,7 +64,7 @@ func (this *RegionProvinceService) FindEnabledRegionProvince(ctx context.Context
|
|||||||
|
|
||||||
return &pb.FindEnabledRegionProvinceResponse{
|
return &pb.FindEnabledRegionProvinceResponse{
|
||||||
RegionProvince: &pb.RegionProvince{
|
RegionProvince: &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -91,7 +91,7 @@ func (this *RegionProvinceService) FindAllRegionProvincesWithRegionCountryId(ctx
|
|||||||
var result = []*pb.RegionProvince{}
|
var result = []*pb.RegionProvince{}
|
||||||
for _, province := range provinces {
|
for _, province := range provinces {
|
||||||
result = append(result, &pb.RegionProvince{
|
result = append(result, &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -125,7 +125,7 @@ func (this *RegionProvinceService) FindRegionProvince(ctx context.Context, req *
|
|||||||
|
|
||||||
return &pb.FindRegionProvinceResponse{
|
return &pb.FindRegionProvinceResponse{
|
||||||
RegionProvince: &pb.RegionProvince{
|
RegionProvince: &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func (this *RegionTownService) FindAllRegionTowns(ctx context.Context, req *pb.F
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbCity = &pb.RegionCity{
|
pbCity = &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
CustomName: city.CustomName,
|
CustomName: city.CustomName,
|
||||||
@@ -58,7 +58,7 @@ func (this *RegionTownService) FindAllRegionTowns(ctx context.Context, req *pb.F
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbTowns = append(pbTowns, &pb.RegionTown{
|
pbTowns = append(pbTowns, &pb.RegionTown{
|
||||||
Id: int64(town.Id),
|
Id: int64(town.ValueId),
|
||||||
Name: town.Name,
|
Name: town.Name,
|
||||||
Codes: town.DecodeCodes(),
|
Codes: town.DecodeCodes(),
|
||||||
RegionCityId: int64(town.CityId),
|
RegionCityId: int64(town.CityId),
|
||||||
@@ -95,7 +95,7 @@ func (this *RegionTownService) FindAllRegionTownsWithRegionCityId(ctx context.Co
|
|||||||
var pbCity = &pb.RegionCity{Id: cityId}
|
var pbCity = &pb.RegionCity{Id: cityId}
|
||||||
|
|
||||||
pbTowns = append(pbTowns, &pb.RegionTown{
|
pbTowns = append(pbTowns, &pb.RegionTown{
|
||||||
Id: int64(town.Id),
|
Id: int64(town.ValueId),
|
||||||
Name: town.Name,
|
Name: town.Name,
|
||||||
Codes: town.DecodeCodes(),
|
Codes: town.DecodeCodes(),
|
||||||
RegionCityId: int64(town.CityId),
|
RegionCityId: int64(town.CityId),
|
||||||
@@ -131,7 +131,7 @@ func (this *RegionTownService) FindRegionTown(ctx context.Context, req *pb.FindR
|
|||||||
|
|
||||||
return &pb.FindRegionTownResponse{
|
return &pb.FindRegionTownResponse{
|
||||||
RegionTown: &pb.RegionTown{
|
RegionTown: &pb.RegionTown{
|
||||||
Id: int64(town.Id),
|
Id: int64(town.ValueId),
|
||||||
Name: town.Name,
|
Name: town.Name,
|
||||||
Codes: town.DecodeCodes(),
|
Codes: town.DecodeCodes(),
|
||||||
RegionCityId: int64(town.CityId),
|
RegionCityId: int64(town.CityId),
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ func (this *ServerService) CreateBasicHTTPServer(ctx context.Context, req *pb.Cr
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, req.UserId, "", addrJSON, nil, "", 10, true, nil, nil, nil, 0, 0, nil, nil, u.Host, false)
|
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, req.UserId, "", addrJSON, nil, "", 10, true, nil, nil, nil, 0, 0, nil, nil, u.Host, false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -651,7 +651,7 @@ func (this *ServerService) CreateBasicTCPServer(ctx context.Context, req *pb.Cre
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, req.UserId, "", addrJSON, nil, "", 10, true, nil, nil, nil, 0, 0, nil, nil, "", false)
|
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, req.UserId, "", addrJSON, nil, "", 10, true, nil, nil, nil, 0, 0, nil, nil, "", false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1301,6 +1301,14 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
order = "trafficOutAsc"
|
order = "trafficOutAsc"
|
||||||
} else if req.TrafficOutDesc {
|
} else if req.TrafficOutDesc {
|
||||||
order = "trafficOutDesc"
|
order = "trafficOutDesc"
|
||||||
|
} else if req.RequestsAsc {
|
||||||
|
order = "requestsAsc"
|
||||||
|
} else if req.RequestsDesc {
|
||||||
|
order = "requestsDesc"
|
||||||
|
} else if req.AttackRequestsAsc {
|
||||||
|
order = "attackRequestsAsc"
|
||||||
|
} else if req.AttackRequestsDesc {
|
||||||
|
order = "attackRequestsDesc"
|
||||||
}
|
}
|
||||||
|
|
||||||
servers, err := models.SharedServerDAO.ListEnabledServersMatch(tx, req.Offset, req.Size, req.ServerGroupId, req.Keyword, req.UserId, req.NodeClusterId, req.AuditingFlag, utils.SplitStrings(req.ProtocolFamily, ","), order)
|
servers, err := models.SharedServerDAO.ListEnabledServersMatch(tx, req.Offset, req.Size, req.ServerGroupId, req.Keyword, req.UserId, req.NodeClusterId, req.AuditingFlag, utils.SplitStrings(req.ProtocolFamily, ","), order)
|
||||||
@@ -1418,11 +1426,13 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
Id: int64(server.ClusterId),
|
Id: int64(server.ClusterId),
|
||||||
Name: clusterName,
|
Name: clusterName,
|
||||||
},
|
},
|
||||||
ServerGroups: pbGroups,
|
ServerGroups: pbGroups,
|
||||||
UserId: int64(server.UserId),
|
UserId: int64(server.UserId),
|
||||||
User: pbUser,
|
User: pbUser,
|
||||||
BandwidthTime: server.BandwidthTime,
|
BandwidthTime: server.BandwidthTime,
|
||||||
BandwidthBytes: int64(server.BandwidthBytes),
|
BandwidthBytes: int64(server.BandwidthBytes),
|
||||||
|
CountRequests: int64(server.CountRequests),
|
||||||
|
CountAttackRequests: int64(server.CountAttackRequests),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ func init() {
|
|||||||
for _, stat := range m {
|
for _, stat := range m {
|
||||||
// 更新服务的带宽峰值
|
// 更新服务的带宽峰值
|
||||||
if stat.ServerId > 0 {
|
if stat.ServerId > 0 {
|
||||||
err := models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests)
|
err = models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
|
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedServerDAO.UpdateServerBandwidth(tx, stat.ServerId, stat.Day+stat.TimeAt, stat.Bytes)
|
err = models.SharedServerDAO.UpdateServerBandwidth(tx, stat.ServerId, stat.Day+stat.TimeAt, stat.Bytes, stat.CountRequests, stat.CountAttackRequests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("ServerBandwidthStatService", "update server bandwidth failed: "+err.Error())
|
remotelogs.Error("ServerBandwidthStatService", "update server bandwidth failed: "+err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,6 +483,7 @@ func (this *ServerGroupService) FindEnabledServerGroupConfigInfo(ctx context.Con
|
|||||||
result.HasAccessLogConfig = webConfig != nil && webConfig.AccessLogRef != nil && webConfig.AccessLogRef.IsPrior
|
result.HasAccessLogConfig = webConfig != nil && webConfig.AccessLogRef != nil && webConfig.AccessLogRef.IsPrior
|
||||||
result.HasStatConfig = webConfig != nil && webConfig.StatRef != nil && webConfig.StatRef.IsPrior
|
result.HasStatConfig = webConfig != nil && webConfig.StatRef != nil && webConfig.StatRef.IsPrior
|
||||||
result.HasCompressionConfig = webConfig != nil && webConfig.Compression != nil && webConfig.Compression.IsPrior
|
result.HasCompressionConfig = webConfig != nil && webConfig.Compression != nil && webConfig.Compression.IsPrior
|
||||||
|
result.HasOptimizationConfig = webConfig != nil && webConfig.Optimization != nil && webConfig.Optimization.IsPrior
|
||||||
result.HasWebsocketConfig = webConfig != nil && webConfig.WebsocketRef != nil && webConfig.WebsocketRef.IsPrior
|
result.HasWebsocketConfig = webConfig != nil && webConfig.WebsocketRef != nil && webConfig.WebsocketRef.IsPrior
|
||||||
result.HasRequestHeadersConfig = webConfig != nil && webConfig.RequestHeaderPolicyRef != nil && webConfig.RequestHeaderPolicyRef.IsPrior
|
result.HasRequestHeadersConfig = webConfig != nil && webConfig.RequestHeaderPolicyRef != nil && webConfig.RequestHeaderPolicyRef.IsPrior
|
||||||
result.HasResponseHeadersConfig = webConfig != nil && webConfig.ResponseHeaderPolicyRef != nil && webConfig.ResponseHeaderPolicyRef.IsPrior
|
result.HasResponseHeadersConfig = webConfig != nil && webConfig.ResponseHeaderPolicyRef != nil && webConfig.ResponseHeaderPolicyRef.IsPrior
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ func (this *ServerRegionCityMonthlyStatService) FindTopServerRegionCityMonthlySt
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionProvince = &pb.RegionProvince{
|
pbStat.RegionProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.DisplayName(),
|
Name: province.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionCity = &pb.RegionCity{
|
pbStat.RegionCity = &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.DisplayName(),
|
Name: city.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func (this *ServerRegionCountryMonthlyStatService) FindTopServerRegionCountryMon
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func (this *ServerRegionProviderMonthlyStatService) FindTopServerRegionProviderM
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionProvider = &pb.RegionProvider{
|
pbStat.RegionProvider = &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.DisplayName(),
|
Name: provider.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ func (this *ServerRegionProvinceMonthlyStatService) FindTopServerRegionProvinceM
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionProvince = &pb.RegionProvince{
|
pbStat.RegionProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.DisplayName(),
|
Name: province.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnable
|
|||||||
IsEnterpriseIdentified: isEnterpriseIdentified,
|
IsEnterpriseIdentified: isEnterpriseIdentified,
|
||||||
BandwidthAlgo: user.BandwidthAlgo,
|
BandwidthAlgo: user.BandwidthAlgo,
|
||||||
OtpLogin: pbOtpAuth,
|
OtpLogin: pbOtpAuth,
|
||||||
|
Lang: user.Lang,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,13 @@ func (this *Setup) Run() error {
|
|||||||
}
|
}
|
||||||
for _, db := range config.DBs {
|
for _, db := range config.DBs {
|
||||||
// 可以同时运行多条语句
|
// 可以同时运行多条语句
|
||||||
db.Dsn += "&multiStatements=true"
|
if !strings.Contains(db.Dsn, "multiStatements=") {
|
||||||
|
if strings.Contains(db.Dsn, "?") {
|
||||||
|
db.Dsn += "&multiStatements=true"
|
||||||
|
} else {
|
||||||
|
db.Dsn += "?multiStatements=true"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dbConfig, ok := config.DBs[Tea.Env]
|
dbConfig, ok := config.DBs[Tea.Env]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
19357
internal/setup/sql.json
19357
internal/setup/sql.json
File diff suppressed because it is too large
Load Diff
@@ -87,14 +87,8 @@ func (this *SQLExecutor) Run(showLog bool) error {
|
|||||||
|
|
||||||
// 检查数据
|
// 检查数据
|
||||||
func (this *SQLExecutor) checkData(db *dbs.DB) error {
|
func (this *SQLExecutor) checkData(db *dbs.DB) error {
|
||||||
// 检查初始化用户
|
|
||||||
err := this.checkUser(db)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查管理员平台节点
|
// 检查管理员平台节点
|
||||||
err = this.checkAdminNode(db)
|
err := this.checkAdminNode(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -111,6 +105,13 @@ func (this *SQLExecutor) checkData(db *dbs.DB) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查初始化用户
|
||||||
|
// 需要放在检查集群后面
|
||||||
|
err = this.checkUser(db)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// 检查IP名单
|
// 检查IP名单
|
||||||
err = this.checkIPList(db)
|
err = this.checkIPList(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -154,7 +155,14 @@ func (this *SQLExecutor) checkUser(db *dbs.DB) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Exec("INSERT INTO edgeUsers (`username`, `password`, `fullname`, `isOn`, `state`, `createdAt`) VALUES (?, ?, ?, ?, ?, ?)", "USER-"+rands.HexString(10), stringutil.Md5(rands.HexString(32)), "默认用户", 1, 1, time.Now().Unix())
|
// 读取默认集群ID
|
||||||
|
// Read default cluster id
|
||||||
|
clusterId, err := db.FindCol(0, "SELECT id FROM edgeNodeClusters WHERE state=1 ORDER BY id ASC LIMIT 1")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec("INSERT INTO edgeUsers (`username`, `password`, `fullname`, `isOn`, `state`, `createdAt`, `clusterId`) VALUES (?, ?, ?, ?, ?, ?, ?)", "USER_"+rands.HexString(10), stringutil.Md5(rands.HexString(32)), "默认用户", 1, 1, time.Now().Unix(), clusterId)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type upgradeVersion struct {
|
type upgradeVersion struct {
|
||||||
@@ -91,6 +92,9 @@ var upgradeFuncs = []*upgradeVersion{
|
|||||||
{
|
{
|
||||||
"0.5.8", upgradeV0_5_8,
|
"0.5.8", upgradeV0_5_8,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"1.2.1", upgradeV1_2_1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpgradeSQLData 升级SQL数据
|
// UpgradeSQLData 升级SQL数据
|
||||||
@@ -536,7 +540,7 @@ func upgradeV0_4_1(db *dbs.DB) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 执行域名统计清理
|
// 执行域名统计清理
|
||||||
err = stats.NewServerDomainHourlyStatDAO().Clean(nil, 7)
|
err = stats.NewServerDomainHourlyStatDAO().CleanDays(nil, 7)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -719,3 +723,32 @@ func upgradeV0_4_11(db *dbs.DB) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// v1.2.1
|
||||||
|
func upgradeV1_2_1(db *dbs.DB) error {
|
||||||
|
// upgrade generated USER-xxx in old versions
|
||||||
|
ones, _, err := db.FindOnes("SELECT id, username, clusterId FROM edgeUsers WHERE username LIKE 'USER-%'")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, one := range ones {
|
||||||
|
var userId = one.GetInt64("id")
|
||||||
|
var clusterId = one.GetInt64("clusterId")
|
||||||
|
var username = one.GetString("username")
|
||||||
|
if clusterId <= 0 {
|
||||||
|
defaultClusterIdValue, err := db.FindCol(0, "SELECT id FROM edgeNodeClusters WHERE state=1 ORDER BY id ASC LIMIT 1")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultClusterId = types.Int64(defaultClusterIdValue)
|
||||||
|
if defaultClusterId > 0 {
|
||||||
|
_, err = db.Exec("UPDATE edgeUsers SET username=?, clusterId=? WHERE id=?", strings.ReplaceAll(username, "-", "_"), defaultClusterId, userId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -252,3 +252,23 @@ func TestUpgradeSQLData_v0_5_3(t *testing.T) {
|
|||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpgradeSQLData_v1_2_1(t *testing.T) {
|
||||||
|
db, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
|
||||||
|
Driver: "mysql",
|
||||||
|
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge?charset=utf8mb4&timeout=30s",
|
||||||
|
Prefix: "edge",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = db.Close()
|
||||||
|
}()
|
||||||
|
err = upgradeV1_2_1(db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func (this *ServerAccessLogCleaner) Loop() error {
|
|||||||
if len(configJSON) == 0 {
|
if len(configJSON) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var config = &systemconfigs.DatabaseConfig{}
|
var config = systemconfigs.NewDatabaseConfig()
|
||||||
err = json.Unmarshal(configJSON, config)
|
err = json.Unmarshal(configJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
59
internal/utils/exec/look_linux.go
Normal file
59
internal/utils/exec/look_linux.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build linux
|
||||||
|
|
||||||
|
package executils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LookPath customize our LookPath() function, to work in broken $PATH environment variable
|
||||||
|
func LookPath(file string) (string, error) {
|
||||||
|
result, err := exec.LookPath(file)
|
||||||
|
if err == nil && len(result) > 0 {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// add common dirs contains executable files these may be excluded in $PATH environment variable
|
||||||
|
var binPaths = []string{
|
||||||
|
"/usr/sbin",
|
||||||
|
"/usr/bin",
|
||||||
|
"/usr/local/sbin",
|
||||||
|
"/usr/local/bin",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, binPath := range binPaths {
|
||||||
|
var fullPath = binPath + string(os.PathSeparator) + file
|
||||||
|
|
||||||
|
stat, err := os.Stat(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if stat.IsDir() {
|
||||||
|
return "", syscall.EISDIR
|
||||||
|
}
|
||||||
|
|
||||||
|
var mode = stat.Mode()
|
||||||
|
if mode.IsDir() {
|
||||||
|
return "", syscall.EISDIR
|
||||||
|
}
|
||||||
|
err = syscall.Faccessat(unix.AT_FDCWD, fullPath, unix.X_OK, unix.AT_EACCESS)
|
||||||
|
if err == nil || (err != syscall.ENOSYS && err != syscall.EPERM) {
|
||||||
|
return fullPath, err
|
||||||
|
}
|
||||||
|
if mode&0111 != 0 {
|
||||||
|
return fullPath, nil
|
||||||
|
}
|
||||||
|
return "", fs.ErrPermission
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", &exec.Error{
|
||||||
|
Name: file,
|
||||||
|
Err: exec.ErrNotFound,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
10
internal/utils/exec/look_others.go
Normal file
10
internal/utils/exec/look_others.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !linux
|
||||||
|
|
||||||
|
package executils
|
||||||
|
|
||||||
|
import "os/exec"
|
||||||
|
|
||||||
|
func LookPath(file string) (string, error) {
|
||||||
|
return exec.LookPath(file)
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
executils "github.com/TeaOSLab/EdgeAPI/internal/utils/exec"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -14,7 +15,7 @@ func AddPortsToFirewall(ports []int) {
|
|||||||
// Linux
|
// Linux
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
// firewalld
|
// firewalld
|
||||||
firewallCmd, _ := exec.LookPath("firewall-cmd")
|
firewallCmd, _ := executils.LookPath("firewall-cmd")
|
||||||
if len(firewallCmd) > 0 {
|
if len(firewallCmd) > 0 {
|
||||||
err := exec.Command(firewallCmd, "--add-port="+types.String(port)+"/tcp").Run()
|
err := exec.Command(firewallCmd, "--add-port="+types.String(port)+"/tcp").Run()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||||
|
executils "github.com/TeaOSLab/EdgeAPI/internal/utils/exec"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/files"
|
"github.com/iwind/TeaGo/files"
|
||||||
"os"
|
"os"
|
||||||
@@ -15,13 +16,13 @@ import (
|
|||||||
var systemdServiceFile = "/etc/systemd/system/edge-api.service"
|
var systemdServiceFile = "/etc/systemd/system/edge-api.service"
|
||||||
var initServiceFile = "/etc/init.d/" + teaconst.SystemdServiceName
|
var initServiceFile = "/etc/init.d/" + teaconst.SystemdServiceName
|
||||||
|
|
||||||
// 安装服务
|
// Install 安装服务
|
||||||
func (this *ServiceManager) Install(exePath string, args []string) error {
|
func (this *ServiceManager) Install(exePath string, args []string) error {
|
||||||
if os.Getgid() != 0 {
|
if os.Getgid() != 0 {
|
||||||
return errors.New("only root users can install the service")
|
return errors.New("only root users can install the service")
|
||||||
}
|
}
|
||||||
|
|
||||||
systemd, err := exec.LookPath("systemctl")
|
systemd, err := executils.LookPath("systemctl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return this.installInitService(exePath, args)
|
return this.installInitService(exePath, args)
|
||||||
}
|
}
|
||||||
@@ -29,14 +30,14 @@ func (this *ServiceManager) Install(exePath string, args []string) error {
|
|||||||
return this.installSystemdService(systemd, exePath, args)
|
return this.installSystemdService(systemd, exePath, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动服务
|
// Start 启动服务
|
||||||
func (this *ServiceManager) Start() error {
|
func (this *ServiceManager) Start() error {
|
||||||
if os.Getgid() != 0 {
|
if os.Getgid() != 0 {
|
||||||
return errors.New("only root users can start the service")
|
return errors.New("only root users can start the service")
|
||||||
}
|
}
|
||||||
|
|
||||||
if files.NewFile(systemdServiceFile).Exists() {
|
if files.NewFile(systemdServiceFile).Exists() {
|
||||||
systemd, err := exec.LookPath("systemctl")
|
systemd, err := executils.LookPath("systemctl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,7 @@ func (this *ServiceManager) Uninstall() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if files.NewFile(systemdServiceFile).Exists() {
|
if files.NewFile(systemdServiceFile).Exists() {
|
||||||
systemd, err := exec.LookPath("systemctl")
|
systemd, err := executils.LookPath("systemctl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -93,7 +94,7 @@ func (this *ServiceManager) installInitService(exePath string, args []string) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
chkCmd, err := exec.LookPath("chkconfig")
|
chkCmd, err := executils.LookPath("chkconfig")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user