在开发react开发过程中在做一些表单内容提交修改过程中:用到了上传和下载附件;富文本编辑等,话不多说上代码:
index.js文件是一个list表格:
/*
* 项目需求列表
*/
import React, { Component } from "react";
import Storage from "store2";
// import History from "@utils/history";
import { Modal, Button, Row, Col, Table, Notification } from "antd";
import Request from "@utils/request";
import { areaName, bankName } from "@utils/codeToName";
import Form from "./form.js";
let version = Storage.get("version");
const columns = _this => [
{
title: "id",
dataIndex: "id",
},
{
title: "需求名称",
dataIndex: "demandName",
},
{
title: "需求编码",
dataIndex: "demandCode",
},
{
title: "需求描述",
dataIndex: "note",
width: 200,
render: text => {
const re = new RegExp("<[^<>]+>", "g");
const text1 = text.replace(re, "");
return <textarea defaultValue={text1}></textarea>;
}
},
{
title: "地区",
dataIndex: "areaCode",
align: "center",
render: (text) => areaName(text)
},
{
title: "银行",
dataIndex: "bankCode",
align: "center",
render: (text) => bankName(text)
},
{
title: "创建时间",
dataIndex: "createTime",
width: 200,
},
{
title: "操作",
dataIndex: "操作",
fixed: "right",
align: "center",
width: 240,
render: (text, record) => (
<div style={{ textAlign: "right" }}>
<Button
type="link"
onClick={() => {
Modal.confirm({
title: "确定删除此项目吗?",
content: (
<div>
<p>项目名称:{record.demandName}</p>
</div>
),
okText: "确认",
cancelText: "取消",
onOk() {
Request.POST(`/api/demand/delete/${record.id}`, {
params: {
loginKey: Storage.get("Authorization"),
}
}).then((res) => {
if (res.success) {
Notification.success({
message: res.msg || "删除成功"
});
_this.loadData();
} else {
Notification.error({
message: res.msg || "删除失败"
});
}
});
}
});
}}
>
删除
</Button>
{
record.loginname !== "admin"
&&
<Button
type="link"
onClick={() => {
_this.setState({
taskModal: true,
taskModalType: "edit",
demandInfo: record.id
})
}}
>
修改
</Button>
}
<Button
type="link"
onClick={() => {
// 获取任详情
Request.GET(`/api/demand/get/${record.id}`, {
params: {
loginKey: Storage.get("Authorization"),
}
}).then((res) => {
if (res.success) {
_this.setState({
downloadtaskModal: true,
downloadDemandInfo: res.data.attachmentList
});
} else {
Notification.warning({
message: res.msg || "获取任详情失败",
});
}
});
}}
>
下载附件
</Button>
</div>
)
}
];
class View extends Component {
constructor(props) {
super(props);
this.state = {
tableSource: [],
taskModal: false,
downloadtaskModal: false,
taskModalType: "add", //创建:add 修改:edit
demandInfo: "",
downloadDemandInfo: [] //附件信息
};
}
componentDidMount() {
this.loadData(); // 获取数据
}
// 渲染页面数据
loadData = async () => {
// 获取任务列表
Request.GET("/api/demand/list", {
params: {
loginKey: Storage.get("Authorization"),
}
}).then((res) => {
if (res.success) {
this.setState({
tableSource: res.data
});
} else {
Notification.warning({
message: res.msg || "获取户失败",
});
}
});
};
CancelTaskModal = () => {
this.setState({
taskModal: false
})
}
CanceldownloadtaskModal = () => {
this.setState({
downloadtaskModal: false
})
}
render() {
const {
tableSource,
taskModalType,
demandInfo,
downloadtaskModal,
downloadDemandInfo
} = this.state;
console.log(downloadDemandInfo)
return (
<div>
<Row>
<Col>
<Button type="primary"
size="large"
onClick={() => {
this.setState({
taskModal: true,
taskModalType: "add"
})
}}
>新增需求</Button>
</Col>
</Row>
<Table
style={{
marginTop: "20px"
}}
scroll={{ x: 1200 }}
dataSource={tableSource}
columns={columns(this)}
rowKey="id"
/>
<Modal
title={taskModalType === "edit" ? "修改需求" : "新增需求"}
footer={null}
width={900}
destroyOnClose
visible={this.state.taskModal}
onCancel={() => { this.CancelTaskModal() }}
>
<Form parentThis={this}
taskModalType={taskModalType}
demandInfo={demandInfo}
/>
</Modal>
<Modal
title="下载附件"
footer={null}
width={900}
destroyOnClose
visible={downloadtaskModal}
onCancel={() => { this.CanceldownloadtaskModal() }}
>
{
(downloadDemandInfo && downloadDemandInfo.length > 0)
?
downloadDemandInfo.map(item => {
return <Button
type="link"
key={item.id}
onClick={() => {
// 下载附件
window.location.href = `${version}/attachment/download/${item.uuid}?loginKey=${Storage.get("Authorization")}`;
}}>
{item.fileName}
</Button>
})
:
"无附件"
}
</Modal>
</div>
);
}
}
export default View;
form.js表单新增,修改
/*
* 创建修改需求
*/
import React from "react";
import { Form, Notification, Button, Input, Row, Col, Select, Radio, message, Upload, Icon } from "antd";
import Request from "@utils/request";
import Storage from "store2";
import Edit from "./edit"
const FormItem = Form.Item;
class ViewForm extends React.Component {
constructor(props) {
super(props);
this.state = {
demandInfo: {},
areaArr: [],
bankArr: [],
editorContent: "",
fileList: [],//要上传的附件list
zzfileList: [], //回显的附件list
};
}
componentDidMount() {
this.areaData();
this.bankData();
const { taskModalType } = this.props;
if (taskModalType === "edit") {
this.loadData(); // 获取数据
}
}
// 获取地区
areaData = () => {
Request.GET("/api/area/list", {
params: {
loginKey: Storage.get("Authorization"),
}
}).then(res => {
if (res.success) {
this.setState({
areaArr: res.data
});
}
})
};
// 获取银行
bankData = () => {
Request.GET("/api/bank/list", {
params: {
loginKey: Storage.get("Authorization"),
}
}).then(res => {
if (res.success) {
this.setState({
bankArr: res.data
});
}
})
};
// 根据地区换银行
changeArea = (value) => {
let areaCode = value;
Request.GET(`/api/area/getByAreaCode/${areaCode}`, {
params: {
loginKey: Storage.get("Authorization"),
}
}).then(res => {
if (res.success) {
this.setState({
bankArr: res.data.bankList
});
} else {
this.setState({
bankArr: []
});
}
})
};
// 编辑器内容
saveEditor = (text) => {
const { form: { setFieldsValue } } = this.props;
this.setState({
editorContent: text
});
setFieldsValue({
"note": text
});
};
// 获取项目信息
loadData = async () => {
Request.GET(`/api/demand/get/${this.props.demandInfo}`, {
params: {
loginKey: Storage.get("Authorization"),
}
}).then((res) => {
if (res.success) {
this.setState({
demandInfo: res.data,
editorContent: res.data.note,
zzfileList: res.data.attachmentList, // 原始数据
fileList: (this.props.taskModalType === "edit" && res.data.attachmentList && res.data.attachmentList.length > 0)
?
res.data.attachmentList.map(f => {
const temp = {
// 为了提供给上传组件回显
id: f.id,
uid: f.uuid, // 这是上传组件规定的文件唯一标识,内部会提供给Form以便正常渲染回显列表
name: f.fileName,
status: "done",
url: "",
fileExt: f.fileExt,
filePath: f.filePath,
fileSize: f.fileSize,
}
return temp;
})
:
[]
});
} else {
Notification.warning({
message: res.msg || "获取项目信息失败",
});
}
});
};
handleSubmit = () => {
const { form: { validateFields }, taskModalType } = this.props;
const { demandInfo, zzfileList, editorContent } = this.state;
validateFields((err, values) => {
if (!err) {
if (taskModalType === "edit") {
Request.POST("/api/demand/update", {
params: {
loginKey: Storage.get("Authorization"),
},
body: {
demandName: values.demandName,
demandCode: values.demandCode,
id: demandInfo.id,
areaCode: values.areaCode,
bankCode: values.bankCode,
demandGeneral: values.demandGeneral,
attachmentList: zzfileList,
note: editorContent,
}
}).then((res) => {
if (res.success) {
Notification.success({
message: res.msg || "修改成功",
});
this.props.parentThis.CancelTaskModal();
this.props.parentThis.loadData();
} else {
Notification.warning({
message: res.msg || "修改失败",
});
}
});
} else {
Request.POST("/api/demand/add", {
params: {
loginKey: Storage.get("Authorization"),
},
body: {
demandName: values.demandName,
areaCode: values.areaCode,
demandCode: values.demandCode,
bankCode: values.bankCode,
demandGeneral: values.demandGeneral,
attachmentList: zzfileList,
note: editorContent,
}
}).then((res) => {
if (res.success) {
Notification.success({
message: res.msg || "新增需求成功",
});
this.props.parentThis.CancelTaskModal();
this.props.parentThis.loadData();
} else {
Notification.warning({
message: res.msg || "新增需求失败",
});
}
});
}
}
});
};
render() {
const { demandInfo, fileList, zzfileList, editorContent, areaArr, bankArr } = this.state;
const { taskModalType } = this.props;
if (taskModalType === "edit" && Object.keys(demandInfo).length === 0) return <div></div>;
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 12 },
};
const formItemLayoutNote = {
labelCol: { span: 4 },
wrapperCol: { span: 20 },
}
let _this = this;
const props = {
accept: ".rar,.zip,.doc,.docx,.xlsx,.xls,.pdf,.jpg,.png",
name: "file",
action: `${Storage.get("version")}/attachment/upload?loginKey=${Storage.get("Authorization")}`,
defaultFileList: fileList,
beforeUpload(file) {
const isLt10M = file.size / 1024 / 1024 <= 100;
if (!isLt10M) {
message.error("文件大小限制在100M以下!");
this.onRemove(file);
return false;
}
},
onRemove(file) {
Request.GET(`/api/attachment/del/${file.uid}`, {
params: {
loginKey: Storage.get("Authorization"),
}
}).then((res) => {
if (res.success) {
Notification.success({
message: res.msg || "删除附件成功",
});
} else {
Notification.warning({
message: res.msg || "删除附件失败",
});
}
});
_this.setState({
fileList: fileList.filter(item => item.name !== file.name),
zzfileList: zzfileList.filter(item => item.fileName !== file.name),
}, () => {
_this.props.form.setFieldsValue({ fileList: fileList });
});
},
onChange(info) { // 上传中、完成、失败都会调用这个函数
let curFileList = [...info.fileList];
curFileList = curFileList.map((file) => {
if (file.response) {
console.log(file.response);
// 这里上传组件回调的数据,有些是提供给上传组件自身使用的,所以不能不要
// 而需要向后端提交的数据这里提前封装起来,以方便最终的提交
// let saveParams = {};
file["fileName"] = file.response.data.fileName;
file["filePath"] = file.response.data.filePath;
file["fileSize"] = file.response.data.fileSize;
file["fileExt"] = file.response.data.fileExt;
file["uuid"] = file.response.data.uuid;
file["id"] = file.response.data.id;
}
return file;
});
curFileList = curFileList.filter(file => {
if (file.size / 1024 / 1024 <= 100) {
if (file.response) {
return file.response.code === 0;
}
return true;
} else {
return false;
}
});
_this.setState({
zzfileList: [
..._this.state.zzfileList,
...curFileList
]
});
},
// fileList: fileList, // 上传组件已使用Form进行代理,所以不要再直接设置
};
return (
<Row>
<Col>
<Form>
<FormItem label="需求名称"
{...formItemLayout}
>
{getFieldDecorator("demandName", {
initialValue: taskModalType === "edit" ? demandInfo.demandName : "",
rules: [{ required: true, message: "请填写需求名称!" }],
})(
<Input placeholder="请填写需求名称" />
)}
</FormItem>
<FormItem label="需求编号"
{...formItemLayout}
>
{getFieldDecorator("demandCode", {
initialValue: taskModalType === "edit" ? demandInfo.demandCode : "",
rules: [{ required: true, message: "请填写需求编号!" }],
})(
<Input placeholder="请填写需求编号" />
)}
</FormItem>
<FormItem label="地区"
{...formItemLayout}
>
{getFieldDecorator("areaCode", {
initialValue: taskModalType === "edit" ? demandInfo.areaCode : "",
rules: [{ required: true, message: "请输入实施地区!" }],
})(
<Select
showSearch
placeholder="请选择实施的地区"
optionFilterProp="children"
onChange={(e) => this.changeArea(e)}
filterOption={(input, option) =>
option.props.children.indexOf(input) >= 0
}
>
{
areaArr.map((item, index) => {
return <Select.Option
value={item.areaCode}
key={index}
>
{item.areaName}
</Select.Option>
})
}
</Select>
)}
</FormItem>
<FormItem label="银行"
{...formItemLayout}
>
{getFieldDecorator("bankCode", {
initialValue: taskModalType === "edit" ? demandInfo.bankCode : "",
rules: [{ required: true, message: "请输入实施银行!" }],
})(
<Select
showSearch
placeholder="请选择实施的银行"
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.indexOf(input) >= 0
}
>
{
bankArr.map((item, index) => {
return <Select.Option
value={item.bankCode}
key={index}
>
{item.bankName}
</Select.Option>
})
}
</Select>
)}
</FormItem>
<FormItem label="是否通用"
{...formItemLayout}
>
{getFieldDecorator("demandGeneral", {
initialValue: taskModalType === "edit" ? demandInfo.demandGeneral : 1,
rules: [{ required: true, message: "请选择是否通用!" }],
})(
<Radio.Group >
<Radio value={1}>通用版本</Radio>
<Radio value={2}>非通用版本</Radio>
</Radio.Group>
)}
</FormItem>
<FormItem {...formItemLayout}
label="上传附件">
{getFieldDecorator("attachmentList", {
rules: [{
required: false, message: "请上传证明材料"
}],
valuePropName: "attachmentList",
getValueFromEvent: (e) => {
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
}
})(
<Upload {...props}>
<Button>
<Icon type="upload" /> 上传文件
</Button>
<span className="upload-desc">支持附件:.rar .zip .xlsx .xls .doc .pdf .jpg .png</span>
</Upload>
)}
</FormItem>
<FormItem label="需求描述"
{...formItemLayoutNote}
>
{getFieldDecorator("note", {
initialValue: taskModalType === "edit" ? editorContent : "",
})(
<Edit
parentThis={this}
getFieldDecorator={getFieldDecorator}
editWord={editorContent}
/>
)}
</FormItem>
</Form>
</Col>
<Col style={{ "textAlign": "right", marginTop: "10px" }}>
<Button type="primary"
htmlType="submit"
onClick={() => {
this.handleSubmit()
}}
>确定</Button>
<Button style={{ "marginLeft": 8 }}
onClick={() => {
this.props.parentThis.CancelTaskModal();
}}
>取消</Button>
</Col>
</Row>
);
}
}
const View = Form.create()(ViewForm);
export default View;
edit.js表单中的富文本编辑器
import React, { Component } from "react";
import E from "wangeditor"
class Wangeditor extends Component {
constructor(props, context) {
super(props, context);
this.myRefOne = React.createRef();
this.state = {
editorContent: ""
}
}
componentDidMount() {
const elem = this.myRefOne;
this.editor = new E(elem);
// 使用 onchange 函数监听内容的变化,并实时更新到 state 中
this.editor.customConfig.onchange = html => {
this.setState({
editorContent: html
});
// let wordText = this.editor.txt.text();
this.props.parentThis.saveEditor(html);
}
this.editor.create();
this.editor.txt.html(this.state.editorContent);
}
// 注意此处有个需要注意的坑,在回显过程中,需要对比props修改的传值问题
shouldComponentUpdate(nextProps) {
if (this.state.editorContent !== nextProps.value) {
this.setState({
editorContent: nextProps.value
}, () => {
this.editor.txt.html(this.state.editorContent);
});
return true;
} else {
return false;
}
}
render() {
// const { getFieldDecorator, value: { note }, parentThis } = this.props;
return (
<div className="editor">
{/* 将生成编辑器 */}
<div
ref={(ref) => this.myRefOne = ref}
style={{
textAlign: "left"
}}
>
</div>
</div>
);
}
}
export default Wangeditor;