feat: wire lucky gift go flow and reward config updates

This commit is contained in:
hy001 2026-04-18 18:53:09 +08:00
parent 7331cfea51
commit 621b15079e
28 changed files with 1067 additions and 379 deletions

View File

@ -10,12 +10,12 @@ spring:
red-circle:
log:
tencent-cls:
secret-id: IKID1pNfgOmrc4G8frlNfcEWU7PMkrd4AwNU
secret-key: oISIp41i7F6fwvby1kCLBivsWqrZ07vV
endpoint: ap-singapore.cls.tencentcs.com
region: ap-singapore
secret-id: ${LIKEI_TENCENT_CLS_SECRET_ID}
secret-key: ${LIKEI_TENCENT_CLS_SECRET_KEY}
endpoint: ${LIKEI_TENCENT_CLS_ENDPOINT}
region: ${LIKEI_TENCENT_CLS_REGION}
rtc:
appId: 4b5e5cea3b86476caf7f7a57d05b82d1
certificate: a6feb209de6448148a926f59634807bb
killRoom: https://api.sd-rtn.com/dev/v1/kicking-rule
authKey: Basic ZTA0MTVjMzYwZjBmNDNhZGFhNTdjZDZmNjgwYTFiZWQ6MWIyYmNjZDU0NGQzNDRhYmJhMTNiNDliZjUyMGY4MTI=
appId: ${LIKEI_RTC_APP_ID}
certificate: ${LIKEI_RTC_CERTIFICATE}
killRoom: ${LIKEI_RTC_KILL_ROOM_URL}
authKey: ${LIKEI_RTC_AUTH_KEY}

View File

@ -2,18 +2,20 @@ framework:
nacos:
subscribeServices:
- rc-auth
- rc-gateway
- rc-service-console
- rc-service-external
- rc-service-order
- rc-service-other
- rc-service-team
- rc-service-user
- rc-service-wallet
- rc-service-live
- rc-scheduling
- game-fruit
- visual-monitor
healthEndpoint: /actuator/health
healthStatus: UP
healthCheckSleepTime: 5000
healthSuccessWaitTime: 5000
instanceDownWaitTime: 15000
stopAfterWaitTime: 5000
stopKey: CxILm9hA1b9hF3Hl
stopKey: ${LIKEI_FRAMEWORK_NACOS_STOP_KEY}

View File

@ -1,7 +1,7 @@
spring:
data:
mongodb:
uri: mongodb://root:123456@localhost:27017/tarab_all?authSource=admin&readPreference=secondaryPreferred&retryWrites=false&maxPoolSize=50&minPoolSize=5&maxIdleTimeMS=6000
uri: ${LIKEI_MONGO_URI}
logging:

View File

@ -3,10 +3,9 @@ spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/likei?characterEncoding=utf8&useUnicode=true&useSSL=false&allowMultiQueries=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&autoReconnect=true
# url: jdbc:p6spy:mysql://10.0.17.81:3306/likei?characterEncoding=utf8&useUnicode=true&useSSL=false&allowMultiQueries=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&autoReconnect=true
username: root
password: 123456
url: ${LIKEI_MYSQL_JDBC_URL}
username: ${LIKEI_MYSQL_USERNAME}
password: ${LIKEI_MYSQL_PASSWORD}
hikari:
# 连接池名称

View File

@ -1,13 +1,13 @@
spring:
data:
redis:
port: 6379
host: localhost
port: ${LIKEI_REDIS_PORT}
host: ${LIKEI_REDIS_HOST}
# username: prod
ssl:
enabled: false
database: 0
database: ${LIKEI_REDIS_DATABASE}
timeout: 120000
lettuce:
pool:

View File

@ -1,4 +1,5 @@
rocketmq:
accessKey: ak9ogoaw3zm5b5d2b2e4f05
secretKey: sk0caf0e8a8b5a9109
endpoints: rmq-9ogoaw3zm.rocketmq.sg.qcloud.tencenttdmq.com:8080
accessKey: ${LIKEI_ROCKETMQ_ACCESS_KEY}
secretKey: ${LIKEI_ROCKETMQ_SECRET_KEY}
endpoints: ${LIKEI_ROCKETMQ_ENDPOINT}
local-disable: ${LIKEI_ROCKETMQ_LOCAL_DISABLE}

View File

@ -11,81 +11,93 @@ spring:
maxAge: 360000
routes:
- id: service-auth
uri: lb://rc-auth
uri: ${LIKEI_GATEWAY_ROUTE_AUTH_URI}
predicates:
- Path=/auth/**
filters:
- StripPrefix=1
- id: service-external
uri: lb://rc-service-external
uri: ${LIKEI_GATEWAY_ROUTE_EXTERNAL_URI}
predicates:
- Path=/external/**
filters:
- StripPrefix=1
- id: service-order
uri: lb://rc-service-order
uri: ${LIKEI_GATEWAY_ROUTE_ORDER_URI}
predicates:
- Path=/order/**
filters:
- StripPrefix=1
- id: service-wallet
uri: lb://rc-service-wallet
uri: ${LIKEI_GATEWAY_ROUTE_WALLET_URI}
predicates:
- Path=/wallet/**
filters:
- StripPrefix=1
- id: service-live
uri: lb://rc-service-live
uri: ${LIKEI_GATEWAY_ROUTE_LIVE_URI}
predicates:
- Path=/live/**
filters:
- StripPrefix=1
- id: invite-campaign-public
uri: http://10.2.1.16:2900
uri: ${LIKEI_GATEWAY_ROUTE_INVITE_PUBLIC_URI}
predicates:
- Path=/public/h5/invite-campaign/**
- id: invite-campaign-app
uri: http://10.2.1.16:2900
uri: ${LIKEI_GATEWAY_ROUTE_INVITE_APP_URI}
predicates:
- Path=/app/h5/invite-campaign/**
- id: register-reward-app
uri: ${LIKEI_GATEWAY_ROUTE_REGISTER_REWARD_APP_URI}
predicates:
- Path=/app/register-reward/**
- id: go-service
uri: ${LIKEI_GATEWAY_ROUTE_GO_URI}
predicates:
- Path=/go/**
filters:
- StripPrefix=1
- id: invite-campaign-internal
uri: http://10.2.1.16:2900
uri: ${LIKEI_GATEWAY_ROUTE_INVITE_INTERNAL_URI}
predicates:
- Path=/internal/invite-campaign/**
- id: game-app
uri: http://10.2.1.16:2900
uri: ${LIKEI_GATEWAY_ROUTE_GAME_APP_URI}
predicates:
- Path=/app/game/**
- id: game-internal
uri: http://10.2.1.16:2900
uri: ${LIKEI_GATEWAY_ROUTE_GAME_INTERNAL_URI}
predicates:
- Path=/internal/game/baishun/**
- id: game-baishun-callback
uri: http://10.2.1.16:2900
uri: ${LIKEI_GATEWAY_ROUTE_GAME_BAISHUN_URI}
predicates:
- Path=/game/baishun/**
- id: service-gateway
uri: lb://rc-service-gateway
uri: ${LIKEI_GATEWAY_ROUTE_FORWARD_URI}
predicates:
- Header=Req-Likei, true
filters:
- name: ForwardRoute
args:
aesKey: 7NcAa111UGiRlRiR
aesKey: ${LIKEI_GATEWAY_FORWARD_ROUTE_AES_KEY}
- id: service-other
uri: lb://rc-service-other
uri: ${LIKEI_GATEWAY_ROUTE_OTHER_URI}
predicates:
- Path=/**
gateway:
@ -139,6 +151,11 @@ gateway:
- /activity/king-queen/**
# week-star
- /activity/week-star/**
- /go/public/**
- /public/h5/week-star/**
- /go/resident-activity/register-reward/**
- /go/resident-activity/specified-gift-weekly-rank/**
- /go/resident-activity/week-star/**
# leaderboard
- /activity/leaderboard/gifts-send
- /activity/leaderboard/gifts-received
@ -147,4 +164,4 @@ gateway:
- /sys/version/manage/latest/review
- /game/yomi/**
- /public/h5/invite-campaign/**
forward-aes-key: 8NcSaTt8EHjRlRuG
forward-aes-key: ${LIKEI_GATEWAY_FORWARD_AES_KEY}

View File

@ -1,72 +1,72 @@
red-circle:
ai:
minimax:
url: https://api.minimax.io/v1/text/chatcompletion_v2
authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJHcm91cE5hbWUiOiJ0b255IGxpdSIsIlVzZXJOYW1lIjoidG9ueSBsaXUiLCJBY2NvdW50IjoiIiwiU3ViamVjdElEIjoiMTkzMDg0MzI0Nzg4NjczMzY4NCIsIlBob25lIjoiIiwiR3JvdXBJRCI6IjE5MzA4NDMyNDc4ODI1MzkzODAiLCJQYWdlTmFtZSI6IiIsIk1haWwiOiJsaXV0YW90b255M0BpY2xvdWQuY29tIiwiQ3JlYXRlVGltZSI6IjIwMjUtMDYtMjUgMTQ6MzA6MjYiLCJUb2tlblR5cGUiOjEsImlzcyI6Im1pbmltYXgifQ.TAHcSE-3YSSLWC9z9424GVF6twqi3Po5LkpGENtLF25397IvEV-CiXDFzBE5F-H6w9yG-YAROwGy0jFxwoDWPF4IsC2emKp5Qan5geavx7YqTEUQ4vJzhu7TJgDrvvUcUanVPQRBo5IyqpPuDagNPHhmPca7wgOrVHQfahUs7Q5VwOUiUDguHdwXcl6h4Yk32Ufv7rHDuS_sZnuAXxG_dY_XfIkJGwdMz7O7c9uWICnnMFXAL7GEyhy50MKJoEiCFLWnIC6Tu20oTnd2QBDlp1JCzdphA9FpBqo0SVCSmR2CZK1Uo4oXioxizkfv4EgPpCZUkOVSqT2f74l1zbFe-g
model: MiniMax-Text-01
url: ${LIKEI_AI_MINIMAX_URL}
authorization: ${LIKEI_AI_MINIMAX_AUTHORIZATION}
model: ${LIKEI_AI_MINIMAX_MODEL}
qian-fan:
url: https://qianfan.baidubce.com/v2/chat/completions
appId: ''
authorization: Bearer bce-v3/ALTAK-DjBrg6HP36lGomporE2iT/3a509ddcafca5e22cea75c85f5bd9b9e11f8d192
model: c0jkrl3v_dt24b
url: ${LIKEI_AI_QIANFAN_URL}
appId: ${LIKEI_AI_QIANFAN_APP_ID:}
authorization: ${LIKEI_AI_QIANFAN_AUTHORIZATION}
model: ${LIKEI_AI_QIANFAN_MODEL}
tts:
url: http://128.168.134.215:9001/tts/stream
model: cloudsway_tts
url: ${LIKEI_AI_TTS_URL}
model: ${LIKEI_AI_TTS_MODEL}
oss:
aliYun:
endpoint: http://oss-accelerate.aliyuncs.com
bucketName: tkm-likei
accessUrl: https://media.haiyihy.com
access-key-id: LTAI5
access-key-secret: v2Z31d
endpoint: ${LIKEI_ALIYUN_OSS_ENDPOINT}
bucketName: ${LIKEI_ALIYUN_OSS_BUCKET_NAME}
accessUrl: ${LIKEI_ALIYUN_OSS_ACCESS_URL}
access-key-id: ${LIKEI_ALIYUN_OSS_ACCESS_KEY_ID}
access-key-secret: ${LIKEI_ALIYUN_OSS_ACCESS_KEY_SECRET}
sts:
endpoint: sts.us-west-1.aliyuncs.com
role-arn: acs:ram::124470563:role/stsoss
endpoint: ${LIKEI_ALIYUN_STS_ENDPOINT}
role-arn: ${LIKEI_ALIYUN_STS_ROLE_ARN}
# 有效时间是900 ~ 3600
token-expire-time: 3600
# policy-file: policy/bucket_write_policy.txt
tencent-cos:
enabled: true
secret-id: IKIDMchhZEfrsiNo472DAtTpzzmLjttkOnyu
secret-key: nMkbLsGRO6ZqulSyJQJ0UjjU0KSKxOgl
bucket-name: yumi-assets-1420526837
region: me-saudi-arabia
access-url: https://media.haiyihy.com
enabled: ${LIKEI_TENCENT_COS_ENABLED}
secret-id: ${LIKEI_TENCENT_COS_SECRET_ID}
secret-key: ${LIKEI_TENCENT_COS_SECRET_KEY}
bucket-name: ${LIKEI_TENCENT_COS_BUCKET}
region: ${LIKEI_TENCENT_COS_REGION}
access-url: ${LIKEI_TENCENT_COS_ACCESS_URL}
instant-message:
broadcast-group:
LOTFUN: "@TGS#a3C"
LIKEI: "@TGS#2RUK4PK5C2"
LOTFUN: ${LIKEI_IM_BROADCAST_GROUP_LOTFUN}
LIKEI: ${LIKEI_IM_BROADCAST_GROUP_LIKEI}
tencet-trtc:
secretId: IKIDMchhZEfrsiNo472DAtTpzzmLjttkOnyu
secretKey: nMkbLsGRO6ZqulSyJQJ0UjjU0KSKxOgl
endpoint: trtc.tencentcloudapi.com
sdkAppId: 20036101
secretId: ${LIKEI_TRTC_SECRET_ID}
secretKey: ${LIKEI_TRTC_SECRET_KEY}
endpoint: ${LIKEI_TRTC_ENDPOINT}
sdkAppId: ${LIKEI_TRTC_SDK_APP_ID}
tencet-im:
appId: 20036101
key: dcdf53135f27e7cf8541c4ae9798fb0cb2f0e4d6c5c20022dbaea053f35cbb8c
identifier: yumiadmin
baseEndpoint: https://adminapisgp.im.qcloud.com
noticeAccount: yuminotice
newsletterAccount: yuminotice
appId: ${LIKEI_IM_APP_ID}
key: ${LIKEI_IM_KEY}
identifier: ${LIKEI_IM_IDENTIFIER}
baseEndpoint: ${LIKEI_IM_BASE_ENDPOINT}
noticeAccount: ${LIKEI_IM_NOTICE_ACCOUNT}
newsletterAccount: ${LIKEI_IM_NEWSLETTER_ACCOUNT}
agora:
appId: 4b5e5cea3b86476caf7f7a57d05b82d1
appCertificate: a6feb209de6448148a926f59634807bb
tokenExpireSecond: 86400
privilegeExpireSecond: 86400
authKey: Basic ZTA0MTVjMzYwZjBmNDNhZGFhNTdjZDZmNjgwYTFiZWQ6MWIyYmNjZDU0NGQzNDRhYmJhMTNiNDliZjUyMGY4MTI=
appId: ${LIKEI_AGORA_APP_ID}
appCertificate: ${LIKEI_AGORA_APP_CERTIFICATE}
tokenExpireSecond: ${LIKEI_AGORA_TOKEN_EXPIRE_SECOND}
privilegeExpireSecond: ${LIKEI_AGORA_PRIVILEGE_EXPIRE_SECOND}
authKey: ${LIKEI_AGORA_AUTH_KEY}
sms:
aliYun:
enabled: true
sign-name: Tarab
access-key-id: LTAI4xxxxxxU8JQ6Xf
access-key-secret: hh2DrAxxxxxxW5bQTA7s1
endpoint: dysmsapi.aliyuncs.com
enabled: ${LIKEI_SMS_ALIYUN_ENABLED}
sign-name: ${LIKEI_SMS_ALIYUN_SIGN_NAME}
access-key-id: ${LIKEI_SMS_ALIYUN_ACCESS_KEY_ID}
access-key-secret: ${LIKEI_SMS_ALIYUN_ACCESS_KEY_SECRET}
endpoint: ${LIKEI_SMS_ALIYUN_ENDPOINT}
censor:
active: qcloud
active: ${LIKEI_CENSOR_ACTIVE}
tupu:
enabled: false
enabled: ${LIKEI_CENSOR_TUPU_ENABLED}
tencent-cloud:
secret-id: AKIDGMNDrNk
secret-key: 71h9dv41lU
endpoint: ims.tencentcloudapi.com
region: ap-guangzhou
secret-id: ${LIKEI_TENCENT_CLOUD_IMS_SECRET_ID}
secret-key: ${LIKEI_TENCENT_CLOUD_IMS_SECRET_KEY}
endpoint: ${LIKEI_TENCENT_CLOUD_IMS_ENDPOINT}
region: ${LIKEI_TENCENT_CLOUD_IMS_REGION}

View File

@ -1,28 +1,28 @@
red-circle:
pay:
web-pay-base-url: 'https://h5.likeichat.com/#/'
web-pay-result-page: pay-result
web-pay-recharge-page: recharge
web-pay-collection-page: collection-receipt
web-pay-base-url: ${LIKEI_PAY_WEB_PAY_BASE_URL}
web-pay-result-page: ${LIKEI_PAY_WEB_PAY_RESULT_PAGE}
web-pay-recharge-page: ${LIKEI_PAY_WEB_PAY_RECHARGE_PAGE}
web-pay-collection-page: ${LIKEI_PAY_WEB_PAY_COLLECTION_PAGE}
googlePayGlobal:
serverAccount: server-api@api-5499404589076025365-781142.iam.gserviceaccount.com
classPatchServiceAccountJson: payfile/google_pay.json
serverAccount: ${LIKEI_GOOGLE_PAY_GLOBAL_SERVER_ACCOUNT}
classPatchServiceAccountJson: ${LIKEI_GOOGLE_PAY_GLOBAL_PATCH_JSON}
googlePay:
TAXAB:
serverAccount: tarab-server@tarab-427706.iam.gserviceaccount.com
publicKey: MIIBIjANxxxxxxxxTjmAO68rmnKr2gYJ3isuepCZsaX0wIDAQAB
classPatchServiceAccountJson: payfile/tarab-427706-04fe535b024a.json
serverAccount: ${LIKEI_GOOGLE_PAY_TAXAB_SERVER_ACCOUNT}
publicKey: ${LIKEI_GOOGLE_PAY_TAXAB_PUBLIC_KEY}
classPatchServiceAccountJson: ${LIKEI_GOOGLE_PAY_TAXAB_PATCH_JSON}
paypal:
merchantId: 'AZm9zUAxxxxx8kiGKL6D4l0elx2'
secretKey: 'EJuYA6cSud6xxxxx4_Fj9rbBh1yYnr97btui2ocuR'
devMerchantId: 'Ac2aB2KFgz3xxxxxGmbS7dcPedRf2_eg23D'
devSecretKey: 'ECjyOP4nxxxxxxB0JEAH9P7im'
merchantId: ${LIKEI_PAYPAL_MERCHANT_ID}
secretKey: ${LIKEI_PAYPAL_SECRET_KEY}
devMerchantId: ${LIKEI_PAYPAL_DEV_MERCHANT_ID}
devSecretKey: ${LIKEI_PAYPAL_DEV_SECRET_KEY}
huawei:
access-token:
grant-type: 'client_credentials'
client-secret: 'dff36e68xxxx30da9c7240ae0bc96'
client-id: '11xx93'
oauth-login-url: https://oauth-login.cloud.huawei.com/oauth2/v3/token
grant-type: ${LIKEI_HUAWEI_GRANT_TYPE}
client-secret: ${LIKEI_HUAWEI_CLIENT_SECRET}
client-id: ${LIKEI_HUAWEI_CLIENT_ID}
oauth-login-url: ${LIKEI_HUAWEI_OAUTH_LOGIN_URL}
host:
CHINA: https://orders-drcn.iap.hicloud.com
GERMANY: https://orders-dre.iap.hicloud.com
@ -33,45 +33,45 @@ red-circle:
PURCHASES_TOKENS_VERIFY: /applications/purchases/tokens/verify
PURCHASES_CONFIRM: /applications/v2/purchases/confirm
PURCHASES_CANCELLED_LIST: /applications/v2/purchases/cancelledList
iap-public-key: MIIBojANBgkqhkiG9w0Bxxxxx7cdmApDJfpAlKeLZ9fy7d3VIWyqZiLYtxxxxj3t+sFuC4lEJBVrw5MgDE7bmpjidOm0rxxxxUYC1hSI8xXagbJ0sOcYXSunxxxx1NaupT2+ILoZPfIQVF4RThlQmphuOif4uMMlYvYosiueCKlv6MYQi0fVcLKEjWVc/XslowtLS4w0EV/eAVpFq7kTvy04LNYVscSjZop7AHEMVVoNgzg+mLC0UGsftYRfEBeKHkNppTg931qodgJSkIM582ZTK0eujAJR43On3z1gc8+UvSKW+9w+tAqw099VYrFY3sXySUfVJ6SoejiHeKlAgMBAAE=
iap-public-key: ${LIKEI_HUAWEI_IAP_PUBLIC_KEY}
# uat环境
payer-max:
secret-key: 8aexx98f
merchant-id: SDP01010
rsa-private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCQU2JiAdSO8M3CQft5nZEGLO9/TPFArQCffVzWoaz3niIacJ/B3dOePJyXMljuKByoRC+1ApW+9ucVXoulkLkqUAve0q7xKMFaxCw4OAEkRC6JhjYgEJyJXLEA9KRT6EklvvomqfUwuddCKtTNLL2hFtG5+2P+BioYrekaIiZh9lIel1msn4WKoBp3LgyStcZBQOPzhD7NcKsbo+ppjT4JBSQyVZrcJ3mYe+YSV/Qnw/KY2v3OzPeLApeZhLh5wVsfcmyz04IHFogLIjRVFGU6Xbvfz8ujRtpoBD+3RSz5GKiBLPjoSgGLSIxCWc10VphKwOlvR0bi3ssKYG9HsHw5AgMBAAECggEADzebgfXrcX7WUwsd9r60UdBfGC8GqOkUzbwsE71MPXeA5QTG82vuKhr977sxQTsdemhmF1HEdDQYPVqQos5Vl66E8eOI6oh/ipBwkSTmiepedcWe41adCqapSw6AXRB61e4C9hypa4/MsH9PnKqA/AEp79AfxOLlgWCk2UqMfXuPuYhKD9SSlYVoJ5x/W48B+NBaRuSiCV3agPfnpRtMuTZ9Vs4IOL4riIyE9ABBgFinL0h/D5qSX6JnrO+N1miORSiM+2e/Sh/xs6nrCIuh9pSBcXjAeO/l4/BKCfj3TPH9hcYWWWRVgbX0WV6MDZFz/au5o9LZ7m9kUltP4dH7AQKBgQDvyrKh7BKIrwEwvt0eWBfCNdwLctb0GbsEoYVsQaiS/cLfje5289DLTTYc18fy/G8dRMGftME6qAiidtQaEb/mfSWPhHYfTayWJ0At8TvX2qbUS2b46or3lRgUBWOgpNkmLSEy7ae0I1UTStI3UN9rJNvjZ7Jntc7KGeZMfivCqQKBgQCaFMN2xBV00KerElFp0XZRaCZEyLz3MkTOwSlcs4c9cA7TTV0sZlxNRsA11WCaFIEV8TGCjZMJfmZihmB+LRXOhb45lXD+xi/JTOPs9UVOPJNpeFHuABL93/TqL0ma7d/VntKkIv2g+/CUoSzXQ6QrLg4/BpmfevZDtW/A8Gx3EQKBgQCe/TmVjM35HHfglxxLK0ONfGKKoLkPHiRW/LVXQu1/kItt6FBNRHmS4n3Xf+bOIDuYH2d1+cYImzMmbT1Sj6Q6MY3+62fad4jQAfRWwdTY2Nu2dMwwjGpZn9xYIf6dm89ytYeGmfaQxMB6yyg4jwGjq8uzqqSqiOw0Khn9a8aeCQKBgArX0zmUav4hgOslCt2rg+wOrELC7alnvDfgmAySBb5pGGH+W8Q4H97AT955+aZeMwdcReOuGt7cKlBcrIW0nog+GTjsL1t+jvZXluKiEBKFaMpPUVSyZKPBEvc4BLIGc24REznBzJ97m16aSRGNDQyM3SvKRx1WBeaV6htlz/xBAoGAbi5IvOQMCbUvtrD/lJ3xkVaoEQL6dlCVBK7Ldf5+6g/Rc9j6d5B2UVb3v9+BOpAHHFa2fIPNI8y22TmCjgIGi6O8Rm60KqFDQIQnzcmPQg9HsTIG5u0V2b/0saUj2txHRzIC+cZ4b+/xms7OHu1OKZeVIZhNdT/+CWmO2wVgA/s=
rsa-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkFNiYgHUjvDNwkH7eZ2RBizvf0zxQK0An31c1qGs954iGnCfwd3TnjyclzJY7igcqEQvtQKVvvbnFV6LpZC5KlAL3tKu8SjBWsQsODgBJEQuiYY2IBCciVyxAPSkU+hJJb76Jqn1MLnXQirUzSy9oRbRuftj/gYqGK3pGiImYfZSHpdZrJ+FiqAady4MkrXGQUDj84Q+zXCrG6PqaY0+CQUkMlWa3Cd5mHvmElf0J8PymNr9zsz3iwKXmYS4ecFbH3Jss9OCBxaICyI0VRRlOl2738/Lo0baaAQ/t0Us+RiogSz46EoBi0iMQlnNdFaYSsDpb0dG4t7LCmBvR7B8OQIDAQAB
platform-rsa-public-key: MIIBIjANBgkqhkiG9w0BAQEFAACBAQ8AMIIBCgKCAQEAi4+8n/BEFhWKzWs1SMdD+1gzK3xiI/wGGTS330yKSxQMM5Ec39AFQjKFTvcjIZegt2vTQYnA/AL0l0O5C98BWSBuM20/pUXd1+i/Ew/lvLYoeKDD4ARkCzJfXQcDgvm4gTZvnVJwerCN+E2rziNZoLTdTo468IArzBVFzWGa/YmQvi7brCbTlzp5EpVeZMNLNpM04I0uJIiqGpEp0PDPbbn/ZVzZLoLKO+LXWxXx1nFPVlL+X1yk1TyJVfPv7Au3mv9UXNGSF6EP21n97aaU1j29+PXNy3Yze8pmkdWmcOqGnORSLPk0Acl6gklBGyvFiSk/QsL1ocecqD8cJk1JbQIDAQAB
app-id: d6afddeb3ca447448
gateway-base-url: https://pay-gate-uat.payermax.com
enable-real-time-exchange-rate: false
secret-key: ${LIKEI_PAYERMAX_SECRET_KEY}
merchant-id: ${LIKEI_PAYERMAX_MERCHANT_ID}
rsa-private-key: ${LIKEI_PAYERMAX_RSA_PRIVATE_KEY}
rsa-public-key: ${LIKEI_PAYERMAX_RSA_PUBLIC_KEY}
platform-rsa-public-key: ${LIKEI_PAYERMAX_PLATFORM_RSA_PUBLIC_KEY}
app-id: ${LIKEI_PAYERMAX_APP_ID}
gateway-base-url: ${LIKEI_PAYERMAX_GATEWAY_BASE_URL}
enable-real-time-exchange-rate: ${LIKEI_PAYERMAX_ENABLE_REAL_TIME_EXCHANGE_RATE}
mifa-pay:
mer-account: 4dab789b6c8
mer-no: 1000
gateway-base-url: https://platformtest.xqdmipay.com
rsa-private-key: MIIEvgIBADANBgkqhkiG9w0BAQGFCASCBKgwggSkAgEAAoIBAQC2DZell5v2A/bfR1lTuvHsPFnzQDl8apqM72WKlRf8/AFCTLsDK2si2iKFHcf/JTL+BqKAReVwYbG0GxapleaouO95YPqH7br6J+mdpTxFVzI9AObuVybdEmrO1vE4+OqLX1EXzh88oeqkuU/lJNow12HIZABDXkj1SilAwEbgusFpZn8cZ6eTRqYYcr5bfq2uIyq1s5Hj2I6q2NwogyV12a8pkPX5y/667Kmgsg8bb+cdpFGLpLltEbm0rk7z0Dv5SWuZxKOowPfxz+ISl53RjxY+yCXks5D1Kw1EwEB0c7N8ADkbO+1BDQM1MM8IGKdTQgGUwEbT/AdhVPK39kvLAgMBAAECggEAOqQKMuaw7/+655Td6yCOiJ+wAbCwU6kq+zapqIf54B10clyw6IZ1zhYhhGthXogm8rhEY7kf/KEbUn5fQGTulW5shNZ+HIaw8Z8lmwf8cAF0Rz4hJKih9hfWm6WUsdtMAXTEdDyKx0cIg+LFH3RNa+oUry22//xA1/H5c8f7jKtQRu5rIePaRsAvMYpfTzmKXjVq0WkD9jMFgYowHWuwBc+HTvN5SI/3Ag+pXhI5dot3BMLXrLqrM7fPIH1cqi1u1jyYZIpIAEM1ZqRWJCfNmXn0YYGjswqpluqNbSgTmwMGuqhMPe1hOYJwwtXwXXSFkyO/lX8iziUbvsq5b4J6wQKBgQDamnLZc7ymnOjzg3yrm9n7SqgBsgk7pYHwl/HVdaopKm6YcsW9uTr80zYXGbTSSE65/pFCN45mkHpyyFdCoCb+FMpMyn1I6bDbDTwQPEdCo9i9uVOZM692/I/8kb9czvCqiG22Uosx3AzY/lem+XjoudDIUBha8P7cwxL64Ie/UQKBgQDVMnUERQVfLnWvdNq0W3bi2de/ynPSXDtDPHP+ezYmyyUUEIYX33BLTBFWYX9jxGVumqyOvUvmweAHTTRHPsDHrtqS/xMztxfOMNW7eBaP5Btp3pBaq/FMCUpqtYH1lMsSfLEC6iQePiAtQThvfgLuNsLm73F3vlFtBs+C3LIqWwKBgQDSn+ey3xHQkvTc1D7F9kdkGT2hTJIa11BIqY4INvP57/lZh5RBRfyw5yyBu3H+/k5kZQQ+gdsBtYlVmPSCrF6FhzCYJq3qF8ggdzL9Dac3bTkDLFKBFUyl35k4KJHx8S3vkb3r4sJdCwGR/hYkOtClo4unxYyB6xwVRxu9f6Mr0QKBgQDLa+2DOWg6vVXFKDZVyL/TDBB0C3Qfz6ksKk5zDpVIxqSGVI3d0XCQJ/CS/0xRoV82/ZaQS8ZUU8CyttOe9x1yakBb6c4klhq8vpPw4FCG0xvlFFugaFdAOc0rrCxoaqSo6xjqswXrZVPGWmjC2PVq3g1x1B3sJ0gCQ3FUZ8gH6QKBgDu+g2Adn3sF7NZKWW/sHcWhhtfx05PuFLdmA7J9LJ6TTQFW1snMp2GjkAvDx6KfwmqTT8TYZmnA0nPgz9bSgdpvCaBAdhbU6EjEcBpc3+gFwDnF4Qen8qAbXVnOE7pOrQ/F6kKaL+Xuu3dTKzJR2v6kFJRTywt+kuo3INAbN86c
platform-rsa-public-key: MIIBIjANBgkqhkiG9w1BAQEFAAOCAQ8AMIIBCgKCAQEAtjRr7TpawlzKYDFwzpUwCK+twx/0KS3W0ZVCPdOAoaVxhEDfacHkgHMUJ7MXd6raqce++k2XHFoYyD4d8fJPkjNrzQ7PPoFm774XfGxz85oemfK88AI6+3PlxEwdf0VBZXmrraJvOdD3dPv4Uq/J15PzKGSh8edYTZgeNSCD/gMRcZoZhacd0WIiaJFf/P4AEa7g+JnefatinayQXAl1n7O5kAiU7jryCzBbno7R5X96riGxUpu/Rxome/tBSBf0644jzQFU7eLA4mJ6aFchArFZ1SvMBVjpYWEgLFgQxyUbJewXRYCPU5uDvzYhFUzF/4bIdhR5swPvAPokavijKwIDAQAB
mer-account: ${LIKEI_MIFA_PAY_MER_ACCOUNT}
mer-no: ${LIKEI_MIFA_PAY_MER_NO}
gateway-base-url: ${LIKEI_MIFA_PAY_GATEWAY_BASE_URL}
rsa-private-key: ${LIKEI_MIFA_PAY_RSA_PRIVATE_KEY}
platform-rsa-public-key: ${LIKEI_MIFA_PAY_PLATFORM_RSA_PUBLIC_KEY}
airwallex:
client-id: j5v_C5xxg
api-key: e397fa14297xxxxxxxx6d3dff3e92c63c338
base-url: https://api-demo.airwallex.com
client-id: ${LIKEI_AIRWALLEX_CLIENT_ID}
api-key: ${LIKEI_AIRWALLEX_API_KEY}
base-url: ${LIKEI_AIRWALLEX_BASE_URL}
api-url:
AUTHENTICATION_LOGIN: /api/v1/authentication/login
PAYMENT_INTENTS_CREATE: /api/v1/pa/payment_intents/create
paynicorn:
app-key: 79xx58
merchant-secret: 704a8xxx50b
app-key: ${LIKEI_PAYNICORN_APP_KEY}
merchant-secret: ${LIKEI_PAYNICORN_MERCHANT_SECRET}
clipspay:
merchantNo: 800xx2370
md5SecretKey: 18455c7xxxxx4a48fb7fe
terminalNo: 10xxx6
terminalKey: NzMyNGRxxxxxYThiMmE4ODA
notifyUrl: https://dexxxxx.com/play/server/notice/clipspay
placeAnOrderApi: http://uat.card.api.clipspay.com/payment/gateway/api/backTransReq
redirectResult: https://dev.xxxxine.com/clipspay/redirect
merchantNo: ${LIKEI_CLIPSPAY_MERCHANT_NO}
md5SecretKey: ${LIKEI_CLIPSPAY_MD5_SECRET_KEY}
terminalNo: ${LIKEI_CLIPSPAY_TERMINAL_NO}
terminalKey: ${LIKEI_CLIPSPAY_TERMINAL_KEY}
notifyUrl: ${LIKEI_CLIPSPAY_NOTIFY_URL}
placeAnOrderApi: ${LIKEI_CLIPSPAY_PLACE_ORDER_API}
redirectResult: ${LIKEI_CLIPSPAY_REDIRECT_RESULT}
telegram:
bot-token: 72649:AAE7gZj0
webhook-url: https://local.api.yuyinfang168.com/order/telegram/webhook
bot-token: ${LIKEI_ORDER_TELEGRAM_BOT_TOKEN}
webhook-url: ${LIKEI_ORDER_TELEGRAM_WEBHOOK_URL}

View File

@ -24,22 +24,22 @@ red-circle:
templateId: 1994334094730010626
game:
hkys:
signKey: svO
signKey: ${LIKEI_GAME_HKYS_SIGN_KEY}
hotgame:
signKey: qFO
signKey: ${LIKEI_GAME_HOTGAME_SIGN_KEY}
baishun:
app-id: 1704692112
app-key: 6EllbAruJDfw
app-channel: lotfun
app-id: ${LIKEI_GAME_BAISHUN_APP_ID}
app-key: ${LIKEI_GAME_BAISHUN_APP_KEY}
app-channel: ${LIKEI_GAME_BAISHUN_APP_CHANNEL}
baishun2fun:
app-id: 26xxxx65
app-key: OWq58W1XDxxxxxxxzAfHqNr0l
app-channel: 2xxxxxn
app-id: ${LIKEI_GAME_BAISHUN2FUN_APP_ID}
app-key: ${LIKEI_GAME_BAISHUN2FUN_APP_KEY}
app-channel: ${LIKEI_GAME_BAISHUN2FUN_APP_CHANNEL}
sud:
app-id: 178xxxx00130
app-key: kAdoDDw6xxxxOphybk3G4
app-secret: Psw9s7nOnxxxxxxxS97y4uf0vW
app-channel: axxxxt,TxxxxN
app-id: ${LIKEI_GAME_SUD_APP_ID}
app-key: ${LIKEI_GAME_SUD_APP_KEY}
app-secret: ${LIKEI_GAME_SUD_APP_SECRET}
app-channel: ${LIKEI_GAME_SUD_APP_CHANNEL}
static-resources:
levelStyle:
wealth:
@ -82,25 +82,30 @@ red-circle:
# 测试
lucky:
gift:
go:
enabled: ${LUCKY_GIFT_GO_ENABLED}
base-url: ${GAME_LUCKY_GIFT_GO_URL}
internal-token: ${GAME_INTERNAL_CALLBACK_SECRET}
timeout-millis: ${LUCKY_GIFT_GO_TIMEOUT_MILLIS}
api:
enabled: true
enabled: ${LUCKY_GIFT_API_ENABLED}
# 多账号配置
configs:
- standardId: 18816
url: https://game-cn-test.jieyou.shop/lucky_gift/start_game
app_key: w0GoEN4hg
app_id: 929
app_channel: likei
- standardId: 19102
url: https://game-cn-test.jieyou.shop/lucky_gift/start_game
app_key: bXdpzw94i
app_id: 261
app_channel: likei
- standardId: ${LUCKY_GIFT_API_CONFIG_1_STANDARD_ID}
url: ${LUCKY_GIFT_API_CONFIG_1_URL}
app_key: ${LIKEI_GAME_BAISHUN_APP_KEY}
app_id: ${LIKEI_GAME_BAISHUN_APP_ID}
app_channel: ${LIKEI_GAME_BAISHUN_APP_CHANNEL}
- standardId: ${LUCKY_GIFT_API_CONFIG_2_STANDARD_ID}
url: ${LUCKY_GIFT_API_CONFIG_2_URL}
app_key: ${LIKEI_GAME_BAISHUN_APP_KEY}
app_id: ${LIKEI_GAME_BAISHUN_APP_ID}
app_channel: ${LIKEI_GAME_BAISHUN_APP_CHANNEL}
# 默认配置(向后兼容)
url: https://game-cn-test.jieyou.shop/lucky_gift/start_game
app_key: w0GoEN4hg6G
app_id: 9291
app_channel: likei
url: ${LUCKY_GIFT_API_DEFAULT_URL}
app_key: ${LIKEI_GAME_BAISHUN_APP_KEY}
app_id: ${LIKEI_GAME_BAISHUN_APP_ID}
app_channel: ${LIKEI_GAME_BAISHUN_APP_CHANNEL}
activity:
ranking:
@ -120,13 +125,13 @@ scheduler:
telegram:
bot:
token: 8350:AAGwh1O
token: ${LIKEI_TELEGRAM_BOT_TOKEN}
monitor:
chat-ids:
- '-5081'
alert-limit-seconds: 60
proxy-host: 127.0.0.1
proxy-port: 7897
- '${LIKEI_TELEGRAM_MONITOR_CHAT_ID_1}'
alert-limit-seconds: ${LIKEI_TELEGRAM_MONITOR_ALERT_LIMIT_SECONDS}
proxy-host: ${LIKEI_TELEGRAM_MONITOR_PROXY_HOST}
proxy-port: ${LIKEI_TELEGRAM_MONITOR_PROXY_PORT}
yomi:
aes_key: Lt2tYDHewn6U4
aes_key: ${LIKEI_YOMI_AES_KEY}

View File

@ -2,9 +2,9 @@ dataSources:
wallet:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbcUrl: jdbc:p6spy:mysql://mysql:3306/likei_wallet?characterEncoding=utf8&useUnicode=true&useSSL=false&allowMultiQueries=true&useLegacyDatetimeCode=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&autoReconnect=true
username: root
password: 123456
jdbcUrl: ${LIKEI_WALLET_MYSQL_JDBC_URL}
username: ${LIKEI_MYSQL_USERNAME}
password: ${LIKEI_MYSQL_PASSWORD}
#hikari:
# 连接池名称

View File

@ -1,5 +1,5 @@
spring:
security:
user:
name: dxxop
password: devxx23
name: ${LIKEI_VISUAL_MONITOR_USERNAME}
password: ${LIKEI_VISUAL_MONITOR_PASSWORD}

View File

@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -44,12 +45,32 @@ public class GameLuckyGiftBusinessEvent implements Serializable {
*/
private String sysOrigin;
/**
* 整个送礼动作业务id.
*/
private String businessId;
/**
* 扣款资产流水id.
*/
private String consumeAssetRecordId;
/**
* 礼物id.
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long giftId;
/**
* 礼物单价.
*/
private BigDecimal giftPrice;
/**
* 是否免费礼物.
*/
private Boolean giftIsFree;
/**
* 选的礼物数量.
*/

View File

@ -6,9 +6,11 @@ import com.red.circle.gateway.constant.ApiConstant;
import com.red.circle.gateway.service.AuthEndpointService;
import com.red.circle.gateway.service.UserCredential;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
/**
@ -20,15 +22,32 @@ public class AuthEndpointServiceImpl implements AuthEndpointService {
private final WebClient.Builder webClientBuilder;
@Value("${FEIGN_AUTH_URL:}")
private String authBaseUrl;
@Override
public Mono<ResultResponse<UserCredential>> getTokenCredential(
String authorization) {
return webClientBuilder.build().get()
.uri(ApiConstant.AUTH_FULL_URL)
.uri(buildTokenCheckUrl())
.header(RequestHeaderConstant.AUTHORIZATION, authorization)
.retrieve()
.bodyToMono(new ParameterizedTypeReference<>() {
});
}
private String buildTokenCheckUrl() {
String normalizedBaseUrl = authBaseUrl == null ? "" : authBaseUrl.trim();
if (normalizedBaseUrl.isEmpty()) {
return ApiConstant.AUTH_FULL_URL;
}
if (normalizedBaseUrl.endsWith("/")) {
normalizedBaseUrl = normalizedBaseUrl.substring(0, normalizedBaseUrl.length() - 1);
}
return UriComponentsBuilder.fromUriString(normalizedBaseUrl)
.path("/token/check")
.build(true)
.toUriString();
}
}

View File

@ -42,6 +42,7 @@ public class ResidentRegisterRewardServiceImpl implements ResidentRegisterReward
return result.setConfigured(Boolean.TRUE)
.setEnabled(Boolean.TRUE.equals(config.getEnabled()))
.setGoldAmount(defaultGoldAmount(config.getGoldAmount()))
.setDailyLimit(defaultDailyLimit(config.getDailyLimit()))
.setRewardGroupId(config.getRewardGroupId())
.setRewardGroupName(getRewardGroupName(config.getRewardGroupId()));
}
@ -62,6 +63,7 @@ public class ResidentRegisterRewardServiceImpl implements ResidentRegisterReward
config.setSysOrigin(normalizedSysOrigin)
.setEnabled(Boolean.TRUE.equals(cmd.getEnabled()))
.setGoldAmount(defaultGoldAmount(cmd.getGoldAmount()))
.setDailyLimit(defaultDailyLimit(cmd.getDailyLimit()))
.setRewardGroupId(cmd.getRewardGroupId());
if (exists) {
@ -84,6 +86,7 @@ public class ResidentRegisterRewardServiceImpl implements ResidentRegisterReward
private void validateConfig(ResidentRegisterRewardConfigSaveCmd cmd) {
long goldAmount = defaultGoldAmount(cmd.getGoldAmount());
long dailyLimit = defaultDailyLimit(cmd.getDailyLimit());
if (Boolean.TRUE.equals(cmd.getEnabled())) {
ResponseAssert.isTrue(ResponseErrorCode.REQUEST_PARAMETER_ERROR,
"At least one reward is required when enabled.",
@ -92,6 +95,9 @@ public class ResidentRegisterRewardServiceImpl implements ResidentRegisterReward
ResponseAssert.isTrue(ResponseErrorCode.REQUEST_PARAMETER_ERROR,
"goldAmount must be greater than or equal to zero.",
goldAmount >= 0);
ResponseAssert.isTrue(ResponseErrorCode.REQUEST_PARAMETER_ERROR,
"dailyLimit must be greater than or equal to zero.",
dailyLimit >= 0);
}
private String normalizeSysOrigin(String sysOrigin) {
@ -102,6 +108,10 @@ public class ResidentRegisterRewardServiceImpl implements ResidentRegisterReward
return goldAmount == null ? 0L : goldAmount;
}
private Long defaultDailyLimit(Long dailyLimit) {
return dailyLimit == null ? 0L : dailyLimit;
}
private String getRewardGroupName(Long rewardGroupId) {
if (rewardGroupId == null) {
return null;

View File

@ -28,4 +28,9 @@ public class ResidentRegisterRewardConfigCO extends ClientObject {
private Long rewardGroupId;
private String rewardGroupName;
/**
* 每日奖励份数上限0 表示不限
*/
private Long dailyLimit = 0L;
}

View File

@ -26,4 +26,9 @@ public class ResidentRegisterRewardConfigSaveCmd implements Serializable {
private Long goldAmount;
private Long rewardGroupId;
/**
* 每日奖励份数上限0 表示不限
*/
private Long dailyLimit;
}

View File

@ -36,4 +36,7 @@ public class ResidentRegisterRewardConfig extends TimestampBaseEntity {
@TableField("reward_group_id")
private Long rewardGroupId;
@TableField("daily_limit")
private Long dailyLimit;
}

View File

@ -0,0 +1,52 @@
package com.red.circle.other.adapter.app.debug;
import com.red.circle.mq.business.model.event.gift.GameLuckyGiftBusinessEvent;
import com.red.circle.other.app.common.gift.LuckyGiftGoClient;
import com.red.circle.other.app.listener.GameLuckyGiftBusinessListener;
import com.red.circle.tool.core.text.StringUtils;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Profile;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Profile("local")
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/internal/debug/lucky-gift", produces = MediaType.APPLICATION_JSON_VALUE)
public class LuckyGiftLocalDebugController {
private final GameLuckyGiftBusinessListener gameLuckyGiftBusinessListener;
@PostMapping("/business-event")
public LuckyGiftGoClient.LuckyGiftGoDrawResponse replayBusinessEvent(
@RequestBody GameLuckyGiftBusinessEvent event) {
validateEvent(event);
LuckyGiftGoClient.LuckyGiftGoDrawResponse response =
gameLuckyGiftBusinessListener.processLotteryEvent(event);
if (response == null) {
throw new IllegalStateException("Lucky gift business event returned empty response");
}
return response;
}
@PostMapping("/go-draw")
public LuckyGiftGoClient.LuckyGiftGoDrawResponse replayGoDrawOnly(
@RequestBody GameLuckyGiftBusinessEvent event) {
validateEvent(event);
return gameLuckyGiftBusinessListener.drawWithGo(event);
}
private void validateEvent(GameLuckyGiftBusinessEvent event) {
if (StringUtils.isBlank(event.getBusinessId())) {
throw new IllegalArgumentException("businessId required");
}
if (Objects.isNull(event.getUsers()) || event.getUsers().isEmpty()) {
throw new IllegalArgumentException("users required");
}
}
}

View File

@ -20,6 +20,7 @@ import com.red.circle.other.inner.enums.material.GiftTabEnum;
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd;
import com.red.circle.wallet.inner.model.dto.WalletReceiptResDTO;
@ -66,27 +67,50 @@ public class LuckyGiftGiveCmdExe {
ResponseAssert.isTrue(ResponseErrorCode.REQUEST_PARAMETER_ERROR,
CollectionUtils.isNotEmpty(cmd.filterAcceptUserId()));
if (giftConfig.getGiftCandy().equals(new BigDecimal("0.00"))) {
BigDecimal dollarAmount = walletGoldClient.getBalance(cmd.requiredReqUserId()).getBody().getDollarAmount();
log.info("赠送幸运礼物金额为0,余额为 {}", dollarAmount);
return dollarAmount;
}
boolean luckyGift = GiftTabEnum.LUCKY_GIFT.name().equals(giftConfig.getGiftTab());
boolean magicGift = GiftTabEnum.MAGIC.name().equals(giftConfig.getGiftTab());
boolean freeGift = giftConfig.getGiftCandy().compareTo(BigDecimal.ZERO) == 0;
String businessId = IdWorkerUtils.getIdStr();
if (GiftTabEnum.MAGIC.name().equals(giftConfig.getGiftTab())) {
if (magicGift) {
ResponseAssert.isFalse(GiftErrorCode.MAGIC_GIFT_QUANTITY_ERROR, cmd.getQuantity() > 1);
}
// 付钱
WalletReceiptResDTO receipt = consumeCandy(cmd, giftConfig);
WalletReceiptResDTO receipt = null;
BigDecimal balance;
if (freeGift) {
balance = walletGoldClient.getBalance(cmd.requiredReqUserId()).getBody().getDollarAmount();
log.info("赠送幸运礼物金额为0,余额为 {}", balance);
if (!luckyGift) {
return balance;
}
} else {
receipt = consumeCandy(cmd, giftConfig);
balance = receipt.getBalance().getDollarAmount();
}
// 礼物处理mq 魔法礼物不处理放到中奖后处理
if (!GiftTabEnum.MAGIC.name().equals(giftConfig.getGiftTab())) {
giftMqMessage.sendGift(receipt.getAssetRecordId().toString(),
giftAppConvertor.toGiveAwayGiftBatchEvent(cmd, giftConfig, receipt.getAssetRecordId()));
if (!magicGift) {
Long trackId = Objects.nonNull(receipt) ? receipt.getAssetRecordId() : Long.parseLong(businessId);
giftMqMessage.sendGift(
Objects.toString(trackId),
giftAppConvertor.toGiveAwayGiftBatchEvent(cmd, giftConfig, trackId)
);
}
// 抽奖mq
if (luckyGift) {
gameLuckyGiftCommon.sendMq(
cmd,
giftConfig.getStandardId(),
businessId,
Objects.nonNull(receipt) ? Objects.toString(receipt.getAssetRecordId()) : null,
giftConfig.getGiftCandy(),
freeGift
);
} else {
gameLuckyGiftCommon.sendMq(cmd, giftConfig.getStandardId());
}
userProfileGateway.removeCache(cmd.requiredReqUserId());
@ -100,7 +124,7 @@ public class LuckyGiftGiveCmdExe {
.build());
}
return receipt.getBalance().getDollarAmount();
return balance;
}
/**

View File

@ -158,6 +158,44 @@ public class GameLuckyGiftCommon {
}
public void sendMq(
GiveAwayGiftBatchCmd cmd,
Long standardId,
String businessId,
String consumeAssetRecordId,
BigDecimal giftPrice,
Boolean giftIsFree
) {
GameLuckyGiftBusinessEvent event = new GameLuckyGiftBusinessEvent()
.setBusinessId(businessId)
.setConsumeAssetRecordId(consumeAssetRecordId)
.setUserId(cmd.requiredReqUserId())
.setRoomId(cmd.getRoomId())
.setSysOrigin(cmd.requireReqSysOrigin())
.setGiftId(cmd.getGiftId())
.setGiftPrice(giftPrice)
.setGiftIsFree(Boolean.TRUE.equals(giftIsFree))
.setQuantity(cmd.getQuantity())
.setCheckCombo(cmd.getCheckCombo())
.setGiftCombos(0)
.setStandardId(standardId)
.setUsers(cmd.filterAcceptUserId().stream().map(acceptUserId ->
new GameLuckyGiftUser()
.setId(IdWorkerUtils.getId())
.setAcceptUserId(acceptUserId)
.setGiftsCount(0)
.setComboLossCount(0)
).collect(Collectors.toList()));
senderService.sendEventMessage(MessageEvent.builder()
.consumeId(businessId)
.topic(FixedTopic.RC_DEFAULT_APP_ORDINARY)
.tag(GameLuckyGiftBusinessSink.TAG)
.body(event)
.build());
}
private Integer getComboLossCount(GameLuckyGiftBusinessEvent event) {
if (Boolean.TRUE.equals(event.getOpenComboLoss())) {

View File

@ -0,0 +1,111 @@
package com.red.circle.other.app.common.gift;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.red.circle.other.infra.config.LuckyGiftGoConfig;
import java.util.List;
import java.util.Objects;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class LuckyGiftGoClient {
private final LuckyGiftGoConfig luckyGiftGoConfig;
public LuckyGiftGoDrawResponse draw(LuckyGiftGoDrawRequest request) {
if (!luckyGiftGoConfig.isEnabled()) {
throw new IllegalStateException("Lucky gift go client is disabled");
}
String baseUrl = Objects.toString(luckyGiftGoConfig.getBaseUrl(), "").trim();
if (baseUrl.isEmpty()) {
throw new IllegalStateException("Lucky gift go baseUrl is blank");
}
HttpResponse response = HttpUtil.createPost(baseUrl + "/internal/lucky-gift/draw")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.header("X-Internal-Token", Objects.toString(luckyGiftGoConfig.getInternalToken(), ""))
.timeout(Objects.requireNonNullElse(luckyGiftGoConfig.getTimeoutMillis(), 10000))
.body(JSON.toJSONString(request))
.execute();
String responseBody = response.body();
if (response.getStatus() < 200 || response.getStatus() >= 300) {
throw new IllegalStateException("Lucky gift go http error, status=" + response.getStatus()
+ ", body=" + responseBody);
}
if (responseBody == null || responseBody.trim().isEmpty()) {
throw new IllegalStateException("Lucky gift go response is empty");
}
JSONObject root = JSON.parseObject(responseBody);
if (root == null) {
throw new IllegalStateException("Lucky gift go response is invalid");
}
if (root.containsKey("status") && !root.getBooleanValue("status")) {
throw new IllegalStateException("Lucky gift go business error: " + root.getString("message"));
}
JSONObject body = root.getJSONObject("body");
LuckyGiftGoDrawResponse result = Objects.nonNull(body)
? body.toJavaObject(LuckyGiftGoDrawResponse.class)
: root.toJavaObject(LuckyGiftGoDrawResponse.class);
if (result == null || result.getBusinessId() == null || result.getResults() == null) {
throw new IllegalStateException("Lucky gift go response body is invalid: " + responseBody);
}
return result;
}
@Data
@Accessors(chain = true)
public static class LuckyGiftGoDrawRequest {
private String businessId;
private String consumeAssetRecordId;
private String sysOrigin;
private Long standardId;
private Long roomId;
private Long sendUserId;
private Long giftId;
private Long giftPrice;
private Long giftNum;
private Boolean giftIsFree;
private List<LuckyGiftGoDrawOrder> orders;
}
@Data
@Accessors(chain = true)
public static class LuckyGiftGoDrawOrder {
private String id;
private Long acceptUserId;
}
@Data
@Accessors(chain = true)
public static class LuckyGiftGoDrawResponse {
private String businessId;
private Integer providerCode;
private Long rewardTotal;
private Long balanceAfter;
private List<LuckyGiftGoDrawResult> results;
}
@Data
@Accessors(chain = true)
public static class LuckyGiftGoDrawResult {
private String id;
private String orderId;
private Long acceptUserId;
private Boolean isWin;
private Long rewardNum;
}
}

View File

@ -0,0 +1,224 @@
package com.red.circle.other.app.common.gift;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.external.inner.model.cmd.message.BroadcastGroupMsgBodyCmd;
import com.red.circle.external.inner.model.cmd.message.CustomGroupMsgBodyCmd;
import com.red.circle.external.inner.model.enums.message.GroupMessageTypeEnum;
import com.red.circle.mq.business.model.event.gift.GameLuckyGiftBusinessEvent;
import com.red.circle.mq.business.model.event.gift.GameLuckyGiftUser;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.game.GameLuckyGiftMsgCO;
import com.red.circle.other.app.dto.cmd.task.RoomDailyTaskProgressUpdateCmd;
import com.red.circle.other.app.service.task.RoomDailyTaskProgressService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.cache.service.other.GiftCacheService;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.rds.entity.game.GameLuckyGiftCount;
import com.red.circle.other.infra.database.rds.entity.live.RoomMember;
import com.red.circle.other.infra.database.rds.service.game.GameLuckyGiftCountService;
import com.red.circle.other.infra.database.rds.service.live.RoomMemberService;
import com.red.circle.other.inner.enums.material.PropsCommodityType;
import com.red.circle.other.inner.enums.task.RoomDailyTaskCode;
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.model.dto.user.props.UserPropsResourcesDTO;
import com.red.circle.other.inner.model.dto.user.props.UserUsePropsDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class LuckyGiftResultProcessor {
private final GameLuckyGiftCountService gameLuckyGiftCountService;
private final GiftCacheService giftCacheService;
private final UserProfileGateway userProfileGateway;
private final UserProfileAppConvertor userProfileAppConvertor;
private final ImGroupClient imGroupClient;
private final RoomDailyTaskProgressService roomDailyTaskProgressService;
private final RoomMemberService roomMemberService;
private final RedisService redisService;
private final RoomProfileManagerService roomProfileManagerService;
private final GameLuckyGiftCommon gameLuckyGiftCommon;
public void process(GameLuckyGiftBusinessEvent event, LuckyGiftGoClient.LuckyGiftGoDrawResponse response) {
GiftConfigDTO giftConfig = giftCacheService.getById(event.getGiftId());
if (giftConfig == null) {
throw new IllegalStateException("Lucky gift config not found, giftId=" + event.getGiftId());
}
UserProfileDTO sendUserProfile = userProfileAppConvertor.toUserProfileDTO(
userProfileGateway.getByUserId(event.getUserId()));
if (sendUserProfile == null) {
throw new IllegalStateException("Lucky gift sender profile not found, userId=" + event.getUserId());
}
Map<String, GameLuckyGiftUser> userMap = Optional.ofNullable(event.getUsers())
.orElse(Collections.emptyList())
.stream()
.collect(Collectors.toMap(user -> Objects.toString(user.getId()), Function.identity()));
if (userMap.size() != Optional.ofNullable(response.getResults()).orElse(Collections.emptyList()).size()) {
throw new IllegalStateException("Lucky gift result size mismatch, businessId=" + event.getBusinessId());
}
UserPropsResourcesDTO avatarFrame = getUserAvatarFrameProps(sendUserProfile);
long payAmount = resolvePayAmount(event, giftConfig);
BigDecimal balanceAfter = BigDecimal.valueOf(Objects.requireNonNullElse(response.getBalanceAfter(), 0L));
for (LuckyGiftGoClient.LuckyGiftGoDrawResult result : response.getResults()) {
GameLuckyGiftUser user = userMap.get(result.getId());
if (user == null) {
throw new IllegalStateException("Lucky gift user mapping missing, resultId=" + result.getId());
}
long rewardNum = Objects.requireNonNullElse(result.getRewardNum(), 0L);
int multiple = payAmount > 0 && rewardNum > 0 ? (int) (rewardNum / payAmount) : 0;
gameLuckyGiftCountService.saveOrUpdate(new GameLuckyGiftCount()
.setId(Long.valueOf(result.getId()))
.setGiftId(event.getGiftId())
.setRoomId(event.getRoomId())
.setQuantity(event.getQuantity())
.setUserId(event.getUserId())
.setSysOrigin(event.getSysOrigin())
.setGiftIncCount(0)
.setGiftCombos(Objects.requireNonNullElse(event.getGiftCombos(), 0))
.setGiftCover(giftConfig.getGiftPhoto())
.setPayAmount(payAmount)
.setMultiple(multiple)
.setChangeInventory(false)
.setSysGiftIncCount(0)
.setAwardAmount(rewardNum)
.setRegionCode(event.getRegionCode())
.setDateNumber(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt())
);
if (rewardNum <= 0) {
continue;
}
sendLuckyGiftMessage(event, giftConfig, sendUserProfile, avatarFrame, result, multiple, balanceAfter);
updateRoomDailyTask(event.getUserId(), event.getRoomId(), rewardNum, RoomDailyTaskCode.PERSONAL_LUCKY_GIFT_GOLD);
}
}
private long resolvePayAmount(GameLuckyGiftBusinessEvent event, GiftConfigDTO giftConfig) {
BigDecimal giftPrice = Objects.nonNull(event.getGiftPrice()) ? event.getGiftPrice() : giftConfig.getGiftCandy();
return giftPrice.multiply(BigDecimal.valueOf(Objects.requireNonNullElse(event.getQuantity(), 0))).longValue();
}
private void sendLuckyGiftMessage(
GameLuckyGiftBusinessEvent event,
GiftConfigDTO giftConfig,
UserProfileDTO sendUserProfile,
UserPropsResourcesDTO avatarFrame,
LuckyGiftGoClient.LuckyGiftGoDrawResult result,
Integer multiple,
BigDecimal balanceAfter
) {
GameLuckyGiftMsgCO giftMsg = new GameLuckyGiftMsgCO()
.setSysOrigin(event.getSysOrigin())
.setRoomId(event.getRoomId())
.setRoomAccount(event.getRoomAccount())
.setSendUserId(event.getUserId())
.setAccount(sendUserProfile.actualAccount())
.setNickname(sendUserProfile.getUserNickname())
.setUserAvatar(sendUserProfile.getUserAvatar())
.setAvatarFrameCover(avatarFrame.getCover())
.setAvatarFrameSvg(avatarFrame.getSourceUrl())
.setMultiple(multiple)
.setAwardAmount(result.getRewardNum())
.setGiftId(event.getGiftId())
.setMultipleType(gameLuckyGiftCommon.getRewardMultipleType(multiple))
.setGiftCover(giftConfig.getGiftPhoto())
.setRegionCode(event.getRegionCode())
.setGiftQuantity(event.getQuantity())
.setAcceptUserId(result.getAcceptUserId())
.setAcceptNickname(resolveAcceptNickname(result.getAcceptUserId()))
.setBalance(balanceAfter)
.setGiftCandy(Objects.nonNull(event.getGiftPrice()) ? event.getGiftPrice() : giftConfig.getGiftCandy())
.setGlobalNews(Boolean.TRUE);
imGroupClient.sendMessageBroadcast(
BroadcastGroupMsgBodyCmd.builder()
.toPlatform(SysOriginPlatformEnum.toEnum(giftMsg.getSysOrigin()))
.type(GroupMessageTypeEnum.GAME_LUCKY_GIFT)
.data(giftMsg)
.build()
);
if (StringUtils.isBlank(giftMsg.getRoomAccount())) {
return;
}
imGroupClient.sendCustomMessage(giftMsg.getRoomAccount(),
CustomGroupMsgBodyCmd.builder()
.type(GroupMessageTypeEnum.GAME_LUCKY_GIFT)
.data(giftMsg)
.build());
}
private String resolveAcceptNickname(Long acceptUserId) {
if (acceptUserId == null) {
return null;
}
return Optional.ofNullable(userProfileGateway.getByUserId(acceptUserId))
.map(profile -> profile.getUserNickname())
.orElse(null);
}
private void updateRoomDailyTask(Long userId, Long roomId, Long rewardAmount, RoomDailyTaskCode taskType) {
RoomMember roomMember = roomMemberService.getRoomMember(roomId, userId);
if (roomMember == null) {
return;
}
RoomProfileManager profileManager = roomProfileManagerService.getByUserId(userId);
if (profileManager == null || Objects.equals(profileManager.getId(), roomMember.getRoomId())) {
return;
}
String redisKey = "room:daily:task:progress:" + taskType.name() + ":" + userId + ":"
+ ZonedDateTimeAsiaRiyadhUtils.now().toLocalDate();
Long total = redisService.increment(redisKey, rewardAmount);
redisService.expire(redisKey, DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight(), TimeUnit.SECONDS);
roomDailyTaskProgressService.updateTaskProgress(
new RoomDailyTaskProgressUpdateCmd()
.setUserId(userId)
.setTaskCode(taskType.name())
.setProgressValue(total.intValue())
);
}
private UserPropsResourcesDTO getUserAvatarFrameProps(UserProfileDTO sendUserProfile) {
if (CollectionUtils.isEmpty(sendUserProfile.getUseProps())) {
return new UserPropsResourcesDTO();
}
return Optional.ofNullable(sendUserProfile.getUseProps().stream()
.filter(props -> Objects.nonNull(props.getPropsResources())
&& !Objects.equals(props.getPropsResources().getType(), PropsCommodityType.AVATAR_FRAME.name())
&& props.getExpireTime() > TimestampUtils.now().getTime())
.findFirst().orElse(new UserUsePropsDTO())
.getPropsResources()).orElse(new UserPropsResourcesDTO());
}
}

View File

@ -10,11 +10,15 @@ import com.red.circle.component.mq.service.MessageListener;
import com.red.circle.mq.business.model.event.gift.GameLuckyGiftBusinessEvent;
import com.red.circle.mq.rocket.business.streams.GameLuckyGiftBusinessSink;
import com.red.circle.other.app.common.gift.GameLuckyGiftCommon;
import com.red.circle.other.app.common.gift.LuckyGiftGoClient;
import com.red.circle.other.app.common.gift.LuckyGiftResultProcessor;
import com.red.circle.other.app.common.gift.GameLuckyGiftParamCmd;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import java.util.stream.Collectors;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -33,6 +37,8 @@ public class GameLuckyGiftBusinessListener implements MessageListener {
private final MessageEventProcess messageEventProcess;
private final GameLuckyGiftCommon gameLuckyGiftManager;
private final RoomProfileManagerService roomProfileManagerService;
private final LuckyGiftGoClient luckyGiftGoClient;
private final LuckyGiftResultProcessor luckyGiftResultProcessor;
@Override
public Action consume(ConsumerMessage message) {
@ -54,36 +60,65 @@ public class GameLuckyGiftBusinessListener implements MessageListener {
* 保存幸运礼物流水.
*/
private void processLottery(GameLuckyGiftBusinessEvent event) {
processLotteryEvent(event);
}
public LuckyGiftGoClient.LuckyGiftGoDrawResponse processLotteryEvent(GameLuckyGiftBusinessEvent event) {
if (Objects.isNull(event.getRoomId())) {
return;
log.warn("Lucky gift event missing roomId, businessId={}", event.getBusinessId());
return null;
}
long startTime = LocalDateTimeUtils.nowEpochMilli();
try {
RoomProfile roomProfile = roomProfileManagerService.getProfileById(event.getRoomId());
if (Objects.isNull(roomProfile)) {
return;
if (Objects.nonNull(roomProfile)) {
event.setRoomAccount(roomProfile.getRoomAccount());
} else if (StringUtils.isBlank(event.getBusinessId())) {
log.warn("Lucky gift room profile missing for legacy flow, roomId={}", event.getRoomId());
return null;
} else {
log.warn("Lucky gift room profile missing, continue go draw with fallback roomAccount, businessId={}, roomId={}",
event.getBusinessId(), event.getRoomId());
}
if (StringUtils.isBlank(event.getRegionCode())) {
event.setRegionCode(userRegionGateway.getRegionCode(event.getUserId()));
}
if (StringUtils.isBlank(event.getBusinessId())) {
GameLuckyGiftParamCmd cmd = buildLuckyGiftRunParam(event, roomProfile);
event.getUsers().forEach(user -> {
cmd.setId(user.getId());
cmd.setGiftsCount(user.getGiftsCount());
cmd.setAcceptUserId(user.getAcceptUserId());
cmd.setComboLossCount(user.getComboLossCount());
gameLuckyGiftManager.run(cmd);
});
return null;
}
LuckyGiftGoClient.LuckyGiftGoDrawResponse response = drawWithGo(event);
luckyGiftResultProcessor.process(event, response);
return response;
} finally {
long endTime = LocalDateTimeUtils.nowEpochMilli() - startTime;
if (endTime > (1000 * 20)) {
log.warn("[游戏幸运礼物抽奖] 队列处理耗时:{}", endTime);
}
}
}
public LuckyGiftGoClient.LuckyGiftGoDrawResponse drawWithGo(GameLuckyGiftBusinessEvent event) {
LuckyGiftGoClient.LuckyGiftGoDrawResponse response = luckyGiftGoClient.draw(buildGoRequest(event));
if (!Objects.equals(event.getBusinessId(), response.getBusinessId())) {
throw new IllegalStateException("Lucky gift businessId mismatch, request=" + event.getBusinessId()
+ ", response=" + response.getBusinessId());
}
log.info("Lucky gift go draw success businessId={}, standardId={}, providerCode={}, rewardTotal={}",
event.getBusinessId(), event.getStandardId(), response.getProviderCode(), response.getRewardTotal());
return response;
}
private GameLuckyGiftParamCmd buildLuckyGiftRunParam(GameLuckyGiftBusinessEvent event,
@ -105,5 +140,24 @@ public class GameLuckyGiftBusinessListener implements MessageListener {
.setStandardId(event.getStandardId());
}
private LuckyGiftGoClient.LuckyGiftGoDrawRequest buildGoRequest(GameLuckyGiftBusinessEvent event) {
return new LuckyGiftGoClient.LuckyGiftGoDrawRequest()
.setBusinessId(event.getBusinessId())
.setConsumeAssetRecordId(event.getConsumeAssetRecordId())
.setSysOrigin(event.getSysOrigin())
.setStandardId(event.getStandardId())
.setRoomId(event.getRoomId())
.setSendUserId(event.getUserId())
.setGiftId(event.getGiftId())
.setGiftPrice(Objects.nonNull(event.getGiftPrice()) ? event.getGiftPrice().longValue() : 0L)
.setGiftNum(Objects.nonNull(event.getQuantity()) ? Long.valueOf(event.getQuantity()) : 0L)
.setGiftIsFree(Boolean.TRUE.equals(event.getGiftIsFree()))
.setOrders(event.getUsers().stream().map(user ->
new LuckyGiftGoClient.LuckyGiftGoDrawOrder()
.setId(Objects.toString(user.getId(), null))
.setAcceptUserId(user.getAcceptUserId())
).collect(Collectors.toList()));
}
}

View File

@ -0,0 +1,21 @@
package com.red.circle.other.infra.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Data
@Component
@RefreshScope
@ConfigurationProperties(prefix = "lucky.gift.go")
public class LuckyGiftGoConfig {
private boolean enabled = true;
private String baseUrl;
private String internalToken;
private Integer timeoutMillis = 10000;
}

View File

@ -85,7 +85,9 @@ public class RegionConfigClientServiceImpl implements RegionConfigClientService
config.setId(IdWorkerUtils.getIdStr());
ResponseAssert.isFalse(UserErrorCode.CODE_ALREADY_EXISTS,
sysRegionConfigService.existRegionCode(config.getRegionCode(), config.getId(), config.getSysOrigin()));
sysRegionConfigService.add(regionConfigInnerConvertor.toSysRegionConfig(config));
SysRegionConfig regionConfig = regionConfigInnerConvertor.toSysRegionConfig(config);
regionConfig.setWithdrawalWays(StringUtils.join(config.getWithdrawalWaysList(), ","));
sysRegionConfigService.add(regionConfig);
regionCacheService.remove(config.getSysOrigin());
}

View File

@ -7,7 +7,7 @@ feign:
gateway:
url: http://127.0.0.1:1100
wallet:
url: http://127.0.0.1:2000
url: http://wallet:2000
other:
url: http://127.0.0.1:2400
live:

View File

@ -3,6 +3,11 @@ package com.red.circle.framework.shardingsphere.driver;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
@ -40,12 +45,6 @@ public class NacosDriverURLProvider implements ShardingSphereDriverURLProvider {
}
Map<String, String> queryParams = parseQuery(url);
Properties properties = new Properties();
setIfHasText(properties, "serverAddr", queryParams.get("serverAddr"));
setIfHasText(properties, "namespace", queryParams.get("namespace"));
setIfHasText(properties, "username", queryParams.get("username"));
setIfHasText(properties, "password", queryParams.get("password"));
String group = Optional.ofNullable(queryParams.get(GROUP))
.filter(NacosDriverURLProvider::hasText)
.orElse("DEFAULT_GROUP");
@ -57,19 +56,95 @@ public class NacosDriverURLProvider implements ShardingSphereDriverURLProvider {
shardingConfigFilename,
group,
queryParams);
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(shardingConfigFilename, group, TIMEOUT_MILLIS);
String content = "";
try {
content = loadConfig(queryParams, shardingConfigFilename, group, true);
} catch (NacosException ex) {
LOGGER.warn(
"Load sharding config via nacos client failed, fallback to HTTP. dataId={}, group={}",
shardingConfigFilename,
group,
ex);
}
if (!hasText(content)) {
LOGGER.warn(
"Empty sharding config via nacos client, fallback to HTTP. dataId={}, group={}",
shardingConfigFilename,
group);
content = loadConfigViaHTTP(queryParams, shardingConfigFilename, group);
}
if (!hasText(content)) {
throw new RuntimeException(
"Empty Nacos sharding config: dataId=" + shardingConfigFilename + ", group=" + group);
}
LOGGER.info(content);
return content.getBytes(StandardCharsets.UTF_8);
} catch (NacosException ex) {
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
private String loadConfig(Map<String, String> queryParams, String dataID, String group,
boolean includeAuth) throws NacosException {
ConfigService configService = NacosFactory.createConfigService(
buildProperties(queryParams, includeAuth));
return configService.getConfig(dataID, group, TIMEOUT_MILLIS);
}
private String loadConfigViaHTTP(Map<String, String> queryParams, String dataID, String group)
throws IOException {
String serverAddr = queryParams.get("serverAddr");
if (!hasText(serverAddr)) {
return "";
}
StringBuilder urlBuilder = new StringBuilder("http://")
.append(serverAddr)
.append("/nacos/v1/cs/configs?dataId=")
.append(encode(dataID))
.append("&group=")
.append(encode(group));
String namespace = queryParams.get("namespace");
if (hasText(namespace) && !"public".equalsIgnoreCase(namespace.trim())) {
urlBuilder.append("&tenant=").append(encode(namespace));
}
HttpURLConnection connection = (HttpURLConnection) new URL(urlBuilder.toString()).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout((int) TIMEOUT_MILLIS);
connection.setReadTimeout((int) TIMEOUT_MILLIS);
int status = connection.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
LOGGER.warn(
"Load sharding config via HTTP failed. status={}, dataId={}, group={}, url={}",
status,
dataID,
group,
urlBuilder);
return "";
}
try (InputStream inputStream = connection.getInputStream()) {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
} finally {
connection.disconnect();
}
}
private Properties buildProperties(Map<String, String> queryParams, boolean includeAuth) {
Properties properties = new Properties();
setIfHasText(properties, "serverAddr", queryParams.get("serverAddr"));
setIfHasText(properties, "namespace", queryParams.get("namespace"));
if (includeAuth) {
setIfHasText(properties, "username", queryParams.get("username"));
setIfHasText(properties, "password", queryParams.get("password"));
}
return properties;
}
private static String encode(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8);
}
private static void setIfHasText(Properties properties, String key, String value) {
if (hasText(value)) {
properties.setProperty(key, value);