瀏覽代碼

reactor:知识库调整;

zhangchong 6 月之前
父節點
當前提交
9f6a5e3925

+ 1 - 1
src/api/knowledge/browse.ts

@@ -23,7 +23,7 @@ export const KnowledgePageViewPaged = (params: object) =>{
 export const KnowledgePageViewExport = (data: object) =>{
 	return request({
     url: '/api/v1/Knowledge/pageview/export',
-    method: 'get',
+    method: 'post',
 		data,
 		responseType: 'blob',
 	}, {

+ 13 - 1
src/api/knowledge/index.ts

@@ -265,4 +265,16 @@ export const knowledgeDetailExport = (data: object) => {
 	}, {
 		reduce_data_format: false
 	});
-};
+};
+/**
+ * @description  根据入参分词返回关键词集合
+ * @param {object} params
+ * @return {*}
+ */
+export const knowledgeKeyword = (params: object) => {
+	return request({
+		url: `/api/v1/Knowledge/participle`,
+		method: 'get',
+		params
+	});
+}

+ 1 - 1
src/components/TextTooltip/index.vue

@@ -48,7 +48,7 @@ let isShow = ref<boolean>(true);
 const contentRef = ref();
 const isShowTooltip = function (): void {
 	// 计算span标签的offsetWidth与盒子元素的offsetWidth,给isShow赋值
-	isShow.value = contentRef.value.parentNode?.offsetWidth >= contentRef.value?.offsetWidth;
+	isShow.value = contentRef.value?.parentNode?.offsetWidth >= contentRef.value?.offsetWidth;
 };
 </script>
 <style>

+ 1 - 0
src/views/business/order/index.vue

@@ -712,6 +712,7 @@ const queryList = (isQuery: boolean = false) => {
 			})
 			.catch(() => {
 				state.loading = false;
+				totalLoading.value = false;
 			});
 	}
 };

+ 1 - 1
src/views/knowledge/components/Knowledge-keywords.vue

@@ -159,7 +159,7 @@ const businessTagRemove = () => {
 // 确定选择关键词
 const onConfirm = () => {
 	const ids = proTableRef.value.selectedList.map((item: any) => item.id);
-	const name = proTableRef.value.selectedList.map((item: any) => item.tag).join(',');
+	const name = proTableRef.value.selectedList.map((item: any) => item.tag);
 	emit('selectKeyword', { ids, name });
 	drawerVisible.value = false;
 };

+ 1 - 2
src/views/knowledge/hotWords/index.vue

@@ -22,8 +22,7 @@
 						</el-form-item>
 					</el-form>
 				</template>
-				<!-- 表格 header 按钮 -->
-				<template #tableHeader="scope">
+				<template #tableHeader>
 					<el-button type="primary" @click="onProjectAdd" v-auth="'knowledge:hotWords:add'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
 				</template>
 				<template #type="{ row }">

+ 17 - 4
src/views/knowledge/index/edit.vue

@@ -338,10 +338,11 @@ import { Local } from '@/utils/storage';
 import other from '@/utils/other';
 import { throttle, transformFile } from '@/utils/tools';
 import { treeList } from '@/api/knowledge/type';
-import { KnowledgeAdd, knowledgeContent, KnowledgeGetKnowledge, KnowledgeInfo, KnowledgeUpdate } from '@/api/knowledge';
+import { KnowledgeAdd, knowledgeContent, KnowledgeGetKnowledge, KnowledgeInfo, knowledgeKeyword, KnowledgeUpdate } from '@/api/knowledge';
 import { getCanUseOrg } from '@/api/system/user';
 import { templateList } from '@/views/knowledge/index/template';
 import { disabledDate } from '@/utils/constants';
+import { removeDuplicate } from '@/utils/arrayOperation';
 // 引入组件
 const Editor = defineAsyncComponent(() => import('@/components/Editor/index.vue')); // 富文本编辑器
 const ProcessAudit = defineAsyncComponent(() => import('@/components/ProcessAudit/index.vue')); // 流程审批
@@ -406,8 +407,9 @@ const validatePassContent = (rule: any, value: any, callback: any) => {
 		callback();
 	}
 };
-// 校验标题/摘要/内容是否重复
+// 校验标题/摘要/内容是否重复  根据输入标题检测出关键词填入
 const Repeat = ref<boolean>(false);
+const keyWordsNameArr = ref<any>([]);
 const isRepeat = (type: string) => {
 	if (state.ruleForm[type]) {
 		knowledgeContent({ [type]: state.ruleForm[type], id: state.ruleForm.id })
@@ -419,6 +421,15 @@ const isRepeat = (type: string) => {
 				state.ruleForm[type] = '';
 			});
 	}
+	knowledgeKeyword({title:state.ruleForm.title}).then(res => {
+		if(res.result.length){
+			const nameArr = res.result.map((item:any) => item.tag);
+			const ids = res.result.map((item:any) => item.id);
+			keyWordsNameArr.value = removeDuplicate([...keyWordsNameArr.value,...nameArr]);
+			state.ruleForm.keywordsName = keyWordsNameArr.value.join(',')
+			state.ruleForm.keywords = removeDuplicate([...state.ruleForm.keywords, ...ids]);
+		}
+	})
 };
 // 默认配置
 const defaultContent = ref([
@@ -448,8 +459,10 @@ const addKeywords = () => {
 };
 // 选择关键词
 const selectKeyword = (val: any) => {
-	state.ruleForm.keywordsName = val.name;
-	state.ruleForm.keywords = val.ids;
+	const nameArr = val.name;
+	keyWordsNameArr.value = removeDuplicate([...keyWordsNameArr.value,...nameArr]);
+	state.ruleForm.keywordsName = keyWordsNameArr.value.join(',')
+	state.ruleForm.keywords = removeDuplicate([...state.ruleForm.keywords, ...val.ids]);
 };
 // 选择知识库模板
 const selectTemplate = (val: any) => {

+ 10 - 0
src/views/knowledge/index/index.vue

@@ -193,6 +193,9 @@
 							<el-button type="primary" @click="onAddKnowledge" v-auth="'knowledge:index:add'" :loading="state.loading">
 								<SvgIcon name="ele-Plus" class="mr5" />创建知识
 							</el-button>
+							<el-button type="primary" @click="onAuditBatch" v-auth="'knowledge:index:audit:batch'" :loading="state.loading" :disabled="!scope.isSelected">
+								<SvgIcon name="ele-Edit" class="mr5" />批量审核
+							</el-button>
 							<el-dropdown  v-auth="'knowledge:index:export:detail'" @command="onExportDetail" class="ml12" :disabled="!scope.isSelected">
 								<el-button type="primary" :disabled="!scope.isSelected"  :loading="state.loading">
 									导出知识详情<SvgIcon name="ele-ArrowDown" class="ml3" />
@@ -317,6 +320,9 @@
 							<el-button type="primary" @click="onAddKnowledge" v-auth="'knowledge:index:add'" :loading="state.loading">
 								<SvgIcon name="ele-Plus" class="mr5" />创建知识
 							</el-button>
+							<el-button type="primary" @click="onAuditBatch" v-auth="'knowledge:index:audit:batch'" :loading="state.loading" :disabled="!scope.isSelected">
+								<SvgIcon name="ele-Edit" class="mr5" />批量审核
+							</el-button>
 							<el-dropdown  v-auth="'knowledge:index:export:detail'" @command="onExportDetail" class="ml12" :disabled="!scope.isSelected">
 								<el-button type="primary" :disabled="!scope.isSelected"  :loading="state.loading">
 									导出知识详情<SvgIcon name="ele-ArrowDown" class="ml3" />
@@ -830,6 +836,10 @@ const onExportDetail = (command: string | number | object)=>{
 	}).catch(()=>{
 		state.loading = false;
 	})
+}
+// 批量审核
+const onAuditBatch = ()=>{
+
 }
 onMounted(() => {
 	getKnowledgeType();

+ 98 - 41
src/views/knowledge/retrieval/index.vue

@@ -22,7 +22,7 @@
 								<el-input v-model="filterHot" placeholder="请填写热点名称" class="input-with-select mb10" clearable> </el-input>
 							</el-tab-pane>
 						</el-tabs>
-						<el-scrollbar style="height: calc(100% - 140px);'" ref="scrollBarRef">
+						<el-scrollbar style="height: calc(100% - 160px);'" ref="scrollBarRef">
 							<el-skeleton :loading="state.loading" animated :rows="10" v-if="state.activeName === '0'">
 								<template #default>
 									<el-auto-resizer>
@@ -115,26 +115,26 @@
 						<el-scrollbar ref="scrollBarRef" :style="userInfos.isCenter ? 'height: calc(100% - 90px);' : 'height: calc(100% - 50px)'">
 							<el-skeleton :loading="state.typeLoading" animated :rows="10">
 								<template #default>
-                  <el-auto-resizer>
-                    <template #default="{ height, width }">
-                      <el-tree-v2
-                        :data="state.knowledgeOptions"
-                        highlight-current
-                        :expand-on-click-node="false"
-                        :props="{ children: 'children', label: 'name' }"
-                        @node-click="handleNodeClick"
-                        ref="typeRef"
-                        :filter-method="filterNodeType"
-                        :item-size="32"
-                        empty-text="暂无知识分类"
-                        :height="height"
-                      >
-                        <template #default="{ node }">
-                          <text-tooltip :content="node.label" effect="dark" placement="top"></text-tooltip>
-                        </template>
-                      </el-tree-v2>
-                    </template>
-                  </el-auto-resizer>
+									<el-auto-resizer>
+										<template #default="{ height, width }">
+											<el-tree-v2
+												:data="state.knowledgeOptions"
+												highlight-current
+												:expand-on-click-node="false"
+												:props="{ children: 'children', label: 'name' }"
+												@node-click="handleNodeClick"
+												ref="typeRef"
+												:filter-method="filterNodeType"
+												:item-size="32"
+												empty-text="暂无知识分类"
+												:height="height"
+											>
+												<template #default="{ node }">
+													<text-tooltip :content="node.label" effect="dark" placement="top"></text-tooltip>
+												</template>
+											</el-tree-v2>
+										</template>
+									</el-auto-resizer>
 								</template>
 							</el-skeleton>
 						</el-scrollbar>
@@ -146,32 +146,52 @@
 							<el-option label="全文" :value="0" />
 							<el-option label="标题" :value="1" />
 							<el-option label="知识内容" :value="2" />
-<!--							<el-option label="摘要" :value="3" />-->
+							<!--							<el-option label="摘要" :value="3" />-->
+							<el-option label="关键词" :value="4" />
 						</el-select>
 						<div class="input-with-button w100">
 							<div class="flex">
-								<el-input v-model="state.queryParams.Keyword" placeholder="关键词" clearable class="mr10 w100" @keyup.enter="handleQuery"> </el-input>
+								<el-input
+									v-model="state.queryParams.Keyword"
+									placeholder="多个关键词请用逗号或空格分割"
+									clearable
+									class="mr10 w100"
+									@keyup.enter="handleQuery"
+								>
+								</el-input>
 								<el-button type="primary" class="btn" :loading="state.loading" @click="handleQuery"
 									><SvgIcon name="ele-Search" class="mr5" />搜索</el-button
 								>
 								<el-button @click="resetQuery" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置</el-button>
 							</div>
-							<div class="flex-center-align mt5">
-								<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 class="mt10" style="display: flex">
+								<div style="display: flex; align-items: flex-start; flex-wrap: wrap">
+									<div>猜你想搜:</div>
+									<div class="keyword-box">
+										<span v-for="(v, i) in state.hotWordsList" :key="i" class="keyword-item" @click="keyWordSearch(v.keyWord)">{{ v.keyWord }}</span>
+									</div>
+								</div>
 							</div>
 						</div>
 					</div>
-					<div v-loading="centerLoading" class="center-container-box" :style="userInfos.isCenter ? 'height: calc(100% - 180px);' : 'height: calc(100% - 120px)'">
+					<div style="display: flex; margin: 10px 15px 0">
+						<div style="height: 32px; line-height: 32px">排序:</div>
+						<el-radio-group v-model="state.queryParams.Sort" @change="handleQuery" style="align-items: normal">
+							<el-radio value="1">浏览量</el-radio>
+							<el-radio value="2">评分</el-radio>
+							<el-radio value="3">创建时间</el-radio>
+						</el-radio-group>
+					</div>
+					<div
+						v-loading="centerLoading"
+						class="center-container-box"
+						:style="userInfos.isCenter ? 'height: calc(100% - 210px)' : 'height: calc(100% - 160px)'"
+					>
 						<template v-if="state.retrievalList.length">
 							<el-scrollbar>
 								<div v-for="(v, i) in state.retrievalList" :key="i" class="retrieval-content-item" @click="onPreview(v)" title="查看详情">
 									<h4 class="mb10 text-no-wrap retrieval-content-item-title">{{ v.title }}</h4>
-<!--									<div class="text-ellipsis2">{{ v.summary }}</div>-->
+									<!--									<div class="text-ellipsis2">{{ v.summary }}</div>-->
 									<div class="flex-center-between mt10 color-info">
 										<div>
 											<span class="mr10">创建部门:{{ v.creatorOrgName }}</span>
@@ -186,14 +206,14 @@
 								</div>
 							</el-scrollbar>
 						</template>
-            <el-empty v-else description="暂无结果" />
+						<el-empty v-else description="暂无结果" />
+						<pagination
+							@pagination="queryList"
+							:total="state.total"
+							v-model:current-page="state.queryParams.PageIndex"
+							v-model:page-size="state.queryParams.PageSize"
+						/>
 					</div>
-					<pagination
-						@pagination="queryList"
-						:total="state.total"
-						v-model:current-page="state.queryParams.PageIndex"
-						v-model:page-size="state.queryParams.PageSize"
-					/>
 				</pane>
 				<pane min-size="20" max-size="30" size="20" class="right-container">
 					<p class="flex-center-between pt10">
@@ -221,7 +241,7 @@
 										</div>
 									</el-scrollbar>
 								</template>
-                <el-empty v-else/>
+								<el-empty v-else />
 							</div>
 						</template>
 					</el-skeleton>
@@ -244,6 +264,7 @@ import { Splitpanes, Pane } from 'splitpanes';
 import 'splitpanes/dist/splitpanes.css';
 import { useUserInfo } from '@/stores/userInfo';
 import { storeToRefs } from 'pinia';
+import { getKnowledgeHotWordsList } from '@/api/knowledge/hotWords';
 
 const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 const TextTooltip = defineAsyncComponent(() => import('@/components/TextTooltip/index.vue'));
@@ -265,6 +286,7 @@ const state = reactive<any>({
 	retrievalList: [], // 检索列表
 	hotSpotData: [], // 热点数据
 	typeLoading: false, // 知识类型loading
+	hotWordsList: [], // 获取热词
 });
 const router = useRouter(); // 路由
 const storesUserInfo = useUserInfo();
@@ -415,7 +437,8 @@ const queryList = () => {
 	centerLoading.value = true;
 	knowledgeRetrieval(state.queryParams)
 		.then((res: any) => {
-			state.retrievalList = res.result?.items ?? [];
+			// state.retrievalList = res.result?.items ?? [];
+			state.retrievalList = [...res.result?.items,...res.result?.items,...res.result?.items,...res.result?.items,...res.result?.items,...res.result?.items,...res.result?.items]
 			state.total = res.result?.total ?? 0;
 			centerLoading.value = false;
 		})
@@ -463,11 +486,26 @@ const resetNode = () => {
 	hotRef.value?.setCurrentKey(null);
 	queryList();
 };
+// 获取热词
+const getHotWords = async () => {
+	try {
+		const res: any = await getKnowledgeHotWordsList({ PageIndex: 1, PageSize: 5 });
+		state.hotWordsList = res.result?.items ?? [];
+	} catch (error) {
+		console.log(error);
+	}
+};
+// 点击关键词检索
+const keyWordSearch = (word: string) => {
+	state.queryParams.Keyword = word;
+	handleQuery();
+};
 onMounted(() => {
 	getKnowledgeType();
 	getOrgListApi();
 	queryList();
 	querySearchNum();
+	getHotWords();
 });
 const scrollBarRef = ref<RefType>(); // 滚动条ref
 </script>
@@ -479,6 +517,8 @@ const scrollBarRef = ref<RefType>(); // 滚动条ref
 	}
 	.center-container {
 		height: 100%;
+		display: flex;
+		flex-direction: column;
 		.input-box {
 			display: flex;
 		}
@@ -526,5 +566,22 @@ const scrollBarRef = ref<RefType>(); // 滚动条ref
 	:deep(.el-card__body) {
 		height: 100%;
 	}
+	.keyword-box {
+		display: flex;
+		flex: 1;
+		flex-wrap: wrap;
+		.keyword-item {
+			margin-right: 5px;
+			cursor: pointer;
+			color: var(--el-color-info);
+			font-size: var(--el-font-size-extra-small);
+			&:last-child {
+				margin-right: 0;
+			}
+			&:hover {
+				color: var(--el-color-primary);
+			}
+		}
+	}
 }
 </style>

+ 21 - 2
src/views/todo/seats/accept/Knowledge.vue

@@ -17,7 +17,23 @@
 				</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.Sort" @change="handleQuery">
+					<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">
 			<el-empty description="暂无数据" v-if="!state.knowledgeList.length" class="mb20">
 				<template #image>
@@ -148,7 +164,10 @@ defineExpose({
 <style scoped lang="scss">
 .knowledge-container {
 	position: relative;
-
+	.el-radio {
+		margin-right: 10px;
+		line-height: 32px;
+	}
 	.knowledge-search-button {
 		height: calc(100% - 6px);
 	}