|
@@ -216,54 +216,57 @@
|
|
|
<template v-if="state.detail.type === 1">
|
|
|
<div class="__czr-title_2 mt-4">
|
|
|
工作流
|
|
|
- <template v-if="state.form.workflows.length > 0">
|
|
|
- ({{ state.form.workflows.length }})
|
|
|
- </template>
|
|
|
<CzrButton
|
|
|
type="normal"
|
|
|
- title="新增"
|
|
|
+ :title="state.form.workflowId ? '选择' : '新增'"
|
|
|
class="ml-auto"
|
|
|
@click="onAddWorkflow"
|
|
|
/>
|
|
|
</div>
|
|
|
- <template v-if="state.form.workflows.length > 0">
|
|
|
+ <template v-if="state.form.workflowId">
|
|
|
<div
|
|
|
class="mt-2 flex max-h-42 flex-col gap-2 overflow-y-auto pr-2"
|
|
|
>
|
|
|
- <template v-for="(item, index) in state.form.workflows">
|
|
|
- <div class="flex items-center gap-1.5">
|
|
|
+ <div class="flex items-center gap-1.5">
|
|
|
+ <div
|
|
|
+ class="flex flex-1 items-center overflow-hidden rounded-sm bg-[#F6F8FC] p-2.5"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ src="@/assets/images/workflow/workflow-default-icon.png"
|
|
|
+ class="mr-4 size-15"
|
|
|
+ />
|
|
|
<div
|
|
|
- class="flex flex-1 items-center overflow-hidden rounded-sm bg-[#F6F8FC] p-2.5"
|
|
|
+ class="flex flex-1 flex-col gap-2 overflow-hidden"
|
|
|
>
|
|
|
- <img
|
|
|
- src="@/assets/images/workflow/workflow-default-icon.png"
|
|
|
- class="mr-4 size-15"
|
|
|
- />
|
|
|
<div
|
|
|
- class="flex flex-1 flex-col gap-2 overflow-hidden"
|
|
|
+ class="text-sm font-bold text-[#2E3238]"
|
|
|
+ v-title
|
|
|
>
|
|
|
- <div
|
|
|
- class="text-sm font-bold text-[#2E3238]"
|
|
|
- v-title
|
|
|
- >
|
|
|
- {{ item.name }}
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="text-sm text-[#6F7889]"
|
|
|
- v-title="{ lines: 2 }"
|
|
|
- >
|
|
|
- {{ item.description }}
|
|
|
- </div>
|
|
|
+ {{
|
|
|
+ DictionaryStore.workflows.map.get(
|
|
|
+ state.form.workflowId,
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="text-sm text-[#6F7889]"
|
|
|
+ v-title="{ lines: 2 }"
|
|
|
+ >
|
|
|
+ {{
|
|
|
+ DictionaryStore.workflows.objMap.get(
|
|
|
+ state.form.workflowId,
|
|
|
+ )?.description
|
|
|
+ }}
|
|
|
</div>
|
|
|
</div>
|
|
|
- <SvgIcon
|
|
|
- class="__hover"
|
|
|
- name="czr_del"
|
|
|
- color="var(--czr-error-color)"
|
|
|
- @click="state.form.workflows.splice(index, 1)"
|
|
|
- />
|
|
|
</div>
|
|
|
- </template>
|
|
|
+ <SvgIcon
|
|
|
+ class="__hover"
|
|
|
+ name="czr_del"
|
|
|
+ color="var(--czr-error-color)"
|
|
|
+ @click="state.form.workflowId = ''"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template v-else>
|
|
@@ -289,16 +292,16 @@
|
|
|
</div>
|
|
|
<div class="__czr-title_2 mt-4">
|
|
|
开场白引导问题
|
|
|
- <template v-if="state.form.prologueQuestions.length > 0">
|
|
|
- ({{ state.form.prologueQuestions.length }})
|
|
|
+ <template v-if="state.prologueQuestionsArr.length > 0">
|
|
|
+ ({{ state.prologueQuestionsArr.length }})
|
|
|
</template>
|
|
|
<div class="ml-auto">
|
|
|
<el-radio-group
|
|
|
- v-model="state.form.prologueType"
|
|
|
+ v-model="state.form.prologueNum"
|
|
|
size="small"
|
|
|
>
|
|
|
- <el-radio-button value="three">显示前3条</el-radio-button>
|
|
|
- <el-radio-button value="all">显示全部</el-radio-button>
|
|
|
+ <el-radio-button :value="3">显示前3条</el-radio-button>
|
|
|
+ <el-radio-button :value="0">显示全部</el-radio-button>
|
|
|
</el-radio-group>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -309,7 +312,7 @@
|
|
|
v-if="state.dragRefresh"
|
|
|
>
|
|
|
<template
|
|
|
- v-for="(item, index) in state.form.prologueQuestions"
|
|
|
+ v-for="(item, index) in state.prologueQuestionsArr"
|
|
|
>
|
|
|
<div
|
|
|
class="flex items-center gap-2"
|
|
@@ -335,8 +338,8 @@
|
|
|
:clearable="false"
|
|
|
maxlength="40"
|
|
|
show-word-limit
|
|
|
- @keyup.enter.stop="onEditPrologue(item)"
|
|
|
- @blur="onEditPrologue(item)"
|
|
|
+ @keyup.enter.stop="onEditPrologue(item, index)"
|
|
|
+ @blur="onEditPrologue(item, index)"
|
|
|
/>
|
|
|
</template>
|
|
|
<template v-else> {{ item.value }} </template>
|
|
@@ -345,7 +348,10 @@
|
|
|
class="__hover"
|
|
|
name="czr_del"
|
|
|
color="var(--czr-error-color)"
|
|
|
- @click="state.form.prologueQuestions.splice(index, 1)"
|
|
|
+ @click="
|
|
|
+ (state.form.prologueQuestions.splice(index, 1),
|
|
|
+ state.prologueQuestionsArr.splice(index, 1))
|
|
|
+ "
|
|
|
/>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -381,17 +387,17 @@
|
|
|
required
|
|
|
label="输入方式"
|
|
|
:span="24"
|
|
|
- v-model:param="state.form.method"
|
|
|
+ v-model:param="state.form.userInputMethod"
|
|
|
link="select"
|
|
|
:options="[
|
|
|
- { value: 1, label: '文字/语音输入' },
|
|
|
- { value: 2, label: '语音通话' },
|
|
|
+ { value: 0, label: '文字/语音输入' },
|
|
|
+ { value: 1, label: '语音通话' },
|
|
|
]"
|
|
|
:clearable="false"
|
|
|
/>
|
|
|
<div
|
|
|
class="mt-4 flex items-center"
|
|
|
- v-if="state.form.method == 2"
|
|
|
+ v-if="state.form.userInputMethod == 1"
|
|
|
>
|
|
|
<div class="flex-1">
|
|
|
<CzrFormColumn
|
|
@@ -434,21 +440,25 @@
|
|
|
v-model="state.form.advise.types"
|
|
|
size="small"
|
|
|
>
|
|
|
- <el-checkbox-button value="open">
|
|
|
+ <el-checkbox-button :value="AdviseType.Open">
|
|
|
开启
|
|
|
</el-checkbox-button>
|
|
|
- <template v-if="state.form.advise.types.includes('open')">
|
|
|
- <el-checkbox-button value="tips">
|
|
|
+ <template
|
|
|
+ v-if="state.form.advise.types.includes(AdviseType.Open)"
|
|
|
+ >
|
|
|
+ <el-checkbox-button :value="AdviseType.Tips">
|
|
|
自定义提示词
|
|
|
</el-checkbox-button>
|
|
|
- <el-checkbox-button value="knowledge">
|
|
|
+ <el-checkbox-button :value="AdviseType.Knowledge">
|
|
|
仅从知识库建议
|
|
|
</el-checkbox-button>
|
|
|
</template>
|
|
|
</el-checkbox-group>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <template v-if="state.form.advise.types.includes('open')">
|
|
|
+ <template
|
|
|
+ v-if="state.form.advise.types.includes(AdviseType.Open)"
|
|
|
+ >
|
|
|
<div class="mt-4">
|
|
|
<CzrFormColumn
|
|
|
class="__czr-table-form-column"
|
|
@@ -472,7 +482,9 @@
|
|
|
/>
|
|
|
应用每次回复后,根据对话内容提出最多3条问题建议
|
|
|
</div>
|
|
|
- <template v-if="state.form.advise.types.includes('tips')">
|
|
|
+ <template
|
|
|
+ v-if="state.form.advise.types.includes(AdviseType.Tips)"
|
|
|
+ >
|
|
|
<div class="mt-2">
|
|
|
<CzrFormColumn
|
|
|
class="__czr-table-form-column"
|
|
@@ -487,12 +499,14 @@
|
|
|
</template>
|
|
|
</div>
|
|
|
<template
|
|
|
- v-if="state.form.advise.types.includes('knowledge')"
|
|
|
+ v-if="
|
|
|
+ state.form.advise.types.includes(AdviseType.Knowledge)
|
|
|
+ "
|
|
|
>
|
|
|
<div class="__czr-title_2 mt-4">
|
|
|
问题建议知识库
|
|
|
- <template v-if="state.form.advise.knowledges.length > 0">
|
|
|
- ({{ state.form.advise.knowledges.length }})
|
|
|
+ <template v-if="state.form.advise.datasetIds.length > 0">
|
|
|
+ ({{ state.form.advise.datasetIds.length }})
|
|
|
</template>
|
|
|
<CzrButton
|
|
|
type="normal"
|
|
@@ -501,12 +515,12 @@
|
|
|
@click="onAddAdviseKnowledge"
|
|
|
/>
|
|
|
</div>
|
|
|
- <template v-if="state.form.advise.knowledges.length > 0">
|
|
|
+ <template v-if="state.form.advise.datasetIds.length > 0">
|
|
|
<div
|
|
|
class="mt-2 flex max-h-42 flex-col gap-2 overflow-y-auto pr-2"
|
|
|
>
|
|
|
<template
|
|
|
- v-for="(id, index) in state.form.advise.knowledges"
|
|
|
+ v-for="(id, index) in state.form.advise.datasetIds"
|
|
|
>
|
|
|
<div class="flex items-center gap-1.5">
|
|
|
<div
|
|
@@ -528,7 +542,7 @@
|
|
|
name="czr_del"
|
|
|
color="var(--czr-error-color)"
|
|
|
@click="
|
|
|
- state.form.advise.knowledges.splice(index, 1)
|
|
|
+ state.form.advise.datasetIds.splice(index, 1)
|
|
|
"
|
|
|
/>
|
|
|
</div>
|
|
@@ -695,6 +709,11 @@ const router = useRouter()
|
|
|
const emit = defineEmits([])
|
|
|
const props = defineProps({})
|
|
|
const { proxy }: any = getCurrentInstance()
|
|
|
+enum AdviseType {
|
|
|
+ Open = 1,
|
|
|
+ Tips = 2,
|
|
|
+ Knowledge = 3,
|
|
|
+}
|
|
|
const state: any = reactive({
|
|
|
ID: route.params.id,
|
|
|
isInit: false,
|
|
@@ -704,31 +723,20 @@ const state: any = reactive({
|
|
|
modelId: '',
|
|
|
components: [],
|
|
|
datasetIds: [],
|
|
|
- workflows: [
|
|
|
- {
|
|
|
- name: '水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水',
|
|
|
- description:
|
|
|
- '水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水水',
|
|
|
- },
|
|
|
- ],
|
|
|
+ workflowId: '',
|
|
|
prologue: '',
|
|
|
- prologueQuestions: [
|
|
|
- { value: '1' },
|
|
|
- { value: '2' },
|
|
|
- { value: '3' },
|
|
|
- { value: '4' },
|
|
|
- { value: '5' },
|
|
|
- ],
|
|
|
- prologueType: 'three',
|
|
|
- method: 1,
|
|
|
+ prologueQuestions: [],
|
|
|
+ prologueNum: 3,
|
|
|
+ userInputMethod: 1,
|
|
|
voicePackage: '',
|
|
|
advise: {
|
|
|
types: [],
|
|
|
modelId: '',
|
|
|
tips: '',
|
|
|
- knowledges: [],
|
|
|
+ datasetIds: [],
|
|
|
},
|
|
|
},
|
|
|
+ prologueQuestionsArr: [],
|
|
|
detail: {},
|
|
|
config: {},
|
|
|
knowledgeSelect: {
|
|
@@ -798,20 +806,31 @@ const autoSave = debounce((v) => {
|
|
|
const params: any = {
|
|
|
appId: state.ID,
|
|
|
prePrompt: state.form.tips,
|
|
|
+ openingStatement: state.form.prologue,
|
|
|
+ showAll: state.form.prologueNum,
|
|
|
+ suggestedQuestions: state.form.prologueQuestions,
|
|
|
+ userInputMethod: state.form.userInputMethod,
|
|
|
+ voice: state.form.voicePackage,
|
|
|
+ qsType: state.form.advise.types,
|
|
|
+ qsModelId: state.form.advise.modelId,
|
|
|
+ qsPrePrompt: state.form.advise.tips,
|
|
|
+ qsDatasetIds: state.form.advise.datasetIds,
|
|
|
}
|
|
|
if (state.detail.type === 0) {
|
|
|
params.modelId = state.form.modelId
|
|
|
params.datasetIds = state.form.datasetIds
|
|
|
} else {
|
|
|
+ params.workflowId = state.form.workflowId
|
|
|
}
|
|
|
appModelConfigSave(params)
|
|
|
.then(({ data }: any) => {
|
|
|
state.autoSaveTimestamp = data.updateTime
|
|
|
state.isDebug = false
|
|
|
- loading.close()
|
|
|
})
|
|
|
.catch(() => {})
|
|
|
- .finally(() => {})
|
|
|
+ .finally(() => {
|
|
|
+ loading.close()
|
|
|
+ })
|
|
|
}, 5000)
|
|
|
const initDetail = () => {
|
|
|
state.isInit = false
|
|
@@ -825,10 +844,26 @@ const initDetail = () => {
|
|
|
state.autoSaveTimestamp = configData.updateTime
|
|
|
state.config = JSON.parse(JSON.stringify(configData))
|
|
|
state.form.tips = configData.prePrompt || ''
|
|
|
+ state.form.prologue = configData.openingStatement || ''
|
|
|
+ state.form.prologueNum = Number(configData.showAll) || 3
|
|
|
+ state.form.prologueQuestions = configData.suggestedQuestions || []
|
|
|
+ state.prologueQuestionsArr = state.form.prologueQuestions.map(
|
|
|
+ (v) => ({
|
|
|
+ value: v,
|
|
|
+ }),
|
|
|
+ )
|
|
|
+ state.form.userInputMethod = Number(configData.userInputMethod) || 0
|
|
|
+ state.form.voicePackage = configData.voice || ''
|
|
|
+ state.form.advise.types =
|
|
|
+ configData.qsType?.map((v) => Number(v)) || []
|
|
|
+ state.form.advise.modelId = configData.qsModelId || ''
|
|
|
+ state.form.advise.tips = configData.qsPrePrompt || ''
|
|
|
+ state.form.advise.datasetIds = configData.qsDatasetIds || []
|
|
|
if (state.detail.type === 0) {
|
|
|
state.form.modelId = configData.modelId || ''
|
|
|
state.form.datasetIds = configData.datasetIds || []
|
|
|
} else {
|
|
|
+ state.form.workflowId = configData.workflowId
|
|
|
}
|
|
|
setTimeout(() => {
|
|
|
state.isInit = true
|
|
@@ -862,11 +897,11 @@ const initDrag = () => {
|
|
|
animation: 150,
|
|
|
handle: '.drag-icon', // 设置可拖拽行的类名(el-table自带的类名)
|
|
|
onEnd: ({ newIndex, oldIndex }: any) => {
|
|
|
- const d = [...state.form.prologueQuestions]
|
|
|
+ const d = [...state.prologueQuestionsArr]
|
|
|
const targetRow = d[oldIndex]
|
|
|
d.splice(oldIndex, 1)
|
|
|
d.splice(newIndex, 0, targetRow)
|
|
|
- state.form.prologueQuestions = [...d]
|
|
|
+ state.prologueQuestionsArr = [...d]
|
|
|
state.dragRefresh = false
|
|
|
setTimeout(() => {
|
|
|
state.dragRefresh = true
|
|
@@ -885,7 +920,7 @@ const onAddKnowledge = () => {
|
|
|
}
|
|
|
const onAddAdviseKnowledge = () => {
|
|
|
state.knowledgeSelect.transfer = {
|
|
|
- ids: state.form.advise.knowledges,
|
|
|
+ ids: state.form.advise.datasetIds,
|
|
|
type: 'advise',
|
|
|
}
|
|
|
state.knowledgeSelect.show = true
|
|
@@ -910,12 +945,14 @@ const onPrologue = (row) => {
|
|
|
}, 100)
|
|
|
}
|
|
|
const onAddPrologue = () => {
|
|
|
- state.form.prologueQuestions.push({ value: state.prologuesAdd.value + '' })
|
|
|
+ state.form.prologueQuestions.push(state.prologuesAdd.value + '')
|
|
|
+ state.prologueQuestionsArr.push({ value: state.prologuesAdd.value + '' })
|
|
|
state.prologuesAdd.value = ''
|
|
|
}
|
|
|
-const onEditPrologue = (row) => {
|
|
|
+const onEditPrologue = (row, index) => {
|
|
|
if (isValue(row.__value.trim())) {
|
|
|
row.value = row.__value + ''
|
|
|
+ state.form.prologueQuestions[index] = row.__value + ''
|
|
|
}
|
|
|
row.__edit = false
|
|
|
}
|
|
@@ -928,7 +965,7 @@ const getKnowledge = (arr) => {
|
|
|
break
|
|
|
case 'advise':
|
|
|
{
|
|
|
- state.form.advise.knowledges.push(...arr.map((v) => v.id))
|
|
|
+ state.form.advise.datasetIds.push(...arr.map((v) => v.id))
|
|
|
}
|
|
|
break
|
|
|
}
|
|
@@ -966,13 +1003,13 @@ const onPublish = () => {
|
|
|
.submit()
|
|
|
.then(() => {
|
|
|
if (state.detail.type == 1) {
|
|
|
- if (state.form.workflows.length === 0) {
|
|
|
+ if (!state.form.workflowId) {
|
|
|
ElMessage.warning('请添加工作流!')
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
- if (state.form.advise.types.includes('knowledge')) {
|
|
|
- if (state.form.advise.knowledges.length === 0) {
|
|
|
+ if (state.form.advise.types.includes(AdviseType.Knowledge)) {
|
|
|
+ if (state.form.advise.datasetIds.length === 0) {
|
|
|
ElMessage.warning('请添加问题建议知识库!')
|
|
|
return
|
|
|
}
|
|
@@ -1041,18 +1078,19 @@ const onTipsTemplate = () => {
|
|
|
}
|
|
|
const onAddWorkflow = () => {
|
|
|
state.workflowSelect.transfer = {
|
|
|
- id: state.form.workflows[0]?.id,
|
|
|
+ id: state.form.workflowId,
|
|
|
}
|
|
|
state.workflowSelect.show = true
|
|
|
}
|
|
|
const getWorkflow = (val) => {
|
|
|
- state.form.workflows = [val]
|
|
|
+ state.form.workflowId = val.id
|
|
|
}
|
|
|
onMounted(() => {
|
|
|
initDictionary()
|
|
|
initDetail()
|
|
|
})
|
|
|
const initDictionary = () => {
|
|
|
+ DictionaryStore.initWorkflows()
|
|
|
DictionaryStore.initModels()
|
|
|
DictionaryStore.initKnowledges(AppStore.tenantInfo?.id)
|
|
|
}
|