自动建群提交 + 触客宝发布朋友圈优化
This commit is contained in:
@@ -1020,7 +1020,6 @@ class WebSocketController extends BaseController
|
||||
// "wechatFriendIds" => $data['wechatFriendIds']
|
||||
"wechatFriendIds" => [17453051,17453058]
|
||||
];
|
||||
|
||||
$message = $this->sendMessage($params,false);
|
||||
return json_encode(['code' => 200, 'msg' => '群聊创建成功', 'data' => $message]);
|
||||
} catch (\Exception $e) {
|
||||
@@ -1116,6 +1115,7 @@ class WebSocketController extends BaseController
|
||||
];
|
||||
}
|
||||
|
||||
//chatroomOperateType 4退群 6群公告 5群名称
|
||||
$params = [
|
||||
"chatroomOperateType" => !empty($data['chatroomName']) ? 6 : 5,
|
||||
"cmdType" => "CmdChatroomOperate",
|
||||
@@ -1125,7 +1125,7 @@ class WebSocketController extends BaseController
|
||||
"wechatChatroomId" => $data['wechatChatroomId']
|
||||
];
|
||||
$message = $this->sendMessage($params,false);
|
||||
return json_encode(['code' => 200, 'msg' => '群聊创建成功', 'data' => $message]);
|
||||
return json_encode(['code' => 200, 'msg' => '修改群信息成功', 'data' => $message]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('修改群信息异常: ' . $e->getMessage());
|
||||
return json_encode(['code' => 500, 'msg' => '修改群信息失败: ' . $e->getMessage()]);
|
||||
|
||||
@@ -39,7 +39,7 @@ class WechatChatroomController extends BaseController
|
||||
'groupId' => $data['groupId'] ?? '',
|
||||
'wechatChatroomId' => $data['wechatChatroomId'] ?? '',
|
||||
'memberKeyword' => $data['memberKeyword'] ?? '',
|
||||
'pageIndex' => $data['pageIndex'] ?? 1,
|
||||
'pageIndex' => $data['pageIndex'] ?? 0,
|
||||
'pageSize' => $data['pageSize'] ?? 20
|
||||
];
|
||||
|
||||
|
||||
@@ -93,27 +93,32 @@ Route::group('v1/', function () {
|
||||
|
||||
// 工作台相关
|
||||
Route::group('workbench', function () {
|
||||
Route::post('create', 'app\cunkebao\controller\WorkbenchController@create'); // 创建工作台
|
||||
Route::get('list', 'app\cunkebao\controller\WorkbenchController@getList'); // 获取工作台列表
|
||||
Route::post('update-status', 'app\cunkebao\controller\WorkbenchController@updateStatus'); // 更新工作台状态
|
||||
Route::delete('delete', 'app\cunkebao\controller\WorkbenchController@delete'); // 删除工作台
|
||||
Route::post('copy', 'app\cunkebao\controller\WorkbenchController@copy'); // 拷贝工作台
|
||||
Route::get('detail', 'app\cunkebao\controller\WorkbenchController@detail'); // 获取工作台详情
|
||||
Route::post('update', 'app\cunkebao\controller\WorkbenchController@update'); // 更新工作台
|
||||
Route::get('like-records', 'app\cunkebao\controller\WorkbenchController@getLikeRecords'); // 获取点赞记录列表
|
||||
Route::get('moments-records', 'app\cunkebao\controller\WorkbenchController@getMomentsRecords'); // 获取朋友圈发布记录列表
|
||||
Route::get('device-labels', 'app\cunkebao\controller\WorkbenchController@getDeviceLabels'); // 获取设备微信好友标签统计
|
||||
Route::get('group-list', 'app\cunkebao\controller\WorkbenchController@getGroupList'); // 获取群列表
|
||||
Route::get('account-list', 'app\cunkebao\controller\WorkbenchController@getAccountList'); // 获取账号列表
|
||||
Route::get('transfer-friends', 'app\cunkebao\controller\WorkbenchController@getTrafficList'); // 获取账号列表
|
||||
Route::get('import-contact', 'app\cunkebao\controller\WorkbenchController@getImportContact'); // 获取通讯录导入记录列表
|
||||
Route::post('create', 'app\cunkebao\controller\workbench\WorkbenchController@create'); // 创建工作台
|
||||
Route::get('list', 'app\cunkebao\controller\workbench\WorkbenchController@getList'); // 获取工作台列表
|
||||
Route::post('update-status', 'app\cunkebao\controller\workbench\WorkbenchController@updateStatus'); // 更新工作台状态
|
||||
Route::delete('delete', 'app\cunkebao\controller\workbench\WorkbenchController@delete'); // 删除工作台
|
||||
Route::post('copy', 'app\cunkebao\controller\workbench\WorkbenchController@copy'); // 拷贝工作台
|
||||
Route::get('detail', 'app\cunkebao\controller\workbench\WorkbenchController@detail'); // 获取工作台详情
|
||||
Route::post('update', 'app\cunkebao\controller\workbench\WorkbenchController@update'); // 更新工作台
|
||||
Route::get('like-records', 'app\cunkebao\controller\workbench\WorkbenchController@getLikeRecords'); // 获取点赞记录列表
|
||||
Route::get('moments-records', 'app\cunkebao\controller\workbench\WorkbenchController@getMomentsRecords'); // 获取朋友圈发布记录列表
|
||||
Route::get('device-labels', 'app\cunkebao\controller\workbench\WorkbenchController@getDeviceLabels'); // 获取设备微信好友标签统计
|
||||
Route::get('group-list', 'app\cunkebao\controller\workbench\WorkbenchController@getGroupList'); // 获取群列表
|
||||
Route::get('created-groups-list', 'app\cunkebao\controller\workbench\WorkbenchController@getCreatedGroupsList'); // 获取已创建的群列表(自动建群)
|
||||
Route::get('created-group-detail', 'app\cunkebao\controller\workbench\WorkbenchController@getCreatedGroupDetail'); // 获取已创建群的详情(自动建群)
|
||||
Route::post('sync-group-info', 'app\cunkebao\controller\workbench\WorkbenchController@syncGroupInfo'); // 同步群最新信息(包括群成员)
|
||||
Route::post('modify-group-info', 'app\cunkebao\controller\workbench\WorkbenchController@modifyGroupInfo'); // 修改群名称、群公告
|
||||
Route::post('quit-group', 'app\cunkebao\controller\workbench\WorkbenchController@quitGroup'); // 退群(自动建群)
|
||||
Route::get('account-list', 'app\cunkebao\controller\workbench\WorkbenchController@getAccountList'); // 获取账号列表
|
||||
Route::get('transfer-friends', 'app\cunkebao\controller\workbench\WorkbenchController@getTrafficList'); // 获取账号列表
|
||||
Route::get('import-contact', 'app\cunkebao\controller\workbench\WorkbenchController@getImportContact'); // 获取通讯录导入记录列表
|
||||
|
||||
Route::get('getJdSocialMedia', 'app\cunkebao\controller\WorkbenchController@getJdSocialMedia'); // 获取京东联盟导购媒体
|
||||
Route::get('getJdPromotionSite', 'app\cunkebao\controller\WorkbenchController@getJdPromotionSite'); // 获取京东联盟广告位
|
||||
Route::get('changeLink', 'app\cunkebao\controller\WorkbenchController@changeLink'); // 获取京东联盟广告位
|
||||
Route::get('getJdSocialMedia', 'app\cunkebao\controller\workbench\WorkbenchController@getJdSocialMedia'); // 获取京东联盟导购媒体
|
||||
Route::get('getJdPromotionSite', 'app\cunkebao\controller\workbench\WorkbenchController@getJdPromotionSite'); // 获取京东联盟广告位
|
||||
Route::get('changeLink', 'app\cunkebao\controller\workbench\WorkbenchController@changeLink'); // 获取京东联盟广告位
|
||||
|
||||
Route::get('group-push-stats', 'app\cunkebao\controller\WorkbenchController@getGroupPushStats'); // 获取群发统计数据
|
||||
Route::get('group-push-history', 'app\cunkebao\controller\WorkbenchController@getGroupPushHistory'); // 获取推送历史记录列表
|
||||
Route::get('group-push-stats', 'app\cunkebao\controller\workbench\WorkbenchController@getGroupPushStats'); // 获取群发统计数据
|
||||
Route::get('group-push-history', 'app\cunkebao\controller\workbench\WorkbenchController@getGroupPushHistory'); // 获取推送历史记录列表
|
||||
});
|
||||
|
||||
// 内容库相关
|
||||
|
||||
@@ -643,7 +643,7 @@ class ContentLibraryController extends Controller
|
||||
// 查询数据
|
||||
$list = ContentItem::where($where)
|
||||
->field('id,libraryId,type,title,content,contentAi,contentType,resUrls,urls,friendId,wechatId,wechatChatroomId,createTime,createMomentTime,createMessageTime,coverImage,ossUrls')
|
||||
->order('createTime DESC,createMomentTime DESC')
|
||||
->order('createMomentTime DESC,createMessageTime DESC,createTime DESC')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
|
||||
@@ -782,8 +782,8 @@ class ChannelController extends BaseController
|
||||
if (!empty($channelIds)) {
|
||||
// 构建提现查询条件
|
||||
$withdrawalWhere = [
|
||||
['companyId', '=', $companyId],
|
||||
['channelId', 'in', $channelIds]
|
||||
['companyId', '=', $companyId],
|
||||
['channelId', 'in', $channelIds]
|
||||
];
|
||||
|
||||
// 如果不是管理员,只能查看自己创建的提现申请
|
||||
@@ -817,7 +817,7 @@ class ChannelController extends BaseController
|
||||
|
||||
// totalRevenue 不包括驳回(rejected)状态的金额
|
||||
if ($status !== DistributionWithdrawal::STATUS_REJECTED) {
|
||||
$withdrawalStats[$cid]['totalRevenue'] += $amount;
|
||||
$withdrawalStats[$cid]['totalRevenue'] += $amount;
|
||||
}
|
||||
|
||||
if ($status === DistributionWithdrawal::STATUS_PAID) {
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller\workbench;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 工作台 - 自动点赞相关功能
|
||||
*/
|
||||
class WorkbenchAutoLikeController extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取点赞记录列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getLikeRecords()
|
||||
{
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$workbenchId = $this->request->param('workbenchId', 0);
|
||||
|
||||
$where = [
|
||||
['wali.workbenchId', '=', $workbenchId]
|
||||
];
|
||||
|
||||
// 查询点赞记录
|
||||
$list = Db::name('workbench_auto_like_item')->alias('wali')
|
||||
->join(['s2_wechat_moments' => 'wm'], 'wali.snsId = wm.snsId')
|
||||
->field([
|
||||
'wali.id',
|
||||
'wali.workbenchId',
|
||||
'wali.momentsId',
|
||||
'wali.snsId',
|
||||
'wali.wechatAccountId',
|
||||
'wali.wechatFriendId',
|
||||
'wali.createTime as likeTime',
|
||||
'wm.content',
|
||||
'wm.resUrls',
|
||||
'wm.createTime as momentTime',
|
||||
'wm.userName',
|
||||
])
|
||||
->where($where)
|
||||
->order('wali.createTime', 'desc')
|
||||
->group('wali.id')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
|
||||
// 处理数据
|
||||
foreach ($list as &$item) {
|
||||
//处理用户信息
|
||||
$friend = Db::table('s2_wechat_friend')
|
||||
->where(['id' => $item['wechatFriendId']])
|
||||
->field('nickName,avatar')
|
||||
->find();
|
||||
if (!empty($friend)) {
|
||||
$item['friendName'] = $friend['nickName'];
|
||||
$item['friendAvatar'] = $friend['avatar'];
|
||||
} else {
|
||||
$item['friendName'] = '';
|
||||
$item['friendAvatar'] = '';
|
||||
}
|
||||
|
||||
|
||||
//处理客服
|
||||
$friend = Db::table('s2_wechat_account')
|
||||
->where(['id' => $item['wechatAccountId']])
|
||||
->field('nickName,avatar')
|
||||
->find();
|
||||
if (!empty($friend)) {
|
||||
$item['operatorName'] = $friend['nickName'];
|
||||
$item['operatorAvatar'] = $friend['avatar'];
|
||||
} else {
|
||||
$item['operatorName'] = '';
|
||||
$item['operatorAvatar'] = '';
|
||||
}
|
||||
|
||||
// 处理时间格式
|
||||
$item['likeTime'] = date('Y-m-d H:i:s', $item['likeTime']);
|
||||
$item['momentTime'] = !empty($item['momentTime']) ? date('Y-m-d H:i:s', $item['momentTime']) : '';
|
||||
|
||||
// 处理资源链接
|
||||
if (!empty($item['resUrls'])) {
|
||||
$item['resUrls'] = json_decode($item['resUrls'], true);
|
||||
} else {
|
||||
$item['resUrls'] = [];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取总记录数
|
||||
$total = Db::name('workbench_auto_like_item')->alias('wali')
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller\workbench;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
use think\facade\Env;
|
||||
|
||||
/**
|
||||
* 工作台 - 辅助功能
|
||||
*/
|
||||
class WorkbenchHelperController extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取所有微信好友标签及数量统计
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getDeviceLabels()
|
||||
{
|
||||
$deviceIds = $this->request->param('deviceIds', '');
|
||||
$companyId = $this->request->userInfo['companyId'];
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
|
||||
$where = [
|
||||
['wc.companyId', '=', $companyId],
|
||||
];
|
||||
|
||||
if (!empty($deviceIds)) {
|
||||
$deviceIds = explode(',', $deviceIds);
|
||||
$where[] = ['dwl.deviceId', 'in', $deviceIds];
|
||||
}
|
||||
|
||||
$wechatAccounts = Db::name('wechat_customer')->alias('wc')
|
||||
->join('device_wechat_login dwl', 'dwl.wechatId = wc.wechatId AND dwl.companyId = wc.companyId AND dwl.alive = 1')
|
||||
->join(['s2_wechat_account' => 'wa'], 'wa.wechatId = wc.wechatId')
|
||||
->where($where)
|
||||
->field('wa.id,wa.wechatId,wa.nickName,wa.labels')
|
||||
->select();
|
||||
$labels = [];
|
||||
$wechatIds = [];
|
||||
foreach ($wechatAccounts as $account) {
|
||||
$labelArr = json_decode($account['labels'], true);
|
||||
if (is_array($labelArr)) {
|
||||
foreach ($labelArr as $label) {
|
||||
if ($label !== '' && $label !== null) {
|
||||
$labels[] = $label;
|
||||
}
|
||||
}
|
||||
}
|
||||
$wechatIds[] = $account['wechatId'];
|
||||
}
|
||||
// 去重(只保留一个)
|
||||
$labels = array_values(array_unique($labels));
|
||||
$wechatIds = array_unique($wechatIds);
|
||||
|
||||
// 搜索过滤
|
||||
if (!empty($keyword)) {
|
||||
$labels = array_filter($labels, function ($label) use ($keyword) {
|
||||
return mb_stripos($label, $keyword) !== false;
|
||||
});
|
||||
$labels = array_values($labels); // 重新索引数组
|
||||
}
|
||||
|
||||
// 分页处理
|
||||
$labels2 = array_slice($labels, ($page - 1) * $limit, $limit);
|
||||
|
||||
// 统计数量
|
||||
$newLabel = [];
|
||||
foreach ($labels2 as $label) {
|
||||
$friendCount = Db::table('s2_wechat_friend')
|
||||
->whereIn('ownerWechatId', $wechatIds)
|
||||
->where('labels', 'like', '%"' . $label . '"%')
|
||||
->count();
|
||||
$newLabel[] = [
|
||||
'label' => $label,
|
||||
'count' => $friendCount
|
||||
];
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $newLabel,
|
||||
'total' => count($labels),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取群列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getGroupList()
|
||||
{
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
|
||||
$where = [
|
||||
['wg.deleteTime', '=', 0],
|
||||
['wg.companyId', '=', $this->request->userInfo['companyId']],
|
||||
];
|
||||
|
||||
if (!empty($keyword)) {
|
||||
$where[] = ['wg.name', 'like', '%' . $keyword . '%'];
|
||||
}
|
||||
|
||||
$query = Db::name('wechat_group')->alias('wg')
|
||||
->join('wechat_account wa', 'wa.wechatId = wg.ownerWechatId')
|
||||
->where($where);
|
||||
|
||||
$total = $query->count();
|
||||
$list = $query->order('wg.id', 'desc')
|
||||
->field('wg.id,wg.name as groupName,wg.ownerWechatId,wa.nickName,wg.createTime,wa.avatar,wa.alias,wg.avatar as groupAvatar')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
// 优化:格式化时间,头像兜底
|
||||
$defaultGroupAvatar = '';
|
||||
$defaultAvatar = '';
|
||||
foreach ($list as &$item) {
|
||||
$item['createTime'] = $item['createTime'] ? date('Y-m-d H:i:s', $item['createTime']) : '';
|
||||
$item['groupAvatar'] = $item['groupAvatar'] ?: $defaultGroupAvatar;
|
||||
$item['avatar'] = $item['avatar'] ?: $defaultAvatar;
|
||||
}
|
||||
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => ['total' => $total, 'list' => $list]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流量池列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getTrafficPoolList()
|
||||
{
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
$companyId = $this->request->userInfo['companyId'];
|
||||
|
||||
$baseQuery = Db::name('traffic_source_package')->alias('tsp')
|
||||
->where('tsp.isDel', 0)
|
||||
->whereIn('tsp.companyId', [$companyId, 0]);
|
||||
|
||||
if (!empty($keyword)) {
|
||||
$baseQuery->whereLike('tsp.name', '%' . $keyword . '%');
|
||||
}
|
||||
|
||||
$total = (clone $baseQuery)->count();
|
||||
|
||||
$list = $baseQuery
|
||||
->leftJoin('traffic_source_package_item tspi', 'tspi.packageId = tsp.id and tspi.isDel = 0')
|
||||
->field('tsp.id,tsp.name,tsp.description,tsp.pic,tsp.companyId,COUNT(tspi.id) as itemCount,max(tspi.createTime) as latestImportTime')
|
||||
->group('tsp.id')
|
||||
->order('tsp.id', 'desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
foreach ($list as &$item) {
|
||||
$item['latestImportTime'] = !empty($item['latestImportTime']) ? date('Y-m-d H:i:s', $item['latestImportTime']) : '';
|
||||
}
|
||||
unset($item);
|
||||
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => ['total' => $total, 'list' => $list]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账号列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getAccountList()
|
||||
{
|
||||
$companyId = $this->request->userInfo['companyId'];
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$query = Db::table('s2_company_account')
|
||||
->alias('a')
|
||||
->where(['a.departmentId' => $companyId, 'a.status' => 0])
|
||||
->whereNotLike('a.userName', '%_offline%')
|
||||
->whereNotLike('a.userName', '%_delete%');
|
||||
|
||||
$total = $query->count();
|
||||
$list = $query->field('a.id,a.userName,a.realName,a.nickname,a.memo')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => ['total' => $total, 'list' => $list]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取京东联盟导购媒体
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getJdSocialMedia()
|
||||
{
|
||||
$data = Db::name('jd_social_media')->order('id DESC')->select();
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => $data]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取京东联盟广告位
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getJdPromotionSite()
|
||||
{
|
||||
$id = $this->request->param('id', '');
|
||||
if (empty($id)) {
|
||||
return json(['code' => 500, 'msg' => '参数缺失']);
|
||||
}
|
||||
|
||||
$data = Db::name('jd_promotion_site')->where('jdSocialMediaId', $id)->order('id DESC')->select();
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => $data]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 京东转链-京推推
|
||||
* @param string $content
|
||||
* @param string $positionid
|
||||
* @return string
|
||||
*/
|
||||
public function changeLink($content = '', $positionid = '')
|
||||
{
|
||||
$unionId = Env::get('jd.unionId', '');
|
||||
$jttAppId = Env::get('jd.jttAppId', '');
|
||||
$appKey = Env::get('jd.appKey', '');
|
||||
$apiUrl = Env::get('jd.apiUrl', '');
|
||||
|
||||
$content = !empty($content) ? $content : $this->request->param('content', '');
|
||||
$positionid = !empty($positionid) ? $positionid : $this->request->param('positionid', '');
|
||||
|
||||
if (empty($content)) {
|
||||
return json_encode(['code' => 500, 'msg' => '转链的内容为空']);
|
||||
}
|
||||
|
||||
// 验证是否包含链接
|
||||
if (!$this->containsLink($content)) {
|
||||
return json_encode(['code' => 500, 'msg' => '内容中未检测到有效链接']);
|
||||
}
|
||||
|
||||
if (empty($unionId) || empty($jttAppId) || empty($appKey) || empty($apiUrl)) {
|
||||
return json_encode(['code' => 500, 'msg' => '参数缺失']);
|
||||
}
|
||||
$params = [
|
||||
'unionid' => $unionId,
|
||||
'content' => $content,
|
||||
'appid' => $jttAppId,
|
||||
'appkey' => $appKey,
|
||||
'v' => 'v2'
|
||||
];
|
||||
|
||||
if (!empty($positionid)) {
|
||||
$params['positionid'] = $positionid;
|
||||
}
|
||||
|
||||
$res = requestCurl($apiUrl, $params, 'GET', [], 'json');
|
||||
$res = json_decode($res, true);
|
||||
if (empty($res)) {
|
||||
return json_encode(['code' => 500, 'msg' => '未知错误']);
|
||||
}
|
||||
$result = $res['result'];
|
||||
if ($res['return'] == 0) {
|
||||
return json_encode(['code' => 200, 'data' => $result['chain_content'], 'msg' => $result['msg']]);
|
||||
} else {
|
||||
return json_encode(['code' => 500, 'msg' => $result['msg']]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证内容是否包含链接
|
||||
* @param string $content 要检测的内容
|
||||
* @return bool
|
||||
*/
|
||||
private function containsLink($content)
|
||||
{
|
||||
// 定义各种链接的正则表达式模式
|
||||
$patterns = [
|
||||
// HTTP/HTTPS链接
|
||||
'/https?:\/\/[^\s]+/i',
|
||||
// 京东商品链接
|
||||
'/item\.jd\.com\/\d+/i',
|
||||
// 京东短链接
|
||||
'/u\.jd\.com\/[a-zA-Z0-9]+/i',
|
||||
// 淘宝商品链接
|
||||
'/item\.taobao\.com\/item\.htm\?id=\d+/i',
|
||||
// 天猫商品链接
|
||||
'/detail\.tmall\.com\/item\.htm\?id=\d+/i',
|
||||
// 淘宝短链接
|
||||
'/m\.tb\.cn\/[a-zA-Z0-9]+/i',
|
||||
// 拼多多链接
|
||||
'/mobile\.yangkeduo\.com\/goods\.html\?goods_id=\d+/i',
|
||||
// 苏宁易购链接
|
||||
'/product\.suning\.com\/\d+\/\d+\.html/i',
|
||||
// 通用域名模式(包含常见电商域名)
|
||||
'/(?:jd|taobao|tmall|yangkeduo|suning|amazon|dangdang)\.com[^\s]*/i',
|
||||
// 通用短链接模式
|
||||
'/[a-zA-Z0-9-]+\.[a-zA-Z]{2,}\/[a-zA-Z0-9\-._~:\/?#\[\]@!$&\'()*+,;=]+/i'
|
||||
];
|
||||
|
||||
// 遍历所有模式进行匹配
|
||||
foreach ($patterns as $pattern) {
|
||||
if (preg_match($pattern, $content)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller\workbench;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 工作台 - 联系人导入相关功能
|
||||
*/
|
||||
class WorkbenchImportContactController extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取通讯录导入记录列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getImportContact()
|
||||
{
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$workbenchId = $this->request->param('workbenchId', 0);
|
||||
|
||||
$where = [
|
||||
['wici.workbenchId', '=', $workbenchId]
|
||||
];
|
||||
|
||||
// 查询发布记录
|
||||
$list = Db::name('workbench_import_contact_item')->alias('wici')
|
||||
->join('traffic_pool tp', 'tp.id = wici.poolId', 'left')
|
||||
->join('traffic_source tc', 'tc.identifier = tp.identifier', 'left')
|
||||
->join('wechat_account wa', 'wa.wechatId = tp.wechatId', 'left')
|
||||
->field([
|
||||
'wici.id',
|
||||
'wici.workbenchId',
|
||||
'wici.createTime',
|
||||
'tp.identifier',
|
||||
'tp.mobile',
|
||||
'tp.wechatId',
|
||||
'tc.name',
|
||||
'wa.nickName',
|
||||
'wa.avatar',
|
||||
'wa.alias',
|
||||
])
|
||||
->where($where)
|
||||
->order('tc.name DESC,wici.createTime DESC')
|
||||
->group('tp.identifier')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
foreach ($list as &$item) {
|
||||
$item['createTime'] = date('Y-m-d H:i:s', $item['createTime']);
|
||||
}
|
||||
|
||||
// 获取总记录数
|
||||
$total = Db::name('workbench_import_contact_item')->alias('wici')
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller\workbench;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 工作台 - 朋友圈同步相关功能
|
||||
*/
|
||||
class WorkbenchMomentsController extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取朋友圈发布记录列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getMomentsRecords()
|
||||
{
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$workbenchId = $this->request->param('workbenchId', 0);
|
||||
|
||||
$where = [
|
||||
['wmsi.workbenchId', '=', $workbenchId]
|
||||
];
|
||||
|
||||
// 查询发布记录
|
||||
$list = Db::name('workbench_moments_sync_item')->alias('wmsi')
|
||||
->join('content_item ci', 'ci.id = wmsi.contentId', 'left')
|
||||
->join(['s2_wechat_account' => 'wa'], 'wa.id = wmsi.wechatAccountId', 'left')
|
||||
->field([
|
||||
'wmsi.id',
|
||||
'wmsi.workbenchId',
|
||||
'wmsi.createTime as publishTime',
|
||||
'ci.contentType',
|
||||
'ci.content',
|
||||
'ci.resUrls',
|
||||
'ci.urls',
|
||||
'wa.nickName as operatorName',
|
||||
'wa.avatar as operatorAvatar'
|
||||
])
|
||||
->where($where)
|
||||
->order('wmsi.createTime', 'desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
foreach ($list as &$item) {
|
||||
$item['resUrls'] = json_decode($item['resUrls'], true);
|
||||
$item['urls'] = json_decode($item['urls'], true);
|
||||
}
|
||||
|
||||
|
||||
// 获取总记录数
|
||||
$total = Db::name('workbench_moments_sync_item')->alias('wmsi')
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取朋友圈发布统计
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getMomentsStats()
|
||||
{
|
||||
$workbenchId = $this->request->param('workbenchId', 0);
|
||||
if (empty($workbenchId)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 获取今日数据
|
||||
$todayStart = strtotime(date('Y-m-d') . ' 00:00:00');
|
||||
$todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
|
||||
|
||||
$todayStats = Db::name('workbench_moments_sync_item')
|
||||
->where([
|
||||
['workbenchId', '=', $workbenchId],
|
||||
['createTime', 'between', [$todayStart, $todayEnd]]
|
||||
])
|
||||
->field([
|
||||
'COUNT(*) as total',
|
||||
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
|
||||
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
|
||||
])
|
||||
->find();
|
||||
|
||||
// 获取总数据
|
||||
$totalStats = Db::name('workbench_moments_sync_item')
|
||||
->where('workbenchId', $workbenchId)
|
||||
->field([
|
||||
'COUNT(*) as total',
|
||||
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
|
||||
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
|
||||
])
|
||||
->find();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'today' => [
|
||||
'total' => intval($todayStats['total']),
|
||||
'success' => intval($todayStats['success']),
|
||||
'failed' => intval($todayStats['failed'])
|
||||
],
|
||||
'total' => [
|
||||
'total' => intval($totalStats['total']),
|
||||
'success' => intval($totalStats['success']),
|
||||
'failed' => intval($totalStats['failed'])
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller\workbench;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 工作台 - 流量分发相关功能
|
||||
*/
|
||||
class WorkbenchTrafficController extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取流量分发记录列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getTrafficDistributionRecords()
|
||||
{
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$workbenchId = $this->request->param('workbenchId', 0);
|
||||
|
||||
$where = [
|
||||
['wtdi.workbenchId', '=', $workbenchId]
|
||||
];
|
||||
|
||||
// 查询分发记录
|
||||
$list = Db::name('workbench_traffic_distribution_item')->alias('wtdi')
|
||||
->join(['s2_wechat_account' => 'wa'], 'wa.id = wtdi.wechatAccountId', 'left')
|
||||
->join(['s2_wechat_friend' => 'wf'], 'wf.id = wtdi.wechatFriendId', 'left')
|
||||
->field([
|
||||
'wtdi.id',
|
||||
'wtdi.workbenchId',
|
||||
'wtdi.wechatAccountId',
|
||||
'wtdi.wechatFriendId',
|
||||
'wtdi.createTime as distributeTime',
|
||||
'wtdi.status',
|
||||
'wtdi.errorMsg',
|
||||
'wa.nickName as operatorName',
|
||||
'wa.avatar as operatorAvatar',
|
||||
'wf.nickName as friendName',
|
||||
'wf.avatar as friendAvatar',
|
||||
'wf.gender',
|
||||
'wf.province',
|
||||
'wf.city'
|
||||
])
|
||||
->where($where)
|
||||
->order('wtdi.createTime', 'desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
// 处理数据
|
||||
foreach ($list as &$item) {
|
||||
// 处理时间格式
|
||||
$item['distributeTime'] = date('Y-m-d H:i:s', $item['distributeTime']);
|
||||
|
||||
// 处理性别
|
||||
$genderMap = [
|
||||
0 => '未知',
|
||||
1 => '男',
|
||||
2 => '女'
|
||||
];
|
||||
$item['genderText'] = $genderMap[$item['gender']] ?? '未知';
|
||||
|
||||
// 处理状态文字
|
||||
$statusMap = [
|
||||
0 => '待分发',
|
||||
1 => '分发成功',
|
||||
2 => '分发失败'
|
||||
];
|
||||
$item['statusText'] = $statusMap[$item['status']] ?? '未知状态';
|
||||
}
|
||||
|
||||
// 获取总记录数
|
||||
$total = Db::name('workbench_traffic_distribution_item')->alias('wtdi')
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流量分发统计
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getTrafficDistributionStats()
|
||||
{
|
||||
$workbenchId = $this->request->param('workbenchId', 0);
|
||||
if (empty($workbenchId)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 获取今日数据
|
||||
$todayStart = strtotime(date('Y-m-d') . ' 00:00:00');
|
||||
$todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
|
||||
|
||||
$todayStats = Db::name('workbench_traffic_distribution_item')
|
||||
->where([
|
||||
['workbenchId', '=', $workbenchId],
|
||||
['createTime', 'between', [$todayStart, $todayEnd]]
|
||||
])
|
||||
->field([
|
||||
'COUNT(*) as total',
|
||||
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
|
||||
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
|
||||
])
|
||||
->find();
|
||||
|
||||
// 获取总数据
|
||||
$totalStats = Db::name('workbench_traffic_distribution_item')
|
||||
->where('workbenchId', $workbenchId)
|
||||
->field([
|
||||
'COUNT(*) as total',
|
||||
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
|
||||
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
|
||||
])
|
||||
->find();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'today' => [
|
||||
'total' => intval($todayStats['total']),
|
||||
'success' => intval($todayStats['success']),
|
||||
'failed' => intval($todayStats['failed'])
|
||||
],
|
||||
'total' => [
|
||||
'total' => intval($totalStats['total']),
|
||||
'success' => intval($totalStats['success']),
|
||||
'failed' => intval($totalStats['failed'])
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流量分发详情
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getTrafficDistributionDetail()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
if (empty($id)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
$detail = Db::name('workbench_traffic_distribution_item')->alias('wtdi')
|
||||
->join(['s2_wechat_account' => 'wa'], 'wa.id = wtdi.wechatAccountId', 'left')
|
||||
->join(['s2_wechat_friend' => 'wf'], 'wf.id = wtdi.wechatFriendId', 'left')
|
||||
->field([
|
||||
'wtdi.id',
|
||||
'wtdi.workbenchId',
|
||||
'wtdi.wechatAccountId',
|
||||
'wtdi.wechatFriendId',
|
||||
'wtdi.createTime as distributeTime',
|
||||
'wtdi.status',
|
||||
'wtdi.errorMsg',
|
||||
'wa.nickName as operatorName',
|
||||
'wa.avatar as operatorAvatar',
|
||||
'wf.nickName as friendName',
|
||||
'wf.avatar as friendAvatar',
|
||||
'wf.gender',
|
||||
'wf.province',
|
||||
'wf.city',
|
||||
'wf.signature',
|
||||
'wf.remark'
|
||||
])
|
||||
->where('wtdi.id', $id)
|
||||
->find();
|
||||
|
||||
if (empty($detail)) {
|
||||
return json(['code' => 404, 'msg' => '记录不存在']);
|
||||
}
|
||||
|
||||
// 处理数据
|
||||
$detail['distributeTime'] = date('Y-m-d H:i:s', $detail['distributeTime']);
|
||||
|
||||
// 处理性别
|
||||
$genderMap = [
|
||||
0 => '未知',
|
||||
1 => '男',
|
||||
2 => '女'
|
||||
];
|
||||
$detail['genderText'] = $genderMap[$detail['gender']] ?? '未知';
|
||||
|
||||
// 处理状态文字
|
||||
$statusMap = [
|
||||
0 => '待分发',
|
||||
1 => '分发成功',
|
||||
2 => '分发失败'
|
||||
];
|
||||
$detail['statusText'] = $statusMap[$detail['status']] ?? '未知状态';
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => $detail
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建流量分发计划
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function createTrafficPlan()
|
||||
{
|
||||
$param = $this->request->post();
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 1. 创建主表
|
||||
$planId = Db::name('ck_workbench')->insertGetId([
|
||||
'name' => $param['name'],
|
||||
'type' => 5, // TYPE_TRAFFIC_DISTRIBUTION
|
||||
'status' => 1,
|
||||
'autoStart' => $param['autoStart'] ?? 0,
|
||||
'userId' => $this->request->userInfo['id'],
|
||||
'companyId' => $this->request->userInfo['companyId'],
|
||||
'createTime' => time(),
|
||||
'updateTime' => time()
|
||||
]);
|
||||
// 2. 创建扩展表
|
||||
Db::name('ck_workbench_traffic_config')->insert([
|
||||
'workbenchId' => $planId,
|
||||
'distributeType' => $param['distributeType'],
|
||||
'maxPerDay' => $param['maxPerDay'],
|
||||
'timeType' => $param['timeType'],
|
||||
'startTime' => $param['startTime'],
|
||||
'endTime' => $param['endTime'],
|
||||
'targets' => json_encode($param['targets'], JSON_UNESCAPED_UNICODE),
|
||||
'pools' => json_encode($param['poolGroups'], JSON_UNESCAPED_UNICODE),
|
||||
'createTime' => time(),
|
||||
'updateTime' => time()
|
||||
]);
|
||||
Db::commit();
|
||||
return json(['code' => 200, 'msg' => '创建成功']);
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
return json(['code' => 500, 'msg' => '创建失败:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流量列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getTrafficList()
|
||||
{
|
||||
$companyId = $this->request->userInfo['companyId'];
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
$workbenchId = $this->request->param('workbenchId', '');
|
||||
$isRecycle = $this->request->param('isRecycle', '');
|
||||
if (empty($workbenchId)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
$workbench = Db::name('workbench')->where(['id' => $workbenchId, 'isDel' => 0, 'companyId' => $companyId, 'type' => 5])->find();
|
||||
|
||||
if (empty($workbench)) {
|
||||
return json(['code' => 400, 'msg' => '该任务不存在或已删除']);
|
||||
}
|
||||
$query = Db::name('workbench_traffic_config_item')->alias('wtc')
|
||||
->join(['s2_wechat_friend' => 'wf'], 'wtc.wechatFriendId = wf.id')
|
||||
->join('users u', 'wtc.wechatAccountId = u.s2_accountId', 'left')
|
||||
->field([
|
||||
'wtc.id', 'wtc.isRecycle', 'wtc.isRecycle', 'wtc.createTime','wtc.recycleTime',
|
||||
'wf.wechatId', 'wf.alias', 'wf.nickname', 'wf.avatar', 'wf.gender', 'wf.phone',
|
||||
'u.account', 'u.username'
|
||||
])
|
||||
->where(['wtc.workbenchId' => $workbenchId])
|
||||
->order('wtc.id DESC');
|
||||
|
||||
if (!empty($keyword)) {
|
||||
$query->where('wf.wechatId|wf.alias|wf.nickname|wf.phone|u.account|u.username', 'like', '%' . $keyword . '%');
|
||||
}
|
||||
|
||||
if ($isRecycle != '' || $isRecycle != null) {
|
||||
$query->where('isRecycle',$isRecycle);
|
||||
}
|
||||
|
||||
$total = $query->count();
|
||||
$list = $query->page($page, $limit)->select();
|
||||
|
||||
foreach ($list as &$item) {
|
||||
$item['createTime'] = date('Y-m-d H:i:s', $item['createTime']);
|
||||
$item['recycleTime'] = date('Y-m-d H:i:s', $item['recycleTime']);
|
||||
}
|
||||
unset($item);
|
||||
|
||||
$data = [
|
||||
'total' => $total,
|
||||
'list' => $list,
|
||||
];
|
||||
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => $data]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,24 @@ namespace app\job;
|
||||
|
||||
use app\chukebao\model\Reply;
|
||||
use app\chukebao\model\ReplyGroup;
|
||||
use think\Db;
|
||||
use think\queue\Job;
|
||||
|
||||
class SyncContentJob
|
||||
{
|
||||
public function fire(Job $job, $data)
|
||||
{
|
||||
|
||||
$ddd= Db::table('s2_wechat_friend')->where('ownerWechatId','wxid_h7nsh7vxseyn29')->select();
|
||||
foreach ($ddd as $v) {
|
||||
$d = Db::table('ck_task_customer')->where('task_id','167')->where('phone',$v['wechatId'])->find();
|
||||
if (!empty($d) && !in_array($d['status'],[4,5])) {
|
||||
Db::table('ck_task_customer')->where('id',$d['id'])->update(['status'=>5]);
|
||||
}
|
||||
}
|
||||
|
||||
exit_data(111);
|
||||
|
||||
return true;
|
||||
/*$ddd= '[{"id":21909,"groupName":"私域运营招聘","sortIndex":240426546,"parentId":0,"replyType":1,"children":[],"replys":null},{"id":8074,"groupName":"存客宝新客户介绍","sortIndex":230,"parentId":0,"replyType":1,"children":[{"id":8081,"groupName":"客户系统上线准备","sortIndex":1,"parentId":8074,"replyType":1,"children":[],"replys":null}],"replys":null},{"id":10441,"groupName":"BOSS直聘","sortIndex":229,"parentId":0,"replyType":1,"children":[],"replys":null},{"id":15111,"groupName":"点了码新客户了解","sortIndex":228,"parentId":0,"replyType":1,"children":[],"replys":null},{"id":12732,"groupName":"测试","sortIndex":219,"parentId":0,"replyType":1,"children":[],"replys":null},{"id":8814,"groupName":"封单话术","sortIndex":176,"parentId":0,"replyType":1,"children":[],"replys":null},{"id":8216,"groupName":"私域合伙人","sortIndex":172,"parentId":0,"replyType":1,"children":[],"replys":null},{"id":6476,"groupName":"新客户了解","sortIndex":119,"parentId":0,"replyType":1,"children":[],"replys":null}]';
|
||||
$ddd=json_decode($ddd,1);*/
|
||||
|
||||
@@ -77,7 +77,8 @@ class WorkbenchGroupCreateJob
|
||||
{
|
||||
try {
|
||||
// 1. 查询启用了建群功能的数据
|
||||
$workbenches = Workbench::where(['status' => 1, 'type' => 4, 'isDel' => 0,'id' => 315])->order('id desc')->select();
|
||||
$workbenches = Workbench::where(['status' => 0, 'type' => 4, 'isDel' => 0,'id' => 354])->order('id desc')->select();
|
||||
|
||||
foreach ($workbenches as $workbench) {
|
||||
// 获取工作台配置
|
||||
$config = WorkbenchGroupCreate::where('workbenchId', $workbench->id)->find();
|
||||
@@ -86,22 +87,49 @@ class WorkbenchGroupCreateJob
|
||||
}
|
||||
|
||||
// 解析配置
|
||||
$config['poolGroups'] = json_decode($config['poolGroups'], true);
|
||||
$config['devices'] = json_decode($config['devices'], true);
|
||||
$config['poolGroups'] = json_decode($config['poolGroups'] ?? '[]', true) ?: [];
|
||||
$config['devices'] = json_decode($config['devices'] ?? '[]', true) ?: [];
|
||||
$config['wechatGroups'] = json_decode($config['wechatGroups'] ?? '[]', true) ?: [];
|
||||
$config['admins'] = json_decode($config['admins'] ?? '[]', true) ?: [];
|
||||
|
||||
if (empty($config['poolGroups']) || empty($config['devices'])) {
|
||||
// 检查时间限制
|
||||
if (!$this->isWithinTimeRange($config)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查每日建群数量限制
|
||||
if (!$this->checkDailyLimit($workbench->id, $config)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查是否有正在创建中的群,如果有则跳过(避免重复创建)
|
||||
$creatingCount = Db::name('workbench_group_create_item')
|
||||
->where('workbenchId', $workbench->id)
|
||||
->where('status', self::STATUS_CREATING)
|
||||
->where('groupId', '<>', null) // 有groupId的记录
|
||||
->group('groupId')
|
||||
->count();
|
||||
if ($creatingCount > 0) {
|
||||
Log::info("工作台ID: {$workbench->id} 有正在创建中的群({$creatingCount}个),跳过本次执行");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($config['devices'])) {
|
||||
continue;
|
||||
}
|
||||
// 获取群主成员(从设备中获取)
|
||||
$groupMember = [];
|
||||
$wechatId = Db::name('device_wechat_login')
|
||||
->whereIn('deviceId',$config['devices'])
|
||||
$wechatIds = Db::name('device_wechat_login')
|
||||
->whereIn('deviceId', $config['devices'])
|
||||
->where('alive', DeviceWechatLoginModel::ALIVE_WECHAT_ACTIVE)
|
||||
->order('id desc')
|
||||
->value('wechatId');
|
||||
if (empty($wechatId)) {
|
||||
->column('wechatId');
|
||||
|
||||
if (empty($wechatIds)) {
|
||||
continue;
|
||||
}
|
||||
$groupMember[] = $wechatId;
|
||||
$groupMember = array_unique($wechatIds);
|
||||
|
||||
// 获取群主好友ID映射(所有群主的好友)
|
||||
$groupMemberWechatId = [];
|
||||
$groupMemberId = [];
|
||||
@@ -110,6 +138,7 @@ class WorkbenchGroupCreateJob
|
||||
$friends = Db::table('s2_wechat_friend')
|
||||
->where('ownerWechatId', $ownerWechatId)
|
||||
->whereIn('wechatId', $groupMember)
|
||||
->where('isDeleted', 0)
|
||||
->field('id,wechatId')
|
||||
->select();
|
||||
|
||||
@@ -120,44 +149,78 @@ class WorkbenchGroupCreateJob
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($groupMemberWechatId)) {
|
||||
|
||||
// 如果配置了wechatGroups,从指定的群组中获取成员
|
||||
if (!empty($config['wechatGroups'])) {
|
||||
$this->addGroupMembersFromWechatGroups($config['wechatGroups'], $groupMember, $groupMemberId, $groupMemberWechatId);
|
||||
}
|
||||
|
||||
if (empty($groupMemberId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取流量池用户
|
||||
$poolItem = Db::name('traffic_source_package_item')
|
||||
->whereIn('packageId', $config['poolGroups'])
|
||||
->group('identifier')
|
||||
->column('identifier');
|
||||
|
||||
|
||||
if (empty($poolItem)) {
|
||||
// 获取流量池用户(如果配置了流量池)
|
||||
$poolItem = [];
|
||||
if (!empty($config['poolGroups'])) {
|
||||
$poolItem = Db::name('traffic_source_package_item')
|
||||
->whereIn('packageId', $config['poolGroups'])
|
||||
->where('isDel', 0)
|
||||
->group('identifier')
|
||||
->column('identifier');
|
||||
}
|
||||
|
||||
// 如果既没有流量池也没有指定群组,跳过
|
||||
if (empty($poolItem) && empty($config['wechatGroups'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取已入群的用户(排除已成功入群的)111
|
||||
$groupUser = Db::name('workbench_group_create_item')
|
||||
->where('workbenchId', $workbench->id)
|
||||
->where('status', 'in', [self::STATUS_SUCCESS, self::STATUS_ADMIN_FRIEND_ADDED, self::STATUS_CREATING])
|
||||
->whereIn('wechatId', $poolItem)
|
||||
->group('wechatId')
|
||||
->column('wechatId');
|
||||
// 待入群的用户
|
||||
$joinUser = array_diff($poolItem, $groupUser);
|
||||
if (empty($joinUser)) {
|
||||
// 获取已入群的用户(排除已成功入群的)
|
||||
$groupUser = [];
|
||||
if (!empty($poolItem)) {
|
||||
$groupUser = Db::name('workbench_group_create_item')
|
||||
->where('workbenchId', $workbench->id)
|
||||
->where('status', 'in', [self::STATUS_SUCCESS, self::STATUS_ADMIN_FRIEND_ADDED, self::STATUS_CREATING])
|
||||
->whereIn('wechatId', $poolItem)
|
||||
->group('wechatId')
|
||||
->column('wechatId');
|
||||
}
|
||||
|
||||
// 待入群的用户(从流量池中筛选)
|
||||
$joinUser = !empty($poolItem) ? array_diff($poolItem, $groupUser) : [];
|
||||
|
||||
// 如果流量池用户已用完或没有配置流量池,但配置了wechatGroups,至少创建一次(使用群主成员)
|
||||
if (empty($joinUser) && !empty($config['wechatGroups'])) {
|
||||
// 如果没有流量池用户,创建一个空批次,让processBatchUsers处理只有群主成员的情况
|
||||
$joinUser = []; // 空数组,但会继续执行
|
||||
}
|
||||
|
||||
// 如果既没有流量池用户也没有配置wechatGroups,跳过
|
||||
if (empty($joinUser) && empty($config['wechatGroups'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 计算随机群人数(不包含管理员,只减去群主成员数)
|
||||
$groupRandNum = mt_rand($config['groupSizeMin'], $config['groupSizeMax']) - count($groupMember);
|
||||
// 群主成员数 = 群主好友ID数量
|
||||
$minGroupSize = max(2, $config['groupSizeMin']); // 至少2人才能建群
|
||||
$maxGroupSize = max($minGroupSize, $config['groupSizeMax']);
|
||||
$groupRandNum = mt_rand($minGroupSize, $maxGroupSize) - count($groupMemberId);
|
||||
if ($groupRandNum <= 0) {
|
||||
$groupRandNum = 1; // 至少需要1个成员
|
||||
}
|
||||
|
||||
// 分批处理待入群用户
|
||||
$addGroupUser = [];
|
||||
$totalRows = count($joinUser);
|
||||
for ($i = 0; $i < $totalRows; $i += $groupRandNum) {
|
||||
$batchRows = array_slice($joinUser, $i, $groupRandNum);
|
||||
if (!empty($batchRows)) {
|
||||
$addGroupUser[] = $batchRows;
|
||||
if (!empty($joinUser)) {
|
||||
$totalRows = count($joinUser);
|
||||
for ($i = 0; $i < $totalRows; $i += $groupRandNum) {
|
||||
$batchRows = array_slice($joinUser, $i, $groupRandNum);
|
||||
if (!empty($batchRows)) {
|
||||
$addGroupUser[] = $batchRows;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 如果没有流量池用户但配置了wechatGroups,创建一个空批次
|
||||
$addGroupUser[] = [];
|
||||
}
|
||||
// 初始化WebSocket
|
||||
$toAccountId = '';
|
||||
@@ -229,28 +292,59 @@ class WorkbenchGroupCreateJob
|
||||
$ownerFriendIdsByAccount = [];
|
||||
$wechatIds = [];
|
||||
|
||||
// 获取群主的好友关系(从流量池中筛选)
|
||||
$ownerFriends = Db::table('s2_wechat_friend')->alias('f')
|
||||
->join(['s2_wechat_account' => 'a'], 'f.wechatAccountId=a.id')
|
||||
->whereIn('f.wechatId', $batchUsers)
|
||||
->whereIn('a.wechatId', $groupOwnerWechatIds)
|
||||
->where('f.isDeleted', 0)
|
||||
->field('f.id,f.wechatId,a.id as wechatAccountId')
|
||||
->select();
|
||||
|
||||
if (empty($ownerFriends)) {
|
||||
Log::warning("未找到群主的好友,跳过。工作台ID: {$workbench->id}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 按微信账号分组群主好友
|
||||
foreach ($ownerFriends as $friend) {
|
||||
$wechatAccountId = $friend['wechatAccountId'];
|
||||
if (!isset($ownerFriendIdsByAccount[$wechatAccountId])) {
|
||||
$ownerFriendIdsByAccount[$wechatAccountId] = [];
|
||||
// 如果batchUsers为空,说明没有流量池用户,但可能配置了wechatGroups
|
||||
// 这种情况下,使用群主成员作为基础,按账号分组
|
||||
if (empty($batchUsers)) {
|
||||
// 按账号分组群主成员
|
||||
foreach ($groupMemberId as $memberId) {
|
||||
$member = Db::table('s2_wechat_friend')->where('id', $memberId)->find();
|
||||
if ($member) {
|
||||
$accountWechatId = $member['ownerWechatId'];
|
||||
$account = Db::table('s2_wechat_account')
|
||||
->where('wechatId', $accountWechatId)
|
||||
->field('id')
|
||||
->find();
|
||||
|
||||
if ($account) {
|
||||
$wechatAccountId = $account['id'];
|
||||
if (!isset($ownerFriendIdsByAccount[$wechatAccountId])) {
|
||||
$ownerFriendIdsByAccount[$wechatAccountId] = [];
|
||||
}
|
||||
$ownerFriendIdsByAccount[$wechatAccountId][] = $memberId;
|
||||
$wechatIds[$memberId] = $groupMemberWechatId[$memberId] ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
$ownerFriendIdsByAccount[$wechatAccountId][] = $friend['id'];
|
||||
$wechatIds[$friend['id']] = $friend['wechatId'];
|
||||
} else {
|
||||
// 获取群主的好友关系(从流量池中筛选)
|
||||
$ownerFriends = Db::table('s2_wechat_friend')->alias('f')
|
||||
->join(['s2_wechat_account' => 'a'], 'f.wechatAccountId=a.id')
|
||||
->whereIn('f.wechatId', $batchUsers)
|
||||
->whereIn('a.wechatId', $groupOwnerWechatIds)
|
||||
->where('f.isDeleted', 0)
|
||||
->field('f.id,f.wechatId,a.id as wechatAccountId')
|
||||
->select();
|
||||
|
||||
if (empty($ownerFriends)) {
|
||||
Log::warning("未找到群主的好友,跳过。工作台ID: {$workbench->id}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 按微信账号分组群主好友
|
||||
foreach ($ownerFriends as $friend) {
|
||||
$wechatAccountId = $friend['wechatAccountId'];
|
||||
if (!isset($ownerFriendIdsByAccount[$wechatAccountId])) {
|
||||
$ownerFriendIdsByAccount[$wechatAccountId] = [];
|
||||
}
|
||||
$ownerFriendIdsByAccount[$wechatAccountId][] = $friend['id'];
|
||||
$wechatIds[$friend['id']] = $friend['wechatId'];
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到任何好友,跳过
|
||||
if (empty($ownerFriendIdsByAccount)) {
|
||||
Log::warning("未找到任何群主好友或成员,跳过。工作台ID: {$workbench->id}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 遍历每个微信账号,创建群
|
||||
@@ -279,21 +373,47 @@ class WorkbenchGroupCreateJob
|
||||
}
|
||||
|
||||
// 4.3 限制群主好友数量(按随机群人数)
|
||||
$limitedOwnerFriendIds = array_slice($ownerFriendIds, 0, $groupRandNum);
|
||||
// 如果ownerFriendIds只包含群主成员(没有流量池用户),则不需要限制
|
||||
$limitedOwnerFriendIds = $ownerFriendIds;
|
||||
if (count($ownerFriendIds) > $groupRandNum) {
|
||||
$limitedOwnerFriendIds = array_slice($ownerFriendIds, 0, $groupRandNum);
|
||||
}
|
||||
|
||||
// 4.4 创建群:管理员 + 群主成员 + 群主好友(从流量池筛选)
|
||||
$createFriendIds = array_merge($currentAdminFriendIds, $currentGroupMemberIds, $limitedOwnerFriendIds);
|
||||
// 合并时去重,避免重复添加群主成员
|
||||
$createFriendIds = array_merge($currentAdminFriendIds, $currentGroupMemberIds);
|
||||
foreach ($limitedOwnerFriendIds as $friendId) {
|
||||
if (!in_array($friendId, $createFriendIds)) {
|
||||
$createFriendIds[] = $friendId;
|
||||
}
|
||||
}
|
||||
|
||||
// 微信建群至少需要2个人
|
||||
if (count($createFriendIds) < 2) {
|
||||
Log::warning("建群好友数量不足,跳过。工作台ID: {$workbench->id}, 微信账号ID: {$wechatAccountId}");
|
||||
Log::warning("建群好友数量不足(至少需要2人),跳过。工作台ID: {$workbench->id}, 微信账号ID: {$wechatAccountId}, 当前人数: " . count($createFriendIds));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 4.5 生成群名称
|
||||
// 4.5 检查当前账号是否有正在创建中的群,如果有则跳过
|
||||
$creatingGroupCount = Db::name('workbench_group_create_item')
|
||||
->where('workbenchId', $workbench->id)
|
||||
->where('wechatAccountId', $wechatAccountId)
|
||||
->where('status', self::STATUS_CREATING)
|
||||
->where('groupId', '<>', null)
|
||||
->group('groupId')
|
||||
->count();
|
||||
|
||||
if ($creatingGroupCount > 0) {
|
||||
Log::info("工作台ID: {$workbench->id}, 微信账号ID: {$wechatAccountId} 有正在创建中的群({$creatingGroupCount}个),跳过本次创建");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 4.6 生成群名称
|
||||
$existingGroupCount = Db::name('workbench_group_create_item')
|
||||
->where('workbenchId', $workbench->id)
|
||||
->where('wechatAccountId', $wechatAccountId)
|
||||
->where('status', self::STATUS_SUCCESS)
|
||||
->where('groupId', '<>', null) // 排除groupId为NULL的记录
|
||||
->group('groupId')
|
||||
->count();
|
||||
|
||||
@@ -301,7 +421,7 @@ class WorkbenchGroupCreateJob
|
||||
? $config['groupNameTemplate'] . ($existingGroupCount + 1) . '群'
|
||||
: $config['groupNameTemplate'];
|
||||
|
||||
// 4.6 调用建群接口
|
||||
// 4.7 调用建群接口
|
||||
$createTime = time();
|
||||
$createResult = $webSocket->CmdChatroomCreate([
|
||||
'chatroomName' => $chatroomName,
|
||||
@@ -311,18 +431,65 @@ class WorkbenchGroupCreateJob
|
||||
|
||||
$createResultData = json_decode($createResult, true);
|
||||
|
||||
// 4.7 解析建群结果,获取群ID
|
||||
$chatroomId = 0;
|
||||
// 4.8 解析建群结果,获取群ID
|
||||
// chatroomId: varchar(64) - 微信的群聊ID(字符串)
|
||||
// groupId: int(10) - 数据库中的群组ID(整数)
|
||||
$chatroomId = null; // 微信群聊ID(字符串)
|
||||
$groupId = 0; // 数据库群组ID(整数)
|
||||
$tempGroupId = null; // 临时群标识,用于轮询查询
|
||||
|
||||
if (!empty($createResultData) && isset($createResultData['code']) && $createResultData['code'] == 200) {
|
||||
// 尝试从返回数据中获取群ID(根据实际API返回格式调整)
|
||||
if (isset($createResultData['data']['chatroomId'])) {
|
||||
$chatroomId = $createResultData['data']['chatroomId'];
|
||||
// API返回的是chatroomId(字符串)
|
||||
$chatroomId = (string)$createResultData['data']['chatroomId'];
|
||||
// 通过chatroomId查询数据库获取groupId
|
||||
$group = Db::name('wechat_group')
|
||||
->where('chatroomId', $chatroomId)
|
||||
->where('deleteTime', 0)
|
||||
->find();
|
||||
if ($group) {
|
||||
$groupId = intval($group['id']);
|
||||
}
|
||||
} elseif (isset($createResultData['data']['id'])) {
|
||||
$chatroomId = $createResultData['data']['id'];
|
||||
// API返回的是数据库ID(整数)
|
||||
$groupId = intval($createResultData['data']['id']);
|
||||
// 通过groupId查询chatroomId
|
||||
$group = Db::name('wechat_group')
|
||||
->where('id', $groupId)
|
||||
->where('deleteTime', 0)
|
||||
->find();
|
||||
if ($group && !empty($group['chatroomId'])) {
|
||||
$chatroomId = (string)$group['chatroomId'];
|
||||
}
|
||||
}
|
||||
// 如果有临时标识,保存用于轮询
|
||||
if (isset($createResultData['data']['tempId'])) {
|
||||
$tempGroupId = $createResultData['data']['tempId'];
|
||||
}
|
||||
}
|
||||
|
||||
// 4.8 记录创建请求
|
||||
// 4.9 如果建群接口没有立即返回群ID,进行同步轮询检查
|
||||
if ($groupId == 0) {
|
||||
// 获取账号的微信ID(群主微信ID)
|
||||
$accountWechatId = Db::table('s2_wechat_account')
|
||||
->where('id', $wechatAccountId)
|
||||
->value('wechatId');
|
||||
|
||||
if (!empty($accountWechatId)) {
|
||||
$pollResult = $this->pollGroupCreation($chatroomName, $accountWechatId, $wechatAccountId, $tempGroupId);
|
||||
if ($pollResult && is_array($pollResult)) {
|
||||
$groupId = intval($pollResult['groupId'] ?? 0);
|
||||
$chatroomId = !empty($pollResult['chatroomId']) ? (string)$pollResult['chatroomId'] : null;
|
||||
} elseif ($pollResult > 0) {
|
||||
// 兼容旧返回值(只返回groupId)
|
||||
$groupId =0;
|
||||
$chatroomId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4.10 记录创建请求
|
||||
$installData = [];
|
||||
foreach ($createFriendIds as $friendId) {
|
||||
$memberType = in_array($friendId, $currentAdminFriendIds)
|
||||
@@ -333,20 +500,21 @@ class WorkbenchGroupCreateJob
|
||||
'workbenchId' => $workbench->id,
|
||||
'friendId' => $friendId,
|
||||
'wechatId' => $wechatIds[$friendId] ?? ($groupMemberWechatId[$friendId] ?? ''),
|
||||
'groupId' => $chatroomId,
|
||||
'groupId' => $groupId > 0 ? $groupId : null, // int类型
|
||||
'wechatAccountId' => $wechatAccountId,
|
||||
'status' => $chatroomId > 0 ? self::STATUS_SUCCESS : self::STATUS_CREATING,
|
||||
'status' => $groupId > 0 ? self::STATUS_SUCCESS : self::STATUS_FAILED,
|
||||
'memberType' => $memberType,
|
||||
'retryCount' => 0,
|
||||
'chatroomId' => $chatroomId > 0 ? $chatroomId : null,
|
||||
'chatroomId' => $chatroomId, // varchar类型
|
||||
'createTime' => $createTime,
|
||||
];
|
||||
}
|
||||
Db::name('workbench_group_create_item')->insertAll($installData);
|
||||
|
||||
// 5. 如果群创建成功,拉管理员的好友进群
|
||||
if ($chatroomId > 0 && !empty($currentAdminFriendIds)) {
|
||||
$this->inviteAdminFriends($workbench, $config, $batchUsers, $currentAdminFriendIds, $chatroomId, $wechatAccountId, $wechatIds, $createTime, $webSocket);
|
||||
// 注意:拉人接口需要chatroomId(字符串),而不是groupId(整数)
|
||||
if (!empty($chatroomId) && !empty($currentAdminFriendIds)) {
|
||||
$this->inviteAdminFriends($workbench, $config, $batchUsers, $currentAdminFriendIds, $chatroomId, $groupId, $wechatAccountId, $wechatIds, $createTime, $webSocket);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -357,13 +525,14 @@ class WorkbenchGroupCreateJob
|
||||
* @param array $config 配置
|
||||
* @param array $batchUsers 批次用户(流量池微信ID数组)
|
||||
* @param array $adminFriendIds 管理员好友ID数组
|
||||
* @param int $chatroomId 群ID
|
||||
* @param string $chatroomId 群聊ID(字符串,用于API调用)
|
||||
* @param int $groupId 数据库群组ID(整数)
|
||||
* @param int $wechatAccountId 微信账号ID
|
||||
* @param array $wechatIds 好友ID到微信ID的映射
|
||||
* @param int $createTime 创建时间
|
||||
* @param WebSocketController $webSocket WebSocket实例
|
||||
*/
|
||||
protected function inviteAdminFriends($workbench, $config, $batchUsers, $adminFriendIds, $chatroomId, $wechatAccountId, $wechatIds, $createTime, $webSocket)
|
||||
protected function inviteAdminFriends($workbench, $config, $batchUsers, $adminFriendIds, $chatroomId, $groupId, $wechatAccountId, $wechatIds, $createTime, $webSocket)
|
||||
{
|
||||
// 获取管理员的微信ID列表
|
||||
$adminWechatIds = [];
|
||||
@@ -399,7 +568,7 @@ class WorkbenchGroupCreateJob
|
||||
$wechatIds[$friend['id']] = $friend['wechatId'];
|
||||
}
|
||||
|
||||
// 调用拉人接口
|
||||
// 调用拉人接口(使用chatroomId字符串)
|
||||
$inviteResult = $webSocket->CmdChatroomInvite([
|
||||
'wechatChatroomId' => $chatroomId,
|
||||
'wechatFriendIds' => $adminFriendIdsToInvite
|
||||
@@ -415,12 +584,12 @@ class WorkbenchGroupCreateJob
|
||||
'workbenchId' => $workbench->id,
|
||||
'friendId' => $friendId,
|
||||
'wechatId' => $wechatIds[$friendId] ?? '',
|
||||
'groupId' => $chatroomId,
|
||||
'groupId' => $groupId > 0 ? $groupId : null, // int类型
|
||||
'wechatAccountId' => $wechatAccountId,
|
||||
'status' => $inviteSuccess ? self::STATUS_ADMIN_FRIEND_ADDED : self::STATUS_FAILED,
|
||||
'memberType' => self::MEMBER_TYPE_ADMIN_FRIEND,
|
||||
'retryCount' => 0,
|
||||
'chatroomId' => $chatroomId,
|
||||
'chatroomId' => $chatroomId, // varchar类型
|
||||
'createTime' => $createTime,
|
||||
];
|
||||
}
|
||||
@@ -429,40 +598,209 @@ class WorkbenchGroupCreateJob
|
||||
if ($inviteSuccess) {
|
||||
// 去除成功日志,减少日志空间消耗
|
||||
} else {
|
||||
Log::warning("管理员好友拉入失败。工作台ID: {$workbench->id}, 群ID: {$chatroomId}");
|
||||
Log::warning("管理员好友拉入失败。工作台ID: {$workbench->id}, 群组ID: {$groupId}, 群聊ID: {$chatroomId}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取设备列表
|
||||
* @param Workbench $workbench 工作台
|
||||
* @param WorkbenchGroupPush $config 配置
|
||||
* @return array|bool
|
||||
* 轮询检查群是否创建成功
|
||||
* @param string $chatroomName 群名称
|
||||
* @param string $ownerWechatId 群主微信ID
|
||||
* @param int $wechatAccountId 微信账号ID
|
||||
* @param string|null $tempGroupId 临时群标识(如果有)
|
||||
* @return array|int 返回数组包含groupId和chatroomId,或只返回groupId(兼容旧代码),如果未找到返回0
|
||||
*/
|
||||
protected function isCreate($workbench, $config, $groupIds = [])
|
||||
protected function pollGroupCreation($chatroomName, $ownerWechatId, $wechatAccountId, $tempGroupId = null)
|
||||
{
|
||||
// 检查发送间隔(新逻辑:根据startTime、endTime、maxPerDay动态计算)
|
||||
$maxAttempts = 10; // 最多查询10次
|
||||
$interval = 5; // 每次间隔5秒
|
||||
|
||||
// 获取账号ID(accountId)和微信账号的微信ID(wechatAccountWechatId),用于查询s2_wechat_chatroom表
|
||||
$accountInfo = Db::table('s2_wechat_account')
|
||||
->where('id', $wechatAccountId)
|
||||
->field('id,wechatId')
|
||||
->find();
|
||||
|
||||
$accountId = $accountInfo['id'] ?? null;
|
||||
$wechatAccountWechatId = $accountInfo['wechatId'] ?? null;
|
||||
|
||||
if (empty($accountId) && empty($wechatAccountWechatId)) {
|
||||
Log::warning("无法获取账号ID和微信账号ID,跳过轮询。微信账号ID: {$wechatAccountId}");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取授权信息(用于调用同步接口)
|
||||
$username = Env::get('api.username2', '');
|
||||
$password = Env::get('api.password2', '');
|
||||
|
||||
for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
|
||||
// 等待5秒(第一次立即查询,后续等待)
|
||||
if ($attempt > 1) {
|
||||
sleep($interval);
|
||||
}
|
||||
|
||||
// 1. 先调用接口同步最新的群组信息
|
||||
try {
|
||||
$chatroomController = new \app\api\controller\WechatChatroomController();
|
||||
// 构建同步参数
|
||||
$syncData = [
|
||||
'wechatAccountKeyword' => $ownerWechatId, // 通过群主微信ID筛选
|
||||
'isDeleted' => false,
|
||||
'pageIndex' => 0,
|
||||
'pageSize' => 5 // 获取足够多的数据
|
||||
];
|
||||
// 调用getlist方法同步数据(内部调用,isInner=true)
|
||||
$chatroomController->getlist($syncData, true, 0);
|
||||
} catch (\Exception $e) {
|
||||
Log::warning("同步群组信息失败: " . $e->getMessage());
|
||||
// 即使同步失败,也继续查询本地数据
|
||||
}
|
||||
|
||||
// 2. 查询本地表 s2_wechat_chatroom
|
||||
// 计算5分钟前的时间戳
|
||||
$fiveMinutesAgo = time() - 300; // 5分钟 = 300秒
|
||||
$now = time();
|
||||
|
||||
// 查询群聊:通过群名称、账号ID或微信账号ID和创建时间查询
|
||||
// 如果accountId不为空,优先使用accountId查询;如果accountId为空,则使用wechatAccountWechatId查询
|
||||
$chatroom = Db::table('s2_wechat_chatroom')
|
||||
->where('nickname', $chatroomName)
|
||||
->where('isDeleted', 0)
|
||||
->where('createTime', '>=', $fiveMinutesAgo) // 创建时间在5分钟内
|
||||
->where('createTime', '<=', $now)
|
||||
->where('wechatAccountWechatId', $wechatAccountWechatId)
|
||||
->order('createTime', 'desc')
|
||||
->find();
|
||||
|
||||
|
||||
// 如果找到了群聊,返回群ID和chatroomId
|
||||
if ($chatroom && !empty($chatroom['id'])) {
|
||||
$chatroomId = !empty($chatroom['chatroomId']) ? (string)$chatroom['chatroomId'] : null;
|
||||
// 如果有chatroomId,尝试查询wechat_group表获取groupId
|
||||
$groupId = $chatroom['id'];
|
||||
Log::info("轮询检查群创建成功。群名称: {$chatroomName}, 群聊ID: {$chatroom['id']}, chatroomId: {$chatroomId}, 群组ID: {$groupId}, 尝试次数: {$attempt}");
|
||||
return [
|
||||
'groupId' => $groupId > 0 ? $groupId : intval($chatroom['id']), // 如果没有groupId,使用chatroom的id
|
||||
'chatroomId' => $chatroomId ?: (string)$chatroom['id']
|
||||
];
|
||||
}
|
||||
|
||||
Log::debug("轮询检查群创建中。群名称: {$chatroomName}, 尝试次数: {$attempt}/{$maxAttempts}");
|
||||
}
|
||||
|
||||
// 10次查询后仍未找到,返回0表示失败
|
||||
Log::warning("轮询检查群创建失败,已查询{$maxAttempts}次仍未找到群组。群名称: {$chatroomName}, 群主微信ID: {$ownerWechatId}, 账号ID: {$accountId}");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否在时间范围内
|
||||
* @param array $config 配置
|
||||
* @return bool
|
||||
*/
|
||||
protected function isWithinTimeRange($config)
|
||||
{
|
||||
if (empty($config['startTime']) || empty($config['endTime'])) {
|
||||
return true; // 如果没有配置时间,则允许执行
|
||||
}
|
||||
|
||||
$today = date('Y-m-d');
|
||||
$startTimestamp = strtotime($today . ' ' . $config['startTime'] . ':00');
|
||||
$endTimestamp = strtotime($today . ' ' . $config['endTime'] . ':00');
|
||||
|
||||
// 如果时间不符,则跳过
|
||||
if ($startTimestamp > time() || $endTimestamp < time() || empty($groupIds)) {
|
||||
$currentTime = time();
|
||||
|
||||
// 如果开始时间大于当前时间,还未到执行时间
|
||||
if ($startTimestamp > $currentTime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 查询今日建群数量
|
||||
$count = Db::name('wechat_group')
|
||||
->whereIn('id', $groupIds)
|
||||
->whereTime('createTime', 'between', [$startTimestamp, $endTimestamp])
|
||||
->count();
|
||||
if ($count >= $config['maxGroupsPerDay']) {
|
||||
|
||||
// 如果结束时间小于当前时间,已过执行时间
|
||||
if ($endTimestamp < $currentTime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查每日建群数量限制
|
||||
* @param int $workbenchId 工作台ID
|
||||
* @param array $config 配置
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkDailyLimit($workbenchId, $config)
|
||||
{
|
||||
if (empty($config['maxGroupsPerDay']) || $config['maxGroupsPerDay'] <= 0) {
|
||||
return true; // 如果没有配置限制,则允许执行
|
||||
}
|
||||
|
||||
$today = date('Y-m-d');
|
||||
$startTimestamp = strtotime($today . ' 00:00:00');
|
||||
$endTimestamp = strtotime($today . ' 23:59:59');
|
||||
|
||||
// 查询今日已创建的群数量(状态为成功)
|
||||
$todayCount = Db::name('workbench_group_create_item')
|
||||
->where('workbenchId', $workbenchId)
|
||||
->where('status', self::STATUS_SUCCESS)
|
||||
->where('groupId', '<>', null) // 排除groupId为NULL的记录
|
||||
->where('createTime', 'between', [$startTimestamp, $endTimestamp])
|
||||
->group('groupId')
|
||||
->count();
|
||||
|
||||
return $todayCount < $config['maxGroupsPerDay'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 从指定的微信群组中获取成员
|
||||
* @param array $wechatGroups 群组ID数组(可能是好友ID或群组ID)
|
||||
* @param array $groupMember 群主成员微信ID数组(引用传递)
|
||||
* @param array $groupMemberId 群主成员好友ID数组(引用传递)
|
||||
* @param array $groupMemberWechatId 群主成员微信ID映射(引用传递)
|
||||
*/
|
||||
protected function addGroupMembersFromWechatGroups($wechatGroups, &$groupMember, &$groupMemberId, &$groupMemberWechatId)
|
||||
{
|
||||
foreach ($wechatGroups as $groupId) {
|
||||
if (is_numeric($groupId)) {
|
||||
// 数字ID:可能是好友ID,查询好友信息
|
||||
$friend = Db::table('s2_wechat_friend')
|
||||
->where('id', $groupId)
|
||||
->where('isDeleted', 0)
|
||||
->field('id,wechatId,ownerWechatId')
|
||||
->find();
|
||||
|
||||
if ($friend) {
|
||||
// 添加到群主成员
|
||||
if (!in_array($friend['ownerWechatId'], $groupMember)) {
|
||||
$groupMember[] = $friend['ownerWechatId'];
|
||||
}
|
||||
|
||||
if (!isset($groupMemberWechatId[$friend['id']])) {
|
||||
$groupMemberWechatId[$friend['id']] = $friend['wechatId'];
|
||||
$groupMemberId[] = $friend['id'];
|
||||
}
|
||||
} else {
|
||||
// 如果不是好友ID,可能是群组ID,查询群组信息
|
||||
$group = Db::name('wechat_group')
|
||||
->where('id', $groupId)
|
||||
->where('deleteTime', 0)
|
||||
->field('ownerWechatId')
|
||||
->find();
|
||||
|
||||
if ($group && !in_array($group['ownerWechatId'], $groupMember)) {
|
||||
$groupMember[] = $group['ownerWechatId'];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 字符串ID:手动创建的群组,可能是wechatId
|
||||
if (!in_array($groupId, $groupMember)) {
|
||||
$groupMember[] = $groupId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 记录任务开始
|
||||
@@ -510,4 +848,5 @@ class WorkbenchGroupCreateJob
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user