Bläddra i källkod

reactor: 140 知识库优化和新需求;

zhangchong 4 månader sedan
förälder
incheckning
191e78672e

+ 1 - 1
.env.development

@@ -3,7 +3,7 @@ VITE_MODE_NAME=development
 # 防止部署多套系统到同一域名不同目录时,变量共用的问题 设置不同的前缀
 VITE_STORAGE_NAME=dev
 # 业务系统基础请求地址
-VITE_API_URL=http://110.188.24.28:50100
+VITE_API_URL=http://110.188.24.28:50300
 # 业务系统socket请求地址
 VITE_API_SOCKET_URL=http://110.188.24.28:50100/hubs/hotline
 # 业务系统文件上传上传请求地址

+ 856 - 0
src/views/knowledge/index/YBIndex.vue

@@ -0,0 +1,856 @@
+<template>
+	<div class="knowledge-index-container layout-padding">
+		<div class="knowledge-index-container-box pd20 h100">
+			<el-tabs v-model="state.queryParams.Attribution" @tab-change="handleClick" v-if="userInfos.isCenter">
+				<el-tab-pane label="中心知识库" name="中心知识库" :disabled="state.tableLoading"></el-tab-pane>
+				<el-tab-pane label="部门知识库" name="部门知识库" :disabled="state.tableLoading"></el-tab-pane>
+			</el-tabs>
+			<splitpanes :horizontal="horizontal" :style="userInfos.isCenter ? 'height: calc(100% - 54px)' :''">
+				<pane min-size="16" max-size="25" size="16" class="left-container">
+					<template v-if="userInfos.isCenter">
+						<template v-if="state.queryParams.Attribution === '中心知识库'">
+							<el-tabs v-model="state.activeName" stretch @tab-change="resetNode">
+								<el-tab-pane label="知识分类" name="1" :disabled="state.tableLoading">
+									<el-input
+										v-model="filterType"
+										placeholder="请填写知识分类名称"
+										class="input-with-select mb10"
+										clearable
+										@input="onQueryChangedType"
+									>
+									</el-input>
+								</el-tab-pane>
+								<el-tab-pane label="部门" name="0" :disabled="state.tableLoading">
+									<el-input v-model="filterOrg" placeholder="请填写部门名称" class="input-with-select mb10" clearable @input="onQueryChanged">
+									</el-input>
+								</el-tab-pane>
+								<el-tab-pane label="热点" name="2" :disabled="state.tableLoading">
+									<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% - 100px);'" ref="scrollBarRef">
+								<el-skeleton :loading="state.loading" animated :rows="10" v-if="state.activeName === '0'">
+									<template #default>
+										<el-auto-resizer>
+											<template #default="{ height, width }">
+												<el-tree-v2
+													:data="state.orgData"
+													highlight-current
+													:expand-on-click-node="false"
+													:props="{ children: 'children', label: 'name' }"
+													@node-click="handleNodeClick"
+													ref="orgRef"
+													:filter-method="filterNode"
+													: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-skeleton :loading="state.typeLoading" animated :rows="10" v-if="state.activeName === '1'">
+									<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"
+													node-key="id"
+												>
+													<template #default="{ node }">
+														<text-tooltip :content="node.label + '(' + node.data.knowledgeNum + ')'" effect="dark" placement="top"></text-tooltip>
+													</template>
+												</el-tree-v2>
+											</template>
+										</el-auto-resizer>
+									</template>
+								</el-skeleton>
+								<el-skeleton :loading="state.loading" animated :rows="10" v-if="state.activeName === '2'">
+									<template #default>
+										<el-tree
+											node-key="id"
+											:load="loadNode"
+											lazy
+											v-if="lazyShow"
+											:props="{
+												label: 'hotSpotFullName',
+												children: 'children',
+												isLeaf: 'hasChild',
+											}"
+											:filter-node-method="filterNodeHot"
+											@node-click="handleNodeClick"
+											highlight-current
+											check-strictly
+											:expand-on-click-node="false"
+											ref="hotRef"
+										/>
+										<el-tree
+											ref="hotRef"
+											:data="state.hotSpotData"
+											node-key="id"
+											v-else
+											default-expand-all
+											highlight-current
+											:props="{
+												label: 'hotSpotFullName',
+												children: 'children',
+											}"
+											:filter-node-method="filterNodeHot"
+											@node-click="handleNodeClick"
+											:expand-on-click-node="false"
+											check-strictly
+										/>
+									</template>
+								</el-skeleton>
+							</el-scrollbar>
+						</template>
+						<template v-else>
+							<el-input v-model="filterOrg" placeholder="请填写部门名称" class="input-with-select mb10" clearable @input="onQueryChanged"> </el-input>
+							<el-scrollbar style="height: calc(100% - 60px);'" ref="scrollBarRef">
+								<el-skeleton :loading="state.loading" animated :rows="10">
+									<template #default>
+										<el-auto-resizer>
+											<template #default="{ height, width }">
+												<el-tree-v2
+													:data="state.orgData"
+													highlight-current
+													:expand-on-click-node="false"
+													:props="{ children: 'children', label: 'name' }"
+													@node-click="handleNodeClick"
+													ref="orgRef"
+													:filter-method="filterNode"
+													: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>
+						</template>
+					</template>
+					<template v-else>
+						<el-input v-model="filterType" placeholder="请填写知识分类名称" class="input-with-select mb10" clearable> </el-input>
+						<el-scrollbar ref="scrollBarRef" noresiz style="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="36"
+												empty-text="暂无知识分类"
+												:height="height"
+											>
+												<template #default="{ node }">
+													<text-tooltip :content="node.label + '(' + node.data.knowledgeNum + ')'" effect="dark" placement="top"></text-tooltip>
+												</template>
+											</el-tree-v2>
+										</template>
+									</el-auto-resizer>
+								</template>
+							</el-skeleton>
+						</el-scrollbar>
+					</template>
+				</pane>
+				<pane class="right-container">
+					<el-tabs v-model="state.queryParams.Status" @tab-change="handleClick">
+						<el-tab-pane :label="v.value" :name="v.key" v-for="(v, i) in state.statusOptions" :key="i" :disabled="state.tableLoading"></el-tab-pane>
+					</el-tabs>
+					<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+						<el-form-item label="审核类型" prop="ModuleCode" v-if="state.queryParams.Status === 1">
+							<el-segmented
+								:options="state.tabAuditingNames"
+								v-model="state.queryParams.ModuleCode"
+								@change="handleQuery"
+								:disabled="state.tableLoading"
+							/>
+						</el-form-item>
+						<el-form-item label="草稿类型" prop="NewDraftsStatus" v-if="state.queryParams.Status === 8">
+							<el-segmented
+								:options="state.tabNewDraftsNames"
+								v-model="state.queryParams.NewDraftsStatus"
+								@change="handleQuery"
+								:disabled="state.tableLoading"
+							/>
+						</el-form-item>
+						<el-form-item label="关键字" prop="Keyword">
+							<el-input
+								v-model="state.queryParams.Keyword"
+								placeholder="标题/创建人/创建部门/来源部门"
+								clearable
+								@keyup.enter="handleQuery"
+								class="keyword-input"
+							/>
+						</el-form-item>
+						<el-form-item label="是否公开" prop="IsPublic">
+							<el-select v-model="state.queryParams.IsPublic" placeholder="请选择是否公开" @change="handleQuery" clearable>
+								<el-option label="是" :value="true" />
+								<el-option label="否" :value="false" />
+							</el-select>
+						</el-form-item>
+						<el-form-item>
+							<el-button type="primary" @click="handleQuery" :loading="state.tableLoading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.tableLoading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+						</el-form-item>
+					</el-form>
+					<vxe-toolbar
+						ref="toolbarRef"
+						:loading="state.tableLoading"
+						custom
+						:refresh="{
+							queryMethod: handleQuery,
+						}"
+						:tools="[{ toolRender: { name: 'exportCurrent' } }, { toolRender: { name: 'exportAll' } }]"
+					>
+						<template #buttons>
+							<el-button type="primary" @click="onAddKnowledge" v-auth="'knowledge:index:add'" :loading="state.tableLoading">
+								<SvgIcon name="ele-Plus" class="mr5" />创建知识
+							</el-button>
+							<el-dropdown v-auth="'knowledge:index:export:detail'" @command="onExportDetail" class="ml12 mr12" :disabled="isChecked">
+								<el-button type="primary" :disabled="isChecked" :loading="state.tableLoading">
+									导出知识详情<SvgIcon name="ele-ArrowDown" class="ml3" />
+								</el-button>
+								<template #dropdown>
+									<el-dropdown-menu>
+										<el-dropdown-item :command="item.key" v-for="item in exportType" :key="item.key">{{ item.value }}</el-dropdown-item>
+									</el-dropdown-menu>
+								</template>
+							</el-dropdown>
+							<el-button
+								type="primary"
+								@click="onAuditBatch"
+								v-if="state.queryParams.Status === 1"
+								v-auth="'knowledge:index:audit:batch'"
+								:loading="state.loading"
+								:disabled="isChecked"
+							>
+								<SvgIcon name="ele-Edit" class="mr5" />批量审核
+							</el-button>
+						</template>
+					</vxe-toolbar>
+					<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+						<vxe-table
+							border
+							:loading="state.tableLoading"
+							:data="state.tableData"
+							:column-config="{ resizable: true }"
+							:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+							ref="tableRef"
+							height="auto"
+							auto-resize
+							show-overflow
+							:print-config="{}"
+							:scrollY="{ enabled: true, gt: 0 }"
+							id="knowledgeManage"
+							:custom-config="{ storage: true }"
+							showHeaderOverflow
+							:params="{ exportMethod: knowledgeExport, exportParams: requestParams }"
+							@checkbox-all="selectAllChangeEvent"
+							@checkbox-change="selectChangeEvent"
+						>
+							<vxe-column type="checkbox" width="50" align="center"></vxe-column>
+							<vxe-column field="workflow.moduleName" title="审核类型" width="120" v-if="state.queryParams.Status === 1"></vxe-column>
+							<vxe-column field="title" title="标题" min-width="200">
+								<template #default="{ row }">
+									<el-button link type="primary" @click="onPreview(row)">{{ row.title }}</el-button>
+								</template>
+							</vxe-column>
+							<vxe-column field="knowledgeTypeText" title="知识分类" width="150"></vxe-column>
+							<vxe-column field="statusName" title="知识状态" width="110"></vxe-column>
+							<vxe-column field="attribution" title="知识归属" width="140"></vxe-column>
+							<vxe-column field="hotspotName" title="热点" width="150"></vxe-column>
+							<vxe-column field="isPublic" title="是否公开" width="100">
+								<template #default="{ row }">
+									{{ row.isPublic ? '是' : '否' }}
+								</template>
+							</vxe-column>
+							<vxe-column field="pageView" title="阅读次数" width="100"></vxe-column>
+							<vxe-column field="onShelfTime" title="上架时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.onShelfTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column field="offShelfTime" title="下架时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.offShelfTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column field="creatorName" title="创建人" width="120"></vxe-column>
+							<vxe-column field="creatorOrgName" title="创建部门" width="150"></vxe-column>
+							<vxe-column field="creationTime" title="创建时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column field="lastModificationTime" title="更新时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.lastModificationTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column title="操作" fixed="right" width="250" align="center">
+								<template #default="{ row }">
+									<el-button
+										link
+										type="primary"
+										@click="onEdit(row)"
+										title="编辑"
+										v-if="[0, 4, 5, 6].includes(row.newStatus) && row.status !== 1"
+										v-auth="'knowledge:index:edit'"
+									>
+										编辑
+									</el-button>
+									<el-button
+										link
+										type="danger"
+										@click="onRowDel(row)"
+										title="删除"
+										v-if="[0, 2, 4, 5, 6].includes(row.newStatus) && row.status !== 1 && ['YiBin'].includes(themeConfig.appScope)"
+										v-auth="'knowledge:index:delete'"
+									>
+										删除
+									</el-button>
+									<el-button
+										link
+										type="primary"
+										@click="offShelfFn(row)"
+										title="下架"
+										v-if="[3].includes(row.newStatus)"
+										v-auth="'knowledge:index:undercarriage'"
+									>
+										下架
+									</el-button>
+									<el-button
+										link
+										type="primary"
+										@click="groundingFn(row)"
+										title="上架"
+										v-if="[4].includes(row.newStatus)"
+										v-auth="'knowledge:index:grounding'"
+									>
+										上架
+									</el-button>
+									<el-button link type="primary" @click="onprogress(row)" title="查看审核记录" v-if="[5].includes(row.newStatus)">
+										审核记录
+									</el-button>
+									<!--									<el-button
+										link
+										type="primary"
+										@click="onAudit(row)"
+										title="审批"
+										v-if="[1, 2].includes(row.status) && row.isCanHandle"
+										v-auth="'business:order:handle'"
+									>
+										审批
+									</el-button>-->
+									<el-button link type="primary" @click="onPreview(row)" title="查看"> 查看 </el-button>
+								</template>
+							</vxe-column>
+						</vxe-table>
+					</div>
+					<pagination
+						@pagination="queryList"
+						:total="state.total"
+						v-model:current-page="state.queryParams.PageIndex"
+						v-model:page-size="state.queryParams.PageSize"
+						:disabled="state.tableLoading"
+					/>
+				</pane>
+			</splitpanes>
+		</div>
+		<!-- 流程审批 -->
+		<process-audit ref="processAuditRef" @orderProcessSuccess="queryList" />
+		<!-- 审核记录 -->
+		<audit-progress ref="auditProgressRef" />
+		<!-- 批量审批 -->
+		<to-end ref="toEndRef" @updateList="queryList" />
+	</div>
+</template>
+
+<script lang="tsx" setup name="knowledgeManage">
+import { ref, reactive, onMounted, watch, defineAsyncComponent, computed } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { formatDate } from '@/utils/formatTime';
+import {
+	KnowledgePaged,
+	KnowledgeOffShelf,
+	KnowledgeOnTheShelf,
+	baseData,
+	KnowledgeDel,
+	knowledgeExport,
+	knowledgeDetailExport,
+} from '@/api/knowledge';
+import { getOrgListByUser } from '@/api/system/organize';
+import { treeList } from '@/api/knowledge/type';
+import { hotSpotSearch, hotSpotType } from '@/api/business/order';
+import { Splitpanes, Pane } from 'splitpanes';
+import 'splitpanes/dist/splitpanes.css';
+import { useUserInfo } from '@/stores/userInfo';
+import { storeToRefs } from 'pinia';
+import Other from '@/utils/other';
+import { downloadFileByStream } from '@/utils/tools';
+import { useThemeConfig } from '@/stores/themeConfig';
+import { VxeUI } from 'vxe-pc-ui';
+
+// 引入组件
+const ProcessAudit = defineAsyncComponent(() => import('@/components/ProcessAudit/index.vue')); // 流程审批
+const AuditProgress = defineAsyncComponent(() => import('@/views/knowledge/components/Audit-progress.vue')); // 编写规范
+const TextTooltip = defineAsyncComponent(() => import('@/components/TextTooltip/index.vue'));
+const ToEnd = defineAsyncComponent(() => import('@/views/knowledge/index/components/To-end.vue')); // 批量审批
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+
+const storesUserInfo = useUserInfo();
+const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
+const storesThemeConfig = useThemeConfig();
+const { themeConfig } = storeToRefs(storesThemeConfig);
+// 定义变量内容
+const state = reactive<any>({
+	queryParams: {
+		PageIndex: 1, //页码
+		PageSize: 20, //每页条数
+		Keyword: null, //关键字
+		Status: 3, //状态 默认已上架
+		OrgId: null, //组织机构
+		HotSpotTypeId: null, //热点分类
+		KnowledgeTypeId: null, //知识类型
+		Title: null, //标题
+		Summary: null, //摘要
+		ModuleCode: '',
+		NewDraftsStatus: -1,
+		Attribution: userInfos.value.isCenter ? '中心知识库' : '部门知识库',
+	},
+	activeName: '1', //tab切换 默认知识分类
+	tableData: [], //表格数据
+	total: 0, //总条数
+	loading: false, //表格loading
+	tableLoading: false, //表格loading
+	orgData: [], //组织机构数据
+	knowledgeOptions: [], //知识库类型数据
+	statusOptions: [], //状态数据
+	hotSpotData: [], //热点数据
+	typeLoading: false, // 知识类型loading
+});
+const router = useRouter(); //路由
+const ruleFormRef = ref<FormInstance>(); //表单ref
+const horizontal = ref(false);
+// 部门查询
+const filterOrg = ref('');
+const orgRef = ref<RefType>();
+const onQueryChanged = (query: string) => {
+	if (query) {
+		orgRef.value!.filter(query);
+	} else {
+		orgRef.value!.filter(query);
+		orgRef.value?.setExpandedKeys([]);
+	}
+};
+const filterNode = (value: string, data: any) => {
+	if (!value) return true;
+	return data.name.includes(value);
+};
+// 知识分类查询
+const filterType = ref('');
+const typeRef = ref<RefType>();
+const onQueryChangedType = (query: string) => {
+	if (query) {
+		typeRef.value!.filter(query);
+	} else {
+		typeRef.value!.filter(query);
+		typeRef.value?.setExpandedKeys([]);
+	}
+};
+const filterNodeType = (value: string, data: any) => {
+	if (!value) return true;
+	return data.name.includes(value);
+};
+// 热点查询
+const filterHot = ref('');
+const hotRef = ref<RefType>();
+watch(filterHot, (val) => {
+	if (val) {
+		lazyShow.value = false; //当填写框有值时关闭懒加载
+		hotSpotSearch(val)
+			.then((res) => {
+				//获取后端搜索的数据
+				state.hotSpotData.length = 0;
+				state.hotSpotData = res.result ?? [];
+				hotRef.value!.filter(val);
+			})
+			.catch((e) => {
+				console.log(e);
+			});
+	} else if (val == '' || val == ' ' || val == null) {
+		lazyShow.value = true; // 懒加载树显示
+	}
+});
+const filterNodeHot = (value: string, data: any) => {
+	if (!value) return true;
+	return data.hotSpotName.includes(value);
+};
+// 热点分类懒加载
+const lazyShow = ref(true);
+const loadNode = async (node: any, resolve: any) => {
+	try {
+		if (node.isLeaf) return resolve([]);
+		const res: any = await hotSpotType({ id: node.data.id ? node.data.id : null });
+		resolve(res.result);
+	} catch (error) {
+		resolve([]);
+	}
+};
+// 切换tab 查询列表
+const handleClick = () => {
+	state.queryParams.ModuleCode = '';
+	state.queryParams.NewDraftsStatus = -1;
+	queryList();
+};
+/** 搜索按钮操作 节流操作 */
+const handleQuery = () => {
+	state.queryParams.PageIndex = 1;
+	queryList();
+};
+// 获取所有组织结构 和基础数据
+const exportType = ref<EmptyArrayType>([]);
+const getOrgListApi = async () => {
+	state.loading = true;
+	try {
+		const res: any = await Promise.all([getOrgListByUser(), baseData()]);
+		state.orgData = res[0].result ?? []; //部门
+		state.statusOptions = res[1].result?.tabNames ?? []; // 列表状态
+		exportType.value = res[1].result?.fileType ?? []; // 导出文件类型
+		state.tabNewDraftsNames = res[1].result?.tabNewDraftsNames.map((item: any) => {
+			return {
+				label: item.value,
+				value: item.key,
+			};
+		});
+		state.tabAuditingNames = res[1].result?.tabAuditingNames.map((item: any) => {
+			return {
+				label: item.value,
+				value: item.key,
+			};
+		});
+		state.loading = false;
+	} catch (error) {
+		state.loading = false;
+	}
+};
+// 获取知识分类
+const getKnowledgeType = async () => {
+	state.typeLoading = true;
+	try {
+		const { result } = await treeList({ IsEnable: true });
+		state.knowledgeOptions = result ?? [];
+		state.typeLoading = false;
+	} catch (error) {
+		state.typeLoading = false;
+	}
+};
+/** 获取知识列表 */
+const requestParams = ref<EmptyObjectType>({});
+const queryList = () => {
+	state.tableLoading = true;
+	requestParams.value = Other.deepClone(state.queryParams);
+	KnowledgePaged(requestParams.value)
+		.then((response: any) => {
+			state.tableData = response?.result.items ?? [];
+			state.total = response?.result.total;
+			state.tableLoading = false;
+		})
+		.catch(() => {
+			state.tableLoading = false;
+		});
+};
+// 点击节点
+const handleNodeClick = (data: any) => {
+	if (userInfos.value.isCenter) {
+		switch (state.activeName) {
+			case '0':
+				state.queryParams.CreateOrgId = data.id;
+				break;
+			case '1':
+				state.queryParams.KnowledgeTypeId = data.id;
+				break;
+			case '2':
+				state.queryParams.HotspotId = data.id;
+				break;
+			default:
+				break;
+		}
+	} else {
+		state.queryParams.KnowledgeTypeId = data.id;
+	}
+	queryList();
+};
+/** 重置按钮操作 */
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	resetNode();
+};
+// 重置选中的节点
+const resetNode = () => {
+	state.queryParams.CreateOrgId = null;
+	state.queryParams.KnowledgeTypeId = null;
+	state.queryParams.HotspotId = null;
+	state.queryParams.ModuleCode = '';
+	state.queryParams.NewDraftsStatus = -1;
+	filterOrg.value = '';
+	filterType.value = '';
+	filterHot.value = '';
+	typeRef.value?.setCurrentKey(null);
+	orgRef.value?.setCurrentKey(null);
+	hotRef.value?.setCurrentKey(null);
+	orgRef.value?.filter();
+	orgRef.value?.setExpandedKeys([]);
+	typeRef.value?.filter();
+	typeRef.value?.setExpandedKeys([]);
+	hotRef.value?.filter();
+	handleQuery();
+};
+// 新增知识
+const onAddKnowledge = () => {
+	router.push({
+		name: 'knowledgeEdit',
+		params: {
+			tagsViewName: '新增知识',
+		},
+	});
+};
+// 修改知识
+const onEdit = (row: any) => {
+	router.push({
+		name: 'knowledgeEdit',
+		params: {
+			id: row.id,
+			tagsViewName: '编辑知识',
+		},
+	});
+};
+// 预览
+const onPreview = (row: any) => {
+	router.push({
+		name: 'knowledgePreview',
+		params: {
+			id: row.id,
+			tagsViewName: row.title,
+		},
+	});
+};
+// 审批
+const processAuditRef = ref<RefType>(); //审核记录ref
+const onAudit = (row: any) => {
+	const params = {
+		id: row.workflowId,
+		processType: '工单办理',
+		orderDetail: {},
+		extra: {
+			dialogTitle: '知识审批',
+			inputPlaceholder: '办理意见',
+			annexName: '知识附件',
+		},
+	};
+	processAuditRef.value.openDialog(params);
+};
+// 下架
+const offShelfFn = (row: any) => {
+	// 如果有流程id,说明是审批中的知识
+	const params = {
+		id: row.workflowId,
+		processType: '知识下架',
+		extra: {
+			dialogTitle: '知识下架',
+			inputPlaceholder: '下架原因',
+			annexName: '知识附件',
+		},
+		orderDetail: row,
+	};
+	processAuditRef.value.openDialog(params);
+	/*	ElMessageBox.confirm(`是否确定要下架【${row.title}】?知识下架后,将不会被检索到!`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			KnowledgeOffShelf(row.id).then(() => {
+				ElMessage.success('操作成功');
+				handleQuery();
+			});
+		})
+		.catch(() => {});*/
+};
+// 上架
+const groundingFn = (row: any) => {
+	ElMessageBox.confirm(`是否确定要上架【${row.title}】?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			KnowledgeOnTheShelf(row.id).then(() => {
+				ElMessage.success('操作成功');
+				handleQuery();
+			});
+		})
+		.catch(() => {});
+};
+// 删除知识
+const onRowDel = (row: any) => {
+	// 如果有流程id,说明是审批中的知识
+	const params = {
+		id: row.workflowId,
+		processType: '删除知识',
+		extra: {
+			dialogTitle: '删除知识',
+			inputPlaceholder: '删除原因',
+			annexName: '知识附件',
+		},
+		orderDetail: row,
+	};
+	processAuditRef.value.openDialog(params);
+	/*	if (row.workflowId) {
+		// 如果有流程id,说明是审批中的知识
+		const params = {
+			id: row.workflowId,
+			processType: '删除知识',
+			extra: {
+				dialogTitle: '删除知识',
+				inputPlaceholder: '删除原因',
+				annexName: '知识附件',
+			},
+			orderDetail: row,
+		};
+		processAuditRef.value.openDialog(params);
+	} else {
+		// 否则直接删除
+		ElMessageBox.confirm(`是否确定要删除【${row.title}】?`, '提示', {
+			confirmButtonText: '确认',
+			cancelButtonText: '取消',
+			type: 'warning',
+			draggable: true,
+			cancelButtonClass: 'default-button',
+		})
+			.then(() => {
+				KnowledgeDel({ data: row }).then(() => {
+					ElMessage.success('操作成功');
+					handleQuery();
+				});
+			})
+			.catch(() => {});
+	}*/
+};
+// 查看审核记录
+const auditProgressRef = ref<RefType>(); //审核记录ref
+const onprogress = (row: any) => {
+	auditProgressRef.value.openDialog(row.id);
+};
+// 导出详情
+const onExportDetail = (command: string | number | object) => {
+	state.loading = true;
+	const ids = checkTable.value.map((item: any) => item.id);
+	VxeUI.modal.message({
+		content: `导出中,请稍等`,
+		status: 'loading',
+		id: 'exportDetail',
+		duration: -1,
+	});
+	knowledgeDetailExport({ ids, fileType: command })
+		.then((res) => {
+			downloadFileByStream(res);
+			state.loading = false;
+			VxeUI.modal.close('exportDetail');
+			VxeUI.modal.message({
+				content: `导出成功`,
+				status: 'success',
+			});
+		})
+		.catch(() => {
+			state.loading = false;
+			VxeUI.modal.close('exportDetail');
+			VxeUI.modal.message({
+				content: `导出失败`,
+				status: 'error',
+			});
+		});
+};
+// 批量审核
+const toEndRef = ref<RefType>();
+const onAuditBatch = () => {
+	const ids = checkTable.value.map((item: any) => item.id);
+	toEndRef.value.openDialog(ids);
+};
+const tableRef = ref<RefType>();
+const checkTable = ref<EmptyArrayType>([]);
+const selectAllChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '所有勾选事件' : '所有取消事件', records);
+	}
+};
+
+const selectChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '勾选事件' : '取消事件', records);
+	}
+};
+const isChecked = computed(() => {
+	return !Boolean(checkTable.value.length);
+});
+const toolbarRef = ref<RefType>();
+onMounted(() => {
+	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
+	getKnowledgeType();
+	getOrgListApi();
+});
+</script>
+<style lang="scss" scoped>
+.knowledge-index-container {
+	.knowledge-index-container-box {
+		background-color: var(--el-color-white);
+		overflow: hidden;
+	}
+	.right-container {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+	}
+}
+</style>

+ 802 - 0
src/views/knowledge/index/ZGIndex.vue

@@ -0,0 +1,802 @@
+<template>
+	<div class="knowledge-index-container layout-padding">
+		<div class="layout-padding-auto layout-padding-view pd20">
+			<splitpanes class="h100" :horizontal="horizontal">
+				<pane min-size="16" max-size="25" size="16">
+					<template v-if="userInfos.isCenter">
+						<el-tabs v-model="state.activeName" stretch @tab-change="resetNode">
+							<el-tab-pane label="知识分类" name="1" :disabled="state.tableLoading">
+								<el-input v-model="filterType" placeholder="请填写知识分类名称" class="input-with-select mb10" clearable @input="onQueryChangedType">
+								</el-input>
+							</el-tab-pane>
+							<el-tab-pane label="部门" name="0" :disabled="state.tableLoading">
+								<el-input v-model="filterOrg" placeholder="请填写部门名称" class="input-with-select mb10" clearable @input="onQueryChanged">
+								</el-input>
+							</el-tab-pane>
+							<el-tab-pane label="热点" name="2" :disabled="state.tableLoading">
+								<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% - 100px);'" ref="scrollBarRef">
+							<el-skeleton :loading="state.loading" animated :rows="10" v-if="state.activeName === '0'">
+								<template #default>
+									<el-auto-resizer>
+										<template #default="{ height, width }">
+											<el-tree-v2
+												:data="state.orgData"
+												highlight-current
+												:expand-on-click-node="false"
+												:props="{ children: 'children', label: 'name' }"
+												@node-click="handleNodeClick"
+												ref="orgRef"
+												:filter-method="filterNode"
+												: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-skeleton :loading="state.typeLoading" animated :rows="10" v-if="state.activeName === '1'">
+								<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"
+												node-key="id"
+											>
+												<template #default="{ node }">
+													<text-tooltip :content="node.label+'('+node.data.knowledgeNum+')'" effect="dark" placement="top"></text-tooltip>
+												</template>
+											</el-tree-v2>
+										</template>
+									</el-auto-resizer>
+								</template>
+							</el-skeleton>
+							<el-skeleton :loading="state.loading" animated :rows="10" v-if="state.activeName === '2'">
+								<template #default>
+									<el-tree
+										node-key="id"
+										:load="loadNode"
+										lazy
+										v-if="lazyShow"
+										:props="{
+											label: 'hotSpotFullName',
+											children: 'children',
+											isLeaf: 'hasChild',
+										}"
+										:filter-node-method="filterNodeHot"
+										@node-click="handleNodeClick"
+										highlight-current
+										check-strictly
+										:expand-on-click-node="false"
+										ref="hotRef"
+									/>
+									<el-tree
+										ref="hotRef"
+										:data="state.hotSpotData"
+										node-key="id"
+										v-else
+										default-expand-all
+										highlight-current
+										:props="{
+											label: 'hotSpotFullName',
+											children: 'children',
+										}"
+										:filter-node-method="filterNodeHot"
+										@node-click="handleNodeClick"
+										:expand-on-click-node="false"
+										check-strictly
+									/>
+								</template>
+							</el-skeleton>
+						</el-scrollbar>
+					</template>
+					<template v-else>
+						<el-input v-model="filterType" placeholder="请填写知识分类名称" class="input-with-select mb10" clearable> </el-input>
+						<el-scrollbar ref="scrollBarRef" noresiz style="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="36"
+												empty-text="暂无知识分类"
+												:height="height"
+											>
+												<template #default="{ node }">
+													<text-tooltip :content="node.label+'('+node.data.knowledgeNum+')'" effect="dark" placement="top"></text-tooltip>
+												</template>
+											</el-tree-v2>
+										</template>
+									</el-auto-resizer>
+								</template>
+							</el-skeleton>
+						</el-scrollbar>
+					</template>
+				</pane>
+				<pane class="h100" style="display: flex; flex-direction: column; flex: 1">
+					<el-tabs v-model="state.queryParams.Status" @tab-change="handleClick" v-loading="state.loading">
+						<el-tab-pane :label="v.value" :name="v.key" v-for="(v, i) in state.statusOptions" :key="i" :disabled="state.tableLoading"></el-tab-pane>
+					</el-tabs>
+					<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+						<el-form-item label="审核类型" prop="ModuleCode" v-if="state.queryParams.Status === 1">
+							<el-segmented
+								:options="state.tabAuditingNames"
+								v-model="state.queryParams.ModuleCode"
+								@change="handleQuery"
+								:disabled="state.tableLoading"
+							/>
+						</el-form-item>
+						<el-form-item label="草稿类型" prop="NewDraftsStatus" v-if="state.queryParams.Status === 8">
+							<el-segmented
+								:options="state.tabNewDraftsNames"
+								v-model="state.queryParams.NewDraftsStatus"
+								@change="handleQuery"
+								:disabled="state.tableLoading"
+							/>
+						</el-form-item>
+						<el-form-item label="关键字" prop="Keyword">
+							<el-input
+								v-model="state.queryParams.Keyword"
+								placeholder="标题/创建人/创建部门/来源部门"
+								clearable
+								@keyup.enter="handleQuery"
+								class="keyword-input"
+							/>
+						</el-form-item>
+						<el-form-item label="是否公开" prop="IsPublic">
+							<el-select v-model="state.queryParams.IsPublic" placeholder="请选择是否公开" @change="handleQuery" clearable>
+								<el-option label="是" :value="true" />
+								<el-option label="否" :value="false" />
+							</el-select>
+						</el-form-item>
+						<el-form-item>
+							<el-button type="primary" @click="handleQuery" :loading="state.tableLoading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.tableLoading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+						</el-form-item>
+					</el-form>
+					<vxe-toolbar
+						ref="toolbarRef"
+						:loading="state.tableLoading"
+						custom
+						:refresh="{
+							queryMethod: handleQuery,
+						}"
+						:tools="[{ toolRender: { name: 'exportCurrent' } }, { toolRender: { name: 'exportAll' } }]"
+					>
+						<template #buttons>
+							<el-button type="primary" @click="onAddKnowledge" v-auth="'knowledge:index:add'" :loading="state.tableLoading">
+								<SvgIcon name="ele-Plus" class="mr5" />创建知识
+							</el-button>
+							<el-dropdown v-auth="'knowledge:index:export:detail'" @command="onExportDetail" class="ml12 mr12" :disabled="isChecked">
+								<el-button type="primary" :disabled="isChecked" :loading="state.tableLoading">
+									导出知识详情<SvgIcon name="ele-ArrowDown" class="ml3" />
+								</el-button>
+								<template #dropdown>
+									<el-dropdown-menu>
+										<el-dropdown-item :command="item.key" v-for="item in exportType" :key="item.key">{{ item.value }}</el-dropdown-item>
+									</el-dropdown-menu>
+								</template>
+							</el-dropdown>
+							<el-button
+								type="primary"
+								@click="onAuditBatch"
+								v-if="state.queryParams.Status === 1"
+								v-auth="'knowledge:index:audit:batch'"
+								:loading="state.loading"
+								:disabled="isChecked"
+							>
+								<SvgIcon name="ele-Edit" class="mr5" />批量审核
+							</el-button>
+						</template>
+					</vxe-toolbar>
+					<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+						<vxe-table
+							border
+							:loading="state.tableLoading"
+							:data="state.tableData"
+							:column-config="{ resizable: true }"
+							:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+							ref="tableRef"
+							height="auto"
+							auto-resize
+							show-overflow
+							:print-config="{}"
+							:scrollY="{ enabled: true, gt: 0 }"
+							id="knowledgeManage"
+							:custom-config="{ storage: true }"
+							showHeaderOverflow
+							:params="{ exportMethod: knowledgeExport, exportParams: requestParams }"
+							@checkbox-all="selectAllChangeEvent"
+							@checkbox-change="selectChangeEvent"
+						>
+							<vxe-column type="checkbox" width="50" align="center"></vxe-column>
+							<vxe-column field="workflow.moduleName" title="审核类型" width="120" v-if="state.queryParams.Status === 1"></vxe-column>
+							<vxe-column field="title" title="标题" min-width="200">
+								<template #default="{ row }">
+									<el-button link type="primary" @click="onPreview(row)">{{ row.title }}</el-button>
+								</template>
+							</vxe-column>
+							<vxe-column field="knowledgeTypeText" title="知识分类" width="150"></vxe-column>
+							<vxe-column field="statusName" title="知识状态" width="110"></vxe-column>
+							<vxe-column field="attribution" title="知识归属" width="140"></vxe-column>
+							<vxe-column field="sourceOrganize.name" title="来源部门" width="140"></vxe-column>
+							<vxe-column field="hotspotName" title="热点" width="150"></vxe-column>
+							<vxe-column field="isPublic" title="是否公开" width="100">
+								<template #default="{ row }">
+									{{ row.isPublic ? '是' : '否' }}
+								</template>
+							</vxe-column>
+							<vxe-column field="pageView" title="阅读次数" width="100"></vxe-column>
+							<vxe-column field="onShelfTime" title="上架时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.onShelfTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column field="offShelfTime" title="下架时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.offShelfTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column field="creatorName" title="创建人" width="120"></vxe-column>
+							<vxe-column field="creatorOrgName" title="创建部门" width="150"></vxe-column>
+							<vxe-column field="creationTime" title="创建时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column field="lastModificationTime" title="更新时间" width="160">
+								<template #default="{ row }">
+									{{ formatDate(row.lastModificationTime, 'YYYY-mm-dd HH:MM:SS') }}
+								</template>
+							</vxe-column>
+							<vxe-column title="操作" fixed="right" width="250" align="center">
+								<template #default="{ row }">
+									<el-button
+										link
+										type="primary"
+										@click="onEdit(row)"
+										title="编辑"
+										v-if="[0, 4, 5, 6].includes(row.newStatus) && row.status !== 1"
+										v-auth="'knowledge:index:edit'"
+									>
+										编辑
+									</el-button>
+									<el-button
+										link
+										type="danger"
+										@click="onRowDel(row)"
+										title="删除"
+										v-if="[0, 2, 4, 5, 6].includes(row.newStatus) && row.status !== 1 && ['YiBin'].includes(themeConfig.appScope)"
+										v-auth="'knowledge:index:delete'"
+									>
+										删除
+									</el-button>
+									<el-button
+										link
+										type="primary"
+										@click="offShelfFn(row)"
+										title="下架"
+										v-if="[3].includes(row.newStatus)"
+										v-auth="'knowledge:index:undercarriage'"
+									>
+										下架
+									</el-button>
+									<el-button
+										link
+										type="primary"
+										@click="groundingFn(row)"
+										title="上架"
+										v-if="[4].includes(row.newStatus)"
+										v-auth="'knowledge:index:grounding'"
+									>
+										上架
+									</el-button>
+									<el-button link type="primary" @click="onprogress(row)" title="查看审核记录" v-if="[5].includes(row.newStatus)">
+										审核记录
+									</el-button>
+									<!--									<el-button
+										link
+										type="primary"
+										@click="onAudit(row)"
+										title="审批"
+										v-if="[1, 2].includes(row.status) && row.isCanHandle"
+										v-auth="'business:order:handle'"
+									>
+										审批
+									</el-button>-->
+									<el-button link type="primary" @click="onPreview(row)" title="查看"> 查看 </el-button>
+								</template>
+							</vxe-column>
+						</vxe-table>
+					</div>
+					<pagination
+						@pagination="queryList"
+						:total="state.total"
+						v-model:current-page="state.queryParams.PageIndex"
+						v-model:page-size="state.queryParams.PageSize"
+						:disabled="state.tableLoading"
+					/>
+				</pane>
+			</splitpanes>
+		</div>
+		<!-- 流程审批 -->
+		<process-audit ref="processAuditRef" @orderProcessSuccess="queryList" />
+		<!-- 审核记录 -->
+		<audit-progress ref="auditProgressRef" />
+		<!-- 批量审批 -->
+		<to-end ref="toEndRef" @updateList="queryList" />
+	</div>
+</template>
+
+<script lang="tsx" setup name="knowledgeManage">
+import { ref, reactive, onMounted, watch, defineAsyncComponent, computed } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { formatDate } from '@/utils/formatTime';
+import {
+	KnowledgePaged,
+	KnowledgeOffShelf,
+	KnowledgeOnTheShelf,
+	baseData,
+	KnowledgeDel,
+	knowledgeExport,
+	knowledgeDetailExport,
+} from '@/api/knowledge';
+import { getOrgListByUser } from '@/api/system/organize';
+import { treeList } from '@/api/knowledge/type';
+import { hotSpotSearch, hotSpotType } from '@/api/business/order';
+import { Splitpanes, Pane } from 'splitpanes';
+import 'splitpanes/dist/splitpanes.css';
+import { useUserInfo } from '@/stores/userInfo';
+import { storeToRefs } from 'pinia';
+import Other from '@/utils/other';
+import { downloadFileByStream } from '@/utils/tools';
+import { useThemeConfig } from '@/stores/themeConfig';
+import { VxeUI } from 'vxe-pc-ui';
+
+// 引入组件
+const ProcessAudit = defineAsyncComponent(() => import('@/components/ProcessAudit/index.vue')); // 流程审批
+const AuditProgress = defineAsyncComponent(() => import('@/views/knowledge/components/Audit-progress.vue')); // 编写规范
+const TextTooltip = defineAsyncComponent(() => import('@/components/TextTooltip/index.vue'));
+const ToEnd = defineAsyncComponent(() => import('@/views/knowledge/index/components/To-end.vue')); // 批量审批
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+
+// 定义变量内容
+const state = reactive<any>({
+	queryParams: {
+		PageIndex: 1, //页码
+		PageSize: 20, //每页条数
+		Keyword: null, //关键字
+		Status: 3, //状态 默认已上架
+		OrgId: null, //组织机构
+		HotSpotTypeId: null, //热点分类
+		KnowledgeTypeId: null, //知识类型
+		Title: null, //标题
+		Summary: null, //摘要
+		ModuleCode: '',
+		NewDraftsStatus: -1,
+	},
+	activeName: '1', //tab切换 默认知识分类
+	tableData: [], //表格数据
+	total: 0, //总条数
+	loading: false, //表格loading
+	tableLoading: false, //表格loading
+	orgData: [], //组织机构数据
+	knowledgeOptions: [], //知识库类型数据
+	statusOptions: [], //状态数据
+	hotSpotData: [], //热点数据
+	typeLoading: false, // 知识类型loading
+});
+const router = useRouter(); //路由
+const ruleFormRef = ref<FormInstance>(); //表单ref
+const horizontal = ref(false);
+const storesUserInfo = useUserInfo();
+const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
+const storesThemeConfig = useThemeConfig();
+const { themeConfig } = storeToRefs(storesThemeConfig);
+// 部门查询
+const filterOrg = ref('');
+const orgRef = ref<RefType>();
+const onQueryChanged = (query: string) => {
+	if (query) {
+		orgRef.value!.filter(query);
+	} else {
+		orgRef.value!.filter(query);
+		orgRef.value?.setExpandedKeys([]);
+	}
+};
+const filterNode = (value: string, data: any) => {
+	if (!value) return true;
+	return data.name.includes(value);
+};
+// 知识分类查询
+const filterType = ref('');
+const typeRef = ref<RefType>();
+const onQueryChangedType = (query: string) => {
+	if (query) {
+		typeRef.value!.filter(query);
+	} else {
+		typeRef.value!.filter(query);
+		typeRef.value?.setExpandedKeys([]);
+	}
+};
+const filterNodeType = (value: string, data: any) => {
+	if (!value) return true;
+	return data.name.includes(value);
+};
+// 热点查询
+const filterHot = ref('');
+const hotRef = ref<RefType>();
+watch(filterHot, (val) => {
+	if (val) {
+		lazyShow.value = false; //当填写框有值时关闭懒加载
+		hotSpotSearch(val)
+			.then((res) => {
+				//获取后端搜索的数据
+				state.hotSpotData.length = 0;
+				state.hotSpotData = res.result ?? [];
+				hotRef.value!.filter(val);
+			})
+			.catch((e) => {
+				console.log(e);
+			});
+	} else if (val == '' || val == ' ' || val == null) {
+		lazyShow.value = true; // 懒加载树显示
+	}
+});
+const filterNodeHot = (value: string, data: any) => {
+	if (!value) return true;
+	return data.hotSpotName.includes(value);
+};
+// 热点分类懒加载
+const lazyShow = ref(true);
+const loadNode = async (node: any, resolve: any) => {
+	try {
+		if (node.isLeaf) return resolve([]);
+		const res: any = await hotSpotType({ id: node.data.id ? node.data.id : null });
+		resolve(res.result);
+	} catch (error) {
+		resolve([]);
+	}
+};
+// 切换tab 查询列表
+const handleClick = () => {
+	state.queryParams.ModuleCode = '';
+	state.queryParams.NewDraftsStatus = -1;
+	queryList();
+};
+/** 搜索按钮操作 节流操作 */
+const handleQuery = () => {
+	state.queryParams.PageIndex = 1;
+	queryList();
+};
+// 获取所有组织结构 和基础数据
+const exportType = ref<EmptyArrayType>([]);
+const getOrgListApi = async () => {
+	state.loading = true;
+	try {
+		const res: any = await Promise.all([getOrgListByUser(), baseData()]);
+		state.orgData = res[0].result ?? []; //部门
+		state.statusOptions = res[1].result?.tabNames ?? []; // 列表状态
+		exportType.value = res[1].result?.fileType ?? []; // 导出文件类型
+		state.tabNewDraftsNames = res[1].result?.tabNewDraftsNames.map((item: any) => {
+			return {
+				label: item.value,
+				value: item.key,
+			};
+		});
+		state.tabAuditingNames = res[1].result?.tabAuditingNames.map((item: any) => {
+			return {
+				label: item.value,
+				value: item.key,
+			};
+		});
+		state.loading = false;
+	} catch (error) {
+		state.loading = false;
+	}
+};
+// 获取知识分类
+const getKnowledgeType = async () => {
+	state.typeLoading = true;
+	try {
+		const { result } = await treeList({ IsEnable: true });
+		state.knowledgeOptions = result ?? [];
+		state.typeLoading = false;
+	} catch (error) {
+		state.typeLoading = false;
+	}
+};
+/** 获取知识列表 */
+const requestParams = ref<EmptyObjectType>({});
+const queryList = () => {
+	state.tableLoading = true;
+	requestParams.value = Other.deepClone(state.queryParams);
+	KnowledgePaged(requestParams.value)
+		.then((response: any) => {
+			state.tableData = response?.result.items ?? [];
+			state.total = response?.result.total;
+			state.tableLoading = false;
+		})
+		.catch(() => {
+			state.tableLoading = false;
+		});
+};
+// 点击节点
+const handleNodeClick = (data: any) => {
+	if (userInfos.value.isCenter) {
+		switch (state.activeName) {
+			case '0':
+				state.queryParams.CreateOrgId = data.id;
+				break;
+			case '1':
+				state.queryParams.KnowledgeTypeId = data.id;
+				break;
+			case '2':
+				state.queryParams.HotspotId = data.id;
+				break;
+			default:
+				break;
+		}
+	} else {
+		state.queryParams.KnowledgeTypeId = data.id;
+	}
+	queryList();
+};
+/** 重置按钮操作 */
+const resetQuery = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+	resetNode();
+};
+// 重置选中的节点
+const resetNode = () => {
+	state.queryParams.CreateOrgId = null;
+	state.queryParams.KnowledgeTypeId = null;
+	state.queryParams.HotspotId = null;
+	state.queryParams.ModuleCode = '';
+	state.queryParams.NewDraftsStatus = -1;
+	filterOrg.value = '';
+	filterType.value = '';
+	filterHot.value = '';
+	typeRef.value?.setCurrentKey(null);
+	orgRef.value?.setCurrentKey(null);
+	hotRef.value?.setCurrentKey(null);
+	orgRef.value?.filter();
+	orgRef.value?.setExpandedKeys([]);
+	typeRef.value?.filter();
+	typeRef.value?.setExpandedKeys([]);
+	hotRef.value?.filter();
+	handleQuery();
+};
+// 新增知识
+const onAddKnowledge = () => {
+	router.push({
+		name: 'knowledgeEdit',
+		params: {
+			tagsViewName: '新增知识',
+		},
+	});
+};
+// 修改知识
+const onEdit = (row: any) => {
+	router.push({
+		name: 'knowledgeEdit',
+		params: {
+			id: row.id,
+			tagsViewName: '编辑知识',
+		},
+	});
+};
+// 预览
+const onPreview = (row: any) => {
+	router.push({
+		name: 'knowledgePreview',
+		params: {
+			id: row.id,
+			tagsViewName: row.title,
+		},
+	});
+};
+// 审批
+const processAuditRef = ref<RefType>(); //审核记录ref
+const onAudit = (row: any) => {
+	const params = {
+		id: row.workflowId,
+		processType: '工单办理',
+		orderDetail: {},
+		extra: {
+			dialogTitle: '知识审批',
+			inputPlaceholder: '办理意见',
+			annexName: '知识附件',
+		},
+	};
+	processAuditRef.value.openDialog(params);
+};
+// 下架
+const offShelfFn = (row: any) => {
+	// 如果有流程id,说明是审批中的知识
+	const params = {
+		id: row.workflowId,
+		processType: '知识下架',
+		extra: {
+			dialogTitle: '知识下架',
+			inputPlaceholder: '下架原因',
+			annexName: '知识附件',
+		},
+		orderDetail: row,
+	};
+	processAuditRef.value.openDialog(params);
+	/*	ElMessageBox.confirm(`是否确定要下架【${row.title}】?知识下架后,将不会被检索到!`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			KnowledgeOffShelf(row.id).then(() => {
+				ElMessage.success('操作成功');
+				handleQuery();
+			});
+		})
+		.catch(() => {});*/
+};
+// 上架
+const groundingFn = (row: any) => {
+	ElMessageBox.confirm(`是否确定要上架【${row.title}】?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			KnowledgeOnTheShelf(row.id).then(() => {
+				ElMessage.success('操作成功');
+				handleQuery();
+			});
+		})
+		.catch(() => {});
+};
+// 删除知识
+const onRowDel = (row: any) => {
+	// 如果有流程id,说明是审批中的知识
+	const params = {
+		id: row.workflowId,
+		processType: '删除知识',
+		extra: {
+			dialogTitle: '删除知识',
+			inputPlaceholder: '删除原因',
+			annexName: '知识附件',
+		},
+		orderDetail: row,
+	};
+	processAuditRef.value.openDialog(params);
+	/*	if (row.workflowId) {
+		// 如果有流程id,说明是审批中的知识
+		const params = {
+			id: row.workflowId,
+			processType: '删除知识',
+			extra: {
+				dialogTitle: '删除知识',
+				inputPlaceholder: '删除原因',
+				annexName: '知识附件',
+			},
+			orderDetail: row,
+		};
+		processAuditRef.value.openDialog(params);
+	} else {
+		// 否则直接删除
+		ElMessageBox.confirm(`是否确定要删除【${row.title}】?`, '提示', {
+			confirmButtonText: '确认',
+			cancelButtonText: '取消',
+			type: 'warning',
+			draggable: true,
+			cancelButtonClass: 'default-button',
+		})
+			.then(() => {
+				KnowledgeDel({ data: row }).then(() => {
+					ElMessage.success('操作成功');
+					handleQuery();
+				});
+			})
+			.catch(() => {});
+	}*/
+};
+// 查看审核记录
+const auditProgressRef = ref<RefType>(); //审核记录ref
+const onprogress = (row: any) => {
+	auditProgressRef.value.openDialog(row.id);
+};
+// 导出详情
+const onExportDetail = (command: string | number | object) => {
+	state.loading = true;
+	const ids = checkTable.value.map((item: any) => item.id);
+	VxeUI.modal.message({
+		content: `导出中,请稍等`,
+		status: 'loading',
+		id: 'exportDetail',
+		duration: -1,
+	});
+	knowledgeDetailExport({ ids, fileType: command })
+		.then((res) => {
+			downloadFileByStream(res);
+			state.loading = false;
+			VxeUI.modal.close('exportDetail');
+			VxeUI.modal.message({
+				content: `导出成功`,
+				status: 'success',
+			});
+		})
+		.catch(() => {
+			state.loading = false;
+			VxeUI.modal.close('exportDetail');
+			VxeUI.modal.message({
+				content: `导出失败`,
+				status: 'error',
+			});
+		});
+};
+// 批量审核
+const toEndRef = ref<RefType>();
+const onAuditBatch = () => {
+	const ids = checkTable.value.map((item: any) => item.id);
+	toEndRef.value.openDialog(ids);
+};
+const tableRef = ref<RefType>();
+const checkTable = ref<EmptyArrayType>([]);
+const selectAllChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '所有勾选事件' : '所有取消事件', records);
+	}
+};
+
+const selectChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '勾选事件' : '取消事件', records);
+	}
+};
+const isChecked = computed(() => {
+	return !Boolean(checkTable.value.length);
+});
+const toolbarRef = ref<RefType>();
+onMounted(() => {
+	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
+	getKnowledgeType();
+	getOrgListApi();
+});
+</script>

+ 19 - 0
src/views/knowledge/index/edit.vue

@@ -305,6 +305,21 @@
 							</template>
 						</el-skeleton>
 					</el-col>
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" v-if="['YiBin'].includes(themeConfig.appScope)">
+						<el-skeleton :loading="state.loading" animated>
+							<template #template>
+								<el-form-item label="知识来源">
+									<el-skeleton-item variant="h1" />
+								</el-form-item>
+							</template>
+							<template #default>
+								<el-form-item label="知识来源" prop="source" :rules="[{ required: false, message: '请填写知识来源', trigger: 'change' }]">
+									<el-input v-model="state.ruleForm.source" placeholder="请填写知识来源" clearable>
+									</el-input>
+								</el-form-item>
+							</template>
+						</el-skeleton>
+					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 						<el-skeleton :loading="state.loading" animated>
 							<template #template>
@@ -361,6 +376,7 @@ import { KnowledgeAdd, knowledgeContent, KnowledgeInfo, knowledgeKeyword, Knowle
 import { templateList } from '@/views/knowledge/index/template';
 import { disabledDate } from '@/utils/constants';
 import { removeDuplicate } from '@/utils/arrayOperation';
+import { useThemeConfig } from '@/stores/themeConfig';
 // 引入组件
 const Editor = defineAsyncComponent(() => import('@/components/Editor/index.vue')); // 富文本编辑器
 const ProcessAudit = defineAsyncComponent(() => import('@/components/ProcessAudit/index.vue')); // 流程审批
@@ -386,12 +402,15 @@ const state = reactive<any>({
 		content: '', // 知识内容
 		sourceOrganizeId: null, // 知识来源部门
 		title: null, // 知识标题
+		source:null, // 知识来源
 	},
 	typeData: [], // 知识分类
 	loading: false,
 	hotspotExternal: [],
 	knowledgeOptions: [], //关联知识
 });
+const storesThemeConfig = useThemeConfig();
+const { themeConfig } = storeToRefs(storesThemeConfig);
 const ruleFormRef = ref<any>(); // 表单ref
 // 选择热点分类
 const chooseHotSpot = (val: any, node: any, externalArr: any) => {

+ 14 - 789
src/views/knowledge/index/index.vue

@@ -1,802 +1,27 @@
 <template>
-	<div class="knowledge-index-container layout-padding">
-		<div class="layout-padding-auto layout-padding-view pd20">
-			<splitpanes class="h100" :horizontal="horizontal">
-				<pane min-size="16" max-size="25" size="16">
-					<template v-if="userInfos.isCenter">
-						<el-tabs v-model="state.activeName" stretch @tab-change="resetNode">
-							<el-tab-pane label="知识分类" name="1" :disabled="state.tableLoading">
-								<el-input v-model="filterType" placeholder="请填写知识分类名称" class="input-with-select mb10" clearable @input="onQueryChangedType">
-								</el-input>
-							</el-tab-pane>
-							<el-tab-pane label="部门" name="0" :disabled="state.tableLoading">
-								<el-input v-model="filterOrg" placeholder="请填写部门名称" class="input-with-select mb10" clearable @input="onQueryChanged">
-								</el-input>
-							</el-tab-pane>
-							<el-tab-pane label="热点" name="2" :disabled="state.tableLoading">
-								<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% - 100px);'" ref="scrollBarRef">
-							<el-skeleton :loading="state.loading" animated :rows="10" v-if="state.activeName === '0'">
-								<template #default>
-									<el-auto-resizer>
-										<template #default="{ height, width }">
-											<el-tree-v2
-												:data="state.orgData"
-												highlight-current
-												:expand-on-click-node="false"
-												:props="{ children: 'children', label: 'name' }"
-												@node-click="handleNodeClick"
-												ref="orgRef"
-												:filter-method="filterNode"
-												: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-skeleton :loading="state.typeLoading" animated :rows="10" v-if="state.activeName === '1'">
-								<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"
-												node-key="id"
-											>
-												<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-skeleton :loading="state.loading" animated :rows="10" v-if="state.activeName === '2'">
-								<template #default>
-									<el-tree
-										node-key="id"
-										:load="loadNode"
-										lazy
-										v-if="lazyShow"
-										:props="{
-											label: 'hotSpotFullName',
-											children: 'children',
-											isLeaf: 'hasChild',
-										}"
-										:filter-node-method="filterNodeHot"
-										@node-click="handleNodeClick"
-										highlight-current
-										check-strictly
-										:expand-on-click-node="false"
-										ref="hotRef"
-									/>
-									<el-tree
-										ref="hotRef"
-										:data="state.hotSpotData"
-										node-key="id"
-										v-else
-										default-expand-all
-										highlight-current
-										:props="{
-											label: 'hotSpotFullName',
-											children: 'children',
-										}"
-										:filter-node-method="filterNodeHot"
-										@node-click="handleNodeClick"
-										:expand-on-click-node="false"
-										check-strictly
-									/>
-								</template>
-							</el-skeleton>
-						</el-scrollbar>
-					</template>
-					<template v-else>
-						<el-input v-model="filterType" placeholder="请填写知识分类名称" class="input-with-select mb10" clearable> </el-input>
-						<el-scrollbar ref="scrollBarRef" noresiz style="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="36"
-												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>
-					</template>
-				</pane>
-				<pane class="h100" style="display: flex; flex-direction: column; flex: 1">
-					<el-tabs v-model="state.queryParams.Status" @tab-change="handleClick" v-loading="state.loading">
-						<el-tab-pane :label="v.value" :name="v.key" v-for="(v, i) in state.statusOptions" :key="i" :disabled="state.tableLoading"></el-tab-pane>
-					</el-tabs>
-					<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
-						<el-form-item label="审核类型" prop="ModuleCode" v-if="state.queryParams.Status === 1">
-							<el-segmented
-								:options="state.tabAuditingNames"
-								v-model="state.queryParams.ModuleCode"
-								@change="handleQuery"
-								:disabled="state.tableLoading"
-							/>
-						</el-form-item>
-						<el-form-item label="草稿类型" prop="NewDraftsStatus" v-if="state.queryParams.Status === 8">
-							<el-segmented
-								:options="state.tabNewDraftsNames"
-								v-model="state.queryParams.NewDraftsStatus"
-								@change="handleQuery"
-								:disabled="state.tableLoading"
-							/>
-						</el-form-item>
-						<el-form-item label="关键字" prop="Keyword">
-							<el-input
-								v-model="state.queryParams.Keyword"
-								placeholder="标题/创建人/创建部门/来源部门"
-								clearable
-								@keyup.enter="handleQuery"
-								class="keyword-input"
-							/>
-						</el-form-item>
-						<el-form-item label="是否公开" prop="IsPublic">
-							<el-select v-model="state.queryParams.IsPublic" placeholder="请选择是否公开" @change="handleQuery" clearable>
-								<el-option label="是" :value="true" />
-								<el-option label="否" :value="false" />
-							</el-select>
-						</el-form-item>
-						<el-form-item>
-							<el-button type="primary" @click="handleQuery" :loading="state.tableLoading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
-							<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.tableLoading">
-								<SvgIcon name="ele-Refresh" class="mr5" />重置
-							</el-button>
-						</el-form-item>
-					</el-form>
-					<vxe-toolbar
-						ref="toolbarRef"
-						:loading="state.tableLoading"
-						custom
-						:refresh="{
-							queryMethod: handleQuery,
-						}"
-						:tools="[{ toolRender: { name: 'exportCurrent' } }, { toolRender: { name: 'exportAll' } }]"
-					>
-						<template #buttons>
-							<el-button type="primary" @click="onAddKnowledge" v-auth="'knowledge:index:add'" :loading="state.tableLoading">
-								<SvgIcon name="ele-Plus" class="mr5" />创建知识
-							</el-button>
-							<el-dropdown v-auth="'knowledge:index:export:detail'" @command="onExportDetail" class="ml12 mr12" :disabled="isChecked">
-								<el-button type="primary" :disabled="isChecked" :loading="state.tableLoading">
-									导出知识详情<SvgIcon name="ele-ArrowDown" class="ml3" />
-								</el-button>
-								<template #dropdown>
-									<el-dropdown-menu>
-										<el-dropdown-item :command="item.key" v-for="item in exportType" :key="item.key">{{ item.value }}</el-dropdown-item>
-									</el-dropdown-menu>
-								</template>
-							</el-dropdown>
-							<el-button
-								type="primary"
-								@click="onAuditBatch"
-								v-if="state.queryParams.Status === 1"
-								v-auth="'knowledge:index:audit:batch'"
-								:loading="state.loading"
-								:disabled="isChecked"
-							>
-								<SvgIcon name="ele-Edit" class="mr5" />批量审核
-							</el-button>
-						</template>
-					</vxe-toolbar>
-					<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
-						<vxe-table
-							border
-							:loading="state.tableLoading"
-							:data="state.tableData"
-							:column-config="{ resizable: true }"
-							:row-config="{ isCurrent: true, isHover: true, height: 30 }"
-							ref="tableRef"
-							height="auto"
-							auto-resize
-							show-overflow
-							:print-config="{}"
-							:scrollY="{ enabled: true, gt: 0 }"
-							id="knowledgeManage"
-							:custom-config="{ storage: true }"
-							showHeaderOverflow
-							:params="{ exportMethod: knowledgeExport, exportParams: requestParams }"
-							@checkbox-all="selectAllChangeEvent"
-							@checkbox-change="selectChangeEvent"
-						>
-							<vxe-column type="checkbox" width="50" align="center"></vxe-column>
-							<vxe-column field="workflow.moduleName" title="审核类型" width="120" v-if="state.queryParams.Status === 1"></vxe-column>
-							<vxe-column field="title" title="标题" min-width="200">
-								<template #default="{ row }">
-									<el-button link type="primary" @click="onPreview(row)">{{ row.title }}</el-button>
-								</template>
-							</vxe-column>
-							<vxe-column field="knowledgeTypeText" title="知识分类" width="150"></vxe-column>
-							<vxe-column field="statusName" title="知识状态" width="110"></vxe-column>
-							<vxe-column field="attribution" title="知识归属" width="140"></vxe-column>
-							<vxe-column field="sourceOrganize.name" title="来源部门" width="140"></vxe-column>
-							<vxe-column field="hotspotName" title="热点" width="150"></vxe-column>
-							<vxe-column field="isPublic" title="是否公开" width="100">
-								<template #default="{ row }">
-									{{ row.isPublic ? '是' : '否' }}
-								</template>
-							</vxe-column>
-							<vxe-column field="pageView" title="阅读次数" width="100"></vxe-column>
-							<vxe-column field="onShelfTime" title="上架时间" width="160">
-								<template #default="{ row }">
-									{{ formatDate(row.onShelfTime, 'YYYY-mm-dd HH:MM:SS') }}
-								</template>
-							</vxe-column>
-							<vxe-column field="offShelfTime" title="下架时间" width="160">
-								<template #default="{ row }">
-									{{ formatDate(row.offShelfTime, 'YYYY-mm-dd HH:MM:SS') }}
-								</template>
-							</vxe-column>
-							<vxe-column field="creatorName" title="创建人" width="120"></vxe-column>
-							<vxe-column field="creatorOrgName" title="创建部门" width="150"></vxe-column>
-							<vxe-column field="creationTime" title="创建时间" width="160">
-								<template #default="{ row }">
-									{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
-								</template>
-							</vxe-column>
-							<vxe-column field="lastModificationTime" title="更新时间" width="160">
-								<template #default="{ row }">
-									{{ formatDate(row.lastModificationTime, 'YYYY-mm-dd HH:MM:SS') }}
-								</template>
-							</vxe-column>
-							<vxe-column title="操作" fixed="right" width="250" align="center">
-								<template #default="{ row }">
-									<el-button
-										link
-										type="primary"
-										@click="onEdit(row)"
-										title="编辑"
-										v-if="[0, 4, 5, 6].includes(row.newStatus) && row.status !== 1"
-										v-auth="'knowledge:index:edit'"
-									>
-										编辑
-									</el-button>
-									<el-button
-										link
-										type="danger"
-										@click="onRowDel(row)"
-										title="删除"
-										v-if="[0, 2, 4, 5, 6].includes(row.newStatus) && row.status !== 1 && ['YiBin'].includes(themeConfig.appScope)"
-										v-auth="'knowledge:index:delete'"
-									>
-										删除
-									</el-button>
-									<el-button
-										link
-										type="primary"
-										@click="offShelfFn(row)"
-										title="下架"
-										v-if="[3].includes(row.newStatus)"
-										v-auth="'knowledge:index:undercarriage'"
-									>
-										下架
-									</el-button>
-									<el-button
-										link
-										type="primary"
-										@click="groundingFn(row)"
-										title="上架"
-										v-if="[4].includes(row.newStatus)"
-										v-auth="'knowledge:index:grounding'"
-									>
-										上架
-									</el-button>
-									<el-button link type="primary" @click="onprogress(row)" title="查看审核记录" v-if="[5].includes(row.newStatus)">
-										审核记录
-									</el-button>
-									<!--									<el-button
-										link
-										type="primary"
-										@click="onAudit(row)"
-										title="审批"
-										v-if="[1, 2].includes(row.status) && row.isCanHandle"
-										v-auth="'business:order:handle'"
-									>
-										审批
-									</el-button>-->
-									<el-button link type="primary" @click="onPreview(row)" title="查看"> 查看 </el-button>
-								</template>
-							</vxe-column>
-						</vxe-table>
-					</div>
-					<pagination
-						@pagination="queryList"
-						:total="state.total"
-						v-model:current-page="state.queryParams.PageIndex"
-						v-model:page-size="state.queryParams.PageSize"
-						:disabled="state.tableLoading"
-					/>
-				</pane>
-			</splitpanes>
-		</div>
-		<!-- 流程审批 -->
-		<process-audit ref="processAuditRef" @orderProcessSuccess="queryList" />
-		<!-- 审核记录 -->
-		<audit-progress ref="auditProgressRef" />
-		<!-- 批量审批 -->
-		<to-end ref="toEndRef" @updateList="queryList" />
-	</div>
+	<component :is="currentCity" />
 </template>
 
 <script lang="tsx" setup name="knowledgeManage">
-import { ref, reactive, onMounted, watch, defineAsyncComponent, computed } from 'vue';
-import { ElMessageBox, ElMessage } from 'element-plus';
-import { useRouter } from 'vue-router';
-import type { FormInstance } from 'element-plus';
-import { formatDate } from '@/utils/formatTime';
-import {
-	KnowledgePaged,
-	KnowledgeOffShelf,
-	KnowledgeOnTheShelf,
-	baseData,
-	KnowledgeDel,
-	knowledgeExport,
-	knowledgeDetailExport,
-} from '@/api/knowledge';
-import { getOrgListByUser } from '@/api/system/organize';
-import { treeList } from '@/api/knowledge/type';
-import { hotSpotSearch, hotSpotType } from '@/api/business/order';
-import { Splitpanes, Pane } from 'splitpanes';
-import 'splitpanes/dist/splitpanes.css';
-import { useUserInfo } from '@/stores/userInfo';
-import { storeToRefs } from 'pinia';
-import Other from '@/utils/other';
-import { downloadFileByStream } from '@/utils/tools';
+import { defineAsyncComponent, computed } from 'vue';
 import { useThemeConfig } from '@/stores/themeConfig';
-import { VxeUI } from 'vxe-pc-ui';
+import { storeToRefs } from 'pinia';
 
 // 引入组件
-const ProcessAudit = defineAsyncComponent(() => import('@/components/ProcessAudit/index.vue')); // 流程审批
-const AuditProgress = defineAsyncComponent(() => import('@/views/knowledge/components/Audit-progress.vue')); // 编写规范
-const TextTooltip = defineAsyncComponent(() => import('@/components/TextTooltip/index.vue'));
-const ToEnd = defineAsyncComponent(() => import('@/views/knowledge/index/components/To-end.vue')); // 批量审批
-const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+const YiBin = defineAsyncComponent(() => import('@/views/knowledge/index/YBIndex.vue')); // 宜宾知识库管理
+const ZiGong = defineAsyncComponent(() => import('@/views/knowledge/index/ZGIndex.vue')); // 自贡知识库管理
+const LuZhou = defineAsyncComponent(() => import('@/views/knowledge/index/ZGIndex.vue')); // 泸州知识库管理
 
-// 定义变量内容
-const state = reactive<any>({
-	queryParams: {
-		PageIndex: 1, //页码
-		PageSize: 20, //每页条数
-		Keyword: null, //关键字
-		Status: 3, //状态 默认已上架
-		OrgId: null, //组织机构
-		HotSpotTypeId: null, //热点分类
-		KnowledgeTypeId: null, //知识类型
-		Title: null, //标题
-		Summary: null, //摘要
-		ModuleCode: '',
-		NewDraftsStatus: -1,
-	},
-	activeName: '1', //tab切换 默认知识分类
-	tableData: [], //表格数据
-	total: 0, //总条数
-	loading: false, //表格loading
-	tableLoading: false, //表格loading
-	orgData: [], //组织机构数据
-	knowledgeOptions: [], //知识库类型数据
-	statusOptions: [], //状态数据
-	hotSpotData: [], //热点数据
-	typeLoading: false, // 知识类型loading
-});
-const router = useRouter(); //路由
-const ruleFormRef = ref<FormInstance>(); //表单ref
-const horizontal = ref(false);
-const storesUserInfo = useUserInfo();
-const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
 const storesThemeConfig = useThemeConfig();
 const { themeConfig } = storeToRefs(storesThemeConfig);
-// 部门查询
-const filterOrg = ref('');
-const orgRef = ref<RefType>();
-const onQueryChanged = (query: string) => {
-	if (query) {
-		orgRef.value!.filter(query);
-	} else {
-		orgRef.value!.filter(query);
-		orgRef.value?.setExpandedKeys([]);
-	}
-};
-const filterNode = (value: string, data: any) => {
-	if (!value) return true;
-	return data.name.includes(value);
-};
-// 知识分类查询
-const filterType = ref('');
-const typeRef = ref<RefType>();
-const onQueryChangedType = (query: string) => {
-	if (query) {
-		typeRef.value!.filter(query);
-	} else {
-		typeRef.value!.filter(query);
-		typeRef.value?.setExpandedKeys([]);
-	}
-};
-const filterNodeType = (value: string, data: any) => {
-	if (!value) return true;
-	return data.name.includes(value);
-};
-// 热点查询
-const filterHot = ref('');
-const hotRef = ref<RefType>();
-watch(filterHot, (val) => {
-	if (val) {
-		lazyShow.value = false; //当填写框有值时关闭懒加载
-		hotSpotSearch(val)
-			.then((res) => {
-				//获取后端搜索的数据
-				state.hotSpotData.length = 0;
-				state.hotSpotData = res.result ?? [];
-				hotRef.value!.filter(val);
-			})
-			.catch((e) => {
-				console.log(e);
-			});
-	} else if (val == '' || val == ' ' || val == null) {
-		lazyShow.value = true; // 懒加载树显示
-	}
-});
-const filterNodeHot = (value: string, data: any) => {
-	if (!value) return true;
-	return data.hotSpotName.includes(value);
-};
-// 热点分类懒加载
-const lazyShow = ref(true);
-const loadNode = async (node: any, resolve: any) => {
-	try {
-		if (node.isLeaf) return resolve([]);
-		const res: any = await hotSpotType({ id: node.data.id ? node.data.id : null });
-		resolve(res.result);
-	} catch (error) {
-		resolve([]);
-	}
-};
-// 切换tab 查询列表
-const handleClick = () => {
-	state.queryParams.ModuleCode = '';
-	state.queryParams.NewDraftsStatus = -1;
-	queryList();
-};
-/** 搜索按钮操作 节流操作 */
-const handleQuery = () => {
-	state.queryParams.PageIndex = 1;
-	queryList();
-};
-// 获取所有组织结构 和基础数据
-const exportType = ref<EmptyArrayType>([]);
-const getOrgListApi = async () => {
-	state.loading = true;
-	try {
-		const res: any = await Promise.all([getOrgListByUser(), baseData()]);
-		state.orgData = res[0].result ?? []; //部门
-		state.statusOptions = res[1].result?.tabNames ?? []; // 列表状态
-		exportType.value = res[1].result?.fileType ?? []; // 导出文件类型
-		state.tabNewDraftsNames = res[1].result?.tabNewDraftsNames.map((item: any) => {
-			return {
-				label: item.value,
-				value: item.key,
-			};
-		});
-		state.tabAuditingNames = res[1].result?.tabAuditingNames.map((item: any) => {
-			return {
-				label: item.value,
-				value: item.key,
-			};
-		});
-		state.loading = false;
-	} catch (error) {
-		state.loading = false;
-	}
-};
-// 获取知识分类
-const getKnowledgeType = async () => {
-	state.typeLoading = true;
-	try {
-		const { result } = await treeList({ IsEnable: true });
-		state.knowledgeOptions = result ?? [];
-		state.typeLoading = false;
-	} catch (error) {
-		state.typeLoading = false;
-	}
-};
-/** 获取知识列表 */
-const requestParams = ref<EmptyObjectType>({});
-const queryList = () => {
-	state.tableLoading = true;
-	requestParams.value = Other.deepClone(state.queryParams);
-	KnowledgePaged(requestParams.value)
-		.then((response: any) => {
-			state.tableData = response?.result.items ?? [];
-			state.total = response?.result.total;
-			state.tableLoading = false;
-		})
-		.catch(() => {
-			state.tableLoading = false;
-		});
-};
-// 点击节点
-const handleNodeClick = (data: any) => {
-	if (userInfos.value.isCenter) {
-		switch (state.activeName) {
-			case '0':
-				state.queryParams.CreateOrgId = data.id;
-				break;
-			case '1':
-				state.queryParams.KnowledgeTypeId = data.id;
-				break;
-			case '2':
-				state.queryParams.HotspotId = data.id;
-				break;
-			default:
-				break;
-		}
-	} else {
-		state.queryParams.KnowledgeTypeId = data.id;
-	}
-	queryList();
-};
-/** 重置按钮操作 */
-const resetQuery = (formEl: FormInstance | undefined) => {
-	if (!formEl) return;
-	formEl.resetFields();
-	resetNode();
-};
-// 重置选中的节点
-const resetNode = () => {
-	state.queryParams.CreateOrgId = null;
-	state.queryParams.KnowledgeTypeId = null;
-	state.queryParams.HotspotId = null;
-	state.queryParams.ModuleCode = '';
-	state.queryParams.NewDraftsStatus = -1;
-	filterOrg.value = '';
-	filterType.value = '';
-	filterHot.value = '';
-	typeRef.value?.setCurrentKey(null);
-	orgRef.value?.setCurrentKey(null);
-	hotRef.value?.setCurrentKey(null);
-	orgRef.value?.filter();
-	orgRef.value?.setExpandedKeys([]);
-	typeRef.value?.filter();
-	typeRef.value?.setExpandedKeys([]);
-	hotRef.value?.filter();
-	handleQuery();
-};
-// 新增知识
-const onAddKnowledge = () => {
-	router.push({
-		name: 'knowledgeEdit',
-		params: {
-			tagsViewName: '新增知识',
-		},
-	});
-};
-// 修改知识
-const onEdit = (row: any) => {
-	router.push({
-		name: 'knowledgeEdit',
-		params: {
-			id: row.id,
-			tagsViewName: '编辑知识',
-		},
-	});
-};
-// 预览
-const onPreview = (row: any) => {
-	router.push({
-		name: 'knowledgePreview',
-		params: {
-			id: row.id,
-			tagsViewName: row.title,
-		},
-	});
-};
-// 审批
-const processAuditRef = ref<RefType>(); //审核记录ref
-const onAudit = (row: any) => {
-	const params = {
-		id: row.workflowId,
-		processType: '工单办理',
-		orderDetail: {},
-		extra: {
-			dialogTitle: '知识审批',
-			inputPlaceholder: '办理意见',
-			annexName: '知识附件',
-		},
-	};
-	processAuditRef.value.openDialog(params);
-};
-// 下架
-const offShelfFn = (row: any) => {
-	// 如果有流程id,说明是审批中的知识
-	const params = {
-		id: row.workflowId,
-		processType: '知识下架',
-		extra: {
-			dialogTitle: '知识下架',
-			inputPlaceholder: '下架原因',
-			annexName: '知识附件',
-		},
-		orderDetail: row,
-	};
-	processAuditRef.value.openDialog(params);
-	/*	ElMessageBox.confirm(`是否确定要下架【${row.title}】?知识下架后,将不会被检索到!`, '提示', {
-		confirmButtonText: '确认',
-		cancelButtonText: '取消',
-		type: 'warning',
-		draggable: true,
-		cancelButtonClass: 'default-button',
-	})
-		.then(() => {
-			KnowledgeOffShelf(row.id).then(() => {
-				ElMessage.success('操作成功');
-				handleQuery();
-			});
-		})
-		.catch(() => {});*/
-};
-// 上架
-const groundingFn = (row: any) => {
-	ElMessageBox.confirm(`是否确定要上架【${row.title}】?`, '提示', {
-		confirmButtonText: '确认',
-		cancelButtonText: '取消',
-		type: 'warning',
-		draggable: true,
-		cancelButtonClass: 'default-button',
-	})
-		.then(() => {
-			KnowledgeOnTheShelf(row.id).then(() => {
-				ElMessage.success('操作成功');
-				handleQuery();
-			});
-		})
-		.catch(() => {});
-};
-// 删除知识
-const onRowDel = (row: any) => {
-	// 如果有流程id,说明是审批中的知识
-	const params = {
-		id: row.workflowId,
-		processType: '删除知识',
-		extra: {
-			dialogTitle: '删除知识',
-			inputPlaceholder: '删除原因',
-			annexName: '知识附件',
-		},
-		orderDetail: row,
-	};
-	processAuditRef.value.openDialog(params);
-	/*	if (row.workflowId) {
-		// 如果有流程id,说明是审批中的知识
-		const params = {
-			id: row.workflowId,
-			processType: '删除知识',
-			extra: {
-				dialogTitle: '删除知识',
-				inputPlaceholder: '删除原因',
-				annexName: '知识附件',
-			},
-			orderDetail: row,
-		};
-		processAuditRef.value.openDialog(params);
-	} else {
-		// 否则直接删除
-		ElMessageBox.confirm(`是否确定要删除【${row.title}】?`, '提示', {
-			confirmButtonText: '确认',
-			cancelButtonText: '取消',
-			type: 'warning',
-			draggable: true,
-			cancelButtonClass: 'default-button',
-		})
-			.then(() => {
-				KnowledgeDel({ data: row }).then(() => {
-					ElMessage.success('操作成功');
-					handleQuery();
-				});
-			})
-			.catch(() => {});
-	}*/
-};
-// 查看审核记录
-const auditProgressRef = ref<RefType>(); //审核记录ref
-const onprogress = (row: any) => {
-	auditProgressRef.value.openDialog(row.id);
-};
-// 导出详情
-const onExportDetail = (command: string | number | object) => {
-	state.loading = true;
-	const ids = checkTable.value.map((item: any) => item.id);
-	VxeUI.modal.message({
-		content: `导出中,请稍等`,
-		status: 'loading',
-		id: 'exportDetail',
-		duration: -1,
-	});
-	knowledgeDetailExport({ ids, fileType: command })
-		.then((res) => {
-			downloadFileByStream(res);
-			state.loading = false;
-			VxeUI.modal.close('exportDetail');
-			VxeUI.modal.message({
-				content: `导出成功`,
-				status: 'success',
-			});
-		})
-		.catch(() => {
-			state.loading = false;
-			VxeUI.modal.close('exportDetail');
-			VxeUI.modal.message({
-				content: `导出失败`,
-				status: 'error',
-			});
-		});
-};
-// 批量审核
-const toEndRef = ref<RefType>();
-const onAuditBatch = () => {
-	const ids = checkTable.value.map((item: any) => item.id);
-	toEndRef.value.openDialog(ids);
-};
-const tableRef = ref<RefType>();
-const checkTable = ref<EmptyArrayType>([]);
-const selectAllChangeEvent = ({ checked }) => {
-	if (tableRef.value) {
-		const records = tableRef.value.getCheckboxRecords();
-		checkTable.value = records;
-		console.log(checked ? '所有勾选事件' : '所有取消事件', records);
-	}
-};
 
-const selectChangeEvent = ({ checked }) => {
-	if (tableRef.value) {
-		const records = tableRef.value.getCheckboxRecords();
-		checkTable.value = records;
-		console.log(checked ? '勾选事件' : '取消事件', records);
-	}
-};
-const isChecked = computed(() => {
-	return !Boolean(checkTable.value.length);
-});
-const toolbarRef = ref<RefType>();
-onMounted(() => {
-	queryList();
-	if (tableRef.value && toolbarRef.value) {
-		tableRef.value.connect(toolbarRef.value);
-	}
-	getKnowledgeType();
-	getOrgListApi();
+const COMPONENT_LIST = {
+	YiBin,
+	ZiGong,
+	LuZhou,
+};
+// 当前地州市
+const currentCity = computed(() => {
+	return COMPONENT_LIST[themeConfig.value.appScope];
 });
 </script>

+ 1 - 0
src/views/knowledge/index/preview.vue

@@ -10,6 +10,7 @@
 					<span class="mr10">创建人:{{ state.info.creatorName }}</span>
 					<span class="mr10">创建部门:{{ state.info.creatorOrgName }}</span>
 					<span class="mr10" v-if="state.info.knowledgeTypeText">知识分类:{{ state.info.knowledgeTypeText }}</span>
+					<span class="mr10" v-if="state.info.source">知识来源:{{ state.info.source }}</span>
 					<span class="mr10">是否公开:{{ state.info.isPublic ? '是' : '否' }}</span>
 					<template v-if="haveId">
 						<span class="mr10">已阅:{{ state.info.pageView }}</span>

+ 2 - 2
src/views/knowledge/retrieval/YBRetrieval.vue

@@ -42,7 +42,7 @@
 													:height="height"
 												>
 													<template #default="{ node }">
-														<text-tooltip :content="node.label" effect="dark" placement="top"></text-tooltip>
+														<text-tooltip :content="node.label+'('+node.data.knowledgeNum+')'" effect="dark" placement="top"></text-tooltip>
 													</template>
 												</el-tree-v2>
 											</template>
@@ -138,7 +138,7 @@
 												:height="height"
 											>
 												<template #default="{ node }">
-													<text-tooltip :content="node.label" effect="dark" placement="top"></text-tooltip>
+													<text-tooltip :content="node.label+'('+node.data.knowledgeNum+')'" effect="dark" placement="top"></text-tooltip>
 												</template>
 											</el-tree-v2>
 										</template>

+ 2 - 2
src/views/knowledge/retrieval/ZGRetrieval.vue

@@ -64,7 +64,7 @@
 												:height="height"
 											>
 												<template #default="{ node }">
-													<text-tooltip :content="node.label" effect="dark" placement="top"></text-tooltip>
+													<text-tooltip :content="node.label+'('+node.data.knowledgeNum+')'" effect="dark" placement="top"></text-tooltip>
 												</template>
 											</el-tree-v2>
 										</template>
@@ -130,7 +130,7 @@
 												:height="height"
 											>
 												<template #default="{ node }">
-													<text-tooltip :content="node.label" effect="dark" placement="top"></text-tooltip>
+													<text-tooltip :content="node.label+'('+node.data.knowledgeNum+')'" effect="dark" placement="top"></text-tooltip>
 												</template>
 											</el-tree-v2>
 										</template>