文件的上传
文件的上传一般会用到formdata
对象。
这里引入一下formdata
的常见方法
直接打印formdata
,打印不出什么东西,只能调用getAll
方法调用,获取内容。
const handleUpload = () => {
const formData = new FormData();
console.log(fileList);
fileList.forEach((file) => {
console.log(file);
formData.set('file', file);
});
console.log(formData.getAll('file'))
let str=formData.getAll('file').name;
//, / ? : @ & = + $
// 调用文件上传的接口 传入fromdata作为参数
};
请求的接口写法
export async function creatDoc1(params) {
return axios(baseUrl+`/v1/docs/upload?className=${name}&secLevel=${secLevel}&scopeId=${scopeId}`, {
method: "POST",
data: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', // 请求头
}
})
}
文件的下载
文件的下载得通过 a 标签来进行下载文件,将后端返回的文件流转为blob对象在生成URL,再通过a标签打开URL。
请求方法的请求头的参数设置为blob。
const downLoadDataQuery = (res, fileName) => {
console.log(res, "header");
let url = window.URL.createObjectURL(new Blob([res], { type: res.type }))
const link = document.createElement('a');
link.style.display = "none";
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(link.href);
document.body.removeChild(link)
}
请求的方法
export async function downloadDoc(params) {
const encode = encodeURIComponent(params);
return axios(baseUrl+`/v1/docs/download?docname=${encode}`, {
method: "GET",
responseType:'blob'
})
}
图片的上传
和文件的上传一样,穿formdata
对象给后端,后端返回URL,但是设置键值对的时候名字得注意。
//图片回调
const handleImageUpload = (file) => {
console.log(file)
var formdata = new FormData();
formdata.set('image', file);
return (
upImage(formdata)
.then(function (response) {
let url="http://10.156.197.65:9000/"+response;
console.log(url);
return url;
}).catch(function (error) {
console.log(error)
}))
};
Markdown编辑器
import React, { useEffect, useImperativeHandle, forwardRef, useRef } from "react";
import Editor from "react-markdown-editor-lite";
import ReactMarkdown from "react-markdown";
import "react-markdown-editor-lite/lib/index.css";
import { Button, useModal, TextField,Row,Col } from 'choerodon-ui/pro';
import { getContent, putDoc, upImage } from '../../utils/api';
import PassageInfo from './PassageInfo'
import remarkMath from 'remark-math'
import rehypeKatex from 'rehype-katex'
// import 'katex/dist/katex.min.css'
import {Base64} from 'js-base64'
const NewEdit = (props) => {
const mdEditor = React.useRef(null);
const [textValue, setTextValue] = React.useState();
const [htmlValue, setHtmlValue] = React.useState();
const [title,setTitle] =React.useState('');
//编辑回调
const handleEditorChange = ({ html, text }) => {
const newValue = text;
const htmlValue = html;
setTextValue(newValue);
setHtmlValue(htmlValue);
};
//图片回调
const handleImageUpload = (file) => {
console.log(file)
var formdata = new FormData();
formdata.set('image', file);
return (
upImage(formdata)
.then(function (response) {
let url="http://10.156.197.65:9000/"+response;
console.log(url);
return url;
}).catch(function (error) {
console.log(error)
}))
};
// 将输入的字符串进行一个转义,减少字符串的长度
const REGX_HTML_ENCODE = /“|&|’|<|>|[\x00-\x20]|[\x7F-\xFF]|[\u0100-\u2700]/g;
const encodeHtml = (s) => {
return (typeof s != "string") ? s :
s.replace(REGX_HTML_ENCODE,
function ($0) {
var c = $0.charCodeAt(0), r = ["&#"];
c = (c == 0x20) ? 0xA0 : c;
r.push(c); r.push(";");
return r.join("");
});
};
const HTML_DECODE = {
"<": "<",
">": ">",
"&": "&",
" ": " ",
""": "\"",
"©": ""
// Add more
};
const REGX_HTML_DECODE = /&\w+;|&#(\d+);/g;
const decodeHtml = (s) => {
return (typeof s != "string") ? s :
s.replace(REGX_HTML_DECODE,
function ($0, $1) {
var c = HTML_DECODE[$0]; // 尝试查表
if (c === undefined) {
// Maybe is Entity Number
if (!isNaN($1)) {
c = String.fromCharCode(($1 == 160) ? 32 : $1);
} else {
// Not Entity Number
c = $0;
}
}
return c;
});
};
const encode_html = encodeHtml(htmlValue);
const encode_text = encodeHtml(textValue)
const uRef = useRef(null)
const Modal = useModal();
// 发布文章弹框 ,选择对应权限和标签
const openModal = (htmlValue,textValue) => {
Modal.open({
title: "发布文章",
children: <PassageInfo ref={uRef} encode_html={htmlValue} encode_text={textValue} title={title}></PassageInfo>,
fullScreen: false,
keyboardClosable: false,
autoCenter: true,
okText: "保存",
cancelText: "取消",
onOk: () => {
uRef.current.save();
}
});
};
const log = (value) => { // 标题输入回调
setTitle(value);
}
return (
<div className="editor" >
<Row gutter={24} className='row_box' style={{margin:'20px 0px' }}>
<Col span={20}>
<strong> 请输入文章标题:</strong>
<TextField
placeholder="请输入文章标题,不超过三十个字"
minLength={1}
maxLength={30}
showLengthInfo
style={{width:'60vw'}}
required
onChange={log} />
</Col>
<Col span={4}>
<Button onClick={()=>openModal(htmlValue,textValue)} color="primary" size="large">发布文章</Button>
</Col>
</Row>
<Editor
ref={mdEditor}
value={textValue}
style={{
height: 700
}}
onChange={handleEditorChange}
onImageUpload={handleImageUpload}
renderHTML={text => <ReactMarkdown source={text} remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex]}/>}
/>
<div>
</div>
</div>
);
}
export default NewEdit