/**
* 新增缺陷弹出框
*/
"use strict";
import "./index.less";
import React, { Component } from "react";
import { message } from "edspUI";
import { Tooltip } from "antd";
import {
InfoCircleOutlined,
FolderOutlined,
CopyFilled,
} from "@ant-design/icons";
import { Language } from "Utils";
import { Modal, Form, Input, Select, Button, Upload, Icon } from "antd";
import { jiraService } 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提示框文字
supportShow: true,
myFileList: [], //文件渲染数组,用来放文件名字和src,这两种
realFileList: [], //真实文件列表
};
}
componentWillMount() {
this.refresh();
}
componentDidMount() {
// 页面挂载后,先初始化一个装文件的
this.setState({ realFileList: new FormData() });
}
refresh() {}
inputF = () => {};
pasteImg = (e) => {
console.log("失效吗");
// 一触发,就把图片隐藏
this.setState({ supportShow: false });
// let items = e.clipboardData.items;
// let len = items.length;
// console.log(
// e,
// e.clipboardData,
// e.clipboardData.types,
// e.clipboardData.files,
// e.clipboardData.items,
// e.clipboardData.items[0],
// e.clipboardData.items[0].getAsFile(),
// len,
// e.clipboardData.getData("Files"),
// e.clipboardData.getData("image/*")
// );
// 如果是复制纯文本,type为text/plain
// 如果是复制一张图片,type为Files
// 如果是复制多张图片,type为Files
// 如果是复制图片加文字,type是['text/plain','text/html']
// 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();
// 这里弄个时间戳给它,渲染的时候
// 有个删除,点击的时候,需要同步删除
let time = new Date().getTime();
this.state.myFileList.push({
fileName: blob.name,
timeStanmp: time,
});
let newArr = this.state.myFileList.concat();
this.setState({ myFileList: newArr });
this.state.realFileList.append(time, blob);
console.log(time, blob);
console.log("this.state.realFileList", this.state.realFileList);
console.log("this.state.myFileList", this.state.myFileList);
}
// console.log(items[i], items[i].getAsFile());
// 纯文本 DataTransferItem {kind: "string", type: "text/plain"}
// 纯图片 DataTransferItem {kind: "file", type: "image/png"}
// 多张图片的复制弄不出来,看了一下,csdn的写博客,我从本地文件夹
// 选择两张图片,复制,然后去博客里粘贴,也粘贴不出来。。。
// 所以我这里也没有这个功能
// 单张图片+文本
// DataTransferItem {kind: "string", type: "text/plain"}
// DataTransferItem {kind: "string", type: "text/html"}
// 多张图片的复制,除了本地文件夹的没用,其他地方的可以
// 比如csdn的,可以在csdn复制多张图片或者多张图片+文本
// 多张图片
// DataTransferItem {kind: "string", type: "text/html"}
// DataTransferItem {kind: "string", type: "cke/id"}
// 多张图片+文本
// DataTransferItem {kind: "string", type: "text/plain"}
// DataTransferItem {kind: "string", type: "text/html"}
// DataTransferItem {kind: "string", type: "cke/id"}
// 所以多张图片的就算了吧
// 就只处理单张图片的和单张图片+文本的就行了,反正只展示图片
// ....现在看来似乎只能处理单张图片。。。
// 就只能一张一张复制
// 但是选择的时候可以选多张
// 要不都放里面,都可编辑,就用li?
// 然后我根据是否是图片来不同的展示就行了,不过
// 我怎么增加文件是增加到state里再渲染到页面上
// 但是我怎么检测删除呢,要不加个垃圾桶按钮吧,不然我怎么检测
// 删除退格啥的,就垃圾桶吧
}
}
}
if (blob) {
// 做两件事,第一件,读成base64,临时展示,算了,不用展示,
// 但是都需要文件的名字和后缀,来展示
// 第二用fd包裹,以便于发送数据给后端
let imgarr = [];
let reader = new FileReader();
reader.readAsDataURL(blob);
let that = this;
reader.onload = function (res) {
if (res.target.result) {
imgarr.push(res.target.result);
}
};
}
// let fd = new FormData();
// console.log(this.files);
// // files文件列表无法通过普通数组等循环遍历,需要通过迭代器循环遍历
// for (let file of this.files) {
// console.log("object", file);
// fd.append(file.name, file);
// }
};
handleFileChange = (e) => {
console.log("e", e);
let fd = new FormData();
console.log(e.target.files);
};
delFile = (e, time) => {
let index = this.state.myFileList.findIndex((el) => el.timeStanmp == time);
if (index >= 0) {
this.state.myFileList.splice(index, 1);
let newArr = this.state.myFileList.concat();
this.setState({ myFileList: newArr });
}
this.state.realFileList.delete(time);
console.log(this.state.myFileList, this.state.realFileList);
};
render() {
// .ant-input-affix-wrapper .ant-input:focus {
// border: none;
// border-bottom: 1px solid white !important;
// box-shadow: none;}
const { hideModal } = this.props;
const { text, supportShow, myFileList } = this.state;
const fileRender = myFileList.map((el) => {
return (
{
this.delFile(e, el.timeStanmp);
}}
>
{el.fileName}
);
});
const modalOpt = {
title: "新增缺陷",
width: 900,
visible: this.state.showModal,
onOk: () => this.handleSubmit(),
onCancel: () => hideModal && hideModal(false),
okText: i18n.ok,
cancelText: i18n.cancel,
maskClosable: false,
};
return (
{/* 头部 */}
缺陷摘要:
{/* onFocus={this.inputF} */}
{/* 下面部分,分为左右两部分 */}
提示:
{/* contenteditable="true" */}
{/* contenteditable="false" */}
支持粘贴图片...
{fileRender}
选择....
);
}
handleSubmit = () => {};
}
const MyForm = Form.create()(AddIssueModal);
export default MyForm;
后来发现bug的原因是,第一次就算你是contenteditable="false",第一次粘贴一定触发
但是之后你粘贴的内容,如果不是contenteditable="true",那就不会有光标,不能编辑,那么粘贴就不会再触发了
但是我这里就是想实现,既不能编辑,又能触发粘贴。。。所以就难搞,要么就写成可编辑的,contenteditable="true",但是能够阻止退格删除事件,不让删除
编辑区的东西
难搞,所以我就吧文件都放在下面了。。。。就没做上面这种
最新包含粘贴和下载的代码
/**
* 新增缺陷弹出框
*/
"use strict";
import "./index.less";
import React, { Component } from "react";
import { message } from "edspUI";
import {
InfoCircleOutlined,
FolderOutlined,
CopyFilled,
VerticalAlignBottomOutlined,
DeleteOutlined,
} from "@ant-design/icons";
import { Language } from "Utils";
import {
Modal,
Select,
Tooltip,
Icon,
Form,
Input,
Button,
Checkbox,
} from "antd";
import { jiraService } 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: [],
};
}
componentWillMount() {
this.refresh();
}
componentDidMount() {}
refresh() {}
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],
}));
}
}
}
}
};
handleFileChange = (e) => {
this.setState({ supportShow: false });
for (let file of e.target.files) {
console.log("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;
}
};
};
render() {
const { hideModal } = this.props;
const { text, fileList } = this.state;
const fileRender = fileList.map((el) => {
return (
{el.name}
{
this.downFile(el);
}}
style={
{ marginRight: "10px" }}
/>
{
this.delFile(el);
}}
style={
{ marginRight: "10px" }}
/>
);
});
const modalOpt = {
title: "新增缺陷",
width: 1200,
visible: this.state.showModal,
onOk: () => this.handleSubmit(),
onCancel: () => hideModal && hideModal(false),
okText: i18n.ok,
cancelText: i18n.cancel,
maskClosable: false,
};
return (
{/* 头部 */}
缺陷摘要:
{/* 下面部分,分为左右两部分 */}
提示:
{/* */}
支持粘贴图片...
选择....
{fileRender}
);
}
handleSubmit = () => {};
}
const MyForm = Form.create()(AddIssueModal);
export default MyForm;