✨ 相册列表接口
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Album;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AlbumController extends Controller
|
||||
{
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$albums = $user->albums()->filter($request)->paginate(40);
|
||||
$albums->getCollection()->each(function (Album $album) {
|
||||
$album->setVisible(['id', 'name', 'intro', 'image_num']);
|
||||
});
|
||||
return $this->success('success', $albums);
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Enums\ImagePermission;
|
||||
use App\Exceptions\UploadException;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Image;
|
||||
use App\Models\User;
|
||||
use App\Services\ImageService;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@@ -35,6 +37,27 @@ class Album extends Model
|
||||
'intro' => '',
|
||||
];
|
||||
|
||||
public function scopeFilter(Builder $builder, Request $request)
|
||||
{
|
||||
return $builder->when($request->query('order') ?: 'newest', function (Builder $builder, $order) {
|
||||
switch ($order) {
|
||||
case 'earliest':
|
||||
$builder->orderBy('created_at');
|
||||
break;
|
||||
case 'most':
|
||||
$builder->orderByDesc('image_num');
|
||||
break;
|
||||
case 'least':
|
||||
$builder->orderBy('image_num');
|
||||
break;
|
||||
default:
|
||||
$builder->latest();
|
||||
}
|
||||
})->when($request->query('keyword'), function (Builder $builder, $keyword) {
|
||||
$builder->whereRaw("concat(name,intro) like ?", ["%{$keyword}%"]);
|
||||
});
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||
|
||||
@@ -582,6 +582,197 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-xl mb-2 text-gray-800 font-semibold">相册相关</p>
|
||||
<div class="space-y-4 bg-white p-3 rounded-md mb-5">
|
||||
<div>
|
||||
<p class="text-lg text-gray-700 font-semibold">相册列表</p>
|
||||
<x-code><span class="text-sky-500 select-none">GET </span>/albums</x-code>
|
||||
|
||||
<div class="my-4 overflow-x-auto">
|
||||
<p class="text-sm mb-2">请求参数(Query)</p>
|
||||
<table class="min-w-full">
|
||||
<thead class="bg-white border">
|
||||
<tr>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
字段
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
类型
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
说明
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white border divide-y text-sm">
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">page</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Integer</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">页码</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">order</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">String</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">排序方式,newest=最新,earliest=最早,most=图片最多,least=图片最少</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">keyword</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">String</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">筛选关键字</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="my-4 overflow-x-auto">
|
||||
<p class="text-sm mb-2">返回参数</p>
|
||||
<table class="min-w-full">
|
||||
<thead class="bg-white border">
|
||||
<tr>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
字段
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
类型
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
说明
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white border divide-y text-sm">
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">status</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Boolean</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">状态,true 或 false</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">message</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">String</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">描述信息</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">data</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Object</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">数据</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-6">current_page</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Integer</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">当前所在页页码</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-6">last_page</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Integer</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">最后一页页码</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-6">per_page</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Integer</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">每页展示数据数量</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-6">total</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Integer</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">图片总数量</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-6">data</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Object[]</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">相册列表</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-10">id</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Integer</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">相册自增ID</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-10">name</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">String</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">相册名称</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-10">intro</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">String</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">相册简介</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap pl-10">image_num</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Integer</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">相册图片数量</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-lg text-gray-700 font-semibold">删除图片</p>
|
||||
<x-code><span class="text-red-300 select-none">DELETE </span>/images/:key</x-code>
|
||||
|
||||
<div class="my-4 overflow-x-auto">
|
||||
<p class="text-sm mb-2">请求参数(Params)</p>
|
||||
<table class="min-w-full">
|
||||
<thead class="bg-white border">
|
||||
<tr>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
字段
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
类型
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
说明
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white border divide-y text-sm">
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">key</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">String</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">图片密钥</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="my-4 overflow-x-auto">
|
||||
<p class="text-sm mb-2">返回参数</p>
|
||||
<table class="min-w-full">
|
||||
<thead class="bg-white border">
|
||||
<tr>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
字段
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
类型
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">
|
||||
说明
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white border divide-y text-sm">
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">status</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Boolean</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">状态,true 或 false</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">message</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">String</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">描述信息</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="px-3 py-2 whitespace-nowrap">data</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">Object</td>
|
||||
<td class="px-3 py-2 whitespace-nowrap">数据</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\Api\V1\ImageController;
|
||||
use App\Http\Controllers\Api\V1\AlbumController;
|
||||
use App\Http\Controllers\Api\V1\TokenController;
|
||||
|
||||
/*
|
||||
@@ -24,6 +25,7 @@ Route::group(['prefix' => 'v1'], function () {
|
||||
], function () {
|
||||
Route::get('images', [ImageController::class, 'images']);
|
||||
Route::delete('images/{key}', [ImageController::class, 'destroy']);
|
||||
Route::get('albums', [AlbumController::class, 'index']);
|
||||
Route::delete('tokens', [TokenController::class, 'clear']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user