import { Component, Emit } from 'vue-property-decorator'; import { EditorBase } from '../../../components'; import { VueLifeCycleProcessing, Watch } from '../../../decorators'; import './json-schema-form-editor.less'; /** * JsonSchema表单编辑器插件类 * * @export * @class JsonSchemaFormEditor * @extends {EditorBase} */ @Component({}) @VueLifeCycleProcessing() export class JsonSchemaFormEditor extends EditorBase { /** * 默认呈现模式 * * @author zhanghengfeng * @date 2023-08-10 18:08:39 * @type {('edit' | 'preview')} */ defaultMode: 'edit' | 'preview' = 'edit'; /** * 当前呈现模式 * * @author zhanghengfeng * @date 2023-08-10 18:08:51 * @type {('edit' | 'preview')} */ mode: 'edit' | 'preview' = 'edit'; /** * 表单数据 * * @author zhanghengfeng * @date 2023-08-10 18:08:43 * @type {Object} */ formData: Object = {}; /** * schema配置 * * @author zhanghengfeng * @date 2023-08-10 18:08:51 * @type {Object} */ schema: Object = {}; /** * 表单底部配置 * * @author zhanghengfeng * @date 2023-08-10 18:08:11 */ formFooter = { show: false, }; /** * 解析错误提示信息 * * @author zhanghengfeng * @date 2023-08-10 18:08:33 * @type {string} */ tips: string = ''; /** * 校验结果 * * @author zhanghengfeng * @date 2023-08-10 18:08:45 * @type {boolean} */ validateResult: boolean = true; /** * 表单数据Json * * @author zhanghengfeng * @date 2023-08-10 18:08:55 * @type {string} */ formDataJson: string = ''; /** * 值项名称 * * @author zhanghengfeng * @date 2023-08-10 19:08:25 * @type {string} */ valueItem: string = ''; /** * 值项的值 * * @author zhanghengfeng * @date 2023-08-10 19:08:51 * @type {string} */ valueItemJson: string = ''; /** * 编辑器change事件 * * @author zhanghengfeng * @date 2023-08-10 18:08:48 * @param {({ name: string; value: string | null })} _value */ @Emit('change') editorChange(_value: { name: string; value: string | null }): void {} /** * 编辑器change事件 * * @author zhanghengfeng * @date 2023-08-10 18:08:53 * @param {(string | null)} value */ handleChange(value: string | null) { this.editorChange({ name: this.editorInstance.name, value }); } /** * 编辑器enter事件 * * @author zhanghengfeng * @date 2023-08-10 18:08:03 */ handleEnter() { this.$emit('enter', arguments); } /** * 编辑器初始化 * * @author zhanghengfeng * @date 2023-08-10 18:08:14 */ async initEditorBase() { await super.initEditorBase(); const { editorParams } = this.editorInstance; if (editorParams) { const mode = editorParams.mode; if (mode === 'preview') { this.defaultMode = mode; this.mode = mode; } } const valueItems = this.editorInstance.M.getPSEditorItems; if (Array.isArray(valueItems) && valueItems.length) { this.valueItem = valueItems[0]?.name; this.onContextDataChange(); } } /** * 设置编辑器的自定义高宽 * * @author zhanghengfeng * @date 2023-08-10 18:08:23 */ setCustomStyle() { const { editorWidth, editorHeight } = this.editorInstance; this.customStyle = {}; this.customStyle.width = editorWidth > 0 ? `${editorWidth}px` : `auto`; this.customStyle.height = editorHeight > 300 ? `${editorHeight}px` : `300px`; } /** * 监听编辑器值变化 * * @author zhanghengfeng * @date 2023-08-10 18:08:47 * @return {*} */ @Watch('value', { immediate: true }) onValueChange() { if (this.value) { try { const value = JSON.parse(this.value); if (Object.prototype.toString.call(value) === '[object Object]') { this.schema = value; this.tips = ''; return; } } catch (err) {} } this.schema = {}; this.tips = 'Json Schema 解析错误'; } /** * 监听表单数据变化 * * @author zhanghengfeng * @date 2023-08-10 18:08:17 */ @Watch('formData', { immediate: true, deep: true }) onFormDataChange() { this.formDataJson = JSON.stringify(this.formData, null, 2); } /** * 监听上下文data数据变化 * * @author zhanghengfeng * @date 2023-08-11 09:08:36 */ @Watch('contextData', { immediate: true, deep: true }) onContextDataChange() { if (this.valueItem) { if (this.contextData) { const value = this.contextData[this.valueItem]; if (value) { if (value !== this.valueItemJson) { try { this.formData = JSON.parse(value); return; } catch (err) {} } else { return; } } } this.formData = {}; } } /** * 监听模式切换按钮点击 * * @author zhanghengfeng * @date 2023-08-10 18:08:33 */ onToggleButtonClick() { this.mode = this.mode === 'edit' ? 'preview' : 'edit'; if (!this.valueItem) { this.formData = {}; } } /** * 监听表单保存按钮点击 * * @author zhanghengfeng * @date 2023-08-10 18:08:16 * @return {*} */ async save() { const form = (this.$refs.form as unknown) as { $$uiFormRef: { validate: () => Promise } }; if (form) { try { await form.$$uiFormRef?.validate(); this.validateResult = true; if (this.valueItem) { this.valueItemJson = JSON.stringify(this.formData); this.editorChange({ name: this.valueItem, value: this.valueItemJson }); } return; } catch (err) {} } this.validateResult = false; } /** * 渲染编辑器 * * @author zhanghengfeng * @date 2023-08-10 18:08:41 * @return {*} */ renderEditor() { return this.$createElement('app-code-editor', { props: { name: this.editorInstance.name, value: this.value, disabled: this.disabled, language: 'json', isSetLanguage: true, ...this.customProps, }, on: { change: this.handleChange, enter: this.handleEnter, }, style: this.customStyle, }); } /** * 渲染预览表单 * * @author zhanghengfeng * @date 2023-08-10 18:08:49 * @return {*} */ renderForm() { return
{this.tips ? this.tips : }
; } render() { if (!this.editorIsLoaded) { return null; } return (
{this.defaultMode === 'edit' ? ( {this.mode === 'edit' ? '预览表单' : '返回编辑'} ) : null} {this.mode === 'edit' ? null : ( {this.validateResult && !this.valueItem ?
{this.formDataJson}
: null} 保存
)}
{this.mode === 'edit' ? this.renderEditor() : this.renderForm()}
); } }