feat(admin): upgrade message management and broadcast interactions
Add message details, per-row actions, selection-aware bulk controls and confirmation dialogs. Merge filters into the list card and link overview statistics to the matching views with site-timezone today filtering. Improve the compose dialog with Unicode character counters, recipient mode segments, role counts and explicit broadcast confirmation verified against the resolved role and recipient count on submission. Split rendering into focused sibling traits and cover rendering, handlers and UI interactions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6195508481
commit
fe3ef82718
9 files changed
+1242
-422
No files matched your search
@@ -25,7 +25,7 @@ final class NotificationAdminQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{status:string,type:string,user_id:int,s:string} $filters user_id:0=不限,<0=无匹配用户
|
||||
* @param array{status:string,type:string,user_id:int,s:string,period?:string} $filters user_id:0=不限,<0=无匹配用户
|
||||
* @return array{items:list<array<string,mixed>>,total:int,page:int}
|
||||
*/
|
||||
public static function paginate(array $filters, int $page, int $per_page = self::PER_PAGE): array {
|
||||
@@ -76,14 +76,15 @@ final class NotificationAdminQuery {
|
||||
}
|
||||
global $wpdb;
|
||||
// created_at 存 GMT;「今日」按站点时区零点换算。
|
||||
$today_gmt = get_gmt_from_date(wp_date('Y-m-d 00:00:00'));
|
||||
[$today_start, $today_end] = self::today_range();
|
||||
$row = $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT COUNT(*) AS total,
|
||||
COALESCE(SUM(is_read = 0), 0) AS unread,
|
||||
COALESCE(SUM(created_at >= %s), 0) AS today,
|
||||
COALESCE(SUM(created_at >= %s AND created_at < %s), 0) AS today,
|
||||
COUNT(DISTINCT user_id) AS recipients
|
||||
FROM {$table}",
|
||||
$today_gmt
|
||||
$today_start,
|
||||
$today_end
|
||||
), ARRAY_A);
|
||||
return [
|
||||
'total' => (int) ($row['total'] ?? 0),
|
||||
@@ -158,9 +159,22 @@ final class NotificationAdminQuery {
|
||||
$params[] = $like;
|
||||
$params[] = $like;
|
||||
}
|
||||
if (($filters['period'] ?? '') === 'today') {
|
||||
$where[] = 'created_at >= %s AND created_at < %s';
|
||||
array_push($params, ...self::today_range());
|
||||
}
|
||||
return [implode(' AND ', $where), $params];
|
||||
}
|
||||
|
||||
/** 先在站点时区计算自然日,再转换成 GMT;正确处理夏令时的 23 / 25 小时日。 */
|
||||
private static function today_range(): array {
|
||||
$start = current_datetime()->setTime(0, 0, 0);
|
||||
return [
|
||||
get_gmt_from_date($start->format('Y-m-d H:i:s')),
|
||||
get_gmt_from_date($start->modify('+1 day')->format('Y-m-d H:i:s')),
|
||||
];
|
||||
}
|
||||
|
||||
private static function prepare(string $sql, array $params): string {
|
||||
global $wpdb;
|
||||
return $params === [] ? $sql : (string) $wpdb->prepare($sql, $params);
|
||||
|
||||
Reference in new issue
Block a user