123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- <template>
- <div class="knowledge-container">
- <el-tabs v-model="state.queryParams.Attribution" @tab-change="handleQuery">
- <el-tab-pane label="推荐知识库" name=""> </el-tab-pane>
- <el-tab-pane label="中心知识库" name="中心知识库"> </el-tab-pane>
- <el-tab-pane label="部门知识库" name="部门知识库"> </el-tab-pane>
- <el-tab-pane label="办事指南" name="guide" v-if="['LuZhou'].includes(themeConfig.appScope)"> </el-tab-pane>
- <el-tab-pane label="知识推荐" name="recommend" v-if="['LuZhou'].includes(themeConfig.appScope)"> </el-tab-pane>
- </el-tabs>
- <div class="knowledge-input" v-if="['', '中心知识库', '部门知识库'].includes(state.queryParams.Attribution)">
- <el-input v-model="state.queryParams.Keyword" placeholder="关键词" clearable class="mr10 w100" @keyup.enter="knowledgeRetrievalPaged">
- <template #prefix>
- <SvgIcon name="ele-Search" size="16px" />
- </template>
- <template #append>
- <el-button type="primary" @click="knowledgeRetrievalPaged" class="search-button" size="small" round
- ><SvgIcon name="ele-Search" class="mr4" /> 查询
- </el-button>
- </template>
- </el-input>
- </div>
- <div class="mt5" style="display: flex; flex-wrap: wrap; justify-content: space-between" v-if="state.queryParams.Attribution === ''">
- <div style="display: flex">
- <div style="height: 32px; line-height: 32px">推荐类型:</div>
- <el-radio-group v-model="state.queryParams.recommendType" @change="changeRecommendType">
- <el-radio value="1">关键词推荐</el-radio>
- <el-radio value="2">热点推荐</el-radio>
- </el-radio-group>
- </div>
- <div style="display: flex">
- <div style="height: 32px; line-height: 32px">排序:</div>
- <el-radio-group v-model="state.queryParams.Sort" @change="handleQuery">
- <el-radio value="1">浏览量</el-radio>
- <el-radio value="2">收藏量</el-radio>
- <el-radio value="3">创建时间</el-radio>
- </el-radio-group>
- </div>
- </div>
- <div class="mt10 retrieval-content" v-loading="state.loading" v-if="['', '中心知识库', '部门知识库'].includes(state.queryParams.Attribution)">
- <el-empty description="暂无数据" v-if="!state.knowledgeList.length" class="mb20">
- <template #image>
- <span></span>
- </template>
- </el-empty>
- <el-scrollbar>
- <div v-for="(v, i) in state.knowledgeList" :key="i" class="retrieval-content-item" @click="onPreview(v)">
- <div class="mb10" style="display: flex">
- <p class="text-no-wrap" style="flex: 1">{{ v.title }}</p>
- <el-button type="primary" size="small" @click.stop="changeYYType(v)" v-if="['ZiGong', 'YiBin'].includes(themeConfig.appScope)">{{
- v.isChoose ? '取消引用' : '引用'
- }}</el-button>
- </div>
- <!-- <div class="text-ellipsis2">{{ v.summary }}</div>-->
- <div class="flex-center-between mt10 color-info">
- <div>
- <span class="mr10">创建部门:{{ v.creatorOrgName }}</span>
- <span>创建时间:{{ formatDate(v.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
- </div>
- <div class="flex-center-align">
- <span class="flex-center-align"><SvgIcon name="ele-StarFilled" size="18px" class="mr3" />{{ v.score }}</span>
- <!-- <span class="flex-center-align ml10"><SvgIcon name="ele-ChatDotSquare" size="16px" class="mr3" />{{ v.commentNum }}</span>-->
- <span class="flex-center-align ml10"><SvgIcon name="ele-View" size="16px" class="mr3" />{{ v.pageView }}</span>
- </div>
- </div>
- </div>
- </el-scrollbar>
- </div>
- </div>
- <pagination
- @pagination="knowledgeRetrievalPaged"
- :total="state.knowledgeTotal"
- v-model:current-page="state.queryParams.PageIndex"
- v-model:page-size="state.queryParams.PageSize"
- layout="prev, pager, next"
- class="pt10"
- v-if="['', '中心知识库', '部门知识库'].includes(state.queryParams.Attribution)"
- />
- <!-- 办事指南 -->
- <div v-if="['guide'].includes(state.queryParams.Attribution)" class="guide">
- <div class="flex flex-center-between mt10">
- <el-radio-group v-model="selectType" @change="getGuideType">
- <el-radio-button label="个人" value="1" />
- <el-radio-button label="企业" value="2" />
- </el-radio-group>
- <el-select v-model="guideType" placeholder="请选择办事分类" style="width: 240px" @change="handleQueryGuide">
- <el-option v-for="item in guideTypeList" :key="item.code" :label="item.describe" :value="item.code" />
- </el-select>
- </div>
- <el-input v-model="guideKeyword" placeholder="请输入文档名称" clearable class="mr10 mt10 w100" @keyup.enter="sendGuide">
- <template #append>
- <el-button type="primary" @click="sendGuide" size="small" round>搜索</el-button>
- </template>
- </el-input>
- <div v-loading="state.loading" class="guide-content">
- <el-empty description="暂无数据" v-if="!guideList.length" class="mb20"> </el-empty>
- <el-scrollbar max-height="350px">
- <div v-for="(item, index) in guideList" :key="index" class="guide-content-item">
- <el-button link type="primary" @click="guideDetail(item)">{{ item.name }}</el-button>
- </div>
- </el-scrollbar>
- <pagination
- @pagination="getGuideDataList"
- :total="guideListTotal"
- v-model:current-page="guidePageIndex"
- v-model:page-size="guidePageSize"
- class="pt10"
- />
- </div>
- </div>
- <!-- 推荐知识 -->
- <div v-if="['recommend'].includes(state.queryParams.Attribution)" class="recommend">
- <el-input v-model="recommendKeyword" placeholder="请输入问题内容" clearable class="mr10 w100" @keyup.enter="sendRecommend">
- <template #append>
- <el-button type="primary" @click="sendRecommend" size="small" round>搜索</el-button>
- </template>
- </el-input>
- <div v-loading="state.loading" class="recommend-content">
- <el-empty description="暂无数据" v-if="!recommendList.length" class="mb20"> </el-empty>
- <el-scrollbar max-height="400px">
- <div v-for="(item, index) in recommendList" :key="index" class="recommend-content-item">
- <div class="recommend-content-item-question">问:{{ item.question }}</div>
- <div class="recommend-content-item-answer" v-html="item.answer" style="text-indent: 1em"></div>
- </div>
- </el-scrollbar>
- </div>
- </div>
- <el-dialog :title="dialogTitle" v-model="dialogVisible" draggable destroy-on-close append-to-body>
- <div v-loading="loading" class="formatted-text">
- {{documentContent}}
- </div>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false" class="default-button">关闭</el-button>
- </span>
- </template>
- </el-dialog>
- </template>
- <script setup lang="ts" name="orderAcceptKnowledge">
- // 定义变量内容
- import { onMounted, reactive, defineAsyncComponent, ref, watch } from 'vue';
- import { useRouter } from 'vue-router';
- import { formatDate } from '@/utils/formatTime';
- import { knowledgeRetrieval, knowledgeRetrievalAccept } from '@/api/knowledge/retrieval';
- import { throttle } from '@/utils/tools';
- import { useThemeConfig } from '@/stores/themeConfig';
- import { storeToRefs } from 'pinia';
- import { removeDuplicate } from '@/utils/arrayOperation';
- import { lzRXFZAuth, lzRXFZDocumentDetail, lzRXFZDocumentList, lzRXFZDocumentType, lzRXFZKnowledge } from '@/api/business/lzRXFZ';
- import { useUserInfo } from '@/stores/userInfo';
- import { Cookie } from '@/utils/storage';
- const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
- const props = defineProps({
- type: {
- // 知识库类型 (中心|部门)
- type: String,
- default: '',
- },
- formData: {
- // 表单填写的数据
- type: Object,
- default: () => {
- return {};
- },
- },
- });
- const storesThemeConfig = useThemeConfig();
- const { themeConfig } = storeToRefs(storesThemeConfig);
- const state = reactive<any>({
- loading: false, // 知识检索加载状态
- knowledgeList: [],
- knowledgeTotal: 0,
- queryParams: {
- PageIndex: 1,
- PageSize: 5,
- Keyword: null,
- RetrievalType: 0, // 检索类型
- Attribution: '',
- Sort: '1',
- recommendType: '1',
- },
- });
- // 手动查询,将页码设置为1
- const handleQuery = () => {
- if (['recommend'].includes(state.queryParams.Attribution)) return;
- if (state.queryParams.Attribution === 'guide') {
- getGuideType();
- return;
- }
- state.queryParams.PageIndex = 1;
- knowledgeRetrievalPaged();
- };
- // 知识查询
- const knowledgeRetrievalPaged = throttle(async () => {
- if (['guide', 'recommend'].includes(state.queryParams.Attribution)) return;
- try {
- state.loading = true;
- let request: EmptyObjectType = {};
- if (state.queryParams.recommendType === '1') {
- //关键词
- request = {
- ...state.queryParams,
- Content: props.formData.content,
- };
- Reflect.deleteProperty(request, 'HotspotId');
- }
- if (state.queryParams.recommendType === '2') {
- //关键词
- request = {
- ...state.queryParams,
- HotspotId: props.formData.hotspotId,
- };
- Reflect.deleteProperty(request, 'Content');
- }
- const { result } = await knowledgeRetrievalAccept(request);
- state.knowledgeList = result?.items ?? [];
- state.knowledgeTotal = result?.total ?? 0;
- if (props.formData.knowledgeQuote) {
- for (let i of state.knowledgeList) {
- for (let j of props.formData.knowledgeQuote) {
- if (i.id === j.key) {
- i.isChoose = true;
- }
- }
- }
- }
- state.loading = false;
- } catch (error) {
- console.log(error);
- state.loading = false;
- }
- }, 300);
- const router = useRouter(); //
- // 预览知识
- const onPreview = (row: any) => {
- router.push({
- name: 'knowledgePreview',
- params: {
- id: row.id,
- tagsViewName: '知识查看',
- },
- });
- };
- // 提供外部查询
- const HotspotName = ref('');
- const querySearch = async (name: string) => {
- try {
- // state.queryParams.Keyword = name;
- HotspotName.value = name;
- state.loading = true;
- const request = {
- ...state.queryParams,
- HotspotName: name,
- };
- const res: any = await knowledgeRetrieval(request);
- state.knowledgeList = res.result?.items ?? [];
- state.knowledgeTotal = res.result?.total ?? 0;
- if (props.formData.knowledgeQuote) {
- for (let i of state.knowledgeList) {
- for (let j of props.formData.knowledgeQuote) {
- if (i.id === j.key) {
- i.isChoose = true;
- }
- }
- }
- }
- state.loading = false;
- } catch (error) {
- console.log(error);
- state.loading = false;
- }
- };
- // 切换推荐类型查询
- const changeRecommendType = () => {
- knowledgeRetrievalPaged();
- };
- const emit = defineEmits(['changeYYType']);
- const chooseArray = ref<EmptyArrayType>([]);
- const changeYYType = (row: any) => {
- // 为了实现分页也能选中
- row.isChoose = !row.isChoose;
- if (row.isChoose) {
- chooseArray.value.push(row);
- removeDuplicate(chooseArray.value, row.id);
- }
- // 获取选中的数据
- const data = chooseArray.value.filter((v: any) => v.isChoose);
- const reData = data.map((v: any) => {
- return {
- key: v.id,
- value: v.title,
- };
- });
- console.log(reData);
- emit('changeYYType', reData);
- };
- watch(
- () => props.formData.hotspotId,
- () => {
- knowledgeRetrievalPaged();
- },
- { immediate: true, deep: true }
- );
- // 指南关键词
- const guideKeyword = ref('');
- const selectType = ref('1'); // 选择类型 1 个人 2 企业
- const guideType = ref(null); // 指南类型
- const guideTypeList = ref<EmptyArrayType>([]); // 指南类型列表
- // 获取指南类型列表
- const getGuideType = () => {
- lzRXFZDocumentType({ type: selectType.value })
- .then((res: any) => {
- guideTypeList.value = res.data;
- guideType.value = res.data[0].code;
- handleQueryGuide();
- })
- .catch((err: any) => {
- console.log(err);
- });
- };
- // 根据分类获取指南数据列表
- const guideListTotal = ref(0);
- const guidePageIndex = ref(1);
- const guidePageSize = ref(10);
- const guideList = ref<EmptyArrayType>([]); // 指南列表
- const handleQueryGuide = () => {
- guidePageIndex.value = 1;
- getGuideDataList();
- };
- const getGuideDataList = () => {
- state.loading = true;
- lzRXFZDocumentList({
- type: selectType.value,
- contentType: guideType.value,
- pageNum: guidePageIndex.value,
- pageSize: guidePageSize.value,
- name: guideKeyword.value,
- })
- .then((res: any) => {
- guideListTotal.value = parseInt(res.data?.total);
- guideList.value = res.data.rows;
- state.loading = false;
- })
- .catch((err: any) => {
- console.log(err);
- state.loading = false;
- });
- };
- // 发送问题
- const sendGuide = () => {
- handleQueryGuide();
- };
- // 点击查看文档详情
- const dialogVisible = ref(false);
- const dialogTitle = ref('文档详情');
- const loading = ref(false); // 加载
- const documentContent = ref(null);
- const guideDetail = (item: any) => {
- dialogVisible.value = true;
- loading.value = true;
- dialogTitle.value = `文档详情(${item.name})`;
- lzRXFZDocumentDetail({ documentId: item.id })
- .then((res: any) => {
- documentContent.value = res.data.content;
- loading.value = false;
- })
- .catch((err: any) => {
- console.log(err);
- loading.value = false;
- });
- };
- // 推荐知识关键词
- const recommendKeyword = ref('');
- // 搜索
- const recommendList = ref<EmptyArrayType>([]); // 推荐列表
- const sendRecommend = () => {
- if (!recommendKeyword.value) {
- recommendList.value = [];
- return;
- }
- state.loading = true;
- lzRXFZKnowledge({ content: recommendKeyword.value })
- .then((res: any) => {
- recommendList.value = res.data;
- state.loading = false;
- })
- .catch((err: any) => {
- console.log(err);
- state.loading = false;
- });
- };
- // 热线赋值授权
- const stores = useUserInfo(); // 用户信息
- const { userInfos } = storeToRefs(stores); // 用户信息
- const getRXFZAuth = () => {
- lzRXFZAuth({ uuid: userInfos.value.id })
- .then((res: any) => {
- Cookie.set('lzRXFZToken', res.data.accessToken);
- })
- .catch((err: any) => {
- console.log(err);
- });
- };
- onMounted(() => {
- knowledgeRetrievalPaged();
- if (['LuZhou'].includes(themeConfig.value.appScope)) {
- getRXFZAuth();
- }
- });
- defineExpose({
- knowledgeRetrievalPaged,
- querySearch,
- });
- </script>
- <style scoped lang="scss">
- .knowledge-container {
- position: relative;
- .el-radio {
- margin-right: 10px;
- line-height: 32px;
- }
- .knowledge-search-button {
- height: calc(100% - 6px);
- }
- .retrieval-content {
- &-item {
- border-bottom: var(--el-border);
- padding: 5px 15px;
- margin-bottom: 10px;
- cursor: pointer;
- &:last-child {
- margin-bottom: 0;
- border: none;
- }
- &:hover {
- color: var(--el-color-primary);
- }
- }
- }
- }
- .recommend-content {
- margin-top: 10px;
- .recommend-content-item {
- padding: 5px;
- border-bottom: var(--el-border);
- &:last-child {
- border: none;
- }
- .recommend-content-item-question {
- font-weight: bold;
- margin-bottom: 5px;
- }
- }
- }
- .guide-content {
- margin-top: 10px;
- .guide-content-item {
- padding: 5px;
- border-bottom: var(--el-border);
- &:last-child {
- border: none;
- }
- }
- }
- </style>
|