公共组件封装之:邮件导出弹框

需求描述:

    对页面上的表格数据进行导出。具体导出方式如下:

      1. 当数据量少于或等于 6000 条时,用户可以直接在页面上导出数据,不需要弹出弹框。

      2. 当数据量超过 6000 条时,需要执行以下步骤:

            ① 弹出一个提示框,要求用户输入他们的邮箱地址和备注信息,需校验邮箱必填和输入的必须是邮件格式。

           ②用户填写邮箱地址和备注信息后,点击确认按钮。

           ③后端将数据导出至用户提供的邮箱地址中。

1 封装的vue组件

<style lang="less" scoped>
.icon{
  position: relative;
  top: -1px;
  right: 5px;
  font-size: 16px;
  padding-left: 10px;
} 
</style>

<template>
  <div>
    <!-- 弹窗录入邮箱 -->
    <Modal v-model="showEmailInput" width="600" @on-cancel="cancelCsv" :mask-closable="false">
      <p slot="header" style="color:#f60;text-align:left">
        <Icon type="ios-information-circle" class="icon"></Icon>
        <span>请填写邮箱地址,并在稍后查看邮箱,请勿重复导出!</span>
      </p>
      <i-form ref="form" :label-width="100" :model="formValidate" :rules="ruleValidate">
        <Row>
          <Col span="22">
            <Form-item label="邮箱地址" prop="email" >
              <Input v-model="formValidate.email" clearable/>
            </Form-item>
          </Col>
        </Row>
        <Row>
          <Col span="22">
            <Form-item label="邮件留言">
              <Input v-model="formValidate.emailDes" clearable/>
            </Form-item>          
          </Col>
        </Row>
      </i-form>
      <div slot="footer">
        <i-button type="primary" ghost style="width:100px;" @click="cancelCsv">取消</i-button>
        <i-button type="primary" style="width:100px;;margin-left:40px;" @click="sendEmail">确认</i-button>
      </div>
    </Modal>
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState(['fileExport'])
  },
  data(){
    return {
      showEmailInput:false,
      formValidate:{
        email:"",
        emailDes:""
      },
      ruleValidate:{
        email:[
          { required: true, message: '必填项', trigger: 'change' },
          { type: 'email', message: '邮箱不正确', trigger: 'change' }
        ]
      }
    }
  },
  created(){
    // vuex 订阅模式, 在组件创建时,订阅字段变化
    this.$store.subscribe((mutation, state) => {
      // console.log(mutation, state.app.fileExport)
      this.showEmailInput = state.app.fileExport

      this.formValidate.email = ""
      this.formValidate.emailDes = ""
      if(state.app.isSuccessful){
        this.$Message.success("文件导出成功,请稍后查看邮箱!")
        this.$store.commit("updataSuccessful",false)
      }
    })
  },
  watch:{
    showEmailInput(newValue,oldValue){
      if(newValue === false){
        this.$refs.form.resetFields()
      }
    }
  },
  methods:{
    cancelCsv(){
      this.formValidate.email = ""
      this.formValidate.emailDes = ""
      this.$refs.form.resetFields()
      this.$store.commit("updataExport",false) 
    },

    sendEmail(){
      this.$refs.form.validate((valid) => {
        if(valid){
          let list = this.$store.state.app.derivedParameter
          list.email = this.formValidate.email
          list.emailDes = this.formValidate.emailDes
          const { param,methodNo,email,emailDes} = list 
          this.methodsEncapsulate.mailExport(param,methodNo,email,emailDes)
          this.$store.commit("updataExport",false) 
        }
      })
    }
  }
}
</script>

2. 对封装的组件在man.js中,进行全局注册

// 封装的公共弹框组件
import exportPackage from "@/views/my-components/modal-to/exportPackage.vue" 

// 公共的导出组件
Vue.component("exportPackage",exportPackage) 

3. 由于交互数据是存放在vuex中的,vuex中也需要增加一些字段

这是vuex中的目录结构

const app = { 
  // 这是存放在 state 中的数据
  state: { 
    fileExport:false, // 邮件导出,是否显示弹框
    isSuccessful:false, // 邮件导出是否成功
    derivedParameter:{}, // 邮件导出时需要的请求参数
  },
  // 这是 mutations 中的方法,用来修改state 中的数据
  mutations:{
    // 修改 导出值,显示弹框输入邮件地址
    updataExport(state,data){
      state.fileExport = data
    },

    // 请求参数赋值
    updataParameter(state,data){
      state.derivedParameter = data
    },

    // 是否导出成功
    updataSuccessful(state,data){
      state.isSuccessful = data
    },
  }
}
export default app

4. 单独新建一个methodsEncapsulate.js的文件,对其中的方法进行封装

注意:这个methodsEncapsulate.js,也需要在main.js中全局注册

  /**
   * 邮件导出 统一封装
   * @param {Object} data
   * @param {String} code
   * @param {String} email
   * @param {String} emailDes
   */
  mailExport(data = "",code = "",email = "",emailDes = ""){
    let list = {
      email:email,
      emailDes:emailDes,
      methodNo:code,
      param:data
    }
    Api.csvExport(list).then(response =>{ // 这地方是调接口的,成功之后进行相关
      if(response.result.method === "1"){ //  1 表示数据量少 直接前端导出即可
        let urls = response.result.urls
        urls.forEach( item =>{           // urls 需要导出文件的数组
          window.open(item,"_blank")
        })
      }else if(response.result.method === "2"){ // 2 表示数据量大,需要邮件导出
        store.commit("updataExport",true)  // 显示弹框
        store.commit("updataParameter",list)  // 请求参数存起来
        // console.log("***",store.state.app.fileExport)
      }else if(response.result.code !== "0"){
        // 是否正常 0-正常,不是0,表示异常,-1方法字典值不存在,-2 没有需要导出的数据, -3 导出数据超过邮件导出条数,请增加筛选条件 -4有正在进行的导出 -99 其他 ,
        modalMesssage(response.result.message) // 抛出异常信息
      }else {
        store.commit("updataSuccessful",true)  // 文件导出成功
      }
    })
  }

5. 在需要的组件中使用

    // 导出
    derive(){
      if(this.status === '0'){
        let data = {
          projectCode:this.projectCode,
          projectName:this.project,
          orderType:this.orderTypes,
          policyHolder:this.subjectInsurance,
          insureTimeBegin:this.timeInsurance[0] ? moment(this.timeInsurance[0]).format("YYYY-MM-DD"):"",
          insureTimeEnd:this.timeInsurance[1] ? moment(this.timeInsurance[1]).format("YYYY-MM-DD"):"",
          orderNo:this.orderNumber,
          policyNo:this.warrantyNumber, 
          inscomName:this.insuranceCompany,
          account:this.statisticalNot === "all" ? "":this.statisticalNot
        }
        // 传递 四个参数 data 是请求对象、"yqGroupExport" 是导出的码值
        this.methodsEncapsulate.mailExport(data,"yqGroupExport","","")
      }else if(this.status === '1'){
        let data = {
          projectCode:this.projectCode,
          projectName:this.project,
          orderType:this.orderTypes,
          bussinessMode:this.serviceIdentification,
          claimDateBegin:this.claimCompletion[0] ? moment(this.claimCompletion[0]).format("YYYY-MM-DD"):"",
          claimDateEnd:this.claimCompletion[1] ? moment(this.claimCompletion[1]).format("YYYY-MM-DD"):"",
          orderNo:this.orderNumber,
          policyNo:this.warrantyNumber,
          inscomName:this.insuranceCompany,
          account:this.statisticalNot === "all" ? "":this.statisticalNot
        }
        this.methodsEncapsulate.mailExport(data,"yqDrugExport","","")
      }
    },

5. 导出时必须要加的导出组件

<!-- 导出 如果数量超过6000条,就必须加这个 弹框-->
<exportPackage></exportPackage>

因为上面用到了 this.$store.subscribe,vuex订阅者模式,来订阅vuex中数据状态的变化,该状态的变化,大部分上都是在`created `钩子函数中订阅的。

想要订阅生效,就必须有地方要使用这个封装好的组件,来触发它,所以这里就要使用这个组件。

猜你喜欢

转载自blog.csdn.net/weixin_48674314/article/details/133387609