@ -42,8 +42,8 @@ import Logger from '@/utils/Logger'
|
|||||||
|
|
||||||
import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患
|
import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患
|
||||||
|
|
||||||
// wangeditor 插件注册
|
// wangEditor 插件注册
|
||||||
import { setupWangeditorPlugin } from '@/views/bpm/model/form/PrintTemplate'
|
import { setupWangEditorPlugin } from '@/views/bpm/model/form/PrintTemplate'
|
||||||
|
|
||||||
import print from 'vue3-print-nb' // 打印插件
|
import print from 'vue3-print-nb' // 打印插件
|
||||||
|
|
||||||
@ -67,8 +67,8 @@ const setupAll = async () => {
|
|||||||
setupAuth(app)
|
setupAuth(app)
|
||||||
setupMountedFocus(app)
|
setupMountedFocus(app)
|
||||||
|
|
||||||
// wangeditor 插件注册
|
// wangEditor 插件注册
|
||||||
setupWangeditorPlugin()
|
setupWangEditorPlugin()
|
||||||
|
|
||||||
await router.isReady()
|
await router.isReady()
|
||||||
|
|
||||||
|
|||||||
@ -491,7 +491,6 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO defaultTemplate 是否需要放到 infra_config TODO @lesan:就先 default 这里好了。
|
|
||||||
const defaultTemplate =
|
const defaultTemplate =
|
||||||
'<p style="text-align: center;"><span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="流程名称" data-info="%7B%22id%22%3A%22processName%22%7D">@流程名称</span></p><p style="text-align: right;">打印人:<span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="打印人" data-info="%7B%22id%22%3A%22printUser%22%7D">@打印人</span></p><p style="text-align: right;">流程编号:<span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="流程编号" data-info="%7B%22id%22%3A%22processNum%22%7D">@流程编号</span> 打印时间:<span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="打印时间" data-info="%7B%22id%22%3A%22printTime%22%7D">@打印时间</span></p><table style="width: 100%;"><tbody><tr><td colSpan="1" rowSpan="1" width="auto">发起人</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="发起人" data-info="%7B%22id%22%3A%22startUser%22%7D">@发起人</span></td><td colSpan="1" rowSpan="1" width="auto">发起时间</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="发起时间" data-info="%7B%22id%22%3A%22startTime%22%7D">@发起时间</span></td></tr><tr><td colSpan="1" rowSpan="1" width="auto">所属部门</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="发起人部门" data-info="%7B%22id%22%3A%22startUserDept%22%7D">@发起人部门</span></td><td colSpan="1" rowSpan="1" width="auto">流程状态</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="流程状态" data-info="%7B%22id%22%3A%22processStatus%22%7D">@流程状态</span></td></tr></tbody></table><p><span data-w-e-type="process-record" data-w-e-is-void data-w-e-is-inline>流程记录</span></p>'
|
'<p style="text-align: center;"><span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="流程名称" data-info="%7B%22id%22%3A%22processName%22%7D">@流程名称</span></p><p style="text-align: right;">打印人:<span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="打印人" data-info="%7B%22id%22%3A%22printUser%22%7D">@打印人</span></p><p style="text-align: right;">流程编号:<span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="流程编号" data-info="%7B%22id%22%3A%22processNum%22%7D">@流程编号</span> 打印时间:<span data-w-e-type="mention" data-w-e-is-void="" data-w-e-is-inline="" data-value="打印时间" data-info="%7B%22id%22%3A%22printTime%22%7D">@打印时间</span></p><table style="width: 100%;"><tbody><tr><td colSpan="1" rowSpan="1" width="auto">发起人</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="发起人" data-info="%7B%22id%22%3A%22startUser%22%7D">@发起人</span></td><td colSpan="1" rowSpan="1" width="auto">发起时间</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="发起时间" data-info="%7B%22id%22%3A%22startTime%22%7D">@发起时间</span></td></tr><tr><td colSpan="1" rowSpan="1" width="auto">所属部门</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="发起人部门" data-info="%7B%22id%22%3A%22startUserDept%22%7D">@发起人部门</span></td><td colSpan="1" rowSpan="1" width="auto">流程状态</td><td colSpan="1" rowSpan="1" width="auto"><span data-w-e-type="mention" data-w-e-is-void data-w-e-is-inline data-value="流程状态" data-info="%7B%22id%22%3A%22processStatus%22%7D">@流程状态</span></td></tr></tbody></table><p><span data-w-e-type="process-record" data-w-e-is-void data-w-e-is-inline>流程记录</span></p>'
|
||||||
const handlePrintTemplateEnableChange = (val: boolean) => {
|
const handlePrintTemplateEnableChange = (val: boolean) => {
|
||||||
|
|||||||
@ -11,10 +11,9 @@ const list = ref([
|
|||||||
{ id: 'processName', name: '流程名称' },
|
{ id: 'processName', name: '流程名称' },
|
||||||
{ id: 'processNum', name: '流程编号' },
|
{ id: 'processNum', name: '流程编号' },
|
||||||
{ id: 'startTime', name: '发起时间' },
|
{ id: 'startTime', name: '发起时间' },
|
||||||
{ id: 'endTime', name: '发起时间' },
|
{ id: 'endTime', name: '结束时间' },
|
||||||
{ id: 'processStatus', name: '流程状态' },
|
{ id: 'processStatus', name: '流程状态' },
|
||||||
{ id: 'processResult', name: '流程结果' },
|
{ id: 'printUsername', name: '打印人' },
|
||||||
{ id: 'printUser', name: '打印人' },
|
|
||||||
{ id: 'printTime', name: '打印时间' }
|
{ id: 'printTime', name: '打印时间' }
|
||||||
])
|
])
|
||||||
const searchedList = computed(() => {
|
const searchedList = computed(() => {
|
||||||
@ -41,9 +40,8 @@ const insertMentionHandler = (id: any, name: any) => {
|
|||||||
emit('hideMentionModal')
|
emit('hideMentionModal')
|
||||||
}
|
}
|
||||||
|
|
||||||
const formFields = inject('formFieldsObj')
|
const formFields = inject<any>('formFieldsObj')
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// TODO @lesan:这里 idea 会爆红,看看能不能处理下;
|
|
||||||
if (formFields.value && formFields.value.length > 0) {
|
if (formFields.value && formFields.value.length > 0) {
|
||||||
const cloneFormField = formFields.value.map((item) => {
|
const cloneFormField = formFields.value.map((item) => {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -3,8 +3,7 @@ import processRecordModule from './module'
|
|||||||
import mentionModule from '@wangeditor/plugin-mention'
|
import mentionModule from '@wangeditor/plugin-mention'
|
||||||
|
|
||||||
// 注册:要在创建编辑器之前注册,且只能注册一次,不可重复注册
|
// 注册:要在创建编辑器之前注册,且只能注册一次,不可重复注册
|
||||||
// TODO @lesan:WangEditor 拼写
|
export const setupWangEditorPlugin = () => {
|
||||||
export const setupWangeditorPlugin = () => {
|
|
||||||
Boot.registerModule(processRecordModule)
|
Boot.registerModule(processRecordModule)
|
||||||
Boot.registerModule(mentionModule)
|
Boot.registerModule(mentionModule)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import elemToHtmlConf from './elem-to-html'
|
|||||||
import parseHtmlConf from './parse-elem-html'
|
import parseHtmlConf from './parse-elem-html'
|
||||||
import processRecordMenu from './menu/ProcessRecordMenu'
|
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> = {
|
const module: Partial<IModuleConf> = {
|
||||||
editorPlugin: withProcessRecord,
|
editorPlugin: withProcessRecord,
|
||||||
renderElems: [renderElemConf],
|
renderElems: [renderElemConf],
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
|
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
|
import { DICT_TYPE, getDictLabel } from '@/utils/dict'
|
||||||
|
import { decodeFields } from '@/utils/formCreate'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
@ -11,11 +13,15 @@ const loading = ref(false)
|
|||||||
const printData = ref()
|
const printData = ref()
|
||||||
const userName = computed(() => userStore.user.nickname ?? '')
|
const userName = computed(() => userStore.user.nickname ?? '')
|
||||||
const printTime = ref(formatDate(new Date(), 'YYYY-MM-DD HH:mm'))
|
const printTime = ref(formatDate(new Date(), 'YYYY-MM-DD HH:mm'))
|
||||||
|
const formFields = ref()
|
||||||
|
const printDataMap = ref({})
|
||||||
|
|
||||||
const open = async (id: string) => {
|
const open = async (id: string) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
printData.value = await ProcessInstanceApi.getProcessInstancePrintData(id)
|
printData.value = await ProcessInstanceApi.getProcessInstancePrintData(id)
|
||||||
|
initPrintDataMap()
|
||||||
|
parseFormFields()
|
||||||
console.log(printData.value)
|
console.log(printData.value)
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@ -24,6 +30,90 @@ const open = async (id: string) => {
|
|||||||
}
|
}
|
||||||
defineExpose({ open })
|
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({
|
const printObj = ref({
|
||||||
id: 'printDivTag',
|
id: 'printDivTag',
|
||||||
popTitle: ' ',
|
popTitle: ' ',
|
||||||
@ -36,7 +126,7 @@ const printObj = ref({
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-loading="loading" v-model="visible" :show-close="false">
|
<el-dialog v-loading="loading" v-model="visible" :show-close="false">
|
||||||
<div id="printDivTag">
|
<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>
|
<div v-else>
|
||||||
<h2 class="text-center">{{ printData.processName }}</h2>
|
<h2 class="text-center">{{ printData.processName }}</h2>
|
||||||
<div class="text-right text-15px">{{ '打印人员: ' + userName }}</div>
|
<div class="text-right text-15px">{{ '打印人员: ' + userName }}</div>
|
||||||
@ -48,27 +138,29 @@ const printObj = ref({
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="p-5px w-25%">发起人</td>
|
<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%">发起时间</td>
|
||||||
<td class="p-5px w-25%">{{ printData.startTime }}</td>
|
<td class="p-5px w-25%">{{ printData.startTime }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="p-5px w-25%">所属部门</td>
|
<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%">流程状态</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>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="p-5px w-100% text-center" colspan="4">
|
<td class="p-5px w-100% text-center" colspan="4">
|
||||||
<h4>表单内容</h4>
|
<h4>表单内容</h4>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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%">
|
<td class="p-5px w-20%">
|
||||||
{{ item.formName }}
|
{{ item.name }}
|
||||||
</td>
|
</td>
|
||||||
<td class="p-5px w-80%" colspan="3">
|
<td class="p-5px w-80%" colspan="3">
|
||||||
<div v-html="item.formValueShow"></div>
|
<div v-html="item.html"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -98,11 +190,4 @@ const printObj = ref({
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- TODO @lesan:最下面的 table 央视,可以去掉么? -->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user