merge from dev branch

pull/256/head
Michael Li 1 year ago
commit 0552008b5b
No known key found for this signature in database

@ -47,7 +47,7 @@ jobs:
name: Test name: Test
strategy: strategy:
matrix: matrix:
go-version: [ 1.19.x, 1.20.x ] go-version: [ 1.20.x ]
platform: [ ubuntu-latest, macos-latest ] platform: [ ubuntu-latest, macos-latest ]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
@ -66,7 +66,7 @@ jobs:
name: TestOnWindows name: TestOnWindows
strategy: strategy:
matrix: matrix:
go-version: [ 1.19.x, 1.20.x ] go-version: [ 1.20.x ]
platform: [ windows-latest ] platform: [ windows-latest ]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:

@ -65,7 +65,7 @@ PaoPao主要由以下优秀的开源项目/工具构建
### 环境要求 ### 环境要求
* Go (1.19+) * Go (1.20+)
* Node.js (14+) * Node.js (14+)
* MySQL (5.7+) * MySQL (5.7+)
* Redis * Redis

@ -181,7 +181,6 @@ Postgres: # PostgreSQL数据库
Sqlite3: # Sqlite3数据库 Sqlite3: # Sqlite3数据库
Path: custom/data/sqlite3/paopao-ce.db Path: custom/data/sqlite3/paopao-ce.db
Redis: Redis:
Host: redis:6379 InitAddress:
Password: - redis:6379
DB:

@ -32,11 +32,22 @@ services:
# networks: # networks:
# - paopao-network # - paopao-network
# redis:
# image: redis:7.0-alpine
# restart: always
# ports:
# - 6379:6379
# networks:
# - paopao-network
redis: redis:
image: redis:7.0-alpine image: redis/redis-stack:7.0.6-RC8
restart: always restart: always
ports: ports:
- 6379:6379 - 6379:6379
- 8001:8001
environment:
REDISEARCH_ARGS: "MAXSEARCHRESULTS 5"
networks: networks:
- paopao-network - paopao-network

@ -26,6 +26,5 @@ LocalOSS: # 本地文件OSS存储配置
Sqlite3: # Sqlite3数据库 Sqlite3: # Sqlite3数据库
Path: custom/data/sqlite3/paopao-ce.db Path: custom/data/sqlite3/paopao-ce.db
Redis: Redis:
Host: 127.0.0.1:6379 InitAddress:
Password: - 127.0.0.1:6379
DB:

@ -1,6 +1,6 @@
module github.com/rocboss/paopao-ce module github.com/rocboss/paopao-ce
go 1.19 go 1.20
require ( require (
github.com/Masterminds/semver/v3 v3.2.0 github.com/Masterminds/semver/v3 v3.2.0
@ -24,9 +24,9 @@ require (
github.com/meilisearch/meilisearch-go v0.21.0 github.com/meilisearch/meilisearch-go v0.21.0
github.com/minio/minio-go/v7 v7.0.49 github.com/minio/minio-go/v7 v7.0.49
github.com/onsi/ginkgo/v2 v2.9.2 github.com/onsi/ginkgo/v2 v2.9.2
github.com/onsi/gomega v1.27.4 github.com/onsi/gomega v1.27.5
github.com/pyroscope-io/client v0.6.0 github.com/pyroscope-io/client v0.6.0
github.com/redis/go-redis/v9 v9.0.2 github.com/rueian/rueidis v0.0.97
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
github.com/smartwalle/alipay/v3 v3.2.0 github.com/smartwalle/alipay/v3 v3.2.0
github.com/sourcegraph/conc v0.3.0 github.com/sourcegraph/conc v0.3.0
@ -49,10 +49,8 @@ require (
require ( require (
github.com/andybalholm/brotli v1.0.4 // indirect github.com/andybalholm/brotli v1.0.4 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/clbanning/mxj v1.8.4 // indirect github.com/clbanning/mxj v1.8.4 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
@ -66,7 +64,7 @@ require (
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect

@ -185,8 +185,6 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/bsm/ginkgo/v2 v2.5.0 h1:aOAnND1T40wEdAtkGSkvSICWeQ8L3UASX7YVCqQx+eQ=
github.com/bsm/gomega v1.20.0 h1:JhAwLmtRzXFTx2AkALSLa8ijZafntmhSoU63Ok18Uq8=
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
@ -204,8 +202,6 @@ github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
@ -375,8 +371,6 @@ github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dhui/dktest v0.3.10 h1:0frpeeoM9pHouHjhLeZDuDTJ0PqjDTrycaHaMmkJAo8= github.com/dhui/dktest v0.3.10 h1:0frpeeoM9pHouHjhLeZDuDTJ0PqjDTrycaHaMmkJAo8=
github.com/dhui/dktest v0.3.10/go.mod h1:h5Enh0nG3Qbo9WjNFRrwmKUaePEBhXMOygbz3Ww7Sz0= github.com/dhui/dktest v0.3.10/go.mod h1:h5Enh0nG3Qbo9WjNFRrwmKUaePEBhXMOygbz3Ww7Sz0=
@ -658,8 +652,8 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -1007,8 +1001,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/onsi/gomega v1.27.5 h1:T/X6I0RNFw/kTqgfkZPcQ5KU6vCnWNBGdtrIx2dpGeQ=
github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/onsi/gomega v1.27.5/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@ -1104,8 +1098,6 @@ github.com/pyroscope-io/client v0.6.0 h1:rcUFgcnfmuyVYDYT+4d0zfqc8YedOyruHSsUb9I
github.com/pyroscope-io/client v0.6.0/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= github.com/pyroscope-io/client v0.6.0/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU=
github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE= github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE=
github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE= github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE=
github.com/redis/go-redis/v9 v9.0.2 h1:BA426Zqe/7r56kCcvxYLWe1mkaz71LKF77GwgFzSxfE=
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@ -1124,6 +1116,8 @@ github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rueian/rueidis v0.0.97 h1:b3jo3CatMd7Jak+Sbz8sPpasdUY/BziBsSjdzT5GQvc=
github.com/rueian/rueidis v0.0.97/go.mod h1:ivvsRYRtAUcf9OnheuKc5Gpa8IebrkLT1P45Lr2jlXE=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=

@ -110,6 +110,7 @@ func setupSetting(suite []string, noDefault bool) error {
SimpleCacheIndexSetting.CheckTickDuration *= time.Second SimpleCacheIndexSetting.CheckTickDuration *= time.Second
SimpleCacheIndexSetting.ExpireTickDuration *= time.Second SimpleCacheIndexSetting.ExpireTickDuration *= time.Second
BigCacheIndexSetting.ExpireInSecond *= time.Second BigCacheIndexSetting.ExpireInSecond *= time.Second
redisSetting.ConnWriteTimeout *= time.Second
Mutex = &sync.Mutex{} Mutex = &sync.Mutex{}
return nil return nil
@ -122,7 +123,6 @@ func Initialize(suite []string, noDefault bool) {
} }
setupLogger() setupLogger()
setupDBEngine()
} }
func GetOssDomain() string { func GetOssDomain() string {

@ -179,7 +179,10 @@ Postgres: # PostgreSQL数据库
Sqlite3: # Sqlite3数据库 Sqlite3: # Sqlite3数据库
Path: custom/data/sqlite3/paopao-ce.db Path: custom/data/sqlite3/paopao-ce.db
Redis: Redis:
Host: redis:6379 InitAddress:
Password: - redis:6379
DB: Username:
Password:
SelectDB:
ConnWriteTimeout: 60 # 连接写超时时间 多少秒 默认 60秒

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/alimy/cfg" "github.com/alimy/cfg"
"github.com/redis/go-redis/v9"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
@ -20,9 +19,8 @@ import (
) )
var ( var (
db *gorm.DB db *gorm.DB
Redis *redis.Client once sync.Once
once sync.Once
) )
func MustGormDB() *gorm.DB { func MustGormDB() *gorm.DB {
@ -84,11 +82,3 @@ func newDBEngine() (*gorm.DB, error) {
return db, err return db, err
} }
func setupDBEngine() {
Redis = redis.NewClient(&redis.Options{
Addr: redisSetting.Host,
Password: redisSetting.Password,
DB: redisSetting.DB,
})
}

@ -0,0 +1,34 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (
"log"
"sync"
"github.com/rueian/rueidis"
)
var (
_redisClient rueidis.Client
_once sync.Once
)
func MustRedisClient() rueidis.Client {
_once.Do(func() {
client, err := rueidis.NewClient(rueidis.ClientOption{
InitAddress: redisSetting.InitAddress,
Username: redisSetting.Username,
Password: redisSetting.Password,
SelectDB: redisSetting.SelectDB,
ConnWriteTimeout: redisSetting.ConnWriteTimeout,
})
if err != nil {
log.Fatalf("create a redis client failed: %s", err)
}
_redisClient = client
})
return _redisClient
}

@ -210,9 +210,11 @@ type LocalOSSSettingS struct {
} }
type RedisSettingS struct { type RedisSettingS struct {
Host string InitAddress []string
Password string Username string
DB int Password string
SelectDB int
ConnWriteTimeout time.Duration
} }
type JWTSettingS struct { type JWTSettingS struct {

@ -5,6 +5,8 @@
package core package core
import ( import (
"context"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
) )
@ -56,3 +58,21 @@ type CacheIndexService interface {
SendAction(act IdxAct, post *dbr.Post) SendAction(act IdxAct, post *dbr.Post)
} }
// RedisCache memory cache by Redis
type RedisCache interface {
SetPushToSearchJob(ctx context.Context) error
DelPushToSearchJob(ctx context.Context) error
SetImgCaptcha(ctx context.Context, id string, value string) error
GetImgCaptcha(ctx context.Context, id string) (string, error)
DelImgCaptcha(ctx context.Context, id string) error
GetCountSmsCaptcha(ctx context.Context, phone string) (int64, error)
IncrCountSmsCaptcha(ctx context.Context, phone string) error
GetCountLoginErr(ctx context.Context, id int64) (int64, error)
DelCountLoginErr(ctx context.Context, id int64) error
IncrCountLoginErr(ctx context.Context, id int64) error
GetCountWhisper(ctx context.Context, uid int64) (int64, error)
IncrCountWhisper(ctx context.Context, uid int64) error
SetRechargeStatus(ctx context.Context, tradeNo string) error
DelRechargeStatus(ctx context.Context, tradeNo string) error
}

@ -13,6 +13,12 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func NewRedisCache() core.RedisCache {
return &redisCache{
c: conf.MustRedisClient(),
}
}
func NewBigCacheIndexService(ips core.IndexPostsService, ams core.AuthorizationManageService) (core.CacheIndexService, core.VersionInfo) { func NewBigCacheIndexService(ips core.IndexPostsService, ams core.AuthorizationManageService) (core.CacheIndexService, core.VersionInfo) {
s := conf.BigCacheIndexSetting s := conf.BigCacheIndexSetting
c := bigcache.DefaultConfig(s.ExpireInSecond) c := bigcache.DefaultConfig(s.ExpireInSecond)

@ -0,0 +1,108 @@
package cache
import (
"context"
"fmt"
"time"
"unsafe"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rueian/rueidis"
)
var (
_ core.RedisCache = (*redisCache)(nil)
)
const (
_pushToSearchJobKey = "JOB_PUSH_TO_SEARCH"
_countLoginErrKey = "PaoPaoUserLoginErr:"
_imgCaptchaKey = "PaoPaoCaptcha:"
_smsCaptchaKey = "PaoPaoSmsCaptcha:"
_countWhisperKey = "WhisperTimes:"
_rechargeStatusKey = "PaoPaoRecharge:"
)
type redisCache struct {
c rueidis.Client
}
func (r *redisCache) SetPushToSearchJob(ctx context.Context) error {
return r.c.Do(ctx, r.c.B().Set().
Key(_pushToSearchJobKey).Value("1").
Nx().ExSeconds(3600).
Build()).Error()
}
func (r *redisCache) DelPushToSearchJob(ctx context.Context) error {
return r.c.Do(ctx, r.c.B().Del().Key(_pushToSearchJobKey).Build()).Error()
}
func (r *redisCache) SetImgCaptcha(ctx context.Context, id string, value string) error {
return r.c.Do(ctx, r.c.B().Set().
Key(_imgCaptchaKey+id).Value(value).
ExSeconds(300).
Build()).Error()
}
func (r *redisCache) GetImgCaptcha(ctx context.Context, id string) (string, error) {
res, err := r.c.Do(ctx, r.c.B().Get().Key(_imgCaptchaKey+id).Build()).AsBytes()
return unsafe.String(&res[0], len(res)), err
}
func (r *redisCache) DelImgCaptcha(ctx context.Context, id string) error {
return r.c.Do(ctx, r.c.B().Del().Key(_imgCaptchaKey+id).Build()).Error()
}
func (r *redisCache) GetCountSmsCaptcha(ctx context.Context, phone string) (int64, error) {
return r.c.Do(ctx, r.c.B().Get().Key(_smsCaptchaKey+phone).Build()).AsInt64()
}
func (r *redisCache) IncrCountSmsCaptcha(ctx context.Context, phone string) (err error) {
if err = r.c.Do(ctx, r.c.B().Incr().Key(_smsCaptchaKey+phone).Build()).Error(); err == nil {
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
err = r.c.Do(ctx, r.c.B().Expire().Key(_smsCaptchaKey+phone).Seconds(int64(endTime.Sub(currentTime)/time.Second)).Build()).Error()
}
return
}
func (r *redisCache) GetCountLoginErr(ctx context.Context, id int64) (int64, error) {
return r.c.Do(ctx, r.c.B().Get().Key(fmt.Sprintf("%s:%d", _countLoginErrKey, id)).Build()).AsInt64()
}
func (r *redisCache) DelCountLoginErr(ctx context.Context, id int64) error {
return r.c.Do(ctx, r.c.B().Del().Key(fmt.Sprintf("%s:%d", _countLoginErrKey, id)).Build()).Error()
}
func (r *redisCache) IncrCountLoginErr(ctx context.Context, id int64) error {
err := r.c.Do(ctx, r.c.B().Incr().Key(fmt.Sprintf("%s:%d", _countLoginErrKey, id)).Build()).Error()
if err == nil {
err = r.c.Do(ctx, r.c.B().Expire().Key(fmt.Sprintf("%s:%d", _countLoginErrKey, id)).Seconds(3600).Build()).Error()
}
return err
}
func (r *redisCache) GetCountWhisper(ctx context.Context, uid int64) (int64, error) {
return r.c.Do(ctx, r.c.B().Get().Key(fmt.Sprintf("%s:%d", _countWhisperKey, uid)).Build()).AsInt64()
}
func (r *redisCache) IncrCountWhisper(ctx context.Context, uid int64) (err error) {
key := fmt.Sprintf("%s:%d", _countWhisperKey, uid)
if err = r.c.Do(ctx, r.c.B().Incr().Key(key).Build()).Error(); err == nil {
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
err = r.c.Do(ctx, r.c.B().Expire().Key(key).Seconds(int64(endTime.Sub(currentTime)/time.Second)).Build()).Error()
}
return
}
func (r *redisCache) SetRechargeStatus(ctx context.Context, tradeNo string) error {
return r.c.Do(ctx, r.c.B().Set().
Key(_rechargeStatusKey+tradeNo).Value("1").
Nx().ExSeconds(5).Build()).Error()
}
func (r *redisCache) DelRechargeStatus(ctx context.Context, tradeNo string) error {
return r.c.Do(ctx, r.c.B().Del().Key(_rechargeStatusKey+tradeNo).Build()).Error()
}

@ -9,23 +9,24 @@ import (
"fmt" "fmt"
"math" "math"
"net/http" "net/http"
"time"
"github.com/alimy/mir/v3" "github.com/alimy/mir/v3"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao"
"github.com/rocboss/paopao-ce/internal/dao/cache"
"github.com/rocboss/paopao-ce/pkg/app" "github.com/rocboss/paopao-ce/pkg/app"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
"github.com/rocboss/paopao-ce/pkg/xerror" "github.com/rocboss/paopao-ce/pkg/xerror"
"github.com/sirupsen/logrus"
) )
type BaseServant types.Empty type BaseServant types.Empty
type DaoServant struct { type DaoServant struct {
Redis *redis.Client
Ds core.DataService Ds core.DataService
Ts core.TweetSearchService Ts core.TweetSearchService
Redis core.RedisCache
} }
type BaseBinding types.Empty type BaseBinding types.Empty
@ -140,8 +141,8 @@ func (s *DaoServant) GetTweetBy(id int64) (*core.PostFormated, error) {
} }
func (s *DaoServant) PushPostsToSearch(c context.Context) { func (s *DaoServant) PushPostsToSearch(c context.Context) {
if ok, _ := s.Redis.SetNX(c, "JOB_PUSH_TO_SEARCH", 1, time.Hour).Result(); ok { if err := s.Redis.SetPushToSearchJob(c); err == nil {
defer s.Redis.Del(c, "JOB_PUSH_TO_SEARCH") defer s.Redis.DelPushToSearchJob(c)
splitNum := 1000 splitNum := 1000
totalRows, _ := s.Ds.GetPostCount(&core.ConditionsT{ totalRows, _ := s.Ds.GetPostCount(&core.ConditionsT{
@ -168,6 +169,8 @@ func (s *DaoServant) PushPostsToSearch(c context.Context) {
s.Ts.AddDocuments(docs, fmt.Sprintf("%d", posts[i].ID)) s.Ts.AddDocuments(docs, fmt.Sprintf("%d", posts[i].ID))
} }
} }
} else {
logrus.Errorf("redis: set JOB_PUSH_TO_SEARCH error: %s", err)
} }
} }
@ -207,3 +210,11 @@ func (s *DaoServant) GetTweetList(conditions *core.ConditionsT, offset, limit in
postFormated, err := s.Ds.MergePosts(posts) postFormated, err := s.Ds.MergePosts(posts)
return posts, postFormated, err return posts, postFormated, err
} }
func NewDaoServant() *DaoServant {
return &DaoServant{
Redis: cache.NewRedisCache(),
Ds: dao.DataService(),
Ts: dao.TweetSearchService(),
}
}

@ -6,7 +6,6 @@ package web
import ( import (
"fmt" "fmt"
"time"
"github.com/alimy/mir/v3" "github.com/alimy/mir/v3"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -80,7 +79,7 @@ func (b *alipayPubBinding) BindAlipayNotify(c *gin.Context) (*web.AlipayNotifyRe
func (s *alipayPubSrv) AlipayNotify(req *web.AlipayNotifyReq) mir.Error { func (s *alipayPubSrv) AlipayNotify(req *web.AlipayNotifyReq) mir.Error {
if req.TradeStatus == alipay.TradeStatusSuccess { if req.TradeStatus == alipay.TradeStatusSuccess {
if ok, _ := s.Redis.SetNX(req.Ctx, "PaoPaoRecharge:"+req.TradeNo, 1, time.Second*5).Result(); ok { if err := s.Redis.SetRechargeStatus(req.Ctx, req.TradeNo); err == nil {
recharge, err := s.Ds.GetRechargeByID(req.ID) recharge, err := s.Ds.GetRechargeByID(req.ID)
if err != nil { if err != nil {
logrus.Errorf("GetRechargeByID id:%d err: %s", req.ID, err) logrus.Errorf("GetRechargeByID id:%d err: %s", req.ID, err)
@ -89,7 +88,7 @@ func (s *alipayPubSrv) AlipayNotify(req *web.AlipayNotifyReq) mir.Error {
if recharge.TradeStatus != "TRADE_SUCCESS" { if recharge.TradeStatus != "TRADE_SUCCESS" {
// 标记为已付款 // 标记为已付款
err := s.Ds.HandleRechargeSuccess(recharge, req.TradeNo) err := s.Ds.HandleRechargeSuccess(recharge, req.TradeNo)
defer s.Redis.Del(req.Ctx, "PaoPaoRecharge:"+req.TradeNo) defer s.Redis.DelRechargeStatus(req.Ctx, req.TradeNo)
if err != nil { if err != nil {
logrus.Errorf("HandleRechargeSuccess id:%d err: %s", req.ID, err) logrus.Errorf("HandleRechargeSuccess id:%d err: %s", req.ID, err)
return _errRechargeNotifyError return _errRechargeNotifyError

@ -6,7 +6,6 @@ package web
import ( import (
"context" "context"
"fmt"
"time" "time"
"unicode/utf8" "unicode/utf8"
@ -225,8 +224,7 @@ func (s *coreSrv) SendUserWhisper(req *web.SendWhisperReq) mir.Error {
// 今日频次限制 // 今日频次限制
ctx := context.Background() ctx := context.Background()
whisperKey := fmt.Sprintf("WhisperTimes:%d", req.Uid) if count, _ := s.Redis.GetCountWhisper(ctx, req.Uid); count >= _MaxWhisperNumDaily {
if res, _ := s.Redis.Get(ctx, whisperKey).Result(); convert.StrTo(res).MustInt() >= _MaxWhisperNumDaily {
return _errTooManyWhisperNum return _errTooManyWhisperNum
} }
@ -244,10 +242,7 @@ func (s *coreSrv) SendUserWhisper(req *web.SendWhisperReq) mir.Error {
} }
// 写入当日(自然日)计数缓存 // 写入当日(自然日)计数缓存
s.Redis.Incr(ctx, whisperKey).Result() s.Redis.IncrCountWhisper(ctx, req.Uid)
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
s.Redis.Expire(ctx, whisperKey, endTime.Sub(currentTime))
return nil return nil
} }

@ -8,11 +8,9 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/base64" "encoding/base64"
"fmt"
"image/color" "image/color"
"image/png" "image/png"
"regexp" "regexp"
"time"
"unicode/utf8" "unicode/utf8"
"github.com/afocus/captcha" "github.com/afocus/captcha"
@ -40,7 +38,6 @@ var (
) )
const ( const (
_LoginErrKey = "PaoPaoUserLoginErr"
_MaxLoginErrTimes = 10 _MaxLoginErrTimes = 10
_MaxPhoneCaptcha = 10 _MaxPhoneCaptcha = 10
) )
@ -207,14 +204,14 @@ func (s *pubSrv) SendCaptcha(req *web.SendCaptchaReq) mir.Error {
ctx := context.Background() ctx := context.Background()
// 验证图片验证码 // 验证图片验证码
if res, err := s.Redis.Get(ctx, "PaoPaoCaptcha:"+req.ImgCaptchaID).Result(); err != nil || res != req.ImgCaptcha { if captcha, err := s.Redis.GetImgCaptcha(ctx, req.ImgCaptchaID); err != nil || string(captcha) != req.ImgCaptcha {
logrus.Debugf("get captcha err:%s expect:%s got:%s", err, res, req.ImgCaptcha) logrus.Debugf("get captcha err:%s expect:%s got:%s", err, captcha, req.ImgCaptcha)
return _errErrorCaptchaPassword return _errErrorCaptchaPassword
} }
s.Redis.Del(ctx, "PaoPaoCaptcha:"+req.ImgCaptchaID).Result() s.Redis.DelImgCaptcha(ctx, req.ImgCaptchaID)
// 今日频次限制 // 今日频次限制
if res, _ := s.Redis.Get(ctx, "PaoPaoSmsCaptcha:"+req.Phone).Result(); convert.StrTo(res).MustInt() >= _MaxPhoneCaptcha { if count, _ := s.Redis.GetCountSmsCaptcha(ctx, req.Phone); count >= _MaxPhoneCaptcha {
return _errTooManyPhoneCaptchaSend return _errTooManyPhoneCaptchaSend
} }
@ -222,10 +219,7 @@ func (s *pubSrv) SendCaptcha(req *web.SendCaptchaReq) mir.Error {
return xerror.ServerError return xerror.ServerError
} }
// 写入计数缓存 // 写入计数缓存
s.Redis.Incr(ctx, "PaoPaoSmsCaptcha:"+req.Phone).Result() s.Redis.IncrCountSmsCaptcha(ctx, req.Phone)
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
s.Redis.Expire(ctx, "PaoPaoSmsCaptcha:"+req.Phone, endTime.Sub(currentTime))
return nil return nil
} }
@ -248,7 +242,7 @@ func (s *pubSrv) GetCaptcha() (*web.GetCaptchaResp, mir.Error) {
} }
key := utils.EncodeMD5(uuid.Must(uuid.NewV4()).String()) key := utils.EncodeMD5(uuid.Must(uuid.NewV4()).String())
// 五分钟有效期 // 五分钟有效期
s.Redis.SetEx(context.Background(), "PaoPaoCaptcha:"+key, password, time.Minute*5) s.Redis.SetImgCaptcha(context.Background(), key, password)
return &web.GetCaptchaResp{ return &web.GetCaptchaResp{
Id: key, Id: key,
Content: "data:image/png;base64," + base64.StdEncoding.EncodeToString(emptyBuff.Bytes()), Content: "data:image/png;base64," + base64.StdEncoding.EncodeToString(emptyBuff.Bytes()),
@ -294,10 +288,8 @@ func (s *pubSrv) Login(req *web.LoginReq) (*web.LoginResp, mir.Error) {
} }
if user.Model != nil && user.ID > 0 { if user.Model != nil && user.ID > 0 {
if errTimes, err := s.Redis.Get(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID)).Result(); err == nil { if count, err := s.Redis.GetCountLoginErr(ctx, user.ID); err == nil && count >= _MaxLoginErrTimes {
if convert.StrTo(errTimes).MustInt() >= _MaxLoginErrTimes { return nil, _errTooManyLoginError
return nil, _errTooManyLoginError
}
} }
// 对比密码是否正确 // 对比密码是否正确
if validPassword(user.Password, req.Password, user.Salt) { if validPassword(user.Password, req.Password, user.Salt) {
@ -305,13 +297,10 @@ func (s *pubSrv) Login(req *web.LoginReq) (*web.LoginResp, mir.Error) {
return nil, _errUserHasBeenBanned return nil, _errUserHasBeenBanned
} }
// 清空登录计数 // 清空登录计数
s.Redis.Del(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID)) s.Redis.DelCountLoginErr(ctx, user.ID)
} else { } else {
// 登录错误计数 // 登录错误计数
_, err = s.Redis.Incr(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID)).Result() s.Redis.IncrCountLoginErr(ctx, user.ID)
if err == nil {
s.Redis.Expire(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID), time.Hour).Result()
}
return nil, xerror.UnauthorizedAuthFailed return nil, xerror.UnauthorizedAuthFailed
} }
} else { } else {

@ -26,11 +26,7 @@ var (
func RouteWeb(e *gin.Engine) { func RouteWeb(e *gin.Engine) {
lazyInitial() lazyInitial()
oss := dao.ObjectStorageService() oss := dao.ObjectStorageService()
ds := &base.DaoServant{ ds := base.NewDaoServant()
Redis: conf.Redis,
Ds: dao.DataService(),
Ts: dao.TweetSearchService(),
}
// aways register servants // aways register servants
api.RegisterAdminServant(e, newAdminSrv(ds), newAdminBinding(), newAdminRender()) api.RegisterAdminServant(e, newAdminSrv(ds), newAdminBinding(), newAdminRender())
api.RegisterCoreServant(e, newCoreSrv(ds, oss), newCoreBinding(), newCoreRender()) api.RegisterCoreServant(e, newCoreSrv(ds, oss), newCoreBinding(), newCoreRender())

Loading…
Cancel
Save