|
|
@@ -8,6 +8,7 @@ use app\models\store\StoreOrderCartInfo;
|
|
|
use app\models\system\SystemAwardHistory;
|
|
|
use app\models\user\UserNotice;
|
|
|
use crmeb\basic\BaseModel;
|
|
|
+use crmeb\utils\Redis;
|
|
|
use think\facade\Log;
|
|
|
|
|
|
|
|
|
@@ -40,7 +41,8 @@ abstract class ActivityCalc {
|
|
|
->where('o.is_system_del', 0)
|
|
|
->where('p.cate_id', $cate_id)
|
|
|
->where('ci.activity', '')
|
|
|
- ->field('o.id, o.pay_price, ci.product_id, ci.cart_info, u.uid, u.now_money, p.store_name')->select();
|
|
|
+ ->field('o.id, o.pay_price, ci.product_id, ci.cart_info, u.uid, u.now_money, u.pay_count, p.store_name')
|
|
|
+ ->select();
|
|
|
$products = $products ? $products->toArray() : [];
|
|
|
return $products;
|
|
|
}
|
|
|
@@ -52,19 +54,21 @@ abstract class ActivityCalc {
|
|
|
// 活动分类ID
|
|
|
$cate_id = $this->getId();
|
|
|
$products = self::getOrders($cate_id);
|
|
|
- if (count($products) <= 1) {
|
|
|
- Log::warning('not enough order, stop activity:' . $this->getNameCN());
|
|
|
+ $pNum = count($products);
|
|
|
+ $minNum = $this->getMinimalProductNum();
|
|
|
+ if ($pNum < $minNum) {
|
|
|
+ Log::warning("not enough order. product num: $pNum, $minNum needed, stop activity: $this->getNameCN()");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 按商品处理订单
|
|
|
- $counter = 0;
|
|
|
- $left = [];
|
|
|
- $right = [];
|
|
|
- $left_spent = 0;
|
|
|
- $right_spent = 0;
|
|
|
- $left_cost = 0;
|
|
|
- $right_cost = 0;
|
|
|
+ $counter = 0; // 订单中商品计数器
|
|
|
+ $left = []; // 左侧商品
|
|
|
+ $right = []; // 右侧商品
|
|
|
+ $left_spent = 0; // 左侧总价
|
|
|
+ $right_spent = 0; // 右侧总价
|
|
|
+ $left_cost = 0; // 左侧总成本
|
|
|
+ $right_cost = 0; // 右侧总成本
|
|
|
|
|
|
// 打乱商品顺序
|
|
|
shuffle($products);
|
|
|
@@ -124,17 +128,46 @@ abstract class ActivityCalc {
|
|
|
$left_profit = bcsub($left_spent, $left_cost, 2);
|
|
|
$right_profit = bcsub($right_spent, $right_cost, 2);
|
|
|
// 定输赢
|
|
|
- $diff_money = bcsub($left_spent, $right_spent, 2);
|
|
|
- if ($diff_money < 0.0) {
|
|
|
- $diff_money = -$diff_money;
|
|
|
- }
|
|
|
- $profit = $left_profit;
|
|
|
+ $diff_money = abs(bcsub($left_spent, $right_spent, 2));
|
|
|
+ // if ($diff_money < 0.0) {
|
|
|
+ // $diff_money = -$diff_money;
|
|
|
+ // }
|
|
|
+ // 假定左边胜利
|
|
|
+ $profit = $right_profit;
|
|
|
$winners = $left;
|
|
|
$losers = $right;
|
|
|
+ // 左边利润高则右边胜利
|
|
|
if ($left_profit > $right_profit) {
|
|
|
$winners = $right;
|
|
|
$losers = $left;
|
|
|
- $profit = $right_profit;
|
|
|
+ $profit = $left_profit;
|
|
|
+ }
|
|
|
+ // 如果只有 1 件商品
|
|
|
+ if ($pNum == 1) {
|
|
|
+ $KEY = 'activity:pool';
|
|
|
+ // 此时,订单必为 loser
|
|
|
+ // 40% 概率胜
|
|
|
+ $itWin = false; // 这单胜了 ?
|
|
|
+ $dice = mt_rand(0, 100);
|
|
|
+ if ( $dice < 40) {
|
|
|
+ $itWin = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ $remain = intval(Redis::hGet($KEY, $this->getName()));
|
|
|
+ if (!$itWin) {
|
|
|
+ // 如果为新用户,且池子有钱,让他胜
|
|
|
+ if ($remain > $profit && $products[0]['pay_count'] <= 1) {
|
|
|
+ $itWin = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($itWin) {
|
|
|
+ $profit = -$profit;
|
|
|
+ list($winners, $losers) = [$losers, $winners];
|
|
|
+ }
|
|
|
+ Redis::hSet($KEY, $this->getName(), $remain + $profit);
|
|
|
+
|
|
|
+ Log::warning("$this->getName(): single order[product]. dice:$dice, remain:$remain, pay_count:$products[0]['pay_count']");
|
|
|
}
|
|
|
|
|
|
$result = $this->getResult($winners == $left);
|
|
|
@@ -159,7 +192,7 @@ abstract class ActivityCalc {
|
|
|
'rate' => $this->repRate(),
|
|
|
]);
|
|
|
|
|
|
- // 结果处置
|
|
|
+ // 结果处置 胜方退款,败方发货
|
|
|
foreach($winners as $p) {
|
|
|
$single = $orders[$p['id']] == 1;
|
|
|
$this->execute($p, $single, true);
|
|
|
@@ -169,7 +202,7 @@ abstract class ActivityCalc {
|
|
|
$this->execute($p, $single, false);
|
|
|
}
|
|
|
|
|
|
- Log::warning('activity ' . $this->getNameCN() . ' calc finished. result:' . $result);
|
|
|
+ Log::warning("activity $this->getNameCN() calc finished. result: $result");
|
|
|
}
|
|
|
|
|
|
protected function execute($product, $single=true, $win=true) {
|
|
|
@@ -233,6 +266,9 @@ abstract class ActivityCalc {
|
|
|
// 赔款所占商品利润的百分比
|
|
|
abstract protected function repRate();
|
|
|
|
|
|
+ // 满足开奖的最小订单数
|
|
|
+ abstract protected function getMinimalProductNum();
|
|
|
+
|
|
|
// 获得开奖结果 int
|
|
|
abstract protected function getResult($leftwin=true);
|
|
|
/**
|