问卷模板组件

具体使用:

第一、模板依赖资源及使用方法。

新建文件renderTemp>index.vue

注:图片及地址类问题需要单独组件,如下方代码依赖:

import UploadImage from '@/views/components/uploadImage/index.vue'
import addressTemp from '@/views/components/addressTemp/index.vue'

组件使用方式:

数据依赖:问卷题目(必),问卷答案(可选),组件高度(可选),禁用状态(可选)

questionData 题目   answerData 答案   tempHeight  高度  disableStatus 是否禁用

注意:需要等父组件加载完数据才能渲染此组件

<script>
  import imgses from '@/assets/images/warningLog.png'
  import UploadImage from '@/views/components/uploadImage/index.vue'
  import addressTemp from '@/views/components/addressTemp/index.vue'
  export default {
    name:'RenderTemp',
    props:{
      questionData:{
        type:Array,
      },
      answerData:{
        type:Object,
      },
      tempHeiht:{
        type:Number,
        default:500
      },
      disableStatus:{
        type:Boolean,
        default:false
      }
    },
    components:{
      UploadImage,
      addressTemp
    },
    data(){
      return{
        value:'',
        answerCode:{},
        a:[],
        isQues1:'',
        isQues2:'',
        checkcode:[],
        childitem:[],
        colors:'',
        addressV:[]
      }
    },
    watch:{
      // questionData:{
      //   handler(N,O){
      //     // console.log(N);
      //   },
      //   deep:true
      // },
      answerData:{
        handler(N,O){
          // let isValue = false
          // for(let key in this.answerData){
          //   isValue=true//若不为空,可遍历,返回false
          // }
          // if (isValue) {
            this.backShow() 
          // }
        },
        deep:true
      }
    },
    created(){
      let isValue = false
      for(let key in this.answerData){
        isValue=true//若不为空,可遍历,返回false
      }
      if (isValue) {
        this.backShow()
      }
    },
    render(createElement){
      let _this = this
      return createElement('el-table',{
        props: {
          data: _this.questionData,
          border:true,
          showHeader:false,
          height:_this.tempHeiht+'px',
          rowClassName:_this.tableRowClassName,
        },
        style:{
          width:100+'%',
        },
      },[
        createElement('el-table-column',{ 
          props: { align: "center", width:200 },
          scopedSlots: {
            default: (props) =>{
              if (props.row.istop == true && props.row.questiontype != 'leadtmpl') {
                if (props.row.yisi==true) {
                  return createElement('span',{
                    style: {
                      color:'red',
                    },
                  },[createElement('img',{
                    style: {
                      width: "1vw",
                      verticalAlign: "middle",
                      marginBottom:"4px",
                      marginRight: "10px",
                      cursor: "pointer",
                    },
                    attrs: {
                      src: imgses
                    },
                    'class': {
                      foo: _this.disableStatus,
                    }
                  }),createElement('span',props.row.title)])
                }
                return createElement('span',props.row.title)
              }
            }
          }
        }),
        createElement('el-table-column', {
          scopedSlots: {
            default: (props) => {
              // 单选题型
              if (props.row.questiontype == 'radiotmpl') {
                let obj = eval(props.row.data)
                return createElement('el-radio-group',{
                  props: {
                    value: _this.answerCode[props.row.checkcode]
                  },
                  on: {
                    input:function (event){
                      _this.$set(_this.answerCode,props.row.checkcode,event)
                    }
                  },
                  'class': {
                    foo: _this.disableStatus,
                  }
                },
                  obj.map(function(item){
                    return createElement('el-radio',{
                      props:{ label: item.opt},
                      on:{
                        change:function(){
                          _this.radioSwich(item.opt,props.row)
                        }
                      }
                    })
                  })
                )
              }
              // 多选框题型
              if (props.row.questiontype == 'checkboxtmpl') {
                let obj = eval(props.row.data)
                // console.log(props.row);
                return createElement('el-checkbox-group',{
                  props: {
                    value: _this.answerCode[props.row.checkcode]
                  },
                  on: {
                    input:function (event){
                      _this.$set(_this.answerCode,props.row.checkcode,event)
                      console.log(_this.answerCode[props.row.checkcode]);
                      // 子级异常显示?
                    },
                  },
                  'class': {
                    foo: _this.disableStatus,
                  }
                },
                  obj.map(function(item,index){
                    return createElement('el-checkbox',{
                      props:{
                        label: item.opt,
                      },
                      on:{
                        change: (e) => {
                          _this.istopValue(item.qita,e)
                          // console.log(_this.answerCode);
                        }
                      }
                    })
                  })
                )
              }
              // 地址
              if (props.row.questiontype == 'addresstmpl') {
                return createElement('address-temp',{
                  props: {
                    value: _this.answerCode[props.row.checkcode],
                    inputAddressList:_this.answerCode.province_id+','+_this.answerCode.city_id+','+_this.answerCode.dist_id+','+_this.answerCode.town_id+','+_this.answerCode.village_id,
                    chinaAddressList:_this.answerCode[props.row.checkcode],
                  },
                  on: {
                    resultAddressList:function (event){
                      if (Array.isArray(event)) {
                        let strEV = event.join(",");
                        _this.$set(_this.answerCode,props.row.checkcode,strEV)
                      }else{
                        _this.$set(_this.answerCode,props.row.checkcode,event)
                      }
                    },
                    addressValue:function (event){
                      _this.addressV=event
                    }
                  },
                  'class': {
                    foo: _this.disableStatus,
                  }
                })
              }
              // input输入框类型题
              let reg = (props.row.questiontype == 'numiptmpl' || props.row.questiontype == 'nametmpl' || props.row.questiontype == 'phonetmpl' || props.row.questiontype == 'textiptmpl' || props.row.questiontype == 'dcynametmpl' || props.row.questiontype == 'dcyphonetmpl')
              if (reg) {
                if (props.row.istop == true) {
                  return createElement('el-input',{
                    props: {
                      value: _this.answerCode[props.row.checkcode]
                    },
                    on: {
                      input:function (event){
                        _this.$set(_this.answerCode,props.row.checkcode,event)
                        // console.log(_this.answerCode);
                      }
                    },
                    attrs: {
                      placeholder:'请 输 入 ......'
                    },
                    style:{
                      width:'250px',
                    },
                    'class': {
                      foo: _this.disableStatus,
                    }
                  })
                }
              }
              // 图片
              if (props.row.questiontype == 'imgtmpl') {
                return createElement('UploadImage',{
                  props: {
                    imgData: _this.answerCode[props.row.checkcode],
                    limit:1,
                    orderId:props.row.checkcode
                  },
                  on: {
                    imgUrls:function (event){
                      _this.$set(_this.answerCode,props.row.checkcode,event)
                      // console.log(_this.answerCode[props.row.checkcode]);
                    }
                  },
                  'class': {
                    foo: _this.disableStatus,
                  }
                })
              }
            }
          },
        }),
      ])
    },
    methods:{
      tableRowClassName({ row, rowIndex }) {
        if (row.istop == false) {
          return 'hidden_box'  //可以动态添加class样式
        }
        return ''
      },
      backShow(){
        var child = []
        this.questionData.forEach(item => {
          if (this.answerData[item.checkcode] && this.answerData[item.checkcode].length !=0) {
            item.istop=true
            if (item.childid) {
              var obj = eval(item.data)
              for(var key in obj){
              if (this.answerData[item.checkcode].indexOf(obj[key].opt) !=-1) {
                if (obj[key].qita) {
                  child.push(obj[key].qita)
                }
              }
            }
            }
            
          };
          if (child.indexOf(item.orderid) != -1) {
            // if (this.answerData[item.checkcode] && this.answerData[item.checkcode].length !=0) {
              item.istop=true
            // }
          };
        });
        this.answerCode=this.answerData
      },
      // 多选隐藏显示子级
      istopValue(v,e){
        // console.log(v,e);
        this.questionData.forEach(item=>{
          if (item.orderid.indexOf(v) != -1) {
            if(e==true){
              item.istop=true
            }else{
              if(item.questiontype=='checkboxtmpl'){
                this.$set(this.answerCode,item.checkcode,[])
              }else{
                this.$set(this.answerCode,item.checkcode,'')
              }
              item.istop=false
            }
          }
        })
      },
      // 单选开关
      radioSwich(e,item){
        // console.log(e,item);
        if(this.answerCode.code655968092418031=='否' && this.answerCode.code655968119802726=='否' && this.answerCode.code655968136235490=='否' && this.answerCode.code655968153567890=='否' && this.answerCode.code655968224928598=='否'){
          this.$set(this.answerCode,'code655968284862397','是')
        }else{
          this.$set(this.answerCode,'code655968284862397','否')
        }
        let b = JSON.parse(item.data)
        // console.log(item.data);
        if(item.childid){
          b.forEach(i=>{
            if(i.opt==e){
              if(i.qita){
                this.questionData.forEach(it=>{
                  // this.isQues1=item.orderid;
                  this.a = i.qita.split("_")
                  if(this.a.indexOf(it.orderid) !=-1){
                    it.istop=true
                  }
                  if(it.orderid==i.qita){
                    it.istop=true
                  }
                })
              }else{
                // this.isQues2=item.orderid;
                for(var key in b){
                  if(b[key].qita){
                    this.a=b[key].qita.split("_")
                  }
                }
                // console.log(this.isQues1);
                // if(this.isQues1==this.isQues2){
                  this.questionData.forEach(quesIe=>{
                    this.a.forEach(itemA=>{
                      if(itemA==quesIe.orderid){
                        if(quesIe.questiontype=='checkboxtmpl'){
                          this.$set(this.answerCode,quesIe.checkcode,[])
                        }
                        if(quesIe.questiontype=='imgtmpl' || quesIe.questiontype=='radiotmpl' || quesIe.questiontype=='selecttmpl'){
                          // this.answerCode[quesIe.checkcode] = ''
                          this.$set(this.answerCode,quesIe.checkcode,'')
                        }
                        quesIe.istop=false
                        // 子孙的显示隐藏
                        if (quesIe.istop==false) {
                          if (quesIe.childid) {
                            this.childitem = quesIe.childid.split(',')
                          }
                        }
                      }
                    })
                    if (this.childitem.indexOf(quesIe.orderid) != -1) {
                      if(quesIe.questiontype=='checkboxtmpl'){
                        this.$set(this.answerCode,quesIe.checkcode,[])
                      }
                      if(quesIe.questiontype=='imgtmpl' || quesIe.questiontype=='radiotmpl' || quesIe.questiontype=='selecttmpl' || quesIe.questiontype=='numiptmpl'){
                        // this.answerCode[quesIe.checkcode] = ''
                        this.$set(this.answerCode,quesIe.checkcode,'')
                      }
                      quesIe.istop=false
                    }
                  })
                  
                // }
              }
            }else{
              this.questionData.forEach(it=>{
                if(it.orderid==i.qita){
                  if(it.questiontype=='checkboxtmpl'){
                    this.$set(this.answerCode,it.checkcode,[])
                  }else{
                    this.$set(this.answerCode,it.checkcode,'')
                  }
                  it.istop=false
                }
              })
              
            }
          })
        }
      }
    }
  }
</script>
<style>
.el-table .hidden_box {
  display: none;
}
.foo{
  pointer-events: none;
}
</style>

地址组件

新建文件addressComp>index.vue

地址回显数据需要是中文数组,如果需要id可以自行修改所依赖数据可在props中查看

<template>
  <div>
    <el-cascader
      ref="labelValue"
      v-model="addressList"
      :options="deptOptions"
      :props="props"
      :size="size || 'medium'"
      :style="{'width': width}"
      @change="handleChange">
    </el-cascader>
  </div>
</template>

<script>

  import { treeselect } from '@/api/system/dept'

  export default {
    name: 'addressTemp',
    props: {
      inputCheckStrictly: [Boolean], // 是否可以选择任意一级, 默认false
      inputAddressList: [String], // 设置选项
      chinaAddressList: [String],
      size: [String], // 组件大小(medium / small / mini)
      width: [String] // 样式
    },
    data() {
      return {
        deptOptions: [],
        props: {
          value: 'id',
          label: 'label',
          children: 'children',
          checkStrictly: this.inputCheckStrictly
        },
        loginUserAddressList: this.$store.getters.tree || [], // 登录用户区划
        labelData:[],
        valueDataAs:[],
        addressList: [], // 选择区划结果
        setDefaultValueFlag: true, // 是否设置默认值
      }
    },
    watch: {
      inputAddressList: {
        handler(val) {
          // console.log(val);
          this.setDefaultValueFlag = false
          this.addressList = val.split(',')
          this.addressList.forEach((item,index) =>{
            this.addressList[index] = parseInt(this.addressList[index])
          })
          // if (val && val.length != 0) {
          //   this.setDefaultValueFlag = false
          //   let len = this.loginUserAddressList.length
          //   let startIndex = len - 1;
          //   this.addressList = val.slice(startIndex)
          //   this.resultAddressList()
          // }
          // else {
          //   this.setDefaultValueFlag = true
          //   let len = this.loginUserAddressList.length
          //   this.addressList = this.loginUserAddressList.slice(len - 1)
          //   this.resultAddressList()
          // }
        },
        immediate: true
      },
    },
    created() {
      this.getTreeselect()
    },
    methods: {
      /** 查询部门下拉树结构 */
      getTreeselect() {
        treeselect().then(response => {
          // console.log(this.$store.getters.addressList);
          this.deptOptions = response.data
          this.setDefaultValue()
        })
      },
      /** 级联下拉框选型变化时触发方法 */
      handleChange(value) {
        const checkedNodes = this.$refs['labelValue'].getCheckedNodes()
        this.valueDataAs=checkedNodes[0].path
        this.$emit('addressValue',this.valueDataAs)
        this.labelData=checkedNodes[0].pathLabels
        this.resultAddressList()
      },
      /** 为下拉框设置初始值 */
      setDefaultValue() {
        if (this.setDefaultValueFlag) {
          this.addressList = this.deptOptions[0].id
          this.$emit('resultAddressList', this.loginUserAddressList)
        } else {
          this.$emit('resultAddressList', this.$props.chinaAddressList)
        }
      },
      /** 返回选择区划方法 */
      resultAddressList() {
        let result = Object.assign([], this.labelData)
        // result.pop()
        // this.addressList.forEach(e => {
        //   console.log(e);
        //   result.push(e)
        // })
        // console.log('---------------resultAddressList:', result)
        this.$emit('resultAddressList', result)
      },
      /** 重置方法 */
      resetAddressList() {
        this.setDefaultValue()
      }
    }
  }
</script>

<style scoped>

</style>

图片上传组件

新建文件imageUploadComp>index.vue

<template>
  <div class="uploadImg">
    <el-upload
      :class="{hide:hideUploadEdit}"
      :limit="limit"
      action="fakeaction"
      :http-request="uploadFile"
      :headers="headers"
      list-type="picture-card"
      :on-change="handlePicChange"
      :on-remove="handlePicRemove"
      :before-upload="beforeAvatarUpload"
      :file-list="fileImgList">
        <i slot="default" class="el-icon-plus"></i>
        <div slot="file" slot-scope="{file}">
          <img
            width="100%"
            class="avatar"
            :src="file.url" alt=""
          >
          <span class="el-upload-list__item-actions">
            <span
              class="el-upload-list__item-preview"
              @click="handlePictureCardPreview(file)"
            >
              <i class="el-icon-zoom-in"></i>
            </span>
            <span
              v-if="!disabled"
              class="el-upload-list__item-delete"
              @click="handleRemove(file)"
            >
              <i class="el-icon-delete"></i>
            </span>
          </span>
        </div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>
<script>
import {getToken} from '@/utils/auth'
import { uploadfile } from '@/api/monitor/server.js'
import { deleteFilePhoto } from "@/api/servers/pc/questionDetailsCheck.js";
import {aliyun} from '@/utils/request.js'
  export default {
    name:'UploadImage',
    props:['limit','imgData','orderId'],
    data() {
      return {
        fileImgList:[],
        dialogImageUrl: '',
        dialogVisible: false,
        disabled: false,
        hideUploadEdit: false,//隐藏upload
        headers: {
          Authorization: 'Bearer ' + getToken(),
        },
      };
    },
    created(){
       this.personInfo = this.$store.getters.detailsdata
    },
    mounted() {
      if (this.$props.imgData) {
        // console.log(this.$props.imgData);
        let imgurl = this.$props.imgData;
        imgurl = imgurl.match(/dingcundaohu(\S*)/)[1]
        let imgcom = aliyun+imgurl
        this.fileImgList.push({url:imgcom})
        if (this.fileImgList.length >= this.limit) {
          this.hideUploadEdit = true
        }else{
          this.hideUploadEdit=false
        }
      }
    // 监听
      const unWatch = this.$watch("imgData", (newVal, oldVal) => {
        if (newVal) {
          // console.log(newVal);
          if (!this.fileImgList) {
            let imgurl = newVal;
            imgurl = imgurl.match(/dingcundaohu(\S*)/)[1]
            let imgcom = aliyun+imgurl
            this.fileImgList.push({url:imgcom})
            if (this.fileImgList.length >= this.limit) {
              this.hideUploadEdit = true
            }else{
              this.hideUploadEdit=false
            }
          }
        }
        unWatch(); // 取消监听
      });
    },
    methods: {
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpeg' || 'image/jpg' || 'image/png';
        const isLt2M = file.size / 1024 / 1024 < 2;

        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG PNG JPEG格式!');
        }
        if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
        }
        return isJPG && isLt2M;
      },
      uploadFile(params){
        const file = params.file;
        // 使用FormData传参数和文件
        var form = new FormData();
        // 文件
        form.append("file", file);
        // 参数
        form.append("answerId", this.personInfo.id);
        form.append("orderId", this.$props.orderId);
        // 调用封装好的上传方法,传给后台FormData
        uploadfile(form).then(resp=>{
          if(resp && resp.code == 200){
            let imgurl = resp.msg;
            imgurl = imgurl.match(/dingcundaohu(\S*)/)[1]
            let imgcom = aliyun+imgurl
            this.fileImgList.push({url:imgcom})
            let arrimg = [];
            arrimg.push({url:resp.msg})
            this.$emit('imgUrls',this.listToString(arrimg))
            this.$message({
              type:'success',
              message:'上传成功'
            });
          }
        })
      },
      handleRemove(file) {
        let deleteData = {
          answerId:this.personInfo.id,
          ques:'img',
          orderId:this.$props.orderId,
          tableName:this.personInfo.questionnaire
        }
        deleteFilePhoto(deleteData).then(res=>{
          this.$message({
            type:'success',
            message:'删除成功'
          });
        })
        const findex = this.fileImgList.map(f => f.path).indexOf(file.path)
        if (findex > -1) {
          this.fileImgList.splice(findex, 1)
          this.$emit('imgUrls',this.listToString(this.fileImgList))
        }
        if (this.fileImgList.length >= this.limit) {
          this.hideUploadEdit = this.fileImgList.length >= this.limit
        }else{
          this.hideUploadEdit=false
        }
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      handlePicRemove(file, fileList) {
       console.log(fileList);
        if (fileList.length >= this.limit) {
          this.hideUploadEdit = fileList.length >= this.limit
        }else{
          this.hideUploadEdit=false
        }
      },
      handlePicChange(file, fileList) {
        // 大于1张隐藏
        // console.log(fileList);
        if (fileList.length >= this.limit) {
          this.hideUploadEdit = fileList.length >= this.limit
        }else{
          this.hideUploadEdit=false
        }
      },
      listToString(list) {
        let strs = ''
        for (let i in list) {
          strs += list[i].url + ','
        }
        return strs != '' ? strs.substr(0, strs.length - 1) : ''
      }
    }
  }
</script>
<style>
  .hide .el-upload--picture-card {
    display: none;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值