wangting
2024-05-27 a9bbbe822377536e6f3374b05e2b64b12b2f188c
Source/ProjectWeb/src/components/dynamic-components/dynamic-custom.vue
@@ -1,9 +1,17 @@
<template>
  <div class="UI-dynamic" :id="'UI-dynamic-'+areasName+componentVO.oid">
    <div v-if="isError" style="color: #F56C6C">这个自定义页面的地址格式不正确。推荐使用bs=?type=xxx&context=yyy&pparam=zzz这种形式</div>
    <el-alert
      class="alert"
      :closable="false"
      v-if="isError"
      title="自定义组件配置信息错误!"
      type="error"
      show-icon
      description="这个自定义页面的地址格式不正确。推荐使用“组件name?param=xxx”(自定义组件)或者“?type=xxx&context=yyy&pparam=zzz”(UI引擎)这2种形式">
    </el-alert>
    <component v-else :is="currentComponent"
               :btmType="btmType"
               :content="content"
               :context="context"
               :inDialog="true"
               :key="areasName+'customCom-'+componentVO.oid"
               :componentVO="componentVO"
@@ -15,38 +23,48 @@
</template>
<script>
import {queryStringToObject} from '@/util/util'
import {validatenull} from "@/util/validate";
export default {
  name: "dynamic-custom",
  components:{
    'UI':()=>import('@/views/base/UIContentViewerInDialog'),
    'test':()=>import('@/views/custom-ui/test'),
    'test2':()=>import('@/views/custom-ui/test2'),
  },
  props:{
    componentVO:{
      type:Object,
  props: {
    //ui上下文的业务类型(或链接类型)
    uiBtmType: {
      type: String
    },
    //ui上下文
    uiContext:{
      type: String
    },
    componentVO: {
      type: Object,
      default: {}
    },
    inDialog: {
      type: Boolean,
      default: false
    },
    areasName:{
      type:String,
      default:''
    canEdit:{
      //内容是否可编辑
      type:Boolean,
      default:false
    },
    sourceData:{
    areasName: {
      type: String,
      default: ''
    },
    sourceData: {
      //所属区域的上一区域选中数据
      type:Object,
      type: Object,
      default: {}
    },
    dataStore:{
    dataStore: {
      //弹窗时按钮所属区域选中数据
      type:Array,
      type: Array,
      default: []
    },
    paramVOS:{
      type:Object,
    paramVOS: {
      type: Object,
      default: {}
    },
    isShow: {
@@ -57,69 +75,77 @@
  },
  data() {
    return {
      btmType:'',
      content:'',
      urlParams:{},
      height:'300px',
      customClass:this.componentVO.customClass, //bs=?type=xxx&context=yyy&param=zzz  或者 bs=组件name?type=xxx&context=yyy&param=zzz
      isError:false, //路径解析失败
      currentComponent: 'UI',//组件name
      btmType: '',
      context: '',
      urlParams: {},
      height: '300px',
      customClass: '', //?type=xxx&context=yyy&param=zzz  或者 组件name?type=xxx&context=yyy&param=zzz
      isError: false, //路径解析失败
      ComponentUrl:'base/UIContentViewerInDialog',
      currentComponent: null
    }
  },
  watch:{
    sourceData:{
  watch: {
    sourceData: {
      handler(newval) {
        //源数据有变化时变更当前区域数据
        console.log(this.areasName);
        console.log(newval);
      }
      },
      deep: true,
      immediate: true
    }
  },
  computed:{
  },
  computed: {},
  created() {
  },
  mounted() {
    if(this.customClass.indexOf("bs=") <0){
      this.isError=true;
      return ;
    }
    this.customClass=this.componentVO.customClass.split("bs=")[1];
    if(this.customClass.indexOf("?") <0 || this.customClass.indexOf("type=") <0 || this.customClass.indexOf("context=") <0){
      this.isError=true;
      return ;
    }
    if(this.customClass.split('?')[0]!='' && this.customClass.split('?')[0]!='UI' && this.customClass.split('?')[0]!='ui'){
      this.currentComponent=this.customClass.split('?')[0];
    }
    this.customClass=this.componentVO.customClass.split("?")[1].split('&');
    let urlParams={};
    let btmType=''
    let content=''
    this.customClass.forEach(item=>{
      var preParam =item.split("=");
      if(preParam[0]=='type'){
        btmType=preParam[1];
      }else if(preParam[0]=='context'){
        content=preParam[1];
      }else{
        urlParams[preParam[0]] = preParam[1];
    this.customClass=this.componentVO.customClass;
    this.componentVO.customClass.split(';').forEach(item=>{
      if(item.indexOf('web=')==0){
        this.customClass=item.split('web=')[1];
      }
    })
    let urlParams = {};
    // 如果路径中存在 '?',则取问号前面部分给 parts
    if (this.customClass.includes('?')) {
      this.ComponentUrl = this.customClass.split("?")[0];
      urlParams = queryStringToObject(this.customClass);
    } else {
      this.ComponentUrl = this.customClass; // 不存在 '?' 整条路径就是 parts
    }
    if(validatenull(this.ComponentUrl) || ['ui', 'UI', 'base','bs'].includes(this.ComponentUrl)){
      this.ComponentUrl='views/base/UIContentViewerInDialog';
    }else if(this.ComponentUrl.indexOf('views/')===-1){
      this.ComponentUrl='views/custom-ui/'+this.ComponentUrl;
    }
    if (this.ComponentUrl=='base/UIContentViewerInDialog' && (!urlParams.type || !urlParams.context)) {
      this.isError = true;
      return;
    }
      this.btmType=btmType,
      this.content=content,
      this.urlParams=Object.assign(this.paramVOS,urlParams)
    this.btmType = urlParams.type;
    this.context = urlParams.context;
    this.urlParams = Object.assign({},this.paramVOS, urlParams)
    this.loadCompoent();
  },
  mounted() {
    //this.getHeight(this.$parent);
 },
  methods:{
    getHeight(el){
      if(el.$el.clientHeight>50){
        this.height=el.$el.clientHeight+'px';
      }else {
  },
  methods: {
    loadCompoent(){
      // 动态导入组件
      import(`@/${this.ComponentUrl}.vue`).then((module) => {
        // 成功导入后,将组件注册到Vue实例中
        this.currentComponent = module.default;
      }).catch((error) => {
        // 处理导入失败的情况
        console.error('组件加载失败:', error);
      });
    },
    getHeight(el) {
      if (el.$el.clientHeight > 50) {
        this.height = el.$el.clientHeight + 'px';
      } else {
        this.getHeight(el.$parent);
      }
    }
@@ -127,6 +153,6 @@
}
</script>
<style scoped>
<style scoped lang="scss">
</style>