Regress likes field of textures table

This commit is contained in:
Pig Fang 2019-05-05 11:21:37 +08:00
parent 26a2b58048
commit b119a8de6d
10 changed files with 108 additions and 39 deletions

View File

@ -0,0 +1,45 @@
<?php
namespace App\Console\Commands;
use Schema;
use App\Models\Texture;
use Illuminate\Console\Command;
class RegressLikesField extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'bs:migrate-v4:likes';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Apply fixes for `likes` field of `textures` table.';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('We are going to update your `textures` table. Please wait...');
$textures = Texture::all();
$bar = $this->output->createProgressBar($textures->count());
$textures->each(function ($texture) use ($bar) {
$texture->likes = $texture->likers->count();
$texture->save();
$bar->advance();
});
$bar->finish();
$this->info("\nCongratulations! Table was updated successfully.");
}
}

View File

@ -18,6 +18,7 @@ class Kernel extends ConsoleKernel
Commands\MigratePlayersTable::class,
Commands\MigrateCloset::class,
Commands\ExecuteInstallation::class,
Commands\RegressLikesField::class,
];
/**

View File

@ -95,6 +95,9 @@ class ClosetController extends Controller
$user->closet()->attach($tid, ['item_name' => $request->name]);
$user->setScore(option('score_per_closet_item'), 'minus');
$texture->likes++;
$texture->save();
$uploader = User::find($texture->uploader);
if ($uploader && $uploader->uid != $user->uid) {
$uploader->score += option('score_award_per_like', 0);
@ -132,7 +135,11 @@ class ClosetController extends Controller
$user->setScore(option('score_per_closet_item'), 'plus');
}
$uploader = User::find(Texture::find($tid)->uploader);
$texture = Texture::find($tid);
$texture->likes--;
$texture->save();
$uploader = User::find($texture->uploader);
$uploader->score -= option('score_award_per_like', 0);
$uploader->save();

View File

@ -97,8 +97,7 @@ class SkinlibController extends Controller
$totalPages = ceil($query->count() / $itemsPerPage);
$sort = $request->input('sort', 'time');
$sortBy = $sort == 'time' ? 'upload_at' : ($sort == 'likes' ? 'likers_count' : $sort);
$query->withCount('likers');
$sortBy = $sort == 'time' ? 'upload_at' : $sort;
$query = $query->orderBy($sortBy, 'desc');
$textures = $query->skip(($currentPage - 1) * $itemsPerPage)->take($itemsPerPage)->get();
@ -228,10 +227,10 @@ class SkinlibController extends Controller
Storage::disk('textures')->put($t->hash, file_get_contents($request->file('file')));
}
$t->likes++;
$t->save();
$user->setScore($cost, 'minus');
$user->closet()->attach($t->tid, ['item_name' => $t->name]);
return json(trans('skinlib.upload.success', ['name' => $request->input('name')]), 0, [
@ -243,47 +242,47 @@ class SkinlibController extends Controller
public function delete(Request $request)
{
$result = Texture::find($request->tid);
$texture = Texture::find($request->tid);
$user = Auth::user();
if (! $result) {
if (! $texture) {
return json(trans('skinlib.non-existent'), 1);
}
if ($result->uploader != $user->uid && ! $user->isAdmin()) {
if ($texture->uploader != $user->uid && ! $user->isAdmin()) {
return json(trans('skinlib.no-permission'), 1);
}
// check if file occupied
if (Texture::where('hash', $result->hash)->count() == 1) {
Storage::disk('textures')->delete($result->hash);
if (Texture::where('hash', $texture->hash)->count() == 1) {
Storage::disk('textures')->delete($texture->hash);
}
$result->likers()->get()->each(function ($user) use ($result) {
$user->closet()->detach($result->tid);
$texture->likers()->get()->each(function ($user) use ($texture) {
$user->closet()->detach($texture->tid);
if (option('return_score')) {
$user->setScore(option('score_per_closet_item'), 'plus');
}
});
if ($u = User::find($result->uploader)) {
if ($u = User::find($texture->uploader)) {
$ret = 0;
if (option('return_score')) {
$ret += $result->size * (
$result->public
$ret += $texture->size * (
$texture->public
? option('score_per_storage')
: option('private_score_per_storage')
);
}
if ($result->public && option('take_back_scores_after_deletion', true)) {
if ($texture->public && option('take_back_scores_after_deletion', true)) {
$ret -= option('score_award_per_texture', 0);
}
$u->setScore($ret, 'plus');
}
if ($result->delete()) {
if ($texture->delete()) {
return json(trans('skinlib.delete.success'), 0);
}
}
@ -322,6 +321,7 @@ class SkinlibController extends Controller
if (option('return_score')) {
$user->setScore(option('score_per_closet_item'), 'plus');
}
$t->likes--;
});
@$uploader->setScore($score_diff, 'plus');

View File

@ -15,17 +15,9 @@ class Texture extends Model
'size' => 'integer',
'uploader' => 'integer',
'public' => 'boolean',
'likes' => 'integer',
];
protected $appends = [
'likes',
];
public function getLikesAttribute()
{
return $this->likers()->count();
}
public function scopeLike($query, $field, $value)
{
return $query->where($field, 'LIKE', "%$value%");

View File

@ -8,6 +8,7 @@ $factory->define(Texture::class, function (Faker\Generator $faker) {
'type' => 'steve',
'hash' => $faker->sha256,
'size' => rand(1, 2048),
'likes' => rand(1, 10),
'uploader' => factory(App\Models\User::class)->create()->uid,
'public' => true,
'upload_at' => $faker->dateTime,
@ -20,6 +21,7 @@ $factory->defineAs(Texture::class, 'alex', function (Faker\Generator $faker) {
'type' => 'alex',
'hash' => $faker->sha256,
'size' => rand(1, 2048),
'likes' => rand(1, 10),
'uploader' => factory(App\Models\User::class)->create()->uid,
'public' => true,
'upload_at' => $faker->dateTime,

View File

@ -0,0 +1,26 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddLikesField extends Migration
{
public function up()
{
if (! Schema::hasColumn('textures', 'likes')) {
Schema::table('textures', function (Blueprint $table) {
$table->integer('likes')->unsigned()->default(0);
});
}
}
public function down()
{
if (Schema::hasColumn('textures', 'likes')) {
Schema::table('textures', function (Blueprint $table) {
$table->dropColumn('likes');
});
}
}
}

View File

@ -0,0 +1,8 @@
<?php
return [
'请您手动打开终端或 PowerShell 执行以下命令以完成升级:',
'Please open terminal or PowerShell to complete upgrade:',
'<code>php artisan migrate --force</code>',
'<code>php artisan bs:migrate-v4:likes</code>',
];

View File

@ -219,7 +219,7 @@ class ClosetControllerTest extends TestCase
'code' => 0,
'message' => trans('user.closet.remove.success'),
]);
$this->assertEquals($likes, Texture::find($texture->tid)->likes);
$this->assertEquals($likes - 1, Texture::find($texture->tid)->likes);
$this->assertEquals($score + option('score_per_closet_item'), $this->user->score);
$this->assertEquals(0, $this->user->closet()->count());
$uploader->refresh();
@ -232,7 +232,7 @@ class ClosetControllerTest extends TestCase
$this->user->closet()->attach($texture->tid, ['item_name' => 'name']);
$score = $this->user->score;
$this->postJson('/user/closet/remove/'.$texture->tid)->assertJson(['code' => 0]);
$this->assertEquals($likes, Texture::find($texture->tid)->likes);
$this->assertEquals($likes - 1, Texture::find($texture->tid)->likes);
$this->assertEquals($score, $this->user->score);
$this->assertEquals(0, $this->user->closet()->count());
}

View File

@ -109,18 +109,6 @@ class SkinlibControllerTest extends TestCase
}, $items);
$this->assertArraySubset($ordered, $items);
// Sort by `likes`
$user = factory(User::class)->create();
$user->closet()->attach($skins->random()->tid, ['item_name' => 'name']);
$items = $this->getJson('/skinlib/data?sort=likes')
->assertJson(['data' => [
'current_uid' => 0,
'total_pages' => 1,
]])
->decodeResponseJson('data')['items'];
$this->assertEquals(1, $items[0]['likes']);
$this->assertEquals(0, $items[1]['likes']);
// Search
$keyword = Str::limit($skins->random()->name, 1, '');
$keyworded = $skins