diff --git a/app/Http/Controllers/CommentController.php b/app/Http/Controllers/CommentController.php index 8f63b456..db8e0a1d 100644 --- a/app/Http/Controllers/CommentController.php +++ b/app/Http/Controllers/CommentController.php @@ -61,7 +61,7 @@ class CommentController extends Controller ]; $data = array_filter($data); foreach ($allTypes as $type) { - if ($data['type'] == $type && empty($data[$type . "_id"])) { + if ($data['type'] == $type && empty($data[$type])) { throw new \InvalidArgumentException("require {$type}_id"); } } diff --git a/app/Http/Controllers/MessageController.php b/app/Http/Controllers/MessageController.php index 184ea1fd..0510f7b7 100644 --- a/app/Http/Controllers/MessageController.php +++ b/app/Http/Controllers/MessageController.php @@ -51,6 +51,7 @@ class MessageController extends Controller public function show($id) { $message = Message::query()->with(['send_user'])->findOrFail($id); + $message->update(['unread' => 'no']); $resource = new MessageResource($message); $resource->additional([ 'page_title' => nexus_trans('message.show.page_title'), diff --git a/app/Http/Controllers/NewsController.php b/app/Http/Controllers/NewsController.php index 7961caee..a766e85b 100644 --- a/app/Http/Controllers/NewsController.php +++ b/app/Http/Controllers/NewsController.php @@ -5,8 +5,11 @@ namespace App\Http\Controllers; use App\Http\Resources\NewsResource; use App\Models\News; use App\Repositories\NewsRepository; +use Carbon\Carbon; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; use Illuminate\Validation\Rule; +use Nexus\Database\NexusDB; class NewsController extends Controller { @@ -95,17 +98,21 @@ class NewsController extends Controller } /** - * @todo update the unread cache - * * @return array */ public function latest() { + $user = Auth::user(); $result = News::query()->orderBy('id', 'desc')->first(); $resource = new NewsResource($result); $resource->additional([ 'site_info' => site_info(), ]); + /** + * Visiting the home page is the same as viewing the latest news + * @see functions.php line 2590 + */ + $user->update(['last_home' => Carbon::now()]); return $this->success($resource); } diff --git a/app/Http/Controllers/RewardController.php b/app/Http/Controllers/RewardController.php index 4af1028c..7288470b 100644 --- a/app/Http/Controllers/RewardController.php +++ b/app/Http/Controllers/RewardController.php @@ -53,7 +53,7 @@ class RewardController extends Controller ]); $result = $this->repository->store($request->torrent_id, $request->value, Auth::user()); $resource = new RewardResource($result); - return $this->success($resource); + return $this->success($resource, '赠魔成功!'); } /** diff --git a/app/Http/Controllers/ThankController.php b/app/Http/Controllers/ThankController.php index a2d07ec6..3f1be909 100644 --- a/app/Http/Controllers/ThankController.php +++ b/app/Http/Controllers/ThankController.php @@ -3,10 +3,13 @@ namespace App\Http\Controllers; use App\Http\Resources\ThankResource; +use App\Models\Setting; use App\Models\Thank; use App\Models\Torrent; +use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; class ThankController extends Controller { @@ -39,17 +42,48 @@ class ThankController extends Controller */ public function store(Request $request) { + $user = Auth::user(); $request->validate(['torrent_id' => 'required']); $torrentId = $request->torrent_id; $torrent = Torrent::query()->findOrFail($torrentId, Torrent::$commentFields); $torrent->checkIsNormal(); - $user = Auth::user(); + $torrentOwner = User::query()->findOrFail($torrent->owner); + if ($user->id == $torrentOwner->id) { + throw new \LogicException("you can't thank to yourself"); + } + $torrentOwner->checkIsNormal(); if ($user->thank_torrent_logs()->where('torrentid', $torrentId)->exists()) { throw new \LogicException("you already thank this torrent"); } - $result = $user->thank_torrent_logs()->create(['torrentid' => $torrentId]); + + $result = DB::transaction(function () use ($user, $torrentOwner, $torrent) { + $thank = $user->thank_torrent_logs()->create(['torrentid' => $torrent->id]); + $sayThanksBonus = Setting::get('bonus.saythanks'); + $receiveThanksBonus = Setting::get('bonus.receivethanks'); + if ($sayThanksBonus > 0) { + $affectedRows = User::query() + ->where('id', $user->id) + ->where('seedbonus', $user->seedbonus) + ->increment('seedbonus', $sayThanksBonus); + if ($affectedRows != 1) { + do_log("affectedRows: $affectedRows, query: " . last_query(), 'error'); + throw new \RuntimeException("increment user bonus fail."); + } + } + if ($receiveThanksBonus > 0) { + $affectedRows = User::query() + ->where('id', $torrentOwner->id) + ->where('seedbonus', $torrentOwner->seedbonus) + ->increment('seedbonus', $receiveThanksBonus); + if ($affectedRows != 1) { + do_log("affectedRows: $affectedRows, query: " . last_query(), 'error'); + throw new \RuntimeException("increment owner bonus fail."); + } + } + return $thank; + }); $resource = new ThankResource($result); - return $this->success($resource); + return $this->success($resource, '说谢谢成功!'); } /** diff --git a/app/Http/Controllers/ToolController.php b/app/Http/Controllers/ToolController.php index 57d2f247..3949f77c 100644 --- a/app/Http/Controllers/ToolController.php +++ b/app/Http/Controllers/ToolController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use App\Repositories\ToolRepository; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class ToolController extends Controller { @@ -14,4 +15,11 @@ class ToolController extends Controller $this->repository = $repository; } + public function notifications(): array + { + $user = Auth::user(); + $result = $this->repository->getNotificationCount($user); + return $this->success($result); + } + } diff --git a/app/Http/Resources/TorrentResource.php b/app/Http/Resources/TorrentResource.php index 435ff0b8..cea502aa 100644 --- a/app/Http/Resources/TorrentResource.php +++ b/app/Http/Resources/TorrentResource.php @@ -35,12 +35,14 @@ class TorrentResource extends JsonResource 'numfiles' => $this->numfiles, 'sp_state' => $this->sp_state, 'sp_state_real' => $this->sp_state_real, - 'sp_state_real_text' => $this->spStateRealText, + 'promotion_info' => $this->promotionInfo, 'hr' => $this->hr, 'pick_type' => $this->picktype, 'pick_time' => $this->picktime, + 'pick_info' => $this->pickInfo, 'download_url' => $this->download_url, 'user' => new UserResource($this->whenLoaded('user')), + 'anonymous' => $this->anonymous, 'basic_category' => new CategoryResource($this->whenLoaded('basic_category')), 'tags' => TagResource::collection($this->whenLoaded('tags')), 'thanks' => ThankResource::collection($this->whenLoaded('thanks')), diff --git a/app/Models/Comment.php b/app/Models/Comment.php index f560e4cd..4f79707a 100644 --- a/app/Models/Comment.php +++ b/app/Models/Comment.php @@ -39,11 +39,13 @@ class Comment extends NexusModel ], ]; - public function scopeType(Builder $query, $type) + public function scopeType(Builder $query, string $type, int $typeValue) { foreach (self::TYPE_MAPS as $key => $value) { if ($type != $key) { $query->where($value['foreign_key'], 0); + } else { + $query->where($value['foreign_key'], $typeValue); } } return $query; diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index d1d360e4..24d73f41 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -69,18 +69,77 @@ class Torrent extends NexusModel const PROMOTION_ONE_THIRD_DOWN = 7; public static array $promotionTypes = [ - self::PROMOTION_NORMAL => ['text' => 'Normal', 'up_multiplier' => 1, 'down_multiplier' => 1], - self::PROMOTION_FREE => ['text' => 'Free', 'up_multiplier' => 1, 'down_multiplier' => 0], - self::PROMOTION_TWO_TIMES_UP => ['text' => '2X', 'up_multiplier' => 2, 'down_multiplier' => 1], - self::PROMOTION_FREE_TWO_TIMES_UP => ['text' => '2X Free', 'up_multiplier' => 2, 'down_multiplier' => 0], - self::PROMOTION_HALF_DOWN => ['text' => '50%', 'up_multiplier' => 1, 'down_multiplier' => 0.5], - self::PROMOTION_HALF_DOWN_TWO_TIMES_UP => ['text' => '2X 50%', 'up_multiplier' => 2, 'down_multiplier' => 0.5], - self::PROMOTION_ONE_THIRD_DOWN => ['text' => '30%', 'up_multiplier' => 1, 'down_multiplier' => 0.3], + self::PROMOTION_NORMAL => [ + 'text' => 'Normal', + 'up_multiplier' => 1, + 'down_multiplier' => 1, + 'color' => '' + ], + self::PROMOTION_FREE => [ + 'text' => 'Free', + 'up_multiplier' => 1, + 'down_multiplier' => 0, + 'color' => 'linear-gradient(to right, rgba(0,52,206,0.5), rgba(0,52,206,1), rgba(0,52,206,0.5))' + ], + self::PROMOTION_TWO_TIMES_UP => [ + 'text' => '2X', + 'up_multiplier' => 2, + 'down_multiplier' => 1, + 'color' => 'linear-gradient(to right, rgba(0,153,0,0.5), rgba(0,153,0,1), rgba(0,153,0,0.5))' + ], + self::PROMOTION_FREE_TWO_TIMES_UP => [ + 'text' => '2X Free', + 'up_multiplier' => 2, + 'down_multiplier' => 0, + 'color' => 'linear-gradient(to right, rgba(0,153,0,1), rgba(0,52,206,1)' + ], + self::PROMOTION_HALF_DOWN => [ + 'text' => '50%', + 'up_multiplier' => 1, + 'down_multiplier' => 0.5, + 'color' => 'linear-gradient(to right, rgba(220,0,3,0.5), rgba(220,0,3,1), rgba(220,0,3,0.5))' + ], + self::PROMOTION_HALF_DOWN_TWO_TIMES_UP => [ + 'text' => '2X 50%', + 'up_multiplier' => 2, + 'down_multiplier' => 0.5, + 'color' => 'linear-gradient(to right, rgba(0,153,0,1), rgba(220,0,3,1)' + ], + self::PROMOTION_ONE_THIRD_DOWN => [ + 'text' => '30%', + 'up_multiplier' => 1, + 'down_multiplier' => 0.3, + 'color' => 'linear-gradient(to right, rgba(65,23,73,0.5), rgba(65,23,73,1), rgba(65,23,73,0.5))' + ], + ]; + + const PICK_NORMAL = 'normal'; + const PICK_HOT = 'hot'; + const PICK_CLASSIC = 'classic'; + const PICK_RECOMMENDED = 'recommended'; + + public static array $pickTypes = [ + self::PICK_NORMAL => ['text' => self::PICK_NORMAL, 'color' => ''], + self::PICK_HOT => ['text' => self::PICK_HOT, 'color' => '#e78d0f'], + self::PICK_CLASSIC => ['text' => self::PICK_CLASSIC, 'color' => '#77b300'], + self::PICK_RECOMMENDED => ['text' => self::PICK_RECOMMENDED, 'color' => '#820084'], ]; const BONUS_REWARD_VALUES = [50, 100, 200, 500, 1000]; + public function getPickInfoAttribute() + { + $info = self::$pickTypes[$this->picktype] ?? null; + if ($info) { + $info['text'] = nexus_trans('torrent.pick_info.' . $this->picktype); + return $info; + } + } + public function getPromotionInfoAttribute() + { + return self::$promotionTypes[$this->sp_state_real] ?? null; + } public function getSpStateRealTextAttribute() { diff --git a/app/Repositories/AgentAllowRepository.php b/app/Repositories/AgentAllowRepository.php index 839db108..66a8d2ce 100644 --- a/app/Repositories/AgentAllowRepository.php +++ b/app/Repositories/AgentAllowRepository.php @@ -4,6 +4,7 @@ namespace App\Repositories; use App\Exceptions\ClientNotAllowedException; use App\Models\AgentAllow; use App\Models\AgentDeny; +use Nexus\Database\NexusDB; class AgentAllowRepository extends BaseRepository { @@ -72,10 +73,12 @@ class AgentAllowRepository extends BaseRepository public function checkClient($peerId, $agent, $debug = false) { //check from high version to low version, if high version allow, stop! - $allows = AgentAllow::query() - ->orderBy('peer_id_start', 'desc') - ->orderBy('agent_start', 'desc') - ->get(); + $allows = NexusDB::remember("all_agent_allows", 600, function () { + return AgentAllow::query() + ->orderBy('peer_id_start', 'desc') + ->orderBy('agent_start', 'desc') + ->get(); + }); $agentAllowPassed = null; $versionTooLowStr = ''; foreach ($allows as $agentAllow) { diff --git a/app/Repositories/AttendanceRepository.php b/app/Repositories/AttendanceRepository.php index b1ef38c1..06d193a7 100644 --- a/app/Repositories/AttendanceRepository.php +++ b/app/Repositories/AttendanceRepository.php @@ -75,8 +75,8 @@ class AttendanceRepository extends BaseRepository ->where('uid', $uid) ->orderBy('id', 'desc'); if (!empty($date)) { - $query->where('added', '>=', Carbon::today()) - ->where('added', '<', Carbon::tomorrow()); + $query->where('added', '>=', Carbon::parse($date)->startOfDay()) + ->where('added', '<=', Carbon::parse($date)->endOfDay()); } return $query->first(); } diff --git a/app/Repositories/CommentRepository.php b/app/Repositories/CommentRepository.php index c2527c0a..1200402e 100644 --- a/app/Repositories/CommentRepository.php +++ b/app/Repositories/CommentRepository.php @@ -41,8 +41,9 @@ class CommentRepository extends BaseRepository $model = new $modelName; $target = $model->newQuery()->with('user')->find($params[$type]); return DB::transaction(function () use ($params, $user, $target) { + $params['added'] = Carbon::now(); $comment = $user->comments()->create($params); - $commentCount = Comment::query()->type($params['type'])->count(); + $commentCount = Comment::query()->type($params['type'], $params[$params['type']])->count(); $target->comments = $commentCount; $target->save(); @@ -60,7 +61,7 @@ class CommentRepository extends BaseRepository 'receiver' => $target->user->id, 'subject' => $messageInfo['subject'], 'msg' => $messageInfo['body'], - 'added' => Carbon::now() + 'added' => $params['added'], ]; Message::query()->insert($insert); NexusDB::cache_del('user_'.$target->user->id.'_unread_message_count'); @@ -100,9 +101,8 @@ class CommentRepository extends BaseRepository $targetScript = Comment::TYPE_MAPS[$type]['target_script']; $targetNameField = Comment::TYPE_MAPS[$type]['target_name_field']; $body = sprintf( - '%s [url="%s/%s"]%s[/url]', - $trans[$type]['msg_torrent_receive_comment'], - getSchemeAndHttpHost(), + '%s [url=%s]%s[/url]', + $trans['msg_torrent_receive_comment'], sprintf($targetScript, $target->id), $target->{$targetNameField} ); diff --git a/app/Repositories/RewardRepository.php b/app/Repositories/RewardRepository.php index 8f88c9fe..ce2eaa79 100644 --- a/app/Repositories/RewardRepository.php +++ b/app/Repositories/RewardRepository.php @@ -30,10 +30,11 @@ class RewardRepository extends BaseRepository } $torrent = Torrent::query()->findOrFail($torrentId, Torrent::$commentFields); $torrent->checkIsNormal(); - $torrentOwner = User::query()->findOrFail($torrent->owner, ['id', 'seedbonus']); + $torrentOwner = User::query()->findOrFail($torrent->owner); if ($user->id == $torrentOwner->id) { throw new \LogicException("you can't reward to yourself."); } + $torrentOwner->checkIsNormal(); return DB::transaction(function () use ($torrentId, $value, $user, $torrentOwner) { $model = $user->reward_torrent_logs()->create([ 'torrentid' => $torrentId, diff --git a/app/Repositories/ToolRepository.php b/app/Repositories/ToolRepository.php index a09885e1..7100e5e4 100644 --- a/app/Repositories/ToolRepository.php +++ b/app/Repositories/ToolRepository.php @@ -1,7 +1,12 @@ getAttendance($user->id, date('Ymd')); + $result['attendance'] = $attendance ? 0 : 1; + + //unread news + $count = News::query()->where('added', '>', $user->last_home)->count(); + $result['news'] = $count; + + //unread messages + $count = Message::query()->where('receiver', $user->id)->where('unread', 'yes')->count(); + $result['message'] = $count; + + //un-vote poll + $total = Poll::query()->count(); + $userVoteCount = PollAnswer::query()->where('userid', $user->id)->selectRaw('count(distinct(pollid)) as counts')->first()->counts; + $result['poll'] = $total - $userVoteCount; + + return $result; + } } diff --git a/app/Repositories/TorrentRepository.php b/app/Repositories/TorrentRepository.php index 30fc5811..9c336486 100644 --- a/app/Repositories/TorrentRepository.php +++ b/app/Repositories/TorrentRepository.php @@ -24,6 +24,7 @@ use Carbon\Carbon; use Hashids\Hashids; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Str; +use Nexus\Database\NexusDB; class TorrentRepository extends BaseRepository { @@ -372,12 +373,14 @@ class TorrentRepository extends BaseRepository private function getTrackerReportAuthKeySecret($id, $uid, $initializeIfNotExists = false) { - $secret = TorrentSecret::query() - ->where('uid', $uid) - ->whereIn('torrent_id', [0, $id]) - ->orderBy('torrent_id', 'desc') - ->orderBy('id', 'desc') - ->first(); + $secret = NexusDB::remember("tracker_report_authkey_secret:$id:$uid", 3600*24, function () use ($id, $uid) { + return TorrentSecret::query() + ->where('uid', $uid) + ->whereIn('torrent_id', [0, $id]) + ->orderBy('torrent_id', 'desc') + ->orderBy('id', 'desc') + ->first(); + }); if ($secret) { return $secret->secret; } diff --git a/app/Repositories/TrackerRepository.php b/app/Repositories/TrackerRepository.php index aea868f1..df79cba4 100644 --- a/app/Repositories/TrackerRepository.php +++ b/app/Repositories/TrackerRepository.php @@ -104,7 +104,7 @@ class TrackerRepository extends BaseRepository $repDict = $this->generateFailedAnnounceResponse($exception->getMessage()); } catch (TrackerException $exception) { $repDict = $this->generateFailedAnnounceResponse($exception->getMessage()); - } catch (\Exception $exception) { + } catch (\Throwable $exception) { //other system exception do_log("[" . get_class($exception) . "] " . $exception->getMessage() . "\n" . $exception->getTraceAsString(), 'error'); $repDict = $this->generateFailedAnnounceResponse("system error, report to sysop please, hint: " . nexus()->getRequestId()); @@ -806,7 +806,7 @@ class TrackerRepository extends BaseRepository $repDict = $this->generateFailedAnnounceResponse($exception->getMessage()); } catch (TrackerException $exception) { $repDict = $this->generateFailedAnnounceResponse($exception->getMessage()); - } catch (\Exception $exception) { + } catch (\Throwable $exception) { //other system exception do_log("[" . get_class($exception) . "] " . $exception->getMessage() . "\n" . $exception->getTraceAsString(), 'error'); $repDict = $this->generateFailedAnnounceResponse("system error, report to sysop please, hint: " . nexus()->getRequestId()); diff --git a/public/announce.php b/public/announce.php index dab58034..ba370203 100644 --- a/public/announce.php +++ b/public/announce.php @@ -35,7 +35,9 @@ if (!empty($_REQUEST['authkey'])) { if (empty($decrypted)) { err('Invalid authkey'); } - $userInfo = \App\Models\User::query()->where('id', $uid)->first(['id', 'passkey']); + $userInfo = \Nexus\Database\NexusDB::remember("announce_user_passkey_$uid", 600, function () use ($uid) { + return \App\Models\User::query()->where('id', $uid)->first(['id', 'passkey']); + }); if (!$userInfo) { err('Invalid authkey'); } diff --git a/resources/lang/en/bonus.php b/resources/lang/en/bonus.php new file mode 100644 index 00000000..2d2bb3c6 --- /dev/null +++ b/resources/lang/en/bonus.php @@ -0,0 +1,5 @@ + 'Spend :bonus bonus buy :medal_name', +]; diff --git a/resources/lang/en/message.php b/resources/lang/en/message.php new file mode 100644 index 00000000..a7da7fa6 --- /dev/null +++ b/resources/lang/en/message.php @@ -0,0 +1,11 @@ + [ + 'page_title' => 'Message list', + ], + 'show' => [ + 'page_title' => 'Message detail', + ] +]; diff --git a/resources/lang/en/reward.php b/resources/lang/en/reward.php new file mode 100644 index 00000000..26f3d7ee --- /dev/null +++ b/resources/lang/en/reward.php @@ -0,0 +1,9 @@ + [ + 'page_title' => 'Rewards', + ] + +]; diff --git a/resources/lang/en/torrent.php b/resources/lang/en/torrent.php index 9017df8d..9d4947d1 100644 --- a/resources/lang/en/torrent.php +++ b/resources/lang/en/torrent.php @@ -25,5 +25,17 @@ return [ 'numfiles_label' => 'Files', 'bookmark_yes_label' => 'Bookmarked', 'bookmark_no_label' => 'Add to bookmark', - ] + 'reward_logs_label' => 'Reward', + 'reward_yes_label' => 'Rewarded', + 'reward_no_label' => 'Reward', + 'download_label' => 'Download', + 'thanks_yes_label' => 'Thanked', + 'thanks_no_label' => 'Thank', + ], + 'pick_info' => [ + 'normal' => 'Normal', + 'hot' => 'Hot', + 'classic' => 'Classic', + 'recommended' => 'Recommend', + ], ]; diff --git a/resources/lang/zh_CN/reward.php b/resources/lang/zh_CN/reward.php index 4b0d9667..2bb80b8c 100644 --- a/resources/lang/zh_CN/reward.php +++ b/resources/lang/zh_CN/reward.php @@ -5,7 +5,5 @@ return [ 'index' => [ 'page_title' => '赠魔者列表', ], - 'show' => [ - 'page_title' => '私信详情', - ] + ]; diff --git a/resources/lang/zh_CN/torrent.php b/resources/lang/zh_CN/torrent.php index 796efd1c..52a67c2c 100644 --- a/resources/lang/zh_CN/torrent.php +++ b/resources/lang/zh_CN/torrent.php @@ -31,5 +31,11 @@ return [ 'download_label' => '下载', 'thanks_yes_label' => '已谢谢', 'thanks_no_label' => '谢谢', - ] + ], + 'pick_info' => [ + 'normal' => '普通', + 'hot' => '热门', + 'classic' => '经典', + 'recommended' => '推荐', + ], ]; diff --git a/resources/lang/zh_TW/bonus.php b/resources/lang/zh_TW/bonus.php new file mode 100644 index 00000000..a0fa40b6 --- /dev/null +++ b/resources/lang/zh_TW/bonus.php @@ -0,0 +1,5 @@ + '花費 :bonus 魔力購買了 :medal_name', +]; diff --git a/resources/lang/zh_TW/message.php b/resources/lang/zh_TW/message.php new file mode 100644 index 00000000..aaba637b --- /dev/null +++ b/resources/lang/zh_TW/message.php @@ -0,0 +1,11 @@ + [ + 'page_title' => '私信列表', + ], + 'show' => [ + 'page_title' => '私信詳情', + ] +]; diff --git a/resources/lang/zh_TW/reward.php b/resources/lang/zh_TW/reward.php new file mode 100644 index 00000000..8501cbff --- /dev/null +++ b/resources/lang/zh_TW/reward.php @@ -0,0 +1,9 @@ + [ + 'page_title' => '贈魔者列表', + ], + +]; diff --git a/resources/lang/zh_TW/torrent.php b/resources/lang/zh_TW/torrent.php index eefcf7bc..2aba515b 100644 --- a/resources/lang/zh_TW/torrent.php +++ b/resources/lang/zh_TW/torrent.php @@ -24,6 +24,18 @@ return [ 'thank_users_count_label' => '謝謝', 'numfiles_label' => '文件', 'bookmark_yes_label' => '已收藏', - 'bookmark_no_label' => '加入收藏', - ] + 'bookmark_no_label' => '收藏', + 'reward_logs_label' => '贈魔', + 'reward_yes_label' => '已贈魔', + 'reward_no_label' => '贈魔', + 'download_label' => '下載', + 'thanks_yes_label' => '已謝謝', + 'thanks_no_label' => '謝謝', + ], + 'pick_info' => [ + 'normal' => '普通', + 'hot' => '熱門', + 'classic' => '經典', + 'recommended' => '推薦', + ], ]; diff --git a/routes/api.php b/routes/api.php index c87e44e6..a6f1a517 100644 --- a/routes/api.php +++ b/routes/api.php @@ -43,6 +43,7 @@ Route::group(['middleware' => ['auth:sanctum', 'locale']], function () { Route::get('polls-latest', [\App\Http\Controllers\PollController::class, 'latest']); Route::post('polls-vote', [\App\Http\Controllers\PollController::class, 'vote']); Route::resource('rewards', \App\Http\Controllers\RewardController::class); + Route::get('notifications', [\App\Http\Controllers\ToolController::class, 'notifications']); }); Route::group(['middleware' => ['admin']], function () {