| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <?php
- namespace crmeb\services\async;
- use app\admin\model\user\User;
- use app\admin\model\user\UserBill;
- use app\models\store\StoreOrder;
- use app\models\store\StoreOrderCartInfo;
- use app\models\user\UserNotice;
- use crmeb\basic\BaseModel;
- use think\facade\Config;
- use think\facade\Log;
- use ActivityCalc;
- class LuckyCalc {
- protected static $NAME = 'lucky';
- private function searchActiveInSuk($suk) {
- $parts = explode(",", $suk);
- if (count($parts) <= 0) {
- return false;
- }
- foreach ($parts as $part) {
- $t = trim($part);
- if ($t == 20 || $t == 21) {
- return $t;
- }
- }
- return false;
- }
- public function calc() {
- $lucky_cate_id = Config::get('activity.lucky_cate_id');
- $products = ActivityCalc::getOrders($lucky_cate_id);
- if (count($products) <= 1) {
- Log::info('not enough order, stop lucky activity');
- return;
- }
- // split win & lose
- shuffle($products);
- shuffle($products);
- $left = [];
- $right = [];
- $left_spent = 0.0;
- $right_spent = 0.0;
- $orders = [];
- foreach ($products as &$p) {
- $ci = json_decode($p['cart_info'], true);
- $num = $ci['num']; // 购买个数
- $productInfo = isset($ci['productInfo']) ? $ci['productInfo'] : [];
- $attrInfo = isset($productInfo['attrInfo']) ? $productInfo['attrInfo'] : [];
- $price = isset($attrInfo['price']) ? $attrInfo['price'] : 0.0;
- $cost = isset($attrInfo['cost']) ? $attrInfo['cost'] : 0.0;
- $ppaid = bcmul($num, $price, 2);// product paid
- $pcost = bcmul($num, $cost, 2);
- $oid = $p['id'];
- $p['paid'] = $ppaid;
- $p['cost'] = $pcost;
- if (!isset($orders[$oid])) {
- $orders[$oid] = 1;
- } else {
- $orders[$oid] += 1;
- }
- if ($ppaid <= 1.0) {
- Log::warning("impossible price, order: ". $p['id']);
- continue;
- }
- if ($cost <= 0.1) {
- Log::warning("impossible cost, order: ". $p['id']);
- continue;
- }
- $suk = isset($attrInfo['suk']) ? $attrInfo['suk'] : 'any';
- $flag = $this->searchActiveInSuk($suk);
- if ($flag == 20) {
- $left[] = $p;
- $left_spent = bcadd($left_spent, $ppaid, 2);
- } else if ($flag == 21) {
- $right[] = $p;
- $right_spent = bcadd($right_spent, $ppaid, 2);
- } else {
- Log::error('cant find suk in lucky field. id=' . $oid);
- continue;
- }
- }// foreach
- $products = [];
- $diff_money = bcsub($left_spent, $right_spent, 2);
- if ($diff_money < 0.0) {
- $diff_money = -$diff_money;
- }
- $open = 20;
- $winners = $left;
- $losers = $right;
- if ($left_spent > $right_spent) {
- $open = 21;
- $winners = $right;
- $losers = $left;
- }
- // 结果处置
- foreach($winners as $p) {
- $single = $orders[$p['id']] == 1;
- $this->execute($p, $single, true);
- }
- foreach($losers as $p) {
- $single = $orders[$p['id']] == 1;
- $this->execute($p, $single, false);
- }
- } // calc
- /**
- * 奖励分配
- *
- * @param $product 获奖订单中的商品
- * @param bool $single 是否是单种商品构成的订单
- * @param bool $win 是否中奖
- */
- protected function execute($product, $single=true, $win=true) {
- BaseModel::beginTrans();
- $result = 0;
- $reparation = 0.0;
- if ($win) {
- $result = 1;
- $reparation = bcmul(bcsub($product['paid'], $product['cost'], 2), 0.1, 2);
- }
- // 标记商品为已参与活动
- $r1 = StoreOrderCartInfo::where('oid', $product['id'])
- ->where('product_id', $product['product_id'])
- ->update([
- 'activity' => self::$NAME,
- 'result' => $result,
- 'reparation' => $reparation,
- ]);
- if (!$win) {
- return;
- }
- $refund_price = bcadd($product['paid'], $reparation, 2);
- // 订单全部商品都中奖的退单
- $r2 = true;
- if ($single) {
- $r2 = StoreOrder::where('id', $product['id'])->update([
- 'refund_price' => $refund_price,
- 'refund_status' => 2,
- ]);
- }
- // 中奖的 退款并赔款返回到佣金
- $r3 = UserBill::income('參加活动', $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');
- $ok = $r1 && $r2 && $r3 && $r4;
- BaseModel::checkTrans($ok);
- if ($ok) {
- // 中奖用户发送中奖消息.
- UserNotice::sendNoticeTo($product['uid'], '您的订单已退款',
- '您好,由于活动商品库存有限,您的订单 ' . $product['store_name']
- . ' 未能成功分配. 该商品付款' . $product['paid'] . '元已如数退还, 并赔付您' . $reparation
- . '元作为补偿, 对您造成的不便我们深感抱歉. 同时感谢您对美天旺的喜爱和信任, 美天旺活动场将永远为您守候. 顺祝生活愉快.');
- }
- }
- }
|