支付宝 接入一系列修改

This commit is contained in:
tangping 2025-02-08 16:30:07 +08:00
parent 27aff930c7
commit cbdce12462
31 changed files with 1432 additions and 357 deletions

View File

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

View File

@ -5,67 +5,35 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="2037df1b-9ccc-4caa-9145-2d6722712612" name="更改" comment=""> <list default="true" id="2037df1b-9ccc-4caa-9145-2d6722712612" name="更改" comment="">
<change afterPath="$PROJECT_DIR$/center/common/rabbitmq/send_data.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/trunk.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/trunk.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/admincenter/config.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/config.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/admincenter/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/go.mod" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/admincenter/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/go.sum" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/admincenter/internal/admin/admin.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/internal/admin/admin.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/admincenter/internal/admin/admin.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/internal/admin/admin.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/admincenter/internal/admin/api.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/internal/admin/api.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/admincenter/internal/admin/api.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/internal/admin/api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/admincenter/internal/admin/logic.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/internal/admin/logic.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/admincenter/internal/admin/logic.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/internal/admin/logic.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/admincenter/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/main.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/admincenter/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/admincenter/main.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/configsYaml/baseConfig.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/configsyaml/baseConfig.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/configsYaml/configYaml.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/configsyaml/configYaml.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/configsYaml/dbConfig.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/configsyaml/dbConfig.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/configsYaml/functionConfig.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/configsyaml/functionConfig.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/configsYaml/init.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/configsyaml/init.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/configsYaml/logMgrConfig.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/configsyaml/logMgrConfig.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/connection/dal.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/connection/dal.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/connection/dal_test.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/connection/dal_test.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/connection/dbHead.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/connection/dbHead.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/connection/dbHead.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/connection/dbHead.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/httpServer/apiContext.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/httpServer/apiContext.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/httpServer/apiHandler.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/httpServer/apiHandler.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/httpServer/apiHandler.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/httpServer/apiHandler.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/httpServer/start.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/httpServer/start.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/httpServer/reflect.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/httpServer/reflect.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/rebbitMQ/config.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/rabbitmq/config.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/httpServer/serverMux.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/httpServer/serverMux.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/rebbitMQ/sendData.go" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/mytime/timefuncs.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/mytime/timefuncs.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/remark/remarkMgr.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/remark/remarkMgr.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/resultstatus/resultStatusCode.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/resultstatus/resultStatusCode.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/resultStatus/resultStatus.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/resultstatus/resultStatus.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/webserver/apiHandler.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/apiHandler.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/resultStatus/resultStatusCode.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/resultstatus/resultStatusCode.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/webserver/reflect.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/reflect.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/apiContext.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/apiContext.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/webserver/responseObject.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/responseObject.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/apiHandler.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/apiHandler.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/common/webserver/serverMux.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/serverMux.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/apiHandlerMgr.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/apiHandlerMgr.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/go.mod" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/reflect.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/reflect.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/go.sum" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/reflectMethod.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/reflectMethod.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/internal/alipay.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/alipay/alipay.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/reflectRequestObject.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/reflectRequestObject.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/internal/mesqueue/game_msg.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/mesqueue/game_msg.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/responseObject.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/responseObject.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/internal/pay.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/wxpay/pay.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/result.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/result.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/serverMux.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/serverMux.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/start.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/start.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/common/webServer/tokenHandler.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/common/webserver/tokenHandler.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/dbcenter/01_test.go" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/center/dbcenter/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/center/dbcenter/go.mod" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/dbcenter/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/center/dbcenter/go.sum" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/dbcenter/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/dbcenter/main.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/config.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/config.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/internal/pay.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/pay.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/internal/pay/api.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/pay/api.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/internal/pay/api.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/pay/api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/internal/pay/logic.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/pay/logic.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/internal/pay/check_order.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/pay/check_order.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/internal/pay/order.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/pay/order.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/paycenter/internal/wxpaycofnig/payconfig.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/wxpay/config.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/internal/wxpaycofnig/payconfig.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/internal/wxpaycofnig/payconfig.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/usercenter/internal/wxuser/api.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/wxuser/api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/main.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/usercenter/internal/wxuser/logic.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/wxuser/logic.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/paycenter/payconfig/wxpayconfig.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/center/paycenter/payconfig/wxpayconfig.yml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/center/usercenter/internal/wxuser/user.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/wxuser/user.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/LOG/2025/1/2025-01-02.tar.gz" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/center/usercenter/internal/wxuser/userrecord.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/wxuser/userrecord.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/LOG/2025/1/2025-01-03-10.debug.txt" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/center/usercenter/internal/wxuser/wechatsdkservice.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/wxuser/wechatsdkservice.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/LOG/2025/1/2025-01-03-10.warn.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/config.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/config.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/go.mod" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/go.sum" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/internal/game/api.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/game/api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/internal/game/logic.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/game/logic.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/internal/user.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/user.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/internal/user/api.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/user/api.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/internal/user/user.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/internal/user/user.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/center/usercenter/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/center/usercenter/main.go" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -85,8 +53,7 @@
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component> </component>
<component name="HighlightingSettingsPerFile"> <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" /> <setting file="file://$USER_HOME$/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.4.windows-amd64/src/log/log.go" root0="SKIP_INSPECTION" />
<setting file="file://$USER_HOME$/go/pkg/mod/github.com/wechatpay-apiv3/wechatpay-go@v0.2.20/services/payments/native/models.go" root0="SKIP_INSPECTION" />
</component> </component>
<component name="ProjectColorInfo">{ <component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 3 &quot;associatedIndex&quot;: 3
@ -99,50 +66,66 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
"DefaultGoTemplateProperty": "Go File", &quot;DefaultGoTemplateProperty&quot;: &quot;Go File&quot;,
"Docker.admincenter.redis: Compose 部署.executor": "Run", &quot;Docker.admincenter.redis: Compose 部署.executor&quot;: &quot;Run&quot;,
"Docker.center/admincenter/Dockerfile builder.executor": "Run", &quot;Docker.admincenter/Dockerfile.executor&quot;: &quot;Run&quot;,
"Go 构建.go build admincenter.executor": "Run", &quot;Docker.center/admincenter/Dockerfile builder.executor&quot;: &quot;Run&quot;,
"Go 构建.go build dbcenter.executor": "Debug", &quot;Go 构建.go build admincenter.executor&quot;: &quot;Run&quot;,
"Go 构建.go build logincenter.executor": "Debug", &quot;Go 构建.go build dbcenter.executor&quot;: &quot;Run&quot;,
"Go 构建.go build usercenter.executor": "Run", &quot;Go 构建.go build logincenter.executor&quot;: &quot;Debug&quot;,
"Go 测试.common/connection 中的 TestGetDBName.executor": "Run", &quot;Go 构建.go build paycenter.executor&quot;: &quot;Run&quot;,
"Go 测试.dbcenter 中的 Test000.executor": "Debug", &quot;Go 构建.go build usercenter.executor&quot;: &quot;Run&quot;,
"Go 测试.dbcenter 中的 Test001 (1).executor": "Debug", &quot;Go 测试.common/connection 中的 TestGetDBName.executor&quot;: &quot;Run&quot;,
"Go 测试.dbcenter 中的 Test001.executor": "Run", &quot;Go 测试.dbcenter 中的 Test000.executor&quot;: &quot;Debug&quot;,
"Go 测试.dbcenter 中的 Test002 (1).executor": "Run", &quot;Go 测试.dbcenter 中的 Test001 (1).executor&quot;: &quot;Debug&quot;,
"Go 测试.dbcenter 中的 Test002.executor": "Run", &quot;Go 测试.dbcenter 中的 Test001.executor&quot;: &quot;Run&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;Go 测试.dbcenter 中的 Test002 (1).executor&quot;: &quot;Run&quot;,
"RunOnceActivity.go.formatter.settings.were.checked": "true", &quot;Go 测试.dbcenter 中的 Test002.executor&quot;: &quot;Run&quot;,
"RunOnceActivity.go.migrated.go.modules.settings": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true", &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
"git-widget-placeholder": "master", &quot;RunOnceActivity.go.formatter.settings.were.checked&quot;: &quot;true&quot;,
"go.import.settings.migrated": "true", &quot;RunOnceActivity.go.migrated.go.modules.settings&quot;: &quot;true&quot;,
"go.sdk.automatically.set": "true", &quot;RunOnceActivity.go.modules.go.list.on.any.changes.was.set&quot;: &quot;true&quot;,
"last_opened_file_path": "D:/workspace/e2023/goProject/trunk/center/usercenter/internal/wxuser2", &quot;git-widget-placeholder&quot;: &quot;master&quot;,
"node.js.detected.package.eslint": "true", &quot;go.import.settings.migrated&quot;: &quot;true&quot;,
"node.js.selected.package.eslint": "(autodetect)", &quot;go.sdk.automatically.set&quot;: &quot;true&quot;,
"nodejs_package_manager_path": "npm", &quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
"settings.editor.selected.configurable": "org.intellij.sdk.editor.settings.AppSettingsConfigurable" &quot;last_opened_file_path&quot;: &quot;D:/workspace/e2023/goProject/trunk&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;run.configurations.included.in.services&quot;: &quot;true&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;
}, },
"keyToStringList": { &quot;keyToStringList&quot;: {
"DatabaseDriversLRU": [ &quot;DatabaseDriversLRU&quot;: [
"mysql_aurora" &quot;mysql_aurora&quot;
] ]
} }
}]]></component> }</component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="D:\workspace\e2023\goProject\trunk\center\paycenter\internal\cert" />
<recent name="D:\workspace\e2023\goProject\trunk\center\usercenter\internal\wxuser2" /> <recent name="D:\workspace\e2023\goProject\trunk\center\usercenter\internal\wxuser2" />
<recent name="D:\workspace\e2023\goProject\trunk\center\dbcenter\internal" /> <recent name="D:\workspace\e2023\goProject\trunk\center\dbcenter\internal" />
<recent name="D:\workspace\e2023\goProject\trunk\center\dbcenter" /> <recent name="D:\workspace\e2023\goProject\trunk\center\dbcenter" />
<recent name="D:\workspace\e2023\goProject\trunk\game\common" /> <recent name="D:\workspace\e2023\goProject\trunk\game\common" />
<recent name="D:\workspace\e2023\goProject\trunk\game\common\model" /> </key>
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\workspace\e2023\goProject\trunk\center\paycenter\internal\alipay" />
<recent name="D:\workspace\e2023\goProject\trunk\center\paycenter\internal\wxpay" />
</key> </key>
</component> </component>
<component name="RunManager" selected="Go 测试.common/connection 中的 TestGetDBName"> <component name="RunDashboard">
<option name="configurationTypes">
<set>
<option value="GoApplicationRunConfiguration" />
</set>
</option>
</component>
<component name="RunManager" selected="Go 构建.go build paycenter">
<configuration name="go build admincenter" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true"> <configuration name="go build admincenter" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
<module name="trunk" /> <module name="trunk" />
<working_directory value="$PROJECT_DIR$/center/admincenter" /> <working_directory value="$PROJECT_DIR$/center/admincenter" />
@ -161,6 +144,15 @@
<filePath value="$PROJECT_DIR$/center/dbcenter/main.go" /> <filePath value="$PROJECT_DIR$/center/dbcenter/main.go" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="go build paycenter" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
<module name="trunk" />
<working_directory value="$PROJECT_DIR$/center/paycenter" />
<kind value="PACKAGE" />
<package value="paycenter" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$/center/paycenter/main.go" />
<method v="2" />
</configuration>
<configuration name="go build usercenter" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true"> <configuration name="go build usercenter" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
<module name="trunk" /> <module name="trunk" />
<working_directory value="$PROJECT_DIR$/center/usercenter" /> <working_directory value="$PROJECT_DIR$/center/usercenter" />
@ -170,29 +162,6 @@
<filePath value="$PROJECT_DIR$/center/usercenter/main.go" /> <filePath value="$PROJECT_DIR$/center/usercenter/main.go" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="common/connection 中的 TestGetDBName" type="GoTestRunConfiguration" factoryName="Go Test" temporary="true" nameIsGenerated="true">
<module name="trunk" />
<working_directory value="$PROJECT_DIR$/center/common/connection" />
<root_directory value="$PROJECT_DIR$/center/common" />
<kind value="PACKAGE" />
<package value="common/connection" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$" />
<framework value="gotest" />
<pattern value="^\QTestGetDBName\E$" />
<method v="2" />
</configuration>
<configuration name="dbcenter 中的 Test001 (1)" type="GoTestRunConfiguration" factoryName="Go Test" temporary="true" nameIsGenerated="true">
<module name="trunk" />
<working_directory value="$PROJECT_DIR$/center/dbcenter" />
<kind value="PACKAGE" />
<package value="dbcenter" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$" />
<framework value="gotest" />
<pattern value="^\QTest001\E$" />
<method v="2" />
</configuration>
<configuration default="true" type="docker-deploy" factoryName="docker-compose.yml" temporary="true"> <configuration default="true" type="docker-deploy" factoryName="docker-compose.yml" temporary="true">
<deployment type="docker-compose.yml"> <deployment type="docker-compose.yml">
<settings /> <settings />
@ -205,21 +174,29 @@
</deployment> </deployment>
<method v="2" /> <method v="2" />
</configuration> </configuration>
<configuration name="admincenter/Dockerfile" type="docker-deploy" factoryName="dockerfile" temporary="true" server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="sourceFilePath" value="center/admincenter/Dockerfile" />
</settings>
</deployment>
<method v="2" />
</configuration>
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Go 测试.common/connection 中的 TestGetDBName" /> <item itemvalue="Go 构建.go build paycenter" />
<item itemvalue="Go 构建.go build admincenter" /> <item itemvalue="Go 构建.go build admincenter" />
<item itemvalue="Go 构建.go build usercenter" />
<item itemvalue="Go 构建.go build dbcenter" /> <item itemvalue="Go 构建.go build dbcenter" />
<item itemvalue="Go 测试.dbcenter 中的 Test001 (1)" /> <item itemvalue="Go 构建.go build usercenter" />
<item itemvalue="Docker.admincenter/Dockerfile" />
</list> </list>
</recent_temporary> </recent_temporary>
</component> </component>
<component name="SharedIndexes"> <component name="SharedIndexes">
<attachedChunks> <attachedChunks>
<set> <set>
<option value="bundled-gosdk-5df93f7ad4aa-df9ad98b711f-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-242.22855.85" /> <option value="bundled-gosdk-d297c17c1fbd-85c80fddc9a6-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-243.23654.166" />
<option value="bundled-js-predefined-d6986cc7102b-5c90d61e3bab-JavaScript-GO-242.22855.85" /> <option value="bundled-js-predefined-d6986cc7102b-822845ee3bb5-JavaScript-GO-243.23654.166" />
</set> </set>
</attachedChunks> </attachedChunks>
</component> </component>

View File

@ -2,14 +2,13 @@ package admin
import ( import (
"common/connection" "common/connection"
"time"
) )
func init() { func init() {
//注册数据库 //注册数据库
connection.RegisterDBModel(&Admin{}) connection.RegisterDBModel(&Admin{})
connection.RegisterDBModel(&RecordLoginOfWxUser{}) connection.RegisterDBModel(&RecordAveragePlayTimes{})
connection.RegisterDBModel(&RecordWatchADOfWxUser{}) connection.RegisterDBModel(&RecordAverageWatchADNum{})
} }
type Admin struct { type Admin struct {
@ -36,28 +35,71 @@ type Admin struct {
type RecordLoginOfWxUser struct { type RecordLoginOfWxUser struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"` ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"` Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"`
SeverId int32 `gorm:"column:severId;comment:区服Id" json:"severId"`
RecordDate int64 `gorm:"column:recorddate;comment:记录日期" json:"recorddate"` //只记录当天0点的时间戳方便查询某一日的数据
LoginInTime int64 `gorm:"column:loginintime;comment:登录时间" json:"loginintime"` LoginInTime int64 `gorm:"column:loginintime;comment:登录时间" json:"loginintime"`
LoginOutTime int64 `gorm:"column:loginouttime;comment:登出时间" json:"loginouttime"` LoginOutTime int64 `gorm:"column:loginouttime;comment:登出时间" json:"loginouttime"`
PlayTimes int64 `gorm:"column:playtimes;comment:游玩时长" json:"playtimes"` PlayTimes int64 `gorm:"column:playtimes;comment:游玩时长" json:"playtimes"`
//用于统计当日的总上线人数 0=否1=是
IsFirstLogin int32 `gorm:"column:isfirstlogin;comment:是否首次登录" json:"isfirstlogin"`
} }
// 看广告相关记录 // 看广告相关记录
// 记录日期便于按天统计 // 记录日期便于按天统计
type RecordWatchADOfWxUser struct { type RecordWatchADOfWxUser struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"` ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
RecordDate time.Time `gorm:"column:recorddate;type:date;comment:记录日期" json:"recorddate"` RecordDate int64 `gorm:"column:recorddate;comment:记录日期" json:"recorddate"` //只记录当天0点的时间戳方便查询某一日的数据
Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"` Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"`
WatchADNum int32 `gorm:"column:watchadnum;comment:看广告次数" json:"watchadnum"` SeverId int32 `gorm:"column:severId;comment:区服Id" json:"severId"`
WatchADNum int32 `gorm:"column:watchadnum;comment:看广告次数" json:"watchadnum"`
}
// 历史平均看广告次数的记录
// 再次查询的时候就不用计算了
type RecordAverageWatchADNum struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
RecordDate int64 `gorm:"column:recorddate;comment:记录日期" json:"recorddate"` //只记录当天0点的时间戳方便查询某一日的数据
SeverId int32 `gorm:"column:severid;comment:区服ID" json:"severid"`
AverageWatchADNum float32 `gorm:"column:averageplaytimes;comment:平均看广告次数" json:"averageplaytimes"`
PlayerNum int64 `gorm:"column:playernum;comment:当日看广告人数人数" json:"playernum"`
}
// 历史平均在线时长的记录
// 再次查询的时候就不用计算了
type RecordAveragePlayTimes struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
RecordDate int64 `gorm:"column:recorddate;comment:记录日期" json:"recorddate"` //只记录当天0点的时间戳方便查询某一日的数据
SeverId int32 `gorm:"column:severid;comment:区服ID" json:"severid"`
AveragePlayTimes int64 `gorm:"column:averageplaytimes;comment:平均在线时长" json:"averageplaytimes"`
PlayerNum int64 `gorm:"column:playernum;comment:当日上线人数" json:"playernum"`
}
// 记录当前为止的开服数
type WxUserSeverList struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
SeverId int32 `gorm:"column:severId;comment:区服Id" json:"severId"`
} }
func (Admin) TableName() string { func (Admin) TableName() string {
return "admin" return "admin"
} }
func (RecordLoginOfWxUser) TableName() string { func (RecordAveragePlayTimes) TableName() string {
return "recordloginofwxuser" return "recordaverageplaytimes"
}
func (RecordAverageWatchADNum) TableName() string {
return "recordaveragewatchadnum"
}
func (WxUserSeverList) TableName() string {
return "wxuserseverlist"
} }
func (RecordWatchADOfWxUser) TableName() string { func (RecordWatchADOfWxUser) TableName() string {
return "recordwatchadofwxuser" return "recordwatchadofwxuser"
} }
func (RecordLoginOfWxUser) TableName() string {
return "recordloginofwxuser"
}

View File

@ -203,55 +203,213 @@ func (a *AdminApi) Login(account string, password string) (responseObj *webServe
return return
} }
// 查询玩家登录相关记录 // 获取某一天玩家的平均在线时长
func init() { func init() {
moduleName := "AdminApi" moduleName := "AdminApi"
methodName := "QueryloginRecord" methodName := "GetAveragePlaytimes"
skipVerifyTokenPage := true skipVerifyTokenPage := true
methodDesc := "查询玩家登录相关记录" methodDesc := "获取某一天玩家的平均在线时长"
methodAuthor := "youjinlan" methodAuthor := "youjinlan"
methodMendor := "" methodMendor := ""
methodDate := "2025-01-21 16:00:00" methodDate := "2025-01-21 16:00:00"
methodInParam := []string{"int64:uid"} methodInParam := []string{"int64 startTime, int64 endTime"}
methodOutParam := ` methodOutParam := `
{ {
"Code '类型:int'": "响应结果的状态值", "Code '类型:int'": "响应结果的状态值",
"Message '类型:string'": "响应结果的状态值所对应的描述信息", "Message '类型:string'": "响应结果的状态值所对应的描述信息",
"Data '类型:interface{}'": "响应结果的数据" "Data '类型:interface{}'": "响应结果的数据"
{ {
"FirstLoginTime '类型:int64'": "首次登录时间", "AveragePlaytimesForEachSever '类型:map[int32]map[int64]int64'": "各个服在该时间段内的各天平均在线时长",
"PlayDayNum '类型:int32'": "生命周期",
"PlayTimes '类型:int64'": "在线时长",
} }
}` }`
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam, skipVerifyTokenPage) remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam, skipVerifyTokenPage)
} }
func (a *AdminApi) QueryloginRecord(uid int64) (responseObj *webServer.ResponseObject) { func (a *AdminApi) GetAveragePlaytimes(startTime, endTime int64) (responseObj *webServer.ResponseObject) {
responseObj = webServer.GetInitResponseObj() responseObj = webServer.GetInitResponseObj()
//验证参数 //验证参数
nowTime := time.Now().Unix()
nowZero := mytime.ZeroTime(nowTime, 0)
if startTime == 0 || endTime == 0 {
responseObj.SetResultStatus(resultStatus.APIDataError)
return
}
if startTime > nowTime {
responseObj.SetResultStatus(resultStatus.APIDataError)
return
}
startZero := mytime.ZeroTime(startTime, 0)
endZero := mytime.ZeroTime(endTime, 0)
if endZero > nowZero {
endZero = nowZero
}
GetAveragePlaytimes()
totalMap := make(map[int32]map[int64]int64)
userSeverList, _ := GetUserSeverList()
date := startZero
for _, severlist := range userSeverList {
dateMap := make(map[int64]int64)
for {
var averagePlaytimes int64
if date != mytime.ZeroTime(nowTime, 0) {
averagePlaytimes, _, _ = GetRecordAveragePlayTimes(date, severlist.SeverId)
if averagePlaytimes == 0 {
playtimes := GetUserTotalPlayTimes(date, severlist.SeverId)
count := GetUserTotalPlayerNum(date, severlist.SeverId)
if playtimes == 0 || count == 0 {
averagePlaytimes = 0
} else {
averagePlaytimes = playtimes / count
}
//把今日之前的数据添加到数据库,因为数据不会再变化了,下次查询就不用计算了
recordAveragePlayTimes := &RecordAveragePlayTimes{}
recordAveragePlayTimes.AveragePlayTimes = averagePlaytimes
recordAveragePlayTimes.PlayerNum = count
recordAveragePlayTimes.SeverId = severlist.SeverId
recordAveragePlayTimes.RecordDate = date
AddRecordAveragePlayTimes(recordAveragePlayTimes)
}
} else {
playtimes := GetUserTotalPlayTimes(date, severlist.SeverId)
count := GetUserTotalPlayerNum(date, severlist.SeverId)
if playtimes == 0 || count == 0 {
averagePlaytimes = 0
} else {
averagePlaytimes = playtimes / count
}
}
dateMap[date] = averagePlaytimes
if date+86400 > endZero {
date = startZero
break
}
date = date + 86400
}
totalMap[severlist.SeverId] = dateMap
}
resultMap := make(map[string]any)
resultMap["AveragePlaytimesForEachSever"] = totalMap
responseObj.SetData(resultMap)
return
}
// 获取某一天玩家的平均看广告次数
func init() {
moduleName := "AdminApi"
methodName := "GetAverageWatchADNum"
skipVerifyTokenPage := true
methodDesc := "获取某一天玩家的平均看广告次数"
methodAuthor := "youjinlan"
methodMendor := ""
methodDate := "2025-01-24 15:00:00"
methodInParam := []string{"int64 startTime, int64 endTime"}
methodOutParam := `
{
"Code '类型:int'": "响应结果的状态值",
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
"Data '类型:interface{}'": "响应结果的数据"
{
"AverageWatchADNumForEachSever '类型:map[int32]map[int64]int32'": "各个服在该时间段内的各天平均看广告次数",
}
}`
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam, skipVerifyTokenPage)
}
func (a *AdminApi) GetAverageWatchADNum(startTime, endTime int64) (responseObj *webServer.ResponseObject) {
responseObj = webServer.GetInitResponseObj()
//验证参数
nowTime := time.Now().Unix()
nowZero := mytime.ZeroTime(nowTime, 0)
if startTime == 0 || endTime == 0 {
responseObj.SetResultStatus(resultStatus.APIDataError)
return
}
if startTime > nowTime {
responseObj.SetResultStatus(resultStatus.APIDataError)
return
}
startZero := mytime.ZeroTime(startTime, 0)
endZero := mytime.ZeroTime(endTime, 0)
if endZero > nowZero {
endZero = nowZero
}
GetAveragePlaytimes()
totalMap := make(map[int32]map[int64]float32)
userSeverList, _ := GetUserSeverList()
date := startZero
for _, severlist := range userSeverList {
dateMap := make(map[int64]float32)
for {
if date != mytime.ZeroTime(nowTime, 0) {
avgWatchADNum, _, _ := GetRecordAverageWatchADNum(date, severlist.SeverId)
if avgWatchADNum == 0 {
avgWatchADNum = GetUserAvgWatchADNum(date, severlist.SeverId)
count := GetUserWatchADPlayerNum(date, severlist.SeverId)
//把今日之前的数据添加到数据库,因为数据不会再变化了,下次查询就不用计算了
recordAverageWatchADNum := &RecordAverageWatchADNum{}
recordAverageWatchADNum.AverageWatchADNum = avgWatchADNum
recordAverageWatchADNum.PlayerNum = count
recordAverageWatchADNum.SeverId = severlist.SeverId
recordAverageWatchADNum.RecordDate = date
AddRecordAverageWatchADNum(recordAverageWatchADNum)
}
} else {
avgWatchADNum := GetUserAvgWatchADNum(date, severlist.SeverId)
dateMap[date] = avgWatchADNum
if date+86400 > endZero {
date = startZero
break
}
date = date + 86400
}
}
totalMap[severlist.SeverId] = dateMap
}
resultMap := make(map[string]any)
resultMap["AverageWatchADNumForEachSever"] = totalMap
responseObj.SetData(resultMap)
return
}
// 获取某个玩家的生命周期
func init() {
moduleName := "AdminApi"
methodName := "GetPlayerLiveNum"
skipVerifyTokenPage := true
methodDesc := "获取某个玩家的生命周期"
methodAuthor := "youjinlan"
methodMendor := ""
methodDate := "2025-01-24 17:00:00"
methodInParam := []string{"int64 uid"}
methodOutParam := `
{
"Code '类型:int'": "响应结果的状态值",
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
"Data '类型:interface{}'": "响应结果的数据"
{
"LiveNum '类型:int32'": "玩家的生命周期(玩了多少天)",
}
}`
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam, skipVerifyTokenPage)
}
func (a *AdminApi) GetPlayerLiveNum(uid int64) (responseObj *webServer.ResponseObject) {
responseObj = webServer.GetInitResponseObj()
if uid == 0 { if uid == 0 {
responseObj.SetResultStatus(resultStatus.APIDataError) responseObj.SetResultStatus(resultStatus.APIDataError)
return return
} }
var userfirstRecord *RecordLoginOfWxUser var userRecord *RecordLoginOfWxUser
if userfirstRecord, _ = GetUserFirstRecord(uid); userfirstRecord == nil { if userRecord, _ = GetUserFirstRecord(uid); userRecord == nil {
responseObj.SetResultStatus(resultStatus.PlayerNotExist) responseObj.SetResultStatus(resultStatus.PlayerNotExist)
return return
} }
userLastRecord, _ := GetUserLastRecord(uid) firstDate := userRecord.RecordDate
firstLoginInTime := userfirstRecord.LoginInTime userRecord, _ = GetUserLastRecord(uid)
var lastLoginOutTime int64 lastDate := userRecord.RecordDate
if userLastRecord.LoginOutTime == 0 {
lastLoginOutTime = userLastRecord.LoginInTime
}
lastLoginOutTime = userLastRecord.LoginOutTime
playDayNum := mytime.DiffDays(lastLoginOutTime, firstLoginInTime)
resultMap := make(map[string]any) resultMap := make(map[string]any)
resultMap["FirstLoginTime"] = firstLoginInTime liveNum := mytime.DiffDays(lastDate, firstDate)
resultMap["PlayDayNum"] = playDayNum resultMap["LiveNum"] = liveNum
resultMap["PlayTimes"] = GetUserTotalPlayTime(uid)
responseObj.SetData(resultMap) responseObj.SetData(resultMap)
return return
} }

View File

@ -62,8 +62,82 @@ func GetUserLastRecord(uid int64) (*RecordLoginOfWxUser, error) {
return userRecord, nil return userRecord, nil
} }
func GetUserTotalPlayTime(uid int64) int64 { // 计算某日某服的玩家在线总时长
func GetUserTotalPlayTimes(date int64, severId int32) int64 {
var totalPlayTime int64 var totalPlayTime int64
connection.GetUserDB().Table("recordloginofwxuser").Where("uid = ?", uid).Select("SUM(playtimes)").Scan(&totalPlayTime) connection.GetUserDB().Table("recordloginofwxuser").Where("recorddate = ? AND severid = ?", date, severId).Select("SUM(playtimes)").Scan(&totalPlayTime)
return totalPlayTime return totalPlayTime
} }
// 计算某日某服的玩家上线总人数
func GetUserTotalPlayerNum(date int64, severId int32) int64 {
var count int64
connection.GetUserDB().Table("recordloginofwxuser").Where("recorddate = ? AND severid = ? AND isfirstlogin = ?", date, severId, 1).Count(&count)
return count
}
// 获取区服列表
func GetUserSeverList() ([]*WxUserSeverList, error) {
var userSeverList []*WxUserSeverList
result := connection.GetUserDB().Find(&userSeverList)
if result.Error != nil {
logUtilPlus.ErrorLog("查询用户区服列表失败 错误信息:%s", result.Error.Error())
return nil, result.Error
}
return userSeverList, nil
}
// 添加玩家的平均在线时长数据到数据库
func AddRecordAveragePlayTimes(recordAveragePlayTimes *RecordAveragePlayTimes) (int64, error) {
connection.CheckTableExists(connection.GetAdminDB(), &RecordAveragePlayTimes{})
result := connection.GetAdminDB().Create(&recordAveragePlayTimes) // 通过数据的指针来创建
if result.Error != nil {
logUtilPlus.ErrorLog("添加平均在线时长记录失败 错误信息:%s", result.Error)
}
return recordAveragePlayTimes.ID, nil
}
// 获取某日某服的玩家平均在线时长记录和总上线人数
func GetRecordAveragePlayTimes(date int64, severId int32) (int64, int64, error) {
var recordAveragePlayTimes *RecordAveragePlayTimes
result := connection.GetAdminDB().Where("recorddate = ? AND severid = ?", date, severId).First(&recordAveragePlayTimes)
if result.Error != nil {
logUtilPlus.ErrorLog("查询平均在线时长记录失败 错误信息:%s", result.Error)
return 0, 0, result.Error
}
return recordAveragePlayTimes.AveragePlayTimes, recordAveragePlayTimes.PlayerNum, nil
}
// 计算某日某服的玩家平均看广告次数
func GetUserAvgWatchADNum(date int64, severId int32) float32 {
var avgWatchADNum float32
connection.GetUserDB().Table("recordwatchadofwxuser").Where("recorddate = ? AND severid = ?", date, severId).Select("AVG(watchadnum)").Scan(&avgWatchADNum)
return avgWatchADNum
}
// 计算某日某服玩家的看广告总人数
func GetUserWatchADPlayerNum(date int64, severId int32) int64 {
var count int64
connection.GetUserDB().Table("recordwatchadofwxuser").Where("recorddate = ? AND severid = ?", date, severId).Count(&count)
return count
}
// 添加玩家的平均看广告次数到数据库
func AddRecordAverageWatchADNum(recordAverageWatchADNum *RecordAverageWatchADNum) (int64, error) {
result := connection.GetAdminDB().Create(&recordAverageWatchADNum) // 通过数据的指针来创建
if result.Error != nil {
logUtilPlus.ErrorLog("添加平均看广告次数记录失败 错误信息:%s", result.Error)
}
return recordAverageWatchADNum.ID, nil
}
// 获取某日某服玩家的平均看广告次数和总人数
func GetRecordAverageWatchADNum(date int64, severId int32) (float32, int64, error) {
var recordAverageWatchADNum *RecordAverageWatchADNum
result := connection.GetAdminDB().Where("recorddate = ? AND severid = ?", date, severId).First(&recordAverageWatchADNum)
if result.Error != nil {
logUtilPlus.ErrorLog("查询平均看广告次数记录失败 错误信息:%s", result.Error)
return 0, 0, result.Error
}
return recordAverageWatchADNum.AverageWatchADNum, recordAverageWatchADNum.PlayerNum, nil
}

View File

@ -5,7 +5,6 @@ import (
"sync" "sync"
_ "admincenter/internal/admin" _ "admincenter/internal/admin"
_ "common/resultStatus"
"common/webServer" "common/webServer"
) )
@ -37,7 +36,6 @@ func loadConfig() {
//设置数据类型 //设置数据类型
connection.SetModelDB(connection.GetAdminDB()) connection.SetModelDB(connection.GetAdminDB())
connection.SetModelDB(connection.GetUserDB())
//构建数据库 //构建数据库
connection.BuildDB() connection.BuildDB()

View File

@ -17,6 +17,14 @@ var (
modelDB *gorm.DB modelDB *gorm.DB
) )
func init() {
// 启动异步处理
go ExecuteCreateChan()
go ExecuteSaveChan()
go ExecuteDeleteChan()
}
// RegisterDBModel 注册数据库模型到全局变量dbModelMap中。 // RegisterDBModel 注册数据库模型到全局变量dbModelMap中。
// 这个函数接受一个interface{}类型的参数dbModel表示数据库模型。 // 这个函数接受一个interface{}类型的参数dbModel表示数据库模型。
// 函数的目的是将传入的数据库模型添加到全局变量dbModelMap中 // 函数的目的是将传入的数据库模型添加到全局变量dbModelMap中
@ -27,7 +35,7 @@ func RegisterDBModel(dbModel interface{}) {
dbModelMap = append(dbModelMap, &dbModel) dbModelMap = append(dbModelMap, &dbModel)
} }
// 设置modelDB 类型 // SetModelDB 设置modelDB 类型
func SetModelDB(db *gorm.DB) { func SetModelDB(db *gorm.DB) {
modelDB = db modelDB = db
} }
@ -138,38 +146,120 @@ func Save(db *gorm.DB, value interface{}, dbIndex int32) *gorm.DB {
return result return result
} }
// DBData 添加数据通道
type DBData struct {
DB *gorm.DB
Value any
}
var (
// 添加数据通道
createChan = make(chan DBData)
// 保存数据通道
saveChan = make(chan DBData)
// 删除数据通道
deleteChan = make(chan DBData)
)
// AsyncCreate 异步创建数据 // AsyncCreate 异步创建数据
func AsyncCreate(db *gorm.DB, value interface{}) { func AsyncCreate(db *gorm.DB, value interface{}) {
go func() { createChan <- DBData{
DB: db,
Value: value,
}
}
//检查表是否存在 // ExecuteCreateChan 执行添加数据通道
CheckTableExists(db, value) func ExecuteCreateChan() {
result := db.Create(value) defer func() {
if result.Error != nil { if err := recover(); err != nil {
logUtilPlus.ErrorLog("AsyncCreate is err: %v", result.Error) logUtilPlus.ErrorLog("AsyncCreate is err: %v", err)
//停止程序
panic(err)
} }
}() }()
for {
select {
case createData := <-createChan:
db := createData.DB
value := createData.Value
//检查表是否存在
CheckTableExists(db, value)
result := db.Create(value)
if result.Error != nil {
logUtilPlus.ErrorLog("AsyncCreate is err: %v", result.Error)
}
}
}
} }
// AsyncSave 异步保存数据 // AsyncSave 异步保存数据
func AsyncSave(db *gorm.DB, value interface{}) { func AsyncSave(db *gorm.DB, value interface{}) {
go func() { saveChan <- DBData{
result := db.Save(value) DB: db,
if result.Error != nil { Value: value,
logUtilPlus.ErrorLog("AsyncSave is err : %v", result.Error) }
}
// ExecuteSaveChan 执行保存数据通道
func ExecuteSaveChan() {
defer func() {
if err := recover(); err != nil {
logUtilPlus.ErrorLog("AsyncSave is err: %v", err)
panic(err)
} }
}() }()
for {
select {
case saveData := <-saveChan:
db := saveData.DB
value := saveData.Value
result := db.Save(value)
if result.Error != nil {
logUtilPlus.ErrorLog("AsyncSave is err : %v", result.Error)
}
}
}
} }
// AsyncDelete 异步删除数据 // AsyncDelete 异步删除数据
func AsyncDelete(db *gorm.DB, value interface{}) { func AsyncDelete(db *gorm.DB, value interface{}) {
go func() { deleteChan <- DBData{
result := db.Delete(value) DB: db,
if result.Error != nil { Value: value,
logUtilPlus.ErrorLog("AsyncDelete is err : %v", result.Error) }
}
// ExecuteDeleteChan 执行删除数据通道
func ExecuteDeleteChan() {
defer func() {
if err := recover(); err != nil {
logUtilPlus.ErrorLog("AsyncDelete is err: %v", err)
panic(err)
} }
}() }()
for {
select {
case deleteData := <-deleteChan:
db := deleteData.DB
value := deleteData.Value
result := db.Delete(value)
if result.Error != nil {
logUtilPlus.ErrorLog("AsyncDelete is err : %v", result.Error)
}
}
}
} }

View File

@ -3,7 +3,7 @@ package httpServer
import ( import (
"net/http" "net/http"
"common/resultStatus" "common/resultstatus"
"common/webServer" "common/webServer"
) )

View File

@ -2,7 +2,7 @@ package httpServer
import ( import (
config "common/configsYaml" config "common/configsYaml"
"common/resultStatus" "common/resultstatus"
"common/webServer" "common/webServer"
"goutil/logUtilPlus" "goutil/logUtilPlus"
"reflect" "reflect"

View File

@ -2,7 +2,7 @@ package httpServer
import ( import (
config "common/configsYaml" config "common/configsYaml"
"common/resultStatus" "common/resultstatus"
"common/utils" "common/utils"
"common/webServer" "common/webServer"
"encoding/json" "encoding/json"

View File

@ -5,16 +5,7 @@ import (
"time" "time"
) )
/*func GetZeroTime(t int64, timezone int) int64 { // 计算两个时间戳之间间隔多少天
return t - (t+int64(timezone))%86400
}
func IsDiffDay(second, first int64, timezone int) int {
secondZeroTime := GetZeroTime(second, timezone)
firstZeroTime := GetZeroTime(first, timezone)
return int(secondZeroTime/86400 - firstZeroTime/86400)
}*/
func DiffDays(new, old int64) int64 { func DiffDays(new, old int64) int64 {
newZeroTime := ZeroTime(new, 0) newZeroTime := ZeroTime(new, 0)
oldZeroTime := ZeroTime(old, 0) oldZeroTime := ZeroTime(old, 0)
@ -27,3 +18,9 @@ func ZeroTime(sec, nsec int64) int64 {
t, _ := time.ParseInLocation("2006-01-02", dateStr, time.Local) t, _ := time.ParseInLocation("2006-01-02", dateStr, time.Local)
return t.Unix() return t.Unix()
} }
func IsSameDay(first, second int64) bool {
firstZero := ZeroTime(first, 0)
secondZero := ZeroTime(second, 0)
return firstZero == secondZero
}

View File

@ -93,6 +93,8 @@ var (
// 玩家不存在 // 玩家不存在
PlayerNotExist = NewResultStatus(-1110, "PlayerNotExist") PlayerNotExist = NewResultStatus(-1110, "PlayerNotExist")
// 玩家uid和服务器id不匹配
PlayerNotMatchSever = NewResultStatus(-1111, "PlayerNotMatchSever")
// 没有合适的玩家 // 没有合适的玩家
NotSuitablePlayer = NewResultStatus(-1155, "NotSuitablePlayer") NotSuitablePlayer = NewResultStatus(-1155, "NotSuitablePlayer")

View File

@ -0,0 +1,159 @@
package timer
import (
"goutil/logUtilPlus"
"time"
)
// 触发类型
const (
// TriggerTypeMinute 一分钟
TriggerTypeMinute = iota + 1
// TriggerTypeFiveMinute 五分钟
TriggerTypeFiveMinute
// TriggerTypeTenMinute 十分钟
TriggerTypeTenMinute
// TriggerTypeHalfHour 半小时
TriggerTypeHalfHour
// TriggerTypeHour 一小时
TriggerTypeHour
// TriggerTypeEightHour 八小时
TriggerTypeEightHour
// TriggerTypeDay 一天 每天0点触发
TriggerTypeDay
// TriggerTypeWeek 一周 周日0点触发
TriggerTypeWeek
// TriggerTypeMonth 每月1号0点触发
TriggerTypeMonth
)
// TimerHandlerFunc 定义可执行的函数类型
type timerHandlerFunc func(nowTime time.Time) error
// 时间触发管理
var (
timerHandlerMap = make(map[int][]timerHandlerFunc)
timerTypeMap = map[int]struct{}{
TriggerTypeMinute: {},
TriggerTypeFiveMinute: {},
TriggerTypeTenMinute: {},
TriggerTypeHalfHour: {},
TriggerTypeHour: {},
TriggerTypeEightHour: {},
TriggerTypeDay: {},
TriggerTypeWeek: {},
TriggerTypeMonth: {},
}
)
// Register 注册时间触发器
// @param timerType 时间触发类型
// @param timerFunc 时间触发函数
func Register(timerType int, timerFunc timerHandlerFunc) {
// 检查timerType是否在常量中
if _, ok := timerTypeMap[timerType]; !ok {
logUtilPlus.ErrorLog("注册时间触发器失败,类型不存在", "timerType", timerType)
return
}
if _, ok := timerHandlerMap[timerType]; !ok {
timerHandlerMap[timerType] = make([]timerHandlerFunc, 0)
}
timerHandlerMap[timerType] = append(timerHandlerMap[timerType], timerFunc)
}
// Execute 执行时间触发器
// @param timerType 时间触发类型
// @param nowTime 当前时间
func Execute(timerType int, nowTime time.Time) {
if _, ok := timerHandlerMap[timerType]; !ok {
return
}
for _, timerHandlerFunc := range timerHandlerMap[timerType] {
if err := timerHandlerFunc(nowTime); err != nil {
logUtilPlus.ErrorLog("执行时间触发器失败", "timerType", timerType, "err", err)
}
}
}
// 初始化init
func init() {
go timerHandler()
}
// 定时触发函数
func timerHandler() {
// 每一分钟执行一次
ticker := time.NewTicker(time.Minute)
defer ticker.Stop()
defer func() {
if err := recover(); err != nil {
logUtilPlus.ErrorLog("定时触发函数异常", "err", err)
restartTimerHandler()
}
}()
for {
select {
case nowTime := <-ticker.C:
go func() {
// 触发minute
Execute(TriggerTypeMinute, nowTime)
// 触发fiveMinute
if nowTime.Minute()%5 == 0 {
Execute(TriggerTypeFiveMinute, nowTime)
}
// 触发tenMinute
if nowTime.Minute()%10 == 0 {
Execute(TriggerTypeTenMinute, nowTime)
}
// 触发halfHour
if nowTime.Minute()%30 == 0 {
Execute(TriggerTypeHalfHour, nowTime)
}
// 触发hour
if nowTime.Minute() == 0 {
Execute(TriggerTypeHour, nowTime)
}
// 触发eightHour
if nowTime.Hour()%8 == 0 {
Execute(TriggerTypeEightHour, nowTime)
}
// 触发day 0点触发
if nowTime.Hour() == 0 && nowTime.Minute() == 0 {
Execute(TriggerTypeDay, nowTime)
}
// 触发week 周日0点触发
if nowTime.Weekday() == time.Sunday && nowTime.Hour() == 0 && nowTime.Minute() == 0 {
Execute(TriggerTypeWeek, nowTime)
}
// 触发month 1号0点触发
if nowTime.Day() == 1 && nowTime.Hour() == 0 && nowTime.Minute() == 0 {
Execute(TriggerTypeMonth, nowTime)
}
}()
}
}
}
// restartTimerHandler 重启定时器
func restartTimerHandler() {
// 设置重试次数
maxRetries := 5
retryCount := 0
for {
select {
case <-time.After(5 * time.Minute): // 等待5分钟后重试
if retryCount >= maxRetries {
logUtilPlus.ErrorLog("定时器重启失败,达到最大重试次数")
return
}
logUtilPlus.InfoLog("重新启动定时器,重试次数: %d", retryCount+1)
go timerHandler()
return
}
retryCount++
}
}

View File

@ -3,7 +3,7 @@ package webServer
import ( import (
"net/http" "net/http"
"common/resultStatus" "common/resultstatus"
) )
// 处理函数 // 处理函数

View File

@ -2,7 +2,7 @@ package webServer
import ( import (
config "common/configsYaml" config "common/configsYaml"
"common/resultStatus" "common/resultstatus"
"goutil/logUtilPlus" "goutil/logUtilPlus"
"reflect" "reflect"
"strconv" "strconv"

View File

@ -1,7 +1,7 @@
package webServer package webServer
import ( import (
"common/resultStatus" "common/resultstatus"
) )
// ResponseObject // ResponseObject

View File

@ -2,7 +2,7 @@ package webServer
import ( import (
config "common/configsYaml" config "common/configsYaml"
"common/resultStatus" "common/resultstatus"
"common/utils" "common/utils"
"encoding/json" "encoding/json"
"fmt" "fmt"

View File

@ -10,6 +10,7 @@ replace (
require ( require (
common v0.0.0-00010101000000-000000000000 common v0.0.0-00010101000000-000000000000
github.com/go-pay/gopay v1.5.108
github.com/wechatpay-apiv3/wechatpay-go v0.2.20 github.com/wechatpay-apiv3/wechatpay-go v0.2.20
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
goutil v0.0.0-20230425160006-b2d0b0a0b0b0 goutil v0.0.0-20230425160006-b2d0b0a0b0b0
@ -22,7 +23,9 @@ require (
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // 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/elastic/go-elasticsearch/v8 v8.0.0-20210916085751-c2fb55d91ba4 // indirect
github.com/fatih/color v1.15.0 // indirect github.com/fatih/color v1.15.0 // indirect
github.com/go-pay/gopay v1.5.108 // indirect github.com/go-pay/crypto v0.0.1 // indirect
github.com/go-pay/util v0.0.4 // indirect
github.com/go-pay/xlog v0.0.3 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/gomodule/redigo v1.8.9 // indirect github.com/gomodule/redigo v1.8.9 // indirect
@ -32,6 +35,7 @@ require (
github.com/jinzhu/now v1.1.5 // indirect github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
github.com/streadway/amqp v1.1.0 // indirect
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect
golang.org/x/sys v0.6.0 // indirect golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.21.0 // indirect

View File

@ -19,8 +19,14 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= 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 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-pay/crypto v0.0.1 h1:B6InT8CLfSLc6nGRVx9VMJRBBazFMjr293+jl0lLXUY=
github.com/go-pay/crypto v0.0.1/go.mod h1:41oEIvHMKbNcYlWUlRWtsnC6+ASgh7u29z0gJXe5bes=
github.com/go-pay/gopay v1.5.108 h1:hMhDfucGz+q/XLlz7uZ2LLLg2oJmahpcCUhi5ifEd/0= github.com/go-pay/gopay v1.5.108 h1:hMhDfucGz+q/XLlz7uZ2LLLg2oJmahpcCUhi5ifEd/0=
github.com/go-pay/gopay v1.5.108/go.mod h1:O41QrjYtfGfxyzDVJVrRDHG63cIqfZuv55Eo0NaGnWw= github.com/go-pay/gopay v1.5.108/go.mod h1:O41QrjYtfGfxyzDVJVrRDHG63cIqfZuv55Eo0NaGnWw=
github.com/go-pay/util v0.0.4 h1:TuwSU9o3Qd7m9v1PbzFuIA/8uO9FJnA6P7neG/NwPyk=
github.com/go-pay/util v0.0.4/go.mod h1:Tsdhs8Ib9J9b4+NKNO1PHh5hWHhlg98PthsX0ckq6PM=
github.com/go-pay/xlog v0.0.3 h1:avyMhCL/JgBHreoGx/am/kHxfs1udDOAeVqbmzP/Yes=
github.com/go-pay/xlog v0.0.3/go.mod h1:mH47xbobrdsSHWsmFtSF5agWbMHFP+tK0ZbVCk5OAEw=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= 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-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.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@ -58,6 +64,8 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM=
github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -70,8 +78,9 @@ github.com/wechatpay-apiv3/wechatpay-go v0.2.20 h1:gS8oFn1bHGnyapR2Zb4aqTV6l4kJW
github.com/wechatpay-apiv3/wechatpay-go v0.2.20/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q= github.com/wechatpay-apiv3/wechatpay-go v0.2.20/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/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/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-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 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=

View File

@ -0,0 +1,88 @@
package alipay
import (
"context"
"errors"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/alipay/v3"
"github.com/go-pay/gopay/pkg/js"
"goutil/logUtilPlus"
"paycenter/internal/cert"
"strconv"
)
var (
ctx = context.Background()
client *alipay.ClientV3
err error
)
func init() {
// 初始化支付宝客V3户端
// appid应用ID
// privateKey应用私钥支持PKCS1和PKCS8
// isProd是否是正式环境沙箱环境请选择新版沙箱应用。
client, err = alipay.NewClientV3(cert.Appid, cert.PrivateKey, false)
if err != nil {
logUtilPlus.ErrorLog("new alipay client err:%s", err)
return
}
// 自定义配置http请求接收返回结果body大小默认 10MB
//client.SetBodySize() // 没有特殊需求,可忽略此配置
// Debug开关输出/关闭日志
client.DebugSwitch = gopay.DebugOn
// 设置自定义RequestId生成方法
//client.SetRequestIdFunc()
// 设置biz_content加密KEY设置此参数默认开启加密目前不可用
//client.SetAESKey("KvKUTqSVZX2fUgmxnFyMaQ==")
// 传入证书内容
err = client.SetCert(cert.AppPublicContent, cert.AlipayRootContent, cert.AlipayPublicContentRSA2)
if err != nil {
logUtilPlus.ErrorLog("set cert err:%s", err)
return
}
}
// AliPayPlace 函数用于发起预支付请求。
// 参数:
//
// outTradeNo: 商户订单号。
// currency: 订单金额,单位为分。
// storeId: 商户门店编号。
// clientIp: 用户的客户端IP。
// description: 订单描述。
//
// 返回值:
//
// 成功时返回预支付ID和nil错误。
// 失败时返回空字符串和错误对象。
func AliPayPlace(outTradeNo int64, currency int64, storeId string, clientIp string, description string) (string, error) {
// 请求参数
bm := make(gopay.BodyMap)
bm.Set("subject", "预创建创建订单").
Set("out_trade_no", strconv.FormatInt(outTradeNo, 10)).
Set("total_amount", currency)
rsp := new(struct {
OutTradeNo string `json:"out_trade_no"`
QrCode string `json:"qr_code"`
})
// 创建订单
res, err := client.DoAliPayAPISelfV3(ctx, alipay.MethodPost, alipay.V3TradePrecreate, bm, rsp)
if err != nil {
logUtilPlus.ErrorLog("client.TradePrecreate(), err:%v", err)
return "", err
}
logUtilPlus.DebugLog("aliRsp:%s", js.Marshal(rsp))
if res.StatusCode != alipay.Success {
logUtilPlus.ErrorLog("aliRsp.StatusCode:%d", res.StatusCode)
return "", errors.New("aliRsp.StatusCode:" + strconv.Itoa(res.StatusCode))
}
return "Success", nil
}

View File

@ -0,0 +1,9 @@
package internal
import (
_ "paycenter/internal/alipay"
_ "paycenter/internal/cert"
_ "paycenter/internal/mesqueue"
_ "paycenter/internal/pay"
_ "paycenter/internal/wxpay"
)

View File

@ -34,13 +34,13 @@ type GameMsg struct {
var ( var (
//消息队列 //消息队列
msgQueue chan GameMsg = make(chan GameMsg, 100) msgQueue = make(chan GameMsg, 100)
fileName = "ErrPushMsg" fileName = "ErrPushMsg"
) )
func init() { func init() {
ConsumeQueue() go ConsumeQueue()
} }
// AddQueue 添加消息队列 // AddQueue 添加消息队列
@ -50,42 +50,40 @@ func AddQueue(gameMsg GameMsg) {
// ConsumeQueue 消费消息队列 // ConsumeQueue 消费消息队列
func ConsumeQueue() { func ConsumeQueue() {
go func() { //捕获异常
//捕获异常 defer func() {
defer func() { if err := recover(); err != nil {
if err := recover(); err != nil { //TODO 捕获异常
//TODO 捕获异常 logUtilPlus.ErrorLog("推送充值信息到game异常 err:%s", err)
logUtilPlus.ErrorLog("推送充值信息到game异常 err:%s", err)
//重新开启 //重新开启
restartConsumer() restartConsumer()
}
}()
for {
gameMsg := <-msgQueue
url := fmt.Sprintf("http://www.game.com/pay %s", gameMsg.GameId)
//消费消息队列 推送重置信息到game
result, err := webUtil.GetWebData(url, map[string]string{})
if err != nil {
logUtilPlus.ErrorLog("推送充值信息到game异常 err:%s", err)
//放入消息队列重新推送
if gameMsg.pushCount < 3 {
msgQueue <- gameMsg
gameMsg.pushCount++
} else { //加入文件放弃推送
WriteErrPushMsg(url)
}
}
if string(result) != "" {
}
} }
}() }()
for {
gameMsg := <-msgQueue
url := fmt.Sprintf("http://www.game.com/pay %s", gameMsg.GameId)
//消费消息队列 推送重置信息到game
result, err := webUtil.GetWebData(url, map[string]string{})
if err != nil {
logUtilPlus.ErrorLog("推送充值信息到game异常 err:%s", err)
//放入消息队列重新推送
if gameMsg.pushCount < 3 {
msgQueue <- gameMsg
gameMsg.pushCount++
} else { //加入文件放弃推送
WriteErrPushMsg(url)
}
}
if string(result) != "" {
}
}
} }
// WriteErrPushMsg 推送异常消息 写入文件 // WriteErrPushMsg 推送异常消息 写入文件
@ -117,7 +115,7 @@ func restartConsumer() {
return return
} }
logUtilPlus.InfoLog("重新启动消费者,重试次数: %d", retryCount+1) logUtilPlus.InfoLog("重新启动消费者,重试次数: %d", retryCount+1)
ConsumeQueue() go ConsumeQueue()
return return
} }
retryCount++ retryCount++

View File

@ -2,12 +2,13 @@ package pay
import ( import (
"common/remark" "common/remark"
"common/resultStatus" "common/resultstatus"
"common/webServer" "common/webServer"
"goutil/logUtilPlus" "goutil/logUtilPlus"
"goutil/webUtil" "goutil/webUtil"
"net/http" "net/http"
"paycenter/internal" "paycenter/internal/alipay"
"paycenter/internal/wxpay"
"strconv" "strconv"
) )
@ -74,7 +75,7 @@ func (a *PayApi) PlaceAnOrder(orderId int64, modelID int32, currency int64, stor
clientIp := webUtil.GetRequestIP(r) clientIp := webUtil.GetRequestIP(r)
//下微信订单 //下微信订单
prepayId, err := internal.Prepay(orderId, currency, storeId, clientIp, "描述!!!!!!!!!!") prepayId, err := wxpay.Prepay(orderId, currency, storeId, clientIp, "描述!!!!!!!!!!")
if err != nil { if err != nil {
responseObj.SetResultStatus(resultStatus.APIDataError) responseObj.SetResultStatus(resultStatus.APIDataError)
return return
@ -139,7 +140,7 @@ func (a *PayApi) CallBack(orderIDStr string) (responseObj *webServer.ResponseObj
} }
//查询订单状态 //查询订单状态
statusStr, err := internal.QueryOrderByOutTradeNo(orderID) statusStr, err := wxpay.QueryOrderByOutTradeNo(orderID)
if err != nil { if err != nil {
responseObj.SetResultStatus(resultStatus.DataError) responseObj.SetResultStatus(resultStatus.DataError)
return return
@ -193,7 +194,7 @@ func (a *PayApi) AliPayPlaceAnOrder(orderId int64, modelID int32, currency int64
clientIp := webUtil.GetRequestIP(r) clientIp := webUtil.GetRequestIP(r)
//下微信订单 //下微信订单
prepayId, err := internal.AliPayPlace(orderId, currency, storeId, clientIp, "描述!!!!!!!!!!") prepayId, err := alipay.AliPayPlace(orderId, currency, storeId, clientIp, "描述!!!!!!!!!!")
if err != nil { if err != nil {
responseObj.SetResultStatus(resultStatus.APIDataError) responseObj.SetResultStatus(resultStatus.APIDataError)
return return
@ -209,4 +210,5 @@ func (a *PayApi) AliPayPlaceAnOrder(orderId int64, modelID int32, currency int64
resultMap["orderID"] = order.OrderID resultMap["orderID"] = order.OrderID
resultMap["prepayId"] = order.PrepayId resultMap["prepayId"] = order.PrepayId
responseObj.SetData(resultMap) responseObj.SetData(resultMap)
return responseObj
} }

View File

@ -2,94 +2,68 @@ package pay
import ( import (
"common/connection" "common/connection"
"common/timer"
"goutil/logUtilPlus" "goutil/logUtilPlus"
"paycenter/internal" "paycenter/internal/wxpay"
"strconv" "strconv"
"time" "time"
) )
func init() { func init() {
go CheckOrderStatus() timer.Register(timer.TriggerTypeHalfHour, CheckOrderStatus)
} }
// CheckOrderStatus 查询订单状态 // CheckOrderStatus 检查订单状态
func CheckOrderStatus() { // @return error
func CheckOrderStatus(nowTime time.Time) error {
//捕获异常 //检索最近一个月的订单
defer func() { for i := 0; i < 2; i++ {
if err := recover(); err != nil {
logUtilPlus.ErrorLog("CheckOrderStatus panic:", err) //取i的负数
restartConsumer() dbDate := connection.GetToMonthAdd(int32(-i))
var orders []Order // 使用切片存储查询结果
//这里使用原始sql
sql := "select * from order_" + strconv.Itoa(int(dbDate)) + " where order_status = 0"
dbResult := connection.GetPayDB().Exec(sql).Find(&orders)
if dbResult.Error != nil {
logUtilPlus.ErrorLog("查询订单状态失败", dbResult.Error.Error())
continue
} }
}()
for { // 处理查询结果
//检索最近一个月的订单 for _, order := range orders {
for i := 0; i < 2; i++ {
//取i的负数 //查询订单状态
dbDate := connection.GetToMonthAdd(int32(-i)) statusStr, err := wxpay.QueryOrderByOutTradeNo(order.OrderID)
var orders []Order // 使用切片存储查询结果 if err != nil {
logUtilPlus.ErrorLog("查询订单状态失败", err.Error())
//这里使用原始sql
sql := "select * from order_" + strconv.Itoa(int(dbDate)) + " where order_status = 0"
dbResult := connection.GetPayDB().Exec(sql).Find(&orders)
if dbResult.Error != nil {
logUtilPlus.ErrorLog("查询订单状态失败", dbResult.Error.Error())
continue continue
} }
if statusStr == "SUCCESS" {
// 处理查询结果 //修改订单状态
for _, order := range orders { err = ChangeOrderStatus(order.OrderID, 1)
//查询订单状态
statusStr, err := internal.QueryOrderByOutTradeNo(order.OrderID)
if err != nil { if err != nil {
logUtilPlus.ErrorLog("查询订单状态失败", err.Error()) logUtilPlus.ErrorLog("修改订单状态失败", err.Error())
continue continue
} }
if statusStr == "SUCCESS" { } else if statusStr == "CLOSED" { //已关闭
//修改订单状态 order.OrderStatus = 2
err = ChangeOrderStatus(order.OrderID, 1) //修改订单状态
if err != nil { connection.AsyncSave(connection.GetPayDB(), &order)
logUtilPlus.ErrorLog("修改订单状态失败", err.Error()) } else if order.OrderTime.Add(time.Hour * 1).Before(time.Now()) { //超一个小时未支付 直接关闭订单
continue //直接关闭订单
} err = wxpay.CloseOrder(order.OrderID)
} else if statusStr == "CLOSED" { //已关闭 if err != nil {
order.OrderStatus = 2 logUtilPlus.ErrorLog("关闭订单失败", err.Error())
//修改订单状态 continue
connection.AsyncSave(connection.GetPayDB(), &order)
} else if order.OrderTime.Add(time.Hour * 1).Before(time.Now()) { //超一个小时未支付 直接关闭订单
//直接关闭订单
internal.CloseOrder(order.OrderID)
order.OrderStatus = 2
connection.AsyncSave(connection.GetPayDB(), &order)
} }
order.OrderStatus = 2
connection.AsyncSave(connection.GetPayDB(), &order)
} }
} }
//休息30分钟
time.Sleep(time.Minute * 30)
} }
}
// restartConsumer 重启消费者 return nil
func restartConsumer() {
// 设置重试次数
maxRetries := 5
retryCount := 0
for {
select {
case <-time.After(5 * time.Second): // 等待5秒后重试
if retryCount >= maxRetries {
logUtilPlus.ErrorLog("查询订单状态,达到最大重试次数")
return
}
logUtilPlus.InfoLog("查询订单状态,重试次数: %d", retryCount+1)
go CheckOrderStatus()
return
}
retryCount++
}
} }

View File

@ -0,0 +1,64 @@
package wxpay
import (
"gopkg.in/yaml.v3"
"goutil/yamlUtil"
"log"
)
type WxPayConfig struct {
MchID string
MchCertificateSerialNumber string
MchAPIv3Key string
AppId string
NotifyUrl string
}
var (
wxPayConfig = &WxPayConfig{}
)
func init() {
//加载配置
reloadConfig()
//校验配置
CheckConfig()
}
// reloadConfig
//
// @description: reloadConfig
//
// parameter:
// return:
//
// @error: 错误信息
func reloadConfig() error {
yamlFile, err := yamlUtil.LoadFromFile("payconfig/wxpayconfig.yml")
if err != nil {
return err
}
// 解析 YAML 文件
err = yaml.Unmarshal(yamlFile, wxPayConfig)
if err != nil {
log.Fatalf("Error unmarshalling config file: %v", err)
return err
}
return nil
}
// CheckConfig 校验配置
func CheckConfig() error {
return nil
}
// GetWxPayConfig 获取配置
func GetWxPayConfig() *WxPayConfig {
return wxPayConfig
}

View File

@ -0,0 +1,249 @@
package wxpay
import (
"context"
"errors"
"fmt"
"github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
"github.com/wechatpay-apiv3/wechatpay-go/utils"
"goutil/logUtilPlus"
"log"
"strconv"
"time"
)
var (
mchID string = GetWxPayConfig().MchID // 商户号
mchCertificateSerialNumber string = GetWxPayConfig().MchCertificateSerialNumber // 商户证书序列号
mchAPIv3Key string = GetWxPayConfig().MchAPIv3Key // 商户APIv3密钥
appId string = GetWxPayConfig().AppId // 应用ID
Address string = "成都市XXXXXXXXXXXXXXXXXXXXXXX" //公司地址
wxPayApiUrl string = GetWxPayConfig().NotifyUrl //支付成功回调地址
)
// Prepay 函数用于发起预支付请求。
// 参数:
//
// outTradeNo: 商户订单号。
// currency: 订单金额,单位为分。
// storeId: 商户门店编号。
// clientIp: 用户的客户端IP。
// description: 订单描述。
//
// 返回值:
//
// 成功时返回预支付ID和nil错误。
// 失败时返回空字符串和错误对象。
func Prepay(outTradeNo int64, currency int64, storeId string, clientIp string, description string) (string, error) {
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
if err != nil {
logUtilPlus.ErrorLog("load merchant private key error")
return "", err
}
ctx := context.Background()
// 使用商户私钥等初始化 client并使它具有自动定时获取微信支付平台证书的能力
opts := []core.ClientOption{
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
}
client, err := core.NewClient(ctx, opts...)
if err != nil {
logUtilPlus.ErrorLog("new wechat pay client err:%s", err)
return "", err
}
svc := app.AppApiService{Client: client}
resp, result, err := svc.Prepay(ctx,
app.PrepayRequest{
Appid: core.String(appId),
Mchid: core.String(mchID),
Description: core.String(description),
OutTradeNo: core.String(strconv.FormatInt(outTradeNo, 10)),
TimeExpire: core.Time(time.Now().Add(time.Hour * 2)), //支付时效时间 2 小时后失效
Attach: core.String(""), //附加数据 这里不需要有个订单id 可以获取订单详细信息
NotifyUrl: core.String(fmt.Sprintf(wxPayApiUrl, strconv.FormatInt(outTradeNo, 10))), //回调地址
//GoodsTag: core.String("WXG"),//优惠标记 这里没用
//LimitPay: []string{"LimitPay_example"},
SupportFapiao: core.Bool(false),
Amount: &app.Amount{
Currency: core.String("CNY"),
Total: core.Int64(currency),
},
Detail: &app.Detail{
//CostPrice: core.Int64(608800),
GoodsDetail: []app.GoodsDetail{app.GoodsDetail{
GoodsName: core.String(storeId), //商品编号
MerchantGoodsId: core.String(description),
Quantity: core.Int64(1),
UnitPrice: core.Int64(currency),
//WechatpayGoodsId: core.String("1001"),
}},
//InvoiceId: core.String("wx123"),
},
SceneInfo: &app.SceneInfo{
//DeviceId: core.String("013467007045764"),
PayerClientIp: core.String(clientIp),
StoreInfo: &app.StoreInfo{
Address: core.String(Address),
//AreaCode: core.String("440305"),
//Id: core.String("0001"),
//Name: core.String("腾讯大厦分店"),
},
},
SettleInfo: &app.SettleInfo{
ProfitSharing: core.Bool(false),
},
},
)
if err != nil {
// 处理错误
logUtilPlus.ErrorLog("call Prepay err:%s", err.Error())
return "", err
}
if result.Response.StatusCode != 200 {
errStr := fmt.Sprintf("status=%d resp=%s", result.Response.StatusCode, resp)
logUtilPlus.ErrorLog(errStr)
return "", errors.New(errStr)
}
return *resp.PrepayId, nil
}
// CloseOrder 关闭订单
func CloseOrder(outTradeNo int64) error {
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
if err != nil {
log.Print("加载商家私钥错误")
}
ctx := context.Background()
// 使用商户私钥等初始化 client并使它具有自动定时获取微信支付平台证书的能力
opts := []core.ClientOption{
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
}
client, err := core.NewClient(ctx, opts...)
if err != nil {
log.Printf("新的 WeChat Pay 客户端 Err:%s", err)
}
svc := app.AppApiService{Client: client}
_, err = svc.CloseOrder(ctx,
app.CloseOrderRequest{
//商户系统内部订单号只能是数字、大小写字母_-*且在同一个商户号下唯
OutTradeNo: core.String(strconv.FormatInt(outTradeNo, 10)),
//直连商户的商户号,由微信支付生成并下发。
Mchid: core.String(mchID),
},
)
if err != nil {
// 处理错误
logUtilPlus.ErrorLog("call CloseOrder err:%s", err)
return err
}
return nil
}
// QueryOrderById 根据商户订单号查询订单
func QueryOrderById() {
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
if err != nil {
log.Print("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.Printf("new wechat pay client err:%s", err)
}
svc := app.AppApiService{Client: client}
resp, result, err := svc.QueryOrderById(ctx,
app.QueryOrderByIdRequest{
TransactionId: core.String("TransactionId_example"),
Mchid: core.String("Mchid_example"),
},
)
if err != nil {
// 处理错误
log.Printf("call QueryOrderById err:%s", err)
} else {
// 处理返回结果
log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
}
}
// QueryOrderByOutTradeNo 根据商户订单号查询订单
func QueryOrderByOutTradeNo(outTradeNo int64) (string, error) {
//循环查询次数
var count int = 0
loop:
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
if err != nil {
log.Print("load merchant private key error")
return "", err
}
ctx := context.Background()
// 使用商户私钥等初始化 client并使它具有自动定时获取微信支付平台证书的能力
opts := []core.ClientOption{
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
}
client, err := core.NewClient(ctx, opts...)
if err != nil {
log.Printf("new wechat pay client err:%s", err)
return "", err
}
svc := app.AppApiService{Client: client}
resp, result, err := svc.QueryOrderByOutTradeNo(ctx,
app.QueryOrderByOutTradeNoRequest{
OutTradeNo: core.String(strconv.FormatInt(outTradeNo, 10)),
Mchid: &mchID,
},
)
if err != nil {
// 处理错误
log.Printf("call QueryOrderByOutTradeNo err:%s", err)
return "", err
} else {
// 处理返回结果
log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
//支付成功
if resp.TradeState == core.String("SUCCESS") {
return "SUCCESS", nil
} else if resp.TradeState == core.String("NOTPAY") && count < 3 { //未支付,循环查找订单
//休息200毫秒
time.Sleep(200 * time.Millisecond)
count++
goto loop
}
//支付失败
return *resp.TradeState, nil
}
}

View File

@ -54,7 +54,7 @@ func (a *WxuserApi) LoginByWechat(code string, severId int32) (responseObj *webS
responseObj.SetResultStatus(resultStatus.APIDataError) responseObj.SetResultStatus(resultStatus.APIDataError)
return return
} }
res, uid := GetWechatsdkService().GetAccessToken(code) res, uid := GetWechatsdkService().GetAccessToken(code, severId)
if res != resultStatus.Success { if res != resultStatus.Success {
responseObj.SetResultStatus(res) responseObj.SetResultStatus(res)
} }
@ -113,7 +113,7 @@ func init() {
"Message '类型:string'": "响应结果的状态值所对应的描述信息", "Message '类型:string'": "响应结果的状态值所对应的描述信息",
"Data '类型:interface{}'": "响应结果的数据" "Data '类型:interface{}'": "响应结果的数据"
{ {
"Uid '类型:int64'": "切服后的区服的唯一Id",
} }
}` }`
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam, skipVerifyTokenPage) remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam, skipVerifyTokenPage)
@ -121,13 +121,17 @@ func init() {
func (a *WxuserApi) SwitchSever(uid int64, oldseverId, newseverId int32) (responseObj *webServer.ResponseObject) { func (a *WxuserApi) SwitchSever(uid int64, oldseverId, newseverId int32) (responseObj *webServer.ResponseObject) {
responseObj = webServer.GetInitResponseObj() responseObj = webServer.GetInitResponseObj()
if uid == 0 { if uid == 0 || oldseverId == 0 || newseverId == 0 {
logUtilPlus.ErrorLog("uid=0") logUtilPlus.ErrorLog("WxuserApi.SwitchSever参数不正确")
responseObj.SetResultStatus(resultStatus.APIDataError) responseObj.SetResultStatus(resultStatus.APIDataError)
return return
} }
// RecordLoginOut(openid, oldseverId) if oldseverId == newseverId {
// RecordLoginIn(openid, newseverId) logUtilPlus.ErrorLog("WxuserApi.SwitchSever参数不正确")
responseObj.SetResultStatus(resultStatus.APIDataError)
return
}
SwitchSever(uid, oldseverId, newseverId)
return return
} }
@ -139,7 +143,7 @@ func init() {
methodAuthor := "youjinlan" methodAuthor := "youjinlan"
methodMendor := "" methodMendor := ""
methodDate := "2025-01-22 10:40:00" methodDate := "2025-01-22 10:40:00"
methodInParam := []string{"string openid,int32 severId"} methodInParam := []string{"int64 uid"}
methodOutParam := ` methodOutParam := `
{ {
"Code '类型:int'": "响应结果的状态值", "Code '类型:int'": "响应结果的状态值",
@ -155,7 +159,7 @@ func init() {
func (a *WxuserApi) WatchAD(uid int64) (responseObj *webServer.ResponseObject) { func (a *WxuserApi) WatchAD(uid int64) (responseObj *webServer.ResponseObject) {
responseObj = webServer.GetInitResponseObj() responseObj = webServer.GetInitResponseObj()
if uid == 0 { if uid == 0 {
logUtilPlus.ErrorLog("openid,openid为空") logUtilPlus.ErrorLog("uid=0")
responseObj.SetResultStatus(resultStatus.APIDataError) responseObj.SetResultStatus(resultStatus.APIDataError)
return return
} }

View File

@ -8,12 +8,16 @@ import (
var ( var (
// 用户缓存对象 // 用户缓存对象
userInfoMap = make(map[string]*WxUserInfo) userInfoMap = make(map[string]*WxUserInfo)
rwmu sync.RWMutex rwmu sync.RWMutex
userRecordMap = make(map[int64]*RecordLoginOfWxUser) userRecordMap = make(map[int64]*RecordLoginOfWxUser)
rwmu2 sync.RWMutex rwmu2 sync.RWMutex
userADRecordMap = make(map[int64]*RecordWatchADOfWxUser) userADRecordMap = make(map[int64]*RecordWatchADOfWxUser)
rwmu3 sync.RWMutex rwmu3 sync.RWMutex
userSeverInfoMap = make(map[string]map[int32]int64)
rwmu4 sync.RWMutex
userUidMap = make(map[int64]*WxUserSeverInfo)
rwmu5 sync.RWMutex
) )
func GetUserByOpenId(openId string) (*WxUserInfo, error) { func GetUserByOpenId(openId string) (*WxUserInfo, error) {
@ -58,12 +62,17 @@ func AddUserCache(user *WxUserInfo) {
} }
// 登录登出相关 // 登录登出相关
// 添加用户登录登出表到缓存
func AddUserRecordCache(userrecord *RecordLoginOfWxUser) { func AddUserRecordCache(userrecord *RecordLoginOfWxUser) {
rwmu2.Lock() rwmu2.Lock()
defer rwmu2.Unlock() defer rwmu2.Unlock()
userRecordMap[userrecord.Uid] = userrecord userRecordMap[userrecord.Uid] = userrecord
} }
// 获取最新一条登录记录
func GetUserRecord(uid int64) (*RecordLoginOfWxUser, error) { func GetUserRecord(uid int64) (*RecordLoginOfWxUser, error) {
var userRecord *RecordLoginOfWxUser var userRecord *RecordLoginOfWxUser
func() *RecordLoginOfWxUser { func() *RecordLoginOfWxUser {
@ -91,6 +100,7 @@ func GetUserRecord(uid int64) (*RecordLoginOfWxUser, error) {
return userRecord, nil return userRecord, nil
} }
// 添加用户登录登出记录
func AddUserRecord(userrecord *RecordLoginOfWxUser) (int64, error) { func AddUserRecord(userrecord *RecordLoginOfWxUser) (int64, error) {
//处理一些验证 //处理一些验证
@ -103,6 +113,7 @@ func AddUserRecord(userrecord *RecordLoginOfWxUser) (int64, error) {
return userrecord.ID, nil return userrecord.ID, nil
} }
// 保存添加用户登录登出记录
func SaveUserRecord(userrecord *RecordLoginOfWxUser) (int64, error) { func SaveUserRecord(userrecord *RecordLoginOfWxUser) (int64, error) {
//处理一些验证 //处理一些验证
@ -116,12 +127,17 @@ func SaveUserRecord(userrecord *RecordLoginOfWxUser) (int64, error) {
} }
// 看广告相关 // 看广告相关
// 添加用户看广告记录到缓存
func AddUserADRecordCache(userADrecord *RecordWatchADOfWxUser) { func AddUserADRecordCache(userADrecord *RecordWatchADOfWxUser) {
rwmu3.Lock() rwmu3.Lock()
defer rwmu3.Unlock() defer rwmu3.Unlock()
userADRecordMap[userADrecord.Uid] = userADrecord userADRecordMap[userADrecord.Uid] = userADrecord
} }
// 获取最新一条看广告记录
func GetUserADRecord(uid int64) (*RecordWatchADOfWxUser, error) { func GetUserADRecord(uid int64) (*RecordWatchADOfWxUser, error) {
var userADRecord *RecordWatchADOfWxUser var userADRecord *RecordWatchADOfWxUser
func() *RecordWatchADOfWxUser { func() *RecordWatchADOfWxUser {
@ -149,6 +165,7 @@ func GetUserADRecord(uid int64) (*RecordWatchADOfWxUser, error) {
return userADRecord, nil return userADRecord, nil
} }
// 添加用户看广告记录到数据库
func AddUserADRecord(userADrecord *RecordWatchADOfWxUser) (int64, error) { func AddUserADRecord(userADrecord *RecordWatchADOfWxUser) (int64, error) {
//处理一些验证 //处理一些验证
@ -161,6 +178,7 @@ func AddUserADRecord(userADrecord *RecordWatchADOfWxUser) (int64, error) {
return userADrecord.ID, nil return userADrecord.ID, nil
} }
// 保存用户看广告记录到数据库
func SaveUserADRecord(userADrecord *RecordWatchADOfWxUser) (int64, error) { func SaveUserADRecord(userADrecord *RecordWatchADOfWxUser) (int64, error) {
//处理一些验证 //处理一些验证
@ -174,6 +192,88 @@ func SaveUserADRecord(userADrecord *RecordWatchADOfWxUser) (int64, error) {
} }
// 区服相关 // 区服相关
// 添加用户的区服信息到缓存 以openid为key的map
func AddUserSeverInfoCache(openid string, severid int32, uid int64) {
rwmu4.Lock()
defer rwmu4.Unlock()
newMap := make(map[int32]int64)
newMap[severid] = uid
if _, ok := userSeverInfoMap[openid]; !ok {
userSeverInfoMap[openid] = newMap
return
}
if _, ok := userSeverInfoMap[openid][severid]; !ok {
userSeverInfoMap[openid][severid] = uid
}
}
// 添加用户的区服信息到缓存 以uid为key
func AddUserUidCache(wxUserSeverInfo *WxUserSeverInfo) {
rwmu5.Lock()
defer rwmu5.Unlock()
userUidMap[wxUserSeverInfo.Uid] = wxUserSeverInfo
}
// 通过uid来获取用户的区服信息
func GetUserSeverInfoByUid(uid int64) (*WxUserSeverInfo, error) {
var userSeverInfoRecord *WxUserSeverInfo
func() *WxUserSeverInfo {
rwmu5.RLock()
defer rwmu5.RUnlock()
ok := true
if userSeverInfoRecord, ok = userUidMap[uid]; ok {
return userSeverInfoRecord
}
return nil
}()
if userSeverInfoRecord == nil {
result := connection.GetUserDB().Where("uid = ?", uid).First(&userSeverInfoRecord)
if result.Error != nil {
return nil, result.Error
}
}
func() {
rwmu5.Lock()
defer rwmu5.Unlock()
userUidMap[uid] = userSeverInfoRecord
}()
return userSeverInfoRecord, nil
}
// 通过openid和severid来获取uid
func GetUserUid(openId string, severId int32) (int64, error) {
var uid int64
func() int64 {
rwmu4.RLock()
defer rwmu4.RUnlock()
ok := true
if _, ok = userSeverInfoMap[openId]; !ok {
return 0
}
if uid, ok = userSeverInfoMap[openId][severId]; ok {
return uid
}
return 0
}()
if uid == 0 {
var userSeverInfoRecord *WxUserSeverInfo
result := connection.GetUserDB().Where("openId = ? AND severId = ?", openId, severId).First(&userSeverInfoRecord)
if result.Error != nil {
return 0, result.Error
}
if userSeverInfoRecord.Uid == 0 {
userSeverInfoRecord.Uid = userSeverInfoRecord.ID + 100000000
SaveUserSeverInfo(userSeverInfoRecord)
}
return userSeverInfoRecord.Uid, nil
}
return uid, nil
}
// 添加用户区服信息到数据库
func AddUserSeverInfo(userSeverInfo *WxUserSeverInfo) (int64, error) { func AddUserSeverInfo(userSeverInfo *WxUserSeverInfo) (int64, error) {
//处理一些验证 //处理一些验证
@ -186,6 +286,7 @@ func AddUserSeverInfo(userSeverInfo *WxUserSeverInfo) (int64, error) {
return userSeverInfo.ID, nil return userSeverInfo.ID, nil
} }
// 保存用户区服信息到数据库
func SaveUserSeverInfo(userSeverInfo *WxUserSeverInfo) (int64, error) { func SaveUserSeverInfo(userSeverInfo *WxUserSeverInfo) (int64, error) {
//处理一些验证 //处理一些验证
@ -198,20 +299,25 @@ func SaveUserSeverInfo(userSeverInfo *WxUserSeverInfo) (int64, error) {
return userSeverInfo.ID, nil return userSeverInfo.ID, nil
} }
func GetUserSeverInfo() (*WxUserSeverInfo, error) { // 查询severid是否存在即是否为新服
var userSeverInfoRecord *WxUserSeverInfo func CheckSeverID(severid int32) bool {
result := connection.GetUserDB().Last(&userSeverInfoRecord) var userSeverList *WxUserSeverList
result := connection.GetUserDB().Where("severId = ?", severid).First(&userSeverList)
if result.Error != nil { if result.Error != nil {
return nil, result.Error return false
} }
return userSeverInfoRecord, nil return true
} }
func GetUserSeverInfoByIds(openId string, severId int32) (*WxUserSeverInfo, error) { // 添加新的severid到服务器列表
var userSeverInfoRecord *WxUserSeverInfo func AddUserSeverList(userSeverList *WxUserSeverList) (int64, error) {
result := connection.GetUserDB().Where("openId = ? AND severId = ?", openId, severId).First(&userSeverInfoRecord)
//处理一些验证
// 写入到数据库
result := connection.GetUserDB().Create(&userSeverList) // 通过数据的指针来创建
if result.Error != nil { if result.Error != nil {
return nil, result.Error logUtilPlus.ErrorLog("添加用户区服列表失败 错误信息:", result.Error.Error())
} }
return userSeverInfoRecord, nil return userSeverList.ID, nil
} }

View File

@ -2,9 +2,6 @@ package wxuser
import ( import (
"common/connection" "common/connection"
"time"
"github.com/jinzhu/gorm"
) )
func init() { func init() {
@ -13,6 +10,7 @@ func init() {
connection.RegisterDBModel(&RecordLoginOfWxUser{}) connection.RegisterDBModel(&RecordLoginOfWxUser{})
connection.RegisterDBModel(&RecordWatchADOfWxUser{}) connection.RegisterDBModel(&RecordWatchADOfWxUser{})
connection.RegisterDBModel(&WxUserSeverInfo{}) connection.RegisterDBModel(&WxUserSeverInfo{})
connection.RegisterDBModel(&WxUserSeverList{})
} }
type WechatTokens struct { type WechatTokens struct {
@ -45,29 +43,40 @@ type WxUserSeverInfo struct {
Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"` Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"`
} }
// 记录当前为止的开服数
type WxUserSeverList struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
SeverId int32 `gorm:"column:severId;comment:区服Id" json:"severId"`
}
// 登录相关的记录 // 登录相关的记录
type RecordLoginOfWxUser struct { type RecordLoginOfWxUser struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"` ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"` Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"`
SeverId int32 `gorm:"column:severId;comment:区服Id" json:"severId"`
RecordDate int64 `gorm:"column:recorddate;comment:记录日期" json:"recorddate"` //只记录当天0点的时间戳方便查询某一日的数据
LoginInTime int64 `gorm:"column:loginintime;comment:登录时间" json:"loginintime"` LoginInTime int64 `gorm:"column:loginintime;comment:登录时间" json:"loginintime"`
LoginOutTime int64 `gorm:"column:loginouttime;comment:登出时间" json:"loginouttime"` LoginOutTime int64 `gorm:"column:loginouttime;comment:登出时间" json:"loginouttime"`
PlayTimes int64 `gorm:"column:playtimes;comment:游玩时长" json:"playtimes"` PlayTimes int64 `gorm:"column:playtimes;comment:游玩时长" json:"playtimes"`
//用于统计当日的总上线人数 0=否1=是
IsFirstLogin int32 `gorm:"column:isfirstlogin;comment:是否首次登录" json:"isfirstlogin"`
} }
// 看广告相关记录 // 看广告相关记录
// 记录日期便于按天统计 // 记录日期便于按天统计
type RecordWatchADOfWxUser struct { type RecordWatchADOfWxUser struct {
ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"` ID int64 `gorm:"column:id;primary_key;comment:自增索引;autoIncrementIncrement" json:"id"`
RecordDate time.Time `gorm:"column:recorddate;type:date;comment:记录日期" json:"recorddate"` RecordDate int64 `gorm:"column:recorddate;comment:记录日期" json:"recorddate"` //只记录当天0点的时间戳方便查询某一日的数据
Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"` Uid int64 `gorm:"column:uid;comment:用户唯一Id" json:"uid"`
WatchADNum int32 `gorm:"column:watchadnum;comment:看广告次数" json:"watchadnum"` SeverId int32 `gorm:"column:severId;comment:区服Id" json:"severId"`
WatchADNum int32 `gorm:"column:watchadnum;comment:看广告次数" json:"watchadnum"`
} }
func (WxUserInfo) TableName() string { func (WxUserInfo) TableName() string {
return "wxuserinfo" return "wxuserinfo"
} }
func (r RecordLoginOfWxUser) TableName(db *gorm.DB) string { func (RecordLoginOfWxUser) TableName() string {
return "recordloginofwxuser" return "recordloginofwxuser"
} }
@ -78,3 +87,7 @@ func (RecordWatchADOfWxUser) TableName() string {
func (WxUserSeverInfo) TableName() string { func (WxUserSeverInfo) TableName() string {
return "wxuserseverinfo" return "wxuserseverinfo"
} }
func (WxUserSeverList) TableName() string {
return "wxuserseverlist"
}

View File

@ -1,24 +1,38 @@
package wxuser package wxuser
import ( import (
"common/mytime"
"common/resultStatus" "common/resultStatus"
"goutil/logUtilPlus" "goutil/logUtilPlus"
"time" "time"
) )
func RecordLoginIn(uid int64) { // 记录登录数据
func RecordLoginIn(uid int64, severId int32) {
nowTime := time.Now().Unix() nowTime := time.Now().Unix()
// if userLastRecord, _ := GetUserRecord(uid); userLastRecord != nil {
// if userLastRecord.LoginOutTime == 0 {
// return
// }
// }
userRecord := &RecordLoginOfWxUser{} userRecord := &RecordLoginOfWxUser{}
userRecord.IsFirstLogin = 1
if userLastRecord, _ := GetUserRecord(uid); userLastRecord != nil {
if userLastRecord.RecordDate == mytime.ZeroTime(nowTime, 0) {
userRecord.IsFirstLogin = 0
}
}
userRecord.LoginInTime = nowTime userRecord.LoginInTime = nowTime
userRecord.Uid = uid
userRecord.RecordDate = mytime.ZeroTime(nowTime, 0)
userRecord.SeverId = severId
AddUserRecord(userRecord) AddUserRecord(userRecord)
AddUserRecordCache(userRecord) AddUserRecordCache(userRecord)
//检测该服是否是新服
if !CheckSeverID(severId) {
//若是新服添加服务器id到服务器列表方便统计的时候知道有多少个服
newUserSeverList := &WxUserSeverList{}
newUserSeverList.SeverId = severId
AddUserSeverList(newUserSeverList)
}
} }
// 统计登出数据
func RecordLoginOut(uid int64) resultStatus.ResultStatus { func RecordLoginOut(uid int64) resultStatus.ResultStatus {
var userRecord *RecordLoginOfWxUser var userRecord *RecordLoginOfWxUser
if userRecord, _ = GetUserRecord(uid); userRecord == nil { if userRecord, _ = GetUserRecord(uid); userRecord == nil {
@ -30,51 +44,90 @@ func RecordLoginOut(uid int64) resultStatus.ResultStatus {
} }
go func() { go func() {
nowTime := time.Now().Unix() nowTime := time.Now().Unix()
userRecord.LoginOutTime = nowTime if userRecord.RecordDate == mytime.ZeroTime(nowTime, 0) {
playTime := nowTime - userRecord.LoginInTime userRecord.LoginOutTime = nowTime
userRecord.PlayTimes += playTime playTime := nowTime - userRecord.LoginInTime
SaveUserRecord(userRecord) userRecord.PlayTimes += playTime
SaveUserRecord(userRecord)
} else {
//如果跨天,要拆分成两条数据记录
zeroTime := mytime.ZeroTime(nowTime, 0)
userRecord.LoginOutTime = zeroTime
playTime := zeroTime - userRecord.LoginInTime
userRecord.PlayTimes += playTime
SaveUserRecord(userRecord)
newUserRecord := &RecordLoginOfWxUser{}
newUserRecord.LoginInTime = zeroTime
newUserRecord.LoginOutTime = nowTime
playTime = nowTime - userRecord.LoginInTime
newUserRecord.PlayTimes += playTime
newUserRecord.RecordDate = mytime.ZeroTime(nowTime, 0)
newUserRecord.Uid = uid
newUserRecord.SeverId = userRecord.SeverId
newUserRecord.IsFirstLogin = 1
AddUserRecord(newUserRecord)
}
}() }()
return resultStatus.Success return resultStatus.Success
} }
// 记录看广告数据
func RecordWatchAD(uid int64) resultStatus.ResultStatus { func RecordWatchAD(uid int64) resultStatus.ResultStatus {
nowTime := time.Now() todayZeroTime := mytime.ZeroTime(time.Now().Unix(), 0)
userADRecord := &RecordWatchADOfWxUser{} userADRecord := &RecordWatchADOfWxUser{}
var userSeverInfoRecord *WxUserSeverInfo
if userSeverInfoRecord, _ = GetUserSeverInfoByUid(uid); userSeverInfoRecord == nil {
return resultStatus.PlayerNotExist
}
severId := userSeverInfoRecord.SeverId
if userLastADRecord, _ := GetUserADRecord(uid); userLastADRecord != nil { if userLastADRecord, _ := GetUserADRecord(uid); userLastADRecord != nil {
if nowTime.Format("2006-01-02") == userLastADRecord.RecordDate.Format("2006-01-02") { if userLastADRecord.RecordDate == mytime.ZeroTime(todayZeroTime, 0) {
//数据按天记录,如果为同一天,就在原来的数据上加
userLastADRecord.WatchADNum++ userLastADRecord.WatchADNum++
SaveUserADRecord(userLastADRecord) SaveUserADRecord(userLastADRecord)
return resultStatus.Success return resultStatus.Success
} }
} }
userADRecord.RecordDate = nowTime userADRecord.RecordDate = todayZeroTime
userADRecord.WatchADNum += 1 userADRecord.WatchADNum += 1
userADRecord.Uid = uid
userADRecord.SeverId = severId
AddUserADRecord(userADRecord) AddUserADRecord(userADRecord)
AddUserADRecordCache(userADRecord) AddUserADRecordCache(userADRecord)
return resultStatus.Success return resultStatus.Success
} }
// 根据openid和severid来创建uid
func CreatUid(openId string, severId int32) int64 { func CreatUid(openId string, severId int32) int64 {
var lastId int64 if uid, _ := GetUserUid(openId, severId); uid != 0 {
if userRecord, _ := GetUserSeverInfoByIds(openId, severId); userRecord != nil { return uid
return userRecord.Uid
}
if userLastRecord, _ := GetUserSeverInfo(); userLastRecord != nil {
lastId = userLastRecord.ID
} }
userSeverInfo := &WxUserSeverInfo{} userSeverInfo := &WxUserSeverInfo{}
userSeverInfo.OpenId = openId userSeverInfo.OpenId = openId
userSeverInfo.SeverId = severId userSeverInfo.SeverId = severId
userSeverInfo.Uid = lastId + 1 + 100000000 ID, _ := AddUserSeverInfo(userSeverInfo)
AddUserSeverInfo(userSeverInfo) //uid=数据库索引+1亿先取索引再相加避免重复
return userSeverInfo.Uid Uid := ID + 100000000
AddUserSeverInfoCache(openId, severId, Uid)
AddUserUidCache(userSeverInfo)
go func() {
userSeverInfo.Uid = Uid
SaveUserSeverInfo(userSeverInfo)
}()
return Uid
} }
// func init() { // 切服时记录数据
// testRecordWatchAD() func SwitchSever(uid int64, oldseverId, newseverId int32) (int64, resultStatus.ResultStatus) {
// } var userSeverInfoRecord *WxUserSeverInfo
if userSeverInfoRecord, _ = GetUserSeverInfoByUid(uid); userSeverInfoRecord == nil {
func testRecordWatchAD() { return 0, resultStatus.PlayerNotExist
//RecordWatchAD("hell) }
if userSeverInfoRecord.SeverId != oldseverId {
return 0, resultStatus.PlayerNotMatchSever
}
RecordLoginOut(uid)
uidOfNewSever := CreatUid(userSeverInfoRecord.OpenId, newseverId)
go RecordLoginIn(uidOfNewSever, newseverId)
return uidOfNewSever, resultStatus.Success
} }

View File

@ -17,7 +17,7 @@ type WechatsdkService struct {
} }
// 通过code来换取assesstoken // 通过code来换取assesstoken
func (w *WechatsdkService) GetAccessToken(code string) (resultStatus.ResultStatus, int64) { func (w *WechatsdkService) GetAccessToken(code string, severId int32) (resultStatus.ResultStatus, int64) {
weburl := fmt.Sprintf("%s%s", Url, "oauth2/access_token") //"https://api.weixin.qq.com/sns/oauth2/access_token" weburl := fmt.Sprintf("%s%s", Url, "oauth2/access_token") //"https://api.weixin.qq.com/sns/oauth2/access_token"
data := make(map[string]string) data := make(map[string]string)
data["appid"] = configYaml.GetWxconfig().AppId data["appid"] = configYaml.GetWxconfig().AppId
@ -49,7 +49,7 @@ func (w *WechatsdkService) GetAccessToken(code string) (resultStatus.ResultStatu
w.GetUserInfo(tokens.AccessToken, tokens.OpenId) w.GetUserInfo(tokens.AccessToken, tokens.OpenId)
} }
}() }()
go RecordLoginIn(Uid) go RecordLoginIn(Uid, severId)
return resultStatus.Success, Uid return resultStatus.Success, Uid
} }