@xw-components/formula-editor 18.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/formula-editor-icon.mjs +9 -0
- package/esm2022/formula-editor-request.service.mjs +18 -0
- package/esm2022/formula-editor.component.mjs +299 -0
- package/esm2022/formula-editor.mjs +5 -0
- package/esm2022/formula-editor.model.mjs +57 -0
- package/esm2022/formula-editor.service.mjs +318 -0
- package/esm2022/index.mjs +6 -0
- package/fesm2022/formula-editor.mjs +699 -0
- package/fesm2022/formula-editor.mjs.map +1 -0
- package/formula-editor-icon.d.ts +8 -0
- package/formula-editor-request.service.d.ts +33 -0
- package/formula-editor.component.d.ts +134 -0
- package/formula-editor.model.d.ts +40 -0
- package/formula-editor.service.d.ts +41 -0
- package/index.d.ts +5 -0
- package/package.json +29 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formula-editor.mjs","sources":["../../../../components/formula-editor/formula-editor-request.service.ts","../../../../components/formula-editor/formula-editor.model.ts","../../../../components/formula-editor/formula-editor.service.ts","../../../../components/formula-editor/formula-editor-icon.ts","../../../../components/formula-editor/formula-editor.component.ts","../../../../components/formula-editor/formula-editor.component.html","../../../../components/formula-editor/formula-editor.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { NzSafeAny } from 'ng-zorro-antd/core/types';\nimport { NzTreeNodeOptions } from 'ng-zorro-antd/tree';\n\nimport { Field, Func, ItemType } from './formula-editor.model';\nimport { ValidationResult } from './formula-editor.service';\n\nexport const FormulaEditorRequestServiceToken = new InjectionToken<FormulaEditorRequestService>('FormulaEditorRequestServiceToken');\n\n/**\n * 公式编辑器请求服务,用于获取函数列表、字段列表、指标列表和校验公式格式\n * 实现类需要实现四个方法。如果有部分方法不需要,可以实现空方法。\n */\nexport abstract class FormulaEditorRequestService {\n constructor() {}\n\n /**\n * 获取函数列表\n */\n abstract getFunctions(): Promise<NzTreeNodeOptions[]>;\n\n /**\n * 获取字段列表\n */\n abstract getFields(): Promise<Field[]>;\n\n /**\n * 校验公式格式\n * @param formula 公式字符串\n * @returns 校验结果\n */\n abstract validateFormula(formula: NzSafeAny): Promise<ValidationResult>;\n\n /**\n * 获取字段的描述\n * @param item 字段对象\n * @returns 描述字符串\n */\n getFieldDescription(): Promise<string> {\n return Promise.resolve('');\n }\n}\n","/**\n * 输入项类型,可选择指标模式或字段模式\n */\nexport enum ItemType {\n Field = 'field', // 字段模式\n Template = 'template' // 模板模式\n}\n\n/**\n * 输入校验格式方法\n */\nexport enum CheckFormatMethod {\n self = 'self', // 组件自带校验\n server = 'server' // 自定义异步校验\n}\n\nexport interface Field {\n id: string;\n name: string;\n image?: string; // 图标url\n icon?: string; // iconfont 图标名\n className?: string; // 类名,用于样式绑定\n description?: string; // 描述\n}\n\nexport interface Func {\n id: string;\n name: string;\n className?: string; // 类名,用于样式绑定\n description?: string; // 描述\n}\n\n/**\n * 函数列表模式,可选择列表或树模式\n */\nexport enum FuncListType {\n List = 'list', // 列表模式\n Tree = 'tree' // 树模式\n}\n\nexport const OPERATOR_LIST = [\n {\n type: 'add',\n name: '+',\n description: '加法'\n },\n {\n type: 'minus',\n name: '-',\n description: '减法'\n },\n {\n type: 'multiply',\n name: '*',\n description: '乘法'\n },\n {\n type: 'divide',\n name: '/',\n description: '除法'\n },\n {\n type: 'left-parenthesis',\n name: '(',\n description: '左括号'\n },\n {\n type: 'right-parenthesis',\n name: ')',\n description: '右括号'\n }\n];\n","import { style } from '@angular/animations';\nimport { inject, Injectable } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { Editor, Node, mergeAttributes } from '@tiptap/core';\nimport { NzSafeAny } from 'ng-zorro-antd/core/types';\nexport interface ValidationResult {\n isValid: boolean;\n errors: string[];\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class FormulaEditorService {\n private readonly sanitizer: DomSanitizer = inject(DomSanitizer);\n funcNode?: Node;\n fieldNode?: Node;\n paramNode?: Node;\n\n initNodes() {\n this.createFuncNode();\n this.createFieldNode();\n }\n\n createFieldNode() {\n this.fieldNode = Node.create({\n name: 'field',\n inline: true,\n group: 'inline',\n selectable: false,\n draggable: true,\n atom: true,\n addAttributes() {\n return {\n id: {\n default: null\n },\n name: {\n default: ''\n },\n className: {\n default: ''\n },\n dataType: {\n default: 'field'\n }\n };\n },\n renderText({ node }) {\n return `${node.attrs['name']}`;\n },\n parseHTML() {\n return [{ tag: 'div[data-type=\"field\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n return [\n 'div',\n mergeAttributes(\n {\n 'data-type': 'field',\n class: `field-node ${node.attrs['className']}` || '',\n contenteditable: 'false',\n style: `display: inline-block;margin: 0 4px;font-size: 13px;height: 18px;line-height: 18px;`\n },\n HTMLAttributes\n ),\n node.attrs['name']\n ];\n }\n });\n }\n\n createFuncNode() {\n this.funcNode = Node.create({\n name: 'func',\n inline: true,\n group: 'inline',\n selectable: false,\n draggable: false,\n content: 'inline*',\n atom: true,\n addAttributes() {\n return {\n id: {\n default: null\n },\n name: {\n default: ''\n },\n className: {\n default: ''\n },\n dataType: {\n default: 'func'\n }\n };\n },\n renderText({ node }) {\n const funcName = node.attrs['name'] || '';\n const childrenText = node.content.content\n .map(child => {\n if (child.text) {\n return child.text;\n }\n if (child.type && child.type.spec && child.type.spec['toText']) {\n return child.type.spec['toText']({ node: child });\n }\n return '';\n })\n .join('');\n return `${funcName}(${childrenText})`;\n },\n parseHTML() {\n return [{ tag: 'div[data-type=\"func\"]' }];\n },\n addNodeView() {\n return ({ node }) => {\n const createElement = (tag: string, props: Record<string, any> = {}) => {\n const element = document.createElement(tag);\n Object.entries(props).forEach(([key, value]) => {\n if (key === 'style') {\n Object.entries(value).forEach(([styleKey, styleValue]) => {\n (element.style as any)[styleKey] = styleValue;\n });\n } else if (key === 'innerText') {\n element.innerText = value;\n } else if (key === 'className') {\n element.className = value;\n } else {\n element.setAttribute(key, value);\n }\n });\n return element;\n };\n\n const className = node.attrs['className'] || '';\n const funcName = node.attrs['name'];\n\n const container = createElement('span', {\n style: {\n display: 'inline-block',\n margin: '0 4px',\n fontSize: '13px'\n }\n });\n\n const content = createElement('span', {\n style: {\n whiteSpace: 'pre-wrap',\n display: 'inline-block'\n },\n contenteditable: 'true'\n });\n\n const before = createElement('span', {\n innerText: `${funcName} `,\n contenteditable: 'false',\n className\n });\n\n const bracket = (value: string, style: Record<string, any> = {}) => {\n return createElement('span', {\n innerText: value,\n contenteditable: 'false',\n style: {\n ...style\n }\n });\n };\n\n container.append(before, bracket('(', { marginRight: '2px' }), content, bracket(')', { marginLeft: '2px' }));\n\n return {\n dom: container,\n contentDOM: content\n };\n };\n }\n });\n }\n\n /**\n * 校验公式的JSON表示是否有效\n * @param formula 公式的JSON表示\n * @returns 校验结果,包含是否有效和错误信息数组\n */\n public validateFormula(formula: any): ValidationResult {\n const errors: string[] = [];\n\n if (!formula) {\n errors.push('公式不能为空');\n return { isValid: false, errors };\n }\n\n if (formula.type !== 'doc') {\n errors.push('公式根节点类型必须是 doc');\n }\n\n if (!formula.content || !Array.isArray(formula.content)) {\n errors.push('公式必须包含 content 数组');\n return { isValid: false, errors };\n }\n\n for (const paragraph of formula.content) {\n if (paragraph.type !== 'paragraph') {\n errors.push('段落类型必须是 paragraph');\n continue;\n }\n\n if (!paragraph.content || !Array.isArray(paragraph.content)) {\n continue;\n }\n\n for (const node of paragraph.content) {\n this.validateNode(node, errors);\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors\n };\n }\n\n /**\n * 从JSON数据中提取内容文本或HTML\n * @param jsonData 公式的JSON表示\n * @param outputFormat 输出格式,'text'或'html',默认'text'\n * @returns 提取的内容文本或HTML字符串\n */\n public getContentFromJson(jsonData: NzSafeAny, outputFormat: 'text' | 'html' = 'text'): string | SafeHtml {\n if (!jsonData || !jsonData.content) return '';\n return outputFormat === 'html'\n ? this.sanitizer.bypassSecurityTrustHtml(this.processContentToHtml(jsonData.content))\n : this.processContent(jsonData.content);\n }\n\n private processContent(content: any[]): string {\n if (!content || !Array.isArray(content)) return '';\n return content.map(item => this.processNode(item)).join('');\n }\n\n private processNode(node: any): string {\n if (!node) return '';\n\n switch (node.type) {\n case 'func':\n return this.processFuncNode(node);\n case 'field':\n return `{${node.attrs?.name || ''}}`;\n case 'metric':\n return `[${node.attrs?.name || ''}]`;\n case 'text':\n return node.text || '';\n case 'paragraph':\n return this.processContent(node.content);\n case 'doc':\n return this.processContent(node.content);\n default:\n return '';\n }\n }\n\n private processFuncNode(node: any): string {\n const funcName = node.attrs?.name || '';\n const content = this.processContent(node.content);\n return `${funcName}(${content})`;\n }\n\n private processContentToHtml(content: any[]): string {\n if (!content || !Array.isArray(content)) return '';\n\n return content.map(item => this.processNodeToHtml(item)).join('');\n }\n\n private processNodeToHtml(node: any): string {\n if (!node) return '';\n\n switch (node.type) {\n case 'func':\n return this.processFuncNodeToHtml(node);\n case 'field':\n return `<span class=\"${node.attrs?.className || ''}\" style=\"display: inline-block; margin: 0 4px;height: 18px;line-height: 18px;\">${node.attrs?.name || ''}</span>`;\n case 'text':\n return this.escapeHtml(node.text || '');\n case 'paragraph':\n return this.processContentToHtml(node.content);\n case 'doc':\n return this.processContentToHtml(node.content);\n default:\n return '';\n }\n }\n\n private processFuncNodeToHtml(node: any): string {\n const funcName = node.attrs?.name || '';\n const className = node.attrs?.className || '';\n const content = this.processContentToHtml(node.content);\n\n return `<span style=\"display: inline-block; margin: 0 4px;\"><span contenteditable=\"false\" class=\"${className}\">${funcName}(</span><span style=\"white-space: pre-wrap; display: inline-block; margin: 0 4px;\" contenteditable=\"true\">${content}</span><span contenteditable=\"false\" class=\"${className}\">)</span></span>`;\n }\n\n private escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n private validateNode(node: any, errors: string[], path: string = ''): void {\n if (!node || !node.type) {\n return;\n }\n\n const currentPath = path ? `${path} > ${node.type}` : node.type;\n\n if (node.type === 'func') {\n this.validateFuncNode(node, errors, currentPath);\n }\n }\n\n private validateFuncNode(node: any, errors: string[], path: string): void {\n if (!node.content || !Array.isArray(node.content)) {\n return;\n }\n\n const content = node.content;\n const length = content.length;\n\n for (let i = 0; i < length; i++) {\n const currentItem = content[i];\n const nextItem = content[i + 1];\n\n if (currentItem.type === 'field' || currentItem.type === 'func') {\n if (i < length - 1) {\n if (nextItem && nextItem.type === 'text') {\n const text = nextItem.text || '';\n if (!text.startsWith(',')) {\n errors.push(`${path}: 参数之间必须用逗号分隔,位置 ${i + 1}`);\n }\n } else {\n errors.push(`${path}: 参数之间必须用逗号分隔,位置 ${i + 1}`);\n }\n }\n }\n\n if (currentItem.type === 'func') {\n this.validateFuncNode(currentItem, errors, `${path} > ${currentItem.attrs?.name || 'func'}`);\n }\n }\n }\n}\n","export const ICONS = {\r\n cheng: `<svg class=\"icon\" width=\"16px\" height=\"16px\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M460.8 896c-7.1 0-12.8-5.7-12.8-12.8V614.8L268.8 794c-5 5-13.1 5.1-18.1 0.1l-0.1-0.1-49.5-49.8c-5-5-5.1-13.1-0.1-18.1l0.1-0.1L383 544.1H140.8c-7.1 0-12.8-5.7-12.8-12.8v-70.4c0-7.1 5.7-12.8 12.8-12.8h239.4L200.9 268.9c-5-5-5.1-13.1-0.1-18.1l0.1-0.1 49.5-49.8c5-5 13.1-5.1 18.1-0.1l0.1 0.1 179.2 179.2V140.8c0-7.1 5.7-12.8 12.8-12.8H531c7.1 0 12.8 5.7 12.8 12.8v242.3L725.9 201c5-4.9 12.9-4.9 17.9 0l49.8 49.8c5 5 5.1 13.1 0.1 18.1l-0.1 0.1-179.2 179.1h268.4c7.1 0 12.8 5.7 12.8 12.8v70.4c0 7.1-5.7 12.8-12.8 12.8H611.6L793.5 726c5 5 5.1 13.1 0.1 18.1l-0.1 0.1-49.8 49.8c-5 4.9-12.9 4.9-17.9 0L543.7 611.8v271.6c0 7.1-5.7 12.8-12.8 12.8l-70.1-0.2z\" /></svg>`,\r\n chu: `<svg class=\"icon\" width=\"16px\" height=\"16px\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M808.3 283.6L283.6 808.3c-5 5-13.1 5-18.1 0l-49.8-49.8c-5-5-5-13.1 0-18.1l524.7-524.7c5-5 13.1-5 18.1 0l49.8 49.8c4.9 5 4.9 13.1 0 18.1z\" /></svg>`,\r\n jia: `<svg class=\"icon\" width=\"16px\" height=\"16px\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M476.8 896c-7.1 0-12.8-5.7-12.8-12.8V560H140.8c-7.1 0-12.8-5.7-12.8-12.8v-70.4c0-7.1 5.7-12.8 12.8-12.8H464V140.8c0-7.1 5.7-12.8 12.8-12.8h70.4c7.1 0 12.8 5.7 12.8 12.8V464h323.2c7.1 0 12.8 5.7 12.8 12.8v70.4c0 7.1-5.7 12.8-12.8 12.8H560v323.2c-0.2 7-5.8 12.7-12.8 12.8h-70.4z\" /></svg>`,\r\n jian: `<svg class=\"icon\" width=\"16px\" height=\"16px\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M140.8 464h742.4c7.1 0 12.8 5.7 12.8 12.8v70.4c0 7.1-5.7 12.8-12.8 12.8H140.8c-7.1 0-12.8-5.7-12.8-12.8v-70.4c0-7.1 5.7-12.8 12.8-12.8z\" /></svg>`,\r\n youkuohao: `<svg class=\"icon\" width=\"16px\" height=\"16px\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M416 163c38.7 49.3 68.8 104.8 88.9 164.1 19.8 59.6 29.7 122.1 29.3 184.9 1.1 62.3-8.5 124.2-28.4 183.2-23.2 59.2-53.3 115.4-89.8 167.4l56.9 33.3c42.9-56 76.8-118.4 100.4-184.9 23.2-64.1 34.9-131.8 34.7-199.9 0.3-69.3-11.4-138-34.7-203.3-23.2-65-57.2-125.8-100.4-179.8L416 163z\" /></svg>`,\r\n zuokuohao: `<svg class=\"icon\" width=\"16px\" height=\"16px\" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M608 163c-38.7 49.3-68.8 104.8-88.9 164.1-19.8 59.6-29.7 122.1-29.3 184.9-1.1 62.3 8.5 124.2 28.4 183.2 23.1 59.2 53.2 115.4 89.6 167.4L550.9 896c-42.8-56-76.6-118.4-100.2-184.9-23.2-64.1-34.9-131.8-34.7-199.9-0.3-69.3 11.4-138 34.7-203.3C473.9 242.8 507.9 182 551.1 128l56.9 35z\" /></svg>`\r\n};\r\n","import { CommonModule } from '@angular/common';\nimport { Component, effect, ElementRef, inject, input, signal, Signal, ViewChild, AfterViewInit, OnInit, TemplateRef } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Editor } from '@tiptap/core';\nimport StarterKit from '@tiptap/starter-kit';\nimport { NzButtonModule } from 'ng-zorro-antd/button';\nimport { NzHighlightPipe } from 'ng-zorro-antd/core/highlight';\nimport { NzColDirective, NzGridModule } from 'ng-zorro-antd/grid';\nimport { NzIconModule } from 'ng-zorro-antd/icon';\nimport { NzInputModule } from 'ng-zorro-antd/input';\nimport { NzMessageService } from 'ng-zorro-antd/message';\nimport { NzToolTipModule } from 'ng-zorro-antd/tooltip';\nimport { NzFormatEmitEvent, NzTreeModule, NzTreeNodeOptions } from 'ng-zorro-antd/tree';\n\nimport { FormulaEditorRequestService, FormulaEditorRequestServiceToken } from './formula-editor-request.service';\nimport { CheckFormatMethod, Field, Func, FuncListType, ItemType, OPERATOR_LIST } from './formula-editor.model';\nimport { FormulaEditorService, ValidationResult } from './formula-editor.service';\nimport { ICONS } from './formula-editor-icon';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n/**\n * 公式编辑器组件\n * 用于创建和编辑计算公式,支持函数、指标和字段的插入与验证\n * 依赖className与在使用组件处使用穿透样式实现样式\n */\n@Component({\n selector: 'app-formula-editor',\n standalone: true,\n imports: [\n NzColDirective,\n NzGridModule,\n NzInputModule,\n FormsModule,\n NzIconModule,\n CommonModule,\n NzTreeModule,\n NzButtonModule,\n NzToolTipModule,\n NzHighlightPipe\n ],\n templateUrl: './formula-editor.component.html',\n styleUrls: ['./formula-editor.component.less']\n})\nexport class FormulaEditorComponent implements AfterViewInit, OnInit {\n private readonly formulaEditorService = inject(FormulaEditorService);\n private readonly sanitizer = inject(DomSanitizer);\n private readonly msg = inject(NzMessageService);\n private readonly formulaEditorRequestService = inject<FormulaEditorRequestService>(FormulaEditorRequestServiceToken);\n @ViewChild('editor') editor!: ElementRef;\n\n /**\n * 项目类型,决定显示字段或自定义\n * 默认值:ItemType.Field\n */\n itemType = input<ItemType>(ItemType.Field);\n\n /**\n * 字段标题,当项目类型为字段时显示\n * 默认值:'字段'\n */\n fieldTitle = input<string>('字段');\n\n /**\n * 格式检查方法\n * 默认值:CheckFormatMethod.self\n */\n checkFormatMethod = input<CheckFormatMethod>(CheckFormatMethod.self);\n\n /**\n * 函数列表显示类型\n * 默认值:FuncListType.Tree\n */\n functionListType = input<FuncListType>(FuncListType.Tree);\n\n itemTemplate = input<TemplateRef<void> | null>(null);\n\n readonly _itemType = ItemType;\n readonly _funcListType = FuncListType;\n\n searchWord: string = '';\n\n fieldListOrigin: Field[] = [];\n fieldList: Field[] = [];\n\n editorObj!: Editor;\n checkLoading: boolean = false;\n showDescription: boolean = true;\n\n funcNode: NzTreeNodeOptions[] = [];\n fieldDescription: string = '';\n editDescription: string = '请选择函数';\n\n editDescShow: 'func' | 'error' | 'none' = 'none';\n\n searchField: Signal<string> = signal('');\n searchFunction: Signal<string> = signal('');\n\n _operatorList = OPERATOR_LIST;\n\n getOperatorIcon(type: string): string {\n const iconMap: Record<string, string> = {\n add: ICONS.jia,\n minus: ICONS.jian,\n multiply: ICONS.cheng,\n divide: ICONS.chu,\n 'left-parenthesis': ICONS.zuokuohao,\n 'right-parenthesis': ICONS.youkuohao\n };\n return this.sanitizer.bypassSecurityTrustHtml(iconMap[type] || '') as string;\n }\n\n /**\n * 构造函数\n * 初始化信号监听,处理搜索和项目类型变化\n */\n\n constructor() {\n effect(() => {\n const searchWord = this.searchField();\n this.fieldList = this.fieldListOrigin.filter(item => item.name.includes(searchWord));\n });\n effect(() => {\n const itemType = this.itemType();\n if (itemType === ItemType.Field) {\n this.formulaEditorRequestService.getFields().then(res => {\n this.fieldListOrigin = res;\n this.fieldList = [...this.fieldListOrigin];\n });\n }\n });\n }\n\n ngOnInit() {\n this.formulaEditorRequestService.getFunctions().then(res => {\n this.funcNode = res;\n });\n this.formulaEditorRequestService.getFieldDescription().then(res => {\n this.fieldDescription = res;\n });\n }\n\n ngAfterViewInit() {\n this.formulaEditorService.initNodes();\n this.editorObj = new Editor({\n element: this.editor.nativeElement,\n extensions: [\n StarterKit.configure({\n blockquote: false,\n codeBlock: false,\n code: false\n }),\n this.formulaEditorService.funcNode!,\n this.formulaEditorService.fieldNode!\n ]\n });\n }\n\n insertFunc(func: Func) {\n this.editorObj\n .chain()\n .insertContent({\n type: 'func',\n attrs: {\n name: func.name,\n id: func.id,\n className: `text-func-${func.className}`\n },\n content: []\n })\n .focus()\n .run();\n }\n\n insertField(field: Field) {\n this.editorObj\n .chain()\n .insertContent({\n type: 'field',\n attrs: {\n name: field.name,\n id: field.id,\n className: `text-field-${field.className}`\n }\n })\n .focus()\n .run();\n }\n\n insertOperator(operator: string) {\n this.editorObj\n .chain()\n .insertContent({\n type: 'text',\n text: operator\n })\n .focus()\n .run();\n }\n\n functionClick(node: NzFormatEmitEvent) {\n const func = node.node!.origin as unknown as Func;\n this.editDescription = func.description || '';\n this.editDescShow = 'func';\n this.insertFunc(func);\n }\n\n /**\n * 获取公式JSON\n * @returns 公式的JSON表示\n * @example\n * // 返回示例\n * {\n * \"type\": \"doc\",\n * \"content\": [\n * {\n * \"type\": \"paragraph\",\n * \"content\": [\n * {\n * \"type\": \"func\",\n * \"attrs\": {\n * \"name\": \"SUM\",\n * \"id\": \"sum\",\n * \"className\": \"text-func-agg\"\n * }\n * }\n * ]\n * }\n * ]\n * }\n */\n public getFormula() {\n const formula = this.editorObj.getJSON();\n return formula;\n }\n\n /**\n * 获取公式文本\n * @returns 公式的纯文本表示\n * @example\n * // 返回示例\n * \"SUM(field1, field2)\"\n */\n public getFormulaText() {\n const formulaText = this.editorObj.getText();\n return formulaText;\n }\n\n checkFormat() {\n if (this.checkFormatMethod() === CheckFormatMethod.self) {\n const result = this.validateFormula();\n if (result.isValid) {\n this.msg.success('格式校验通过');\n } else {\n this.msg.error(`格式校验不通过: ${result.errors.join(', ')}`);\n this.editDescription = result.errors.join(', ');\n this.editDescShow = 'error';\n }\n } else {\n this.checkLoading = true;\n this.formulaEditorRequestService.validateFormula(this.getFormula()).then(res => {\n this.checkLoading = false;\n if (res.isValid) {\n this.msg.success('格式校验通过');\n } else {\n this.msg.error(`格式校验不通过: ${res.errors.join(', ')}`);\n this.editDescription = res.errors.join(', ');\n this.editDescShow = 'error';\n }\n });\n }\n }\n\n /**\n * 从JSON加载公式\n * @param formula 公式的JSON表示\n * @example\n * // 使用示例\n * const formula = {\n * \"type\": \"doc\",\n * \"content\": [\n * {\n * \"type\": \"paragraph\",\n * \"content\": [\n * {\n * \"type\": \"func\",\n * \"attrs\": {\n * \"name\": \"SUM\",\n * \"id\": \"sum\",\n * \"className\": \"text-func-agg\"\n * }\n * }\n * ]\n * }\n * ]\n * };\n * formulaEditor.loadFormula(formula);\n */\n public loadFormula(formula: any) {\n if (!formula || !this.editorObj) {\n return;\n }\n this.editorObj.commands.setContent(formula);\n }\n\n // 校验公式\n validateFormula(): ValidationResult {\n const formula = this.editorObj.getJSON();\n const result = this.formulaEditorService.validateFormula(formula);\n return result;\n }\n\n toggleDescription() {\n this.showDescription = !this.showDescription;\n }\n}\n","<div nz-row class=\"formula-editor\">\n <div nz-col nzSpan=\"10\" class=\"editor-box\">\n <div class=\"editor-title\">\n <div class=\"label-title label-require\">字段表达式</div>\n <button nz-button nzType=\"link\" nzSize=\"small\" [nzLoading]=\"checkLoading\" (click)=\"checkFormat()\">格式校验</button>\n </div>\n <div class=\"edit-box\">\n <div class=\"edit-operation-box\">\n @for (item of _operatorList; track item) {\n <div class=\"edit-operation-item\" (click)=\"insertOperator(item.name)\">\n <span class=\"operator-icon\" [innerHTML]=\"getOperatorIcon(item.type)\"></span>\n </div>\n }\n </div>\n <div #editor class=\"editor\"></div>\n @if (editDescShow !== 'none') {\n <div class=\"edit-description-box\">\n <div class=\"edit-description-head\" [style]=\"{ marginBottom: !showDescription ? '10px' : '0' }\">\n <span class=\"edit-description-title\">{{ editDescShow === 'func' ? '函数释义' : '校验错误信息' }}</span>\n <span\n class=\"edit-description-icon\"\n nz-icon\n [nzType]=\"showDescription ? 'down' : 'up'\"\n nzTheme=\"outline\"\n (click)=\"toggleDescription()\"\n ></span>\n </div>\n @if (showDescription) {\n <div class=\"edit-description-text\"> {{ editDescription }} </div>\n }\n </div>\n }\n </div>\n </div>\n @switch (itemType()) {\n @case (_itemType.Field) {\n <div nz-col nzSpan=\"7\" class=\"field-box\">\n <div class=\"label-title\"\n >{{ fieldTitle() }}\n @if (fieldDescription) {\n <span nz-icon nzType=\"question-circle\" nzTheme=\"outline\" nz-tooltip [nzTooltipTitle]=\"fieldDescription\"></span>\n }\n </div>\n <nz-input-group [nzSuffix]=\"suffixIconSearch\">\n <input type=\"text\" nz-input placeholder=\"搜索\" [(ngModel)]=\"searchField\" />\n </nz-input-group>\n <ng-template #suffixIconSearch>\n <i nz-icon nzType=\"search\"></i>\n </ng-template>\n <div class=\"field-list\">\n @for (item of fieldList; track item) {\n <div (click)=\"insertField(item)\" [class]=\"item.className ? 'item-field-' + item.className : ''\" class=\"field-list-item\">\n @if (item.image) {\n <img class=\"field-img\" [src]=\"item.image\" />\n }\n @if (item.icon) {\n <span class=\"field-icon\" nz-icon [nzIconfont]=\"item.icon\"></span>\n }\n <span class=\"field-name\" [innerHTML]=\"item.name | nzHighlight: searchField() : 'i' : 'node-highlight'\"></span>\n @if (item.description) {\n <span\n class=\"desc-icon\"\n nz-icon\n nzType=\"question-circle\"\n nzTheme=\"outline\"\n nz-tooltip\n [nzTooltipTitle]=\"item.description\"\n ></span>\n }\n </div>\n }\n </div>\n </div>\n }\n @case (_itemType.Template) {\n <div nz-col nzSpan=\"7\" class=\"field-box\">\n <ng-container *ngTemplateOutlet=\"itemTemplate()\"></ng-container>\n </div>\n }\n }\n <div nz-col nzSpan=\"7\" class=\"function-box\">\n <div class=\"label-title\">函数</div>\n <nz-input-group [nzSuffix]=\"suffixIconSearch\">\n <input type=\"text\" nz-input placeholder=\"搜索\" [(ngModel)]=\"searchFunction\" />\n </nz-input-group>\n <ng-template #suffixIconSearch>\n <i nz-icon nzType=\"search\"></i>\n </ng-template>\n <nz-tree\n class=\"function-tree\"\n [nzHideUnMatched]=\"true\"\n [nzSearchValue]=\"searchFunction()\"\n [nzTreeTemplate]=\"nzTreeTemplate\"\n [nzData]=\"funcNode\"\n [nzShowExpand]=\"functionListType() === _funcListType.Tree\"\n (nzClick)=\"functionClick($event)\"\n ></nz-tree>\n <ng-template #nzTreeTemplate let-node let-origin=\"origin\">\n <span class=\"custom-node\" [innerHTML]=\"origin.name | nzHighlight: searchFunction() : 'i' : 'node-highlight'\">\n @if (origin.description) {\n <span\n class=\"desc-icon\"\n nz-icon\n nzType=\"question-circle\"\n nzTheme=\"outline\"\n nz-tooltip\n [nzTooltipTitle]=\"origin.description\"\n ></span>\n }\n </span>\n </ng-template>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import { NzSafeAny } from 'ng-zorro-antd/core/types';
|
|
3
|
+
import { NzTreeNodeOptions } from 'ng-zorro-antd/tree';
|
|
4
|
+
import { Field } from './formula-editor.model';
|
|
5
|
+
import { ValidationResult } from './formula-editor.service';
|
|
6
|
+
export declare const FormulaEditorRequestServiceToken: InjectionToken<FormulaEditorRequestService>;
|
|
7
|
+
/**
|
|
8
|
+
* 公式编辑器请求服务,用于获取函数列表、字段列表、指标列表和校验公式格式
|
|
9
|
+
* 实现类需要实现四个方法。如果有部分方法不需要,可以实现空方法。
|
|
10
|
+
*/
|
|
11
|
+
export declare abstract class FormulaEditorRequestService {
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* 获取函数列表
|
|
15
|
+
*/
|
|
16
|
+
abstract getFunctions(): Promise<NzTreeNodeOptions[]>;
|
|
17
|
+
/**
|
|
18
|
+
* 获取字段列表
|
|
19
|
+
*/
|
|
20
|
+
abstract getFields(): Promise<Field[]>;
|
|
21
|
+
/**
|
|
22
|
+
* 校验公式格式
|
|
23
|
+
* @param formula 公式字符串
|
|
24
|
+
* @returns 校验结果
|
|
25
|
+
*/
|
|
26
|
+
abstract validateFormula(formula: NzSafeAny): Promise<ValidationResult>;
|
|
27
|
+
/**
|
|
28
|
+
* 获取字段的描述
|
|
29
|
+
* @param item 字段对象
|
|
30
|
+
* @returns 描述字符串
|
|
31
|
+
*/
|
|
32
|
+
getFieldDescription(): Promise<string>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { ElementRef, Signal, AfterViewInit, OnInit, TemplateRef } from '@angular/core';
|
|
2
|
+
import { Editor } from '@tiptap/core';
|
|
3
|
+
import { NzFormatEmitEvent, NzTreeNodeOptions } from 'ng-zorro-antd/tree';
|
|
4
|
+
import { CheckFormatMethod, Field, Func, FuncListType, ItemType } from './formula-editor.model';
|
|
5
|
+
import { ValidationResult } from './formula-editor.service';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/**
|
|
8
|
+
* 公式编辑器组件
|
|
9
|
+
* 用于创建和编辑计算公式,支持函数、指标和字段的插入与验证
|
|
10
|
+
* 依赖className与在使用组件处使用穿透样式实现样式
|
|
11
|
+
*/
|
|
12
|
+
export declare class FormulaEditorComponent implements AfterViewInit, OnInit {
|
|
13
|
+
private readonly formulaEditorService;
|
|
14
|
+
private readonly sanitizer;
|
|
15
|
+
private readonly msg;
|
|
16
|
+
private readonly formulaEditorRequestService;
|
|
17
|
+
editor: ElementRef;
|
|
18
|
+
/**
|
|
19
|
+
* 项目类型,决定显示字段或自定义
|
|
20
|
+
* 默认值:ItemType.Field
|
|
21
|
+
*/
|
|
22
|
+
itemType: import("@angular/core").InputSignal<ItemType>;
|
|
23
|
+
/**
|
|
24
|
+
* 字段标题,当项目类型为字段时显示
|
|
25
|
+
* 默认值:'字段'
|
|
26
|
+
*/
|
|
27
|
+
fieldTitle: import("@angular/core").InputSignal<string>;
|
|
28
|
+
/**
|
|
29
|
+
* 格式检查方法
|
|
30
|
+
* 默认值:CheckFormatMethod.self
|
|
31
|
+
*/
|
|
32
|
+
checkFormatMethod: import("@angular/core").InputSignal<CheckFormatMethod>;
|
|
33
|
+
/**
|
|
34
|
+
* 函数列表显示类型
|
|
35
|
+
* 默认值:FuncListType.Tree
|
|
36
|
+
*/
|
|
37
|
+
functionListType: import("@angular/core").InputSignal<FuncListType>;
|
|
38
|
+
itemTemplate: import("@angular/core").InputSignal<TemplateRef<void> | null>;
|
|
39
|
+
readonly _itemType: typeof ItemType;
|
|
40
|
+
readonly _funcListType: typeof FuncListType;
|
|
41
|
+
searchWord: string;
|
|
42
|
+
fieldListOrigin: Field[];
|
|
43
|
+
fieldList: Field[];
|
|
44
|
+
editorObj: Editor;
|
|
45
|
+
checkLoading: boolean;
|
|
46
|
+
showDescription: boolean;
|
|
47
|
+
funcNode: NzTreeNodeOptions[];
|
|
48
|
+
fieldDescription: string;
|
|
49
|
+
editDescription: string;
|
|
50
|
+
editDescShow: 'func' | 'error' | 'none';
|
|
51
|
+
searchField: Signal<string>;
|
|
52
|
+
searchFunction: Signal<string>;
|
|
53
|
+
_operatorList: {
|
|
54
|
+
type: string;
|
|
55
|
+
name: string;
|
|
56
|
+
description: string;
|
|
57
|
+
}[];
|
|
58
|
+
getOperatorIcon(type: string): string;
|
|
59
|
+
/**
|
|
60
|
+
* 构造函数
|
|
61
|
+
* 初始化信号监听,处理搜索和项目类型变化
|
|
62
|
+
*/
|
|
63
|
+
constructor();
|
|
64
|
+
ngOnInit(): void;
|
|
65
|
+
ngAfterViewInit(): void;
|
|
66
|
+
insertFunc(func: Func): void;
|
|
67
|
+
insertField(field: Field): void;
|
|
68
|
+
insertOperator(operator: string): void;
|
|
69
|
+
functionClick(node: NzFormatEmitEvent): void;
|
|
70
|
+
/**
|
|
71
|
+
* 获取公式JSON
|
|
72
|
+
* @returns 公式的JSON表示
|
|
73
|
+
* @example
|
|
74
|
+
* // 返回示例
|
|
75
|
+
* {
|
|
76
|
+
* "type": "doc",
|
|
77
|
+
* "content": [
|
|
78
|
+
* {
|
|
79
|
+
* "type": "paragraph",
|
|
80
|
+
* "content": [
|
|
81
|
+
* {
|
|
82
|
+
* "type": "func",
|
|
83
|
+
* "attrs": {
|
|
84
|
+
* "name": "SUM",
|
|
85
|
+
* "id": "sum",
|
|
86
|
+
* "className": "text-func-agg"
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
* ]
|
|
90
|
+
* }
|
|
91
|
+
* ]
|
|
92
|
+
* }
|
|
93
|
+
*/
|
|
94
|
+
getFormula(): import("@tiptap/core").DocumentType<Record<string, any> | undefined, import("@tiptap/core").NodeType<string, Record<string, any> | undefined, any, (import("@tiptap/core").NodeType<any, any, any, any> | import("@tiptap/core").TextType<import("@tiptap/core").MarkType<any, any>>)[]>[]>;
|
|
95
|
+
/**
|
|
96
|
+
* 获取公式文本
|
|
97
|
+
* @returns 公式的纯文本表示
|
|
98
|
+
* @example
|
|
99
|
+
* // 返回示例
|
|
100
|
+
* "SUM(field1, field2)"
|
|
101
|
+
*/
|
|
102
|
+
getFormulaText(): string;
|
|
103
|
+
checkFormat(): void;
|
|
104
|
+
/**
|
|
105
|
+
* 从JSON加载公式
|
|
106
|
+
* @param formula 公式的JSON表示
|
|
107
|
+
* @example
|
|
108
|
+
* // 使用示例
|
|
109
|
+
* const formula = {
|
|
110
|
+
* "type": "doc",
|
|
111
|
+
* "content": [
|
|
112
|
+
* {
|
|
113
|
+
* "type": "paragraph",
|
|
114
|
+
* "content": [
|
|
115
|
+
* {
|
|
116
|
+
* "type": "func",
|
|
117
|
+
* "attrs": {
|
|
118
|
+
* "name": "SUM",
|
|
119
|
+
* "id": "sum",
|
|
120
|
+
* "className": "text-func-agg"
|
|
121
|
+
* }
|
|
122
|
+
* }
|
|
123
|
+
* ]
|
|
124
|
+
* }
|
|
125
|
+
* ]
|
|
126
|
+
* };
|
|
127
|
+
* formulaEditor.loadFormula(formula);
|
|
128
|
+
*/
|
|
129
|
+
loadFormula(formula: any): void;
|
|
130
|
+
validateFormula(): ValidationResult;
|
|
131
|
+
toggleDescription(): void;
|
|
132
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FormulaEditorComponent, never>;
|
|
133
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FormulaEditorComponent, "app-formula-editor", never, { "itemType": { "alias": "itemType"; "required": false; "isSignal": true; }; "fieldTitle": { "alias": "fieldTitle"; "required": false; "isSignal": true; }; "checkFormatMethod": { "alias": "checkFormatMethod"; "required": false; "isSignal": true; }; "functionListType": { "alias": "functionListType"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
134
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 输入项类型,可选择指标模式或字段模式
|
|
3
|
+
*/
|
|
4
|
+
export declare enum ItemType {
|
|
5
|
+
Field = "field",// 字段模式
|
|
6
|
+
Template = "template"
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 输入校验格式方法
|
|
10
|
+
*/
|
|
11
|
+
export declare enum CheckFormatMethod {
|
|
12
|
+
self = "self",// 组件自带校验
|
|
13
|
+
server = "server"
|
|
14
|
+
}
|
|
15
|
+
export interface Field {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
image?: string;
|
|
19
|
+
icon?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface Func {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
className?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 函数列表模式,可选择列表或树模式
|
|
31
|
+
*/
|
|
32
|
+
export declare enum FuncListType {
|
|
33
|
+
List = "list",// 列表模式
|
|
34
|
+
Tree = "tree"
|
|
35
|
+
}
|
|
36
|
+
export declare const OPERATOR_LIST: {
|
|
37
|
+
type: string;
|
|
38
|
+
name: string;
|
|
39
|
+
description: string;
|
|
40
|
+
}[];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SafeHtml } from '@angular/platform-browser';
|
|
2
|
+
import { Node } from '@tiptap/core';
|
|
3
|
+
import { NzSafeAny } from 'ng-zorro-antd/core/types';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export interface ValidationResult {
|
|
6
|
+
isValid: boolean;
|
|
7
|
+
errors: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class FormulaEditorService {
|
|
10
|
+
private readonly sanitizer;
|
|
11
|
+
funcNode?: Node;
|
|
12
|
+
fieldNode?: Node;
|
|
13
|
+
paramNode?: Node;
|
|
14
|
+
initNodes(): void;
|
|
15
|
+
createFieldNode(): void;
|
|
16
|
+
createFuncNode(): void;
|
|
17
|
+
/**
|
|
18
|
+
* 校验公式的JSON表示是否有效
|
|
19
|
+
* @param formula 公式的JSON表示
|
|
20
|
+
* @returns 校验结果,包含是否有效和错误信息数组
|
|
21
|
+
*/
|
|
22
|
+
validateFormula(formula: any): ValidationResult;
|
|
23
|
+
/**
|
|
24
|
+
* 从JSON数据中提取内容文本或HTML
|
|
25
|
+
* @param jsonData 公式的JSON表示
|
|
26
|
+
* @param outputFormat 输出格式,'text'或'html',默认'text'
|
|
27
|
+
* @returns 提取的内容文本或HTML字符串
|
|
28
|
+
*/
|
|
29
|
+
getContentFromJson(jsonData: NzSafeAny, outputFormat?: 'text' | 'html'): string | SafeHtml;
|
|
30
|
+
private processContent;
|
|
31
|
+
private processNode;
|
|
32
|
+
private processFuncNode;
|
|
33
|
+
private processContentToHtml;
|
|
34
|
+
private processNodeToHtml;
|
|
35
|
+
private processFuncNodeToHtml;
|
|
36
|
+
private escapeHtml;
|
|
37
|
+
private validateNode;
|
|
38
|
+
private validateFuncNode;
|
|
39
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FormulaEditorService, never>;
|
|
40
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<FormulaEditorService>;
|
|
41
|
+
}
|
package/index.d.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xw-components/formula-editor",
|
|
3
|
+
"version": "18.1.0",
|
|
4
|
+
"author": "shatong",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"ng-zorro-antd": "^18.2.1",
|
|
7
|
+
"@tiptap/core": "^3.16.0",
|
|
8
|
+
"@tiptap/pm": "^3.16.0",
|
|
9
|
+
"@tiptap/starter-kit": "^3.16.0",
|
|
10
|
+
"tslib": "^2.3.0"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"registry": "https://registry.npmjs.org/"
|
|
14
|
+
},
|
|
15
|
+
"module": "fesm2022/formula-editor.mjs",
|
|
16
|
+
"typings": "index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
"./package.json": {
|
|
19
|
+
"default": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./index.d.ts",
|
|
23
|
+
"esm2022": "./esm2022/formula-editor.mjs",
|
|
24
|
+
"esm": "./esm2022/formula-editor.mjs",
|
|
25
|
+
"default": "./fesm2022/formula-editor.mjs"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"sideEffects": false
|
|
29
|
+
}
|