Compare commits

..

8 Commits

Author SHA1 Message Date
ayflying
e8f94c911c 修稿红点删除缓存清理方式 2025-03-27 11:25:31 +08:00
ayflying
f55b3bc609 更新缓存模块 2025-03-27 11:20:07 +08:00
ayflying
d05d865b0d 去掉重复注册 2025-03-25 16:04:50 +08:00
ayflying
6e19671d06 增加控制器的反向注册 2025-03-25 15:58:20 +08:00
ayflying
f349dca0f7 所有包同意改为pkg 2025-03-25 15:00:54 +08:00
ayflying
58f00b4f8e 跟新mod 2025-03-25 14:24:56 +08:00
ayflying
d9ab1be2e7 更新pb目录 2025-03-25 14:14:48 +08:00
ayflying
4b77cd140d 初始化驱动 2025-03-25 14:06:03 +08:00
24 changed files with 726 additions and 172 deletions

View File

@@ -1,10 +1,10 @@
# utility_go强大的Go语言工具类库 # utility_go强大的Go语言工具类库
## 一、项目概述 ## 一、项目概述
`utility_go` 是一个功能丰富的Go语言工具类库旨在助开发者更高效地开发Go应用程序。它提供了一系列实用的功能模块涵盖数据库操作、缓存处理、支付接口集成、排名算法实现等多个方面,可广泛应用于各种类型的Go项目 `utility_go` 是一个功能丰富的Go语言工具类库旨在助开发者更高效地开发Go应用程序。它提供了一系列实用的功能模块广泛涵盖数据库操作、缓存处理、支付接口集成、排名算法实现等多个方面,适用于各类Go项目。
## 二、安装方式 ## 二、安装方式
要使用 `utility_go` 工具类库,你可以使用 `go get` 命令进行安装。请确保你的Go环境已正确配置,且可访问互联网。 要使用 `utility_go` 工具类库,使用 `go get` 命令进行安装。请确保你的Go环境已正确配置且可访问互联网。
### 安装命令 ### 安装命令
```sh ```sh
@@ -12,7 +12,7 @@ go get github.com/ayflying/utility_go
``` ```
### 安装验证 ### 安装验证
安装完成后,你可以在你的Go代码中导入 `utility_go` 相关的包,检查是否能够正常使用。例如: 安装完成后你可以在Go代码中导入 `utility_go` 相关的包,检查是否能够正常使用。例如
```go ```go
package main package main
@@ -29,39 +29,45 @@ func main() {
``` ```
## 三、项目结构 ## 三、项目结构
`utility_go` 的项目结构设计清晰,各模块分工明确,便开发者使用和扩展。以下是项目的主要目录结构: `utility_go` 的项目结构设计清晰,各模块分工明确,便开发者使用和扩展。以下是项目的主要目录结构及说明
### 主要目录说明 ### 主要目录说明
- **`api/`**存放与API相关的代码包含不同模块的API接口定义`admin``callback``system` 等。这些API接口用于处理各种外部请求是项目与外部系统交互的重要入口。 - **api/**存放与API相关的代码包含不同模块的API接口定义`admin``callback``system` 等。这些API接口用于处理各种外部请求是项目与外部系统交互的重要入口。
- **`service/`**:服务层代码,包含各种业务逻辑的实现,如 `game_act.go``ip_2_region.go` 等。服务层负责处理具体的业务需求,将数据处理和业务逻辑封装在独立的函数或方法中,提高代码的可维护性和复用性。 - **service/**:服务层代码,包含各种业务逻辑的实现,如 `game_act.go``ip_2_region.go` 等。服务层负责处理具体的业务需求,将数据处理和业务逻辑封装在独立的函数或方法中,提高代码的可维护性和复用性。
- **`controller/`**控制器层代码主要用于处理HTTP请求和响应。控制器接收客户端的请求调用相应的服务层方法进行处理并将处理结果返回给客户端。 - **controller/**控制器层代码主要用于处理HTTP请求和响应。控制器接收客户端的请求调用相应的服务层方法进行处理并将处理结果返回给客户端。
- **`internal/`**:内部包,包含项目的核心业务逻辑,如 `game``logic``model` 等模块。其中,`model` 模块定义了项目中使用的数据模型,如数据库表对应的结构体;`logic` 模块实现了各种业务逻辑的处理函数。 - **internal/**:内部包,包含项目的核心业务逻辑,如 `game``logic``model` 等模块。其中,`model` 模块定义了项目中使用的数据模型,如数据库表对应的结构体;`logic` 模块实现了各种业务逻辑的处理函数。
- **`package/`**:包含各种功能包,提供了丰富的工具和功能,具体如下: - **package/**:包含各种功能包,提供了丰富的工具和功能,具体如下:
- **`aycache`**:缓存相关的功能包,提供了缓存操作的接口和实现,帮助开发者更方便地使用缓存技术,提高应用程序的性能。 - **aycache**:缓存相关的功能包,提供了缓存操作的接口和实现,帮助开发者更方便地使用缓存技术,提高应用程序的性能。
- **`elasticsearch`**Elasticsearch相关的功能包用于与Elasticsearch搜索引擎进行交互实现数据的存储、检索和分析等功能。 - **elasticsearch**Elasticsearch相关的功能包用于与Elasticsearch搜索引擎进行交互实现数据的存储、检索和分析等功能。
- **`excel`**Excel处理相关的功能包提供了Excel文件的读写操作接口方便开发者处理Excel文件中的数据。 - **excel**Excel处理相关的功能包提供了Excel文件的读写操作接口方便开发者处理Excel文件中的数据。
- **`pay`**:支付相关的功能包,包含了与各种支付平台的接口集成,如 `apple`(苹果支付)、`playstore`Google Play Store支付支持应用内购买等支付功能。 - **pay**:支付相关的功能包,包含了与各种支付平台的接口集成,如 `apple`(苹果支付)、`playstore`Google Play Store支付支持应用内购买等支付功能。
- **`rand`**:随机数相关的功能包,提供了生成各种随机数的函数,可用于测试、加密等场景。 - **rand**:随机数相关的功能包,提供了生成各种随机数的函数,可用于测试、加密等场景。
- **`rank`**排名相关的功能包实现了各种排名算法如基于Redis的排行榜功能可用于游戏排名、活动排名等场景。 - **rank**排名相关的功能包实现了各种排名算法如基于Redis的排行榜功能可用于游戏排名、活动排名等场景。
- **`s3`**S3存储相关的功能包用于与Amazon S3等云存储服务进行交互实现文件的上传、下载、删除等操作。 - **s3**S3存储相关的功能包用于与Amazon S3等云存储服务进行交互实现文件的上传、下载、删除等操作。
- **`tools/`**:工具类代码,包含了一些常用的工具函数,如 `redis.go`Redis操作相关`time.go`(时间处理相关)、`tools.go`(通用工具函数)等,方便开发者在项目中使用。 - **tools/**:工具类代码,包含了一些常用的工具函数,如 `redis.go`Redis操作相关`time.go`(时间处理相关)、`tools.go`(通用工具函数)等,方便开发者在项目中使用。
## 四、主要模块功能 ## 四、主要模块功能
### 4.1 `pay/playstore` ### 4.1 pay/playstore
该模块主要用于与Google Play Store API交互处理应用内购买相关的操作。它提供以下主要功能: 该模块主要用于与Google Play Store API交互处理应用内购买相关的操作提供以下主要功能:
- **创建客户端**:通过 `New` 函数创建并返回一个包含访问androidpublisher API所需凭证的http客户端方便开发者与Google Play Store API进行通信。 - **创建客户端**:通过 `New` 函数创建并返回一个包含访问 `androidpublisher` API所需凭证的HTTP客户端方便开发者与Google Play Store API进行通信。
- **使用自定义客户端**`NewWithClient` 函数允许开发者使用自定义的http客户端创建并返回一个包含访问androidpublisher API所需凭证的http客户端,增加了客户端的灵活性。 - **使用自定义客户端**`NewWithClient` 函数允许开发者使用自定义的HTTP客户端创建并返回一个包含访问 `androidpublisher` API所需凭证的HTTP客户端,增加了客户端的灵活性。
- **验证签名**`VerifySignature` 函数用于验证应用内购买的签名,确保支付信息的安全性和合法性。 - **验证签名**`VerifySignature` 函数用于验证应用内购买的签名,确保支付信息的安全性和合法性。
### 4.2 `s3` ### 4.2 s3
`s3` 模块主要用于与S3存储服务进行交互提供文件存储和管理的功能。其中,`ListBuckets` 函数可以列出S3存储桶的信息方便开发者管理存储桶中的文件。 `s3` 模块主要用于与S3存储服务进行交互提供文件存储和管理的功能。其中`ListBuckets` 函数可以列出S3存储桶的信息方便开发者管理存储桶中的文件。
### 4.3 `model` ### 4.3 model
`model` 模块定义了项目中使用的数据模型,这些数据模型通常与数据库表相对应,用于数据的存储和操作。例如: `model` 模块定义了项目中使用的数据模型,这些数据模型通常与数据库表相对应,用于数据的存储和操作。例如:
- **`GameMailMass`**:表示游戏邮件群发的数据模型,包含邮件的标题、内容、类型等信息。 - **GameMailMass**:表示游戏邮件群发的数据模型,包含邮件的标题、内容、类型等信息。
- **`GameBag`**:表示游戏背包的数据模型,包含用户标识、道具数据、图鉴、手势等信息。 - **GameBag**:表示游戏背包的数据模型,包含用户标识、道具数据、图鉴、手势等信息。
- **`MemberSave`**:(根据具体代码中的定义)可能表示用户会员信息的数据模型,用于存储用户的会员相关数据。 - **MemberSave**:(根据具体代码中的定义)可能表示用户会员信息的数据模型,用于存储用户的会员相关数据。
### 4.4 tools
`tools` 模块提供了一系列通用工具函数涵盖时间处理、Redis操作、道具数据处理等功能
- **时间处理**`time.go` 文件中的函数可以进行时间计算,如获取本周开始时间、计算两个时间间隔天数等。
- **Redis操作**`redis.go` 文件中的函数可以进行Redis的扫描操作支持批量获取大量数据。
- **通用工具**`tools.go` 文件中的函数提供了字符串处理、切片操作、道具数据合并等功能。
## 五、使用示例 ## 五、使用示例
@@ -115,6 +121,33 @@ func main() {
} }
``` ```
### 5.3 工具模块示例
以下是一个使用 `tools` 模块处理道具数据的示例代码:
```go
package main
import (
"fmt"
"github.com/ayflying/utility_go/tools"
)
func main() {
// 字符串转道具类型
str := "1|10|2|20"
result := tools.Tools.Spilt2Item(str)
fmt.Println("Spilt2Item result:", result)
// 切片换道具类型
slice := []int64{1, 10, 2, 20}
res := tools.Tools.Slice2Item(slice)
fmt.Println("Slice2Item result:", res)
// 道具格式转map
list := tools.Tools.Items2Map(result)
fmt.Println("Items2Map result:", list)
}
```
## 六、注意事项 ## 六、注意事项
- **自动生成文件**项目中有部分代码文件是由GoFrame CLI工具生成并维护的这些文件通常会标注有 `// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.` 注释。请不要手动修改这些文件,以免造成不必要的问题。 - **自动生成文件**项目中有部分代码文件是由GoFrame CLI工具生成并维护的这些文件通常会标注有 `// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.` 注释。请不要手动修改这些文件,以免造成不必要的问题。
- **版本兼容性**:在使用 `utility_go` 工具类库时请确保你的Go语言版本与工具类库的要求版本兼容。建议使用最新的Go语言版本以获得更好的性能和稳定性。 - **版本兼容性**:在使用 `utility_go` 工具类库时请确保你的Go语言版本与工具类库的要求版本兼容。建议使用最新的Go语言版本以获得更好的性能和稳定性。
@@ -124,4 +157,3 @@ func main() {
## 八、许可证信息 ## 八、许可证信息
`utility_go` 工具类库遵循MIT许可证你可以在项目的 `LICENSE` 文件中查看详细的许可证条款。请确保在使用该工具类库时遵守相关的许可证规定。 `utility_go` 工具类库遵循MIT许可证你可以在项目的 `LICENSE` 文件中查看详细的许可证条款。请确保在使用该工具类库时遵守相关的许可证规定。
```

View File

@@ -2,7 +2,7 @@
// versions: // versions:
// protoc-gen-go v1.28.1 // protoc-gen-go v1.28.1
// protoc v3.20.0 // protoc v3.20.0
// source: pgk/v1/pgk.proto // source: pkg/v1/pkg.proto
package v1 package v1
@@ -61,11 +61,11 @@ func (x NoticeType) String() string {
} }
func (NoticeType) Descriptor() protoreflect.EnumDescriptor { func (NoticeType) Descriptor() protoreflect.EnumDescriptor {
return file_pgk_v1_pgk_proto_enumTypes[0].Descriptor() return file_pkg_v1_pkg_proto_enumTypes[0].Descriptor()
} }
func (NoticeType) Type() protoreflect.EnumType { func (NoticeType) Type() protoreflect.EnumType {
return &file_pgk_v1_pgk_proto_enumTypes[0] return &file_pkg_v1_pkg_proto_enumTypes[0]
} }
func (x NoticeType) Number() protoreflect.EnumNumber { func (x NoticeType) Number() protoreflect.EnumNumber {
@@ -74,7 +74,7 @@ func (x NoticeType) Number() protoreflect.EnumNumber {
// Deprecated: Use NoticeType.Descriptor instead. // Deprecated: Use NoticeType.Descriptor instead.
func (NoticeType) EnumDescriptor() ([]byte, []int) { func (NoticeType) EnumDescriptor() ([]byte, []int) {
return file_pgk_v1_pgk_proto_rawDescGZIP(), []int{0} return file_pkg_v1_pkg_proto_rawDescGZIP(), []int{0}
} }
// 排行榜数据 // 排行榜数据
@@ -92,7 +92,7 @@ type RankData struct {
func (x *RankData) Reset() { func (x *RankData) Reset() {
*x = RankData{} *x = RankData{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_pgk_v1_pgk_proto_msgTypes[0] mi := &file_pkg_v1_pkg_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -105,7 +105,7 @@ func (x *RankData) String() string {
func (*RankData) ProtoMessage() {} func (*RankData) ProtoMessage() {}
func (x *RankData) ProtoReflect() protoreflect.Message { func (x *RankData) ProtoReflect() protoreflect.Message {
mi := &file_pgk_v1_pgk_proto_msgTypes[0] mi := &file_pkg_v1_pkg_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -118,7 +118,7 @@ func (x *RankData) ProtoReflect() protoreflect.Message {
// Deprecated: Use RankData.ProtoReflect.Descriptor instead. // Deprecated: Use RankData.ProtoReflect.Descriptor instead.
func (*RankData) Descriptor() ([]byte, []int) { func (*RankData) Descriptor() ([]byte, []int) {
return file_pgk_v1_pgk_proto_rawDescGZIP(), []int{0} return file_pkg_v1_pkg_proto_rawDescGZIP(), []int{0}
} }
func (x *RankData) GetId() int64 { func (x *RankData) GetId() int64 {
@@ -149,10 +149,10 @@ func (x *RankData) GetUpdateTs() int64 {
return 0 return 0
} }
var File_pgk_v1_pgk_proto protoreflect.FileDescriptor var File_pkg_v1_pkg_proto protoreflect.FileDescriptor
var file_pgk_v1_pgk_proto_rawDesc = []byte{ var file_pkg_v1_pkg_proto_rawDesc = []byte{
0x0a, 0x10, 0x70, 0x67, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x67, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x0a, 0x10, 0x70, 0x6b, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6b, 0x67, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x22, 0x61, 0x0a, 0x08, 0x52, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x22, 0x61, 0x0a, 0x08, 0x52,
0x61, 0x6e, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x61, 0x6e, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65,
@@ -166,29 +166,29 @@ var file_pgk_v1_pgk_proto_rawDesc = []byte{
0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x4d, 0x53, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x4f, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x4d, 0x53, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x4f,
0x49, 0x43, 0x45, 0x10, 0x04, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x49, 0x43, 0x45, 0x10, 0x04, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x79, 0x66, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x2f, 0x75, 0x74, 0x69, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x79, 0x66, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x2f, 0x75, 0x74, 0x69,
0x6c, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x67, 0x6b, 0x2f, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x67, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
file_pgk_v1_pgk_proto_rawDescOnce sync.Once file_pkg_v1_pkg_proto_rawDescOnce sync.Once
file_pgk_v1_pgk_proto_rawDescData = file_pgk_v1_pgk_proto_rawDesc file_pkg_v1_pkg_proto_rawDescData = file_pkg_v1_pkg_proto_rawDesc
) )
func file_pgk_v1_pgk_proto_rawDescGZIP() []byte { func file_pkg_v1_pkg_proto_rawDescGZIP() []byte {
file_pgk_v1_pgk_proto_rawDescOnce.Do(func() { file_pkg_v1_pkg_proto_rawDescOnce.Do(func() {
file_pgk_v1_pgk_proto_rawDescData = protoimpl.X.CompressGZIP(file_pgk_v1_pgk_proto_rawDescData) file_pkg_v1_pkg_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_v1_pkg_proto_rawDescData)
}) })
return file_pgk_v1_pgk_proto_rawDescData return file_pkg_v1_pkg_proto_rawDescData
} }
var file_pgk_v1_pgk_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_pkg_v1_pkg_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_pgk_v1_pgk_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_pkg_v1_pkg_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_pgk_v1_pgk_proto_goTypes = []interface{}{ var file_pkg_v1_pkg_proto_goTypes = []interface{}{
(NoticeType)(0), // 0: package.NoticeType (NoticeType)(0), // 0: package.NoticeType
(*RankData)(nil), // 1: package.RankData (*RankData)(nil), // 1: package.RankData
} }
var file_pgk_v1_pgk_proto_depIdxs = []int32{ var file_pkg_v1_pkg_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type 0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type 0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension type_name
@@ -196,13 +196,13 @@ var file_pgk_v1_pgk_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for field type_name 0, // [0:0] is the sub-list for field type_name
} }
func init() { file_pgk_v1_pgk_proto_init() } func init() { file_pkg_v1_pkg_proto_init() }
func file_pgk_v1_pgk_proto_init() { func file_pkg_v1_pkg_proto_init() {
if File_pgk_v1_pgk_proto != nil { if File_pkg_v1_pkg_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled { if !protoimpl.UnsafeEnabled {
file_pgk_v1_pgk_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { file_pkg_v1_pkg_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RankData); i { switch v := v.(*RankData); i {
case 0: case 0:
return &v.state return &v.state
@@ -219,19 +219,19 @@ func file_pgk_v1_pgk_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pgk_v1_pgk_proto_rawDesc, RawDescriptor: file_pkg_v1_pkg_proto_rawDesc,
NumEnums: 1, NumEnums: 1,
NumMessages: 1, NumMessages: 1,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },
GoTypes: file_pgk_v1_pgk_proto_goTypes, GoTypes: file_pkg_v1_pkg_proto_goTypes,
DependencyIndexes: file_pgk_v1_pgk_proto_depIdxs, DependencyIndexes: file_pkg_v1_pkg_proto_depIdxs,
EnumInfos: file_pgk_v1_pgk_proto_enumTypes, EnumInfos: file_pkg_v1_pkg_proto_enumTypes,
MessageInfos: file_pgk_v1_pgk_proto_msgTypes, MessageInfos: file_pkg_v1_pkg_proto_msgTypes,
}.Build() }.Build()
File_pgk_v1_pgk_proto = out.File File_pkg_v1_pkg_proto = out.File
file_pgk_v1_pgk_proto_rawDesc = nil file_pkg_v1_pkg_proto_rawDesc = nil
file_pgk_v1_pgk_proto_goTypes = nil file_pkg_v1_pkg_proto_goTypes = nil
file_pgk_v1_pgk_proto_depIdxs = nil file_pkg_v1_pkg_proto_depIdxs = nil
} }

View File

@@ -2,7 +2,6 @@ package aycache
import ( import (
"github.com/ayflying/utility_go/pkg/aycache/drive" "github.com/ayflying/utility_go/pkg/aycache/drive"
drive2 "github.com/ayflying/utility_go/pkg/aycache/drive"
"github.com/gogf/gf/v2/os/gcache" "github.com/gogf/gf/v2/os/gcache"
) )
@@ -24,13 +23,13 @@ func New(_name ...string) gcache.Adapter {
} }
switch name { switch name {
case "cache": case "cache":
cacheAdapterObj = drive2.NewAdapterMemory() cacheAdapterObj = drive.NewAdapterMemory()
case "redis": case "redis":
cacheAdapterObj = drive2.NewAdapterRedis() cacheAdapterObj = drive.NewAdapterRedis()
case "file": case "file":
cacheAdapterObj = drive2.NewAdapterFile("runtime/cache") cacheAdapterObj = drive.NewAdapterFile("runtime/cache")
case "es": //case "es":
cacheAdapterObj = drive.NewAdapterElasticsearch([]string{"http://127.0.0.1:9200"}) //cacheAdapterObj = drive.NewAdapterElasticsearch("http://127.0.0.1:9200"})
} }
//var client = gcache.New() //var client = gcache.New()

21
cmd/load.go Normal file
View File

@@ -0,0 +1,21 @@
package cmd
import (
"github.com/ayflying/utility_go/controller/callback"
"github.com/gogf/gf/v2/net/ghttp"
)
// 注册游客方法
func RegistrationAnonymous(group *ghttp.RouterGroup) (res []interface{}) {
group.Bind(
callback.NewV1(),
)
return
}
// 注册用户方法
func RegistrationUser(group *ghttp.RouterGroup) (res []interface{}) {
group.Bind()
return
}

View File

@@ -0,0 +1,83 @@
package elasticsearch
import (
"github.com/elastic/go-elasticsearch/v8"
)
var (
es *elasticsearch.TypedClient
)
type elastic struct {
client *elasticsearch.TypedClient
}
//func (d *Driver) Insert(ctx context.Context, table string, data interface{}, batch ...int) (res sql.Result, err error) {
//
// return
//}
//
//// createIndex 创建索引
//func (d *Driver) CreateIndex(name string) {
//
// resp, err := d.client.Indices.
// Create(name).
// Do(context.Background())
// if err != nil {
// fmt.Printf("create index failed, err:%v\n", err)
// return
// }
// fmt.Printf("index:%#v\n", resp.Index)
//}
//
//// indexDocument 索引文档
//func (d *Driver) IndexDocument(name string, key string, data interface{}) {
//
// // 添加文档
// resp, err := d.client.Index(name).
// Id(key).
// Document(data).
// Do(context.Background())
// if err != nil {
// fmt.Printf("indexing document failed, err:%v\n", err)
// return
// }
// fmt.Printf("result:%#v\n", resp.Result)
//}
//
//// getDocument 获取文档
//func (d *Driver) Get(name string, id string) (res json.RawMessage) {
// resp, err := d.client.Get(name, id).
// Do(context.Background())
// if err != nil {
// fmt.Printf("get document by id failed, err:%v\n", err)
// return
// }
// fmt.Printf("fileds:%d\n", resp.Source_)
// res = resp.Source_
// return
//}
//
//// updateDocument 更新文档
//func (d *Driver) UpdateDocument(name string, key string, data interface{}) {
//
// resp, err := d.client.Update(name, key).
// Doc(data). // 使用结构体变量更新
// Do(context.Background())
// if err != nil {
// fmt.Printf("update document failed, err:%v\n", err)
// return
// }
// fmt.Printf("result:%v\n", resp.Result)
//}
//
//// deleteDocument 删除 document
//func (d *Driver) DeleteDocument(name string, key string) {
// resp, err := d.client.Delete(name, key).
// Do(context.Background())
// if err != nil {
// fmt.Printf("delete document failed, err:%v\n", err)
// return
// }
// fmt.Printf("result:%v\n", resp.Result)
//}

View File

@@ -0,0 +1,39 @@
package elasticsearch
import (
"database/sql"
"github.com/elastic/go-elasticsearch/v8"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
)
func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
var (
source string
underlyingDriverName = "elasticsearch"
)
source = config.Host
cfg := elasticsearch.Config{
Addresses: []string{
config.Host,
},
}
es, err = elasticsearch.NewTypedClient(cfg)
//if err != nil {
// fmt.Printf("elasticsearch.NewTypedClient failed, err:%v\n", err)
// return
//}
if db, err = sql.Open(underlyingDriverName, source); err != nil {
err = gerror.WrapCodef(
gcode.CodeDbOperationError, err,
`sql.Open failed for driver "%s" by source "%s"`, underlyingDriverName, source,
)
return nil, err
}
return
}

View File

@@ -0,0 +1,47 @@
package elasticsearch
import (
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// Driver is the driver for mysql database.
type Driver struct {
*gdb.Core
}
const (
quoteChar = "`"
)
func init() {
var (
err error
driverObj = New()
driverNames = g.SliceStr{"es", "elasticsearch"}
)
for _, driverName := range driverNames {
if err = gdb.Register(driverName, driverObj); err != nil {
panic(err)
}
}
}
// New create and returns a driver that implements gdb.Driver, which supports operations for MySQL.
func New() gdb.Driver {
return &Driver{}
}
// New creates and returns a database object for mysql.
// It implements the interface of gdb.Driver for extra database driver installation.
func (d *Driver) New(core *gdb.Core, node *gdb.ConfigNode) (res gdb.DB, err error) {
res = &Driver{
Core: core,
}
return
}
// GetChars returns the security char for this type of database.
func (d *Driver) GetChars() (charLeft string, charRight string) {
return quoteChar, quoteChar
}

53
drivers/db/found/found.go Normal file
View File

@@ -0,0 +1,53 @@
package found
import (
"database/sql"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// Driver is the driver for mysql database.
type Driver struct {
*gdb.Core
}
func (d *Driver) Open(config *gdb.ConfigNode) (*sql.DB, error) {
//TODO implement me
panic("implement me")
}
const (
quoteChar = "`"
)
func init() {
var (
err error
driverObj = New()
driverNames = g.SliceStr{"es", "found"}
)
for _, driverName := range driverNames {
if err = gdb.Register(driverName, driverObj); err != nil {
panic(err)
}
}
}
// New create and returns a driver that implements gdb.Driver, which supports operations for MySQL.
func New() gdb.Driver {
return &Driver{}
}
// New creates and returns a database object for mysql.
// It implements the interface of gdb.Driver for extra database driver installation.
func (d *Driver) New(core *gdb.Core, node *gdb.ConfigNode) (res gdb.DB, err error) {
res = &Driver{
Core: core,
}
return
}
// GetChars returns the security char for this type of database.
func (d *Driver) GetChars() (charLeft string, charRight string) {
return quoteChar, quoteChar
}

4
go.mod
View File

@@ -12,6 +12,8 @@ require (
github.com/goccy/go-json v0.10.4 github.com/goccy/go-json v0.10.4
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.0 github.com/gogf/gf/contrib/config/apollo/v2 v2.9.0
github.com/gogf/gf/v2 v2.9.0 github.com/gogf/gf/v2 v2.9.0
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20241220152942-06eb5c6e8230 github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20241220152942-06eb5c6e8230
github.com/minio/minio-go/v7 v7.0.85 github.com/minio/minio-go/v7 v7.0.85
github.com/xuri/excelize/v2 v2.9.0 github.com/xuri/excelize/v2 v2.9.0
@@ -40,9 +42,7 @@ require (
github.com/go-pay/xtime v0.0.2 // indirect github.com/go-pay/xtime v0.0.2 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/gax-go/v2 v2.0.5 // indirect github.com/googleapis/gax-go/v2 v2.0.5 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect github.com/grokify/html-strip-tags-go v0.1.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/compress v1.17.11 // indirect

View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"github.com/ayflying/utility_go/internal/model/do" "github.com/ayflying/utility_go/internal/model/do"
"github.com/ayflying/utility_go/internal/model/entity" "github.com/ayflying/utility_go/internal/model/entity"
"github.com/ayflying/utility_go/pgk"
"github.com/ayflying/utility_go/pkg" "github.com/ayflying/utility_go/pkg"
service2 "github.com/ayflying/utility_go/service" service2 "github.com/ayflying/utility_go/service"
"github.com/ayflying/utility_go/tools" "github.com/ayflying/utility_go/tools"
@@ -216,9 +215,28 @@ func (s *sGameAct) Save(actId int) (err error) {
// 清空GetRedDot缓存 // 清空GetRedDot缓存
func (s *sGameAct) RefreshGetRedDotCache(uid int64) { func (s *sGameAct) RefreshGetRedDotCache(uid int64) {
cacheKey := fmt.Sprintf("gameAct:GetRedDot:%s:%d", gtime.Now().Format("d"), uid) cacheKey := fmt.Sprintf("gameAct:GetRedDot:%s:%d", gtime.Now().Format("d"), uid)
_, err := pgk.Cache("redis").Remove(gctx.New(), cacheKey) _, err := pkg.Cache("redis").Remove(gctx.New(), cacheKey)
if err != nil { if err != nil {
g.Log().Error(ctx, err) g.Log().Error(ctx, err)
g.Dump(err) g.Dump(err)
} }
} }
func (s *sGameAct) Del(uid int64, actId int) {
if uid == 0 || actId == 0 {
g.Log().Error(ctx, "当前参数为空")
return
}
// 构造缓存键名
keyCache := fmt.Sprintf("act:%v:%v", actId, uid)
//删除活动缓存
g.Redis("redis").Del(ctx, keyCache)
//删除当前活动储存
g.Model(Name).Where(do.GameAct{
Uid: uid,
ActId: actId,
}).Delete()
}

View File

@@ -3,7 +3,7 @@ package systemCron
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
v1 "github.com/ayflying/utility_go/api/pgk/v1" v1 "github.com/ayflying/utility_go/api/pkg/v1"
"github.com/ayflying/utility_go/pkg/notice" "github.com/ayflying/utility_go/pkg/notice"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gclient" "github.com/gogf/gf/v2/net/gclient"

View File

@@ -1,7 +1,7 @@
syntax = "proto3"; syntax = "proto3";
package package; package package;
option go_package = "github.com/ayflying/utility_go/api/pgk/v1"; option go_package = "github.com/ayflying/utility_go/api/pkg/v1";
// NoticeType // NoticeType

View File

@@ -1,7 +1,7 @@
package pgk package pgk
import ( import (
v1 "github.com/ayflying/utility_go/api/pgk/v1" v1 "github.com/ayflying/utility_go/api/pkg/v1"
"github.com/ayflying/utility_go/pkg/aycache" "github.com/ayflying/utility_go/pkg/aycache"
"github.com/ayflying/utility_go/pkg/notice" "github.com/ayflying/utility_go/pkg/notice"
"github.com/ayflying/utility_go/pkg/rank" "github.com/ayflying/utility_go/pkg/rank"

View File

@@ -2,7 +2,7 @@ package rank
import ( import (
"fmt" "fmt"
v1 "github.com/ayflying/utility_go/api/pgk/v1" v1 "github.com/ayflying/utility_go/api/pkg/v1"
"time" "time"
"github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/database/gredis"

View File

@@ -29,7 +29,7 @@ func New(_name ...string) gcache.Adapter {
case "file": case "file":
cacheAdapterObj = drive2.NewAdapterFile("runtime/cache") cacheAdapterObj = drive2.NewAdapterFile("runtime/cache")
case "es": case "es":
cacheAdapterObj = drive.NewAdapterElasticsearch([]string{"http://127.0.0.1:9200"}) cacheAdapterObj = drive.NewAdapterElasticsearch(_name[1])
} }
//var client = gcache.New() //var client = gcache.New()

View File

@@ -2,23 +2,51 @@ package drive
import ( import (
"context" "context"
"fmt"
"github.com/elastic/go-elasticsearch/v8"
"github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcache" "github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/util/gconv"
"time" "time"
) )
var (
adapterElasticsearchClient gcache.Adapter
)
type AdapterElasticsearch struct { type AdapterElasticsearch struct {
//FilePath string client *elasticsearch.TypedClient
Addresses []string name string
} }
func (a AdapterElasticsearch) Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) error { func (a AdapterElasticsearch) Set(ctx context.Context, _key interface{}, value interface{}, duration time.Duration) (err error) {
//TODO implement me key := gconv.String(_key)
panic("implement me") data := gconv.Map(value)
if duration > 0 {
data["delete_time"] = time.Now().Add(duration)
}
_, err = a.client.Index(a.name).Id(key).
Document(data).Do(ctx)
if err != nil {
fmt.Printf("indexing document failed, err:%v\n", err)
return
}
return
} }
func (a AdapterElasticsearch) SetMap(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error { func (a AdapterElasticsearch) SetMap(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error {
//TODO implement me for k, v := range data {
save := gconv.Map(v)
if duration > 0 {
save["delete_time"] = time.Now().Add(duration)
}
key := gconv.String(k)
a.client.Index(a.name).Id(key).
Document(save).Do(ctx)
}
panic("implement me") panic("implement me")
} }
@@ -37,9 +65,17 @@ func (a AdapterElasticsearch) SetIfNotExistFuncLock(ctx context.Context, key int
panic("implement me") panic("implement me")
} }
func (a AdapterElasticsearch) Get(ctx context.Context, key interface{}) (*gvar.Var, error) { func (a AdapterElasticsearch) Get(ctx context.Context, key interface{}) (res *gvar.Var, err error) {
//TODO implement me _key := gconv.String(key)
panic("implement me") resp, err := a.client.Get(a.name, _key).
Do(context.Background())
if err != nil {
fmt.Printf("get document by id failed, err:%v\n", err)
return
}
fmt.Printf("fileds:%s\n", resp.Source_)
res = gvar.New(resp.Source_)
return
} }
func (a AdapterElasticsearch) GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) { func (a AdapterElasticsearch) GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) {
@@ -82,9 +118,26 @@ func (a AdapterElasticsearch) Values(ctx context.Context) (values []interface{},
panic("implement me") panic("implement me")
} }
func (a AdapterElasticsearch) Update(ctx context.Context, key interface{}, value interface{}) (oldValue *gvar.Var, exist bool, err error) { func (a AdapterElasticsearch) Update(ctx context.Context, _key interface{}, value interface{}) (oldValue *gvar.Var, exist bool, err error) {
//TODO implement me key := gconv.String(_key)
panic("implement me") data := gconv.Map(value)
oldValue, err = a.Get(ctx, key)
if err != nil {
exist = false
} else {
for k, v := range oldValue.Map() {
if _, ok := data[k]; !ok {
data[k] = v
}
}
}
_, err = a.client.Update(a.name, key).
Doc(data).Do(context.Background())
if err != nil {
return
}
return
} }
func (a AdapterElasticsearch) UpdateExpire(ctx context.Context, key interface{}, duration time.Duration) (oldDuration time.Duration, err error) { func (a AdapterElasticsearch) UpdateExpire(ctx context.Context, key interface{}, duration time.Duration) (oldDuration time.Duration, err error) {
@@ -98,8 +151,15 @@ func (a AdapterElasticsearch) GetExpire(ctx context.Context, key interface{}) (t
} }
func (a AdapterElasticsearch) Remove(ctx context.Context, keys ...interface{}) (lastValue *gvar.Var, err error) { func (a AdapterElasticsearch) Remove(ctx context.Context, keys ...interface{}) (lastValue *gvar.Var, err error) {
//TODO implement me //获取keys最后一个
panic("implement me") lastKey := keys[len(keys)-1]
lastValue, _ = a.Get(ctx, lastKey)
for k := range keys {
key := gconv.String(k)
a.client.Delete(a.name, key).Do(ctx)
}
return
} }
func (a AdapterElasticsearch) Clear(ctx context.Context) error { func (a AdapterElasticsearch) Clear(ctx context.Context) error {
@@ -112,8 +172,17 @@ func (a AdapterElasticsearch) Close(ctx context.Context) error {
panic("implement me") panic("implement me")
} }
func NewAdapterElasticsearch(addresses []string) gcache.Adapter { func NewAdapterElasticsearch(name string) gcache.Adapter {
return &AdapterElasticsearch{
Addresses: addresses, if adapterElasticsearchClient == nil {
_cfg, _ := g.Cfg().Get(gctx.New(), "elasticsearch")
var cfg elasticsearch.Config
_cfg.Scan(&cfg)
es, _ := elasticsearch.NewTypedClient(cfg)
adapterElasticsearchClient = &AdapterElasticsearch{
client: es,
name: name,
} }
} }
return adapterElasticsearchClient
}

View File

@@ -16,17 +16,6 @@ type AdapterFile struct {
} }
func (a AdapterFile) Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) error { func (a AdapterFile) Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) error {
//defer a.handleLruKey(ctx, key)
//expireTime := a.getInternalExpire(duration)
//a.data.Set(key, memoryDataItem{
// a: value,
// a: expireTime,
//})
//c.eventList.PushBack(&adapterMemoryEvent{
// k: key,
// e: expireTime,
//})
arr := strings.Split(":", gconv.String(key)) arr := strings.Split(":", gconv.String(key))
fileName := path.Join(arr...) fileName := path.Join(arr...)
return gfile.PutBytes(fileName, gconv.Bytes(value)) return gfile.PutBytes(fileName, gconv.Bytes(value))

View File

@@ -19,7 +19,6 @@ func NewAdapterRedis() gcache.Adapter {
redisObj, _ := gredis.New(cfg) redisObj, _ := gredis.New(cfg)
//adapterRedisClient = gcache.NewAdapterRedis(g.Redis("default")) //adapterRedisClient = gcache.NewAdapterRedis(g.Redis("default"))
adapterRedisClient = gcache.NewAdapterRedis(redisObj) adapterRedisClient = gcache.NewAdapterRedis(redisObj)
adapterRedisCache.SetAdapter(adapterRedisClient) adapterRedisCache.SetAdapter(adapterRedisClient)
} }
return adapterRedisCache return adapterRedisCache

189
pkg/config/config.go Normal file
View File

@@ -0,0 +1,189 @@
package config
import (
"fmt"
"github.com/apolloconfig/agollo/v4"
apolloConfig "github.com/apolloconfig/agollo/v4/env/config"
"github.com/apolloconfig/agollo/v4/storage"
"github.com/gogf/gf/contrib/config/apollo/v2"
"github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gres"
"github.com/gogf/gf/v2/text/gstr"
"sync"
)
var (
//ApolloCfg *apolloConfig.AppConfig
ApolloCfg *apollo.Config
ApolloListener []string
Item2Obj = map[string]Load{}
)
// load接口定义了Load方法用于加载数据
type Load interface {
Load(cfg ...string)
}
func NewV1() *Cfg {
return &Cfg{}
}
type Cfg struct {
Lock sync.Mutex
}
func (c *Cfg) GetDbFile(name string) (res *g.Var, err error) {
get2, err := g.Model("game_config").
Where("name", name).Master().Value("data")
err = get2.Scan(&res)
if res == nil {
res = &gvar.Var{}
}
return
}
func (c *Cfg) GetFile(filename string, obj ...Load) (jsonObj *gjson.Json, err error) {
pathStr := "manifest/game/"
filePath := pathStr + filename + ".json"
//err := gres.Load(pathStr + filename)
//载入静态资源到文件对象
err = gres.Load(filePath)
var bytes []byte
if gfile.IsFile(filePath) {
bytes = gfile.GetBytes(filePath)
} else {
bytes = gres.GetContent(filePath)
}
jsonObj, err = gjson.DecodeToJson(bytes)
//g.Dump(filePath, jsonObj)
return
}
// getUrlFile 获取远程配置
func (c *Cfg) GetUrlFile(name string) (jsonObj *gjson.Json, err error) {
urlStr := fmt.Sprintf("http://sdf.sdfs.sdf/%s.json", name)
getUrl, err := g.Client().Discovery(nil).Get(nil, urlStr)
bytes := getUrl.ReadAll()
jsonObj, err = gjson.DecodeToJson(bytes)
return
}
// 获取阿波罗
//func (c *Cfg) GetApollo(name string, obj Load) (jsonObj *gjson.Json, err error) {
// jsonObj, err = c.GetApolloV2(name, obj)
// return
//
// //c.Lock.Lock()
// //defer c.Lock.Unlock()
// //
// //Item2Obj[name+".json"] = obj
// //var cfg = apolloConfig.AppConfig{
// // AppID: ApolloCfg.AppID,
// // Cluster: ApolloCfg.Cluster,
// // IP: ApolloCfg.IP,
// // NamespaceName: name + ".json",
// // Secret: ApolloCfg.Secret,
// // IsBackupConfig: ApolloCfg.IsBackupConfig,
// // BackupConfigPath: ApolloCfg.BackupConfigPath,
// // SyncServerTimeout: 60,
// // MustStart: true,
// //}
// ////cfg.NamespaceName = name + ".json"
// //
// //client, err := agollo.StartWithConfig(func() (*apolloConfig.AppConfig, error) {
// // return ApolloCfg, nil
// //})
// //if client == nil {
// // return
// //}
// //var getStr string
// //var getApollo *storage.Config
// //for range 5 {
// // getApollo = client.GetConfig(cfg.NamespaceName)
// // if getApollo != nil {
// // break
// // }
// // time.Sleep(time.Second * 5)
// //}
// //
// //if getApollo != nil {
// // getStr = getApollo.GetValue("content")
// // if getStr != "" {
// // //写入配置
// // gfile.PutContents(path.Join("manifest", "game", name+".json"), getStr)
// // }
// //} else {
// // jsonObj, err = c.GetFile(name)
// //}
// //jsonObj, err = gjson.DecodeToJson(getStr)
// ////首次运行加入监听器
// //if !gstr.InArray(ApolloListener, name) {
// // c2 := &CustomChangeListener{}
// // client.AddChangeListener(c2)
// // ApolloListener = append(ApolloListener, name)
// //}
// //return
//}
func (c *Cfg) GetApollo(name string, obj Load) (jsonObj *gjson.Json, err error) {
Item2Obj[name+".json"] = obj
// 接入阿波罗配置
ApolloCfg.NamespaceName = name + ".json"
adapter, err := apollo.New(nil, *ApolloCfg)
if err != nil {
g.Log().Fatalf(nil, `%+v`, err)
}
// Change the adapter of default configuration instance.
g.Cfg(name).SetAdapter(adapter)
//首次运行加入监听器
if !gstr.InArray(ApolloListener, name+".json") {
//放置监听器
client, _ := agollo.StartWithConfig(func() (*apolloConfig.AppConfig, error) {
return &apolloConfig.AppConfig{
AppID: ApolloCfg.AppID,
Cluster: ApolloCfg.Cluster,
NamespaceName: ApolloCfg.NamespaceName,
IP: ApolloCfg.IP,
IsBackupConfig: ApolloCfg.IsBackupConfig,
BackupConfigPath: ApolloCfg.BackupConfigPath,
Secret: ApolloCfg.Secret,
SyncServerTimeout: ApolloCfg.SyncServerTimeout,
MustStart: ApolloCfg.MustStart,
}, nil
})
c2 := &CustomChangeListener{}
client.AddChangeListener(c2)
ApolloListener = append(ApolloListener, name+".json")
}
cfg, err := g.Cfg(name).Get(nil, "content")
cfg.Scan(&jsonObj)
return
}
// 阿波罗监听器
type CustomChangeListener struct {
wg sync.WaitGroup
}
func (c *CustomChangeListener) OnChange(changeEvent *storage.ChangeEvent) {
g.Log().Debugf(nil, "当前Namespace变化了%v", changeEvent.Namespace)
filename := changeEvent.Namespace
if obj, ok := Item2Obj[filename]; ok {
//重载配置文件
obj.Load(changeEvent.Changes["content"].NewValue.(string))
}
}
func (c *CustomChangeListener) OnNewestChange(event *storage.FullChangeEvent) {
//write your code here
}

View File

@@ -5,97 +5,102 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/elastic/go-elasticsearch/v8" "github.com/elastic/go-elasticsearch/v8"
"github.com/elastic/go-elasticsearch/v8/typedapi/core/bulk"
"github.com/elastic/go-elasticsearch/v8/typedapi/core/delete"
"github.com/elastic/go-elasticsearch/v8/typedapi/core/search"
"github.com/elastic/go-elasticsearch/v8/typedapi/core/update"
"github.com/elastic/go-elasticsearch/v8/typedapi/types"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
) )
var ( var (
es *elasticsearch.TypedClient es *elasticsearch.TypedClient
) )
type elastic struct { type Elastic struct {
client *elasticsearch.TypedClient client *elasticsearch.TypedClient
name string
} }
func New(name ...string) *elastic { func NewV1(name string) *Elastic {
// ES 配置 var cfg elasticsearch.Config
cfg := elasticsearch.Config{ _cfg := g.Cfg().MustGetWithEnv(gctx.New(), "elasticsearch")
Addresses: []string{ _cfg.Scan(&cfg)
"http://ay.cname.com:9200",
},
}
if es == nil { if es == nil {
var err error var err error
es, err = elasticsearch.NewTypedClient(cfg) es, err = elasticsearch.NewTypedClient(cfg)
if err != nil { if err != nil {
fmt.Printf("elasticsearch.NewTypedClient failed, err:%v\n", err) fmt.Printf("elasticsearch.NewTypedClient failed, err:%v\n", err)
return &elastic{} return &Elastic{}
} }
} }
return &elastic{ return &Elastic{
client: es, client: es,
name: name,
}
} }
} //// Create 创建索引
//func (s *Elastic) Create(ctx context.Context) {
// createIndex 创建索引 // resp, err := s.client.Indices.
func (s *elastic) CreateIndex(name string) { // Create(s.name).Do(ctx)
resp, err := s.client.Indices. // if err != nil {
Create(name). // fmt.Printf("create index failed, err:%v\n", err)
Do(context.Background()) // return
if err != nil { // }
fmt.Printf("create index failed, err:%v\n", err) // fmt.Printf("index:%#v\n", resp.Index)
return //}
}
fmt.Printf("index:%#v\n", resp.Index)
}
// indexDocument 索引文档
func (s *elastic) IndexDocument(name string, key string, data interface{}) {
// Set 索引文档
func (s *Elastic) Set(ctx context.Context, key string, data interface{}) (err error) {
// 添加文档 // 添加文档
resp, err := s.client.Index(name). _, err = s.client.Index(s.name).Id(key).Document(data).Do(ctx)
Id(key).
Document(data).
Do(context.Background())
if err != nil {
fmt.Printf("indexing document failed, err:%v\n", err)
return
}
fmt.Printf("result:%#v\n", resp.Result)
}
// getDocument 获取文档
func (s *elastic) GetDocument(name string, id string) (res json.RawMessage) {
resp, err := s.client.Get(name, id).
Do(context.Background())
if err != nil {
fmt.Printf("get document by id failed, err:%v\n", err)
return
}
fmt.Printf("fileds:%s\n", resp.Source_)
res = resp.Source_
return return
} }
// updateDocument 更新文档 // SetBulk 批量添加文档
func (s *elastic) UpdateDocument(name string, key string, data interface{}) { func (s *Elastic) SetBulk(ctx context.Context, data []any) (err error) {
var save *bulk.Request
resp, err := s.client.Update(name, key). save = &bulk.Request{
Doc(data). // 使用结构体变量更新 data,
Do(context.Background()) }
if err != nil { s.client.Bulk().Index(s.name).Request(save).Do(ctx)
fmt.Printf("update document failed, err:%v\n", err)
return return
} }
fmt.Printf("result:%v\n", resp.Result)
}
// deleteDocument 删除 document // Get 获取文档
func (s *elastic) DeleteDocument(name string, key string) { func (s *Elastic) Get(ctx context.Context, id string) (res json.RawMessage, err error) {
resp, err := s.client.Delete(name, key). get, err := s.client.Get(s.name, id).Do(ctx)
Do(context.Background())
if err != nil { if err != nil {
fmt.Printf("delete document failed, err:%v\n", err)
return return
} }
fmt.Printf("result:%v\n", resp.Result) res = get.Source_
return
}
// Update 更新文档
func (s *Elastic) Update(ctx context.Context, key string, data interface{}) (res *update.Response, err error) {
res, err = s.client.Update(s.name, key).Doc(data).Do(ctx)
return
}
// Delete 删除 document
func (s *Elastic) Delete(ctx context.Context, key string) (res *delete.Response, err error) {
res, err = s.client.Delete(s.name, key).Do(ctx)
if err != nil {
return
}
return
}
// Select 查询
func (s *Elastic) Select(ctx context.Context, query *types.MatchAllQuery) (res *search.Response, err error) {
res, err = s.client.Search(). //Index("my_index").
Request(&search.Request{
Query: &types.Query{
MatchAll: &types.MatchAllQuery{},
},
}).Do(ctx)
return
} }

View File

@@ -1,7 +1,7 @@
package notice package notice
import ( import (
v1 "github.com/ayflying/utility_go/api/pgk/v1" v1 "github.com/ayflying/utility_go/api/pkg/v1"
"github.com/ayflying/utility_go/pkg/notice/drive" "github.com/ayflying/utility_go/pkg/notice/drive"
) )

View File

@@ -1,8 +1,10 @@
package pkg package pkg
import ( import (
v1 "github.com/ayflying/utility_go/api/pgk/v1" v1 "github.com/ayflying/utility_go/api/pkg/v1"
"github.com/ayflying/utility_go/pkg/aycache" "github.com/ayflying/utility_go/pkg/aycache"
"github.com/ayflying/utility_go/pkg/config"
"github.com/ayflying/utility_go/pkg/elasticsearch"
"github.com/ayflying/utility_go/pkg/notice" "github.com/ayflying/utility_go/pkg/notice"
"github.com/ayflying/utility_go/pkg/rank" "github.com/ayflying/utility_go/pkg/rank"
"github.com/ayflying/utility_go/pkg/s3" "github.com/ayflying/utility_go/pkg/s3"
@@ -33,3 +35,11 @@ func Rank() *rank.Mod {
func Websocket() *websocket.SocketV1 { func Websocket() *websocket.SocketV1 {
return websocket.NewV1() return websocket.NewV1()
} }
func Config() *config.Cfg {
return config.NewV1()
}
func Elastic(name string) *elasticsearch.Elastic {
return elasticsearch.NewV1(name)
}

View File

@@ -2,7 +2,7 @@ package rank
import ( import (
"fmt" "fmt"
v1 "github.com/ayflying/utility_go/api/pgk/v1" v1 "github.com/ayflying/utility_go/api/pkg/v1"
"time" "time"
"github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/database/gredis"

View File

@@ -33,6 +33,7 @@ type (
Save(actId int) (err error) Save(actId int) (err error)
// 清空GetRedDot缓存 // 清空GetRedDot缓存
RefreshGetRedDotCache(uid int64) RefreshGetRedDotCache(uid int64)
Del(uid int64, actId int)
} }
) )