review:【bpm 工作流】流程打印
This commit is contained in:
@ -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,12 +67,14 @@ const setupAll = async () => {
|
|||||||
setupAuth(app)
|
setupAuth(app)
|
||||||
setupMountedFocus(app)
|
setupMountedFocus(app)
|
||||||
|
|
||||||
|
// wangeditor 插件注册
|
||||||
setupWangeditorPlugin()
|
setupWangeditorPlugin()
|
||||||
|
|
||||||
await router.isReady()
|
await router.isReady()
|
||||||
|
|
||||||
app.use(VueDOMPurifyHTML)
|
app.use(VueDOMPurifyHTML)
|
||||||
|
|
||||||
|
// 打印
|
||||||
app.use(print)
|
app.use(print)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|||||||
@ -254,7 +254,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<print-template ref="printTemplateRef" @confirm="confirmPrintTemplate"/>
|
<print-template ref="printTemplateRef" @confirm="confirmPrintTemplate" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -491,8 +491,9 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO defaultTemplate 是否需要放到 infra_config
|
// TODO defaultTemplate 是否需要放到 infra_config TODO @lesan:就先 default 这里好了。
|
||||||
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>'
|
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>'
|
||||||
const handlePrintTemplateEnableChange = (val: boolean) => {
|
const handlePrintTemplateEnableChange = (val: boolean) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
if (!modelData.value.printTemplateSetting.template) {
|
if (!modelData.value.printTemplateSetting.template) {
|
||||||
@ -504,7 +505,7 @@ const printTemplateRef = ref()
|
|||||||
const handleEditPrintTemplate = () => {
|
const handleEditPrintTemplate = () => {
|
||||||
printTemplateRef.value.open(modelData.value.printTemplateSetting.template)
|
printTemplateRef.value.open(modelData.value.printTemplateSetting.template)
|
||||||
}
|
}
|
||||||
const confirmPrintTemplate = (template) => {
|
const confirmPrintTemplate = (template: any) => {
|
||||||
modelData.value.printTemplateSetting.template = template
|
modelData.value.printTemplateSetting.template = template
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {Editor, Toolbar} from '@wangeditor/editor-for-vue'
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||||
import {IDomEditor} from '@wangeditor/editor'
|
import { IDomEditor } from '@wangeditor/editor'
|
||||||
import MentionModal from "./MentionModal.vue";
|
import MentionModal from './MentionModal.vue'
|
||||||
|
|
||||||
const emit = defineEmits(['confirm'])
|
const emit = defineEmits(['confirm'])
|
||||||
|
|
||||||
// mention
|
// @mention 相关
|
||||||
const isShowModal = ref(false)
|
const isShowModal = ref(false)
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
isShowModal.value = true
|
isShowModal.value = true
|
||||||
@ -13,12 +13,12 @@ const showModal = () => {
|
|||||||
const hideModal = () => {
|
const hideModal = () => {
|
||||||
isShowModal.value = false
|
isShowModal.value = false
|
||||||
}
|
}
|
||||||
const insertMention = (id, name) => {
|
const insertMention = (id: any, name: any) => {
|
||||||
const mentionNode = {
|
const mentionNode = {
|
||||||
type: 'mention',
|
type: 'mention',
|
||||||
value: name,
|
value: name,
|
||||||
info: {id},
|
info: { id },
|
||||||
children: [{text: ''}],
|
children: [{ text: '' }]
|
||||||
}
|
}
|
||||||
const editor = editorRef.value
|
const editor = editorRef.value
|
||||||
if (editor) {
|
if (editor) {
|
||||||
@ -29,20 +29,19 @@ const insertMention = (id, name) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dialog
|
// Dialog 相关
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const open = async (template) => {
|
const open = async (template: string) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
valueHtml.value = template
|
valueHtml.value = template
|
||||||
console.log(template)
|
|
||||||
}
|
}
|
||||||
defineExpose({open})
|
defineExpose({ open })
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
emit('confirm', valueHtml.value)
|
emit('confirm', valueHtml.value)
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Editor
|
// Editor 相关
|
||||||
const editorRef = shallowRef<IDomEditor>()
|
const editorRef = shallowRef<IDomEditor>()
|
||||||
const editorId = ref('wangeEditor-1')
|
const editorId = ref('wangeEditor-1')
|
||||||
const toolbarConfig = {
|
const toolbarConfig = {
|
||||||
@ -57,41 +56,45 @@ const editorConfig = {
|
|||||||
EXTEND_CONF: {
|
EXTEND_CONF: {
|
||||||
mentionConfig: {
|
mentionConfig: {
|
||||||
showModal,
|
showModal,
|
||||||
hideModal,
|
hideModal
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
const valueHtml = ref()
|
const valueHtml = ref()
|
||||||
const handleCreated = (editor: IDomEditor) => {
|
const handleCreated = (editor: IDomEditor) => {
|
||||||
editorRef.value = editor
|
editorRef.value = editor
|
||||||
}
|
}
|
||||||
|
|
||||||
// onBeforeUnmount
|
/** 初始化 */
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
const editor = editorRef.value
|
const editor = editorRef.value
|
||||||
if (editor == null) return
|
if (editor == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
editor.destroy()
|
editor.destroy()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="dialogVisible" title="自定义模板" fullscreen>
|
<el-dialog v-model="dialogVisible" title="自定义模板" fullscreen>
|
||||||
<div style="margin: 0 10px;">
|
<div style="margin: 0 10px">
|
||||||
<el-alert
|
<el-alert
|
||||||
title="输入 @ 可选择插入流程表单选项和默认选项"
|
title="输入 @ 可选择插入流程表单选项和默认选项"
|
||||||
type="info"
|
type="info"
|
||||||
show-icon
|
show-icon
|
||||||
:closable="false"/>
|
:closable="false"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style="border: 1px solid #ccc;margin: 10px;">
|
<!-- TODO @unocss 简化 style -->
|
||||||
|
<div style="border: 1px solid #ccc; margin: 10px">
|
||||||
<Toolbar
|
<Toolbar
|
||||||
style="border-bottom: 1px solid #ccc;"
|
style="border-bottom: 1px solid #ccc"
|
||||||
:editor="editorRef"
|
:editor="editorRef"
|
||||||
:editorId="editorId"
|
:editorId="editorId"
|
||||||
:defaultConfig="toolbarConfig"
|
:defaultConfig="toolbarConfig"
|
||||||
/>
|
/>
|
||||||
<Editor
|
<Editor
|
||||||
style="height: 500px; overflow-y: hidden;"
|
style="height: 500px; overflow-y: hidden"
|
||||||
v-model="valueHtml"
|
v-model="valueHtml"
|
||||||
:defaultConfig="editorConfig"
|
:defaultConfig="editorConfig"
|
||||||
:editorId="editorId"
|
:editorId="editorId"
|
||||||
@ -100,9 +103,10 @@ onBeforeUnmount(() => {
|
|||||||
<MentionModal
|
<MentionModal
|
||||||
v-if="isShowModal"
|
v-if="isShowModal"
|
||||||
@hide-mention-modal="hideModal"
|
@hide-mention-modal="hideModal"
|
||||||
@insert-mention="insertMention"/>
|
@insert-mention="insertMention"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-right: 10px;float: right;">
|
<div style="margin-right: 10px; float: right">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
<el-button type="primary" @click="handleConfirm">确 定</el-button>
|
<el-button type="primary" @click="handleConfirm">确 定</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,47 +6,48 @@ const top = ref('')
|
|||||||
const left = ref('')
|
const left = ref('')
|
||||||
const searchVal = ref('')
|
const searchVal = ref('')
|
||||||
const list = ref([
|
const list = ref([
|
||||||
{id: 'startUser', name: '发起人'},
|
{ id: 'startUser', name: '发起人' },
|
||||||
{id: 'startUserDept', name: '发起人部门'},
|
{ id: 'startUserDept', name: '发起人部门' },
|
||||||
{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: 'processResult', name: '流程结果' },
|
||||||
{id: 'printUser', name: '打印人'},
|
{ id: 'printUser', name: '打印人' },
|
||||||
{id: 'printTime', name: '打印时间'},
|
{ id: 'printTime', name: '打印时间' }
|
||||||
])
|
])
|
||||||
const searchedList = computed(() => {
|
const searchedList = computed(() => {
|
||||||
const searchValStr = searchVal.value.trim().toLowerCase()
|
const searchValStr = searchVal.value.trim().toLowerCase()
|
||||||
return list.value.filter(item => {
|
return list.value.filter((item) => {
|
||||||
const name = item.name.toLowerCase()
|
const name = item.name.toLowerCase()
|
||||||
return name.indexOf(searchValStr) >= 0;
|
return name.indexOf(searchValStr) >= 0
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
const inputKeyupHandler = (event) => {
|
const inputKeyupHandler = (event: any) => {
|
||||||
if (event.key === 'Escape') {
|
if (event.key === 'Escape') {
|
||||||
emit('hideMentionModal')
|
emit('hideMentionModal')
|
||||||
}
|
}
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
const firstOne = searchedList.value[0]
|
const firstOne = searchedList.value[0]
|
||||||
if (firstOne) {
|
if (firstOne) {
|
||||||
const {id, name} = firstOne
|
const { id, name } = firstOne
|
||||||
insertMentionHandler(id, name)
|
insertMentionHandler(id, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const insertMentionHandler = (id, name) => {
|
const insertMentionHandler = (id: any, name: any) => {
|
||||||
emit('insertMention', id, name)
|
emit('insertMention', id, name)
|
||||||
emit('hideMentionModal')
|
emit('hideMentionModal')
|
||||||
}
|
}
|
||||||
|
|
||||||
const formFields = inject('formFieldsObj')
|
const formFields = inject('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 {
|
||||||
name: '[表单]'+item.title,
|
name: '[表单]' + item.title,
|
||||||
id: item.field
|
id: item.field
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -66,13 +67,15 @@ onMounted(()=> {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="mention-modal" :style="{ top: top, left: left }">
|
<div id="mention-modal" :style="{ top: top, left: left }">
|
||||||
|
<!-- TODO @lesan:css 可以用 unocss 哇? -->
|
||||||
<input id="mention-input" v-model="searchVal" ref="inputRef" @keyup="inputKeyupHandler" />
|
<input id="mention-input" v-model="searchVal" ref="inputRef" @keyup="inputKeyupHandler" />
|
||||||
<ul id="mention-list">
|
<ul id="mention-list">
|
||||||
<li
|
<li
|
||||||
v-for="item in searchedList"
|
v-for="item in searchedList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@click="insertMentionHandler(item.id, item.name)"
|
@click="insertMentionHandler(item.id, item.name)"
|
||||||
>{{ item.name }}
|
>
|
||||||
|
{{ item.name }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import {Boot} from '@wangeditor/editor'
|
import { Boot } from '@wangeditor/editor'
|
||||||
import processRecordModule from "./module";
|
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)
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { SlateElement } from '@wangeditor/editor'
|
import { SlateElement } from '@wangeditor/editor'
|
||||||
|
|
||||||
function processRecordToHtml(elem: SlateElement, childrenHtml: string): string {
|
function processRecordToHtml(_elem: SlateElement, _childrenHtml: string): string {
|
||||||
return `<span data-w-e-type="process-record" data-w-e-is-void data-w-e-is-inline>流程记录</span>`
|
return `<span data-w-e-type="process-record" data-w-e-is-void data-w-e-is-inline>流程记录</span>`
|
||||||
}
|
}
|
||||||
|
|
||||||
const conf = {
|
const conf = {
|
||||||
type: 'process-record',
|
type: 'process-record',
|
||||||
elemToHtml: processRecordToHtml,
|
elemToHtml: processRecordToHtml
|
||||||
}
|
}
|
||||||
|
|
||||||
export default conf
|
export default conf
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
import {IModuleConf} from '@wangeditor/editor'
|
import { IModuleConf } from '@wangeditor/editor'
|
||||||
import withProcessRecord from './plugin'
|
import withProcessRecord from './plugin'
|
||||||
import renderElemConf from './render-elem'
|
import renderElemConf from './render-elem'
|
||||||
import elemToHtmlConf from './elem-to-html'
|
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 稍微写点注释,方便大家理解;
|
||||||
const module: Partial<IModuleConf> = {
|
const module: Partial<IModuleConf> = {
|
||||||
editorPlugin: withProcessRecord,
|
editorPlugin: withProcessRecord,
|
||||||
renderElems: [renderElemConf],
|
renderElems: [renderElemConf],
|
||||||
elemsToHtml: [elemToHtmlConf],
|
elemsToHtml: [elemToHtmlConf],
|
||||||
parseElemsHtml: [parseHtmlConf],
|
parseElemsHtml: [parseHtmlConf],
|
||||||
menus: [processRecordMenu],
|
menus: [processRecordMenu]
|
||||||
}
|
}
|
||||||
|
|
||||||
export default module
|
export default module
|
||||||
|
|||||||
@ -1,31 +1,31 @@
|
|||||||
import { IButtonMenu, IDomEditor } from '@wangeditor/editor'
|
import { IButtonMenu, IDomEditor } from '@wangeditor/editor'
|
||||||
|
|
||||||
class ProcessRecordMenu implements IButtonMenu {
|
class ProcessRecordMenu implements IButtonMenu {
|
||||||
readonly tag: string;
|
readonly tag: string
|
||||||
readonly title: string;
|
readonly title: string
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.title = '流程记录'
|
this.title = '流程记录'
|
||||||
this.tag = 'button'
|
this.tag = 'button'
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue(editor: IDomEditor): string {
|
getValue(_editor: IDomEditor): string {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
isActive(editor: IDomEditor): boolean {
|
isActive(_editor: IDomEditor): boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
isDisabled(editor: IDomEditor): boolean {
|
isDisabled(_editor: IDomEditor): boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
exec(editor: IDomEditor, value: string) {
|
exec(editor: IDomEditor, _value: string) {
|
||||||
if (this.isDisabled(editor)) return
|
if (this.isDisabled(editor)) return
|
||||||
const processRecordElem = {
|
const processRecordElem = {
|
||||||
type: 'process-record',
|
type: 'process-record',
|
||||||
children: [{ text: '' }],
|
children: [{ text: '' }]
|
||||||
}
|
}
|
||||||
editor.insertNode(processRecordElem)
|
editor.insertNode(processRecordElem)
|
||||||
editor.move(1)
|
editor.move(1)
|
||||||
|
|||||||
@ -2,19 +2,20 @@ import { DOMElement } from './utils/dom'
|
|||||||
import { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor/editor'
|
import { IDomEditor, SlateDescendant, SlateElement } from '@wangeditor/editor'
|
||||||
|
|
||||||
function parseHtml(
|
function parseHtml(
|
||||||
elem: DOMElement,
|
_elem: DOMElement,
|
||||||
children: SlateDescendant[],
|
_children: SlateDescendant[],
|
||||||
editor: IDomEditor
|
_editor: IDomEditor
|
||||||
): SlateElement {
|
): SlateElement {
|
||||||
return {
|
return {
|
||||||
|
// TODO @lesan:这里有个红色告警,可以去掉哇?
|
||||||
type: 'process-record',
|
type: 'process-record',
|
||||||
children: [{ text: '' }],
|
children: [{ text: '' }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseHtmlConf = {
|
const parseHtmlConf = {
|
||||||
selector: 'span[data-w-e-type="process-record"]',
|
selector: 'span[data-w-e-type="process-record"]',
|
||||||
parseElemHtml: parseHtml,
|
parseElemHtml: parseHtml
|
||||||
}
|
}
|
||||||
|
|
||||||
export default parseHtmlConf
|
export default parseHtmlConf
|
||||||
|
|||||||
@ -4,7 +4,7 @@ function withProcessRecord<T extends IDomEditor>(editor: T) {
|
|||||||
const { isInline, isVoid } = editor
|
const { isInline, isVoid } = editor
|
||||||
const newEditor = editor
|
const newEditor = editor
|
||||||
|
|
||||||
newEditor.isInline = elem => {
|
newEditor.isInline = (elem) => {
|
||||||
const type = DomEditor.getNodeType(elem)
|
const type = DomEditor.getNodeType(elem)
|
||||||
if (type === 'process-record') {
|
if (type === 'process-record') {
|
||||||
return true
|
return true
|
||||||
@ -13,7 +13,7 @@ function withProcessRecord<T extends IDomEditor>(editor: T) {
|
|||||||
return isInline(elem)
|
return isInline(elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
newEditor.isVoid = elem => {
|
newEditor.isVoid = (elem) => {
|
||||||
const type = DomEditor.getNodeType(elem)
|
const type = DomEditor.getNodeType(elem)
|
||||||
if (type === 'process-record') {
|
if (type === 'process-record') {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -1,58 +1,60 @@
|
|||||||
import {h, VNode} from 'snabbdom'
|
import { h, VNode } from 'snabbdom'
|
||||||
import {DomEditor, IDomEditor, SlateElement} from '@wangeditor/editor'
|
import { DomEditor, IDomEditor, SlateElement } from '@wangeditor/editor'
|
||||||
|
|
||||||
function renderProcessRecord(elem: SlateElement, children: VNode[] | null, editor: IDomEditor): VNode {
|
function renderProcessRecord(
|
||||||
|
elem: SlateElement,
|
||||||
|
_children: VNode[] | null,
|
||||||
|
editor: IDomEditor
|
||||||
|
): VNode {
|
||||||
const selected = DomEditor.isNodeSelected(editor, elem)
|
const selected = DomEditor.isNodeSelected(editor, elem)
|
||||||
|
|
||||||
const vnode = h(
|
return h(
|
||||||
'table',
|
'table',
|
||||||
{
|
{
|
||||||
props: {
|
props: {
|
||||||
contentEditable: false,
|
contentEditable: false
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
border: selected
|
border: selected ? '2px solid var(--w-e-textarea-selected-border-color)' : ''
|
||||||
? '2px solid var(--w-e-textarea-selected-border-color)'
|
}
|
||||||
: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
h('thead', [
|
h('thead', [h('tr', [h('th', { attrs: { colSpan: 3 } }, '流程记录')])]),
|
||||||
h('tr', [h('th', {attrs: {colSpan: 3}}, '流程记录')])
|
|
||||||
]),
|
|
||||||
h('tbody', [
|
h('tbody', [
|
||||||
h('tr', [
|
h('tr', [
|
||||||
h('td', [h(
|
h('td', [
|
||||||
|
h(
|
||||||
'span',
|
'span',
|
||||||
{
|
{
|
||||||
props: {
|
props: {
|
||||||
contentEditable: false,
|
contentEditable: false
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
marginLeft: '3px',
|
marginLeft: '3px',
|
||||||
marginRight: '3px',
|
marginRight: '3px',
|
||||||
backgroundColor: 'var(--w-e-textarea-slight-bg-color)',
|
backgroundColor: 'var(--w-e-textarea-slight-bg-color)',
|
||||||
borderRadius: '3px',
|
borderRadius: '3px',
|
||||||
padding: '0 3px',
|
padding: '0 3px'
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
`节点`
|
`节点`
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
h('td', [h(
|
h('td', [
|
||||||
|
h(
|
||||||
'span',
|
'span',
|
||||||
{
|
{
|
||||||
props: {
|
props: {
|
||||||
contentEditable: false,
|
contentEditable: false
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
marginLeft: '3px',
|
marginLeft: '3px',
|
||||||
marginRight: '3px',
|
marginRight: '3px',
|
||||||
backgroundColor: 'var(--w-e-textarea-slight-bg-color)',
|
backgroundColor: 'var(--w-e-textarea-slight-bg-color)',
|
||||||
borderRadius: '3px',
|
borderRadius: '3px',
|
||||||
padding: '0 3px',
|
padding: '0 3px'
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
`操作`
|
`操作`
|
||||||
)
|
)
|
||||||
@ -61,12 +63,11 @@ function renderProcessRecord(elem: SlateElement, children: VNode[] | null, edito
|
|||||||
])
|
])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
return vnode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const conf = {
|
const conf = {
|
||||||
type: 'process-record',
|
type: 'process-record',
|
||||||
renderElem: renderProcessRecord,
|
renderElem: renderProcessRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
export default conf
|
export default conf
|
||||||
|
|||||||
@ -12,7 +12,7 @@ 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 open = async (id) => {
|
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)
|
||||||
@ -98,6 +98,7 @@ const printObj = ref({
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<!-- TODO @lesan:最下面的 table 央视,可以去掉么? -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
/>
|
/>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="text-#878c93 h-15px">编号:{{ id }}</div>
|
<div class="text-#878c93 h-15px">编号:{{ id }}</div>
|
||||||
<Icon icon="ep:printer" class="ml-15px cursor-pointer" @click="handlePrint"/>
|
<Icon icon="ep:printer" class="ml-15px cursor-pointer" @click="handlePrint" />
|
||||||
</div>
|
</div>
|
||||||
<el-divider class="!my-8px" />
|
<el-divider class="!my-8px" />
|
||||||
<div class="flex items-center gap-5 mb-10px h-40px">
|
<div class="flex items-center gap-5 mb-10px h-40px">
|
||||||
@ -128,6 +128,8 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 打印预览弹窗 -->
|
||||||
<PrintDialog ref="printRef" />
|
<PrintDialog ref="printRef" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -192,6 +194,7 @@ const getDetail = () => {
|
|||||||
/** 加载流程实例 */
|
/** 加载流程实例 */
|
||||||
const BusinessFormComponent = ref<any>(null) // 异步组件
|
const BusinessFormComponent = ref<any>(null) // 异步组件
|
||||||
/** 获取审批详情 */
|
/** 获取审批详情 */
|
||||||
|
const activityNodes = ref<ProcessInstanceApi.ApprovalNodeInfo[]>([]) // 审批节点信息
|
||||||
const getApprovalDetail = async () => {
|
const getApprovalDetail = async () => {
|
||||||
processInstanceLoading.value = true
|
processInstanceLoading.value = true
|
||||||
try {
|
try {
|
||||||
@ -270,11 +273,7 @@ const getProcessModelView = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 审批节点信息
|
/** 设置表单权限 */
|
||||||
const activityNodes = ref<ProcessInstanceApi.ApprovalNodeInfo[]>([])
|
|
||||||
/**
|
|
||||||
* 设置表单权限
|
|
||||||
*/
|
|
||||||
const setFieldPermission = (field: string, permission: string) => {
|
const setFieldPermission = (field: string, permission: string) => {
|
||||||
if (permission === FieldPermissionType.READ) {
|
if (permission === FieldPermissionType.READ) {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
@ -292,20 +291,19 @@ const setFieldPermission = (field: string, permission: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 操作成功后刷新 */
|
||||||
* 操作成功后刷新
|
|
||||||
*/
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
// 重新获取详情
|
// 重新获取详情
|
||||||
getDetail()
|
getDetail()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 处理打印 */
|
||||||
const printRef = ref()
|
const printRef = ref()
|
||||||
const handlePrint = async () => {
|
const handlePrint = async () => {
|
||||||
printRef.value.open(props.id)
|
printRef.value.open(props.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 当前的Tab */
|
/** 当前的 Tab */
|
||||||
const activeTab = ref('form')
|
const activeTab = ref('form')
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
|
|||||||
Reference in New Issue
Block a user