You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
541 lines
15 KiB
541 lines
15 KiB
import React, {
|
|
useState,
|
|
useRef,
|
|
useEffect,
|
|
useLayoutEffect,
|
|
useImperativeHandle,
|
|
forwardRef,
|
|
} from "react";
|
|
import {
|
|
Form,
|
|
Pagination,
|
|
Table,
|
|
Button,
|
|
Select,
|
|
Row,
|
|
Col,
|
|
Input,
|
|
TreeSelect,
|
|
DatePicker,
|
|
Cascader,
|
|
message,
|
|
Modal,
|
|
} from "antd";
|
|
import { dictionary } from "@/config/common";
|
|
import ajax from "@/services";
|
|
import exportAjax from "@/config/ajax";
|
|
import moment from "moment";
|
|
import { useSetState } from "ahooks";
|
|
import { ResultFlow, ExportBtn } from "@/components";
|
|
import "./index.scss";
|
|
const { RangePicker } = DatePicker;
|
|
//如想在外部调用搜索方法,请通过<TableModule ref={Ref} /> , Ref.current.fetche 的方式调用
|
|
const TableModule = forwardRef((props, ref) => {
|
|
const {
|
|
pagename = "",
|
|
columns = [], //表头
|
|
tableData = [], //table的数据
|
|
formSearch = [], //左侧数据搜索项
|
|
search = () => { }, //搜索按钮的回调函数
|
|
total = 0, //总数据量
|
|
initFormData = {}, //初始化的表格搜索项
|
|
exportUrl = "", //导出的接口
|
|
rowSelection = false, //自定义选择项
|
|
isExport = true, //是否显示导出按钮
|
|
rightButtonGroup = [], //右侧按钮额外的展示,需要传入数组
|
|
otherData = {}, //额外需要携带的参数,传入对象
|
|
rowKey, //table的key值
|
|
userInfo = {},//用户信息页面数据
|
|
} = props;
|
|
const [searchForm] = Form.useForm();
|
|
const [tipForm] = Form.useForm();
|
|
const timeFlag =
|
|
formSearch.filter((item) => {
|
|
return item.type === "FormSliderPicker";
|
|
}).length === 0
|
|
? false
|
|
: true;
|
|
const inputParams = {
|
|
maxLength: 50,
|
|
showCount: true,
|
|
};
|
|
|
|
const areaName =
|
|
formSearch.filter((item) => item.type === "TreeSelect")[0]?.name || null;
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
//区域的下拉数据
|
|
const [areaList, setAreaList] = useState([]);
|
|
//商户名称
|
|
const [operatorList, setOperatorList] = useState([]);
|
|
//时间范围
|
|
const [timeGroup, setTimeGroup] = useState({
|
|
timeType: 1,
|
|
timeRanges: {
|
|
start_time: moment().subtract(1, "day").format(),
|
|
end_time: moment().format(),
|
|
},
|
|
});
|
|
//区域列表
|
|
const [areaSelectedList, setAreaSelectedList] = useState([]);
|
|
const [toTime, setToTime] = useState(moment().subtract(3, 'days').startOf("day"));
|
|
//tip导出弹窗
|
|
const [tipModal, setTipModal] = useState({
|
|
visible: false,
|
|
filename:
|
|
pagename +
|
|
(new Date().getMonth() + 1).toString().padStart(2, "0") +
|
|
new Date().getDate(),
|
|
});
|
|
const [pageData, setPageData] = useSetState({
|
|
// 分页参数
|
|
pn: 1,
|
|
page_size: 15,
|
|
});
|
|
//导出参数
|
|
const [postdata, setPostdata] = useState({
|
|
formData: { ...pageData },
|
|
});
|
|
|
|
function onShowSizeChange(pn, page_size) {
|
|
setPageData({
|
|
pn,
|
|
page_size,
|
|
});
|
|
}
|
|
//查询函数
|
|
function fetch() {
|
|
// setLoading(true);
|
|
let form = { ...searchForm.getFieldsValue(), ...pageData, ...otherData };
|
|
if (timeFlag) {
|
|
form = {
|
|
...form,
|
|
timeType: timeGroup.timeType,
|
|
start_time: moment(timeGroup.timeRanges.start_time).format(
|
|
"YYYY-MM-DD HH:mm:ss"
|
|
),
|
|
end_time: moment(timeGroup.timeRanges.end_time).format(
|
|
"YYYY-MM-DD HH:mm:ss"
|
|
),
|
|
};
|
|
}
|
|
if (areaName !== null) form[areaName] = areaSelectedList;
|
|
if (form.start_time !== void 0 && form.end_time !== void 0) {
|
|
form.start_time = moment(form.start_time).format("YYYY-MM-DD HH:mm:ss");
|
|
form.end_time = moment(form.end_time).format("YYYY-MM-DD HH:mm:ss");
|
|
}
|
|
search(form);
|
|
}
|
|
//重置
|
|
function reset() {
|
|
searchForm.resetFields();
|
|
}
|
|
function cascaderChange(value, options) {
|
|
let last = options[options.length - 1];
|
|
let res = [];
|
|
if (last.children) {
|
|
addChild(last, res);
|
|
}
|
|
res.push(last.id);
|
|
setAreaSelectedList(res);
|
|
}
|
|
const addChild = (child, res) => {
|
|
if (child.children) {
|
|
child.children.forEach((item) => {
|
|
addChild(item, res);
|
|
});
|
|
} else {
|
|
res.push(child.id);
|
|
}
|
|
};
|
|
|
|
//查询部分
|
|
function renderSearch(params) {
|
|
return (
|
|
<Form
|
|
form={searchForm}
|
|
labelCol={{ span: 6 }}
|
|
wrapperCol={{ span: 18 }}
|
|
colon={false}
|
|
initialValues={initFormData}
|
|
>
|
|
<Row>
|
|
{formSearch.map((item) => {
|
|
let children = null;
|
|
switch (item.type) {
|
|
case "Input":
|
|
children = (
|
|
<Form.Item
|
|
label={item.label}
|
|
name={item.name}
|
|
key={item.name}
|
|
>
|
|
{item.hiddenCount ? (
|
|
<Input placeholder={item.placeholder} />
|
|
) : (
|
|
<Input {...inputParams} placeholder={item.placeholder} />
|
|
)}
|
|
</Form.Item>
|
|
);
|
|
break;
|
|
case "Select":
|
|
children = (
|
|
<Form.Item
|
|
label={item.label}
|
|
name={item.name}
|
|
key={item.name}
|
|
>
|
|
<Select
|
|
options={
|
|
item.name === "operator" || item.name === "merchantName"
|
|
? operatorList
|
|
: item.options
|
|
}
|
|
defaultValue={item.defaultValue}
|
|
placeholder={item.placeholder}
|
|
/>
|
|
</Form.Item>
|
|
);
|
|
break;
|
|
case "TreeSelect":
|
|
children = (
|
|
<Form.Item
|
|
label={item.label}
|
|
name={item.name}
|
|
key={item.name}
|
|
>
|
|
<Cascader
|
|
options={areaList}
|
|
placeholder="请选择区域"
|
|
expandTrigger="hover"
|
|
changeOnSelect
|
|
fieldNames={{
|
|
label: "name",
|
|
value: "id",
|
|
children: "children",
|
|
}}
|
|
onChange={cascaderChange}
|
|
/>
|
|
</Form.Item>
|
|
);
|
|
break;
|
|
case "RangePicker":
|
|
children = (
|
|
<>
|
|
<Form.Item
|
|
label={
|
|
(item.defaultTitle && item.defaultTitle[0]) ||
|
|
"开始时间"
|
|
}
|
|
name={"start_time"}
|
|
key={"start_time"}
|
|
initialValue={
|
|
toTime||(item.defaultValue && item.defaultValue[0]) ||
|
|
moment().startOf("day")
|
|
}
|
|
>
|
|
<DatePicker showTime format={"YYYY-MM-DD HH:mm:ss"} />
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="end_time"
|
|
label={
|
|
(item.defaultTitle && item.defaultTitle[1]) ||
|
|
"结束时间"
|
|
}
|
|
key={"end_time"}
|
|
initialValue={
|
|
(item.defaultValue && item.defaultValue[1]) || moment()
|
|
}
|
|
>
|
|
<DatePicker showTime format={"YYYY-MM-DD HH:mm:ss"} />
|
|
</Form.Item>
|
|
{/* <div onClick={() => { setToTime(moment().subtract(7, 'days').startOf("day")) }}>昨天</div> */}
|
|
</>
|
|
);
|
|
break;
|
|
case "FormSliderPicker":
|
|
children = (
|
|
<InputSelectGroup
|
|
onChange={(range, type) => {
|
|
setTimeGroup({ timeType: type, timeRanges: range });
|
|
}}
|
|
/>
|
|
);
|
|
break;
|
|
case "stopTime":
|
|
children = (
|
|
<Form.Item label="停车时长" name={item.name} key={item.name}>
|
|
<Input addonBefore="大于等于" addonAfter="分钟" />
|
|
</Form.Item>
|
|
);
|
|
break;
|
|
case "__react_node":
|
|
children = (
|
|
<Form.Item
|
|
label={item.label}
|
|
name={item.name}
|
|
key={item.name}
|
|
>
|
|
{item.component()}
|
|
</Form.Item>
|
|
);
|
|
}
|
|
return (
|
|
<Col span={24} key={item.label}>
|
|
{children}
|
|
</Col>
|
|
);
|
|
})}
|
|
</Row>
|
|
</Form>
|
|
);
|
|
}
|
|
|
|
function getAllOperator() {
|
|
ajax.getAllOperator().then((res) => {
|
|
if (res.status === 20000) {
|
|
setOperatorList(res.data);
|
|
}
|
|
});
|
|
}
|
|
|
|
const exportBtn = (filename) => {
|
|
let form = {
|
|
...searchForm.getFieldsValue(),
|
|
...pageData,
|
|
...otherData,
|
|
export: filename,
|
|
};
|
|
if (timeFlag) {
|
|
form = {
|
|
...form,
|
|
timeType: timeGroup.timeType,
|
|
start_time: moment(timeGroup.timeRanges.start_time).format(
|
|
"YYYY-MM-DD HH:mm:ss"
|
|
),
|
|
end_time: moment(timeGroup.timeRanges.end_time).format(
|
|
"YYYY-MM-DD HH:mm:ss"
|
|
),
|
|
};
|
|
}
|
|
if (areaName !== null) form[areaName] = areaSelectedList;
|
|
if (form.start_time !== void 0 && form.end_time !== void 0) {
|
|
form.start_time = moment(form.start_time).format("YYYY-MM-DD HH:mm:ss");
|
|
form.end_time = moment(form.end_time).format("YYYY-MM-DD HH:mm:ss");
|
|
}
|
|
exportAjax({
|
|
url: exportUrl,
|
|
type: "post",
|
|
data: form,
|
|
})
|
|
.then((res) => {
|
|
if (res.status === 20000) {
|
|
const link = document.createElement("a");
|
|
link.href = res.data.export_url;
|
|
link.target = "_blank"; // 打开新页面
|
|
link.click();
|
|
setTipModal({ ...tipModal, visible: false });
|
|
} else {
|
|
message.error(res.message);
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
};
|
|
function handleOk() {
|
|
tipForm
|
|
.validateFields()
|
|
.then((res) => {
|
|
exportBtn(res.filename);
|
|
})
|
|
.catch((err) => console.error(err));
|
|
}
|
|
useImperativeHandle(ref, () => ({
|
|
fetch,
|
|
}));
|
|
|
|
useEffect(() => {
|
|
getAllOperator();
|
|
}, []);
|
|
useEffect(() => {
|
|
fetch();
|
|
// setLoading(false);
|
|
}, [pageData]);
|
|
|
|
useEffect(() => {
|
|
ajax
|
|
.getAreaTree()
|
|
.then((res) => {
|
|
if (res.status === 20000) {
|
|
setAreaList(res.data);
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
}, []);
|
|
|
|
return (
|
|
<div className="TableModule">
|
|
<div className="left-search">
|
|
<div className="title">{"查询条件"}</div>
|
|
<div className="searchWrap">
|
|
{renderSearch()}
|
|
<div className="bottomBox">
|
|
<Button className="reset" onClick={reset}>
|
|
重置
|
|
</Button>
|
|
<Button type="primary" className="submit" onClick={fetch}>
|
|
查询
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="right-list">
|
|
{userInfo.all_user_count ?
|
|
<div className="total-wrapper">
|
|
<div className="total-item">
|
|
用户总量:<span>{userInfo.all_user_count} </span>
|
|
</div >
|
|
<div className="total-item">
|
|
身份认证总量:<span> {userInfo.auth_user_count}</span>
|
|
</div>
|
|
<div className="total-item">
|
|
绑定车辆会员数量:<span>{userInfo.total} </span>
|
|
</div>
|
|
</div>
|
|
: null}
|
|
|
|
<div className="total-row-wrapper">
|
|
<span className="number-wrapper">
|
|
<span className="letter">共查询到</span>
|
|
<span className="total-number"> {total}</span>
|
|
<span className="letter">条结果</span>
|
|
</span>
|
|
<div className="right-button-group">
|
|
{rightButtonGroup.map((item) => item)}
|
|
{isExport && (
|
|
<Button
|
|
type="primary"
|
|
onClick={() => setTipModal({ ...tipModal, visible: true })}
|
|
>
|
|
导出
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<ResultFlow
|
|
hasLoad={true}
|
|
loading={loading}
|
|
resultData={tableData}
|
|
message={"暂无数据"}
|
|
>
|
|
<div className="table-wrap">
|
|
<Table
|
|
rowSelection={rowSelection}
|
|
// className="yisa-table"
|
|
rowKey={rowKey}
|
|
columns={columns}
|
|
dataSource={tableData}
|
|
pagination={false}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<Pagination
|
|
className="pagination-common"
|
|
showSizeChanger={true}
|
|
showQuickJumper={true}
|
|
// showTotal={() => `共 ${total_records} 条`}
|
|
total={total}
|
|
current={pageData.pn}
|
|
pageSize={pageData.page_size}
|
|
pageSizeOptions={dictionary?.pageSizeOptions}
|
|
onChange={onShowSizeChange}
|
|
onShowSizeChange={onShowSizeChange}
|
|
/>
|
|
</div>
|
|
</ResultFlow>
|
|
</div>
|
|
<Modal
|
|
open={tipModal.visible}
|
|
onCancel={() => setTipModal({ ...tipModal, visible: false })}
|
|
title="提示"
|
|
onOk={handleOk}
|
|
>
|
|
<Form form={tipForm}>
|
|
<Form.Item
|
|
label="文件名"
|
|
name="filename"
|
|
initialValue={tipModal.filename}
|
|
rules={[{ required: true }]}
|
|
>
|
|
<Input defaultValue={tipModal.filename} />
|
|
</Form.Item>
|
|
</Form>{" "}
|
|
</Modal>
|
|
</div>
|
|
);
|
|
});
|
|
function InputSelectGroup(params) {
|
|
const { onChange = () => { } } = params;
|
|
const [timeType, setTimeType] = useState(1);
|
|
const [timeGroup, setTimeGroup] = useState({
|
|
start_time: moment().subtract(1, "day").format(),
|
|
end_time: moment().format(),
|
|
});
|
|
useEffect(() => {
|
|
onChange(timeGroup, timeType);
|
|
}, [timeGroup, timeType]);
|
|
return (
|
|
<>
|
|
<Row>
|
|
<Col span={8}>
|
|
<Select
|
|
style={{ width: "100%" }}
|
|
onChange={(timeType) => {
|
|
setTimeType(timeType);
|
|
}}
|
|
defaultValue={1}
|
|
options={[
|
|
{
|
|
label: "支付时间",
|
|
value: 1,
|
|
},
|
|
{
|
|
label: "抵扣时间",
|
|
value: 2,
|
|
},
|
|
]}
|
|
/>
|
|
</Col>
|
|
<Col span={16}>
|
|
<DatePicker
|
|
placeholder="请选择开始日期"
|
|
onChange={(val, string) => {
|
|
setTimeGroup({ ...timeGroup, start_time: string });
|
|
}}
|
|
format={"YYYY-MM-DD HH:mm:ss"}
|
|
defaultValue={moment().startOf("day")}
|
|
showTime
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col offset={8} span={16}>
|
|
<DatePicker
|
|
placeholder="请选择结束日期"
|
|
defaultValue={moment()}
|
|
onChange={(val, string) => {
|
|
setTimeGroup({ ...timeGroup, end_time: string });
|
|
}}
|
|
format={"YYYY-MM-DD HH:mm:ss"}
|
|
showTime
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default TableModule;
|