Commit 22485358 by pangchong

refactor(api): 优化接口请求处理与表单提交方式

- 移除旧的错误信息智能识别和处理逻辑,精简响应码拦截代码
- 新增 postForm 方法支持自动处理 multipart/form-data,优化文件上传逻辑
- 删除下载文件相关的复杂实现,简化请求发送流程
- 在批量翻译功能中添加取消翻译支持,完善用户交互
- 优化编辑器选中节点逻辑,确保滚动时正确设置选中状态
- 调整编辑器工具栏分隔线的样式,提升界面一致性
- 修改搜索翻译模块的警示卡样式,增强视觉效果
- 移除多个无用的 utils 导入,精简编辑器相关代码
- 修正设置面板确认清空并退出弹窗调用,使用标准对象参数
- 新增 Splitter 组件的类型定义,调整相关实现导入方式
parent a05473b7
......@@ -466,7 +466,10 @@ const importPrefs = async () => {
const clearAndLogout = async () => {
try {
await window.$dialog.warning('确认清空并退出', '确定要清空所有本地缓存并退出登录吗?此操作不可逆。')
await window.$dialog.warning({
title: '确认清空并退出',
content: '确定要清空所有本地缓存并退出登录吗?此操作不可逆。'
})
localStorage.clear()
router.push('/login')
window.$message.success('已清空并退出')
......
......@@ -10,7 +10,6 @@ import { setupNaiveDefaults } from '@/plugins/naive-ui-defaults'
// 设置 Naive UI 组件默认属性
setupNaiveDefaults()
import { setupNaiveDiscreteApi } from '@/utils/naive'
const app = createApp(App)
......
import type { Ref } from 'vue'
import type { XmlNode } from '@/types/xmlNode'
import type { EditorState } from './types'
import { createDefaultAttributes, canAddChild } from '@/utils/dtdManager'
import { parseXmlToTree } from '@/utils/xmlParser'
import { useAppStore } from '@/store/app'
import { CHINESE_FIRST_PARA_TAGS } from '@/configs/xmlTags'
......
......@@ -24,7 +24,6 @@
<script setup lang="ts">
import { SettingsOutline } from '@vicons/ionicons5'
import type { XmlNode } from '@/types/xmlNode'
import { getElementAttributes } from '@/utils/dtdManager'
import { useAttributeEditor } from './functionals'
const props = defineProps<{
......
import { useEditorStore } from '@/store/editor'
import type { XmlNode } from '@/types/xmlNode'
import { serializeTreeToXml } from '@/utils/xmlParser'
import { getElementRule, isMixedContentElement } from '@/utils/dtdManager'
import type { EditAreaContextMenuProps } from '../constants'
// 导入共享弹窗状态
......
......@@ -311,6 +311,9 @@ export function useEditorPanel() {
return
}
el.scrollIntoView({ behavior: 'auto', block: 'center' })
if (foundNodeId && foundNodeId !== editorStore.selectedNodeId) {
editorStore.setSelectedNodeId(foundNodeId)
}
return
}
......@@ -344,6 +347,9 @@ export function useEditorPanel() {
}
if (targetEl) {
targetEl.scrollIntoView({ behavior: 'auto', block: 'center' })
if (subFoundId && subFoundId !== editorStore.selectedNodeId) {
editorStore.setSelectedNodeId(subFoundId)
}
}
}, 100)
})
......
......@@ -73,6 +73,22 @@ export function useBatchTranslate() {
}
}
const cancelTranslation = () => {
if (!loading.value) return
if (pollInterval) {
clearInterval(pollInterval)
pollInterval = null
}
loading.value = false
completed.value = false
progress.value = 0
resultFileId.value = ''
resultDownloadUrl.value = ''
progressText.value = '正在准备翻译文档...'
addLog('翻译已取消,返回配置页面')
window.$message.info('已取消翻译')
}
const open = async () => {
showModal.value = true
if (loading.value || completed.value) {
......@@ -80,7 +96,7 @@ export function useBatchTranslate() {
}
reset()
try {
const res = (await service.get('/xml/tags')) as any as { success: boolean; message: string; tags: string[] }
const res = await service.get('/xml/tags')
if (res && res.success && res.tags && res.tags.length > 0) {
availableTags.value = res.tags
// 自动勾选所有获取到的标签
......@@ -98,7 +114,7 @@ export function useBatchTranslate() {
pollInterval = setInterval(async () => {
try {
const statusRes = (await service.get(`/translation/status/${fileId}`)) as any as TranslationStatusResponse
const statusRes = await service.get(`/translation/status/${fileId}`)
if (statusRes) {
if (statusRes.status === 'completed') {
clearInterval(pollInterval)
......@@ -159,28 +175,19 @@ export function useBatchTranslate() {
addLog(`文档序列化完成,大小: ${Math.round(blob.size / 1024)} KB。准备上传...`)
addLog(`请求配置: 模型 = ${form.value.model_name}, 目标标签 = [${form.value.target_tags.join(', ')}]`)
const formData = new FormData()
formData.append('files', blob, 'document.xml')
if (form.value.model_name) {
formData.append('model_name', form.value.model_name)
}
formData.append('search_direction', form.value.search_direction)
formData.append('target_tags', form.value.target_tags.join(','))
if (form.value.suffix) {
formData.append('suffix', form.value.suffix)
}
formData.append('save_to_database', String(form.value.save_to_database))
formData.append('use_parallel_method', String(form.value.use_parallel_method))
const dbPartition = form.value.save_to_database ? form.value.database_partition_name : undefined
if (dbPartition) {
formData.append('database_partition_name', dbPartition)
}
const res = (await service.post('/translate/xml', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})) as any as TranslateXmlResponse
const res = await service.postForm('/translate/xml', {
query_partition_names: import.meta.env.VITE_PARTITION_NAME,
files: [blob, 'document.xml'],
...(form.value.model_name ? { model_name: form.value.model_name } : {}),
search_direction: form.value.search_direction,
target_tags: form.value.target_tags.join(','),
...(form.value.suffix ? { suffix: form.value.suffix } : {}),
save_to_database: form.value.save_to_database,
use_parallel_method: form.value.use_parallel_method,
...(form.value.save_to_database && form.value.database_partition_name
? { database_partition_name: form.value.database_partition_name }
: {})
})
if (res && res.success && res.file_id) {
resultFileId.value = res.file_id
......@@ -259,6 +266,7 @@ export function useBatchTranslate() {
open,
reset,
startTranslation,
cancelTranslation,
downloadResult,
importResult,
logs
......
......@@ -78,8 +78,9 @@
<template #footer>
<div class="flex justify-end gap-3 w-full">
<!-- 翻译中状态:允许隐入后台 -->
<!-- 翻译中状态:允许隐入后台或取消 -->
<template v-if="loading">
<CommonButton type="error" secondary @click="cancelTranslation">取消翻译</CommonButton>
<CommonButton type="primary" secondary @click="showModal = false">后台运行 (隐藏)</CommonButton>
</template>
<!-- 翻译完成状态 -->
......@@ -118,6 +119,7 @@ const {
open,
reset,
startTranslation,
cancelTranslation,
downloadResult,
importResult,
logs
......
import { type ExtractResponse } from '../constants'
import { useEditorStore } from '@/store/editor'
import { serializeTreeToXml } from '@/utils/xmlParser'
import { getBaseOrigin } from '@/utils/render'
export function useExtractTranslate() {
const editorStore = useEditorStore()
......
import { type SearchResult, type SearchResponse, type SearchRequest } from '../constants'
import { serviceManage } from '@/api'
import dayjs from 'dayjs'
export function useSearchTranslate() {
......
......@@ -160,7 +160,7 @@
<div class="flex flex-col gap-4">
<!-- 警示卡片:说明删除操作 -->
<div
class="bg-amber-50 dark:bg-amber-950/20 border border-amber-200 dark:border-amber-900 rounded-lg p-4 text-xs text-amber-800 dark:text-amber-300 flex items-start gap-2"
class="bg-[color-mix(in_srgb,var(--warning-color)_10%,transparent)] border border-[color-mix(in_srgb,var(--warning-color)_25%,transparent)] rounded-lg p-4 text-xs text-warning flex items-start gap-2"
>
<n-icon size="18" class="mt-0.5"><alert-circle-outline /></n-icon>
<div class="flex-1 flex flex-col gap-1">
......
import { useEditorStore, createTableStructure } from '@/store/editor'
import { useAppStore } from '@/store/app/index'
import { canAddChild } from '@/utils/dtdManager'
import type { XmlNode } from '@/types/xmlNode'
/**
......
......@@ -25,7 +25,7 @@
</div>
</div>
<div class="w-[1px] h-4 bg-divider mx-1 flex-shrink-0"></div>
<div class="w-px h-5 flex-shrink-0 mx-2" style="background: #d0d0d0"></div>
<!-- 组 2:插入元素按钮组 -->
<div class="flex items-center gap-0.5 flex-shrink-0">
......@@ -51,9 +51,8 @@
</button>
</div>
<div class="w-[1px] h-4 bg-divider mx-1 flex-shrink-0"></div>
<div class="w-px h-5 flex-shrink-0 mx-3" style="background: #d0d0d0"></div>
<!-- 组 3:翻译辅助组 -->
<div class="flex items-center gap-0.5 flex-shrink-0">
<button
type="button"
......@@ -94,7 +93,7 @@
</button>
</div>
<div class="w-[1px] h-4 bg-divider mx-1 flex-shrink-0"></div>
<div class="w-px h-5 flex-shrink-0 mx-3" style="background: #d0d0d0"></div>
<!-- 组 4:文件管理与导入导出 -->
<div class="flex items-center gap-0.5 flex-shrink-0">
......@@ -136,7 +135,7 @@
</button>
</div>
<div class="w-[1px] h-4 bg-divider mx-1 flex-shrink-0"></div>
<div class="w-px h-5 flex-shrink-0 mx-2" style="background: #d0d0d0"></div>
<!-- 组 5:历史操作 (撤销 / 重做) -->
<div class="flex items-center gap-0.5 flex-shrink-0">
......
import type { FormInst } from 'naive-ui'
import { getElementAttributes, createDefaultAttributes, isTextOnlyElement, isMixedContentElement } from '@/utils/dtdManager'
import { useEditorStore } from '@/store/editor'
import { useAppStore } from '@/store/app'
......
import { useEditorStore } from '@/store/editor'
import type { XmlNode } from '@/types/xmlNode'
import type { BlockedNodeDetail, SafeNodeItem } from '../../../constants'
import { canDeleteChild } from '@/utils/dtdManager'
export function useBatchDeleteConfirmModal(emit: (event: 'confirm') => void) {
const editorStore = useEditorStore()
......
......@@ -19,8 +19,6 @@ import {
import { useEditorStore } from '@/store/editor'
import { useAppStore } from '@/store/app'
import type { XmlNode } from '@/types/xmlNode'
import { serializeTreeToXml } from '@/utils/xmlParser'
import { isMixedContentElement, isTextOnlyElement, sortChildrenByDtd } from '@/utils/dtdManager'
import type { CheckRuleData, InsertMode, FlatNode, TranslationResponse } from '../constants'
import { DOCUMENT_LIKE_TAGS } from '../constants'
import { STRUCTURAL_TAGS, WARNING_LIKE_TAGS, NOTE_AND_REF_TAGS, COLORED_TAGS } from '@/configs/xmlTags'
......
export interface SplitterProps {
width: number
collapsed: boolean
collapseThreshold?: number
defaultWidth?: number
maxRatio?: number
}
export interface SplitterProps {
width: number
collapsed: boolean
collapseThreshold?: number
defaultWidth?: number
maxRatio?: number
}
import { type SplitterProps } from '../constants'
export function useSplitter(
props: SplitterProps,
......
import { useEditorStore } from '@/store/editor'
import { loadDtdSchema, getElementRule } from '@/utils/dtdManager'
import { parseXmlToTreeAsync, serializeTreeToXml } from '@/utils/xmlParser'
import type { XmlNode } from '@/types/xmlNode'
import { DEFAULT_FILE_NAME } from '../constants'
......
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