Compare commits

..

29 Commits

Author SHA1 Message Date
ayflying
239115ead8 Merge branch 'master' of https://gitea.adesk.com/public_project/utility_go 2025-12-02 10:40:07 +08:00
ayflying
02b3e275d0 暂时屏蔽缓存的删除,来测试持久化 2025-12-02 10:39:53 +08:00
goldensea
9810e55a15 修复safeProperty方法 2025-12-01 17:18:17 +08:00
ayflying
03e4ad5db5 优化持久化代码,提高持久化性能 2025-12-01 15:37:32 +08:00
ayflying
eb94e50f02 改为3天持久化 2025-11-24 11:20:18 +08:00
liaoyulong
26444905cf 新增DelByStopRank方法 调整SetScore 2025-11-21 10:29:46 +08:00
liaoyulong
d82b12ddaf Revert "解决后续data解析到空map为nil的问题"
This reverts commit f3e1ad74b5.
2025-11-19 14:56:12 +08:00
liaoyulong
b9a7970699 新增set分数的函数 2025-11-19 13:38:40 +08:00
ayflying
6f25e7baf3 更新核心库版本 2025-11-17 11:56:24 +08:00
513ed653e2 防止传入非法的属性key 2025-10-31 14:38:38 +08:00
31cd9896b6 Merge branch 'master' of new-gitlab.adesk.com:public_project/utility_go 2025-10-30 16:24:46 +08:00
9c99508bdd 发送时额外增加超时时间, 每5000条+1秒 2025-10-30 16:24:44 +08:00
liaoyulong
f3e1ad74b5 解决后续data解析到空map为nil的问题 2025-10-28 20:43:25 +08:00
liaoyulong
ba0f9bfd98 新增通用方法 2025-10-27 18:20:26 +08:00
ayflying
d07881bc29 上传失败后,尝试使用自己的代理地址 2025-10-27 16:12:11 +08:00
cdcdac3531 测试代码 更新 2025-10-20 15:10:43 +08:00
0a19bb5518 Merge branch 'master' of new-gitlab.adesk.com:public_project/utility_go 2025-10-20 14:50:27 +08:00
c7409fbf02 注释更新 2025-10-20 14:50:26 +08:00
ayflying
82d3824cae 更新服务器代码通过判断本地配置文件决定需要更新的目录 2025-10-20 10:14:19 +08:00
ayflying
ba3c561c4c 服务增加不同架构的编译代码,区分windows与linux的相同方法进行交叉编译 2025-10-16 18:11:54 +08:00
27fed91922 替换值 2025-10-14 10:45:42 +08:00
19585af99f 新增onlyword字段设置 2025-10-14 10:45:23 +08:00
a752ef543c 正则修改 2025-10-13 11:00:04 +08:00
5614f678bd 替换转义字符 2025-10-11 16:07:27 +08:00
b10eaf5133 新增过滤字符 2025-10-11 16:02:14 +08:00
4c2435b14c 导出和记录属性的时候,替换特殊字符串 2025-10-11 10:07:52 +08:00
3d963e19e2 导出string类型错误修复 2025-10-09 11:22:09 +08:00
5148627d2d 新增一个导出相关的函数 2025-09-26 18:27:43 +08:00
da1e982ab5 新增日志传输存储类型 2025-09-26 17:34:01 +08:00
15 changed files with 467 additions and 57 deletions

View File

@@ -42,6 +42,9 @@ var (
getFileName, err := g.Cfg("hack").Get(ctx, "gfcli.build.name")
Filename := getFileName.String()
getPath, err := g.Cfg("hack").Get(ctx, "gfcli.build.path")
Path := getPath.String()
//获取版本号
getVersion, err := g.Cfg("hack").Get(ctx, "gfcli.build.version")
Version := getVersion.String()
@@ -89,7 +92,7 @@ var (
if v.Arch != "" && v.System != "" {
systemName = v.System + "_" + v.Arch
}
var filename = path.Join(Version, systemName, Filename)
var filename = path.Join(Path, Version, systemName, Filename)
g.Log().Debugf(ctx, "当前上传文件:"+filename)
url[v.S3], err = UploadS3(v.S3, filename)
@@ -109,9 +112,24 @@ var (
FileUrl: url[v.S3],
})
if err != nil {
Proxy := g.Cfg().MustGet(ctx, "update_proxy", "http://192.168.50.170:10808").String()
g.Log().Debugf(ctx, "切换代理进行上传:err=%v", err)
get, err = client.Proxy(Proxy).Post(ctx, address+"/callback/update", &UpdateReq{
// 读取HTTP代理环境变量小写/大写通常都兼容,部分系统可能用大写)
httpProxy := os.Getenv("http_proxy")
if httpProxy == "" {
httpProxy = os.Getenv("HTTP_PROXY")
}
if httpProxy == "" {
// 读取HTTPS代理环境变量
httpProxy = os.Getenv("https_proxy")
if httpProxy == "" {
httpProxy = os.Getenv("HTTPS_PROXY")
}
}
// 如果没有读取到本地的代理,使用配置上传
if httpProxy == "" {
httpProxy = g.Cfg().MustGet(ctx, "update_proxy", "http://192.168.50.173:10808").String()
}
g.Log().Debugf(ctx, "切换代理进行上传:ip=%v,err=%v", httpProxy, err)
get, err = client.Proxy(httpProxy).Post(ctx, address+"/callback/update", &UpdateReq{
FileUrl: url[v.S3],
})
}

15
go.mod
View File

@@ -7,12 +7,13 @@ require (
github.com/ayflying/excel2json v1.1.9
github.com/casdoor/casdoor-go-sdk v1.20.0
github.com/elastic/go-elasticsearch/v8 v8.19.0
github.com/getlantern/systray v1.2.2
github.com/go-pay/crypto v0.0.1
github.com/go-pay/gopay v1.5.114
github.com/go-pay/util v0.0.4
github.com/goccy/go-json v0.10.5
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.3
github.com/gogf/gf/v2 v2.9.3
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.4
github.com/gogf/gf/v2 v2.9.4
github.com/google/uuid v1.6.0
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250916043522-9a14e3273609
github.com/minio/minio-go/v7 v7.0.95
@@ -38,6 +39,12 @@ require (
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 // indirect
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 // indirect
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 // indirect
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 // indirect
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
@@ -45,6 +52,7 @@ require (
github.com/go-pay/smap v0.0.2 // indirect
github.com/go-pay/xlog v0.0.3 // indirect
github.com/go-pay/xtime v0.0.2 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/google/s2a-go v0.1.9 // indirect
@@ -64,7 +72,8 @@ require (
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.1.1 // indirect
github.com/olekukonko/tablewriter v1.0.9 // indirect
github.com/olekukonko/tablewriter v1.1.0 // indirect
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect

42
go.sum
View File

@@ -105,6 +105,20 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So=
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk=
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
github.com/getlantern/systray v1.2.2 h1:dCEHtfmvkJG7HZ8lS/sLklTH4RKUcIsKrAD9sThoEBE=
github.com/getlantern/systray v1.2.2/go.mod h1:pXFOI1wwqwYXEhLPm9ZGjS2u/vVELeIgNMY5HvhHhcE=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -130,15 +144,17 @@ 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-pay/xtime v0.0.2 h1:7YR4/iuELsEHpJ6LUO0SVK80hQxDO9MLCfuVYIiTCRM=
github.com/go-pay/xtime v0.0.2/go.mod h1:W1yRbJaSt4CSBcdAtLBQ8xajiN/Pl5hquGczUcUE9xE=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.3 h1:/IcE+DmlQDWeDjnkKWr1Rql7VCLUxEqz7gXoQKZHd8o=
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.3/go.mod h1:mek4CnNsvdum4jYhf0PzaIYzoSBuSvVXyuCZG4I9qvw=
github.com/gogf/gf/v2 v2.9.3 h1:qjN4s55FfUzxZ1AE8vUHNDX3V0eIOUGXhF2DjRTVZQ4=
github.com/gogf/gf/v2 v2.9.3/go.mod h1:w6rcfD13SmO7FKI80k9LSLiSMGqpMYp50Nfkrrc2sEE=
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.4 h1:l2vkPpqteotzpq0h5Qg6S/GK84WpPUZlRwPVfZSDbYs=
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.4/go.mod h1:mTfSf2Zm8+C49+rM7pK6AC8cwDSDxxwO8sLMNOl0yCI=
github.com/gogf/gf/v2 v2.9.4 h1:6vleEWypot9WBPncP2GjbpgAUeG6Mzb1YESb9nPMkjY=
github.com/gogf/gf/v2 v2.9.4/go.mod h1:Ukl+5HUH9S7puBmNLR4L1zUqeRwi0nrW4OigOknEztU=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@@ -266,6 +282,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250916043522-9a14e3273609 h1:LfPCMQ+fjqOLKNYrE1wCrmq2CX2ukY0AItPt2rneF4s=
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250916043522-9a14e3273609/go.mod h1:+mNMTBuDMdEGhWzoQgc6kBdqeaQpWh5ba8zqmp2MxCU=
github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
@@ -303,8 +321,10 @@ github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.1.1 h1:9Dfeed5/Mgaxb9lHRAftLK9pVfYETvHn+If6lywVhJc=
github.com/olekukonko/ll v0.1.1/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo=
github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8=
github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
@@ -323,8 +343,7 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
@@ -344,6 +363,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
@@ -402,8 +422,7 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
@@ -565,6 +584,7 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -576,6 +596,7 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
@@ -763,6 +784,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -26,6 +26,7 @@ var (
Name = "game_act"
ActList = gset.New(true)
RunTimeMax *gtime.Time
TaskMax int64 = 5
)
type sGameAct struct {
@@ -77,7 +78,7 @@ func (s *sGameAct) Info(uid int64, actId int) (data *g.Var, err error) {
_, err = g.Redis().Set(ctx, keyCache, data)
var CacheKey = fmt.Sprintf("act:update:%d", uid)
pkg.Cache("redis").Set(ctx, CacheKey, uid, time.Hour*24*1)
pkg.Cache("redis").Set(ctx, CacheKey, uid, time.Hour*24*3+time.Hour*12)
return
}
@@ -236,7 +237,7 @@ func (s *sGameAct) Save(ctx context.Context, actId int) (err error) {
}
//删除缓存
go s.DelCacheKey(ctx, v.ActId, v.Uid)
//s.DelCacheKey(ctx, v.ActId, v.Uid)
updateCount++
update = make([]*entity.GameAct, 0)
@@ -264,10 +265,10 @@ func (s *sGameAct) Save(ctx context.Context, actId int) (err error) {
return
}
for _, v2 := range add {
//删除缓存
go s.DelCacheKey(ctx, v2.ActId, v2.Uid)
}
//for _, v2 := range add {
// //删除缓存
// s.DelCacheKey(ctx, v2.ActId, v2.Uid)
//}
//g.Log().Debugf(ctx, "当前 %v 写入数据库: %v 条", actId, count)
add = make([]*entity.GameAct, 0)
@@ -311,7 +312,7 @@ func (s *sGameAct) SavesV2() (err error) {
go func() {
scanErr := tools.Redis.RedisScanV2("act:*", func(keys []string) error {
if gtime.Now().After(RunTimeMax) {
return errors.New("Redis扫描超时")
return errors.New("redis扫描超时")
}
for _, key := range keys {
if keyErr := s.SaveV2(ctx, key, addChan, updateChan); keyErr != nil {
@@ -421,12 +422,18 @@ func (s *sGameAct) SaveV2(ctx context.Context, cacheKey string, addChan, updateC
// @param update []*entity.GameAct: 更新数据
// @return err error: 返回错误信息
func (s *sGameAct) Cache2Sql(ctx context.Context, add, update []*entity.GameAct) {
tx, err := g.DB().Begin(ctx)
if err != nil {
g.Log().Error(ctx, err)
return
}
//批量写入数据库
updateCount := 0
var updateCount int64
if len(update) > 0 {
for _, v := range update {
v.UpdatedAt = gtime.Now()
updateRes, err2 := g.Model(Name).Where(do.GameAct{
updateRes, err2 := tx.Model(Name).Where(do.GameAct{
Uid: v.Uid,
ActId: v.ActId,
}).Data(v).Update()
@@ -438,10 +445,22 @@ func (s *sGameAct) Cache2Sql(ctx context.Context, add, update []*entity.GameAct)
g.Log().Error(ctx, "本次更新为0更新数据失败: %v", v)
continue
}
//删除缓存
s.DelCacheKey(ctx, v.ActId, v.Uid)
updateCount++
if updateCount > TaskMax {
g.Log().Debugf(ctx, "act当前更新数据库: %v 条", updateCount)
err = tx.Commit()
if err != nil {
g.Log().Debugf(ctx, "act当前更新数据库失败:%v", err)
return
}
updateCount = 0
tx, err = g.DB().Begin(ctx)
}
//删除缓存
//s.DelCacheKey(ctx, v.ActId, v.Uid)
}
//循环结束了,最后写入一波
g.Log().Debugf(ctx, "act当前更新数据库: %v 条", updateCount)
update = (update)[:0]
}
@@ -449,7 +468,7 @@ func (s *sGameAct) Cache2Sql(ctx context.Context, add, update []*entity.GameAct)
var addCount int64
if len(add) > 0 {
for _, v := range add {
addRes, err2 := g.Model(Name).Data(v).Insert()
addRes, err2 := tx.Model(Name).Data(v).Insert()
if err2 != nil {
g.Log().Error(ctx, err2)
continue
@@ -459,12 +478,26 @@ func (s *sGameAct) Cache2Sql(ctx context.Context, add, update []*entity.GameAct)
continue
}
addCount++
if addCount > TaskMax {
g.Log().Debugf(ctx, "act当前写入数据库: %v 条", addCount)
err = tx.Commit()
if err != nil {
g.Log().Debugf(ctx, "act当前写入数据库失败:%v", err)
return
}
addCount = 0
tx, err = g.DB().Begin(ctx)
}
//删除缓存
s.DelCacheKey(ctx, v.ActId, v.Uid)
//s.DelCacheKey(ctx, v.ActId, v.Uid)
}
//循环结束了,最后写入一波
g.Log().Debugf(ctx, "act当前写入数据库: %v 条", addCount)
add = (add)[:0]
}
err = tx.Commit()
return
}
@@ -478,8 +511,14 @@ func (s *sGameAct) Cache2SqlChan(ctx context.Context, addChan, updateChan chan *
addClosed := false
updateClosed := false
tx, err := g.DB().Begin(ctx)
if err != nil {
g.Log().Error(ctx, err)
return
}
// 使用链式安全模式
var db = g.Model(Name).Safe()
//var db = tx.Model(Name).Safe()
for {
//检查是否两个通道都已关闭且为空
@@ -493,7 +532,7 @@ func (s *sGameAct) Cache2SqlChan(ctx context.Context, addChan, updateChan chan *
addClosed = true // 仅标记关闭,不立即日志
continue
}
addRes, err2 := db.Data(v).Insert()
addRes, err2 := tx.Model(Name).Data(v).Insert()
if err2 != nil {
g.Log().Error(ctx, err2)
continue
@@ -504,8 +543,20 @@ func (s *sGameAct) Cache2SqlChan(ctx context.Context, addChan, updateChan chan *
}
row, _ := addRes.RowsAffected()
addCount += row
if addCount > TaskMax {
g.Log().Debugf(ctx, "act当前写入数据库: %v 条", addCount)
err = tx.Commit()
if err != nil {
g.Log().Debugf(ctx, "act当前写入数据库失败:%v", err)
return
}
addCount = 0
tx, err = g.DB().Begin(ctx)
}
//删除缓存
s.DelCacheKey(ctx, v.ActId, v.Uid)
//s.DelCacheKey(ctx, v.ActId, v.Uid)
case v, ok := <-updateChan:
if !ok {
@@ -513,7 +564,7 @@ func (s *sGameAct) Cache2SqlChan(ctx context.Context, addChan, updateChan chan *
continue
}
v.UpdatedAt = gtime.Now()
updateRes, err2 := db.Where(do.GameAct{
updateRes, err2 := tx.Model(Name).Where(do.GameAct{
Uid: v.Uid,
ActId: v.ActId,
}).Data(v).Update()
@@ -525,16 +576,29 @@ func (s *sGameAct) Cache2SqlChan(ctx context.Context, addChan, updateChan chan *
//g.Log().Error(ctx, "本次更新为0更新数据失败: %v", v)
continue
}
//删除缓存
s.DelCacheKey(ctx, v.ActId, v.Uid)
updateCount++
if updateCount > TaskMax {
g.Log().Debugf(ctx, "act当前写入数据库: %v 条", addCount)
err = tx.Commit()
if err != nil {
g.Log().Debugf(ctx, "act当前写入数据库失败:%v", err)
return
}
updateCount = 0
tx, err = g.DB().Begin(ctx)
}
//删除缓存
//s.DelCacheKey(ctx, v.ActId, v.Uid)
case <-ctx.Done():
g.Log().Debug(ctx, "act协程被上下文取消")
return
}
}
err = tx.Commit()
// 仅在所有通道处理完毕后打印最终计数(移除中间冗余日志)
g.Log().Debugf(ctx, "act当前写入数据库: %v 条", addCount)
g.Log().Debugf(ctx, "act当前更新数据库: %v 条", updateCount)
@@ -543,17 +607,19 @@ func (s *sGameAct) Cache2SqlChan(ctx context.Context, addChan, updateChan chan *
// 删除缓存key
func (s *sGameAct) DelCacheKey(ctx context.Context, aid int, uid int64) {
//如果有活跃,跳过删除
if getBool, _ := pkg.Cache("redis").
Contains(ctx, fmt.Sprintf("act:update:%d", uid)); getBool {
return
}
go func() {
//如果有活跃,跳过删除
if getBool, _ := pkg.Cache("redis").
Contains(ctx, fmt.Sprintf("act:update:%d", uid)); getBool {
return
}
cacheKey := fmt.Sprintf("act:%v:%v", aid, uid)
_, err := g.Redis().Del(ctx, cacheKey)
if err != nil {
g.Log().Error(ctx, err)
}
cacheKey := fmt.Sprintf("act:%v:%v", aid, uid)
_, err := g.Redis().Del(ctx, cacheKey)
if err != nil {
g.Log().Error(ctx, err)
}
}()
}
// 清空GetRedDot缓存

View File

@@ -10,6 +10,7 @@ import (
_ "github.com/ayflying/utility_go/internal/logic/gameKv"
_ "github.com/ayflying/utility_go/internal/logic/ip2region"
_ "github.com/ayflying/utility_go/internal/logic/logData"
_ "github.com/ayflying/utility_go/internal/logic/os"
_ "github.com/ayflying/utility_go/internal/logic/systemCron"
_ "github.com/ayflying/utility_go/internal/logic/systemLog"
)

View File

@@ -0,0 +1,7 @@
//go:build !windows
package os
func (s *sOS) start() {
}

41
internal/logic/os/os.go Normal file
View File

@@ -0,0 +1,41 @@
package os
import (
"github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/os/gcmd"
)
type systrayType struct {
Icon string `json:"icon" dc:"图标"`
Title string `json:"title" dc:"标题"`
Tooltip string `json:"tooltip" dc:"提示"`
}
type sOS struct {
systray *systrayType
}
func New() *sOS {
return &sOS{
systray: &systrayType{},
}
}
func init() {
service.RegisterOS(New())
}
func (s *sOS) Load(title string, tooltip string, ico string) {
if title == "" {
title = gcmd.GetArg(0).String()
}
if tooltip == "" {
tooltip = gcmd.GetArg(0).String()
}
s.systray = &systrayType{
Icon: ico,
Title: title,
Tooltip: tooltip,
}
s.start()
}

View File

@@ -0,0 +1,43 @@
//go:build windows
package os
import (
"os"
"github.com/getlantern/systray"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gfile"
)
func (s *sOS) start() {
// 系统托盘初始化(设置图标、右键菜单)
go systray.Run(s.onSystrayReady, s.onSystrayExit)
}
// 系统托盘初始化(设置图标、右键菜单)
func (s *sOS) onSystrayReady() {
iconByte := gfile.GetBytes(s.systray.Icon)
systray.SetIcon(iconByte)
systray.SetTitle(s.systray.Title)
systray.SetTooltip(s.systray.Tooltip)
mQuit := systray.AddMenuItem("退出", "退出应用")
// Sets the icon of a menu item. Only available on Mac and Windows.
//mQuit.SetIcon(iconByte)
go func() {
<-mQuit.ClickedCh
systray.Quit()
}()
}
func (s *sOS) onSystrayExit() {
// clean up here
g.Log().Debugf(gctx.New(), "系统托盘退出")
defer os.Exit(0)
}

View File

@@ -2,6 +2,7 @@ package systemLog
import (
"context"
v1 "github.com/ayflying/utility_go/api/admin/v1"
"github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/frame/g"

46
package/gamelog/export.go Normal file
View File

@@ -0,0 +1,46 @@
package gamelog
import (
"encoding/json"
"time"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
// 获取日志行
func (sdk *SDK) GetLogItem(uid, event string, property map[string]any, timezone string, customEventTime ...time.Time) string {
loc := time.Local
if _loc := getLocationMapValue(timezone); _loc != nil {
loc = _loc
}
if len(property) == 0 {
property = map[string]any{"ts": gtime.Now().Timestamp()}
}
var et *gtime.Time
if len(customEventTime) > 0 {
et = gtime.NewFromTime(customEventTime[0])
} else {
et = gtime.Now()
}
safeProperty(property)
pstr, err := json.Marshal(property)
if err != nil {
g.Log().Errorf(ctx, "GetLogItem Fail ! json marshal property err: %v", err)
return ""
}
item := []any{
uid,
event,
gconv.String(pstr),
et.TimestampMilli(),
et.In(loc).Format(datetimeFmt),
}
itemstr, err := json.Marshal(item)
if err != nil {
g.Log().Errorf(ctx, "GetLogItem Fail ! json marshal item err: %v", err)
return ""
}
return gconv.String(itemstr)
}

View File

@@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"
"sync"
"time"
@@ -15,11 +16,13 @@ import (
"github.com/gogf/gf/v2/net/gclient"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
type sendBody struct {
Pid string `json:"pid"`
Data [][]any `json:"data"`
Pid string `json:"pid"`
Data [][]any `json:"data"`
SaveType int `json:"save_type" dc:"0=文件存储, 1=kafka存储"`
}
// todo 游戏日志对象
@@ -41,7 +44,8 @@ type SDKConfig struct {
RetryN int // 每N次重试
ChanSize int // 信道大小, 默认1000
reportN int
reportN int
SendSaveType int // 发送存储类型, 默认不设置为0代表文件存储, 1代表走kafka可实同步日志
}
type SDK struct {
@@ -64,6 +68,45 @@ var (
)
var safePropertyRE = regexp.MustCompile(`[/"'\\\/]`)
// 设置某些字段只允许包含字母、数字和下划线
var onlyWordRE = regexp.MustCompile(`\W`)
var nonWordCharRes = regexp.MustCompile(`[^\w]`)
func hasNonWordChar(s string) bool {
// 匹配非 \w 字符的正则表达式
return nonWordCharRes.MatchString(s)
}
var onlyWordPropertyNames = map[string]struct{}{
"nickname": {},
}
func SetOnlyWordProperty(propertyNames ...string) {
for _, propertyName := range propertyNames {
onlyWordPropertyNames[propertyName] = struct{}{}
}
}
func safeProperty(property map[string]any) {
delkeys := []string{}
for k, v := range property {
if hasNonWordChar(k) {
delkeys = append(delkeys, k)
continue
}
if _, ok := onlyWordPropertyNames[k]; ok {
if _, ok := v.(string); ok {
property[k] = onlyWordRE.ReplaceAllString(gconv.String(v), "*")
}
}
}
for _, delkey := range delkeys {
delete(property, delkey)
}
}
func getLocationMapValue(key string) *time.Location {
// 1. 先尝试读
value, loaded := locationMap.Load(key)
@@ -276,6 +319,7 @@ func (sdk *SDK) Log(uid, event string, property map[string]any, timezone string,
if len(property) == 0 {
property = map[string]any{"ts": gtime.Now().Timestamp()}
}
safeProperty(property)
var et *gtime.Time
if len(customEventTime) > 0 {
et = gtime.NewFromTime(customEventTime[0])
@@ -358,7 +402,7 @@ func (sdk *SDK) flush() {
// 发送消息
func (sdk *SDK) send(logs []GameLog) {
waitSecond := time.Duration(sdk.sdkConfig.FlushInterval/4) * time.Second
waitSecond := time.Duration(sdk.sdkConfig.FlushInterval/4)*time.Second + time.Second*time.Duration(gconv.Int(len(logs)/5000))
timeoutCtx, cancel := context.WithTimeout(context.Background(), waitSecond)
defer cancel()
data := make([][]any, 0, len(logs))
@@ -379,8 +423,9 @@ func (sdk *SDK) send(logs []GameLog) {
}
// json化
sbody := sendBody{
Pid: sdk.sdkConfig.Pid,
Data: data,
Pid: sdk.sdkConfig.Pid,
Data: data,
SaveType: sdk.sdkConfig.SendSaveType,
}
jsonBody, err := json.Marshal(sbody)
if err != nil {

View File

@@ -14,15 +14,17 @@ import (
func TestGamelog(t *testing.T) {
glsdk, err := gamelog.INIT(&gamelog.SDKConfig{
// 必填
Pid: "test5", // 项目ID
BaseUrl: "http://47.76.178.47:10101", // 香港测试服上报地址
Pid: "test5", // 项目ID
// BaseUrl: "http://47.76.178.47:10101", // 香港测试服上报地址
BaseUrl: "http://101.37.28.111:10101", // 香港测试服上报地址
// BaseUrl: "http://127.0.0.1:10101", // 本次测试上报地址
ReportSk: "sngame2025", // xor混淆key
FlushInterval: 5, // 上报间隔
DiskBakPath: "gamelog", // 本地磁盘备份, 用于意外情况下临时保存日志, 请确保该目录持久化(容器内要挂载). 每次启动时或每N次上报时加载到失败队列
// 可填
RetryN: 2, // 默认每10次, 上传检查一次磁盘的失败数据
ChanSize: 500, // 默认1000, 信道size
RetryN: 2, // 默认每10次, 上传检查一次磁盘的失败数据
ChanSize: 500, // 默认1000, 信道size
SendSaveType: 2, // 发送存储类型, 默认不设置为0代表文件存储, 2代表走kafka可实同步日志
})
// 随机测试事件和属性

View File

@@ -2,9 +2,10 @@ package rank
import (
"fmt"
v1 "github.com/ayflying/utility_go/api/pkg/v1"
"time"
v1 "github.com/ayflying/utility_go/api/pkg/v1"
"github.com/gogf/gf/v2/database/gredis"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
@@ -98,6 +99,53 @@ func (r *F64CountRank) IncrScore(id int64, score int64) (curScore float64, err e
return
}
// SetScore 对指定ID的分数进行赋值,这样同分情况下先完成的在前面。
// 该方法首先更新成员的更新时间戳,然后更新成员的分数。
//
// 参数:
//
// id - 要操作的成员ID。
// score - 要更新的分数。
//
// 返回值:
//
// err - 操作过程中可能发生的错误。
//
// @Description:
// @receiver r
// @param id
// @param score
// @return err
func (r *F64CountRank) SetScore(id int64, score int) (err error) {
//如果分数小于0则删除
if score <= 0 {
err = r.DelScore(id)
if err != nil {
return
}
return
}
// 记录当前时间戳,用于更新成员的最新活动时间。
now := time.Now().UnixMilli()
// 将成员的更新时间戳加入到Redis的有序集合中确保成员的排序依据是最新的活动时间。
_, err = g.Redis().ZAdd(ctx, r.updateTs, &gredis.ZAddOption{}, gredis.ZAddMember{
Score: float64(now),
Member: id,
})
if err != nil {
return
}
// 覆盖成员的分数
_, err = g.Redis().ZAdd(ctx, r.name, &gredis.ZAddOption{}, gredis.ZAddMember{
Score: float64(score) + (3*1e13-float64(now))/1e14,
Member: id,
})
return
}
// todo暂时未使用
func (r *F64CountRank) GetCount() {
count, _ := g.Redis().ZCard(ctx, r.name)
@@ -141,6 +189,35 @@ func (r *F64CountRank) DelScore(id int64) (err error) {
return
}
// DelByStopRank 删除指定名次后的元素
func (r *F64CountRank) DelByStopRank(stop int64) (err error) {
// 初始化一个空的int64切片用于存储指定排名范围内的元素。
var members []int64
// 使用Redis的ZRange命令获取指定排名范围内的元素。
// 选项Rev设置为true表示按照分数从高到低的顺序返回元素。
get, err := g.Redis().ZRange(ctx, r.name, stop, 9999999,
gredis.ZRangeOption{
Rev: true,
})
// 使用Scan方法将获取到的元素扫描到members切片中。
err = get.Scan(&members)
// 如果扫描过程中出现错误,直接返回错误。
if err != nil {
return
}
// 遍历members切片对于每个元素使用ZRem命令从更新时间集合中删除对应的成员。
for _, member := range members {
_, err = g.Redis().ZRem(ctx, r.updateTs, member)
// 忽略ZRem操作的错误因为即使元素不存在ZRem也不会返回错误。
}
//删除超过9999的数据
g.Redis().ZRemRangeByRank(ctx, r.name, 0, -(stop + 1))
return
}
// DelByRank 根据排名范围删除元素。
// 该方法使用了Redis的有序集合数据结构通过ZRange和ZRemRangeByRank命令来实现。
// 参数start和stop定义了要删除的排名范围从start到stop包括start和stop

27
service/os.go Normal file
View File

@@ -0,0 +1,27 @@
// ================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// You can delete these comments if you wish manually maintain this interface file.
// ================================================================================
package service
type (
IOS interface {
Load(title string, tooltip string, ico string)
}
)
var (
localOS IOS
)
func OS() IOS {
if localOS == nil {
panic("implement not found for interface IOS, forgot register?")
}
return localOS
}
func RegisterOS(i IOS) {
localOS = i
}

View File

@@ -152,3 +152,8 @@ func (m *timeMod) CheckIsBeRwd(createdTime, lastRwdTime time.Time, _now ...time.
// 如果是,则说明还没领过,可以领取
return lastRwdTime.Before(refreshToday)
}
// 获取指定时间的本月最后一刻
func (m *timeMod) EndOfMonth(t time.Time) time.Time {
return time.Date(t.Year(), t.Month()+1, 1, 0, 0, 0, 0, t.Location()).Add(-time.Second)
}