Perf: i18n change and captcha code. (#2625)

* perf: send captcha check

* perf: back router

* perf: i18n init

* perf: ui

* i18n

* perf: ui duration
This commit is contained in:
Archer 2024-09-05 23:01:12 +08:00 committed by GitHub
parent 478386c612
commit c614f8b9ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 259 additions and 793 deletions

View File

@ -13,7 +13,7 @@
"js", "js",
"ts" "ts"
], ],
"i18n-ally.keystyle": "nested", "i18n-ally.keystyle": "flat",
"i18n-ally.sortKeys": true, "i18n-ally.sortKeys": true,
"i18n-ally.keepFulfilled": false, "i18n-ally.keepFulfilled": false,
"i18n-ally.sourceLanguage": "zh", // "i18n-ally.sourceLanguage": "zh", //

View File

@ -56,32 +56,35 @@ curl --location --request POST 'https://{{host}}/api/admin/initv4810' \
7. 新增 - 应用调用迁移成单独节点,同时可以传递全局变量和用户的文件。 7. 新增 - 应用调用迁移成单独节点,同时可以传递全局变量和用户的文件。
8. 新增 - 插件增加使用说明配置。 8. 新增 - 插件增加使用说明配置。
9. 新增 - 工作流导出导入,支持直接导出和导入 JSON 文件,便于交流。 9. 新增 - 工作流导出导入,支持直接导出和导入 JSON 文件,便于交流。
10. 商业版新增 - 飞书机器人接入 10. 新增 - HTTP模块支持超时配置、支持更多的 Body 类型params 和 headers 支持新的变量选择模式。
11. 商业版新增 - 公众号接入接入 11. 新增 - 发送验证码安全校验。
12. 商业版新增 - 自助开票申请 12. 商业版新增 - 飞书机器人接入
13. 商业版新增 - SSO 定制 13. 商业版新增 - 公众号接入接入
14. 优化 - 工作流循环校验,避免 skip 循环空转。同时支持分支完全并发执行。 14. 商业版新增 - 自助开票申请
15. 优化 - SSE 响应优化。 15. 商业版新增 - SSO 定制
16. 优化 - 无 SSL 证书情况下,优化复制。 16. 优化 - 工作流循环校验,避免 skip 循环空转。同时支持分支完全并发执行。
17. 优化 - 单选框打开后自动滚动到选中的位置。 17. 优化 - SSE 响应优化。
18. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。 18. 优化 - 无 SSL 证书情况下,优化复制。
19. 优化 - 节点选择,避免切换 tab 时候path 加载报错。 19. 优化 - 单选框打开后自动滚动到选中的位置。
20. 优化 - 最新 React Markdown 组件,支持 Base64 图片。 20. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。
21. 优化 - 知识库列表 UI。 21. 优化 - 节点选择,避免切换 tab 时候path 加载报错。
22. 优化 - 知识库详情页 UI。 22. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
23. 优化 - 支持无网络配置情况下运行。 23. 优化 - 知识库列表 UI。
24. 优化 - 部分全局变量,增加数据类型约束。 24. 优化 - 知识库详情页 UI。
25. 优化 - 查看工作流详情,切换 tab 时,自动滚动到顶部。 25. 优化 - 支持无网络配置情况下运行。
26. 修复 - 全局变量 key 可能重复。 26. 优化 - 部分全局变量,增加数据类型约束。
27. 修复 - Prompt 模式调用工具stream=false 模式下,会携带 0: 开头标记。 27. 优化 - 查看工作流详情,切换 tab 时,自动滚动到顶部。
28. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。 28. 优化 - 对话框性能问题。
29. 修复 - 选择 Milvus 部署时,无法导出知识库。 29. 修复 - 全局变量 key 可能重复。
30. 修复 - 创建 APP 副本,无法复制系统配置。 30. 修复 - Prompt 模式调用工具stream=false 模式下,会携带 0: 开头标记。
31. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。 31. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
32. 修复 - 内容提取的数据类型与输出数据类型未一致。 32. 修复 - 选择 Milvus 部署时,无法导出知识库。
33. 修复 - 工作流运行时间统计错误。 33. 修复 - 创建 APP 副本,无法复制系统配置。
34. 修复 - stream 模式下,工具调用有可能出现 undefined 34. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
35. 修复 - 全局变量在 API 中无法持久化。 35. 修复 - 内容提取的数据类型与输出数据类型未一致。
36. 修复 - OpenAPIdetail=false模式下不应该返回 tool 调用结果,仅返回文字。(可解决 cow 不适配问题) 36. 修复 - 工作流运行时间统计错误。
37. 修复 - 知识库标签重复加载。 37. 修复 - stream 模式下,工具调用有可能出现 undefined
38. 修复 - Debug 模式下,循环调用边问题。 38. 修复 - 全局变量在 API 中无法持久化。
39. 修复 - OpenAPIdetail=false模式下不应该返回 tool 调用结果,仅返回文字。(可解决 cow 不适配问题)
40. 修复 - 知识库标签重复加载。
41. 修复 - Debug 模式下,循环调用边问题。

View File

@ -48,7 +48,7 @@ export class PgVectorCtrl {
const { teamId, datasetId, collectionId, vector, retry = 3 } = props; const { teamId, datasetId, collectionId, vector, retry = 3 } = props;
try { try {
const { rows } = await PgClient.insert(DatasetVectorTableName, { const { rowCount, rows } = await PgClient.insert(DatasetVectorTableName, {
values: [ values: [
[ [
{ key: 'vector', value: `[${vector}]` }, { key: 'vector', value: `[${vector}]` },
@ -58,6 +58,11 @@ export class PgVectorCtrl {
] ]
] ]
}); });
if (rowCount === 0) {
return Promise.reject('insertDatasetData: no insert');
}
return { return {
insertId: rows[0].id insertId: rows[0].id
}; };

View File

@ -0,0 +1,45 @@
import Cookies, { CookieAttributes } from 'js-cookie';
import { useTranslation } from 'next-i18next';
const setCookie = (key: string, value: string, options?: CookieAttributes) => {
Cookies.set(key, value, options);
};
const getCookie = (key: string) => {
return Cookies.get(key);
};
const LANG_KEY = 'NEXT_LOCALE';
export const useI18nLng = () => {
const { i18n } = useTranslation();
const onChangeLng = (lng: string) => {
setCookie(LANG_KEY, lng, {
expires: 30,
sameSite: 'None',
secure: true
});
i18n?.changeLanguage(lng);
};
const setUserDefaultLng = () => {
if (!navigator || !localStorage) return;
if (getCookie(LANG_KEY)) return onChangeLng(getCookie(LANG_KEY) as string);
const languageMap = {
zh: 'zh',
'zh-CN': 'zh'
};
// @ts-ignore
const lang = languageMap[navigator.language] || 'en';
// currentLng not in userLang
return onChangeLng(lang);
};
return {
onChangeLng,
setUserDefaultLng
};
};

View File

@ -15,8 +15,7 @@
"version_initial_copy": "Duplicate - Original State", "version_initial_copy": "Duplicate - Original State",
"version_name_tips": "Version name cannot be empty", "version_name_tips": "Version name cannot be empty",
"version_past": "Previously Published", "version_past": "Previously Published",
"version_publish_tips": "This version will be saved to the team cloud, synchronized with the entire team, and update the app version on all release channels.", "version_publish_tips": "This version will be saved to the team cloud, synchronized with the entire team, and update the app version on all release channels."
"version_save_tips": "This version will be saved to the team cloud, synchronized with the entire team."
}, },
"app_detail": "Application Details", "app_detail": "Application Details",
"chat_debug": "Chat Preview", "chat_debug": "Chat Preview",
@ -138,13 +137,11 @@
"Create plugin bot": "Create Plugin", "Create plugin bot": "Create Plugin",
"Create simple bot": "Create Simple App", "Create simple bot": "Create Simple App",
"Create simple bot tip": "Create a simple AI app by filling out a form, suitable for beginners.", "Create simple bot tip": "Create a simple AI app by filling out a form, suitable for beginners.",
"Create template tip": "Explore more features in the template market to help you understand and get started with various applications.",
"Create workflow bot": "Create Workflow", "Create workflow bot": "Create Workflow",
"Create workflow tip": "Build complex multi-turn dialogue AI applications through low-code methods, recommended for advanced users.", "Create workflow tip": "Build complex multi-turn dialogue AI applications through low-code methods, recommended for advanced users.",
"Http plugin": "HTTP Plugin", "Http plugin": "HTTP Plugin",
"Plugin": "Plugin", "Plugin": "Plugin",
"Simple bot": "Simple App", "Simple bot": "Simple App",
"Template": "Create via Template",
"Workflow bot": "Workflow" "Workflow bot": "Workflow"
}, },
"upload_file_max_amount": "Maximum File Quantity", "upload_file_max_amount": "Maximum File Quantity",
@ -169,8 +166,6 @@
"workflow": { "workflow": {
"Input guide": "Input Guide", "Input guide": "Input Guide",
"file_url": "Document Link", "file_url": "Document Link",
"option1": "Option 1",
"option2": "Option 2",
"read_files": "Document Parsing", "read_files": "Document Parsing",
"read_files_result": "Document Parsing Result", "read_files_result": "Document Parsing Result",
"read_files_result_desc": "Original document text, consisting of file names and document content, separated by hyphens between multiple files.", "read_files_result_desc": "Original document text, consisting of file names and document content, separated by hyphens between multiple files.",

View File

@ -24,12 +24,10 @@
"items": "Items", "items": "Items",
"module_runtime_and": "Total Module Runtime", "module_runtime_and": "Total Module Runtime",
"multiple_AI_conversations": "Multiple AI Conversations", "multiple_AI_conversations": "Multiple AI Conversations",
"new_chat": "New Conversation",
"new_input_guide_lexicon": "New Lexicon", "new_input_guide_lexicon": "New Lexicon",
"no_workflow_response": "No workflow data", "no_workflow_response": "No workflow data",
"plugins_output": "Plugin Output", "plugins_output": "Plugin Output",
"question_tip": "From top to bottom, the response order of each module", "question_tip": "From top to bottom, the response order of each module",
"rearrangement": "Rearrangement of Retrieval Results",
"response": { "response": {
"node_inputs": "Node Inputs" "node_inputs": "Node Inputs"
}, },

View File

@ -6,10 +6,6 @@
"ai_point_expire_a": "Yes, they will expire. After the current package expires, the AI points will be reset to the new package's AI points. Annual package AI points are valid for one year, not monthly.", "ai_point_expire_a": "Yes, they will expire. After the current package expires, the AI points will be reset to the new package's AI points. Annual package AI points are valid for one year, not monthly.",
"ai_point_expire_q": "Do AI points expire?", "ai_point_expire_q": "Do AI points expire?",
"ai_point_q": "What are AI points?", "ai_point_q": "What are AI points?",
"auto_renew_a": "After the current package expires, the system will automatically renew according to the 'Future Package'. The system will attempt to deduct the fee from your account balance. Please ensure there is sufficient balance for automatic renewal.",
"auto_renew_q": "Will the subscription package renew automatically?",
"change_package_a": "If the current package price is higher than the new package, it cannot be switched immediately and will switch upon renewal after the current package expires.\nIf the current package price is lower than the new package, the system will calculate the remaining balance of the current package, and you can pay the difference to switch packages.",
"change_package_q": "Can I switch subscription packages?",
"check_subscription_a": "Go to Account - Personal Information - Package Details - Usage. You can view the effective and expiration dates of your subscribed packages. After the paid package expires, it will automatically switch to the free version.", "check_subscription_a": "Go to Account - Personal Information - Package Details - Usage. You can view the effective and expiration dates of your subscribed packages. After the paid package expires, it will automatically switch to the free version.",
"check_subscription_q": "Where can I view my subscribed packages?", "check_subscription_q": "Where can I view my subscribed packages?",
"dataset_compute_a": "1 Dataset storage equals 1 Dataset index. A piece of Dataset data can contain one or more Dataset indexes. In enhanced training, 1 piece of data generates 5 indexes.", "dataset_compute_a": "1 Dataset storage equals 1 Dataset index. A piece of Dataset data can contain one or more Dataset indexes. In enhanced training, 1 piece of data generates 5 indexes.",
@ -27,7 +23,6 @@
"Login": "Login", "Login": "Login",
"Move": "Move", "Move": "Move",
"Name": "Name", "Name": "Name",
"Not_selected": "Not selected",
"Rename": "Rename", "Rename": "Rename",
"Resume": "Resume", "Resume": "Resume",
"Running": "Running", "Running": "Running",
@ -146,7 +141,6 @@
"Exit": "Exit", "Exit": "Exit",
"Exit Directly": "Exit Directly", "Exit Directly": "Exit Directly",
"Expired Time": "Expiration Time", "Expired Time": "Expiration Time",
"Field": "Field",
"File": "File", "File": "File",
"Finish": "Finish", "Finish": "Finish",
"Import": "Import", "Import": "Import",
@ -212,7 +206,6 @@
"Update Failed": "Update Failed", "Update Failed": "Update Failed",
"Update Success": "Updated Successfully", "Update Success": "Updated Successfully",
"Update Successful": "Updated Successfully", "Update Successful": "Updated Successfully",
"Upload File Failed": "File Upload Failed",
"Username": "Username", "Username": "Username",
"Waiting": "Waiting", "Waiting": "Waiting",
"Warning": "Warning", "Warning": "Warning",
@ -225,7 +218,7 @@
"base_config": "Basic Configuration", "base_config": "Basic Configuration",
"choosable": "Choosable", "choosable": "Choosable",
"confirm": { "confirm": {
"Common Tip": "Operation Confirmation" "Common Tip": "Confirm"
}, },
"copy_to_clipboard": "Copy to Clipboard", "copy_to_clipboard": "Copy to Clipboard",
"course": { "course": {
@ -236,7 +229,6 @@
}, },
"error": { "error": {
"Select avatar failed": "Avatar Selection Failed", "Select avatar failed": "Avatar Selection Failed",
"too_many_request": "Too Many Requests, Please Try Again Later.",
"unKnow": "An Unexpected Error Occurred" "unKnow": "An Unexpected Error Occurred"
}, },
"export_to_json": "Export to JSON", "export_to_json": "Export to JSON",
@ -278,7 +270,6 @@
}, },
"submit_success": "Submitted Successfully", "submit_success": "Submitted Successfully",
"submitted": "Submitted", "submitted": "Submitted",
"submitting": "Submitting",
"support": "Support", "support": "Support",
"system": { "system": {
"Commercial version function": "Please Upgrade to the Commercial Version to Use This Feature: https://fastgpt.in", "Commercial version function": "Please Upgrade to the Commercial Version to Use This Feature: https://fastgpt.in",
@ -335,8 +326,6 @@
"Max histories": "Number of Chat Histories", "Max histories": "Number of Chat Histories",
"Max tokens": "Response Limit", "Max tokens": "Response Limit",
"Name and avatar": "Avatar & Name", "Name and avatar": "Avatar & Name",
"Not saved": "Not Saved",
"Onclick to save": "Click to Save",
"Publish": "Publish", "Publish": "Publish",
"Publish Confirm": "Confirm to Publish App? This Will Immediately Update the App Status on All Publishing Channels.", "Publish Confirm": "Confirm to Publish App? This Will Immediately Update the App Status on All Publishing Channels.",
"Publish app tip": "After Publishing the App, All Publishing Channels Will Immediately Use This Version", "Publish app tip": "After Publishing the App, All Publishing Channels Will Immediately Use This Version",
@ -345,7 +334,6 @@
"Quote prompt": "Quote Template Prompt", "Quote prompt": "Quote Template Prompt",
"Quote templates": "Quote Content Templates", "Quote templates": "Quote Content Templates",
"Random": "Divergent", "Random": "Divergent",
"Saved time": "Saved: {{time}}",
"Search team tags": "Search Tags", "Search team tags": "Search Tags",
"Select TTS": "Select Voice Playback Mode", "Select TTS": "Select Voice Playback Mode",
"Select app from template": "Select from Template", "Select app from template": "Select from Template",
@ -385,22 +373,12 @@
"Custom feedback": "Custom Feedback", "Custom feedback": "Custom Feedback",
"close custom feedback": "Close Feedback" "close custom feedback": "Close Feedback"
}, },
"have_publish": "Published",
"have_saved": "Saved", "have_saved": "Saved",
"loading": "Loading",
"logs": { "logs": {
"Source And Time": "Source & Time" "Source And Time": "Source & Time"
}, },
"more": "View More", "more": "View More",
"navbar": {
"External": "External Use",
"Flow mode": "Advanced Orchestration",
"Publish": "Publish",
"Publish app": "Publish App",
"Simple mode": "Simple Configuration"
},
"no_app": "No Apps Yet, Create One Now!", "no_app": "No Apps Yet, Create One Now!",
"not_published": "Not Published",
"not_saved": "Not Saved", "not_saved": "Not Saved",
"outLink": { "outLink": {
"Can Drag": "Icon Can Be Dragged", "Can Drag": "Icon Can Be Dragged",
@ -415,7 +393,6 @@
"Show History": "Show Chat History" "Show History": "Show Chat History"
}, },
"publish": { "publish": {
"Fei Shu Bot Desc": "Integrate into Feishu Bot",
"Fei shu bot": "Feishu", "Fei shu bot": "Feishu",
"Fei shu bot publish": "Publish to Feishu Bot" "Fei shu bot publish": "Publish to Feishu Bot"
}, },
@ -474,13 +451,11 @@
"Audio Not Support": "Device Does Not Support Voice Playback", "Audio Not Support": "Device Does Not Support Voice Playback",
"Audio Speech Error": "Voice Playback Error", "Audio Speech Error": "Voice Playback Error",
"Cancel Speak": "Cancel Voice Input", "Cancel Speak": "Cancel Voice Input",
"Chat API is error or undefined": "Chat API Error or Undefined",
"Confirm to clear history": "Confirm to Clear Online Chat History for This App? Share and API Call Records Will Not Be Cleared.", "Confirm to clear history": "Confirm to Clear Online Chat History for This App? Share and API Call Records Will Not Be Cleared.",
"Confirm to clear share chat history": "Confirm to Delete All Chat Records?", "Confirm to clear share chat history": "Confirm to Delete All Chat Records?",
"Converting to text": "Converting to Text...", "Converting to text": "Converting to Text...",
"Custom History Title": "Custom History Title", "Custom History Title": "Custom History Title",
"Custom History Title Description": "If set to empty, it will automatically follow the chat record.", "Custom History Title Description": "If set to empty, it will automatically follow the chat record.",
"Debug test": "Debug Preview",
"Exit Chat": "Exit Chat", "Exit Chat": "Exit Chat",
"Failed to initialize chat": "Failed to Initialize Chat", "Failed to initialize chat": "Failed to Initialize Chat",
"Feedback Failed": "Feedback Submission Failed", "Feedback Failed": "Feedback Submission Failed",
@ -504,7 +479,6 @@
"Record": "Voice Input", "Record": "Voice Input",
"Restart": "Restart Chat", "Restart": "Restart Chat",
"Run test": "Run Preview", "Run test": "Run Preview",
"Select Image": "Select Image",
"Select dataset": "Select Dataset", "Select dataset": "Select Dataset",
"Select dataset Desc": "Select a Dataset to store the expected answer", "Select dataset Desc": "Select a Dataset to store the expected answer",
"Send Message": "Send", "Send Message": "Send",
@ -549,10 +523,8 @@
"response": { "response": {
"Complete Response": "Complete Response", "Complete Response": "Complete Response",
"Extension model": "Question Optimization Model", "Extension model": "Question Optimization Model",
"Plugin response detail": "Plugin Details",
"Read complete response": "View Details", "Read complete response": "View Details",
"Read complete response tips": "Click to View Detailed Process", "Read complete response tips": "Click to View Detailed Process",
"Tool call response detail": "Tool Run Details",
"Tool call tokens": "Tool Call Tokens Consumption", "Tool call tokens": "Tool Call Tokens Consumption",
"context total length": "Total Context Length", "context total length": "Total Context Length",
"module cq": "Question Classification List", "module cq": "Question Classification List",
@ -589,14 +561,11 @@
} }
}, },
"dataset": { "dataset": {
"All Dataset": "All Datasets",
"Avatar": "Dataset Avatar",
"Choose Dataset": "Associate Dataset", "Choose Dataset": "Associate Dataset",
"Collection": "Dataset", "Collection": "Dataset",
"Create dataset": "Create a {{name}}", "Create dataset": "Create a {{name}}",
"Dataset": "Dataset", "Dataset": "Dataset",
"Dataset ID": "Dataset ID", "Dataset ID": "Dataset ID",
"Dataset Type": "Dataset Type",
"Delete Confirm": "Confirm to Delete This Dataset? Data Cannot Be Recovered After Deletion, Please Confirm!", "Delete Confirm": "Confirm to Delete This Dataset? Data Cannot Be Recovered After Deletion, Please Confirm!",
"Empty Dataset": "Empty Dataset", "Empty Dataset": "Empty Dataset",
"Empty Dataset Tips": "No Dataset Yet, Create One Now!", "Empty Dataset Tips": "No Dataset Yet, Create One Now!",
@ -605,7 +574,6 @@
"Intro Placeholder": "This Dataset Has No Introduction Yet", "Intro Placeholder": "This Dataset Has No Introduction Yet",
"Manual collection": "Manual Dataset", "Manual collection": "Manual Dataset",
"My Dataset": "My Dataset", "My Dataset": "My Dataset",
"Name": "Dataset Name",
"Query extension intro": "Enabling the question optimization function can improve the accuracy of Dataset searches during continuous conversations. After enabling this function, when performing Dataset searches, the AI will complete the missing information of the question based on the conversation history.", "Query extension intro": "Enabling the question optimization function can improve the accuracy of Dataset searches during continuous conversations. After enabling this function, when performing Dataset searches, the AI will complete the missing information of the question based on the conversation history.",
"Quote Length": "Quote Content Length", "Quote Length": "Quote Content Length",
"Read Dataset": "View Dataset Details", "Read Dataset": "View Dataset Details",
@ -629,7 +597,6 @@
"Chunk Size": "Chunk Size", "Chunk Size": "Chunk Size",
"Createtime": "Creation Time", "Createtime": "Creation Time",
"Raw text length": "Raw Text Length", "Raw text length": "Raw Text Length",
"Read Metadata": "View Metadata",
"Training Type": "Training Mode", "Training Type": "Training Mode",
"Updatetime": "Update Time", "Updatetime": "Update Time",
"Web page selector": "Web Page Selector", "Web page selector": "Web Page Selector",
@ -648,8 +615,7 @@
"success": "Sync Started" "success": "Sync Started"
} }
}, },
"training": { "training": {}
}
}, },
"data": { "data": {
"Auxiliary Data": "Auxiliary Data", "Auxiliary Data": "Auxiliary Data",
@ -665,7 +631,6 @@
"Search data placeholder": "Search Related Data", "Search data placeholder": "Search Related Data",
"Too Long": "Total Length Exceeded", "Too Long": "Total Length Exceeded",
"Total Amount": "{{total}} Groups", "Total Amount": "{{total}} Groups",
"empty_index": "No Custom Index",
"group": "Group", "group": "Group",
"unit": "Items" "unit": "Items"
}, },
@ -673,7 +638,6 @@
"error": { "error": {
"Data not found": "Data Not Found or Deleted", "Data not found": "Data Not Found or Deleted",
"Start Sync Failed": "Failed to Start Sync", "Start Sync Failed": "Failed to Start Sync",
"Template does not exist": "Template Does Not Exist",
"invalidVectorModelOrQAModel": "Invalid Vector Model or QA Model", "invalidVectorModelOrQAModel": "Invalid Vector Model or QA Model",
"unAuthDataset": "Unauthorized to Operate This Dataset", "unAuthDataset": "Unauthorized to Operate This Dataset",
"unAuthDatasetCollection": "Unauthorized to Operate This Dataset", "unAuthDatasetCollection": "Unauthorized to Operate This Dataset",
@ -814,7 +778,6 @@
"Add question type": "Add Question Type", "Add question type": "Add Question Type",
"Add_option": "Add Option", "Add_option": "Add Option",
"Can not connect self": "Cannot Connect to Itself", "Can not connect self": "Cannot Connect to Itself",
"Confirm Delete Node": "Confirm to Delete This Node?",
"Data Type": "Data Type", "Data Type": "Data Type",
"Dataset quote": { "Dataset quote": {
"label": "Dataset Quote", "label": "Dataset Quote",
@ -859,19 +822,15 @@
}, },
"http": { "http": {
"Add props": "Add Parameter", "Add props": "Add Parameter",
"Add props_and_tips": "To add parameters, enter \"/\" to invoke the variable list",
"AppId": "App ID", "AppId": "App ID",
"AppSecret": "AppSecret",
"ChatId": "Current Chat ID", "ChatId": "Current Chat ID",
"Current time": "Current Time", "Current time": "Current Time",
"Histories": "History Records", "Histories": "History Records",
"Key already exists": "Key Already Exists", "Key already exists": "Key Already Exists",
"Key cannot be empty": "Parameter Name Cannot Be Empty", "Key cannot be empty": "Parameter Name Cannot Be Empty",
"Props name": "Parameter Name", "Props name": "Parameter Name",
"Props name_and_tips": "Parameter name, enter \"/\" to call up the variable list",
"Props tip": "You can set related parameters for the HTTP request\nYou can call global variables or external parameter inputs through {{key}}, currently available variables:\n{{variable}}", "Props tip": "You can set related parameters for the HTTP request\nYou can call global variables or external parameter inputs through {{key}}, currently available variables:\n{{variable}}",
"Props value": "Parameter Value", "Props value": "Parameter Value",
"Props value_and_tips": "Parameter value, enter \"/\" to invoke the variable list",
"ResponseChatItemId": "AI Response ID", "ResponseChatItemId": "AI Response ID",
"Url and params have been split": "Path parameters have been automatically added to Params", "Url and params have been split": "Path parameters have been automatically added to Params",
"curl import": "cURL Import", "curl import": "cURL Import",
@ -923,14 +882,12 @@
"Query extension": "Question Optimization", "Query extension": "Question Optimization",
"System Plugin": "System Plugin", "System Plugin": "System Plugin",
"System input module": "System Input", "System input module": "System Input",
"Team Plugin": "Team Plugin",
"Team app": "Team App", "Team app": "Team App",
"Tool module": "Tool", "Tool module": "Tool",
"UnKnow Module": "Unknown Module", "UnKnow Module": "Unknown Module",
"ai_chat": "AI conversation", "ai_chat": "AI conversation",
"ai_chat_intro": "AI large model dialogue", "ai_chat_intro": "AI large model dialogue",
"config_params": "Can configure application system parameters", "config_params": "Can configure application system parameters",
"empty_app": "Blank application",
"empty_plugin": "Blank plugin", "empty_plugin": "Blank plugin",
"empty_workflow": "Blank workflow", "empty_workflow": "Blank workflow",
"http body placeholder": "Same syntax as Apifox", "http body placeholder": "Same syntax as Apifox",
@ -959,9 +916,7 @@
"variable option is value is required": "Option Content Cannot Be Empty", "variable option is value is required": "Option Content Cannot Be Empty",
"variable options": "Options" "variable options": "Options"
}, },
"variable add option": "Add Option", "variable add option": "Add Option"
"variable_update": "Variable Update",
"variable_update_info": "Can update the output value of the specified node or update global variables"
}, },
"plugin": { "plugin": {
"Custom headers": "Custom Request Headers", "Custom headers": "Custom Request Headers",
@ -1009,7 +964,6 @@
"Reference": "Variable Reference", "Reference": "Variable Reference",
"custom": "Custom Variable", "custom": "Custom Variable",
"dynamicTargetInput": "Dynamic External Data", "dynamicTargetInput": "Dynamic External Data",
"file_link": "File Upload",
"input": "Single Line Input Box", "input": "Single Line Input Box",
"number input": "Number Input Box", "number input": "Number Input Box",
"select": "Single Select Box", "select": "Single Select Box",
@ -1024,7 +978,6 @@
"OnRevert version confirm": "Confirm to Revert to This Version? The configuration of the editing version will be saved, and a new release version will be created for the reverted version.", "OnRevert version confirm": "Confirm to Revert to This Version? The configuration of the editing version will be saved, and a new release version will be created for the reverted version.",
"histories": "Release Records" "histories": "Release Records"
}, },
"run_test": "Run",
"template": { "template": {
"Interactive": "Interactive", "Interactive": "Interactive",
"Multimodal": "Multimodal", "Multimodal": "Multimodal",
@ -1068,21 +1021,14 @@
"Select One Collection To Store": "Select a File to Store" "Select One Collection To Store": "Select a File to Store"
}, },
"data": { "data": {
"Add Index": "Add Custom Index",
"Can not edit": "No Edit Permission", "Can not edit": "No Edit Permission",
"Custom Index Number": "Custom Index {{number}}", "Custom Index Number": "Custom Index {{number}}",
"Default Index": "Default Index", "Default Index": "Default Index",
"Delete Tip": "Confirm to Delete This Data?", "Delete Tip": "Confirm to Delete This Data?",
"Index Edit": "Data Index",
"Index Placeholder": "Enter Index Text Content", "Index Placeholder": "Enter Index Text Content",
"Input Data": "Import New Data",
"Input Success Tip": "Data Imported Successfully", "Input Success Tip": "Data Imported Successfully",
"Update Data": "Update Data",
"Update Success Tip": "Data Updated Successfully", "Update Success Tip": "Data Updated Successfully",
"edit": { "edit": {
"Content": "Data Content",
"Course": "Documentation",
"Delete": "Delete Data",
"Index": "Data Index ({{amount}})", "Index": "Data Index ({{amount}})",
"divide_content": "Segment Content" "divide_content": "Segment Content"
}, },
@ -1094,19 +1040,15 @@
"noResult": "No Search Results" "noResult": "No Search Results"
} }
}, },
"default_reply": "Default Reply",
"error": { "error": {
"Create failed": "Create failed", "Create failed": "Create failed",
"code_error": "Code error",
"fileNotFound": "File not found~", "fileNotFound": "File not found~",
"inheritPermissionError": "Inherit permission Error", "inheritPermissionError": "Inherit permission Error",
"missingParams": "Insufficient parameters", "missingParams": "Insufficient parameters",
"team": {
"overSize": "Team Member Limit Exceeded"
},
"upload_file_error_filename": "{{name}} Upload Failed", "upload_file_error_filename": "{{name}} Upload Failed",
"username_empty": "Account cannot be empty" "username_empty": "Account cannot be empty"
}, },
"error.code_error": "Verification code error",
"extraction_results": "Extraction Results", "extraction_results": "Extraction Results",
"field_name": "Field Name", "field_name": "Field Name",
"free": "Free", "free": "Free",
@ -1142,28 +1084,16 @@
}, },
"new_create": "Create New", "new_create": "Create New",
"no": "No", "no": "No",
"no_data": "No Data Available",
"no_laf_env": "System Not Configured with Laf Environment", "no_laf_env": "System Not Configured with Laf Environment",
"not_yet_introduced": "No Introduction Yet", "not_yet_introduced": "No Introduction Yet",
"option": "Option", "option": "Option",
"pay": { "pay": {
"amount": "Amount", "amount": "Amount",
"balance": "Account Balance",
"balance_notice": "Insufficient Account Balance",
"confirm_pay": "Confirm Payment",
"get_pay_QR": "Get Payment QR Code",
"need_pay": "Need to Pay",
"need_to_pay": "Actual Payment",
"new_package_price": "New Package Price",
"notice": "Please Do Not Close the Page",
"old_package_price": "Old Package Balance",
"other": "Other Amount, Please Use Whole Numbers",
"package_tip": { "package_tip": {
"buy": "The package you purchased is lower than the current package. This package will take effect after the current package expires.\nYou can view the package usage in Account - Personal Information - Package Details.", "buy": "The package you purchased is lower than the current package. This package will take effect after the current package expires.\nYou can view the package usage in Account - Personal Information - Package Details.",
"renewal": "You are renewing the package. You can view the package usage in Account - Personal Information - Package Details.", "renewal": "You are renewing the package. You can view the package usage in Account - Personal Information - Package Details.",
"upgrade": "The package you purchased is higher than the current package. This package will take effect immediately, and the current package will take effect later. You can view the package usage in Account - Personal Information - Package Details." "upgrade": "The package you purchased is higher than the current package. This package will take effect immediately, and the current package will take effect later. You can view the package usage in Account - Personal Information - Package Details."
}, },
"to_recharge": "Insufficient Balance, Go to Recharge",
"wechat": "Please Scan the QR Code with WeChat to Pay: {{price}} Yuan\nPlease Do Not Close the Page", "wechat": "Please Scan the QR Code with WeChat to Pay: {{price}} Yuan\nPlease Do Not Close the Page",
"yuan": "{{amount}} Yuan" "yuan": "{{amount}} Yuan"
}, },
@ -1218,7 +1148,6 @@
"go to laf": "Go to Write", "go to laf": "Go to Write",
"path": "Path" "path": "Path"
}, },
"reply_now": "Reply Now",
"required": "Required", "required": "Required",
"resume_failed": "Resume Failed", "resume_failed": "Resume Failed",
"select_reference_variable": "Select Reference Variable", "select_reference_variable": "Select Reference Variable",
@ -1252,8 +1181,6 @@
}, },
"standard": { "standard": {
"AI Bonus Points": "AI Points", "AI Bonus Points": "AI Points",
"Expired Time": "End Time",
"Start Time": "Start Time",
"due_date": "Due Date", "due_date": "Due Date",
"storage": "Storage", "storage": "Storage",
"type": "Type" "type": "Type"
@ -1279,22 +1206,14 @@
"System message": "System Message" "System message": "System Message"
}, },
"login": { "login": {
"And": "and",
"Email": "Email", "Email": "Email",
"Forget Password": "Forgot Password?",
"Github": "GitHub Login", "Github": "GitHub Login",
"Google": "Google Login", "Google": "Google Login",
"Password": "Password", "Password": "Password",
"Password login": "Password Login", "Password login": "Password Login",
"Phone": "Phone Login", "Phone": "Phone Login",
"Phone number": "Phone Number", "Phone number": "Phone Number",
"Policy tip": "By using, you agree to our",
"Privacy": "Privacy Policy",
"Provider error": "Login Error, Please Try Again", "Provider error": "Login Error, Please Try Again",
"Register": "Register Account",
"Root login": "Login with Root User",
"Root password placeholder": "Root password is the environment variable you set",
"Terms": "Terms of Service",
"Username": "Username", "Username": "Username",
"Wechat": "WeChat Login", "Wechat": "WeChat Login",
"can_not_login": "Cannot Log In, Click to Contact", "can_not_login": "Cannot Log In, Click to Contact",
@ -1314,12 +1233,9 @@
"wallet": { "wallet": {
"Ai point every thousand tokens": "{{points}} Points/1K Tokens", "Ai point every thousand tokens": "{{points}} Points/1K Tokens",
"Amount": "Amount", "Amount": "Amount",
"Bills": "Bills and Invoices",
"Buy": "Buy", "Buy": "Buy",
"Confirm pay": "Payment Confirmation",
"Not sufficient": "Insufficient AI Points, Please Upgrade Your Package or Purchase Additional AI Points to Continue Using.", "Not sufficient": "Insufficient AI Points, Please Upgrade Your Package or Purchase Additional AI Points to Continue Using.",
"Plan expired time": "Package Expiration Time", "Plan expired time": "Package Expiration Time",
"Plan reset time": "Package Reset Time",
"Standard Plan Detail": "Package Details", "Standard Plan Detail": "Package Details",
"To read plan": "View Package", "To read plan": "View Package",
"amount_0": "Purchase Quantity Cannot Be 0", "amount_0": "Purchase Quantity Cannot Be 0",
@ -1356,7 +1272,6 @@
"company_address": "Company Address", "company_address": "Company Address",
"company_phone": "Company Phone", "company_phone": "Company Phone",
"email": "Email Address", "email": "Email Address",
"in_valid": "There are empty fields or email format errors",
"need_special_invoice": "Need Special Invoice", "need_special_invoice": "Need Special Invoice",
"organization_name": "Organization Name", "organization_name": "Organization Name",
"unit_code": "Unified Credit Code" "unit_code": "Unified Credit Code"
@ -1376,7 +1291,6 @@
"AI points usage": "AI Points Usage", "AI points usage": "AI Points Usage",
"AI points usage tip": "Each time the AI model is called, a certain amount of AI points will be consumed. For specific calculation standards, please refer to the 'Pricing' above.", "AI points usage tip": "Each time the AI model is called, a certain amount of AI points will be consumed. For specific calculation standards, please refer to the 'Pricing' above.",
"Ai points": "AI Points Calculation Standards", "Ai points": "AI Points Calculation Standards",
"Buy now": "Switch Package",
"Current plan": "Current Package", "Current plan": "Current Package",
"Extra ai points": "Extra AI Points", "Extra ai points": "Extra AI Points",
"Extra dataset size": "Extra Dataset Capacity", "Extra dataset size": "Extra Dataset Capacity",
@ -1385,10 +1299,7 @@
"FAQ": "FAQ", "FAQ": "FAQ",
"Month amount": "Months", "Month amount": "Months",
"Next plan": "Future Package", "Next plan": "Future Package",
"Nonsupport": "No Purchase Needed",
"Stand plan level": "Subscription Package", "Stand plan level": "Subscription Package",
"Standard update fail": "Failed to Update Subscription Package",
"Standard update success": "Subscription Package Updated Successfully!",
"Sub plan": "Subscription Package", "Sub plan": "Subscription Package",
"Sub plan tip": "Free to use {{title}} or upgrade to a higher package", "Sub plan tip": "Free to use {{title}} or upgrade to a higher package",
"Team plan and usage": "Package and Usage", "Team plan and usage": "Package and Usage",
@ -1454,8 +1365,7 @@
"Total points": "AI Points Consumption", "Total points": "AI Points Consumption",
"Usage Detail": "Usage Details", "Usage Detail": "Usage Details",
"Whisper": "Voice Input" "Whisper": "Voice Input"
}, }
"use_default": "Use Default Header"
} }
}, },
"sync_link": "Sync Link", "sync_link": "Sync Link",
@ -1492,28 +1402,23 @@
"Laf Account Setting": "Laf Account Configuration", "Laf Account Setting": "Laf Account Configuration",
"Language": "Language", "Language": "Language",
"Member Name": "Nickname", "Member Name": "Nickname",
"Notice": "Notice",
"Notification Receive": "Notification Receive", "Notification Receive": "Notification Receive",
"Notification Receive Bind": "Please bind the notification receive method first", "Notification Receive Bind": "Please bind the notification receive method first",
"Old password is error": "Old Password is Incorrect", "Old password is error": "Old Password is Incorrect",
"OpenAI Account Setting": "OpenAI Account Configuration", "OpenAI Account Setting": "OpenAI Account Configuration",
"Password": "Password", "Password": "Password",
"Pay": "Recharge", "Pay": "Recharge",
"Personal Information": "Profile",
"Promotion": "Promotion", "Promotion": "Promotion",
"Promotion Rate": "Cashback Rate", "Promotion Rate": "Cashback Rate",
"Promotion Record": "Promotion Record",
"Promotion rate tip": "You will receive a balance reward when friends recharge", "Promotion rate tip": "You will receive a balance reward when friends recharge",
"Replace": "Replace", "Replace": "Replace",
"Set OpenAI Account Failed": "Failed to Set OpenAI Account", "Set OpenAI Account Failed": "Failed to Set OpenAI Account",
"Sign Out": "Sign Out",
"Team": "Team", "Team": "Team",
"Time": "Time", "Time": "Time",
"Timezone": "Timezone", "Timezone": "Timezone",
"Update Password": "Update Password", "Update Password": "Update Password",
"Update password failed": "Failed to Update Password", "Update password failed": "Failed to Update Password",
"Update password successful": "Password Updated Successfully", "Update password successful": "Password Updated Successfully",
"Usage Record": "Usage Record",
"apikey": { "apikey": {
"key": "API Key" "key": "API Key"
}, },
@ -1568,8 +1473,7 @@
}, },
"role": { "role": {
"Admin": "Admin", "Admin": "Admin",
"Owner": "Owner", "Owner": "Owner"
"Visitor": "Visitor"
} }
}, },
"type": "Type" "type": "Type"

View File

@ -1,7 +1,5 @@
{ {
"Disabled": "Disabled",
"Enable": "Enable", "Enable": "Enable",
"Enabled": "Enabled",
"collection": { "collection": {
"Create update time": "Creation/Update Time", "Create update time": "Creation/Update Time",
"Training type": "Training Mode" "Training type": "Training Mode"

View File

@ -0,0 +1,13 @@
{
"Login": "Login",
"forget_password": "Find password",
"login_failed": "Login failed",
"login_success": "Login successful",
"password_condition": "Password maximum 60 characters",
"policy_tip": "By useing, you agree to our",
"privacy": "Privacy policy",
"register": "Register",
"root_password_placeholder": "The root user password is the value of the environment variable DEFAULT_ROOT_PSW",
"terms": "Terms",
"use_root_login": "Log in as root user"
}

View File

@ -4,20 +4,17 @@
"copy_link_hint": "Copy the link below to the specified location", "copy_link_hint": "Copy the link below to the specified location",
"create_api_key": "Create New Key", "create_api_key": "Create New Key",
"create_link": "Create Link", "create_link": "Create Link",
"default_response": "Default Response",
"edit_api_key": "Edit Key Details", "edit_api_key": "Edit Key Details",
"edit_feishu_bot": "Edit Feishu Bot", "edit_feishu_bot": "Edit Feishu Bot",
"edit_link": "Edit", "edit_link": "Edit",
"feishu_api": "Feishu API", "feishu_api": "Feishu API",
"feishu_bot": "Feishu Bot", "feishu_bot": "Feishu Bot",
"feishu_bot_desc": "Connect to Feishu Bot directly via API", "feishu_bot_desc": "Connect to Feishu Bot directly via API",
"feishu_name": "Feishu",
"key_alias": "Key alias, for display only", "key_alias": "Key alias, for display only",
"key_tips": "You can use the API key to access specific interfaces (cannot access the application, use the in-app API key for that)", "key_tips": "You can use the API key to access specific interfaces (cannot access the application, use the in-app API key for that)",
"link_name": "Share Link Name", "link_name": "Share Link Name",
"new_feishu_bot": "Add New Feishu Bot", "new_feishu_bot": "Add New Feishu Bot",
"official_account": { "official_account": {
"api": "WeChat Official Account API",
"create_modal_title": "Create WeChat Official Account Integration", "create_modal_title": "Create WeChat Official Account Integration",
"desc": "Connect to WeChat Official Account directly via API", "desc": "Connect to WeChat Official Account directly via API",
"edit_modal_title": "Edit WeChat Official Account Integration", "edit_modal_title": "Edit WeChat Official Account Integration",

View File

@ -2,7 +2,6 @@
"bill": { "bill": {
"balance": "Balance", "balance": "Balance",
"buy_plan": "Purchase Plan", "buy_plan": "Purchase Plan",
"buy_standard_plan_success": "Plan Purchase Successful",
"contact_customer_service": "Contact Support", "contact_customer_service": "Contact Support",
"conversion": "Conversion", "conversion": "Conversion",
"convert_error": "Conversion Failed", "convert_error": "Conversion Failed",
@ -20,6 +19,7 @@
"you_can_convert": "You can convert", "you_can_convert": "You can convert",
"yuan": "Yuan" "yuan": "Yuan"
}, },
"bill_and_invoices": "Bill & Invoice",
"bind_inform_account_error": "Failed to Bind Notification Account", "bind_inform_account_error": "Failed to Bind Notification Account",
"bind_inform_account_success": "Notification Account Bound Successfully", "bind_inform_account_success": "Notification Account Bound Successfully",
"delete": { "delete": {
@ -27,28 +27,24 @@
"admin_success": "Admin Deleted Successfully" "admin_success": "Admin Deleted Successfully"
}, },
"has_chosen": "Selected", "has_chosen": "Selected",
"individuation": "Individuation",
"login": { "login": {
"error": "Login Error", "error": "Login Error",
"failed": "Login Failed",
"login_account": "Login to {{account}} Account",
"login_error": "Incorrect Username or Password",
"password_condition": "Password can be up to 60 characters", "password_condition": "Password can be up to 60 characters",
"success": "Login Successful", "success": "Login Successful"
"to_register": "No account? Register"
}, },
"name": "Name", "name": "Name",
"notice": "Notice",
"notification": { "notification": {
"Bind Notification Pipe Hint": "Please bind a notification receiving account to ensure you receive notifications such as plan expiration reminders, ensuring your service runs smoothly.", "Bind Notification Pipe Hint": "Please bind a notification receiving account to ensure you receive notifications such as plan expiration reminders, ensuring your service runs smoothly.",
"remind_owner_bind": "Please remind the creator to bind a notification account" "remind_owner_bind": "Please remind the creator to bind a notification account"
}, },
"operations": "Actions", "operations": "Actions",
"password": { "password": {
"change_error": "Password Change Error",
"code_required": "Verification Code Required", "code_required": "Verification Code Required",
"code_send_error": "Failed to Send Verification Code", "code_send_error": "Failed to Send Verification Code",
"code_sended": "Verification Code Sent", "code_sended": "Verification Code Sent",
"confirm": "Confirm Password", "confirm": "Confirm Password",
"email_phone": "Email/Phone Number",
"email_phone_error": "Invalid Email/Phone Number Format", "email_phone_error": "Invalid Email/Phone Number Format",
"email_phone_void": "Email/Phone Number Cannot Be Empty", "email_phone_void": "Email/Phone Number Cannot Be Empty",
"get_code": "Get Verification Code", "get_code": "Get Verification Code",
@ -80,19 +76,17 @@
"write": "In addition to readable resources, you can also create new resources" "write": "In addition to readable resources, you can also create new resources"
}, },
"permissions": "Permissions", "permissions": "Permissions",
"promotion": { "personal_information": "Me",
"pay": "Friend Payment", "personalization": "Personalization",
"register": "Friend Registration" "promotion_records": "Promotion",
},
"register": { "register": {
"confirm": "Confirm Registration", "confirm": "Confirm Registration",
"error": "Registration Error",
"failed": "Registration Failed",
"register_account": "Register {{account}} Account", "register_account": "Register {{account}} Account",
"success": "Registration Successful", "success": "Registration Successful",
"to_login": "Already have an account? Login" "to_login": "Already have an account? Login"
}, },
"search_user": "Search Username", "search_user": "Search Username",
"sign_out": "Sign out",
"synchronization": { "synchronization": {
"button": "Sync Now", "button": "Sync Now",
"placeholder": "Enter Sync Tag", "placeholder": "Enter Sync Tag",
@ -109,5 +103,6 @@
"official_account": "Official Account", "official_account": "Official Account",
"share": "Share Link", "share": "Share Link",
"wecom": "WeCom" "wecom": "WeCom"
} },
"usage_record": "Usages"
} }

View File

@ -1,11 +1,4 @@
{ {
" i18nT('workflow": {
"use_user_id'),\n required": {
"workflow": {
"use_user_id": ""
}
}
},
"Code": "Code", "Code": "Code",
"about_xxx_question": "Question regarding xxx", "about_xxx_question": "Question regarding xxx",
"add_new_input": "Add New Input", "add_new_input": "Add New Input",
@ -122,15 +115,12 @@
"Custom outputs": "Custom Outputs", "Custom outputs": "Custom Outputs",
"Error": "Error", "Error": "Error",
"Read file result": "Read File Result", "Read file result": "Read File Result",
"User_select_description": "Description",
"User_select_result": "Selected Result",
"read files": "Read Files" "read files": "Read Files"
}, },
"select_an_application": "Select an Application", "select_an_application": "Select an Application",
"select_another_application_to_call": "You can choose another application to call", "select_another_application_to_call": "You can choose another application to call",
"special_array_format": "Special array format, returns an empty array when the search result is empty.", "special_array_format": "Special array format, returns an empty array when the search result is empty.",
"start_with": "Starts With", "start_with": "Starts With",
"system_variables": "system variables",
"target_fields_description": "A target field consists of 'description' and 'key'. Multiple target fields can be extracted.", "target_fields_description": "A target field consists of 'description' and 'key'. Multiple target fields can be extracted.",
"template": { "template": {
"ai_chat": "AI Chat", "ai_chat": "AI Chat",
@ -156,9 +146,7 @@
"variable_picker_tips": "Type node name or variable name to search", "variable_picker_tips": "Type node name or variable name to search",
"variable_update": "Variable Update", "variable_update": "Variable Update",
"workflow": { "workflow": {
"Back_to_current_version": "Back to Current Version",
"My edit": "My Edit", "My edit": "My Edit",
"Switch_failed": "Switch Failed",
"Switch_success": "Switch Successful", "Switch_success": "Switch Successful",
"Team cloud": "Team Cloud", "Team cloud": "Team Cloud",
"exit_tips": "Your changes have not been saved. 'Exit directly' will not save your edits." "exit_tips": "Your changes have not been saved. 'Exit directly' will not save your edits."

View File

@ -15,8 +15,7 @@
"version_initial_copy": "副本-初始状态", "version_initial_copy": "副本-初始状态",
"version_name_tips": "版本名称不能为空", "version_name_tips": "版本名称不能为空",
"version_past": "发布过", "version_past": "发布过",
"version_publish_tips": "该版本将被保存至团队云端,同步给整个团队,同时更新所有发布渠道的应用版本", "version_publish_tips": "该版本将被保存至团队云端,同步给整个团队,同时更新所有发布渠道的应用版本"
"version_save_tips": "该版本将被保存至团队云端,同步给整个团队"
}, },
"app_detail": "应用详情", "app_detail": "应用详情",
"chat_debug": "调试预览", "chat_debug": "调试预览",
@ -131,13 +130,11 @@
"Create plugin bot": "创建插件", "Create plugin bot": "创建插件",
"Create simple bot": "创建简易应用", "Create simple bot": "创建简易应用",
"Create simple bot tip": "通过填表单形式,创建简单的 AI 应用,适合新手", "Create simple bot tip": "通过填表单形式,创建简单的 AI 应用,适合新手",
"Create template tip": "在模板市场探索更多玩法,带你理解并上手各种应用",
"Create workflow bot": "创建工作流", "Create workflow bot": "创建工作流",
"Create workflow tip": "通过低代码的方式,构建逻辑复杂的多轮对话 AI 应用,推荐高级玩家使用", "Create workflow tip": "通过低代码的方式,构建逻辑复杂的多轮对话 AI 应用,推荐高级玩家使用",
"Http plugin": "HTTP 插件", "Http plugin": "HTTP 插件",
"Plugin": "插件", "Plugin": "插件",
"Simple bot": "简易应用", "Simple bot": "简易应用",
"Template": "通过模板创建",
"Workflow bot": "工作流" "Workflow bot": "工作流"
}, },
"upload_file_max_amount": "最大文件数量", "upload_file_max_amount": "最大文件数量",
@ -162,8 +159,6 @@
"workflow": { "workflow": {
"Input guide": "填写说明", "Input guide": "填写说明",
"file_url": "文档链接", "file_url": "文档链接",
"option1": "选项 1",
"option2": "选项 2",
"read_files": "文档解析", "read_files": "文档解析",
"read_files_result": "文档解析结果", "read_files_result": "文档解析结果",
"read_files_result_desc": "文档原文,由文件名和文档内容组成,多个文件之间通过横线隔开。", "read_files_result_desc": "文档原文,由文件名和文档内容组成,多个文件之间通过横线隔开。",

View File

@ -24,12 +24,10 @@
"items": "条", "items": "条",
"module_runtime_and": "模块运行时间和", "module_runtime_and": "模块运行时间和",
"multiple_AI_conversations": "多组 AI 对话", "multiple_AI_conversations": "多组 AI 对话",
"new_chat": "新对话",
"new_input_guide_lexicon": "新词库", "new_input_guide_lexicon": "新词库",
"no_workflow_response": "没有运行数据", "no_workflow_response": "没有运行数据",
"plugins_output": "插件输出", "plugins_output": "插件输出",
"question_tip": "从上到下,为各个模块的响应顺序", "question_tip": "从上到下,为各个模块的响应顺序",
"rearrangement": "检索结果重排",
"response": { "response": {
"node_inputs": "节点输入" "node_inputs": "节点输入"
}, },

View File

@ -6,10 +6,6 @@
"ai_point_expire_a": "会过期。当前套餐过期后AI积分将会清空并更新为新套餐的AI积分。年度套餐的AI积分时长为1年而不是每个月。", "ai_point_expire_a": "会过期。当前套餐过期后AI积分将会清空并更新为新套餐的AI积分。年度套餐的AI积分时长为1年而不是每个月。",
"ai_point_expire_q": "AI积分会过期么", "ai_point_expire_q": "AI积分会过期么",
"ai_point_q": "什么是AI积分", "ai_point_q": "什么是AI积分",
"auto_renew_a": "当前套餐过期后,系统会自动根据“未来套餐”进行续费,系统会尝试从账户余额进行扣费,如果您需要自动续费,请在账户余额中预留额度。",
"auto_renew_q": "订阅套餐会自动续费么?",
"change_package_a": "当前套餐价格大于新套餐时,无法立即切换,将会在当前套餐过期后以“续费”形式进行切换。\n当前套餐价格小于新套餐时系统会自动计算当前套餐剩余余额您可支付差价进行套餐切换。",
"change_package_q": "能否切换订阅套餐?",
"check_subscription_a": "账号-个人信息-套餐详情-使用情况。您可以查看所拥有套餐的生效和到期时间。当付费套餐到期后将自动切换免费版。", "check_subscription_a": "账号-个人信息-套餐详情-使用情况。您可以查看所拥有套餐的生效和到期时间。当付费套餐到期后将自动切换免费版。",
"check_subscription_q": "在哪里查看已订阅的套餐?", "check_subscription_q": "在哪里查看已订阅的套餐?",
"dataset_compute_a": "1条知识库存储等于1条知识库索引。一条知识库数据可以包含1条或多条知识库索引。增强训练中1条数据会生成5条索引。", "dataset_compute_a": "1条知识库存储等于1条知识库索引。一条知识库数据可以包含1条或多条知识库索引。增强训练中1条数据会生成5条索引。",
@ -27,7 +23,6 @@
"Login": "登录", "Login": "登录",
"Move": "移动", "Move": "移动",
"Name": "名称", "Name": "名称",
"Not_selected": "未选择",
"Rename": "重命名", "Rename": "重命名",
"Resume": "恢复", "Resume": "恢复",
"Running": "运行中", "Running": "运行中",
@ -146,7 +141,6 @@
"Exit": "退出", "Exit": "退出",
"Exit Directly": "直接退出", "Exit Directly": "直接退出",
"Expired Time": "过期时间", "Expired Time": "过期时间",
"Field": "字段",
"File": "文件", "File": "文件",
"Finish": "完成", "Finish": "完成",
"Import": "导入", "Import": "导入",
@ -212,7 +206,6 @@
"Update Failed": "更新异常", "Update Failed": "更新异常",
"Update Success": "更新成功", "Update Success": "更新成功",
"Update Successful": "更新成功", "Update Successful": "更新成功",
"Upload File Failed": "上传文件失败",
"Username": "用户名", "Username": "用户名",
"Waiting": "等待中", "Waiting": "等待中",
"Warning": "警告", "Warning": "警告",
@ -236,7 +229,6 @@
}, },
"error": { "error": {
"Select avatar failed": "头像选择异常", "Select avatar failed": "头像选择异常",
"too_many_request": "请求太频繁了,请稍后重试。",
"unKnow": "出现了点意外~" "unKnow": "出现了点意外~"
}, },
"export_to_json": "导出为 JSON", "export_to_json": "导出为 JSON",
@ -278,7 +270,6 @@
}, },
"submit_success": "提交成功", "submit_success": "提交成功",
"submitted": "已提交", "submitted": "已提交",
"submitting": "提交中",
"support": "支持", "support": "支持",
"system": { "system": {
"Commercial version function": "请升级商业版后使用该功能https://fastgpt.in", "Commercial version function": "请升级商业版后使用该功能https://fastgpt.in",
@ -335,8 +326,6 @@
"Max histories": "聊天记录数量", "Max histories": "聊天记录数量",
"Max tokens": "回复上限", "Max tokens": "回复上限",
"Name and avatar": "头像 & 名称", "Name and avatar": "头像 & 名称",
"Not saved": "未保存",
"Onclick to save": "点击保存",
"Publish": "发布", "Publish": "发布",
"Publish Confirm": "确认发布应用?会立即更新所有发布渠道的应用状态。", "Publish Confirm": "确认发布应用?会立即更新所有发布渠道的应用状态。",
"Publish app tip": "发布应用后,所有发布渠道将会立即使用该版本", "Publish app tip": "发布应用后,所有发布渠道将会立即使用该版本",
@ -345,7 +334,6 @@
"Quote prompt": "引用模板提示词", "Quote prompt": "引用模板提示词",
"Quote templates": "引用内容模板", "Quote templates": "引用内容模板",
"Random": "发散", "Random": "发散",
"Saved time": "已保存:{{time}}",
"Search team tags": "搜索标签", "Search team tags": "搜索标签",
"Select TTS": "选择语音播放模式", "Select TTS": "选择语音播放模式",
"Select app from template": "从模板中选择", "Select app from template": "从模板中选择",
@ -385,22 +373,12 @@
"Custom feedback": "自定义反馈", "Custom feedback": "自定义反馈",
"close custom feedback": "关闭反馈" "close custom feedback": "关闭反馈"
}, },
"have_publish": "已发布",
"have_saved": "已保存", "have_saved": "已保存",
"loading": "加载中",
"logs": { "logs": {
"Source And Time": "来源 & 时间" "Source And Time": "来源 & 时间"
}, },
"more": "查看更多", "more": "查看更多",
"navbar": {
"External": "外部使用",
"Flow mode": "高级编排",
"Publish": "发布",
"Publish app": "发布应用",
"Simple mode": "简易配置"
},
"no_app": "还没有应用,快去创建一个吧!", "no_app": "还没有应用,快去创建一个吧!",
"not_published": "未发布",
"not_saved": "未保存", "not_saved": "未保存",
"outLink": { "outLink": {
"Can Drag": "图标可拖拽", "Can Drag": "图标可拖拽",
@ -415,7 +393,6 @@
"Show History": "展示历史对话" "Show History": "展示历史对话"
}, },
"publish": { "publish": {
"Fei Shu Bot Desc": "接入到飞书机器人中",
"Fei shu bot": "飞书", "Fei shu bot": "飞书",
"Fei shu bot publish": "发布到飞书机器人" "Fei shu bot publish": "发布到飞书机器人"
}, },
@ -474,13 +451,11 @@
"Audio Not Support": "设备不支持语音播放", "Audio Not Support": "设备不支持语音播放",
"Audio Speech Error": "语音播报异常", "Audio Speech Error": "语音播报异常",
"Cancel Speak": "取消语音输入", "Cancel Speak": "取消语音输入",
"Chat API is error or undefined": "对话接口报错或返回为空",
"Confirm to clear history": "确认清空该应用的在线聊天记录?分享和 API 调用的记录不会被清空。", "Confirm to clear history": "确认清空该应用的在线聊天记录?分享和 API 调用的记录不会被清空。",
"Confirm to clear share chat history": "确认删除所有聊天记录?", "Confirm to clear share chat history": "确认删除所有聊天记录?",
"Converting to text": "正在转换为文本...", "Converting to text": "正在转换为文本...",
"Custom History Title": "自定义历史记录标题", "Custom History Title": "自定义历史记录标题",
"Custom History Title Description": "如果设置为空,会自动跟随聊天记录。", "Custom History Title Description": "如果设置为空,会自动跟随聊天记录。",
"Debug test": "调试预览",
"Exit Chat": "退出聊天", "Exit Chat": "退出聊天",
"Failed to initialize chat": "初始化聊天失败", "Failed to initialize chat": "初始化聊天失败",
"Feedback Failed": "提交反馈异常", "Feedback Failed": "提交反馈异常",
@ -504,7 +479,6 @@
"Record": "语音输入", "Record": "语音输入",
"Restart": "重开对话", "Restart": "重开对话",
"Run test": "运行预览", "Run test": "运行预览",
"Select Image": "选择图片",
"Select dataset": "选择知识库", "Select dataset": "选择知识库",
"Select dataset Desc": "选择一个知识库存储预期答案", "Select dataset Desc": "选择一个知识库存储预期答案",
"Send Message": "发送", "Send Message": "发送",
@ -529,9 +503,9 @@
"logs": { "logs": {
"api": "API 调用", "api": "API 调用",
"feishu": "飞书", "feishu": "飞书",
"free_login": "免登录链接",
"official_account": "公众号", "official_account": "公众号",
"online": "在线使用", "online": "在线使用",
"free_login": "免登录链接",
"share": "外部链接调用", "share": "外部链接调用",
"team": "团队空间对话", "team": "团队空间对话",
"test": "测试", "test": "测试",
@ -549,10 +523,8 @@
"response": { "response": {
"Complete Response": "完整响应", "Complete Response": "完整响应",
"Extension model": "问题优化模型", "Extension model": "问题优化模型",
"Plugin response detail": "插件详情",
"Read complete response": "查看详情", "Read complete response": "查看详情",
"Read complete response tips": "点击查看详细流程", "Read complete response tips": "点击查看详细流程",
"Tool call response detail": "工具运行详情",
"Tool call tokens": "工具调用 tokens 消耗", "Tool call tokens": "工具调用 tokens 消耗",
"context total length": "上下文总长度", "context total length": "上下文总长度",
"module cq": "问题分类列表", "module cq": "问题分类列表",
@ -589,14 +561,11 @@
} }
}, },
"dataset": { "dataset": {
"All Dataset": "全部知识库",
"Avatar": "知识库头像",
"Choose Dataset": "关联知识库", "Choose Dataset": "关联知识库",
"Collection": "数据集", "Collection": "数据集",
"Create dataset": "创建一个{{name}}", "Create dataset": "创建一个{{name}}",
"Dataset": "知识库", "Dataset": "知识库",
"Dataset ID": "知识库 ID", "Dataset ID": "知识库 ID",
"Dataset Type": "知识库类型",
"Delete Confirm": "确认删除该知识库?删除后数据无法恢复,请确认!", "Delete Confirm": "确认删除该知识库?删除后数据无法恢复,请确认!",
"Empty Dataset": "空数据集", "Empty Dataset": "空数据集",
"Empty Dataset Tips": "还没有知识库,快去创建一个吧!", "Empty Dataset Tips": "还没有知识库,快去创建一个吧!",
@ -605,7 +574,6 @@
"Intro Placeholder": "这个知识库还没有介绍~", "Intro Placeholder": "这个知识库还没有介绍~",
"Manual collection": "手动数据集", "Manual collection": "手动数据集",
"My Dataset": "我的知识库", "My Dataset": "我的知识库",
"Name": "知识库名称",
"Query extension intro": "开启问题优化功能,可以提高提高连续对话时,知识库搜索的精度。开启该功能后,在进行知识库搜索时,会根据对话记录,利用 AI 补全问题缺失的信息。", "Query extension intro": "开启问题优化功能,可以提高提高连续对话时,知识库搜索的精度。开启该功能后,在进行知识库搜索时,会根据对话记录,利用 AI 补全问题缺失的信息。",
"Quote Length": "引用内容长度", "Quote Length": "引用内容长度",
"Read Dataset": "查看知识库详情", "Read Dataset": "查看知识库详情",
@ -629,7 +597,6 @@
"Chunk Size": "分割大小", "Chunk Size": "分割大小",
"Createtime": "创建时间", "Createtime": "创建时间",
"Raw text length": "原文长度", "Raw text length": "原文长度",
"Read Metadata": "查看元数据",
"Training Type": "训练模式", "Training Type": "训练模式",
"Updatetime": "更新时间", "Updatetime": "更新时间",
"Web page selector": "网站选择器", "Web page selector": "网站选择器",
@ -664,7 +631,6 @@
"Search data placeholder": "搜索相关数据", "Search data placeholder": "搜索相关数据",
"Too Long": "总长度超长了", "Too Long": "总长度超长了",
"Total Amount": "{{total}} 组", "Total Amount": "{{total}} 组",
"empty_index": "无自定义索引",
"group": "组", "group": "组",
"unit": "条" "unit": "条"
}, },
@ -672,7 +638,6 @@
"error": { "error": {
"Data not found": "数据不存在或已被删除", "Data not found": "数据不存在或已被删除",
"Start Sync Failed": "开始同步失败", "Start Sync Failed": "开始同步失败",
"Template does not exist": "模板不存在",
"invalidVectorModelOrQAModel": "VectorModel 或 QA 模型错误", "invalidVectorModelOrQAModel": "VectorModel 或 QA 模型错误",
"unAuthDataset": "无权操作该知识库", "unAuthDataset": "无权操作该知识库",
"unAuthDatasetCollection": "无权操作该数据集", "unAuthDatasetCollection": "无权操作该数据集",
@ -813,7 +778,6 @@
"Add question type": "添加问题类型", "Add question type": "添加问题类型",
"Add_option": "添加选项", "Add_option": "添加选项",
"Can not connect self": "不能连接自身", "Can not connect self": "不能连接自身",
"Confirm Delete Node": "确认删除该节点?",
"Data Type": "数据类型", "Data Type": "数据类型",
"Dataset quote": { "Dataset quote": {
"label": "知识库引用", "label": "知识库引用",
@ -858,19 +822,15 @@
}, },
"http": { "http": {
"Add props": "添加参数", "Add props": "添加参数",
"Add props_and_tips": "添加参数,输入“/”唤起变量列表",
"AppId": "应用 ID", "AppId": "应用 ID",
"AppSecret": "AppSecret",
"ChatId": "当前对话 ID", "ChatId": "当前对话 ID",
"Current time": "当前时间", "Current time": "当前时间",
"Histories": "历史记录", "Histories": "历史记录",
"Key already exists": "Key 已经存在", "Key already exists": "Key 已经存在",
"Key cannot be empty": "参数名不能为空", "Key cannot be empty": "参数名不能为空",
"Props name": "参数名", "Props name": "参数名",
"Props name_and_tips": "参数名,输入”/“唤起变量列表",
"Props tip": "可以设置 HTTP 请求的相关参数\n可通过输入 / 来调用变量,当前可使用变量:\n{{variable}}", "Props tip": "可以设置 HTTP 请求的相关参数\n可通过输入 / 来调用变量,当前可使用变量:\n{{variable}}",
"Props value": "参数值", "Props value": "参数值",
"Props value_and_tips": "参数值,输入“/”唤起变量列表",
"ResponseChatItemId": "AI 回复的 ID", "ResponseChatItemId": "AI 回复的 ID",
"Url and params have been split": "路径参数已被自动加入 Params 中", "Url and params have been split": "路径参数已被自动加入 Params 中",
"curl import": "cURL 导入", "curl import": "cURL 导入",
@ -922,22 +882,20 @@
"Query extension": "问题优化", "Query extension": "问题优化",
"System Plugin": "系统插件", "System Plugin": "系统插件",
"System input module": "系统输入", "System input module": "系统输入",
"Team Plugin": "团队插件",
"Team app": "团队应用", "Team app": "团队应用",
"Tool module": "工具", "Tool module": "工具",
"UnKnow Module": "未知模块", "UnKnow Module": "未知模块",
"http body placeholder": "与 Apifox 相同的语法", "ai_chat": "AI 对话",
"empty_workflow": "空白工作流", "ai_chat_intro": "AI 大模型对话",
"empty_app": "空白应用", "config_params": "可以配置应用的系统参数",
"empty_plugin": "空白插件", "empty_plugin": "空白插件",
"system_config": "系统配置", "empty_workflow": "空白工作流",
"system_config_info": "可以配置应用的系统参数", "http body placeholder": "与 Apifox 相同的语法",
"work_start": "流程开始",
"self_input": "自定义插件输入", "self_input": "自定义插件输入",
"self_output": "自定义插件输出", "self_output": "自定义插件输出",
"config_params": "可以配置应用的系统参数", "system_config": "系统配置",
"ai_chat": "AI 对话", "system_config_info": "可以配置应用的系统参数",
"ai_chat_intro": "AI 大模型对话" "work_start": "流程开始"
}, },
"templates": { "templates": {
"Load plugin error": "加载插件失败" "Load plugin error": "加载插件失败"
@ -958,9 +916,7 @@
"variable option is value is required": "选项内容不能为空", "variable option is value is required": "选项内容不能为空",
"variable options": "选项" "variable options": "选项"
}, },
"variable add option": "添加选项", "variable add option": "添加选项"
"variable_update": "变量更新",
"variable_update_info": "可以更新指定节点的输出值或更新全局变量"
}, },
"plugin": { "plugin": {
"Custom headers": "自定义请求头", "Custom headers": "自定义请求头",
@ -1008,7 +964,6 @@
"Reference": "变量引用", "Reference": "变量引用",
"custom": "自定义变量", "custom": "自定义变量",
"dynamicTargetInput": "动态外部数据", "dynamicTargetInput": "动态外部数据",
"file_link": "文件上传",
"input": "单行输入框", "input": "单行输入框",
"number input": "数字输入框", "number input": "数字输入框",
"select": "单选框", "select": "单选框",
@ -1023,7 +978,6 @@
"OnRevert version confirm": "确认回退至该版本?会为您保存编辑中版本的配置,并为回退版本创建一个新的发布版本。", "OnRevert version confirm": "确认回退至该版本?会为您保存编辑中版本的配置,并为回退版本创建一个新的发布版本。",
"histories": "发布记录" "histories": "发布记录"
}, },
"run_test": "运行",
"template": { "template": {
"Interactive": "交互", "Interactive": "交互",
"Multimodal": "多模态", "Multimodal": "多模态",
@ -1067,21 +1021,14 @@
"Select One Collection To Store": "选择一个文件进行存储" "Select One Collection To Store": "选择一个文件进行存储"
}, },
"data": { "data": {
"Add Index": "新增自定义索引",
"Can not edit": "无编辑权限", "Can not edit": "无编辑权限",
"Custom Index Number": "自定义索引{{number}}", "Custom Index Number": "自定义索引{{number}}",
"Default Index": "默认索引", "Default Index": "默认索引",
"Delete Tip": "确认删除该条数据?", "Delete Tip": "确认删除该条数据?",
"Index Edit": "数据索引",
"Index Placeholder": "输入索引文本内容", "Index Placeholder": "输入索引文本内容",
"Input Data": "导入新数据",
"Input Success Tip": "导入数据成功", "Input Success Tip": "导入数据成功",
"Update Data": "更新数据",
"Update Success Tip": "更新数据成功", "Update Success Tip": "更新数据成功",
"edit": { "edit": {
"Content": "数据内容",
"Course": "说明文档",
"Delete": "删除数据",
"Index": "数据索引({{amount}})", "Index": "数据索引({{amount}})",
"divide_content": "分块内容" "divide_content": "分块内容"
}, },
@ -1093,19 +1040,15 @@
"noResult": "搜索结果为空" "noResult": "搜索结果为空"
} }
}, },
"default_reply": "默认回复",
"error": { "error": {
"Create failed": "创建失败", "Create failed": "创建失败",
"code_error": "验证码错误",
"fileNotFound": "文件找不到了~", "fileNotFound": "文件找不到了~",
"inheritPermissionError": "权限继承错误", "inheritPermissionError": "权限继承错误",
"missingParams": "参数缺失", "missingParams": "参数缺失",
"team": {
"overSize": "团队成员超出上限"
},
"upload_file_error_filename": "{{name}} 上传失败", "upload_file_error_filename": "{{name}} 上传失败",
"username_empty": "账号不能为空" "username_empty": "账号不能为空"
}, },
"error.code_error": "验证码错误",
"extraction_results": "提取结果", "extraction_results": "提取结果",
"field_name": "字段名", "field_name": "字段名",
"free": "免费", "free": "免费",
@ -1141,28 +1084,16 @@
}, },
"new_create": "新建", "new_create": "新建",
"no": "否", "no": "否",
"no_data": "暂无数据",
"no_laf_env": "系统未配置Laf环境", "no_laf_env": "系统未配置Laf环境",
"not_yet_introduced": "暂无介绍", "not_yet_introduced": "暂无介绍",
"option": "选项", "option": "选项",
"pay": { "pay": {
"amount": "金额", "amount": "金额",
"balance": "账号余额",
"balance_notice": "账号余额不足",
"confirm_pay": "确认支付",
"get_pay_QR": "获取充值二维码",
"need_pay": "需支付",
"need_to_pay": "实付",
"new_package_price": "新套餐价格",
"notice": "请勿关闭页面",
"old_package_price": "旧套餐余额",
"other": "其他金额,请取整数",
"package_tip": { "package_tip": {
"buy": "您购买的套餐等级低于当前套餐,该套餐将在当前套餐过期后生效。\n您可在账号—个人信息—套餐详情里查看套餐使用情况。", "buy": "您购买的套餐等级低于当前套餐,该套餐将在当前套餐过期后生效。\n您可在账号—个人信息—套餐详情里查看套餐使用情况。",
"renewal": "您正在续费套餐。您可在账号—个人信息—套餐详情里,查看套餐使用情况。", "renewal": "您正在续费套餐。您可在账号—个人信息—套餐详情里,查看套餐使用情况。",
"upgrade": "您购买的套餐等级高于当前套餐,该套餐将即刻生效,当前套餐将延后生效。您可在账号—个人信息—套餐详情里,查看套餐使用情况。" "upgrade": "您购买的套餐等级高于当前套餐,该套餐将即刻生效,当前套餐将延后生效。您可在账号—个人信息—套餐详情里,查看套餐使用情况。"
}, },
"to_recharge": "余额不足,去充值",
"wechat": "请微信扫码支付: {{price}}元\n请勿关闭页面", "wechat": "请微信扫码支付: {{price}}元\n请勿关闭页面",
"yuan": "{{amount}}元" "yuan": "{{amount}}元"
}, },
@ -1170,9 +1101,6 @@
"Collaborator": "协作者", "Collaborator": "协作者",
"Default permission": "默认权限", "Default permission": "默认权限",
"Manage": "管理", "Manage": "管理",
"manager": "管理员",
"read": "读权限",
"write": "写权限",
"No InheritPermission": "已限制权限,不再继承父级文件夹的权限,", "No InheritPermission": "已限制权限,不再继承父级文件夹的权限,",
"Not collaborator": "暂无协作者", "Not collaborator": "暂无协作者",
"Owner": "创建者", "Owner": "创建者",
@ -1191,7 +1119,10 @@
"change_owner_placeholder": "输入用户名查找账号", "change_owner_placeholder": "输入用户名查找账号",
"change_owner_success": "成功转移所有权", "change_owner_success": "成功转移所有权",
"change_owner_tip": "转移后您的权限不会保留", "change_owner_tip": "转移后您的权限不会保留",
"change_owner_to": "转移给" "change_owner_to": "转移给",
"manager": "管理员",
"read": "读权限",
"write": "写权限"
}, },
"plugin": { "plugin": {
"App": "选择应用", "App": "选择应用",
@ -1217,7 +1148,6 @@
"go to laf": "去编写", "go to laf": "去编写",
"path": "路径" "path": "路径"
}, },
"reply_now": "立即回复",
"required": "必须", "required": "必须",
"resume_failed": "恢复失败", "resume_failed": "恢复失败",
"select_reference_variable": "选择引用变量", "select_reference_variable": "选择引用变量",
@ -1251,8 +1181,6 @@
}, },
"standard": { "standard": {
"AI Bonus Points": "AI 积分", "AI Bonus Points": "AI 积分",
"Expired Time": "结束时间",
"Start Time": "开始时间",
"due_date": "到期时间", "due_date": "到期时间",
"storage": "存储量", "storage": "存储量",
"type": "类型" "type": "类型"
@ -1278,22 +1206,14 @@
"System message": "系统消息" "System message": "系统消息"
}, },
"login": { "login": {
"And": "和",
"Email": "邮箱", "Email": "邮箱",
"Forget Password": "忘记密码?",
"Github": "GitHub 登录", "Github": "GitHub 登录",
"Google": "Google 登录", "Google": "Google 登录",
"Password": "密码", "Password": "密码",
"Password login": "密码登录", "Password login": "密码登录",
"Phone": "手机号登录", "Phone": "手机号登录",
"Phone number": "手机号", "Phone number": "手机号",
"Policy tip": "使用即代表你同意我们的",
"Privacy": "隐私政策",
"Provider error": "登录异常,请重试", "Provider error": "登录异常,请重试",
"Register": "注册账号",
"Root login": "使用 root 用户登录",
"Root password placeholder": "root 密码为你设置的环境变量",
"Terms": "服务协议",
"Username": "用户名", "Username": "用户名",
"Wechat": "微信登录", "Wechat": "微信登录",
"can_not_login": "无法登录,点击联系", "can_not_login": "无法登录,点击联系",
@ -1313,12 +1233,9 @@
"wallet": { "wallet": {
"Ai point every thousand tokens": "{{points}} 积分/1K tokens", "Ai point every thousand tokens": "{{points}} 积分/1K tokens",
"Amount": "金额", "Amount": "金额",
"Bills": "账单与开票",
"Buy": "购买", "Buy": "购买",
"Confirm pay": "支付确认",
"Not sufficient": "您的 AI 积分不足,请先升级套餐或购买额外 AI 积分后继续使用。", "Not sufficient": "您的 AI 积分不足,请先升级套餐或购买额外 AI 积分后继续使用。",
"Plan expired time": "套餐到期时间", "Plan expired time": "套餐到期时间",
"Plan reset time": "套餐重置时间",
"Standard Plan Detail": "套餐详情", "Standard Plan Detail": "套餐详情",
"To read plan": "查看套餐", "To read plan": "查看套餐",
"amount_0": "购买数量不能为0", "amount_0": "购买数量不能为0",
@ -1355,7 +1272,6 @@
"company_address": "公司地址", "company_address": "公司地址",
"company_phone": "公司电话", "company_phone": "公司电话",
"email": "邮箱地址", "email": "邮箱地址",
"in_valid": "存在空字段或邮箱格式错误",
"need_special_invoice": "是否需要专票", "need_special_invoice": "是否需要专票",
"organization_name": "组织名称", "organization_name": "组织名称",
"unit_code": "统一信用代码" "unit_code": "统一信用代码"
@ -1375,7 +1291,6 @@
"AI points usage": "AI 积分使用量", "AI points usage": "AI 积分使用量",
"AI points usage tip": "每次调用 AI 模型时,都会消耗一定的 AI 积分。具体的计算标准可参考上方的“计费标准”", "AI points usage tip": "每次调用 AI 模型时,都会消耗一定的 AI 积分。具体的计算标准可参考上方的“计费标准”",
"Ai points": "AI 积分计算标准", "Ai points": "AI 积分计算标准",
"Buy now": "切换套餐",
"Current plan": "当前套餐", "Current plan": "当前套餐",
"Extra ai points": "额外 AI 积分", "Extra ai points": "额外 AI 积分",
"Extra dataset size": "额外知识库容量", "Extra dataset size": "额外知识库容量",
@ -1384,10 +1299,7 @@
"FAQ": "常见问题", "FAQ": "常见问题",
"Month amount": "月数", "Month amount": "月数",
"Next plan": "未来套餐", "Next plan": "未来套餐",
"Nonsupport": "无需购买",
"Stand plan level": "订阅套餐", "Stand plan level": "订阅套餐",
"Standard update fail": "修改订阅套餐异常",
"Standard update success": "变更订阅套餐成功!",
"Sub plan": "订阅套餐", "Sub plan": "订阅套餐",
"Sub plan tip": "免费使用 {{title}} 或升级更高的套餐", "Sub plan tip": "免费使用 {{title}} 或升级更高的套餐",
"Team plan and usage": "套餐与用量", "Team plan and usage": "套餐与用量",
@ -1453,8 +1365,7 @@
"Total points": "AI 积分消耗", "Total points": "AI 积分消耗",
"Usage Detail": "使用详情", "Usage Detail": "使用详情",
"Whisper": "语音输入" "Whisper": "语音输入"
}, }
"use_default": "使用默认抬头"
} }
}, },
"sync_link": "同步链接", "sync_link": "同步链接",
@ -1491,28 +1402,23 @@
"Laf Account Setting": "laf 账号配置", "Laf Account Setting": "laf 账号配置",
"Language": "语言", "Language": "语言",
"Member Name": "昵称", "Member Name": "昵称",
"Notice": "通知",
"Notification Receive": "通知接收", "Notification Receive": "通知接收",
"Notification Receive Bind": "请先绑定通知接收途径", "Notification Receive Bind": "请先绑定通知接收途径",
"Old password is error": "旧密码错误", "Old password is error": "旧密码错误",
"OpenAI Account Setting": "OpenAI 账号配置", "OpenAI Account Setting": "OpenAI 账号配置",
"Password": "密码", "Password": "密码",
"Pay": "充值", "Pay": "充值",
"Personal Information": "个人信息",
"Promotion": "促销", "Promotion": "促销",
"Promotion Rate": "返现比例", "Promotion Rate": "返现比例",
"Promotion Record": "推广记录",
"Promotion rate tip": "好友充值时你将获得一定比例的余额奖励", "Promotion rate tip": "好友充值时你将获得一定比例的余额奖励",
"Replace": "更换", "Replace": "更换",
"Set OpenAI Account Failed": "设置 OpenAI 账号异常", "Set OpenAI Account Failed": "设置 OpenAI 账号异常",
"Sign Out": "登出",
"Team": "团队", "Team": "团队",
"Time": "时间", "Time": "时间",
"Timezone": "时区", "Timezone": "时区",
"Update Password": "修改密码", "Update Password": "修改密码",
"Update password failed": "修改密码异常", "Update password failed": "修改密码异常",
"Update password successful": "修改密码成功", "Update password successful": "修改密码成功",
"Usage Record": "使用记录",
"apikey": { "apikey": {
"key": "API 密钥" "key": "API 密钥"
}, },
@ -1567,8 +1473,7 @@
}, },
"role": { "role": {
"Admin": "管理员", "Admin": "管理员",
"Owner": "创建者", "Owner": "创建者"
"Visitor": "访客"
} }
}, },
"type": "类型" "type": "类型"

View File

@ -1,7 +1,5 @@
{ {
"Disabled": "已禁用",
"Enable": "启用", "Enable": "启用",
"Enabled": "已启用",
"collection": { "collection": {
"Create update time": "创建/更新时间", "Create update time": "创建/更新时间",
"Training type": "训练模式" "Training type": "训练模式"

View File

@ -0,0 +1,13 @@
{
"Login": "登录",
"forget_password": "忘记密码?",
"login_failed": "登录异常",
"login_success": "登录成功",
"password_condition": "密码最多 60 位",
"policy_tip": "使用即代表你同意我们的",
"privacy": "隐私协议",
"register": "注册账号",
"root_password_placeholder": "root 用户密码为环境变量 DEFAULT_ROOT_PSW 的值",
"terms": "服务协议",
"use_root_login": "使用 root 用户登录"
}

View File

@ -4,20 +4,17 @@
"copy_link_hint": "将下面链接复制到指定位置", "copy_link_hint": "将下面链接复制到指定位置",
"create_api_key": "创建新 key", "create_api_key": "创建新 key",
"create_link": "创建链接", "create_link": "创建链接",
"default_response": "默认回复",
"edit_api_key": "编辑 key 信息", "edit_api_key": "编辑 key 信息",
"edit_feishu_bot": "编辑飞书机器人", "edit_feishu_bot": "编辑飞书机器人",
"edit_link": "编辑", "edit_link": "编辑",
"feishu_api": "飞书接口", "feishu_api": "飞书接口",
"feishu_bot": "飞书机器人", "feishu_bot": "飞书机器人",
"feishu_bot_desc": "通过 API 直接接入飞书机器人", "feishu_bot_desc": "通过 API 直接接入飞书机器人",
"feishu_name": "飞书",
"key_alias": "key 的别名,仅用于展示", "key_alias": "key 的别名,仅用于展示",
"key_tips": "你可以使用 API 密钥访问一些特定的接口(无法访问应用,访问应用需使用应用内的 API key", "key_tips": "你可以使用 API 密钥访问一些特定的接口(无法访问应用,访问应用需使用应用内的 API key",
"link_name": "分享链接的名字", "link_name": "分享链接的名字",
"new_feishu_bot": "新增飞书机器人", "new_feishu_bot": "新增飞书机器人",
"official_account": { "official_account": {
"api": "微信公众号 API",
"create_modal_title": "创建微信公众号接入", "create_modal_title": "创建微信公众号接入",
"desc": "通过 API 直接接入微信公众号", "desc": "通过 API 直接接入微信公众号",
"edit_modal_title": "编辑微信公众号接入", "edit_modal_title": "编辑微信公众号接入",

View File

@ -2,13 +2,14 @@
"bill": { "bill": {
"balance": "余额", "balance": "余额",
"buy_plan": "购买套餐", "buy_plan": "购买套餐",
"buy_standard_plan_success": "购买套餐成功",
"contact_customer_service": "联系客服", "contact_customer_service": "联系客服",
"conversion": "兑换", "conversion": "兑换",
"convert_error": "兑换失败", "convert_error": "兑换失败",
"convert_success": "兑换成功", "convert_success": "兑换成功",
"current_token_price": "当前积分价格",
"not_need_invoice": "余额支付,无法开票", "not_need_invoice": "余额支付,无法开票",
"price": "价格", "price": "价格",
"renew_plan": "续费套餐",
"standard_valid_tip": "套餐使用规则:系统优先使用更高级的套餐,原未用完的套餐将延后生效", "standard_valid_tip": "套餐使用规则:系统优先使用更高级的套餐,原未用完的套餐将延后生效",
"token_expire_1year": "积分有效期一年", "token_expire_1year": "积分有效期一年",
"tokens": "积分", "tokens": "积分",
@ -16,14 +17,9 @@
"use_balance_hint": "由于系统升级,原“自动续费从余额扣款”模式取消,余额充值入口关闭。您的余额可用于购买积分", "use_balance_hint": "由于系统升级,原“自动续费从余额扣款”模式取消,余额充值入口关闭。您的余额可用于购买积分",
"valid_time": "生效时间", "valid_time": "生效时间",
"you_can_convert": "您可兑换", "you_can_convert": "您可兑换",
"renew_plan": "续费套餐",
"current_token_price": "当前积分价格",
"yuan": "元" "yuan": "元"
}, },
"promotion": { "bill_and_invoices": "账单 & 发票",
"register": "好友注册",
"pay": "好友充值"
},
"bind_inform_account_error": "绑定通知账号异常", "bind_inform_account_error": "绑定通知账号异常",
"bind_inform_account_success": "绑定通知账号成功", "bind_inform_account_success": "绑定通知账号成功",
"delete": { "delete": {
@ -31,28 +27,24 @@
"admin_success": "删除管理员成功" "admin_success": "删除管理员成功"
}, },
"has_chosen": "已选择", "has_chosen": "已选择",
"individuation": "个性化",
"login": { "login": {
"error": "登录异常", "error": "登录异常",
"failed": "登录失败",
"login_account": "登录 {{account}} 账号",
"login_error": "用户名或密码错误",
"password_condition": "密码最多 60 位", "password_condition": "密码最多 60 位",
"success": "登录成功", "success": "登录成功"
"to_register": "没有账号,去注册"
}, },
"name": "名称", "name": "名称",
"notice": "通知",
"notification": { "notification": {
"Bind Notification Pipe Hint": "请绑定通知接收账号,以确保您能正常接收套餐过期提醒等通知,保障您的服务正常运行。", "Bind Notification Pipe Hint": "请绑定通知接收账号,以确保您能正常接收套餐过期提醒等通知,保障您的服务正常运行。",
"remind_owner_bind": "请提醒创建者绑定通知账号" "remind_owner_bind": "请提醒创建者绑定通知账号"
}, },
"operations": "操作", "operations": "操作",
"password": { "password": {
"change_error": "修改密码异常",
"code_required": "验证码不能为空", "code_required": "验证码不能为空",
"code_send_error": "验证码发送异常", "code_send_error": "验证码发送异常",
"code_sended": "验证码已发送", "code_sended": "验证码已发送",
"confirm": "确认密码", "confirm": "确认密码",
"email_phone": "邮箱/手机号",
"email_phone_error": "邮箱/手机号格式错误", "email_phone_error": "邮箱/手机号格式错误",
"email_phone_void": "邮箱/手机号不能为空", "email_phone_void": "邮箱/手机号不能为空",
"get_code": "获取验证码", "get_code": "获取验证码",
@ -78,16 +70,23 @@
"team_read": "团队可访问", "team_read": "团队可访问",
"team_write": "团队可编辑" "team_write": "团队可编辑"
}, },
"permission_des": {
"manage": "可创建资源、邀请、删除成员",
"read": "成员仅可阅读相关资源,无法新建资源",
"write": "除了可读资源外,还可以新建新的资源"
},
"permissions": "权限", "permissions": "权限",
"personal_information": "个人信息",
"personalization": "个性化",
"promotion_records": "推广记录",
"register": { "register": {
"confirm": "确认注册", "confirm": "确认注册",
"error": "注册异常",
"failed": "注册失败",
"register_account": "注册 {{account}} 账号", "register_account": "注册 {{account}} 账号",
"success": "注册成功", "success": "注册成功",
"to_login": "已有账号,去登录" "to_login": "已有账号,去登录"
}, },
"search_user": "搜索用户名", "search_user": "搜索用户名",
"sign_out": "登出",
"synchronization": { "synchronization": {
"button": "立即同步", "button": "立即同步",
"placeholder": "请输入同步标签", "placeholder": "请输入同步标签",
@ -105,9 +104,5 @@
"share": "分享链接", "share": "分享链接",
"wecom": "企业微信" "wecom": "企业微信"
}, },
"permission_des": { "usage_record": "使用记录"
"read": "成员仅可阅读相关资源,无法新建资源",
"write": "除了可读资源外,还可以新建新的资源",
"manage": "可创建资源、邀请、删除成员"
}
} }

View File

@ -1,11 +1,4 @@
{ {
" i18nT('workflow": {
"use_user_id'),\n required": {
"workflow": {
"use_user_id": "使用者 ID"
}
}
},
"Code": "代码", "Code": "代码",
"about_xxx_question": "关于 xxx 的问题", "about_xxx_question": "关于 xxx 的问题",
"add_new_input": "新增输入", "add_new_input": "新增输入",
@ -122,15 +115,12 @@
"Custom outputs": "自定义输出", "Custom outputs": "自定义输出",
"Error": "错误信息", "Error": "错误信息",
"Read file result": "文档解析结果预览", "Read file result": "文档解析结果预览",
"User_select_description": "说明文字",
"User_select_result": "选择的结果",
"read files": "解析的文档" "read files": "解析的文档"
}, },
"select_an_application": "选择一个应用", "select_an_application": "选择一个应用",
"select_another_application_to_call": "可以选择一个其他应用进行调用", "select_another_application_to_call": "可以选择一个其他应用进行调用",
"special_array_format": "特殊数组格式,搜索结果为空时,返回空数组。", "special_array_format": "特殊数组格式,搜索结果为空时,返回空数组。",
"start_with": "开始为", "start_with": "开始为",
"system_variables": "系统变量",
"target_fields_description": "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段", "target_fields_description": "由 '描述' 和 'key' 组成一个目标字段,可提取多个目标字段",
"template": { "template": {
"ai_chat": "AI 对话", "ai_chat": "AI 对话",
@ -156,9 +146,7 @@
"variable_picker_tips": "可输入节点名或变量名搜索", "variable_picker_tips": "可输入节点名或变量名搜索",
"variable_update": "变量更新", "variable_update": "变量更新",
"workflow": { "workflow": {
"Back_to_current_version": "回到初始状态",
"My edit": "我的编辑", "My edit": "我的编辑",
"Switch_failed": "切换失败",
"Switch_success": "切换成功", "Switch_success": "切换成功",
"Team cloud": "团队云端", "Team cloud": "团队云端",
"exit_tips": "您的更改尚未保存,「直接退出」将不会保存您的编辑记录。" "exit_tips": "您的更改尚未保存,「直接退出」将不会保存您的编辑记录。"

View File

@ -21,21 +21,23 @@
"ahooks": "^3.7.11", "ahooks": "^3.7.11",
"date-fns": "2.30.0", "date-fns": "2.30.0",
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"i18next": "23.11.5",
"js-cookie": "^3.0.5",
"lexical": "0.12.6", "lexical": "0.12.6",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"i18next": "23.11.5",
"next-i18next": "15.3.0", "next-i18next": "15.3.0",
"react-i18next": "14.1.2",
"papaparse": "^5.4.1", "papaparse": "^5.4.1",
"react": "18.3.1", "react": "18.3.1",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
"react-day-picker": "^8.7.1", "react-day-picker": "^8.7.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-hook-form": "7.43.1", "react-hook-form": "7.43.1",
"react-i18next": "14.1.2",
"react-photo-view": "^1.2.6", "react-photo-view": "^1.2.6",
"use-context-selector": "^1.4.4" "use-context-selector": "^1.4.4"
}, },
"devDependencies": { "devDependencies": {
"@types/js-cookie": "^3.0.5",
"@types/lodash": "^4.14.191", "@types/lodash": "^4.14.191",
"@types/papaparse": "^5.3.7", "@types/papaparse": "^5.3.7",
"@types/react": "18.3.1", "@types/react": "18.3.1",

View File

@ -7,6 +7,7 @@ import publish from '../i18n/zh/publish.json';
import workflow from '../i18n/zh/workflow.json'; import workflow from '../i18n/zh/workflow.json';
import user from '../i18n/zh/user.json'; import user from '../i18n/zh/user.json';
import chat from '../i18n/zh/chat.json'; import chat from '../i18n/zh/chat.json';
import login from '../i18n/zh/login.json';
export interface I18nNamespaces { export interface I18nNamespaces {
common: typeof common; common: typeof common;
@ -17,18 +18,11 @@ export interface I18nNamespaces {
workflow: typeof workflow; workflow: typeof workflow;
user: typeof user; user: typeof user;
chat: typeof chat; chat: typeof chat;
login: typeof login;
} }
export type I18nNsType = (keyof I18nNamespaces)[]; export type I18nNsType = (keyof I18nNamespaces)[];
export type I18nCommonKey = NestedKeyOf<I18nNamespaces['common']>;
export type I18nDataSetKey = NestedKeyOf<I18nNamespaces['dataset']>;
export type I18nAppKey = NestedKeyOf<I18nNamespaces['app']>;
export type I18nPublishKey = NestedKeyOf<I18nNamespaces['publish']>;
export type I18nWorkflowKey = NestedKeyOf<I18nNamespaces['workflow']>;
export type I18nUserKey = NestedKeyOf<I18nNamespaces['user']>;
export type I18nChatKey = NestedKeyOf<I18nNamespaces['chat']>;
export type NestedKeyOf<ObjectType extends object> = { export type NestedKeyOf<ObjectType extends object> = {
[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object [Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object
? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}` ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}`
@ -46,7 +40,7 @@ export type I18nKeyFunction = {
declare module 'i18next' { declare module 'i18next' {
interface CustomTypeOptions { interface CustomTypeOptions {
returnNull: false; returnNull: false;
defaultNS: ['common', 'dataset', 'app', 'file', 'publish', 'workflow', 'user', 'chat']; defaultNS: ['common', 'dataset', 'app', 'file', 'publish', 'workflow', 'user', 'chat', 'login'];
resources: I18nNamespaces; resources: I18nNamespaces;
} }
} }

29
pnpm-lock.yaml generated
View File

@ -22,7 +22,7 @@ importers:
version: 13.3.0 version: 13.3.0
next-i18next: next-i18next:
specifier: 15.3.0 specifier: 15.3.0
version: 15.3.0(i18next@23.11.5)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) version: 15.3.0(i18next@23.11.5)(next@14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
prettier: prettier:
specifier: 3.2.4 specifier: 3.2.4
version: 3.2.4 version: 3.2.4
@ -250,7 +250,7 @@ importers:
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1) version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@chakra-ui/next-js': '@chakra-ui/next-js':
specifier: 2.1.5 specifier: 2.1.5
version: 2.1.5(@chakra-ui/react@2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react@18.3.1) version: 2.1.5(@chakra-ui/react@2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react@18.3.1)
'@chakra-ui/react': '@chakra-ui/react':
specifier: 2.8.1 specifier: 2.8.1
version: 2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -302,6 +302,9 @@ importers:
i18next: i18next:
specifier: 23.11.5 specifier: 23.11.5
version: 23.11.5 version: 23.11.5
js-cookie:
specifier: ^3.0.5
version: 3.0.5
lexical: lexical:
specifier: 0.12.6 specifier: 0.12.6
version: 0.12.6 version: 0.12.6
@ -310,7 +313,7 @@ importers:
version: 4.17.21 version: 4.17.21
next-i18next: next-i18next:
specifier: 15.3.0 specifier: 15.3.0
version: 15.3.0(i18next@23.11.5)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) version: 15.3.0(i18next@23.11.5)(next@14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
papaparse: papaparse:
specifier: ^5.4.1 specifier: ^5.4.1
version: 5.4.1 version: 5.4.1
@ -339,6 +342,9 @@ importers:
specifier: ^1.4.4 specifier: ^1.4.4
version: 1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2) version: 1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2)
devDependencies: devDependencies:
'@types/js-cookie':
specifier: ^3.0.5
version: 3.0.6
'@types/lodash': '@types/lodash':
specifier: ^4.14.191 specifier: ^4.14.191
version: 4.17.7 version: 4.17.7
@ -368,7 +374,7 @@ importers:
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1) version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@chakra-ui/next-js': '@chakra-ui/next-js':
specifier: 2.1.5 specifier: 2.1.5
version: 2.1.5(@chakra-ui/react@2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react@18.3.1) version: 2.1.5(@chakra-ui/react@2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react@18.3.1)
'@chakra-ui/react': '@chakra-ui/react':
specifier: 2.8.1 specifier: 2.8.1
version: 2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -464,7 +470,7 @@ importers:
version: 14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) version: 14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8)
next-i18next: next-i18next:
specifier: 15.3.0 specifier: 15.3.0
version: 15.3.0(i18next@23.11.5)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) version: 15.3.0(i18next@23.11.5)(next@14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
nextjs-node-loader: nextjs-node-loader:
specifier: ^1.1.5 specifier: ^1.1.5
version: 1.1.5(webpack@5.92.1) version: 1.1.5(webpack@5.92.1)
@ -529,9 +535,6 @@ importers:
'@types/formidable': '@types/formidable':
specifier: ^2.0.5 specifier: ^2.0.5
version: 2.0.6 version: 2.0.6
'@types/js-cookie':
specifier: ^3.0.3
version: 3.0.6
'@types/js-yaml': '@types/js-yaml':
specifier: ^4.0.9 specifier: ^4.0.9
version: 4.0.9 version: 4.0.9
@ -6015,6 +6018,10 @@ packages:
js-cookie@2.2.1: js-cookie@2.2.1:
resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==}
js-cookie@3.0.5:
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
engines: {node: '>=14'}
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -10024,7 +10031,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
'@chakra-ui/next-js@2.1.5(@chakra-ui/react@2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react@18.3.1)': '@chakra-ui/next-js@2.1.5(@chakra-ui/react@2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react@18.3.1)':
dependencies: dependencies:
'@chakra-ui/react': 2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@chakra-ui/react': 2.8.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@emotion/cache': 11.11.0 '@emotion/cache': 11.11.0
@ -15529,6 +15536,8 @@ snapshots:
js-cookie@2.2.1: {} js-cookie@2.2.1: {}
js-cookie@3.0.5: {}
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
js-tokens@9.0.0: {} js-tokens@9.0.0: {}
@ -16625,7 +16634,7 @@ snapshots:
neo-async@2.6.2: {} neo-async@2.6.2: {}
next-i18next@15.3.0(i18next@23.11.5)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): next-i18next@15.3.0(i18next@23.11.5)(next@14.2.5(@babel/core@7.24.9)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
dependencies: dependencies:
'@babel/runtime': 7.24.8 '@babel/runtime': 7.24.8
'@types/hoist-non-react-statics': 3.3.5 '@types/hoist-non-react-statics': 3.3.5

View File

@ -5,11 +5,11 @@
module.exports = { module.exports = {
i18n: { i18n: {
defaultLocale: 'zh', defaultLocale: 'en',
locales: ['en', 'zh'], locales: ['en', 'zh'],
localeDetection: false localeDetection: false
}, },
localePath: localePath:
typeof window === 'undefined' ? require('path').resolve('../../packages/web/i18n') : '/i18n', typeof window === 'undefined' ? require('path').resolve('../../packages/web/i18n') : '/i18n',
reloadOnPrerender: process.env.NODE_ENV === 'development' reloadOnPrerender: process.env.NODE_ENV === 'development'
} };

View File

@ -68,7 +68,6 @@
"devDependencies": { "devDependencies": {
"@svgr/webpack": "^6.5.1", "@svgr/webpack": "^6.5.1",
"@types/formidable": "^2.0.5", "@types/formidable": "^2.0.5",
"@types/js-cookie": "^3.0.3",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/jsonwebtoken": "^9.0.3", "@types/jsonwebtoken": "^9.0.3",
"@types/lodash": "^4.14.191", "@types/lodash": "^4.14.191",

View File

@ -7,9 +7,11 @@ import { useQuery } from '@tanstack/react-query';
import { useUserStore } from '@/web/support/user/useUserStore'; import { useUserStore } from '@/web/support/user/useUserStore';
import { getUnreadCount } from '@/web/support/user/inform/api'; import { getUnreadCount } from '@/web/support/user/inform/api';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { useI18nLng } from '@fastgpt/web/hooks/useI18n';
import Auth from './auth'; import Auth from './auth';
import { useSystem } from '@fastgpt/web/hooks/useSystem'; import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { useMount } from 'ahooks';
const Navbar = dynamic(() => import('./navbar')); const Navbar = dynamic(() => import('./navbar'));
const NavbarPhone = dynamic(() => import('./navbarPhone')); const NavbarPhone = dynamic(() => import('./navbarPhone'));
const UpdateInviteModal = dynamic(() => import('@/components/support/user/team/UpdateInviteModal')); const UpdateInviteModal = dynamic(() => import('@/components/support/user/team/UpdateInviteModal'));
@ -46,6 +48,7 @@ const Layout = ({ children }: { children: JSX.Element }) => {
const { loading, feConfigs, isNotSufficientModal } = useSystemStore(); const { loading, feConfigs, isNotSufficientModal } = useSystemStore();
const { isPc } = useSystem(); const { isPc } = useSystem();
const { userInfo } = useUserStore(); const { userInfo } = useUserStore();
const { setUserDefaultLng } = useI18nLng();
const isChatPage = useMemo( const isChatPage = useMemo(
() => router.pathname === '/chat' && Object.values(router.query).join('').length !== 0, () => router.pathname === '/chat' && Object.values(router.query).join('').length !== 0,
@ -61,6 +64,10 @@ const Layout = ({ children }: { children: JSX.Element }) => {
const isHideNavbar = !!pcUnShowLayoutRoute[router.pathname]; const isHideNavbar = !!pcUnShowLayoutRoute[router.pathname];
useMount(() => {
setUserDefaultLng();
});
return ( return (
<> <>
<Box h={'100%'} bg={'myGray.100'}> <Box h={'100%'} bg={'myGray.100'}>

View File

@ -37,7 +37,7 @@ const SendCodeAuthModal = ({
<Skeleton <Skeleton
minH="200px" minH="200px"
isLoaded={!loading} isLoaded={!loading}
fadeDuration={2} fadeDuration={1}
display={'flex'} display={'flex'}
justifyContent={'center'} justifyContent={'center'}
my={1} my={1}

View File

@ -15,6 +15,7 @@ import NextHead from '@/components/common/NextHead';
function App({ Component, pageProps }: AppProps) { function App({ Component, pageProps }: AppProps) {
const { feConfigs, scripts, title } = useInitApp(); const { feConfigs, scripts, title } = useInitApp();
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<> <>
<NextHead <NextHead

View File

@ -7,8 +7,10 @@ import { UserType } from '@fastgpt/global/support/user/type';
import { useToast } from '@fastgpt/web/hooks/useToast'; import { useToast } from '@fastgpt/web/hooks/useToast';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { UserUpdateParams } from '@/types/user'; import { UserUpdateParams } from '@/types/user';
import { langMap, setLngStore } from '@/web/common/utils/i18n'; import { langMap } from '@/web/common/utils/i18n';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useI18nLng } from '@fastgpt/web/hooks/useI18n';
import MySelect from '@fastgpt/web/components/common/MySelect'; import MySelect from '@fastgpt/web/components/common/MySelect';
import TimezoneSelect from '@fastgpt/web/components/common/MySelect/TimezoneSelect'; import TimezoneSelect from '@fastgpt/web/components/common/MySelect/TimezoneSelect';
@ -16,7 +18,7 @@ const Individuation = () => {
const { t, i18n } = useTranslation(); const { t, i18n } = useTranslation();
const { userInfo, updateUserInfo } = useUserStore(); const { userInfo, updateUserInfo } = useUserStore();
const { toast } = useToast(); const { toast } = useToast();
const router = useRouter(); const { onChangeLng } = useI18nLng();
const { reset } = useForm<UserUpdateParams>({ const { reset } = useForm<UserUpdateParams>({
defaultValues: userInfo as UserType defaultValues: userInfo as UserType
@ -55,14 +57,7 @@ const Individuation = () => {
}))} }))}
onchange={(val: any) => { onchange={(val: any) => {
const lang = val; const lang = val;
setLngStore(lang); onChangeLng(lang);
router.replace(
{
query: router.query
},
router.asPath,
{ locale: lang }
);
}} }}
/> />
</Box> </Box>

View File

@ -40,14 +40,14 @@ const Account = ({ currentTab }: { currentTab: TabEnum }) => {
const tabList = [ const tabList = [
{ {
icon: 'support/user/userLight', icon: 'support/user/userLight',
label: t('common:user.Personal Information'), label: t('user:personal_information'),
value: TabEnum.info value: TabEnum.info
}, },
...(feConfigs?.isPlus ...(feConfigs?.isPlus
? [ ? [
{ {
icon: 'support/usage/usageRecordLight', icon: 'support/usage/usageRecordLight',
label: t('common:user.Usage Record'), label: t('user:usage_record'),
value: TabEnum.usage value: TabEnum.usage
} }
] ]
@ -57,7 +57,7 @@ const Account = ({ currentTab }: { currentTab: TabEnum }) => {
? [ ? [
{ {
icon: 'support/bill/payRecordLight', icon: 'support/bill/payRecordLight',
label: t('common:support.wallet.Bills'), label: t('user:bill_and_invoices'),
value: TabEnum.bill value: TabEnum.bill
} }
] ]
@ -67,7 +67,7 @@ const Account = ({ currentTab }: { currentTab: TabEnum }) => {
? [ ? [
{ {
icon: 'support/account/promotionLight', icon: 'support/account/promotionLight',
label: t('common:user.Promotion Record'), label: t('user:promotion_records'),
value: TabEnum.promotion value: TabEnum.promotion
} }
] ]
@ -83,14 +83,14 @@ const Account = ({ currentTab }: { currentTab: TabEnum }) => {
: []), : []),
{ {
icon: 'support/user/individuation', icon: 'support/user/individuation',
label: t('common:support.account.Individuation'), label: t('user:personalization'),
value: TabEnum.individuation value: TabEnum.individuation
}, },
...(feConfigs.isPlus ...(feConfigs.isPlus
? [ ? [
{ {
icon: 'support/user/informLight', icon: 'support/user/informLight',
label: t('common:user.Notice'), label: t('user:notice'),
value: TabEnum.inform value: TabEnum.inform
} }
] ]
@ -98,7 +98,7 @@ const Account = ({ currentTab }: { currentTab: TabEnum }) => {
{ {
icon: 'support/account/loginoutLight', icon: 'support/account/loginoutLight',
label: t('common:user.Sign Out'), label: t('user:sign_out'),
value: TabEnum.loginout value: TabEnum.loginout
} }
]; ];

View File

@ -125,9 +125,14 @@ const Header = () => {
try { try {
localStorage.removeItem(`${appDetail._id}-past`); localStorage.removeItem(`${appDetail._id}-past`);
localStorage.removeItem(`${appDetail._id}-future`); localStorage.removeItem(`${appDetail._id}-future`);
router.back(); router.push({
pathname: '/app/list',
query: {
parentId: appDetail.parentId
}
});
} catch (error) {} } catch (error) {}
}, [appDetail._id, router]); }, [appDetail._id, appDetail.parentId, router]);
const Render = useMemo(() => { const Render = useMemo(() => {
return ( return (

View File

@ -125,9 +125,14 @@ const Header = () => {
try { try {
localStorage.removeItem(`${appDetail._id}-past`); localStorage.removeItem(`${appDetail._id}-past`);
localStorage.removeItem(`${appDetail._id}-future`); localStorage.removeItem(`${appDetail._id}-future`);
router.back(); router.push({
pathname: '/app/list',
query: {
parentId: appDetail.parentId
}
});
} catch (error) {} } catch (error) {}
}, [appDetail._id, router]); }, [appDetail._id, appDetail.parentId, router]);
const Render = useMemo(() => { const Render = useMemo(() => {
return ( return (

View File

@ -272,7 +272,7 @@ function List() {
{owner && ( {owner && (
<HStack spacing={1}> <HStack spacing={1}>
<Avatar src={owner.avatar} w={'0.875rem'} borderRadius={'50%'} /> <Avatar src={owner.avatar} w={'0.875rem'} borderRadius={'50%'} />
<Box maxW={'150px'} className="textEllipsis"> <Box maxW={'150px'} className="textEllipsis" fontSize={'mini'}>
{owner.memberName} {owner.memberName}
</Box> </Box>
</HStack> </HStack>
@ -288,7 +288,9 @@ function List() {
{isPc && ( {isPc && (
<HStack spacing={1} className="time"> <HStack spacing={1} className="time">
<MyIcon name={'history'} w={'0.85rem'} color={'myGray.400'} /> <MyIcon name={'history'} w={'0.85rem'} color={'myGray.400'} />
<Box color={'myGray.500'}>{formatTimeToChatTime(dataset.updateTime)}</Box> <Box color={'myGray.500'} fontSize={'mini'}>
{formatTimeToChatTime(dataset.updateTime)}
</Box>
</HStack> </HStack>
)} )}
{dataset.permission.hasWritePer && ( {dataset.permission.hasWritePer && (

View File

@ -43,12 +43,12 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
}) })
); );
toast({ toast({
title: t('user:login.success'), title: t('login:login_success'),
status: 'success' status: 'success'
}); });
} catch (error: any) { } catch (error: any) {
toast({ toast({
title: error.message || t('user:login.error'), title: error.message || t('login:login_failed'),
status: 'error' status: 'error'
}); });
} }
@ -61,7 +61,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
const placeholder = (() => { const placeholder = (() => {
if (isCommunityVersion) { if (isCommunityVersion) {
return t('common:support.user.login.Root login'); return t('login:use_root_login');
} }
return [t('common:support.user.login.Username')] return [t('common:support.user.login.Username')]
.concat( .concat(
@ -102,36 +102,36 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
type={'password'} type={'password'}
placeholder={ placeholder={
isCommunityVersion isCommunityVersion
? t('common:support.user.login.Root password placeholder') ? t('login:root_password_placeholder')
: t('common:support.user.login.Password') : t('common:support.user.login.Password')
} }
{...register('password', { {...register('password', {
required: true, required: true,
maxLength: { maxLength: {
value: 60, value: 60,
message: t('user:login.password_condition') message: t('login:password_condition')
} }
})} })}
></Input> ></Input>
</FormControl> </FormControl>
{feConfigs?.docUrl && ( {feConfigs?.docUrl && (
<Flex alignItems={'center'} mt={7} fontSize={'sm'}> <Flex alignItems={'center'} mt={7} fontSize={'mini'}>
{t('common:support.user.login.Policy tip')} {t('login:policy_tip')}
<Link <Link
ml={1} ml={1}
href={getDocPath('/docs/agreement/terms/')} href={getDocPath('/docs/agreement/terms/')}
target={'_blank'} target={'_blank'}
color={'primary.500'} color={'primary.500'}
> >
{t('common:support.user.login.Terms')} {t('login:terms')}
</Link> </Link>
<Box mx={1}>{t('common:support.user.login.And')}</Box> <Box mx={1}>&</Box>
<Link <Link
href={getDocPath('/docs/agreement/privacy/')} href={getDocPath('/docs/agreement/privacy/')}
target={'_blank'} target={'_blank'}
color={'primary.500'} color={'primary.500'}
> >
{t('common:support.user.login.Privacy')} {t('login:privacy')}
</Link> </Link>
</Flex> </Flex>
)} )}
@ -145,7 +145,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
isLoading={requesting} isLoading={requesting}
onClick={handleSubmit(onclickLogin)} onClick={handleSubmit(onclickLogin)}
> >
{t('common:Login')} {t('login:Login')}
</Button> </Button>
<Flex align={'center'} justifyContent={'flex-end'} color={'primary.700'}> <Flex align={'center'} justifyContent={'flex-end'} color={'primary.700'}>
@ -156,7 +156,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
onClick={() => setPageType('forgetPassword')} onClick={() => setPageType('forgetPassword')}
fontSize="sm" fontSize="sm"
> >
{t('common:support.user.login.Forget Password')} {t('login:forget_password')}
</Box> </Box>
)} )}
{feConfigs?.register_method && feConfigs.register_method.length > 0 && ( {feConfigs?.register_method && feConfigs.register_method.length > 0 && (
@ -168,7 +168,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => {
onClick={() => setPageType('register')} onClick={() => setPageType('register')}
fontSize="sm" fontSize="sm"
> >
{t('common:support.user.login.Register')} {t('login:register')}
</Box> </Box>
</> </>
)} )}

View File

@ -129,7 +129,7 @@ const Login = () => {
export async function getServerSideProps(context: any) { export async function getServerSideProps(context: any) {
return { return {
props: { ...(await serviceSideProps(context, ['app', 'user'])) } props: { ...(await serviceSideProps(context, ['app', 'user', 'login'])) }
}; };
} }

View File

@ -1,7 +1,6 @@
import { I18nNsType } from '@fastgpt/web/types/i18next'; import { I18nNsType } from '@fastgpt/web/types/i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
export const LANG_KEY = 'NEXT_LOCALE_LANG';
export enum LangEnum { export enum LangEnum {
'zh' = 'zh', 'zh' = 'zh',
'en' = 'en' 'en' = 'en'
@ -20,24 +19,3 @@ export const langMap = {
export const serviceSideProps = (content: any, ns: I18nNsType = []) => { export const serviceSideProps = (content: any, ns: I18nNsType = []) => {
return serverSideTranslations(content.locale, ['common', 'error', ...ns], null, content.locales); return serverSideTranslations(content.locale, ['common', 'error', ...ns], null, content.locales);
}; };
export const getLng = (lng: string) => {
return lng.split('-')[0];
};
export const change2DefaultLng = (currentLng: string) => {
if (!navigator || !localStorage) return;
if (localStorage.getItem(LANG_KEY)) return;
const userLang = navigator.language;
if (userLang.includes(currentLng)) {
return;
}
// currentLng not in userLang
return getLng(userLang);
};
export const setLngStore = (lng: string) => {
if (!localStorage) return;
localStorage.setItem(LANG_KEY, lng);
};

View File

@ -1,17 +1,14 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { clientInitData } from '@/web/common/system/staticData'; import { clientInitData } from '@/web/common/system/staticData';
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useSystemStore } from '@/web/common/system/useSystemStore';
import type { FastGPTFeConfigsType } from '@fastgpt/global/common/system/types/index.d'; import type { FastGPTFeConfigsType } from '@fastgpt/global/common/system/types/index.d';
import { change2DefaultLng, LangEnum, setLngStore } from '@/web/common/utils/i18n';
import { useMemoizedFn, useMount } from 'ahooks'; import { useMemoizedFn, useMount } from 'ahooks';
import { TrackEventName } from '../common/system/constants'; import { TrackEventName } from '../common/system/constants';
export const useInitApp = () => { export const useInitApp = () => {
const router = useRouter(); const router = useRouter();
const { hiId } = router.query as { hiId?: string }; const { hiId } = router.query as { hiId?: string };
const { i18n } = useTranslation();
const { loadGitStar, setInitd, feConfigs } = useSystemStore(); const { loadGitStar, setInitd, feConfigs } = useSystemStore();
const [scripts, setScripts] = useState<FastGPTFeConfigsType['scripts']>([]); const [scripts, setScripts] = useState<FastGPTFeConfigsType['scripts']>([]);
const [title, setTitle] = useState(process.env.SYSTEM_NAME || 'AI'); const [title, setTitle] = useState(process.env.SYSTEM_NAME || 'AI');
@ -38,20 +35,8 @@ export const useInitApp = () => {
setInitd(); setInitd();
}); });
const initUserLanguage = useMemoizedFn(() => {
// get default language
const targetLng =
change2DefaultLng(i18n.language) ||
(['zh', 'zh-CN'].includes(navigator.language) ? 'zh' : 'en');
setLngStore(targetLng);
router.replace(router.asPath, undefined, { locale: targetLng });
});
useMount(() => { useMount(() => {
initFetch(); initFetch();
initUserLanguage();
const errorTrack = (event: ErrorEvent) => { const errorTrack = (event: ErrorEvent) => {
window.umami?.track(TrackEventName.windowError, { window.umami?.track(TrackEventName.windowError, {

View File

@ -1,188 +0,0 @@
const fs = require('fs').promises
const path = require('path')
// 配置项
const CONFIG = {
i18nDirectory: path.join(__dirname, '../../packages/web/i18n'),
sourceDirectories: ['../../packages', '../../projects/app'].map(dir => path.join(__dirname, dir)),
fileExtensions: ['.ts', '.tsx', '.js', '.jsx'],
ignoreDirectories: ['node_modules', '.next', 'public', 'i18n']
}
// 从文件中加载 JSON
const loadJSON = async (filePath) => {
try {
const data = await fs.readFile(filePath, 'utf8')
return JSON.parse(data)
} catch (error) {
console.error(`读取 JSON 文件 ${filePath} 时出错:`, error)
return null
}
}
// 递归提取 JSON 对象的所有键
const extractKeysFromJSON = (obj, parentKey = '') => {
let keys = []
for (const [key, value] of Object.entries(obj)) {
const fullKey = parentKey ? `${parentKey}.${key}` : key
if (typeof value === 'object' && value !== null) {
keys = keys.concat(extractKeysFromJSON(value, fullKey))
} else {
keys.push(fullKey)
}
}
return keys
}
// 递归获取文件夹中的所有 JSON 文件
const getAllJSONFiles = async (dir) => {
let results = []
const list = await fs.readdir(dir)
await Promise.all(list.map(async (file) => {
const filePath = path.join(dir, file)
const stat = await fs.stat(filePath)
if (stat.isDirectory()) {
if (!CONFIG.ignoreDirectories.includes(file)) {
results = results.concat(await getAllJSONFiles(filePath))
}
} else if (filePath.endsWith('.json')) {
results.push(filePath)
}
}))
return results
}
// 提取文件夹中所有 JSON 文件的键
const extractKeysFromDirectory = async (dir) => {
let allKeys = new Set()
const subDirs = await fs.readdir(dir)
await Promise.all(subDirs.map(async (subDir) => {
const subDirPath = path.join(dir, subDir)
const stat = await fs.stat(subDirPath)
if (stat.isDirectory() && !CONFIG.ignoreDirectories.includes(subDir)) {
const files = await getAllJSONFiles(subDirPath)
await Promise.all(files.map(async (file) => {
const jsonObject = await loadJSON(file)
if (jsonObject) {
const keys = extractKeysFromJSON(jsonObject)
keys.forEach(key => allKeys.add(key))
}
}))
}
}))
return Array.from(allKeys)
}
// 检查键是否在内容中使用
const isKeyUsedInContent = (content, key) => {
const regex = new RegExp(`\\b${key}\\b`, 'g')
return regex.test(content)
}
// 递归在文件夹中搜索键
const searchKeysInFiles = async (dir, keys, usedKeys) => {
const list = await fs.readdir(dir)
await Promise.all(list.map(async (file) => {
const filePath = path.join(dir, file)
const stat = await fs.stat(filePath)
if (stat.isDirectory()) {
if (!CONFIG.ignoreDirectories.includes(file)) {
await searchKeysInFiles(filePath, keys, usedKeys)
}
} else if (CONFIG.fileExtensions.includes(path.extname(file))) {
const data = await fs.readFile(filePath, 'utf8')
keys.forEach(key => {
if (isKeyUsedInContent(data, key)) {
usedKeys.add(key)
}
})
}
}))
}
// 从扁平键路径恢复嵌套对象
const restoreNestedStructure = (keys) => {
const result = {}
keys.forEach(key => {
const parts = key.split('.')
let current = result
parts.forEach((part, index) => {
if (!current[part]) {
current[part] = index === parts.length - 1 ? null : {}
}
current = current[part]
})
})
return result
}
// 递归删除未使用的键
const removeUnusedKeys = (target, unusedKeys) => {
for (const [key, value] of Object.entries(unusedKeys)) {
if (value === null) {
delete target[key]
} else if (typeof target[key] === 'object' && target[key] !== null) {
removeUnusedKeys(target[key], value)
if (Object.keys(target[key]).length === 0) {
delete target[key]
}
}
}
}
// 处理 JSON 文件
const processJSONFile = async (filePath, unusedKeys) => {
try {
const jsonObject = await loadJSON(filePath)
if (jsonObject) {
removeUnusedKeys(jsonObject, unusedKeys)
await fs.writeFile(filePath, JSON.stringify(jsonObject, null, 2), 'utf8')
console.log(`已处理文件 ${filePath}`)
}
} catch (error) {
console.error(`处理文件 ${filePath} 时出错:`, error)
}
}
// 递归处理目录中的所有 JSON 文件
const processJSONFilesInDirectory = async (dir, unusedKeys) => {
const list = await fs.readdir(dir)
await Promise.all(list.map(async (file) => {
const filePath = path.join(dir, file)
const stat = await fs.stat(filePath)
if (stat.isDirectory() && !CONFIG.ignoreDirectories.includes(file)) {
await processJSONFilesInDirectory(filePath, unusedKeys)
} else if (stat.isFile() && file.endsWith('.json')) {
await processJSONFile(filePath, unusedKeys)
}
}))
}
// 将 keys 写入 JSON 文件
const writeKeysToFile = async (filePath, keys) => {
try {
await fs.writeFile(filePath, JSON.stringify(keys, null, 2), 'utf8')
console.log(`已将 keys 写入文件 ${filePath}`)
} catch (error) {
console.error(`写入文件 ${filePath} 时出错:`, error)
}
}
// 主函数
const main = async () => {
const allKeys = await extractKeysFromDirectory(CONFIG.i18nDirectory)
// await writeKeysToFile(path.join(__dirname, 'allKeys.json'), allKeys)
const usedKeys = new Set()
await Promise.all(CONFIG.sourceDirectories.map(dir => searchKeysInFiles(dir, allKeys, usedKeys)))
const unusedKeys = allKeys.filter(key => !usedKeys.has(key))
// await writeKeysToFile(path.join(__dirname, 'unusedKeys.json'), unusedKeys)
console.log(unusedKeys)
const nestedUnusedKeys = restoreNestedStructure(unusedKeys)
await processJSONFilesInDirectory(CONFIG.i18nDirectory, nestedUnusedKeys)
}
main().catch(err => console.error('执行过程中出错:', err))

View File

@ -1,15 +0,0 @@
{
"name": "i18n",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@phenomnomnominal/tsquery": "^6.1.3"
}
}

View File

@ -1,94 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var tsquery_1 = require("@phenomnomnominal/tsquery");
var path = require("path");
var fs = require("fs");
//
var root = path.join(__dirname, '../../');
// get all files in the project recursively
function getAllFiles(dirPath, arrayOfFiles) {
if (arrayOfFiles === void 0) { arrayOfFiles = []; }
var files = fs.readdirSync(dirPath);
files.forEach(function (file) {
var filePath = path.join(dirPath, file);
if (fs.statSync(filePath).isDirectory()) {
arrayOfFiles = getAllFiles(filePath, arrayOfFiles);
}
else {
arrayOfFiles.push(filePath);
}
});
return arrayOfFiles;
}
var allFiles = getAllFiles(root).filter(function (file) { return file.endsWith('.ts') || file.endsWith('.tsx'); })
.filter(function (file) { return !file.includes('node_modules'); })
.filter(function (file) { return !file.includes('jieba'); });
function processFiles(allFiles) {
return __awaiter(this, void 0, void 0, function () {
var fileContents, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, Promise.all(allFiles.map(function (file) { return fs.readFileSync(file, 'utf-8'); }))];
case 1:
fileContents = _a.sent();
// 处理每个文件的内容
fileContents.forEach(function (content, index) {
var astTree = (0, tsquery_1.ast)(content);
var res = (0, tsquery_1.query)(astTree, 'JsxText,StringLiteral');
for (var _i = 0, res_1 = res; _i < res_1.length; _i++) {
var node = res_1[_i];
var text = node.getText().trim();
if (text.length > 0 && text.match(/[\u4e00-\u9fa5]/g)) {
console.log(allFiles[index], text);
}
}
});
return [3 /*break*/, 3];
case 2:
error_1 = _a.sent();
console.error('Error processing files:', error_1);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
}
processFiles(allFiles);

View File

@ -1,49 +0,0 @@
import { ast, query } from '@phenomnomnominal/tsquery';
import * as path from 'path';
import * as fs from 'fs';
//
const root = path.join(__dirname, '../../');
// get all files in the project recursively
function getAllFiles(dirPath: string, arrayOfFiles: string[] = []): string[] {
const files = fs.readdirSync(dirPath);
files.forEach((file) => {
const filePath = path.join(dirPath, file);
if (fs.statSync(filePath).isDirectory()) {
arrayOfFiles = getAllFiles(filePath, arrayOfFiles);
} else {
arrayOfFiles.push(filePath);
}
});
return arrayOfFiles;
}
const allFiles = getAllFiles(root)
.filter((file) => file.endsWith('.ts') || file.endsWith('.tsx'))
.filter((file) => !file.includes('node_modules'))
.filter((file) => !file.includes('jieba'));
async function processFiles(allFiles: string[]) {
try {
// 并行读取所有文件内容
const fileContents = await Promise.all(allFiles.map((file) => fs.readFileSync(file, 'utf-8')));
// 处理每个文件的内容
fileContents.forEach((content, index) => {
const astTree = ast(content);
const res = query(astTree, 'JsxText,StringLiteral');
for (const node of res) {
const text = node.getText().trim();
if (text.length > 0 && text.match(/[\u4e00-\u9fa5]/g)) {
console.log(allFiles[index], text);
}
}
});
} catch (error) {
console.error('Error processing files:', error);
}
}
processFiles(allFiles);