文件
2026-06-04 22:42:27 +08:00

510 行
16 KiB
PHP

<?php
// 引入数据库模块和用户模块
require_once __DIR__ . '/../db.php';
require_once __DIR__ . '/user.php';
// 格式化时间
function formatTime($timestamp) {
return date('H:i', $timestamp);
}
// 发送消息
function sendMessage($senderId, $receiverId, $content, $isImage = false, $quote = null, $isGroup = false) {
$db = Database::getInstance();
// 创建新消息
$newMessage = [
'id' => generateId(),
'sender_id' => $senderId,
'receiver_id' => $receiverId,
'content' => $content,
'is_image' => $isImage ? 1 : 0,
'is_group' => $isGroup ? 1 : 0,
'timestamp' => getCurrentTimestamp(),
'read' => 0,
'delivered' => 0,
'recalled' => 0
];
// 插入新消息
$sql = "INSERT INTO messages (id, sender_id, receiver_id, content, timestamp, read, delivered, is_image, is_group, recalled)
VALUES (:id, :sender_id, :receiver_id, :content, :timestamp, :read, :delivered, :is_image, :is_group, :recalled)";
$db->execute($sql, $newMessage);
// 添加引用消息信息
if ($quote) {
$db->execute("INSERT INTO message_quotes (message_id, sender, content, quoted_message_id)
VALUES (:message_id, :sender, :content, :quoted_message_id)", [
'message_id' => $newMessage['id'],
'sender' => $quote['sender'],
'content' => $quote['content'],
'quoted_message_id' => isset($quote['message_id']) ? $quote['message_id'] : null
]);
}
// 检查是否是向Parlz官方发送消息
$systemUserId = 100000;
if ($receiverId == $systemUserId && !$isImage) {
// 立即发送一条"正在处理..."的消息给用户
$db = Database::getInstance();
$processingMessage = [
'id' => generateId(),
'sender_id' => $systemUserId,
'receiver_id' => $senderId,
'content' => '正在处理您的消息,请稍候...',
'is_image' => 0,
'is_group' => 0,
'timestamp' => getCurrentTimestamp(),
'read' => 0,
'delivered' => 0,
'recalled' => 0
];
// 插入正在处理的消息
$sql = "INSERT INTO messages (id, sender_id, receiver_id, content, timestamp, read, delivered, is_image, is_group, recalled)
VALUES (:id, :sender_id, :receiver_id, :content, :timestamp, :read, :delivered, :is_image, :is_group, :recalled)";
$db->execute($sql, $processingMessage);
// 同步处理系统消息回复,便于调试
// 记录开始处理消息
file_put_contents(__DIR__ . '/../logs/ai_error.log', date('Y-m-d H:i:s') . ' - 开始处理消息: ' . addslashes($content) . '\n', FILE_APPEND);
// 处理消息
$result = handleSystemMessageReply($senderId, $content);
// 记录处理结果
file_put_contents(__DIR__ . '/../logs/ai_error.log', date('Y-m-d H:i:s') . ' - 处理结果: ' . ($result ? '成功' : '失败') . '\n', FILE_APPEND);
}
return true;
}
// 获取聊天历史(支持私聊和群聊)
function getChatHistory($userId, $targetId, $page = 1, $limit = 20, $olderThan = null, $isGroup = false) {
$db = Database::getInstance();
// 计算偏移量
$offset = ($page - 1) * $limit;
// 构建查询
if ($isGroup) {
// 群组聊天:获取所有发送到该群组的消息
$sql = "SELECT * FROM messages WHERE receiver_id = :targetId AND is_group = 1 ORDER BY timestamp DESC LIMIT :limit OFFSET :offset";
$params = [
'targetId' => $targetId,
'limit' => $limit,
'offset' => $offset
];
// 获取总数
$totalResult = $db->query("SELECT COUNT(*) as total FROM messages WHERE receiver_id = :targetId AND is_group = 1", ['targetId' => $targetId]);
} else {
// 私聊:获取两个用户之间的消息
$sql = "SELECT * FROM messages WHERE (sender_id = :userId AND receiver_id = :targetId) OR
(sender_id = :targetId AND receiver_id = :userId) ORDER BY timestamp DESC LIMIT :limit OFFSET :offset";
$params = [
'userId' => $userId,
'targetId' => $targetId,
'limit' => $limit,
'offset' => $offset
];
// 获取总数
$totalResult = $db->query("SELECT COUNT(*) as total FROM messages WHERE (sender_id = :userId AND receiver_id = :targetId) OR
(sender_id = :targetId AND receiver_id = :userId)", [
'userId' => $userId,
'targetId' => $targetId
]);
}
// 执行查询
$pagedMessages = $db->query($sql, $params);
$total = !empty($totalResult) ? $totalResult[0]['total'] : 0;
if (empty($pagedMessages)) {
return [
'messages' => [],
'total' => $total,
'page' => $page,
'limit' => $limit,
'hasMore' => $offset + $limit < $total
];
}
// 收集需要的用户ID和消息ID
$userIds = [];
$messageIds = [];
foreach ($pagedMessages as $message) {
$messageIds[] = $message['id'];
if ($isGroup && $message['sender_id'] !== $userId) {
$userIds[] = $message['sender_id'];
}
}
// 批量获取用户信息
$usersMap = [];
if (!empty($userIds)) {
$userIds = array_unique($userIds);
$placeholders = [];
$userParams = [];
foreach ($userIds as $index => $id) {
$key = 'id' . $index;
$placeholders[] = ':' . $key;
$userParams[$key] = $id;
}
$userSql = "SELECT * FROM users WHERE id IN (" . implode(',', $placeholders) . ")";
$users = $db->query($userSql, $userParams);
foreach ($users as $user) {
$usersMap[$user['id']] = $user;
}
}
// 批量获取引用信息
$quotesMap = [];
if (!empty($messageIds)) {
$placeholders = [];
$quoteParams = [];
foreach ($messageIds as $index => $id) {
$key = 'id' . $index;
$placeholders[] = ':' . $key;
$quoteParams[$key] = $id;
}
$quoteSql = "SELECT * FROM message_quotes WHERE message_id IN (" . implode(',', $placeholders) . ")";
$quotes = $db->query($quoteSql, $quoteParams);
foreach ($quotes as $quote) {
$quotesMap[$quote['message_id']] = $quote;
}
}
// 按时间正序排序(显示时按时间顺序)
usort($pagedMessages, function($a, $b) {
return $a['timestamp'] - $b['timestamp'];
});
// 格式化消息
$formattedMessages = [];
foreach ($pagedMessages as $message) {
$formattedMessage = [
'id' => $message['id'],
'sender_id' => $message['sender_id'],
'sender' => $message['sender_id'] === $userId ? 'me' : 'other',
'content' => $message['content'],
'is_image' => $message['is_image'] === 1,
'is_group' => $message['is_group'] === 1,
'recalled' => $message['recalled'] === 1,
'read' => $message['read'] === 1,
'delivered' => $message['delivered'] === 1,
'time' => formatTime($message['timestamp']),
'timestamp' => $message['timestamp']
];
// 在群组消息中添加发送者名称和头像
if ($isGroup && $message['sender_id'] !== $userId && isset($usersMap[$message['sender_id']])) {
$senderUser = $usersMap[$message['sender_id']];
$formattedMessage['sender_name'] = $senderUser['username'];
$formattedMessage['sender_avatar'] = isset($senderUser['avatar']) ? $senderUser['avatar'] : '';
}
// 添加引用消息信息
if (isset($quotesMap[$message['id']])) {
$quote = $quotesMap[$message['id']];
$formattedMessage['quote'] = [
'sender' => $quote['sender'],
'content' => $quote['content'],
'message_id' => $quote['quoted_message_id']
];
}
$formattedMessages[] = $formattedMessage;
}
return [
'messages' => $formattedMessages,
'total' => $total,
'page' => $page,
'limit' => $limit,
'hasMore' => $offset + $limit < $total
];
}
// 获取用户的所有未读消息
function getUnreadMessages($userId) {
$db = Database::getInstance();
$result = $db->query("SELECT * FROM messages WHERE receiver_id = :userId AND read = 0", ['userId' => $userId]);
return $result;
}
// 标记消息为已读
function markMessagesAsRead($userId, $senderId) {
$db = Database::getInstance();
$sql = "UPDATE messages SET read = 1 WHERE receiver_id = :userId AND sender_id = :senderId AND read = 0";
return $db->execute($sql, [
'userId' => $userId,
'senderId' => $senderId
]);
}
// 标记消息为已送达
function markMessagesAsDelivered($userId, $senderId) {
$db = Database::getInstance();
$sql = "UPDATE messages SET delivered = 1 WHERE receiver_id = :userId AND sender_id = :senderId AND delivered = 0";
return $db->execute($sql, [
'userId' => $userId,
'senderId' => $senderId
]);
}
// 获取用户的最新消息
function getLatestMessages($userId, $limit = 10) {
$db = Database::getInstance();
$result = $db->query("SELECT * FROM messages WHERE sender_id = :userId OR receiver_id = :userId ORDER BY timestamp DESC LIMIT :limit", [
'userId' => $userId,
'limit' => $limit
]);
return $result;
}
// 删除消息
function deleteMessage($messageId) {
$db = Database::getInstance();
// 删除消息引用
$db->execute("DELETE FROM message_quotes WHERE message_id = :message_id", ['message_id' => $messageId]);
// 删除消息
return $db->execute("DELETE FROM messages WHERE id = :message_id", ['message_id' => $messageId]);
}
// 撤回消息
function recallMessage($senderId, $receiverId, $content, $isGroup = false, $messageId = '') {
$db = Database::getInstance();
$updated = false;
// 如果提供了消息ID,使用消息ID匹配
if ($messageId) {
$result = $db->execute("UPDATE messages SET recalled = 1 WHERE id = :messageId AND sender_id = :senderId", [
'messageId' => $messageId,
'senderId' => $senderId
]);
$updated = $result;
} else {
// 否则使用内容匹配
$result = $db->execute("UPDATE messages SET recalled = 1 WHERE sender_id = :senderId AND receiver_id = :receiverId AND content = :content AND is_group = :isGroup", [
'senderId' => $senderId,
'receiverId' => $receiverId,
'content' => $content,
'isGroup' => $isGroup ? 1 : 0
]);
$updated = $result;
}
return $updated;
}
// 举报消息
function reportMessage($messageId, $reporterId, $reason = '') {
$db = Database::getInstance();
// 检查消息是否存在
$message = $db->query("SELECT * FROM messages WHERE id = :message_id", ['message_id' => $messageId]);
if (empty($message)) {
return false;
}
// 检查是否已经举报过
$existingReport = $db->query("SELECT * FROM reports WHERE message_id = :message_id AND reporter_id = :reporter_id", [
'message_id' => $messageId,
'reporter_id' => $reporterId
]);
if (!empty($existingReport)) {
return false;
}
// 创建新举报
$newReport = [
'id' => generateId(),
'message_id' => $messageId,
'reporter_id' => $reporterId,
'reason' => $reason,
'status' => 'pending',
'created_at' => getCurrentTimestamp()
];
// 插入新举报
$sql = "INSERT INTO reports (id, message_id, reporter_id, reason, status, created_at)
VALUES (:id, :message_id, :reporter_id, :reason, :status, :created_at)";
return $db->execute($sql, $newReport);
}
// 获取所有举报
function getReports($status = null) {
$db = Database::getInstance();
if ($status) {
$result = $db->query("SELECT * FROM reports WHERE status = :status ORDER BY created_at DESC", ['status' => $status]);
} else {
$result = $db->query("SELECT * FROM reports ORDER BY created_at DESC");
}
return $result;
}
// 获取举报详情
function getReportById($reportId) {
$db = Database::getInstance();
$result = $db->query("SELECT * FROM reports WHERE id = :id", ['id' => $reportId]);
return !empty($result) ? $result[0] : null;
}
// 处理举报
function processReport($reportId, $adminId, $action, $reason = '') {
$db = Database::getInstance();
// 更新举报状态
$sql = "UPDATE reports SET status = :status, processed_by = :processed_by, processed_at = :processed_at WHERE id = :id";
$result = $db->execute($sql, [
'status' => $action,
'processed_by' => $adminId,
'processed_at' => getCurrentTimestamp(),
'id' => $reportId
]);
// 如果是删除消息
if ($action === 'deleted') {
$report = $db->query("SELECT message_id FROM reports WHERE id = :id", ['id' => $reportId]);
if (!empty($report)) {
deleteMessage($report[0]['message_id']);
}
}
return $result;
}
// 获取举报的消息详情
function getReportedMessage($messageId) {
$db = Database::getInstance();
$result = $db->query("SELECT * FROM messages WHERE id = :id", ['id' => $messageId]);
if (empty($result)) {
return null;
}
$message = $result[0];
// 获取发送者信息
$sender = $db->query("SELECT * FROM users WHERE id = :id", ['id' => $message['sender_id']]);
if (!empty($sender)) {
$message['sender_info'] = $sender[0];
}
return $message;
}
// 发布系统公告
function publishSystemAnnouncement($title, $content) {
$db = Database::getInstance();
// 虚拟系统账户信息
$systemUserId = 100000;
$systemUsername = 'Parlz官方';
// 构建公告内容
$announcementContent = "【系统公告】$title\n\n$content";
// 获取所有用户
$users = $db->query("SELECT id FROM users");
// 向每个用户发送私信
foreach ($users as $user) {
$userId = $user['id'];
// 创建新消息
$newMessage = [
'id' => generateId(),
'sender_id' => $systemUserId,
'receiver_id' => $userId,
'content' => $announcementContent,
'is_image' => 0,
'is_group' => 0,
'timestamp' => getCurrentTimestamp(),
'read' => 0,
'delivered' => 0,
'recalled' => 0
];
// 插入新消息
$sql = "INSERT INTO messages (id, sender_id, receiver_id, content, timestamp, read, delivered, is_image, is_group, recalled)
VALUES (:id, :sender_id, :receiver_id, :content, :timestamp, :read, :delivered, :is_image, :is_group, :recalled)";
$db->execute($sql, $newMessage);
}
return true;
}
// 获取系统用户信息(虚拟账户)
function getSystemUser() {
return [
'id' => 100000,
'username' => 'Parlz官方',
'avatar' => '',
'is_admin' => true,
'is_banned' => false
];
}
// 处理用户向Parlz官方发送消息的自动回复
function handleSystemMessageReply($senderId, $content) {
$systemUserId = 100000;
$systemUsername = 'Parlz官方';
// 加载本地AI模型
require_once __DIR__ . '/local_ai.php';
$localAI = new LocalAI();
// 使用本地AI模型生成回复
$replyContent = $localAI->generateReply($content);
// 发送回复消息
$db = Database::getInstance();
$newMessage = [
'id' => generateId(),
'sender_id' => $systemUserId,
'receiver_id' => $senderId,
'content' => $replyContent,
'is_image' => 0,
'is_group' => 0,
'timestamp' => getCurrentTimestamp(),
'read' => 0,
'delivered' => 0,
'recalled' => 0
];
// 插入新消息
$sql = "INSERT INTO messages (id, sender_id, receiver_id, content, timestamp, read, delivered, is_image, is_group, recalled)
VALUES (:id, :sender_id, :receiver_id, :content, :timestamp, :read, :delivered, :is_image, :is_group, :recalled)";
$db->execute($sql, $newMessage);
return true;
}
?>