一些点的记录3

1.图片下载

本来a标签有个download属性,指定文件名就可以下载,但现在浏览器里都只能预览了,那么只能另外一种方式,

将图片装换成 Data URLs下载图片

看这篇https://blog.csdn.net/qq_43258252/article/details/85063970

和这篇 http://www.360doc.com/content/19/1229/12/26535044_882890313.shtml

这篇最屌https://www.cnblogs.com/lijuntao/p/11557199.html,图片,文件全都能下

我的react中做的完整案例

包括粘贴获取图片,图片转为base64,图片上传(我的那篇文章https://blog.csdn.net/qq_41430522/article/details/116278894解释了fetch的坑,不能把formdata给JSON。stringfy,不然放不到请求体里),自己的写的upload图片上传,包括删除图片,下载图片,formData的基本使用,还包括表单的一些基本操作,cookie的一些操作携带等,还是挺不错一个例子

/**
 * 新增缺陷弹出框
 */
"use strict";
import "./index.less";
import React, { Component } from "react";
import { message } from "edspUI";
import moment from "moment";
import {
  InfoCircleOutlined,
  FolderOutlined,
  CopyFilled,
  VerticalAlignBottomOutlined,
  DeleteOutlined,
} from "@ant-design/icons";
import { Language } from "Utils";
import {
  Modal,
  Select,
  Tooltip,
  Icon,
  Form,
  Input,
  Button,
  Checkbox,
  DatePicker,
} from "antd";
import { jiraService, jiraService1 } from "Services";
const FormItem = Form.Item;
const Option = Select.Option;
const { TextArea } = Input;
//资源国际化
const i18n = Language.getLanguage("jira");
class AddIssueModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: this.props.showModal, //是否显示弹出框
      text: "支持多文件同时上传", //tooltip提示框文字
      fileList: [],
      defectTitle: "",
      creatorName: "", //创建人姓名
      systemInfoIdList: [], // 被测系统列表
      moduleInfoIdList: [], // 被测模块列表
      selTradeList: [], // 交易信息列表
      selWindowList: [], // 目标版本列表
      currenetSystemId: "",
      timeNow: "",

      moduleInfoIdList1: [], // 被测模块列表
      selTradeList1: [], // 交易信息列表
      currenetSystemId1: "",
    };
  }

  componentWillMount() {
    this.refresh();
    this.setState((state) => ({
      creatorName: JSON.parse(localStorage.getItem("user_claims")).usrnam,
    }));
    this.selPersonByName();
    this.selAllSysName();
    this.selWindow();
    // 为所属开发项目 表单赋初始值 738
    this.props.form.projectDevId = 738;
    // 为所属测试组 表单赋初始值 接口自动化测试组
    this.props.form.groupId = "接口自动化测试组";
  }
  componentDidMount() {}
  refresh() {}
  // 获取人员信息
  selPersonByName = () => {
    let params = {
      input: {},
      sys: {
        prcscd: "selPersonByName",
      },
    };
    params.input.person_name = JSON.parse(
      localStorage.getItem("user_claims")
    ).usrnam;
    params.input.tentid = localStorage.getItem("TENTID");
    let that = this;
    //新增和修改
    jiraService.selPersonByName(params, function (res) {
      //S表示成功
      if (res.sys.status == "S") {
        if (res.output.issuce == "true") {
          // 成功了就打印下看看
          that.props.form.bugCreator = res.output.person.id;
        } else {
          message.error(res.output.mesage);
        }
      } else {
        message.error(res.sys.erortx);
      }
    });
  };
  // 获取所有系统信息
  selAllSysName = () => {
    let params = {
      input: {},
      sys: {
        prcscd: "selAllSysName",
      },
    };
    params.input.tentid = localStorage.getItem("TENTID");
    let that = this;
    //新增和修改
    jiraService.selAllSysName(params, function (res) {
      //S表示成功
      if (res.sys.status == "S") {
        if (res.output.issuce == "true") {
          let arr = res.output.sysname.map((el) => ({
            value: el.sys_name,
            id: el.sys_no,
          }));
          that.setState((state) => {
            return {
              systemInfoIdList: arr.concat(),
            };
          });
        } else {
          message.error(res.output.mesage);
        }
      } else {
        message.error(res.sys.erortx);
      }
    });
  };
  // 获取目标版本
  selWindow = () => {
    let params = {
      input: {},
      sys: {
        prcscd: "selWindow",
      },
    };
    params.input.tentid = localStorage.getItem("TENTID");
    let that = this;
    //新增和修改
    jiraService.selWindow(params, function (res) {
      //S表示成功
      if (res.sys.status == "S") {
        if (res.output.issuce == "true") {
          let arr = res.output.windowlist.map((el) => ({
            value: el.window_name,
            id: el.id,
          }));
          that.setState((state) => {
            return {
              selWindowList: arr.concat(),
            };
          });
        } else {
          message.error(res.output.mesage);
        }
      } else {
        message.error(res.sys.erortx);
      }
    });
  };
  // 获取被测模块 传选的被测系统的id
  selModuBySysid = (id, type) => {
    if (type == "belong") {
      this.props.form.setFieldsValue({ bugGmodule: "" });
      this.props.form.setFieldsValue({ bugGtrade: "" });
      this.setState({
        moduleInfoIdList1: [],
        selTradeList1: [],
        currenetSystemId1: id,
      });
    } else if (type == "beTested") {
      this.props.form.setFieldsValue({ moduleInfoId: "" });
      this.props.form.setFieldsValue({ bugSystemfunction: "" });
      this.setState({
        moduleInfoIdList: [],
        selTradeList: [],
        currenetSystemId: id,
      });
    }

    let params = {
      input: { id },
      sys: {
        prcscd: "selModuBySysid",
      },
    };
    params.input.tentid = localStorage.getItem("TENTID");
    let that = this;
    //新增和修改
    jiraService.selModuBySysid(params, function (res) {
      //S表示成功
      if (res.sys.status == "S") {
        if (res.output.issuce == "true") {
          let arr = res.output.module_name.map((el) => ({
            value: el.module_name,
          }));
          if (type == "belong") {
            that.setState((state) => {
              return {
                moduleInfoIdList1: arr.concat(),
              };
            });
          } else if (type == "beTested") {
            that.setState((state) => {
              return {
                moduleInfoIdList: arr.concat(),
              };
            });
          }
        } else {
          message.error(res.output.mesage);
        }
      } else {
        message.error(res.sys.erortx);
      }
    });
  };
  // 获取被测模块 传选的被测系统的id 被测模块的value
  selTradeByModu = (module_name, type) => {
    let params = {
      input: { system_info_id: this.state.currenetSystemId, module_name },
      sys: {
        prcscd: "selTradeByModu",
      },
    };
    params.input.tentid = localStorage.getItem("TENTID");
    let that = this;
    //新增和修改
    jiraService.selTradeByModu(params, function (res) {
      //S表示成功
      if (res.sys.status == "S") {
        if (res.output.issuce == "true") {
          let arr = res.output.trade.map((el) => ({
            id: el.id,
            value: el.trade_name,
          }));
          if (type == "belong") {
            that.setState((state) => {
              return {
                selTradeList1: arr.concat(),
              };
            });
          } else if (type == "beTested") {
            that.setState((state) => {
              return {
                selTradeList: arr.concat(),
              };
            });
          }
        } else {
          message.error(res.output.mesage);
        }
      } else {
        message.error(res.sys.erortx);
      }
    });
  };
  pasteImg = (e) => {
    e.preventDefault();
    //正式
    let blob = null;
    if (e.clipboardData || e.originalEvent) {
      let clipboardData = e.clipboardData || e.originalEvent.clipboardData;
      if (clipboardData.items) {
        let items = clipboardData.items;
        let len = items.length;
        // 循环拿到所有图片文件  至于选择文件就另外放到一个list里吧,
        // 就不展示出来了,要不还是展示出来吧,不过展示在那下面比较好 嗯嗯
        // 如果是图片就添加到上面去,其他文件就放下面
        for (let i = 0; i < len; i++) {
          if (items[i].type.includes("image")) {
            blob = items[i].getAsFile();
            this.setState((state) => ({
              fileList: [...state.fileList, blob],
            }));
          }
        }
      }
    }
  };
  handleTitle = (e) => {
    if (!e.target.value) {
      return;
    }
    this.setState({
      defectTitle: e.target.value,
    });
  };
  // 选择文件时吧文件放进列表渲染
  handleFileChange = (e) => {
    for (let file of e.target.files) {
      let fd = new FormData();
      fd.append("file", file);
      this.setState((state) => ({
        fileList: [...state.fileList, file],
      }));
    }
  };
  // 删除图片
  delFile = (file) => {
    this.setState((state) => {
      // 真没想到indexOf可以根据file来找。。。。之前都只能找单层的数组
      const index = state.fileList.indexOf(file);
      const newFileList = state.fileList.slice();
      newFileList.splice(index, 1);
      return {
        fileList: newFileList,
      };
    });
  };
  // 下载图片
  // downFile = (file) => {
  //   const image = new Image();
  //   // 解决跨域 canvas 污染问题
  //   image.setAttribute("crossOrigin", "anonymous");
  //   image.onload = function () {
  //     const canvas = document.createElement("canvas");
  //     canvas.width = image.width;
  //     canvas.height = image.height;
  //     const context = canvas.getContext("2d");
  //     context.drawImage(image, 0, 0, image.width, image.height);
  //     //得到图片的base64编码数据
  //     const url = canvas.toDataURL("image/png");
  //     // 生成一个 a 标签
  //     const a = document.createElement("a");
  //     // 创建一个点击事件
  //     const event = new MouseEvent("click");
  //     // 将 a 的 download 属性设置为我们想要下载的图片的名称,若 name 不存在则使用'图片'作为默认名称
  //     a.download = file.name || "图片";
  //     // 将生成的 URL 设置为 a.href 属性
  //     a.href = url;
  //     // 触发 a 的点击事件
  //     a.dispatchEvent(event);
  //     // return a;
  //   };
  //   let reader = new FileReader();
  //   reader.readAsDataURL(file);
  //   reader.onload = function (res) {
  //     if (res.target.result) {
  //       image.src = res.target.result;
  //     }
  //   };
  // };
  // 下载图片和文件
  downFile = (file) => {
    let a = document.createElement("a");
    let url = window.URL.createObjectURL(file);
    a.href = url;
    a.download = file.name;
    a.click();
    window.URL.revokeObjectURL(url);
  };
  handleTimeChoose = (e1, e2) => {
    this.setState({ timeNow: e2 });
  };
  render() {
    const { hideModal } = this.props;
    const {
      text,
      fileList,
      creatorName,
      systemInfoIdList,
      selWindowList,
      moduleInfoIdList,
      selTradeList,
      moduleInfoIdList1,
      selTradeList1,
    } = this.state;
    const fileRender = fileList.map((el) => {
      return (
        
  • {el.name}
    { this.downFile(el); }} style={ { marginRight: "10px" }} /> { this.delFile(el); }} style={ { marginRight: "10px" }} />
  • ); }); const dateFormat = "YYYY-MM-DD"; const modalOpt = { title: "新增缺陷", width: 1200, visible: this.state.showModal, onOk: () => this.handleSubmit(), onCancel: () => hideModal && hideModal(false), okText: i18n.ok, cancelText: i18n.cancel, maskClosable: false, }; const { getFieldDecorator, getFieldValue } = this.props.form; const formItemLayout = { labelCol: { span: 5 }, wrapperCol: { span: 16 }, }; const systemInfoIdListOption = systemInfoIdList.map((el) => { return ; }); const windowlistOption = selWindowList.map((el) => { return ; }); const moduleInfoIdListOption = moduleInfoIdList.map((el) => { return ; }); const selTradeListOption = selTradeList.map((el) => { return ; }); const moduleInfoIdListOption1 = moduleInfoIdList1.map((el) => { return ; }); const selTradeListOption1 = selTradeList1.map((el) => { return ; }); return ( {/* 头部 */}
    缺陷摘要:
    {/* 下面部分,分为左右两部分 */}
    提示:
    {/* */}
    支持粘贴图片...
    选择....
      {fileRender}
    {/* 所属开发项目 */} {getFieldDecorator("projectDevId", { rules: [ { required: true, message: `${i18n.projectDevId}${i18n.isNotNull}`, }, ], initialValue: "SunATP_自动化测试平台", })( )} {/* 目标版本 */} {getFieldDecorator("targetVersion", { rules: [ { required: true, message: `${i18n.targetVersion}${i18n.isNotNull}`, }, ], })( )} {/* 所属迭代 */} {getFieldDecorator("iteration", { rules: [ { required: false, message: `${i18n.iteration}${i18n.isNotNull}`, }, ], })( )} {/* 缺陷来源 */} {getFieldDecorator("bugResource", { rules: [ { required: false, message: `${i18n.bugResource}${i18n.isNotNull}`, }, ], })( )} {/* 缺陷来源编号 */} {getFieldDecorator("bugResourceCode", { rules: [ { required: false, message: `${i18n.bugResourceCode}${i18n.isNotNull}`, }, ], })( )} {/* 所属任务 */} {getFieldDecorator("testTaskId", { rules: [ { required: false, message: `${i18n.testTaskId}${i18n.isNotNull}`, }, ], })( )} {/* 测试阶段 */} {getFieldDecorator("taskStage", { rules: [ { required: true, message: `${i18n.taskStage}${i18n.isNotNull}`, }, ], })( )} {/* 测试类型 */} {getFieldDecorator("bugTestType", { rules: [ { required: true, message: `${i18n.bugTestType}${i18n.isNotNull}`, }, ], })( )} {/* 缺陷发现轮次 */} {getFieldDecorator("roundId", { rules: [ { required: true, message: `${i18n.roundId}${i18n.isNotNull}`, }, ], })( )} {/* 缺陷摘要 */} {getFieldDecorator("bugTitle", { rules: [ { required: true, message: `${i18n.bugTitle}${i18n.isNotNull}`, }, ], })( )} {/* 所属测试组 */} {getFieldDecorator("groupId", { rules: [ { required: true, message: `${i18n.groupId}${i18n.isNotNull}`, }, ], initialValue: "接口自动化测试组", })( )} {/* 被测系统 */} {getFieldDecorator("systemInfoId", { rules: [ { required: true, message: `${i18n.systemInfoId}${i18n.isNotNull}`, }, ], })( )} {/* 被测模块 */} {getFieldDecorator("moduleInfoId", { rules: [ { required: true, message: `${i18n.moduleInfoId}${i18n.isNotNull}`, }, ], })( )} {/* 所属交易/功能 */} {getFieldDecorator("bugSystemfunction", { rules: [ { required: true, message: `${i18n.bugSystemfunction}${i18n.isNotNull}`, }, ], })( )} {/* 所属案例编号 */} {getFieldDecorator("caseId", { rules: [ { required: false, message: `${i18n.caseId}${i18n.isNotNull}`, }, ], })( )} {/* 优先级 */} {getFieldDecorator("bugPriority", { rules: [ { required: true, message: `${i18n.bugPriority}${i18n.isNotNull}`, }, ], })( )} {/* 分派给 */} {getFieldDecorator("bugDisper", { rules: [ { required: true, message: `${i18n.bugDisper}${i18n.isNotNull}`, }, ], })( )} {/* 计划解决时间 */} {getFieldDecorator("bugJtime", { rules: [ { required: false, message: `${i18n.bugJtime}${i18n.isNotNull}`, }, ], })( // )} {/* 缺陷F分析 */} {getFieldDecorator("bugAnalysis", { rules: [ { required: true, message: `${i18n.bugAnalysis}${i18n.isNotNull}`, }, ], })( )} {/* 归属系统 */} {getFieldDecorator("bugGsystem", { rules: [ { required: true, message: `${i18n.bugGsystem}${i18n.isNotNull}`, }, ], })( )} {/* 归属模块 */} {getFieldDecorator("bugGmodule", { rules: [ { required: true, message: `${i18n.bugGmodule}${i18n.isNotNull}`, }, ], })( )} {/* 归属交易/功能 */} {getFieldDecorator("bugGtrade", { rules: [ { required: true, message: `${i18n.bugGtrade}${i18n.isNotNull}`, }, ], })( )} {/* 缺陷类型 */} {getFieldDecorator("bugType", { rules: [ { required: true, message: `${i18n.bugType}${i18n.isNotNull}`, }, ], })( )} {/* 缺陷严重性 */} {getFieldDecorator("bugSeverity", { rules: [ { required: true, message: `${i18n.bugSeverity}${i18n.isNotNull}`, }, ], })( )} {/* 创建人 */} {getFieldDecorator("bugCreator", { rules: [ { required: true, message: `${i18n.bugCreator}${i18n.isNotNull}`, }, ], initialValue: creatorName, })()} {/* 缺陷发现环境 */} {getFieldDecorator("bugEnvir", { rules: [ { required: true, message: `${i18n.bugEnvir}${i18n.isNotNull}`, }, ], })( )} {/* 需求提出部门 */} {getFieldDecorator("dept", { rules: [ { required: true, message: `${i18n.dept}${i18n.isNotNull}`, }, ], })( )} {/* 缺陷描述 */} {getFieldDecorator("bugDesc", { rules: [ { required: true, message: `${i18n.bugDesc}${i18n.isNotNull}`, }, ], })(