Commit adb87977 authored by tyyin lan's avatar tyyin lan

feat: 多语言切换

parent 6f8d5ac9
...@@ -16,4 +16,5 @@ ...@@ -16,4 +16,5 @@
"src/locales/langs" "src/locales/langs"
], ],
"i18n-ally.sourceLanguage": "zh-cn", "i18n-ally.sourceLanguage": "zh-cn",
} "i18n-ally.keystyle": "nested",
}
\ No newline at end of file
...@@ -25,6 +25,7 @@ export default [ ...@@ -25,6 +25,7 @@ export default [
ConversationMessageItem: 'readonly', ConversationMessageItem: 'readonly',
ConversationMessageItemInfo: 'readonly', ConversationMessageItemInfo: 'readonly',
MittEvents: 'readonly', MittEvents: 'readonly',
I18n: 'readonly',
}, },
parser: vueParser, parser: vueParser,
parserOptions: { parserOptions: {
......
<script setup lang="ts">
import { useSystemLanguageStore } from '@/store/modules/system-language'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { Up, Translate, Down } from '@icon-park/vue-next'
interface Props {
arrowDirection: 'top' | 'bottom'
btnBgColor?: string
}
const { arrowDirection = 'bottom', btnBgColor = '#f4f5f5' } = defineProps<Props>()
const systemLanguageStore = useSystemLanguageStore()
const { locale } = useI18n()
const isShowLanguagePopover = ref(false)
function handleLanguageOptionsUpdateShow(value: boolean) {
if (value) {
isShowLanguagePopover.value = true
} else {
isShowLanguagePopover.value && (isShowLanguagePopover.value = false)
}
}
function handleLanguageOptionSelect(key: I18n.LangType) {
systemLanguageStore.updateCurrentLanguageInfo(key)
locale.value = key
isShowLanguagePopover.value = false
}
</script>
<template>
<n-popover
placement="bottom"
trigger="hover"
class="!p-[10px]"
:show-arrow="false"
:show="isShowLanguagePopover"
@update:show="handleLanguageOptionsUpdateShow"
>
<template #trigger>
<button
class="flex w-full items-center rounded-[6px] bg-[#f4f5f5] px-[12px] py-[6px] transition hover:bg-[#eceded]"
:style="{ backgroundColor: btnBgColor }"
>
<Translate theme="outline" size="16" fill="#000dff" :stroke-width="3" />
<div class="ml-[10px] flex flex-1 items-center justify-between">
<span>{{ systemLanguageStore.currentLanguageInfo.label }}</span>
<Up
v-if="arrowDirection === 'top'"
class="transition-[rotate] duration-300 ease-in-out"
:class="{ 'rotate-180': isShowLanguagePopover }"
theme="outline"
size="21"
fill="#333"
:stroke-width="3"
/>
<Down
v-else
theme="outline"
size="21"
fill="#333"
:stroke-width="3"
class="transition-[rotate] duration-300 ease-in-out"
:class="{ 'rotate-180': isShowLanguagePopover }"
/>
</div>
</button>
</template>
<ul class="select-none">
<li
v-for="langItem in systemLanguageStore.languageOptions"
:key="langItem.key"
class="relative mb-[6px] cursor-pointer bg-[#f3f3f5] px-[20px] py-[4px] text-center transition last:mb-0 hover:bg-[#e7e7e7]"
@click="handleLanguageOptionSelect(langItem.key as I18n.LangType)"
>
{{ langItem.label }}
<i
v-show="langItem.key === systemLanguageStore.currentLanguageInfo.key"
class="iconfont icon-xuanze text-theme-color absolute bottom-0 right-0 text-[14px]"
></i>
</li>
</ul>
</n-popover>
</template>
<script setup lang="ts"> <script setup lang="ts">
import { h, readonly, ref, shallowReadonly, watchEffect } from 'vue' import { computed, h, ref, watchEffect } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { Plus } from '@icon-park/vue-next' import { Plus } from '@icon-park/vue-next'
import type { MenuOption } from 'naive-ui' import type { MenuOption } from 'naive-ui'
import CustomIcon from '@/components/custom-icon/custom-icon.vue' import CustomIcon from '@/components/custom-icon/custom-icon.vue'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import LanguageSetting from '@/components/language-setting/language-setting.vue'
const { t } = useI18n() const { t } = useI18n()
...@@ -18,26 +19,30 @@ const defaultAvatar = 'https://gsst-poe-sit.gz.bcebos.com/data/20240910/17259529 ...@@ -18,26 +19,30 @@ const defaultAvatar = 'https://gsst-poe-sit.gz.bcebos.com/data/20240910/17259529
const currentMenuValue = ref('') const currentMenuValue = ref('')
const menuOptions = shallowReadonly<MenuOption[]>([ const menuOptions = computed<MenuOption[]>(() => {
{ return [
label: () => h('div', {}, t('router_title_module.home')), {
key: 'Home', label: () => h('div', {}, t('router_title_module.home')),
icon: () => h('i', { class: 'iconfont icon-home' }), key: 'Home',
}, icon: () => h('i', { class: 'iconfont icon-home' }),
{ },
label: () => h('div', {}, t('router_title_module.personal')), {
key: 'PersonalSpace', label: () => h('div', {}, t('router_title_module.personal')),
icon: () => h('i', { class: 'iconfont icon-personal' }), key: 'PersonalSpace',
}, icon: () => h('i', { class: 'iconfont icon-personal' }),
]) },
]
const avatarOptions = readonly([ })
{
label: () => h('div', {}, t('common_module.logout')), const avatarOptions = computed(() => {
key: 'logout', return [
icon: () => h(CustomIcon, { icon: 'teenyicons:logout-solid' }), {
}, label: () => h('div', {}, t('common_module.logout')),
]) key: 'logout',
icon: () => h(CustomIcon, { icon: 'teenyicons:logout-solid' }),
},
]
})
watchEffect(() => { watchEffect(() => {
currentMenuValue.value = (currentRoute.meta.belong as string) || '' currentMenuValue.value = (currentRoute.meta.belong as string) || ''
...@@ -98,27 +103,33 @@ function handleMenuValueChange(key: string) { ...@@ -98,27 +103,33 @@ function handleMenuValueChange(key: string) {
</n-scrollbar> </n-scrollbar>
</div> </div>
<div class="my-7 px-3"> <div class="mb-[20px] mt-6 px-[12px]">
<NDropdown <div>
v-if="userStore.isLogin" <NDropdown
trigger="click" v-if="userStore.isLogin"
placement="top-start" trigger="click"
:options="avatarOptions" placement="top-start"
@select="handleDropdownSelect" :options="avatarOptions"
> @select="handleDropdownSelect"
<div class="flex h-full cursor-pointer items-center"> >
<NAvatar round :size="40" object-fit="cover" :src="userStore.userInfo.avatarUrl || defaultAvatar" /> <div class="flex h-full cursor-pointer items-center">
<NAvatar round :size="40" object-fit="cover" :src="userStore.userInfo.avatarUrl || defaultAvatar" />
<div class="ml-3 line-clamp-1 max-w-[140px] select-none break-all text-base">
{{ userStore.userInfo.nickName || t('common_module.not_login_text') }} <div class="ml-3 line-clamp-1 max-w-[140px] select-none break-all text-base">
{{ userStore.userInfo.nickName || t('common_module.not_login_text') }}
</div>
</div> </div>
</NDropdown>
<div v-else>
<NButton type="primary" class="w-full! rounded-md!" @click="handleToLogin">
{{ t('common_module.login_now') }}
</NButton>
</div> </div>
</NDropdown> </div>
<div v-else> <div class="mt-[10px]">
<NButton type="primary" class="w-full! rounded-md!" @click="handleToLogin"> <LanguageSetting arrow-direction="top" />
{{ t('common_module.login_now') }}
</NButton>
</div> </div>
</div> </div>
</div> </div>
......
import { type App } from 'vue' import { type App } from 'vue'
import { createI18n } from 'vue-i18n' import { createI18n } from 'vue-i18n'
import messages from './messages' import messages from './messages'
import { ss } from '@/utils/storage'
export const defaultLocale = 'zh-CN'
const i18n = createI18n<[I18n.Schema], I18n.LangType>({ const i18n = createI18n<[I18n.Schema], I18n.LangType>({
legacy: false, legacy: false,
locale: 'zh-CN', locale: ss.get('i18nextLng') || defaultLocale,
fallbackLocale: 'zh-HK', fallbackLocale: 'zh-HK',
messages, messages,
}) })
......
common_module:
cancel_btn_text: 'Cancel'
confirm_btn_text: 'Confirm'
prev_btn_text: 'Previous step'
next_btn_text: 'Next step'
create: 'Newly added'
delete: 'Delete'
login: 'Login'
logout: 'Logout'
not_login_text: 'Please log in first'
login_now: 'Sign in now'
name: 'Name'
desc: 'Description'
publish_time_in: 'Publish in'
created_time: 'Creation time'
modified_time: 'Edit time'
is_open: 'Enable'
status: 'Status'
publish: 'Publish'
published: 'Have released'
unpublished: 'Unpublish'
ai_generate: 'AI generation'
regenerate: 'Regenerate'
unavailable: 'Not available'
available: 'Usable'
studying: 'Studying'
config: 'Configure'
agent: 'Apply'
knowledge: 'Knowledge base'
custom: 'Custom'
char: 'Character'
upload: 'Upload'
uploading: 'Uploading...'
upload_success_message: 'Upload successfully'
empty_data: 'No data available'
search_empty_data: 'No related content found'
create_agent_btn_text: 'Create an application'
copy_success_message: 'Successful replication'
delete_success_message: 'Successfully deleted'
save_success_message: 'Save successfully'
save_fail_message: 'Save failure'
edit_success_message: 'Edit successfully'
publish_success_message: 'Release success'
clear_success_message: 'Clear successfully'
add_success_message: 'New success'
loading: 'Loading'
updating: 'Uploading'
successful_update: 'Update successfully'
recommended_questions: 'Recommendation problem'
exchange: 'Change'
tip: 'Tips'
during_operation: 'In operation'
deletion_failed_please_try_again: 'Failed to delete, please try again'
select_all: 'Select all'
quit: 'Quit'
retry: 'Retry'
currently: 'Current'
multi_model_debug: 'Multi-model debugging'
accurate_mode: 'Precision model'
balance_mode: 'Equilibrium mode'
creative_mode: 'Creative mode'
all: 'All'
collect: 'Collect'
listing_successfully: 'Shelf success'
listing_failed: 'Shelf failure'
removal_successfully: 'Removed successfully'
removal_failed: 'Removal failure'
collect_successfully: 'Successful collection'
collect_unsubscribed: 'Uncollected'
cancel: 'Cancel'
preservation: 'Save'
dialogue_module:
continue_question_message: 'You can keep asking questions'
empty_message_content: '[Empty content]'
question_input_placeholder: 'Please enter your question to ask'
generate_warning_message: 'The above content is generated by AI and is for reference only'
clear_message_popover_message: 'Clear history session'
clear_message_dialog_title: 'Are you sure you want to clear the conversation?'
clear_message_dialog_content: 'Clearing the session will clear all the history of the session in the debug area. Are you sure to clear the session?'
data_table_module:
action: 'Controls'
edit: 'Editor'
copy: 'Copy'
delete: 'Delete'
view: 'View'
analysis: 'Analyze'
listing_applications: 'Launch application'
remove_applications: 'Takedown application'
pagination_module:
page_no: 'Size'
page_size: 'Page'
page_unit: 'Each page'
total: 'Total'
goto: 'Skip to'
login_module:
app_welcome_words: 'Welcome to CuiXiang POC'
please_enter_your_account_number: 'Please enter your account number'
please_enter_your_password: 'Please enter password'
please_enter_your_cell_phone_number: 'Please enter your phone number'
please_enter_your_correct_cell_phone_number: 'Please enter the correct phone number'
please_enter_the_verification_code: 'Please enter the verification code'
please_enter_your_email_address: 'Please enter your email address'
please_enter_the_correct_email_address: 'Please enter the correct email address'
mainland_china: 'Chinese mainland'
hong_kong_china: 'Hong Kong, China'
login_success: 'Login successful'
successful: 'Obtain success'
get_verification_code: 'Get verification code'
other_login_methods: 'Other login methods'
home_module:
agent_welcome_message: 'Hi, welcome to SuperLink'
agent_description: 'Here, you can experience models and dedicated agents for multiple platforms'
currently_in_the_latest_session: 'This is the latest session'
switching_over: 'Switching'
history_application_success: 'Description The history record was successfully applied'
history_application_failed_please_try_again: 'Failed to apply history. Please try again'
starting_a_new_session: 'Initiate a new session'
please_enter_a_question: 'Please type the question (press enter+shift to wrap lines)'
all_of_the_above_content_is_generated_by_ai_and_is_for_reference_only: 'The above content is generated by AI and is for reference only'
history_record_item_delete_tip: 'Are you sure to delete the currently selected session record?'
there_is_currently_no_history_to_work_with: 'There is currently no history to operate'
the_selected_list_cannot_be_empty: 'The selected list cannot be empty'
history_record_item_apply_tip: 'Are you sure to apply this session record?'
historical_record: 'Historical record'
interrupt_dialogue_prompt: 'The current reply is not complete. Are you sure to interrupt and initiate a new session?'
interrupt_the_conversation_and_apply_the_history_prompt: 'The current reply is not complete, are you sure to interrupt the conversation and apply another record?'
router_title_module:
login: 'Login'
server_error: 'Server error'
universal: 'The page was not found'
home: 'Home page'
personal: 'Personal space'
app_setting: 'Application Settings'
agent_application: 'Agent application'
share_application: 'My Agent application'
knowledge: 'Knowledge base'
upload_knowledge_document: 'Uploading Knowledge Base Documents'
knowledge_document_list: 'Knowledge base document list'
knowledge_document_detail: 'Knowledge base Document Details'
multi_model_dialogue: 'Multi-model debugging'
personal_space_module:
title: 'Personal space'
create_btn_text: 'Newly build'
agent_module:
agent_list_module:
search_agent_placeholder: 'Please enter an application name or description'
agent_title: 'Application title'
large_model: 'Model name'
agent_id: 'Application ID'
agent_publish_status: 'Release status'
modified_time: 'Recent edit'
channel: 'Channel'
channel_popover_text: 'View release details'
agent_copy: 'Copy'
empty_agent_list: 'No application'
search_empty_agent_list: 'No related content found'
delete_agent_dialog_title: 'Are you sure you want to delete the selected app?'
delete_agent_dialog_content: 'If you want to use it again after deleting it, create it again'
remove_applications_dialog_title: 'Are you sure you want to take the app down?'
already_bottom: 'Have come to the end'
application_empty: 'No application created'
agent_setting_module:
modified: 'Have been changed'
auto_save_in: 'Autosave to'
update_publish_btn_text: 'Update release'
publish_btn_text: 'Hair cloth'
please_finish_publish: 'Please finish publishing first'
missing_agent_title_message: 'The application name cannot be empty'
missing_agent_desc_message: 'No description yet'
agent_config_module:
stop_generate: 'Stop generation'
generating_config_message: 'Configuration information generation...'
title: 'Application configuration'
ai_auto_config: 'AI automatic configuration'
question_answer_model: 'Question and answer model'
question_answer_model_desc: 'Used to summarize and generate reply results'
generate_diversity: 'Generative diversity'
accurate_mode: 'Precision model'
balance_mode: 'Equilibrium mode'
creative_mode: 'Creative mode'
topP: 'Top P'
topP_popover_message: 'When the model generates the output, it starts with the words with the highest probability until the total probability of these words accumulates to a value of Top p. This limits the model to choosing only these high-probability terms, thereby controlling the diversity of output content.'
temperature: 'Generative randomness'
temperature_popover_message: 'Used to control the diversity of model outputs. The recommended value is 0, and the larger the value, the greater the difference in the output content of the model推荐值为 0,数值越大,模型每次输出内容的差异性越大'
communication_turn: 'Refer to session rounds'
communication_turn_popover_message: 'The maximum number of session rounds passed into the large model context. The recommended value is 2, the higher the value, the stronger the context correlation in multiple rounds of conversations, but the more Tokens are consumed'
agent_setting: 'Application setting'
base_info: 'Basic information'
agent_title_input_placeholder: 'Please enter the application name'
agent_title_input_rule_message: 'Please enter the application name'
agent_desc_input_placeholder: 'Please describe your app, which will be displayed regularly after the app is published'
update_avatar: 'Modify profile picture'
agent_system_prompt: 'Role instruction'
agent_system_popover_message: 'Through the Instruction function, you can precisely set the scope of the Agent application. This includes specifying the role the application will play, the components it can use, and the format and style of the output. In addition, you can specify what actions the app cannot perform, and so on.'
optimize_agent_system_prompt: 'Optimize'
optimize_agent_system_popover_message: 'AI optimization'
agent_system_template: 'Template'
agent_system_template_message: "
# Character setting
As a ____, your task is ____. \n\n
# Component capability \n
You have the ability ____. \n\n
# Requirements and limitations \n
1. The style of the output content is required ____\n
2. The output is formatted as ____\n
3. The word limit of output content shall not exceed ____\n
......"
agent_system_input_placeholder: 'Please enter the task objectives that you want the character to complete, the component capabilities that they have, and the requirements and limitations on the output answers'
ability_expand: 'Capacity expansion'
knowledge: 'Knowledge'
knowledge_base: 'Knowledge base'
knowledge_base_desc: 'Reference text data, tabular knowledge data (including FAQ questions, multi-column index questions) and web data to achieve knowledge base questions and answers. The application can be associated with a maximum of 5 knowledge bases. Please fill in the detailed description of the knowledge base to improve the accuracy of questions and answers'
dialogue: 'Dialogue'
preamble: 'Opening remarks'
preamble_input_placeholder: 'Please enter an opening statement'
featured_questions: 'Referral question'
featured_questions_input_placeholder: 'Please enter a recommendation question'
continuous_question: 'Make a close inquiry'
continuous_question_popover_message: 'The large model automatically generates additional questions based on the content of the conversation'
continuous_question_default: 'Default'
continuous_question_default_desc: 'Based on the user''s latest round of conversation, it automatically provides three question suggestions after a reply.'
continuous_question_close: 'Close'
continuous_question_close_desc: 'After each round of responses, users will not be provided with any suggestions for questions'
memory: 'Memory'
add_memory_variable: 'Add memory variable'
memory_variable: 'Memory variable'
memory_message:
'The developer can set the memory variable according to the application, and the application user can input the variable content during the conversation, and each variable can store one-dimensional and single data.
During the conversation, the application responds based on the stored variable value. Take "travel assistant" as an example:'
memory_variable_message: 'Recording one-dimensional, individual application or user information in a chat conversation allows agents to personalize their responses.'
memory_variable_action_edit: 'Editor'
memory_variable_action_copy: 'Copy name'
variable_name: 'Variable name'
variable_value: 'Variable value'
memory_variable_modal:
edit_memory_variable: 'Edit memory variable'
memory_variable_message_tip: 'Deleting a variable or changing its name or description will cause the variable data corresponding to the application user to be deleted or reset to the default value after the application update is released. Exercise caution when performing this operation'
memory_variable_table_name: 'Name'
memory_variable_table_name_tip: 'Fill in the content'
memory_variable_table_name_content: '1. English and Chinese only'
memory_variable_table_name_length: '2. Length of 50 characters or less'
memory_variable_table_default_value: 'Default value'
default_value_tip: 'Developers can set default values for app users'
default_value_tip_example: 'Example: Beijing'
memory_variable_table_action: 'Controls'
default_value_placeholder: 'Please enter'
name_placeholder: 'Please enter name'
add_variable: 'New variable'
memory_variable_rules:
name_not_null: 'Please enter name'
name_length: 'The name contains a maximum of 50 characters'
name_supports: 'English and Chinese only'
name_not_duplicated: 'Name must not be repeated'
preview: '预览与调试'
avatar_oversize_message: '图片不能超过3MB'
generate_format_error_message: '生成内容格式出错啦'
auto_config_modal_module:
modal_title: 'AI生成配置信息'
generate_tip_message: '生成结果将覆盖当前的配置内容,请确认是否继续生成'
auto_config_input_placeholder: '请告诉我你想创建一个什么样的应用,大模型将为你自动生成'
cancel_btn_text: ' 消'
random_generate_btn_text: '随机生成'
optimize_system_modal_module:
modal_title: '角色指令优化'
confirm_btn_text: '使 用'
agent_publish_module:
channel: '发布渠道'
web_channel_name: '网页端'
web_channel_desc: '可通过PC或移动设备立即开始对话'
access_page: '立即访问'
share_link: '分享链接'
copy_share_url_success_message: '链接复制成功,快分享给你的好友吧!'
agent_sale_module:
application_square_release_setting: '应用广场发布配置'
application_classification: '应用分类'
application_classification_null: '应用分类不能为空'
application_classify:
media_entertainment: '媒体文娱'
education_training: '教育培训'
business_services: '商业服务'
medical_health: '医疗健康'
efficiency_tools: '效率工具'
office_personnel: '办公人事'
marketing_commerce: '营销电商'
finance: '金融'
law: '法律'
culture_tourism: '文旅'
is_copy: '是否允许复制'
yes: '是'
no: '否'
confirm_release: '确认发布'
copy_tip: '选择「是」代表您允许平台的开发者和用户,复制您的应用配置进行二次开发来创建新应用。注意:私有配置不支持复制(私有配置包含:知识库、数据库)'
knowledge_module:
search_knowledge_placeholder: '请输入知识库名称'
knowledge_name: '知识库名称'
knowledge_desc: '知识库描述'
delete_knowledge_dialog_content: '删除后将无法恢复'
not_find_knowledge_message: '未找到知识库'
search_knowledge_document_placeholder: '请输入文件名称'
knowledge_document_name: '文件名称'
knowledge_document_char_count: '字符数'
knowledge_document_format: '文件格式'
view_knowledge_document_fragment: '查看切片'
training_knowledge_document: '重新训练'
empty_knowledge_document_list: '暂无文件'
upload_knowledge_document_btn_text: '导入文件'
batch_delete_knowledge_document_btn_text: '批量删除'
not_find_knowledge_document_message: '未找到知识库文件'
create_knowledge_modal_title: '创建知识库'
edit_knowledge_modal_title: '编辑知识库'
knowledge_name_input_placeholder: '请输入数据集名称'
knowledge_desc_input_placeholder: '请输入数据集内容描述'
knowledge_import_type_label: '导入类型'
knowledge_type_rule: '请选择数据集类型'
knowledge_name_rule: '请输入数据集名称'
knowledge_import_type_rule: '请选择数据集导入方式'
knowledge_document_text_type: '文本格式'
import_local_document_knowledge: '本地文档'
import_local_document_knowledge_desc: '支持上传TXT、MD、PDF、DOC、DOCX、格式的本地文件'
segment: '分段'
auto_segment: '自动分段'
add_chunk_up_message: '向上添加分片'
add_chunk_down_message: '向下添加分片'
search_knowledge_chunk_placeholder: '请输入切片名称'
add_knowledge_chunk_modal_title: '新增切片'
knowledge_chunk_content_input_placeholder: '请输入内容'
knowledge_chunk_content_input_rule: '内容不能为空'
delete_knowledge_chunk_content_message: '确认删除该切片'
upload_document_module:
segment_setting: '分段处理'
data_process: '数据处理'
process_success: '处理成功'
process_fail: '处理失败'
processed: '处理中~'
upload_action_tip_message: '点击上传或拖拽文档到这里'
upload_limit_tip_message: '支持DOC、DOCX、TXT、PDF、MD,最多可上传5个文件,每个文件不超过10MB'
empty_document_content_message: '上传文件内容不能为空'
upload_format_error_message: '只能上传DOC、DOCX、TXT、PDF、MD格式文本文件,请重新上传'
upload_size_error_message: '上传文件大小不能超过10M'
upload_error_message: '上传失败,请删除文件后再进行操作'
default_segment_setting_title: '自动分段与清洗'
default_segment_setting_desc: '自动分段与预处理规则'
data_process_tip_message: '点击确认不影响数据处理,处理完毕后可进行引用'
share_agent_module:
please: '请先'
after_action: '后开始提问'
create_agent_dialogue_title: '温馨提示'
create_agent_dialogue_content: '为保证您的体验,请通过pc端访问'
create_agent_dialogue_positive_text: '我知道啦'
multi_model_dialogue_module:
not_find_agent: '应用不存在'
add_model: '增加模型'
quit_test: '退出测试'
model_setting: '模型设置'
agent_system: '系统人设'
remove_dialogue: '移除'
one_click_configuration: '一键配置'
select_model: '选择模型'
please_select_model: '请选择模型'
please_select_model_first: '请先选择模型'
replace_configuration_tip: '是否将该模型的配置覆盖到原来的配置项上'
open_new_conversation: '已开启新会话'
...@@ -116,7 +116,7 @@ home_module: ...@@ -116,7 +116,7 @@ home_module:
agent_welcome_message: 'Hi, 欢迎使用SuperLink' agent_welcome_message: 'Hi, 欢迎使用SuperLink'
agent_description: '在这里,你可以体验多个平台的模型和专属的智能体' agent_description: '在这里,你可以体验多个平台的模型和专属的智能体'
currently_in_the_latest_session: '当前已是最新会话' currently_in_the_latest_session: '当前已是最新会话'
switching_over: '切换中...' switching_over: '切换中'
history_application_success: '历史记录应用成功' history_application_success: '历史记录应用成功'
history_application_failed_please_try_again: '历史记录应用失败,请重试' history_application_failed_please_try_again: '历史记录应用失败,请重试'
starting_a_new_session: '发起新会话' starting_a_new_session: '发起新会话'
......
...@@ -118,7 +118,7 @@ home_module: ...@@ -118,7 +118,7 @@ home_module:
agent_welcome_message: 'Hi, 歡迎使用SuperLink' agent_welcome_message: 'Hi, 歡迎使用SuperLink'
agent_description: '在這裏,你可以體驗多個平臺的模型和專屬的智' agent_description: '在這裏,你可以體驗多個平臺的模型和專屬的智'
currently_in_the_latest_session: '當前已是最新會話' currently_in_the_latest_session: '當前已是最新會話'
switching_over: '切換中...' switching_over: '切換中'
history_application_success: '歷史記錄應用成功' history_application_success: '歷史記錄應用成功'
history_application_failed_please_try_again: '歷史記錄應用失敗,請重試' history_application_failed_please_try_again: '歷史記錄應用失敗,請重試'
starting_a_new_session: '發起新會話' starting_a_new_session: '發起新會話'
......
import zhHK from './langs/zh-hk.yaml' import zhHK from './langs/zh-hk.yaml'
import zhCN from './langs/zh-cn.yaml' import zhCN from './langs/zh-cn.yaml'
import en from './langs/en.yaml'
const messages: Record<I18n.LangType, I18n.Schema> = { const messages: Record<I18n.LangType, I18n.Schema> = {
'zh-HK': zhHK, 'zh-HK': zhHK,
'zh-CN': zhCN, 'zh-CN': zhCN,
en,
} }
export default messages export default messages
import { ss } from '@/utils/storage'
import { defineStore } from 'pinia'
import { defaultLocale } from '@/locales/index'
interface SystemLanguageState {
currentLanguageInfo: {
key: string
label: string
}
languageOptions: {
key: string
label: string
}[]
}
const defaultLanguageOptions = [
{
label: '中文简体',
key: 'zh-CN',
},
{
label: '中文繁體',
key: 'zh-HK',
},
{
label: 'English',
key: 'en',
},
]
const localeKey = ss.get('i18nextLng') || defaultLocale
export const useSystemLanguageStore = defineStore('system-language-store', {
state: (): SystemLanguageState => ({
currentLanguageInfo: {
key: localeKey,
label: defaultLanguageOptions.find((optionItem) => optionItem.key === localeKey)!.label,
},
languageOptions: defaultLanguageOptions,
}),
actions: {
updateCurrentLanguageInfo(key: I18n.LangType) {
if (this.currentLanguageInfo.key === key) return ''
ss.set('i18nextLng', key)
this.currentLanguageInfo = this.languageOptions.find((optionItem) => optionItem.key === key) as {
key: string
label: string
}
},
},
})
// export const useSystemLanguageStore = defineStore('system-language-store', () => {
// const currentLanguageInfo = ref({
// key: localeKey,
// label: defaultLanguageOptions.find((optionItem) => optionItem.key === localeKey)!.label,
// })
// const languageOptions = readonly(defaultLanguageOptions)
// function updateCurrentLanguageInfo(key: I18n.LangType) {
// if (currentLanguageInfo.value.key === key) return ''
// ss.set('i18nextLng', key)
// const { locale } = useI18n()
// locale.value = key
// currentLanguageInfo.value = defaultLanguageOptions.find((optionItem) => optionItem.key === key) as {
// key: string
// label: string
// }
// }
// return { currentLanguageInfo, languageOptions, updateCurrentLanguageInfo }
// })
...@@ -150,7 +150,7 @@ function onHistoryRecordListUpdate() { ...@@ -150,7 +150,7 @@ function onHistoryRecordListUpdate() {
function onGetMessageRecordList(recordId: string) { function onGetMessageRecordList(recordId: string) {
currentSessionId.value = recordId currentSessionId.value = recordId
const loadingCtl = window.$message.loading(t('home_module.switching_over')) const loadingCtl = window.$message.loading(`${t('home_module.switching_over')}...`)
fetchMessageRecordList< fetchMessageRecordList<
{ {
......
<script setup lang="ts"> <script setup lang="ts">
import { ref, shallowReadonly, useTemplateRef, watchEffect } from 'vue' import { computed, ref, shallowReadonly, useTemplateRef, watchEffect } from 'vue'
import type { FormInst, FormRules, FormItemRule, CountdownInst } from 'naive-ui' import type { FormInst, FormRules, FormItemRule, CountdownInst } from 'naive-ui'
import { Mail, Lock, Iphone, Down, User } from '@icon-park/vue-next' import { Mail, Lock, Iphone, Down, User } from '@icon-park/vue-next'
import isMobilePhone from 'validator/es/lib/isMobilePhone' import isMobilePhone from 'validator/es/lib/isMobilePhone'
...@@ -11,6 +11,7 @@ import { useUserStore } from '@/store/modules/user' ...@@ -11,6 +11,7 @@ import { useUserStore } from '@/store/modules/user'
import type { UserInfo } from '@/store/types/user' import type { UserInfo } from '@/store/types/user'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import LanguageSetting from '@/components/language-setting/language-setting.vue'
enum StorageKeyEnum { enum StorageKeyEnum {
smsCountdownTime = 'SMS_COUNTDOWN_TIME', smsCountdownTime = 'SMS_COUNTDOWN_TIME',
...@@ -89,16 +90,18 @@ const emailLoginFormRules = shallowReadonly<FormRules>({ ...@@ -89,16 +90,18 @@ const emailLoginFormRules = shallowReadonly<FormRules>({
code: { required: true, message: t('login_module.please_enter_the_verification_code') }, code: { required: true, message: t('login_module.please_enter_the_verification_code') },
}) })
const phoneNumberAreaOptions = shallowReadonly([ const phoneNumberAreaOptions = computed(() => {
{ return [
label: `+86 ${t('login_module.mainland_china')}`, {
value: '+86', label: `+86 ${t('login_module.mainland_china')}`,
}, value: '+86',
{ },
label: `+852 ${t('login_module.hong_kong_china')}`, {
value: '+852', label: `+852 ${t('login_module.hong_kong_china')}`,
}, value: '+852',
]) },
]
})
const currentPhoneNumberArea = ref<'+86' | '+852'>('+852') const currentPhoneNumberArea = ref<'+86' | '+852'>('+852')
const countdownActive = ref(true) const countdownActive = ref(true)
...@@ -304,6 +307,10 @@ function handleEmailCodeGain() { ...@@ -304,6 +307,10 @@ function handleEmailCodeGain() {
class="bg-px-logo-png z-100 absolute left-[60px] top-[25px] h-[29px] w-[119px] bg-contain bg-center bg-no-repeat" class="bg-px-logo-png z-100 absolute left-[60px] top-[25px] h-[29px] w-[119px] bg-contain bg-center bg-no-repeat"
></div> ></div>
<div class="z-100 absolute right-[60px] top-[25px] w-[140px]">
<LanguageSetting arrow-direction="bottom" btn-bg-color="#f4f5f5" />
</div>
<div class="absolute right-[14%] top-1/2 h-[458px] w-[390px] -translate-y-1/2"> <div class="absolute right-[14%] top-1/2 h-[458px] w-[390px] -translate-y-1/2">
<div <div
class="h-full w-full rounded-[10px] bg-[#fff] px-[29px] shadow-2xl" class="h-full w-full rounded-[10px] bg-[#fff] px-[29px] shadow-2xl"
...@@ -412,9 +419,9 @@ function handleEmailCodeGain() { ...@@ -412,9 +419,9 @@ function handleEmailCodeGain() {
> >
<template #suffix> <template #suffix>
<div class="flex items-center"> <div class="flex items-center">
<div class="mx-[6px] h-[18px] w-[1px] bg-[#868686]"></div> <div class="ml-[6px] mr-[10px] h-[18px] w-[1px] bg-[#868686]"></div>
<div class="w-[90px] text-end"> <div class="text-end">
<n-button <n-button
v-show="!isShowCountdown" v-show="!isShowCountdown"
class="!text-[11px]" class="!text-[11px]"
...@@ -486,9 +493,9 @@ function handleEmailCodeGain() { ...@@ -486,9 +493,9 @@ function handleEmailCodeGain() {
> >
<template #suffix> <template #suffix>
<div class="flex items-center"> <div class="flex items-center">
<div class="mx-[6px] h-[18px] w-[1px] bg-[#868686]"></div> <div class="ml-[6px] mr-[10px] h-[18px] w-[1px] bg-[#868686]"></div>
<div class="w-[90px] text-end"> <div class="text-end">
<n-button <n-button
v-show="!isShowCountdown" v-show="!isShowCountdown"
class="!text-[11px]" class="!text-[11px]"
......
declare namespace I18n { declare namespace I18n {
type LangType = 'zh-HK' | 'zh-CN' type LangType = 'zh-HK' | 'zh-CN' | 'en'
type Schema = { type Schema = {
common_module: { common_module: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment