| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252 |
- <template>
- <el-container class="FormMaking fm-form" :class="{
- ['fm-'+formKey]: true,
- 'is-fullscreen': fullscreen
- }" :style="{'--scrollbarWidth': scrollbarWidth, 'z-index': zIndex}">
- <el-main class="FormMaking-main">
- <el-container>
- <el-aside width="250px" class="widget-left-panel" ref="widgetLeftPanel">
- <el-tabs v-model="activeLeft" class="left-tabs" v-show="!leftHide">
- <el-tab-pane name="field">
- <template #label>
- <el-tooltip :content="$t('fm.actions.components')" placement="bottom-start">
- <span> <i class="fm-iconfont icon-yuanshuju-zujianku"></i> </span>
- </el-tooltip>
- </template>
- <el-scrollbar style="height: 100%;" class="vertical">
- <div class="components-list">
- <el-collapse v-model="activeFields">
- <el-collapse-item name="layout" v-if="layoutFields.length" :title="$t('fm.components.layout.title')">
- <draggable tag="ul" :list="layoutComponents"
- v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
- @end="handleMoveEnd"
- @start="handleMoveStart"
- :move="handleMove"
- >
- <li @click="handleField(item)" v-if="layoutFields.indexOf(item.type) >=0" class="form-edit-widget-label no-put" v-for="(item, index) in layoutComponents" :key="index">
- <a>
- <i class="icon fm-iconfont" :class="item.icon"></i>
- <span>{{item.name}}</span>
- </a>
- </li>
- </draggable>
- </el-collapse-item>
- <el-collapse-item name="collection" v-if="collectionFields.length" :title="$t('fm.components.collection.title')">
- <draggable tag="ul" :list="collectionComponents"
- v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
- @end="handleMoveEnd"
- @start="handleMoveStart"
- :move="handleMove"
- >
- <li @click="handleField(item)" v-if="collectionFields.indexOf(item.type) >=0" class="form-edit-widget-label no-put" v-for="(item, index) in collectionComponents" :key="index"
- :class="{
- 'subform-put': item.type == 'table' || item.type == 'subform',
- 'dialog-put': item.type == 'dialog'
- }"
- >
- <a>
- <i class="icon fm-iconfont" :class="item.icon"></i>
- <span>{{item.name}}</span>
- </a>
- </li>
- </draggable>
- </el-collapse-item>
- <el-collapse-item name="basic" v-if="basicFields.length" :title="$t('fm.components.basic.title')">
- <draggable tag="ul" :list="basicComponents"
- v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
- @end="handleMoveEnd"
- @start="handleMoveStart"
- :move="handleMove"
- >
- <li @click="handleField(item)" v-if="basicFields.indexOf(item.type)>=0" class="form-edit-widget-label" :class="{'no-put': item.type == 'divider'}" v-for="(item, index) in basicComponents" :key="index">
- <a>
- <i class="icon fm-iconfont" :class="item.icon"></i>
- <span>{{item.name}}</span>
- </a>
- </li>
- </draggable>
- </el-collapse-item>
- <el-collapse-item name="advance" v-if="advanceFields.length" :title="$t('fm.components.advance.title')">
- <draggable tag="ul" :list="advanceComponents"
- v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
- @end="handleMoveEnd"
- @start="handleMoveStart"
- :move="handleMove"
- >
- <li @click="handleField(item)" v-if="advanceFields.indexOf(item.type) >= 0" class="form-edit-widget-label"
- v-for="(item, index) in advanceComponents" :key="index">
- <a>
- <i class="icon fm-iconfont" :class="item.icon"></i>
- <span>{{item.name}}</span>
- </a>
- </li>
- </draggable>
- </el-collapse-item>
- <el-collapse-item name="custom" v-if="customFields.length" :title="$t('fm.components.custom.title')">
- <draggable tag="ul" :list="customComponents"
- v-bind="{group:{ name:'people', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}"
- @end="handleMoveEnd"
- @start="handleMoveStart"
- :move="handleMove"
- >
- <li @click="handleField(item)" class="form-edit-widget-label" v-for="(item, index) in customComponents" :key="index">
- <a>
- <i class="icon fm-iconfont custom" :class="item.icon ? '' : 'icon-extend'">
- <span v-html="item.icon" v-if="item.icon"></span>
- </i>
- <span>{{item.name}}</span>
- </a>
- </li>
- </draggable>
- </el-collapse-item>
- </el-collapse>
- </div>
- </el-scrollbar>
- </el-tab-pane>
- <el-tab-pane name="outline">
- <template #label>
- <el-tooltip :content="$t('fm.actions.outline')" placement="bottom">
- <span> <i class="fm-iconfont icon-fuhao-dagangshu"></i> </span>
- </el-tooltip>
- </template>
- <outline ref="outlineRef" :show="activeLeft == 'outline'" :data="widgetForm.list" @select="onSelectWidget"></outline>
- </el-tab-pane>
- </el-tabs>
- <div class="container-left-arrow" @click="handleLeftToggle"></div>
- </el-aside>
- <el-container class="center-container" direction="vertical">
- <el-header class="btn-bar" style="height: 45px;">
- <div class="btn-bar-plat">
- <!-- <a :class="{'active': platform == 'pc'}" @click="handlePlatform('pc')"><i class="fm-iconfont icon-pc"></i></a>-->
- <!-- <a :class="{'active': platform == 'pad'}" @click="handlePlatform('pad')"><i class="fm-iconfont icon-pad"></i></a>-->
- <a :class="{'active': platform == 'mobile'}" @click="handlePlatform('mobile')"><i class="fm-iconfont icon-mobile"></i></a>
- </div>
- <div class="btn-diviler"></div>
- <div class="btn-bar-action" v-if="showDo">
- <el-tooltip :content="$t('fm.actions.undo')" placement="bottom">
- <a @click="handleUndo" :class="{'disabled': !undo}"><i class="fm-iconfont icon-007caozuo_chexiao"></i></a>
- </el-tooltip>
- <el-tooltip :content="$t('fm.actions.redo')" placement="bottom">
- <a @click="handleRedo" :class="{'disabled': !redo}"><i class="fm-iconfont icon-8zhongzuo"></i></a>
- </el-tooltip>
- </div>
- <div class="btn-diviler" v-if="showDo"></div>
- <div class="btn-bar-action">
- <el-tooltip :content="$t('fm.actions.fullScreen')" placement="bottom" v-if="!fullscreen">
- <a @click="handleFullScreen"><i class="fm-iconfont icon-quanping_o"></i></a>
- </el-tooltip>
- <el-tooltip :content="$t('fm.actions.exitFullScreen')" placement="bottom" v-if="fullscreen">
- <a @click="handleExitFullScreen"><i class="fm-iconfont icon-quxiaoquanping_o"></i></a>
- </el-tooltip>
- </div>
- <slot name="action">
- </slot>
- <el-button v-if="upload" type="text" size="default" @click="handleUpload"><i class="fm-iconfont icon-daoru" style="font-size: 16px; font-weight: 600; margin: 5px;" />{{$t('fm.actions.import')}}</el-button>
- <el-button v-if="preview" type="text" size="default" @click="handlePreview"><i class="fm-iconfont icon-icon_yulan" style="font-size: 16px; font-weight: 600; margin: 5px;" />{{$t('fm.actions.preview')}}</el-button>
- <el-button v-if="clearable" type="text" size="default" @click="handleClear"><i class="fm-iconfont icon-qingkong" style="font-size: 16px; font-weight: 600; margin: 5px;" />{{$t('fm.actions.clear')}}</el-button>
- <el-button v-if="generateJson" type="text" size="default" @click="handleGenerateJson"><i class="fm-iconfont icon-json1" style="font-size: 16px; font-weight: 600; margin: 5px;" />{{$t('fm.actions.json')}}</el-button>
- <el-button v-if="generateCode" type="text" size="default" @click="handleGenerateCode"><i class="fm-iconfont icon-daimakuai" style="font-size: 16px; font-weight: 600; margin: 5px;" />{{$t('fm.actions.code')}}</el-button>
- </el-header>
- <el-main :class="{'widget-empty': widgetForm.list.length == 0}">
- <widget-form v-if="!resetJson" ref="widgetForm" :data="widgetForm" :select.sync="widgetFormSelect" :platform="platform" :form-key="formKey"></widget-form>
- </el-main>
- </el-container>
- <el-aside class="widget-config-container" ref="widgetConfigContainer">
- <el-container v-show="!rightHide">
- <el-header height="45px">
- <div class="config-tab" :class="{active: configTab=='widget'}" @click="handleConfigSelect('widget')">{{$t('fm.config.widget.title')}}</div>
- <div class="config-tab" :class="{active: configTab=='form'}" @click="handleConfigSelect('form')">{{$t('fm.config.form.title')}}</div>
- </el-header>
- <el-main class="config-content">
- <widget-config v-show="configTab=='widget'" ref="widgetConfig"
- :platform="platform"
- :sheets="styleSheetsArray"
- :datasources="dataSourceArray"
- :eventscripts="eventScriptArray"
- :data="widgetFormSelect"
- :key="formConfigKey"
- @on-event-add="handleEventAdd"
- @on-event-edit="handleEventEdit"
- @on-datasource-edit="handleDatasourceEdit"
- @on-class-edit="handleClassEdit"
- :form-key="formKey"
- :field-models="fieldModels"
- >
- <template #widgetconfig="{type, customProps, data}">
- <slot name="widgetconfig" :type="type" :customProps="customProps" :data="data"></slot>
- </template>
- </widget-config>
- <form-config v-show="configTab=='form'" ref="formConfig"
- :sheets="styleSheetsArray"
- :data="widgetForm.config"
- @on-style-update="onStyleUpdate"
- @on-datasource-update="onDataSourceUpdate"
- @on-eventscript-update="onEventScriptUpdate"
- @on-eventscript-confirm="onEventScriptConfirm"
- :form-key="formKey"
- ></form-config>
- </el-main>
- </el-container>
- <div class="container-right-arrow" @click="handleRightToggle"></div>
- </el-aside>
- <preview-dialog ref="previewDialog" @get-data-success="preivewGetData"></preview-dialog>
- <import-json-dialog ref="importJsonDialog" @load-json="handleLoadJson"></import-json-dialog>
- <cus-dialog
- :visible="jsonVisible"
- @on-close="jsonVisible = false"
- ref="jsonPreview"
- width="800px"
- form
- :title="jsonTitle"
- >
- <code-editor height="400px" mode="json" v-model="jsonTemplate"></code-editor>
- <template slot="action">
- <el-button type="primary" class="json-btn" :data-clipboard-text="jsonCopyValue">{{$t('fm.actions.copyData')}}</el-button>
- <el-button type="primary" @click="handleExportJSON">{{$t('fm.actions.export')}}</el-button>
- </template>
- </cus-dialog>
- <cus-dialog
- :visible="codeVisible"
- @on-close="codeVisible = false"
- ref="codePreview"
- width="800px"
- form
- :title="$t('fm.actions.code')"
- >
- <el-tabs type="border-card" style="box-shadow: none;" v-model="codeActiveName">
- <el-tab-pane label="Vue Component" name="vue">
- <code-editor height="450px" mode="html" v-model="vueTemplate"></code-editor>
- </el-tab-pane>
- <el-tab-pane label="HTML" name="html">
- <code-editor height="450px" mode="html" v-model="htmlTemplate"></code-editor>
- </el-tab-pane>
- </el-tabs>
- <template slot="action">
- <el-button type="primary" class="code-btn" :data-clipboard-text="codeCopyValue">{{$t('fm.actions.copyData')}}</el-button>
- <el-button type="primary" @click="handleExport">{{$t('fm.actions.export')}}</el-button>
- </template>
- </cus-dialog>
- </el-container>
- </el-main>
- <el-footer height="30px" style="font-weight: 600;"><a target="_blank" href="http://form.making.link">Powered by FormMaking {{version ? ` @ ${version}` : ''}}</a></el-footer>
- </el-container>
- </template>
- <script>
- import Draggable from 'vuedraggable'
- import WidgetConfig from './WidgetConfig'
- import FormConfig from './FormConfig'
- import WidgetForm from './WidgetForm'
- import CusDialog from './CusDialog'
- import GenerateForm from './GenerateForm'
- import AntdGenerateForm from './AntdvGenerator/GenerateForm'
- import Clipboard from 'clipboard'
- import CodeEditor from '../components/CodeEditor'
- import {basicComponents, layoutComponents, advanceComponents, collectionComponents} from './componentsConfig.js'
- import {updateStyleSheets, splitStyleSheets, splitSheetName, addClass, removeClass} from '../util/index.js'
- import { EventBus } from '../util/event-bus.js'
- import generateCode from './generateCode.js'
- import historyManager from '../util/history-manager.js'
- import _ from 'lodash'
- import { UpgradeData } from '../util/version-upgrade'
- import PreviewDialog from './PreviewDialog.vue'
- import ImportJsonDialog from './ImportJson/dialog.vue'
- import Outline from './Outline.vue'
- import { findModelNodeString } from '../util/find-node.js'
- import { getModels } from '../util/model-outline.js'
- import { Message } from 'element-ui'
- import {defaultDataSource} from './defaultWidgetForm'
- export default {
- name: 'fm-making-form',
- components: {
- Draggable,
- WidgetConfig,
- FormConfig,
- WidgetForm,
- CusDialog,
- GenerateForm,
- CodeEditor,
- AntdGenerateForm,
- PreviewDialog,
- ImportJsonDialog,
- Outline
- },
- props: {
- preview: {
- type: Boolean,
- default: false
- },
- generateCode: {
- type: Boolean,
- default: false
- },
- generateJson: {
- type: Boolean,
- default: false
- },
- upload: {
- type: Boolean,
- default: false
- },
- clearable: {
- type: Boolean,
- default: false
- },
- basicFields: {
- type: Array,
- default: () => ['input', 'textarea', 'number', 'radio', 'checkbox', 'time', 'date', 'rate', 'color', 'select', 'switch', 'slider', 'text', 'html', 'button', 'link', 'cascader', 'steps', 'pagination', 'transfer','deptAndUserCascader','deptCascader','deptSelect','userSelect','takeLeaveDate']
- },
- advanceFields: {
- type: Array,
- default: () => ['blank', 'component', 'fileupload', 'imgupload', 'editor']
- },
- layoutFields: {
- type: Array,
- default: () => ['grid', 'report', 'tabs', 'collapse', 'inline', 'card', 'divider', 'alert']
- },
- collectionFields: {
- type: Array,
- default: () => ['table', 'subform', 'dialog', 'group']
- },
- customFields: {
- type: Array,
- default: () => []
- },
- globalConfig: {
- type: Object,
- default: () => ({})
- },
- fieldConfig: {
- type: Array,
- default: () => []
- },
- name: {
- type: String,
- default: ''
- },
- cache: {
- type: Boolean,
- default: false
- },
- jsonTemplates: {
- type: Array,
- default: () => []
- },
- initFromTemplate: {
- type :Boolean,
- default: false
- },
- fieldModels: {
- type: Array,
- default: () => []
- },
- panel: {
- type: String,
- default: 'field'
- },
- zIndex: {
- type: Number,
- default: 2000
- }
- },
- data () {
- return {
- version: window.FormMaking_OPTIONS['version'],
- basicComponents,
- layoutComponents,
- advanceComponents,
- collectionComponents,
- customComponents: [],
- resetJson: false,
- widgetForm: {
- list: [],
- config: {
- labelWidth: 80,
- labelPosition: 'left',
- size: 'default',
- customClass: '',
- ui: 'element',
- layout: 'horizontal',
- width: '100%',
- hideLabel: false,
- hideErrorMessage: false,
- dataSource: []
- },
- },
- configTab: 'form',
- widgetFormSelect: null,
- previewVisible: false,
- jsonVisible: false,
- codeVisible: false,
- uploadVisible: false,
- blank: '',
- htmlTemplate: '',
- jsonTemplate: '',
- vueTemplate: '',
- uploadEditor: null,
- jsonCopyValue: '',
- jsonClipboard: null,
- codeCopyValue: '',
- codeClipboard: null,
- codeActiveName: 'vue',
- undo: false,
- redo: false,
- formKey: Math.random().toString(36).slice(-8),
- formConfigKey: Math.random().toString(36).slice(-8),
- styleSheetsArray: [],
- dataSourceArray: [],
- eventScriptArray: [],
- platform: 'mobile',
- activeFields: ['basic', 'advance', 'layout', 'custom', 'collection'],
- activeLeft: this.panel,
- isScrollTo: true,
- jsonTitle: this.$t('fm.actions.json'),
- modelNode: '',
- rightHide: false,
- leftHide: false,
- scrollbarWidth: '6px',
- fullscreen: false,
- showDo: false,
- dragging: false
- }
- },
- created () {
- this._loadComponents()
- },
- provide () {
- return {
- 'changeConfigTab': this.changeConfigTab,
- 'getModelNode': this.getModelNode,
- 'isMobile': this.isMobile,
- 'getFormModels': this.getFormModels,
- 'getFormFields': this.getFormFields,
- 'getDataSourceArray': this.getDataSourceArray,
- 'setDragging': this.setDragging,
- 'getDragging': this.getDragging
- }
- },
- mounted () {
- if (navigator.userAgent.indexOf("Firefox") !== -1) {
- // 当前浏览器是火狐浏览器
- this.scrollbarWidth = '17px'
- }
- if (navigator.userAgent.includes('Macintosh')) {
- // 当前操作系统为 macOS
- this.scrollbarWidth = '0px'
- }
- const _this = this
- // 添加表单默认事件
- this.widgetForm.config.eventScript = [
- {key: 'mounted', name: 'mounted', func: ''},
- {key: 'refresh', name: 'refresh', func: ''},
- {key: 'onFormChange', name: 'onFormChange', type: 'rule'}
- ]
- // 加载全局配置项
- this.widgetForm.config = {
- ...this.widgetForm.config,
- ...this.globalConfig
- }
- this.widgetForm.config.dataSource = defaultDataSource
- this.platform = this.widgetForm.config.platform || 'mobile'
- this.initConfig()
- this.cache && this.setJSON(localStorage.getItem('fmjson'+this.name) || this.widgetForm)
- this.$emit('ready')
- window.onbeforeunload = (e) => {
- this.saveJsonCache()
- }
- // 从模板导入
- if (this.initFromTemplate) {
- this.handleUpload()
- }
- historyManager.clear().then(() => {
- this.showDo = true
- EventBus.$on('on-history-add-' + this.formKey, () => {
- console.log('xxx', this.widgetFormSelect)
- historyManager.add(this.widgetForm, (this.widgetFormSelect && this.widgetFormSelect.key) ? this.widgetFormSelect.key : '').then(() => {
- _this.undo = true
- _this.redo = false
- })
- this.saveJsonCache()
- })
- })
- },
- beforeDestroy () {
- EventBus.$off('on-history-add-' + this.formKey)
- this.saveJsonCache()
- },
- methods: {
- setDragging (dragging) {
- this.dragging = dragging
- },
- getDragging () {
- return this.dragging
- },
- generatePreviewQrcode (url) {
- this.$refs.previewDialog.generateQrcode(url)
- },
- handleRightToggle () {
- if (this.rightHide) {
- removeClass(this.$refs['widgetConfigContainer'].$el, 'hide-status')
- this.rightHide = false
- } else {
- addClass(this.$refs['widgetConfigContainer'].$el, 'hide-status')
- this.rightHide = true
- }
- },
- handleLeftToggle () {
- if (this.leftHide) {
- removeClass(this.$refs['widgetLeftPanel'].$el, 'hide-status')
- this.leftHide = false
- } else {
- addClass(this.$refs['widgetLeftPanel'].$el, 'hide-status')
- this.leftHide = true
- }
- },
- saveJsonCache () {
- this.cache && localStorage.setItem('fmjson'+this.name, JSON.stringify(this.widgetForm))
- },
- removeJsonCache () {
- localStorage.setItem('fmjson'+this.name, JSON.stringify(this.widgetForm))
- },
- initConfig () {
- this.platform = this.widgetForm.config.platform || 'mobile'
- this.onStyleUpdate(splitStyleSheets(this.widgetForm.config.styleSheets || ''))
- console.log(this.widgetForm.config.dataSource);
- this.onDataSourceUpdate(this.widgetForm.config.dataSource || [])
- this.onEventScriptUpdate(this.widgetForm.config.eventScript || [])
- this.formConfigKey = Math.random().toString(36).slice(-8)
- },
- handleGoGithub () {
- window.location.href = 'https://github.com/GavinZhuLei/vue-form-making'
- },
- handleConfigSelect (value) {
- this.configTab = value
- },
- handleMoveEnd (evt) {
- console.log('end', evt)
- },
- handleMoveStart ({oldIndex}) {
- console.log('start', oldIndex, this.basicComponents)
- },
- handleMove () {
- return true
- },
- handlePreview () {
- this.$emit('preview', _.cloneDeep(this.widgetForm))
- this.$refs.previewDialog.preview(_.cloneDeep(this.widgetForm), this.platform)
- },
- preivewGetData (data) {
- this.jsonTitle = this.$t('fm.actions.getData')
- this.jsonVisible = true
- this.jsonTemplate = data
- this.$nextTick(() => {
- if (!this.jsonClipboard) {
- this.jsonClipboard = new Clipboard('.json-btn')
- this.jsonClipboard.on('success', (e) => {
- Message.success(this.$t('fm.message.copySuccess'))
- })
- }
- this.jsonCopyValue = JSON.stringify(data)
- })
- },
- handleGenerateJson () {
- this.jsonTitle = this.$t('fm.actions.json')
- this.jsonVisible = true
- this.jsonTemplate = this.widgetForm
- console.log(JSON.stringify(this.widgetForm))
- this.$nextTick(() => {
- if (!this.jsonClipboard) {
- this.jsonClipboard = new Clipboard('.json-btn')
- this.jsonClipboard.on('success', (e) => {
- Message.success(this.$t('fm.message.copySuccess'))
- })
- }
- this.jsonCopyValue = JSON.stringify(this.widgetForm)
- })
- },
- handleGenerateCode () {
- this.codeVisible = true
- this.htmlTemplate = generateCode(JSON.stringify(this.widgetForm), 'html', this.widgetForm.config.ui)
- this.vueTemplate = generateCode(JSON.stringify(this.widgetForm), 'vue', this.widgetForm.config.ui)
- this.$nextTick(() => {
- if (!this.codeClipboard) {
- this.codeClipboard = new Clipboard('.code-btn')
- this.codeClipboard.on('success', (e) => {
- Message.success(this.$t('fm.message.copySuccess'))
- })
- }
- this.codeCopyValue = this.codeActiveName == 'vue' ? this.vueTemplate : this.htmlTemplate
- })
- },
- handleUpload () {
- this.$refs.importJsonDialog.open(this.jsonTemplates)
- },
- handleLoadJson (json) {
- try {
- this.setLoadJSON(json)
- } catch (e) {
- Message.error(e.message)
- }
- },
- handleClear () {
- this.widgetForm = {
- ...this.widgetForm,
- list: [],
- }
- this.widgetFormSelect = {}
- this.$nextTick(() => {
- EventBus.$emit('on-history-add-' + this.formKey)
- })
- },
- clear () {
- this.handleClear()
- },
- getJSON () {
- return JSON.stringify(this.widgetForm)
- },
- getHtml () {
- return generateCode(JSON.stringify(this.widgetForm))
- },
- setJSON (json) {
- if (typeof json === 'string') {
- json = JSON.parse(json)
- }
- this.widgetForm = _.cloneDeep({
- ...json,
- list: json.list ? json.list.map(item => UpgradeData(item)) : []
- })
- if (this.widgetForm.config?.eventScript) {
- this.widgetForm.config.eventScript.findIndex(item => item.key === 'onFormChange') < 0
- && this.widgetForm.config.eventScript.unshift({key: 'onFormChange', name: 'onFormChange', type: 'rule'})
- this.widgetForm.config.eventScript.findIndex(item => item.key === 'refresh') < 0
- && this.widgetForm.config.eventScript.unshift({key: 'refresh', name: 'refresh', func: ''})
- this.widgetForm.config.eventScript.findIndex(item => item.key === 'mounted') < 0
- && this.widgetForm.config.eventScript.unshift({key: 'mounted', name: 'mounted', func: ''})
- }
- if (json.list.length> 0) {
- this.widgetFormSelect = this.widgetForm.list[0]
- } else {
- this.widgetFormSelect = {}
- }
- this.initConfig()
- this.$nextTick(() => { EventBus.$emit('on-history-add-' + this.formKey) })
- },
- setLoadJSON (json) {
- if (typeof json === 'string') {
- json = JSON.parse(json)
- }
- this.widgetForm = _.cloneDeep({
- ...json,
- config: {
- ...this.widgetForm.config,
- ...json.config,
- eventScript:[
- ...this.widgetForm.config.eventScript,
- ...json.config.eventScript,
- ]
- },
- list: json.list ? [ ...this.widgetForm.list,...json.list.map(item => UpgradeData(item))] : [...this.widgetForm.list]
- })
- if (this.widgetForm.config?.eventScript) {
- this.widgetForm.config.eventScript.findIndex(item => item.key === 'onFormChange') < 0
- && this.widgetForm.config.eventScript.unshift({key: 'onFormChange', name: 'onFormChange', type: 'rule'})
- this.widgetForm.config.eventScript.findIndex(item => item.key === 'refresh') < 0
- && this.widgetForm.config.eventScript.unshift({key: 'refresh', name: 'refresh', func: ''})
- this.widgetForm.config.eventScript.findIndex(item => item.key === 'mounted') < 0
- && this.widgetForm.config.eventScript.unshift({key: 'mounted', name: 'mounted', func: ''})
- }
- if (json.list.length> 0) {
- this.widgetFormSelect = this.widgetForm.list[0]
- } else {
- this.widgetFormSelect = {}
- }
- this.initConfig()
- this.$nextTick(() => { EventBus.$emit('on-history-add-' + this.formKey) })
- },
- handleInput (val) {
- console.log(val)
- this.blank = val
- },
- handleField (item) {
- if (item.type=='takeLeaveDate'){
- item.components.forEach((i,index) => {
- let nameObj = {
- 0:'开始时间',
- 1:'结束时间',
- 2:'天数',
- }
- i.name=nameObj[index]
- setTimeout(()=>{
- EventBus.$emit('on-field-add-' + this.formKey, i)
- })
- })
- }else {
- EventBus.$emit('on-field-add-' + this.formKey, item)
- }
- },
- handleUndo () {
- if (this.undo) {
- historyManager.updateLatest(this.widgetForm, (this.widgetFormSelect && this.widgetFormSelect.key) ? this.widgetFormSelect.key : '').then(() => {
- historyManager.undo().then((data) => {
- this.widgetForm = {...data.data}
- this.widgetFormSelect = this._findWidgetItem(this.widgetForm.list, data.key)
- this.undo = data.undo
- this.redo = data.redo
- this.initConfig()
- })
- })
- }
- },
- handleRedo () {
- if (this.redo) {
- historyManager.redo().then((data) => {
- this.widgetForm = {...data.data}
- this.widgetFormSelect = this._findWidgetItem(this.widgetForm.list, data.key)
- this.undo = data.undo
- this.redo = data.redo
- this.initConfig()
- })
- }
- },
- handleFullScreen() {
- this.fullscreen = true
- },
- handleExitFullScreen () {
- this.fullscreen = false
- },
- _findWidgetItem (list, key, type = 'key') {
- const index = list.findIndex(item => item[type] == key)
- if (index >= 0) {
- return list[index]
- } else {
- for (let m = 0; m < list.length; m++) {
- const item = list[m]
- if (item.type === 'grid') {
- let findItem = this._findWidgetItem(item.columns, key, type)
- if (findItem.key) {
- return findItem
- }
- for (let i = 0; i < item.columns.length; i++) {
- let findItem = this._findWidgetItem(item.columns[i].list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- }
- if (item.type === 'table') {
- let findItem = this._findWidgetItem(item.tableColumns, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- if (item.type === 'subform') {
- let findItem = this._findWidgetItem(item.list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- if (item.type === 'tabs') {
- for (let i = 0; i < item.tabs.length; i++) {
- let findItem = this._findWidgetItem(item.tabs[i].list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- }
- if (item.type === 'collapse') {
- for (let i = 0; i < item.tabs.length; i++) {
- let findItem = this._findWidgetItem(item.tabs[i].list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- }
- if (item.type === 'report') {
- for (let r = 0; r < item.rows.length; r++) {
- let findItem = this._findWidgetItem(item.rows[r].columns, key, type)
- if (findItem.key) {
- return findItem
- }
- for (let c = 0; c < item.rows[r].columns.length; c++) {
- let findItem = this._findWidgetItem(item.rows[r].columns[c].list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- }
- }
- if (item.type === 'inline') {
- let findItem = this._findWidgetItem(item.list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- if (item.type === 'dialog') {
- let findItem = this._findWidgetItem(item.list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- if (item.type === 'card') {
- let findItem = this._findWidgetItem(item.list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- if (item.type === 'group') {
- let findItem = this._findWidgetItem(item.list, key, type)
- if (findItem.key) {
- return findItem
- }
- }
- }
- return {}
- }
- },
- _loadComponents () {
- this.basicComponents = this.basicComponents.map(item => {
- return {
- ...item,
- name: this.$t(`fm.components.fields.${item.type}`),
- options: (() => {
- let newField = this.fieldConfig.find(o => o.type == item.type)
- if (newField) {
- return {...item.options, ...newField.options}
- } else {
- return {...item.options}
- }
- })()
- }
- })
- this.advanceComponents = this.advanceComponents.map(item => {
- return {
- ...item,
- name: this.$t(`fm.components.fields.${item.type}`),
- options: (() => {
- let newField = this.fieldConfig.find(o => o.type == item.type)
- if (newField) {
- return {...item.options, ...newField.options}
- } else {
- return {...item.options}
- }
- })()
- }
- })
- this.layoutComponents = this.layoutComponents.map(item => {
- return {
- ...item,
- name: this.$t(`fm.components.fields.${item.type}`),
- options: (() => {
- let newField = this.fieldConfig.find(o => o.type == item.type)
- if (newField) {
- return {...item.options, ...newField.options}
- } else {
- return {...item.options}
- }
- })()
- }
- })
- this.collectionComponents = this.collectionComponents.map(item => {
- return {
- ...item,
- name: this.$t(`fm.components.fields.${item.type}`),
- options: (() => {
- let newField = this.fieldConfig.find(o => o.type == item.type)
- if (newField) {
- return {...item.options, ...newField.options}
- } else {
- return {...item.options}
- }
- })()
- }
- })
- this.customComponents = this.customFields.map(item => {
- return {
- ...item,
- type: 'custom',
- options: (() => {
- let newField = this.fieldConfig.find(o => o.type == item.type)
- if (newField) {
- return {...item.options, ...newField.options}
- } else {
- return {...item.options}
- }
- })()
- }
- })
- },
- onStyleUpdate (sheets) {
- let head = '.fm-' + this.formKey + ' '
- updateStyleSheets(sheets, head)
- this.styleSheetsArray = splitSheetName(sheets)
- },
- onDataSourceUpdate (dataSource) {
- this.dataSourceArray = dataSource.map(item => ({
- value: item.key,
- label: item.name,
- args: item.args ? Object.fromEntries(item.args.map(o => [o, ''])) : {}
- }))
- },
- onEventScriptUpdate (eventScript) {
- this.eventScriptArray = eventScript.map(item => ({
- value: item.key,
- label: item.name
- }))
- },
- onEventScriptConfirm (eventObj) {
- this.$refs.widgetConfig.setEvent(eventObj)
- this.$nextTick(() => {
- EventBus.$emit('on-history-add-' + this.formKey)
- })
- },
- handlePlatform (platform) {
- this.widgetForm.config.platform = this.platform = platform
- },
- handleExport () {
- const fileName = (new Date().getTime()) + '.' + this.codeActiveName
- const fileData = this.codeActiveName == 'vue' ? this.vueTemplate : this.htmlTemplate
- this._exportFile(fileData, fileName)
- },
- handleExportJSON () {
- this._exportFile(JSON.stringify(this.jsonTemplate), (new Date().getTime()) + '.json')
- },
- handleClassEdit () {
- this.$refs.formConfig.editClass()
- },
- handleDatasourceEdit (datasource) {
- this.$refs.formConfig.editDatasource(datasource)
- },
- handleEventAdd (name) {
- this.$refs.formConfig.editScript(name)
- },
- handleEventEdit ({eventName, functionKey}) {
- this.$refs.formConfig.editScript(eventName, functionKey)
- },
- _exportFile (data, fileName) {
- let blob = new Blob([data], {
- type: 'application/octet-stream'
- })
- if(navigator.msSaveOrOpenBlob ){
- navigator.msSaveOrOpenBlob(blob, fileName);
- }else{
- // Create download link element
- let downloadLink = document.createElement("a");
- // Create a link to the file
- downloadLink.href = window.URL.createObjectURL(blob);
- // Setting the file name
- downloadLink.download = fileName;
- downloadLink.style.display = 'none'
- document.body.appendChild(downloadLink);
- //triggering the function
- downloadLink.click();
- document.body.removeChild(downloadLink);
- }
- },
- setSelect (field) {
- let selectWidget = this._findWidgetItem(this.widgetForm.list, field, 'model')
- if (selectWidget) {
- this.widgetFormSelect = selectWidget
- }
- },
- changeConfigTab (tab) {
- this.configTab = tab
- },
- onSelectWidget (key) {
- let selectWidget = this._findWidgetItem(this.widgetForm.list, key, 'key')
- if (selectWidget) {
- this.isScrollTo = false
- this.widgetFormSelect = selectWidget
- }
- setTimeout(() => {
- this.$refs.widgetForm.scrollTo()
- }, 200)
- },
- getModelNode () {
- return this.modelNode
- },
- isMobile () {
- return this.platform === 'mobile'
- },
- getFormModels () {
- return getModels(this.widgetForm.list)
- },
- getFormFields () {
- return this._getFormFields(this.widgetForm.list)
- },
- _getFormFields (list, group = '', parent = '') {
- let currentNode = []
- for (let i = 0; i < list.length; i++) {
- if (!list[i].type) continue
- const curLabel = parent
- ? [parent, `<${this.$t('fm.components.fields.' + list[i].type)}>${list[i].model || ''}`].join(' / ')
- : `<${this.$t('fm.components.fields.' + list[i].type)}>${list[i].model || ''}`
- currentNode.push({
- id: list[i].model ? ( group ? group + '.' + list[i].model : list[i].model ) : list[i].key,
- label: curLabel,
- icon: list[i].icon,
- type: list[i].type,
- model: list[i].model,
- children: [],
- disabled: (list[i].model ? false : true) || ['grid', 'report', 'tabs', 'collapse', 'inline', 'card', 'divider', 'alert'].includes(list[i].type),
- hideDisabled: list[i].model ? false : true,
- dataBind: list[i].options?.dataBind,
- options: list[i].options,
- setdataDisabled: (list[i].model ? false : true) || ['grid', 'report', 'tabs', 'collapse', 'inline', 'card', 'divider', 'alert', 'button', 'link'].includes(list[i].type),
- remoteOptionDisabled: !list[i].options.remote,
- dynamicValueDisabled: !list[i].options.isDynamicValue,
- dialogDisabled: list[i].type !== 'dialog',
- optionDisabled: !(list[i].type == 'steps' || list[i].type == 'transfer' || Object.keys(list[i].options).indexOf('options')>=0 )
- })
- if (list[i].type == 'grid') {
- currentNode[i].children = this._getFormFields(list[i].columns, group, curLabel)
- }
- if (list[i].type == 'col') {
- currentNode[i].children = this._getFormFields(list[i].list, group, curLabel)
- }
- if (list[i].type == 'report') {
- let reportList = []
- for (let r = 0; r < list[i].rows.length; r++) {
- for (let c = 0; c < list[i].rows[r].columns.length; c++) {
- let td = list[i].rows[r].columns[c]
- if (!td.options.invisible) {
- reportList.push(td)
- }
- }
- }
- currentNode[i].children = this._getFormFields(reportList, group, curLabel)
- }
- if (list[i].type == 'td') {
- currentNode[i].children = this._getFormFields(list[i].list, group, curLabel)
- }
- if (list[i].type == 'tabs') {
- for (let t = 0; t < list[i].tabs.length; t++) {
- currentNode[i].children.push({
- label: list[i].tabs[t].label,
- children: [],
- disabled: true,
- id: Math.random().toString(36).slice(-8),
- setdataDisabled: true,
- remoteOptionDisabled: true,
- dialogDisabled: true
- })
- currentNode[i].children[t].children = this._getFormFields(list[i].tabs[t].list, group, curLabel)
- }
- }
- if (list[i].type == 'collapse') {
- for (let t = 0; t < list[i].tabs.length; t++) {
- currentNode[i].children.push({
- label: list[i].tabs[t].title,
- children: [],
- disabled: true,
- id: Math.random().toString(36).slice(-8),
- setdataDisabled: true,
- remoteOptionDisabled: true,
- dialogDisabled: true
- })
- currentNode[i].children[t].children = this._getFormFields(list[i].tabs[t].list, group, curLabel)
- }
- }
- if (list[i].type == 'inline') {
- currentNode[i].children = this._getFormFields(list[i].list, group, curLabel)
- }
- if (list[i].type == 'table') {
- let curGroup = group ? group + '.' + list[i].model : list[i].model
- currentNode[i].children = this._getFormFields(list[i].tableColumns, curGroup, curLabel)
- }
- if (list[i].type == 'subform') {
- let curGroup = group ? group + '.' + list[i].model : list[i].model
- currentNode[i].children = this._getFormFields(list[i].list, curGroup, curLabel)
- }
- if (list[i].type == 'dialog') {
- let curGroup = group ? group + '.' + list[i].model : list[i].model
- currentNode[i].children = this._getFormFields(list[i].list, curGroup, curLabel)
- }
- if (list[i].type == 'card') {
- currentNode[i].children = this._getFormFields(list[i].list, group, curLabel)
- }
- if (list[i].type == 'group') {
- let curGroup = group ? group + '.' + list[i].model : list[i].model
- currentNode[i].children = this._getFormFields(list[i].list, curGroup, curLabel)
- }
- if (!(currentNode[i].children && currentNode[i].children.length)) {
- delete currentNode[i].children
- }
- }
- return currentNode
- },
- getDataSourceArray () {
- return _.cloneDeep(this.dataSourceArray)
- }
- },
- watch: {
- '$i18n.locale': function (val) {
- this._loadComponents()
- },
- codeActiveName (val) {
- this.codeCopyValue = this.codeActiveName == 'vue' ? this.vueTemplate : this.htmlTemplate
- },
- widgetFormSelect (val) {
- val.key && this.$refs.outlineRef?.setCurrentKey(val.key, this.isScrollTo)
- this.isScrollTo = true
- this.modelNode = findModelNodeString(this.widgetForm.list, 'key', val.key)
- },
- activeLeft (val) {
- if (val == 'outline') {
- this.widgetFormSelect?.key && this.$refs.outlineRef?.setCurrentKey(this.widgetFormSelect.key, this.isScrollTo)
- }
- },
- 'widgetFormSelect.key': function (val) {
- this.formConfigKey = Math.random().toString(36).slice(-8)
- }
- }
- }
- </script>
- <style lang="scss">
- .widget-empty{
- background-position: 50%;
- }
- .custom1 .el-col{
- border: 1px solid #ccc;
- overflow: hidden;
- padding: 5px;
- // margin-right:-1px;
- // margin-bottom:-1px;
- margin-right: -1px;
- margin-bottom: -1px;
- }
- .custom .el-col{
- border-top: 1px solid #ccc;
- border-left: 1px solid #ccc;
- }
- .fm2-container{
- .el-scrollbar{
- .el-scrollbar__wrap{
- height: calc(100% + var(--scrollbarWidth));
- width: calc(100% + var(--scrollbarWidth));
- }
- }
- }
- </style>
|