edit.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. <template>
  2. <div class="knowledge-edit-container layout-pd">
  3. <el-card shadow="never" style="padding: 0 50px">
  4. <el-form :model="state.ruleForm" ref="ruleFormRef" label-width="120px" scroll-to-error>
  5. <el-row :gutter="35">
  6. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  7. <el-form-item label="温馨提示">
  8. <span class="color-danger">
  9. 发布知识前请仔细阅读 <el-link type="primary" @click="showStandard">【知识编写规范】</el-link>,以免知识无法通过审核,浪费您的时间!
  10. </span>
  11. </el-form-item>
  12. </el-col>
  13. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
  14. <el-skeleton :loading="state.loading" animated>
  15. <template #template>
  16. <el-form-item label="知识归属">
  17. <el-skeleton-item variant="h1" />
  18. </el-form-item>
  19. </template>
  20. <template #default>
  21. <el-form-item label="知识归属" prop="attribution" :rules="[{ required: true, message: '请选择知识归属', trigger: 'change' }]">
  22. <!-- 是否是中心 -->
  23. <el-select v-model="state.ruleForm.attribution" placeholder="请选择知识归属" class="w100" :disabled="userInfos.isCenter">
  24. <el-option label="中心知识库" value="中心知识库" />
  25. <el-option label="部门知识库" value="部门知识库" />
  26. </el-select>
  27. </el-form-item>
  28. </template>
  29. </el-skeleton>
  30. </el-col>
  31. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
  32. <el-skeleton :loading="state.loading" animated>
  33. <template #template>
  34. <el-form-item label="知识分类">
  35. <el-skeleton-item variant="h1" />
  36. </el-form-item>
  37. </template>
  38. <template #default>
  39. <el-form-item label="知识分类" prop="knowledgeTypeId" :rules="[{ required: true, message: '请选择知识分类', trigger: 'change' }]">
  40. <!-- <el-cascader-->
  41. <!-- :options="state.typeData"-->
  42. <!-- filterable-->
  43. <!-- :props="{ value: 'id', label: 'name', emitPath: false, children: 'children', multiple: true }"-->
  44. <!-- placeholder="请选择知识分类"-->
  45. <!-- clearable-->
  46. <!-- class="w100"-->
  47. <!-- v-model="state.ruleForm.knowledgeTypeId"-->
  48. <!-- ref="cascadeRef"-->
  49. <!-- @change="getKnowledgeList"-->
  50. <!-- collapse-tags-->
  51. <!-- collapse-tags-tooltip-->
  52. <!-- :max-collapse-tags="2"-->
  53. <!-- >-->
  54. <!-- </el-cascader>-->
  55. <el-tree-select
  56. v-model="state.ruleForm.knowledgeTypeId"
  57. :data="state.typeData"
  58. multiple
  59. :render-after-expand="false"
  60. show-checkbox
  61. ref="cascadeRef"
  62. node-key="id"
  63. @change="getKnowledgeList"
  64. :props="{ label: 'name' }"
  65. class="w100"
  66. check-strictly
  67. check-on-click-node
  68. collapse-tags
  69. collapse-tags-tooltip
  70. :max-collapse-tags="2"
  71. filterable
  72. placeholder="请选择知识分类"
  73. >
  74. </el-tree-select>
  75. </el-form-item>
  76. </template>
  77. </el-skeleton>
  78. </el-col>
  79. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
  80. <el-skeleton :loading="state.loading" animated>
  81. <template #template>
  82. <el-form-item>
  83. <template #label>
  84. <div style="height: 34px; display: flex; align-items: center">
  85. 失效时间
  86. <el-tooltip placement="top-start">
  87. <SvgIcon name="ele-QuestionFilled" size="18px" class="ml3" />
  88. <template #content> 不设置则代表永久有效;到达预设失效时间,知识将自动下架 </template>
  89. </el-tooltip>
  90. </div>
  91. </template>
  92. <el-skeleton-item variant="h1" />
  93. </el-form-item>
  94. </template>
  95. <template #default>
  96. <el-form-item label="失效时间" prop="expiredTime" :rules="[{ required: false, message: '请选择失效时间', trigger: 'change' }]">
  97. <template #label>
  98. <div style="height: 34px; display: flex; align-items: center">
  99. 失效时间
  100. <el-tooltip placement="top-start">
  101. <SvgIcon name="ele-QuestionFilled" size="18px" class="ml3" />
  102. <template #content> 不设置则代表永久有效;到达预设失效时间,知识将自动下架 </template>
  103. </el-tooltip>
  104. </div>
  105. </template>
  106. <el-date-picker
  107. v-model="state.ruleForm.expiredTime"
  108. type="datetime"
  109. placeholder="请选择失效时间"
  110. class="w100"
  111. value-format="YYYY-MM-DD[T]HH:mm:ss"
  112. :disabled-date="disabledDate"
  113. popper-class="no-atTheMoment"
  114. />
  115. </el-form-item>
  116. </template>
  117. </el-skeleton>
  118. </el-col>
  119. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
  120. <el-skeleton :loading="state.loading" animated>
  121. <template #template>
  122. <el-form-item label="是否公开">
  123. <el-skeleton-item variant="h1" />
  124. </el-form-item>
  125. </template>
  126. <template #default>
  127. <el-form-item label="是否公开" prop="isPublic" :rules="[{ required: false, message: '请选择是否公开', trigger: 'change' }]">
  128. <el-radio-group v-model="state.ruleForm.isPublic">
  129. <el-radio :label="true">是</el-radio>
  130. <el-radio :label="false">否</el-radio>
  131. </el-radio-group>
  132. <span class="color-danger ml10" v-if="state.ruleForm.isPublic">(公开后将在12345官网进行展示)</span>
  133. </el-form-item>
  134. </template>
  135. </el-skeleton>
  136. </el-col>
  137. <!-- <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
  138. <el-skeleton :loading="state.loading" animated>
  139. <template #template>
  140. <el-form-item label="来源部门" prop="sourceOrganizeId" :rules="[{ required: true, message: '请选择来源部门', trigger: 'change' }]">
  141. <el-skeleton-item variant="h1" />
  142. </el-form-item>
  143. </template>
  144. <template #default>
  145. <el-form-item label="来源部门" prop="sourceOrganizeId" :rules="[{ required: true, message: '请选择来源部门', trigger: 'change' }]">
  146. <el-cascader
  147. :options="orgsOptions"
  148. filterable
  149. :props="{ value: 'id', label: 'name', emitPath: false, checkStrictly: true }"
  150. placeholder="请选择来源部门"
  151. class="w100"
  152. v-model="state.ruleForm.sourceOrganizeId"
  153. ref="orgRef"
  154. >
  155. </el-cascader>
  156. </el-form-item>
  157. </template>
  158. </el-skeleton>
  159. </el-col>-->
  160. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
  161. <el-skeleton :loading="state.loading" animated>
  162. <template #template>
  163. <el-form-item label="热点分类">
  164. <el-skeleton-item variant="h1" />
  165. </el-form-item>
  166. </template>
  167. <template #default>
  168. <el-form-item label="热点分类" prop="hotspotId" :rules="[{ required: true, message: '请选择热点分类', trigger: 'change' }]">
  169. <hot-spot-select v-model="state.ruleForm.hotspotId" class="w100" :externalArr="state.hotspotExternal" @choose="chooseHotSpot" />
  170. </el-form-item>
  171. </template>
  172. </el-skeleton>
  173. </el-col>
  174. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  175. <el-skeleton :loading="state.loading" animated>
  176. <template #template>
  177. <el-form-item label="知识标题">
  178. <el-skeleton-item variant="h1" />
  179. </el-form-item>
  180. </template>
  181. <template #default>
  182. <el-form-item label="知识标题" prop="title" :rules="[{ required: true, validator: validatePassTitle, trigger: 'blur' }]">
  183. <el-input v-model="state.ruleForm.title" placeholder="请填写知识标题" clearable @blur="isRepeat('title')"></el-input>
  184. </el-form-item>
  185. </template>
  186. </el-skeleton>
  187. </el-col>
  188. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  189. <el-skeleton :loading="state.loading" animated>
  190. <template #template>
  191. <el-form-item label="知识摘要">
  192. <el-skeleton-item variant="h1" />
  193. </el-form-item>
  194. </template>
  195. <template #default>
  196. <el-form-item label="知识摘要" prop="summary" :rules="[{ required: false, validator: validatePassSummary, trigger: 'blur' }]">
  197. <el-input v-model="state.ruleForm.summary" placeholder="请填写知识摘要" clearable @blur="isRepeat('summary')"></el-input>
  198. </el-form-item>
  199. </template>
  200. </el-skeleton>
  201. </el-col>
  202. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  203. <el-skeleton :loading="state.loading" animated>
  204. <template #template>
  205. <el-form-item label="知识摘要">
  206. <template #label>
  207. <div style="height: 34px; display: flex; align-items: center">
  208. 关联知识
  209. <el-tooltip placement="top-start">
  210. <SvgIcon name="ele-QuestionFilled" size="18px" class="ml3" />
  211. <template #content> 关联其它相似或业务相关的知识,方便话务员可以查询其他相似的知识 </template>
  212. </el-tooltip>
  213. </div>
  214. </template>
  215. <el-skeleton-item variant="h1" />
  216. </el-form-item>
  217. </template>
  218. <template #default>
  219. <el-form-item label="关联知识" prop="knowledges" :rules="[{ required: false, message: '请选择关联知识', trigger: 'change' }]">
  220. <template #label>
  221. <div style="height: 34px; display: flex; align-items: center">
  222. 关联知识
  223. <el-tooltip placement="top-start">
  224. <SvgIcon name="ele-QuestionFilled" size="18px" class="ml3" />
  225. <template #content> 关联其它相似或业务相关的知识,方便话务员可以查询其他相似的知识 </template>
  226. </el-tooltip>
  227. </div>
  228. </template>
  229. <el-select-v2
  230. v-model="state.ruleForm.knowledges"
  231. filterable
  232. clearable
  233. :options="state.knowledgeOptions"
  234. placeholder="请选择关联知识"
  235. class="w100"
  236. multiple
  237. collapse-tags
  238. collapse-tags-tooltip
  239. :max-collapse-tags="5"
  240. :props="{
  241. label: 'title',
  242. value: 'id',
  243. }"
  244. />
  245. </el-form-item>
  246. </template>
  247. </el-skeleton>
  248. </el-col>
  249. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  250. <el-skeleton :loading="state.loading" animated>
  251. <template #template>
  252. <el-form-item label="关键词">
  253. <el-skeleton-item variant="h1" />
  254. </el-form-item>
  255. </template>
  256. <template #default>
  257. <el-form-item label="关键词" prop="keywordsName" :rules="[{ required: false, message: '请添加关键词', trigger: 'change' }]">
  258. <el-input v-model="state.ruleForm.keywordsName" readonly placeholder="请添加关键词" max-length="200" clearable>
  259. <template #append>
  260. <el-button @click="addKeywords">添加</el-button>
  261. </template>
  262. </el-input>
  263. </el-form-item>
  264. </template>
  265. </el-skeleton>
  266. </el-col>
  267. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  268. <el-skeleton :loading="state.loading" animated>
  269. <template #template>
  270. <el-form-item label="知识库模板">
  271. <el-skeleton-item variant="h1" />
  272. </el-form-item>
  273. </template>
  274. <template #default>
  275. <el-form-item label="知识库模板" prop="template" :rules="[{ required: false, message: '请选择知识库模板', trigger: 'change' }]">
  276. <el-select v-model="state.ruleForm.template" placeholder="请选择知识库模板" class="w100" @change="selectTemplate" clearable>
  277. <el-option :label="item.label" :value="item.value" v-for="item in templateList" :key="item.id" />
  278. </el-select>
  279. </el-form-item>
  280. </template>
  281. </el-skeleton>
  282. </el-col>
  283. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  284. <el-skeleton :loading="state.loading" animated>
  285. <template #template>
  286. <el-form-item label="知识内容">
  287. <el-skeleton-item variant="h1" />
  288. </el-form-item>
  289. </template>
  290. <template #default>
  291. <el-form-item label="知识内容" prop="content" :rules="[{ required: true, validator: validatePassContent, trigger: 'blur' }]">
  292. <editor
  293. v-model:get-html="state.ruleForm.content"
  294. :disable="state.disable"
  295. placeholder="请填写知识内容"
  296. @blur="isRepeat('content')"
  297. />
  298. </el-form-item>
  299. </template>
  300. </el-skeleton>
  301. </el-col>
  302. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  303. <el-skeleton :loading="state.loading" animated>
  304. <template #template>
  305. <el-form-item label="附件">
  306. <el-skeleton-item variant="h1" />
  307. </el-form-item>
  308. </template>
  309. <template #default>
  310. <el-form-item label="附件" prop="files" :rules="[{ required: false, message: '请选择附件', trigger: 'change' }]">
  311. <annex-list
  312. name="知识附件"
  313. v-model="state.ruleForm.files"
  314. v-model:format="filesFormat"
  315. :businessId="state.ruleForm.id"
  316. classify="知识附件"
  317. />
  318. </el-form-item>
  319. </template>
  320. </el-skeleton>
  321. </el-col>
  322. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  323. <el-form-item>
  324. <el-button type="primary" @click="onSubmitReview(ruleFormRef)" :loading="state.loading">提交审核</el-button>
  325. <el-button class="default-button" @click="onPreview" :loading="state.loading">预览 </el-button>
  326. <el-button @click="onSaveOnly(ruleFormRef)" class="default-button" :loading="state.loading">保存为草稿</el-button>
  327. <el-button class="default-button" @click="onCancel" :loading="state.loading">取消 </el-button>
  328. </el-form-item>
  329. </el-col>
  330. </el-row>
  331. </el-form>
  332. </el-card>
  333. <!-- 编写规范 -->
  334. <knowledge-standard ref="KnowledgeStandardRef" />
  335. <!-- 流程审批 -->
  336. <process-audit ref="processAuditRef" @orderProcessSuccess="knowledgeProcessSuccess" />
  337. <!-- 关键词 -->
  338. <knowledge-keywords ref="knowledgeKeywordsRef" @selectKeyword="selectKeyword" />
  339. </div>
  340. </template>
  341. <script setup lang="ts" name="knowledgeEdit">
  342. import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
  343. import type { FormInstance } from 'element-plus';
  344. import { ElMessage } from 'element-plus';
  345. import mittBus from '@/utils/mitt';
  346. import { useRoute, useRouter } from 'vue-router';
  347. import { storeToRefs } from 'pinia';
  348. import { useUserInfo } from '@/stores/userInfo';
  349. import { Local } from '@/utils/storage';
  350. import other from '@/utils/other';
  351. import { throttle, transformFile } from '@/utils/tools';
  352. import { treeList } from '@/api/knowledge/type';
  353. import { KnowledgeAdd, knowledgeContent, KnowledgeGetKnowledge, KnowledgeInfo, KnowledgeUpdate } from '@/api/knowledge';
  354. import { getCanUseOrg } from '@/api/system/user';
  355. import { templateList } from '@/views/knowledge/index/template';
  356. import { disabledDate } from '@/utils/constants';
  357. // 引入组件
  358. const Editor = defineAsyncComponent(() => import('@/components/Editor/index.vue')); // 富文本编辑器
  359. const ProcessAudit = defineAsyncComponent(() => import('@/components/ProcessAudit/index.vue')); // 流程审批
  360. const KnowledgeStandard = defineAsyncComponent(() => import('@/views/knowledge/component/Knowledge-standard-info.vue')); // 编写规范
  361. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件组件
  362. const KnowledgeKeywords = defineAsyncComponent(() => import('@/views/knowledge/component/Knowledge-keywords.vue')); // 关键词组件
  363. const HotSpotSelect = defineAsyncComponent(() => import('@/components/Hotspot/index.vue')); // 选择热点
  364. const stores = useUserInfo(); // 用户信息
  365. const { userInfos } = storeToRefs(stores); // 用户信息
  366. // 定义变量内容
  367. const state = reactive<any>({
  368. dialogVisible: false,
  369. ruleForm: {
  370. attribution: userInfos.value.isCenter ? '中心知识库' : '', // 知识归属
  371. isPublic: true, // 是否公开
  372. keywords: [], // 关键字
  373. keywordsName: '', // 关键字名称
  374. knowledgeTypeId: [], // 知识分类
  375. hotspotId: '', // 热点分类
  376. knowledges: [], // 关联知识
  377. files: [], // 附件
  378. template: '', // 知识库模板
  379. content: '', // 知识内容
  380. sourceOrganizeId: '', // 知识来源部门
  381. title: '', // 知识标题
  382. },
  383. typeData: [], // 知识分类
  384. loading: false,
  385. hotspotExternal: [],
  386. knowledgeOptions: [], //关联知识
  387. });
  388. const ruleFormRef = ref<any>(); // 表单ref
  389. // 选择热点分类
  390. const chooseHotSpot = (val: any) => {
  391. state.ruleForm.hotspotSpliceName = val.hotSpotFullName; // 热点分类拼接名称
  392. state.ruleForm.hotspotName = val.hotSpotName; // 热点分类名称
  393. state.ruleForm.hotspotCode = val.provinceCode; // 热点分类code
  394. state.ruleForm.hotspotExternal = val?.externalArr?.join(',') ?? ''; // 热点分类默认展开项
  395. };
  396. const validatePassTitle = (rule: any, value: any, callback: any) => {
  397. if (value === '' || value === null) {
  398. callback(new Error('请填写知识标题'));
  399. } else if (Repeat.value) {
  400. callback(new Error('有相似标题,请检查!'));
  401. } else {
  402. callback();
  403. }
  404. };
  405. const validatePassSummary = (rule: any, value: any, callback: any) => {
  406. if (Repeat.value) {
  407. callback(new Error('有相似摘要,请检查!'));
  408. } else {
  409. callback();
  410. }
  411. };
  412. const validatePassContent = (rule: any, value: any, callback: any) => {
  413. if (value === '' || value === null) {
  414. callback(new Error('请填写知识内容'));
  415. } else if (Repeat.value) {
  416. callback(new Error('有相似内容,请检查!'));
  417. } else {
  418. callback();
  419. }
  420. };
  421. // 校验标题/摘要/内容是否重复
  422. const Repeat = ref<boolean>(false);
  423. const isRepeat = (type: string) => {
  424. if (state.ruleForm[type]) {
  425. knowledgeContent({ [type]: state.ruleForm[type], id: state.ruleForm.id })
  426. .then((res: any) => {
  427. Repeat.value = res.result;
  428. ruleFormRef.value.validateField(type);
  429. })
  430. .catch(() => {
  431. state.ruleForm[type] = '';
  432. });
  433. }
  434. };
  435. // 展示编写规范
  436. const KnowledgeStandardRef = ref<RefType>();
  437. const showStandard = () => {
  438. KnowledgeStandardRef.value.openDialog();
  439. };
  440. const cascadeRef = ref<RefType>();
  441. // 获取选择name值
  442. const getKnowledgeList = () => {
  443. const currentNode = cascadeRef.value.getCheckedNodes();
  444. state.ruleForm.knowledgeType = currentNode.map((item: any) => {
  445. return { KnowledgeTypeName: item.name, KnowledgeTypeId: item.id, KnowledgeTypeSpliceName : item.spliceName };
  446. });
  447. };
  448. // 添加关键词
  449. const knowledgeKeywordsRef = ref<RefType>();
  450. const addKeywords = () => {
  451. knowledgeKeywordsRef.value.openDialog(state.ruleForm.keywords);
  452. };
  453. // 选择关键词
  454. const selectKeyword = (val: any) => {
  455. state.ruleForm.keywordsName = val.name;
  456. state.ruleForm.keywords = val.ids;
  457. };
  458. // 选择知识库模板
  459. const selectTemplate = (val: any) => {
  460. state.ruleForm.content = state.ruleForm.content + val;
  461. };
  462. // 提交审核
  463. const processAuditRef = ref<RefType>(); // 流程组件
  464. const route = useRoute(); // 获取路由
  465. const router = useRouter(); // 路由跳转
  466. const filesFormat = ref<EmptyArrayType>([]); // 附件列表格式化
  467. const onSubmitReview = async (formEl: FormInstance | undefined) => {
  468. if (!formEl) return;
  469. await formEl.validate((valid: boolean) => {
  470. if (!valid) return;
  471. state.loading = true;
  472. state.ruleForm.files = filesFormat.value;
  473. const submitObj = other.deepClone(state.ruleForm);
  474. Reflect.deleteProperty(submitObj, 'creationTime');
  475. //如果已经有ID 说明是已经提交过的数据 提交更新流程
  476. if (route.params.id) {
  477. if (submitObj.status !== 0) {
  478. //不是草稿
  479. const params = {
  480. id: submitObj.workflowId ?? '',
  481. processType: '更新知识',
  482. extra: {
  483. dialogTitle: '更新知识',
  484. inputPlaceholder: '办理意见',
  485. annexName: '知识附件',
  486. },
  487. orderDetail: submitObj,
  488. };
  489. processAuditRef.value.openDialog(params);
  490. state.loading = false;
  491. } else {
  492. // 草稿 (特殊逻辑)
  493. const params = {
  494. id: submitObj.workflowId ?? '',
  495. processType: '更新新增知识',
  496. extra: {
  497. dialogTitle: '更新知识',
  498. inputPlaceholder: '办理意见',
  499. annexName: '知识附件',
  500. },
  501. orderDetail: submitObj,
  502. };
  503. processAuditRef.value.openDialog(params);
  504. state.loading = false;
  505. }
  506. } else {
  507. // 新增
  508. const params = {
  509. id: '',
  510. processType: '新增知识',
  511. extra: {
  512. dialogTitle: '新增知识',
  513. inputPlaceholder: '办理意见',
  514. annexName: '知识附件',
  515. },
  516. orderDetail: submitObj,
  517. };
  518. processAuditRef.value.openDialog(params);
  519. state.loading = false;
  520. }
  521. });
  522. };
  523. // 流程提交成功
  524. const knowledgeProcessSuccess = () => {
  525. // 关闭当前 tagsView
  526. mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
  527. mittBus.emit('clearCache', 'knowledgeManage');
  528. router.push({
  529. path: '/knowledge/index',
  530. });
  531. };
  532. // 预览
  533. const onPreview = () => {
  534. if (route.params.id) {
  535. } else {
  536. state.ruleForm.creatorName = userInfos.value?.name ?? '';
  537. state.ruleForm.creationTime = new Date();
  538. state.ruleForm.creatorOrgName = userInfos.value?.orgName ?? '';
  539. }
  540. Local.set('previewForm', state.ruleForm);
  541. router.push({
  542. name: 'knowledgePreview',
  543. params: {
  544. tagsViewName: '知识预览',
  545. },
  546. });
  547. };
  548. // 保存到草稿箱
  549. const onSaveOnly = throttle(async (formEl: FormInstance | undefined) => {
  550. if (!formEl) return;
  551. await formEl.validate((valid: boolean) => {
  552. if (!valid) return;
  553. state.loading = true;
  554. state.ruleForm.files = filesFormat.value;
  555. const submitObj = other.deepClone(state.ruleForm);
  556. Reflect.deleteProperty(submitObj, 'creationTime');
  557. if (route.params.id) {
  558. // 更新
  559. KnowledgeUpdate({ data: { ...submitObj, status: 0 } })
  560. .then(handleSuccess)
  561. .catch(() => {
  562. state.loading = false;
  563. });
  564. } else {
  565. // 新增
  566. KnowledgeAdd({ data: submitObj })
  567. .then(handleSuccess)
  568. .catch(() => {
  569. state.loading = false;
  570. });
  571. }
  572. });
  573. }, 300);
  574. // 取消
  575. const onCancel = () => {
  576. state.loading = true;
  577. mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
  578. mittBus.emit('clearCache', 'knowledgeManage');
  579. router.push({
  580. path: '/knowledge/index',
  581. });
  582. state.loading = false;
  583. };
  584. const handleSuccess = () => {
  585. state.loading = false;
  586. ElMessage.success('操作成功');
  587. // 关闭当前 tagsView
  588. mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
  589. mittBus.emit('clearCache', 'knowledgeManage');
  590. router.push({
  591. path: '/knowledge/index',
  592. });
  593. };
  594. const orgsOptions = ref<EmptyArrayType>([]); // 来源单位
  595. // 知识分类
  596. const getKnowledgeType = async () => {
  597. state.loading = true;
  598. try {
  599. const [typeDataRes, knowledgeOptionsRes, orgsOptionsRes] = await Promise.all([
  600. treeList({ IsEnable: true }),
  601. KnowledgeGetKnowledge(),
  602. getCanUseOrg(),
  603. ]);
  604. state.typeData = typeDataRes.result ?? [];
  605. state.knowledgeOptions = knowledgeOptionsRes.result ?? [];
  606. orgsOptions.value = orgsOptionsRes.result ?? [];
  607. await getDetail();
  608. state.loading = false;
  609. } catch (error) {
  610. state.loading = false;
  611. }
  612. };
  613. const getDetail = async () => {
  614. if (route.params.id) {
  615. const res: any = await KnowledgeInfo(route.params.id); //知识详情
  616. state.ruleForm = res.result ?? {};
  617. state.ruleForm.files = transformFile(state.ruleForm.files);
  618. if (state.ruleForm.hotspotExternal) {
  619. //热点分类默认展开
  620. state.hotspotExternal = state.ruleForm.hotspotExternal.split(',');
  621. }
  622. state.ruleForm.knowledges = state.ruleForm.knowledges ?? [];
  623. if (state.ruleForm.keywordsDto && state.ruleForm.keywordsDto.length) {
  624. state.ruleForm.keywordsName = state.ruleForm.keywordsDto.map((item: any) => item.tag).join(',');
  625. }
  626. state.ruleForm.knowledgeTypeId = state.ruleForm.knowledgeType.map((item: any) => item.knowledgeTypeId);
  627. }
  628. };
  629. onMounted(() => {
  630. getKnowledgeType();
  631. });
  632. </script>