From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/bpm/processInstance/detail/PrintDialog.vue | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 234 insertions(+), 0 deletions(-)
diff --git a/src/views/bpm/processInstance/detail/PrintDialog.vue b/src/views/bpm/processInstance/detail/PrintDialog.vue
new file mode 100644
index 0000000..fb8cd8b
--- /dev/null
+++ b/src/views/bpm/processInstance/detail/PrintDialog.vue
@@ -0,0 +1,234 @@
+<script setup lang="ts">
+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()
+
+const visible = ref(false)
+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()
+ } finally {
+ loading.value = false
+ }
+ visible.value = true
+}
+defineExpose({ open })
+
+const parseFormFields = () => {
+ if (!printData.value) return
+
+ const formFieldsObj = decodeFields(
+ printData.value.processInstance.processDefinition?.formFields || []
+ )
+ const processVariables = printData.value.processInstance.formVariables
+ let res: any = []
+ for (const item of formFieldsObj) {
+ const id = item['field']
+ const name = item['title']
+ const variable = processVariables[item['field']]
+ let html = variable
+ switch (item['type']) {
+ case 'UploadImg': {
+ let imgEl = document.createElement('img')
+ imgEl.setAttribute('src', variable)
+ imgEl.setAttribute('style', 'max-width: 600px;')
+ html = imgEl.outerHTML
+ break
+ }
+ case 'radio':
+ case 'checkbox':
+ case 'select': {
+ const options = item['options'] || []
+ const temp: any = []
+ if (Array.isArray(variable)) {
+ const labels = options.filter((o) => variable.includes(o.value)).map((o) => o.label)
+ temp.push(...labels)
+ } else {
+ const opt = options.find((o) => o.value === variable)
+ temp.push(opt.label)
+ }
+ html = temp.join(',')
+ }
+ // TODO 鏇村琛ㄥ崟鎵撳嵃灞曠ず
+ }
+ printDataMap.value[item['field']] = html
+ res.push({ id, name, html })
+ }
+ formFields.value = res
+}
+
+const initPrintDataMap = () => {
+ printDataMap.value['startUser'] = printData.value.processInstance.startUser.nickname
+ printDataMap.value['startUserDept'] = printData.value.processInstance.startUser.deptName
+ printDataMap.value['processName'] = printData.value.processInstance.name
+ printDataMap.value['processNum'] = printData.value.processInstance.id
+ printDataMap.value['startTime'] = formatDate(printData.value.processInstance.startTime)
+ printDataMap.value['endTime'] = formatDate(printData.value.processInstance.endTime)
+ printDataMap.value['processStatus'] = getDictLabel(
+ DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS,
+ printData.value.processInstance.status
+ )
+ printDataMap.value['printUser'] = 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.tasks.forEach((item) => {
+ const tr = document.createElement('tr')
+ const td1 = document.createElement('td')
+ td1.innerHTML = item.name
+ const td2 = document.createElement('td')
+ td2.innerHTML = item.description
+ 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: ' ',
+ extraCss: '/print.css',
+ extraHead: '',
+ zIndex: 20003
+})
+</script>
+
+<template>
+ <el-dialog v-loading="loading" v-model="visible" :show-close="false">
+ <div id="printDivTag" style="word-break: break-all">
+ <div v-if="printData.printTemplateEnable" v-html="getPrintTemplateHTML()"></div>
+ <div v-else>
+ <h2 class="text-center">{{ printData.processInstance.name }}</h2>
+ <div class="text-right text-15px">{{ '鎵撳嵃浜哄憳: ' + userName }}</div>
+ <div class="flex justify-between">
+ <div class="text-15px">{{ '娴佺▼缂栧彿: ' + printData.processInstance.id }}</div>
+ <div class="text-15px">{{ '鎵撳嵃鏃堕棿: ' + printTime }}</div>
+ </div>
+ <table class="mt-20px w-100%" border="1" style="border-collapse: collapse">
+ <tbody>
+ <tr>
+ <td class="p-5px w-25%">鍙戣捣浜�</td>
+ <td class="p-5px w-25%">{{ printData.processInstance.startUser.nickname }}</td>
+ <td class="p-5px w-25%">鍙戣捣鏃堕棿</td>
+ <td class="p-5px w-25%">{{ formatDate(printData.processInstance.startTime) }}</td>
+ </tr>
+ <tr>
+ <td class="p-5px w-25%">鎵�灞為儴闂�</td>
+ <td class="p-5px w-25%">{{ printData.processInstance.startUser.deptName }}</td>
+ <td class="p-5px w-25%">娴佺▼鐘舵��</td>
+ <td class="p-5px w-25%">
+ {{
+ getDictLabel(
+ DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS,
+ printData.processInstance.status
+ )
+ }}
+ </td>
+ </tr>
+ <tr>
+ <td class="p-5px w-100% text-center" colspan="4">
+ <h4>琛ㄥ崟鍐呭</h4>
+ </td>
+ </tr>
+ <tr v-for="item in formFields" :key="item.id">
+ <td class="p-5px w-20%">
+ {{ item.name }}
+ </td>
+ <td class="p-5px w-80%" colspan="3">
+ <div v-html="item.html"></div>
+ </td>
+ </tr>
+ <tr>
+ <td class="p-5px w-100% text-center" colspan="4">
+ <h4>娴佺▼鑺傜偣</h4>
+ </td>
+ </tr>
+ <tr v-for="item in printData.tasks" :key="item.id">
+ <td class="p-5px w-20%">
+ {{ item.name }}
+ </td>
+ <td class="p-5px w-80%" colspan="3">
+ {{ item.description }}
+ <div v-if="item.signPicUrl && item.signPicUrl.length > 0">
+ <img class="w-90px h-40px" :src="item.signPicUrl" alt="" />
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="visible = false">鍙� 娑�</el-button>
+ <el-button type="primary" v-print="printObj"> 鎵� 鍗�</el-button>
+ </div>
+ </template>
+ </el-dialog>
+</template>
+
+<style>
+/* 淇鎵撳嵃鍙樉绀轰竴椤� */
+@media print {
+ @page {
+ size: auto;
+ }
+
+ body,
+ html,
+ div {
+ height: auto !important;
+ }
+}
+</style>
--
Gitblit v1.8.0