diff --git a/h5/smash-golden-egg/index.html b/h5/smash-golden-egg/index.html
index 9892cdd..3b9de2f 100644
--- a/h5/smash-golden-egg/index.html
+++ b/h5/smash-golden-egg/index.html
@@ -33,7 +33,7 @@
-
+
diff --git a/h5/smash-golden-egg/index_local.html b/h5/smash-golden-egg/index_local.html
index 9892cdd..3b9de2f 100644
--- a/h5/smash-golden-egg/index_local.html
+++ b/h5/smash-golden-egg/index_local.html
@@ -33,7 +33,7 @@
-
+
diff --git a/h5/smash-golden-egg/js/api_bridge.js b/h5/smash-golden-egg/js/api_bridge.js
index 1858b37..ab27c20 100644
--- a/h5/smash-golden-egg/js/api_bridge.js
+++ b/h5/smash-golden-egg/js/api_bridge.js
@@ -266,6 +266,32 @@
url.searchParams.set(key, value)
}
+ function hasIdempotencyKey(url) {
+ return !!(
+ url.searchParams.get('idempotencyKey') ||
+ url.searchParams.get('idempotency_key') ||
+ url.searchParams.get('requestId') ||
+ url.searchParams.get('request_id') ||
+ url.searchParams.get('nonce')
+ )
+ }
+
+ function randomPart() {
+ try {
+ if (window.crypto && window.crypto.getRandomValues) {
+ var values = new Uint32Array(2)
+ window.crypto.getRandomValues(values)
+ return values[0].toString(16) + values[1].toString(16)
+ }
+ } catch (error) {}
+ return Math.floor(Math.random() * 0x100000000).toString(16) +
+ Math.floor(Math.random() * 0x100000000).toString(16)
+ }
+
+ function createIdempotencyKey(activity) {
+ return ['h5', activity, resolveUID() || 'guest', Date.now(), randomPart()].join('-').slice(0, 128)
+ }
+
function isLegacySmashUrl(url) {
return (
url.pathname === '/index.php' &&
@@ -280,6 +306,19 @@
)
}
+ function isSmashDrawUrl(url) {
+ return (
+ (url.pathname === '/index.php' && url.searchParams.get('action') === 'Action/TreasureHunt.startHunt') ||
+ url.pathname === '/app/smash-golden-egg/draw' ||
+ url.pathname === '/h5/smash-golden-egg/draw'
+ )
+ }
+
+ function ensureDrawIdempotency(url) {
+ if (!isSmashDrawUrl(url) || hasIdempotencyKey(url)) return
+ url.searchParams.set('idempotencyKey', createIdempotencyKey('smash-egg'))
+ }
+
function rewriteLegacyActionToSemanticPath(url) {
var action = String(url.searchParams.get('action') || '')
var pathname = legacySemanticRoutes[action]
@@ -423,6 +462,7 @@
rewriteSemanticPathToLegacyAction(parsed)
}
replaceQueryPlaceholders(parsed)
+ ensureDrawIdempotency(parsed)
return gatewayBase + gatewayPrefix + parsed.pathname + parsed.search
}
diff --git a/h5/yumi-wheel/h5/agencypanel/index.html b/h5/yumi-wheel/h5/agencypanel/index.html
index f1ab0cb..872357c 100644
--- a/h5/yumi-wheel/h5/agencypanel/index.html
+++ b/h5/yumi-wheel/h5/agencypanel/index.html
@@ -1 +1 @@
-
Yumi
+Yumi
diff --git a/h5/yumi-wheel/h5/agencypanel/index_local.html b/h5/yumi-wheel/h5/agencypanel/index_local.html
index 893addd..b974420 100644
--- a/h5/yumi-wheel/h5/agencypanel/index_local.html
+++ b/h5/yumi-wheel/h5/agencypanel/index_local.html
@@ -1 +1 @@
-Yumi Wheel Local
+Yumi Wheel Local
diff --git a/h5/yumi-wheel/h5/agencypanel/static/js/wheel-gateway-api.js b/h5/yumi-wheel/h5/agencypanel/static/js/wheel-gateway-api.js
index dda8bd6..787caee 100644
--- a/h5/yumi-wheel/h5/agencypanel/static/js/wheel-gateway-api.js
+++ b/h5/yumi-wheel/h5/agencypanel/static/js/wheel-gateway-api.js
@@ -329,6 +329,85 @@
return '';
}
+ function randomPart() {
+ try {
+ if (window.crypto && window.crypto.getRandomValues) {
+ var values = new Uint32Array(2);
+ window.crypto.getRandomValues(values);
+ return values[0].toString(16) + values[1].toString(16);
+ }
+ } catch (error) {}
+ return Math.floor(Math.random() * 0x100000000).toString(16) +
+ Math.floor(Math.random() * 0x100000000).toString(16);
+ }
+
+ function createIdempotencyKey(activity) {
+ var uid = String(params._login_uid || params.uid || params.userId || params.loginUid || 'guest').trim();
+ return ['h5', activity, uid || 'guest', Date.now(), randomPart()].join('-').slice(0, 128);
+ }
+
+ function queryHasIdempotencyKey(url) {
+ try {
+ var parsed = new URL(url, window.location.href);
+ return !!(
+ parsed.searchParams.get('idempotencyKey') ||
+ parsed.searchParams.get('idempotency_key') ||
+ parsed.searchParams.get('requestId') ||
+ parsed.searchParams.get('request_id') ||
+ parsed.searchParams.get('nonce')
+ );
+ } catch (error) {
+ return false;
+ }
+ }
+
+ function bodyHasIdempotencyKey(body) {
+ if (!body) return false;
+ if (typeof FormData !== 'undefined' && body instanceof FormData) {
+ return !!(
+ body.get('idempotencyKey') ||
+ body.get('idempotency_key') ||
+ body.get('requestId') ||
+ body.get('request_id') ||
+ body.get('nonce')
+ );
+ }
+ if (typeof URLSearchParams !== 'undefined' && body instanceof URLSearchParams) {
+ return !!(
+ body.get('idempotencyKey') ||
+ body.get('idempotency_key') ||
+ body.get('requestId') ||
+ body.get('request_id') ||
+ body.get('nonce')
+ );
+ }
+ if (typeof body === 'string') {
+ try {
+ var payload = JSON.parse(body);
+ if (payload && typeof payload === 'object') {
+ return !!(
+ payload.idempotencyKey ||
+ payload.idempotency_key ||
+ payload.requestId ||
+ payload.request_id ||
+ payload.nonce
+ );
+ }
+ } catch (error) {}
+ try {
+ var params = new URLSearchParams(body);
+ return !!(
+ params.get('idempotencyKey') ||
+ params.get('idempotency_key') ||
+ params.get('requestId') ||
+ params.get('request_id') ||
+ params.get('nonce')
+ );
+ } catch (innerError) {}
+ }
+ return false;
+ }
+
function firstDrawReward(drawResult) {
drawResult = drawResult || {};
if (Array.isArray(drawResult.records) && drawResult.records.length > 0) {
@@ -445,6 +524,7 @@
var nextUrl = rewriteUrl(url);
this.__wheelGatewayRequest = nextUrl !== url && isWheelApiPath(originalPath);
this.__wheelGatewayDrawRequest = this.__wheelGatewayRequest && isWheelDrawPath(originalPath);
+ this.__wheelGatewayUrl = nextUrl;
this.__wheelGatewayHeaders = {};
this.__wheelGatewayHeaderValues = {};
if (this.__wheelGatewayRequest) {
@@ -498,6 +578,13 @@
nativeSetRequestHeader.call(this, 'req-version', this.__wheelGatewayHeaderValues['req-version'] || params.reqVersion || defaultReqVersion);
nativeSetRequestHeader.call(this, 'req-zone', resolveReqZone(this.__wheelGatewayHeaderValues['req-zone']));
nativeSetRequestHeader.call(this, 'req-lang', resolveReqLang(this.__wheelGatewayHeaderValues['req-lang']));
+ if (this.__wheelGatewayDrawRequest &&
+ !this.__wheelGatewayHeaders['idempotency-key'] &&
+ !this.__wheelGatewayHeaders['x-idempotency-key'] &&
+ !queryHasIdempotencyKey(this.__wheelGatewayUrl) &&
+ !bodyHasIdempotencyKey(arguments[0])) {
+ nativeSetRequestHeader.call(this, 'Idempotency-Key', createIdempotencyKey('wheel'));
+ }
if (explicitAuthorization) {
try {
window.sessionStorage.setItem('Authorization', explicitAuthorization);