...
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-11-17 15:59:35 +08:00
parent 22a0cf46fb
commit 0bf3b718b2
35 changed files with 204 additions and 841 deletions

View File

@@ -1,11 +0,0 @@
"use client";
import { SessionProvider } from "next-auth/react";
export default function SessionWrapper({
children,
}: {
children: React.ReactNode;
}) {
return <SessionProvider>{children}</SessionProvider>;
}

View File

@@ -1,3 +1,5 @@
"use server";
import { format } from "util";
async function callZhipuAPI(

View File

@@ -3,8 +3,8 @@
import {
folderCreateInput,
folderUpdateInput,
} from "../../../generated/prisma/models";
import prisma from "../db";
} from "../../../../generated/prisma/models";
import prisma from "../../db";
export async function getFoldersByOwner(owner: string) {
const folders = await prisma.folder.findMany({

View File

@@ -3,8 +3,8 @@
import {
text_pairCreateInput,
text_pairUpdateInput,
} from "../../../generated/prisma/models";
import prisma from "../db";
} from "../../../../generated/prisma/models";
import prisma from "../../db";
export async function createTextPair(data: text_pairCreateInput) {
await prisma.text_pair.create({

View File

@@ -1,6 +1,6 @@
"use server";
import { getLLMAnswer } from "../ai";
import { getLLMAnswer } from "./ai";
export const genIPA = async (text: string) => {
return (

View File

@@ -0,0 +1,58 @@
import {
TranslationHistoryArraySchema,
TranslationHistorySchema,
} from "@/lib/interfaces";
import z from "zod";
import { shallowEqual } from "../utils";
export const getLocalStorageOperator = <T extends z.ZodTypeAny>(
key: string,
schema: T,
) => {
return {
get: (): z.infer<T> => {
try {
const item = globalThis.localStorage.getItem(key);
if (!item) return [];
const rawData = JSON.parse(item) as z.infer<T>;
const result = schema.safeParse(rawData);
if (result.success) {
return result.data;
} else {
console.error(
"Invalid data structure in localStorage:",
result.error,
);
return [];
}
} catch (e) {
console.error(`Failed to parse ${key} data:`, e);
return [];
}
},
set: (data: z.infer<T>) => {
if (!globalThis.localStorage) return;
globalThis.localStorage.setItem(key, JSON.stringify(data));
return data;
},
};
};
const MAX_HISTORY_LENGTH = 50;
export const tlso = getLocalStorageOperator<
typeof TranslationHistoryArraySchema
>("translator", TranslationHistoryArraySchema);
export const tlsoPush = (item: z.infer<typeof TranslationHistorySchema>) => {
const oldHistory = tlso.get();
if (oldHistory.some((v) => shallowEqual(v, item))) return oldHistory;
const newHistory = [...oldHistory, item].slice(-MAX_HISTORY_LENGTH);
tlso.set(newHistory);
return newHistory;
};

View File

@@ -1,5 +1,4 @@
import { ProsodyOptions } from "edge-tts-universal";
import { EdgeTTS } from "edge-tts-universal/browser";
import { ProsodyOptions, EdgeTTS } from "edge-tts-universal/browser";
export async function getTTSAudioUrl(
text: string,

View File

@@ -1,22 +0,0 @@
import {
TranslationHistoryArraySchema,
TranslationHistorySchema,
} from "@/lib/interfaces";
import { getLocalStorageOperator, shallowEqual } from "@/lib/utils";
import z from "zod";
const MAX_HISTORY_LENGTH = 50;
export const tlso = getLocalStorageOperator<
typeof TranslationHistoryArraySchema
>("translator", TranslationHistoryArraySchema);
export const tlsoPush = (item: z.infer<typeof TranslationHistorySchema>) => {
const oldHistory = tlso.get();
if (oldHistory.some((v) => shallowEqual(v, item))) return oldHistory;
const newHistory = [...oldHistory, item].slice(-MAX_HISTORY_LENGTH);
tlso.set(newHistory);
return newHistory;
};

View File

@@ -1,130 +1,3 @@
import { EdgeTTS, ProsodyOptions } from "edge-tts-universal/browser";
import { env } from "process";
import z from "zod";
import { NextResponse } from "next/server";
export function inspect(word: string) {
const goto = (url: string) => {
window.open(url, "_blank");
};
return () => {
word = word.toLowerCase();
goto(`https://www.youdao.com/result?word=${word}&lang=en`);
};
}
export function urlGoto(url: string) {
window.open(url, "_blank");
}
const API_KEY = env.ZHIPU_API_KEY;
export async function callZhipuAPI(
messages: { role: string; content: string }[],
model = "glm-4.6",
) {
const url = "https://open.bigmodel.cn/api/paas/v4/chat/completions";
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: "Bearer " + API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: model,
messages: messages,
temperature: 0.2,
thinking: {
type: "disabled",
},
}),
});
if (!response.ok) {
throw new Error(`API 调用失败: ${response.status}`);
}
return await response.json();
}
export async function getTTSAudioUrl(
text: string,
short_name: string,
options: ProsodyOptions | undefined = undefined,
) {
const tts = new EdgeTTS(text, short_name, options);
try {
const result = await tts.synthesize();
return URL.createObjectURL(result.audio);
} catch (e) {
throw e;
}
}
export const getLocalStorageOperator = <T extends z.ZodTypeAny>(
key: string,
schema: T,
) => {
return {
get: (): z.infer<T> => {
try {
const item = globalThis.localStorage.getItem(key);
if (!item) return [];
const rawData = JSON.parse(item) as z.infer<T>;
const result = schema.safeParse(rawData);
if (result.success) {
return result.data;
} else {
console.error(
"Invalid data structure in localStorage:",
result.error,
);
return [];
}
} catch (e) {
console.error(`Failed to parse ${key} data:`, e);
return [];
}
},
set: (data: z.infer<T>) => {
if (!globalThis.localStorage) return;
globalThis.localStorage.setItem(key, JSON.stringify(data));
return data;
},
};
};
export function handleAPIError(error: unknown, message: string) {
console.error(message, error);
return NextResponse.json(
{ error: "服务器内部错误", message },
{ status: 500 },
);
}
export const letsFetch = (
url: string,
onSuccess: (message: string) => void,
onError: (message: string) => void,
onFinally: () => void,
) => {
return fetch(url)
.then((response) => response.json())
.then((data) => {
if (data.status === "success") {
onSuccess(data.message);
} else if (data.status === "error") {
onError(data.message);
} else {
onError("Unknown error");
}
})
.finally(onFinally);
};
export function isNonNegativeInteger(str: string): boolean {
return /^\d+$/.test(str);
}