manghe/app/common/service/PaymentCalculator.php
2025-04-13 21:57:55 +08:00

350 lines
14 KiB
PHP

<?php
namespace app\common\service;
use app\common\model\Goods as GoodsModel;
use app\common\model\Order;
use app\common\model\GoodsExtend;
use app\common\model\CouponReceive as CouponReceiveModel;
/**
* 支付计算服务类
* 用于处理订单金额计算、支付方式与抵扣逻辑
*/
class PaymentCalculator
{
/**
* 计算订单金额
*
* @param array $user 用户信息
* @param int $goods_id 盒子ID
* @param int $prize_num 抽奖数量
* @param int $use_money_is 是否使用余额
* @param int $use_integral_is 是否使用货币1
* @param int $use_money2_is 是否使用货币2
* @param int $coupon_id 优惠券ID
* @param array $goods 盒子信息(可选,如不传则会从数据库获取)
* @param array $goodsExtend 盒子扩展信息(可选,如不传则会从数据库获取)
* @return array 计算结果数组
*/
public function calculateOrderAmount($user, $goods_id, $prize_num, $use_money_is = 0, $use_integral_is = 0, $use_money2_is = 0, $coupon_id = 0, $goods = null, $goodsExtend = null)
{
// 如果未传入盒子信息,则从数据库获取
if (!$goods) {
$goods = GoodsModel::field('id,title,imgurl_detail,type,price,status,is_shou_zhe,quanju_xiangou,daily_xiangou,choujiang_xianzhi')
->where(['id' => $goods_id])
->find();
if (!$goods) {
return ['status' => 0, 'msg' => '盒子不存在'];
}
if ($goods['status'] != 1) {
return ['status' => 0, 'msg' => '盒子已下架'];
}
}
// 获取盒子类型
$goods_type = $goods['type'];
// 如果未传入扩展信息,则从数据库获取
if (!$goodsExtend) {
$goodsExtend = GoodsExtend::getGoodsExtendByGoodsId($goods_id, $goods_type);
if (!$goodsExtend) {
return ['status' => 0, 'msg' => '盒子类型配置不存在'];
}
}
// 处理图片URL
$goods['imgurl_detail'] = imageUrl($goods['imgurl_detail']);
// 盒子单价
$box_price = $goods['price'];
// 首抽五折处理
$shou_zhe_price = 0;
if ($goods['type'] != 5 && $goods_type != 10 && $goods_type != 15) {
$is_chou = Order::field('id')->where([['user_id', '=', $user['id']], ['status', '=', 1]])->find();
$is_chou2 = Order::field('id')->where([['is_shou_zhe', '=', 1], ['status', '=', 1], ['user_id', '=', $user['id']]])->find();
if (!$is_chou && !$is_chou2 && $goods['is_shou_zhe'] == 1) {
$shou_zhe_price = bcmul("$box_price", "0.5", 2);
}
}
// 计算总价
$goods['shou_zhe_price'] = $shou_zhe_price;
$price = bcmul("$box_price", "$prize_num", 2);
$price = bcsub("$price", "$shou_zhe_price", 2);
// 订单金额
$order_total = $order_zhe_total = $price;
// 初始化变量
$coupon_price = 0;
$use_money = 0; // 余额抵扣
$use_integral = 0; // 货币1抵扣
$use_money2 = 0; // 货币2抵扣
$zhe = 0; // 会员折扣
$daily_coupon_limit = \app\common\helper\ConfigHelper::getAppSettingKey("daily_coupon_limit");
// 优惠券处理
if ($shou_zhe_price <= 0 && !empty($coupon_id) && $goodsExtend['pay_coupon'] == 1) {
//是否限制每日优惠券次数
$is_daily_coupon = true;
if ($daily_coupon_limit > 0) {
$today_start = strtotime(date('Y-m-d 00:00:00', time()));
$today_end = strtotime(date('Y-m-d 23:59:59', time()));
$today_count = CouponReceiveModel::where('user_id', '=', $user['id'])
->where('addtime', '>=', $today_start)
->where('addtime', '<=', $today_end)
->where('status', '=', 1)
->count();
if ($today_count >= $daily_coupon_limit) {
// return ['status' => 0, 'msg' => '今日优惠券次数已达上限'];
$is_daily_coupon = false;
}
}
if ($is_daily_coupon) {
// 获取优惠券信息
$coupon = CouponReceiveModel::where([
'id' => $coupon_id,
'status' => 0,
'user_id' => $user['id']
])->where('man_price', '<=', $price)
->where('end_time', '>', time()) // 确保优惠券未过期
->find();
if ($coupon) {
$coupon_price = $coupon['price'];
} else {
$coupon_id = 0;
}
} else {
$coupon_id = 0;
}
} else {
$coupon_id = 0;
}
$price = bcsub("$price", "$coupon_price", 2);
if ($price <= 0) {
$price = 0;
}
$order_zhe_total = $price;
// 如果不是首抽五折,处理各种支付抵扣
if ($shou_zhe_price <= 0) {
$iszhifu = 0;
// 余额抵扣
if ($use_money_is == 1 && $goodsExtend['pay_balance'] == 1) {
if ($goodsExtend['is_deduction'] == 1) {
// 抵扣模式
if ($user['money'] >= $price) {
$use_money = $price;
$price = 0;
} else {
$use_money = $user['money'];
$price = bcsub("$price", "$use_money", 2);
}
} else {
// 支付模式
if ($user['money'] >= $price) {
$use_money = $price;
$price = 0;
$iszhifu++;
} else {
// 支付模式下余额不足无法抵扣
$use_money = 0;
return ['status' => 0, 'msg' => '金额不足'];
}
}
}
// 货币1抵扣
if ($use_integral_is == 1 && $goodsExtend['pay_currency'] == 1) {
$price_in_currency = $price * 100; // 1:100比例
if ($goodsExtend['is_deduction'] == 1) {
// 抵扣模式
if ($user['integral'] >= $price_in_currency) {
$use_integral = $price_in_currency;
$price = 0;
} else {
$use_integral = $user['integral'];
$price = bcsub("$price", bcdiv("$use_integral", "100", 2), 2);
}
} else {
// 支付模式
if ($user['integral'] >= $price_in_currency) {
$use_integral = $price_in_currency;
$price = 0;
$iszhifu++;
} else {
// 支付模式下货币不足无法抵扣
$use_integral = 0;
return ['status' => 0, 'msg' => '金额不足'];
}
}
}
// 货币2抵扣
if ($use_money2_is == 1 && $goodsExtend['pay_currency2'] == 1) {
$price_in_currency2 = $price * 100; // 1:100比例
if ($goodsExtend['is_deduction'] == 1) {
// 抵扣模式
if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) {
$use_money2 = $price_in_currency2;
$price = 0;
} else if (isset($user['money2'])) {
$use_money2 = $user['money2'];
$price = bcsub("$price", bcdiv("$use_money2", "100", 2), 2);
}
} else {
// 支付模式
if (isset($user['money2']) && $user['money2'] >= $price_in_currency2) {
$use_money2 = $price_in_currency2;
$price = 0;
$iszhifu++;
} else {
// 支付模式下货币2不足无法抵扣
$use_money2 = 0;
return ['status' => 0, 'msg' => '金额不足'];
}
}
}
// 如果是支付模式但未选择任何支付方式
if ($goodsExtend['is_deduction'] == 0 && $iszhifu == 0 && $goodsExtend['pay_wechat'] == 0) {
return ['status' => 0, 'msg' => '请选择支付方式'];
}
}
// 设置抽奖数量
$goods['prize_num'] = $prize_num;
// 组装返回数据
$data = [
'status' => 1,
'goods' => $goods,
'order_total' => round(floatval($order_total), 2),
'order_zhe_total' => round($order_zhe_total, 2),
'zhe' => round($zhe, 2),
'price' => round($price, 2),
'integral' => round($user['integral'], 2),
'use_integral' => round($use_integral, 2),
'use_integral_money' => round(round($use_integral, 2) / 100, 2),
'money' => round($user['money'], 2),
'use_money' => round($use_money, 2),
'score' => isset($user['money2']) ? $user['money2'] : 0,
'use_score' => $use_money2,
'coupon_id' => $coupon_id,
'coupon_price' => round($coupon_price, 2),
'goods_extend' => $goodsExtend,
'use_money2' => $use_money2,
'daily_coupon_limit' => $daily_coupon_limit
];
// 添加首抽五折状态
$data['is_shou_zhe'] = $shou_zhe_price > 0 ? 1 : 0;
return $data;
}
/**
* 验证抽奖限制
*
* @param array $user 用户信息
* @param array $goods 盒子信息
* @param int $prize_num 抽奖数量
* @return array 验证结果 ['status' => 0/1, 'msg' => '提示信息']
*/
public function validateDrawRestrictions($user, $goods, $prize_num)
{
// 验证抽奖门槛
$user_id = $user['id'];
$choujiang_xianzhi = $goods['choujiang_xianzhi'];
if ($choujiang_xianzhi && $choujiang_xianzhi > 0) {
// 验证福利屋活动
if ($goods['type'] == 15) {
// 获取用户在该福利屋活动期间的消费情况
$consumptionData = \app\common\service\CommonService::getUserConsumptionByTimeRange(
$user_id,
$goods['flw_start_time'],
$goods['flw_end_time']
);
if ($consumptionData['total_consumed'] < $choujiang_xianzhi) {
return [
'status' => 0,
'msg' => "需在指定时间" . date('Y-m-d H:i:s', $goods['flw_start_time']) . "-"
. date('Y-m-d H:i:s', $goods['flw_end_time']) . "消耗达到" . $choujiang_xianzhi
. "钻石,即可加入房间,还需" . round(($choujiang_xianzhi - $consumptionData['total_consumed']), 2) . "钻石."
];
}
} else {
// 常规消费验证
// $user_price = Order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('price');
// $user_price = Order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('order_zhe_total');
// if ($user_price < $choujiang_xianzhi) {
// if ($user['istest'] > 0) {
// $user_price = Order::where('user_id', '=', $user_id)->where('status', '=', 1)->sum('order_zhe_total');
// }
// if ($user_price < $choujiang_xianzhi) {
// return [
// 'status' => 0,
// 'msg' => "消费满" . $choujiang_xianzhi . "元可参与 已消费" . round($user_price, 2) . "元"
// ];
// }
// }
}
}
// 验证全局限购
if ($goods['quanju_xiangou'] > 0) {
$user_quanju_count = \app\common\model\OrderList::field('id')
->where('goods_id', '=', $goods['id'])
->where('user_id', '=', $user_id)
->where('parent_goods_list_id', '=', 0)
->count();
if ($user_quanju_count >= $goods['quanju_xiangou']) {
return ['status' => 0, 'msg' => '当前限购' . $goods['quanju_xiangou'] . '次'];
}
$now_prize_num = $prize_num + $user_quanju_count;
if ($now_prize_num > $goods['quanju_xiangou']) {
return [
'status' => 0,
'msg' => '购买超出限制,还允许购买' . ($goods['quanju_xiangou'] - $user_quanju_count) . '次'
];
}
}
// 验证每日限购
if ($goods['daily_xiangou'] > 0) {
$todayMidnight = strtotime('today');
$goods_id = $goods['id'];
$user_toDay_count = \app\common\model\OrderList::field('id')
->where('goods_id', '=', $goods['id'])
->where('user_id', '=', $user_id)
// ->where('parent_goods_list_id', '=', 0)
->where('addtime', '>=', $todayMidnight)
->count();
if ($user_toDay_count >= $goods['daily_xiangou']) {
return ['status' => 0, 'msg' => '今日限购' . $goods['daily_xiangou'] . '次'];
}
$now_prize_num = $prize_num + $user_toDay_count;
if ($now_prize_num > $goods['daily_xiangou']) {
return [
'status' => 0,
'msg' => '购买超出限制,今日还允许购买' . ($goods['daily_xiangou'] - $user_toDay_count) . '次'
];
}
}
return ['status' => 1, 'msg' => '验证通过'];
}
}