|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
|
|
|
|
|
|
use App\Http\Controllers\Controller;
|
|
|
|
|
use App\Models\CrawlAddress;
|
|
|
|
|
use App\Models\DictItem;
|
|
|
|
|
use App\Models\DictType;
|
|
|
|
|
use App\Support\ApiResponse;
|
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Illuminate\Validation\Rule;
|
|
|
|
|
|
|
|
|
|
class CrawlAddressController extends Controller
|
|
|
|
|
{
|
|
|
|
|
use ApiResponse;
|
|
|
|
|
|
|
|
|
|
public function index(Request $request): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
$query = CrawlAddress::query()->with(['categoryDictItem', 'university']);
|
|
|
|
|
|
|
|
|
|
if ($type = $request->query('target_type')) {
|
|
|
|
|
$query->where('target_type', $type);
|
|
|
|
|
}
|
|
|
|
|
if ($kw = trim((string) $request->query('keyword', ''))) {
|
|
|
|
|
$query->where(function ($q) use ($kw) {
|
|
|
|
|
$q->where('name', 'like', "%{$kw}%")
|
|
|
|
|
->orWhere('request_url', 'like', "%{$kw}%")
|
|
|
|
|
->orWhere('keyword', 'like', "%{$kw}%");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if ($request->filled('status')) {
|
|
|
|
|
$query->where('status', (int) $request->query('status'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$paginator = $query
|
|
|
|
|
->orderBy('sort')
|
|
|
|
|
->orderByDesc('id')
|
|
|
|
|
->paginate((int) $request->query('page_size', 20))
|
|
|
|
|
->withQueryString();
|
|
|
|
|
|
|
|
|
|
$paginator->getCollection()->transform(fn (CrawlAddress $row) => $this->serialize($row));
|
|
|
|
|
|
|
|
|
|
return $this->paginated($paginator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function options(Request $request): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
$query = CrawlAddress::query()
|
|
|
|
|
->where('status', 1)
|
|
|
|
|
->orderBy('sort')
|
|
|
|
|
->orderBy('name');
|
|
|
|
|
|
|
|
|
|
if ($type = $request->query('target_type')) {
|
|
|
|
|
$query->where('target_type', $type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$items = $query->get()->map(fn (CrawlAddress $row) => $this->serialize($row));
|
|
|
|
|
|
|
|
|
|
return $this->ok(['items' => $items]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function store(Request $request): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
$data = $this->validatePayload($request);
|
|
|
|
|
$row = CrawlAddress::query()->create($data);
|
|
|
|
|
|
|
|
|
|
return $this->ok($this->serialize($row->fresh(['categoryDictItem', 'university'])), '已创建');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function update(Request $request, int $crawlAddress): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
$row = CrawlAddress::query()->findOrFail($crawlAddress);
|
|
|
|
|
$data = $this->validatePayload($request, $row);
|
|
|
|
|
$row->fill($data);
|
|
|
|
|
$row->save();
|
|
|
|
|
|
|
|
|
|
return $this->ok($this->serialize($row->fresh(['categoryDictItem', 'university'])), '已保存');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function destroy(int $crawlAddress): JsonResponse
|
|
|
|
|
{
|
|
|
|
|
CrawlAddress::query()->whereKey($crawlAddress)->delete();
|
|
|
|
|
|
|
|
|
|
return $this->ok(null, '已删除');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return array<string, mixed>
|
|
|
|
|
*/
|
|
|
|
|
protected function validatePayload(Request $request, ?CrawlAddress $existing = null): array
|
|
|
|
|
{
|
|
|
|
|
$newsCategoryTypeId = DictType::query()
|
|
|
|
|
->where('code', 'news_category')
|
|
|
|
|
->where('status', 1)
|
|
|
|
|
->value('id');
|
|
|
|
|
|
|
|
|
|
$data = $request->validate([
|
|
|
|
|
'target_type' => ['required', 'in:paper,industry_news,teacher'],
|
|
|
|
|
'name' => ['required', 'string', 'max:128'],
|
|
|
|
|
'request_url' => ['required', 'url', 'max:512'],
|
|
|
|
|
'keyword' => ['nullable', 'string', 'max:512'],
|
|
|
|
|
'category_dict_item_id' => [
|
|
|
|
|
'nullable',
|
|
|
|
|
'integer',
|
|
|
|
|
Rule::exists('dict_items', 'id')->where(
|
|
|
|
|
fn ($q) => $q->where('dict_type_id', $newsCategoryTypeId)->where('status', 1)
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
'university_id' => ['nullable', 'integer', 'exists:universities,id'],
|
|
|
|
|
'department' => ['nullable', 'string', 'max:128'],
|
|
|
|
|
'sort' => ['nullable', 'integer', 'min:0'],
|
|
|
|
|
'status' => ['required', 'integer', 'in:0,1'],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$data['name'] = trim($data['name']);
|
|
|
|
|
$data['keyword'] = isset($data['keyword']) ? trim((string) $data['keyword']) : null;
|
|
|
|
|
if ($data['keyword'] === '') {
|
|
|
|
|
$data['keyword'] = null;
|
|
|
|
|
}
|
|
|
|
|
$data['sort'] = (int) ($data['sort'] ?? 0);
|
|
|
|
|
$data['status'] = (int) $data['status'];
|
|
|
|
|
|
|
|
|
|
if ($data['target_type'] !== 'industry_news') {
|
|
|
|
|
$data['category_dict_item_id'] = null;
|
|
|
|
|
}
|
|
|
|
|
if ($data['target_type'] !== 'teacher') {
|
|
|
|
|
$data['university_id'] = null;
|
|
|
|
|
$data['department'] = null;
|
|
|
|
|
} else {
|
|
|
|
|
$data['department'] = isset($data['department']) ? trim((string) $data['department']) : null;
|
|
|
|
|
if ($data['department'] === '') {
|
|
|
|
|
$data['department'] = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return array<string, mixed>
|
|
|
|
|
*/
|
|
|
|
|
protected function serialize(CrawlAddress $row): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'id' => $row->id,
|
|
|
|
|
'target_type' => $row->target_type,
|
|
|
|
|
'name' => $row->name,
|
|
|
|
|
'request_url' => $row->request_url,
|
|
|
|
|
'keyword' => $row->keyword,
|
|
|
|
|
'category_dict_item_id' => $row->category_dict_item_id,
|
|
|
|
|
'category_label' => $row->categoryDictItem?->label,
|
|
|
|
|
'university_id' => $row->university_id,
|
|
|
|
|
'university_name' => $row->university?->name,
|
|
|
|
|
'department' => $row->department,
|
|
|
|
|
'sort' => (int) $row->sort,
|
|
|
|
|
'status' => (int) $row->status,
|
|
|
|
|
'created_at' => $row->created_at?->toIso8601String(),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|