From b8ae97e49b9038dd71d508b2cef0ac58f0903725 Mon Sep 17 00:00:00 2001 From: Tony Yang Date: Tue, 15 Apr 2025 12:01:53 +0800 Subject: [PATCH] feat: daily motto --- functions/api/motto.js | 25 +++++++++++++++++++++++++ src/lib/api.js | 25 +++++++++++++++++++++++++ src/router/index.js | 11 +++++++++++ src/views/DailyMottoView.vue | 36 ++++++++++++++++++++++++++++++++++++ wrangler.toml | 5 ++++- 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 functions/api/motto.js create mode 100644 src/views/DailyMottoView.vue diff --git a/functions/api/motto.js b/functions/api/motto.js new file mode 100644 index 0000000..e4a4bd9 --- /dev/null +++ b/functions/api/motto.js @@ -0,0 +1,25 @@ +import { verifyJWT } from '../middleware/auth'; +import { createErrorResponse, createSuccessResponse } from '../utils'; + +export async function onRequestGet(context) { + try { + // Verify the JWT token + const authResult = await verifyJWT(context); + if (authResult) { + return authResult; // Return the error response from the middleware + } + + // Use Cloudflare AI Gateway to proxy the request to Google AI Studio + const ai = context.env.AI; + + const input = { prompt: '用繁體中文生成一句名言佳句' }; + + const response = await ai.run('@cf/meta/llama-3.2-1b-instruct', input); + const motto = response.response; + + return createSuccessResponse({ motto }); + } catch (error) { + console.error("Gen motto error:", error); + return createErrorResponse("Get motto failed", 500); + } +} diff --git a/src/lib/api.js b/src/lib/api.js index 02b11aa..522e715 100644 --- a/src/lib/api.js +++ b/src/lib/api.js @@ -173,3 +173,28 @@ export async function uploadAvatar(avatar, jwt) { const data = await response.json(); return data; } + +export async function generateMotto(jwt) { + try { + const response = await fetch('/api/motto', { + headers: { + 'Authorization': `Bearer ${jwt}`, + }, + }); + + if (!response.ok) { + if (response.status === 401) { + unauthRedirectToLogin(); + return; + } + const error = await response.json(); + throw new Error(error.error || 'Generating motto failed'); + } + + const data = await response.json(); + return data.motto; + } catch { + console.error('Error generating motto:', error); + throw new Error('Failed to generate motto'); + } +} diff --git a/src/router/index.js b/src/router/index.js index a7162d9..9b1f30a 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -6,6 +6,7 @@ import AboutView from '../views/AboutView.vue'; import LoginView from '../views/LoginView.vue'; import ProfileView from '../views/ProfileView.vue'; import RegisterView from '../views/RegisterView.vue'; +import DailyMottoView from '../views/DailyMottoView.vue'; const routes = [ { @@ -62,6 +63,16 @@ const routes = [ showInNav: false, navName: '個人資料' } + }, + { + path: '/daily-motto', + name: 'DailyMotto', + component: DailyMottoView, + meta: { + keepAlive: true, + showInNav: true, + navName: '每日名言佳句' + } } ]; diff --git a/src/views/DailyMottoView.vue b/src/views/DailyMottoView.vue new file mode 100644 index 0000000..ece3768 --- /dev/null +++ b/src/views/DailyMottoView.vue @@ -0,0 +1,36 @@ + + + \ No newline at end of file diff --git a/wrangler.toml b/wrangler.toml index f48244f..3433204 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -14,4 +14,7 @@ database_id = "a2088769-aab4-44be-b24e-25c8762f0e80" [[r2_buckets]] binding = "MY_BUCKET" -bucket_name = "ntu-padn-mid-web" \ No newline at end of file +bucket_name = "ntu-padn-mid-web" + +[ai] +binding = "AI" \ No newline at end of file