Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
module 91porn-server/tests/checkin
go 1.26.1
require (
91porn-server v0.0.0
git.ruishengces.com/pub_tool/autotest v0.0.0-20260430042504-d6b5bf976a06
github.com/gin-gonic/gin v1.9.1
go.mongodb.org/mongo-driver v1.17.9
)
require (
github.com/IBM/sarama v1.45.2 // indirect
github.com/aws/aws-sdk-go v1.44.260 // indirect
github.com/badoux/checkmail v1.2.1 // indirect
github.com/bxcodec/faker/v3 v3.1.0 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ddliu/go-httpclient v0.7.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/didip/tollbooth v4.0.2+incompatible // indirect
github.com/didip/tollbooth_gin v0.0.0-20170928041415-5752492be505 // indirect
github.com/eapache/go-resiliency v1.7.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/elastic/elastic-transport-go/v8 v8.2.0 // indirect
github.com/elastic/go-elasticsearch/v8 v8.8.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/pprof v1.4.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ego/gpy v0.42.1 // indirect
github.com/go-ego/gse v0.80.2 // indirect
github.com/go-playground/form v3.1.4+incompatible // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-redis/redis v6.15.9+incompatible // indirect
github.com/go-redsync/redsync/v4 v4.8.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang-module/carbon/v2 v2.3.10 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gopherjs/gopherjs v1.20.2 // indirect
github.com/grafov/m3u8 v0.12.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
github.com/jcmturner/gofork v1.7.6 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/jinzhu/copier v0.3.5 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/makiuchi-d/gozxing v0.1.1 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/moul/http2curl v1.0.0 // indirect
github.com/mozillazg/go-pinyin v0.19.0 // indirect
github.com/nyaruka/phonenumbers v1.1.6 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/redis/go-redis/v9 v9.18.0 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/smarty/assertions v1.16.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/vcaesar/cedar v0.20.1 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9 // indirect
github.com/xuri/excelize/v2 v2.7.1 // indirect
github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sync v0.14.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace 91porn-server => ../..
+446
View File
@@ -0,0 +1,446 @@
git.ruishengces.com/pub_tool/autotest v0.0.0-20260430042504-d6b5bf976a06 h1:ZRcu8KfH+aHrKMIIYF6a03EKkbTWF5b6iE98POBt1oY=
git.ruishengces.com/pub_tool/autotest v0.0.0-20260430042504-d6b5bf976a06/go.mod h1:HnkqUUd7M6qkYdyuR61pdVeHYtTsjP5HbPsEp6t3iiI=
github.com/IBM/sarama v1.45.2 h1:8m8LcMCu3REcwpa7fCP6v2fuPuzVwXDAM2DOv3CBrKw=
github.com/IBM/sarama v1.45.2/go.mod h1:ppaoTcVdGv186/z6MEKsMm70A5fwJfRTpstI37kVn3Y=
github.com/aws/aws-sdk-go v1.44.260 h1:78IJkDpDPXvLXvIkNAKDP/i3z8Vj+3sTAtQYw/v/2o8=
github.com/aws/aws-sdk-go v1.44.260/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/badoux/checkmail v1.2.1 h1:TzwYx5pnsV6anJweMx2auXdekBwGr/yt1GgalIx9nBQ=
github.com/badoux/checkmail v1.2.1/go.mod h1:XroCOBU5zzZJcLvgwU15I+2xXyCdTWXyR9MGfRhBYy0=
github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bxcodec/faker/v3 v3.1.0 h1:VCCPusvvk1My6RjWFnqVbh6EdHDqjWmrHJCHduUksV0=
github.com/bxcodec/faker/v3 v3.1.0/go.mod h1:gF31YgnMSMKgkvl+fyEo1xuSMbEuieyqfeslGYFjneM=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ddliu/go-httpclient v0.7.1 h1:COWYBalfbaFNe6e0eQU38++vCD5kzLh1H1RFs3xcn9g=
github.com/ddliu/go-httpclient v0.7.1/go.mod h1:uwipe9x9SYGk4JhBemO7+dD87QbiY224y0DLB9OY0Ik=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
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/didip/tollbooth v4.0.2+incompatible h1:fVSa33JzSz0hoh2NxpwZtksAzAgd7zjmGO20HCZtF4M=
github.com/didip/tollbooth v4.0.2+incompatible/go.mod h1:A9b0665CE6l1KmzpDws2++elm/CsuWBMa5Jv4WY0PEY=
github.com/didip/tollbooth_gin v0.0.0-20170928041415-5752492be505 h1:VkJBA707rG0mOUM5nuqTs53hlJEb6peXnY7elFDWh88=
github.com/didip/tollbooth_gin v0.0.0-20170928041415-5752492be505/go.mod h1:ieayd+rxBVaj62fhAdF5p1U70Y4ZCcfpk0+4jesd0f8=
github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA=
github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws=
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/elastic/elastic-transport-go/v8 v8.0.0-20230329154755-1a3c63de0db6/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI=
github.com/elastic/elastic-transport-go/v8 v8.2.0 h1:hkK5IIs/15mpSXzd5THWVlWTKJyMw6cbCWM3T/B2S5E=
github.com/elastic/elastic-transport-go/v8 v8.2.0/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI=
github.com/elastic/go-elasticsearch/v8 v8.8.0 h1:yNBPlXNo6wstMG7I3KiZPbLFgA82RMryYqkh1xBMV3A=
github.com/elastic/go-elasticsearch/v8 v8.8.0/go.mod h1:NGmpvohKiRHXI0Sw4fuUGn6hYOmAXlyCphKpzVBiqDE=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
github.com/gin-contrib/pprof v1.4.0/go.mod h1:RrehPJasUVBPK6yTUwOl8/NP6i0vbUgmxtis+Z5KE90=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-ego/gpy v0.42.1 h1:P/doarxZi2J5qwNzLIM0ESd3VXLXMpdhwO/GNontLdE=
github.com/go-ego/gpy v0.42.1/go.mod h1:eBtY3/uCDqBFog4ES9L00xytTpXar/0mGf45Rb7zcgg=
github.com/go-ego/gse v0.80.2 h1:3LRfkaBuwlsHsmkOZvnhTcsYPXUAhiP06Sqcid7mO1M=
github.com/go-ego/gse v0.80.2/go.mod h1:kesekpZfcFQ/kwd9b27VZHUOH5dQUjaaQUZ4OGt4Hj4=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/form v3.1.4+incompatible h1:lvKiHVxE2WvzDIoyMnWcjyiBxKt2+uFJyZcPYWsLnjI=
github.com/go-playground/form v3.1.4+incompatible/go.mod h1:lhcKXfTuhRtIZCIKUeJ0b5F207aeQCPbZU09ScKjwWg=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-redsync/redsync/v4 v4.8.1 h1:rq2RvdTI0obznMdxKUWGdmmulo7lS9yCzb8fgDKOlbM=
github.com/go-redsync/redsync/v4 v4.8.1/go.mod h1:LmUAsQuQxhzZAoGY7JS6+dNhNmZyonMZiiEDY9plotM=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang-module/carbon/v2 v2.3.10 h1:C25x4A4UrIch6bisV3j37eU+op5+cp4gw/Fffv5c/FA=
github.com/golang-module/carbon/v2 v2.3.10/go.mod h1:XDALX7KgqmHk95xyLeaqX9/LJGbfLATyruTziq68SZ8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v1.20.2 h1:mzF/NBZH47L63jqg19OQgXv32FYRvFZVWom8PiQ2HbU=
github.com/gopherjs/gopherjs v1.20.2/go.mod h1:h+FTmmLgbXMmmtuZFp9bUqXciN429Wx0sJEJuMnpyfM=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/grafov/m3u8 v0.12.0 h1:T6iTwTsSEtMcwkayef+FJO8kj+Sglr4Lh81Zj8Ked/4=
github.com/grafov/m3u8 v0.12.0/go.mod h1:nqzOkfBiZJENr52zTVd/Dcl03yzphIMbJqkXGu+u080=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/makiuchi-d/gozxing v0.1.1 h1:xxqijhoedi+/lZlhINteGbywIrewVdVv2wl9r5O9S1I=
github.com/makiuchi-d/gozxing v0.1.1/go.mod h1:eRIHbOjX7QWxLIDJoQuMLhuXg9LAuw6znsUtRkNw9DU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
github.com/mozillazg/go-pinyin v0.19.0 h1:p+J8/kjJ558KPvVGYLvqBhxf8jbZA2exSLCs2uUVN8c=
github.com/mozillazg/go-pinyin v0.19.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nyaruka/phonenumbers v1.1.6 h1:DcueYq7QrOArAprAYNoQfDgp0KetO4LqtnBtQC6Wyes=
github.com/nyaruka/phonenumbers v1.1.6/go.mod h1:yShPJHDSH3aTKzCbXyVxNpbl2kA+F+Ne5Pun/MvFRos=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
github.com/redis/go-redis/v9 v9.18.0 h1:pMkxYPkEbMPwRdenAzUNyFNrDgHx9U+DrBabWNfSRQs=
github.com/redis/go-redis/v9 v9.18.0/go.mod h1:k3ufPphLU5YXwNTUcCRXGxUoF1fqxnhFQmscfkCoDA0=
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 h1:pyecQtsPmlkCsMkYhT5iZ+sUXuwee+OvfuJjinEA3ko=
github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62/go.mod h1:65XQgovT59RWatovFwnwocoUxiI/eENTnOY5GK3STuY=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY=
github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI=
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM=
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/vcaesar/cedar v0.20.1 h1:cDOmYWdprO7ZW8cngJrDi8Zivnscj9dA/y8Y+2SB1P0=
github.com/vcaesar/cedar v0.20.1/go.mod h1:iMDweyuW76RvSrCkQeZeQk4iCbshiPzcCvcGCtpM7iI=
github.com/vcaesar/tt v0.20.0 h1:9t2Ycb9RNHcP0WgQgIaRKJBB+FrRdejuaL6uWIHuoBA=
github.com/vcaesar/tt v0.20.0/go.mod h1:GHPxQYhn+7OgKakRusH7KJ0M5MhywoeLb8Fcffs/Gtg=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9 h1:ge5g8vsTQclA5lXDi+PuiAFw5GMIlMHOB/5e1hsf96E=
github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.7.1 h1:gm8q0UCAyaTt3MEF5wWMjVdmthm2EHAWesGSKS9tdVI=
github.com/xuri/excelize/v2 v2.7.1/go.mod h1:qc0+2j4TvAUrBw36ATtcTeC1VCM0fFdAXZOmcF4nTpY=
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83 h1:xVwnvkzzi+OiwhIkWOXvh1skFI6bagk8OvGuazM80Rw=
github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU=
go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
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=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
+35
View File
@@ -0,0 +1,35 @@
package main
import (
"fmt"
"os"
"time"
fw "git.ruishengces.com/pub_tool/autotest"
"git.ruishengces.com/pub_tool/autotest/reporter"
)
func main() {
cfg := fw.ParseFlags("checkin")
env := &Env{}
base, cleanup := fw.ManageEnv(env, fw.EnvConfig{}, cfg)
defer cleanup()
summary := fw.NewRunner("签到模块测试", cfg).
Report(reporter.Console()).
Report(reporter.HTML("签到模块测试", "reports", env.Meta())).
Report(reporter.JSON("reports")).
Register(
&CheckinSuite{env: env, url: base.AppBaseURL},
).
Build().
Run()
fmt.Printf("\n总计: %d 通过, %d 失败, 耗时 %s\n",
summary.Stats.Passed, summary.Stats.Failed, summary.Duration.Round(time.Millisecond))
if summary.Stats.Failed > 0 {
os.Exit(1)
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"total": 32,
"passed": 32,
"failed": 0
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,962 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>签到模块测试 - 测试报告</title>
<style>
:root {
--green: #059669; --red: #dc2626; --blue: #2563eb; --purple: #7c3aed;
--gray: #6b7280; --light: #f8fafc; --border: #e5e7eb; --sidebar-w: 320px;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f0f2f5; color: #1f2937; height: 100vh; overflow: hidden; }
.topbar {
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff; padding: 16px 28px; display: flex; align-items: center; gap: 32px; flex-wrap: wrap;
position: fixed; top: 0; left: 0; right: 0; z-index: 100; height: auto; min-height: 64px;
}
.topbar h1 { font-size: 18px; white-space: nowrap; }
.topbar .stats { display: flex; gap: 20px; align-items: center; }
.topbar .stat { text-align: center; }
.topbar .stat .num { font-size: 24px; font-weight: 800; }
.topbar .stat .lbl { font-size: 10px; opacity: .7; }
.topbar .stat.pass .num { color: #86efac; }
.topbar .stat.fail .num { color: #fca5a5; }
.topbar .stat.rate .num { color: #93c5fd; }
.topbar .delta { font-size: 10px; opacity: .8; }
.topbar .env-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.topbar .env-tags span { background: rgba(255,255,255,.15); padding: 3px 10px; border-radius: 6px; font-size: 11px; }
.topbar .progress { position: absolute; bottom: 0; left: 0; right: 0; height: 3px; background: rgba(255,255,255,.2); }
.topbar .progress .fill { height: 100%; background: #86efac; }
.layout { display: flex; margin-top: 64px; height: calc(100vh - 64px); }
.sidebar {
width: var(--sidebar-w); min-width: var(--sidebar-w); background: #fff;
border-right: 1px solid var(--border); overflow-y: auto; padding: 12px 0;
}
.sidebar .suite-group { margin-bottom: 4px; }
.sidebar .suite-title {
padding: 8px 16px; font-size: 13px; font-weight: 600; color: #374151;
display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none;
}
.sidebar .suite-title:hover { background: #f9fafb; }
.sidebar .suite-title .arrow { font-size: 10px; color: #aaa; transition: transform .2s; }
.sidebar .suite-group.open .arrow { transform: rotate(90deg); }
.sidebar .suite-title .cnt { margin-left: auto; font-size: 11px; font-weight: 400; color: #aaa; }
.sidebar .suite-title .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.sidebar .dot.pass { background: var(--green); } .sidebar .dot.fail { background: var(--red); } .sidebar .dot.skip { background: #fbbf24; }
.sidebar .case-list { display: none; }
.sidebar .suite-group.open .case-list { display: block; }
.sidebar .case-item {
padding: 6px 16px 6px 36px; font-size: 12px; cursor: pointer;
display: flex; align-items: center; gap: 6px; color: #6b7280;
border-left: 3px solid transparent;
}
.sidebar .case-item:hover { background: #f3f4f6; }
.sidebar .case-item.active { background: #eef2ff; border-left-color: #6366f1; color: #1f2937; font-weight: 500; }
.sidebar .case-item .icon { font-size: 12px; }
.detail {
flex: 1; overflow-y: auto; padding: 28px 36px; background: var(--light);
}
.detail .empty { color: #aaa; font-size: 15px; margin-top: 120px; text-align: center; }
.detail .d-header { margin-bottom: 24px; }
.detail .d-header h2 { font-size: 20px; margin-bottom: 8px; display: flex; align-items: center; gap: 10px; }
.detail .d-header h2 .status { font-size: 22px; }
.detail .d-header .d-meta { font-size: 13px; color: var(--gray); display: flex; gap: 16px; }
.detail .d-section { background: #fff; border-radius: 10px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 4px rgba(0,0,0,.05); }
.detail .d-section h3 { font-size: 14px; color: var(--gray); margin-bottom: 12px; font-weight: 500; }
.detail .kv-grid { display: grid; grid-template-columns: 56px 1fr; gap: 6px 12px; font-size: 14px; }
.detail .kv-grid .k { color: var(--gray); text-align: right; font-size: 13px; }
.detail .kv-grid .v { font-family: "SF Mono", Monaco, monospace; word-break: break-all; }
.detail .kv-grid .v.pass { color: var(--green); } .detail .kv-grid .v.fail { color: var(--red); }
.detail .curl-block {
background: #1e293b; color: #e2e8f0; border-radius: 8px; padding: 16px 18px;
font-family: "SF Mono", Monaco, "Cascadia Code", monospace; font-size: 13px;
white-space: pre-wrap; word-break: break-all; line-height: 1.7; position: relative;
}
.detail .curl-block .copy-btn {
position: absolute; top: 10px; right: 10px;
background: #475569; color: #e2e8f0; border: none; border-radius: 5px;
padding: 4px 14px; font-size: 12px; cursor: pointer;
}
.detail .curl-block .copy-btn:hover { background: #64748b; }
.detail .req-info { font-size: 13px; }
.detail .req-row { display: flex; gap: 10px; margin-bottom: 6px; align-items: baseline; }
.detail .req-row .rl { color: var(--gray); min-width: 56px; text-align: right; font-size: 12px; flex-shrink: 0; }
.detail .req-row .rv { font-family: "SF Mono", Monaco, monospace; word-break: break-all; }
.detail .method-badge { display: inline-block; padding: 2px 10px; border-radius: 4px; font-weight: 700; font-size: 12px; color: #fff; }
.detail .method-badge.GET { background: var(--blue); }
.detail .method-badge.POST { background: var(--green); }
.detail .method-badge.PUT { background: #d97706; }
.detail .method-badge.PATCH { background: #7c3aed; }
.detail .method-badge.DELETE { background: var(--red); }
.jtree { font-family: "SF Mono", Monaco, monospace; font-size: 12.5px; line-height: 1.8; background: #1e293b; color: #e2e8f0; border-radius: 8px; padding: 16px 18px; max-height: 500px; overflow: auto; }
.jtree .jk { color: #7dd3fc; } .jtree .js { color: #86efac; } .jtree .jn { color: #fbbf24; } .jtree .jb { color: #f87171; }
.jtree .jt { cursor: pointer; user-select: none; } .jtree .jt::before { content: "▼ "; font-size: 10px; color: #64748b; }
.jtree .jt.closed::before { content: "▶ "; } .jtree .jt.closed + .jc { display: none; }
.jtree .jc { } .jtree .ji { padding-left: 20px; }
.detail .resp-status-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.detail .resp-code { font-size: 14px; font-weight: 700; font-family: monospace; }
.detail .resp-code.ok { color: var(--green); }
.detail .resp-code.err { color: var(--red); }
.detail .loc-link { font-size: 12px; color: #6366f1; font-family: monospace; }
.footer { text-align: center; color: #bbb; font-size: 11px; padding: 16px 0; }
</style>
</head>
<body>
<div class="topbar">
<h1>签到模块测试</h1>
<div class="stats">
<div class="stat"><div class="num">25</div><div class="lbl">总计</div></div>
<div class="stat pass"><div class="num">25</div><div class="lbl">通过</div></div>
<div class="stat fail"><div class="num">0</div><div class="lbl">失败</div></div>
<div class="stat rate"><div class="num">100.0%</div><div class="lbl">通过率</div></div>
</div>
<div class="env-tags">
<span>📅 2026-05-07 21:20:08</span>
<span>⏱ 11s</span>
<span>项目: 91porn-server</span><span>模块: 签到</span><span>时间: 2026-05-07 21:19:57</span>
</div>
<div class="progress"><div class="fill" style="width:100%"></div></div>
</div>
<div class="layout">
<div class="sidebar">
<div class="suite-group " data-suite="0">
<div class="suite-title" onclick="this.parentElement.classList.toggle('open')">
<span class="dot pass"></span>
<span class="arrow"></span>
<span>签到功能</span>
<span class="cnt">25/25</span>
</div>
<div class="case-list">
<div class="case-item" data-suite="0" data-case="0" onclick="showCase( 0 , 0 )">
<span class="icon"></span>
<span>空数据查询-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="1" onclick="showCase( 0 , 1 )">
<span class="icon"></span>
<span>空数据-todayChecked=false</span>
</div>
<div class="case-item" data-suite="0" data-case="2" onclick="showCase( 0 , 2 )">
<span class="icon"></span>
<span>空数据-连续=0</span>
</div>
<div class="case-item" data-suite="0" data-case="3" onclick="showCase( 0 , 3 )">
<span class="icon"></span>
<span>空数据-累计=0</span>
</div>
<div class="case-item" data-suite="0" data-case="4" onclick="showCase( 0 , 4 )">
<span class="icon"></span>
<span>连续3天-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="5" onclick="showCase( 0 , 5 )">
<span class="icon"></span>
<span>连续3天-todayChecked=false</span>
</div>
<div class="case-item" data-suite="0" data-case="6" onclick="showCase( 0 , 6 )">
<span class="icon"></span>
<span>连续3天-continuously=3</span>
</div>
<div class="case-item" data-suite="0" data-case="7" onclick="showCase( 0 , 7 )">
<span class="icon"></span>
<span>连续3天-cumulative=3</span>
</div>
<div class="case-item" data-suite="0" data-case="8" onclick="showCase( 0 , 8 )">
<span class="icon"></span>
<span>断签-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="9" onclick="showCase( 0 , 9 )">
<span class="icon"></span>
<span>断签-continuously=0</span>
</div>
<div class="case-item" data-suite="0" data-case="10" onclick="showCase( 0 , 10 )">
<span class="icon"></span>
<span>断签-cumulative=2</span>
</div>
<div class="case-item" data-suite="0" data-case="11" onclick="showCase( 0 , 11 )">
<span class="icon"></span>
<span>断一天-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="12" onclick="showCase( 0 , 12 )">
<span class="icon"></span>
<span>断一天-continuously=1</span>
</div>
<div class="case-item" data-suite="0" data-case="13" onclick="showCase( 0 , 13 )">
<span class="icon"></span>
<span>断一天-cumulative=2</span>
</div>
<div class="case-item" data-suite="0" data-case="14" onclick="showCase( 0 , 14 )">
<span class="icon"></span>
<span>跨月-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="15" onclick="showCase( 0 , 15 )">
<span class="icon"></span>
<span>跨月-continuously=0</span>
</div>
<div class="case-item" data-suite="0" data-case="16" onclick="showCase( 0 , 16 )">
<span class="icon"></span>
<span>今天已签到-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="17" onclick="showCase( 0 , 17 )">
<span class="icon"></span>
<span>今天已签到-todayChecked=true</span>
</div>
<div class="case-item" data-suite="0" data-case="18" onclick="showCase( 0 , 18 )">
<span class="icon"></span>
<span>今天已签到-continuously=3</span>
</div>
<div class="case-item" data-suite="0" data-case="19" onclick="showCase( 0 , 19 )">
<span class="icon"></span>
<span>双倍奖励-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="20" onclick="showCase( 0 , 20 )">
<span class="icon"></span>
<span>6天连续&#43;未签到-doubleReward=true</span>
</div>
<div class="case-item" data-suite="0" data-case="21" onclick="showCase( 0 , 21 )">
<span class="icon"></span>
<span>6天连续-continuously=6</span>
</div>
<div class="case-item" data-suite="0" data-case="22" onclick="showCase( 0 , 22 )">
<span class="icon"></span>
<span>断签恢复-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="23" onclick="showCase( 0 , 23 )">
<span class="icon"></span>
<span>断签恢复-continuously=1</span>
</div>
<div class="case-item" data-suite="0" data-case="24" onclick="showCase( 0 , 24 )">
<span class="icon"></span>
<span>断签恢复-cumulative=3</span>
</div>
</div>
</div>
</div>
<div class="detail" id="detail">
<div class="empty">👈 点击左侧用例查看详情</div>
</div>
</div>
<script>
const DATA = [
[
{
name: "空数据查询-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 90 ,
func: "testQueryEmpty",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":0,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:19:58.522Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "空数据-todayChecked=false",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 95 ,
func: "testQueryEmpty",
detail: "",
got: "false",
want: "false",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "空数据-连续=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 96 ,
func: "testQueryEmpty",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "空数据-累计=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 97 ,
func: "testQueryEmpty",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 112 ,
func: "testContinuous3Days",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:19:59.645Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-todayChecked=false",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 115 ,
func: "testContinuous3Days",
detail: "",
got: "false",
want: "false",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-continuously=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 116 ,
func: "testContinuous3Days",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-cumulative=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 117 ,
func: "testContinuous3Days",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 129 ,
func: "testBrokenStreak",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:00.972Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "断签-continuously=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 131 ,
func: "testBrokenStreak",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签-cumulative=2",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 132 ,
func: "testBrokenStreak",
detail: "",
got: "2",
want: "2",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断一天-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 144 ,
func: "testBrokenStreakOneDayGap",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:02.170Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "断一天-continuously=1",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 146 ,
func: "testBrokenStreakOneDayGap",
detail: "",
got: "1",
want: "1",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断一天-cumulative=2",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 147 ,
func: "testBrokenStreakOneDayGap",
detail: "",
got: "2",
want: "2",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "跨月-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 160 ,
func: "testCrossMonthContinuous",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:03.531Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "跨月-continuously=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 162 ,
func: "testCrossMonthContinuous",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "今天已签到-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 180 ,
func: "testTodayChecked",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":true},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:04.950Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "今天已签到-todayChecked=true",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 182 ,
func: "testTodayChecked",
detail: "",
got: "true",
want: "true",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "今天已签到-continuously=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 183 ,
func: "testTodayChecked",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "双倍奖励-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 201 ,
func: "testDoubleReward",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":6,\"cumulativeDays\":6,\"doubleReward\":true,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:06.570Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "6天连续+未签到-doubleReward=true",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 203 ,
func: "testDoubleReward",
detail: "",
got: "true",
want: "true",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "6天连续-continuously=6",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 204 ,
func: "testDoubleReward",
detail: "",
got: "6",
want: "6",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签恢复-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 222 ,
func: "testCheckinAfterBroken",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:08.267Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "断签恢复-continuously=1",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 224 ,
func: "testCheckinAfterBroken",
detail: "",
got: "1",
want: "1",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签恢复-cumulative=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 225 ,
func: "testCheckinAfterBroken",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
],
];
function showCase(si, ci) {
document.querySelectorAll('.case-item.active').forEach(el => el.classList.remove('active'));
const item = document.querySelector('.case-item[data-suite="'+si+'"][data-case="'+ci+'"]');
if (item) item.classList.add('active');
const c = DATA[si][ci];
const el = document.getElementById('detail');
let html = '';
html += '<div class="d-header">';
html += '<h2><span class="status">' + (c.passed?'✅':'❌') + '</span> ' + esc(c.name) + '</h2>';
html += '<div class="d-meta">';
html += '<span>套件: ' + esc(c.suite) + '</span>';
if (c.file) html += '<span class="loc-link">📍 ' + esc(c.file) + ':' + c.line + ' → ' + esc(c.func) + '()</span>';
if (c.attempt > 1) html += '<span>重试 #' + c.attempt + '</span>';
html += '</div></div>';
html += '<div class="d-section"><h3>断言结果</h3><div class="kv-grid">';
html += '<span class="k">状态</span><span class="v ' + (c.passed?'pass':'fail') + '">' + (c.passed?'✅ 通过':'❌ 失败') + '</span>';
if (!c.passed && c.detail) html += '<span class="k">原因</span><span class="v fail">' + esc(c.detail) + '</span>';
if (c.got && c.got !== '<nil>') html += '<span class="k">实际值</span><span class="v">' + esc(c.got) + '</span>';
if (c.want && c.want !== '<nil>') html += '<span class="k">期望值</span><span class="v">' + esc(c.want) + '</span>';
html += '</div></div>';
if (c.curl) {
html += '<div class="d-section"><h3>cURL 命令</h3>';
html += '<div class="curl-block"><button class="copy-btn" onclick="copyCurl(this)">复制</button><code id="curl-code-'+si+'-'+ci+'"></code></div>';
html += '</div>';
}
if (c.reqURL) {
html += '<div class="d-section"><h3>请求信息</h3><div class="req-info">';
html += '<div class="req-row"><span class="rl">Method</span><span class="rv"><span class="method-badge ' + esc(c.reqMethod) + '">' + esc(c.reqMethod) + '</span></span></div>';
html += '<div class="req-row"><span class="rl">URL</span><span class="rv">' + esc(c.reqURL) + '</span></div>';
if (c.reqHeaders) {
const hkeys = Object.keys(c.reqHeaders);
for (let hi = 0; hi < hkeys.length; hi++) {
html += '<div class="req-row"><span class="rl">' + (hi===0?'Header':'') + '</span><span class="rv" style="color:#999">' + esc(hkeys[hi]) + ': ' + esc(c.reqHeaders[hkeys[hi]]) + '</span></div>';
}
}
if (c.reqBody && c.reqBody !== 'null') {
html += '<div style="margin-top:12px;font-size:12px;color:#94a3b8;margin-bottom:6px">Request Body</div>';
html += '<div class="jtree" id="req-tree-'+si+'-'+ci+'"></div>';
}
html += '</div></div>';
}
if (c.respBody) {
html += '<div class="d-section"><h3>响应信息</h3>';
const ok = c.respStatus >= 200 && c.respStatus < 300;
html += '<div class="resp-status-bar"><span>Status:</span> <span class="resp-code ' + (ok?'ok':'err') + '">HTTP ' + c.respStatus + '</span></div>';
html += '<div class="jtree" id="resp-tree-'+si+'-'+ci+'"></div>';
html += '</div>';
}
html += '<div class="footer">Generated by tests/framework</div>';
el.innerHTML = html;
if (c.reqBody && c.reqBody !== 'null') {
try { renderTree(document.getElementById('req-tree-'+si+'-'+ci), JSON.parse(c.reqBody)); }
catch(e) { var reqEl = document.getElementById('req-tree-'+si+'-'+ci); if(reqEl) reqEl.textContent = c.reqBody; }
}
if (c.respBody) {
try { renderTree(document.getElementById('resp-tree-'+si+'-'+ci), JSON.parse(c.respBody)); }
catch(e) { var respEl = document.getElementById('resp-tree-'+si+'-'+ci); if(respEl) respEl.textContent = c.respBody; }
}
const curlEl = document.getElementById('curl-code-'+si+'-'+ci);
if (curlEl) curlEl.textContent = c.curl;
}
function renderTree(container, data) {
if (!container) return;
container.innerHTML = '';
container.appendChild(buildNode(data, 0));
}
function buildNode(val, depth) {
if (val === null) return txtSpan('null', 'jb');
if (typeof val === 'boolean') return txtSpan(String(val), 'jb');
if (typeof val === 'number') return txtSpan(String(val), 'jn');
if (typeof val === 'string') return txtSpan('"' + val + '"', 'js');
const isArr = Array.isArray(val);
const keys = isArr ? val.map((_,i) => i) : Object.keys(val);
const wrap = document.createDocumentFragment();
const toggle = document.createElement('span');
toggle.className = 'jt';
toggle.textContent = isArr ? 'Array[' + keys.length + ']' : 'Object{' + keys.length + '}';
toggle.onclick = function(e) { e.stopPropagation(); this.classList.toggle('closed'); };
wrap.appendChild(toggle);
const block = document.createElement('div');
block.className = 'jc';
keys.forEach(k => {
const row = document.createElement('div');
row.className = 'ji';
if (!isArr) {
const kSpan = document.createElement('span');
kSpan.className = 'jk';
kSpan.textContent = '"' + k + '"';
row.appendChild(kSpan);
row.appendChild(document.createTextNode(': '));
}
row.appendChild(buildNode(val[k], depth + 1));
block.appendChild(row);
});
wrap.appendChild(block);
return wrap;
}
function txtSpan(text, cls) {
const s = document.createElement('span');
s.className = cls;
s.textContent = text;
return s;
}
function esc(s) {
if (!s) return '';
const d = document.createElement('div');
d.textContent = s;
return d.innerHTML;
}
function copyCurl(btn) {
const block = btn.parentElement;
const text = block.textContent.replace('复制', '').trim();
navigator.clipboard.writeText(text).then(() => {
btn.textContent = '已复制 ✓';
setTimeout(() => btn.textContent = '复制', 1500);
});
}
(function() {
for (let si = 0; si < DATA.length; si++) {
for (let ci = 0; ci < DATA[si].length; ci++) {
if (!DATA[si][ci].passed) { showCase(si, ci); return; }
}
}
if (DATA.length > 0 && DATA[0].length > 0) showCase(0, 0);
})();
</script>
</body>
</html>
@@ -0,0 +1,962 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>签到模块测试 - 测试报告</title>
<style>
:root {
--green: #059669; --red: #dc2626; --blue: #2563eb; --purple: #7c3aed;
--gray: #6b7280; --light: #f8fafc; --border: #e5e7eb; --sidebar-w: 320px;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f0f2f5; color: #1f2937; height: 100vh; overflow: hidden; }
.topbar {
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff; padding: 16px 28px; display: flex; align-items: center; gap: 32px; flex-wrap: wrap;
position: fixed; top: 0; left: 0; right: 0; z-index: 100; height: auto; min-height: 64px;
}
.topbar h1 { font-size: 18px; white-space: nowrap; }
.topbar .stats { display: flex; gap: 20px; align-items: center; }
.topbar .stat { text-align: center; }
.topbar .stat .num { font-size: 24px; font-weight: 800; }
.topbar .stat .lbl { font-size: 10px; opacity: .7; }
.topbar .stat.pass .num { color: #86efac; }
.topbar .stat.fail .num { color: #fca5a5; }
.topbar .stat.rate .num { color: #93c5fd; }
.topbar .delta { font-size: 10px; opacity: .8; }
.topbar .env-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.topbar .env-tags span { background: rgba(255,255,255,.15); padding: 3px 10px; border-radius: 6px; font-size: 11px; }
.topbar .progress { position: absolute; bottom: 0; left: 0; right: 0; height: 3px; background: rgba(255,255,255,.2); }
.topbar .progress .fill { height: 100%; background: #86efac; }
.layout { display: flex; margin-top: 64px; height: calc(100vh - 64px); }
.sidebar {
width: var(--sidebar-w); min-width: var(--sidebar-w); background: #fff;
border-right: 1px solid var(--border); overflow-y: auto; padding: 12px 0;
}
.sidebar .suite-group { margin-bottom: 4px; }
.sidebar .suite-title {
padding: 8px 16px; font-size: 13px; font-weight: 600; color: #374151;
display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none;
}
.sidebar .suite-title:hover { background: #f9fafb; }
.sidebar .suite-title .arrow { font-size: 10px; color: #aaa; transition: transform .2s; }
.sidebar .suite-group.open .arrow { transform: rotate(90deg); }
.sidebar .suite-title .cnt { margin-left: auto; font-size: 11px; font-weight: 400; color: #aaa; }
.sidebar .suite-title .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.sidebar .dot.pass { background: var(--green); } .sidebar .dot.fail { background: var(--red); } .sidebar .dot.skip { background: #fbbf24; }
.sidebar .case-list { display: none; }
.sidebar .suite-group.open .case-list { display: block; }
.sidebar .case-item {
padding: 6px 16px 6px 36px; font-size: 12px; cursor: pointer;
display: flex; align-items: center; gap: 6px; color: #6b7280;
border-left: 3px solid transparent;
}
.sidebar .case-item:hover { background: #f3f4f6; }
.sidebar .case-item.active { background: #eef2ff; border-left-color: #6366f1; color: #1f2937; font-weight: 500; }
.sidebar .case-item .icon { font-size: 12px; }
.detail {
flex: 1; overflow-y: auto; padding: 28px 36px; background: var(--light);
}
.detail .empty { color: #aaa; font-size: 15px; margin-top: 120px; text-align: center; }
.detail .d-header { margin-bottom: 24px; }
.detail .d-header h2 { font-size: 20px; margin-bottom: 8px; display: flex; align-items: center; gap: 10px; }
.detail .d-header h2 .status { font-size: 22px; }
.detail .d-header .d-meta { font-size: 13px; color: var(--gray); display: flex; gap: 16px; }
.detail .d-section { background: #fff; border-radius: 10px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 4px rgba(0,0,0,.05); }
.detail .d-section h3 { font-size: 14px; color: var(--gray); margin-bottom: 12px; font-weight: 500; }
.detail .kv-grid { display: grid; grid-template-columns: 56px 1fr; gap: 6px 12px; font-size: 14px; }
.detail .kv-grid .k { color: var(--gray); text-align: right; font-size: 13px; }
.detail .kv-grid .v { font-family: "SF Mono", Monaco, monospace; word-break: break-all; }
.detail .kv-grid .v.pass { color: var(--green); } .detail .kv-grid .v.fail { color: var(--red); }
.detail .curl-block {
background: #1e293b; color: #e2e8f0; border-radius: 8px; padding: 16px 18px;
font-family: "SF Mono", Monaco, "Cascadia Code", monospace; font-size: 13px;
white-space: pre-wrap; word-break: break-all; line-height: 1.7; position: relative;
}
.detail .curl-block .copy-btn {
position: absolute; top: 10px; right: 10px;
background: #475569; color: #e2e8f0; border: none; border-radius: 5px;
padding: 4px 14px; font-size: 12px; cursor: pointer;
}
.detail .curl-block .copy-btn:hover { background: #64748b; }
.detail .req-info { font-size: 13px; }
.detail .req-row { display: flex; gap: 10px; margin-bottom: 6px; align-items: baseline; }
.detail .req-row .rl { color: var(--gray); min-width: 56px; text-align: right; font-size: 12px; flex-shrink: 0; }
.detail .req-row .rv { font-family: "SF Mono", Monaco, monospace; word-break: break-all; }
.detail .method-badge { display: inline-block; padding: 2px 10px; border-radius: 4px; font-weight: 700; font-size: 12px; color: #fff; }
.detail .method-badge.GET { background: var(--blue); }
.detail .method-badge.POST { background: var(--green); }
.detail .method-badge.PUT { background: #d97706; }
.detail .method-badge.PATCH { background: #7c3aed; }
.detail .method-badge.DELETE { background: var(--red); }
.jtree { font-family: "SF Mono", Monaco, monospace; font-size: 12.5px; line-height: 1.8; background: #1e293b; color: #e2e8f0; border-radius: 8px; padding: 16px 18px; max-height: 500px; overflow: auto; }
.jtree .jk { color: #7dd3fc; } .jtree .js { color: #86efac; } .jtree .jn { color: #fbbf24; } .jtree .jb { color: #f87171; }
.jtree .jt { cursor: pointer; user-select: none; } .jtree .jt::before { content: "▼ "; font-size: 10px; color: #64748b; }
.jtree .jt.closed::before { content: "▶ "; } .jtree .jt.closed + .jc { display: none; }
.jtree .jc { } .jtree .ji { padding-left: 20px; }
.detail .resp-status-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.detail .resp-code { font-size: 14px; font-weight: 700; font-family: monospace; }
.detail .resp-code.ok { color: var(--green); }
.detail .resp-code.err { color: var(--red); }
.detail .loc-link { font-size: 12px; color: #6366f1; font-family: monospace; }
.footer { text-align: center; color: #bbb; font-size: 11px; padding: 16px 0; }
</style>
</head>
<body>
<div class="topbar">
<h1>签到模块测试</h1>
<div class="stats">
<div class="stat"><div class="num">25</div><div class="lbl">总计</div></div>
<div class="stat pass"><div class="num">25</div><div class="lbl">通过</div></div>
<div class="stat fail"><div class="num">0</div><div class="lbl">失败</div></div>
<div class="stat rate"><div class="num">100.0%</div><div class="lbl">通过率</div></div>
</div>
<div class="env-tags">
<span>📅 2026-05-08 16:29:23</span>
<span>⏱ 12s</span>
<span>项目: 91porn-server</span><span>模块: 签到</span><span>时间: 2026-05-08 16:29:10</span>
</div>
<div class="progress"><div class="fill" style="width:100%"></div></div>
</div>
<div class="layout">
<div class="sidebar">
<div class="suite-group " data-suite="0">
<div class="suite-title" onclick="this.parentElement.classList.toggle('open')">
<span class="dot pass"></span>
<span class="arrow"></span>
<span>签到功能</span>
<span class="cnt">25/25</span>
</div>
<div class="case-list">
<div class="case-item" data-suite="0" data-case="0" onclick="showCase( 0 , 0 )">
<span class="icon"></span>
<span>空数据查询-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="1" onclick="showCase( 0 , 1 )">
<span class="icon"></span>
<span>空数据-todayChecked=false</span>
</div>
<div class="case-item" data-suite="0" data-case="2" onclick="showCase( 0 , 2 )">
<span class="icon"></span>
<span>空数据-连续=0</span>
</div>
<div class="case-item" data-suite="0" data-case="3" onclick="showCase( 0 , 3 )">
<span class="icon"></span>
<span>空数据-累计=0</span>
</div>
<div class="case-item" data-suite="0" data-case="4" onclick="showCase( 0 , 4 )">
<span class="icon"></span>
<span>连续3天-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="5" onclick="showCase( 0 , 5 )">
<span class="icon"></span>
<span>连续3天-todayChecked=false</span>
</div>
<div class="case-item" data-suite="0" data-case="6" onclick="showCase( 0 , 6 )">
<span class="icon"></span>
<span>连续3天-continuously=3</span>
</div>
<div class="case-item" data-suite="0" data-case="7" onclick="showCase( 0 , 7 )">
<span class="icon"></span>
<span>连续3天-cumulative=3</span>
</div>
<div class="case-item" data-suite="0" data-case="8" onclick="showCase( 0 , 8 )">
<span class="icon"></span>
<span>断签-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="9" onclick="showCase( 0 , 9 )">
<span class="icon"></span>
<span>断签-continuously=0</span>
</div>
<div class="case-item" data-suite="0" data-case="10" onclick="showCase( 0 , 10 )">
<span class="icon"></span>
<span>断签-cumulative=2</span>
</div>
<div class="case-item" data-suite="0" data-case="11" onclick="showCase( 0 , 11 )">
<span class="icon"></span>
<span>断一天-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="12" onclick="showCase( 0 , 12 )">
<span class="icon"></span>
<span>断一天-continuously=1</span>
</div>
<div class="case-item" data-suite="0" data-case="13" onclick="showCase( 0 , 13 )">
<span class="icon"></span>
<span>断一天-cumulative=2</span>
</div>
<div class="case-item" data-suite="0" data-case="14" onclick="showCase( 0 , 14 )">
<span class="icon"></span>
<span>跨月-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="15" onclick="showCase( 0 , 15 )">
<span class="icon"></span>
<span>跨月-continuously=0</span>
</div>
<div class="case-item" data-suite="0" data-case="16" onclick="showCase( 0 , 16 )">
<span class="icon"></span>
<span>今天已签到-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="17" onclick="showCase( 0 , 17 )">
<span class="icon"></span>
<span>今天已签到-todayChecked=true</span>
</div>
<div class="case-item" data-suite="0" data-case="18" onclick="showCase( 0 , 18 )">
<span class="icon"></span>
<span>今天已签到-continuously=3</span>
</div>
<div class="case-item" data-suite="0" data-case="19" onclick="showCase( 0 , 19 )">
<span class="icon"></span>
<span>双倍奖励-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="20" onclick="showCase( 0 , 20 )">
<span class="icon"></span>
<span>6天连续&#43;未签到-doubleReward=true</span>
</div>
<div class="case-item" data-suite="0" data-case="21" onclick="showCase( 0 , 21 )">
<span class="icon"></span>
<span>6天连续-continuously=6</span>
</div>
<div class="case-item" data-suite="0" data-case="22" onclick="showCase( 0 , 22 )">
<span class="icon"></span>
<span>断签恢复-code=200</span>
</div>
<div class="case-item" data-suite="0" data-case="23" onclick="showCase( 0 , 23 )">
<span class="icon"></span>
<span>断签恢复-continuously=1</span>
</div>
<div class="case-item" data-suite="0" data-case="24" onclick="showCase( 0 , 24 )">
<span class="icon"></span>
<span>断签恢复-cumulative=3</span>
</div>
</div>
</div>
</div>
<div class="detail" id="detail">
<div class="empty">👈 点击左侧用例查看详情</div>
</div>
</div>
<script>
const DATA = [
[
{
name: "空数据查询-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 90 ,
func: "testQueryEmpty",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":0,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:12.515Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "空数据-todayChecked=false",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 95 ,
func: "testQueryEmpty",
detail: "",
got: "false",
want: "false",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "空数据-连续=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 96 ,
func: "testQueryEmpty",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "空数据-累计=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 97 ,
func: "testQueryEmpty",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 112 ,
func: "testContinuous3Days",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:13.756Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-todayChecked=false",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 115 ,
func: "testContinuous3Days",
detail: "",
got: "false",
want: "false",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-continuously=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 116 ,
func: "testContinuous3Days",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "连续3天-cumulative=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 117 ,
func: "testContinuous3Days",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 129 ,
func: "testBrokenStreak",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:15.122Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "断签-continuously=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 131 ,
func: "testBrokenStreak",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签-cumulative=2",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 132 ,
func: "testBrokenStreak",
detail: "",
got: "2",
want: "2",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断一天-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 144 ,
func: "testBrokenStreakOneDayGap",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:16.448Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "断一天-continuously=1",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 146 ,
func: "testBrokenStreakOneDayGap",
detail: "",
got: "1",
want: "1",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断一天-cumulative=2",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 147 ,
func: "testBrokenStreakOneDayGap",
detail: "",
got: "2",
want: "2",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "跨月-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 160 ,
func: "testCrossMonthContinuous",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:17.871Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "跨月-continuously=0",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 162 ,
func: "testCrossMonthContinuous",
detail: "",
got: "0",
want: "0",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "今天已签到-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 180 ,
func: "testTodayChecked",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":true},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:19.408Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "今天已签到-todayChecked=true",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 182 ,
func: "testTodayChecked",
detail: "",
got: "true",
want: "true",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "今天已签到-continuously=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 183 ,
func: "testTodayChecked",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "双倍奖励-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 201 ,
func: "testDoubleReward",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":6,\"cumulativeDays\":6,\"doubleReward\":true,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:21.166Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "6天连续+未签到-doubleReward=true",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 203 ,
func: "testDoubleReward",
detail: "",
got: "true",
want: "true",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "6天连续-continuously=6",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 204 ,
func: "testDoubleReward",
detail: "",
got: "6",
want: "6",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签恢复-code=200",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 222 ,
func: "testCheckinAfterBroken",
detail: "",
got: "200",
want: "200",
curl: "curl -X POST \\\n 'http://127.0.0.1:13051/api/app/checkin/prize' \\\n -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js' \\\n -H 'Content-Type: application/json' \\\n -H 'User-Agent: 91porn/3.8.0 (Android; test)' \\\n -H 'X-User-Agent: ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001' \\\n -d '{}'",
reqMethod: "POST",
reqURL: "http://127.0.0.1:13051/api/app/checkin/prize",
reqHeaders: { "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js", "Content-Type": "application/json", "User-Agent": "91porn/3.8.0 (Android; test)", "X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001", },
reqBody: "{}",
respStatus: 200 ,
respBody: "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:23.020Z\",\"tip\":\"\"}",
suite: "签到功能",
attempt: 0
},
{
name: "断签恢复-continuously=1",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 224 ,
func: "testCheckinAfterBroken",
detail: "",
got: "1",
want: "1",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
{
name: "断签恢复-cumulative=3",
passed: true ,
file: "tests/checkin/suite_checkin.go",
line: 225 ,
func: "testCheckinAfterBroken",
detail: "",
got: "3",
want: "3",
curl: "",
reqMethod: "",
reqURL: "",
reqHeaders: { },
reqBody: "",
respStatus: 0 ,
respBody: "",
suite: "签到功能",
attempt: 0
},
],
];
function showCase(si, ci) {
document.querySelectorAll('.case-item.active').forEach(el => el.classList.remove('active'));
const item = document.querySelector('.case-item[data-suite="'+si+'"][data-case="'+ci+'"]');
if (item) item.classList.add('active');
const c = DATA[si][ci];
const el = document.getElementById('detail');
let html = '';
html += '<div class="d-header">';
html += '<h2><span class="status">' + (c.passed?'✅':'❌') + '</span> ' + esc(c.name) + '</h2>';
html += '<div class="d-meta">';
html += '<span>套件: ' + esc(c.suite) + '</span>';
if (c.file) html += '<span class="loc-link">📍 ' + esc(c.file) + ':' + c.line + ' → ' + esc(c.func) + '()</span>';
if (c.attempt > 1) html += '<span>重试 #' + c.attempt + '</span>';
html += '</div></div>';
html += '<div class="d-section"><h3>断言结果</h3><div class="kv-grid">';
html += '<span class="k">状态</span><span class="v ' + (c.passed?'pass':'fail') + '">' + (c.passed?'✅ 通过':'❌ 失败') + '</span>';
if (!c.passed && c.detail) html += '<span class="k">原因</span><span class="v fail">' + esc(c.detail) + '</span>';
if (c.got && c.got !== '<nil>') html += '<span class="k">实际值</span><span class="v">' + esc(c.got) + '</span>';
if (c.want && c.want !== '<nil>') html += '<span class="k">期望值</span><span class="v">' + esc(c.want) + '</span>';
html += '</div></div>';
if (c.curl) {
html += '<div class="d-section"><h3>cURL 命令</h3>';
html += '<div class="curl-block"><button class="copy-btn" onclick="copyCurl(this)">复制</button><code id="curl-code-'+si+'-'+ci+'"></code></div>';
html += '</div>';
}
if (c.reqURL) {
html += '<div class="d-section"><h3>请求信息</h3><div class="req-info">';
html += '<div class="req-row"><span class="rl">Method</span><span class="rv"><span class="method-badge ' + esc(c.reqMethod) + '">' + esc(c.reqMethod) + '</span></span></div>';
html += '<div class="req-row"><span class="rl">URL</span><span class="rv">' + esc(c.reqURL) + '</span></div>';
if (c.reqHeaders) {
const hkeys = Object.keys(c.reqHeaders);
for (let hi = 0; hi < hkeys.length; hi++) {
html += '<div class="req-row"><span class="rl">' + (hi===0?'Header':'') + '</span><span class="rv" style="color:#999">' + esc(hkeys[hi]) + ': ' + esc(c.reqHeaders[hkeys[hi]]) + '</span></div>';
}
}
if (c.reqBody && c.reqBody !== 'null') {
html += '<div style="margin-top:12px;font-size:12px;color:#94a3b8;margin-bottom:6px">Request Body</div>';
html += '<div class="jtree" id="req-tree-'+si+'-'+ci+'"></div>';
}
html += '</div></div>';
}
if (c.respBody) {
html += '<div class="d-section"><h3>响应信息</h3>';
const ok = c.respStatus >= 200 && c.respStatus < 300;
html += '<div class="resp-status-bar"><span>Status:</span> <span class="resp-code ' + (ok?'ok':'err') + '">HTTP ' + c.respStatus + '</span></div>';
html += '<div class="jtree" id="resp-tree-'+si+'-'+ci+'"></div>';
html += '</div>';
}
html += '<div class="footer">Generated by tests/framework</div>';
el.innerHTML = html;
if (c.reqBody && c.reqBody !== 'null') {
try { renderTree(document.getElementById('req-tree-'+si+'-'+ci), JSON.parse(c.reqBody)); }
catch(e) { var reqEl = document.getElementById('req-tree-'+si+'-'+ci); if(reqEl) reqEl.textContent = c.reqBody; }
}
if (c.respBody) {
try { renderTree(document.getElementById('resp-tree-'+si+'-'+ci), JSON.parse(c.respBody)); }
catch(e) { var respEl = document.getElementById('resp-tree-'+si+'-'+ci); if(respEl) respEl.textContent = c.respBody; }
}
const curlEl = document.getElementById('curl-code-'+si+'-'+ci);
if (curlEl) curlEl.textContent = c.curl;
}
function renderTree(container, data) {
if (!container) return;
container.innerHTML = '';
container.appendChild(buildNode(data, 0));
}
function buildNode(val, depth) {
if (val === null) return txtSpan('null', 'jb');
if (typeof val === 'boolean') return txtSpan(String(val), 'jb');
if (typeof val === 'number') return txtSpan(String(val), 'jn');
if (typeof val === 'string') return txtSpan('"' + val + '"', 'js');
const isArr = Array.isArray(val);
const keys = isArr ? val.map((_,i) => i) : Object.keys(val);
const wrap = document.createDocumentFragment();
const toggle = document.createElement('span');
toggle.className = 'jt';
toggle.textContent = isArr ? 'Array[' + keys.length + ']' : 'Object{' + keys.length + '}';
toggle.onclick = function(e) { e.stopPropagation(); this.classList.toggle('closed'); };
wrap.appendChild(toggle);
const block = document.createElement('div');
block.className = 'jc';
keys.forEach(k => {
const row = document.createElement('div');
row.className = 'ji';
if (!isArr) {
const kSpan = document.createElement('span');
kSpan.className = 'jk';
kSpan.textContent = '"' + k + '"';
row.appendChild(kSpan);
row.appendChild(document.createTextNode(': '));
}
row.appendChild(buildNode(val[k], depth + 1));
block.appendChild(row);
});
wrap.appendChild(block);
return wrap;
}
function txtSpan(text, cls) {
const s = document.createElement('span');
s.className = cls;
s.textContent = text;
return s;
}
function esc(s) {
if (!s) return '';
const d = document.createElement('div');
d.textContent = s;
return d.innerHTML;
}
function copyCurl(btn) {
const block = btn.parentElement;
const text = block.textContent.replace('复制', '').trim();
navigator.clipboard.writeText(text).then(() => {
btn.textContent = '已复制 ✓';
setTimeout(() => btn.textContent = '复制', 1500);
});
}
(function() {
for (let si = 0; si < DATA.length; si++) {
for (let ci = 0; ci < DATA[si].length; ci++) {
if (!DATA[si][ci].passed) { showCase(si, ci); return; }
}
}
if (DATA.length > 0 && DATA[0].length > 0) showCase(0, 0);
})();
</script>
</body>
</html>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,363 @@
{
"duration": "11.335346958s",
"stats": {
"total": 25,
"passed": 25,
"failed": 0,
"skipped": 0
},
"suites": [
{
"name": "签到功能",
"results": [
{
"name": "空数据查询-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 90,
"func": "testQueryEmpty",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":0,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:19:58.522Z\",\"tip\":\"\"}"
}
},
{
"name": "空数据-todayChecked=false",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 95,
"func": "testQueryEmpty",
"got": false,
"want": false
},
{
"name": "空数据-连续=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 96,
"func": "testQueryEmpty",
"got": 0,
"want": 0
},
{
"name": "空数据-累计=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 97,
"func": "testQueryEmpty",
"got": 0,
"want": 0
},
{
"name": "连续3天-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 112,
"func": "testContinuous3Days",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:19:59.645Z\",\"tip\":\"\"}"
}
},
{
"name": "连续3天-todayChecked=false",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 115,
"func": "testContinuous3Days",
"got": false,
"want": false
},
{
"name": "连续3天-continuously=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 116,
"func": "testContinuous3Days",
"got": 3,
"want": 3
},
{
"name": "连续3天-cumulative=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 117,
"func": "testContinuous3Days",
"got": 3,
"want": 3
},
{
"name": "断签-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 129,
"func": "testBrokenStreak",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:00.972Z\",\"tip\":\"\"}"
}
},
{
"name": "断签-continuously=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 131,
"func": "testBrokenStreak",
"got": 0,
"want": 0
},
{
"name": "断签-cumulative=2",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 132,
"func": "testBrokenStreak",
"got": 2,
"want": 2
},
{
"name": "断一天-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 144,
"func": "testBrokenStreakOneDayGap",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:02.170Z\",\"tip\":\"\"}"
}
},
{
"name": "断一天-continuously=1",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 146,
"func": "testBrokenStreakOneDayGap",
"got": 1,
"want": 1
},
{
"name": "断一天-cumulative=2",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 147,
"func": "testBrokenStreakOneDayGap",
"got": 2,
"want": 2
},
{
"name": "跨月-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 160,
"func": "testCrossMonthContinuous",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:03.531Z\",\"tip\":\"\"}"
}
},
{
"name": "跨月-continuously=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 162,
"func": "testCrossMonthContinuous",
"got": 0,
"want": 0
},
{
"name": "今天已签到-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 180,
"func": "testTodayChecked",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":true},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:04.950Z\",\"tip\":\"\"}"
}
},
{
"name": "今天已签到-todayChecked=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 182,
"func": "testTodayChecked",
"got": true,
"want": true
},
{
"name": "今天已签到-continuously=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 183,
"func": "testTodayChecked",
"got": 3,
"want": 3
},
{
"name": "双倍奖励-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 201,
"func": "testDoubleReward",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":6,\"cumulativeDays\":6,\"doubleReward\":true,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:06.570Z\",\"tip\":\"\"}"
}
},
{
"name": "6天连续+未签到-doubleReward=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 203,
"func": "testDoubleReward",
"got": true,
"want": true
},
{
"name": "6天连续-continuously=6",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 204,
"func": "testDoubleReward",
"got": 6,
"want": 6
},
{
"name": "断签恢复-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 222,
"func": "testCheckinAfterBroken",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgxNTk5OTcsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.INz0ZZ2ZoGM7FnncWzec2jDZwQGbL8lJEoI6LETadAM",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"\",\"description\":\"测试签到配置\",\"enable\":true,\"integerExchangeList\":null},\"prizes\":[]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-07T13:20:08.267Z\",\"tip\":\"\"}"
}
},
{
"name": "断签恢复-continuously=1",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 224,
"func": "testCheckinAfterBroken",
"got": 1,
"want": 1
},
{
"name": "断签恢复-cumulative=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 225,
"func": "testCheckinAfterBroken",
"got": 3,
"want": 3
}
],
"elapsed": 11335345667
}
],
"time": "2026-05-07T21:20:08+08:00"
}
@@ -0,0 +1,363 @@
{
"duration": "12.377991708s",
"stats": {
"total": 25,
"passed": 25,
"failed": 0,
"skipped": 0
},
"suites": [
{
"name": "签到功能",
"results": [
{
"name": "空数据查询-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 90,
"func": "testQueryEmpty",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":0,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:12.515Z\",\"tip\":\"\"}"
}
},
{
"name": "空数据-todayChecked=false",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 95,
"func": "testQueryEmpty",
"got": false,
"want": false
},
{
"name": "空数据-连续=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 96,
"func": "testQueryEmpty",
"got": 0,
"want": 0
},
{
"name": "空数据-累计=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 97,
"func": "testQueryEmpty",
"got": 0,
"want": 0
},
{
"name": "连续3天-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 112,
"func": "testContinuous3Days",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:13.756Z\",\"tip\":\"\"}"
}
},
{
"name": "连续3天-todayChecked=false",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 115,
"func": "testContinuous3Days",
"got": false,
"want": false
},
{
"name": "连续3天-continuously=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 116,
"func": "testContinuous3Days",
"got": 3,
"want": 3
},
{
"name": "连续3天-cumulative=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 117,
"func": "testContinuous3Days",
"got": 3,
"want": 3
},
{
"name": "断签-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 129,
"func": "testBrokenStreak",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:15.122Z\",\"tip\":\"\"}"
}
},
{
"name": "断签-continuously=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 131,
"func": "testBrokenStreak",
"got": 0,
"want": 0
},
{
"name": "断签-cumulative=2",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 132,
"func": "testBrokenStreak",
"got": 2,
"want": 2
},
{
"name": "断一天-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 144,
"func": "testBrokenStreakOneDayGap",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:16.448Z\",\"tip\":\"\"}"
}
},
{
"name": "断一天-continuously=1",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 146,
"func": "testBrokenStreakOneDayGap",
"got": 1,
"want": 1
},
{
"name": "断一天-cumulative=2",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 147,
"func": "testBrokenStreakOneDayGap",
"got": 2,
"want": 2
},
{
"name": "跨月-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 160,
"func": "testCrossMonthContinuous",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:17.871Z\",\"tip\":\"\"}"
}
},
{
"name": "跨月-continuously=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 162,
"func": "testCrossMonthContinuous",
"got": 0,
"want": 0
},
{
"name": "今天已签到-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 180,
"func": "testTodayChecked",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":true},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:19.408Z\",\"tip\":\"\"}"
}
},
{
"name": "今天已签到-todayChecked=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 182,
"func": "testTodayChecked",
"got": true,
"want": true
},
{
"name": "今天已签到-continuously=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 183,
"func": "testTodayChecked",
"got": 3,
"want": 3
},
{
"name": "双倍奖励-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 201,
"func": "testDoubleReward",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":6,\"cumulativeDays\":6,\"doubleReward\":true,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:21.166Z\",\"tip\":\"\"}"
}
},
{
"name": "6天连续+未签到-doubleReward=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 203,
"func": "testDoubleReward",
"got": true,
"want": true
},
{
"name": "6天连续-continuously=6",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 204,
"func": "testDoubleReward",
"got": 6,
"want": 6
},
{
"name": "断签恢复-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 222,
"func": "testCheckinAfterBroken",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjg5NTAsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.Rp5rRh5CNUDwUahtYoVGtej_cEqTuinyOIZ_vbr03js",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a2\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99db2354ba0975cac478\",\"prizeName\":\"积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:29:23.020Z\",\"tip\":\"\"}"
}
},
{
"name": "断签恢复-continuously=1",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 224,
"func": "testCheckinAfterBroken",
"got": 1,
"want": 1
},
{
"name": "断签恢复-cumulative=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 225,
"func": "testCheckinAfterBroken",
"got": 3,
"want": 3
}
],
"elapsed": 12377968917
}
],
"time": "2026-05-08T16:29:23+08:00"
}
@@ -0,0 +1,441 @@
{
"duration": "14.859319041s",
"stats": {
"total": 32,
"passed": 32,
"failed": 0,
"skipped": 0
},
"suites": [
{
"name": "签到功能",
"results": [
{
"name": "空数据查询-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 126,
"func": "testQueryEmpty",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":0,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:06.203Z\",\"tip\":\"\"}"
}
},
{
"name": "空数据-todayChecked=false",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 131,
"func": "testQueryEmpty",
"got": false,
"want": false
},
{
"name": "空数据-连续=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 132,
"func": "testQueryEmpty",
"got": 0,
"want": 0
},
{
"name": "空数据-累计=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 133,
"func": "testQueryEmpty",
"got": 0,
"want": 0
},
{
"name": "连续3天-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 148,
"func": "testContinuous3Days",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:07.531Z\",\"tip\":\"\"}"
}
},
{
"name": "连续3天-todayChecked=false",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 151,
"func": "testContinuous3Days",
"got": false,
"want": false
},
{
"name": "连续3天-continuously=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 152,
"func": "testContinuous3Days",
"got": 3,
"want": 3
},
{
"name": "连续3天-cumulative=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 153,
"func": "testContinuous3Days",
"got": 3,
"want": 3
},
{
"name": "断签-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 165,
"func": "testBrokenStreak",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:08.957Z\",\"tip\":\"\"}"
}
},
{
"name": "断签-continuously=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 167,
"func": "testBrokenStreak",
"got": 0,
"want": 0
},
{
"name": "断签-cumulative=2",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 168,
"func": "testBrokenStreak",
"got": 2,
"want": 2
},
{
"name": "断一天-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 180,
"func": "testBrokenStreakOneDayGap",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":2,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:10.517Z\",\"tip\":\"\"}"
}
},
{
"name": "断一天-continuously=1",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 182,
"func": "testBrokenStreakOneDayGap",
"got": 1,
"want": 1
},
{
"name": "断一天-cumulative=2",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 183,
"func": "testBrokenStreakOneDayGap",
"got": 2,
"want": 2
},
{
"name": "跨月-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 196,
"func": "testCrossMonthContinuous",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":0,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:12.074Z\",\"tip\":\"\"}"
}
},
{
"name": "跨月-continuously=0",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 198,
"func": "testCrossMonthContinuous",
"got": 0,
"want": 0
},
{
"name": "今天已签到-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 216,
"func": "testTodayChecked",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":true},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:13.703Z\",\"tip\":\"\"}"
}
},
{
"name": "今天已签到-todayChecked=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 218,
"func": "testTodayChecked",
"got": true,
"want": true
},
{
"name": "今天已签到-continuously=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 219,
"func": "testTodayChecked",
"got": 3,
"want": 3
},
{
"name": "双倍奖励-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 237,
"func": "testDoubleReward",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":6,\"cumulativeDays\":6,\"doubleReward\":true,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:15.525Z\",\"tip\":\"\"}"
}
},
{
"name": "6天连续+未签到-doubleReward=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 239,
"func": "testDoubleReward",
"got": true,
"want": true
},
{
"name": "6天连续-continuously=6",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 240,
"func": "testDoubleReward",
"got": 6,
"want": 6
},
{
"name": "断签恢复-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 258,
"func": "testCheckinAfterBroken",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":1,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":false},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":false,\"isReceive\":false,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:17.371Z\",\"tip\":\"\"}"
}
},
{
"name": "断签恢复-continuously=1",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 260,
"func": "testCheckinAfterBroken",
"got": 1,
"want": 1
},
{
"name": "断签恢复-cumulative=3",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 261,
"func": "testCheckinAfterBroken",
"got": 3,
"want": 3
},
{
"name": "isCheckedIn-code=200",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 279,
"func": "testIsCheckedIn",
"got": 200,
"want": 200,
"request": {
"method": "POST",
"url": "http://127.0.0.1:13051/api/app/checkin/prize",
"headers": {
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE3NzgyMjkxMjQsInR5cGUiOjAsInVpZCI6MzAwMTAwfQ.iin-dSFNLY267ImH9PhARkSfGXnkX2yhUsTFdAeIKDk",
"Content-Type": "application/json",
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0\u0026sysType=android\u0026devType=test\u0026devId=checkin-test-001"
},
"body": "{}"
},
"response": {
"statusCode": 200,
"body": "{\"code\":200,\"data\":{\"bigPrizes\":[{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c0\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第1天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},{\"bigPrize\":true,\"canClaim\":false,\"checkinDays\":2,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e32354ba0975cac4c1\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fc99dc2354ba0975cac481\",\"prizeName\":\"VIP积分x5\",\"prizeType\":8,\"score\":5,\"status\":true,\"title\":\"VIP第2天\",\"updatedAt\":\"2026-05-07T21:55:38.682+08:00\"},\"... (31 items total)\"],\"checkin\":{\"continuouslyDays\":3,\"cumulativeDays\":3,\"doubleReward\":false,\"todayChecked\":true},\"config\":{\"backgroundImage\":\"cf230705/image/2mf/x9/2n2/v/ddddedb148a7bdc7b4ded365861ddc55.jpeg\",\"description\":\"每日签到领好礼!连续签到天数越多奖励越丰厚,第7天可获得双倍奖励!月卡VIP用户每天额外领取专属奖品。坚持签到31天有超级大礼!\",\"enable\":true,\"integerExchangeList\":[{\"icon\":\"cf230705/image/kc/1ad/2t8/1yc/521c547f934cfb05bc0a105a2eb93c3b.jpeg\",\"name\":\"观影券 X2\"},{\"icon\":\"cf230705/image/4/2ha/x0/2qt/1db16a6ef0d197daf4d084bad2aff665.jpeg\",\"name\":\"VIP体验 X2\"}]},\"prizes\":[{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"2026-05-07T21:55:38.682+08:00\",\"id\":\"69fc99e02354ba0975cac4a1\",\"image\":\"cf230705/image/1wc/sl/na/14c/164e8a0b0496b2c4525e5f98d116331f.png\",\"isCheckedIn\":true,\"isReceive\":true,\"prizeId\":\"69fc99dc2354ba0975cac485\",\"prizeName\":\"积分x3\",\"prizeType\":8,\"score\":3,\"status\":true,\"title\":\"第1天\",\"updatedAt\":\"2026-05-08T13:09:01.62+08:00\"},{\"bigPrize\":false,\"canClaim\":false,\"checkinDays\":1,\"checkinType\":1,\"createdAt\":\"0001-01-01T08:05:43+08:05\",\"id\":\"69fd9f84fdb9ef08e4d0451a\",\"image\":\"\",\"isCheckedIn\":true,\"isReceive\":false,\"prizeId\":\"69fd9f84fdb9ef08e4d0451b\",\"prizeName\":\"测试奖品1\",\"prizeType\":0,\"score\":0,\"status\":true,\"title\":\"测试奖品第1天\",\"updatedAt\":\"0001-01-01T08:05:43+08:05\"},\"... (34 items total)\"]},\"hash\":false,\"msg\":\"success\",\"time\":\"2026-05-08T08:32:18.998Z\",\"tip\":\"\"}"
}
},
{
"name": "第1天-isCheckedIn=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 290,
"func": "testIsCheckedIn",
"got": true,
"want": true
},
{
"name": "第1天-isReceive=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 291,
"func": "testIsCheckedIn",
"got": true,
"want": true
},
{
"name": "第2天-isCheckedIn=true(签到未发奖)",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 295,
"func": "testIsCheckedIn",
"got": true,
"want": true
},
{
"name": "第2天-isReceive=false(奖品未发放)",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 296,
"func": "testIsCheckedIn",
"got": false,
"want": false
},
{
"name": "第3天-isCheckedIn=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 300,
"func": "testIsCheckedIn",
"got": true,
"want": true
},
{
"name": "第3天-isReceive=true",
"passed": true,
"file": "tests/checkin/suite_checkin.go",
"line": 301,
"func": "testIsCheckedIn",
"got": true,
"want": true
}
],
"elapsed": 14859290417
}
],
"time": "2026-05-08T16:32:19+08:00"
}
+98
View File
@@ -0,0 +1,98 @@
package main
import (
"fmt"
"time"
"91porn-server/app/appg"
"91porn-server/app/middleware/authuser"
"91porn-server/app/router"
"91porn-server/common"
"91porn-server/common/cachev2"
"91porn-server/common/conf"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/common/services"
"91porn-server/models"
"91porn-server/models/Init"
fw "git.ruishengces.com/pub_tool/autotest"
"github.com/gin-gonic/gin"
)
type Env struct {
AppToken string // APP 用户 token
TestUID uint64
}
func (e *Env) Start(cfg fw.Config, base *fw.BaseEnv) {
time.Local, _ = time.LoadLocation("Asia/Shanghai")
// 读取配置
appCfg := appg.GlobalConfig{}
if err := conf.LoadJSON("../../app/config/app.json", &appCfg); err != nil {
panic("load config error: " + err.Error())
}
appg.Conf = &appCfg
log.Init(log.Options{Level: appCfg.Log.Level, DisableStack: appCfg.Log.DisableStacktrace})
common.InitGinSecret(appCfg.Base.ResKey, appCfg.Base.ResKey360, appCfg.Base.Env)
// 初始化 MongoDB
ds := db.InitDS(appg.InitMongodbParam(models.RegisterPool))
for k, v := range ds {
switch k {
case models.VideoDb:
appg.VideoDB = v
case models.LogDb:
appg.LogDB = v
case models.StatDb:
appg.StatDB = v
}
}
// 初始化 Redis
appg.InitRedis()
services.Init(appg.Redis)
cachev2.Init(appg.Redis, log.ZapLog)
// 初始化 Models
Init.InitMongo()
// 生成 APP 测试 token
e.TestUID = 300100
var err error
e.AppToken, err = authuser.GenToken(&authuser.Claims{
UID: e.TestUID,
Timestamp: time.Now().Unix(),
Type: 0,
})
if err != nil {
panic("gen token error: " + err.Error())
}
// 缓存到 Redis
tokenKey := fmt.Sprintf("token:user:%d", e.TestUID)
_ = appg.Redis.Set(tokenKey, e.AppToken, 24*time.Hour)
// 启动 HTTP 服务
gin.SetMode(gin.TestMode)
base.AppBaseURL = base.StartHTTP("APP", 13051, router.SetupGin())
}
func (e *Env) SetupData() {
// 基础数据由各 Suite 的 Setup 负责
}
func (e *Env) CleanData() {}
func (e *Env) Destroy() {
db.CloseDS()
_ = appg.RedisClose()
}
func (e *Env) Meta() []fw.ReportMeta {
return []fw.ReportMeta{
{Key: "项目", Value: "91porn-server"},
{Key: "模块", Value: "签到"},
{Key: "时间", Value: time.Now().Format("2006-01-02 15:04:05")},
}
}
+302
View File
@@ -0,0 +1,302 @@
package main
import (
"fmt"
"time"
"91porn-server/common/timeutil"
"91porn-server/models/v/checkinconfigmod"
"91porn-server/models/v/checkinprizemod"
"91porn-server/models/v/usercheckinmod"
fw "git.ruishengces.com/pub_tool/autotest"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type CheckinSuite struct {
env *Env
url string // AppBaseURL
prizeIds []primitive.ObjectID
}
func (s *CheckinSuite) Name() string { return "签到功能" }
func (s *CheckinSuite) Setup(ctx *fw.TestContext) error {
// 确保签到功能已启用
cfg, _ := checkinconfigmod.FindOne(bson.M{})
if cfg == nil {
if err := checkinconfigmod.InsertOne(&checkinconfigmod.CheckinConfig{
Enable: true,
Description: "测试签到",
}); err != nil {
return err
}
} else if !cfg.Enable {
if err := checkinconfigmod.UpdateOne(bson.M{"_id": cfg.ID}, bson.M{"$set": bson.M{"enable": true}}); err != nil {
return err
}
}
// 创建测试用签到奖品配置(连续签到第1~3天)
s.prizeIds = make([]primitive.ObjectID, 3)
for i := 0; i < 3; i++ {
id := primitive.NewObjectID()
s.prizeIds[i] = id
if err := checkinprizemod.InsertOne(&checkinprizemod.CheckinPrize{
ID: id,
Title: fmt.Sprintf("测试奖品第%d天", i+1),
CheckinDays: int64(i + 1),
CheckinType: checkinprizemod.CheckinTypeContinuously,
PrizeId: primitive.NewObjectID(), // 故意用不存在的奖品ID
PrizeName: fmt.Sprintf("测试奖品%d", i+1),
Status: true,
BigPrize: false,
}); err != nil {
return err
}
}
return nil
}
func (s *CheckinSuite) Teardown(ctx *fw.TestContext) {
s.cleanCheckins()
s.cleanPrizes()
}
func (s *CheckinSuite) cleanCheckins() {
for {
n, _ := usercheckinmod.DeleteOne(bson.M{"userId": s.env.TestUID})
if n == 0 {
break
}
}
}
func (s *CheckinSuite) cleanPrizes() {
for _, id := range s.prizeIds {
checkinprizemod.DeleteOne(bson.M{"_id": id})
}
}
func (s *CheckinSuite) insertRecord(date time.Time, contDays, cumDays int64) {
s.insertRecordWithGave(date, contDays, cumDays, true)
}
func (s *CheckinSuite) insertRecordWithGave(date time.Time, contDays, cumDays int64, gave bool) {
_ = usercheckinmod.InsertOne(&usercheckinmod.UserCheckin{
ID: primitive.NewObjectID(),
Date: timeutil.BeginOfTime(date),
UserId: s.env.TestUID,
Gave: gave,
ContinuouslyDays: contDays,
CumulativeDays: cumDays,
CreatedAt: date,
})
}
func (s *CheckinSuite) headers() map[string]string {
return map[string]string{
"Authorization": s.env.AppToken,
"User-Agent": "91porn/3.8.0 (Android; test)",
"X-User-Agent": "ver=3.8.0&sysType=android&devType=test&devId=checkin-test-001",
}
}
func (s *CheckinSuite) getPrize() *fw.Resp {
return fw.DoWithHeaders("POST", s.url+"/api/app/checkin/prize", map[string]interface{}{}, s.headers())
}
func (s *CheckinSuite) Run(ctx *fw.TestContext) {
s.testQueryEmpty(ctx)
s.testContinuous3Days(ctx)
s.testBrokenStreak(ctx)
s.testBrokenStreakOneDayGap(ctx)
s.testCrossMonthContinuous(ctx)
s.testTodayChecked(ctx)
s.testDoubleReward(ctx)
s.testCheckinAfterBroken(ctx)
s.testIsCheckedIn(ctx)
}
// 空数据查询
func (s *CheckinSuite) testQueryEmpty(ctx *fw.TestContext) {
s.cleanCheckins()
resp := s.getPrize()
ctx.CodeEqual("空数据查询-code=200", resp, 200)
data := resp.Data()
if data != nil {
checkin, _ := data["checkin"].(map[string]interface{})
if checkin != nil {
ctx.Equal("空数据-todayChecked=false", checkin["todayChecked"], false)
ctx.Equal("空数据-连续=0", fw.Num(checkin, "continuouslyDays"), float64(0))
ctx.Equal("空数据-累计=0", fw.Num(checkin, "cumulativeDays"), float64(0))
}
}
}
// 连续签到3天
func (s *CheckinSuite) testContinuous3Days(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
today := timeutil.BeginOfTime(now)
s.insertRecord(today.Add(-3*24*time.Hour), 1, 1)
s.insertRecord(today.Add(-2*24*time.Hour), 2, 2)
s.insertRecord(today.Add(-1*24*time.Hour), 3, 3)
resp := s.getPrize()
ctx.CodeEqual("连续3天-code=200", resp, 200)
data := resp.Data()
checkin, _ := data["checkin"].(map[string]interface{})
ctx.Equal("连续3天-todayChecked=false", checkin["todayChecked"], false)
ctx.Equal("连续3天-continuously=3", fw.Num(checkin, "continuouslyDays"), float64(3))
ctx.Equal("连续3天-cumulative=3", fw.Num(checkin, "cumulativeDays"), float64(3))
}
// 断签:4天前、3天前签到,昨天和前天没签
func (s *CheckinSuite) testBrokenStreak(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
today := timeutil.BeginOfTime(now)
s.insertRecord(today.Add(-4*24*time.Hour), 1, 1)
s.insertRecord(today.Add(-3*24*time.Hour), 2, 2)
resp := s.getPrize()
ctx.CodeEqual("断签-code=200", resp, 200)
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
ctx.Equal("断签-continuously=0", fw.Num(checkin, "continuouslyDays"), float64(0))
ctx.Equal("断签-cumulative=2", fw.Num(checkin, "cumulativeDays"), float64(2))
}
// 中间断一天:3天前签,2天前没签,昨天签
func (s *CheckinSuite) testBrokenStreakOneDayGap(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
today := timeutil.BeginOfTime(now)
s.insertRecord(today.Add(-3*24*time.Hour), 1, 1)
s.insertRecord(today.Add(-1*24*time.Hour), 1, 2)
resp := s.getPrize()
ctx.CodeEqual("断一天-code=200", resp, 200)
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
ctx.Equal("断一天-continuously=1", fw.Num(checkin, "continuouslyDays"), float64(1))
ctx.Equal("断一天-cumulative=2", fw.Num(checkin, "cumulativeDays"), float64(2))
}
// 跨月:上月记录不计入连续
func (s *CheckinSuite) testCrossMonthContinuous(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
beginOfMonth := timeutil.BeginningOfMonth(now)
s.insertRecord(beginOfMonth.Add(-3*24*time.Hour), 1, 1)
s.insertRecord(beginOfMonth.Add(-2*24*time.Hour), 2, 2)
s.insertRecord(beginOfMonth.Add(-1*24*time.Hour), 3, 3)
resp := s.getPrize()
ctx.CodeEqual("跨月-code=200", resp, 200)
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
ctx.Equal("跨月-continuously=0", fw.Num(checkin, "continuouslyDays"), float64(0))
ctx.Info(fmt.Sprintf("跨月-cumulative=%v (含上月记录,原版行为)", fw.Num(checkin, "cumulativeDays")))
}
// 今天已签到
func (s *CheckinSuite) testTodayChecked(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
today := timeutil.BeginOfTime(now)
if now.Day() < 3 {
ctx.Info("月初不足3天,跳过今天已签到测试")
return
}
s.insertRecord(today.Add(-2*24*time.Hour), 1, 1)
s.insertRecord(today.Add(-1*24*time.Hour), 2, 2)
s.insertRecord(today, 3, 3)
resp := s.getPrize()
ctx.CodeEqual("今天已签到-code=200", resp, 200)
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
ctx.Equal("今天已签到-todayChecked=true", checkin["todayChecked"], true)
ctx.Equal("今天已签到-continuously=3", fw.Num(checkin, "continuouslyDays"), float64(3))
}
// 第7天双倍奖励
func (s *CheckinSuite) testDoubleReward(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
today := timeutil.BeginOfTime(now)
if now.Day() < 7 {
ctx.Info("本月不足7天,跳过双倍奖励测试")
return
}
for i := 6; i >= 1; i-- {
d := today.Add(time.Duration(-i) * 24 * time.Hour)
s.insertRecord(d, int64(7-i), int64(7-i))
}
resp := s.getPrize()
ctx.CodeEqual("双倍奖励-code=200", resp, 200)
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
ctx.Equal("6天连续+未签到-doubleReward=true", checkin["doubleReward"], true)
ctx.Equal("6天连续-continuously=6", fw.Num(checkin, "continuouslyDays"), float64(6))
}
// 断签后恢复
func (s *CheckinSuite) testCheckinAfterBroken(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
today := timeutil.BeginOfTime(now)
if now.Day() < 5 {
ctx.Info("月初不足5天,跳过断签恢复测试")
return
}
s.insertRecord(today.Add(-5*24*time.Hour), 1, 1)
s.insertRecord(today.Add(-4*24*time.Hour), 2, 2)
// 3天前和2天前断签
s.insertRecord(today.Add(-1*24*time.Hour), 1, 3)
resp := s.getPrize()
ctx.CodeEqual("断签恢复-code=200", resp, 200)
checkin, _ := resp.Data()["checkin"].(map[string]interface{})
ctx.Equal("断签恢复-continuously=1", fw.Num(checkin, "continuouslyDays"), float64(1))
ctx.Equal("断签恢复-cumulative=3", fw.Num(checkin, "cumulativeDays"), float64(3))
}
// isCheckedIn字段:签到但未发奖时isCheckedIn=trueisReceive=false
func (s *CheckinSuite) testIsCheckedIn(ctx *fw.TestContext) {
s.cleanCheckins()
now := time.Now().Local()
today := timeutil.BeginOfTime(now)
if now.Day() < 3 {
ctx.Info("月初不足3天,跳过isCheckedIn测试")
return
}
// 第1天正常发奖,第2天签到但未发奖(Gave=false),第3天正常发奖
s.insertRecord(today.Add(-2*24*time.Hour), 1, 1)
s.insertRecordWithGave(today.Add(-1*24*time.Hour), 2, 2, false) // 签到了但奖品未发放
s.insertRecord(today, 3, 3)
resp := s.getPrize()
ctx.CodeEqual("isCheckedIn-code=200", resp, 200)
data := resp.Data()
prizes, _ := data["prizes"].([]interface{})
if len(prizes) < 3 {
ctx.Info(fmt.Sprintf("prizes数量不足3个(got=%d),跳过isCheckedIn断言", len(prizes)))
return
}
// 第1天:isCheckedIn=true, isReceive=true
p1, _ := prizes[0].(map[string]interface{})
ctx.Equal("第1天-isCheckedIn=true", p1["isCheckedIn"], true)
ctx.Equal("第1天-isReceive=true", p1["isReceive"], true)
// 第2天:签到了但未发奖 → isCheckedIn=true, isReceive=false
p2, _ := prizes[1].(map[string]interface{})
ctx.Equal("第2天-isCheckedIn=true(签到未发奖)", p2["isCheckedIn"], true)
ctx.Equal("第2天-isReceive=false(奖品未发放)", p2["isReceive"], false)
// 第3天:isCheckedIn=true, isReceive=true
p3, _ := prizes[2].(map[string]interface{})
ctx.Equal("第3天-isCheckedIn=true", p3["isCheckedIn"], true)
ctx.Equal("第3天-isReceive=true", p3["isReceive"], true)
}