document/公司/工作/友达/Untitled-1.txt
2025-05-18 15:14:53 +08:00

372 lines
14 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
class OrderController extends Controller
{
/**
* 下单计算金额
*/
public function infinite_ordermoney()
{
$user = $this->getUser();
$params = $this->getRequestParams();
$goods = $this->getGoods($params['goods_id']);
if (!$goods || $goods['status'] != 1) return $this->renderError("盒子不存在或已下架");
$goodsExtend = GoodsExtend::getGoodsExtendByGoodsId($goods['id'], $goods['type']);
if (!$goodsExtend) return $this->renderError("盒子类型配置不存在");
if (($res = $this->checkGlobalLimit($goods, $user['id'], $params['prize_num'])) !== true) return $res;
if (($res = $this->checkDailyLimit($goods, $user['id'], $params['prize_num'])) !== true) return $res;
if (($res = $this->checkConsumptionLimit($goods, $user)) !== true) return $res;
$priceInfo = $this->calculatePriceInfo($goods, $goodsExtend, $user, $params);
return $this->renderSuccess("请求成功", $priceInfo);
}
/**
* 下单
*/
public function infinite_orderbuy()
{
$user = $this->getUser();
if (empty($user['mobile'])) return $this->renderError('请先绑定手机号', [], -9);
$params = $this->getRequestParams();
$goods = $this->getGoods($params['goods_id']);
if (!$goods || $goods['status'] != 1) return $this->renderError("盒子不存在或已下架");
$goodsExtend = GoodsExtend::getGoodsExtendByGoodsId($goods['id'], $goods['type']);
if (!$goodsExtend) return $this->renderError("盒子类型配置不存在");
if (!in_array($goods['type'], [2, 8, 9, 10, 16, 17])) return $this->renderError("非法请求");
if (($res = $this->checkGlobalLimit($goods, $user['id'], $params['prize_num'])) !== true) return $res;
if (($res = $this->checkDailyLimit($goods, $user['id'], $params['prize_num'])) !== true) return $res;
if (($res = $this->checkConsumptionLimit($goods, $user)) !== true) return $res;
if (!$this->checkGoodsPrize($goods, $params)) return $this->renderError('暂无奖品信息');
$priceInfo = $this->calculatePriceInfo($goods, $goodsExtend, $user, $params);
if (!$this->acquireLock($user['id'])) return $this->renderError("当前操作太快了,请等待");
$orderResult = $this->createOrderAndPay($user, $goods, $params, $priceInfo);
$this->releaseLock($user['id']);
return $orderResult;
}
// ================= 工具方法 =================
private function getRequestParams()
{
return [
'goods_id' => request()->param('goods_id/d', 0),
'prize_num' => request()->param('prize_num/d', 0),
'use_money_is' => request()->param('use_money_is/d', 0),
'use_integral_is' => request()->param('use_integral_is/d', 0),
'use_money2_is' => request()->param('use_money2_is/d', 0),
'coupon_id' => request()->param('coupon_id'),
'is_mibao' => request()->param('is_mibao/d', 0),
'ad_id' => request()->header('adid'),
];
}
private function getGoods($goodsId)
{
return Goodsmodel::field('id,title,imgurl_detail,type,price,status,is_shou_zhe,choujiang_xianzhi,quanju_xiangou,daily_xiangou')
->where(['id' => $goodsId])->find();
}
private function checkGlobalLimit($goods, $userId, $buyCount)
{
if ($goods['quanju_xiangou'] <= 0) return true;
$userCount = OrderList::where('goods_id', $goods['id'])
->where('user_id', $userId)->where('parent_goods_list_id', 0)->count();
if ($userCount >= $goods['quanju_xiangou']) {
return $this->renderError("当前限购{$goods['quanju_xiangou']}次");
}
if ($userCount + $buyCount > $goods['quanju_xiangou']) {
$allow = $goods['quanju_xiangou'] - $userCount;
return $this->renderError("购买超出限制,还允许购买{$allow}次");
}
return true;
}
private function checkDailyLimit($goods, $userId, $buyCount)
{
if ($goods['daily_xiangou'] <= 0) return true;
$todayMidnight = strtotime('today');
$userTodayCount = OrderList::where('goods_id', $goods['id'])
->where('user_id', $userId)
->where('parent_goods_list_id', 0)
->where('addtime', '>=', $todayMidnight)
->count();
if ($userTodayCount >= $goods['daily_xiangou']) {
return $this->renderError("今日限购{$goods['daily_xiangou']}次");
}
if ($userTodayCount + $buyCount > $goods['daily_xiangou']) {
$allow = $goods['daily_xiangou'] - $userTodayCount;
return $this->renderError("购买超出限制,今日还允许购买{$allow}次");
}
return true;
}
private function checkConsumptionLimit($goods, $user)
{
if (empty($goods['choujiang_xianzhi']) || $goods['choujiang_xianzhi'] <= 0) return true;
$userId = $user['id'];
$userPrice = Order::where('user_id', $userId)->where('status', 1)->sum('price');
if ($userPrice < $goods['choujiang_xianzhi']) {
if ($user['istest'] > 0) {
$userPrice = Order::where('user_id', $userId)->where('status', 1)->sum('order_zhe_total');
}
if ($userPrice < $goods['choujiang_xianzhi']) {
return $this->renderError("消费满{$goods['choujiang_xianzhi']}元可参与 已消费" . round($userPrice, 2) . "元");
}
}
return true;
}
private function checkGoodsPrize($goods, $params)
{
$where = [['goods_id', '=', $goods['id']]];
if ($goods['type'] == 10) {
$where[] = ['shang_id', 'between', [10, 33]];
$where[] = ['num', '=', 1];
} else {
$where[] = ['num', '=', 0];
$where[] = ['real_pro', '>', 0];
$where[] = ['shang_id', 'between', self::$shang_prize_id];
}
if ($goods['type'] == 9 && $params['is_mibao'] == 1) {
$where[] = ['lian_ji_type', '=', 1];
}
return GoodsList::where($where)->find();
}
private function acquireLock($userId)
{
$redis = (new \app\common\server\RedisHelper())->getRedis();
$key = "kpw_infinite_orderbuy_{$userId}";
if ($redis->get($key)) return false;
$redis->set($key, 1, 3);
return true;
}
private function releaseLock($userId)
{
$redis = (new \app\common\server\RedisHelper())->getRedis();
$key = "kpw_infinite_orderbuy_{$userId}";
$redis->del($key);
}
/**
* 金额计算逻辑,包括首抽折扣、优惠券、三种抵扣方式
*/
private function calculatePriceInfo($goods, $goodsExtend, $user, $params)
{
$prizeNum = intval($params['prize_num']);
$boxPrice = $goods['price'];
// 首抽五折逻辑
$shouZhePrice = 0;
if (!in_array($goods['type'], [5, 10])) {
$isChou = Order::where([['user_id', '=', $user['id']], ['status', '=', 1]])->find();
$isChou2 = Order::where([['is_shou_zhe', '=', 1], ['status', '=', 1], ['user_id', '=', $user['id']]])->find();
if (!$isChou && !$isChou2 && $goods['is_shou_zhe'] == 1) {
$shouZhePrice = bcmul((string)$boxPrice, '0.5', 2);
}
}
$goods['shou_zhe_price'] = $shouZhePrice;
// 初始总价
$price = bcmul((string)$boxPrice, (string)$prizeNum, 2);
$price = bcsub($price, (string)$shouZhePrice, 2);
$orderTotal = $orderZheTotal = $price;
// 抵扣处理
$useMoney = 0;
$useIntegral = 0;
$useMoney2 = 0;
$couponPrice = 0;
$zhe = 0;
$iszhifu = 0;
// 优惠券抵扣
if ($shouZhePrice <= 0 && !empty($params['coupon_id']) && $goodsExtend['pay_coupon'] == 1) {
$coupon = CouponReceiveModel::where([
'id' => $params['coupon_id'],
'status' => 0,
'user_id' => $user['id']
])->where('man_price', '<=', $price)->where('end_time', '>', time())->find();
if ($coupon) {
$couponPrice = $coupon['price'];
$price = bcsub($price, (string)$couponPrice, 2);
}
}
if ($price < 0) $price = '0.00';
$orderZheTotal = $price;
// 余额抵扣
if ($params['use_money_is'] == 1 && $goodsExtend['pay_balance'] == 1) {
if ($goodsExtend['is_deduction'] == 1) {
$useMoney = min($user['money'], $price);
$price = bcsub($price, (string)$useMoney, 2);
} else if ($user['money'] >= $price) {
$useMoney = $price;
$price = '0.00';
$iszhifu++;
} else {
return $this->renderError('金额不足');
}
}
// 积分抵扣1:100
if ($params['use_integral_is'] == 1 && $goodsExtend['pay_currency'] == 1) {
$priceInIntegral = bcmul($price, '100', 0);
if ($goodsExtend['is_deduction'] == 1) {
$useIntegral = min($user['integral'], $priceInIntegral);
$price = bcsub($price, bcdiv((string)$useIntegral, '100', 2), 2);
} else if ($user['integral'] >= $priceInIntegral) {
$useIntegral = $priceInIntegral;
$price = '0.00';
$iszhifu++;
} else {
return $this->renderError('金额不足');
}
}
// 货币2抵扣
if ($params['use_money2_is'] == 1 && $goodsExtend['pay_currency2'] == 1) {
$priceInCurrency2 = bcmul($price, '100', 0);
if ($goodsExtend['is_deduction'] == 1) {
$useMoney2 = min($user['money2'] ?? 0, $priceInCurrency2);
$price = bcsub($price, bcdiv((string)$useMoney2, '100', 2), 2);
} else if (($user['money2'] ?? 0) >= $priceInCurrency2) {
$useMoney2 = $priceInCurrency2;
$price = '0.00';
$iszhifu++;
} else {
return $this->renderError('金额不足');
}
}
// 支付方式校验
if ($goodsExtend['is_deduction'] == 0 && $iszhifu == 0 && $goodsExtend['pay_wechat'] == 0) {
return $this->renderError('请选择支付方式');
}
return [
'goods' => $goods,
'order_total' => round(floatval($orderTotal), 2),
'order_zhe_total' => round($orderZheTotal, 2),
'zhe' => round($zhe, 2),
'price' => round($price, 2),
'integral' => round($user['integral'], 2),
'use_integral' => round($useIntegral, 2),
'use_integral_money' => round($useIntegral / 100, 2),
'money' => round($user['money'], 2),
'use_money' => round($useMoney, 2),
'score' => $user['money2'] ?? 0,
'use_score' => $useMoney2,
'coupon_id' => $params['coupon_id'] ?? 0,
'coupon_price' => round($couponPrice, 2),
'goods_extend' => $goodsExtend,
'prize_num' => $prizeNum
];
}
private function createOrderAndPay($user, $goods, $params, $priceInfo)
{
Db::startTrans();
try {
$num = ($goods['type'] == 10) ? 1 : 0;
$orderNum = create_order_no('MH_', 'order', 'order_num');
$orderId = Order::insertGetId([
'user_id' => $user['id'],
'order_num' => $orderNum,
'order_total' => $priceInfo['order_total'],
'order_zhe_total' => $priceInfo['order_zhe_total'],
'price' => $priceInfo['price'],
'use_money' => $priceInfo['use_money'],
'use_integral' => $priceInfo['use_integral'],
'use_money2' => $priceInfo['use_score'],
'use_score' => 0,
'zhe' => $priceInfo['zhe'],
'goods_id' => $goods['id'],
'num' => $num,
'goods_price' => $goods['price'],
'goods_title' => $goods['title'],
'goods_imgurl' => $goods['imgurl_detail'],
'prize_num' => $params['prize_num'],
'status' => 0,
'pay_type' => 1,
'order_type' => $goods['type'],
'addtime' => time(),
'coupon_id' => $priceInfo['coupon_id'],
'use_coupon' => $priceInfo['coupon_price'],
'is_mibao' => $params['is_mibao'],
'is_shou_zhe' => $goods['shou_zhe_price'] > 0 ? 1 : 0,
'ad_id' => $params['ad_id'],
'click_id' => $user['click_id'] ?? ''
]);
// 是否需要支付
if ($priceInfo['price'] > 0) {
$body = '购买盒子' . $goods['title'];
$attach = $goods['type'] == 16 ? 'order_fbs' : 'order_wxs';
$payRes = (new Pay())->wxCreateOrder($orderNum, $priceInfo['price'], $user['openid'], $body, $attach);
if ($payRes['status'] != 1) {
Db::rollback();
return $this->renderError('下单失败');
}
Db::commit();
return $this->renderSuccess('下单成功', [
'status' => 1,
'order_num' => $orderNum,
'res' => $payRes['data']
]);
} else {
// 0元单直接开奖
$res = (new Notify($this->app))->infinite_drawprize_notice($user['id'], $orderId, $goods['id'], $num);
if (!$res) {
Db::rollback();
return $this->renderError('开奖失败');
}
Db::commit();
return $this->renderSuccess('下单成功', [
'status' => 0,
'order_num' => $orderNum
]);
}
} catch (\Throwable $e) {
Db::rollback();
return $this->renderError('系统异常: ' . $e->getMessage());
}
}
}