新增: AI Chat @灵感提及(ChatInput mention idea组)
- ChatInput.vue: MentionItem type加idea + mentionItems加idea过滤(title/description projectsStore.ideas) + mentionGroups加idea组 + selectMention插入[灵感: title] - i18n zh/en: mentionGroupIdea 灵感走store同步computed(同project/task模式 无IPC)
This commit is contained in:
@@ -119,7 +119,7 @@ import { ref, computed, nextTick, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useAiStore } from '../../stores/ai'
|
||||
import { useProjectStore } from '../../stores/project'
|
||||
import type { AiMessage, ContentPart, SkillInfo, ProjectRecord, TaskRecord } from '../../api/types'
|
||||
import type { AiMessage, ContentPart, SkillInfo, ProjectRecord, TaskRecord, IdeaRecord } from '../../api/types'
|
||||
|
||||
const props = defineProps<{
|
||||
/** UX-09: 编辑末条 user 消息态;父持有,handleSend 据此走 editMessage 而非 sendMessage */
|
||||
@@ -324,7 +324,7 @@ function clearSkill() {
|
||||
// 触发:输入框光标前最近的 @ 后无空白/换行 → 激活;Esc/光标移开/选中插入 → 关闭。
|
||||
// Enter 不冲突:popover 开时 Enter 插入选中(覆盖发送),关时 Enter 发送(原逻辑)。
|
||||
interface MentionItem {
|
||||
type: 'project' | 'task'
|
||||
type: 'project' | 'task' | 'idea'
|
||||
/** 扁平后唯一 key(用于 key/导航扁平索引定位) */
|
||||
uid: string
|
||||
/** 实体原始 id(供后端解析,目前仅插入 [类型:名] 文本,id 未透传) */
|
||||
@@ -342,6 +342,7 @@ const mentionStart = ref(-1)
|
||||
const mentionGroupLabel = computed(() => ({
|
||||
project: t('aiChat.mentionGroupProject'),
|
||||
task: t('aiChat.mentionGroupTask'),
|
||||
idea: t('aiChat.mentionGroupIdea'),
|
||||
}))
|
||||
|
||||
/** 当前 @ 查询文本(@ 之后的串,不含 @) */
|
||||
@@ -378,19 +379,33 @@ const mentionItems = computed<MentionItem[]>(() => {
|
||||
desc: tk.description || '',
|
||||
typeLabel: t('aiChat.mentionGroupTask'),
|
||||
}))
|
||||
return [...projectItems, ...taskItems]
|
||||
const ideas = (projectsStore.ideas || []) as IdeaRecord[]
|
||||
const ideaItems: MentionItem[] = ideas
|
||||
.filter(it => match(it.title) || match(it.description || ''))
|
||||
.slice(0, 20)
|
||||
.map(it => ({
|
||||
type: 'idea' as const,
|
||||
uid: 'i-' + it.id,
|
||||
id: it.id,
|
||||
name: it.title,
|
||||
desc: it.description || '',
|
||||
typeLabel: t('aiChat.mentionGroupIdea'),
|
||||
}))
|
||||
return [...projectItems, ...taskItems, ...ideaItems]
|
||||
})
|
||||
|
||||
/** 联想候选总数(未过滤,用于区分"无匹配" vs "空") */
|
||||
const mentionTotal = computed(() =>
|
||||
((projectsStore.projects || []) as ProjectRecord[]).length
|
||||
+ ((projectsStore.tasks || []) as TaskRecord[]).length,
|
||||
+ ((projectsStore.tasks || []) as TaskRecord[]).length
|
||||
+ ((projectsStore.ideas || []) as IdeaRecord[]).length,
|
||||
)
|
||||
|
||||
/** 按类型分组(模板按组渲染组标题) */
|
||||
const mentionGroups = computed(() => [
|
||||
{ key: 'project', label: mentionGroupLabel.value.project, items: mentionItems.value.filter(i => i.type === 'project') },
|
||||
{ key: 'task', label: mentionGroupLabel.value.task, items: mentionItems.value.filter(i => i.type === 'task') },
|
||||
{ key: 'idea', label: mentionGroupLabel.value.idea, items: mentionItems.value.filter(i => i.type === 'idea') },
|
||||
])
|
||||
|
||||
/** 扁平下标(组内 item 在扁平列表中的位置,供键盘导航 ↑↓/高亮) */
|
||||
@@ -405,7 +420,9 @@ function selectMention(item: MentionItem) {
|
||||
const after = inputText.value.slice(cursorAfter)
|
||||
const label = item.type === 'project'
|
||||
? `[${t('aiChat.mentionGroupProject')}: ${item.name}]`
|
||||
: `[${t('aiChat.mentionGroupTask')}: ${item.name}]`
|
||||
: item.type === 'task'
|
||||
? `[${t('aiChat.mentionGroupTask')}: ${item.name}]`
|
||||
: `[${t('aiChat.mentionGroupIdea')}: ${item.name}]`
|
||||
inputText.value = before + label + ' ' + after
|
||||
mentionOpen.value = false
|
||||
mentionStart.value = -1
|
||||
|
||||
@@ -90,6 +90,7 @@ export default {
|
||||
mentionHint: "{'@'} to mention project/task",
|
||||
mentionGroupProject: 'Projects',
|
||||
mentionGroupTask: 'Tasks',
|
||||
mentionGroupIdea: 'Ideas',
|
||||
mentionNoMatch: 'No matching entity',
|
||||
mentionEmpty: 'No project/task to mention',
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ export default {
|
||||
mentionHint: "{'@'} 引用项目/任务",
|
||||
mentionGroupProject: '项目',
|
||||
mentionGroupTask: '任务',
|
||||
mentionGroupIdea: '灵感',
|
||||
mentionNoMatch: '无匹配实体',
|
||||
mentionEmpty: '暂无可引用的项目/任务',
|
||||
|
||||
|
||||
Reference in New Issue
Block a user