diff --git a/.eslintrc.json b/.eslintrc.json index bffb357..03925c7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,8 @@ { - "extends": "next/core-web-vitals" + "extends": "next/core-web-vitals", + "rules": { + "@next/next/no-img-element": "off", + "react-hooks/exhaustive-deps": "off", + "@next/next/no-html-link-for-pages": "off" + } } diff --git a/.gitignore b/.gitignore index fd3dbb5..185fc45 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,9 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +.idea +.vscode +yarn.lock +pnpm-lock.yaml +package-lock.json diff --git a/package.json b/package.json index 768bfc4..5d2d4dc 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "dependencies": { "@headlessui/react": "^1.7.18", "@heroicons/react": "^2.1.1", - "@next/third-parties": "^14.1.3", + "@next/third-parties": "^14.2.25", "@stripe/stripe-js": "^3.0.7", "@tailwindcss/typography": "^0.5.10", "ahooks": "^3.7.10", @@ -18,9 +18,9 @@ "clsx": "^2.1.0", "date-fns": "^3.3.1", "google-auth-library": "^9.6.3", - "next": "14.1.3", + "next": "14.2.25", "next-auth": "^4.24.6", - "next-intl": "^3.9.2", + "next-intl": "^3.26.0", "pg": "^8.11.3", "react": "^18", "react-dom": "^18", @@ -36,7 +36,7 @@ "@types/react-dom": "^18", "autoprefixer": "^10.0.1", "eslint": "^8", - "eslint-config-next": "14.1.3", + "eslint-config-next": "14.2.25", "postcss": "^8", "tailwindcss": "^3.3.0", "typescript": "^5" diff --git a/sql/tables/8_search_log.sql b/sql/tables/7_search_log.sql similarity index 100% rename from sql/tables/8_search_log.sql rename to sql/tables/7_search_log.sql diff --git a/sql/tables/7_works_translate_task.sql b/sql/tables/7_works_translate_task.sql deleted file mode 100644 index d601d43..0000000 --- a/sql/tables/7_works_translate_task.sql +++ /dev/null @@ -1,25 +0,0 @@ --- auto-generated definition -create table works_translate_task -( - id bigint generated by default as identity - primary key, - created_at timestamp with time zone default now() not null, - updated_at timestamp with time zone default now() not null, - uid varchar, - origin_language varchar, - status varchar -); - -comment on table works_translate_task is 'works_translate_task'; - -comment on column works_translate_task.id is '自增id'; - -comment on column works_translate_task.created_at is '创建时间'; - -comment on column works_translate_task.updated_at is '更新时间'; - -comment on column works_translate_task.uid is 'uid'; - -comment on column works_translate_task.origin_language is 'origin_language'; - -comment on column works_translate_task.status is 'status: 0未翻译,1已翻译'; diff --git a/sql/tables/9_sensitive_words.sql b/sql/tables/8_sensitive_words.sql similarity index 100% rename from sql/tables/9_sensitive_words.sql rename to sql/tables/8_sensitive_words.sql diff --git a/src/app/[locale]/api/cron/workTranslate/route.ts b/src/app/[locale]/api/cron/workTranslate/route.ts deleted file mode 100644 index 9763cc9..0000000 --- a/src/app/[locale]/api/cron/workTranslate/route.ts +++ /dev/null @@ -1,78 +0,0 @@ -import {getDb} from "~/libs/db"; -import {locales} from "~/config"; -import {translateContent} from "~/servers/translate"; - -export const maxDuration = 300; - -export async function GET() { - const db = getDb(); - const timeFlag = 'workTranslate' + '-=->' + new Date().getTime(); - console.time(timeFlag); - const results = await db.query('select * from works_translate_task where status=$1 order by created_at asc limit 3', [0]); - const rows = results.rows; - if (rows.length <= 0) { - console.log('没有任务需要处理'); - console.timeEnd(timeFlag); - return Response.json({message: '没有任务需要处理'}); - } - for (let i = 0; i < rows.length; i++) { - const oneTask = rows[i]; - // 翻译为除了原始语言的其他语言,如果原始语言不在支持列表,就翻译为支持的十种语言 - const origin_language = oneTask.origin_language; - const uid = oneTask.uid; - - const needLanguage = getNeedTranslateLanguage(origin_language); - - if (needLanguage.length <= 0) { - // 更新状态为已翻译完成 - await db.query('update works_translate_task set status=$1 where uid=$2', [1, uid]); - console.log('没有需要翻译的语言-=->', uid); - console.timeEnd(timeFlag); - return Response.json({message: '没有需要翻译的语言'}); - } - - // 查出原始数据 - const resultsOrigin = await db.query('select * from works where uid=$1 and is_origin=$2 and is_delete=$3', [uid, true, false]); - const rowsOrigin = resultsOrigin.rows; - if (rowsOrigin.length <= 0) { - console.log('没有原始数据-=->', uid); - console.timeEnd(timeFlag); - // 更新状态为已翻译完成 - await db.query('update works_translate_task set status=$1 where uid=$2', [1, uid]); - return Response.json({message: '没有原始数据'}); - } - const originData = rowsOrigin[0]; - if (originData.output_url == '') { - // 如果原始数据的url还没生成,就不翻译了 - console.log('原始数据的url还没生成-=->', uid); - console.timeEnd(timeFlag); - return Response.json({message: '原始数据的url还没生成'}); - } - const timeFlagCurrent = '翻译' + '-=->' + uid; - console.time(timeFlagCurrent); - for (let i = 0; i < needLanguage.length; i++) { - const toLanguage = needLanguage[i]; - const translateText = await translateContent(originData.input_text, toLanguage); - const sqlStr = 'insert into works(uid, input_text, output_url, is_public, status, user_id, revised_text, is_origin, origin_language, current_language) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)'; - const data = [uid, translateText, originData.output_url, originData.is_public, originData.status, originData.user_id, originData.revised_text, false, originData.origin_language, toLanguage]; - await db.query(sqlStr, data); - } - console.timeEnd(timeFlagCurrent); - console.log('翻译完-=->', uid); - // 更新状态为已翻译完成 - await db.query('update works_translate_task set status=$1 where uid=$2', [1, uid]); - } - console.timeEnd(timeFlag); - return Response.json({message: '本次翻译任务翻译完'}); -} - -function getNeedTranslateLanguage(origin_language: string) { - const needTranslateLanguage = []; - // 判断出需要翻译的语言,并调用翻译 - for (let i = 0; i < locales.length; i++) { - if (origin_language != locales[i]) { - needTranslateLanguage.push(locales[i]); - } - } - return needTranslateLanguage; -} diff --git a/src/app/[locale]/api/generate/handle/route.ts b/src/app/[locale]/api/generate/handle/route.ts index 27cbd60..644f398 100644 --- a/src/app/[locale]/api/generate/handle/route.ts +++ b/src/app/[locale]/api/generate/handle/route.ts @@ -1,13 +1,12 @@ -import {getUserById} from "~/servers/user"; -import {checkUserTimes, countDownUserTimes} from "~/servers/manageUserTimes"; -import {v4 as uuidv4} from 'uuid'; -import {getReplicateClient} from "~/libs/replicateClient"; -import {getInput} from "~/libs/replicate"; -import {getDb} from "~/libs/db"; -import {getLanguage} from "~/servers/language"; -import {checkSubscribe} from "~/servers/subscribe"; -import {checkSensitiveInputText} from "~/servers/checkInput"; - +import { getUserById } from "~/servers/user"; +import { checkUserTimes, countDownUserTimes } from "~/servers/manageUserTimes"; +import { v4 as uuidv4 } from "uuid"; +import { getReplicateClient } from "~/libs/replicateClient"; +import { getInput } from "~/libs/replicate"; +import { getDb } from "~/libs/db"; +import { getLanguage } from "~/servers/language"; +import { checkSubscribe } from "~/servers/subscribe"; +import { checkSensitiveInputText } from "~/servers/checkInput"; export async function POST(req: Request, res: Response) { let json = await req.json(); @@ -15,14 +14,14 @@ export async function POST(req: Request, res: Response) { let user_id = json.user_id; let is_public = json.is_public; - if (!user_id && process.env.NEXT_PUBLIC_CHECK_GOOGLE_LOGIN != '0') { - return Response.json({msg: "Login to continue.", status: 601}); + if (!user_id && process.env.NEXT_PUBLIC_CHECK_GOOGLE_LOGIN != "0") { + return Response.json({ msg: "Login to continue.", status: 601 }); } // 检查用户在数据库是否存在,不存在则返回需登录 const resultsUser = await getUserById(user_id); - if (resultsUser.email == '' && process.env.NEXT_PUBLIC_CHECK_GOOGLE_LOGIN != '0') { - return Response.json({msg: "Login to continue.", status: 601}); + if (resultsUser.email == "" && process.env.NEXT_PUBLIC_CHECK_GOOGLE_LOGIN != "0") { + return Response.json({ msg: "Login to continue.", status: 601 }); } const checkSubscribeStatus = await checkSubscribe(user_id); @@ -30,14 +29,14 @@ export async function POST(req: Request, res: Response) { if (!is_public) { // 判断用户是否订阅状态,否则返回错误 if (!checkSubscribeStatus) { - return Response.json({msg: "Pricing to continue.", status: 602}); + return Response.json({ msg: "Pricing to continue.", status: 602 }); } } if (!checkSubscribeStatus) { const check = await checkUserTimes(user_id); - if (!check && process.env.NEXT_PUBLIC_CHECK_AVAILABLE_TIME != '0') { - return Response.json({msg: "Pricing to continue.", status: 602}); + if (!check && process.env.NEXT_PUBLIC_CHECK_AVAILABLE_TIME != "0") { + return Response.json({ msg: "Pricing to continue.", status: 602 }); } } @@ -46,7 +45,7 @@ export async function POST(req: Request, res: Response) { // 敏感词没通过,校验是否订阅 if (!checkSubscribeStatus) { // 未订阅则返回付费再继续 - return Response.json({msg: "Pricing to continue.", status: 602}); + return Response.json({ msg: "Pricing to continue.", status: 602 }); } else { // 订阅强制设置其为用户私有,不公开 is_public = false; @@ -63,23 +62,30 @@ export async function POST(req: Request, res: Response) { input: input, webhook: `${process.env.REPLICATE_WEBHOOK}/api/generate/callByReplicate?uid=${uid}`, webhook_events_filter: ["completed"], - }) + }); const db = getDb(); // 创建新的数据 - await db.query('insert into works(uid, input_text, output_url, is_public, status, user_id, revised_text, is_origin, origin_language, current_language) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)', - [uid, textStr, '', is_public, 0, user_id, input.prompt, true, origin_language, origin_language]); - // 创建一条翻译任务 - await db.query('insert into works_translate_task(uid,origin_language,status) values($1,$2,$3)', [uid, origin_language, 0]); - + await db.query("insert into works(uid, input_text, output_url, is_public, status, user_id, revised_text, is_origin, origin_language, current_language) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)", [ + uid, + textStr, + "", + is_public, + 0, + user_id, + input.prompt, + true, + origin_language, + origin_language, + ]); // 需要登录,且需要支付时,才操作该项 - if (process.env.NEXT_PUBLIC_CHECK_GOOGLE_LOGIN != '0' && process.env.NEXT_PUBLIC_CHECK_AVAILABLE_TIME != '0' && !checkSubscribeStatus) { + if (process.env.NEXT_PUBLIC_CHECK_GOOGLE_LOGIN != "0" && process.env.NEXT_PUBLIC_CHECK_AVAILABLE_TIME != "0" && !checkSubscribeStatus) { // 减少用户次数 await countDownUserTimes(user_id); } const resultInfo = { - uid: uid - } + uid: uid, + }; return Response.json(resultInfo); } diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 230db3e..6b6654a 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -1,14 +1,14 @@ import clsx from 'clsx'; -import {Inter} from 'next/font/google'; -import {notFound} from 'next/navigation'; -import {unstable_setRequestLocale} from 'next-intl/server'; -import {ReactNode} from 'react'; -import {locales} from '~/config'; -import {CommonProvider} from '~/context/common-context'; -import {NextAuthProvider} from '~/context/next-auth-context'; -import {getAuthText, getCommonText, getMenuText, getPricingText} from "~/configs/languageText"; +import { Inter } from 'next/font/google'; +import { notFound } from 'next/navigation'; +import { setRequestLocale } from 'next-intl/server'; +import { ReactNode } from 'react'; +import { locales } from '~/i18n/config'; +import { CommonProvider } from '~/context/common-context'; +import { NextAuthProvider } from '~/context/next-auth-context'; +import { getAuthText, getCommonText, getMenuText, getPricingText } from "~/i18n/languageText"; -const inter = Inter({subsets: ['latin']}); +const inter = Inter({ subsets: ['latin'] }); type Props = { children: ReactNode; @@ -16,19 +16,19 @@ type Props = { }; export function generateStaticParams() { - return locales.map((locale) => ({locale})); + return locales.map((locale) => ({ locale })); } export default async function LocaleLayout({ - children, - params: {locale} - }: Props) { + children, + params: { locale } +}: Props) { // Validate that the incoming `locale` parameter is valid if (!locales.includes(locale as any)) notFound(); // Enable static rendering - unstable_setRequestLocale(locale); + setRequestLocale(locale); const commonText = await getCommonText(); const authText = await getAuthText(); @@ -37,21 +37,21 @@ export default async function LocaleLayout({ return ( -
- - - -