Browse Source

增加计费规则管理页面

tags/PMS_Frontend_v1.0.6-develop
Liujinxu 2 years ago
parent
commit
a295a36459
  1. 32
      src/components/TableModule/index.jsx
  2. 34
      src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/RecordList.jsx
  3. 10
      src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/RefundList.jsx
  4. 47
      src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/StopList.jsx
  5. 10
      src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/index.jsx
  6. 53
      src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/loadable.jsx
  7. 149
      src/pages/OutRoadMgm/OutBusinessRecord/OutPayOrders/loadable.jsx
  8. 293
      src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/AddModal.jsx
  9. 182
      src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/Detail.jsx
  10. 193
      src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/EffectiveDate.jsx
  11. 178
      src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/TimePart.jsx
  12. 85
      src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/index.scss
  13. 179
      src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/loadable.jsx
  14. 254
      src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/ConfigParking/BillingRules.jsx
  15. 155
      src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/ConfigParking/TollCollectorManagement.jsx
  16. 2
      src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/ConfigParking/index.jsx
  17. 207
      src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/QRModal.jsx
  18. 12
      src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/index.scss
  19. 51
      src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/loadable.jsx
  20. 48
      src/services/OutRoadMgm/ChargeRulesMgm.js
  21. 25
      src/services/OutRoadMgm/OutParkingRecordInquiry.js
  22. 12
      src/services/OutRoadMgm/OutPayOrders.js
  23. 131
      src/services/OutRoadMgm/OutSegment.js
  24. 6
      src/services/OutRoadMgm/index.js

32
src/components/TableModule/index.jsx

@ -1,4 +1,11 @@
import React, { useState, useRef, useEffect, useLayoutEffect } from "react";
import React, {
useState,
useRef,
useEffect,
useLayoutEffect,
useImperativeHandle,
forwardRef,
} from "react";
import {
Form,
Pagination,
@ -22,8 +29,8 @@ import { useSetState } from "ahooks";
import { ResultFlow, ExportBtn } from "@/components";
import "./index.scss";
const { RangePicker } = DatePicker;
function TableModule(props) {
//<TableModule ref={Ref} /> Ref.current.fetche
const TableModule = forwardRef((props, ref) => {
const {
pagename = "",
columns = [], //
@ -337,6 +344,9 @@ function TableModule(props) {
})
.catch((err) => console.error(err));
}
useImperativeHandle(ref, () => ({
fetch,
}));
useEffect(() => {
getAllOperator();
@ -384,12 +394,14 @@ function TableModule(props) {
</span>
<div className="right-button-group">
{rightButtonGroup.map((item) => item)}
<Button
type="primary"
onClick={() => setTipModal({ ...tipModal, visible: true })}
>
导出
</Button>
{isExport && (
<Button
type="primary"
onClick={() => setTipModal({ ...tipModal, visible: true })}
>
导出
</Button>
)}
</div>
</div>
<ResultFlow
@ -443,7 +455,7 @@ function TableModule(props) {
</Modal>
</div>
);
}
});
function InputSelectGroup(params) {
const { onChange = () => {} } = params;
const [timeType, setTimeType] = useState(1);

34
src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/RecordList.jsx

@ -26,43 +26,43 @@ function RecordList({ id }) {
},
{
title: "应收金额",
dataIndex: "ys_money",
key: "ys_money",
dataIndex: "receivable_amount",
key: "receivable_amount",
},
{
title: "优惠金额",
dataIndex: "yh_money",
key: "yh_money",
dataIndex: "preferential_amount",
key: "preferential_amount",
},
{
title: "实收金额",
dataIndex: "sf_money",
key: "sf_money",
dataIndex: "actual_amount",
key: "actual_amount",
},
{
title: "支付类型",
dataIndex: "pay_type_name",
key: "pay_type_name",
dataIndex: "pay_type",
key: "pay_type",
},
{
title: "支付渠道",
dataIndex: "payment_type_name",
key: "payment_type_name",
dataIndex: "payment_channels",
key: "payment_channels",
},
{
title: "支付设备",
dataIndex: "payment_device_name",
key: "payment_device_name",
dataIndex: "payment_equipment",
key: "payment_equipment",
},
{
title: "支付人",
dataIndex: "car_owner_name",
key: "car_owner_name",
dataIndex: "dealer",
key: "dealer",
},
{
title: "付款车场",
dataIndex: "park_name",
key: "park_name",
dataIndex: "pay_road",
key: "pay_road",
},
{
title: "第三方流水ID",
@ -72,7 +72,7 @@ function RecordList({ id }) {
];
const [dataSource, setDataSource] = useState([]);
function getList() {
ajax.showPayList({ id }).then((res) => {
ajax.getOutParkingReacordPayment({ park_record_id: id }).then((res) => {
if (res.status === 20000) {
setDataSource(res.data.list);
}

10
src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/RefundList.jsx

@ -16,14 +16,14 @@ function RefundList({ id }) {
},
{
title: "支付渠道",
dataIndex: "payment_type_name",
key: "payment_type_name",
dataIndex: "payment_channels",
key: "payment_channels",
},
{
title: "支付设备",
dataIndex: "payment_device_name",
key: "payment_device_name",
dataIndex: "payment_channels",
key: "payment_channels",
},
{
title: "退款原因",
@ -54,7 +54,7 @@ function RefundList({ id }) {
];
const [dataSource, setDataSource] = useState([]);
function getList() {
ajax.showRefoundList({ id }).then((res) => {
ajax.getOutParkingReacordRefund({ park_record_id: id }).then((res) => {
if (res.status === 20000) {
setDataSource(res.data.list);
}

47
src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/StopList.jsx

@ -1,43 +1,26 @@
import React, { useState, useEffect } from "react";
import ajax from "@/services";
import { message, Descriptions, Image } from "antd";
function StopList({ id }) {
function StopList({ id, record }) {
//
const [recordData, setRecordData] = useState({});
const [recordData, setRecordData] = useState(record);
function getRecord() {
ajax.showStopList({ id }).then((res) => {
if (res.status === 20000) {
setRecordData(res.data.list[0]);
} else {
message.error(res.message);
}
});
}
useEffect(() => {
getRecord();
}, []);
return (
<div>
<Descriptions title="停车场信息">
<Descriptions.Item label="停车场名称">
{recordData.park_name}
</Descriptions.Item>
<Descriptions.Item label="区域">
{recordData.area_name}
{recordData.road}
</Descriptions.Item>
<Descriptions.Item label="区域">{recordData.region}</Descriptions.Item>
<Descriptions.Item label="商户">
{recordData.shop_name}
{recordData.operator}
</Descriptions.Item>
<Descriptions.Item label="车场类型">
{recordData.road_type_name}
{recordData.road_type}
</Descriptions.Item>
</Descriptions>
<Descriptions title="停车信息">
<Descriptions.Item label="车牌号">
{recordData.plate_num}
</Descriptions.Item>
<Descriptions.Item label="车牌号">{recordData.plate}</Descriptions.Item>
<Descriptions.Item label="会员手机号">
{recordData.phone}
</Descriptions.Item>
@ -48,16 +31,16 @@ function StopList({ id }) {
{recordData.out_time}
</Descriptions.Item>
<Descriptions.Item label="停车时长">
{recordData.parking_time}
{recordData.parking_duration}
</Descriptions.Item>
<Descriptions.Item label="应收金额">
{recordData.ys_money}
{recordData.receivable_amount}
</Descriptions.Item>
<Descriptions.Item label="优惠金额">
{recordData.yh_money}
{recordData.preferential_amount}
</Descriptions.Item>
<Descriptions.Item label="实付金额">
{recordData.sf_money}
{recordData.actual_amount}
</Descriptions.Item>
</Descriptions>
<Descriptions title="入场照片">
@ -68,6 +51,14 @@ function StopList({ id }) {
<Image src={recordData.in_plate_pic} />
</Descriptions.Item>
</Descriptions>
<Descriptions title="出场照片">
<Descriptions.Item label="出场车辆照片">
<Image src={recordData.out_veh_pic} />
</Descriptions.Item>
<Descriptions.Item label="出场车牌照片">
<Image src={recordData.out_plate_pic} />
</Descriptions.Item>
</Descriptions>
</div>
);
}

10
src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/Detail/index.jsx

@ -6,13 +6,19 @@ import RecordList from "./RecordList";
import RefundList from "./RefundList";
import "./index.scss";
function Detail(props) {
const { visible = false, close = () => {}, onOk = () => {}, id } = props;
const {
visible = false,
close = () => {},
onOk = () => {},
id,
record = {},
} = props;
//tabs
const tabsItems = [
{
label: "停车记录",
key: "1",
children: <StopList id={id} />,
children: <StopList id={id} record={record} />,
},
{
label: "支付记录",

53
src/pages/OutRoadMgm/OutBusinessRecord/OutParkingRecordInquiry/loadable.jsx

@ -13,61 +13,62 @@ function OutParkingRecordInquiry() {
title: "序号",
dataIndex: "id",
key: "id",
render: (text, record, index) => index + 1,
},
{
title: "区域",
dataIndex: "area",
key: "area",
dataIndex: "region",
key: "region",
},
{
title: "商户名称",
dataIndex: "merchantName",
key: "merchantName",
dataIndex: "operator",
key: "operator",
},
{
title: "停车场名称",
dataIndex: "parkingLotName",
key: "parkingLotName",
dataIndex: "road",
key: "road",
},
{
title: "车场类型",
dataIndex: "parkingLotType",
key: "parkingLotType",
dataIndex: "road_type",
key: "road_type",
},
{
title: "车牌号",
dataIndex: "licensePlate",
key: "licensePlate",
dataIndex: "plate",
key: "plate",
},
{
title: "泊位号",
dataIndex: "berthNumber",
key: "berthNumber",
dataIndex: "berth_id",
key: "berth_id",
},
{
title: "入场时间",
dataIndex: "entryTime",
key: "entryTime",
dataIndex: "in_time",
key: "in_time",
},
{
title: "离场时间",
dataIndex: "exitTime",
key: "exitTime",
dataIndex: "out_time",
key: "out_time",
},
{
title: "停车时长",
dataIndex: "parkingDuration",
key: "parkingDuration",
dataIndex: "parking_duration",
key: "parking_duration",
},
{
title: "应收金额",
dataIndex: "receivableAmount",
key: "receivableAmount",
dataIndex: "receivable_amount",
key: "receivable_amount",
},
{
title: "实收金额",
dataIndex: "actualAmount",
key: "actualAmount",
dataIndex: "actual_amount",
key: "actual_amount",
},
{
title: "操作",
@ -78,10 +79,12 @@ function OutParkingRecordInquiry() {
onClick={() => {
setDetailModal({
...detailModal,
record,
visible: true,
id: record.id,
});
}}
type="primary"
>
操作
</Button>
@ -144,6 +147,7 @@ function OutParkingRecordInquiry() {
const [detailModal, setDetailModal] = useState({
id: "",
visible: false,
record: {},
close: () => setDetailModal({ ...detailModal, visible: false }),
onOk: () => {
detailModal.close();
@ -151,7 +155,7 @@ function OutParkingRecordInquiry() {
});
function fetch(params) {
ajax.getRecordList(params).then((res) => {
ajax.getOutParkingRecordList(params).then((res) => {
if (res.status === 20000) {
setTableData(res.data.list);
setTotal(res.data.total);
@ -169,13 +173,14 @@ function OutParkingRecordInquiry() {
pagename=""
search={fetch}
initFormData={initFormData}
exportUrl=""
isExport={false} //
/>
<Detail
visible={detailModal.visible}
close={detailModal.close}
onOk={detailModal.onOk}
id={detailModal.id}
record={detailModal.record}
/>
</>
);

149
src/pages/OutRoadMgm/OutBusinessRecord/OutPayOrders/loadable.jsx

@ -1,15 +1,150 @@
import React, { useState, useRef, useEffect } from "react";
// import { message, Pagination, Table, Space, Modal, } from "antd";
import { message, Pagination, Table, Space, Modal, Button } from "antd";
// import { dictionary, utils } from "@/config/common";
// import moment from 'moment'
// import { useSessionStorageState, useUpdateEffect, useSize, useUpdate } from 'ahooks';
// import ajax from "@/services"
// import { FormInput, FormSelect, OptionPanel, ResultPanel, FormSliderPicker, AreaCascader, ImgResize, ImgZoom, } from "@/components"
// import "./index.scss";
// import errorImg from "@/assets/images/layout/error.png"
// import { useLocation } from "react-router-dom";
import ajax from "@/services";
import { TableModule } from "@/components";
import "./index.scss";
function OutPayOrders() {
return <div>OutPayOrders</div>
const columns = [
{
title: "订单ID",
dataIndex: "order_id",
key: "order_id",
},
{
title: "停车场",
dataIndex: "road",
key: "road",
},
{
title: "车牌号",
dataIndex: "plate",
key: "plate",
},
{
title: "入场时间",
dataIndex: "in_time",
key: "in_time",
},
{
title: "出场时间",
dataIndex: "out_time",
key: "out_time",
},
{
title: "停车时长",
dataIndex: "parking_duration",
key: "parking_duration",
},
{
title: "应收金额",
dataIndex: "receivable_amount",
key: "receivable_amount",
},
{
title: "实收金额",
dataIndex: "actual_amount",
key: "actual_amount",
},
{
title: "支付渠道",
dataIndex: "payment_channels",
key: "payment_channels",
},
{
title: "支付设备",
dataIndex: "payment_equipment",
key: "payment_equipment",
},
{
title: "操作人",
dataIndex: "dealer",
key: "dealer",
},
{
title: "支付时间",
dataIndex: "pay_time",
key: "pay_time",
},
{
title: "第三方流水ID",
dataIndex: "third_party_flow_id",
key: "third_party_flow_id",
},
];
const formSearch = [
{
name: "road",
type: "Input",
label: "停车场名称",
placeholder: "请选择停车场名称",
},
{
name: "plate",
type: "Input",
label: "车牌号",
placeholder: "请输入车牌号",
},
{
name: "payment_channels",
type: "Select",
label: "支付渠道",
placeholder: "请选择支付渠道",
},
{
name: "payment_equipment",
type: "Select",
label: "支付设备",
placeholder: "请选择支付设备",
},
{
name: "time",
type: "RangePicker",
label: "时间段",
},
];
//
const initFormData = {};
//
const [tableData, setTableData] = useState([]);
//
const [total, setTotal] = useState(0);
const [detailModal, setDetailModal] = useState({
id: "",
visible: false,
record: {},
close: () => setDetailModal({ ...detailModal, visible: false }),
onOk: () => {
detailModal.close();
},
});
function fetch(params) {
ajax.getOutPayOrdersList(params).then((res) => {
if (res.status === 20000) {
setTableData(res.data.list);
setTotal(res.data.total);
}
});
}
return (
<>
<TableModule
columns={columns}
tableData={tableData}
formSearch={formSearch}
total={total}
pagename="停车支付订单"
search={fetch}
initFormData={initFormData}
exportUrl="/api/orp/business/get_payment_export"
/>
</>
);
}
export default OutPayOrders;

293
src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/AddModal.jsx

@ -0,0 +1,293 @@
import React, { useEffect, useState } from "react";
import {
Modal,
Form,
Input,
Select,
Button,
Row,
Col,
Divider,
Checkbox,
Radio,
message,
} from "antd";
import ajax from "@/services";
import EffectiveDate from "./EffectiveDate";
function AddModal(props) {
const [form] = Form.useForm();
const {
record = {},
visible = false,
close = () => {},
status = "add",
research = () => {},
} = props;
const isEdit = status === "edit";
const [effectiveDateList, setEffectiveDateList] = useState(() => {
if (status === "add") {
return [
{
key:
Math.floor(Math.random() * 1000).toString() +
Date.now().toString().substring(0, 6),
},
];
} else {
return record.property.map((item) => {
item.key =
Math.floor(Math.random() * 1000).toString() +
Date.now().toString().substring(0, 6);
item.status = "disable";
return item;
});
}
});
function addEctiveDate() {
const randomNum = Math.floor(Math.random() * 1000);
const item = {
key: randomNum.toString() + Date.now().toString().substring(0, 6),
};
console.log(effectiveDateList);
setEffectiveDateList([...effectiveDateList, item]);
}
function removeEffectiveDate(key) {
const _effectiveDateList = effectiveDateList
.map((item) => item.key !== key && item)
.filter((item) => item.key !== undefined);
setEffectiveDateList(_effectiveDateList);
}
//
function submitSuccess() {
research();
close();
}
//
function fetch(params) {
if (status === "add") {
ajax.addChargeRule(params).then((res) => {
if (res.status === 20000) {
message.success("添加成功");
submitSuccess();
} else {
message.error(res.message);
}
});
} else {
ajax.editChargeRule(params).then((res) => {
if (res.status === 20000) {
message.success("编辑成功");
submitSuccess();
} else {
message.error(res.message);
}
});
}
}
//
function submit() {
form
.validateFields()
.then((res) => {
const params = {
...res,
property: effectiveDateList,
};
fetch(params);
})
.catch((err) => console.error(err));
}
return (
<Modal
open={visible}
width={1200}
onCancel={close}
title="添加"
onOk={submit}
>
<div>
<Form
form={form}
labelCol={{ span: 6 }}
colon={false}
initialValues={record}
>
<Row gutter={[30]}>
<Col span={12}>
<Form.Item
label="计费规则名称"
name="feeName"
rules={[{ required: true }]}
>
<Input style={{ width: "40%" }} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="规则编码"
name="feeCode"
rules={[{ required: true }]}
>
<Input style={{ width: "40%" }} />
</Form.Item>
</Col>
<Col style={{ width: "50%" }}>
<Form.Item
label="所属商户"
name="operationId"
rules={[{ required: true }]}
>
<Select
disabled={isEdit}
style={{ width: "40%" }}
options={[
{
label: "测试",
value: 1,
},
]}
/>
</Form.Item>
</Col>
<Col style={{ width: "50%" }}>
<Form.Item
label="描述"
name="description"
rules={[{ required: true }]}
>
<Input.TextArea />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="24小时最大收费金额" name="limit24hour">
<Input addonAfter={"元"} style={{ width: "57%" }} />
</Form.Item>
</Col>
<Col span={13}>
<Form.Item
label="免费分钟数"
name="freeTime"
rules={[{ required: true }]}
>
<Input addonAfter={"分"} style={{ width: "50%" }} />
</Form.Item>
</Col>
<Col span={11}>
<Form.Item name="freeTimeAbleF">
<Checkbox.Group
options={[
{
label: "免费分钟数纳入计费时间",
value: 1,
},
]}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="特殊车辆优惠"
name="typeF"
rules={[{ required: true }]}
initialValue={1}
>
<Radio.Group
options={[
{
label: "启用",
value: 1,
},
{
label: "禁用",
value: 0,
},
]}
></Radio.Group>
</Form.Item>
</Col>
<Form.Item
shouldUpdate={(prev, cur) => prev.typeF !== cur.typeF}
noStyle
>
{({ getFieldValue, setFieldsValue }) => {
const type = getFieldValue("typeF");
if (type === 0) {
setFieldsValue({ evFreeTime: "", evFreeTimeAble: [] });
}
return (
<>
<Col span={13}>
<Form.Item
label="新能源车辆免费分钟"
name="evFreeTime"
initialValue={type === 0 || ""}
>
<Input
disabled={type === 0}
addonAfter={"分"}
style={{ width: "50%" }}
/>
</Form.Item>
</Col>
<Col span={11}>
<Form.Item
name="evFreeTimeAble"
initialValue={type === 0 && []}
>
<Checkbox.Group
disabled={type === 0}
options={[
{
label: "免费分钟数纳入计费时间",
value: 1,
},
]}
/>
</Form.Item>
</Col>
</>
);
}}
</Form.Item>
</Row>
</Form>
<div>
<Button
onClick={addEctiveDate}
type="primary"
style={{ margin: "0 0 20px 0" }}
>
添加生效日期
</Button>
</div>
<Divider />
{effectiveDateList.map((item, index) => {
return (
<EffectiveDate
disable={item.status === "disable"}
record={item}
key={item.key}
index={index + 1}
itemKey={item.key}
remove={removeEffectiveDate}
onChange={(value, key) => {
const _effectiveDateList = effectiveDateList.map((item) => {
if (item.key === key) {
item = { ...item, ...value };
}
return item;
});
setEffectiveDateList(_effectiveDateList);
}}
/>
);
})}
</div>
</Modal>
);
}
export default AddModal;

182
src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/Detail.jsx

@ -0,0 +1,182 @@
import React, { useState, useEffect } from "react";
import {
Modal,
Form,
Input,
Select,
Button,
Row,
Col,
Divider,
Checkbox,
Descriptions,
Radio,
} from "antd";
import EffectiveDate from "./EffectiveDate";
import ajax from "@/services";
function Detail(props) {
const { record, visible = false, close = () => {} } = props;
const [form] = Form.useForm();
const [effectiveDateList, setEffectiveDateList] = useState(record.property);
useEffect(() => {
setEffectiveDateList(record.property);
console.log(record.property);
}, []);
return (
<Modal
open={visible}
destroyOnClose
onCancel={close}
width={1200}
title="详情"
>
<div>
<Descriptions column={2}>
<Descriptions.Item label="规则名称" span={1}>
{record.feeName}
</Descriptions.Item>
<Descriptions.Item label="编码" span={1}>
{record.feeCode}
</Descriptions.Item>
<Descriptions.Item label="描述" span={1}>
{record.description}
</Descriptions.Item>
<Descriptions.Item label="所属商户" span={1}>
{record.operationName}
</Descriptions.Item>
<Descriptions.Item label="操作时间" span={1}>
{record.createdTime}
</Descriptions.Item>
<Descriptions.Item label="14小时最大收费金额" span={1}>
{record.limit24hour}
</Descriptions.Item>
<Descriptions.Item label="免费分钟数" span={1}>
{record.freeTime}
<div style={{ margin: "0 10px" }}>
<Checkbox disabled defaultChecked={record.freeTimeAbleF}>
免费分钟数纳入计费时间
</Checkbox>
</div>
</Descriptions.Item>
<Descriptions.Item label="特殊车辆优惠" span={2}>
<Radio.Group
disabled
defaultValue={record.typeF}
options={[
{
label: "启用",
value: 1,
},
{
label: "禁用",
value: 0,
},
]}
/>
</Descriptions.Item>
<Descriptions.Item label="新能源车辆免费分钟" span={1}>
{record.evFreeTime}
<div style={{ margin: "0 10px" }}>
<Checkbox disabled defaultChecked={record.evFreeTimeAble}>
免费分钟数纳入计费时间
</Checkbox>
</div>
</Descriptions.Item>
</Descriptions>
<Divider />
{effectiveDateList &&
effectiveDateList.map((item, index) => {
console.log(item);
return <EffectiveDetail record={item} key={index} />;
})}
</div>
</Modal>
);
}
function EffectiveDetail(props) {
const { record } = props;
console.log(123);
return (
<>
<Descriptions column={2}>
<Descriptions.Item label="生效日期" span={1}>
{record.effective_date}
</Descriptions.Item>
<Descriptions.Item span={2}>
<Checkbox.Group
defaultValue={record.unit_fee_type_group}
disabled
options={[
{
label: "跨段延续计费",
value: 1,
},
{
label: "出场时不满计费单元部分补齐计费单元收费",
value: 2,
},
]}
></Checkbox.Group>
</Descriptions.Item>
</Descriptions>
{record.time_part_arr.map((item, index) => {
return <TimePartDetail index={index + 1} record={item} />;
})}
</>
);
}
function TimePartDetail(props) {
const { record, index } = props;
function partName(type) {
switch (type) {
case 1:
return "基础时段";
case 2:
return "周期计费";
case 3:
return "按次计费";
}
}
return (
<>
<Descriptions column={2}>
<Descriptions.Item label={`时段${index}`}>
{`${record.time_part[0]}-${record.time_part[1]}`}
</Descriptions.Item>
{(record.interval === 1 || record.interval === 2) && (
<Descriptions.Item label="时段最高金额">
{record.time_max_money}
</Descriptions.Item>
)}
<Descriptions.Item label={`区间${index}`} span={2}>
{partName(record.interval)}
</Descriptions.Item>
{record.interval === 1 && (
<>
<Descriptions.Item span={2}>
<div>{`前:${record.time_before} 分钟,${record.time_before_money}元/${record.time_before_minute}分钟`}</div>
</Descriptions.Item>
<Descriptions.Item span={2}>
<div>{`满:${record.time_before} 分钟后,${record.time_after_money}元/${record.time_after_minute}分钟`}</div>
</Descriptions.Item>
</>
)}
{record.interval === 2 && (
<Descriptions.Item span={2}>
<div>{`${record.time_money}元/${record.time_minute}分钟`}</div>
</Descriptions.Item>
)}
{record.interval === 3 && (
<Descriptions.Item span={2}>
<div>{`${record.money_per_time}元/次`}</div>
</Descriptions.Item>
)}
</Descriptions>
<Divider />
</>
);
}
export default Detail;

193
src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/EffectiveDate.jsx

@ -0,0 +1,193 @@
import React, { useEffect, useState } from "react";
import {
Form,
Input,
Button,
Select,
DatePicker,
Checkbox,
Row,
Col,
Divider,
message,
} from "antd";
import TimePart from "./TimePart";
import moment from "moment";
function EffectiveDate(props) {
const {
remove = () => {},
itemKey,
onChange = () => {},
index,
disable = false,
record = {},
} = props;
const [form] = Form.useForm();
const [timePartList, setTimePartList] = useState(() => {
if (!disable) {
return [
{
key:
Math.floor(Math.random() * 1000).toString() +
Date.now().toString().substring(0, 6),
},
];
} else {
return record.time_part_arr.map((item) => {
item.status = "disable";
item.key =
Math.floor(Math.random() * 1000).toString() +
Date.now().toString().substring(0, 6);
return item;
});
}
});
const addTimePart = () => {
const randomNum = Math.floor(Math.random() * 1000);
const item = {
key: randomNum.toString() + Date.now().toString().substring(0, 6),
};
setTimePartList([...timePartList, item]);
};
const removeTimePart = (key) => {
const _timePartList = timePartList
.map((item) => item.key !== key && item)
.filter((item) => item.key !== undefined);
setTimePartList(_timePartList);
};
//
function isOneDay(time) {
let total = 0;
for (let i = 0; i < timePartList.length; i++) {
if (timePartList[i].time_part) {
total += Math.abs(
moment(timePartList[i].time_part[1], "HH:mm:ss").diff(
moment(timePartList[i].time_part[0], "HH:mm:ss"),
"minutes"
)
);
}
}
total += 1;
console.log(total);
if (total === 1440) {
return true;
}
return false;
}
function submit() {
form
.validateFields()
.then((values) => {
if (isOneDay(values)) {
message.success("时段检验通过");
} else {
message.error("时段检验未通过");
}
})
.catch((err) => {
console.error(err);
});
}
return (
<div>
<Form
form={form}
initialValues={{
...record,
effective_date: moment(record.effective_date),
}}
disabled={disable}
>
<Row>
<Col span={12}>
<Form.Item
label="生效日期"
name="effective_date"
rules={[{ required: true }]}
>
<DatePicker />
</Form.Item>
</Col>
<Col span={12}>
{index !== 1 && (
<Button type="primary" onClick={() => remove(itemKey)}>
移除
</Button>
)}
</Col>
</Row>
<Form.Item name="unit_fee_type_group">
<Checkbox.Group
options={[
{
label: "跨段延续计费",
value: 1,
},
{
label: "出场时不满计费单元部分补齐计费单元收费",
value: 2,
},
]}
></Checkbox.Group>
</Form.Item>
</Form>
{!disable && (
<>
<Button
onClick={addTimePart}
type="primary"
style={{ margin: "0 0 20px 0 " }}
>
添加时段
</Button>
<Button type="primary" style={{ margin: "0 10px" }} onClick={submit}>
检验时段
</Button>
</>
)}
<Divider />
{timePartList.map((item, index) => {
console.log(item);
return (
<TimePart
disable={item.status === "disable"}
record={item}
index={index + 1}
key={item.key}
remove={removeTimePart}
itemKey={item.key}
onChange={(value) => {
const _timePartList = timePartList.map((item) => {
if (item.key === value.key) {
if (value.time_part) {
value.time_part = value.time_part.map((item) => {
item = item.format("HH:mm:ss");
return item;
});
}
return value;
} else {
return item;
}
});
const obj = {
...form.getFieldsValue(),
time_part_arr: _timePartList,
};
if (obj.effective_date !== void 0) {
obj.effective_date = obj.effective_date.format("YYYY-MM-DD");
}
onChange(obj, itemKey);
setTimePartList(_timePartList);
}}
/>
);
})}
</div>
);
}
export default EffectiveDate;

178
src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/TimePart.jsx

@ -0,0 +1,178 @@
import React, { useEffect, useState } from "react";
import {
Form,
Input,
Button,
Select,
DatePicker,
TimePicker,
Row,
Col,
Divider,
} from "antd";
import moment from "moment";
function TimePart(props) {
const [form] = Form.useForm();
const {
index,
remove,
itemKey,
onChange = () => {},
record,
disable = false,
} = props;
console.log(disable);
const valueChange = (value, all) => {
all.key = itemKey;
onChange(all);
};
return (
<div>
<Form
form={form}
onValuesChange={valueChange}
disabled={disable}
initialValues={
disable
? {
...record,
time_part: [
moment(record.time_part[0], "HH:mm:ss"),
moment(record.time_part[1], "HH:mm:ss"),
],
}
: {}
}
>
<Row gutter={[30]}>
<Col span={16}>
<Form.Item label={`时段${index}`} name="time_part">
<TimePicker.RangePicker style={{ width: "50%" }} order={false} />
</Form.Item>
</Col>
<Col span={8}>
{index === 1 ? null : (
<Button type="primary" onClick={() => remove(itemKey)}>
移除
</Button>
)}
</Col>
<Col span={24}>
<Form.Item label={`区间${index}`} name="interval" initialValue={1}>
<Select
style={{ width: "20%" }}
options={[
{
label: "基础时段",
value: 1,
},
{
label: "周期计价",
value: 2,
},
{
label: "按次计价",
value: 3,
},
]}
/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
shouldUpdate={(prev, next) => prev.interval !== next.interval}
>
{({ getFieldValue }) => {
const type = getFieldValue("interval");
switch (type) {
case 1:
return (
<>
<Input.Group compact>
<Form.Item name="time_before" label="前:">
<Input addonAfter={"分钟"} />
</Form.Item>
<Form.Item name="time_before_money" noStyle>
<Input
addonAfter={"元/"}
style={{ width: "20%" }}
/>
</Form.Item>
<Form.Item name="time_before_minute" noStyle>
<Input
addonAfter={"分钟"}
style={{ width: "20%" }}
/>
</Form.Item>
</Input.Group>
<Input.Group compact>
<Form.Item name="time_before" label="满:">
<Input addonAfter={"分钟"} disabled />
</Form.Item>
<Form.Item name="time_after_money" noStyle>
<Input
addonAfter={"元/"}
style={{ width: "20%" }}
/>
</Form.Item>
<Form.Item name="time_after_minute" noStyle>
<Input
addonAfter={"分钟"}
style={{ width: "20%" }}
/>
</Form.Item>
</Input.Group>
</>
);
case 2:
return (
<Input.Group compact>
<Form.Item name="time_money" noStyle>
<Input addonAfter={"元/"} style={{ width: "20%" }} />
</Form.Item>
<Form.Item name="time_minute" noStyle>
<Input addonAfter={"分钟"} style={{ width: "20%" }} />
</Form.Item>
</Input.Group>
);
case 3:
return (
<Form.Item name="money_per_time">
<Input addonAfter={"元/次"} style={{ width: "20%" }} />
</Form.Item>
);
}
}}
</Form.Item>
</Col>
<Form.Item
shouldUpdate={(prev, next) => prev.interval !== next.interval}
>
{({ getFieldValue }) => {
return (
(getFieldValue("interval") === 1 ||
getFieldValue("interval") === 2) && (
<Col span={24}>
<Form.Item
label="时段最高收费金额"
name="time_max_money"
rules={[{ required: true }]}
>
<Input />
</Form.Item>
</Col>
)
);
}}
</Form.Item>
</Row>
</Form>
<Divider></Divider>
</div>
);
}
export default TimePart;

85
src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/index.scss

@ -1,5 +1,82 @@
@import "@/assets/css/mixin.scss";
$color-container-bg : var(--color-container-bg);
$color-user-list-bg : var(--color-user-list-bg);
$color-text : var(--color-text);
$color-primary : var(--color-primary);
$color-container-bg: var(--color-container-bg);
$color-user-list-bg: var(--color-user-list-bg);
$color-text: var(--color-text);
$color-primary: var(--color-primary);
.ant-modal-content {
.charge-rule-bottom-button {
display: flex;
justify-content: center;
margin-top: 20px;
button {
margin: 0 10px;
}
}
textarea,
input {
background: var(--color-search-list-item-bg);
}
.ant-select-selection-placeholder {
color: var(--color-placeholder);
}
.ant-select-disabled.ant-select-single:not(.ant-select-customize-input) .ant-select-selector {
background: var(--color-input-disabled-bg);
color: var(--color-placeholder);
}
.ant-select-disabled .ant-select-arrow {
color: var(--color-placeholder);
}
.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector {
background-color: var(--color-input-disabled-bg);
color: var(--color-input-disabled-color);
cursor: not-allowed;
}
.ant-select-multiple {
.ant-select-selector {
.ant-select-selection-item {
background-color: var(--color-bg-body);
border-color: var(--color-border);
.ant-select-selection-item-remove {
color: var(--color-text);
}
}
}
}
.ant-select-arrow {
color: var(--color-text);
}
.ant-select-clear {
border-radius: 50%;
}
.ant-select-dropdown-menu {
background-color: var(--color-input-bg);
.ant-select-dropdown-menu-item {
color: var(--color-text);
&.ant-select-dropdown-menu-item-active {
color: #fff;
// background-color: var(--radio-button-bg-checked);
}
&.ant-select-dropdown-menu-item-selected {
color: #fff;
// background-color: var(--radio-button-bg-checked);
}
&:hover {
color: #fff;
// background-color: var(--radio-button-bg-checked);
}
}
}
.ant-select-selector {
background-color: var(--color-search-list-item-bg) !important;
box-shadow: none !important;
border-radius: 4px;
color: var(--color-search-list-item-value);
border-color: var(--color-search-list-item-bd) !important;
}
.ant-select-selection {
background-color: var(--color-input-bg);
box-shadow: none;
color: var(--color-text);
// border-color:var(--checkable-tag-border);
}
}

179
src/pages/OutRoadMgm/OutSegmentMgm/ChargeRulesMgm/loadable.jsx

@ -1,37 +1,47 @@
import React, { useState, useRef, useEffect } from "react";
import { message, Pagination, Table, Space, Modal, Button } from "antd";
import {
message,
Pagination,
Table,
Space,
Modal,
Button,
Popover,
} from "antd";
// import { dictionary, utils } from "@/config/common";
// import moment from 'moment'
// import { useSessionStorageState, useUpdateEffect, useSize, useUpdate } from 'ahooks';
import ajax from "@/services";
import { TableModule } from "@/components";
import AddModal from "./AddModal";
import Detail from "./Detail";
import "./index.scss";
function ChargeRulesMgm() {
const columns = [
{
title: "商户名称",
dataIndex: "merchantName",
key: "merchantName",
dataIndex: "operationName",
key: "operationName",
},
{
title: "规则名称",
dataIndex: "ruleName",
key: "ruleName",
dataIndex: "feeName",
key: "feeName",
},
{
title: "规则编码",
dataIndex: "ruleCode",
key: "ruleCode",
dataIndex: "feeName",
key: "feeName",
},
{
title: "创建人",
dataIndex: "creator",
key: "creator",
dataIndex: "creatorName",
key: "creatorName",
},
{
title: "更新时间",
dataIndex: "updateTime",
key: "updateTime",
dataIndex: "createdTime",
key: "createdTime",
},
{
title: "描述",
@ -42,7 +52,56 @@ function ChargeRulesMgm() {
title: "操作",
dataIndex: "operation",
key: "operation",
render: () => <a>Edit</a>,
render: (_, record) => {
return (
<Popover
trigger={"hover"}
content={
<div>
<div>
<a
onClick={() => {
getRuleDetail(record.id);
}}
>
查看
</a>
</div>
<div>
<a
onClick={() => {
ajax.getChargeRuleInfo({ id: record.id }).then((res) => {
if (res.status === 20000) {
console.log(res.data);
setAddModal({
...addModal,
visible: true,
record: res.data,
status: "edit",
});
}
});
}}
>
编辑
</a>
</div>
<div>
<a
onClick={() => {
delChargeRule(record.id);
}}
>
删除
</a>
</div>
</div>
}
>
<Button type="primary">操作</Button>
</Popover>
);
},
},
];
const formSearch = [
@ -74,32 +133,106 @@ function ChargeRulesMgm() {
road_type: 0,
plate: "",
};
//ref
const childRef = useRef(null);
//
const [tableData, setTableData] = useState([]);
//
const [total, setTotal] = useState(0);
//modal
const [addModal, setAddModal] = useState({
visible: false,
close: () => setAddModal({ ...addModal, visible: false }),
record: {},
status: "add",
});
//modal
const [detailModal, setDetailModal] = useState({
visible: false,
close: () => setDetailModal({ ...detailModal, visible: false }),
record: {},
});
function addItem() {
return (
<Button
type="primary"
key="add"
onClick={() => {
setAddModal({
...addModal,
visible: true,
record: {},
status: "add",
});
}}
>
添加
</Button>
);
}
function fetch(params) {
ajax.getParkingArrearsList(params).then((res) => {
ajax.getChargeRuleList(params).then((res) => {
if (res.status === 20000) {
setTableData(res.data.list);
setTotal(res.data.total);
}
});
}
//
function delChargeRule(id) {
ajax.delChargeRule({ id }).then((res) => {
if (res.status === 20000) {
message.success("删除成功");
research();
}
});
}
//research
function research() {
childRef.current.fetch();
}
const getRuleDetail = (id) => {
ajax.getChargeRuleInfo({ id }).then((res) => {
if (res.status === 20000) {
setDetailModal({ ...detailModal, visible: true, record: res.data });
console.log(res.data);
}
});
};
//TODO
return (
<TableModule
columns={columns}
tableData={tableData}
formSearch={formSearch}
total={total}
pagename="停车欠费订单"
search={fetch}
initFormData={initFormData}
exportUrl="/api/bpm/record/get_parking_arrears_export"
/>
<>
<TableModule
ref={childRef}
columns={columns}
tableData={tableData}
formSearch={formSearch}
total={total}
search={fetch}
initFormData={initFormData}
isExport={false}
rightButtonGroup={[addItem()]}
/>
{addModal.visible && (
<AddModal
visible={addModal.visible}
close={addModal.close}
record={addModal.record}
status={addModal.status}
research={research}
/>
)}
{detailModal.visible && (
<Detail
visible={detailModal.visible}
close={detailModal.close}
record={detailModal.record}
/>
)}
</>
);
}

254
src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/ConfigParking/BillingRules.jsx

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import {
Input,
Form,
@ -9,49 +9,52 @@ import {
Modal,
Select,
Popover,
message,
} from "antd";
function BillingRules() {
import ajax from "@/services";
function BillingRules(props) {
const { id } = props;
const [form] = Form.useForm();
const [editform] = Form.useForm();
const carTypeList = [
{ label: "小型车", value: 1 },
{ label: "大型车", value: 2 },
];
const columns = [
{
title: "规则名称",
dataIndex: "ruleName",
key: "ruleName",
dataIndex: "rule_name",
key: "rule_name",
align: "center",
},
{
title: "规则编码",
dataIndex: "ruleCode",
key: "ruleCode",
dataIndex: "rule_code",
key: "rule_code",
align: "center",
},
{
title: "车辆类型",
dataIndex: "vehicleType",
key: "vehicleType",
dataIndex: "vehicle_type",
key: "vehicle_type",
align: "center",
},
{
title: "车辆组",
dataIndex: "vehicleGroup",
key: "vehicleGroup",
align: "center",
},
{
title: "同步状态",
dataIndex: "syncStatus",
key: "syncStatus",
dataIndex: "group_ids",
key: "group_ids",
align: "center",
},
{
title: "描述",
dataIndex: "description",
key: "description",
dataIndex: "group_ids",
key: "group_ids",
align: "center",
},
{
title: "更新时间",
dataIndex: "updateTime",
key: "updateTime",
dataIndex: "update_time",
key: "update_time",
align: "center",
},
{
@ -59,14 +62,36 @@ function BillingRules() {
dataIndex: "action",
key: "action",
align: "center",
render: () => {
render: (_, record) => {
return (
<Popover
trigger="hover"
content={
<div>
<p>编辑</p>
<p>删除</p>
<div>
<a
onClick={() => {
setModalData({ ...modalData, visible: true });
console.log(record.group_ids);
editform.setFieldsValue({
rule_id: record.rule_id,
vehicle_type: record.vehicle_type,
group_ids: +record.group_ids,
});
}}
>
编辑
</a>
</div>
<div>
<a
onClick={() => {
setDelModal({ id: record.id, visible: true });
}}
>
删除
</a>
</div>
</div>
}
>
@ -78,23 +103,136 @@ function BillingRules() {
];
const [modalData, setModalData] = useState({
visible: false,
status: "add",
});
//
const [chargeRuleList, setChargeRuleList] = useState([]);
//
const [tableData, setTableData] = useState([]);
//
const [tempGroup, setTempGroup] = useState([]);
//
const [total, setTotal] = useState(0);
//
const [pageData, setPageData] = useState({
pn: 1,
page_size: 10,
});
//
const [delModal, setDelModal] = useState({
visible: false,
id: "",
});
const addRule = () => {
setModalData({ ...modalData, visible: true });
};
//
const search = () => {
const params = form.getFieldsValue();
ajax
.getRoadBillRuleList({ road_id: id, ...pageData, ...params })
.then((res) => {
if (res.status === 20000) {
setTableData(res.data.list);
setTotal(res.data.total);
}
});
};
//
const getChargeRuleList = () => {
ajax.getRoadBillRule().then((res) => {
if (res.status === 20000) {
setChargeRuleList(res.data);
}
});
};
//
const getTempGroup = () => {
ajax.getRoadTemporaryGroup({ road_id: id }).then((res) => {
if (res.status === 20000) {
setTempGroup(res.data);
}
});
};
//
const addRoadBillRule = (params) => {
ajax.addRoadBillRule(params).then((res) => {
if (res.status === 20000) {
message.success("添加成功");
successSubmit();
} else {
message.error(res.message);
}
});
};
//
const editRoadBullRule = (params) => {
ajax.editRoadBullRule(params).then((res) => {
if (res.status === 20000) {
message.success("编辑成功");
successSubmit();
} else {
message.error(res.message);
}
});
};
//
const submit = () => {
editform
.validateFields()
.then((values) => {
if (modalData.status === "add") {
addRoadBillRule({ ...values, road_id: id, ...pageData });
} else if (modalData.status === "edit") {
editRoadBullRule({ ...values, road_id: id, ...pageData });
}
})
.catch((err) => console.error(err));
};
//
const successSubmit = () => {
setModalData({ ...modalData, visible: false });
editform.resetFields();
setPageData({ pn: 1, page_size: 10 });
};
//
const delRoadBillRule = (id) => {
ajax.delRoadBillRule({ id }).then((res) => {
if (res.status === 20000) {
message.success("删除成功");
setDelModal({ ...delModal, visible: false });
setPageData({ pn: 1, page_size: 10 });
}
});
};
useEffect(() => {
getChargeRuleList();
getTempGroup();
}, []);
useEffect(() => {
search();
}, [pageData]);
return (
<div>
<header style={{ margin: "10px 0" }}>
<Form>
<Form form={form}>
<Row gutter={[30]}>
<Col span="4_8" style={{ width: "30%" }}>
<Form.Item label="计费规则">
<Select />
<Form.Item label="计费规则" name="rule_id">
<Select options={chargeRuleList} />
</Form.Item>
</Col>
<Col span="4_8" style={{ width: "30%" }}>
<Form.Item label="车辆类型">
<Select />
<Form.Item label="车辆类型" name="vehicle_type">
<Select options={carTypeList} />
</Form.Item>
</Col>
<Form.Item>
@ -109,25 +247,67 @@ function BillingRules() {
</Form>
</header>
<main>
<Table columns={columns} className="yisa-table"></Table>
<Table
columns={columns}
className="yisa-table"
dataSource={tableData}
pagination={{
total,
current: pageData.pn,
pageSize: pageData.page_size,
onChange: (page, pageSize) => {
setPageData({ ...pageData, pn: page, page_size: pageSize });
},
onShowSizeChange: (current, size) => {
setPageData({ ...pageData, pn: current, page_size: size });
},
}}
></Table>
</main>
<Modal
title="添加计费规则"
open={modalData.visible}
onCancel={() => setModalData({ ...modalData, visible: false })}
onCancel={() => {
setModalData({ ...modalData, visible: false });
editform.resetFields();
}}
onOk={submit}
>
<Form labelCol={{ span: 6 }}>
<Form.Item label="车辆类型">
<Select />
<Form labelCol={{ span: 6 }} form={editform}>
<Form.Item
label="车辆类型"
name="vehicle_type"
rules={[{ required: true }]}
>
<Select options={carTypeList} />
</Form.Item>
<Form.Item label="车辆组">
<Select />
<Form.Item
label="车辆组"
name="group_ids"
rules={[{ required: true }]}
>
<Select options={tempGroup} />
</Form.Item>
<Form.Item label="计费规则">
<Select />
<Form.Item
label="计费规则"
name="rule_id"
rules={[{ required: true }]}
>
<Select options={chargeRuleList} />
</Form.Item>
</Form>
</Modal>
{/* 删除弹窗 */}
<Modal
title="提示"
open={delModal.visible}
onCancel={() => {
setDelModal({ ...delModal, visible: false });
}}
onOk={() => delRoadBillRule(delModal.id)}
>
确定要删除这条数据吗
</Modal>
</div>
);
}

155
src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/ConfigParking/TollCollectorManagement.jsx

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import {
Input,
Form,
@ -9,8 +9,10 @@ import {
Modal,
Select,
Popover,
Transfer,
} from "antd";
function TollCollectorManagement() {
import ajax from "@/services";
function TollCollectorManagement({ id: road_id }) {
const columns = [
{
title: "收费员姓名",
@ -20,14 +22,14 @@ function TollCollectorManagement() {
},
{
title: "收费员编号",
dataIndex: "id",
key: "id",
dataIndex: "user_code",
key: "user_code",
align: "center",
},
{
title: "收费员账号",
dataIndex: "account",
key: "account",
dataIndex: "user_account",
key: "user_account",
align: "center",
},
{
@ -41,14 +43,21 @@ function TollCollectorManagement() {
dataIndex: "action",
key: "action",
align: "center",
render: () => {
render: (_, record) => {
return (
<Popover
trigger="hover"
content={
<div>
<p>编辑</p>
<p>删除</p>
<div>
<a
onClick={() => {
deleteOutSegmentUser(record.id);
}}
>
删除
</a>
</div>
</div>
}
>
@ -58,36 +67,116 @@ function TollCollectorManagement() {
},
},
];
const [form] = Form.useForm();
const [modalData, setModalData] = useState({
visible: false,
});
const [pageData, setPageData] = useState({
pn: 1,
page_size: 10,
});
const [transferSouceData, setTransferSouceData] = useState([]);
const [selectedKeys, setSelectedKeys] = useState([]);
const [targetKeys, setTargetKeys] = useState([]);
const [collectorList, setCollectorList] = useState([]);
const [total, setTotal] = useState(0);
const addCollector = () => {
setModalData({ ...modalData, visible: true });
};
//
const getOutSegmentUserList = () => {
const params = {
...form.getFieldsValue(),
road_id,
...pageData,
};
ajax.getOutSegmentUserList(params).then((res) => {
if (res.status === 20000) {
setCollectorList(res.data.list);
setTotal(res.data.total);
}
});
};
//穿
const transferChange = (nextTargetKeys) => {
setTargetKeys(nextTargetKeys);
};
const onSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
};
//穿
const getTransferData = () => {
ajax.getOperatorMbUser({ road_id }).then((res) => {
if (res.status === 20000) {
const allData = [...res.data.selected, ...res.data.unselected].map(
(item) => {
item.key = item.value;
return item;
}
);
const selected = res.data.selected.map((item) => item.value);
setTargetKeys(selected);
setTransferSouceData(allData);
}
});
};
//
const addOutSegmentUser = () => {
ajax.addRoadUser({ road_id, user_ids: targetKeys }).then((res) => {
if (res.status === 20000) {
setModalData({ ...modalData, visible: false });
getOutSegmentUserList();
}
});
};
//
const deleteOutSegmentUser = (id) => {
ajax.deleteRoadUser({ id }).then((res) => {
if (res.status === 20000) {
setModalData({ ...modalData, visible: false });
getOutSegmentUserList();
}
});
};
//
const search = () => {
setPageData({ ...pageData, pn: 1 });
};
useEffect(() => {
getTransferData();
}, []);
useEffect(() => {
getOutSegmentUserList();
}, [pageData]);
return (
<div>
<header style={{ margin: "10px 0" }}>
<Form>
<Form form={form} onFinish={search}>
<Row gutter={[30]}>
<Col span="4_8" style={{ width: "30%" }}>
<Form.Item label="收费员姓名">
<Form.Item label="收费员姓名" name="name">
<Input />
</Form.Item>
</Col>
<Col span="4_8" style={{ width: "30%" }}>
<Form.Item label="收费员账号">
<Form.Item label="收费员账号" name="user_account">
<Input />
</Form.Item>
</Col>
<Col span="4_8" style={{ width: "30%" }}>
<Form.Item label="角色">
<Form.Item label="角色" name="user_account">
<Select />
</Form.Item>
</Col>
<Form.Item>
<div className="bottom-button">
<Button type="primary">查询</Button>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button type="primary" onClick={addCollector}>
添加
</Button>
@ -97,24 +186,36 @@ function TollCollectorManagement() {
</Form>
</header>
<main>
<Table columns={columns} className="yisa-table"></Table>
<Table
columns={columns}
className="yisa-table"
dataSource={collectorList}
pagination={{
total: total,
showTotal: (total) => `${total}`,
pageSize: pageData.page_size,
current: pageData.pn,
onChange: (page, pageSize) => {
setPageData({ ...pageData, pn: page, page_size: pageSize });
},
}}
></Table>
</main>
<Modal
title="添加计费规则"
title="添加收费员"
open={modalData.visible}
onCancel={() => setModalData({ ...modalData, visible: false })}
onOk={addOutSegmentUser}
>
<Form labelCol={{ span: 6 }}>
<Form.Item label="车辆类型">
<Select />
</Form.Item>
<Form.Item label="车辆组">
<Select />
</Form.Item>
<Form.Item label="计费规则">
<Select />
</Form.Item>
</Form>
<Transfer
dataSource={transferSouceData}
titles={["未选择", "已选择"]}
targetKeys={targetKeys}
onChange={transferChange}
selectedKeys={selectedKeys}
onSelectChange={onSelectChange}
render={(item) => item.label}
/>
</Modal>
</div>
);

2
src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/ConfigParking/index.jsx

@ -60,7 +60,7 @@ function ConfigParking(props) {
{
label: "收费员管理",
key: "9",
children: <TollCollectorManagement />,
children: <TollCollectorManagement id={itemData.id} />,
},
{
label: "欠费立场",

207
src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/QRModal.jsx

@ -0,0 +1,207 @@
import React, { useEffect, useState } from "react";
import { Button, Modal, Table, Descriptions, message } from "antd";
import ajax from "@/services";
import copy from "copy-to-clipboard";
function QRModal(props) {
const {
visible = false,
close = () => {},
itemData = {},
id: road_id,
} = props;
console.log(road_id);
const columns_12 = [
{
title: "停车场",
dataIndex: "road_name",
key: "road_name",
},
{
title: "通道名称",
dataIndex: "channel_name",
key: "channel_name",
},
{
title: "链接地址",
dataIndex: "link",
key: "link",
},
{
title: "操作",
dataIndex: "action",
key: "action",
render: (_, record) => {
return (
<div>
<Button onClick={() => getLink(record)}>复制链接</Button>
<Button
onClick={() => {
getPicById(record.id);
}}
>
导出二维码
</Button>
</div>
);
},
},
];
const columns_3 = [
{
title: "停车场",
dataIndex: "road_name",
key: "road_name",
},
{
title: "链接地址",
dataIndex: "link",
key: "link",
},
{
title: "操作",
dataIndex: "action",
key: "action",
align: "center",
width: 200,
render: (_, record) => {
return (
<div className="buttons">
<Button type="primary" onClick={() => getLink(record)}>
复制链接
</Button>
<Button
onClick={() => {
getPicById(record.id);
}}
type="primary"
>
导出二维码
</Button>
</div>
);
},
},
];
const [qrcode1, setQrcode1] = useState([]);
const [qrcode2, setQrcode2] = useState([]);
const [qrcode3, setQrcode3] = useState([]);
function getData() {
ajax.getRoadQRcodeInfo({ road_id }).then((res) => {
if (res.status === 20000) {
setQrcode1(res.data.qrcode_1);
setQrcode2(res.data.qrcode_2);
setQrcode3(res.data.qrcode_3);
}
});
}
//
const getLink = (record) => {
if (copy(record.link)) {
message.success("复制成功");
} else message.error("复制失败,请手动复制");
};
//
const getPicById = (id) => {
ajax.getRoadQRcodePic({ id }).then((res) => {
if (res.status === 20000) {
const name = res.data.url
.split("/")
[res.data.url.split("/").length - 1].split("?")[0];
downloadImage(res.data.url, name);
}
});
};
//
const getNmae = (url) => {
if (!url) return false;
else if (url === "") return false;
return url.split("/")[url.split("/").length - 1].split("?")[0];
};
const getPicByIds = (road_id) => {
ajax.getRoadQRcodePicBatch({ road_id }).then((res) => {
if (res.status === 20000) {
const { url1, url2, url3 } = res.data;
const name1 = getNmae(url1);
const name2 = getNmae(url2);
const name3 = getNmae(url3);
if (name1) {
downloadImage(url1, name1);
}
if (name2) {
downloadImage(url2, name2);
}
if (name3) {
downloadImage(url3, name3);
}
}
});
};
//
const downloadImage = (url, filename) => {
fetch(url)
.then((response) => response.blob())
.then((blob) => {
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
})
.catch((err) => console.log(err));
};
useEffect(() => {
getData();
}, []);
return (
<Modal title="二维码下载" open={visible} onCancel={close} width={1200}>
<header className="QR-header">
<h3>{itemData.road_name}</h3>
<div className="buttons">
<Button
type="primary"
onClick={() => {
getPicByIds(road_id);
}}
>
导出全部二维码
</Button>
</div>
</header>
<main>
<Descriptions title="入场无牌车二维码">
<Descriptions.Item span={3}>
<Table
columns={columns_12}
className="yisa-table"
dataSource={qrcode1}
pagination={false}
/>
</Descriptions.Item>
</Descriptions>
<Descriptions title="出场缴费二维码">
<Descriptions.Item span={3}>
<Table
columns={columns_12}
className="yisa-table"
dataSource={qrcode2}
pagination={false}
/>
</Descriptions.Item>
</Descriptions>
<Descriptions title="出场缴费二维码">
<Descriptions.Item span={3}>
<Table
columns={columns_3}
className="yisa-table"
dataSource={qrcode3}
pagination={false}
/>
</Descriptions.Item>
</Descriptions>
</main>
</Modal>
);
}
export default QRModal;

12
src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/index.scss

@ -33,6 +33,18 @@ $color-primary: var(--color-primary);
color: var(--color-search-list-item-value);
}
}
.QR-header {
display: flex;
justify-content: space-between;
}
.buttons {
display: flex;
justify-content: space-between;
align-items: center;
button {
margin-left: 10px;
}
}
// .ant-tabs-tabpane-hidden {
// display: none;

51
src/pages/OutRoadMgm/OutSegmentMgm/OutSegment/loadable.jsx

@ -29,12 +29,14 @@ import Detail from "./Detail";
import AddParking from "./AddParking";
import "./index.scss";
import ConfigParking from "./ConfigParking";
import QRModal from "./QRModal";
// import errorImg from "@/assets/images/layout/error.png"
// import { useLocation } from "react-router-dom";
function OutSegment() {
const [searchForm] = Form.useForm();
const [commentForm] = Form.useForm();
const [berthForm] = Form.useForm();
const inputParams = {
maxLength: 50,
showCount: true,
@ -145,12 +147,22 @@ function OutSegment() {
</a>
</div>
<div>
<a>二维码下载</a>
<a
onClick={() => {
setQrModal({ ...qrModal, visible: true, record });
}}
>
二维码下载
</a>
</div>
<div>
<a
onClick={() => {
setBerthNumModal({ ...berthNumModal, visible: true });
setBerthNumModal({
...berthNumModal,
visible: true,
id: record.id,
});
}}
>
修改剩余泊位
@ -218,6 +230,13 @@ function OutSegment() {
const [berthNumModal, setBerthNumModal] = useState({
visible: false,
close: () => setBerthNumModal({ ...berthNumModal, visible: false }),
id: "",
});
//
const [qrModal, setQrModal] = useState({
visible: false,
close: () => setQrModal({ ...qrModal, visible: false }),
record: {},
});
const [operationName, setOperationName] = useState([]);
@ -291,7 +310,17 @@ function OutSegment() {
}
});
};
//
const editBerthNumber = (id, berth_number) => {
ajax.editBerthNumber({ id, berth_number }).then((res) => {
if (res.status === 20000) {
message.success(res.message);
} else {
message.error(res.message);
}
setBerthNumModal({ ...berthNumModal, visible: false });
});
};
//
const configAppraise = () => {
let values = commentForm.getFieldsValue();
@ -478,6 +507,12 @@ function OutSegment() {
itemData={configModal.record}
bodyStyle="modal-style"
/>
<QRModal
visible={qrModal.visible}
close={qrModal.close}
itemData={qrModal.record}
id={qrModal.record.id}
/>
<Modal
title="批量评价配置"
visible={appraiseModal.visible}
@ -505,9 +540,15 @@ function OutSegment() {
title="修改剩余泊位数"
open={berthNumModal.visible}
onCancel={berthNumModal.close}
onOk={() => {
editBerthNumber(
berthNumModal.id,
berthForm.getFieldValue("berth_number")
);
}}
>
<Form colon={false} labelCol={{ span: 8 }}>
<Form.Item label="剩余泊位数">
<Form colon={false} labelCol={{ span: 8 }} form={berthForm}>
<Form.Item label="剩余泊位数" name="berth_number">
<Input />
</Form.Item>
</Form>

48
src/services/OutRoadMgm/ChargeRulesMgm.js

@ -0,0 +1,48 @@
import ajax from "@/config/ajax";
///api/orp/bill/get_rule_list 计费规则列表查询展示
const getChargeRuleList = (params) => {
return ajax({
url: "/api/orp/bill/get_rule_list",
type: "post",
data: params,
});
};
///api/orp/bill/del_rule 删除计费规则
const delChargeRule = (params) => {
return ajax({
url: "/api/orp/bill/del_rule",
type: "get",
data: params,
});
};
///api/orp/bill/get_rule_info 获取详情
const getChargeRuleInfo = (params) => {
return ajax({
url: "/api/orp/bill/get_rule_info",
type: "get",
data: params,
});
};
///api/orp/bill/add_rule 新增计费规则
const addChargeRule = (params) => {
return ajax({
url: "/api/orp/bill/add_rule",
type: "post",
data: params,
});
};
///api/orp/bill/edit_rule 编辑计费规则
const editChargeRule = (params) => {
return ajax({
url: "/api/orp/bill/edit_rule",
type: "post",
data: params,
});
};
export default {
getChargeRuleList,
delChargeRule,
getChargeRuleInfo,
addChargeRule,
editChargeRule,
};

25
src/services/OutRoadMgm/OutParkingRecordInquiry.js

@ -1,6 +1,6 @@
import ajax from "@/config/ajax";
///api/orp/business/get_record_list 停车记录查询/欠费订单-列表
const getRecordList = (params) => {
const getOutParkingRecordList = (params) => {
return ajax({
url: "/api/orp/business/get_record_list ",
type: "post",
@ -8,4 +8,25 @@ const getRecordList = (params) => {
});
};
export default { getRecordList };
///api/orp/business/get_record_payment 停车记录查询-支付列表
const getOutParkingReacordPayment = (params) => {
return ajax({
url: "/api/orp/business/get_record_payment",
type: "get",
data: params,
});
};
///api/orp/business/get_record_refund 停车记录查询-退款列表
const getOutParkingReacordRefund = (params) => {
return ajax({
url: "/api/orp/business/get_record_refund",
type: "get",
data: params,
});
};
export default {
getOutParkingRecordList,
getOutParkingReacordPayment,
getOutParkingReacordRefund,
};

12
src/services/OutRoadMgm/OutPayOrders.js

@ -0,0 +1,12 @@
import ajax from "@/config/ajax";
// /api/orp/business/get_payment_list 支付订单-列表
const getOutPayOrdersList = (params) => {
return ajax({
url: "/api/orp/business/get_payment_list",
type: "post",
data: params,
});
};
export default {
getOutPayOrdersList,
};

131
src/services/OutRoadMgm/OutSegment.js

@ -266,6 +266,123 @@ const delLED = (params) => {
data: params,
});
};
///api/orp/road/user_list 路段配置页面收费员列表
const getOutSegmentUserList = (params) => {
return ajax({
url: "/api/orp/road/user_list",
type: "post",
data: params,
});
};
///api/orp/road/get_operator_mb_user 获取路段对应商户的MB收费员 左右侧筛选
const getOperatorMbUser = (params) => {
return ajax({
url: "/api/orp/road/get_operator_mb_user",
type: "post",
data: params,
});
};
///api/orp/road/add_user 添加路段收费员
const addRoadUser = (params) => {
return ajax({
url: "/api/orp/road/add_user",
type: "post",
data: params,
});
};
///api/orp/road/del_road_user 删除路段收费员
const deleteRoadUser = (params) => {
return ajax({
url: "/api/orp/road/del_road_user",
type: "post",
data: params,
});
};
///api/orp/road/get_road_qrcode_info 路段二维码相关数据
const getRoadQRcodeInfo = (params) => {
return ajax({
url: "/api/orp/road/get_road_qrcode_info",
type: "post",
data: params,
});
};
///api/orp/road/get_road_qrcode_info_1694677215313 获取路段二维码图片
const getRoadQRcodePic = (params) => {
return ajax({
url: "/api/orp/road/get_road_qrcode_info_1694677215313",
type: "post",
data: params,
});
};
///api/orp/road/batch_get_qrcode 批量获取路段二维码图片
const getRoadQRcodePicBatch = (params) => {
return ajax({
url: "/api/orp/road/batch_get_qrcode",
type: "post",
data: params,
});
};
///api/orp/road/edit_berth_number 编辑剩余泊位
const editBerthNumber = (params) => {
return ajax({
url: "/api/orp/road/edit_berth_number",
type: "post",
data: params,
});
};
///api/orp/bill/get_road_bill_rule 获取路段对应计费规则下拉
const getRoadBillRule = (params) => {
return ajax({
url: "/api/orp/bill/get_road_bill_rule",
type: "post",
data: params,
});
};
///api/orp/road/raod_bill_rule_list 路段对应计费规则列表
const getRoadBillRuleList = (params) => {
return ajax({
url: "/api/orp/road/raod_bill_rule_list",
type: "post",
data: params,
});
};
///api/orp/road/get_road_temporary_group 获取路段临时车辆组
const getRoadTemporaryGroup = (params) => {
return ajax({
url: "/api/orp/road/get_road_temporary_group",
type: "post",
data: params,
});
};
///api/orp/road/add_road_bill_rule 添加路段对应计费规则
const addRoadBillRule = (params) => {
return ajax({
url: "/api/orp/road/add_road_bill_rule",
type: "post",
data: params,
});
};
//api/orp/road/edit_road_bill_rule 编辑路段对应计费规则
const editRoadBullRule = (params) => {
return ajax({
url: "/api/orp/road/edit_road_bill_rule",
type: "post",
data: params,
});
};
///api/orp/road/del_road_bill_rule 删除路段对应计费规则
const delRoadBillRule = (params) => {
return ajax({
url: "/api/orp/road/del_road_bill_rule",
type: "post",
data: params,
});
};
export default {
getOrpRoadList,
getOrpRoadInfo,
@ -299,4 +416,18 @@ export default {
editLED,
addLED,
delLED,
getOutSegmentUserList,
getOperatorMbUser,
addRoadUser,
deleteRoadUser,
getRoadQRcodeInfo,
getRoadQRcodePicBatch,
getRoadQRcodePic,
editBerthNumber,
getRoadBillRule,
getRoadBillRuleList,
getRoadTemporaryGroup,
addRoadBillRule,
editRoadBullRule,
delRoadBillRule,
};

6
src/services/OutRoadMgm/index.js

@ -4,11 +4,15 @@ import OutParkingRecordInquiry from "./OutParkingRecordInquiry";
import OutNVRMgm from "./OutNVRMgm";
import LiftUpPoleRecord from "./LiftUpPoleRecord";
import ZombieCarCleanRecord from "./ZombieCarCleanRecord";
import OutPayOrders from "./OutPayOrders";
import ChargeRulesMgm from "./ChargeRulesMgm";
export default {
...OutSegment,
...ZombieCarMgm,
...OutParkingRecordInquiry,
...OutNVRMgm,
...LiftUpPoleRecord,
...ZombieCarCleanRecord
...ZombieCarCleanRecord,
...OutPayOrders,
...ChargeRulesMgm,
};
Loading…
Cancel
Save