停车场项目web, 互联网仓库, 开发完成后, 需要将代码回传云桌面.
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

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;