wujingjing
2024-12-31 5809dbeb20d83b30a9d4e5354016e5d56d9a7e6e
src/components/chat/components/playBar/phrase/CommonPhrases.vue
@@ -1,7 +1,7 @@
<template>
   <div class="container" :class="isHome ? 'top-[100%] mt-[8px]' : 'bottom-[100%] mb-[8px]'">
   <div ref="commonPhrasesRef" class="container" :class="isHome ? 'top-[100%] mt-[8px]' : 'bottom-[100%] mb-[8px]'">
      <div class="container_header">
         <div class="title">常用语</div>
         <div class="question">常用语</div>
         <span class="ywifont ywicon-guanbi text-[15px] cursor-pointer text-[#767a97]" @click="closeCommonPhrases"></span>
      </div>
      <div class="container_content">
@@ -9,10 +9,10 @@
            <div class="w-full h-full absolute top-0">
               <div class="py-0 mt-0 box-border h-full">
                  <div style="overflow-anchor: none" v-for="(item, index) in commonPhrases" :key="index">
                     <div class="phase_item">
                     <div class="phase_item" @click="titleClick(item)">
                        <div class="flex flex-col">
                           <div class="title" @click="titleClick(item)">
                              {{ item.title }}
                           <div class="question">
                              {{ item.question }}
                           </div>
                           <!-- <div class="content">
                              {{ item.content }}
@@ -21,11 +21,11 @@
                        <div class="py-2">
                           <span
                              class="ywifont ywicon-bianji cursor-pointer text-[#767a97] pt-[4px] pr-[6px] pb-[2px] pl-0 rounded-lg !text-[13px]"
                              @click="editCommonPhrases(item)"
                              @click.stop="editCommonPhrases(item)"
                           ></span>
                           <span
                              class="ywifont ywicon-shanchu3 cursor-pointer text-[red] pt-[4px] pr-[6px] pb-[2px] pl-0 rounded-lg"
                              @click="deleteCommonPhrases(item)"
                              @click.stop="deleteCommonPhrases(item)"
                           ></span>
                        </div>
                     </div>
@@ -59,18 +59,22 @@
</template>
<script setup lang="ts">
import { ElMessageBox } from 'element-plus';
import { computed, reactive, ref } from 'vue';
import { addUserSample } from '/@/api/ai/chat';
import { ElMessage, ElMessageBox } from 'element-plus';
import { computed, onMounted, reactive, ref } from 'vue';
import { addUserSample, deleteUserSample, listUserSample, updateUserSample } from '/@/api/ai/chat';
import { activeGroupType, activeRoomId, activeSampleId, setRoomConfig } from '/@/stores/chatRoom';
import { onClickOutside } from '@vueuse/core';
const state = reactive({
   useCommonPhrasesDialog: false,
   show_sample_title: false,
   inputCommonPhrases: '',
   sample_title: null,
   sample_id: null,
});
const commonPhrases = ref([]);
const props = defineProps(['isHome']);
const props = defineProps({
   isHome: Boolean,
});
const isShow = defineModel('isShow', {
   type: Boolean,
});
@@ -85,7 +89,16 @@
   isShow.value = false;
};
//#endregion
//#region ====================== 获取常用语 ======================
const updatePhrase = async () => {
   const res = await listUserSample({
      group_type: activeGroupType.value,
   });
   if (res.json_ok) {
      commonPhrases.value = res.values;
   }
};
//#endregion
//#region ====================== 添加常用语 ======================
//关闭常用语弹窗
const handleClose = () => {
@@ -99,21 +112,43 @@
};
const editCommonPhrases = (item) => {
   state.useCommonPhrasesDialog = true;
   state.inputCommonPhrases = item.content;
   state.show_sample_title = true;
   state.inputCommonPhrases = item.question;
   state.sample_id = item.id;
};
const deleteCommonPhrases = (item) => {
   ElMessageBox.confirm(`你确定要删除常用语吗?<div style="white-space: pre-line;">[${item.title}]</div>`, '提示', {
const deleteCommonPhrases = (row) => {
   ElMessageBox.confirm(`你确定要删除常用语吗?`, '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      dangerouslyUseHTMLString: true,
      closeOnClickModal: false,
      type: 'warning',
   }).then(async () => {
      commonPhrases.value = commonPhrases.value.filter((i) => i.id !== item.id);
      const res = await deleteUserSample({
         sample_id: row.id,
      });
      const foundIndex = commonPhrases.value.findIndex((item) => item === row);
      foundIndex > -1 && commonPhrases.value.splice(foundIndex, 1);
   });
};
//提交常用语
const submitCommonPhrases = async () => {
   if (state.show_sample_title) {
      const res = await updateUserSample({
         sample_id: state.sample_id,
         question: state.inputCommonPhrases,
      });
      if (res.json_ok) {
         const foundIndex = commonPhrases.value.findIndex((item) => item.id === state.sample_id);
         foundIndex > -1 && (commonPhrases.value[foundIndex].question = state.inputCommonPhrases);
         handleClose();
      }
   } else {
      addCommonPhrasesData();
   }
};
//添加一条数据源
const addCommonPhrasesData = async () => {
   const res = await addUserSample({
      question: state.inputCommonPhrases,
      group_type: activeGroupType.value,
@@ -121,111 +156,60 @@
   if (res.json_ok) {
      commonPhrases.value.push({
         id: res.sample_id,
         title: state.inputCommonPhrases,
         question: state.inputCommonPhrases,
      });
      state.useCommonPhrasesDialog = false;
      handleClose();
   }
};
//#endregion
//#region ====================== 常用语到对话框 ======================
const emits = defineEmits<{
   (event: 'updateCommonChatInput', val): void;
   (event: 'updateInput', val): void;
}>();
const titleClick = (item) => {
   emits('updateCommonChatInput', item.title);
   emits('updateInput', item.question);
   isShow.value = false;
   setRoomConfig(activeRoomId.value, 'isAnswerByLLM', false);
   activeSampleId.value = item.id;
};
const commonChatByUser = (data) => {
   const question = data.question;
   const isCommon = commonPhrases.value.findIndex((item) => item.question === question) > -1;
   if (isCommon) {
      return ElMessage.warning('该问题已存在常用语中');
   } else {
      state.inputCommonPhrases = question;
      addCommonPhrasesData();
   }
};
//#endregion
</script>
<style scoped lang="scss">
.container {
   position: absolute;
   width: 100%;
   max-height: 40vh;
   padding: 0 8px 8px;
   left: 0px;
   border-radius: 12px;
   background-color: #ffffff;
   border: 1px solid #e5e5e5;
   box-shadow: 0px 8px 25px 0px #0000000d;
   display: flex;
   flex-direction: column;
   z-index: 990;
   &_header {
      width: 100%;
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      padding: 10px 6px;
      color: #060607;
      .title {
         font-size: 14px;
         color: #060607;
         font-weight: 600;
         line-height: 20px;
         letter-spacing: 0.25px;
         flex-grow: 1;
         display: flex;
      }
const commonPhrasesRef = ref<HTMLDivElement>(null);
onClickOutside(
   commonPhrasesRef,
   () => {
      isShow.value = false;
   },
   {
      ignore: ['.el-message-box'],
   }
   &_content {
      width: 100%;
      max-height: 35vh;
      height: fit-content;
      overflow-y: auto;
      .set_phrases {
         outline: none;
         overflow-y: auto;
         position: relative;
         transition: height 0.1s linear;
         .phase_item {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: center;
            cursor: pointer;
            padding: 6px 8px;
            flex-shrink: 0;
            background: #fff;
            border-radius: 8px;
            width: 100%;
            &:hover {
               background: #e5e7ed;
            }
            .title {
               font-size: 14px;
               color: #060607;
               font-family: PingFang HK;
               font-weight: 600;
               font-style: normal;
               white-space: nowrap;
               text-overflow: ellipsis;
               overflow: hidden;
            }
            .content {
               font-size: 12px;
               color: #5e6772;
               font-family: PingFang SC;
               white-space: nowrap;
               text-overflow: ellipsis;
               overflow: hidden;
            }
         }
      }
   }
   &_add {
      display: flex;
      flex-direction: row;
      align-items: center;
      cursor: pointer;
      padding: 6px 8px;
      background: #fff;
      border-radius: 8px;
      &:hover {
         background: #e5e7ed;
      }
);
const addPhrase = (val) =>{
    if (!props.isHome) {
      let obj = {
         id: val?.historyId,
         question: val?.content.values,
      };
      commonChatByUser(obj);
      isShow.value = true;
   }
}
onMounted(() => {
   updatePhrase();
});
defineExpose({ addPhrase, updatePhrase });
</script>
<style scoped lang="scss">
@use './index.scss';
</style>