初始化项目
This commit is contained in:
commit
1b77f62820
149
trunk/.idea/workspace.xml
Normal file
149
trunk/.idea/workspace.xml
Normal file
@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="ALL" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="2037df1b-9ccc-4caa-9145-2d6722712612" name="更改" comment="" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Dockerfile" />
|
||||
<option value="Go File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="GOROOT" url="file://$USER_HOME$/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.windows-amd64" />
|
||||
<component name="HighlightingSettingsPerFile">
|
||||
<setting file="file://$USER_HOME$/go/pkg/mod/github.com/wechatpay-apiv3/wechatpay-go@v0.2.20/services/payments/jsapi/api_jsapi_request_payment.go" root0="SKIP_INSPECTION" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 3
|
||||
}</component>
|
||||
<component name="ProjectId" id="2qn73uMaWLMYCjjMpyatMYepw4t" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"DefaultGoTemplateProperty": "Go File",
|
||||
"Docker.admincenter.redis: Compose 部署.executor": "Run",
|
||||
"Docker.center/admincenter/Dockerfile builder.executor": "Run",
|
||||
"Go 构建.go build admincenter.executor": "Debug",
|
||||
"Go 构建.go build logincenter.executor": "Debug",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
||||
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
||||
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
||||
"go.import.settings.migrated": "true",
|
||||
"go.sdk.automatically.set": "true",
|
||||
"last_opened_file_path": "D:/desktop/go_test01",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "go.sdk"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="D:\workspace\e2023\goProject\trunk\center\logincenter\internal\game" />
|
||||
<recent name="D:\workspace\e2023\goProject\trunk\center\logincenter" />
|
||||
<recent name="D:\workspace\e2023\goProject\trunk\center" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager" selected="Go 构建.go build logincenter">
|
||||
<configuration name="go build admincenter" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||
<module name="trunk" />
|
||||
<working_directory value="$PROJECT_DIR$/center/admincenter" />
|
||||
<kind value="PACKAGE" />
|
||||
<package value="admincenter" />
|
||||
<directory value="$PROJECT_DIR$" />
|
||||
<filePath value="$PROJECT_DIR$/center/admincenter/main.go" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="go build logincenter" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
||||
<module name="trunk" />
|
||||
<working_directory value="$PROJECT_DIR$/center/logincenter" />
|
||||
<kind value="PACKAGE" />
|
||||
<package value="logincenter" />
|
||||
<directory value="$PROJECT_DIR$" />
|
||||
<filePath value="$PROJECT_DIR$/center/logincenter/main.go" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration default="true" type="docker-deploy" factoryName="docker-compose.yml" temporary="true">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings />
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration default="true" type="docker-deploy" factoryName="dockerfile" temporary="true">
|
||||
<deployment type="dockerfile">
|
||||
<settings />
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="admincenter.redis: Compose 部署" type="docker-deploy" factoryName="docker-compose.yml" temporary="true" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="services">
|
||||
<list>
|
||||
<option value="redis" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="center/admincenter/docker-compose.yml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="center/admincenter/Dockerfile builder" type="docker-deploy" factoryName="dockerfile" temporary="true" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="golang1.20_builder" />
|
||||
<option name="buildCliOptions" value="--target builder" />
|
||||
<option name="sourceFilePath" value="center/admincenter/Dockerfile" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Go 构建.go build logincenter" />
|
||||
<item itemvalue="Go 构建.go build admincenter" />
|
||||
<item itemvalue="Docker.admincenter.redis: Compose 部署" />
|
||||
<item itemvalue="Docker.center/admincenter/Dockerfile builder" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-gosdk-5df93f7ad4aa-df9ad98b711f-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-242.22855.85" />
|
||||
<option value="bundled-js-predefined-d6986cc7102b-5c90d61e3bab-JavaScript-GO-242.22855.85" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="VgoProject">
|
||||
<settings-migrated>true</settings-migrated>
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
<breakpoints>
|
||||
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
|
||||
<url>file://$USER_HOME$/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.windows-amd64/src/context/context.go</url>
|
||||
<line>68</line>
|
||||
<option name="timeStamp" value="8" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
</project>
|
||||
8
trunk/center/.idea/.gitignore
vendored
Normal file
8
trunk/center/.idea/.gitignore
vendored
Normal file
@ -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
|
||||
9
trunk/center/.idea/center.iml
Normal file
9
trunk/center/.idea/center.iml
Normal file
@ -0,0 +1,9 @@
|
||||
<?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>
|
||||
8
trunk/center/.idea/modules.xml
Normal file
8
trunk/center/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/center.iml" filepath="$PROJECT_DIR$/.idea/center.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
40
trunk/center/admincenter/Dockerfile
Normal file
40
trunk/center/admincenter/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
||||
# 使用官方的 Go 镜像作为构建环境
|
||||
FROM golang:1.22.10-alpine AS builder
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置 Go 代理
|
||||
ENV GOPROXY=https://goproxy.cn,direct
|
||||
|
||||
# 禁用 CGO
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
# 复制所有源代码文件
|
||||
COPY . .
|
||||
|
||||
WORKDIR /app/admincenter
|
||||
|
||||
# 构建应用程序,并确认生成的文件
|
||||
RUN go build -o adminserver -ldflags="-s -w"
|
||||
|
||||
# 使用官方的 Alpine 镜像作为运行环境
|
||||
FROM alpine:latest
|
||||
|
||||
# 设置作者标签
|
||||
LABEL authors="tp"
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 从构建阶段复制编译好的可执行文件
|
||||
COPY --from=builder /app/admincenter/adminserver .
|
||||
|
||||
# 复制配置文件
|
||||
COPY --from=builder /app/admincenter/config.yaml .
|
||||
|
||||
# 暴露端口(假设 adminserver 监听 10051 端口)
|
||||
EXPOSE 10051
|
||||
|
||||
# 设置容器启动时运行 adminserver
|
||||
ENTRYPOINT ["./adminserver"]
|
||||
@ -0,0 +1,6 @@
|
||||
2025-01-02 13:41:26---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-02 13:41:26---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
18
trunk/center/admincenter/LOG/2025/1/2025-01-02-13.warn.txt
Normal file
18
trunk/center/admincenter/LOG/2025/1/2025-01-02-13.warn.txt
Normal file
@ -0,0 +1,18 @@
|
||||
2025-01-02 13:41:26---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-02 13:41:26---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-02 13:41:26---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-02 13:41:26---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-02 13:41:26---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-02 13:41:26---->
|
||||
Web服务器开始监听:192.168.50.85:10051
|
||||
------------------------------------------------------
|
||||
21
trunk/center/admincenter/buildLiunx.sh
Normal file
21
trunk/center/admincenter/buildLiunx.sh
Normal file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 设置 Go 环境变量,确保使用 Linux 架构
|
||||
export GOOS=linux
|
||||
export GOARCH=amd64
|
||||
|
||||
echo "开始编译..."
|
||||
|
||||
# 编译 Go 代码
|
||||
go build -o adminServer
|
||||
|
||||
# 检查编译是否成功
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "编译成功!"
|
||||
else
|
||||
echo "编译失败!"
|
||||
fi
|
||||
|
||||
# 等待用户输入任意键
|
||||
read -p "编译完成,按任意键继续..."
|
||||
exit 1
|
||||
54
trunk/center/admincenter/config.yaml
Normal file
54
trunk/center/admincenter/config.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
# 配置根节点
|
||||
root:
|
||||
# 是否是调试模式
|
||||
debug: true
|
||||
|
||||
# Web服务监听地址和端口
|
||||
web_server_address: "192.168.50.85:10051"
|
||||
|
||||
# Elasticsearch 地址
|
||||
es_urls: "http://10.252.0.70:18099"
|
||||
|
||||
# 数据库配置
|
||||
db_config:
|
||||
admin_db:
|
||||
# 最大处于开启状态的连接数
|
||||
max_open_conns: 0
|
||||
|
||||
# 最大处于空闲状态的连接数
|
||||
max_idle_conns: 0
|
||||
|
||||
# 数据库连接字符串
|
||||
connection_string: "root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true"
|
||||
|
||||
user_db:
|
||||
# 最大处于开启状态的连接数
|
||||
max_open_conns: 0
|
||||
|
||||
# 最大处于空闲状态的连接数
|
||||
max_idle_conns: 0
|
||||
|
||||
# 数据库连接字符串
|
||||
connection_string: "root:Qq5201530300@tcp(192.168.50.110:3306)/user?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true"
|
||||
|
||||
redis_config:
|
||||
# 数据库连接字符串
|
||||
connection_string: "192.168.50.110:6379"
|
||||
|
||||
# 密码, 如果要设置用户Id,则密码设置为:"UserId:Password"
|
||||
password: ""
|
||||
|
||||
# 数据库序号
|
||||
database: 5
|
||||
|
||||
# 最大活跃连接数
|
||||
max_active: 500
|
||||
|
||||
# 最大空闲的连接数
|
||||
max_idle: 200
|
||||
|
||||
# 连接空闲超时时间,单位:秒
|
||||
idle_timeout: 300
|
||||
|
||||
# 连接超时时间, 单位:秒
|
||||
dial_connect_timeout: 10
|
||||
37
trunk/center/admincenter/docker-compose.yml
Normal file
37
trunk/center/admincenter/docker-compose.yml
Normal file
@ -0,0 +1,37 @@
|
||||
version: '3'
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: mysql-admin
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
MYSQL_DATABASE: admin,user
|
||||
volumes:
|
||||
- /my/own/datadir:/var/lib/mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
redis:
|
||||
image: redis:7.0
|
||||
container_name: redis-admin
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
restart: always
|
||||
command: ["redis-server", "--appendonly", "yes"]
|
||||
|
||||
admin-center:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: admin-center
|
||||
ports:
|
||||
- "10051:10051"
|
||||
volumes:
|
||||
- ./app:/app
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
28
trunk/center/admincenter/dockerRun.sh
Normal file
28
trunk/center/admincenter/dockerRun.sh
Normal file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 导航到 Dockerfile 所在目录
|
||||
#cd D:\workspace\e2023\goProject\trunk\center\admincenter
|
||||
|
||||
# 构建 Docker 镜像
|
||||
echo "开始构建 Docker 镜像..."
|
||||
docker build -t adminserver-image .
|
||||
|
||||
# 检查构建是否成功
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "构建失败!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "镜像构建成功!"
|
||||
|
||||
# 运行 Docker 容器
|
||||
echo "开始运行 Docker 容器..."
|
||||
docker run -d -p 10051:10051 --name adminserver-container adminserver-image
|
||||
|
||||
# 检查容器是否成功运行
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "容器启动失败!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "容器启动成功!"
|
||||
38
trunk/center/admincenter/go.mod
Normal file
38
trunk/center/admincenter/go.mod
Normal file
@ -0,0 +1,38 @@
|
||||
module admincenter
|
||||
|
||||
go 1.22.10
|
||||
|
||||
replace (
|
||||
common => ../common
|
||||
framework => ../../framework
|
||||
goutil => ../../goutil
|
||||
)
|
||||
|
||||
require (
|
||||
common v0.0.0-00010101000000-000000000000
|
||||
goutil v0.0.0-20230425160006-b2d0b0a0b0b0
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
framework v0.0.0-20230425160006-b2d0b0a0b0b0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/gomodule/redigo v1.8.9 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/jinzhu/gorm v1.9.12 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
gorm.io/driver/mysql v1.5.7 // indirect
|
||||
gorm.io/gorm v1.25.12 // indirect
|
||||
)
|
||||
89
trunk/center/admincenter/go.sum
Normal file
89
trunk/center/admincenter/go.sum
Normal file
@ -0,0 +1,89 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4 h1:OoL469zqSNrTLSz5zeVF/I6VOO7fiw2bzSzQe4J557c=
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4/go.mod h1:xe9a/L2aeOgFKKgrO3ibQTnMdpAeL0GC+5/HpGScSa4=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
|
||||
github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
5
trunk/center/admincenter/internal/admin.go
Normal file
5
trunk/center/admincenter/internal/admin.go
Normal file
@ -0,0 +1,5 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
_ "admincenter/internal/admin"
|
||||
)
|
||||
34
trunk/center/admincenter/internal/admin/admin.go
Normal file
34
trunk/center/admincenter/internal/admin/admin.go
Normal file
@ -0,0 +1,34 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"common/connection"
|
||||
)
|
||||
|
||||
func init() {
|
||||
//注册数据库
|
||||
connection.RegisterDBModel(&Admin{})
|
||||
}
|
||||
|
||||
type Admin struct {
|
||||
ID int64 `gorm:"column:id;primary_key;comment:管理员id;autoIncrementIncrement" json:"id"`
|
||||
//账号
|
||||
Account string `gorm:"column:account;comment:账号" json:"account"`
|
||||
Name string `gorm:"column:name;comment:管理员名称" json:"name"`
|
||||
Password string `gorm:"column:password;comment:管理员密码" json:"password"`
|
||||
//性别
|
||||
Sex int32 `gorm:"column:sex;comment:性别" json:"sex"`
|
||||
//生日
|
||||
Birthday string `gorm:"column:birthday;comment:生日" json:"birthday"`
|
||||
//手机
|
||||
Phone int64 `gorm:"column:phone;comment:手机" json:"phone"`
|
||||
//邮箱
|
||||
Email string `gorm:"column:email;comment:邮箱" json:"email"`
|
||||
//微信群【方便发送通知】
|
||||
WechatGroup string `gorm:"column:wechat_group;comment:微信群" json:"wechat_group"`
|
||||
//备注
|
||||
Describe string `gorm:"column:describe;comment:备注" json:"describe"`
|
||||
}
|
||||
|
||||
func (Admin) TableName() string {
|
||||
return "admin"
|
||||
}
|
||||
198
trunk/center/admincenter/internal/admin/api.go
Normal file
198
trunk/center/admincenter/internal/admin/api.go
Normal file
@ -0,0 +1,198 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"common/remark"
|
||||
"common/resultStatus"
|
||||
"common/webServer"
|
||||
"goutil/intUtil"
|
||||
"goutil/securityUtil"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
//注册接口
|
||||
webServer.RegisterFunction(new(AdminApi))
|
||||
}
|
||||
|
||||
func init() {
|
||||
moduleName := "AdminApi"
|
||||
desc := "管理员接口"
|
||||
author := "tangping"
|
||||
mendor := ""
|
||||
date := "2024-12-25"
|
||||
remark.RegisterModuleRemark(moduleName, desc, author, mendor, date)
|
||||
}
|
||||
|
||||
// AdminApi 管理员接口
|
||||
type AdminApi struct {
|
||||
}
|
||||
|
||||
// ---------------------------------------- 接口 --------------------------------------------------
|
||||
func init() {
|
||||
moduleName := "AdminApi"
|
||||
methodName := "Add"
|
||||
methodDesc := "添加管理员用户"
|
||||
methodAuthor := "tangping"
|
||||
methodMendor := ""
|
||||
methodDate := "2024-12-25 15:55:00"
|
||||
methodInParam := []string{"string 账号,string:管理员名称,string:管理员密码,string:管理员性别,string:管理员生日,int64:管理员手机号,string:管理员邮箱,string:管理员微信群,string:管理员备注"}
|
||||
methodOutParam := `
|
||||
{
|
||||
"Code '类型:int'": "响应结果的状态值",
|
||||
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
|
||||
"Data '类型:interface{}'": "响应结果的数据"
|
||||
{
|
||||
"id '类型:int'": "管理员id",
|
||||
}
|
||||
}`
|
||||
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam)
|
||||
}
|
||||
func (a *AdminApi) Add(account string, name string, password string, sex int32, birthday string, phone int64, email string, wechatGroup string, describe string) (responseObj *webServer.ResponseObject) {
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
//校验参数
|
||||
if account == "" || name == "" || password == "" || sex == 0 || birthday == "" || phone == 0 || email == "" || wechatGroup == "" {
|
||||
responseObj.SetResultStatus(resultStatus.APIDataError)
|
||||
return
|
||||
}
|
||||
|
||||
//密码md5加密
|
||||
password = securityUtil.Md5String(password, true)
|
||||
|
||||
//处理数据
|
||||
adminModel := &Admin{
|
||||
Account: account,
|
||||
Name: name,
|
||||
Password: password,
|
||||
Sex: sex,
|
||||
Birthday: birthday,
|
||||
Phone: phone,
|
||||
Email: email,
|
||||
WechatGroup: wechatGroup,
|
||||
Describe: describe,
|
||||
}
|
||||
|
||||
//添加到数据库
|
||||
AddAdmin(adminModel)
|
||||
|
||||
resultMap := make(map[string]any)
|
||||
resultMap["id"] = adminModel.ID
|
||||
responseObj.SetData(resultMap)
|
||||
return
|
||||
}
|
||||
|
||||
func init() {
|
||||
moduleName := "AdminApi"
|
||||
methodName := "Get"
|
||||
methodDesc := "获取管理员用户"
|
||||
methodAuthor := "tangping"
|
||||
methodMendor := ""
|
||||
methodDate := "2024-12-25 15:55:00"
|
||||
methodInParam := []string{"int64:管理员id"}
|
||||
methodOutParam := `
|
||||
{
|
||||
"Code '类型:int'": "响应结果的状态值",
|
||||
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
|
||||
"Data '类型:interface{}'": "响应结果的数据"
|
||||
{
|
||||
"account '类型:string'": "管理员账号",
|
||||
"name '类型:string'": "管理员名称",
|
||||
"sex '类型:int32'": "管理员性别",
|
||||
"birthday '类型:string'": "管理员生日",
|
||||
"phone '类型:int64'": "管理员手机号",
|
||||
"email '类型:string'": "管理员邮箱",
|
||||
"wechatGroup '类型:string'": "管理员微信群",
|
||||
"describe '类型:string'": "管理员备注",
|
||||
}
|
||||
}`
|
||||
|
||||
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam)
|
||||
}
|
||||
func (a *AdminApi) Get(adminId int64) (responseObj *webServer.ResponseObject) {
|
||||
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
//验证参数
|
||||
if adminId == 0 {
|
||||
responseObj.SetResultStatus(resultStatus.APIDataError)
|
||||
return
|
||||
}
|
||||
|
||||
adminData, err := GetAdminByID(adminId)
|
||||
if err != nil {
|
||||
responseObj.SetResultStatus(resultStatus.DataError)
|
||||
return
|
||||
}
|
||||
|
||||
//adminData映射成map
|
||||
resultMap := make(map[string]any)
|
||||
resultMap["account"] = adminData.Account
|
||||
resultMap["name"] = adminData.Name
|
||||
resultMap["sex"] = adminData.Sex
|
||||
resultMap["birthday"] = adminData.Birthday
|
||||
resultMap["phone"] = adminData.Phone
|
||||
resultMap["email"] = adminData.Email
|
||||
resultMap["wechatGroup"] = adminData.WechatGroup
|
||||
resultMap["describe"] = adminData.Describe
|
||||
|
||||
responseObj.SetData(resultMap)
|
||||
return
|
||||
}
|
||||
|
||||
// 管理员登录
|
||||
func init() {
|
||||
moduleName := "AdminApi"
|
||||
methodName := "Login"
|
||||
methodDesc := "管理员登录"
|
||||
methodAuthor := "tangping"
|
||||
methodMendor := ""
|
||||
methodDate := "2024-12-26 15:55:00"
|
||||
methodInParam := []string{"string:账号,string:密码"}
|
||||
methodOutParam := `
|
||||
{
|
||||
"Code '类型:int'": "响应结果的状态值",
|
||||
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
|
||||
"Data '类型:interface{}'": "响应结果的数据"
|
||||
{
|
||||
"Token '类型:string'": "登录令牌",
|
||||
}
|
||||
}`
|
||||
|
||||
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam)
|
||||
}
|
||||
|
||||
func (a *AdminApi) Login(account string, password string) (responseObj *webServer.ResponseObject) {
|
||||
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
//验证参数
|
||||
if account == "" || password == "" {
|
||||
responseObj.SetResultStatus(resultStatus.APIDataError)
|
||||
return
|
||||
}
|
||||
|
||||
adminData, err := Login(account, securityUtil.Md5String(password, true))
|
||||
if err != nil {
|
||||
responseObj.SetResultStatus(resultStatus.DataError)
|
||||
return
|
||||
}
|
||||
|
||||
//生成一个随机token
|
||||
token, err := intUtil.ShuffleIntDigits(time.Now().UnixNano())
|
||||
if err != nil {
|
||||
responseObj.SetResultStatus(resultStatus.DataError)
|
||||
return
|
||||
}
|
||||
|
||||
//添加登录用户
|
||||
webServer.AddLoginUserToken(token, &webServer.TokenInfo{Id: adminData.ID, Account: account})
|
||||
|
||||
//adminData映射成map
|
||||
resultMap := make(map[string]any)
|
||||
resultMap["Token"] = strconv.FormatInt(token, 10)
|
||||
|
||||
responseObj.SetData(resultMap)
|
||||
return
|
||||
}
|
||||
43
trunk/center/admincenter/internal/admin/logic.go
Normal file
43
trunk/center/admincenter/internal/admin/logic.go
Normal file
@ -0,0 +1,43 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"common/connection"
|
||||
"goutil/logUtilPlus"
|
||||
)
|
||||
|
||||
// AddAdmin 添加管理员
|
||||
// AddAdmin 添加新的管理员到数据库中。
|
||||
// 参数 admin: 包含管理员信息的对象。
|
||||
// 返回值: 插入操作影响的行数和可能发生的错误。
|
||||
func AddAdmin(admin *Admin) (int64, error) {
|
||||
|
||||
//处理一些验证
|
||||
|
||||
// 写入到数据库
|
||||
result := connection.GetAdminDB().Create(&admin) // 通过数据的指针来创建
|
||||
|
||||
if result.Error != nil {
|
||||
logUtilPlus.ErrorLog("添加管理员失败 错误信息:", result.Error.Error())
|
||||
}
|
||||
return admin.ID, nil
|
||||
}
|
||||
|
||||
// GetAdminByID 根据管理员ID获取管理员信息
|
||||
func GetAdminByID(adminID int64) (*Admin, error) {
|
||||
var admin Admin
|
||||
result := connection.GetAdminDB().First(&admin, adminID)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return &admin, nil
|
||||
}
|
||||
|
||||
// 管理员登录
|
||||
func Login(account string, password string) (*Admin, error) {
|
||||
var admin Admin
|
||||
result := connection.GetAdminDB().Where("account = ? AND password = ?", account, password).First(&admin)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return &admin, nil
|
||||
}
|
||||
40
trunk/center/admincenter/main.go
Normal file
40
trunk/center/admincenter/main.go
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"common/connection"
|
||||
"sync"
|
||||
|
||||
_ "admincenter/internal/admin"
|
||||
_ "common/resultStatus"
|
||||
"common/webServer"
|
||||
)
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 设置WaitGroup需要等待的数量,只要有一个服务器出现错误都停止服务器
|
||||
wg.Add(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
//加载配置
|
||||
loadConfig()
|
||||
|
||||
// 启动webserver
|
||||
go webServer.Start(&wg)
|
||||
|
||||
// 阻塞等待,以免main线程退出
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// loadConfig 用于加载配置信息。
|
||||
// 该函数会读取配置文件或环境变量中的设置,并根据这些设置初始化程序所需的配置。
|
||||
// 目前函数的实现为空,需要根据实际的配置加载逻辑进行填充。
|
||||
func loadConfig() {
|
||||
|
||||
//构建数据库
|
||||
connection.BuildDB()
|
||||
}
|
||||
20
trunk/center/admincenter/run.sh
Normal file
20
trunk/center/admincenter/run.sh
Normal file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 赋予可执行权限
|
||||
chmod +x adminServer
|
||||
|
||||
echo "启动中..."
|
||||
|
||||
# 接受命令行传入一个参数
|
||||
case "$1" in
|
||||
d)
|
||||
# 使用 nohup 将进程放到后台运行,并将输出重定向到 nohup.out 文件
|
||||
nohup ./adminServer > nohup.out 2>&1 &
|
||||
echo "启动完成"
|
||||
;;
|
||||
*)
|
||||
./adminServer
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "启动完成"
|
||||
16
trunk/center/admincenter/stop.sh
Normal file
16
trunk/center/admincenter/stop.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 查找 adminServer 的 PID
|
||||
PID=$(pgrep adminServer)
|
||||
|
||||
if [ -z "$PID" ]; then
|
||||
echo "adminServer 进程未找到"
|
||||
else
|
||||
echo "停止中... (PID: $PID)"
|
||||
kill $PID
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "adminServer 进程已终止 (PID: $PID)"
|
||||
else
|
||||
echo "无法终止 adminServer 进程 (PID: $PID)"
|
||||
fi
|
||||
fi
|
||||
52
trunk/center/common/cache/cache.go
vendored
Normal file
52
trunk/center/common/cache/cache.go
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Cache 结构体代表缓存
|
||||
type Cache struct {
|
||||
data map[string]any
|
||||
rwmu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewCache 创建并返回一个新的缓存实例
|
||||
func NewCache() *Cache {
|
||||
return &Cache{
|
||||
data: make(map[string]any),
|
||||
}
|
||||
}
|
||||
|
||||
// Set 方法用于向缓存中设置键值对,写操作会加写锁保证并发安全
|
||||
func (c *Cache) set(key string, value any) {
|
||||
c.rwmu.Lock()
|
||||
defer c.rwmu.Unlock()
|
||||
c.data[key] = value
|
||||
}
|
||||
|
||||
// Get 方法用于从缓存中根据键获取对应的值,读操作会加读锁允许并发读
|
||||
func (c *Cache) get(key string) any {
|
||||
c.rwmu.RLock()
|
||||
defer c.rwmu.RUnlock()
|
||||
value := c.data[key]
|
||||
return value
|
||||
}
|
||||
|
||||
// Delete 方法用于从缓存中删除指定的键值对,写操作会加写锁保证并发安全
|
||||
func (c *Cache) Delete(key string) {
|
||||
c.rwmu.Lock()
|
||||
defer c.rwmu.Unlock()
|
||||
delete(c.data, key)
|
||||
}
|
||||
|
||||
// GetData 方法用于从缓存中根据键获取对应的值,读操作会加读锁允许并发读
|
||||
func GetData[V any](c *Cache, key string) (value V, ok bool) {
|
||||
v := c.get(key)
|
||||
value, ok = v.(V)
|
||||
return
|
||||
}
|
||||
|
||||
// SetData 方法用于向缓存中设置键值对,写操作会加写锁保证并发安全
|
||||
func SetData(c *Cache, key string, value any) {
|
||||
c.set(key, value)
|
||||
}
|
||||
48
trunk/center/common/cache/cacheslice.go
vendored
Normal file
48
trunk/center/common/cache/cacheslice.go
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// SliceCache结构体代表基于切片的缓存,内部使用切片存储元素,并通过读写锁保证并发安全
|
||||
type SliceCache struct {
|
||||
data []interface{}
|
||||
rwmu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewSliceCache创建并返回一个新的基于切片的缓存实例
|
||||
func NewSliceCache() *SliceCache {
|
||||
return &SliceCache{
|
||||
data: make([]interface{}, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// Add方法用于向切片缓存中添加元素,写操作加写锁保证并发安全
|
||||
func (sc *SliceCache) Add(element interface{}) {
|
||||
sc.rwmu.Lock()
|
||||
sc.data = append(sc.data, element)
|
||||
sc.rwmu.Unlock()
|
||||
}
|
||||
|
||||
// GetAll方法用于获取切片缓存中的所有元素,读操作加读锁允许并发读
|
||||
func (sc *SliceCache) GetAll() []interface{} {
|
||||
sc.rwmu.RLock()
|
||||
result := make([]interface{}, len(sc.data))
|
||||
copy(result, sc.data)
|
||||
sc.rwmu.RUnlock()
|
||||
return result
|
||||
}
|
||||
|
||||
// Remove方法用于从切片缓存中删除指定元素,写操作加写锁保证并发安全
|
||||
func (sc *SliceCache) Remove(element interface{}) bool {
|
||||
sc.rwmu.Lock()
|
||||
for i, e := range sc.data {
|
||||
if e == element {
|
||||
sc.data = append(sc.data[:i], sc.data[i+1:]...)
|
||||
sc.rwmu.Unlock()
|
||||
return true
|
||||
}
|
||||
}
|
||||
sc.rwmu.Unlock()
|
||||
return false
|
||||
}
|
||||
BIN
trunk/center/common/configs.zip
Normal file
BIN
trunk/center/common/configs.zip
Normal file
Binary file not shown.
97
trunk/center/common/configsYaml/baseConfig.go
Normal file
97
trunk/center/common/configsYaml/baseConfig.go
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
配置包,提供项目的配置信息
|
||||
*/
|
||||
package configYaml
|
||||
|
||||
import (
|
||||
"goutil/debugUtil"
|
||||
)
|
||||
|
||||
var (
|
||||
// 是否是DEBUG模式
|
||||
DEBUG bool
|
||||
|
||||
// web服务监听端口
|
||||
WebServerAddress string
|
||||
|
||||
// gRpc监听地址和端口(内网地址即可)
|
||||
GrpcServerAddress string
|
||||
|
||||
// 战斗服务器地址
|
||||
FightServerAddress string
|
||||
|
||||
// 战区Id
|
||||
BigGroupId int
|
||||
|
||||
// 页签Id
|
||||
TagId int
|
||||
|
||||
// 是否是中心服务器地址
|
||||
PlayerServerCenter bool
|
||||
|
||||
// 数据中心服务器地址
|
||||
DataCenterAddress string
|
||||
|
||||
// es urls
|
||||
EsUrls string
|
||||
|
||||
BaseDay int
|
||||
)
|
||||
|
||||
// initBaseConfig
|
||||
// @description: 初始化基础配置数据
|
||||
// parameter:
|
||||
// @configObj: 基础配置数据
|
||||
// return:
|
||||
// @error: 错误信息
|
||||
func initBaseConfig() {
|
||||
|
||||
root := ConfigYaml.Root
|
||||
|
||||
// 为DEBUG模式赋值
|
||||
DEBUG = root.Debug
|
||||
|
||||
// 设置debugUtil的状态
|
||||
debugUtil.SetDebug(DEBUG)
|
||||
|
||||
// 解析rpcConfig配置
|
||||
WebServerAddress = root.WebServerAddress
|
||||
|
||||
// gRpc监听地址和端口(内网地址即可)
|
||||
GrpcServerAddress = root.GrpcServerAddress
|
||||
|
||||
// 解析BigGroupId配置
|
||||
BigGroupId = root.BigGroupId
|
||||
|
||||
// 解析FightServerAddress配置
|
||||
FightServerAddress = root.FightServerAddress
|
||||
|
||||
EsUrls = root.EsUrls
|
||||
|
||||
BaseDay = root.BaseDay
|
||||
}
|
||||
|
||||
// GetDebug
|
||||
// @description: 获取是否是开发环境
|
||||
// parameter:
|
||||
// return:
|
||||
// @bool:
|
||||
func GetDebug() bool {
|
||||
return ConfigYaml.Root.Debug
|
||||
}
|
||||
|
||||
// GetWebServerAddress 返回Web服务器的地址。
|
||||
// 该函数通过访问ConfigYaml中的配置信息,获取并返回Web服务器的地址。
|
||||
// 主要用于需要与Web服务器建立连接的场景。
|
||||
func GetWebServerAddress() string {
|
||||
return ConfigYaml.Root.WebServerAddress
|
||||
}
|
||||
|
||||
// GetEsUrls 返回配置文件中 Elasticsearch 的 URL 地址。
|
||||
//
|
||||
// 该函数通过访问全局变量 ConfigYaml,获取其 Root 字段下的 EsUrls 属性,
|
||||
// 并将其作为字符串返回。这提供了一种简单的方法来获取 Elasticsearch 数据库的连接信息,
|
||||
// 而无需直接访问配置文件。
|
||||
func GetEsUrls() string {
|
||||
return ConfigYaml.Root.EsUrls
|
||||
}
|
||||
154
trunk/center/common/configsYaml/configYaml.go
Normal file
154
trunk/center/common/configsYaml/configYaml.go
Normal file
@ -0,0 +1,154 @@
|
||||
package configYaml
|
||||
|
||||
var ConfigYaml = Config{}
|
||||
|
||||
// Config 定义与 YAML 文件结构匹配的结构体
|
||||
type Config struct {
|
||||
Root Root
|
||||
}
|
||||
|
||||
// Root 是整个配置文件的根结构体
|
||||
type Root struct {
|
||||
// 是否是调试模式
|
||||
Debug bool `yaml:"debug"`
|
||||
|
||||
// 是否是 CrossServer 中心节点(标记为 true 时,才会进行排行榜处理)
|
||||
CrossServerCenter bool `yaml:"cross_server_center"`
|
||||
|
||||
// ManagerCenter 配置
|
||||
ManagerCenterConfig ManagerCenterConf `yaml:"manager_center_config"`
|
||||
|
||||
// logmgr 配置
|
||||
LogMgr LogMgr `yaml:"log_mgr"`
|
||||
|
||||
// Web 服务监听地址和端口
|
||||
WebServerAddress string `yaml:"web_server_address"`
|
||||
|
||||
// gRPC 监听地址和端口 (内网地址即可)
|
||||
GrpcServerAddress string `yaml:"grpc_server_address"`
|
||||
|
||||
// 战斗服务器地址
|
||||
FightServerAddress string `yaml:"fight_server_address"`
|
||||
|
||||
// 数据中心地址
|
||||
DataCenterAddress string `yaml:"data_center_address"`
|
||||
|
||||
// OrderId 和 BigGroupId(仅用于非 PlayerServer)
|
||||
OrderId int `yaml:"order_id"`
|
||||
BigGroupId int `yaml:"big_group_id"`
|
||||
|
||||
// 重启时载入 Redis 数据日期范围
|
||||
BaseDay int `yaml:"base_day"`
|
||||
|
||||
// ES 地址
|
||||
EsUrls string `yaml:"es_urls"`
|
||||
|
||||
// 数据库配置
|
||||
DbConfig DBConfig `yaml:"db_config"`
|
||||
|
||||
// 监控相关配置
|
||||
MonitorConfig MonitorConf `yaml:"monitor_config"`
|
||||
|
||||
// 功能开关配置
|
||||
FunctionConfig FunctionConf `yaml:"function_config"`
|
||||
}
|
||||
|
||||
// ManagerCenterConf 是 ManagerCenter 的配置结构体
|
||||
type ManagerCenterConf struct {
|
||||
// ManagerCenter API 的 URL
|
||||
ManageCenterAPIUrl string `yaml:"manage_center_api_url"`
|
||||
|
||||
// 服务器组类型
|
||||
GroupType string `yaml:"group_type"`
|
||||
|
||||
// 刷新间隔,单位:分钟
|
||||
RefreshInterval int `yaml:"refresh_interval"`
|
||||
}
|
||||
|
||||
// LogMgr 是日志管理器的配置结构体
|
||||
type LogMgr struct {
|
||||
// group boxId
|
||||
GroupId string `yaml:"group_id"`
|
||||
|
||||
// group secret
|
||||
GroupSecret string `yaml:"group_secret"`
|
||||
|
||||
// product boxId
|
||||
ProductId string `yaml:"product_id"`
|
||||
}
|
||||
|
||||
// DBConfig 包含数据库和 Redis 的配置
|
||||
type DBConfig struct {
|
||||
|
||||
//管理员数据库配置
|
||||
AdminDB DatabaseConfig `yaml:"admin_db"`
|
||||
|
||||
// 用户数据库配置
|
||||
UserDB DatabaseConfig `yaml:"user_db"`
|
||||
|
||||
// 游戏模型数据库配置
|
||||
GameModel DatabaseConfig `yaml:"game_model"`
|
||||
|
||||
// 游戏数据库配置
|
||||
GameDB DatabaseConfig `yaml:"game_db"`
|
||||
|
||||
// 玩家数据库配置
|
||||
PlayerDB DatabaseConfig `yaml:"player_db"`
|
||||
|
||||
// Redis 配置
|
||||
RedisConfig RedisConfig `yaml:"redis_config"`
|
||||
}
|
||||
|
||||
// DatabaseConfig 是数据库连接的配置结构体
|
||||
type DatabaseConfig struct {
|
||||
// 最大处于开启状态的连接数
|
||||
MaxOpenConns int `yaml:"max_open_conns"`
|
||||
|
||||
// 最大处于空闲状态的连接数
|
||||
MaxIdleConns int `yaml:"max_idle_conns"`
|
||||
|
||||
// 数据库连接字符串
|
||||
ConnectionString string `yaml:"connection_string"`
|
||||
}
|
||||
|
||||
// RedisConfig 是 Redis 连接的配置结构体
|
||||
type RedisConfig struct {
|
||||
// Redis 数据库连接字符串
|
||||
ConnectionString string `yaml:"connection_string"`
|
||||
|
||||
// 密码, 如果要设置用户 Id,则密码设置为: "UserId:Password"
|
||||
Password string `yaml:"password"`
|
||||
|
||||
// 数据库序号
|
||||
Database int `yaml:"database"`
|
||||
|
||||
// 最大活跃连接数
|
||||
MaxActive int `yaml:"max_active"`
|
||||
|
||||
// 最大空闲的连接数
|
||||
MaxIdle int `yaml:"max_idle"`
|
||||
|
||||
// 连接空闲超时时间,单位:秒
|
||||
IdleTimeout int `yaml:"idle_timeout"`
|
||||
|
||||
// 连接超时时间, 单位:秒
|
||||
DialConnectTimeout int `yaml:"dial_connect_timeout"`
|
||||
}
|
||||
|
||||
// MonitorConf 是监控配置的结构体
|
||||
type MonitorConf struct {
|
||||
// 监控使用的服务器 IP (本机的外网地址)
|
||||
ServerIP string `yaml:"server_ip"`
|
||||
|
||||
// 监控使用的服务器名称
|
||||
ServerName string `yaml:"server_name"`
|
||||
|
||||
// 监控的时间间隔(单位:分钟)
|
||||
Interval int `yaml:"interval"`
|
||||
}
|
||||
|
||||
// FunctionConf 是功能开关配置的结构体
|
||||
type FunctionConf struct {
|
||||
// 游戏代码: qyc, xh, dzz
|
||||
GameCode string `yaml:"game_code"`
|
||||
}
|
||||
188
trunk/center/common/configsYaml/dbConfig.go
Normal file
188
trunk/center/common/configsYaml/dbConfig.go
Normal file
@ -0,0 +1,188 @@
|
||||
package configYaml
|
||||
|
||||
import (
|
||||
"goutil/logUtilPlus"
|
||||
"goutil/mysqlUtil"
|
||||
"goutil/redisUtil"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DbConfig
|
||||
//
|
||||
// @description: mysql配置对象
|
||||
type DbConfig struct {
|
||||
|
||||
// 管理员数据库链接字符串
|
||||
adminConfig *mysqlUtil.DBConfig
|
||||
|
||||
// 用户数据库链接字符串
|
||||
userConfig *mysqlUtil.DBConfig
|
||||
|
||||
// 游戏模型数据库链接字符串
|
||||
gameModelConfig *mysqlUtil.DBConfig
|
||||
|
||||
// 游戏数据库链接字符串
|
||||
gameConfig *mysqlUtil.DBConfig
|
||||
|
||||
// 游戏数据库链接字符串
|
||||
playerConfig *mysqlUtil.DBConfig
|
||||
|
||||
// redis配置对象
|
||||
redisConfig *redisUtil.RedisConfig
|
||||
}
|
||||
|
||||
var (
|
||||
// 数据库配置对象
|
||||
dbConfigObj *DbConfig
|
||||
)
|
||||
|
||||
// GetAdminConfig
|
||||
// @description: 获取admin库配置
|
||||
// parameter:
|
||||
//
|
||||
// @receiver config:config
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*mysqlUtil.DBConfig:admin库配置
|
||||
func (config *DbConfig) GetAdminConfig() *mysqlUtil.DBConfig {
|
||||
return config.adminConfig
|
||||
}
|
||||
|
||||
// GetUserConfig
|
||||
// @description: 获取user库配置
|
||||
// parameter:
|
||||
//
|
||||
// @receiver config:config
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*mysqlUtil.DBConfig:user库配置
|
||||
func (config *DbConfig) GetUserConfig() *mysqlUtil.DBConfig {
|
||||
return config.userConfig
|
||||
}
|
||||
|
||||
// GetGameModelConfig
|
||||
// @description: 获取model库配置
|
||||
// parameter:
|
||||
//
|
||||
// @receiver config:config
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*mysqlUtil.DBConfig:model库配置
|
||||
func (config *DbConfig) GetGameModelConfig() *mysqlUtil.DBConfig {
|
||||
return config.gameModelConfig
|
||||
}
|
||||
|
||||
// GetGameConfig
|
||||
// @description: 获取Game库配置
|
||||
// parameter:
|
||||
//
|
||||
// @receiver config:config
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*mysqlUtil.DBConfig:Game库配置
|
||||
func (config *DbConfig) GetGameConfig() *mysqlUtil.DBConfig {
|
||||
return config.gameConfig
|
||||
}
|
||||
|
||||
// GetPlayerConfig
|
||||
// @description: 获取玩家库配置
|
||||
// parameter:
|
||||
//
|
||||
// @receiver config:config
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*mysqlUtil.DBConfig:玩家库配置
|
||||
func (config *DbConfig) GetPlayerConfig() *mysqlUtil.DBConfig {
|
||||
return config.playerConfig
|
||||
}
|
||||
|
||||
// GetRedisConfig
|
||||
// @description: 获取redis配置对象
|
||||
// parameter:
|
||||
//
|
||||
// @receiver config:config
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*redisUtil.RedisConfig:redis配置
|
||||
func (config *DbConfig) GetRedisConfig() *redisUtil.RedisConfig {
|
||||
return config.redisConfig
|
||||
}
|
||||
|
||||
// newMysqlConfig
|
||||
//
|
||||
// @description: 创建新的Mysql配置对象
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @_gameModelConfig:
|
||||
// @_gameConfig:
|
||||
// @_playerConfig:
|
||||
// @_redisConfig:
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*DbConfig:
|
||||
func newMysqlConfig(_adminConfig *mysqlUtil.DBConfig, _userConfig *mysqlUtil.DBConfig, _gameModelConfig *mysqlUtil.DBConfig,
|
||||
_gameConfig *mysqlUtil.DBConfig,
|
||||
_playerConfig *mysqlUtil.DBConfig,
|
||||
_redisConfig *redisUtil.RedisConfig) *DbConfig {
|
||||
return &DbConfig{
|
||||
adminConfig: _adminConfig,
|
||||
userConfig: _userConfig,
|
||||
gameModelConfig: _gameModelConfig,
|
||||
gameConfig: _gameConfig,
|
||||
redisConfig: _redisConfig,
|
||||
playerConfig: _playerConfig,
|
||||
}
|
||||
}
|
||||
|
||||
// initDbConfig
|
||||
//
|
||||
// @description: 初始化数据库配置
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @configObj: 数据库配置
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @error: 错误数据
|
||||
func initDbConfig() error {
|
||||
|
||||
logUtilPlus.DebugLog("开始加载DbConfig")
|
||||
|
||||
redisConfig := ConfigYaml.Root.DbConfig.RedisConfig
|
||||
|
||||
//if redisConfig == nil {
|
||||
// logUtilPlus.DebugLog("redis配置为空")
|
||||
// return nil
|
||||
//}
|
||||
|
||||
// 初始化mysql配置对象
|
||||
dbConfigObj = newMysqlConfig(
|
||||
mysqlUtil.NewDBConfig(ConfigYaml.Root.DbConfig.AdminDB.ConnectionString, ConfigYaml.Root.DbConfig.AdminDB.MaxOpenConns, ConfigYaml.Root.DbConfig.AdminDB.MaxIdleConns),
|
||||
mysqlUtil.NewDBConfig(ConfigYaml.Root.DbConfig.UserDB.ConnectionString, ConfigYaml.Root.DbConfig.UserDB.MaxOpenConns, ConfigYaml.Root.DbConfig.UserDB.MaxIdleConns),
|
||||
mysqlUtil.NewDBConfig(ConfigYaml.Root.DbConfig.GameModel.ConnectionString, ConfigYaml.Root.DbConfig.GameModel.MaxOpenConns, ConfigYaml.Root.DbConfig.GameModel.MaxIdleConns),
|
||||
mysqlUtil.NewDBConfig(ConfigYaml.Root.DbConfig.GameDB.ConnectionString, ConfigYaml.Root.DbConfig.GameDB.MaxOpenConns, ConfigYaml.Root.DbConfig.GameDB.MaxIdleConns),
|
||||
mysqlUtil.NewDBConfig(ConfigYaml.Root.DbConfig.PlayerDB.ConnectionString, ConfigYaml.Root.DbConfig.PlayerDB.MaxOpenConns, ConfigYaml.Root.DbConfig.PlayerDB.MaxIdleConns),
|
||||
redisUtil.NewRedisConfig2(redisConfig.ConnectionString, redisConfig.Password, redisConfig.Database, redisConfig.MaxActive, redisConfig.MaxIdle, time.Duration(redisConfig.IdleTimeout)*time.Second, time.Duration(redisConfig.DialConnectTimeout)*time.Second))
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDbConfig
|
||||
//
|
||||
// @description: 获取mysql配置
|
||||
//
|
||||
// parameter:
|
||||
// return:
|
||||
//
|
||||
// @*DbConfig: mysql配置对象
|
||||
func GetDbConfig() *DbConfig {
|
||||
return dbConfigObj
|
||||
}
|
||||
63
trunk/center/common/configsYaml/functionConfig.go
Normal file
63
trunk/center/common/configsYaml/functionConfig.go
Normal file
@ -0,0 +1,63 @@
|
||||
package configYaml
|
||||
|
||||
// FunctionConfig
|
||||
//
|
||||
// @description: 功能开关配置
|
||||
type FunctionConfig struct {
|
||||
|
||||
// 游戏代码
|
||||
GameCode string
|
||||
|
||||
// 仙术副本 清理过期房间信息时间 5 分钟
|
||||
MagicCopyTeamOutTime int
|
||||
|
||||
// 请求青瓷的Url
|
||||
QCSdk_Url string
|
||||
|
||||
// 请求青瓷的GameCode
|
||||
QCSdk_GameCode string
|
||||
|
||||
// 请求青瓷的GameId
|
||||
QCSdk_GameId string
|
||||
|
||||
// 请求青瓷的加密signKey
|
||||
QCSdk_SignKey string
|
||||
}
|
||||
|
||||
var (
|
||||
// 功能开关配置对象
|
||||
functionConfigObj *FunctionConfig
|
||||
)
|
||||
|
||||
// initFunctionConfig
|
||||
//
|
||||
// @description: 加载功能开关配置
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @configObj: 开关配置
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @error: 错误信息
|
||||
func initFunctionConfig() error {
|
||||
functionConfigObj = &FunctionConfig{}
|
||||
|
||||
functionConfig := ConfigYaml.Root.FunctionConfig
|
||||
|
||||
functionConfigObj.GameCode = functionConfig.GameCode
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFunctionConfigObj
|
||||
//
|
||||
// @description: 获取功能开关配置对象
|
||||
//
|
||||
// parameter:
|
||||
// return:
|
||||
//
|
||||
// @*FunctionConfig:
|
||||
func GetFunctionConfigObj() *FunctionConfig {
|
||||
return functionConfigObj
|
||||
}
|
||||
61
trunk/center/common/configsYaml/init.go
Normal file
61
trunk/center/common/configsYaml/init.go
Normal file
@ -0,0 +1,61 @@
|
||||
package configYaml
|
||||
|
||||
import (
|
||||
"framework/configMgr"
|
||||
"gopkg.in/yaml.v3"
|
||||
"goutil/logUtil"
|
||||
"goutil/yamlUtil"
|
||||
"log"
|
||||
)
|
||||
|
||||
var (
|
||||
// 配置对象
|
||||
|
||||
configManager = configMgr.NewConfigManager()
|
||||
)
|
||||
|
||||
// init
|
||||
//
|
||||
// @description: init
|
||||
//
|
||||
// parameter:
|
||||
// return:
|
||||
func init() {
|
||||
// 设置日志文件的存储目录
|
||||
logUtil.SetLogPath("LOG")
|
||||
|
||||
if err := reloadConfig(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//加载配置
|
||||
initBaseConfig()
|
||||
initDbConfig()
|
||||
initFunctionConfig()
|
||||
initLogMgrConfig()
|
||||
}
|
||||
|
||||
// reloadConfig
|
||||
//
|
||||
// @description: reloadConfig
|
||||
//
|
||||
// parameter:
|
||||
// return:
|
||||
//
|
||||
// @error: 错误信息
|
||||
func reloadConfig() error {
|
||||
|
||||
yamlFile, err := yamlUtil.LoadFromFile("config.yaml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析 YAML 文件
|
||||
err = yaml.Unmarshal(yamlFile, &ConfigYaml)
|
||||
if err != nil {
|
||||
log.Fatalf("Error unmarshalling config file: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
62
trunk/center/common/configsYaml/logMgrConfig.go
Normal file
62
trunk/center/common/configsYaml/logMgrConfig.go
Normal file
@ -0,0 +1,62 @@
|
||||
package configYaml
|
||||
|
||||
import (
|
||||
"goutil/logUtilPlus"
|
||||
)
|
||||
|
||||
// LogMgrConfig
|
||||
//
|
||||
// @description: logMgr配置对象
|
||||
type LogMgrConfig struct {
|
||||
// 组id
|
||||
GroupId string
|
||||
|
||||
// 组秘钥
|
||||
GroupSecret string
|
||||
|
||||
// 项目id
|
||||
ProductId string
|
||||
}
|
||||
|
||||
var (
|
||||
// logMgr配置对象
|
||||
logMgrConfigObj *LogMgrConfig
|
||||
)
|
||||
|
||||
// initLogMgrConfig
|
||||
//
|
||||
// @description: 初始化LogMgr配置
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @configObj:
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @error: 错误信息
|
||||
func initLogMgrConfig() error {
|
||||
|
||||
logUtilPlus.DebugLog("开始加载LogMgr")
|
||||
|
||||
logMgr := ConfigYaml.Root.LogMgr
|
||||
|
||||
logMgrConfigObj = &LogMgrConfig{
|
||||
GroupId: logMgr.GroupId,
|
||||
GroupSecret: logMgr.GroupSecret,
|
||||
ProductId: logMgr.ProductId,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetLogMgrConfig
|
||||
//
|
||||
// @description: 获取游戏模型数据库链接字符串
|
||||
//
|
||||
// parameter:
|
||||
// return:
|
||||
//
|
||||
// @*LogMgrConfig: 游戏模型数据库链接字符串
|
||||
func GetLogMgrConfig() *LogMgrConfig {
|
||||
return logMgrConfigObj
|
||||
}
|
||||
225
trunk/center/common/connection/dal.go
Normal file
225
trunk/center/common/connection/dal.go
Normal file
@ -0,0 +1,225 @@
|
||||
package connection
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"framework/sqlAsyncMgr"
|
||||
goredis "github.com/go-redis/redis/v8"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"goutil/logUtilPlus"
|
||||
"time"
|
||||
|
||||
// _ "github.com/go-sql-driver/mysql"
|
||||
config "common/configsYaml"
|
||||
"goutil/mysqlUtil"
|
||||
"goutil/redisUtil"
|
||||
)
|
||||
|
||||
var (
|
||||
adminDB *gorm.DB //管理员数据库对象
|
||||
userDB *gorm.DB //用户数据库对象
|
||||
gameModelDB *gorm.DB // 游戏模型数据库对象
|
||||
gameDB *gorm.DB // 游戏数据库
|
||||
gamePlayerDB *gorm.DB // 玩家库
|
||||
redisDB *goredis.Client // 游戏redis连接客户端
|
||||
syncMgr *sqlAsyncMgr.SqlAsyncUtil // 同步管理对象
|
||||
syncFileSize = 1024 * 1024 // 同步文件大小
|
||||
fileMaxSaveTime = 24 * 7 // 保留7天的sql文件
|
||||
)
|
||||
|
||||
var excuteSqlFunc func(*gorm.DB, ITable, string) error
|
||||
var loghandle func(s string, is ...interface{})
|
||||
var defaultType = SyncSql
|
||||
|
||||
type ITable interface {
|
||||
TableName() string
|
||||
}
|
||||
|
||||
type SqlExecuteType int32
|
||||
|
||||
const (
|
||||
SyncSql SqlExecuteType = iota
|
||||
ASyncSql
|
||||
Name = "BaseDal"
|
||||
)
|
||||
|
||||
// init
|
||||
// @description: init
|
||||
// parameter:
|
||||
// return:
|
||||
func init() {
|
||||
|
||||
//管理中心数据库配置
|
||||
adminDB = initMysql(config.GetDbConfig().GetAdminConfig())
|
||||
userDB = initMysql(config.GetDbConfig().GetUserConfig())
|
||||
|
||||
// 初始化游戏模型数据库
|
||||
gameModelDBConfig := config.GetDbConfig().GetGameModelConfig()
|
||||
gameModelDB = initMysql(gameModelDBConfig)
|
||||
|
||||
// 初始化crossSever 游戏数据库
|
||||
gameDBConfig := config.GetDbConfig().GetGameConfig()
|
||||
gameDB = initMysql(gameDBConfig)
|
||||
gamePlayerDB = initMysql(config.GetDbConfig().GetPlayerConfig())
|
||||
|
||||
// 初始化redis-client
|
||||
excuteSqlFunc = func(gdb *gorm.DB, table ITable, sql string) error {
|
||||
db := gdb.Exec(sql)
|
||||
if db.Error != nil {
|
||||
loghandle("sql执行错误:%s;错误信息:%v", sql, db.Error.Error())
|
||||
return db.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
redisDB = initRedis(config.GetDbConfig().GetRedisConfig())
|
||||
}
|
||||
|
||||
// 初始化Mysql
|
||||
// initMysql
|
||||
// @description: 初始化Mysql
|
||||
// parameter:
|
||||
// @dbConfig: dbConfig
|
||||
// return:
|
||||
// @*gorm.DB: DB
|
||||
func initMysql(dbConfig *mysqlUtil.DBConfig) *gorm.DB {
|
||||
|
||||
//不存在配置
|
||||
if dbConfig == nil || dbConfig.ConnectionString == "" {
|
||||
return nil
|
||||
}
|
||||
logUtilPlus.WarnLog("开始连接mysql:%s", dbConfig.ConnectionString)
|
||||
dbObj, err := gorm.Open(mysql.Open(dbConfig.ConnectionString), &gorm.Config{})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("初始化数据库:%s失败,错误信息为:%s", dbConfig.ConnectionString, err))
|
||||
}
|
||||
logUtilPlus.WarnLog("连接mysql:%s成功", dbConfig.ConnectionString)
|
||||
|
||||
return dbObj
|
||||
}
|
||||
|
||||
// initRedis
|
||||
// @description: 初始化redis客户端
|
||||
// parameter:
|
||||
// @redisConfig: redisConfig
|
||||
// return:
|
||||
// @*goredis.Client: Client
|
||||
func initRedis(redisConfig *redisUtil.RedisConfig) *goredis.Client {
|
||||
|
||||
client := goredis.NewClient(&goredis.Options{
|
||||
Addr: redisConfig.ConnectionString,
|
||||
Password: redisConfig.Password,
|
||||
DB: redisConfig.Database,
|
||||
IdleTimeout: redisConfig.IdleTimeout,
|
||||
DialTimeout: redisConfig.DialConnectTimeout,
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
|
||||
ping, err := client.Ping(ctx).Result()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("ping->redis:%s失败,DB:%s,错误信息为:%s", redisConfig.ConnectionString, redisConfig.Database, err))
|
||||
}
|
||||
|
||||
logUtilPlus.WarnLog("ping->redis:%s成功,信息为:%s", redisConfig.ConnectionString, ping)
|
||||
return client
|
||||
}
|
||||
|
||||
// GetAdminDB
|
||||
// @description: 获取admin库db实例
|
||||
// parameter:
|
||||
// return:
|
||||
// @*gorm.DB:admin库db实例
|
||||
func GetAdminDB() *gorm.DB {
|
||||
return adminDB
|
||||
}
|
||||
|
||||
// GetUserDB
|
||||
// @description: 获取user库db实例
|
||||
// parameter:
|
||||
// return:
|
||||
// @*gorm.DB:user库db实例
|
||||
func GetUserDB() *gorm.DB {
|
||||
return userDB
|
||||
}
|
||||
|
||||
// GetGameDB
|
||||
// @description: 获取game库db实例
|
||||
// parameter:
|
||||
// return:
|
||||
// @*gorm.DB:game库db实例
|
||||
func GetGameDB() *gorm.DB {
|
||||
return gameDB
|
||||
}
|
||||
|
||||
// GetPlayerDB
|
||||
// @description: 获取玩家库db实例
|
||||
// parameter:
|
||||
// return:
|
||||
// @*gorm.DB:玩家库db实例
|
||||
func GetPlayerDB() *gorm.DB {
|
||||
return gamePlayerDB
|
||||
}
|
||||
|
||||
// GetGameModelDB
|
||||
// @description: 获取model库db实例
|
||||
// parameter:
|
||||
// return:
|
||||
// @*gorm.DB:model库db实例
|
||||
func GetGameModelDB() *gorm.DB {
|
||||
return gameModelDB
|
||||
}
|
||||
|
||||
// GetRedisClient
|
||||
// @description: 获取redisdb实例
|
||||
// parameter:
|
||||
// return:
|
||||
// @*goredis.Client:redisdb实例
|
||||
func GetRedisClient() *goredis.Client {
|
||||
return redisDB
|
||||
}
|
||||
|
||||
// GetAll
|
||||
// @description: 获取model数据
|
||||
// parameter:
|
||||
// @dataList:数据列表
|
||||
// return:
|
||||
// @error:错误信息
|
||||
func GetAll(dataList interface{}) error {
|
||||
mysqlObj := GetGameModelDB()
|
||||
if mysqlObj = mysqlObj.Find(dataList); mysqlObj.Error != nil {
|
||||
WriteLog("dal.GetAll", mysqlObj.Error)
|
||||
return mysqlObj.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetGameModelData
|
||||
// @description: 获取GameModel数据
|
||||
// parameter:
|
||||
// @moduleName:模块名称
|
||||
// @dataList:数据列表
|
||||
// return:
|
||||
// @error:错误信息
|
||||
func GetGameModelData(moduleName string, dataList interface{}) error {
|
||||
if result := gameModelDB.Find(dataList); result.Error != nil {
|
||||
WriteLog(moduleName+"GetGameModelData", result.Error)
|
||||
return result.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteLog
|
||||
// @description: 记录错误日志
|
||||
// parameter:
|
||||
// @command:命令
|
||||
// @err:错误信息
|
||||
// return:
|
||||
func WriteLog(command string, err error) {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("Scan失败,错误信息:%s,command:%s", err, command))
|
||||
}
|
||||
31
trunk/center/common/connection/dal_test.go
Normal file
31
trunk/center/common/connection/dal_test.go
Normal file
@ -0,0 +1,31 @@
|
||||
package connection
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type testDal struct{}
|
||||
|
||||
func (t testDal) TableName() string {
|
||||
return "test"
|
||||
}
|
||||
|
||||
var TestDal = testDal{}
|
||||
|
||||
type User struct {
|
||||
ID uint `gorm:"primary_key"`
|
||||
Name string `gorm:"column:name"`
|
||||
Age int `gorm:"column:age"`
|
||||
Birthday time.Time `gorm:"column:birthday"`
|
||||
}
|
||||
|
||||
func TestExecute(t *testing.T) {
|
||||
user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
|
||||
|
||||
result := adminDB.Create(&user) // 通过数据的指针来创建
|
||||
|
||||
_ = user.ID // 返回插入数据的主键
|
||||
_ = result.Error // 返回 error
|
||||
_ = result.RowsAffected // 返回插入记录的条数
|
||||
}
|
||||
41
trunk/center/common/connection/dbHead.go
Normal file
41
trunk/center/common/connection/dbHead.go
Normal file
@ -0,0 +1,41 @@
|
||||
package connection
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
var (
|
||||
// 存放实体结构
|
||||
dbModelMap = make([]interface{}, 0)
|
||||
|
||||
//当前管理数据库
|
||||
modelDB *gorm.DB
|
||||
)
|
||||
|
||||
// RegisterDBModel 注册数据库模型到全局变量dbModelMap中。
|
||||
// 这个函数接受一个interface{}类型的参数dbModel,表示数据库模型。
|
||||
// 函数的目的是将传入的数据库模型添加到全局变量dbModelMap中,
|
||||
// 以便在其他地方可以访问和使用这些数据库模型。
|
||||
func RegisterDBModel(dbModel interface{}) {
|
||||
// 将dbModel的地址添加到dbModelMap中。
|
||||
// 这里使用地址是因为数据库模型可能比较大,通过引用存储可以提高效率。
|
||||
dbModelMap = append(dbModelMap, &dbModel)
|
||||
}
|
||||
|
||||
// 设置modelDB 类型
|
||||
func SetModelDB(db *gorm.DB) {
|
||||
modelDB = db
|
||||
}
|
||||
|
||||
// BuildDB 用于遍历dbModelMap中的所有数据库模型,并检查每个模型对应的表是否存在于数据库中。
|
||||
// 如果表不存在,则自动迁移(创建)该表。这样可以确保数据库模式与程序中的模型保持同步。
|
||||
func BuildDB() {
|
||||
// 遍历dbModelMap中的每个元素
|
||||
for _, dbModel := range dbModelMap {
|
||||
|
||||
// 检查数据库中是否存在与dbModel对应的表
|
||||
tableExists := modelDB.Migrator().HasTable(dbModel)
|
||||
if !tableExists {
|
||||
// 如果表不存在,则进行自动迁移
|
||||
modelDB.AutoMigrate(dbModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
35
trunk/center/common/go.mod
Normal file
35
trunk/center/common/go.mod
Normal file
@ -0,0 +1,35 @@
|
||||
module common
|
||||
|
||||
go 1.22.10
|
||||
|
||||
toolchain go1.23.4
|
||||
|
||||
replace (
|
||||
framework => ../../framework
|
||||
goutil => ../../goutil
|
||||
)
|
||||
|
||||
require (
|
||||
framework v0.0.0-20230425160006-b2d0b0a0b0b0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
gorm.io/gorm v1.25.12
|
||||
goutil v0.0.0-20230425160006-b2d0b0a0b0b0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/gomodule/redigo v1.8.9 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/stretchr/testify v1.8.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
)
|
||||
231
trunk/center/common/go.sum
Normal file
231
trunk/center/common/go.sum
Normal file
@ -0,0 +1,231 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Shopify/sarama v1.29.1/go.mod h1:mdtqvCSg8JOxk8PmpTNGyo6wzd4BMm4QXSfDnTXmgkE=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
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/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4 h1:OoL469zqSNrTLSz5zeVF/I6VOO7fiw2bzSzQe4J557c=
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4/go.mod h1:xe9a/L2aeOgFKKgrO3ibQTnMdpAeL0GC+5/HpGScSa4=
|
||||
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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
|
||||
github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rabbitmq/amqp091-go v1.8.1/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20201211165307-7117e9ea2414/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.230/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vms v1.0.230/go.mod h1:zElyabRGi8DktckzhT3krsYChstFJdSrzDb7pwF2P58=
|
||||
github.com/xdg/scram v1.0.3/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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=
|
||||
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
191
trunk/center/common/httpServer/apiContext.go
Normal file
191
trunk/center/common/httpServer/apiContext.go
Normal file
@ -0,0 +1,191 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"goutil/logUtilPlus"
|
||||
"goutil/typeUtil"
|
||||
"goutil/zlibUtil"
|
||||
)
|
||||
|
||||
// ApiContext
|
||||
// @description: Api请求上下文对象
|
||||
type ApiContext struct {
|
||||
// 请求对象
|
||||
request *http.Request
|
||||
|
||||
// 应答写对象
|
||||
responseWriter http.ResponseWriter
|
||||
|
||||
// 请求数据
|
||||
requestBytes []byte
|
||||
|
||||
// 字典形式的请求数据
|
||||
requestDataByMap typeUtil.MapData
|
||||
}
|
||||
|
||||
// GetRequest
|
||||
// @description: 获取请求对象
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @*http.Request: 请求对象
|
||||
func (this *ApiContext) GetRequest() *http.Request {
|
||||
return this.request
|
||||
}
|
||||
|
||||
// GetResponseWriter
|
||||
// @description: 获取应答写对象
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @http.ResponseWriter: 应答写对象
|
||||
func (this *ApiContext) GetResponseWriter() http.ResponseWriter {
|
||||
return this.responseWriter
|
||||
}
|
||||
|
||||
// GetRequestBytes
|
||||
// @description: 获取请求字节数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]byte: 请求字节数组
|
||||
func (this *ApiContext) GetRequestBytes() []byte {
|
||||
return this.requestBytes
|
||||
}
|
||||
|
||||
// readContent
|
||||
// @description: 读取内容
|
||||
// parameter:
|
||||
// @receiver this: this 请求对象
|
||||
// @isZlib: 是否数据压缩
|
||||
// return:
|
||||
// @content: 二进制格式的内容
|
||||
// @err: 错误对象
|
||||
func (this *ApiContext) readContent(isZlib bool) (content []byte, err error) {
|
||||
var buffer []byte
|
||||
|
||||
defer this.request.Body.Close()
|
||||
if buffer, err = ioutil.ReadAll(this.request.Body); err != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("url:%s,读取数据出错,错误信息为:%s", this.request.RequestURI, err))
|
||||
return
|
||||
}
|
||||
|
||||
// 不压缩,则直接返回
|
||||
if isZlib == false {
|
||||
this.requestBytes = buffer
|
||||
|
||||
return buffer, err
|
||||
}
|
||||
|
||||
// 解压数据
|
||||
if content, err = zlibUtil.Decompress(buffer); err != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("url:%s,解压缩数据出错,错误信息为:%s", this.request.RequestURI, err))
|
||||
return
|
||||
}
|
||||
|
||||
this.requestBytes = content
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Unmarshal
|
||||
// @description: 反序列化
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// @obj: 反序列化结果数据
|
||||
// return:
|
||||
// @error: 反序列化错误数据
|
||||
func (this *ApiContext) Unmarshal(obj interface{}) error {
|
||||
contentData := this.GetRequestBytes()
|
||||
|
||||
// 反序列化
|
||||
if errMsg := json.Unmarshal(contentData, &obj); errMsg != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("反序列化%s出错,错误信息为:%s", string(contentData), errMsg.Error()))
|
||||
return errMsg
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RequestDataByMap
|
||||
// @description: 获取请求的map格式数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @typeUtil.MapData: map数据
|
||||
// @error: 错误信息
|
||||
func (this *ApiContext) RequestDataByMap() (typeUtil.MapData, error) {
|
||||
if this.requestDataByMap != nil {
|
||||
return this.requestDataByMap, nil
|
||||
}
|
||||
|
||||
var data typeUtil.MapData
|
||||
if err := this.Unmarshal(&data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
this.requestDataByMap = data
|
||||
|
||||
return this.requestDataByMap, nil
|
||||
}
|
||||
|
||||
// RequestDataBySlice
|
||||
// @description: 获取请求的slice格式数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]interface{}: 返回的数组数据
|
||||
func (this *ApiContext) RequestDataBySlice() []interface{} {
|
||||
result := make([]interface{}, 0, 8)
|
||||
for _, value := range this.requestDataByMap {
|
||||
result = append(result, value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// RequestDataBySlice2
|
||||
// @description: 获取请求的slice格式数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]interface{}: 返回的数组数据
|
||||
// @error:
|
||||
func (this *ApiContext) RequestDataBySlice2() ([]interface{}, error) {
|
||||
contentData := this.GetRequestBytes()
|
||||
|
||||
// 反序列化
|
||||
result := make([]interface{}, 0, 8)
|
||||
if errMsg := json.Unmarshal(contentData, &result); errMsg != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("用[]interface{}反序列化%s出错,错误信息为:%s", string(contentData), errMsg.Error()))
|
||||
return nil, errMsg
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewApiContext
|
||||
// @description: 新建API上下文对象
|
||||
// parameter:
|
||||
// @_request: 请求对象
|
||||
// @_responseWriter: 应答写对象
|
||||
// @isZlib: 数据是否压缩
|
||||
// return:
|
||||
// @*ApiContext: 上下文
|
||||
// @error: 错误信息
|
||||
func NewApiContext(_request *http.Request, _responseWriter http.ResponseWriter, isZlib bool) (*ApiContext, error) {
|
||||
context := &ApiContext{
|
||||
request: _request,
|
||||
responseWriter: _responseWriter,
|
||||
}
|
||||
|
||||
// 读取数据
|
||||
_, errMsg := context.readContent(isZlib)
|
||||
if errMsg != nil {
|
||||
return nil, errMsg
|
||||
}
|
||||
|
||||
return context, nil
|
||||
}
|
||||
87
trunk/center/common/httpServer/apiHandler.go
Normal file
87
trunk/center/common/httpServer/apiHandler.go
Normal file
@ -0,0 +1,87 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
"common/webServer"
|
||||
"net/http"
|
||||
|
||||
"common/resultStatus"
|
||||
)
|
||||
|
||||
// 处理函数
|
||||
type HandleFunc func(context *ApiContext) *webServer.ResponseObject
|
||||
|
||||
// ApiHandler
|
||||
// @description: API处理结构
|
||||
type ApiHandler struct {
|
||||
// API完整路径名称
|
||||
apiFullName string
|
||||
|
||||
// 方法定义
|
||||
handleFun HandleFunc
|
||||
|
||||
// 方法参数名称集合
|
||||
funcParamNames []string
|
||||
}
|
||||
|
||||
// ApiFullName
|
||||
// @description: API完整路径名称
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @string:
|
||||
func (this *ApiHandler) ApiFullName() string {
|
||||
return this.apiFullName
|
||||
}
|
||||
|
||||
// HandleFun
|
||||
// @description: 方法定义
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @HandleFunc: 方法
|
||||
func (this *ApiHandler) HandleFun() HandleFunc {
|
||||
return this.handleFun
|
||||
}
|
||||
|
||||
// FuncParamNames
|
||||
// @description: 方法参数名称集合
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]string: 方法参数名称集合
|
||||
func (this *ApiHandler) FuncParamNames() []string {
|
||||
return this.funcParamNames
|
||||
}
|
||||
|
||||
// CheckParam
|
||||
// @description: 检测参数数量
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// @r:
|
||||
// return:
|
||||
// @resultStatus.ResultStatus: 状态码数据
|
||||
func (this *ApiHandler) CheckParam(r *http.Request) resultStatus.ResultStatus {
|
||||
for _, name := range this.funcParamNames {
|
||||
if r.Form[name] == nil || len(r.Form[name]) == 0 {
|
||||
return resultStatus.APIParamError
|
||||
}
|
||||
}
|
||||
|
||||
return resultStatus.Success
|
||||
}
|
||||
|
||||
// newApiHandler
|
||||
// @description: 创建新的请求方法对象
|
||||
// parameter:
|
||||
// @_apiFullName: API完整路径名称
|
||||
// @_funcDefinition: 方法定义
|
||||
// @_funcParamNames: 方法参数名称集合
|
||||
// return:
|
||||
// @*ApiHandler: 请求方法对象
|
||||
func newApiHandler(_apiFullName string, _funcDefinition HandleFunc, _funcParamNames ...string) *ApiHandler {
|
||||
return &ApiHandler{
|
||||
apiFullName: _apiFullName,
|
||||
handleFun: _funcDefinition,
|
||||
funcParamNames: _funcParamNames,
|
||||
}
|
||||
}
|
||||
56
trunk/center/common/httpServer/apiHandlerMgr.go
Normal file
56
trunk/center/common/httpServer/apiHandlerMgr.go
Normal file
@ -0,0 +1,56 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
// 处理方法集合
|
||||
// Key:API名
|
||||
handlerData = make(map[string]*ApiHandler)
|
||||
|
||||
// 文档方法
|
||||
remarkFunc func(w http.ResponseWriter, r *http.Request)
|
||||
)
|
||||
|
||||
// RegisterRemarkFunc
|
||||
// @description: 注册文档api方法
|
||||
// parameter:
|
||||
// @_remarkFunc: _remarkFunc
|
||||
// return:
|
||||
func RegisterRemarkFunc(_remarkFunc func(w http.ResponseWriter, r *http.Request)) {
|
||||
remarkFunc = _remarkFunc
|
||||
}
|
||||
|
||||
// RegisterHandleFunc
|
||||
// @description: 注册处理方法
|
||||
// parameter:
|
||||
// @apiName: API名称
|
||||
// @callback: 回调方法
|
||||
// @paramNames: 参数名称集合
|
||||
// return:
|
||||
func RegisterHandleFunc(apiName string, callback HandleFunc, paramNames ...string) {
|
||||
apiFullName := fmt.Sprintf("/API/%s", apiName)
|
||||
|
||||
if _, exist := handlerData[apiFullName]; exist {
|
||||
panic(fmt.Errorf("重复注册处理函数:%s", apiFullName))
|
||||
}
|
||||
|
||||
handlerData[apiFullName] = newApiHandler(apiFullName, callback, paramNames...)
|
||||
}
|
||||
|
||||
// GetHandleFunc
|
||||
// @description: 获取请求方法
|
||||
// parameter:
|
||||
// @apiFullName: 方法名称
|
||||
// return:
|
||||
// @*ApiHandler: 请求方法
|
||||
// @bool: 是否存在
|
||||
func GetHandleFunc(apiFullName string) (*ApiHandler, bool) {
|
||||
if requestFuncObj, exists := handlerData[apiFullName]; exists {
|
||||
return requestFuncObj, exists
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
400
trunk/center/common/httpServer/reflect.go
Normal file
400
trunk/center/common/httpServer/reflect.go
Normal file
@ -0,0 +1,400 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
config "common/configsYaml"
|
||||
"common/resultStatus"
|
||||
"common/webServer"
|
||||
"goutil/logUtilPlus"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// 供客户端访问的模块的后缀
|
||||
con_ModuleSuffix = "Module"
|
||||
|
||||
// 定义用于分隔模块名称和方法名称的分隔符
|
||||
con_DelimeterOfObjAndMethod = "_"
|
||||
)
|
||||
|
||||
var (
|
||||
// 定义存放所有方法映射的变量
|
||||
methodMap = make(map[string]*methodAndInOutTypes)
|
||||
|
||||
// 函数返回值类型
|
||||
responseType reflect.Type = reflect.TypeOf(new(webServer.ResponseObject))
|
||||
)
|
||||
|
||||
// getStructName
|
||||
// @description: 获取结构体类型的名称
|
||||
// parameter:
|
||||
// @structType: 结构体类型
|
||||
// return:
|
||||
// @string: 结构体类型的名称
|
||||
func getStructName(structType reflect.Type) string {
|
||||
reflectTypeStr := structType.String()
|
||||
reflectTypeArr := strings.Split(reflectTypeStr, ".")
|
||||
|
||||
return reflectTypeArr[len(reflectTypeArr)-1]
|
||||
}
|
||||
|
||||
// getFullModuleName
|
||||
// @description: 获取完整的模块名称
|
||||
// parameter:
|
||||
// @moduleName: 模块名称
|
||||
// return:
|
||||
// @string: 完整的模块名称
|
||||
func getFullModuleName(moduleName string) string {
|
||||
return moduleName + con_ModuleSuffix
|
||||
}
|
||||
|
||||
// getFullMethodName
|
||||
// @description: 获取完整的方法名称
|
||||
// parameter:
|
||||
// @structName: 结构体名称
|
||||
// @methodName: 方法名称
|
||||
// return:
|
||||
// @string: 完整的方法名称
|
||||
func getFullMethodName(structName, methodName string) string {
|
||||
return structName + con_DelimeterOfObjAndMethod + methodName
|
||||
}
|
||||
|
||||
// resolveMethodInOutParams
|
||||
// @description: 解析方法的输入输出参数
|
||||
// parameter:
|
||||
// @method: 方法对应的反射值
|
||||
// return:
|
||||
// @inTypes: 输入参数类型集合
|
||||
// @outTypes: 输出参数类型集合
|
||||
func resolveMethodInOutParams(method reflect.Value) (inTypes []reflect.Type, outTypes []reflect.Type) {
|
||||
methodType := method.Type()
|
||||
for i := 0; i < methodType.NumIn(); i++ {
|
||||
inTypes = append(inTypes, methodType.In(i))
|
||||
}
|
||||
|
||||
for i := 0; i < methodType.NumOut(); i++ {
|
||||
outTypes = append(outTypes, methodType.Out(i))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RegisterFunction
|
||||
// @description: 将需要对客户端提供方法的对象进行注册
|
||||
// parameter:
|
||||
// @structObject: 对象
|
||||
// return:
|
||||
func RegisterFunction(structObject interface{}) {
|
||||
// 获取structObject对应的反射 Type 和 Value
|
||||
reflectValue := reflect.ValueOf(structObject)
|
||||
reflectType := reflect.TypeOf(structObject)
|
||||
|
||||
// 提取对象类型名称
|
||||
structName := getStructName(reflectType)
|
||||
|
||||
// 获取structObject中返回值为responseObject的方法
|
||||
for i := 0; i < reflectType.NumMethod(); i++ {
|
||||
// 获得方法名称
|
||||
methodName := reflectType.Method(i).Name
|
||||
|
||||
// 获得方法及其输入参数的类型列表
|
||||
method := reflectValue.MethodByName(methodName)
|
||||
inTypes, outTypes := resolveMethodInOutParams(method)
|
||||
|
||||
// 判断输出参数数量是否正确
|
||||
if len(outTypes) != 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 判断返回值是否为responseObject
|
||||
if outTypes[0] != responseType {
|
||||
continue
|
||||
}
|
||||
|
||||
// 添加到列表中
|
||||
methodMap[getFullMethodName(structName, methodName)] = newmethodAndInOutTypes(method, inTypes, outTypes)
|
||||
}
|
||||
}
|
||||
|
||||
// CallFunction
|
||||
// @description: 调用方法
|
||||
// parameter:
|
||||
// @requestObj: 客户端对象
|
||||
// return:
|
||||
// @responseObj: 请求对象
|
||||
func CallFunction(requestObj *webServer.RequestObject) (responseObj *webServer.ResponseObject) {
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
var methodAndInOutTypes *methodAndInOutTypes
|
||||
var ok bool
|
||||
|
||||
// 根据传入的ModuleName和MethodName找到对应的方法对象
|
||||
key := getFullMethodName(requestObj.ModuleName, requestObj.MethodName)
|
||||
if methodAndInOutTypes, ok = methodMap[key]; !ok {
|
||||
logUtilPlus.ErrorLog("找不到指定的方法:%s", key)
|
||||
responseObj.SetResultStatus(resultStatus.NotSpecificMethod)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断参数数量是否相同
|
||||
inTypesLength := len(methodAndInOutTypes.InTypes)
|
||||
paramLength := len(requestObj.Parameters)
|
||||
if paramLength != inTypesLength {
|
||||
logUtilPlus.ErrorLog("传入的参数数量不符,本地方法%s的参数数量:%d,传入的参数数量为:%d", key, inTypesLength, paramLength)
|
||||
responseObj.SetResultStatus(resultStatus.ParamNotMatch)
|
||||
return
|
||||
}
|
||||
|
||||
// 构造参数
|
||||
in := make([]reflect.Value, inTypesLength)
|
||||
for i := 0; i < inTypesLength; i++ {
|
||||
inTypeItem := methodAndInOutTypes.InTypes[i]
|
||||
paramItem := requestObj.Parameters[i]
|
||||
|
||||
// 已支持类型:Client,Player(非基本类型)
|
||||
// 已支持类型:Bool,Int,Int8,Int16,Int32,Int64,Uint,Uint8,Uint16,Uint32,Uint64,Float32,Float64,String
|
||||
// 已支持类型:以及上面所列出类型的Slice类型
|
||||
// 未支持类型:Uintptr,Complex64,Complex128,Array,Chan,Func,Interface,Map,Ptr,Struct,UnsafePointer
|
||||
// 由于byte与int8同义,rune与int32同义,所以并不需要单独处理
|
||||
// 枚举参数的类型,并进行类型转换
|
||||
switch inTypeItem.Kind() {
|
||||
case reflect.Bool:
|
||||
if param_bool, ok := paramItem.(bool); ok {
|
||||
in[i] = reflect.ValueOf(param_bool)
|
||||
}
|
||||
case reflect.Int:
|
||||
if param_float64, ok := paramItem.(int); ok {
|
||||
in[i] = reflect.ValueOf(int(param_float64))
|
||||
}
|
||||
case reflect.Int8:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int8(param_float64))
|
||||
}
|
||||
case reflect.Int16:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int16(param_float64))
|
||||
}
|
||||
case reflect.Int32:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int32(param_float64))
|
||||
}
|
||||
case reflect.Int64:
|
||||
if param_float64, ok := paramItem.(int64); ok {
|
||||
in[i] = reflect.ValueOf(int64(param_float64))
|
||||
} else if param_uint64, ok := paramItem.(uint64); ok {
|
||||
in[i] = reflect.ValueOf(int64(param_uint64))
|
||||
} else if param_string, ok := paramItem.(string); ok {
|
||||
|
||||
i64, err := strconv.ParseInt(param_string, 10, 64)
|
||||
|
||||
if err == nil {
|
||||
in[i] = reflect.ValueOf(i64)
|
||||
}
|
||||
}
|
||||
case reflect.Uint:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint(param_float64))
|
||||
}
|
||||
case reflect.Uint8:
|
||||
if param_float64, ok := paramItem.(uint8); ok {
|
||||
in[i] = reflect.ValueOf(uint8(param_float64))
|
||||
}
|
||||
case reflect.Uint16:
|
||||
if param_float64, ok := paramItem.(uint16); ok {
|
||||
in[i] = reflect.ValueOf(uint16(param_float64))
|
||||
}
|
||||
case reflect.Uint32:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint32(param_float64))
|
||||
}
|
||||
case reflect.Uint64:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint64(param_float64))
|
||||
}
|
||||
case reflect.Float32:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(float32(param_float64))
|
||||
}
|
||||
case reflect.Float64:
|
||||
if param_float64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(param_float64)
|
||||
}
|
||||
case reflect.String:
|
||||
if param_string, ok := paramItem.(string); ok {
|
||||
in[i] = reflect.ValueOf(param_string)
|
||||
}
|
||||
case reflect.Slice:
|
||||
// 如果是Slice类型,则需要对其中的项再次进行类型判断及类型转换
|
||||
if param_interface, ok := paramItem.([]interface{}); ok {
|
||||
switch inTypeItem.String() {
|
||||
case "[]bool":
|
||||
params_inner := make([]bool, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_bool, ok := param_interface[i].(bool); ok {
|
||||
params_inner[i] = param_bool
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int":
|
||||
params_inner := make([]int, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(int); ok {
|
||||
params_inner[i] = int(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int8":
|
||||
params_inner := make([]int8, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = int8(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int16":
|
||||
params_inner := make([]int16, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = int16(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int32":
|
||||
params_inner := make([]int32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
param_float64, ok := param_interface[i].(int32)
|
||||
if ok {
|
||||
params_inner[i] = int32(param_float64)
|
||||
continue
|
||||
} else {
|
||||
param_int16, right := param_interface[i].(uint16)
|
||||
if right == true {
|
||||
params_inner[i] = int32(param_int16)
|
||||
}
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int64":
|
||||
params_inner := make([]int64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(int64); ok {
|
||||
params_inner[i] = int64(param_float64)
|
||||
} else if param_uint64, ok := param_interface[i].(uint64); ok {
|
||||
params_inner[i] = int64(param_uint64)
|
||||
} else if param_string, ok := param_interface[i].(string); ok {
|
||||
|
||||
i64, err := strconv.ParseInt(param_string, 10, 64)
|
||||
|
||||
if err == nil {
|
||||
params_inner[i] = i64
|
||||
}
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint":
|
||||
params_inner := make([]uint, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint); ok {
|
||||
params_inner[i] = uint(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
// case "[]uint8": 特殊处理
|
||||
case "[]uint16":
|
||||
params_inner := make([]uint16, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint16); ok {
|
||||
params_inner[i] = uint16(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint32":
|
||||
params_inner := make([]uint32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint32); ok {
|
||||
params_inner[i] = uint32(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint64":
|
||||
params_inner := make([]uint64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint64); ok {
|
||||
params_inner[i] = uint64(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]float32":
|
||||
params_inner := make([]float32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = float32(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]float64":
|
||||
params_inner := make([]float64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = param_float64
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]string":
|
||||
params_inner := make([]string, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_string, ok := param_interface[i].(string); ok {
|
||||
params_inner[i] = param_string
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
}
|
||||
} else if inTypeItem.String() == "[]uint8" { // 由于[]uint8在传输过程中会被转化成字符串,所以单独处理;
|
||||
if param_string, ok := paramItem.(string); ok {
|
||||
param_uint8 := ([]uint8)(param_string)
|
||||
in[i] = reflect.ValueOf(param_uint8)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否有无效的参数(传入的参数类型和方法定义的类型不匹配导致没有赋值)
|
||||
for _, item := range in {
|
||||
if reflect.Value.IsValid(item) == false {
|
||||
logUtilPlus.ErrorLog("type:%v,value:%v.方法%s传入的参数%v无效", reflect.TypeOf(item), reflect.ValueOf(item), key, requestObj.Parameters)
|
||||
responseObj.SetResultStatus(resultStatus.ParamInValid)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 传入参数,调用方法
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
logUtilPlus.DebugLog("Begin Call Func:module:%v, method:%v,inParams:%v\n\n", requestObj.ModuleName, requestObj.MethodName, in)
|
||||
}
|
||||
}
|
||||
|
||||
out := methodAndInOutTypes.Method.Call(in)
|
||||
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
for i, v := range in {
|
||||
logUtilPlus.DebugLog("\nparams %v,%v\n", i, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 并输出结果到客户端(由于只有一个返回值,所以取out[0])
|
||||
if responseObj, ok = (&out[0]).Interface().(*webServer.ResponseObject); !ok {
|
||||
logUtilPlus.ErrorLog("返回值类型推断为ResponseObject 出错, tyep is :%v", reflect.TypeOf(out[0]))
|
||||
responseObj.SetResultStatus(resultStatus.ParamInValid)
|
||||
return
|
||||
}
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
logUtilPlus.DebugLog("返回数据:code:%v, data:%v, mess:%v\n\n", responseObj.Code, responseObj.Value, responseObj.Message)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
34
trunk/center/common/httpServer/reflectMethod.go
Normal file
34
trunk/center/common/httpServer/reflectMethod.go
Normal file
@ -0,0 +1,34 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// methodAndInOutTypes
|
||||
// @description: 反射的方法和输入、输出参数类型组合类型
|
||||
type methodAndInOutTypes struct {
|
||||
// 反射出来的对应方法对象
|
||||
Method reflect.Value
|
||||
|
||||
// 反射出来的方法的输入参数的类型集合
|
||||
InTypes []reflect.Type
|
||||
|
||||
// 反射出来的方法的输出参数的类型集合
|
||||
OutTypes []reflect.Type
|
||||
}
|
||||
|
||||
// newmethodAndInOutTypes
|
||||
// @description: newmethodAndInOutTypes
|
||||
// parameter:
|
||||
// @_method: _method
|
||||
// @_inTypes: _inTypes
|
||||
// @_outTypes: _outTypes
|
||||
// return:
|
||||
// @*methodAndInOutTypes: methodAndInOutTypes
|
||||
func newmethodAndInOutTypes(_method reflect.Value, _inTypes []reflect.Type, _outTypes []reflect.Type) *methodAndInOutTypes {
|
||||
return &methodAndInOutTypes{
|
||||
Method: _method,
|
||||
InTypes: _inTypes,
|
||||
OutTypes: _outTypes,
|
||||
}
|
||||
}
|
||||
27
trunk/center/common/httpServer/result.go
Normal file
27
trunk/center/common/httpServer/result.go
Normal file
@ -0,0 +1,27 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
"common/webServer"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"goutil/logUtilPlus"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// responseResult
|
||||
// @description: responseResult
|
||||
// parameter:
|
||||
// @w: w
|
||||
// @responseObj: responseObj
|
||||
// return:
|
||||
func responseResult(w http.ResponseWriter, responseObj *webServer.ResponseObject) {
|
||||
b, err := json.Marshal(responseObj)
|
||||
if err != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("序列化输出结果%v出错", responseObj))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Length", strconv.Itoa(len(b)))
|
||||
w.Write(b)
|
||||
}
|
||||
80
trunk/center/common/httpServer/serverMux.go
Normal file
80
trunk/center/common/httpServer/serverMux.go
Normal file
@ -0,0 +1,80 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
config "common/configsYaml"
|
||||
"common/resultStatus"
|
||||
"common/utils"
|
||||
"common/webServer"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"goutil/logUtilPlus"
|
||||
"goutil/stringUtil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// selfDefineMux
|
||||
// @description: 定义自定义的Mux对象
|
||||
type selfDefineMux struct {
|
||||
}
|
||||
|
||||
// ServeHTTP
|
||||
// @description: ServeHTTP
|
||||
// parameter:
|
||||
// @receiver mux: mux
|
||||
// @w: w
|
||||
// @r: r
|
||||
// return:
|
||||
func (mux *selfDefineMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
responseObj := webServer.GetInitResponseObj()
|
||||
defer utils.LogReqErrorRecover(r)
|
||||
|
||||
// 判断是否是接口文档
|
||||
if strings.Contains(r.RequestURI, "Remarks") && r.Method == "GET" {
|
||||
remarkFunc(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断是否是POST方法
|
||||
if r.Method != "POST" {
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.OnlySupportPOST))
|
||||
return
|
||||
}
|
||||
|
||||
// 因为httpserver——面向外网client故屏蔽了webserver中的ip限制
|
||||
// 构造contex
|
||||
context, errMsg := NewApiContext(r, w, false)
|
||||
if errMsg != nil {
|
||||
// 输出结果
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
|
||||
return
|
||||
}
|
||||
|
||||
// 根据路径选择不同的处理方法
|
||||
if handlerFunObj, exists := GetHandleFunc(r.RequestURI); exists {
|
||||
defer func() {
|
||||
if config.DEBUG {
|
||||
b, _ := json.Marshal(responseObj)
|
||||
msg := fmt.Sprintf("API:%v 请求数据:%v;返回数据:%s;",
|
||||
r.RequestURI, string(context.GetRequestBytes()), string(b))
|
||||
logUtilPlus.DebugLog(msg)
|
||||
}
|
||||
}()
|
||||
|
||||
// 输出结果
|
||||
responseObj := handlerFunObj.HandleFun()(context)
|
||||
responseResult(w, responseObj)
|
||||
return
|
||||
}
|
||||
|
||||
// 通过反射选择不同的方法
|
||||
strs := stringUtil.Split(r.RequestURI, []string{"/"})
|
||||
params, err := context.RequestDataBySlice2()
|
||||
if err != nil {
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
|
||||
return
|
||||
}
|
||||
resquestData := webServer.NewRequestObject(strs[1], strs[2], params)
|
||||
resp := CallFunction(resquestData)
|
||||
responseResult(w, resp)
|
||||
}
|
||||
42
trunk/center/common/httpServer/start.go
Normal file
42
trunk/center/common/httpServer/start.go
Normal file
@ -0,0 +1,42 @@
|
||||
package httpServer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"goutil/logUtil"
|
||||
"goutil/logUtilPlus"
|
||||
// "log"
|
||||
"net/http/pprof"
|
||||
|
||||
config "common/configsYaml"
|
||||
)
|
||||
|
||||
// Start
|
||||
// @description: 启动服务器
|
||||
// parameter:
|
||||
// @wg: WaitGroup对象
|
||||
// return:
|
||||
func Start(wg *sync.WaitGroup) {
|
||||
defer func() {
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
// 启动过程中不需要捕获异常
|
||||
logUtilPlus.PrintAndWriteLog(logUtil.Info, fmt.Sprintf("Web服务器开始监听:%v", config.WebServerAddress))
|
||||
|
||||
// 启动Web服务器监听
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/", &selfDefineMux{})
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
|
||||
err := http.ListenAndServe(config.WebServerAddress, mux)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("ListenAndServe失败,错误信息为:%s", err))
|
||||
}
|
||||
}
|
||||
58
trunk/center/common/remark/methodRemark.go
Normal file
58
trunk/center/common/remark/methodRemark.go
Normal file
@ -0,0 +1,58 @@
|
||||
package remark
|
||||
|
||||
// 方法说明对象
|
||||
type MethodRemark struct {
|
||||
// 模块名称
|
||||
ModuleName string
|
||||
|
||||
// 方法名称
|
||||
Name string
|
||||
|
||||
// 方法描述
|
||||
Desc string
|
||||
|
||||
// 接口作者
|
||||
Author string
|
||||
|
||||
// 修改者
|
||||
Mendor string
|
||||
|
||||
// 接口设计日期
|
||||
Date string
|
||||
|
||||
// 输入参数
|
||||
InParam []string
|
||||
|
||||
// 输出参数
|
||||
OutParam string
|
||||
}
|
||||
|
||||
// newMethodRemark
|
||||
// @description: 创建新的方法说明对象
|
||||
// parameter:
|
||||
// @moduleName: 模块名称
|
||||
// @name: 方法名称
|
||||
// @desc: 方法描述
|
||||
// @author: 方法作者
|
||||
// @mendor: 方法修改者(多个用,分隔)
|
||||
// @date: 创建日期
|
||||
// @inParam: 输入参数
|
||||
// @outParam: 输出参数
|
||||
// return:
|
||||
// @*MethodRemark: 新的方法说明对象
|
||||
func newMethodRemark(moduleName, name, desc, author, mendor, date string, inParam []string, outParam string) *MethodRemark {
|
||||
if mendor == "" {
|
||||
mendor = "无"
|
||||
}
|
||||
|
||||
return &MethodRemark{
|
||||
ModuleName: moduleName,
|
||||
Name: name,
|
||||
Desc: desc,
|
||||
Author: author,
|
||||
Mendor: mendor,
|
||||
Date: date,
|
||||
InParam: inParam,
|
||||
OutParam: outParam,
|
||||
}
|
||||
}
|
||||
48
trunk/center/common/remark/moduleRemark.go
Normal file
48
trunk/center/common/remark/moduleRemark.go
Normal file
@ -0,0 +1,48 @@
|
||||
package remark
|
||||
|
||||
// ModuleRemark
|
||||
// @description: 模块说明对象
|
||||
type ModuleRemark struct {
|
||||
// 模块名称
|
||||
Name string
|
||||
|
||||
// 模块描述
|
||||
Desc string
|
||||
|
||||
// 接口作者
|
||||
Author string
|
||||
|
||||
// 修改者
|
||||
Mendor string
|
||||
|
||||
// 接口设计日期
|
||||
Date string
|
||||
|
||||
// 方法对象列表
|
||||
MethodRemarkSlice []*MethodRemark
|
||||
}
|
||||
|
||||
// newModuleRemark
|
||||
// @description: 创建新的模块说明对象
|
||||
// parameter:
|
||||
// @name: 模块名称
|
||||
// @desc: 模块描述
|
||||
// @author: 模块作者
|
||||
// @mendor: 模块修改者(多个用,分隔)
|
||||
// @date: 创建日期
|
||||
// return:
|
||||
// @*ModuleRemark: 新的模块说明对象
|
||||
func newModuleRemark(name, desc, author, mendor, date string) *ModuleRemark {
|
||||
if mendor == "" {
|
||||
mendor = "无"
|
||||
}
|
||||
|
||||
return &ModuleRemark{
|
||||
Name: name,
|
||||
Desc: desc,
|
||||
Author: author,
|
||||
Mendor: mendor,
|
||||
Date: date,
|
||||
MethodRemarkSlice: make([]*MethodRemark, 0, 16),
|
||||
}
|
||||
}
|
||||
60
trunk/center/common/remark/remarkMgr.go
Normal file
60
trunk/center/common/remark/remarkMgr.go
Normal file
@ -0,0 +1,60 @@
|
||||
package remark
|
||||
|
||||
import (
|
||||
"goutil/logUtilPlus"
|
||||
)
|
||||
|
||||
var (
|
||||
remarksSlice []*ModuleRemark = make([]*ModuleRemark, 0, 32)
|
||||
)
|
||||
|
||||
// RegisterModuleRemark
|
||||
//
|
||||
// @description: 注册模块说明对象
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @name: 模块名称
|
||||
// @desc: 模块描述
|
||||
// @author: 模块作者
|
||||
// @mendor: 模块修改者(多个用,分隔)
|
||||
// @date: 创建日期
|
||||
//
|
||||
// return:
|
||||
func RegisterModuleRemark(name, desc, author, mendor, date string) {
|
||||
remarksSlice = append(remarksSlice, newModuleRemark(name, desc, author, mendor, date))
|
||||
}
|
||||
|
||||
// RegisterMethodRemark
|
||||
//
|
||||
// @description: 注册方法说明对象
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @moduleName: 模块名称
|
||||
// @name: 方法名称
|
||||
// @desc: 方法描述
|
||||
// @author: 方法作者
|
||||
// @mendor: 方法修改者(多个用,分隔)
|
||||
// @date: 创建日期
|
||||
// @inParam: 输入参数
|
||||
// @outParam: 输出参数
|
||||
//
|
||||
// return:
|
||||
func RegisterMethodRemark(moduleName, name, desc, author, mendor, date string, inParam []string, outParam string) {
|
||||
var moduleRemark *ModuleRemark
|
||||
var exists bool
|
||||
for _, item := range remarksSlice {
|
||||
if item.Name == moduleName {
|
||||
moduleRemark = item
|
||||
exists = true
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
logUtilPlus.ErrorLog("ModuleRemark:%s尚未注册", moduleName)
|
||||
return
|
||||
}
|
||||
|
||||
moduleRemark.MethodRemarkSlice = append(moduleRemark.MethodRemarkSlice, newMethodRemark(moduleName, name, desc, author, mendor, date, inParam, outParam))
|
||||
}
|
||||
56
trunk/center/common/remark/webApi.go
Normal file
56
trunk/center/common/remark/webApi.go
Normal file
@ -0,0 +1,56 @@
|
||||
package remark
|
||||
|
||||
import (
|
||||
"common/httpServer"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"common/webServer"
|
||||
)
|
||||
|
||||
// init
|
||||
// @description: init
|
||||
// parameter:
|
||||
// return:
|
||||
func init() {
|
||||
webServer.RegisterRemarkFunc(remarkdCallback)
|
||||
httpServer.RegisterRemarkFunc(remarkdCallback)
|
||||
}
|
||||
|
||||
// remarkdCallback
|
||||
// @description: remarkdCallback
|
||||
// parameter:
|
||||
// @w: w
|
||||
// @r: r
|
||||
// return:
|
||||
func remarkdCallback(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
for index, moduleItem := range remarksSlice {
|
||||
// 输出模块信息
|
||||
fmt.Fprintf(w, fmt.Sprintf("%d、%s【Name:%s Author:%s Mendor:%s Date:%s】\n", index+1, moduleItem.Desc, moduleItem.Name, moduleItem.Author, moduleItem.Mendor, moduleItem.Date))
|
||||
|
||||
// 输出方法列表信息
|
||||
for subIndex, methodItem := range moduleItem.MethodRemarkSlice {
|
||||
fmt.Fprintf(w, fmt.Sprintf(" %d.%d、%s【Name:%s Author:%s Mendor:%s Date:%s】\n", index+1, subIndex+1, methodItem.Desc, methodItem.Name, methodItem.Author, methodItem.Mendor, methodItem.Date))
|
||||
|
||||
fmt.Fprintln(w, " \t输入参数:")
|
||||
if len(methodItem.InParam) > 0 {
|
||||
for _, param := range methodItem.InParam {
|
||||
fmt.Fprintln(w, " ", param)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintln(w, " ", "无")
|
||||
}
|
||||
|
||||
fmt.Fprintln(w, " \t输出参数:")
|
||||
if methodItem.OutParam != "" {
|
||||
fmt.Fprintln(w, " ", methodItem.OutParam)
|
||||
} else {
|
||||
fmt.Fprintln(w, " ", "无")
|
||||
}
|
||||
|
||||
fmt.Fprintln(w)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
71
trunk/center/common/resultStatus/resultStatus.go
Normal file
71
trunk/center/common/resultStatus/resultStatus.go
Normal file
@ -0,0 +1,71 @@
|
||||
package resultStatus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type StatusCode int
|
||||
|
||||
// ResultStatus
|
||||
// @description: 状态码数据
|
||||
type ResultStatus struct {
|
||||
// 状态码
|
||||
code StatusCode
|
||||
|
||||
// 消息
|
||||
message string
|
||||
}
|
||||
|
||||
// Code
|
||||
// @description: 状态码
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @StatusCode: 状态码
|
||||
func (this *ResultStatus) Code() StatusCode {
|
||||
return this.code
|
||||
}
|
||||
|
||||
// Message
|
||||
// @description: 错误信息
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @string:
|
||||
func (this *ResultStatus) Message() string {
|
||||
return this.message
|
||||
}
|
||||
|
||||
// NewResultStatus
|
||||
// @description: 创建新的状态码对象
|
||||
// parameter:
|
||||
// @_code: 错误码
|
||||
// @_message: 提示消息
|
||||
// return:
|
||||
// @ResultStatus: 状态码对象
|
||||
func NewResultStatus(_code StatusCode, _message string) ResultStatus {
|
||||
return ResultStatus{
|
||||
code: _code,
|
||||
message: _message,
|
||||
}
|
||||
}
|
||||
|
||||
// IsSuccess
|
||||
// @description: 是否是成功
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @bool: true:成功 false:失败
|
||||
func (this *ResultStatus) IsSuccess() bool {
|
||||
return this.code == Success.Code()
|
||||
}
|
||||
|
||||
// String
|
||||
// @description: 打印状态码信息
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @string: 状态码信息
|
||||
func (this *ResultStatus) String() string {
|
||||
return fmt.Sprintf("Code:%d,Message:%s", this.code, this.message)
|
||||
}
|
||||
910
trunk/center/common/resultStatus/resultStatusCode.go
Normal file
910
trunk/center/common/resultStatus/resultStatusCode.go
Normal file
@ -0,0 +1,910 @@
|
||||
package resultStatus
|
||||
|
||||
// 系统错误码
|
||||
var (
|
||||
// 成功
|
||||
Success = NewResultStatus(0, "Success")
|
||||
|
||||
// 数据库错误
|
||||
DBError = NewResultStatus(-2, "DBError")
|
||||
|
||||
// 方法未定义
|
||||
MethodNotDefined = NewResultStatus(-3, "MethodNotDefined")
|
||||
|
||||
// 参数无效
|
||||
ParamInValid = NewResultStatus(-4, "ParamInValid")
|
||||
|
||||
// 参数不匹配
|
||||
ParamNotMatch = NewResultStatus(-5, "ParamNotMatch")
|
||||
|
||||
// 功能未开启
|
||||
ModuleNotOpen = NewResultStatus(-6, "ModuleNotOpen")
|
||||
|
||||
// 只支持Post
|
||||
OnlySupportPOST = NewResultStatus(-7, "OnlySupportPOST")
|
||||
|
||||
// API未定义
|
||||
APINotDefined = NewResultStatus(-8, "APINotDefined")
|
||||
|
||||
// API数据错误
|
||||
APIDataError = NewResultStatus(-9, "APIDataError")
|
||||
|
||||
// API参数错误
|
||||
APIParamError = NewResultStatus(-10, "APIParamError")
|
||||
|
||||
// IP被禁用
|
||||
IPForbid = NewResultStatus(-11, "IPForbid")
|
||||
|
||||
// 没有有效的服务器
|
||||
NoAvailableServer = NewResultStatus(-12, "NoAvailableServer")
|
||||
|
||||
// 服务器组不存在
|
||||
ServerGroupNotExists = NewResultStatus(-13, "ServerGroupNotExists")
|
||||
|
||||
// 测试接口只能debug下调用
|
||||
DebugInterface = NewResultStatus(-14, "DebugInterface")
|
||||
|
||||
// 模块不存在
|
||||
ModuleNotExists = NewResultStatus(-15, "ModuleNotExists")
|
||||
|
||||
// 未能找到指定方法
|
||||
NotSpecificMethod = NewResultStatus(-16, "NotSpecificMethod")
|
||||
|
||||
// 非指定区域
|
||||
NotMatchRegion = NewResultStatus(-17, "NotMatchRegion")
|
||||
|
||||
// 发送空数据
|
||||
SendNullData = NewResultStatus(-18, "SendNullData")
|
||||
|
||||
// 序列化失败
|
||||
MarshalDataError = NewResultStatus(-19, "MarshalDataError")
|
||||
|
||||
//未登录
|
||||
NotLogin = NewResultStatus(-20, "NotLogin")
|
||||
|
||||
// 数据错误
|
||||
DataError = NewResultStatus(-31, "DataError")
|
||||
|
||||
// 战区合并维护中,敬请期待
|
||||
MergeDataRunning = NewResultStatus(-67, "MergeDataRunning")
|
||||
|
||||
// 下载器内容未配置
|
||||
QcDownloadConfigNotExists = NewResultStatus(-68, "QcDownloadConfigNotExists")
|
||||
|
||||
// 下载器奖励已领取
|
||||
QcDownloadHasReward = NewResultStatus(-69, "QcDownloadHasReward")
|
||||
|
||||
// 下载器奖励没有奖励可领取
|
||||
QcDownloadNotReward = NewResultStatus(-70, "QcDownloadNotReward")
|
||||
|
||||
// 下载器奖励积分不足
|
||||
QcDownloadNotScore = NewResultStatus(-71, "QcDownloadNotScore")
|
||||
)
|
||||
|
||||
// 玩家
|
||||
var (
|
||||
|
||||
// 玩家不存在
|
||||
PlayerNotExist = NewResultStatus(-1110, "PlayerNotExist")
|
||||
|
||||
// 没有合适的玩家
|
||||
NotSuitablePlayer = NewResultStatus(-1155, "NotSuitablePlayer")
|
||||
|
||||
// 玩家阵容不存在
|
||||
PlayerSlotFormationNotExist = NewResultStatus(-1156, "PlayerSlotFormationNotExist")
|
||||
)
|
||||
|
||||
// 仙盟和GS保持同步
|
||||
var (
|
||||
// 玩家不在仙盟中
|
||||
GuildNotIn = NewResultStatus(-9401, "玩家不在仙盟中")
|
||||
|
||||
// 仙盟不存在
|
||||
GuildNotExist = NewResultStatus(-9402, "仙盟不存在")
|
||||
|
||||
// 玩家已在仙盟中
|
||||
GuildHasIn = NewResultStatus(-9403, "玩家已在仙盟中")
|
||||
|
||||
// 玩家操作目标和所在仙盟不一致
|
||||
TargetGuildNotMatch = NewResultStatus(-9404, "玩家操作目标和所在仙盟不一致")
|
||||
|
||||
// 仙盟不存在成员
|
||||
GuildMemberNotExist = NewResultStatus(-9405, "仙盟不存在成员")
|
||||
|
||||
// vip等级不足
|
||||
GuildNeedVip = NewResultStatus(-9406, "vip等级不足")
|
||||
|
||||
// 仙盟权限不足
|
||||
GuildNeedAuth = NewResultStatus(-9407, "仙盟权限不足")
|
||||
|
||||
// boss节点今日未开放
|
||||
GuildBossTodayNotOpen = NewResultStatus(-9411, "boss节点今日未开放")
|
||||
|
||||
// 职位人数已满
|
||||
GuildPostEnough = NewResultStatus(-9415, "职位人数已满")
|
||||
|
||||
// boss开启错误
|
||||
GuildBossOpenError = NewResultStatus(-9416, "boss开启错误")
|
||||
|
||||
// boss开启条件不足
|
||||
GuildBossOpenEnough = NewResultStatus(-9417, "boss开启条件不足")
|
||||
|
||||
// 仙盟名称已存在
|
||||
GuildNameHasExist = NewResultStatus(-9419, "仙盟名称已存在")
|
||||
|
||||
// 该职位人数达上限
|
||||
GuildPostLimit = NewResultStatus(-9420, "该职位人数达上限")
|
||||
|
||||
// 世界喊话CD中
|
||||
GuildShareCd = NewResultStatus(-9423, "世界喊话CD中")
|
||||
|
||||
// 弹劾条件不足
|
||||
GuildImpeachNotEnough = NewResultStatus(-9424, "弹劾条件不足")
|
||||
|
||||
// 不是成员或者长老
|
||||
GuildIsNotMember = NewResultStatus(-9428, "不是成员或者长老")
|
||||
|
||||
// boss已开启
|
||||
GuildBossHasOpen = NewResultStatus(-9429, "boss已开启")
|
||||
|
||||
// 盟主不允许退盟
|
||||
GuildLeaderNotAllowedExit = NewResultStatus(-9430, "盟主不允许退盟")
|
||||
|
||||
// 盟主公告锁定
|
||||
GuildNoticeIsLock = NewResultStatus(-9431, "盟主公告锁定")
|
||||
|
||||
// 仙盟次数不足
|
||||
GuildMiniGameNumNotAllow = NewResultStatus(-9439, "仙盟次数不足")
|
||||
|
||||
// 仙盟名称已被占用
|
||||
GuildNameIsNotValid = NewResultStatus(-9445, "仙盟名称已存在")
|
||||
|
||||
// 不是盟主
|
||||
GuildPlayerNotLeader = NewResultStatus(-9454, "不是盟主")
|
||||
|
||||
// 模式切换未到冷却时间
|
||||
GuildSwitchModeNotCool = NewResultStatus(-9455, "模式切换未到冷却时间")
|
||||
|
||||
// 该玩家职位变更还在冷却中
|
||||
GuildChangePostNotCool = NewResultStatus(-9460, "该玩家职位变更还在冷却中")
|
||||
|
||||
// 当前仙盟管理模式不可任命
|
||||
GuildModeCanNotAppoint = NewResultStatus(-9461, "当前仙盟管理模式不可任命")
|
||||
|
||||
// 当前仙盟管理模式不可挑战
|
||||
GuildModeCanNotFight = NewResultStatus(-9463, "当前仙盟管理模式不可挑战")
|
||||
|
||||
// 玩家等级不满足仙盟等级要求
|
||||
GuildPlayerLvLessThanNeedLv = NewResultStatus(-9465, "玩家等级不满足仙盟等级要求")
|
||||
|
||||
// 玩家未申请
|
||||
GuildPlayerNotApply = NewResultStatus(-9466, "玩家未申请")
|
||||
|
||||
// 仙盟信息未变更
|
||||
GuildInfoNotChange = NewResultStatus(-9483, "仙盟信息未变更")
|
||||
|
||||
// 战略编辑次数不足,明日再来
|
||||
GuildStrategyEditNum = NewResultStatus(-9486, "战略编辑次数不足,明日再来")
|
||||
|
||||
// 建筑不存在
|
||||
GuildBuildNotExist = NewResultStatus(-9489, "建筑不存在")
|
||||
|
||||
// 礼包已采购
|
||||
GuildWelfarePurchased = NewResultStatus(-9490, "该礼包已采购")
|
||||
|
||||
// 礼包已采购
|
||||
GuildWelfareCaptailNotEnough = NewResultStatus(-9491, "采购礼包所需资金不足")
|
||||
|
||||
// 礼包已采购
|
||||
GuildWelfareLvNotEnough = NewResultStatus(-9492, "仙盟等级不足,无法采购")
|
||||
|
||||
// 建筑经验超过最大值
|
||||
GuildBuildExpOverMax = NewResultStatus(-9496, "建筑经验超过最大值")
|
||||
|
||||
// 未能设置该类型职位信息
|
||||
GuildSetPostTypeNot = NewResultStatus(-9497, "未能设置该类型职位信息")
|
||||
|
||||
// 仙盟成员已达上限
|
||||
GuildNumMax = NewResultStatus(-9499, "仙盟成员已达上限")
|
||||
|
||||
// 建筑尚未开启
|
||||
GuildBuildIsLock = NewResultStatus(-109013, "建筑尚未开启")
|
||||
|
||||
// 建筑配置未获取
|
||||
GuildBuildConfigNotExist = NewResultStatus(-109014, "未获取到建筑配置")
|
||||
|
||||
// 等级不匹配
|
||||
GuildWelfareLvNotMatch = NewResultStatus(-109015, "等级不匹配")
|
||||
|
||||
// 建筑等级已达到满级
|
||||
GuildBuildHasMaxLv = NewResultStatus(-109017, "建筑等级已达到满级")
|
||||
|
||||
// 采购礼包ID不存在
|
||||
GuildGiftIdNotExist = NewResultStatus(-109018, "采购礼包ID不存在")
|
||||
|
||||
// 盟主令次数不足
|
||||
GuildLeaderOrderCount = NewResultStatus(-109019, "盟主令次数不足")
|
||||
|
||||
// 仙盟每日可踢出人数已达上限
|
||||
GuildTodayKickOutCountIsMax = NewResultStatus(-109020, "仙盟每日可踢出人数已达上限")
|
||||
|
||||
// 已申请该仙盟,请耐心等待审核
|
||||
GuildHasApply = NewResultStatus(-109499, "已申请该仙盟,请耐心等待审核")
|
||||
)
|
||||
|
||||
// 仙盟试炼
|
||||
var (
|
||||
GuildTrainBoxRewardDrawed = NewResultStatus(-109001, "仙盟试炼宝箱已领取")
|
||||
|
||||
// 仙盟boss战报不存在
|
||||
GuildTimeBossReportNotExists = NewResultStatus(-109002, "仙盟boss战报不存在")
|
||||
|
||||
// 仙盟试炼节点不存在
|
||||
GuildTrainNodeNotExists = NewResultStatus(-109003, "仙盟试炼节点不存在")
|
||||
|
||||
// 仙盟试炼奖励槽位不存在
|
||||
GuildTrainBoxSlotNotExists = NewResultStatus(-109004, "仙盟试炼奖励槽位不存在")
|
||||
|
||||
// 仙盟试炼目标位置奖励信息已变化
|
||||
GuildTrainBoxSlotHasRefresh = NewResultStatus(-109005, "仙盟试炼目标位置奖励信息已变化")
|
||||
|
||||
// 仙盟限时boss开启积分不足
|
||||
GuildTimedOpenNotEnougth = NewResultStatus(-109006, "仙盟限时boss开启积分不足")
|
||||
|
||||
// 仙盟限时boss开启积分不足
|
||||
GuildTrainNotKill = NewResultStatus(-109007, "BOSS未镇压,无法领奖")
|
||||
|
||||
// 试炼章节暂未开启
|
||||
GuildTrainNodeNotOpen = NewResultStatus(-109010, "试炼章节暂未开启")
|
||||
|
||||
// 试炼已经镇压
|
||||
GuildTrainIsKilled = NewResultStatus(-109011, "BOSS已镇压,不可挑战")
|
||||
)
|
||||
|
||||
// 仙盟红包
|
||||
var (
|
||||
// 仙盟红包不存在
|
||||
GuildRedPacketNotExist = NewResultStatus(-9950, "仙盟红包不存在")
|
||||
|
||||
// 仙盟玩家红包不存在
|
||||
GuildPlayerRedPacketNotExist = NewResultStatus(-9959, "仙盟玩家红包不存在")
|
||||
|
||||
// 仙盟红包已过期
|
||||
GuildRedPacketIsExpire = NewResultStatus(-9953, "仙盟红包已过期")
|
||||
|
||||
// 仙盟红包没有奖励可以领取
|
||||
GuildRedPacketNotReward = NewResultStatus(-9960, "仙盟红包没有奖励可以领取")
|
||||
|
||||
// 仙盟红包奖励已领取
|
||||
GuildRedPacketHasRewarded = NewResultStatus(-9954, "仙盟红包奖励已领取")
|
||||
)
|
||||
|
||||
// 组队副本
|
||||
var (
|
||||
// 房间不存在
|
||||
TeamCopyRoomNotExists = NewResultStatus(-9612, "TeamCopyRoomNotExists")
|
||||
|
||||
// 成员不存在
|
||||
TeamCopyMemberNotExists = NewResultStatus(-9613, "TeamCopyMemberNotExists")
|
||||
|
||||
// 不是房主
|
||||
TeamCopyNotIsLeader = NewResultStatus(-9614, "TeamCopyNotIsLeader")
|
||||
|
||||
// 战斗失败
|
||||
TeamCopyFigthFail = NewResultStatus(-9615, "TeamCopyFigthFail")
|
||||
|
||||
// 房间玩家未准备
|
||||
TeamCopyNotAllReady = NewResultStatus(-9616, "TeamCopyNotAllReady")
|
||||
|
||||
// 玩家人数不足
|
||||
TeamCopyNotEnough = NewResultStatus(-9617, "TeamCopyNotEnough")
|
||||
|
||||
// 玩家战力不足
|
||||
TeamCopyFapNotEnough = NewResultStatus(-9618, "TeamCopyFapNotEnough")
|
||||
|
||||
// 仍有奖励未领取
|
||||
TeamCopyHasReward = NewResultStatus(-9619, "TeamCopyHasReward")
|
||||
|
||||
// 未被邀请
|
||||
TeamCopyNotShare = NewResultStatus(-9620, "TeamCopyNotShare")
|
||||
|
||||
// 目标节点尚未开启
|
||||
TeamCopyNodeNotOpen = NewResultStatus(-9622, "TeamCopyNodeNotOpen")
|
||||
|
||||
// 人数已满
|
||||
TeamCopyIsMax = NewResultStatus(-9624, "TeamCopyIsMax")
|
||||
|
||||
// 没有权限进入房间
|
||||
TeamCopyNotAuth = NewResultStatus(-9625, "TeamCopyNotAuth")
|
||||
|
||||
// 组队战斗已开始
|
||||
TeamCopyIsFighting = NewResultStatus(-9626, "TeamCopyIsFighting")
|
||||
|
||||
// 邀请已存在
|
||||
TeamCopyIsExistShare = NewResultStatus(-9627, "TeamCopyIsExistShare")
|
||||
|
||||
// 队伍不能为全部助战状态
|
||||
TeamCopyIsAllHelp = NewResultStatus(-9633, "TeamCopyIsAllHelp")
|
||||
|
||||
// 您已被踢出
|
||||
TeamCopyKickOut = NewResultStatus(-9638, "TeamCopyKickOut")
|
||||
|
||||
// 房间已经解散
|
||||
TeamCopyRoomRemove = NewResultStatus(-9639, "房间已经解散")
|
||||
|
||||
// 玩家不在房间中
|
||||
TeamCopyRoomMemberNotIn = NewResultStatus(-9644, "玩家不在房间中")
|
||||
|
||||
// 玩家战力不足
|
||||
TeamCopyPlayerFapLimit = NewResultStatus(-9647, "玩家战力不足")
|
||||
|
||||
// 布阵阵容错误
|
||||
TeamCopyFormationError = NewResultStatus(-212603, "布阵阵容错误")
|
||||
|
||||
// 单人模式不允许加入
|
||||
TeamCopySingleNotJoin = NewResultStatus(-212604, "单人模式不允许加入")
|
||||
|
||||
// 队员未准备
|
||||
PlayerNotReady = NewResultStatus(-212605, "队员未准备")
|
||||
)
|
||||
|
||||
// 矿战
|
||||
var (
|
||||
// 矿战玩家信息不存在
|
||||
KuangzhanPlayerNotExist = NewResultStatus(-36131, "KuangzhanPlayerNotExist")
|
||||
|
||||
// 占领节点错误
|
||||
KuangzhanOccupyNode = NewResultStatus(-36113, "KuangzhanOccupyNode")
|
||||
|
||||
// 矿战节点不存在
|
||||
NodeConfigNotExist = NewResultStatus(-36132, "NodeConfigNotExist")
|
||||
|
||||
// 此洞府正在被攻击
|
||||
TheOtherPlayerFighting = NewResultStatus(-36114, "TheOtherPlayerFighting")
|
||||
|
||||
// 该节点已经被占领
|
||||
KuangzhanoverOccupyNode = NewResultStatus(-36113, "KuangzhanoverOccupyNode")
|
||||
|
||||
// 占领节点玩家无阵容
|
||||
KuangzhanPlayerNoFormation = NewResultStatus(-36133, "KuangzhanPlayerNoFormation")
|
||||
|
||||
// 获取阵容失败
|
||||
KuangzhanPlayerGetFormationFail = NewResultStatus(-36134, "KuangzhanPlayerGetFormationFail")
|
||||
|
||||
// 已占领洞府节点
|
||||
KuangzhanOverLoad = NewResultStatus(-36115, "KuangzhanOverLoad")
|
||||
|
||||
// 今日抢夺次数已经用完
|
||||
KuangzhanDailyLootOver = NewResultStatus(-36117, "KuangzhanDailyLootOver")
|
||||
|
||||
// 此洞府今日已无法被抢夺
|
||||
KuangzhanDailyRobbedOver = NewResultStatus(-36118, "KuangzhanDailyRobbedOver")
|
||||
|
||||
// 洞天抢夺暂未开启
|
||||
KuangzhanRobbedTimeNotOpen = NewResultStatus(-36119, "KuangzhanRobbedTimeNotOpen")
|
||||
|
||||
// 剩余洞天宝石不可抢夺
|
||||
KuangzhanGemIsOver = NewResultStatus(-36120, "KuangzhanGemIsOver")
|
||||
|
||||
// 玩家不匹配
|
||||
KuangzhanPlayerNotMatching = NewResultStatus(-36122, "KuangzhanPlayerNotMatching")
|
||||
|
||||
// 不是被邀请的玩家
|
||||
KuangzhanInviteFailed = NewResultStatus(-36123, "邀请好友失败")
|
||||
|
||||
// 不是被邀请的玩家
|
||||
KuangzhanNotInvited = NewResultStatus(-36124, "不是被邀请的玩家")
|
||||
|
||||
// 协助信息已失效
|
||||
KuangzhanInviteExpired = NewResultStatus(-36125, "协助信息已失效")
|
||||
|
||||
// 已经帮助过该玩家
|
||||
KuangzhanAlreadyHelped = NewResultStatus(-36135, "已经帮助过该玩家")
|
||||
|
||||
// 对方任务已经完成
|
||||
KuangzhanTaskFinished = NewResultStatus(-36136, "对方任务已经完成")
|
||||
)
|
||||
|
||||
// 蜀山论剑
|
||||
var (
|
||||
// 战斗校验出现异常
|
||||
FightException = NewResultStatus(-1354, "FightException")
|
||||
|
||||
// 比武大会玩家信息不存在
|
||||
HegeMonyPlayerInfoNotExist = NewResultStatus(-9701, "HegeMonyPlayerInfoNotExist")
|
||||
|
||||
// 比武大会玩家已有匹配
|
||||
HegeMonyHasMatch = NewResultStatus(-9702, "HegeMonyHasMatch")
|
||||
|
||||
// 比武大会玩家未找到匹配
|
||||
HegeMonyNotMatch = NewResultStatus(-9703, "HegeMonyNotMatch")
|
||||
|
||||
// 比武大会玩家未找到阵容
|
||||
HegeMonyFormationNotExist = NewResultStatus(-9704, "HegeMonyFormationNotExist")
|
||||
|
||||
// 比武大会对手玩家信息不存在
|
||||
HegeMonyTargetPlayerInfoNotExist = NewResultStatus(-9705, "HegeMonyTargetPlayerInfoNotExist")
|
||||
|
||||
// 比武大会玩家未匹配
|
||||
HegeMonyPlayerNotMatch = NewResultStatus(-9706, "HegeMonyPlayerNotMatch")
|
||||
|
||||
// 比武大会赛季不匹配
|
||||
SeasonNotMatch = NewResultStatus(-9707, "SeasonNotMatch")
|
||||
|
||||
// 比武大会战报信息不存在
|
||||
HegeMonyReportNotExist = NewResultStatus(-9730, "HegeMonyReportNotExist")
|
||||
|
||||
// 比武大会战斗未能找到匹配对手
|
||||
HegeMonyFightNotMatch = NewResultStatus(-9731, "HegeMonyFightNotMatch")
|
||||
|
||||
// 比武大会荣耀玩家不存在
|
||||
HegeMonyHonorPlayerNotExist = NewResultStatus(-9732, "HegeMonyHonorPlayerNotExist")
|
||||
)
|
||||
|
||||
// 战报
|
||||
var (
|
||||
// 战报信息不存在
|
||||
FightReportNotExist = NewResultStatus(-9707, "FightReportNotExist")
|
||||
|
||||
// 数据解析错误
|
||||
JsonDecodeDataError = NewResultStatus(-9708, "JsonDecodeDataError")
|
||||
)
|
||||
|
||||
// 喜信
|
||||
var (
|
||||
// 信息Id错误
|
||||
HappyNewsIdError = NewResultStatus(-40103, "HappyNewsIdError")
|
||||
|
||||
// 信息序号错误
|
||||
HappyNewsOrderIdError = NewResultStatus(-40104, "HappyNewsOrderIdError")
|
||||
|
||||
// 喜信获取好友失败
|
||||
HappyNewsGetFriendsError = NewResultStatus(-40105, "HappyNewsGetFriendsError")
|
||||
|
||||
// 没有好友
|
||||
NoFriend = NewResultStatus(-8565, "NoFriend")
|
||||
)
|
||||
|
||||
// 仙盟远征
|
||||
var (
|
||||
// 仙盟远征错误
|
||||
GuildExpeditionError = NewResultStatus(-29900, "GuildExpeditionError")
|
||||
|
||||
// 仙盟远征活动未开启
|
||||
GuildExpeditionActivityNotOpen = NewResultStatus(-29906, "GuildExpeditionActivityNotOpen")
|
||||
|
||||
// 仙盟远征公会未匹配
|
||||
GuildExpeditionGuildNotMatch = NewResultStatus(-29908, "GuildExpeditionGuildNotMatch")
|
||||
|
||||
// 仙盟远征阵容无法解析
|
||||
GuildExpeditionFormationUnknow = NewResultStatus(-29909, "GuildExpeditionFormationUnknow")
|
||||
|
||||
// 仙盟远征房间信息不存在
|
||||
GuildExpeditionRoomInfoError = NewResultStatus(-29912, "GuildExpeditionRoomInfoError")
|
||||
|
||||
// 仙盟远征阶段一挑战次数不足
|
||||
GuildExpeditionFirstStepTimesIsNotEnough = NewResultStatus(-29913, "GuildExpeditionfirstStepTimesIsNotEnough")
|
||||
|
||||
// 仙盟远征阶段一挑战次数不足
|
||||
GuildExpeditionSecondStepTimesIsNotEnough = NewResultStatus(-29914, "GuildExpeditionSecondStepTimesIsNotEnough")
|
||||
|
||||
// 仙盟远征房间已锁定
|
||||
GuildExpeditionRoomIsLock = NewResultStatus(-29915, "GuildExpeditionRoomIsLock")
|
||||
|
||||
// 不是参与远征的仙盟成员
|
||||
GuildExpeditionIsNotJoinMember = NewResultStatus(-29916, "GuildExpeditionIsNotJoinMember")
|
||||
|
||||
// 目标没有防御阵容
|
||||
GuildExpeditionTargetNoDefenceFormation = NewResultStatus(-29917, "GuildExpeditionTargetNoDefenceFormation")
|
||||
|
||||
// 仙盟远征战斗验证失败
|
||||
GuildExpeditionFightValidFail = NewResultStatus(-29918, "GuildExpeditionFightValidFail")
|
||||
)
|
||||
|
||||
// 义结金兰
|
||||
var (
|
||||
// 玩家未结交,标记g_yjjl对象
|
||||
YjjlPlayerNotExist = NewResultStatus(-33501, "YjjlPlayerNotExist")
|
||||
|
||||
// 玩家未结义,标记g_yjjl_player对象
|
||||
YjjlPlayerNotExistForPlayer = NewResultStatus(-33588, "YjjlPlayerNotExistForPlayer")
|
||||
|
||||
// 玩家未结义,标记玩家对象属于第三者
|
||||
YjjlPlayerNotMatch = NewResultStatus(-33589, "YjjlPlayerNotMatch")
|
||||
|
||||
// 玩家已结交
|
||||
YjjlPlayerHasExist = NewResultStatus(-33502, "YjjlPlayerHasExist")
|
||||
|
||||
// 玩家已设置本特效
|
||||
QingyiLvSpecialeffectsIsExists = NewResultStatus(-33515, "QingyiLvSpecialeffectsIsExists")
|
||||
|
||||
// 亲密付已达月上限
|
||||
HelpPayIsLimit = NewResultStatus(-33571, "HelpPayIsLimit")
|
||||
|
||||
// 玩家当前未培养花卉
|
||||
FlowerNotExist = NewResultStatus(-33523, "FlowerNotExist")
|
||||
|
||||
// 玩家当前花卉经验值已满
|
||||
FlowerExpIsMax = NewResultStatus(-33524, "FlowerExpIsMax")
|
||||
|
||||
// 玩家当前花卉经验值未满
|
||||
FlowerExpNotEnough = NewResultStatus(-33525, "FlowerExpNotEnough")
|
||||
|
||||
// 玩家已培养花卉
|
||||
FlowerIsExists = NewResultStatus(-33530, "FlowerIsExists")
|
||||
|
||||
// 培养的花卉不匹配
|
||||
FlowerNotMatch = NewResultStatus(-33531, "FlowerNotMatch")
|
||||
|
||||
// 花卉可收获,不能重置
|
||||
FlowerCanGet = NewResultStatus(-33532, "FlowerCanGet")
|
||||
|
||||
// 同心榜CP组唯一标识错误
|
||||
RankGroupIdError = NewResultStatus(-33541, "RankGroupIdError")
|
||||
|
||||
// 暂无留言
|
||||
RankTipNotExists = NewResultStatus(-33542, "RankTipNotExists")
|
||||
|
||||
// 结交好友匹配错误
|
||||
RankCpMatchError = NewResultStatus(-33544, "RankCpMatchError")
|
||||
|
||||
// 留言点赞和玩家结义数据不匹配
|
||||
RankCpMessageZanNotMatch = NewResultStatus(-33545, "RankCpMessageZanNotMatch")
|
||||
|
||||
// 该玩家今日已点赞!
|
||||
PlayerGood = NewResultStatus(-212301, "PlayerGood")
|
||||
|
||||
// 义结金兰没有任务数据
|
||||
YjjlTaskNoData = NewResultStatus(-33547, "YjjlTaskNoData")
|
||||
|
||||
// 金兰契奖励节点错误
|
||||
YjjlRewardNodeError = NewResultStatus(-33568, "YjjlRewardNodeError")
|
||||
|
||||
// 亲密等级不足
|
||||
IntimacyLvNotEnough = NewResultStatus(-33569, "IntimacyLvNotEnough")
|
||||
|
||||
// 活动期间获取的亲密度不足
|
||||
AddIntimacyNotEnough = NewResultStatus(-33583, "活动期间获取的亲密度不足")
|
||||
|
||||
// 亲密度奖励已经领取
|
||||
HasAddIntimacyReward = NewResultStatus(-33584, "亲密度奖励已经领取")
|
||||
|
||||
// 亲密等级不足,未解锁
|
||||
YjjlShowIsLock = NewResultStatus(-33586, "亲密等级不足,未解锁")
|
||||
|
||||
// 活动还没结束
|
||||
TimedActivityNotClose = NewResultStatus(-2006, "活动还没结束")
|
||||
)
|
||||
|
||||
// 蜀山之巅(跨服Pvp冠军赛)
|
||||
var (
|
||||
// 赛季未开启
|
||||
WeekChampionSeasonNotOpen = NewResultStatus(-4000, "WeekChampionSeasonNotOpen")
|
||||
|
||||
// 赛季分组数据不存在
|
||||
WeekChampionNoExistGroupMatch = NewResultStatus(-4007, "WeekChampionNoExistGroupMatch")
|
||||
|
||||
// 跨服蜀山之巅竞猜玩家错误
|
||||
WeekChampionBetPlayerError = NewResultStatus(-4008, "WeekChampionBetPlayerError")
|
||||
|
||||
// 战报信息不存在
|
||||
WeekChampionFightReportNotExist = NewResultStatus(-4009, "WeekChampionFightReportNotExist")
|
||||
|
||||
// 战报信息解析错误
|
||||
WeekChampionFightReportJsonDecodeDataError = NewResultStatus(-4010, "WeekChampionFightReportJsonDecodeDataError")
|
||||
)
|
||||
|
||||
var (
|
||||
// SocialSquareGiftNotExist 礼物不存在
|
||||
SocialSquareGiftNotExist = NewResultStatus(-40400, "SocialSquareGiftNotExist")
|
||||
|
||||
// SocialSquarePlayerNotExist 社交广场玩家不存在
|
||||
SocialSquarePlayerNotExist = NewResultStatus(-40401, "SocialSquarePlayerNotExist")
|
||||
|
||||
// SocialSquarePhotoNotExist 社交广场玩家不存在
|
||||
SocialSquarePhotoNotExist = NewResultStatus(-40402, "SocialSquarePhotoNotExist")
|
||||
)
|
||||
|
||||
var (
|
||||
// 模块错误
|
||||
VideoModuleError = NewResultStatus(-38183, "VideoModuleError")
|
||||
|
||||
// 未检测到该战报
|
||||
VideoIdError = NewResultStatus(-38184, "VideoIdError")
|
||||
)
|
||||
|
||||
var (
|
||||
// 金兰宴玩家对象不是举办方
|
||||
YjjlFeastIsNotHost = NewResultStatus(-44108, "YjjlFeastIsNotHost")
|
||||
|
||||
// 宴会还在准备中
|
||||
YjjlFeastIsPreraring = NewResultStatus(-44111, "YjjlFeastIsPreraring")
|
||||
|
||||
// 金兰宴宴会已开始
|
||||
YjjlFeastRandomIsStart = NewResultStatus(-44112, "YjjlFeastRandomIsStart")
|
||||
|
||||
// 金兰宴房间类型错误
|
||||
YjjlFeastRoomTypeError = NewResultStatus(-44116, "YjjlFeastRoomTypeError")
|
||||
|
||||
// 金兰宴房间不存在
|
||||
YjjlFeastRoomNotExist = NewResultStatus(-44118, "YjjlFeastRoomNotExist")
|
||||
|
||||
// 金兰宴玩家不能加入该房间
|
||||
YjjlFeastPlayerCantEnterThisRoom = NewResultStatus(-44119, "YjjlFeastPlayerCantEnterThisRoom")
|
||||
|
||||
// 金兰宴玩家不能同时主办两场及以上的宴会
|
||||
YjjlFeastHostBuySamePlayer = NewResultStatus(-44120, "YjjlFeastHostBuySamePlayer")
|
||||
|
||||
// 金兰宴宾客人数达到上限
|
||||
YjjlFeastRoomGuestMax = NewResultStatus(-44121, "YjjlFeastRoomGuestMax")
|
||||
|
||||
// 金兰宴玩家不在房间
|
||||
YjjlFeastIsNotInScene = NewResultStatus(-44122, "YjjlFeastIsNotInScene")
|
||||
|
||||
// 金兰宴不是来宾
|
||||
YjjlFeastIsHost = NewResultStatus(-44123, "YjjlFeastIsHost")
|
||||
|
||||
// 金兰宴红包不存在
|
||||
YjjlFeastRedPacketNotExist = NewResultStatus(-44124, "YjjlFeastRedPacketNotExist")
|
||||
|
||||
// 金兰宴红包已领取或已领完
|
||||
YjjlFeastRedPacketHadDraw = NewResultStatus(-44125, "YjjlFeastRedPacketHadDraw")
|
||||
)
|
||||
|
||||
var (
|
||||
// 全服红包id错误
|
||||
RedPacketIdError = NewResultStatus(-40501, "RedPacketIdError")
|
||||
|
||||
// 全服红包已经领取完
|
||||
RedPacketHaveOver = NewResultStatus(-40502, "RedPacketHaveOver")
|
||||
|
||||
// 全服红包不可领取
|
||||
RedPacketCanNotDraw = NewResultStatus(-40503, "RedPacketCanNotDraw")
|
||||
|
||||
// 已经领取该红包
|
||||
RedPacketHaveDraw = NewResultStatus(-40504, "RedPacketHaveDraw")
|
||||
|
||||
// 红包领取失败
|
||||
RedPacketDrawError = NewResultStatus(-40505, "RedPacketDrawError")
|
||||
)
|
||||
|
||||
// 跨服昆仑神虚
|
||||
var (
|
||||
// 昆仑之墟尚未开启
|
||||
GlobalCitywarMapNotOpen = NewResultStatus(-45003, "昆仑之墟尚未开启")
|
||||
|
||||
// 仙盟未参与
|
||||
CitywarCsGuildNotParticipate = NewResultStatus(-50000, "CitywarCsGuildNotParticipate")
|
||||
|
||||
// 跨服昆仑神虚地图不存在
|
||||
CitywarCsMapNotExist = NewResultStatus(-50001, "CitywarCsMapNotExist")
|
||||
|
||||
// 跨服昆仑神虚城池不存在
|
||||
CitywarCsLandNotExist = NewResultStatus(-50002, "CitywarCsLandNotExist")
|
||||
|
||||
// 跨服昆仑神虚城池未占领
|
||||
CitywarCsLandNotOccupy = NewResultStatus(-50003, "CitywarCsLandNotOccupy")
|
||||
|
||||
// 跨服昆仑神虚城池正在战斗中
|
||||
CitywarCsLandIsFighting = NewResultStatus(-50004, "CitywarCsLandIsFighting")
|
||||
|
||||
// 昆仑之墟节点坐标不匹配
|
||||
CitywarCsAxisNotRight = NewResultStatus(-50011, "CitywarCsAxisNotRight")
|
||||
|
||||
// 昆仑之墟玩家队伍不存在
|
||||
CitywarCsPlayerTeamNotExist = NewResultStatus(-50012, "CitywarCsPlayerTeamNotExist")
|
||||
|
||||
// 昆仑之墟玩家队伍复活中
|
||||
CitywarCsPlayerTeamReviving = NewResultStatus(-50013, "CitywarCsPlayerTeamReviving")
|
||||
|
||||
// 昆仑之墟玩家已派遣
|
||||
CitywarCsPlayerTeamIsMoving = NewResultStatus(-50014, "CitywarCsPlayerTeamIsMoving")
|
||||
|
||||
// 昆仑之墟玩家未派遣
|
||||
CitywarCsPlayerTeamNoMoving = NewResultStatus(-50015, "CitywarCsPlayerTeamNoMoving")
|
||||
|
||||
// 昆仑之墟玩家玩家队伍已经死亡
|
||||
CitywarCsTeamIdDead = NewResultStatus(-50016, "CitywarCsTeamIdDead")
|
||||
|
||||
// 没有奖励可以领取
|
||||
CitywarCsNotDrawReward = NewResultStatus(-50017, "CitywarCsNotDrawReward")
|
||||
|
||||
// 昆仑之墟休战中
|
||||
CitywarCsNotFightTime = NewResultStatus(-50018, "CitywarCsNotFightTime")
|
||||
|
||||
// 昆仑之墟已经结束
|
||||
CitywarCsIsEnd = NewResultStatus(-50019, "CitywarCsIsEnd")
|
||||
|
||||
// 玩家昆仑之墟出征次数不足
|
||||
CitywarCsFightNumNotEnough = NewResultStatus(-50020, "CitywarCsFightNumNotEnough")
|
||||
|
||||
// 昆仑之墟出生地无法操作
|
||||
CitywarCsLandIsBirth = NewResultStatus(-50021, "CitywarCsLandIsBirth")
|
||||
|
||||
// 昆仑之墟队伍已放入仙盟大营中
|
||||
CitywarCsPlayerTeamInGuildTeam = NewResultStatus(-50022, "CitywarCsPlayerTeamInGuildTeam")
|
||||
|
||||
// 昆仑之墟队伍不在仙盟大营中
|
||||
CitywarCsPlayerTeamNotInGuildTeam = NewResultStatus(-50023, "CitywarCsPlayerTeamNotInGuildTeam")
|
||||
|
||||
// 昆仑神墟未选择仙盟大营中队伍
|
||||
CitywarCsGuildTeamNotExist = NewResultStatus(-50024, "CitywarCsGuildTeamNotExist")
|
||||
|
||||
// 昆仑神墟地块正在燃烧
|
||||
CitywarCsLandIsFire = NewResultStatus(-50025, "CitywarCsLandIsFire")
|
||||
|
||||
// 非相邻地不允许攻击
|
||||
CitywarCsLandNotAdjoinNotAtk = NewResultStatus(-50027, "CitywarCsLandNotAdjoinNotAtk")
|
||||
)
|
||||
|
||||
var (
|
||||
// 巅峰对决信息不存在
|
||||
PeakInfoNotExist = NewResultStatus(-40804, "PeakInfoNotExist")
|
||||
|
||||
// 该位置不是空位置
|
||||
PeakRankNotEmpty = NewResultStatus(-40805, "PeakRankNotEmpty")
|
||||
|
||||
// 不能挑战低于自己的对手
|
||||
PeakCantFight = NewResultStatus(-40806, "PeakCantFight")
|
||||
|
||||
// 排位已经变化
|
||||
PeakNeedRefresh = NewResultStatus(-40808, "PeakNeedRefresh")
|
||||
|
||||
// 当前排名不可挑战,挑战列表已刷新
|
||||
PeakNeedRefreshTwo = NewResultStatus(-40814, "PeakNeedRefreshTwo")
|
||||
|
||||
// 不可挑战前三
|
||||
PeakCantFightTopThree = NewResultStatus(-40815, "PeakCantFightTopThree")
|
||||
)
|
||||
|
||||
// 蜀山论剑PvpTournament
|
||||
var (
|
||||
// 玩家信息不存在
|
||||
PvpTournamentInfoNotExist = NewResultStatus(-40901, "PvpTournamentInfoNotExist")
|
||||
|
||||
// 玩家未找到阵容
|
||||
PvpTournamentFormationNotExist = NewResultStatus(-40902, "PvpTournamentFormationNotExist")
|
||||
|
||||
// 排位已经变化
|
||||
PvpTournamentNeedRefresh = NewResultStatus(-40903, "PvpTournamentNeedRefresh")
|
||||
|
||||
// 不能挑战太靠前的玩家
|
||||
PvpTournamentCantFight = NewResultStatus(-40907, "PvpTournamentCantFight")
|
||||
)
|
||||
|
||||
// 幸运彩卡luckyCard
|
||||
var (
|
||||
// 幸运彩卡奖励配置不存在
|
||||
LuckyCardRewardConfigNotExist = NewResultStatus(-42610, "LuckyCardRewardConfigNotExist")
|
||||
|
||||
// 幸运彩卡奖励不足
|
||||
LuckyCardRewardNotEnough = NewResultStatus(-42611, "LuckyCardRewardNotEnough")
|
||||
|
||||
// 幸运彩卡青钻奖励不足
|
||||
LuckyCardRewardQingzuanNotEnough = NewResultStatus(-42612, "LuckyCardRewardQingzuanNotEnough")
|
||||
|
||||
// 用户青钻额度不足
|
||||
LuckyCardQingzuanNotEnough = NewResultStatus(-42613, "LuckyCardQingzuanNotEnough")
|
||||
|
||||
// 交换信息不存在
|
||||
LuckyCardExchangeMessageNotExist = NewResultStatus(-42615, "LuckyCardExchangeMessageNotExist")
|
||||
)
|
||||
|
||||
// 新版金兰宴
|
||||
var (
|
||||
// NewFeastHaveAppointment 已经预约过
|
||||
NewFeastHaveAppointment = NewResultStatus(-41101, "NewFeastHaveAppointment")
|
||||
|
||||
// NewFeastAppointmentTimeOut 时间已过
|
||||
NewFeastAppointmentTimeOut = NewResultStatus(-41102, "NewFeastAppointmentTimeOut")
|
||||
|
||||
// NotAppointment 没有预约
|
||||
NewFeastNotAppointment = NewResultStatus(-41103, "NewFeastNotAppointment")
|
||||
|
||||
// NewFeastHaveInvite 已经邀请
|
||||
NewFeastHaveInvite = NewResultStatus(-41104, "NewFeastHaveInvite")
|
||||
|
||||
// NewFeastAppointmentOverdue 宴会已过期
|
||||
NewFeastAppointmentOverdue = NewResultStatus(-41105, "NewFeastAppointmentOverdue")
|
||||
|
||||
// 金兰宴房间不存在
|
||||
NewFeastRoomNotExist = NewResultStatus(-41106, "NewFeastRoomNotExist")
|
||||
|
||||
// 金兰宴玩家不存在
|
||||
NewFeastPlayerNotInRoom = NewResultStatus(-41107, "NewFeastPlayerNotInRoom")
|
||||
|
||||
// 金兰宴对方玩家不存在
|
||||
NewFeastTargetPlayerPlayerNotInRoom = NewResultStatus(-41108, "NewFeastTargetPlayerPlayerNotInRoom")
|
||||
|
||||
// 道具已被抢
|
||||
NewFeastPropBeRobbed = NewResultStatus(-41109, "NewFeastPropBeRobbed")
|
||||
|
||||
// 变身球数量不足
|
||||
NewFeastBallNotEnough = NewResultStatus(-41110, "NewFeastBallNotEnough")
|
||||
|
||||
// 已拥有烟花
|
||||
NewFeastHaveFirework = NewResultStatus(-41111, "NewFeastHaveFirework")
|
||||
|
||||
// 宴会已结束
|
||||
NewFeastEnd = NewResultStatus(-41112, "NewFeastEnd")
|
||||
|
||||
// 已经品菜过了
|
||||
NewFeastHaveEatFood = NewResultStatus(-41113, "NewFeastHaveEatFood")
|
||||
|
||||
// 不在品菜时间内
|
||||
NewFeastNotEatFoodTime = NewResultStatus(-41114, "NewFeastNotEatFoodTime")
|
||||
|
||||
// 房间人气不足
|
||||
NewFeastRoomPopularNotEnough = NewResultStatus(-41115, "NewFeastRoomPopularNotEnough")
|
||||
|
||||
// 密码不正确
|
||||
NewFeastBoxPasswordError = NewResultStatus(-41116, "NewFeastBoxPasswordError")
|
||||
|
||||
// 不是房主
|
||||
NewFeastNotHsot = NewResultStatus(-41117, "NewFeastNotHsot")
|
||||
|
||||
// 已经领取
|
||||
NewFeastBoxHaveDraw = NewResultStatus(-41118, "NewFeastBoxHaveDraw")
|
||||
|
||||
// 房间人数已满
|
||||
NewFeastRoomPlayerMax = NewResultStatus(-41119, "NewFeastRoomPlayerMax")
|
||||
|
||||
// 不能邀请
|
||||
NewFeastCantInvite = NewResultStatus(-41120, "NewFeastCantInvite")
|
||||
|
||||
// 被其他人预约
|
||||
NewFeastAppointmentByOthers = NewResultStatus(-41121, "NewFeastAppointmentByOthers")
|
||||
)
|
||||
|
||||
// NoWorldBossDamageData 世界boss1.0
|
||||
var (
|
||||
NoWorldBossDamageData = NewResultStatus(-41200, "NoWorldBossDamageData")
|
||||
)
|
||||
var (
|
||||
// 拍卖行商品不存在
|
||||
AuctionGoodsNotExist = NewResultStatus(-41301, "AuctionGoodsNotExist")
|
||||
|
||||
// 拍卖行加价失败
|
||||
AuctionAddPriceErr = NewResultStatus(-41302, "AuctionAddPriceErr")
|
||||
|
||||
// 仙盟拍卖暂无商品
|
||||
AuctionGuildNoGoods = NewResultStatus(-41303, "AuctionGuildNoGoods")
|
||||
|
||||
// 仙盟拍卖未结束
|
||||
AuctionGuildNotEnd = NewResultStatus(-41304, "AuctionGuildNotEnd")
|
||||
|
||||
// 分红已经领取
|
||||
AuctionBonusHaveDraw = NewResultStatus(-41305, "AuctionBonusHaveDraw")
|
||||
|
||||
// 暂无分红
|
||||
AuctionNoBonus = NewResultStatus(-41306, "AuctionNoBonus")
|
||||
|
||||
// 不能取消关注
|
||||
AuctionCantCancelFollow = NewResultStatus(-41307, "AuctionCantCancelFollow")
|
||||
|
||||
// 拍卖未开始
|
||||
AuctionNotStart = NewResultStatus(-41308, "AuctionNotStart")
|
||||
|
||||
// 该商品已经售出
|
||||
AuctionGoodsHaveAuction = NewResultStatus(-41309, "AuctionGoodsHaveAuction")
|
||||
|
||||
// 该商品已经流拍
|
||||
AuctionGoodsHaveNoPrice = NewResultStatus(-41310, "AuctionGoodsHaveNoPrice")
|
||||
|
||||
// 玩家金龙不足
|
||||
AuctionPlayerGoldNotEnough = NewResultStatus(-41311, "AuctionPlayerGoldNotEnough")
|
||||
|
||||
//该商品拍卖时间已结束
|
||||
AuctionGoodsEnd = NewResultStatus(-41312, "AuctionGoodsEnd")
|
||||
|
||||
//未参与决战神虚,不可分红
|
||||
AuctionCantBonus = NewResultStatus(-41313, "AuctionCantBonus")
|
||||
)
|
||||
|
||||
var (
|
||||
// 交易行商品不存在
|
||||
TradeProductNotExistInfoNotExist = NewResultStatus(-41500, "TradeProductNotExistInfoNotExist")
|
||||
|
||||
// 交易行审核类型不存在
|
||||
TradeAuditTypeNotExist = NewResultStatus(-41501, "TradeAuditTypeNotExist")
|
||||
)
|
||||
377
trunk/center/common/utils/commonUtil.go
Normal file
377
trunk/center/common/utils/commonUtil.go
Normal file
@ -0,0 +1,377 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/flate"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"goutil/logUtilPlus"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 定义常量
|
||||
var MinDateTime = time.Date(2000, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
var MaxDateTime = time.Date(3000, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
var GuidEmpty = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
// IsTrue
|
||||
// @description: 是否为true
|
||||
// parameter:
|
||||
// @data: []byte格式的bool信息
|
||||
// return:
|
||||
// @bool: 返回布尔值
|
||||
func IsTrue(data []byte) bool {
|
||||
|
||||
if data == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if data[0] == 0 {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertBooleanToBytes
|
||||
// @description: bool型转换成byte数组
|
||||
// parameter:
|
||||
// @status: 状态
|
||||
// return:
|
||||
// @[]byte: 返回字节数组
|
||||
func ConvertBooleanToBytes(status bool) []byte {
|
||||
|
||||
if status == false {
|
||||
return []byte{0}
|
||||
} else {
|
||||
return []byte{1}
|
||||
}
|
||||
}
|
||||
|
||||
// StrSliceJoinToStr
|
||||
// @description: 将[]string组装成字符串
|
||||
// parameter:
|
||||
// @numArray: 源int32数组
|
||||
// @sep: 分割字符串
|
||||
// return:
|
||||
// @string: 组成的字符串
|
||||
func StrSliceJoinToStr(numArray []string, sep string) string {
|
||||
str := ""
|
||||
if numArray == nil || len(numArray) == 0 {
|
||||
return str
|
||||
}
|
||||
|
||||
for _, n := range numArray {
|
||||
str += fmt.Sprintf("%s%s", n, sep)
|
||||
}
|
||||
|
||||
str = strings.TrimSuffix(str, sep)
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// Int32SliceJoinToStr
|
||||
// @description: 将[]int32转换成字符串
|
||||
// parameter:
|
||||
// @source: 资源
|
||||
// @sep: 分隔符
|
||||
// return:
|
||||
// @result: 字符串
|
||||
func Int32SliceJoinToStr(source []int32, sep string) (result string) {
|
||||
if source == nil || len(source) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, s := range source {
|
||||
result += fmt.Sprintf("%d%s", s, sep)
|
||||
}
|
||||
|
||||
result = strings.TrimRight(result, sep)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SplitToStrSlice
|
||||
// @description: 将字符串切割为[]string
|
||||
// parameter:
|
||||
// @s: 输入字符串
|
||||
// @sep: 分割字符串
|
||||
// @removeEmpty: 是否去除空字符串
|
||||
// return:
|
||||
// @resultSlice: 字符串列表
|
||||
func SplitToStrSlice(s, sep string, removeEmpty bool) (resultSlice []string) {
|
||||
if len(s) == 0 {
|
||||
return make([]string, 0)
|
||||
}
|
||||
|
||||
// 先按照分隔符进行切割
|
||||
strSlice := strings.Split(s, sep)
|
||||
|
||||
for _, value := range strSlice {
|
||||
if removeEmpty {
|
||||
// 去除空格
|
||||
if value = strings.TrimSpace(value); value == "" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
resultSlice = append(resultSlice, value)
|
||||
}
|
||||
|
||||
return resultSlice
|
||||
}
|
||||
|
||||
// ParseTimeString
|
||||
// @description: 解析时间字符串
|
||||
// parameter:
|
||||
// @timeStr: 时间字符串,例:12:33:12
|
||||
// return:
|
||||
// @hour: 小时
|
||||
// @minute: 分钟
|
||||
// @second: 秒数
|
||||
func ParseTimeString(timeStr string) (hour int, minute int, second int) {
|
||||
timeSlice := strings.Split(timeStr, ":")
|
||||
if len(timeSlice) != 3 {
|
||||
return
|
||||
}
|
||||
|
||||
hour, _ = strconv.Atoi(timeSlice[0])
|
||||
minute, _ = strconv.Atoi(timeSlice[1])
|
||||
second, _ = strconv.Atoi(timeSlice[2])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Rm_duplicate_string
|
||||
// @description: 去重
|
||||
// parameter:
|
||||
// @list: 列表
|
||||
// return:
|
||||
// @[]string: 去重后的数据
|
||||
func Rm_duplicate_string(list []string) []string {
|
||||
var x []string = []string{}
|
||||
for _, i := range list {
|
||||
if len(x) == 0 {
|
||||
x = append(x, i)
|
||||
} else {
|
||||
for k, v := range x {
|
||||
if i == v {
|
||||
break
|
||||
}
|
||||
if k == len(x)-1 {
|
||||
x = append(x, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// Rm_duplicate_int32
|
||||
// @description: 去重
|
||||
// parameter:
|
||||
// @list: 列表数据
|
||||
// return:
|
||||
// @[]int32: 去重后的结果
|
||||
func Rm_duplicate_int32(list []int32) []int32 {
|
||||
var x []int32 = []int32{}
|
||||
for _, i := range list {
|
||||
if len(x) == 0 {
|
||||
x = append(x, i)
|
||||
} else {
|
||||
for k, v := range x {
|
||||
if i == v {
|
||||
break
|
||||
}
|
||||
if k == len(x)-1 {
|
||||
x = append(x, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// RandomAarrayOfInt32
|
||||
// @description: int32数组乱序
|
||||
// parameter:
|
||||
// @arr: 数组
|
||||
// return:
|
||||
func RandomAarrayOfInt32(arr []int32) {
|
||||
|
||||
if arr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(arr) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
for i := len(arr) - 1; i > 0; i-- {
|
||||
num := rand.Intn(i + 1)
|
||||
arr[i], arr[num] = arr[num], arr[i]
|
||||
}
|
||||
}
|
||||
|
||||
// RandomAarrayOfString
|
||||
// @description: string数组乱序
|
||||
// parameter:
|
||||
// @arr: 数组
|
||||
// return:
|
||||
func RandomAarrayOfString(arr []string) {
|
||||
|
||||
if arr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(arr) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
for i := len(arr) - 1; i > 0; i-- {
|
||||
num := rand.Intn(i + 1)
|
||||
arr[i], arr[num] = arr[num], arr[i]
|
||||
}
|
||||
}
|
||||
|
||||
// LogErrorRecover
|
||||
// @description: 记录错误
|
||||
// parameter:
|
||||
// return:
|
||||
func LogErrorRecover() {
|
||||
if err := recover(); err != nil {
|
||||
tmsg := fmt.Sprintf("err msg:%s stack:%s", err, debug.Stack())
|
||||
logUtilPlus.ErrorLog(tmsg)
|
||||
}
|
||||
}
|
||||
|
||||
// LogReqErrorRecover
|
||||
// @description: 记录错误
|
||||
// parameter:
|
||||
// @r:
|
||||
// return:
|
||||
func LogReqErrorRecover(r *http.Request) {
|
||||
if err := recover(); err != nil {
|
||||
b, err := json.Marshal(r)
|
||||
reqStr := ""
|
||||
if err == nil {
|
||||
reqStr = string(b)
|
||||
}
|
||||
tmsg := fmt.Sprintf("RequestInfo:%s .err msg:%s stack:%s", reqStr, err, debug.Stack())
|
||||
logUtilPlus.ErrorLog(tmsg)
|
||||
}
|
||||
}
|
||||
|
||||
// StringSliceIsExists
|
||||
// @description: StringSliceIsExists
|
||||
// parameter:
|
||||
// @strList: strList
|
||||
// @val: val
|
||||
// return:
|
||||
// @bool: 是否存在
|
||||
func StringSliceIsExists(strList []string, val string) bool {
|
||||
|
||||
if strList == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, v := range strList {
|
||||
if v == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Int64SliceIsExists
|
||||
// @description: Int64SliceIsExists
|
||||
// parameter:
|
||||
// @strList: strList
|
||||
// @val: val
|
||||
// return:
|
||||
// @bool: 是否存在
|
||||
func Int64SliceIsExists(strList []int64, val int64) bool {
|
||||
|
||||
if strList == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, v := range strList {
|
||||
if v == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// SliceIsExists
|
||||
// @description: SliceIsExists
|
||||
// parameter:
|
||||
// @n: n
|
||||
// @f: f
|
||||
// return:
|
||||
// @bool: 是否存在
|
||||
func SliceIsExists(n int, f func(int) bool) bool {
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
if f(i) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// FlateEncode
|
||||
// @description: 压缩字符串
|
||||
// parameter:
|
||||
// @input: 输入字符列表
|
||||
// return:
|
||||
// @result: 结果字符列表
|
||||
// @err: 错误信息
|
||||
func FlateEncode(input []byte) (result []byte, err error) {
|
||||
var buf bytes.Buffer
|
||||
w, err := flate.NewWriter(&buf, flate.DefaultCompression)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 无法使用defer close使用无法拿到结果
|
||||
_, err = w.Write(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
w.Close()
|
||||
|
||||
result = buf.Bytes()
|
||||
return
|
||||
}
|
||||
|
||||
// FlateDecode
|
||||
// @description: FlateDecode
|
||||
// parameter:
|
||||
// @input: 输入字符列表
|
||||
// return:
|
||||
// @result: 结果字符列表
|
||||
// @err: 错误信息
|
||||
func FlateDecode(input []byte) (result []byte, err error) {
|
||||
result, err = ioutil.ReadAll(flate.NewReader(bytes.NewReader(input)))
|
||||
return
|
||||
}
|
||||
218
trunk/center/common/webServer/apiContext.go
Normal file
218
trunk/center/common/webServer/apiContext.go
Normal file
@ -0,0 +1,218 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"goutil/jsonUtil"
|
||||
"goutil/logUtilPlus"
|
||||
"goutil/typeUtil"
|
||||
"goutil/zlibUtil"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ApiContext
|
||||
// @description: Api请求上下文对象
|
||||
type ApiContext struct {
|
||||
// 请求对象
|
||||
request *http.Request
|
||||
|
||||
// 应答写对象
|
||||
responseWriter http.ResponseWriter
|
||||
|
||||
// 请求数据
|
||||
requestBytes []byte
|
||||
|
||||
// 字典形式的请求数据
|
||||
requestDataByMap typeUtil.MapData
|
||||
|
||||
//获取头部信息
|
||||
header *http.Header
|
||||
}
|
||||
|
||||
// GetRequest
|
||||
// @description: 获取请求对象
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @*http.Request: 请求对象
|
||||
func (this *ApiContext) GetRequest() *http.Request {
|
||||
return this.request
|
||||
}
|
||||
|
||||
// GetResponseWriter
|
||||
// @description: 获取应答写对象
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @http.ResponseWriter: 应答写对象
|
||||
func (this *ApiContext) GetResponseWriter() http.ResponseWriter {
|
||||
return this.responseWriter
|
||||
}
|
||||
|
||||
// GetRequestBytes
|
||||
// @description: 获取请求字节数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]byte: 请求字节数组
|
||||
func (this *ApiContext) GetRequestBytes() []byte {
|
||||
return this.requestBytes
|
||||
}
|
||||
|
||||
// readContent
|
||||
// @description: 读取内容
|
||||
// parameter:
|
||||
// @receiver this: this 请求对象
|
||||
// @isZlib: 是否数据压缩
|
||||
// return:
|
||||
// @content: 二进制格式的内容
|
||||
// @err: 错误对象
|
||||
func (this *ApiContext) readContent(isZlib bool) (content []byte, err error) {
|
||||
var buffer []byte
|
||||
|
||||
defer this.request.Body.Close()
|
||||
if buffer, err = ioutil.ReadAll(this.request.Body); err != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("url:%s,读取数据出错,错误信息为:%s", this.request.RequestURI, err))
|
||||
return
|
||||
}
|
||||
|
||||
// 不压缩,则直接返回
|
||||
if isZlib == false {
|
||||
this.requestBytes = buffer
|
||||
|
||||
return buffer, err
|
||||
}
|
||||
|
||||
// 解压数据
|
||||
if content, err = zlibUtil.Decompress(buffer); err != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("url:%s,解压缩数据出错,错误信息为:%s", this.request.RequestURI, err))
|
||||
return
|
||||
}
|
||||
|
||||
this.requestBytes = content
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Unmarshal
|
||||
// @description: 反序列化
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// @obj: 反序列化结果数据
|
||||
// return:
|
||||
// @error: 反序列化错误数据
|
||||
func (this *ApiContext) Unmarshal(obj interface{}) error {
|
||||
contentData := this.GetRequestBytes()
|
||||
|
||||
var errMsg error
|
||||
|
||||
// 反序列化
|
||||
if obj, errMsg = json.Marshal(contentData); errMsg != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("反序列化%s出错,错误信息为:%s", string(contentData), errMsg.Error()))
|
||||
return errMsg
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RequestDataByMap
|
||||
// @description: 获取请求的map格式数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @typeUtil.MapData: map数据
|
||||
// @error: 错误信息
|
||||
func (this *ApiContext) RequestDataByMap() (typeUtil.MapData, error) {
|
||||
if this.requestDataByMap != nil {
|
||||
return this.requestDataByMap, nil
|
||||
}
|
||||
|
||||
var data typeUtil.MapData
|
||||
if err := this.Unmarshal(&data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
this.requestDataByMap = data
|
||||
|
||||
return this.requestDataByMap, nil
|
||||
}
|
||||
|
||||
// RequestDataBySlice
|
||||
// @description: 获取请求的slice格式数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]interface{}: 返回的数组数据
|
||||
func (this *ApiContext) RequestDataBySlice() []interface{} {
|
||||
result := make([]interface{}, 0, 8)
|
||||
for _, value := range this.requestDataByMap {
|
||||
result = append(result, value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// RequestDataBySlice2
|
||||
// @description: 获取请求的slice格式数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]interface{}: 返回的数组数据
|
||||
// @error:
|
||||
func (this *ApiContext) RequestDataBySlice2() (interface{}, error) {
|
||||
contentData := this.GetRequestBytes()
|
||||
|
||||
// 反序列化
|
||||
var result interface{}
|
||||
var errMsg error
|
||||
if result, errMsg = jsonUtil.UnMarshalWithNumberType(string(contentData)); errMsg != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("用[]interface{}反序列化%s出错,错误信息为:%s", string(contentData), errMsg.Error()))
|
||||
return nil, errMsg
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// RequestDataBySlice2ByJson
|
||||
// @description: 获取请求的slice格式数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// return:
|
||||
// @[]interface{}: 返回的数组数据
|
||||
// @error:
|
||||
func (this *ApiContext) RequestDataBySlice2ByJson() ([]interface{}, error) {
|
||||
contentData := this.GetRequestBytes()
|
||||
|
||||
// 反序列化
|
||||
result := make([]interface{}, 0, 8)
|
||||
if errMsg := json.Unmarshal(contentData, &result); errMsg != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("用[]interface{}反序列化%s出错,错误信息为:%s", string(contentData), errMsg.Error()))
|
||||
return nil, errMsg
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewApiContext
|
||||
// @description: 新建API上下文对象
|
||||
// parameter:
|
||||
// @_request: 请求对象
|
||||
// @_responseWriter: 应答写对象
|
||||
// @isZlib: 数据是否压缩
|
||||
// return:
|
||||
// @*ApiContext: 上下文
|
||||
// @error: 错误信息
|
||||
func NewApiContext(_request *http.Request, _responseWriter http.ResponseWriter, isZlib bool) (*ApiContext, error) {
|
||||
context := &ApiContext{
|
||||
request: _request,
|
||||
header: &_request.Header,
|
||||
responseWriter: _responseWriter,
|
||||
}
|
||||
|
||||
// 读取数据
|
||||
_, errMsg := context.readContent(isZlib)
|
||||
if errMsg != nil {
|
||||
return nil, errMsg
|
||||
}
|
||||
|
||||
return context, nil
|
||||
}
|
||||
112
trunk/center/common/webServer/apiHandler.go
Normal file
112
trunk/center/common/webServer/apiHandler.go
Normal file
@ -0,0 +1,112 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"common/resultStatus"
|
||||
)
|
||||
|
||||
// 处理函数
|
||||
type HandleFunc func(context *ApiContext) *ResponseObject
|
||||
|
||||
// ApiHandler
|
||||
//
|
||||
// @description: API处理结构
|
||||
type ApiHandler struct {
|
||||
// API完整路径名称
|
||||
apiFullName string
|
||||
|
||||
// 方法定义
|
||||
handleFun HandleFunc
|
||||
|
||||
// 方法参数名称集合
|
||||
funcParamNames []string
|
||||
}
|
||||
|
||||
// ApiFullName
|
||||
//
|
||||
// @description: API完整路径名称
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @receiver this: this
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @string:
|
||||
func (this *ApiHandler) ApiFullName() string {
|
||||
return this.apiFullName
|
||||
}
|
||||
|
||||
// HandleFun
|
||||
//
|
||||
// @description: 方法定义
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @receiver this: this
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @HandleFunc: 方法
|
||||
func (this *ApiHandler) HandleFun() HandleFunc {
|
||||
return this.handleFun
|
||||
}
|
||||
|
||||
// FuncParamNames
|
||||
//
|
||||
// @description: 方法参数名称集合
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @receiver this: this
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @[]string: 方法参数名称集合
|
||||
func (this *ApiHandler) FuncParamNames() []string {
|
||||
return this.funcParamNames
|
||||
}
|
||||
|
||||
// CheckParam
|
||||
//
|
||||
// @description: 检测参数数量
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @receiver this: this
|
||||
// @r:
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @resultStatus.ResultStatus: 状态码数据
|
||||
func (this *ApiHandler) CheckParam(r *http.Request) resultStatus.ResultStatus {
|
||||
for _, name := range this.funcParamNames {
|
||||
if r.Form[name] == nil || len(r.Form[name]) == 0 {
|
||||
return resultStatus.APIParamError
|
||||
}
|
||||
}
|
||||
|
||||
return resultStatus.Success
|
||||
}
|
||||
|
||||
// newApiHandler
|
||||
//
|
||||
// @description: 创建新的请求方法对象
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @_apiFullName: API完整路径名称
|
||||
// @_funcDefinition: 方法定义
|
||||
// @_funcParamNames: 方法参数名称集合
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @*ApiHandler: 请求方法对象
|
||||
func newApiHandler(_apiFullName string, _funcDefinition HandleFunc, _funcParamNames ...string) *ApiHandler {
|
||||
return &ApiHandler{
|
||||
apiFullName: _apiFullName,
|
||||
handleFun: _funcDefinition,
|
||||
funcParamNames: _funcParamNames,
|
||||
}
|
||||
}
|
||||
56
trunk/center/common/webServer/apiHandlerMgr.go
Normal file
56
trunk/center/common/webServer/apiHandlerMgr.go
Normal file
@ -0,0 +1,56 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
// 处理方法集合
|
||||
// Key:API名
|
||||
handlerData = make(map[string]*ApiHandler)
|
||||
|
||||
// 文档方法
|
||||
remarkFunc func(w http.ResponseWriter, r *http.Request)
|
||||
)
|
||||
|
||||
// RegisterRemarkFunc
|
||||
// @description: 注册文档api方法
|
||||
// parameter:
|
||||
// @_remarkFunc: _remarkFunc
|
||||
// return:
|
||||
func RegisterRemarkFunc(_remarkFunc func(w http.ResponseWriter, r *http.Request)) {
|
||||
remarkFunc = _remarkFunc
|
||||
}
|
||||
|
||||
// RegisterHandleFunc
|
||||
// @description: 注册处理方法
|
||||
// parameter:
|
||||
// @apiName: API名称
|
||||
// @callback: 回调方法
|
||||
// @paramNames: 参数名称集合
|
||||
// return:
|
||||
func RegisterHandleFunc(apiName string, callback HandleFunc, paramNames ...string) {
|
||||
apiFullName := fmt.Sprintf("/API/%s", apiName)
|
||||
|
||||
if _, exist := handlerData[apiFullName]; exist {
|
||||
panic(fmt.Errorf("重复注册处理函数:%s", apiFullName))
|
||||
}
|
||||
|
||||
handlerData[apiFullName] = newApiHandler(apiFullName, callback, paramNames...)
|
||||
}
|
||||
|
||||
// GetHandleFunc
|
||||
// @description: 获取请求方法
|
||||
// parameter:
|
||||
// @apiFullName: 方法名称
|
||||
// return:
|
||||
// @*ApiHandler: 请求方法
|
||||
// @bool: 是否存在
|
||||
func GetHandleFunc(apiFullName string) (*ApiHandler, bool) {
|
||||
if requestFuncObj, exists := handlerData[apiFullName]; exists {
|
||||
return requestFuncObj, exists
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
431
trunk/center/common/webServer/reflect.go
Normal file
431
trunk/center/common/webServer/reflect.go
Normal file
@ -0,0 +1,431 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
config "common/configsYaml"
|
||||
"common/resultStatus"
|
||||
"goutil/logUtilPlus"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// 供客户端访问的模块的后缀
|
||||
con_ModuleSuffix = "Module"
|
||||
|
||||
// 定义用于分隔模块名称和方法名称的分隔符
|
||||
con_DelimeterOfObjAndMethod = "_"
|
||||
)
|
||||
|
||||
var (
|
||||
// 定义存放所有方法映射的变量
|
||||
methodMap = make(map[string]*methodAndInOutTypes)
|
||||
|
||||
// 函数返回值类型
|
||||
responseType reflect.Type = reflect.TypeOf(new(ResponseObject))
|
||||
)
|
||||
|
||||
// getStructName
|
||||
//
|
||||
// @description: 获取结构体类型的名称
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @structType: 结构体类型
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @string: 结构体类型的名称
|
||||
func getStructName(structType reflect.Type) string {
|
||||
reflectTypeStr := structType.String()
|
||||
reflectTypeArr := strings.Split(reflectTypeStr, ".")
|
||||
|
||||
return reflectTypeArr[len(reflectTypeArr)-1]
|
||||
}
|
||||
|
||||
// getFullModuleName
|
||||
//
|
||||
// @description: 获取完整的模块名称
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @moduleName: 模块名称
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @string: 完整的模块名称
|
||||
func getFullModuleName(moduleName string) string {
|
||||
return moduleName + con_ModuleSuffix
|
||||
}
|
||||
|
||||
// getFullMethodName
|
||||
//
|
||||
// @description: 获取完整的方法名称
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @structName: 结构体名称
|
||||
// @methodName: 方法名称
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @string: 完整的方法名称
|
||||
func getFullMethodName(structName, methodName string) string {
|
||||
return structName + con_DelimeterOfObjAndMethod + methodName
|
||||
}
|
||||
|
||||
// resolveMethodInOutParams
|
||||
//
|
||||
// @description: 解析方法的输入输出参数
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @method: 方法对应的反射值
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @inTypes: 输入参数类型集合
|
||||
// @outTypes: 输出参数类型集合
|
||||
func resolveMethodInOutParams(method reflect.Value) (inTypes []reflect.Type, outTypes []reflect.Type) {
|
||||
methodType := method.Type()
|
||||
for i := 0; i < methodType.NumIn(); i++ {
|
||||
inTypes = append(inTypes, methodType.In(i))
|
||||
}
|
||||
|
||||
for i := 0; i < methodType.NumOut(); i++ {
|
||||
outTypes = append(outTypes, methodType.Out(i))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// RegisterFunction
|
||||
//
|
||||
// @description: 将需要对客户端提供方法的对象进行注册
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @structObject: 对象
|
||||
//
|
||||
// return:
|
||||
func RegisterFunction(structObject interface{}) {
|
||||
// 获取structObject对应的反射 Type 和 Value
|
||||
reflectValue := reflect.ValueOf(structObject)
|
||||
reflectType := reflect.TypeOf(structObject)
|
||||
|
||||
// 提取对象类型名称
|
||||
structName := getStructName(reflectType)
|
||||
|
||||
// 获取structObject中返回值为responseObject的方法
|
||||
for i := 0; i < reflectType.NumMethod(); i++ {
|
||||
// 获得方法名称
|
||||
methodName := reflectType.Method(i).Name
|
||||
|
||||
// 获得方法及其输入参数的类型列表
|
||||
method := reflectValue.MethodByName(methodName)
|
||||
inTypes, outTypes := resolveMethodInOutParams(method)
|
||||
|
||||
// 判断输出参数数量是否正确
|
||||
if len(outTypes) != 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 判断返回值是否为responseObject
|
||||
if outTypes[0] != responseType {
|
||||
continue
|
||||
}
|
||||
|
||||
// 添加到列表中
|
||||
methodMap[getFullMethodName(structName, methodName)] = newmethodAndInOutTypes(method, inTypes, outTypes)
|
||||
}
|
||||
}
|
||||
|
||||
// CallFunction
|
||||
//
|
||||
// @description: 调用方法
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @requestObj: 客户端对象
|
||||
//
|
||||
// return:
|
||||
//
|
||||
// @responseObj: 请求对象
|
||||
func CallFunction(requestObj *RequestObject) (responseObj *ResponseObject) {
|
||||
responseObj = GetInitResponseObj()
|
||||
|
||||
var methodAndInOutTypes *methodAndInOutTypes
|
||||
var ok bool
|
||||
|
||||
// 根据传入的ModuleName和MethodName找到对应的方法对象
|
||||
key := getFullMethodName(requestObj.ModuleName, requestObj.MethodName)
|
||||
if methodAndInOutTypes, ok = methodMap[key]; !ok {
|
||||
logUtilPlus.ErrorLog("找不到指定的方法:%s", key)
|
||||
responseObj.SetResultStatus(resultStatus.NotSpecificMethod)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断参数数量是否相同
|
||||
inTypesLength := len(methodAndInOutTypes.InTypes)
|
||||
paramLength := len(requestObj.Parameters)
|
||||
if paramLength != inTypesLength {
|
||||
logUtilPlus.ErrorLog("传入的参数数量不符,本地方法%s的参数数量:%d,传入的参数数量为:%d", key, inTypesLength, paramLength)
|
||||
responseObj.SetResultStatus(resultStatus.ParamNotMatch)
|
||||
return
|
||||
}
|
||||
|
||||
// 构造参数
|
||||
in := make([]reflect.Value, inTypesLength)
|
||||
for i := 0; i < inTypesLength; i++ {
|
||||
inTypeItem := methodAndInOutTypes.InTypes[i]
|
||||
paramItem := requestObj.Parameters[i]
|
||||
|
||||
// 已支持类型:Client,Player(非基本类型)
|
||||
// 已支持类型:Bool,Int,Int8,Int16,Int32,Int64,Uint,Uint8,Uint16,Uint32,Uint64,Float32,Float64,String
|
||||
// 已支持类型:以及上面所列出类型的Slice类型
|
||||
// 未支持类型:Uintptr,Complex64,Complex128,Array,Chan,Func,Interface,Map,Ptr,Struct,UnsafePointer
|
||||
// 由于byte与int8同义,rune与int32同义,所以并不需要单独处理
|
||||
// 枚举参数的类型,并进行类型转换
|
||||
switch inTypeItem.Kind() {
|
||||
case reflect.Bool:
|
||||
if paramBool, ok := paramItem.(bool); ok {
|
||||
in[i] = reflect.ValueOf(paramBool)
|
||||
}
|
||||
case reflect.Int:
|
||||
if paramInt, ok := paramItem.(int); ok {
|
||||
in[i] = reflect.ValueOf(int(paramInt))
|
||||
}
|
||||
case reflect.Int8:
|
||||
if paramInt8, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int8(paramInt8))
|
||||
}
|
||||
case reflect.Int16:
|
||||
if paramInt16, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int16(paramInt16))
|
||||
}
|
||||
case reflect.Int32:
|
||||
if paramInt32, ok := paramItem.(int32); ok {
|
||||
in[i] = reflect.ValueOf(paramInt32)
|
||||
} else if paramFloat64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int32(paramFloat64))
|
||||
}
|
||||
case reflect.Int64:
|
||||
if paramInt64, ok := paramItem.(int64); ok {
|
||||
in[i] = reflect.ValueOf(paramInt64)
|
||||
} else if paramUint64, ok := paramItem.(uint64); ok {
|
||||
in[i] = reflect.ValueOf(int64(paramUint64))
|
||||
} else if paramString, ok := paramItem.(string); ok {
|
||||
|
||||
i64, err := strconv.ParseInt(paramString, 10, 64)
|
||||
if err == nil {
|
||||
in[i] = reflect.ValueOf(i64)
|
||||
}
|
||||
} else if paramFloat64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(int64(paramFloat64))
|
||||
}
|
||||
case reflect.Uint:
|
||||
if paramUint, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint(paramUint))
|
||||
}
|
||||
case reflect.Uint8:
|
||||
if paramUint8, ok := paramItem.(uint8); ok {
|
||||
in[i] = reflect.ValueOf(uint8(paramUint8))
|
||||
}
|
||||
case reflect.Uint16:
|
||||
if paramUint16, ok := paramItem.(uint16); ok {
|
||||
in[i] = reflect.ValueOf(uint16(paramUint16))
|
||||
}
|
||||
case reflect.Uint32:
|
||||
if paramUint32, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint32(paramUint32))
|
||||
}
|
||||
case reflect.Uint64:
|
||||
if paramUint64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(uint64(paramUint64))
|
||||
}
|
||||
case reflect.Float32:
|
||||
if paramFloat32, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(float32(paramFloat32))
|
||||
}
|
||||
case reflect.Float64:
|
||||
if paramFloat64, ok := paramItem.(float64); ok {
|
||||
in[i] = reflect.ValueOf(paramFloat64)
|
||||
}
|
||||
case reflect.String:
|
||||
if paramString, ok := paramItem.(string); ok {
|
||||
in[i] = reflect.ValueOf(paramString)
|
||||
}
|
||||
case reflect.Slice:
|
||||
// 如果是Slice类型,则需要对其中的项再次进行类型判断及类型转换
|
||||
if param_interface, ok := paramItem.([]interface{}); ok {
|
||||
switch inTypeItem.String() {
|
||||
case "[]bool":
|
||||
params_inner := make([]bool, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_bool, ok := param_interface[i].(bool); ok {
|
||||
params_inner[i] = param_bool
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int":
|
||||
params_inner := make([]int, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(int); ok {
|
||||
params_inner[i] = int(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int8":
|
||||
params_inner := make([]int8, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = int8(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int16":
|
||||
params_inner := make([]int16, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = int16(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int32":
|
||||
params_inner := make([]int32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
param_float64, ok := param_interface[i].(int32)
|
||||
if ok {
|
||||
params_inner[i] = int32(param_float64)
|
||||
continue
|
||||
} else {
|
||||
param_int16, right := param_interface[i].(uint16)
|
||||
if right == true {
|
||||
params_inner[i] = int32(param_int16)
|
||||
}
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]int64":
|
||||
params_inner := make([]int64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(int64); ok {
|
||||
params_inner[i] = int64(param_float64)
|
||||
} else if param_uint64, ok := param_interface[i].(uint64); ok {
|
||||
params_inner[i] = int64(param_uint64)
|
||||
} else if param_string, ok := param_interface[i].(string); ok {
|
||||
|
||||
i64, err := strconv.ParseInt(param_string, 10, 64)
|
||||
|
||||
if err == nil {
|
||||
params_inner[i] = i64
|
||||
}
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint":
|
||||
params_inner := make([]uint, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint); ok {
|
||||
params_inner[i] = uint(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
// case "[]uint8": 特殊处理
|
||||
case "[]uint16":
|
||||
params_inner := make([]uint16, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint16); ok {
|
||||
params_inner[i] = uint16(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint32":
|
||||
params_inner := make([]uint32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint32); ok {
|
||||
params_inner[i] = uint32(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]uint64":
|
||||
params_inner := make([]uint64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(uint64); ok {
|
||||
params_inner[i] = uint64(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]float32":
|
||||
params_inner := make([]float32, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = float32(param_float64)
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]float64":
|
||||
params_inner := make([]float64, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_float64, ok := param_interface[i].(float64); ok {
|
||||
params_inner[i] = param_float64
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
case "[]string":
|
||||
params_inner := make([]string, len(param_interface), len(param_interface))
|
||||
for i := 0; i < len(param_interface); i++ {
|
||||
if param_string, ok := param_interface[i].(string); ok {
|
||||
params_inner[i] = param_string
|
||||
}
|
||||
}
|
||||
in[i] = reflect.ValueOf(params_inner)
|
||||
}
|
||||
} else if inTypeItem.String() == "[]uint8" { // 由于[]uint8在传输过程中会被转化成字符串,所以单独处理;
|
||||
if param_string, ok := paramItem.(string); ok {
|
||||
param_uint8 := ([]uint8)(param_string)
|
||||
in[i] = reflect.ValueOf(param_uint8)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否有无效的参数(传入的参数类型和方法定义的类型不匹配导致没有赋值)
|
||||
for _, item := range in {
|
||||
if reflect.Value.IsValid(item) == false {
|
||||
logUtilPlus.ErrorLog("type:%v,value:%v.方法%s传入的参数%v无效", reflect.TypeOf(item), reflect.ValueOf(item), key, requestObj.Parameters)
|
||||
responseObj.SetResultStatus(resultStatus.ParamInValid)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 传入参数,调用方法
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
logUtilPlus.DebugLog("Begin Call Func:module:%v, method:%v,inParams:%v\n\n", requestObj.ModuleName, requestObj.MethodName, in)
|
||||
}
|
||||
}
|
||||
|
||||
out := methodAndInOutTypes.Method.Call(in)
|
||||
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
for i, v := range in {
|
||||
logUtilPlus.DebugLog("\nparams %v,%v\n", i, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 并输出结果到客户端(由于只有一个返回值,所以取out[0])
|
||||
if responseObj, ok = (&out[0]).Interface().(*ResponseObject); !ok {
|
||||
logUtilPlus.ErrorLog("返回值类型推断为ResponseObject 出错, tyep is :%v", reflect.TypeOf(out[0]))
|
||||
responseObj.SetResultStatus(resultStatus.ParamInValid)
|
||||
return
|
||||
}
|
||||
if config.DEBUG {
|
||||
if requestObj.MethodName != "GetRefreshData" {
|
||||
logUtilPlus.DebugLog("返回数据:code:%v, data:%v, mess:%v\n\n", responseObj.Code, responseObj.Value, responseObj.Message)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
34
trunk/center/common/webServer/reflectMethod.go
Normal file
34
trunk/center/common/webServer/reflectMethod.go
Normal file
@ -0,0 +1,34 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// methodAndInOutTypes
|
||||
// @description: 反射的方法和输入、输出参数类型组合类型
|
||||
type methodAndInOutTypes struct {
|
||||
// 反射出来的对应方法对象
|
||||
Method reflect.Value
|
||||
|
||||
// 反射出来的方法的输入参数的类型集合
|
||||
InTypes []reflect.Type
|
||||
|
||||
// 反射出来的方法的输出参数的类型集合
|
||||
OutTypes []reflect.Type
|
||||
}
|
||||
|
||||
// newmethodAndInOutTypes
|
||||
// @description: newmethodAndInOutTypes
|
||||
// parameter:
|
||||
// @_method: _method
|
||||
// @_inTypes: _inTypes
|
||||
// @_outTypes: _outTypes
|
||||
// return:
|
||||
// @*methodAndInOutTypes: methodAndInOutTypes
|
||||
func newmethodAndInOutTypes(_method reflect.Value, _inTypes []reflect.Type, _outTypes []reflect.Type) *methodAndInOutTypes {
|
||||
return &methodAndInOutTypes{
|
||||
Method: _method,
|
||||
InTypes: _inTypes,
|
||||
OutTypes: _outTypes,
|
||||
}
|
||||
}
|
||||
31
trunk/center/common/webServer/reflectRequestObject.go
Normal file
31
trunk/center/common/webServer/reflectRequestObject.go
Normal file
@ -0,0 +1,31 @@
|
||||
package webServer
|
||||
|
||||
// RequestObject
|
||||
// @description: 请求对象
|
||||
type RequestObject struct {
|
||||
// 以下属性是由客户端直接传入的,可以直接反序列化直接得到的
|
||||
// 请求的模块名称
|
||||
ModuleName string
|
||||
|
||||
// 请求的方法名称
|
||||
MethodName string
|
||||
|
||||
// 请求的参数数组
|
||||
Parameters []interface{}
|
||||
}
|
||||
|
||||
// NewRequestObject
|
||||
// @description: NewRequestObject
|
||||
// parameter:
|
||||
// @_ModuleName: _ModuleName
|
||||
// @_MethodName: _MethodName
|
||||
// @_Parameters: _Parameters
|
||||
// return:
|
||||
// @*RequestObject: RequestObject
|
||||
func NewRequestObject(_ModuleName string, _MethodName string, _Parameters []interface{}) *RequestObject {
|
||||
return &RequestObject{
|
||||
ModuleName: _ModuleName,
|
||||
MethodName: _MethodName,
|
||||
Parameters: _Parameters,
|
||||
}
|
||||
}
|
||||
83
trunk/center/common/webServer/responseObject.go
Normal file
83
trunk/center/common/webServer/responseObject.go
Normal file
@ -0,0 +1,83 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"common/resultStatus"
|
||||
)
|
||||
|
||||
// ResponseObject
|
||||
// @description: 响应对象
|
||||
type ResponseObject struct {
|
||||
// 响应结果的状态值
|
||||
Code resultStatus.StatusCode
|
||||
|
||||
// Status 状态
|
||||
Status int32
|
||||
|
||||
// 响应结果的状态值所对应的描述信息
|
||||
Message string
|
||||
|
||||
// 响应结果的数据
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
// SetResultStatus
|
||||
// @description: 设置响应结果的状态值
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// @rs: 响应结果的状态值
|
||||
// return:
|
||||
// @*ResponseObject: 响应结果对象
|
||||
func (this *ResponseObject) SetResultStatus(rs resultStatus.ResultStatus) *ResponseObject {
|
||||
this.Code = rs.Code()
|
||||
this.Message = rs.Message()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
// SetData
|
||||
// @description: 设置响应对象数据
|
||||
// parameter:
|
||||
// @receiver this: this
|
||||
// @data: 响应结果的数据
|
||||
// return:
|
||||
// @*ResponseObject: 响应结果对象
|
||||
func (this *ResponseObject) SetData(data interface{}) *ResponseObject {
|
||||
this.Value = data
|
||||
return this
|
||||
}
|
||||
|
||||
// IsSuccess
|
||||
// @description: 是否是请求成功
|
||||
// parameter:
|
||||
// @receiver this:this
|
||||
// return:
|
||||
// @bool:是请求成功
|
||||
func (this *ResponseObject) IsSuccess() bool {
|
||||
return this.Code == resultStatus.Success.Code()
|
||||
}
|
||||
|
||||
// SetCodeStatus
|
||||
// @description: 同步code和status状态
|
||||
// parameter:
|
||||
// @receiver this:this
|
||||
// return:
|
||||
func (this *ResponseObject) SetCodeStatus() {
|
||||
if this.Code == resultStatus.Success.Code() && resultStatus.StatusCode(this.Status) != resultStatus.Success.Code() {
|
||||
this.Code = resultStatus.StatusCode(this.Status)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetInitResponseObj
|
||||
// @description: 获取初始的响应对象
|
||||
// parameter:
|
||||
// return:
|
||||
// @*ResponseObject: 响应对象
|
||||
func GetInitResponseObj() *ResponseObject {
|
||||
return &ResponseObject{
|
||||
Code: resultStatus.Success.Code(),
|
||||
Message: "",
|
||||
Value: nil,
|
||||
}
|
||||
}
|
||||
43
trunk/center/common/webServer/result.go
Normal file
43
trunk/center/common/webServer/result.go
Normal file
@ -0,0 +1,43 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"goutil/logUtilPlus"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// responseResult
|
||||
// @description: responseResult
|
||||
// parameter:
|
||||
// @w: w
|
||||
// @responseObj: responseObj
|
||||
// return:
|
||||
func responseResult(w http.ResponseWriter, responseObj *ResponseObject) {
|
||||
b, err := json.Marshal(responseObj)
|
||||
if err != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("序列化输出结果%v出错", responseObj))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Length", strconv.Itoa(len(b)))
|
||||
w.Write(b)
|
||||
}
|
||||
|
||||
// responseResultByJson
|
||||
// @description: responseResult
|
||||
// parameter:
|
||||
// @w: w
|
||||
// @responseObj: responseObj
|
||||
// return:
|
||||
func responseResultByJson(w http.ResponseWriter, responseObj *ResponseObject) {
|
||||
b, err := json.Marshal(responseObj)
|
||||
if err != nil {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("序列化输出结果%v出错", responseObj))
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Length", strconv.Itoa(len(b)))
|
||||
w.Write(b)
|
||||
}
|
||||
122
trunk/center/common/webServer/serverMux.go
Normal file
122
trunk/center/common/webServer/serverMux.go
Normal file
@ -0,0 +1,122 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
config "common/configsYaml"
|
||||
"common/resultStatus"
|
||||
"common/utils"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"framework/ipMgr"
|
||||
"goutil/logUtilPlus"
|
||||
"goutil/stringUtil"
|
||||
"goutil/webUtil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// selfDefineMux
|
||||
//
|
||||
// @description: 定义自定义的Mux对象
|
||||
type selfDefineMux struct {
|
||||
}
|
||||
|
||||
// ServeHTTP
|
||||
//
|
||||
// @description: ServeHTTP
|
||||
//
|
||||
// parameter:
|
||||
//
|
||||
// @receiver mux: mux
|
||||
// @w: w
|
||||
// @r: r
|
||||
//
|
||||
// return:
|
||||
func (mux *selfDefineMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
responseObj := GetInitResponseObj()
|
||||
defer utils.LogReqErrorRecover(r)
|
||||
|
||||
// 判断是否是接口文档
|
||||
if strings.Contains(r.RequestURI, "Remarks") && r.Method == "GET" {
|
||||
remarkFunc(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断是否是POST方法
|
||||
if r.Method != "POST" {
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.OnlySupportPOST))
|
||||
return
|
||||
}
|
||||
|
||||
// 验证IP是否正确
|
||||
if config.DEBUG == false && ipMgr.IsIpValid(webUtil.GetRequestIP(r)) == false {
|
||||
logUtilPlus.ErrorLog(fmt.Sprintf("请求的IP:%s无效", webUtil.GetRequestIP(r)))
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.IPForbid))
|
||||
return
|
||||
}
|
||||
|
||||
// 构造contex
|
||||
context, errMsg := NewApiContext(r, w, false)
|
||||
if errMsg != nil {
|
||||
// 输出结果
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
|
||||
return
|
||||
}
|
||||
|
||||
// 根据路径选择不同的处理方法
|
||||
if handlerFunObj, exists := GetHandleFunc(r.RequestURI); exists {
|
||||
defer func() {
|
||||
if config.DEBUG {
|
||||
b, _ := json.Marshal(responseObj)
|
||||
msg := fmt.Sprintf("API:%v 请求数据:%v;返回数据:%s;",
|
||||
r.RequestURI, string(context.GetRequestBytes()), string(b))
|
||||
logUtilPlus.DebugLog(msg)
|
||||
}
|
||||
}()
|
||||
|
||||
// 输出结果
|
||||
responseObj := handlerFunObj.HandleFun()(context)
|
||||
responseResult(w, responseObj)
|
||||
return
|
||||
}
|
||||
|
||||
// 通过反射选择不同的方法
|
||||
strs := stringUtil.Split(r.RequestURI, []string{"/"})
|
||||
var params []interface{}
|
||||
var err error
|
||||
isJson := false
|
||||
|
||||
// 参数错误
|
||||
if len(strs) != 2 {
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
|
||||
return
|
||||
}
|
||||
|
||||
//验证是否登录
|
||||
if strs[0] != "AdminApi" || strs[1] != "Login" {
|
||||
tokenStr := context.header.Get("token")
|
||||
|
||||
// token 转型成 int64
|
||||
token := stringUtil.StringToInt64(tokenStr)
|
||||
|
||||
//是否存在
|
||||
if !CheckToken(token) {
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.NotLogin))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
params, err = context.RequestDataBySlice2ByJson()
|
||||
if err != nil {
|
||||
responseResult(w, responseObj.SetResultStatus(resultStatus.APIDataError))
|
||||
return
|
||||
}
|
||||
|
||||
resquestData := NewRequestObject(strs[0], strs[1], params)
|
||||
resp := CallFunction(resquestData)
|
||||
if isJson {
|
||||
responseResultByJson(w, resp)
|
||||
} else {
|
||||
responseResult(w, resp)
|
||||
}
|
||||
|
||||
}
|
||||
41
trunk/center/common/webServer/start.go
Normal file
41
trunk/center/common/webServer/start.go
Normal file
@ -0,0 +1,41 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"goutil/logUtil"
|
||||
"goutil/logUtilPlus"
|
||||
"net/http/pprof"
|
||||
|
||||
config "common/configsYaml"
|
||||
)
|
||||
|
||||
// Start
|
||||
// @description: 启动服务器
|
||||
// parameter:
|
||||
// @wg: WaitGroup对象
|
||||
// return:
|
||||
func Start(wg *sync.WaitGroup) {
|
||||
defer func() {
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
// 启动过程中不需要捕获异常
|
||||
logUtilPlus.PrintAndWriteLog(logUtil.Warn, fmt.Sprintf("Web服务器开始监听:%v", config.ConfigYaml.Root.WebServerAddress))
|
||||
|
||||
// 启动Web服务器监听
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/", &selfDefineMux{})
|
||||
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
|
||||
err := http.ListenAndServe(config.ConfigYaml.Root.WebServerAddress, mux)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("ListenAndServe失败,错误信息为:%s", err))
|
||||
}
|
||||
}
|
||||
92
trunk/center/common/webServer/tokenHandler.go
Normal file
92
trunk/center/common/webServer/tokenHandler.go
Normal file
@ -0,0 +1,92 @@
|
||||
package webServer
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
//已经登录的用户
|
||||
loginUserMap = make(map[int64]*TokenInfo)
|
||||
|
||||
//锁
|
||||
lock sync.RWMutex
|
||||
)
|
||||
|
||||
type TokenInfo struct {
|
||||
//管理员id
|
||||
Id int64
|
||||
|
||||
//管理员账号
|
||||
Account string
|
||||
|
||||
//过期时间
|
||||
ExpireTime time.Time
|
||||
}
|
||||
|
||||
// AddLoginUserToken 添加登录用户及其令牌信息到缓存中
|
||||
// 参数:
|
||||
//
|
||||
// token: 用户的登录令牌
|
||||
// tokenInfo: 令牌的详细信息,包括过期时间等
|
||||
func AddLoginUserToken(token int64, tokenInfo *TokenInfo) {
|
||||
|
||||
//添加锁防止并发
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
// 默认24小时过期
|
||||
tokenInfo.ExpireTime = time.Now().Add(time.Hour * 24)
|
||||
|
||||
//移除旧的令牌
|
||||
for tokenKey, tokenInfoValue := range loginUserMap {
|
||||
if tokenInfo.Id == tokenInfoValue.Id {
|
||||
delete(loginUserMap, tokenKey)
|
||||
}
|
||||
}
|
||||
|
||||
// 将令牌与用户信息添加到全局的登录用户映射中
|
||||
loginUserMap[token] = tokenInfo
|
||||
}
|
||||
|
||||
// CheckToken 检查令牌是否有效
|
||||
// 参数:
|
||||
//
|
||||
// token: 需要检查的令牌字符串
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// bool: 表示令牌是否有效的布尔值,true表示有效,false表示无效
|
||||
func CheckToken(token int64) bool {
|
||||
|
||||
//添加锁防止并发
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
// 获取当前时间
|
||||
now := time.Now()
|
||||
|
||||
// 获取令牌对应的用户信息
|
||||
tokenInfo, ok := loginUserMap[token]
|
||||
if !ok {
|
||||
// 如果没有找到对应的用户信息,则令牌无效
|
||||
return false
|
||||
}
|
||||
|
||||
// 获取令牌过期时间
|
||||
expireTime := tokenInfo.ExpireTime
|
||||
|
||||
// 如果令牌过期时间早于当前时间,则令牌无效
|
||||
if expireTime.Before(now) {
|
||||
|
||||
//移除令牌
|
||||
delete(loginUserMap, token)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//如果生效的话,则更新过期时间
|
||||
tokenInfo.ExpireTime = now.Add(time.Hour * 24)
|
||||
|
||||
return true
|
||||
}
|
||||
5
trunk/center/paycenter/go.mod
Normal file
5
trunk/center/paycenter/go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module main.go
|
||||
|
||||
go 1.22.10
|
||||
|
||||
require github.com/wechatpay-apiv3/wechatpay-go v0.2.20
|
||||
20
trunk/center/paycenter/go.sum
Normal file
20
trunk/center/paycenter/go.sum
Normal file
@ -0,0 +1,20 @@
|
||||
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
|
||||
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/wechatpay-apiv3/wechatpay-go v0.2.20 h1:gS8oFn1bHGnyapR2Zb4aqTV6l4kJWgbtqjCq6k1L9DQ=
|
||||
github.com/wechatpay-apiv3/wechatpay-go v0.2.20/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
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=
|
||||
73
trunk/center/paycenter/main.go
Normal file
73
trunk/center/paycenter/main.go
Normal file
@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
mchID string = "190000****" // 商户号
|
||||
mchCertificateSerialNumber string = "3775B6A45ACD588826D15E583A95F5DD********" // 商户证书序列号
|
||||
mchAPIv3Key string = "2ab9****************************" // 商户APIv3密钥
|
||||
)
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
|
||||
if err != nil {
|
||||
log.Fatal("load merchant private key error")
|
||||
}
|
||||
ctx := context.Background()
|
||||
// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
|
||||
opts := []core.ClientOption{
|
||||
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
|
||||
}
|
||||
client, err := core.NewClient(ctx, opts...)
|
||||
if err != nil {
|
||||
log.Fatalf("new wechat pay client err:%s", err)
|
||||
}
|
||||
// 以 Native 支付为例
|
||||
svc := native.NativeApiService{Client: client}
|
||||
// 发送请求
|
||||
resp, result, err := svc.Prepay(ctx,
|
||||
native.PrepayRequest{
|
||||
Appid: core.String("wxd678efh567hg6787"),
|
||||
Mchid: core.String("1900009191"),
|
||||
Description: core.String("Image形象店-深圳腾大-QQ公仔"),
|
||||
OutTradeNo: core.String("1217752501201407033233368018"),
|
||||
Attach: core.String("自定义数据说明"),
|
||||
NotifyUrl: core.String("https://www.weixin.qq.com/wxpay/pay.php"),
|
||||
Amount: &native.Amount{
|
||||
Total: core.Int64(100),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// 使用微信扫描 resp.code_url 对应的二维码,即可体验Native支付
|
||||
log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
|
||||
svc1 := jsapi.JsapiApiService{Client: client}
|
||||
// 得到prepay_id,以及调起支付所需的参数和签名
|
||||
resp1, result, err := svc1.PrepayWithRequestPayment(ctx,
|
||||
jsapi.PrepayRequest{
|
||||
Appid: core.String("wxd678efh567hg6787"),
|
||||
Mchid: core.String("1900009191"),
|
||||
Description: core.String("Image形象店-深圳腾大-QQ公仔"),
|
||||
OutTradeNo: core.String("1217752501201407033233368018"),
|
||||
Attach: core.String("自定义数据说明"),
|
||||
NotifyUrl: core.String("https://www.weixin.qq.com/wxpay/pay.php"),
|
||||
Amount: &jsapi.Amount{
|
||||
Total: core.Int64(100),
|
||||
},
|
||||
Payer: &jsapi.Payer{
|
||||
Openid: core.String("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// 使用微信扫描 resp.code_url 对应的二维码,即可体验Native支付
|
||||
log.Printf("status=%d resp=%s", result.Response.StatusCode, resp1)
|
||||
}
|
||||
40
trunk/center/usercenter/Dockerfile
Normal file
40
trunk/center/usercenter/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
||||
# 使用官方的 Go 镜像作为构建环境
|
||||
FROM golang:1.22.10-alpine AS builder
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置 Go 代理
|
||||
ENV GOPROXY=https://goproxy.cn,direct
|
||||
|
||||
# 禁用 CGO
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
# 复制所有源代码文件
|
||||
COPY . .
|
||||
|
||||
WORKDIR /app/admincenter
|
||||
|
||||
# 构建应用程序,并确认生成的文件
|
||||
RUN go build -o adminserver -ldflags="-s -w"
|
||||
|
||||
# 使用官方的 Alpine 镜像作为运行环境
|
||||
FROM alpine:latest
|
||||
|
||||
# 设置作者标签
|
||||
LABEL authors="tp"
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 从构建阶段复制编译好的可执行文件
|
||||
COPY --from=builder /app/admincenter/adminserver .
|
||||
|
||||
# 复制配置文件
|
||||
COPY --from=builder /app/admincenter/config.yaml .
|
||||
|
||||
# 暴露端口(假设 adminserver 监听 10051 端口)
|
||||
EXPOSE 10051
|
||||
|
||||
# 设置容器启动时运行 adminserver
|
||||
ENTRYPOINT ["./adminserver"]
|
||||
BIN
trunk/center/usercenter/LOG/2025/1/2025-01-02.tar.gz
Normal file
BIN
trunk/center/usercenter/LOG/2025/1/2025-01-02.tar.gz
Normal file
Binary file not shown.
48
trunk/center/usercenter/LOG/2025/1/2025-01-03-10.debug.txt
Normal file
48
trunk/center/usercenter/LOG/2025/1/2025-01-03-10.debug.txt
Normal file
@ -0,0 +1,48 @@
|
||||
2025-01-03 10:17:22---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:17:22---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:06---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:06---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:30:37---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:30:37---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:16---->
|
||||
开始加载DbConfig
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:16---->
|
||||
开始加载LogMgr
|
||||
------------------------------------------------------
|
||||
165
trunk/center/usercenter/LOG/2025/1/2025-01-03-10.warn.txt
Normal file
165
trunk/center/usercenter/LOG/2025/1/2025-01-03-10.warn.txt
Normal file
@ -0,0 +1,165 @@
|
||||
2025-01-03 10:17:22---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:17:22---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:17:22---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:17:22---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:17:22---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:17:22---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:17:32---->
|
||||
monitorNewMgr没有初始化参数,请调用SetParam进行初始化
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:21:53---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:22:03---->
|
||||
monitorNewMgr没有初始化参数,请调用SetParam进行初始化
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:46---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:26:56---->
|
||||
monitorNewMgr没有初始化参数,请调用SetParam进行初始化
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:18---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:28---->
|
||||
monitorNewMgr没有初始化参数,请调用SetParam进行初始化
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:27:57---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:06---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:06---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:06---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:06---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:06---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:28:56---->
|
||||
monitorNewMgr没有初始化参数,请调用SetParam进行初始化
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:30:02---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:30:37---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:30:37---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:30:42---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:30:42---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:04---->
|
||||
monitorNewMgr没有初始化参数,请调用SetParam进行初始化
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:04---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:04---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:16---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:16---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:19---->
|
||||
开始连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/user?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:19---->
|
||||
连接mysql:root:Qq5201530300@tcp(192.168.50.110:3306)/user?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true成功
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:19---->
|
||||
ping->redis:192.168.50.110:6379成功,信息为:PONG
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:21---->
|
||||
Web服务器开始监听:192.168.50.85:10052
|
||||
------------------------------------------------------
|
||||
2025-01-03 10:31:26---->
|
||||
monitorNewMgr没有初始化参数,请调用SetParam进行初始化
|
||||
------------------------------------------------------
|
||||
21
trunk/center/usercenter/buildLiunx.sh
Normal file
21
trunk/center/usercenter/buildLiunx.sh
Normal file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 设置 Go 环境变量,确保使用 Linux 架构
|
||||
export GOOS=linux
|
||||
export GOARCH=amd64
|
||||
|
||||
echo "开始编译..."
|
||||
|
||||
# 编译 Go 代码
|
||||
go build -o adminServer
|
||||
|
||||
# 检查编译是否成功
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "编译成功!"
|
||||
else
|
||||
echo "编译失败!"
|
||||
fi
|
||||
|
||||
# 等待用户输入任意键
|
||||
read -p "编译完成,按任意键继续..."
|
||||
exit 1
|
||||
54
trunk/center/usercenter/config.yaml
Normal file
54
trunk/center/usercenter/config.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
# 配置根节点
|
||||
root:
|
||||
# 是否是调试模式
|
||||
debug: true
|
||||
|
||||
# Web服务监听地址和端口
|
||||
web_server_address: "192.168.50.85:10052"
|
||||
|
||||
# Elasticsearch 地址
|
||||
es_urls: "http://10.252.0.70:18099"
|
||||
|
||||
# 数据库配置
|
||||
db_config:
|
||||
admin_db:
|
||||
# 最大处于开启状态的连接数
|
||||
max_open_conns: 0
|
||||
|
||||
# 最大处于空闲状态的连接数
|
||||
max_idle_conns: 0
|
||||
|
||||
# 数据库连接字符串
|
||||
connection_string: "root:Qq5201530300@tcp(192.168.50.110:3306)/admin?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true"
|
||||
|
||||
user_db:
|
||||
# 最大处于开启状态的连接数
|
||||
max_open_conns: 0
|
||||
|
||||
# 最大处于空闲状态的连接数
|
||||
max_idle_conns: 0
|
||||
|
||||
# 数据库连接字符串
|
||||
connection_string: "root:Qq5201530300@tcp(192.168.50.110:3306)/user?charset=utf8&parseTime=true&loc=Local&timeout=30s&multiStatements=true"
|
||||
|
||||
redis_config:
|
||||
# 数据库连接字符串
|
||||
connection_string: "192.168.50.110:6379"
|
||||
|
||||
# 密码, 如果要设置用户Id,则密码设置为:"UserId:Password"
|
||||
password: ""
|
||||
|
||||
# 数据库序号
|
||||
database: 5
|
||||
|
||||
# 最大活跃连接数
|
||||
max_active: 500
|
||||
|
||||
# 最大空闲的连接数
|
||||
max_idle: 200
|
||||
|
||||
# 连接空闲超时时间,单位:秒
|
||||
idle_timeout: 300
|
||||
|
||||
# 连接超时时间, 单位:秒
|
||||
dial_connect_timeout: 10
|
||||
37
trunk/center/usercenter/docker-compose.yml
Normal file
37
trunk/center/usercenter/docker-compose.yml
Normal file
@ -0,0 +1,37 @@
|
||||
version: '3'
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: mysql-admin
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
MYSQL_DATABASE: admin,user
|
||||
volumes:
|
||||
- /my/own/datadir:/var/lib/mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
redis:
|
||||
image: redis:7.0
|
||||
container_name: redis-admin
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
restart: always
|
||||
command: ["redis-server", "--appendonly", "yes"]
|
||||
|
||||
admin-center:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: admin-center
|
||||
ports:
|
||||
- "10051:10051"
|
||||
volumes:
|
||||
- ./app:/app
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
28
trunk/center/usercenter/dockerRun.sh
Normal file
28
trunk/center/usercenter/dockerRun.sh
Normal file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 导航到 Dockerfile 所在目录
|
||||
#cd D:\workspace\e2023\goProject\trunk\center\admincenter
|
||||
|
||||
# 构建 Docker 镜像
|
||||
echo "开始构建 Docker 镜像..."
|
||||
docker build -t adminserver-image .
|
||||
|
||||
# 检查构建是否成功
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "构建失败!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "镜像构建成功!"
|
||||
|
||||
# 运行 Docker 容器
|
||||
echo "开始运行 Docker 容器..."
|
||||
docker run -d -p 10051:10051 --name adminserver-container adminserver-image
|
||||
|
||||
# 检查容器是否成功运行
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "容器启动失败!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "容器启动成功!"
|
||||
38
trunk/center/usercenter/go.mod
Normal file
38
trunk/center/usercenter/go.mod
Normal file
@ -0,0 +1,38 @@
|
||||
module logincenter
|
||||
|
||||
go 1.22.10
|
||||
|
||||
replace (
|
||||
common => ../common
|
||||
framework => ../../framework
|
||||
goutil => ../../goutil
|
||||
)
|
||||
|
||||
require (
|
||||
common v0.0.0-00010101000000-000000000000
|
||||
goutil v0.0.0-20230425160006-b2d0b0a0b0b0
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
framework v0.0.0-20230425160006-b2d0b0a0b0b0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/gomodule/redigo v1.8.9 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/jinzhu/gorm v1.9.12 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
gorm.io/driver/mysql v1.5.7 // indirect
|
||||
gorm.io/gorm v1.25.12 // indirect
|
||||
)
|
||||
89
trunk/center/usercenter/go.sum
Normal file
89
trunk/center/usercenter/go.sum
Normal file
@ -0,0 +1,89 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4 h1:OoL469zqSNrTLSz5zeVF/I6VOO7fiw2bzSzQe4J557c=
|
||||
github.com/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4/go.mod h1:xe9a/L2aeOgFKKgrO3ibQTnMdpAeL0GC+5/HpGScSa4=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
|
||||
github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
21
trunk/center/usercenter/internal/game/game.go
Normal file
21
trunk/center/usercenter/internal/game/game.go
Normal file
@ -0,0 +1,21 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"common/connection"
|
||||
)
|
||||
|
||||
func init() {
|
||||
//注册数据库
|
||||
connection.RegisterDBModel(&Game{})
|
||||
}
|
||||
|
||||
type Game struct {
|
||||
GameID int64 `gorm:"column:game_id;primary_key;comment:用户id;autoIncrementIncrement" json:"gameid"`
|
||||
|
||||
//账号
|
||||
Account string `gorm:"column:account;comment:账号" json:"account"`
|
||||
}
|
||||
|
||||
func (Game) TableName() string {
|
||||
return "user"
|
||||
}
|
||||
77
trunk/center/usercenter/internal/game/logic.go
Normal file
77
trunk/center/usercenter/internal/game/logic.go
Normal file
@ -0,0 +1,77 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"common/cache"
|
||||
"common/connection"
|
||||
"goutil/logUtilPlus"
|
||||
. "logincenter/internal/user"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// 包名称(功能名称)
|
||||
var packageName = "game"
|
||||
|
||||
// 读写锁
|
||||
var lock sync.RWMutex
|
||||
|
||||
func AddGame(user *User, game *Game) (int64, error) {
|
||||
|
||||
//处理一些验证
|
||||
|
||||
//判断缓存是否存在
|
||||
gameMap, _ := cache.GetData[map[int64]*Game](user.Cache, packageName)
|
||||
if gameMap == nil {
|
||||
gameMap = make(map[int64]*Game)
|
||||
}
|
||||
|
||||
//添加新的缓存
|
||||
func() {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
gameMap[game.GameID] = game
|
||||
}()
|
||||
|
||||
//写入缓存
|
||||
cache.SetData[*Game](user.Cache, packageName, gameMap)
|
||||
|
||||
// 写入到数据库
|
||||
result := connection.GetUserDB().Create(&game) // 通过数据的指针来创建
|
||||
|
||||
if result.Error != nil {
|
||||
logUtilPlus.ErrorLog("添加用户失败 错误信息:", result.Error.Error())
|
||||
}
|
||||
return game.GameID, nil
|
||||
}
|
||||
|
||||
// 获取有些列表
|
||||
func GetGameList(user *User) (map[int64]*Game, error) {
|
||||
|
||||
//处理一些验证
|
||||
|
||||
//验证缓存
|
||||
gameMap, _ := cache.GetData[map[int64]*Game](user.Cache, packageName)
|
||||
if gameMap != nil {
|
||||
return gameMap, nil
|
||||
}
|
||||
|
||||
// 获取全部列表
|
||||
var gameList []*Game
|
||||
result := connection.GetUserDB().Find(&gameList) // 通过数据的指针来创建
|
||||
|
||||
if result.Error != nil {
|
||||
logUtilPlus.ErrorLog("添加用户失败 错误信息:", result.Error.Error())
|
||||
}
|
||||
|
||||
for _, game := range gameList {
|
||||
gameMap[game.GameID] = game
|
||||
}
|
||||
|
||||
//添加缓存
|
||||
func() {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
cache.SetData(user.Cache, packageName, gameMap)
|
||||
}()
|
||||
|
||||
return gameMap, nil
|
||||
}
|
||||
6
trunk/center/usercenter/internal/user.go
Normal file
6
trunk/center/usercenter/internal/user.go
Normal file
@ -0,0 +1,6 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
_ "logincenter/internal/game"
|
||||
_ "logincenter/internal/user"
|
||||
)
|
||||
139
trunk/center/usercenter/internal/user/api.go
Normal file
139
trunk/center/usercenter/internal/user/api.go
Normal file
@ -0,0 +1,139 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"common/remark"
|
||||
"common/resultStatus"
|
||||
"common/webServer"
|
||||
"goutil/intUtil"
|
||||
"goutil/securityUtil"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
//注册接口
|
||||
webServer.RegisterFunction(new(UserApi))
|
||||
}
|
||||
|
||||
func init() {
|
||||
moduleName := "UserApi"
|
||||
desc := "用户接口"
|
||||
author := "tangping"
|
||||
mendor := ""
|
||||
date := "2024-12-25"
|
||||
remark.RegisterModuleRemark(moduleName, desc, author, mendor, date)
|
||||
}
|
||||
|
||||
// UserApi 用户接口
|
||||
type UserApi struct {
|
||||
}
|
||||
|
||||
// ---------------------------------------- 接口 --------------------------------------------------
|
||||
func init() {
|
||||
moduleName := "UserApi"
|
||||
methodName := "Register"
|
||||
methodDesc := "注册用户"
|
||||
methodAuthor := "tangping"
|
||||
methodMendor := ""
|
||||
methodDate := "2024-12-25 15:55:00"
|
||||
methodInParam := []string{"string 账号,string:用户名称,string:用户密码,string:用户性别,string:用户生日,int64:用户手机号,string:用户邮箱,string:用户微信群,string:用户备注"}
|
||||
methodOutParam := `
|
||||
{
|
||||
"Code '类型:int'": "响应结果的状态值",
|
||||
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
|
||||
"Data '类型:interface{}'": "响应结果的数据"
|
||||
{
|
||||
"id '类型:int'": "用户id",
|
||||
}
|
||||
}`
|
||||
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam)
|
||||
}
|
||||
func (a *UserApi) Register(account string, name string, password string, sex int32, birthday string, phone int64, email string, wechatGroup string, describe string) (responseObj *webServer.ResponseObject) {
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
//校验参数
|
||||
if account == "" || name == "" || password == "" || sex == 0 || birthday == "" || phone == 0 || email == "" || wechatGroup == "" {
|
||||
responseObj.SetResultStatus(resultStatus.APIDataError)
|
||||
return
|
||||
}
|
||||
|
||||
//密码md5加密
|
||||
password = securityUtil.Md5String(password, true)
|
||||
|
||||
//处理数据
|
||||
UserModel := &User{
|
||||
Account: account,
|
||||
Name: name,
|
||||
Password: password,
|
||||
Sex: sex,
|
||||
Birthday: birthday,
|
||||
Phone: phone,
|
||||
Email: email,
|
||||
Describe: describe,
|
||||
}
|
||||
|
||||
//添加到数据库
|
||||
AddUser(UserModel)
|
||||
|
||||
resultMap := make(map[string]any)
|
||||
resultMap["id"] = UserModel.ID
|
||||
responseObj.SetData(resultMap)
|
||||
return
|
||||
}
|
||||
|
||||
// 用户登录
|
||||
func init() {
|
||||
moduleName := "UserApi"
|
||||
methodName := "Login"
|
||||
methodDesc := "用户登录"
|
||||
methodAuthor := "tangping"
|
||||
methodMendor := ""
|
||||
methodDate := "2024-12-26 15:55:00"
|
||||
methodInParam := []string{"string:账号,string:密码"}
|
||||
methodOutParam := `
|
||||
{
|
||||
"Code '类型:int'": "响应结果的状态值",
|
||||
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
|
||||
"Data '类型:interface{}'": "响应结果的数据"
|
||||
{
|
||||
"Token '类型:string'": "登录令牌",
|
||||
}
|
||||
}`
|
||||
|
||||
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam)
|
||||
}
|
||||
|
||||
func (a *UserApi) Login(account string, password string) (responseObj *webServer.ResponseObject) {
|
||||
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
//验证参数
|
||||
if account == "" || password == "" {
|
||||
responseObj.SetResultStatus(resultStatus.APIDataError)
|
||||
return
|
||||
}
|
||||
|
||||
userData, err := Login(account, securityUtil.Md5String(password, true))
|
||||
if err != nil {
|
||||
responseObj.SetResultStatus(resultStatus.DataError)
|
||||
return
|
||||
}
|
||||
|
||||
//生成一个随机token
|
||||
token, err := intUtil.ShuffleIntDigits(time.Now().UnixNano())
|
||||
if err != nil {
|
||||
responseObj.SetResultStatus(resultStatus.DataError)
|
||||
return
|
||||
}
|
||||
|
||||
//添加登录用户
|
||||
webServer.AddLoginUserToken(token, &webServer.TokenInfo{Id: userData.ID, Account: account})
|
||||
|
||||
//UserData映射成map
|
||||
resultMap := make(map[string]any)
|
||||
resultMap["Token"] = strconv.FormatInt(token, 10)
|
||||
|
||||
responseObj.SetData(resultMap)
|
||||
return
|
||||
}
|
||||
89
trunk/center/usercenter/internal/user/logic.go
Normal file
89
trunk/center/usercenter/internal/user/logic.go
Normal file
@ -0,0 +1,89 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"common/cache"
|
||||
"common/connection"
|
||||
"goutil/logUtilPlus"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// 用户缓存对象
|
||||
var userMap = make(map[int64]*User)
|
||||
var rwmu sync.RWMutex
|
||||
|
||||
// GetUserByID 根据用户id获取用户信息
|
||||
func GetUserByID(UserID int64) (*User, error) {
|
||||
|
||||
//判断缓存是否存在
|
||||
var user *User
|
||||
|
||||
func() *User {
|
||||
rwmu.RLock()
|
||||
defer rwmu.RUnlock()
|
||||
ok := true
|
||||
if user, ok = userMap[UserID]; ok {
|
||||
return user
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
|
||||
if user != nil {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
result := connection.GetUserDB().First(&user, UserID)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
//添加缓存
|
||||
func() {
|
||||
rwmu.Lock()
|
||||
defer rwmu.Unlock()
|
||||
user.Cache = cache.NewCache()
|
||||
userMap[user.ID] = user
|
||||
}()
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// AddUserCache 添加用户缓存
|
||||
func AddUserCache(user *User) {
|
||||
rwmu.Lock()
|
||||
defer rwmu.Unlock()
|
||||
user.Cache = cache.NewCache()
|
||||
userMap[user.ID] = user
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
// AddUser 添加新的用户到数据库中。
|
||||
// 参数 User: 包含用户信息的对象。
|
||||
// 返回值: 插入操作影响的行数和可能发生的错误。
|
||||
func AddUser(User *User) (int64, error) {
|
||||
|
||||
//处理一些验证
|
||||
|
||||
//写入缓存
|
||||
AddUserCache(User)
|
||||
|
||||
// 写入到数据库
|
||||
result := connection.GetUserDB().Create(&User) // 通过数据的指针来创建
|
||||
|
||||
if result.Error != nil {
|
||||
logUtilPlus.ErrorLog("添加用户失败 错误信息:", result.Error.Error())
|
||||
}
|
||||
return User.ID, nil
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
func Login(account string, password string) (*User, error) {
|
||||
|
||||
//这里优先验证缓存数据
|
||||
|
||||
var User User
|
||||
result := connection.GetUserDB().Where("account = ? AND password = ?", account, password).First(&User)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return &User, nil
|
||||
}
|
||||
36
trunk/center/usercenter/internal/user/user.go
Normal file
36
trunk/center/usercenter/internal/user/user.go
Normal file
@ -0,0 +1,36 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"common/cache"
|
||||
"common/connection"
|
||||
)
|
||||
|
||||
func init() {
|
||||
//注册数据库
|
||||
connection.RegisterDBModel(&User{})
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID int64 `gorm:"column:id;primary_key;comment:用户id;autoIncrementIncrement" json:"id"`
|
||||
//账号
|
||||
Account string `gorm:"column:account;comment:账号" json:"account"`
|
||||
Name string `gorm:"column:name;comment:用户名称" json:"name"`
|
||||
Password string `gorm:"column:password;comment:用户密码" json:"password"`
|
||||
//性别
|
||||
Sex int32 `gorm:"column:sex;comment:性别" json:"sex"`
|
||||
//生日
|
||||
Birthday string `gorm:"column:birthday;comment:生日" json:"birthday"`
|
||||
//手机
|
||||
Phone int64 `gorm:"column:phone;comment:手机" json:"phone"`
|
||||
//邮箱
|
||||
Email string `gorm:"column:email;comment:邮箱" json:"email"`
|
||||
//备注
|
||||
Describe string `gorm:"column:describe;comment:备注" json:"describe"`
|
||||
|
||||
//玩家的缓存对象
|
||||
Cache *cache.Cache `gorm:"-"`
|
||||
}
|
||||
|
||||
func (User) TableName() string {
|
||||
return "user"
|
||||
}
|
||||
43
trunk/center/usercenter/main.go
Normal file
43
trunk/center/usercenter/main.go
Normal file
@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"common/connection"
|
||||
"sync"
|
||||
|
||||
_ "common/resultStatus"
|
||||
"common/webServer"
|
||||
_ "logincenter/internal/user"
|
||||
)
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 设置WaitGroup需要等待的数量,只要有一个服务器出现错误都停止服务器
|
||||
wg.Add(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
//加载配置
|
||||
loadConfig()
|
||||
|
||||
// 启动webserver
|
||||
go webServer.Start(&wg)
|
||||
|
||||
// 阻塞等待,以免main线程退出
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// loadConfig 用于加载配置信息。
|
||||
// 该函数会读取配置文件或环境变量中的设置,并根据这些设置初始化程序所需的配置。
|
||||
// 目前函数的实现为空,需要根据实际的配置加载逻辑进行填充。
|
||||
func loadConfig() {
|
||||
|
||||
//设置数据类型
|
||||
connection.SetModelDB(connection.GetUserDB())
|
||||
|
||||
//构建数据库
|
||||
connection.BuildDB()
|
||||
}
|
||||
20
trunk/center/usercenter/run.sh
Normal file
20
trunk/center/usercenter/run.sh
Normal file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 赋予可执行权限
|
||||
chmod +x adminServer
|
||||
|
||||
echo "启动中..."
|
||||
|
||||
# 接受命令行传入一个参数
|
||||
case "$1" in
|
||||
d)
|
||||
# 使用 nohup 将进程放到后台运行,并将输出重定向到 nohup.out 文件
|
||||
nohup ./adminServer > nohup.out 2>&1 &
|
||||
echo "启动完成"
|
||||
;;
|
||||
*)
|
||||
./adminServer
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "启动完成"
|
||||
16
trunk/center/usercenter/stop.sh
Normal file
16
trunk/center/usercenter/stop.sh
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 查找 adminServer 的 PID
|
||||
PID=$(pgrep adminServer)
|
||||
|
||||
if [ -z "$PID" ]; then
|
||||
echo "adminServer 进程未找到"
|
||||
else
|
||||
echo "停止中... (PID: $PID)"
|
||||
kill $PID
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "adminServer 进程已终止 (PID: $PID)"
|
||||
else
|
||||
echo "无法终止 adminServer 进程 (PID: $PID)"
|
||||
fi
|
||||
fi
|
||||
8
trunk/framework/.idea/.gitignore
vendored
Normal file
8
trunk/framework/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
9
trunk/framework/.idea/Framework.iml
Normal file
9
trunk/framework/.idea/Framework.iml
Normal file
@ -0,0 +1,9 @@
|
||||
<?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,0 +1,5 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" />
|
||||
</settings>
|
||||
</component>
|
||||
6
trunk/framework/.idea/misc.xml
Normal file
6
trunk/framework/.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
||||
8
trunk/framework/.idea/modules.xml
Normal file
8
trunk/framework/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Framework.iml" filepath="$PROJECT_DIR$/.idea/Framework.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
trunk/framework/.idea/vcs.xml
Normal file
6
trunk/framework/.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
17
trunk/framework/README
Normal file
17
trunk/framework/README
Normal file
@ -0,0 +1,17 @@
|
||||
v1.0版本,支持以下功能:
|
||||
1、项目中的各种基础功能;
|
||||
2、其中的managecenterMgr兼容旧版本的ManageCenter(2019-12-01之前)。
|
||||
3、新增日志记录功能(LogMgr 2020-03-09)
|
||||
4、新增监控功能(MonitorNewMgr 2020-03-09)
|
||||
5、新增短链功能(ShortUrlMgr 2020-03-09)
|
||||
|
||||
v2.0版本,支持以下功能:
|
||||
1、新的ManageCenter版本(2019-12-01之后)
|
||||
|
||||
v2.0.0.1
|
||||
LogMgr里面Log日志消息先进行base64编码之后再发送到mq,因为原消息有特殊符号,
|
||||
直接发送消息会导致消息返送之后,在腾讯mq收到消息之后数据会丢失,导致验签失败
|
||||
|
||||
v2.0.1.1
|
||||
新增屏蔽字处理forbidWordsMgr
|
||||
新增gameServerMgr
|
||||
9
trunk/framework/bash.exe.stackdump
Normal file
9
trunk/framework/bash.exe.stackdump
Normal file
@ -0,0 +1,9 @@
|
||||
Stack trace:
|
||||
Frame Function Args
|
||||
000FFFFA328 0018006021E (00180252DED, 001802340A6, 000FFFFA328, 000FFFF9220)
|
||||
000FFFFA328 00180048859 (00000000000, 00000000000, 00000000000, 00000000000)
|
||||
000FFFFA328 00180048892 (00180252EA9, 000FFFFA1D8, 000FFFFA328, 00000000000)
|
||||
000FFFFA328 001800AF0D8 (00000000000, 00000000000, 00000000000, 00000000000)
|
||||
000FFFFA328 001800AF25D (000FFFFA340, 00000000000, 00000000000, 00000000000)
|
||||
000FFFFA5B0 001800B0673 (000FFFFA340, 00000000000, 00000000000, 00000000000)
|
||||
End of stack trace
|
||||
34
trunk/framework/configMgr/configMgr.go
Normal file
34
trunk/framework/configMgr/configMgr.go
Normal file
@ -0,0 +1,34 @@
|
||||
package configMgr
|
||||
|
||||
import (
|
||||
"goutil/configUtil"
|
||||
)
|
||||
|
||||
// 配置管理对象
|
||||
type ConfigManager struct {
|
||||
// 初始化方法列表
|
||||
initFuncList []func(*configUtil.XmlConfig) error
|
||||
}
|
||||
|
||||
// 注册初始化方法
|
||||
func (this *ConfigManager) RegisterInitFunc(initFunc func(*configUtil.XmlConfig) error) {
|
||||
this.initFuncList = append(this.initFuncList, initFunc)
|
||||
}
|
||||
|
||||
// 初始化
|
||||
func (this *ConfigManager) Init(configObj *configUtil.XmlConfig) error {
|
||||
for _, initFunc := range this.initFuncList {
|
||||
if err := initFunc(configObj); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建配置管理对象
|
||||
func NewConfigManager() *ConfigManager {
|
||||
return &ConfigManager{
|
||||
initFuncList: make([]func(*configUtil.XmlConfig) error, 0, 8),
|
||||
}
|
||||
}
|
||||
13
trunk/framework/contextcheckMgr/resultmodel.go
Normal file
13
trunk/framework/contextcheckMgr/resultmodel.go
Normal file
@ -0,0 +1,13 @@
|
||||
package contextcheckMgr
|
||||
|
||||
type ResultModel struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Result ResultDetail `json:"result"`
|
||||
}
|
||||
|
||||
type ResultDetail struct {
|
||||
TaskId string `json:"taskId"`
|
||||
Action int `json:"action"`
|
||||
CensorType int `json:"censorType"`
|
||||
}
|
||||
126
trunk/framework/contextcheckMgr/textcheck.go
Normal file
126
trunk/framework/contextcheckMgr/textcheck.go
Normal file
@ -0,0 +1,126 @@
|
||||
package contextcheckMgr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"goutil/logUtil"
|
||||
"goutil/securityUtil"
|
||||
"goutil/webUtil"
|
||||
)
|
||||
|
||||
var (
|
||||
//接口密钥Id
|
||||
msecretId string = "c98276c73c122eaa65163fe431cbf7d4"
|
||||
//接口密钥key
|
||||
msecretKey string = "3d2b39f824fa2f992494e17be500e303"
|
||||
//业务ID
|
||||
mbusinessId string = "9559ce74b5c5d24f6b124799a53c7431"
|
||||
//接口请求地址
|
||||
mapiurl string = "http://as.dun.163.com/v3/text/check"
|
||||
//版本号
|
||||
mversion string = "v3.1"
|
||||
)
|
||||
|
||||
//参数设置
|
||||
func SetPara(secretId, secretKey, businessId, apiurl, version string) {
|
||||
msecretId = secretId
|
||||
msecretKey = secretKey
|
||||
mbusinessId = businessId
|
||||
mapiurl = apiurl
|
||||
mversion = version
|
||||
}
|
||||
|
||||
//content:用户发表内容
|
||||
//account:玩家账号(用户唯一标识)
|
||||
//nickname:角色名称
|
||||
//extStr1:角色区服名称
|
||||
//extStr2:UserId
|
||||
//ip:用户IP地址,建议抄送,辅助机审策略精准调优
|
||||
//extLon1:区服ID
|
||||
//返回值 code: 0:通过, 1:嫌疑,2:不通过
|
||||
//文本内容检测
|
||||
func TextCheck(content, account, nickname, extStr1, extStr2, ip string, extLon1 int64) (code int, err error) {
|
||||
//构造请求参数
|
||||
postDataDict := make(map[string]string)
|
||||
postDataDict["secretId"] = msecretId
|
||||
postDataDict["businessId"] = mbusinessId
|
||||
postDataDict["timestamp"] = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
postDataDict["nonce"] = strconv.FormatInt(rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(10000000000), 10)
|
||||
rawString := fmt.Sprintf("%v%v%v", account, postDataDict["timestamp"], content)
|
||||
postDataDict["dataId"] = securityUtil.Md5String(rawString, false)
|
||||
postDataDict["content"] = content
|
||||
postDataDict["version"] = mversion
|
||||
postDataDict["account"] = account
|
||||
postDataDict["nickname"] = nickname
|
||||
postDataDict["extLon1"] = strconv.FormatInt(extLon1, 10)
|
||||
// postDataDict["extLon2"] = extLon2
|
||||
postDataDict["extStr1"] = extStr1
|
||||
postDataDict["extStr2"] = extStr2
|
||||
postDataDict["ip"] = ip
|
||||
postDataDict["signature"] = getSignature(postDataDict)
|
||||
|
||||
//请求url,请求头
|
||||
header := webUtil.GetFormHeader()
|
||||
transport := webUtil.NewTransport()
|
||||
transport.DisableKeepAlives = true
|
||||
transport = webUtil.GetTimeoutTransport(transport, 30)
|
||||
|
||||
//请求接口
|
||||
statusCode, result, err := webUtil.PostMapData(mapiurl, postDataDict, header, transport)
|
||||
//定义错误信息
|
||||
var logMessage string
|
||||
|
||||
//post请求错误
|
||||
if err != nil {
|
||||
logMessage = fmt.Sprintf("TextCheck:,错误信息为:%s", err.Error())
|
||||
logUtil.ErrorLog(logMessage)
|
||||
return
|
||||
}
|
||||
if statusCode != 200 {
|
||||
logMessage = fmt.Sprintf("TextCheck:%d is wrong", statusCode)
|
||||
logUtil.ErrorLog(logMessage)
|
||||
err = fmt.Errorf("TextCheck:%d is wrong", statusCode)
|
||||
return
|
||||
}
|
||||
|
||||
//反序列化结果
|
||||
var checkResponseObj *ResultModel
|
||||
err = json.Unmarshal(result, &checkResponseObj)
|
||||
if err != nil {
|
||||
logMessage = fmt.Sprintf("json.Unmarshal(checkResponseObj),err:%s", err.Error())
|
||||
logUtil.ErrorLog(logMessage)
|
||||
return
|
||||
}
|
||||
|
||||
//判断接口是否调用成功
|
||||
if checkResponseObj.Code != 200 {
|
||||
logMessage = fmt.Sprintf("TextCheck接口调用失败,ResultStatus %d", checkResponseObj.Code)
|
||||
err = fmt.Errorf("TextCheck接口调用失败,code:%d", checkResponseObj.Code)
|
||||
return
|
||||
}
|
||||
|
||||
//返回检测结果
|
||||
code = checkResponseObj.Result.Action
|
||||
return
|
||||
}
|
||||
|
||||
//生成签名字符串
|
||||
func getSignature(postDataDict map[string]string) string {
|
||||
var paramStr string
|
||||
keys := make([]string, 0, len(postDataDict))
|
||||
for k := range postDataDict {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
paramStr += key + postDataDict[key]
|
||||
}
|
||||
paramStr += msecretKey
|
||||
|
||||
return securityUtil.Md5String(paramStr, false)
|
||||
}
|
||||
49
trunk/framework/contextcheckMgr/textcheck_test.go
Normal file
49
trunk/framework/contextcheckMgr/textcheck_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
package contextcheckMgr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCheck(t *testing.T) {
|
||||
//content, account, nickname, extLon1, extLon2, extStr1, extStr2, ip
|
||||
var content = "文本检查测试"
|
||||
var account = "000e6a6e-7cfc-4da7-81a2-ef3a5d24c586"
|
||||
var nickname = "不仅仅是喜欢"
|
||||
var extLon1 int64 = 10001
|
||||
//var extLon2 = "游戏内聊天"
|
||||
var extStr1 = "10001铁血丹心"
|
||||
var extStr2 = "5DF67DD225640567D4D0B6FE273262B5"
|
||||
var ip = "113.116.66.45"
|
||||
//设置完全正确的参数
|
||||
code, err := TextCheck(content, account, nickname, extStr1, extStr2, ip, extLon1)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("There should be no error, but now there is:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("检测完成,状态码为:%d\n", code)
|
||||
|
||||
content = "修炼发轮功"
|
||||
|
||||
code, err = TextCheck(content, account, nickname, extStr1, extStr2, ip, extLon1)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("There should be no error, but now there is:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("检测完成,状态码为:%d\n", code)
|
||||
|
||||
content = ""
|
||||
|
||||
code, err = TextCheck(content, account, nickname, extStr1, extStr2, ip, extLon1)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("There should be no error, but now there is:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("检测完成,状态码为:%d\n", code)
|
||||
}
|
||||
13
trunk/framework/dataSyncMgr/mysqlSync/doc.go
Normal file
13
trunk/framework/dataSyncMgr/mysqlSync/doc.go
Normal file
@ -0,0 +1,13 @@
|
||||
package mysqlSync
|
||||
|
||||
/*
|
||||
提供数据同步到mysql的方法。基本逻辑如下:
|
||||
1、对外接收数据,以追加的方式保存到大文件中。数据的格式为:header(4bytes)+content。
|
||||
2、启动独立的goroutine来从大文件中读取数据,并保存到数据库中。
|
||||
3、使用syncInfo.txt文件保存当前已经处理的文件的路径,以及下一次将要读取的文件的Offset。为了降低向syncInfo.txt文件中写入失败,
|
||||
导致需要从头开始同步数据,所以采用了在指定数目的范围内以追加形式来写入数据的方式;只有达到了指定数量才会将整个文件清空。
|
||||
|
||||
对于错误的处理方式,分为以下两种:
|
||||
1、文件错误:由于文件系统是本系统的核心,所以如果出现文件的读写出错,则需要终止整个进程,所以需要抛出panic。
|
||||
2、数据库错误:当数据库不可访问时,为了不影响整个外部进程的运行,故而不抛出panic,而只是通过monitorNewMgr.Report的方式来报告故障。
|
||||
*/
|
||||
100
trunk/framework/dataSyncMgr/mysqlSync/errorHandle.go
Normal file
100
trunk/framework/dataSyncMgr/mysqlSync/errorHandle.go
Normal file
@ -0,0 +1,100 @@
|
||||
package mysqlSync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"goutil/fileUtil"
|
||||
"goutil/logUtil"
|
||||
)
|
||||
|
||||
var (
|
||||
// 记录错误sql命令的文件名
|
||||
con_Error_FileName = "errorFile.txt"
|
||||
)
|
||||
|
||||
// 定义处理错误命令的文件对象
|
||||
type errorFile struct {
|
||||
// 错误文件
|
||||
file *os.File
|
||||
|
||||
// 文件路径
|
||||
filePath string
|
||||
|
||||
// 同步数据对象的唯一标识,用于进行重复判断
|
||||
identifier string
|
||||
}
|
||||
|
||||
// 保存命令到错误文件
|
||||
// command: sql命令
|
||||
func (this *errorFile) SaveCommand(command string) {
|
||||
this.open()
|
||||
defer this.close()
|
||||
|
||||
// 覆盖写入
|
||||
this.file.Seek(0, 0)
|
||||
|
||||
// 写入命令
|
||||
_, err := this.file.WriteString(command)
|
||||
if err != nil {
|
||||
prefix := fmt.Sprintf("%s-%s", this.identifier, "errorFile.SaveCommand")
|
||||
err = fmt.Errorf("%s-Write %s to file failed:%s", prefix, command, err)
|
||||
logUtil.ErrorLog(err.Error())
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 清理残留数据
|
||||
this.file.Truncate(int64(len(command)))
|
||||
}
|
||||
|
||||
// 读取文件中命令
|
||||
func (this *errorFile) ReadCommand() string {
|
||||
this.open()
|
||||
defer this.close()
|
||||
|
||||
this.file.Seek(0, 0)
|
||||
content, err := ioutil.ReadAll(this.file)
|
||||
if err != nil {
|
||||
prefix := fmt.Sprintf("%s-%s", this.identifier, "errorFile.ReadCommand")
|
||||
err = fmt.Errorf("%s-Read command failed:%s", prefix, err)
|
||||
logUtil.ErrorLog(err.Error())
|
||||
panic(err)
|
||||
}
|
||||
return string(content)
|
||||
}
|
||||
|
||||
// 打开文件
|
||||
func (this *errorFile) open() {
|
||||
// 打开errorFile文件, 如果没有就创建
|
||||
var err error
|
||||
this.file, err = os.OpenFile(this.filePath, os.O_CREATE|os.O_RDWR, os.ModePerm|os.ModeTemporary)
|
||||
if err != nil {
|
||||
prefix := fmt.Sprintf("%s-%s", this.identifier, "errorFile.newErrorFile.os.OpenFile")
|
||||
err = fmt.Errorf("%s-Open File failed:%s", prefix, err)
|
||||
logUtil.ErrorLog(err.Error())
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭文件
|
||||
func (this *errorFile) close() {
|
||||
this.file.Close()
|
||||
}
|
||||
|
||||
// 删除文件
|
||||
func (this *errorFile) Delete() {
|
||||
fileUtil.DeleteFile(this.filePath)
|
||||
}
|
||||
|
||||
// 构造错误文件对象
|
||||
// _dirPath:文件路径
|
||||
// _identifier:唯一标识
|
||||
func newErrorFile(_dirPath string, _identifier string) *errorFile {
|
||||
_filePath := filepath.Join(_dirPath, con_Error_FileName)
|
||||
return &errorFile{
|
||||
filePath: _filePath,
|
||||
identifier: _identifier,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package logSqlSync
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"goutil/logUtil"
|
||||
)
|
||||
|
||||
// 错误信息记录表是否已经初始化
|
||||
var ifSyncErrorInfoTableInited bool = false
|
||||
|
||||
// 同步的错误信息处理对象
|
||||
type syncErrorInfo struct {
|
||||
// 数据库连接对象
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// 初始化表信息
|
||||
func (this *syncErrorInfo) init() error {
|
||||
// 初始化表结构
|
||||
if ifSyncErrorInfoTableInited == false {
|
||||
err := this.initTable(this.db)
|
||||
if err == nil {
|
||||
ifSyncErrorInfoTableInited = true
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 把同步信息更新到数据库
|
||||
// data:待更新的数据
|
||||
// 返回值:
|
||||
// error:错误信息
|
||||
func (this *syncErrorInfo) AddErrorSql(tran *sql.Tx, data string, errMsg string) error {
|
||||
updateSql := "INSERT INTO `sync_error_info` (`SqlString`,`ExecuteTime`,`RetryCount`,`ErrMessage`) VALUES(?,?,?,?);"
|
||||
|
||||
var err error
|
||||
if tran != nil {
|
||||
_, err = tran.Exec(updateSql, data, time.Now(), 0, errMsg)
|
||||
} else {
|
||||
_, err = this.db.Exec(updateSql, data, time.Now(), 0, errMsg)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logUtil.ErrorLog(fmt.Sprintf("logSqlSync/syncErrorInfo.AddErrorSql Error:%s", err.Error()))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// 初始化同步信息表结构
|
||||
// db:数据库连接对象
|
||||
func (this *syncErrorInfo) initTable(db *sql.DB) error {
|
||||
// 创建同步信息表
|
||||
createTableSql := `CREATE TABLE IF NOT EXISTS sync_error_info (
|
||||
Id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增Id',
|
||||
SqlString varchar(1024) NOT NULL COMMENT '执行的sql',
|
||||
ExecuteTime datetime NOT NULL COMMENT '最近一次执行时间',
|
||||
RetryCount int NOT NULL COMMENT '重试次数',
|
||||
ErrMessage text NULL COMMENT '执行错误的信息',
|
||||
PRIMARY KEY (Id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='未执行成功的sql数据';`
|
||||
if _, err := db.Exec(createTableSql); err != nil {
|
||||
logUtil.ErrorLog(fmt.Sprintf("logSqlSync/syncErrorInfo.initTable Error:%s", err.Error()))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建同步信息对象
|
||||
// _db:数据库连接对象
|
||||
// 返回值:
|
||||
// 同步信息对象
|
||||
func newSyncErrorInfoObject(_db *sql.DB) (result *syncErrorInfo, err error) {
|
||||
result = &syncErrorInfo{
|
||||
db: _db,
|
||||
}
|
||||
|
||||
err = result.init()
|
||||
|
||||
return result, err
|
||||
}
|
||||
204
trunk/framework/dataSyncMgr/mysqlSync/logSqlSync/syncObject.go
Normal file
204
trunk/framework/dataSyncMgr/mysqlSync/logSqlSync/syncObject.go
Normal file
@ -0,0 +1,204 @@
|
||||
package logSqlSync
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"Framework/dataSyncMgr/mysqlSync/sqlSync"
|
||||
"goutil/logUtil"
|
||||
)
|
||||
|
||||
// 同步对象定义
|
||||
type SyncObject struct {
|
||||
// 服务器组Id
|
||||
serverGroupId int32
|
||||
|
||||
// 同步数据的存储路径
|
||||
dirPath string
|
||||
|
||||
// 同步数据对象的唯一标识,用于进行重复判断
|
||||
identifier string
|
||||
|
||||
// 数据库对象
|
||||
dbObj *sql.DB
|
||||
|
||||
// 同步信息对象
|
||||
syncingInfoObj *syncingInfo
|
||||
|
||||
// 错误处理对象
|
||||
errorHandleObj *syncErrorInfo
|
||||
|
||||
// 同步对象
|
||||
syncObj *sqlSync.SyncObject
|
||||
}
|
||||
|
||||
// 初始化
|
||||
// baseObj:基础同步对象
|
||||
func (this *SyncObject) Init(baseObj *sqlSync.SyncObject) {
|
||||
this.syncObj = baseObj
|
||||
|
||||
// 初始化同步信息对象
|
||||
syncingInfoObj, err := newSyncingInfoObject(this.serverGroupId, this.dbObj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
//// 初始化错误处理对象
|
||||
errorHandleObj, err := newSyncErrorInfoObject(this.dbObj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
this.syncingInfoObj = syncingInfoObj
|
||||
this.errorHandleObj = errorHandleObj
|
||||
|
||||
// 初始化当前处理的文件
|
||||
fileList := sqlSync.GetDataFileList(this.dirPath)
|
||||
filePath, _ := this.syncingInfoObj.GetSyncingInfo()
|
||||
if len(filePath) < 0 && len(fileList) > 0 {
|
||||
this.syncingInfoObj.Update(fileList[0], 0, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取正在同步的信息
|
||||
// filePath:文件路径
|
||||
// offset:文件偏移量
|
||||
func (this *SyncObject) GetSyncingInfo() (filePath string, offset int64) {
|
||||
return this.syncingInfoObj.GetSyncingInfo()
|
||||
}
|
||||
|
||||
// 更新
|
||||
// filePath:文件路径
|
||||
// offset:文件偏移量
|
||||
// tran:事务对象
|
||||
// 返回值:
|
||||
// error:错误对象
|
||||
func (this *SyncObject) Update(filePath string, offset int64, tx *sql.Tx) error {
|
||||
return this.syncingInfoObj.Update(filePath, offset, tx)
|
||||
}
|
||||
|
||||
// 同步一条sql语句
|
||||
// command:待执行的命令
|
||||
// filePath:保存路径
|
||||
// offset:文件偏移量
|
||||
// 返回值:
|
||||
// error:错误信息
|
||||
func (this *SyncObject) SyncOneSql(command string, filePath string, offset int64) {
|
||||
var err error
|
||||
for {
|
||||
err = sqlSync.ExecuteByTran(this.dbObj, func(tran *sql.Tx) (isCommit bool, err error) {
|
||||
// 保存sql到数据库
|
||||
err = this.syncToMysql(command, tran)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 保存进度信息到数据库
|
||||
err = this.syncingInfoObj.Update(filePath, offset, tran)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
isCommit = true
|
||||
return
|
||||
})
|
||||
|
||||
// 如果是连接出错,则仍然循环执行
|
||||
if err != nil {
|
||||
if sqlSync.CheckIfConnectionError(err.Error()) {
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// 如果不是数据库连接出错,则算是执行完成
|
||||
break
|
||||
}
|
||||
|
||||
// 如果存在错误,则循环尝试执行
|
||||
if err != nil {
|
||||
this.recordSqlError(command, filePath, offset, err.Error())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 同步数据到mysql中
|
||||
// command:sql语句
|
||||
// tx:事务处理对象
|
||||
// 返回值:
|
||||
// error:错误信息
|
||||
func (this *SyncObject) syncToMysql(command string, tx *sql.Tx) error {
|
||||
_, err := tx.Exec(command)
|
||||
if err != nil {
|
||||
logUtil.ErrorLog(fmt.Sprintf("mysqlSync/logSqlSync/syncObject.syncToMysql error:%s", err.Error()))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 错误处理
|
||||
// cmd:待执行的命令
|
||||
// filePath:保存路径
|
||||
// offset:文件偏移量
|
||||
// errMsg:错误信息
|
||||
func (this *SyncObject) recordSqlError(command string, filePath string, offset int64, errMsg string) {
|
||||
errMsg = sqlSync.GetSimpleErrorMessage(errMsg)
|
||||
|
||||
for {
|
||||
err := sqlSync.ExecuteByTran(this.dbObj, func(tran *sql.Tx) (isCommit bool, err error) {
|
||||
// 保存sql到数据库
|
||||
err = this.errorHandleObj.AddErrorSql(tran, command, errMsg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 保存进度信息到数据库
|
||||
err = this.syncingInfoObj.Update(filePath, offset, tran)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
isCommit = true
|
||||
return
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// 创新新的mysql同步对象
|
||||
// dirPath:存放数据的目录
|
||||
// identifier:当前数据的唯一标识(可以使用数据库表名)
|
||||
// dbObj:数据库对象
|
||||
// syncingInfoObj:同步信息记录对象
|
||||
// errorHandleObj:错误处理对象
|
||||
// 返回值:
|
||||
// mysql同步对象
|
||||
func NewSyncObject(serverGroupId int32, dirPath, identifier string, dbObj *sql.DB) *SyncObject {
|
||||
dirPath = filepath.Join(dirPath, identifier)
|
||||
|
||||
// 创建更新目录
|
||||
err := os.MkdirAll(dirPath, os.ModePerm|os.ModeTemporary)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%s-%s-make dir failed:%s", identifier, "SyncObject.newSyncObject.os.MkdirAll", err)
|
||||
logUtil.ErrorLog(err.Error())
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 构造同步信息对象
|
||||
result := &SyncObject{
|
||||
serverGroupId: serverGroupId,
|
||||
dirPath: dirPath,
|
||||
identifier: identifier,
|
||||
dbObj: dbObj,
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
186
trunk/framework/dataSyncMgr/mysqlSync/logSqlSync/syncingInfo.go
Normal file
186
trunk/framework/dataSyncMgr/mysqlSync/logSqlSync/syncingInfo.go
Normal file
@ -0,0 +1,186 @@
|
||||
package logSqlSync
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"goutil/logUtil"
|
||||
)
|
||||
|
||||
// 同步信息表是否已经被初始化
|
||||
var ifSyncingTableInited bool = false
|
||||
|
||||
// 同步信息项,保存已经处理过的文件的信息
|
||||
type syncingModel struct {
|
||||
// 服务器组Id
|
||||
ServerGroupId int32
|
||||
|
||||
// 待处理文件的绝对路径
|
||||
FilePath string
|
||||
|
||||
// 待处理文件的偏移量
|
||||
FileOffset int64
|
||||
|
||||
// 更新时间
|
||||
UpdateTime time.Time
|
||||
}
|
||||
|
||||
// 同步信息对象
|
||||
type syncingInfo struct {
|
||||
// 服务器组Id
|
||||
ServerGroupId int32
|
||||
|
||||
// 同步信息项
|
||||
item *syncingModel
|
||||
|
||||
// 数据库连接对象
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// 获取同步信息
|
||||
// filePath:正在同步的文件
|
||||
// fileOffset:同步到的位置
|
||||
func (this *syncingInfo) GetSyncingInfo() (filePath string, fileOffset int64) {
|
||||
return this.item.FilePath, this.item.FileOffset
|
||||
}
|
||||
|
||||
// 更新正在同步的位置和文件信息
|
||||
// filePath:文件路径
|
||||
// offset:当前同步到的位置
|
||||
// tran:事务对象,可以为nil
|
||||
// 返回值:
|
||||
// error:处理的错误信息
|
||||
func (this *syncingInfo) Update(filePath string, offset int64, tran *sql.Tx) error {
|
||||
this.item.FilePath = filePath
|
||||
this.item.FileOffset = offset
|
||||
this.item.UpdateTime = time.Now()
|
||||
|
||||
// 更新到数据库
|
||||
return this.update(this.item, tran)
|
||||
}
|
||||
|
||||
// 初始化同步信息
|
||||
// 返回值:
|
||||
// error:错误信息
|
||||
func (this *syncingInfo) init() error {
|
||||
// 数据表初始化
|
||||
if ifSyncingTableInited == false {
|
||||
if err := this.initSyncingInfoTable(this.db); err == nil {
|
||||
ifSyncingTableInited = true
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 获取此表的同步信息
|
||||
data, exist, err := this.get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. 如果同步信息不存在,则初始化一条到此表
|
||||
if exist == false {
|
||||
data = &syncingModel{
|
||||
ServerGroupId: this.ServerGroupId,
|
||||
FilePath: "",
|
||||
FileOffset: 0,
|
||||
UpdateTime: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
this.item = data
|
||||
return nil
|
||||
}
|
||||
|
||||
// 初始化同步信息表结构
|
||||
// db:数据库连接对象
|
||||
func (this *syncingInfo) initSyncingInfoTable(db *sql.DB) error {
|
||||
// 创建同步信息表
|
||||
createTableSql := `CREATE TABLE IF NOT EXISTS syncing_info (
|
||||
ServerGroupId int NOT NULL COMMENT '服务器组Id',
|
||||
FilePath varchar(500) NOT NULL COMMENT '正在同步的文件路径',
|
||||
FileOffset bigint(20) NOT NULL COMMENT '偏移量',
|
||||
UpdateTime datetime NOT NULL COMMENT '最后一次更新时间',
|
||||
PRIMARY KEY (ServerGroupId)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='正在同步的文件信息';`
|
||||
if _, err := db.Exec(createTableSql); err != nil {
|
||||
logUtil.ErrorLog(fmt.Sprintf("logSqlSync/syncingInfo.initSyncingInfoTable Error:%s", err.Error()))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 从数据库获取数据
|
||||
// 返回值:
|
||||
// data:获取到的数据
|
||||
// exist:是否存在此数据
|
||||
// err:错误信息
|
||||
func (this *syncingInfo) get() (data *syncingModel, exist bool, err error) {
|
||||
//// 从数据库查询
|
||||
querySql := fmt.Sprintf("SELECT FilePath,FileOffset,UpdateTime FROM syncing_info WHERE ServerGroupId ='%v'", this.ServerGroupId)
|
||||
var rows *sql.Rows
|
||||
rows, err = this.db.Query(querySql)
|
||||
if err != nil {
|
||||
logUtil.ErrorLog(fmt.Sprintf("logSqlSync/syncingInfo.get.Query ServerGroupId:%v error:%s", this.ServerGroupId, err.Error()))
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() == false {
|
||||
exist = false
|
||||
return
|
||||
}
|
||||
exist = true
|
||||
|
||||
// 读取数据
|
||||
data = &syncingModel{
|
||||
ServerGroupId: this.ServerGroupId,
|
||||
}
|
||||
err = rows.Scan(&data.FilePath, &data.FileOffset, &data.UpdateTime)
|
||||
if err != nil {
|
||||
logUtil.ErrorLog(fmt.Sprintf("logSqlSync/syncingInfo.get.Query ServerGroupId:%v error:%s", this.ServerGroupId, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 把同步信息更新到数据库
|
||||
// data:待更新的数据
|
||||
// tran:事务处理对象
|
||||
// 返回值:
|
||||
// error:错误信息
|
||||
func (this *syncingInfo) update(data *syncingModel, tran *sql.Tx) error {
|
||||
updateSql := "REPLACE INTO `syncing_info` SET `ServerGroupId` = ?, `FilePath` = ?,`FileOffset` = ?, `UpdateTime` = ?;"
|
||||
var err error
|
||||
if tran != nil {
|
||||
_, err = tran.Exec(updateSql, data.ServerGroupId, data.FilePath, data.FileOffset, data.UpdateTime)
|
||||
} else {
|
||||
_, err = this.db.Exec(updateSql, data.ServerGroupId, data.FilePath, data.FileOffset, data.UpdateTime)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logUtil.ErrorLog(fmt.Sprintf("logSqlSync/syncingInfo.update ServerGroupId:%v error:%s", this.ServerGroupId, err.Error()))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建同步信息对象
|
||||
// _dirPath:目录的路径
|
||||
// _identifier:当前数据的唯一标识(可以使用数据库表名)
|
||||
// _db:数据库连接对象
|
||||
// 返回值:
|
||||
// 同步信息对象
|
||||
func newSyncingInfoObject(serverGroupId int32, _db *sql.DB) (result *syncingInfo, err error) {
|
||||
result = &syncingInfo{
|
||||
ServerGroupId: serverGroupId,
|
||||
db: _db,
|
||||
}
|
||||
|
||||
err = result.init()
|
||||
|
||||
return result, err
|
||||
}
|
||||
62
trunk/framework/dataSyncMgr/mysqlSync/logSyncTest/dal.go
Normal file
62
trunk/framework/dataSyncMgr/mysqlSync/logSyncTest/dal.go
Normal file
@ -0,0 +1,62 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/jinzhu/gorm"
|
||||
"Framework/dataSyncMgr/mysqlSync"
|
||||
"goutil/logUtil"
|
||||
)
|
||||
|
||||
var _ = mysql.DeregisterLocalFile
|
||||
|
||||
var (
|
||||
connectionString = "root:moqikaka3309@tcp(10.1.0.10:3309)/develop_liujun?charset=utf8&parseTime=true&loc=Local&timeout=60s"
|
||||
maxOpenConns = 10
|
||||
maxIdleConns = 10
|
||||
|
||||
syncFileSize = 1024 * 1024
|
||||
)
|
||||
|
||||
var (
|
||||
// 数据库对象
|
||||
dbObj *gorm.DB
|
||||
|
||||
// 同步管理对象
|
||||
syncMgr *mysqlSync.SyncMgr
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 初始化数据库连接
|
||||
dbObj = initMysql()
|
||||
|
||||
// 构造同步管理对象
|
||||
syncMgr = mysqlSync.NewLogSyncMgr(1, "Sync", syncFileSize, dbObj.DB())
|
||||
}
|
||||
|
||||
// 初始化Mysql
|
||||
func initMysql() *gorm.DB {
|
||||
dbObj, err := gorm.Open("mysql", connectionString)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("初始化数据库:%s失败,错误信息为:%s", connectionString, err))
|
||||
}
|
||||
logUtil.DebugLog(fmt.Sprintf("连接mysql:%s成功", connectionString))
|
||||
|
||||
if maxOpenConns > 0 && maxIdleConns > 0 {
|
||||
dbObj.DB().SetMaxOpenConns(maxOpenConns)
|
||||
dbObj.DB().SetMaxIdleConns(maxIdleConns)
|
||||
}
|
||||
|
||||
return dbObj
|
||||
}
|
||||
|
||||
// 注册同步对象
|
||||
func registerSyncObj(identifier string) {
|
||||
syncMgr.RegisterSyncObj(identifier)
|
||||
}
|
||||
|
||||
// 保存sql数据
|
||||
func save(identifier string, command string) {
|
||||
syncMgr.Save(identifier, command)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user