show-exam

This commit is contained in:
xiaomlove
2021-04-25 21:28:58 +08:00
parent 512af7511d
commit 7cfde3f95b
13 changed files with 206 additions and 17 deletions
+6 -3
View File
@@ -2,9 +2,13 @@
namespace App\Console\Commands;
use App\Models\Exam;
use App\Models\ExamProgress;
use App\Models\ExamUser;
use App\Models\User;
use App\Repositories\ExamRepository;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class Test extends Command
@@ -40,9 +44,8 @@ class Test extends Command
*/
public function handle()
{
$examRep = new ExamRepository();
$user = User::query()->find(1);
$r = $examRep->assignToUser($user->id);
$rep = new ExamRepository();
$r = $rep->listUserExamProgress(1);
dd($r);
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ namespace App\Models;
class ExamProgress extends NexusModel
{
protected $fillable = ['exam_id', 'uid', 'type_id', 'value'];
protected $fillable = ['exam_user_id', 'exam_id', 'uid', 'index', 'value', 'torrent_id'];
public $timestamps = true;
}
+5
View File
@@ -35,5 +35,10 @@ class ExamUser extends NexusModel
return $this->belongsTo(User::class, 'uid');
}
public function progresses()
{
return $this->hasMany(ExamProgress::class, 'exam_user_id');
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace App\Models;
class Torrent extends NexusModel
{
protected $fillable = [
'name', 'filename', 'save_as', 'descr', 'small_descr', 'ori_descr',
'category', 'source', 'medium', 'codec', 'standard', 'processing', 'team', 'audiocodec',
'size', 'added', 'type', 'numfiles', 'owner', 'nfo', 'sp_state', 'promotion_time_type',
'promotion_until', 'anonymous', 'url', 'pos_state', 'cache_stamp', 'picktype', 'picktime',
'last_reseed', 'pt_gen', 'tags', 'technical_info'
];
const VISIBLE_YES = 'yes';
const VISIBLE_NO = 'no';
const BANNED_YES = 'yes';
const BANNED_NO = 'no';
public $timestamps = true;
public function checkIsNormal(array $fields = ['visible', 'banned'])
{
if (in_array('visible', $fields) && $this->getAttribute('visible') != self::VISIBLE_YES) {
throw new \InvalidArgumentException(sprintf('Torrent: %s is not visible.', $this->id));
}
if (in_array('banned', $fields) && $this->getAttribute('banned') == self::BANNED_YES) {
throw new \InvalidArgumentException(sprintf('Torrent: %s is banned.', $this->id));
}
return true;
}
}
+16 -5
View File
@@ -16,6 +16,9 @@ class User extends Authenticatable
const STATUS_CONFIRMED = 'confirmed';
const STATUS_PENDING = 'pending';
const ENABLED_YES = 'yes';
const ENABLED_NO = 'no';
const CLASS_PEASANT = "0";
const CLASS_USER = "1";
const CLASS_POWER_USER = "2";
@@ -96,12 +99,20 @@ class User extends Authenticatable
* @var array
*/
protected $casts = [
'added' => 'datetime',
];
protected $dates = [
'added'
];
public function checkIsNormal(array $fields = ['status', 'enabled'])
{
if (in_array('visible', $fields) && $this->getAttribute('status') != self::STATUS_CONFIRMED) {
throw new \InvalidArgumentException(sprintf('User: %s is not confirmed.', $this->id));
}
if (in_array('enabled', $fields) && $this->getAttribute('enabled') != self::ENABLED_YES) {
throw new \InvalidArgumentException(sprintf('User: %s is not enabled.', $this->id));
}
return true;
}
public function exams(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
@@ -111,7 +122,7 @@ class User extends Authenticatable
public function examDetails(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(ExamUser::class. 'uid');
return $this->hasMany(ExamUser::class, 'uid');
}
+67
View File
@@ -2,8 +2,10 @@
namespace App\Repositories;
use App\Models\Exam;
use App\Models\ExamProgress;
use App\Models\ExamUser;
use App\Models\Setting;
use App\Models\Torrent;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Arr;
@@ -141,6 +143,7 @@ class ExamRepository extends BaseRepository
return $filtered;
}
/**
* assign exam to user
*
@@ -187,6 +190,70 @@ class ExamRepository extends BaseRepository
}
public function addProgress(int $examUserId, int $indexId, int $value, int $torrentId)
{
$examUser = ExamUser::query()->with(['exam', 'user'])->findOrFail($examUserId);
if ($examUser->status != ExamUser::STATUS_NORMAL) {
throw new \InvalidArgumentException("ExamUser: $examUserId is not normal.");
}
if (!isset(Exam::$indexes[$indexId])) {
throw new \InvalidArgumentException("Invalid index id: $indexId.");
}
$exam = $examUser->exam;
$indexes = collect($exam->indexes)->keyBy('index');
if (!$indexes->has($indexId)) {
throw new \InvalidArgumentException(sprintf('Exam: %s does not has index: %s', $exam->id, $indexId));
}
$index = $indexes->get($indexId);
if (!isset($index['checked']) || !$index['checked']) {
throw new \InvalidArgumentException(sprintf('Exam: %s index: %s is not checked', $exam->id, $indexId));
}
$torrentFields = ['id', 'visible', 'banned'];
$torrent = Torrent::query()->findOrFail($torrentId, $torrentFields);
$torrent->checkIsNormal(true, $torrentFields);
$user = $examUser->user;
$user->checkIsNormal();
$data = [
'uid' => $user->id,
'exam_id' => $exam->id,
'torrent_id' => $torrentId,
'index' => $indexId,
'value' => $value,
];
Log::info('[addProgress]', $data);
return $examUser->progresses()->create($data);
}
public function listUserExamProgress($uid, $status = null)
{
$logPrefix = "uid: $uid";
$query = ExamUser::query()->with(['exam', 'user'])->where('uid', $uid)->orderBy('exam_id', 'desc');
if ($status) {
$query->where('status', $status);
}
$result = $query->paginate();
$idArr = array_column($result->items(), 'id');
$progressSum = ExamProgress::query()
->whereIn('exam_user_id', $idArr)
->groupBy(['exam_user_id', 'index'])
->selectRaw('`exam_user_id`, `index`, sum(`value`) as `index_sum`')
->get();
$map = [];
foreach ($progressSum as $value) {
$map[$value->exam_user_id][$value->index] = $value->index_sum;
}
foreach ($result as &$item) {
$item->progress_value = $map[$item->id] ?? [];
}
return $result;
}