!264 Merge remote-tracking branch 'yudao/dev' into dev
Merge pull request !264 from Jason/dev
This commit is contained in:
@@ -9,5 +9,3 @@ export { default as MyProcessDesigner } from './designer';
|
|||||||
// TODO @puhui999:流程发起时,预览相关的,需要使用;
|
// TODO @puhui999:流程发起时,预览相关的,需要使用;
|
||||||
export { default as MyProcessViewer } from './designer/index2';
|
export { default as MyProcessViewer } from './designer/index2';
|
||||||
export { default as MyProcessPenal } from './penal';
|
export { default as MyProcessPenal } from './penal';
|
||||||
|
|
||||||
// TODO @jason:【有个迁移的打印】【新增】流程打印,由 [@Lesan](https://gitee.com/LesanOuO) 贡献 [#816](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/816/)、[#1418](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1418/)、[#817](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/817/)、[#1419](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1419/)、[#1424](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1424)、[#819](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/819)、[#821](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/821/)
|
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { MentionItem } from '../modules/tinymce-plugin';
|
||||||
|
|
||||||
|
import { computed, onBeforeUnmount, ref, shallowRef } from 'vue';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
// @ts-ignore - tinymce vue 声明文件按项目依赖提供
|
||||||
|
import Editor from '@tinymce/tinymce-vue';
|
||||||
|
|
||||||
|
import { setupTinyPlugins } from './tinymce-plugin';
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
formFields?: Array<{ field: string; title: string }>;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
formFields: () => [],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
/** TinyMCE 自托管:https://www.jianshu.com/p/59a9c3802443 */
|
||||||
|
const tinymceScriptSrc = `${import.meta.env.VITE_BASE}tinymce/tinymce.min.js`;
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
closable: true,
|
||||||
|
footer: false,
|
||||||
|
title: '自定义模板',
|
||||||
|
async onOpenChange(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modalApi.lock();
|
||||||
|
try {
|
||||||
|
const { template } = modalApi.getData<{
|
||||||
|
template: string;
|
||||||
|
}>();
|
||||||
|
if (template !== undefined) {
|
||||||
|
valueHtml.value = template;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
modalApi.unlock();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
/** 通过 setData 传递确认的数据,在父组件的 onConfirm 中获取 */
|
||||||
|
modalApi.setData({ confirmedTemplate: valueHtml.value as string });
|
||||||
|
modalApi.onConfirm();
|
||||||
|
modalApi.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提供给 @ 自动补全的字段(默认 + 表单字段)
|
||||||
|
const mentionList = computed<MentionItem[]>(() => {
|
||||||
|
const base: MentionItem[] = [
|
||||||
|
{ id: 'startUser', name: '发起人' },
|
||||||
|
{ id: 'startUserDept', name: '发起人部门' },
|
||||||
|
{ id: 'processName', name: '流程名称' },
|
||||||
|
{ id: 'processNum', name: '流程编号' },
|
||||||
|
{ id: 'startTime', name: '发起时间' },
|
||||||
|
{ id: 'endTime', name: '结束时间' },
|
||||||
|
{ id: 'processStatus', name: '流程状态' },
|
||||||
|
{ id: 'printUser', name: '打印人' },
|
||||||
|
{ id: 'printTime', name: '打印时间' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const extras: MentionItem[] = (props.formFields || []).map((it: any) => ({
|
||||||
|
id: it.field,
|
||||||
|
name: `[表单]${it.title}`,
|
||||||
|
}));
|
||||||
|
return [...base, ...extras];
|
||||||
|
});
|
||||||
|
|
||||||
|
// 编辑器
|
||||||
|
const valueHtml = ref<string>('');
|
||||||
|
const editorRef = shallowRef<any>();
|
||||||
|
|
||||||
|
const tinyInit = {
|
||||||
|
height: 400,
|
||||||
|
width: 'auto',
|
||||||
|
menubar: false,
|
||||||
|
plugins: 'link importcss table code preview autoresize lists ',
|
||||||
|
toolbar:
|
||||||
|
'undo redo | styles fontsize | bold italic underline | alignleft aligncenter alignright | link table | processrecord code preview',
|
||||||
|
language: 'zh_CN',
|
||||||
|
branding: false,
|
||||||
|
statusbar: true,
|
||||||
|
content_style:
|
||||||
|
'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
|
||||||
|
setup(editor: any) {
|
||||||
|
editorRef.value = editor;
|
||||||
|
// 在编辑器 setup 时注册自定义插件
|
||||||
|
setupTinyPlugins(editor, () => mentionList.value);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (editorRef.value) {
|
||||||
|
editorRef.value.destroy?.();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal class="w-3/4">
|
||||||
|
<div class="mb-3">
|
||||||
|
<a-alert
|
||||||
|
message="输入 @ 可选择插入流程选项和表单选项"
|
||||||
|
type="info"
|
||||||
|
show-icon
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Editor
|
||||||
|
v-model="valueHtml"
|
||||||
|
:init="tinyInit"
|
||||||
|
:tinymce-script-src="tinymceScriptSrc"
|
||||||
|
license-key="gpl"
|
||||||
|
/>
|
||||||
|
<template #footer>
|
||||||
|
<div class="flex justify-end gap-2">
|
||||||
|
<a-button @click="modalApi.onCancel()">取 消</a-button>
|
||||||
|
<a-button type="primary" @click="handleConfirm">确 定</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, provide, ref, watch } from 'vue';
|
import { computed, provide, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import {
|
import {
|
||||||
BpmAutoApproveType,
|
BpmAutoApproveType,
|
||||||
BpmModelFormType,
|
BpmModelFormType,
|
||||||
@@ -9,6 +10,7 @@ import {
|
|||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Col,
|
Col,
|
||||||
Form,
|
Form,
|
||||||
@@ -32,6 +34,8 @@ import {
|
|||||||
parseFormFields,
|
parseFormFields,
|
||||||
} from '#/views/bpm/components/simple-process-design';
|
} from '#/views/bpm/components/simple-process-design';
|
||||||
|
|
||||||
|
import PrintTemplate from './custom-print-template.vue';
|
||||||
|
|
||||||
const modelData = defineModel<any>();
|
const modelData = defineModel<any>();
|
||||||
|
|
||||||
/** 自定义 ID 流程编码 */
|
/** 自定义 ID 流程编码 */
|
||||||
@@ -147,9 +151,9 @@ function handleTaskAfterTriggerEnableChange(val: boolean | number | string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 表单字段 */
|
/** 表单字段 */
|
||||||
const formField = ref<Array<{ field: string; title: string }>>([]);
|
const formFields = ref<Array<{ field: string; title: string }>>([]);
|
||||||
const formFieldOptions4Title = computed(() => {
|
const formFieldOptions4Title = computed(() => {
|
||||||
const cloneFormField = formField.value.map((item) => {
|
const cloneFormField = formFields.value.map((item) => {
|
||||||
return {
|
return {
|
||||||
label: item.title,
|
label: item.title,
|
||||||
value: item.field,
|
value: item.field,
|
||||||
@@ -171,7 +175,7 @@ const formFieldOptions4Title = computed(() => {
|
|||||||
return cloneFormField;
|
return cloneFormField;
|
||||||
});
|
});
|
||||||
const formFieldOptions4Summary = computed(() => {
|
const formFieldOptions4Summary = computed(() => {
|
||||||
return formField.value.map((item) => {
|
return formFields.value.map((item) => {
|
||||||
return {
|
return {
|
||||||
label: item.title,
|
label: item.title,
|
||||||
value: item.field,
|
value: item.field,
|
||||||
@@ -192,6 +196,12 @@ function initData() {
|
|||||||
length: 5,
|
length: 5,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (!modelData.value.printTemplateSetting) {
|
||||||
|
modelData.value.printTemplateSetting = {
|
||||||
|
enable: false,
|
||||||
|
template: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
if (!modelData.value.autoApprovalType) {
|
if (!modelData.value.autoApprovalType) {
|
||||||
modelData.value.autoApprovalType = BpmAutoApproveType.NONE;
|
modelData.value.autoApprovalType = BpmAutoApproveType.NONE;
|
||||||
}
|
}
|
||||||
@@ -237,9 +247,9 @@ watch(
|
|||||||
parseFormFields(JSON.parse(fieldStr), result);
|
parseFormFields(JSON.parse(fieldStr), result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
formField.value = result;
|
formFields.value = result;
|
||||||
} else {
|
} else {
|
||||||
formField.value = [];
|
formFields.value = [];
|
||||||
unParsedFormFields.value = [];
|
unParsedFormFields.value = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -252,6 +262,86 @@ async function validate() {
|
|||||||
await formRef.value?.validate();
|
await formRef.value?.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 自定义打印模板模态框 */
|
||||||
|
const [PrintTemplateModal, printTemplateModalApi] = useVbenModal({
|
||||||
|
connectedComponent: PrintTemplate,
|
||||||
|
destroyOnClose: true,
|
||||||
|
onConfirm() {
|
||||||
|
// 会在内部模态框中设置数据,这里获取数据, 内部模态框中不能有 onConfirm 方法
|
||||||
|
const { confirmedTemplate } = printTemplateModalApi.getData<{
|
||||||
|
confirmedTemplate: string;
|
||||||
|
}>();
|
||||||
|
if (confirmedTemplate !== undefined) {
|
||||||
|
modelData.value.printTemplateSetting.template = confirmedTemplate;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 弹出自定义打印模板弹窗 */
|
||||||
|
const openPrintTemplateModal = () => {
|
||||||
|
printTemplateModalApi
|
||||||
|
.setData({ template: modelData.value.printTemplateSetting.template })
|
||||||
|
.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 默认的打印模板, 目前自定义模板没有引入自定义样式。 看后续是否需要 */
|
||||||
|
const defaultTemplate = `<p style="text-align: center;font-size: 1.25rem;"><strong><span data-w-e-type="mention" data-value="流程名称" data-info="%7B%22id%22%3A%22processName%22%7D">@流程名称</span></strong></p>
|
||||||
|
<p style="text-align: right;">打印人员:<span data-w-e-type="mention" data-info="%7B%22id%22%3A%22printUser%22%7D">@打印人</span></p>
|
||||||
|
<p style="text-align: left;">流程编号:<span data-w-e-type="mention" data-value="流程编号" data-info="%7B%22id%22%3A%22processNum%22%7D">@流程编号</span></p>
|
||||||
|
<p> </p>
|
||||||
|
<table style="width: 100%; height: 72.2159px;">
|
||||||
|
<tbody>
|
||||||
|
<tr style="height: 36.108px;">
|
||||||
|
<td style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">发起人</td>
|
||||||
|
<td style="width: 30.5551%; border: 1px solid;" colspan="1" rowspan="1" width="auto"><span data-w-e-type="mention" data-value="发起人" data-info="%7B%22id%22%3A%22startUser%22%7D">@发起人</span></td>
|
||||||
|
<td style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">发起时间</td>
|
||||||
|
<td style="width: 26.0284%; border: 1px solid;" colspan="1" rowspan="1" width="auto"><span data-w-e-type="mention" data-value="发起时间" data-info="%7B%22id%22%3A%22startTime%22%7D">@发起时间</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr style="height: 36.108px;">
|
||||||
|
<td style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">所属部门</td>
|
||||||
|
<td style="width: 30.5551%; border: 1px solid;" 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 style="width: 21.7532%; border: 1px solid;" colspan="1" rowspan="1" width="auto">流程状态</td>
|
||||||
|
<td style="width: 26.0284%; border: 1px solid;" colspan="1" rowspan="1" width="auto"><span data-w-e-type="mention" data-value="流程状态" data-info="%7B%22id%22%3A%22processStatus%22%7D">@流程状态</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p> </p>
|
||||||
|
<div contenteditable="false" data-w-e-type="process-record" data-w-e-is-void="">
|
||||||
|
<table class="process-record-table" style="width: 100%; border-collapse: collapse; border: 1px solid;">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 100%; border: 1px solid; text-align: center;" colspan="2">流程记录</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 25%; border: 1px solid;">节点</td>
|
||||||
|
<td style="width: 75%; border: 1px solid;">操作</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<p> </p>`;
|
||||||
|
|
||||||
|
const handlePrintTemplateEnableChange = (checked: any) => {
|
||||||
|
const val = !!checked;
|
||||||
|
if (val && !modelData.value.printTemplateSetting.template) {
|
||||||
|
modelData.value.printTemplateSetting.template = defaultTemplate;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义打印模板开关
|
||||||
|
const printTemplateEnable = computed<boolean>({
|
||||||
|
get() {
|
||||||
|
return !!modelData.value?.printTemplateSetting?.enable;
|
||||||
|
},
|
||||||
|
set(val: boolean) {
|
||||||
|
if (!modelData.value.printTemplateSetting) {
|
||||||
|
modelData.value.printTemplateSetting = {
|
||||||
|
enable: false,
|
||||||
|
template: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
modelData.value.printTemplateSetting.enable = !!val;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
defineExpose({ initData, validate });
|
defineExpose({ initData, validate });
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
@@ -515,6 +605,27 @@ defineExpose({ initData, validate });
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<!-- TODO @jason:这里有个 “自定义打印模板” -->
|
<FormItem class="mb-5" label="自定义打印模板">
|
||||||
|
<div class="flex w-full flex-col">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<Switch
|
||||||
|
v-model:checked="printTemplateEnable"
|
||||||
|
@change="handlePrintTemplateEnableChange"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
v-if="printTemplateEnable"
|
||||||
|
class="ml-2 flex items-center"
|
||||||
|
type="link"
|
||||||
|
@click="openPrintTemplateModal"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<IconifyIcon icon="lucide:pencil" />
|
||||||
|
</template>
|
||||||
|
编辑模板
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</FormItem>
|
||||||
|
<PrintTemplateModal :form-fields="formFields" />
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/** TinyMCE 自定义功能:
|
||||||
|
* - processrecord 按钮:插入流程记录占位元素
|
||||||
|
* - @ 自动补全:插入 mention 占位元素
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @ts-ignore TinyMCE 全局或通过打包器提供
|
||||||
|
import type { Editor } from 'tinymce';
|
||||||
|
|
||||||
|
export interface MentionItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 在编辑器 setup 回调中注册流程记录按钮和 @ 自动补全 */
|
||||||
|
export function setupTinyPlugins(
|
||||||
|
editor: Editor,
|
||||||
|
getMentionList: () => MentionItem[],
|
||||||
|
) {
|
||||||
|
// 按钮:流程记录
|
||||||
|
editor.ui.registry.addButton('processrecord', {
|
||||||
|
text: '流程记录',
|
||||||
|
tooltip: '插入流程记录占位',
|
||||||
|
onAction: () => {
|
||||||
|
// 流程记录占位显示, 仅用于显示。process-print.vue 组件中会替换掉
|
||||||
|
editor.insertContent(
|
||||||
|
[
|
||||||
|
'<div data-w-e-type="process-record" data-w-e-is-void contenteditable="false">',
|
||||||
|
'<table class="process-record-table" style="width: 100%; border-collapse: collapse; border: 1px solid;">',
|
||||||
|
'<tr><td style="width: 100%; border: 1px solid; text-align: center;" colspan="2">流程记录</td></tr>',
|
||||||
|
'<tr>',
|
||||||
|
'<td style="width: 25%; border: 1px solid;">节点</td>',
|
||||||
|
'<td style="width: 75%; border: 1px solid;">操作</td>',
|
||||||
|
'</tr>',
|
||||||
|
'</table>',
|
||||||
|
'</div>',
|
||||||
|
].join(''),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ 自动补全
|
||||||
|
editor.ui.registry.addAutocompleter('bpmMention', {
|
||||||
|
trigger: '@',
|
||||||
|
minChars: 0,
|
||||||
|
columns: 1,
|
||||||
|
fetch: (
|
||||||
|
pattern: string,
|
||||||
|
_maxResults: number,
|
||||||
|
_fetchOptions: Record<string, any>,
|
||||||
|
) => {
|
||||||
|
const list = getMentionList();
|
||||||
|
const keyword = (pattern || '').toLowerCase().trim();
|
||||||
|
const data = list
|
||||||
|
.filter((i) => i.name.toLowerCase().includes(keyword))
|
||||||
|
.map((i) => ({
|
||||||
|
value: i.id,
|
||||||
|
text: i.name,
|
||||||
|
}));
|
||||||
|
return Promise.resolve(data);
|
||||||
|
},
|
||||||
|
onAction: (
|
||||||
|
autocompleteApi: any,
|
||||||
|
rng: Range,
|
||||||
|
value: string,
|
||||||
|
_meta: Record<string, any>,
|
||||||
|
) => {
|
||||||
|
const list = getMentionList();
|
||||||
|
const item = list.find((i) => i.id === value);
|
||||||
|
const name = item ? item.name : value;
|
||||||
|
const info = encodeURIComponent(JSON.stringify({ id: value }));
|
||||||
|
editor.selection.setRng(rng);
|
||||||
|
editor.insertContent(
|
||||||
|
`<span data-w-e-type="mention" data-info="${info}">@${name}</span>`,
|
||||||
|
);
|
||||||
|
autocompleteApi.hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ import { registerComponent } from '#/utils';
|
|||||||
|
|
||||||
import ProcessInstanceBpmnViewer from './modules/bpm-viewer.vue';
|
import ProcessInstanceBpmnViewer from './modules/bpm-viewer.vue';
|
||||||
import ProcessInstanceOperationButton from './modules/operation-button.vue';
|
import ProcessInstanceOperationButton from './modules/operation-button.vue';
|
||||||
import ProcessssPrint from './modules/processs-print.vue';
|
import ProcessssPrint from './modules/process-print.vue';
|
||||||
import ProcessInstanceSimpleViewer from './modules/simple-bpm-viewer.vue';
|
import ProcessInstanceSimpleViewer from './modules/simple-bpm-viewer.vue';
|
||||||
import BpmProcessInstanceTaskList from './modules/task-list.vue';
|
import BpmProcessInstanceTaskList from './modules/task-list.vue';
|
||||||
import ProcessInstanceTimeline from './modules/time-line.vue';
|
import ProcessInstanceTimeline from './modules/time-line.vue';
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ function initPrintDataMap() {
|
|||||||
printDataMap.value.printTime = printTime.value;
|
printDataMap.value.printTime = printTime.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取打印模板 HTML (TODO 需求实现配置打印模板) */
|
/** 获取打印模板 HTML */
|
||||||
function getPrintTemplateHTML() {
|
function getPrintTemplateHTML() {
|
||||||
if (!printData.value?.printTemplateHtml) return '';
|
if (!printData.value?.printTemplateHtml) return '';
|
||||||
|
|
||||||
@@ -153,16 +153,6 @@ function getPrintTemplateHTML() {
|
|||||||
'text/html',
|
'text/html',
|
||||||
);
|
);
|
||||||
|
|
||||||
// table 添加 border
|
|
||||||
const tables = doc.querySelectorAll('table');
|
|
||||||
tables.forEach((item) => {
|
|
||||||
item.setAttribute('border', '1');
|
|
||||||
item.setAttribute(
|
|
||||||
'style',
|
|
||||||
`${item.getAttribute('style') || ''}border-collapse:collapse;`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 替换 mentions
|
// 替换 mentions
|
||||||
const mentions = doc.querySelectorAll('[data-w-e-type="mention"]');
|
const mentions = doc.querySelectorAll('[data-w-e-type="mention"]');
|
||||||
mentions.forEach((item) => {
|
mentions.forEach((item) => {
|
||||||
@@ -181,26 +171,23 @@ function getPrintTemplateHTML() {
|
|||||||
|
|
||||||
if (processRecords.length > 0) {
|
if (processRecords.length > 0) {
|
||||||
// 构建流程记录 html
|
// 构建流程记录 html
|
||||||
processRecordTable.setAttribute('border', '1');
|
processRecordTable.setAttribute('class', 'w-full border-collapse');
|
||||||
processRecordTable.setAttribute(
|
|
||||||
'style',
|
|
||||||
'width:100%;border-collapse:collapse;',
|
|
||||||
);
|
|
||||||
|
|
||||||
const headTr = document.createElement('tr');
|
const headTr = document.createElement('tr');
|
||||||
const headTd = document.createElement('td');
|
const headTd = document.createElement('td');
|
||||||
headTd.setAttribute('colspan', '2');
|
headTd.setAttribute('colspan', '2');
|
||||||
headTd.setAttribute('width', 'auto');
|
headTd.setAttribute('class', 'border border-black p-1.5 text-center');
|
||||||
headTd.setAttribute('style', 'text-align: center;');
|
headTd.innerHTML = '流程记录';
|
||||||
headTd.innerHTML = '流程节点';
|
|
||||||
headTr.append(headTd);
|
headTr.append(headTd);
|
||||||
processRecordTable.append(headTr);
|
processRecordTable.append(headTr);
|
||||||
|
|
||||||
printData.value?.tasks.forEach((item) => {
|
printData.value?.tasks.forEach((item) => {
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
const td1 = document.createElement('td');
|
const td1 = document.createElement('td');
|
||||||
|
td1.setAttribute('class', 'border border-black p-1.5');
|
||||||
td1.innerHTML = item.name;
|
td1.innerHTML = item.name;
|
||||||
const td2 = document.createElement('td');
|
const td2 = document.createElement('td');
|
||||||
|
td2.setAttribute('class', 'border border-black p-1.5');
|
||||||
td2.innerHTML = item.description;
|
td2.innerHTML = item.description;
|
||||||
tr.append(td1);
|
tr.append(td1);
|
||||||
tr.append(td2);
|
tr.append(td2);
|
||||||
@@ -229,35 +216,34 @@ function getPrintTemplateHTML() {
|
|||||||
<h2 class="mb-3 text-center text-xl font-bold">
|
<h2 class="mb-3 text-center text-xl font-bold">
|
||||||
{{ printData.processInstance.name }}
|
{{ printData.processInstance.name }}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="mb-2 text-right text-sm">
|
|
||||||
{{ `打印人员: ${userName}` }}
|
|
||||||
</div>
|
|
||||||
<div class="mb-2 flex justify-between text-sm">
|
<div class="mb-2 flex justify-between text-sm">
|
||||||
<div>
|
<div>
|
||||||
{{ `流程编号: ${printData.processInstance.id}` }}
|
{{ `流程编号: ${printData.processInstance.id}` }}
|
||||||
</div>
|
</div>
|
||||||
<div>{{ `打印时间: ${printTime}` }}</div>
|
<div>
|
||||||
|
{{ `打印人员: ${userName}` }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="mt-3 w-full border-collapse border border-gray-400">
|
<table class="mt-3 w-full border-collapse">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">发起人</td>
|
<td class="w-1/4 border border-black p-1.5">发起人</td>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">
|
<td class="w-1/4 border border-black p-1.5">
|
||||||
{{ printData.processInstance.startUser?.nickname }}
|
{{ printData.processInstance.startUser?.nickname }}
|
||||||
</td>
|
</td>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">发起时间</td>
|
<td class="w-1/4 border border-black p-1.5">发起时间</td>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">
|
<td class="w-1/4 border border-black p-1.5">
|
||||||
<!-- TODO @jason:这里会告警呢 -->
|
<!-- TODO @jason:这里会告警呢 TODO @芋艿 我这边不会有警告呀 -->
|
||||||
{{ formatDate(printData.processInstance.startTime) }}
|
{{ formatDate(printData.processInstance.startTime) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">所属部门</td>
|
<td class="w-1/4 border border-black p-1.5">所属部门</td>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">
|
<td class="w-1/4 border border-black p-1.5">
|
||||||
{{ printData.processInstance.startUser?.deptName }}
|
{{ printData.processInstance.startUser?.deptName }}
|
||||||
</td>
|
</td>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">流程状态</td>
|
<td class="w-1/4 border border-black p-1.5">流程状态</td>
|
||||||
<td class="w-1/4 border border-gray-400 p-1.5">
|
<td class="w-1/4 border border-black p-1.5">
|
||||||
{{
|
{{
|
||||||
getDictLabel(
|
getDictLabel(
|
||||||
DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS,
|
DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS,
|
||||||
@@ -268,33 +254,33 @@ function getPrintTemplateHTML() {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
class="w-full border border-gray-400 p-1.5 text-center"
|
class="w-full border border-black p-1.5 text-center"
|
||||||
colspan="4"
|
colspan="4"
|
||||||
>
|
>
|
||||||
<h4>表单内容</h4>
|
<h4>表单内容</h4>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-for="item in formFields" :key="item.id">
|
<tr v-for="item in formFields" :key="item.id">
|
||||||
<td class="w-1/5 border border-gray-400 p-1.5">
|
<td class="w-1/5 border border-black p-1.5">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</td>
|
</td>
|
||||||
<td class="w-4/5 border border-gray-400 p-1.5" colspan="3">
|
<td class="w-4/5 border border-black p-1.5" colspan="3">
|
||||||
<div v-html="item.html"></div>
|
<div v-html="item.html"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
class="w-full border border-gray-400 p-1.5 text-center"
|
class="w-full border border-black p-1.5 text-center"
|
||||||
colspan="4"
|
colspan="4"
|
||||||
>
|
>
|
||||||
<h4>流程节点</h4>
|
<h4>流程记录</h4>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-for="item in printData.tasks" :key="item.id">
|
<tr v-for="item in printData.tasks" :key="item.id">
|
||||||
<td class="w-1/5 border border-gray-400 p-1.5">
|
<td class="w-1/5 border border-black p-1.5">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</td>
|
</td>
|
||||||
<td class="w-4/5 border border-gray-400 p-1.5" colspan="3">
|
<td class="w-4/5 border border-black p-1.5" colspan="3">
|
||||||
{{ item.description }}
|
{{ item.description }}
|
||||||
<div v-if="item.signPicUrl && item.signPicUrl.length > 0">
|
<div v-if="item.signPicUrl && item.signPicUrl.length > 0">
|
||||||
<img class="h-10 w-[90px]" :src="item.signPicUrl" alt="" />
|
<img class="h-10 w-[90px]" :src="item.signPicUrl" alt="" />
|
||||||
Reference in New Issue
Block a user