前端--导出

这边记录我们公司后端做的导出接口和前端是如何对接的
    这边的技术栈是:
               1: react 

               2: fetch

第一步:简单封装--导出界面

import { DrawerForm } from '@ant-design/pro-components';
import { CloseOutlined } from '@ant-design/icons';
import { Col, Input, Row, Select, DatePicker, message, InputNumber, Card, Button } from 'antd'
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { DEPT_NAMESPACE } from "@/actions/dept";
import { getCurrentUser } from "@/utils/authority";
import { getDictBiz } from "@/utils/utils";
import { DICT_BIZ_NAMESPACE } from "@/actions/dictbiz";
import { clubSetMealSave, clubSetMealUpdate } from "@/services/club";
import { list } from '@/services/menu';

import style from './common.less';

const { TextArea } = Input;

function NewExp(props) {
     //show  是根据需要是否展示下方的弹窗
    //hang 是根据返回结果关闭弹窗
   //changeHange 是根据需要把参数返回出去
  //title  是弹窗的标题
 //Component  是触发弹窗的关键
    const {  title, Component, changeHange, hang, show } = props

    //  时间
    const [startDate, setStartDate] = useState(null)
    const [startDate1, setStartDate1] = useState(null)
    const [flag, setflag] = useState(false)


    const submit = async () => {

        // 判断时间
        if (!show) {
            if (startDate != null || startDate1 != null) {
                // 时间比较大小
                if (startDate1 < startDate) {
                    return message.error('结束时间不能小于开始时间')
                }
                let data = {
                    d1: startDate,
                    d2: startDate1,
                }
                changeHange(data)
                if (hang() == 1) {
                    setflag(false)
                    setStartDate(null)
                    setStartDate1(null)
                }
            }
        } else {
            changeHange()
            if (hang() == 1) {
                setflag(false)
                setStartDate(null)
                setStartDate1(null)
            }
        }

        // if (res?.success) {
        //     message.success('保存成功')
        //     setflag(false)
        //     changeupadte()

        // }


    }





    const onChange = (date, dateString) => {

        setStartDate(dateString)
    };
    const onChange1 = (date, dateString) => {

        setStartDate1(dateString)
    };



    return (
        <>
            {!show ?
                <>
                    <DrawerForm
                        className={style.common}
                        submitter={{
                            resetButtonProps: { type: 'dashed' },
                            submitButtonProps: { style: { display: 'none' } },
                            resetButtonRender: (_, dom) => null,
                            //   <Button key="submit" type="primary" onClick={() => { submit() }}>保存</Button>
                            render: (props, defaultDoms) => {
                                return [
                                    <Button key="clean" onClick={() => { setflag(false) }}>取消</Button>,
                                    <Button key="close" type="primary" onClick={() => { submit('pass') }}>下载</Button>,

                                ]

                            }

                        }} drawerProps={{
                            closeIcon: null,
                            destroyOnClose: true,
                            extra: <CloseOutlined onClick={() => setflag(false)} />
                        }}
                        visible={flag}
                        onVisibleChange={(e) => {
                            setflag(e)
                        }}
                        width={440}
                        onFinish={() => submit()}
                        title={
                            <span style={{
                                color: '#1F1F1F',
                                fontSize: '18px',
                                fontWeight: 600,
                                height: '22px',
                                lineHeight: '22px'
                            }}>{title}</span>
                        }
                        trigger={Component}
                    >


                        <div style={{ ...style0 }}>
                            <div style={{ ...style1 }}>
                                导出开始时间
                            </div>

                            <DatePicker placeholder='请选择开始时间' style={{ ...style2 }} onChange={onChange} />
                        </div>
                        <div style={{ ...style0, margin: '20px 0' }}>
                            <div style={{ ...style1, }}>
                                导出结束结束
                            </div>

                            <DatePicker placeholder='请选择结束时间' style={{ ...style2 }} onChange={onChange1} />
                        </div>

                    </DrawerForm>
                </>
                :
                <>
                    <Button
                        onClick={() => { submit('pass') }}
                        type="primary">
                        导出
                    </Button>
                </>}

        </>

    )
}
const style0 = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
}
const style1 = {
    width: '22%'
}
const style2 = {
    width: '76%'
}
const mapStateToProps = (state) => {
    return {
        
    };
};

export default connect(mapStateToProps)(NewExp)

 

第二步:封装请求导出js-----utils
     

import {  stringify } from 'qs';//引入qs库

export async function download(url, params) {
  // /api/blade-cust/custhubAppointment/export-customer
  const urls = `/api/${url}?${stringify(params)}`;

  const response = await fetch(urls, {
    method: 'GET',
    headers: {
      'Authorization': ``,
      'Blade-Auth': `Bearer ${getAccessToken()}` //请求token,
      'Content-Type': 'application/json' //JSON形式----有时候也是具体什么时候用看需求                  
       //responseType:"blob",,
    }
  });

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const blob = await response.blob();
  const contentDisposition = response.headers.get('content-disposition');
  const filename = contentDisposition ? contentDisposition.split('filename=')[1].replace(/"/g, '') : 'exported_data.csv';

  const urlBlob = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  if (a) {
//创建了一个a  直接下载  
    a.href = urlBlob;
    a.download = filename;
    document.body.appendChild(a);

    a.click();
    a.remove();
    window.URL.revokeObjectURL(urlBlob);
    return true //这边是给我返回成功的状态
  }

}

 第三步:导入封好的js---使用

import { download } from '@/utils/utils'

  const hang = () => {
        return 1
    }

    const changeHange = async (e) => {
        try {
//这个都是 参数---接口需要
            const startTime = e.d1;
            const endTime = e.d2;
            const type = userRole;
            const bigType = defaultvalue;
            const params1 = {
                startTime,
                endTime,
                type,
                bigType
            };
            let d = await download('blade-cust/custhubCustomer/export-customer', params1)
            if (d) {
                message.success('导出成功,请保存')
                hang()
            }
        } catch (error) {
            console.error('Export failed:', error);
        }

    }
 //导出显示组件
  <NewExps title={'导出'}
                                hang={hang}
                                Component={
                                    <Button type="primary">
                                        导出
                                    </Button>}
                                changeHange={changeHange}
                            ></NewExps>

 上方是不用打开新的页面---直接可以点击下载的
 这个是打开新界面---代码奉献上---弹窗一个 直接会弹出对应的下载框

import { Upload, Switch, Button, Card, Col, Input, message, Modal, Row, Tree } from 'antd';

 Modal.confirm({
      title: '用户导出确认',
      content: '是否导出用户数据?',
      okText: '确定',
      okType: 'danger',
      cancelText: '取消',
      onOk() {
        const account = params.account || '';
        const realName = params.realName || '';
        window.open(
          `/api/blade-system/user/export-user?Blade-Auth=bearer ${getAccessToken()}&account=${account}&realName=${realName}`
        );
      },
      onCancel() {},
    });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/684872.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不会制作企业版电子书?学会这几个步骤就好啦!

公司安排你制作一本专业的电子书&#xff0c;不知道如何下手&#xff1f;别担心&#xff0c;今天LookLook同学就来给大家分享一下如何轻松制作企业版电子书。参考这几个步骤&#xff0c;相信你一定能轻松搞定&#xff01; 第一步&#xff1a;明确电子书的目标和受众 在开始制作…

【ai】DeepStream 简介

NVIDIA Metropolis 平台。 NVIDIA 大都会 利用视觉 AI 将来自数万亿物联网设备的数据转化为有价值的见解。 NVIDIA Metropolis 是一个应用程序框架、一套开发工具和合作伙伴生态系统,它将视觉数据和 AI 结合在一起,以提高各行各业的运营效率和安全性。它有助于理解数万亿个…

漏洞挖掘 | 验证码绕过

还是老规矩&#xff0c;开局一个登录框&#xff0c;中途漏洞全靠舔&#xff0c;先来研究一下这个登录窗口 很好&#xff0c;发现有验证码登录&#xff0c;先测试测试能不能并发 看来没有&#xff0c;只成功发送了两条&#xff0c;再看看验证码是不是4位 很好&#xff0c;是4位。…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十八)- 微服务(8)

目录 11.4 SpringAMQP 11.4.2 Work Queue工作队列 11.4.3 发布订阅模型 11.4.4 FanoutExchange(广播交换机) 11.4.5 DirectExchange(路由模式交换机) 11.4.6 TopicExchange 11.5 消息转换器 11.4 SpringAMQP 父工程引入AMQP依赖 <!--AMQP依赖&#xff0c;包含RabbitMQ…

什么无线领夹麦克风音质最好?领夹麦克风品牌排行榜前十名推荐

​在当今的数字化浪潮中&#xff0c;个人声音的传播和记录变得尤为重要。无论是会议中心、教室讲台还是户外探险&#xff0c;无线领夹麦克风以其卓越的便携性和连接稳定性&#xff0c;成为了人们沟通和表达的首选工具。面对市场上琳琅满目的无线麦克风选择&#xff0c;为了帮助…

中国出海企业“奔赴”俄罗斯蓝海 有哪些认知需要对齐? | TopOn变现干货

中国企业加速出海已成常态化。在出海大潮席卷下&#xff0c;中国企业的身影已遍布欧美、东南亚、拉美、中东等多个成熟市场和潜力市场&#xff0c;眼下&#xff0c;这些热门市场几成红海&#xff0c;准入门槛也相对提高。而俄罗斯市场&#xff0c;作为全球TOP10的经济体之一&am…

在Linux上的Java项目导出PDF乱码问题

在Linux上的Java项目导出PDF乱码问题 场景&#xff1a;一个Java项目导出PDF&#xff0c;在我本地导出是没有问题&#xff0c;但是部署上Linux上后&#xff0c;导出就出现了乱码了。 处理方案 我这里使用的处理方案是在Linux服务器上安装一些PDF需要使用的字体 1.把字体上传到…

找寻卓越的生成式人工智能应用案例?别浪费在无趣之处!

“ 生成式AI&#xff08;AI&#xff09;技术的强大众所周知。但不知道你们是否和我有一样感觉&#xff0c;目前市面上&#xff0c;企业对生成式AI的应用&#xff0c;场景大多较为单一。” Ingo Mierswa Altair产品开发高级副总裁 我说这些生成式AI的应用单一&#xff0c;是指…

upload-labs-第五关

目录 第五关 1、构造.user.ini文件 2、构造一个一句话木马文件&#xff0c;后缀名为jpg 3、上传.user.ini文件后上传flag.jpg 4、上传成功后访问上传路径 第五关 原理&#xff1a; 这一关采用黑名单的方式进行过滤&#xff0c;不允许上传php、php3、.htaccess等这几类文件…

区块链(Blockchain)调查研究

文章目录 1. 区块链是什么&#xff1f;2. 区块链分类和特点3. 区块链核心关键技术3.1 共识机制3.2 密码学技术3.4 分布式存储3.5 智能合约 4. 区块链未来发展趋势5. 区块链 Java 实现小案例 1. 区块链是什么&#xff1f; 区块链是分布式数据存储、点对点传输、共识机制、加密算…

在自己的esp idf工程中添加ESP-ADF

其实esp-adf也就相当于是一个组件&#xff0c;直接在工程的CMakeList.txt中加入就行&#xff0c;这样就可以满足自己的需要&#xff0c;直接在当前工程上增加adf&#xff0c;使用其中的部分功能。 参考adf基础工程可以发现&#xff0c;一条命令即可。 include($ENV{ADF_PATH}/…

【ocean】测试phaseDeg,phaseDegUnwrapped和phaseMargin

对二级运放进行测试 -101.35,78.01,78.01 GBW gainBwProd((VF("/Vout2") / VF("/Vin")))PHASE phaseDegUnwrapped((VF("/Vout2") / VF("/Vin")))plot( PHASE ?expr ( "PHASE" ) ) PHASEdeg phaseDeg((VF("/Vout2&q…

SQL语句练习每日5题(二)

题目1——查找学校是北大的学生信息 筛选出所有北京大学的学生进行用户调研&#xff0c;请你从用户信息表中取出满足条件的数据&#xff0c;结果返回设备id和学校。 解法&#xff1a;考察where条件语句 select device_id,university from user_profile where university北京…

如何做谷歌seo排名优化?Google SEO优化步骤你更快获得谷歌排名

谷歌SEO优化&#xff08;搜索引擎优化&#xff09;是一系列策略和技巧&#xff0c;旨在提高网站在谷歌搜索结果中的排名&#xff0c;从而增加有机流量。以下是一些关键的谷歌SEO优化步骤&#xff1a; 1. 关键词研究 选择合适的关键词&#xff1a;使用工具如Google Keyword Pl…

webservice、WCF、webAPI、MVC权限认证

webservice 权限认证 》》soapHeader SOAPHeader案例 服务引用下生成的服务方法参数中会自动加入一个soapHeader的参数&#xff0c; WEB服务引用则没有&#xff0c;我感觉采用WEB服务引用基于这种验证比较方便&#xff0c; 因为只需将soapHeader实例赋值一次就可以多次调用不…

windows11 安装cnpm 报错 Error: EPERM: operation not permitted 没权限

全部试过&#xff1a; 您遇到的错误是EPERM: operation not permitted&#xff0c;这意味着npm在尝试重命名文件或目录时缺少必要的权限。这通常与操作系统的权限设置有关。为了解决这个问题&#xff0c;您可以尝试以下几个步骤&#xff1a; 以管理员身份运行命令行&#xff1…

Python 可变长参数的魔法:灵活函数设计的秘密

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 什么是可变长参数&#xff1f; 在 Python 中&#xff0c;可变长参数允许你向函数传入任意数量的参数&#xff0c;而无需预先定义它们的个数。这为编写更加灵活和通用的函数提供了可能。可变长参数主要有两种形式&am…

使用kafka tools工具连接带有用户名密码的kafka

使用kafka tools工具连接带有用户名密码的kafka 创建kafka连接&#xff0c;配置zookeeper 在Security选择Type类型为SASL Plaintext 在Advanced页面添加如下图红框框住的内容 在JAAS_Config加上如下配置 需要加的配置&#xff1a; org.apache.kafka.common.security.plain.Pla…

如何通过内容识别关键词保护商业机密防泄漏

在数字化商业环境中&#xff0c;商业机密的保护对于企业的竞争力至关重要。随着数据泄露事件的增多&#xff0c;企业越来越需要采取有效措施来保护其敏感信息。内容识别技术&#xff0c;特别是关键词识别&#xff0c;已成为防止商业机密泄漏的重要手段。本文将探讨如何利用这一…

微软新AI工具 Recall 被白帽公开锤了?

近日&#xff0c;一些网络安全研究人员演示了恶意软件是如何成功窃取 Windows Recall 工具收集到的数据。 2024年5月21日&#xff0c;微软发布全新的“CopilotPC”&#xff0c;这类 AI PC 通过与高通的最新芯片合作&#xff0c;实现了一个叫做“Recall”的功能。借助这个人工智…