diff --git a/code/allapp/allapp-go-v2/.idea/.gitignore b/code/allapp/allapp-go-v2/.idea/.gitignore
new file mode 100644
index 00000000..13566b81
--- /dev/null
+++ b/code/allapp/allapp-go-v2/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/code/allapp/allapp-go-v2/.idea/allapp-go-v2.iml b/code/allapp/allapp-go-v2/.idea/allapp-go-v2.iml
new file mode 100644
index 00000000..5e764c4f
--- /dev/null
+++ b/code/allapp/allapp-go-v2/.idea/allapp-go-v2.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/allapp/allapp-go-v2/.idea/modules.xml b/code/allapp/allapp-go-v2/.idea/modules.xml
new file mode 100644
index 00000000..c5d6625d
--- /dev/null
+++ b/code/allapp/allapp-go-v2/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/allapp/allapp-go-v2/.idea/vcs.xml b/code/allapp/allapp-go-v2/.idea/vcs.xml
new file mode 100644
index 00000000..c2365ab1
--- /dev/null
+++ b/code/allapp/allapp-go-v2/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/allapp/allapp-go-v2/cmd/main.go b/code/allapp/allapp-go-v2/cmd/main.go
new file mode 100644
index 00000000..24c640c8
--- /dev/null
+++ b/code/allapp/allapp-go-v2/cmd/main.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+ "allapp-go-v2/internal/bootstrap"
+ "allapp-go-v2/internal/server"
+ "log"
+)
+
+func main() {
+ app, err := bootstrap.NewApp()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ if err := server.Start(app); err != nil {
+ log.Fatal(err)
+ }
+
+}
diff --git a/code/allapp/allapp-go-v2/configs/config.dev.yaml b/code/allapp/allapp-go-v2/configs/config.dev.yaml
new file mode 100644
index 00000000..e69de29b
diff --git a/code/allapp/allapp-go-v2/configs/config.prod.yaml b/code/allapp/allapp-go-v2/configs/config.prod.yaml
new file mode 100644
index 00000000..e69de29b
diff --git a/code/allapp/allapp-go-v2/configs/config.yaml b/code/allapp/allapp-go-v2/configs/config.yaml
new file mode 100644
index 00000000..cb757913
--- /dev/null
+++ b/code/allapp/allapp-go-v2/configs/config.yaml
@@ -0,0 +1,14 @@
+app:
+ name: allapp
+
+server:
+ port: 8086
+
+postgres:
+ host: 117.72.182.135
+ port: 5432
+ user: postgres
+ password: zhang520..
+ dbname: app
+ timezone: Asia/Shanghai
+ sll_mode: false
\ No newline at end of file
diff --git a/code/allapp/allapp-go-v2/go.mod b/code/allapp/allapp-go-v2/go.mod
new file mode 100644
index 00000000..7e3d1ced
--- /dev/null
+++ b/code/allapp/allapp-go-v2/go.mod
@@ -0,0 +1,44 @@
+module allapp-go-v2
+
+go 1.25.0
+
+require (
+ github.com/gofiber/fiber/v3 v3.1.0
+ github.com/jackc/pgx/v5 v5.9.1
+ github.com/spf13/viper v1.21.0
+)
+
+require (
+ github.com/andybalholm/brotli v1.2.0 // indirect
+ github.com/fsnotify/fsnotify v1.9.0 // indirect
+ github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
+ github.com/gofiber/schema v1.7.0 // indirect
+ github.com/gofiber/utils/v2 v2.0.2 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/jackc/pgpassfile v1.0.0 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
+ github.com/jackc/puddle/v2 v2.2.2 // indirect
+ github.com/klauspost/compress v1.18.4 // indirect
+ github.com/mattn/go-colorable v0.1.14 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/pelletier/go-toml/v2 v2.2.4 // indirect
+ github.com/philhofer/fwd v1.2.0 // indirect
+ github.com/sagikazarmark/locafero v0.11.0 // indirect
+ github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
+ github.com/spf13/afero v1.15.0 // indirect
+ github.com/spf13/cast v1.10.0 // indirect
+ github.com/spf13/pflag v1.0.10 // indirect
+ github.com/subosito/gotenv v1.6.0 // indirect
+ github.com/tinylib/msgp v1.6.3 // indirect
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
+ github.com/valyala/fasthttp v1.69.0 // indirect
+ go.uber.org/multierr v1.10.0 // indirect
+ go.uber.org/zap v1.27.1 // indirect
+ go.yaml.in/yaml/v3 v3.0.4 // indirect
+ golang.org/x/crypto v0.48.0 // indirect
+ golang.org/x/net v0.50.0 // indirect
+ golang.org/x/sync v0.19.0 // indirect
+ golang.org/x/sys v0.41.0 // indirect
+ golang.org/x/text v0.34.0 // indirect
+ gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
+)
diff --git a/code/allapp/allapp-go-v2/go.sum b/code/allapp/allapp-go-v2/go.sum
new file mode 100644
index 00000000..e1bb55a5
--- /dev/null
+++ b/code/allapp/allapp-go-v2/go.sum
@@ -0,0 +1,105 @@
+github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
+github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
+github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
+github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
+github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/gofiber/fiber/v3 v3.1.0 h1:1p4I820pIa+FGxfwWuQZ5rAyX0WlGZbGT6Hnuxt6hKY=
+github.com/gofiber/fiber/v3 v3.1.0/go.mod h1:n2nYQovvL9z3Too/FGOfgtERjW3GQcAUqgfoezGBZdU=
+github.com/gofiber/schema v1.7.0 h1:yNM+FNRZjyYEli9Ey0AXRBrAY9jTnb+kmGs3lJGPvKg=
+github.com/gofiber/schema v1.7.0/go.mod h1:A/X5Ffyru4p9eBdp99qu+nzviHzQiZ7odLT+TwxWhbk=
+github.com/gofiber/utils/v2 v2.0.2 h1:ShRRssz0F3AhTlAQcuEj54OEDtWF7+HJDwEi/aa6QLI=
+github.com/gofiber/utils/v2 v2.0.2/go.mod h1:+9Ub4NqQ+IaJoTliq5LfdmOJAA/Hzwf4pXOxOa3RrJ0=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc=
+github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
+github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
+github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
+github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
+github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
+github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
+github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
+github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
+github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
+github.com/shamaton/msgpack/v3 v3.1.0 h1:jsk0vEAqVvvS9+fTZ5/EcQ9tz860c9pWxJ4Iwecz8gU=
+github.com/shamaton/msgpack/v3 v3.1.0/go.mod h1:DcQG8jrdrQCIxr3HlMYkiXdMhK+KfN2CitkyzsQV4uc=
+github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
+github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
+github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
+github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
+github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
+github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
+github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
+github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
+github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
+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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s=
+github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZyVI=
+github.com/valyala/fasthttp v1.69.0/go.mod h1:4wA4PfAraPlAsJ5jMSqCE2ug5tqUPwKXxVj8oNECGcw=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
+github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
+go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
+go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
+golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
+golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
+golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
+golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
+golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
+golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
+golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/code/allapp/allapp-go-v2/internal/bootstrap/app.go b/code/allapp/allapp-go-v2/internal/bootstrap/app.go
new file mode 100644
index 00000000..3e3864ca
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/bootstrap/app.go
@@ -0,0 +1,38 @@
+package bootstrap
+
+import (
+ "allapp-go-v2/internal/config"
+ "allapp-go-v2/internal/pkg/logger"
+
+ "github.com/jackc/pgx/v5/pgxpool"
+)
+
+type App struct {
+ Config *config.Config
+ Db *pgxpool.Pool
+}
+
+func NewApp() (*App, error) {
+ cfg, err := config.Load()
+ if err != nil {
+ return nil, err
+ }
+
+ // 初始化日志
+ if err := logger.Init(cfg.App.Env); err != nil {
+ return nil, err
+ }
+
+ InitUniqueId(cfg)
+
+ db, err := InitDB(cfg)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &App{
+ Config: cfg,
+ Db: db,
+ }, nil
+}
diff --git a/code/allapp/allapp-go-v2/internal/bootstrap/db.go b/code/allapp/allapp-go-v2/internal/bootstrap/db.go
new file mode 100644
index 00000000..9d0da76c
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/bootstrap/db.go
@@ -0,0 +1,53 @@
+package bootstrap
+
+import (
+ "allapp-go-v2/internal/config"
+ "allapp-go-v2/internal/pkg/logger"
+ "context"
+ "fmt"
+ "net/url"
+ "time"
+
+ "github.com/jackc/pgx/v5/pgxpool"
+)
+
+func InitDB(cfg *config.Config) (*pgxpool.Pool, error) {
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+
+ pg := cfg.Postgres
+
+ // ssl mode
+ sslMode := "disable"
+ if pg.SslMode {
+ sslMode = "require"
+ }
+
+ // 转义密码(防止特殊字符问题)
+ password := url.QueryEscape(pg.Password)
+
+ // 构建 DSN
+ dsn := fmt.Sprintf(
+ "postgres://%s:%s@%s:%d/%s?sslmode=%s&timezone=%s",
+ pg.User,
+ password,
+ pg.Host,
+ pg.Port,
+ pg.Dbname,
+ sslMode,
+ pg.TimeZone,
+ )
+
+ db, err := pgxpool.New(ctx, dsn)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := db.Ping(ctx); err != nil {
+ return nil, err
+ }
+
+ logger.Log.Info("√ 数据库连接成功")
+
+ return db, nil
+}
diff --git a/code/allapp/allapp-go-v2/internal/bootstrap/unique_id.go b/code/allapp/allapp-go-v2/internal/bootstrap/unique_id.go
new file mode 100644
index 00000000..466ddb6e
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/bootstrap/unique_id.go
@@ -0,0 +1,11 @@
+package bootstrap
+
+import (
+ "allapp-go-v2/internal/config"
+ "allapp-go-v2/internal/pkg/uniqueid"
+)
+
+func InitUniqueId(cfg *config.Config) {
+ options := uniqueid.NewIdGeneratorOptions(cfg.UniqueID.WorkerID)
+ uniqueid.SetIdGenerator(options)
+}
diff --git a/code/allapp/allapp-go-v2/internal/config/config.go b/code/allapp/allapp-go-v2/internal/config/config.go
new file mode 100644
index 00000000..599ec614
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/config/config.go
@@ -0,0 +1,103 @@
+package config
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/spf13/viper"
+)
+
+func Load() (*Config, error) {
+ env := getEnv("APP_ENV", "dev")
+
+ v := viper.New()
+ v.SetConfigType("yaml")
+
+ // 配置路径
+ v.AddConfigPath("configs")
+
+ // ======================
+ // 1️⃣ 基础配置
+ // ======================
+ if err := loadBase(v); err != nil {
+ return nil, err
+ }
+
+ // ======================
+ // 2️⃣ 环境配置(支持多环境)
+ // ======================
+ loadByEnv(v, env)
+
+ // ======================
+ // 3️⃣ 环境变量覆盖
+ // ======================
+ bindEnv(v)
+
+ // ======================
+ // 4️⃣ 默认值
+ // ======================
+ setDefaults(v, env)
+
+ // ======================
+ // 5️⃣ 解析
+ // ======================
+ var cfg Config
+ if err := v.Unmarshal(&cfg); err != nil {
+ return nil, fmt.Errorf("decode config failed: %w", err)
+ }
+
+ return &cfg, nil
+}
+
+func loadBase(v *viper.Viper) error {
+ v.SetConfigName("config")
+
+ if err := v.ReadInConfig(); err != nil {
+ return fmt.Errorf("read base config failed: %w", err)
+ }
+ return nil
+}
+
+func loadByEnv(v *viper.Viper, env string) {
+ envs := strings.Split(env, ",")
+
+ for _, e := range envs {
+ e = strings.TrimSpace(e)
+ if e == "" {
+ continue
+ }
+
+ v.SetConfigName("config." + e)
+
+ if err := v.MergeInConfig(); err != nil {
+ fmt.Printf("⚠️ config.%s.yaml not found\n", e)
+ }
+ }
+}
+
+func bindEnv(v *viper.Viper) {
+ v.AutomaticEnv()
+ v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
+}
+
+func setDefaults(v *viper.Viper, env string) {
+ v.SetDefault("app.env", env)
+
+ v.SetDefault("app.name", "golang")
+
+ v.SetDefault("server.port", "8080")
+
+ v.SetDefault("unique_id.datacenter_id", 1)
+ v.SetDefault("unique_id.worker_id", 1)
+
+ v.SetDefault("jwt.secret", "abcdedhaldkasdlkasd")
+ v.SetDefault("jwt.access_expiry", -1)
+}
+
+func getEnv(key, def string) string {
+ if val := os.Getenv(key); val != "" {
+ return val
+ }
+ return def
+}
diff --git a/code/allapp/allapp-go-v2/internal/config/types.go b/code/allapp/allapp-go-v2/internal/config/types.go
new file mode 100644
index 00000000..64a3133e
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/config/types.go
@@ -0,0 +1,54 @@
+package config
+
+import "time"
+
+type Config struct {
+ App AppConfig `mapstructure:"app"`
+ Server ServerConfig `mapstructure:"server"`
+ JWT JwtConfig `mapstructure:"jwt"`
+ UniqueID UniqueIDConfig `mapstructure:"unique_id"`
+ Postgres PostgresConfig `mapstructure:"postgres"`
+ Wechat WechatConfig `mapstructure:"wechat"`
+ Redis RedisConfig `mapstructure:"redis"`
+}
+
+type AppConfig struct {
+ Name string `mapstructure:"name"`
+ Env string `mapstructure:"env"`
+}
+
+type ServerConfig struct {
+ Port string `mapstructure:"port"`
+}
+
+type JwtConfig struct {
+ Secret string `mapstructure:"secret"`
+ AccessExpiry time.Duration `mapstructure:"access_expiry"`
+}
+
+type UniqueIDConfig struct {
+ DataCenterID uint16 `mapstructure:"datacenter_id"`
+ WorkerID uint16 `mapstructure:"worker_id"`
+}
+
+type WechatConfig struct {
+ AppId string `mapstructure:"app_id"`
+ AppSecret string `mapstructure:"app_secret"`
+}
+
+type PostgresConfig struct {
+ Host string `mapstructure:"host"`
+ Port int `mapstructure:"port"`
+ User string `mapstructure:"user"`
+ Password string `mapstructure:"password"`
+ Dbname string `mapstructure:"dbname"`
+ SslMode bool `mapstructure:"ssl_mode"`
+ TimeZone string `mapstructure:"timezone"`
+}
+
+type RedisConfig struct {
+ Host string `mapstructure:"host"`
+ Port int `mapstructure:"port"`
+ Db int `mapstructure:"db"`
+ Password string `mapstructure:"password"`
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/logger/logger.go b/code/allapp/allapp-go-v2/internal/pkg/logger/logger.go
new file mode 100644
index 00000000..35e0ebc9
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/logger/logger.go
@@ -0,0 +1,147 @@
+package logger
+
+import (
+ "os"
+ "path/filepath"
+ "sync"
+ "time"
+
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+)
+
+var Log *zap.Logger
+
+var (
+ currentDate string
+ mu sync.Mutex
+ envMode string
+)
+
+// ======================
+// 初始化
+// ======================
+func Init(env string) error {
+ envMode = env
+ logger := buildLogger()
+
+ Log = logger
+ return nil
+}
+
+// ======================
+// 构建 logger
+// ======================
+func buildLogger() *zap.Logger {
+ currentDate = getToday()
+
+ level := zap.InfoLevel
+ if envMode == "dev" {
+ level = zap.DebugLevel
+ }
+
+ encoderConfig := zapcore.EncoderConfig{
+ TimeKey: "time",
+ LevelKey: "level",
+ MessageKey: "msg",
+ CallerKey: "caller",
+ EncodeLevel: zapcore.CapitalLevelEncoder,
+ EncodeTime: timeEncoder,
+ EncodeCaller: zapcore.ShortCallerEncoder,
+ }
+
+ encoder := zapcore.NewJSONEncoder(encoderConfig)
+
+ consoleWriter := zapcore.AddSync(os.Stdout)
+
+ infoWriter := zapcore.AddSync(&dailyWriter{
+ level: "info",
+ })
+
+ errorWriter := zapcore.AddSync(&dailyWriter{
+ level: "error",
+ })
+
+ infoCore := zapcore.NewCore(
+ encoder,
+ zapcore.NewMultiWriteSyncer(consoleWriter, infoWriter),
+ zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
+ return lvl < zapcore.ErrorLevel && lvl >= level
+ }),
+ )
+
+ errorCore := zapcore.NewCore(
+ encoder,
+ zapcore.NewMultiWriteSyncer(consoleWriter, errorWriter),
+ zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
+ return lvl >= zapcore.ErrorLevel
+ }),
+ )
+
+ core := zapcore.NewTee(infoCore, errorCore)
+
+ return zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1))
+}
+
+// ======================
+// 自定义 Writer(核心)
+// ======================
+type dailyWriter struct {
+ level string
+ file *os.File
+}
+
+func (w *dailyWriter) Write(p []byte) (n int, err error) {
+ mu.Lock()
+ defer mu.Unlock()
+
+ today := getToday()
+
+ // 跨天切换
+ if w.file == nil || today != currentDate {
+ if w.file != nil {
+ _ = w.file.Close()
+ }
+
+ currentDate = today
+
+ filename := getLogFilePath(w.level, today)
+
+ file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
+ if err != nil {
+ return 0, err
+ }
+
+ w.file = file
+ }
+
+ return w.file.Write(p)
+}
+
+func (w *dailyWriter) Sync() error {
+ return nil
+}
+
+// ======================
+// 工具函数
+// ======================
+
+// 获取当天
+func getToday() string {
+ return time.Now().Format("2006-01-02")
+}
+
+// 获取日志路径
+func getLogFilePath(level, date string) string {
+ dir := filepath.Join("logs", level)
+
+ // 自动创建目录
+ _ = os.MkdirAll(dir, os.ModePerm)
+
+ return filepath.Join(dir, date+".log")
+}
+
+// 时间格式
+func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+ enc.AppendString(t.Format("2006-01-02 15:04:05"))
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/DefaultIdGenerator.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/DefaultIdGenerator.go
new file mode 100644
index 00000000..3d2d57f4
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/DefaultIdGenerator.go
@@ -0,0 +1,83 @@
+package uniqueid
+
+import (
+ "strconv"
+ "time"
+)
+
+type DefaultIdGenerator struct {
+ Options *IdGeneratorOptions
+ SnowWorker ISnowWorker
+ IdGeneratorException IdGeneratorException
+}
+
+func NewDefaultIdGenerator(options *IdGeneratorOptions) *DefaultIdGenerator {
+ if options == nil {
+ panic("dig.Options error.")
+ }
+
+ // 1.BaseTime
+ minTime := int64(631123200000) // time.Now().AddDate(-30, 0, 0).UnixNano() / 1e6
+ if options.BaseTime < minTime || options.BaseTime > time.Now().UnixNano()/1e6 {
+ panic("BaseTime error.")
+ }
+
+ // 2.WorkerIdBitLength
+ if options.WorkerIdBitLength <= 0 {
+ panic("WorkerIdBitLength error.(range:[1, 21])")
+ }
+ if options.WorkerIdBitLength+options.SeqBitLength > 22 {
+ panic("error:WorkerIdBitLength + SeqBitLength <= 22")
+ }
+
+ // 3.WorkerId
+ maxWorkerIdNumber := uint16(1< maxWorkerIdNumber {
+ panic("WorkerId error. (range:[0, " + strconv.FormatUint(uint64(maxWorkerIdNumber), 10) + "]")
+ }
+
+ // 4.SeqBitLength
+ if options.SeqBitLength < 2 || options.SeqBitLength > 21 {
+ panic("SeqBitLength error. (range:[2, 21])")
+ }
+
+ // 5.MaxSeqNumber
+ maxSeqNumber := uint32(1< maxSeqNumber {
+ panic("MaxSeqNumber error. (range:[1, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]")
+ }
+
+ // 6.MinSeqNumber
+ if options.MinSeqNumber < 5 || options.MinSeqNumber > maxSeqNumber {
+ panic("MinSeqNumber error. (range:[5, " + strconv.FormatUint(uint64(maxSeqNumber), 10) + "]")
+ }
+
+ var snowWorker ISnowWorker
+ switch options.Method {
+ case 1:
+ snowWorker = NewSnowWorkerM1(options)
+ case 2:
+ snowWorker = NewSnowWorkerM2(options)
+ default:
+ snowWorker = NewSnowWorkerM1(options)
+ }
+
+ if options.Method == 1 {
+ time.Sleep(time.Duration(500) * time.Microsecond)
+ }
+
+ return &DefaultIdGenerator{
+ Options: options,
+ SnowWorker: snowWorker,
+ }
+}
+
+func (dig DefaultIdGenerator) NewLong() int64 {
+ return dig.SnowWorker.NextId()
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IIdGenerator.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IIdGenerator.go
new file mode 100644
index 00000000..a0c1e4de
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IIdGenerator.go
@@ -0,0 +1,5 @@
+package uniqueid
+
+type IIdGenerator interface {
+ NewLong() uint64
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/ISnowWorker.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/ISnowWorker.go
new file mode 100644
index 00000000..c066e6d6
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/ISnowWorker.go
@@ -0,0 +1,5 @@
+package uniqueid
+
+type ISnowWorker interface {
+ NextId() int64
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdGeneratorException.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdGeneratorException.go
new file mode 100644
index 00000000..c0ae9086
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdGeneratorException.go
@@ -0,0 +1,12 @@
+package uniqueid
+
+import "fmt"
+
+type IdGeneratorException struct {
+ message string
+ error error
+}
+
+func (e IdGeneratorException) IdGeneratorException(message ...interface{}) {
+ fmt.Println(message)
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdGeneratorOptions.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdGeneratorOptions.go
new file mode 100644
index 00000000..1f4ff6e1
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdGeneratorOptions.go
@@ -0,0 +1,25 @@
+package uniqueid
+
+type IdGeneratorOptions struct {
+ Method uint16 // 雪花计算方法,(1-漂移算法|2-传统算法),默认1
+ BaseTime int64 // 基础时间(ms单位),不能超过当前系统时间
+ WorkerId uint16 // 机器码,必须由外部设定,最大值 2^WorkerIdBitLength-1
+ WorkerIdBitLength byte // 机器码位长,默认值6,取值范围 [1, 15](要求:序列数位长+机器码位长不超过22)
+ SeqBitLength byte // 序列数位长,默认值6,取值范围 [3, 21](要求:序列数位长+机器码位长不超过22)
+ MaxSeqNumber uint32 // 最大序列数(含),设置范围 [MinSeqNumber, 2^SeqBitLength-1],默认值0,表示最大序列数取最大值(2^SeqBitLength-1])
+ MinSeqNumber uint32 // 最小序列数(含),默认值5,取值范围 [5, MaxSeqNumber],每毫秒的前5个序列数对应编号0-4是保留位,其中1-4是时间回拨相应预留位,0是手工新值预留位
+ TopOverCostCount uint32 // 最大漂移次数(含),默认2000,推荐范围500-10000(与计算能力有关)
+}
+
+func NewIdGeneratorOptions(workerId uint16) *IdGeneratorOptions {
+ return &IdGeneratorOptions{
+ Method: 1,
+ WorkerId: workerId,
+ BaseTime: 1582136402000,
+ WorkerIdBitLength: 6,
+ SeqBitLength: 6,
+ MaxSeqNumber: 0,
+ MinSeqNumber: 5,
+ TopOverCostCount: 2000,
+ }
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdHelper.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdHelper.go
new file mode 100644
index 00000000..a76494a8
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/IdHelper.go
@@ -0,0 +1,29 @@
+package uniqueid
+
+import (
+ "sync"
+)
+
+var singletonMutex sync.Mutex
+var idGenerator *DefaultIdGenerator
+
+// SetIdGenerator .
+func SetIdGenerator(options *IdGeneratorOptions) {
+ singletonMutex.Lock()
+ idGenerator = NewDefaultIdGenerator(options)
+ singletonMutex.Unlock()
+}
+
+// NextId .
+func NextId() int64 {
+ if idGenerator == nil {
+ singletonMutex.Lock()
+ defer singletonMutex.Unlock()
+ if idGenerator == nil {
+ options := NewIdGeneratorOptions(1)
+ idGenerator = NewDefaultIdGenerator(options)
+ }
+ }
+
+ return idGenerator.NewLong()
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/OverCostActionArg.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/OverCostActionArg.go
new file mode 100644
index 00000000..5b8942cc
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/OverCostActionArg.go
@@ -0,0 +1,19 @@
+package uniqueid
+
+type OverCostActionArg struct {
+ ActionType int32
+ TimeTick int64
+ WorkerId uint16
+ OverCostCountInOneTerm int32
+ GenCountInOneTerm int32
+ TermIndex int32
+}
+
+func (ocaa OverCostActionArg) OverCostActionArg(workerId uint16, timeTick int64, actionType int32, overCostCountInOneTerm int32, genCountWhenOverCost int32, index int32) {
+ ocaa.ActionType = actionType
+ ocaa.TimeTick = timeTick
+ ocaa.WorkerId = workerId
+ ocaa.OverCostCountInOneTerm = overCostCountInOneTerm
+ ocaa.GenCountInOneTerm = genCountWhenOverCost
+ ocaa.TermIndex = index
+}
diff --git a/code/allapp/allapp-go-v2/internal/pkg/uniqueid/SnowWorkerM1.go b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/SnowWorkerM1.go
new file mode 100644
index 00000000..b9edde7f
--- /dev/null
+++ b/code/allapp/allapp-go-v2/internal/pkg/uniqueid/SnowWorkerM1.go
@@ -0,0 +1,243 @@
+package uniqueid
+
+import (
+ "sync"
+ "time"
+)
+
+// SnowWorkerM1 .
+type SnowWorkerM1 struct {
+ BaseTime int64 //基础时间
+ WorkerId uint16 //机器码
+ WorkerIdBitLength byte //机器码位长
+ SeqBitLength byte //自增序列数位长
+ MaxSeqNumber uint32 //最大序列数(含)
+ MinSeqNumber uint32 //最小序列数(含)
+ TopOverCostCount uint32 //最大漂移次数
+ _TimestampShift byte
+ _CurrentSeqNumber uint32
+
+ _LastTimeTick int64
+ _TurnBackTimeTick int64
+ _TurnBackIndex byte
+ _IsOverCost bool
+ _OverCostCountInOneTerm uint32
+ _GenCountInOneTerm uint32
+ _TermIndex uint32
+
+ sync.Mutex
+}
+
+// NewSnowWorkerM1 .
+func NewSnowWorkerM1(options *IdGeneratorOptions) ISnowWorker {
+ var workerIdBitLength byte
+ var seqBitLength byte
+ var maxSeqNumber uint32
+
+ // 1.BaseTime
+ var baseTime int64
+ if options.BaseTime != 0 {
+ baseTime = options.BaseTime
+ } else {
+ baseTime = 1582136402000
+ }
+
+ // 2.WorkerIdBitLength
+ if options.WorkerIdBitLength == 0 {
+ workerIdBitLength = 6
+ } else {
+ workerIdBitLength = options.WorkerIdBitLength
+ }
+
+ // 3.WorkerId
+ var workerId = options.WorkerId
+
+ // 4.SeqBitLength
+ if options.SeqBitLength == 0 {
+ seqBitLength = 6
+ } else {
+ seqBitLength = options.SeqBitLength
+ }
+
+ // 5.MaxSeqNumber
+ if options.MaxSeqNumber <= 0 {
+ maxSeqNumber = (1 << seqBitLength) - 1
+ } else {
+ maxSeqNumber = options.MaxSeqNumber
+ }
+
+ // 6.MinSeqNumber
+ var minSeqNumber = options.MinSeqNumber
+
+ // 7.Others
+ var topOverCostCount = options.TopOverCostCount
+ if topOverCostCount == 0 {
+ topOverCostCount = 2000
+ }
+
+ timestampShift := (byte)(workerIdBitLength + seqBitLength)
+ currentSeqNumber := minSeqNumber
+
+ return &SnowWorkerM1{
+ BaseTime: baseTime,
+ WorkerIdBitLength: workerIdBitLength,
+ WorkerId: workerId,
+ SeqBitLength: seqBitLength,
+ MaxSeqNumber: maxSeqNumber,
+ MinSeqNumber: minSeqNumber,
+ TopOverCostCount: topOverCostCount,
+ _TimestampShift: timestampShift,
+ _CurrentSeqNumber: currentSeqNumber,
+
+ _LastTimeTick: 0,
+ _TurnBackTimeTick: 0,
+ _TurnBackIndex: 0,
+ _IsOverCost: false,
+ _OverCostCountInOneTerm: 0,
+ _GenCountInOneTerm: 0,
+ _TermIndex: 0,
+ }
+}
+
+// DoGenIDAction .
+func (m1 *SnowWorkerM1) DoGenIdAction(arg *OverCostActionArg) {
+
+}
+
+func (m1 *SnowWorkerM1) BeginOverCostAction(useTimeTick int64) {
+
+}
+
+func (m1 *SnowWorkerM1) EndOverCostAction(useTimeTick int64) {
+ if m1._TermIndex > 10000 {
+ m1._TermIndex = 0
+ }
+}
+
+func (m1 *SnowWorkerM1) BeginTurnBackAction(useTimeTick int64) {
+
+}
+
+func (m1 *SnowWorkerM1) EndTurnBackAction(useTimeTick int64) {
+
+}
+
+func (m1 *SnowWorkerM1) NextOverCostId() int64 {
+ currentTimeTick := m1.GetCurrentTimeTick()
+ if currentTimeTick > m1._LastTimeTick {
+ m1.EndOverCostAction(currentTimeTick)
+ m1._LastTimeTick = currentTimeTick
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = false
+ m1._OverCostCountInOneTerm = 0
+ m1._GenCountInOneTerm = 0
+ return m1.CalcId(m1._LastTimeTick)
+ }
+ if m1._OverCostCountInOneTerm >= m1.TopOverCostCount {
+ m1.EndOverCostAction(currentTimeTick)
+ m1._LastTimeTick = m1.GetNextTimeTick()
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = false
+ m1._OverCostCountInOneTerm = 0
+ m1._GenCountInOneTerm = 0
+ return m1.CalcId(m1._LastTimeTick)
+ }
+ if m1._CurrentSeqNumber > m1.MaxSeqNumber {
+ m1._LastTimeTick++
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = true
+ m1._OverCostCountInOneTerm++
+ m1._GenCountInOneTerm++
+
+ return m1.CalcId(m1._LastTimeTick)
+ }
+
+ m1._GenCountInOneTerm++
+ return m1.CalcId(m1._LastTimeTick)
+}
+
+// NextNormalID .
+func (m1 *SnowWorkerM1) NextNormalId() int64 {
+ currentTimeTick := m1.GetCurrentTimeTick()
+ if currentTimeTick < m1._LastTimeTick {
+ if m1._TurnBackTimeTick < 1 {
+ m1._TurnBackTimeTick = m1._LastTimeTick - 1
+ m1._TurnBackIndex++
+ // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序
+ // 最多4次回拨(防止回拨重叠)
+ if m1._TurnBackIndex > 4 {
+ m1._TurnBackIndex = 1
+ }
+ m1.BeginTurnBackAction(m1._TurnBackTimeTick)
+ }
+
+ // time.Sleep(time.Duration(1) * time.Millisecond)
+ return m1.CalcTurnBackId(m1._TurnBackTimeTick)
+ }
+
+ // 时间追平时,_TurnBackTimeTick清零
+ if m1._TurnBackTimeTick > 0 {
+ m1.EndTurnBackAction(m1._TurnBackTimeTick)
+ m1._TurnBackTimeTick = 0
+ }
+
+ if currentTimeTick > m1._LastTimeTick {
+ m1._LastTimeTick = currentTimeTick
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ return m1.CalcId(m1._LastTimeTick)
+ }
+
+ if m1._CurrentSeqNumber > m1.MaxSeqNumber {
+ m1.BeginOverCostAction(currentTimeTick)
+ m1._TermIndex++
+ m1._LastTimeTick++
+ m1._CurrentSeqNumber = m1.MinSeqNumber
+ m1._IsOverCost = true
+ m1._OverCostCountInOneTerm = 1
+ m1._GenCountInOneTerm = 1
+
+ return m1.CalcId(m1._LastTimeTick)
+ }
+
+ return m1.CalcId(m1._LastTimeTick)
+}
+
+// CalcID .
+func (m1 *SnowWorkerM1) CalcId(useTimeTick int64) int64 {
+ result := int64(useTimeTick< m2.MaxSeqNumber {
+ m2._CurrentSeqNumber = m2.MinSeqNumber
+ currentTimeTick = m2.GetNextTimeTick()
+ }
+ } else {
+ m2._CurrentSeqNumber = m2.MinSeqNumber
+ }
+ if currentTimeTick < m2._LastTimeTick {
+ fmt.Println("Time error for {0} milliseconds", strconv.FormatInt(m2._LastTimeTick-currentTimeTick, 10))
+ }
+ m2._LastTimeTick = currentTimeTick
+ result := int64(currentTimeTick<