feat : coupon

This commit is contained in:
2025-03-19 11:23:54 +08:00
parent 67dc58e90b
commit 785d27fe7b
5 changed files with 329 additions and 136 deletions

View File

@@ -22,12 +22,6 @@ use Hyperf\Di\Annotation\Inject;
class HomePopupsService extends BaseService
{
/**
* @var CouponDispenseUser
*/
#[Inject]
protected CouponDispenseUser $couponDispenseUserModel;
/**
* @var CouponDispenseLog
*/
@@ -40,158 +34,211 @@ class HomePopupsService extends BaseService
#[Inject]
protected UserCoupon $userCouponModel;
/**
* @var array|array[]
*/
protected array $res = [
'can_receive_ids' => [],
'coupon_info' => []
];
/**
* @return array
*/
public function handle(): array
{
$dispenseIds = $this->couponDispenseUserModel->getNoReceiveCountByUserId($this->userId);
$data = $this->couponDispenseLogModel->getNoReceiveCount();
if (empty($dispenseIds) && empty($data['all']) && empty($data['appoint'])) return $this->returnNullRes();
$allDispenseIds = [];
if (!empty($data['all'])) {
$allDispenseIds = $this->userCouponModel->getReceiveCountByUserIds($this->userId,$data['all']);
}
if (empty($data)) return $this->return->success('success',$this->res);
$canReceive = array_unique(array_merge(
array_diff($data['all'], $allDispenseIds),
array_intersect($dispenseIds,$data['appoint'])
));
$allDispenseIds = $this->userCouponModel->getReceiveCountByUserIds($this->userId,$data);
if (empty($canReceive)) return $this->returnNullRes();
$canReceive = array_unique(array_diff($data,$allDispenseIds));
$res = $this->receive($canReceive);
if (empty($canReceive)) return $this->return->success('success',$this->res);
return $this->return->success('success',['coupon_data' => $res]);
$this->getInfo($canReceive);
return $this->return->success('success',$this->res);
}
/**
* @param array $data
* @return array
* @param array $canReceive
* @return void
*/
private function receive(array $data): array
private function getInfo(array $canReceive): void
{
$list = $this->couponDispenseLogModel->getListByIds($data);
if (empty($list)) return [];
$list = $this->couponDispenseLogModel->getListByIds($canReceive);
if (empty($list)) return;
$insertData = [];
$appointUpdateData = [];
$allUpdateData =[];
$destroyDispenseData = [];
$resCouponData = [];
foreach ($list as $item) {
$validityTime = [];
$endTime = null;
$validityValue = json_decode($item['validity_time_value'],true);
switch ($item['validity_time_type']) {
case CouponCode::VALIDITY_TIME_TYPE_CYCLE:
$validityValue = json_decode($item['validity_time_value'],true);
$validityTime = [
'start_time' => date('Y-m-d H:i:s'),
'end_time' => date('Y-m-d H:i:s', time() + ($validityValue['day_num'] * DateUtil::DAY))
];
$endTime = date('Y-m-d H:i:s', time() + ($validityValue['day_num'] * DateUtil::DAY));
break;
case CouponCode::VALIDITY_TIME_TYPE_FIX:
$validityTime = json_decode($item['validity_time_value'],true);
$endTime = $validityValue['end_time'] ?? null;
break;
}
//有效期不存在或者到期销毁当前分发逻辑
if (($validityTime['end_time'] ?? date('Y-m-d H:i:s')) < date('Y-m-d H:i:s')) {
if (($endTime ?? date('Y-m-d H:i:s')) < date('Y-m-d H:i:s')) {
$destroyDispenseData[] = $item['id'];
continue;
}
$oneData = [
'user_id' => $this->userId,
'coupon_template_id' => $item['coupon_template_id'],
'coupon_name' => $item['coupon_name'],
'coupon_dispense_id' => $item['id'],
'status' => CouponCode::COUPON_STATUS_UNUSED,
'validity_start_time' => $validityTime['start_time'] ?? date('Y-m-d H:i:s', time()),
'validity_end_time' => $validityTime['end_time'] ?? date('Y-m-d H:i:s', time()),
];
$copies = array_map(function () use ($oneData) {
return $oneData;
}, array_fill(0, $item['item_count'], null));
$insertData = array_merge($insertData, $copies);
$this->res['coupon_info'] = array_merge($this->res['coupon_info'], $copies);
$oneData['count'] = $item['item_count'];
if ($item['appoint_group'] != CouponCode::DISPENSE_APPOINT_GROUP_ALL_PEOPLE) {
$appointUpdateData[] = [
'coupon_dispense_id' => $item['id'],
// 'user_id' => $this->userId,
'receive_count' => $item['receive_count'],
'is_receive' => CouponCode::DISPENSE_STATUS_IS_RECEIVED
];
}
$allUpdateData[] = [
'id' => $item['id'],
'receive_count' => $item['receive_count'] +$item['item_count'],
];
$resCouponData[] = $oneData;
$this->res['can_receive_ids'][] = $item['id'];
}
if (empty($allUpdateData)) return [];
if (!empty($appointUpdateData)) {
$appointList = $this->couponDispenseUserModel->where('user_id',$this->userId)->whereIn('id',array_column($appointUpdateData,'coupon_dispense_id'))->pluck('id','coupon_dispense_id');
foreach ($appointUpdateData as &$item) {
$item['id'] = $appointList[$item['coupon_dispense_id']];
}
if (!empty($destroyDispenseData)) {
(new CouponDispenseLog)->whereIn('id',$destroyDispenseData)->update([
'status' => CouponCode::DISPENSE_NULL,
]);
}
Db::transaction(function () use($allUpdateData,$appointUpdateData,$insertData,$destroyDispenseData) {
$appointUpdateFlag = true;
if (!empty($appointUpdateData)) {
$userUpdateModel = new CouponDispenseUser();
foreach (array_chunk($appointUpdateData, 500) as $chunk) {
foreach ($chunk as $item) {
$appointUpdateFlag = $userUpdateModel
->where('id',$item['id'])
->update(array_diff_key($item, ['coupon_dispense_id' => null,'id' => null]));
if (!$appointUpdateFlag) break;
}
if (!$appointUpdateFlag) break;
}
// $appointUpdateFlag = (new CouponDispenseUser)->update($appointUpdateData);
}
$destroyDispenseFlag = true;
if (!empty($destroyDispenseData)) {
$destroyDispenseFlag = (new CouponDispenseLog)->whereIn('id',$destroyDispenseData)->update([
'status' => CouponCode::DISPENSE_NULL,
]);
}
// $allUpdateFlag = (new CouponDispenseLog)->update($allUpdateData);
$allUpdateFlag = true;
$updateModel = new CouponDispenseLog();
foreach (array_chunk($allUpdateData, 500) as $chunk) {
foreach ($chunk as $item) {
$allUpdateFlag = $updateModel->where('id',$item['id'])->update(array_diff_key($item, ['id' => null]));
if (!$allUpdateFlag) break;
}
if (!$allUpdateFlag) break;
}
$insertFlag = (new UserCoupon)->insert($insertData);
if (!$allUpdateFlag || !$appointUpdateFlag || !$insertFlag || !$destroyDispenseFlag) throw new ErrException('领取失败');
});
return $resCouponData;
// return $this->res;
}
private function returnNullRes(): array
{
return $this->return->success();
}
// /**
// * @param array $data
// * @return array
// */
// private function receive(array $data): array
// {
// $list = $this->couponDispenseLogModel->getListByIds($data);
// if (empty($list)) return [];
//
// $insertData = [];
// $appointUpdateData = [];
// $allUpdateData =[];
// $destroyDispenseData = [];
//
// $resCouponData = [];
//
// foreach ($list as $item) {
// $validityTime = [];
// switch ($item['validity_time_type']) {
// case CouponCode::VALIDITY_TIME_TYPE_CYCLE:
// $validityValue = json_decode($item['validity_time_value'],true);
// $validityTime = [
// 'start_time' => date('Y-m-d H:i:s'),
// 'end_time' => date('Y-m-d H:i:s', time() + ($validityValue['day_num'] * DateUtil::DAY))
// ];
// break;
// case CouponCode::VALIDITY_TIME_TYPE_FIX:
// $validityTime = json_decode($item['validity_time_value'],true);
// break;
// }
//
// //有效期不存在或者到期销毁当前分发逻辑
// if (($validityTime['end_time'] ?? date('Y-m-d H:i:s')) < date('Y-m-d H:i:s')) {
// $destroyDispenseData[] = $item['id'];
// continue;
// }
//
// $oneData = [
// 'user_id' => $this->userId,
// 'coupon_template_id' => $item['coupon_template_id'],
// 'coupon_name' => $item['coupon_name'],
// 'coupon_dispense_id' => $item['id'],
// 'status' => CouponCode::COUPON_STATUS_UNUSED,
// 'validity_start_time' => $validityTime['start_time'] ?? date('Y-m-d H:i:s', time()),
// 'validity_end_time' => $validityTime['end_time'] ?? date('Y-m-d H:i:s', time()),
// ];
//
// $copies = array_map(function () use ($oneData) {
// return $oneData;
// }, array_fill(0, $item['item_count'], null));
// $insertData = array_merge($insertData, $copies);
//
// $oneData['count'] = $item['item_count'];
//
// if ($item['appoint_group'] != CouponCode::DISPENSE_APPOINT_GROUP_ALL_PEOPLE) {
// $appointUpdateData[] = [
// 'coupon_dispense_id' => $item['id'],
//// 'user_id' => $this->userId,
// 'receive_count' => $item['receive_count'],
// 'is_receive' => CouponCode::DISPENSE_STATUS_IS_RECEIVED
// ];
// }
//
// $allUpdateData[] = [
// 'id' => $item['id'],
// 'receive_count' => $item['receive_count'] +$item['item_count'],
// ];
//
// $resCouponData[] = $oneData;
// }
//
// if (empty($allUpdateData)) return [];
//
// if (!empty($appointUpdateData)) {
// $appointList = $this->couponDispenseUserModel->where('user_id',$this->userId)->whereIn('id',array_column($appointUpdateData,'coupon_dispense_id'))->pluck('id','coupon_dispense_id');
//
// foreach ($appointUpdateData as &$item) {
// $item['id'] = $appointList[$item['coupon_dispense_id']];
// }
// }
//
// Db::transaction(function () use($allUpdateData,$appointUpdateData,$insertData,$destroyDispenseData) {
// $appointUpdateFlag = true;
// if (!empty($appointUpdateData)) {
// $userUpdateModel = new CouponDispenseUser();
// foreach (array_chunk($appointUpdateData, 500) as $chunk) {
// foreach ($chunk as $item) {
// $appointUpdateFlag = $userUpdateModel
// ->where('id',$item['id'])
// ->update(array_diff_key($item, ['coupon_dispense_id' => null,'id' => null]));
// if (!$appointUpdateFlag) break;
// }
// if (!$appointUpdateFlag) break;
// }
//// $appointUpdateFlag = (new CouponDispenseUser)->update($appointUpdateData);
// }
//
// $destroyDispenseFlag = true;
// if (!empty($destroyDispenseData)) {
// $destroyDispenseFlag = (new CouponDispenseLog)->whereIn('id',$destroyDispenseData)->update([
// 'status' => CouponCode::DISPENSE_NULL,
// ]);
// }
//
//// $allUpdateFlag = (new CouponDispenseLog)->update($allUpdateData);
// $allUpdateFlag = true;
// $updateModel = new CouponDispenseLog();
// foreach (array_chunk($allUpdateData, 500) as $chunk) {
// foreach ($chunk as $item) {
// $allUpdateFlag = $updateModel->where('id',$item['id'])->update(array_diff_key($item, ['id' => null]));
// if (!$allUpdateFlag) break;
// }
// if (!$allUpdateFlag) break;
// }
//
// $insertFlag = (new UserCoupon)->insert($insertData);
//
// if (!$allUpdateFlag || !$appointUpdateFlag || !$insertFlag || !$destroyDispenseFlag) throw new ErrException('领取失败');
// });
//
// return $resCouponData;
// }
// private function returnNullRes(): array
// {
// return $this->return->success();
// }
}

View File

@@ -0,0 +1,149 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Api\Coupon;
use App\Constants\Common\CouponCode;
use App\Exception\ErrException;
use App\Extend\DateUtil;
use App\Model\CouponDispenseLog;
use App\Model\UserCoupon;
use App\Service\Api\BaseService;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
class ReceiveService extends BaseService
{
/**
* @var CouponDispenseLog
*/
#[Inject]
protected CouponDispenseLog $couponDispenseLogModel;
/**
* @var UserCoupon
*/
#[Inject]
protected UserCoupon $userCouponModel;
/**
* @return array
*/
public function handle(): array
{
$idArr = $this->request->input('id_arr');
if (empty($idArr)) throw new ErrException('参数错误');
$couponArr = $this->couponDispenseLogModel->getInfoByIds($idArr);
if ($couponArr->isEmpty()) throw new ErrException('领取的优惠券中有不存在的优惠券,请刷新后领取');
$couponArr = $couponArr->toArray();
$userBag = $this->userCouponModel->getReceiveCountByUserIds($this->userId, $idArr);
if (count(array_diff(array_column($couponArr, 'id'), $userBag)) != $couponArr) throw new ErrException('优惠券已领完');
$this->receive($couponArr);
return $this->return->success();
}
/**
* @var array
*/
private array $insertData = [];
private array $allUpdateData =[];
private array $destroyDispenseData = [];
/**
* @param array $couponArr
* @return void
*/
private function receive(array $couponArr): void
{
if (empty($couponArr)) return;
foreach ($couponArr as $item) {
$validityTime = [];
switch ($item['validity_time_type']) {
case CouponCode::VALIDITY_TIME_TYPE_CYCLE:
$validityValue = json_decode($item['validity_time_value'],true);
$validityTime = [
'start_time' => date('Y-m-d H:i:s'),
'end_time' => date('Y-m-d H:i:s', time() + ($validityValue['day_num'] * DateUtil::DAY))
];
break;
case CouponCode::VALIDITY_TIME_TYPE_FIX:
$validityTime = json_decode($item['validity_time_value'],true);
break;
}
//有效期不存在或者到期销毁当前分发逻辑
if (($validityTime['end_time'] ?? date('Y-m-d H:i:s')) < date('Y-m-d H:i:s')) {
$this->destroyDispenseData[] = $item['id'];
continue;
}
$oneData = [
'user_id' => $this->userId,
'coupon_template_id' => $item['coupon_template_id'],
'coupon_name' => $item['coupon_name'],
'coupon_dispense_id' => $item['id'],
'status' => CouponCode::COUPON_STATUS_UNUSED,
'validity_start_time' => $validityTime['start_time'] ?? date('Y-m-d H:i:s', time()),
'validity_end_time' => $validityTime['end_time'] ?? date('Y-m-d H:i:s', time()),
];
$copies = array_map(function () use ($oneData) {
return $oneData;
}, array_fill(0, $item['item_count'], null));
$this->insertData = array_merge($this->insertData, $copies);
$this->allUpdateData[] = [
'id' => $item['id'],
'receive_count' => $item['receive_count'] +$item['item_count'],
];
}
if (empty($allUpdateData)) return;
$this->matters();
}
/**
* @return void
*/
private function matters(): void
{
Db::transaction(function () {
$destroyDispenseFlag = true;
if (!empty($this->destroyDispenseData)) {
$destroyDispenseFlag = (new CouponDispenseLog)->whereIn('id',$this->destroyDispenseData)->update([
'status' => CouponCode::DISPENSE_NULL,
]);
}
// $allUpdateFlag = (new CouponDispenseLog)->update($allUpdateData);
$allUpdateFlag = true;
$updateModel = new CouponDispenseLog();
foreach (array_chunk($this->allUpdateData, 500) as $chunk) {
foreach ($chunk as $item) {
$allUpdateFlag = $updateModel->where('id',$item['id'])->update(array_diff_key($item, ['id' => null]));
if (!$allUpdateFlag) break;
}
if (!$allUpdateFlag) break;
}
$insertFlag = (new UserCoupon)->insert($this->insertData);
if (!$allUpdateFlag || !$insertFlag || !$destroyDispenseFlag) throw new ErrException('领取失败');
});
}
}