dootask/app/Module/Push/PushService.php
kuaifan 9151939ba5 feat(push): 移动端推送从友盟替换为 DooPush 通道
新移动端 (Expo App) 使用 doopush-react-native-sdk 完成设备注册;服务端
按 userid 标签 OR 并集定向推送,替代原友盟 alias 链路。

- 新增 app/Services/DooPushClient.php:DooPush 服务端 HTTP 客户端
  POST /apps/{appId}/push(按 tags 定向)
  POST /apps/{appId}/device-tags/{deviceToken}(绑定 userid 标签)
  DELETE 同上(解绑)
  X-API-Key 鉴权
- 新增 app/Module/Push/PushService.php:推送业务编排
  按 badge(未读数)分组合并下发,减少 HTTP 次数
- 新增 app/Http/Controllers/Api/PushController.php:设备注册/解绑接口
  api/push/register、api/push/unregister
- 修改 app/Models/UmengAlias.php:pushMsgToUserid 入口在
  DooPushClient::enabled() 时委托新通道,否则保留旧友盟链路
- 修改 config/dootask.php:新增 doopush 段(appId/apiKey/baseURL/tag_name)
- 修改 routes/web.php:注册 api/push/{method} 路由
- 同步 routes/api-map.md(doc:api-map 自动生成)

旧 EEUI App 推送链路完全不动;新 App 通过 .env 的 DOOPUSH_ENABLED=yes 启用。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-17 06:55:07 +00:00

59 lines
1.8 KiB
PHP
Raw Permalink 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\Module\Push;
use App\Models\WebSocketDialogMsgRead;
use App\Services\DooPushClient;
/**
* 推送业务编排DooPush 通道)。
*
* UmengAlias::pushMsgToUserid 在 DooPushClient::enabled() 时委托到此处;
* 旧 Umeng 链路仍在 UmengAlias 内部保留,不动 private 方法的可见性。
*/
class PushService
{
/**
* DooPush按 userid 标签 OR 并集定向推送badge 按每个 user 单独取未读数。
*
* DooPush /push 一次只能下发一个 badge需按 badge 分组合并下发以减少 HTTP 次数。
*
* @param array<int>|int $userid
* @param array{title?:string, body?:string, extra?:array} $array
*/
public static function pushToUsers($userid, array $array): void
{
if (empty($userid) || empty($array)) {
return;
}
$userids = is_array($userid) ? array_values(array_filter($userid)) : [(int) $userid];
if (empty($userids)) {
return;
}
// userid -> badge 数;按 badge 分组合并下发
$byBadge = [];
foreach ($userids as $uid) {
$badge = WebSocketDialogMsgRead::whereUserid($uid)
->whereSilence(0)
->whereReadAt(null)
->count();
$byBadge[$badge][] = (int) $uid;
}
foreach ($byBadge as $badge => $batch) {
try {
$msg = $array;
$msg['badge'] = (int) $badge;
$resp = DooPushClient::pushToUserids($batch, $msg);
if (!$resp->successful()) {
info('[DooPush] non-2xx: ' . $resp->status() . ' ' . $resp->body());
}
} catch (\Throwable $e) {
info('[DooPush] exception: ' . $e->getMessage());
}
}
}
}