From 8d8e3b7768cb88f7688e234c202131aacfbf0095 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 5 Jan 2023 18:29:31 +0800 Subject: [PATCH] bonus can buy: tmp invite + rainbow ID + change username card --- app/Models/BonusLogs.php | 27 +++++++++ app/Models/Invite.php | 2 + app/Repositories/BonusRepository.php | 82 +++++++++++++++++++++++++++ app/Repositories/UserRepository.php | 24 +++++--- include/constants.php | 2 +- lang/chs/lang_mybonus.php | 10 ++++ lang/chs/lang_settings.php | 8 +++ lang/cht/lang_mybonus.php | 10 ++++ lang/cht/lang_settings.php | 8 +++ lang/en/lang_mybonus.php | 10 ++++ lang/en/lang_settings.php | 8 +++ nexus/Install/settings.default.php | 4 ++ public/invite.php | 10 +++- public/mybonus.php | 83 +++++++++++++++++++++------- public/settings.php | 8 ++- public/takesignup.php | 7 +++ resources/lang/en/bonus.php | 3 + resources/lang/zh_CN/bonus.php | 3 + resources/lang/zh_TW/bonus.php | 3 + 19 files changed, 279 insertions(+), 33 deletions(-) diff --git a/app/Models/BonusLogs.php b/app/Models/BonusLogs.php index aae920a6..588b09f1 100644 --- a/app/Models/BonusLogs.php +++ b/app/Models/BonusLogs.php @@ -11,6 +11,9 @@ class BonusLogs extends NexusModel const DEFAULT_BONUS_CANCEL_ONE_HIT_AND_RUN = 10000; const DEFAULT_BONUS_BUY_ATTENDANCE_CARD = 1000; + const DEFAULT_BONUS_BUY_TEMPORARY_INVITE = 500; + const DEFAULT_BONUS_BUY_RAINBOW_ID = 5000; + const DEFAULT_BONUS_BUY_CHANGE_USERNAME_CARD = 100000; const BUSINESS_TYPE_CANCEL_HIT_AND_RUN = 1; const BUSINESS_TYPE_BUY_MEDAL = 2; @@ -26,6 +29,9 @@ class BonusLogs extends NexusModel const BUSINESS_TYPE_GIFT_TO_LOW_SHARE_RATIO = 12; const BUSINESS_TYPE_LUCKY_DRAW = 13; const BUSINESS_TYPE_EXCHANGE_DOWNLOAD = 14; + const BUSINESS_TYPE_BUY_TEMPORARY_INVITE = 15; + const BUSINESS_TYPE_BUY_RAINBOW_ID = 16; + const BUSINESS_TYPE_BUY_CHANGE_USERNAME_CARD = 17; public static array $businessTypes = [ self::BUSINESS_TYPE_CANCEL_HIT_AND_RUN => ['text' => 'Cancel H&R'], @@ -42,6 +48,9 @@ class BonusLogs extends NexusModel self::BUSINESS_TYPE_GIFT_TO_LOW_SHARE_RATIO => ['text' => 'Gift to low share ratio'], self::BUSINESS_TYPE_LUCKY_DRAW => ['text' => 'Lucky draw'], self::BUSINESS_TYPE_EXCHANGE_DOWNLOAD => ['text' => 'Exchange download'], + self::BUSINESS_TYPE_BUY_TEMPORARY_INVITE => ['text' => 'Buy temporary invite'], + self::BUSINESS_TYPE_BUY_RAINBOW_ID => ['text' => 'Buy rainbow ID'], + self::BUSINESS_TYPE_BUY_CHANGE_USERNAME_CARD => ['text' => 'Buy change username card'], ]; public static function getBonusForCancelHitAndRun() @@ -56,5 +65,23 @@ class BonusLogs extends NexusModel return $result ?? self::DEFAULT_BONUS_BUY_ATTENDANCE_CARD; } + public static function getBonusForBuyTemporaryInvite() + { + $result = Setting::get('bonus.one_tmp_invite'); + return $result ?? self::DEFAULT_BONUS_BUY_TEMPORARY_INVITE; + } + + public static function getBonusForBuyRainbowId() + { + $result = Setting::get('bonus.rainbow_id'); + return $result ?? self::DEFAULT_BONUS_BUY_RAINBOW_ID; + } + + public static function getBonusForBuyChangeUsernameCard() + { + $result = Setting::get('bonus.change_username_card'); + return $result ?? self::DEFAULT_BONUS_BUY_CHANGE_USERNAME_CARD; + } + } diff --git a/app/Models/Invite.php b/app/Models/Invite.php index 371aab30..0462858a 100644 --- a/app/Models/Invite.php +++ b/app/Models/Invite.php @@ -9,6 +9,8 @@ class Invite extends NexusModel const VALID_YES = 1; const VALID_NO = 0; + const TEMPORARY_INVITE_VALID_DAYS = 7; + protected $casts = [ 'expired_at' => 'datetime', ]; diff --git a/app/Repositories/BonusRepository.php b/app/Repositories/BonusRepository.php index a00ca11c..9d13a714 100644 --- a/app/Repositories/BonusRepository.php +++ b/app/Repositories/BonusRepository.php @@ -1,12 +1,15 @@ findOrFail($uid); + $requireBonus = BonusLogs::getBonusForBuyTemporaryInvite(); + $toolRep = new ToolRepository(); + $hashArr = $toolRep->generateUniqueInviteHash([], $count, $count); + NexusDB::transaction(function () use ($user, $requireBonus, $hashArr) { + $comment = nexus_trans('bonus.comment_buy_temporary_invite', [ + 'bonus' => $requireBonus, + 'count' => count($hashArr) + ], $user->locale); + do_log("comment: $comment"); + $this->consumeUserBonus($user, $requireBonus, BonusLogs::BUSINESS_TYPE_BUY_TEMPORARY_INVITE, $comment); + $invites = []; + foreach ($hashArr as $hash) { + $invites[] = [ + 'inviter' => $user->id, + 'invitee' => '', + 'hash' => $hash, + 'valid' => 0, + 'expired_at' => Carbon::now()->addDays(Invite::TEMPORARY_INVITE_VALID_DAYS), + 'created_at' => Carbon::now(), + ]; + } + Invite::query()->insert($invites); + }); + + return true; + + } + + public function consumeToBuyRainbowId($uid, $duration = 30): bool + { + $user = User::query()->findOrFail($uid); + $requireBonus = BonusLogs::getBonusForBuyRainbowId(); + NexusDB::transaction(function () use ($user, $requireBonus, $duration) { + $comment = nexus_trans('bonus.comment_buy_rainbow_id', [ + 'bonus' => $requireBonus, + 'duration' => $duration, + ], $user->locale); + do_log("comment: $comment"); + $this->consumeUserBonus($user, $requireBonus, BonusLogs::BUSINESS_TYPE_BUY_RAINBOW_ID, $comment); + $metaData = [ + 'meta_key' => UserMeta::META_KEY_PERSONALIZED_USERNAME, + 'duration' => $duration, + ]; + $userRep = new UserRepository(); + $userRep->addMeta($user, $metaData, $metaData, false); + }); + + return true; + + } + + public function consumeToBuyChangeUsernameCard($uid): bool + { + $user = User::query()->findOrFail($uid); + $requireBonus = BonusLogs::getBonusForBuyChangeUsernameCard(); + if (UserMeta::query()->where('uid', $uid)->where('meta_key', UserMeta::META_KEY_CHANGE_USERNAME)->exists()) { + throw new NexusException("user already has change username card"); + } + NexusDB::transaction(function () use ($user, $requireBonus) { + $comment = nexus_trans('bonus.comment_buy_change_username_card', [ + 'bonus' => $requireBonus, + ], $user->locale); + do_log("comment: $comment"); + $this->consumeUserBonus($user, $requireBonus, BonusLogs::BUSINESS_TYPE_BUY_CHANGE_USERNAME_CARD, $comment); + $metaData = [ + 'meta_key' => UserMeta::META_KEY_CHANGE_USERNAME, + ]; + $userRep = new UserRepository(); + $userRep->addMeta($user, $metaData, $metaData, false); + }); + + return true; + + } + public function consumeUserBonus($user, $requireBonus, $logBusinessType, $logComment = '', array $userUpdates = []) { if (!isset(BonusLogs::$businessTypes[$logBusinessType])) { diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index 03a1cf24..486e99f4 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -466,7 +466,7 @@ class UserRepository extends BaseRepository return true; } - public function addMeta($user, array $metaData, array $keyExistsUpdates = []) + public function addMeta($user, array $metaData, array $keyExistsUpdates = [], $notify = true) { $user = $this->getUser($user); $locale = $user->locale; @@ -484,7 +484,9 @@ class UserRepository extends BaseRepository } else { $durationText = nexus_trans('label.permanent', [], $locale); } - $message['msg'] = nexus_trans('user.grant_props_notification.body', ['name' => $metaName, 'operator' => Auth::user()->username, 'duration' => $durationText], $locale); + $operatorId = get_user_id(); + $operatorInfo = get_user_row($operatorId); + $message['msg'] = nexus_trans('user.grant_props_notification.body', ['name' => $metaName, 'operator' => $operatorInfo['username'], 'duration' => $durationText], $locale); if (!empty($metaData['duration'])) { $metaData['deadline'] = now()->addDays($metaData['duration']); } @@ -520,7 +522,9 @@ class UserRepository extends BaseRepository } if ($result) { clear_user_cache($user->id, $user->passkey); - Message::query()->insert($message); + if ($notify) { + Message::add($message); + } } do_log($log); return $result; @@ -570,7 +574,7 @@ class UserRepository extends BaseRepository return true; } - public function addTemporaryInvite(User $operator, int $uid, string $action, int $count, int|null $days, string|null $reason = '') + public function addTemporaryInvite(User|null $operator, int $uid, string $action, int $count, int|null $days, string|null $reason = '') { do_log("uid: $uid, action: $action, count: $count, days: $days, reason: $reason"); $action = strtolower($action); @@ -578,7 +582,9 @@ class UserRepository extends BaseRepository throw new \InvalidArgumentException("days or count lte 0"); } $targetUser = User::query()->findOrFail($uid, User::$commonFields); - $this->checkPermission($operator, $targetUser); + if ($operator) { + $this->checkPermission($operator, $targetUser); + } $toolRep = new ToolRepository(); $locale = $targetUser->locale; @@ -587,7 +593,7 @@ class UserRepository extends BaseRepository $body = nexus_trans('message.temporary_invite_change.body', [ 'change_type' => $changeType, 'count' => $count, - 'operator' => $operator->username, + 'operator' => $operator->username ?? '', 'reason' => $reason, ], $locale); $message = [ @@ -611,7 +617,7 @@ class UserRepository extends BaseRepository ]; } } - NexusDB::transaction(function () use ($uid, $message, $inviteData, $count) { + NexusDB::transaction(function () use ($uid, $message, $inviteData, $count, $operator) { if (!empty($inviteData)) { Invite::query()->insert($inviteData); do_log("[INSERT TEMPORARY INVITE] to $uid, count: $count"); @@ -624,7 +630,9 @@ class UserRepository extends BaseRepository ; do_log("[DELETE TEMPORARY INVITE] of $uid, count: $count"); } - Message::add($message); + if ($operator) { + Message::add($message); + } }); return true; } diff --git a/include/constants.php b/include/constants.php index 3bdf583d..0ac71742 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ '数量', 'col_size' => '体积', 'col_a' => 'A 值', + 'text_buy_tmp_invite' => '1个临时邀请名额', + 'text_buy_tmp_invite_note' => '如果有足够的魔力值,你可以用它来换取临时邀请名额,有效期 7 天。交易完成后,你的魔力值会减少,邀请临时名额数则会增加。', + 'text_success_tmp_invites' => "祝贺你,你获得了1个新的临时邀请名额!", + 'text_buy_rainbow_id' => "购买彩虹 ID", + 'text_buy_rainbow_id_note' => '为用户名增加如彩虹般闪烁的效果,有效期 30 天,重复购买时间累加。', + 'text_success_buy_rainbow_id' => "祝贺你,彩虹 ID 增加了30天!", + 'text_buy_change_username_card' => "购买改名卡", + 'text_buy_change_username_card_note' => '修改用户名一次,永久有效。', + 'text_success_buy_change_username_card' => "祝贺你,成功购买了改名卡!", + 'text_change_username_card_already_has' => '已经拥有改名卡', ); ?> diff --git a/lang/chs/lang_settings.php b/lang/chs/lang_settings.php index e9b0d498..89091f27 100644 --- a/lang/chs/lang_settings.php +++ b/lang/chs/lang_settings.php @@ -799,6 +799,14 @@ $lang_settings = array 'row_protected_forum' => '隐私保护论坛板块', 'text_protected_forum' => '输入开启隐私保护的论坛板块ID,该版块的回复仅楼主作者及管理员以上可见,使用逗号分割(如:1,2,3)', 'forum_format_error' => '论坛ID格式错误,请检查输入!', + 'row_buy_an_tmp_invite' => '购买临时邀请名额', + 'text_buy_an_tmp_invite_note' => "个魔力值,如果他选择交换一个临时邀请名额。默认'500'。", + 'row_buy_rainbow_id' => '购买彩虹 ID', + 'text_buy_rainbow_id_note' => "个魔力值,如果他选择交换一个彩虹 ID,有效期 30 天。默认'5,000'。", + 'row_buy_change_username_card' => '购买改名卡', + 'text_buy_change_username_card_note' => "个魔力值,如果他选择交换一个改名卡,永久有效。默认'100,000'。", + 'row_initial_tmp_invites' => '初始临时邀请名额', + 'text_initial_tmp_invites_note' => "新注册用户的初始临时邀请名额,有效期 7 天。默认'0'。", ); ?> diff --git a/lang/cht/lang_mybonus.php b/lang/cht/lang_mybonus.php index 70c265bf..31c21b23 100644 --- a/lang/cht/lang_mybonus.php +++ b/lang/cht/lang_mybonus.php @@ -156,6 +156,16 @@ $lang_mybonus = array 'col_count' => '數量', 'col_size' => '體積', 'col_a' => 'A 值', + 'text_buy_tmp_invite' => '1個臨時邀請名額', + 'text_buy_tmp_invite_note' => '如果有足夠的魔力值,你可以用它來換取臨時邀請名額,有效期 7 天。交易完成後,你的魔力值會減少,邀請臨時名額數則會增加。', + 'text_success_tmp_invites' => "祝賀你,你獲得了1個新的臨時邀請名額!", + 'text_buy_rainbow_id' => "購買彩虹 ID", + 'text_buy_rainbow_id_note' => '為用戶名增加如彩虹般閃爍的效果,有效期 30 天,重復購買時間累加。', + 'text_success_buy_rainbow_id' => "祝賀你,彩虹 ID 增加了30天!", + 'text_buy_change_username_card' => "購買改名卡", + 'text_buy_change_username_card_note' => '修改用戶名一次,永久有效。', + 'text_success_buy_change_username_card' => "祝賀你,成功購買了改名卡!", + 'text_change_username_card_already_has' => '已經擁有改名卡', ); ?> diff --git a/lang/cht/lang_settings.php b/lang/cht/lang_settings.php index 5b7f8282..cb62a8e9 100644 --- a/lang/cht/lang_settings.php +++ b/lang/cht/lang_settings.php @@ -799,6 +799,14 @@ $lang_settings = array 'row_protected_forum' => '隱私保護論壇板塊', 'text_protected_forum' => '輸入開啟隱私保護的論壇板塊ID,該版塊的回覆僅樓主作者及管理員以上可見,使用逗號分割(如:1,2,3)', 'forum_format_error' => '論壇ID格式錯誤,請核查校對!', + 'row_buy_an_tmp_invite' => '購買臨時邀請名額', + 'text_buy_an_tmp_invite_note' => "個魔力值,如果他選擇交換一個臨時邀請名額。默認'500'。", + 'row_buy_rainbow_id' => '購買彩虹 ID', + 'text_buy_rainbow_id_note' => "個魔力值,如果他選擇交換一個彩虹 ID,有效期 30 天。默認'5,000'。", + 'row_buy_change_username_card' => '購買改名卡', + 'text_buy_change_username_card_note' => "個魔力值,如果他選擇交換一個改名卡,永久有效。默認'100,000'。", + 'row_initial_tmp_invites' => '初始臨時邀請名額', + 'text_initial_tmp_invites_note' => "新註冊用戶的初始臨時邀請名額,有效期 7 天。默認'0'。", ); ?> diff --git a/lang/en/lang_mybonus.php b/lang/en/lang_mybonus.php index 70179d9f..afc040f1 100644 --- a/lang/en/lang_mybonus.php +++ b/lang/en/lang_mybonus.php @@ -156,6 +156,16 @@ where