账号评分

This commit is contained in:
wong
2025-11-20 16:07:57 +08:00
parent 367a250fba
commit b0a60e428c
6 changed files with 3116 additions and 48 deletions

View File

@@ -2816,6 +2816,8 @@ class WorkbenchController extends Controller
$limit = $this->request->param('limit', 10);
$workbenchId = $this->request->param('workbenchId', 0);
$keyword = $this->request->param('keyword', '');
$pushType = $this->request->param('pushType', ''); // 推送类型筛选:''=全部, 'friend'=好友消息, 'group'=群消息, 'announcement'=群公告
$status = $this->request->param('status', ''); // 状态筛选:''=全部, 'success'=已完成, 'progress'=进行中, 'failed'=失败
$userId = $this->request->userInfo['id'];
// 构建工作台查询条件
@@ -2840,10 +2842,11 @@ class WorkbenchController extends Controller
$workbenchWhere[] = ['w.id', '=', $workbenchId];
}
// 按内容ID、工作台ID和时间分组统计每次推送
$query = Db::name('workbench_group_push_item')
// 1. 先查询所有已执行的推送记录(按推送时间分组)
$pushHistoryQuery = Db::name('workbench_group_push_item')
->alias('wgpi')
->join('workbench w', 'w.id = wgpi.workbenchId', 'left')
->join('workbench_group_push wgp', 'wgp.workbenchId = wgpi.workbenchId', 'left')
->join('content_item ci', 'ci.id = wgpi.contentId', 'left')
->join('content_library cl', 'cl.id = ci.libraryId', 'left')
->where($workbenchWhere)
@@ -2853,52 +2856,57 @@ class WorkbenchController extends Controller
'wgpi.contentId',
'FROM_UNIXTIME(wgpi.createTime, "%Y-%m-%d %H:00:00") as pushTime',
'wgpi.targetType',
'wgp.groupPushSubType',
'MIN(wgpi.createTime) as createTime',
'COUNT(DISTINCT wgpi.id) as totalCount',
'cl.name as contentLibraryName'
])
->group('wgpi.workbenchId, wgpi.contentId, pushTime, wgpi.targetType');
->group('wgpi.workbenchId, wgpi.contentId, pushTime, wgpi.targetType, wgp.groupPushSubType');
if (!empty($keyword)) {
$query->where('w.name|cl.name|ci.content', 'like', '%' . $keyword . '%');
$pushHistoryQuery->where('w.name|cl.name|ci.content', 'like', '%' . $keyword . '%');
}
// 获取分页数据
$list = $query->order('createTime', 'desc')
->page($page, $limit)
->select();
// 对于有 group by 的查询,统计总数需要重新查询
$totalQuery = Db::name('workbench_group_push_item')
->alias('wgpi')
->join('workbench w', 'w.id = wgpi.workbenchId', 'left')
->join('content_item ci', 'ci.id = wgpi.contentId', 'left')
->join('content_library cl', 'cl.id = ci.libraryId', 'left')
->where($workbenchWhere);
if (!empty($keyword)) {
$totalQuery->where('w.name|cl.name|ci.content', 'like', '%' . $keyword . '%');
}
// 统计分组后的记录数(使用子查询)
$subQuery = $totalQuery
$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([
'wgpi.workbenchId',
'wgpi.contentId',
'FROM_UNIXTIME(wgpi.createTime, "%Y-%m-%d %H:00:00") as pushTime',
'wgpi.targetType'
])
->group('wgpi.workbenchId, wgpi.contentId, pushTime, wgpi.targetType')
->buildSql();
$total = Db::table('(' . $subQuery . ') as temp')->count();
'w.id as workbenchId',
'w.name as workbenchName',
'w.createTime',
'wgp.targetType',
'wgp.groupPushSubType',
'wgp.groups',
'wgp.friends',
'wgp.trafficPools'
]);
// 处理每条记录
foreach ($list as &$item) {
if (!empty($keyword)) {
$allTasksQuery->where('w.name', 'like', '%' . $keyword . '%');
}
$allTasks = $allTasksQuery->select();
// 3. 合并数据:已执行的推送记录 + 未执行的任务
$resultList = [];
$executedWorkbenchIds = [];
// 处理已执行的推送记录
foreach ($pushHistoryList as $item) {
$itemWorkbenchId = $item['workbenchId'];
$contentId = $item['contentId'];
$pushTime = $item['pushTime'];
$targetType = intval($item['targetType']);
$groupPushSubType = isset($item['groupPushSubType']) ? intval($item['groupPushSubType']) : 1;
// 标记该工作台已有执行记录
if (!in_array($itemWorkbenchId, $executedWorkbenchIds)) {
$executedWorkbenchIds[] = $itemWorkbenchId;
}
// 将时间字符串转换为时间戳范围(小时级别)
$pushTimeStart = strtotime($pushTime);
@@ -2937,23 +2945,149 @@ class WorkbenchController extends Controller
$failCount = 0; // 简化处理,实际需要从发送状态获取
// 状态判断
$status = $successCount > 0 ? 'success' : 'failed';
$itemStatus = $successCount > 0 ? 'success' : 'failed';
if ($failCount > 0 && $successCount > 0) {
$status = 'partial';
$itemStatus = 'partial';
}
$item['pushType'] = $targetType == 1 ? '群推送' : '好友推送';
$item['pushTypeCode'] = $targetType;
$item['targetCount'] = $targetCount;
$item['successCount'] = $successCount;
$item['failCount'] = $failCount;
$item['status'] = $status;
$item['statusText'] = $status == 'success' ? '成功' : ($status == 'partial' ? '部分成功' : '失败');
$item['createTime'] = date('Y-m-d H:i:s', $item['createTime']);
// 任务名称(工作台名称)
$item['taskName'] = $item['workbenchName'] ?? '';
// 推送类型判断
$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'] ?? ''
];
}
unset($item);
// 处理未执行的任务
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);
return json([
'code' => 200,
@@ -2967,5 +3101,21 @@ class WorkbenchController extends Controller
]);
}
/**
* 获取状态文本
* @param string $status 状态码
* @return string 状态文本
*/
private function getStatusText($status)
{
$statusMap = [
'success' => '已完成',
'partial' => '进行中',
'pending' => '进行中',
'failed' => '失败'
];
return $statusMap[$status] ?? '未知';
}
}