350 lines
14 KiB
PHP
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' => '验证通过'];
|
|
}
|
|
} |