Files
cunkebao_v3/Server/application/cunkebao/controller/WorkbenchController.php
2025-11-07 15:25:50 +08:00

1911 lines
82 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\cunkebao\controller;
use app\common\model\Device as DeviceModel;
use app\common\model\DeviceWechatLogin as DeviceWechatLoginModel;
use app\common\model\WechatCustomer as WechatCustomerModel;
use app\cunkebao\model\Workbench;
use app\cunkebao\model\WorkbenchAutoLike;
use app\cunkebao\model\WorkbenchImportContact;
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;
use app\cunkebao\model\WorkbenchTrafficConfig;
use app\cunkebao\model\ContentLibrary;
use think\facade\Env;
/**
* 工作台控制器
*/
class WorkbenchController extends Controller
{
/**
* 工作台类型定义
*/
const TYPE_AUTO_LIKE = 1; // 自动点赞
const TYPE_MOMENTS_SYNC = 2; // 朋友圈同步
const TYPE_GROUP_PUSH = 3; // 群消息推送
const TYPE_GROUP_CREATE = 4; // 自动建群
const TYPE_TRAFFIC_DISTRIBUTION = 5; // 流量分发
const TYPE_IMPORT_CONTACT = 6; // 联系人导入
/**
* 创建工作台
* @return \think\response\Json
*/
public function create()
{
if (!$this->request->isPost()) {
return json(['code' => 400, 'msg' => '请求方式错误']);
}
// 获取登录用户信息
$userInfo = request()->userInfo;
// 获取请求参数
$param = $this->request->post();
// 验证数据
$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'];
$workbench->status = !empty($param['status']) ? 1 : 0;
$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']);
$config->devices = json_encode($param['deviceGroups']);
$config->friends = json_encode($param['friendsGroups']);
// $config->targetGroups = json_encode($param['targetGroups']);
// $config->tagOperator = $param['tagOperator'];
$config->friendMaxLikes = $param['friendMaxLikes'];
$config->friendTags = $param['friendTags'];
$config->enableFriendTags = $param['enableFriendTags'];
$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'];
$config->startTime = $param['startTime'];
$config->endTime = $param['endTime'];
$config->accountType = $param['accountType'];
$config->devices = json_encode($param['deviceGroups']);
$config->contentLibraries = json_encode($param['contentGroups'] ?? []);
$config->createTime = time();
$config->updateTime = time();
$config->save();
break;
case self::TYPE_GROUP_PUSH: // 群消息推送
$config = new WorkbenchGroupPush;
$config->workbenchId = $workbench->id;
$config->pushType = !empty($param['pushType']) ? 1 : 0; // 推送方式:定时/立即
$config->targetType = !empty($param['targetType']) ? intval($param['targetType']) : 1; // 推送目标类型1=群推送2=好友推送
$config->startTime = $param['startTime'];
$config->endTime = $param['endTime'];
$config->maxPerDay = intval($param['maxPerDay']); // 每日推送数
$config->pushOrder = $param['pushOrder']; // 推送顺序
// 根据targetType存储不同的数据
if ($config->targetType == 1) {
// 群推送
$config->isLoop = !empty($param['isLoop']) ? 1 : 0; // 是否循环
$config->groups = json_encode($param['wechatGroups'] ?? [], JSON_UNESCAPED_UNICODE); // 群组信息
$config->friends = json_encode([], JSON_UNESCAPED_UNICODE); // 好友信息为空数组
$config->devices = json_encode([], JSON_UNESCAPED_UNICODE); // 群推送不需要设备
} else {
// 好友推送isLoop必须为0设备必填
$config->isLoop = 0; // 好友推送时强制为0
$config->friends = json_encode($param['wechatFriends'] ?? [], JSON_UNESCAPED_UNICODE); // 好友信息(可以为空数组)
$config->groups = json_encode([], JSON_UNESCAPED_UNICODE); // 群组信息为空数组
$config->devices = json_encode($param['deviceGroups'] ?? [], JSON_UNESCAPED_UNICODE); // 设备信息(必填)
}
$config->status = !empty($param['status']) ? 1 : 0; // 是否启用
$config->contentLibraries = json_encode($param['contentGroups'], JSON_UNESCAPED_UNICODE); // 内容库信息
$config->socialMediaId = !empty($param['socialMediaId']) ? $param['socialMediaId'] : '';
$config->promotionSiteId = !empty($param['promotionSiteId']) ? $param['promotionSiteId'] : '';
$config->createTime = time();
$config->updateTime = time();
$config->save();
break;
case self::TYPE_GROUP_CREATE: // 自动建群
$config = new WorkbenchGroupCreate;
$config->workbenchId = $workbench->id;
$config->devices = json_encode($param['deviceGroups'], JSON_UNESCAPED_UNICODE);
$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'];
$config->poolGroups = json_encode($param['poolGroups'] ?? []);
$config->wechatGroups = json_encode($param['wechatGroups'] ?? []);
$config->createTime = time();
$config->updateTime = time();
$config->save();
break;
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'];
$config->devices = json_encode($param['deviceGroups'], JSON_UNESCAPED_UNICODE);
$config->pools = json_encode($param['poolGroups'], JSON_UNESCAPED_UNICODE);
$config->account = json_encode($param['accountGroups'], JSON_UNESCAPED_UNICODE);
$config->createTime = time();
$config->updateTime = time();
$config->save();
break;
case self::TYPE_IMPORT_CONTACT: //联系人导入
$config = new WorkbenchImportContact;
$config->workbenchId = $workbench->id;
$config->devices = json_encode($param['deviceGroups'], JSON_UNESCAPED_UNICODE);
$config->pools = json_encode($param['poolGroups'], JSON_UNESCAPED_UNICODE);
$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;
}
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', '');
$keyword = $this->request->param('keyword', '');
$where = [
['userId', '=', $this->request->userInfo['id']],
['isDel', '=', 0]
];
// 添加类型筛选
if ($type !== '') {
$where[] = ['type', '=', $type];
}
// 添加名称模糊搜索
if ($keyword !== '') {
$where[] = ['name', 'like', '%' . $keyword . '%'];
}
// 定义关联关系
$with = [
'autoLike' => function ($query) {
$query->field('workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,friends');
},
'momentsSync' => function ($query) {
$query->field('workbenchId,syncInterval,syncCount,syncType,startTime,endTime,accountType,devices,contentLibraries');
},
'trafficConfig' => function ($query) {
$query->field('workbenchId,distributeType,maxPerDay,timeType,startTime,endTime,devices,pools,account');
},
'groupPush' => function ($query) {
$query->field('workbenchId,pushType,targetType,startTime,endTime,maxPerDay,pushOrder,isLoop,status,groups,friends,devices,contentLibraries');
},
'groupCreate' => function($query) {
$query->field('workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription,poolGroups,wechatGroups');
},
'importContact' => function($query) {
$query->field('workbenchId,devices,pools,num,remarkType,remark,clearContact,startTime,endTime');
},
'user' => function ($query) {
$query->field('id,username');
}
];
$list = Workbench::where($where)
->with($with)
->field('id,companyId,name,type,status,autoStart,userId,createTime,updateTime')
->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);
$item->config->contentTypes = json_decode($item->config->contentTypes, true);
$item->config->friends = json_decode($item->config->friends, true);
// 添加今日点赞数
$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();
// 添加总点赞数
$totalLikeCount = Db::name('workbench_auto_like_item')
->where('workbenchId', $item->id)
->count();
$item->config->todayLikeCount = $todayLikeCount;
$item->config->totalLikeCount = $totalLikeCount;
}
unset($item->autoLike, $item->auto_like);
break;
case self::TYPE_MOMENTS_SYNC:
if (!empty($item->momentsSync)) {
$item->config = $item->momentsSync;
$item->config->devices = json_decode($item->config->devices, true);
$item->config->contentGroups = json_decode($item->config->contentLibraries, true);
//同步记录
$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');
$item->lastSyncTime = !empty($lastTime) ? date('Y-m-d H:i', $lastTime) : '--';
// 获取内容库名称
if (!empty($item->config->contentGroups)) {
$libraryNames = ContentLibrary::where('id', 'in', $item->config->contentGroups)->select();
$item->config->contentGroupsOptions = $libraryNames;
} else {
$item->config->contentGroupsOptions = [];
}
}
unset($item->momentsSync, $item->moments_sync,$item->config->contentLibraries);
break;
case self::TYPE_GROUP_PUSH:
if (!empty($item->groupPush)) {
$item->config = $item->groupPush;
$item->config->pushType = $item->config->pushType;
$item->config->targetType = isset($item->config->targetType) ? intval($item->config->targetType) : 1; // 默认1=群推送
$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;
// 根据targetType解析不同的数据
if ($item->config->targetType == 1) {
// 群推送
$item->config->wechatGroups = json_decode($item->config->groups, true) ?: [];
$item->config->wechatFriends = [];
$item->config->deviceGroups = [];
} else {
// 好友推送
$item->config->wechatFriends = json_decode($item->config->friends, true) ?: [];
$item->config->wechatGroups = [];
$item->config->deviceGroups = json_decode($item->config->devices ?? '[]', true) ?: [];
}
$item->config->contentLibraries = json_decode($item->config->contentLibraries, true);
$item->config->lastPushTime = '';
}
unset($item->groupPush, $item->group_push);
break;
case self::TYPE_GROUP_CREATE:
if (!empty($item->groupCreate)) {
$item->config = $item->groupCreate;
$item->config->devices = json_decode($item->config->devices, true);
$item->config->poolGroups = json_decode($item->config->poolGroups, true);
$item->config->wechatGroups = json_decode($item->config->wechatGroups, true);
}
unset($item->groupCreate, $item->group_create);
break;
case self::TYPE_TRAFFIC_DISTRIBUTION:
if (!empty($item->trafficConfig)) {
$item->config = $item->trafficConfig;
$item->config->devices = json_decode($item->config->devices, true);
$item->config->poolGroups = json_decode($item->config->pools, true);
$item->config->account = json_decode($item->config->account, true);
$config_item = Db::name('workbench_traffic_config_item')->where(['workbenchId' => $item->id])->order('id DESC')->find();
$item->config->lastUpdated = !empty($config_item) ? date('Y-m-d H:i', $config_item['createTime']) : '--';
//统计
$labels = $item->config->poolGroups;
$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]
])
->whereIn('wa.currentDeviceId', $item->config->devices);
if (!empty($labels) && count($labels) > 0) {
$totalUsers = $totalUsers->where(function ($q) use ($labels) {
foreach ($labels as $label) {
$q->whereOrRaw("JSON_CONTAINS(wf.labels, '\"{$label}\"')");
}
});
}
$totalUsers = $totalUsers->count();
$totalAccounts = count($item->config->account);
$dailyAverage = Db::name('workbench_traffic_config_item')
->where('workbenchId', $item->id)
->count();
$day = (time() - strtotime($item->createTime)) / 86400;
$day = intval($day);
if ($dailyAverage > 0 && $totalAccounts > 0 && $day > 0) {
$dailyAverage = $dailyAverage / $totalAccounts / $day;
}
$item->config->total = [
'dailyAverage' => intval($dailyAverage),
'totalAccounts' => $totalAccounts,
'deviceCount' => count($item->config->devices),
'poolCount' => !empty($item->config->poolGroups) ? count($item->config->poolGroups) : 'ALL',
'totalUsers' => $totalUsers >> 0
];
}
unset($item->trafficConfig, $item->traffic_config);
break;
case self::TYPE_IMPORT_CONTACT:
if (!empty($item->importContact)) {
$item->config = $item->importContact;
$item->config->devices = json_decode($item->config->devices, true);
$item->config->poolGroups = json_decode($item->config->pools, true);
}
unset($item->importContact, $item->import_contact);
break;
}
// 添加创建人名称
$item['creatorName'] = $item->user ? $item->user->username : '';
unset($item['user']); // 移除关联数据
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
*/
public function detail()
{
$id = $this->request->param('id', '');
if (empty($id)) {
return json(['code' => 400, 'msg' => '参数错误']);
}
// 定义关联关系
$with = [
'autoLike' => function ($query) {
$query->field('workbenchId,interval,maxLikes,startTime,endTime,contentTypes,devices,friends,friendMaxLikes,friendTags,enableFriendTags');
},
'momentsSync' => function ($query) {
$query->field('workbenchId,syncInterval,syncCount,syncType,startTime,endTime,accountType,devices,contentLibraries');
},
'trafficConfig' => function ($query) {
$query->field('workbenchId,distributeType,maxPerDay,timeType,startTime,endTime,devices,pools,account');
},
'groupPush' => function ($query) {
$query->field('workbenchId,pushType,targetType,startTime,endTime,maxPerDay,pushOrder,isLoop,status,groups,friends,devices,contentLibraries');
},
'groupCreate' => function($query) {
$query->field('workbenchId,devices,startTime,endTime,groupSizeMin,groupSizeMax,maxGroupsPerDay,groupNameTemplate,groupDescription,poolGroups,wechatGroups');
},
'importContact' => function($query) {
$query->field('workbenchId,devices,pools,num,remarkType,remark,clearContact,startTime,endTime');
},
];
$workbench = Workbench::where([
['id', '=', $id],
['userId', '=', $this->request->userInfo['id']],
['isDel', '=', 0]
])
->field('id,name,type,status,autoStart,createTime,updateTime,companyId')
->with($with)
->find();
if (empty($workbench)) {
return json(['code' => 404, 'msg' => '工作台不存在']);
}
// 处理配置信息
switch ($workbench->type) {
//自动点赞
case self::TYPE_AUTO_LIKE:
if (!empty($workbench->autoLike)) {
$workbench->config = $workbench->autoLike;
$workbench->config->deviceGroups = json_decode($workbench->config->devices, true);
$workbench->config->friendsGroups = json_decode($workbench->config->friends, true);
//$workbench->config->targetGroups = json_decode($workbench->config->targetGroups, true);
$workbench->config->contentTypes = json_decode($workbench->config->contentTypes, true);
// 添加今日点赞数
$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();
// 添加总点赞数
$totalLikeCount = Db::name('workbench_auto_like_item')
->where('workbenchId', $workbench->id)
->count();
$workbench->config->todayLikeCount = $todayLikeCount;
$workbench->config->totalLikeCount = $totalLikeCount;
unset($workbench->autoLike, $workbench->auto_like);
}
break;
//自动同步朋友圈
case self::TYPE_MOMENTS_SYNC:
if (!empty($workbench->momentsSync)) {
$workbench->config = $workbench->momentsSync;
$workbench->config->deviceGroups = json_decode($workbench->config->devices, true);
$workbench->config->contentGroups = json_decode($workbench->config->contentLibraries, true);
//同步记录
$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');
$workbench->lastSyncTime = !empty($lastTime) ? date('Y-m-d H:i', $lastTime) : '--';
unset($workbench->momentsSync, $workbench->moments_sync);
}
break;
//群推送
case self::TYPE_GROUP_PUSH:
if (!empty($workbench->groupPush)) {
$workbench->config = $workbench->groupPush;
$workbench->config->targetType = isset($workbench->config->targetType) ? intval($workbench->config->targetType) : 1; // 默认1=群推送
// 根据targetType解析不同的数据
if ($workbench->config->targetType == 1) {
// 群推送
$workbench->config->wechatGroups = json_decode($workbench->config->groups, true) ?: [];
$workbench->config->wechatFriends = [];
$workbench->config->deviceGroups = [];
} else {
// 好友推送
$workbench->config->wechatFriends = json_decode($workbench->config->friends, true) ?: [];
$workbench->config->wechatGroups = [];
$workbench->config->deviceGroups = json_decode($workbench->config->devices ?? '[]', true) ?: [];
}
$workbench->config->contentLibraries = json_decode($workbench->config->contentLibraries, true);
unset($workbench->groupPush, $workbench->group_push);
}
break;
//建群助手
case self::TYPE_GROUP_CREATE:
if (!empty($workbench->groupCreate)) {
$workbench->config = $workbench->groupCreate;
$workbench->config->deviceGroups = json_decode($workbench->config->devices, true);
$workbench->config->poolGroups = json_decode($workbench->config->poolGroups, true);
$workbench->config->wechatGroups = json_decode($workbench->config->wechatGroups, true);
unset($workbench->groupCreate, $workbench->group_create);
}
break;
//流量分发
case self::TYPE_TRAFFIC_DISTRIBUTION:
if (!empty($workbench->trafficConfig)) {
$workbench->config = $workbench->trafficConfig;
$workbench->config->deviceGroups = json_decode($workbench->config->devices, true);
$workbench->config->accountGroups = json_decode($workbench->config->account, true);
$workbench->config->poolGroups = json_decode($workbench->config->pools, true);
$config_item = Db::name('workbench_traffic_config_item')->where(['workbenchId' => $workbench->id])->order('id DESC')->find();
$workbench->config->lastUpdated = !empty($config_item) ? date('Y-m-d H:i', $config_item['createTime']) : '--';
//统计
$labels = $workbench->config->poolGroups;
$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]
])
->whereIn('wa.currentDeviceId', $workbench->config->deviceGroups)
->field('wf.id,wf.wechatAccountId,wf.wechatId,wf.labels,sa.userName,wa.currentDeviceId as deviceId')
->where(function ($q) use ($labels) {
foreach ($labels as $label) {
$q->whereOrRaw("JSON_CONTAINS(wf.labels, '\"{$label}\"')");
}
})->count();
$totalAccounts = Db::table('s2_company_account')
->alias('a')
->where(['a.departmentId' => $workbench->companyId, 'a.status' => 0])
->whereNotLike('a.userName', '%_offline%')
->whereNotLike('a.userName', '%_delete%')
->group('a.id')
->count();
$dailyAverage = Db::name('workbench_traffic_config_item')
->where('workbenchId', $workbench->id)
->count();
$day = (time() - strtotime($workbench->createTime)) / 86400;
$day = intval($day);
if ($dailyAverage > 0) {
$dailyAverage = $dailyAverage / $totalAccounts / $day;
}
$workbench->config->total = [
'dailyAverage' => intval($dailyAverage),
'totalAccounts' => $totalAccounts,
'deviceCount' => count($workbench->config->deviceGroups),
'poolCount' => count($workbench->config->poolGroups),
'totalUsers' => $totalUsers >> 0
];
unset($workbench->trafficConfig, $workbench->traffic_config);
}
break;
case self::TYPE_IMPORT_CONTACT:
if (!empty($workbench->importContact)) {
$workbench->config = $workbench->importContact;
$workbench->config->deviceGroups = json_decode($workbench->config->devices, true);
$workbench->config->poolGroups = json_decode($workbench->config->pools, true);
}
unset($workbench->importContact, $workbench->import_contact);
break;
}
unset(
$workbench->autoLike,
$workbench->momentsSync,
$workbench->groupPush,
$workbench->groupCreate,
$workbench->config->devices,
$workbench->config->friends,
$workbench->config->groups,
$workbench->config->contentLibraries,
$workbench->config->account,
);
//获取设备信息
if (!empty($workbench->config->deviceGroups)) {
$deviceList = DeviceModel::alias('d')
->field([
'd.id', 'd.imei', 'd.memo', 'd.alive',
'l.wechatId',
'a.nickname', 'a.alias', 'a.avatar', 'a.alias', '0 totalFriend'
])
->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')
->whereIn('d.id', $workbench->config->deviceGroups)
->order('d.id desc')
->select();
foreach ($deviceList as &$device) {
$curstomer = WechatCustomerModel::field('friendShip')->where(['wechatId' => $device['wechatId']])->find();
$device['totalFriend'] = $curstomer->friendShip->totalFriend ?? 0;
}
unset($device);
$workbench->config->deviceGroupsOptions = $deviceList;
} else {
$workbench->config->deviceGroupsOptions = [];
}
// 获取群当targetType=1时
if (!empty($workbench->config->wechatGroups) && isset($workbench->config->targetType) && $workbench->config->targetType == 1){
$groupList = Db::name('wechat_group')->alias('wg')
->join('wechat_account wa', 'wa.wechatId = wg.ownerWechatId')
->where('wg.id', 'in', $workbench->config->wechatGroups)
->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;
}else{
$workbench->config->wechatGroupsOptions = [];
}
// 获取好友当targetType=2时
if (!empty($workbench->config->wechatFriends) && isset($workbench->config->targetType) && $workbench->config->targetType == 2){
$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;
}else{
$workbench->config->wechatFriendsOptions = [];
}
// 获取内容库名称
if (!empty($workbench->config->contentGroups)) {
$libraryNames = ContentLibrary::where('id', 'in', $workbench->config->contentGroups)->select();
$workbench->config->contentGroupsOptions = $libraryNames;
} else {
$workbench->config->contentGroupsOptions = [];
}
//账号
if (!empty($workbench->config->accountGroups)){
$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();
$workbench->config->accountGroupsOptions = $account;
}else{
$workbench->config->accountGroupsOptions = [];
}
if (!empty($workbench->config->poolGroups)){
$poolGroupsOptions = Db::name('traffic_source_package')->alias('tsp')
->join('traffic_source_package_item tspi','tspi.packageId=tsp.id','left')
->whereIn('tsp.companyId', [$this->request->userInfo['companyId'],0])
->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;
}else{
$workbench->config->poolGroupsOptions = [];
}
return json(['code' => 200, 'msg' => '获取成功', 'data' => $workbench]);
}
/**
* 更新工作台
* @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()]);
}
// 查询工作台是否存在
$workbench = Workbench::where([
['id', '=', $param['id']],
['userId', '=', $this->request->userInfo['id']],
['isDel', '=', 0]
])->find();
if (!$workbench) {
return json(['code' => 404, 'msg' => '工作台不存在']);
}
Db::startTrans();
try {
// 更新工作台基本信息
$workbench->name = $param['name'];
$workbench->status = !empty($param['status']) ? 1 : 0;
$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']);
$config->devices = json_encode($param['deviceGroups']);
$config->friends = json_encode($param['friendsGroups']);
// $config->targetGroups = json_encode($param['targetGroups']);
// $config->tagOperator = $param['tagOperator'];
$config->friendMaxLikes = $param['friendMaxLikes'];
$config->friendTags = $param['friendTags'];
$config->enableFriendTags = $param['enableFriendTags'];
$config->updateTime = time();
$config->save();
}
break;
case self::TYPE_MOMENTS_SYNC:
$config = WorkbenchMomentsSync::where('workbenchId', $param['id'])->find();
if ($config) {
if (!empty($param['contentGroups'])) {
foreach ($param['contentGroups'] as $library) {
if (isset($library['id']) && !empty($library['id'])) {
$contentLibraries[] = $library['id'];
} else {
$contentLibraries[] = $library;
}
}
} else {
$contentLibraries = [];
}
$config->syncInterval = $param['syncInterval'];
$config->syncCount = $param['syncCount'];
$config->syncType = $param['syncType'];
$config->startTime = $param['startTime'];
$config->endTime = $param['endTime'];
$config->accountType = $param['accountType'];
$config->devices = json_encode($param['deviceGroups']);
$config->contentLibraries = json_encode($contentLibraries);
$config->updateTime = time();
$config->save();
}
break;
case self::TYPE_GROUP_PUSH:
$config = WorkbenchGroupPush::where('workbenchId', $param['id'])->find();
if ($config) {
$config->pushType = !empty($param['pushType']) ? 1 : 0; // 推送方式:定时/立即
$config->targetType = !empty($param['targetType']) ? intval($param['targetType']) : 1; // 推送目标类型1=群推送2=好友推送
$config->startTime = $param['startTime'];
$config->endTime = $param['endTime'];
$config->maxPerDay = intval($param['maxPerDay']); // 每日推送数
$config->pushOrder = $param['pushOrder']; // 推送顺序
// 根据targetType存储不同的数据
if ($config->targetType == 1) {
// 群推送
$config->isLoop = !empty($param['isLoop']) ? 1 : 0; // 是否循环
$config->groups = json_encode($param['wechatGroups'] ?? [], JSON_UNESCAPED_UNICODE); // 群组信息
$config->friends = json_encode([], JSON_UNESCAPED_UNICODE); // 好友信息为空数组
$config->devices = json_encode([], JSON_UNESCAPED_UNICODE); // 群推送不需要设备
} else {
// 好友推送isLoop必须为0设备必填
$config->isLoop = 0; // 好友推送时强制为0
$config->friends = json_encode($param['wechatFriends'] ?? [], JSON_UNESCAPED_UNICODE); // 好友信息(可以为空数组)
$config->groups = json_encode([], JSON_UNESCAPED_UNICODE); // 群组信息为空数组
$config->devices = json_encode($param['deviceGroups'] ?? [], JSON_UNESCAPED_UNICODE); // 设备信息(必填)
}
$config->status = !empty($param['status']) ? 1 : 0; // 是否启用
$config->contentLibraries = json_encode($param['contentGroups'], JSON_UNESCAPED_UNICODE); // 内容库信息
$config->socialMediaId = !empty($param['socialMediaId']) ? $param['socialMediaId'] : '';
$config->promotionSiteId = !empty($param['promotionSiteId']) ? $param['promotionSiteId'] : '';
$config->updateTime = time();
$config->save();
}
break;
case self::TYPE_GROUP_CREATE:
$config = WorkbenchGroupCreate::where('workbenchId', $param['id'])->find();
if ($config) {
$config->devices = json_encode($param['deviceGroups'], JSON_UNESCAPED_UNICODE);
$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'];
$config->poolGroups = json_encode($param['poolGroups'] ?? []);
$config->wechatGroups = json_encode($param['wechatGroups'] ?? []);
$config->updateTime = time();
$config->save();
}
break;
case self::TYPE_TRAFFIC_DISTRIBUTION:
$config = WorkbenchTrafficConfig::where('workbenchId', $param['id'])->find();
if ($config) {
$config->distributeType = $param['distributeType'];
$config->maxPerDay = $param['maxPerDay'];
$config->timeType = $param['timeType'];
$config->startTime = $param['startTime'];
$config->endTime = $param['endTime'];
$config->devices = json_encode($param['deviceGroups']);
$config->pools = json_encode($param['poolGroups']);
$config->account = json_encode($param['accountGroups']);
$config->updateTime = time();
$config->save();
}
break;
case self::TYPE_IMPORT_CONTACT: //联系人导入
$config = WorkbenchImportContact::where('workbenchId', $param['id'])->find();;
if ($config) {
$config->devices = json_encode($param['deviceGroups']);
$config->pools = json_encode($param['poolGroups']);
$config->num = $param['num'];
$config->clearContact = $param['clearContact'];
$config->remark = $param['remark'];
$config->startTime = $param['startTime'];
$config->endTime = $param['endTime'];
$config->save();
}
break;
}
Db::commit();
return json(['code' => 200, 'msg' => '更新成功']);
} catch (\Exception $e) {
Db::rollback();
return json(['code' => 500, 'msg' => '更新失败:' . $e->getMessage()]);
}
}
/**
* 更新工作台状态
* @return \think\response\Json
*/
public function updateStatus()
{
if (!$this->request->isPost()) {
return json(['code' => 400, 'msg' => '请求方式错误']);
}
$id = $this->request->param('id', '');
if (empty($id)) {
return json(['code' => 400, 'msg' => '参数错误']);
}
$workbench = Workbench::where([
['id', '=', $id],
['companyId', '=', $this->request->userInfo['companyId']]
])->find();
if (empty($workbench)) {
return json(['code' => 404, 'msg' => '工作台不存在']);
}
$workbench->status = !$workbench['status'];
$workbench->save();
return json(['code' => 200, 'msg' => '更新成功']);
}
/**
* 删除工作台(软删除)
*/
public function delete()
{
$id = $this->request->param('id');
if (empty($id)) {
return json(['code' => 400, 'msg' => '参数错误']);
}
$workbench = Workbench::where([
['id', '=', $id],
['userId', '=', $this->request->userInfo['id']],
['isDel', '=', 0]
])->find();
if (!$workbench) {
return json(['code' => 404, 'msg' => '工作台不存在']);
}
// 软删除
$workbench->isDel = 1;
$workbench->deleteTime = time();
$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'];
$newWorkbench->companyId = $this->request->userInfo['companyId'];
$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;
$newConfig->friends = $config->friends;
$newConfig->createTime = time();
$newConfig->updateTime = time();
$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;
$newConfig->startTime = $config->startTime;
$newConfig->endTime = $config->endTime;
$newConfig->accountType = $config->accountType;
$newConfig->devices = $config->devices;
$newConfig->contentLibraries = $config->contentLibraries;
$newConfig->createTime = time();
$newConfig->updateTime = time();
$newConfig->save();
}
break;
case self::TYPE_GROUP_PUSH:
$config = WorkbenchGroupPush::where('workbenchId', $id)->find();
if ($config) {
$newConfig = new WorkbenchGroupPush;
$newConfig->workbenchId = $newWorkbench->id;
$newConfig->pushType = $config->pushType;
$newConfig->targetType = isset($config->targetType) ? $config->targetType : 1; // 默认1=群推送
$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;
$newConfig->friends = $config->friends;
$newConfig->devices = $config->devices;
$newConfig->contentLibraries = $config->contentLibraries;
$newConfig->socialMediaId = $config->socialMediaId;
$newConfig->promotionSiteId = $config->promotionSiteId;
$newConfig->createTime = time();
$newConfig->updateTime = time();
$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;
$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;
$newConfig->poolGroups = $config->poolGroups;
$newConfig->wechatGroups = $config->wechatGroups;
$newConfig->createTime = time();
$newConfig->updateTime = time();
$newConfig->save();
}
break;
case self::TYPE_IMPORT_CONTACT: //联系人导入
$config = WorkbenchImportContact::where('workbenchId',$id)->find();
if ($config) {
$newConfig = new WorkbenchImportContact;
$newConfig->workbenchId = $newWorkbench->id;
$newConfig->devices = $config->devices;
$newConfig->pools = $config->pools;
$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;
}
Db::commit();
return json(['code' => 200, 'msg' => '拷贝成功', 'data' => ['id' => $newWorkbench->id]]);
} catch (\Exception $e) {
Db::rollback();
return json(['code' => 500, 'msg' => '拷贝失败:' . $e->getMessage()]);
}
}
/**
* 获取点赞记录列表
* @return \think\response\Json
*/
public function getLikeRecords()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$workbenchId = $this->request->param('workbenchId', 0);
$where = [
['wali.workbenchId', '=', $workbenchId]
];
// 查询点赞记录
$list = Db::name('workbench_auto_like_item')->alias('wali')
->join(['s2_wechat_moments' => 'wm'], 'wali.snsId = wm.snsId')
->field([
'wali.id',
'wali.workbenchId',
'wali.momentsId',
'wali.snsId',
'wali.wechatAccountId',
'wali.wechatFriendId',
'wali.createTime as likeTime',
'wm.content',
'wm.resUrls',
'wm.createTime as momentTime',
'wm.userName',
])
->where($where)
->order('wali.createTime', 'desc')
->group('wali.id')
->page($page, $limit)
->select();
// 处理数据
foreach ($list as &$item) {
//处理用户信息
$friend = Db::table('s2_wechat_friend')
->where(['id' => $item['wechatFriendId']])
->field('nickName,avatar')
->find();
if(!empty($friend)){
$item['friendName'] = $friend['nickName'];
$item['friendAvatar'] = $friend['avatar'];
}else{
$item['friendName'] = '';
$item['friendAvatar'] = '';
}
//处理客服
$friend = Db::table('s2_wechat_account')
->where(['id' => $item['wechatAccountId']])
->field('nickName,avatar')
->find();
if(!empty($friend)){
$item['operatorName'] = $friend['nickName'];
$item['operatorAvatar'] = $friend['avatar'];
}else{
$item['operatorName'] = '';
$item['operatorAvatar'] = '';
}
// 处理时间格式
$item['likeTime'] = date('Y-m-d H:i:s', $item['likeTime']);
$item['momentTime'] = !empty($item['momentTime']) ? date('Y-m-d H:i:s', $item['momentTime']) : '';
// 处理资源链接
if (!empty($item['resUrls'])) {
$item['resUrls'] = json_decode($item['resUrls'], true);
} else {
$item['resUrls'] = [];
}
}
// 获取总记录数
$total = Db::name('workbench_auto_like_item')->alias('wali')
->where($where)
->count();
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
'limit' => $limit
]
]);
}
/**
* 获取朋友圈发布记录列表
* @return \think\response\Json
*/
public function getMomentsRecords()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$workbenchId = $this->request->param('workbenchId', 0);
$where = [
['wmsi.workbenchId', '=', $workbenchId]
];
// 查询发布记录
$list = Db::name('workbench_moments_sync_item')->alias('wmsi')
->join('content_item ci', 'ci.id = wmsi.contentId', 'left')
->join(['s2_wechat_account' => 'wa'], 'wa.id = wmsi.wechatAccountId', 'left')
->field([
'wmsi.id',
'wmsi.workbenchId',
'wmsi.createTime as publishTime',
'ci.contentType',
'ci.content',
'ci.resUrls',
'ci.urls',
'wa.nickName as operatorName',
'wa.avatar as operatorAvatar'
])
->where($where)
->order('wmsi.createTime', 'desc')
->page($page, $limit)
->select();
foreach ($list as &$item) {
$item['resUrls'] = json_decode($item['resUrls'], true);
$item['urls'] = json_decode($item['urls'], true);
}
// 获取总记录数
$total = Db::name('workbench_moments_sync_item')->alias('wmsi')
->where($where)
->count();
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
'limit' => $limit
]
]);
}
/**
* 获取朋友圈发布统计
* @return \think\response\Json
*/
public function getMomentsStats()
{
$workbenchId = $this->request->param('workbenchId', 0);
if (empty($workbenchId)) {
return json(['code' => 400, 'msg' => '参数错误']);
}
// 获取今日数据
$todayStart = strtotime(date('Y-m-d') . ' 00:00:00');
$todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
$todayStats = Db::name('workbench_moments_sync_item')
->where([
['workbenchId', '=', $workbenchId],
['createTime', 'between', [$todayStart, $todayEnd]]
])
->field([
'COUNT(*) as total',
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
])
->find();
// 获取总数据
$totalStats = Db::name('workbench_moments_sync_item')
->where('workbenchId', $workbenchId)
->field([
'COUNT(*) as total',
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
])
->find();
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'today' => [
'total' => intval($todayStats['total']),
'success' => intval($todayStats['success']),
'failed' => intval($todayStats['failed'])
],
'total' => [
'total' => intval($totalStats['total']),
'success' => intval($totalStats['success']),
'failed' => intval($totalStats['failed'])
]
]
]);
}
/**
* 获取流量分发记录列表
* @return \think\response\Json
*/
public function getTrafficDistributionRecords()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$workbenchId = $this->request->param('workbenchId', 0);
$where = [
['wtdi.workbenchId', '=', $workbenchId]
];
// 查询分发记录
$list = Db::name('workbench_traffic_distribution_item')->alias('wtdi')
->join(['s2_wechat_account' => 'wa'], 'wa.id = wtdi.wechatAccountId', 'left')
->join(['s2_wechat_friend' => 'wf'], 'wf.id = wtdi.wechatFriendId', 'left')
->field([
'wtdi.id',
'wtdi.workbenchId',
'wtdi.wechatAccountId',
'wtdi.wechatFriendId',
'wtdi.createTime as distributeTime',
'wtdi.status',
'wtdi.errorMsg',
'wa.nickName as operatorName',
'wa.avatar as operatorAvatar',
'wf.nickName as friendName',
'wf.avatar as friendAvatar',
'wf.gender',
'wf.province',
'wf.city'
])
->where($where)
->order('wtdi.createTime', 'desc')
->page($page, $limit)
->select();
// 处理数据
foreach ($list as &$item) {
// 处理时间格式
$item['distributeTime'] = date('Y-m-d H:i:s', $item['distributeTime']);
// 处理性别
$genderMap = [
0 => '未知',
1 => '男',
2 => '女'
];
$item['genderText'] = $genderMap[$item['gender']] ?? '未知';
// 处理状态文字
$statusMap = [
0 => '待分发',
1 => '分发成功',
2 => '分发失败'
];
$item['statusText'] = $statusMap[$item['status']] ?? '未知状态';
}
// 获取总记录数
$total = Db::name('workbench_traffic_distribution_item')->alias('wtdi')
->where($where)
->count();
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'list' => $list,
'total' => $total,
'page' => $page,
'limit' => $limit
]
]);
}
/**
* 获取流量分发统计
* @return \think\response\Json
*/
public function getTrafficDistributionStats()
{
$workbenchId = $this->request->param('workbenchId', 0);
if (empty($workbenchId)) {
return json(['code' => 400, 'msg' => '参数错误']);
}
// 获取今日数据
$todayStart = strtotime(date('Y-m-d') . ' 00:00:00');
$todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
$todayStats = Db::name('workbench_traffic_distribution_item')
->where([
['workbenchId', '=', $workbenchId],
['createTime', 'between', [$todayStart, $todayEnd]]
])
->field([
'COUNT(*) as total',
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
])
->find();
// 获取总数据
$totalStats = Db::name('workbench_traffic_distribution_item')
->where('workbenchId', $workbenchId)
->field([
'COUNT(*) as total',
'SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success',
'SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) as failed'
])
->find();
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'today' => [
'total' => intval($todayStats['total']),
'success' => intval($todayStats['success']),
'failed' => intval($todayStats['failed'])
],
'total' => [
'total' => intval($totalStats['total']),
'success' => intval($totalStats['success']),
'failed' => intval($totalStats['failed'])
]
]
]);
}
/**
* 获取流量分发详情
* @return \think\response\Json
*/
public function getTrafficDistributionDetail()
{
$id = $this->request->param('id', 0);
if (empty($id)) {
return json(['code' => 400, 'msg' => '参数错误']);
}
$detail = Db::name('workbench_traffic_distribution_item')->alias('wtdi')
->join(['s2_wechat_account' => 'wa'], 'wa.id = wtdi.wechatAccountId', 'left')
->join(['s2_wechat_friend' => 'wf'], 'wf.id = wtdi.wechatFriendId', 'left')
->field([
'wtdi.id',
'wtdi.workbenchId',
'wtdi.wechatAccountId',
'wtdi.wechatFriendId',
'wtdi.createTime as distributeTime',
'wtdi.status',
'wtdi.errorMsg',
'wa.nickName as operatorName',
'wa.avatar as operatorAvatar',
'wf.nickName as friendName',
'wf.avatar as friendAvatar',
'wf.gender',
'wf.province',
'wf.city',
'wf.signature',
'wf.remark'
])
->where('wtdi.id', $id)
->find();
if (empty($detail)) {
return json(['code' => 404, 'msg' => '记录不存在']);
}
// 处理数据
$detail['distributeTime'] = date('Y-m-d H:i:s', $detail['distributeTime']);
// 处理性别
$genderMap = [
0 => '未知',
1 => '男',
2 => '女'
];
$detail['genderText'] = $genderMap[$detail['gender']] ?? '未知';
// 处理状态文字
$statusMap = [
0 => '待分发',
1 => '分发成功',
2 => '分发失败'
];
$detail['statusText'] = $statusMap[$detail['status']] ?? '未知状态';
return json([
'code' => 200,
'msg' => '获取成功',
'data' => $detail
]);
}
/**
* 创建流量分发计划
* @return \think\response\Json
*/
public function createTrafficPlan()
{
$param = $this->request->post();
Db::startTrans();
try {
// 1. 创建主表
$planId = Db::name('ck_workbench')->insertGetId([
'name' => $param['name'],
'type' => 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),
'pools' => json_encode($param['poolGroups'], JSON_UNESCAPED_UNICODE),
'createTime' => time(),
'updateTime' => time()
]);
Db::commit();
return json(['code' => 200, 'msg' => '创建成功']);
} catch (\Exception $e) {
Db::rollback();
return json(['code' => 500, 'msg' => '创建失败:' . $e->getMessage()]);
}
}
/**
* 获取所有微信好友标签及数量统计
* @return \think\response\Json
*/
public function getDeviceLabels()
{
$deviceIds = $this->request->param('deviceIds', '');
$companyId = $this->request->userInfo['companyId'];
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$where = [
['wc.companyId', '=', $companyId],
];
if (!empty($deviceIds)) {
$deviceIds = explode(',', $deviceIds);
$where[] = ['dwl.deviceId', 'in', $deviceIds];
}
$wechatAccounts = Db::name('wechat_customer')->alias('wc')
->join('device_wechat_login dwl', 'dwl.wechatId = wc.wechatId AND dwl.companyId = wc.companyId AND dwl.alive = 1')
->join(['s2_wechat_account' => 'wa'], 'wa.wechatId = wc.wechatId')
->where($where)
->field('wa.id,wa.wechatId,wa.nickName,wa.labels')
->select();
$labels = [];
$wechatIds = [];
foreach ($wechatAccounts as $account) {
$labelArr = json_decode($account['labels'], true);
if (is_array($labelArr)) {
foreach ($labelArr as $label) {
if ($label !== '' && $label !== null) {
$labels[] = $label;
}
}
}
$wechatIds[] = $account['wechatId'];
}
// 去重(只保留一个)
$labels = array_values(array_unique($labels));
$wechatIds = array_unique($wechatIds);
// 搜索过滤
if (!empty($keyword)) {
$labels = array_filter($labels, function ($label) use ($keyword) {
return mb_stripos($label, $keyword) !== false;
});
$labels = array_values($labels); // 重新索引数组
}
// 分页处理
$labels2 = array_slice($labels, ($page - 1) * $limit, $limit);
// 统计数量
$newLabel = [];
foreach ($labels2 as $label) {
$friendCount = Db::table('s2_wechat_friend')
->whereIn('ownerWechatId', $wechatIds)
->where('labels', 'like', '%"' . $label . '"%')
->count();
$newLabel[] = [
'label' => $label,
'count' => $friendCount
];
}
// 返回结果
return json([
'code' => 200,
'msg' => '获取成功',
'data' => [
'list' => $newLabel,
'total' => count($labels),
]
]);
}
/**
* 获取群列表
* @return \think\response\Json
*/
public function getGroupList()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$where = [
['wg.deleteTime', '=', 0],
['wg.companyId', '=', $this->request->userInfo['companyId']],
];
if (!empty($keyword)) {
$where[] = ['wg.name', 'like', '%' . $keyword . '%'];
}
$query = Db::name('wechat_group')->alias('wg')
->join('wechat_account wa', 'wa.wechatId = wg.ownerWechatId')
->where($where);
$total = $query->count();
$list = $query->order('wg.id', 'desc')
->field('wg.id,wg.name as groupName,wg.ownerWechatId,wa.nickName,wg.createTime,wa.avatar,wa.alias,wg.avatar as groupAvatar')
->page($page, $limit)
->select();
// 优化:格式化时间,头像兜底
$defaultGroupAvatar = '';
$defaultAvatar = '';
foreach ($list as &$item) {
$item['createTime'] = $item['createTime'] ? date('Y-m-d H:i:s', $item['createTime']) : '';
$item['groupAvatar'] = $item['groupAvatar'] ?: $defaultGroupAvatar;
$item['avatar'] = $item['avatar'] ?: $defaultAvatar;
}
return json(['code' => 200, 'msg' => '获取成功', 'data' => ['total' => $total, 'list' => $list]]);
}
public function getAccountList()
{
$companyId = $this->request->userInfo['companyId'];
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$query = Db::table('s2_company_account')
->alias('a')
->where(['a.departmentId' => $companyId, 'a.status' => 0])
->whereNotLike('a.userName', '%_offline%')
->whereNotLike('a.userName', '%_delete%');
$total = $query->count();
$list = $query->field('a.id,a.userName,a.realName,a.nickname,a.memo')
->page($page, $limit)
->select();
return json(['code' => 200, 'msg' => '获取成功', 'data' => ['total' => $total, 'list' => $list]]);
}
/**
* 获取京东联盟导购媒体
* @return \think\response\Json
* @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' => '参数缺失']);
}
$data = Db::name('jd_promotion_site')->where('jdSocialMediaId', $id)->order('id DESC')->select();
return json(['code' => 200, 'msg' => '获取成功', 'data' => $data]);
}
//京东转链-京推推
public function changeLink($content = '',$positionid = '')
{
$unionId = Env::get('jd.unionId', '');
$jttAppId = Env::get('jd.jttAppId', '');
$appKey = Env::get('jd.appKey', '');
$apiUrl = Env::get('jd.apiUrl', '');
$content = !empty($content) ? $content : $this->request->param('content', '');
$positionid = !empty($positionid) ? $positionid : $this->request->param('positionid', '');
if (empty($content)){
return json_encode(['code' => 500, 'msg' => '转链的内容为空']) ;
}
// 验证是否包含链接
if (!$this->containsLink($content)) {
return json_encode(['code' => 500, 'msg' => '内容中未检测到有效链接']) ;
}
if(empty($unionId) || empty($jttAppId) || empty($appKey) || empty($apiUrl)){
return json_encode(['code' => 500, 'msg' => '参数缺失']) ;
}
$params = [
'unionid' => $unionId,
'content' => $content,
'appid' => $jttAppId,
'appkey' => $appKey,
'v' => 'v2'
];
if (!empty($positionid)) {
$params['positionid'] = $positionid;
}
$res = requestCurl($apiUrl,$params,'GET',[],'json');
$res = json_decode($res,true);
if (empty($res)){
return json_encode(['code' => 500, 'msg' => '未知错误']) ;
}
$result = $res['result'];
if ($res['return'] == 0){
return json_encode(['code' => 200,'data' => $result['chain_content'],'msg' => $result['msg']]) ;
}else{
return json_encode(['code' => 500, 'msg' => $result['msg']]) ;
}
}
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' => '参数错误']);
}
$workbench = Db::name('workbench')->where(['id' => $workbenchId,'isDel' => 0,'companyId' => $companyId,'type' => 5])->find();
if (empty($workbench)){
return json(['code' => 400, 'msg' => '该任务不存在或已删除']);
}
$query = Db::name('workbench_traffic_config_item')->alias('wtc')
->join(['s2_wechat_friend' => 'wf'],'wtc.wechatFriendId = wf.id')
->join('users u','wtc.wechatAccountId = u.s2_accountId','left')
->field([
'wtc.id','wtc.isRecycle','wtc.isRecycle','wtc.createTime',
'wf.wechatId','wf.alias','wf.nickname','wf.avatar','wf.gender','wf.phone',
'u.account','u.username'
])
->where(['wtc.workbenchId' => $workbenchId])
->order('wtc.id DESC');
if (!empty($keyword)){
$query->where('wf.wechatId|wf.alias|wf.nickname|wf.phone|u.account|u.username','like','%' . $keyword . '%');
}
$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]);
}
/**
* 验证内容是否包含链接
* @param string $content 要检测的内容
* @return bool
*/
private function containsLink($content)
{
// 定义各种链接的正则表达式模式
$patterns = [
// HTTP/HTTPS链接
'/https?:\/\/[^\s]+/i',
// 京东商品链接
'/item\.jd\.com\/\d+/i',
// 京东短链接
'/u\.jd\.com\/[a-zA-Z0-9]+/i',
// 淘宝商品链接
'/item\.taobao\.com\/item\.htm\?id=\d+/i',
// 天猫商品链接
'/detail\.tmall\.com\/item\.htm\?id=\d+/i',
// 淘宝短链接
'/m\.tb\.cn\/[a-zA-Z0-9]+/i',
// 拼多多链接
'/mobile\.yangkeduo\.com\/goods\.html\?goods_id=\d+/i',
// 苏宁易购链接
'/product\.suning\.com\/\d+\/\d+\.html/i',
// 通用域名模式(包含常见电商域名)
'/(?:jd|taobao|tmall|yangkeduo|suning|amazon|dangdang)\.com[^\s]*/i',
// 通用短链接模式
'/[a-zA-Z0-9-]+\.[a-zA-Z]{2,}\/[a-zA-Z0-9\-._~:\/?#\[\]@!$&\'()*+,;=]+/i'
];
// 遍历所有模式进行匹配
foreach ($patterns as $pattern) {
if (preg_match($pattern, $content)) {
return true;
}
}
return false;
}
/**
* 获取通讯录导入记录列表
* @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,
]
]);
}
}