Files
chatroom/app/Services/WechatBot/WechatNotificationService.php
lkddi fc57f97c9e feat(wechat): 微信机器人全链路集成与稳定性修复
- 新增:管理员后台的微信机器人双向收发参数设置页面及扫码绑定能力。
- 新增:WechatBotApiService 与 KafkaConsumerService 模块打通过往僵尸进程导致的拒绝连接问题。
- 新增:下发所有群发/私聊通知时统一带上「[和平聊吧]」标注前缀。
- 优化:前端个人中心绑定逻辑支持一键生成及复制动态口令。
- 修复:闭环联调修补各个模型中产生的变量警告如 stdClass 对象获取等异常预警。
2026-04-02 14:56:51 +08:00

195 lines
5.5 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
/**
* 文件功能:微信消息发送核心业务逻辑服务
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Services\WechatBot;
use App\Jobs\SendWechatBotMessage;
use App\Models\SysParam;
use App\Models\User;
use Illuminate\Support\Facades\Redis;
class WechatNotificationService
{
protected array $config = [];
protected bool $globalEnabled = false;
public function __construct()
{
$param = SysParam::where('alias', 'wechat_bot_config')->first();
if ($param && ! empty($param->body)) {
$this->config = json_decode($param->body, true) ?? [];
}
}
/**
* 管理员上线群通知
*/
public function notifyAdminOnline(User $user): void
{
if (empty($this->config['group_notify']['toggle_admin_online'])) {
return;
}
$groupWxid = $this->config['group_notify']['target_wxid'] ?? '';
if (! $groupWxid) {
return;
}
// 判断是否真的是管理员(这里假设大于等于某等级,比如 15
$adminLevel = (int) Sysparam::getValue('level_kick', '15');
if ($user->user_level < $adminLevel) {
return;
}
$message = "👑 【管理员上线】\n"
."管理员 [{$user->username}] 刚刚登录了系统。";
SendWechatBotMessage::dispatch($groupWxid, $message);
}
/**
* 百家乐开奖群通知
*/
public function notifyBaccaratResult(string $historyText): void
{
if (empty($this->config['group_notify']['toggle_baccarat_result'])) {
return;
}
$groupWxid = $this->config['group_notify']['target_wxid'] ?? '';
if (! $groupWxid) {
return;
}
$message = "🎰 【百家乐开奖】\n{$historyText}";
SendWechatBotMessage::dispatch($groupWxid, $message);
}
/**
* 彩票开奖群通知
*/
public function notifyLotteryResult(string $historyText): void
{
if (empty($this->config['group_notify']['toggle_lottery_result'])) {
return;
}
$groupWxid = $this->config['group_notify']['target_wxid'] ?? '';
if (! $groupWxid) {
return;
}
$message = "🎲 【彩票开奖】\n{$historyText}";
SendWechatBotMessage::dispatch($groupWxid, $message);
}
/**
* 好友上线私聊通知(带冷却)
*/
public function notifyFriendsOnline(User $user): void
{
if (empty($this->config['personal_notify']['toggle_friend_online'])) {
return;
}
$cacheKey = "wechat_notify_cd:friend_online:{$user->id}";
if (Redis::exists($cacheKey)) {
return;
}
// 假定有好友关系模型 Friends (视具体业务而定,目前先预留或者查询好友)
$friends = $this->getUserFriends($user->id);
foreach ($friends as $friend) {
if ($friend->wxid) {
$message = "👋 【好友上线】\n您的好友 [{$user->username}] 刚刚上线了!";
SendWechatBotMessage::dispatch($friend->wxid, $message);
}
}
// 冷却 30 分钟
Redis::setex($cacheKey, 1800, 1);
}
/**
* 夫妻上线私聊通知(带冷却)
*/
public function notifySpouseOnline(User $user): void
{
if (empty($this->config['personal_notify']['toggle_spouse_online'])) {
return;
}
$cacheKey = "wechat_notify_cd:spouse_online:{$user->id}";
if (Redis::exists($cacheKey)) {
return;
}
// 获取伴侣
$spouse = $this->getUserSpouse($user);
if ($spouse && $spouse->wxid) {
$message = "❤️ 【伴侣上线】\n您的伴侣 [{$user->username}] 刚刚上线了!";
SendWechatBotMessage::dispatch($spouse->wxid, $message);
// 冷却 30 分钟
Redis::setex($cacheKey, 1800, 1);
}
}
/**
* 等级变动私聊通知
*/
public function notifyLevelChange(User $user, int $oldLevel, int $newLevel): void
{
if (empty($this->config['personal_notify']['toggle_level_change'])) {
return;
}
if (! $user->wxid || $newLevel <= $oldLevel) {
return;
}
$message = "✨ 【等级提升】\n"
."恭喜您!您的聊天室等级已从 LV{$oldLevel} 提升至 LV{$newLevel}";
SendWechatBotMessage::dispatch($user->wxid, $message);
}
// ---------------------------------------------------------
// Helper Methods (Mocking the real data retrieval methods)
// ---------------------------------------------------------
protected function getUserFriends(int $userId)
{
// 假定有好友表
if (\Illuminate\Support\Facades\Schema::hasTable('friends')) {
return \Illuminate\Support\Facades\DB::table('friends')
->join('users', 'users.id', '=', 'friends.friend_id')
->where('friends.user_id', $userId)
->whereNotNull('users.wxid')
->select('users.*')
->get();
}
return collect([]);
}
protected function getUserSpouse(User $user)
{
// 如果有配偶字段
$mateName = $user->peiou ?? null;
if ($mateName && $mateName !== '无' && $mateName !== '') {
return User::where('username', $mateName)->whereNotNull('wxid')->first();
}
return null;
}
}