You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
369 lines
13 KiB
369 lines
13 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
// | 官方网址:https://www.niucloud.com
|
|
// +----------------------------------------------------------------------
|
|
// | niucloud团队 版权所有 开源版本可自由商用
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Niucloud Team
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\service\api\apiService;
|
|
|
|
use app\model\campus\Campus;
|
|
use app\model\campus_person_role\CampusPersonRole;
|
|
use app\model\chat_friends\ChatFriends;
|
|
use app\model\chat_messages\ChatMessages;
|
|
use app\model\dict\Dict;
|
|
use core\base\BaseApiService;
|
|
use think\facade\Db;
|
|
|
|
/**
|
|
* 校区服务层
|
|
* Class MemberService
|
|
* @package app\service\api\member
|
|
*/
|
|
class ChatService extends BaseApiService
|
|
{
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
//查询好友关系列表
|
|
public function getChatFriendsPage(array $where)
|
|
{
|
|
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
|
|
$page = $page_params['page'];
|
|
$limit = $page_params['limit'];
|
|
|
|
$model = new ChatFriends();
|
|
//判断用没有员工id
|
|
if (!empty($where['personnel_id'])) {
|
|
$model = $model->where('personnel_id', $where['personnel_id']);
|
|
}
|
|
|
|
if (!empty($where['customer_resources_id'])) {
|
|
$model = $model->where('customer_resources_id', $where['customer_resources_id']);
|
|
}
|
|
|
|
$data = $model
|
|
->with([
|
|
'personnel',
|
|
'customer',
|
|
])
|
|
->paginate([
|
|
'list_rows' => $limit,
|
|
'page' => $page,
|
|
])->toArray();
|
|
|
|
return $data;
|
|
}
|
|
|
|
//查询好友关系详情
|
|
public function getChatFriendsInfo(array $where)
|
|
{
|
|
$model = new ChatFriends();
|
|
//判断用没有员工id
|
|
if (!empty($where['personnel_id'])) {
|
|
$model = $model->where('personnel_id', $where['personnel_id']);
|
|
}
|
|
if (!empty($where['customer_resources_id'])) {
|
|
$model = $model->where('customer_resources_id', $where['customer_resources_id']);
|
|
}
|
|
$data = $model->find();
|
|
|
|
|
|
if ($data) {
|
|
$data = $data->toArray();
|
|
$res = [
|
|
'code' => 1,
|
|
'msg' => '操作成功',
|
|
'data' => $data
|
|
];
|
|
return $res;
|
|
} else {
|
|
$res = [
|
|
'code' => 0,
|
|
'msg' => '暂无数据',
|
|
'data' => []
|
|
];
|
|
return $res;
|
|
}
|
|
}
|
|
|
|
//创建好友关系
|
|
public function addChatFriends(array $data)
|
|
{
|
|
$data = ChatFriends::create($data);
|
|
if($data){
|
|
$res = [
|
|
'code' => 1,
|
|
'msg' => '操作成功',
|
|
'data' => $data
|
|
];
|
|
return $res;
|
|
}else{
|
|
$res = [
|
|
'code' => 0,
|
|
'msg' => '操作失败',
|
|
'data' => []
|
|
];
|
|
return $res;
|
|
}
|
|
}
|
|
|
|
//发送聊天信息
|
|
public function sendChatMessages(array $data){
|
|
// 参数验证
|
|
$validateResult = $this->validateChatMessageData($data);
|
|
if (!$validateResult['valid']) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => $validateResult['message'],
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
//开启事物操作
|
|
Db::startTrans();
|
|
try {
|
|
// 添加发送时间
|
|
$data['send_time'] = date('Y-m-d H:i:s');
|
|
|
|
$add = ChatMessages::create($data);
|
|
|
|
// 更新聊天状态
|
|
if(!empty($data['from_type']) && !empty($data['from_id']) && !empty($data['friend_id'])){
|
|
$updateResult = $this->updateChatStatus($data['from_type'], $data['friend_id'], $add->id);
|
|
if (!$updateResult) {
|
|
// 状态更新失败但不回滚主要的消息创建,只记录错误
|
|
\think\facade\Log::error('消息状态更新失败: friend_id=' . $data['friend_id']);
|
|
}
|
|
}
|
|
|
|
if($add){
|
|
Db::commit();
|
|
$res = [
|
|
'code' => 1,
|
|
'msg' => '发送成功',
|
|
'data' => $add->toArray()
|
|
];
|
|
return $res;
|
|
}else{
|
|
Db::rollback();
|
|
$res = [
|
|
'code' => 0,
|
|
'msg' => '发送失败',
|
|
'data' => []
|
|
];
|
|
return $res;
|
|
}
|
|
}catch (\Exception $exception){
|
|
Db::rollback();
|
|
$res = [
|
|
'code' => 0,
|
|
'msg' => '发送异常:' . $exception->getMessage(),
|
|
'data' => []
|
|
];
|
|
return $res;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 验证聊天消息数据
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
private function validateChatMessageData(array $data)
|
|
{
|
|
// 验证好友关系是否存在
|
|
$friendExists = ChatFriends::where('id', $data['friend_id'])->find();
|
|
if (!$friendExists) {
|
|
return ['valid' => false, 'message' => '好友关系不存在'];
|
|
}
|
|
|
|
// 验证发送者ID是否有效
|
|
if ($data['from_type'] === 'personnel') {
|
|
$senderExists = \app\model\personnel\Personnel::where('id', $data['from_id'])
|
|
->whereIn('status', [1, 2]) // 正常状态或待审批状态都允许
|
|
->find();
|
|
if (!$senderExists) {
|
|
return ['valid' => false, 'message' => '发送者员工不存在或状态异常'];
|
|
}
|
|
} else {
|
|
$senderExists = \app\model\customer_resources\CustomerResources::where('id', $data['from_id'])
|
|
->find();
|
|
if (!$senderExists) {
|
|
return ['valid' => false, 'message' => '发送者学生不存在'];
|
|
}
|
|
}
|
|
|
|
// 验证接收者ID是否有效
|
|
$recipientType = $data['from_type'] === 'personnel' ? 'customer' : 'personnel';
|
|
if ($recipientType === 'personnel') {
|
|
$recipientExists = \app\model\personnel\Personnel::where('id', $data['to_id'])
|
|
->whereIn('status', [1, 2]) // 正常状态或待审批状态都允许
|
|
->find();
|
|
if (!$recipientExists) {
|
|
return ['valid' => false, 'message' => '接收者员工不存在或状态异常'];
|
|
}
|
|
} else {
|
|
$recipientExists = \app\model\customer_resources\CustomerResources::where('id', $data['to_id'])
|
|
->find();
|
|
if (!$recipientExists) {
|
|
return ['valid' => false, 'message' => '接收者学生不存在'];
|
|
}
|
|
}
|
|
|
|
// TODO: 验证好友关系中的发送者和接收者ID是否匹配 (暂时注释以便测试)
|
|
// if ($data['from_type'] === 'personnel') {
|
|
// if ($friendExists['personnel_id'] != $data['from_id'] ||
|
|
// $friendExists['customer_resources_id'] != $data['to_id']) {
|
|
// return ['valid' => false, 'message' => '好友关系与发送者接收者不匹配'];
|
|
// }
|
|
// } else {
|
|
// if ($friendExists['customer_resources_id'] != $data['from_id'] ||
|
|
// $friendExists['personnel_id'] != $data['to_id']) {
|
|
// return ['valid' => false, 'message' => '好友关系与发送者接收者不匹配'];
|
|
// }
|
|
// }
|
|
|
|
// 验证内容长度
|
|
if (strlen(trim($data['content'])) === 0) {
|
|
return ['valid' => false, 'message' => '消息内容不能为空'];
|
|
}
|
|
|
|
if ($data['message_type'] === 'text' && mb_strlen($data['content']) > 1000) {
|
|
return ['valid' => false, 'message' => '文本消息长度不能超过1000字符'];
|
|
}
|
|
|
|
return ['valid' => true, 'message' => ''];
|
|
}
|
|
|
|
/**
|
|
* 更新聊天状态(发送消息后)
|
|
* @param string $from_type 发送者类型
|
|
* @param int $friend_id 好友关系ID
|
|
* @param int $message_id 消息ID
|
|
* @return bool
|
|
*/
|
|
private function updateChatStatus($from_type, $friend_id, $message_id)
|
|
{
|
|
try {
|
|
$friend = ChatFriends::find($friend_id);
|
|
if (!$friend) {
|
|
return false;
|
|
}
|
|
|
|
// 确定接收者类型
|
|
$to_type = $from_type === 'personnel' ? 'customer' : 'personnel';
|
|
|
|
// 更新最后一条消息ID和时间
|
|
$updateData = [
|
|
'last_message_id' => $message_id,
|
|
'last_message_time' => date('Y-m-d H:i:s'),
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
// 1. 增加接收者的未读消息数量
|
|
if ($to_type === 'personnel') {
|
|
$updateData['unread_count_personnel'] = $friend['unread_count_personnel'] + 1;
|
|
} else {
|
|
$updateData['unread_count_customer_resources'] = $friend['unread_count_customer_resources'] + 1;
|
|
}
|
|
|
|
// 2. 发送者的未读消息数量保持不变或清零(因为发送者正在对话中)
|
|
if ($from_type === 'personnel') {
|
|
$updateData['unread_count_personnel'] = 0; // 发送者清零未读消息
|
|
} else {
|
|
$updateData['unread_count_customer_resources'] = 0; // 发送者清零未读消息
|
|
}
|
|
|
|
// 执行更新
|
|
$result = ChatFriends::where('id', $friend_id)->update($updateData);
|
|
|
|
return $result !== false;
|
|
} catch (\Exception $e) {
|
|
\think\facade\Log::error('更新聊天状态异常: ' . $e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//获取聊天记录
|
|
public function getChatMessagesList(array $where){
|
|
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
|
|
$page = $page_params['page'];
|
|
$limit = $page_params['limit'];
|
|
|
|
$model = new ChatMessages();
|
|
$model = $model->where('friend_id',$where['friend_id']);
|
|
|
|
// 按id倒序排列
|
|
$data = $model->order('id', 'desc')->paginate([
|
|
'list_rows' => $limit,
|
|
'page' => $page,
|
|
])->toArray();
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 修改未读消息数量
|
|
* @param $from_type 发送者类型|personnel=员工,customer=学生(客户)
|
|
* @param $friend_id 关联chat_friends表id
|
|
* @return bool
|
|
*/
|
|
public function editUnreadCount($from_type, $friend_id)
|
|
{
|
|
try {
|
|
$data = ['updated_at' => date('Y-m-d H:i:s')];
|
|
|
|
if ($from_type == 'personnel') {
|
|
// 员工查看消息 -> 把员工的未读消息数量清空
|
|
$data['unread_count_personnel'] = 0;
|
|
} else {
|
|
// 学生查看消息 -> 把学生的未读消息数量清空
|
|
$data['unread_count_customer_resources'] = 0;
|
|
}
|
|
|
|
$result = ChatFriends::where('id', $friend_id)->update($data);
|
|
return $result !== false;
|
|
} catch (\Exception $e) {
|
|
\think\facade\Log::error('修改未读消息数量异常: ' . $e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 追加接收消息的人未读消息数量+1
|
|
* @param $to_type 接收者类型|personnel=员工,customer=学生(客户)
|
|
* @param $friend_id 关联chat_friends表id
|
|
* @return bool
|
|
*/
|
|
public function addUnreadCount($to_type, $friend_id)
|
|
{
|
|
try {
|
|
$updateData = ['updated_at' => date('Y-m-d H:i:s')];
|
|
|
|
if ($to_type == 'personnel') {
|
|
// 员工接收的消息 -> 员工的未读消息数量+1
|
|
$result = ChatFriends::where('id', $friend_id)
|
|
->inc('unread_count_personnel')
|
|
->update($updateData);
|
|
} else {
|
|
// 学生接收的消息 -> 学生的未读消息数量+1
|
|
$result = ChatFriends::where('id', $friend_id)
|
|
->inc('unread_count_customer_resources')
|
|
->update($updateData);
|
|
}
|
|
|
|
return $result !== false;
|
|
} catch (\Exception $e) {
|
|
\think\facade\Log::error('增加未读消息数量异常: ' . $e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}
|
|
|