diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php new file mode 100644 index 0000000..681b388 --- /dev/null +++ b/app/Http/Controllers/ProfileController.php @@ -0,0 +1,63 @@ + $request->user() instanceof MustVerifyEmail, + 'status' => session('status'), + ]); + } + + /** + * Update the user's profile information. + */ + public function update(ProfileUpdateRequest $request): RedirectResponse + { + $request->user()->fill($request->validated()); + + if ($request->user()->isDirty('email')) { + $request->user()->email_verified_at = null; + } + + $request->user()->save(); + + return Redirect::route('profile.edit'); + } + + /** + * Delete the user's account. + */ + public function destroy(Request $request): RedirectResponse + { + $request->validate([ + 'password' => ['required', 'current-password'], + ]); + + $user = $request->user(); + + Auth::logout(); + + $user->delete(); + + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return Redirect::to('/'); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 23b4063..777bed0 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -41,4 +41,9 @@ class User extends Authenticatable protected $casts = [ 'email_verified_at' => 'datetime', ]; + + public function getSubscribedAttribute(): bool + { + return $this->subscription_type > 0 && $this->subscription_ends_at > now(); + } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 3eea113..0d71900 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -47,12 +47,12 @@ protected function configureRateLimiting(): void RateLimiter::for('chat', function (Request $request) { return $request->input('api_key') ? Limit::none() - : Limit::perMinute(30)->by($request->user()?->id ?: $request->ip()); + : Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); }); RateLimiter::for('audio', function (Request $request) { return $request->input('api_key') ? Limit::none() - : Limit::perMinute(15)->by($request->user()?->id ?: $request->ip()); + : Limit::perMinute(30)->by($request->user()?->id ?: $request->ip()); }); RateLimiter::for('image', function (Request $request) { return $request->input('api_key') diff --git a/config/openai.php b/config/openai.php index 463261e..1638b87 100644 --- a/config/openai.php +++ b/config/openai.php @@ -13,7 +13,7 @@ */ 'api_key' => env('OPENAI_API_KEY'), - 'base_uri' => env('OPENAI_BASE_URI', 'api.openai.com'), + 'base_uri' => env('OPENAI_BASE_URI', 'https://api.openai.com'), 'organization' => env('OPENAI_ORGANIZATION'), 'http_proxy' => env('HTTP_PROXY'), ]; diff --git a/database/migrations/2023_03_24_080248_users_add_subscription_columns.php b/database/migrations/2023_03_24_080248_users_add_subscription_columns.php new file mode 100644 index 0000000..d1885ee --- /dev/null +++ b/database/migrations/2023_03_24_080248_users_add_subscription_columns.php @@ -0,0 +1,32 @@ +tinyInteger('subscription_type')->default(0)->after('email_verified_at'); + // 订阅结束时间 + $table->timestamp('subscription_ends_at')->nullable()->after('subscription_type'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('subscription_type'); + $table->dropColumn('subscription_ends_at'); + }); + } +}; diff --git a/resources/js/Components/ApplicationLogo.vue b/resources/js/Components/ApplicationLogo.vue index d952df7..d05e4b6 100644 --- a/resources/js/Components/ApplicationLogo.vue +++ b/resources/js/Components/ApplicationLogo.vue @@ -1,7 +1,3 @@ diff --git a/resources/js/Components/PrimaryButton.vue b/resources/js/Components/PrimaryButton.vue index 6260768..a452512 100644 --- a/resources/js/Components/PrimaryButton.vue +++ b/resources/js/Components/PrimaryButton.vue @@ -8,10 +8,8 @@ defineProps({ diff --git a/resources/js/Layouts/AuthenticatedLayout.vue b/resources/js/Layouts/AuthenticatedLayout.vue index e839e40..a84d01d 100644 --- a/resources/js/Layouts/AuthenticatedLayout.vue +++ b/resources/js/Layouts/AuthenticatedLayout.vue @@ -20,17 +20,15 @@ const showingNavigationDropdown = ref(false);
- - + +
@@ -41,32 +39,24 @@ const showingNavigationDropdown = ref(false); @@ -75,31 +65,19 @@ const showingNavigationDropdown = ref(false);
-
@@ -107,13 +85,10 @@ const showingNavigationDropdown = ref(false); -
+
- Dashboard + 用户后台
@@ -127,9 +102,9 @@ const showingNavigationDropdown = ref(false);
- Profile + 用户信息 - Log Out + 退出
diff --git a/resources/js/Pages/Auth/ConfirmPassword.vue b/resources/js/Pages/Auth/ConfirmPassword.vue index 6be73ab..84cca4f 100644 --- a/resources/js/Pages/Auth/ConfirmPassword.vue +++ b/resources/js/Pages/Auth/ConfirmPassword.vue @@ -19,30 +19,24 @@ const submit = () => {