jack 3 月之前
父節點
當前提交
5a5b93bf26
共有 59 個文件被更改,包括 1174 次插入122 次删除
  1. 1 0
      gf/UserManager/.gitattributes
  2. 19 0
      gf/UserManager/.gitignore
  3. 0 8
      gf/UserManager/.idea/.gitignore
  4. 0 9
      gf/UserManager/.idea/UserManager.iml
  5. 0 89
      gf/UserManager/.idea/inspectionProfiles/Project_Default.xml
  6. 0 8
      gf/UserManager/.idea/modules.xml
  7. 0 6
      gf/UserManager/.idea/vcs.xml
  8. 6 0
      gf/UserManager/Makefile
  9. 12 0
      gf/UserManager/README.MD
  10. 17 0
      gf/UserManager/api/hello/hello.go
  11. 12 0
      gf/UserManager/api/hello/v1/hello.go
  12. 39 2
      gf/UserManager/go.mod
  13. 103 0
      gf/UserManager/go.sum
  14. 11 0
      gf/UserManager/hack/config.yaml
  15. 19 0
      gf/UserManager/hack/hack-cli.mk
  16. 75 0
      gf/UserManager/hack/hack.mk
  17. 44 0
      gf/UserManager/internal/cmd/cmd.go
  18. 1 0
      gf/UserManager/internal/consts/consts.go
  19. 5 0
      gf/UserManager/internal/controller/hello/hello.go
  20. 16 0
      gf/UserManager/internal/controller/hello/hello_new.go
  21. 13 0
      gf/UserManager/internal/controller/hello/hello_v1_hello.go
  22. 114 0
      gf/UserManager/internal/controller/user/user.go
  23. 0 0
      gf/UserManager/internal/dao/.gitkeep
  24. 85 0
      gf/UserManager/internal/dao/internal/user.go
  25. 27 0
      gf/UserManager/internal/dao/user.go
  26. 0 0
      gf/UserManager/internal/logic/.gitkeep
  27. 115 0
      gf/UserManager/internal/logic/user/user.go
  28. 0 0
      gf/UserManager/internal/model/.gitkeep
  29. 0 0
      gf/UserManager/internal/model/do/.gitkeep
  30. 22 0
      gf/UserManager/internal/model/do/user.go
  31. 0 0
      gf/UserManager/internal/model/entity/.gitkeep
  32. 20 0
      gf/UserManager/internal/model/entity/user.go
  33. 44 0
      gf/UserManager/internal/model/user.go
  34. 1 0
      gf/UserManager/internal/packed/packed.go
  35. 0 0
      gf/UserManager/internal/service/.gitkeep
  36. 24 0
      gf/UserManager/internal/service/user.go
  37. 15 0
      gf/UserManager/main.go
  38. 21 0
      gf/UserManager/manifest/deploy/kustomize/base/deployment.yaml
  39. 8 0
      gf/UserManager/manifest/deploy/kustomize/base/kustomization.yaml
  40. 12 0
      gf/UserManager/manifest/deploy/kustomize/base/service.yaml
  41. 14 0
      gf/UserManager/manifest/deploy/kustomize/overlays/develop/configmap.yaml
  42. 10 0
      gf/UserManager/manifest/deploy/kustomize/overlays/develop/deployment.yaml
  43. 14 0
      gf/UserManager/manifest/deploy/kustomize/overlays/develop/kustomization.yaml
  44. 16 0
      gf/UserManager/manifest/docker/Dockerfile
  45. 8 0
      gf/UserManager/manifest/docker/docker.sh
  46. 0 0
      gf/UserManager/manifest/protobuf/.keep-if-necessary
  47. 23 0
      gf/UserManager/manifest/sql/postgres/user.sql
  48. 0 0
      gf/UserManager/resource/i18n/.gitkeep
  49. 0 0
      gf/UserManager/resource/public/html/.gitkeep
  50. 0 0
      gf/UserManager/resource/public/plugin/.gitkeep
  51. 0 0
      gf/UserManager/resource/public/resource/css/.gitkeep
  52. 0 0
      gf/UserManager/resource/public/resource/image/.gitkeep
  53. 0 0
      gf/UserManager/resource/public/resource/js/.gitkeep
  54. 0 0
      gf/UserManager/resource/template/.gitkeep
  55. 188 0
      gf/UserManager/template/index.html
  56. 0 0
      gf/UserManager/utility/.gitkeep
  57. 0 0
      rabbitmq/09-死信队列(DLX DLQ)/consumer_dlq.py
  58. 0 0
      rabbitmq/09-死信队列(DLX DLQ)/producer_dlq.py
  59. 0 0
      rabbitmq/09-死信队列(DLX DLQ)/usage.txt

+ 1 - 0
gf/UserManager/.gitattributes

@@ -0,0 +1 @@
+* linguist-language=GO

+ 19 - 0
gf/UserManager/.gitignore

@@ -0,0 +1,19 @@
+.buildpath
+.hgignore.swp
+.project
+.orig
+.swp
+.idea/
+.settings/
+.vscode/
+bin/
+**/.DS_Store
+gf
+main
+main.exe
+output/
+manifest/output/
+temp/
+temp.yaml
+bin
+**/config/config.yaml

+ 0 - 8
gf/UserManager/.idea/.gitignore

@@ -1,8 +0,0 @@
-# 默认忽略的文件
-/shelf/
-/workspace.xml
-# 基于编辑器的 HTTP 客户端请求
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml

+ 0 - 9
gf/UserManager/.idea/UserManager.iml

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="WEB_MODULE" version="4">
-  <component name="Go" enabled="true" />
-  <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$" />
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>

+ 0 - 89
gf/UserManager/.idea/inspectionProfiles/Project_Default.xml

@@ -1,89 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0">
-    <option name="myName" value="Project Default" />
-    <inspection_tool class="PyPackageRequirementsInspection" enabled="false" level="WARNING" enabled_by_default="false">
-      <option name="ignoredPackages">
-        <value>
-          <list size="74">
-            <item index="0" class="java.lang.String" itemvalue="blinker" />
-            <item index="1" class="java.lang.String" itemvalue="kaitaistruct" />
-            <item index="2" class="java.lang.String" itemvalue="rsa" />
-            <item index="3" class="java.lang.String" itemvalue="selenium-wire" />
-            <item index="4" class="java.lang.String" itemvalue="bs4" />
-            <item index="5" class="java.lang.String" itemvalue="canvas" />
-            <item index="6" class="java.lang.String" itemvalue="jieba" />
-            <item index="7" class="java.lang.String" itemvalue="async-timeout" />
-            <item index="8" class="java.lang.String" itemvalue="Brotli" />
-            <item index="9" class="java.lang.String" itemvalue="cryptography" />
-            <item index="10" class="java.lang.String" itemvalue="h2" />
-            <item index="11" class="java.lang.String" itemvalue="pyasn1" />
-            <item index="12" class="java.lang.String" itemvalue="zstandard" />
-            <item index="13" class="java.lang.String" itemvalue="redis" />
-            <item index="14" class="java.lang.String" itemvalue="pyOpenSSL" />
-            <item index="15" class="java.lang.String" itemvalue="charset-normalizer" />
-            <item index="16" class="java.lang.String" itemvalue="ping3" />
-            <item index="17" class="java.lang.String" itemvalue="yarl" />
-            <item index="18" class="java.lang.String" itemvalue="pycryptodome" />
-            <item index="19" class="java.lang.String" itemvalue="PyExecJS" />
-            <item index="20" class="java.lang.String" itemvalue="pyparsing" />
-            <item index="21" class="java.lang.String" itemvalue="aiosignal" />
-            <item index="22" class="java.lang.String" itemvalue="httpx" />
-            <item index="23" class="java.lang.String" itemvalue="exceptiongroup" />
-            <item index="24" class="java.lang.String" itemvalue="pymongo" />
-            <item index="25" class="java.lang.String" itemvalue="selenium" />
-            <item index="26" class="java.lang.String" itemvalue="anyio" />
-            <item index="27" class="java.lang.String" itemvalue="aiohttp" />
-            <item index="28" class="java.lang.String" itemvalue="importlib-metadata" />
-            <item index="29" class="java.lang.String" itemvalue="httpcore" />
-            <item index="30" class="java.lang.String" itemvalue="idna" />
-            <item index="31" class="java.lang.String" itemvalue="chardet" />
-            <item index="32" class="java.lang.String" itemvalue="python-stdnum" />
-            <item index="33" class="java.lang.String" itemvalue="pydot" />
-            <item index="34" class="java.lang.String" itemvalue="num2words" />
-            <item index="35" class="java.lang.String" itemvalue="python-dateutil" />
-            <item index="36" class="java.lang.String" itemvalue="pyserial" />
-            <item index="37" class="java.lang.String" itemvalue="libsass" />
-            <item index="38" class="java.lang.String" itemvalue="pyopenssl" />
-            <item index="39" class="java.lang.String" itemvalue="passlib" />
-            <item index="40" class="java.lang.String" itemvalue="zeep" />
-            <item index="41" class="java.lang.String" itemvalue="mock" />
-            <item index="42" class="java.lang.String" itemvalue="typing_extensions" />
-            <item index="43" class="java.lang.String" itemvalue="pyee" />
-            <item index="44" class="java.lang.String" itemvalue="fastapi" />
-            <item index="45" class="java.lang.String" itemvalue="starlette" />
-            <item index="46" class="java.lang.String" itemvalue="uvicorn" />
-            <item index="47" class="java.lang.String" itemvalue="websockets" />
-            <item index="48" class="java.lang.String" itemvalue="pydantic-settings" />
-            <item index="49" class="java.lang.String" itemvalue="pydantic" />
-            <item index="50" class="java.lang.String" itemvalue="alembic" />
-            <item index="51" class="java.lang.String" itemvalue="greenlet" />
-            <item index="52" class="java.lang.String" itemvalue="cairosvg" />
-            <item index="53" class="java.lang.String" itemvalue="asyncpg" />
-            <item index="54" class="java.lang.String" itemvalue="sqlalchemy-utils" />
-            <item index="55" class="java.lang.String" itemvalue="cython" />
-            <item index="56" class="java.lang.String" itemvalue="mypy" />
-            <item index="57" class="java.lang.String" itemvalue="qrcode" />
-            <item index="58" class="java.lang.String" itemvalue="black" />
-            <item index="59" class="java.lang.String" itemvalue="python-dotenv" />
-            <item index="60" class="java.lang.String" itemvalue="pypdf" />
-            <item index="61" class="java.lang.String" itemvalue="python-multipart" />
-            <item index="62" class="java.lang.String" itemvalue="xlsxwriter" />
-            <item index="63" class="java.lang.String" itemvalue="sqlalchemy" />
-            <item index="64" class="java.lang.String" itemvalue="pyicu" />
-            <item index="65" class="java.lang.String" itemvalue="svgwrite" />
-            <item index="66" class="java.lang.String" itemvalue="apscheduler" />
-            <item index="67" class="java.lang.String" itemvalue="python-jose" />
-            <item index="68" class="java.lang.String" itemvalue="asyncer" />
-            <item index="69" class="java.lang.String" itemvalue="python-barcode" />
-            <item index="70" class="java.lang.String" itemvalue="pillow" />
-            <item index="71" class="java.lang.String" itemvalue="psycopg2-binary" />
-            <item index="72" class="java.lang.String" itemvalue="helium" />
-            <item index="73" class="java.lang.String" itemvalue="pydantic_core" />
-          </list>
-        </value>
-      </option>
-    </inspection_tool>
-    <inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
-    <inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
-  </profile>
-</component>

+ 0 - 8
gf/UserManager/.idea/modules.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/UserManager.iml" filepath="$PROJECT_DIR$/.idea/UserManager.iml" />
-    </modules>
-  </component>
-</project>

+ 0 - 6
gf/UserManager/.idea/vcs.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
-  </component>
-</project>

+ 6 - 0
gf/UserManager/Makefile

@@ -0,0 +1,6 @@
+ROOT_DIR    = $(shell pwd)
+NAMESPACE   = "default"
+DEPLOY_NAME = "template-single"
+DOCKER_NAME = "template-single"
+
+include ./hack/hack.mk

+ 12 - 0
gf/UserManager/README.MD

@@ -0,0 +1,12 @@
+# GoFrame Template For SingleRepo
+
+Quick Start: 
+- https://goframe.org/pages/viewpage.action?pageId=1114399
+
+curl -X POST 127.0.0.1:8000/user/register \
+  -d "passport=demo001&password=123456&nickname=DemoUser"
+  
+  
+curl -X POST http://localhost:8000/user/login \
+-H "Content-Type: application/json" \
+-d '{"passport":"demo001","password":"123456"}'

+ 17 - 0
gf/UserManager/api/hello/hello.go

@@ -0,0 +1,17 @@
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 
+// =================================================================================
+
+package hello
+
+import (
+	"context"
+	
+	"UserManager/api/hello/v1"
+)
+
+type IHelloV1 interface {
+	Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error)
+}
+
+

+ 12 - 0
gf/UserManager/api/hello/v1/hello.go

@@ -0,0 +1,12 @@
+package v1
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+type HelloReq struct {
+	g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
+}
+type HelloRes struct {
+	g.Meta `mime:"text/html" example:"string"`
+}

+ 39 - 2
gf/UserManager/go.mod

@@ -1,3 +1,40 @@
-module user_manager
+module UserManager
 
-go 1.22.2
+go 1.24.0
+
+toolchain go1.24.7
+
+require github.com/gogf/gf/v2 v2.9.3
+
+require (
+	github.com/BurntSushi/toml v1.5.0 // indirect
+	github.com/clbanning/mxj/v2 v2.7.0 // indirect
+	github.com/emirpasic/gods v1.18.1 // indirect
+	github.com/fatih/color v1.18.0 // indirect
+	github.com/fsnotify/fsnotify v1.9.0 // indirect
+	github.com/go-logr/logr v1.4.3 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.9.3 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/gorilla/websocket v1.5.3 // indirect
+	github.com/grokify/html-strip-tags-go v0.1.0 // indirect
+	github.com/lib/pq v1.10.9 // indirect
+	github.com/magiconair/properties v1.8.10 // indirect
+	github.com/mattn/go-colorable v0.1.14 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/mattn/go-runewidth v0.0.16 // indirect
+	github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
+	github.com/olekukonko/errors v1.1.0 // indirect
+	github.com/olekukonko/ll v0.1.1 // indirect
+	github.com/olekukonko/tablewriter v1.0.9 // indirect
+	github.com/rivo/uniseg v0.4.7 // indirect
+	go.opentelemetry.io/auto/sdk v1.2.1 // indirect
+	go.opentelemetry.io/otel v1.38.0 // indirect
+	go.opentelemetry.io/otel/metric v1.38.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.38.0 // indirect
+	go.opentelemetry.io/otel/trace v1.38.0 // indirect
+	golang.org/x/net v0.44.0 // indirect
+	golang.org/x/sys v0.36.0 // indirect
+	golang.org/x/text v0.29.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)

+ 103 - 0
gf/UserManager/go.sum

@@ -0,0 +1,103 @@
+github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
+github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
+github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
+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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
+github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
+github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
+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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.9.3 h1:8QgjRauacL7nOKxEHxNiHGL+041ke9lXHe93NIvPYw8=
+github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.9.3/go.mod h1:umGqltjrzpY2Il2GF0GX1/TQAk8Xz6vYQM4/q3BuqIo=
+github.com/gogf/gf/v2 v2.9.3 h1:qjN4s55FfUzxZ1AE8vUHNDX3V0eIOUGXhF2DjRTVZQ4=
+github.com/gogf/gf/v2 v2.9.3/go.mod h1:w6rcfD13SmO7FKI80k9LSLiSMGqpMYp50Nfkrrc2sEE=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+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/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
+github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
+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/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
+github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
+github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+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/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=
+github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
+github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
+github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
+github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
+github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
+github.com/olekukonko/ll v0.1.1 h1:9Dfeed5/Mgaxb9lHRAftLK9pVfYETvHn+If6lywVhJc=
+github.com/olekukonko/ll v0.1.1/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo=
+github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8=
+github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
+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/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
+go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
+go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
+go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
+go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
+go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
+go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
+go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
+go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
+go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
+go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
+go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
+go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
+go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
+go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
+go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
+go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
+golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
+golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
+golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
+golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
+golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
+golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
+golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
+golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
+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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 11 - 0
gf/UserManager/hack/config.yaml

@@ -0,0 +1,11 @@
+
+# CLI tool, only in development environment.
+# https://goframe.org/pages/viewpage.action?pageId=3673173
+gfcli:
+  docker:
+    build: "-a amd64 -s linux -p temp -ew"
+    tagPrefixes:
+      - my.image.pub/my-app
+  gen:
+    dao:
+      link: "pgsql:jack:aaaAAA111@tcp(127.0.0.1:5432)/user_manager?sslmode=disable"  

+ 19 - 0
gf/UserManager/hack/hack-cli.mk

@@ -0,0 +1,19 @@
+
+# Install/Update to the latest CLI tool.
+.PHONY: cli
+cli:
+	@set -e; \
+	wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(shell go env GOOS)_$(shell go env GOARCH) && \
+	chmod +x gf && \
+	./gf install -y && \
+	rm ./gf
+
+
+# Check and install CLI tool.
+.PHONY: cli.install
+cli.install:
+	@set -e; \
+	gf -v > /dev/null 2>&1 || if [[ "$?" -ne "0" ]]; then \
+  		echo "GoFame CLI is not installed, start proceeding auto installation..."; \
+		make cli; \
+	fi;

+ 75 - 0
gf/UserManager/hack/hack.mk

@@ -0,0 +1,75 @@
+include ./hack/hack-cli.mk
+
+# Update GoFrame and its CLI to latest stable version.
+.PHONY: up
+up: cli.install
+	@gf up -a
+
+# Build binary using configuration from hack/config.yaml.
+.PHONY: build
+build: cli.install
+	@gf build -ew
+
+# Parse api and generate controller/sdk.
+.PHONY: ctrl
+ctrl: cli.install
+	@gf gen ctrl
+
+# Generate Go files for DAO/DO/Entity.
+.PHONY: dao
+dao: cli.install
+	@gf gen dao
+
+# Parse current project go files and generate enums go file.
+.PHONY: enums
+enums: cli.install
+	@gf gen enums
+
+# Generate Go files for Service.
+.PHONY: service
+service: cli.install
+	@gf gen service
+
+
+# Build docker image.
+.PHONY: image
+image: cli.install
+	$(eval _TAG  = $(shell git describe --dirty --always --tags --abbrev=8 --match 'v*' | sed 's/-/./2' | sed 's/-/./2'))
+ifneq (, $(shell git status --porcelain 2>/dev/null))
+	$(eval _TAG  = $(_TAG).dirty)
+endif
+	$(eval _TAG  = $(if ${TAG},  ${TAG}, $(_TAG)))
+	$(eval _PUSH = $(if ${PUSH}, ${PUSH}, ))
+	@gf docker ${_PUSH} -tn $(DOCKER_NAME):${_TAG};
+
+
+# Build docker image and automatically push to docker repo.
+.PHONY: image.push
+image.push:
+	@make image PUSH=-p;
+
+
+# Deploy image and yaml to current kubectl environment.
+.PHONY: deploy
+deploy:
+	$(eval _TAG = $(if ${TAG},  ${TAG}, develop))
+
+	@set -e; \
+	mkdir -p $(ROOT_DIR)/temp/kustomize;\
+	cd $(ROOT_DIR)/manifest/deploy/kustomize/overlays/${_ENV};\
+	kustomize build > $(ROOT_DIR)/temp/kustomize.yaml;\
+	kubectl   apply -f $(ROOT_DIR)/temp/kustomize.yaml; \
+	if [ $(DEPLOY_NAME) != "" ]; then \
+		kubectl   patch -n $(NAMESPACE) deployment/$(DEPLOY_NAME) -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(shell date +%s)\"}}}}}"; \
+	fi;
+
+
+# Parsing protobuf files and generating go files.
+.PHONY: pb
+pb: cli.install
+	@gf gen pb
+
+# Generate protobuf files for database tables.
+.PHONY: pbentity
+pbentity: cli.install
+	@gf gen pbentity

+ 44 - 0
gf/UserManager/internal/cmd/cmd.go

@@ -0,0 +1,44 @@
+package cmd
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/gogf/gf/v2/os/gcmd"
+
+	"UserManager/internal/controller/hello"
+	"UserManager/internal/controller/user"
+)
+
+var (
+	Main = gcmd.Command{
+		Name:  "main",
+		Usage: "main",
+		Brief: "start http server",
+		Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
+			s := g.Server()
+
+			// 静态文件服务,用于提供前端页面
+			s.SetServerRoot("template")
+			s.AddStaticPath("/", "template")
+
+			// 1. 根分组,保留官方示例
+			s.Group("/", func(g *ghttp.RouterGroup) {
+				g.Middleware(ghttp.MiddlewareHandlerResponse)
+				g.Bind(hello.NewV1())
+			})
+
+			// 2. 用户分组,挂我们写的控制器
+			s.Group("/user", func(g *ghttp.RouterGroup) {
+				g.Middleware(ghttp.MiddlewareHandlerResponse)
+				g.Bind(
+					user.User, // 用我们之前写的全局实例
+				)
+			})
+
+			s.Run()
+			return nil
+		},
+	}
+)

+ 1 - 0
gf/UserManager/internal/consts/consts.go

@@ -0,0 +1 @@
+package consts

+ 5 - 0
gf/UserManager/internal/controller/hello/hello.go

@@ -0,0 +1,5 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package hello

+ 16 - 0
gf/UserManager/internal/controller/hello/hello_new.go

@@ -0,0 +1,16 @@
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT. 
+// =================================================================================
+
+package hello
+
+import (
+	"UserManager/api/hello"
+)
+
+type ControllerV1 struct{}
+
+func NewV1() hello.IHelloV1 {
+	return &ControllerV1{}
+}
+

+ 13 - 0
gf/UserManager/internal/controller/hello/hello_v1_hello.go

@@ -0,0 +1,13 @@
+package hello
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/frame/g"
+
+	"UserManager/api/hello/v1"
+)
+
+func (c *ControllerV1) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
+	g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
+	return
+}

+ 114 - 0
gf/UserManager/internal/controller/user/user.go

@@ -0,0 +1,114 @@
+package user
+
+import (
+	"context"
+
+	"UserManager/internal/model"
+	"UserManager/internal/service"
+
+	"github.com/gogf/gf/v2/errors/gerror"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+type cUser struct{}
+
+var User = cUser{} // 全局实例,方便路由绑定
+
+// RegisterReq 接收参数
+type RegisterReq struct {
+	g.Meta   `path:"/register" method:"post"`
+	Passport string `v:"required|length:3,16"`
+	Password string `v:"required|length:6,20"`
+	Nickname string
+}
+type RegisterRes struct{} // 空响应
+
+// ListReq 用户列表请求
+type ListReq struct {
+	g.Meta   `path:"/list" method:"get"`
+	Page     int `d:"1" v:"min:1"`
+	PageSize int `d:"10" v:"min:1|max:100"`
+	Passport string
+	Nickname string
+}
+
+// ListRes 用户列表响应
+type ListRes struct {
+	List  []*model.UserOutput `json:"list"`
+	Total int                 `json:"total"`
+	Page  int                 `json:"page"`
+}
+
+// GetByPassportReq 根据账号查询请求
+type GetByPassportReq struct {
+	g.Meta   `path:"/get" method:"get"`
+	Passport string `v:"required"`
+}
+
+// GetByPassportRes 根据账号查询响应
+type GetByPassportRes *model.UserOutput
+
+func (c *cUser) Register(ctx context.Context, req *RegisterReq) (res *RegisterRes, err error) {
+	err = service.User().Register(ctx, model.UserRegisterInput{
+		Passport: req.Passport,
+		Password: req.Password,
+		Nickname: req.Nickname,
+	})
+	return
+}
+
+func (c *cUser) List(ctx context.Context, req *ListReq) (res *ListRes, err error) {
+	output, err := service.User().GetList(ctx, model.UserListInput{
+		Page:     req.Page,
+		PageSize: req.PageSize,
+		Passport: req.Passport,
+		Nickname: req.Nickname,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return &ListRes{
+		List:  output.List,
+		Total: output.Total,
+		Page:  output.Page,
+	}, nil
+}
+
+func (c *cUser) GetByPassport(ctx context.Context, req *GetByPassportReq) (res *GetByPassportRes, err error) {
+	output, err := service.User().GetByPassport(ctx, req.Passport)
+	if err != nil {
+		return nil, err
+	}
+
+	return (*GetByPassportRes)(&output), nil
+}
+
+type LoginReq struct {
+	g.Meta   `path:"/login" method:"post"`
+	Passport string `v:"required" json:"passport"`
+	Password string `v:"required" json:"password"`
+}
+
+// LoginRes 登录响应
+type LoginRes struct {
+	Token    string            `json:"token"`
+	UserInfo *model.UserOutput `json:"user_info"`
+}
+
+func (c *cUser) Login(ctx context.Context, req *LoginReq) (res *LoginRes, err error) {
+	output, err := service.User().Login(ctx, model.UserLoginInput{
+		Passport: req.Passport,
+		Password: req.Password,
+	})
+
+	if err != nil {
+		// 在这里统一转换错误信息
+		return nil, gerror.New("登录失败,请检查账号密码")
+	}
+
+	return &LoginRes{
+		Token:    output.Token,
+		UserInfo: output.UserInfo,
+	}, nil
+}

+ 0 - 0
gf/UserManager/internal/dao/.gitkeep


+ 85 - 0
gf/UserManager/internal/dao/internal/user.go

@@ -0,0 +1,85 @@
+// ==========================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// UserDao is the data access object for table user.
+type UserDao struct {
+	table   string      // table is the underlying table name of the DAO.
+	group   string      // group is the database configuration group name of current DAO.
+	columns UserColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// UserColumns defines and stores column names for table user.
+type UserColumns struct {
+	Id        string //
+	Passport  string //
+	Password  string //
+	Nickname  string //
+	Status    string //
+	CreatedAt string //
+	UpdatedAt string //
+}
+
+// userColumns holds the columns for table user.
+var userColumns = UserColumns{
+	Id:        "id",
+	Passport:  "passport",
+	Password:  "password",
+	Nickname:  "nickname",
+	Status:    "status",
+	CreatedAt: "created_at",
+	UpdatedAt: "updated_at",
+}
+
+// NewUserDao creates and returns a new DAO object for table data access.
+func NewUserDao() *UserDao {
+	return &UserDao{
+		group:   "default",
+		table:   "user",
+		columns: userColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *UserDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *UserDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *UserDao) Columns() UserColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *UserDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *UserDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *UserDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 27 - 0
gf/UserManager/internal/dao/user.go

@@ -0,0 +1,27 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"UserManager/internal/dao/internal"
+)
+
+// internalUserDao is internal type for wrapping internal DAO implements.
+type internalUserDao = *internal.UserDao
+
+// userDao is the data access object for table user.
+// You can define custom methods on it to extend its functionality as you wish.
+type userDao struct {
+	internalUserDao
+}
+
+var (
+	// User is globally public accessible object for table user operations.
+	User = userDao{
+		internal.NewUserDao(),
+	}
+)
+
+// Fill with you ideas below.

+ 0 - 0
gf/UserManager/internal/logic/.gitkeep


+ 115 - 0
gf/UserManager/internal/logic/user/user.go

@@ -0,0 +1,115 @@
+package user
+
+import (
+	"UserManager/internal/dao"
+	"UserManager/internal/model"
+	"UserManager/internal/service"
+	"context"
+
+	"github.com/gogf/gf/v2/crypto/gmd5"
+	"github.com/gogf/gf/v2/errors/gerror"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/util/guid"
+)
+
+type sUser struct{}
+
+func init() { service.RegisterUser(New()) }
+
+func New() *sUser { return &sUser{} }
+
+// Register 业务:唯一性校验 + 加密密码 + 插入
+func (s *sUser) Register(ctx context.Context, in model.UserRegisterInput) error {
+	// 账号是否已存在
+	count, err := dao.User.Ctx(ctx).Where("passport", in.Passport).Count()
+	if err != nil {
+		return err
+	}
+	if count > 0 {
+		return gerror.New("账号已存在")
+	}
+	// 写入
+	_, err = dao.User.Ctx(ctx).Data(g.Map{
+		"passport": in.Passport,
+		"password": gmd5.MustEncryptString(in.Password),
+		"nickname": in.Nickname,
+	}).Insert()
+	return err
+}
+
+// GetList 获取用户列表
+func (s *sUser) GetList(ctx context.Context, in model.UserListInput) (out *model.UserListOutput, err error) {
+	out = &model.UserListOutput{
+		Page: in.Page,
+	}
+
+	m := dao.User.Ctx(ctx)
+
+	// 条件查询
+	if in.Passport != "" {
+		m = m.WhereLike("passport", "%"+in.Passport+"%")
+	}
+	if in.Nickname != "" {
+		m = m.WhereLike("nickname", "%"+in.Nickname+"%")
+	}
+
+	// 获取总数
+	out.Total, err = m.Count()
+	if err != nil {
+		return nil, err
+	}
+
+	// 分页查询
+	err = m.Page(in.Page, in.PageSize).Scan(&out.List)
+	if err != nil {
+		return nil, err
+	}
+
+	return out, nil
+}
+
+// GetByPassport 根据账号获取用户信息
+func (s *sUser) GetByPassport(ctx context.Context, passport string) (out *model.UserOutput, err error) {
+	err = dao.User.Ctx(ctx).Where("passport", passport).Scan(&out)
+	return out, err
+}
+
+// Login 用户登录
+func (s *sUser) Login(ctx context.Context, in model.UserLoginInput) (out *model.UserLoginOutput, err error) {
+	// 1. 根据账号查询用户
+	var user *model.UserOutput
+	err = dao.User.Ctx(ctx).Where("passport", in.Passport).Scan(&user)
+	if err != nil {
+		return nil, gerror.New("登录失败,请稍后重试") // 不返回具体错误
+	}
+
+	// 2. 用户不存在
+	if user == nil {
+		return nil, gerror.New("账号或密码错误") // 模糊错误信息
+	}
+
+	// 3. 验证密码
+	encryptedPassword := gmd5.MustEncryptString(in.Password)
+	correctPassword, err := dao.User.Ctx(ctx).
+		Where("passport", in.Passport).
+		Where("password", encryptedPassword).
+		Count()
+	if err != nil {
+		return nil, gerror.New("登录失败,请稍后重试")
+	}
+
+	if correctPassword == 0 {
+		return nil, gerror.New("账号或密码错误") // 模糊错误信息
+	}
+
+	// 4. 生成token
+	token := guid.S()
+
+	// 5. 返回登录结果
+	out = &model.UserLoginOutput{
+		Token:    token,
+		UserInfo: user,
+	}
+
+	return out, nil
+}

+ 0 - 0
gf/UserManager/internal/model/.gitkeep


+ 0 - 0
gf/UserManager/internal/model/do/.gitkeep


+ 22 - 0
gf/UserManager/internal/model/do/user.go

@@ -0,0 +1,22 @@
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package do
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// User is the golang structure of table user for DAO operations like Where/Data.
+type User struct {
+	g.Meta    `orm:"table:user, do:true"`
+	Id        interface{} //
+	Passport  interface{} //
+	Password  interface{} //
+	Nickname  interface{} //
+	Status    interface{} //
+	CreatedAt *gtime.Time //
+	UpdatedAt *gtime.Time //
+}

+ 0 - 0
gf/UserManager/internal/model/entity/.gitkeep


+ 20 - 0
gf/UserManager/internal/model/entity/user.go

@@ -0,0 +1,20 @@
+// =================================================================================
+// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package entity
+
+import (
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// User is the golang structure for table user.
+type User struct {
+	Id        int         `json:"id"        ` //
+	Passport  string      `json:"passport"  ` //
+	Password  string      `json:"password"  ` //
+	Nickname  string      `json:"nickname"  ` //
+	Status    int         `json:"status"    ` //
+	CreatedAt *gtime.Time `json:"createdAt" ` //
+	UpdatedAt *gtime.Time `json:"updatedAt" ` //
+}

+ 44 - 0
gf/UserManager/internal/model/user.go

@@ -0,0 +1,44 @@
+package model
+
+// UserRegisterInput 业务层输入
+type UserRegisterInput struct {
+	Passport string
+	Password string
+	Nickname string
+}
+
+// UserListInput 用户列表查询输入
+type UserListInput struct {
+	Page     int
+	PageSize int
+	Passport string
+	Nickname string
+}
+
+// UserListOutput 用户列表查询输出
+type UserListOutput struct {
+	List  []*UserOutput
+	Total int
+	Page  int
+}
+
+// UserOutput 用户信息输出
+type UserOutput struct {
+	Id        uint   `json:"id"`
+	Passport  string `json:"passport"`
+	Nickname  string `json:"nickname"`
+	CreatedAt string `json:"created_at"`
+	UpdatedAt string `json:"updated_at"`
+}
+
+// 用户登陆输入
+type UserLoginInput struct {
+	Passport string
+	Password string
+}
+
+// 用户登陆输出
+type UserLoginOutput struct {
+	Token    string      `json:"token"`
+	UserInfo *UserOutput `json:"user_info"`
+}

+ 1 - 0
gf/UserManager/internal/packed/packed.go

@@ -0,0 +1 @@
+package packed

+ 0 - 0
gf/UserManager/internal/service/.gitkeep


+ 24 - 0
gf/UserManager/internal/service/user.go

@@ -0,0 +1,24 @@
+package service
+
+import (
+	"UserManager/internal/model"
+	"context"
+)
+
+type IUser interface {
+	Register(ctx context.Context, in model.UserRegisterInput) error
+	GetList(ctx context.Context, in model.UserListInput) (out *model.UserListOutput, err error)
+	GetByPassport(ctx context.Context, passport string) (out *model.UserOutput, err error)
+	Login(ctx context.Context, in model.UserLoginInput) (out *model.UserLoginOutput, err error)
+}
+
+var localUser IUser
+
+func User() IUser {
+	if localUser == nil {
+		panic("implement not registered")
+	}
+	return localUser
+}
+
+func RegisterUser(i IUser) { localUser = i }

+ 15 - 0
gf/UserManager/main.go

@@ -0,0 +1,15 @@
+package main
+
+import (
+	_ "UserManager/internal/logic/user"
+	_ "UserManager/internal/packed"
+
+	_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
+	"github.com/gogf/gf/v2/os/gctx"
+
+	"UserManager/internal/cmd"
+)
+
+func main() {
+	cmd.Main.Run(gctx.GetInitCtx())
+}

+ 21 - 0
gf/UserManager/manifest/deploy/kustomize/base/deployment.yaml

@@ -0,0 +1,21 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: template-single
+  labels:
+    app: template-single
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: template-single
+  template:
+    metadata:
+      labels:
+        app: template-single
+    spec:
+      containers:
+        - name : main
+          image: template-single
+          imagePullPolicy: Always
+

+ 8 - 0
gf/UserManager/manifest/deploy/kustomize/base/kustomization.yaml

@@ -0,0 +1,8 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+- deployment.yaml
+- service.yaml
+
+
+

+ 12 - 0
gf/UserManager/manifest/deploy/kustomize/base/service.yaml

@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: template-single
+spec:
+  ports:
+  - port: 80
+    protocol: TCP
+    targetPort: 8000
+  selector:
+    app: template-single
+

+ 14 - 0
gf/UserManager/manifest/deploy/kustomize/overlays/develop/configmap.yaml

@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: template-single-configmap
+data:
+  config.yaml: |
+    server:
+      address:     ":8000"
+      openapiPath: "/api.json"
+      swaggerPath: "/swagger"
+
+    logger:
+      level : "all"
+      stdout: true

+ 10 - 0
gf/UserManager/manifest/deploy/kustomize/overlays/develop/deployment.yaml

@@ -0,0 +1,10 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: template-single
+spec:
+  template:
+    spec:
+      containers:
+        - name : main
+          image: template-single:develop

+ 14 - 0
gf/UserManager/manifest/deploy/kustomize/overlays/develop/kustomization.yaml

@@ -0,0 +1,14 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+- ../../base
+- configmap.yaml
+
+patchesStrategicMerge:
+- deployment.yaml
+
+namespace: default
+
+
+

+ 16 - 0
gf/UserManager/manifest/docker/Dockerfile

@@ -0,0 +1,16 @@
+FROM loads/alpine:3.8
+
+###############################################################################
+#                                INSTALLATION
+###############################################################################
+
+ENV WORKDIR                 /app
+ADD resource                $WORKDIR/
+ADD ./temp/linux_amd64/main $WORKDIR/main
+RUN chmod +x $WORKDIR/main
+
+###############################################################################
+#                                   START
+###############################################################################
+WORKDIR $WORKDIR
+CMD ./main

+ 8 - 0
gf/UserManager/manifest/docker/docker.sh

@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# This shell is executed before docker build.
+
+
+
+
+

+ 0 - 0
gf/UserManager/manifest/protobuf/.keep-if-necessary


+ 23 - 0
gf/UserManager/manifest/sql/postgres/user.sql

@@ -0,0 +1,23 @@
+CREATE TABLE IF NOT EXISTS public.user (
+  id        SERIAL PRIMARY KEY,
+  passport  VARCHAR(32) NOT NULL UNIQUE,
+  password  VARCHAR(64) NOT NULL,
+  nickname  VARCHAR(64),
+  status    SMALLINT DEFAULT 1,
+  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- 可选:自动更新 updated_at
+CREATE OR REPLACE FUNCTION set_updated_at()
+RETURNS TRIGGER AS $$
+BEGIN
+  NEW.updated_at = CURRENT_TIMESTAMP;
+  RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER trg_user_updated
+BEFORE UPDATE ON public.user
+FOR EACH ROW
+EXECUTE FUNCTION set_updated_at();

+ 0 - 0
gf/UserManager/resource/i18n/.gitkeep


+ 0 - 0
gf/UserManager/resource/public/html/.gitkeep


+ 0 - 0
gf/UserManager/resource/public/plugin/.gitkeep


+ 0 - 0
gf/UserManager/resource/public/resource/css/.gitkeep


+ 0 - 0
gf/UserManager/resource/public/resource/image/.gitkeep


+ 0 - 0
gf/UserManager/resource/public/resource/js/.gitkeep


+ 0 - 0
gf/UserManager/resource/template/.gitkeep


+ 188 - 0
gf/UserManager/template/index.html

@@ -0,0 +1,188 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>用户管理系统</title>
+    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
+</head>
+<body>
+    <div id="app" class="container mt-4">
+        <h1 class="mb-4">用户管理系统</h1>
+        
+        <!-- 查询表单 -->
+        <div class="card mb-4">
+            <div class="card-header">
+                <h5 class="mb-0">查询用户</h5>
+            </div>
+            <div class="card-body">
+                <form @submit.prevent="searchUsers" class="row g-3">
+                    <div class="col-md-4">
+                        <label class="form-label">账号</label>
+                        <input type="text" class="form-control" v-model="searchParams.passport" placeholder="输入账号">
+                    </div>
+                    <div class="col-md-4">
+                        <label class="form-label">昵称</label>
+                        <input type="text" class="form-control" v-model="searchParams.nickname" placeholder="输入昵称">
+                    </div>
+                    <div class="col-md-4">
+                        <label class="form-label">每页数量</label>
+                        <select class="form-select" v-model="searchParams.pageSize">
+                            <option value="10">10</option>
+                            <option value="20">20</option>
+                            <option value="50">50</option>
+                        </select>
+                    </div>
+                    <div class="col-12">
+                        <button type="submit" class="btn btn-primary">查询</button>
+                        <button type="button" class="btn btn-secondary ms-2" @click="resetSearch">重置</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+
+        <!-- 用户列表 -->
+        <div class="card">
+            <div class="card-header d-flex justify-content-between align-items-center">
+                <h5 class="mb-0">用户列表</h5>
+                <span class="text-muted">共 {{ total }} 条记录</span>
+            </div>
+            <div class="card-body">
+                <div class="table-responsive">
+                    <table class="table table-striped table-hover">
+                        <thead>
+                            <tr>
+                                <th>ID</th>
+                                <th>账号</th>
+                                <th>昵称</th>
+                                <th>创建时间</th>
+                                <th>更新时间</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <tr v-for="user in userList" :key="user.id">
+                                <td>{{ user.id }}</td>
+                                <td>{{ user.passport }}</td>
+                                <td>{{ user.nickname }}</td>
+                                <td>{{ user.created_at }}</td>
+                                <td>{{ user.updated_at }}</td>
+                            </tr>
+                            <tr v-if="userList.length === 0">
+                                <td colspan="5" class="text-center text-muted">暂无数据</td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+                
+                <!-- 分页 -->
+                <nav v-if="total > 0">
+                    <ul class="pagination justify-content-center">
+                        <li class="page-item" :class="{ disabled: currentPage === 1 }">
+                            <a class="page-link" href="#" @click.prevent="changePage(currentPage - 1)">上一页</a>
+                        </li>
+                        <li class="page-item" v-for="page in pages" :key="page" :class="{ active: page === currentPage }">
+                            <a class="page-link" href="#" @click.prevent="changePage(page)">{{ page }}</a>
+                        </li>
+                        <li class="page-item" :class="{ disabled: currentPage === totalPages }">
+                            <a class="page-link" href="#" @click.prevent="changePage(currentPage + 1)">下一页</a>
+                        </li>
+                    </ul>
+                </nav>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        const { createApp, ref, computed, onMounted } = Vue;
+        
+        createApp({
+            setup() {
+                const userList = ref([]);
+                const total = ref(0);
+                const currentPage = ref(1);
+                const pageSize = ref(10);
+                const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
+                
+                const searchParams = ref({
+                    passport: '',
+                    nickname: '',
+                    pageSize: 10
+                });
+                
+                const pages = computed(() => {
+                    const result = [];
+                    const start = Math.max(1, currentPage.value - 2);
+                    const end = Math.min(totalPages.value, start + 4);
+                    
+                    for (let i = start; i <= end; i++) {
+                        result.push(i);
+                    }
+                    return result;
+                });
+                
+                async function fetchUsers(page = 1) {
+                    try {
+                        const params = new URLSearchParams({
+                            page: page,
+                            pageSize: searchParams.value.pageSize,
+                            passport: searchParams.value.passport,
+                            nickname: searchParams.value.nickname
+                        });
+                        
+                        const response = await fetch(`/user/list?${params}`);
+                        const data = await response.json();
+                        
+                        if (data.code === 0) {
+                            userList.value = data.data.list;
+                            total.value = data.data.total;
+                            currentPage.value = data.data.page;
+                            pageSize.value = searchParams.value.pageSize;
+                        } else {
+                            alert('获取用户列表失败: ' + data.message);
+                        }
+                    } catch (error) {
+                        console.error('Error:', error);
+                        alert('网络错误,请稍后重试');
+                    }
+                }
+                
+                function searchUsers() {
+                    currentPage.value = 1;
+                    fetchUsers(1);
+                }
+                
+                function resetSearch() {
+                    searchParams.value = {
+                        passport: '',
+                        nickname: '',
+                        pageSize: 10
+                    };
+                    searchUsers();
+                }
+                
+                function changePage(page) {
+                    if (page < 1 || page > totalPages.value) return;
+                    fetchUsers(page);
+                }
+                
+                onMounted(() => {
+                    fetchUsers(1);
+                });
+                
+                return {
+                    userList,
+                    total,
+                    currentPage,
+                    totalPages,
+                    pages,
+                    searchParams,
+                    searchUsers,
+                    resetSearch,
+                    changePage
+                };
+            }
+        }).mount('#app');
+    </script>
+</body>
+</html>

+ 0 - 0
gf/UserManager/utility/.gitkeep


+ 0 - 0
rabbitmq/09-死信队列(DLX|DLQ)/consumer_dlq.py → rabbitmq/09-死信队列(DLX DLQ)/consumer_dlq.py


+ 0 - 0
rabbitmq/09-死信队列(DLX|DLQ)/producer_dlq.py → rabbitmq/09-死信队列(DLX DLQ)/producer_dlq.py


+ 0 - 0
rabbitmq/09-死信队列(DLX|DLQ)/usage.txt → rabbitmq/09-死信队列(DLX DLQ)/usage.txt