S2OJ/web/app/models/ClickZans.php
Baoshuo bc3cf49280
All checks were successful
continuous-integration/drone/push Build is passing
feat: click_zan cnt block title
2023-02-24 17:21:09 +08:00

127 lines
2.8 KiB
PHP

<?php
class ClickZans {
public static function getTable($type) {
switch ($type) {
case 'B':
return 'blogs';
case 'BC':
return 'blogs_comments';
case 'P':
return 'problems';
case 'C':
return 'contests';
}
return null;
}
public static function canClickZan($id, $type, $user) {
switch ($type) {
case 'P':
return UOJProblem::query($id)->userCanClickZan($user);
default:
return true;
}
}
public static function query($id, $type, $user) {
if ($user == null) {
return 0;
}
$row = DB::selectFirst([
"select val from click_zans",
"where", [
'username' => $user['username'],
'type' => $type,
'target_id' => $id
]
]);
if ($row == null) {
return 0;
}
return $row['val'];
}
public static function click($id, $type, $user, $delta) {
if (!DB::$in_transaction) {
return DB::transaction(fn () => ClickZans::click($id, $type, $user, $delta));
}
$table_name = ClickZans::getTable($type);
$cur = ClickZans::query($id, $type, $user);
$row = DB::selectFirst([
"select zan from", DB::table($table_name),
"where", ['id' => $id], DB::for_update()
]);
if (!$row) {
return '<div class="text-danger">failed</div>';
}
if ($cur != $delta) {
$cur += $delta;
if ($cur == 0) {
DB::delete([
"delete from click_zans",
"where", [
'username' => Auth::id(),
'type' => $type,
'target_id' => $id
]
]);
} elseif ($cur != $delta) {
DB::update([
"update click_zans",
"set", ['val' => $cur],
"where", [
'username' => Auth::id(),
'type' => $type,
'target_id' => $id
]
]);
} else {
DB::insert([
"insert into click_zans",
"(username, type, target_id, val)", "values",
DB::tuple([Auth::id(), $type, $id, $cur])
]);
}
$cnt = $row['zan'] + $delta;
DB::update([
"update", DB::table($table_name),
"set", ['zan' => $cnt],
"where", ['id' => $id]
]);
} else {
$cnt = $row['zan'];
}
return ClickZans::getBlock($type, $id, $cnt, $cur);
}
public static function getBlock($type, $id, $cnt, $val = null) {
if ($val === null) {
$val = ClickZans::query($id, $type, Auth::user());
}
return '<div class="uoj-click-zan-block" data-id="' . $id . '" data-type="' . $type . '" data-val="' . $val . '" data-cnt="' . $cnt . '"></div>';
}
public static function getCntBlock($cnt) {
$cls = 'uoj-click-zan-block-';
if ($cnt > 0) {
$cls .= 'positive';
} elseif ($cnt < 0) {
$cls .= 'negative';
} else {
$cls .= 'neutral';
}
$display_cnt = $cnt > 0 ? '+' . $cnt : $cnt;
if ($cnt < 0) $display_cnt = '-?';
return '<span class="' . $cls . '"><span class="uoj-click-zan-cnt" title="' . $cnt . '">[<strong>' . $display_cnt . '</strong>]</span></span>';
}
}