<template>
|
<div ref="commonPhrasesRef" class="container" :class="isHome ? 'top-[100%] mt-[8px]' : 'bottom-[100%] mb-[8px]'">
|
<div class="container_header">
|
<div class="question">常用语</div>
|
<span class="ywifont ywicon-guanbi text-[15px] cursor-pointer text-[#767a97]" @click="closeCommonPhrases"></span>
|
</div>
|
<div class="container_content">
|
<div class="set_phrases" :style="{ height: commonPhrases.length * 46 + 'px' }">
|
<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" @click="titleClick(item)">
|
<div class="flex flex-col">
|
<div class="question">
|
{{ item.question }}
|
</div>
|
<!-- <div class="content">
|
{{ item.content }}
|
</div> -->
|
</div>
|
<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.stop="editCommonPhrases(item)"
|
></span>
|
<span
|
class="ywifont ywicon-shanchu3 cursor-pointer text-[red] pt-[4px] pr-[6px] pb-[2px] pl-0 rounded-lg"
|
@click.stop="deleteCommonPhrases(item)"
|
></span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="container_add" @click="addCommonPhrases">
|
<span class="ywifont ywicon-jia text-[15px] cursor-pointer text-[#767a97]"></span>
|
<div class="grow">添加常用语</div>
|
</div>
|
<el-dialog
|
v-model="state.useCommonPhrasesDialog"
|
:title="`${showCommonPhrases}常用语`"
|
width="500"
|
:before-close="handleClose"
|
style="z-index: 999"
|
>
|
<el-input v-model="state.inputCommonPhrases" :rows="10" type="textarea" placeholder="自定义常用语"></el-input>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="handleClose">取消</el-button>
|
<el-button type="primary" @click="submitCommonPhrases" :disabled="is_input_title">
|
{{ showCommonPhrases }}
|
</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
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: Boolean,
|
});
|
const isShow = defineModel('isShow', {
|
type: Boolean,
|
});
|
//#region ====================== 是否显示常用语 ======================
|
const showCommonPhrases = computed(() => {
|
return state.show_sample_title == true ? (state.sample_title = '编辑') : (state.sample_title = '添加');
|
});
|
const is_input_title = computed(() => {
|
return state.inputCommonPhrases == '' ? true : false;
|
});
|
const closeCommonPhrases = () => {
|
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 = () => {
|
state.useCommonPhrasesDialog = false;
|
};
|
//打开常用语弹窗
|
const addCommonPhrases = () => {
|
state.useCommonPhrasesDialog = true;
|
state.show_sample_title = false;
|
state.inputCommonPhrases = '';
|
};
|
const editCommonPhrases = (item) => {
|
state.useCommonPhrasesDialog = true;
|
state.show_sample_title = true;
|
state.inputCommonPhrases = item.question;
|
state.sample_id = item.id;
|
};
|
const deleteCommonPhrases = (row) => {
|
ElMessageBox.confirm(`你确定要删除常用语吗?`, '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
dangerouslyUseHTMLString: true,
|
closeOnClickModal: false,
|
type: 'warning',
|
}).then(async () => {
|
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,
|
});
|
if (res.json_ok) {
|
commonPhrases.value.push({
|
id: res.sample_id,
|
question: state.inputCommonPhrases,
|
});
|
handleClose();
|
}
|
};
|
//#endregion
|
//#region ====================== 常用语到对话框 ======================
|
const emits = defineEmits<{
|
(event: 'updateInput', val): void;
|
}>();
|
const titleClick = (item) => {
|
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
|
|
const commonPhrasesRef = ref<HTMLDivElement>(null);
|
onClickOutside(
|
commonPhrasesRef,
|
() => {
|
isShow.value = false;
|
},
|
{
|
ignore: ['.el-message-box'],
|
}
|
);
|
|
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>
|