调整活动红包发放策略

This commit is contained in:
luofei 2024-01-21 10:56:27 +08:00
parent 5c528703c8
commit a642abe2da
3 changed files with 68 additions and 29 deletions

View File

@ -3,6 +3,8 @@
namespace app\common\dao\store;
use app\common\dao\BaseDao;
use app\common\model\store\consumption\StoreConsumptionDetail;
use app\common\model\store\consumption\StoreConsumptionUser;
use app\common\model\store\StoreActivityOrder;
class StoreActivityOrderDao extends BaseDao
@ -19,7 +21,7 @@ class StoreActivityOrderDao extends BaseDao
* @param int $spreadId 推荐人id
* @param int $isFirstOrder 是否首单
* @param int $activityId 活动id
* @return void
* @return StoreActivityOrder
* @throws \Exception
*/
public function save($groupOrder, int $spreadId, int $isFirstOrder, int $activityId = 1)
@ -29,11 +31,25 @@ class StoreActivityOrderDao extends BaseDao
$model->user_id = $groupOrder['uid'];
$model->group_order_id = $groupOrder['group_order_id'];
$model->spread_id = $spreadId;
$model->total_amount = $groupOrder['pay_price'];
$model->pay_price = $groupOrder['pay_price'];
$model->is_first_order = $isFirstOrder;
$consumptionDetail = StoreConsumptionDetail::where('group_order_id', $groupOrder['group_order_id'])
->field('group_order_id,sum(amount) amount,sum(pay_price) pay_price,coupon_user_id')
->find();
if (!empty($consumptionDetail['amount'])) {
// 当前订单使用现金抵扣红包 或 使用通用红包后采购金额不足红包金额的2.5倍,视为无效订单
$redPackType = StoreConsumptionUser::where('coupon_id', $consumptionDetail['coupon_user_id'])->value('type');
if ($redPackType == StoreConsumptionUser::TYPE_TWO || $consumptionDetail['pay_price'] < $consumptionDetail['amount'] * 1.5) {
$model->status = StoreActivityOrder::STATUS_INVALID;
}
$model->red_pack = $consumptionDetail['amount'];
} else {
$model->red_pack = 0;
}
if (!$model->save()) {
throw new \Exception('活动订单保存失败');
}
return $model;
}
/**

View File

@ -158,7 +158,7 @@ class StoreActivityUserDao extends BaseDao
}
$userConsumption->status = StoreConsumptionUser::STATUS_UNUSED;
$userConsumption->start_time = date('Y-m-d H:i:s', time() + 7 * 86400);
$userConsumption->end_time = date('Y-m-d H:i:s', time() + 7 * 86400 + 365 * 86400);
$userConsumption->end_time = '2026-01-15 23:59:59';
if (!$userConsumption->save()) {
throw new \Exception('领取出错,请稍后重试');
}

View File

@ -10,11 +10,14 @@ use app\common\model\store\consumption\StoreConsumptionUser;
use app\common\model\store\order\StoreGroupOrder;
use app\common\model\store\StoreActivityOrder;
use app\common\model\user\User;
use app\common\repositories\user\UserBillRepository;
use think\facade\Db;
class StoreConsumptionUserDao extends BaseDao
{
public $maxAmount = 20000;
protected function getModel(): string
{
return StoreConsumptionUser::class;
@ -59,7 +62,8 @@ class StoreConsumptionUserDao extends BaseDao
return false;
}
$endTime = strtotime('+1 year', $activityUser['create_time']);
$scope = $this->getScope($consumption, $groupOrder['pay_price']);
$orderValidAmount = min($groupOrder['pay_price'], $this->maxAmount);
$scope = $this->getScope($consumption, $orderValidAmount);
//用户没有达到 消费金活动 任一档次
if ($scope['rate'] <= 0) {
return false;
@ -68,9 +72,10 @@ class StoreConsumptionUserDao extends BaseDao
try {
$isFirstOrder = $this->isFirstOrder($userId, $consumption['start_time'], $endTime);
$storeActivityOrderDao = new StoreActivityOrderDao();
$storeActivityOrderDao->save($groupOrder, $spreadUserId, $isFirstOrder);
if ($consumption['type'] == StoreConsumption::TYPE_OWNER_CONSUMPTION) {
$this->send($consumption, $scope['rate'], $userId, $groupOrder['group_order_id'], $groupOrder['pay_price'], StoreConsumptionUser::STATUS_UNUSED);
$storeActivityOrder = $storeActivityOrderDao->save($groupOrder, $spreadUserId, $isFirstOrder);
if ($consumption['type'] == StoreConsumption::TYPE_OWNER_CONSUMPTION && $storeActivityOrder['status'] == StoreActivityOrder::STATUS_VALID) {
$this->send($consumption, $scope['rate'], $userId, $groupOrder['group_order_id'], $orderValidAmount, StoreConsumptionUser::STATUS_UNUSED);
$this->send($consumption, $scope['rate_two'], $userId, $groupOrder['group_order_id'], $orderValidAmount, StoreConsumptionUser::STATUS_UNUSED, StoreConsumptionUser::TYPE_TWO);
$storeActivityOrderDao->repeal($groupOrder['group_order_id']);
}
Db::commit();
@ -96,14 +101,16 @@ class StoreConsumptionUserDao extends BaseDao
$spreadActivityUser = (new StoreActivityUserDao())->getOne($spreadUserId);
$spreadConsumption = (new StoreConsumptionDao())->getOne($spreadActivityUser['value'] ?? 0);
// 查询推荐人满足条件的有效订单
$spreadGroupOrderId = StoreActivityOrder::where('user_id', $spreadUserId)->where('status', StoreActivityOrder::STATUS_VALID)->value('group_order_id');
$spreadGroupOrder = StoreGroupOrder::where('group_order_id', $spreadGroupOrderId)->where('paid', 1)->find();
$spreadGroupOrder = StoreActivityOrder::where('user_id', $spreadUserId)->where('status', StoreActivityOrder::STATUS_VALID)->find();
if (empty($spreadGroupOrder) || empty($spreadConsumption['config']) || empty($spreadActivityUser) || strtotime('+1 year', $spreadActivityUser['create_time']) < time()) {
// 推荐人消费金数据为空 或 推荐人的有效订单为空 或推荐人已超过任务完成时间,作为发起人参加活动
return $this->promoter($userId, $groupOrder, 0);
}
$endTime = strtotime('+1 year', $spreadActivityUser['create_time']);
$spreadScope = $this->getScope($spreadConsumption, $spreadGroupOrder['pay_price']);
// 订单有效金额为实付金额+红包金额
$orderValidAmount = bcadd($spreadGroupOrder['pay_price'], $spreadGroupOrder['red_pack'], 2);
$orderValidAmount = min($orderValidAmount, $this->maxAmount);
$spreadScope = $this->getScope($spreadConsumption, $orderValidAmount);
if ($groupOrder['pay_price'] < $spreadScope['start']) {
// 当前用户的订单不在推荐人的档位区间,作为发起人参加活动
return $this->promoter($userId, $groupOrder, 0);
@ -112,13 +119,13 @@ class StoreConsumptionUserDao extends BaseDao
try {
$isFirstOrder = $this->isFirstOrder($userId, $spreadConsumption['start_time'], $endTime);
$storeActivityOrderDao = new StoreActivityOrderDao();
$storeActivityOrderDao->save($groupOrder, $spreadUserId, $isFirstOrder);
if ($spreadConsumption['type'] == StoreConsumption::TYPE_PULL_CONSUMPTION && $isFirstOrder) {
$storeActivityOrder = $storeActivityOrderDao->save($groupOrder, $spreadUserId, $isFirstOrder);
if ($spreadConsumption['type'] == StoreConsumption::TYPE_PULL_CONSUMPTION && $isFirstOrder && $storeActivityOrder['status'] == StoreActivityOrder::STATUS_VALID) {
// 推荐人消费金类型为拉新且当前用户为首单
$spreadOrderIds = $this->isFinished($spreadUserId, $spreadScope);
if ($spreadOrderIds !== false) {
$spreadOrderIds = "{$spreadGroupOrder['group_order_id']}," . $spreadOrderIds;
$this->send($spreadConsumption, $spreadScope['rate'], $spreadUserId, $spreadOrderIds, $spreadGroupOrder['total_amount']);
$this->send($spreadConsumption, $spreadScope['rate'], $spreadUserId, $spreadOrderIds, bcmul($orderValidAmount, 0.8, 2));
$storeActivityOrderDao->batchRepeal(explode(',', $spreadOrderIds));
}
}
@ -138,9 +145,6 @@ class StoreConsumptionUserDao extends BaseDao
{
$scope = [];
foreach ($consumption['config'] as $k => $item) {
if (($k + 1) == count($consumption['config'])) {
$item['end'] = 100000000;
}
if ($item['start'] <= $amount && $item['end'] >= $amount) {
$item['rate'] = bcdiv($item['rate'], 100, 2);
$scope = $item;
@ -186,27 +190,46 @@ class StoreConsumptionUserDao extends BaseDao
* @param string $groupOrderIds 订单id集合
* @param float $amount 订单金额
* @param float $status 红包领取状态
* @param int $type 红包类型
* @return void
* @throws \Exception
*/
public function send($consumption, float $rate, int $userId, string $groupOrderIds, float $amount, $status = -2, $type = 1)
{
$model = new StoreConsumptionUser();
$model->coupon_id = $consumption['coupon_id'];
$model->uid = $userId;
$model->coupon_title = $consumption['title'];
$model->order_id_set = $groupOrderIds;
$model->coupon_price = bcmul($amount, $rate, 2);
$model->balance = $model->coupon_price;
$model->order_amount = $amount;
$model->create_time = date('Y-m-d H:i:s');
$model->start_time = date('Y-m-d H:i:s', time() + 7 * 86400);
$model->end_time = date('Y-m-d H:i:s', time() + 7 * 86400 + 365 * 86400);
$model->type = $type;
$model->status = $status;
$model = StoreConsumptionUser::where('uid', $userId)->where('type', StoreConsumptionUser::TYPE_TWO)->find();
$couponPrice = bcmul($amount, $rate, 2);
if (!empty($model) && $model['type'] == $type) {
$model->coupon_price = bcadd($model->coupon_price, $couponPrice, 2);
$model->balance = bcadd($model->balance, $couponPrice, 2);
} else {
$model = new StoreConsumptionUser();
$model->coupon_id = $consumption['coupon_id'];
$model->uid = $userId;
$model->coupon_title = $consumption['title'];
$model->order_id_set = $groupOrderIds;
$model->coupon_price = $couponPrice;
$model->balance = $model->coupon_price;
$model->order_amount = $amount;
$model->create_time = date('Y-m-d H:i:s');
$model->start_time = date('Y-m-d H:i:s', time() + 7 * 86400);
$model->end_time = '2026-01-15 23:59:59';
$model->type = $type;
$model->status = $status;
}
if (!$model->save()) {
throw new \Exception('发放失败');
}
// 写入红包日志
/** @var $userBillRepository UserBillRepository */
$userBillRepository = app()->make(UserBillRepository::class);
$userBillRepository->incBill($userId, 'red_pack', "red_pack_{$type}", [
'link_id' => $model['coupon_user_id'],
'status' => 1,
'title' => '获得现金抵扣红包',
'number' => $couponPrice,
'mark' => '获得现金抵扣红包' . $couponPrice,
'balance' => 0
]);
}
/**