Răsfoiți Sursa

1. 每轮自动从数据库读取当前商品价格,重写 order 请求里的 product.price 和 modifyPrice
2. order 只有返回真实 id 或 orderSn 才计入成功
3. respondType=priceError 会标为 ERR/INVALID
4. 修复最终同时输出 INVALID 和 FAIL 的问题

shizhongqi 2 luni în urmă
părinte
comite
b81acf67a2
1 a modificat fișierele cu 96 adăugiri și 6 ștergeri
  1. 96 6
      scripts/test_ghs_stock_concurrency.php

+ 96 - 6
scripts/test_ghs_stock_concurrency.php

@@ -89,7 +89,12 @@ for ($round = 1; $round <= $rounds; $round++) {
     $before = loadStocks($productIds);
     printStocks('Before', $before, $productIds);
 
-    $requests = buildRequests($requestDefs, $orderCount, $stockOutCount);
+    $currentRequestDefs = $requestDefs;
+    $priceSummary = '';
+    $currentRequestDefs['order']['body'] = refreshOrderBodyPrices($orderBody, $priceSummary);
+    echo "Order request pricing: {$priceSummary}\n";
+
+    $requests = buildRequests($currentRequestDefs, $orderCount, $stockOutCount);
     $logOffset = getFileSize($appLogFile);
     $responses = runConcurrentRequests($requests, $commonHeaders);
     $newLog = readFileFromOffset($appLogFile, $logOffset);
@@ -116,7 +121,7 @@ for ($round = 1; $round <= $rounds; $round++) {
 
     $successCounts = countSuccessfulRequests($responses);
     $after = loadStocks($productIds);
-    $expected = calcExpectedStocks($before, $requestDefs, $successCounts, $productIds);
+    $expected = calcExpectedStocks($before, $currentRequestDefs, $successCounts, $productIds);
 
     printStocks('Expected after successful requests', $expected, $productIds);
     printStocks('Actual', $after, $productIds);
@@ -150,8 +155,9 @@ if ($overallConcurrencyError) {
     exit(4);
 }
 
-if ($overallInvalid) {
+if ($overallInvalid && $overallPass) {
     echo "FINAL: INVALID (at least one round had failed business responses)\n";
+    exit(3);
 }
 
 if (!$overallInvalid && $overallPass) {
@@ -218,6 +224,72 @@ function buildRequests($requestDefs, $orderCount, $stockOutCount)
     return $requests;
 }
 
+function refreshOrderBodyPrices($orderBody, &$summary)
+{
+    parse_str($orderBody, $params);
+    $customId = isset($params['customId']) ? intval($params['customId']) : 0;
+    $products = isset($params['product']) ? json_decode($params['product'], true) : [];
+    if (empty($customId) || empty($products) || !is_array($products)) {
+        $summary = 'keep original prices';
+        return $orderBody;
+    }
+
+    $custom = \bizGhs\custom\classes\CustomClass::getCustom($customId);
+    if (empty($custom)) {
+        $summary = 'keep original prices; custom not found';
+        return $orderBody;
+    }
+
+    $productIds = array_unique(array_filter(array_column($products, 'productId')));
+    $productInfo = \bizGhs\product\classes\ProductClass::getByIds($productIds, null, 'id');
+    if (empty($productInfo)) {
+        $summary = 'keep original prices; products not found';
+        return $orderBody;
+    }
+
+    $priceMap = \bizGhs\custom\classes\CustomClass::$levelPriceKeyMap;
+    $addPriceMap = \bizGhs\custom\classes\CustomClass::$levelAddPriceKeyMap;
+    $addPriceMap['risePercent'] = isset($custom['risePercent']) ? $custom['risePercent'] : 0;
+    $level = isset($custom['level']) ? $custom['level'] : 1;
+    $modifyPrice = '0';
+    $parts = [];
+
+    foreach ($products as $key => $product) {
+        $productId = isset($product['productId']) ? intval($product['productId']) : 0;
+        if (empty($productInfo[$productId])) {
+            continue;
+        }
+        $systemInfo = $productInfo[$productId];
+        $price = \bizGhs\product\classes\ProductClass::getFinalPrice($systemInfo, $level, $priceMap, $addPriceMap);
+        $bigNum = isset($product['bigNum']) ? (string)$product['bigNum'] : '0';
+        $smallNum = isset($product['smallNum']) ? (string)$product['smallNum'] : '0';
+
+        $reachDiscountPrice = '0';
+        $reachNum = isset($systemInfo['reachNum']) ? $systemInfo['reachNum'] : 0;
+        $reachNumDiscount = isset($systemInfo['reachNumDiscount']) ? $systemInfo['reachNumDiscount'] : 0;
+        if ($reachNum > 0 && $bigNum >= $reachNum && $price > $reachNumDiscount) {
+            $price = bcsub($price, $reachNumDiscount, 2);
+            $reachDiscountPrice = bcmul($reachNumDiscount, $bigNum, 2);
+        }
+
+        $products[$key]['price'] = sprintf('%.2f', (float)$price);
+        $linePrice = bcmul((string)$products[$key]['price'], $bigNum, 2);
+        if ($smallNum > 0) {
+            $ratio = isset($systemInfo['ratio']) && $systemInfo['ratio'] > 0 ? $systemInfo['ratio'] : 1;
+            $smallItemNum = bcdiv($smallNum, $ratio, 2);
+            $linePrice = bcadd($linePrice, bcmul((string)$products[$key]['price'], $smallItemNum, 2), 2);
+        }
+        $modifyPrice = bcadd($modifyPrice, $linePrice, 2);
+        $name = isset($systemInfo['name']) ? $systemInfo['name'] : $productId;
+        $parts[] = $productId . '(' . $name . ')=' . $products[$key]['price'] . 'x' . $bigNum . ($reachDiscountPrice > 0 ? ',reachDiscount=' . $reachDiscountPrice : '');
+    }
+
+    $params['product'] = json_encode($products, JSON_UNESCAPED_UNICODE);
+    $params['modifyPrice'] = $modifyPrice;
+    $summary = implode('; ', $parts) . '; modifyPrice=' . $modifyPrice;
+    return http_build_query($params);
+}
+
 function runConcurrentRequests($requests, $headers)
 {
     $multi = curl_multi_init();
@@ -261,7 +333,7 @@ function runConcurrentRequests($requests, $headers)
         $error = curl_error($ch);
         $httpCode = isset($info['http_code']) ? (int)$info['http_code'] : 0;
         $totalTime = isset($info['total_time']) ? (float)$info['total_time'] : microtime(true) - $item['startedAt'];
-        $parsed = parseBusinessResponse($body, $httpCode, $error);
+        $parsed = parseBusinessResponse($body, $httpCode, $error, $item['request']['type']);
 
         $responses[] = [
             'type' => $item['request']['type'],
@@ -280,7 +352,7 @@ function runConcurrentRequests($requests, $headers)
     return $responses;
 }
 
-function parseBusinessResponse($body, $httpCode, $curlError)
+function parseBusinessResponse($body, $httpCode, $curlError, $requestType)
 {
     if ($curlError !== '') {
         return ['success' => false, 'summary' => 'curl_error=' . $curlError];
@@ -290,10 +362,28 @@ function parseBusinessResponse($body, $httpCode, $curlError)
     if (is_array($decoded)) {
         $code = isset($decoded['code']) ? $decoded['code'] : null;
         $msg = isset($decoded['msg']) ? $decoded['msg'] : '';
+        $data = isset($decoded['data']) && is_array($decoded['data']) ? $decoded['data'] : [];
+        $respondType = isset($data['respondType']) ? (string)$data['respondType'] : '';
         $success = ($httpCode >= 200 && $httpCode < 300 && (string)$code === '1');
+        if ($requestType === 'order') {
+            $hasOrderIdentity = !empty($data['id']) || !empty($data['orderSn']);
+            if ($respondType === 'priceError' || !$hasOrderIdentity) {
+                $success = false;
+            }
+        }
+        $extra = [];
+        if ($respondType !== '') {
+            $extra[] = 'respondType=' . $respondType;
+        }
+        if (!empty($data['id'])) {
+            $extra[] = 'id=' . $data['id'];
+        }
+        if (!empty($data['orderSn'])) {
+            $extra[] = 'orderSn=' . $data['orderSn'];
+        }
         return [
             'success' => $success,
-            'summary' => 'code=' . json_encode($code, JSON_UNESCAPED_UNICODE) . ' msg=' . trimText((string)$msg, 180),
+            'summary' => trimText('code=' . json_encode($code, JSON_UNESCAPED_UNICODE) . ' msg=' . (string)$msg . (!empty($extra) ? ' ' . implode(' ', $extra) : ''), 240),
         ];
     }