最近開發項目中,做管理後臺,很多表格列表,有搜索條件,有分頁;在跳轉到詳情頁面,返回時,列表組件重新渲染,之前的搜索條件,分頁什麼的,都沒有記住;還需要重新選,點擊,交互體驗很不好。
1.這裏想到2兩個辦法,一個是吧搜索條件存到緩存中;每次進行讀寫;條件太多,或者多個上級頁面跳轉到同一頁面,再返回是還得區分,很是麻煩。而且點擊瀏覽器的返回按鈕,沒辦法記錄
這裏我們用路由傳遞,參數的辦法;上級頁面把搜索條件傳給,下級頁面;下級頁面返回時,在傳給上級頁面
主要看,state和history傳值就行了
上級頁面代碼:
/*
* 代理任務
*/
import React, { Component } from "react";
import Storage from "store2";
import History from "@utils/history";
import { Table, Select, Button, DatePicker, Modal, Notification, Row, Col } from "antd";
import moment from "moment";
import Request from "@utils/request";
import { urlAppendQuery } from "@utils/tools";
import { number4 } from "@utils/changeMoneyUnit";
import { bankShortName } from "@utils/codeToName";
import ModalDetail from "./form.js";
import "./style.less";
const curBranchCode = Storage.get("loginRes").bank.code;
const agentType = Storage.get("loginRes").bank["agentType"];
const chost = Storage.get("chost");
// 格式化時間
const format = "YYYY-MM-DD";
const taskStatus = {
"1": "未出庫",
"2": "在途",
"3": "已完成",
};
// 顯示彈框標題
const showTitle = (modalType) => {
let zz = "";
if (modalType === "add") {
zz = "新建任務";
} else if (modalType === "edit") {
zz = "修改任務";
}
return zz;
}
const columns = (_this) => [
{
title: "任務編號",
dataIndex: "taskCode",
width: 200,
align: "center",
},
{
title: "出庫銀行",
dataIndex: "outBank",
width: 150,
align: "center",
render: (text) => <span>{bankShortName(text) || "--"}</span>
},
{
title: "入庫銀行",
dataIndex: "inBank",
width: 150,
align: "center",
render: (text) => <span>{bankShortName(text) || "--"}</span>
},
{
title: "任務金額(元)",
dataIndex: "amount",
width: 100,
align: "center",
render: (text) => number4(text)
},
{
title: "雙流(元)",
dataIndex: "doubleAmount",
width: 100,
align: "center",
render: (text) => number4(text)
},
{
title: "非雙流(元)",
dataIndex: "freeAmount",
width: 100,
align: "center",
render: (text) => number4(text)
},
{
title: "任務時間",
dataIndex: "taskTime",
align: "center",
width: 100,
render: (text) => <div>{text ? moment(text).format(format) : "--"}</div>
},
{
title: "業務類型",
dataIndex: "taskType",
align: "center",
width: 100,
render: (text) => taskType[text]
},
{
title: "業務狀態",
dataIndex: "taskStatus",
align: "center",
width: 100,
render: (text) => taskStatus[text]
},
{
title: "創建人",
dataIndex: "createOperator",
align: "center",
width: 150,
render: (text) => <span>{text || "--"}</span>
},
{
title: "創建時間",
dataIndex: "createTime",
align: "center",
width: 100,
render: (text) => <div>{text ? moment(text).format(format) : "--"}</div>
},
{
title: "操作",
dataIndex: "操作",
fixed: "right",
align: "center",
width: 240,
render: (text, record) => (
<div style={{ textAlign: "center" }}>
{
record.taskStatus === 1
&&
<Button
type="link"
size="small"
onClick={() => {
let aa = "";
if ((curBranchCode === record.inBank) && agentType === 1) {
aa = "pay";
} else if ((curBranchCode === record.outBank) && agentType === 2) {
aa = "pay";
} else {
aa = "get";
}
_this.toggleModal(record, "edit", aa); // get被代理行入庫,pay被代理行出庫
}}
>
修改
</Button>
}
{
record.taskStatus === 2 && curBranchCode === record.inBank
&&
<Button
type="link"
size="small"
onClick={() => {
History.push("/transferInRoom", {
taskCode: record.taskCode,
type: "agent",
});
}}
>
入庫
</Button>
}
{
record.taskStatus === 1 && curBranchCode === record.outBank
&&
<Button
type="link"
size="small"
onClick={() => {
History.push("/transferOutRoom", {
taskCode: record.taskCode,
type: "agent",
});
}}
>
出庫
</Button>
}
<Button
type="link"
size="small"
onClick={() => {
History.push("/transferTaskDetail", {
taskCode: record.taskCode,
fromUrl: "/agent",
time: [_this.state.startTime, _this.state.endTime].join(","),
taskStatus: _this.state.taskStatus,
nowPage: _this.state.nowPage,
});
}}
>
任務詳情
</Button>
{
record.taskStatus === 1
&&
<Button
type="link"
roles="button"
style={{ color: "#ff0000" }}
onClick={() => {
Modal.confirm({
title: "確定刪除代理任務?",
content: (
<div>
<p>任務號:{record.taskCode},</p>
<p>任務金額:{record.amount}</p>
</div>
),
okText: "確認",
cancelText: "取消",
onOk() {
Request.POST(`/api/api/task/delete/${record.taskCode}`).then((res) => {
if (res.success) {
Notification.success({
message: res.message || "刪除成功"
});
_this.loadData({ page: 1 }); // 回到第一頁
} else {
Notification.error({
message: res.message || "刪除失敗"
});
}
});
}
});
}}
>
刪除
</Button>
}
</div>
)
}
];
class View extends Component {
constructor(props) {
super(props);
const isHaveSearch = Boolean(this.props.location.state);
this.state = {
startTime: isHaveSearch ? moment(this.props.location.state.time.split(",")[0]) : moment(),
endTime: isHaveSearch ? moment(this.props.location.state.time.split(",")[1]) : moment(),
tableSource: {}, // 表格數據
modalShowed: false, // 調入調出彈出框
modalType: "add", // 彈窗默認類型新增add,修改edit
modalCode: "", // 彈窗任務編碼
modalId: "", // 彈窗任務ID
moneyType: "", // 被代理行出入庫類型
taskTypeArr: [2], // 任務類型任務類型1:跨行調款 2:代理任務 3:向人行交款 4:從人行取款 5:上繳殘損券
taskStatus: isHaveSearch ? this.props.location.state.taskStatus : null, // 任務狀態
endOpen: false, // 時間框關閉
nowPage: isHaveSearch ? this.props.location.state.nowPage : 1, // 當前分頁
};
}
componentDidMount() {
this.loadData(); // 獲取當天數據
}
disabledStartDate = startValue => {
const { endTime } = this.state;
if (!startValue || !endTime) {
return false;
}
return startValue.valueOf() > endTime.valueOf();
};
disabledEndDate = endValue => {
const { startTime } = this.state;
if (!endValue || !startTime) {
return false;
}
return endValue.valueOf() <= startTime.valueOf();
};
// 修改開始時間
changeStartTime = (time) => {
this.setState({
startTime: time
});
};
// 修改結束時間
changeEndTime = (time) => {
this.setState({
endTime: time
});
};
handleStartOpenChange = open => {
if (!open) {
this.setState({ endOpen: true });
}
};
handleEndOpenChange = open => {
this.setState({ endOpen: open });
};
// 渲染頁面數據
loadData = async (obj) => {
const {
startTime,
endTime,
taskTypeArr,
taskStatus,
nowPage,
} = this.state;
// 獲取任務列表
Request.GET("/api/api/task/pageList", {
params: {
pageNo: (obj && obj.page) || nowPage,
pageSize: (obj && obj.limit) || 10,
taskTimeBegin: moment(startTime).format(format),
taskTimeEnd: moment(endTime).format(format),
taskTypeList: taskTypeArr,
taskStatus,
}
}).then((res) => {
const tableData = res.data;
if (res.success) {
this.setState({
tableSource: tableData,
nowPage: tableData.pageNo
});
} else {
Notification.error({
message: res.message || "後端接口數據錯誤"
});
}
});
};
taskExport = ()=>{
const {
startTime,
endTime,
taskTypeArr,
taskStatus,
} = this.state;
if (endTime.diff(startTime, "day") >= 366) {
Notification.warn({
message: "僅支持導出最近一年內的任務!"
});
} else {
const downUrl = urlAppendQuery(`${chost}/cbank/api/task/export`,{
"Access-Token":Storage.get("Authorization"),
taskStatus,
taskTimeBegin:startTime.format(format),
taskTimeEnd:endTime.format(format),
taskTypeList:taskTypeArr
});
// 導出任務
window.location.href = downUrl;
}
}
// 修改、添加
toggleModal = (record, type, moneyType) => {
this.setState({
modalShowed: !this.state.modalShowed,
modalType: type,
modalcode: type === "add" ? "" : record.taskCode,
modalId: type === "add" ? "" : record.id,
moneyType: moneyType
}, () => {
console.log(this.state.modalcode, this.state.modalType);
});
};
// 點擊陰影顯示
handleCancel = () => {
this.setState({
modalShowed: !this.state.modalShowed,
});
};
CancelTaskModal = () => {
this.setState({
modalShowed: !this.state.modalShowed,
});
};
render() {
const {
startTime,
endTime,
taskStatus,
endOpen,
tableSource,
modalShowed,
modalType,
moneyType,
} = this.state;
return (
<div className="list">
<Row>
<Col span={14}>
<Row style={{ "marginBottom": "20px" }}>
<Col style={{ "marginBottom": "20px" }}>
任務時間:
<DatePicker
allowClear={!1}
disabledDate={this.disabledStartDate}
format="YYYY-MM-DD"
value={startTime}
placeholder="開始"
onChange={this.changeStartTime}
onOpenChange={this.handleStartOpenChange}
/>
<span className="mlr5">--</span>
<DatePicker
allowClear={!1}
disabledDate={this.disabledEndDate}
format="YYYY-MM-DD"
value={endTime}
placeholder="結束"
onChange={this.changeEndTime}
open={endOpen}
onOpenChange={this.handleEndOpenChange}
/>
</Col>
<Col>
任務狀態:
<Select
style={{ width: "100px", marginRight: "25px" }}
value={taskStatus}
onChange={(val) => {
this.setState({
taskStatus: val
});
}}
>
<Select.Option value={null}>全部</Select.Option>
<Select.Option value={1}>未出庫</Select.Option>
<Select.Option value={2}>在途</Select.Option>
<Select.Option value={3}>已完成</Select.Option>
</Select>
<Button
type="primary"
onClick={() => {
this.loadData({page: 1});
}}
>
查詢
</Button>
<Button
type="primary"
style={{"marginLeft":"20px"}}
onClick={() => {
this.taskExport();
}}
>
任務導出
</Button>
</Col>
</Row>
</Col>
<Col span={10}>
{
agentType === 1 &&
<Button
style={{ margin: "10px", width: "150px", height: "60px" }}
type="primary"
onClick={() => {
this.toggleModal(null, "add", "get"); // get被代理行入庫,pay被代理行出庫
}}
>
向被代理行調款
</Button>
}
{
agentType === 2 &&
<div>
<Button
style={{ margin: "10px", width: "150px", height: "60px" }}
type="primary"
onClick={() => {
this.toggleModal(null, "add", "get"); // get被代理行入庫,pay被代理行出庫
}}
>
從代理行取款
</Button>
<Button
type="primary"
style={{ margin: "10px", width: "150px", height: "60px" }}
onClick={() => {
this.toggleModal(null, "add", "pay"); // get被代理行入庫,pay被代理行出庫
}}
>
向代理行交款
</Button>
</div>
}
</Col>
</Row>
<Table
scroll={{ x: 1950 }}
dataSource={tableSource && tableSource.dataList}
columns={columns(this)}
rowSelection={null}
rowKey="id"
pagination={{
showQuickJumper: false,
total: tableSource.totalSize,
current: tableSource.pageNo,
pageSize: tableSource.pageSize,
onChange: (page) => {
this.loadData({ limit: tableSource.size, page });
},
}}
/>
<Modal
visible={modalShowed}
footer={null}
destroyOnClose={!!1}
onCancel={() => this.handleCancel()}
width="800px"
maskClosable={!1}
title={showTitle(modalType)}
>
<ModalDetail parentThis={this}
modalType={modalType}
moneyType={moneyType}
modalCode={this.state.modalcode}
modalId={this.state.modalId}
/>
</Modal>
</div>
);
}
}
export default View;
下級頁面代碼:
/*
* 創建代理任務
*/
import React from "react";
import { Form, Notification, Button, Select, DatePicker, Row, Col, Input } from "antd";
import Request from "@utils/request";
import Storage from "store2";
import np from "number-precision";
import moment from "moment";
import { bankName } from "@utils/codeToName.js"
import ValutaForm from "./valutaForm.js";
const FormItem = Form.Item;
const moneyReg = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/; // 包含小數點
const dateFormat = "YYYY-MM-DD H:mm:ss";
const agentType = Storage.get("loginRes").bank["agentType"];
const currentBankCode = Storage.get("loginRes").bank.code;
const currentBankName = Storage.get("loginRes").bank.name;
class ViewForm extends React.Component {
constructor(props) {
super(props);
console.log(props)
this.state = {
valutaList: [], // 幣值表
inBank: "",
outBank: "",
taskTime: null,
note: "", // 備註
id: "",
taskCode: "",
agentBankCode: "",
agentBankName: "",
toAgentArr: [],
sureBtn: false, // 創建任務按鈕
};
}
componentDidMount() {
if (agentType === 1) {
this.getAgentArr(); // 查詢代理點
if (this.props.moneyType === "get") {
this.setState({
inBank: "",
outBank: currentBankCode,
agentBankCode: currentBankCode,
agentBankName: currentBankName,
});
} else if (this.props.moneyType === "pay") {
this.setState({
inBank: currentBankCode,
outBank: "",
agentBankCode: currentBankCode,
agentBankName: currentBankName,
});
}
} else if (agentType === 2) {
// 被代理行獲取代理行的編碼
let agentBankCode = Storage.get("loginRes").bank["agentCode"];
let zzArr = [{ "id": 1, "code": currentBankCode, "name": currentBankName }];
if (this.props.moneyType === "get") {
this.setState({
inBank: currentBankCode,
outBank: agentBankCode,
agentBankCode: agentBankCode,
agentBankName: bankName(agentBankCode),
toAgentArr: zzArr,
});
} else if (this.props.moneyType === "pay") {
this.setState({
inBank: agentBankCode,
outBank: currentBankCode,
agentBankCode: agentBankCode,
agentBankName: bankName(agentBankCode),
toAgentArr: zzArr,
});
}
}
if (this.props.modalType === "edit") {
this.getTaskInfo();
} else {
this.getPbankValuta(); // 獲取幣值表
}
}
// 獲取任務信息
getTaskInfo = () => {
console.log(this.props.modalCode);
Request.GET(`/api/api/task/get/${this.props.modalCode}`).then((res) => {
if (res.success) {
this.setState({
valutaList: res.data.taskValutaList,
inBank: res.data.task.inBank,
note: res.data.task.note,
outBank: res.data.task.outBank,
taskTime: moment(res.data.task.taskTime),
id: res.data.task.id,
taskCode: res.data.task.taskCode,
});
} else {
Notification.warning({
message: res.message || "獲取該任務的調款信息失敗",
});
}
});
}
// 獲取被代理銀行列表
getAgentArr = () => {
Request.GET(`/api/api/bank/agent?agentBankCode=${currentBankCode}`).then((res) => {
if (res.success) {
this.setState({
toAgentArr: res.data,
});
} else {
Notification.warning({
message: res.message || "獲取被代理銀行信息失敗",
});
}
});
};
// 獲取幣值表
getPbankValuta = () => {
Request.GET("/api/api/valuta/list").then((res) => {
if (res.success) {
this.setState({
valutaList: res.data.map(item => {
item.valutaAmount = 0;
return item;
}),
// inBank: "",
// outBank: "",
// taskTime: null,
// id: "",
// taskCode: "",
});
} else {
Notification.warning({
message: res.message || "獲取幣值列表失敗",
});
}
});
};
disabledDate = (current) => {
// Can not select days before today and today
return current && current < moment().endOf("day");
}
changePbankValutaList = (value, record) => {
if (!value || moneyReg.test(value)) {
this.setState({
valutaList: this.state.valutaList.map(item => {
if (item.code === record.code) {
item.valutaAmount = value;
}
return item;
})
})
} else {
Notification.warning({
message: "請輸入合法數值!",
});
}
}
compute = () => this.state.valutaList.reduce((total, item) => np.plus(total, item.valutaAmount), 0);
slCompute = () => {
return this.state.valutaList.reduce((total, item) => {
if (item.flag === 1) {
return np.plus(total, item.valutaAmount);
}
return total;
}, 0);
};
fslCompute = () => {
return this.state.valutaList.reduce((total, item) => {
if (item.flag === 0) {
return np.plus(total, item.valutaAmount);
}
return total;
}, 0);
};
handleSubmit = () => {
if (this.compute() === 0 || this.compute() < 0) {
Notification.warning({
message: "調款金額不能小於等於0元!",
});
this.setState({
sureBtn: false
});
return;
}
const { id, taskCode } = this.state;
const { form: { validateFields }, modalType } = this.props;
validateFields((err, values) => {
if (!err) {
if (modalType === "edit") {
Request.POST("/api/api/task/update", {
body: {
task: {
id,
taskCode,
inBank: values.inBank,
inBankName: bankName(values.inBank),
outBank: values.outBank,
outBankName: bankName(values.outBank),
taskTime: values.taskTime.format(dateFormat),
taskType: 2,
remark: values.remark
},
taskValutaList: values.taskValutaList.valuta.filter(item => item.valutaAmount > 0).map(item => {
let temp = {};
temp.valutaCode = item.code;
temp.valutaFlag = item.flag;
temp.valutaAmount = item.valutaAmount;
return temp;
})
}
}).then((res) => {
if (res.success) {
Notification.success({
message: res.message || "修改調款任務成功",
});
this.props.parentThis.CancelTaskModal();
this.props.parentThis.loadData();
} else {
Notification.warning({
message: res.message || "修改調款任務成功失敗",
});
}
this.setState({
sureBtn: false
});
});
} else {
Request.POST("/api/api/task/add", {
params: {
loginKey: "b02a523f8ec348feb30aac2ea794724c",
},
body: {
task: {
inBank: values.inBank,
inBankName: bankName(values.inBank),
outBank: values.outBank,
outBankName: bankName(values.outBank),
taskTime: values.taskTime.format(dateFormat),
taskType: 2, //1:跨行調款 2:代理任務 3:向人行交款 4:從人行取款 5:上繳殘損券
remark: values.remark
},
taskValutaList: values.taskValutaList.valuta.filter(item => item.valutaAmount > 0).map(item => {
let temp = {};
temp.valutaCode = item.code;
temp.valutaFlag = item.flag;
temp.valutaAmount = item.valutaAmount;
return temp;
})
}
}).then((res) => {
if (res.success) {
Notification.success({
message: res.message || "創建調款任務成功",
});
this.props.parentThis.CancelTaskModal();
this.props.parentThis.loadData();
} else {
Notification.warning({
message: res.message || "創建調款任務成功失敗",
});
}
this.setState({
sureBtn: false
});
});
}
}
});
};
render() {
const { getFieldDecorator, getFieldValue } = this.props.form;
const { sureBtn, toAgentArr, agentBankCode, agentBankName, valutaList, inBank, outBank, taskTime, remark } = this.state;
const { modalType, moneyType } = this.props;
console.log(toAgentArr);
const formItemLayout = {
labelCol: { span: 3 },
wrapperCol: { span: 16 },
};
const formItemLayoutValuta = {
labelCol: { span: 3 },
wrapperCol: { span: 20 },
}
const _this = this;
return (
<Row className="modalForm">
<Col>
<Form>
<FormItem label="時間"
{...formItemLayout}>
{getFieldDecorator("taskTime", {
initialValue: taskTime,
rules: [{ required: true, message: "請輸入調款時間!" }],
})(
<DatePicker
allowClear={!1}
disabledDate={this.disabledDate}
showTime={{ format: "HH:mm" }}
format="YYYY-MM-DD HH:mm"
placeholder="請選擇調款任務時間"
/>
)}
</FormItem>
<FormItem label="出庫行"
{...formItemLayout}>
{getFieldDecorator("outBank", {
initialValue: outBank,
rules: [{ required: true, message: "請輸入調款出庫行!" }, {
validator: (rule, value, callback) => {
if (getFieldValue("inBank") === value) {
callback("出庫行和入庫行不能爲同一銀行!");
}
callback();
}
}],
})(
<Select
showSearch
placeholder="請選擇出庫行"
disabled={agentType === 2 || modalType === "edit"}
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.indexOf(input) >= 0
}
>
{
moneyType === "get" ?
<Select.Option
value={agentBankCode}
>
{agentBankName}
</Select.Option> :
toAgentArr.map(item => {
return <Select.Option
value={item.code}
key={item.id}
>
{item.name}
</Select.Option>
})
}
</Select>
)}
</FormItem>
<FormItem label="入庫行"
{...formItemLayout}>
{getFieldDecorator("inBank", {
initialValue: inBank,
rules: [
{ required: true, message: "請輸入調款入庫行!" }, {
validator: (rule, value, callback) => {
if (getFieldValue("outBank") === value) {
callback("出庫行和入庫行不能爲同一銀行!");
}
callback();
}
}],
})(
<Select
showSearch
disabled={agentType === 2 || modalType === "edit"}
placeholder="請選擇入庫行"
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.indexOf(input) >= 0
}
>
{
moneyType === "pay" ?
<Select.Option
value={agentBankCode}
>
{agentBankName}
</Select.Option> :
toAgentArr.map(item => {
return <Select.Option
value={item.code}
key={item.id}
>
{item.name}
</Select.Option>
})
}
</Select>
)}
</FormItem>
<FormItem label="幣值"
{...formItemLayoutValuta}>
{getFieldDecorator("taskValutaList", {
initialValue: {
valuta: valutaList
}
})(
<ValutaForm
getFieldDecorator={getFieldDecorator}
changePbankValutaList={this.changePbankValutaList}
parentThis={this}
/>
)}
</FormItem>
<FormItem label="備註說明"
{...formItemLayout}>
{getFieldDecorator("remark", {
initialValue: remark,
rules: [{
required: false,
message: "請填寫備註說明",
}],
})(
<Input.TextArea placeholder="請填寫備註說明" />
)}
</FormItem>
</Form>
</Col>
<Col style={{ "textAlign": "right" }}>
<Button type="primary"
htmlType="submit"
disabled={sureBtn}
onClick={() => {
this.setState({
sureBtn: true,
}, ()=> {
// 解決一下setState異步問題
setTimeout(() => {
_this.handleSubmit();
}, 500);
});
}}>確定</Button>
<Button style={{ "marginLeft": 8 }}
onClick={() => {
this.props.parentThis.CancelTaskModal();
}}>取消</Button>
</Col>
</Row>
);
}
}
const View = Form.create()(ViewForm);
export default View;