|
@@ -8,176 +8,70 @@ use Longyi\RewardPoints\Models\RewardActiveRule;
|
|
|
use Webkul\Customer\Models\Customer;
|
|
use Webkul\Customer\Models\Customer;
|
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
|
+use Carbon\Carbon;
|
|
|
|
|
+
|
|
|
class CustomerEvents
|
|
class CustomerEvents
|
|
|
{
|
|
{
|
|
|
- protected $rewardPointRepository;
|
|
|
|
|
|
|
+ protected RewardPointRepository $rewardPointRepository;
|
|
|
|
|
|
|
|
public function __construct(RewardPointRepository $rewardPointRepository)
|
|
public function __construct(RewardPointRepository $rewardPointRepository)
|
|
|
{
|
|
{
|
|
|
$this->rewardPointRepository = $rewardPointRepository;
|
|
$this->rewardPointRepository = $rewardPointRepository;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public function handleCustomerRegistration($event)
|
|
|
|
|
|
|
+ public function handleCustomerRegistration($event): void
|
|
|
{
|
|
{
|
|
|
-
|
|
|
|
|
- // 检查事件参数类型
|
|
|
|
|
- if (is_object($event) && method_exists($event, 'getAttribute')) {
|
|
|
|
|
- $customer = $event;
|
|
|
|
|
- } elseif (is_array($event) && isset($event['customer'])) {
|
|
|
|
|
- $customer = $event['customer'];
|
|
|
|
|
- } elseif (is_array($event) && isset($event['id'])) {
|
|
|
|
|
- $customer = Customer::find($event['id']);
|
|
|
|
|
- } elseif (is_int($event) || is_string($event)) {
|
|
|
|
|
- $customer = Customer::find($event);
|
|
|
|
|
- } else {
|
|
|
|
|
- $customer = $event;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ $customer = $this->resolveCustomer($event);
|
|
|
if (!$customer) {
|
|
if (!$customer) {
|
|
|
Log::warning('Customer not found in registration event');
|
|
Log::warning('Customer not found in registration event');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 查询注册规则
|
|
|
|
|
- $registrationRule = RewardActiveRule::where('type_of_transaction', RewardActiveRule::TYPE_REGISTRATION)
|
|
|
|
|
- ->where('status', 1)
|
|
|
|
|
- ->first();
|
|
|
|
|
-
|
|
|
|
|
- // 查询订阅规则
|
|
|
|
|
- $subscribeRule = RewardActiveRule::where('type_of_transaction', RewardActiveRule::TYPE_SUBSCRIBE)
|
|
|
|
|
- ->where('status', 1)
|
|
|
|
|
- ->first();
|
|
|
|
|
-
|
|
|
|
|
- // 准备批量添加的积分列表
|
|
|
|
|
$pointsList = [];
|
|
$pointsList = [];
|
|
|
|
|
|
|
|
- // 添加注册积分
|
|
|
|
|
- $registrationPoints = $this->getPointsFromRuleOrConfig(
|
|
|
|
|
- $registrationRule,
|
|
|
|
|
- 'rewardpoints.registration.points_per_registration',
|
|
|
|
|
- 100
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
|
|
+ // 注册积分
|
|
|
|
|
+ $registrationPoints = $this->getRegistrationPoints($customer);
|
|
|
if ($registrationPoints > 0) {
|
|
if ($registrationPoints > 0) {
|
|
|
- $pointsList[] = [
|
|
|
|
|
- 'amount' => $registrationPoints,
|
|
|
|
|
- 'type' => RewardActiveRule::TYPE_REGISTRATION,
|
|
|
|
|
- 'detail' => 'Registration bonus',
|
|
|
|
|
- 'rule' => $registrationRule
|
|
|
|
|
- ];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 检查客户是否订阅了新闻通讯
|
|
|
|
|
- $isSubscribedToNewsletter = false;
|
|
|
|
|
- if (property_exists($customer, 'subscribed_to_news_letter')) {
|
|
|
|
|
- $isSubscribedToNewsletter = $customer->subscribed_to_news_letter;
|
|
|
|
|
- } elseif (method_exists($customer, 'getAttribute')) {
|
|
|
|
|
- $isSubscribedToNewsletter = $customer->getAttribute('subscribed_to_news_letter');
|
|
|
|
|
|
|
+ $pointsList[] = $this->buildPointsItem($registrationPoints, RewardActiveRule::TYPE_REGISTRATION, 'Registration bonus');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 如果用户订阅了新闻通讯,添加订阅积分
|
|
|
|
|
- if ($isSubscribedToNewsletter) {
|
|
|
|
|
- $subscribePoints = $this->getPointsFromRuleOrConfig(
|
|
|
|
|
- $subscribeRule,
|
|
|
|
|
- 'rewardpoints.newsletter_subscribe.points_per_subscription',
|
|
|
|
|
- 200
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
|
|
+ // 订阅积分(仅当用户订阅了新闻通讯)
|
|
|
|
|
+ if ($this->isSubscribedToNewsletter($customer)) {
|
|
|
|
|
+ $subscribePoints = $this->getSubscribePoints($customer);
|
|
|
if ($subscribePoints > 0) {
|
|
if ($subscribePoints > 0) {
|
|
|
- $pointsList[] = [
|
|
|
|
|
- 'amount' => $subscribePoints,
|
|
|
|
|
- 'type' => RewardActiveRule::TYPE_SUBSCRIBE,
|
|
|
|
|
- 'detail' => 'Newsletter subscription bonus',
|
|
|
|
|
- 'rule' => $subscribeRule
|
|
|
|
|
- ];
|
|
|
|
|
|
|
+ $pointsList[] = $this->buildPointsItem($subscribePoints, RewardActiveRule::TYPE_SUBSCRIBE, 'Newsletter subscription bonus');
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 如果有积分需要添加,使用批量添加方法
|
|
|
|
|
if (!empty($pointsList)) {
|
|
if (!empty($pointsList)) {
|
|
|
- $histories = $this->rewardPointRepository->addPointsBatch($customer->id, $pointsList);
|
|
|
|
|
-
|
|
|
|
|
- /*Log::info('Points added for customer registration', [
|
|
|
|
|
- 'customer_id' => $customer->id,
|
|
|
|
|
- 'points_count' => count($pointsList),
|
|
|
|
|
- 'points_breakdown' => array_column($pointsList, 'amount'),
|
|
|
|
|
- 'total_points' => array_sum(array_column($pointsList, 'amount'))
|
|
|
|
|
- ]);*/
|
|
|
|
|
|
|
+ $this->rewardPointRepository->addPointsBatch($customer->id, $pointsList);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 处理客户登录事件,赠送登录积分
|
|
|
|
|
- */
|
|
|
|
|
- public function handleCustomerLogin($event)
|
|
|
|
|
|
|
+ public function handleCustomerLogin($event): void
|
|
|
{
|
|
{
|
|
|
- // 检查事件参数类型
|
|
|
|
|
- if (is_object($event) && method_exists($event, 'getAttribute')) {
|
|
|
|
|
- $customer = $event;
|
|
|
|
|
- } elseif (is_array($event) && isset($event['customer'])) {
|
|
|
|
|
- $customer = $event['customer'];
|
|
|
|
|
- } elseif (is_array($event) && isset($event['id'])) {
|
|
|
|
|
- $customer = Customer::find($event['id']);
|
|
|
|
|
- } elseif (is_int($event) || is_string($event)) {
|
|
|
|
|
- $customer = Customer::find($event);
|
|
|
|
|
- } else {
|
|
|
|
|
- $customer = $event;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ $customer = $this->resolveCustomer($event);
|
|
|
if (!$customer) {
|
|
if (!$customer) {
|
|
|
Log::warning('Customer not found in login event');
|
|
Log::warning('Customer not found in login event');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Log::info('Customer identified', [
|
|
|
|
|
- 'customer_id' => $customer->id,
|
|
|
|
|
- 'customer_email' => $customer->email ?? 'N/A'
|
|
|
|
|
- ]);
|
|
|
|
|
-
|
|
|
|
|
- // 检查今天是否已经获得过登录积分(使用 Redis/Cache 标记)
|
|
|
|
|
- $today = \Carbon\Carbon::now()->format('Y-m-d');
|
|
|
|
|
- $cacheKey = "reward_points:login_received:{$customer->id}:{$today}";
|
|
|
|
|
-
|
|
|
|
|
- // 尝试从缓存获取标记
|
|
|
|
|
- $alreadyReceivedToday = Cache::has($cacheKey);
|
|
|
|
|
- // 尝试从数据库获取登陆状态
|
|
|
|
|
- if(empty($alreadyReceivedToday)){
|
|
|
|
|
- $alreadyReceivedToday = RewardPointHistory::where('customer_id', $customer->id)
|
|
|
|
|
- ->where('type_of_transaction', RewardActiveRule::TYPE_LOGIN)
|
|
|
|
|
- ->whereDate('transaction_time', $today)
|
|
|
|
|
- ->where('status', RewardPointHistory::STATUS_COMPLETED)
|
|
|
|
|
- ->exists();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if ($alreadyReceivedToday) {
|
|
|
|
|
- /*Log::info('Customer already received login points today (from cache), skipping', [
|
|
|
|
|
- 'customer_id' => $customer->id,
|
|
|
|
|
- 'date' => $today,
|
|
|
|
|
- 'cache_store' => config('cache.default')
|
|
|
|
|
- ]);*/
|
|
|
|
|
|
|
+ // 检查今天是否已获得登录积分
|
|
|
|
|
+ if ($this->hasReceivedLoginPointsToday($customer)) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- // 查询登录规则
|
|
|
|
|
- $loginRule = RewardActiveRule::where('type_of_transaction', RewardActiveRule::TYPE_LOGIN)
|
|
|
|
|
- ->where('status', 1)
|
|
|
|
|
- ->first();
|
|
|
|
|
-
|
|
|
|
|
- if (!$loginRule) {
|
|
|
|
|
- Log::info('No active login rule found, skipping login points');
|
|
|
|
|
|
|
+ $loginRule = RewardActiveRule::active()->ofType(RewardActiveRule::TYPE_LOGIN)->first();
|
|
|
|
|
+ if (!$loginRule || !$loginRule->isApplicableToCustomer($customer)) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 获取登录积分
|
|
|
|
|
- $loginPoints = (int) $loginRule->reward_point;
|
|
|
|
|
|
|
+ $loginPoints = $this->getLoginPoints($customer, $loginRule);
|
|
|
if ($loginPoints <= 0) {
|
|
if ($loginPoints <= 0) {
|
|
|
- Log::info('Login points is 0 or negative, skipping login points');
|
|
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 添加登录积分
|
|
|
|
|
- $history = $this->rewardPointRepository->addPoints(
|
|
|
|
|
|
|
+ $this->rewardPointRepository->addPoints(
|
|
|
$customer->id,
|
|
$customer->id,
|
|
|
RewardActiveRule::TYPE_LOGIN,
|
|
RewardActiveRule::TYPE_LOGIN,
|
|
|
$loginPoints,
|
|
$loginPoints,
|
|
@@ -185,22 +79,138 @@ class CustomerEvents
|
|
|
'Login bonus'
|
|
'Login bonus'
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- /*Log::info('Login points added successfully', [
|
|
|
|
|
- 'customer_id' => $customer->id,
|
|
|
|
|
- 'points' => $loginPoints,
|
|
|
|
|
- 'history_id' => $history->history_id ?? null
|
|
|
|
|
- ]);*/
|
|
|
|
|
|
|
+ // 设置缓存标记,避免重复发放
|
|
|
|
|
+ $this->markLoginPointsReceived($customer);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 解析客户对象
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function resolveCustomer($event): ?Customer
|
|
|
|
|
+ {
|
|
|
|
|
+ if ($event instanceof Customer) {
|
|
|
|
|
+ return $event;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (is_array($event)) {
|
|
|
|
|
+ if (isset($event['customer'])) {
|
|
|
|
|
+ return $event['customer'] instanceof Customer ? $event['customer'] : null;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (isset($event['id'])) {
|
|
|
|
|
+ return Customer::find($event['id']);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (is_int($event) || is_string($event)) {
|
|
|
|
|
+ return Customer::find($event);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查是否订阅了新闻通讯
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function isSubscribedToNewsletter(Customer $customer): bool
|
|
|
|
|
+ {
|
|
|
|
|
+ return (bool)($customer->subscribed_to_news_letter ?? false);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取注册积分
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function getRegistrationPoints(Customer $customer): int
|
|
|
|
|
+ {
|
|
|
|
|
+ $rule = RewardActiveRule::active()->ofType(RewardActiveRule::TYPE_REGISTRATION)->first();
|
|
|
|
|
+ return $this->getPointsFromRuleOrConfig($rule, 'rewardpoints.registration.points_per_registration', 100);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取订阅积分
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function getSubscribePoints(Customer $customer): int
|
|
|
|
|
+ {
|
|
|
|
|
+ $rule = RewardActiveRule::active()->ofType(RewardActiveRule::TYPE_SUBSCRIBE)->first();
|
|
|
|
|
+ return $this->getPointsFromRuleOrConfig($rule, 'rewardpoints.newsletter_subscribe.points_per_subscription', 200);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取登录积分
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function getLoginPoints(Customer $customer, RewardActiveRule $rule): int
|
|
|
|
|
+ {
|
|
|
|
|
+ $customerGroupId = $customer->customer_group_id;
|
|
|
|
|
+ return $customerGroupId !== null
|
|
|
|
|
+ ? $rule->getRewardPointForCustomerGroup($customerGroupId)
|
|
|
|
|
+ : (int)$rule->reward_point;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查今日是否已获得登录积分
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function hasReceivedLoginPointsToday(Customer $customer): bool
|
|
|
|
|
+ {
|
|
|
|
|
+ $today = Carbon::now()->format('Y-m-d');
|
|
|
|
|
+ $cacheKey = $this->getLoginCacheKey($customer->id, $today);
|
|
|
|
|
+
|
|
|
|
|
+ if (Cache::has($cacheKey)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $exists = RewardPointHistory::where('customer_id', $customer->id)
|
|
|
|
|
+ ->where('type_of_transaction', RewardActiveRule::TYPE_LOGIN)
|
|
|
|
|
+ ->whereDate('transaction_time', $today)
|
|
|
|
|
+ ->where('status', RewardPointHistory::STATUS_COMPLETED)
|
|
|
|
|
+ ->exists();
|
|
|
|
|
+
|
|
|
|
|
+ if ($exists) {
|
|
|
|
|
+ // 回填缓存
|
|
|
|
|
+ Cache::put($cacheKey, true, Carbon::now()->endOfDay());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $exists;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 标记今日已获得登录积分
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function markLoginPointsReceived(Customer $customer): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $today = Carbon::now()->format('Y-m-d');
|
|
|
|
|
+ $cacheKey = $this->getLoginCacheKey($customer->id, $today);
|
|
|
|
|
+ Cache::put($cacheKey, true, Carbon::now()->endOfDay());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取登录积分缓存Key
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function getLoginCacheKey(int $customerId, string $date): string
|
|
|
|
|
+ {
|
|
|
|
|
+ return "reward_points:login_received:{$customerId}:{$date}";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构建积分项
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function buildPointsItem(int $amount, int $type, string $detail): array
|
|
|
|
|
+ {
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'amount' => $amount,
|
|
|
|
|
+ 'type' => $type,
|
|
|
|
|
+ 'detail' => $detail,
|
|
|
|
|
+ 'rule' => null,
|
|
|
|
|
+ ];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 从规则或配置获取积分值
|
|
* 从规则或配置获取积分值
|
|
|
*/
|
|
*/
|
|
|
- private function getPointsFromRuleOrConfig($rule, $configKey, $defaultValue)
|
|
|
|
|
|
|
+ private function getPointsFromRuleOrConfig($rule, string $configKey, int $defaultValue): int
|
|
|
{
|
|
{
|
|
|
if ($rule && $rule->reward_point > 0) {
|
|
if ($rule && $rule->reward_point > 0) {
|
|
|
- return (int) $rule->reward_point;
|
|
|
|
|
|
|
+ return (int)$rule->reward_point;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return (int) config($configKey, $defaultValue);
|
|
|
|
|
|
|
+ return (int)config($configKey, $defaultValue);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|