feat(steady): 重构稳态校验功能并优化界面布局
- 更新 API 接口路径从 /steady/data-view/checksquare/* 到 /steady/checksquare/* - 修改校验任务状态枚举值 FAILED 为 FAIL 并更新相关处理逻辑 - 移除缺失率和最大连续缺失分钟数字段,简化数据完整性计算 - 添加新的创建结果面板组件 ChecksquareCreateResultPanel.vue - 调整创建对话框布局,采用两行搜索控件设计 - 更新任务表头部按钮文字为"新增"并调整搜索列配置为5列 - 修改详情面板显示开始时间和结束时间字段 - 重构工作台界面布局,使用 flex 布局替代 grid 布局 - 更新设备类型相关 API 接口和数据结构定义 - 添加设备类型字典常量并更新路由配置 - 优化搜索表单展开收起逻辑的计算方式 - 调整创建流程不再轮询获取任务详情,改为直接显示摘要信息 - 更新数据完整性格式化函数参数和调用方式 - 修改创建对话框样式类名和尺寸配置 - 添加设备类型管理相关的接口定义和实现方法
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
<section class="mapping-panel config-panel">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<h2 class="panel-title">人工索引配置</h2>
|
||||
<p class="panel-description">展示现有的人工索引配置,并允许继续编辑。</p>
|
||||
<div class="panel-title-tabs">
|
||||
<span class="panel-title-tab">索引配置</span>
|
||||
</div>
|
||||
<p v-if="showDescription" class="panel-description">展示现有的索引配置,并允许继续编辑。</p>
|
||||
</div>
|
||||
<div class="panel-actions">
|
||||
<el-button
|
||||
@@ -23,7 +25,7 @@
|
||||
:disabled="!canGenerate"
|
||||
@click="emit('generate')"
|
||||
>
|
||||
生成JSON映射
|
||||
JSON映射
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,7 +41,7 @@
|
||||
:disabled="isSubmitting"
|
||||
:rows="18"
|
||||
resize="none"
|
||||
placeholder="人工索引配置完成后,这里会自动回填索引配置,仍可继续直接编辑。"
|
||||
placeholder="索引配置完成后,这里会自动回填索引配置,仍可继续直接编辑。"
|
||||
@update:model-value="value => emit('update:indexSelectionJson', String(value || ''))"
|
||||
/>
|
||||
</div>
|
||||
@@ -56,7 +58,7 @@ defineOptions({
|
||||
name: 'MappingConfigPanel'
|
||||
})
|
||||
|
||||
defineProps<{
|
||||
withDefaults(defineProps<{
|
||||
indexSelectionJson: string
|
||||
isSubmitting: boolean
|
||||
isGenerating: boolean
|
||||
@@ -68,7 +70,10 @@ defineProps<{
|
||||
canConfirm: boolean
|
||||
hasDefaultJson: boolean
|
||||
emptyDescription: string
|
||||
}>()
|
||||
showDescription?: boolean
|
||||
}>(), {
|
||||
showDescription: true
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:indexSelectionJson', value: string): void
|
||||
@@ -110,12 +115,34 @@ const emit = defineEmits<{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
color: #1f2937;
|
||||
.panel-actions :deep(.el-button + .el-button) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.panel-title-tabs {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--el-border-color-light);
|
||||
}
|
||||
|
||||
.panel-title-tab {
|
||||
position: relative;
|
||||
height: 36px;
|
||||
padding: 0 2px;
|
||||
font-size: 13px;
|
||||
line-height: 36px;
|
||||
color: var(--el-color-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.panel-title-tab::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
height: 2px;
|
||||
background-color: var(--el-color-primary);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.panel-description {
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
<section class="mapping-panel">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<h2 class="panel-title">ICD 解析</h2>
|
||||
<p class="panel-description">选择 ICD 文件后仅保存当前文件,点击“解析 ICD”后才会向后台请求候选数据。</p>
|
||||
<div class="panel-title-tabs">
|
||||
<span class="panel-title-tab">{{ panelTitle }}</span>
|
||||
</div>
|
||||
<p v-if="showDescription" class="panel-description">选择 ICD 文件后仅保存当前文件,点击“解析 ICD”后才会向后台请求候选数据。</p>
|
||||
</div>
|
||||
<el-tag :type="requestStatusTagType" effect="light">{{ requestStatusText }}</el-tag>
|
||||
<el-tag v-if="requestStatusText" :type="requestStatusTagType" effect="light">{{ requestStatusText }}</el-tag>
|
||||
</div>
|
||||
|
||||
<div class="panel-content">
|
||||
@@ -19,7 +21,6 @@
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
:icon="FolderOpened"
|
||||
:disabled="isSubmitting"
|
||||
@click="openIcdFilePicker"
|
||||
@@ -43,7 +44,14 @@
|
||||
>
|
||||
解析 ICD
|
||||
</el-button>
|
||||
<el-button type="danger" plain :icon="Delete" :disabled="!canReset || isSubmitting" @click="emit('reset')">
|
||||
<el-button
|
||||
v-if="showResetButton"
|
||||
type="danger"
|
||||
plain
|
||||
:icon="Delete"
|
||||
:disabled="!canReset || isSubmitting"
|
||||
@click="emit('reset')"
|
||||
>
|
||||
清空
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -61,16 +69,23 @@ defineOptions({
|
||||
|
||||
type TagType = 'success' | 'warning' | 'info' | 'primary' | 'danger'
|
||||
|
||||
defineProps<{
|
||||
withDefaults(defineProps<{
|
||||
selectedIcdFileName: string
|
||||
isSubmitting: boolean
|
||||
isParsing: boolean
|
||||
icdFileAccept: string
|
||||
requestStatusText: string
|
||||
requestStatusTagType: TagType
|
||||
requestStatusText?: string
|
||||
requestStatusTagType?: TagType
|
||||
showDescription?: boolean
|
||||
showResetButton?: boolean
|
||||
panelTitle?: string
|
||||
canParse: boolean
|
||||
canReset: boolean
|
||||
}>()
|
||||
}>(), {
|
||||
showDescription: true,
|
||||
showResetButton: true,
|
||||
panelTitle: 'ICD 解析'
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'file-change', value: Event): void
|
||||
@@ -106,12 +121,30 @@ const openIcdFilePicker = () => {
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
color: #1f2937;
|
||||
.panel-title-tabs {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--el-border-color-light);
|
||||
}
|
||||
|
||||
.panel-title-tab {
|
||||
position: relative;
|
||||
height: 36px;
|
||||
padding: 0 2px;
|
||||
font-size: 13px;
|
||||
line-height: 36px;
|
||||
color: var(--el-color-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.panel-title-tab::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
height: 2px;
|
||||
background-color: var(--el-color-primary);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.panel-description {
|
||||
|
||||
@@ -2,10 +2,20 @@
|
||||
<section class="mapping-panel">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<h2 class="panel-title">映射结果</h2>
|
||||
<p class="panel-description">展示和导出JSON与XML的映射结果,以及JSON的映射序列配置。</p>
|
||||
<div class="panel-title-tabs">
|
||||
<span class="panel-title-tab">映射结果</span>
|
||||
</div>
|
||||
<p v-if="showDescription" class="panel-description">展示和导出JSON与XML的映射结果,以及JSON的映射序列配置。</p>
|
||||
</div>
|
||||
<div class="panel-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Setting"
|
||||
:disabled="!canConfigureSequence"
|
||||
@click="openSequenceDialog"
|
||||
>
|
||||
序列配置
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Connection"
|
||||
@@ -13,12 +23,20 @@
|
||||
:disabled="!canGenerateXmlMapping"
|
||||
@click="emit('generate-xml-mapping')"
|
||||
>
|
||||
生成XML映射
|
||||
XML映射
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showIcdCheckAction"
|
||||
type="primary"
|
||||
:icon="CircleCheck"
|
||||
:disabled="!canSaveIcdCheckResult"
|
||||
@click="emit('icd-check')"
|
||||
>
|
||||
ICD校验
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showSaveIcdCheckResult"
|
||||
type="primary"
|
||||
plain
|
||||
:icon="Finished"
|
||||
:loading="isSavingIcdCheckResult"
|
||||
:disabled="!canSaveIcdCheckResult"
|
||||
@@ -26,42 +44,31 @@
|
||||
>
|
||||
{{ saveIcdCheckResultText }}
|
||||
</el-button>
|
||||
<div class="export-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
:icon="Download"
|
||||
:disabled="!canExportActiveMapping"
|
||||
@click="emit('export-mapping', activeExportType)"
|
||||
>
|
||||
{{ exportButtonText }}
|
||||
</el-button>
|
||||
<el-dropdown trigger="click" :disabled="!canExportAnyMapping" @command="handleExportCommand">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
class="export-menu-button"
|
||||
:icon="ArrowDown"
|
||||
:disabled="!canExportAnyMapping"
|
||||
/>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="json" :disabled="!canExportJsonMapping">
|
||||
导出JSON映射
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="xml" :disabled="!canExportXmlMapping">
|
||||
导出XML映射
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<el-tag :type="responseStatusTagType" effect="light">{{ responseStatusText }}</el-tag>
|
||||
<el-tag v-if="responseStatusText" :type="responseStatusTagType" effect="light">
|
||||
{{ responseStatusText }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-content panel-content--fixed">
|
||||
<div class="panel-section result-card grow-card preview-tab-section">
|
||||
<div class="mapping-preview-tabs">
|
||||
<button
|
||||
type="button"
|
||||
:class="['panel-title-tab', { 'is-active': activeTabProxy === 'json' }]"
|
||||
@click="activeTabProxy = 'json'"
|
||||
>
|
||||
JSON映射
|
||||
</button>
|
||||
<button
|
||||
v-if="showXmlMappingTab"
|
||||
type="button"
|
||||
:class="['panel-title-tab', { 'is-active': activeTabProxy === 'xml' }]"
|
||||
@click="activeTabProxy = 'xml'"
|
||||
>
|
||||
XML映射
|
||||
</button>
|
||||
</div>
|
||||
<el-tabs v-model="activeTabProxy" class="preview-tabs">
|
||||
<el-tab-pane label="JSON映射" name="json">
|
||||
<div class="mapping-json-scroll">
|
||||
@@ -71,16 +78,6 @@
|
||||
:meta-text="mappingMetaText"
|
||||
>
|
||||
<template #actions>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
:icon="Setting"
|
||||
:disabled="!mappingJsonPreview"
|
||||
@click="openSequenceDialog"
|
||||
>
|
||||
序列配置
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@@ -91,27 +88,49 @@
|
||||
{{ problemButtonText }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template #trailing-actions>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
:icon="Download"
|
||||
:disabled="!canExportJsonMapping"
|
||||
@click="emit('export-mapping', 'json')"
|
||||
>
|
||||
下载JSON映射
|
||||
</el-button>
|
||||
</template>
|
||||
</JsonMappingTree>
|
||||
<el-empty v-else description="当前返回未包含 mappingJson" />
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="showXmlMappingTab" label="XML映射" name="xml">
|
||||
<div class="mapping-json-scroll">
|
||||
<div class="match-result-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
:icon="Document"
|
||||
:disabled="!methodDescribe"
|
||||
@click="matchResultDialogVisible = true"
|
||||
>
|
||||
匹配结果展示
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="xmlMappingPreview" class="xml-file-viewer">
|
||||
<div class="xml-file-header">
|
||||
<span class="xml-file-name">XML 文件</span>
|
||||
<span class="xml-file-meta">{{ xmlMetaText }}</span>
|
||||
<div v-if="xmlMappingPreview" class="xml-preview-viewer">
|
||||
<div class="xml-preview-toolbar">
|
||||
<div class="xml-preview-meta">{{ xmlMetaText }}</div>
|
||||
<div class="xml-preview-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
:icon="Document"
|
||||
:disabled="!methodDescribe"
|
||||
@click="matchResultDialogVisible = true"
|
||||
>
|
||||
匹配结果展示
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
:icon="Download"
|
||||
:disabled="!canExportXmlMapping"
|
||||
@click="emit('export-mapping', 'xml')"
|
||||
>
|
||||
下载XML映射
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<pre class="xml-file-content">{{ xmlMappingPreview }}</pre>
|
||||
</div>
|
||||
@@ -148,9 +167,9 @@
|
||||
<el-dialog
|
||||
v-model="sequenceDialogVisible"
|
||||
title="序列配置"
|
||||
width="920px"
|
||||
width="960px"
|
||||
destroy-on-close
|
||||
top="8vh"
|
||||
top="6vh"
|
||||
class="sequence-config-dialog"
|
||||
>
|
||||
<template v-if="sequenceConfigRows.length">
|
||||
@@ -217,7 +236,7 @@
|
||||
</template>
|
||||
<el-empty v-else description="当前 JSON 映射中未分析到包含 start 和 end 的序列。" />
|
||||
<template #footer>
|
||||
<el-button @click="sequenceDialogVisible = false">取消</el-button>
|
||||
<el-button @click="closeSequenceDialog">取消</el-button>
|
||||
<el-button type="primary" :disabled="!sequenceConfigRows.length" @click="confirmSequenceConfig">
|
||||
确定
|
||||
</el-button>
|
||||
@@ -227,9 +246,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ArrowDown, Connection, Document, Download, Finished, Search, Setting, Warning } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { computed, ref } from 'vue'
|
||||
import { CircleCheck, Connection, Document, Download, Finished, Search, Setting, Warning } from '@element-plus/icons-vue'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import JsonMappingTree from './JsonMappingTree.vue'
|
||||
|
||||
defineOptions({
|
||||
@@ -271,9 +289,10 @@ interface SequenceConfigGroup {
|
||||
typeGroups: SequenceConfigTypeGroup[]
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
responseStatusText: string
|
||||
responseStatusTagType: TagType
|
||||
const props = withDefaults(defineProps<{
|
||||
responseStatusText?: string
|
||||
responseStatusTagType?: TagType
|
||||
showDescription?: boolean
|
||||
activeResultTab: ResultTab
|
||||
mappingMetaText: string
|
||||
mappingJsonPreview: string
|
||||
@@ -286,20 +305,29 @@ const props = defineProps<{
|
||||
methodDescribe: string
|
||||
canExportJsonMapping: boolean
|
||||
canExportXmlMapping: boolean
|
||||
canConfigureSequence: boolean
|
||||
canGenerateXmlMapping: boolean
|
||||
isGeneratingXml: boolean
|
||||
showXmlMappingTab: boolean
|
||||
sequenceDialogVisible: boolean
|
||||
showIcdCheckAction?: boolean
|
||||
showSaveIcdCheckResult: boolean
|
||||
canSaveIcdCheckResult: boolean
|
||||
isSavingIcdCheckResult: boolean
|
||||
saveIcdCheckResultText: string
|
||||
}>()
|
||||
}>(), {
|
||||
showDescription: true,
|
||||
showIcdCheckAction: true
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:activeResultTab', value: ResultTab): void
|
||||
(event: 'export-mapping', value: ExportMappingType): void
|
||||
(event: 'generate-xml-mapping'): void
|
||||
(event: 'update-mapping-json', value: string): void
|
||||
(event: 'update:sequenceDialogVisible', value: boolean): void
|
||||
(event: 'sequence-config-complete'): void
|
||||
(event: 'icd-check'): void
|
||||
(event: 'save-icd-check-result'): void
|
||||
}>()
|
||||
|
||||
@@ -308,25 +336,17 @@ const activeTabProxy = computed({
|
||||
set: value => emit('update:activeResultTab', value)
|
||||
})
|
||||
|
||||
const canExportAnyMapping = computed(() => props.canExportJsonMapping || props.canExportXmlMapping)
|
||||
const activeExportType = computed<ExportMappingType>(() => {
|
||||
if (props.activeResultTab === 'xml') return 'xml'
|
||||
if (props.canExportJsonMapping) return 'json'
|
||||
if (props.canExportXmlMapping) return 'xml'
|
||||
return 'json'
|
||||
})
|
||||
const canExportActiveMapping = computed(() =>
|
||||
activeExportType.value === 'json' ? props.canExportJsonMapping : props.canExportXmlMapping
|
||||
)
|
||||
const exportButtonText = computed(() => (activeExportType.value === 'xml' ? '导出XML映射' : '导出JSON映射'))
|
||||
const problemButtonText = computed(() =>
|
||||
props.problemList.length ? `问题列表(${props.problemList.length})` : '问题列表'
|
||||
)
|
||||
const problemDialogVisible = ref(false)
|
||||
const matchResultDialogVisible = ref(false)
|
||||
const sequenceDialogVisible = ref(false)
|
||||
const sequenceConfigRows = ref<SequenceConfigRow[]>([])
|
||||
const sequenceSearchKeyword = ref('')
|
||||
const sequenceDialogVisible = computed({
|
||||
get: () => props.sequenceDialogVisible,
|
||||
set: value => emit('update:sequenceDialogVisible', value)
|
||||
})
|
||||
const normalizedSequenceSearchKeyword = computed(() => sequenceSearchKeyword.value.trim().toLowerCase())
|
||||
const filteredSequenceRows = computed(() => {
|
||||
const keyword = normalizedSequenceSearchKeyword.value
|
||||
@@ -379,12 +399,6 @@ const sequenceConfigGroups = computed<SequenceConfigGroup[]>(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const handleExportCommand = (command: string | number | object) => {
|
||||
if (command === 'json' || command === 'xml') {
|
||||
emit('export-mapping', command)
|
||||
}
|
||||
}
|
||||
|
||||
const isRecord = (value: unknown): value is JsonObject =>
|
||||
Boolean(value && typeof value === 'object' && !Array.isArray(value))
|
||||
|
||||
@@ -475,18 +489,36 @@ const normalizeSequenceValue = (value: string, valueType: string) => {
|
||||
return numericValue
|
||||
}
|
||||
|
||||
const openSequenceDialog = () => {
|
||||
const prepareSequenceDialog = () => {
|
||||
try {
|
||||
const parsed = JSON.parse(props.mappingJsonPreview) as unknown
|
||||
|
||||
sequenceConfigRows.value = collectSequenceRows(parsed)
|
||||
sequenceSearchKeyword.value = ''
|
||||
sequenceDialogVisible.value = true
|
||||
return true
|
||||
} catch {
|
||||
ElMessage.warning('当前 JSON 映射内容无法解析,不能配置序列')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const openSequenceDialog = () => {
|
||||
if (!prepareSequenceDialog()) return
|
||||
sequenceDialogVisible.value = true
|
||||
}
|
||||
|
||||
const closeSequenceDialog = () => {
|
||||
sequenceDialogVisible.value = false
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.sequenceDialogVisible,
|
||||
visible => {
|
||||
if (!visible) return
|
||||
prepareSequenceDialog()
|
||||
}
|
||||
)
|
||||
|
||||
const confirmSequenceConfig = () => {
|
||||
try {
|
||||
const nextJson = JSON.parse(props.mappingJsonPreview) as unknown
|
||||
@@ -502,6 +534,7 @@ const confirmSequenceConfig = () => {
|
||||
})
|
||||
|
||||
emit('update-mapping-json', JSON.stringify(nextJson, null, 4))
|
||||
emit('sequence-config-complete')
|
||||
sequenceDialogVisible.value = false
|
||||
ElMessage.success('序列配置已同步到 JSON 映射')
|
||||
} catch (error) {
|
||||
@@ -539,25 +572,58 @@ const confirmSequenceConfig = () => {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.export-actions {
|
||||
.panel-actions :deep(.el-button + .el-button) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.panel-title-tabs {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-bottom: 1px solid var(--el-border-color-light);
|
||||
}
|
||||
|
||||
.panel-title-tab {
|
||||
position: relative;
|
||||
height: 36px;
|
||||
padding: 0 2px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
font-size: 13px;
|
||||
line-height: 36px;
|
||||
color: var(--el-color-primary);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.export-menu-button {
|
||||
width: 32px;
|
||||
padding: 8px;
|
||||
.panel-title-tab::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
height: 2px;
|
||||
background-color: var(--el-color-primary);
|
||||
content: '';
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
color: #1f2937;
|
||||
.mapping-preview-tabs {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
align-self: flex-start;
|
||||
margin-bottom: 12px;
|
||||
border-bottom: 1px solid var(--el-border-color-light);
|
||||
}
|
||||
|
||||
.mapping-preview-tabs .panel-title-tab {
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.mapping-preview-tabs .panel-title-tab:not(.is-active)::after {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.mapping-preview-tabs .panel-title-tab.is-active {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.panel-description {
|
||||
@@ -609,7 +675,7 @@ const confirmSequenceConfig = () => {
|
||||
}
|
||||
|
||||
.preview-tabs :deep(.el-tabs__header) {
|
||||
margin-bottom: 16px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.preview-tabs :deep(.el-tabs__nav-wrap::after) {
|
||||
@@ -661,49 +727,14 @@ const confirmSequenceConfig = () => {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.xml-file-viewer {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
border: 1px solid #dbe3f0;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.xml-file-header {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
min-height: 40px;
|
||||
padding: 0 14px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
background: #f8fafc;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.xml-file-name {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.xml-file-meta {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
color: #64748b;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.xml-file-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
margin: 0;
|
||||
padding: 16px;
|
||||
border: 1px solid #dbe3f0;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
overflow: auto;
|
||||
font-family: Consolas, 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
@@ -712,11 +743,48 @@ const confirmSequenceConfig = () => {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.xml-preview-viewer {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.xml-preview-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
min-height: 28px;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.xml-preview-meta {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.xml-preview-actions {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.xml-preview-actions :deep(.el-button + .el-button) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.problem-dialog-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
max-height: 62vh;
|
||||
max-height: 58vh;
|
||||
padding-right: 4px;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -753,13 +821,6 @@ const confirmSequenceConfig = () => {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.match-result-actions {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.match-result-detail {
|
||||
max-height: 58vh;
|
||||
padding: 14px 16px;
|
||||
@@ -793,7 +854,7 @@ const confirmSequenceConfig = () => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
max-height: 62vh;
|
||||
max-height: 58vh;
|
||||
padding-right: 4px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user