内容库群选择功能 + 场景获客分页修复

This commit is contained in:
wong
2025-12-25 15:39:57 +08:00
parent 302617cd81
commit b8754f6174
11 changed files with 985 additions and 53 deletions

View File

@@ -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群公告
});

View File

@@ -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');

View File

@@ -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', // 自动分配微信群聊

View File

@@ -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);

View File

@@ -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();