2996 lines
126 KiB
PHP
Executable File
2996 lines
126 KiB
PHP
Executable File
<?php
|
||
declare(strict_types=1);
|
||
|
||
namespace app\api\controller;
|
||
|
||
use app\common\model\CardLevel;
|
||
use app\common\model\Goods;
|
||
use app\common\model\GoodsList;
|
||
use app\common\model\GoodsLock;
|
||
use app\common\model\ItemCard;
|
||
use app\common\model\Order;
|
||
use app\common\model\OrderList;
|
||
use app\common\model\OrderListSend;
|
||
use app\common\model\OrderSale;
|
||
use app\common\model\ProductOrder;
|
||
use app\common\model\ProductOrderList;
|
||
use app\common\model\ProfitPay;
|
||
use app\common\model\Shang;
|
||
use app\common\model\User;
|
||
use app\common\model\UserLevelCoupon;
|
||
use app\common\model\UserRecharge;
|
||
use app\common\model\Ads;
|
||
use think\facade\Db;
|
||
use think\facade\Request;
|
||
use app\common\model\CouponReceive as CouponReceiveModel;
|
||
|
||
use app\common\helper\ConfigHelper;
|
||
use app\common\service\RewardService;
|
||
/**
|
||
* Class Notify 同步处理
|
||
* @package app\index\controller
|
||
*/
|
||
class Notify extends Base
|
||
{
|
||
static $shang_prize_id = [10, 33];#抽奖赏品id
|
||
static $shang_give_first_id = 1;#赠送(FIRST赏)赏品id
|
||
static $shang_give_arr = [2, 3, 4];#赠送(LAST赏 最终赏 全局赏)赏品id
|
||
static $shang_give_w_id = 4;#赠送(全局赏)赏品id
|
||
static $shang_give_quan_id = 5;#赠送(拳王赏)赏品id
|
||
static $secretKey = null;
|
||
static $secretKeyAccount = null;
|
||
|
||
public function initialize()
|
||
{
|
||
// 获取微信支付配置
|
||
$wxpayConfig = \app\common\helper\WxPayHelper::getWxPayConfig();
|
||
$merchant = $wxpayConfig['merchant'];
|
||
|
||
// 使用随机商户的密钥
|
||
static::$secretKey = $merchant['keys'];
|
||
|
||
// 获取公众号密钥
|
||
static::$secretKeyAccount = getConfig('wechatofficialaccount')['keys'];
|
||
}
|
||
|
||
public function ceshi()
|
||
{
|
||
$order['goods_id'] = 18;
|
||
$order['num'] = 1;
|
||
$order['order_type'] = 3;
|
||
// dd(11);
|
||
$this->quan_prize_notice($order);
|
||
}
|
||
|
||
/**
|
||
* 特殊奖品开奖 拳王赏
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function quan_prize_notice($order)
|
||
{
|
||
$res = [];
|
||
$goods_id = $order['goods_id'];
|
||
$num = $order['num'];
|
||
$order_type = $order['order_type'];
|
||
#盒子
|
||
$goods_info = Goods::field('prize_num,stock')->where(['id' => $goods_id])->find();
|
||
#特殊奖品存在where('goods_id', '=', $goods_id)
|
||
$special_prize = GoodsList::where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('surplus_stock', '>', 0)
|
||
->where('shang_id', '=', self::$shang_give_quan_id)
|
||
->order('prize_num desc')
|
||
->select();
|
||
// dd($special_prize);
|
||
$user_ids = [];
|
||
foreach ($special_prize as $value) {
|
||
$surplus_give_stock = $value ? $value['surplus_stock'] : 0;
|
||
if ($value && $surplus_give_stock > 0) {
|
||
|
||
#符合条件的订单
|
||
$quan_prize_num = $value['prize_num'];
|
||
// dd($quan_prize_num);
|
||
// var_dump($quan_prize_num);
|
||
$prize_num_data = OrderList::field('id,user_id,count(`id`) as all_num')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('order_type', '=', $order_type)
|
||
->where('shang_id', '=', self::$shang_give_w_id)
|
||
->having('all_num', '>=', $quan_prize_num)
|
||
->group('user_id')
|
||
->select()->toArray();
|
||
|
||
$prize_num_data_arr = [];
|
||
foreach ($prize_num_data as $val) {
|
||
if ($val['all_num'] >= $quan_prize_num && !in_array($val['user_id'], $user_ids)) {
|
||
$prize_num_data_arr[] = $val;
|
||
}
|
||
}
|
||
// dd($prize_num_data_arr);
|
||
if ($prize_num_data_arr) {
|
||
// dd($prize_num_data);
|
||
#多个随机
|
||
shuffle($prize_num_data_arr);
|
||
|
||
$quan_prize_info = $prize_num_data_arr[0];
|
||
|
||
$user_id = $quan_prize_info['user_id'];
|
||
$user_ids[] = $quan_prize_info['user_id'];
|
||
|
||
$order_goods = [
|
||
'order_id' => 0,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => $num,
|
||
'shang_id' => $value['shang_id'],
|
||
'goodslist_id' => $value['id'],
|
||
'goodslist_title' => $value['title'],
|
||
'goodslist_imgurl' => $value['imgurl'],
|
||
'goodslist_price' => $value['price'],
|
||
'goodslist_money' => $value['money'],
|
||
'goodslist_type' => $value['goods_type'],
|
||
'goodslist_sale_time' => $value['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $value['prize_code'],
|
||
'order_type' => $order_type,
|
||
'order_list_id' => 0,
|
||
];
|
||
// var_dump($order_goods);
|
||
#新增奖品列表
|
||
$res[] = OrderList::insert($order_goods);
|
||
|
||
#减少库存
|
||
$res[] = GoodsList::field('surplus_stock')
|
||
->where(['id' => $value['id']])
|
||
->dec('surplus_stock')
|
||
->update();
|
||
// var_dump($res);
|
||
}
|
||
}
|
||
|
||
}
|
||
#赏品
|
||
$goods_list_zd = GoodsList::where(['goods_id' => $goods_id])
|
||
->where(['num' => 1])
|
||
->select()->toArray();
|
||
if ($goods_list_zd) {
|
||
#循环数据
|
||
$save_sports_data = [];
|
||
$start_num = $goods_info['stock'] + 1;
|
||
for ($i = $start_num; $i <= $start_num; $i++) {
|
||
foreach ($goods_list_zd as $k => $v) {
|
||
unset($v['id']);
|
||
unset($v['num']);
|
||
$v['num'] = $i;
|
||
$v['surplus_stock'] = $v['stock'];
|
||
$save_sports_data[] = $v;
|
||
}
|
||
}
|
||
#添加赏品
|
||
$res[] = GoodsList::insertAll($save_sports_data);
|
||
#增加库存
|
||
$res[] = Goods::where(['id' => $goods_id])->inc('stock', 1)->update();
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
*
|
||
* 获取支付结果通知数据
|
||
* return array
|
||
*/
|
||
public function order_notify()
|
||
{
|
||
#获取通知的数据
|
||
$xml = file_get_contents("php://input");
|
||
if (empty($xml)) {
|
||
return false;
|
||
}
|
||
#转成数组
|
||
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
||
$sign = $data['sign'];
|
||
unset($data['sign']);
|
||
$newSign = $this->MakeSign($data);
|
||
$newSignAccount = $this->MakeSignAccount($data);
|
||
#验证签名
|
||
if ($sign == $newSign || $sign == $newSignAccount) {
|
||
//如果成功返回了
|
||
if ($data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS') {
|
||
$user = User::where('openid', $data['openid'])->find();
|
||
try {
|
||
// 使用profit_pay表记录支付信息,而不是wxpay_log表
|
||
Db::name('profit_pay')->insert([
|
||
'user_id' => $user['id'],
|
||
'order_num' => $data['out_trade_no'],
|
||
'change_money' => isset($data['total_fee']) ? ($data['total_fee'] / 100) : 0,
|
||
'content' => $data['attach'] ? $data['attach'] : '微信支付',
|
||
'pay_type' => 1, // 1微信 2支付宝
|
||
'addtime' => time(),
|
||
]);
|
||
} catch (\Throwable $e) {
|
||
$this->CallbackSuccess();
|
||
}
|
||
$out_trade_no = $data['out_trade_no'];//订单号
|
||
$table = $data['attach'];#表名
|
||
if ($table == 'user_recharge') {#余额充值
|
||
$orderInfo = UserRecharge::where('order_num', '=', $out_trade_no)
|
||
->where(['status' => 1])
|
||
->find();
|
||
#这个订单存在状态对
|
||
if ($orderInfo && $orderInfo['status'] == 1) {
|
||
$user_id = $orderInfo['user_id'];
|
||
$money = $orderInfo['money'];
|
||
Db::startTrans();
|
||
#修改订单状态
|
||
$res[] = UserRecharge::field('status,pay_time')
|
||
->where(['id' => $orderInfo['id']])->update([
|
||
'status' => 2,
|
||
'pay_time' => time(),
|
||
]);
|
||
$res[] = User::changeMoney($user_id, $money, 2, '在线充值');
|
||
#记录微信支付
|
||
$res[] = ProfitPay::insert([
|
||
'user_id' => $user_id,
|
||
'order_num' => $out_trade_no,
|
||
'change_money' => $money,
|
||
'content' => '微信支付',
|
||
'pay_type' => 1,#1微信 2支付宝
|
||
'addtime' => time(),
|
||
]);
|
||
if (resCheck($res)) {
|
||
Db::commit();
|
||
} else {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
} elseif ($table == 'order_yfs' || $table == 'order_lts' || $table == 'order_zzs' || $table == 'order_flw' || $table == 'order_scs') {#抽赏一番赏 擂台赏
|
||
$orderInfo = Order::where('order_num', '=', $out_trade_no)
|
||
->where('status', '=', 0)
|
||
->find();
|
||
#这个订单存在状态对
|
||
if ($orderInfo && $orderInfo['status'] == 0) {
|
||
$user_id = $orderInfo['user_id'];
|
||
$price = $orderInfo['price'];
|
||
Db::startTrans();
|
||
try {
|
||
#开盒子
|
||
$res[] = $this->drawprize_notice($user_id, $orderInfo['id'], $orderInfo['goods_id'], $orderInfo['num']);
|
||
|
||
$this->wx_gf_fahuo($user_id, $orderInfo['order_num']);
|
||
#广告收益回调
|
||
if (!empty($orderInfo['click_id']) && !empty($orderInfo['ad_id'])) {
|
||
$order_ad_num = Order::where('user_id', '=', $user_id)->where('status', '=', 1)->where('ad_id', '>', 0)->where('click_id', '>', 0)->where('price', '>', 0)->count();
|
||
if ($order_ad_num <= 1) {
|
||
|
||
$this->ad_notify($orderInfo['ad_id'], $orderInfo['click_id']);
|
||
|
||
}
|
||
|
||
}
|
||
} catch (\Throwable $e) {
|
||
Db::rollback();
|
||
#卡单了
|
||
Order::field('kd_is')->where(['id' => $orderInfo['id']])
|
||
->update(['kd_is' => 1]);
|
||
#通知微信
|
||
$this->CallbackSuccess();
|
||
}
|
||
#记录微信支付
|
||
$res[] = ProfitPay::insert([
|
||
'user_id' => $user_id,
|
||
'order_num' => $out_trade_no,
|
||
'change_money' => $price,
|
||
'content' => '购买盒子' . $orderInfo['goods_title'],
|
||
'pay_type' => 1,#1微信 2支付宝
|
||
'addtime' => time(),
|
||
]);
|
||
if (resCheck($res)) {
|
||
Db::commit();
|
||
} else {
|
||
Db::rollback();
|
||
}
|
||
} else {
|
||
$tempOrder = Order::where('order_num', '=', $out_trade_no)
|
||
->find();
|
||
if ($tempOrder) {
|
||
// 作废订单支付
|
||
$tempOrder->status = 3;
|
||
$tempOrder->save();
|
||
}
|
||
}
|
||
} elseif ($table == 'order_wxs' || $table == 'order_fbs') {#抽赏无限赏
|
||
$orderInfo = Order::where('order_num', '=', $out_trade_no)
|
||
->where('status', '=', 0)
|
||
->find();
|
||
#这个订单存在状态对
|
||
if ($orderInfo && $orderInfo['status'] == 0) {
|
||
$user_id = $orderInfo['user_id'];
|
||
$price = $orderInfo['price'];
|
||
Db::startTrans();
|
||
$res[] = $this->infinite_drawprize_notice($user_id, $orderInfo['id'], $orderInfo['goods_id']);
|
||
#记录微信支付
|
||
$res[] = ProfitPay::insert([
|
||
'user_id' => $user_id,
|
||
'order_num' => $out_trade_no,
|
||
'change_money' => $price,
|
||
'content' => '购买盒子' . $orderInfo['goods_title'],
|
||
'pay_type' => 1,#1微信 2支付宝
|
||
'addtime' => time(),
|
||
]);
|
||
|
||
$this->wx_gf_fahuo($user_id, $orderInfo['order_num']);
|
||
#广告收益回调
|
||
if (!empty($orderInfo['click_id']) && !empty($orderInfo['ad_id'])) {
|
||
$order_ad_num = Order::where('user_id', '=', $user_id)->where('status', '=', 1)->where('ad_id', '>', 0)->where('click_id', '>', 0)->where('price', '>', 0)->count();
|
||
if ($order_ad_num <= 1) {
|
||
$this->ad_notify($orderInfo['ad_id'], $orderInfo['click_id']);
|
||
}
|
||
|
||
|
||
}
|
||
if (resCheck($res)) {
|
||
Db::commit();
|
||
} else {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
} elseif ($table == 'order_ckj') {#抽赏抽卡机
|
||
$orderInfo = Order::where('order_num', '=', $out_trade_no)
|
||
->where('status', '=', 0)
|
||
->where('order_type', '=', 4)
|
||
->find();
|
||
#这个订单存在状态对
|
||
if ($orderInfo && $orderInfo['status'] == 0) {
|
||
$user_id = $orderInfo['user_id'];
|
||
$price = $orderInfo['price'];
|
||
Db::startTrans();
|
||
$res[] = $this->cardextractor_drawprize_notice($user_id, $orderInfo['id'], $orderInfo['goods_id']);
|
||
#记录微信支付
|
||
$res[] = ProfitPay::insert([
|
||
'user_id' => $user_id,
|
||
'order_num' => $out_trade_no,
|
||
'change_money' => $price,
|
||
'content' => '购买盒子' . $orderInfo['goods_title'],
|
||
'pay_type' => 1,#1微信 2支付宝
|
||
'addtime' => time(),
|
||
]);
|
||
|
||
$this->wx_gf_fahuo($user_id, $orderInfo['order_num']);
|
||
|
||
if (resCheck($res)) {
|
||
Db::commit();
|
||
} else {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
} elseif ($table == 'order_list_send') {#背包发货
|
||
$orderInfo = OrderListSend::where('send_num', '=', $out_trade_no)
|
||
->where('status', '=', 0)
|
||
->find();
|
||
#这个订单存在状态对
|
||
if ($orderInfo && $orderInfo['status'] == 0) {
|
||
$user_id = $orderInfo['user_id'];
|
||
$freight = $orderInfo['freight'];
|
||
Db::startTrans();
|
||
$res[] = $this->reward_order_handle($user_id, $orderInfo['id']);
|
||
#记录微信支付
|
||
$res[] = ProfitPay::insert([
|
||
'user_id' => $user_id,
|
||
'order_num' => $out_trade_no,
|
||
'change_money' => $freight,
|
||
'content' => '背包发货',
|
||
'pay_type' => 1,#1微信 2支付宝
|
||
'addtime' => time(),
|
||
]);
|
||
|
||
$this->wx_gf_fahuo($user_id, $orderInfo['order_num']);
|
||
|
||
if (resCheck($res)) {
|
||
Db::commit();
|
||
} else {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
} elseif ($table == 'order_js') {
|
||
|
||
}
|
||
}
|
||
}
|
||
$this->CallbackSuccess();
|
||
}
|
||
|
||
/*
|
||
广告推广
|
||
*/
|
||
public function ad_notify($ads_id, $click_id)
|
||
{
|
||
$tencent_ad = Ads::where('id', $ads_id)->find();
|
||
if (!empty($tencent_ad)) {
|
||
$result = tencent_ad_attribution($click_id, 1, $tencent_ad['account_id'], $tencent_ad['access_token'], $tencent_ad['user_action_set_id']);
|
||
dump($result);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 生成签名
|
||
* @return 签名
|
||
*/
|
||
public function MakeSign($params)
|
||
{
|
||
//签名步骤一:按字典序排序数组参数
|
||
ksort($params);
|
||
$string = $this->ToUrlParams($params);
|
||
//签名步骤二:在string后加入KEY
|
||
$string = $string . "&key=" . static::$secretKey;
|
||
//签名步骤三:MD5加密
|
||
$string = md5($string);
|
||
//签名步骤四:所有字符转为大写
|
||
$result = strtoupper($string);
|
||
return $result;
|
||
}
|
||
|
||
|
||
/**
|
||
* 生成签名
|
||
* @return 签名
|
||
*/
|
||
public function MakeSignAccount($params)
|
||
{
|
||
//签名步骤一:按字典序排序数组参数
|
||
ksort($params);
|
||
$string = $this->ToUrlParams($params);
|
||
//签名步骤二:在string后加入KEY
|
||
$string = $string . "&key=" . static::$secretKeyAccount;
|
||
//签名步骤三:MD5加密
|
||
$string = md5($string);
|
||
//签名步骤四:所有字符转为大写
|
||
$result = strtoupper($string);
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 将参数拼接为url: key=value&key=value
|
||
* @param $params
|
||
* @return string
|
||
*/
|
||
public function ToUrlParams($params)
|
||
{
|
||
$string = '';
|
||
if (!empty($params)) {
|
||
$array = array();
|
||
foreach ($params as $key => $value) {
|
||
$array[] = $key . '=' . $value;
|
||
}
|
||
$string = implode("&", $array);
|
||
}
|
||
return $string;
|
||
}
|
||
|
||
/**
|
||
* 接收通知成功后应答输出XML数据
|
||
* @param string $xml
|
||
*/
|
||
public function CallbackSuccess()
|
||
{
|
||
exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
|
||
}
|
||
|
||
/**
|
||
* 接收通知成功后应答输出XML数据
|
||
* @param string $xml
|
||
*/
|
||
public function CallbackSuccess_new($payment_type)
|
||
{
|
||
if ($payment_type == "zfbpay") {
|
||
exit('success');
|
||
} else {
|
||
exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 抽赏开始抽赏======================================================
|
||
* @param int $user_id 会员id
|
||
* @param int $order_id 订单ID
|
||
* @param int $goods_id 盒子id
|
||
* @param int $num 盒子箱号
|
||
*/
|
||
public function drawprize_notice($user_id = 0, $order_id = 0, $goods_id = 0, $num = 0)
|
||
{
|
||
$res = [];
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => $num])
|
||
->where(['status' => 0])
|
||
->where('order_type', 'in', [1, 3, 5, 6, 11, 15, 10])
|
||
->find();
|
||
|
||
if ($order) {
|
||
|
||
#改变状态
|
||
$res[] = Order::field('status,pay_time')
|
||
->where(['id' => $order['id']])
|
||
->update([
|
||
'status' => 1,
|
||
'pay_time' => time(),
|
||
]);
|
||
#扣余额
|
||
if ($order['use_money'] > 0) {
|
||
$res[] = User::changeMoney($order['user_id'], -$order['use_money'], 3, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#扣吧唧币
|
||
if ($order['use_integral'] > 0) {
|
||
$res[] = User::changeIntegral($order['user_id'], -$order['use_integral'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#扣积分
|
||
if ($order['use_score'] > 0) {
|
||
$res[] = User::changeScore($order['user_id'], -$order['use_score'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
# 扣货币2
|
||
if ($order['use_money2'] > 0) {
|
||
$res[] = User::changeMoney2($order['user_id'], -$order['use_money2'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#判断一下优惠券
|
||
if (!empty($order['coupon_id'])) {
|
||
$coupon = CouponReceiveModel::where(['id' => $order['coupon_id'], 'status' => 0])->update(['status' => 1]);
|
||
}
|
||
#分销奖励
|
||
$res[] = User::distribution($order);
|
||
#分销奖励
|
||
|
||
if ($order['order_type'] == 15) {
|
||
$res[] = $this->ordinary_prize_notice_flw($order);
|
||
} elseif ($order['order_type'] == 10) {
|
||
$res[] = $this->infinite_shangchengshang($order);
|
||
|
||
} else {
|
||
#普通奖品==========================================================
|
||
$res[] = $this->ordinary_prize_notice($order);
|
||
#普通奖品==========================================================
|
||
#判断是否发积分 发券
|
||
$res[] = User::is_integral_coupon($order);
|
||
//升级欧气值
|
||
if ($order['price'] > 0) {
|
||
User::ou_qi_level_up($order['user_id'], $order['price']);
|
||
}
|
||
|
||
|
||
#特殊奖品**********************************************************
|
||
#普通奖品余量信息
|
||
$goodslist = GoodsList::field('sum(`stock`) as stock, sum(`surplus_stock`) as surplus_stock')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('shang_id', 'between', self::$shang_prize_id)
|
||
->where('goods_list_id', '=', 0)
|
||
->find();
|
||
// var_dump($goodslist['surplus_stock']);
|
||
#普通赏销量数量
|
||
$sale_count = $goodslist['stock'] - $goodslist['surplus_stock'];
|
||
#普通奖品一半
|
||
$first_count = floor($goodslist['stock'] / 2);
|
||
#FIRST
|
||
if ($order['order_type'] != 3 && $sale_count >= $first_count) {
|
||
$res[] = $this->special_first_notice($order, $first_count);
|
||
}
|
||
#LAST赏 全局赏 拳王赏
|
||
if ($goodslist['surplus_stock'] <= 0) {
|
||
// var_dump($goodslist['surplus_stock']);
|
||
|
||
$res[] = $this->special_prize_notice($order, $first_count);
|
||
// var_dump($res);
|
||
#擂台赏
|
||
if ($order['order_type'] == 3) {
|
||
$res[] = $this->quan_prize_notice($order);
|
||
}
|
||
#增加盒子库存
|
||
$goods = Goods::field('id,stock,sale_stock')
|
||
->where(['id' => $goods_id])
|
||
->find();
|
||
$save_update = [];
|
||
$goods_sale_stock = $goods['sale_stock'] + 1;
|
||
if ($goods_sale_stock >= $goods['stock']) {
|
||
$save_update['status'] = 3;
|
||
}
|
||
$save_update['sale_stock'] = $goods_sale_stock;
|
||
$res[] = Goods::field('id,status,sale_stock')
|
||
->where(['id' => $goods_id])
|
||
->update($save_update);
|
||
}
|
||
}
|
||
#特殊奖品**********************************************************
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 普通奖品开奖
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function ordinary_prize_notice($order)
|
||
{
|
||
$user_id = $order['user_id'];
|
||
$order_id = $order['id'];
|
||
$goods_id = $order['goods_id'];
|
||
$num = $order['num'];
|
||
$order_type = $order['order_type'];
|
||
#抽奖数量
|
||
$prize_num = $order['prize_num'];
|
||
#普通奖品信息
|
||
$ordinary_prize = GoodsList::where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('shang_id', 'between', self::$shang_prize_id)
|
||
->where('goods_list_id', '=', 0)
|
||
->order('sort desc,shang_id asc')
|
||
->select()->toArray();
|
||
if (!$ordinary_prize) {
|
||
$res[] = 0;
|
||
return $res;
|
||
}
|
||
$res[] = $this->ordinary_prize_notice_box($ordinary_prize, $prize_num, $order_id, $user_id, $goods_id, $order_type, $num);
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 普通奖品开奖宝箱
|
||
* @param mixed $ordinary_prize
|
||
* @param mixed $prize_num
|
||
* @param mixed $order_id
|
||
* @param mixed $user_id
|
||
* @param mixed $goods_id
|
||
* @param mixed $order_type
|
||
* @param mixed $num
|
||
* @return array<array|GoodsList|int>
|
||
*/
|
||
protected function ordinary_prize_notice_box($ordinary_prize, $prize_num, $order_id, $user_id, $goods_id, $order_type, $num)
|
||
{
|
||
$res = [];
|
||
|
||
|
||
try {
|
||
// 过滤掉库存为0的奖品
|
||
$valid_prizes = array_filter($ordinary_prize, function ($item) {
|
||
return $item['surplus_stock'] > 0;
|
||
});
|
||
|
||
if (empty($valid_prizes)) {
|
||
return [0]; // 没有有效奖品
|
||
}
|
||
|
||
// 创建权重数组用于加权随机
|
||
$weights = [];
|
||
foreach ($valid_prizes as $index => $prize) {
|
||
$weights[$index] = $prize['surplus_stock'];
|
||
}
|
||
|
||
// 开普通奖品
|
||
for ($i = 0; $i < $prize_num; $i++) {
|
||
// 检查是否还有可抽奖品
|
||
if (empty($weights) || array_sum($weights) <= 0) {
|
||
break;
|
||
}
|
||
|
||
// 使用加权随机算法选择奖品
|
||
$selected_index = $this->weightedRandom($weights);
|
||
$ordinary_prize_info = $valid_prizes[$selected_index];
|
||
|
||
// 减少权重以反映库存变化
|
||
$weights[$selected_index]--;
|
||
|
||
// 如果权重为0,则从数组中移除
|
||
if ($weights[$selected_index] <= 0) {
|
||
unset($weights[$selected_index]);
|
||
unset($valid_prizes[$selected_index]);
|
||
}
|
||
|
||
$order_goods_info = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => $num,
|
||
'shang_id' => $ordinary_prize_info['shang_id'],
|
||
'goodslist_id' => $ordinary_prize_info['id'],
|
||
'goodslist_title' => $ordinary_prize_info['title'],
|
||
'goodslist_imgurl' => $ordinary_prize_info['imgurl'],
|
||
'goodslist_price' => $ordinary_prize_info['price'],
|
||
'goodslist_money' => $ordinary_prize_info['money'],
|
||
'goodslist_type' => $ordinary_prize_info['goods_type'],
|
||
'goodslist_sale_time' => $ordinary_prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => isset($ordinary_prize_info['prize_code']) ? $ordinary_prize_info['prize_code'] : '',
|
||
'order_type' => $order_type,
|
||
'parent_goods_list_id' => $ordinary_prize_info['goods_list_id'],
|
||
'source' => 1, // 标记来源为抽奖
|
||
];
|
||
|
||
// 插入订单商品记录
|
||
$res[] = OrderList::insert($order_goods_info);
|
||
|
||
// 减少库存
|
||
$res[] = GoodsList::where(['id' => $ordinary_prize_info['id']])
|
||
->dec('surplus_stock')
|
||
->update();
|
||
|
||
// 赠送货币
|
||
if (isset($ordinary_prize_info['doubling']) && $ordinary_prize_info['doubling'] > 1) {
|
||
$bei = $ordinary_prize_info['doubling'] - 1;
|
||
$change_money = $ordinary_prize_info['money'] * $bei * 100;
|
||
$res[] = User::changeIntegral($user_id, $change_money, 6, '抽中翻倍赏-' . $ordinary_prize_info['title'] . '赠送');
|
||
}
|
||
if (isset($ordinary_prize_info['reward_id']) && $ordinary_prize_info['reward_id'] != '') {
|
||
RewardService::sendReward($user_id, $ordinary_prize_info['reward_id'], '抽中' . $ordinary_prize_info['title']);
|
||
}
|
||
// RewardService::sendReward($user['user_id'], $prize['reward_id'], $goods_title . '开奖');
|
||
|
||
|
||
// 处理宝箱奖品
|
||
if ($ordinary_prize_info['goods_type'] == 4) {
|
||
// 查找宝箱奖品
|
||
$goodslist_1 = GoodsList::where(['goods_id' => $goods_id])
|
||
->where('goods_list_id', '=', $ordinary_prize_info['id'])
|
||
->select()->toArray();
|
||
|
||
if (!empty($goodslist_1)) {
|
||
$box_res = $this->ordinary_prize_notice_box($goodslist_1, 1, $order_id, $user_id, $goods_id, $order_type, $num);
|
||
$res = array_merge($res, $box_res);
|
||
}
|
||
}
|
||
}
|
||
|
||
return $res;
|
||
} catch (\Exception $e) {
|
||
// 记录错误日志
|
||
trace('抽奖异常: ' . $e->getMessage(), 'error');
|
||
// 抛出异常,让外层事务处理回滚
|
||
throw $e;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加权随机算法
|
||
* @param array $weights 权重数组
|
||
* @return int 选中的索引
|
||
*/
|
||
private function weightedRandom(array $weights)
|
||
{
|
||
$sum = array_sum($weights);
|
||
$rand = random_int(1, $sum);
|
||
|
||
foreach ($weights as $index => $weight) {
|
||
$rand -= $weight;
|
||
if ($rand <= 0) {
|
||
return $index;
|
||
}
|
||
}
|
||
|
||
return array_key_first($weights); // 防止浮点数精度问题导致无法选中
|
||
}
|
||
|
||
/**
|
||
* 福利屋购买
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function ordinary_prize_notice_flw($order)
|
||
{
|
||
$user_id = $order['user_id'];
|
||
$order_id = $order['id'];
|
||
$goods_id = $order['goods_id'];
|
||
$order_type = $order['order_type'];
|
||
$goods_price = $order['goods_price'];
|
||
#入库奖品
|
||
$save_order_goods = [];
|
||
#开普通奖品
|
||
$save_order_goods[] = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => 0,
|
||
'source' => 3,
|
||
'shang_id' => 0,
|
||
'goodslist_id' => 0,
|
||
'goodslist_title' => '',
|
||
'goodslist_imgurl' => '',
|
||
'goodslist_price' => $goods_price,
|
||
'goodslist_money' => 0,
|
||
'goodslist_type' => 3,
|
||
'goodslist_sale_time' => '',
|
||
'addtime' => time(),
|
||
'prize_code' => '',
|
||
'order_type' => $order_type,
|
||
];
|
||
if ($save_order_goods) {
|
||
#新增奖品列表
|
||
$res[] = OrderList::insertAll($save_order_goods);
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 特殊奖品开奖 FIRST
|
||
* @param $order 订单信息
|
||
* @param $first_count
|
||
*/
|
||
protected function special_first_notice($order, $first_count)
|
||
{
|
||
$res = [];
|
||
$goods_id = $order['goods_id'];
|
||
$num = $order['num'];
|
||
$order_type = $order['order_type'];
|
||
#特殊奖品存在
|
||
$special_prize = GoodsList::where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('surplus_stock', '>', 0)
|
||
->where('shang_id', '=', self::$shang_give_first_id)
|
||
->find();
|
||
#剩余数量
|
||
$surplus_give_stock = $special_prize ? $special_prize['surplus_stock'] : 0;
|
||
if ($special_prize && $surplus_give_stock > 0) {
|
||
#所有奖品信息
|
||
$all_order_list = OrderList::where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('order_type', '=', $order_type)
|
||
->where('shang_id', 'between', self::$shang_prize_id)
|
||
->order('id asc')
|
||
->limit((int) $first_count)
|
||
->select()->toArray();
|
||
shuffle($all_order_list);
|
||
shuffle($all_order_list);
|
||
$prize_info = $all_order_list[0];
|
||
$user_id = $prize_info['user_id'];
|
||
#特殊赏中奖订单id
|
||
$order_list_id = $prize_info['id'];
|
||
#中奖奖项
|
||
$order_goods = [
|
||
'order_id' => 0,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => $num,
|
||
'shang_id' => $special_prize['shang_id'],
|
||
'goodslist_id' => $special_prize['id'],
|
||
'goodslist_title' => $special_prize['title'],
|
||
'goodslist_imgurl' => $special_prize['imgurl'],
|
||
'goodslist_price' => $special_prize['price'],
|
||
'goodslist_money' => $special_prize['money'],
|
||
'goodslist_type' => $special_prize['goods_type'],
|
||
'goodslist_sale_time' => $special_prize['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $special_prize['prize_code'],
|
||
'order_type' => $order_type,
|
||
'order_list_id' => $order_list_id,
|
||
];
|
||
#增加销量
|
||
$res[] = GoodsList::field('surplus_stock')
|
||
->where(['id' => $special_prize['id']])
|
||
->dec('surplus_stock')
|
||
->update();
|
||
#新增奖品列表
|
||
$res[] = OrderList::insert($order_goods);
|
||
} else {
|
||
$res[] = 1;
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 特殊奖品开奖 LAST 最终赏 全局赏
|
||
* @param $order 订单信息
|
||
* @param $first_count
|
||
*/
|
||
protected function special_prize_notice($order, $first_count)
|
||
{
|
||
|
||
$res = [];
|
||
$goods_id = $order['goods_id'];
|
||
$num = $order['num'];
|
||
$order_type = $order['order_type'];
|
||
#特殊奖品存在
|
||
$special_prize = GoodsList::where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('surplus_stock', '>', 0)
|
||
->where('shang_id', 'in', self::$shang_give_arr)
|
||
->where('goods_list_id', '=', 0)
|
||
->select()->toArray();
|
||
$surplus_give_stock = $special_prize ? array_sum(array_column($special_prize, 'surplus_stock')) : 0;
|
||
if ($special_prize && $surplus_give_stock > 0) {
|
||
#所有奖品信息
|
||
$all_order_list = OrderList::field('id,user_id')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('order_type', '=', $order_type)
|
||
->where('shang_id', 'between', self::$shang_prize_id)
|
||
->order('id asc')
|
||
->select()->toArray();
|
||
$order_goods = [];
|
||
foreach ($special_prize as $k => $v) {
|
||
if ($v['shang_id'] == 4) {#全局赏
|
||
|
||
for ($surplus_stock_i = 0; $surplus_stock_i < $v['surplus_stock']; $surplus_stock_i++) {
|
||
$overall_order_list = $all_order_list;
|
||
shuffle($overall_order_list);
|
||
shuffle($overall_order_list);
|
||
$prize_info = $overall_order_list[0];
|
||
$user_id = $prize_info['user_id'];
|
||
#特殊赏中奖订单id
|
||
$order_list_id = $prize_info['id'];
|
||
#中奖奖项
|
||
$ordinary_prize_info = $v;
|
||
$order_goods_temp = [
|
||
'order_id' => 0,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => $num,
|
||
'shang_id' => $ordinary_prize_info['shang_id'],
|
||
'goodslist_id' => $ordinary_prize_info['id'],
|
||
'goodslist_title' => $ordinary_prize_info['title'],
|
||
'goodslist_imgurl' => $ordinary_prize_info['imgurl'],
|
||
'goodslist_price' => $ordinary_prize_info['price'],
|
||
'goodslist_money' => $ordinary_prize_info['money'],
|
||
'goodslist_type' => $ordinary_prize_info['goods_type'],
|
||
'goodslist_sale_time' => $ordinary_prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $ordinary_prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
'order_list_id' => $order_list_id,
|
||
'parent_goods_list_id' => $ordinary_prize_info['goods_list_id'],
|
||
];
|
||
$res[] = OrderList::insert($order_goods_temp);
|
||
#减少库存
|
||
$res[] = GoodsList::field('surplus_stock')
|
||
->where(['id' => $ordinary_prize_info['id']])
|
||
->dec('surplus_stock')
|
||
->update();
|
||
if (isset($ordinary_prize_info['reward_id']) && $ordinary_prize_info['reward_id'] != '') {
|
||
RewardService::sendReward($user_id, $ordinary_prize_info['reward_id'], '抽中' . $ordinary_prize_info['title']);
|
||
}
|
||
# 宝箱处理
|
||
if ($ordinary_prize_info['goods_type'] == 4) {
|
||
# 查找宝箱奖品
|
||
$goodslist_1 = GoodsList::where(['goods_id' => $goods_id])
|
||
->where('goods_list_id', '=', $ordinary_prize_info['id'])
|
||
->select()->toArray();
|
||
if ($goodslist_1) {
|
||
$res[] = $this->ordinary_prize_notice_box($goodslist_1, 1, 0, $user_id, $goods_id, $order_type, $num);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
if ($v['shang_id'] == 2) {#LAST赏
|
||
$last_order_list = array_slice($all_order_list, (int) $first_count);
|
||
shuffle($last_order_list);
|
||
shuffle($last_order_list);
|
||
$prize_info = $last_order_list[0];
|
||
#中奖用户id
|
||
$user_id = $prize_info['user_id'];
|
||
#特殊赏中奖订单id
|
||
$order_list_id = $prize_info['id'];
|
||
#中奖奖项
|
||
$ordinary_prize_info = $v;
|
||
} elseif ($v['shang_id'] == 3) {#最终赏
|
||
$end_order_list = $all_order_list;
|
||
$prize_info = end($end_order_list);
|
||
#中奖用户id
|
||
$user_id = $prize_info['user_id'];
|
||
#特殊赏中奖订单id
|
||
$order_list_id = $prize_info['id'];
|
||
#中奖奖项
|
||
$ordinary_prize_info = $v;
|
||
}
|
||
$order_goods_temp = [
|
||
'order_id' => 0,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => $num,
|
||
'shang_id' => $ordinary_prize_info['shang_id'],
|
||
'goodslist_id' => $ordinary_prize_info['id'],
|
||
'goodslist_title' => $ordinary_prize_info['title'],
|
||
'goodslist_imgurl' => $ordinary_prize_info['imgurl'],
|
||
'goodslist_price' => $ordinary_prize_info['price'],
|
||
'goodslist_money' => $ordinary_prize_info['money'],
|
||
'goodslist_type' => $ordinary_prize_info['goods_type'],
|
||
'goodslist_sale_time' => $ordinary_prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $ordinary_prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
'order_list_id' => $order_list_id,
|
||
'parent_goods_list_id' => $ordinary_prize_info['goods_list_id'],
|
||
];
|
||
$res[] = OrderList::insert($order_goods_temp);
|
||
#减少库存
|
||
$res[] = GoodsList::field('surplus_stock')
|
||
->where(['id' => $ordinary_prize_info['id']])
|
||
->dec('surplus_stock')
|
||
->update();
|
||
## 判断是否有奖励
|
||
if (isset($ordinary_prize_info['reward_id']) && $ordinary_prize_info['reward_id'] != '') {
|
||
RewardService::sendReward($user_id, $ordinary_prize_info['reward_id'], '抽中' . $ordinary_prize_info['title']);
|
||
}
|
||
# 宝箱处理
|
||
if ($ordinary_prize_info['goods_type'] == 4) {
|
||
# 查找宝箱奖品
|
||
$goodslist_1 = GoodsList::where(['goods_id' => $goods_id])
|
||
->where('goods_list_id', '=', $ordinary_prize_info['id'])
|
||
->select()->toArray();
|
||
if ($goodslist_1) {
|
||
$res[] = $this->ordinary_prize_notice_box($goodslist_1, 1, 0, $user_id, $goods_id, $order_type, $num);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#新增奖品列表
|
||
// $res[] = OrderList::insertAll($order_goods);
|
||
} else {
|
||
$res[] = 1;
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 无限赏开始抽赏======================================================
|
||
* @param int $user_id 会员id
|
||
* @param int $order_id 订单ID
|
||
* @param int $box_id 盲盒id
|
||
*/
|
||
public function infinite_drawprize_notice($user_id = 0, $order_id = 0, $goods_id = 0, $num = 0)
|
||
{
|
||
// if()
|
||
$res = [];
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => $num])
|
||
->where(['status' => 0])
|
||
->find();
|
||
if ($order == null && $num == 0) {
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => 1])
|
||
->where(['status' => 0])
|
||
->find();
|
||
if ($order != null) {
|
||
$order_type1 = $order['order_type'];
|
||
if ($order_type1 == 10) {
|
||
$num = 1;
|
||
}
|
||
}
|
||
}
|
||
if ($order) {
|
||
#改变状态
|
||
$res[] = Order::field('status,pay_time')
|
||
->where(['id' => $order['id']])
|
||
->update([
|
||
'status' => 1,
|
||
'pay_time' => time(),
|
||
]);
|
||
#扣余额
|
||
if ($order['use_money'] > 0) {
|
||
$res[] = User::changeMoney($order['user_id'], -$order['use_money'], 3, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#扣货币1
|
||
if ($order['use_integral'] > 0) {
|
||
$res[] = User::changeIntegral($order['user_id'], -$order['use_integral'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#
|
||
if ($order['use_money2'] > 0) {
|
||
$res[] = User::changeMoney2($order['user_id'], -$order['use_money2'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
|
||
#判断一下优惠券
|
||
if (!empty($order['coupon_id'])) {
|
||
$coupon = CouponReceiveModel::where(['id' => $order['coupon_id'], 'status' => 0])->update(['status' => 1]);
|
||
}
|
||
|
||
#分销奖励
|
||
$res[] = User::distribution($order);
|
||
|
||
#分销奖励
|
||
#开奖==================================================
|
||
if ($order['order_type'] == 10) {
|
||
$res[] = $this->infinite_shangchengshang($order);
|
||
}
|
||
if ($order['order_type'] == 17) {
|
||
$res[] = $this->infinite_drawprize_tesu($order);
|
||
} else {
|
||
$res[] = $this->infinite_drawprize($order);
|
||
}
|
||
|
||
#开奖==================================================
|
||
#判断是否发积分 发券
|
||
$res[] = User::is_integral_coupon($order);
|
||
#判断是否发积分
|
||
|
||
//升级欧气值
|
||
if ($order['price'] > 0) {
|
||
User::ou_qi_level_up($order['user_id'], $order['price']);
|
||
}
|
||
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
|
||
return $res;
|
||
}
|
||
|
||
|
||
/**
|
||
* 无限赏开奖逻辑
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function infinite_drawprize_tesu($order = [])
|
||
{
|
||
$user_id = $order['user_id'];#用户ID
|
||
$order_id = $order['id'];#订单ID
|
||
$goods_id = $order['goods_id'];#盒子ID
|
||
$prize_num = $order['prize_num'];#抽奖数量
|
||
$order_type = $order['order_type'];#订单类型
|
||
$whe = [];
|
||
$whe[] = ['id', '=', $order['goods_id']];
|
||
$infinite_goods = Goods::getInfo($whe, 'type');
|
||
|
||
$where = [];
|
||
$where[] = ['goods_id', '=', $goods_id];
|
||
$where[] = ['num', '=', 0];
|
||
$where[] = ['real_pro', '>', 0];
|
||
//普通
|
||
$where[] = ['lian_ji_type', '=', 0];
|
||
$where[] = ['goods_list_id', '=', 0];
|
||
#查找奖品
|
||
$goodslist = GoodsList::field('id,shang_id,real_pro,stock')
|
||
->where($where)
|
||
->select()->toArray();
|
||
if ($goodslist) {
|
||
$res[] = $this->infinite_drawprize_tesu_box($goodslist, $prize_num, $order_id, $user_id, $goods_id, $order_type);
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
|
||
}
|
||
|
||
/**
|
||
* 抽出奖品
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function infinite_drawprize_tesu_box($goodslist, $prize_num, $order_id, $user_id, $goods_id, $order_type)
|
||
{
|
||
|
||
// 计算总概率
|
||
$totalProbability = array_sum(array_column($goodslist, 'real_pro'));
|
||
//获取今天凌晨时间
|
||
$todayMidnight = strtotime('today');
|
||
// 构建概率区间
|
||
$probabilityRanges = [];
|
||
$currentRange = 0;
|
||
foreach ($goodslist as $good) {
|
||
|
||
// if ($good['stock'] <= 0) {
|
||
// continue;
|
||
// }
|
||
#判断今日库存
|
||
$user_quanju_count = OrderList::field('id')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('parent_goods_list_id', '=', 0)
|
||
->where('addtime', '>=', $todayMidnight)
|
||
->count();
|
||
// if ($user_quanju_count >= $good['stock']) {
|
||
// continue;
|
||
// }
|
||
$rangeStart = $currentRange;
|
||
$currentRange += $good['real_pro'];
|
||
$probabilityRanges[] = [
|
||
'id' => $good['id'],
|
||
'start' => $rangeStart,
|
||
'end' => $currentRange
|
||
];
|
||
}
|
||
$multiple = ConfigHelper::getInfiniteMultiple();
|
||
for ($i = 0; $i < $prize_num; $i++) {
|
||
// 生成随机数 (保持与原始方法相同的精度:100000)
|
||
|
||
$maxRand = (int) ($totalProbability * $multiple);
|
||
$random = random_int(0, $maxRand) / $multiple;
|
||
|
||
// 查找中奖奖品
|
||
$prize_id = null;
|
||
foreach ($probabilityRanges as $range) {
|
||
if ($random >= $range['start'] && $random < $range['end']) {
|
||
$prize_id = $range['id'];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 获取奖品信息
|
||
$prize_info = GoodsList::where(['id' => $prize_id])->find();
|
||
|
||
#编号
|
||
$luck_no = OrderList::field('id')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', 0)
|
||
->where('order_type', '=', $order_type)
|
||
->order('id desc')
|
||
->value('luck_no');
|
||
$luck_no++;
|
||
$doubling = $prize_info['doubling'];
|
||
if (!$doubling) {
|
||
$doubling = 0;
|
||
}
|
||
#新增记录
|
||
$save_prize_info = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => 0,
|
||
'doubling' => $doubling,
|
||
'shang_id' => $prize_info['shang_id'],
|
||
'goodslist_id' => $prize_info['id'],
|
||
'goodslist_title' => $prize_info['title'],
|
||
'goodslist_imgurl' => $prize_info['imgurl'],
|
||
'goodslist_price' => $prize_info['price'],
|
||
'goodslist_money' => $prize_info['money'],
|
||
'goodslist_type' => $prize_info['goods_type'],
|
||
'goodslist_sale_time' => $prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
'luck_no' => $luck_no,
|
||
'parent_goods_list_id' => $prize_info['goods_list_id'],
|
||
];
|
||
|
||
#入库===
|
||
$res[] = OrderList::insert($save_prize_info);
|
||
# 赠送货币
|
||
if ($prize_info['doubling'] > 1) {
|
||
$bei = $prize_info['doubling'] - 1;
|
||
$change_money = $prize_info['money'] * $bei * 100;
|
||
$res[] = User::changeIntegral($user_id, $change_money, 6, '抽中翻倍赏-' . $prize_info['title'] . '赠送');
|
||
}
|
||
if (isset($prize_info['reward_id']) && $prize_info['reward_id'] != '') {
|
||
RewardService::sendReward($user_id, $prize_info['reward_id'], '抽中' . $prize_info['title']);
|
||
}
|
||
# 宝箱
|
||
if ($prize_info['goods_type'] == 4) {
|
||
# 查找宝箱奖品
|
||
$goodslist_1 = GoodsList::where(['goods_id' => $goods_id])
|
||
->where('goods_list_id', '=', $prize_info['id'])
|
||
->select()->toArray();
|
||
// $res[] = $this->infinite_drawprize_box($order);
|
||
$res[] = $this->infinite_drawprize_tesu_box($goodslist_1, 1, $order_id, $user_id, $goods_id, $order_type);
|
||
}
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
|
||
/**
|
||
* 无限赏开奖逻辑
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function infinite_drawprize($order = [])
|
||
{
|
||
$user_id = $order['user_id'];#用户ID
|
||
$order_id = $order['id'];#订单ID
|
||
$goods_id = $order['goods_id'];#盒子ID
|
||
$prize_num = $order['prize_num'];#抽奖数量
|
||
// $order_type = $order['order_type'];#订单类型
|
||
$whe = [];
|
||
$whe[] = ['id', '=', $order['goods_id']];
|
||
$infinite_goods = Goods::getInfo($whe, '*');
|
||
|
||
$where = [];
|
||
$where[] = ['goods_id', '=', $goods_id];
|
||
$where[] = ['num', '=', 0];
|
||
$where[] = ['real_pro', '>', 0];
|
||
if ($infinite_goods['type'] == 9 && $order['is_mibao'] == 1) {
|
||
//秘宝池
|
||
$where[] = ['lian_ji_type', '=', 1];
|
||
} else {
|
||
//普通
|
||
$where[] = ['lian_ji_type', '=', 0];
|
||
}
|
||
$where[] = ['goods_list_id', '=', 0];
|
||
#查找奖品
|
||
$goodslist = GoodsList::field('id,shang_id,real_pro,title,price,money')
|
||
->where($where)
|
||
->select()->toArray();
|
||
if ($goodslist) {
|
||
|
||
$res[] = $this->infinite_drawprize_box($goodslist, $prize_num, $user_id, $goods_id, $infinite_goods, $order);
|
||
|
||
// 更新Redis中盒子的热度值(增加本次抽奖次数)
|
||
$this->updateGoodsHeat($goods_id, $prize_num);
|
||
|
||
//去除秘宝池次数
|
||
if ($infinite_goods['type'] == 9 && $order['is_mibao'] == 1) {
|
||
User::where('id', $user_id)->dec('mb_number', $prize_num)->update();
|
||
}
|
||
|
||
//计算怒气值
|
||
$this->rage($goods_id, $order_id, $user_id);
|
||
|
||
//领主
|
||
$this->ling_zhu($order, $order_id);
|
||
|
||
//连击赏
|
||
if ($infinite_goods['type'] == 9 && $order['is_mibao'] == 0) {
|
||
$this->lian_ji($order, $order_id);
|
||
}
|
||
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
|
||
}
|
||
|
||
/**
|
||
* 抽出奖品
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function infinite_drawprize_box1($goodslist, $prize_num, $user_id, $goods_id, $infinite_goods, $order)
|
||
{
|
||
$order_id = $order['id'];
|
||
$order_type = $order['order_type'];
|
||
|
||
// 计算总概率
|
||
$totalProbability = array_sum(array_column($goodslist, 'real_pro'));
|
||
|
||
// 构建概率区间
|
||
$probabilityRanges = [];
|
||
$currentRange = 0;
|
||
foreach ($goodslist as $good) {
|
||
$rangeStart = $currentRange;
|
||
$currentRange += $good['real_pro'];
|
||
$probabilityRanges[] = [
|
||
'id' => $good['id'],
|
||
'start' => $rangeStart,
|
||
'end' => $currentRange
|
||
];
|
||
}
|
||
//获取抽奖倍数,100000
|
||
$multiple = ConfigHelper::getInfiniteMultiple();
|
||
$lingzhu_shang_id = 0;
|
||
if (!$infinite_goods) {
|
||
$infinite_goods = Goods::getInfo(['id' => $goods_id], 'type,lingzhu_is,lingzhu_fan,lingzhu_shang_id,king_user_id');
|
||
}
|
||
if ($infinite_goods != null && $infinite_goods['type'] == 8 && $infinite_goods['lingzhu_is'] == 1) {
|
||
$lingzhu_shang_id = $infinite_goods['lingzhu_shang_id'];
|
||
}
|
||
|
||
for ($i = 0; $i < $prize_num; $i++) {
|
||
// 生成随机数 (保持与原始方法相同的精度:100000)
|
||
|
||
$maxRand = (int) ($totalProbability * $multiple);
|
||
$random = random_int(0, $maxRand) / $multiple;
|
||
// 查找中奖奖品
|
||
$prize_id = null;
|
||
foreach ($probabilityRanges as $range) {
|
||
if ($random >= $range['start'] && $random < $range['end']) {
|
||
$prize_id = $range['id'];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 获取奖品信息
|
||
$prize_info = GoodsList::where(['id' => $prize_id])->find();
|
||
|
||
#编号
|
||
$luck_no = OrderList::field('id')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', 0)
|
||
->where('order_type', '=', $order_type)
|
||
->order('id desc')
|
||
->value('luck_no');
|
||
$luck_no++;
|
||
$doubling = $prize_info['doubling'];
|
||
if (!$doubling) {
|
||
$doubling = 0;
|
||
}
|
||
$lingzhu = $prize_info['is_lingzhu'];
|
||
if ($infinite_goods['type'] == 8) {
|
||
//如果是领主赏,则去查询一下。是否为领主
|
||
if ($lingzhu_shang_id > 0 && $lingzhu == 0) {
|
||
if ($lingzhu_shang_id == $prize_info['shang_id']) {
|
||
$lingzhu = 1;
|
||
}
|
||
}
|
||
}
|
||
#新增记录
|
||
$save_prize_info = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => 0,
|
||
'doubling' => $doubling,
|
||
'shang_id' => $prize_info['shang_id'],
|
||
'goodslist_id' => $prize_info['id'],
|
||
'goodslist_title' => $prize_info['title'],
|
||
'goodslist_imgurl' => $prize_info['imgurl'],
|
||
'goodslist_price' => $prize_info['price'],
|
||
'goodslist_money' => $prize_info['money'],
|
||
'goodslist_type' => $prize_info['goods_type'],
|
||
'goodslist_sale_time' => $prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
'luck_no' => $luck_no,
|
||
'parent_goods_list_id' => $prize_info['goods_list_id'],
|
||
'is_lingzhu' => $lingzhu,
|
||
];
|
||
|
||
#入库===
|
||
$res[] = OrderList::insert($save_prize_info);
|
||
# 赠送货币
|
||
if ($prize_info['doubling'] > 1) {
|
||
$bei = $prize_info['doubling'] - 1;
|
||
$change_money = $prize_info['money'] * $bei * 100;
|
||
$res[] = User::changeIntegral($user_id, $change_money, 6, '抽中翻倍赏-' . $prize_info['title'] . '赠送');
|
||
}
|
||
if (isset($prize_info['reward_id']) && $prize_info['reward_id'] != '') {
|
||
RewardService::sendReward($user_id, $prize_info['reward_id'], '抽中' . $prize_info['title']);
|
||
}
|
||
# 宝箱
|
||
if ($prize_info['goods_type'] == 4) {
|
||
# 查找宝箱奖品
|
||
$goodslist_1 = GoodsList::where(['goods_id' => $goods_id])
|
||
->where('goods_list_id', '=', $prize_info['id'])
|
||
->select()->toArray();
|
||
// $res[] = $this->infinite_drawprize_box($order);
|
||
$res[] = $this->infinite_drawprize_box($goodslist_1, 1, $user_id, $goods_id, $infinite_goods, $order);
|
||
}
|
||
}
|
||
|
||
return $res;
|
||
}
|
||
/**
|
||
* 无限抽奖箱:每次抽奖重新随机排序并构建概率区间
|
||
*
|
||
* @param array $goodslist 奖品列表(每个奖品需要包含 real_pro 字段作为概率)
|
||
* @param int $prize_num 抽奖次数
|
||
* @param int $order_id 订单ID
|
||
* @param int $user_id 用户ID
|
||
* @param int $goods_id 商品ID
|
||
* @param int $order_type 订单类型
|
||
* @param array|null $infinite_goods 商品扩展信息(用于领主赏判断)
|
||
* @return array 抽奖结果集合
|
||
*/
|
||
protected function infinite_drawprize_box($goodslist, $prize_num, $user_id, $goods_id, $infinite_goods, $order)
|
||
{
|
||
// 记录抽奖总开始时间
|
||
$total_start_time = microtime(true);
|
||
|
||
// 记录抽奖出货总金额
|
||
$total_prize_money = 0;
|
||
|
||
$order_id = $order['id'];//订单id
|
||
$order_type = $order['order_type'];//订单类型
|
||
$order_num = $order['order_num'];//订单编号
|
||
$res = []; // 保存每次抽奖结果
|
||
$multiple = ConfigHelper::getInfiniteMultiple(); // 获取随机倍数(例如100000)
|
||
|
||
// 将赏品列表转换为map格式,以id为键,便于快速查找
|
||
$shang_list_array = Shang::field('id,title')->select()->toArray();
|
||
$shang_list = [];
|
||
foreach ($shang_list_array as $shang) {
|
||
$shang_list[$shang['id']] = $shang['title'];
|
||
}
|
||
|
||
$lingzhu_shang_id = 0; // 初始化领主赏上级ID
|
||
if (!$infinite_goods) {
|
||
$infinite_goods = Goods::getInfo(['id' => $goods_id], '*');
|
||
}
|
||
if ($infinite_goods != null && $infinite_goods['type'] == 8 && $infinite_goods['lingzhu_is'] == 1) {
|
||
$lingzhu_shang_id = $infinite_goods['lingzhu_shang_id'];
|
||
}
|
||
|
||
// 创建日志数据集合数组
|
||
$log_data_collection = [];
|
||
|
||
// 循环抽奖指定次数
|
||
for ($i = 0; $i < $prize_num; $i++) {
|
||
// 记录单次抽奖开始时间
|
||
$single_start_time = microtime(true);
|
||
|
||
// 用于记录日志的数据
|
||
$log_data = [
|
||
'draw_num' => $i + 1,
|
||
'user_id' => $user_id,
|
||
'box_id' => $goods_id,
|
||
'order_num' => $order_num,
|
||
'probability_ranges' => []
|
||
];
|
||
|
||
// 1. 每次抽奖前,随机打乱奖品列表
|
||
$shuffledGoodsList = $goodslist;
|
||
shuffle($shuffledGoodsList);
|
||
// 2. 重新计算总概率和构建新的概率区间
|
||
$totalProbability = array_sum(array_column($shuffledGoodsList, 'real_pro'));
|
||
$probabilityRanges = [];
|
||
$currentRange = 0;
|
||
foreach ($shuffledGoodsList as $good) {
|
||
$rangeStart = $currentRange;
|
||
$currentRange += $good['real_pro'];
|
||
$probabilityRanges[] = [
|
||
'id' => $good['id'],
|
||
'start' => $rangeStart,
|
||
'end' => $currentRange
|
||
];
|
||
|
||
// 收集奖品区间分布数据用于日志
|
||
// 判断$good中是否已包含需要的信息
|
||
if (isset($good['title']) && isset($good['price'])) {
|
||
$log_data['probability_ranges'][] = [
|
||
'id' => $good['id'],
|
||
'title' => $good['title'],
|
||
'price' => $good['price'],
|
||
'money' => $good['money'],
|
||
'start' => $rangeStart,
|
||
'shang_id' => $good['shang_id'],
|
||
'shang_title' => isset($shang_list[$good['shang_id']]) ? $shang_list[$good['shang_id']] : '未知',
|
||
'end' => $currentRange,
|
||
'real_pro' => $good['real_pro']
|
||
];
|
||
} else {
|
||
// 如果没有,才查询数据库
|
||
$good_info = GoodsList::where(['id' => $good['id']])->field('id,title,price,money,real_pro,shang_id')->find();
|
||
if ($good_info) {
|
||
$log_data['probability_ranges'][] = [
|
||
'id' => $good['id'],
|
||
'title' => $good_info['title'],
|
||
'price' => $good_info['price'],
|
||
'money' => $good_info['money'],
|
||
'shang_id' => $good_info['shang_id'],
|
||
'shang_title' => isset($shang_list[$good_info['shang_id']]) ? $shang_list[$good_info['shang_id']] : '未知',
|
||
'start' => $rangeStart,
|
||
'end' => $currentRange,
|
||
'real_pro' => $good_info['real_pro']
|
||
];
|
||
}
|
||
}
|
||
}
|
||
|
||
// 3. 随机生成一个数,根据区间确定中奖奖品
|
||
$maxRand = (int) ($totalProbability * $multiple);
|
||
$random = random_int(0, $maxRand) / $multiple;
|
||
|
||
// 记录随机数
|
||
$log_data['random'] = $random;
|
||
|
||
$prize_id = null;
|
||
foreach ($probabilityRanges as $range) {
|
||
if ($random >= $range['start'] && $random < $range['end']) {
|
||
$prize_id = $range['id'];
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!$prize_id) {
|
||
// 记录日志 - 未中奖
|
||
$log_data['prize_id'] = 0;
|
||
$log_data['prize_title'] = '未中奖';
|
||
|
||
// 计算单次抽奖耗时
|
||
$single_end_time = microtime(true);
|
||
$log_data['execution_time'] = round(($single_end_time - $single_start_time) * 1000, 2); // 毫秒
|
||
|
||
// 收集日志数据而不是立即写入
|
||
$log_data_collection[] = $log_data;
|
||
continue; // 防止异常空抽
|
||
}
|
||
|
||
// 4. 获取中奖奖品详细信息
|
||
$prize_info = GoodsList::where(['id' => $prize_id])->find();
|
||
if (!$prize_info) {
|
||
// 记录日志 - 奖品信息不存在
|
||
$log_data['prize_id'] = $prize_id;
|
||
$log_data['prize_title'] = '奖品信息不存在';
|
||
|
||
// 计算单次抽奖耗时
|
||
$single_end_time = microtime(true);
|
||
$log_data['execution_time'] = round(($single_end_time - $single_start_time) * 1000, 2); // 毫秒
|
||
|
||
// 收集日志数据而不是立即写入
|
||
$log_data_collection[] = $log_data;
|
||
continue;
|
||
}
|
||
|
||
// 累加中奖金额到总金额
|
||
$total_prize_money += (float) $prize_info['money'];
|
||
$log_data['prize_money'] = $prize_info['money'];
|
||
|
||
// 5. 处理编号
|
||
$luck_no = OrderList::field('luck_no')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', 0)
|
||
->where('order_type', '=', $order_type)
|
||
->order('id desc')
|
||
->value('luck_no');
|
||
$luck_no = $luck_no ? $luck_no + 1 : 1;
|
||
|
||
// 6. 处理翻倍赏
|
||
$doubling = $prize_info['doubling'] ?? 0;
|
||
|
||
// 7. 判断是否是领主赏
|
||
$lingzhu = $prize_info['is_lingzhu'] ?? 0;
|
||
if ($infinite_goods['type'] == 8) {
|
||
if ($lingzhu_shang_id > 0 && $lingzhu == 0) {
|
||
if ($lingzhu_shang_id == $prize_info['shang_id']) {
|
||
$lingzhu = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 记录日志数据
|
||
$log_data['prize_id'] = $prize_info['id'];
|
||
$log_data['prize_title'] = $prize_info['title'];
|
||
$log_data['doubling'] = $doubling;
|
||
$log_data['is_lingzhu'] = $lingzhu;
|
||
$log_data['is_king'] = isset($infinite_goods['king_user_id']) && $infinite_goods['king_user_id'] == $user_id ? 1 : 0;
|
||
$log_data['is_box'] = $prize_info['goods_type'] == 4 ? 1 : 0;
|
||
$log_data['shang_id'] = $prize_info['shang_id'];
|
||
$log_data['shang_title'] = isset($shang_list[$prize_info['shang_id']]) ? $shang_list[$prize_info['shang_id']] : '未知';
|
||
|
||
// 8. 组装抽奖记录
|
||
$save_prize_info = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0, // 0未操作
|
||
'goods_id' => $goods_id,
|
||
'num' => 0,
|
||
'doubling' => $doubling,
|
||
'shang_id' => $prize_info['shang_id'],
|
||
'goodslist_id' => $prize_info['id'],
|
||
'goodslist_title' => $prize_info['title'],
|
||
'goodslist_imgurl' => $prize_info['imgurl'],
|
||
'goodslist_price' => $prize_info['price'],
|
||
'goodslist_money' => $prize_info['money'],
|
||
'goodslist_type' => $prize_info['goods_type'],
|
||
'goodslist_sale_time' => $prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
'luck_no' => $luck_no,
|
||
'parent_goods_list_id' => $prize_info['goods_list_id'],
|
||
'is_lingzhu' => $lingzhu,
|
||
];
|
||
|
||
// 9. 插入中奖记录到订单表
|
||
$res[] = OrderList::insert($save_prize_info);
|
||
// 10. 如果中奖是翻倍赏,赠送货币积分
|
||
if ($doubling > 1) {
|
||
$bei = $doubling - 1;
|
||
$change_money = $prize_info['money'] * $bei * 100;
|
||
$res[] = User::changeIntegral($user_id, $change_money, 6, '抽中翻倍赏-' . $prize_info['title'] . '赠送');
|
||
$log_data['doubling_res'] = '翻倍赠送UU币:' . $change_money;
|
||
}
|
||
// 11. 如果奖品绑定了额外奖励,发放奖励
|
||
if (isset($prize_info['reward_id']) && $prize_info['reward_id'] != '') {
|
||
$reward_res = RewardService::sendReward($user_id, $prize_info['reward_id'], '抽中' . $prize_info['title']);
|
||
$log_data['reward_res'] = $reward_res;
|
||
}
|
||
|
||
// 计算单次抽奖耗时
|
||
$single_end_time = microtime(true);
|
||
$log_data['execution_time'] = round(($single_end_time - $single_start_time) * 1000, 2); // 毫秒
|
||
|
||
// 收集日志数据而不是立即写入
|
||
$log_data_collection[] = $log_data;
|
||
|
||
// 12. 如果抽到宝箱奖品,需要继续递归抽奖
|
||
if ($prize_info['goods_type'] == 4) {
|
||
$goodslist_1 = GoodsList::where(['goods_id' => $goods_id])
|
||
->where('goods_list_id', '=', $prize_info['id'])
|
||
->select()
|
||
->toArray();
|
||
if (!empty($goodslist_1)) {
|
||
$box_result = $this->infinite_drawprize_box($goodslist_1, 1, $user_id, $goods_id, $infinite_goods, $order);
|
||
// 将子抽奖的总金额加到当前总金额中
|
||
if (isset($box_result['total_prize_money'])) {
|
||
$total_prize_money += $box_result['total_prize_money'];
|
||
}
|
||
$res[] = $box_result;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 计算总耗时
|
||
$total_end_time = microtime(true);
|
||
$total_execution_time = round(($total_end_time - $total_start_time) * 1000, 2); // 毫秒
|
||
|
||
// 抽奖循环结束后,统一写入日志
|
||
if (!empty($log_data_collection)) {
|
||
try {
|
||
$this->recordDrawLog($log_data_collection, $infinite_goods, $order, $total_execution_time, $total_prize_money);
|
||
} catch (\Exception $e) {
|
||
// 记录异常信息,但不影响主流程
|
||
\think\facade\Log::error('记录抽奖日志异常:' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
// 将总金额添加到返回结果中,以便递归调用时能够累加子抽奖的金额
|
||
$res['total_prize_money'] = $total_prize_money;
|
||
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 记录抽奖日志(Markdown 格式)
|
||
* @param array $data_collection 抽奖数据集合
|
||
* @param array $goods 商品信息
|
||
* @param array $order 订单信息
|
||
* @param float $total_execution_time 总执行时间(毫秒)
|
||
* @param float $total_prize_money 总出货金额
|
||
* @return void
|
||
*/
|
||
protected function recordDrawLog($data_collection, $goods, $order, $total_execution_time = 0, $total_prize_money = 0)
|
||
{
|
||
// 如果数据集合为空,直接返回
|
||
if (empty($data_collection)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// 获取第一条数据,用于确定日志文件路径
|
||
// $first_data = $data_collection[0];
|
||
$goods_id = $goods['id'];
|
||
$goods_title = $goods['title'];
|
||
$goods_price = $goods['price'];
|
||
$order_num = $order['order_num'];
|
||
// 日志目录格式:./draw_log/{box_id}/
|
||
$log_dir = "./draw_log/{$goods_id}";
|
||
if (!is_dir($log_dir)) {
|
||
mkdir($log_dir, 0755, true);
|
||
}
|
||
|
||
// 日志文件路径
|
||
$log_file = $log_dir . '/' . $order_num . '.md';
|
||
|
||
// 是否为新文件,写入标题
|
||
$is_new_file = !file_exists($log_file);
|
||
|
||
// 构建完整的日志内容
|
||
$full_log_content = '';
|
||
|
||
$full_log_content .= "# 抽奖日志 - 盒子名称: {$goods_title} - 订单号: {$order_num} - 盒子ID: {$goods_id} - 盒子价格: {$goods_price} " . PHP_EOL . PHP_EOL;
|
||
|
||
// 添加订单详情信息
|
||
$full_log_content .= "## 订单详情" . PHP_EOL;
|
||
$full_log_content .= "- **订单总金额**: {$order['order_total']}" . PHP_EOL;
|
||
$full_log_content .= "- **订单折扣金额**: {$order['order_zhe_total']}" . PHP_EOL;
|
||
$full_log_content .= "- **微信支付**: {$order['price']}" . PHP_EOL;
|
||
$full_log_content .= "- **钻石支付**: {$order['use_money']}" . PHP_EOL;
|
||
$full_log_content .= "- **UU币支付**: {$order['use_integral']}" . PHP_EOL;
|
||
$full_log_content .= "- **达达卷支付**: {$order['use_money2']}" . PHP_EOL;
|
||
$full_log_content .= "- **优惠券ID**: {$order['coupon_id']}" . PHP_EOL;
|
||
$full_log_content .= "- **是否首抽五折**: " . ($order['is_shou_zhe'] == 1 ? '是' : '否') . PHP_EOL;
|
||
$full_log_content .= "- **抽奖数量**: {$order['prize_num']}" . PHP_EOL;
|
||
$full_log_content .= "- **下单时间**: " . date('Y-m-d H:i:s', $order['addtime']) . PHP_EOL;
|
||
if (!empty($order['pay_time'])) {
|
||
$full_log_content .= "- **付款时间**: " . date('Y-m-d H:i:s', $order['pay_time']) . PHP_EOL;
|
||
}
|
||
$full_log_content .= "- **是否为福利屋**: " . ($order['is_flw'] == 1 ? '是' : '否') . PHP_EOL;
|
||
$full_log_content .= "- **支付类型**: " . ($order['pay_type'] == 1 ? '微信' : ($order['pay_type'] == 2 ? '支付宝' : '其他')) . PHP_EOL;
|
||
$full_log_content .= PHP_EOL;
|
||
|
||
// 添加总执行时间信息和出货总金额
|
||
$full_log_content .= "## 抽奖总耗时: {$total_execution_time} 毫秒" . PHP_EOL;
|
||
$full_log_content .= "## 本次抽奖出货总金额: {$total_prize_money}" . PHP_EOL . PHP_EOL;
|
||
|
||
// 处理每条抽奖记录
|
||
foreach ($data_collection as $data) {
|
||
// 当前时间
|
||
$now = date('Y-m-d H:i:s');
|
||
|
||
$full_log_content .= "## 第 {$data['draw_num']} 次抽奖 - {$now}" . PHP_EOL;
|
||
$full_log_content .= "- **用户ID**: {$data['user_id']}" . PHP_EOL;
|
||
$full_log_content .= "- **随机数**: {$data['random']}" . PHP_EOL;
|
||
$full_log_content .= "- **执行时间**: {$data['execution_time']} 毫秒" . PHP_EOL;
|
||
|
||
// 获取中奖ID,方便后续在表格中标红
|
||
$winning_prize_id = isset($data['prize_id']) && $data['prize_id'] > 0 ? $data['prize_id'] : 0;
|
||
|
||
// 中奖信息
|
||
if ($winning_prize_id) {
|
||
$full_log_content .= "- **中奖ID**: {$data['prize_id']}" . PHP_EOL;
|
||
$full_log_content .= "- **商品名**: {$data['prize_title']}" . PHP_EOL;
|
||
if (isset($data['prize_money'])) {
|
||
$full_log_content .= "- **奖品金额**: {$data['prize_money']}" . PHP_EOL;
|
||
}
|
||
if (isset($data['shang_id']) && isset($data['shang_title'])) {
|
||
$full_log_content .= "- **赏ID**: {$data['shang_id']}" . PHP_EOL;
|
||
$full_log_content .= "- **赏名称**: {$data['shang_title']}" . PHP_EOL;
|
||
}
|
||
} else {
|
||
$full_log_content .= "- **未中奖或奖品信息异常**" . PHP_EOL;
|
||
}
|
||
|
||
// 奖品翻倍
|
||
if (isset($data['doubling']) && $data['doubling'] > 0) {
|
||
$full_log_content .= "- **奖品翻倍**: {$data['doubling']} 倍" . PHP_EOL;
|
||
if (isset($data['doubling_res'])) {
|
||
$full_log_content .= "- **翻倍奖励**: {$data['doubling_res']}" . PHP_EOL;
|
||
}
|
||
} else {
|
||
$full_log_content .= "- **奖品翻倍**: 无" . PHP_EOL;
|
||
}
|
||
|
||
// 领主等信息
|
||
$full_log_content .= "- **是否领主赏**: " . (isset($data['is_lingzhu']) && $data['is_lingzhu'] == 1 ? "是" : "否") . PHP_EOL;
|
||
$full_log_content .= "- **是否领主**: " . (isset($data['is_king']) && $data['is_king'] == 1 ? "是" : "否") . PHP_EOL;
|
||
$full_log_content .= "- **是否宝箱**: " . (isset($data['is_box']) && $data['is_box'] == 1 ? "是" : "否") . PHP_EOL;
|
||
|
||
// 发放奖励结果
|
||
if (isset($data['reward_res'])) {
|
||
$full_log_content .= "- **发放奖励结果**: " . (is_string($data['reward_res']) ? $data['reward_res'] : json_encode($data['reward_res'], JSON_UNESCAPED_UNICODE)) . PHP_EOL;
|
||
}
|
||
|
||
// 奖品区间分布表格
|
||
if (!empty($data['probability_ranges'])) {
|
||
$full_log_content .= PHP_EOL . "### 奖品区间分布" . PHP_EOL;
|
||
$full_log_content .= "| 奖品ID | 名称 | 价格 | 金额 | 概率 | 区间范围 | 赏ID | 赏名称 |" . PHP_EOL;
|
||
$full_log_content .= "|--------|------|------|------|------|-----------|------|--------|" . PHP_EOL;
|
||
foreach ($data['probability_ranges'] as $range) {
|
||
$start = $range['start'];
|
||
$end = $range['end'];
|
||
$shang_id = $range['shang_id'] ?? 0;
|
||
$shang_title = $range['shang_title'] ?? '未知';
|
||
$money = $range['money'] ?? 0;
|
||
|
||
// 判断是否是中奖奖品,如果是,则把名称变成红色
|
||
$title = $range['title'];
|
||
if ($winning_prize_id && $winning_prize_id == $range['id']) {
|
||
$title = "<span style=\"color:red\">{$title}</span>";
|
||
}
|
||
|
||
$full_log_content .= "| {$range['id']} | {$title} | {$range['price']} | {$money} | {$range['real_pro']} | {$start} ~ {$end} | {$shang_id} | {$shang_title} |" . PHP_EOL;
|
||
}
|
||
}
|
||
|
||
$full_log_content .= PHP_EOL . "---" . PHP_EOL . PHP_EOL;
|
||
}
|
||
|
||
// 一次性写入所有日志内容
|
||
file_put_contents($log_file, $full_log_content, $is_new_file ? FILE_APPEND : (FILE_APPEND | LOCK_EX));
|
||
|
||
} catch (\Exception $e) {
|
||
// 捕获异常,防止影响主流程
|
||
\think\facade\Log::error('记录抽奖日志异常:' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 商城赏
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function infinite_shangchengshang($order = [])
|
||
{
|
||
$user_id = $order['user_id'];#用户ID
|
||
$order_id = $order['id'];#订单ID
|
||
$goods_id = $order['goods_id'];#盒子ID
|
||
$prize_num = $order['prize_num'];#抽奖数量
|
||
$order_type = $order['order_type'];#订单类型
|
||
$whe = [];
|
||
$whe[] = ['id', '=', $order['goods_id']];
|
||
$infinite_goods = Goods::getInfo($whe, 'type');
|
||
$num = 1;
|
||
$where = [];
|
||
$where[] = ['goods_id', '=', $goods_id];
|
||
$where[] = ['num', '=', $num];
|
||
#查找奖品
|
||
$goodslist = GoodsList::field('id,shang_id,real_pro,surplus_stock')
|
||
->where($where)
|
||
->select()->toArray();
|
||
if ($goodslist) {
|
||
#组合中奖商品
|
||
$all_goods_id = [];
|
||
foreach ($goodslist as $value) {
|
||
$surplus_stock = $value['surplus_stock'];
|
||
for ($i = 1; $i <= $surplus_stock; $i++) {
|
||
$all_goods_id[] = $value['id'];
|
||
}
|
||
}
|
||
|
||
for ($i = 0; $i < $prize_num; $i++) {
|
||
|
||
$prize_id = $all_goods_id[0];
|
||
$prize_info = GoodsList::where(['id' => $prize_id])->find();
|
||
$prize_info_surplus_stock = $prize_info['surplus_stock'];
|
||
$prize_info['surplus_stock'] = $prize_info_surplus_stock - 1;
|
||
if ($prize_info_surplus_stock < 0) {
|
||
$res[] = 0;
|
||
return;
|
||
}
|
||
$prize_info->save();
|
||
#编号
|
||
$luck_no = OrderList::field('id')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', $num)
|
||
->where('order_type', '=', $order_type)
|
||
->order('id desc')
|
||
->value('luck_no');
|
||
$luck_no++;
|
||
#新增记录
|
||
$save_prize_info = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => $num,
|
||
'shang_id' => $prize_info['shang_id'],
|
||
'goodslist_id' => $prize_info['id'],
|
||
'goodslist_title' => $prize_info['title'],
|
||
'goodslist_imgurl' => $prize_info['imgurl'],
|
||
'goodslist_price' => $prize_info['price'],
|
||
'goodslist_money' => $prize_info['money'],
|
||
'goodslist_type' => $prize_info['goods_type'],
|
||
'goodslist_sale_time' => $prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
'luck_no' => $luck_no,
|
||
];
|
||
#入库===
|
||
$res[] = OrderList::insert($save_prize_info);
|
||
}
|
||
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
|
||
}
|
||
|
||
//计算怒气值
|
||
public function rage($goods_id, $order_id, $user_id)
|
||
{
|
||
$order_list = OrderList::field('id')->where(['order_id' => $order_id])->find();
|
||
if (!$order_list) {
|
||
return false;
|
||
}
|
||
try {
|
||
$goods = Goods::field('id')->field('rage_is,rage,item_card_id')->where(['id' => $goods_id])->find();
|
||
if ($goods['rage_is'] == 1 && $goods['rage'] > 0 && $goods['item_card_id'] > 0) {
|
||
$order = Order::field('order_total')->where(['id' => $order_id])->find();
|
||
if ($order['order_total'] > 0) {
|
||
//获取奖品总价值
|
||
$out_price_sum = OrderList::where(['order_id' => $order_id])->sum('goodslist_money');
|
||
$rage_number = bcsub($order['order_total'], "$out_price_sum", 2);
|
||
$user_rage = Db::name('user_rage')->field('id,rage')->where(['user_id' => $user_id, 'goods_id' => $goods_id])->find();
|
||
|
||
if ($user_rage) {
|
||
$rage_number2 = bcadd((string) ($user_rage['rage']), "$rage_number", 2);
|
||
if ($rage_number2 >= $goods['rage']) {
|
||
//赠送道具卡
|
||
$item_card = ItemCard::field('id,title')->where(['id' => $goods['item_card_id']])->find();
|
||
if ($item_card) {
|
||
Db::name('user_item_card')->insert(['user_id' => $user_id, 'item_card_id' => $item_card['id'], 'title' => $item_card['title'], 'status' => 1, 'addtime' => time(), 'updatetime' => time()]);
|
||
}
|
||
Db::name('user_rage')->where(['user_id' => $user_id, 'goods_id' => $goods_id])->update(['rage' => 0, 'updatetime' => time()]);
|
||
} else {
|
||
Db::name('user_rage')->where(['user_id' => $user_id, 'goods_id' => $goods_id])->update(['rage' => $rage_number2, 'updatetime' => time()]);
|
||
}
|
||
|
||
} else {
|
||
Db::name('user_rage')->insert(['user_id' => $user_id, 'goods_id' => $goods_id, 'rage' => $rage_number, 'addtime' => time(), 'updatetime' => time()]);
|
||
}
|
||
}
|
||
}
|
||
} catch (\Exception $e) {
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//领主
|
||
public function ling_zhu($order, $order_id)
|
||
{
|
||
//是否开启领主模式
|
||
$whe = [];
|
||
$whe[] = ['id', '=', $order['goods_id']];
|
||
$infinite_goods = Goods::getInfo($whe, 'type,lingzhu_is,lingzhu_fan,lingzhu_shang_id,king_user_id');
|
||
if ($infinite_goods['type'] != 8) {
|
||
return false;
|
||
}
|
||
|
||
if ($infinite_goods['lingzhu_is'] == 1) {
|
||
$whe2 = [];
|
||
$whe2[] = ['order_id', '=', $order_id];
|
||
$order_list = OrderList::getAllList($whe2, 'id,shang_id,user_id,goods_id,is_lingzhu', 'id asc');
|
||
foreach ($order_list as $k => $v) {
|
||
if ($v['shang_id'] == $infinite_goods['lingzhu_shang_id'] || $v['is_lingzhu'] == 1) {
|
||
// 查找当前池子是否有领主
|
||
if ($infinite_goods['king_user_id'] != 0) {
|
||
Db::name('goods_king_rank')->where([['user_id', '=', $infinite_goods['king_user_id']], ['goods_id', '=', $v['goods_id']]])->order('id', 'desc')->limit(1)->update(['end_time' => time()]);
|
||
}
|
||
|
||
//新的领主
|
||
Goods::where(['id' => $v['goods_id']])->update(['king_user_id' => $v['user_id']]);
|
||
//多少发晋升领主
|
||
$luck_no = OrderList::where([['goods_id', '=', $v['goods_id']], ['id', '<=', $v['id']]])->count();
|
||
$rank = [
|
||
'user_id' => $v['user_id'],
|
||
'goods_id' => $v['goods_id'],
|
||
'count' => $luck_no,
|
||
'order_list_id' => $v['id'],
|
||
'addtime' => time(),
|
||
];
|
||
|
||
$result = Db::name('goods_king_rank')->insert($rank);
|
||
} else {
|
||
// 查找当前池子是否有领主
|
||
$infinite_goods = Goods::getInfo($whe, 'lingzhu_is,lingzhu_fan,lingzhu_shang_id,king_user_id');
|
||
|
||
if ($infinite_goods['king_user_id'] != 0) {
|
||
$king_user_id = $infinite_goods['king_user_id'];
|
||
Db::name('goods_king_rank')->where([['user_id', '=', $infinite_goods['king_user_id']], ['goods_id', '=', $v['goods_id']]])->order('id', 'desc')->limit(1)->inc('z_nums', 1)->update();
|
||
$king_money = $infinite_goods['lingzhu_fan'];
|
||
if ($king_money && $king_money > 0) {
|
||
|
||
Db::name('goods_king_rank')->where([['user_id', '=', $infinite_goods['king_user_id']], ['goods_id', '=', $v['goods_id']]])->order('id', 'desc')->limit(1)->inc('money', floatval($king_money))->update();
|
||
|
||
// User::changeIntegral($infinite_goods['king_user_id'], $king_money, 4, '领主收益');
|
||
User::changeIntegral($infinite_goods['king_user_id'], $king_money, 4, '领主收益');
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//连击赏
|
||
public function lian_ji($order, $order_id)
|
||
{
|
||
//是否是连击赏
|
||
$whe = [];
|
||
$whe[] = ['id', '=', $order['goods_id']];
|
||
$infinite_goods = Goods::getInfo($whe, 'type,lian_ji_num,lian_ji_shang_id');
|
||
if ($infinite_goods['type'] != 9) {
|
||
return false;
|
||
}
|
||
if ($order['is_mibao'] == 1) {
|
||
//减少秘宝池次数
|
||
User::field('mb_number')->where(['id' => $order['user_id']])->dec('mb_number', $order['prize_num'])->update();
|
||
}
|
||
$whe2 = [];
|
||
$whe2[] = ['order_id', '=', $order_id];
|
||
$order_list = OrderList::getAllList($whe2, 'id,shang_id,goods_id,user_id', 'id asc');
|
||
foreach ($order_list as $k => $v) {
|
||
//是否已有连击
|
||
$user_goods_lian_ji = Db::name('user_goods_lian_ji')->where([['user_id', '=', $v['user_id']], ['goods_id', '=', $v['goods_id']]])->whereNull('deltime')->order('id', 'desc')->find();
|
||
|
||
if ($v['shang_id'] == $infinite_goods['lian_ji_shang_id']) {
|
||
|
||
if ($infinite_goods['lian_ji_num'] != 0 && $infinite_goods['lian_ji_shang_id'] != 0) {
|
||
|
||
if ($user_goods_lian_ji) {
|
||
Db::name('user_goods_lian_ji')->field('number,updatetime')->where([['user_id', '=', $v['user_id']], ['goods_id', '=', $v['goods_id']]])->whereNull('deltime')->order('id', 'desc')->inc('number', 1)->update(['updatetime' => time()]);
|
||
//连击次数是否满足条件
|
||
$lian_ji_number = Db::name('user_goods_lian_ji')->where([['user_id', '=', $v['user_id']], ['goods_id', '=', $v['goods_id']]])->whereNull('deltime')->order('id', 'desc')->limit(1)->value('number');
|
||
if ($lian_ji_number && $lian_ji_number >= $infinite_goods['lian_ji_num']) {
|
||
//赠送秘宝池次数
|
||
User::field('mb_number')->where(['id' => $v['user_id']])->inc('mb_number', 1)->update();
|
||
//清空连击次数
|
||
Db::name('user_goods_lian_ji')->field('number,updatetime')->where([['user_id', '=', $v['user_id']], ['goods_id', '=', $v['goods_id']]])->whereNull('deltime')->order('id', 'desc')->update(['number' => 0, 'updatetime' => time()]);
|
||
}
|
||
} else {
|
||
Db::name('user_goods_lian_ji')->insert(['user_id' => $v['user_id'], 'goods_id' => $v['goods_id'], 'number' => 1, 'addtime' => time(), 'updatetime' => time()]);
|
||
}
|
||
}
|
||
} else {
|
||
if ($user_goods_lian_ji) {
|
||
Db::name('user_goods_lian_ji')->field('number,updatetime')->where([['user_id', '=', $v['user_id']], ['goods_id', '=', $v['goods_id']]])->whereNull('deltime')->order('id', 'desc')->update(['number' => 0, 'updatetime' => time()]);
|
||
} else {
|
||
Db::name('user_goods_lian_ji')->insert(['user_id' => $v['user_id'], 'goods_id' => $v['goods_id'], 'number' => 0, 'addtime' => time(), 'updatetime' => time()]);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 抽卡机抽奖逻辑
|
||
* @param int $user_id
|
||
* @param int $order_id
|
||
* @param int $goods_id
|
||
*/
|
||
public function cardextractor_drawprize_notice($user_id = 0, $order_id = 0, $goods_id = 0)
|
||
{
|
||
$res = [];
|
||
// dd(11);
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => 0])
|
||
->where(['status' => 0])
|
||
->where(['order_type' => 4])
|
||
->find();
|
||
// dd($order);
|
||
if ($order) {
|
||
#改变状态
|
||
$res[] = Order::field('status,pay_time')
|
||
->where(['id' => $order['id']])
|
||
->update([
|
||
'status' => 1,
|
||
'pay_time' => time(),
|
||
]);
|
||
#扣余额
|
||
if ($order['use_money'] > 0) {
|
||
$res[] = User::changeMoney($order['user_id'], -$order['use_money'], 3, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#扣货币1
|
||
if ($order['use_integral'] > 0) {
|
||
$res[] = User::changeIntegral($order['user_id'], -$order['use_integral'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
//扣除货币2
|
||
if ($order['use_money2'] > 0) {
|
||
$res[] = User::changeMoney2($order['user_id'], -$order['use_money2'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#判断一下优惠券
|
||
if (!empty($order['coupon_id'])) {
|
||
$coupon = CouponReceiveModel::where(['id' => $order['coupon_id'], 'status' => 0])->update(['status' => 1]);
|
||
}
|
||
#判断是否发积分 发券
|
||
$res[] = User::is_integral_coupon($order);
|
||
#判断是否发积分
|
||
|
||
#分销奖励
|
||
$res[] = User::distribution($order);
|
||
#分销奖励
|
||
|
||
#开奖==================================================
|
||
$res[] = $this->cardextractor_drawprize($order);
|
||
#开奖==================================================
|
||
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 抽卡机开奖
|
||
* @param array $order
|
||
*/
|
||
public function cardextractor_drawprize($order = [])
|
||
{
|
||
$user_id = $order['user_id'];#用户ID
|
||
$order_id = $order['id'];#订单ID
|
||
$goods_id = $order['goods_id'];#盒子ID
|
||
$prize_num = $order['prize_num'];#抽奖数量
|
||
$order_type = $order['order_type'];#订单类型
|
||
$prize_card_set = $order['prize_card_set'] ? json_decode($order['prize_card_set'], true) : '';#抽卡机必出设置
|
||
// dd($order);
|
||
#排除必出等级卡条件
|
||
$shang_where = [];
|
||
// dd(11111);
|
||
#必出卡等级
|
||
$set_prize_shang = [];
|
||
if ($prize_card_set && isset($prize_card_set['shang_id']) && isset($prize_card_set['shang_count'])) {
|
||
|
||
// dd($prize_card_set['shang_count']);
|
||
// foreach ($prize_card_set as $set_key => $set_value) {
|
||
|
||
for ($seti = 1; $seti <= $prize_card_set['shang_count']; $seti++) {
|
||
$set_prize_shang[] = $prize_card_set['shang_id'];
|
||
}
|
||
// }
|
||
// dd($set_prize_shang);
|
||
|
||
#排除必出等级卡条件
|
||
$shang_where[] = ['id', 'not in', array_unique($set_prize_shang)];
|
||
#减去必出数量
|
||
$prize_num = $prize_num - count($set_prize_shang);
|
||
}
|
||
|
||
// dd($shang_where);
|
||
#卡等级随机
|
||
$shang = CardLevel::field('id,title')
|
||
// ->where('goods_id', '=', $goods_id)
|
||
// ->where('pro', '>', 0)
|
||
->where($shang_where)
|
||
->select()->toArray();
|
||
// dd(1111)
|
||
// dd($shang);
|
||
if ($shang) {
|
||
|
||
#卡等级随机
|
||
$all_shang_id = [];
|
||
foreach ($shang as $shang_value) {
|
||
// $real_shang_pro = $shang_value['pro'] * 100;
|
||
// for ($is = 1; $is <= $real_shang_pro; $is++) {
|
||
$goods = GoodsList::where('shang_id', $shang_value['id'])->where('goods_id', '=', $goods_id)->find();
|
||
if ($goods) {
|
||
$all_shang_id[] = $shang_value['id'];
|
||
}
|
||
|
||
// }
|
||
}
|
||
// dd($all_shang_id);
|
||
#中奖卡等级
|
||
$prize_shang = [];
|
||
for ($i = 0; $i < $prize_num; $i++) {
|
||
#随机打乱
|
||
shuffle($all_shang_id);
|
||
shuffle($all_shang_id);
|
||
$prize_shang[] = $all_shang_id[0];
|
||
}
|
||
// dd($prize_shang);
|
||
$prize_shang = array_merge($prize_shang, $set_prize_shang);
|
||
shuffle($prize_shang);
|
||
$save_prize_data = [];
|
||
// dd($prize_shang);
|
||
#根据卡等级中奖奖品
|
||
foreach ($prize_shang as $prize_shang_id) {
|
||
#查找奖品
|
||
$goodslist = GoodsList::field('id,shang_id,real_pro,special_stock')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('shang_id', '=', $prize_shang_id)
|
||
->where('num', '=', 0)
|
||
->where('real_pro', '>', 0)
|
||
->where('special_stock = -100 OR special_stock > 0')
|
||
->select()->toArray();
|
||
if (empty($goodslist)) {
|
||
$res[] = 0;
|
||
return $res;
|
||
}
|
||
// dd($goodslist);
|
||
if ($goodslist) {
|
||
#组合中奖商品
|
||
$all_goods_id = [];
|
||
foreach ($goodslist as $value) {
|
||
$real_pro = $value['real_pro'] * 100;
|
||
for ($i = 1; $i <= $real_pro; $i++) {
|
||
$all_goods_id[] = $value['id'];
|
||
}
|
||
}
|
||
#随机打乱
|
||
shuffle($all_goods_id);
|
||
shuffle($all_goods_id);
|
||
$prize_id = $all_goods_id[0];
|
||
$prize_info = GoodsList::where(['id' => $prize_id])->find();
|
||
$save_prize_data[] = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => 0,
|
||
'shang_id' => $prize_info['shang_id'],
|
||
'goodslist_id' => $prize_info['id'],
|
||
'goodslist_title' => $prize_info['title'],
|
||
'goodslist_imgurl' => $prize_info['imgurl'],
|
||
'goodslist_price' => $prize_info['price'],
|
||
'goodslist_money' => $prize_info['money'],
|
||
'goodslist_type' => $prize_info['goods_type'],
|
||
'goodslist_sale_time' => $prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
];
|
||
if ($prize_info['special_stock'] >= 1) {
|
||
#减少库存
|
||
$res[] = GoodsList::field('special_stock')
|
||
->where(['id' => $prize_info['id']])
|
||
->dec('special_stock')
|
||
->update();
|
||
}
|
||
} else {
|
||
$res[] = $prize_shang_id;
|
||
}
|
||
}
|
||
#入库===
|
||
$res[] = OrderList::insertAll($save_prize_data);
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 背包发货订单处理
|
||
* @param int $user_id 用户id
|
||
* @param int $order_id 订单id
|
||
*/
|
||
public function reward_order_handle($user_id = 0, $order_id = 0)
|
||
{
|
||
$res = [];
|
||
$send_info = OrderListSend::where(['user_id' => $user_id])
|
||
->where('user_id', '=', $user_id)
|
||
->where('id', '=', $order_id)
|
||
->where('status', '=', 0)#0待支付 1待发货 2待收货 3已完成
|
||
->find();
|
||
if ($send_info) {
|
||
#改变订单状态
|
||
$res[] = OrderListSend::field('id,status,pay_time')
|
||
->where('id', '=', $order_id)
|
||
->update([
|
||
'status' => 1,#0待支付 1待发货 2待收货 3已完成
|
||
'pay_time' => time(),#支付时间
|
||
]);
|
||
#改变赏品信息
|
||
$res[] = OrderList::field('id,status,send_num,choice_time')
|
||
->where('user_id', '=', $user_id)
|
||
->where('status', '=', 0)
|
||
->where('goodslist_type', '=', 1)
|
||
->where('send_num', '=', $send_info['send_num'])
|
||
->update([
|
||
'status' => 2,
|
||
'choice_time' => time(),
|
||
]);
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
}
|
||
|
||
|
||
|
||
|
||
public function order_notify7()
|
||
{
|
||
$testxml = file_get_contents("php://input");
|
||
$jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA));
|
||
$result = json_decode($jsonxml, true);//转成数组,
|
||
// wri($result['out_trade_no'], '秒杀商城回调--' . $result['out_trade_no']);
|
||
if ($result) {
|
||
//如果成功返回了
|
||
$out_trade_no = $result['out_trade_no'];
|
||
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
|
||
// writelog($out_trade_no, "秒杀商城支付成功--");
|
||
Db::startTrans();
|
||
$res[] = $this->order_update($out_trade_no, 7);
|
||
if (resCheck($res)) {
|
||
Db::commit();
|
||
} else {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
}
|
||
$html = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
|
||
die($html);
|
||
}
|
||
|
||
public static function order_update($order_num, $type)
|
||
{
|
||
$res = [];
|
||
$order_info = Db::name('kk_order')
|
||
->where(['order_no' => $order_num])
|
||
->where(['status' => 0])#0待付款 1待发货 2待收货 3确认收货
|
||
->find();
|
||
if ($order_info) {
|
||
#改变订单状态
|
||
$res[] = Db::name('kk_order')->field('id,status,pay_time')
|
||
->where(['id' => $order_info['id']])
|
||
->update([
|
||
'status' => 1,#0待付款 1待发货 2待收货 3确认收货
|
||
'pay_time' => time(),#支付时间
|
||
]);
|
||
if ($order_info['money'] > 0) {
|
||
// dd($order_info['user_id']);
|
||
User::changeMoney($order_info['user_id'], '-' . $order_info['money'], 7);
|
||
}
|
||
if ($order_info['integral'] > 0) {
|
||
User::changeIntegral($order_info['user_id'], '-' . $order_info['integral'], 4);
|
||
}
|
||
$goods_data = Db::name('kk_order_good')
|
||
->field('id,goods_id,goods_num,goods_spec_id')
|
||
->where(['order_id' => $order_info['id']])
|
||
->select()->toArray();
|
||
foreach ($goods_data as $k => $v) {
|
||
#加销量
|
||
Db::name('kk_product')
|
||
->field('id,sale_num')
|
||
->where('id', $v['goods_id'])
|
||
->inc('sale_num', $v['goods_num'])
|
||
->update();
|
||
#减库存
|
||
Db::name('kk_product_spec')
|
||
->field('id,stock')
|
||
->where('id', $v['goods_spec_id'])
|
||
->dec('stock', $v['goods_num'])
|
||
->update();
|
||
}
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
|
||
}
|
||
|
||
/**
|
||
* 抽奖券======================================================
|
||
* @param int $user_id 会员id
|
||
* @param int $order_id 订单ID
|
||
* @param int $box_id 盲盒id
|
||
*/
|
||
public function draw_drawprize_notice($user_id = 0, $order_id = 0, $goods_id = 0)
|
||
{
|
||
$res = [];
|
||
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => 0])
|
||
->where(['status' => 0])
|
||
->where(['order_type' => 7])
|
||
->find();
|
||
if ($order) {
|
||
#改变状态
|
||
$res[] = Order::field('status,pay_time')
|
||
->where(['id' => $order['id']])
|
||
->update([
|
||
'status' => 1,
|
||
'pay_time' => time(),
|
||
]);
|
||
#扣抽奖券
|
||
if ($order['use_draw'] > 0) {
|
||
$res[] = User::changeDraw($order['user_id'], -$order['use_draw'], 3, '抽奖券消费' . $order['goods_title']);
|
||
}
|
||
#开奖==================================================
|
||
$res[] = $this->draw_drawprize($order);
|
||
#开奖==================================================
|
||
|
||
// 更新Redis中盒子的热度值
|
||
$this->updateGoodsHeat($goods_id, $order['prize_num']);
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 无限赏开奖逻辑
|
||
* @param $order 订单信息
|
||
*/
|
||
protected function draw_drawprize($order = [])
|
||
{
|
||
|
||
$user_id = $order['user_id'];#用户ID
|
||
$order_id = $order['id'];#订单ID
|
||
$goods_id = $order['goods_id'];#盒子ID
|
||
$prize_num = $order['prize_num'];#抽奖数量
|
||
$order_type = $order['order_type'];#订单类型
|
||
|
||
#查找奖品
|
||
$goodslist = GoodsList::field('id,shang_id,real_pro')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', 0)
|
||
->where('real_pro', '>', 0)
|
||
->select()->toArray();
|
||
if ($goodslist) {
|
||
#组合中奖商品
|
||
$all_goods_id = [];
|
||
foreach ($goodslist as $value) {
|
||
$real_pro = $value['real_pro'] * 100;
|
||
for ($i = 1; $i <= $real_pro; $i++) {
|
||
$all_goods_id[] = $value['id'];
|
||
}
|
||
}
|
||
for ($i = 0; $i < $prize_num; $i++) {
|
||
#随机打乱
|
||
shuffle($all_goods_id);
|
||
shuffle($all_goods_id);
|
||
$prize_id = $all_goods_id[0];
|
||
$prize_info = GoodsList::where(['id' => $prize_id])->find();
|
||
#编号
|
||
$luck_no = OrderList::field('id')
|
||
->where('goods_id', '=', $goods_id)
|
||
->where('num', '=', 0)
|
||
->where('order_type', '=', $order_type)
|
||
->order('id desc')
|
||
->value('luck_no');
|
||
$luck_no++;
|
||
#新增记录
|
||
$save_prize_info = [
|
||
'order_id' => $order_id,
|
||
'user_id' => $user_id,
|
||
'status' => 0,#0未操作 1选择兑换 2选择发货
|
||
'goods_id' => $goods_id,
|
||
'num' => 0,
|
||
'shang_id' => $prize_info['shang_id'],
|
||
'goodslist_id' => $prize_info['id'],
|
||
'goodslist_title' => $prize_info['title'],
|
||
'goodslist_imgurl' => $prize_info['imgurl'],
|
||
'goodslist_price' => $prize_info['price'],
|
||
'goodslist_money' => $prize_info['money'],
|
||
'goodslist_type' => $prize_info['goods_type'],
|
||
'goodslist_sale_time' => $prize_info['sale_time'],
|
||
'addtime' => time(),
|
||
'prize_code' => $prize_info['prize_code'],
|
||
'order_type' => $order_type,
|
||
'luck_no' => $luck_no,
|
||
];
|
||
#入库===
|
||
$res[] = OrderList::insert($save_prize_info);
|
||
}
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
return $res;
|
||
|
||
}
|
||
|
||
/**
|
||
* 道具卡======================================================
|
||
* @param int $user_id 会员id
|
||
* @param int $order_id 订单ID
|
||
* @param int $box_id 盲盒id
|
||
*/
|
||
public function item_card_notice($user_id = 0, $order_id = 0, $goods_id = 0)
|
||
{
|
||
$res = [];
|
||
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => 0])
|
||
->where(['status' => 0])
|
||
->find();
|
||
if ($order) {
|
||
#改变状态
|
||
$res[] = Order::field('status,pay_time')
|
||
->where(['id' => $order['id']])
|
||
->update([
|
||
'status' => 1,
|
||
'pay_time' => time(),
|
||
]);
|
||
#扣道具卡
|
||
if ($order['use_item_card'] > 0) {
|
||
$res[] = Db::name('user_item_card')->where(['user_id' => $user_id, 'status' => 1])->order('id asc')->limit($order['use_item_card'])->update(['status' => 2, 'order_id' => $order_id, 'updatetime' => time()]);
|
||
}
|
||
#开奖==================================================
|
||
$res[] = $this->draw_drawprize($order);
|
||
#开奖==================================================
|
||
|
||
// 更新Redis中盒子的热度值
|
||
$this->updateGoodsHeat($goods_id, $order['prize_num']);
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
|
||
return $res;
|
||
}
|
||
|
||
public function wx_gf_fahuo($user_id, $order_num)
|
||
{
|
||
$user = Db::name('user')->where('id', $user_id)->find();
|
||
$mp = new \app\common\server\platform\MiniProgramPlatform();
|
||
$mp->post_order($user, $order_num);
|
||
// //微信官方发货
|
||
// $wxServer = new \app\common\server\Wx($this->app);
|
||
|
||
// $access_token = $wxServer->get_access_token();
|
||
// $open_id = Db::name('user')->where('id', $user_id)->value('openid');
|
||
// $pay = new \app\api\controller\Pay();
|
||
// $pay->post_order($open_id, $access_token, $order_num);
|
||
// $wxServer->post_order($open_id, $access_token, $order_num);
|
||
}
|
||
|
||
/**
|
||
* 商城赏======================================================
|
||
* @param int $user_id 会员id
|
||
* @param int $order_id 订单ID
|
||
* @param int $box_id 盲盒id
|
||
*/
|
||
public function infinite_shangchengshang_notice($user_id = 0, $order_id = 0, $goods_id = 0, $num = 0)
|
||
{
|
||
|
||
$res = [];
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => $num])
|
||
->where(['status' => 0])
|
||
->find();
|
||
if ($order == null && $num == 0) {
|
||
$order = Order::where(['id' => $order_id])
|
||
->where(['user_id' => $user_id])
|
||
->where(['goods_id' => $goods_id])
|
||
->where(['num' => 1])
|
||
->where(['status' => 0])
|
||
->find();
|
||
if ($order != null) {
|
||
$order_type1 = $order['order_type'];
|
||
if ($order_type1 == 10) {
|
||
$num = 1;
|
||
}
|
||
}
|
||
}
|
||
if ($order) {
|
||
#改变状态
|
||
$res[] = Order::field('status,pay_time')
|
||
->where(['id' => $order['id']])
|
||
->update([
|
||
'status' => 1,
|
||
'pay_time' => time(),
|
||
]);
|
||
#扣余额
|
||
if ($order['use_money'] > 0) {
|
||
$res[] = User::changeMoney($order['user_id'], -$order['use_money'], 3, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#扣货币
|
||
if ($order['use_integral'] > 0) {
|
||
$res[] = User::changeIntegral($order['user_id'], -$order['use_integral'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
#扣货币2
|
||
if ($order['use_money2'] > 0) {
|
||
$res[] = User::changeMoney2($order['user_id'], -$order['use_money2'], 2, '购买盒子' . $order['goods_title']);
|
||
}
|
||
$res[] = $this->infinite_shangchengshang($order);
|
||
} else {
|
||
$res[] = 0;
|
||
}
|
||
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 更新Redis中盒子的热度值
|
||
*
|
||
* @param int $goods_id 盒子ID
|
||
* @param int $prize_num 本次抽奖次数
|
||
* @return bool 更新结果
|
||
*/
|
||
private function updateGoodsHeat($goods_id, $prize_num)
|
||
{
|
||
try {
|
||
// 获取Redis实例
|
||
$redis = (new \app\common\server\RedisHelper())->getRedis();
|
||
$cacheKey = "order_goods_count:{$goods_id}";
|
||
|
||
// 获取当前热度值
|
||
$current_heat = $redis->get($cacheKey);
|
||
|
||
// 如果缓存不存在,先从数据库获取
|
||
if ($current_heat === false) {
|
||
$current_heat = \app\common\model\OrderList::where('goods_id', '=', $goods_id)
|
||
->where('shang_id', 'between', [34, 38])
|
||
->where('parent_goods_list_id', '=', 0)
|
||
->count();
|
||
} else {
|
||
// 转为整数
|
||
$current_heat = intval($current_heat);
|
||
}
|
||
|
||
// 计算新的热度值
|
||
$new_heat = $current_heat + $prize_num;
|
||
|
||
// 更新Redis缓存,设置5分钟过期时间
|
||
$redis->set($cacheKey, $new_heat, 300);
|
||
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
// 发生异常时记录日志
|
||
\think\facade\Log::error("更新盒子热度值失败:" . $e->getMessage());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 新的支付结果通知处理方法(通过路径参数接收)
|
||
* @param string|null $payment_type 支付方式
|
||
* @param string|null $order_type 赏品类型(order_yfs, order_lts等)
|
||
* @param int|null $user_id 用户ID
|
||
* @param string|null $order_num 订单号
|
||
* @param int|null $timestamp 支付时间戳
|
||
* @param string|null $sign 加密验签
|
||
* @return void
|
||
*/
|
||
public function order_notify_new($payment_type = null, $order_type = null, $user_id = null, $order_num = null, $timestamp = null, $sign = null)
|
||
{
|
||
$rawContent = Request::getContent(); // 返回原始字符串
|
||
// 记录接收到的参数
|
||
writelog('pay_notify_log', json_encode([
|
||
'method' => 'order_notify_new',
|
||
'payment_type' => $payment_type,
|
||
'order_type' => $order_type,
|
||
'user_id' => $user_id,
|
||
'order_num' => $order_num,
|
||
'timestamp' => $timestamp,
|
||
'sign' => $sign,
|
||
'time' => date('Y-m-d H:i:s'),
|
||
'psot' => $rawContent
|
||
]));
|
||
// 验证所有必要参数是否存在
|
||
if (empty($payment_type) || empty($order_type) || empty($user_id) || empty($order_num) || empty($timestamp) || empty($sign)) {
|
||
writelog('pay_notify_error', "缺少必要参数: payment_type={$payment_type}, order_type={$order_type}, user_id={$user_id}, order_num={$order_num}, timestamp={$timestamp}, sign={$sign}");
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
// 验证时间戳,允许6小时的误差
|
||
if (abs(time() - intval($timestamp)) > 21600) {
|
||
writelog('pay_notify_error', "时间戳验证失败,超出6小时的有效期: " . $timestamp);
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
if ($payment_type == "zfbpay") {
|
||
$postData = request()->post();
|
||
$h5 = new \app\common\server\platform\H5Platform();
|
||
$zfb_result = $h5->verify($order_num, $postData);
|
||
if (!$zfb_result) {
|
||
writelog('pay_notify_error', "支付宝支付验证失败: " . $order_num);
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
}
|
||
// 获取Redis实例
|
||
$redis = (new \app\common\server\RedisHelper())->getRedis();
|
||
$lockKey = "pay_notify_lock:{$order_num}";
|
||
|
||
// 尝试获取锁,过期时间为5分钟
|
||
if (!$redis->setnx($lockKey, time())) {
|
||
// 如果锁已存在,检查是否已经超时
|
||
$lockTime = $redis->get($lockKey);
|
||
if ($lockTime && time() - $lockTime < 300) {
|
||
// 锁未超时,说明订单正在处理中,直接返回成功
|
||
writelog('pay_notify_info', "订单 {$order_num} 正在处理中,跳过重复请求");
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
// 锁已超时,可以强制获取
|
||
$redis->set($lockKey, time(), 300);
|
||
} else {
|
||
// 成功获取锁,设置过期时间
|
||
$redis->expire($lockKey, 300);
|
||
}
|
||
|
||
try {
|
||
// 从订单通知表中获取随机字符串
|
||
$orderNotify = \app\common\model\OrderNotify::getByOrderNo($order_num);
|
||
if (!$orderNotify) {
|
||
writelog('pay_notify_error', "未找到订单通知记录: " . $order_num);
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
$nonce_str = $orderNotify['nonce_str'];
|
||
if (empty($nonce_str)) {
|
||
writelog('pay_notify_error', "订单 {$order_num} 没有关联的随机字符串");
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
// 验证签名
|
||
$data = [
|
||
'payment_type' => $payment_type,
|
||
'order_type' => $order_type,
|
||
'user_id' => $user_id,
|
||
'order_num' => $order_num,
|
||
'timestamp' => $timestamp,
|
||
'nonce_str' => $nonce_str // 使用从数据库中获取的随机字符串
|
||
];
|
||
|
||
if (!verifyPayNotifySign($data, $sign)) {
|
||
writelog('pay_notify_error', "签名验证失败: " . json_encode($data));
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
$price = 0;
|
||
|
||
// 开始处理支付
|
||
Db::startTrans();
|
||
try {
|
||
$res = [];
|
||
|
||
// 更新订单通知状态为处理中
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 1, '回调处理中');
|
||
|
||
if ($order_type == 'order_list_send') {
|
||
// 背包发货处理逻辑
|
||
$orderInfo = OrderListSend::where('send_num', '=', $order_num)
|
||
->where('status', '=', 0)
|
||
->find();
|
||
|
||
if (!$orderInfo) {
|
||
writelog('pay_notify_error', "未找到发货订单或状态错误: " . $order_num);
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '未找到发货订单或状态错误');
|
||
Db::rollback();
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
$user_id = $orderInfo['user_id'];
|
||
$freight = $orderInfo['freight'];
|
||
|
||
$res[] = $this->reward_order_handle($user_id, $orderInfo['id']);
|
||
|
||
// 记录微信支付
|
||
$res[] = ProfitPay::insert([
|
||
'user_id' => $user_id,
|
||
'order_num' => $order_num,
|
||
'change_money' => $freight,
|
||
'content' => '背包发货',
|
||
'pay_type' => $payment_type == 'alipay' ? 2 : 1,
|
||
'addtime' => time(),
|
||
]);
|
||
// 微信官方公众号发货通知
|
||
if ($payment_type == "wxpay") {
|
||
$this->wx_gf_fahuo($user_id, $order_num);
|
||
}
|
||
|
||
} else {
|
||
// 普通盒子订单处理逻辑
|
||
$orderInfo = Order::where('order_num', '=', $order_num)
|
||
->find();
|
||
|
||
if (!$orderInfo) {
|
||
writelog('pay_notify_error', "未找到订单: " . $order_num);
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '未找到订单');
|
||
Db::rollback();
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
// 检查订单状态
|
||
if ($orderInfo['status'] != 0) {
|
||
writelog('pay_notify_error', "订单状态不正确: " . $order_num . ", 状态: " . $orderInfo['status']);
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '订单状态不正确');
|
||
Order::where(['order_num' => $order_num])->update(['kd_is' => 1]);
|
||
Db::rollback();
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
// 验证用户ID是否一致
|
||
if ($orderInfo['user_id'] != $user_id) {
|
||
writelog('pay_notify_error', "用户ID不匹配: 通知中的用户ID={$user_id}, 订单中的用户ID={$orderInfo['user_id']}");
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '用户ID不匹配');
|
||
Order::where(['order_num' => $order_num])->update(['kd_is' => 1]);
|
||
Db::rollback();
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
$price = $orderInfo['price'];
|
||
|
||
// 根据订单类型执行不同的处理逻辑
|
||
if (in_array($order_type, ['order_wxs', 'order_fbs'])) {
|
||
// 无限赏处理
|
||
$res[] = $this->infinite_drawprize_notice($user_id, $orderInfo['id'], $orderInfo['goods_id'], $orderInfo['num']);
|
||
} elseif (in_array($order_type, ['order_yfs', 'order_lts', 'order_zzs', 'order_flw', 'order_scs'])) {
|
||
// 一番赏、擂台赏等处理
|
||
$res[] = $this->drawprize_notice($user_id, $orderInfo['id'], $orderInfo['goods_id'], $orderInfo['num']);
|
||
} elseif ($order_type == 'order_ckj') {
|
||
// 抽卡机处理
|
||
$res[] = $this->cardextractor_drawprize_notice($user_id, $orderInfo['id'], $orderInfo['goods_id']);
|
||
} else {
|
||
writelog('pay_notify_error', "不支持的订单类型: " . $order_type);
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '不支持的订单类型');
|
||
Db::rollback();
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
return;
|
||
}
|
||
|
||
// 微信官方公众号发货通知
|
||
if ($payment_type == "wxpay") {
|
||
$this->wx_gf_fahuo($user_id, $orderInfo['order_num']);
|
||
}
|
||
|
||
// 记录支付信息
|
||
$res[] = Db::name('profit_pay')->insert([
|
||
'user_id' => $user_id,
|
||
'order_num' => $order_num,
|
||
'change_money' => $price,
|
||
'content' => '购买盒子' . $orderInfo['goods_title'],
|
||
'pay_type' => $payment_type == 'alipay' ? 2 : 1,
|
||
'addtime' => time(),
|
||
]);
|
||
}
|
||
|
||
if (resCheck($res)) {
|
||
Db::commit();
|
||
writelog('pay_notify_success', "支付成功处理完成: " . $order_num);
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 1, '支付处理成功');
|
||
} else {
|
||
Db::rollback();
|
||
writelog('pay_notify_error', "支付处理失败,可能存在业务逻辑错误: " . $order_num);
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '支付处理失败,业务逻辑错误');
|
||
}
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
writelog('pay_notify_error', "支付处理异常: " . $e->getMessage() . ", 订单号: " . $order_num);
|
||
|
||
try {
|
||
// 标记订单为卡单状态
|
||
if ($order_type == 'order_list_send') {
|
||
OrderListSend::where(['send_num' => $order_num])->update(['kd_is' => 1]);
|
||
} else {
|
||
Order::where(['order_num' => $order_num])->update(['kd_is' => 1]);
|
||
}
|
||
|
||
\app\common\model\OrderNotify::updateStatus($orderNotify['id'], 2, '支付处理异常: ' . $e->getMessage());
|
||
} catch (\Exception $ex) {
|
||
writelog('pay_notify_error', "更新卡单状态异常: " . $ex->getMessage());
|
||
}
|
||
}
|
||
|
||
// 无论处理结果如何,都释放锁并返回成功,避免重复通知
|
||
$redis->del($lockKey);
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功
|
||
} catch (\Exception $e) {
|
||
// 处理外层异常(如锁获取失败等)
|
||
writelog('pay_notify_error', "处理订单异常: " . $e->getMessage() . ", 订单号: " . $order_num);
|
||
$this->CallbackSuccess_new($payment_type); // 返回成功避免重复通知
|
||
|
||
}
|
||
}
|
||
|
||
public function test_notify_url()
|
||
{
|
||
// 测试生成支付通知URL
|
||
$payment_type = 'wxpay';
|
||
$order_type = 'order_wxs';
|
||
$user_id = 123;
|
||
$order_num = 'MH_' . date('YmdHis') . random_int(1000, 9999);
|
||
$nonce_str = getRandStr(16);
|
||
|
||
try {
|
||
// 生成URL
|
||
$notify_url = generatePayNotifyUrl($payment_type, $order_type, $user_id, $order_num, $nonce_str);
|
||
|
||
// 解析URL以提取参数和签名
|
||
$url_parts = parse_url($notify_url);
|
||
$path_parts = explode('/', trim($url_parts['path'], '/'));
|
||
|
||
// 路径格式应该是: notify/payment_type/order_type/user_id/order_num/timestamp/sign
|
||
$extracted_payment_type = $path_parts[1] ?? '';
|
||
$extracted_order_type = $path_parts[2] ?? '';
|
||
$extracted_user_id = $path_parts[3] ?? '';
|
||
$extracted_order_num = $path_parts[4] ?? '';
|
||
$extracted_timestamp = $path_parts[5] ?? '';
|
||
$extracted_sign = $path_parts[6] ?? '';
|
||
|
||
// 重新构建验证数据
|
||
$verify_data = [
|
||
'payment_type' => $extracted_payment_type,
|
||
'order_type' => $extracted_order_type,
|
||
'user_id' => $extracted_user_id,
|
||
'order_num' => $extracted_order_num,
|
||
'timestamp' => $extracted_timestamp,
|
||
'nonce_str' => $nonce_str
|
||
];
|
||
|
||
// 验证签名
|
||
$is_valid = verifyPayNotifySign($verify_data, $extracted_sign);
|
||
|
||
// 返回测试结果
|
||
return json([
|
||
'original' => [
|
||
'payment_type' => $payment_type,
|
||
'order_type' => $order_type,
|
||
'user_id' => $user_id,
|
||
'order_num' => $order_num,
|
||
'nonce_str' => $nonce_str
|
||
],
|
||
'generated_url' => $notify_url,
|
||
'extracted' => [
|
||
'payment_type' => $extracted_payment_type,
|
||
'order_type' => $extracted_order_type,
|
||
'user_id' => $extracted_user_id,
|
||
'order_num' => $extracted_order_num,
|
||
'timestamp' => $extracted_timestamp,
|
||
'sign' => $extracted_sign
|
||
],
|
||
'is_valid' => $is_valid,
|
||
'message' => '支付通知URL测试成功'
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return json([
|
||
'error' => $e->getMessage(),
|
||
'message' => '生成支付通知URL失败,请确保提供了所有必要参数'
|
||
]);
|
||
}
|
||
}
|
||
|
||
} |