内容库群选择功能 + 场景获客分页修复
This commit is contained in:
@@ -21,6 +21,7 @@ Route::group('v1/', function () {
|
||||
Route::group('wechatChatroom/', function () {
|
||||
Route::get('list', 'app\chukebao\controller\WechatChatroomController@getList'); // 获取好友列表
|
||||
Route::get('detail', 'app\chukebao\controller\WechatChatroomController@getDetail'); // 获取群详情
|
||||
Route::get('members', 'app\chukebao\controller\WechatChatroomController@getMembers'); // 获取群成员列表
|
||||
Route::post('aiAnnouncement', 'app\chukebao\controller\WechatChatroomController@aiAnnouncement'); // AI群公告
|
||||
});
|
||||
|
||||
|
||||
@@ -151,6 +151,68 @@ class WechatChatroomController extends BaseController
|
||||
return ResponseHelper::success($detail);
|
||||
}
|
||||
|
||||
public function getMembers()
|
||||
{
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$groupId = $this->request->param('groupId', '');
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
|
||||
$accountId = $this->getUserInfo('s2_accountId');
|
||||
if (empty($accountId)) {
|
||||
return ResponseHelper::error('请先登录');
|
||||
}
|
||||
|
||||
// 验证群组ID必填
|
||||
if (empty($groupId)) {
|
||||
return ResponseHelper::error('群组ID不能为空');
|
||||
}
|
||||
|
||||
// 验证群组是否属于当前账号
|
||||
$chatroom = Db::table('s2_wechat_chatroom')
|
||||
->where(['id' => $groupId, 'isDeleted' => 0])
|
||||
->find();
|
||||
|
||||
if (!$chatroom) {
|
||||
return ResponseHelper::error('群组不存在或无权限访问');
|
||||
}
|
||||
|
||||
// 获取群组的chatroomId(微信群聊ID)
|
||||
$chatroomId = $chatroom['chatroomId'] ?? $chatroom['id'];
|
||||
|
||||
// 如果chatroomId为空,使用id作为chatroomId
|
||||
if (empty($chatroomId)) {
|
||||
$chatroomId = $chatroom['id'];
|
||||
}
|
||||
|
||||
// 构建查询
|
||||
$query = Db::table('s2_wechat_chatroom_member')
|
||||
->where('chatroomId', $chatroomId);
|
||||
|
||||
// 关键字搜索:昵称、备注、别名
|
||||
if ($keyword !== '' && $keyword !== null) {
|
||||
$query->where(function ($q) use ($keyword) {
|
||||
$like = '%' . $keyword . '%';
|
||||
$q->whereLike('nickname', $like)
|
||||
->whereOr('conRemark', 'like', $like)
|
||||
->whereOr('alias', 'like', $like);
|
||||
});
|
||||
}
|
||||
|
||||
$query->order('id desc');
|
||||
$total = $query->count();
|
||||
$list = $query->page($page, $limit)->select();
|
||||
|
||||
// 处理时间格式
|
||||
foreach ($list as $k => &$v) {
|
||||
$v['createTime'] = !empty($v['createTime']) ? date('Y-m-d H:i:s', $v['createTime']) : '';
|
||||
$v['updateTime'] = !empty($v['updateTime']) ? date('Y-m-d H:i:s', $v['updateTime']) : '';
|
||||
}
|
||||
unset($v);
|
||||
|
||||
return ResponseHelper::success(['list' => $list, 'total' => $total]);
|
||||
}
|
||||
|
||||
public function aiAnnouncement()
|
||||
{
|
||||
$userId = $this->getUserInfo('id');
|
||||
|
||||
@@ -19,7 +19,7 @@ return [
|
||||
'message:friendsList' => 'app\command\MessageFriendsListCommand', // 微信好友消息列表 √
|
||||
'message:chatroomList' => 'app\command\MessageChatroomListCommand', // 微信群聊消息列表 √
|
||||
'department:list' => 'app\command\DepartmentListCommand', // 部门列表 √
|
||||
'content:sync' => 'app\command\SyncContentCommand', // 同步内容库 √
|
||||
'content:sync' => 'app\command\SyncContentCommand', // 同步内容库 XXXXXXXX
|
||||
'groupFriends:list' => 'app\command\GroupFriendsCommand', // 微信群好友列表
|
||||
// 'allotFriends:run' => 'app\command\AllotFriendCommand', // 自动分配微信好友
|
||||
// 'allotChatroom:run' => 'app\command\AllotChatroomCommand', // 自动分配微信群聊
|
||||
|
||||
@@ -357,6 +357,7 @@ class ContentLibraryController extends Controller
|
||||
// 初始化选项数组
|
||||
$library['friendsGroupsOptions'] = [];
|
||||
$library['wechatGroupsOptions'] = [];
|
||||
$library['groupMembersOptions'] = [];
|
||||
|
||||
// 批量查询好友信息
|
||||
if (!empty($library['friendsGroups'])) {
|
||||
@@ -385,6 +386,61 @@ class ContentLibraryController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// 批量查询群成员信息
|
||||
if (!empty($library['groupMembers'])) {
|
||||
// groupMembers格式: {"826825": ["413771", "413769"], "840818": ["496300", "496302"]}
|
||||
// 键是群组ID,值是成员ID数组
|
||||
$allMemberIds = [];
|
||||
$groupMembersMap = [];
|
||||
|
||||
if (is_array($library['groupMembers'])) {
|
||||
foreach ($library['groupMembers'] as $groupId => $memberIds) {
|
||||
if (is_array($memberIds) && !empty($memberIds)) {
|
||||
$allMemberIds = array_merge($allMemberIds, $memberIds);
|
||||
// 保存群组ID和成员ID的映射关系
|
||||
$groupMembersMap[$groupId] = $memberIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($allMemberIds)) {
|
||||
// 去重
|
||||
$allMemberIds = array_unique($allMemberIds);
|
||||
|
||||
// 查询群成员信息
|
||||
$members = Db::table('s2_wechat_chatroom_member')
|
||||
->field('id, chatroomId, wechatId, nickname, avatar, conRemark, alias, friendType, createTime, updateTime')
|
||||
->whereIn('id', $allMemberIds)
|
||||
->select();
|
||||
|
||||
// 将成员数据按ID建立索引
|
||||
$membersById = [];
|
||||
foreach ($members as $member) {
|
||||
// 格式化时间字段
|
||||
$member['createTime'] = !empty($member['createTime']) ? date('Y-m-d H:i:s', $member['createTime']) : '';
|
||||
$member['updateTime'] = !empty($member['updateTime']) ? date('Y-m-d H:i:s', $member['updateTime']) : '';
|
||||
$membersById[$member['id']] = $member;
|
||||
}
|
||||
|
||||
// 按照群组ID分组返回
|
||||
$groupMembersOptions = [];
|
||||
foreach ($groupMembersMap as $groupId => $memberIds) {
|
||||
$groupMembersOptions[$groupId] = [];
|
||||
foreach ($memberIds as $memberId) {
|
||||
if (isset($membersById[$memberId])) {
|
||||
$groupMembersOptions[$groupId][] = $membersById[$memberId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$library['groupMembersOptions'] = $groupMembersOptions;
|
||||
} else {
|
||||
$library['groupMembersOptions'] = [];
|
||||
}
|
||||
} else {
|
||||
$library['groupMembersOptions'] = [];
|
||||
}
|
||||
|
||||
//获取设备信息
|
||||
if (!empty($library['deviceGroups'])) {
|
||||
$deviceList = DeviceModel::alias('d')
|
||||
@@ -921,7 +977,7 @@ class ContentLibraryController extends Controller
|
||||
|
||||
// 如果有发送者信息,也获取发送者详情
|
||||
if (!empty($item['wechatId'])) {
|
||||
$senderInfo = Db::name('wechat_chatroom_member')
|
||||
$senderInfo = Db::table('s2_wechat_chatroom_member')
|
||||
->where([
|
||||
'chatroomId' => $groupInfo['chatroomId'],
|
||||
'wechatId' => $item['wechatId']
|
||||
@@ -1477,8 +1533,8 @@ class ContentLibraryController extends Controller
|
||||
|
||||
try {
|
||||
// 查询群组信息
|
||||
$groups = Db::name('wechat_group')->alias('g')
|
||||
->field('g.id, g.chatroomId, g.name, g.ownerWechatId')
|
||||
$groups = Db::table('s2_wechat_chatroom')->alias('g')
|
||||
->field('g.id, g.chatroomId, g.nickname as name, g.wechatAccountWechatId as ownerWechatId')
|
||||
->whereIn('g.id', $groupIds)
|
||||
->where('g.deleteTime', 0)
|
||||
->select();
|
||||
@@ -1500,12 +1556,59 @@ class ContentLibraryController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
// groupMembers格式: {"826825": ["413771", "413769"], "840818": ["496300", "496302"]}
|
||||
// 键是群组ID,值是该群组的成员ID数组
|
||||
// 需要按群组分组处理,确保每个群组只采集该群组配置的成员
|
||||
|
||||
// 建立群组ID到成员ID数组的映射
|
||||
$groupIdToMemberIds = [];
|
||||
if (is_array($groupMembers)) {
|
||||
foreach ($groupMembers as $groupId => $memberIds) {
|
||||
if (is_array($memberIds) && !empty($memberIds)) {
|
||||
$groupIdToMemberIds[$groupId] = $memberIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($groupIdToMemberIds)) {
|
||||
return [
|
||||
'status' => 'failed',
|
||||
'message' => '未找到有效的群成员ID'
|
||||
];
|
||||
}
|
||||
|
||||
// 为每个群组查询成员信息,建立群组ID到成员wechatId数组的映射
|
||||
$groupIdToMemberWechatIds = [];
|
||||
foreach ($groupIdToMemberIds as $groupId => $memberIds) {
|
||||
// 查询该群组的成员信息,获取wechatId
|
||||
$members = Db::table('s2_wechat_chatroom_member')
|
||||
->field('id, wechatId')
|
||||
->whereIn('id', $memberIds)
|
||||
->select();
|
||||
|
||||
$wechatIds = [];
|
||||
foreach ($members as $member) {
|
||||
if (!empty($member['wechatId'])) {
|
||||
$wechatIds[] = $member['wechatId'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($wechatIds)) {
|
||||
$groupIdToMemberWechatIds[$groupId] = array_unique($wechatIds);
|
||||
}
|
||||
}
|
||||
if (empty($groupIdToMemberWechatIds)) {
|
||||
return [
|
||||
'status' => 'failed',
|
||||
'message' => '未找到有效的群成员微信ID'
|
||||
];
|
||||
}
|
||||
|
||||
// 从群组采集内容
|
||||
$collectedData = [];
|
||||
$totalMessagesCount = 0;
|
||||
$chatroomIds = array_column($groups, 'id');
|
||||
|
||||
// 获取群消息 - 支持时间范围过滤
|
||||
// 获取群消息 - 支持时间范围过滤(先不添加群成员过滤,后面按群组分别过滤)
|
||||
$messageWhere = [
|
||||
['wechatChatroomId', 'in', $chatroomIds],
|
||||
['type', '=', 2]
|
||||
@@ -1516,7 +1619,7 @@ class ContentLibraryController extends Controller
|
||||
$messageWhere[] = ['createTime', 'between', [$library['timeStart'], $library['timeEnd']]];
|
||||
}
|
||||
|
||||
// 查询群消息
|
||||
// 查询群消息(先查询所有消息,后面按群组和成员过滤)
|
||||
$groupMessages = Db::table('s2_wechat_message')
|
||||
->where($messageWhere)
|
||||
->order('createTime', 'desc')
|
||||
@@ -1532,6 +1635,34 @@ class ContentLibraryController extends Controller
|
||||
$groupedMessages = [];
|
||||
foreach ($groupMessages as $message) {
|
||||
$chatroomId = $message['wechatChatroomId'];
|
||||
$senderWechatId = $message['senderWechatId'] ?? '';
|
||||
|
||||
// 找到对应的群组信息
|
||||
$groupInfo = null;
|
||||
foreach ($groups as $group) {
|
||||
if ($group['id'] == $chatroomId) {
|
||||
$groupInfo = $group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$groupInfo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查该消息的发送者是否在该群组的配置成员列表中
|
||||
$groupId = $groupInfo['id'];
|
||||
if (!isset($groupIdToMemberWechatIds[$groupId])) {
|
||||
// 该群组没有配置成员,跳过
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查发送者是否在配置的成员列表中
|
||||
if (!in_array($senderWechatId, $groupIdToMemberWechatIds[$groupId])) {
|
||||
// 发送者不在该群组的配置成员列表中,跳过
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($groupedMessages[$chatroomId])) {
|
||||
$groupedMessages[$chatroomId] = [
|
||||
'count' => 0,
|
||||
@@ -1579,27 +1710,14 @@ class ContentLibraryController extends Controller
|
||||
continue;
|
||||
}
|
||||
|
||||
// 找到对应的群组信息
|
||||
$groupInfo = null;
|
||||
foreach ($groups as $group) {
|
||||
if ($group['id'] == $chatroomId) {
|
||||
$groupInfo = $group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$groupInfo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// 如果启用了AI处理
|
||||
if (!empty($library['aiEnabled']) && !empty($content)) {
|
||||
$contentAi = $this->aiRewrite($library, $content);
|
||||
if (!empty($content)) {
|
||||
$moment['contentAi'] = $contentAi;
|
||||
if (!empty($contentAi)) {
|
||||
$message['contentAi'] = $contentAi;
|
||||
} else {
|
||||
$moment['contentAi'] = '';
|
||||
$message['contentAi'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1968,7 +2086,38 @@ class ContentLibraryController extends Controller
|
||||
return true;
|
||||
}
|
||||
|
||||
// 提取消息内容中的链接
|
||||
$resUrls = [];
|
||||
|
||||
$content = '';
|
||||
switch ($message['msgType']) {
|
||||
case 1: // 文字
|
||||
$content = $message['content'];
|
||||
$contentType = 4;
|
||||
break;
|
||||
case 3: //图片
|
||||
$resUrls[] = $message['content'];
|
||||
$contentType = 1;
|
||||
break;
|
||||
case 47: //动态图片
|
||||
$resUrls[] = $message['content'];
|
||||
$contentType = 1;
|
||||
break;
|
||||
case 34: //语言
|
||||
return false;
|
||||
case 43: //视频
|
||||
$resUrls[] = $message['content'];
|
||||
$contentType = 3;
|
||||
break;
|
||||
case 42: //名片
|
||||
return false;
|
||||
case 49: //文件
|
||||
$links = json_decode($message['content'],true);
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*// 提取消息内容中的链接
|
||||
$content = $message['content'] ?? '';
|
||||
$links = [];
|
||||
$pattern = '/https?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]/';
|
||||
@@ -1986,6 +2135,8 @@ class ContentLibraryController extends Controller
|
||||
|
||||
// 判断内容类型 (0=未知, 1=图片, 2=链接, 3=视频, 4=文本, 5=小程序, 6=图文)
|
||||
$contentType = $this->determineContentType($content, $resUrls, $links);
|
||||
*/
|
||||
|
||||
|
||||
// 创建新的内容项目
|
||||
$item = new ContentItem();
|
||||
@@ -1993,7 +2144,7 @@ class ContentLibraryController extends Controller
|
||||
$item->type = 'group_message'; // 群消息类型
|
||||
$item->title = '来自 ' . ($group['name'] ?? '未知群组') . ' 的消息';
|
||||
$item->contentData = json_encode($message, JSON_UNESCAPED_UNICODE);
|
||||
$item->msgId = $message['msgId'] ?? ''; // 存储msgId便于后续查询
|
||||
$item->msgId = $message['msgSvrId'] ?? ''; // 存储msgSvrId便于后续查询
|
||||
$item->createTime = time();
|
||||
$item->content = $content;
|
||||
$item->contentType = $contentType; // 设置内容类型
|
||||
@@ -2011,13 +2162,17 @@ class ContentLibraryController extends Controller
|
||||
if (!empty($resUrls[0])) {
|
||||
$item->coverImage = $resUrls[0];
|
||||
}
|
||||
}else{
|
||||
$item->resUrls = json_encode([], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
// 处理链接
|
||||
if (!empty($links)) {
|
||||
$item->urls = json_encode($links, JSON_UNESCAPED_UNICODE);
|
||||
}else{
|
||||
$item->urls = json_encode([], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
$item->ossUrls = json_encode([], JSON_UNESCAPED_UNICODE);
|
||||
// 设置商品信息(需根据消息内容解析)
|
||||
$this->extractProductInfo($item, $content);
|
||||
|
||||
|
||||
@@ -39,10 +39,10 @@ class GetChatroomListV1Controller extends BaseController
|
||||
|
||||
$where = [];
|
||||
if ($this->getUserInfo('isAdmin') == 1) {
|
||||
$where[] = ['g.deleteTime', '=', 0];
|
||||
$where[] = ['gg.isDeleted', '=', 0];
|
||||
$where[] = ['g.ownerWechatId', 'in', $wechatIds];
|
||||
} else {
|
||||
$where[] = ['g.deleteTime', '=', 0];
|
||||
$where[] = ['gg.isDeleted', '=', 0];
|
||||
$where[] = ['g.ownerWechatId', 'in', $wechatIds];
|
||||
//$where[] = ['g.userId', '=', $this->getUserInfo('id')];
|
||||
}
|
||||
@@ -55,6 +55,7 @@ class GetChatroomListV1Controller extends BaseController
|
||||
->field(['g.id', 'g.chatroomId', 'g.name', 'g.avatar','g.ownerWechatId', 'g.identifier', 'g.createTime',
|
||||
'wa.nickname as ownerNickname','wa.avatar as ownerAvatar','wa.alias as ownerAlias'])
|
||||
->join('wechat_account wa', 'g.ownerWechatId = wa.wechatId', 'LEFT')
|
||||
->join(['s2_wechat_chatroom' => 'gg'], 'g.id = gg.id', 'LEFT')
|
||||
->where($where);
|
||||
|
||||
$total = $data->count();
|
||||
|
||||
Reference in New Issue
Block a user