diff --git a/apps/web-antd/src/views/bpm/model/form/modules/custom-print-template.vue b/apps/web-antd/src/views/bpm/model/form/modules/custom-print-template.vue new file mode 100644 index 000000000..d4b26c391 --- /dev/null +++ b/apps/web-antd/src/views/bpm/model/form/modules/custom-print-template.vue @@ -0,0 +1,127 @@ + + + diff --git a/apps/web-antd/src/views/bpm/model/form/modules/extra-setting.vue b/apps/web-antd/src/views/bpm/model/form/modules/extra-setting.vue index 1e64b37c7..af3d6bfa9 100644 --- a/apps/web-antd/src/views/bpm/model/form/modules/extra-setting.vue +++ b/apps/web-antd/src/views/bpm/model/form/modules/extra-setting.vue @@ -1,6 +1,7 @@ diff --git a/apps/web-antd/src/views/bpm/model/form/modules/tinymce-plugin.ts b/apps/web-antd/src/views/bpm/model/form/modules/tinymce-plugin.ts new file mode 100644 index 000000000..145dc894b --- /dev/null +++ b/apps/web-antd/src/views/bpm/model/form/modules/tinymce-plugin.ts @@ -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( + [ + '
', + '', + '', + '', + '', + '', + '', + '
流程记录
节点操作
', + '
', + ].join(''), + ); + }, + }); + + // @ 自动补全 + editor.ui.registry.addAutocompleter('bpmMention', { + trigger: '@', + minChars: 0, + columns: 1, + fetch: ( + pattern: string, + _maxResults: number, + _fetchOptions: Record, + ) => { + 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, + ) => { + 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( + `@${name}`, + ); + autocompleteApi.hide(); + }, + }); +} diff --git a/apps/web-antd/src/views/bpm/processInstance/detail/index.vue b/apps/web-antd/src/views/bpm/processInstance/detail/index.vue index 6c0c1b47e..064c45858 100644 --- a/apps/web-antd/src/views/bpm/processInstance/detail/index.vue +++ b/apps/web-antd/src/views/bpm/processInstance/detail/index.vue @@ -34,7 +34,7 @@ import { registerComponent } from '#/utils'; import ProcessInstanceBpmnViewer from './modules/bpm-viewer.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 BpmProcessInstanceTaskList from './modules/task-list.vue'; import ProcessInstanceTimeline from './modules/time-line.vue'; diff --git a/apps/web-antd/src/views/bpm/processInstance/detail/modules/processs-print.vue b/apps/web-antd/src/views/bpm/processInstance/detail/modules/process-print.vue similarity index 80% rename from apps/web-antd/src/views/bpm/processInstance/detail/modules/processs-print.vue rename to apps/web-antd/src/views/bpm/processInstance/detail/modules/process-print.vue index e4e87e14e..504db968a 100644 --- a/apps/web-antd/src/views/bpm/processInstance/detail/modules/processs-print.vue +++ b/apps/web-antd/src/views/bpm/processInstance/detail/modules/process-print.vue @@ -143,7 +143,7 @@ function initPrintDataMap() { printDataMap.value.printTime = printTime.value; } -/** 获取打印模板 HTML (TODO 需求实现配置打印模板) */ +/** 获取打印模板 HTML */ function getPrintTemplateHTML() { if (!printData.value?.printTemplateHtml) return ''; @@ -153,16 +153,6 @@ function getPrintTemplateHTML() { '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 const mentions = doc.querySelectorAll('[data-w-e-type="mention"]'); mentions.forEach((item) => { @@ -181,26 +171,23 @@ function getPrintTemplateHTML() { if (processRecords.length > 0) { // 构建流程记录 html - processRecordTable.setAttribute('border', '1'); - processRecordTable.setAttribute( - 'style', - 'width:100%;border-collapse:collapse;', - ); + processRecordTable.setAttribute('class', 'w-full border-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 = '流程节点'; + headTd.setAttribute('class', 'border border-black p-1.5 text-center'); + headTd.innerHTML = '流程记录'; headTr.append(headTd); processRecordTable.append(headTr); printData.value?.tasks.forEach((item) => { const tr = document.createElement('tr'); const td1 = document.createElement('td'); + td1.setAttribute('class', 'border border-black p-1.5'); td1.innerHTML = item.name; const td2 = document.createElement('td'); + td2.setAttribute('class', 'border border-black p-1.5'); td2.innerHTML = item.description; tr.append(td1); tr.append(td2); @@ -229,35 +216,34 @@ function getPrintTemplateHTML() {

{{ printData.processInstance.name }}

-
- {{ `打印人员: ${userName}` }} -
{{ `流程编号: ${printData.processInstance.id}` }}
-
{{ `打印时间: ${printTime}` }}
+
+ {{ `打印人员: ${userName}` }} +
- +
- - + - - + - - + - - + - - - -
发起人 + 发起人 {{ printData.processInstance.startUser?.nickname }} 发起时间 - + 发起时间 + {{ formatDate(printData.processInstance.startTime) }}
所属部门 + 所属部门 {{ printData.processInstance.startUser?.deptName }} 流程状态 + 流程状态 {{ getDictLabel( DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, @@ -268,33 +254,33 @@ function getPrintTemplateHTML() {

表单内容

+ {{ item.name }} +
-

流程节点

+

流程记录

+ {{ item.name }} + {{ item.description }}