no message

This commit is contained in:
hajimi
2026-06-11 12:15:29 +08:00
parent 10ebe39c30
commit 96efa1d905
5859 changed files with 815501 additions and 5 deletions
@@ -0,0 +1,140 @@
<?php
namespace app\api\controller;
use app\common\model\popup\PagePopup;
use app\common\model\popup\PagePopupLog;
use think\response\Json;
/**
* 页面弹窗
* GET /api/popup/list?page_path=...&platform=...
* POST /api/popup/report body: popup_id, action(1=show 2=click 3=close), page_path, device_id
*/
class PopupController extends BaseApiController
{
public array $notNeedLogin = ['list', 'report'];
/**
* 获取当前页面匹配的弹窗列表
*/
public function list(): Json
{
$pagePath = trim((string) $this->request->get('page_path', ''));
$platform = trim((string) $this->request->get('platform', ''));
if (!$pagePath) {
return $this->data(['lists' => []]);
}
$now = time();
$query = PagePopup::where('status', 1)
->where(function ($q) use ($now) {
$q->whereOr([
['start_time', '=', 0],
['start_time', '<=', $now]
]);
})
->where(function ($q) use ($now) {
$q->whereOr([
['end_time', '=', 0],
['end_time', '>=', $now]
]);
})
->order(['sort' => 'desc', 'id' => 'desc']);
$all = $query->select()->toArray();
// 路径匹配 + 平台筛选(PHP 端处理通配符)
$matched = [];
foreach ($all as $item) {
// 平台筛选
if (!empty($item['target_platform']) && $platform) {
$platforms = array_filter(array_map('trim', explode(',', $item['target_platform'])));
if (!empty($platforms) && !in_array($platform, $platforms, true)) {
continue;
}
}
// 路径匹配
if (!self::pathMatch($item['page_path'], $pagePath)) {
continue;
}
$matched[] = [
'id' => $item['id'],
'name' => $item['name'],
'popup_type' => $item['popup_type'],
'image' => $item['image'],
'title' => $item['title'],
'content' => $item['content'],
'link_type' => $item['link_type'],
'link_url' => $item['link_url'],
'frequency' => $item['frequency'],
'delay_seconds' => $item['delay_seconds'],
'auto_close_seconds' => $item['auto_close_seconds'] ?? 0,
'is_closable' => $item['is_closable'] ?? 1,
'sort' => $item['sort'],
];
}
return $this->data(['lists' => $matched]);
}
/**
* 上报弹窗操作
*/
public function report(): Json
{
$popupId = (int) $this->request->post('popup_id/d', 0);
$action = (int) $this->request->post('action/d', 0);
$pagePath = (string) $this->request->post('page_path', '');
$deviceId = (string) $this->request->post('device_id', '');
$platform = (string) $this->request->post('platform', '');
if ($popupId <= 0 || !in_array($action, [1, 2, 3], true)) {
return $this->fail('参数错误');
}
$now = time();
$ip = $this->request->ip() ?: '';
$ua = $this->request->header('user-agent', '');
if (mb_strlen($ua) > 500)
$ua = mb_substr($ua, 0, 500);
PagePopupLog::insert([
'popup_id' => $popupId,
'user_id' => $this->userId ?: 0,
'device_id' => $deviceId,
'action' => $action,
'page_path' => $pagePath,
'platform' => $platform,
'ip' => $ip,
'ua' => $ua,
'create_time' => $now,
]);
// 冗余统计字段
$field = [1 => 'show_count', 2 => 'click_count', 3 => 'close_count'][$action] ?? '';
if ($field) {
PagePopup::where('id', $popupId)->inc($field)->update();
}
return $this->data(['ok' => true]);
}
/**
* 路径匹配规则:
* - * 匹配所有
* - 末尾 * 表示前缀匹配(/pages/news_detail/*
* - 完全相等
*/
private static function pathMatch(string $pattern, string $path): bool
{
$pattern = trim($pattern);
if ($pattern === '' || $pattern === '*')
return true;
if (substr($pattern, -1) === '*') {
$prefix = substr($pattern, 0, -1);
return strpos($path, $prefix) === 0;
}
return $pattern === $path;
}
}