219 lines
6.3 KiB
PHP
219 lines
6.3 KiB
PHP
<?php
|
|
|
|
namespace app\common\model\live;
|
|
|
|
use think\Model;
|
|
|
|
class Message extends Model
|
|
{
|
|
|
|
|
|
// 表名
|
|
protected $name = 'live_message';
|
|
|
|
// 自动写入时间戳字段
|
|
protected $autoWriteTimestamp = 'integer';
|
|
|
|
// 定义时间戳字段名
|
|
protected $createTime = 'createtime';
|
|
protected $updateTime = false;
|
|
protected $deleteTime = false;
|
|
|
|
// 追加属性
|
|
protected $append = [
|
|
|
|
];
|
|
|
|
/**
|
|
* 保存消息
|
|
* @param $userId
|
|
* @param $courseId
|
|
* @param $topic
|
|
* @param $type
|
|
* @param $message
|
|
* @param $status
|
|
* @return void
|
|
*/
|
|
public static function sendMessage($userId,$courseId,$topic,$type,$message,$status){
|
|
// 读取直播间使用的消息服务商
|
|
$provider = \app\common\library\live\message\Manager::providerNameByCourseId($courseId);
|
|
|
|
// 阿里云 MsgType 映射:text→10001, image→10002, gift→10003
|
|
$msgType = \app\common\library\live\message\Message::mapMsgType($type);
|
|
|
|
// 阿里云模式下,发送者ID需传入用户ID(过滤后),便于客户端识别消息来源
|
|
$senderId = '';
|
|
if ($provider === 'aliyun') {
|
|
$senderId = $userId ? ('u-' . $userId) : 'system';
|
|
}
|
|
|
|
// 先落库(阿里云模式下 msg_tid 暂为空,发送成功后回填)
|
|
$data = [
|
|
'uniacid'=>UNIACID,
|
|
'course_id'=>$courseId,
|
|
'user_id'=>$userId,
|
|
'type'=>$type,
|
|
'is_send'=>$status,
|
|
'content'=>$message,
|
|
'status'=>$status,
|
|
'createtime'=>time(),
|
|
'msg_tid'=>'',
|
|
];
|
|
self::insert($data);
|
|
$messageId = self::getLastInsID();
|
|
|
|
if($status){
|
|
$formatMessage = self::formatMessage($userId,$type,$message,$messageId);
|
|
$result = \app\common\library\live\Message::sendByProvider($provider,$topic,$formatMessage,$msgType,$senderId);
|
|
|
|
// 阿里云模式下,保存返回的 msg_tid 用于撤回
|
|
if ($provider === 'aliyun' && $messageId && is_array($result) && isset($result['msg_tid']) && $result['msg_tid']) {
|
|
self::where(['id' => $messageId])->update(['msg_tid' => $result['msg_tid']]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 格式化消息
|
|
* @param int $userId
|
|
* @param string $type
|
|
* @param string $message
|
|
* @param int $messageId 数据库消息ID,用于前端定位(删除等操作)
|
|
* @return false|string
|
|
*/
|
|
public static function formatMessage($userId, $type, $message, $messageId = 0){
|
|
|
|
if($userId == 0){
|
|
$userInfo = [
|
|
'id'=>0,
|
|
'avatar'=>letter_avatar('管'),
|
|
'nickname'=>'管理员'
|
|
];
|
|
}else{
|
|
$userInfo = \app\common\model\User::getUserInfo($userId);
|
|
}
|
|
|
|
|
|
if(!$userInfo){
|
|
throw new \app\common\exception\Exception("获取用户信息出错");
|
|
}
|
|
|
|
return json_encode([
|
|
'id'=>$messageId,
|
|
'user_id'=>$userInfo['id'],
|
|
'nickname'=>$userInfo['nickname'],
|
|
'avatar'=>$userInfo['avatar'],
|
|
'type'=>$type,
|
|
'message'=>$message,
|
|
'time'=>time()
|
|
]);
|
|
}
|
|
|
|
|
|
/**
|
|
* 效验敏感词
|
|
* @param $message
|
|
* @param $banWords array
|
|
* @return void
|
|
*/
|
|
public static function check($message,$banWords){
|
|
|
|
$banWords = array_filter($banWords);
|
|
if(!$banWords){
|
|
return true;
|
|
}
|
|
// 将敏感词列表转换成正则表达式
|
|
$pattern = '/(' . implode('|', $banWords) . ')/i';
|
|
// 使用正则表达式匹配段落中的敏感词
|
|
$matches = array();
|
|
preg_match_all($pattern, $message, $matches);
|
|
// 输出检测结果
|
|
if (!empty($matches[1])) {
|
|
|
|
$sensitive_words_found = array_unique($matches[1]);
|
|
$sensitive_words_str = implode(', ', $sensitive_words_found);
|
|
return $sensitive_words_str;
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
public function user()
|
|
{
|
|
return $this->belongsTo('app\common\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
|
|
}
|
|
|
|
public function liveuser()
|
|
{
|
|
return $this->belongsTo('app\admin\model\live\User', 'user_id', 'user_id', [], 'LEFT')->setEagerlyType(0);
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取消息列表 历史消息
|
|
* @return void
|
|
*/
|
|
public function getMessageList($courseId,$offset,$limit,$role = ''){
|
|
|
|
$query = self::with(['user','liveuser']);
|
|
|
|
if($role == 'user'){
|
|
$query->where('message.user_id','<>',0);
|
|
}
|
|
|
|
if($role == 'admin'){
|
|
$query->where('message.user_id',0);
|
|
}
|
|
|
|
$list = $query
|
|
->where([
|
|
'course_id'=>$courseId,
|
|
'message.status'=>1
|
|
])
|
|
->where(function($query) {
|
|
$query->where('message.user_id', 0)
|
|
->whereOr(function($query) {
|
|
$query->where('message.user_id', '<>', 0)
|
|
->where('liveuser.bantalk', 0)
|
|
->where('liveuser.black', 0);
|
|
});
|
|
})
|
|
->group('message.id')
|
|
->order('createtime', 'desc')
|
|
->limit($offset,$limit)
|
|
->select();
|
|
|
|
$data = [];
|
|
|
|
if(!empty($list)){
|
|
foreach ($list as $item){
|
|
if($item['user_id'] == 0){
|
|
$userInfo = [
|
|
'user_id'=>$item['user_id'],
|
|
'avatar'=>letter_avatar('管'),
|
|
'nickname'=>'管理员'
|
|
];
|
|
}else{
|
|
$userInfo = [
|
|
'user_id'=>$item['user_id'],
|
|
'avatar'=>$item->user->avatar ? $item->user->avatar: letter_avatar($item->user->nickname) ,
|
|
'nickname'=>$item->user->nickname
|
|
];
|
|
}
|
|
$temp = [
|
|
'id'=>$item['id'],
|
|
'time'=>$item['createtime'],
|
|
'message'=>$item['content'],
|
|
'type'=>$item['type'],
|
|
'liveuser'=>$item['liveuser']
|
|
];
|
|
|
|
$data[] = array_merge($temp,$userInfo);
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
} |