fix(document): 统一编辑器与文书纸的排版和字体口径
This commit is contained in:
@@ -1,11 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import '@wangeditor/editor/dist/css/style.css'
|
||||
/**
|
||||
* 文书编辑器(WangEditor 引擎)。
|
||||
*
|
||||
* **编辑面就是一张「纸」**:编辑器根节点同时挂 `pane-content`(纸壳里的白纸)与
|
||||
* `doc-paper`(utils/document-paper.ts 里那份唯一排版)—— 编辑时看到的段落间距、
|
||||
* 表格内边距、字号字体,与签署预览、签署工作台、导出的 PDF 完全同一份来源。
|
||||
*
|
||||
* 为什么还要绕一层 styles/editor-vendor.css:WangEditor 自带一套权重更高的正文默认
|
||||
* (`p{margin:15px 0}` 等),会把那份排版盖掉。它整包被压进最低优先级的 cascade layer,
|
||||
* 于是 `.doc-paper p` 这类规则不必写 !important 也能生效。细节见那个文件。
|
||||
*/
|
||||
import '@/styles/editor-vendor.css'
|
||||
|
||||
import { onBeforeUnmount, shallowRef } from 'vue'
|
||||
import { onBeforeUnmount, ref, shallowRef } from 'vue'
|
||||
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||
import { DomEditor } from '@wangeditor/editor'
|
||||
import type { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
|
||||
|
||||
import { loadDocumentFont } from '../../../../../../../packages/document-fonts'
|
||||
import { getDefaultDocumentFont } from '@/api/management/document-fonts'
|
||||
import type { SigningFieldDef } from '@/api/workbench/types'
|
||||
import { normalizePastedHtml } from '@/utils/rich-text'
|
||||
import { decorateSigningMarkers, registerSigningEditorMarks } from '@/utils/signing-editor-marks'
|
||||
@@ -40,6 +53,34 @@ const editorRef = shallowRef<IDomEditor>()
|
||||
const editableRef = shallowRef<Element | null>(null)
|
||||
const editorMode = 'default'
|
||||
|
||||
/**
|
||||
* 文书字体(后台「文书字体设置」里配置的默认字体)。
|
||||
*
|
||||
* 加载口径与 DocumentPaper 完全一致:**同一个默认字体**。少了这一道,
|
||||
* 后台配了仿宋/楷体时会出现「编辑器里是微软雅黑、签出来是仿宋」——
|
||||
* 同一份文书两副长相,而且换行位置也会跟着变。
|
||||
*
|
||||
* 用 ref 而不是直接等:字体是网络请求,加载完再挂 .managed-font,
|
||||
* 加载失败就退回全局字体(编辑不受影响,只是字体与签署态不一致)。
|
||||
* 不做「转圈等字体」:编辑器要能立刻编辑,不能因为一个字体把人挡在门外。
|
||||
*/
|
||||
const fontFamily = ref('')
|
||||
|
||||
async function prepareFont() {
|
||||
try {
|
||||
const font = await getDefaultDocumentFont()
|
||||
const family = await loadDocumentFont(font, import.meta.env.VITE_API_BASE_URL || '/api')
|
||||
|
||||
if (family) {
|
||||
fontFamily.value = family
|
||||
}
|
||||
} catch {
|
||||
fontFamily.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
void prepareFont()
|
||||
|
||||
/**
|
||||
* 用户是否真的把光标放进过正文。
|
||||
*
|
||||
@@ -258,11 +299,17 @@ onBeforeUnmount(() => {
|
||||
`.pane-desk` 提供灰底与唯一滚动条;
|
||||
`.pane-sheet` 负责限宽居中 —— % 页边距以**包含块**宽度为基准,
|
||||
限宽必须落在这里,落到纸上就会按更宽的桌面算(页边距偏大);
|
||||
`.pane-content` 才是白纸本身(A4 比例 + 页边距)。 -->
|
||||
`.pane-content` 才是白纸本身(A4 比例 + 页边距)。
|
||||
`doc-paper` 是**唯一那份正文排版**的根类(utils/document-paper.ts):
|
||||
白纸壳与编辑面各自挂一次,段落 / 标题 / 表格 / 字体的口径因此只有一份。
|
||||
WangEditor 自己的 DOM(`.w-e-text-container`、`[data-slate-editor]`)会挂在
|
||||
这层下面,所以那份排版是**继承**进去的,不是另抄一份。 -->
|
||||
<div class="pane-desk">
|
||||
<div class="pane-sheet">
|
||||
<Editor
|
||||
class="pane-content"
|
||||
class="pane-content doc-paper"
|
||||
:class="{ 'managed-font': Boolean(fontFamily) }"
|
||||
:style="{ '--document-font': fontFamily }"
|
||||
:model-value="props.modelValue"
|
||||
:default-config="editorConfig"
|
||||
:mode="editorMode"
|
||||
@@ -328,9 +375,13 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
|
||||
/* 空文档提示绝对定位于纸的内层容器,WangEditor 自带一点偏移(实测右下各偏 ~10/17px),
|
||||
这里拉回版心原点,否则空文档时提示文字不与正文左边界对齐 */
|
||||
这里拉回版心原点,否则空文档时提示文字不与正文左边界对齐。
|
||||
`color: inherit` 同理:WangEditor 在这个容器上写死了自己的正文色(#333),
|
||||
而纸的正文色是 #1c2b33 —— 与字号字体一样,正文色也只该有纸那一份口径。
|
||||
这里用 inherit 透传、不复述颜色值,颜色仍然只有 .doc-paper 一处定义。 */
|
||||
.pane-content :deep(.w-e-text-container) {
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.pane-content :deep(.w-e-text-placeholder) {
|
||||
@@ -342,27 +393,11 @@ onBeforeUnmount(() => {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 粘贴的 Word 表格:解除绝对列宽、允许单元格换行,
|
||||
超出容器时横向滚动而不是被裁切 */
|
||||
.pane-content :deep(table) {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: auto;
|
||||
}
|
||||
|
||||
.pane-content :deep(th),
|
||||
.pane-content :deep(td) {
|
||||
padding: 4px 6px;
|
||||
vertical-align: top;
|
||||
border: 1px solid #52646e;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.pane-content :deep(th p),
|
||||
.pane-content :deep(td p) {
|
||||
margin: 0;
|
||||
}
|
||||
/* 表格(width / border-collapse / table-layout / 边框色 / 单元格内边距 / 换行策略)
|
||||
不再在这里写第二份 —— 编辑面挂着 doc-paper,吃的是 utils/document-paper.ts 里
|
||||
唯一那一份。这里曾经各写一套(4px 6px / vertical-align: top),
|
||||
结果「编辑时看到的表格」与「预览、签署时看到的表格」不是同一张。
|
||||
粘进来的 Word 表格的绝对列宽由 utils/rich-text.ts 的 normalizePastedHtml 解除。 */
|
||||
|
||||
/* ---- 占位符 / 勾选框胶囊 ----
|
||||
配色与形状照原型 V10.2 的 .docfld(见 styles/signing-document.css 里签署态的同一套色):
|
||||
|
||||
Reference in New Issue
Block a user