yangyin
2024-10-15 20dd2dc0554748c4f8e507374be31e3b5ec7a270
src/components/drawer/CustomDrawer.vue
@@ -30,25 +30,32 @@
                  <el-input v-model="queryParams.sample_title" placeholder="搜索更多" class="set-input" :prefix-icon="Search" clearable>
                  </el-input>
               </div>
               <div class="mt20 w100 relative" v-show="state.businessTagList.length > 0">
               <div class="mt20 w100 relative" v-show="state.customBusinessList.length > 0">
                  <div class="set_custom_label">
                     <div class="chanel-tags">
                        <div v-for="(item, index) in state.businessTagList" :key="index" class="flex items-center">
                           <span class="set-group-name">{{ item.group_name }}</span>
                           <div
                              class="overflow-hidden min-h-[43px] transition-[max-height 0.2s] w100 flex flex-wrap text-xs leading-[14px] items-center"
                           >
                              <div
                                 v-for="(itemChildren, index) in item.Children"
                                 :key="index"
                                 :class="{ 'set-label-active': state.activeBusinessChildName === itemChildren.group_id }"
                                 @click="handleLabelChildClick(itemChildren)"
                                 class="cursor-pointer rounded-xl bg-[#e0e7f] text-[#b2b2b2] text-[12px] transition-[background-color .1s, color .1s, border-color .1s]"
                              >
                                 <el-divider direction="vertical" />{{ itemChildren.group_name }}
                              </div>
                           </div>
                        <div
                           v-for="(item, index) in state.customBusinessList"
                           :key="index"
                           :class="{ 'set-group-label-active': state.activeBusinessName === item.group_id }"
                           class="flex items-center"
                           @click="handleBusinessClick(item)"
                        >
                           <span class="set-group-name">{{ item.group_name }}</span
                           ><el-divider direction="vertical" />
                        </div>
                     </div>
                  </div>
                  <div
                     class="overflow-hidden min-h-[43px] transition-[max-height 0.2s] w100 flex flex-wrap text-xs leading-[14px] items-center pt-2"
                  >
                     <div
                        v-for="(itemChildren, index) in state.customBusinessChildList"
                        :key="index"
                        :class="{ 'set-label-active': state.activeBusinessChildName === itemChildren.group_id }"
                        @click="handleLabelChildClick(itemChildren)"
                        class="cursor-pointer m-[5px] py-[5px] pl-[10px] pr-[14px] rounded-xl border border-solid border-[#b2b2b2] bg-[#e0e7f] text-[#4c4c4c] transition-[background-color .1s, color .1s, border-color .1s]"
                     >
                        {{ itemChildren.group_name }}
                     </div>
                  </div>
                  <div class="mt20 w100" v-show="finalSampleList.length > 0">
@@ -77,32 +84,39 @@
         <div class="box-border w-[354px] flex-1 min-h-0 bg-[#e0e7fb]" v-show="state.activeName == 2">
            <div class="flex flex-col w100 h100 pt-0 pr-[15px] pb-0 pl-[20px] overflow-auto">
               <div class="flex items-center w100 h-[30px] border border-solid border-[#b2b2b2] transition-[border-color 1s] rounded-2xl">
                  <el-input v-model="instructParams.template_title" placeholder="搜索更多" class="set-input" :prefix-icon="Search" clearable>
                  <el-input v-model="officeParams.template_title" placeholder="搜索更多" class="set-input" :prefix-icon="Search" clearable>
                  </el-input>
               </div>
               <div class="mt20 w100 relative" v-show="state.customOfficeList.length > 0">
                  <div class="set_custom_label">
                     <div class="chanel-tags">
                        <div v-for="(item, index) in state.customOfficeList" :key="index" class="flex items-center">
                           <span class="set-group-name">{{ item.group_name }}</span>
                           <div
                              class="overflow-hidden min-h-[43px] transition-[max-height 0.2s] w100 flex flex-wrap text-xs leading-[14px] items-center"
                           >
                              <div
                                 v-for="(itemChildren, index) in item.Children"
                                 :key="index"
                                 :class="{ 'set-label-active': state.activeOfficeChildName === itemChildren.group_id }"
                                 @click="handleOfficeChildClick(itemChildren)"
                                 class="cursor-pointer rounded-xl bg-[#e0e7f] text-[#b2b2b2] text-[12px] transition-[background-color .1s, color .1s, border-color .1s]"
                              >
                                 <el-divider direction="vertical" />{{ itemChildren.group_name }}
                              </div>
                           </div>
                        <div
                           v-for="(item, index) in state.customOfficeList"
                           :key="index"
                           :class="{ 'set-group-label-active': state.activeOfficeName === item.group_id }"
                           class="flex items-center"
                           @click="handleOfficeClick(item)"
                        >
                           <span class="set-group-name">{{ item.group_name }}</span
                           ><el-divider direction="vertical" />
                        </div>
                     </div>
                  </div>
                  <div
                     class="overflow-hidden min-h-[43px] transition-[max-height 0.2s] w100 flex flex-wrap text-xs leading-[14px] items-center pt-2"
                  >
                     <div
                        v-for="(itemChildren, index) in state.customOfficeChildList"
                        :key="index"
                        :class="{ 'set-label-active': state.activeOfficeChildName === itemChildren.group_id }"
                        @click="handleOfficeChildClick(itemChildren)"
                        class="cursor-pointer m-[5px] py-[5px] pl-[10px] pr-[14px] rounded-xl border border-solid border-[#b2b2b2] bg-[#e0e7f] text-[#4c4c4c] transition-[background-color .1s, color .1s, border-color .1s]"
                     >
                        {{ itemChildren.group_name }}
                     </div>
                  </div>
                  <div class="mt20 w100">
                     <div class="w100 pb-[20px] flex overflow-auto flex-col" v-for="item in showInstructList" :key="item.group_id">
                     <div class="w100 pb-[20px] flex overflow-auto flex-col" v-for="item in finalOfficeList" :key="item.group_id">
                        <div class="bg-[#f5f7fd] p-[12px] transition-[background-color .2s] flex flex-col rounded-2xl">
                           <div class="flex justify-between">
                              <span class="set-title">{{ item.template_title }}</span>
@@ -127,22 +141,29 @@
               <div class="mt20 w100 relative" v-show="state.knowledgeBaseList.length > 0">
                  <div class="set_custom_label">
                     <div class="chanel-tags">
                        <div v-for="(item, index) in state.knowledgeBaseList" :key="index" class="flex items-center">
                           <span class="set-group-name">{{ item.group_name }}</span>
                           <div
                              class="overflow-hidden min-h-[43px] transition-[max-height 0.2s] w100 flex flex-wrap text-xs leading-[14px] items-center"
                           >
                              <div
                                 v-for="(itemChildren, index) in item.Children"
                                 :key="index"
                                 :class="{ 'set-label-active': state.activeKnowledgeChildName === itemChildren.group_id }"
                                 @click="handleKnowledgeChildClick(itemChildren)"
                                 class="cursor-pointer rounded-xl bg-[#e0e7f] text-[#b2b2b2] text-[12px] transition-[background-color .1s, color .1s, border-color .1s]"
                              >
                                 <el-divider direction="vertical" />{{ itemChildren.group_name }}
                              </div>
                           </div>
                        <div
                           v-for="(item, index) in state.knowledgeBaseList"
                           :key="index"
                           :class="{ 'set-group-label-active': state.activeKnowledgeName === item.group_id }"
                           class="flex items-center"
                           @click="handleKnowledgeClick(item)"
                        >
                           <span class="set-group-name">{{ item.group_name }}</span
                           ><el-divider direction="vertical" />
                        </div>
                     </div>
                  </div>
                  <div
                     class="overflow-hidden min-h-[43px] transition-[max-height 0.2s] w100 flex flex-wrap text-xs leading-[14px] items-center pt-2"
                  >
                     <div
                        v-for="(itemChildren, index) in state.customKnowledgeChildList"
                        :key="index"
                        :class="{ 'set-label-active': state.activeKnowledgeChildName === itemChildren.group_id }"
                        @click="handleKnowledgeChildClick(itemChildren)"
                        class="cursor-pointer m-[5px] py-[5px] pl-[10px] pr-[14px] rounded-xl border border-solid border-[#b2b2b2] bg-[#e0e7f] text-[#4c4c4c] transition-[background-color .1s, color .1s, border-color .1s]"
                     >
                        {{ itemChildren.group_name }}
                     </div>
                  </div>
                  <div class="mt20 w100" v-show="finalKnowledgeList.length > 0">
@@ -196,9 +217,18 @@
      { ID: 3, Name: '知识库' },
   ],
   activeName: 1,
   activeBusinessChildName: '', //场景
   activeOfficeChildName: '', //办公
   activeKnowledgeChildName: '', //知识库
   activeBusinessName: '', //场景
   activeBusinessChildName: '',
   customBusinessList: [],
   customBusinessChildList: [],
   activeOfficeName: '', //办公
   activeOfficeChildName: '',
   customOfficeList: [],
   customOfficeChildList: [],
   activeKnowledgeName: '', //知识库
   activeKnowledgeChildName: '',
   knowledgeBaseList: [],
   customKnowledgeChildList: [],
   useInstructDialog: false,
   instructInfo: {},
   inputInstruct: '', //可修改指令
@@ -208,19 +238,17 @@
   listInstructLoading: false,
   listSampleExpand: false,
   listInstructExpand: false,
   knowledgeBaseList: [],
   customTagChildList: [],
   customOfficeList: [],
   businessTagList: [],
});
const instructContentList = ref([]); //指令列表
const exampleList = ref([]); //示例列表
//#region ====================== 传参 ======================
const isShow = defineModel('isShow', {
   type: Boolean,
});
const emit = defineEmits(['updateChatInput']);
const rightBox = computed(() => (isShow.value ? 354 : 0));
const emit = defineEmits(['updateChatInput']);
//#endregion
//#region ====================== 业务场景/办公助手/知识库的list ======================
const instructContentList = ref([]); //指令列表
const exampleList = ref([]); //示例列表
//获取模版列表
const getSelectListSample = async () => {
   state.listSampleLoading = true;
@@ -259,35 +287,71 @@
   });
   instructContentList.value = res.templates;
};
//切换到指令/提问
const handleTabClick = (item) => {
//#endregion
//#region ====================== 默认选择第一个的场景的子场景 ======================
//tags标签切换
const handleTabClick = async (item) => {
   state.activeName = item.ID;
   if (state.activeName == 2) {
      if (state.listInstructExpand) return;
      await getUserTemplate();
      state.listInstructExpand = true;
   }
   tagListClick(sectionAList.value);
   getTableData();
};
//场景子场景
const handleBusinessClick = (item) => {
   state.activeBusinessName = item.group_id;
   state.customBusinessChildList = item.Children;
   if (item.Children.length > 0) {
      state.activeBusinessChildName = item.Children[0].group_id ?? '';
   } else {
      state.activeBusinessChildName = '';
      state.customBusinessChildList = [];
   }
};
const handleLabelChildClick = (item) => {
   state.activeBusinessChildName = item.group_id;
};
//办公子场景
const handleOfficeClick = (item) => {
   state.activeOfficeName = item.group_id;
   state.customOfficeChildList = item.Children;
   if (item.Children.length > 0) {
      state.activeOfficeChildName = item.Children[0].group_id ?? '';
   } else {
      state.activeOfficeChildName = '';
      state.customOfficeChildList = [];
   }
};
const handleOfficeChildClick = (item) => {
   state.activeOfficeChildName = item.group_id;
};
//知识库子场景
const handleKnowledgeClick = (item) => {
   state.activeKnowledgeName = item.group_id;
   state.customKnowledgeChildList = item.Children;
   if (item.Children.length > 0) {
      state.activeKnowledgeChildName = item.Children[0].group_id ?? '';
   } else {
      state.activeKnowledgeChildName = '';
      state.customKnowledgeChildList = [];
   }
};
const handleKnowledgeChildClick = (item) => {
   state.activeKnowledgeChildName = item.group_id;
};
//#endregion
//打开高级示例
const toggleShow = async () => {
   isShow.value = !isShow.value;
   if (!isShow.value) {
      loadingData.value = true;
      await getMainSectionList().finally(() => {
         loadingData.value = false;
      });
      getTableData();
   }
   getTableData();
};
//关闭高级示例
const handleCloseTemplate = () => {
   isShow.value = false;
};
//获取主场景列表
const getMainSectionList = async () => {
   const res = await getSectionList();
   const iconList = [
@@ -309,27 +373,19 @@
};
const loadingData = ref(false);
const getTableData = async () => {
   loadingData.value = true;
   try {
   if (!isShow.value) {
      loadingData.value = true;
      await getMainSectionList().finally(() => {
         loadingData.value = false;
      });
      if (state.activeName == 1 || state.activeName == 3) {
         if (state.listSampleExpand) return;
         await getSelectListSample();
         state.listSampleExpand = true;
      }
      if (state.activeName == 2) {
         if (state.listInstructExpand) return;
         await getUserTemplate();
         state.listInstructExpand = true;
      }
   } finally {
      loadingData.value = false;
   }
};
//关闭高级示例
const handleCloseTemplate = () => {
   isShow.value = false;
};
//#region ====================== templateUseClick ======================
const templateUseClick = (row) => {
   state.useInstructDialog = true;
@@ -362,15 +418,18 @@
   }
);
//办公
const instructParams = ref({
const officeParams = ref({
   template_title: '',
});
const { query: queryInstruct, queryData: showInstructList } = useSearch(instructContentList, instructParams);
const { query: queryInstruct, queryData: showInstructList } = useSearch(instructContentList, officeParams);
const finalOfficeList = computed(() => {
   const result = showInstructList.value.filter((item) => item.template_group == state.activeOfficeChildName);
   return result ?? [];
});
const instructQuery = debounce(queryInstruct);
watch(
   () => instructParams.value.template_title,
   () => officeParams.value.template_title,
   (val) => {
      instructQuery();
   }
@@ -387,7 +446,7 @@
const knowledgeQuery = debounce(queryKnowledge);
watch(
   () => instructParams.value.template_title,
   () => officeParams.value.template_title,
   (val) => {
      knowledgeQuery();
   }
@@ -420,8 +479,10 @@
               Children: 'Children',
               ParentID: 'p_group_id',
            });
            state.activeBusinessChildName = treeBusinessList[0].Children[0].group_id ?? '';
            state.businessTagList = treeBusinessList; //业务场景
            state.customBusinessList = treeBusinessList; //业务场景数据源
            state.activeBusinessName = treeBusinessList[0].group_id; //默认选中第一个业务场景
            state.customBusinessChildList = treeBusinessList[0].Children; //默认选中第一个业务场景的第一个子场景的数据源
            state.activeBusinessChildName = treeBusinessList[0].Children[0].group_id;
            break;
         case 2:
            const treeOfficeList = convertListToTree(officeList, {
@@ -429,8 +490,10 @@
               Children: 'Children',
               ParentID: 'p_group_id',
            });
            state.activeOfficeChildName = treeOfficeList[0].Children[0].group_id ?? '';
            state.customOfficeList = treeOfficeList; //办公助手
            state.customOfficeList = treeOfficeList; //办公助手数据源
            state.activeOfficeName = treeOfficeList[0].group_id; //默认选中第一个办公助手
            state.customOfficeChildList = treeOfficeList[0].Children; //默认选中第一个办公助手的第一个子场景的数据源
            state.activeOfficeChildName = treeOfficeList[0].Children[0].group_id; //默认选中第一个办公助手的第一个子场景
            break;
         case 3:
            const treeTagList = convertListToTree(selectTagList, {
@@ -438,14 +501,25 @@
               Children: 'Children',
               ParentID: 'p_group_id',
            });
            state.knowledgeBaseList = treeTagList; //知识库
            state.activeKnowledgeChildName = treeTagList[0].Children[0].group_id ?? '';
            state.knowledgeBaseList = treeTagList; //知识库数据源
            state.activeKnowledgeName = treeTagList[0].group_id; //默认选中第一个知识库
            state.customKnowledgeChildList = treeTagList[0].Children; //默认选中第一个知识库的第一个子场景的数据源
            state.activeKnowledgeChildName = treeTagList[0].Children[0].group_id; //默认选中第一个知识库的第一个子场景
            break;
      }
   } else {
      state.knowledgeBaseList = [];
      state.customBusinessList = [];
      state.customBusinessChildList = [];
      state.customOfficeChildList = [];
      state.customKnowledgeChildList = [];
      state.activeBusinessName = '';
      state.activeBusinessChildName = '';
      state.activeOfficeName = '';
      state.activeOfficeChildName = '';
      state.activeKnowledgeName = '';
      state.activeKnowledgeChildName = '';
      state.customOfficeList = [];
      state.businessTagList = [];
      state.knowledgeBaseList = [];
   }
};
//#endregion
@@ -454,7 +528,6 @@
</script>
<style scoped lang="scss">
.exampleSlide {
   // position: absolute;
   right: 0;
   top: 0;
   height: 100%;
@@ -463,8 +536,7 @@
   z-index: 100;
}
.set_custom_label {
   // height: 141px;
   min-height: 53px;
   min-height: 38px;
   box-sizing: border-box;
   background-color: #f2f4f8;
   border-bottom: 1px solid #eee;
@@ -473,9 +545,12 @@
      position: relative;
      overflow: hidden;
      font-size: 12px;
      color: #000;
      display: flex;
      flex-wrap: wrap;
      line-height: 26px;
      padding: 6px;
      color: #4c4c4c;
      cursor: pointer;
      -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
@@ -571,6 +646,8 @@
      color: #1c86ff;
   }
   .set-label-active {
      border-color: #1c86ff;
      background-color: #ccdcfb;
      color: #1c86ff;
   }
   .example-body {