소스 검색

地图选址组件

yangfan 2 달 전
부모
커밋
b5af294eca

+ 236 - 0
src/components/Generator/components/JNPFMap/index.vue

@@ -0,0 +1,236 @@
+<template>
+  <div>
+    <el-input placeholder="请输入内容" v-model="innerValue" v-on="$listeners">
+      <template slot="append"><el-button icon="el-icon-location" @click="isShow = true" size="small"></el-button></template>
+    </el-input>
+    <div v-if="$attrs.expandMode && this.innerValue" id="mapDiv1" style="width: 100%; height: 200px"></div>
+    <vxe-modal v-if="isShow" v-model="isShow" title="地图选址" width="80%" height="70%">
+      <div class="flex flex-between" style="width: 100%; height: 100%">
+        <div style="width: 260px; margin-right: 20px">
+          <el-tabs v-model="activeName">
+            <el-tab-pane label="基本信息" name="first">
+              <el-form>
+                <el-form-item label="自定义位置">
+                  <div class="flex" style="gap: 5px">
+                    <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" v-model="keywordAddress" />
+                    <el-button @click="search">确定</el-button>
+                  </div>
+                </el-form-item>
+                <el-form-item label="经度">
+                  {{ mapObject.lon }}
+                </el-form-item>
+                <el-form-item label="纬度">
+                  {{ mapObject.lat }}
+                </el-form-item>
+                <el-form-item label="地址">
+                  {{ mapObject.formatted_address }}
+                </el-form-item>
+                <el-form-item>
+                  <el-button type="primary" @click="submit">确定</el-button>
+                  <el-button @click="isShow = false">取消</el-button>
+                </el-form-item>
+              </el-form>
+            </el-tab-pane>
+            <el-tab-pane label="搜索位置" name="second">
+              <el-input v-model="keywordAddress" @input="getKeywordAddress" placeholder="请输入地址" />
+              <div @click="setPostion(item)" style="padding: 5px; cursor: pointer" v-for="item in searchResultList">
+                {{ item.name }}
+              </div>
+            </el-tab-pane>
+          </el-tabs>
+        </div>
+        <div style="height: 100%; width: 100%; flex: 1 1 0">
+          <div id="mapDiv" style="width: 100%; height: 100%"></div>
+        </div>
+      </div>
+    </vxe-modal>
+  </div>
+</template>
+
+<script>
+// 动态加载外部链接
+export function loadJS(url) {
+  return new Promise((resolve) => {
+    const script = document.createElement('script')
+    script.type = 'text/javascript'
+    script.src = url
+    // IE
+    if (script.readyState) {
+      script.onreadystatechange = () => {
+        if (script.readyState == 'loaded' || script.readyState == 'complete') {
+          script.onreadystatechange = null
+          resolve()
+        }
+      }
+    } else {
+      // 其他浏览器
+      script.onload = function () {
+        resolve()
+      }
+    }
+    document.getElementsByTagName('head')[0].appendChild(script)
+  })
+}
+let map,
+  zoom = 12,
+  geocode,
+  marker,
+  localsearch
+export default {
+  name: 'JNPFMap',
+  props: ['value'],
+  model: {
+    prop: 'value',
+    event: 'change'
+  },
+  data() {
+    return {
+      isShow: false,
+      activeName: 'first',
+      options: [],
+      innerValue: this.value,
+      keywordAddress: '',
+      searchResultList: [],
+      mapObject: {
+        lon: 116.40769,
+        lat: 39.89945,
+        addressComponent: {},
+        formatted_address: ''
+      }
+    }
+  },
+  async mounted() {
+    await loadJS('http://api.tianditu.gov.cn/api?v=4.0&tk=a4dc3ba4fde4085083ab82395af6c046')
+  },
+  watch: {
+    isShow(val) {
+      if (val) {
+        setTimeout(() => {
+          if (this.innerValue) {
+            const lon = this.innerValue.split(this.$attrs.keepSeparator)[0]
+            const lat = this.innerValue.split(this.$attrs.keepSeparator)[1]
+            this.mapObject.lon = lon
+            this.mapObject.lat = lat
+          }
+          if (!map) {
+            map = new T.Map('mapDiv')
+            map.centerAndZoom(new T.LngLat(this.mapObject.lon, this.mapObject.lat), zoom)
+            marker = new T.Marker(new T.LngLat(this.mapObject.lng, this.mapObject.lat))
+            //向地图上添加标注
+            map.addOverLay(marker)
+            // 清楚标注
+          } else {
+            map = new T.Map('mapDiv')
+            map.clearOverLays()
+            map.centerAndZoom(new T.LngLat(this.mapObject.lon, this.mapObject.lat), zoom)
+            marker = new T.Marker()
+            marker.setLngLat(new T.LngLat(this.mapObject.lon, this.mapObject.lat))
+            map.addOverLay(marker)
+          }
+
+          geocode = new T.Geocoder()
+          this.addMapMoveend()
+          this.addMapMove()
+
+          const config = {
+            pageCapacity: 10, //每页显示的数量
+            onSearchComplete: this.localSearchResult //接收数据的回调函数
+          }
+          //创建搜索对象
+          localsearch = new T.LocalSearch(map, config)
+        }, 500)
+      }
+    },
+    innerValue(val) {
+      val && this.$emit('change', val)
+      if (val) {
+        if (this.$attrs.expandMode) {
+          setTimeout(() => {
+            const lon = val.split(this.$attrs.keepSeparator)[0]
+            const lat = val.split(this.$attrs.keepSeparator)[1]
+            const map1 = new T.Map('mapDiv1')
+            map1.centerAndZoom(new T.LngLat(lon, lat), zoom)
+            marker = new T.Marker(new T.LngLat(lon, lat))
+            //向地图上添加标注
+            map1.addOverLay(marker)
+          }, 500)
+        }
+      }
+    },
+    value(val) {
+      this.innerValue = val
+    }
+  },
+
+  methods: {
+    getKeywordAddress(value) {
+      if (value) {
+        localsearch.search(value, 4)
+      }
+    },
+    localSearchResult(data) {
+      this.searchResultList = data.suggests
+      console.log(data)
+    },
+    addMapMove() {
+      //移除地图的移动停止事件
+      map.addEventListener('drag', this.MapMove)
+    },
+    addMapMoveend() {
+      //移除地图的移动停止事件
+      this.removeMapMoveend()
+      map.addEventListener('dragend', this.MapMoveend)
+    },
+    removeMapMoveend() {
+      //移除地图的移动停止事件
+      map.removeEventListener('drag', this.MapMove)
+      map.removeEventListener('dragend', this.MapMoveend)
+    },
+    searchResult(e) {
+      this.mapObject.addressComponent = e.addressComponen
+      this.mapObject.formatted_address = e.formatted_address
+    },
+    MapMove(e) {
+      marker.setLngLat(new T.LngLat(e.target.getCenter().getLng(), e.target.getCenter().getLat()))
+    },
+    MapMoveend(e) {
+      geocode.getLocation(e.target.getCenter(), this.searchResult)
+      this.mapObject.lon = e.target.getCenter().getLng()
+      this.mapObject.lat = e.target.getCenter().getLat()
+      marker.setLngLat(new T.LngLat(this.mapObject.lon, this.mapObject.lat))
+      // //向地图上添加标注
+      map.addOverLay(marker)
+    },
+    search() {
+      map.clearOverLays()
+      geocode.getPoint(this.keywordAddress, (result) => {
+        map.panTo(result.getLocationPoint(), zoom)
+        marker.setLngLat(new T.LngLat(result.location.lon, result.location.lat))
+        map.addOverLay(marker)
+        this.mapObject.lon = result.location.lon
+        this.mapObject.lat = result.location.lat
+        this.mapObject.formatted_address = this.keywordAddress
+      })
+    },
+    setPostion(item) {
+      item.lon = item.lonlat.split(',')[0]
+      item.lat = item.lonlat.split(',')[1]
+      map.panTo(new T.LngLat(item.lon, item.lat), zoom)
+      marker.setLngLat(new T.LngLat(item.lon, item.lat))
+      map.addOverLay(marker)
+      this.mapObject.lon = item.lon
+      this.mapObject.lat = item.lat
+      this.mapObject.formatted_address = item.name
+    },
+    submit() {
+      this.isShow = false
+      this.innerValue = [this.mapObject.lon, this.mapObject.lat].join(this.$attrs.keepSeparator)
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.address-cascader {
+  width: 100%;
+}
+</style>

+ 9 - 5
src/components/Generator/components/NewInput/index.vue

@@ -1,8 +1,13 @@
 <template>
   <div class="JNPFInput">
-    <div class="JNPFInput-input">
-      <el-input style="width: 99% !important" v-model="innerValue" :debounce="2000" @input="getChange" v-bind="$attrs"></el-input>
-    </div>
+    <template v-if="$attrs.isScan">
+      <div class="JNPFInput-input">
+        <el-input style="width: 99% !important" v-model="innerValue" :debounce="2000" @input="getChange" v-bind="$attrs"></el-input>
+      </div>
+    </template>
+    <template v-else>
+      <el-input style="width: 99% !important" v-model="innerValue" :debounce="2000" v-on="$listeners" v-bind="$attrs"></el-input>
+    </template>
     <div v-if="$attrs.isScan" class="JNPFInput-scan">
       <svg data-v-217a6391="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgba(24,144,255,1)">
         <path data-v-217a6391="" d="M15 3H21V8H19V5H15V3ZM9 3V5H5V8H3V3H9ZM15 21V19H19V16H21V21H15ZM9 21H3V16H5V19H9V21ZM3 11H21V13H3V11Z"></path>
@@ -37,7 +42,6 @@ export default {
   },
   mounted() {
     this.isScan = this.$attrs.isScan
-    console.log(this.$attrs.isScan)
     // console.log(this.$listeners.input(1111111))
     // document.onkeydown = (e) => {
     //   if (e.keyCode === 13) {
@@ -60,7 +64,7 @@ export default {
       // if (this.$attrs.propsUrl && val) {
       // this.$emit('change', val)
       //   console.log(val)
-        this.$listeners.input(val)
+      this.$listeners.input(val)
       // }
     },
     setValue() {

+ 24 - 21
src/components/Generator/generator/config.js

@@ -34,7 +34,7 @@ export const inputComponents = [
       label: '单行输入',
       labelWidth: undefined,
       showLabel: true,
-      tag: 'NewInput',
+      tag: 'newInput',
       tagIcon: 'icon-ym icon-ym-generator-input',
       defaultValue: undefined,
       required: false,
@@ -809,27 +809,30 @@ export const inputComponents = [
     },
     h: 6,
     placeholder: '请输入内容...'
+  },
+  {
+    __config__: {
+      jnpfKey: 'JNPFMap',
+      label: '地图选址',
+      labelWidth: undefined,
+      showLabel: true,
+      tag: 'JNPFMap',
+      tagIcon: 'icon-ym icon-ym-generator-rich-text',
+      defaultValue: null,
+      required: false,
+      layout: 'colFormItem',
+      span: 24,
+      dragDisabled: false,
+      regList: [],
+      trigger: 'blur',
+      viewDataType: 'STRING'
+    },
+    h: 6,
+    placeholder: '请输入内容...',
+    keepSeparator: ',',
+    expandMode: false,
+    expandHeight: 200
   }
-  // {
-  //   __config__: {
-  //     jnpfKey: 'JNPFMap',
-  //     label: '地图选址',
-  //     labelWidth: undefined,
-  //     showLabel: true,
-  //     tag: 'JNPF-Map',
-  //     tagIcon: 'icon-ym icon-ym-generator-rich-text',
-  //     defaultValue: null,
-  //     required: false,
-  //     layout: 'colFormItem',
-  //     span: 24,
-  //     dragDisabled: false,
-  //     regList: [],
-  //     trigger: 'blur',
-  //     viewDataType: 'STRING'
-  //   },
-  //   h: 6,
-  //   placeholder: '请输入内容...'
-  // }
 ]
 
 // 高级控件 【左面板】

+ 711 - 0
src/components/Generator/index/RightComponents/ComNewInput.vue

@@ -0,0 +1,711 @@
+<template>
+  <el-row>
+    <p v-if="activeData.__vModel__ && activeData.__config__.viewDataType !== 'STRING'" style="color: #ff0000; font-size: 12px; margin-bottom: 18px">
+      {{
+        '提示:当前绑定控件字段 「 ' +
+        activeData.__config__.label +
+        ' 」 为 ' +
+        activeData.__config__.viewDataType +
+        ' 类型,使用单行文本可能会造成录入信息错误,如需使用单行文本请添加数据类型校验!!!'
+      }}
+    </p>
+    <el-form-item label="控件标题">
+      <el-input v-model="activeData.__config__.label" placeholder="请输入控件标题" />
+    </el-form-item>
+    <el-form-item label="占位提示">
+      <el-input v-model="activeData.placeholder" placeholder="请输入占位提示" />
+    </el-form-item>
+    <template v-if="!activeData.__config__.isSubTable">
+      <el-form-item label="控件栅格">
+        <el-slider v-model="activeData.__config__.span" :max="24" :min="6" show-stops :step="2" show-tooltip />
+      </el-form-item>
+      <el-form-item label="标题宽度">
+        <el-input-number v-model="activeData.__config__.labelWidth" placeholder="标题宽度" :min="0" :precision="0" controls-position="right" />
+      </el-form-item>
+    </template>
+    <el-form-item label="控件宽度" v-if="activeData.__config__.isSubTable">
+      <el-input-number v-model="activeData.__config__.columnWidth" placeholder="控件宽度" :min="0" :precision="0" controls-position="right" />
+    </el-form-item>
+    <el-form-item>
+      <template slot="label">
+        <span>自动填写</span>
+        <el-tooltip style="cursor: pointer" effect="dark" :content="'设置指定规则,将结果自动填写到字段输入框中'" placement="top">
+          <i class="el-icon-question" />
+        </el-tooltip>
+      </template>
+      <el-select v-model="activeData.__config__.inputType" @change="activeData.defaultVarType = []" placeholder="请选择">
+        <el-option label="指定数值" :value="1">
+          <span>指定数值</span>
+          <el-tooltip style="cursor: pointer" effect="dark" :content="'创建数据时将指定数值自动输入'" placement="top">
+            <i class="el-icon-question" />
+          </el-tooltip>
+        </el-option>
+        <el-option label="自定义表达式" :value="2">
+          <span>自定义表达式</span>
+          <el-tooltip style="cursor: pointer" effect="dark" :content="'通过函数和本表其他字段的运算结果自动填入,被引用的字段值改变时不会改变当前字段值'" placement="top">
+            <i class="el-icon-question" />
+          </el-tooltip>
+        </el-option>
+        <el-option label="页面变量" :value="4">
+          <span>页面变量</span>
+          <el-tooltip style="cursor: pointer" effect="dark" :content="'通过页面内定义变量值结果自动填入'" placement="top">
+            <i class="el-icon-question" />
+          </el-tooltip>
+        </el-option>
+      </el-select>
+    </el-form-item>
+    <el-form-item label="指定数值" v-if="activeData.__config__.inputType === 1">
+      <el-input :value="setDefaultValue(activeData.__config__.defaultValue)" placeholder="请输入默认值" @input="onDefaultValueInput" />
+    </el-form-item>
+    <el-form-item label="自定义表达" v-if="activeData.__config__.inputType === 2">
+      <customExpression :defaultValueExp="activeData.defaultValueExp" @onChangeExp="setDefaultValExp" :dbLinkId="dbLinkId" :drawList="drawList" :activeData="activeData" />
+    </el-form-item>
+    <el-form-item label="选择变量" v-if="activeData.__config__.inputType === 4">
+      <el-cascader ref="varCascader" @change="varchange" v-model="activeData.defaultVarType" :options="varTypeList" @visible-change="allVarListChange"></el-cascader>
+    </el-form-item>
+    <el-form-item v-if="(activeData.__config__.inputType === 4 && cascaderTypeshow) || activeData.cascaderType">
+      <template slot="label">
+        <span>选择层级</span>
+        <el-tooltip style="cursor: pointer" effect="dark" :content="'适用于级联组件全局变量,可配置选择层级'" placement="top">
+          <i class="el-icon-question" />
+        </el-tooltip>
+      </template>
+      <el-select v-model="activeData.cascaderType" placeholder="请选择">
+        <el-option label="子节点值" value="son"></el-option>
+        <el-option label="父节点值" value="topLeve"></el-option>
+      </el-select>
+    </el-form-item>
+    <el-form-item label="前缀">
+      <el-input v-model="activeData.__slot__.prepend" placeholder="请输入前缀" />
+    </el-form-item>
+    <el-form-item label="后缀">
+      <el-input v-model="activeData.__slot__.append" placeholder="请输入后缀" />
+    </el-form-item>
+    <el-form-item label="前图标">
+      <el-input v-model="activeData['prefix-icon']" placeholder="请输入前图标名称">
+        <el-button slot="append" @click="openIconsDialog('prefix-icon')"> 选择 </el-button>
+      </el-input>
+    </el-form-item>
+    <el-form-item label="后图标">
+      <el-input v-model="activeData['suffix-icon']" placeholder="请输入后图标名称">
+        <el-button slot="append" @click="openIconsDialog('suffix-icon')"> 选择 </el-button>
+      </el-input>
+    </el-form-item>
+    <el-form-item label="最多输入">
+      <el-input v-model="activeData.maxlength" placeholder="请输入字符长度" type="number">
+        <template slot="append">个字符</template>
+      </el-input>
+    </el-form-item>
+    <!-- <el-form-item label="显示标签">
+      <el-switch v-model="activeData.__config__.showLabel" />
+    </el-form-item> -->
+    <!-- <el-form-item label="输入统计">
+      <el-switch v-model="activeData['show-word-limit']" />
+    </el-form-item> -->
+    <!-- <el-form-item label="能否清空">
+      <el-switch v-model="activeData.clearable" />
+    </el-form-item> -->
+    <el-form-item>
+      <template slot="label">
+        <span>应用变量</span>
+        <el-tooltip style="cursor: pointer" effect="dark" :content="'将当前组件应用为表单内全局变量'" placement="top">
+          <i class="el-icon-question" />
+        </el-tooltip>
+      </template>
+      <el-switch v-model="activeData.allVar" />
+    </el-form-item>
+    <el-form-item label="是否密码">
+      <el-switch v-model="activeData['show-password']" />
+    </el-form-item>
+    <el-form-item label="是否只读">
+      <el-switch v-model="activeData.readonly" />
+    </el-form-item>
+    <el-form-item label="是否禁用">
+      <el-switch v-model="activeData.disabled" />
+    </el-form-item>
+    <el-form-item label="是否隐藏">
+      <el-switch v-model="activeData.displayNone" />
+    </el-form-item>
+    <el-form-item label="是否URL">
+      <el-switch v-model="activeData.isUrl" />
+    </el-form-item>
+    <el-form-item label="只做展示">
+      <el-switch
+        v-model="activeData.isText"
+        @change="
+          activeData.__vModel__ = 'isOnlyRead_' + +new Date()
+          activeData.__vModelName__ = 'isOnlyRead_' + +new Date()
+        "
+      />
+    </el-form-item>
+    <el-form-item label="别名展示">
+      <el-switch v-model="activeData.anotherName" />
+      <el-button
+        v-if="activeData.anotherName"
+        style="margin-left: 100px"
+        size="mini"
+        icon="el-icon-plus"
+        @click="activeData.anotherNameList.push({ realValue: '', anotherName: '', columnBackgroundColor: null })"
+        >添加</el-button
+      >
+    </el-form-item>
+    <columnAnotherName v-if="activeData.anotherName" :anotherNameList="activeData.anotherNameList" />
+    <el-form-item label="开启扫码">
+      <el-switch v-model="activeData.isScan" />
+    </el-form-item>
+    <template>
+      <el-form-item label="" label-width="40px">
+        <el-radio-group v-model="activeData.__config__.dataType" size="small" style="text-align: center" @change="dataTypeChange">
+          <!--          <el-radio-button label="static">静态数据</el-radio-button>-->
+          <!--          <el-radio-button label="dictionary">数据字典</el-radio-button>-->
+          <el-radio-button label="dynamic">API数据</el-radio-button>
+        </el-radio-group>
+      </el-form-item>
+      <template v-if="activeData.__config__.dataType === 'dynamic'">
+        <el-form-item label="API数据">
+          <el-cascader
+            :options="dataInterfaceSelector"
+            v-model="activeData.__config__.propsUrl"
+            placeholder="请选择API数据"
+            :filter-method="apiFilterMethod"
+            :props="{ expandTrigger: 'hover', emitPath: false }"
+            :show-all-levels="false"
+            @change="propsUrlChange"
+            clearable
+            filterable
+          >
+          </el-cascader>
+        </el-form-item>
+        <el-divider v-if="activeData.__config__.ApiParams && activeData.__config__.ApiParams.length">API输入参数设置</el-divider>
+        <el-form-item class="varFormItem" v-for="(param, i) of activeData.__config__.ApiParams" :key="i" :label="param.name + ' ' + param.key">
+          <el-cascader v-model="param.varType" :options="varTypeList"></el-cascader>
+          <el-input v-if="param.varType == 1 && param.datatype === 'string'" v-model="param.def"></el-input>
+          <el-input v-if="param.varType == 1 && param.datatype === 'number'" v-model="param.def" type="number"></el-input>
+          <el-date-picker v-if="param.varType == 1 && param.datatype === 'date'" v-model="param.def" placeholder="选择日期" type="date" value-format="yyyyMMdd"></el-date-picker>
+          <el-date-picker v-if="param.varType == 1 && param.datatype === 'month'" v-model="param.def" placeholder="选择月" type="month" value-format="yyyyMM"></el-date-picker>
+          <el-time-picker v-if="param.varType == 1 && param.datatype === 'time'" v-model="param.def" placeholder="选择时间" value-format="HH:mm:ss"></el-time-picker>
+          <el-date-picker v-if="param.varType == 1 && param.datatype === 'timestamp'" v-model="param.def" placeholder="选择日期" type="date" value-format="timestamp"></el-date-picker>
+          <el-time-picker v-if="param.varType == 1 && param.datatype === 'timestamp'" v-model="param.def" placeholder="选择时间" value-format="timestamp"></el-time-picker>
+        </el-form-item>
+        <el-divider>API返回值设置</el-divider>
+        <el-form-item>
+          <template slot="label">
+            <span>组件设置:</span>
+            <el-tooltip style="cursor: pointer" effect="dark" :content="'当前组件设置,指定API返回值某一项作为key或value'" placement="top">
+              <i class="el-icon-question" />
+            </el-tooltip>
+          </template>
+          <el-button size="mini" type="primary" plain @click="previewClick" icon="View">API返回值结构预览</el-button>
+        </el-form-item>
+        <template v-if="activeData.__config__.ApiReturn && activeData.__config__.ApiReturn.length">
+          <el-form-item>
+            <template slot="label">
+              <span>变量设置:</span>
+              <el-tooltip style="cursor: pointer" effect="dark" :content="'当前页面变量设置,从API返回值结构预览中选择一或多个类作为变量'" placement="top">
+                <i class="el-icon-question" />
+              </el-tooltip>
+            </template>
+          </el-form-item>
+          <el-table :data="activeData.__config__.ApiReturn" style="width: 100%">
+            <el-table-column prop="keyName" label="API返回值"></el-table-column>
+            <el-table-column label="页面变量名">
+              <template slot-scope="scope">
+                <el-input @input="varNamefitlte(scope.row, $event)" v-model="scope.row.varName" placeholder="请输入页面变量名" />
+                <div v-if="varNamefitlteclass(scope.row, scope.row.varName)" style="color: red">变量名重复 重新输入</div>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="50">
+              <template slot-scope="scope">
+                <div class="close-btn select-line-icon" style="cursor: pointer" @click="activeData.__config__.ApiReturn.splice(scope.$index, 1)">
+                  <i class="el-icon-delete" />
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+        </template>
+      </template>
+      <!--      <el-divider />-->
+    </template>
+    <el-divider>校验</el-divider>
+    <el-form-item label="是否必填">
+      <el-switch v-model="activeData.__config__.required" />
+    </el-form-item>
+    <div v-for="(item, index) in activeData.__config__.regList" :key="index" class="reg-item">
+      <span class="close-btn" @click="activeData.__config__.regList.splice(index, 1)">
+        <i class="el-icon-close" />
+      </span>
+      <el-form-item label="表达式">
+        <el-input v-model="item.pattern" placeholder="请输入正则" />
+      </el-form-item>
+      <el-form-item label="错误提示" style="margin-bottom: 0">
+        <el-input v-model="item.message" placeholder="请输入错误提示" />
+      </el-form-item>
+    </div>
+    <div class="mt-10">
+      <el-dropdown>
+        <el-button type="primary">添加常用校验<i class="el-icon-arrow-down el-icon--right"></i> </el-button>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item @click.native="addHandle(item)" v-for="(item, i) in ruleList" :key="i"> {{ item.label }}</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+      <el-button type="primary" @click="addReg" style="margin-left: 10px"> 自定义规则 </el-button>
+    </div>
+    <iconBox :visible.sync="iconsVisible" :current="activeData[currentIconModel]" @choiceIcon="setIcon" />
+    <el-dialog :visible.sync="previewShow" title="API数据结构预览" width="800px" append-to-body class="source-http-preview">
+      <el-table :data="previewArr" border row-key="path" default-expand-all>
+        <el-table-column label="结构">
+          <template #default="scope">
+            {{ scope.row.key }}
+          </template>
+        </el-table-column>
+        <el-table-column label="类型" width="100px" align="center">
+          <template #default="scope">
+            {{ scope.row.type }}
+          </template>
+        </el-table-column>
+        <el-table-column label="jsonpath">
+          <template #default="scope">
+            {{ scope.row.path }}
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="140px" align="center">
+          <template #default="scope">
+            <el-button v-if="scope.row.type === 'array'" size="small" type="primary" plain @click="getAllPath(scope.row)"> 使用全部子项 </el-button>
+            <el-button v-if="scope.row.type !== 'array' && scope.row.type !== 'object'" size="small" type="primary" plain @click="getPath(scope.row)"> 使用 </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </el-row>
+</template>
+<script>
+import iconBox from '@/components/JNPF-iconBox'
+import customExpression from '@/components/Generator/index/RightComponents/customExpression'
+import columnAnotherName from '@/components/Generator/index/RightComponents/componets/columnAnotherName'
+import comMixin from './mixin'
+import { loopActiveTabelList, loopRelationList, loopRelationTabelList } from '@/utils'
+import { dataapicategoryList, dataapiDetail, dataapiList } from '@/api/systemData/dataInterface'
+import { getparamsys, paramList } from '@/api/newbi/globalParams'
+import { getAPIData } from '@/components/Dataset-filter/util'
+import { openurl } from '@/components/Dataset-filter/report'
+import { param } from '@/components/Dataset-filter/config'
+export default {
+  props: ['activeData', 'dbLinkId', 'drawList'],
+  mixins: [comMixin],
+  components: { iconBox, customExpression, columnAnotherName },
+  data() {
+    return {
+      iconsVisible: false,
+      currentIconModel: null,
+      ruleList: [
+        {
+          pattern: '/^\\d+$/',
+          message: '请输入正确的数字',
+          label: '数字'
+        },
+        {
+          pattern: '/^[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*|0?\\.0+|0$/',
+          message: '请输入正确的金额',
+          label: '金额'
+        },
+        {
+          pattern: '/^0\\d{2,3}-?\\d{7,8}$/',
+          message: '请输入正确的电话号码',
+          label: '电话'
+        },
+        {
+          pattern: '/^1[3456789]\\d{9}$/',
+          message: '请输入正确的手机号码',
+          label: '手机'
+        },
+        {
+          pattern: '/^1[3456789]\\d{9}$|^0\\d{2,3}-?\\d{7,8}$/',
+          message: '请输入正确的联系方式',
+          label: '电话/手机'
+        },
+        {
+          pattern: '/^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/',
+          message: '请输入正确的邮箱',
+          label: '邮箱'
+        },
+        {
+          pattern: '/^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$/',
+          message: '请输入正确的身份证号码',
+          label: '身份证'
+        },
+        {
+          pattern: '/^\\d{4}-\\d{1,2}-\\d{1,2}$/',
+          message: '请输入格式为YYYY-MM-DD的日期',
+          label: '年日日'
+        },
+        {
+          pattern: '/^\\d{4}-\\d{1,2}-\\d{1,2} \\d{2}:\\d{2}:\\d{2}$/',
+          message: '请输入格式为YYYY-MM-DD HH:mm:ss的日期',
+          label: '年日日 时分秒'
+        },
+        {
+          pattern: '/^\\d{4}-\\d{1,2}-\\d{1,2} \\d{2}:\\d{2}$/',
+          message: '请输入格式为HH:mm:ss的时间',
+          label: '时分秒'
+        },
+        {
+          pattern: '/^\\d{2}:\\d{2}:\\d{2}$/',
+          message: '请输入格式为HH:mm的时间',
+          label: '时分'
+        },
+        {
+          pattern: '/^\\d{2}:\\d{2}$/',
+          message: '请输入格式为HH的时间',
+          label: '时'
+        }
+      ],
+      allVarList: [],
+      apiVarList: [],
+      varTypeList: [],
+      cascaderTypeshow: false,
+
+      treeData: [],
+      dataInterfaceSelector: [],
+      sysVarList: [], //系统变量
+      previewShow: false,
+      previewArr: [],
+      showFields: [],
+      apiJoinName: ''
+    }
+  },
+  created() {
+    this.allVarListChange(true)
+    this.getDataInterfaceSelector()
+    if (this.activeData.__config__.dataType === 'dynamic' && this.activeData.__config__.propsUrl) {
+      this.propsUrlChange(this.activeData.__config__.propsUrl)
+    }
+  },
+  methods: {
+    varchange() {
+      this.cascaderTypeshow = false
+      this.activeData.cascaderType = ''
+      let vardata = this.$refs['varCascader'].getCheckedNodes()[0].data
+      if (vardata && vardata.cascaderType) {
+        this.activeData.cascaderType = ''
+        this.cascaderTypeshow = true
+      }
+    },
+    getAllVarList() {
+      //获取表单内变量
+      let mapList = this.activeData.__config__.relationTable ? loopActiveTabelList(this.drawList, this.activeData.__config__.relationTable) : loopRelationList(this.drawList)
+      this.allVarList = mapList
+        .map((o) => {
+          if (o.allVar) {
+            return {
+              label: o.__config__.label,
+              value: o.__vModel__
+            }
+          }
+        })
+        .filter((l) => l !== undefined)
+    },
+    getAllapiVarList() {
+      //获取API返回变量
+      this.apiVarList = []
+      let mapList = this.activeData.__config__.relationTable ? loopActiveTabelList(this.drawList, this.activeData.__config__.relationTable) : loopRelationList(this.drawList)
+      mapList.forEach((item, key) => {
+        let config = item.__config__
+        if (config.ApiReturn && config.ApiReturn.length) {
+          let list = []
+          if (config.jnpfKey === 'cascader') {
+            list = config.ApiReturn.map((o) => {
+              return {
+                label: o.varName,
+                value: o.varName,
+                cascaderType: true
+              }
+            }).filter((l) => l !== undefined)
+          } else {
+            list = config.ApiReturn.map((o) => {
+              return {
+                label: o.varName,
+                value: o.varName
+              }
+            }).filter((l) => l !== undefined)
+          }
+          this.apiVarList = [...this.apiVarList, ...list]
+        }
+      })
+    },
+    //相同组件切换时 表单内全局变量数据不会及时更新  利用下拉框出现时刷新一下
+    allVarListChange(val) {
+      if (val) {
+        this.getAllVarList()
+        this.getAllapiVarList()
+        this.varTypeList = [
+          { value: 1, label: '默认值' },
+          { value: 2, label: '系统全局变量', children: this.sysVarList || [] },
+          { value: 3, label: '表单全局变量', children: this.allVarList || [] },
+          { value: 4, label: 'api全局变量', children: this.apiVarList || [] }
+        ]
+      }
+    },
+    openIconsDialog(model) {
+      this.iconsVisible = true
+      this.currentIconModel = model
+    },
+    setIcon(val) {
+      this.activeData[this.currentIconModel] = val
+    },
+    addHandle(row) {
+      this.activeData.__config__.regList.push({
+        pattern: row.pattern,
+        message: row.message
+      })
+    },
+
+    dataTypeChange(val) {
+      this.activeData.__config__.defaultValue = this.activeData.multiple ? [] : ''
+      // this.activeData.__slot__.options = []
+      this.activeData.__config__.props.value = 'id'
+      this.activeData.__config__.props.label = 'fullName'
+      if (val === 'static') {
+        this.activeData.__config__.dictionaryType = ''
+        this.activeData.__config__.propsUrl = ''
+        this.activeData.__config__.ApiParams = []
+        this.activeData.__slot__.options = []
+      }
+      if (val === 'dynamic') {
+        this.activeData.__config__.dictionaryType = ''
+      }
+      if (val === 'dictionary') {
+        this.activeData.__config__.propsUrl = ''
+        this.activeData.__config__.ApiParams = []
+      }
+      this.$nextTick(() => {
+        this.$forceUpdate()
+      })
+    },
+    previewClick() {
+      if (!this.activeData.__config__.propsUrl)
+        return this.$message({
+          message: '当前未选择API接口,不支持数据预览',
+          type: 'warning'
+        })
+      dataapiDetail(this.activeData.__config__.propsUrl).then((res) => {
+        let { apiKey } = res.data.data
+        this.apiJoinName = res.data.data.apiName
+        let resJson = JSON.parse(res.data.data.note || '{}')
+        let formVarObj = {}
+        if (resJson.params && resJson.params.length) {
+          resJson.params.forEach((i, k) => {
+            formVarObj[i.key] = i.def
+          })
+        }
+        console.log(apiKey)
+        openurl(apiKey, { ...param, ...formVarObj }).then((res) => {
+          let { data } = res.data
+          console.log(1111, data)
+          try {
+            let arr = []
+            this.previewShow = true
+            this.jsonPath(arr, data, '$')
+            this.previewArr = arr
+            console.log(arr)
+          } catch (e) {
+            this.$message({ message: '接口返回数据格式不支持', type: 'warning' })
+          }
+        })
+      })
+    },
+    jsonPath(arr, json, basePath) {
+      const type = this.validateType(json)
+      if (type === 'object') {
+        for (let key in json) {
+          const item = {
+            key,
+            path: `${basePath}.${key}`
+          }
+          const childType = this.validateType(json[key])
+          item.type = childType
+          if (childType === 'object' || childType === 'array') {
+            item.leaf = true
+            item.children = []
+            this.jsonPath(item.children, json[key], item.path)
+          } else {
+            item.leaf = false
+            item.value = json[key]
+          }
+          arr.push(item)
+        }
+      } else if (type === 'array') {
+        json = json[0]
+        if (json === undefined) return
+        for (let key in json) {
+          const item = {
+            key,
+            path: `${basePath}[*].${key}`
+          }
+          const childType = this.validateType(json[key])
+          item.type = childType
+          if (childType === 'object' || childType === 'array') {
+            item.leaf = true
+            item.children = []
+            this.jsonPath(item.children, json[key], item.path)
+          } else {
+            item.leaf = false
+            item.value = json[key]
+          }
+          arr.push(item)
+        }
+      }
+    },
+    validateType(val) {
+      // 校验JSON数据类型
+      const type = typeof val
+      if (type === 'object') {
+        if (Array.isArray(val)) {
+          return 'array'
+        } else if (val === null) {
+          return 'null'
+        } else {
+          return 'object'
+        }
+      } else {
+        return type
+      }
+    },
+    getDataInterfaceSelector() {
+      this.getAllVarList()
+      this.getAllapiVarList()
+      //获取api列表
+      dataapicategoryList().then((res) => {
+        let category = res.data.data
+        dataapiList({ apiFormal: 1, apiTypes: '1,2' }).then((res) => {
+          let list = res.data.data
+          this.dataInterfaceSelector = category
+            .map((i) => ({
+              label: i.categoryName,
+              value: i.id,
+              children: list.filter((j) => j.categoryId === i.id).map((k) => ({ label: k.apiName, value: k.id, key: k.apiKey }))
+            }))
+            .filter((i) => i.children.length)
+        })
+        this.getSysparamList()
+      })
+    },
+    getSysparamList() {
+      //获取全局系统变量
+      paramList({ paramType: 'SYSTEM' }).then((res) => {
+        let arr = res.data.data.records
+        getparamsys({ dateFormat: 'yyyy_MM_dd' }).then((r) => {
+          let sysVarValue = r.data.data
+          if (sysVarValue) {
+            this.sysVarList = arr
+              .map((i) => {
+                return {
+                  label: i.paramName,
+                  value: sysVarValue[i.paramKey] || null
+                }
+              })
+              .filter((l) => l !== undefined)
+          }
+        })
+        this.varTypeList = [
+          { value: 1, label: '默认值' },
+          { value: 2, label: '系统全局变量', children: this.sysVarList || [] },
+          { value: 3, label: '表单全局变量', children: this.allVarList || [] },
+          { value: 4, label: 'api全局变量', children: this.apiVarList || [] }
+        ]
+        this.$nextTick(() => {
+          this.allVarListChange(true)
+        })
+      })
+    },
+    varNamefitlte(row, val) {
+      if (this.activeData.__config__.ApiReturn.find((i) => i.varName === val && i.keyName !== row.keyName)) {
+        this.activeData.varRepeat = true
+        return this.$message({
+          message: '检测到变量命名重复,请重新输入',
+          type: 'warning'
+        })
+      }
+      if (this.apiVarList.find((i) => i.label === val)) {
+        this.activeData.varRepeat = true
+        return this.$message({
+          message: '检测到变量命名重复,请重新输入',
+          type: 'warning'
+        })
+      }
+      this.activeData.varRepeat = false
+      this.getAllapiVarList()
+      this.varTypeList[3].children = this.apiVarList
+    },
+    varNamefitlteclass(row, val) {
+      let flag = false
+      if (this.activeData.__config__.ApiReturn.find((i) => i.varName === val && i.keyName !== row.keyName)) {
+        flag = true
+      }
+      if (this.apiVarList.filter((i) => i.label === val).length > 1) {
+        flag = true
+      }
+      return flag
+    },
+    apiFilterMethod(node, keyword) {
+      let { label, key } = node.data
+      keyword = keyword.toLowerCase()
+      return label.includes(keyword) || key.toLowerCase().includes(keyword)
+    },
+    fitLabelChange() {
+      if (!this.activeData.__config__.apiProps.fitLabel.length) {
+        this.activeData.__config__.apiProps.labelSeparator = ''
+      }
+    },
+    propsUrlChange(val) {
+      if (!val) {
+        this.activeData.__slot__.options = []
+        return
+      }
+      // this.activeData.__config__.ApiParams = []
+      // this.activeData.__config__.apiProps = {label: '',value: ''}
+      this.activeData.__config__.defaultValue = this.activeData.multiple ? [] : ''
+      //获取api信息
+      dataapiDetail(val).then((res) => {
+        //获取api值
+        getAPIData(this.activeData.__slot__, val, [], [], '', this.activeData.__config__.apiProps).then((res) => {
+          this.$set(this.activeData.__slot__, 'options', res)
+        })
+        let resJson = JSON.parse(res.data.data.note || '{}')
+        this.showFields = resJson.showFields || []
+        if (resJson.params && resJson.params.length) {
+          //添加变量类型 1:默认 2:全局系统变量 3:表单内全局变量
+          if (!this.activeData.__config__.ApiParams.length) {
+            resJson.params.forEach((i, k) => [Object.assign(i, { varType: [1] })])
+            this.activeData.__config__.ApiParams = resJson.params
+          } else {
+            let APIKeylist = resJson.params.map((i) => {
+              return i.key
+            })
+            let paramsList = this.activeData.__config__.ApiParams.filter((l) => APIKeylist.includes(l.key))
+            paramsList.forEach((i, k) => {
+              if (!i.varType) {
+                Object.assign(i, { varType: [1] })
+              }
+            })
+            this.activeData.__config__.ApiParams = paramsList
+          }
+        } else {
+          this.activeData.__config__.ApiParams = []
+        }
+      })
+    },
+    getPath(item) {
+      this.getAPiPath(item)
+    },
+    getAllPath(array) {
+      array.children.forEach((item) => this.getAPiPath(item))
+    },
+    getAPiPath({ key }) {
+      if (this.activeData.__config__.ApiReturn.find((i) => i.keyName === key)) return
+      this.activeData.__config__.ApiReturn.push({ keyName: key, varName: key, apiName: this.apiJoinName })
+      this.getAllapiVarList()
+      this.varTypeList[2].children = this.apiVarList
+    }
+  }
+}
+</script>

+ 26 - 0
src/components/Generator/index/RightComponents/JNPFMap.vue

@@ -0,0 +1,26 @@
+<template>
+  <div>
+    <el-form-item label="字段隔开字符">
+      <el-input v-model="activeData.keepSeparator"></el-input>
+    </el-form-item>
+    <el-form-item label="展开模式">
+      <el-switch v-model="activeData.expandMode"></el-switch>
+    </el-form-item>
+    <template v-if="activeData.expandMode">
+      <el-form-item label="展开高度">
+        <el-input v-model="activeData.expandHeight"></el-input>
+      </el-form-item>
+    </template>
+  </div>
+</template>
+<script>
+import comMixin from './mixin'
+export default {
+  props: ['activeData', 'dbLinkId', 'drawList'],
+  mixins: [comMixin],
+  data() {
+    return {}
+  },
+  created() {}
+}
+</script>

+ 68 - 47
src/components/Generator/index/RightPanel.vue

@@ -39,11 +39,11 @@
                     <!--                                     :label="group.tableName">-->
                     <template v-if="activeData.__config__.isSubTable">
                       <el-option
-                                 v-for="item in getSubTalebFiled(activeData.__config__.relationTable)"
-                                 :key="item.id"
-                                 :value="item.id"
-                                 :disabled="getChildrenDisabledSelect(activeData.__config__.relationTable, item.id)"
-                                 :label="item.columnTitle ? item.columnTitle + ' ' + item.columnName : item.columnComment + ' ' + item.columnName"
+                        v-for="item in getSubTalebFiled(activeData.__config__.relationTable)"
+                        :key="item.id"
+                        :value="item.id"
+                        :disabled="getChildrenDisabledSelect(activeData.__config__.relationTable, item.id)"
+                        :label="item.columnTitle ? item.columnTitle + ' ' + item.columnName : item.columnComment + ' ' + item.columnName"
                       >
                       </el-option>
                     </template>
@@ -61,7 +61,6 @@
                     <!--                    </el-option-group>-->
                   </el-select>
                 </el-form-item>
-
               </template>
               <template v-else>
                 <template v-if="!activeData.__config__.isSubTable">
@@ -141,9 +140,17 @@
             <serialNumber v-if="activeData.__config__.jnpfKey === 'serialNumber'" :active-data="activeData" :draw-list="drawList" :columnModelId="columnModelId" />
             <Tab v-if="activeData.__config__.jnpfKey === 'tab'" :active-data="activeData" />
             <Collapse v-if="activeData.__config__.jnpfKey === 'collapse'" :active-data="activeData" />
-            <Table v-if="activeData.__config__.jnpfKey === 'table'" :dbtable-list="tableList" :active-data="activeData" :dbSourceId="dbSourceId" :columnModelId="columnModelId" :allTabelList="allTabelList" />
+            <Table
+              v-if="activeData.__config__.jnpfKey === 'table'"
+              :dbtable-list="tableList"
+              :active-data="activeData"
+              :dbSourceId="dbSourceId"
+              :columnModelId="columnModelId"
+              :allTabelList="allTabelList"
+            />
             <NewDivider v-if="activeData.__config__.jnpfKey === 'new-divider'" :active-data="activeData" />
             <PlaceholderCom v-if="activeData.__config__.jnpfKey === 'PlaceholderCom'" :active-data="activeData" />
+            <JNPFMap v-if="activeData.__config__.jnpfKey === 'JNPFMap'" :active-data="activeData" />
             <template v-if="isSystem">
               <el-form-item label="控件标题">
                 <el-input v-model="activeData.__config__.label" placeholder="请输入控件标题" />
@@ -266,8 +273,7 @@
                       <i class="el-icon-question" />
                     </el-tooltip>
                   </template>
-                  <el-switch v-model="i.hideClear">
-                  </el-switch>
+                  <el-switch v-model="i.hideClear"> </el-switch>
                 </el-form-item>
               </template>
             </el-card>
@@ -276,7 +282,7 @@
         <!-- 关联设置 -->
         <el-form v-loading="loading" v-show="currentTab === 'relation'" label-width="90px" size="small" labelPosition="left">
           <template v-if="activeData.relationData">
-            <el-form-item >
+            <el-form-item>
               <template slot="label">
                 <span>关联表单</span>
                 <el-tooltip style="cursor: pointer" effect="dark" :content="'被关联的表单需同时符合【未关联其他表单】和【是一个单表表单】才会在下拉选择中展示'" placement="top">
@@ -284,7 +290,7 @@
                 </el-tooltip>
               </template>
               <el-select v-model="activeData.relationData.itemRelationTable" filterable placeholder="请选择" clearable @change="onRelationTableChange($event)">
-                <el-option v-for="(item, index) in allTabelList.filter(o=> o.visualdevTableType && o.visualdevTableType == 1)" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
+                <el-option v-for="(item, index) in allTabelList.filter((o) => o.visualdevTableType && o.visualdevTableType == 1)" :label="item.fullName" :value="item.id" :key="item.id"></el-option>
               </el-select>
               <!--                  <el-cascader ref="relationcascader"-->
               <!--                    v-model="i.relationName" :options="relationData" :props="{ expandTrigger: 'hover', emitPath: false }"-->
@@ -307,18 +313,13 @@
               <el-switch v-model="activeData.relationData.isCheck" @change="isCheckChange()" />
             </el-form-item>
             <el-form-item label="数据填充设置" label-width="240px">
-              <el-button size="mini" icon="el-icon-plus" @click="activeData.relationData.itemRelationList.push({columnId: '', drawId: '',plaintext: 0})">添加</el-button>
+              <el-button size="mini" icon="el-icon-plus" @click="activeData.relationData.itemRelationList.push({ columnId: '', drawId: '', plaintext: 0 })">添加</el-button>
             </el-form-item>
             <el-table v-if="activeData.relationData.itemRelationList.length" :data="activeData.relationData.itemRelationList" style="width: 100%" border>
               <el-table-column label="关联字段">
                 <template slot-scope="scope">
                   <el-select v-model="scope.row.columnId" filterable clearable placeholder="请选择" ref="selectRef">
-                    <el-option
-                      v-for="(item, index) in columnList"
-                      :label="item.title"
-                      :value="item.propId"
-                      :key="item.propId"
-                    ></el-option>
+                    <el-option v-for="(item, index) in columnList" :label="item.title" :value="item.propId" :key="item.propId"></el-option>
                   </el-select>
                 </template>
               </el-table-column>
@@ -348,7 +349,7 @@
               </el-table-column>
               <el-table-column width="35">
                 <template slot-scope="scope">
-                  <i class="el-icon-delete" style="cursor: pointer" @click="activeData.relationData.itemRelationList.splice(scope.$index,1)"></i>
+                  <i class="el-icon-delete" style="cursor: pointer" @click="activeData.relationData.itemRelationList.splice(scope.$index, 1)"></i>
                 </template>
               </el-table-column>
             </el-table>
@@ -433,14 +434,20 @@
           <p style="color: #ff0000">注:该表单列被其它表单所引用关联,即其它表单组件“关联设置”关联该表单列;</p>
 
           <el-tooltip content="" placement="top">
-            <div slot="content">注:如表单物理表字段进行了增删改情况,可以通过刷新同步主表结构进行同步更新。<br/>同步新结构后,请调整表单设计,避免不必要的异常情况;</div>
-            <el-button @click="fieldCompareChange" type="success" plain style="margin: 10px 0;">
-              刷新同步主表结构<i class="el-icon-question" />
-            </el-button>
+            <div slot="content">注:如表单物理表字段进行了增删改情况,可以通过刷新同步主表结构进行同步更新。<br />同步新结构后,请调整表单设计,避免不必要的异常情况;</div>
+            <el-button @click="fieldCompareChange" type="success" plain style="margin: 10px 0"> 刷新同步主表结构<i class="el-icon-question" /> </el-button>
           </el-tooltip>
-          <el-upload class="upload-demo" accept=".xlsx,.xls" ref="uploadFile"
-            :action="define.comUploadUrl" :on-success="onSuccess" :before-upload="beforeUploadChange" :on-remove="handleRemove"
-            :headers="{ 'Blade-Auth': Authorization }" :file-list="formConf.importTemplatePathFileList">
+          <el-upload
+            class="upload-demo"
+            accept=".xlsx,.xls"
+            ref="uploadFile"
+            :action="define.comUploadUrl"
+            :on-success="onSuccess"
+            :before-upload="beforeUploadChange"
+            :on-remove="handleRemove"
+            :headers="{ 'Blade-Auth': Authorization }"
+            :file-list="formConf.importTemplatePathFileList"
+          >
             <el-tooltip content="" placement="top">
               <div slot="content">注:自定义上传表单导入模板,将出现在“批量导入”下载导入模板中,默认下载导入模板为表单全部列;</div>
               <el-button size="small" type="success" plain>上传表单数据导入模板 <i class="el-icon-question" /></el-button>
@@ -497,12 +504,13 @@ import serialNumber from './RightComponents/serialNumber'
 import Table from './RightComponents/Table'
 import PlaceholderCom from './RightComponents/PlaceholderCom'
 import NewDivider from './RightComponents/NewDivider'
+import JNPFMap from './RightComponents/JNPFMap'
 import { cubeFieldList } from '@/api/workFlow/FlowEngine'
-import {fieldCompare, getAssociatedFormInterfaces, getConfigData} from '@/api/onlineDev/visualDev'
+import { fieldCompare, getAssociatedFormInterfaces, getConfigData } from '@/api/onlineDev/visualDev'
 import { loopRelationList } from '@/utils'
 import AmisSdk from '@/components/AmisSdk.vue'
 import Event from '@/components/Generator/index/RightComponents/Event.vue'
-import {getToken} from "@/utils/auth";
+import { getToken } from '@/utils/auth'
 
 const commonRightList = ['comSelect', 'depSelect', 'posSelect', 'userSelect', 'dicSelect', 'editor']
 const systemList = ['createUser', 'createUserId', 'modifyUserId', 'createTime', 'modifyUser', 'modifyTime', 'currOrganize', 'currDept', 'currPosition', 'billRule']
@@ -548,7 +556,8 @@ export default {
     serialNumber,
     Table,
     PlaceholderCom,
-    NewDivider
+    NewDivider,
+    JNPFMap
   },
   props: ['showField', 'activeData', 'formConf', 'drawList', 'modelType', 'relationData', 'logicData', 'cubeList', 'dbLinkId', 'tableList', 'dbSourceId', 'activeId', 'allTabelList', 'columnModelId'],
   data() {
@@ -600,7 +609,7 @@ export default {
       LogicList: [],
       relationDrawList: [],
       formInterfacesList: [],
-      Authorization: 'bearer ' + getToken(),
+      Authorization: 'bearer ' + getToken()
     }
   },
   computed: {
@@ -625,7 +634,7 @@ export default {
     filteredArray() {
       return this.activeData.relationData.itemRelationList.filter((item) => item.drawId)
     },
-    isVmodelList(){
+    isVmodelList() {
       return loopRelationList(this.drawList).filter((item) => item.__vModel__)
     }
   },
@@ -689,12 +698,24 @@ export default {
   },
   methods: {
     // 刷新同步主表结构
-    fieldCompareChange(){
-      fieldCompare(this.dbLinkId).then((res)=>{
-        let data  = res.data.data[0]
-        let creatData = data.fieldsCreat.map((i)=> {return i.columnName}).join(',');
-        let updateData = data.fieldsUpdate.map((i)=> {return i.columnName}).join(',')
-        let deletedData = data.fieldsDeleted.map((i)=> {return i.columnName}).join(',')
+    fieldCompareChange() {
+      fieldCompare(this.dbLinkId).then((res) => {
+        let data = res.data.data[0]
+        let creatData = data.fieldsCreat
+          .map((i) => {
+            return i.columnName
+          })
+          .join(',')
+        let updateData = data.fieldsUpdate
+          .map((i) => {
+            return i.columnName
+          })
+          .join(',')
+        let deletedData = data.fieldsDeleted
+          .map((i) => {
+            return i.columnName
+          })
+          .join(',')
         // 自定义模板
         const notifyTemplate = `
 <!--            <div>-->
@@ -702,14 +723,14 @@ export default {
                 <p style="text-align: initial;"><span>修改字段:</span><span>${updateData || '暂无更新'}</span></p>
                 <p style="text-align: initial;"><span>删除字段:</span><span>${deletedData || '暂无更新'}</span></p>
 <!--            </div>-->
-        `;
-        const h = this.$createElement;
+        `
+        const h = this.$createElement
         this.$notify({
           title: '提示',
           message: notifyTemplate,
           dangerouslyUseHTMLString: true,
           duration: 0
-        });
+        })
       })
     },
     // 获取被引用关联表单接口
@@ -743,10 +764,10 @@ export default {
         })
         .filter((l) => l !== undefined)
       // 兼容 组件在修改下拉框值后 逻辑属性中保存的options未能及时更新问题
-      this.logicData.forEach((i,z) => {
+      this.logicData.forEach((i, z) => {
         try {
-          i.logicOpList = this.drawList.find((o)=> o.__vModel__ && o.__vModel__ === i.op).__slot__.options
-        }catch (e) {}
+          i.logicOpList = this.drawList.find((o) => o.__vModel__ && o.__vModel__ === i.op).__slot__.options
+        } catch (e) {}
       })
     },
     logicOpChange(e, item) {
@@ -819,7 +840,7 @@ export default {
       this.relationData.push({ relationName: '', fieldName: [], fieldList: [], tablesList: [], relationList: [] })
     },
     addLogic() {
-      this.logicData.push({ hostval: '', op: '', setType: '', deVal: [], logicOpList: [],hideClear:false, })
+      this.logicData.push({ hostval: '', op: '', setType: '', deVal: [], logicOpList: [], hideClear: false })
     },
     getLogicDisOption(id) {
       let res = false
@@ -1060,13 +1081,13 @@ export default {
       }
       return (extension || extension2) && isLt2M
     },
-    onSuccess(res){
+    onSuccess(res) {
       if (res.code === 200) {
         this.formConf.importTemplatePath = res.data.filePath
-        this.formConf.importTemplatePathFileList = [{name:res.data.fileName,url:res.data.filePath}]
+        this.formConf.importTemplatePathFileList = [{ name: res.data.fileName, url: res.data.filePath }]
       }
     },
-    handleRemove(){
+    handleRemove() {
       this.formConf.importTemplatePath = ''
       this.formConf.importTemplatePathFileList = []
     }

+ 2 - 0
src/components/index.js

@@ -15,6 +15,7 @@ import YangForm from '@/components/YangForm'
 import JNPFText from '@/components/Generator/components/JNPFText'
 import JNPFCascader from '@/components/Generator/components/cascader/index'
 import JNPFUploadFz from '@/components/Generator/components/Upload/UploadFz'
+import JNPFMap from '@/components/Generator/components/JNPFMap'
 import JNPFUploadImg from '@/components/Generator/components/Upload/UploadImg'
 import JNPFUploadSign from '@/components/Generator/components/Upload/UploadSign.vue'
 import PopupSelect from '@/components/Generator/components/PopupSelect'
@@ -77,5 +78,6 @@ export default {
     Vue.component('PlaceholderCom', PlaceholderCom)
     Vue.component('NewInput', NewInput)
     Vue.component('NewDivider', NewDivider)
+    Vue.component('JNPFMap', JNPFMap)
   }
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2 - 2
src/utils/request.js