optimize querying reports

This commit is contained in:
Pig Fang 2020-06-08 09:51:35 +08:00
parent 322b1a4c5e
commit 2fb67537df
5 changed files with 46 additions and 24 deletions

View File

@ -20,6 +20,7 @@ class ReportController extends Controller
'tid' => 'required|exists:textures',
'reason' => 'required',
]);
/** @var User */
$reporter = auth()->user();
$tid = $data['tid'];
$reason = $data['reason'];
@ -68,22 +69,9 @@ class ReportController extends Controller
{
$q = $request->input('q');
$pagination = Report::usingSearchString($q)->paginate(9);
$collection = $pagination->getCollection()->map(function ($report) {
$uploader = User::find($report->uploader);
if ($uploader) {
$report->uploaderName = $uploader->nickname;
}
if ($report->informer) {
$report->reporterName = $report->informer->nickname;
}
$report->getAttribute('texture');
return $report;
});
$pagination->setCollection($collection);
return $pagination;
return Report::usingSearchString($q)
->with(['texture', 'textureUploader', 'informer'])
->paginate(9);
}
public function review(

View File

@ -51,6 +51,11 @@ class Report extends Model
return $this->belongsTo(Texture::class, 'tid', 'tid');
}
public function textureUploader()
{
return $this->belongsTo(User::class, 'uploader', 'uid');
}
public function informer()
{
return $this->belongsTo(User::class, 'reporter', 'uid');

View File

@ -49,7 +49,7 @@ const ImageBox: React.FC<Props> = (props) => {
{t('skinlib.show.uploader')}
{': '}
</b>
<span className="mr-1">{report.uploaderName}</span>
<span className="mr-1">{report.texture_uploader?.nickname}</span>
(UID: {report.uploader})
</div>
<div className="card-body">
@ -114,7 +114,7 @@ const ImageBox: React.FC<Props> = (props) => {
{t('report.reporter')}
{': '}
</b>
<span className="mr-1">{report.reporterName}</span>
<span className="mr-1">{report.informer?.nickname}</span>
(UID: {report.reporter})
</div>
<details>

View File

@ -1,4 +1,4 @@
import { Texture } from '@/scripts/types'
import { Texture, User } from '@/scripts/types'
export const enum Status {
Pending = 0,
@ -11,9 +11,9 @@ export type Report = {
tid: number
texture: Texture | null
uploader: number
uploaderName: string
texture_uploader: User | null
reporter: number
reporterName: string
informer: User | null
reason: string
status: Status
report_at: string

View File

@ -3,7 +3,7 @@ import { render, waitFor, fireEvent } from '@testing-library/react'
import { createPaginator } from '../../utils'
import { t } from '@/scripts/i18n'
import * as fetch from '@/scripts/net'
import { Texture, TextureType } from '@/scripts/types'
import { Texture, TextureType, User, UserPermission } from '@/scripts/types'
import ReportsManagement from '@/views/admin/ReportsManagement'
import { Report, Status } from '@/views/admin/ReportsManagement/types'
@ -14,9 +14,31 @@ const fixture: Readonly<Report> = Object.freeze<Report>({
tid: 1,
texture: null,
uploader: 1,
uploaderName: 'xx',
texture_uploader: Object.freeze<Readonly<User>>({
uid: 1,
email: 'a@b.c',
nickname: 'abc',
score: 1000,
avatar: 0,
permission: UserPermission.Normal,
ip: '::1',
last_sign_at: new Date().toString(),
register_at: new Date().toString(),
verified: true,
}),
reporter: 2,
reporterName: 'yy',
informer: Object.freeze<Readonly<User>>({
uid: 1,
email: 'a@b.c',
nickname: 'abc',
score: 1000,
avatar: 0,
permission: UserPermission.Normal,
ip: '::1',
last_sign_at: new Date().toString(),
register_at: new Date().toString(),
verified: true,
}),
reason: 'nsfw',
status: Status.Pending,
report_at: new Date().toString(),
@ -45,6 +67,13 @@ test('search reports', async () => {
)
})
test('empty reporter or texture uploader', async () => {
const report = { ...fixture, texture_uploader: null, informer: null }
fetch.get.mockResolvedValue(createPaginator([report]))
render(<ReportsManagement />)
})
test('preview texture', async () => {
const texture: Texture = {
tid: fixture.tid,