feat: add title element
This commit is contained in:
+15
@@ -111,6 +111,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="menu-divider"></div>
|
<div class="menu-divider"></div>
|
||||||
<div class="menu-item">
|
<div class="menu-item">
|
||||||
|
<div class="menu-item__title">
|
||||||
|
<i></i>
|
||||||
|
<span class="select" title="切换标题">正文</span>
|
||||||
|
<div class="options">
|
||||||
|
<ul>
|
||||||
|
<li style="font-size:16px;">正文</li>
|
||||||
|
<li data-level="first" style="font-size:26px;">标题1</li>
|
||||||
|
<li data-level="second" style="font-size:24px;">标题2</li>
|
||||||
|
<li data-level="third" style="font-size:22px;">标题3</li>
|
||||||
|
<li data-level="fourth" style="font-size:20px;">标题4</li>
|
||||||
|
<li data-level="fifth" style="font-size:18px;">标题5</li>
|
||||||
|
<li data-level="sixth" style="font-size:16px;">标题6</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="menu-item__left">
|
<div class="menu-item__left">
|
||||||
<i></i>
|
<i></i>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="#3D4757" fill-rule="evenodd"><path d="M14 1a1 1 0 011 1v12a1 1 0 01-1 1H2a1 1 0 01-1-1V2a1 1 0 011-1h12zm0 1H2v12h12V2z" fill-rule="nonzero"/><path fill-rule="nonzero" d="M4 11h8v1H4zm0-3h4v1H4zm0-3h2v1H4z"/><path d="M9 5h1v4H9z"/><path d="M7 5h5v1H7z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 336 B |
@@ -1,4 +1,4 @@
|
|||||||
import { IElement, ImageDisplay, INavigateInfo, TableBorder, VerticalAlign } from '../..'
|
import { IElement, ImageDisplay, INavigateInfo, TableBorder, TitleLevel, VerticalAlign } from '../..'
|
||||||
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
||||||
import { RowFlex } from '../../dataset/enum/Row'
|
import { RowFlex } from '../../dataset/enum/Row'
|
||||||
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
||||||
@@ -33,6 +33,7 @@ export class Command {
|
|||||||
private static subscript: CommandAdapt['subscript']
|
private static subscript: CommandAdapt['subscript']
|
||||||
private static color: CommandAdapt['color']
|
private static color: CommandAdapt['color']
|
||||||
private static highlight: CommandAdapt['highlight']
|
private static highlight: CommandAdapt['highlight']
|
||||||
|
private static title: CommandAdapt['title']
|
||||||
private static left: CommandAdapt['rowFlex']
|
private static left: CommandAdapt['rowFlex']
|
||||||
private static center: CommandAdapt['rowFlex']
|
private static center: CommandAdapt['rowFlex']
|
||||||
private static right: CommandAdapt['rowFlex']
|
private static right: CommandAdapt['rowFlex']
|
||||||
@@ -109,6 +110,7 @@ export class Command {
|
|||||||
Command.subscript = adapt.subscript.bind(adapt)
|
Command.subscript = adapt.subscript.bind(adapt)
|
||||||
Command.color = adapt.color.bind(adapt)
|
Command.color = adapt.color.bind(adapt)
|
||||||
Command.highlight = adapt.highlight.bind(adapt)
|
Command.highlight = adapt.highlight.bind(adapt)
|
||||||
|
Command.title = adapt.title.bind(adapt)
|
||||||
Command.left = adapt.rowFlex.bind(adapt)
|
Command.left = adapt.rowFlex.bind(adapt)
|
||||||
Command.center = adapt.rowFlex.bind(adapt)
|
Command.center = adapt.rowFlex.bind(adapt)
|
||||||
Command.right = adapt.rowFlex.bind(adapt)
|
Command.right = adapt.rowFlex.bind(adapt)
|
||||||
@@ -260,6 +262,11 @@ export class Command {
|
|||||||
return Command.highlight(payload)
|
return Command.highlight(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 标题、对齐方式
|
||||||
|
public executeTitle(payload: TitleLevel | null) {
|
||||||
|
return Command.title(payload)
|
||||||
|
}
|
||||||
|
|
||||||
public executeLeft() {
|
public executeLeft() {
|
||||||
return Command.left(RowFlex.LEFT)
|
return Command.left(RowFlex.LEFT)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { WRAP, ZERO } from '../../dataset/constant/Common'
|
import { WRAP, ZERO } from '../../dataset/constant/Common'
|
||||||
import { EDITOR_ELEMENT_STYLE_ATTR } from '../../dataset/constant/Element'
|
import { EDITOR_ELEMENT_STYLE_ATTR } from '../../dataset/constant/Element'
|
||||||
|
import { titleSizeMapping } from '../../dataset/constant/Title'
|
||||||
import { defaultWatermarkOption } from '../../dataset/constant/Watermark'
|
import { defaultWatermarkOption } from '../../dataset/constant/Watermark'
|
||||||
import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control'
|
import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control'
|
||||||
import { EditorContext, EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
import { EditorContext, EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
||||||
@@ -7,6 +8,7 @@ import { ElementType } from '../../dataset/enum/Element'
|
|||||||
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
||||||
import { RowFlex } from '../../dataset/enum/Row'
|
import { RowFlex } from '../../dataset/enum/Row'
|
||||||
import { TableBorder } from '../../dataset/enum/table/Table'
|
import { TableBorder } from '../../dataset/enum/table/Table'
|
||||||
|
import { TitleLevel } from '../../dataset/enum/Title'
|
||||||
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
||||||
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
||||||
import { IEditorOption, IEditorResult } from '../../interface/Editor'
|
import { IEditorOption, IEditorResult } from '../../interface/Editor'
|
||||||
@@ -379,6 +381,63 @@ export class CommandAdapt {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public title(payload: TitleLevel | null) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
|
if (!~startIndex && !~endIndex) return
|
||||||
|
// 需要改变的元素列表
|
||||||
|
let changeElementList: IElement[] = []
|
||||||
|
const elementList = this.draw.getElementList()
|
||||||
|
if (startIndex === endIndex) {
|
||||||
|
// 选区行信息
|
||||||
|
const rangeRow = this.range.getRangeRow()
|
||||||
|
if (!rangeRow) return
|
||||||
|
const positionList = this.position.getPositionList()
|
||||||
|
for (let p = 0; p < positionList.length; p++) {
|
||||||
|
const position = positionList[p]
|
||||||
|
const rowSet = rangeRow.get(position.pageNo)
|
||||||
|
if (!rowSet) continue
|
||||||
|
if (rowSet.has(position.rowNo)) {
|
||||||
|
changeElementList.push(elementList[p])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
changeElementList = elementList.slice(startIndex + 1, endIndex + 1)
|
||||||
|
}
|
||||||
|
// 检验数据合法性
|
||||||
|
const isExistNotTextElement = !!changeElementList.find(el =>
|
||||||
|
el.type &&
|
||||||
|
el.type !== ElementType.TEXT &&
|
||||||
|
el.type !== ElementType.TITLE
|
||||||
|
)
|
||||||
|
if (isExistNotTextElement) return
|
||||||
|
// 设置值
|
||||||
|
const titleId = getUUID()
|
||||||
|
const titleOptions = this.draw.getOptions().title
|
||||||
|
changeElementList.forEach(el => {
|
||||||
|
if (payload) {
|
||||||
|
el.type = ElementType.TITLE
|
||||||
|
el.level = payload
|
||||||
|
el.titleId = titleId
|
||||||
|
el.size = titleOptions[titleSizeMapping[payload]]
|
||||||
|
el.bold = true
|
||||||
|
} else {
|
||||||
|
if (el.type === ElementType.TITLE) {
|
||||||
|
delete el.type
|
||||||
|
delete el.titleId
|
||||||
|
delete el.level
|
||||||
|
delete el.size
|
||||||
|
delete el.bold
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 光标定位
|
||||||
|
const isSetCursor = startIndex === endIndex
|
||||||
|
const curIndex = isSetCursor ? endIndex : startIndex
|
||||||
|
this.draw.render({ curIndex, isSetCursor })
|
||||||
|
}
|
||||||
|
|
||||||
public rowFlex(payload: RowFlex) {
|
public rowFlex(payload: RowFlex) {
|
||||||
const isReadonly = this.draw.isReadonly()
|
const isReadonly = this.draw.isReadonly()
|
||||||
if (isReadonly) return
|
if (isReadonly) return
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function input(data: string, host: CanvasEvent) {
|
|||||||
cursor.clearAgentDomValue()
|
cursor.clearAgentDomValue()
|
||||||
}
|
}
|
||||||
const activeControl = control.getActiveControl()
|
const activeControl = control.getActiveControl()
|
||||||
const { TEXT, HYPERLINK, SUBSCRIPT, SUPERSCRIPT, DATE } = ElementType
|
const { TEXT, HYPERLINK, SUBSCRIPT, SUPERSCRIPT, DATE, TITLE } = ElementType
|
||||||
const text = data.replaceAll(`\n`, ZERO)
|
const text = data.replaceAll(`\n`, ZERO)
|
||||||
const rangeManager = draw.getRange()
|
const rangeManager = draw.getRange()
|
||||||
const { startIndex, endIndex } = rangeManager.getRange()
|
const { startIndex, endIndex } = rangeManager.getRange()
|
||||||
@@ -55,6 +55,7 @@ export function input(data: string, host: CanvasEvent) {
|
|||||||
|| (!copyElement.type && copyElement.value !== ZERO)
|
|| (!copyElement.type && copyElement.value !== ZERO)
|
||||||
|| (copyElement.type === HYPERLINK && nextElement?.type === HYPERLINK)
|
|| (copyElement.type === HYPERLINK && nextElement?.type === HYPERLINK)
|
||||||
|| (copyElement.type === DATE && nextElement?.type === DATE)
|
|| (copyElement.type === DATE && nextElement?.type === DATE)
|
||||||
|
|| copyElement.type === TITLE
|
||||||
|| (copyElement.type === SUBSCRIPT && nextElement?.type === SUBSCRIPT)
|
|| (copyElement.type === SUBSCRIPT && nextElement?.type === SUBSCRIPT)
|
||||||
|| (copyElement.type === SUPERSCRIPT && nextElement?.type === SUPERSCRIPT)
|
|| (copyElement.type === SUPERSCRIPT && nextElement?.type === SUPERSCRIPT)
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ export class RangeManager {
|
|||||||
const rowFlex = curElement.rowFlex || null
|
const rowFlex = curElement.rowFlex || null
|
||||||
const rowMargin = curElement.rowMargin || this.options.defaultRowMargin
|
const rowMargin = curElement.rowMargin || this.options.defaultRowMargin
|
||||||
const dashArray = curElement.dashArray || []
|
const dashArray = curElement.dashArray || []
|
||||||
|
const level = curElement.level || null
|
||||||
// 菜单
|
// 菜单
|
||||||
const painter = !!this.draw.getPainterStyle()
|
const painter = !!this.draw.getPainterStyle()
|
||||||
const undo = this.historyManager.isCanUndo()
|
const undo = this.historyManager.isCanUndo()
|
||||||
@@ -171,7 +172,8 @@ export class RangeManager {
|
|||||||
highlight,
|
highlight,
|
||||||
rowFlex,
|
rowFlex,
|
||||||
rowMargin,
|
rowMargin,
|
||||||
dashArray
|
dashArray,
|
||||||
|
level
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +200,8 @@ export class RangeManager {
|
|||||||
highlight: null,
|
highlight: null,
|
||||||
rowFlex: null,
|
rowFlex: null,
|
||||||
rowMargin,
|
rowMargin,
|
||||||
dashArray: []
|
dashArray: [],
|
||||||
|
level: null
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ export const EDITOR_ELEMENT_COPY_ATTR: Array<keyof IElement> = [
|
|||||||
'url',
|
'url',
|
||||||
'hyperlinkId',
|
'hyperlinkId',
|
||||||
'dateId',
|
'dateId',
|
||||||
'dateFormat'
|
'dateFormat',
|
||||||
|
'level',
|
||||||
|
'titleId'
|
||||||
]
|
]
|
||||||
|
|
||||||
export const EDITOR_ELEMENT_ZIP_ATTR: Array<keyof IElement> = [
|
export const EDITOR_ELEMENT_ZIP_ATTR: Array<keyof IElement> = [
|
||||||
@@ -52,7 +54,8 @@ export const EDITOR_ELEMENT_ZIP_ATTR: Array<keyof IElement> = [
|
|||||||
'control',
|
'control',
|
||||||
'checkbox',
|
'checkbox',
|
||||||
'dateFormat',
|
'dateFormat',
|
||||||
'block'
|
'block',
|
||||||
|
'level'
|
||||||
]
|
]
|
||||||
|
|
||||||
export const TEXTLIKE_ELEMENT_TYPE: ElementType[] = [
|
export const TEXTLIKE_ELEMENT_TYPE: ElementType[] = [
|
||||||
@@ -61,7 +64,8 @@ export const TEXTLIKE_ELEMENT_TYPE: ElementType[] = [
|
|||||||
ElementType.SUBSCRIPT,
|
ElementType.SUBSCRIPT,
|
||||||
ElementType.SUPERSCRIPT,
|
ElementType.SUPERSCRIPT,
|
||||||
ElementType.CONTROL,
|
ElementType.CONTROL,
|
||||||
ElementType.DATE
|
ElementType.DATE,
|
||||||
|
ElementType.TITLE
|
||||||
]
|
]
|
||||||
|
|
||||||
export const INLINE_ELEMENT_TYPE: ElementType[] = [
|
export const INLINE_ELEMENT_TYPE: ElementType[] = [
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { ITitleOption, ITitleSizeOption } from '../../interface/Title'
|
||||||
|
import { TitleLevel } from '../enum/Title'
|
||||||
|
|
||||||
|
export const defaultTitleOption: Readonly<Required<ITitleOption>> = {
|
||||||
|
defaultFirstSize: 26,
|
||||||
|
defaultSecondSize: 24,
|
||||||
|
defaultThirdSize: 22,
|
||||||
|
defaultFourthSize: 20,
|
||||||
|
defaultFifthSize: 18,
|
||||||
|
defaultSixthSize: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
export const titleSizeMapping: Record<TitleLevel, keyof ITitleSizeOption> = {
|
||||||
|
[TitleLevel.FIRST]: 'defaultFirstSize',
|
||||||
|
[TitleLevel.SECOND]: 'defaultSecondSize',
|
||||||
|
[TitleLevel.THIRD]: 'defaultThirdSize',
|
||||||
|
[TitleLevel.FOURTH]: 'defaultFourthSize',
|
||||||
|
[TitleLevel.FIFTH]: 'defaultFifthSize',
|
||||||
|
[TitleLevel.SIXTH]: 'defaultSixthSize'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const titleOrderNumberMapping: Record<TitleLevel, number> = {
|
||||||
|
[TitleLevel.FIRST]: 1,
|
||||||
|
[TitleLevel.SECOND]: 2,
|
||||||
|
[TitleLevel.THIRD]: 3,
|
||||||
|
[TitleLevel.FOURTH]: 4,
|
||||||
|
[TitleLevel.FIFTH]: 5,
|
||||||
|
[TitleLevel.SIXTH]: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
export const titleNodeNameMapping: Record<string, TitleLevel> = {
|
||||||
|
'H1': TitleLevel.FIRST,
|
||||||
|
'H2': TitleLevel.SECOND,
|
||||||
|
'H3': TitleLevel.THIRD,
|
||||||
|
'H4': TitleLevel.FOURTH,
|
||||||
|
'H5': TitleLevel.FIFTH,
|
||||||
|
'H6': TitleLevel.SIXTH
|
||||||
|
}
|
||||||
@@ -12,5 +12,6 @@ export enum ElementType {
|
|||||||
LATEX = 'latex',
|
LATEX = 'latex',
|
||||||
TAB = 'tab',
|
TAB = 'tab',
|
||||||
DATE = 'date',
|
DATE = 'date',
|
||||||
BLOCK = 'block'
|
BLOCK = 'block',
|
||||||
|
TITLE = 'title'
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export enum TitleLevel {
|
||||||
|
FIRST = 'first',
|
||||||
|
SECOND = 'second',
|
||||||
|
THIRD = 'third',
|
||||||
|
FOURTH = 'fourth',
|
||||||
|
FIFTH = 'fifth',
|
||||||
|
SIXTH = 'sixth'
|
||||||
|
}
|
||||||
+11
-2
@@ -38,6 +38,9 @@ import { TableBorder } from './dataset/enum/table/Table'
|
|||||||
import { IFooter } from './interface/Footer'
|
import { IFooter } from './interface/Footer'
|
||||||
import { defaultFooterOption } from './dataset/constant/Footer'
|
import { defaultFooterOption } from './dataset/constant/Footer'
|
||||||
import { MaxHeightRatio, NumberType } from './dataset/enum/Common'
|
import { MaxHeightRatio, NumberType } from './dataset/enum/Common'
|
||||||
|
import { ITitleOption } from './interface/Title'
|
||||||
|
import { defaultTitleOption } from './dataset/constant/Title'
|
||||||
|
import { TitleLevel } from './dataset/enum/Title'
|
||||||
|
|
||||||
export default class Editor {
|
export default class Editor {
|
||||||
|
|
||||||
@@ -75,6 +78,10 @@ export default class Editor {
|
|||||||
...defaultCursorOption,
|
...defaultCursorOption,
|
||||||
...options.cursor
|
...options.cursor
|
||||||
}
|
}
|
||||||
|
const titleOptions: Required<ITitleOption> = {
|
||||||
|
...defaultTitleOption,
|
||||||
|
...options.title
|
||||||
|
}
|
||||||
|
|
||||||
const editorOptions: DeepRequired<IEditorOption> = {
|
const editorOptions: DeepRequired<IEditorOption> = {
|
||||||
mode: EditorMode.EDIT,
|
mode: EditorMode.EDIT,
|
||||||
@@ -117,7 +124,8 @@ export default class Editor {
|
|||||||
watermark: waterMarkOptions,
|
watermark: waterMarkOptions,
|
||||||
control: controlOptions,
|
control: controlOptions,
|
||||||
checkbox: checkboxOptions,
|
checkbox: checkboxOptions,
|
||||||
cursor: cursorOptions
|
cursor: cursorOptions,
|
||||||
|
title: titleOptions
|
||||||
}
|
}
|
||||||
// 数据处理
|
// 数据处理
|
||||||
let headerElementList: IElement[] = []
|
let headerElementList: IElement[] = []
|
||||||
@@ -190,7 +198,8 @@ export {
|
|||||||
PaperDirection,
|
PaperDirection,
|
||||||
TableBorder,
|
TableBorder,
|
||||||
MaxHeightRatio,
|
MaxHeightRatio,
|
||||||
NumberType
|
NumberType,
|
||||||
|
TitleLevel
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对外类型
|
// 对外类型
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { IFooter } from './Footer'
|
|||||||
import { IHeader } from './Header'
|
import { IHeader } from './Header'
|
||||||
import { IMargin } from './Margin'
|
import { IMargin } from './Margin'
|
||||||
import { IPageNumber } from './PageNumber'
|
import { IPageNumber } from './PageNumber'
|
||||||
|
import { ITitleOption } from './Title'
|
||||||
import { IWatermark } from './Watermark'
|
import { IWatermark } from './Watermark'
|
||||||
|
|
||||||
export interface IEditorData {
|
export interface IEditorData {
|
||||||
@@ -56,6 +57,7 @@ export interface IEditorOption {
|
|||||||
control?: IControlOption;
|
control?: IControlOption;
|
||||||
checkbox?: ICheckboxOption;
|
checkbox?: ICheckboxOption;
|
||||||
cursor?: ICursorOption;
|
cursor?: ICursorOption;
|
||||||
|
title?: ITitleOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEditorResult {
|
export interface IEditorResult {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ControlComponent, ImageDisplay } from '../dataset/enum/Control'
|
import { ControlComponent, ImageDisplay } from '../dataset/enum/Control'
|
||||||
import { ElementType } from '../dataset/enum/Element'
|
import { ElementType } from '../dataset/enum/Element'
|
||||||
import { RowFlex } from '../dataset/enum/Row'
|
import { RowFlex } from '../dataset/enum/Row'
|
||||||
|
import { TitleLevel } from '../dataset/enum/Title'
|
||||||
import { TableBorder } from '../dataset/enum/table/Table'
|
import { TableBorder } from '../dataset/enum/table/Table'
|
||||||
import { IBlock } from './Block'
|
import { IBlock } from './Block'
|
||||||
import { ICheckbox } from './Checkbox'
|
import { ICheckbox } from './Checkbox'
|
||||||
@@ -30,6 +31,12 @@ export interface IElementStyle {
|
|||||||
letterSpacing?: number;
|
letterSpacing?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ITitleElement {
|
||||||
|
valueList?: IElement[];
|
||||||
|
level?: TitleLevel;
|
||||||
|
titleId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ITableAttr {
|
export interface ITableAttr {
|
||||||
colgroup?: IColgroup[];
|
colgroup?: IColgroup[];
|
||||||
trList?: ITr[];
|
trList?: ITr[];
|
||||||
@@ -97,6 +104,7 @@ export type IElement = IElementBasic
|
|||||||
& IDateElement
|
& IDateElement
|
||||||
& IImageElement
|
& IImageElement
|
||||||
& IBlockElement
|
& IBlockElement
|
||||||
|
& ITitleElement
|
||||||
|
|
||||||
export interface IElementMetrics {
|
export interface IElementMetrics {
|
||||||
width: number;
|
width: number;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { EditorZone, ElementType, PageMode } from '..'
|
import { EditorZone, ElementType, PageMode, TitleLevel } from '..'
|
||||||
import { RowFlex } from '../dataset/enum/Row'
|
import { RowFlex } from '../dataset/enum/Row'
|
||||||
import { IControl } from './Control'
|
import { IControl } from './Control'
|
||||||
import { IEditorResult } from './Editor'
|
import { IEditorResult } from './Editor'
|
||||||
@@ -19,6 +19,7 @@ export interface IRangeStyle {
|
|||||||
rowFlex: RowFlex | null;
|
rowFlex: RowFlex | null;
|
||||||
rowMargin: number;
|
rowMargin: number;
|
||||||
dashArray: number[];
|
dashArray: number[];
|
||||||
|
level: TitleLevel | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IRangeStyleChange = (payload: IRangeStyle) => void
|
export type IRangeStyleChange = (payload: IRangeStyle) => void
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export interface ITitleSizeOption {
|
||||||
|
defaultFirstSize?: number;
|
||||||
|
defaultSecondSize?: number;
|
||||||
|
defaultThirdSize?: number;
|
||||||
|
defaultFourthSize?: number;
|
||||||
|
defaultFifthSize?: number;
|
||||||
|
defaultSixthSize?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ITitleOption = ITitleSizeOption & {}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { IEditorOption, IElement, RowFlex } from '..'
|
import { IEditorOption, IElement, RowFlex } from '..'
|
||||||
import { ZERO } from '../dataset/constant/Common'
|
import { ZERO } from '../dataset/constant/Common'
|
||||||
import { TEXTLIKE_ELEMENT_TYPE } from '../dataset/constant/Element'
|
import { TEXTLIKE_ELEMENT_TYPE } from '../dataset/constant/Element'
|
||||||
|
import { titleNodeNameMapping, titleOrderNumberMapping } from '../dataset/constant/Title'
|
||||||
import { ControlComponent } from '../dataset/enum/Control'
|
import { ControlComponent } from '../dataset/enum/Control'
|
||||||
import { ElementType } from '../dataset/enum/Element'
|
import { ElementType } from '../dataset/enum/Element'
|
||||||
import { DeepRequired } from '../interface/Common'
|
import { DeepRequired } from '../interface/Common'
|
||||||
@@ -35,6 +36,33 @@ export function writeClipboardItem(text: string, html: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function convertElementToDom(element: IElement, options: DeepRequired<IEditorOption>): HTMLElement {
|
||||||
|
const isBlock = element.rowFlex === RowFlex.CENTER || element.rowFlex === RowFlex.RIGHT
|
||||||
|
const dom = document.createElement(isBlock ? 'p' : 'span')
|
||||||
|
dom.style.fontFamily = element.font || options.defaultFont
|
||||||
|
if (element.rowFlex) {
|
||||||
|
const isAlignment = element.rowFlex === RowFlex.ALIGNMENT
|
||||||
|
dom.style.textAlign = isAlignment ? 'justify' : element.rowFlex
|
||||||
|
}
|
||||||
|
if (element.color) {
|
||||||
|
dom.style.color = element.color
|
||||||
|
}
|
||||||
|
if (element.bold) {
|
||||||
|
dom.style.fontWeight = '600'
|
||||||
|
}
|
||||||
|
if (element.italic) {
|
||||||
|
dom.style.fontStyle = 'italic'
|
||||||
|
}
|
||||||
|
if (element.size) {
|
||||||
|
dom.style.fontSize = `${element.size}px`
|
||||||
|
}
|
||||||
|
if (element.highlight) {
|
||||||
|
dom.style.backgroundColor = element.highlight
|
||||||
|
}
|
||||||
|
dom.innerText = element.value.replace(new RegExp(`${ZERO}`, 'g'), '\n')
|
||||||
|
return dom
|
||||||
|
}
|
||||||
|
|
||||||
export function writeElementList(elementList: IElement[], options: DeepRequired<IEditorOption>) {
|
export function writeElementList(elementList: IElement[], options: DeepRequired<IEditorOption>) {
|
||||||
const clipboardDom: HTMLDivElement = document.createElement('div')
|
const clipboardDom: HTMLDivElement = document.createElement('div')
|
||||||
function buildDomFromElementList(payload: IElement[]) {
|
function buildDomFromElementList(payload: IElement[]) {
|
||||||
@@ -61,11 +89,18 @@ export function writeElementList(elementList: IElement[], options: DeepRequired<
|
|||||||
clipboardDom.append(tableDom)
|
clipboardDom.append(tableDom)
|
||||||
} else if (element.type === ElementType.HYPERLINK) {
|
} else if (element.type === ElementType.HYPERLINK) {
|
||||||
const a = document.createElement('a')
|
const a = document.createElement('a')
|
||||||
a.innerText = element.valueList![0].value
|
a.innerText = element.valueList!.map(v => v.value).join('')
|
||||||
if (element.url) {
|
if (element.url) {
|
||||||
a.href = element.url
|
a.href = element.url
|
||||||
}
|
}
|
||||||
clipboardDom.append(a)
|
clipboardDom.append(a)
|
||||||
|
} else if (element.type === ElementType.TITLE) {
|
||||||
|
const h = document.createElement(`h${titleOrderNumberMapping[element.level!]}`)
|
||||||
|
element.valueList!.forEach(el => {
|
||||||
|
const dom = convertElementToDom(el, options)
|
||||||
|
h.append(dom)
|
||||||
|
})
|
||||||
|
clipboardDom.append(h)
|
||||||
} else if (element.type === ElementType.IMAGE) {
|
} else if (element.type === ElementType.IMAGE) {
|
||||||
const img = document.createElement('img')
|
const img = document.createElement('img')
|
||||||
if (element.value) {
|
if (element.value) {
|
||||||
@@ -98,29 +133,12 @@ export function writeElementList(elementList: IElement[], options: DeepRequired<
|
|||||||
text = element.value
|
text = element.value
|
||||||
}
|
}
|
||||||
if (!text) continue
|
if (!text) continue
|
||||||
const isBlock = element.rowFlex === RowFlex.CENTER || element.rowFlex === RowFlex.RIGHT
|
// 前一个元素是标题,移除首行换行符
|
||||||
const dom = document.createElement(isBlock ? 'p' : 'span')
|
if (payload[e - 1]?.type === ElementType.TITLE) {
|
||||||
|
text = text.replace(/^\n/, '')
|
||||||
|
}
|
||||||
|
const dom = convertElementToDom(element, options)
|
||||||
dom.innerText = text.replace(new RegExp(`${ZERO}`, 'g'), '\n')
|
dom.innerText = text.replace(new RegExp(`${ZERO}`, 'g'), '\n')
|
||||||
dom.style.fontFamily = element.font || options.defaultFont
|
|
||||||
if (element.rowFlex) {
|
|
||||||
const isAlignment = element.rowFlex === RowFlex.ALIGNMENT
|
|
||||||
dom.style.textAlign = isAlignment ? 'justify' : element.rowFlex
|
|
||||||
}
|
|
||||||
if (element.color) {
|
|
||||||
dom.style.color = element.color
|
|
||||||
}
|
|
||||||
if (element.bold) {
|
|
||||||
dom.style.fontWeight = '600'
|
|
||||||
}
|
|
||||||
if (element.italic) {
|
|
||||||
dom.style.fontStyle = 'italic'
|
|
||||||
}
|
|
||||||
if (element.size) {
|
|
||||||
dom.style.fontSize = `${element.size}px`
|
|
||||||
}
|
|
||||||
if (element.highlight) {
|
|
||||||
dom.style.backgroundColor = element.highlight
|
|
||||||
}
|
|
||||||
clipboardDom.append(dom)
|
clipboardDom.append(dom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,6 +204,19 @@ export function getElementListByHTML(htmlText: string, options: IGetElementListB
|
|||||||
url: aElement.href
|
url: aElement.href
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
} else if (/H[1-6]/.test(node.nodeName)) {
|
||||||
|
const hElement = node as HTMLTitleElement
|
||||||
|
const valueList = getElementListByHTML(hElement.innerHTML, options)
|
||||||
|
.filter(el => !el.type || el.type === ElementType.TEXT)
|
||||||
|
elementList.push({
|
||||||
|
value: '',
|
||||||
|
type: ElementType.TITLE,
|
||||||
|
level: titleNodeNameMapping[node.nodeName],
|
||||||
|
valueList
|
||||||
|
})
|
||||||
|
elementList.push({
|
||||||
|
value: '\n'
|
||||||
|
})
|
||||||
} else if (node.nodeName === 'HR') {
|
} else if (node.nodeName === 'HR') {
|
||||||
elementList.push({
|
elementList.push({
|
||||||
value: '\n',
|
value: '\n',
|
||||||
|
|||||||
+67
-20
@@ -5,9 +5,22 @@ import { defaultCheckboxOption } from '../dataset/constant/Checkbox'
|
|||||||
import { ZERO } from '../dataset/constant/Common'
|
import { ZERO } from '../dataset/constant/Common'
|
||||||
import { defaultControlOption } from '../dataset/constant/Control'
|
import { defaultControlOption } from '../dataset/constant/Control'
|
||||||
import { EDITOR_ELEMENT_ZIP_ATTR } from '../dataset/constant/Element'
|
import { EDITOR_ELEMENT_ZIP_ATTR } from '../dataset/constant/Element'
|
||||||
|
import { titleSizeMapping } from '../dataset/constant/Title'
|
||||||
import { ControlComponent, ControlType } from '../dataset/enum/Control'
|
import { ControlComponent, ControlType } from '../dataset/enum/Control'
|
||||||
import { ITd } from '../interface/table/Td'
|
import { ITd } from '../interface/table/Td'
|
||||||
|
|
||||||
|
export function unzipElementList(elementList: IElement[]): IElement[] {
|
||||||
|
const result: IElement[] = []
|
||||||
|
for (let v = 0; v < elementList.length; v++) {
|
||||||
|
const valueItem = elementList[v]
|
||||||
|
const textList = splitText(valueItem.value)
|
||||||
|
for (let d = 0; d < textList.length; d++) {
|
||||||
|
result.push({ ...valueItem, value: textList[d] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
interface IFormatElementListOption {
|
interface IFormatElementListOption {
|
||||||
isHandleFirstElement?: boolean;
|
isHandleFirstElement?: boolean;
|
||||||
editorOptions: Required<IEditorOption>;
|
editorOptions: Required<IEditorOption>;
|
||||||
@@ -58,19 +71,12 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (el.type === ElementType.HYPERLINK) {
|
} else if (el.type === ElementType.HYPERLINK) {
|
||||||
const valueList = el.valueList || []
|
|
||||||
// 移除父节点
|
// 移除父节点
|
||||||
elementList.splice(i, 1)
|
elementList.splice(i, 1)
|
||||||
// 追加字节点
|
|
||||||
if (valueList.length) {
|
|
||||||
// 元素展开
|
// 元素展开
|
||||||
if (valueList[0].value.length > 1) {
|
const valueList = unzipElementList(el.valueList || [])
|
||||||
const deleteValue = valueList.splice(0, 1)[0]
|
// 追加节点
|
||||||
const deleteTextList = splitText(deleteValue.value)
|
if (valueList.length) {
|
||||||
for (let d = 0; d < deleteTextList.length; d++) {
|
|
||||||
valueList.splice(d, 0, { ...deleteValue, value: deleteTextList[d] })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const hyperlinkId = getUUID()
|
const hyperlinkId = getUUID()
|
||||||
for (let v = 0; v < valueList.length; v++) {
|
for (let v = 0; v < valueList.length; v++) {
|
||||||
const value = valueList[v]
|
const value = valueList[v]
|
||||||
@@ -83,19 +89,12 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
}
|
}
|
||||||
i--
|
i--
|
||||||
} else if (el.type === ElementType.DATE) {
|
} else if (el.type === ElementType.DATE) {
|
||||||
const valueList = el.valueList || []
|
|
||||||
// 移除父节点
|
// 移除父节点
|
||||||
elementList.splice(i, 1)
|
elementList.splice(i, 1)
|
||||||
// 追加字节点
|
|
||||||
if (valueList.length) {
|
|
||||||
// 元素展开
|
// 元素展开
|
||||||
if (valueList[0].value.length > 1) {
|
const valueList = unzipElementList(el.valueList || [])
|
||||||
const deleteValue = valueList.splice(0, 1)[0]
|
// 追加节点
|
||||||
const deleteTextList = splitText(deleteValue.value)
|
if (valueList.length) {
|
||||||
for (let d = 0; d < deleteTextList.length; d++) {
|
|
||||||
valueList.splice(d, 0, { ...deleteValue, value: deleteTextList[d] })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const dateId = getUUID()
|
const dateId = getUUID()
|
||||||
for (let v = 0; v < valueList.length; v++) {
|
for (let v = 0; v < valueList.length; v++) {
|
||||||
const value = valueList[v]
|
const value = valueList[v]
|
||||||
@@ -107,6 +106,31 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
i--
|
i--
|
||||||
|
} else if (el.type === ElementType.TITLE) {
|
||||||
|
// 移除父节点
|
||||||
|
elementList.splice(i, 1)
|
||||||
|
// 元素展开
|
||||||
|
const valueList = unzipElementList(el.valueList || [])
|
||||||
|
// 追加节点
|
||||||
|
if (valueList.length) {
|
||||||
|
const titleId = getUUID()
|
||||||
|
const titleOptions = editorOptions.title
|
||||||
|
for (let v = 0; v < valueList.length; v++) {
|
||||||
|
const value = valueList[v]
|
||||||
|
value.titleId = titleId
|
||||||
|
value.type = el.type
|
||||||
|
value.level = el.level
|
||||||
|
if (!value.size) {
|
||||||
|
value.size = titleOptions[titleSizeMapping[value.level!]]
|
||||||
|
}
|
||||||
|
if (value.bold === undefined) {
|
||||||
|
value.bold = true
|
||||||
|
}
|
||||||
|
elementList.splice(i, 0, value)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i--
|
||||||
} else if (el.type === ElementType.CONTROL) {
|
} else if (el.type === ElementType.CONTROL) {
|
||||||
const { prefix, postfix, value, placeholder, code, type, valueSets } = el.control!
|
const { prefix, postfix, value, placeholder, code, type, valueSets } = el.control!
|
||||||
const controlId = getUUID()
|
const controlId = getUUID()
|
||||||
@@ -370,6 +394,29 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
|||||||
}
|
}
|
||||||
dateElement.valueList = zipElementList(valueList)
|
dateElement.valueList = zipElementList(valueList)
|
||||||
element = dateElement
|
element = dateElement
|
||||||
|
} else if (element.type === ElementType.TITLE) {
|
||||||
|
// 标题处理
|
||||||
|
const titleId = element.titleId
|
||||||
|
const level = element.level
|
||||||
|
const titleElement: IElement = {
|
||||||
|
type: ElementType.TITLE,
|
||||||
|
value: '',
|
||||||
|
level
|
||||||
|
}
|
||||||
|
const valueList: IElement[] = []
|
||||||
|
while (e < elementList.length) {
|
||||||
|
const titleE = elementList[e]
|
||||||
|
if (titleId !== titleE.titleId) {
|
||||||
|
e--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
delete titleE.type
|
||||||
|
delete titleE.level
|
||||||
|
valueList.push(titleE)
|
||||||
|
e++
|
||||||
|
}
|
||||||
|
titleElement.valueList = zipElementList(valueList)
|
||||||
|
element = titleElement
|
||||||
} else if (element.type === ElementType.CONTROL) {
|
} else if (element.type === ElementType.CONTROL) {
|
||||||
// 控件处理
|
// 控件处理
|
||||||
const controlId = element.controlId
|
const controlId = element.controlId
|
||||||
|
|||||||
+25
-1
@@ -1,7 +1,7 @@
|
|||||||
import { data, options } from './mock'
|
import { data, options } from './mock'
|
||||||
import './style.css'
|
import './style.css'
|
||||||
import prism from 'prismjs'
|
import prism from 'prismjs'
|
||||||
import Editor, { BlockType, Command, ControlType, EditorMode, ElementType, IBlock, IElement, KeyMap, PageMode, PaperDirection, RowFlex } from './editor'
|
import Editor, { BlockType, Command, ControlType, EditorMode, ElementType, IBlock, IElement, KeyMap, PageMode, PaperDirection, RowFlex, TitleLevel } from './editor'
|
||||||
import { Dialog } from './components/dialog/Dialog'
|
import { Dialog } from './components/dialog/Dialog'
|
||||||
import { formatPrismToken } from './utils/prism'
|
import { formatPrismToken } from './utils/prism'
|
||||||
import { Signature } from './components/signature/Signature'
|
import { Signature } from './components/signature/Signature'
|
||||||
@@ -175,6 +175,19 @@ window.onload = function () {
|
|||||||
highlightControlDom?.click()
|
highlightControlDom?.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const titleDom = document.querySelector<HTMLDivElement>('.menu-item__title')!
|
||||||
|
const titleSelectDom = titleDom.querySelector<HTMLDivElement>('.select')!
|
||||||
|
const titleOptionDom = titleDom.querySelector<HTMLDivElement>('.options')!
|
||||||
|
titleDom.onclick = function () {
|
||||||
|
console.log('title')
|
||||||
|
titleOptionDom.classList.toggle('visible')
|
||||||
|
}
|
||||||
|
titleOptionDom.onclick = function (evt) {
|
||||||
|
const li = evt.target as HTMLLIElement
|
||||||
|
const level = <TitleLevel>li.dataset.level
|
||||||
|
instance.command.executeTitle(level || null)
|
||||||
|
}
|
||||||
|
|
||||||
const leftDom = document.querySelector<HTMLDivElement>('.menu-item__left')!
|
const leftDom = document.querySelector<HTMLDivElement>('.menu-item__left')!
|
||||||
leftDom.title = `左对齐(${isApple ? '⌘' : 'Ctrl'}+L)`
|
leftDom.title = `左对齐(${isApple ? '⌘' : 'Ctrl'}+L)`
|
||||||
leftDom.onclick = function () {
|
leftDom.onclick = function () {
|
||||||
@@ -1056,6 +1069,17 @@ window.onload = function () {
|
|||||||
payload.undo ? undoDom.classList.remove('no-allow') : undoDom.classList.add('no-allow')
|
payload.undo ? undoDom.classList.remove('no-allow') : undoDom.classList.add('no-allow')
|
||||||
payload.redo ? redoDom.classList.remove('no-allow') : redoDom.classList.add('no-allow')
|
payload.redo ? redoDom.classList.remove('no-allow') : redoDom.classList.add('no-allow')
|
||||||
payload.painter ? painterDom.classList.add('active') : painterDom.classList.remove('active')
|
payload.painter ? painterDom.classList.add('active') : painterDom.classList.remove('active')
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
titleOptionDom.querySelectorAll<HTMLLIElement>('li').forEach(li => li.classList.remove('active'))
|
||||||
|
if (payload.level) {
|
||||||
|
const curTitleDom = titleOptionDom.querySelector<HTMLLIElement>(`[data-level='${payload.level}']`)!
|
||||||
|
titleSelectDom.innerText = curTitleDom.innerText
|
||||||
|
curTitleDom.classList.add('active')
|
||||||
|
} else {
|
||||||
|
titleSelectDom.innerText = '正文'
|
||||||
|
titleOptionDom.querySelector('li:first-child')!.classList.add('active')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.listener.visiblePageNoListChange = function (payload) {
|
instance.listener.visiblePageNoListChange = function (payload) {
|
||||||
|
|||||||
+45
-31
@@ -1,13 +1,17 @@
|
|||||||
import { ControlType, ElementType, IEditorOption, IElement } from './editor'
|
import { ControlType, ElementType, IEditorOption, IElement, TitleLevel } from './editor'
|
||||||
|
|
||||||
const text = `主诉:\n发热三天,咳嗽五天。\n现病史:\n患者于三天前无明显诱因,感冒后发现面部水肿,无皮疹,尿量减少,出现乏力,在外治疗无好转,现来我院就诊。\n既往史:\n有糖尿病10年,有高血压2年,有传染性疾病1年。报告其他既往疾病。\n流行病史:\n否认14天内接触过确诊患者、疑似患者、无症状感染者及其密切接触者;否认14天内去过以下场所:水产、肉类批发市场,农贸市场,集市,大型超市,夜市;否认14天内与以下场所工作人员密切接触:水产、肉类批发市场,农贸市场,集市,大型超市;否认14天内周围(如家庭、办公室)有2例以上聚集性发病;否认14天内接触过有发热或呼吸道症状的人员;否认14天内自身有发热或呼吸道症状;否认14天内接触过纳入隔离观察的人员及其他可能与新冠肺炎关联的情形;陪同家属无以上情况。\n体格检查:\nT:39.5℃,P:80bpm,R:20次/分,BP:120/80mmHg;\n辅助检查:\n2020年6月10日,普放:血细胞比容36.50%(偏低)40~50;单核细胞绝对值0.75*10/L(偏高)参考值:0.1~0.6;\n门诊诊断:\n1.高血压\n2.糖尿病\n3.病毒性感冒\n4.过敏性鼻炎\n5.过敏性鼻息肉\n处置治疗:\n1.超声引导下甲状腺细针穿刺术;\n2.乙型肝炎表面抗体测定;\n3.膜式病变细胞采集术、后颈皮下肤层;\n电子签名:【】\n其他记录:`
|
const text = `主诉:\n发热三天,咳嗽五天。\n现病史:\n患者于三天前无明显诱因,感冒后发现面部水肿,无皮疹,尿量减少,出现乏力,在外治疗无好转,现来我院就诊。\n既往史:\n有糖尿病10年,有高血压2年,有传染性疾病1年。报告其他既往疾病。\n流行病史:\n否认14天内接触过确诊患者、疑似患者、无症状感染者及其密切接触者;否认14天内去过以下场所:水产、肉类批发市场,农贸市场,集市,大型超市,夜市;否认14天内与以下场所工作人员密切接触:水产、肉类批发市场,农贸市场,集市,大型超市;否认14天内周围(如家庭、办公室)有2例以上聚集性发病;否认14天内接触过有发热或呼吸道症状的人员;否认14天内自身有发热或呼吸道症状;否认14天内接触过纳入隔离观察的人员及其他可能与新冠肺炎关联的情形;陪同家属无以上情况。\n体格检查:\nT:39.5℃,P:80bpm,R:20次/分,BP:120/80mmHg;\n辅助检查:\n2020年6月10日,普放:血细胞比容36.50%(偏低)40~50;单核细胞绝对值0.75*10/L(偏高)参考值:0.1~0.6;\n门诊诊断:\n1.高血压\n2.糖尿病\n3.病毒性感冒\n4.过敏性鼻炎\n5.过敏性鼻息肉\n处置治疗:\n1.超声引导下甲状腺细针穿刺术;\n2.乙型肝炎表面抗体测定;\n3.膜式病变细胞采集术、后颈皮下肤层;\n电子签名:【】\n其他记录:`
|
||||||
|
|
||||||
// 模拟加粗字
|
// 模拟标题
|
||||||
const boldText = ['主诉:', '现病史:', '既往史:', '流行病史:', '体格检查:', '辅助检查:', '门诊诊断:', '处置治疗:', '电子签名:', '其他记录:']
|
const titleText = ['主诉:', '现病史:', '既往史:', '流行病史:', '体格检查:', '辅助检查:', '门诊诊断:', '处置治疗:', '电子签名:', '其他记录:']
|
||||||
const boldIndex: number[] = boldText.map(b => {
|
const titleMap: Map<number, string> = new Map()
|
||||||
const i = text.indexOf(b)
|
for (let t = 0; t < titleText.length; t++) {
|
||||||
return ~i ? Array(b.length).fill(i).map((_, j) => i + j) : []
|
const value = titleText[t]
|
||||||
}).flat()
|
const i = text.indexOf(value)
|
||||||
|
if (~i) {
|
||||||
|
titleMap.set(i, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 模拟颜色字
|
// 模拟颜色字
|
||||||
const colorText = ['传染性疾病']
|
const colorText = ['传染性疾病']
|
||||||
@@ -23,36 +27,46 @@ const highlightIndex: number[] = highlightText.map(b => {
|
|||||||
return ~i ? Array(b.length).fill(i).map((_, j) => i + j) : []
|
return ~i ? Array(b.length).fill(i).map((_, j) => i + j) : []
|
||||||
}).flat()
|
}).flat()
|
||||||
|
|
||||||
|
const elementList: IElement[] = []
|
||||||
// 组合纯文本数据
|
// 组合纯文本数据
|
||||||
const elementList: IElement[] = text.split('').map((value, index) => {
|
const textList = text.split('')
|
||||||
if (boldIndex.includes(index)) {
|
let index = 0
|
||||||
return {
|
while (index < textList.length) {
|
||||||
value,
|
const value = textList[index]
|
||||||
size: 18,
|
const title = titleMap.get(index)
|
||||||
bold: true
|
if (title) {
|
||||||
}
|
elementList.push({
|
||||||
}
|
value: '',
|
||||||
if (colorIndex.includes(index)) {
|
type: ElementType.TITLE,
|
||||||
return {
|
level: TitleLevel.FIRST,
|
||||||
|
valueList: [{
|
||||||
|
value: title,
|
||||||
|
size: 18
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
index += title.length - 1
|
||||||
|
} else if (colorIndex.includes(index)) {
|
||||||
|
elementList.push({
|
||||||
value,
|
value,
|
||||||
color: '#FF0000',
|
color: '#FF0000',
|
||||||
size: 16
|
size: 16
|
||||||
}
|
})
|
||||||
}
|
} else if (highlightIndex.includes(index)) {
|
||||||
if (highlightIndex.includes(index)) {
|
elementList.push({
|
||||||
return {
|
|
||||||
value,
|
value,
|
||||||
highlight: '#F2F27F'
|
highlight: '#F2F27F'
|
||||||
}
|
})
|
||||||
}
|
} else {
|
||||||
return {
|
elementList.push({
|
||||||
value,
|
value,
|
||||||
size: 16
|
size: 16
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
|
||||||
// 模拟文本控件
|
// 模拟文本控件
|
||||||
elementList.splice(14, 0, {
|
elementList.splice(12, 0, {
|
||||||
type: ElementType.CONTROL,
|
type: ElementType.CONTROL,
|
||||||
value: '',
|
value: '',
|
||||||
control: {
|
control: {
|
||||||
@@ -65,7 +79,7 @@ elementList.splice(14, 0, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 模拟下拉控件
|
// 模拟下拉控件
|
||||||
elementList.splice(102, 0, {
|
elementList.splice(94, 0, {
|
||||||
type: ElementType.CONTROL,
|
type: ElementType.CONTROL,
|
||||||
value: '',
|
value: '',
|
||||||
control: {
|
control: {
|
||||||
@@ -89,7 +103,7 @@ elementList.splice(102, 0, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 模拟超链接
|
// 模拟超链接
|
||||||
elementList.splice(128, 0, {
|
elementList.splice(116, 0, {
|
||||||
type: ElementType.HYPERLINK,
|
type: ElementType.HYPERLINK,
|
||||||
value: '',
|
value: '',
|
||||||
valueList: [{
|
valueList: [{
|
||||||
@@ -109,20 +123,20 @@ elementList.splice(128, 0, {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 模拟下标
|
// 模拟下标
|
||||||
elementList.splice(361, 0, {
|
elementList.splice(345, 0, {
|
||||||
value: '∆',
|
value: '∆',
|
||||||
color: '#FF0000',
|
color: '#FF0000',
|
||||||
type: ElementType.SUBSCRIPT
|
type: ElementType.SUBSCRIPT
|
||||||
})
|
})
|
||||||
|
|
||||||
// 模拟上标
|
// 模拟上标
|
||||||
elementList.splice(449, 0, {
|
elementList.splice(429, 0, {
|
||||||
value: '9',
|
value: '9',
|
||||||
type: ElementType.SUPERSCRIPT
|
type: ElementType.SUPERSCRIPT
|
||||||
})
|
})
|
||||||
|
|
||||||
// 模拟图片
|
// 模拟图片
|
||||||
elementList.splice(575, 0, {
|
elementList.splice(543, 0, {
|
||||||
value: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAAAgCAYAAAB5JtSmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAQ0SURBVGhD7dhrUSNBFAVgvKACEVjAAhJQgAIUYAABGEAABvgfAdn6UnWou01PppOZhIXNj1P9vo9zH5PK1Waz2V5wWlxIPgMuJJ8Bi0h+fn7eXl9fb29ubrYPDw/dO/8DHh8fu/vB4kym4Orqaofb29vund8OSSbhemewSrugBMnG3vlvw9vb265yn56edmtz/t/f33+5C8MkixQSZSsl9UzLOHUmcwTYAN/Rpl5eXnY+pnIB0Xd3d7s5m3rvDsrkCGszNiQ7r/tr4v39fSc/uipOqRcqufTHBiO78GGdzG5xcLtIFmVde7L9NsvXRo9s84+Pj+79pUAwn5GcD1wIz5r+fYGeJdnjGiF9hwL7iWAcfX19/evtKVHJXrtN8Rf4A3TVczqhrut5i1mSZQgnIriSWtdzP2N+EvIhi3/GWqHWtWXuy2IYbheiKarJZIZknkxyrryc2Utrgal+9S8iScUXIx/3kcxfe/jotcuDezLFlIbARDrzHpytXdKnQr4xyc74Vu9YV5Ih2Q/tT7mDSEYw5ZU4wu3nJx64k/1z9umlUG0hah/JSbC6Jzi5exDJWoTHERoBxu8uf/pT1j3HDkUIJitjbRfRA/iwVzlgy1RCfSF5ili9xj7BUWKs9wJZ3MpditYu+lsc+/PRx53cVF9Pdg/syE9Hb6cS75PkmhUEUFofmTvLGEXKimHueJP9Y3swWQwGLUiA9xEbHKuvgs4pPe1+1myTAKlw81buJ8kigjAXKauXPLQPhEYgJSEYsgdTUR0BmTVgc6C359wcvKGnBrGO8dO5VlD1ZZ519nrBHvrwKVMCas9hgL0YUI2wV98fC4FqCWizzXyqF44A0ZKLHkilgvPs1zbiTuZIdZ414KvqGCKZYx4zple+MSrrJVncAyL02/TOqncJwVMglx5zI4QDZ5WPvBGEcNP+7TlEcqJIAQFGsIdQjmZt7MlYA5yiI3pOQTCQXUm2TuVmXgmewxDJQDgl6deJJoU5y7p9uwZagmu1mCvbNoOOBfkhOf6lRZjzPb8qRjBMMiUhM9GNMZQq5/oRXBP7Mlj/i12A7EMIaJGqDcl8I79+/N1xTvdINQ2TDAQSvI9Md479vdqCHKSFQKAfEmgBqCTDkjaSgOZXQkg2jy1ti0xApnBQJo/0obQRipeQXbN3CmxKGQch5xgki4Efghl/kFqzPD//2DnXIodIRpaoETaXxcmwGNO7N4I2Oyuc6b+xK/tL9IH3kY/E+r1JdST4yM+7VUiuJbuPZHBeHZcNvXtziMMV9mRuvUOX8Vg9IFjRx9dUYM3s2oJyNx9ahFfSWwyRHKHG3nmL2q/mojyFVAWnEdi2Hg7OBXwUCCKr1QEtoe0+/9jI3xqIiuF2QRD0zqcwpfQnge9TVSI4tWrNe79shj98F0xDC0N4bTUVF5LPgAvJJ8dm+wcP2iJuZNdC5QAAAABJRU5ErkJggg==`,
|
value: `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAAAgCAYAAAB5JtSmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAQ0SURBVGhD7dhrUSNBFAVgvKACEVjAAhJQgAIUYAABGEAABvgfAdn6UnWou01PppOZhIXNj1P9vo9zH5PK1Waz2V5wWlxIPgMuJJ8Bi0h+fn7eXl9fb29ubrYPDw/dO/8DHh8fu/vB4kym4Orqaofb29vund8OSSbhemewSrugBMnG3vlvw9vb265yn56edmtz/t/f33+5C8MkixQSZSsl9UzLOHUmcwTYAN/Rpl5eXnY+pnIB0Xd3d7s5m3rvDsrkCGszNiQ7r/tr4v39fSc/uipOqRcqufTHBiO78GGdzG5xcLtIFmVde7L9NsvXRo9s84+Pj+79pUAwn5GcD1wIz5r+fYGeJdnjGiF9hwL7iWAcfX19/evtKVHJXrtN8Rf4A3TVczqhrut5i1mSZQgnIriSWtdzP2N+EvIhi3/GWqHWtWXuy2IYbheiKarJZIZknkxyrryc2Utrgal+9S8iScUXIx/3kcxfe/jotcuDezLFlIbARDrzHpytXdKnQr4xyc74Vu9YV5Ih2Q/tT7mDSEYw5ZU4wu3nJx64k/1z9umlUG0hah/JSbC6Jzi5exDJWoTHERoBxu8uf/pT1j3HDkUIJitjbRfRA/iwVzlgy1RCfSF5ili9xj7BUWKs9wJZ3MpditYu+lsc+/PRx53cVF9Pdg/syE9Hb6cS75PkmhUEUFofmTvLGEXKimHueJP9Y3swWQwGLUiA9xEbHKuvgs4pPe1+1myTAKlw81buJ8kigjAXKauXPLQPhEYgJSEYsgdTUR0BmTVgc6C359wcvKGnBrGO8dO5VlD1ZZ519nrBHvrwKVMCas9hgL0YUI2wV98fC4FqCWizzXyqF44A0ZKLHkilgvPs1zbiTuZIdZ414KvqGCKZYx4zple+MSrrJVncAyL02/TOqncJwVMglx5zI4QDZ5WPvBGEcNP+7TlEcqJIAQFGsIdQjmZt7MlYA5yiI3pOQTCQXUm2TuVmXgmewxDJQDgl6deJJoU5y7p9uwZagmu1mCvbNoOOBfkhOf6lRZjzPb8qRjBMMiUhM9GNMZQq5/oRXBP7Mlj/i12A7EMIaJGqDcl8I79+/N1xTvdINQ2TDAQSvI9Md479vdqCHKSFQKAfEmgBqCTDkjaSgOZXQkg2jy1ti0xApnBQJo/0obQRipeQXbN3CmxKGQch5xgki4Efghl/kFqzPD//2DnXIodIRpaoETaXxcmwGNO7N4I2Oyuc6b+xK/tL9IH3kY/E+r1JdST4yM+7VUiuJbuPZHBeHZcNvXtziMMV9mRuvUOX8Vg9IFjRx9dUYM3s2oJyNx9ahFfSWwyRHKHG3nmL2q/mojyFVAWnEdi2Hg7OBXwUCCKr1QEtoe0+/9jI3xqIiuF2QRD0zqcwpfQnge9TVSI4tWrNe79shj98F0xDC0N4bTUVF5LPgAvJJ8dm+wcP2iJuZNdC5QAAAABJRU5ErkJggg==`,
|
||||||
width: 89,
|
width: 89,
|
||||||
height: 32,
|
height: 32,
|
||||||
|
|||||||
+21
-2
@@ -78,7 +78,7 @@ ul {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0 3px;
|
margin: 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item>div:hover {
|
.menu-item>div:hover {
|
||||||
@@ -261,6 +261,25 @@ ul {
|
|||||||
background-color: #ffff00;
|
background-color: #ffff00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-item .menu-item__title {
|
||||||
|
width: 60px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item__title .select {
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item__title i {
|
||||||
|
transform: translateX(-5px);
|
||||||
|
background-image: url('./assets/images/title.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item__title .options {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-item__left i {
|
.menu-item__left i {
|
||||||
background-image: url('./assets/images/left.svg');
|
background-image: url('./assets/images/left.svg');
|
||||||
}
|
}
|
||||||
@@ -467,7 +486,7 @@ ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-item__date .options {
|
.menu-item__date .options {
|
||||||
width: 150px;
|
width: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item__block i {
|
.menu-item__block i {
|
||||||
|
|||||||
Reference in New Issue
Block a user