-
Notifications
You must be signed in to change notification settings - Fork 2.7k
feat: Base node knowledge option #4936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| <template> | ||
| <el-form-item | ||
| :label="$t('dynamicsForm.Knowledge.label', '可选知识库')" | ||
| prop="knowledge_list" | ||
| :rules="[{ message: '请至少选择一个可选知识库', type: 'array', min: 1 }]" | ||
| > | ||
| <template #label> | ||
| <div | ||
| class="flex-between mb-12 cursor" | ||
| @click="collapseData.optional_knowledge = !collapseData.optional_knowledge" | ||
| > | ||
| <div class="flex align-center"> | ||
| <el-icon | ||
| class="mr-8 arrow-icon" | ||
| :class="collapseData.optional_knowledge ? 'rotate-90' : ''" | ||
| > | ||
| <CaretRight /> | ||
| </el-icon> | ||
| <span class="lighter">可选知识库</span> | ||
| <span class="ml-4" v-if="formValue.knowledge_list?.length" | ||
| >({{ formValue.knowledge_list.length }})</span | ||
| > | ||
| </div> | ||
| <div> | ||
| <el-button type="primary" link @click.stop="openAddKnowledgeDialog"> | ||
| <AppIcon iconName="app-add-outlined"></AppIcon> | ||
| </el-button> | ||
| </div> | ||
| </div> | ||
| </template> | ||
| <div class="w-full" v-if="collapseData.optional_knowledge"> | ||
| <el-text type="info" v-if="formValue.knowledge_list?.length === 0"> | ||
| 请选择关联的知识库 | ||
| </el-text> | ||
| <div v-else> | ||
| <template v-for="(item, index) in formValue.knowledge_list" :key="item.id"> | ||
| <div class="flex-between border border-r-6 white-bg mb-4" style="padding: 5px 8px"> | ||
| <div class="flex align-center" style="width: 80%"> | ||
| <KnowledgeIcon :type="item.type" class="mr-8" :size="20" /> | ||
|
|
||
| <span class="ellipsis cursor" :title="item.name"> {{ item.name }}</span> | ||
| </div> | ||
| <el-button text @click="removeKnowledge(item.id)"> | ||
| <el-icon><Close /></el-icon> | ||
| </el-button> | ||
| </div> | ||
| </template> | ||
| </div> | ||
| </div> | ||
| </el-form-item> | ||
| <el-form-item | ||
| :label="$t('dynamicsForm.Knowledge.defaultLabel', '默认知识库')" | ||
| prop="default_value" | ||
| required | ||
| :rules="[{ message: '请选择默认知识库', type: 'array', min: 1 }]" | ||
| > | ||
| <div class="w-full" v-if="formValue.knowledge_list?.length > 0"> | ||
| <Knowledge | ||
| v-model="formValue.default_value" | ||
| :form-field="{ attrs: { knowledge_list: formValue.knowledge_list } } as any" | ||
| /> | ||
| </div> | ||
| </el-form-item> | ||
| <AddKnowledgeDialog | ||
| ref="AddKnowledgeDialogRef" | ||
| @addData="addKnowledge" | ||
| :data="formValue.knowledge_list" | ||
| :loading="knowledgeLoading" | ||
| /> | ||
| </template> | ||
| <script setup lang="ts"> | ||
| import { computed, reactive, ref } from 'vue' | ||
| import AddKnowledgeDialog from '@/views/application/component/AddKnowledgeDialog.vue' | ||
| import Knowledge from '../../items/Knowledge/Knowledge.vue' | ||
|
|
||
| const props = defineProps<{ | ||
| modelValue: any | ||
| }>() | ||
|
|
||
| const emit = defineEmits(['update:modelValue']) | ||
|
|
||
| const collapseData = reactive({ | ||
| optional_knowledge: true, | ||
| }) | ||
| const knowledgeLoading = ref(false) | ||
|
|
||
| const formValue = computed({ | ||
| set: (item: any) => { | ||
| emit('update:modelValue', item) | ||
| }, | ||
| get: () => { | ||
| return props.modelValue || { knowledge_list: [], default_value: [] } | ||
| }, | ||
| }) | ||
|
|
||
| const getData = () => { | ||
| const knowledgeItemList = (formValue.value.knowledge_list || []).map((k: any) => { | ||
| return { | ||
| id: k.id, | ||
| name: k.name, | ||
| type: k.type, | ||
| } | ||
| }) | ||
|
|
||
| return { | ||
| input_type: 'Knowledge', | ||
| default_value: formValue.value.default_value || [], | ||
| attrs: { | ||
| knowledge_list: knowledgeItemList, | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| const rander = (form_data: any) => { | ||
| formValue.value.default_value = form_data.default_value || [] | ||
| formValue.value.knowledge_list = form_data.attrs?.knowledge_list || [] | ||
| } | ||
|
|
||
| defineExpose({ getData, rander }) | ||
|
|
||
| const AddKnowledgeDialogRef = ref<InstanceType<typeof AddKnowledgeDialog>>() | ||
|
|
||
| function openAddKnowledgeDialog() { | ||
| const ids = formValue.value.knowledge_list?.map((k: any) => k.id) || [] | ||
| AddKnowledgeDialogRef.value?.open(ids) | ||
| } | ||
|
|
||
| function addKnowledge(data: any[]) { | ||
| formValue.value.knowledge_list = data | ||
| if (formValue.value.default_value) { | ||
| const currentIds = data.map((k: any) => k.id) | ||
| formValue.value.default_value = formValue.value.default_value.filter((id: string) => | ||
| currentIds.includes(id), | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| function removeKnowledge(id: string) { | ||
| formValue.value.knowledge_list = formValue.value.knowledge_list.filter((k: any) => k.id !== id) | ||
| if (formValue.value.default_value) { | ||
| formValue.value.default_value = formValue.value.default_value.filter( | ||
| (k_id: string) => k_id !== id, | ||
| ) | ||
| } | ||
| } | ||
| </script> | ||
| <style lang="scss" scoped></style> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| <template> | ||
| <div class="w-full"> | ||
| <el-select | ||
| v-model="selectedIds" | ||
| multiple | ||
| class="w-full" | ||
| :placeholder="$t('dynamicsForm.Knowledge.placeholder', '请选择知识库')" | ||
| > | ||
| <el-option v-for="item in availableList" :key="item.id" :label="item.name" :value="item.id"> | ||
| <div class="flex align-center"> | ||
| <KnowledgeIcon :type="item.type" class="mr-8" :size="20" /> | ||
| <span>{{ item.name }}</span> | ||
| </div> | ||
| </el-option> | ||
| <template #tag> | ||
| <el-tag | ||
| v-for="item in selectedItems" | ||
| :key="item.id" | ||
| closable | ||
| type="info" | ||
| @close="removeItem(item.id)" | ||
| style="margin-right: 4px" | ||
| > | ||
| <div class="flex align-center"> | ||
| <KnowledgeIcon :type="item.type" class="mr-4" :size="16" /> | ||
| <span>{{ item.name }}</span> | ||
| </div> | ||
| </el-tag> | ||
| </template> | ||
| </el-select> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| import { computed } from 'vue' | ||
| import type { FormField } from '../../type' | ||
|
|
||
| const props = withDefaults( | ||
| defineProps<{ | ||
| modelValue?: string[] | ||
| formField: FormField | ||
| }>(), | ||
| { modelValue: () => [] }, | ||
| ) | ||
|
|
||
| const emit = defineEmits(['update:modelValue', 'change']) | ||
|
|
||
| const model_value = computed({ | ||
| get: () => props.modelValue || [], | ||
| set: (value: string[]) => { | ||
| emit('update:modelValue', value) | ||
| emit('change', props.formField) | ||
| }, | ||
| }) | ||
|
|
||
| const availableList = computed(() => { | ||
| return (props.formField.attrs?.knowledge_list as any[]) || [] | ||
| }) | ||
|
|
||
| const selectedItems = computed(() => { | ||
| return availableList.value.filter((k: any) => selectedIds.value.includes(k.id)) | ||
| }) | ||
|
|
||
| const selectedIds = computed({ | ||
| get: () => model_value.value || [], | ||
| set: (ids: string[]) => { | ||
| model_value.value = ids | ||
| }, | ||
| }) | ||
|
|
||
| function removeItem(id: string) { | ||
| model_value.value = model_value.value.filter((item_id: string) => item_id !== id) | ||
| } | ||
| </script> | ||
| <style lang="scss" scoped></style> | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There seems to be an issue with the template slot Here are some optimization suggestions:
For example: <script setup>
// ... existing code ...
const selectedItems = computed(() =>
availableList.value.reduce((acc, item) => {
const isSelected = selectedIds.some(id => id === item.id);
acc[isSelected ? 'push' : 'unshift'](item);
return acc;
}, [])
);
function addItemToSelection(key: string | null): void {
if (!key || !items.find(i => i.key == key)) return;
model_value.value.push(key);
}
function removeItemFromSelection(key: string | null): void {
model_value.value = model_value.value.filter(id => id != key);
}
</script>These changes will ensure that |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -502,7 +502,10 @@ | |
|
|
||
| <!-- 技能 --> | ||
| <div v-if="toolPermissionPrecise.read()"> | ||
| <div class="flex-between mb-8" @click="collapseData.skill = !collapseData.skill"> | ||
| <div | ||
| class="flex-between mb-8" | ||
| @click="collapseData.skill = !collapseData.skill" | ||
| > | ||
| <div class="flex align-center lighter cursor"> | ||
| <el-icon | ||
| class="mr-8 arrow-icon" | ||
|
|
@@ -535,7 +538,10 @@ | |
| collapseData.skill | ||
| " | ||
| > | ||
| <template v-for="(item, index) in applicationForm.skill_tool_ids" :key="index"> | ||
| <template | ||
| v-for="(item, index) in applicationForm.skill_tool_ids" | ||
| :key="index" | ||
| > | ||
| <div | ||
| v-if="relatedObject(skillToolSelectOptions, item, 'id')" | ||
| class="flex-between border border-r-6 white-bg mb-4" | ||
|
|
@@ -550,7 +556,9 @@ | |
| class="mr-8" | ||
| > | ||
| <img | ||
| :src="resetUrl(relatedObject(skillToolSelectOptions, item, 'id')?.icon)" | ||
| :src=" | ||
| resetUrl(relatedObject(skillToolSelectOptions, item, 'id')?.icon) | ||
| " | ||
| alt="" | ||
| /> | ||
| </el-avatar> | ||
|
|
@@ -809,8 +817,6 @@ | |
| </el-button> | ||
| </div> | ||
| </el-form-item> | ||
|
|
||
|
|
||
| </el-form> | ||
| </el-scrollbar> | ||
| </div> | ||
|
|
@@ -846,8 +852,8 @@ | |
| @refresh="submitReasoningDialog" | ||
| /> | ||
| <McpServersDialog ref="mcpServersDialogRef" @refresh="submitMcpServersDialog" /> | ||
| <ToolDialog ref="toolDialogRef" @refresh="submitToolDialog" tool_type="CUSTOM"/> | ||
| <ToolDialog ref="skillToolDialogRef" @refresh="submitSkillToolDialog" tool_type="SKILL"/> | ||
| <ToolDialog ref="toolDialogRef" @refresh="submitToolDialog" tool_type="CUSTOM" /> | ||
| <ToolDialog ref="skillToolDialogRef" @refresh="submitSkillToolDialog" tool_type="SKILL" /> | ||
| <ApplicationDialog ref="applicationDialogRef" @refresh="submitApplicationDialog" /> | ||
| </div> | ||
| </template> | ||
|
|
@@ -988,7 +994,6 @@ const knowledgeList = ref<Array<any>>([]) | |
| const sttModelOptions = ref<any>(null) | ||
| const ttsModelOptions = ref<any>(null) | ||
|
|
||
|
|
||
| function submitPrologueDialog(val: string) { | ||
| applicationForm.value.prologue = val | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a few issues in the provided code, primarily related to incorrect formatting and syntax errors:
Here's the corrected version of the code: <div v-if="toolPermissionPrecise.read()"> <!-- Corrected if statement -->
<!-- 技能 -->
<div
class="flex-between mb-8"
@click="collapseData.skill = !collapseData.skill"
>
<div class="flex align-center lighter cursor">
<el-icon
class="mr-8 arrow-icon"
></el-icon>
技能
</div>
<img src="@/assets/close.svg" alt="" @click.stop="toggleCollapse('skil')" />
</div>
<transition name="slide-fade-in-out">
<div :class="{ active: collapseData.skill }" style="margin-top: 6px;">
<template v-for="(item, index) in applicationForm.skill_tool_ids" :key="index">And here is the complete component with corrections for all issues: <template>
<div class="apply-application-page">
<header
id="page-header"
class="shadow-md bg-white flex justify-between items-start pl-10 pr-24"
>
<h5>应用申请表</h5>
<footer>
<router-link
tag="button"
to="/apply/list/"
class="bg-blue-500 text-sm ml-auto px-6 py-2 rounded hover:bg-black transition-all duration-300 disabled:opacity-40 disabled:pointer-events-none outline-0 shadow-lg focus:bg-black focus:text-white"
>
返回列表页
</router-link>
<slot />
<a href="#" aria-hidden type="button" @click.prevent="$emit('printPage', true)">
<el-button circle class="text-green-500 font-bold"><i class="mdi mdi-printer"></i></el-button>
</a>
<a href="#" aria-hidden type="button" @click.prevent="$emit('copyText', '复制成功!')">
<el-button circle class="text-red-500 font-bold"> <i class="mdi mdi-content-copy"></i></el-button>
</a>
<el-popover placement="bottom-end right">
<!-- 面试官对话框 -->
<button
data-bs-toggle="modal"
data-bs-target="#prologueDialog"
>
简历内容(可选)
</button>
</footer>
</header>
<el-scrollbar height="calc(100% - 73px)" ref="scrollbarRef" v-loading.fullscreen.lock="loading">
<form
action="#!"
autocomplete="on"
class="apply-form-container pt-15 pb-12"
label-position="top"
ref="applicationFormData"
>
...
</form>
<hr color="#eee">
<!-- 提交按钮 -->
<button
type="primary"
class="ml-8 mr-auto mt-8 py-6 px-12 shadow-xl font-bold tracking-wide capitalize text-sm md:mx-[auto] mx-[330px]"
@click="handleApplySubmit()"
>提交</button>
<PrologueDialog
ref="prologueDialogRef"
:visible.sync="dialogVisible"
width="70%"
title="简历详情"
:init-value="applicationForm.prologue ?? ''"
@confirm="submitPrologueDialog"
/>
<ToolDialog ref="toolDialogRef" @refresh="submitToolDialog" tool_type="CUSTOM"/>
<ToolDialog ref="skillToolDialogRef" @refresh="submitSkillToolDialog" tool_type="SKILL"/>
<!-- 其他 components references ... -->
</div>
<script>
// Component definitions ...
export default {
// Component properties and methods
};
</script>
<style scoped>
/* styles */
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: opacity .3s ease;
}
.slide-fade-enter-from,
.slide-fade-leave-to {
opacity: 0;
}
.active {
display: block;
}
</style>
Key Corrections:
These changes should resolve the identified issues in your code. |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your code is well-structured and functional. Here are some minor points to consider:
Arrow Function Usage: Inline arrow functions can sometimes lead to readability issues due to their lack of
thisbinding. You might want to defineprops,emit, and other variables outside of the template.Template Logic: The conditional rendering between
<div>elements withv-ifconditions could be slightly optimized to avoid unnecessary DOM manipulations.Styling: Consider adding more specific classes in the CSS file to improve styling consistency.
Comments: Adding comments throughout the code will help maintain it over time.
Here's an updated version with these considerations:
These changes aim to enhance clarity and maintainability while preserving functionality.