2025-04-10 16:40:30 +08:00
< ? php
namespace app\cunkebao\controller ;
2025-07-06 00:17:24 +08:00
use app\common\model\Device as DeviceModel ;
use app\common\model\DeviceWechatLogin as DeviceWechatLoginModel ;
2025-08-15 15:37:00 +08:00
use app\common\model\WechatCustomer as WechatCustomerModel ;
2025-04-10 16:40:30 +08:00
use app\cunkebao\model\Workbench ;
use app\cunkebao\model\WorkbenchAutoLike ;
2025-09-10 11:43:47 +08:00
use app\cunkebao\model\WorkbenchImportContact ;
2025-04-10 16:40:30 +08:00
use app\cunkebao\model\WorkbenchMomentsSync ;
use app\cunkebao\model\WorkbenchGroupPush ;
use app\cunkebao\model\WorkbenchGroupCreate ;
use app\cunkebao\validate\Workbench as WorkbenchValidate ;
use think\Controller ;
use think\Db ;
2025-05-26 17:56:12 +08:00
use app\cunkebao\model\WorkbenchTrafficConfig ;
2025-06-06 14:45:06 +08:00
use app\cunkebao\model\ContentLibrary ;
2025-09-02 11:24:23 +08:00
use think\facade\Env ;
2025-04-10 16:40:30 +08:00
/**
* 工作台控制器
*/
class WorkbenchController extends Controller
{
/**
* 工作台类型定义
*/
const TYPE_AUTO_LIKE = 1 ; // 自动点赞
const TYPE_MOMENTS_SYNC = 2 ; // 朋友圈同步
const TYPE_GROUP_PUSH = 3 ; // 群消息推送
const TYPE_GROUP_CREATE = 4 ; // 自动建群
2025-05-26 17:56:12 +08:00
const TYPE_TRAFFIC_DISTRIBUTION = 5 ; // 流量分发
2025-09-10 11:43:47 +08:00
const TYPE_IMPORT_CONTACT = 6 ; // 联系人导入
2025-04-10 16:40:30 +08:00
/**
* 创建工作台
* @ return \think\response\Json
*/
public function create ()
{
if ( ! $this -> request -> isPost ()) {
return json ([ 'code' => 400 , 'msg' => '请求方式错误' ]);
}
// 获取登录用户信息
$userInfo = request () -> userInfo ;
// 获取请求参数
$param = $this -> request -> post ();
2025-11-13 16:10:47 +08:00
// 根据业务默认值补全参数
if (
isset ( $param [ 'type' ]) &&
intval ( $param [ 'type' ]) === self :: TYPE_GROUP_PUSH
) {
if ( empty ( $param [ 'startTime' ])) {
$param [ 'startTime' ] = '09:00' ;
}
if ( empty ( $param [ 'endTime' ])) {
$param [ 'endTime' ] = '21:00' ;
}
}
2025-04-10 16:40:30 +08:00
// 验证数据
$validate = new WorkbenchValidate ;
if ( ! $validate -> scene ( 'create' ) -> check ( $param )) {
return json ([ 'code' => 400 , 'msg' => $validate -> getError ()]);
}
Db :: startTrans ();
try {
// 创建工作台基本信息
$workbench = new Workbench ;
$workbench -> name = $param [ 'name' ];
$workbench -> type = $param [ 'type' ];
2025-08-22 10:23:05 +08:00
$workbench -> status = ! empty ( $param [ 'status' ]) ? 1 : 0 ;
2025-04-10 16:40:30 +08:00
$workbench -> autoStart = ! empty ( $param [ 'autoStart' ]) ? 1 : 0 ;
$workbench -> userId = $userInfo [ 'id' ];
$workbench -> companyId = $userInfo [ 'companyId' ];
$workbench -> createTime = time ();
$workbench -> updateTime = time ();
$workbench -> save ();
// 根据类型创建对应的配置
switch ( $param [ 'type' ]) {
case self :: TYPE_AUTO_LIKE : // 自动点赞
$config = new WorkbenchAutoLike ;
$config -> workbenchId = $workbench -> id ;
$config -> interval = $param [ 'interval' ];
$config -> maxLikes = $param [ 'maxLikes' ];
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> contentTypes = json_encode ( $param [ 'contentTypes' ]);
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ]);
2025-08-12 09:28:57 +08:00
$config -> friends = json_encode ( $param [ 'friendsGroups' ]);
2025-05-09 09:22:31 +08:00
// $config->targetGroups = json_encode($param['targetGroups']);
// $config->tagOperator = $param['tagOperator'];
2025-05-16 09:43:04 +08:00
$config -> friendMaxLikes = $param [ 'friendMaxLikes' ];
$config -> friendTags = $param [ 'friendTags' ];
$config -> enableFriendTags = $param [ 'enableFriendTags' ];
2025-04-10 16:40:30 +08:00
$config -> createTime = time ();
$config -> updateTime = time ();
$config -> save ();
break ;
case self :: TYPE_MOMENTS_SYNC : // 朋友圈同步
$config = new WorkbenchMomentsSync ;
$config -> workbenchId = $workbench -> id ;
$config -> syncInterval = $param [ 'syncInterval' ];
$config -> syncCount = $param [ 'syncCount' ];
$config -> syncType = $param [ 'syncType' ];
2025-04-11 16:15:48 +08:00
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> accountType = $param [ 'accountType' ];
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ]);
2025-08-12 09:28:57 +08:00
$config -> contentLibraries = json_encode ( $param [ 'contentGroups' ] ? ? []);
2025-04-10 16:40:30 +08:00
$config -> createTime = time ();
$config -> updateTime = time ();
$config -> save ();
break ;
case self :: TYPE_GROUP_PUSH : // 群消息推送
2025-11-13 16:10:47 +08:00
$ownerWechatIds = $this -> normalizeOwnerWechatIds ( $param [ 'ownerWechatIds' ] ? ? []);
$groupPushData = $this -> prepareGroupPushData ( $param , $ownerWechatIds );
$groupPushData [ 'workbenchId' ] = $workbench -> id ;
$groupPushData [ 'createTime' ] = time ();
$groupPushData [ 'updateTime' ] = time ();
2025-04-10 16:40:30 +08:00
$config = new WorkbenchGroupPush ;
2025-11-13 16:10:47 +08:00
$config -> save ( $groupPushData );
2025-04-10 16:40:30 +08:00
break ;
case self :: TYPE_GROUP_CREATE : // 自动建群
$config = new WorkbenchGroupCreate ;
$config -> workbenchId = $workbench -> id ;
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ], JSON_UNESCAPED_UNICODE );
2025-08-20 17:35:34 +08:00
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> groupSizeMin = $param [ 'groupSizeMin' ];
$config -> groupSizeMax = $param [ 'groupSizeMax' ];
$config -> maxGroupsPerDay = $param [ 'maxGroupsPerDay' ];
$config -> groupNameTemplate = $param [ 'groupNameTemplate' ];
$config -> groupDescription = $param [ 'groupDescription' ];
2025-08-22 10:23:05 +08:00
$config -> poolGroups = json_encode ( $param [ 'poolGroups' ] ? ? []);
$config -> wechatGroups = json_encode ( $param [ 'wechatGroups' ] ? ? []);
2025-04-10 16:40:30 +08:00
$config -> createTime = time ();
$config -> updateTime = time ();
$config -> save ();
break ;
2025-05-26 17:56:12 +08:00
case self :: TYPE_TRAFFIC_DISTRIBUTION : // 流量分发
$config = new WorkbenchTrafficConfig ;
$config -> workbenchId = $workbench -> id ;
$config -> distributeType = $param [ 'distributeType' ];
$config -> maxPerDay = $param [ 'maxPerDay' ];
$config -> timeType = $param [ 'timeType' ];
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ], JSON_UNESCAPED_UNICODE );
2025-09-22 18:03:45 +08:00
$config -> pools = json_encode ( $param [ 'poolGroups' ], JSON_UNESCAPED_UNICODE );
2025-08-12 09:28:57 +08:00
$config -> account = json_encode ( $param [ 'accountGroups' ], JSON_UNESCAPED_UNICODE );
2025-05-26 17:56:12 +08:00
$config -> createTime = time ();
$config -> updateTime = time ();
$config -> save ();
break ;
2025-09-10 11:43:47 +08:00
case self :: TYPE_IMPORT_CONTACT : //联系人导入
$config = new WorkbenchImportContact ;
$config -> workbenchId = $workbench -> id ;
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ], JSON_UNESCAPED_UNICODE );
2025-09-22 18:03:45 +08:00
$config -> pools = json_encode ( $param [ 'poolGroups' ], JSON_UNESCAPED_UNICODE );
2025-09-10 11:43:47 +08:00
$config -> num = $param [ 'num' ];
$config -> clearContact = $param [ 'clearContact' ];
$config -> remark = $param [ 'remark' ];
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> createTime = time ();
$config -> save ();
break ;
2025-04-10 16:40:30 +08:00
}
Db :: commit ();
return json ([ 'code' => 200 , 'msg' => '创建成功' , 'data' => [ 'id' => $workbench -> id ]]);
} catch ( \Exception $e ) {
Db :: rollback ();
return json ([ 'code' => 500 , 'msg' => '创建失败:' . $e -> getMessage ()]);
}
}
/**
* 获取工作台列表
* @ return \think\response\Json
*/
public function getList ()
{
$page = $this -> request -> param ( 'page' , 1 );
$limit = $this -> request -> param ( 'limit' , 10 );
$type = $this -> request -> param ( 'type' , '' );
2025-06-06 14:45:06 +08:00
$keyword = $this -> request -> param ( 'keyword' , '' );
2025-04-10 16:40:30 +08:00
$where = [
2025-11-17 17:34:46 +08:00
[ 'companyId' , '=' , $this -> request -> userInfo [ 'companyId' ]],
2025-04-10 16:40:30 +08:00
[ 'isDel' , '=' , 0 ]
];
2025-08-12 09:28:57 +08:00
2025-11-17 17:34:46 +08:00
if ( empty ( $this -> request -> userInfo [ 'isAdmin' ])) {
$where [] = [ 'userId' , '=' , $this -> request -> userInfo [ 'id' ]];
}
2025-04-10 16:40:30 +08:00
// 添加类型筛选
if ( $type !== '' ) {
$where [] = [ 'type' , '=' , $type ];
}
2025-08-12 09:28:57 +08:00
2025-04-10 16:40:30 +08:00
// 添加名称模糊搜索
if ( $keyword !== '' ) {
$where [] = [ 'name' , 'like' , '%' . $keyword . '%' ];
}
// 定义关联关系
$with = [
2025-08-12 09:28:57 +08:00
'autoLike' => function ( $query ) {
2025-05-09 09:22:31 +08:00
$query -> field ( 'workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,friends' );
2025-04-10 16:40:30 +08:00
},
2025-08-12 09:28:57 +08:00
'momentsSync' => function ( $query ) {
2025-04-11 16:15:48 +08:00
$query -> field ( 'workbenchId,syncInterval,syncCount,syncType,startTime,endTime,accountType,devices,contentLibraries' );
},
2025-08-12 09:28:57 +08:00
'trafficConfig' => function ( $query ) {
2025-06-07 17:34:20 +08:00
$query -> field ( 'workbenchId,distributeType,maxPerDay,timeType,startTime,endTime,devices,pools,account' );
2025-05-26 17:56:12 +08:00
},
2025-08-12 09:28:57 +08:00
'groupPush' => function ( $query ) {
2025-11-13 16:10:47 +08:00
$query -> field ( 'workbenchId,pushType,targetType,groupPushSubType,startTime,endTime,maxPerDay,pushOrder,isLoop,status,groups,friends,ownerWechatIds,trafficPools,contentLibraries,friendIntervalMin,friendIntervalMax,messageIntervalMin,messageIntervalMax,isRandomTemplate,postPushTags,announcementContent,enableAiRewrite,aiRewritePrompt' );
2025-06-06 14:45:06 +08:00
},
2025-11-13 16:10:47 +08:00
'groupCreate' => function ( $query ) {
2025-08-22 10:23:05 +08:00
$query -> field ( 'workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription,poolGroups,wechatGroups' );
2025-08-20 17:35:34 +08:00
},
2025-11-13 16:10:47 +08:00
'importContact' => function ( $query ) {
2025-09-10 11:43:47 +08:00
$query -> field ( 'workbenchId,devices,pools,num,remarkType,remark,clearContact,startTime,endTime' );
},
2025-08-12 09:28:57 +08:00
'user' => function ( $query ) {
2025-04-17 09:46:47 +08:00
$query -> field ( 'id,username' );
}
2025-04-10 16:40:30 +08:00
];
$list = Workbench :: where ( $where )
-> with ( $with )
2025-06-04 11:38:43 +08:00
-> field ( 'id,companyId,name,type,status,autoStart,userId,createTime,updateTime' )
2025-04-10 16:40:30 +08:00
-> order ( 'id' , 'desc' )
-> page ( $page , $limit )
-> select ()
-> each ( function ( $item ) {
// 处理配置信息
switch ( $item -> type ) {
case self :: TYPE_AUTO_LIKE :
if ( ! empty ( $item -> autoLike )) {
$item -> config = $item -> autoLike ;
$item -> config -> devices = json_decode ( $item -> config -> devices , true );
2025-08-12 09:28:57 +08:00
$item -> config -> contentTypes = json_decode ( $item -> config -> contentTypes , true );
2025-05-09 09:22:31 +08:00
$item -> config -> friends = json_decode ( $item -> config -> friends , true );
2025-08-12 09:28:57 +08:00
2025-05-14 17:28:05 +08:00
// 添加今日点赞数
$startTime = strtotime ( date ( 'Y-m-d' ) . ' 00:00:00' );
$endTime = strtotime ( date ( 'Y-m-d' ) . ' 23:59:59' );
$todayLikeCount = Db :: name ( 'workbench_auto_like_item' )
-> where ( 'workbenchId' , $item -> id )
-> whereTime ( 'createTime' , 'between' , [ $startTime , $endTime ])
-> count ();
2025-08-12 09:28:57 +08:00
2025-05-14 17:28:05 +08:00
// 添加总点赞数
$totalLikeCount = Db :: name ( 'workbench_auto_like_item' )
-> where ( 'workbenchId' , $item -> id )
-> count ();
2025-08-12 09:28:57 +08:00
2025-05-14 17:28:05 +08:00
$item -> config -> todayLikeCount = $todayLikeCount ;
$item -> config -> totalLikeCount = $totalLikeCount ;
2025-04-10 16:40:30 +08:00
}
2025-08-12 09:28:57 +08:00
unset ( $item -> autoLike , $item -> auto_like );
2025-04-10 16:40:30 +08:00
break ;
case self :: TYPE_MOMENTS_SYNC :
if ( ! empty ( $item -> momentsSync )) {
$item -> config = $item -> momentsSync ;
$item -> config -> devices = json_decode ( $item -> config -> devices , true );
2025-08-29 09:51:00 +08:00
$item -> config -> contentGroups = json_decode ( $item -> config -> contentLibraries , true );
2025-07-06 00:17:24 +08:00
//同步记录
$sendNum = Db :: name ( 'workbench_moments_sync_item' ) -> where ([ 'workbenchId' => $item -> id ]) -> count ();
$item -> syncCount = $sendNum ;
$lastTime = Db :: name ( 'workbench_moments_sync_item' ) -> where ([ 'workbenchId' => $item -> id ]) -> order ( 'id DESC' ) -> value ( 'createTime' );
2025-08-12 09:28:57 +08:00
$item -> lastSyncTime = ! empty ( $lastTime ) ? date ( 'Y-m-d H:i' , $lastTime ) : '--' ;
2025-07-06 00:17:24 +08:00
2025-07-11 11:09:48 +08:00
2025-04-17 09:46:47 +08:00
// 获取内容库名称
2025-08-29 09:51:00 +08:00
if ( ! empty ( $item -> config -> contentGroups )) {
$libraryNames = ContentLibrary :: where ( 'id' , 'in' , $item -> config -> contentGroups ) -> select ();
$item -> config -> contentGroupsOptions = $libraryNames ;
2025-04-17 09:46:47 +08:00
} else {
2025-08-29 09:51:00 +08:00
$item -> config -> contentGroupsOptions = [];
2025-04-17 09:46:47 +08:00
}
2025-04-10 16:40:30 +08:00
}
2025-11-13 16:10:47 +08:00
unset ( $item -> momentsSync , $item -> moments_sync , $item -> config -> contentLibraries );
2025-04-10 16:40:30 +08:00
break ;
case self :: TYPE_GROUP_PUSH :
if ( ! empty ( $item -> groupPush )) {
$item -> config = $item -> groupPush ;
2025-06-06 14:45:06 +08:00
$item -> config -> pushType = $item -> config -> pushType ;
2025-11-07 15:25:50 +08:00
$item -> config -> targetType = isset ( $item -> config -> targetType ) ? intval ( $item -> config -> targetType ) : 1 ; // 默认1=群推送
2025-11-13 16:10:47 +08:00
$item -> config -> groupPushSubType = isset ( $item -> config -> groupPushSubType ) ? intval ( $item -> config -> groupPushSubType ) : 1 ; // 默认1=群群发
2025-06-06 14:45:06 +08:00
$item -> config -> startTime = $item -> config -> startTime ;
$item -> config -> endTime = $item -> config -> endTime ;
$item -> config -> maxPerDay = $item -> config -> maxPerDay ;
$item -> config -> pushOrder = $item -> config -> pushOrder ;
$item -> config -> isLoop = $item -> config -> isLoop ;
$item -> config -> status = $item -> config -> status ;
2025-11-13 16:10:47 +08:00
$item -> config -> ownerWechatIds = json_decode ( $item -> config -> ownerWechatIds ? ? '[]' , true ) ? : [];
2025-11-07 15:25:50 +08:00
// 根据targetType解析不同的数据
if ( $item -> config -> targetType == 1 ) {
// 群推送
$item -> config -> wechatGroups = json_decode ( $item -> config -> groups , true ) ? : [];
$item -> config -> wechatFriends = [];
2025-11-13 16:10:47 +08:00
// 群推送不需要devices字段
// 群公告相关字段
if ( $item -> config -> groupPushSubType == 2 ) {
$item -> config -> announcementContent = isset ( $item -> config -> announcementContent ) ? $item -> config -> announcementContent : '' ;
$item -> config -> enableAiRewrite = isset ( $item -> config -> enableAiRewrite ) ? intval ( $item -> config -> enableAiRewrite ) : 0 ;
$item -> config -> aiRewritePrompt = isset ( $item -> config -> aiRewritePrompt ) ? $item -> config -> aiRewritePrompt : '' ;
}
$item -> config -> trafficPools = [];
2025-11-07 15:25:50 +08:00
} else {
// 好友推送
$item -> config -> wechatFriends = json_decode ( $item -> config -> friends , true ) ? : [];
$item -> config -> wechatGroups = [];
2025-11-13 16:10:47 +08:00
$item -> config -> trafficPools = json_decode ( $item -> config -> trafficPools ? ? '[]' , true ) ? : [];
2025-11-07 15:25:50 +08:00
}
2025-06-06 14:45:06 +08:00
$item -> config -> contentLibraries = json_decode ( $item -> config -> contentLibraries , true );
2025-11-13 16:10:47 +08:00
$item -> config -> postPushTags = json_decode ( $item -> config -> postPushTags ? ? '[]' , true ) ? : [];
2025-08-22 10:23:05 +08:00
$item -> config -> lastPushTime = '' ;
2025-11-13 16:10:47 +08:00
if ( ! empty ( $item -> config -> ownerWechatIds )) {
$ownerWechatOptions = Db :: name ( 'wechat_account' )
-> whereIn ( 'id' , $item -> config -> ownerWechatIds )
-> field ( 'id,wechatId,nickName,avatar,alias' )
-> select ();
$item -> config -> ownerWechatOptions = $ownerWechatOptions ;
} else {
$item -> config -> ownerWechatOptions = [];
}
2025-04-10 16:40:30 +08:00
}
2025-08-12 09:28:57 +08:00
unset ( $item -> groupPush , $item -> group_push );
2025-04-10 16:40:30 +08:00
break ;
case self :: TYPE_GROUP_CREATE :
if ( ! empty ( $item -> groupCreate )) {
$item -> config = $item -> groupCreate ;
$item -> config -> devices = json_decode ( $item -> config -> devices , true );
2025-08-22 10:23:05 +08:00
$item -> config -> poolGroups = json_decode ( $item -> config -> poolGroups , true );
$item -> config -> wechatGroups = json_decode ( $item -> config -> wechatGroups , true );
2025-04-10 16:40:30 +08:00
}
2025-08-12 09:28:57 +08:00
unset ( $item -> groupCreate , $item -> group_create );
2025-04-10 16:40:30 +08:00
break ;
2025-05-26 17:56:12 +08:00
case self :: TYPE_TRAFFIC_DISTRIBUTION :
if ( ! empty ( $item -> trafficConfig )) {
$item -> config = $item -> trafficConfig ;
$item -> config -> devices = json_decode ( $item -> config -> devices , true );
2025-09-22 18:03:45 +08:00
$item -> config -> poolGroups = json_decode ( $item -> config -> pools , true );
2025-06-07 17:34:20 +08:00
$item -> config -> account = json_decode ( $item -> config -> account , true );
2025-06-04 11:38:43 +08:00
$config_item = Db :: name ( 'workbench_traffic_config_item' ) -> where ([ 'workbenchId' => $item -> id ]) -> order ( 'id DESC' ) -> find ();
2025-08-12 09:28:57 +08:00
$item -> config -> lastUpdated = ! empty ( $config_item ) ? date ( 'Y-m-d H:i' , $config_item [ 'createTime' ]) : '--' ;
2025-06-04 11:38:43 +08:00
//统计
2025-09-22 18:03:45 +08:00
$labels = $item -> config -> poolGroups ;
2025-06-04 11:38:43 +08:00
$totalUsers = Db :: table ( 's2_wechat_friend' ) -> alias ( 'wf' )
-> join ([ 's2_company_account' => 'sa' ], 'sa.id = wf.accountId' , 'left' )
-> join ([ 's2_wechat_account' => 'wa' ], 'wa.id = wf.wechatAccountId' , 'left' )
-> where ([
[ 'wf.isDeleted' , '=' , 0 ],
[ 'sa.departmentId' , '=' , $item -> companyId ]
])
2025-06-11 15:31:46 +08:00
-> whereIn ( 'wa.currentDeviceId' , $item -> config -> devices );
2025-08-12 09:28:57 +08:00
if ( ! empty ( $labels ) && count ( $labels ) > 0 ) {
2025-06-11 15:31:46 +08:00
$totalUsers = $totalUsers -> where ( function ( $q ) use ( $labels ) {
foreach ( $labels as $label ) {
$q -> whereOrRaw ( " JSON_CONTAINS(wf.labels, ' \" { $label } \" ') " );
}
});
}
$totalUsers = $totalUsers -> count ();
2025-06-07 17:34:20 +08:00
$totalAccounts = count ( $item -> config -> account );
2025-06-04 11:38:43 +08:00
$dailyAverage = Db :: name ( 'workbench_traffic_config_item' )
2025-08-12 09:28:57 +08:00
-> where ( 'workbenchId' , $item -> id )
-> count ();
2025-06-06 14:45:06 +08:00
$day = ( time () - strtotime ( $item -> createTime )) / 86400 ;
$day = intval ( $day );
2025-08-12 09:28:57 +08:00
if ( $dailyAverage > 0 && $totalAccounts > 0 && $day > 0 ) {
2025-06-06 14:45:06 +08:00
$dailyAverage = $dailyAverage / $totalAccounts / $day ;
2025-06-04 11:38:43 +08:00
}
2025-05-28 15:45:08 +08:00
$item -> config -> total = [
2025-06-04 11:38:43 +08:00
'dailyAverage' => intval ( $dailyAverage ),
'totalAccounts' => $totalAccounts ,
2025-05-28 15:45:08 +08:00
'deviceCount' => count ( $item -> config -> devices ),
2025-09-22 18:03:45 +08:00
'poolCount' => ! empty ( $item -> config -> poolGroups ) ? count ( $item -> config -> poolGroups ) : 'ALL' ,
2025-06-04 11:38:43 +08:00
'totalUsers' => $totalUsers >> 0
2025-05-28 15:45:08 +08:00
];
2025-05-26 17:56:12 +08:00
}
2025-08-12 09:28:57 +08:00
unset ( $item -> trafficConfig , $item -> traffic_config );
2025-05-26 17:56:12 +08:00
break ;
2025-09-10 11:43:47 +08:00
case self :: TYPE_IMPORT_CONTACT :
if ( ! empty ( $item -> importContact )) {
$item -> config = $item -> importContact ;
$item -> config -> devices = json_decode ( $item -> config -> devices , true );
2025-09-22 18:03:45 +08:00
$item -> config -> poolGroups = json_decode ( $item -> config -> pools , true );
2025-09-10 11:43:47 +08:00
}
unset ( $item -> importContact , $item -> import_contact );
break ;
2025-04-10 16:40:30 +08:00
}
2025-04-17 09:46:47 +08:00
// 添加创建人名称
$item [ 'creatorName' ] = $item -> user ? $item -> user -> username : '' ;
unset ( $item [ 'user' ]); // 移除关联数据
2025-04-10 16:40:30 +08:00
return $item ;
});
$total = Workbench :: where ( $where ) -> count ();
return json ([
'code' => 200 ,
'msg' => '获取成功' ,
'data' => [
'list' => $list ,
'total' => $total ,
'page' => $page ,
'limit' => $limit
]
]);
}
/**
* 获取工作台详情
* @ param int $id 工作台ID
* @ return \think\response\Json
*/
2025-04-11 16:15:48 +08:00
public function detail ()
2025-04-10 16:40:30 +08:00
{
2025-04-11 16:15:48 +08:00
$id = $this -> request -> param ( 'id' , '' );
2025-04-10 16:40:30 +08:00
if ( empty ( $id )) {
return json ([ 'code' => 400 , 'msg' => '参数错误' ]);
}
// 定义关联关系
$with = [
2025-08-12 09:28:57 +08:00
'autoLike' => function ( $query ) {
2025-05-16 09:43:04 +08:00
$query -> field ( 'workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,friends,friendMaxLikes,friendTags,enableFriendTags' );
2025-04-10 16:40:30 +08:00
},
2025-08-12 09:28:57 +08:00
'momentsSync' => function ( $query ) {
2025-04-11 16:15:48 +08:00
$query -> field ( 'workbenchId,syncInterval,syncCount,syncType,startTime,endTime,accountType,devices,contentLibraries' );
2025-04-10 16:40:30 +08:00
},
2025-08-12 09:28:57 +08:00
'trafficConfig' => function ( $query ) {
2025-06-07 17:34:20 +08:00
$query -> field ( 'workbenchId,distributeType,maxPerDay,timeType,startTime,endTime,devices,pools,account' );
2025-05-28 15:45:08 +08:00
},
2025-08-12 09:28:57 +08:00
'groupPush' => function ( $query ) {
2025-11-13 16:10:47 +08:00
$query -> field ( 'workbenchId,pushType,targetType,groupPushSubType,startTime,endTime,maxPerDay,pushOrder,isLoop,status,groups,friends,ownerWechatIds,trafficPools,contentLibraries,friendIntervalMin,friendIntervalMax,messageIntervalMin,messageIntervalMax,isRandomTemplate,postPushTags,announcementContent,enableAiRewrite,aiRewritePrompt' );
},
'groupCreate' => function ( $query ) {
$query -> field ( 'workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription,poolGroups,wechatGroups' );
2025-06-06 14:45:06 +08:00
},
2025-11-13 16:10:47 +08:00
'importContact' => function ( $query ) {
2025-09-10 11:43:47 +08:00
$query -> field ( 'workbenchId,devices,pools,num,remarkType,remark,clearContact,startTime,endTime' );
},
2025-04-10 16:40:30 +08:00
];
2025-11-17 17:34:46 +08:00
$where = [
2025-04-10 16:40:30 +08:00
[ 'id' , '=' , $id ],
2025-11-17 17:34:46 +08:00
[ 'companyId' , '=' , $this -> request -> userInfo [ 'companyId' ]],
2025-04-10 16:40:30 +08:00
[ 'isDel' , '=' , 0 ]
2025-11-17 17:34:46 +08:00
];
if ( empty ( $this -> request -> userInfo [ 'isAdmin' ])) {
$where [] = [ 'userId' , '=' , $this -> request -> userInfo [ 'id' ]];
}
$workbench = Workbench :: where ( $where )
2025-08-12 09:28:57 +08:00
-> field ( 'id,name,type,status,autoStart,createTime,updateTime,companyId' )
-> with ( $with )
-> find ();
2025-04-10 16:40:30 +08:00
if ( empty ( $workbench )) {
return json ([ 'code' => 404 , 'msg' => '工作台不存在' ]);
}
// 处理配置信息
switch ( $workbench -> type ) {
2025-08-12 09:28:57 +08:00
//自动点赞
2025-04-10 16:40:30 +08:00
case self :: TYPE_AUTO_LIKE :
if ( ! empty ( $workbench -> autoLike )) {
$workbench -> config = $workbench -> autoLike ;
2025-09-11 15:16:04 +08:00
$workbench -> config -> deviceGroups = json_decode ( $workbench -> config -> devices , true );
2025-08-12 09:28:57 +08:00
$workbench -> config -> friendsGroups = json_decode ( $workbench -> config -> friends , true );
2025-05-09 09:22:31 +08:00
//$workbench->config->targetGroups = json_decode($workbench->config->targetGroups, true);
2025-04-11 16:15:48 +08:00
$workbench -> config -> contentTypes = json_decode ( $workbench -> config -> contentTypes , true );
2025-08-12 09:28:57 +08:00
2025-05-14 17:28:05 +08:00
// 添加今日点赞数
$startTime = strtotime ( date ( 'Y-m-d' ) . ' 00:00:00' );
$endTime = strtotime ( date ( 'Y-m-d' ) . ' 23:59:59' );
$todayLikeCount = Db :: name ( 'workbench_auto_like_item' )
-> where ( 'workbenchId' , $workbench -> id )
-> whereTime ( 'createTime' , 'between' , [ $startTime , $endTime ])
-> count ();
2025-08-12 09:28:57 +08:00
2025-05-14 17:28:05 +08:00
// 添加总点赞数
$totalLikeCount = Db :: name ( 'workbench_auto_like_item' )
-> where ( 'workbenchId' , $workbench -> id )
-> count ();
2025-08-12 09:28:57 +08:00
2025-05-14 17:28:05 +08:00
$workbench -> config -> todayLikeCount = $todayLikeCount ;
$workbench -> config -> totalLikeCount = $totalLikeCount ;
2025-08-12 09:28:57 +08:00
unset ( $workbench -> autoLike , $workbench -> auto_like );
2025-04-10 16:40:30 +08:00
}
break ;
2025-08-12 09:28:57 +08:00
//自动同步朋友圈
2025-04-10 16:40:30 +08:00
case self :: TYPE_MOMENTS_SYNC :
if ( ! empty ( $workbench -> momentsSync )) {
$workbench -> config = $workbench -> momentsSync ;
2025-09-11 15:16:04 +08:00
$workbench -> config -> deviceGroups = json_decode ( $workbench -> config -> devices , true );
2025-08-12 09:28:57 +08:00
$workbench -> config -> contentGroups = json_decode ( $workbench -> config -> contentLibraries , true );
2025-07-06 00:17:24 +08:00
//同步记录
$sendNum = Db :: name ( 'workbench_moments_sync_item' ) -> where ([ 'workbenchId' => $workbench -> id ]) -> count ();
$workbench -> syncCount = $sendNum ;
$lastTime = Db :: name ( 'workbench_moments_sync_item' ) -> where ([ 'workbenchId' => $workbench -> id ]) -> order ( 'id DESC' ) -> value ( 'createTime' );
2025-08-12 09:28:57 +08:00
$workbench -> lastSyncTime = ! empty ( $lastTime ) ? date ( 'Y-m-d H:i' , $lastTime ) : '--' ;
unset ( $workbench -> momentsSync , $workbench -> moments_sync );
2025-04-10 16:40:30 +08:00
}
break ;
2025-08-12 09:28:57 +08:00
//群推送
2025-04-10 16:40:30 +08:00
case self :: TYPE_GROUP_PUSH :
if ( ! empty ( $workbench -> groupPush )) {
$workbench -> config = $workbench -> groupPush ;
2025-11-07 15:25:50 +08:00
$workbench -> config -> targetType = isset ( $workbench -> config -> targetType ) ? intval ( $workbench -> config -> targetType ) : 1 ; // 默认1=群推送
2025-11-13 16:10:47 +08:00
$workbench -> config -> groupPushSubType = isset ( $workbench -> config -> groupPushSubType ) ? intval ( $workbench -> config -> groupPushSubType ) : 1 ; // 默认1=群群发
$workbench -> config -> ownerWechatIds = json_decode ( $workbench -> config -> ownerWechatIds ? ? '[]' , true ) ? : [];
2025-11-07 15:25:50 +08:00
// 根据targetType解析不同的数据
if ( $workbench -> config -> targetType == 1 ) {
// 群推送
$workbench -> config -> wechatGroups = json_decode ( $workbench -> config -> groups , true ) ? : [];
$workbench -> config -> wechatFriends = [];
2025-11-13 16:10:47 +08:00
$workbench -> config -> trafficPools = [];
// 群推送不需要devices字段
// 群公告相关字段
if ( $workbench -> config -> groupPushSubType == 2 ) {
$workbench -> config -> announcementContent = isset ( $workbench -> config -> announcementContent ) ? $workbench -> config -> announcementContent : '' ;
$workbench -> config -> enableAiRewrite = isset ( $workbench -> config -> enableAiRewrite ) ? intval ( $workbench -> config -> enableAiRewrite ) : 0 ;
$workbench -> config -> aiRewritePrompt = isset ( $workbench -> config -> aiRewritePrompt ) ? $workbench -> config -> aiRewritePrompt : '' ;
}
2025-11-07 15:25:50 +08:00
} else {
// 好友推送
$workbench -> config -> wechatFriends = json_decode ( $workbench -> config -> friends , true ) ? : [];
$workbench -> config -> wechatGroups = [];
2025-11-13 16:10:47 +08:00
$workbench -> config -> trafficPools = json_decode ( $workbench -> config -> trafficPools ? ? '[]' , true ) ? : [];
2025-11-07 15:25:50 +08:00
}
2025-06-06 14:45:06 +08:00
$workbench -> config -> contentLibraries = json_decode ( $workbench -> config -> contentLibraries , true );
2025-11-13 16:10:47 +08:00
$workbench -> config -> postPushTags = json_decode ( $workbench -> config -> postPushTags ? ? '[]' , true ) ? : [];
2025-06-06 14:45:06 +08:00
unset ( $workbench -> groupPush , $workbench -> group_push );
2025-04-10 16:40:30 +08:00
}
break ;
2025-08-12 09:28:57 +08:00
//建群助手
2025-04-10 16:40:30 +08:00
case self :: TYPE_GROUP_CREATE :
if ( ! empty ( $workbench -> groupCreate )) {
$workbench -> config = $workbench -> groupCreate ;
2025-09-11 15:16:04 +08:00
$workbench -> config -> deviceGroups = json_decode ( $workbench -> config -> devices , true );
2025-08-22 10:23:05 +08:00
$workbench -> config -> poolGroups = json_decode ( $workbench -> config -> poolGroups , true );
$workbench -> config -> wechatGroups = json_decode ( $workbench -> config -> wechatGroups , true );
2025-08-20 17:35:34 +08:00
unset ( $workbench -> groupCreate , $workbench -> group_create );
2025-04-10 16:40:30 +08:00
}
break ;
2025-08-12 09:28:57 +08:00
//流量分发
2025-05-28 15:45:08 +08:00
case self :: TYPE_TRAFFIC_DISTRIBUTION :
if ( ! empty ( $workbench -> trafficConfig )) {
$workbench -> config = $workbench -> trafficConfig ;
2025-09-11 15:16:04 +08:00
$workbench -> config -> deviceGroups = json_decode ( $workbench -> config -> devices , true );
2025-08-12 09:28:57 +08:00
$workbench -> config -> accountGroups = json_decode ( $workbench -> config -> account , true );
2025-09-22 18:03:45 +08:00
$workbench -> config -> poolGroups = json_decode ( $workbench -> config -> pools , true );
2025-06-06 14:45:06 +08:00
$config_item = Db :: name ( 'workbench_traffic_config_item' ) -> where ([ 'workbenchId' => $workbench -> id ]) -> order ( 'id DESC' ) -> find ();
2025-08-12 09:28:57 +08:00
$workbench -> config -> lastUpdated = ! empty ( $config_item ) ? date ( 'Y-m-d H:i' , $config_item [ 'createTime' ]) : '--' ;
2025-06-06 14:45:06 +08:00
//统计
2025-09-22 18:03:45 +08:00
$labels = $workbench -> config -> poolGroups ;
2025-06-06 14:45:06 +08:00
$totalUsers = Db :: table ( 's2_wechat_friend' ) -> alias ( 'wf' )
-> join ([ 's2_company_account' => 'sa' ], 'sa.id = wf.accountId' , 'left' )
-> join ([ 's2_wechat_account' => 'wa' ], 'wa.id = wf.wechatAccountId' , 'left' )
-> where ([
[ 'wf.isDeleted' , '=' , 0 ],
[ 'sa.departmentId' , '=' , $workbench -> companyId ]
])
2025-09-11 15:16:04 +08:00
-> whereIn ( 'wa.currentDeviceId' , $workbench -> config -> deviceGroups )
2025-06-06 14:45:06 +08:00
-> field ( 'wf.id,wf.wechatAccountId,wf.wechatId,wf.labels,sa.userName,wa.currentDeviceId as deviceId' )
-> where ( function ( $q ) use ( $labels ) {
2025-08-12 09:28:57 +08:00
foreach ( $labels as $label ) {
$q -> whereOrRaw ( " JSON_CONTAINS(wf.labels, ' \" { $label } \" ') " );
}
}) -> count ();
2025-06-06 14:45:06 +08:00
$totalAccounts = Db :: table ( 's2_company_account' )
2025-08-12 09:28:57 +08:00
-> alias ( 'a' )
-> where ([ 'a.departmentId' => $workbench -> companyId , 'a.status' => 0 ])
-> whereNotLike ( 'a.userName' , '%_offline%' )
-> whereNotLike ( 'a.userName' , '%_delete%' )
-> group ( 'a.id' )
-> count ();
2025-06-06 14:45:06 +08:00
$dailyAverage = Db :: name ( 'workbench_traffic_config_item' )
2025-08-12 09:28:57 +08:00
-> where ( 'workbenchId' , $workbench -> id )
-> count ();
2025-06-06 14:45:06 +08:00
$day = ( time () - strtotime ( $workbench -> createTime )) / 86400 ;
$day = intval ( $day );
2025-08-12 09:28:57 +08:00
if ( $dailyAverage > 0 ) {
2025-06-06 14:45:06 +08:00
$dailyAverage = $dailyAverage / $totalAccounts / $day ;
}
2025-05-28 15:45:08 +08:00
$workbench -> config -> total = [
2025-06-06 14:45:06 +08:00
'dailyAverage' => intval ( $dailyAverage ),
'totalAccounts' => $totalAccounts ,
2025-09-11 15:16:04 +08:00
'deviceCount' => count ( $workbench -> config -> deviceGroups ),
2025-09-22 18:03:45 +08:00
'poolCount' => count ( $workbench -> config -> poolGroups ),
2025-06-06 14:45:06 +08:00
'totalUsers' => $totalUsers >> 0
2025-05-28 15:45:08 +08:00
];
2025-08-12 09:28:57 +08:00
unset ( $workbench -> trafficConfig , $workbench -> traffic_config );
2025-05-28 15:45:08 +08:00
}
break ;
2025-09-10 11:43:47 +08:00
case self :: TYPE_IMPORT_CONTACT :
2025-09-11 10:08:26 +08:00
if ( ! empty ( $workbench -> importContact )) {
$workbench -> config = $workbench -> importContact ;
2025-09-11 15:16:04 +08:00
$workbench -> config -> deviceGroups = json_decode ( $workbench -> config -> devices , true );
2025-09-22 18:03:45 +08:00
$workbench -> config -> poolGroups = json_decode ( $workbench -> config -> pools , true );
2025-09-10 11:43:47 +08:00
}
2025-09-11 10:08:26 +08:00
unset ( $workbench -> importContact , $workbench -> import_contact );
2025-09-10 11:43:47 +08:00
break ;
2025-04-10 16:40:30 +08:00
}
2025-08-12 09:28:57 +08:00
unset (
$workbench -> autoLike ,
$workbench -> momentsSync ,
$workbench -> groupPush ,
$workbench -> groupCreate ,
$workbench -> config -> devices ,
$workbench -> config -> friends ,
$workbench -> config -> groups ,
$workbench -> config -> contentLibraries ,
$workbench -> config -> account ,
);
//获取设备信息
2025-09-11 15:16:04 +08:00
if ( ! empty ( $workbench -> config -> deviceGroups )) {
2025-08-12 09:28:57 +08:00
$deviceList = DeviceModel :: alias ( 'd' )
-> field ([
'd.id' , 'd.imei' , 'd.memo' , 'd.alive' ,
'l.wechatId' ,
2025-08-15 15:37:00 +08:00
'a.nickname' , 'a.alias' , 'a.avatar' , 'a.alias' , '0 totalFriend'
2025-08-12 09:28:57 +08:00
])
-> leftJoin ( 'device_wechat_login l' , 'd.id = l.deviceId and l.alive =' . DeviceWechatLoginModel :: ALIVE_WECHAT_ACTIVE . ' and l.companyId = d.companyId' )
-> leftJoin ( 'wechat_account a' , 'l.wechatId = a.wechatId' )
2025-09-11 15:16:04 +08:00
-> whereIn ( 'd.id' , $workbench -> config -> deviceGroups )
2025-08-12 09:28:57 +08:00
-> order ( 'd.id desc' )
-> select ();
2025-08-15 15:37:00 +08:00
foreach ( $deviceList as & $device ) {
2025-11-13 16:10:47 +08:00
$curstomer = WechatCustomerModel :: field ( 'friendShip' ) -> where ([ 'wechatId' => $device [ 'wechatId' ]]) -> find ();
2025-08-15 15:37:00 +08:00
$device [ 'totalFriend' ] = $curstomer -> friendShip -> totalFriend ? ? 0 ;
}
unset ( $device );
2025-09-11 15:16:04 +08:00
$workbench -> config -> deviceGroupsOptions = $deviceList ;
2025-08-12 09:28:57 +08:00
} else {
2025-09-11 15:16:04 +08:00
$workbench -> config -> deviceGroupsOptions = [];
2025-08-12 09:28:57 +08:00
}
2025-11-07 15:25:50 +08:00
// 获取群( 当targetType=1时)
2025-11-13 16:10:47 +08:00
if ( ! empty ( $workbench -> config -> wechatGroups ) && isset ( $workbench -> config -> targetType ) && $workbench -> config -> targetType == 1 ) {
2025-08-12 09:28:57 +08:00
$groupList = Db :: name ( 'wechat_group' ) -> alias ( 'wg' )
-> join ( 'wechat_account wa' , 'wa.wechatId = wg.ownerWechatId' )
2025-11-07 15:25:50 +08:00
-> where ( 'wg.id' , 'in' , $workbench -> config -> wechatGroups )
2025-08-12 09:28:57 +08:00
-> order ( 'wg.id' , 'desc' )
-> field ( 'wg.id,wg.name as groupName,wg.ownerWechatId,wa.nickName,wa.avatar,wa.alias,wg.avatar as groupAvatar' )
-> select ();
$workbench -> config -> wechatGroupsOptions = $groupList ;
2025-11-13 16:10:47 +08:00
} else {
2025-08-12 09:28:57 +08:00
$workbench -> config -> wechatGroupsOptions = [];
}
2025-11-07 15:25:50 +08:00
// 获取好友( 当targetType=2时)
2025-11-13 16:10:47 +08:00
if ( ! empty ( $workbench -> config -> wechatFriends ) && isset ( $workbench -> config -> targetType ) && $workbench -> config -> targetType == 2 ) {
2025-11-07 15:25:50 +08:00
$friendList = Db :: table ( 's2_wechat_friend' ) -> alias ( 'wf' )
-> join ( 's2_wechat_account wa' , 'wa.id = wf.wechatAccountId' , 'left' )
-> where ( 'wf.id' , 'in' , $workbench -> config -> wechatFriends )
-> order ( 'wf.id' , 'desc' )
-> field ( 'wf.id,wf.wechatId,wf.nickname as friendName,wf.avatar as friendAvatar,wf.conRemark,wf.ownerWechatId,wa.nickName as accountName,wa.avatar as accountAvatar' )
-> select ();
$workbench -> config -> wechatFriendsOptions = $friendList ;
2025-11-13 16:10:47 +08:00
} else {
2025-11-07 15:25:50 +08:00
$workbench -> config -> wechatFriendsOptions = [];
}
2025-11-13 16:10:47 +08:00
// 获取流量池( 当targetType=2时)
if ( ! empty ( $workbench -> config -> trafficPools ) && isset ( $workbench -> config -> targetType ) && $workbench -> config -> targetType == 2 ) {
$poolList = Db :: name ( 'traffic_source_package' ) -> alias ( 'tsp' )
-> leftJoin ( 'traffic_source_package_item tspi' , 'tspi.packageId = tsp.id and tspi.isDel = 0' )
-> whereIn ( 'tsp.id' , $workbench -> config -> trafficPools )
-> where ( 'tsp.isDel' , 0 )
-> whereIn ( 'tsp.companyId' , [ $this -> request -> userInfo [ 'companyId' ], 0 ])
-> field ( 'tsp.id,tsp.name,tsp.description,tsp.pic,COUNT(tspi.id) as itemCount' )
-> group ( 'tsp.id' )
-> order ( 'tsp.id' , 'desc' )
-> select ();
$workbench -> config -> trafficPoolsOptions = $poolList ;
} else {
$workbench -> config -> trafficPoolsOptions = [];
}
2025-08-12 09:28:57 +08:00
// 获取内容库名称
if ( ! empty ( $workbench -> config -> contentGroups )) {
$libraryNames = ContentLibrary :: where ( 'id' , 'in' , $workbench -> config -> contentGroups ) -> select ();
$workbench -> config -> contentGroupsOptions = $libraryNames ;
} else {
$workbench -> config -> contentGroupsOptions = [];
}
//账号
2025-11-13 16:10:47 +08:00
if ( ! empty ( $workbench -> config -> accountGroups )) {
2025-08-12 09:28:57 +08:00
$account = Db :: table ( 's2_company_account' ) -> alias ( 'a' )
-> where ([ 'a.departmentId' => $this -> request -> userInfo [ 'companyId' ], 'a.status' => 0 ])
-> whereIn ( 'a.id' , $workbench -> config -> accountGroups )
-> whereNotLike ( 'a.userName' , '%_offline%' )
-> whereNotLike ( 'a.userName' , '%_delete%' )
-> field ( 'a.id,a.userName,a.realName,a.nickname,a.memo' )
-> select ();
2025-11-13 16:10:47 +08:00
$workbench -> config -> accountGroupsOptions = $account ;
} else {
2025-08-12 09:28:57 +08:00
$workbench -> config -> accountGroupsOptions = [];
}
2025-04-10 16:40:30 +08:00
2025-11-13 16:10:47 +08:00
if ( ! empty ( $workbench -> config -> poolGroups )) {
2025-08-22 10:23:05 +08:00
$poolGroupsOptions = Db :: name ( 'traffic_source_package' ) -> alias ( 'tsp' )
2025-11-13 16:10:47 +08:00
-> join ( 'traffic_source_package_item tspi' , 'tspi.packageId=tsp.id' , 'left' )
-> whereIn ( 'tsp.companyId' , [ $this -> request -> userInfo [ 'companyId' ], 0 ])
2025-08-22 10:23:05 +08:00
-> whereIn ( 'tsp.id' , $workbench -> config -> poolGroups )
-> field ( 'tsp.id,tsp.name,tsp.description,tsp.createTime,count(tspi.id) as num' )
-> group ( 'tsp.id' )
-> select ();
$workbench -> config -> poolGroupsOptions = $poolGroupsOptions ;
2025-11-13 16:10:47 +08:00
} else {
2025-08-22 10:23:05 +08:00
$workbench -> config -> poolGroupsOptions = [];
}
2025-11-13 16:10:47 +08:00
if ( ! empty ( $workbench -> config -> ownerWechatIds )) {
$ownerWechatOptions = Db :: name ( 'wechat_account' )
-> whereIn ( 'id' , $workbench -> config -> ownerWechatIds )
-> field ( 'id,wechatId,nickName,avatar,alias' )
-> select ();
$workbench -> config -> ownerWechatOptions = $ownerWechatOptions ;
} else {
$workbench -> config -> ownerWechatOptions = [];
}
2025-08-22 10:23:05 +08:00
2025-04-10 16:40:30 +08:00
return json ([ 'code' => 200 , 'msg' => '获取成功' , 'data' => $workbench ]);
}
2025-04-11 16:15:48 +08:00
/**
* 更新工作台
* @ return \think\response\Json
*/
public function update ()
{
if ( ! $this -> request -> isPost ()) {
return json ([ 'code' => 400 , 'msg' => '请求方式错误' ]);
}
// 获取请求参数
$param = $this -> request -> post ();
// 验证数据
$validate = new WorkbenchValidate ;
if ( ! $validate -> scene ( 'update' ) -> check ( $param )) {
return json ([ 'code' => 400 , 'msg' => $validate -> getError ()]);
}
2025-11-17 17:34:46 +08:00
$where = [
2025-04-11 16:15:48 +08:00
[ 'id' , '=' , $param [ 'id' ]],
2025-11-17 17:34:46 +08:00
[ 'companyId' , '=' , $this -> request -> userInfo [ 'companyId' ]],
2025-04-11 16:15:48 +08:00
[ 'isDel' , '=' , 0 ]
2025-11-17 17:34:46 +08:00
];
if ( empty ( $this -> request -> userInfo [ 'isAdmin' ])) {
$where [] = [ 'userId' , '=' , $this -> request -> userInfo [ 'id' ]];
}
// 查询工作台是否存在
$workbench = Workbench :: where ( $where ) -> find ();
2025-04-11 16:15:48 +08:00
if ( ! $workbench ) {
return json ([ 'code' => 404 , 'msg' => '工作台不存在' ]);
}
Db :: startTrans ();
try {
// 更新工作台基本信息
$workbench -> name = $param [ 'name' ];
2025-08-22 10:23:05 +08:00
$workbench -> status = ! empty ( $param [ 'status' ]) ? 1 : 0 ;
2025-04-11 16:15:48 +08:00
$workbench -> autoStart = ! empty ( $param [ 'autoStart' ]) ? 1 : 0 ;
$workbench -> updateTime = time ();
$workbench -> save ();
// 根据类型更新对应的配置
switch ( $workbench -> type ) {
case self :: TYPE_AUTO_LIKE :
$config = WorkbenchAutoLike :: where ( 'workbenchId' , $param [ 'id' ]) -> find ();
if ( $config ) {
$config -> interval = $param [ 'interval' ];
$config -> maxLikes = $param [ 'maxLikes' ];
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> contentTypes = json_encode ( $param [ 'contentTypes' ]);
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ]);
2025-08-12 09:28:57 +08:00
$config -> friends = json_encode ( $param [ 'friendsGroups' ]);
2025-05-09 09:22:31 +08:00
// $config->targetGroups = json_encode($param['targetGroups']);
// $config->tagOperator = $param['tagOperator'];
2025-05-16 09:43:04 +08:00
$config -> friendMaxLikes = $param [ 'friendMaxLikes' ];
$config -> friendTags = $param [ 'friendTags' ];
$config -> enableFriendTags = $param [ 'enableFriendTags' ];
2025-04-11 16:15:48 +08:00
$config -> updateTime = time ();
$config -> save ();
}
break ;
case self :: TYPE_MOMENTS_SYNC :
$config = WorkbenchMomentsSync :: where ( 'workbenchId' , $param [ 'id' ]) -> find ();
if ( $config ) {
2025-08-12 09:28:57 +08:00
if ( ! empty ( $param [ 'contentGroups' ])) {
foreach ( $param [ 'contentGroups' ] as $library ) {
if ( isset ( $library [ 'id' ]) && ! empty ( $library [ 'id' ])) {
2025-07-11 11:09:48 +08:00
$contentLibraries [] = $library [ 'id' ];
2025-08-12 09:28:57 +08:00
} else {
2025-07-11 11:09:48 +08:00
$contentLibraries [] = $library ;
}
}
2025-08-12 09:28:57 +08:00
} else {
2025-07-11 11:09:48 +08:00
$contentLibraries = [];
}
2025-08-12 09:28:57 +08:00
2025-04-11 16:15:48 +08:00
$config -> syncInterval = $param [ 'syncInterval' ];
$config -> syncCount = $param [ 'syncCount' ];
$config -> syncType = $param [ 'syncType' ];
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> accountType = $param [ 'accountType' ];
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ]);
2025-07-11 11:09:48 +08:00
$config -> contentLibraries = json_encode ( $contentLibraries );
2025-04-11 16:15:48 +08:00
$config -> updateTime = time ();
$config -> save ();
}
break ;
case self :: TYPE_GROUP_PUSH :
$config = WorkbenchGroupPush :: where ( 'workbenchId' , $param [ 'id' ]) -> find ();
if ( $config ) {
2025-11-13 16:10:47 +08:00
$ownerWechatIds = $this -> normalizeOwnerWechatIds ( $param [ 'ownerWechatIds' ] ? ? null , $config );
$groupPushData = $this -> prepareGroupPushData ( $param , $ownerWechatIds , $config );
$groupPushData [ 'updateTime' ] = time ();
$config -> save ( $groupPushData );
2025-04-11 16:15:48 +08:00
}
break ;
case self :: TYPE_GROUP_CREATE :
$config = WorkbenchGroupCreate :: where ( 'workbenchId' , $param [ 'id' ]) -> find ();
if ( $config ) {
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ], JSON_UNESCAPED_UNICODE );
2025-08-20 17:35:34 +08:00
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> groupSizeMin = $param [ 'groupSizeMin' ];
$config -> groupSizeMax = $param [ 'groupSizeMax' ];
$config -> maxGroupsPerDay = $param [ 'maxGroupsPerDay' ];
$config -> groupNameTemplate = $param [ 'groupNameTemplate' ];
$config -> groupDescription = $param [ 'groupDescription' ];
2025-08-22 10:23:05 +08:00
$config -> poolGroups = json_encode ( $param [ 'poolGroups' ] ? ? []);
$config -> wechatGroups = json_encode ( $param [ 'wechatGroups' ] ? ? []);
2025-04-11 16:15:48 +08:00
$config -> updateTime = time ();
$config -> save ();
}
break ;
2025-05-28 15:45:08 +08:00
case self :: TYPE_TRAFFIC_DISTRIBUTION :
2025-05-29 17:45:10 +08:00
$config = WorkbenchTrafficConfig :: where ( 'workbenchId' , $param [ 'id' ]) -> find ();
2025-05-28 15:45:08 +08:00
if ( $config ) {
$config -> distributeType = $param [ 'distributeType' ];
$config -> maxPerDay = $param [ 'maxPerDay' ];
$config -> timeType = $param [ 'timeType' ];
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ]);
2025-09-22 18:03:45 +08:00
$config -> pools = json_encode ( $param [ 'poolGroups' ]);
2025-08-12 09:28:57 +08:00
$config -> account = json_encode ( $param [ 'accountGroups' ]);
2025-05-28 15:45:08 +08:00
$config -> updateTime = time ();
$config -> save ();
}
break ;
2025-09-10 11:43:47 +08:00
case self :: TYPE_IMPORT_CONTACT : //联系人导入
2025-11-13 16:10:47 +08:00
$config = WorkbenchImportContact :: where ( 'workbenchId' , $param [ 'id' ]) -> find ();;
2025-09-10 11:43:47 +08:00
if ( $config ) {
2025-09-11 15:16:04 +08:00
$config -> devices = json_encode ( $param [ 'deviceGroups' ]);
2025-09-22 18:03:45 +08:00
$config -> pools = json_encode ( $param [ 'poolGroups' ]);
2025-09-10 11:43:47 +08:00
$config -> num = $param [ 'num' ];
$config -> clearContact = $param [ 'clearContact' ];
$config -> remark = $param [ 'remark' ];
$config -> startTime = $param [ 'startTime' ];
$config -> endTime = $param [ 'endTime' ];
$config -> save ();
}
break ;
2025-04-11 16:15:48 +08:00
}
Db :: commit ();
return json ([ 'code' => 200 , 'msg' => '更新成功' ]);
} catch ( \Exception $e ) {
Db :: rollback ();
return json ([ 'code' => 500 , 'msg' => '更新失败:' . $e -> getMessage ()]);
}
}
2025-04-10 16:40:30 +08:00
/**
* 更新工作台状态
* @ return \think\response\Json
*/
public function updateStatus ()
{
if ( ! $this -> request -> isPost ()) {
return json ([ 'code' => 400 , 'msg' => '请求方式错误' ]);
}
2025-08-12 09:28:57 +08:00
$id = $this -> request -> param ( 'id' , '' );
2025-04-10 16:40:30 +08:00
2025-08-12 09:28:57 +08:00
if ( empty ( $id )) {
2025-06-10 09:53:01 +08:00
return json ([ 'code' => 400 , 'msg' => '参数错误' ]);
2025-04-10 16:40:30 +08:00
}
2025-11-17 17:34:46 +08:00
$where = [
2025-06-10 09:53:01 +08:00
[ 'id' , '=' , $id ],
2025-11-17 17:34:46 +08:00
[ 'companyId' , '=' , $this -> request -> userInfo [ 'companyId' ]],
[ 'isDel' , '=' , 0 ]
];
if ( empty ( $this -> request -> userInfo [ 'isAdmin' ])) {
$where [] = [ 'userId' , '=' , $this -> request -> userInfo [ 'id' ]];
}
$workbench = Workbench :: where ( $where ) -> find ();
2025-04-10 16:40:30 +08:00
if ( empty ( $workbench )) {
return json ([ 'code' => 404 , 'msg' => '工作台不存在' ]);
}
$workbench -> status = ! $workbench [ 'status' ];
$workbench -> save ();
return json ([ 'code' => 200 , 'msg' => '更新成功' ]);
}
/**
* 删除工作台(软删除)
*/
2025-04-11 16:15:48 +08:00
public function delete ()
2025-04-10 16:40:30 +08:00
{
2025-04-11 16:15:48 +08:00
$id = $this -> request -> param ( 'id' );
2025-04-10 16:40:30 +08:00
if ( empty ( $id )) {
return json ([ 'code' => 400 , 'msg' => '参数错误' ]);
}
2025-11-17 17:34:46 +08:00
$where = [
2025-04-10 16:40:30 +08:00
[ 'id' , '=' , $id ],
2025-11-17 17:34:46 +08:00
[ 'companyId' , '=' , $this -> request -> userInfo [ 'companyId' ]],
2025-04-10 16:40:30 +08:00
[ 'isDel' , '=' , 0 ]
2025-11-17 17:34:46 +08:00
];
if ( empty ( $this -> request -> userInfo [ 'isAdmin' ])) {
$where [] = [ 'userId' , '=' , $this -> request -> userInfo [ 'id' ]];
}
$workbench = Workbench :: where ( $where ) -> find ();
2025-04-10 16:40:30 +08:00
if ( ! $workbench ) {
return json ([ 'code' => 404 , 'msg' => '工作台不存在' ]);
}
// 软删除
$workbench -> isDel = 1 ;
2025-06-25 11:42:04 +08:00
$workbench -> deleteTime = time ();
2025-04-10 16:40:30 +08:00
$workbench -> save ();
return json ([ 'code' => 200 , 'msg' => '删除成功' ]);
}
/**
* 拷贝工作台
* @ return \think\response\Json
*/
public function copy ()
{
if ( ! $this -> request -> isPost ()) {
return json ([ 'code' => 400 , 'msg' => '请求方式错误' ]);
}
$id = $this -> request -> post ( 'id' );
if ( empty ( $id )) {
return json ([ 'code' => 400 , 'msg' => '参数错误' ]);
}
// 验证权限并获取原数据
$workbench = Workbench :: where ([
[ 'id' , '=' , $id ],
[ 'userId' , '=' , $this -> request -> userInfo [ 'id' ]]
]) -> find ();
if ( empty ( $workbench )) {
return json ([ 'code' => 404 , 'msg' => '工作台不存在' ]);
}
Db :: startTrans ();
try {
// 创建新的工作台基本信息
$newWorkbench = new Workbench ;
$newWorkbench -> name = $workbench -> name . ' copy' ;
$newWorkbench -> type = $workbench -> type ;
$newWorkbench -> status = 1 ; // 新拷贝的默认启用
$newWorkbench -> autoStart = $workbench -> autoStart ;
$newWorkbench -> userId = $this -> request -> userInfo [ 'id' ];
2025-04-11 16:15:48 +08:00
$newWorkbench -> companyId = $this -> request -> userInfo [ 'companyId' ];
2025-04-10 16:40:30 +08:00
$newWorkbench -> save ();
// 根据类型拷贝对应的配置
switch ( $workbench -> type ) {
case self :: TYPE_AUTO_LIKE :
$config = WorkbenchAutoLike :: where ( 'workbenchId' , $id ) -> find ();
if ( $config ) {
$newConfig = new WorkbenchAutoLike ;
$newConfig -> workbenchId = $newWorkbench -> id ;
$newConfig -> interval = $config -> interval ;
$newConfig -> maxLikes = $config -> maxLikes ;
$newConfig -> startTime = $config -> startTime ;
$newConfig -> endTime = $config -> endTime ;
$newConfig -> contentTypes = $config -> contentTypes ;
$newConfig -> devices = $config -> devices ;
2025-05-09 09:22:31 +08:00
$newConfig -> friends = $config -> friends ;
2025-08-22 10:23:05 +08:00
$newConfig -> createTime = time ();
$newConfig -> updateTime = time ();
2025-04-10 16:40:30 +08:00
$newConfig -> save ();
}
break ;
case self :: TYPE_MOMENTS_SYNC :
$config = WorkbenchMomentsSync :: where ( 'workbenchId' , $id ) -> find ();
if ( $config ) {
$newConfig = new WorkbenchMomentsSync ;
$newConfig -> workbenchId = $newWorkbench -> id ;
$newConfig -> syncInterval = $config -> syncInterval ;
$newConfig -> syncCount = $config -> syncCount ;
$newConfig -> syncType = $config -> syncType ;
2025-04-11 16:15:48 +08:00
$newConfig -> startTime = $config -> startTime ;
$newConfig -> endTime = $config -> endTime ;
$newConfig -> accountType = $config -> accountType ;
2025-04-10 16:40:30 +08:00
$newConfig -> devices = $config -> devices ;
2025-04-11 16:15:48 +08:00
$newConfig -> contentLibraries = $config -> contentLibraries ;
2025-08-22 10:23:05 +08:00
$newConfig -> createTime = time ();
$newConfig -> updateTime = time ();
2025-04-10 16:40:30 +08:00
$newConfig -> save ();
}
break ;
case self :: TYPE_GROUP_PUSH :
$config = WorkbenchGroupPush :: where ( 'workbenchId' , $id ) -> find ();
if ( $config ) {
$newConfig = new WorkbenchGroupPush ;
$newConfig -> workbenchId = $newWorkbench -> id ;
2025-06-06 14:45:06 +08:00
$newConfig -> pushType = $config -> pushType ;
2025-11-07 15:25:50 +08:00
$newConfig -> targetType = isset ( $config -> targetType ) ? $config -> targetType : 1 ; // 默认1=群推送
2025-06-06 14:45:06 +08:00
$newConfig -> startTime = $config -> startTime ;
$newConfig -> endTime = $config -> endTime ;
$newConfig -> maxPerDay = $config -> maxPerDay ;
$newConfig -> pushOrder = $config -> pushOrder ;
$newConfig -> isLoop = $config -> isLoop ;
$newConfig -> status = $config -> status ;
$newConfig -> groups = $config -> groups ;
2025-11-07 15:25:50 +08:00
$newConfig -> friends = $config -> friends ;
2025-06-06 14:45:06 +08:00
$newConfig -> contentLibraries = $config -> contentLibraries ;
2025-11-13 16:10:47 +08:00
$newConfig -> trafficPools = property_exists ( $config , 'trafficPools' ) ? $config -> trafficPools : json_encode ([], JSON_UNESCAPED_UNICODE );
2025-11-07 15:25:50 +08:00
$newConfig -> socialMediaId = $config -> socialMediaId ;
$newConfig -> promotionSiteId = $config -> promotionSiteId ;
2025-11-13 16:10:47 +08:00
$newConfig -> ownerWechatIds = $config -> ownerWechatIds ;
2025-08-22 10:23:05 +08:00
$newConfig -> createTime = time ();
$newConfig -> updateTime = time ();
2025-04-10 16:40:30 +08:00
$newConfig -> save ();
}
break ;
case self :: TYPE_GROUP_CREATE :
$config = WorkbenchGroupCreate :: where ( 'workbenchId' , $id ) -> find ();
if ( $config ) {
$newConfig = new WorkbenchGroupCreate ;
$newConfig -> workbenchId = $newWorkbench -> id ;
$newConfig -> devices = $config -> devices ;
2025-08-20 17:35:34 +08:00
$newConfig -> startTime = $config -> startTime ;
$newConfig -> endTime = $config -> endTime ;
$newConfig -> groupSizeMin = $config -> groupSizeMin ;
$newConfig -> groupSizeMax = $config -> groupSizeMax ;
$newConfig -> maxGroupsPerDay = $config -> maxGroupsPerDay ;
$newConfig -> groupNameTemplate = $config -> groupNameTemplate ;
$newConfig -> groupDescription = $config -> groupDescription ;
2025-11-13 16:10:47 +08:00
$newConfig -> poolGroups = $config -> poolGroups ;
$newConfig -> wechatGroups = $config -> wechatGroups ;
2025-08-20 17:35:34 +08:00
$newConfig -> createTime = time ();
$newConfig -> updateTime = time ();
2025-04-10 16:40:30 +08:00
$newConfig -> save ();
}
break ;
2025-09-10 11:43:47 +08:00
case self :: TYPE_IMPORT_CONTACT : //联系人导入
2025-11-13 16:10:47 +08:00
$config = WorkbenchImportContact :: where ( 'workbenchId' , $id ) -> find ();
2025-09-10 11:43:47 +08:00
if ( $config ) {
$newConfig = new WorkbenchImportContact ;
2025-09-11 10:08:26 +08:00
$newConfig -> workbenchId = $newWorkbench -> id ;
$newConfig -> devices = $config -> devices ;
$newConfig -> pools = $config -> pools ;
2025-09-10 11:43:47 +08:00
$newConfig -> num = $config -> num ;
$newConfig -> clearContact = $config -> clearContact ;
$newConfig -> remark = $config -> remark ;
$newConfig -> startTime = $config -> startTime ;
$newConfig -> endTime = $config -> endTime ;
$newConfig -> createTime = time ();
$newConfig -> save ();
}
break ;
2025-04-10 16:40:30 +08:00
}
Db :: commit ();
return json ([ 'code' => 200 , 'msg' => '拷贝成功' , 'data' => [ 'id' => $newWorkbench -> id ]]);
} catch ( \Exception $e ) {
Db :: rollback ();
return json ([ 'code' => 500 , 'msg' => '拷贝失败:' . $e -> getMessage ()]);
}
}
2025-05-16 15:12:49 +08:00
/**
* 获取点赞记录列表
* @ 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' )
2025-07-02 15:48:22 +08:00
-> join ([ 's2_wechat_moments' => 'wm' ], 'wali.snsId = wm.snsId' )
2025-05-16 15:12:49 +08:00
-> 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' )
2025-07-02 15:48:22 +08:00
-> group ( 'wali.id' )
2025-05-16 15:12:49 +08:00
-> page ( $page , $limit )
-> select ();
2025-08-20 17:35:34 +08:00
2025-05-16 15:12:49 +08:00
// 处理数据
foreach ( $list as & $item ) {
2025-08-20 17:35:34 +08:00
//处理用户信息
$friend = Db :: table ( 's2_wechat_friend' )
-> where ([ 'id' => $item [ 'wechatFriendId' ]])
-> field ( 'nickName,avatar' )
-> find ();
2025-11-13 16:10:47 +08:00
if ( ! empty ( $friend )) {
2025-08-20 17:35:34 +08:00
$item [ 'friendName' ] = $friend [ 'nickName' ];
$item [ 'friendAvatar' ] = $friend [ 'avatar' ];
2025-11-13 16:10:47 +08:00
} else {
2025-08-20 17:35:34 +08:00
$item [ 'friendName' ] = '' ;
$item [ 'friendAvatar' ] = '' ;
}
//处理客服
$friend = Db :: table ( 's2_wechat_account' )
-> where ([ 'id' => $item [ 'wechatAccountId' ]])
-> field ( 'nickName,avatar' )
-> find ();
2025-11-13 16:10:47 +08:00
if ( ! empty ( $friend )) {
2025-08-20 17:35:34 +08:00
$item [ 'operatorName' ] = $friend [ 'nickName' ];
$item [ 'operatorAvatar' ] = $friend [ 'avatar' ];
2025-11-13 16:10:47 +08:00
} else {
2025-08-20 17:35:34 +08:00
$item [ 'operatorName' ] = '' ;
$item [ 'operatorAvatar' ] = '' ;
}
2025-05-16 15:12:49 +08:00
// 处理时间格式
$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' ]) : '' ;
2025-08-12 09:28:57 +08:00
2025-05-16 15:12:49 +08:00
// 处理资源链接
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
]
]);
}
2025-05-26 17:56:12 +08:00
/**
* 获取朋友圈发布记录列表
* @ 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 ();
2025-08-12 09:28:57 +08:00
foreach ( $list as & $item ) {
$item [ 'resUrls' ] = json_decode ( $item [ 'resUrls' ], true );
$item [ 'urls' ] = json_decode ( $item [ 'urls' ], true );
}
2025-05-26 17:56:12 +08:00
// 获取总记录数
$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' );
2025-08-12 09:28:57 +08:00
2025-05-26 17:56:12 +08:00
$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' ])
]
]
]);
}
/**
* 获取流量分发记录列表
* @ 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' ]);
2025-08-12 09:28:57 +08:00
2025-05-26 17:56:12 +08:00
// 处理性别
$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' );
2025-08-12 09:28:57 +08:00
2025-05-26 17:56:12 +08:00
$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' ]);
2025-08-12 09:28:57 +08:00
2025-05-26 17:56:12 +08:00
// 处理性别
$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' => self :: 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 ),
2025-09-22 18:03:45 +08:00
'pools' => json_encode ( $param [ 'poolGroups' ], JSON_UNESCAPED_UNICODE ),
2025-05-26 17:56:12 +08:00
'createTime' => time (),
'updateTime' => time ()
]);
Db :: commit ();
2025-08-12 09:28:57 +08:00
return json ([ 'code' => 200 , 'msg' => '创建成功' ]);
2025-05-26 17:56:12 +08:00
} catch ( \Exception $e ) {
Db :: rollback ();
2025-08-12 09:28:57 +08:00
return json ([ 'code' => 500 , 'msg' => '创建失败:' . $e -> getMessage ()]);
2025-05-26 17:56:12 +08:00
}
}
2025-05-29 17:45:10 +08:00
/**
* 获取所有微信好友标签及数量统计
* @ return \think\response\Json
*/
public function getDeviceLabels ()
{
$deviceIds = $this -> request -> param ( 'deviceIds' , '' );
$companyId = $this -> request -> userInfo [ 'companyId' ];
2025-06-07 17:34:20 +08:00
$page = $this -> request -> param ( 'page' , 1 );
$limit = $this -> request -> param ( 'limit' , 10 );
$keyword = $this -> request -> param ( 'keyword' , '' );
2025-05-29 17:45:10 +08:00
$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 );
2025-06-07 17:34:20 +08:00
// 搜索过滤
if ( ! empty ( $keyword )) {
2025-08-12 09:28:57 +08:00
$labels = array_filter ( $labels , function ( $label ) use ( $keyword ) {
2025-06-07 17:34:20 +08:00
return mb_stripos ( $label , $keyword ) !== false ;
});
$labels = array_values ( $labels ); // 重新索引数组
}
// 分页处理
$labels2 = array_slice ( $labels , ( $page - 1 ) * $limit , $limit );
2025-05-29 17:45:10 +08:00
// 统计数量
$newLabel = [];
2025-06-07 17:34:20 +08:00
foreach ( $labels2 as $label ) {
2025-05-29 17:45:10 +08:00
$friendCount = Db :: table ( 's2_wechat_friend' )
2025-08-12 09:28:57 +08:00
-> whereIn ( 'ownerWechatId' , $wechatIds )
-> where ( 'labels' , 'like' , '%"' . $label . '"%' )
-> count ();
2025-05-29 17:45:10 +08:00
$newLabel [] = [
'label' => $label ,
'count' => $friendCount
];
}
// 返回结果
2025-06-07 17:34:20 +08:00
return json ([
2025-08-12 09:28:57 +08:00
'code' => 200 ,
'msg' => '获取成功' ,
2025-06-07 17:34:20 +08:00
'data' => [
'list' => $newLabel ,
'total' => count ( $labels ),
]
]);
2025-05-29 17:45:10 +08:00
}
2025-06-06 14:45:06 +08:00
/**
* 获取群列表
* @ 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' )
2025-08-12 09:28:57 +08:00
-> 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 ();
2025-06-06 14:45:06 +08:00
// 优化:格式化时间,头像兜底
$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 ;
}
2025-08-12 09:28:57 +08:00
return json ([ 'code' => 200 , 'msg' => '获取成功' , 'data' => [ 'total' => $total , 'list' => $list ]]);
2025-06-06 14:45:06 +08:00
}
2025-11-13 16:10:47 +08:00
/**
* 获取流量池列表
* @ 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 ]]);
}
2025-06-06 14:45:06 +08:00
2025-06-07 17:34:20 +08:00
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' )
2025-08-12 09:28:57 +08:00
-> alias ( 'a' )
-> where ([ 'a.departmentId' => $companyId , 'a.status' => 0 ])
-> whereNotLike ( 'a.userName' , '%_offline%' )
-> whereNotLike ( 'a.userName' , '%_delete%' );
2025-06-07 17:34:20 +08:00
$total = $query -> count ();
$list = $query -> field ( 'a.id,a.userName,a.realName,a.nickname,a.memo' )
2025-08-12 09:28:57 +08:00
-> page ( $page , $limit )
-> select ();
2025-06-07 17:34:20 +08:00
2025-08-12 09:28:57 +08:00
return json ([ 'code' => 200 , 'msg' => '获取成功' , 'data' => [ 'total' => $total , 'list' => $list ]]);
2025-06-07 17:34:20 +08:00
}
2025-08-06 18:02:03 +08:00
/**
* 获取京东联盟导购媒体
* @ return \think\response\Json
* @ throws \think\db\exception\DataNotFoundException
* @ throws \think\db\exception\ModelNotFoundException
* @ throws \think\exception\DbException
*/
public function getJdSocialMedia ()
{
$data = Db :: name ( 'jd_social_media' ) -> order ( 'id DESC' ) -> select ();
return json ([ 'code' => 200 , 'msg' => '获取成功' , 'data' => $data ]);
}
/**
* 获取京东联盟广告位
* @ return \think\response\Json
* @ throws \think\db\exception\DataNotFoundException
* @ throws \think\db\exception\ModelNotFoundException
* @ throws \think\exception\DbException
*/
public function getJdPromotionSite ()
{
$id = $this -> request -> param ( 'id' , '' );
if ( empty ( $id )) {
return json ([ 'code' => 500 , 'msg' => '参数缺失' ]);
}
2025-08-12 09:28:57 +08:00
$data = Db :: name ( 'jd_promotion_site' ) -> where ( 'jdSocialMediaId' , $id ) -> order ( 'id DESC' ) -> select ();
2025-08-06 18:02:03 +08:00
return json ([ 'code' => 200 , 'msg' => '获取成功' , 'data' => $data ]);
}
2025-09-02 11:24:23 +08:00
//京东转链-京推推
2025-11-13 16:10:47 +08:00
public function changeLink ( $content = '' , $positionid = '' )
2025-09-02 11:24:23 +08:00
{
$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' , '' );
2025-11-13 16:10:47 +08:00
if ( empty ( $content )) {
return json_encode ([ 'code' => 500 , 'msg' => '转链的内容为空' ]);
2025-09-02 11:24:23 +08:00
}
2025-11-13 16:10:47 +08:00
2025-09-02 11:24:23 +08:00
// 验证是否包含链接
if ( ! $this -> containsLink ( $content )) {
2025-11-13 16:10:47 +08:00
return json_encode ([ 'code' => 500 , 'msg' => '内容中未检测到有效链接' ]);
2025-09-02 11:24:23 +08:00
}
2025-11-13 16:10:47 +08:00
if ( empty ( $unionId ) || empty ( $jttAppId ) || empty ( $appKey ) || empty ( $apiUrl )) {
return json_encode ([ 'code' => 500 , 'msg' => '参数缺失' ]);
2025-09-02 11:24:23 +08:00
}
$params = [
'unionid' => $unionId ,
'content' => $content ,
'appid' => $jttAppId ,
'appkey' => $appKey ,
'v' => 'v2'
];
if ( ! empty ( $positionid )) {
$params [ 'positionid' ] = $positionid ;
}
2025-11-13 16:10:47 +08:00
$res = requestCurl ( $apiUrl , $params , 'GET' , [], 'json' );
$res = json_decode ( $res , true );
if ( empty ( $res )) {
return json_encode ([ 'code' => 500 , 'msg' => '未知错误' ]);
2025-09-02 11:24:23 +08:00
}
$result = $res [ 'result' ];
2025-11-13 16:10:47 +08:00
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' ]]);
2025-09-02 11:24:23 +08:00
}
}
2025-08-20 17:35:34 +08:00
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' , '' );
if ( empty ( $workbenchId )) {
return json ([ 'code' => 400 , 'msg' => '参数错误' ]);
}
2025-11-13 16:10:47 +08:00
$workbench = Db :: name ( 'workbench' ) -> where ([ 'id' => $workbenchId , 'isDel' => 0 , 'companyId' => $companyId , 'type' => 5 ]) -> find ();
2025-08-20 17:35:34 +08:00
2025-11-13 16:10:47 +08:00
if ( empty ( $workbench )) {
2025-08-20 17:35:34 +08:00
return json ([ 'code' => 400 , 'msg' => '该任务不存在或已删除' ]);
}
$query = Db :: name ( 'workbench_traffic_config_item' ) -> alias ( 'wtc' )
2025-11-13 16:10:47 +08:00
-> join ([ 's2_wechat_friend' => 'wf' ], 'wtc.wechatFriendId = wf.id' )
-> join ( 'users u' , 'wtc.wechatAccountId = u.s2_accountId' , 'left' )
2025-08-20 17:35:34 +08:00
-> field ([
2025-11-13 16:10:47 +08:00
'wtc.id' , 'wtc.isRecycle' , 'wtc.isRecycle' , 'wtc.createTime' ,
'wf.wechatId' , 'wf.alias' , 'wf.nickname' , 'wf.avatar' , 'wf.gender' , 'wf.phone' ,
'u.account' , 'u.username'
2025-08-20 17:35:34 +08:00
])
-> where ([ 'wtc.workbenchId' => $workbenchId ])
-> order ( 'wtc.id DESC' );
2025-11-13 16:10:47 +08:00
if ( ! empty ( $keyword )) {
$query -> where ( 'wf.wechatId|wf.alias|wf.nickname|wf.phone|u.account|u.username' , 'like' , '%' . $keyword . '%' );
2025-08-20 17:35:34 +08:00
}
$total = $query -> count ();
$list = $query -> page ( $page , $limit ) -> select ();
foreach ( $list as & $item ) {
$item [ 'createTime' ] = date ( 'Y-m-d H:i:s' , $item [ 'createTime' ]);
}
unset ( $item );
$data = [
'total' => $total ,
'list' => $list ,
];
return json ([ 'code' => 200 , 'msg' => '获取成功' , 'data' => $data ]);
}
2025-11-13 16:10:47 +08:00
/**
* 规范化客服微信ID列表
* @ param mixed $ownerWechatIds
* @ param WorkbenchGroupPush | null $originalConfig
* @ return array
* @ throws \Exception
*/
private function normalizeOwnerWechatIds ( $ownerWechatIds , WorkbenchGroupPush $originalConfig = null ) : array
{
if ( $ownerWechatIds === null ) {
$existing = $originalConfig ? $this -> decodeJsonArray ( $originalConfig -> ownerWechatIds ? ? []) : [];
if ( empty ( $existing )) {
throw new \Exception ( '请至少选择一个客服微信' );
}
return $existing ;
}
if ( ! is_array ( $ownerWechatIds )) {
throw new \Exception ( '客服参数格式错误' );
}
$normalized = $this -> extractIdList ( $ownerWechatIds , '客服参数格式错误' );
if ( empty ( $normalized )) {
throw new \Exception ( '请至少选择一个客服微信' );
}
return $normalized ;
}
/**
* 构建群推送配置数据
* @ param array $param
* @ param array $ownerWechatIds
* @ param WorkbenchGroupPush | null $originalConfig
* @ return array
* @ throws \Exception
*/
private function prepareGroupPushData ( array $param , array $ownerWechatIds , WorkbenchGroupPush $originalConfig = null ) : array
{
$targetTypeDefault = $originalConfig ? intval ( $originalConfig -> targetType ) : 1 ;
$targetType = intval ( $this -> getParamValue ( $param , 'targetType' , $targetTypeDefault )) ? : 1 ;
$groupPushSubTypeDefault = $originalConfig ? intval ( $originalConfig -> groupPushSubType ) : 1 ;
$groupPushSubType = intval ( $this -> getParamValue ( $param , 'groupPushSubType' , $groupPushSubTypeDefault )) ? : 1 ;
if ( ! in_array ( $groupPushSubType , [ 1 , 2 ], true )) {
$groupPushSubType = 1 ;
}
$data = [
'pushType' => $this -> toBoolInt ( $this -> getParamValue ( $param , 'pushType' , $originalConfig -> pushType ? ? 0 )),
'targetType' => $targetType ,
'startTime' => $this -> getParamValue ( $param , 'startTime' , $originalConfig -> startTime ? ? '' ),
'endTime' => $this -> getParamValue ( $param , 'endTime' , $originalConfig -> endTime ? ? '' ),
'maxPerDay' => intval ( $this -> getParamValue ( $param , 'maxPerDay' , $originalConfig -> maxPerDay ? ? 0 )),
'pushOrder' => $this -> getParamValue ( $param , 'pushOrder' , $originalConfig -> pushOrder ? ? 1 ),
'groupPushSubType' => $groupPushSubType ,
'status' => $this -> toBoolInt ( $this -> getParamValue ( $param , 'status' , $originalConfig -> status ? ? 0 )),
'socialMediaId' => $this -> getParamValue ( $param , 'socialMediaId' , $originalConfig -> socialMediaId ? ? '' ),
'promotionSiteId' => $this -> getParamValue ( $param , 'promotionSiteId' , $originalConfig -> promotionSiteId ? ? '' ),
'friendIntervalMin' => intval ( $this -> getParamValue ( $param , 'friendIntervalMin' , $originalConfig -> friendIntervalMin ? ? 10 )),
'friendIntervalMax' => intval ( $this -> getParamValue ( $param , 'friendIntervalMax' , $originalConfig -> friendIntervalMax ? ? 20 )),
'messageIntervalMin' => intval ( $this -> getParamValue ( $param , 'messageIntervalMin' , $originalConfig -> messageIntervalMin ? ? 1 )),
'messageIntervalMax' => intval ( $this -> getParamValue ( $param , 'messageIntervalMax' , $originalConfig -> messageIntervalMax ? ? 12 )),
'isRandomTemplate' => $this -> toBoolInt ( $this -> getParamValue ( $param , 'isRandomTemplate' , $originalConfig -> isRandomTemplate ? ? 0 )),
'ownerWechatIds' => json_encode ( $ownerWechatIds , JSON_UNESCAPED_UNICODE ),
];
if ( $data [ 'friendIntervalMin' ] > $data [ 'friendIntervalMax' ]) {
throw new \Exception ( '目标间最小间隔不能大于最大间隔' );
}
if ( $data [ 'messageIntervalMin' ] > $data [ 'messageIntervalMax' ]) {
throw new \Exception ( '消息间最小间隔不能大于最大间隔' );
}
$contentGroupsExisting = $originalConfig ? $this -> decodeJsonArray ( $originalConfig -> contentLibraries ? ? []) : [];
$contentGroupsParam = $this -> getParamValue ( $param , 'contentGroups' , null );
$contentGroups = $contentGroupsParam !== null
? $this -> extractIdList ( $contentGroupsParam , '内容库参数格式错误' )
: $contentGroupsExisting ;
$data [ 'contentLibraries' ] = json_encode ( $contentGroups , JSON_UNESCAPED_UNICODE );
$postPushTagsExisting = $originalConfig ? $this -> decodeJsonArray ( $originalConfig -> postPushTags ? ? []) : [];
$postPushTagsParam = $this -> getParamValue ( $param , 'postPushTags' , null );
$postPushTags = $postPushTagsParam !== null
? $this -> extractIdList ( $postPushTagsParam , '推送标签参数格式错误' )
: $postPushTagsExisting ;
$data [ 'postPushTags' ] = json_encode ( $postPushTags , JSON_UNESCAPED_UNICODE );
if ( $targetType === 1 ) {
$data [ 'isLoop' ] = $this -> toBoolInt ( $this -> getParamValue ( $param , 'isLoop' , $originalConfig -> isLoop ? ? 0 ));
$groupsExisting = $originalConfig ? $this -> decodeJsonArray ( $originalConfig -> groups ? ? []) : [];
$wechatGroups = array_key_exists ( 'wechatGroups' , $param )
? $this -> extractIdList ( $param [ 'wechatGroups' ], '群参数格式错误' )
: $groupsExisting ;
if ( empty ( $wechatGroups )) {
throw new \Exception ( '群推送必须选择微信群' );
}
$data [ 'groups' ] = json_encode ( $wechatGroups , JSON_UNESCAPED_UNICODE );
$data [ 'friends' ] = json_encode ([], JSON_UNESCAPED_UNICODE );
$data [ 'trafficPools' ] = json_encode ([], JSON_UNESCAPED_UNICODE );
if ( $groupPushSubType === 2 ) {
$announcementContent = $this -> getParamValue ( $param , 'announcementContent' , $originalConfig -> announcementContent ? ? '' );
if ( empty ( $announcementContent )) {
throw new \Exception ( '群公告必须输入公告内容' );
}
$enableAiRewrite = $this -> toBoolInt ( $this -> getParamValue ( $param , 'enableAiRewrite' , $originalConfig -> enableAiRewrite ? ? 0 ));
$aiRewritePrompt = trim (( string ) $this -> getParamValue ( $param , 'aiRewritePrompt' , $originalConfig -> aiRewritePrompt ? ? '' ));
if ( $enableAiRewrite === 1 && $aiRewritePrompt === '' ) {
throw new \Exception ( '启用AI智能话术改写时, 必须输入改写提示词' );
}
$data [ 'announcementContent' ] = $announcementContent ;
$data [ 'enableAiRewrite' ] = $enableAiRewrite ;
$data [ 'aiRewritePrompt' ] = $aiRewritePrompt ;
} else {
$data [ 'groupPushSubType' ] = 1 ;
$data [ 'announcementContent' ] = '' ;
$data [ 'enableAiRewrite' ] = 0 ;
$data [ 'aiRewritePrompt' ] = '' ;
}
} else {
$data [ 'isLoop' ] = 0 ;
$friendsExisting = $originalConfig ? $this -> decodeJsonArray ( $originalConfig -> friends ? ? []) : [];
$trafficPoolsExisting = $originalConfig ? $this -> decodeJsonArray ( $originalConfig -> trafficPools ? ? []) : [];
$friendTargets = array_key_exists ( 'wechatFriends' , $param )
? $this -> extractIdList ( $param [ 'wechatFriends' ], '好友参数格式错误' )
: $friendsExisting ;
$trafficPools = array_key_exists ( 'trafficPools' , $param )
? $this -> extractIdList ( $param [ 'trafficPools' ], '流量池参数格式错误' )
: $trafficPoolsExisting ;
if ( empty ( $friendTargets ) && empty ( $trafficPools )) {
throw new \Exception ( '好友推送需至少选择好友或流量池' );
}
$data [ 'friends' ] = json_encode ( $friendTargets , JSON_UNESCAPED_UNICODE );
$data [ 'trafficPools' ] = json_encode ( $trafficPools , JSON_UNESCAPED_UNICODE );
$data [ 'groups' ] = json_encode ([], JSON_UNESCAPED_UNICODE );
$data [ 'groupPushSubType' ] = 1 ;
$data [ 'announcementContent' ] = '' ;
$data [ 'enableAiRewrite' ] = 0 ;
$data [ 'aiRewritePrompt' ] = '' ;
}
return $data ;
}
/**
* 获取参数值,若不存在则返回默认值
* @ param array $param
* @ param string $key
* @ param mixed $default
* @ return mixed
*/
private function getParamValue ( array $param , string $key , $default )
{
return array_key_exists ( $key , $param ) ? $param [ $key ] : $default ;
}
/**
* 将值转换为整型布尔
* @ param mixed $value
* @ return int
*/
private function toBoolInt ( $value ) : int
{
return empty ( $value ) ? 0 : 1 ;
}
/**
* 从参数中提取ID列表
* @ param mixed $items
* @ param string $errorMessage
* @ return array
* @ throws \Exception
*/
private function extractIdList ( $items , string $errorMessage = '参数格式错误' ) : array
{
if ( ! is_array ( $items )) {
throw new \Exception ( $errorMessage );
}
$ids = [];
foreach ( $items as $item ) {
if ( is_array ( $item ) && isset ( $item [ 'id' ])) {
$item = $item [ 'id' ];
}
if ( $item === '' || $item === null ) {
continue ;
}
$ids [] = $item ;
}
return array_values ( array_unique ( $ids ));
}
/**
* 解码JSON数组
* @ param mixed $value
* @ return array
*/
private function decodeJsonArray ( $value ) : array
{
if ( empty ( $value )) {
return [];
}
if ( is_array ( $value )) {
return $value ;
}
$decoded = json_decode ( $value , true );
return is_array ( $decoded ) ? $decoded : [];
}
2025-09-02 11:24:23 +08:00
/**
* 验证内容是否包含链接
* @ 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'
];
2025-11-13 16:10:47 +08:00
2025-09-02 11:24:23 +08:00
// 遍历所有模式进行匹配
foreach ( $patterns as $pattern ) {
if ( preg_match ( $pattern , $content )) {
return true ;
}
}
2025-11-13 16:10:47 +08:00
2025-09-02 11:24:23 +08:00
return false ;
}
2025-09-12 10:25:19 +08:00
/**
* 获取通讯录导入记录列表
* @ 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 ,
]
]);
}
2025-11-13 16:10:47 +08:00
/**
* 获取群发统计数据
* @ return \think\response\Json
*/
public function getGroupPushStats ()
{
$workbenchId = $this -> request -> param ( 'workbenchId' , 0 );
$timeRange = $this -> request -> param ( 'timeRange' , '7' ); // 默认最近7天
$contentLibraryIds = $this -> request -> param ( 'contentLibraryIds' , '' ); // 话术组筛选
$userId = $this -> request -> userInfo [ 'id' ];
// 如果指定了工作台ID, 则验证权限
if ( ! empty ( $workbenchId )) {
$workbench = Workbench :: where ([
[ 'id' , '=' , $workbenchId ],
[ 'userId' , '=' , $userId ],
[ 'type' , '=' , self :: TYPE_GROUP_PUSH ],
[ 'isDel' , '=' , 0 ]
]) -> find ();
if ( empty ( $workbench )) {
return json ([ 'code' => 404 , 'msg' => '工作台不存在' ]);
}
}
// 计算时间范围
$days = intval ( $timeRange );
$startTime = strtotime ( date ( 'Y-m-d 00:00:00' , strtotime ( " - { $days } days " )));
$endTime = time ();
// 构建查询条件
$where = [
[ 'wgpi.createTime' , '>=' , $startTime ],
[ 'wgpi.createTime' , '<=' , $endTime ]
];
// 如果指定了工作台ID, 则限制查询范围
if ( ! empty ( $workbenchId )) {
$where [] = [ 'wgpi.workbenchId' , '=' , $workbenchId ];
} else {
// 如果没有指定工作台ID, 则查询当前用户的所有群推送工作台
$workbenchIds = Workbench :: where ([
[ 'userId' , '=' , $userId ],
[ 'type' , '=' , self :: TYPE_GROUP_PUSH ],
[ 'isDel' , '=' , 0 ]
]) -> column ( 'id' );
if ( empty ( $workbenchIds )) {
// 如果没有工作台,返回空结果
$workbenchIds = [ - 1 ];
}
$where [] = [ 'wgpi.workbenchId' , 'in' , $workbenchIds ];
}
// 话术组筛选 - 先获取符合条件的内容ID列表
$contentIds = null ;
if ( ! empty ( $contentLibraryIds )) {
$libraryIds = is_array ( $contentLibraryIds ) ? $contentLibraryIds : explode ( ',' , $contentLibraryIds );
$libraryIds = array_filter ( array_map ( 'intval' , $libraryIds ));
if ( ! empty ( $libraryIds )) {
// 查询符合条件的内容ID
$contentIds = Db :: name ( 'content_item' )
-> whereIn ( 'libraryId' , $libraryIds )
-> column ( 'id' );
if ( empty ( $contentIds )) {
// 如果没有符合条件的内容,返回空结果
$contentIds = [ - 1 ]; // 使用不存在的ID, 确保查询结果为空
}
}
}
// 1. 基础统计:触达率、回复率、平均回复时间、链接点击率
$stats = $this -> calculateBasicStats ( $workbenchId , $where , $startTime , $endTime , $contentIds );
// 2. 话术组对比
$contentLibraryComparison = $this -> getContentLibraryComparison ( $workbenchId , $where , $startTime , $endTime , $contentIds );
// 3. 时段分析
$timePeriodAnalysis = $this -> getTimePeriodAnalysis ( $workbenchId , $where , $startTime , $endTime , $contentIds );
// 4. 互动深度(可选,需要更多数据)
$interactionDepth = $this -> getInteractionDepth ( $workbenchId , $where , $startTime , $endTime , $contentIds );
return json ([
'code' => 200 ,
'msg' => '获取成功' ,
'data' => [
'basicStats' => $stats ,
'contentLibraryComparison' => $contentLibraryComparison ,
'timePeriodAnalysis' => $timePeriodAnalysis ,
'interactionDepth' => $interactionDepth
]
]);
}
/**
* 计算基础统计数据
*/
private function calculateBasicStats ( $workbenchId , $where , $startTime , $endTime , $contentIds = null )
{
// 获取工作台配置,计算计划发送数
// 如果 workbenchId 为空,则查询所有工作台的配置
$configQuery = WorkbenchGroupPush :: alias ( 'wgp' )
-> join ( 'workbench w' , 'w.id = wgp.workbenchId' , 'left' )
-> where ( 'w.type' , self :: TYPE_GROUP_PUSH )
-> where ( 'w.isDel' , 0 );
if ( ! empty ( $workbenchId )) {
$configQuery -> where ( 'wgp.workbenchId' , $workbenchId );
} else {
// 如果没有指定工作台ID, 需要从 where 条件中获取 workbenchId 列表
$workbenchIdCondition = null ;
foreach ( $where as $condition ) {
if ( is_array ( $condition ) && isset ( $condition [ 0 ]) && $condition [ 0 ] === 'wgpi.workbenchId' ) {
if ( $condition [ 1 ] === 'in' && is_array ( $condition [ 2 ])) {
$workbenchIdCondition = $condition [ 2 ];
break ;
} elseif ( $condition [ 1 ] === '=' ) {
$workbenchIdCondition = [ $condition [ 2 ]];
break ;
}
}
}
if ( $workbenchIdCondition ) {
$configQuery -> whereIn ( 'wgp.workbenchId' , $workbenchIdCondition );
}
}
$configs = $configQuery -> select ();
$targetType = 1 ; // 默认值
if ( ! empty ( $configs )) {
// 如果只有一个配置,使用它的 targetType; 如果有多个, 默认使用1
$targetType = intval ( $configs [ 0 ] -> targetType ? ? 1 );
}
// 计划发送数(根据配置计算)
$plannedSend = 0 ;
if ( ! empty ( $configs )) {
$days = ceil (( $endTime - $startTime ) / 86400 );
foreach ( $configs as $config ) {
$maxPerDay = intval ( $config -> maxPerDay ? ? 0 );
$configTargetType = intval ( $config -> targetType ? ? 1 );
if ( $configTargetType == 1 ) {
// 群推送:计划发送数 = 每日推送次数 * 天数 * 群数量
$groups = $this -> decodeJsonArray ( $config -> groups ? ? []);
$plannedSend += $maxPerDay * $days * count ( $groups );
} else {
// 好友推送:计划发送数 = 每日推送人数 * 天数
$plannedSend += $maxPerDay * $days ;
}
}
}
// 构建查询条件
$queryWhere = $where ;
if ( $contentIds !== null ) {
$queryWhere [] = [ 'wgpi.contentId' , 'in' , $contentIds ];
}
// 实际成功发送数(从推送记录表统计)
$successSend = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $queryWhere )
-> count ();
// 触达率 = 成功发送数 / 计划发送数
$reachRate = $plannedSend > 0 ? round (( $successSend / $plannedSend ) * 100 , 1 ) : 0 ;
// 获取发送记录列表,用于查询回复
$sentItemIds = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $queryWhere )
-> field ( 'wgpi.id, wgpi.groupId, wgpi.friendId, wgpi.wechatAccountId, wgpi.createTime, wgpi.targetType, wgpi.contentId' )
-> select ();
// 回复统计(通过消息表查询)
$replyStats = $this -> calculateReplyStats ( $sentItemIds , $targetType , $startTime , $endTime );
// 链接点击统计
$clickStats = $this -> calculateClickStats ( $sentItemIds , $targetType , $startTime , $endTime );
// 计算本月对比数据(简化处理,实际应该查询上个月同期数据)
$currentMonthStart = strtotime ( date ( 'Y-m-01 00:00:00' ));
$lastMonthStart = strtotime ( date ( 'Y-m-01 00:00:00' , strtotime ( '-1 month' )));
$lastMonthEnd = $currentMonthStart - 1 ;
// 获取本月统计数据(避免递归调用)
$currentMonthWhere = [
[ 'wgpi.createTime' , '>=' , $currentMonthStart ]
];
// 复制 workbenchId 条件
foreach ( $where as $condition ) {
if ( is_array ( $condition ) && isset ( $condition [ 0 ]) && $condition [ 0 ] === 'wgpi.workbenchId' ) {
$currentMonthWhere [] = $condition ;
break ;
}
}
if ( $contentIds !== null ) {
$currentMonthWhere [] = [ 'wgpi.contentId' , 'in' , $contentIds ];
}
$currentMonthSend = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $currentMonthWhere )
-> count ();
// 获取本月配置
$currentMonthConfigQuery = WorkbenchGroupPush :: alias ( 'wgp' )
-> join ( 'workbench w' , 'w.id = wgp.workbenchId' , 'left' )
-> where ( 'w.type' , self :: TYPE_GROUP_PUSH )
-> where ( 'w.isDel' , 0 );
if ( ! empty ( $workbenchId )) {
$currentMonthConfigQuery -> where ( 'wgp.workbenchId' , $workbenchId );
} else {
foreach ( $where as $condition ) {
if ( is_array ( $condition ) && isset ( $condition [ 0 ]) && $condition [ 0 ] === 'wgpi.workbenchId' && $condition [ 1 ] === 'in' ) {
$currentMonthConfigQuery -> whereIn ( 'wgp.workbenchId' , $condition [ 2 ]);
break ;
}
}
}
$currentMonthConfigs = $currentMonthConfigQuery -> select ();
$currentMonthPlanned = 0 ;
if ( ! empty ( $currentMonthConfigs )) {
$currentMonthDays = ceil (( $endTime - $currentMonthStart ) / 86400 );
foreach ( $currentMonthConfigs as $currentMonthConfig ) {
$currentMonthMaxPerDay = intval ( $currentMonthConfig -> maxPerDay ? ? 0 );
$currentMonthTargetType = intval ( $currentMonthConfig -> targetType ? ? 1 );
if ( $currentMonthTargetType == 1 ) {
$currentMonthGroups = $this -> decodeJsonArray ( $currentMonthConfig -> groups ? ? []);
$currentMonthPlanned += $currentMonthMaxPerDay * $currentMonthDays * count ( $currentMonthGroups );
} else {
$currentMonthPlanned += $currentMonthMaxPerDay * $currentMonthDays ;
}
}
}
$currentMonthReachRate = $currentMonthPlanned > 0 ? round (( $currentMonthSend / $currentMonthPlanned ) * 100 , 1 ) : 0 ;
// 获取上个月统计数据
$lastMonthWhere = [
[ 'wgpi.createTime' , '>=' , $lastMonthStart ],
[ 'wgpi.createTime' , '<=' , $lastMonthEnd ]
];
// 复制 workbenchId 条件
foreach ( $where as $condition ) {
if ( is_array ( $condition ) && isset ( $condition [ 0 ]) && $condition [ 0 ] === 'wgpi.workbenchId' ) {
$lastMonthWhere [] = $condition ;
break ;
}
}
if ( $contentIds !== null ) {
$lastMonthWhere [] = [ 'wgpi.contentId' , 'in' , $contentIds ];
}
$lastMonthSend = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $lastMonthWhere )
-> count ();
// 获取上个月配置
$lastMonthConfigQuery = WorkbenchGroupPush :: alias ( 'wgp' )
-> join ( 'workbench w' , 'w.id = wgp.workbenchId' , 'left' )
-> where ( 'w.type' , self :: TYPE_GROUP_PUSH )
-> where ( 'w.isDel' , 0 );
if ( ! empty ( $workbenchId )) {
$lastMonthConfigQuery -> where ( 'wgp.workbenchId' , $workbenchId );
} else {
foreach ( $where as $condition ) {
if ( is_array ( $condition ) && isset ( $condition [ 0 ]) && $condition [ 0 ] === 'wgpi.workbenchId' && $condition [ 1 ] === 'in' ) {
$lastMonthConfigQuery -> whereIn ( 'wgp.workbenchId' , $condition [ 2 ]);
break ;
}
}
}
$lastMonthConfigs = $lastMonthConfigQuery -> select ();
$lastMonthPlanned = 0 ;
if ( ! empty ( $lastMonthConfigs )) {
$lastMonthDays = ceil (( $lastMonthEnd - $lastMonthStart ) / 86400 );
foreach ( $lastMonthConfigs as $lastMonthConfig ) {
$lastMonthMaxPerDay = intval ( $lastMonthConfig -> maxPerDay ? ? 0 );
$lastMonthTargetType = intval ( $lastMonthConfig -> targetType ? ? 1 );
if ( $lastMonthTargetType == 1 ) {
$lastMonthGroups = $this -> decodeJsonArray ( $lastMonthConfig -> groups ? ? []);
$lastMonthPlanned += $lastMonthMaxPerDay * $lastMonthDays * count ( $lastMonthGroups );
} else {
$lastMonthPlanned += $lastMonthMaxPerDay * $lastMonthDays ;
}
}
}
$lastMonthReachRate = $lastMonthPlanned > 0 ? round (( $lastMonthSend / $lastMonthPlanned ) * 100 , 1 ) : 0 ;
// 获取上个月的回复和点击统计(简化处理)
$lastMonthSentItems = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $lastMonthWhere )
-> field ( 'wgpi.id, wgpi.groupId, wgpi.friendId, wgpi.wechatAccountId, wgpi.createTime, wgpi.targetType, wgpi.contentId' )
-> select ();
$lastMonthReplyStats = $this -> calculateReplyStats ( $lastMonthSentItems , $targetType , $lastMonthStart , $lastMonthEnd );
$lastMonthClickStats = $this -> calculateClickStats ( $lastMonthSentItems , $targetType , $lastMonthStart , $lastMonthEnd );
return [
'reachRate' => [
'value' => $reachRate ,
'trend' => round ( $reachRate - $lastMonthReachRate , 1 ),
'unit' => '%' ,
'description' => '成功发送/计划发送'
],
'replyRate' => [
'value' => $replyStats [ 'replyRate' ],
'trend' => round ( $replyStats [ 'replyRate' ] - $lastMonthReplyStats [ 'replyRate' ], 1 ),
'unit' => '%' ,
'description' => '收到回复/成功发送'
],
'avgReplyTime' => [
'value' => $replyStats [ 'avgReplyTime' ],
'trend' => round ( $lastMonthReplyStats [ 'avgReplyTime' ] - $replyStats [ 'avgReplyTime' ], 0 ),
'unit' => '分钟' ,
'description' => '从发送到回复的平均时长'
],
'clickRate' => [
'value' => $clickStats [ 'clickRate' ],
'trend' => round ( $clickStats [ 'clickRate' ] - $lastMonthClickStats [ 'clickRate' ], 1 ),
'unit' => '%' ,
'description' => '点击链接/成功发送'
],
'plannedSend' => $plannedSend ,
'successSend' => $successSend ,
'replyCount' => $replyStats [ 'replyCount' ],
'clickCount' => $clickStats [ 'clickCount' ]
];
}
/**
* 计算回复统计
*/
private function calculateReplyStats ( $sentItems , $targetType , $startTime , $endTime )
{
if ( empty ( $sentItems )) {
return [ 'replyRate' => 0 , 'avgReplyTime' => 0 , 'replyCount' => 0 ];
}
$replyCount = 0 ;
$totalReplyTime = 0 ;
$replyTimes = [];
foreach ( $sentItems as $item ) {
$itemArray = is_array ( $item ) ? $item : ( array ) $item ;
$sendTime = $itemArray [ 'createTime' ] ? ? 0 ;
$accountId = $itemArray [ 'wechatAccountId' ] ? ? 0 ;
if ( $targetType == 1 ) {
// 群推送:查找群内回复消息
$groupId = $itemArray [ 'groupId' ] ? ? 0 ;
$group = Db :: name ( 'wechat_group' ) -> where ( 'id' , $groupId ) -> find ();
if ( $group ) {
$replyMsg = Db :: table ( 's2_wechat_message' )
-> where ( 'wechatChatroomId' , $group [ 'chatroomId' ])
-> where ( 'wechatAccountId' , $accountId )
-> where ( 'isSend' , 0 ) // 接收的消息
-> where ( 'wechatTime' , '>' , $sendTime )
-> where ( 'wechatTime' , '<=' , $sendTime + 86400 ) // 24小时内回复
-> order ( 'wechatTime' , 'asc' )
-> find ();
if ( $replyMsg ) {
$replyCount ++ ;
$replyTime = $replyMsg [ 'wechatTime' ] - $sendTime ;
$replyTimes [] = $replyTime ;
$totalReplyTime += $replyTime ;
}
}
} else {
// 好友推送:查找好友回复消息
$friendId = $itemArray [ 'friendId' ] ? ? 0 ;
$friend = Db :: table ( 's2_wechat_friend' ) -> where ( 'id' , $friendId ) -> find ();
if ( $friend ) {
$replyMsg = Db :: table ( 's2_wechat_message' )
-> where ( 'wechatFriendId' , $friendId )
-> where ( 'wechatAccountId' , $accountId )
-> where ( 'isSend' , 0 ) // 接收的消息
-> where ( 'wechatTime' , '>' , $sendTime )
-> where ( 'wechatTime' , '<=' , $sendTime + 86400 ) // 24小时内回复
-> order ( 'wechatTime' , 'asc' )
-> find ();
if ( $replyMsg ) {
$replyCount ++ ;
$replyTime = $replyMsg [ 'wechatTime' ] - $sendTime ;
$replyTimes [] = $replyTime ;
$totalReplyTime += $replyTime ;
}
}
}
}
$successSend = count ( $sentItems );
$replyRate = $successSend > 0 ? round (( $replyCount / $successSend ) * 100 , 1 ) : 0 ;
$avgReplyTime = $replyCount > 0 ? round (( $totalReplyTime / $replyCount ) / 60 , 0 ) : 0 ; // 转换为分钟
return [
'replyRate' => $replyRate ,
'avgReplyTime' => $avgReplyTime ,
'replyCount' => $replyCount
];
}
/**
* 计算链接点击统计
*/
private function calculateClickStats ( $sentItems , $targetType , $startTime , $endTime )
{
if ( empty ( $sentItems )) {
return [ 'clickRate' => 0 , 'clickCount' => 0 ];
}
$clickCount = 0 ;
$linkContentIds = [];
// 获取所有发送的内容ID
foreach ( $sentItems as $item ) {
$itemArray = is_array ( $item ) ? $item : ( array ) $item ;
$contentId = $itemArray [ 'contentId' ] ? ? 0 ;
if ( $contentId > 0 ) {
$linkContentIds [] = $contentId ;
}
}
if ( empty ( $linkContentIds )) {
return [ 'clickRate' => 0 , 'clickCount' => 0 ];
}
// 查询包含链接的内容
$linkContents = Db :: name ( 'content_item' )
-> whereIn ( 'id' , array_unique ( $linkContentIds ))
-> where ( 'contentType' , 2 ) // 链接类型
-> column ( 'id' );
// 统计发送了链接内容的记录数
$linkSendCount = 0 ;
foreach ( $sentItems as $item ) {
$itemArray = is_array ( $item ) ? $item : ( array ) $item ;
$contentId = $itemArray [ 'contentId' ] ? ? 0 ;
if ( in_array ( $contentId , $linkContents )) {
$linkSendCount ++ ;
}
}
// 简化处理:假设点击率基于链接消息的发送(实际应该从点击追踪系统获取)
// 这里可以根据业务需求调整,比如通过消息中的链接点击事件统计
$clickCount = $linkSendCount ; // 简化处理,实际需要真实的点击数据
$successSend = count ( $sentItems );
$clickRate = $successSend > 0 ? round (( $clickCount / $successSend ) * 100 , 1 ) : 0 ;
return [
'clickRate' => $clickRate ,
'clickCount' => $clickCount
];
}
/**
* 获取话术组对比数据
*/
private function getContentLibraryComparison ( $workbenchId , $where , $startTime , $endTime , $contentIds = null )
{
$queryWhere = $where ;
if ( $contentIds !== null ) {
$queryWhere [] = [ 'wgpi.contentId' , 'in' , $contentIds ];
}
$comparison = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> join ( 'content_item ci' , 'ci.id = wgpi.contentId' , 'left' )
-> join ( 'content_library cl' , 'cl.id = ci.libraryId' , 'left' )
-> where ( $queryWhere )
-> where ( 'cl.id' , '<>' , null )
-> field ([
'cl.id as libraryId' ,
'cl.name as libraryName' ,
'COUNT(DISTINCT wgpi.id) as pushCount'
])
-> group ( 'cl.id, cl.name' )
-> select ();
$result = [];
foreach ( $comparison as $item ) {
$libraryId = $item [ 'libraryId' ];
$pushCount = intval ( $item [ 'pushCount' ]);
// 获取该内容库的详细统计
$libraryContentIds = Db :: name ( 'content_item' )
-> where ( 'libraryId' , $libraryId )
-> column ( 'id' );
if ( empty ( $libraryContentIds )) {
$libraryContentIds = [ - 1 ];
}
$libraryWhere = array_merge ( $where , [[ 'wgpi.contentId' , 'in' , $libraryContentIds ]]);
$librarySentItems = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $libraryWhere )
-> field ( 'wgpi.id, wgpi.groupId, wgpi.friendId, wgpi.wechatAccountId, wgpi.createTime, wgpi.targetType, wgpi.contentId' )
-> select ();
$config = WorkbenchGroupPush :: where ( 'workbenchId' , $workbenchId ) -> find ();
$targetType = $config ? intval ( $config -> targetType ) : 1 ;
$replyStats = $this -> calculateReplyStats ( $librarySentItems , $targetType , $startTime , $endTime );
$clickStats = $this -> calculateClickStats ( $librarySentItems , $targetType , $startTime , $endTime );
// 计算转化率(简化处理,实际需要根据业务定义)
$conversionRate = $pushCount > 0 ? round (( $replyStats [ 'replyCount' ] / $pushCount ) * 100 , 1 ) : 0 ;
$result [] = [
'libraryId' => $libraryId ,
'libraryName' => $item [ 'libraryName' ],
'pushCount' => $pushCount ,
'reachRate' => 100 , // 简化处理,实际应该计算
'replyRate' => $replyStats [ 'replyRate' ],
'clickRate' => $clickStats [ 'clickRate' ],
'conversionRate' => $conversionRate ,
'avgReplyTime' => $replyStats [ 'avgReplyTime' ],
'level' => $this -> getPerformanceLevel ( $replyStats [ 'replyRate' ], $clickStats [ 'clickRate' ], $conversionRate )
];
}
// 按回复率排序
usort ( $result , function ( $a , $b ) {
return $b [ 'replyRate' ] <=> $a [ 'replyRate' ];
});
return $result ;
}
/**
* 获取性能等级
*/
private function getPerformanceLevel ( $replyRate , $clickRate , $conversionRate )
{
$score = ( $replyRate * 0.4 ) + ( $clickRate * 0.3 ) + ( $conversionRate * 0.3 );
if ( $score >= 40 ) {
return '优秀' ;
} elseif ( $score >= 25 ) {
return '良好' ;
} elseif ( $score >= 15 ) {
return '一般' ;
} else {
return '待提升' ;
}
}
/**
* 获取时段分析数据
*/
private function getTimePeriodAnalysis ( $workbenchId , $where , $startTime , $endTime , $contentIds = null )
{
$queryWhere = $where ;
if ( $contentIds !== null ) {
$queryWhere [] = [ 'wgpi.contentId' , 'in' , $contentIds ];
}
$analysis = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $queryWhere )
-> field ([
'FROM_UNIXTIME(wgpi.createTime, "%H") as hour' ,
'COUNT(*) as count'
])
-> group ( 'hour' )
-> order ( 'hour' , 'asc' )
-> select ();
$result = [];
foreach ( $analysis as $item ) {
$result [] = [
'hour' => intval ( $item [ 'hour' ]),
'count' => intval ( $item [ 'count' ])
];
}
return $result ;
}
/**
* 获取互动深度数据
*/
private function getInteractionDepth ( $workbenchId , $where , $startTime , $endTime , $contentIds = null )
{
// 简化处理,实际需要更复杂的统计逻辑
return [
'singleReply' => 0 , // 单次回复
'multipleReply' => 0 , // 多次回复
'deepInteraction' => 0 // 深度互动
];
}
/**
* 获取推送历史记录列表
* @ return \think\response\Json
*/
public function getGroupPushHistory ()
{
$page = $this -> request -> param ( 'page' , 1 );
$limit = $this -> request -> param ( 'limit' , 10 );
$workbenchId = $this -> request -> param ( 'workbenchId' , 0 );
$keyword = $this -> request -> param ( 'keyword' , '' );
2025-11-20 16:07:57 +08:00
$pushType = $this -> request -> param ( 'pushType' , '' ); // 推送类型筛选:''=全部, 'friend'=好友消息, 'group'=群消息, 'announcement'=群公告
$status = $this -> request -> param ( 'status' , '' ); // 状态筛选:''=全部, 'success'=已完成, 'progress'=进行中, 'failed'=失败
2025-11-13 16:10:47 +08:00
$userId = $this -> request -> userInfo [ 'id' ];
// 构建工作台查询条件
$workbenchWhere = [
[ 'w.userId' , '=' , $userId ],
[ 'w.type' , '=' , self :: TYPE_GROUP_PUSH ],
[ 'w.isDel' , '=' , 0 ]
];
// 如果指定了工作台ID, 则验证权限并限制查询范围
if ( ! empty ( $workbenchId )) {
$workbench = Workbench :: where ([
[ 'id' , '=' , $workbenchId ],
[ 'userId' , '=' , $userId ],
[ 'type' , '=' , self :: TYPE_GROUP_PUSH ],
[ 'isDel' , '=' , 0 ]
]) -> find ();
if ( empty ( $workbench )) {
return json ([ 'code' => 404 , 'msg' => '工作台不存在' ]);
}
$workbenchWhere [] = [ 'w.id' , '=' , $workbenchId ];
}
2025-11-20 16:07:57 +08:00
// 1. 先查询所有已执行的推送记录(按推送时间分组)
$pushHistoryQuery = Db :: name ( 'workbench_group_push_item' )
2025-11-13 16:10:47 +08:00
-> alias ( 'wgpi' )
-> join ( 'workbench w' , 'w.id = wgpi.workbenchId' , 'left' )
2025-11-20 16:07:57 +08:00
-> join ( 'workbench_group_push wgp' , 'wgp.workbenchId = wgpi.workbenchId' , 'left' )
2025-11-13 16:10:47 +08:00
-> join ( 'content_item ci' , 'ci.id = wgpi.contentId' , 'left' )
-> join ( 'content_library cl' , 'cl.id = ci.libraryId' , 'left' )
-> where ( $workbenchWhere )
-> field ([
'wgpi.workbenchId' ,
'w.name as workbenchName' ,
'wgpi.contentId' ,
'FROM_UNIXTIME(wgpi.createTime, "%Y-%m-%d %H:00:00") as pushTime' ,
'wgpi.targetType' ,
2025-11-20 16:07:57 +08:00
'wgp.groupPushSubType' ,
2025-11-13 16:10:47 +08:00
'MIN(wgpi.createTime) as createTime' ,
'COUNT(DISTINCT wgpi.id) as totalCount' ,
'cl.name as contentLibraryName'
])
2025-11-20 16:07:57 +08:00
-> group ( 'wgpi.workbenchId, wgpi.contentId, pushTime, wgpi.targetType, wgp.groupPushSubType' );
2025-11-13 16:10:47 +08:00
if ( ! empty ( $keyword )) {
2025-11-20 16:07:57 +08:00
$pushHistoryQuery -> where ( 'w.name|cl.name|ci.content' , 'like' , '%' . $keyword . '%' );
2025-11-13 16:10:47 +08:00
}
2025-11-20 16:07:57 +08:00
$pushHistoryList = $pushHistoryQuery -> order ( 'createTime' , 'desc' ) -> select ();
// 2. 查询所有任务(包括未执行的)
$allTasksQuery = Db :: name ( 'workbench' )
-> alias ( 'w' )
-> join ( 'workbench_group_push wgp' , 'wgp.workbenchId = w.id' , 'left' )
-> where ( $workbenchWhere )
-> field ([
'w.id as workbenchId' ,
'w.name as workbenchName' ,
'w.createTime' ,
'wgp.targetType' ,
'wgp.groupPushSubType' ,
'wgp.groups' ,
'wgp.friends' ,
'wgp.trafficPools'
]);
2025-11-13 16:10:47 +08:00
if ( ! empty ( $keyword )) {
2025-11-20 16:07:57 +08:00
$allTasksQuery -> where ( 'w.name' , 'like' , '%' . $keyword . '%' );
2025-11-13 16:10:47 +08:00
}
2025-11-20 16:07:57 +08:00
$allTasks = $allTasksQuery -> select ();
// 3. 合并数据:已执行的推送记录 + 未执行的任务
$resultList = [];
$executedWorkbenchIds = [];
// 处理已执行的推送记录
foreach ( $pushHistoryList as $item ) {
2025-11-13 16:10:47 +08:00
$itemWorkbenchId = $item [ 'workbenchId' ];
$contentId = $item [ 'contentId' ];
$pushTime = $item [ 'pushTime' ];
$targetType = intval ( $item [ 'targetType' ]);
2025-11-20 16:07:57 +08:00
$groupPushSubType = isset ( $item [ 'groupPushSubType' ]) ? intval ( $item [ 'groupPushSubType' ]) : 1 ;
// 标记该工作台已有执行记录
if ( ! in_array ( $itemWorkbenchId , $executedWorkbenchIds )) {
$executedWorkbenchIds [] = $itemWorkbenchId ;
}
2025-11-13 16:10:47 +08:00
// 将时间字符串转换为时间戳范围(小时级别)
$pushTimeStart = strtotime ( $pushTime );
$pushTimeEnd = $pushTimeStart + 3600 ; // 一小时后
// 获取该次推送的详细统计
$pushWhere = [
[ 'wgpi.workbenchId' , '=' , $itemWorkbenchId ],
[ 'wgpi.contentId' , '=' , $contentId ],
[ 'wgpi.createTime' , '>=' , $pushTimeStart ],
[ 'wgpi.createTime' , '<' , $pushTimeEnd ],
[ 'wgpi.targetType' , '=' , $targetType ]
];
// 目标数量
if ( $targetType == 1 ) {
// 群推送:统计群数量
$targetCount = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $pushWhere )
-> where ( 'wgpi.groupId' , '<>' , null )
-> distinct ( true )
-> count ( 'wgpi.groupId' );
} else {
// 好友推送:统计好友数量
$targetCount = Db :: name ( 'workbench_group_push_item' )
-> alias ( 'wgpi' )
-> where ( $pushWhere )
-> where ( 'wgpi.friendId' , '<>' , null )
-> distinct ( true )
-> count ( 'wgpi.friendId' );
}
// 成功数和失败数(简化处理,实际需要根据发送状态判断)
$successCount = intval ( $item [ 'totalCount' ]); // 简化处理
$failCount = 0 ; // 简化处理,实际需要从发送状态获取
// 状态判断
2025-11-20 16:07:57 +08:00
$itemStatus = $successCount > 0 ? 'success' : 'failed' ;
2025-11-13 16:10:47 +08:00
if ( $failCount > 0 && $successCount > 0 ) {
2025-11-20 16:07:57 +08:00
$itemStatus = 'partial' ;
2025-11-13 16:10:47 +08:00
}
2025-11-20 16:07:57 +08:00
// 推送类型判断
$pushTypeText = '' ;
$pushTypeCode = '' ;
if ( $targetType == 1 ) {
// 群推送
if ( $groupPushSubType == 2 ) {
$pushTypeText = '群公告' ;
$pushTypeCode = 'announcement' ;
} else {
$pushTypeText = '群消息' ;
$pushTypeCode = 'group' ;
}
} else {
// 好友推送
$pushTypeText = '好友消息' ;
$pushTypeCode = 'friend' ;
}
$resultList [] = [
'workbenchId' => $itemWorkbenchId ,
'taskName' => $item [ 'workbenchName' ] ? ? '' ,
'pushType' => $pushTypeText ,
'pushTypeCode' => $pushTypeCode ,
'targetCount' => $targetCount ,
'successCount' => $successCount ,
'failCount' => $failCount ,
'status' => $itemStatus ,
'statusText' => $this -> getStatusText ( $itemStatus ),
'createTime' => date ( 'Y-m-d H:i:s' , $item [ 'createTime' ]),
'contentLibraryName' => $item [ 'contentLibraryName' ] ? ? ''
];
2025-11-13 16:10:47 +08:00
}
2025-11-20 16:07:57 +08:00
// 处理未执行的任务
foreach ( $allTasks as $task ) {
$taskWorkbenchId = $task [ 'workbenchId' ];
// 如果该任务已有执行记录,跳过(避免重复)
if ( in_array ( $taskWorkbenchId , $executedWorkbenchIds )) {
continue ;
}
$targetType = isset ( $task [ 'targetType' ]) ? intval ( $task [ 'targetType' ]) : 1 ;
$groupPushSubType = isset ( $task [ 'groupPushSubType' ]) ? intval ( $task [ 'groupPushSubType' ]) : 1 ;
// 计算目标数量(从配置中获取)
$targetCount = 0 ;
if ( $targetType == 1 ) {
// 群推送:统计配置的群数量
$groups = json_decode ( $task [ 'groups' ] ? ? '[]' , true );
$targetCount = is_array ( $groups ) ? count ( $groups ) : 0 ;
} else {
// 好友推送:统计配置的好友数量或流量池数量
$friends = json_decode ( $task [ 'friends' ] ? ? '[]' , true );
$trafficPools = json_decode ( $task [ 'trafficPools' ] ? ? '[]' , true );
$friendCount = is_array ( $friends ) ? count ( $friends ) : 0 ;
$poolCount = is_array ( $trafficPools ) ? count ( $trafficPools ) : 0 ;
// 如果配置了流量池,目标数量暂时显示为流量池数量(实际数量需要从流量池中统计)
$targetCount = $friendCount > 0 ? $friendCount : $poolCount ;
}
// 推送类型判断
$pushTypeText = '' ;
$pushTypeCode = '' ;
if ( $targetType == 1 ) {
// 群推送
if ( $groupPushSubType == 2 ) {
$pushTypeText = '群公告' ;
$pushTypeCode = 'announcement' ;
} else {
$pushTypeText = '群消息' ;
$pushTypeCode = 'group' ;
}
} else {
// 好友推送
$pushTypeText = '好友消息' ;
$pushTypeCode = 'friend' ;
}
$resultList [] = [
'workbenchId' => $taskWorkbenchId ,
'taskName' => $task [ 'workbenchName' ] ? ? '' ,
'pushType' => $pushTypeText ,
'pushTypeCode' => $pushTypeCode ,
'targetCount' => $targetCount ,
'successCount' => 0 ,
'failCount' => 0 ,
'status' => 'pending' ,
'statusText' => '进行中' ,
'createTime' => date ( 'Y-m-d H:i:s' , $task [ 'createTime' ]),
'contentLibraryName' => ''
];
}
// 应用筛选条件
$filteredList = [];
foreach ( $resultList as $item ) {
// 推送类型筛选
if ( ! empty ( $pushType )) {
if ( $pushType === 'friend' && $item [ 'pushTypeCode' ] !== 'friend' ) {
continue ;
}
if ( $pushType === 'group' && $item [ 'pushTypeCode' ] !== 'group' ) {
continue ;
}
if ( $pushType === 'announcement' && $item [ 'pushTypeCode' ] !== 'announcement' ) {
continue ;
}
}
// 状态筛选
if ( ! empty ( $status )) {
if ( $status === 'success' && $item [ 'status' ] !== 'success' ) {
continue ;
}
if ( $status === 'progress' ) {
// 进行中:包括 partial 和 pending
if ( $item [ 'status' ] !== 'partial' && $item [ 'status' ] !== 'pending' ) {
continue ;
}
}
if ( $status === 'failed' && $item [ 'status' ] !== 'failed' ) {
continue ;
}
}
$filteredList [] = $item ;
}
// 按创建时间倒序排序
usort ( $filteredList , function ( $a , $b ) {
return strtotime ( $b [ 'createTime' ]) - strtotime ( $a [ 'createTime' ]);
});
// 分页处理
$total = count ( $filteredList );
$offset = ( $page - 1 ) * $limit ;
$list = array_slice ( $filteredList , $offset , $limit );
2025-11-13 16:10:47 +08:00
return json ([
'code' => 200 ,
'msg' => '获取成功' ,
'data' => [
'list' => $list ,
'total' => $total ,
'page' => $page ,
'limit' => $limit
]
]);
}
2025-11-20 16:07:57 +08:00
/**
* 获取状态文本
* @ param string $status 状态码
* @ return string 状态文本
*/
private function getStatusText ( $status )
{
$statusMap = [
'success' => '已完成' ,
'partial' => '进行中' ,
'pending' => '进行中' ,
'failed' => '失败'
];
return $statusMap [ $status ] ? ? '未知' ;
}
2025-09-12 10:25:19 +08:00
2025-08-12 09:28:57 +08:00
}