add
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace app\models\chat;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 客服状态配置模型
|
||||
* Class ChatAdminStatus
|
||||
* @package app\models\chat
|
||||
*/
|
||||
class ChatAdminStatus extends Model
|
||||
{
|
||||
protected $table = 'cg_chat_admin_status';
|
||||
protected $pk = 'id';
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取客服配置
|
||||
*/
|
||||
public static function getByAdminId(int $adminId): ?array
|
||||
{
|
||||
$status = self::where('admin_id', $adminId)->find();
|
||||
return $status ? $status->toArray() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建客服配置
|
||||
*/
|
||||
public static function getOrCreate(int $adminId): array
|
||||
{
|
||||
$status = self::getByAdminId($adminId);
|
||||
if ($status === null) {
|
||||
$data = [
|
||||
'admin_id' => $adminId,
|
||||
'max_sessions' => 10,
|
||||
'is_enabled' => 1,
|
||||
'create_time' => time(),
|
||||
'update_time' => time(),
|
||||
];
|
||||
self::insert($data);
|
||||
$status = $data;
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新最后在线时间
|
||||
*/
|
||||
public static function updateLastOnlineTime(int $adminId): void
|
||||
{
|
||||
self::where('admin_id', $adminId)->update([
|
||||
'last_online_time' => time(),
|
||||
'update_time' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取启用客服功能的管理员ID列表
|
||||
*/
|
||||
public static function getEnabledAdminIds(): array
|
||||
{
|
||||
return self::where('is_enabled', 1)->column('admin_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace app\models\chat;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 聊天消息模型
|
||||
* Class ChatMessage
|
||||
* @package app\models\chat
|
||||
*/
|
||||
class ChatMessage extends Model
|
||||
{
|
||||
protected $table = 'cg_chat_message';
|
||||
protected $pk = 'id';
|
||||
protected $autoWriteTimestamp = false;
|
||||
|
||||
// 发送者类型
|
||||
const SENDER_USER = 1; // 用户
|
||||
const SENDER_ADMIN = 2; // 客服
|
||||
|
||||
// 消息类型
|
||||
const MSG_TYPE_TEXT = 1; // 文字
|
||||
const MSG_TYPE_IMAGE = 2; // 图片
|
||||
|
||||
// 消息状态
|
||||
const STATUS_PENDING = 0; // 待发送
|
||||
const STATUS_SENT = 1; // 已发送
|
||||
const STATUS_DELIVERED = 2; // 已送达
|
||||
const STATUS_READ = 3; // 已读
|
||||
const STATUS_FAILED = 4; // 发送失败
|
||||
|
||||
/**
|
||||
* 获取会话消息列表
|
||||
*/
|
||||
public static function getBySessionId(int $sessionId, int $limit = 50, int $lastId = 0): array
|
||||
{
|
||||
$query = self::where('session_id', $sessionId);
|
||||
if ($lastId > 0) {
|
||||
$query->where('id', '<', $lastId);
|
||||
}
|
||||
return $query->order('id', 'desc')
|
||||
->limit($limit)
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话未读消息
|
||||
*/
|
||||
public static function getUnreadBySessionId(int $sessionId, int $senderType, int $limit = 50): array
|
||||
{
|
||||
return self::where('session_id', $sessionId)
|
||||
->where('sender_type', '<>', $senderType)
|
||||
->where('status', '<', self::STATUS_READ)
|
||||
->order('id', 'asc')
|
||||
->limit($limit)
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查消息ID是否存在(幂等性)
|
||||
*/
|
||||
public static function existsByMsgId(int $msgId): bool
|
||||
{
|
||||
return self::where('msg_id', $msgId)->count() > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace app\models\chat;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 快捷回复模型
|
||||
* Class ChatQuickReply
|
||||
* @package app\models\chat
|
||||
*/
|
||||
class ChatQuickReply extends Model
|
||||
{
|
||||
protected $table = 'cg_chat_quick_reply';
|
||||
protected $pk = 'id';
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
/**
|
||||
* 获取启用的快捷回复列表
|
||||
*/
|
||||
public static function getEnabledList(?string $category = null): array
|
||||
{
|
||||
$query = self::where('status', 1);
|
||||
if ($category !== null) {
|
||||
$query->where('category', $category);
|
||||
}
|
||||
return $query->order('sort', 'asc')
|
||||
->order('id', 'asc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类列表
|
||||
*/
|
||||
public static function getCategories(): array
|
||||
{
|
||||
return self::where('status', 1)
|
||||
->whereNotNull('category')
|
||||
->where('category', '<>', '')
|
||||
->group('category')
|
||||
->column('category');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace app\models\chat;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 客服会话模型
|
||||
* Class ChatSession
|
||||
* @package app\models\chat
|
||||
*/
|
||||
class ChatSession extends Model
|
||||
{
|
||||
protected $table = 'cg_chat_session';
|
||||
protected $pk = 'id';
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
// 会话状态
|
||||
const STATUS_PENDING = 0; // 待分配
|
||||
const STATUS_ACTIVE = 1; // 进行中
|
||||
const STATUS_ENDED = 2; // 已结束
|
||||
|
||||
// 来源
|
||||
const SOURCE_PC = 1;
|
||||
const SOURCE_GAME = 2;
|
||||
const SOURCE_PORTAL = 3;
|
||||
|
||||
/**
|
||||
* 获取用户活跃会话
|
||||
*/
|
||||
public static function getActiveByUserId(int $userId): ?array
|
||||
{
|
||||
$session = self::where('user_id', $userId)
|
||||
->whereIn('status', [self::STATUS_PENDING, self::STATUS_ACTIVE])
|
||||
->find();
|
||||
return $session ? $session->toArray() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客服进行中的会话列表
|
||||
*/
|
||||
public static function getActiveByAdminId(int $adminId): array
|
||||
{
|
||||
return self::where('admin_id', $adminId)
|
||||
->where('status', self::STATUS_ACTIVE)
|
||||
->order('last_msg_time', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待分配会话数量
|
||||
*/
|
||||
public static function getPendingCount(): int
|
||||
{
|
||||
return self::where('status', self::STATUS_PENDING)->count();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user