feat: 增加知识库新类型FAQ知识库

This commit is contained in:
2026-02-24 13:07:14 +08:00
parent e27ba8d457
commit a9060ed2b9
27 changed files with 1701 additions and 58 deletions

View File

@@ -0,0 +1,181 @@
<script setup lang="ts">
import {ref} from 'vue';
import {$t} from '@easyflow/locales';
import {Delete, Edit, Plus} from '@element-plus/icons-vue';
import {ElButton, ElMessage, ElMessageBox, ElTable, ElTableColumn,} from 'element-plus';
import {api} from '#/api/request';
import HeaderSearch from '#/components/headerSearch/HeaderSearch.vue';
import PageData from '#/components/page/PageData.vue';
import FaqEditDialog from './FaqEditDialog.vue';
const props = defineProps({
knowledgeId: {
type: String,
required: true,
},
});
const pageDataRef = ref();
const dialogVisible = ref(false);
const editData = ref<any>({});
const queryParams = ref({
collectionId: props.knowledgeId,
});
const headerButtons = [
{
key: 'add',
text: $t('button.add'),
icon: Plus,
type: 'primary',
},
];
const reloadList = () => {
pageDataRef.value.setQuery(queryParams.value);
};
const handleSearch = (keyword: string) => {
pageDataRef.value.setQuery({
...queryParams.value,
question: keyword,
});
};
const openAddDialog = () => {
editData.value = {
collectionId: props.knowledgeId,
answerHtml: '',
question: '',
};
dialogVisible.value = true;
};
const handleButtonClick = (event: any) => {
if (event.key === 'add') {
openAddDialog();
}
};
const openEditDialog = (row: any) => {
editData.value = {
id: row.id,
collectionId: row.collectionId,
question: row.question,
answerHtml: row.answerHtml,
orderNo: row.orderNo,
};
dialogVisible.value = true;
};
const saveFaq = async (payload: any) => {
const url = payload.id ? '/api/v1/faqItem/update' : '/api/v1/faqItem/save';
const res = await api.post(url, payload);
if (res.errorCode === 0) {
ElMessage.success(payload.id ? $t('message.updateOkMessage') : $t('message.saveOkMessage'));
dialogVisible.value = false;
reloadList();
} else {
ElMessage.error(res.message);
}
};
const removeFaq = (row: any) => {
ElMessageBox.confirm($t('message.deleteAlert'), $t('message.noticeTitle'), {
confirmButtonText: $t('button.confirm'),
cancelButtonText: $t('button.cancel'),
type: 'warning',
}).then(() => {
api.post('/api/v1/faqItem/remove', { id: row.id }).then((res) => {
if (res.errorCode === 0) {
ElMessage.success($t('message.deleteOkMessage'));
reloadList();
} else {
ElMessage.error(res.message);
}
});
});
};
</script>
<template>
<div class="faq-table-wrapper">
<div class="faq-header">
<HeaderSearch
:buttons="headerButtons"
@search="handleSearch"
@button-click="handleButtonClick"
/>
</div>
<PageData
ref="pageDataRef"
page-url="/api/v1/faqItem/page"
:page-size="10"
:extra-query-params="queryParams"
>
<template #default="{ pageList }">
<ElTable :data="pageList" size="large">
<ElTableColumn
prop="question"
:label="$t('documentCollection.faq.question')"
min-width="220"
/>
<ElTableColumn
prop="answerText"
:label="$t('documentCollection.faq.answer')"
min-width="260"
show-overflow-tooltip
/>
<ElTableColumn :label="$t('common.handle')" width="170" align="right">
<template #default="{ row }">
<ElButton link type="primary" :icon="Edit" @click="openEditDialog(row)">
{{ $t('button.edit') }}
</ElButton>
<ElButton link type="danger" :icon="Delete" @click="removeFaq(row)">
{{ $t('button.delete') }}
</ElButton>
</template>
</ElTableColumn>
</ElTable>
</template>
</PageData>
<FaqEditDialog
v-model="dialogVisible"
:data="editData"
@submit="saveFaq"
/>
</div>
</template>
<style scoped>
.faq-table-wrapper {
width: 100%;
border: 1px solid var(--el-border-color-lighter);
border-radius: 12px;
padding: 14px 16px 8px;
background: var(--el-fill-color-blank);
}
.faq-header {
margin-bottom: 12px;
}
:deep(.el-table) {
border-radius: 10px;
overflow: hidden;
}
:deep(.el-table th.el-table__cell) {
background: var(--el-fill-color-light);
}
:deep(.el-table td.el-table__cell) {
padding-top: 14px;
padding-bottom: 14px;
}
</style>