浏览代码

Merge branch 'ratios' into raccount

stanley-king 3 年之前
父节点
当前提交
27ca7c0534
共有 4 个文件被更改,包括 214 次插入7 次删除
  1. 2 0
      admin/control/merchant.php
  2. 21 0
      admin/templates/default/merchant.ctl.php
  3. 183 5
      helper/refill/policy/mratio_control.php
  4. 8 2
      test/TestBigData.php

+ 2 - 0
admin/control/merchant.php

@@ -1129,6 +1129,8 @@ class merchantControl extends SystemControl
                 $profit_ratio = floatval($_POST['profit_ratio']) ?? 0;
                 $retry_times_cfg['lower_ratio'] = ['ratio' => $ratio, 'period' => $period];
                 $retry_times_cfg['profit_ratio'] = $profit_ratio;
+                $profit_formula = $_POST['profit_formula'] ?? '';
+                $retry_times_cfg['profit_formula'] = $profit_formula;
                 return serialize($retry_times_cfg);
             };
 

+ 21 - 0
admin/templates/default/merchant.ctl.php

@@ -157,6 +157,27 @@
             </tr>
 
             <tr class="noborder">
+                <td colspan="2" class="required">
+                    <label style="margin-left: 45px;" for="name">利润计算方式:</label>
+                    <label>
+                        <select name="profit_formula">
+                            <option value="qts" <?php if ($output['retry_times']['profit_formula'] == 'qts') {
+                                echo 'selected';
+                            } ?>>卡类型+面值
+                            <option value="qt" <?php if ($output['retry_times']['profit_formula'] == 'qt') {
+                                echo 'selected';
+                            } ?>>卡类型
+                            </option>
+                            <option value="all" <?php if ($output['retry_times']['profit_formula'] == 'all') {
+                                echo 'selected';
+                            } ?>>全部
+                            </option>
+                        </select>
+                    </label>
+                </td>
+            </tr>
+
+            <tr class="noborder">
                 <td>
                     <hr>
                 </td>

+ 183 - 5
helper/refill/policy/mratio_control.php

@@ -10,6 +10,7 @@ class mratio_control
     private $mInterceptConfig;
     private $mGrossRatios;
     private $mDetailRatios;
+    private $mMchQTS;
     private $mMixedPrices;
 
 
@@ -116,6 +117,19 @@ class mratio_control
         if (!empty($detail_ratios)) {
             $this->mDetailRatios = $detail_ratios;
         }
+
+        $this->mMchQTS = [];
+        foreach ($detail_ratios as $key=>$val)
+        {
+            [$mchid,$quality,$card_type,$spec] = explode('-',$key);
+
+            $mchid = intval($mchid);
+            $quality = intval($quality);
+            $card_type = intval($card_type);
+            $spec = intval($spec);
+
+            $this->mMchQTS[$mchid][] = [$quality,$card_type,$spec];
+        }
     }
 
     public function setMixedPrice($mchid, $mixed_quality, $card_type, $spec, $prices)
@@ -253,6 +267,10 @@ class mratio_control
         return $result;
     }
 
+    private function getMerchantSuppleType($mchid) {
+        return $this->mTimesConfig[$mchid]['profit_formula'] ?? 'qts';
+    }
+
     //return true 表示不可以补充。
     public function ratio_match($mchid, $org_quality, $cur_quality, $card_type, $spec, $qualities)
     {
@@ -266,15 +284,175 @@ class mratio_control
         Log::record("{$header} gross_ratio = {$gross_ratio},lower_ratio={$ratio}",Log::DEBUG);
 
         if($gross_ratio >= $ratio) return true;
-        [$_succ, $_fail, $cur_ratio] = $this->detail_ratio($mchid, $cur_quality, $card_type, $spec, $period);
-        Log::record("{$header} cur_ratio = {$cur_ratio},lower_ratio={$ratio}",Log::DEBUG);
-
-        if($cur_ratio >= $ratio) return true;
 
         if (!PolicyUtil::mixed_quality($org_quality)) {
             return false;
         }
 
+        $type = $this->getMerchantSuppleType($mchid);
+        Log::record("type = {$type}",Log::DEBUG);
+        if($type === 'all') {
+            return $this->all_checker($mchid, $org_quality, $spec, $qualities, $period, $header, $ratio);
+        }
+        elseif($type === 'qt') {
+            return $this->qts_checker($mchid, $org_quality,$cur_quality, $card_type, $spec, $qualities,$period,$header,$ratio);
+        }
+        else {
+            return $this->qts_checker($mchid, $org_quality,$cur_quality, $card_type, $spec, $qualities,$period,$header,$ratio);
+        }
+    }
+
+    private function all_checker($mchid, $org_quality, $spec, $qualities, $period, $header, $low_ratio)
+    {
+        $qtsex = $this->mMchQTS[$mchid];
+        $profit_judger = function ($mchid, $qtsex, $org_quality, $period, $profit_ratio, $header)
+        {
+            $profit = 0;
+            $amount = 0;
+
+            foreach ($qtsex as $qts)
+            {
+                [$quality,$card_type,$spec] = $qts;
+                if($quality == $org_quality) {
+                    continue;
+                }
+
+//                Log::record("quality={$quality},card_type ={$card_type},spec={$spec}",Log::DEBUG);
+
+                $prices = $this->getPrice($mchid, $org_quality, $card_type, $spec);
+                $out_price = $prices[$org_quality];
+                $in_price = $prices[$quality] ?? false;
+                if ($in_price === false || $in_price <= 0) {
+                    continue;
+                }
+
+                [$succ, $fail, $ratio] = $this->detail_ratio($mchid, $quality,$card_type, $spec, $period);
+                $profit += $succ * ($out_price - $in_price);
+                $amount += $succ * $spec;
+
+//                Log::record("out_price = {$out_price},in_price={$in_price} profit={$profit} amount={$amount}",Log::DEBUG);
+            }
+
+            $cur_pratio = round(($profit + 0.00001) / ($amount + 0.00001),4);
+            $profit_ratio = round($profit_ratio,4);
+            $profit_ratio = round($profit_ratio,4);
+
+            Log::record("{$header} all_checker cur_pratio = {$cur_pratio},profit_ratio={$profit_ratio}",Log::DEBUG);
+            return $cur_pratio > $profit_ratio;
+        };
+
+        $spec_max = function ($mchid,$qtsex, $org_quality, $qualities, $low_ratio,$period)
+        {
+            $specs = [];
+            $spec_qt = [];
+            foreach ($qtsex as $qts) {
+                [$quality, $card_type, $spec] = $qts;
+                $specs[] = $spec;
+                $spec_qt[$spec][] = [$quality,$card_type];
+            }
+
+            $specs = array_unique($specs);
+            sort($specs);
+
+            $ratio_calc = function ($mchid, $specs, $spec_qt, $max_spec, $org_quality, $qualities, $period)
+            {
+                $all_succ = 0;
+                $all_fail = 0;
+
+                foreach ($specs as $spec)
+                {
+                    $qts = $spec_qt[$spec];
+                    if($max_spec >= $spec) {
+                        $fHigtRatio = true;
+                    } else {
+                        $fHigtRatio = false;
+                    }
+
+                    $card_types = [];
+                    foreach ($qts as $qt)
+                    {
+                        [$quality,$card_type] = $qt;
+                        if($quality === $org_quality) {
+                            continue;
+                        }
+
+                        $card_types[] = $card_type;
+                    }
+
+                    $detail_ratios = $this->detail_ratios($mchid, $qualities,$card_type, $spec, $period);
+                    if($fHigtRatio)
+                    {
+                        $all = 0;
+                        $ratios = [];
+                        foreach ($detail_ratios as $quality => $sfr) {
+                            [$succ,$fail,$ratio] = $sfr;
+//                            Log::record("high succ={$succ},fail={$fail},ratio = {$ratio}",Log::DEBUG);
+                            $ratios[] = $ratio;
+                            $all += $succ;
+                            $all += $fail;
+                        }
+
+                        $max_ratios = max($ratios);
+                        $succs = $max_ratios * $all;
+                        $fails = $all - $succs;
+
+                        $all_succ += $succs;
+                        $all_fail += $fails;
+                    }
+                    else
+                    {
+                        foreach ($detail_ratios as $quality => $sfr)
+                        {
+                            [$succ,$fail,$ratio] = $sfr;
+//                            Log::record("normal succ={$succ},fail={$fail},ratio = {$ratio}",Log::DEBUG);
+                            $all_succ += $succ;
+                            $all_fail += $fail;
+                        }
+                    }
+                }
+
+                $ratio = ($all_succ + 0.00001)/ ($all_succ + $all_fail + 0.00001);
+                return round($ratio,4);
+            };
+
+            for ($i = 0; $i < count($specs); $i++)
+            {
+                $max_spec = $specs[$i];
+                $ratio = $ratio_calc($mchid, $specs, $spec_qt, $max_spec, $org_quality, $qualities, $period);
+//                Log::record("spec={$max_spec},ratio={$ratio},low_ratio={$low_ratio}",Log::DEBUG);
+                if($ratio >= $low_ratio) {
+                    break;
+                }
+            }
+
+            return $max_spec;
+        };
+
+        $profit_ratio = $this->profit_ratio($mchid);
+        $can_next = $profit_judger($mchid, $qtsex, $org_quality, $period, $profit_ratio, $header);
+
+        if($can_next)
+        {
+            $max_spec = $spec_max($mchid,$qtsex, $org_quality, $qualities, $low_ratio,$period);
+            Log::record("max_spec={$max_spec}",Log::DEBUG);
+            if($max_spec >= $spec) {
+                return false;
+            } else {
+                return true;
+            }
+        }
+        else {
+            return true;
+        }
+    }
+
+    private function qts_checker($mchid, $org_quality,$cur_quality, $card_type, $spec, $qualities,$period,$header,$ratio)
+    {
+        [$_succ, $_fail, $cur_ratio] = $this->detail_ratio($mchid, $cur_quality, $card_type, $spec, $period);
+        Log::record("{$header} cur_ratio = {$cur_ratio},lower_ratio={$ratio}",Log::DEBUG);
+
+        if($cur_ratio >= $ratio) return true;
+
         $prices = $this->getPrice($mchid, $org_quality, $card_type, $spec);
         if ($prices === false) {
             return false;
@@ -301,7 +479,7 @@ class mratio_control
             $cur_pratio = round(($profit + 0.00001) / ($amount + 0.00001),4);
             $profit_ratio = round($profit_ratio,4);
 
-            Log::record("{$header} cur_pratio = {$cur_pratio},profit_ratio={$profit_ratio}",Log::DEBUG);
+            Log::record("{$header} qts_checker cur_pratio = {$cur_pratio},profit_ratio={$profit_ratio}",Log::DEBUG);
             return $cur_pratio > $profit_ratio;
         };
 

文件差异内容过多而无法显示
+ 8 - 2
test/TestBigData.php