Files
p_ysk/app/model/MessagePushTask.php
2025-09-17 18:03:28 +08:00

435 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\model;
// 消息推送
use support\Log;
use support\think\Db;
use EasyWeChat\Factory;
class MessagePushTask
{
public static function send_msg()
{
// 查询任务
$event_list = Db::name('tb_push_event')->where(['status' => 0])->select();
if($event_list) {
try {
Db::startTrans();
foreach ($event_list as $k => $event) {
Db::name('tb_push_event')->where(['id' => $event['id']])->update(['status' => 1, 'start_time' => date('Y-m-d H:i:s')]);
$res = self::getPullInfoUser($event);
if($res) {
foreach ($res as $rk => &$rv) {
if(empty($rv['open_id'])) {
unset($res[$rk]);
}
$rv['push_event_id'] = $event['id'];
$rv['template_id'] = $event['template_id'];
$rv['keyword1'] = $event['keyword1'];
$rv['keyword2'] = $event['keyword2'];
$rv['keyword3'] = $event['keyword3'];
$rv['keyword4'] = $event['keyword4'];
$rv['keyword5'] = $event['keyword5'];
}
$user_list = uniqueMultidimensionalArray($res);
// 需要接收推送的用户 准备发送
foreach ($user_list as $k => $user) {
$user_push_list_res_id = Db::name('tb_user_push_event')->insertGetId([
'push_event_id' => $user['push_event_id'],
'user_id' => $user['user_id'],
'create_time' => date("Y-m-d H:i:s"),
]);
if($user_push_list_res_id) {
$app = Factory::officialAccount([
'app_id' => config('cons.app_id'),
'secret' => config('cons.secret'),
'response_type' => 'array',
]);
$data = [
'thing2' => $user['keyword1'],
'amount3' => $user['keyword2'],
'time6' => $user['keyword3'],
];
// 正式推送
$push = $app->template_message->send([
'touser' => $user['open_id'],
'template_id' => $user['template_id'],
'data' => $data
]);
Log::info('用户-' . $user['user_id'] . ' 推送模版ID'. $user['template_id'] .' 内容:' . json_encode($data, 256) . ' 推送结果:' . json_encode($push));
if($push['errcode'] == 0) {
Db::name('tb_user_push_event')->where(['id' => $user_push_list_res_id])->update(['update_time' => date("Y-m-d H:i:s"), 'status' => 1]);
}else {
Db::name('tb_user_push_event')->where(['id' => $user_push_list_res_id])->update(['update_time' => date("Y-m-d H:i:s"), 'status' => -1, 'error' => json_encode($push)]);
}
}
sleep(1);
}
Db::name('tb_push_event')->where(['id' => $event['id']])->update(['status' => 2, 'send_time' => date('Y-m-d H:i:s')]);
}
}
Db::commit();
}catch (\Exception $e) {
Log::info('执行出错--' . $e->getMessage());
Db::rollback();
}
}
Log::info('没有推送任务可执行');
return true;
}
/**
* 找到可以接收订阅消息的用户
* @param $type类型 1按次数发送 2自定义 3按标签
* @return array
*/
public static function getPullInfoUser($event): array
{
$user_arr = [];
switch ($event['type']) {
case 1;
$user_arr = self::getPullInfoUserToNumber($event);
break;
case 2;
$user_arr = self::getPullInfoUserToCustom($event);
break;
case 3;
$user_arr = self::getPullInfoUserToLabel($event);
break;
}
return $user_arr;
}
// 按照可接收次数获取用户信息
public static function getPullInfoUserToNumber($event)
{
$user_num = [];
if($event['can_send_times'] > 0) {
$user_num = Db::name('tb_user_push_event_num')->alias('upen')->where('upen.num', '>=', $event['can_send_times'])
->join('tb_user_info u', 'upen.user_id = u.id')
->field('upen.user_id as user_id, upen.open_id as open_id')
->select()
->toArray();
}
return $user_num;
}
// 按照自定义获取用户信息
public static function getPullInfoUserToCustom($event)
{
$data_arr = [];
// 按照性别
if(isset($event['gender']) && is_string($event['gender'])) {
$gender_data_arr = [];
$gender_arr = explode(',', $event['gender']);
foreach ($gender_arr as $k => $gender) {
// 未知
if($gender == 0) {
$gender_data_res = Db::name('tb_user_info')->whereNotIn('sex', [0,1])
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 男
if($gender == 1) {
$gender_data_res = Db::name('tb_user_info')->where('sex', 1)
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 女
if($gender == 2) {
$gender_data_res = Db::name('tb_user_info')->where('sex', 0)
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
if($gender_data_arr) {
$gender_data_arr = array_merge($gender_data_arr, $gender_data_res);
}else {
$gender_data_arr = $gender_data_res;
}
}
if($gender_data_arr) {
$data_arr = array_merge($data_arr, $gender_data_arr);
}
}
// 按照下单次数
if(isset($event['order_history']) && is_string($event['order_history'])) {
$order_history_arr = explode(',', $event['order_history']);
$order_history_data_arr = [];
foreach ($order_history_arr as $k => $order_history) {
// 从未下单
if($order_history == 0) {
$order_history_data_res = Db::name('tb_user_info')
->alias('u') // 用户表别名u
->leftJoin('tb_order_info o', 'u.id = o.user_id')
->where('o.user_id', 'null')
->distinct()
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 下过1单
if($order_history == 1) {
$order_history_data_res = Db::name('tb_user_info')
->alias('u')
// 关联订单表,使用内连接确保只包含有订单的用户
->join('tb_order_info o', 'u.id = o.user_id')
// 按用户ID分组
->group('u.id')
// 筛选出订单数量为1的用户
->having('COUNT(o.id) = 1')
// 选择需要的用户字段,同时查询订单数量(可选)
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 下过2-5单
if($order_history == 2) {
$order_history_data_res = Db::name('tb_user_info')
->alias('u')
// 关联订单表,使用内连接确保只包含有订单的用户
->join('tb_order_info o', 'u.id = o.user_id')
// 按用户ID分组
->group('u.id')
// 筛选出订单数量为1的用户
->having('COUNT(o.id) BETWEEN 2 AND 5')
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 下过5单起
if($order_history == 3) {
$order_history_data_res = Db::name('tb_user_info')
->alias('u')
// 关联订单表,使用内连接确保只包含有订单的用户
->join('tb_order_info o', 'u.id = o.user_id')
// 按用户ID分组
->group('u.id')
// 筛选出订单数量为1的用户
->having('COUNT(o.id) >= 5')
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->select()
->toArray();
}
if($order_history_data_arr) {
$order_history_data_arr = array_merge($order_history_data_arr, $order_history_data_res);
;
}else {
$order_history_data_arr = $order_history_data_res;
}
}
if($order_history_data_arr) {
$data_arr = array_merge($data_arr, $gender_data_arr);
}
}
// 按照下单时间
if(isset($event['order_times']) && is_string($event['order_times'])) {
$order_times_arr = explode(',', $event['order_times']);
$order_times_data_arr = [];
foreach ($order_times_arr as $k => $order_times) {
// 今天下过
if($order_times == 0) {
$order_times_data_res = Db::name('tb_user_info')
->alias('u') // 用户表别名u
->join('tb_order_info o', 'u.id = o.user_id')
->where('o.create_time', '>=', date('Y-m-d 00:00:00'))
->where('o.create_time', '<=', date('Y-m-d 23:59:59'))
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->distinct()
->select()
->toArray();
}
// 昨天下过
if($order_times == 1) {
$order_times_data_res = Db::name('tb_user_info')
->alias('u') // 用户表别名u
->join('tb_order_info o', 'u.id = o.user_id')
->where('o.create_time', '>=', date('Y-m-d 00:00:00', strtotime('-1 day')))
->where('o.create_time', '<=', date('Y-m-d 23:59:59', strtotime('-1 day')))
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->distinct()
->select()
->toArray();
}
// 2周内没下过
if($order_times == 2) {
$twoWeeksAgo = date('Y-m-d H:i:s', strtotime('-14 days'));
$order_times_data_res = Db::name('tb_user_info')
->alias('u') // 用户表别名u
// 左连接订单表,关联条件包含近两周内的订单
->leftJoin('tb_order_info o', 'u.id = o.user_id')
->where('o.create_time', '>=', $twoWeeksAgo)
->where('o.id', 'null')
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->distinct()
->select()
->toArray();
}
// 半个月-1个月没下过
if($order_times == 3) {
$startTime = date('Y-m-d H:i:s', strtotime('-30 days'));
$endTime = date('Y-m-d H:i:s', strtotime('-15 days'));
$order_times_data_res = Db::name('tb_user_info')
->alias('u') // 用户表别名u
// 左连接订单表,关联条件包含近两周内的订单
->join('tb_order_info o', 'u.id = o.user_id')
// 按用户分组
->group('u.id')
// 筛选最后下单时间在30天前到15天前之间的用户
->having('MAX(o.create_time) >="'. $startTime .'" AND MAX(o.create_time) <= "' . $endTime . '"')
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 1个月以上没下过
if($order_times == 4) {
$oneMonthAgo = date('Y-m-d H:i:s', strtotime('-30 days'));
$order_times_data_res = Db::name('tb_user_info')
->alias('u') // 用户表别名u
// 左连接订单表,关联条件包含近两周内的订单
->join('tb_order_info o', 'u.id = o.user_id')
// 按用户分组
->group('u.id')
// 筛选最后下单时间在1个月前及更早
->having('MAX(o.create_time) <= "' . $oneMonthAgo . '"')
// ->field('u.id as user_id, u.wechat_ac_open_id as open_id, MAX(o.create_time) as last_order_time')
->field('u.id as user_id, u.wechat_ac_open_id as open_id')
->select()
->toArray();
}
if($order_times_data_arr) {
$order_times_data_arr = array_merge($order_times_data_arr, $order_times_data_res);
}else {
$order_times_data_arr = $order_times_data_res;
}
}
if($order_times_data_arr) {
$data_arr = array_merge($data_arr, $order_times_data_arr);
}
// 按照会员
if(isset($event['vip']) && is_string($event['vip'])) {
$vip_data_arr = [];
$vip_arr = explode(',', $event['vip']);
foreach ($vip_arr as $k => $vip) {
// 非会员
if($vip == 0) {
$vip_data_res = Db::name('tb_user_info')->whereNotIn('is_vip', 0)
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 会员
if($vip == 1) {
$vip_data_res = Db::name('tb_user_info')->where('is_vip', 1)
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
if($vip_data_arr) {
$vip_data_arr = array_merge($vip_data_arr, $vip_data_res);
}else {
$vip_data_arr = $vip_data_res;
}
}
if($vip_data_arr) {
$data_arr = array_merge($data_arr, $vip_data_arr);
}
}
// 按照手机号
if(isset($event['telphone']) && is_string($event['telphone'])) {
$telphone_data_arr = [];
$telphone_arr = explode(',', $event['telphone']);
foreach ($telphone_arr as $k => $telphone) {
// 非绑定
if($telphone == 0) {
$telphone_data_res = Db::name('tb_user_info')->where(function ($query) {
$query->where('phone', 'null') // 为 NULL
->whereOr('phone', ''); // 为空字符串
})
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
// 已绑定
if($telphone == 1) {
$telphone_data_res = Db::name('tb_user_info')->where('phone', '<>', '')
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
if($telphone_data_arr) {
$telphone_data_arr = array_merge($telphone_data_arr, $telphone_data_res);
}else {
$telphone_data_arr = $telphone_data_res;
}
}
if($telphone_data_arr) {
$data_arr = array_merge($data_arr, $telphone_data_arr);
}
}
}
return $data_arr;
}
// 按照标签获取用户信息
public static function getPullInfoUserToLabel($event)
{
$data_arr = [];
$label = Db::name('tb_user_label')->whereIn('label_id', explode(',', $event['user_label']))
->distinct()
->column('user_id');
if($label) {
$data_arr = Db::name('tb_user_info')->whereIn('id', $label)
->field('id as user_id, wechat_ac_open_id as open_id')
->select()
->toArray();
}
return $data_arr;
}
// 给用户送送优惠券
public static function sendUserCoupon(int | array $user_id, $coupon_id, $number = 1)
{
try {
Db::startTrans();
if(is_int($user_id)) {
}elseif (is_array($user_id)) {
}
Db::commit();
return true;
}catch (\Exception $e) {
Db::rollback();
Log::info('用户送券异常-->' . $e->getMessage());
return false;
}
}
}