mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: 编排样式
This commit is contained in:
parent
f87919642b
commit
c043592bd7
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.78395 12.7399C8.87529 12.6625 8.93678 12.5557 8.9578 12.4378L10.4173 3.95194C10.4294 3.87835 10.4253 3.803 10.4054 3.73113C10.3855 3.65926 10.3502 3.59258 10.3019 3.53572C10.2536 3.47887 10.1936 3.43318 10.1259 3.40185C10.0582 3.37051 9.98452 3.35427 9.90994 3.35425H8.04041C7.92032 3.35426 7.80413 3.39687 7.7125 3.4745C7.62088 3.55212 7.55976 3.65974 7.54002 3.77819L7.01877 6.78751H4.5168L5.01025 3.95194C5.02234 3.87835 5.01828 3.803 4.99836 3.73113C4.97843 3.65926 4.94311 3.59258 4.89485 3.53572C4.84658 3.47887 4.78653 3.43318 4.71885 3.40185C4.65117 3.37051 4.57748 3.35427 4.5029 3.35425H2.63337C2.51366 3.35562 2.39818 3.39872 2.30683 3.47611C2.21549 3.5535 2.154 3.66033 2.13298 3.77819L0.673494 12.264C0.6614 12.3376 0.665456 12.413 0.685383 12.4849C0.70531 12.5567 0.740631 12.6234 0.788895 12.6803C0.837159 12.7371 0.897213 12.7828 0.964892 12.8141C1.03257 12.8455 1.10626 12.8617 1.18084 12.8617H3.02257C3.14266 12.8617 3.25885 12.8191 3.35048 12.7415C3.4421 12.6639 3.50322 12.5563 3.52296 12.4378L4.07201 9.42848H6.57398L6.08053 12.264C6.06844 12.3376 6.0725 12.413 6.09243 12.4849C6.11235 12.5567 6.14767 12.6234 6.19594 12.6803C6.2442 12.7371 6.30425 12.7828 6.37193 12.8141C6.43961 12.8455 6.5133 12.8617 6.58788 12.8617H8.45741C8.57712 12.8604 8.6926 12.8173 8.78395 12.7399Z" fill="white"/>
|
||||
<path d="M13.686 12.7378C13.7786 12.6617 13.8418 12.5555 13.8644 12.4378L14.6428 7.9134C14.6603 7.83959 14.6613 7.76282 14.6456 7.68859C14.6299 7.61437 14.598 7.54454 14.5522 7.48409C14.5064 7.42364 14.4477 7.37409 14.3805 7.33897C14.3133 7.30385 14.2391 7.28404 14.1633 7.28096H12.2938C12.1741 7.28233 12.0586 7.32543 11.9672 7.40282C11.8759 7.48021 11.8144 7.58704 11.7934 7.7049L10.9872 12.2571C10.9739 12.3303 10.9769 12.4055 10.996 12.4774C11.015 12.5493 11.0497 12.6161 11.0974 12.6731C11.1451 12.7302 11.2048 12.776 11.2723 12.8074C11.3397 12.8388 11.4132 12.855 11.4876 12.8548H13.3571C13.477 12.8553 13.5934 12.814 13.686 12.7378Z" fill="white"/>
|
||||
<path opacity="0.5" d="M14.891 5.59802C14.9822 5.52202 15.0443 5.41679 15.0667 5.30021L15.3239 3.93802C15.3383 3.86434 15.3362 3.78837 15.3176 3.71561C15.2991 3.64284 15.2647 3.5751 15.2168 3.51725C15.1689 3.45941 15.1088 3.41291 15.0408 3.38112C14.9728 3.34932 14.8986 3.33301 14.8235 3.33338H12.9609C12.8428 3.33281 12.7282 3.37345 12.6369 3.4483C12.5455 3.52315 12.4832 3.62752 12.4605 3.74343L12.1964 5.11256C12.1833 5.18609 12.1863 5.2616 12.2054 5.33384C12.2244 5.40607 12.2589 5.4733 12.3065 5.53084C12.3541 5.58839 12.4137 5.63486 12.4811 5.66705C12.5485 5.69923 12.6221 5.71635 12.6968 5.71721H14.5663C14.6851 5.71614 14.7998 5.67403 14.891 5.59802Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.185 14.7097C8.41034 15.273 9.21034 15.2667 9.42667 14.6997L10.8753 10.9044L14.701 9.42671C15.266 9.20838 15.2707 8.41072 14.7083 8.18572L5.28034 4.41438C4.736 4.19672 4.196 4.73705 4.41367 5.28105L8.185 14.7097Z" fill="white"/>
|
||||
<path opacity="0.5" d="M8.33167 4.559C8.275 2.58367 6.65567 1 4.66667 1C2.64167 1 1 2.64167 1 4.66667C1 6.65467 2.58167 8.273 4.55567 8.33167L3.98233 6.898C3.59753 6.77974 3.24987 6.56394 2.97314 6.27157C2.69642 5.9792 2.50004 5.6202 2.4031 5.22948C2.30617 4.83876 2.31196 4.42961 2.41993 4.0418C2.52791 3.65398 2.73438 3.3007 3.01928 3.01629C3.30418 2.73187 3.65781 2.52601 4.04581 2.4187C4.43381 2.3114 4.84298 2.3063 5.23353 2.40391C5.62408 2.50152 5.98274 2.69851 6.27463 2.97574C6.56653 3.25296 6.78174 3.60099 6.89933 3.986L8.33167 4.559Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 904 B |
|
|
@ -1,6 +1,6 @@
|
|||
import Components from '@/components'
|
||||
import ElementPlus from 'element-plus'
|
||||
import { HtmlNode, HtmlNodeModel } from '@logicflow/core'
|
||||
import { HtmlNode, HtmlNodeModel, BaseEdge } from '@logicflow/core'
|
||||
import { createApp, h } from 'vue'
|
||||
import directives from '@/directives'
|
||||
|
||||
|
|
@ -80,6 +80,7 @@ class AppNodeModel extends HtmlNodeModel {
|
|||
}
|
||||
return style
|
||||
}
|
||||
|
||||
setHeight(height: number, inputContainerHeight: number, outputContainerHeight: number) {
|
||||
this.height = height + inputContainerHeight + outputContainerHeight + 100
|
||||
this.baseHeight = height
|
||||
|
|
@ -96,7 +97,7 @@ class AppNodeModel extends HtmlNodeModel {
|
|||
})
|
||||
}
|
||||
setAttributes() {
|
||||
this.width = 500
|
||||
this.width = 340
|
||||
|
||||
const circleOnlyAsTarget = {
|
||||
message: '只允许从右边的锚点连出',
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ class CustomEdgeModel2 extends BezierEdgeModel {
|
|||
const style = super.getEdgeStyle()
|
||||
|
||||
// svg属性
|
||||
style.strokeWidth = 1
|
||||
style.stroke = '#ababac'
|
||||
style.strokeWidth = 2
|
||||
style.stroke = '#BBBFC4'
|
||||
return style
|
||||
}
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<template>
|
||||
<AppAvatar shape="square" style="background: #FF8800;">
|
||||
<img src="@/assets/icon_hi.svg" style="width: 75%" alt="" />
|
||||
</AppAvatar>
|
||||
</template>
|
||||
<script setup lang="ts"></script>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<template>
|
||||
<AppAvatar shape="square" style="background: #D136D1;">
|
||||
<img src="@/assets/icon_start.svg" style="width: 75%" alt="" />
|
||||
</AppAvatar>
|
||||
</template>
|
||||
<script setup lang="ts"></script>
|
||||
|
|
@ -6,11 +6,11 @@
|
|||
<script setup lang="ts">
|
||||
import LogicFlow from '@logicflow/core'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import AiChatNode from './nodes/ai-chat-node/index'
|
||||
import AppEdge from './common/edge/index'
|
||||
import { AppMenu } from './common/menu/index'
|
||||
import '@logicflow/extension/lib/style/index.css'
|
||||
import '@logicflow/core/dist/style/index.css'
|
||||
const nodes: any = import.meta.glob('./nodes/**/index.ts', { eager: true })
|
||||
|
||||
defineOptions({ name: 'WorkFlow' })
|
||||
|
||||
|
|
@ -30,67 +30,72 @@ const graphData = {
|
|||
nodes: [
|
||||
{
|
||||
id: '92a94b25-453d-4a00-aa26-9fed9b487e08',
|
||||
type: 'ai-chat-node',
|
||||
x: -10,
|
||||
y: 239,
|
||||
type: 'base-node',
|
||||
x: 0,
|
||||
y: 250,
|
||||
properties: {
|
||||
height: 200,
|
||||
stepName: 'AI对话',
|
||||
input: [{ key: '输入' }],
|
||||
output: [{ key: '输出' }],
|
||||
node_data: { model: 'shanghai', name: '222' }
|
||||
stepName: '基本信息',
|
||||
// input: [{ key: '输入' }],
|
||||
// output: [{ key: '输出' }],
|
||||
node_data: {
|
||||
name: '2222',
|
||||
desc: '',
|
||||
prologue:
|
||||
'您好,我是 MaxKB 小助手,您可以向我提出 MaxKB 使用问题。\n- MaxKB 主要功能有什么?\n- MaxKB 支持哪些大语言模型?\n- MaxKB 支持哪些文档类型?'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4',
|
||||
type: 'ai-chat-node',
|
||||
x: 143,
|
||||
y: 523,
|
||||
type: 'start-node',
|
||||
x: 0,
|
||||
y: 753,
|
||||
properties: {
|
||||
height: 200,
|
||||
stepName: 'AI对话',
|
||||
input: [{ key: '输入' }],
|
||||
output: [{ key: '输出' }],
|
||||
node_data: { model: 'shanghai', name: '222222' }
|
||||
stepName: '开始',
|
||||
// input: [{ key: '输入' }],
|
||||
output: [{ key: '输出' }]
|
||||
// node_data: { model: 'shanghai', name: '222222' }
|
||||
}
|
||||
}
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
id: 'bc7297fa-2409-4c85-9a4d-3d74c9c1e30f',
|
||||
type: 'app-edge',
|
||||
sourceNodeId: '92a94b25-453d-4a00-aa26-9fed9b487e08',
|
||||
targetNodeId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4',
|
||||
startPoint: { x: 230, y: 333.000005 },
|
||||
endPoint: { x: -97, y: 596.111105 },
|
||||
properties: {},
|
||||
pointsList: [
|
||||
{ x: 230, y: 333.000005 },
|
||||
{ x: 340, y: 333.000005 },
|
||||
{ x: -207, y: 596.111105 },
|
||||
{ x: -97, y: 596.111105 }
|
||||
],
|
||||
sourceAnchorId: '92a94b25-453d-4a00-aa26-9fed9b487e08_输出_right',
|
||||
targetAnchorId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4_输入_left'
|
||||
},
|
||||
{
|
||||
id: '9f5740ce-b55e-42d4-90a2-a06f34d6f5ef',
|
||||
type: 'app-edge',
|
||||
sourceNodeId: '92a94b25-453d-4a00-aa26-9fed9b487e08',
|
||||
targetNodeId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4',
|
||||
startPoint: { x: 230, y: 333.000005 },
|
||||
endPoint: { x: -97, y: 596.111105 },
|
||||
properties: {},
|
||||
pointsList: [
|
||||
{ x: 230, y: 333.000005 },
|
||||
{ x: 340, y: 333.000005 },
|
||||
{ x: -207, y: 596.111105 },
|
||||
{ x: -97, y: 596.111105 }
|
||||
],
|
||||
sourceAnchorId: '92a94b25-453d-4a00-aa26-9fed9b487e08_输出_right',
|
||||
targetAnchorId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4_输入_left'
|
||||
}
|
||||
]
|
||||
// edges: [
|
||||
// {
|
||||
// id: 'bc7297fa-2409-4c85-9a4d-3d74c9c1e30f',
|
||||
// type: 'app-edge',
|
||||
// sourceNodeId: '92a94b25-453d-4a00-aa26-9fed9b487e08',
|
||||
// targetNodeId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4',
|
||||
// startPoint: { x: 230, y: 333.000005 },
|
||||
// endPoint: { x: -97, y: 596.111105 },
|
||||
// properties: {},
|
||||
// pointsList: [
|
||||
// { x: 230, y: 333.000005 },
|
||||
// { x: 340, y: 333.000005 },
|
||||
// { x: -207, y: 596.111105 },
|
||||
// { x: -97, y: 596.111105 }
|
||||
// ],
|
||||
// sourceAnchorId: '92a94b25-453d-4a00-aa26-9fed9b487e08_输出_right',
|
||||
// targetAnchorId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4_输入_left'
|
||||
// },
|
||||
// {
|
||||
// id: '9f5740ce-b55e-42d4-90a2-a06f34d6f5ef',
|
||||
// type: 'app-edge',
|
||||
// sourceNodeId: '92a94b25-453d-4a00-aa26-9fed9b487e08',
|
||||
// targetNodeId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4',
|
||||
// startPoint: { x: 230, y: 333.000005 },
|
||||
// endPoint: { x: -97, y: 596.111105 },
|
||||
// properties: {},
|
||||
// pointsList: [
|
||||
// { x: 230, y: 333.000005 },
|
||||
// { x: 340, y: 333.000005 },
|
||||
// { x: -207, y: 596.111105 },
|
||||
// { x: -97, y: 596.111105 }
|
||||
// ],
|
||||
// sourceAnchorId: '92a94b25-453d-4a00-aa26-9fed9b487e08_输出_right',
|
||||
// targetAnchorId: '34902d3d-a3ff-497f-b8e1-0c34a44d7dd4_输入_left'
|
||||
// }
|
||||
// ]
|
||||
}
|
||||
const lf = ref()
|
||||
|
||||
|
|
@ -145,8 +150,7 @@ onMounted(() => {
|
|||
}
|
||||
})
|
||||
|
||||
lf.value.register(AiChatNode)
|
||||
lf.value.register(AppEdge)
|
||||
lf.value.batchRegister([...Object.keys(nodes).map((key) => nodes[key].default), AppEdge])
|
||||
lf.value.setDefaultEdgeType('app-edge')
|
||||
|
||||
lf.value.render(graphData)
|
||||
|
|
@ -168,7 +172,7 @@ const onmousedown = (shapeItem: ShapeItem) => {
|
|||
lf.value.dnd.startDrag({
|
||||
type: shapeItem.type,
|
||||
properties: shapeItem.properties,
|
||||
icon: shapeItem.icon,
|
||||
icon: shapeItem.icon
|
||||
})
|
||||
}
|
||||
if (shapeItem.callback) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const icons: any = import.meta.glob('./icons/**.vue', { eager: true })
|
||||
function iconComponent(name) {
|
||||
function iconComponent(name: string) {
|
||||
const url = `./icons/${name}.vue`
|
||||
return icons[url]?.default || null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import ChatNodeVue from './index.vue'
|
||||
import { AppNode, AppNodeModel } from '@/components/workflow/common/app-node/index'
|
||||
class ChatNode extends AppNode {
|
||||
constructor(props: any) {
|
||||
super(props, ChatNodeVue)
|
||||
}
|
||||
}
|
||||
export default {
|
||||
type: 'base-node',
|
||||
model: AppNodeModel,
|
||||
view: ChatNode
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<template>
|
||||
<NodeContainer :nodeModel="nodeModel" style="width: 320px">
|
||||
<el-form
|
||||
@submit.prevent
|
||||
:model="chat_data"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
class="mb-24"
|
||||
label-width="auto"
|
||||
ref="aiChatNodeFormRef"
|
||||
>
|
||||
<el-form-item
|
||||
label="应用名称"
|
||||
prop="name"
|
||||
:rules="{
|
||||
message: '应用名称不能为空',
|
||||
trigger: 'blur',
|
||||
required: true
|
||||
}"
|
||||
>
|
||||
<el-input
|
||||
v-model="chat_data.name"
|
||||
maxlength="64"
|
||||
placeholder="请输入应用名称"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="应用描述">
|
||||
<el-input
|
||||
v-model="chat_data.desc"
|
||||
placeholder="请输入应用描述"
|
||||
:rows="3"
|
||||
type="textarea"
|
||||
maxlength="256"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="开场白">
|
||||
<MdEditor
|
||||
style="height: 150px"
|
||||
v-model="chat_data.prologue"
|
||||
:preview="false"
|
||||
:toolbars="[]"
|
||||
:footers="[]"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</NodeContainer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import NodeContainer from '@/components/workflow/common/node-container/index.vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { MdEditor } from 'md-editor-v3'
|
||||
|
||||
const chat_data = computed({
|
||||
get: () => {
|
||||
if (props.nodeModel.properties.node_data) {
|
||||
return props.nodeModel.properties.node_data
|
||||
} else {
|
||||
props.nodeModel.properties.node_data = {
|
||||
name: '',
|
||||
desc: '',
|
||||
prologue:
|
||||
'您好,我是 MaxKB 小助手,您可以向我提出 MaxKB 使用问题。\n- MaxKB 主要功能有什么?\n- MaxKB 支持哪些大语言模型?\n- MaxKB 支持哪些文档类型?'
|
||||
}
|
||||
}
|
||||
return props.nodeModel.properties.node_data
|
||||
},
|
||||
set: (value) => {
|
||||
props.nodeModel.properties.node_data = value
|
||||
}
|
||||
})
|
||||
const props = defineProps<{ nodeModel: any }>()
|
||||
const handleFocus = () => {
|
||||
props.nodeModel.isSelected = false
|
||||
}
|
||||
const aiChatNodeFormRef = ref<FormInstance>()
|
||||
|
||||
const validate = () => {
|
||||
aiChatNodeFormRef.value?.validate()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
props.nodeModel.validate = validate
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import ChatNodeVue from './index.vue'
|
||||
import { AppNode, AppNodeModel } from '@/components/workflow/common/app-node/index'
|
||||
class ChatNode extends AppNode {
|
||||
constructor(props: any) {
|
||||
super(props, ChatNodeVue)
|
||||
}
|
||||
}
|
||||
export default {
|
||||
type: 'start-node',
|
||||
model: AppNodeModel,
|
||||
view: ChatNode
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<NodeContainer :nodeModel="nodeModel" class="start-node" style="width: 320px">
|
||||
<h5 class="title-decoration-1 mb-8">全局变量</h5>
|
||||
<div class="text-bg p-8-12 mb-8">当前时 {time}</div>
|
||||
<h5 class="title-decoration-1 mb-8">参数输出</h5>
|
||||
<div class="text-bg p-8-12 mb-8">用户问题 {question}</div>
|
||||
</NodeContainer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import NodeContainer from '@/components/workflow/common/node-container/index.vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { MdEditor } from 'md-editor-v3'
|
||||
|
||||
const chat_data = computed({
|
||||
get: () => {
|
||||
if (props.nodeModel.properties.node_data) {
|
||||
return props.nodeModel.properties.node_data
|
||||
} else {
|
||||
props.nodeModel.properties.node_data = {
|
||||
name: '',
|
||||
desc: '',
|
||||
prologue:
|
||||
'您好,我是 MaxKB 小助手,您可以向我提出 MaxKB 使用问题。\n- MaxKB 主要功能有什么?\n- MaxKB 支持哪些大语言模型?\n- MaxKB 支持哪些文档类型?'
|
||||
}
|
||||
}
|
||||
return props.nodeModel.properties.node_data
|
||||
},
|
||||
set: (value) => {
|
||||
props.nodeModel.properties.node_data = value
|
||||
}
|
||||
})
|
||||
const props = defineProps<{ nodeModel: any }>()
|
||||
const handleFocus = () => {
|
||||
props.nodeModel.isSelected = false
|
||||
}
|
||||
const aiChatNodeFormRef = ref<FormInstance>()
|
||||
|
||||
const validate = () => {
|
||||
aiChatNodeFormRef.value?.validate()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
props.nodeModel.validate = validate
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.start-node {
|
||||
.text-bg {
|
||||
background: var(--app-layout-bg-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue