Pārlūkot izejas kodu

!817 feat: 代码评审修改
Merge pull request !817 from Lesan/feature/bpm-打印

芋道源码 5 mēneši atpakaļ
vecāks
revīzija
15adc07b2e

+ 4 - 4
src/main.ts

@@ -42,8 +42,8 @@ import Logger from '@/utils/Logger'
 
 import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患
 
-// wangeditor 插件注册
-import { setupWangeditorPlugin } from '@/views/bpm/model/form/PrintTemplate'
+// wangEditor 插件注册
+import { setupWangEditorPlugin } from '@/views/bpm/model/form/PrintTemplate'
 
 import print from 'vue3-print-nb' // 打印插件
 
@@ -67,8 +67,8 @@ const setupAll = async () => {
   setupAuth(app)
   setupMountedFocus(app)
 
-  // wangeditor 插件注册
-  setupWangeditorPlugin()
+  // wangEditor 插件注册
+  setupWangEditorPlugin()
 
   await router.isReady()
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 1
src/views/bpm/model/form/ExtraSettings.vue


+ 3 - 5
src/views/bpm/model/form/PrintTemplate/MentionModal.vue

@@ -11,10 +11,9 @@ const list = ref([
   { id: 'processName', name: '流程名称' },
   { id: 'processNum', name: '流程编号' },
   { id: 'startTime', name: '发起时间' },
-  { id: 'endTime', name: '发起时间' },
+  { id: 'endTime', name: '结束时间' },
   { id: 'processStatus', name: '流程状态' },
-  { id: 'processResult', name: '流程结果' },
-  { id: 'printUser', name: '打印人' },
+  { id: 'printUsername', name: '打印人' },
   { id: 'printTime', name: '打印时间' }
 ])
 const searchedList = computed(() => {
@@ -41,9 +40,8 @@ const insertMentionHandler = (id: any, name: any) => {
   emit('hideMentionModal')
 }
 
-const formFields = inject('formFieldsObj')
+const formFields = inject<any>('formFieldsObj')
 onMounted(() => {
-  // TODO @lesan:这里 idea 会爆红,看看能不能处理下;
   if (formFields.value && formFields.value.length > 0) {
     const cloneFormField = formFields.value.map((item) => {
       return {

+ 1 - 2
src/views/bpm/model/form/PrintTemplate/index.ts

@@ -3,8 +3,7 @@ import processRecordModule from './module'
 import mentionModule from '@wangeditor/plugin-mention'
 
 // 注册:要在创建编辑器之前注册,且只能注册一次,不可重复注册
-// TODO @lesan:WangEditor 拼写
-export const setupWangeditorPlugin = () => {
+export const setupWangEditorPlugin = () => {
   Boot.registerModule(processRecordModule)
   Boot.registerModule(mentionModule)
 }

+ 1 - 1
src/views/bpm/model/form/PrintTemplate/module/index.ts

@@ -5,7 +5,7 @@ import elemToHtmlConf from './elem-to-html'
 import parseHtmlConf from './parse-elem-html'
 import processRecordMenu from './menu/ProcessRecordMenu'
 
-// TODO @lesan:PrintTemplate 是参考了哪些文档哇?要不要在 index.ts 稍微写点注释,方便大家理解;
+// 可参考 wangEditor 官方文档进行自定义扩展插件:https://www.wangeditor.com/v5/development.html#%E5%AE%9A%E4%B9%89%E6%96%B0%E5%85%83%E7%B4%A0
 const module: Partial<IModuleConf> = {
   editorPlugin: withProcessRecord,
   renderElems: [renderElemConf],

+ 99 - 14
src/views/bpm/processInstance/detail/PrintDialog.vue

@@ -2,6 +2,8 @@
 import * as ProcessInstanceApi from '@/api/bpm/processInstance'
 import { useUserStore } from '@/store/modules/user'
 import { formatDate } from '@/utils/formatTime'
+import { DICT_TYPE, getDictLabel } from '@/utils/dict'
+import { decodeFields } from '@/utils/formCreate'
 
 const userStore = useUserStore()
 
@@ -11,11 +13,15 @@ const loading = ref(false)
 const printData = ref()
 const userName = computed(() => userStore.user.nickname ?? '')
 const printTime = ref(formatDate(new Date(), 'YYYY-MM-DD HH:mm'))
+const formFields = ref()
+const printDataMap = ref({})
 
 const open = async (id: string) => {
   loading.value = true
   try {
     printData.value = await ProcessInstanceApi.getProcessInstancePrintData(id)
+    initPrintDataMap()
+    parseFormFields()
     console.log(printData.value)
   } finally {
     loading.value = false
@@ -24,6 +30,90 @@ const open = async (id: string) => {
 }
 defineExpose({ open })
 
+const parseFormFields = () => {
+  const formFieldsObj = decodeFields(printData.value.formFields)
+  const processVariables = printData.value.processVariables
+  let res: any = []
+  for (const item of formFieldsObj) {
+    const id = item['field']
+    const name = item['title']
+    let html = '暂不支持此类型的表单展示'
+    // TODO 完善各类型表单的展示
+    if (item['type'] === 'input') {
+      html = processVariables[item['field']]
+    }
+    if (item['type'] === 'UploadImg') {
+      html = `<img src="${processVariables[item['field']]}" style="max-width: 600px" />`
+    }
+    printDataMap.value[item['field']] = html
+    res.push({ id, name, html })
+  }
+  formFields.value = res
+}
+
+const initPrintDataMap = () => {
+  printDataMap.value['startUser'] = printData.value.startUser.nickname
+  printDataMap.value['startUserDept'] = printData.value.startUser.deptName
+  printDataMap.value['processName'] = printData.value.processName
+  printDataMap.value['processNum'] = printData.value.processInstanceId
+  printDataMap.value['startTime'] = printData.value.startTime
+  printDataMap.value['endTime'] = printData.value.endTime
+  printDataMap.value['processStatus'] = getDictLabel(
+    DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS,
+    printData.value.processStatus
+  )
+  printDataMap.value['printUsername'] = userName.value
+  printDataMap.value['printTime'] = printTime.value
+}
+
+const getPrintTemplateHTML = () => {
+  const parser = new DOMParser()
+  let doc = parser.parseFromString(printData.value.printTemplateHtml, 'text/html')
+  // table 添加border
+  let tables = doc.querySelectorAll('table')
+  tables.forEach((item) => {
+    item.setAttribute('border', '1')
+    item.setAttribute('style', (item.getAttribute('style') || '') + 'border-collapse:collapse;')
+  })
+  // 替换mentions
+  let mentions = doc.querySelectorAll('[data-w-e-type="mention"]')
+  mentions.forEach((item) => {
+    const mentionId = JSON.parse(decodeURIComponent(item.getAttribute('data-info') ?? ''))['id']
+    item.innerHTML = printDataMap.value[mentionId] ?? ''
+  })
+  // 替换流程记录
+  let processRecords = doc.querySelectorAll('[data-w-e-type="process-record"]')
+  let processRecordTable : Element = document.createElement('table')
+  if (processRecords.length > 0) {
+    // 构建流程记录html
+    processRecordTable.setAttribute('border', '1')
+    processRecordTable.setAttribute('style', 'width:100%;border-collapse:collapse;')
+    const headTr = document.createElement('tr')
+    const headTd = document.createElement('td')
+    headTd.setAttribute('colspan', '2')
+    headTd.setAttribute('width', 'auto')
+    headTd.setAttribute('style', 'text-align: center;')
+    headTd.innerHTML = '流程节点'
+    headTr.appendChild(headTd)
+    processRecordTable.appendChild(headTr)
+    printData.value.approveNodes.forEach(item => {
+      const tr = document.createElement('tr')
+      const td1 = document.createElement('td')
+      td1.innerHTML = item.nodeName
+      const td2 = document.createElement('td')
+      td2.innerHTML = item.nodeDesc
+      tr.appendChild(td1)
+      tr.appendChild(td2)
+      processRecordTable.appendChild(tr)
+    })
+  }
+  processRecords.forEach(item => {
+    item.innerHTML = processRecordTable.outerHTML
+  })
+  // 返回html
+  return doc.body.innerHTML
+}
+
 const printObj = ref({
   id: 'printDivTag',
   popTitle: '&nbsp',
@@ -36,7 +126,7 @@ const printObj = ref({
 <template>
   <el-dialog v-loading="loading" v-model="visible" :show-close="false">
     <div id="printDivTag">
-      <div v-if="printData.printTemplateEnable" v-html="printData.printTemplateHtml"></div>
+      <div v-if="printData.printTemplateEnable" v-html="getPrintTemplateHTML()"></div>
       <div v-else>
         <h2 class="text-center">{{ printData.processName }}</h2>
         <div class="text-right text-15px">{{ '打印人员: ' + userName }}</div>
@@ -48,27 +138,29 @@ const printObj = ref({
           <tbody>
             <tr>
               <td class="p-5px w-25%">发起人</td>
-              <td class="p-5px w-25%">{{ printData.startUser }}</td>
+              <td class="p-5px w-25%">{{ printData.startUser.nickname }}</td>
               <td class="p-5px w-25%">发起时间</td>
               <td class="p-5px w-25%">{{ printData.startTime }}</td>
             </tr>
             <tr>
               <td class="p-5px w-25%">所属部门</td>
-              <td class="p-5px w-25%">{{ printData.startUserDept }}</td>
+              <td class="p-5px w-25%">{{ printData.startUser.deptName }}</td>
               <td class="p-5px w-25%">流程状态</td>
-              <td class="p-5px w-25%">{{ printData.processStatusShow }}</td>
+              <td class="p-5px w-25%">
+                {{ getDictLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, printData.processStatus) }}
+              </td>
             </tr>
             <tr>
               <td class="p-5px w-100% text-center" colspan="4">
                 <h4>表单内容</h4>
               </td>
             </tr>
-            <tr v-for="item in printData.formFields" :key="item.formId">
+            <tr v-for="item in formFields" :key="item.id">
               <td class="p-5px w-20%">
-                {{ item.formName }}
+                {{ item.name }}
               </td>
               <td class="p-5px w-80%" colspan="3">
-                <div v-html="item.formValueShow"></div>
+                <div v-html="item.html"></div>
               </td>
             </tr>
             <tr>
@@ -98,11 +190,4 @@ const printObj = ref({
       </div>
     </template>
   </el-dialog>
-  <!-- TODO @lesan:最下面的 table 央视,可以去掉么? -->
 </template>
-
-<style lang="scss">
-table {
-  border-collapse: collapse;
-}
-</style>