feat(signing): 签署任务固化文书 HTML 并交互化渲染

This commit is contained in:
yelan
2026-09-14 09:13:07 +08:00
parent 1b576c6095
commit 545326bd81
10 changed files with 328 additions and 116 deletions
@@ -1,82 +0,0 @@
<script setup lang="ts">
import { shallowRef } from 'vue'
// 副作用导入:注册全局 window.tinymce(@tinymce/tinymce-vue 会检测全局实例,从而走本地包而非 CDN)。
import 'tinymce/tinymce'
import 'tinymce/themes/silver'
import 'tinymce/icons/default/icons'
import 'tinymce/models/dom'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/table'
import 'tinymce/skins/ui/oxide/skin.min.css'
import TinyEditor from '@tinymce/tinymce-vue'
// TinyMCE 8(GPL 开源模式需声明 license_key: 'gpl')。
// skin: false / content_css: false —— 皮肤样式由打包引入,iframe 内容样式用 content_style 内联。
const editorRef = shallowRef<TinyMceApi | null>(null)
interface TinyMceApi {
getContent: (options?: { format?: string }) => string
setContent: (content: string) => void
insertContent: (content: string) => void
}
const props = defineProps<{
modelValue: string
}>()
const emit = defineEmits<{
'update:modelValue': [value: string]
}>()
const init = {
license_key: 'gpl',
menubar: false,
placeholder: '将 Word / WPS 中的文书内容直接粘贴到此处(保留表格与基本格式)。',
// TinyMCE 8:paste 已并入核心,不能再声明(声明会导致插件加载失败)。
plugins: 'lists table',
toolbar:
'undo redo | bold italic underline | alignleft aligncenter alignright alignjustify | fontsizeselect forecolor backcolor | bullist numlist | table',
skin: false,
content_css: false,
content_style: `
body { font-family: 'SimSun', 'Songti SC', serif; font-size: 14px; line-height: 1.8; color: #1c2b33; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #52646e; padding: 5px 7px; }
`,
paste_data_images: true,
height: 460,
// tinymce-vue 不派发 init 事件,编辑器实例只能从这里拿。
init_instance_callback: (editor: TinyMceApi) => {
editorRef.value = editor
},
}
function getText(): string {
return editorRef.value?.getContent({ format: 'text' }).trim() ?? ''
}
function insertText(text: string) {
editorRef.value?.insertContent(text)
}
defineExpose({ getText, insertText })
</script>
<template>
<div class="tiny-pane">
<TinyEditor
:model-value="props.modelValue"
:init="init"
@update:model-value="emit('update:modelValue', $event)"
/>
</div>
</template>
<style scoped>
.tiny-pane {
overflow: hidden;
border: 1px solid var(--line);
border-radius: 8px;
}
</style>