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 @@
+
+
+
+
+
+
每日金句生成器
+
Powered By Cloudflare Workers AI
+
+
每日金句:
+
{{ motto }}
+
+
+
\ 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