Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/src/api/types/paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface ProblemBatchAssociationPayload {

export interface ParagraphDetail extends ParagraphItem {
problem_list: ParagraphProblem[]
source_file_id?: string | null
}

export interface ParagraphUpdatePayload {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/mk-drag-upload/MultipleFileUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ defineExpose({ clearFiles, handleRemove })
<el-image
:src="(file.raw ? imagePreviewUrls.get(file.raw) : undefined) ?? file.url"
fit="cover"
class="h-26! w-26!"
class="size-26"
:class="{ 'border-danger!': file.status === 'fail' }"
></el-image>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,10 @@ const uploadFile = async (file: DynamicFormValue, fileList: DynamicFormValue[])
<template v-for="(item, index) in images" :key="index">
<div class="file cursor border-r-6" v-if="item.url">
<el-image
class="size-8"
:src="item.url"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="getAttrsArray(images, 'url')"
:scale="0.8"
:initial-index="index"
fit="cover"
/>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/mk-edit-avatar/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ onBeforeUnmount(() => {
:show-file-list="false"
:on-change="selectImage"
>
<el-image v-if="previewIcon" :src="previewIcon" fit="cover" class="h-20! w-20!" />
<el-image v-if="previewIcon" :src="previewIcon" fit="cover" class="size-20" />
<div v-else class="flex-center h-20 w-20 rounded-md border border-dashed bg-N200 hover:border-primary">
<MkIcon name="icon_add_outlined" :size="24" />
</div>
Expand Down
27 changes: 24 additions & 3 deletions ui/src/conversation-panel/components/message-input/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,22 @@ import { formatFileSize } from '@/utils/number'
import { inputShortcut } from '../../core/shortcuts'
import { useMessageInputStore } from './index'

const { question, fileList, maxFiles, maxSizeMB, acceptList, streamLoading, disabled, placeholder, canSend, imageFiles, addFiles, removeFile, send, stop } =
useMessageInputStore()
const {
question,
fileList,
maxFiles,
maxSizeMB,
acceptList,
streamLoading,
disabled,
placeholder,
canSend,
imageFiles,
addFiles,
removeFile,
send,
stop,
} = useMessageInputStore()

// 选择和粘贴附件统一交给输入 Store 处理。
const fileInputRef = ref<HTMLInputElement | null>(null)
Expand Down Expand Up @@ -41,7 +55,14 @@ const handleKeydown = (event: KeyboardEvent) => {
<template v-for="(file, index) in fileList" :key="file.uid">
<div class="group relative shrink-0">
<!-- 图片 -->
<el-image v-if="imageFiles.includes(file)" :src="file.url || file.previewUrl" :alt="file.name" :title="file.name" fit="cover" />
<el-image
class="size-8"
v-if="imageFiles.includes(file)"
:src="file.url || file.previewUrl"
:alt="file.name"
:title="file.name"
fit="cover"
/>
<!-- 音频 -->
<MkAudio v-else-if="isAudio(file.name)" :src="file.previewUrl || file.url || ''" :name="file.name">
<el-card shadow="never" class="small w-60 rounded-lg! cursor-pointer">
Expand Down
6 changes: 6 additions & 0 deletions ui/src/styles/STYLE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ Drawer 的 `header` 插槽内时,组合 `absolute-center` 和宽度工具类
图片预览遮罩 `.el-image-viewer__mask` 统一使用 `var(--el-overlay-color-lighter)`,
并将元素 `opacity` 设为 `1`,避免与背景色自身透明度叠加;与媒体预览遮罩保持一致。

`.el-image` 全局仅提供边框、圆角和块级展示,不设置固定宽高。使用处按场景指定尺寸,
普通缩略图使用 `size-8`,头像、上传及召回图片保留各自尺寸。按比例展示且限制最大高度时,
同时约束内部图片的尺寸,避免仅限制外层高度造成裁切;点击放大复用 `preview-src-list` 和 `preview-teleported`。
启用点击预览时统一设置 `:scale="0.8"`,缩放步长和上下限使用 Element Plus 默认值,
不重复声明 `zoom-rate="1.2"`、`max-scale="7"` 和 `min-scale="0.2"`。

### 普通 CSS 中叠加透明度

使用 `color-mix(in srgb, var(--mk-primary) 10%, transparent)`。
Expand Down
6 changes: 2 additions & 4 deletions ui/src/styles/element-plus.scss
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
&.is-circle {
width: 32px;
height: 32px;
--el-button-hover-text-color: var(--el-text-color-primary);
--el-button-hover-text-color: var(--el-color-primary);
--el-button-hover-bg-color: white;
--el-button-hover-border-color: var(--el-border-color);
&.el-button--large {
Expand Down Expand Up @@ -627,10 +627,8 @@

/* image */
.el-image {
border-radius: var(--el-border-radius-base);
width: 60px;
height: 60px;
border: 1px solid var(--mk-N300);
border-radius: var(--el-border-radius-base);
display: block;
}

Expand Down
3 changes: 3 additions & 0 deletions ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ Workspace 共享只读,隐藏创建、编辑、排序、关联修改及批量

`paragraph-dialog/` 使用 `CreateParagraphDialog` 和 `ParagraphDialog`(详情/编辑),组合
`ParagraphForm`、`ParagraphPreview`、`ParagraphQuestions`。创建可指定插入位置;正文表单支持 Markdown 和知识库图片上传。
`ParagraphDialog` 的 `title` 可自定义详情标题,默认“分段详情”,图片列表传入“图片详情”;编辑模式标题为“编辑”。
图片列表将行数据的 `meta.source_file_id` 通过 `ParagraphDialog.sourceFileId` 传入,预览合并为分段的 `source_file_id`;
仅存在文件 ID 时展示图片,图片与 Markdown 正文共用滚动区域,保存正文后保留图片。
问题区使用远程候选和即时关联/解除,不删除问题本身;无分段 ID 时保存本地问题草稿,随新增提交。
正文保存不提交或回填 `problem_list`,避免覆盖并行关联操作;取消编辑不撤销问题修改。
问题区请求状态独立,不阻止正文保存/关闭;共享模式只展示,不查询可关联候选。
Expand Down
1 change: 1 addition & 0 deletions ui/src/views/document-detail/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ onMounted(() => {
<EditParagraphDialog
v-if="editDialogMounted"
ref="editDialogRef"
title="分段详情"
:knowledge-id="knowledgeId"
:document-id="documentId"
@success="handleReplaceParagraph"
Expand Down
18 changes: 12 additions & 6 deletions ui/src/views/document-detail/paragraph-dialog/ParagraphDialog.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { ref } from 'vue'
import { useDocumentDetailContext } from '@/views/document-detail/context'
import type { ParagraphDetail, ParagraphItem, ParagraphUpdatePayload } from '@/api/types'
import type { ParagraphQuestionDraft } from './types.ts'
Expand All @@ -13,14 +13,15 @@ defineOptions({ name: 'EditParagraphDialog' })
const props = defineProps<{
knowledgeId: string
documentId: string
sourceFileId?: string
title?: string
}>()
const { resourceApi } = useDocumentDetailContext()
const emit = defineEmits<{ success: [paragraph: ParagraphItem]; closed: [] }>()

/* 详情加载:打开时固定目标,关闭动画后由页面卸载。 */
const visible = ref(false)
const mode = ref<'edit' | 'detail'>('detail')
const dialogTitle = computed(() => (mode.value === 'edit' ? '编辑' : '分段详情'))
const paragraphDetail = ref<ParagraphDetail>()
const targetKnowledgeId = ref('')
const targetDocumentId = ref('')
Expand All @@ -36,7 +37,7 @@ function loadParagraphDetail() {
return resourceApi.paragraph
.getParagraphDetail(targetKnowledgeId.value, targetDocumentId.value, targetParagraphId.value)
.then((paragraph) => {
paragraphDetail.value = paragraph
paragraphDetail.value = { ...paragraph, source_file_id: props.sourceFileId }
relatedQuestions.value = paragraph.problem_list
paragraphForm.value = { title: paragraph.title ?? '', content: paragraph.content }
})
Expand Down Expand Up @@ -95,7 +96,7 @@ function handleSubmit() {
})
.then((paragraph) => {
// 问题由独立接口更新,正文保存响应不回填问题列表,避免覆盖并行操作结果。
paragraphDetail.value = paragraph
paragraphDetail.value = { ...paragraph, source_file_id: props.sourceFileId }
mode.value = 'detail'
MsgSuccess('保存成功')
emit('success', paragraph)
Expand All @@ -111,12 +112,17 @@ defineExpose({ open, close })
</script>

<template>
<MkDialog v-model="visible" :title="dialogTitle" width="1000" align-center :before-close="handleBeforeClose" @closed="emit('closed')">
<MkDialog v-model="visible" :title="title" width="1000" align-center :before-close="handleBeforeClose" @closed="emit('closed')">
<div v-loading="loading">
<div class="flex h-[480px] max-h-[calc(100vh-272px)] w-full gap-4">
<el-card v-if="mode === 'detail'" shadow="never" class="mk-paragraph-card group relative min-w-0 flex-1" body-class="flex-column h-full">
<!-- 编辑分段标题和内容 -->
<el-button v-if="!isWorkspaceSharedResource()" circle class="group-hover-visible absolute! top-4 right-4 shadow-md" @click="handleEdit">
<el-button
v-if="!isWorkspaceSharedResource()"
circle
class="group-hover-visible absolute! top-2 right-2 z-10 shadow-md"
@click="handleEdit"
>
<MkIcon name="icon_edit_outlined" />
</el-button>
<ParagraphPreview :paragraph="paragraphDetail" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
<script setup lang="ts">
import type { ParagraphDetail } from '@/api/types'
import { datetimeFormat } from '@/utils/time'
import { getFileUrl } from '@/utils/common'

defineOptions({ name: 'ParagraphPreview' })
defineProps<{ paragraph?: ParagraphDetail }>()
</script>

<template>
<h4 class="mb-3 min-w-0 shrink-0 break-words">{{ paragraph?.title || '-' }}</h4>
<el-scrollbar height="100%" class="min-h-0 flex-1">
<!-- 点击预览原图 -->
<el-image
v-if="paragraph?.source_file_id"
class="w-fit [&_img]:size-auto! [&_img]:max-h-50 mb-2"
:src="getFileUrl(paragraph.source_file_id)"
:preview-src-list="[getFileUrl(paragraph.source_file_id)]"
preview-teleported
:scale="0.8"
:alt="paragraph.title || ''"
fit="contain"
/>
<h4 class="mb-3 min-w-0 shrink-0 break-words">{{ paragraph?.title || '-' }}</h4>
<MdPreview :model-value="paragraph?.content ?? ''" />
</el-scrollbar>
<div class="mt-4 flex-align-center shrink-0 gap-2 text-sm text-N600">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ onBeforeUnmount(() => {
:alt="image.name"
:title="image.name"
:preview-src-list="[image.previewUrl]"
:scale="0.8"
preview-teleported
fit="cover"
class="size-20 rounded-lg border"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ defineProps<{ paragraph: KnowledgeHitTestResult; index: number }>()
:src="paragraph.hit_asset.url"
:alt="paragraph.hit_asset.caption || paragraph.hit_asset.file_name"
:preview-src-list="[paragraph.hit_asset.url]"
:scale="0.8"
preview-teleported
fit="contain"
class="mt-3 h-40 max-w-full rounded-md"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { computed, nextTick, ref } from 'vue'
import type { DocumentImportParagraph, DocumentSplitResult } from '@/api/types'
import { getFileIconUrl } from '@/utils/icon'
import { getFileUrl } from '@/utils/common'
import { MsgWarning } from '@/utils/message'
import EditParagraphDialog from '../upload-document/EditParagraphDialog.vue'

Expand Down Expand Up @@ -73,7 +74,14 @@ function handleDeleteParagraph(index: number) {
@keydown.enter="handleSelectDocument(index)"
>
<div class="flex-align-center gap-2">
<img :src="getFileIconUrl(document.name)" alt="" class="size-6 shrink-0" />
<el-image
v-if="document.source_file_id"
class="size-8 shrink-0"
:src="getFileUrl(document.source_file_id)"
:alt="document.name"
fit="cover"
/>
<img v-else :src="getFileIconUrl(document.name)" alt="" class="size-6 shrink-0" />
<span class="truncate" :title="document.name">{{ document.name }}</span>
</div>
</el-card>
Expand All @@ -99,7 +107,17 @@ function handleDeleteParagraph(index: number) {
</el-button>
</el-card>
</div>
<h4 v-if="paragraph.title" class="mb-3 pr-20">{{ paragraph.title }}</h4>

<!-- 图片-->
<el-image
v-if="selectedDocument.source_file_id"
class="w-fit [&_img]:size-auto! [&_img]:max-h-50 mb-2"
:src="getFileUrl(selectedDocument.source_file_id)"
:alt="selectedDocument.name"
fit="contain"
/>

<h4 v-if="paragraph.title" class="mb-2 pr-20">{{ paragraph.title }}</h4>
<MdPreview :model-value="paragraph.content" />
<p class="mt-2 text-sm text-N600">{{ paragraph.content.length }} 字符</p>
</el-card>
Expand Down
8 changes: 5 additions & 3 deletions ui/src/views/knowledge-detail/library/image/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const { knowledge, resourceApi } = useKnowledgeDetailContext()

/* 图片分段详情:取首个分段,弹窗关闭后卸载。 */
const paragraphDialogRef = ref<InstanceType<typeof ParagraphDialog>>()
const selectedParagraph = ref<ParagraphItem>()
const selectedParagraph = ref<ParagraphItem & { source_file_id?: string }>()

function handleOpenParagraph(document: DocumentItem, column?: TableColumnCtx<DocumentItem> | null) {
if (loading.value || operationLoading.value || selectedParagraph.value || column?.type === 'selection') return
Expand All @@ -57,7 +57,7 @@ function handleOpenParagraph(document: DocumentItem, column?: TableColumnCtx<Doc
.then(async (page) => {
const paragraph = page.records[0]
if (!paragraph) return
selectedParagraph.value = paragraph
selectedParagraph.value = { ...paragraph, source_file_id: document.meta?.source_file_id as string | undefined }
await nextTick()
paragraphDialogRef.value?.open(paragraph)
})
Expand Down Expand Up @@ -315,7 +315,7 @@ onBeforeUnmount(() => {
>
<template #prefix>
<!-- 图片 -->
<el-image class="h-7.5! w-7.5!" :src="getFileUrl(row.meta?.source_file_id as string | undefined)" :alt="row.name" fit="cover" />
<el-image class="size-7.5" :src="getFileUrl(row.meta?.source_file_id as string | undefined)" :alt="row.name" fit="cover" />
</template>
</MkEditName>
</template>
Expand Down Expand Up @@ -594,8 +594,10 @@ onBeforeUnmount(() => {
<ParagraphDialog
v-if="selectedParagraph"
ref="paragraphDialogRef"
title="图片详情"
:knowledge-id="knowledgeId"
:document-id="selectedParagraph.document_id"
:source-file-id="selectedParagraph.source_file_id"
@success="refreshAfterOperation"
@closed="selectedParagraph = undefined"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,7 @@ defineProps<{
<div class="whitespace-pre-wrap space-y-2">
<template v-if="Array.isArray(data.question)">
<div v-for="(item, qIndex) in data.question" :key="qIndex">
<el-image
v-if="item.type === 'image_url'"
:src="item.image_url?.url || item.image_url"
fit="cover"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
/>
<el-image class="size-8" v-if="item.type === 'image_url'" :src="item.image_url?.url || item.image_url" fit="cover" />
<video
v-else-if="item.type === 'video_url'"
:src="item.video_url?.url || item.video_url"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,7 @@ defineProps<{
<div class="whitespace-pre-wrap space-y-2">
<template v-if="Array.isArray(data.question)">
<div v-for="(item, qIndex) in data.question" :key="qIndex">
<el-image
v-if="item.type === 'image_url'"
:src="item.image_url?.url || item.image_url"
fit="cover"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
/>
<el-image class="size-8" v-if="item.type === 'image_url'" :src="item.image_url?.url || item.image_url" fit="cover" />
<video
v-else-if="item.type === 'video_url'"
:src="item.video_url?.url || item.video_url"
Expand Down
13 changes: 8 additions & 5 deletions ui/src/workflow-canvas/nodes/application-node/details/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ defineProps<{
<div class="mk-gray-card-sm">
<h6 class="mb-2">输入参数</h6>
<div class="space-y-2">
<p><span class="mr-1 text-N600">问题:</span>{{ data.question || '-' }}</p>
<p>
<span class="mr-1 text-N600">问题:</span>
{{ data.question || '-' }}
</p>

<p v-for="(f, i) in data.global_fields" :key="i">
<span class="mr-1 text-N600">{{ f.label }}:</span>{{ f.value }}
<span class="mr-1 text-N600">{{ f.label }}:</span>
{{ f.value }}
</p>

<div v-if="data.document_list?.length > 0">
Expand All @@ -40,15 +44,14 @@ defineProps<{
<p class="mb-1 text-N600">图片:</p>
<div class="flex flex-wrap gap-2">
<el-image
class="size-8"
v-for="(f, i) in data.image_list"
:key="i"
:src="f.url"
fit="cover"
:preview-src-list="data.image_list.map((img: any) => img.url)"
:scale="0.8"
:initial-index="i"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
/>
</div>
</div>
Expand Down
Loading
Loading