db->beginTransaction(); try { $mall_id = $activity['mall_id']; $order_arr = $order_ids; //中文配置 $customize_text = \Yii::$app->services->setting->addons->get($mall_id, LuckyGroupEnum::ADDONS_NAME, 'customize_text'); $customize_reward_name = \Yii::$app->services->setting->addons->get($mall_id, LuckyGroupEnum::ADDONS_NAME, 'customize_reward_name'); $customize_arr = array_merge($customize_text, $customize_reward_name); // 获取同一拼团同一商品,参团中的订单,抽中次数小于购买次数的订单 - 按时间顺序取拼团数量 $group_require_num = $activity['group_num']; //开团需要人数 $virtual_num = $activity['virtual_num']; //活动设置的虚拟人数 $real_group_require_num = $group_require_num - $virtual_num; //真实开团需要人数 $real_group_require_num = $real_group_require_num < 0 ? $group_require_num : $real_group_require_num; $configs['basic'] = \Yii::$app->services->setting->addons->get($mall_id, LuckyGroupEnum::ADDONS_NAME, 'basic'); $configs['bonus_pool'] = \Yii::$app->services->setting->addons->get($mall_id, LuckyGroupEnum::ADDONS_NAME, 'bonus_pool'); $joining_orders = LuckyGroupOrder::find() ->where(['id' => $order_ids, 'group_status' => 1]) ->andWhere(new \yii\db\Expression('`buy_nums` > `win_nums`')) ->indexBy('id') ->all(); $attend_order_num = count($joining_orders); //本次可开奖订单数(人数) echo '
';
var_dump(
'开团需要人数:' . $group_require_num,
'活动设置的虚拟人数:' . $virtual_num,
'真实开团需要人数:' . $real_group_require_num,
'本次可开奖订单数(人数):' . $attend_order_num
);
// 随机拼中人数
$random_win_num = ($activity['random_win_num'] <= 0) ? 1 : $activity['random_win_num'];
if ($attend_order_num < $random_win_num) {
//先删除订单id入队标记
$queue_logic = new OrderPaidQueueLogic();
$queue_logic->delOrderEnqueueFlag($order_arr);
$order_id_enqueue = array_column($joining_orders, 'id');
$queue_logic->enqueue($mall_id, $activity, $goods_id, $order_id_enqueue);
return false;
}
$user_id_arr = array_column($joining_orders, 'user_id');
$lottery_rules = new LotteryRulesLogic();
$win_keys = $lottery_rules->checkWinOrLoss($mall_id, $joining_orders, $user_id_arr, $attend_order_num, $random_win_num, $configs['basic']);
if (!is_array($win_keys)) $win_keys = [$win_keys];
$this->updateGroupGoodsJoinNum($activity['id'], $goods_id, $attend_order_num);
$group_users = LuckyGroupUser::lists(
[
'where' => [
['user_id' => $user_id_arr]
],
'index' => 'user_id'
],
false
);
$users = User::lists(
[
'where' => [
['id' => $user_id_arr]
],
'index' => 'id'
]
);
$user_wallets = UserWallet::lists(
[
'where' => [
['user_id' => $user_id_arr]
],
'index' => 'user_id'
],
false
);
$win_log_list = LuckyGroupWinLog::lists([
'where' => [
['mall_id' => $mall_id],
['activity_id' => $activity['id']],
['status' => StatusEnum::ENABLED],
['user_id' => $user_id_arr],
],
'select' => 'user_id,sum(win_num) as win_num',
'index' => 'user_id',
'group' => 'user_id'
]);
$expend_type = $activity['expend_type'] ?? ''; // 参团消耗类型
$expend_num = $activity['expend_num'] ?? 0; // 参团消耗数量
$yu_attend_times = $consume = 0;
$order_ids = $win_order_ids = $loss_order_ids = '';
$insert_wallet = $frozen_log_arr = $user_frozen_arr = $order_id_enqueue = [];
$time = time();
$attend_award_setting = json_decode($activity['attend_award_setting'], true);
$win_award_setting = json_decode($activity['win_award_setting'], true);
$bonus_pool = LuckyGroupBonusPool::findOne(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]);
$user_address_id_arr = [];
$order_no_arr = [];
$goods_attr_id = 0;
foreach ($joining_orders as $key => $order) {
$goods_attr_id = $order['goods_attr_id'];
if (in_array($key, $win_keys)) {
$user_address_id_arr[] = $order['address_id'];
$order_no_arr[] = $order['order_no'];
}
}
$pay_order_list = PaymentTradeOrder::lists(['where' => [['order_no' => $order_no_arr],['is_pay'=>1]], 'index' => 'order_no']);
$trade_id_arr = array_column($pay_order_list, 'trade_id');
$pay_trade_list = PaymentTrade::lists(['where' => [['id' => $trade_id_arr]], 'index' => 'id']);
$user_address_arr = UserAddress::lists(['where' => [['id' => $user_address_id_arr]], 'index' => 'user_id']);
$goods_attr = GoodsAttr::findOne(['id' => $goods_attr_id]);
$goods = Goods::findOne(['id' => $goods_id]);
$user_arr = [];
$trans_pool_money = $subsidy = 0;
$lottery_period_arr = [];
$lottery_period = LuckyGroupLotteryPeriod::getOne([['activity_id' => $activity['id']], ['goods_id' => $goods_id]], false, [], 'number desc');
$number = $lottery_period['number'] ?? 0;
$win_money = $win_peoples = $attend_reward = 0;
$loss_money = 0;
$loss_peoples = 0;
$attend_reward_amounts = 0;
$win_reward_scores = 0;
$win_reward_balances = 0;
$group_failed_times = 0;
$deplete_balances = 0;
$deplete_scores = 0;
$goods_price = 0;
// 因为主商城订单在事务中。会导致触发事件时订单详情,所以需要一个数组存储
$mainOrderList = [];
foreach ($joining_orders as $key => $order) {
$user_arr[$order['user_id']]['order_id'] = $order['id'];
$goods_price = bcdiv($order['total_goods_price'] , $order['buy_nums'], 2);
$order_ids .= $order['id'] . ',';
//判断预扣参团次数是否大于0,是直接减预扣
$attend_times = 0;
if ($order['yu_attend_times'] <= 0) {
$res = $this->reduceAttendTimes($group_users, $order, $customize_arr);
if ($res == false) {
unset($joining_orders[$key]);
var_dump(3);
continue;
}
$attend_times = 1;
} else {
$yu_attend_times = -1;
}
//消耗
if ($expend_num > 0) {
if ($order['consume'] <= 0) {
$res = $this->reduceExpendNum($expend_type, $expend_num, $user_wallets, $order, $deplete_balances, $deplete_scores);
if ($res == false) {
unset($joining_orders[$key]);
var_dump(4);
continue;
}
} else {
$consume = -$expend_num;
if ($expend_type == LuckyGroupEnum::AWARD_TYPE_BALANCE) $deplete_balances += $expend_num;
if ($expend_type == LuckyGroupEnum::AWARD_TYPE_SCORE) $deplete_scores += $expend_num;
}
}
$res = $this->updateLuckyGroupUser($group_users[$order['user_id']], $order, $attend_times);
if ($res == false) {
unset($joining_orders[$key]);
var_dump(2);
continue;
}
$res = $this->updateLuckyOrder($order, $yu_attend_times, $consume);
if ($res == false) {
unset($joining_orders[$key]);
var_dump(1);
continue;
}
$win_user_id = $win_order_id = $loss_user_id = $loss_order_id = 0;
$unit_price = $order['total_pay_price'] / $order['buy_nums'];
if (in_array($key, $win_keys)) {
//生成主订单
$main_order = self::createMallOrder($order, $pay_order_list, $pay_trade_list, $user_address_arr, $goods, $goods_attr);
if ($main_order == false) {
//生成主订单失败,退款
//todo 退用户余额并修改状态为拼团失败
$desc = ('幸运拼团生成主订单失败');
var_dump('order_id:' . $order['id'] . $desc);
$order->group_status = 3;
$group_buy_text = Customize::to($customize_arr, 'group_buy_text');
$desc = ($group_buy_text ?? '幸运拼团') . '生成主订单失败';
$this->refundToBalance($order, $desc);
continue;
}
//拼中
$group_users[$order['user_id']]->win_num += 1;
$group_users[$order['user_id']]->save();
$order->group_status = LuckyGroupEnum::GROUP_SUCCESS;
$order->win_time = time();
$order->win_nums = $order->win_nums + 1;
//如果类型为自动拼团,并且购买数量大于中奖次数,则自动继续参与拼团
if ($order->attend_type == LuckyGroupEnum::ATTEND_TYPE_AUTO
&& $order->buy_nums > $order->win_nums) {
$order->group_status = LuckyGroupEnum::GROUP_JOINING;
$order_id_enqueue[] = $order['id'];
}
$order->save();
$win_order_id = $order['id'];
$win_user_id = $order['user_id'];
$win_order_ids .= $win_order_id . ',';
$user_win_times = $win_log_list[$order['user_id']]['win_num'] ?? 0;
//生成拼中奖励
GroupRewardLogic::computeWinReward($win_award_setting, $mall_id, $win_user_id, $win_order_id, $activity['win_times'], $user_win_times+1, $insert_wallet, $win_reward_scores, $win_reward_balances, $customize_arr,
$order['order_no'],$order['user_id'],$goods_price,$goods['goods_name']);
try {
$mainOrderList[] = [
'id' => $main_order['id'],
'operator_id' => $main_order['user_id'],
'operator_name' => $users[$main_order['user_id']]['nickname'] ?? '',
];
} catch (\Exception $e) {
var_dump($e->getMessage());
}
GroupRewardLogic::computePrizePool($configs, $order['id'], $group_users[$order['user_id']], $time, $bonus_pool['money'] ?? 0, $frozen_log_arr, $user_frozen_arr, $customize_arr);
$pool_trans_money = $activity['pool_trans_money']; //转到奖金池金额%
$is_percent_pool_trans = $activity['is_percent_pool_trans']; //是否按百分比算分配奖金池金额【1是 0否】
if ($pool_trans_money > 0) {
//计算转入奖金池金额,除以拼中订单购买数量
$trans_pool_money += $is_percent_pool_trans ? ($unit_price * $pool_trans_money / 100) : $pool_trans_money;
}
$win_money += $unit_price; //拼中金额
$win_peoples++;//拼中人数
LuckyGroupWinLog::setData(['mall_id'=>$mall_id,'user_id'=>$order['user_id'],'activity_id'=>$activity['id'],'win_num'=>1]);
} else {
$group_failed_times += 1;
//拼不中
if ($order['attend_type'] == LuckyGroupEnum::ATTEND_TYPE_AUTO) {
$order_id_enqueue[] = $order['id'];
LuckyGroupWinLog::setData(['mall_id'=>$mall_id,'user_id'=>$order['user_id'],'activity_id'=>$activity['id'],'win_num'=>0]);
} else {
//拼团失败,退款
//todo 退用户余额并修改状态为拼团失败
$order->group_status = 3;
$group_buy_order_text = Customize::to($customize_arr, 'group_buy_order_text');
$join_team_text = Customize::to($customize_arr, 'join_team_text');
$desc = ($group_buy_order_text ?? '幸运拼团订单') . '(id:' . $order['id'] . ')' . ($join_team_text ?? '拼团') . '失败,退还购物金额';
var_dump('order_id:' . $order['id'] . $desc);
$this->refundToBalance($order, $desc);
$loss_order_id = $order['id'];
$loss_user_id = $order['user_id'];
$loss_order_ids .= $loss_order_id . ',';
$loss_money += $unit_price;
$loss_peoples++;//拼不中人数
}
}
$attend_reward_amounts += $unit_price;
//生成参团奖励数据
GroupRewardLogic::computeJoinReward($attend_award_setting, $activity['attend_user_type'], $mall_id,
$order['user_id'], $order['id'], $win_user_id, $win_order_id, $loss_user_id, $loss_order_id, $insert_wallet, $customize_arr, $attend_reward,
$order['order_no'],$order['user_id'],$goods_price,$goods['goods_name']
);
//生成推荐参团奖励数量
GroupRewardLogic::computeInviteReward($mall_id, $goods_price, $configs, $order['id'], $users[$order['user_id']], $insert_wallet, $customize_arr,
$order['order_no'],$order['user_id'],$goods['goods_name']);
}
if (!empty($insert_wallet)) {
$res = $this->sendUserWallet($insert_wallet, $group_users);
if ($res == false) throw new Exception('发送资金队列失败');
}
//开团日志
$params = [
'mall_id' => $mall_id, 'goods_id' => $goods_id, 'group_require_num' => $group_require_num,
'real_group_require_num' => $real_group_require_num,
'activity_id' => $activity['id'], 'expend_type' => $expend_type, 'expend_num' => $expend_num,
'virtual_num' => $virtual_num, 'attend_order_num' => $attend_order_num, 'order_id' => trim($order_ids, ','),
'win_order_ids' => trim($win_order_ids, ','), 'win_reward_scores' => $win_reward_scores, 'win_reward_balances' => $win_reward_balances,
'attend_reward_amounts' => $attend_reward_amounts,
'distribute_bonus_pool_amounts' => $trans_pool_money,
];
$open_reward_log_model = LuckyGroupOpenRewardLog::setData($params);
if ($open_reward_log_model == false) throw new Exception('添加开团日志失败');
//生成奖金池冻结数据
if (!empty($frozen_log_arr)) {
LuckyGroupFrozenLog::batchAdd($frozen_log_arr);
if (!empty($user_frozen_arr)) {
foreach ($user_frozen_arr as $user_id => $money) {
$group_users[$user_id]->frozen_commission += $money;
$group_users[$user_id]->pool_commission += $money;
$group_users[$user_id]->save();
}
}
}
// 参团等级佣金奖励发放
if(MallAddons::isInstall($mall_id,AddonsEnum::ADDONS_NAME_AGENT)){
GroupRewardLogic::sendGroupCommissionLog($configs, $joining_orders, $user_arr, $activity,$goods_price,$goods['goods_name']);
}
//先删除订单id入队标记
$queue_logic = new OrderPaidQueueLogic();
$queue_logic->delOrderEnqueueFlag($order_arr);
if ($order_id_enqueue) {
var_dump('重新入队订单id:' . implode(',', $order_id_enqueue));
$queue_logic->enqueue($mall_id, $activity, $goods_id, $order_id_enqueue);
}
if ($trans_pool_money > 0) {
LuckyGroupBonusPool::setData($bonus_pool, $mall_id, $trans_pool_money);
}
$send_sms_order_ids = [];
foreach ($joining_orders as $key => $order) {
$lottery_period_arr[] = [
$order['mall_id'],
$open_reward_log_model['id'],
$order['activity_id'],
$order['goods_id'],
$order['user_id'],
$order['id'],
$number + 1,
trim($win_order_ids, ','),
trim($loss_order_ids, ','),
StatusEnum::ENABLED,
$time,
$time,
];
$send_sms_order_ids = $order['id'];
}
//添加期数
LuckyGroupLotteryPeriod::setData($lottery_period_arr);
//活动统计
$params = [
'activity_id' => $activity['id'],
'mall_id' => $mall_id,
'group_amounts' => $attend_reward_amounts,
'group_peoples' => $random_win_num,
'group_periods' => 1,
'group_failed_times' => $group_failed_times,
'deplete_balances' => $deplete_balances,
'deplete_scores' => $deplete_scores,
'win_reward_balances' => $win_reward_balances,
'win_reward_scores' => $win_reward_scores,
'distribute_bonus_pool_amounts' => $trans_pool_money,
];
$res = LuckyGroupActivityStatistics::updateStatistics($params);
//商城统计,按月
$params = [
'win_money' => $win_money,
'win_peoples' => $win_peoples,
'attend_commission' => $attend_reward,
'mall_id' => $mall_id,
];
var_dump('商城统计,按月');
var_dump($params);
$res = LuckyGroupMallStatistics::updateStatistics($params);
//商城统计,按日
$params = [
'win_money' => $win_money,
'loss_money' => $loss_money,
'win_peoples' => $win_peoples,
'loss_peoples' => $loss_peoples,
];
$params['mall_id'] = $mall_id;
$res = LuckyGroupMallOpenGroupStatistics::updateStatistics($params);
$t->commit();
if (!empty($mainOrderList)) { // 因为受到事务影响导致。执行队列事件是可能主商城订单详情并未创建成功。所以移动到事务外
$event = new \common\events\order\OrderPaidEvent($mall_id);
foreach ($mainOrderList as $main_order) {
$main_data['id'] = $main_order['id'];
$main_data['operator_id'] = $main_order['operator_id'] ?? 0;
$main_data['operator_name'] = $main_order['operator_name'];
\Yii::$app->services->events->dispatch($event, $main_data, $event->listeners);
}
}
var_dump('开团成功');
$send_service = new Notify();
//发送短信通知 成功或失败
$order_ids = explode(',', trim($order_ids, ','));
\Yii::$app->custom->logs(__METHOD__ . "幸运拼团发送短信 " . json_encode($order_ids));
if ($order_ids) {
foreach ($order_ids as $order_id) {
\Yii::$app->custom->logs("幸运拼团发送短信 " . $order_id);
$send_service->send(['id' => $order_id]);
}
}
return true;
} catch (\Exception $e) {
$t->rollBack();
var_dump('openReward:err:' . $e->getMessage() . $e->getFile().$e->getLine());
return false;
}
}
public function sendUserWallet($insert_wallet, $group_users)
{
$mall_id = 0;
// 批量插入数据
try {
//投递到资产队列
if ($insert_wallet) {
$res = UserWalletService::batchHandleByQueue($insert_wallet);
if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
$arr = [];
var_dump('sendUserWallet====insert_wallet'.json_encode($insert_wallet));
foreach ($insert_wallet as $k => $item) {
$wallet_type = $item['wallet_type'];
$mall_id = $item['mall_id'];
if (isset($arr[$item['user_id']])) {
if (isset($arr[$item['user_id']][$wallet_type])) {
$arr[$item['user_id']][$wallet_type] += $item['money'];
} else {
$arr[$item['user_id']][$wallet_type] = $item['money'];
}
} else {
$arr[$item['user_id']] = [
$wallet_type => $item['money'],
];
}
}
var_dump('sendUserWallet====arr'.json_encode($arr));
foreach ($arr as $user_id => $value) {
if (isset($group_users[$user_id])) {
var_dump($user_id.'更新前'.$group_users[$user_id]->balance);
foreach ($value as $wallet_type => $money) {
$group_users[$user_id]->$wallet_type += $money;
}
$res = $group_users[$user_id]->save();
var_dump($user_id.'更新后'.$group_users[$user_id]->balance);
if (empty($res)) throw new \Exception('更新团长表奖励数额报错');
}else{
$lg_user = LuckyGroupUser::findOne(['user_id'=>$user_id,'mall_id'=>$mall_id,'status'=>1]);
if(empty($lg_user)){
$post = ['user_id' => $user_id, 'level' => 0];
foreach ($value as $wallet_type => $money) {
$post[$wallet_type] = $money;
}
LuckyGroupUser::setData($mall_id, $post);
}else{
var_dump($user_id.'==更新前'.$lg_user->balance);
foreach ($value as $wallet_type => $money) {
$lg_user->$wallet_type += $money;
}
$lg_user->save();
var_dump($user_id.'==更新后'.$lg_user->balance);
}
}
}
}
return true;
} catch (\Exception $e) {
echo '开团发送资金' . $e->getMessage();
return false;
}
}
//更新团长数据
public function updateLuckyGroupUser($group_user, $order, $attend_times)
{
$group_user->has_attend_times += 1;
$group_user->attend_times -= $attend_times;
if ($group_user->attend_times < 0) $group_user->attend_times = 0;
$res = $group_user->save();
if ($res == false) {
$order->group_status = 3;
$this->refundToBalance($order, '更新团长数据失败');
return false;
}
return true;
}
//更新订单数据
public function updateLuckyOrder($order, $yu_attend_times, $consume)
{
if (!empty($yu_attend_times)) $order->yu_attend_times += $yu_attend_times;
if (!empty($consume)) $order->consume += $consume;
$order->open_times += 1;
$res = $order->save();
if ($res == false) {
$this->refundToBalance($order, '更新订单数据失败');
return false;
}
return true;
}
//扣减参团次数
public function reduceAttendTimes($group_users, $order, $customize_arr)
{
$group_buy_order_text = Customize::to($customize_arr, 'group_buy_order_text');
$join_into_team_text = Customize::to($customize_arr, 'join_into_team_text');
$desc = ($group_buy_order_text ?? '幸运拼团订单') . ',' . ($join_into_team_text ?? '参团') . '次数不足';
try {
if ($group_users[$order['user_id']]['attend_times'] <= 0) {
throw new Exception($desc);
}
return true;
} catch (\Exception $e) {
$order->group_status = 3;
$this->refundToBalance($order, $desc);
return false;
}
}
//扣减消耗
public function reduceExpendNum($expend_type, $expend_num, $user_wallets, &$order, &$deplete_balances, &$deplete_scores, $customize_arr = [])
{
$group_buy_order_text = Customize::to($customize_arr, 'group_buy_order_text');
$join_into_team_text = Customize::to($customize_arr, 'join_into_team_text');
try {
$user_money = 0;
if (!empty($expend_type) && !empty($expend_num)) {
$is_can_continue = true;
switch ($expend_type) {
case LuckyGroupEnum::AWARD_TYPE_BALANCE:
// 消耗余额
$user_money = $user_wallets[$order['user_id']]->$expend_type;
break;
case LuckyGroupEnum::AWARD_TYPE_SCORE:
// 消耗积分
$user_money = $user_wallets[$order['user_id']]->$expend_type;
break;
default:
}
//判断积分、余额、货币是否足够
if ($is_can_continue === false || $user_money < $expend_num) throw new Exception('拼团消耗不足');
//参团消耗扣减
if (in_array($expend_type, [LuckyGroupEnum::AWARD_TYPE_BALANCE, LuckyGroupEnum::AWARD_TYPE_SCORE])) {
//积分余额消耗
if ($expend_num > 0) {
$expend_name = '';
if ($expend_type == LuckyGroupEnum::AWARD_TYPE_BALANCE) {
$expend_name = '余额';
$deplete_balances += $expend_num;
}
if ($expend_type == LuckyGroupEnum::AWARD_TYPE_SCORE) {
$expend_name = '积分';
$deplete_scores += $expend_num;
}
$desc = ($group_buy_order_text ?? '幸运拼团订单') . '(' . $order['id'] . ')' . ($join_into_team_text ?? '参团') . '成功,扣减' . $expend_name . $expend_num;
$data = [
'message_id' => 0,
'not_add_total' => true,
'mall_id' => $order['mall_id'], 'user_id' => $order['user_id'],
'is_frozen' => false,
'wallet_type' => $expend_type,
'money' => -$expend_num,
'desc' => $desc,
'source_table' => $extension['source_table'] ?? '',
'source_table_id' => $extension['source_table_id'] ?? 0,
'from_type' => LuckyGroupEnum::ADDONS_NAME,
'capital_type' => UserWalletEnum::LUCKY_GROUP_CONSUME,
];
$res = UserWalletService::handle(0, $data);
if ($res == false) {
$desc = ($group_buy_order_text ?? '幸运拼团订单') . ($join_into_team_text ?? '参团') . '扣减' . $expend_name . '失败';
throw new Exception($desc);
}
}
}
}
return true;
} catch (\Exception $e) {
$order->group_status = 3;
$this->refundToBalance($order, $e->getMessage());
return false;
}
}
//更新参团次数
public function updateGroupGoodsJoinNum($activity_id, $goods_id, $attend_order_num)
{
$lucky_group_goods = LuckyGroupGoods::findOne(['activity_id' => $activity_id, 'goods_id' => $goods_id]);
if(!$lucky_group_goods) throw new \Exception('activity_id:'.$activity_id.',goods_id:'.$goods_id.' not exist');
$open_times = $lucky_group_goods->open_times;
$lucky_group_goods->open_times++;
$lucky_group_goods->join_num = $lucky_group_goods->join_num + $attend_order_num;
$res = $lucky_group_goods->save();
if ($res == false) throw new Exception($lucky_group_goods->getErrorMessage());
return $open_times;
}
public function refundToBalance($order, $desc = '', $wallet_type = 'balance')
{
// 开启事务
$transaction = \Yii::$app->db->beginTransaction();
$single_prize = bcdiv($order['total_pay_price'], $order['buy_nums'], 2) + 0;
$refund_money = ($order['buy_nums'] - $order['win_nums']) * $single_prize; // 退款金额
if ($refund_money <= 0) {
\Yii::$app->custom->logs('退款金额小于等于0不进行退款', $order['order_no']);
return true;
}
try {
// 查看当前订单是否存在售后表中
$refund = OrderRefund::find()->where(['order_no' => $order['order_no'], 'status' => StatusEnum::ENABLED])->exists();
if ($refund) {
\Yii::$app->custom->logs('幸运拼团退款订单已存在', $order['order_no']);
return true;
}
// 不存在则创建退款订单
$refundModel = new OrderRefund();
$refundModel->mall_id = $order['mall_id'];
$refundModel->user_id = $order['user_id'];
$refundModel->order_id = $order['id'];
$refundModel->order_no = $order['order_no'];
$refundModel->type = 1;
$refundModel->reason = '幸运拼团失败退款';
$refundModel->refund_price = $refund_money;
$refundModel->reality_refund_price = $refund_money;
$refundModel->refund_at = time();
$refundModel->num = ($order['buy_nums'] - $order['win_nums']);
$refundModel->step_status = RefundStatusEnum::STEP_6;
$refundModel->refund_status = RefundStatusEnum::FINISH;
$res = $refundModel->save();
if (!$res) {
\Yii::$app->custom->logs('课程退款订单创建失败', OrderRefund::getStaticError());
return true;
}
// 查询支付单号
$trade_id = PaymentTradeOrder::find()->where(['order_no' => $order['order_no'], 'order_type' => PaymentTradeOrderEnum::LUCKY_GROUP_BUY_ORDER])
->select('trade_id')->scalar();
if (empty($trade_id)) {
\Yii::$app->custom->logs('课程退款订单不存在', $order['order_no']);
return true;
}
$payment_trade = PaymentTrade::findOne(['id' => $trade_id]);
$list = PaymentTrade::find()->where(['id' => $trade_id, 'is_pay' => 1])->all();
if ($payment_trade->isMixedPay()) { // 组合支付退款
$list = PaymentTradeItem::find()->where(['trade_id' => $trade_id, 'is_pay' => 1])->all();
}
$insert_wallet = [];
$params = [
'id' => $refundModel->id,
'step_status' => RefundStatusEnum::STEP_6
];
foreach ($list as $item) {
if (in_array($item->pay_type, [PayTypeEnum::BALANCE, PayTypeEnum::SCORE])) { // 余额-积分退款
$wallet_type = $item->pay_type == PayTypeEnum::SCORE ? UserWalletService::WALLET_TYPE_SCORE : UserWalletService::WALLET_TYPE_BALANCE;
$insert_wallet [] = [
'mall_id' => $order['mall_id'],
'user_id' => $order['user_id'],
'is_frozen' => false,
'wallet_type' => $wallet_type,
'money' => $item->pay_fee,
'desc' => $desc,
'source_table' => LuckyGroupOrder::tableName(),
'source_table_id' => $order['id'],
'from_type' => LuckyGroupEnum::ADDONS_NAME,
'capital_type' => UserWalletEnum::REFUND_ORDER,
];
} elseif(in_array($item->pay_type,[PayTypeEnum::JOINPAY,PayTypeEnum::ALI,PayTypeEnum::JOINPAY_FAST_PAY,PayTypeEnum::WECHAT,PayTypeEnum::SANDPAY_FAST_PAY])) {
// 退款原路退款
$res = \Yii::$app->services->pay->refund(
$item->pay_fee,
$item->pay_fee,
$payment_trade->out_trade_no,
$order,
'幸运拼团订单退款',
'',
'',
$item->pay_type
);
if ($res === false) {
\Yii::$app->custom->logs('幸运拼团综合订单退款失败', $order['order_no']);
return true;
};
} elseif ($res = GlobalInvoke::exec(GlobalInvoke::INVOKE_ORDER_REFUND, $order['mall_id'], [
'id' => $refundModel->id,
'mall_id' => $refundModel->mall_id,
'refund' => $refundModel,
'params' => $params,
'order_no' => $order['order_no'],
'refund_order_no' => $refundModel->order_no,
'payment_trade_id' => $payment_trade->id,
'refund_price' => $item->pay_fee,
'order_type' => 'LuckyGroup',
'pay_type' => $item->pay_type,
])) {
list($boolean, $msg) = $res;
if (!$boolean) {
\Yii::$app->custom->logs('幸运拼团退款订单退款失败', $msg);
return true;
}
} else {
\Yii::$app->custom->logs('幸运拼团退款订单退款失败', '不存在退款方式');
return true;
}
}
$payment_trade->setRefund($refundModel->id);
LuckyGroupWinLog::setData(['mall_id'=>$order['mall_id'],'user_id'=>$order['user_id'],'activity_id'=>$order['activity_id'],'win_num'=>0]);
$order->save();
$transaction->commit();
if (!empty($insert_wallet)) {
UserWalletService::batchHandleByQueue($insert_wallet);
}
} catch (\Exception $e) {
$transaction->rollBack();
\Yii::$app->custom->logs('幸运拼团退款订单退款失败', $e->getMessage());
}
return true;
}
//创建主订单
/**
* @desc:生成主订单
* @Author: hua
* @Date: 2022/3/28
* @Time: 10:47
* @Copyright: copyright (c) 2021 广东七件事集团
* @param $lucky_group_order
* @param $pay_order_list
* @param $pay_trade_list
* @param $user_address_arr
* @param $goods
* @param $goods_attr
* @return int
* @throws Exception
*/
public static function createMallOrder($lucky_group_order, $pay_order_list, $pay_trade_list, $user_address_arr, $goods, $goods_attr)
{
$t = \Yii::$app->db->beginTransaction();
try {
$new_goods_attr = GoodsAttr::findOne(['id' => $lucky_group_order->goods_attr_id]);
$trade_id = $pay_order_list[$lucky_group_order['order_no']]['trade_id'];
$out_trade_no = $pay_trade_list[$trade_id]['out_trade_no'];
$user_address = $user_address_arr[$lucky_group_order['user_id']];
$order = new Order();
$order->loadDefaultValues();
$order->mall_id = $lucky_group_order['mall_id'];
$order->mch_id = $goods['mch_id'];
$order->user_id = $lucky_group_order['user_id'];
$order->order_no = StringHelper::generateOrderNo('s');
$order->out_trade_no = $out_trade_no;
$order->mobile = $user_address['mobile'] ?? '';
if ($user_address) {
$order->province = $user_address['province_id'];
$order->city = $user_address['city_id'];
$order->area = $user_address['district_id'];
$order->town = $user_address['town_id'];
$order->address = $user_address['detail'];
$order->region_name = $user_address['province'] . $user_address['city'] . $user_address['district'] . $user_address['town'];
$order->receiver_name = $user_address['name'];
}
$order->remark = $lucky_group_order['remark'];
$order->shipping_type = ShippingTypeEnum::LOGISTICS;
$order->shipping_money = $lucky_group_order['shipping_money'];
$order->pay_money = $lucky_group_order['total_pay_price'];
$order->goods_price = $lucky_group_order['total_goods_price'] / $lucky_group_order['buy_nums'];
$order->original_goods_price = $lucky_group_order['total_goods_original_price'] / $lucky_group_order['buy_nums'];
$order->order_status = OrderStatusEnum::PAY;
$order->marketing_id = $lucky_group_order['id'];
$order->marketing_type = LuckyGroupEnum::ADDONS_NAME;
$order->pay_status = OrderStatusEnum::PAY;
$order->extra_info = $lucky_group_order['major_data'];
$order->payment_type = $lucky_group_order['payment_type'];
$order->pay_time = $lucky_group_order['pay_at'];
$order->score = 0;
$res = $order->save();
if ($res == false) throw new \Exception($order->getErrorMessage());
$res = self::createMallOrderDetail($lucky_group_order, $order, $goods, $new_goods_attr);
if ($res == false) throw new \Exception('创建主订单详情失败');
if ($new_goods_attr->stock <= 0) throw new \Exception('库存不足');
$new_goods_attr->stock--;
$res = $new_goods_attr->save();
if ($res == false) throw new \Exception($new_goods_attr->getErrorMessage());
if ($goods->stock <= 0) throw new \Exception('库存不足');
$goods->stock--;
$goods->sales_num++;
$res = $goods->save();
if ($res == false) throw new \Exception($goods->getErrorMessage());
$t->commit();
return $order;
} catch (\Exception $e) {
$t->rollBack();
var_dump($e->getMessage().$e->getFile().$e->getLine());
return false;
}
}
/**
* @desc:生成主订单详情
* @Author: hua
* @Date: 2021/12/16
* @Time: 14:32
* @Copyright: copyright (c) 2021 广东七件事集团
* @param $lucky_group_order
* @param $order
* @param $goods
* @param $goods_attr
* @param $marketing_type
* @throws Exception
*/
protected static function createMallOrderDetail($lucky_group_order, $order, $goods, $goods_attr)
{
// 因为主订单生成并且触发了订单支付事件。订单详情还没生成所以需要关联下
try {
// 订单详情
$order_detail = new OrderDetail();
$order_detail->loadDefaultValues();
$order_detail->user_id = $lucky_group_order->user_id;
$order_detail->mall_id = $lucky_group_order->mall_id;
$order_detail->mch_id = $order->mch_id;
$order_detail->order_id = $order->id;
$order_detail->goods_id = $lucky_group_order->goods_id;
$order_detail->goods_attr_id = $lucky_group_order->goods_attr_id;
if ($goods) {
$order_detail->goods_name = $goods->goods_name;
//$order_detail->is_virtual = $goods->goods_type;
$order_detail->is_virtual = $goods->goods_type == GoodsTypeEnum::GoodsTypeVirtual ? 1 : 0;
}
if ($goods_attr) {
$order_detail->goods_attr_name = $goods_attr->name ?? '';
$order_detail->price = $goods_attr->price;
$order_detail->cost_price = $goods_attr->cost_price;
$order_detail->original_goods_price = $goods_attr->original_price;
$order_detail->pic_url = $goods_attr->pic_url ? $goods_attr->pic_url : $goods->cover_pic;
}
$order_detail->goods_price = $lucky_group_order['total_goods_price'] / $lucky_group_order['buy_nums'];
$order_detail->goods_price = $lucky_group_order['total_goods_price'] / $lucky_group_order['buy_nums'];
$order_detail->num = 1;
$order_detail->marketing_id = $lucky_group_order->id;
$order_detail->marketing_type = LuckyGroupEnum::ADDONS_NAME;
$order_detail->order_status = OrderStatusEnum::PAY;
$order_detail->remark = $lucky_group_order->remark;
$res = $order_detail->save();
if ($res == false) throw new \Exception('拼中生成订单详情失败');
return $res;
} catch (\Exception $e) {
\Yii::$app->custom->logs('幸运拼团生成订单详情失败');
return false;
}
}
//获取上级数据
protected static function getUserParentList($user_id_arr)
{
$user_relation_list = UserPartitionRelationship::lists(['where' => [['user_id' => $user_id_arr]], 'order' => 'part asc']);
$data = [];
foreach ($user_relation_list as $key => $value) {
if (isset($data[$value['user_id']])) {
$data[$value['user_id']] = array_merge($data[$value['user_id']], explode(',', $value['tree']));
} else {
$data[$value['user_id']] = explode(',', $value['tree']);
}
}
return $data;
}
//获取等级数据
protected static function getLevelConfig($activity)
{
$config_arr = [];
$mall_id = $activity['mall_id'];
if (!empty($activity['enable_commison'])) {
$team_commission_setting = json_decode($activity['team_commission_setting'], true);
$equal_commission_setting = json_decode($activity['equal_commission_setting'], true);
$over_commission_setting = json_decode($activity['over_commission_setting'], true);
foreach ($team_commission_setting as $item) {
$config_arr[$item['level']]['is_percent_team'] = 0;
$config_arr[$item['level']]['agent_team_prize'] = $item['team_commission'];
}
foreach ($equal_commission_setting as $item) {
$config_arr[$item['level']]['is_percent_equal'] = 0;
$config_arr[$item['level']]['agent_equal_prize'] = $item['equal_commission'];
}
foreach ($over_commission_setting as $item) {
$config_arr[$item['level']]['is_percent_over'] = 0;
$config_arr[$item['level']]['agent_over_prize'] = $item['over_commission'];
}
} else {
$level_list = LuckyGroupLevel::lists(['where' => [['mall_id' => $mall_id], ['status' => StatusEnum::ENABLED]]]);
foreach ($level_list as $item) {
$config_arr[$item['level']]['is_percent_team'] = 0;
$config_arr[$item['level']]['agent_team_prize'] = $item['team_commission'];
$config_arr[$item['level']]['is_percent_equal'] = 0;
$config_arr[$item['level']]['agent_equal_prize'] = $item['equal_commission'];
$config_arr[$item['level']]['is_percent_over'] = 0;
$config_arr[$item['level']]['agent_over_prize'] = $item['over_commission'];
}
}
return $config_arr;
}
//禁用活动
public function disableActivity($order_ids)
{
$joining_orders = LuckyGroupOrder::find()
->where(['id' => $order_ids, 'group_status' => 1])
->andWhere(new \yii\db\Expression('`buy_nums` > `win_nums`'))
->indexBy('id')
->all();
foreach ($joining_orders as $key => $order) {
$user_arr[$order['user_id']]['order_id'] = $order['id'];
$order->group_status = 3;
$this->refundToBalance($order, '禁用活动');
}
}
}