first commit

This commit is contained in:
root
2025-06-18 10:31:43 +08:00
commit d9f820b55d
981 changed files with 449311 additions and 0 deletions

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Controller;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Psr\Container\ContainerInterface;
abstract class AbstractController
{
#[Inject]
protected ContainerInterface $container;
#[Inject]
protected RequestInterface $request;
#[Inject]
protected ResponseInterface $response;
}

17
app/Controller/Hicontroller.php Executable file
View File

@ -0,0 +1,17 @@
<?php
namespace App\Controller;
use Grpc\HiReply;
use Grpc\HiUser;
class Hicontroller extends AbstractController
{
public function sayHello(HiUser $user)
{
$message = new HiReply();
$message->setMessage("Hello World");
$message->setUser($user);
return $message;
}
}

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace App\Controller;
use App\Helpers\ExcelHelper;
use App\Model\AppKeywordsMonitor;
use App\Model\AppKeywordsMonitorResult;
use App\Model\AppKeywordsMonitorTask;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\RenderInterface;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
#[AutoController]
class IndexController extends AbstractController
{
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
return [
'method' => $method,
'message' => "Hello {$user}.",
];
}
public function test(RenderInterface $render)
{
return $render->render('index', ['name' => 'Hyperf']);
}
}

View File

@ -0,0 +1,159 @@
<?php
namespace App\Controller;
use App\Helpers\AppHelper;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Psr\Http\Message\RequestInterface;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use function Hyperf\Config\config;
#[Controller(prefix: 'upload')]
class UploadController extends AbstractController
{
/**
* @url common/uploadImage
* @return array
* @throws \Exception
*/
// #[RequestMapping(path: "upload-image", methods: "post")]
public function uploadImage(): array
{
$baseConfigKey = 'plugin.admin.upload.qiniu.';
// 需要填写你的 Access Key 和 Secret Key
$accessKey = config('upload.qiniu.access_key');
$secretKey = config('upload.qiniu.secret_key');
$bucket = config('upload.qiniu.bucket');
$file = $this->request->file('file');
// 构建鉴权对象
$auth = new Auth($accessKey, $secretKey);
$returnBody = '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}';
$policy = array(
'returnBody' => $returnBody
);
// 生成上传 Token
$token = $auth->uploadToken($bucket, policy: $policy);
// 要上传文件的本地路径
// 上传到存储后保存的文件名
$filePath = $file->getRealPath();
$key = date('Y-m') . '/' . $file->getClientFilename();
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
// 调用 UploadManager 的 putFile 方法进行文件的上传。
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath, null, 'application/octet-stream', true, null, 'v2');
return [
'code' => 0,
'msg' => '上传成功@@',
'data' => [
'base_url' => AppHelper::getImageBaseUrl(),
'base_path' => $ret['key'],
'src' => AppHelper::getImageBaseUrl() . $ret['key'],
'name' => $ret['key'],
'size' => $ret['fsize'],
]
];
}
#[RequestMapping(path: "image", methods: "post")]
public function image()
{
$file = $file = $this->request->file('file');
if (!$file || $file->getError() !== UPLOAD_ERR_OK) {
return $this->response->json(['code' => 400, 'msg' => '文件上传失败']);
}
// 校验类型
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!in_array($file->getClientMediaType(), $allowedTypes)) {
return $this->response->json(['code' => 415, 'msg' => '不支持的图片格式']);
}
// 限制大小 (例如 5MB)
$maxSize = 5 * 1024 * 1024;
if ($file->getSize() > $maxSize) {
return $this->response->json(['code' => 413, 'msg' => '图片大小不能超过 5MB']);
}
// 保存路径
$filename = uniqid() . '.' . pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
$targetPath = BASE_PATH . '/uploads/' . $filename;
// 确保目录存在
if (!is_dir(dirname($targetPath))) {
mkdir(dirname($targetPath), 0777, true);
}
// 移动文件
$file->moveTo($targetPath);
// 构造返回 URL
$url = '/uploads/' . $filename;
return $this->response->json([
'errno' => 0,
'msg' => '上传成功!!',
'data' => [
'url' => 'http://' . '127.0.0.1:9503' . $url,
]
]);
}
/**
* 上传关键词监控页面
* @url upload/search-image
*/
#[RequestMapping(path: 'search-image', methods: 'post')]
public function uploadSearchImage()
{
$file = $file = $this->request->file('file');
if (!$file || $file->getError() !== UPLOAD_ERR_OK) {
return $this->response->json(['code' => 400, 'msg' => '文件上传失败']);
}
// 校验类型
// $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
// if (!in_array($file->getClientMediaType(), $allowedTypes)) {
// return $this->response->json(['code' => 415, 'msg' => '不支持的图片格式']);
// }
// 限制大小 (例如 5MB)
$maxSize = 5 * 1024 * 1024;
if ($file->getSize() > $maxSize) {
return $this->response->json(['code' => 413, 'msg' => '图片大小不能超过 5MB']);
}
// 保存路径
$filename = uniqid() . '.' . pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
$date = date('m-d');
$targetPath = BASE_PATH . '/uploads/' . $filename;
// 确保目录存在
if (!is_dir(dirname($targetPath))) {
mkdir(dirname($targetPath), 0777, true);
}
// 移动文件
$file->moveTo($targetPath);
// 构造返回 URL
$url = '/uploads/' . $filename;
return $this->response->json([
'errno' => 0,
'msg' => '上传成功~~',
'data' => [
'url' => 'http://' . '127.0.0.1:9503' . $url,
'file_name' => $url
]
]);
}
}

View File

@ -0,0 +1,87 @@
<?php
namespace App\Controller\admin;
use App\Controller\AbstractController;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller]
class ConfigController extends AbstractController
{
#[RequestMapping(path: '', methods: 'get')]
public function index()
{
return '{
"logo": {
"title": "舆情管理后台",
"image": "/app/admin/admin/images/logo.png"
},
"menu": {
"data": "/admin/menu-config",
"method": "GET",
"accordion": true,
"collapse": false,
"control": false,
"controlWidth": 2000,
"select": "0",
"async": true
},
"tab": {
"enable": false,
"keepState": true,
"session": true,
"preload": false,
"max": "30",
"index": {
"id": "0",
"href": "\/admin\/dashboard",
"title": "仪表盘"
}
},
"theme": {
"defaultColor": "2",
"defaultMenu": "light-theme",
"defaultHeader": "light-theme",
"allowCustom": true,
"banner": false
},
"colors": [
{
"id": "1",
"color": "#36b368",
"second": "#f0f9eb"
},
{
"id": "2",
"color": "#2d8cf0",
"second": "#ecf5ff"
},
{
"id": "3",
"color": "#f6ad55",
"second": "#fdf6ec"
},
{
"id": "4",
"color": "#f56c6c",
"second": "#fef0f0"
},
{
"id": "5",
"color": "#3963bc",
"second": "#ecf5ff"
}
],
"other": {
"keepLoad": "500",
"autoHead": false,
"footer": false
},
"header": {
"message": false
}
}';
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Controller\admin;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\RenderInterface;
#[Controller]
class DashboardController
{
#[RequestMapping(path: '', methods: 'get')]
public function index(RenderInterface $render)
{
return $render->render('dashboard');
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Controller\admin;
use App\Controller\AbstractController;
use App\Helpers\TreeHelper;
use App\Model\AppAdminMenu;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\RenderInterface;
#[Controller(prefix: 'admin')]
class IndexController extends AbstractController
{
#[RequestMapping(path: '', methods: 'get')]
public function index(RenderInterface $render)
{
return $render->render('admin');
}
#[RequestMapping(path: 'menu-config', methods: 'get')]
public function menuConfig()
{
$items = AppAdminMenu::orderBy('weight', 'DESC')->get()->toArray();
$formatted_items = [];
foreach ($items as $item) {
$item['pid'] = (int)$item['pid'];
$item['name'] = $item['title'];
$item['value'] = $item['id'];
$item['icon'] = $item['icon'] ? "layui-icon {$item['icon']}" : '';
$formatted_items[] = $item;
}
return [
'code' => 0,
'data' => TreeHelper::getTree($formatted_items)
];
return $data;
}
}

View File

@ -0,0 +1,48 @@
<?php
namespace App\Controller\admin;
use App\Controller\AbstractController;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\Render;
use Psr\Http\Message\ResponseInterface;
#[Controller(prefix: 'admin/keywords')]
class KeywordsController extends AbstractController
{
/**
* 舆情关键词列表
* @url /admin/keywords/monitor
*/
#[RequestMapping(path: 'monitor', methods: 'get')]
public function monitor(Render $render): \Psr\Http\Message\ResponseInterface
{
return $render->render('keywords/index');
}
/**
* 新增舆情监控关键词页面
* @url /admin/keywords/monitor/insert
* @param Render $render
* @return ResponseInterface
*/
#[RequestMapping(path: 'monitor/insert', methods: 'get')]
public function monitorInsert(Render $render): \Psr\Http\Message\ResponseInterface
{
return $render->render('keywords/insert');
}
/**
* 编辑舆情监控关键词页面
* @url /admin/keywords/monitor/view
* @param Render $render
* @return ResponseInterface
*/
#[RequestMapping(path: 'monitor/view', methods: 'get')]
public function monitorUpdate(Render $render): \Psr\Http\Message\ResponseInterface
{
return $render->render('keywords/view');
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Controller\admin;
use App\Controller\AbstractController;
use App\Helpers\TreeHelper;
use App\Model\AppAdminMenu;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\RenderInterface;
use plugin\admin\app\common\Tree;
#[Controller(prefix: 'admin/menu')]
class MenuController extends AbstractController
{
#[RequestMapping(path: '', methods: 'get')]
public function index(RenderInterface $render)
{
return $render->render('menu/index');
}
#[RequestMapping(path: 'insert', methods: 'get')]
public function insert(RenderInterface $render)
{
return $render->render('menu/insert');
}
#[RequestMapping(path: 'update', methods: 'get')]
public function update(RenderInterface $render)
{
return $render->render('menu/update');
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Controller\admin;
use App\Controller\AbstractController;
use App\Model\AppNews;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\RenderInterface;
#[Controller(prefix: 'admin/news')]
class NewsController extends AbstractController
{
#[RequestMapping(path: '', methods: 'get')]
public function index(RenderInterface $render): \Psr\Http\Message\ResponseInterface
{
return $render->render('news/index');
}
/**
* 查看新闻详情
* @url /admin/news/view
*/
#[RequestMapping(path: 'view', methods: 'get')]
public function view(RenderInterface $render): \Psr\Http\Message\ResponseInterface
{
$id = $this->request->query('id');
$query = AppNews::where('id', $id)->first()->toArray();
return $render->render('news/view');
}
/**
* 新增新闻页面
* @url /admin/news/insert
*/
#[RequestMapping(path: 'insert', methods: 'get')]
public function insert(RenderInterface $render): \Psr\Http\Message\ResponseInterface
{
return $render->render('news/insert');
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Controller\admin;
use App\Controller\AbstractController;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\RenderInterface;
#[Controller(prefix: 'admin/spider-article')]
class SpiderArticleController extends AbstractController
{
#[RequestMapping(path: '', methods: 'get')]
public function index(RenderInterface $render): \Psr\Http\Message\ResponseInterface
{
return $render->render('spider-article/index');
}
#[RequestMapping(path: 'view', methods: 'get')]
public function view(RenderInterface $render): \Psr\Http\Message\ResponseInterface
{
return $render->render('spider-article/view');
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace App\Controller\admin\api;
use App\Controller\AbstractController;
use App\Enums\ArticlePublishedStatusEnum;
use App\FormModel\admin\articles\ModifyModel;
use App\Helpers\AppHelper;
use App\Model\AppArticle;
use App\Model\AppBrand;
use App\Model\AppNews;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller(prefix: 'admin/api')]
class ArticleController extends AbstractController
{
/**
* 文章列表
* @url /admin/api/article
* @return array
*/
#[RequestMapping(path:'articles', methods: 'get')]
public function index(): array
{
$publishedStatus = $this->request->query('published_status', '');
$createdFilter = $this->request->query('created_at', [date('Y-m-d', strtotime('-1 month')), date('Y-m-d', time())]);
foreach ($createdFilter as $index => &$item) {
if ($index == 0) {
$item = strtotime($item . ' 00:00:00');
}
if ($index == 1) {
$item = strtotime($item . ' 23:59:59');
}
}
$query = AppNews::formatQuery(['module', 'published_status', 'location'])
->select(['id'])
->when($publishedStatus !== '', fn($q) => $q->where('published_status', $publishedStatus))
->whereBetween('created_at', $createdFilter)
->orderBy('created_at', 'desc');
$pagination = $query->paginate($this->request->input('limit', 10), page: $this->request->input('page'));
foreach ($pagination->items() as $item) {
$ids[] = $item->id;
}
$value = AppNews::find($ids, ['aid', 'title', 'module', 'published_status', 'location'])->toArray();
return ['code' => 0, 'msg' => 'ok', 'count' => $pagination->total(), 'data' => $value];
}
// /**
// * 新增/编辑文章
// * @url /api/v1/articles/save
// * @return array
// */
// #[RequestMapping(path:'save', methods: 'post')]
// public function save(): array
// {
// $id = $this->request->input('id');
// $model = new ArticlesModel();
// if ($id) {
// $model->edit();
// } else {
// $model->create();
// }
//
// return [
// 'code' => 0,
// 'message' => 'ok'
// ];
// }
#[RequestMapping(path:'brand-search', methods: 'get')]
public function brandSearch(): array
{
$input = $this->request->input('brand');
$query = AppBrand::query()->select(['name', 'cn_name', 'id'])->where('name', 'like', "%$input%")
->orWhere('cn_name', 'like', "%$input%")
->get()->toArray();
return ['code' => 0, 'msg' => 'ok', 'data' => $query];
}
#[RequestMapping(path:'view', methods: 'get')]
public function view(): \Psr\Http\Message\ResponseInterface
{
$query = AppNews::formatQuery(['images', 'brand_name', 'translate_title'])
->select(['brand as brand_name', 'brand', 'images', 'id', 'title', 'title as translate_title', 'cover', 'aid', 'location'])
->where('aid', $this->request->query('id'));
return $this->response->json(['code' => 0, 'msg' => 'ok', 'data' => $query->first()]);
}
#[RequestMapping(path:'publish', methods: 'post')]
public function publish()
{
$query = AppArticle::where('aid', $this->request->post('aid'))->first();
$query->published_status = ArticlePublishedStatusEnum::TRUE->value;
$query->published_at = time();
$query->save();
return $this->response->json(['code' => 0, 'msg' => 'ok']);
}
#[RequestMapping(path:'update', methods: 'post')]
public function update()
{
$model = new ModifyModel();
$model->setAttributes($this->request->post());
$model->update();
return $this->response->json(['code' => 0, 'msg' => 'ok']);
}
}

View File

@ -0,0 +1,188 @@
<?php
namespace App\Controller\admin\api;
use App\Controller\AbstractController;
use App\Helpers\ExcelHelper;
use App\Model\AppKeywordsMonitor;
use App\Model\AppKeywordsMonitorResult;
use App\Model\AppKeywordsMonitorTask;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\View\RenderInterface;
use Laminas\Stdlib\ArrayUtils;
#[Controller(prefix: 'admin/api/keywords')]
class KeywordsController extends AbstractController
{
/**
* 列表数据
* @url /admin/api/keywords/monitor
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path: 'monitor', methods: 'get')]
public function monitor(): \Psr\Http\Message\ResponseInterface
{
$ids = [];
$query = AppKeywordsMonitor::query()
->select(['id'])
->where('is_delete', 0)
->orderBy('id', 'desc');
$pagination = $query->paginate($this->request->input('limit', 10), page: $this->request->input('page'));
foreach ($pagination->items() as $item) {
$ids[] = $item->id;
}
$value = AppKeywordsMonitor::query()->whereIn('id', $ids)->orderBy('id', 'desc')->get()->toArray();
return $this->response->json(['code' => 0, 'msg' => 'ok', 'count' => $pagination->total(), 'data' => $value]);
}
/**
* 新增关键词
* @url /admin/api/keywords/monitor/insert
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path: 'monitor/insert', methods: 'post')]
public function monitorInsert(): \Psr\Http\Message\ResponseInterface
{
$keyword = $this->request->post('keyword');
$query = AppKeywordsMonitor::query()->where([
['keyword', $keyword],
['is_delete', 0]
])->get()->toArray();
if ($query) {
return $this->response->json(['code' => 400, 'msg' => '已重复添加']);
}
$query = new AppKeywordsMonitor();
$query->keyword = $keyword;
$query->save();
foreach ($this->request->post('platform', []) as $platform) {
$task = new AppKeywordsMonitorTask();
$task->keyword = $keyword;
$task->aid = $query->id;
$task->platform = $platform;
$task->save();
}
return $this->response->json(['code' => 0, 'msg' => 'ok']);
}
/**
* 查看关键词
* @url /admin/api/keywords/monitor/view
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path: 'monitor/view', methods: 'get')]
public function monitorView(): \Psr\Http\Message\ResponseInterface
{
$id = $this->request->input('id');
$query = AppKeywordsMonitor::query()->where(['id' => $id])->first()->toArray();
if (!$query) {
return $this->response->json(['code' => 400, 'msg' => 'id 有误']);
}
$query['platform'] = AppKeywordsMonitorTask::query()->select(['platform'])
->where([
['aid', $query['id']],
['is_delete', 0],
])
->get()?->pluck('platform');
return $this->response->json(['code' => 0, 'msg' => 'ok', 'data' => $query]);
}
/**
* 编辑关键词
* @url /admin/api/keywords/monitor/save
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path: 'monitor/save', methods: 'post')]
public function monitorSave(): \Psr\Http\Message\ResponseInterface
{
$id = $this->request->post('id');
$keyword = $this->request->post('keyword');
$platform = $this->request->post('platform', []);
$query = AppKeywordsMonitor::find($id);
if (!$query) {
return $this->response->json(['code' => 400, 'msg' => 'id 有误']);
}
$query->keyword = $keyword;
$query->save();
// 先全部删掉
AppKeywordsMonitorTask::query()->where(['aid' => $id])->update(['is_delete' => 1]);
foreach ($platform as $platformItem) {
$query = AppKeywordsMonitorTask::query()->where('aid', $id)->first();
if ($query) {
$query->is_delete = 0;
$query->save();
} else {
$query = new AppKeywordsMonitorTask();
$query->platform = $platformItem;
$query->aid = $id;
$query->keyword = $keyword;
$query->save();
}
}
return $this->response->json(['code' => 0, 'msg' => 'ok', 'data' => $query]);
}
/**
* 删除关键词
* @url /admin/api/keywords/monitor/delete
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path: 'monitor/delete', methods: 'post')]
public function monitorDelete(): \Psr\Http\Message\ResponseInterface
{
$id = $this->request->post('id');
$query = AppKeywordsMonitor::find($id);
if (!$query) {
return $this->response->json(['code' => 400, 'msg' => 'id 有误']);
}
$query->is_delete = 1;
$query->save();
AppKeywordsMonitorTask::query()->where(['aid' => $id])->update(['is_delete' => 1]);
return $this->response->json(['code' => 0, 'msg' => 'ok', 'data' => $query]);
}
/**
* 导出关键词报表
* @url /admin/api/keywords/monitor/export-all
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path: 'monitor/export-all', methods: 'get')]
public function monitorExportAll(): \Psr\Http\Message\ResponseInterface
{
$res = AppKeywordsMonitorResult::query()->orderBy('aid', 'desc')->get()->toArray();
foreach ($res as &$v) {
$v['keyword'] = AppKeywordsMonitorTask::find($v['aid'])->keyword;
$v['screen_path'] = 'http://127..0.0.1:9503' . $v['screen_path'];
}
$fileName = date('Y-m-d') . '关键词监控结果';
return ExcelHelper::exportData($this->response, list: $res, header: [
['关键词', 'keyword', 'text'],
['标题', 'title', 'text'],
['排名', 'order', 'text'],
['链接地址', 'url', 'text'],
['ip归属地', 'ip_source', 'text'],
['截图地址', 'screen_path', 'text'],
], filename:$fileName);
return [];
}
}

View File

@ -0,0 +1,101 @@
<?php
namespace App\Controller\admin\api;
use App\Controller\AbstractController;
use App\Helpers\AppHelper;
use App\Helpers\TreeHelper;
use App\Model\AppAdminMenu;
use App\Model\AppArticle;
use App\Model\AppBrand;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Psr\Http\Message\ResponseInterface;
#[Controller(prefix: 'admin/api/menu')]
class MenuController extends AbstractController
{
#[RequestMapping(path:'', methods: 'get')]
public function index(): array
{
$request = $this->request;
$query = AppAdminMenu::query()->orderBy('id');
$pagination = $query->paginate($request->input('limit', 10), page: $request->input('page'));
$data = $query->get()->toArray();
// $data['cover'] = AppHelper::setImageUrl($query['cover']);
// foreach ($data as &$v) {
// $v['cover'] = AppHelper::setImageUrl($v['cover']);
// }
return ['code' => 0, 'msg' => 'ok', 'count' => $pagination->total(), 'data' => $data];
}
#[RequestMapping(path:'list', methods: 'get')]
public function list(): array
{
$items = AppAdminMenu::query()->whereIn('type', [0, 1])->orderBy('weight', 'DESC')->get()->toArray();
$formatted_items = [];
foreach ($items as $item) {
$item['pid'] = (int)$item['pid'];
$item['name'] = $item['title'];
$item['value'] = $item['id'];
$item['icon'] = $item['icon'] ? "layui-icon {$item['icon']}" : '';
$formatted_items[] = $item;
}
return [
'code' => 0,
'data' => TreeHelper::getTree($formatted_items)
];
}
/**
* 新增菜单
* @url /admin/api/menu/insert
* @return ResponseInterface
*/
#[RequestMapping(path: 'insert', methods: 'post')]
public function insert(): \Psr\Http\Message\ResponseInterface
{
$model = new AppAdminMenu();
$model->setRawAttributes($this->request->post());
$model->pid = $model->pid ?: 0;
$model->save();
return $this->response->json([
'code' => 0,
'msg' => 'ok'
]);
}
/**
* 编辑菜单数据
* @return ResponseInterface
*/
#[RequestMapping(path: 'update', methods: 'post')]
public function update(): \Psr\Http\Message\ResponseInterface
{
$model = AppAdminMenu::find($this->request->post('id'));
$model->setRawAttributes($this->request->post());
$model->save();
return $this->response->json([
'code' => 0,
'msg' => 'ok'
]);
}
/**
* 预览菜单数据
* @return ResponseInterface
*/
#[RequestMapping(path: 'view', methods: 'get')]
public function view(): ResponseInterface
{
$id = $this->request->input('id');
$model = AppAdminMenu::find($id)->toArray();
return $this->response->json([
'code' => 0,
'data' => $model,
'msg' => 'ok'
]);
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace App\Controller\admin\api;
use App\Controller\AbstractController;
use App\Enums\ArticlePublishedStatusEnum;
use App\FormModel\admin\articles\ModifyModel;
use App\FormModel\admin\news\NewsFormModel;
use App\Helpers\AppHelper;
use App\Model\AppArticle;
use App\Model\AppBrand;
use App\Model\AppNews;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller(prefix: 'admin/api/news')]
class NewsController extends AbstractController
{
/**
* 文章列表
* @url /admin/api/news
* @return array
*/
#[RequestMapping(path:'', methods: 'get')]
public function index(): array
{
$createdFilter = $this->request->query('created_at', [date('Y-m-d', strtotime('-1 month')), date('Y-m-d', time())]);
foreach ($createdFilter as $index => &$item) {
if ($index == 0) {
$item = strtotime($item . ' 00:00:00');
}
if ($index == 1) {
$item = strtotime($item . ' 23:59:59');
}
}
$ids = [];
$query = AppNews::query()
->select(['id'])
->whereBetween('created_at', $createdFilter)
->orderBy('id', 'desc');
$pagination = $query->paginate($this->request->input('limit', 10), page: $this->request->input('page'));
foreach ($pagination->items() as $item) {
$ids[] = $item->id;
}
$value = AppNews::query()->whereIn('id', $ids)->orderBy('id', 'desc')->get()->toArray();
// $value = AppNews::find($ids, ['title', 'is_record'])->toArray();
return ['code' => 0, 'msg' => 'ok', 'count' => $pagination->total(), 'data' => $value];
}
/**
* 查看文章详情信息
* @url /admin/api/news/view
*/
#[RequestMapping(path:'view', methods: 'get')]
public function view(): \Psr\Http\Message\ResponseInterface
{
$query = AppNews::query()
->where('id', $this->request->query('id'));
return $this->response->json(['code' => 0, 'msg' => 'ok', 'data' => $query->first()]);
}
/**
* 更新文章内容
* @url /admin/api/news/update
*/
#[RequestMapping(path:'update', methods: 'post')]
public function update()
{
$model = new NewsFormModel();
$model->setAttributes($this->request->post());
$model->update();
return $this->response->json(['code' => 0, 'msg' => 'ok']);
}
/**
* 新增新新闻接口
* @url /admin/api/news/insert
*/
#[RequestMapping(path:'insert', methods: 'post')]
public function insert()
{
$model = new NewsFormModel();
$model->setAttributes($this->request->post(), ['title', 'keywords', 'description', 'cover', 'content']);
$model->insert();
return $this->response->json(['code' => 0, 'msg' => 'ok']);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Controller\admin\api;
use App\Controller\AbstractController;
use App\Model\AppAdminMenu;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller(prefix: 'admin/api/permission')]
class PermissionController extends AbstractController
{
#[RequestMapping(path:'', methods: 'get')]
public function index(): array
{
return ['code' => 0, 'msg' => 'ok', 'data' => ['*']];
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Controller\admin\api;
use App\Controller\AbstractController;
use App\Enums\SpiderArticlePublishedStatusEnum;
use App\FormModel\spiderArticle\ReviewModel;
use App\Model\AppSpiderArticle;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller(prefix: 'admin/api/spider-article')]
class SpiderArticleController extends AbstractController
{
#[RequestMapping(path: '', methods: 'get')]
public function index(): array
{
$createdFilter = $this->request->query('created_at', [date('Y-m-d', strtotime('-1 month')), date('Y-m-d', time())]);
foreach ($createdFilter as $index => &$item) {
if ($index == 0) {
$item = strtotime($item . ' 00:00:00');
}
if ($index == 1) {
$item = strtotime($item . ' 23:59:59');
}
}
$titleFilter = $this->request->query('title');
$publishedStatus = $this->request->query('published_status', SpiderArticlePublishedStatusEnum::FALSE);
$request = $this->request;
$query = AppSpiderArticle::formatQuery(['created_at', 'module', 'published_status'])
->select(['id', 'title', 'created_at', 'module', 'source_url', 'published_status'])
->when($publishedStatus !== null, fn($q) => $q->where('published_status', $publishedStatus))
->when($titleFilter, fn($q) => $q->where('title', 'like', "%{$titleFilter}%"))
->when($this->request->query('module', '') !== '', fn($q) => $q->where('module', $this->request->query('module')))
->whereBetween('created_at', $createdFilter)
->orderBy('created_at', 'desc');
$pagination = $query->paginate($request->input('limit', 10), page: $request->input('page'));
return ['code' => 0, 'msg' => 'ok', 'count' => $pagination->total(), 'data' => $pagination->items()];
}
#[RequestMapping(path: 'view', methods: 'get')]
public function view(): \Psr\Http\Message\ResponseInterface
{
$query = AppSpiderArticle::formatQuery(['images', 'module', 'brand'])->find($this->request->query('id'));
return $this->response->json(['code' => 0, 'msg' => 'ok', 'data' => $query->toArray()]);
}
#[RequestMapping(path: 'pre-publish', methods: 'post')]
public function prePublish(): \Psr\Http\Message\ResponseInterface
{
$prePublishModel = new ReviewModel();
$prePublishModel->prePublish($this->request->post('id'));
return $this->response->json(['code' => 0, 'msg' => 'ok']);
}
}

View File

@ -0,0 +1,118 @@
<?php
namespace App\Controller\api\expose\v1;
use App\Controller\AbstractController;
use App\Model\AppKeywordsMonitor;
use App\Model\AppKeywordsMonitorResult;
use App\Model\AppKeywordsMonitorTask;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller(prefix: "/api/expose/v1/tools")]
class ToolsController extends AbstractController
{
/**
* 获取关键词监控的关键词
* @url /api/expose/v1/tools/get-query-keyword
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path:'get-query-keyword', methods:'get')]
public function getQueryKeyword(): \Psr\Http\Message\ResponseInterface
{
$keyword = AppKeywordsMonitorTask::formatQuery(['created_at'])
->where('queried_at', '<=', strtotime('-2 hours'))
->where('is_delete', 0);
if ($keyword) {
$query = $keyword->first()->toArray();
return $this->response->json([
'code' => 0,
'data' => $query
]);
}
return $this->response->json([
'code' => 0,
'data' => ''
]);
}
/**
* 提交监控数据
* @url /api/expose/v1/tools/submit-query-keyword
* @return \Psr\Http\Message\ResponseInterface
*/
#[RequestMapping(path:'submit-query-keyword', methods:'post')]
public function submitQueryKeyword(): \Psr\Http\Message\ResponseInterface
{
$requestData = $this->request->post();
if (!isset($requestData['length']) || !isset($requestData['keyword_id']) || !$requestData['keyword_id'] || !$requestData['image_name'] || !$requestData['ip_info']) {
return $this->response->json([
'code' => 0,
]);
}
// 被查的关键词id
$aid = $requestData['keyword_id'];
foreach ($requestData['items'] ?? [] as $key => $value) {
// 非负面不存储
if (!$value['matched'] || !$value['mu']) {
continue;
}
$query = AppKeywordsMonitorResult::query()->where([
['aid', $aid],
['url', $value['mu']],
['is_delete', 0],
])->first()?->toArray();
// 如果这个负面存过了就不管了
if ($query) {
continue;
}
list($title, $desc) = call_user_func(function () use ($value) {
$content = $value['content'];
$ex = explode(PHP_EOL . PHP_EOL, $content);
if (count($ex) > 1) {
return [$ex[0], $ex[1]];
}
return ['', ''];
});
if (!$title || !$desc) {
continue;
}
$query = new AppKeywordsMonitorResult();
$query->aid = $aid;
$query->title = $title;
$query->description = $desc;
$query->url = $value['mu'];
$query->order = $value['id'];
$ipInfo = json_decode($requestData['ip_info'], true);
$query->ip_address = $ipInfo['ip'];
$query->ip_source = "{$ipInfo['country']}{$ipInfo['province']}{$ipInfo['city']}";
$query->screen_path = $requestData['image_name'];
$query->save();
}
// 更新关键词最后查询时间
$query = AppKeywordsMonitorTask::find($aid);
$query->queried_at = time();
$query->save();
// 更新关键词最后查询时间
$query = AppKeywordsMonitor::query()->where('id', $query->aid)->first();
$query->queried_at = time();
$query->save();
return $this->response->json([]);
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace App\Controller\api\v1;
use App\Controller\AbstractController;
use App\FormModel\api\v1\ArticlesModel;
use App\Helpers\AppHelper;
use App\Model\AppArticle;
use App\Model\AppBrand;
use Hyperf\Collection\Collection;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller]
class ArticlesController extends AbstractController
{
/**
* 文章列表
* @url /api/v1/articles
* @return array
*/
#[RequestMapping(path:'', methods: 'get')]
public function index(): array
{
$request = $this->request;
$query = Model::query()->orderBy('id');
$pagination = $query->paginate($request->input('limit', 10), page: $request->input('page'));
$data = $query->get()->toArray();
// $data['cover'] = AppHelper::setImageUrl($query['cover']);
foreach ($data as &$v) {
$v['cover'] = AppHelper::setImageUrl($v['cover']);
}
return ['code' => 0, 'msg' => 'ok', 'count' => $pagination->total(), 'data' => $data];
}
/**
* 新增/编辑文章
* @url /api/v1/articles/save
* @return array
*/
#[RequestMapping(path:'save', methods: 'post')]
public function save(): array
{
$id = $this->request->input('id');
$model = new ArticlesModel();
if ($id) {
$model->edit();
} else {
$model->create();
}
return [
'code' => 0,
'message' => 'ok'
];
}
#[RequestMapping(path:'brand-search', methods: 'get')]
public function brandSearch(): array
{
$input = $this->request->input('brand');
$query = Model::query()->select(['name', 'cn_name', 'id'])->where('name', 'like', "%$input%")
->orWhere('cn_name', 'like', "%$input%")
->get()->toArray();
return ['code' => 0, 'msg' => 'ok', 'data' => $query];
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Controller\api\v1;
use App\Controller\AbstractController;
use App\FormModel\api\v1\UserModel;
use App\Request\Test;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
#[Controller]
class UserController extends AbstractController
{
#[RequestMapping(path: '/api/v1/user/register', methods: 'post')]
public function register(Test $validator)
{
$validator = $validator->validated();
$model = new UserModel();
$model->register();
return [];
}
public function login()
{
}
public function logout()
{
}
}