准备实现富文本编辑器
This commit is contained in:
parent
5a2a699a51
commit
ea44620dee
BIN
chi_sim.traineddata
Normal file
BIN
chi_sim.traineddata
Normal file
Binary file not shown.
BIN
eng.traineddata
Normal file
BIN
eng.traineddata
Normal file
Binary file not shown.
115
renderer/src/components/k-rich-textarea/index.vue
Normal file
115
renderer/src/components/k-rich-textarea/index.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<div class="k-rich-textarea">
|
||||
<div
|
||||
ref="editor"
|
||||
contenteditable="true"
|
||||
class="rich-editor"
|
||||
:placeholder="placeholder"
|
||||
@input="handleInput"
|
||||
@keydown.enter="handleKeydown"
|
||||
@compositionstart="handleCompositionStart"
|
||||
@compositionend="handleCompositionEnd"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, defineProps, defineEmits, watch } from 'vue';
|
||||
import type { RichTextItem } from './textarea.dto';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Array as () => RichTextItem[],
|
||||
required: true
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '输入消息...'
|
||||
},
|
||||
customClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'pressEnter']);
|
||||
|
||||
const editor = ref<HTMLElement | null>(null);
|
||||
|
||||
const renderRichText = (items: RichTextItem[]) => {
|
||||
return items.map(item => {
|
||||
if (item.type === 'prompt' || item.type === 'resource') {
|
||||
return `<span class="rich-item rich-item-${item.type}">${item.text}</span>`;
|
||||
}
|
||||
return item.text;
|
||||
}).join('');
|
||||
};
|
||||
|
||||
const handleInput = (event: Event) => {
|
||||
if (editor.value) {
|
||||
console.log(editor.value);
|
||||
|
||||
const items: RichTextItem[] = [];
|
||||
// 解析编辑器内容并转换为 RichTextItem[]
|
||||
// ... 实现解析逻辑
|
||||
emit('update:modelValue', items);
|
||||
}
|
||||
};
|
||||
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
if (editor.value) {
|
||||
editor.value.innerHTML = renderRichText(newValue);
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
const isComposing = ref(false);
|
||||
|
||||
const handleKeydown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'Enter' && !event.shiftKey && !isComposing.value) {
|
||||
event.preventDefault();
|
||||
emit('pressEnter', event);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCompositionStart = () => {
|
||||
isComposing.value = true;
|
||||
};
|
||||
|
||||
const handleCompositionEnd = () => {
|
||||
isComposing.value = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.k-rich-textarea {
|
||||
border-radius: .9em;
|
||||
border: 1px solid #DCDFE6;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.rich-editor {
|
||||
min-height: 100px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.rich-editor:empty::before {
|
||||
content: attr(placeholder);
|
||||
color: #C0C4CC;
|
||||
}
|
||||
|
||||
.rich-item {
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.rich-item-prompt {
|
||||
background-color: #e8f0fe;
|
||||
color: #1a73e8;
|
||||
}
|
||||
|
||||
.rich-item-resource {
|
||||
background-color: #f1f3f4;
|
||||
color: #202124;
|
||||
}
|
||||
</style>
|
17
renderer/src/components/k-rich-textarea/textarea.dto.ts
Normal file
17
renderer/src/components/k-rich-textarea/textarea.dto.ts
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
interface PromptTextItem {
|
||||
type: 'prompt'
|
||||
text: string
|
||||
}
|
||||
|
||||
interface ResourceTextItem {
|
||||
type: 'resource'
|
||||
text: string
|
||||
}
|
||||
|
||||
interface TextItem {
|
||||
type: 'text'
|
||||
text: string
|
||||
}
|
||||
|
||||
export type RichTextItem = PromptTextItem | ResourceTextItem | TextItem;
|
@ -59,6 +59,8 @@ function whenGetPromptResponse(msg: PromptsGetResponse) {
|
||||
try {
|
||||
const content = msg.messages[0].content;
|
||||
|
||||
selectPrompt.value = undefined;
|
||||
|
||||
if (content) {
|
||||
emits('update:modelValue', props.modelValue + content);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<Model />
|
||||
<SystemPrompt />
|
||||
<ToolUse />
|
||||
<Prompt v-model="val" />
|
||||
<Prompt v-model="modelValue" />
|
||||
<Websearch />
|
||||
<Temperature />
|
||||
<ContextLength />
|
||||
@ -11,7 +11,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps, provide, ref } from 'vue';
|
||||
import { defineProps, defineEmits, provide, ref, computed } from 'vue';
|
||||
import { llmManager } from '@/views/setting/llm';
|
||||
import { tabs } from '../../panel';
|
||||
import type { ChatSetting, ChatStorage } from '../chat';
|
||||
@ -35,7 +35,17 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
const val = ref('');
|
||||
const emits = defineEmits(['update:modelValue']);
|
||||
|
||||
const modelValue = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
emits('update:modelValue', value);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const tab = tabs.content[props.tabId];
|
||||
const tabStorage = tab.storage as ChatStorage & { settings: ChatSetting };
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"currentIndex": 1,
|
||||
"currentIndex": 0,
|
||||
"tabs": [
|
||||
{
|
||||
"name": "交互测试",
|
||||
@ -9,50 +9,7 @@
|
||||
"storage": {
|
||||
"messages": [],
|
||||
"settings": {
|
||||
"modelIndex": 15,
|
||||
"enableTools": [
|
||||
{
|
||||
"name": "add",
|
||||
"description": "对两个数字进行实数域的加法",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "multiply",
|
||||
"description": "对两个数字进行实数域的乘法运算",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "is_even",
|
||||
"description": "判断一个整数是否为偶数",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "capitalize",
|
||||
"description": "将字符串首字母大写",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "get_weather_by_city_code",
|
||||
"description": "根据城市天气预报的城市编码 (int),获取指定城市的天气信息",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enableWebSearch": false,
|
||||
"temperature": 0.7,
|
||||
"contextLength": 20,
|
||||
"systemPrompt": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "交互测试",
|
||||
"icon": "icon-robot",
|
||||
"type": "blank",
|
||||
"componentIndex": 3,
|
||||
"storage": {
|
||||
"messages": [],
|
||||
"settings": {
|
||||
"modelIndex": 15,
|
||||
"modelIndex": 0,
|
||||
"enableTools": [
|
||||
{
|
||||
"name": "add",
|
||||
|
Loading…
x
Reference in New Issue
Block a user