preview.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <template>
  2. <div class="knowledge-preview-container layout-pd">
  3. <el-card shadow="never">
  4. <el-row v-loading="loading">
  5. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb10">
  6. <h1 class="font18">{{ state.info.title }}</h1></el-col
  7. >
  8. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="color-info flex-center-align flex-warp">
  9. <span class="mr10">创建时间:{{ formatDate(state.info.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
  10. <span class="mr10">创建人:{{ state.info.creatorName }}</span>
  11. <span class="mr10">创建部门:{{ state.info.creatorOrgName }}</span>
  12. <span class="mr10">更新时间:{{ formatDate(state.info.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
  13. <span class="mr10">知识分类:{{ state.info.knowledgeType?.map(item=> item.value).join(',') }}</span>
  14. <template v-if="route.params.id">
  15. <span class="mr10">已阅:{{ state.info.pageView }}</span>
  16. <el-button link class="flex-center-align" type="info" @click="onCollect" v-auth="'knowledge:collect:collect'">
  17. <SvgIcon :name="state.info?.collect?.collect ? 'ele-StarFilled' : 'ele-Star'" class="mr4" size="18px" />{{
  18. state.info?.collect?.collect ? '取消收藏' : '收藏'
  19. }}
  20. </el-button>
  21. <el-button link class="flex-center-align" type="info" v-auth="'knowledge:collect:rate'">
  22. <el-rate v-model="state.info.score" allow-half @change="onRate" /> 评分</el-button
  23. >
  24. <el-button link class="flex-center-align" type="info" @click="onError"> <SvgIcon name="ele-EditPen" class="mr4" />知识纠错</el-button>
  25. <el-button link class="flex-center-align" type="info" @click="onQuestion">
  26. <SvgIcon name="ele-QuestionFilled" class="mr4" />知识提问</el-button
  27. >
  28. </template>
  29. </el-col>
  30. <el-divider />
  31. 摘要
  32. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mt5"> {{ state.info.summary }}</el-col>
  33. <el-divider />
  34. 正文
  35. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mt5 editor-content-view">
  36. <div v-html="state.info.content" class="lineHeight24"></div
  37. ></el-col>
  38. <template v-if="state.info.knowledgeDtos && state.info.knowledgeDtos.length">
  39. <el-divider />
  40. 关联知识
  41. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mt5">
  42. <div v-for="item in state.info.knowledgeDtos" @click="onPreview(item)" class="relevance">
  43. <el-link type="primary">{{ item.title }}</el-link>
  44. </div>
  45. </el-col>
  46. </template>
  47. <template v-if="route.params.id">
  48. <el-divider />
  49. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mt10">
  50. <el-form-item label="附件">
  51. <annex-list name="知识附件" v-model="state.info.files" readonly classify="知识附件" />
  52. </el-form-item>
  53. </el-col>
  54. </template>
  55. </el-row>
  56. <el-button
  57. type="primary"
  58. @click="onAudit"
  59. title="审批"
  60. v-if="[1, 2].includes(state.info.status) && state.info.isCanHandle"
  61. v-auth="'knowledge:index:audit'"
  62. >
  63. 审批
  64. </el-button>
  65. </el-card>
  66. <!-- 知识纠错 -->
  67. <error-add ref="errorAddRef" />
  68. <!-- 知识提问 -->
  69. <question-add ref="questionRef" />
  70. <!-- 流程审批 -->
  71. <process-audit ref="processAuditRef" @orderProcessSuccess="closePage" />
  72. </div>
  73. </template>
  74. <script setup lang="ts" name="knowledgePreview">
  75. import { reactive, onMounted, onBeforeUnmount, ref, defineAsyncComponent } from 'vue';
  76. import { useRoute, useRouter } from 'vue-router';
  77. import { Local } from '@/utils/storage';
  78. import { KnowledgeInfo, knowledgeCollect, knowledgeScore } from '@/api/knowledge';
  79. import { formatDate } from '@/utils/formatTime';
  80. import { ElMessage } from 'element-plus';
  81. import mittBus from '@/utils/mitt';
  82. import { transformFile } from '@/utils/tools';
  83. // 引入组件
  84. const ErrorAdd = defineAsyncComponent(() => import('@/views/knowledge/error/components/Error-add.vue')); // 知识纠错
  85. const QuestionAdd = defineAsyncComponent(() => import('@/views/knowledge/question/components/Question-add.vue')); // 知识提问
  86. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件列表
  87. const ProcessAudit = defineAsyncComponent(() => import('@/components/ProcessAudit/index.vue')); // 流程审批
  88. // 定义变量内容
  89. const state = reactive<any>({
  90. info: {
  91. knowledgeTypeName: '', // 类别
  92. hotspotName: '', // 热点
  93. keywords: '', // 关键词
  94. isPublic: false, // 是否公开
  95. creatorName: '', // 创建人
  96. creationTime: '', // 创建时间
  97. summary: '', // 摘要
  98. content: '', // 内容
  99. collect: false, // 收藏
  100. score: 0, // 评分
  101. },
  102. });
  103. const loading = ref<Boolean>(false); // 加载状态
  104. // 查询知识详情
  105. const route = useRoute(); // 获取路由参数
  106. // 收藏
  107. const onCollect = () => {
  108. knowledgeCollect({ knowledgeId: state.info.id, collect: !state.info?.collect?.collect })
  109. .then(() => {
  110. ElMessage.success('操作成功');
  111. getInfo();
  112. })
  113. .catch(() => {});
  114. };
  115. // 评分
  116. const onRate = () => {
  117. knowledgeScore({ knowledgeId: state.info.id, score: state.info.score })
  118. .then(() => {
  119. ElMessage.success('操作成功');
  120. getInfo();
  121. })
  122. .catch(() => {});
  123. };
  124. // 知识纠错
  125. const errorAddRef = ref<RefType>();
  126. const onError = () => {
  127. errorAddRef.value?.openDialog(state.info);
  128. };
  129. // 知识提问
  130. const questionRef = ref<RefType>();
  131. const onQuestion = () => {
  132. questionRef.value?.openDialog(state.info);
  133. };
  134. // 预览
  135. const router = useRouter();
  136. const onPreview = (row: any) => {
  137. if (!router.hasRoute('knowledgePreview')) {
  138. ElMessage.warning('未找到知识查看页面');
  139. return;
  140. }
  141. router.push({
  142. name: 'knowledgePreview',
  143. params: {
  144. id: row.id,
  145. tagsViewName: '知识查看',
  146. },
  147. });
  148. };
  149. // 查询详情
  150. const getInfo = async () => {
  151. loading.value = true;
  152. if (route.params.id) {
  153. try {
  154. const { isAddPv } = route.params;
  155. let IsAddPv = isAddPv ? 'true' : false;
  156. const res: any = await KnowledgeInfo(route.params.id, { isAddPv: IsAddPv });
  157. state.info = res.result ?? {};
  158. state.info.files = transformFile(state.info.files);
  159. loading.value = false;
  160. } catch (error) {
  161. loading.value = false;
  162. }
  163. } else {
  164. state.info = Local.get('previewForm') ?? {};
  165. state.info.files = transformFile(state.info.files);
  166. loading.value = false;
  167. }
  168. };
  169. // 审批
  170. const processAuditRef = ref<RefType>(); //审核记录ref
  171. const onAudit = () => {
  172. const params = {
  173. id: state.info.workflowId,
  174. processType: '知识审批',
  175. orderDetail: state.info,
  176. extra: {
  177. dialogTitle: '知识审批',
  178. inputPlaceholder: '办理意见',
  179. annexName: '知识附件',
  180. },
  181. };
  182. processAuditRef.value.openDialog(params);
  183. };
  184. // 关闭当前页
  185. const closePage = () => {
  186. // 关闭当前 tagsView
  187. mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
  188. mittBus.emit('clearCache', 'knowledgeManage');
  189. router.push({
  190. path: '/knowledge/index',
  191. });
  192. };
  193. onMounted(() => {
  194. getInfo();
  195. });
  196. onBeforeUnmount(() => {
  197. Local.remove('previewForm'); // 删除本地缓存
  198. });
  199. </script>
  200. <style lang="scss" scoped>
  201. .knowledge-preview-container {
  202. .relevance {
  203. margin-bottom: 5px;
  204. &:last-child {
  205. margin-bottom: 0;
  206. }
  207. }
  208. }
  209. </style>