chore: 添加静态资源文件和版本配置文件

添加大量图片、字体、音频等静态资源文件,包括用户界面图片、模板文件和安装界面素材
添加系统版本配置文件(.version)和常量定义文件(.constant)
更新供应商依赖文件,包括Symfony VarDumper组件和相关许可证文件
添加验证码配置文件(captcha.php)和.gitignore规则
This commit is contained in:
2026-03-06 20:14:23 +08:00
commit c9a98f342c
4485 changed files with 490986 additions and 0 deletions

View File

@@ -0,0 +1,938 @@
<?php
declare (strict_types=1);
namespace app\services\activity\holiday;
use app\dao\activity\holiday\HolidayGiftPushDao;
use app\jobs\activity\HolidayGiftJob;
use app\services\activity\coupon\StoreCouponIssueServices;
use app\services\BaseServices;
use app\services\user\UserServices;
use app\services\user\UserBillServices;
use app\services\user\UserMoneyServices;
use app\services\activity\coupon\CouponIssueServices;
use app\services\message\NoticeService;
use crmeb\exceptions\AdminException;
use crmeb\exceptions\ApiException;
use think\exception\ValidateException;
use think\facade\Log;
/**
* 节日有礼推送记录服务
* Class HolidayGiftPushServices
* @package app\services\activity
* @mixin HolidayGiftPushDao
*/
class HolidayGiftPushServices extends BaseServices
{
/**
* 构造方法
* HolidayGiftPushServices constructor.
* @param HolidayGiftPushDao $dao
*/
public function __construct(HolidayGiftPushDao $dao)
{
$this->dao = $dao;
}
/**
* 获取节日有礼推送记录列表
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getHolidayGiftPushList(array $where)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getHolidayGiftPushList($where, '*', $page, $limit);
$count = $this->dao->count($where);
if ($list) {
// 获取用户信息
$uids = array_column($list, 'uid');
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userInfos = $userService->getUserList(['uid' => $uids], 'uid,nickname,avatar,phone');
$userInfos = array_combine(array_column($userInfos, 'uid'), $userInfos);
// 获取节日有礼活动信息
$giftIds = array_column($list, 'gift_id');
/** @var HolidayGiftServices $giftService */
$giftService = app()->make(HolidayGiftServices::class);
$giftInfos = $giftService->getHolidayGiftList(['id' => $giftIds])['list'];
$giftInfos = array_combine(array_column($giftInfos, 'id'), $giftInfos);
foreach ($list as &$item) {
$item['user_info'] = $userInfos[$item['uid']] ?? [];
$item['gift_info'] = $giftInfos[$item['gift_id']] ?? [];
}
}
return compact('list', 'count');
}
/**
* 获取节日有礼推送记录详情
* @param int $id
* @param string $field
* @return array|\think\Model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getHolidayGiftPushInfo(int $id, string $field = '*')
{
if (!$id) {
throw new AdminException('参数错误');
}
$info = $this->dao->get($id, $field);
if (!$info) {
throw new AdminException('推送记录不存在');
}
return $info;
}
/**
* 获取用户的节日有礼推送记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID,可选
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserPushRecord(int $uid, int $giftId = 0)
{
if (!$uid) {
return [];
}
$where = ['uid' => $uid];
if ($giftId) {
$where['gift_id'] = $giftId;
}
return $this->dao->getHolidayGiftPushList($where);
}
/**
* 获取用户今日的节日有礼推送记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID,可选
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserTodayPushRecord(int $uid, int $giftId = 0)
{
if (!$uid) {
return [];
}
$where = [
['uid', '=', $uid],
['push_time', '>', strtotime(date('Y-m-d'))]
];
if ($giftId) {
$where[] = ['gift_id', '=', $giftId];
}
return $this->dao->getHolidayGiftPushList($where);
}
/**
* 获取用户本周的节日有礼推送记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID,可选
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserWeekPushRecord(int $uid, int $giftId = 0)
{
if (!$uid) {
return [];
}
$weekStart = strtotime(date('Y-m-d', strtotime('this week Monday')));
$where = [
'uid' => $uid,
'push_time' => ['>=', $weekStart]
];
if ($giftId) {
$where['gift_id'] = $giftId;
}
return $this->dao->getHolidayGiftPushList($where);
}
/**
* 获取用户本月的节日有礼推送记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID,可选
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserMonthPushRecord(int $uid, int $giftId = 0)
{
if (!$uid) {
return [];
}
$monthStart = strtotime(date('Y-m-01'));
$where = [
'uid' => $uid,
'push_time' => ['>=', $monthStart]
];
if ($giftId) {
$where['gift_id'] = $giftId;
}
return $this->dao->getHolidayGiftPushList($where);
}
/**
* 更新节日有礼推送记录状态
* @param int $id 记录ID
* @param int $status 状态:0未读,1已读
* @return mixed
*/
public function updatePushStatus(int $id, int $status)
{
if (!$id) {
throw new AdminException('参数错误');
}
return $this->dao->update($id, ['status' => $status]);
}
/**
* 删除节日有礼推送记录
* @param int $id 记录ID
* @return mixed
*/
public function deletePush(int $id)
{
if (!$id) {
throw new AdminException('参数错误');
}
return $this->dao->update($id, []);
}
/**
* 批量删除节日有礼推送记录
* @param array $ids 记录ID数组
* @return mixed
*/
public function batchDeletePush(array $ids)
{
if (!$ids) {
throw new AdminException('参数错误');
}
return $this->dao->batchUpdate($ids, []);
}
/**
* 统计节日有礼推送数据
* @param array $where
* @return array
*/
public function getPushStatistics(array $where = [])
{
// 总推送人数
$totalUsers = $this->dao->distinct(true)->field('uid')->where($where)->count();
// 总推送次数
$totalPushes = $this->dao->count($where);
// 今日推送人数
$todayWhere = $where;
$todayWhere['push_time'] = ['>=', strtotime(date('Y-m-d'))];
$todayUsers = $this->dao->distinct(true)->field('uid')->where($todayWhere)->count();
// 今日推送次数
$todayPushes = $this->dao->count($todayWhere);
// 昨日推送人数
$yesterdayStart = strtotime(date('Y-m-d', strtotime('-1 day')));
$yesterdayEnd = strtotime(date('Y-m-d')) - 1;
$yesterdayWhere = $where;
$yesterdayWhere['push_time'] = ['between', [$yesterdayStart, $yesterdayEnd]];
$yesterdayUsers = $this->dao->distinct(true)->field('uid')->where($yesterdayWhere)->count();
// 昨日推送次数
$yesterdayPushes = $this->dao->count($yesterdayWhere);
// 本月推送人数
$monthWhere = $where;
$monthWhere['push_time'] = ['>=', strtotime(date('Y-m-01'))];
$monthUsers = $this->dao->distinct(true)->field('uid')->where($monthWhere)->count();
// 本月推送次数
$monthPushes = $this->dao->count($monthWhere);
// 按推送渠道统计
$channelStats = [];
$pushTypes = [1 => '短信', 2 => '公众号', 3 => '弹框广告'];
foreach ($pushTypes as $type => $name) {
$typeWhere = $where;
$typeWhere['push_type'] = $type;
$channelStats[$type] = [
'name' => $name,
'count' => $this->dao->count($typeWhere),
'users' => $this->dao->distinct(true)->field('uid')->where($typeWhere)->count()
];
}
return [
'total_users' => $totalUsers,
'total_pushes' => $totalPushes,
'today_users' => $todayUsers,
'today_pushes' => $todayPushes,
'yesterday_users' => $yesterdayUsers,
'yesterday_pushes' => $yesterdayPushes,
'month_users' => $monthUsers,
'month_pushes' => $monthPushes,
'channel_stats' => $channelStats
];
}
/**
* 检查用户是否可以推送节日有礼消息
* @param int $uid 用户ID
* @param array $giftInfo 节日有礼活动信息
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function checkUserCanPush(int $uid, array $giftInfo)
{
if (!$uid || !$giftInfo) {
return false;
}
// 获取用户推送记录
$pushRecords = $this->getUserPushRecord($uid, $giftInfo['id']);
if (!$pushRecords) {
return true; // 没有推送记录,可以推送
}
// 根据推送频次检查是否可以推送
switch ($giftInfo['push_frequency']) {
case 1: // 永久一次
return false; // 已经推送过,不能再推送
case 2: // 每次进入
return true; // 每次都可以推送
case 3: // 每天
// 检查今天是否已经推送过
$todayRecords = $this->getUserTodayPushRecord($uid, $giftInfo['id']);
return empty($todayRecords);
case 4: // 每月
// 检查本月是否已经推送过
$monthRecords = $this->getUserMonthPushRecord($uid, $giftInfo['id']);
return empty($monthRecords);
case 5: // 每周
// 检查今天是否是设置的星期几,以及本周是否已经推送过
$weekDay = date('N'); // 1-7 表示周一到周日
$weekDays = explode(',', $giftInfo['push_week_days']);
if (!in_array($weekDay, $weekDays)) {
return false; // 今天不是设置的星期几,不能推送
}
// 检查本周是否已经推送过
$weekRecords = $this->getUserWeekPushRecord($uid, $giftInfo['id']);
return empty($weekRecords);
default:
return false;
}
}
/**
* 检查用户是否在推送时段内
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
public function checkPushTimeRange(array $giftInfo)
{
// 如果是全时段,直接返回true
if ($giftInfo['push_time_type'] == 1) {
return true;
}
// 指定时段,需要检查当前时间是否在时段内
$now = date('H:i');
$startTime = $giftInfo['push_start_time'];
$endTime = $giftInfo['push_end_time'];
return $now >= $startTime && $now <= $endTime;
}
/**
* 用户是否包邮,双倍积分
* @return
* User: liusl
* DateTime: 2025/8/5 16:18
*/
public function receiveHolidayGift(int $uid, int $type)
{
//$type 1: 是否包邮 2: 双倍积分
$holidayGiftRecordServices = app()->make(HolidayGiftRecordServices::class);
//已经领取的活动
$recordList = $holidayGiftRecordServices->selectList(['uid' => $uid]);
if (!$recordList) {
return false;
}
$recordList = $recordList->toArray();
$integral_multiple = 0;
foreach ($recordList as $record) {
$giftInfo = json_decode($record['gift_content'], true);
// 检查json_decode是否失败
if ($giftInfo === null) {
continue;
}
if ($this->checkAdvancePush($giftInfo, true, $uid)) {
if ($type == 1) {
// 检查是否包含包邮权益(类型5)
if (isset($giftInfo['gift_type']) && in_array(5, $giftInfo['gift_type'])) {
return true;
}
} elseif ($type == 2) {
// 检查是否包含双倍积分权益(类型3)
if (isset($giftInfo['gift_type']) && in_array(3, $giftInfo['gift_type']) && $giftInfo['integral_multiple']) {
$integral_multiple = max($integral_multiple, (int)$giftInfo['integral_multiple']);
}
}
}
}
// 默认返回false
return $type == 2 && $integral_multiple ? $integral_multiple : false;
}
/**
* 检查是否需要提前推送或当天推送
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
public function checkAdvancePush(array $giftInfo, bool $is_advance = false, int $uid = 0)
{
if ($giftInfo['task_type'] == 2) {
// 根据活动日期类型检查
switch ($giftInfo['activity_date_type']) {
case 1: // 自定义日期
return $this->checkCustomDateAdvancePush($giftInfo, $is_advance);
case 2: // 每月
return $this->checkMonthlyAdvancePush($giftInfo, $is_advance);
case 3: // 每周
return $this->checkWeeklyAdvancePush($giftInfo, $is_advance);
default:
return false;
}
} else {
//生日
if ($giftInfo['task_type'] == 1) { // 生日任务
$user = app()->make(UserServices::class)->getUserCacheInfo($uid);
if(!$user['birthday']){
return false;
}
$today = strtotime(date('Y-m-d'));
$userBirthday = strtotime($user['birthday']);
// 如果 is_advance 为 false,需要判断提前推送
if (!$is_advance && $giftInfo['advance_push'] == 1 && $giftInfo['advance_days'] > 0) {
$advanceDays = (int)$giftInfo['advance_days'];
//生日当天 - 提前推送
if ($giftInfo['birthday_type'] == 1) {
$thisYearBirthday = strtotime(date('Y') . '-' . date('m-d', $userBirthday));
// 如果今年生日已过,计算明年生日
if ($thisYearBirthday < $today) {
$thisYearBirthday = strtotime((date('Y') + 1) . '-' . date('m-d', $userBirthday));
}
$advancePushDate = $thisYearBirthday - ($advanceDays * 24 * 60 * 60);
if ($today < $advancePushDate || $today > $thisYearBirthday) {
return false;
}
}
//生日当周 - 提前推送
elseif ($giftInfo['birthday_type'] == 2) {
$thisYearBirthday = strtotime(date('Y') . '-' . date('m-d', $userBirthday));
if ($thisYearBirthday < $today) {
$thisYearBirthday = strtotime((date('Y') + 1) . '-' . date('m-d', $userBirthday));
}
$birthdayWeekStart = strtotime('last monday', $thisYearBirthday);
$birthdayWeekEnd = strtotime('next sunday', $birthdayWeekStart);
$advancePushDate = $birthdayWeekStart - ($advanceDays * 24 * 60 * 60);
if ($today < $advancePushDate || $today > $birthdayWeekEnd) {
return false;
}
}
//生日当月 - 提前推送
elseif ($giftInfo['birthday_type'] == 3) {
$thisYearBirthday = strtotime(date('Y') . '-' . date('m-d', $userBirthday));
if ($thisYearBirthday < $today) {
$thisYearBirthday = strtotime((date('Y') + 1) . '-' . date('m-d', $userBirthday));
}
$birthdayMonth = date('Y-m', $thisYearBirthday);
$monthStart = strtotime($birthdayMonth . '-01');
$monthEnd = strtotime($birthdayMonth . '-' . date('t', $thisYearBirthday));
$advancePushDate = $monthStart - ($advanceDays * 24 * 60 * 60);
if ($today < $advancePushDate || $today > $monthEnd) {
return false;
}
}
} else {
// 原有逻辑:不提前推送
$todayMd = date('m-d');
$birthday = date('m-d', $userBirthday);
//生日当天
if ($giftInfo['birthday_type'] == 1) {
if ($todayMd != $birthday) {
return false;
}
}
//生日当周
elseif ($giftInfo['birthday_type'] == 2) {
$birthday = strtotime(date('Y').'-'.date('m-d', $userBirthday));
$birthdayWeekStart = strtotime('last monday', $birthday);
$birthdayWeekEnd = strtotime('next sunday', $birthdayWeekStart);
$todayTimestamp = strtotime('today');
if ($todayTimestamp <= $birthdayWeekStart || $todayTimestamp >= $birthdayWeekEnd) {
return false;
}
}
//生日当月
elseif ($giftInfo['birthday_type'] == 3) {
if (date('m') != date('m', $userBirthday)) {
return false;
}
}
}
}
}
return true;
}
/**
* 检查自定义日期的提前推送
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
private function checkCustomDateAdvancePush(array $giftInfo, $is_advance = false)
{
$currentDate = strtotime(date('Y-m-d'));
$startDate = $giftInfo['activity_start_date'];
$endDate = $giftInfo['activity_end_date'];
// 如果没有设置提前推送,检查是否在活动日期范围内
if (empty($giftInfo['advance_push']) || empty($giftInfo['advance_days']) || $is_advance) {
return $currentDate >= $startDate && $currentDate <= $endDate;
}
// 计算提前推送日期
$currentYear = date('Y');
$startTimestamp = strtotime($currentYear . '-' . $startDate);
$currentTimestamp = strtotime($currentYear . '-' . $currentDate);
// 如果开始日期已经过了今年,则计算明年的日期
if ($startTimestamp < $currentTimestamp) {
$startTimestamp = strtotime(($currentYear + 1) . '-' . $startDate);
}
// 计算天数差
$daysDiff = round(($startTimestamp - $currentTimestamp) / 86400);
// 检查是否符合提前推送天数或在活动期间
return $daysDiff == $giftInfo['advance_days'] || ($currentDate >= $startDate && $currentDate <= $endDate);
}
/**
* 检查每月活动的推送
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
private function checkMonthlyAdvancePush(array $giftInfo, bool $is_advance = false)
{
$currentDay = (int)date('d');
$monthDays = is_array($giftInfo['activity_month_days']) ? $giftInfo['activity_month_days'] : explode(',', $giftInfo['activity_month_days']);
$monthDays = array_map('intval', $monthDays);
// 如果没有设置提前推送,检查今天是否是活动日期
if (empty($giftInfo['advance_push']) || empty($giftInfo['advance_days']) || $is_advance) {
return in_array($currentDay, $monthDays);
}
// 检查是否有活动日期需要提前推送
foreach ($monthDays as $day) {
$daysDiff = $day - $currentDay;
if ($daysDiff < 0) {
// 如果活动日期已过,计算下个月的天数差
$daysInMonth = (int)date('t');
$daysDiff = $daysInMonth - $currentDay + $day;
}
if ($daysDiff == $giftInfo['advance_days']) {
return true;
}
}
// 检查今天是否是活动日期
return in_array($currentDay, $monthDays);
}
/**
* 检查每周活动的推送
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
private function checkWeeklyAdvancePush(array $giftInfo, bool $is_advance = false)
{
$currentWeekDay = (int)date('N'); // 1-7表示周一到周日
$weekDays = is_array($giftInfo['activity_week_days']) ? $giftInfo['activity_week_days'] : explode(',', $giftInfo['activity_week_days']);
$weekDays = array_map('intval', $weekDays);
// 如果没有设置提前推送,检查今天是否是活动日期
if (empty($giftInfo['advance_push']) || empty($giftInfo['advance_days']) || $is_advance) {
return in_array($currentWeekDay, $weekDays);
}
// 检查是否有活动日期需要提前推送
foreach ($weekDays as $weekDay) {
$daysDiff = $weekDay - $currentWeekDay;
if ($daysDiff < 0) {
// 如果活动日期已过,计算下周的天数差
$daysDiff = 7 + $daysDiff;
}
if ($daysDiff == $giftInfo['advance_days']) {
return true;
}
}
// 检查今天是否是活动日期
return in_array($currentWeekDay, $weekDays);
}
/**
* 检查用户是否符合节日有礼活动条件
* @param int $uid 用户ID
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
public function checkUserCondition(int $uid, array $giftInfo)
{
/** @var HolidayGiftServices $giftService */
$giftService = app()->make(HolidayGiftServices::class);
return $giftService->checkUserCondition($uid, $giftInfo);
}
/**
* 保存用户节日有礼推送记录
* @param array $ids 活动ID数组
* @param int $uid 用户ID
* @param array $data 附加数据
* @return bool
*/
public function saveGiftPush(array $ids, int $uid, array $data = [])
{
if (!$ids) return true;
$saveData = [];
foreach ($ids as $id) {
$data['gift_id'] = $id;
$data['uid'] = $uid;
$data['push_time'] = $data['add_time'] = time();
$saveData[] = $data;
}
$this->dao->saveAll($saveData);
return true;
}
/**
* 定时任务处理节日有礼活动
* 获取当前活动日期的活动,判断给用户赠送积分、余额等权益
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function handleHolidayGiftTask()
{
try {
// 获取当前有效的节日有礼活动
/** @var HolidayGiftServices $giftService */
$giftService = app()->make(HolidayGiftServices::class);
$activeGifts = $giftService->getActiveHolidayGifts();
if (empty($activeGifts)) {
return true;
}
foreach ($activeGifts as $giftInfo) {
// 获取符合条件的用户并执行推送
$this->processGiftForUsers($giftInfo);
}
return true;
} catch (\Exception $e) {
// 记录错误日志
Log::error('节日有礼定时任务执行失败: ' . $e->getMessage());
return false;
}
}
/**
* 为符合条件的用户处理节日有礼
* @param array $giftInfo 节日有礼活动信息
* @return
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function processGiftForUsers(array $giftInfo)
{
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
/** @var HolidayGiftServices $giftService */
$giftService = app()->make(HolidayGiftServices::class);
// 获取符合条件的用户
$userIds = $this->getEligibleUsers($giftInfo);
if (empty($userIds)) {
return true;
}
$successCount = 0;
$failCount = 0;
// 将用户处理任务分发到队列中,避免大量用户时的性能问题
foreach ($userIds as $uid) {
// try {
// $this->grantUserBenefits($uid, $giftInfo);
// $this->recordPushLog($uid, $giftInfo);
// 分发到队列处理
HolidayGiftJob::dispatch('doJob', [$uid, $giftInfo]);
$successCount++;
// } catch (\Exception $e) {
// Log::error("用户{$uid}节日有礼队列分发失败: " . $e->getMessage());
// $failCount++;
// }
}
// 记录处理结果日志
Log::info("节日有礼活动[{$giftInfo['id']}]已分发到队列处理,总用户数:" . count($userIds) . ",成功分发:{$successCount}人,分发失败:{$failCount}人");
return [
'dispatched' => $successCount,
'dispatch_failed' => $failCount,
'total' => count($userIds)
];
}
/**
* 获取符合条件的用户ID列表
* @param array $giftInfo 节日有礼活动信息
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getEligibleUsers(array $giftInfo)
{
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$where = ['status' => 1, 'is_del' => 0];
// 如果是生日任务,需要特殊处理
if ($giftInfo['task_type'] == 1) { // 生日任务
$today = date('m-d');
if ($giftInfo['birthday_type'] == 1) { // 阳历生日
$where['birthday'] = ['like', '%' . $today];
}
}
$query = $userService->search($where)
->when($giftInfo['task_type'] == 2 && $giftInfo['push_user_type'] == 2, function ($query) use ($giftInfo) {
//自定义活动和指定人群
if ($giftInfo['condition_type'] == 1) {
//满足任一条件
} else {
//满足全部条件
$query->when($giftInfo['user_level'], function ($query) use ($giftInfo) {
$query->whereIn('level', $giftInfo['user_level']);
})->when($giftInfo['user_tag'], function ($query) use ($giftInfo) {
//1等级会员,2付费会员,3推广员,4采购商
if (in_array(1, $giftInfo['user_tag'])) {
$query->where('level', '>', 0);
}
if (in_array(2, $giftInfo['user_tag'])) {
$query->where(function ($query) {
$query->where(function ($query) {
$query->where('is_money_level', '>', 0)->where('overdue_time', '>', time());
})->whereOr(function ($query) {
$query->where('is_ever_level', '>', 0);
});
});
}
if (in_array(3, $giftInfo['user_tag'])) {
$query->where('is_promoter', 1);
}
if (in_array(4, $giftInfo['user_tag'])) {
$query->where('is_channel', 1);
}
})->when($giftInfo['user_label'], function ($query) use ($giftInfo) {
$user_label = $giftInfo['user_label'];
$query->whereIn('uid', function ($q) use ($user_label) {
$q->name('user_label_relation')->whereIn('label_id', $user_label)->field('uid')->select();
});
});
}
});
$users = $query->field('uid')->select()->toArray();
return array_column($users, 'uid');
}
/**
* 给用户赠送权益
* @param int $uid 用户ID
* @param array $giftInfo 节日有礼活动信息
* @return array|bool
*/
public function grantUserBenefits(int $uid, array $giftInfo)
{
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$grantResults = true;
Log::info("开始为用户{$uid}赠送节日有礼权益,活动ID:{$giftInfo['id']}");
// 赠送积分
if (in_array(2, $giftInfo['gift_type'])) { // 积分
if (!empty($giftInfo['integral'])) {
$userInfo = $userService->getUserInfo($uid);
if ($userInfo) {
$newIntegral = bcadd((string)$userInfo['integral'], (string)$giftInfo['integral'], 0);
/** @var UserBillServices $userBillService */
$userBillService = app()->make(UserBillServices::class);
$billResult = $userBillService->income('holiday_gift_integral', $uid, (int)$giftInfo['integral'], (int)$newIntegral, 0, 0, '节日有礼赠送积分');
$updateResult = $userService->update($uid, ['integral' => $newIntegral]);
$integralSuccess = $billResult && $updateResult;
if ($integralSuccess) {
Log::info("用户{$uid}积分赠送成功,赠送积分:{$giftInfo['integral']}");
} else {
Log::error("用户{$uid}积分赠送失败,赠送积分:{$giftInfo['integral']}");
$grantResults = false;
}
} else {
Log::error("用户{$uid}不存在,积分赠送失败");
$grantResults = false;
}
}
}
// 赠送余额
if (in_array(4, $giftInfo['gift_type'])) { // 余额
if (!empty($giftInfo['balance'])) {
$userInfo = $userService->getUserInfo($uid);
if ($userInfo) {
$newMoney = bcadd((string)$userInfo['now_money'], (string)$giftInfo['balance'], 2);
/** @var UserMoneyServices $userMoneyService */
$userMoneyService = app()->make(UserMoneyServices::class);
$billResult = $userMoneyService->income('holiday_gift_money', $uid, $giftInfo['balance'], $newMoney, 0, '', '节日有礼赠送余额');
$updateResult = $userService->update($uid, ['now_money' => $newMoney]);
$moneySuccess = $billResult && $updateResult;
if ($moneySuccess) {
Log::info("用户{$uid}余额赠送成功,赠送余额:{$giftInfo['balance']}");
} else {
Log::error("用户{$uid}余额赠送失败,赠送余额:{$giftInfo['balance']}");
$grantResults = false;
}
} else {
Log::error("用户{$uid}不存在,余额赠送失败");
$grantResults = false;
}
}
}
// 赠送优惠券
if (in_array(1, $giftInfo['gift_type'])) {
if (!empty($giftInfo['coupon_ids'])) {
try {
/** @var StoreCouponIssueServices $issueService */
$issueService = app()->make(StoreCouponIssueServices::class);
$couponList = $issueService->search([])->whereIn('id', $giftInfo['coupon_ids'])->select()->toArray();
if ($couponList) {
/** @var StoreCouponIssueServices $storeCouponIssueServices */
$storeCouponIssueServices = app()->make(StoreCouponIssueServices::class);
$couponSuccess = true;
foreach ($couponList as $coupon) {
$res = $storeCouponIssueServices->setCoupon($coupon, [$uid], '', '', true);
if (!$res) {
$couponSuccess = false;
Log::error("用户{$uid}优惠券赠送失败,优惠券ID:{$coupon['id']}");
}
}
if ($couponSuccess) {
Log::info("用户{$uid}优惠券赠送成功,优惠券IDs:" . implode(',', $giftInfo['coupon_ids']));
} else {
$grantResults = false;
}
} else {
Log::error("用户{$uid}优惠券赠送失败,未找到有效优惠券");
$grantResults = false;
}
} catch (\Exception $e) {
Log::error("用户{$uid}优惠券赠送异常:" . $e->getMessage());
$grantResults = false;
}
}
}
if ($grantResults) {
Log::info("用户{$uid}节日有礼权益赠送完成,活动ID:{$giftInfo['id']}");
} else {
Log::error("用户{$uid}节日有礼权益赠送失败,活动ID:{$giftInfo['id']}");
}
return $grantResults;
}
/**
* 记录推送日志
* @param int $uid 用户ID
* @param array $giftInfo 节日有礼活动信息
* @param array $grantResults 赠送结果详情
* @return bool|\crmeb\basic\BaseModel|\think\Model
*/
public function recordPushLog(int $uid, array $giftInfo)
{
try {
// 记录详细的礼品记录到 holiday_gift_record 表
/** @var HolidayGiftRecordServices $recordService */
$recordService = app()->make(HolidayGiftRecordServices::class);
$recordData = [
'uid' => $uid,
'gift_id' => $giftInfo['id'],
'gift_type' => implode(',', $giftInfo['gift_type']),
'gift_content' => json_encode($giftInfo),
'receive_time' => time(),
'add_time' => time()
];
$recordResult = $recordService->dao->save($recordData);
if (!$recordResult) {
Log::error("节日有礼记录保存失败: 用户ID {$uid}, 活动ID {$giftInfo['id']}");
return false;
}
return $recordResult;
} catch (\Exception $e) {
Log::error("节日有礼记录保存异常: " . $e->getMessage());
return false;
}
}
}

View File

@@ -0,0 +1,414 @@
<?php
declare (strict_types=1);
namespace app\services\activity\holiday;
use app\dao\activity\holiday\HolidayGiftRecordDao;
use app\services\BaseServices;
use app\services\user\UserServices;
use crmeb\exceptions\AdminException;
use crmeb\exceptions\ApiException;
use think\exception\ValidateException;
/**
* 节日有礼领取记录服务
* Class HolidayGiftRecordServices
* @package app\services\activity
* @mixin HolidayGiftRecordDao
*/
class HolidayGiftRecordServices extends BaseServices
{
/**
* 构造方法
* HolidayGiftRecordServices constructor.
* @param HolidayGiftRecordDao $dao
*/
public function __construct(HolidayGiftRecordDao $dao)
{
$this->dao = $dao;
}
/**
* 获取节日有礼领取记录列表
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getHolidayGiftRecordList(array $where)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getHolidayGiftRecordList($where, '*', $page, $limit);
$count = $this->dao->count($where);
if ($list) {
// 获取用户信息
$uids = array_column($list, 'uid');
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userInfos = $userService->getUserList(['uid' => $uids], 'uid,nickname,avatar,phone');
$userInfos = array_combine(array_column($userInfos, 'uid'), $userInfos);
// 获取节日有礼活动信息
$giftIds = array_column($list, 'gift_id');
/** @var HolidayGiftServices $giftService */
$giftService = app()->make(HolidayGiftServices::class);
$giftInfos = $giftService->getHolidayGiftList(['id' => $giftIds])['list'];
$giftInfos = array_combine(array_column($giftInfos, 'id'), $giftInfos);
foreach ($list as &$item) {
$item['user_info'] = $userInfos[$item['uid']] ?? [];
$item['gift_info'] = $giftInfos[$item['gift_id']] ?? [];
}
}
return compact('list', 'count');
}
/**
* 获取节日有礼领取记录详情
* @param int $id
* @param string $field
* @return array|\think\Model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getHolidayGiftRecordInfo(int $id, string $field = '*')
{
if (!$id) {
throw new AdminException('参数错误');
}
$info = $this->dao->get($id, $field);
if (!$info) {
throw new AdminException('领取记录不存在');
}
return $info;
}
/**
* 获取用户领取的节日有礼记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID
* @return array|\think\Model|null
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserGiftRecord(int $uid, int $giftId)
{
if (!$uid || !$giftId) {
return null;
}
return $this->dao->getOne(['uid' => $uid, 'gift_id' => $giftId, 'is_del' => 0]);
}
/**
* 获取用户今日领取的节日有礼记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID,可选
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserTodayGiftRecord(int $uid, int $giftId = 0)
{
if (!$uid) {
return [];
}
$where = [
'uid' => $uid,
'is_del' => 0,
'receive_time' => ['>=', strtotime(date('Y-m-d'))]
];
if ($giftId) {
$where['gift_id'] = $giftId;
}
return $this->dao->getList($where);
}
/**
* 获取用户本周领取的节日有礼记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID,可选
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserWeekGiftRecord(int $uid, int $giftId = 0)
{
if (!$uid) {
return [];
}
$weekStart = strtotime(date('Y-m-d', strtotime('this week Monday')));
$where = [
'uid' => $uid,
'is_del' => 0,
'receive_time' => ['>=', $weekStart]
];
if ($giftId) {
$where['gift_id'] = $giftId;
}
return $this->dao->getList($where);
}
/**
* 获取用户本月领取的节日有礼记录
* @param int $uid 用户ID
* @param int $giftId 节日有礼活动ID,可选
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserMonthGiftRecord(int $uid, int $giftId = 0)
{
if (!$uid) {
return [];
}
$monthStart = strtotime(date('Y-m-01'));
$where = [
'uid' => $uid,
'is_del' => 0,
'receive_time' => ['>=', $monthStart]
];
if ($giftId) {
$where['gift_id'] = $giftId;
}
return $this->dao->getList($where);
}
/**
* 更新节日有礼领取记录状态
* @param int $id 记录ID
* @param int $status 状态:0未使用,1已使用
* @return mixed
*/
public function updateRecordStatus(int $id, int $status)
{
if (!$id) {
throw new AdminException('参数错误');
}
$data = ['status' => $status];
if ($status == 1) {
$data['use_time'] = time();
}
return $this->dao->update($id, $data);
}
/**
* 删除节日有礼领取记录
* @param int $id 记录ID
* @return mixed
*/
public function deleteRecord(int $id)
{
if (!$id) {
throw new AdminException('参数错误');
}
return $this->dao->update($id, ['is_del' => 1]);
}
/**
* 批量删除节日有礼领取记录
* @param array $ids 记录ID数组
* @return mixed
*/
public function batchDeleteRecord(array $ids)
{
if (!$ids) {
throw new AdminException('参数错误');
}
return $this->dao->batchUpdate($ids, ['is_del' => 1]);
}
/**
* 统计节日有礼领取数据
* @param array $where
* @return array
*/
public function getRecordStatistics(array $where = [])
{
// 总领取人数
$totalUsers = $this->dao->distinct(true)->field('uid')->where($where)->count();
// 总领取次数
$totalRecords = $this->dao->count($where);
// 今日领取人数
$todayWhere = $where;
$todayWhere['receive_time'] = ['>=', strtotime(date('Y-m-d'))];
$todayUsers = $this->dao->distinct(true)->field('uid')->where($todayWhere)->count();
// 今日领取次数
$todayRecords = $this->dao->count($todayWhere);
// 昨日领取人数
$yesterdayStart = strtotime(date('Y-m-d', strtotime('-1 day')));
$yesterdayEnd = strtotime(date('Y-m-d')) - 1;
$yesterdayWhere = $where;
$yesterdayWhere['receive_time'] = ['between', [$yesterdayStart, $yesterdayEnd]];
$yesterdayUsers = $this->dao->distinct(true)->field('uid')->where($yesterdayWhere)->count();
// 昨日领取次数
$yesterdayRecords = $this->dao->count($yesterdayWhere);
// 本月领取人数
$monthWhere = $where;
$monthWhere['receive_time'] = ['>=', strtotime(date('Y-m-01'))];
$monthUsers = $this->dao->distinct(true)->field('uid')->where($monthWhere)->count();
// 本月领取次数
$monthRecords = $this->dao->count($monthWhere);
return [
'total_users' => $totalUsers,
'total_records' => $totalRecords,
'today_users' => $todayUsers,
'today_records' => $todayRecords,
'yesterday_users' => $yesterdayUsers,
'yesterday_records' => $yesterdayRecords,
'month_users' => $monthUsers,
'month_records' => $monthRecords
];
}
/**
* 获取用户可用的多倍积分记录
* @param int $uid 用户ID
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserAvailableMultipleIntegral(int $uid)
{
if (!$uid) {
return [];
}
// 查询用户领取的多倍积分记录,且未使用的
$where = [
'uid' => $uid,
'is_del' => 0,
'status' => 0,
'gift_type' => ['like', '%3%'] // 包含多倍积分类型
];
$list = $this->dao->getList($where);
if (!$list) {
return [];
}
$now = time();
$result = [];
// 获取节日有礼活动信息
$giftIds = array_column($list, 'gift_id');
/** @var HolidayGiftServices $giftService */
$giftService = app()->make(HolidayGiftServices::class);
$giftInfos = $giftService->getHolidayGiftList(['id' => $giftIds])['list'];
$giftInfos = array_combine(array_column($giftInfos, 'id'), $giftInfos);
foreach ($list as $item) {
$giftInfo = $giftInfos[$item['gift_id']] ?? null;
if (!$giftInfo) {
continue;
}
// 检查活动是否有效
if ($giftInfo['status'] != 1 || $giftInfo['is_del'] == 1) {
continue;
}
// 检查活动时间(如果不是永久活动)
if ((!isset($giftInfo['is_permanent']) || $giftInfo['is_permanent'] != 1) &&
($now < $giftInfo['start_time'] || $now > $giftInfo['end_time'])) {
continue;
}
// 添加到结果中
$result[] = [
'record_id' => $item['id'],
'gift_id' => $item['gift_id'],
'gift_name' => $giftInfo['name'],
'integral_multiple' => $giftInfo['integral_multiple'],
'receive_time' => $item['receive_time'],
'end_time' => $giftInfo['end_time']
];
}
return $result;
}
/**
* 获取用户可用的全场包邮记录
* @param int $uid 用户ID
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserAvailableFreeShipping(int $uid)
{
if (!$uid) {
return [];
}
// 查询用户领取的全场包邮记录,且未使用的
$where = [
'uid' => $uid,
'is_del' => 0,
'status' => 0,
'gift_type' => ['like', '%5%'] // 包含全场包邮类型
];
$list = $this->dao->getList($where);
if (!$list) {
return [];
}
$now = time();
$result = [];
// 获取节日有礼活动信息
$giftIds = array_column($list, 'gift_id');
/** @var HolidayGiftServices $giftService */
$giftService = app()->make(HolidayGiftServices::class);
$giftInfos = $giftService->getHolidayGiftList(['id' => $giftIds])['list'];
$giftInfos = array_combine(array_column($giftInfos, 'id'), $giftInfos);
foreach ($list as $item) {
$giftInfo = $giftInfos[$item['gift_id']] ?? null;
if (!$giftInfo) {
continue;
}
// 检查活动是否有效
if ($giftInfo['status'] != 1 || $giftInfo['is_del'] == 1) {
continue;
}
// 检查活动时间(如果不是永久活动)
if ((!isset($giftInfo['is_permanent']) || $giftInfo['is_permanent'] != 1) &&
($now < $giftInfo['start_time'] || $now > $giftInfo['end_time'])) {
continue;
}
// 添加到结果中
$result[] = [
'record_id' => $item['id'],
'gift_id' => $item['gift_id'],
'gift_name' => $giftInfo['name'],
'receive_time' => $item['receive_time'],
'end_time' => isset($giftInfo['is_permanent']) && $giftInfo['is_permanent'] == 1 ? 0 : $giftInfo['end_time']
];
}
return $result;
}
}

View File

@@ -0,0 +1,747 @@
<?php
declare (strict_types=1);
namespace app\services\activity\holiday;
use app\dao\activity\holiday\HolidayGiftDao;
use app\model\activity\holiday\HolidayGift;
use app\services\BaseServices;
use app\services\product\product\StoreProductCouponServices;
use app\services\user\label\UserLabelRelationServices;
use app\services\user\label\UserLabelServices;
use app\services\user\level\UserLevelServices;
use app\services\user\UserServices;
use app\services\activity\coupon\StoreCouponIssueServices;
use app\services\activity\coupon\StoreCouponUserServices;
use app\services\user\UserBillServices;
use crmeb\exceptions\AdminException;
use crmeb\exceptions\ApiException;
use think\exception\ValidateException;
use think\facade\Db;
/**
* 节日有礼服务
* Class HolidayGiftServices
* @package app\services\activity
* @mixin HolidayGiftDao
*/
class HolidayGiftServices extends BaseServices
{
/**
* 构造方法
* HolidayGiftServices constructor.
* @param HolidayGiftDao $dao
*/
public function __construct(HolidayGiftDao $dao)
{
$this->dao = $dao;
}
/**
* 获取节日有礼列表
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getHolidayGiftList(array $where)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getHolidayGiftList($where, '*', $page, $limit);
$count = $this->dao->count($where);
foreach ($list as &$item) {
$item['start_time'] = date('Y-m-d H:i:s', $item['start_time']);
$item['end_time'] = date('Y-m-d H:i:s', $item['end_time']);
// 使用辅助方法转换数值为文本描述
$this->formatHolidayGiftData($item);
}
return compact('list', 'count');
}
/**
* 获取节日有礼详情
* @param int $id
* @param string $field
* @return array|\think\Model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getHolidayGiftInfo(int $id, array $field = ['*'])
{
if (!$id) {
throw new AdminException('参数错误');
}
$info = $this->dao->get($id, $field);
if (!$info) {
throw new AdminException('节日有礼不存在');
}
$info = $info->toArray();
if ($info['is_permanent'] == 0) {
$start_time = $info['start_time'] ? date('Y-m-d H:i:s', (int)$info['start_time']) : '';
$end_time = $info['start_time'] ? date('Y-m-d H:i:s', (int)$info['end_time']) : '';
$info['start_time'] = [$start_time, $end_time];
}
$info['activity_date'] = [];
if ($info['activity_date_type'] == 1) {
$activity_start_date = $info['activity_start_date'] ? date('Y-m-d H:i:s', (int)$info['activity_start_date']) : '';
$activity_end_date = $info['activity_end_date'] ? date('Y-m-d H:i:s', (int)$info['activity_end_date']) : '';
if ($activity_start_date && $activity_end_date) {
$info['activity_date'] = [
$activity_start_date,
$activity_end_date
];
}
}
$coupon_ids = $info['coupon_ids'];
$user_label = $info['user_label'];
if ($coupon_ids) {
$info['coupon'] = app()->make(StoreCouponIssueServices::class)->search([])->whereIn('id', $coupon_ids)->field('id,coupon_title as title')->select()->toArray();
}
if ($user_label) {
$info['label'] = app()->make(UserLabelServices::class)->search([])->whereIn('id', $user_label)->field('id,label_name')->select()->toArray();
}
return $info;
}
/**
* 格式化节日有礼数据,添加文本描述
* @param array &$data 节日有礼数据
* @return void
*/
protected function formatHolidayGiftData(array &$data)
{
// 基本信息
if (isset($data['task_type'])) {
$data['task_type_text'] = HolidayGift::TASK_TYPE[$data['task_type']] ?? '';
}
if (isset($data['birthday_type'])) {
$data['birthday_type_text'] = HolidayGift::BIRTHDAY_TYPE[$data['birthday_type']] ?? '';
}
if (isset($data['status'])) {
$data['status_text'] = HolidayGift::STATUS[$data['status']] ?? '';
}
if (isset($data['is_permanent'])) {
$data['is_permanent_text'] = HolidayGift::IS_PERMANENT[$data['is_permanent']] ?? '';
}
// 推送相关
if (isset($data['push_time_type'])) {
$data['push_time_type_text'] = HolidayGift::PUSH_TIME_TYPE[$data['push_time_type']] ?? '';
}
if (isset($data['push_user_type'])) {
$data['push_user_type_text'] = HolidayGift::PUSH_USER_TYPE[$data['push_user_type']] ?? '';
}
if (isset($data['push_frequency'])) {
$data['push_frequency_text'] = HolidayGift::PUSH_FREQUENCY[$data['push_frequency']] ?? '';
}
if (isset($data['advance_push'])) {
$data['advance_push_text'] = HolidayGift::ADVANCE_PUSH[$data['advance_push']] ?? '';
}
if (isset($data['push_status'])) {
$data['push_status_text'] = HolidayGift::PUSH_STATUS[$data['push_status']] ?? '';
}
// 条件和礼品相关
if (isset($data['condition_type'])) {
$data['condition_type_text'] = HolidayGift::CONDITION_TYPE[$data['condition_type']] ?? '';
}
if (isset($data['gift_type'])) {
if (is_array($data['gift_type'])) {
$data['gift_type_text'] = [];
foreach ($data['gift_type'] as $type) {
$data['gift_type_text'][] = HolidayGift::GIFT_TYPE[$type] ?? '';
}
} else {
$data['gift_type_text'] = HolidayGift::GIFT_TYPE[$data['gift_type']] ?? '';
}
}
// 渠道和页面相关
if (isset($data['push_channel'])) {
if (is_array($data['push_channel'])) {
$data['push_channel_text'] = [];
foreach ($data['push_channel'] as $channel) {
$data['push_channel_text'][] = HolidayGift::PUSH_CHANNEL[$channel] ?? '';
}
} else {
$data['push_channel_text'] = HolidayGift::PUSH_CHANNEL[$data['push_channel']] ?? '';
}
}
if (isset($data['show_page'])) {
if (is_array($data['show_page'])) {
$data['show_page_text'] = [];
foreach ($data['show_page'] as $page) {
$data['show_page_text'][] = HolidayGift::SHOW_PAGE[$page] ?? '';
}
} else {
$data['show_page_text'] = HolidayGift::SHOW_PAGE[$data['show_page']] ?? '';
}
}
}
/**
* 保存节日有礼数据
* @param array $data
* @return mixed
*/
public function saveHolidayGift(array $data)
{
// 数据验证
$this->checkHolidayGiftData($data);
$data['add_time'] = time();
$data['update_time'] = time();
return $this->dao->save($data);
}
/**
* 更新节日有礼数据
* @param int $id
* @param array $data
* @return mixed
*/
public function updateHolidayGift(int $id, array $data)
{
// 数据验证
$this->checkHolidayGiftData($data);
$data['update_time'] = time();
return $this->dao->update($id, $data);
}
/**
* 删除节日有礼
* @param int $id
* @return mixed
*/
public function deleteHolidayGift(int $id)
{
if (!$id) {
throw new AdminException('参数错误');
}
return $this->dao->update($id, ['is_del' => 1]);
}
/**
* 修改节日有礼状态
* @param int $id
* @param int $status
* @return mixed
*/
public function setStatus(int $id, int $status)
{
if (!$id) {
throw new AdminException('参数错误');
}
return $this->dao->update($id, ['status' => $status]);
}
/**
* 验证节日有礼数据
* @param array $data
* @return bool
*/
public function checkHolidayGiftData(array $data)
{
// 验证活动名称
if (!isset($data['name']) || !$data['name']) {
throw new AdminException('请输入活动名称');
}
// 验证活动时间(如果不是永久活动)
if (!isset($data['is_permanent']) || $data['is_permanent'] != 1) {
if (!isset($data['start_time']) || !$data['start_time']) {
throw new AdminException('请选择开始时间');
}
if (!isset($data['end_time']) || !$data['end_time']) {
throw new AdminException('请选择结束时间');
}
if ($data['start_time'] >= $data['end_time']) {
throw new AdminException('结束时间必须大于开始时间');
}
}
// 验证任务类型
if (!isset($data['task_type']) || !in_array($data['task_type'], array_keys(HolidayGift::TASK_TYPE))) {
throw new AdminException('请选择正确的任务类型');
}
// 根据任务类型验证相关数据
if ($data['task_type'] == array_search('用户生日', HolidayGift::TASK_TYPE)) { // 用户生日
if (!isset($data['birthday_type']) || !in_array((int)$data['birthday_type'], array_keys(HolidayGift::BIRTHDAY_TYPE))) {
throw new AdminException('请选择正确的生日类型');
}
} else { // 活动日期
// 验证活动日期类型
if (!isset($data['activity_date_type']) || !in_array((int)$data['activity_date_type'], array_keys(HolidayGift::ACTIVITY_DATE_TYPE))) {
throw new AdminException('请选择正确的活动日期类型');
}
// 根据活动日期类型验证相关数据
switch ($data['activity_date_type']) {
case 1: // 自定义日期
if (!isset($data['activity_start_date']) || !$data['activity_start_date']) {
throw new AdminException('请选择活动开始日期');
}
if (!isset($data['activity_end_date']) || !$data['activity_end_date']) {
throw new AdminException('请选择活动结束日期');
}
break;
case 2: // 每月
if (!isset($data['activity_month_days']) || (is_array($data['activity_month_days']) && empty($data['activity_month_days'])) || !$data['activity_month_days']) {
throw new AdminException('请选择每月活动日期');
}
// 验证月份日期范围 1-31
$monthDays = is_array($data['activity_month_days']) ? $data['activity_month_days'] : explode(',', $data['activity_month_days']);
foreach ($monthDays as $day) {
if (!is_numeric($day) || $day < 1 || $day > 31) {
throw new AdminException('每月活动日期必须在1-31之间');
}
}
break;
case 3: // 每周
if (!isset($data['activity_week_days']) || (is_array($data['activity_week_days']) && empty($data['activity_week_days'])) || !$data['activity_week_days']) {
throw new AdminException('请选择每周活动日期');
}
// 验证周几范围 1-7
$weekDays = is_array($data['activity_week_days']) ? $data['activity_week_days'] : explode(',', $data['activity_week_days']);
foreach ($weekDays as $day) {
if (!is_numeric($day) || $day < 1 || $day > 7) {
throw new AdminException('每周活动日期必须在1-7之间(1表示周一,7表示周日)');
}
}
break;
}
}
// 验证提前推送
if (isset($data['advance_push']) && $data['advance_push']) {
if (!isset($data['advance_days']) || $data['advance_days'] <= 0) {
throw new AdminException('请输入正确的提前推送天数');
}
}
// 验证推送时段
if (isset($data['push_time_type']) && $data['push_time_type'] == array_search('指定时段', HolidayGift::PUSH_TIME_TYPE)) {
if (!isset($data['push_start_time']) || !$data['push_start_time']) {
throw new AdminException('请选择推送开始时间');
}
if (!isset($data['push_end_time']) || !$data['push_end_time']) {
throw new AdminException('请选择推送结束时间');
}
// 验证时间格式 HH:mm:ss 或 HH:mm
if (!preg_match('/^([0-1][0-9]|2[0-3]):([0-5][0-9])(:[0-5][0-9])?$/', $data['push_start_time']) ||
!preg_match('/^([0-1][0-9]|2[0-3]):([0-5][0-9])(:[0-5][0-9])?$/', $data['push_end_time'])) {
throw new AdminException('推送时间格式不正确,应为HH:mm:ss或HH:mm格式');
}
}
// 验证推送人群
if (isset($data['push_user_type']) && $data['push_user_type'] == array_search('指定人群', HolidayGift::PUSH_USER_TYPE)) {
if ((!isset($data['user_level']) || !$data['user_level']) &&
(!isset($data['user_label']) || (is_array($data['user_label']) && empty($data['user_label'])) || !$data['user_label']) &&
(!isset($data['user_tag']) || (is_array($data['user_tag']) && empty($data['user_tag'])) || !$data['user_tag'])) {
throw new AdminException('请至少选择一种用户筛选条件');
}
}
// 验证赠送内容
// if (!isset($data['gift_type']) || !$data['gift_type']) {
// throw new AdminException('请选择赠送内容');
// }
$giftTypes = is_array($data['gift_type']) ? $data['gift_type'] : explode(',', $data['gift_type']);
foreach ($giftTypes as $type) {
if ($type == array_search('优惠券', HolidayGift::GIFT_TYPE) && (!isset($data['coupon_ids']) || (is_array($data['coupon_ids']) && empty($data['coupon_ids'])) || !$data['coupon_ids'])) {
throw new AdminException('请选择赠送的优惠券');
}
if ($type == array_search('积分', HolidayGift::GIFT_TYPE) && (!isset($data['integral']) || $data['integral'] <= 0)) {
throw new AdminException('请输入正确的赠送积分数量');
}
if ($type == array_search('多倍积分', HolidayGift::GIFT_TYPE) && (!isset($data['integral_multiple']) || $data['integral_multiple'] <= 1)) {
throw new AdminException('请输入正确的积分倍数,必须大于1');
}
if ($type == array_search('余额', HolidayGift::GIFT_TYPE) && (!isset($data['balance']) || $data['balance'] <= 0)) {
throw new AdminException('请输入正确的赠送余额');
}
}
// 验证推送渠道
if (!isset($data['push_channel']) || (is_array($data['push_channel']) && empty($data['push_channel'])) || !$data['push_channel']) {
throw new AdminException('请选择推送渠道');
}
$pushChannels = is_array($data['push_channel']) ? $data['push_channel'] : explode(',', $data['push_channel']);
foreach ($pushChannels as $channel) {
if ($channel == array_search('公众号', HolidayGift::PUSH_CHANNEL) && (!isset($data['wechat_image']) || (is_array($data['wechat_image']) && empty($data['wechat_image'])) || !$data['wechat_image'])) {
throw new AdminException('请上传公众号推送图片');
}
}
// 验证推送频次
if (!isset($data['push_frequency']) || !in_array((int)$data['push_frequency'], array_keys(HolidayGift::PUSH_FREQUENCY))) {
throw new AdminException('请选择正确的推送频次');
}
if ($data['push_frequency'] == array_search('每周', HolidayGift::PUSH_FREQUENCY) && (!isset($data['push_week_days']) || (is_array($data['push_week_days']) && empty($data['push_week_days'])) || !$data['push_week_days'])) {
throw new AdminException('请选择每周推送的星期几');
}
// 验证应用界面
if (!isset($data['show_page']) || (is_array($data['show_page']) && empty($data['show_page'])) || !$data['show_page']) {
throw new AdminException('请选择应用界面');
}
$showPages = is_array($data['show_page']) ? $data['show_page'] : explode(',', $data['show_page']);
foreach ($showPages as $page) {
if ($page == array_search('专题页面', HolidayGift::SHOW_PAGE) && (!isset($data['topic_ids']) || (is_array($data['topic_ids']) && empty($data['topic_ids'])) || !$data['topic_ids'])) {
throw new AdminException('请选择专题页面');
}
}
return true;
}
/**
* 获取活动中的节日有礼
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getActiveHolidayGift(array $where = [])
{
return $this->dao->getActiveHolidayGift($where);
}
/**
* 获取用户生日相关的节日有礼活动
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getBirthdayHolidayGift(array $where = [])
{
return $this->dao->getBirthdayHolidayGift($where);
}
/**
* 获取活动日期相关的节日有礼活动
* @param string $date 日期,格式:MM-DD
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getCustomDateHolidayGift(string $date, array $where = [])
{
return $this->dao->getCustomDateHolidayGift($date, $where);
}
/**
* 获取每月活动日期相关的节日有礼活动
* @param int $day 日期,1-31
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getMonthlyHolidayGift(int $day, array $where = [])
{
return $this->dao->getMonthlyHolidayGift($day, $where);
}
/**
* 获取每周活动日期相关的节日有礼活动
* @param int $weekDay 周几,1-7表示周一到周日
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getWeeklyHolidayGift(int $weekDay, array $where = [])
{
return $this->dao->getWeeklyHolidayGift($weekDay, $where);
}
/**
* 获取当前日期相关的所有节日有礼活动
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getTodayHolidayGift(array $where = [])
{
$activities = [];
$today = date('m-d'); // MM-DD格式
$todayDay = (int)date('d'); // 当前日期
$todayWeek = (int)date('N'); // 当前周几,1-7表示周一到周日
// 获取自定义日期活动
$customDateActivities = $this->getCustomDateHolidayGift($today, $where);
$activities = array_merge($activities, $customDateActivities);
// 获取每月活动
$monthlyActivities = $this->getMonthlyHolidayGift($todayDay, $where);
$activities = array_merge($activities, $monthlyActivities);
// 获取每周活动
$weeklyActivities = $this->getWeeklyHolidayGift($todayWeek, $where);
$activities = array_merge($activities, $weeklyActivities);
// 去重(根据ID)
$uniqueActivities = [];
$ids = [];
foreach ($activities as $activity) {
if (!in_array($activity['id'], $ids)) {
$uniqueActivities[] = $activity;
$ids[] = $activity['id'];
}
}
return $uniqueActivities;
}
/**
* 检查用户是否符合节日有礼活动条件
* @param int $uid 用户ID
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
public function checkUserCondition(int $uid, array $giftInfo)
{
// 如果是全部人群,直接返回true
if ($giftInfo['push_user_type'] == 1) {
return true;
}
// 指定人群,需要检查条件
$isLevelMatch = $isLabelMatch = $isTagMatch = true;
// 检查用户等级
if (!empty($giftInfo['user_level'])) {
$isLevelMatch = false;
$userLevelService = app()->make(UserLevelServices::class);
$userLevel = $userLevelService->getUserLevel($uid);
if ($userLevel) {
$levelIds = is_string($giftInfo['user_level']) ? explode(',', $giftInfo['user_level']) : $giftInfo['user_level'];
$isLevelMatch = in_array($userLevel['level_id'], $levelIds);
}
}
// 检查用户标签
if (!empty($giftInfo['user_label'])) {
$isLabelMatch = false;
$userLabelRelationService = app()->make(UserLabelRelationServices::class);
$userLabels = $userLabelRelationService->getUserLabels($uid);
if ($userLabels) {
$labelIds = is_string($giftInfo['user_label']) ? explode(',', $giftInfo['user_label']) : $giftInfo['user_label'];
$isLabelMatch = (bool)empty(array_diff($labelIds, $userLabels));
}
}
// 检查客户身份
if (!empty($giftInfo['user_tag'])) {
$isTagMatch = false;
$userService = app()->make(UserServices::class);
$userTag = $userService->checkUserTag($uid);
if ($userTag) {
$tagIds = is_string($giftInfo['user_tag']) ? explode(',', $giftInfo['user_tag']) : $giftInfo['user_tag'];
$isTagMatch = (bool)empty(array_diff($tagIds, $userTag));
}
}
// 根据条件满足类型返回结果
if ($giftInfo['condition_type'] == 1) { // 满足任一条件
return $isLevelMatch || $isLabelMatch || $isTagMatch;
} else { // 满足全部条件
return $isLevelMatch && $isLabelMatch && $isTagMatch;
}
}
/**
* 检查弹框广告是否符合节日有礼活动条件
* @param int $uid 用户ID
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
public function checkPopupAdCondition(int $uid, array $giftInfo)
{
// 检查推送渠道是否包含弹框广告
$pushChannels = is_array($giftInfo['push_channel']) ? $giftInfo['push_channel'] : explode(',', $giftInfo['push_channel']);
$popupAdChannel = 3;
if (!in_array($popupAdChannel, $pushChannels)) {
return false;
}
// 根据推送频次检查是否可以推送
/** @var HolidayGiftPushServices $pushService */
$pushService = app()->make(HolidayGiftPushServices::class);
switch ($giftInfo['push_frequency']) {
case 1: // 永久一次
// 检查是否已经推送过
$pushRecord = $pushService->getUserPushRecord($uid, $giftInfo['id']);
return empty($pushRecord);
case 2: // 每次进入
return true; // 每次都可以推送
case 3: // 每天
// 检查今天是否已经推送过
$todayRecord = $pushService->getUserTodayPushRecord($uid, $giftInfo['id']);
return empty($todayRecord);
case 4: // 每月
// 检查本月是否已经推送过
$monthRecord = $pushService->getUserMonthPushRecord($uid, $giftInfo['id']);
return empty($monthRecord);
case 5: // 每周
// 检查今天是否是设置的星期几
$weekDay = date('N'); // 1-7 表示周一到周日
$weekDays = explode(',', $giftInfo['push_week_days']);
if (!in_array($weekDay, $weekDays)) {
return false; // 今天不是设置的星期几,不能推送
}
// 检查本周是否已经推送过
$weekRecord = $pushService->getUserWeekPushRecord($uid, $giftInfo['id']);
return empty($weekRecord);
default:
return false;
}
}
/**
* 检查用户是否在推送时段内
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
public function checkPushTimeRange(array $giftInfo, int $uid = 0)
{
// 如果是全时段,直接返回true
if ($giftInfo['push_time_type'] == 1) {
return true;
}
// 指定时段,需要检查当前时间是否在时段内
$now = date('H:i');
$startTime = $giftInfo['push_start_time'];
$endTime = $giftInfo['push_end_time'];
return $now >= $startTime && $now <= $endTime;
}
/**
* 获取当前有效的节日有礼活动
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getActiveHolidayGifts()
{
$currentTime = time();
$where = [
'status' => 1,
'is_del' => 0,
'is_valid' => 1,
];
$list = $this->dao->search($where)
->select()
->toArray();
return $list;
}
/**
* 推送节日有礼消息
* @param int $uid 用户ID
* @param array $giftInfo 节日有礼活动信息
* @return bool
*/
public function pushHolidayGiftMessage(int $uid, array $giftInfo)
{
if (!$uid || !$giftInfo) {
return false;
}
// 获取用户信息
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userInfo = $userService->getUserInfo($uid);
if (!$userInfo) {
return false;
}
// 准备推送记录数据
$pushData = [
'gift_id' => $giftInfo['id'],
'uid' => $uid,
'push_time' => time(),
'status' => 0,
'add_time' => time()
];
// 处理不同推送渠道
$pushChannels = explode(',', $giftInfo['push_channel']);
$pushSuccess = false;
/** @var HolidayGiftPushServices $pushService */
$pushService = app()->make(HolidayGiftPushServices::class);
/** @var NoticeServices $noticeService */
$noticeService = app()->make(NoticeServices::class);
foreach ($pushChannels as $channel) {
switch ($channel) {
case 1: // 短信
if (!empty($userInfo['phone'])) {
$pushData['push_type'] = 1;
$pushData['push_content'] = '尊敬的用户,您有一份节日礼物待领取,请登录APP查看。';
// 发送短信
$noticeService->smsNotice($userInfo['phone'], ['gift_name' => $giftInfo['name']], 'HOLIDAY_GIFT');
$pushData['status'] = 1;
$pushService->save($pushData);
$pushSuccess = true;
}
break;
case 2: // 公众号
if (!empty($userInfo['openid'])) {
$pushData['push_type'] = 2;
$pushData['push_content'] = '尊敬的用户,您有一份节日礼物待领取,请登录APP查看。';
// 发送公众号消息
$noticeService->wechatNotice($userInfo['openid'], 'HOLIDAY_GIFT', [
'first' => '节日有礼提醒',
'keyword1' => $giftInfo['name'],
'keyword2' => date('Y-m-d H:i:s'),
'remark' => '点击领取您的节日礼物'
], '');
$pushData['status'] = 1;
$pushService->save($pushData);
$pushSuccess = true;
}
break;
case 3: // 弹框广告
$pushData['push_type'] = 3;
$pushData['push_content'] = '弹框广告推送';
$pushData['status'] = 1;
$pushService->save($pushData);
$pushSuccess = true;
break;
}
}
return $pushSuccess;
}
}