chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types = 1);
|
||||
namespace addon\wxchat\controller\api;
|
||||
|
||||
use addon\wxchat\model\WxchatMessage;
|
||||
use addon\wxchat\model\WxchatUnreadCount;
|
||||
use think\facade\Db;
|
||||
use think\facade\Request;
|
||||
use ywxapp\controller\FrontendBase;
|
||||
use ywxapp\model\MemberUser as UserModel;
|
||||
use ywxapp\model\MemberProfile as ProfileModel;
|
||||
|
||||
/**
|
||||
* Message 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class Message extends FrontendBase
|
||||
{
|
||||
protected $noNeedLogin = [];
|
||||
protected $noNeedVerify = ['*'];
|
||||
|
||||
|
||||
protected function initialize()
|
||||
{}
|
||||
|
||||
/**
|
||||
* 发送消息(HTTP 落库,WebSocket 实时推送由 worker 处理)
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
$uid = $this->auth->model->uid;
|
||||
$receiverId = (int) Request::post('receiver_id', 0);
|
||||
$receiverType = (int) Request::post('receiver_type', 0); // 0-单聊 1-群聊
|
||||
$content = trim((string) Request::post('content', ''));
|
||||
$contentType = (int) Request::post('content_type', 0);
|
||||
|
||||
if (! $receiverId || $receiverId == $uid) {
|
||||
$this->error('接收者无效');
|
||||
}
|
||||
if ($content === '' && $contentType == 0) {
|
||||
$this->error('消息内容不能为空');
|
||||
}
|
||||
|
||||
$msg = new WxchatMessage();
|
||||
$msg->sender_id = $uid;
|
||||
$msg->receiver_type = $receiverType;
|
||||
$msg->receiver_id = $receiverId;
|
||||
$msg->content = $content;
|
||||
$msg->content_type = $contentType;
|
||||
$msg->save();
|
||||
|
||||
// 更新对方未读计数(单聊)
|
||||
if ($receiverType == 0) {
|
||||
WxchatUnreadCount::increment($receiverId, 0, $uid);
|
||||
}
|
||||
|
||||
$this->success($msg->toArray(), '发送成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 会话历史(单聊 / 群聊)
|
||||
*/
|
||||
public function history()
|
||||
{
|
||||
$uid = $this->auth->uid;
|
||||
$contactId = (int) Request::get('contact_id', 0);
|
||||
$contactType = (int) Request::get('contact_type', 0);
|
||||
$limit = (int) Request::get('limit', 20);
|
||||
$page = (int) Request::get('page', 1);
|
||||
|
||||
if (! $contactId) {
|
||||
$this->error('会话对象无效');
|
||||
}
|
||||
|
||||
$query = WxchatMessage::where('is_recalled', 0)
|
||||
->where('receiver_type', $contactType);
|
||||
if ($contactType == 0) {
|
||||
// 单聊:取双方互发消息(修复原逻辑因外层 receiver_id 过滤而漏掉对方发来的消息)
|
||||
$query->where(function ($q) use ($uid, $contactId) {
|
||||
$q->where(function ($q) use ($uid, $contactId) {
|
||||
$q->where('sender_id', $uid)->where('receiver_id', $contactId);
|
||||
})->whereOr(function ($q) use ($uid, $contactId) {
|
||||
$q->where('sender_id', $contactId)->where('receiver_id', $uid);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$query->where('receiver_id', $contactId);
|
||||
}
|
||||
$list = $query->order('create_at', 'desc')
|
||||
->paginate($limit, false, ['page' => $page]);
|
||||
|
||||
// 单聊:读取后清零未读
|
||||
if ($contactType == 0) {
|
||||
WxchatUnreadCount::reset($uid, 0, $contactId);
|
||||
}
|
||||
|
||||
$this->success([
|
||||
'list' => $list->items(),
|
||||
'total' => $list->total(),
|
||||
'pages' => $list->lastPage(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 未读消息列表
|
||||
*/
|
||||
public function unread()
|
||||
{
|
||||
$uid = $this->auth->model->uid;
|
||||
$list = WxchatUnreadCount::where('user_id', $uid)
|
||||
->where('unread_count', '>', 0)
|
||||
->order('update_at', 'desc')
|
||||
->select();
|
||||
$this->success($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 会话列表(聚合单聊最新一条消息 + 未读 + 对方资料/在线状态)
|
||||
*/
|
||||
public function conversations()
|
||||
{
|
||||
$uid = $this->auth->model->uid;
|
||||
|
||||
$msgs = WxchatMessage::where('receiver_type', 0)
|
||||
->where('is_recalled', 0)
|
||||
->where(function ($q) use ($uid) {
|
||||
$q->where('sender_id', $uid)->whereOr('receiver_id', $uid);
|
||||
})
|
||||
->order('id', 'desc')
|
||||
->limit(1000)
|
||||
->select();
|
||||
|
||||
$convMap = [];
|
||||
$peerIds = [];
|
||||
foreach ($msgs as $m) {
|
||||
$sid = (int) $m->sender_id;
|
||||
$rid = (int) $m->receiver_id;
|
||||
$peer = ($sid == $uid) ? $rid : $sid;
|
||||
if (! isset($convMap[$peer])) {
|
||||
$convMap[$peer] = [
|
||||
'peer_id' => $peer,
|
||||
'last_content' => $m->content,
|
||||
'last_content_type' => (int) $m->content_type,
|
||||
'last_time' => (int) $m->create_at,
|
||||
'last_sender_id' => $sid,
|
||||
];
|
||||
$peerIds[] = $peer;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($peerIds)) {
|
||||
$this->success(['list' => [], 'total' => 0]);
|
||||
return;
|
||||
}
|
||||
|
||||
$users = UserModel::where('uid', 'in', $peerIds)->column('*', 'uid');
|
||||
$unread = WxchatUnreadCount::where('user_id', $uid)
|
||||
->where('contact_type', 0)
|
||||
->where('contact_id', 'in', $peerIds)
|
||||
->column('unread_count', 'contact_id');
|
||||
$onlineMap = MemberProfile::where('uid', 'in', $peerIds)->column('online_status', 'uid');
|
||||
|
||||
$list = [];
|
||||
foreach ($convMap as $peer => $c) {
|
||||
$u = $users[$peer] ?? [];
|
||||
$list[] = [
|
||||
'peer_id' => $peer,
|
||||
'nickname' => $u['nickname'] ?? '',
|
||||
'avatar' => $u['avatar'] ?? '',
|
||||
'online' => ((int) ($onlineMap[$peer] ?? 0)) == 1,
|
||||
'last_content' => $c['last_content'],
|
||||
'last_content_type' => $c['last_content_type'],
|
||||
'last_time' => $c['last_time'],
|
||||
'unread_count' => (int) ($unread[$peer] ?? 0),
|
||||
'is_self' => $c['last_sender_id'] == $uid,
|
||||
];
|
||||
}
|
||||
|
||||
usort($list, function ($a, $b) {
|
||||
return $b['last_time'] - $a['last_time'];
|
||||
});
|
||||
|
||||
$this->success(['list' => $list, 'total' => count($list)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回消息
|
||||
*/
|
||||
public function recall()
|
||||
{
|
||||
$userId = $this->auth->model->uid;
|
||||
$messageId = (int) Request::post('message_id', 0);
|
||||
|
||||
$message = WxchatMessage::find($messageId);
|
||||
if (! $message || $message->sender_id != $userId) {
|
||||
$this->error('无权撤回', 403);
|
||||
}
|
||||
|
||||
$message->is_recalled = 1;
|
||||
$message->recalled_at = date('Y-m-d H:i:s');
|
||||
$message->save();
|
||||
|
||||
$this->success([], '撤回成功');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user