|
|
@@ -16,11 +16,12 @@ use tw\redis\ActivityPool;
|
|
|
*
|
|
|
* 活动设计为:一个活动有一个商品分类,该分类下的商品为该活动商品
|
|
|
*/
|
|
|
-abstract class ActivityCalc {
|
|
|
+abstract class ActivityCalc
|
|
|
+{
|
|
|
protected $ctx = [];
|
|
|
|
|
|
- public function __construct() {
|
|
|
-
|
|
|
+ public function __construct()
|
|
|
+ {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -28,8 +29,9 @@ abstract class ActivityCalc {
|
|
|
* @param $cate_id
|
|
|
* @return array
|
|
|
*/
|
|
|
- protected static function getOrders($cate_id) {
|
|
|
- $products = StoreOrderCartInfo::alias('ci')
|
|
|
+ protected static function getOrders($cate_id)
|
|
|
+ {
|
|
|
+ $orders = StoreOrderCartInfo::alias('ci')
|
|
|
->join('store_order o', 'o.id=ci.oid')
|
|
|
->join('store_product p', 'ci.product_id=p.id')
|
|
|
->join('user u', 'u.uid = o.uid')
|
|
|
@@ -42,14 +44,15 @@ abstract class ActivityCalc {
|
|
|
->where('ci.activity', '')
|
|
|
->field('o.id, o.order_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;
|
|
|
+ $orders = $orders ? $orders->toArray() : [];
|
|
|
+ return $orders;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 用统一的架构来计算输赢
|
|
|
*/
|
|
|
- public function calc() {
|
|
|
+ public function calc()
|
|
|
+ {
|
|
|
// 活动分类ID
|
|
|
$cate_id = $this->getId();
|
|
|
$products = self::getOrders($cate_id);
|
|
|
@@ -57,7 +60,7 @@ abstract class ActivityCalc {
|
|
|
$minNum = $this->getMinimalProductNum();
|
|
|
if ($pNum < $minNum) {
|
|
|
warnlog("not enough order. product num: $pNum, $minNum needed, stop activity:" . $this->getNameCN());
|
|
|
- SystemAwardHistory::create([
|
|
|
+ SystemAwardHistory::create([
|
|
|
'activity' => $this->getName(),
|
|
|
'result' => $this->getResult(mt_rand(0, 10) < 5 ? true : false),
|
|
|
'ts' => time(),
|
|
|
@@ -86,7 +89,7 @@ abstract class ActivityCalc {
|
|
|
|
|
|
// 标记有多件商品的订单, 再次统计到属于某个订单的商品时, 订单会重复
|
|
|
$orders = [];
|
|
|
- foreach($products as &$p) {
|
|
|
+ foreach ($products as &$p) {
|
|
|
$counter += 1;
|
|
|
|
|
|
$ci = json_decode($p['cart_info'], true);
|
|
|
@@ -97,7 +100,7 @@ abstract class ActivityCalc {
|
|
|
$price = isset($attrInfo['price']) ? $attrInfo['price'] : 0.0;
|
|
|
$cost = isset($attrInfo['cost']) ? $attrInfo['cost'] : 0.0;
|
|
|
// 付款总额, 总成本
|
|
|
- $ppaid = bcmul($num, $price, 2);// product paid
|
|
|
+ $ppaid = bcmul($num, $price, 2); // product paid
|
|
|
$pcost = bcmul($num, $cost, 2);
|
|
|
// orderId
|
|
|
$oid = $p['id'];
|
|
|
@@ -133,7 +136,7 @@ abstract class ActivityCalc {
|
|
|
$right_cost = bcadd($right_cost, $pcost, 2);
|
|
|
}
|
|
|
} // foreach
|
|
|
-
|
|
|
+
|
|
|
// 利润
|
|
|
$left_profit = bcsub($left_spent, $left_cost, 2);
|
|
|
$right_profit = bcsub($right_spent, $right_cost, 2);
|
|
|
@@ -157,19 +160,19 @@ abstract class ActivityCalc {
|
|
|
// 此时,订单必为 loser
|
|
|
// 47% 概率胜
|
|
|
$itWin = false; // 这单胜了 ?
|
|
|
- $dice = mt_rand(0, 100);
|
|
|
- if ( $dice < 60) {
|
|
|
+ $dice = mt_rand(0, 100);
|
|
|
+ if ($dice < 60) {
|
|
|
$itWin = true;
|
|
|
}
|
|
|
|
|
|
- $poolBalance = floatval((new ActivityPool)->get('', $this->getName()));// pool 中金额
|
|
|
+ $poolBalance = floatval((new ActivityPool)->get('', $this->getName())); // pool 中金额
|
|
|
if (!$itWin) {
|
|
|
// 如果为新用户,且池子有钱,让他胜
|
|
|
if ($poolBalance > $profit && $products[0]['pay_count'] <= 1) {
|
|
|
$itWin = true;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if ($itWin) {
|
|
|
$profit = -$profit;
|
|
|
list($winners, $losers) = [$losers, $winners]; // swap
|
|
|
@@ -181,7 +184,7 @@ abstract class ActivityCalc {
|
|
|
|
|
|
$result = $this->getResult($winners == $left);
|
|
|
|
|
|
- warnlog('products:' . json_encode($products)
|
|
|
+ warnlog('products:' . json_encode($products)
|
|
|
. ' left:' . json_encode($left) . ' left_spent:' . $left_spent
|
|
|
. ' left_cost:' . $left_cost . ' left_profit:' . $left_profit
|
|
|
. ' right' . json_encode($right) . ' right_spent:' . $right_spent
|
|
|
@@ -202,11 +205,11 @@ abstract class ActivityCalc {
|
|
|
]);
|
|
|
|
|
|
// 结果处置 胜方退款,败方发货
|
|
|
- foreach($winners as $p) {
|
|
|
+ foreach ($winners as $p) {
|
|
|
$single = $orders[$p['id']] == 1;
|
|
|
$this->execute($p, $single, true);
|
|
|
}
|
|
|
- foreach($losers as $p) {
|
|
|
+ foreach ($losers as $p) {
|
|
|
$single = $orders[$p['id']] == 1;
|
|
|
$this->execute($p, $single, false);
|
|
|
}
|
|
|
@@ -214,60 +217,75 @@ abstract class ActivityCalc {
|
|
|
warnlog("activity" . $this->getNameCN() . " calc finished. result: $result");
|
|
|
}
|
|
|
|
|
|
- protected function execute($product, $single=true, $win=true) {
|
|
|
+ protected function execute($order, $single = true, $win = true)
|
|
|
+ {
|
|
|
BaseModel::beginTrans();
|
|
|
$result = 0;
|
|
|
$reparation = 0.0;
|
|
|
+
|
|
|
+ $product_name = $order['store_name'];
|
|
|
+ $order_str = $order['order_id'];
|
|
|
+ $paid = $order['paid'];
|
|
|
+ $cost = $order['cost'];
|
|
|
+
|
|
|
if ($win) {
|
|
|
$result = 1;
|
|
|
- $reparation = bcmul(bcsub($product['paid'], $product['cost'], 2), $this->repRate(), 2);
|
|
|
+ $reparation = bcmul(bcsub($paid, $cost, 2), $this->repRate(), 2);
|
|
|
}
|
|
|
if ($reparation < 0.0) {
|
|
|
- warnlog("reparation = $reparation, orderId=" . $product['id']);
|
|
|
+ warnlog("reparation = $reparation, orderId=" . $order_str);
|
|
|
$reparation = 0.0;
|
|
|
}
|
|
|
// 标记商品为已参与活动
|
|
|
- $r1 = StoreOrderCartInfo::where('oid', $product['id'])
|
|
|
- ->where('product_id', $product['product_id'])
|
|
|
+ $r1 = StoreOrderCartInfo::where('oid', $order['id'])
|
|
|
+ ->where('product_id', $order['product_id'])
|
|
|
->update([
|
|
|
'activity' => $this->getName(),
|
|
|
'result' => $result,
|
|
|
'reparation' => $reparation,
|
|
|
]);
|
|
|
|
|
|
+ // 没胜利,退出
|
|
|
if (!$win) {
|
|
|
BaseModel::checkTrans($r1);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- $refund_price = bcadd($product['paid'], $reparation, 2);
|
|
|
+ $refund_price = bcadd($paid, $reparation, 2);
|
|
|
// 订单全部商品都中奖的退单
|
|
|
$r2 = true;
|
|
|
if ($single) {
|
|
|
- $r2 = StoreOrder::where('id', $product['id'])->update([
|
|
|
+ $r2 = StoreOrder::where('id', $order['id'])->update([
|
|
|
'refund_price' => $refund_price,
|
|
|
'refund_status' => 2,
|
|
|
]);
|
|
|
}
|
|
|
// 中奖的 退款并赔款返回到佣金
|
|
|
- $r3 = UserBill::income('活动' . $this->getNameCN(), $product['uid'], 'now_money', 'brokerage',
|
|
|
- $refund_price, $product['id'], bcadd($product['now_money'], $refund_price, 2),
|
|
|
- '订单退款' . $product['paid'] . '+' . $reparation . '元');
|
|
|
- $r4 = User::bcInc($product['uid'], 'brokerage_price', $refund_price, 'uid');
|
|
|
+ $r3 = UserBill::income(
|
|
|
+ '活动' . $this->getNameCN() . "[$order_str]",
|
|
|
+ $order['uid'],
|
|
|
+ 'now_money',
|
|
|
+ 'brokerage',
|
|
|
+ $refund_price,
|
|
|
+ $order['id'],
|
|
|
+ bcadd($order['now_money'], $refund_price, 2),
|
|
|
+ '订单退款' . $order['paid'] . '+' . $reparation . '元'
|
|
|
+ );
|
|
|
+ $r4 = User::bcInc($order['uid'], 'brokerage_price', $refund_price, 'uid');
|
|
|
|
|
|
$ok = $r1 && $r2 && $r3 && $r4;
|
|
|
BaseModel::checkTrans($ok);
|
|
|
|
|
|
if ($ok) {
|
|
|
- $pname = $product['store_name'];
|
|
|
- $order_id = $product['order_id'];
|
|
|
- $paid = $product['paid'];
|
|
|
-
|
|
|
// 中奖用户发送中奖消息.
|
|
|
- UserNotice::sendNoticeTo($product['uid'], '您的订单已处理 点击查看',
|
|
|
- "您好,由于活动商品库存有限,您的订单 $pname(订单号 $order_id) 未能成功发货。 该商品付款 $paid 元已如数退还,并赔付您 $reparation 元作为补偿,请在”我的佣金”中核实。对您造成的不便我们深感抱歉。感谢您对我们的信任和喜爱,美天旺祝您生活愉快。", $product['image']);
|
|
|
+ UserNotice::sendNoticeTo(
|
|
|
+ $order['uid'],
|
|
|
+ '您的订单已处理 点击查看',
|
|
|
+ "您好,由于活动商品库存有限,您的订单 $product_name(订单号 $order_str) 未能成功发货。 该商品付款 $paid 元已如数退还,并赔付您 $reparation 元作为补偿,请在”我的佣金”中核实。对您造成的不便我们深感抱歉。感谢您对我们的信任和喜爱,美天旺祝您生活愉快。",
|
|
|
+ $order['image']
|
|
|
+ );
|
|
|
}
|
|
|
- }
|
|
|
+ } // execute
|
|
|
|
|
|
// 活动所属的 $categoryId
|
|
|
abstract protected function getId();
|
|
|
@@ -285,7 +303,7 @@ abstract class ActivityCalc {
|
|
|
abstract protected function getMinimalProductNum();
|
|
|
|
|
|
// 获得开奖结果 int
|
|
|
- abstract protected function getResult($leftwin=true);
|
|
|
+ abstract protected function getResult($leftwin = true);
|
|
|
/**
|
|
|
* 根据此函数返回值来划分 getOrders() 返回的订单为两份, 其中一份中奖, 当本函数返回 true, $product 加入"左边"
|
|
|
*
|
|
|
@@ -295,4 +313,4 @@ abstract class ActivityCalc {
|
|
|
* @return boolean true 加入左边
|
|
|
*/
|
|
|
abstract protected function leaningJudge($index, $product, $attr);
|
|
|
-}
|
|
|
+}
|