FormScript.vue 4.84 KB
<template>
  <el-dialog title="表单脚本" :close-on-click-modal="false"
    class="NCC-dialog NCC-dialog_center form-script-dialog" lock-scroll append-to-body
    v-bind="$attrs" width="1100px" :modal-append-to-body="false" v-on="$listeners" @open="onOpen">
    <div class="form-script-dialog-body">
      <div class="left-tree">
        <el-tree :data="treeData" default-expand-all :expand-on-click-node="false"
          :props="treeProps" @node-click="handleNodeClick"></el-tree>
      </div>
      <div class="right-main">
        <div class="codeEditor">
          <NCCCodeEditor v-model="text" :options="options" ref="CodeEditor" />
        </div>
        <div class="tips">
          <p>请从左侧面板选择的字段名,支持JavaScript的脚本,参考编写脚本API</p>
          <p>data--当前组件的选中值,formData--表单数据,setFormData--设置表单某个组件数据(prop,value)</p>
          <p>
            setShowOrHide--设置显示或隐藏(prop,value),setRequired--设置必填项(prop,value),setDisabled--设置禁用项(prop,value)
          </p>
          <p>
            request--异步请求(url,method,data),getFieldOptions--获取选项(prop),setFieldOptions--设置选项(prop,value)
          </p>
        </div>
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="closeDialog">{{$t('common.cancelButton')}}</el-button>
      <el-button type="primary" @click="onClose()">{{$t('common.confirmButton')}}</el-button>
    </span>
  </el-dialog>
</template>

<script>
import NCCCodeEditor from '@/components/NCCEditor/monaco'
export default {
  components: { NCCCodeEditor },
  props: ['tpl', 'fields'],
  inject: ["getFormInfo"],
  data() {
    return {
      text: '',
      treeData: [],
      treeProps: {
        children: 'children',
        label: 'label',
      },
      treeData: [],
      options: {
        language: 'javascript'
      },
    }
  },
  watch: {
    keyword(val) {
      this.search()
    },
    activeName(val) {
      if (this.keyword) {
        this.keyword = ''
      } else {
        this.search()
      }
    }
  },
  methods: {
    onOpen() {
      this.text = this.tpl
      this.getTree()
      this.$nextTick(() => {
        this.$refs.CodeEditor.changeEditor({
          value: this.text,
          options: this.options
        })
      });
    },
    getTree() {
      let list = []
      const loop = (data, parent) => {
        if (!data) return
        if (data.__config__ && data.__config__.nccKey !== 'table' && data.__config__.children && Array.isArray(data.__config__.children)) {
          loop(data.__config__.children, data)
        }
        if (Array.isArray(data)) data.forEach(d => loop(d, parent))
        if (data.__vModel__) {
          if (data.__config__.nccKey === 'table') {
            let item = {
              value: data.__vModel__,
              label: data.__config__.label,
              children: []
            }
            let children = []
            if (data.__config__.children && Array.isArray(data.__config__.children) && data.__config__.children.length) {
              for (let i = 0; i < data.__config__.children.length; i++) {
                const child = data.__config__.children[i]
                children.push({ value: child.__vModel__, label: child.__config__.label })
              }
            }
            item.children = children
            list.push(item)
          } else {
            list.push({ value: data.__vModel__, label: data.__config__.label })
          }
        }
      }
      loop(this.fields)
      let topItem = {
        value: +new Date(),
        label: this.getFormInfo().fullName,
        top: true,
        children: list
      }
      this.treeData = [topItem]
    },
    onClose() {
      this.$emit('updateScript', this.text)
      this.closeDialog()
    },
    closeDialog() {
      this.$emit('update:visible', false)
    },
    handleNodeClick(item, node) {
      if (item.top) return
      this.$refs.CodeEditor.insert(item.value);
    }
  }
}
</script>
<style lang="scss" scoped>
.form-script-dialog {
  >>> .el-dialog .el-dialog__body {
    padding: 20px 20px 10px;
  }
  .form-script-dialog-body {
    height: 600px;
    display: flex;

    .left-tree {
      height: 600px;
      width: 220px;
      flex-shrink: 0;
      margin-right: 10px;
    }
    .right-main {
      height: 600px;
      flex: 1;
      display: flex;
      flex-direction: column;
      .codeEditor {
        flex: 1;
        border: 1px solid #dcdfe6;
      }
      .tips {
        flex-shrink: 0;
        padding: 8px 16px;
        background-color: #ecf8ff;
        border-radius: 4px;
        border-left: 5px solid #50bfff;
        margin-top: 20px;
        p {
          line-height: 24px;
          color: #5e6d82;
          span {
            display: inline-block;
            padding-right: 10px;
          }
        }
      }
    }
  }
}
</style>