群列表+群成员接口外加对接

This commit is contained in:
wong
2025-04-22 19:17:14 +08:00
parent 793ee5cb4f
commit 46ba136255
18 changed files with 1137 additions and 123 deletions

View File

@@ -66,7 +66,7 @@ Route::group('v1', function () {
// WechatChatroom控制器路由
Route::group('chatroom', function () {
Route::get('list', 'app\\api\\controller\\WechatChatroomController@getList'); // 获取微信群聊列表 √
//Route::get('members/:wechatChatroomId', 'app\\api\\controller\\WechatChatroomController@listChatroomMember'); // 获取群成员列表 √
Route::get('members', 'app\\api\\controller\\WechatChatroomController@listChatroomMember'); // 获取群成员列表 √
// Route::get('sync', 'app\\api\\controller\\WechatChatroomController@syncChatrooms'); // 同步微信群聊数据 √
});

View File

@@ -120,16 +120,28 @@ class WechatChatroomController extends BaseController
* @param string $wechatChatroomId 微信群ID
* @return \think\response\Json
*/
public function listChatroomMember($wechatChatroomId = '')
public function listChatroomMember($wechatChatroomId = '',$chatroomId = '',$isJob = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
$wechatChatroomId = !empty($wechatChatroomId) ? $wechatChatroomId : $this->request->param('id', '');
$chatroomId = !empty($chatroomId) ? $chatroomId : $this->request->param('chatroomId', '');
if (empty($authorization)) {
return errorJson('缺少授权信息');
if($isJob){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
if (empty($wechatChatroomId)) {
return errorJson('群ID不能为空');
if($isJob){
return json_encode(['code'=>500,'msg'=>'群ID不能为空']);
}else{
return errorJson('群ID不能为空');
}
}
try {
@@ -147,15 +159,23 @@ class WechatChatroomController extends BaseController
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response['results'])) {
foreach ($response['results'] as $item) {
$this->saveChatroomMember($item, $wechatChatroomId);
if (!empty($response)) {
foreach ($response as $item) {
$this->saveChatroomMember($item, $chatroomId);
}
}
return successJson($response);
if($isJob){
return json_encode(['code'=>200,'msg'=>'success','data'=>$response]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
return errorJson('获取群成员列表失败:' . $e->getMessage());
if($isJob){
return json_encode(['code'=>500,'msg'=>'获取群成员列表失败:' . $e->getMessage()]);
}else{
return errorJson('获取群成员列表失败:' . $e->getMessage());
}
}
}

View File

@@ -19,5 +19,9 @@ return [
'message:friendsList' => 'app\command\MessageFriendsListCommand', // 微信好友消息列表 √
'message:chatroomList' => 'app\command\MessageChatroomListCommand', // 微信群聊消息列表 √
'department:list' => 'app\command\DepartmentListCommand', // 部门列表 √
<<<<<<< Updated upstream
'content:sync' => 'app\command\SyncContentCommand', // 同步内容库 √
=======
'groupFriends:list' => 'app\command\GroupFriendsCommand', // 微信群好友列表
>>>>>>> Stashed changes
];

View File

@@ -0,0 +1,60 @@
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Log;
use think\Queue;
use app\job\GroupFriendsJob;
use think\facade\Cache;
class GroupFriendsCommand extends Command
{
protected function configure()
{
$this->setName('groupFriends:list')
->setDescription('获取微信群好友列表,并根据分页自动处理下一页');
}
protected function execute(Input $input, Output $output)
{
$output->writeln('开始处理微信群好友列表任务...');
try {
// 从缓存获取初始页码,缓存有效期一天
$pageIndex = Cache::get('groupFriendsPage', 0);
$output->writeln('从缓存获取页码:' . $pageIndex);
$pageSize = 100; // 每页获取100条记录
// 将任务添加到队列
$this->addToQueue($pageIndex, $pageSize);
$output->writeln('微信群好友列表任务已添加到队列');
} catch (\Exception $e) {
Log::error('微信群好友列表任务添加失败:' . $e->getMessage());
$output->writeln('微信群好友列表任务添加失败:' . $e->getMessage());
return false;
}
return true;
}
/**
* 添加任务到队列
* @param int $pageIndex 页码
* @param int $pageSize 每页大小
*/
protected function addToQueue($pageIndex, $pageSize)
{
$data = [
'pageIndex' => $pageIndex,
'pageSize' => $pageSize
];
// 添加到队列,设置任务名为 group_friends
Queue::push(GroupFriendsJob::class, $data, 'group_friends');
}
}

View File

@@ -168,7 +168,7 @@ class AuthService
// 尝试从缓存获取授权信息
$authorization = Cache::get($cacheKey);
// $authorization = 'aXRi4R80zwTXo9V-VCXVYk4IMLl5ufKASoRtYHfaRh_uLwil_mO9U_jWfxeR1yupJIPuQCZknXGpctr9PTS1hbormw3RSrOwunNKTsvvcGzjTa0bBUz3S9W8x_PtvbY4_JpoXl8x8hm8cUa37zLlN7DQBAmj8He40FCxMTh1MC4xorM11aXoVFvYcrAkv_urHINWDmfNhH9icXzreiX9Uynw4fq7BkuP7yr6WHQ5z0NkOfKoMcesH4gPn_h_OLHC0T_ps2ky--M5HOvd5WgBmYRecNOcqbe4e0oIIO5ffANLsybyhLOEha3a03qKsyfAFWdf0A';
$authorization = 'mYpVVhPY7PxctvYw1pn1VCTS2ck0yZG8q11gAiJrRN_D3q7KXXBPAfXoAmqs7kKHeaAx-h4GB7DiqVIQJ09HiXVhaQT6PtgLX3w8YV16erThC-lG1fyJB4DJxu-QxA3Q8ogSs1WFOa8aAXD1QQUZ7Kbjkw_VMLL4lrfe0Yjaqy3DnO7aL1xGnNjjX8P5uqCAZgHKlN8NjuDEGyYvXygW1YyoK9pNpwvq-6DYKjLWdmbHvFaAybHf-hU1XyrFavZqcZYxIoVXjfJ5ASp4XxeCWqMCzwtSoz9RAvwLAlNxGweowtuyX9389ZaXI-zbqb2T0S8llg';
// 如果缓存中没有或已过期,则重新获取
if (empty($authorization)) {
try {

View File

@@ -70,4 +70,12 @@ Route::group('v1/', function () {
Route::group('friend', function () {
Route::get('', 'app\\cunkebao\\controller\\friend\\GetFriendListV1Controller@index'); // 获取好友列表
});
//群相关
Route::group('chatroom', function () {
Route::get('', 'app\\cunkebao\\controller\\chatroom\\GetChatroomListV1Controller@index'); // 获取群列表
Route::get('getMemberList', 'app\\cunkebao\\controller\\chatroom\\GetChatroomListV1Controller@getMemberList'); // 获取群详情
});
})->middleware(['jwt']);

View File

@@ -57,6 +57,43 @@ class ContentLibraryController extends Controller
$item['keywordExclude'] = json_decode($item['keywordExclude'] ?: '[]', true);
// 添加创建人名称
$item['creatorName'] = $item['user']['username'] ?? '';
// 获取好友详细信息
if (!empty($item['sourceFriends'] && $item['sourceType'] == 1)) {
$friendIds = $item['sourceFriends'];
$friendsInfo = [];
if (!empty($friendIds)) {
// 查询好友信息使用wechat_friend表
$friendsInfo = Db::name('wechat_friend')->alias('wf')
->field('wf.id,wf.wechatId, wa.nickname, wa.avatar')
->join('wechat_account wa', 'wf.wechatId = wa.wechatId')
->whereIn('wf.id', $friendIds)
->select();
}
// 将好友信息添加到返回数据中
$item['selectedFriends'] = $friendsInfo;
}
// 获取群组详细信息
if (!empty($item['sourceGroups']) && $item['sourceType'] == 2) {
$groupIds = $item['sourceGroups'];
$groupsInfo = [];
if (!empty($groupIds)) {
// 查询群组信息
$groupsInfo = Db::name('wechat_group')->alias('g')
->field('g.id, g.chatroomId, g.name, g.avatar, g.ownerWechatId')
->whereIn('g.id', $groupIds)
->select();
}
// 将群组信息添加到返回数据中
$item['selectedGroups'] = $groupsInfo;
}
unset($item['user']); // 移除关联数据
}
unset($item);
@@ -117,17 +154,36 @@ class ContentLibraryController extends Controller
$friendsInfo = [];
if (!empty($friendIds)) {
// 查询好友信息使用wechat_account
$friendsInfo = Db::name('wechat_account')
->field('wechatId, nickname, avatar')
->whereIn('wechatId', $friendIds)
->select();
// 查询好友信息使用wechat_friend
$friendsInfo = Db::name('wechat_friend')->alias('wf')
->field('wf.id,wf.wechatId, wa.nickname, wa.avatar')
->join('wechat_account wa', 'wf.wechatId = wa.wechatId')
->whereIn('wf.id', $friendIds)
->select();
}
// 将好友信息添加到返回数据中
$library['selectedFriends'] = $friendsInfo;
}
// 获取群组详细信息
if (!empty($library['sourceGroups'])) {
$groupIds = $library['sourceGroups'];
$groupsInfo = [];
if (!empty($groupIds)) {
// 查询群组信息
$groupsInfo = Db::name('wechat_group')->alias('g')
->field('g.id, g.chatroomId, g.name, g.avatar, g.ownerWechatId,wa.nickname as ownerNickname,wa.avatar as ownerAvatar,wa.alias as ownerAlias')
->join('wechat_account wa', 'g.ownerWechatId = wa.wechatId')
->whereIn('g.id', $groupIds)
->select();
}
// 将群组信息添加到返回数据中
$library['selectedGroups'] = $groupsInfo;
}
return json([
@@ -163,15 +219,21 @@ class ContentLibraryController extends Controller
Db::startTrans();
try {
$keywordInclude = isset($param['keywordInclude']) ? json_encode($param['keywordInclude'],256) : json_encode([]);
$keywordExclude = isset($param['keywordExclude']) ? json_encode($param['keywordExclude'],256) : json_encode([]);
$sourceType = isset($param['sourceType']) ? $param['sourceType'] : 1;
// 构建数据
$data = [
'name' => $param['name'],
// 数据来源配置
'sourceFriends' => isset($param['friends']) ? json_encode($param['friends']) : '[]', // 选择的微信好友
'sourceGroups' => isset($param['groups']) ? json_encode($param['groups']) : '[]', // 选择的微信群
'sourceFriends' => $sourceType == 1 ? json_encode($param['friends']) : json_encode([]), // 选择的微信好友
'sourceGroups' => $sourceType == 2 ? json_encode($param['groups']) : json_encode([]), // 选择的微信群
// 关键词配置
'keywordInclude' => isset($param['keywordInclude']) ? json_encode($param['keywordInclude']) : '[]', // 包含的关键词
'keywordExclude' => isset($param['keywordExclude']) ? json_encode($param['keywordExclude']) : '[]', // 排除的关键词
'keywordInclude' => $keywordInclude, // 包含的关键词
'keywordExclude' => $keywordExclude, // 排除的关键词
// AI配置
'aiEnabled' => isset($param['aiEnabled']) ? $param['aiEnabled'] : 0, // 是否启用AI
'aiPrompt' => isset($param['aiPrompt']) ? $param['aiPrompt'] : '', // AI提示词
@@ -180,7 +242,7 @@ class ContentLibraryController extends Controller
'timeStart' => isset($param['startTime']) ? strtotime($param['startTime']) : 0, // 开始时间(转换为时间戳)
'timeEnd' => isset($param['endTime']) ? strtotime($param['endTime']) : 0, // 结束时间(转换为时间戳)
// 来源类型
'sourceType' => isset($param['sourceType']) ? $param['sourceType'] : 0, // 1=好友2=群3=好友和群
'sourceType' => $sourceType, // 1=好友2=群3=好友和群
// 基础信息
'status' => isset($param['status']) ? $param['status'] : 0, // 状态0=禁用1=启用
'userId' => $this->request->userInfo['id'],
@@ -240,9 +302,27 @@ class ContentLibraryController extends Controller
Db::startTrans();
try {
$keywordInclude = isset($param['keywordInclude']) ? json_encode($param['keywordInclude'],256) : json_encode([]);
$keywordExclude = isset($param['keywordExclude']) ? json_encode($param['keywordExclude'],256) : json_encode([]);
// 更新内容库基本信息
$library->name = $param['name'];
$library->description = isset($param['description']) ? $param['description'] : '';
$library->sourceType = isset($param['sourceType']) ? $param['sourceType'] : 1;
$library->sourceFriends = $param['sourceType'] == 1 ? json_encode($param['friends']) : json_encode([]);
$library->sourceGroups = $param['sourceType'] == 2 ? json_encode($param['groups']) : json_encode([]);
$library->keywordInclude = $keywordInclude;
$library->keywordExclude = $keywordExclude;
$library->aiEnabled = isset($param['aiEnabled']) ? $param['aiEnabled'] : 0;
$library->aiPrompt = isset($param['aiPrompt']) ? $param['aiPrompt'] : '';
$library->timeEnabled = isset($param['timeEnabled']) ? $param['timeEnabled'] : 0;
$library->timeStart = isset($param['startTime']) ? strtotime($param['startTime']) : 0;
$library->timeEnd = isset($param['endTime']) ? strtotime($param['endTime']) : 0;
$library->status = isset($param['status']) ? $param['status'] : 0;
$library->updateTime = time();
$library->save();
Db::commit();

View File

@@ -0,0 +1,136 @@
<?php
namespace app\cunkebao\controller\chatroom;
use app\cunkebao\controller\BaseController;
use app\cunkebao\model\WechatChatroom;
use think\Db;
/**
* 群聊管理控制器
*/
class GetChatroomListV1Controller extends BaseController
{
/**
* 获取群聊列表
* @return \think\response\Json
*/
public function index()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 20);
$keyword = $this->request->param('keyword', '');
try {
$where = [];
if ($this->getUserInfo('isAdmin') == 1) {
$where[] = ['g.companyId', '=', $this->getUserInfo('companyId')];
$where[] = ['g.deleteTime', '=', 0];
} else {
$where[] = ['g.companyId', '=', $this->getUserInfo('companyId')];
$where[] = ['g.deleteTime', '=', 0];
//$where[] = ['g.userId', '=', $this->getUserInfo('id')];
}
if(!empty($keyword)){
$where[] = ['g.name', 'like', '%'.$keyword.'%'];
}
$data = WechatChatroom::alias('g')
->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')
->where($where);
$total = $data->count();
$list = $data->page($page, $limit)->order('g.id DESC')->select();
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'list' => $list,
'total' => $total,
]
]);
} catch (\Exception $e) {
return json([
'code' => $e->getCode(),
'msg' => $e->getMessage()
]);
}
}
/**
* 获取群成员列表
* @return \think\response\Json
*/
public function getMemberList()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 20);
$keyword = $this->request->param('keyword', '');
$groupId = $this->request->param('groupId', 0);
if (empty($groupId)) {
return json([
'code' => 400,
'msg' => '群ID不能为空'
]);
}
try {
$where = [];
$where[] = ['m.groupId', '=', $groupId];
$where[] = ['m.deleteTime', '=', 0];
// 如果有搜索关键词
if (!empty($keyword)) {
$where[] = ['m.nickname|m.identifier', 'like', '%'.$keyword.'%'];
}
$data = Db::name('wechat_group_member')
->alias('m')
->field([
'm.id',
'm.identifier',
'm.customerIs',
'wa.nickname',
'wa.avatar',
'm.groupId',
'm.createTime',
'g.name as groupName',
'g.chatroomId'
])
->join('wechat_group g', 'm.groupId = g.id', 'LEFT')
->join('wechat_account wa', 'wa.wechatId = m.identifier', 'LEFT')
->where($where);
$total = $data->count();
$list = $data->page($page, $limit)
->order('m.id DESC')
->select();
// 格式化时间
foreach ($list as &$item) {
if (!empty($item['createTime'])) {
$item['createTime'] = date('Y-m-d H:i:s', $item['createTime']);
}
}
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'list' => $list,
'total' => $total,
]
]);
} catch (\Exception $e) {
return json([
'code' => $e->getCode() ?: 500,
'msg' => $e->getMessage()
]);
}
}
}

View File

@@ -5,6 +5,7 @@ use app\common\model\Device as DeviceModel;
use app\common\model\DeviceUser as DeviceUserModel;
use app\common\model\WechatFriend;
use app\cunkebao\controller\BaseController;
use think\Db;
/**
* 设备管理控制器
@@ -26,29 +27,29 @@ class GetFriendListV1Controller extends BaseController
$where = [];
if ($this->getUserInfo('isAdmin') == 1) {
$where['wf.companyId'] = $this->getUserInfo('companyId');
$where['wf.deleteTime'] = 0;
$where[] = ['wf.companyId','=',$this->getUserInfo('companyId')];
$where[] = ['wf.deleteTime','=',0];
} else {
$where['wf.companyId'] = $this->getUserInfo('companyId');
$where['wf.deleteTime'] = 0;
//$where['userId'] = $this->getUserInfo('id');
$where[] = ['wf.companyId','=',$this->getUserInfo('companyId')];
$where[] = ['wf.deleteTime','=',0];
//$where[] = ['wf.userId','=',$this->getUserInfo('id')];
}
if($keyword){
$where['wa1.nickname'] = ['like','%'.$keyword.'%'];
if(!empty($keyword)){
$where[] = ['wa1.nickname','like','%'.$keyword.'%'];
}
$data = WechatFriend::alias('wf')
->field(['wa1.nickname','wa1.avatar','wa1.alias','wf.wechatId','wa2.nickname as ownerNickname','wa2.alias as ownerAlias','wa2.wechatId as ownerWechatId','wf.createTime'])
->field(['wa1.nickname','wa1.avatar','wa1.alias','wf.id','wf.wechatId','wa2.nickname as ownerNickname','wa2.alias as ownerAlias','wa2.wechatId as ownerWechatId','wf.createTime'])
->Join('wechat_account wa1','wf.wechatId = wa1.wechatId')
->Join('wechat_account wa2','wf.ownerWechatId = wa2.wechatId')
->where($where);
$total = $data->count();
$list = $data->page($page, $limit)->select();
$list = $data->page($page, $limit)->order('wf.id DESC')->select();

View File

@@ -0,0 +1,15 @@
<?php
namespace app\cunkebao\model;
use think\Model;
/**
* 微信好友模型类
*/
class WechatChatroom extends Model
{
// 设置表名
protected $name = 'wechat_group';
}

View File

@@ -0,0 +1,145 @@
<?php
namespace app\job;
use think\queue\Job;
use think\facade\Log;
use think\Queue;
use think\facade\Config;
use think\facade\Cache;
use app\api\controller\WechatChatroomController;
use app\api\model\WechatChatroomModel;
use think\Db;
class GroupFriendsJob
{
/**
* 队列任务处理
* @param Job $job 队列任务
* @param array $data 任务数据
* @return void
*/
public function fire(Job $job, $data)
{
try {
// 如果任务执行成功后删除任务
if ($this->processGroupFriendsList($data, $job->attempts())) {
$job->delete();
Log::info('微信群好友列表任务执行成功,页码:' . $data['pageIndex']);
} else {
if ($job->attempts() > 3) {
// 超过重试次数,删除任务
Log::error('微信群好友列表任务执行失败,已超过重试次数,页码:' . $data['pageIndex']);
$job->delete();
} else {
// 任务失败,重新放回队列
Log::warning('微信群好友列表任务执行失败,重试次数:' . $job->attempts() . ',页码:' . $data['pageIndex']);
$job->release(Config::get('queue.failed_delay', 10));
}
}
} catch (\Exception $e) {
// 出现异常,记录日志
Log::error('微信群好友列表任务异常:' . $e->getMessage());
if ($job->attempts() > 3) {
$job->delete();
} else {
$job->release(Config::get('queue.failed_delay', 10));
}
}
}
/**
* 处理微信群好友列表获取
* @param array $data 任务数据
* @param int $attempts 重试次数
* @return bool
*/
protected function processGroupFriendsList($data, $attempts)
{
// 获取参数
$pageIndex = isset($data['pageIndex']) ? $data['pageIndex'] : 0;
$pageSize = isset($data['pageSize']) ? $data['pageSize'] : 100;
Log::info('开始获取微信群好友列表,页码:' . $pageIndex . ',页大小:' . $pageSize);
try {
// 从数据库获取未删除的群聊列表
$chatrooms = WechatChatroomModel::where('isDeleted', 0)
->page($pageIndex + 1, $pageSize)
->order('id', 'desc')
->select();
if (empty($chatrooms)) {
Log::info('未找到需要处理的群聊数据,页码:' . $pageIndex);
return true;
}
// 实例化控制器
$wechatChatroomController = new WechatChatroomController();
// 遍历每个群聊,获取其成员
foreach ($chatrooms as $chatroom) {
try {
// 调用获取群成员列表方法
$result = $wechatChatroomController->listChatroomMember($chatroom['id'],$chatroom['chatroomId'],true);
$response = is_string($result) ? json_decode($result, true) : $result;
// 判断是否成功
if (is_array($response) && isset($response['code']) && $response['code'] == 200) {
//Log::info('成功获取群 ' . $chatroom['chatroomId'] . ' 的成员列表');
} else {
$errorMsg = isset($response['msg']) ? $response['msg'] : '未知错误';
Log::error('获取群 ' . $chatroom['chatroomId'] . ' 的成员列表失败:' . $errorMsg);
}
} catch (\Exception $e) {
Log::error('获取群 ' . $chatroom['chatroomId'] . ' 的成员列表异常:' . $e->getMessage());
}
}
//Log::info('群成员获取完成,成功:' . $successCount . ',失败:' . $failCount);
// 计算总数量
$totalCount = WechatChatroomModel::where('isDeleted', 0)->count();
$processedCount = ($pageIndex + 1) * $pageSize;
// 判断是否有下一页
if ($processedCount < $totalCount) {
// 更新缓存中的页码,设置一天过期
Cache::set('groupFriendsPage', $pageIndex + 1, 86400);
//Log::info('更新缓存,下一页页码:' . ($pageIndex + 1) . '缓存时间1天');
// 有下一页,将下一页任务添加到队列
$nextPageIndex = $pageIndex + 1;
$this->addNextPageToQueue($nextPageIndex, $pageSize);
Log::info('添加下一页任务到队列,页码:' . $nextPageIndex);
} else {
// 没有下一页,重置缓存,设置一天过期
Cache::set('groupFriendsPage', 0, 86400);
Log::info('获取完成重置缓存缓存时间1天');
}
return true;
} catch (\Exception $e) {
Log::error('获取微信群好友列表处理失败:' . $e->getMessage());
return false;
}
}
/**
* 添加下一页任务到队列
* @param int $pageIndex 页码
* @param int $pageSize 每页大小
*/
protected function addNextPageToQueue($pageIndex, $pageSize)
{
$data = [
'pageIndex' => $pageIndex,
'pageSize' => $pageSize
];
// 添加到队列,设置任务名为 group_friends
Queue::push(self::class, $data, 'group_friends');
}
}