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}
);
}
handleBeforesubmit = (callback) => {
let imgarr = [];
let fileLength = 0;
let reader = new FileReader();
if (this.state.fileList.length == 0) {
return callback([]);
}
reader.readAsDataURL(this.state.fileList[fileLength]);
let that = this;
// 通过filereader,用readAsDataURL把files文件列表的文件一个个读取成base64
// 每次读取好了就会触发它的onload事件
// 要注意的是,filereader每次只能读取一个文件,所以这里才用这种长度判断
// 的方式不停的循环读取
reader.onload = function (res) {
if (res.target.result) {
imgarr.push(res.target.result);
fileLength++;
if (fileLength < that.state.fileList.length) {
reader.readAsDataURL(that.state.fileList[fileLength]);
} else {
callback(imgarr);
}
}
};
};
clearAllCookie() {
var date = new Date();
date.setTime(date.getTime() - 10000);
var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
if (keys) {
for (var i = keys.length; i--; )
document.cookie =
keys[i] + "=0; expires=" + date.toGMTString() + "; path=/";
}
}
handleRealsubmit = (imgarr) => {
let that = this;
const { defectTitle, timeNow } = this.state;
const { hideModal } = this.props;
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
values.bugJtime = timeNow;
let params = {
projectId: localStorage.getItem("PROJID"),
defectTitle,
datas: values,
};
if (!defectTitle) {
return message.error("请输入缺陷标题");
}
document.cookie = `projectId=${localStorage.getItem("PROJID")};`;
document.cookie = `Authorization=${localStorage.getItem(
"access_token"
)};`;
jiraService1.bugManagement(params, function (res) {
// S表示成功;
if (res.code == 200) {
// 成功之后得到返回的id,然后再发接下来的两个请求,上传图片请求
if (imgarr.length > 0) {
// document.cookie = "token=0;expires=" + new Date().toUTCString();
jiraService1.uploadImg(
{ src: [...imgarr], defectId: res.data },
function (res) {
if (res.code == 200) {
message.success("成功");
} else {
message.error("失败");
}
}
);
}
for (let i = 0; i < that.state.fileList.length; i++) {
let fd = new FormData();
fd.append("file", that.state.fileList[i]);
fd.append("defectId", res.data);
jiraService1.uploadAccessory(fd, function (res) {
if (res.code == 200) {
if (i == that.state.fileList.length) {
hideModal && hideModal(false);
}
message.success("成功");
} else {
message.error("失败");
}
});
}
message.success("成功");
} else {
message.error("失败");
}
});
}
});
};
handleSubmit = () => {
// 点击确定提交
// 先执行一个函数,吧base64都读出来
// 然后再执行提交的操作
this.handleBeforesubmit(this.handleRealsubmit);
};
}
const MyForm = Form.create()(AddIssueModal);
export default MyForm;
2.ant中的form清空某个表单值
https://www.cnblogs.com/xlizi/p/13653004.html