|  | @@ -1,5 +1,6 @@
 | 
	
		
			
				|  |  |  <script setup lang="ts">
 | 
	
		
			
				|  |  |  import { computed, isReactive, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
 | 
	
		
			
				|  |  | +import { useI18n } from 'vue-i18n'
 | 
	
		
			
				|  |  |  import { Local } from '/@/utils/storage'
 | 
	
		
			
				|  |  |  import {
 | 
	
		
			
				|  |  |  	ArrowDown,
 | 
	
	
		
			
				|  | @@ -46,6 +47,9 @@ import system from '/@/api/system'
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const plugins: Array<MarkdownPlugin<any>> = [EChartsPlugin(), ToolsLoadingPlugin(), TablePlugin(), StructDataPlugin()]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +// 国际化
 | 
	
		
			
				|  |  | +const { t } = useI18n()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  //聊天管理接口
 | 
	
		
			
				|  |  |  // 消息列表
 | 
	
		
			
				|  |  |  const messages = ref<Message[]>([])
 | 
	
	
		
			
				|  | @@ -66,7 +70,7 @@ const dropToUploadZone = ref<HTMLElement>()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const { isOverDropZone } = useDropZone(dropToUploadZone, async (files: File[] | null) => {
 | 
	
		
			
				|  |  |  	if (loadingUpload.value) {
 | 
	
		
			
				|  |  | -		ElMessage.warning('请等待上传完成')
 | 
	
		
			
				|  |  | +		ElMessage.warning(t('message.assistant.status.uploading'))
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	if (files === null || files.length === 0) return
 | 
	
	
		
			
				|  | @@ -166,12 +170,12 @@ const removeAttachment = (index: number) => {
 | 
	
		
			
				|  |  |  const modelOptions = ref<LmConfigInfo[]>([])
 | 
	
		
			
				|  |  |  const modelLabel = computed(() => {
 | 
	
		
			
				|  |  |  	if (!loadingModels.value && selectedModel.value === undefined) {
 | 
	
		
			
				|  |  | -		return '未配置模型'
 | 
	
		
			
				|  |  | +		return t('message.assistant.status.noModelConfigured')
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	const select = modelOptions.value.filter((i) => i.id === selectedModel.value)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if (select.length === 0) {
 | 
	
		
			
				|  |  | -		return '加载中'
 | 
	
		
			
				|  |  | +		return t('message.assistant.status.loading')
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	return select[0].modelName
 | 
	
	
		
			
				|  | @@ -208,7 +212,7 @@ const displayPromptList = computed(() => {
 | 
	
		
			
				|  |  |  	if (customPrompt.value.trim() !== '') {
 | 
	
		
			
				|  |  |  		r.splice(1, 0, {
 | 
	
		
			
				|  |  |  			id: -2,
 | 
	
		
			
				|  |  | -			title: `自定义提示词 (${customPrompt.value.length}) 字`,
 | 
	
		
			
				|  |  | +			title: t('message.assistant.prompt.customPromptWithCount', { count: customPrompt.value.length }),
 | 
	
		
			
				|  |  |  			prompt: customPrompt.value,
 | 
	
		
			
				|  |  |  		})
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -231,12 +235,12 @@ watch(selectPromptId, (newVal) => {
 | 
	
		
			
				|  |  |  })
 | 
	
		
			
				|  |  |  const promptLabel = computed(() => {
 | 
	
		
			
				|  |  |  	if (!loadingPromptList.value && selectPromptId.value === undefined) {
 | 
	
		
			
				|  |  | -		return '未配置提示词'
 | 
	
		
			
				|  |  | +		return t('message.assistant.status.noPromptConfigured')
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	const select = displayPromptList.value.filter((i) => i.id === selectPromptId.value)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if (select.length === 0) {
 | 
	
		
			
				|  |  | -		return '加载中'
 | 
	
		
			
				|  |  | +		return t('message.assistant.status.loading')
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	return select[0].title
 | 
	
	
		
			
				|  | @@ -253,7 +257,7 @@ const { loading: loadingPromptList, doLoading: loadPromptList } = useLoading(asy
 | 
	
		
			
				|  |  |  	if (promptList.value.length !== 0) {
 | 
	
		
			
				|  |  |  		promptList.value.unshift({
 | 
	
		
			
				|  |  |  			id: -1,
 | 
	
		
			
				|  |  | -			title: '不启用提示词',
 | 
	
		
			
				|  |  | +			title: t('message.assistant.prompt.noPrompt'),
 | 
	
		
			
				|  |  |  			prompt: '',
 | 
	
		
			
				|  |  |  		})
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -346,11 +350,11 @@ const replaceMessage = async (index: number) => {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		if (aiMessage?.like === true) {
 | 
	
		
			
				|  |  |  			const confirm = await ElMessageBox({
 | 
	
		
			
				|  |  | -				title: '提示',
 | 
	
		
			
				|  |  | -				message: '替换消息会导致收藏内容被修改,是否继续?',
 | 
	
		
			
				|  |  | +				title: t('message.assistant.messages.prompt'),
 | 
	
		
			
				|  |  | +				message: t('message.assistant.messages.replaceMessageWarning'),
 | 
	
		
			
				|  |  |  				type: 'warning',
 | 
	
		
			
				|  |  | -				confirmButtonText: '确认',
 | 
	
		
			
				|  |  | -				cancelButtonText: '取消',
 | 
	
		
			
				|  |  | +				confirmButtonText: t('message.assistant.buttons.confirmDialog'),
 | 
	
		
			
				|  |  | +				cancelButtonText: t('message.assistant.buttons.cancelDialog'),
 | 
	
		
			
				|  |  |  			})
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			if (!confirm) {
 | 
	
	
		
			
				|  | @@ -509,7 +513,7 @@ ${resp.request.data.replace('\n', '')}
 | 
	
		
			
				|  |  |  				.catch(() => false)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			if (!save_status) {
 | 
	
		
			
				|  |  | -				ElMessage.warning('消息保存失败,切换对话会导致消息记录丢失')
 | 
	
		
			
				|  |  | +				ElMessage.warning(t('message.assistant.messages.messageSaveFailed'))
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			chatInstance.value = undefined
 | 
	
	
		
			
				|  | @@ -536,7 +540,7 @@ const scrollToBottom = () => {
 | 
	
		
			
				|  |  |  // 所有会话
 | 
	
		
			
				|  |  |  const conversations = ref<LmSession[]>([])
 | 
	
		
			
				|  |  |  const displayConversations = computed(() => {
 | 
	
		
			
				|  |  | -	return [{ session_id: -1, title: '收藏夹' }, ...conversations.value]
 | 
	
		
			
				|  |  | +	return [{ session_id: -1, title: t('message.assistant.sidebar.bookmark') }, ...conversations.value]
 | 
	
		
			
				|  |  |  })
 | 
	
		
			
				|  |  |  const { loading: loadConversations, doLoading: doLoadConversations } = useLoading(async () => {
 | 
	
		
			
				|  |  |  	const data: { list: LmSession[]; total: number } = await assist.session
 | 
	
	
		
			
				|  | @@ -625,7 +629,7 @@ const { loading: loadingDeleteConversation, doLoading: deleteConversation } = us
 | 
	
		
			
				|  |  |  	if (!res) {
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	ElMessage.success('删除成功')
 | 
	
		
			
				|  |  | +	ElMessage.success(t('message.assistant.messages.deleteSuccess'))
 | 
	
		
			
				|  |  |  	activeConversationId.value = undefined
 | 
	
		
			
				|  |  |  	messages.value = []
 | 
	
		
			
				|  |  |  	conversations.value = conversations.value.filter((item) => item.session_id !== id)
 | 
	
	
		
			
				|  | @@ -646,15 +650,15 @@ const multiDeleteConversationClear = () => {
 | 
	
		
			
				|  |  |  // 多选删除会话
 | 
	
		
			
				|  |  |  const startMultidelete = async () => {
 | 
	
		
			
				|  |  |  	if (multiDeleteConversationModel.value.selectedConversations.length === 0) {
 | 
	
		
			
				|  |  | -		ElMessage.warning('请选择要删除的会话')
 | 
	
		
			
				|  |  | +		ElMessage.warning(t('message.assistant.messages.selectConversationsToDelete'))
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	const confirm = await ElMessageBox.confirm(
 | 
	
		
			
				|  |  | -		`确定要删除选中的 ${multiDeleteConversationModel.value.selectedConversations.length} 个会话吗?此操作不可恢复!`,
 | 
	
		
			
				|  |  | -		'警告',
 | 
	
		
			
				|  |  | +		t('message.assistant.messages.deleteConfirm', { count: multiDeleteConversationModel.value.selectedConversations.length }),
 | 
	
		
			
				|  |  | +		t('message.assistant.messages.warning'),
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  | -			confirmButtonText: '确定',
 | 
	
		
			
				|  |  | -			cancelButtonText: '取消',
 | 
	
		
			
				|  |  | +			confirmButtonText: t('message.assistant.buttons.confirmDialog'),
 | 
	
		
			
				|  |  | +			cancelButtonText: t('message.assistant.buttons.cancelDialog'),
 | 
	
		
			
				|  |  |  			type: 'error',
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	)
 | 
	
	
		
			
				|  | @@ -672,7 +676,7 @@ const startMultidelete = async () => {
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	ElMessage.success('删除成功')
 | 
	
		
			
				|  |  | +	ElMessage.success(t('message.assistant.messages.deleteSuccess'))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	await nextTick()
 | 
	
		
			
				|  |  |  	conversations.value = conversations.value.filter((item) => !multiDeleteConversationModel.value.selectedConversations.includes(item.session_id))
 | 
	
	
		
			
				|  | @@ -681,7 +685,7 @@ const startMultidelete = async () => {
 | 
	
		
			
				|  |  |  // 创建新对话
 | 
	
		
			
				|  |  |  const { loading: creatingConversation, doLoading: createConversationAndSetItActive } = useLoading(async () => {
 | 
	
		
			
				|  |  |  	// 调用API创建新对话,默认标题为"新对话"
 | 
	
		
			
				|  |  | -	const { id } = await assist.session.add('新对话')
 | 
	
		
			
				|  |  | +	const { id } = await assist.session.add(t('message.assistant.sidebar.createConversation'))
 | 
	
		
			
				|  |  |  	// 刷新对话列表
 | 
	
		
			
				|  |  |  	await doLoadConversations()
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -900,7 +904,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  		<!-- 左侧会话列表 -->
 | 
	
		
			
				|  |  |  		<el-aside width="300px" class="chat-sidebar">
 | 
	
		
			
				|  |  |  			<div class="sidebar-header">
 | 
	
		
			
				|  |  | -				<h3>对话历史</h3>
 | 
	
		
			
				|  |  | +				<h3>{{ t('message.assistant.sidebar.conversationHistory') }}</h3>
 | 
	
		
			
				|  |  |  				<el-dropdown v-model="showSettingsPanel" trigger="click" placement="bottom-end">
 | 
	
		
			
				|  |  |  					<el-button round :icon="EleSetting" size="small">
 | 
	
		
			
				|  |  |  						<el-icon class="el-icon--right">
 | 
	
	
		
			
				|  | @@ -911,18 +915,18 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  						<el-dropdown-menu v-if="!multiDeleteConversationModel.visible">
 | 
	
		
			
				|  |  |  							<el-dropdown-item class="settings-item">
 | 
	
		
			
				|  |  |  								<div class="settings-row">
 | 
	
		
			
				|  |  | -									<span class="settings-label">新对话自动记录工具调用</span>
 | 
	
		
			
				|  |  | +									<span class="settings-label">{{ t('message.assistant.settings.autoRecordToolCalls') }}</span>
 | 
	
		
			
				|  |  |  									<el-switch v-model="showToolCalls" size="small" />
 | 
	
		
			
				|  |  |  								</div>
 | 
	
		
			
				|  |  |  							</el-dropdown-item>
 | 
	
		
			
				|  |  |  							<el-dropdown-item @click="redirectToModelManager">
 | 
	
		
			
				|  |  | -								<span class="settings-label">模型管理</span>
 | 
	
		
			
				|  |  | +								<span class="settings-label">{{ t('message.assistant.settings.modelManagement') }}</span>
 | 
	
		
			
				|  |  |  							</el-dropdown-item>
 | 
	
		
			
				|  |  |  							<el-dropdown-item @click="promptDialogVisible = true">
 | 
	
		
			
				|  |  | -								<span class="settings-label">提示词管理</span>
 | 
	
		
			
				|  |  | +								<span class="settings-label">{{ t('message.assistant.settings.promptManagement') }}</span>
 | 
	
		
			
				|  |  |  							</el-dropdown-item>
 | 
	
		
			
				|  |  |  							<el-dropdown-item @click="multiDeleteConversationModel.visible = true">
 | 
	
		
			
				|  |  | -								<span class="settings-label">对话管理</span>
 | 
	
		
			
				|  |  | +								<span class="settings-label">{{ t('message.assistant.settings.conversationManagement') }}</span>
 | 
	
		
			
				|  |  |  							</el-dropdown-item>
 | 
	
		
			
				|  |  |  						</el-dropdown-menu>
 | 
	
		
			
				|  |  |  						<el-dropdown-menu v-else>
 | 
	
	
		
			
				|  | @@ -930,13 +934,13 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  								<el-icon>
 | 
	
		
			
				|  |  |  									<Close />
 | 
	
		
			
				|  |  |  								</el-icon>
 | 
	
		
			
				|  |  | -								<span>取消选择</span>
 | 
	
		
			
				|  |  | +								<span>{{ t('message.assistant.settings.cancelSelection') }}</span>
 | 
	
		
			
				|  |  |  							</el-dropdown-item>
 | 
	
		
			
				|  |  |  							<el-dropdown-item @click="startMultidelete">
 | 
	
		
			
				|  |  |  								<el-icon>
 | 
	
		
			
				|  |  |  									<Delete />
 | 
	
		
			
				|  |  |  								</el-icon>
 | 
	
		
			
				|  |  | -								<span>删除选中</span>
 | 
	
		
			
				|  |  | +								<span>{{ t('message.assistant.settings.deleteSelected') }}</span>
 | 
	
		
			
				|  |  |  							</el-dropdown-item>
 | 
	
		
			
				|  |  |  						</el-dropdown-menu>
 | 
	
		
			
				|  |  |  					</template>
 | 
	
	
		
			
				|  | @@ -977,7 +981,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  						<!-- 非编辑状态的三点菜单 -->
 | 
	
		
			
				|  |  |  						<template v-if="editingConversationId !== conv.session_id">
 | 
	
		
			
				|  |  |  							<el-dropdown trigger="click" placement="bottom-end" @click.stop>
 | 
	
		
			
				|  |  | -								<el-button type="primary" size="small" :icon="MoreFilled" class="action-btn more-btn" title="更多操作" plain circle @click.stop />
 | 
	
		
			
				|  |  | +								<el-button type="primary" size="small" :icon="MoreFilled" class="action-btn more-btn" :title="t('message.assistant.buttons.more')" plain circle @click.stop />
 | 
	
		
			
				|  |  |  								<template #dropdown>
 | 
	
		
			
				|  |  |  									<el-dropdown-menu>
 | 
	
		
			
				|  |  |  										<el-dropdown-item @click="exportConversation(conv.session_id)">
 | 
	
	
		
			
				|  | @@ -985,13 +989,13 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  											<el-icon v-else>
 | 
	
		
			
				|  |  |  												<Download />
 | 
	
		
			
				|  |  |  											</el-icon>
 | 
	
		
			
				|  |  | -											<span>导出</span>
 | 
	
		
			
				|  |  | +											<span>{{ t('message.assistant.buttons.export') }}</span>
 | 
	
		
			
				|  |  |  										</el-dropdown-item>
 | 
	
		
			
				|  |  |  										<el-dropdown-item @click="editSummary(conv.session_id)">
 | 
	
		
			
				|  |  |  											<el-icon>
 | 
	
		
			
				|  |  |  												<Edit />
 | 
	
		
			
				|  |  |  											</el-icon>
 | 
	
		
			
				|  |  | -											<span>编辑</span>
 | 
	
		
			
				|  |  | +											<span>{{ t('message.assistant.buttons.edit') }}</span>
 | 
	
		
			
				|  |  |  										</el-dropdown-item>
 | 
	
		
			
				|  |  |  										<el-dropdown-item
 | 
	
		
			
				|  |  |  											@click="deleteConversation(conv.session_id)"
 | 
	
	
		
			
				|  | @@ -1000,7 +1004,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  											<el-icon>
 | 
	
		
			
				|  |  |  												<Delete />
 | 
	
		
			
				|  |  |  											</el-icon>
 | 
	
		
			
				|  |  | -											<span>删除</span>
 | 
	
		
			
				|  |  | +											<span>{{ t('message.assistant.buttons.delete') }}</span>
 | 
	
		
			
				|  |  |  										</el-dropdown-item>
 | 
	
		
			
				|  |  |  									</el-dropdown-menu>
 | 
	
		
			
				|  |  |  								</template>
 | 
	
	
		
			
				|  | @@ -1016,7 +1020,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  								:loading="loadingConfirmEdit"
 | 
	
		
			
				|  |  |  								@click.stop="confirmEdit(conv.session_id)"
 | 
	
		
			
				|  |  |  								class="action-btn confirm-btn"
 | 
	
		
			
				|  |  | -								title="确认修改"
 | 
	
		
			
				|  |  | +								:title="t('message.assistant.buttons.confirm')"
 | 
	
		
			
				|  |  |  								plain
 | 
	
		
			
				|  |  |  								circle
 | 
	
		
			
				|  |  |  							/>
 | 
	
	
		
			
				|  | @@ -1025,7 +1029,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  								size="small"
 | 
	
		
			
				|  |  |  								@click.stop="cancelEdit(conv.session_id)"
 | 
	
		
			
				|  |  |  								class="action-btn cancel-btn"
 | 
	
		
			
				|  |  | -								title="取消编辑"
 | 
	
		
			
				|  |  | +								:title="t('message.assistant.buttons.cancel')"
 | 
	
		
			
				|  |  |  								plain
 | 
	
		
			
				|  |  |  								circle
 | 
	
		
			
				|  |  |  							>
 | 
	
	
		
			
				|  | @@ -1044,7 +1048,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  				@click="createConversationAndSetItActive"
 | 
	
		
			
				|  |  |  				:loading="creatingConversation"
 | 
	
		
			
				|  |  |  				:disabled="isConversationActive"
 | 
	
		
			
				|  |  | -				>创建对话
 | 
	
		
			
				|  |  | +				>{{ t('message.assistant.sidebar.createConversation') }}
 | 
	
		
			
				|  |  |  			</el-button>
 | 
	
		
			
				|  |  |  		</el-aside>
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1066,7 +1070,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  											<span class="dot"></span>
 | 
	
		
			
				|  |  |  											<span class="dot"></span>
 | 
	
		
			
				|  |  |  										</div>
 | 
	
		
			
				|  |  | -										<span class="loading-text">AI正在思考中...</span>
 | 
	
		
			
				|  |  | +										<span class="loading-text">{{ t('message.assistant.status.aiThinking') }}</span>
 | 
	
		
			
				|  |  |  									</div>
 | 
	
		
			
				|  |  |  								</div>
 | 
	
		
			
				|  |  |  								<div class="ai-message-actions">
 | 
	
	
		
			
				|  | @@ -1105,7 +1109,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  											:key="file.path"
 | 
	
		
			
				|  |  |  											class="file-item"
 | 
	
		
			
				|  |  |  											@click="openFile(file.full_path)"
 | 
	
		
			
				|  |  | -											:title="`点击打开: ${file.name}`"
 | 
	
		
			
				|  |  | +											:title="t('message.assistant.file.clickToOpen', { name: file.name })"
 | 
	
		
			
				|  |  |  										>
 | 
	
		
			
				|  |  |  											<el-icon class="file-icon">
 | 
	
		
			
				|  |  |  												<Document v-if="file.type.includes('text') || file.type.includes('document')" />
 | 
	
	
		
			
				|  | @@ -1128,7 +1132,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  										plain
 | 
	
		
			
				|  |  |  										:disabled="isConversationActive"
 | 
	
		
			
				|  |  |  									>
 | 
	
		
			
				|  |  | -										重试
 | 
	
		
			
				|  |  | +										{{ t('message.assistant.buttons.retry') }}
 | 
	
		
			
				|  |  |  									</el-button>
 | 
	
		
			
				|  |  |  								</div>
 | 
	
		
			
				|  |  |  							</div>
 | 
	
	
		
			
				|  | @@ -1147,27 +1151,27 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  							</el-icon>
 | 
	
		
			
				|  |  |  						</div>
 | 
	
		
			
				|  |  |  						<div class="empty-text">
 | 
	
		
			
				|  |  | -							<h2 class="empty-title">暂无收藏消息</h2>
 | 
	
		
			
				|  |  | -							<p class="empty-description">您还没有收藏任何对话消息</p>
 | 
	
		
			
				|  |  | +							<h2 class="empty-title">{{ t('message.assistant.empty.noBookmarks') }}</h2>
 | 
	
		
			
				|  |  | +							<p class="empty-description">{{ t('message.assistant.empty.noBookmarksDescription') }}</p>
 | 
	
		
			
				|  |  |  						</div>
 | 
	
		
			
				|  |  |  						<div class="empty-tips">
 | 
	
		
			
				|  |  |  							<div class="tip-item">
 | 
	
		
			
				|  |  |  								<el-icon color="#409eff">
 | 
	
		
			
				|  |  |  									<InfoFilled />
 | 
	
		
			
				|  |  |  								</el-icon>
 | 
	
		
			
				|  |  | -								<span>在对话中点击 ⭐ 按钮即可收藏消息</span>
 | 
	
		
			
				|  |  | +								<span>{{ t('message.assistant.empty.bookmarkTip1') }}</span>
 | 
	
		
			
				|  |  |  							</div>
 | 
	
		
			
				|  |  |  							<div class="tip-item">
 | 
	
		
			
				|  |  |  								<el-icon color="#67c23a">
 | 
	
		
			
				|  |  |  									<Search />
 | 
	
		
			
				|  |  |  								</el-icon>
 | 
	
		
			
				|  |  | -								<span>收藏的消息支持关键词搜索</span>
 | 
	
		
			
				|  |  | +								<span>{{ t('message.assistant.empty.bookmarkTip2') }}</span>
 | 
	
		
			
				|  |  |  							</div>
 | 
	
		
			
				|  |  |  							<div class="tip-item">
 | 
	
		
			
				|  |  |  								<el-icon color="#e6a23c">
 | 
	
		
			
				|  |  |  									<Collection />
 | 
	
		
			
				|  |  |  								</el-icon>
 | 
	
		
			
				|  |  | -								<span>收藏消息会保存在云端,永不丢失</span>
 | 
	
		
			
				|  |  | +								<span>{{ t('message.assistant.empty.bookmarkTip3') }}</span>
 | 
	
		
			
				|  |  |  							</div>
 | 
	
		
			
				|  |  |  						</div>
 | 
	
		
			
				|  |  |  					</div>
 | 
	
	
		
			
				|  | @@ -1180,18 +1184,18 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  							</el-icon>
 | 
	
		
			
				|  |  |  						</div>
 | 
	
		
			
				|  |  |  						<div class="empty-text">
 | 
	
		
			
				|  |  | -							<h2 class="empty-title">开始新的对话</h2>
 | 
	
		
			
				|  |  | +							<h2 class="empty-title">{{ t('message.assistant.empty.startNewConversation') }}</h2>
 | 
	
		
			
				|  |  |  						</div>
 | 
	
		
			
				|  |  |  						<div class="example-questions">
 | 
	
		
			
				|  |  | -							<h4>试试这些问题:</h4>
 | 
	
		
			
				|  |  | +							<h4>{{ t('message.assistant.empty.tryTheseQuestions') }}</h4>
 | 
	
		
			
				|  |  |  							<div class="question-tags">
 | 
	
		
			
				|  |  | -								<el-tag class="question-tag" @click="inputMessage = '帮我查看设备运行状态和告警信息'" type="info">
 | 
	
		
			
				|  |  | -									帮我查看设备运行状态和告警信息
 | 
	
		
			
				|  |  | +								<el-tag class="question-tag" @click="inputMessage = t('message.assistant.examples.deviceStatus')" type="info">
 | 
	
		
			
				|  |  | +									{{ t('message.assistant.examples.deviceStatus') }}
 | 
	
		
			
				|  |  |  								</el-tag>
 | 
	
		
			
				|  |  | -								<el-tag class="question-tag" @click="inputMessage = '分析用户权限配置和角色分配情况'" type="success">
 | 
	
		
			
				|  |  | -									分析用户权限配置和角色分配情况
 | 
	
		
			
				|  |  | +								<el-tag class="question-tag" @click="inputMessage = t('message.assistant.examples.userPermissions')" type="success">
 | 
	
		
			
				|  |  | +									{{ t('message.assistant.examples.userPermissions') }}
 | 
	
		
			
				|  |  |  								</el-tag>
 | 
	
		
			
				|  |  | -								<el-tag class="question-tag" @click="inputMessage = '检查系统性能和在线用户统计'" type="warning"> 检查系统性能和在线用户统计 </el-tag>
 | 
	
		
			
				|  |  | +								<el-tag class="question-tag" @click="inputMessage = t('message.assistant.examples.systemPerformance')" type="warning"> {{ t('message.assistant.examples.systemPerformance') }} </el-tag>
 | 
	
		
			
				|  |  |  							</div>
 | 
	
		
			
				|  |  |  						</div>
 | 
	
		
			
				|  |  |  					</div>
 | 
	
	
		
			
				|  | @@ -1226,8 +1230,8 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  								</div>
 | 
	
		
			
				|  |  |  								<!-- 无附件时的提示信息 -->
 | 
	
		
			
				|  |  |  								<div v-if="selectedFiles.length === 0" class="attachment-hint">
 | 
	
		
			
				|  |  | -									<span v-if="!isOverDropZone">点击右侧+上传文件</span>
 | 
	
		
			
				|  |  | -									<span v-else>松开鼠标上传文件...</span>
 | 
	
		
			
				|  |  | +									<span v-if="!isOverDropZone">{{ t('message.assistant.status.clickToUpload') }}</span>
 | 
	
		
			
				|  |  | +									<span v-else>{{ t('message.assistant.status.uploadProgress') }}</span>
 | 
	
		
			
				|  |  |  								</div>
 | 
	
		
			
				|  |  |  							</div>
 | 
	
		
			
				|  |  |  						</el-scrollbar>
 | 
	
	
		
			
				|  | @@ -1242,7 +1246,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  					<textarea
 | 
	
		
			
				|  |  |  						v-model="inputMessage"
 | 
	
		
			
				|  |  |  						class="large-textarea"
 | 
	
		
			
				|  |  | -						placeholder="请输入您的问题..."
 | 
	
		
			
				|  |  | +						:placeholder="t('message.assistant.placeholders.inputQuestion')"
 | 
	
		
			
				|  |  |  						@keydown.enter.ctrl="sendMessage"
 | 
	
		
			
				|  |  |  						@keydown.enter.meta="sendMessage"
 | 
	
		
			
				|  |  |  						:disabled="isConversationActive"
 | 
	
	
		
			
				|  | @@ -1254,7 +1258,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  						<!-- 左下角按钮组 -->
 | 
	
		
			
				|  |  |  						<div class="left-controls">
 | 
	
		
			
				|  |  |  							<!-- 模型选择按钮 -->
 | 
	
		
			
				|  |  | -							<el-dropdown trigger="click" placement="top-start" :disabled="loadingModels || modelLabel == '未配置模型'">
 | 
	
		
			
				|  |  | +							<el-dropdown trigger="click" placement="top-start" :disabled="loadingModels || modelLabel == t('message.assistant.status.noModelConfigured')">
 | 
	
		
			
				|  |  |  								<button class="control-btn model-btn">
 | 
	
		
			
				|  |  |  									<el-icon>
 | 
	
		
			
				|  |  |  										<Setting v-if="!loadingModels" />
 | 
	
	
		
			
				|  | @@ -1277,7 +1281,7 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  							</el-dropdown>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  							<!-- 词嵌入模型选择按钮 -->
 | 
	
		
			
				|  |  | -							<el-dropdown trigger="click" placement="top-start" :disabled="loadingModels || promptLabel == '未配置提示词'">
 | 
	
		
			
				|  |  | +							<el-dropdown trigger="click" placement="top-start" :disabled="loadingModels || promptLabel == t('message.assistant.status.noPromptConfigured')">
 | 
	
		
			
				|  |  |  								<button class="control-btn embedding-model-btn">
 | 
	
		
			
				|  |  |  									<el-icon>
 | 
	
		
			
				|  |  |  										<CopyDocument v-if="!loadingPromptList" />
 | 
	
	
		
			
				|  | @@ -1326,19 +1330,19 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  					<div class="bookmark-search">
 | 
	
		
			
				|  |  |  						<el-input
 | 
	
		
			
				|  |  |  							v-model="bookmarkOptions.keyWord"
 | 
	
		
			
				|  |  | -							placeholder="搜索收藏的消息..."
 | 
	
		
			
				|  |  | +							:placeholder="t('message.assistant.placeholders.searchBookmarks')"
 | 
	
		
			
				|  |  |  							:prefix-icon="Search"
 | 
	
		
			
				|  |  |  							clearable
 | 
	
		
			
				|  |  |  							@keydown.enter="handleBookmarkSearch"
 | 
	
		
			
				|  |  |  							@clear="handleBookmarkReset"
 | 
	
		
			
				|  |  |  							style="width: 300px"
 | 
	
		
			
				|  |  |  						/>
 | 
	
		
			
				|  |  | -						<el-button type="primary" :icon="Search" @click="handleBookmarkSearch" :loading="loadingMessage"> 搜索 </el-button>
 | 
	
		
			
				|  |  | +						<el-button type="primary" :icon="Search" @click="handleBookmarkSearch" :loading="loadingMessage"> {{ t('message.assistant.buttons.search') }} </el-button>
 | 
	
		
			
				|  |  |  					</div>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  					<!-- 分页和重置 -->
 | 
	
		
			
				|  |  |  					<div class="bookmark-pagination">
 | 
	
		
			
				|  |  | -						<el-button @click="handleBookmarkReset" :loading="loadingMessage"> 重置</el-button>
 | 
	
		
			
				|  |  | +						<el-button @click="handleBookmarkReset" :loading="loadingMessage"> {{ t('message.assistant.buttons.reset') }} </el-button>
 | 
	
		
			
				|  |  |  						<el-pagination
 | 
	
		
			
				|  |  |  							v-model:current-page="bookmarkOptions.pageNum"
 | 
	
		
			
				|  |  |  							v-model:page-size="bookmarkOptions.pageSize"
 | 
	
	
		
			
				|  | @@ -1358,22 +1362,22 @@ const isSystemLoading = computed(()=> {
 | 
	
		
			
				|  |  |  		</el-main>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		<!-- 提示词管理对话框 -->
 | 
	
		
			
				|  |  | -		<el-dialog v-model="promptDialogVisible" title="提示词管理" width="60%" append-to-body>
 | 
	
		
			
				|  |  | +		<el-dialog v-model="promptDialogVisible" :title="t('message.assistant.prompt.management')" width="60%" append-to-body>
 | 
	
		
			
				|  |  |  			<div class="prompt-dialog-content">
 | 
	
		
			
				|  |  |  				<div class="prompt-input-section">
 | 
	
		
			
				|  |  | -					<h4>自定义提示词</h4>
 | 
	
		
			
				|  |  | +					<h4>{{ t('message.assistant.prompt.customPrompt') }}</h4>
 | 
	
		
			
				|  |  |  					<el-input
 | 
	
		
			
				|  |  |  						v-model="customPrompt"
 | 
	
		
			
				|  |  |  						type="textarea"
 | 
	
		
			
				|  |  |  						:autosize="{ minRows: 12, maxRows: 24 }"
 | 
	
		
			
				|  |  | -						placeholder="在此编写你的提示词...(将用于本次会话的系统提示)"
 | 
	
		
			
				|  |  | +						:placeholder="t('message.assistant.placeholders.customPrompt')"
 | 
	
		
			
				|  |  |  					/>
 | 
	
		
			
				|  |  |  				</div>
 | 
	
		
			
				|  |  |  			</div>
 | 
	
		
			
				|  |  |  			<template #footer>
 | 
	
		
			
				|  |  |  				<div class="dialog-footer">
 | 
	
		
			
				|  |  | -					<el-button @click="promptDialogVisible = false">取 消</el-button>
 | 
	
		
			
				|  |  | -					<el-button type="primary" @click="promptDialogVisible = false">确 认</el-button>
 | 
	
		
			
				|  |  | +					<el-button @click="promptDialogVisible = false">{{ t('message.assistant.buttons.cancelDialog') }}</el-button>
 | 
	
		
			
				|  |  | +					<el-button type="primary" @click="promptDialogVisible = false">{{ t('message.assistant.buttons.confirmDialog') }}</el-button>
 | 
	
		
			
				|  |  |  				</div>
 | 
	
		
			
				|  |  |  			</template>
 | 
	
		
			
				|  |  |  		</el-dialog>
 |